From 62fd3b8f978c87f625b03720365a988b80ab4c7d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 29 May 2019 12:28:18 +0800 Subject: [PATCH 0001/1029] =?UTF-8?q?=E6=8A=98=E8=85=BE=20net45=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=EF=BC=8C=E5=A2=9E=E5=8A=A0=20MySqlConnector?= =?UTF-8?q?=20=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 4 +-- FreeSql.sln | 23 ++++++++++--- FreeSql/FreeSql.csproj | 7 ++-- FreeSql/FreeSqlBuilder.cs | 1 + .../AdoProvider/AdoProviderAsync.cs | 10 +++--- .../SelectProvider/Select0Provider.cs | 6 ++-- FreeSql/Internal/UtilsExpressionTree.cs | 16 ++++++++-- .../FreeSql.Provider.MySql.csproj | 6 ++-- .../FreeSql.Provider.MySqlConnector/Class1.cs | 6 ++++ .../FreeSql.Provider.MySqlConnector.csproj | 32 +++++++++++++++++++ .../FreeSql.Provider.Oracle.csproj | 14 +++++--- .../FreeSql.Provider.PostgreSQL.csproj | 9 +++--- .../FreeSql.Provider.SqlServer.csproj | 9 +++--- .../FreeSql.Provider.Sqlite.csproj | 6 ++-- readme.md | 26 +++++++-------- 15 files changed, 124 insertions(+), 51 deletions(-) create mode 100644 Providers/FreeSql.Provider.MySqlConnector/Class1.cs create mode 100644 Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6e0c035c..eefa3548 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.6.1 + 0.6.2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. @@ -20,7 +20,7 @@ - + diff --git a/FreeSql.sln b/FreeSql.sln index c3d37c4a..024df11f 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -30,15 +30,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MySql", "P EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Oracle", "Providers\FreeSql.Provider.Oracle\FreeSql.Provider.Oracle.csproj", "{3DE45286-B0DB-4D74-B322-F5467FB2EF53}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.Sqlite", "Providers\FreeSql.Provider.Sqlite\FreeSql.Provider.Sqlite.csproj", "{559B6369-1868-4A06-A590-F80BA7B80A1B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Sqlite", "Providers\FreeSql.Provider.Sqlite\FreeSql.Provider.Sqlite.csproj", "{559B6369-1868-4A06-A590-F80BA7B80A1B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.SqlServer", "Providers\FreeSql.Provider.SqlServer\FreeSql.Provider.SqlServer.csproj", "{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.SqlServer", "Providers\FreeSql.Provider.SqlServer\FreeSql.Provider.SqlServer.csproj", "{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.PostgreSQL", "Providers\FreeSql.Provider.PostgreSQL\FreeSql.Provider.PostgreSQL.csproj", "{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.PostgreSQL", "Providers\FreeSql.Provider.PostgreSQL\FreeSql.Provider.PostgreSQL.csproj", "{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{4A92E8A6-9A6D-41A1-9CDA-DE10899648AA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Extensions.LazyLoading", "Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj", "{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.LazyLoading", "Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj", "{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.MySqlConnector", "Providers\FreeSql.Provider.MySqlConnector\FreeSql.Provider.MySqlConnector.csproj", "{D2A41321-5E84-410B-B25C-3AA122D4CA27}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -206,6 +208,18 @@ Global {1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|x64.Build.0 = Release|Any CPU {1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|x86.ActiveCfg = Release|Any CPU {1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|x86.Build.0 = Release|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Debug|x64.ActiveCfg = Debug|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Debug|x64.Build.0 = Debug|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Debug|x86.ActiveCfg = Debug|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Debug|x86.Build.0 = Debug|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|Any CPU.Build.0 = Release|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x64.ActiveCfg = Release|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x64.Build.0 = Release|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.ActiveCfg = Release|Any CPU + {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -221,6 +235,7 @@ Global {B61AAC9E-59E9-4F47-BBE3-97AC24112EFE} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} + {D2A41321-5E84-410B-B25C-3AA122D4CA27} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 5fb7079e..b8342ba7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - 0.6.1 + netstandard2.0;net45 + 0.6.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. @@ -23,7 +23,8 @@ - + + diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index f9875fd8..9ce5494c 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -108,6 +108,7 @@ namespace FreeSql { switch(_dataType) { case DataType.MySql: type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); + if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); break; case DataType.SqlServer: type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 7b711256..956ac42b 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -34,7 +34,7 @@ namespace FreeSql.Internal.CommonProvider { flag = sbflag.ToString(); } ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); - return Task.CompletedTask; + return Task.FromResult(false); }, cmdType, cmdText, cmdParms); return ret; } @@ -88,7 +88,7 @@ namespace FreeSql.Internal.CommonProvider { ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); break; } - return Task.CompletedTask; + return Task.FromResult(false); }, cmdType, cmdText, cmdParms); return (ret1, ret2); } @@ -162,7 +162,7 @@ namespace FreeSql.Internal.CommonProvider { ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); break; } - return Task.CompletedTask; + return Task.FromResult(false); }, cmdType, cmdText, cmdParms); return (ret1, ret2, ret3); } @@ -256,7 +256,7 @@ namespace FreeSql.Internal.CommonProvider { ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); break; } - return Task.CompletedTask; + return Task.FromResult(false); }, cmdType, cmdText, cmdParms); return (ret1, ret2, ret3, ret4); } @@ -370,7 +370,7 @@ namespace FreeSql.Internal.CommonProvider { ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); break; } - return Task.CompletedTask; + return Task.FromResult(false); }, cmdType, cmdText, cmdParms); return (ret1, ret2, ret3, ret4, ret5); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 1e8159f5..9a7fe7c5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -285,7 +285,7 @@ namespace FreeSql.Internal.CommonProvider { await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => { var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); ret.Add((TTuple)read.Value); - return Task.CompletedTask; + return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } catch (Exception ex) { exception = ex; @@ -337,7 +337,7 @@ namespace FreeSql.Internal.CommonProvider { foreach (var other in otherData) other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); } - return Task.CompletedTask; + return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } catch (Exception ex) { exception = ex; @@ -431,7 +431,7 @@ namespace FreeSql.Internal.CommonProvider { await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => { var index = -1; ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); - return Task.CompletedTask; + return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } catch (Exception ex) { exception = ex; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6de5c976..f439171c 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -83,7 +83,12 @@ namespace FreeSql.Internal { }; if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable; if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)"; - colattr.DbType = colattr.DbType.ToUpper(); + if (colattr.DbType.StartsWith("set(") || colattr.DbType.StartsWith("enum(")) { + var leftBt = colattr.DbType.IndexOf('('); + colattr.DbType = colattr.DbType.Substring(0, leftBt).ToUpper() + colattr.DbType.Substring(leftBt); + } + else + colattr.DbType = colattr.DbType.ToUpper(); if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; @@ -1164,7 +1169,14 @@ namespace FreeSql.Internal { } var typeOrg = type; if (type.IsNullableType()) type = type.GenericTypeArguments.First(); - if (type.IsEnum) return Expression.Return(returnTarget, Expression.Call(MethodEnumParse, Expression.Constant(type, typeof(Type)), Expression.Call(MethodToString, valueExp), Expression.Constant(true, typeof(bool)))); + if (type.IsEnum) + return Expression.Block( + Expression.IfThenElse( + Expression.Equal(Expression.TypeAs(valueExp, typeof(string)), Expression.Constant(string.Empty)), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(type), typeof(object))), + Expression.Return(returnTarget, Expression.Call(MethodEnumParse, Expression.Constant(type, typeof(Type)), Expression.Call(MethodToString, valueExp), Expression.Constant(true, typeof(bool)))) + ) + ); Expression tryparseExp = null; Expression tryparseBooleanExp = null; ParameterExpression tryparseVarExp = null; diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 224fc15a..65e13c74 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - 0.6.1 + netstandard2.0;net452 + 0.6.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 @@ -18,7 +18,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/Class1.cs b/Providers/FreeSql.Provider.MySqlConnector/Class1.cs new file mode 100644 index 00000000..e855068e --- /dev/null +++ b/Providers/FreeSql.Provider.MySqlConnector/Class1.cs @@ -0,0 +1,6 @@ +using System; + +namespace FreeSql.Provider.MySqlConnector { + public class Class1 { + } +} diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj new file mode 100644 index 00000000..ed132945 --- /dev/null +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -0,0 +1,32 @@ + + + + netstandard2.0;net45 + 0.6.2 + true + YeXiangQin + FreeSql 数据库实现,基于 MySql 5.6 + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + $(AssemblyName) + true + true + + + + + + + + + + + + + + + diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a839d7ce..7244b7c9 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - 0.6.1 + netstandard2.0;net45 + 0.6.2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 @@ -16,9 +16,13 @@ true true - - - + + + + + + + diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e99f8ff0..9561f1a8 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - 0.6.1 + netstandard2.0;net45 + 0.6.2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 @@ -18,10 +18,11 @@ - - + + + diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a8e7a825..302cf2c7 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - 0.6.1 + netstandard2.0;net451 + 0.6.2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -16,11 +16,12 @@ true true - + - + + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 66086d68..6be75fce 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - 0.6.1 + netstandard2.0;net45 + 0.6.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 @@ -18,7 +18,7 @@ - + diff --git a/readme.md b/readme.md index 3778bcdc..2fc9d1e7 100644 --- a/readme.md +++ b/readme.md @@ -31,16 +31,21 @@ FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程 | [FreeSql.AdminLTE](https://github.com/2881099/FreeSql.AdminLTE) | [![nuget](https://img.shields.io/nuget/v/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.AdminLTE) | [![stats](https://img.shields.io/nuget/dt/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.AdminLTE?groupby=Version) | | [FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Connection.Extensions) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Connection.Extensions?groupby=Version) | +- FreeSql 是核心,提供原始用法; +- FreeSql.DbContext 是扩展包,提供面向对象的用法(像EF); +- FreeSql.Repository 也是扩展包,提供仓储+工作单元用法; +- FreeSql.Connection.Extensions 也是扩展包,提供像 Dapper 一样的用法; + # Providers -| Package Name | NuGet | Downloads | -|--------------| ------- | ---- | -| FreeSql.Provider.MySql | [![nuget](https://img.shields.io/nuget/v/FreeSql.Provider.MySql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Provider.MySql) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Provider.MySql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Provider.MySql?groupby=Version) | -| FreeSql.Provider.PostgreSQL | [![nuget](https://img.shields.io/nuget/v/FreeSql.Provider.PostgreSQL.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Provider.PostgreSQL) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Provider.PostgreSQL.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Provider.PostgreSQL?groupby=Version) | -| FreeSql.Provider.SqlServer | [![nuget](https://img.shields.io/nuget/v/FreeSql.Provider.SqlServer.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Provider.SqlServer) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Provider.SqlServer.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Provider.SqlServer?groupby=Version) | -| FreeSql.Provider.Sqlite | [![nuget](https://img.shields.io/nuget/v/FreeSql.Provider.Sqlite.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Provider.Sqlite) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Provider.MySqliteSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Provider.Sqlite?groupby=Version) | -| FreeSql.Provider.Oracle | [![nuget](https://img.shields.io/nuget/v/FreeSql.Provider.Oracle.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Provider.Oracle) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Provider.Oracle.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Provider.Oracle?groupby=Version) | -| FreeSql.Extensions.LazyLoading | [![nuget](https://img.shields.io/nuget/v/FreeSql.Extensions.LazyLoading.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Extensions.LazyLoading) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Extensions.LazyLoading.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Extensions.LazyLoading?groupby=Version) | +| Package Name | Version | +|--------------| ------- | +| FreeSql.Provider.MySql | NETStandard2.0、net452 | +| FreeSql.Provider.PostgreSQL | NETStandard2.0、net45 | +| FreeSql.Provider.SqlServer | NETStandard2.0、net451 | +| FreeSql.Provider.Sqlite | NETStandard2.0、net45 | +| FreeSql.Provider.Oracle | NETStandard2.0、net45 | +| FreeSql.Extensions.LazyLoading | NETStandard2.0 | # Quick start @@ -132,11 +137,6 @@ var t5 = fsql.Select() ``` 更多前往Wiki:[《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) -- IFreeSql 是核心,提供原始用法; -- FreeSql.DbContext 是扩展包,提供面向对象的用法(像EF); -- FreeSql.Repository 也是扩展包,提供仓储+工作单元用法(实际上和 DbContext 是一个扩展包); -- FreeSql.Connection.Extensions 也是扩展包,提供像 Dapper 一样的用法; - # Repository & UnitOfWork > dotnet add package FreeSql.Repository From 58314516c674b70c0e4fcda388c8b1a2864968dc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 29 May 2019 12:32:24 +0800 Subject: [PATCH 0002/1029] update --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 2fc9d1e7..280951da 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.6.1+(QQ群:4336577)。 +FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577)。 据了解,用户使用很少问问题,编码过程中,因业务阻塞,情有可原;因框架使用问题阻塞,得不偿失。我们的口号:做 .net 最方便的 ORM!愿每一位开发者嘴角上扬😏! From f64d0e9d5602f5c97f80f51a55594cd9bf756a16 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 30 May 2019 09:19:13 +0800 Subject: [PATCH 0003/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20=E5=BD=93?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=20ConnectionString=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=B8=BA=E7=A9=BA=E6=97=B6=EF=BC=8C=E7=BB=99=E5=87=BA?= =?UTF-8?q?=E5=8F=8B=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/UnitTest1.cs | 9 +++++++++ FreeSql/FreeSqlBuilder.cs | 1 + 2 files changed, 10 insertions(+) diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 9af6083d..4b6c705f 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -123,9 +123,18 @@ namespace FreeSql.Tests { } } + public class TestEnum { + public Guid id { get; set; } + public Enum em { get; set; } + } + [Fact] public void Test1() { + + g.sqlite.Insert(new TestEnum { }).ExecuteAffrows(); + var telist = g.sqlite.Select().ToList(); + Assert.Throws(() => g.sqlite.CodeFirst.SyncStructure()); var TestEnumable = new TestEnumable(); diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 9ce5494c..9b2d4315 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -103,6 +103,7 @@ namespace FreeSql { public IFreeSql Build() => Build(); public IFreeSql Build() { + if (string.IsNullOrEmpty(_masterConnectionString)) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString"); IFreeSql ret = null; Type type = null; switch(_dataType) { From b13b5011316e4b17ee887cd5ffc2a04a018e05b2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 30 May 2019 17:11:55 +0800 Subject: [PATCH 0004/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IUpdate.Ingo?= =?UTF-8?q?reColumns/UpdateColumns=20=E8=8B=A5=E5=AE=9E=E4=BD=93=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E5=88=AB=E5=90=8D=E5=90=8E=EF=BC=8C=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E6=97=A0=E6=95=88=E7=9A=84bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.Tests/UnitTest1.cs | 118 ++++++++++++++++-- FreeSql/FreeSql.csproj | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 4 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 10 files changed, 121 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index eefa3548..ae2caae1 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.6.2 + 0.6.3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 4b6c705f..f9c9e131 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -106,11 +106,16 @@ namespace FreeSql.Tests { [Column(IsIdentity = true)] public int id { get; set; } - public string title { get; set; } + public string Title { get; set; } public Model1 Parent { get; set; } - public int parent_id { get; set; } + public int Parent_id { get; set; } + public string Ccc { get; set; } + public DateTime Date { get; set; } + + [Column(Name = "Waxxx2")] + public int Wa_xxx2 { get; set; } } public class TestEnumable : IEnumerable { @@ -128,9 +133,108 @@ namespace FreeSql.Tests { public Enum em { get; set; } } + /// + /// + /// + [Table(Name = "news_article")] + public class NewsArticle { + /// + /// + /// + [Column(Name = "article_id", IsIdentity = true, IsPrimary = true)] + public int ArticleId { get; set; } + + /// + /// + /// + [Column(Name = "article_title")] + public string ArticleTitle { get; set; } + + /// + /// + /// + [Column(Name = "category_id")] + public int CategoryId { get; set; } + + /// + /// + /// + [Column(Name = "channel_id")] + public int ChannelId { get; set; } + + /// + /// 类型 + /// + [Column(Name = "type_id")] + public int TypeId { get; set; } + + /// + /// 内容简介 + /// + [Column(Name = "summary")] + public string Summary { get; set; } + + /// + /// 缩略图 + /// + [Column(Name = "thumbnail")] + public string Thumbnail { get; set; } + + /// + /// 点击量 + /// + [Column(Name = "hits")] + public int Hits { get; set; } + + /// + /// + /// + [Column(Name = "is_display")] + public int IsDisplay { get; set; } + + /// + /// + /// + [Column(Name = "status")] + public int Status { get; set; } + + /// + /// + /// + [Column(Name = "create_time")] + public int CreateTime { get; set; } + + /// + /// + /// + [Column(Name = "release_time")] + public int ReleaseTime { get; set; } + + } + [Fact] public void Test1() { + var entity = new NewsArticle { + ArticleId = 1, + ArticleTitle = "测试标题" + }; + var where = new NewsArticle { + ArticleId = 1, + ChannelId = 1, + }; + var sqldddkdk = g.mysql.Update(where) + .SetSource(entity) + .UpdateColumns(x => new { x.Status, x.CategoryId, x.ArticleTitle }) + .ToSql(); + + + var sql1111333 = g.mysql.Update() + .SetSource(new Model2 { id = 1, Title = "xxx", Parent_id = 0 }) + .UpdateColumns(x => new { x.Parent_id, x.Date, x.Wa_xxx2 }) + .NoneParameter() + .ToSql(); + g.sqlite.Insert(new TestEnum { }).ExecuteAffrows(); var telist = g.sqlite.Select().ToList(); @@ -145,16 +249,16 @@ namespace FreeSql.Tests { M2Id = DateTime.Now.Second + DateTime.Now.Minute, Childs = new[] { new Model2 { - title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0001", + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0001", }, new Model2 { - title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0002", + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0002", }, new Model2 { - title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0003", + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0003", }, new Model2 { - title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0004", + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0004", } } }); @@ -183,7 +287,7 @@ namespace FreeSql.Tests { - var ttt1 = g.sqlite.Select().Where(a => a.Childs.AsSelect().Any(b => b.title == "111")).ToList(); + var ttt1 = g.sqlite.Select().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList(); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b8342ba7..ab936e84 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.2 + 0.6.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 68ced821..e34d715a 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -458,7 +458,7 @@ namespace FreeSql.Internal.CommonProvider { _paramsSource.Clear(); var colidx = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.CsName) == false) { + if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false) { if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); var value = col.GetMapValue(_source.First()); @@ -484,7 +484,7 @@ namespace FreeSql.Internal.CommonProvider { _paramsSource.Clear(); var colidx = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.CsName) == false) { + if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false) { if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 65e13c74..6a343c57 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.2 + 0.6.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ed132945..7cf27c37 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.2 + 0.6.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7244b7c9..65a25680 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.2 + 0.6.3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 9561f1a8..f72aa2fd 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.2 + 0.6.3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 302cf2c7..06f8c7ab 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.2 + 0.6.3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 6be75fce..c935571a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.2 + 0.6.3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 451b6c9769577f8c37561737cf18401f3e8ca0de Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 31 May 2019 20:30:09 +0800 Subject: [PATCH 0005/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20NavigateAttr?= =?UTF-8?q?ibute=20=E9=85=8D=E7=BD=AE=E5=AF=BC=E8=88=AA=E5=85=B3=E7=B3=BB?= =?UTF-8?q?=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20LinqToSql=20=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E5=BC=80=E5=90=AF=E8=87=AA=E5=8A=A8=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E6=97=B6=EF=BC=8C=E8=BF=81=E7=A7=BB=E4=BA=86=E6=97=A0?= =?UTF-8?q?=E5=85=B3=E7=B1=BB=E7=9A=84=20bug=EF=BC=9B=20-=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20Oracle=20DbFirst=20date(7)=20=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=9C=AA=E5=A4=84=E7=90=86=E7=9A=84=20bug=EF=BC=9B#57=20-=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20AsSelect().Any()=20=E6=9C=AA=E7=BB=99?= =?UTF-8?q?=E5=85=B6=E4=BB=96=E6=9D=A1=E4=BB=B6=E6=97=B6=EF=BC=8C=E4=BA=A7?= =?UTF-8?q?=E7=94=9F=20null=20bug=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20Free?= =?UTF-8?q?Sql.Extensions.LazyLoading=20=E5=AF=B9=20.net=204.5=20=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81=EF=BC=9B=20-=20=E4=BC=98=E5=8C=96=20MySql=20?= =?UTF-8?q?CodeFirst=20=E5=A2=9E=E5=8A=A0=20DateTime=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E9=BB=98=E8=AE=A4=E5=80=BC=E4=B8=BA=200000-0?= =?UTF-8?q?0-00=20=E5=AF=BC=E8=87=B4=E8=AF=BB=E5=8F=96=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B=20-=20=E4=BC=98=E5=8C=96=20LazyLoading?= =?UTF-8?q?=20=E5=8F=8B=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 10 +- .../LazyLoadingComplier.cs | 28 ++- FreeSql.Tests/FreeSql.Tests.csproj | 2 +- FreeSql.Tests/UnitTest1.cs | 67 +++++++ FreeSql.sln | 30 ++- FreeSql/DataAnnotations/ColumnAttribute.cs | 2 +- FreeSql/DataAnnotations/NavigateAttribute.cs | 16 ++ FreeSql/Extensions/EntityUtilExtensions.cs | 19 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 10 +- FreeSql/Internal/CommonExpression.cs | 6 +- .../CommonProvider/CodeFirstProvider.cs | 75 +++++++ .../SelectProvider/Select1Provider.cs | 4 + FreeSql/Internal/UtilsExpressionTree.cs | 184 +++++++++++------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 58 +----- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../OracleCodeFirst.cs | 57 +----- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 4 + .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../PostgreSQLCodeFirst.cs | 59 +----- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../SqlServerCodeFirst.cs | 62 +----- .../FreeSql.Provider.Sqlite.csproj | 2 +- .../SqliteCodeFirst.cs | 59 +----- readme.md | 2 +- 27 files changed, 407 insertions(+), 361 deletions(-) create mode 100644 FreeSql/DataAnnotations/NavigateAttribute.cs create mode 100644 FreeSql/Internal/CommonProvider/CodeFirstProvider.cs diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ae2caae1..dea41cf0 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - 0.6.3 + netstandard2.0;net45 + 0.6.4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. @@ -17,9 +17,13 @@ true - + + + + ns20;netstandard20 + diff --git a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs index 9c50116a..90ebbd32 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs +++ b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs @@ -1,4 +1,6 @@ -using System; +using Microsoft.CSharp; +using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using System.Reflection; using System.Text; @@ -7,6 +9,7 @@ namespace FreeSql.Extensions.LazyLoading { public class LazyLoadingComplier { +#if ns20 internal static Lazy _compiler = new Lazy(() => { //var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll"); var compiler = new CSScriptLib.RoslynEvaluator(); @@ -26,5 +29,28 @@ namespace FreeSql.Extensions.LazyLoading { public static Assembly CompileCode(string cscode) { return _compiler.Value.CompileCode(cscode); } +#else + + + public static Assembly CompileCode(string cscode) { + + using (var compiler = CodeDomProvider.CreateProvider("cs")) { + + var objCompilerParameters = new CompilerParameters(); + objCompilerParameters.ReferencedAssemblies.Add("System.dll"); + objCompilerParameters.ReferencedAssemblies.Add("FreeSql.dll"); + objCompilerParameters.GenerateExecutable = false; + objCompilerParameters.GenerateInMemory = true; + + CompilerResults cr = compiler.CompileAssemblyFromSource(objCompilerParameters, cscode); + + if (cr.Errors.Count > 0) + throw new Exception(cr.Errors[0].ErrorText); + + return cr.CompiledAssembly; + } + } + +#endif } } diff --git a/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests.csproj index 4157ec50..b778f4e2 100644 --- a/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.csproj @@ -7,7 +7,6 @@ - @@ -15,6 +14,7 @@ + diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index f9c9e131..2c7c220c 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -210,10 +210,72 @@ namespace FreeSql.Tests { [Column(Name = "release_time")] public int ReleaseTime { get; set; } + public DateTime testaddtime { get; set; } + public DateTime? testaddtime2 { get; set; } + } + + public class NewsArticleDto : NewsArticle { + + } + + + public class TaskBuildInfo { + [FreeSql.DataAnnotations.Column(IsPrimary = true)] + public Guid Id { get; set; } + public Guid TbId { get; set; } + public Guid DataBaseConfigId { get; set; } + public string Name { get; set; } + public int Level { get; set; } + + [Column(IsIgnore = true)] + public virtual TaskBuild TaskBuild { get; set; } + } + public class Templates { + [Column(IsPrimary = true)] + public Guid Id { get; set; } + public string Title { get; set; } + public DateTime AddTime { get; set; } = DateTime.Now; + public DateTime EditTime { get; set; } + [Column(DbType = "text")] + public string Code { get; set; } + } + public class TaskBuild { + + [FreeSql.DataAnnotations.Column(IsPrimary = true)] + public Guid Id { get; set; } + public string TaskName { get; set; } + public Guid TemplatesId { get; set; } + public string GeneratePath { get; set; } + public string FileName { get; set; } + public string NamespaceName { get; set; } + public bool OptionsEntity01 { get; set; } = false; + public bool OptionsEntity02 { get; set; } = false; + public bool OptionsEntity03 { get; set; } = false; + public bool OptionsEntity04 { get; set; } = false; + + [Navigate("TbId")] + public virtual ICollection Builds { get; set; } + public Templates Templates { get; set; } } [Fact] public void Test1() { + g.sqlite.SetDbContextOptions(opt => opt.EnableAddOrUpdateNavigateList = true); + var trepo = g.sqlite.GetGuidRepository(); + trepo.Insert(new TaskBuild { + TaskName = "tt11", + Builds = new[] { + new TaskBuildInfo { + Level = 1, + Name = "t111_11" + } + } + }); + + var ttdkdkd = trepo.Select.Where(a => a.Builds.AsSelect().Any()).ToList(); + + var list1113233 = trepo.Select.ToList(); + var entity = new NewsArticle { ArticleId = 1, @@ -223,11 +285,16 @@ namespace FreeSql.Tests { ArticleId = 1, ChannelId = 1, }; + + g.mysql.Insert(new[] { entity }).ExecuteAffrows(); + var sqldddkdk = g.mysql.Update(where) .SetSource(entity) .UpdateColumns(x => new { x.Status, x.CategoryId, x.ArticleTitle }) .ToSql(); + var sqldddklist = g.mysql.Select().Select(a => new NewsArticleDto { }).ToList(); + var sql1111333 = g.mysql.Update() .SetSource(new Model2 { id = 1, Title = "xxx", Parent_id = 0 }) diff --git a/FreeSql.sln b/FreeSql.sln index 024df11f..912afefe 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -40,7 +40,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.LazyLoading", "Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj", "{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.MySqlConnector", "Providers\FreeSql.Provider.MySqlConnector\FreeSql.Provider.MySqlConnector.csproj", "{D2A41321-5E84-410B-B25C-3AA122D4CA27}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MySqlConnector", "Providers\FreeSql.Provider.MySqlConnector\FreeSql.Provider.MySqlConnector.csproj", "{D2A41321-5E84-410B-B25C-3AA122D4CA27}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.DbContext", "..\FreeSql.DbContext\FreeSql.DbContext\FreeSql.DbContext.csproj", "{9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Repository", "..\FreeSql.DbContext\FreeSql.Repository\FreeSql.Repository.csproj", "{D7A9C833-8679-41B3-8258-757A6FB27A0E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -220,6 +224,30 @@ Global {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x64.Build.0 = Release|Any CPU {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.ActiveCfg = Release|Any CPU {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.Build.0 = Release|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|x64.ActiveCfg = Debug|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|x64.Build.0 = Debug|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|x86.ActiveCfg = Debug|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|x86.Build.0 = Debug|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|Any CPU.Build.0 = Release|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|x64.ActiveCfg = Release|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|x64.Build.0 = Release|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|x86.ActiveCfg = Release|Any CPU + {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|x86.Build.0 = Release|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|x64.ActiveCfg = Debug|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|x64.Build.0 = Debug|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|x86.ActiveCfg = Debug|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|x86.Build.0 = Debug|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|Any CPU.Build.0 = Release|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|x64.ActiveCfg = Release|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|x64.Build.0 = Release|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|x86.ActiveCfg = Release|Any CPU + {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 4bc8dedb..412b3bde 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -66,7 +66,7 @@ namespace FreeSql.DataAnnotations { /// /// 数据库默认值 /// - public object DbDefautValue { get; set; } + public object DbDefautValue { get; internal set; } /// /// 类型映射,比如:可将 enum 属性映射成 typeof(string) diff --git a/FreeSql/DataAnnotations/NavigateAttribute.cs b/FreeSql/DataAnnotations/NavigateAttribute.cs new file mode 100644 index 00000000..d9b052f5 --- /dev/null +++ b/FreeSql/DataAnnotations/NavigateAttribute.cs @@ -0,0 +1,16 @@ +using System; +using System.Linq; + +namespace FreeSql.DataAnnotations { + public class NavigateAttribute : Attribute { + + /// + /// 导航属性,手工绑定 + /// + public string Bind { get; set; } + + public NavigateAttribute(string bind) { + this.Bind = bind; + } + } +} diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 30ef1a80..f7bb3f2d 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -15,24 +15,26 @@ namespace FreeSql.Extensions.EntityUtil { static readonly MethodInfo MethodStringConcat = typeof(string).GetMethod("Concat", new Type[] { typeof(object) }); static readonly MethodInfo MethodFreeUtilNewMongodbId = typeof(FreeUtil).GetMethod("NewMongodbId"); - static ConcurrentDictionary>> _dicGetEntityKeyString = new ConcurrentDictionary>>(); + static ConcurrentDictionary>> _dicGetEntityKeyString = new ConcurrentDictionary>>(); /// - /// 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时(当Guid无值时,会生成有序的新值),返回 null + /// 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null /// /// /// /// + /// 当Guid无值时,会生成有序的新值 /// /// //public static string GetEntityKeyString(this IFreeSql orm, TEntity entity, string splitString = "*|_,[,_|*") => GetEntityKeyString(orm, typeof(TEntity), entity, splitString); - public static string GetEntityKeyString(this IFreeSql orm, Type entityType, object entity, string splitString = "*|_,[,_|*") { + public static string GetEntityKeyString(this IFreeSql orm, Type entityType, object entity, bool genGuid, string splitString = "*|_,[,_|*") { if (entity == null) return null; if (entityType == null) entityType = entity.GetType(); - var func = _dicGetEntityKeyString.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { + var func = _dicGetEntityKeyString.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { var _table = orm.CodeFirst.GetTableByEntity(t); var pks = _table.Primarys; var returnTarget = Expression.Label(typeof(string)); var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(bool)); var var1Parm = Expression.Variable(t); var var2Sb = Expression.Variable(typeof(StringBuilder)); var var3IsNull = Expression.Variable(typeof(bool)); @@ -84,7 +86,10 @@ namespace FreeSql.Extensions.EntityUtil { Expression.IsFalse(var3IsNull), Expression.IfThenElse( Expression.Equal(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Default(pks[a].CsType)), - expthen, + Expression.IfThen( + Expression.IsTrue(parm2), + expthen + ), Expression.Block( new Expression[]{ a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, @@ -119,9 +124,9 @@ namespace FreeSql.Extensions.EntityUtil { ) ); exps.Add(Expression.Label(returnTarget, Expression.Default(typeof(string)))); - return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb, var3IsNull }, exps), new[] { parm1 }).Compile(); + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb, var3IsNull }, exps), new[] { parm1, parm2 }).Compile(); }); - return func(entity); + return func(entity, genGuid); } static ConcurrentDictionary>> _dicGetEntityKeyValues = new ConcurrentDictionary>>(); /// diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index ab936e84..b8b8c8e1 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.3 + 0.6.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index cca0ec01..dcb10d9c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -113,6 +113,11 @@ + + + 导航属性,手工绑定 + + 数据库表名 @@ -288,13 +293,14 @@ 枚举项 - + - 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时(当Guid无值时,会生成有序的新值),返回 null + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null + 当Guid无值时,会生成有序的新值 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 69b4fd57..7c1fe876 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -500,7 +500,7 @@ namespace FreeSql.Internal { if (asSelectParentExp != null) { var testExecuteExp = asSelectParentExp; if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联 - testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).Properties.First().Value); + testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key); var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List(), tsc.getSelectGroupingMapString, SelectTableInfoType.LeftJoin); tsc2.isDisableDiyParse = true; tsc2.style = ExpressionStyle.AsSelect; @@ -553,6 +553,10 @@ namespace FreeSql.Internal { } if (fsql != null) { if (asSelectParentExp != null) { //执行 asSelect() 的关联,OneToMany,ManyToMany + if (fsqltables[0].Parameter == null) { + fsqltables[0].Alias = $"tb_{fsqltables.Count}"; + fsqltables[0].Parameter = Expression.Parameter(asSelectEntityType, fsqltables[0].Alias); + } var fsqlWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType3 => typeof(ISelect<>).MakeGenericType(asSelectEntityType3).GetMethod("Where", new[] { typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool))) diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs new file mode 100644 index 00000000..5a12ce5b --- /dev/null +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -0,0 +1,75 @@ +using FreeSql.DataAnnotations; +using FreeSql.Extensions.EntityUtil; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider { + + public abstract partial class CodeFirstProvider : ICodeFirst { + + protected IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public CodeFirstProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public bool IsAutoSyncStructure { get; set; } = false; + public bool IsSyncStructureToLower { get; set; } = false; + public bool IsSyncStructureToUpper { get; set; } = false; + public bool IsConfigEntityFromDbFirst { get; set; } = false; + public bool IsNoneCommandParameter { get; set; } = false; + public bool IsLazyLoading { get; set; } = false; + + public abstract (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); + + public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); + public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); + public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); + public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); + + public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); + public abstract string GetComparisonDDLStatements(params Type[] entityTypes); + + static object syncStructureLock = new object(); + internal ConcurrentDictionary dicSyced = new ConcurrentDictionary(); + public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); + public bool SyncStructure(params Type[] entityTypes) { + if (entityTypes == null) return true; + var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray(); + if (syncTypes.Any() == false) return true; + var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); + _orm.Aop.SyncStructureBefore?.Invoke(this, before); + Exception exception = null; + string ddl = null; + try { + lock (syncStructureLock) { + ddl = this.GetComparisonDDLStatements(syncTypes); + if (string.IsNullOrEmpty(ddl)) { + foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); + return true; + } + var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); + foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); + return affrows > 0; + } + } catch (Exception ex) { + exception = ex; + throw ex; + } finally { + var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); + _orm.Aop.SyncStructureAfter?.Invoke(this, after); + } + } + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 15009f2e..e66dce58 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -159,6 +159,7 @@ namespace FreeSql.Internal.CommonProvider { if (typeof(TReturn) == typeof(T1)) return this as ISelect; _tables[0].Parameter = select.Parameters[0]; _selectExpression = select.Body; + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TReturn).FullName, true); var ret = _orm.Select(); Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -172,6 +173,7 @@ namespace FreeSql.Internal.CommonProvider { ), SelectTableInfoType.InnerJoin); if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -185,6 +187,7 @@ namespace FreeSql.Internal.CommonProvider { ), SelectTableInfoType.InnerJoin); if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -211,6 +214,7 @@ namespace FreeSql.Internal.CommonProvider { } if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index f439171c..ca0cd16b 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -231,6 +231,7 @@ namespace FreeSql.Internal { $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace}.{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace}.{a.Name}"))}>" : (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace}.{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name}"); + var pnvBind = pnv.GetCustomAttribute()?.Bind.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); var nvref = new TableRef(); nvref.Property = pnv; @@ -241,7 +242,7 @@ namespace FreeSql.Internal { if (trytb.Primarys.Any() == false) { nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {trytbTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) throw nvref.Exception; + //if (isLazy) throw nvref.Exception; continue; } @@ -259,7 +260,7 @@ namespace FreeSql.Internal { if (tbref.Primarys.Any() == false) { nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) throw nvref.Exception; + //if (isLazy) throw nvref.Exception; continue; } @@ -376,14 +377,14 @@ namespace FreeSql.Internal { if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) { nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {trytb.CsName}.{trytb.Primarys[a].CsName} 类型不一致"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) throw nvref.Exception; - continue; + //if (isLazy) throw nvref.Exception; + break; } if (trycol == null) { nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTrytb.Name}{findtrytbPkCsName}、{midTypePropsTrytb.Name}_{findtrytbPkCsName}"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) throw nvref.Exception; - continue; + //if (isLazy) throw nvref.Exception; + break; } nvref.Columns.Add(trytb.Primarys[a]); @@ -397,34 +398,36 @@ namespace FreeSql.Internal { } } - var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; - for (var a = 0; a < tbref.Primarys.Length; a++) { - var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); - if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); - if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 - tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名 - ) { + if (nvref.Exception == null) { + var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; + for (var a = 0; a < tbref.Primarys.Length; a++) { + var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); + if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); + if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 + tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名 + ) { - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) throw nvref.Exception; - continue; - } - if (trycol == null) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTbref.Name}{findtbrefPkCsName}、{midTypePropsTbref.Name}_{findtbrefPkCsName}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) throw nvref.Exception; - continue; - } + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTbref.Name}{findtbrefPkCsName}、{midTypePropsTbref.Name}_{findtbrefPkCsName}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } - nvref.RefColumns.Add(tbref.Primarys[a]); - nvref.MiddleColumns.Add(trycol); - if (tbmid.Primarys.Any() == false) - trycol.Attribute.IsPrimary = true; + nvref.RefColumns.Add(tbref.Primarys[a]); + nvref.MiddleColumns.Add(trycol); + if (tbmid.Primarys.Any() == false) + trycol.Attribute.IsPrimary = true; - if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); + if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); + } } if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) { nvref.RefMiddleEntityType = tbmid.Type; @@ -441,12 +444,17 @@ namespace FreeSql.Internal { .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); if (vp.Item2) { //get 重写 cscode.Append(" get {\r\n") - .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {") - .Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}") - .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace}.{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") - .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();"); - cscode.Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;") - .Append(" }\r\n") + .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); + + if (nvref.Exception == null) + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}") + .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace}.{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") + .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); + else + cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); + + cscode.Append(" }\r\n") .Append(" return base.").Append(pnv.Name).AppendLine(";") .Append(" }\r\n"); } @@ -456,16 +464,39 @@ namespace FreeSql.Internal { cscode.AppendLine(" }"); } } else { //One To Many + List bindColumns = new List(); + if (pnvBind != null) { + foreach(var bi in pnvBind) { + if (tbref.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {tbrefTypeName} 未找到属性:{bi}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + bindColumns.Add(trybindcol); + } + } + + PropertyInfo refprop = null; var refcols = tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type); - var refprop = refcols.Count() == 1 ? refcols.First().Value : null; + refprop = refcols.Count() == 1 ? refcols.First().Value : null; var lmbdWhere = isLazy ? new StringBuilder() : null; - for (var a = 0; a < trytb.Primarys.Length; a++) { + + if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != trytb.Primarys.Length) { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 内部主键数目({trytb.Primarys.Length}) 不相同"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + for (var a = 0; nvref.Exception == null && a < trytb.Primarys.Length; a++) { var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); var findtrytb = pnv.Name; if (findtrytb.EndsWith(tbref.CsName + "s")) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1); findtrytb += trytb.CsName; - if (tbref.ColumnsByCs.TryGetValue($"{findtrytb}{findtrytbPkCsName}", out var trycol) == false && //骆峰命名 + + var trycol = bindColumns.Any() ? bindColumns[a] : null; + if (trycol == null && + tbref.ColumnsByCs.TryGetValue($"{findtrytb}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 tbref.ColumnsByCs.TryGetValue($"{findtrytb}_{findtrytbPkCsName}", out trycol) == false //下划线命名 ) { if (refprop != null && @@ -474,18 +505,18 @@ namespace FreeSql.Internal { { } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) { - nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trytb.Primarys[a].CsName} 和 {tbref.CsName}.{trycol.CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - continue; - } - if (trycol == null) { - nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbref.CsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}" + (refprop == null ? "" : $"、{refprop.Name}{findtrytbPkCsName}、{refprop.Name}_{findtrytbPkCsName}")); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - continue; - } + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) { + nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trytb.Primarys[a].CsName} 和 {tbref.CsName}.{trycol.CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) { + nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbref.CsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}" + (refprop == null ? "" : $"、{refprop.Name}{findtrytbPkCsName}、{refprop.Name}_{findtrytbPkCsName}")); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; } nvref.Columns.Add(trytb.Primarys[a]); @@ -545,20 +576,42 @@ namespace FreeSql.Internal { if (tbref.Primarys.Any() == false) { nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {propTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) throw nvref.Exception; - continue; + //if (isLazy) throw nvref.Exception; } + var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}"; var isOnoToOne = pnv.PropertyType != trytb.Type && tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type).Any() && tbref.Primarys.Length == trytb.Primarys.Length && string.Join(",", tbref.Primarys.Select(a => a.CsType.FullName).OrderBy(a => a)) == string.Join(",", trytb.Primarys.Select(a => a.CsType.FullName).OrderBy(a => a)); + + List bindColumns = new List(); + if (pnvBind != null) { + foreach(var bi in pnvBind) { + if (trytb.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {trytbTypeName} 未找到属性:{bi}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + bindColumns.Add(trybindcol); + } + } var lmbdWhere = new StringBuilder(); - for (var a = 0; a < tbref.Primarys.Length; a++) { + + if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != tbref.Primarys.Length) { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 外部主键数目({tbref.Primarys.Length}) 不相同"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + for (var a = 0; nvref.Exception == null && a < tbref.Primarys.Length; a++) { var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); - if (trytb.ColumnsByCs.TryGetValue($"{pnv.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 + + var trycol = bindColumns.Any() ? bindColumns[a] : null; + if (trycol == null && + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}{findtbrefPkCsName}", out trycol) == false && //骆峰命名 trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_{findtbrefPkCsName}", out trycol) == false && //下划线命名 - //tbref.Primarys.Length == 1 && + //tbref.Primarys.Length == 1 && trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_Id", out trycol) == false && trytb.ColumnsByCs.TryGetValue($"{pnv.Name}Id", out trycol) == false ) { @@ -579,19 +632,18 @@ namespace FreeSql.Internal { } } } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) throw nvref.Exception; - continue; - } } - + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } if (trycol == null) { nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 没有找到对应的字段,如:{pnv.Name}{findtbrefPkCsName}、{pnv.Name}_{findtbrefPkCsName}"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; - continue; + break; } nvref.Columns.Add(trycol); @@ -658,7 +710,7 @@ namespace FreeSql.Internal { } static Lazy MethodLazyLoadingComplier = new Lazy(() => { var type = Type.GetType("FreeSql.Extensions.LazyLoading.LazyLoadingComplier,FreeSql.Extensions.LazyLoading"); - return type.GetMethod("CompileCode"); + return type?.GetMethod("CompileCode"); }); public static T[] GetDbParamtersByObject(string sql, object obj, string paramPrefix, Func constructorParamter) { diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6a343c57..e474560d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.3 + 0.6.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 86d0e7db..6148c2a0 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -13,22 +13,9 @@ using System.Text.RegularExpressions; namespace FreeSql.MySql { - class MySqlCodeFirst : ICodeFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public MySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } + class MySqlCodeFirst : Internal.CommonProvider.CodeFirstProvider { - public bool IsAutoSyncStructure { get; set; } = false; - public bool IsSyncStructureToLower { get; set; } = false; - public bool IsSyncStructureToUpper { get; set; } = false; - public bool IsConfigEntityFromDbFirst { get; set; } = false; - public bool IsNoneCommandParameter { get; set; } = false; - public bool IsLazyLoading { get; set; } = false; + public MySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); static Dictionary _dicCsToDb = new Dictionary() { @@ -64,7 +51,7 @@ namespace FreeSql.MySql { { typeof(MygisMultiPolygon).FullName, (MySqlDbType.Geometry, "multipolygon", "multipolygon", false, null, new MygisMultiPolygon(new[]{new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}}),new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})})) }, }; - public (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; @@ -85,8 +72,7 @@ namespace FreeSql.MySql { return null; } - public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); - public string GetComparisonDDLStatements(params Type[] entityTypes) { + public override string GetComparisonDDLStatements(params Type[] entityTypes) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; Func ExecuteScalar = (db, sql) => { @@ -205,6 +191,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); } //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } @@ -286,40 +273,5 @@ where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbna } } } - - static object syncStructureLock = new object(); - ConcurrentDictionary dicSyced = new ConcurrentDictionary(); - public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); - public bool SyncStructure(params Type[] entityTypes) { - if (entityTypes == null) return true; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray(); - if (syncTypes.Any() == false) return true; - var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); - _orm.Aop.SyncStructureBefore?.Invoke(this, before); - Exception exception = null; - string ddl = null; - try { - lock (syncStructureLock) { - ddl = this.GetComparisonDDLStatements(syncTypes); - if (string.IsNullOrEmpty(ddl)) { - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return true; - } - var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return affrows > 0; - } - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); - _orm.Aop.SyncStructureAfter?.Invoke(this, after); - } - } - public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); - public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); - public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); - public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7cf27c37..280f0170 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.3 + 0.6.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 65a25680..81b5a530 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.3 + 0.6.4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 9209933e..6893b677 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -13,22 +13,9 @@ using System.Text.RegularExpressions; namespace FreeSql.Oracle { - class OracleCodeFirst : ICodeFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public OracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } + class OracleCodeFirst : Internal.CommonProvider.CodeFirstProvider { - public bool IsAutoSyncStructure { get; set; } = false; - public bool IsSyncStructureToLower { get; set; } = false; - public bool IsSyncStructureToUpper { get; set; } = false; - public bool IsConfigEntityFromDbFirst { get; set; } = false; - public bool IsNoneCommandParameter { get; set; } = false; - public bool IsLazyLoading { get; set; } = false; + public OracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); static Dictionary _dicCsToDb = new Dictionary() { @@ -58,7 +45,7 @@ namespace FreeSql.Oracle { { typeof(Guid).FullName, (OracleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OracleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, }; - public (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; @@ -78,8 +65,7 @@ namespace FreeSql.Oracle { return null; } - public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); - public string GetComparisonDDLStatements(params Type[] entityTypes) { + public override string GetComparisonDDLStatements(params Type[] entityTypes) { var userId = (_orm.Ado.MasterPool as OracleConnectionPool).UserId; var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 @@ -333,40 +319,5 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); sqlType += $"({data_length})"; return sqlType; } - - static object syncStructureLock = new object(); - ConcurrentDictionary dicSyced = new ConcurrentDictionary(); - public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); - public bool SyncStructure(params Type[] entityTypes) { - if (entityTypes == null) return true; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray(); - if (syncTypes.Any() == false) return true; - var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); - _orm.Aop.SyncStructureBefore?.Invoke(this, before); - Exception exception = null; - string ddl = null; - try { - lock (syncStructureLock) { - ddl = this.GetComparisonDDLStatements(syncTypes); - if (string.IsNullOrEmpty(ddl)) { - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return true; - } - var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return affrows > 0; - } - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); - _orm.Aop.SyncStructureAfter?.Invoke(this, after); - } - } - public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); - public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); - public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); - public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 8a9ef894..087580ad 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -58,6 +58,9 @@ namespace FreeSql.Oracle { case "interval day to second": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); return OracleDbType.IntervalDS; + case "date": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["date(7)"]); + return OracleDbType.IntervalDS; case "timestamp": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); return OracleDbType.TimeStamp; @@ -106,6 +109,7 @@ namespace FreeSql.Oracle { { "number(10,2)", ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, { "interval day(2) to second(6)", ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date(7)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, { "timestamp(6)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, { "timestamp(6) with local time zone", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f72aa2fd..35993249 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.3 + 0.6.4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 0c7da3c5..4568a53f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -18,22 +18,9 @@ using System.Text.RegularExpressions; namespace FreeSql.PostgreSQL { - class PostgreSQLCodeFirst : ICodeFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public PostgreSQLCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } + class PostgreSQLCodeFirst : Internal.CommonProvider.CodeFirstProvider { - public bool IsAutoSyncStructure { get; set; } = false; - public bool IsSyncStructureToLower { get; set; } = false; - public bool IsSyncStructureToUpper { get; set; } = false; - public bool IsConfigEntityFromDbFirst { get; set; } = false; - public bool IsNoneCommandParameter { get; set; } = false; - public bool IsLazyLoading { get; set; } = false; + public PostgreSQLCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); static Dictionary _dicCsToDb = new Dictionary() { @@ -94,7 +81,7 @@ namespace FreeSql.PostgreSQL { { typeof(PostgisGeometryCollection).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisGeometryCollection(new[]{new PostgisPoint(0, 0),new PostgisPoint(0, 0) })) }, }; - public (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { var isarray = type.FullName != "System.Byte[]" && type.IsArray; var elementType = isarray ? type.GetElementType() : type; var info = GetDbInfoNoneArray(elementType); @@ -122,9 +109,8 @@ namespace FreeSql.PostgreSQL { } return null; } - - public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); - public string GetComparisonDDLStatements(params Type[] entityTypes) { + + public override string GetComparisonDDLStatements(params Type[] entityTypes) { var sb = new StringBuilder(); var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 @@ -338,40 +324,5 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp } return sb.Length == 0 ? null : sb.ToString(); } - - static object syncStructureLock = new object(); - ConcurrentDictionary dicSyced = new ConcurrentDictionary(); - public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); - public bool SyncStructure(params Type[] entityTypes) { - if (entityTypes == null) return true; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray(); - if (syncTypes.Any() == false) return true; - var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); - _orm.Aop.SyncStructureBefore?.Invoke(this, before); - Exception exception = null; - string ddl = null; - try { - lock (syncStructureLock) { - ddl = this.GetComparisonDDLStatements(syncTypes); - if (string.IsNullOrEmpty(ddl)) { - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return true; - } - var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return affrows > 0; - } - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); - _orm.Aop.SyncStructureAfter?.Invoke(this, after); - } - } - public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); - public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); - public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); - public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 06f8c7ab..c75f6439 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.3 + 0.6.4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 4fb6cf4b..1356b66f 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -12,22 +12,9 @@ using System.Text.RegularExpressions; namespace FreeSql.SqlServer { - class SqlServerCodeFirst : ICodeFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public SqlServerCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } - - public bool IsAutoSyncStructure { get; set; } = false; - public bool IsSyncStructureToLower { get; set; } = false; - public bool IsSyncStructureToUpper { get; set; } = false; - public bool IsConfigEntityFromDbFirst { get; set; } = false; - public bool IsNoneCommandParameter { get; set; } = false; - public bool IsLazyLoading { get; set; } = false; + class SqlServerCodeFirst : Internal.CommonProvider.CodeFirstProvider { + + public SqlServerCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); static Dictionary _dicCsToDb = new Dictionary() { @@ -57,7 +44,7 @@ namespace FreeSql.SqlServer { { typeof(Guid).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, }; - public (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; @@ -76,9 +63,8 @@ namespace FreeSql.SqlServer { } return null; } - - public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); - public string GetComparisonDDLStatements(params Type[] entityTypes) { + + public override string GetComparisonDDLStatements(params Type[] entityTypes) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; Func ExecuteScalar = (db, sql) => { @@ -326,41 +312,5 @@ use " + database, tboldname ?? tbname); } return ddv; } - - - static object syncStructureLock = new object(); - ConcurrentDictionary dicSyced = new ConcurrentDictionary(); - public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); - public bool SyncStructure(params Type[] entityTypes) { - if (entityTypes == null) return true; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray(); - if (syncTypes.Any() == false) return true; - var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); - _orm.Aop.SyncStructureBefore?.Invoke(this, before); - Exception exception = null; - string ddl = null; - try { - lock (syncStructureLock) { - ddl = this.GetComparisonDDLStatements(syncTypes); - if (string.IsNullOrEmpty(ddl)) { - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return true; - } - var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return affrows > 0; - } - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); - _orm.Aop.SyncStructureAfter?.Invoke(this, after); - } - } - public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); - public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); - public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); - public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c935571a..db52761c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.3 + 0.6.4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 930580e6..e3fdc8c5 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -12,22 +12,9 @@ using System.Text.RegularExpressions; namespace FreeSql.Sqlite { - class SqliteCodeFirst : ICodeFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public SqliteCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } + class SqliteCodeFirst : Internal.CommonProvider.CodeFirstProvider { - public bool IsAutoSyncStructure { get; set; } = false; - public bool IsSyncStructureToLower { get; set; } = false; - public bool IsSyncStructureToUpper { get; set; } = false; - public bool IsConfigEntityFromDbFirst { get; set; } = false; - public bool IsNoneCommandParameter { get; set; } = false; - public bool IsLazyLoading { get; set; } = false; + public SqliteCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); static Dictionary _dicCsToDb = new Dictionary() { @@ -56,7 +43,7 @@ namespace FreeSql.Sqlite { { typeof(Guid).FullName, (DbType.Guid, "character", "character(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (DbType.Guid, "character", "character(36)", false, true, null) }, }; - public (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; @@ -75,9 +62,8 @@ namespace FreeSql.Sqlite { } return null; } - - public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); - public string GetComparisonDDLStatements(params Type[] entityTypes) { + + public override string GetComparisonDDLStatements(params Type[] entityTypes) { var sb = new StringBuilder(); var sbDeclare = new StringBuilder(); foreach (var entityType in entityTypes) { @@ -250,40 +236,5 @@ namespace FreeSql.Sqlite { return sb.Length == 0 ? null : sb.ToString(); } static Regex _regexUK = new Regex(@"CONSTRAINT\s*""([^""]+)""\s*UNIQUE\s*\(([^\)]+)\)", RegexOptions.IgnoreCase | RegexOptions.Compiled); - - static object syncStructureLock = new object(); - ConcurrentDictionary dicSyced = new ConcurrentDictionary(); - public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); - public bool SyncStructure(params Type[] entityTypes) { - if (entityTypes == null) return true; - var syncTypes = entityTypes.Where(a => a.IsAnonymousType() == false && dicSyced.ContainsKey(a.FullName) == false).ToArray(); - if (syncTypes.Any() == false) return true; - var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); - _orm.Aop.SyncStructureBefore?.Invoke(this, before); - Exception exception = null; - string ddl = null; - try { - lock (syncStructureLock) { - ddl = this.GetComparisonDDLStatements(syncTypes); - if (string.IsNullOrEmpty(ddl)) { - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return true; - } - var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return affrows > 0; - } - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); - _orm.Aop.SyncStructureAfter?.Invoke(this, after); - } - } - public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); - public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); - public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); - public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); } } \ No newline at end of file diff --git a/readme.md b/readme.md index 280951da..9238f0b8 100644 --- a/readme.md +++ b/readme.md @@ -45,7 +45,7 @@ FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程 | FreeSql.Provider.SqlServer | NETStandard2.0、net451 | | FreeSql.Provider.Sqlite | NETStandard2.0、net45 | | FreeSql.Provider.Oracle | NETStandard2.0、net45 | -| FreeSql.Extensions.LazyLoading | NETStandard2.0 | +| FreeSql.Extensions.LazyLoading | NETStandard2.0、net45 | # Quick start From e25a7a484149ce281a4ed28cd9ee3b8ea11d6436 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 31 May 2019 21:13:22 +0800 Subject: [PATCH 0006/1029] update --- FreeSql.Tests/FreeSql.Tests.csproj | 2 +- FreeSql.sln | 28 ---------------------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests.csproj index b778f4e2..9370e56c 100644 --- a/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.csproj @@ -7,6 +7,7 @@ + @@ -14,7 +15,6 @@ - diff --git a/FreeSql.sln b/FreeSql.sln index 912afefe..2e1597bb 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -42,10 +42,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.LazyLoad EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MySqlConnector", "Providers\FreeSql.Provider.MySqlConnector\FreeSql.Provider.MySqlConnector.csproj", "{D2A41321-5E84-410B-B25C-3AA122D4CA27}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.DbContext", "..\FreeSql.DbContext\FreeSql.DbContext\FreeSql.DbContext.csproj", "{9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Repository", "..\FreeSql.DbContext\FreeSql.Repository\FreeSql.Repository.csproj", "{D7A9C833-8679-41B3-8258-757A6FB27A0E}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -224,30 +220,6 @@ Global {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x64.Build.0 = Release|Any CPU {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.ActiveCfg = Release|Any CPU {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.Build.0 = Release|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|x64.ActiveCfg = Debug|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|x64.Build.0 = Debug|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|x86.ActiveCfg = Debug|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Debug|x86.Build.0 = Debug|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|Any CPU.Build.0 = Release|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|x64.ActiveCfg = Release|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|x64.Build.0 = Release|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|x86.ActiveCfg = Release|Any CPU - {9A04925D-4EBA-4B4D-A6DA-F79A41F0F14E}.Release|x86.Build.0 = Release|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|x64.ActiveCfg = Debug|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|x64.Build.0 = Debug|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|x86.ActiveCfg = Debug|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Debug|x86.Build.0 = Debug|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|Any CPU.Build.0 = Release|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|x64.ActiveCfg = Release|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|x64.Build.0 = Release|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|x86.ActiveCfg = Release|Any CPU - {D7A9C833-8679-41B3-8258-757A6FB27A0E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 15ee2a096a6beb68d3a02d845dd15e68aa7dd366 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 1 Jun 2019 01:36:35 +0800 Subject: [PATCH 0007/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=AD=90?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E4=BD=BF=E7=94=A8=E9=9D=9E=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E6=96=B9=E6=B3=95=E6=97=B6=EF=BC=8C=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=97=A0=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.Tests/UnitTest1.cs | 6 ++++++ FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 2 +- FreeSql/Internal/UtilsExpressionTree.cs | 4 ++-- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index dea41cf0..6ad03cd9 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.4 + 0.6.5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 2c7c220c..5fc896a5 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -260,6 +260,12 @@ namespace FreeSql.Tests { [Fact] public void Test1() { + var tsqlddd = g.sqlite.Select().Where(a => + g.sqlite.Select().Where(b => b.NamespaceName == a.ArticleTitle) + .Where("@id=1", new { id = 1 }).Any() + ).ToSql(); + + g.sqlite.SetDbContextOptions(opt => opt.EnableAddOrUpdateNavigateList = true); var trepo = g.sqlite.GetGuidRepository(); trepo.Insert(new TaskBuild { diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b8b8c8e1..f52bc7b2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.4 + 0.6.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 7c1fe876..5225db8d 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -543,7 +543,7 @@ namespace FreeSql.Internal { fsqltable1SetAlias = true; } } - args[a] = argExp; + args[a] = argExp ?? Expression.Lambda(arg3Exp).Compile().DynamicInvoke(); //if (args[a] == null) ExpressionLambdaToSql(call3Exp.Arguments[a], fsqltables, null, null, SelectTableInfoType.From, true); } } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index ca0cd16b..b81b7c1b 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -513,7 +513,7 @@ namespace FreeSql.Internal { break; } if (trycol == null) { - nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbref.CsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}" + (refprop == null ? "" : $"、{refprop.Name}{findtrytbPkCsName}、{refprop.Name}_{findtrytbPkCsName}")); + nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbref.CsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}" + (refprop == null ? "" : $"、{refprop.Name}{findtrytbPkCsName}、{refprop.Name}_{findtrytbPkCsName}。或者使用 [Navigate] 特性指定关系映射。")); trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; break; @@ -640,7 +640,7 @@ namespace FreeSql.Internal { break; } if (trycol == null) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 没有找到对应的字段,如:{pnv.Name}{findtbrefPkCsName}、{pnv.Name}_{findtbrefPkCsName}"); + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 没有找到对应的字段,如:{pnv.Name}{findtbrefPkCsName}、{pnv.Name}_{findtbrefPkCsName}。或者使用 [Navigate] 特性指定关系映射。"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; break; diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e474560d..8544c582 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.4 + 0.6.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 280f0170..4d5696aa 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.4 + 0.6.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 81b5a530..24f4689c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.4 + 0.6.5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 35993249..08f06797 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.4 + 0.6.5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c75f6439..7ba089a9 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.4 + 0.6.5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index db52761c..ae56a12c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.4 + 0.6.5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 3dd60d5492a149f4b5d3116c81bdfa0eb149a375 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Jun 2019 12:40:10 +0800 Subject: [PATCH 0008/1029] =?UTF-8?q?-=20=E9=80=82=E9=85=8D=20FreeSql.Prov?= =?UTF-8?q?ider.MySqlConnector=EF=BC=8C=E5=92=8C=E5=AE=83=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E7=9A=84266=E4=B8=AA=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...eeSql.Tests.Provider.MySqlConnector.csproj | 21 + .../MySqlConnector/Curd/MySqlDeleteTest.cs | 87 + .../MySqlConnector/Curd/MySqlInsertTest.cs | 135 ++ .../MySqlConnector/Curd/MySqlSelectTest.cs | 1231 +++++++++++++ .../MySqlConnector/Curd/MySqlUpdateTest.cs | 186 ++ .../MapType/BoolNullableTest.cs | 1562 +++++++++++++++++ .../MySqlConnector/MapType/BoolTest.cs | 1096 ++++++++++++ .../MySqlConnector/MapType/EnumTest.cs | 254 +++ .../MySqlConnector/MapType/ToStringTest.cs | 557 ++++++ .../MySqlConnector/MySqlCodeFirstTest.cs | 477 +++++ .../MySqlConnectorAdo/MySqlAdoTest.cs | 54 + .../MySqlConnectorExpression/ConvertTest.cs | 146 ++ .../MySqlConnectorExpression/DateTimeTest.cs | 623 +++++++ .../MySqlConnectorExpression/MathTest.cs | 132 ++ .../MySqlConnectorExpression/OtherTest.cs | 121 ++ .../MySqlConnectorExpression/StringTest.cs | 696 ++++++++ .../MySqlConnectorExpression/TimeSpanTest.cs | 260 +++ .../MySqlConnector/MySqlDbFirstTest.cs | 21 + FreeSql.Tests.Provider.MySqlConnector/g.cs | 22 + FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs | 4 +- FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 4 +- .../MySql/MySqlExpression/StringTest.cs | 4 +- FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs | 4 +- FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs | 4 +- .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 4 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 4 +- .../SqlServer/Curd/SqlServerDeleteTest.cs | 4 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 4 +- FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs | 4 +- FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 4 +- FreeSql.Tests/UnitTest1.cs | 2 +- FreeSql.sln | 14 + FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector/Class1.cs | 6 - .../FreeSql.Provider.MySqlConnector.csproj | 7 +- .../MySqlConnectorUtils.cs | 111 ++ .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 41 files changed, 7841 insertions(+), 36 deletions(-) create mode 100644 FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs create mode 100644 FreeSql.Tests.Provider.MySqlConnector/g.cs delete mode 100644 Providers/FreeSql.Provider.MySqlConnector/Class1.cs create mode 100644 Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj b/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj new file mode 100644 index 00000000..7ba5e744 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + + + + + + diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs new file mode 100644 index 00000000..fe402ce3 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs @@ -0,0 +1,87 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector { + public class MySqlDeleteTest { + + IDelete delete => g.mysql.Delete(); //�������� + + [Table(Name = "tb_topic")] + class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + + sql = g.mysql.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + } + + [Fact] + public void Where() { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() { + + } + [Fact] + public void ExecuteAffrows() { + + var id = g.mysql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() { + + //delete.Where(a => a.Id > 0).ExecuteDeleted(); + } + + [Fact] + public void AsTable() { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + + sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs new file mode 100644 index 00000000..ff222517 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs @@ -0,0 +1,135 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector { + public class MySqlInsertTest { + + IInsert insert => g.mysql.Insert(); //�������� + + [Table(Name = "tb_topic")] + class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumInsertTb { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumInserTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumInserTbType { str1, biggit, sum211 } + + [Fact] + public void AppendData() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Now }).ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES(@type_0, @time_0)", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + } + + [Fact] + public void InsertColumns() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + } + [Fact] + public void IgnoreColumns() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + [Fact] + public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + + var id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select< TestEnumInsertTb>().Where(a => a.id == id).First()?.type); + id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void ExecuteInserted() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + //insert.AppendData(items.First()).ExecuteInserted(); + } + + [Fact] + public void AsTable() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs new file mode 100644 index 00000000..19b22f96 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -0,0 +1,1231 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector { + + public class MySqlSelectTest { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + public class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + [Column(OldName = "TypeGuid")] + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + + public virtual TopicFields Fields { get; set; } + } + public class TopicFields { + [Column(IsPrimary = true)] + public int TopicId { get; set; } + public virtual Topic Topic { get; set; } + } + public class TestTypeInfo { + [Column(IsIdentity = true)] + public int Guid { get; set; } + + public int ParentId { get; set; } + public virtual TestTypeParentInfo Parent { get; set; } + + public string Name { get; set; } + + public virtual ICollection Topics { get; set; } + } + public class TestTypeParentInfo { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + public partial class Song { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] + class TestInfo { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AsSelect() { + //OneToOne、ManyToOne + var t0 = g.mysql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.mysql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() { + var tags = g.mysql.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.mysql.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, g.mysql.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, g.mysql.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.mysql.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + + class TestDto { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + var testDto5 = select.Limit(10).ToList(); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + var t0 = select.Limit(50).ToList(); + + + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new { + a.Id, + tp33 = new { + a.Id + } + } + }); + + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.mysql.Select().ToList(a => new { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new { + a.Id, + tp33 = new { + a.Id + } + } + + }); + + var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.mysql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.mysql.Select().ToList(); + var testGuidId6 = g.mysql.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() { + g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); + + var sql1 = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); + var sql2 = g.mysql.Select().Where(a => testenumWhereType.Blaaa == a.type).ToSql(); + + var sql3 = g.mysql.Select().Where(a => a.type.Equals(testenumWhereType.Blaaa)).ToSql(); + var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); + } + class testenumWhere { + public Guid id { get; set; } + public testenumWhereType type { get; set; } + } + public enum testenumWhereType { Menu, Class, Blaaa } + + [Fact] + public void Any() { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + } + [Fact] + public void Master() { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid`", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + + } + [Fact] + public void Where() { + + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TypeGuid` AND b.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = @id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = @id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + + [Fact] + public void OrderBy() { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() { + } + [Fact] + public void Min() { + } + [Fact] + public void Max() { + } + [Fact] + public void Avg() { + } + [Fact] + public void As() { + } + + [Fact] + public void AsTable() { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` c ON c.`Id` = a__Type.`ParentId`", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfoAsTable` c ON b.`ParentId` = c.`Id`", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + } + + public class TestInclude_OneToManyModel1 { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.mysql.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.mysql.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.mysql.Insert(model4s).ExecuteAffrows()); + + var t0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.mysql.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + + var t1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() { + var tag1 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.mysql.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.mysql.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.mysql.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.mysql.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() { + + var tag1 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.mysql.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.mysql.Insert(song1).ExecuteIdentity(); + var song2 = new Song { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.mysql.Insert(song2).ExecuteIdentity(); + var song3 = new Song { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.mysql.Insert(song3).ExecuteIdentity(); + + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs new file mode 100644 index 00000000..f8f12a20 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -0,0 +1,186 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector { + public class MySqlUpdateTest { + IUpdate update => g.mysql.Update(); + + [Table(Name = "tb_topic")] + class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumUpdateTb { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumUpdateTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumUpdateTbType { str1, biggit, sum211 } + + [Fact] + public void Dywhere() { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = @p_0, `Title` = @p_1, `CreateTime` = @p_2 WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, `Title` = CASE `Id` WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, `CreateTime` = CASE `Id` WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = CASE `Id` WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `CreateTime` = @p_0 WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES(@type_0, @time_0)", sql); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0, `time` = @p_1 WHERE (`id` = 0)", sql); + g.mysql.Update().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + id = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); + g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void IgnoreColumns() { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = 0)", sql); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void UpdateColumns() { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = 0)", sql); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Set() { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0, `CreateTime` = @p_1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 / 1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); + + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = {id})", sql); + g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'str1' WHERE (`id` = {id})", sql); + g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void SetRaw() { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET clicks = clicks + @incrClick WHERE (`Id` = 1)", sql); + + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0).SetRaw("`type` = {0}".FormatMySql(TestEnumUpdateTbType.sum211)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Where() { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + + sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) + .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); + } + [Fact] + public void WhereExists() { + + } + [Fact] + public void ExecuteAffrows() { + + } + [Fact] + public void ExecuteUpdated() { + + } + + [Fact] + public void AsTable() { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..5202b06c --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs @@ -0,0 +1,1562 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorMapType { + public class BoolNullableTest { + class BoolNullableMap { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() { + } + [Fact] + public void TimeSpanNullable() { + } + [Fact] + public void DateTime() { + } + [Fact] + public void DateTimeNullable() { + } + + [Fact] + public void ByteArray() { + } + [Fact] + public void String() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() { + } + [Fact] + public void GuidNullable() { + } + + [Fact] + public void MygisPoint() { + } + [Fact] + public void MygisLineString() { + } + [Fact] + public void MygisPolygon() { + } + [Fact] + public void MygisMultiPoint() { + } + [Fact] + public void MygisMultiLineString() { + } + [Fact] + public void MygisMultiPolygon() { + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs new file mode 100644 index 00000000..f6e7bdfe --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs @@ -0,0 +1,1096 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorMapType { + public class BoolTest { + + class BoolMap { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() { + } + [Fact] + public void TimeSpanNullable() { + } + [Fact] + public void DateTime() { + } + [Fact] + public void DateTimeNullable() { + } + + [Fact] + public void ByteArray() { + } + [Fact] + public void String() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() { + } + [Fact] + public void GuidNullable() { + } + + [Fact] + public void MygisPoint() { + } + [Fact] + public void MygisLineString() { + } + [Fact] + public void MygisPolygon() { + } + [Fact] + public void MygisMultiPoint() { + } + [Fact] + public void MygisMultiLineString() { + } + [Fact] + public void MygisMultiPolygon() { + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs new file mode 100644 index 00000000..a5115406 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs @@ -0,0 +1,254 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorMapType { + public class EnumTest { + class EnumTestMap { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs new file mode 100644 index 00000000..ae9f6796 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs @@ -0,0 +1,557 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorMapType { + public class ToStringTest { + class ToStringMap { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs new file mode 100644 index 00000000..6d9b8a46 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -0,0 +1,477 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector { + public class MySqlCodeFirstTest { + + [Fact] + public void ı_ֶ() { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<ı2>(); + g.mysql.CodeFirst.SyncStructure<ı2>(); + + var item = new ı2 { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.mysql.Insert<ı2>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı2 { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } + + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } + + [Fact] + public void AddField() { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + + var id = g.mysql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField { + [Column(IsIdentity = true)] + public int? Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title222 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() { + + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( + `Id` INT(11) NOT NULL AUTO_INCREMENT, + `testFieldBool` BIT(1) NOT NULL, + `testFieldSByte` TINYINT(3) NOT NULL, + `testFieldShort` SMALLINT(6) NOT NULL, + `testFieldInt` INT(11) NOT NULL, + `testFieldLong` BIGINT(20) NOT NULL, + `testFieldByte` TINYINT(3) UNSIGNED NOT NULL, + `testFieldUShort` SMALLINT(5) UNSIGNED NOT NULL, + `testFieldUInt` INT(10) UNSIGNED NOT NULL, + `testFieldULong` BIGINT(20) UNSIGNED NOT NULL, + `testFieldDouble` DOUBLE NOT NULL, + `testFieldFloat` FLOAT NOT NULL, + `testFieldDecimal` DECIMAL(10,2) NOT NULL, + `testFieldTimeSpan` TIME NOT NULL, + `testFieldDateTime` DATETIME(3) NOT NULL, + `testFieldBytes` VARBINARY(255), + `testFieldString` VARCHAR(255), + `testFieldGuid` VARCHAR(36), + `testFieldBoolNullable` BIT(1), + `testFieldSByteNullable` TINYINT(3), + `testFieldShortNullable` SMALLINT(6), + `testFieldIntNullable` INT(11), + `testFielLongNullable` BIGINT(20), + `testFieldByteNullable` TINYINT(3) UNSIGNED, + `testFieldUShortNullable` SMALLINT(5) UNSIGNED, + `testFieldUIntNullable` INT(10) UNSIGNED, + `testFieldULongNullable` BIGINT(20) UNSIGNED, + `testFieldDoubleNullable` DOUBLE, + `testFieldFloatNullable` FLOAT, + `testFieldDecimalNullable` DECIMAL(10,2), + `testFieldTimeSpanNullable` TIME, + `testFieldDateTimeNullable` DATETIME(3), + `testFieldGuidNullable` VARCHAR(36), + `testFieldPoint` POINT, + `testFieldLineString` LINESTRING, + `testFieldPolygon` POLYGON, + `testFieldMultiPoint` MULTIPOINT, + `testFieldMultiLineString` MULTILINESTRING, + `testFieldMultiPolygon` MULTIPOLYGON, + `testFieldEnum1` ENUM('E1','E2','E3') NOT NULL, + `testFieldEnum1Nullable` ENUM('E1','E2','E3'), + `testFieldEnum2` SET('F1','F2','F3') NOT NULL, + `testFieldEnum2Nullable` SET('F1','F2','F3'), + PRIMARY KEY (`Id`) +) Engine=InnoDB; +", sql); + } + + sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.mysql.Insert(); + ISelect select => g.mysql.Select(); + + [Fact] + public void CurdAllField() { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = 255, + testFieldByteNullable = 127, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(-1), + testFieldDecimal = 99.99M, + testFieldDecimalNullable = 99.98M, + testFieldDouble = 999.99, + testFieldDoubleNullable = 999.98, + testFieldEnum1 = TableAllTypeEnumType1.e5, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 19.99F, + testFieldFloatNullable = 19.98F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldLineString = new MygisLineString(new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }), + testFieldLong = long.MaxValue, + testFieldMultiLineString = new MygisMultiLineString(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }, + new[] { new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 100) } }), + testFieldMultiPoint = new MygisMultiPoint(new[] { new MygisCoordinate2D(11, 11), new MygisCoordinate2D(51, 11) }), + testFieldMultiPolygon = new MygisMultiPolygon(new[] { + new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), + new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }) }), + testFieldPoint = new MygisPoint(99, 99), + testFieldPolygon = new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), + testFieldSByte = 100, + testFieldSByteNullable = 99, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "йstring", + testFieldTimeSpan = TimeSpan.FromSeconds(999), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + + var items = select.ToList(); + } + + + [JsonObject(MemberSerialization.OptIn), Table(Name = "tb_alltype")] + public partial class Tb_alltype { + + [JsonProperty, Column(Name = "Id", DbType = "int(11)", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + + [JsonProperty, Column(Name = "testFieldBool", DbType = "bit(1)")] + public bool TestFieldBool { get; set; } + + + [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit(1)", IsNullable = true)] + public bool? TestFieldBoolNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint(3) unsigned")] + public byte TestFieldByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint(3) unsigned", IsNullable = true)] + public byte? TestFieldByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] + public byte[] TestFieldBytes { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] + public DateTime TestFieldDateTime { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] + public DateTime? TestFieldDateTimeNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] + public decimal TestFieldDecimal { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] + public decimal? TestFieldDecimalNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDouble", DbType = "double")] + public double TestFieldDouble { get; set; } + + + [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "double", IsNullable = true)] + public double? TestFieldDoubleNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1", DbType = "enum('E1','E2','E3','E5')")] + public Tb_alltypeTESTFIELDENUM1 TestFieldEnum1 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "enum('E1','E2','E3','E5')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM1NULLABLE? TestFieldEnum1Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2", DbType = "set('F1','F2','F3')")] + public Tb_alltypeTESTFIELDENUM2 TestFieldEnum2 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "set('F1','F2','F3')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM2NULLABLE? TestFieldEnum2Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloat", DbType = "float")] + public float TestFieldFloat { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "float", IsNullable = true)] + public float? TestFieldFloatNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuid", DbType = "char(36)")] + public Guid TestFieldGuid { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "char(36)", IsNullable = true)] + public Guid? TestFieldGuidNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldInt", DbType = "int(11)")] + public int TestFieldInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int(11)", IsNullable = true)] + public int? TestFieldIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldLineString", DbType = "linestring", IsNullable = true)] + public MygisGeometry TestFieldLineString { get; set; } + + + [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint(20)")] + public long TestFieldLong { get; set; } + + + [JsonProperty, Column(Name = "testFieldMultiLineString", DbType = "multilinestring", IsNullable = true)] + public MygisGeometry TestFieldMultiLineString { get; set; } + + + [JsonProperty, Column(Name = "testFieldMultiPoint", DbType = "multipoint", IsNullable = true)] + public MygisGeometry TestFieldMultiPoint { get; set; } + + + [JsonProperty, Column(Name = "testFieldMultiPolygon", DbType = "multipolygon", IsNullable = true)] + public MygisGeometry TestFieldMultiPolygon { get; set; } + + + [JsonProperty, Column(Name = "testFieldPoint", DbType = "point", IsNullable = true)] + public MygisGeometry TestFieldPoint { get; set; } + + + [JsonProperty, Column(Name = "testFieldPolygon", DbType = "polygon", IsNullable = true)] + public MygisGeometry TestFieldPolygon { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint(3)")] + public sbyte TestFieldSByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint(3)", IsNullable = true)] + public sbyte? TestFieldSByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint(6)")] + public short TestFieldShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint(6)", IsNullable = true)] + public short? TestFieldShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldString", DbType = "varchar(255)", IsNullable = true)] + public string TestFieldString { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] + public TimeSpan TestFieldTimeSpan { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] + public TimeSpan? TestFieldTimeSpanNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUInt", DbType = "int(10) unsigned")] + public uint TestFieldUInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int(10) unsigned", IsNullable = true)] + public uint? TestFieldUIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint(20) unsigned")] + public ulong TestFieldULong { get; set; } + + + [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint(20) unsigned", IsNullable = true)] + public ulong? TestFieldULongNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint(5) unsigned")] + public ushort TestFieldUShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint(5) unsigned", IsNullable = true)] + public ushort? TestFieldUShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint(20)", IsNullable = true)] + public long? TestFielLongNullable { get; set; } + + internal static IFreeSql mysql => null; + public static FreeSql.ISelect Select => mysql.Select(); + + public static long Delete(int Id) { + var affrows = mysql.Delete().Where(a => a.Id == Id).ExecuteAffrows(); + return affrows; + } + + /// + /// ӣֵ UpdateӰΪ 0 Insert + /// + public void Save() { + if (this.Id != default(int)) { + var affrows = mysql.Update().Where(a => a.Id == Id).ExecuteAffrows(); + if (affrows > 0) return; + } + this.Id = (int)mysql.Insert().AppendData(this).ExecuteIdentity(); + } + + } + + public enum Tb_alltypeTESTFIELDENUM1 { + E1 = 1, E2, E3, E5 + } + public enum Tb_alltypeTESTFIELDENUM1NULLABLE { + E1 = 1, E2, E3, E5 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2 : long { + F1 = 1, F2 = 2, F3 = 4 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2NULLABLE : long { + F1 = 1, F2 = 2, F3 = 4 + } + + + [Table(Name = "tb_alltype")] + class TableAllType { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public MygisPoint testFieldPoint { get; set; } + public MygisLineString testFieldLineString { get; set; } + public MygisPolygon testFieldPolygon { get; set; } + public MygisMultiPoint testFieldMultiPoint { get; set; } + public MygisMultiLineString testFieldMultiLineString { get; set; } + public MygisMultiPolygon testFieldMultiPolygon { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs new file mode 100644 index 00000000..e2ec87e4 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector { + public class MySqlAdoTest { + [Fact] + public void Pool() { + var t1 = g.mysql.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() { + var t2 = g.mysql.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() { + + } + [Fact] + public void ExecuteArray() { + + } + [Fact] + public void ExecuteNonQuery() { + + } + [Fact] + public void ExecuteScalar() { + + } + + [Fact] + public void Query() { + var t3 = g.mysql.Ado.Query("select * from song"); + + var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + + var t5 = g.mysql.Ado.Query("select * from song"); + } + + [Fact] + public void QueryMultipline() { + var t3 = g.mysql.Ado.Query("select * from song; select * from song; select * from song"); + } + + class xxx { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs new file mode 100644 index 00000000..8aff8e08 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs @@ -0,0 +1,146 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorExpression { + public class ConvertTest { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs new file mode 100644 index 00000000..5dcbc74b --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs @@ -0,0 +1,623 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorExpression { + public class DateTimeTest { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic111333")] + class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] + public void this_Equals() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs new file mode 100644 index 00000000..83d333b5 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs @@ -0,0 +1,132 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorExpression { + public class MathTest { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() { + var data = new List(); + data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() { + var data = new List(); + data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs new file mode 100644 index 00000000..ad037e00 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs @@ -0,0 +1,121 @@ +using FreeSql.DataAnnotations; +using MySql.Data.MySqlClient; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorExpression { + public class OtherTest { + + ISelect select => g.mysql.Select(); + + public OtherTest() { + + } + + [Fact] + public void Boolean() { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } + + [Fact] + public void Array() { + int[] nullarr = null; + Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); + + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public MygisPoint testFieldPoint { get; set; } + public MygisLineString testFieldLineString { get; set; } + public MygisPolygon testFieldPolygon { get; set; } + public MygisMultiPoint testFieldMultiPoint { get; set; } + public MygisMultiLineString testFieldMultiLineString { get; set; } + public MygisMultiPolygon testFieldMultiPolygon { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs new file mode 100644 index 00000000..331170d1 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -0,0 +1,696 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorExpression { + public class StringTest { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid { + public Guid id { get; set; } + public bool IsDeleted { get; set; } + } + + [Fact] + public void Equals__() { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.mysql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); + } + + [Fact] + public void Empty() { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs new file mode 100644 index 00000000..2f4431c3 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs @@ -0,0 +1,260 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorExpression { + public class TimeSpanTest { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs new file mode 100644 index 00000000..86a3aa7d --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs @@ -0,0 +1,21 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector { + public class MySqlDbFirstTest { + [Fact] + public void GetDatabases() { + + var t1 = g.mysql.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() { + + var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); + + } + } +} diff --git a/FreeSql.Tests.Provider.MySqlConnector/g.cs b/FreeSql.Tests.Provider.MySqlConnector/g.cs new file mode 100644 index 00000000..7f1750d7 --- /dev/null +++ b/FreeSql.Tests.Provider.MySqlConnector/g.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + + +public class g { + + static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .Build()); + public static IFreeSql mysql => mysqlLazy.Value; +} diff --git a/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs index 0c018754..d9c34893 100644 --- a/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs @@ -40,8 +40,8 @@ namespace FreeSql.Tests.MySql { var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (id = ?id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = delete.Where(item).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index bf184608..382dca0c 100644 --- a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -279,7 +279,7 @@ namespace FreeSql.Tests.MySql { var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any(c => c.Id == a.Id + 10) ); @@ -697,7 +697,7 @@ namespace FreeSql.Tests.MySql { sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any() diff --git a/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index 30bbb7a6..1b70d10e 100644 --- a/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -41,8 +41,8 @@ namespace FreeSql.Tests.MySqlExpression { public void Equals__() { var list = new List(); list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); - list.Add(g.sqlite.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); - list.Add(g.sqlite.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); + list.Add(g.mysql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } [Fact] diff --git a/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs index 5d31ff17..ece0e712 100644 --- a/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs @@ -40,8 +40,8 @@ namespace FreeSql.Tests.Oracle { var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); - sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = ?id)", sql); + sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = delete.Where(item).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 6167d286..22397b90 100644 --- a/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -174,7 +174,7 @@ namespace FreeSql.Tests.Oracle { var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any(c => c.Id == a.Id + 10) ); @@ -591,7 +591,7 @@ namespace FreeSql.Tests.Oracle { sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any() diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index 4da943ac..aad0a58b 100644 --- a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -40,8 +40,8 @@ namespace FreeSql.Tests.PostgreSQL { var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); - sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (id = ?id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (id = @id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = delete.Where(item).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 08b6a39e..b4ac0f9f 100644 --- a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -244,7 +244,7 @@ namespace FreeSql.Tests.PostgreSQL { var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any(c => c.Id == a.Id + 10) ); @@ -663,7 +663,7 @@ namespace FreeSql.Tests.PostgreSQL { sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any() diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs index 5847adb0..5b11406e 100644 --- a/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs @@ -49,8 +49,8 @@ namespace FreeSql.Tests.SqlServer { var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); - sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = ?id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = @id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = delete.Where(item).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index fa9b68ac..bdc0325b 100644 --- a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -176,7 +176,7 @@ namespace FreeSql.Tests.SqlServer { var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any(c => c.Id == a.Id + 10) ); @@ -594,7 +594,7 @@ namespace FreeSql.Tests.SqlServer { sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any() diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs index 56507ce9..fca1ae13 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs @@ -40,8 +40,8 @@ namespace FreeSql.Tests.Sqlite { var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); - sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (id = ?id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (id = @id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = delete.Where(item).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 4805780d..6b08d8da 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -185,7 +185,7 @@ namespace FreeSql.Tests.Sqlite { var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any(c => c.Id == a.Id + 10) ); @@ -537,7 +537,7 @@ namespace FreeSql.Tests.Sqlite { sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any() diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 5fc896a5..380837af 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -568,7 +568,7 @@ namespace FreeSql.Tests { var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) + //.Offset(a.Id) .Any() ).Any() ).ToList(); diff --git a/FreeSql.sln b/FreeSql.sln index 2e1597bb..78fdd490 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -42,6 +42,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.LazyLoad EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MySqlConnector", "Providers\FreeSql.Provider.MySqlConnector\FreeSql.Provider.MySqlConnector.csproj", "{D2A41321-5E84-410B-B25C-3AA122D4CA27}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Tests.Provider.MySqlConnector", "FreeSql.Tests.Provider.MySqlConnector\FreeSql.Tests.Provider.MySqlConnector.csproj", "{D113CDFB-FB97-482B-8A00-058E715B624A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -220,6 +222,18 @@ Global {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x64.Build.0 = Release|Any CPU {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.ActiveCfg = Release|Any CPU {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.Build.0 = Release|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|x64.ActiveCfg = Debug|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|x64.Build.0 = Debug|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|x86.ActiveCfg = Debug|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|x86.Build.0 = Debug|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|Any CPU.Build.0 = Release|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|x64.ActiveCfg = Release|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|x64.Build.0 = Release|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|x86.ActiveCfg = Release|Any CPU + {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f52bc7b2..e38c5ed5 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.5 + 0.6.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 8544c582..8e19a68f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.5 + 0.6.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/Class1.cs b/Providers/FreeSql.Provider.MySqlConnector/Class1.cs deleted file mode 100644 index e855068e..00000000 --- a/Providers/FreeSql.Provider.MySqlConnector/Class1.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System; - -namespace FreeSql.Provider.MySqlConnector { - public class Class1 { - } -} diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4d5696aa..4c50b8dc 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.5 + 0.6.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 @@ -23,6 +23,11 @@ + + + + + diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs new file mode 100644 index 00000000..37a02a57 --- /dev/null +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -0,0 +1,111 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using MySql.Data.MySqlClient; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace FreeSql.MySql { + + class MySqlUtils : CommonUtils { + public MySqlUtils(IFreeSql orm) : base(orm) { + } + + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) { + if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } else { + ret.MySqlDbType = (MySqlDbType)tp.Value; + if (ret.MySqlDbType == MySqlDbType.Enum && value != null) + ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + } + } + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { + var ret = new MySqlParameter { ParameterName = $"@{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) { + if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } else { + ret.MySqlDbType = (MySqlDbType)tp.Value; + if (ret.MySqlDbType == MySqlDbType.Enum && value != null) + ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + } + } + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); + public override string QuoteSqlName(string name) { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; + } + public override string TrimQuoteSqlName(string name) { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string QuoteWriteParamter(Type type, string paramterName) { + switch (type.FullName) { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})"; + } + return paramterName; + } + + public override string QuoteReadColumn(Type type, string columnName) { + switch (type.FullName) { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"AsText({columnName})"; + } + return columnName; + } + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { + if (value == null) return "NULL"; + if (type == typeof(byte[])) { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("0x"); + foreach (var vc in bytes) { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); + } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { + var ts = (TimeSpan)value; + value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 24f4689c..01d33495 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.5 + 0.6.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 08f06797..cc74e43f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.5 + 0.6.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 7ba089a9..e8d6d575 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.5 + 0.6.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ae56a12c..e58f7ae7 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.5 + 0.6.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From e737a793af462fd76a4bb9272a5a16d906fe5d75 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Jun 2019 17:46:11 +0800 Subject: [PATCH 0009/1029] update --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 9238f0b8..ee422cfc 100644 --- a/readme.md +++ b/readme.md @@ -35,6 +35,7 @@ FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程 - FreeSql.DbContext 是扩展包,提供面向对象的用法(像EF); - FreeSql.Repository 也是扩展包,提供仓储+工作单元用法; - FreeSql.Connection.Extensions 也是扩展包,提供像 Dapper 一样的用法; +- [FreeSql.Tools 生成器](https://github.com/2881099/FreeSql.Tools),基于 razor 模板的生成器; # Providers From 93bbcaebbfdbaf082becbdce5d1e4c6a7b92a336 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 4 Jun 2019 10:56:14 +0800 Subject: [PATCH 0010/1029] =?UTF-8?q?=E5=A4=84=E7=90=86=20=E9=9D=9E?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8=20Provider=20GC=20=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E4=B8=BA=20null=20=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.MySql/MySqlProvider.cs | 2 +- Providers/FreeSql.Provider.Oracle/OracleProvider.cs | 2 +- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs | 2 +- Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs | 2 +- Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index 2e032f27..461274fc 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -71,7 +71,7 @@ namespace FreeSql.MySql { bool _isdisposed = false; public void Dispose() { if (_isdisposed) return; - (this.Ado as AdoProvider).Dispose(); + (this.Ado as AdoProvider)?.Dispose(); } } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index 2f2e7f44..16ae24c3 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -48,7 +48,7 @@ namespace FreeSql.Oracle { bool _isdisposed = false; public void Dispose() { if (_isdisposed) return; - (this.Ado as AdoProvider).Dispose(); + (this.Ado as AdoProvider)?.Dispose(); } } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index bca60aa3..7f73ee10 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -98,7 +98,7 @@ namespace FreeSql.PostgreSQL { bool _isdisposed = false; public void Dispose() { if (_isdisposed) return; - (this.Ado as AdoProvider).Dispose(); + (this.Ado as AdoProvider)?.Dispose(); } } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index a2d03c74..f6abcc0d 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -55,7 +55,7 @@ namespace FreeSql.SqlServer { bool _isdisposed = false; public void Dispose() { if (_isdisposed) return; - (this.Ado as AdoProvider).Dispose(); + (this.Ado as AdoProvider)?.Dispose(); } } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index cfb02e77..73948db3 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -47,7 +47,7 @@ namespace FreeSql.Sqlite { bool _isdisposed = false; public void Dispose() { if (_isdisposed) return; - (this.Ado as AdoProvider).Dispose(); + (this.Ado as AdoProvider)?.Dispose(); } } } From 0c575c7b566213b45ff5a9722c085b4e4f3ef1ac Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 5 Jun 2019 15:42:44 +0800 Subject: [PATCH 0011/1029] update --- FreeSql.Tests/UnitTest1.cs | 3 +++ readme.md | 1 + 2 files changed, 4 insertions(+) diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 380837af..6527efef 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -260,6 +260,9 @@ namespace FreeSql.Tests { [Fact] public void Test1() { + + var ttdkdk = g.mysql.Select().Where(a => a.NamespaceName == "ddd").ToSql(); + var tsqlddd = g.sqlite.Select().Where(a => g.sqlite.Select().Where(b => b.NamespaceName == a.ArticleTitle) .Where("@id=1", new { id = 1 }).Any() diff --git a/readme.md b/readme.md index ee422cfc..4d0f0936 100644 --- a/readme.md +++ b/readme.md @@ -36,6 +36,7 @@ FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程 - FreeSql.Repository 也是扩展包,提供仓储+工作单元用法; - FreeSql.Connection.Extensions 也是扩展包,提供像 Dapper 一样的用法; - [FreeSql.Tools 生成器](https://github.com/2881099/FreeSql.Tools),基于 razor 模板的生成器; +- [ABP 使用 FreeSql ORM](https://github.com/gnsilence/JPGZService),测试中...; # Providers From 16c6fc334bb0f69650ac1577bde87d1dd9ac4419 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 6 Jun 2019 12:12:43 +0800 Subject: [PATCH 0012/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.Orde?= =?UTF-8?q?rBy=20=E9=87=8D=E8=BD=BD=EF=BC=8C=E4=B8=8E=20WhereIf=20?= =?UTF-8?q?=E7=9B=B8=E5=90=8C=E8=A1=8C=E4=B8=BA=EF=BC=9B=20-=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20Aop.ParseExpression=20=E4=BD=BF=E7=94=A8=20FreePars?= =?UTF-8?q?e=20=E6=96=B9=E6=B3=95=E6=AD=BB=E5=BE=AA=E7=8E=AF=E7=9A=84=20bu?= =?UTF-8?q?g=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.Tests/UnitTest1.cs | 34 +++++++++++++++++++ FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 28 ++++++++++++++- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 10 +++++- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 15 ++++++++ FreeSql/Internal/CommonExpression.cs | 2 +- .../SelectProvider/Select0Provider.cs | 4 ++- .../SelectProvider/Select1Provider.cs | 31 +++++++++++++---- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 15 files changed, 121 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6ad03cd9..43c2ea14 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.5 + 0.6.7 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 6527efef..7f1a36f2 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -258,9 +258,43 @@ namespace FreeSql.Tests { public Templates Templates { get; set; } } + public class SqlFunc { + public static string FormatDateTime() { + return ""; + } + } + [Fact] public void Test1() { +g.sqlite.Aop.ParseExpression = (s, e) => { + if (e.Expression.NodeType == ExpressionType.Call) { + var callExp = e.Expression as MethodCallExpression; + if (callExp.Object.Type == typeof(DateTime) && + callExp.Method.Name == "ToString" && + callExp.Arguments.Count == 1 && + callExp.Arguments[0].Type == typeof(string) && + callExp.Arguments[0].NodeType == ExpressionType.Constant) { + var format = (callExp.Arguments[0] as ConstantExpression)?.Value?.ToString(); + + if (string.IsNullOrEmpty(format) == false) { + var tmp = e.FreeParse(callExp.Object); + + switch(format) { + case "yyyy-MM-dd HH:mm": + tmp = $"date_format({tmp}, '%Y-%m-%d %H:%i')"; + break; + } + e.Result = tmp; + } + } + } +}; + + g.mysql.Select().ToList(a => new { + testaddtime = a.testaddtime.ToString("yyyy-MM-dd HH:mm") + }); + var ttdkdk = g.mysql.Select().Where(a => a.NamespaceName == "ddd").ToSql(); var tsqlddd = g.sqlite.Select().Where(a => diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e38c5ed5..b0992a4a 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.6 + 0.6.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index dcb10d9c..40fae6b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -893,12 +893,21 @@ - 按原生sql语法排序,OrderBy("count(name) + ?cc", new { cc = 1 }) + 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) sql语法 参数 + + + 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + + true 时生效 + sql语法 + 参数 + + 查询向后偏移行数 @@ -1230,6 +1239,15 @@ + + + 按列排序,OrderBy(true, a => a.Time) + + + true 时生效 + + + 按列倒向排序,OrderByDescending(a => a.Time) @@ -1237,6 +1255,14 @@ + + + 按列倒向排序,OrderByDescending(true, a => a.Time) + + true 时生效 + 列 + + 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 636124c8..d162d72a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -203,12 +203,20 @@ namespace FreeSql { TSelect Having(string sql, object parms = null); /// - /// 按原生sql语法排序,OrderBy("count(name) + ?cc", new { cc = 1 }) + /// 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) /// /// sql语法 /// 参数 /// TSelect OrderBy(string sql, object parms = null); + /// + /// 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + /// + /// true 时生效 + /// sql语法 + /// 参数 + /// + TSelect OrderBy(bool condition, string sql, object parms = null); /// /// 查询向后偏移行数 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 3abdf2ed..0c5f2ce2 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -288,11 +288,26 @@ namespace FreeSql { /// ISelect OrderBy(Expression> column); /// + /// 按列排序,OrderBy(true, a => a.Time) + /// + /// + /// true 时生效 + /// + /// + ISelect OrderBy(bool condition, Expression> column); + /// /// 按列倒向排序,OrderByDescending(a => a.Time) /// /// 列 /// ISelect OrderByDescending(Expression> column); + /// + /// 按列倒向排序,OrderByDescending(true, a => a.Time) + /// + /// true 时生效 + /// 列 + /// + ISelect OrderByDescending(bool condition, Expression> column); /// /// 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 5225db8d..69aee515 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -929,7 +929,7 @@ namespace FreeSql.Internal { getSelectGroupingMapString = this.getSelectGroupingMapString, tbtype = this.tbtype, isQuoteName = this.isQuoteName, - isDisableDiyParse = false, + isDisableDiyParse = true, style = this.style, currentTable = this.currentTable }; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 9a7fe7c5..bb43b573 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -182,7 +182,9 @@ namespace FreeSql.Internal.CommonProvider { } public TSelect Offset(int offset) => this.Skip(offset) as TSelect; - public TSelect OrderBy(string sql, object parms = null) { + public TSelect OrderBy(string sql, object parms = null) => this.OrderBy(true, sql, parms); + public TSelect OrderBy(bool condition, string sql, object parms = null) { + if (condition == false) return this as TSelect; if (string.IsNullOrEmpty(sql)) _orderby = null; var isnull = string.IsNullOrEmpty(_orderby); _orderby = string.Concat(isnull ? " \r\nORDER BY " : "", _orderby, isnull ? "" : ", ", sql); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index e66dce58..0f2ee90e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -40,8 +40,24 @@ namespace FreeSql.Internal.CommonProvider { if (whereIfCond == "1" || whereIfCond == "'t'") this.InternalWhere(expCall.Arguments[1]); break; - case "OrderBy": this.InternalOrderBy(expCall.Arguments[0]); break; - case "OrderByDescending": this.InternalOrderByDescending(expCall.Arguments[0]); break; + case "OrderBy": + if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) { + var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); + if (ifcond == "1" || ifcond == "'t'") + this.InternalOrderBy(expCall.Arguments.LastOrDefault()); + break; + } + this.InternalOrderBy(expCall.Arguments.LastOrDefault()); + break; + case "OrderByDescending": + if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) { + var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); + if (ifcond == "1" || ifcond == "'t'") + this.InternalOrderByDescending(expCall.Arguments.LastOrDefault()); + break; + } + this.InternalOrderByDescending(expCall.Arguments.LastOrDefault()); + break; case "LeftJoin": this.InternalJoin(expCall.Arguments[0], SelectTableInfoType.LeftJoin); break; case "InnerJoin": this.InternalJoin(expCall.Arguments[0], SelectTableInfoType.InnerJoin); break; @@ -113,14 +129,15 @@ namespace FreeSql.Internal.CommonProvider { _tables[0].Parameter = column.Parameters[0]; return this.InternalMinAsync(column?.Body); } - - public ISelect OrderBy(Expression> column) { - if (column == null) return this; + public ISelect OrderBy(Expression> column) => this.OrderBy(true, column); + public ISelect OrderBy(bool condition, Expression> column) { + if (condition == false || column == null) return this; _tables[0].Parameter = column.Parameters[0]; return this.InternalOrderBy(column?.Body); } - public ISelect OrderByDescending(Expression> column) { - if (column == null) return this; + public ISelect OrderByDescending(Expression> column) => this.OrderByDescending(true, column); + public ISelect OrderByDescending(bool condition, Expression> column) { + if (condition == false || column == null) return this; _tables[0].Parameter = column.Parameters[0]; return this.InternalOrderByDescending(column?.Body); } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 8e19a68f..11d633ad 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.6 + 0.6.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4c50b8dc..ff9c3512 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.6 + 0.6.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 01d33495..a995bb46 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.6 + 0.6.7 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index cc74e43f..17cd460f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.6 + 0.6.7 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e8d6d575..a7755327 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.6 + 0.6.7 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e58f7ae7..5170bd65 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.6 + 0.6.7 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From e62890bbfba85e663f18c633828c048ae89c24ad Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 6 Jun 2019 12:24:07 +0800 Subject: [PATCH 0013/1029] update 0.6.8 --- FreeSql.Tests/UnitTest1.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 7f1a36f2..e5a468c2 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -267,7 +267,7 @@ namespace FreeSql.Tests { [Fact] public void Test1() { -g.sqlite.Aop.ParseExpression = (s, e) => { +g.mysql.Aop.ParseExpression = (s, e) => { if (e.Expression.NodeType == ExpressionType.Call) { var callExp = e.Expression as MethodCallExpression; if (callExp.Object.Type == typeof(DateTime) && diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b0992a4a..4c32cb45 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.7 + 0.6.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 69aee515..95365fa7 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -402,7 +402,7 @@ namespace FreeSql.Internal { public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) { if (exp == null) return ""; if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpression != null) { - var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(exp, tsc.CloneDisableDiyParse())); + var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, tsc.CloneDisableDiyParse())); _common._orm.Aop.ParseExpression?.Invoke(this, args); if (string.IsNullOrEmpty(args.Result) == false) return args.Result; } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 11d633ad..b38829be 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.7 + 0.6.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ff9c3512..b71a761b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.7 + 0.6.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a995bb46..3c8d59c9 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.7 + 0.6.8 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 17cd460f..d625393e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.7 + 0.6.8 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a7755327..2959a9b2 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.7 + 0.6.8 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5170bd65..f021b60d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.7 + 0.6.8 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From eb2d258f080ae09f8885e18dce69f0e1da0f905e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 6 Jun 2019 12:37:05 +0800 Subject: [PATCH 0014/1029] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E9=80=9F=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 16 ++++++++-------- FreeSql.Tests/UnitTest1.cs | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 43c2ea14..17df14ce 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.7 + 0.6.8 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 6b08d8da..de328f03 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -489,32 +489,32 @@ namespace FreeSql.Tests.Sqlite { query = select.WhereIf(false, a => a.Id == 10); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.ToList(); + query.First(); query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.ToList(); + query.First(); query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.ToList(); + query.First(); query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.ToList(); + query.First(); query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.ToList(); + query.First(); query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.ToList(); + query.First(); //����һ�� From ��Ķ������ query2 = select.From((s, b, c) => s @@ -522,13 +522,13 @@ namespace FreeSql.Tests.Sqlite { .WhereIf(false, a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b, \"TestTypeParentInfo\" c", sql); - query2.ToList(); + query2.First(); //������϶����㲻�� query = select.WhereIf(false, "a.\"Clicks\" > 100 and a.\"Id\" = @id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.ToList(); + query.First(); } [Fact] public void WhereExists() { diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index e5a468c2..d6aa8ea1 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -270,7 +270,7 @@ namespace FreeSql.Tests { g.mysql.Aop.ParseExpression = (s, e) => { if (e.Expression.NodeType == ExpressionType.Call) { var callExp = e.Expression as MethodCallExpression; - if (callExp.Object.Type == typeof(DateTime) && + if (callExp.Object?.Type == typeof(DateTime) && callExp.Method.Name == "ToString" && callExp.Arguments.Count == 1 && callExp.Arguments[0].Type == typeof(string) && From fe6d6326243219df2904f5c19ed40e818bdb0920 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 7 Jun 2019 18:23:51 +0800 Subject: [PATCH 0015/1029] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E6=8F=92=E5=85=A5/=E6=9B=B4=E6=96=B0=E5=A4=A7=E9=87=8F?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=97=B6=EF=BC=8C=E6=9C=AA=E4=BD=BF=E7=94=A8?= =?UTF-8?q?NoneParameter=EF=BC=8C=E4=BC=9A=E5=AF=BC=E8=87=B4=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=9C=AA=E6=89=A7=E8=A1=8C=E7=9A=84bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.Tests/UnitTest1.cs | 12 ++++++++++++ FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonProvider/InsertProvider.cs | 2 +- FreeSql/Internal/CommonProvider/UpdateProvider.cs | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 17df14ce..3a490ea7 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.8 + 0.6.9 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index d6aa8ea1..ea48b4ca 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -267,6 +267,18 @@ namespace FreeSql.Tests { [Fact] public void Test1() { + var testaddlist = new List(); + for(var a = 0; a < 133905; a++) { + testaddlist.Add(new NewsArticle { + ArticleTitle = "testaddlist_topic" + a, + Hits = a, + }); + } + g.sqlite.Insert(testaddlist) + //.NoneParameter() + .ExecuteAffrows(); + + g.mysql.Aop.ParseExpression = (s, e) => { if (e.Expression.NodeType == ExpressionType.Call) { var callExp = e.Expression as MethodCallExpression; diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4c32cb45..499c1ef9 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.8 + 0.6.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index b9095eb0..9ebdc0ed 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -91,7 +91,7 @@ namespace FreeSql.Internal.CommonProvider { var pamTotal = colSum * _source.Count; if (pamTotal < parameterLimit) return new[] { _source }; - var execCount = (int)Math.Ceiling(1.0 * pamTotal / parameterLimit); + var execCount = (int)Math.Ceiling(1.0 * pamTotal / takeMax / colSum); var ret = new List[execCount]; for (var a = 0; a < execCount; a++) { var subSource = new List(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index e34d715a..c5d17d13 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -96,7 +96,7 @@ namespace FreeSql.Internal.CommonProvider { var pamTotal = colSum * _source.Count; if (pamTotal < parameterLimit) return new[] { _source }; - var execCount = (int)Math.Ceiling(1.0 * pamTotal / parameterLimit); + var execCount = (int)Math.Ceiling(1.0 * pamTotal / takeMax / colSum); var ret = new List[execCount]; for (var a = 0; a < execCount; a++) { var subSource = new List(); diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b38829be..93c45632 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.8 + 0.6.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index b71a761b..5e1ce63f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.8 + 0.6.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 3c8d59c9..b53610f6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.8 + 0.6.9 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d625393e..896c9f4f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.8 + 0.6.9 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2959a9b2..fc9e1384 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.8 + 0.6.9 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f021b60d..5e3e0aaa 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.8 + 0.6.9 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From d54ebf3a0418e636d34f80f0b5fe180b3d66ecfd Mon Sep 17 00:00:00 2001 From: stulzq Date: Thu, 13 Jun 2019 14:42:48 +0800 Subject: [PATCH 0016/1029] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=AE=9E=E4=BD=93=E5=B1=9E=E6=80=A7=E5=90=8D?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSqlBuilder.cs | 140 ++++++++++++++++++++------ FreeSql/Internal/StringConvertType.cs | 45 +++++++++ FreeSql/Internal/StringUtils.cs | 20 ++++ 3 files changed, 174 insertions(+), 31 deletions(-) create mode 100644 FreeSql/Internal/StringConvertType.cs create mode 100644 FreeSql/Internal/StringUtils.cs diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 8e49e579..6574371e 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -1,12 +1,12 @@ -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.Logging; -using System; +using System; using System.Data.Common; +using System.Linq; +using System.Reflection; +using FreeSql.DataAnnotations; +using FreeSql.Internal; namespace FreeSql { public class FreeSqlBuilder { - IDistributedCache _cache; - ILogger _logger; DataType _dataType; string _masterConnectionString; string[] _slaveConnectionString; @@ -16,28 +16,10 @@ namespace FreeSql { bool _isConfigEntityFromDbFirst = false; bool _isNoneCommandParameter = false; bool _isLazyLoading = false; + StringConvertType _entityPropertyConvertType = StringConvertType.None; Action _aopCommandExecuting = null; Action _aopCommandExecuted = null; - /// - /// 使用缓存,不指定默认使用内存 - /// - /// 缓存实现 - /// - public FreeSqlBuilder UseCache(IDistributedCache cache) { - _cache = cache; - return this; - } - - /// - /// 使用日志,不指定默认输出控制台 - /// - /// - /// - public FreeSqlBuilder UseLogger(ILogger logger) { - _logger = logger; - return this; - } /// /// 使用连接串 /// @@ -124,17 +106,45 @@ namespace FreeSql { return this; } - public IFreeSql Build() => Build(); + /// + /// 自动转换实体属性名称 Entity Property -> Db Filed + /// + /// *不会覆盖 [Column] 特性设置的Name + /// + /// + /// + public FreeSqlBuilder UseEntityPropertyNameConvert(StringConvertType convertType) + { + _entityPropertyConvertType = convertType; + return this; + } + + public IFreeSql Build() => Build(); public IFreeSql Build() { + if (string.IsNullOrEmpty(_masterConnectionString)) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString"); IFreeSql ret = null; + Type type = null; switch(_dataType) { - case DataType.MySql: ret = new MySql.MySqlProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break; - case DataType.SqlServer: ret = new SqlServer.SqlServerProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break; - case DataType.PostgreSQL: ret = new PostgreSQL.PostgreSQLProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break; - case DataType.Oracle: ret = new Oracle.OracleProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break; - case DataType.Sqlite: ret = new Sqlite.SqliteProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break; + case DataType.MySql: + type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); + if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); + break; + case DataType.SqlServer: type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); + break; + case DataType.PostgreSQL: type = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); + break; + case DataType.Oracle: type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); + break; + case DataType.Sqlite: type = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); + break; default: throw new Exception("未指定 UseConnectionString"); } + ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql; if (ret != null) { ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure; @@ -146,7 +156,75 @@ namespace FreeSql { var ado = ret.Ado as Internal.CommonProvider.AdoProvider; ado.AopCommandExecuting += _aopCommandExecuting; ado.AopCommandExecuted += _aopCommandExecuted; - } + + //添加实体属性名全局AOP转换处理 + if (_entityPropertyConvertType != StringConvertType.None) + { + // 局部方法判断是否存在Column特性以及是否设置Name的值 + bool CheckEntityPropertyColumnAttribute(PropertyInfo propertyInfo) + { + var attr = propertyInfo.GetCustomAttribute(); + if (attr == null || string.IsNullOrEmpty(attr.Name)) + { + return true; + } + + return false; + } + + switch (_entityPropertyConvertType) + { + case StringConvertType.Lower: + ret.Aop.ConfigEntityProperty = (s, e) => + { + if (CheckEntityPropertyColumnAttribute(e.Property)) + { + e.ModifyResult.Name = e.Property.Name.ToLower(); + } + }; + break; + case StringConvertType.Upper: + ret.Aop.ConfigEntityProperty = (s, e) => + { + if (CheckEntityPropertyColumnAttribute(e.Property)) + { + e.ModifyResult.Name = e.Property.Name.ToUpper(); + } + }; + break; + case StringConvertType.PascalCaseToUnderscore: + ret.Aop.ConfigEntityProperty = (s, e) => + { + if (CheckEntityPropertyColumnAttribute(e.Property)) + { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); + } + }; + break; + case StringConvertType.PascalCaseToUnderscoreWithLower: + ret.Aop.ConfigEntityProperty = (s, e) => + { + if (CheckEntityPropertyColumnAttribute(e.Property)) + { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); + } + }; + break; + case StringConvertType.PascalCaseToUnderscoreWithUpper: + ret.Aop.ConfigEntityProperty = (s, e) => + { + if (CheckEntityPropertyColumnAttribute(e.Property)) + { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); + } + }; + break; + default: + break; + } + } + } + return ret; } } diff --git a/FreeSql/Internal/StringConvertType.cs b/FreeSql/Internal/StringConvertType.cs new file mode 100644 index 00000000..281fe8fa --- /dev/null +++ b/FreeSql/Internal/StringConvertType.cs @@ -0,0 +1,45 @@ +namespace FreeSql.Internal +{ + public enum StringConvertType + { + /// + /// 不进行任何处理 + /// + None = 0, + + /// + /// 将帕斯卡命名字符串转换为下划线分隔字符串 + /// + /// BigApple -> Big_Apple + /// + PascalCaseToUnderscore, + + /// + /// 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + /// + /// BigApple -> BIG_APPLE + /// + PascalCaseToUnderscoreWithUpper, + + /// + /// 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + /// + /// BigApple -> big_apple + /// + PascalCaseToUnderscoreWithLower, + + /// + /// 将字符串转换为大写 + /// + /// BigApple -> BIGAPPLE + /// + Upper, + + /// + /// 将字符串转换为小写 + /// + /// BigApple -> bigapple + /// + Lower + } +} \ No newline at end of file diff --git a/FreeSql/Internal/StringUtils.cs b/FreeSql/Internal/StringUtils.cs new file mode 100644 index 00000000..6ec4819b --- /dev/null +++ b/FreeSql/Internal/StringUtils.cs @@ -0,0 +1,20 @@ +using System.Linq; + +namespace FreeSql.Internal +{ + public static class StringUtils + { + /// + /// 将帕斯卡命名字符串转换为下划线分隔字符串 + /// + /// BigApple -> Big_Apple + /// + /// + /// + public static string PascalCaseToUnderScore(string str) + { + return string.Concat(str.Select((x, i) => + i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); + } + } +} \ No newline at end of file From 38d51a809df1a10fd15078be2c69fd50fcde27c1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 13 Jun 2019 20:04:08 +0800 Subject: [PATCH 0017/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20TableAttribu?= =?UTF-8?q?te=20=E7=89=B9=E6=80=A7=E5=B1=9E=E6=80=A7=20DisableSyncStructur?= =?UTF-8?q?e=EF=BC=8C=E5=BD=93=E5=AE=9E=E4=BD=93=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=E7=9A=84=E6=98=AF=E8=A7=86=E5=9B=BE=E6=97=B6=EF=BC=8C=E5=8F=AF?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=9C=AC=E5=8A=9F=E8=83=BD=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=20#61=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20Fr?= =?UTF-8?q?eeSqlBuilder=20UseEntityPropertyNameConvert()=20=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E8=BD=AC=E6=8D=A2=E5=AE=9E=E4=BD=93=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=90=8D=E6=96=B9=E6=B3=95=20#60=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../DataAnnotations/MySqlFluentTest.cs | 17 +++ .../DataAnnotations/SqlServerFluentTest.cs | 17 +++ FreeSql/DataAnnotations/TableAttribute.cs | 6 ++ FreeSql/DataAnnotations/TableFluent.cs | 16 +++ FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 73 +++++++++++++ FreeSql/FreeSqlBuilder.cs | 102 ++++++------------ .../CommonProvider/CodeFirstProvider.cs | 6 +- FreeSql/Internal/CommonUtils.cs | 4 + FreeSql/Internal/Model/TableInfo.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 1 + .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 180 insertions(+), 79 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 3a490ea7..80f24053 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index d373da3f..815821ec 100644 --- a/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -1,4 +1,5 @@ using FreeSql.DataAnnotations; +using MySql.Data.MySqlClient; using System; using System.Linq; using Xunit; @@ -9,6 +10,22 @@ namespace FreeSql.Tests.DataAnnotations { public MySqlFluentTest() { } + [Fact] + public void DisableSyncStructure() { + Assert.Throws(() => g.mysql.Select().ToList()); + + g.mysql.Select().ToList(); + } + [Table(DisableSyncStructure = true)] + class ModelDisableSyncStructure { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + class ModelSyncStructure { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + [Fact] public void AopConfigEntity() { g.mysql.CodeFirst.ConfigEntity(a => a.Property(b => b.pkid).IsPrimary(true)); diff --git a/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs b/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs index c178dcb7..f4354f51 100644 --- a/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs +++ b/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs @@ -1,6 +1,7 @@ using FreeSql.DataAnnotations; using FreeSql.Tests.DataContext.SqlServer; using System; +using System.Data.SqlClient; using Xunit; namespace FreeSql.Tests.DataAnnotations { @@ -14,6 +15,22 @@ namespace FreeSql.Tests.DataAnnotations { _sqlserverFixture = sqlserverFixture; } + [Fact] + public void DisableSyncStructure() { + Assert.Throws(() => _sqlserverFixture.SqlServer.Select().ToList()); + + _sqlserverFixture.SqlServer.Select().ToList(); + } + [Table(DisableSyncStructure = true)] + class ModelDisableSyncStructure { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + class ModelSyncStructure { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + [Fact] public void Fluent() { _sqlserverFixture.SqlServer.CodeFirst diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index fe6788a5..c1061e93 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -17,6 +17,12 @@ namespace FreeSql.DataAnnotations { /// public string SelectFilter { get; set; } + internal bool? _DisableSyncStructure; + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; } + internal ConcurrentDictionary _columns { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); } } diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 781a812b..64383cd4 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -38,6 +38,14 @@ namespace FreeSql.DataAnnotations { return this; } + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public TableFluent DisableSyncStructure(bool value) { + _table.DisableSyncStructure = value; + return this; + } + public ColumnFluent Property(string proto) { if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto }); @@ -74,6 +82,14 @@ namespace FreeSql.DataAnnotations { return this; } + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public TableFluent DisableSyncStructure(bool value) { + _table.DisableSyncStructure = value; + return this; + } + public ColumnFluent Property(Expression> column) { var proto = (column.Body as MemberExpression)?.Member; if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 499c1ef9..cd3eb7be 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 40fae6b3..77e52249 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -133,6 +133,11 @@ 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + + + 禁用 CodeFirst 同步结构迁移 + + 数据库表名 @@ -148,6 +153,11 @@ 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + + + 禁用 CodeFirst 同步结构迁移 + + 数据库表名 @@ -163,6 +173,11 @@ 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + + + 禁用 CodeFirst 同步结构迁移 + + 所属表 @@ -480,6 +495,15 @@ 执行后,可监视执行性能 + + + 自动转换实体属性名称 Entity Property -> Db Filed + + *不会覆盖 [Column] 特性设置的Name + + + + 指定事务对象 @@ -2251,6 +2275,55 @@ 中间表,多对多 + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + 测量两个经纬度的距离,返回单位:米 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 6574371e..56fca2a8 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -147,7 +147,7 @@ namespace FreeSql { ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql; if (ret != null) { ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure; - + ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower; ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper; ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst; @@ -157,73 +157,39 @@ namespace FreeSql { ado.AopCommandExecuting += _aopCommandExecuting; ado.AopCommandExecuted += _aopCommandExecuted; - //添加实体属性名全局AOP转换处理 - if (_entityPropertyConvertType != StringConvertType.None) - { - // 局部方法判断是否存在Column特性以及是否设置Name的值 - bool CheckEntityPropertyColumnAttribute(PropertyInfo propertyInfo) - { - var attr = propertyInfo.GetCustomAttribute(); - if (attr == null || string.IsNullOrEmpty(attr.Name)) - { - return true; - } - - return false; - } - - switch (_entityPropertyConvertType) - { - case StringConvertType.Lower: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = e.Property.Name.ToLower(); - } - }; - break; - case StringConvertType.Upper: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = e.Property.Name.ToUpper(); - } - }; - break; - case StringConvertType.PascalCaseToUnderscore: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); - } - }; - break; - case StringConvertType.PascalCaseToUnderscoreWithLower: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); - } - }; - break; - case StringConvertType.PascalCaseToUnderscoreWithUpper: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); - } - }; - break; - default: - break; - } - } - } + //添加实体属性名全局AOP转换处理 + if (_entityPropertyConvertType != StringConvertType.None) { + switch (_entityPropertyConvertType) { + case StringConvertType.Lower: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = e.Property.Name.ToLower(); + }; + break; + case StringConvertType.Upper: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = e.Property.Name.ToUpper(); + }; + break; + case StringConvertType.PascalCaseToUnderscore: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); + }; + break; + case StringConvertType.PascalCaseToUnderscoreWithLower: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); + }; + break; + case StringConvertType.PascalCaseToUnderscoreWithUpper: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); + }; + break; + default: + break; + } + } + } return ret; } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 5a12ce5b..6f611883 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -45,9 +45,9 @@ namespace FreeSql.Internal.CommonProvider { internal ConcurrentDictionary dicSyced = new ConcurrentDictionary(); public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); public bool SyncStructure(params Type[] entityTypes) { - if (entityTypes == null) return true; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray(); - if (syncTypes.Any() == false) return true; + if (entityTypes == null) return false; + var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray(); + if (syncTypes.Any() == false) return false; var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); _orm.Aop.SyncStructureBefore?.Invoke(this, before); Exception exception = null; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 3c23e48d..c2510bf5 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -73,6 +73,8 @@ namespace FreeSql.Internal { if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name; if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter; + if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; + } var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); foreach (var tryattrobj in attrs) { @@ -81,10 +83,12 @@ namespace FreeSql.Internal { if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter; + if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure; } if (!string.IsNullOrEmpty(attr.Name)) return attr; if (!string.IsNullOrEmpty(attr.OldName)) return attr; if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr; + if (attr._DisableSyncStructure != null) return attr; return null; } public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) { diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index adaa0678..c08cfdb7 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -18,6 +18,7 @@ namespace FreeSql.Internal.Model { public string DbName { get; set; } public string DbOldName { get; set; } public string SelectFilter { get; set; } + public bool DisableSyncStructure { get; set; } public ColumnInfo VersionColumn { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index b81b7c1b..1b38ca9f 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -53,6 +53,7 @@ namespace FreeSql.Internal { trytb.DbOldName = trytb.DbOldName?.ToUpper(); } trytb.SelectFilter = tbattr?.SelectFilter; + if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; var propsLazy = new List<(PropertyInfo, bool, bool)>(); var propsNavObjs = new List(); foreach (var p in trytb.Properties.Values) { diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 93c45632..348ebb56 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 5e1ce63f..667ae1e4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b53610f6..9b5064d8 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 896c9f4f..e2ff1e19 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index fc9e1384..0546a070 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5e3e0aaa..a53f4f70 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 5ce51bc31041f7413e78d09a969476c33ff85e4f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 14 Jun 2019 18:14:14 +0800 Subject: [PATCH 0018/1029] =?UTF-8?q?codefirst=20=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A=EF=BC=8C=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=88=B0=E6=95=B0=E6=8D=AE=E5=BA=93=E5=A4=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests.csproj | 4 + FreeSql.Tests/FreeSql.Tests.xml | 198 ++++++++++++++++++ FreeSql.Tests/UnitTest1.cs | 7 + FreeSql.Tests/ftTests.xml | 198 ++++++++++++++++++ FreeSql/FreeSql.xml | 7 + FreeSql/Internal/CommonUtils.cs | 33 +++ FreeSql/Internal/Model/ColumnInfo.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 3 + .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 1 + 9 files changed, 452 insertions(+) create mode 100644 FreeSql.Tests/FreeSql.Tests.xml create mode 100644 FreeSql.Tests/ftTests.xml diff --git a/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests.csproj index 9370e56c..27134387 100644 --- a/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.csproj @@ -6,6 +6,10 @@ false + + FreeSql.Tests.xml + + diff --git a/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests.xml new file mode 100644 index 00000000..55568931 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.xml @@ -0,0 +1,198 @@ + + + + FreeSql.Tests + + + + + 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 类型 + + + + + 内容简介 + + + + + 缩略图 + + + + + 点击量 + + + + + + + + + + + + + + + + + + + + + + + + + 主键,ID + + + + + 试卷表 + + + + + 考核计划ID + + + + + 总分 + + + + + 菜单权限ID + + + + + 菜单主键ID + + + + + 按钮主键ID + + + + + 菜单权限 + + + + + 主键 + + + + + 父级ID + + + + + 名称 + + + + + 图标 + + + + + 链接地址 + + + + + 是否公开 + + + + + 排序 + + + + + 备注 + + + + + 创建日期 + + + + + 按钮主键 + + + + + 名称 + + + + + 事件名称 + + + + + 编码 + + + + + 图标 + + + + + 排序 + + + + + 创建日期 + + + + diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index ea48b4ca..54d3e0d6 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -231,6 +231,9 @@ namespace FreeSql.Tests { public virtual TaskBuild TaskBuild { get; set; } } public class Templates { + /// + /// 主键,ID + /// [Column(IsPrimary = true)] public Guid Id { get; set; } public string Title { get; set; } @@ -267,6 +270,10 @@ namespace FreeSql.Tests { [Fact] public void Test1() { + var dkdkdkd = g.mysql.Select().ToList(); + + + var testaddlist = new List(); for(var a = 0; a < 133905; a++) { testaddlist.Add(new NewsArticle { diff --git a/FreeSql.Tests/ftTests.xml b/FreeSql.Tests/ftTests.xml new file mode 100644 index 00000000..55568931 --- /dev/null +++ b/FreeSql.Tests/ftTests.xml @@ -0,0 +1,198 @@ + + + + FreeSql.Tests + + + + + 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 类型 + + + + + 内容简介 + + + + + 缩略图 + + + + + 点击量 + + + + + + + + + + + + + + + + + + + + + + + + + 主键,ID + + + + + 试卷表 + + + + + 考核计划ID + + + + + 总分 + + + + + 菜单权限ID + + + + + 菜单主键ID + + + + + 按钮主键ID + + + + + 菜单权限 + + + + + 主键 + + + + + 父级ID + + + + + 名称 + + + + + 图标 + + + + + 链接地址 + + + + + 是否公开 + + + + + 排序 + + + + + 备注 + + + + + 创建日期 + + + + + 按钮主键 + + + + + 名称 + + + + + 事件名称 + + + + + 编码 + + + + + 图标 + + + + + 排序 + + + + + 创建日期 + + + + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 77e52249..e59d286f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2270,6 +2270,13 @@ + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + 中间表,多对多 diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index c2510bf5..c16f0104 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -8,11 +8,14 @@ using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.Common; +using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; +using System.Xml; +using System.Xml.XPath; namespace FreeSql.Internal { public abstract class CommonUtils { @@ -239,6 +242,36 @@ namespace FreeSql.Internal { return iidx == 1 ? sb.Remove(0, 5).Remove(sb.Length - 1, 1).ToString() : sb.Remove(0, 4).ToString(); } + /// + /// 通过属性的注释文本,通过 xml 读取 + /// + /// + /// Dict:key=属性名,value=注释 + public static Dictionary GetProperyCommentBySummary(Type type) { + var xmlPath = type.Assembly.Location.Replace(".dll", ".xml"); + if (File.Exists(xmlPath) == false) return null; + + var dic = new Dictionary(); + var className = type.IsNested ? $"{type.Namespace}.{type.DeclaringType.Name}.{type.Name}" : $"{type.Namespace}.{type.Name}"; + var sReader = new StringReader(File.ReadAllText(xmlPath)); + using (var xmlReader = XmlReader.Create(sReader)) { + var xpath = new XPathDocument(xmlReader); + var xmlNav = xpath.CreateNavigator(); + + var props = type.GetProperties(); + foreach (var prop in props) { + var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); + if (node == null) continue; + var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); + if (string.IsNullOrEmpty(comment)) continue; + + dic.Add(prop.Name, comment); + } + } + + return dic; + } + public static void PrevReheatConnectionPool(ObjectPool pool, int minPoolSize) { if (minPoolSize <= 0) minPoolSize = Math.Min(5, pool.Policy.PoolSize); if (minPoolSize > pool.Policy.PoolSize) minPoolSize = pool.Policy.PoolSize; diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index 24bfdcd9..fe17b231 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -10,6 +10,7 @@ namespace FreeSql.Internal.Model { public string CsName { get; set; } public Type CsType { get; set; } public ColumnAttribute Attribute { get; set; } + public string Comment { get; internal set; } static ConcurrentDictionary> _dicGetMapValue = new ConcurrentDictionary>(); public object GetMapValue(object obj) { diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 1b38ca9f..1899dcb2 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -56,6 +56,7 @@ namespace FreeSql.Internal { if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; var propsLazy = new List<(PropertyInfo, bool, bool)>(); var propsNavObjs = new List(); + var propsComment = CommonUtils.GetProperyCommentBySummary(entity); foreach (var p in trytb.Properties.Values) { var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); var colattr = common.GetEntityColumnAttribute(entity, p); @@ -124,6 +125,8 @@ namespace FreeSql.Internal { CsType = p.PropertyType, Attribute = colattr }; + if (propsComment != null && propsComment.TryGetValue(p.Name, out var trycomment)) + col.Comment = trycomment; if (colattr.IsIgnore) { trytb.ColumnsByCsIgnore.Add(p.Name, col); continue; diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 6148c2a0..1c9950c8 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -119,6 +119,7 @@ namespace FreeSql.MySql { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); sb.Append(","); } if (tb.Primarys.Any()) { From 9e6b4fb52e539745c7fbd614314c11e619fecd33 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 17 Jun 2019 12:04:31 +0800 Subject: [PATCH 0019/1029] =?UTF-8?q?=E5=AE=8C=E6=88=90CodeFirst=20?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A=EF=BC=8C?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=88=B0=E6=95=B0=E6=8D=AE=E5=BA=93=E5=A4=87?= =?UTF-8?q?=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.Tests/FreeSql.Tests.xml | 4 +- FreeSql.Tests/UnitTest1.cs | 29 +++++----- FreeSql.Tests/g.cs | 14 +++++ FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 20 +++++-- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../OracleCodeFirst.cs | 47 +++++++++++----- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../PostgreSQLCodeFirst.cs | 24 ++++++-- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../SqlServerCodeFirst.cs | 56 +++++++++++++++++-- .../FreeSql.Provider.Sqlite.csproj | 2 +- .../SqliteCodeFirst.cs | 2 +- 17 files changed, 157 insertions(+), 57 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 80f24053..60966e88 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.10 + 0.6.11 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests.xml index 55568931..6b525395 100644 --- a/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests.xml @@ -74,9 +74,9 @@ - + - 主键,ID + 测试中文重命名id diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 54d3e0d6..6234d919 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -232,14 +232,13 @@ namespace FreeSql.Tests { } public class Templates { /// - /// 主键,ID + /// 测试中文重命名id /// - [Column(IsPrimary = true)] - public Guid Id { get; set; } + [Column(IsPrimary = true, OldName = "Id")] + public Guid Id2 { get; set; } public string Title { get; set; } public DateTime AddTime { get; set; } = DateTime.Now; public DateTime EditTime { get; set; } - [Column(DbType = "text")] public string Code { get; set; } } public class TaskBuild { @@ -270,20 +269,20 @@ namespace FreeSql.Tests { [Fact] public void Test1() { - var dkdkdkd = g.mysql.Select().ToList(); + var dkdkdkd = g.oracle.Select().ToList(); - var testaddlist = new List(); - for(var a = 0; a < 133905; a++) { - testaddlist.Add(new NewsArticle { - ArticleTitle = "testaddlist_topic" + a, - Hits = a, - }); - } - g.sqlite.Insert(testaddlist) - //.NoneParameter() - .ExecuteAffrows(); + //var testaddlist = new List(); + //for(var a = 0; a < 133905; a++) { + // testaddlist.Add(new NewsArticle { + // ArticleTitle = "testaddlist_topic" + a, + // Hits = a, + // }); + //} + //g.sqlite.Insert(testaddlist) + // //.NoneParameter() + // .ExecuteAffrows(); g.mysql.Aop.ParseExpression = (s, e) => { diff --git a/FreeSql.Tests/g.cs b/FreeSql.Tests/g.cs index 6df85b6c..7396b139 100644 --- a/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/g.cs @@ -39,6 +39,20 @@ public class g { }); public static IFreeSql pgsql => pgsqlLazy.Value; + static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .Build()); + public static IFreeSql sqlserver => sqlserverLazy.Value; + static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") .UseAutoSyncStructure(true) diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cd3eb7be..37ca9137 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.10 + 0.6.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 348ebb56..e27094b4 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.10 + 0.6.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 1c9950c8..8fed3c85 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -152,7 +152,8 @@ select a.column_name, a.column_type, case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', -case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity' +case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', +a.column_comment 'comment' from information_schema.columns a where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -164,7 +165,8 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); sqlType = a1, is_nullable = string.Concat(a[2]) == "1", is_identity = string.Concat(a[3]) == "1", - is_unsigned = string.Concat(a[1]).EndsWith(" unsigned") + is_unsigned = string.Concat(a[1]).EndsWith(" unsigned"), + comment = string.Concat(a[4]) }; }, StringComparer.CurrentCultureIgnoreCase); @@ -174,18 +176,22 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || tbcol.Attribute.IsNullable != tbstructcol.is_nullable || - tbcol.Attribute.IsIdentity != tbstructcol.is_identity) { + tbcol.Attribute.IsIdentity != tbstructcol.is_identity || + isCommentChanged) { sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); + if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(")"); sbalter.Append(";\r\n"); } - if (tbstructcol.column == tbcol.Attribute.OldName) { + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) { //修改列名 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (isIdentityChanged) sb.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } continue; @@ -193,6 +199,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } @@ -228,6 +235,7 @@ where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbna sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); sb.Append(","); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 667ae1e4..5c4526ac 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.10 + 0.6.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 9b5064d8..d3155615 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.10 + 0.6.11 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 6893b677..7d59e1c1 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -112,6 +112,11 @@ namespace FreeSql.Oracle { } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } continue; } //如果新表,旧表在一个模式下,直接修改表名 @@ -127,17 +132,19 @@ namespace FreeSql.Oracle { //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 var sql = _commonUtils.FormatSql($@" select -column_name, -data_type, -data_length, -data_precision, -data_scale, -char_used, -case when nullable = 'Y' then 1 else 0 end, -nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||all_tab_columns.column_name), 0), -nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||all_tab_columns.column_name||'TI'), 0) -from all_tab_columns -where owner={{0}} and table_name={{1}}", tboldname ?? tbname); +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'Y' then 1 else 0 end, +nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), +nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +b.comments +from all_tab_columns a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { var sqlType = GetOracleSqlTypeFullName(a); @@ -145,7 +152,8 @@ where owner={{0}} and table_name={{1}}", tboldname ?? tbname); column = string.Concat(a[0]), sqlType, is_nullable = string.Concat(a[6]) == "1", - is_identity = string.Concat(a[7]) == "1" && string.Concat(a[8]) == "1" + is_identity = string.Concat(a[7]) == "1" && string.Concat(a[8]) == "1", + comment = string.Concat(a[9]) }; }, StringComparer.CurrentCultureIgnoreCase); @@ -153,7 +161,8 @@ where owner={{0}} and table_name={{1}}", tboldname ?? tbname); foreach (var tbcol in tb.Columns.Values) { var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) istmpatler = true; //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); @@ -164,9 +173,11 @@ where owner={{0}} and table_name={{1}}", tboldname ?? tbname); } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (tbstructcol.column == tbcol.Attribute.OldName) + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); + if (isCommentChanged) + sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; } //添加列 @@ -176,6 +187,7 @@ where owner={{0}} and table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } var dsuksql = _commonUtils.FormatSql(@" select @@ -231,6 +243,11 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.Columns.Values) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 087580ad..4d008622 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -199,7 +199,7 @@ a.data_length, a.data_precision, a.data_scale, a.char_used, -case when nullable = 'Y' then 1 else 0 end, +case when a.nullable = 'Y' then 1 else 0 end, nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), b.comments from all_tab_cols a diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e2ff1e19..d9e23606 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.10 + 0.6.11 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 4568a53f..708f73a3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -155,6 +155,11 @@ namespace FreeSql.PostgreSQL { } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -176,7 +181,8 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, e.adsrc, -a.attndims +a.attndims, +d.description as comment from pg_class c inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid inner join pg_type t on t.oid = a.atttypid @@ -207,7 +213,8 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), - attndims + attndims, + comment = string.Concat(a[7]) }; }, StringComparer.CurrentCultureIgnoreCase); @@ -215,6 +222,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); foreach (var tbcol in tb.Columns.Values) { if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); @@ -222,9 +230,11 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (tbstructcol.column == tbcol.Attribute.OldName) + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (isCommentChanged) + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); continue; } //添加列 @@ -232,6 +242,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0};\r\n", tbcol.Attribute.DbDefautValue)); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql(@" select @@ -288,6 +299,11 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.Columns.Values) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0546a070..6a700bf8 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.10 + 0.6.11 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 1356b66f..6df8fd72 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -63,7 +63,37 @@ namespace FreeSql.SqlServer { } return null; } - + + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) { + if (string.IsNullOrEmpty(comment)) { + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + 'COLUMN', N'{2}')) > 0) + EXEC sp_dropextendedproperty @name = N'MS_Description' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''")); + return; + } + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + 'COLUMN', N'{2}')) > 0) + EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'{3}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +ELSE + EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'{3}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); + } public override string GetComparisonDDLStatements(params Type[] entityTypes) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; @@ -133,6 +163,11 @@ namespace FreeSql.SqlServer { sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + } continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -160,6 +195,7 @@ a.name 'Column' else '' end as 'SqlType' ,case when a.is_nullable = 1 then '1' else '0' end 'IsNullable' ,case when a.is_identity = 1 then '1' else '0' end 'IsIdentity' +,c.value from sys.columns a inner join sys.types b on b.user_type_id = a.user_type_id left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id @@ -172,23 +208,27 @@ use " + database, tboldname ?? tbname); column = string.Concat(a[0]), sqlType = string.Concat(a[1]), is_nullable = string.Concat(a[2]) == "1", - is_identity = string.Concat(a[3]) == "1" + is_identity = string.Concat(a[3]) == "1", + comment = string.Concat(a[4]) }, StringComparer.CurrentCultureIgnoreCase); if (istmpatler == false) { foreach (var tbcol in tb.Columns.Values) { if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || tbcol.Attribute.IsNullable != tbstructcol.is_nullable || tbcol.Attribute.IsIdentity != tbstructcol.is_identity) { istmpatler = true; break; } - if (tbstructcol.column == tbcol.Attribute.OldName) { + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 - sbalter.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN';\r\n", $"{tbname[0]}.{tbname[1]}.{tbname[2]}.{tbcol.Attribute.OldName}", tbcol.Attribute.Name)); - } + sbalter.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN';\r\n", $"{tbname[0]}.{tbname[1]}.{tbname[2]}.{tbstructcol.column}", tbcol.Attribute.Name)); + if (isCommentChanged) + //修改备备注 + AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); continue; } //添加列 @@ -199,6 +239,7 @@ use " + database, tboldname ?? tbname); if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); } sbalter.Append(";\r\n"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } var dsuksql = string.Format(@" use [{0}]; @@ -265,6 +306,11 @@ use " + database, tboldname ?? tbname); sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); + } sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a53f4f70..8bc42afb 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.10 + 0.6.11 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index e3fdc8c5..e3488b89 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -152,7 +152,7 @@ namespace FreeSql.Sqlite { istmpatler = true; if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) istmpatler = true; - if (tbstructcol.column == tbcol.Attribute.OldName) + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 istmpatler = true; continue; From 08550fb467fab31d762197b9f51adbe42ffebedd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 18 Jun 2019 15:29:33 +0800 Subject: [PATCH 0020/1029] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 4d0f0936..360c4bfe 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,9 @@ -FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577)。 +FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577)。 据了解,用户使用很少问问题,编码过程中,因业务阻塞,情有可原;因框架使用问题阻塞,得不偿失。我们的口号:做 .net 最方便的 ORM!愿每一位开发者嘴角上扬😏! +扶摇直上,至强ORM只为自由编码;下联:鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) + # Features - [x] 支持 CodeFirst 迁移; From 6feb340b85cc815fd9701ba82dace3009432fc49 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 18 Jun 2019 15:31:20 +0800 Subject: [PATCH 0021/1029] update readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 360c4bfe..82197738 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 据了解,用户使用很少问问题,编码过程中,因业务阻塞,情有可原;因框架使用问题阻塞,得不偿失。我们的口号:做 .net 最方便的 ORM!愿每一位开发者嘴角上扬😏! -扶摇直上,至强ORM只为自由编码;下联:鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) +扶摇直上,至强ORM只为自由编码;鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) # Features From d1bd3170a5850404ff1620a19635225fb93ecd9a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 19 Jun 2019 12:07:06 +0800 Subject: [PATCH 0022/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IUpdate.Set?= =?UTF-8?q?=20=E6=94=AF=E6=8C=81=20Set(a=20=3D>=20new=20{=20Clicks=20=3D?= =?UTF-8?q?=20a.Clicks=20+=201,=20Time=20=3D=20DateTime.Now=20})=20?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E5=A4=9A=E4=B8=AA=E5=AD=97=E6=AE=B5=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E7=94=A8=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/UnitTest1.cs | 8 +++++ FreeSql/FreeSql.xml | 4 ++- FreeSql/Interface/Curd/IUpdate.cs | 6 ++-- .../Internal/CommonProvider/UpdateProvider.cs | 31 +++++++++++++++---- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 6234d919..65f1f96b 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -269,6 +269,14 @@ namespace FreeSql.Tests { [Fact] public void Test1() { + var tbid = g.sqlite.Select().First().Id; + var tbidsql = g.sqlite.Update().Where(a => a.Id == tbid) + .Set(a => new TaskBuild { + FileName = "111", + TaskName = a.TaskName + "333" + }).ToSql(); + + var dkdkdkd = g.oracle.Select().ToList(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e59d286f..2636dad9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1534,9 +1534,11 @@ 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + + 指定更新,格式:Set(a => new { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' - + diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index b16c0e65..d1708055 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -74,11 +74,13 @@ namespace FreeSql { IUpdate Set(Expression> column, TMember value); /// /// 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + /// + /// 指定更新,格式:Set(a => new { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' /// /// - /// + /// /// - IUpdate Set(Expression> binaryExpression); + IUpdate Set(Expression> exp); /// /// 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) /// diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index c5d17d13..286f325a 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Linq.Expressions; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -340,15 +341,33 @@ namespace FreeSql.Internal.CommonProvider { //foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value); return this; } - public IUpdate Set(Expression> binaryExpression) { - if (binaryExpression?.Body.NodeType == ExpressionType.Equal) { - _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, binaryExpression, null)); + public IUpdate Set(Expression> exp) { + var body = exp?.Body; + var nodeType = body?.NodeType; + if (nodeType == ExpressionType.Equal) { + _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp, null)); return this; } - if (binaryExpression?.Body is BinaryExpression == false && - binaryExpression?.Body.NodeType != ExpressionType.Call) return this; + + if (nodeType == ExpressionType.MemberInit) { + var initExp = body as MemberInitExpression; + if (initExp.Bindings?.Count > 0) { + for (var a = 0; a < initExp.Bindings.Count; a++) { + var initAssignExp = (initExp.Bindings[a] as MemberAssignment); + if (initAssignExp == null) continue; + var memberName = initExp.Bindings[a].Member.Name; + if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; + if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); + var memberValue = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, initAssignExp.Expression, null); + _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); + } + } + return this; + } + if (body is BinaryExpression == false && + nodeType != ExpressionType.Call) return this; var cols = new List(); - var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, binaryExpression, null); + var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, exp, null); if (cols.Any() == false) return this; foreach (var col in cols) { if (col.Column.Attribute.IsNullable == true && col.Column.Attribute.MapType.IsNullableType()) { From f776fae7d25722b8c2ed0809b0a643348c07454b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 19 Jun 2019 19:16:52 +0800 Subject: [PATCH 0023/1029] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20FreeSql=20?= =?UTF-8?q?=E4=BB=8B=E7=BB=8D=20PPT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 82197738..dced2a73 100644 --- a/readme.md +++ b/readme.md @@ -39,6 +39,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore - FreeSql.Connection.Extensions 也是扩展包,提供像 Dapper 一样的用法; - [FreeSql.Tools 生成器](https://github.com/2881099/FreeSql.Tools),基于 razor 模板的生成器; - [ABP 使用 FreeSql ORM](https://github.com/gnsilence/JPGZService),测试中...; +- [FreeSql 优势.pptx](https://github.com/2881099/FreeSql/files/3305785/FreeSql.pptx); # Providers From 06ff0a4da2a96dda4ea7bbc494583438232035b1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 19 Jun 2019 19:36:53 +0800 Subject: [PATCH 0024/1029] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ppt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index dced2a73..2f41d03e 100644 --- a/readme.md +++ b/readme.md @@ -39,7 +39,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore - FreeSql.Connection.Extensions 也是扩展包,提供像 Dapper 一样的用法; - [FreeSql.Tools 生成器](https://github.com/2881099/FreeSql.Tools),基于 razor 模板的生成器; - [ABP 使用 FreeSql ORM](https://github.com/gnsilence/JPGZService),测试中...; -- [FreeSql 优势.pptx](https://github.com/2881099/FreeSql/files/3305785/FreeSql.pptx); +- [FreeSql 优势.pptx](https://github.com/2881099/FreeSql/files/3305852/FreeSql.pptx); # Providers From 3e8fed416d8c06455ac8f357b4f1fc4043821987 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 20 Jun 2019 17:56:07 +0800 Subject: [PATCH 0025/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20LambdaExpres?= =?UTF-8?q?sion=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=20And/Or/Not=20?= =?UTF-8?q?=E5=BF=AB=E9=80=9F=E6=8B=BC=E6=8E=A5=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../LambadaExpressionExtensionsTest.cs | 43 ++++++++ .../Extensions/LambadaExpressionExtensions.cs | 98 +++++++++++++++++++ FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 41 ++++++++ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs create mode 100644 FreeSql/Extensions/LambadaExpressionExtensions.cs diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 60966e88..5c32ade8 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.11 + 0.6.12 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs b/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs new file mode 100644 index 00000000..ca387c1e --- /dev/null +++ b/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using Xunit; + +namespace FreeSql.Tests.Extensions { + public class LambadaExpressionExtensionsTest { + + [Fact] + public void And() { + Expression> where = a => a.id == Guid.Empty; + + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" > 0)", g.sqlite.Select().Where(where.And(b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.And(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" = 1 AND a.\"num\" = 2)", g.sqlite.Select().Where(where.And(b => b.num == 1).And(b => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.And(false, b => b.num == 1).And(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); + } + + [Fact] + public void Or() { + Expression> where = a => a.id == Guid.Empty; + + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE ((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" > 0))", g.sqlite.Select().Where(where.Or(b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Or(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" = 1) OR a.\"num\" = 2))", g.sqlite.Select().Where(where.Or(b => b.num == 1).Or(b => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Or(false, b => b.num == 1).Or(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); + } + + [Fact] + public void Not() { + Expression> where = a => a.id == Guid.Empty; + + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (not(a.\"id\" = '00000000-0000-0000-0000-000000000000'))", g.sqlite.Select().Where(where.Not()).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Not(false)).ToSql().Replace("\r\n", "")); + } + + class testExpAddOr { + public Guid id { get; set; } + + public int num { get; set; } + } + } +} diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs new file mode 100644 index 00000000..8a00b022 --- /dev/null +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -0,0 +1,98 @@ +using FreeSql; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace System.Linq.Expressions { + public static partial class LambadaExpressionExtensions { + + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + /// + /// true 时生效 + /// + /// + public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) { + if (condition == false) return exp1; + if (exp1 == null) return exp2; + if (exp2 == null) return exp1; + + ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); + NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); + + var left = visitor.Replace(exp1.Body); + var right = visitor.Replace(exp2.Body); + var body = Expression.AndAlso(left, right); + return Expression.Lambda>(body, newParameter); + } + + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + /// + /// true 时生效 + /// + /// + public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) { + if (condition == false) return exp1; + if (exp1 == null) return exp2; + if (exp2 == null) return exp1; + + ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); + NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); + + var left = visitor.Replace(exp1.Body); + var right = visitor.Replace(exp2.Body); + var body = Expression.OrElse(left, right); + return Expression.Lambda>(body, newParameter); + } + + /// + /// 将 lambda 表达式取反 + /// + /// + /// + /// true 时生效 + /// + public static Expression> Not(this Expression> exp, bool condition = true) { + if (condition == false) return exp; + if (exp == null) return null; + + var candidateExpr = exp.Parameters[0]; + var body = Expression.Not(exp.Body); + return Expression.Lambda>(body, candidateExpr); + } + } + + internal class NewExpressionVisitor : ExpressionVisitor { + public ParameterExpression _newParameter { get; private set; } + public NewExpressionVisitor(ParameterExpression param) { + this._newParameter = param; + } + public Expression Replace(Expression exp) { + return this.Visit(exp); + } + protected override Expression VisitParameter(ParameterExpression node) { + return this._newParameter; + } + } +} \ No newline at end of file diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 37ca9137..9b3c0cc3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.11 + 0.6.12 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 2636dad9..9ce72c3a 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2349,6 +2349,47 @@ + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + 生成类似Mongodb的ObjectId有序、不重复Guid diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e27094b4..49f82402 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.11 + 0.6.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 5c4526ac..cdc59973 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.11 + 0.6.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d3155615..f4627275 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.11 + 0.6.12 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d9e23606..1d129267 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.11 + 0.6.12 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 6a700bf8..74cc5afe 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.11 + 0.6.12 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 8bc42afb..48e33397 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.11 + 0.6.12 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 5891493402ee033cbc11c57fcdf39031588980bb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 21 Jun 2019 11:11:08 +0800 Subject: [PATCH 0026/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=20.HasValue=20=E5=92=8C=20!.HasValue=20?= =?UTF-8?q?=E7=9A=84=E8=A7=A3=E6=9E=90=E6=94=AF=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/UnitTest1.cs | 22 +++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 32 +++++++++++++++++----------- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 65f1f96b..0ec89789 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -269,6 +269,28 @@ namespace FreeSql.Tests { [Fact] public void Test1() { + var dcksdkdsk = g.sqlite.Select().Where(a => a.testaddtime2.HasValue).ToSql(); + var dcksdkdsk2 = g.sqlite.Select().Where(a => !a.testaddtime2.HasValue).ToSql(); + + var testgrpsql = g.sqlite.Select() + .From((a, b) => a.InnerJoin(aa => aa.TemplatesId + == b.Id2)) + .GroupBy((a, b) => b.Title) + .ToSql(a => new { + a.Key, + sss = a.Sum(a.Value.Item1.Id) + }); + + var testgrpsql2 = g.sqlite.Select() + .From((a, b) => a.InnerJoin(aa => aa.TemplatesId + == b.Id2)) + .GroupBy((a, b) => b.Title) + .ToList(a => new { + a.Key, + sss = a.Sum(a.Value.Item1.Id) + }); + + var tbid = g.sqlite.Select().First().Id; var tbidsql = g.sqlite.Update().Where(a => a.Id == tbid) .Set(a => new TaskBuild { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 95365fa7..74f2f1b3 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -278,7 +278,7 @@ namespace FreeSql.Internal { }; public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString) { var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table }); - if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool)) + if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; switch (sql) { case "1": @@ -291,7 +291,7 @@ namespace FreeSql.Internal { public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString) { var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); - if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool)) + if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; switch (sql) { case "1": @@ -303,26 +303,26 @@ namespace FreeSql.Internal { } public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString) { var tbidx = _tables.Count; - var filter = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); - if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool)) - filter = $"{filter} = {formatSql(true, null)}"; - switch (filter) { + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); + if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) + sql = $"{sql} = {formatSql(true, null)}"; + switch (sql) { case "1": - case "'t'": filter = "1=1"; break; + case "'t'": sql = "1=1"; break; case "0": - case "'f'": filter = "1=2"; break; + case "'f'": sql = "1=2"; break; default: break; } if (_tables.Count > tbidx) { _tables[tbidx].Type = tbtype; - _tables[tbidx].On = filter; + _tables[tbidx].On = sql; for (var a = tbidx + 1; a < _tables.Count; a++) _tables[a].Type = SelectTableInfoType.From; } else { var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On)).LastOrDefault(); if (find != null) { find.Type = tbtype; - find.On = filter; + find.On = sql; } } } @@ -409,7 +409,14 @@ namespace FreeSql.Internal { switch (exp.NodeType) { case ExpressionType.Not: var notExp = (exp as UnaryExpression)?.Operand; - if (notExp.NodeType == ExpressionType.MemberAccess) return $"{ExpressionLambdaToSql(notExp, tsc)} = {formatSql(false, null)}"; + if (notExp.NodeType == ExpressionType.MemberAccess) { + var notBody = ExpressionLambdaToSql(notExp, tsc); + if (notBody.Contains(" IS NULL")) return notBody.Replace(" IS NULL", " IS NOT NULL"); + if (notBody.Contains(" IS NOT NULL")) return notBody.Replace(" IS NOT NULL", " IS NULL"); + if (notBody.Contains("=")) return notBody.Replace("=", "!="); + if (notBody.Contains("!=")) return notBody.Replace("!=", "="); + return $"{notBody} = {formatSql(false, null)}"; + } return $"not({ExpressionLambdaToSql(notExp, tsc)})"; case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc); @@ -665,7 +672,8 @@ namespace FreeSql.Internal { case ExpressionType.MemberAccess: var exp4 = exp as MemberExpression; if (exp4 != null) { - if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) return ExpressionLambdaToSql(exp4.Expression, tsc); + if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) + return exp4.Member.Name == "HasValue" ? $"{ExpressionLambdaToSql(exp4.Expression, tsc)} IS NOT NULL" : ExpressionLambdaToSql(exp4.Expression, tsc); var extRet = ""; var memberType = exp4.Expression?.Type ?? exp4.Type; switch (memberType.FullName) { From 4ade1c80b4a0b601085a82474b60ba625a0fa009 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 21 Jun 2019 16:48:52 +0800 Subject: [PATCH 0027/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=20DateTime=20-=20DateTime=20=E5=92=8C=20Date?= =?UTF-8?q?Time=20-=20TimeSpan=20=E7=9A=84=E8=A7=A3=E6=9E=90=E6=94=AF?= =?UTF-8?q?=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataContext/SqlServer/SqlServerFixture.cs | 2 + .../MySql/MySqlExpression/DateTimeTest.cs | 32 ++++++++ .../Oracle/OracleExpression/DateTimeTest.cs | 80 ++++++++++++++----- .../PostgreSQLExpression/DateTimeTest.cs | 80 ++++++++++++++----- .../SqlServerExpression/DateTimeTest.cs | 11 +++ .../Sqlite/SqliteExpression/DateTimeTest.cs | 80 ++++++++++++++----- FreeSql/Internal/CommonExpression.cs | 8 ++ 7 files changed, 239 insertions(+), 54 deletions(-) diff --git a/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs b/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs index 9561b14c..bb00942c 100644 --- a/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs +++ b/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; @@ -14,6 +15,7 @@ namespace FreeSql.Tests.DataContext.SqlServer //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=(localdb)\\mssqllocaldb;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") .UseAutoSyncStructure(true) .UseLazyLoading(true) + .UseMonitorCommand(t => Trace.WriteLine(t.CommandText)) .Build()); // ... initialize data in the test database ... diff --git a/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs index 36c929b6..2b1e8d4c 100644 --- a/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs +++ b/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs @@ -493,6 +493,38 @@ namespace FreeSql.Tests.MySqlExpression { //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) } [Fact] + public void _ЧͬSubtract() { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] public void this_Equals() { var data = new List(); data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); diff --git a/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs index 107ec889..48bedc9e 100644 --- a/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs @@ -466,31 +466,75 @@ namespace FreeSql.Tests.OracleExpression { data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") } [Fact] public void this_Equals() { diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs b/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs index a00b7c80..ee70bad6 100644 --- a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs +++ b/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs @@ -466,31 +466,75 @@ namespace FreeSql.Tests.PostgreSQLExpression { data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + } + [Fact] + public void _ЧͬSubtract() { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") } [Fact] public void this_Equals() { diff --git a/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs index 8d41226e..ef9d4708 100644 --- a/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -228,6 +228,17 @@ namespace FreeSql.Tests.SqlServerExpression { data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); } [Fact] + public void _ЧͬSubtract() { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] public void this_Equals() { var data = new List(); data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); diff --git a/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs b/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs index e6aeb694..7577bd3e 100644 --- a/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs +++ b/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs @@ -466,31 +466,75 @@ namespace FreeSql.Tests.SqliteExpression { data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") + } + [Fact] + public void _ЧͬSubtract() { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") } [Fact] public void this_Equals() { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 74f2f1b3..3190d746 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -332,6 +332,8 @@ namespace FreeSql.Internal { static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectAnyMethodInfo = new ConcurrentDictionary(); internal static ConcurrentDictionary _dicNullableValueProperty = new ConcurrentDictionary(); static ConcurrentDictionary _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary(); + static MethodInfo MethodDateTimeSubtractDateTime = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(DateTime) }); + static MethodInfo MethodDateTimeSubtractTimeSpan = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(TimeSpan) }); public string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) { switch (oper) { @@ -342,6 +344,12 @@ namespace FreeSql.Internal { case "-": if (oper == "+" && (leftExp.Type == typeof(string) || rightExp.Type == typeof(string))) return _common.StringConcat(new[] { ExpressionLambdaToSql(leftExp, tsc), ExpressionLambdaToSql(rightExp, tsc) }, new[] { leftExp.Type, rightExp.Type }); + if (oper == "-" && leftExp.Type.NullableTypeOrThis() == typeof(DateTime)) { + if (rightExp.Type.NullableTypeOrThis() == typeof(DateTime)) + return ExpressionLambdaToSql(Expression.Call(leftExp, MethodDateTimeSubtractDateTime, rightExp), tsc); + if (rightExp.Type.NullableTypeOrThis() == typeof(TimeSpan)) + return ExpressionLambdaToSql(Expression.Call(leftExp, MethodDateTimeSubtractTimeSpan, rightExp), tsc); + } return $"({ExpressionLambdaToSql(leftExp, tsc)} {oper} {ExpressionLambdaToSql(rightExp, tsc)})"; } From a708062c9746aad3d1c14188f7b69f07dee0f45a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 24 Jun 2019 17:03:39 +0800 Subject: [PATCH 0028/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IUpdate.Set?= =?UTF-8?q?=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs/Program.cs | 19 ++++--- Examples/orm_vs/orm_vs.csproj | 2 + .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.Tests/UnitTest1.cs | 8 ++- FreeSql.sln | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 53 +++++++++++-------- .../Internal/CommonProvider/UpdateProvider.cs | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 61 insertions(+), 41 deletions(-) diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 770b9a16..e90b1aaf 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -15,8 +15,8 @@ namespace orm_vs class Program { static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") - //.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=20") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + .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=20") .UseAutoSyncStructure(false) .UseNoneCommandParameter(true) //.UseConfigEntityFromDbFirst(true) @@ -25,10 +25,10 @@ namespace orm_vs static SqlSugarClient sugar { get => new SqlSugarClient(new ConnectionConfig() { //不欺负,让连接池100个最小 - ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", - DbType = DbType.SqlServer, - //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", - //DbType = DbType.MySql, + //ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + //DbType = DbType.SqlServer, + ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + DbType = DbType.MySql, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute }); @@ -37,8 +37,8 @@ namespace orm_vs class SongContext : DbContext { public DbSet Songs { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); - //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); + //optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); + optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); } } @@ -48,6 +48,9 @@ namespace orm_vs //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements + sugar.Aop.OnLogExecuted = (s, e) => { + Trace.WriteLine(s); + }; //测试前清空数据 fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index 81b0c501..a36447e3 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -13,6 +13,8 @@ + + diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5c32ade8..871e5062 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.12 + 0.6.13 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 0ec89789..15e99247 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -253,7 +253,7 @@ namespace FreeSql.Tests { public bool OptionsEntity01 { get; set; } = false; public bool OptionsEntity02 { get; set; } = false; public bool OptionsEntity03 { get; set; } = false; - public bool OptionsEntity04 { get; set; } = false; + public int OptionsEntity04 { get; set; } [Navigate("TbId")] public virtual ICollection Builds { get; set; } @@ -292,10 +292,14 @@ namespace FreeSql.Tests { var tbid = g.sqlite.Select().First().Id; + + var testarray = new[] { 1, 2, 3 }; var tbidsql = g.sqlite.Update().Where(a => a.Id == tbid) .Set(a => new TaskBuild { FileName = "111", - TaskName = a.TaskName + "333" + TaskName = a.TaskName + "333", + OptionsEntity02 = false, + OptionsEntity04 = testarray[0] }).ToSql(); diff --git a/FreeSql.sln b/FreeSql.sln index 78fdd490..672214b1 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -42,7 +42,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.LazyLoad EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MySqlConnector", "Providers\FreeSql.Provider.MySqlConnector\FreeSql.Provider.MySqlConnector.csproj", "{D2A41321-5E84-410B-B25C-3AA122D4CA27}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Tests.Provider.MySqlConnector", "FreeSql.Tests.Provider.MySqlConnector\FreeSql.Tests.Provider.MySqlConnector.csproj", "{D113CDFB-FB97-482B-8A00-058E715B624A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.MySqlConnector", "FreeSql.Tests.Provider.MySqlConnector\FreeSql.Tests.Provider.MySqlConnector.csproj", "{D113CDFB-FB97-482B-8A00-058E715B624A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9b3c0cc3..586d5cd8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.12 + 0.6.13 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 3190d746..740bab69 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -278,40 +278,51 @@ namespace FreeSql.Internal { }; public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString) { var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table }); - if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) + var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); + if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; - switch (sql) { - case "1": - case "'t'": return "1=1"; - case "0": - case "'f'": return "1=2"; - default:return sql; + if (isBool) { + switch (sql) { + case "1": + case "'t'": return "1=1"; + case "0": + case "'f'": return "1=2"; + default: return sql; + } } + return sql; } public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString) { var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); - if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) + var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); + if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; - switch (sql) { - case "1": - case "'t'": return "1=1"; - case "0": - case "'f'": return "1=2"; - default: return sql; + if (isBool) { + switch (sql) { + case "1": + case "'t'": return "1=1"; + case "0": + case "'f'": return "1=2"; + default: return sql; + } } + return sql; } public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString) { var tbidx = _tables.Count; var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); - if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) + var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); + if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) sql = $"{sql} = {formatSql(true, null)}"; - switch (sql) { - case "1": - case "'t'": sql = "1=1"; break; - case "0": - case "'f'": sql = "1=2"; break; - default: break; + if (isBool) { + switch (sql) { + case "1": + case "'t'": sql = "1=1"; break; + case "0": + case "'f'": sql = "1=2"; break; + default: break; + } } if (_tables.Count > tbidx) { _tables[tbidx].Type = tbtype; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 286f325a..9843e35b 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -358,7 +358,7 @@ namespace FreeSql.Internal.CommonProvider { var memberName = initExp.Bindings[a].Member.Name; if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); - var memberValue = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, initAssignExp.Expression, null); + var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { }); _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); } } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 49f82402..2c2c7b11 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.12 + 0.6.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index cdc59973..f160ff74 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.12 + 0.6.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index f4627275..4a938a3e 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.12 + 0.6.13 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1d129267..6c9d2cd2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.12 + 0.6.13 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 74cc5afe..5917a46e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.12 + 0.6.13 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 48e33397..17a52aac 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.12 + 0.6.13 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 611c066481f5fe8b756a576ce65eb139453d3245 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 26 Jun 2019 10:09:26 +0800 Subject: [PATCH 0029/1029] =?UTF-8?q?-=20=E5=90=88=E5=B9=B6=20FreeSql.DbCo?= =?UTF-8?q?ntext=20=E9=A1=B9=E7=9B=AE=E8=87=B3=20FreeSql=20=E7=BB=B4?= =?UTF-8?q?=E6=8A=A4=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ValuesController.cs | 241 ++++++++++++++ .../dbcontext_01/DbContexts/SongContext.cs | 52 +++ Examples/dbcontext_01/Program.cs | 70 ++++ .../Properties/launchSettings.json | 27 ++ Examples/dbcontext_01/Startup.cs | 111 +++++++ .../dbcontext_01/appsettings.Development.json | 9 + Examples/dbcontext_01/appsettings.json | 8 + Examples/dbcontext_01/dbcontext_01.csproj | 21 ++ .../Controllers/SongController.cs | 98 ++++++ Examples/repository_01/Entitys/Song.cs | 11 + Examples/repository_01/Program.cs | 24 ++ .../Properties/launchSettings.json | 27 ++ Examples/repository_01/Startup.cs | 98 ++++++ .../appsettings.Development.json | 9 + Examples/repository_01/appsettings.json | 8 + Examples/repository_01/repository_01.csproj | 20 ++ .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/DbContext/DbContext.cs | 154 +++++++++ FreeSql.DbContext/DbContext/DbContextAsync.cs | 119 +++++++ .../DbContext/DbContextOptions.cs | 10 + .../DbContext/DbContextOptionsBuilder.cs | 13 + FreeSql.DbContext/DbContext/DbContextSync.cs | 119 +++++++ FreeSql.DbContext/DbContext/FreeContext.cs | 10 + FreeSql.DbContext/DbSet/DbSet.cs | 281 ++++++++++++++++ FreeSql.DbContext/DbSet/DbSetAsync.cs | 268 +++++++++++++++ FreeSql.DbContext/DbSet/DbSetSync.cs | 305 ++++++++++++++++++ .../Extenssions/DependencyInjection.cs | 32 ++ .../FreeSqlDbContextExtenssions.cs | 38 +++ FreeSql.DbContext/FreeSql.DbContext.csproj | 36 +++ FreeSql.DbContext/FreeSql.DbContext.xml | 259 +++++++++++++++ .../ContextSet/RepositoryDbContext.cs | 62 ++++ .../Repository/ContextSet/RepositoryDbSet.cs | 60 ++++ .../ContextSet/RepositoryUnitOfWork.cs | 57 ++++ .../Repository/DataFilter/DataFilter.cs | 152 +++++++++ .../Repository/DataFilter/DataFilterUtil.cs | 89 +++++ .../Extenssions/DependencyInjection.cs | 39 +++ .../FreeSqlRepositoryExtenssions.cs | 65 ++++ .../Repository/Repository/BaseRepository.cs | 160 +++++++++ .../Repository/DefaultRepository.cs | 16 + .../Repository/Repository/GuidRepository.cs | 15 + .../Repository/Repository/IBaseRepository.cs | 30 ++ .../Repository/Repository/IBasicRepository.cs | 45 +++ .../Repository/IReadOnlyRepository.cs | 27 ++ FreeSql.DbContext/TempExtensions.cs | 5 + FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 34 ++ FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 103 ++++++ FreeSql.DbContext/readme.md | 284 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 23 ++ FreeSql.Repository/readme.md | 132 ++++++++ .../FreeSql.Tests.PerformanceTests.csproj | 26 -- .../FreeSql.Tests.DbContext.csproj | 25 ++ .../RepositoryTests.cs | 261 +++++++++++++++ .../FreeSql.Tests.DbContext/UnitTest1.cs | 160 +++++++++ FreeSql.Tests/FreeSql.Tests.DbContext/g.cs | 86 +++++ .../FreeSql.Tests.PerformanceTests.csproj | 26 ++ .../MySqlAdoTest.cs | 0 .../FreeSql.Tests.PerformanceTests}/g.cs | 0 ...eeSql.Tests.Provider.MySqlConnector.csproj | 6 +- .../MySqlConnector/Curd/MySqlDeleteTest.cs | 0 .../MySqlConnector/Curd/MySqlInsertTest.cs | 0 .../MySqlConnector/Curd/MySqlSelectTest.cs | 0 .../MySqlConnector/Curd/MySqlUpdateTest.cs | 0 .../MapType/BoolNullableTest.cs | 0 .../MySqlConnector/MapType/BoolTest.cs | 0 .../MySqlConnector/MapType/EnumTest.cs | 0 .../MySqlConnector/MapType/ToStringTest.cs | 0 .../MySqlConnector/MySqlCodeFirstTest.cs | 0 .../MySqlConnectorAdo/MySqlAdoTest.cs | 0 .../MySqlConnectorExpression/ConvertTest.cs | 0 .../MySqlConnectorExpression/DateTimeTest.cs | 0 .../MySqlConnectorExpression/MathTest.cs | 0 .../MySqlConnectorExpression/OtherTest.cs | 0 .../MySqlConnectorExpression/StringTest.cs | 0 .../MySqlConnectorExpression/TimeSpanTest.cs | 0 .../MySqlConnector/MySqlDbFirstTest.cs | 0 .../g.cs | 0 FreeSql.Tests/{ => FreeSql.Tests}/Class1.cs | 0 .../DataAnnotations/MySqlFluentTest.cs | 0 .../DataAnnotations/SqlServerFluentTest.cs | 0 .../SqlServer/SqlServerCollection.cs | 0 .../DataContext/SqlServer/SqlServerFixture.cs | 0 .../GetDataReaderValueBlockExpressionTest.cs | 0 .../LambadaExpressionExtensionsTest.cs | 0 .../Extensions/StringExtensionsTest.cs | 0 .../{ => FreeSql.Tests}/FreeSql.Tests.csproj | 22 +- .../{ => FreeSql.Tests}/FreeSql.Tests.xml | 0 .../LinqToSql/SqliteLinqToSqlTests.cs | 0 .../MySql/Curd/MySqlDeleteTest.cs | 0 .../MySql/Curd/MySqlInsertTest.cs | 0 .../MySql/Curd/MySqlSelectTest.cs | 0 .../MySql/Curd/MySqlUpdateTest.cs | 0 .../MySql/MapType/BoolNullableTest.cs | 0 .../MySql/MapType/BoolTest.cs | 0 .../MySql/MapType/EnumTest.cs | 0 .../MySql/MapType/ToStringTest.cs | 0 .../MySql/MySqlAdo/MySqlAdoTest.cs | 0 .../MySql/MySqlCodeFirstTest.cs | 0 .../MySql/MySqlDbFirstTest.cs | 0 .../MySql/MySqlExpression/ConvertTest.cs | 0 .../MySql/MySqlExpression/DateTimeTest.cs | 0 .../MySql/MySqlExpression/MathTest.cs | 0 .../MySql/MySqlExpression/OtherTest.cs | 0 .../MySql/MySqlExpression/StringTest.cs | 0 .../MySql/MySqlExpression/TimeSpanTest.cs | 0 .../Oracle/Curd/OracleDeleteTest.cs | 0 .../Oracle/Curd/OracleInsertTest.cs | 0 .../Oracle/Curd/OracleSelectTest.cs | 0 .../Oracle/Curd/OracleUpdateTest.cs | 0 .../Oracle/MapType/BoolNullableTest.cs | 0 .../Oracle/MapType/BoolTest.cs | 0 .../Oracle/MapType/EnumTest.cs | 0 .../Oracle/MapType/ToStringTest.cs | 0 .../Oracle/OracleAdo/OracleAdoTest.cs | 0 .../Oracle/OracleCodeFirstTest.cs | 0 .../Oracle/OracleDbFirstTest.cs | 0 .../Oracle/OracleExpression/ConvertTest.cs | 0 .../Oracle/OracleExpression/DateTimeTest.cs | 0 .../Oracle/OracleExpression/MathTest.cs | 0 .../Oracle/OracleExpression/OtherTest.cs | 0 .../Oracle/OracleExpression/StringTest.cs | 0 .../Oracle/OracleExpression/TimeSpanTest.cs | 0 .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 0 .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 0 .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 0 .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 0 .../PostgreSQL/MapType/BoolNullableTest.cs | 0 .../PostgreSQL/MapType/BoolTest.cs | 0 .../PostgreSQL/MapType/EnumTest.cs | 0 .../PostgreSQL/MapType/JTokenTest.cs | 0 .../PostgreSQL/MapType/ToStringTest.cs | 0 .../PostgreSQLAdo/PostgreSQLAdoTest.cs | 0 .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 0 .../PostgreSQL/PostgreSQLDbFirstTest.cs | 0 .../PostgreSQLExpression/ConvertTest.cs | 0 .../PostgreSQLExpression/DateTimeTest.cs | 0 .../PostgreSQLExpression/MathTest.cs | 0 .../PostgreSQLExpression/OtherTest.cs | 0 .../PostgreSQLExpression/StringTest.cs | 0 .../PostgreSQLExpression/TimeSpanTest.cs | 0 .../SqlServer/Curd/SqlServerDeleteTest.cs | 0 .../SqlServer/Curd/SqlServerInsertTest.cs | 0 .../SqlServer/Curd/SqlServerSelectTest.cs | 0 .../SqlServer/Curd/SqlServerUpdateTest.cs | 0 .../SqlServer/MapType/BoolNullableTest.cs | 0 .../SqlServer/MapType/BoolTest.cs | 0 .../SqlServer/MapType/EnumTest.cs | 0 .../SqlServer/MapType/ToStringTest.cs | 0 .../SqlServerAdo/SqlServerAdoTest.cs | 0 .../SqlServer/SqlServerCodeFirstTest.cs | 0 .../SqlServer/SqlServerDbFirstTest.cs | 0 .../SqlServerExpression/ConvertTest.cs | 0 .../SqlServerExpression/DateTimeTest.cs | 0 .../SqlServer/SqlServerExpression/MathTest.cs | 0 .../SqlServerExpression/OtherTest.cs | 0 .../SqlServerExpression/StringTest.cs | 0 .../SqlServerExpression/TimeSpanTest.cs | 0 .../Sqlite/Curd/SqliteDeleteTest.cs | 0 .../Sqlite/Curd/SqliteInsertTest.cs | 0 .../Sqlite/Curd/SqliteSelectTest.cs | 0 .../Sqlite/Curd/SqliteUpdateTest.cs | 0 .../Sqlite/MapType/BoolNullableTest.cs | 0 .../Sqlite/MapType/BoolTest.cs | 0 .../Sqlite/MapType/EnumTest.cs | 0 .../Sqlite/MapType/ToStringTest.cs | 0 .../Sqlite/SqliteAdo/SqliteAdoTest.cs | 0 .../Sqlite/SqliteCodeFirstTest.cs | 0 .../Sqlite/SqliteExpression/ConvertTest.cs | 0 .../Sqlite/SqliteExpression/DateTimeTest.cs | 0 .../Sqlite/SqliteExpression/MathTest.cs | 0 .../Sqlite/SqliteExpression/OtherTest.cs | 0 .../Sqlite/SqliteExpression/StringTest.cs | 0 .../Sqlite/SqliteExpression/TimeSpanTest.cs | 0 .../{ => FreeSql.Tests}/UnitTest1.cs | 12 +- .../{ => FreeSql.Tests}/UnitTest2.cs | 0 FreeSql.Tests/{ => FreeSql.Tests}/ftTests.xml | 0 FreeSql.Tests/{ => FreeSql.Tests}/g.cs | 0 FreeSql.sln | 154 ++++++--- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- readme.md | 2 +- 185 files changed, 4577 insertions(+), 95 deletions(-) create mode 100644 Examples/dbcontext_01/Controllers/ValuesController.cs create mode 100644 Examples/dbcontext_01/DbContexts/SongContext.cs create mode 100644 Examples/dbcontext_01/Program.cs create mode 100644 Examples/dbcontext_01/Properties/launchSettings.json create mode 100644 Examples/dbcontext_01/Startup.cs create mode 100644 Examples/dbcontext_01/appsettings.Development.json create mode 100644 Examples/dbcontext_01/appsettings.json create mode 100644 Examples/dbcontext_01/dbcontext_01.csproj create mode 100644 Examples/repository_01/Controllers/SongController.cs create mode 100644 Examples/repository_01/Entitys/Song.cs create mode 100644 Examples/repository_01/Program.cs create mode 100644 Examples/repository_01/Properties/launchSettings.json create mode 100644 Examples/repository_01/Startup.cs create mode 100644 Examples/repository_01/appsettings.Development.json create mode 100644 Examples/repository_01/appsettings.json create mode 100644 Examples/repository_01/repository_01.csproj create mode 100644 FreeSql.DbContext/DbContext/DbContext.cs create mode 100644 FreeSql.DbContext/DbContext/DbContextAsync.cs create mode 100644 FreeSql.DbContext/DbContext/DbContextOptions.cs create mode 100644 FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs create mode 100644 FreeSql.DbContext/DbContext/DbContextSync.cs create mode 100644 FreeSql.DbContext/DbContext/FreeContext.cs create mode 100644 FreeSql.DbContext/DbSet/DbSet.cs create mode 100644 FreeSql.DbContext/DbSet/DbSetAsync.cs create mode 100644 FreeSql.DbContext/DbSet/DbSetSync.cs create mode 100644 FreeSql.DbContext/Extenssions/DependencyInjection.cs create mode 100644 FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs create mode 100644 FreeSql.DbContext/FreeSql.DbContext.csproj create mode 100644 FreeSql.DbContext/FreeSql.DbContext.xml create mode 100644 FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs create mode 100644 FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs create mode 100644 FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs create mode 100644 FreeSql.DbContext/Repository/DataFilter/DataFilter.cs create mode 100644 FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs create mode 100644 FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs create mode 100644 FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs create mode 100644 FreeSql.DbContext/Repository/Repository/BaseRepository.cs create mode 100644 FreeSql.DbContext/Repository/Repository/DefaultRepository.cs create mode 100644 FreeSql.DbContext/Repository/Repository/GuidRepository.cs create mode 100644 FreeSql.DbContext/Repository/Repository/IBaseRepository.cs create mode 100644 FreeSql.DbContext/Repository/Repository/IBasicRepository.cs create mode 100644 FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs create mode 100644 FreeSql.DbContext/TempExtensions.cs create mode 100644 FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs create mode 100644 FreeSql.DbContext/UnitOfWork/UnitOfWork.cs create mode 100644 FreeSql.DbContext/readme.md create mode 100644 FreeSql.Repository/FreeSql.Repository.csproj create mode 100644 FreeSql.Repository/readme.md delete mode 100644 FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj create mode 100644 FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj create mode 100644 FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.DbContext/g.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj rename {FreeSql.Tests.PerformanceTests => FreeSql.Tests/FreeSql.Tests.PerformanceTests}/MySqlAdoTest.cs (100%) rename {FreeSql.Tests.PerformanceTests => FreeSql.Tests/FreeSql.Tests.PerformanceTests}/g.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/FreeSql.Tests.Provider.MySqlConnector.csproj (59%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/Curd/MySqlDeleteTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/Curd/MySqlInsertTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/Curd/MySqlSelectTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/Curd/MySqlUpdateTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MapType/BoolNullableTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MapType/BoolTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MapType/EnumTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MapType/ToStringTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlCodeFirstTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlConnectorExpression/MathTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlConnectorExpression/OtherTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlConnectorExpression/StringTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/MySqlConnector/MySqlDbFirstTest.cs (100%) rename {FreeSql.Tests.Provider.MySqlConnector => FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector}/g.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Class1.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/DataAnnotations/MySqlFluentTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/DataAnnotations/SqlServerFluentTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/DataContext/SqlServer/SqlServerCollection.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/DataContext/SqlServer/SqlServerFixture.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Extensions/LambadaExpressionExtensionsTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Extensions/StringExtensionsTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/FreeSql.Tests.csproj (51%) rename FreeSql.Tests/{ => FreeSql.Tests}/FreeSql.Tests.xml (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/LinqToSql/SqliteLinqToSqlTests.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/Curd/MySqlDeleteTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/Curd/MySqlInsertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/Curd/MySqlSelectTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/Curd/MySqlUpdateTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MapType/BoolNullableTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MapType/BoolTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MapType/EnumTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MapType/ToStringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlAdo/MySqlAdoTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlCodeFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlDbFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlExpression/ConvertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlExpression/DateTimeTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlExpression/MathTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlExpression/OtherTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlExpression/StringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/MySql/MySqlExpression/TimeSpanTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/Curd/OracleDeleteTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/Curd/OracleInsertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/Curd/OracleSelectTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/Curd/OracleUpdateTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/MapType/BoolNullableTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/MapType/BoolTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/MapType/EnumTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/MapType/ToStringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleAdo/OracleAdoTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleCodeFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleDbFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleExpression/ConvertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleExpression/DateTimeTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleExpression/MathTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleExpression/OtherTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleExpression/StringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Oracle/OracleExpression/TimeSpanTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/Curd/PostgreSQLDeleteTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/Curd/PostgreSQLInsertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/Curd/PostgreSQLSelectTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/Curd/PostgreSQLUpdateTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/MapType/BoolNullableTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/MapType/BoolTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/MapType/EnumTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/MapType/JTokenTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/MapType/ToStringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLCodeFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLDbFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLExpression/ConvertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLExpression/MathTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLExpression/OtherTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLExpression/StringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/Curd/SqlServerDeleteTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/Curd/SqlServerInsertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/Curd/SqlServerSelectTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/Curd/SqlServerUpdateTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/MapType/BoolNullableTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/MapType/BoolTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/MapType/EnumTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/MapType/ToStringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerAdo/SqlServerAdoTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerCodeFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerDbFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerExpression/ConvertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerExpression/DateTimeTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerExpression/MathTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerExpression/OtherTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerExpression/StringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/SqlServer/SqlServerExpression/TimeSpanTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/Curd/SqliteDeleteTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/Curd/SqliteInsertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/Curd/SqliteSelectTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/Curd/SqliteUpdateTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/MapType/BoolNullableTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/MapType/BoolTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/MapType/EnumTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/MapType/ToStringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/SqliteAdo/SqliteAdoTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/SqliteCodeFirstTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/SqliteExpression/ConvertTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/SqliteExpression/DateTimeTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/SqliteExpression/MathTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/SqliteExpression/OtherTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/SqliteExpression/StringTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/Sqlite/SqliteExpression/TimeSpanTest.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/UnitTest1.cs (98%) rename FreeSql.Tests/{ => FreeSql.Tests}/UnitTest2.cs (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/ftTests.xml (100%) rename FreeSql.Tests/{ => FreeSql.Tests}/g.cs (100%) diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs new file mode 100644 index 00000000..90252e03 --- /dev/null +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using FreeSql; +using Microsoft.AspNetCore.Mvc; + +namespace dbcontext_01.Controllers { + [Route("api/[controller]")] + [ApiController] + public class ValuesController : ControllerBase { + + IFreeSql _orm; + SongContext _songContext; + public ValuesController(SongContext songContext, + IFreeSql orm1, IFreeSql orm2, + IFreeSql orm3 + ) { + _songContext = songContext; + _orm = orm1; + + } + + // GET api/values + [HttpGet] + async public Task Get() { + + long id = 0; + + try { + + var repos2Song = _orm.GetRepository(); + repos2Song.Where(a => a.Id > 10).ToList(); + //查询结果,进入 states + + var song = new Song { }; + repos2Song.Insert(song); + id = song.Id; + + var adds = Enumerable.Range(0, 100) + .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .ToList(); + //创建一堆无主键值 + + repos2Song.Insert(adds); + + for (var a = 0; a < 10; a++) + adds[a].Title = "dkdkdkdk" + a; + + repos2Song.Update(adds); + //批量修改 + + repos2Song.Delete(adds.Skip(10).Take(20).ToList()); + //批量删除,10-20 元素的主键值会被清除 + + adds.Last().Url = "skldfjlksdjglkjjcccc"; + repos2Song.Update(adds.Last()); + + adds.First().Url = "skldfjlksdjglkjjcccc"; + repos2Song.Update(adds.First()); + + + var ctx = _songContext; + var tag = new Tag { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + ctx.Tags.Add(tag); + + + ctx.UnitOfWork.GetOrBeginTransaction(); + + var tagAsync = new Tag { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + await ctx.Tags.AddAsync(tagAsync); + + + ctx.Songs.Select.Where(a => a.Id > 10).ToList(); + //查询结果,进入 states + + song = new Song { }; + //可插入的 song + + ctx.Songs.Add(song); + id = song.Id; + //因有自增类型,立即开启事务执行SQL,返回自增值 + + adds = Enumerable.Range(0, 100) + .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .ToList(); + //创建一堆无主键值 + + ctx.Songs.AddRange(adds); + //立即执行,将自增值赋给 adds 所有元素,因为有自增类型,如果其他类型,指定传入主键值,不会立即执行 + + for (var a = 0; a < 10; a++) + adds[a].Title = "dkdkdkdk" + a; + + ctx.Songs.UpdateRange(adds); + //批量修改,进入队列 + + ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); + //批量删除,进入队列,完成时 10-20 元素的主键值会被清除 + + //ctx.Songs.Update(adds.First()); + + adds.Last().Url = "skldfjlksdjglkjjcccc"; + ctx.Songs.Update(adds.Last()); + + adds.First().Url = "skldfjlksdjglkjjcccc"; + ctx.Songs.Update(adds.First()); + + //单条修改 urls 的值,进入队列 + + //throw new Exception("回滚"); + + //ctx.Songs.Select.First(); + //这里做一个查询,会立即打包【执行队列】,避免没有提交的数据,影响查询结果 + + ctx.SaveChanges(); + //打包【执行队列】,提交事务 + + + using (var uow = _orm.CreateUnitOfWork()) { + + var reposSong = uow.GetRepository(); + reposSong.Where(a => a.Id > 10).ToList(); + //查询结果,进入 states + + song = new Song { }; + reposSong.Insert(song); + id = song.Id; + + adds = Enumerable.Range(0, 100) + .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .ToList(); + //创建一堆无主键值 + + reposSong.Insert(adds); + + for (var a = 0; a < 10; a++) + adds[a].Title = "dkdkdkdk" + a; + + reposSong.Update(adds); + //批量修改 + + reposSong.Delete(adds.Skip(10).Take(20).ToList()); + //批量删除,10-20 元素的主键值会被清除 + + adds.Last().Url = "skldfjlksdjglkjjcccc"; + reposSong.Update(adds.Last()); + + adds.First().Url = "skldfjlksdjglkjjcccc"; + reposSong.Update(adds.First()); + + uow.Commit(); + } + + + + //using (var ctx = new SongContext()) { + + // var song = new Song { }; + // await ctx.Songs.AddAsync(song); + // id = song.Id; + + // var adds = Enumerable.Range(0, 100) + // .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + // .ToList(); + // await ctx.Songs.AddRangeAsync(adds); + + // for (var a = 0; a < adds.Count; a++) + // adds[a].Title = "dkdkdkdk" + a; + + // ctx.Songs.UpdateRange(adds); + + // ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); + + // //ctx.Songs.Update(adds.First()); + + // adds.Last().Url = "skldfjlksdjglkjjcccc"; + // ctx.Songs.Update(adds.Last()); + + // //throw new Exception("回滚"); + + // await ctx.SaveChangesAsync(); + //} + } catch { + var item = await _orm.Select().Where(a => a.Id == id).FirstAsync(); + + throw; + } + + var item22 = await _orm.Select().Where(a => a.Id == id).FirstAsync(); + var item33 = await _orm.Select().Where(a => a.Id > id).ToListAsync(); + + return item22.Id.ToString(); + } + + // GET api/values/5 + [HttpGet("{id}")] + public ActionResult Get(int id) { + return "value"; + } + + // POST api/values + [HttpPost] + public void Post([FromBody] string value) { + } + + // PUT api/values/5 + [HttpPut("{id}")] + public void Put(int id, [FromBody] string value) { + } + + // DELETE api/values/5 + [HttpDelete("{id}")] + public void Delete(int id) { + } + } +} diff --git a/Examples/dbcontext_01/DbContexts/SongContext.cs b/Examples/dbcontext_01/DbContexts/SongContext.cs new file mode 100644 index 00000000..126c5fd4 --- /dev/null +++ b/Examples/dbcontext_01/DbContexts/SongContext.cs @@ -0,0 +1,52 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; + +namespace dbcontext_01 { + + public class SongContext : DbContext { + + public DbSet Songs { get; set; } + public DbSet Tags { get; set; } + + //protected override void OnConfiguring(DbContextOptionsBuilder builder) { + // builder.UseFreeSql(dbcontext_01.Startup.Fsql); + //} + } + + + public class Song { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + + [Column(IsVersion = true)] + public long versionRow { get; set; } + } + public class Song_tag { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + + public class Tag { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } +} diff --git a/Examples/dbcontext_01/Program.cs b/Examples/dbcontext_01/Program.cs new file mode 100644 index 00000000..d1a5dafb --- /dev/null +++ b/Examples/dbcontext_01/Program.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Threading.Tasks; +using FreeSql; +using FreeSql.DataAnnotations; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace dbcontext_01 +{ + public class Program + { + + public class Song { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string BigNumber { get; set; } + + [Column(IsVersion = true)]//使用简单 + public long versionRow { get; set; } + } + + public class SongContext : DbContext { + + public DbSet Songs { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder builder) { + builder.UseFreeSql(fsql); + } + } + static IFreeSql fsql; + public static void Main(string[] args) { + fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNoneCommandParameter(true) + + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .Build(); + + + using (var ctx = new SongContext()) { + var song = new Song { BigNumber = "1000000000000000000" }; + ctx.Songs.Add(song); + + ctx.Songs.Update(song); + + song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); + ctx.Songs.Update(song); + + ctx.SaveChanges(); + + var sql = fsql.Update().SetSource(song).ToSql(); + } + + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup(); + } +} diff --git a/Examples/dbcontext_01/Properties/launchSettings.json b/Examples/dbcontext_01/Properties/launchSettings.json new file mode 100644 index 00000000..a7caa4d3 --- /dev/null +++ b/Examples/dbcontext_01/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:53030/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "dbcontext_01": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:53031/" + } + } +} \ No newline at end of file diff --git a/Examples/dbcontext_01/Startup.cs b/Examples/dbcontext_01/Startup.cs new file mode 100644 index 00000000..3955cb87 --- /dev/null +++ b/Examples/dbcontext_01/Startup.cs @@ -0,0 +1,111 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Swashbuckle.AspNetCore.Swagger; +using System; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace dbcontext_01 +{ + public class Startup + { + public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) + { + Configuration = configuration; + + Fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document2.db;Pooling=true;Max Pool Size=10") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + + //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") + //.UseSyncStructureToUpper(true) + + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNoneCommandParameter(true) + + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), + (cmd, log) => Trace.WriteLine(log) + ) + .Build(); + Fsql.Aop.SyncStructureBefore = (s, e) => { + Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName))); + }; + Fsql.Aop.SyncStructureAfter = (s, e) => { + Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName)) + " " + e.ElapsedMilliseconds + "ms\r\n" + e.Exception?.Message + e.Sql); + }; + + Fsql.Aop.CurdBefore = (s, e) => { + Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + ", " + e.Sql); + }; + Fsql.Aop.CurdAfter = (s, e) => { + Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + " " + e.ElapsedMilliseconds + "ms, " + e.Sql); + }; + + Fsql2 = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document222.db;Pooling=true;Max Pool Size=10") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), + (cmd, log) => Trace.WriteLine(log) + ) + .Build(); + } + + enum MySql { } + enum PgSql { } + + public IConfiguration Configuration { get; } + public static IFreeSql Fsql { get; private set; } + public static IFreeSql Fsql2 { get; private set; } + + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + services.AddSwaggerGen(options => { + options.SwaggerDoc("v1", new Info { + Version = "v1", + Title = "FreeSql.DbContext API" + }); + //options.IncludeXmlComments(xmlPath); + }); + + + + services.AddSingleton(Fsql); + services.AddSingleton>(Fsql2); + services.AddFreeDbContext(options => options.UseFreeSql(Fsql)); + + + var sql1 = Fsql.Update(1).Set(a => a.Id + 10).ToSql(); + var sql2 = Fsql.Update(1).Set(a => a.Title + 10).ToSql(); + var sql3 = Fsql.Update(1).Set(a => a.Create_time.Value.AddHours(1)).ToSql(); + } + + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Console.OutputEncoding = Encoding.GetEncoding("GB2312"); + Console.InputEncoding = Encoding.GetEncoding("GB2312"); + + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); + + app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); + app.UseDeveloperExceptionPage(); + app.UseMvc(); + + app.UseSwagger(); + app.UseSwaggerUI(c => { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); + }); + } + } +} diff --git a/Examples/dbcontext_01/appsettings.Development.json b/Examples/dbcontext_01/appsettings.Development.json new file mode 100644 index 00000000..e203e940 --- /dev/null +++ b/Examples/dbcontext_01/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/Examples/dbcontext_01/appsettings.json b/Examples/dbcontext_01/appsettings.json new file mode 100644 index 00000000..def9159a --- /dev/null +++ b/Examples/dbcontext_01/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj new file mode 100644 index 00000000..7d31fc7b --- /dev/null +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp2.1 + InProcess + + + + + + + + + + + + + + + + diff --git a/Examples/repository_01/Controllers/SongController.cs b/Examples/repository_01/Controllers/SongController.cs new file mode 100644 index 00000000..d162c33c --- /dev/null +++ b/Examples/repository_01/Controllers/SongController.cs @@ -0,0 +1,98 @@ +using FreeSql; +using Microsoft.AspNetCore.Mvc; +using restful.Entitys; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace restful.Controllers { + + public class SongRepository : GuidRepository { + public SongRepository(IFreeSql fsql) : base(fsql) { + } + } + + [Route("restapi/[controller]")] + public class SongsController : Controller { + + BaseRepository _songRepository; + + public class xxxx { + public int Id { get; set; } + + public bool IsDeleted { get; set; } + } + + + + public SongsController(IFreeSql fsql, + GuidRepository repos1, + GuidRepository repos2, + + DefaultRepository repos11, + DefaultRepository repos21, + + BaseRepository repos3, BaseRepository repos4, + IBasicRepository repos31, IBasicRepository repos41, + IReadOnlyRepository repos311, IReadOnlyRepository repos411, + + SongRepository reposSong + ) { + _songRepository = repos4; + + //test code + var curd1 = fsql.GetRepository(); + var curd2 = fsql.GetRepository(); + var curd3 = fsql.GetRepository(); + var curd4 = fsql.GetGuidRepository(); + + Console.WriteLine(repos1.Select.ToSql()); + Console.WriteLine(reposSong.Select.ToSql()); + + Console.WriteLine(repos2.Select.ToSql()); + Console.WriteLine(repos21.Select.ToSql()); + + using (reposSong.DataFilter.DisableAll()) { + Console.WriteLine(reposSong.Select.ToSql()); + } + } + + [HttpGet] + public Task> GetItems([FromQuery] string key, [FromQuery] int page = 1, [FromQuery] int limit = 20) { + return _songRepository.Select.WhereIf(!string.IsNullOrEmpty(key), a => a.Title.Contains(key)).Page(page, limit).ToListAsync(); + } + + [HttpGet("{id}")] + public Task GetItem([FromRoute] int id) { + return _songRepository.FindAsync(id); + } + + public class ModelSong { + public string title { get; set; } + } + + [HttpPost, ProducesResponseType(201)] + public Task Create([FromBody] ModelSong model) { + return _songRepository.InsertAsync(new Song { Title = model.title }); + } + + [HttpPut("{id}")] + public Task Update([FromRoute] int id, [FromBody] ModelSong model) { + return _songRepository.UpdateAsync(new Song { Id = id, Title = model.title }); + } + + [HttpPatch("{id}")] + async public Task UpdateDiy([FromRoute] int id, [FromForm] string title) { + var up = _songRepository.UpdateDiy.Where(a => a.Id == id); + if (!string.IsNullOrEmpty(title)) up.Set(a => a.Title, title); + var ret = await up.ExecuteUpdatedAsync(); + return ret.FirstOrDefault(); + } + + [HttpDelete("{id}"), ProducesResponseType(204)] + public Task Delete([FromRoute] int id) { + return _songRepository.DeleteAsync(a => a.Id == id); + } + } +} diff --git a/Examples/repository_01/Entitys/Song.cs b/Examples/repository_01/Entitys/Song.cs new file mode 100644 index 00000000..8c8a8a14 --- /dev/null +++ b/Examples/repository_01/Entitys/Song.cs @@ -0,0 +1,11 @@ +using FreeSql.DataAnnotations; +using repository_01; + +namespace restful.Entitys { + public class Song { + + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + } +} diff --git a/Examples/repository_01/Program.cs b/Examples/repository_01/Program.cs new file mode 100644 index 00000000..da7591b3 --- /dev/null +++ b/Examples/repository_01/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace repository_01 +{ + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup(); + } +} diff --git a/Examples/repository_01/Properties/launchSettings.json b/Examples/repository_01/Properties/launchSettings.json new file mode 100644 index 00000000..0426ce6f --- /dev/null +++ b/Examples/repository_01/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:52751/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "repository_01": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:52752/" + } + } +} \ No newline at end of file diff --git a/Examples/repository_01/Startup.cs b/Examples/repository_01/Startup.cs new file mode 100644 index 00000000..07243127 --- /dev/null +++ b/Examples/repository_01/Startup.cs @@ -0,0 +1,98 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using restful.Entitys; +using Swashbuckle.AspNetCore.Swagger; +using System; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace repository_01 { + + /// + /// 用户密码信息 + /// + public class Sys1UserLogOn { + [Column(IsPrimary = true, Name = "Id")] + public Guid UserLogOnId { get; set; } + public virtual Sys1User User { get; set; } + } + public class Sys1User { + [Column(IsPrimary = true, Name = "Id")] + public Guid UserId { get; set; } + public virtual Sys1UserLogOn UserLogOn { get; set; } + } + + public class Startup { + public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) { + Configuration = configuration; + + Fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .Build(); + + var sysu = new Sys1User { }; + Fsql.Insert().AppendData(sysu).ExecuteAffrows(); + Fsql.Insert().AppendData(new Sys1UserLogOn { UserLogOnId = sysu.UserId }).ExecuteAffrows(); + var a = Fsql.Select().ToList(); + var b = Fsql.Select().Any(); + } + + public IConfiguration Configuration { get; } + public static IFreeSql Fsql { get; private set; } + + public void ConfigureServices(IServiceCollection services) { + + //services.AddTransient(s => s.) + + services.AddMvc(); + services.AddSwaggerGen(options => { + options.SwaggerDoc("v1", new Info { + Version = "v1", + Title = "FreeSql.RESTful API" + }); + //options.IncludeXmlComments(xmlPath); + }); + + services.AddSingleton(Fsql); + + services.AddFreeRepository(filter => { + filter + //.Apply("test", a => a.Title == DateTime.Now.ToString() + System.Threading.Thread.CurrentThread.ManagedThreadId) + .Apply("softdelete", a => a.IsDeleted == false); + }, this.GetType().Assembly); + } + + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Console.OutputEncoding = Encoding.GetEncoding("GB2312"); + Console.InputEncoding = Encoding.GetEncoding("GB2312"); + + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); + + app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); + app.UseDeveloperExceptionPage(); + app.UseMvc(); + + app.UseSwagger(); + app.UseSwaggerUI(c => { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); + }); + } + } + + public interface ISoftDelete { + bool IsDeleted { get; set; } + } +} diff --git a/Examples/repository_01/appsettings.Development.json b/Examples/repository_01/appsettings.Development.json new file mode 100644 index 00000000..86f6b8f7 --- /dev/null +++ b/Examples/repository_01/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Warning", + "Microsoft": "Warning" + } + } +} diff --git a/Examples/repository_01/appsettings.json b/Examples/repository_01/appsettings.json new file mode 100644 index 00000000..def9159a --- /dev/null +++ b/Examples/repository_01/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Examples/repository_01/repository_01.csproj b/Examples/repository_01/repository_01.csproj new file mode 100644 index 00000000..14435386 --- /dev/null +++ b/Examples/repository_01/repository_01.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp2.1 + InProcess + + + + + + + + + + + + + + + diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 871e5062..4d94d32d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.13 + 0.7.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs new file mode 100644 index 00000000..90625e87 --- /dev/null +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace FreeSql { + public abstract partial class DbContext : IDisposable { + + internal IFreeSql _orm; + internal IFreeSql _fsql => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); + + public IFreeSql Orm => _fsql; + + protected IUnitOfWork _uowPriv; + internal IUnitOfWork _uow => _isUseUnitOfWork ? (_uowPriv ?? (_uowPriv = new UnitOfWork(_fsql))) : null; + internal bool _isUseUnitOfWork = true; //不使用工作单元事务 + + public IUnitOfWork UnitOfWork => _uow; + + DbContextOptions _options; + internal DbContextOptions Options { + get { + if (_options != null) return _options; + if (FreeSqlDbContextExtenssions._dicSetDbContextOptions.TryGetValue(Orm, out _options)) return _options; + _options = new DbContextOptions(); + return _options; + } + } + + static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); + protected DbContext() { + + var builder = new DbContextOptionsBuilder(); + OnConfiguring(builder); + _orm = builder._fsql; + + if (_orm != null) InitPropSets(); + } + + internal void InitPropSets() { + var props = _dicGetDbSetProps.GetOrAdd(this.GetType(), tp => + tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) + .Where(a => a.PropertyType.IsGenericType && + a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GenericTypeArguments[0])).ToArray()); + + foreach (var prop in props) { + var set = this.Set(prop.PropertyType.GenericTypeArguments[0]); + + prop.SetValue(this, set); + AllSets.Add(prop.Name, set); + } + } + + protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { + + } + + protected Dictionary _dicSet = new Dictionary(); + public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; + public virtual IDbSet Set(Type entityType) { + if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; + var sd = Activator.CreateInstance(typeof(DbContextDbSet<>).MakeGenericType(entityType), this) as IDbSet; + if (entityType != typeof(object)) _dicSet.Add(entityType, sd); + return sd; + } + protected Dictionary AllSets { get; } = new Dictionary(); + + #region DbSet 快速代理 + /// + /// 添加 + /// + /// + /// + public void Add(TEntity data) where TEntity : class => this.Set().Add(data); + public void AddRange(IEnumerable data) where TEntity : class => this.Set().AddRange(data); + public Task AddAsync(TEntity data) where TEntity : class => this.Set().AddAsync(data); + public Task AddRangeAsync(IEnumerable data) where TEntity : class => this.Set().AddRangeAsync(data); + + /// + /// 更新 + /// + /// + /// + public void Update(TEntity data) where TEntity : class => this.Set().Update(data); + public void UpdateRange(IEnumerable data) where TEntity : class => this.Set().UpdateRange(data); + public Task UpdateAsync(TEntity data) where TEntity : class => this.Set().UpdateAsync(data); + public Task UpdateRangeAsync(IEnumerable data) where TEntity : class => this.Set().UpdateRangeAsync(data); + + /// + /// 删除 + /// + /// + /// + public void Remove(TEntity data) where TEntity : class => this.Set().Remove(data); + public void RemoveRange(IEnumerable data) where TEntity : class => this.Set().RemoveRange(data); + + /// + /// 添加或更新 + /// + /// + /// + public void AddOrUpdate(TEntity data) where TEntity : class => this.Set().AddOrUpdate(data); + public Task AddOrUpdateAsync(TEntity data) where TEntity : class => this.Set().AddOrUpdateAsync(data); + + /// + /// 附加实体,可用于不查询就更新或删除 + /// + /// + /// + public void Attach(TEntity data) where TEntity : class => this.Set().Attach(data); + public void AttachRange(IEnumerable data) where TEntity : class => this.Set().AttachRange(data); + #endregion + + internal class ExecCommandInfo { + public ExecCommandInfoType actionType { get; set; } + public IDbSet dbSet { get; set; } + public Type stateType { get; set; } + public object state { get; set; } + } + internal enum ExecCommandInfoType { Insert, Update, Delete } + Queue _actions = new Queue(); + internal int _affrows = 0; + + internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, object state) { + _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); + } + + ~DbContext() { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() { + if (_isdisposed) return; + try { + _actions.Clear(); + + foreach (var set in _dicSet) + try { + set.Value.Dispose(); + } catch { } + + _dicSet.Clear(); + AllSets.Clear(); + + _uow?.Rollback(); + } finally { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + } +} diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs new file mode 100644 index 00000000..269486f9 --- /dev/null +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql { + partial class DbContext { + + async public virtual Task SaveChangesAsync() { + await ExecCommandAsync(); + _uow?.Commit(); + var ret = _affrows; + _affrows = 0; + return ret; + } + + static Dictionary>>> _dicExecCommandDbContextBetchAsync = new Dictionary>>>(); + async internal Task ExecCommandAsync() { + if (isExecCommanding) return; + if (_actions.Any() == false) return; + isExecCommanding = true; + + ExecCommandInfo oldinfo = null; + var states = new List(); + + Func> dbContextBetch = methodName => { + if (_dicExecCommandDbContextBetchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false) + trydic = new Dictionary>>(); + if (trydic.TryGetValue(methodName, out var tryfunc) == false) { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + + var returnTarget = Expression.Label(typeof(Task)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + tryfunc = Expression.Lambda>>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(Task))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + trydic.Add(methodName, tryfunc); + } + return tryfunc(oldinfo.dbSet, states.ToArray()); + }; + Func funcDelete = async () => { + _affrows += await dbContextBetch("DbContextBetchRemoveAsync"); + states.Clear(); + }; + Func funcInsert = async () => { + _affrows += await dbContextBetch("DbContextBetchAddAsync"); + states.Clear(); + }; + Func funcUpdate = async (isLiveUpdate) => { + var affrows = 0; + if (isLiveUpdate) affrows = await dbContextBetch("DbContextBetchUpdateNowAsync"); + else affrows = await dbContextBetch("DbContextBetchUpdateAsync"); + if (affrows == -999) { //最后一个元素已被删除 + states.RemoveAt(states.Count - 1); + return; + } + if (affrows == -998 || affrows == -997) { //没有执行更新 + var laststate = states[states.Count - 1]; + states.Clear(); + if (affrows == -997) states.Add(laststate); //保留最后一个 + } + if (affrows > 0) { + _affrows += affrows; + var islastNotUpdated = states.Count != affrows; + var laststate = states[states.Count - 1]; + states.Clear(); + if (islastNotUpdated) states.Add(laststate); //保留最后一个 + } + }; + + while (_actions.Any() || states.Any()) { + var info = _actions.Any() ? _actions.Dequeue() : null; + if (oldinfo == null) oldinfo = info; + var isLiveUpdate = false; + + if (_actions.Any() == false && states.Any() || + info != null && oldinfo.actionType != info.actionType || + info != null && oldinfo.stateType != info.stateType) { + + if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { + //最后一个,合起来发送 + states.Add(info.state); + info = null; + } + + switch (oldinfo.actionType) { + case ExecCommandInfoType.Insert: + await funcInsert(); + break; + case ExecCommandInfoType.Delete: + await funcDelete(); + break; + } + isLiveUpdate = true; + } + + if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { + if (states.Any()) + await funcUpdate(isLiveUpdate); + } + + if (info != null) { + states.Add(info.state); + oldinfo = info; + } + } + isExecCommanding = false; + } + } +} diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs new file mode 100644 index 00000000..47095091 --- /dev/null +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -0,0 +1,10 @@ + +namespace FreeSql { + public class DbContextOptions { + + /// + /// 是否开启一对多,联级保存功能 + /// + public bool EnableAddOrUpdateNavigateList { get; set; } = true; + } +} diff --git a/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs b/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs new file mode 100644 index 00000000..a003f65d --- /dev/null +++ b/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs @@ -0,0 +1,13 @@ + + +namespace FreeSql { + public class DbContextOptionsBuilder { + + internal IFreeSql _fsql; + + public DbContextOptionsBuilder UseFreeSql(IFreeSql orm) { + _fsql = orm; + return this; + } + } +} diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs new file mode 100644 index 00000000..6eec203b --- /dev/null +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Linq.Expressions; + +namespace FreeSql { + partial class DbContext { + + public virtual int SaveChanges() { + ExecCommand(); + _uow?.Commit(); + var ret = _affrows; + _affrows = 0; + return ret; + } + + static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); + bool isExecCommanding = false; + internal void ExecCommand() { + if (isExecCommanding) return; + if (_actions.Any() == false) return; + isExecCommanding = true; + + ExecCommandInfo oldinfo = null; + var states = new List(); + + Func dbContextBetch = methodName => { + if (_dicExecCommandDbContextBetch.TryGetValue(oldinfo.stateType, out var trydic) == false) + trydic = new Dictionary>(); + if (trydic.TryGetValue(methodName, out var tryfunc) == false) { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + + var returnTarget = Expression.Label(typeof(int)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + tryfunc = Expression.Lambda>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(int))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + trydic.Add(methodName, tryfunc); + } + return tryfunc(oldinfo.dbSet, states.ToArray()); + }; + Action funcDelete = () => { + _affrows += dbContextBetch("DbContextBetchRemove"); + states.Clear(); + }; + Action funcInsert = () => { + _affrows += dbContextBetch("DbContextBetchAdd"); + states.Clear(); + }; + Action funcUpdate = isLiveUpdate => { + var affrows = 0; + if (isLiveUpdate) affrows = dbContextBetch("DbContextBetchUpdateNow"); + else affrows = dbContextBetch("DbContextBetchUpdate"); + if (affrows == -999) { //最后一个元素已被删除 + states.RemoveAt(states.Count - 1); + return; + } + if (affrows == -998 || affrows == -997) { //没有执行更新 + var laststate = states[states.Count - 1]; + states.Clear(); + if (affrows == -997) states.Add(laststate); //保留最后一个 + } + if (affrows > 0) { + _affrows += affrows; + var islastNotUpdated = states.Count != affrows; + var laststate = states[states.Count - 1]; + states.Clear(); + if (islastNotUpdated) states.Add(laststate); //保留最后一个 + } + }; + + while (_actions.Any() || states.Any()) { + var info = _actions.Any() ? _actions.Dequeue() : null; + if (oldinfo == null) oldinfo = info; + var isLiveUpdate = false; + + if (_actions.Any() == false && states.Any() || + info != null && oldinfo.actionType != info.actionType || + info != null && oldinfo.stateType != info.stateType) { + + if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { + //最后一个,合起来发送 + states.Add(info.state); + info = null; + } + + switch (oldinfo.actionType) { + case ExecCommandInfoType.Insert: + funcInsert(); + break; + case ExecCommandInfoType.Delete: + funcDelete(); + break; + } + isLiveUpdate = true; + } + + if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { + if (states.Any()) + funcUpdate(isLiveUpdate); + } + + if (info != null) { + states.Add(info.state); + oldinfo = info; + } + } + isExecCommanding = false; + } + } +} diff --git a/FreeSql.DbContext/DbContext/FreeContext.cs b/FreeSql.DbContext/DbContext/FreeContext.cs new file mode 100644 index 00000000..a6b0549d --- /dev/null +++ b/FreeSql.DbContext/DbContext/FreeContext.cs @@ -0,0 +1,10 @@ + + +namespace FreeSql { + public class FreeContext : DbContext { + + public FreeContext(IFreeSql orm) { + _orm = orm; + } + } +} diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs new file mode 100644 index 00000000..b115f424 --- /dev/null +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -0,0 +1,281 @@ +using FreeSql.Extensions.EntityUtil; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace FreeSql { + + internal class DbContextDbSet : DbSet where TEntity : class { + + public DbContextDbSet(DbContext ctx) { + _ctx = ctx; + _uow = ctx._uow; + _fsql = ctx._fsql; + } + } + + public interface IDbSet : IDisposable { + Type EntityType { get; } + } + public abstract partial class DbSet : IDbSet where TEntity : class { + + internal DbContext _ctx; + internal IUnitOfWork _uow; + internal IFreeSql _fsql; + + protected virtual ISelect OrmSelect(object dywhere) { + DbContextExecCommand(); //查询前先提交,否则会出脏读 + return _fsql.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); + } + + ~DbSet() { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() { + if (_isdisposed) return; + try { + this._dicUpdateTimes.Clear(); + this._states.Clear(); + } finally { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + + protected virtual IInsert OrmInsert() => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); + protected virtual IInsert OrmInsert(TEntity data) => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); + protected virtual IInsert OrmInsert(IEnumerable data) => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); + + protected virtual IUpdate OrmUpdate(IEnumerable entitys) => _fsql.Update().AsType(_entityType).SetSource(entitys).WithTransaction(_uow?.GetOrBeginTransaction()); + protected virtual IDelete OrmDelete(object dywhere) => _fsql.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); + + internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) { + _ctx.EnqueueAction(actionType, this, typeof(EntityState), state); + } + internal void IncrAffrows(int affrows) { + _ctx._affrows += affrows; + } + + internal void TrackToList(object list) { + if (list == null) return; + var ls = list as IList; + if (ls == null) { + var ie = list as IEnumerable; + if (ie == null) return; + foreach (var item in ie) { + if (item == null) return; + var itemType = item.GetType(); + if (itemType == typeof(object)) return; + if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + var dbset = _ctx.Set(itemType); + dbset?.GetType().GetMethod("TrackToList", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dbset, new object[] { list }); + return; + } + return; + } + + foreach (var item in ls) { + var key = _fsql.GetEntityKeyString(_entityType, item, false); + if (key == null) continue; + _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { + _fsql.MapEntityValue(_entityType, item, ov.Value); + ov.Time = DateTime.Now; + return ov; + }); + } + } + + public ISelect Select => this.OrmSelect(null); + public ISelect Where(Expression> exp) => this.OrmSelect(null).Where(exp); + public ISelect WhereIf(bool condition, Expression> exp) => this.OrmSelect(null).WhereIf(condition, exp); + + protected ConcurrentDictionary _states = new ConcurrentDictionary(); + internal ConcurrentDictionary _statesInternal => _states; + TableInfo _tablePriv; + protected TableInfo _table => _tablePriv ?? (_tablePriv = _fsql.CodeFirst.GetTableByEntity(_entityType)); + ColumnInfo[] _tableIdentitysPriv; + protected ColumnInfo[] _tableIdentitys => _tableIdentitysPriv ?? (_tableIdentitysPriv = _table.Primarys.Where(a => a.Attribute.IsIdentity).ToArray()); + protected Type _entityType = typeof(TEntity); + public Type EntityType => _entityType; + + /// + /// 动态Type,在使用 DbSet<object> 后使用本方法,指定实体类型 + /// + /// + /// + public void AsType(Type entityType) { + if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); + if (entityType == _entityType) return; + var newtb = _fsql.CodeFirst.GetTableByEntity(entityType); + _entityType = entityType; + _tablePriv = newtb ?? throw new Exception("DbSet.AsType 参数错误,请传入正确的实体类型"); + _tableIdentitysPriv = null; + } + + public class EntityState { + public EntityState(TEntity value, string key) { + this.Value = value; + this.Key = key; + this.Time = DateTime.Now; + } + public TEntity OldValue { get; set; } + public TEntity Value { get; set; } + public string Key { get; set; } + public DateTime Time { get; set; } + } + /// + /// 附加实体,可用于不查询就更新或删除 + /// + /// + public void Attach(TEntity data) => AttachRange(new[] { data }); + public void AttachRange(IEnumerable data) { + if (data == null || data.Any() == false) return; + if (_table.Primarys.Any() == false) throw new Exception($"不可附加,实体没有主键:{_fsql.GetEntityString(_entityType, data.First())}"); + foreach (var item in data) { + var key = _fsql.GetEntityKeyString(_entityType, item, false); + if (string.IsNullOrEmpty(key)) throw new Exception($"不可附加,未设置主键的值:{_fsql.GetEntityString(_entityType, item)}"); + + _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { + _fsql.MapEntityValue(_entityType, item, ov.Value); + ov.Time = DateTime.Now; + return ov; + }); + } + } + /// + /// 清空状态数据 + /// + public void FlushState() { + _states.Clear(); + } + + #region Utils + EntityState CreateEntityState(TEntity data) { + if (data == null) throw new ArgumentNullException(nameof(data)); + var key = _fsql.GetEntityKeyString(_entityType, data, false); + var state = new EntityState((TEntity)Activator.CreateInstance(_entityType), key); + _fsql.MapEntityValue(_entityType, data, state.Value); + return state; + } + bool? ExistsInStates(TEntity data) { + if (data == null) throw new ArgumentNullException(nameof(data)); + var key = _fsql.GetEntityKeyString(_entityType, data, false); + if (string.IsNullOrEmpty(key)) return null; + return _states.ContainsKey(key); + } + + bool CanAdd(IEnumerable data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (data.Any() == false) return false; + foreach (var s in data) if (CanAdd(s, isThrow) == false) return false; + return true; + } + bool CanAdd(TEntity data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (_table.Primarys.Any() == false) { + if (isThrow) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + var key = _fsql.GetEntityKeyString(_entityType, data, true); + if (string.IsNullOrEmpty(key)) { + switch (_fsql.Ado.DataType) { + case DataType.SqlServer: + case DataType.PostgreSQL: + return true; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { + return true; + } + if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + } else { + if (_states.ContainsKey(key)) { + if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + var idval = _fsql.GetEntityIdentityValueWithPrimary(_entityType, data); + if (idval > 0) { + if (isThrow) throw new Exception($"不可添加,自增属性有值:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + } + return true; + } + + bool CanUpdate(IEnumerable data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (data.Any() == false) return false; + foreach (var s in data) if (CanUpdate(s, isThrow) == false) return false; + return true; + } + bool CanUpdate(TEntity data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (_table.Primarys.Any() == false) { + if (isThrow) throw new Exception($"不可更新,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + var key = _fsql.GetEntityKeyString(_entityType, data, false); + if (string.IsNullOrEmpty(key)) { + if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + if (_states.TryGetValue(key, out var tryval) == false) { + if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询 或者 Attach:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + return true; + } + + bool CanRemove(IEnumerable data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (data.Any() == false) return false; + foreach (var s in data) if (CanRemove(s, isThrow) == false) return false; + return true; + } + bool CanRemove(TEntity data, bool isThrow) { + if (data == null) { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (_table.Primarys.Any() == false) { + if (isThrow) throw new Exception($"不可删除,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + var key = _fsql.GetEntityKeyString(_entityType, data, false); + if (string.IsNullOrEmpty(key)) { + if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + //if (_states.TryGetValue(key, out var tryval) == false) { + // if (isThrow) throw new Exception($"不可删除,数据未被跟踪,应该先查询:{_fsql.GetEntityString(_entityType, data)}"); + // return false; + //} + return true; + } + #endregion + } +} diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs new file mode 100644 index 00000000..2b5978f9 --- /dev/null +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -0,0 +1,268 @@ +using FreeSql.Extensions.EntityUtil; +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace FreeSql { + partial class DbSet { + + Task DbContextExecCommandAsync() { + _dicUpdateTimes.Clear(); + return _ctx.ExecCommandAsync(); + } + + async Task DbContextBetchAddAsync(EntityState[] adds) { + if (adds.Any() == false) return 0; + var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(); + return affrows; + } + + #region Add + async Task AddPrivAsync(TEntity data, bool isCheck) { + if (isCheck && CanAdd(data, true) == false) return; + if (_tableIdentitys.Length > 0) { + //有自增,马上执行 + switch (_fsql.Ado.DataType) { + case DataType.SqlServer: + case DataType.PostgreSQL: + if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { + await DbContextExecCommandAsync(); + var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); + IncrAffrows(1); + _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + await AddOrUpdateNavigateListAsync(data); + } else { + await DbContextExecCommandAsync(); + var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); + IncrAffrows(1); + _fsql.MapEntityValue(_entityType, newval, data); + Attach(newval); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + await AddOrUpdateNavigateListAsync(data); + } + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { + await DbContextExecCommandAsync(); + var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); + IncrAffrows(1); + _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + await AddOrUpdateNavigateListAsync(data); + } + return; + } + } + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + await AddOrUpdateNavigateListAsync(data); + } + public Task AddAsync(TEntity data) => AddPrivAsync(data, true); + async public Task AddRangeAsync(IEnumerable data) { + if (CanAdd(data, true) == false) return; + if (data.ElementAtOrDefault(1) == default(TEntity)) { + await AddAsync(data.First()); + return; + } + if (_tableIdentitys.Length > 0) { + //有自增,马上执行 + switch (_fsql.Ado.DataType) { + case DataType.SqlServer: + case DataType.PostgreSQL: + await DbContextExecCommandAsync(); + var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); + var idx = 0; + foreach (var s in data) + _fsql.MapEntityValue(_entityType, rets[idx++], s); + IncrAffrows(rets.Count); + AttachRange(rets); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + await AddOrUpdateNavigateListAsync(item); + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + foreach (var s in data) + await AddPrivAsync(s, false); + return; + } + } else { + //进入队列,等待 SaveChanges 时执行 + foreach (var item in data) + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); + AttachRange(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + await AddOrUpdateNavigateListAsync(item); + } + } + async Task AddOrUpdateNavigateListAsync(TEntity item) { + Type itemType = null; + foreach (var prop in _table.Properties) { + if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; + if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; + var tref = _table.GetTableRef(prop.Key, true); + if (tref == null) continue; + + switch (tref.RefType) { + case Internal.Model.TableRefType.OneToOne: + case Internal.Model.TableRefType.ManyToOne: + case Internal.Model.TableRefType.ManyToMany: + continue; + case Internal.Model.TableRefType.OneToMany: + if (itemType == null) itemType = item.GetType(); + if (_table.TypeLazy != null && itemType == _table.TypeLazy) { + var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => + _table.TypeLazy.GetField($"__lazy__{propName}", System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + if (lazyField != null) { + var lazyFieldValue = (bool)lazyField.GetValue(item); + if (lazyFieldValue == false) continue; + } + } + var propVal = prop.Value.GetValue(item); + var propValEach = propVal as IEnumerable; + if (propValEach == null) continue; + object dbset = null; + System.Reflection.MethodInfo dbsetAddOrUpdate = null; + foreach (var propValItem in propValEach) { + if (dbset == null) { + dbset = _ctx.Set(tref.RefEntityType); + dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdateAsync", new Type[] { tref.RefEntityType }); + } + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { + tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName] + .SetValue(propValItem, tref.Columns[colidx].Table.Properties[tref.Columns[colidx].CsName].GetValue(item)); + } + Task task = dbsetAddOrUpdate.Invoke(dbset, new object[] { propValItem }) as Task; + await task; + } + break; + } + } + } + #endregion + + #region UpdateAsync + Task DbContextBetchUpdateAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, false); + Task DbContextBetchUpdateNowAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, true); + async Task DbContextBetchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate) { + if (ups.Any() == false) return 0; + var uplst1 = ups[ups.Length - 1]; + var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; + + if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; + var lstval2 = default(EntityState); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(_entityType, uplst2.Value)}"); + + var cuig1 = _fsql.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; + + List data = null; + string[] cuig = null; + if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { + //最后一个不保存 + data = ups.ToList(); + data.RemoveAt(ups.Length - 1); + cuig = cuig2; + } else if (isLiveUpdate) { + //立即保存 + data = ups.ToList(); + cuig = cuig1; + } + + if (data?.Count > 0) { + + if (cuig.Length == _table.Columns.Count) + return ups.Length == data.Count ? -998 : -997; + + var updateSource = data.Select(a => a.Value).ToArray(); + var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); + + var affrows = await update.ExecuteAffrowsAsync(); + + foreach (var newval in data) { + if (_states.TryGetValue(newval.Key, out var tryold)) + _fsql.MapEntityValue(_entityType, newval.Value, tryold.Value); + if (newval.OldValue != null) + _fsql.MapEntityValue(_entityType, newval.Value, newval.OldValue); + } + return affrows; + } + + //等待下次对比再保存 + return 0; + } + async public Task UpdateAsync(TEntity data) { + var exists = ExistsInStates(data); + if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (exists == false) { + var olddata = await OrmSelect(data).FirstAsync(); + if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_fsql.GetEntityString(_entityType, data)}"); + } + + await UpdateRangePrivAsync(new[] { data }, true); + } + public Task UpdateRangeAsync(IEnumerable data) => UpdateRangePrivAsync(data, true); + async Task UpdateRangePrivAsync(IEnumerable data, bool isCheck) { + if (CanUpdate(data, true) == false) return; + foreach (var item in data) { + if (_dicUpdateTimes.ContainsKey(item)) + await DbContextExecCommandAsync(); + _dicUpdateTimes.Add(item, 1); + + var state = CreateEntityState(item); + state.OldValue = item; + EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); + } + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + await AddOrUpdateNavigateListAsync(item); + } + #endregion + + #region RemoveAsync + async Task DbContextBetchRemoveAsync(EntityState[] dels) { + if (dels.Any() == false) return 0; + var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); + return Math.Max(dels.Length, affrows); + } + #endregion + + #region AddOrUpdateAsync + async public Task AddOrUpdateAsync(TEntity data) { + if (data == null) throw new ArgumentNullException(nameof(data)); + if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + + var flagExists = ExistsInStates(data); + if (flagExists == false) { + var olddata = await OrmSelect(data).FirstAsync(); + if (olddata == null) flagExists = false; + } + + if (flagExists == true && CanUpdate(data, false)) { + await DbContextExecCommandAsync(); + var affrows = _ctx._affrows; + await UpdateRangePrivAsync(new[] { data }, false); + await DbContextExecCommandAsync(); + affrows = _ctx._affrows - affrows; + if (affrows > 0) return; + } + if (CanAdd(data, false)) { + _fsql.ClearEntityPrimaryValueWithIdentity(_entityType, data); + await AddPrivAsync(data, false); + } + } + #endregion + } +} diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs new file mode 100644 index 00000000..c41c1d77 --- /dev/null +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -0,0 +1,305 @@ +using FreeSql.Extensions.EntityUtil; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; +using System.Reflection; + +namespace FreeSql { + partial class DbSet { + + void DbContextExecCommand() { + _dicUpdateTimes.Clear(); + _ctx.ExecCommand(); + } + + int DbContextBetchAdd(EntityState[] adds) { + if (adds.Any() == false) return 0; + var affrows = this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrows(); + return affrows; + } + + #region Add + void AddPriv(TEntity data, bool isCheck) { + if (isCheck && CanAdd(data, true) == false) return; + if (_tableIdentitys.Length > 0) { + //有自增,马上执行 + switch (_fsql.Ado.DataType) { + case DataType.SqlServer: + case DataType.PostgreSQL: + if (_tableIdentitys.Length == 1) { + DbContextExecCommand(); + var idtval = this.OrmInsert(data).ExecuteIdentity(); + IncrAffrows(1); + _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + AddOrUpdateNavigateList(data); + } else { + DbContextExecCommand(); + var newval = this.OrmInsert(data).ExecuteInserted().First(); + IncrAffrows(1); + _fsql.MapEntityValue(_entityType, newval, data); + Attach(newval); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + AddOrUpdateNavigateList(data); + } + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + if (_tableIdentitys.Length == 1) { + DbContextExecCommand(); + var idtval = this.OrmInsert(data).ExecuteIdentity(); + IncrAffrows(1); + _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + AddOrUpdateNavigateList(data); + } + return; + } + } + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + AddOrUpdateNavigateList(data); + } + /// + /// 添加 + /// + /// + public void Add(TEntity data) => AddPriv(data, true); + public void AddRange(IEnumerable data) { + if (CanAdd(data, true) == false) return; + if (data.ElementAtOrDefault(1) == default(TEntity)) { + Add(data.First()); + return; + } + if (_tableIdentitys.Length > 0) { + //有自增,马上执行 + switch (_fsql.Ado.DataType) { + case DataType.SqlServer: + case DataType.PostgreSQL: + DbContextExecCommand(); + var rets = this.OrmInsert(data).ExecuteInserted(); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); + var idx = 0; + foreach (var s in data) + _fsql.MapEntityValue(_entityType, rets[idx++], s); + IncrAffrows(rets.Count); + AttachRange(rets); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + AddOrUpdateNavigateList(item); + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + foreach (var s in data) + AddPriv(s, false); + return; + } + } else { + //进入队列,等待 SaveChanges 时执行 + foreach (var item in data) + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); + AttachRange(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + AddOrUpdateNavigateList(item); + } + } + static ConcurrentDictionary> _dicLazyIsSetField = new ConcurrentDictionary>(); + void AddOrUpdateNavigateList(TEntity item) { + Type itemType = null; + foreach (var prop in _table.Properties) { + if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; + if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; + + object propVal = null; + + if (itemType == null) itemType = item.GetType(); + if (_table.TypeLazy != null && itemType == _table.TypeLazy) { + var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => + _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); + if (lazyField != null) { + var lazyFieldValue = (bool)lazyField.GetValue(item); + if (lazyFieldValue == false) continue; + } + propVal = prop.Value.GetValue(item); + } else { + propVal = prop.Value.GetValue(item); + if (propVal == null) continue; + } + + var tref = _table.GetTableRef(prop.Key, true); + if (tref == null) continue; + + switch(tref.RefType) { + case Internal.Model.TableRefType.OneToOne: + case Internal.Model.TableRefType.ManyToOne: + case Internal.Model.TableRefType.ManyToMany: + continue; + case Internal.Model.TableRefType.OneToMany: + var propValEach = propVal as IEnumerable; + if (propValEach == null) continue; + object dbset = null; + MethodInfo dbsetAddOrUpdate = null; + foreach (var propValItem in propValEach) { + if (dbset == null) { + dbset = _ctx.Set(tref.RefEntityType); + dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdate", new Type[] { tref.RefEntityType }); + } + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { + tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName] + .SetValue(propValItem, tref.Columns[colidx].Table.Properties[tref.Columns[colidx].CsName].GetValue(item)); + } + dbsetAddOrUpdate.Invoke(dbset, new object[] { propValItem }); + } + break; + } + } + } + #endregion + + #region Update + int DbContextBetchUpdate(EntityState[] ups) => DbContextBetchUpdatePriv(ups, false); + int DbContextBetchUpdateNow(EntityState[] ups) => DbContextBetchUpdatePriv(ups, true); + int DbContextBetchUpdatePriv(EntityState[] ups, bool isLiveUpdate) { + if (ups.Any() == false) return 0; + var uplst1 = ups[ups.Length - 1]; + var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; + + if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; + var lstval2 = default(EntityState); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(_entityType, uplst2.Value)}"); + + var cuig1 = _fsql.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; + + List data = null; + string[] cuig = null; + if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { + //最后一个不保存 + data = ups.ToList(); + data.RemoveAt(ups.Length - 1); + cuig = cuig2; + } else if (isLiveUpdate) { + //立即保存 + data = ups.ToList(); + cuig = cuig1; + } + + if (data?.Count > 0) { + + if (cuig.Length == _table.Columns.Count) + return ups.Length == data.Count ? -998 : -997; + + var updateSource = data.Select(a => a.Value).ToArray(); + var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); + + var affrows = update.ExecuteAffrows(); + + foreach (var newval in data) { + if (_states.TryGetValue(newval.Key, out var tryold)) + _fsql.MapEntityValue(_entityType, newval.Value, tryold.Value); + if (newval.OldValue != null) + _fsql.MapEntityValue(_entityType, newval.Value, newval.OldValue); + } + return affrows; + } + + //等待下次对比再保存 + return 0; + } + + Dictionary _dicUpdateTimes = new Dictionary(); + /// + /// 更新 + /// + /// + public void Update(TEntity data) { + var exists = ExistsInStates(data); + if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (exists == false) { + var olddata = OrmSelect(data).First(); + if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_fsql.GetEntityString(_entityType, data)}"); + } + + UpdateRangePriv(new[] { data }, true); + } + public void UpdateRange(IEnumerable data) => UpdateRangePriv(data, true); + void UpdateRangePriv(IEnumerable data, bool isCheck) { + if (CanUpdate(data, true) == false) return; + foreach (var item in data) { + if (_dicUpdateTimes.ContainsKey(item)) + DbContextExecCommand(); + _dicUpdateTimes.Add(item, 1); + + var state = CreateEntityState(item); + state.OldValue = item; + EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); + } + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + AddOrUpdateNavigateList(item); + } + #endregion + + #region Remove + int DbContextBetchRemove(EntityState[] dels) { + if (dels.Any() == false) return 0; + var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); + return Math.Max(dels.Length, affrows); + } + + /// + /// 删除 + /// + /// + public void Remove(TEntity data) => RemoveRange(new[] { data }); + public void RemoveRange(IEnumerable data) { + if (CanRemove(data, true) == false) return; + foreach (var item in data) { + var state = CreateEntityState(item); + _states.TryRemove(state.Key, out var trystate); + _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, item); + + EnqueueToDbContext(DbContext.ExecCommandInfoType.Delete, state); + } + } + #endregion + + #region AddOrUpdate + /// + /// 添加或更新 + /// + /// + public void AddOrUpdate(TEntity data) { + if (data == null) throw new ArgumentNullException(nameof(data)); + if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + + var flagExists = ExistsInStates(data); + if (flagExists == false) { + var olddata = OrmSelect(data).First(); + if (olddata == null) flagExists = false; + } + + if (flagExists == true && CanUpdate(data, false)) { + DbContextExecCommand(); + var affrows = _ctx._affrows; + UpdateRangePriv(new[] { data }, false); + DbContextExecCommand(); + affrows = _ctx._affrows - affrows; + if (affrows > 0) return; + } + if (CanAdd(data, false)) { + _fsql.ClearEntityPrimaryValueWithIdentity(_entityType, data); + AddPriv(data, false); + } + } + #endregion + } +} diff --git a/FreeSql.DbContext/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Extenssions/DependencyInjection.cs new file mode 100644 index 00000000..a91635a5 --- /dev/null +++ b/FreeSql.DbContext/Extenssions/DependencyInjection.cs @@ -0,0 +1,32 @@ +#if ns20 + +using Microsoft.Extensions.DependencyInjection; +using System; + +namespace FreeSql { + public static class DbContextDependencyInjection { + + public static IServiceCollection AddFreeDbContext(this IServiceCollection services, Action options) where TDbContext : DbContext { + + services.AddScoped(sp => { + var ctx = Activator.CreateInstance(); + + if (ctx._orm == null) { + var builder = new DbContextOptionsBuilder(); + options(builder); + ctx._orm = builder._fsql; + + if (ctx._orm == null) + throw new Exception("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); + + ctx.InitPropSets(); + } + + return ctx; + }); + + return services; + } + } +} +#endif \ No newline at end of file diff --git a/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs b/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs new file mode 100644 index 00000000..7fae5c66 --- /dev/null +++ b/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs @@ -0,0 +1,38 @@ +using FreeSql; +using System; +using System.Collections.Concurrent; + +public static class FreeSqlDbContextExtenssions { + + /// + /// 创建普通数据上下文档对象 + /// + /// + /// + public static DbContext CreateDbContext(this IFreeSql that) { + return new FreeContext(that); + } + + /// + /// 不跟踪查询的实体数据(在不需要更新其数据时使用),可提长查询性能 + /// + /// + /// + /// + public static ISelect NoTracking(this ISelect select) where T : class { + return select.TrackToList(null); + } + + /// + /// 设置 DbContext 选项设置 + /// + /// + /// + public static void SetDbContextOptions(this IFreeSql that, Action options) { + if (options == null) return; + var cfg = _dicSetDbContextOptions.GetOrAdd(that, t => new DbContextOptions()); + options(cfg); + _dicSetDbContextOptions.AddOrUpdate(that, cfg, (t, o) => cfg); + } + internal static ConcurrentDictionary _dicSetDbContextOptions = new ConcurrentDictionary(); +} \ No newline at end of file diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj new file mode 100644 index 00000000..3371ed37 --- /dev/null +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -0,0 +1,36 @@ + + + + netstandard2.0;net45 + 0.7.1 + true + YeXiangQin + FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. + https://github.com/2881099/FreeSql.DbContext + FreeSql ORM DbContext + git + MIT + $(AssemblyName) + $(AssemblyName) + true + true + + + + FreeSql.DbContext.xml + 3 + + + + ns20;netstandard20 + + + + + + + + + + + diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml new file mode 100644 index 00000000..bdb7a92e --- /dev/null +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -0,0 +1,259 @@ + + + + FreeSql.DbContext + + + + + 添加 + + + + + + + 更新 + + + + + + + 删除 + + + + + + + 添加或更新 + + + + + + + 附加实体,可用于不查询就更新或删除 + + + + + + + 是否开启一对多,联级保存功能 + + + + + 动态Type,在使用 DbSet<object> 后使用本方法,指定实体类型 + + + + + + + 附加实体,可用于不查询就更新或删除 + + + + + + 清空状态数据 + + + + + 添加 + + + + + + 更新 + + + + + + 删除 + + + + + + 添加或更新 + + + + + + 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点 + + + + 数据过滤 + 验证 + + + + + 在工作单元内创建联合主键的仓储类,工作单元下的仓储操作具有事务特点 + + + 数据过滤 + 验证 + + + + + 在工作单元内创建仓库类,工作单元下的仓储操作具有事务特点 + + + 数据过滤 + 验证 + 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + + + + + 开启过滤器,若使用 using 则使用完后,恢复为原有状态 + + 过滤器名称 + + + + + 开启所有过滤器,若使用 using 则使用完后,恢复为原有状态 + + + + + + 禁用过滤器,若使用 using 则使用完后,恢复为原有状态 + + + + + + + 禁用所有过滤器,若使用 using 则使用完后,恢复为原有状态 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 + + + + + + + 清空状态数据 + + + + + 附加实体,可用于不查询就更新或删除 + + + + + + 是否启用工作单元 + + + + + 禁用工作单元 + + + 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 + + + + + 开启工作单元 + + + + + 是否启用工作单元 + + + + + 禁用工作单元 + + + 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 + + + + + 创建普通数据上下文档对象 + + + + + + + 不跟踪查询的实体数据(在不需要更新其数据时使用),可提长查询性能 + + + + + + + + 设置 DbContext 选项设置 + + + + + + + 返回默认仓库类 + + + + + 数据过滤 + 验证 + + + + + 返回默认仓库类,适用联合主键的仓储类 + + + + 数据过滤 + 验证 + + + + + 返回仓库类 + + + + 数据过滤 + 验证 + 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + + + + + 合并两个仓储的设置(过滤+分表),以便查询 + + + + + + + + + + 创建基于仓储功能的工作单元,务必使用 using 包含使用 + + + + + + diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs new file mode 100644 index 00000000..ac3dbf7a --- /dev/null +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Concurrent; +using System.Reflection; +using System.Threading.Tasks; + +namespace FreeSql { + internal class RepositoryDbContext : DbContext { + + protected IBaseRepository _repos; + public RepositoryDbContext(IFreeSql orm, IBaseRepository repos) : base() { + _orm = orm; + _repos = repos; + _isUseUnitOfWork = false; + _uowPriv = _repos.UnitOfWork; + } + + + static ConcurrentDictionary _dicGetRepositoryDbField = new ConcurrentDictionary(); + static FieldInfo GetRepositoryDbField(Type type) => _dicGetRepositoryDbField.GetOrAdd(type, tp => typeof(BaseRepository<,>).MakeGenericType(tp, typeof(int)).GetField("_dbPriv", BindingFlags.Instance | BindingFlags.NonPublic)); + public override IDbSet Set(Type entityType) { + if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; + + var tb = _orm.CodeFirst.GetTableByEntity(entityType); + if (tb == null) return null; + + object repos = _repos; + if (entityType != _repos.EntityType) { + repos = Activator.CreateInstance(typeof(DefaultRepository<,>).MakeGenericType(entityType, typeof(int)), _repos.Orm); + (repos as IBaseRepository).UnitOfWork = _repos.UnitOfWork; + GetRepositoryDbField(entityType).SetValue(repos, this); + + typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repos.EntityType) + .Invoke(null, new object[] { repos, _repos }); + } + + var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repos) as IDbSet; + if (entityType != typeof(object)) _dicSet.Add(entityType, sd); + return sd; + } + + public static void SetRepositoryDataFilter(object repos, BaseRepository baseRepo) where TEntity : class { + var filter = baseRepo.DataFilter as DataFilter; + DataFilterUtil.SetRepositoryDataFilter(repos, fl => { + foreach (var f in filter._filters) + fl.Apply(f.Key, f.Value.Expression); + }); + } + + public override int SaveChanges() { + ExecCommand(); + var ret = _affrows; + _affrows = 0; + return ret; + } + async public override Task SaveChangesAsync() { + await ExecCommandAsync(); + var ret = _affrows; + _affrows = 0; + return ret; + } + } +} diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs new file mode 100644 index 00000000..b50225ed --- /dev/null +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs @@ -0,0 +1,60 @@ +using FreeSql.Extensions.EntityUtil; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace FreeSql { + internal class RepositoryDbSet : DbSet where TEntity : class { + + protected BaseRepository _repos; + public RepositoryDbSet(BaseRepository repos) { + _ctx = repos._db; + _fsql = repos.Orm; + _uow = repos.UnitOfWork; + _repos = repos; + } + + protected override ISelect OrmSelect(object dywhere) { + var select = base.OrmSelect(dywhere); + + var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) select.Where(filter.Value.Expression); + return select.AsTable(_repos.AsTableSelectInternal); + } + internal ISelect OrmSelectInternal(object dywhere) => OrmSelect(dywhere); + protected override IUpdate OrmUpdate(IEnumerable entitys) { + var update = base.OrmUpdate(entitys); + var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) { + if (entitys != null) + foreach (var entity in entitys) + if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) + throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_fsql.GetEntityString(_entityType, entity)}"); + update.Where(filter.Value.Expression); + } + return update.AsTable(_repos.AsTableInternal); + } + internal IUpdate OrmUpdateInternal(IEnumerable entitys) => OrmUpdate(entitys); + protected override IDelete OrmDelete(object dywhere) { + var delete = base.OrmDelete(dywhere); + var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) delete.Where(filter.Value.Expression); + return delete.AsTable(_repos.AsTableInternal); + } + internal IDelete OrmDeleteInternal(object dywhere) => OrmDelete(dywhere); + protected override IInsert OrmInsert(TEntity entity) => OrmInsert(new[] { entity }); + protected override IInsert OrmInsert(IEnumerable entitys) { + var insert = base.OrmInsert(entitys); + var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) { + if (entitys != null) + foreach (var entity in entitys) + if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) + throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_fsql.GetEntityString(_entityType, entity)}"); + } + return insert.AsTable(_repos.AsTableInternal); + } + internal IInsert OrmInsertInternal(TEntity entity) => OrmInsert(entity); + internal IInsert OrmInsertInternal(IEnumerable entitys) => OrmInsert(entitys); + } +} diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs new file mode 100644 index 00000000..d36c4887 --- /dev/null +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs @@ -0,0 +1,57 @@ +using System; +using System.Linq.Expressions; + +namespace FreeSql { + + public interface IRepositoryUnitOfWork : IUnitOfWork { + /// + /// 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点 + /// + /// + /// + /// 数据过滤 + 验证 + /// + DefaultRepository GetRepository(Expression> filter = null) where TEntity : class; + + /// + /// 在工作单元内创建联合主键的仓储类,工作单元下的仓储操作具有事务特点 + /// + /// + /// 数据过滤 + 验证 + /// + BaseRepository GetRepository(Expression> filter = null) where TEntity : class; + + /// + /// 在工作单元内创建仓库类,工作单元下的仓储操作具有事务特点 + /// + /// + /// 数据过滤 + 验证 + /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + /// + GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class; + } + + class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork { + + public RepositoryUnitOfWork(IFreeSql fsql) : base(fsql) { + } + + public GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class { + var repos = new GuidRepository(_fsql, filter, asTable); + repos.UnitOfWork = this; + return repos; + } + + public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class { + var repos = new DefaultRepository(_fsql, filter); + repos.UnitOfWork = this; + return repos; + } + + public BaseRepository GetRepository(Expression> filter = null) where TEntity : class { + var repos = new DefaultRepository(_fsql, filter); + repos.UnitOfWork = this; + return repos; + } + } +} diff --git a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs new file mode 100644 index 00000000..d65a3b0a --- /dev/null +++ b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq.Expressions; +using System.Linq; + +namespace FreeSql { + public interface IDataFilter : IDisposable where TEntity : class { + + IDataFilter Apply(string filterName, Expression> filterAndValidateExp); + + /// + /// 开启过滤器,若使用 using 则使用完后,恢复为原有状态 + /// + /// 过滤器名称 + /// + IDisposable Enable(params string[] filterName); + /// + /// 开启所有过滤器,若使用 using 则使用完后,恢复为原有状态 + /// + /// + IDisposable EnableAll(); + + /// + /// 禁用过滤器,若使用 using 则使用完后,恢复为原有状态 + /// + /// + /// + IDisposable Disable(params string[] filterName); + /// + /// 禁用所有过滤器,若使用 using 则使用完后,恢复为原有状态 + /// + /// + IDisposable DisableAll(); + + bool IsEnabled(string filterName); + } + + internal class DataFilter : IDataFilter where TEntity : class { + + internal class FilterItem { + public Expression> Expression { get; set; } + Func _expressionDelegate; + public Func ExpressionDelegate => _expressionDelegate ?? (_expressionDelegate = Expression?.Compile()); + public bool IsEnabled { get; set; } + } + + internal ConcurrentDictionary _filters = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + public IDataFilter Apply(string filterName, Expression> filterAndValidateExp) { + + if (filterName == null) + throw new ArgumentNullException(nameof(filterName)); + if (filterAndValidateExp == null) return this; + + var filterItem = new FilterItem { Expression = filterAndValidateExp, IsEnabled = true }; + _filters.AddOrUpdate(filterName, filterItem, (k, v) => filterItem); + return this; + } + + public IDisposable Disable(params string[] filterName) { + if (filterName == null || filterName.Any() == false) return new UsingAny(() => { }); + + List restore = new List(); + foreach (var name in filterName) { + if (_filters.TryGetValue(name, out var tryfi)) { + if (tryfi.IsEnabled) { + restore.Add(name); + tryfi.IsEnabled = false; + } + } + } + return new UsingAny(() => this.Enable(restore.ToArray())); + } + public IDisposable DisableAll() { + List restore = new List(); + foreach (var val in _filters) { + if (val.Value.IsEnabled) { + restore.Add(val.Key); + val.Value.IsEnabled = false; + } + } + return new UsingAny(() => this.Enable(restore.ToArray())); + } + class UsingAny : IDisposable { + Action _ondis; + public UsingAny(Action ondis) { + _ondis = ondis; + } + public void Dispose() { + _ondis?.Invoke(); + } + } + + public IDisposable Enable(params string[] filterName) { + if (filterName == null || filterName.Any() == false) return new UsingAny(() => { }); + + List restore = new List(); + foreach (var name in filterName) { + if (_filters.TryGetValue(name, out var tryfi)) { + if (tryfi.IsEnabled == false) { + restore.Add(name); + tryfi.IsEnabled = true; + } + } + } + return new UsingAny(() => this.Disable(restore.ToArray())); + } + public IDisposable EnableAll() { + List restore = new List(); + foreach (var val in _filters) { + if (val.Value.IsEnabled == false) { + restore.Add(val.Key); + val.Value.IsEnabled = true; + } + } + return new UsingAny(() => this.Disable(restore.ToArray())); + } + + public bool IsEnabled(string filterName) { + if (filterName == null) return false; + return _filters.TryGetValue(filterName, out var tryfi) ? tryfi.IsEnabled : false; + } + + ~DataFilter() { + this.Dispose(); + } + public void Dispose() { + _filters.Clear(); + } + } + + public class FluentDataFilter : IDisposable { + + internal List<(Type type, string name, LambdaExpression exp)> _filters = new List<(Type type, string name, LambdaExpression exp)>(); + + public FluentDataFilter Apply(string filterName, Expression> filterAndValidateExp) where TEntity : class { + if (filterName == null) + throw new ArgumentNullException(nameof(filterName)); + if (filterAndValidateExp == null) return this; + + _filters.Add((typeof(TEntity), filterName, filterAndValidateExp)); + return this; + } + + ~FluentDataFilter() { + this.Dispose(); + } + public void Dispose() { + _filters.Clear(); + } + } +} diff --git a/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs b/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs new file mode 100644 index 00000000..b94905b4 --- /dev/null +++ b/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace FreeSql { + + internal class DataFilterUtil { + + internal static Action _globalDataFilter; + + static ConcurrentDictionary _dicSetRepositoryDataFilterApplyDataFilterFunc = new ConcurrentDictionary(); + static ConcurrentDictionary> _dicSetRepositoryDataFilterConvertFilterNotExists = new ConcurrentDictionary>(); + internal static void SetRepositoryDataFilter(object repos, Action scopedDataFilter) { + if (scopedDataFilter != null) { + SetRepositoryDataFilter(repos, null); + } + if (scopedDataFilter == null) { + scopedDataFilter = _globalDataFilter; + } + if (scopedDataFilter == null) return; + using (var globalFilter = new FluentDataFilter()) { + scopedDataFilter(globalFilter); + + var type = repos.GetType(); + Type entityType = (repos as IBaseRepository).EntityType; + if (entityType == null) throw new Exception("FreeSql.Repository 设置过滤器失败,原因是对象不属于 IRepository"); + + var notExists = _dicSetRepositoryDataFilterConvertFilterNotExists.GetOrAdd(type, t => new ConcurrentDictionary()); + var newFilter = new Dictionary(); + foreach (var gf in globalFilter._filters) { + if (notExists.ContainsKey(gf.name)) continue; + + LambdaExpression newExp = null; + var filterParameter1 = Expression.Parameter(entityType, gf.exp.Parameters[0].Name); + try { + newExp = Expression.Lambda( + typeof(Func<,>).MakeGenericType(entityType, typeof(bool)), + new ReplaceVisitor().Modify(gf.exp.Body, filterParameter1), + filterParameter1 + ); + } catch { + notExists.TryAdd(gf.name, true); //防止第二次错误 + continue; + } + newFilter.Add(gf.name, newExp); + } + if (newFilter.Any() == false) return; + + var del = _dicSetRepositoryDataFilterApplyDataFilterFunc.GetOrAdd(type, t => { + var reposParameter = Expression.Parameter(type); + var nameParameter = Expression.Parameter(typeof(string)); + var expressionParameter = Expression.Parameter( + typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(entityType, typeof(bool))) + ); + return Expression.Lambda( + Expression.Block( + Expression.Call(reposParameter, type.GetMethod("ApplyDataFilter", BindingFlags.Instance | BindingFlags.NonPublic), nameParameter, expressionParameter) + ), + new[] { + reposParameter, nameParameter, expressionParameter + } + ).Compile(); + }); + foreach (var nf in newFilter) { + del.DynamicInvoke(repos, nf.Key, nf.Value); + } + newFilter.Clear(); + } + } + } + + class ReplaceVisitor : ExpressionVisitor { + private ParameterExpression parameter; + + public Expression Modify(Expression expression, ParameterExpression parameter) { + this.parameter = parameter; + return Visit(expression); + } + + protected override Expression VisitMember(MemberExpression node) { + if (node.Expression?.NodeType == ExpressionType.Parameter) + return Expression.Property(parameter, node.Member.Name); + return base.VisitMember(node); + } + } +} diff --git a/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs new file mode 100644 index 00000000..9265774d --- /dev/null +++ b/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs @@ -0,0 +1,39 @@ +#if ns20 + +using System; +using System.Reflection; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; + +namespace FreeSql { + public static class FreeSqlRepositoryDependencyInjection { + + public static IServiceCollection AddFreeRepository(this IServiceCollection services, Action globalDataFilter = null, params Assembly[] assemblies) { + + DataFilterUtil._globalDataFilter = globalDataFilter; + + services.AddScoped(typeof(IReadOnlyRepository<>), typeof(GuidRepository<>)); + services.AddScoped(typeof(IBasicRepository<>), typeof(GuidRepository<>)); + services.AddScoped(typeof(BaseRepository<>), typeof(GuidRepository<>)); + services.AddScoped(typeof(GuidRepository<>)); + + services.AddScoped(typeof(IReadOnlyRepository<,>), typeof(DefaultRepository<,>)); + services.AddScoped(typeof(IBasicRepository<,>), typeof(DefaultRepository<,>)); + services.AddScoped(typeof(BaseRepository<,>), typeof(DefaultRepository<,>)); + services.AddScoped(typeof(DefaultRepository<,>)); + + if (assemblies?.Any() == true) { + foreach(var asse in assemblies) { + foreach (var repos in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(IBaseRepository).IsAssignableFrom(a))) { + + services.AddScoped(repos); + } + } + } + + return services; + } + } +} + +#endif \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs new file mode 100644 index 00000000..5c4fedd3 --- /dev/null +++ b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs @@ -0,0 +1,65 @@ +using FreeSql; +using System; +using System.Linq.Expressions; +using System.Linq; + +public static class FreeSqlRepositoryExtenssions { + + /// + /// 返回默认仓库类 + /// + /// + /// + /// + /// 数据过滤 + 验证 + /// + public static DefaultRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { + return new DefaultRepository(that, filter); + } + + /// + /// 返回默认仓库类,适用联合主键的仓储类 + /// + /// + /// + /// 数据过滤 + 验证 + /// + public static BaseRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { + return new DefaultRepository(that, filter); + } + + /// + /// 返回仓库类 + /// + /// + /// + /// 数据过滤 + 验证 + /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + /// + public static GuidRepository GetGuidRepository(this IFreeSql that, Expression> filter = null, Func asTable = null) where TEntity : class { + return new GuidRepository(that, filter, asTable); + } + + /// + /// 合并两个仓储的设置(过滤+分表),以便查询 + /// + /// + /// + /// + /// + /// + public static ISelect FromRepository(this ISelect that, BaseRepository repos) where TEntity : class where T2 : class { + var filters = (repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) that.Where(filter.Value.Expression); + return that.AsTable(repos.AsTableSelectInternal); + } + + /// + /// 创建基于仓储功能的工作单元,务必使用 using 包含使用 + /// + /// + /// + public static IRepositoryUnitOfWork CreateUnitOfWork(this IFreeSql that) { + return new RepositoryUnitOfWork(that); + } +} \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs new file mode 100644 index 00000000..5ecbd52d --- /dev/null +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql { + public abstract class BaseRepository : IBaseRepository + where TEntity : class { + + internal RepositoryDbContext _dbPriv; + internal RepositoryDbContext _db => _dbPriv ?? (_dbPriv = new RepositoryDbContext(Orm, this)); + internal RepositoryDbSet _dbsetPriv; + internal RepositoryDbSet _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set() as RepositoryDbSet); + public IDataFilter DataFilter { get; } = new DataFilter(); + Func _asTableVal; + protected Func AsTable { + get => _asTableVal; + set { + _asTableVal = value; + AsTableSelect = value == null ? null : new Func((a, b) => a == EntityType ? value(b) : null); + } + } + internal Func AsTableInternal => AsTable; + protected Func AsTableSelect { get; private set; } + internal Func AsTableSelectInternal => AsTableSelect; + + protected void ApplyDataFilter(string name, Expression> exp) => DataFilter.Apply(name, exp); + + protected BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) { + Orm = fsql; + DataFilterUtil.SetRepositoryDataFilter(this, null); + DataFilter.Apply("", filter); + AsTable = asTable; + } + + ~BaseRepository() { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() { + if (_isdisposed) return; + try { + _dbsetPriv?.Dispose(); + _dbPriv?.Dispose(); + this.DataFilter.Dispose(); + } finally { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + public Type EntityType => _dbsetPriv?.EntityType ?? typeof(TEntity); + public void AsType(Type entityType) => _dbset.AsType(entityType); + + public IFreeSql Orm { get; private set; } + public IUnitOfWork UnitOfWork { get; set; } + public IUpdate UpdateDiy => _dbset.OrmUpdateInternal(null); + + public ISelect Select => _dbset.OrmSelectInternal(null); + public ISelect Where(Expression> exp) => _dbset.OrmSelectInternal(null).Where(exp); + public ISelect WhereIf(bool condition, Expression> exp) => _dbset.OrmSelectInternal(null).WhereIf(condition, exp); + + public int Delete(Expression> predicate) => _dbset.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows(); + public Task DeleteAsync(Expression> predicate) => _dbset.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync(); + + public int Delete(TEntity entity) { + _dbset.Remove(entity); + return _db.SaveChanges(); + } + public Task DeleteAsync(TEntity entity) { + _dbset.Remove(entity); + return _db.SaveChangesAsync(); + } + public int Delete(IEnumerable entitys) { + _dbset.RemoveRange(entitys); + return _db.SaveChanges(); + } + public Task DeleteAsync(IEnumerable entitys) { + _dbset.RemoveRange(entitys); + return _db.SaveChangesAsync(); + } + + public virtual TEntity Insert(TEntity entity) { + _dbset.Add(entity); + _db.SaveChanges(); + return entity; + } + async public virtual Task InsertAsync(TEntity entity) { + await _dbset.AddAsync(entity); + _db.SaveChanges(); + return entity; + } + public virtual List Insert(IEnumerable entitys) { + _dbset.AddRange(entitys); + _db.SaveChanges(); + return entitys.ToList(); + } + async public virtual Task> InsertAsync(IEnumerable entitys) { + await _dbset.AddRangeAsync(entitys); + await _db.SaveChangesAsync(); + return entitys.ToList(); + } + + public int Update(TEntity entity) { + _dbset.Update(entity); + return _db.SaveChanges(); + } + public Task UpdateAsync(TEntity entity) { + _dbset.Update(entity); + return _db.SaveChangesAsync(); + } + public int Update(IEnumerable entitys) { + _dbset.UpdateRange(entitys); + return _db.SaveChanges(); + } + public Task UpdateAsync(IEnumerable entitys) { + _dbset.UpdateRange(entitys); + return _db.SaveChangesAsync(); + } + + public void Attach(TEntity data) => _db.Attach(data); + public void Attach(IEnumerable data) => _db.AttachRange(data); + public void FlushState() => _dbset.FlushState(); + + public TEntity InsertOrUpdate(TEntity entity) { + _dbset.AddOrUpdate(entity); + _db.SaveChanges(); + return entity; + } + async public Task InsertOrUpdateAsync(TEntity entity) { + await _dbset.AddOrUpdateAsync(entity); + _db.SaveChanges(); + return entity; + } + } + + public abstract class BaseRepository : BaseRepository, IBaseRepository + where TEntity : class { + + public BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base(fsql, filter, asTable) { + } + + public int Delete(TKey id) { + var stateKey = string.Concat(id); + _dbset._statesInternal.TryRemove(stateKey, out var trystate); + return _dbset.OrmDeleteInternal(id).ExecuteAffrows(); + } + public Task DeleteAsync(TKey id) { + var stateKey = string.Concat(id); + _dbset._statesInternal.TryRemove(stateKey, out var trystate); + return _dbset.OrmDeleteInternal(id).ExecuteAffrowsAsync(); + } + + public TEntity Find(TKey id) => _dbset.OrmSelectInternal(id).ToOne(); + public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(id).ToOneAsync(); + + public TEntity Get(TKey id) => Find(id); + public Task GetAsync(TKey id) => FindAsync(id); + } +} diff --git a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs new file mode 100644 index 00000000..8a711e2f --- /dev/null +++ b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs @@ -0,0 +1,16 @@ +using System; +using System.Linq.Expressions; + +namespace FreeSql { + public class DefaultRepository : + BaseRepository + where TEntity : class { + + public DefaultRepository(IFreeSql fsql) : base(fsql, null, null) { + + } + + public DefaultRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter, null) { + } + } +} diff --git a/FreeSql.DbContext/Repository/Repository/GuidRepository.cs b/FreeSql.DbContext/Repository/Repository/GuidRepository.cs new file mode 100644 index 00000000..f7eba195 --- /dev/null +++ b/FreeSql.DbContext/Repository/Repository/GuidRepository.cs @@ -0,0 +1,15 @@ +using System; +using System.Linq.Expressions; + +namespace FreeSql { + public class GuidRepository : + BaseRepository + where TEntity : class { + + public GuidRepository(IFreeSql fsql) : this(fsql, null, null) { + + } + public GuidRepository(IFreeSql fsql, Expression> filter, Func asTable) : base(fsql, filter, asTable) { + } + } +} diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs new file mode 100644 index 00000000..f1919f29 --- /dev/null +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -0,0 +1,30 @@ +using System; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql { + + public interface IBaseRepository : IDisposable { + Type EntityType { get; } + IUnitOfWork UnitOfWork { get; set; } + IFreeSql Orm { get; } + + /// + /// 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 + /// + /// + /// + void AsType(Type entityType); + } + + public interface IBaseRepository : IReadOnlyRepository, IBasicRepository + where TEntity : class { + int Delete(Expression> predicate); + + Task DeleteAsync(Expression> predicate); + } + + public interface IBaseRepository : IBaseRepository, IReadOnlyRepository, IBasicRepository + where TEntity : class { + } +} \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs new file mode 100644 index 00000000..33d79ec6 --- /dev/null +++ b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace FreeSql { + public interface IBasicRepository : IReadOnlyRepository + where TEntity : class { + TEntity Insert(TEntity entity); + List Insert(IEnumerable entitys); + Task InsertAsync(TEntity entity); + Task> InsertAsync(IEnumerable entitys); + + /// + /// 清空状态数据 + /// + void FlushState(); + /// + /// 附加实体,可用于不查询就更新或删除 + /// + /// + void Attach(TEntity entity); + void Attach(IEnumerable entity); + int Update(TEntity entity); + int Update(IEnumerable entitys); + Task UpdateAsync(TEntity entity); + Task UpdateAsync(IEnumerable entitys); + + TEntity InsertOrUpdate(TEntity entity); + Task InsertOrUpdateAsync(TEntity entity); + + IUpdate UpdateDiy { get; } + + int Delete(TEntity entity); + int Delete(IEnumerable entitys); + Task DeleteAsync(TEntity entity); + Task DeleteAsync(IEnumerable entitys); + } + + public interface IBasicRepository : IBasicRepository, IReadOnlyRepository + where TEntity : class { + int Delete(TKey id); + + Task DeleteAsync(TKey id); + } +} + diff --git a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs b/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs new file mode 100644 index 00000000..8b2f47ee --- /dev/null +++ b/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs @@ -0,0 +1,27 @@ +using System; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql { + public interface IReadOnlyRepository : IBaseRepository + where TEntity : class { + + IDataFilter DataFilter { get; } + + ISelect Select { get; } + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + } + + public interface IReadOnlyRepository : IReadOnlyRepository + where TEntity : class { + TEntity Get(TKey id); + + Task GetAsync(TKey id); + + TEntity Find(TKey id); + + Task FindAsync(TKey id); + } +} diff --git a/FreeSql.DbContext/TempExtensions.cs b/FreeSql.DbContext/TempExtensions.cs new file mode 100644 index 00000000..fbb7bd53 --- /dev/null +++ b/FreeSql.DbContext/TempExtensions.cs @@ -0,0 +1,5 @@ + +namespace FreeSql.Extensions.EntityUtil { + public static class TempExtensions { + } +} diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs new file mode 100644 index 00000000..8ded92ff --- /dev/null +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -0,0 +1,34 @@ +using System; +using System.Data; +using System.Data.Common; + +namespace FreeSql { + public interface IUnitOfWork : IDisposable { + + DbTransaction GetOrBeginTransaction(bool isCreate = true); + + IsolationLevel? IsolationLevel { get; set; } + + /// + /// 是否启用工作单元 + /// + bool Enable { get; } + + void Commit(); + + void Rollback(); + + /// + /// 禁用工作单元 + /// + /// + /// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 + /// + void Close(); + + /// + /// 开启工作单元 + /// + void Open(); + } +} diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs new file mode 100644 index 00000000..5cbaf016 --- /dev/null +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -0,0 +1,103 @@ +using SafeObjectPool; +using System; +using System.Data; +using System.Data.Common; + +namespace FreeSql { + class UnitOfWork : IUnitOfWork { + + protected IFreeSql _fsql; + protected Object _conn; + protected DbTransaction _tran; + + public UnitOfWork(IFreeSql fsql) { + _fsql = fsql; + } + + void ReturnObject() { + _fsql.Ado.MasterPool.Return(_conn); + _tran = null; + _conn = null; + } + + + /// + /// 是否启用工作单元 + /// + public bool Enable { get; private set; } = true; + + /// + /// 禁用工作单元 + /// + /// + /// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 + /// + public void Close() + { + if (_tran != null) + { + throw new Exception("已开启事务,不能禁用工作单元"); + } + + Enable = false; + } + + public void Open() + { + Enable = true; + } + + public IsolationLevel? IsolationLevel { get; set; } + + public DbTransaction GetOrBeginTransaction(bool isCreate = true) { + + if (_tran != null) return _tran; + if (isCreate == false) return null; + if (!Enable) return null; + if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); + + _conn = _fsql.Ado.MasterPool.Get(); + try { + _tran = IsolationLevel == null ? + _conn.Value.BeginTransaction() : + _conn.Value.BeginTransaction(IsolationLevel.Value); + } catch { + ReturnObject(); + throw; + } + return _tran; + } + + public void Commit() { + if (_tran != null) { + try { + _tran.Commit(); + } finally { + ReturnObject(); + } + } + } + public void Rollback() { + if (_tran != null) { + try { + _tran.Rollback(); + } finally { + ReturnObject(); + } + } + } + ~UnitOfWork() { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() { + if (_isdisposed) return; + try { + this.Rollback(); + } finally { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + } +} diff --git a/FreeSql.DbContext/readme.md b/FreeSql.DbContext/readme.md new file mode 100644 index 00000000..155847e5 --- /dev/null +++ b/FreeSql.DbContext/readme.md @@ -0,0 +1,284 @@ +这是 [FreeSql](https://github.com/2881099/FreeSql) 衍生出来的扩展包,包含 DbContext & DbSet、Repository & UnitOfWork 实现面向对象的特性(QQ群:4336577)。 + +> dotnet add package FreeSql.DbContext + +## 更新日志 + +### v0.6.5 + +- 修复 Repository 联级保存的 bug; +- 添加工作单元开启方法; +- 适配 .net framework 4.5、netstandard 2.0; + +### v0.6.1 + +- 拆分 FreeSql 小包引用,各数据库单独包、延时加载包; +- FreeSql.Extensions.LazyLoading +- FreeSql.Provider.MySql +- FreeSql.Provider.PostgreSQL +- FreeSql.Provider.SqlServer +- FreeSql.Provider.Sqlite +- FreeSql.Provider.Oracle +- 移除 IFreeSql.Cache,以及 ISelect.Caching 方法; +- 移除 IFreeSql.Log,包括内部原有的日志输出,改为 Trace.WriteLine; +- IAdo.Query\ 读取返回变为 List\\>; +- 定义 IFreeSql 和以前一样,移除了 UseCache、UseLogger 方法; + +## DbContext & DbSet + +```csharp +using (var ctx = new SongContext()) { + var song = new Song { BigNumber = "1000000000000000000" }; + ctx.Songs.Add(song); + + song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); + ctx.Songs.Update(song); + + var tag = new Tag { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + ctx.Tags.Add(tag); + + ctx.SaveChanges(); +} +``` + +## Repository & UnitOfWork + +仓储与工作单元一起使用,工作单元具有事务特点。 + +```csharp +using (var unitOfWork = fsql.CreateUnitOfWork()) { + var songRepository = unitOfWork.GetRepository(); + var tagRepository = unitOfWork.GetRepository(); + + var song = new Song { BigNumber = "1000000000000000000" }; + songRepository.Insert(song); + + songRepository.Update(song); + + song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); + songRepository.Update(song); + + var tag = new Tag { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + tagRepository.Insert(tag); + + ctx.Commit(); +} +``` + +## Repository + +简单使用仓储,有状态跟踪,它不包含事务的特点。 + +```csharp +var songRepository = fsql.GetRepository(); +var song = new Song { BigNumber = "1000000000000000000" }; +songRepository.Insert(song); +``` + +## IFreeSql 核心定义 + +```csharp +var fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseNoneCommandParameter(true) + + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .Build(); + +public class Song { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string BigNumber { get; set; } + + [Column(IsVersion = true)] //乐观锁 + public long versionRow { get; set; } +} +public class Tag { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public string Name { get; set; } + + public virtual ICollection Tags { get; set; } +} + +public class SongContext : DbContext { + public DbSet Songs { get; set; } + public DbSet Tags { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder builder) { + builder.UseFreeSql(fsql); + } +} +``` + +# 过滤器与验证 + +假设我们有User(用户)、Topic(主题)两个实体,在领域类中定义了两个仓储: + +```csharp +var userRepository = fsql.GetGuidRepository(); +var topicRepository = fsql.GetGuidRepository(); +``` + +在开发过程中,总是担心 topicRepository 的数据安全问题,即有可能查询或操作到其他用户的主题。因此我们在v0.0.7版本进行了改进,增加了 filter lambad 表达式参数。 + +```csharp +var userRepository = fsql.GetGuidRepository(a => a.Id == 1); +var topicRepository = fsql.GetGuidRepository(a => a.UserId == 1); +``` + +* 在查询/修改/删除时附加此条件,从而达到不会修改其他用户的数据; +* 在添加时,使用表达式验证数据的合法性,若不合法则抛出异常; + +# 分表与分库 + +FreeSql 提供 AsTable 分表的基础方法,GuidRepository 作为分存式仓储将实现了分表与分库(不支持跨服务器分库)的封装。 + +```csharp +var logRepository = fsql.GetGuidRepository(null, oldname => $"{oldname}_{DateTime.Now.ToString("YYYYMM")}"); +``` + +上面我们得到一个日志仓储按年月分表,使用它 CURD 最终会操作 Log_201903 表。 + +合并两个仓储,实现分表下的联表查询: + +```csharp +fsql.GetGuidRepository().Select.FromRepository(logRepository) + .LeftJoin(b => b.UserId == a.Id) + .ToList(); +``` + +注意事项: + +* 不能使用 CodeFirst 迁移分表,开发环境时仍然可以迁移 Log 表; +* 不可在分表分库的实体类型中使用《延时加载》; + +# 历史版本 + +### v0.5.23 + +- 增加 DbSet/Repository FlushState 手工清除状态管理数据; + +### v0.5.21 + +- 修复 AddOrUpdate/InsertOrUpdate 当主键无值时,仍然查询了一次数据库; +- 增加 查询数据时 TrackToList 对导航集合的状态跟踪; +- 完善 AddOrUpdateNavigateList 联级保存,忽略标记 IsIgnore 的集合属性; +- 完成 IFreeSql.Include、IncludeMany 功能; + +### v0.5.12 + +- 增加 工作单元开关,可在任意 Insert/Update/Delete 之前调用,以关闭工作单元使其失效;[PR #1](https://github.com/2881099/FreeSql.DbContext/pull/1) + +### v0.5.9 + +- 增加 linq to sql 的查询语法,以及单元测试,[wiki](https://github.com/2881099/FreeSql/wiki/LinqToSql); +- 修复 EnableAddOrUpdateNavigateList 设置对异步方法无效的 bug; + +### v0.5.8 + +- 增加 IFreeSql.SetDbContextOptions 设置 DbContext 的功能:开启或禁用连级一对多导航集合属性保存的功能,EnableAddOrUpdateNavigateList(默认开启); +- 增加 IUnitOfWork.IsolationLevel 设置事务级别; + +### v0.5.7 + +- 修复 UnitOfWork.GetRepository() 事务 bug,原因:仓储的每步操作都提交了事务; + +### v0.5.5 + +- 修复 MapEntityValue 对 IsIgnore 未处理的 bug; + +### v0.5.4 + +- 修复 Repository 追加导航集合的保存 bug; +- 公开 IRepository.Orm 对象; + +### v0.5.3 + +- 修复 实体跟踪的 bug,当查询到的实体自增值为 0 时重现; +- 优化 状态管理字典为 ConcurrentDictionary; + +### v0.5.2 + +- 优化 SqlServer UnitOfWork 使用bug,在 FreeSql 内部解决的; +- 补充 测试与支持联合主键的自增; + +### v0.5.1 + +- 补充 开放 DbContext.UnitOfWork 对象,方便扩展并保持在同一个事务执行; +- 补充 增加 DbSet\、Repository\ 使用方法,配合 AsType(实体类型),实现弱类型操作; +- 修复 DbContext.AddOrUpdate 传入 null 时,任然会查询一次数据库的 bug; +- 优化 DbContext.AddOrUpdate 未添加实体主键的错误提醒; +- 修复 DbContext.Set\ 缓存的 bug,使用多种弱类型时发生; +- 修复 IsIgnore 过滤字段后,查询的错误; +- 修复 全局过滤器功能迁移的遗留 bug; + +### v0.4.14 + +- 优化 Add 时未设置主键的错误提醒; + +### v0.4.13 + +- 补充 Repository 增加 Attach 方法; +- 优化 Update/AddOrUpdate 实体的时候,若状态管理不存在,尝试查询一次数据库,以便跟踪对象; + +### v0.4.12 + +- 修复 非自增情况下,Add 后再 Update 该实体时,错误(需要先 Attach 或查询)的 bug; + +### v0.4.10 + +- 补充 开放 DbContext.Orm 对象; +- 修复 OnConfiguring 未配置时注入获取失败的 bug; + +### v0.4.6 + +- 修复 DbSet AddRange/UpdateRange/RemoveRange 参数为空列表时报错,现在不用判断 data.Any() == true 再执行; +- 增加 DbContext 对 DbSet 的快速代理方法(Add/Update/Remove/Attach); +- 增加 DbContext 通用类,命名为:FreeContext,也可以通过 IFreeSql 扩展方法 CreateDbContext 创建; +- 增加 ISelect NoTracking 扩展方法,查询数据时不追踪(从而提升查询性能); + +### v0.4.5 + +- 增加 DbSet Attach 方法附加实体,可用于不查询就更新或删除; + +### v0.4.2 + +- 增加 DbSet UpdateAsync/UpdateRangeAsync 方法,当一个实体被更新两次时,会先执行前面的队列; +- 增加 GetRepository 获取联合主键的适用仓储类; +- 增加 DbSet 在 Add/Update 时对导航属性(OneToMany) 的处理(AddOrUpdate); + +### v0.4.1 +- 独立 FreeSql.DbContext 项目; +- 实现 Repository + DbSet 统一的状态跟踪与工作单元; +- 增加 DbSet AddOrUpdate 方法; +- 增加 Repository InsertOrUpdate 方法; \ No newline at end of file diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj new file mode 100644 index 00000000..a0b504d7 --- /dev/null +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -0,0 +1,23 @@ + + + + netstandard2.0;net45 + 0.7.1 + YeXiangQin + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. + https://github.com/2881099/FreeSql/wiki/Repository + FreeSql ORM Repository + true + git + MIT + $(AssemblyName) + $(AssemblyName) + true + true + + + + + + + diff --git a/FreeSql.Repository/readme.md b/FreeSql.Repository/readme.md new file mode 100644 index 00000000..32fee71e --- /dev/null +++ b/FreeSql.Repository/readme.md @@ -0,0 +1,132 @@ +这是 [FreeSql](https://github.com/2881099/FreeSql) 衍生出来的扩展包,包含 Repository & UnitOfWork 实现面向对象的特性(QQ群:4336577)。 + +> dotnet add package FreeSql.Repository + +## Repository & UnitOfWork + +仓储与工作单元一起使用,工作单元具有事务特点。 + +```csharp +using (var unitOfWork = fsql.CreateUnitOfWork()) { + var songRepository = unitOfWork.GetRepository(); + var tagRepository = unitOfWork.GetRepository(); + + var song = new Song { BigNumber = "1000000000000000000" }; + songRepository.Insert(song); + + songRepository.Update(song); + + song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); + songRepository.Update(song); + + var tag = new Tag { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + tagRepository.Insert(tag); + + ctx.Commit(); +} +``` + +## Repository + +简单使用仓储,有状态跟踪,它不包含事务的特点。 + +```csharp +var songRepository = fsql.GetRepository(); +var song = new Song { BigNumber = "1000000000000000000" }; +songRepository.Insert(song); +``` + +## IFreeSql 核心定义 + +```csharp +var fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseNoneCommandParameter(true) + + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .Build(); + +public class Song { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string BigNumber { get; set; } + + [Column(IsVersion = true)] //乐观锁 + public long versionRow { get; set; } +} +public class Tag { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public string Name { get; set; } + + public virtual ICollection Tags { get; set; } +} + +public class SongContext : DbContext { + public DbSet Songs { get; set; } + public DbSet Tags { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder builder) { + builder.UseFreeSql(fsql); + } +} +``` + +# 过滤器与验证 + +假设我们有User(用户)、Topic(主题)两个实体,在领域类中定义了两个仓储: + +```csharp +var userRepository = fsql.GetGuidRepository(); +var topicRepository = fsql.GetGuidRepository(); +``` + +在开发过程中,总是担心 topicRepository 的数据安全问题,即有可能查询或操作到其他用户的主题。因此我们在v0.0.7版本进行了改进,增加了 filter lambad 表达式参数。 + +```csharp +var userRepository = fsql.GetGuidRepository(a => a.Id == 1); +var topicRepository = fsql.GetGuidRepository(a => a.UserId == 1); +``` + +* 在查询/修改/删除时附加此条件,从而达到不会修改其他用户的数据; +* 在添加时,使用表达式验证数据的合法性,若不合法则抛出异常; + +# 分表与分库 + +FreeSql 提供 AsTable 分表的基础方法,GuidRepository 作为分存式仓储将实现了分表与分库(不支持跨服务器分库)的封装。 + +```csharp +var logRepository = fsql.GetGuidRepository(null, oldname => $"{oldname}_{DateTime.Now.ToString("YYYYMM")}"); +``` + +上面我们得到一个日志仓储按年月分表,使用它 CURD 最终会操作 Log_201903 表。 + +合并两个仓储,实现分表下的联表查询: + +```csharp +fsql.GetGuidRepository().Select.FromRepository(logRepository) + .LeftJoin(b => b.UserId == a.Id) + .ToList(); +``` + +注意事项: + +* 不能使用 CodeFirst 迁移分表,开发环境时仍然可以迁移 Log 表; +* 不可在分表分库的实体类型中使用《延时加载》; diff --git a/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj b/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj deleted file mode 100644 index 70e6eb76..00000000 --- a/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - netcoreapp2.1 - - false - - - - - - - - - - - - - - - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj new file mode 100644 index 00000000..761bebcf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs new file mode 100644 index 00000000..da499384 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -0,0 +1,261 @@ +using System; +using Xunit; + +namespace FreeSql.Tests { + public class RepositoryTests { + + [Fact] + public void AddUpdate() { + var repos = g.sqlite.GetGuidRepository(); + + var item = repos.Insert(new AddUpdateInfo()); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + + item = repos.Insert(new AddUpdateInfo { Id = Guid.NewGuid() }); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + + item.Title = "xxx"; + repos.Update(item); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + + Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql()); + repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows(); + + item = repos.Find(item.Id); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + } + + [Fact] + public void UpdateAttach() { + var repos = g.sqlite.GetGuidRepository(); + + var item = new AddUpdateInfo { Id = Guid.NewGuid() }; + repos.Attach(item); + + item.Title = "xxx"; + repos.Update(item); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + + Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql()); + repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows(); + + item = repos.Find(item.Id); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + } + + [Fact] + public void UpdateWhenNotExists() { + var repos = g.sqlite.GetGuidRepository(); + + var item = new AddUpdateInfo { Id = Guid.NewGuid() }; + item.Title = "xxx"; + Assert.Throws(() => repos.Update(item)); + } + + [Fact] + public void Update() { + g.sqlite.Insert(new AddUpdateInfo()).ExecuteAffrows(); + + var repos = g.sqlite.GetGuidRepository(); + + var item = new AddUpdateInfo { Id = g.sqlite.Select().First().Id }; + + item.Title = "xxx"; + repos.Update(item); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + } + + public class AddUpdateInfo { + + public Guid Id { get; set; } + public string Title { get; set; } + + public int Clicks { get; set; } = 10; + } + + [Fact] + public void UnitOfWorkRepository() { + foreach (var fsql in new[] { g.sqlite, /*g.mysql, g.pgsql, g.oracle, g.sqlserver*/ }) { + + fsql.CodeFirst.ConfigEntity(f => { + f.Property(b => b.UserId).IsPrimary(true); + f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); + f.Property(b => b.Name).IsNullable(false); + }); + + FlowModel flow = new FlowModel() { + CreateTime = DateTime.Now, + Name = "aaa", + LastModifyTime = DateTime.Now, + UserId = 1, + }; + var flowRepos = fsql.GetRepository(); + flowRepos.Insert(flow); + + // + flow = new FlowModel() { + CreateTime = DateTime.Now, + Name = "aaa", + LastModifyTime = DateTime.Now, + UserId = 1, + }; + using (var uow = fsql.CreateUnitOfWork()) { + flowRepos = uow.GetRepository(); + flowRepos.Insert(flow); + uow.Commit(); + } + } + } + + [Fact] + public void UnitOfWorkRepositoryWithDisableBeforeInsert() + { + foreach (var fsql in new[] { g.sqlite, }) + { + fsql.CodeFirst.ConfigEntity(f => { + f.Property(b => b.UserId).IsPrimary(true); + f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); + f.Property(b => b.Name).IsNullable(false); + }); + + var flowRepos = fsql.GetRepository(); + + var flow = new FlowModel() + { + CreateTime = DateTime.Now, + Name = "aaa", + LastModifyTime = DateTime.Now, + UserId = 1, + }; + + //ݿѴڵݣΪ˽IJ + flowRepos.Delete(a => a.UserId == 1 &&a.Name== "aaa"); + + using (var uow = fsql.CreateUnitOfWork()) + { + //رչԪῪʼ + uow.Close(); + var uowFlowRepos = uow.GetRepository(); + uowFlowRepos.Insert(flow); + //ѹرչԪ᲻ύûӰ죬˴עȷԪǷЧرˣCommitҲӦò + //uow.Commit(); + } + + Assert.True(flowRepos.Select.Any(a => a.UserId == 1 && a.Name == "aaa")); + } + + } + + [Fact] + public void UnitOfWorkRepositoryWithDisableAfterInsert() + { + foreach (var fsql in new[] {g.sqlite,}) + { + fsql.CodeFirst.ConfigEntity(f => + { + f.Property(b => b.UserId).IsPrimary(true); + f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); + f.Property(b => b.Name).IsNullable(false); + }); + + var flowRepos = fsql.GetRepository(); + + //ݿѴڵݣΪ˽IJ + flowRepos.Delete(a => a.UserId == 1 && a.Name == "aaa"); + + var flow = new FlowModel() + { + CreateTime = DateTime.Now, + Name = "aaa", + LastModifyTime = DateTime.Now, + UserId = 1, + }; + + + Assert.Throws(() => + { + using (var uow = fsql.CreateUnitOfWork()) + { + var uowFlowRepos = uow.GetRepository(); + uowFlowRepos.Insert(flow); + // Insert/Update/Delete ùرuowķᷢ쳣 + uow.Close(); + uow.Commit(); + } + + }); + } + } + + [Fact] + public void UnitOfWorkRepositoryWithoutDisable() + { + foreach (var fsql in new[] { g.sqlite, }) + { + fsql.CodeFirst.ConfigEntity(f => + { + f.Property(b => b.UserId).IsPrimary(true); + f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); + f.Property(b => b.Name).IsNullable(false); + }); + + var flowRepos = fsql.GetRepository(); + if (flowRepos.Select.Any(a => a.UserId == 1 && a.Name == "aaa")) + { + flowRepos.Delete(a => a.UserId == 1); + } + + + var flow = new FlowModel() + { + CreateTime = DateTime.Now, + Name = "aaa", + LastModifyTime = DateTime.Now, + UserId = 1, + }; + + + using (var uow = fsql.CreateUnitOfWork()) + { + var uowFlowRepos = uow.GetRepository(); + uowFlowRepos.Insert(flow); + //commitύݿ + //uow.Commit(); + } + Assert.False(flowRepos.Select.Any(a => a.UserId == 1 && a.Name == "aaa")); + } + } + + + public partial class FlowModel { + public int UserId { get; set; } + public int Id { get; set; } + public int? ParentId { get; set; } + public string Name { get; set; } + public DateTime CreateTime { get; set; } + public DateTime LastModifyTime { get; set; } + public string Desc { get; set; } + } + + [Fact] + public void AsType() { + g.sqlite.Insert(new AddUpdateInfo()).ExecuteAffrows(); + + var repos = g.sqlite.GetGuidRepository(); + repos.AsType(typeof(AddUpdateInfo)); + + var item = new AddUpdateInfo(); + repos.Insert(item); + repos.Update(item); + + item.Clicks += 1; + repos.InsertOrUpdate(item); + + var item2 = repos.Find(item.Id) as AddUpdateInfo; + Assert.Equal(item.Clicks, item2.Clicks); + + repos.DataFilter.Apply("xxx", a => (a as AddUpdateInfo).Clicks == 2); + Assert.Null(repos.Find(item.Id)); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs new file mode 100644 index 00000000..0bbc0c4a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -0,0 +1,160 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace FreeSql.Tests { + public class UnitTest1 { + + class testenumWhere { + public Guid id { get; set; } + public testenumWhereType type { get; set; } + } + public enum testenumWhereType { Menu, Class, Blaaa } + + [Fact] + public void Include_ManyToMany() { + + g.sqlite.CodeFirst.SyncStructure(); + g.sqlite.CodeFirst.SyncStructure(); + g.sqlite.CodeFirst.SyncStructure(); + + using (var ctx = g.sqlite.CreateDbContext()) { + + var songs = ctx.Set().Select + .IncludeMany(a => a.Tags) + .ToList(); + + var tag1 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_й" + }; + var tag2 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_" + }; + var tag3 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_ձ" + }; + ctx.AddRange(new[] { tag1, tag2, tag3 }); + + var song1 = new Song { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_й.mp3", + Url = "http://ww.baidu.com/" + }; + var song2 = new Song { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_һ.mp3", + Url = "http://ww.163.com/" + }; + var song3 = new Song { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_ǧһ.mp3", + Url = "http://ww.sina.com/" + }; + ctx.AddRange(new[] { song1, song2, song3 }); + + ctx.AddRange( + new[] { + new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }, + new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }, + new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }, + new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }, + new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }, + new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }, + } + ); + ctx.SaveChanges(); + } + } + + [Fact] + public void Add() { + + g.sqlite.SetDbContextOptions(opt => { + //opt.EnableAddOrUpdateNavigateList = false; + }); + + g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); + + var sql = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); + var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); + + //֧ 1Զ + + using (var ctx = new FreeContext(g.sqlite)) { + + var tags = ctx.Set().Select.IncludeMany(a => a.Tags).ToList(); + + var tag = new Tag { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + ctx.Add(tag); + ctx.SaveChanges(); + } + } + + [Fact] + public void Update() { + //ѯ 1Զ࣬ + + using (var ctx = new FreeContext(g.sqlite)) { + + var tag = ctx.Set().Select.First(); + tag.Tags.Add(new Tag { Name = "sub3" }); + ctx.Update(tag); + ctx.SaveChanges(); + } + } + + public class Song { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + + [Column(IsVersion = true)] + public long versionRow { get; set; } + } + public class Song_tag { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + + public class Tag { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + } +} + diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs new file mode 100644 index 00000000..4aec7356 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + + +public class g { + + static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .UseNoneCommandParameter(true) + .Build()); + public static IFreeSql sqlserver => sqlserverLazy.Value; + + static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .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") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .UseNoneCommandParameter(true) + .Build()); + public static IFreeSql mysql => mysqlLazy.Value; + + static Lazy pgsqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") + .UseAutoSyncStructure(true) + .UseSyncStructureToLower(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseNoneCommandParameter(true) + .Build()); + public static IFreeSql pgsql => pgsqlLazy.Value; + + static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseSyncStructureToUpper(true) + .UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .Build()); + public static IFreeSql oracle => oracleLazy.Value; + + static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|/document22.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseNoneCommandParameter(true) + .Build()); + public static IFreeSql sqlite => sqliteLazy.Value; +} diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj new file mode 100644 index 00000000..afdd5535 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + + + + + + + diff --git a/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs similarity index 100% rename from FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs rename to FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs diff --git a/FreeSql.Tests.PerformanceTests/g.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/g.cs similarity index 100% rename from FreeSql.Tests.PerformanceTests/g.cs rename to FreeSql.Tests/FreeSql.Tests.PerformanceTests/g.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj similarity index 59% rename from FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj index 7ba5e744..1085dbcd 100644 --- a/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj @@ -13,9 +13,9 @@ - - - + + + diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs diff --git a/FreeSql.Tests.Provider.MySqlConnector/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs similarity index 100% rename from FreeSql.Tests.Provider.MySqlConnector/g.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs diff --git a/FreeSql.Tests/Class1.cs b/FreeSql.Tests/FreeSql.Tests/Class1.cs similarity index 100% rename from FreeSql.Tests/Class1.cs rename to FreeSql.Tests/FreeSql.Tests/Class1.cs diff --git a/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs similarity index 100% rename from FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs rename to FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs diff --git a/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs similarity index 100% rename from FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs rename to FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs diff --git a/FreeSql.Tests/DataContext/SqlServer/SqlServerCollection.cs b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerCollection.cs similarity index 100% rename from FreeSql.Tests/DataContext/SqlServer/SqlServerCollection.cs rename to FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerCollection.cs diff --git a/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs similarity index 100% rename from FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs rename to FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs diff --git a/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs b/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs similarity index 100% rename from FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs rename to FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs diff --git a/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs similarity index 100% rename from FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs rename to FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs diff --git a/FreeSql.Tests/Extensions/StringExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/Extensions/StringExtensionsTest.cs similarity index 100% rename from FreeSql.Tests/Extensions/StringExtensionsTest.cs rename to FreeSql.Tests/FreeSql.Tests/Extensions/StringExtensionsTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj similarity index 51% rename from FreeSql.Tests/FreeSql.Tests.csproj rename to FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 27134387..902899b6 100644 --- a/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -11,23 +11,12 @@ - - - - - - - - - - - @@ -35,4 +24,15 @@ + + + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml similarity index 100% rename from FreeSql.Tests/FreeSql.Tests.xml rename to FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml diff --git a/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs b/FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs similarity index 100% rename from FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs rename to FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs diff --git a/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs similarity index 100% rename from FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs diff --git a/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs similarity index 100% rename from FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs diff --git a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs similarity index 100% rename from FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs diff --git a/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs similarity index 100% rename from FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs diff --git a/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MapType/BoolNullableTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs diff --git a/FreeSql.Tests/MySql/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MapType/BoolTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolTest.cs diff --git a/FreeSql.Tests/MySql/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/EnumTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MapType/EnumTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MapType/EnumTest.cs diff --git a/FreeSql.Tests/MySql/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/ToStringTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MapType/ToStringTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MapType/ToStringTest.cs diff --git a/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs diff --git a/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlCodeFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs diff --git a/FreeSql.Tests/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlDbFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs diff --git a/FreeSql.Tests/MySql/MySqlExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/ConvertTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlExpression/ConvertTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/ConvertTest.cs diff --git a/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs diff --git a/FreeSql.Tests/MySql/MySqlExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/MathTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlExpression/MathTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/MathTest.cs diff --git a/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs diff --git a/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlExpression/StringTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs diff --git a/FreeSql.Tests/MySql/MySqlExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/TimeSpanTest.cs similarity index 100% rename from FreeSql.Tests/MySql/MySqlExpression/TimeSpanTest.cs rename to FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/TimeSpanTest.cs diff --git a/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs diff --git a/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs diff --git a/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs diff --git a/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs diff --git a/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs diff --git a/FreeSql.Tests/Oracle/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/MapType/BoolTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs diff --git a/FreeSql.Tests/Oracle/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/EnumTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/MapType/EnumTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/MapType/EnumTest.cs diff --git a/FreeSql.Tests/Oracle/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/ToStringTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/MapType/ToStringTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/MapType/ToStringTest.cs diff --git a/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs diff --git a/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleCodeFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs diff --git a/FreeSql.Tests/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleDbFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs diff --git a/FreeSql.Tests/Oracle/OracleExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/ConvertTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleExpression/ConvertTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/ConvertTest.cs diff --git a/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs diff --git a/FreeSql.Tests/Oracle/OracleExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/MathTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleExpression/MathTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/MathTest.cs diff --git a/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs diff --git a/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleExpression/StringTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs diff --git a/FreeSql.Tests/Oracle/OracleExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/TimeSpanTest.cs similarity index 100% rename from FreeSql.Tests/Oracle/OracleExpression/TimeSpanTest.cs rename to FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/TimeSpanTest.cs diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs diff --git a/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs diff --git a/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs diff --git a/FreeSql.Tests/PostgreSQL/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/EnumTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/MapType/EnumTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/EnumTest.cs diff --git a/FreeSql.Tests/PostgreSQL/MapType/JTokenTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/JTokenTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/MapType/JTokenTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/JTokenTest.cs diff --git a/FreeSql.Tests/PostgreSQL/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/ToStringTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/MapType/ToStringTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/ToStringTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/ConvertTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLExpression/ConvertTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/ConvertTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs similarity index 100% rename from FreeSql.Tests/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs rename to FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs diff --git a/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs diff --git a/FreeSql.Tests/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/MapType/BoolTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs diff --git a/FreeSql.Tests/SqlServer/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/MapType/EnumTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs diff --git a/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/MapType/ToStringTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs diff --git a/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs similarity index 100% rename from FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs rename to FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs diff --git a/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs diff --git a/FreeSql.Tests/Sqlite/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/MapType/BoolTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs diff --git a/FreeSql.Tests/Sqlite/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/EnumTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/MapType/EnumTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/EnumTest.cs diff --git a/FreeSql.Tests/Sqlite/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/ToStringTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/MapType/ToStringTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/ToStringTest.cs diff --git a/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs diff --git a/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs diff --git a/FreeSql.Tests/Sqlite/SqliteExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/ConvertTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/SqliteExpression/ConvertTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/ConvertTest.cs diff --git a/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs diff --git a/FreeSql.Tests/Sqlite/SqliteExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/MathTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/SqliteExpression/MathTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/MathTest.cs diff --git a/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs diff --git a/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs diff --git a/FreeSql.Tests/Sqlite/SqliteExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/TimeSpanTest.cs similarity index 100% rename from FreeSql.Tests/Sqlite/SqliteExpression/TimeSpanTest.cs rename to FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/TimeSpanTest.cs diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs similarity index 98% rename from FreeSql.Tests/UnitTest1.cs rename to FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 15e99247..9695c6a0 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -275,23 +275,25 @@ namespace FreeSql.Tests { var testgrpsql = g.sqlite.Select() .From((a, b) => a.InnerJoin(aa => aa.TemplatesId == b.Id2)) - .GroupBy((a, b) => b.Title) + .GroupBy((a, b) => b.Code) .ToSql(a => new { a.Key, - sss = a.Sum(a.Value.Item1.Id) + sss = a.Sum(a.Value.Item1.Id), + sss2 = a.Sum(a.Value.Item2.Id2) }); var testgrpsql2 = g.sqlite.Select() .From((a, b) => a.InnerJoin(aa => aa.TemplatesId == b.Id2)) - .GroupBy((a, b) => b.Title) + .GroupBy((a, b) => b.Code) .ToList(a => new { a.Key, - sss = a.Sum(a.Value.Item1.Id) + sss = a.Sum(a.Value.Item1.Id), + sss2 = a.Sum(a.Value.Item2.Id2) }); - var tbid = g.sqlite.Select().First().Id; + var tbid = g.sqlite.Select().First()?.Id ?? Guid.Empty; var testarray = new[] { 1, 2, 3 }; var tbidsql = g.sqlite.Update().Where(a => a.Id == tbid) diff --git a/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs similarity index 100% rename from FreeSql.Tests/UnitTest2.cs rename to FreeSql.Tests/FreeSql.Tests/UnitTest2.cs diff --git a/FreeSql.Tests/ftTests.xml b/FreeSql.Tests/FreeSql.Tests/ftTests.xml similarity index 100% rename from FreeSql.Tests/ftTests.xml rename to FreeSql.Tests/FreeSql.Tests/ftTests.xml diff --git a/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs similarity index 100% rename from FreeSql.Tests/g.cs rename to FreeSql.Tests/FreeSql.Tests/g.cs diff --git a/FreeSql.sln b/FreeSql.sln index 672214b1..00fecbec 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -5,15 +5,11 @@ VisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql", "FreeSql\FreeSql.csproj", "{AF9C50EC-6EB6-494B-9B3B-7EDBA6FD0EBB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests", "FreeSql.Tests\FreeSql.Tests.csproj", "{AA88EB04-4788-4180-AE68-7FA5ED17D98C}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{C6A74E2A-6660-473D-8852-B1D8348DB4E9}" ProjectSection(SolutionItems) = preProject readme.md = readme.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.PerformanceTests", "FreeSql.Tests.PerformanceTests\FreeSql.Tests.PerformanceTests.csproj", "{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{94C8A78D-AA15-47B2-A348-530CD86BFC1B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "restful", "Examples\restful\restful.csproj", "{83D10565-AF9D-4EDC-8FB8-8C962A843F97}" @@ -42,7 +38,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.LazyLoad EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MySqlConnector", "Providers\FreeSql.Provider.MySqlConnector\FreeSql.Provider.MySqlConnector.csproj", "{D2A41321-5E84-410B-B25C-3AA122D4CA27}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.MySqlConnector", "FreeSql.Tests.Provider.MySqlConnector\FreeSql.Tests.Provider.MySqlConnector.csproj", "{D113CDFB-FB97-482B-8A00-058E715B624A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dbcontext_01", "Examples\dbcontext_01\dbcontext_01.csproj", "{690F89E0-A721-423F-8F5D-D262F73235EA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "repository_01", "Examples\repository_01\repository_01.csproj", "{4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests", "FreeSql.Tests\FreeSql.Tests\FreeSql.Tests.csproj", "{C98891E0-1C83-41F8-B36F-982B8DC45999}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.DbContext", "FreeSql.DbContext\FreeSql.DbContext.csproj", "{82885C27-23C8-4A6E-92CF-80FE61A041E1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Repository", "FreeSql.Repository\FreeSql.Repository.csproj", "{3B6887DA-A7E3-410A-B450-587F6B4923F7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.DbContext", "FreeSql.Tests\FreeSql.Tests.DbContext\FreeSql.Tests.DbContext.csproj", "{11C37354-7AF1-4010-9BB6-43AA9CBA6291}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.PerformanceTests", "FreeSql.Tests\FreeSql.Tests.PerformanceTests\FreeSql.Tests.PerformanceTests.csproj", "{DFFD1206-A70A-493A-BE88-3131B800522E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.MySqlConnector", "FreeSql.Tests\FreeSql.Tests.Provider.MySqlConnector\FreeSql.Tests.Provider.MySqlConnector.csproj", "{0F45294A-34FF-4FB8-A046-20E09E3A4D5C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -66,30 +76,6 @@ Global {AF9C50EC-6EB6-494B-9B3B-7EDBA6FD0EBB}.Release|x64.Build.0 = Release|Any CPU {AF9C50EC-6EB6-494B-9B3B-7EDBA6FD0EBB}.Release|x86.ActiveCfg = Release|Any CPU {AF9C50EC-6EB6-494B-9B3B-7EDBA6FD0EBB}.Release|x86.Build.0 = Release|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Debug|x64.ActiveCfg = Debug|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Debug|x64.Build.0 = Debug|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Debug|x86.ActiveCfg = Debug|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Debug|x86.Build.0 = Debug|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|Any CPU.Build.0 = Release|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|x64.ActiveCfg = Release|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|x64.Build.0 = Release|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|x86.ActiveCfg = Release|Any CPU - {AA88EB04-4788-4180-AE68-7FA5ED17D98C}.Release|x86.Build.0 = Release|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|x64.ActiveCfg = Debug|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|x64.Build.0 = Debug|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|x86.ActiveCfg = Debug|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Debug|x86.Build.0 = Debug|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|Any CPU.Build.0 = Release|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|x64.ActiveCfg = Release|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|x64.Build.0 = Release|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|x86.ActiveCfg = Release|Any CPU - {446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}.Release|x86.Build.0 = Release|Any CPU {83D10565-AF9D-4EDC-8FB8-8C962A843F97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {83D10565-AF9D-4EDC-8FB8-8C962A843F97}.Debug|Any CPU.Build.0 = Debug|Any CPU {83D10565-AF9D-4EDC-8FB8-8C962A843F97}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -222,18 +208,102 @@ Global {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x64.Build.0 = Release|Any CPU {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.ActiveCfg = Release|Any CPU {D2A41321-5E84-410B-B25C-3AA122D4CA27}.Release|x86.Build.0 = Release|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|x64.ActiveCfg = Debug|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|x64.Build.0 = Debug|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|x86.ActiveCfg = Debug|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Debug|x86.Build.0 = Debug|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|Any CPU.Build.0 = Release|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|x64.ActiveCfg = Release|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|x64.Build.0 = Release|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|x86.ActiveCfg = Release|Any CPU - {D113CDFB-FB97-482B-8A00-058E715B624A}.Release|x86.Build.0 = Release|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Debug|x64.ActiveCfg = Debug|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Debug|x64.Build.0 = Debug|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Debug|x86.ActiveCfg = Debug|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Debug|x86.Build.0 = Debug|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Release|Any CPU.Build.0 = Release|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Release|x64.ActiveCfg = Release|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Release|x64.Build.0 = Release|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Release|x86.ActiveCfg = Release|Any CPU + {690F89E0-A721-423F-8F5D-D262F73235EA}.Release|x86.Build.0 = Release|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Debug|x64.ActiveCfg = Debug|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Debug|x64.Build.0 = Debug|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Debug|x86.ActiveCfg = Debug|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Debug|x86.Build.0 = Debug|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Release|Any CPU.Build.0 = Release|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Release|x64.ActiveCfg = Release|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Release|x64.Build.0 = Release|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Release|x86.ActiveCfg = Release|Any CPU + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513}.Release|x86.Build.0 = Release|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Debug|x64.ActiveCfg = Debug|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Debug|x64.Build.0 = Debug|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Debug|x86.ActiveCfg = Debug|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Debug|x86.Build.0 = Debug|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Release|Any CPU.Build.0 = Release|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Release|x64.ActiveCfg = Release|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Release|x64.Build.0 = Release|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Release|x86.ActiveCfg = Release|Any CPU + {C98891E0-1C83-41F8-B36F-982B8DC45999}.Release|x86.Build.0 = Release|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Debug|x64.ActiveCfg = Debug|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Debug|x64.Build.0 = Debug|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Debug|x86.ActiveCfg = Debug|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Debug|x86.Build.0 = Debug|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Release|Any CPU.Build.0 = Release|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Release|x64.ActiveCfg = Release|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Release|x64.Build.0 = Release|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Release|x86.ActiveCfg = Release|Any CPU + {82885C27-23C8-4A6E-92CF-80FE61A041E1}.Release|x86.Build.0 = Release|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Debug|x64.ActiveCfg = Debug|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Debug|x64.Build.0 = Debug|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Debug|x86.ActiveCfg = Debug|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Debug|x86.Build.0 = Debug|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Release|Any CPU.Build.0 = Release|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Release|x64.ActiveCfg = Release|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Release|x64.Build.0 = Release|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Release|x86.ActiveCfg = Release|Any CPU + {3B6887DA-A7E3-410A-B450-587F6B4923F7}.Release|x86.Build.0 = Release|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Debug|Any CPU.Build.0 = Debug|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Debug|x64.ActiveCfg = Debug|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Debug|x64.Build.0 = Debug|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Debug|x86.ActiveCfg = Debug|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Debug|x86.Build.0 = Debug|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Release|Any CPU.ActiveCfg = Release|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Release|Any CPU.Build.0 = Release|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Release|x64.ActiveCfg = Release|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Release|x64.Build.0 = Release|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Release|x86.ActiveCfg = Release|Any CPU + {11C37354-7AF1-4010-9BB6-43AA9CBA6291}.Release|x86.Build.0 = Release|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Debug|x64.ActiveCfg = Debug|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Debug|x64.Build.0 = Debug|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Debug|x86.ActiveCfg = Debug|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Debug|x86.Build.0 = Debug|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Release|Any CPU.Build.0 = Release|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Release|x64.ActiveCfg = Release|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Release|x64.Build.0 = Release|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Release|x86.ActiveCfg = Release|Any CPU + {DFFD1206-A70A-493A-BE88-3131B800522E}.Release|x86.Build.0 = Release|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Debug|x64.ActiveCfg = Debug|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Debug|x64.Build.0 = Debug|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Debug|x86.ActiveCfg = Debug|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Debug|x86.Build.0 = Debug|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|Any CPU.Build.0 = Release|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|x64.ActiveCfg = Release|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|x64.Build.0 = Release|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|x86.ActiveCfg = Release|Any CPU + {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -250,6 +320,8 @@ Global {22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {D2A41321-5E84-410B-B25C-3AA122D4CA27} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {690F89E0-A721-423F-8F5D-D262F73235EA} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 586d5cd8..657f4034 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.13 + 0.7.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 2c2c7b11..dc32780a 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.13 + 0.7.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f160ff74..86e4ba0f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.13 + 0.7.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 4a938a3e..a2fbdd88 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.13 + 0.7.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 6c9d2cd2..efd7c307 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.13 + 0.7.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5917a46e..0cc24814 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.13 + 0.7.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 17a52aac..a3423442 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.13 + 0.7.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/readme.md b/readme.md index 2f41d03e..6ab84261 100644 --- a/readme.md +++ b/readme.md @@ -29,7 +29,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore |--------------| ------- | ---- | | FreeSql | [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) | [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) | | [FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Repository) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Repository?groupby=Version) | -| [FreeSql.DbContext](https://github.com/2881099/FreeSql.DbContext) | [![nuget](https://img.shields.io/nuget/v/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.DbContext) | [![stats](https://img.shields.io/nuget/dt/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.DbContext?groupby=Version) | +| FreeSql.DbContext | [![nuget](https://img.shields.io/nuget/v/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.DbContext) | [![stats](https://img.shields.io/nuget/dt/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.DbContext?groupby=Version) | | [FreeSql.AdminLTE](https://github.com/2881099/FreeSql.AdminLTE) | [![nuget](https://img.shields.io/nuget/v/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.AdminLTE) | [![stats](https://img.shields.io/nuget/dt/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.AdminLTE?groupby=Version) | | [FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Connection.Extensions) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Connection.Extensions?groupby=Version) | From 873364c7ee7fc8d008d2df443901bdf5ccd2a172 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 26 Jun 2019 10:10:06 +0800 Subject: [PATCH 0030/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20.From.Gr?= =?UTF-8?q?oupBy=20Item2=20=E4=BB=A5=E4=B8=8A=E6=97=A0=E7=BB=84=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=9C=AA=E6=9F=A5=E6=89=BE=E5=88=B0=E7=9A=84=20bug=20?= =?UTF-8?q?#63=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommonProvider/SelectProvider/SelectGroupingProvider.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 397e987f..9389c832 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -41,8 +41,9 @@ namespace FreeSql.Internal.CommonProvider { if (mem0Name?.StartsWith("Item") == true && int.TryParse(mem0Name.Substring(4), out var tryitemidx)) { if (tryitemidx == 1) foridx++; else { - var alias = $"SP10{(char)(96 + tryitemidx)}"; - var tmptb = _tables.Where(a => a.AliasInit == alias && a.Table.Type == mem0.Type).FirstOrDefault(); + //var alias = $"SP10{(char)(96 + tryitemidx)}"; + var tmptb = _tables.Where((a,idx) => //a.AliasInit == alias && + a.Table.Type == mem0.Type && idx == tryitemidx - 1).FirstOrDefault(); if (tmptb != null) { tb = tmptb; foridx++; From f8c3608fdac2933b528605cc46b21b71c79eaacb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 27 Jun 2019 09:40:35 +0800 Subject: [PATCH 0031/1029] =?UTF-8?q?=E6=BA=90=E4=BB=A3=E7=A0=81=E6=94=B9?= =?UTF-8?q?=E7=94=A8vs=E9=BB=98=E8=AE=A4=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/benchmarker/Program.cs | 369 +- .../Controllers/ValuesController.cs | 362 +- .../dbcontext_01/DbContexts/SongContext.cs | 75 +- Examples/dbcontext_01/Program.cs | 71 +- .../Properties/launchSettings.json | 46 +- Examples/dbcontext_01/Startup.cs | 148 +- .../dbcontext_01/appsettings.Development.json | 12 +- Examples/dbcontext_01/appsettings.json | 12 +- .../DBContexts/BaseDBContext.cs | 26 +- .../DBContexts/Topic1Context.cs | 19 +- .../DBContexts/Topic2Context.cs | 21 +- Examples/efcore_to_freesql/Entitys/Topic1.cs | 3 +- Examples/efcore_to_freesql/Entitys/Topic2.cs | 3 +- .../FreeSqlExtensions/CodeFirstExtensions.cs | 91 +- .../Properties/launchSettings.json | 52 +- Examples/efcore_to_freesql/Startup.cs | 78 +- .../appsettings.Development.json | 12 +- Examples/efcore_to_freesql/appsettings.json | 12 +- Examples/orm_vs/Program.cs | 535 +-- .../Controllers/SongController.cs | 150 +- Examples/repository_01/Entitys/Song.cs | 14 +- .../Properties/launchSettings.json | 46 +- Examples/repository_01/Startup.cs | 146 +- .../appsettings.Development.json | 14 +- Examples/repository_01/appsettings.json | 12 +- .../restful/Controllers/SongController.cs | 92 +- Examples/restful/Entitys/Song.cs | 14 +- .../restful/Properties/launchSettings.json | 46 +- Examples/restful/Startup.cs | 104 +- Examples/restful/appsettings.Development.json | 12 +- Examples/restful/appsettings.json | 12 +- .../LazyLoadingComplier.cs | 46 +- FreeSql.DbContext/DbContext/DbContext.cs | 264 +- FreeSql.DbContext/DbContext/DbContextAsync.cs | 218 +- .../DbContext/DbContextOptions.cs | 16 +- .../DbContext/DbContextOptionsBuilder.cs | 19 +- FreeSql.DbContext/DbContext/DbContextSync.cs | 220 +- FreeSql.DbContext/DbContext/FreeContext.cs | 15 +- FreeSql.DbContext/DbSet/DbSet.cs | 552 +-- FreeSql.DbContext/DbSet/DbSetAsync.cs | 518 +-- FreeSql.DbContext/DbSet/DbSetSync.cs | 584 +-- .../Extenssions/DependencyInjection.cs | 41 +- .../FreeSqlDbContextExtenssions.cs | 64 +- .../ContextSet/RepositoryDbContext.cs | 103 +- .../Repository/ContextSet/RepositoryDbSet.cs | 111 +- .../ContextSet/RepositoryUnitOfWork.cs | 97 +- .../Repository/DataFilter/DataFilter.cs | 279 +- .../Repository/DataFilter/DataFilterUtil.cs | 157 +- .../Extenssions/DependencyInjection.cs | 50 +- .../FreeSqlRepositoryExtenssions.cs | 114 +- .../Repository/Repository/BaseRepository.cs | 300 +- .../Repository/DefaultRepository.cs | 22 +- .../Repository/Repository/GuidRepository.cs | 22 +- .../Repository/Repository/IBaseRepository.cs | 44 +- .../Repository/Repository/IBasicRepository.cs | 71 +- .../Repository/IReadOnlyRepository.cs | 33 +- FreeSql.DbContext/TempExtensions.cs | 8 +- FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 12 +- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 143 +- .../RepositoryTests.cs | 236 +- .../FreeSql.Tests.DbContext/UnitTest1.cs | 268 +- FreeSql.Tests/FreeSql.Tests.DbContext/g.cs | 157 +- .../MySqlAdoTest.cs | 335 +- .../FreeSql.Tests.PerformanceTests/g.cs | 45 +- .../MySqlConnector/Curd/MySqlDeleteTest.cs | 133 +- .../MySqlConnector/Curd/MySqlInsertTest.cs | 213 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 2526 ++++++------- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 309 +- .../MapType/BoolNullableTest.cs | 3148 ++++++++-------- .../MySqlConnector/MapType/BoolTest.cs | 2216 ++++++------ .../MySqlConnector/MapType/EnumTest.cs | 445 +-- .../MySqlConnector/MapType/ToStringTest.cs | 991 +++--- .../MySqlConnector/MySqlCodeFirstTest.cs | 648 ++-- .../MySqlConnectorAdo/MySqlAdoTest.cs | 95 +- .../MySqlConnectorExpression/ConvertTest.cs | 287 +- .../MySqlConnectorExpression/DateTimeTest.cs | 1270 +++---- .../MySqlConnectorExpression/MathTest.cs | 266 +- .../MySqlConnectorExpression/OtherTest.cs | 198 +- .../MySqlConnectorExpression/StringTest.cs | 1402 ++++---- .../MySqlConnectorExpression/TimeSpanTest.cs | 531 +-- .../MySqlConnector/MySqlDbFirstTest.cs | 26 +- .../g.cs | 31 +- .../DataAnnotations/MySqlFluentTest.cs | 203 +- .../DataAnnotations/SqlServerFluentTest.cs | 194 +- .../SqlServer/SqlServerCollection.cs | 14 +- .../DataContext/SqlServer/SqlServerFixture.cs | 92 +- .../GetDataReaderValueBlockExpressionTest.cs | 735 ++-- .../LambadaExpressionExtensionsTest.cs | 64 +- .../Extensions/StringExtensionsTest.cs | 107 +- .../LinqToSql/SqliteLinqToSqlTests.cs | 321 +- .../MySql/Curd/MySqlDeleteTest.cs | 135 +- .../MySql/Curd/MySqlInsertTest.cs | 215 +- .../MySql/Curd/MySqlSelectTest.cs | 2507 ++++++------- .../MySql/Curd/MySqlUpdateTest.cs | 311 +- .../MySql/MapType/BoolNullableTest.cs | 3148 ++++++++-------- .../FreeSql.Tests/MySql/MapType/BoolTest.cs | 2216 ++++++------ .../FreeSql.Tests/MySql/MapType/EnumTest.cs | 445 +-- .../MySql/MapType/ToStringTest.cs | 991 +++--- .../MySql/MySqlAdo/MySqlAdoTest.cs | 95 +- .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 648 ++-- .../FreeSql.Tests/MySql/MySqlDbFirstTest.cs | 26 +- .../MySql/MySqlExpression/ConvertTest.cs | 287 +- .../MySql/MySqlExpression/DateTimeTest.cs | 1335 +++---- .../MySql/MySqlExpression/MathTest.cs | 266 +- .../MySql/MySqlExpression/OtherTest.cs | 198 +- .../MySql/MySqlExpression/StringTest.cs | 1402 ++++---- .../MySql/MySqlExpression/TimeSpanTest.cs | 531 +-- .../Oracle/Curd/OracleDeleteTest.cs | 137 +- .../Oracle/Curd/OracleInsertTest.cs | 202 +- .../Oracle/Curd/OracleSelectTest.cs | 2286 ++++++------ .../Oracle/Curd/OracleUpdateTest.cs | 216 +- .../Oracle/MapType/BoolNullableTest.cs | 3148 ++++++++-------- .../FreeSql.Tests/Oracle/MapType/BoolTest.cs | 2216 ++++++------ .../FreeSql.Tests/Oracle/MapType/EnumTest.cs | 445 +-- .../Oracle/MapType/ToStringTest.cs | 991 +++--- .../Oracle/OracleAdo/OracleAdoTest.cs | 95 +- .../Oracle/OracleCodeFirstTest.cs | 332 +- .../FreeSql.Tests/Oracle/OracleDbFirstTest.cs | 26 +- .../Oracle/OracleExpression/ConvertTest.cs | 287 +- .../Oracle/OracleExpression/DateTimeTest.cs | 1359 +++---- .../Oracle/OracleExpression/MathTest.cs | 266 +- .../Oracle/OracleExpression/OtherTest.cs | 184 +- .../Oracle/OracleExpression/StringTest.cs | 1400 ++++---- .../Oracle/OracleExpression/TimeSpanTest.cs | 531 +-- .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 135 +- .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 180 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 2427 +++++++------ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 216 +- .../PostgreSQL/MapType/BoolNullableTest.cs | 3148 ++++++++-------- .../PostgreSQL/MapType/BoolTest.cs | 2216 ++++++------ .../PostgreSQL/MapType/EnumTest.cs | 445 +-- .../PostgreSQL/MapType/JTokenTest.cs | 752 ++-- .../PostgreSQL/MapType/ToStringTest.cs | 991 +++--- .../PostgreSQLAdo/PostgreSQLAdoTest.cs | 99 +- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 917 ++--- .../PostgreSQL/PostgreSQLDbFirstTest.cs | 26 +- .../PostgreSQLExpression/ConvertTest.cs | 287 +- .../PostgreSQLExpression/DateTimeTest.cs | 1359 +++---- .../PostgreSQLExpression/MathTest.cs | 266 +- .../PostgreSQLExpression/OtherTest.cs | 500 +-- .../PostgreSQLExpression/StringTest.cs | 1400 ++++---- .../PostgreSQLExpression/TimeSpanTest.cs | 531 +-- .../SqlServer/Curd/SqlServerDeleteTest.cs | 158 +- .../SqlServer/Curd/SqlServerInsertTest.cs | 213 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 2279 ++++++------ .../SqlServer/Curd/SqlServerUpdateTest.cs | 230 +- .../SqlServer/MapType/BoolNullableTest.cs | 3165 +++++++++-------- .../SqlServer/MapType/BoolTest.cs | 2231 ++++++------ .../SqlServer/MapType/EnumTest.cs | 456 +-- .../SqlServer/MapType/ToStringTest.cs | 1002 +++--- .../SqlServerAdo/SqlServerAdoTest.cs | 150 +- .../SqlServer/SqlServerCodeFirstTest.cs | 566 +-- .../SqlServer/SqlServerDbFirstTest.cs | 38 +- .../SqlServerExpression/ConvertTest.cs | 299 +- .../SqlServerExpression/DateTimeTest.cs | 590 +-- .../SqlServer/SqlServerExpression/MathTest.cs | 279 +- .../SqlServerExpression/OtherTest.cs | 191 +- .../SqlServerExpression/StringTest.cs | 490 +-- .../SqlServerExpression/TimeSpanTest.cs | 375 +- .../Sqlite/Curd/SqliteDeleteTest.cs | 137 +- .../Sqlite/Curd/SqliteInsertTest.cs | 172 +- .../Sqlite/Curd/SqliteSelectTest.cs | 2213 ++++++------ .../Sqlite/Curd/SqliteUpdateTest.cs | 220 +- .../Sqlite/MapType/BoolNullableTest.cs | 3148 ++++++++-------- .../FreeSql.Tests/Sqlite/MapType/BoolTest.cs | 2216 ++++++------ .../FreeSql.Tests/Sqlite/MapType/EnumTest.cs | 445 +-- .../Sqlite/MapType/ToStringTest.cs | 991 +++--- .../Sqlite/SqliteAdo/SqliteAdoTest.cs | 118 +- .../Sqlite/SqliteCodeFirstTest.cs | 402 ++- .../Sqlite/SqliteExpression/ConvertTest.cs | 287 +- .../Sqlite/SqliteExpression/DateTimeTest.cs | 1359 +++---- .../Sqlite/SqliteExpression/MathTest.cs | 266 +- .../Sqlite/SqliteExpression/OtherTest.cs | 184 +- .../Sqlite/SqliteExpression/StringTest.cs | 1398 ++++---- .../Sqlite/SqliteExpression/TimeSpanTest.cs | 531 +-- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 1708 ++++----- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 29 +- FreeSql.Tests/FreeSql.Tests/g.cs | 156 +- FreeSql/DataAnnotations/ColumnAttribute.cs | 143 +- FreeSql/DataAnnotations/ColumnFluent.cs | 175 +- FreeSql/DataAnnotations/NavigateAttribute.cs | 23 +- FreeSql/DataAnnotations/TableAttribute.cs | 44 +- FreeSql/DataAnnotations/TableFluent.cs | 183 +- FreeSql/DataType.cs | 5 +- FreeSql/DatabaseModel/DBColumnInfo.cs | 96 +- FreeSql/DatabaseModel/DBTableInfo.cs | 109 +- FreeSql/DatabaseModel/DbEnumInfo.cs | 24 +- FreeSql/DatabaseModel/DbForeignInfo.cs | 16 +- FreeSql/DatabaseModel/DbTypeInfo.cs | 24 +- FreeSql/Extensions/EntityUtilExtensions.cs | 1334 +++---- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 169 +- .../Extensions/LambadaExpressionExtensions.cs | 163 +- FreeSql/FreeSqlBuilder.cs | 363 +- FreeSql/FreeUtil.cs | 42 +- FreeSql/Interface/Curd/IDelete.cs | 168 +- FreeSql/Interface/Curd/IInsert.cs | 172 +- FreeSql/Interface/Curd/ISelect/ILinqToSql.cs | 48 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 472 +-- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 616 ++-- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelect4.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelect5.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelect6.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelect7.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelect8.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelect9.cs | 56 +- FreeSql/Interface/Curd/ISelect/ISelectFrom.cs | 66 +- .../Interface/Curd/ISelect/ISelectGrouping.cs | 236 +- FreeSql/Interface/Curd/IUpdate.cs | 298 +- FreeSql/Interface/IAdo.cs | 746 ++-- FreeSql/Interface/IAop.cs | 455 +-- FreeSql/Interface/ICodeFirst.cs | 168 +- FreeSql/Interface/IFreeSql.cs | 189 +- FreeSql/Interface/iDbFirst.cs | 138 +- FreeSql/Internal/CommonExpression.cs | 2027 ++++++----- .../CommonProvider/AdoProvider/AdoProvider.cs | 1407 ++++---- .../AdoProvider/AdoProviderAsync.cs | 1295 +++---- .../AdoProvider/AdoProviderTransaction.cs | 248 +- .../AdoProvider/AdoProviderUtils.cs | 38 +- .../Internal/CommonProvider/AopProvider.cs | 26 +- .../CommonProvider/CodeFirstProvider.cs | 119 +- .../Internal/CommonProvider/DeleteProvider.cs | 233 +- .../Internal/CommonProvider/InsertProvider.cs | 943 ++--- .../SelectProvider/Select0Provider.cs | 1812 +++++----- .../SelectProvider/Select10Provider.cs | 328 +- .../SelectProvider/Select1Provider.cs | 1563 ++++---- .../SelectProvider/Select2Provider.cs | 280 +- .../SelectProvider/Select3Provider.cs | 286 +- .../SelectProvider/Select4Provider.cs | 292 +- .../SelectProvider/Select5Provider.cs | 298 +- .../SelectProvider/Select6Provider.cs | 304 +- .../SelectProvider/Select7Provider.cs | 310 +- .../SelectProvider/Select8Provider.cs | 316 +- .../SelectProvider/Select9Provider.cs | 322 +- .../SelectProvider/SelectGroupingProvider.cs | 267 +- .../Internal/CommonProvider/UpdateProvider.cs | 1126 +++--- FreeSql/Internal/CommonUtils.cs | 594 ++-- FreeSql/Internal/Model/ColumnInfo.cs | 130 +- .../Internal/Model/ReadAnonymousTypeInfo.cs | 28 +- FreeSql/Internal/Model/SelectColumnInfo.cs | 12 +- FreeSql/Internal/Model/SelectTableInfo.cs | 40 +- FreeSql/Internal/Model/TableInfo.cs | 99 +- FreeSql/Internal/UtilsExpressionTree.cs | 2972 ++++++++-------- .../Curd/MySqlDelete.cs | 145 +- .../Curd/MySqlInsert.cs | 245 +- .../Curd/MySqlSelect.cs | 248 +- .../Curd/MySqlUpdate.cs | 219 +- .../MySqlAdo/MySqlAdo.cs | 107 +- .../MySqlAdo/MySqlConnectionPool.cs | 310 +- .../MySqlAdo/MygisTypes.cs | 563 +-- .../MySqlAdo/MygisTypesExtensions.cs | 30 +- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 526 +-- .../FreeSql.Provider.MySql/MySqlDbFirst.cs | 622 ++-- .../FreeSql.Provider.MySql/MySqlExpression.cs | 813 +++-- .../FreeSql.Provider.MySql/MySqlExtensions.cs | 19 +- .../FreeSql.Provider.MySql/MySqlProvider.cs | 122 +- .../FreeSql.Provider.MySql/MySqlUtils.cs | 196 +- .../MySqlConnectorUtils.cs | 210 +- .../Curd/OracleDelete.cs | 29 +- .../Curd/OracleInsert.cs | 355 +- .../Curd/OracleSelect.cs | 274 +- .../Curd/OracleUpdate.cs | 99 +- .../OracleAdo/OracleAdo.cs | 105 +- .../OracleAdo/OracleConnectionPool.cs | 329 +- .../OracleCodeFirst.cs | 612 ++-- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 660 ++-- .../OracleExpression.cs | 816 +++-- .../OracleExtensions.cs | 19 +- .../FreeSql.Provider.Oracle/OracleProvider.cs | 79 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 132 +- .../Curd/PostgreSQLDelete.cs | 145 +- .../Curd/PostgreSQLInsert.cs | 325 +- .../Curd/PostgreSQLSelect.cs | 252 +- .../Curd/PostgreSQLUpdate.cs | 219 +- .../PostgreSQLAdo/PostgreSQLAdo.cs | 133 +- .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 321 +- .../PostgreSQLAdo/PostgreSQLTypesConverter.cs | 249 +- .../PostgreSQLTypesExtensions.cs | 116 +- .../PostgreSQLCodeFirst.cs | 581 +-- .../PostgreSQLDbFirst.cs | 762 ++-- .../PostgreSQLExpression.cs | 1022 +++--- .../PostgreSQLExtensions.cs | 19 +- .../PostgreSQLProvider.cs | 164 +- .../PostgreSQLUtils.cs | 320 +- .../Curd/SqlServerDelete.cs | 161 +- .../Curd/SqlServerInsert.cs | 261 +- .../Curd/SqlServerSelect.cs | 449 +-- .../Curd/SqlServerUpdate.cs | 231 +- .../SqlServerAdo/SqlServerAdo.cs | 117 +- .../SqlServerAdo/SqlServerConnectionPool.cs | 317 +- .../SqlServerCodeFirst.cs | 614 ++-- .../SqlServerDbFirst.cs | 586 +-- .../SqlServerExpression.cs | 780 ++-- .../SqlServerExtensions.cs | 19 +- .../SqlServerProvider.cs | 97 +- .../SqlServerUtils.cs | 141 +- .../Curd/SqliteDelete.cs | 29 +- .../Curd/SqliteInsert.cs | 145 +- .../Curd/SqliteSelect.cs | 248 +- .../Curd/SqliteUpdate.cs | 99 +- .../SqliteAdo/SqliteAdo.cs | 103 +- .../SqliteAdo/SqliteConnectionPool.cs | 373 +- .../SqliteCodeFirst.cs | 460 +-- .../SqliteExpression.cs | 822 +++-- .../SqliteExtensions.cs | 19 +- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 77 +- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 142 +- 309 files changed, 73814 insertions(+), 67594 deletions(-) diff --git a/Examples/benchmarker/Program.cs b/Examples/benchmarker/Program.cs index e07cc6bb..c7f00f27 100644 --- a/Examples/benchmarker/Program.cs +++ b/Examples/benchmarker/Program.cs @@ -8,207 +8,230 @@ using BenchmarkDotNet.Running; using Microsoft.EntityFrameworkCore; //using SqlSugar; -namespace FreeSql.Bechmarker { +namespace FreeSql.Bechmarker +{ - public class Program { - public static void Main(string[] args) { - var summaryInsert = BenchmarkRunner.Run(); - var summarySelect = BenchmarkRunner.Run(); - var summaryUpdate = BenchmarkRunner.Run(); - } - } + public class Program + { + public static void Main(string[] args) + { + var summaryInsert = BenchmarkRunner.Run(); + var summarySelect = BenchmarkRunner.Run(); + var summaryUpdate = BenchmarkRunner.Run(); + } + } - public class Orm { - public static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") - //.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=20") - .UseAutoSyncStructure(false) - .UseNoneCommandParameter(true) - //.UseConfigEntityFromDbFirst(true) - .Build(); + public class Orm + { + public static IFreeSql fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + //.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=20") + .UseAutoSyncStructure(false) + .UseNoneCommandParameter(true) + //.UseConfigEntityFromDbFirst(true) + .Build(); - //public static SqlSugarClient sugar { - // get => new SqlSugarClient(new ConnectionConfig() { - // //不欺负,让连接池100个最小 - // ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", - // DbType = DbType.SqlServer, - // //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", - // //DbType = DbType.MySql, - // IsAutoCloseConnection = true, - // InitKeyType = InitKeyType.Attribute - // }); - //} - } - class SongContext : DbContext { - public DbSet Songs { get; set; } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); - //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); - } - } + //public static SqlSugarClient sugar { + // get => new SqlSugarClient(new ConnectionConfig() { + // //不欺负,让连接池100个最小 + // ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + // DbType = DbType.SqlServer, + // //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + // //DbType = DbType.MySql, + // IsAutoCloseConnection = true, + // InitKeyType = InitKeyType.Attribute + // }); + //} + } + class SongContext : DbContext + { + public DbSet Songs { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); + //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); + } + } - [CoreJob] - [RPlotExporter, RankColumn] - public class OrmVsInsert { - public IEnumerable songs; + [CoreJob] + [RPlotExporter, RankColumn] + public class OrmVsInsert + { + public IEnumerable songs; - [Params(1, 500, 1000, 5000, 10000, 50000, 100000)] - public int size; + [Params(1, 500, 1000, 5000, 10000, 50000, 100000)] + public int size; - [GlobalSetup] - public void Setup() { - Orm.fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); - //Orm.sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); - //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements + [GlobalSetup] + public void Setup() + { + Orm.fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); + //Orm.sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements - //测试前清空数据 - Orm.fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); - //Orm.sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); - Orm.fsql.Ado.ExecuteNonQuery("delete from efcore_song"); + //测试前清空数据 + Orm.fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); + //Orm.sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); + Orm.fsql.Ado.ExecuteNonQuery("delete from efcore_song"); - songs = Enumerable.Range(0, size).Select(a => new Song { - Create_time = DateTime.Now, - Is_deleted = false, - Title = $"Insert_{a}", - Url = $"Url_{a}" - }); + songs = Enumerable.Range(0, size).Select(a => new Song + { + Create_time = DateTime.Now, + Is_deleted = false, + Title = $"Insert_{a}", + Url = $"Url_{a}" + }); - //预热 - Orm.fsql.Insert(songs.First()).ExecuteAffrows(); - //Orm.sugar.Insertable(songs.First()).ExecuteCommand(); - using (var db = new SongContext()) { - //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.AddRange(songs.First()); - db.SaveChanges(); - } - } + //预热 + Orm.fsql.Insert(songs.First()).ExecuteAffrows(); + //Orm.sugar.Insertable(songs.First()).ExecuteCommand(); + using (var db = new SongContext()) + { + //db.Configuration.AutoDetectChangesEnabled = false; + db.Songs.AddRange(songs.First()); + db.SaveChanges(); + } + } - [Benchmark] - public int FreeSqlInsert() => Orm.fsql.Insert(songs).ExecuteAffrows(); + [Benchmark] + public int FreeSqlInsert() => Orm.fsql.Insert(songs).ExecuteAffrows(); - //[Benchmark] - //public int SqlSugarInsert() => Orm.sugar.Insertable(songs.ToArray()).ExecuteCommand(); + //[Benchmark] + //public int SqlSugarInsert() => Orm.sugar.Insertable(songs.ToArray()).ExecuteCommand(); - [Benchmark] - public int EfCoreInsert() { - using (var db = new SongContext()) { - //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.AddRange(songs.ToArray()); - return db.SaveChanges(); - } - } - } + [Benchmark] + public int EfCoreInsert() + { + using (var db = new SongContext()) + { + //db.Configuration.AutoDetectChangesEnabled = false; + db.Songs.AddRange(songs.ToArray()); + return db.SaveChanges(); + } + } + } - [CoreJob] - [RPlotExporter, RankColumn] - public class OrmVsUpdate { - public List songs; + [CoreJob] + [RPlotExporter, RankColumn] + public class OrmVsUpdate + { + public List songs; - [Params(1, 500, 1000, 5000, 10000, 50000, 100000)] - public int size; + [Params(1, 500, 1000, 5000, 10000, 50000, 100000)] + public int size; - [GlobalSetup] - public void Setup() { - songs = Orm.fsql.Select().Limit(size).ToList(); - } + [GlobalSetup] + public void Setup() + { + songs = Orm.fsql.Select().Limit(size).ToList(); + } - [Benchmark] - public int FreeSqlUpdate() => Orm.fsql.Update().SetSource(songs).ExecuteAffrows(); + [Benchmark] + public int FreeSqlUpdate() => Orm.fsql.Update().SetSource(songs).ExecuteAffrows(); - //[Benchmark] - //public int SqlSugarUpdate() => Orm.sugar.Updateable(songs).ExecuteCommand(); + //[Benchmark] + //public int SqlSugarUpdate() => Orm.sugar.Updateable(songs).ExecuteCommand(); - [Benchmark] - public int EfCoreUpdate() { - using (var db = new SongContext()) { - //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.UpdateRange(songs.ToArray()); - return db.SaveChanges(); - } - } - } + [Benchmark] + public int EfCoreUpdate() + { + using (var db = new SongContext()) + { + //db.Configuration.AutoDetectChangesEnabled = false; + db.Songs.UpdateRange(songs.ToArray()); + return db.SaveChanges(); + } + } + } - [CoreJob] - [RPlotExporter, RankColumn] - public class OrmVsSelect { + [CoreJob] + [RPlotExporter, RankColumn] + public class OrmVsSelect + { - [Params(1, 500, 1000, 5000, 10000, 50000, 100000)] - public int size; + [Params(1, 500, 1000, 5000, 10000, 50000, 100000)] + public int size; - [GlobalSetup] - public void Setup() { - - } + [GlobalSetup] + public void Setup() + { - [Benchmark] - public List FreeSqlSelect() => Orm.fsql.Select().Limit(size).ToList(); + } - //[Benchmark] - //public List SqlSugarSelect() => Orm.sugar.Queryable().Take(size).ToList(); + [Benchmark] + public List FreeSqlSelect() => Orm.fsql.Select().Limit(size).ToList(); - [Benchmark] - public List EfCoreSelect() { - using (var db = new SongContext()) { - return db.Songs.Take(size).AsNoTracking().ToList(); - } - } - } + //[Benchmark] + //public List SqlSugarSelect() => Orm.sugar.Queryable().Take(size).ToList(); - [FreeSql.DataAnnotations.Table(Name = "freesql_song")] - //[SugarTable("sugar_song")] - [Table("efcore_song")] - public class Song { - [FreeSql.DataAnnotations.Column(IsIdentity = true)] - //[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } + [Benchmark] + public List EfCoreSelect() + { + using (var db = new SongContext()) + { + return db.Songs.Take(size).AsNoTracking().ToList(); + } + } + } - //[SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual ICollection Tags { get; set; } - } - [FreeSql.DataAnnotations.Table(Name = "freesql_song_tag")] - //[SugarTable("sugar_song_tag")] - [Table("efcore_song_tag")] - public class Song_tag { - public int Song_id { get; set; } - //[SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual Song Song { get; set; } + [FreeSql.DataAnnotations.Table(Name = "freesql_song")] + //[SugarTable("sugar_song")] + [Table("efcore_song")] + public class Song + { + [FreeSql.DataAnnotations.Column(IsIdentity = true)] + //[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } - public int Tag_id { get; set; } - //[SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual Tag Tag { get; set; } - } - [FreeSql.DataAnnotations.Table(Name = "freesql_tag")] - //[SugarTable("sugar_tag")] - [Table("efcore_tag")] - public class Tag { - [FreeSql.DataAnnotations.Column(IsIdentity = true)] - //[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - public int? Parent_id { get; set; } - //[SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual Tag Parent { get; set; } + //[SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual ICollection Tags { get; set; } + } + [FreeSql.DataAnnotations.Table(Name = "freesql_song_tag")] + //[SugarTable("sugar_song_tag")] + [Table("efcore_song_tag")] + public class Song_tag + { + public int Song_id { get; set; } + //[SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual Song Song { get; set; } - public decimal? Ddd { get; set; } - public string Name { get; set; } + public int Tag_id { get; set; } + //[SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual Tag Tag { get; set; } + } + [FreeSql.DataAnnotations.Table(Name = "freesql_tag")] + //[SugarTable("sugar_tag")] + [Table("efcore_tag")] + public class Tag + { + [FreeSql.DataAnnotations.Column(IsIdentity = true)] + //[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + public int? Parent_id { get; set; } + //[SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual Tag Parent { get; set; } - //[SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual ICollection Songs { get; set; } - //[SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual ICollection Tags { get; set; } - } + public decimal? Ddd { get; set; } + public string Name { get; set; } + + //[SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual ICollection Songs { get; set; } + //[SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual ICollection Tags { get; set; } + } } diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs index 90252e03..8d8e4299 100644 --- a/Examples/dbcontext_01/Controllers/ValuesController.cs +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -5,237 +5,251 @@ using System.Threading.Tasks; using FreeSql; using Microsoft.AspNetCore.Mvc; -namespace dbcontext_01.Controllers { - [Route("api/[controller]")] - [ApiController] - public class ValuesController : ControllerBase { - - IFreeSql _orm; - SongContext _songContext; - public ValuesController(SongContext songContext, - IFreeSql orm1, IFreeSql orm2, - IFreeSql orm3 - ) { - _songContext = songContext; - _orm = orm1; +namespace dbcontext_01.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ValuesController : ControllerBase + { + + IFreeSql _orm; + SongContext _songContext; + public ValuesController(SongContext songContext, + IFreeSql orm1, IFreeSql orm2, + IFreeSql orm3 + ) + { + _songContext = songContext; + _orm = orm1; + + } + + // GET api/values + [HttpGet] + async public Task Get() + { + + long id = 0; + + try + { + + var repos2Song = _orm.GetRepository(); + repos2Song.Where(a => a.Id > 10).ToList(); + //查询结果,进入 states + + var song = new Song { }; + repos2Song.Insert(song); + id = song.Id; - } - - // GET api/values - [HttpGet] - async public Task Get() { + var adds = Enumerable.Range(0, 100) + .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .ToList(); + //创建一堆无主键值 - long id = 0; + repos2Song.Insert(adds); - try { + for (var a = 0; a < 10; a++) + adds[a].Title = "dkdkdkdk" + a; - var repos2Song = _orm.GetRepository(); - repos2Song.Where(a => a.Id > 10).ToList(); - //查询结果,进入 states + repos2Song.Update(adds); + //批量修改 - var song = new Song { }; - repos2Song.Insert(song); - id = song.Id; + repos2Song.Delete(adds.Skip(10).Take(20).ToList()); + //批量删除,10-20 元素的主键值会被清除 - var adds = Enumerable.Range(0, 100) - .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) - .ToList(); - //创建一堆无主键值 + adds.Last().Url = "skldfjlksdjglkjjcccc"; + repos2Song.Update(adds.Last()); - repos2Song.Insert(adds); + adds.First().Url = "skldfjlksdjglkjjcccc"; + repos2Song.Update(adds.First()); - for (var a = 0; a < 10; a++) - adds[a].Title = "dkdkdkdk" + a; - repos2Song.Update(adds); - //批量修改 + var ctx = _songContext; + var tag = new Tag + { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + ctx.Tags.Add(tag); - repos2Song.Delete(adds.Skip(10).Take(20).ToList()); - //批量删除,10-20 元素的主键值会被清除 - adds.Last().Url = "skldfjlksdjglkjjcccc"; - repos2Song.Update(adds.Last()); + ctx.UnitOfWork.GetOrBeginTransaction(); - adds.First().Url = "skldfjlksdjglkjjcccc"; - repos2Song.Update(adds.First()); + var tagAsync = new Tag + { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + await ctx.Tags.AddAsync(tagAsync); - var ctx = _songContext; - var tag = new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } - } - }; - ctx.Tags.Add(tag); + ctx.Songs.Select.Where(a => a.Id > 10).ToList(); + //查询结果,进入 states + song = new Song { }; + //可插入的 song - ctx.UnitOfWork.GetOrBeginTransaction(); + ctx.Songs.Add(song); + id = song.Id; + //因有自增类型,立即开启事务执行SQL,返回自增值 - var tagAsync = new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } - } - }; - await ctx.Tags.AddAsync(tagAsync); + adds = Enumerable.Range(0, 100) + .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .ToList(); + //创建一堆无主键值 + ctx.Songs.AddRange(adds); + //立即执行,将自增值赋给 adds 所有元素,因为有自增类型,如果其他类型,指定传入主键值,不会立即执行 - ctx.Songs.Select.Where(a => a.Id > 10).ToList(); - //查询结果,进入 states + for (var a = 0; a < 10; a++) + adds[a].Title = "dkdkdkdk" + a; - song = new Song { }; - //可插入的 song + ctx.Songs.UpdateRange(adds); + //批量修改,进入队列 - ctx.Songs.Add(song); - id = song.Id; - //因有自增类型,立即开启事务执行SQL,返回自增值 + ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); + //批量删除,进入队列,完成时 10-20 元素的主键值会被清除 - adds = Enumerable.Range(0, 100) - .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) - .ToList(); - //创建一堆无主键值 + //ctx.Songs.Update(adds.First()); - ctx.Songs.AddRange(adds); - //立即执行,将自增值赋给 adds 所有元素,因为有自增类型,如果其他类型,指定传入主键值,不会立即执行 + adds.Last().Url = "skldfjlksdjglkjjcccc"; + ctx.Songs.Update(adds.Last()); - for (var a = 0; a < 10; a++) - adds[a].Title = "dkdkdkdk" + a; + adds.First().Url = "skldfjlksdjglkjjcccc"; + ctx.Songs.Update(adds.First()); - ctx.Songs.UpdateRange(adds); - //批量修改,进入队列 + //单条修改 urls 的值,进入队列 - ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); - //批量删除,进入队列,完成时 10-20 元素的主键值会被清除 + //throw new Exception("回滚"); - //ctx.Songs.Update(adds.First()); + //ctx.Songs.Select.First(); + //这里做一个查询,会立即打包【执行队列】,避免没有提交的数据,影响查询结果 - adds.Last().Url = "skldfjlksdjglkjjcccc"; - ctx.Songs.Update(adds.Last()); + ctx.SaveChanges(); + //打包【执行队列】,提交事务 - adds.First().Url = "skldfjlksdjglkjjcccc"; - ctx.Songs.Update(adds.First()); - //单条修改 urls 的值,进入队列 + using (var uow = _orm.CreateUnitOfWork()) + { - //throw new Exception("回滚"); + var reposSong = uow.GetRepository(); + reposSong.Where(a => a.Id > 10).ToList(); + //查询结果,进入 states - //ctx.Songs.Select.First(); - //这里做一个查询,会立即打包【执行队列】,避免没有提交的数据,影响查询结果 + song = new Song { }; + reposSong.Insert(song); + id = song.Id; - ctx.SaveChanges(); - //打包【执行队列】,提交事务 + adds = Enumerable.Range(0, 100) + .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .ToList(); + //创建一堆无主键值 + reposSong.Insert(adds); - using (var uow = _orm.CreateUnitOfWork()) { + for (var a = 0; a < 10; a++) + adds[a].Title = "dkdkdkdk" + a; - var reposSong = uow.GetRepository(); - reposSong.Where(a => a.Id > 10).ToList(); - //查询结果,进入 states + reposSong.Update(adds); + //批量修改 - song = new Song { }; - reposSong.Insert(song); - id = song.Id; + reposSong.Delete(adds.Skip(10).Take(20).ToList()); + //批量删除,10-20 元素的主键值会被清除 - adds = Enumerable.Range(0, 100) - .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) - .ToList(); - //创建一堆无主键值 + adds.Last().Url = "skldfjlksdjglkjjcccc"; + reposSong.Update(adds.Last()); - reposSong.Insert(adds); + adds.First().Url = "skldfjlksdjglkjjcccc"; + reposSong.Update(adds.First()); - for (var a = 0; a < 10; a++) - adds[a].Title = "dkdkdkdk" + a; + uow.Commit(); + } - reposSong.Update(adds); - //批量修改 - reposSong.Delete(adds.Skip(10).Take(20).ToList()); - //批量删除,10-20 元素的主键值会被清除 - adds.Last().Url = "skldfjlksdjglkjjcccc"; - reposSong.Update(adds.Last()); + //using (var ctx = new SongContext()) { - adds.First().Url = "skldfjlksdjglkjjcccc"; - reposSong.Update(adds.First()); + // var song = new Song { }; + // await ctx.Songs.AddAsync(song); + // id = song.Id; - uow.Commit(); - } + // var adds = Enumerable.Range(0, 100) + // .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + // .ToList(); + // await ctx.Songs.AddRangeAsync(adds); + // for (var a = 0; a < adds.Count; a++) + // adds[a].Title = "dkdkdkdk" + a; + // ctx.Songs.UpdateRange(adds); - //using (var ctx = new SongContext()) { + // ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); - // var song = new Song { }; - // await ctx.Songs.AddAsync(song); - // id = song.Id; + // //ctx.Songs.Update(adds.First()); - // var adds = Enumerable.Range(0, 100) - // .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) - // .ToList(); - // await ctx.Songs.AddRangeAsync(adds); + // adds.Last().Url = "skldfjlksdjglkjjcccc"; + // ctx.Songs.Update(adds.Last()); - // for (var a = 0; a < adds.Count; a++) - // adds[a].Title = "dkdkdkdk" + a; + // //throw new Exception("回滚"); - // ctx.Songs.UpdateRange(adds); + // await ctx.SaveChangesAsync(); + //} + } + catch + { + var item = await _orm.Select().Where(a => a.Id == id).FirstAsync(); - // ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); + throw; + } - // //ctx.Songs.Update(adds.First()); + var item22 = await _orm.Select().Where(a => a.Id == id).FirstAsync(); + var item33 = await _orm.Select().Where(a => a.Id > id).ToListAsync(); - // adds.Last().Url = "skldfjlksdjglkjjcccc"; - // ctx.Songs.Update(adds.Last()); + return item22.Id.ToString(); + } - // //throw new Exception("回滚"); + // GET api/values/5 + [HttpGet("{id}")] + public ActionResult Get(int id) + { + return "value"; + } - // await ctx.SaveChangesAsync(); - //} - } catch { - var item = await _orm.Select().Where(a => a.Id == id).FirstAsync(); + // POST api/values + [HttpPost] + public void Post([FromBody] string value) + { + } - throw; - } + // PUT api/values/5 + [HttpPut("{id}")] + public void Put(int id, [FromBody] string value) + { + } - var item22 = await _orm.Select().Where(a => a.Id == id).FirstAsync(); - var item33 = await _orm.Select().Where(a => a.Id > id).ToListAsync(); - - return item22.Id.ToString(); - } - - // GET api/values/5 - [HttpGet("{id}")] - public ActionResult Get(int id) { - return "value"; - } - - // POST api/values - [HttpPost] - public void Post([FromBody] string value) { - } - - // PUT api/values/5 - [HttpPut("{id}")] - public void Put(int id, [FromBody] string value) { - } - - // DELETE api/values/5 - [HttpDelete("{id}")] - public void Delete(int id) { - } - } + // DELETE api/values/5 + [HttpDelete("{id}")] + public void Delete(int id) + { + } + } } diff --git a/Examples/dbcontext_01/DbContexts/SongContext.cs b/Examples/dbcontext_01/DbContexts/SongContext.cs index 126c5fd4..2e0ddde9 100644 --- a/Examples/dbcontext_01/DbContexts/SongContext.cs +++ b/Examples/dbcontext_01/DbContexts/SongContext.cs @@ -3,50 +3,55 @@ using FreeSql.DataAnnotations; using System; using System.Collections.Generic; -namespace dbcontext_01 { +namespace dbcontext_01 +{ - public class SongContext : DbContext { + public class SongContext : DbContext + { - public DbSet Songs { get; set; } - public DbSet Tags { get; set; } + public DbSet Songs { get; set; } + public DbSet Tags { get; set; } - //protected override void OnConfiguring(DbContextOptionsBuilder builder) { - // builder.UseFreeSql(dbcontext_01.Startup.Fsql); - //} - } + //protected override void OnConfiguring(DbContextOptionsBuilder builder) { + // builder.UseFreeSql(dbcontext_01.Startup.Fsql); + //} + } - public class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } + public class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } - public virtual ICollection Tags { get; set; } + public virtual ICollection Tags { get; set; } - [Column(IsVersion = true)] - public long versionRow { get; set; } - } - public class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } + [Column(IsVersion = true)] + public long versionRow { get; set; } + } + public class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } - } + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } - public class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } + public class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } - public decimal? Ddd { get; set; } - public string Name { get; set; } + public decimal? Ddd { get; set; } + public string Name { get; set; } - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } - } + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } } diff --git a/Examples/dbcontext_01/Program.cs b/Examples/dbcontext_01/Program.cs index d1a5dafb..ef6e0446 100644 --- a/Examples/dbcontext_01/Program.cs +++ b/Examples/dbcontext_01/Program.cs @@ -17,51 +17,56 @@ namespace dbcontext_01 public class Program { - public class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string BigNumber { get; set; } + public class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string BigNumber { get; set; } - [Column(IsVersion = true)]//使用简单 - public long versionRow { get; set; } - } + [Column(IsVersion = true)]//使用简单 + public long versionRow { get; set; } + } - public class SongContext : DbContext { + public class SongContext : DbContext + { - public DbSet Songs { get; set; } + public DbSet Songs { get; set; } - protected override void OnConfiguring(DbContextOptionsBuilder builder) { - builder.UseFreeSql(fsql); - } - } - static IFreeSql fsql; - public static void Main(string[] args) { - fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseNoneCommandParameter(true) + protected override void OnConfiguring(DbContextOptionsBuilder builder) + { + builder.UseFreeSql(fsql); + } + } + static IFreeSql fsql; + public static void Main(string[] args) + { + fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNoneCommandParameter(true) - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) - .Build(); + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .Build(); - using (var ctx = new SongContext()) { - var song = new Song { BigNumber = "1000000000000000000" }; - ctx.Songs.Add(song); + using (var ctx = new SongContext()) + { + var song = new Song { BigNumber = "1000000000000000000" }; + ctx.Songs.Add(song); - ctx.Songs.Update(song); + ctx.Songs.Update(song); - song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); - ctx.Songs.Update(song); + song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); + ctx.Songs.Update(song); - ctx.SaveChanges(); + ctx.SaveChanges(); - var sql = fsql.Update().SetSource(song).ToSql(); - } + var sql = fsql.Update().SetSource(song).ToSql(); + } - CreateWebHostBuilder(args).Build().Run(); - } + CreateWebHostBuilder(args).Build().Run(); + } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) diff --git a/Examples/dbcontext_01/Properties/launchSettings.json b/Examples/dbcontext_01/Properties/launchSettings.json index a7caa4d3..b51150e2 100644 --- a/Examples/dbcontext_01/Properties/launchSettings.json +++ b/Examples/dbcontext_01/Properties/launchSettings.json @@ -1,27 +1,27 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:53030/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:53030/", + "sslPort": 0 + } }, - "dbcontext_01": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:53031/" + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "dbcontext_01": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:53031/" + } } - } } \ No newline at end of file diff --git a/Examples/dbcontext_01/Startup.cs b/Examples/dbcontext_01/Startup.cs index 3955cb87..181e9068 100644 --- a/Examples/dbcontext_01/Startup.cs +++ b/Examples/dbcontext_01/Startup.cs @@ -19,93 +19,101 @@ namespace dbcontext_01 { Configuration = configuration; - Fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document2.db;Pooling=true;Max Pool Size=10") - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + Fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document2.db;Pooling=true;Max Pool Size=10") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") - //.UseSyncStructureToUpper(true) + //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") + //.UseSyncStructureToUpper(true) - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseNoneCommandParameter(true) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNoneCommandParameter(true) - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), - (cmd, log) => Trace.WriteLine(log) - ) - .Build(); - Fsql.Aop.SyncStructureBefore = (s, e) => { - Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName))); - }; - Fsql.Aop.SyncStructureAfter = (s, e) => { - Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName)) + " " + e.ElapsedMilliseconds + "ms\r\n" + e.Exception?.Message + e.Sql); - }; + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), + (cmd, log) => Trace.WriteLine(log) + ) + .Build(); + Fsql.Aop.SyncStructureBefore = (s, e) => + { + Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName))); + }; + Fsql.Aop.SyncStructureAfter = (s, e) => + { + Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName)) + " " + e.ElapsedMilliseconds + "ms\r\n" + e.Exception?.Message + e.Sql); + }; - Fsql.Aop.CurdBefore = (s, e) => { - Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + ", " + e.Sql); - }; - Fsql.Aop.CurdAfter = (s, e) => { - Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + " " + e.ElapsedMilliseconds + "ms, " + e.Sql); - }; + Fsql.Aop.CurdBefore = (s, e) => + { + Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + ", " + e.Sql); + }; + Fsql.Aop.CurdAfter = (s, e) => + { + Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + " " + e.ElapsedMilliseconds + "ms, " + e.Sql); + }; - Fsql2 = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document222.db;Pooling=true;Max Pool Size=10") - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) + Fsql2 = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document222.db;Pooling=true;Max Pool Size=10") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), - (cmd, log) => Trace.WriteLine(log) - ) - .Build(); - } + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), + (cmd, log) => Trace.WriteLine(log) + ) + .Build(); + } - enum MySql { } - enum PgSql { } + enum MySql { } + enum PgSql { } - public IConfiguration Configuration { get; } - public static IFreeSql Fsql { get; private set; } - public static IFreeSql Fsql2 { get; private set; } + public IConfiguration Configuration { get; } + public static IFreeSql Fsql { get; private set; } + public static IFreeSql Fsql2 { get; private set; } - public void ConfigureServices(IServiceCollection services) + public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - services.AddSwaggerGen(options => { - options.SwaggerDoc("v1", new Info { - Version = "v1", - Title = "FreeSql.DbContext API" - }); - //options.IncludeXmlComments(xmlPath); - }); + services.AddMvc(); + services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new Info + { + Version = "v1", + Title = "FreeSql.DbContext API" + }); + //options.IncludeXmlComments(xmlPath); + }); - services.AddSingleton(Fsql); - services.AddSingleton>(Fsql2); - services.AddFreeDbContext(options => options.UseFreeSql(Fsql)); + services.AddSingleton(Fsql); + services.AddSingleton>(Fsql2); + services.AddFreeDbContext(options => options.UseFreeSql(Fsql)); - var sql1 = Fsql.Update(1).Set(a => a.Id + 10).ToSql(); - var sql2 = Fsql.Update(1).Set(a => a.Title + 10).ToSql(); - var sql3 = Fsql.Update(1).Set(a => a.Create_time.Value.AddHours(1)).ToSql(); - } + var sql1 = Fsql.Update(1).Set(a => a.Id + 10).ToSql(); + var sql2 = Fsql.Update(1).Set(a => a.Title + 10).ToSql(); + var sql3 = Fsql.Update(1).Set(a => a.Create_time.Value.AddHours(1)).ToSql(); + } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - Console.OutputEncoding = Encoding.GetEncoding("GB2312"); - Console.InputEncoding = Encoding.GetEncoding("GB2312"); + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Console.OutputEncoding = Encoding.GetEncoding("GB2312"); + Console.InputEncoding = Encoding.GetEncoding("GB2312"); - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); - app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); - app.UseDeveloperExceptionPage(); - app.UseMvc(); + app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); + app.UseDeveloperExceptionPage(); + app.UseMvc(); - app.UseSwagger(); - app.UseSwaggerUI(c => { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); - }); - } - } + app.UseSwagger(); + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); + }); + } + } } diff --git a/Examples/dbcontext_01/appsettings.Development.json b/Examples/dbcontext_01/appsettings.Development.json index e203e940..6ba02f3f 100644 --- a/Examples/dbcontext_01/appsettings.Development.json +++ b/Examples/dbcontext_01/appsettings.Development.json @@ -1,9 +1,9 @@ { - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } } - } } diff --git a/Examples/dbcontext_01/appsettings.json b/Examples/dbcontext_01/appsettings.json index def9159a..6d451ac2 100644 --- a/Examples/dbcontext_01/appsettings.json +++ b/Examples/dbcontext_01/appsettings.json @@ -1,8 +1,8 @@ { - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" } diff --git a/Examples/efcore_to_freesql/DBContexts/BaseDBContext.cs b/Examples/efcore_to_freesql/DBContexts/BaseDBContext.cs index 98eef7f6..69c4326d 100644 --- a/Examples/efcore_to_freesql/DBContexts/BaseDBContext.cs +++ b/Examples/efcore_to_freesql/DBContexts/BaseDBContext.cs @@ -2,18 +2,22 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using System; -namespace efcore_to_freesql.DBContexts { +namespace efcore_to_freesql.DBContexts +{ - public class BaseDBContext : DbContext { + public class BaseDBContext : DbContext + { - public static IFreeSql Fsql { get; set; } + public static IFreeSql Fsql { get; set; } - protected override void OnModelCreating(ModelBuilder modelBuilder) { - base.OnModelCreating(modelBuilder); - Fsql.CodeFirst.ConfigEntity(modelBuilder.Model); //ͬ - } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseSqlite(@"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10"); - } - } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + Fsql.CodeFirst.ConfigEntity(modelBuilder.Model); //ͬ + } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(@"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10"); + } + } } \ No newline at end of file diff --git a/Examples/efcore_to_freesql/DBContexts/Topic1Context.cs b/Examples/efcore_to_freesql/DBContexts/Topic1Context.cs index f827c0bc..b0a8d782 100644 --- a/Examples/efcore_to_freesql/DBContexts/Topic1Context.cs +++ b/Examples/efcore_to_freesql/DBContexts/Topic1Context.cs @@ -1,18 +1,21 @@ using efcore_to_freesql.Entitys; using Microsoft.EntityFrameworkCore; -namespace efcore_to_freesql.DBContexts { +namespace efcore_to_freesql.DBContexts +{ - public class Topic1Context : BaseDBContext { + public class Topic1Context : BaseDBContext + { public DbSet Topic1s { get; set; } - protected override void OnModelCreating(ModelBuilder modelBuilder) { + protected override void OnModelCreating(ModelBuilder modelBuilder) + { - modelBuilder.Entity().ToTable("topic1_sss").HasKey(a => a.Id); - modelBuilder.Entity().Property(a => a.Id).HasColumnName("topic1_id").ValueGeneratedOnAdd(); + modelBuilder.Entity().ToTable("topic1_sss").HasKey(a => a.Id); + modelBuilder.Entity().Property(a => a.Id).HasColumnName("topic1_id").ValueGeneratedOnAdd(); - base.OnModelCreating(modelBuilder); - } - } + base.OnModelCreating(modelBuilder); + } + } } \ No newline at end of file diff --git a/Examples/efcore_to_freesql/DBContexts/Topic2Context.cs b/Examples/efcore_to_freesql/DBContexts/Topic2Context.cs index bb978828..0799b0e0 100644 --- a/Examples/efcore_to_freesql/DBContexts/Topic2Context.cs +++ b/Examples/efcore_to_freesql/DBContexts/Topic2Context.cs @@ -1,18 +1,21 @@ using efcore_to_freesql.Entitys; using Microsoft.EntityFrameworkCore; -namespace efcore_to_freesql.DBContexts { +namespace efcore_to_freesql.DBContexts +{ - public class Topic2Context : BaseDBContext { + public class Topic2Context : BaseDBContext + { - public DbSet Topic2s { get; set; } + public DbSet Topic2s { get; set; } - protected override void OnModelCreating(ModelBuilder modelBuilder) { + protected override void OnModelCreating(ModelBuilder modelBuilder) + { - modelBuilder.Entity().ToTable("topic2_sss"); - modelBuilder.Entity().Property(a => a.Id).HasColumnName("topic2_id"); + modelBuilder.Entity().ToTable("topic2_sss"); + modelBuilder.Entity().Property(a => a.Id).HasColumnName("topic2_id"); - base.OnModelCreating(modelBuilder); - } - } + base.OnModelCreating(modelBuilder); + } + } } \ No newline at end of file diff --git a/Examples/efcore_to_freesql/Entitys/Topic1.cs b/Examples/efcore_to_freesql/Entitys/Topic1.cs index cb28c4f4..9bdecef6 100644 --- a/Examples/efcore_to_freesql/Entitys/Topic1.cs +++ b/Examples/efcore_to_freesql/Entitys/Topic1.cs @@ -1,6 +1,7 @@ using System; -namespace efcore_to_freesql.Entitys { +namespace efcore_to_freesql.Entitys +{ public class Topic1 { diff --git a/Examples/efcore_to_freesql/Entitys/Topic2.cs b/Examples/efcore_to_freesql/Entitys/Topic2.cs index 2e503ba4..f0112ba8 100644 --- a/Examples/efcore_to_freesql/Entitys/Topic2.cs +++ b/Examples/efcore_to_freesql/Entitys/Topic2.cs @@ -2,7 +2,8 @@ using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace efcore_to_freesql.Entitys { +namespace efcore_to_freesql.Entitys +{ public class Topic2 { diff --git a/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs b/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs index 9c480405..1c6d5e68 100644 --- a/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs +++ b/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs @@ -6,60 +6,67 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -public static class CodeFirstExtensions { +public static class CodeFirstExtensions +{ - public static void ConfigEntity(this ICodeFirst codeFirst, IModel efmodel) { + public static void ConfigEntity(this ICodeFirst codeFirst, IModel efmodel) + { - foreach (var type in efmodel.GetEntityTypes()) { + foreach (var type in efmodel.GetEntityTypes()) + { - codeFirst.ConfigEntity(type.ClrType, a => { + codeFirst.ConfigEntity(type.ClrType, a => + { - //表名 - var relationalTableName = type.FindAnnotation("Relational:TableName"); - if (relationalTableName != null) - a.Name(relationalTableName.Value?.ToString() ?? type.ClrType.Name); + //表名 + var relationalTableName = type.FindAnnotation("Relational:TableName"); + if (relationalTableName != null) + a.Name(relationalTableName.Value?.ToString() ?? type.ClrType.Name); - foreach (var prop in type.GetProperties()) { + foreach (var prop in type.GetProperties()) + { - var freeProp = a.Property(prop.Name); + var freeProp = a.Property(prop.Name); - //列名 - var relationalColumnName = prop.FindAnnotation("Relational:ColumnName"); - if (relationalColumnName != null) - freeProp.Name(relationalColumnName.Value?.ToString() ?? prop.Name); + //列名 + var relationalColumnName = prop.FindAnnotation("Relational:ColumnName"); + if (relationalColumnName != null) + freeProp.Name(relationalColumnName.Value?.ToString() ?? prop.Name); - //主键 - freeProp.IsPrimary(prop.IsPrimaryKey()); + //主键 + freeProp.IsPrimary(prop.IsPrimaryKey()); - //自增 - freeProp.IsIdentity( - prop.ValueGenerated == ValueGenerated.Never || - prop.ValueGenerated == ValueGenerated.OnAdd || - prop.GetAnnotations().Where(z => - z.Name == "SqlServer:ValueGenerationStrategy" && z.Value.ToString().Contains("IdentityColumn") //sqlserver 自增 - || z.Value.ToString().Contains("IdentityColumn") //其他数据库实现未经测试 - ).Any() - ); + //自增 + freeProp.IsIdentity( + prop.ValueGenerated == ValueGenerated.Never || + prop.ValueGenerated == ValueGenerated.OnAdd || + prop.GetAnnotations().Where(z => + z.Name == "SqlServer:ValueGenerationStrategy" && z.Value.ToString().Contains("IdentityColumn") //sqlserver 自增 + || z.Value.ToString().Contains("IdentityColumn") //其他数据库实现未经测试 + ).Any() + ); - //可空 - freeProp.IsNullable(prop.AfterSaveBehavior != PropertySaveBehavior.Throw); + //可空 + freeProp.IsNullable(prop.AfterSaveBehavior != PropertySaveBehavior.Throw); - //类型 - var relationalColumnType = prop.FindAnnotation("Relational:ColumnType"); - if (relationalColumnType != null) { + //类型 + var relationalColumnType = prop.FindAnnotation("Relational:ColumnType"); + if (relationalColumnType != null) + { - var dbType = relationalColumnType.ToString(); - if (!string.IsNullOrEmpty(dbType)) { + var dbType = relationalColumnType.ToString(); + if (!string.IsNullOrEmpty(dbType)) + { - var maxLength = prop.FindAnnotation("MaxLength"); - if (maxLength != null) - dbType += $"({maxLength})"; + var maxLength = prop.FindAnnotation("MaxLength"); + if (maxLength != null) + dbType += $"({maxLength})"; - freeProp.DbType(dbType); - } - } - } - }); - } - } + freeProp.DbType(dbType); + } + } + } + }); + } + } } \ No newline at end of file diff --git a/Examples/efcore_to_freesql/Properties/launchSettings.json b/Examples/efcore_to_freesql/Properties/launchSettings.json index 1ff6c056..73df3ed4 100644 --- a/Examples/efcore_to_freesql/Properties/launchSettings.json +++ b/Examples/efcore_to_freesql/Properties/launchSettings.json @@ -1,30 +1,30 @@ { - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:58143", - "sslPort": 44349 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "api/values", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:58143", + "sslPort": 44349 + } }, - "efcore_to_freesql": { - "commandName": "Project", - "launchBrowser": true, - "launchUrl": "api/values", - "applicationUrl": "https://localhost:5001;http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "efcore_to_freesql": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "api/values", + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } } - } } \ No newline at end of file diff --git a/Examples/efcore_to_freesql/Startup.cs b/Examples/efcore_to_freesql/Startup.cs index 8f30257d..0e9eea21 100644 --- a/Examples/efcore_to_freesql/Startup.cs +++ b/Examples/efcore_to_freesql/Startup.cs @@ -22,57 +22,59 @@ namespace efcore_to_freesql { Configuration = configuration; - Fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .Build(); + Fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .Build(); - DBContexts.BaseDBContext.Fsql = Fsql; + DBContexts.BaseDBContext.Fsql = Fsql; - var sql11 = Fsql.Select().ToSql(); - //SELECT a."Id", a."Title", a."CreateTime" FROM "Topic1" a - var sql12 = Fsql.Insert().AppendData(new Topic1()).ToSql(); - //INSERT INTO "Topic1"("Id", "Title", "CreateTime") VALUES(@Id0, @Title0, @CreateTime0) + var sql11 = Fsql.Select().ToSql(); + //SELECT a."Id", a."Title", a."CreateTime" FROM "Topic1" a + var sql12 = Fsql.Insert().AppendData(new Topic1()).ToSql(); + //INSERT INTO "Topic1"("Id", "Title", "CreateTime") VALUES(@Id0, @Title0, @CreateTime0) - var sql21 = Fsql.Select().ToSql(); - //SELECT a."Id", a."Title", a."CreateTime" FROM "Topic2" a - var sql22 = Fsql.Insert().AppendData(new Topic2()).ToSql(); - //INSERT INTO "Topic2"("Id", "Title", "CreateTime") VALUES(@Id0, @Title0, @CreateTime0) + var sql21 = Fsql.Select().ToSql(); + //SELECT a."Id", a."Title", a."CreateTime" FROM "Topic2" a + var sql22 = Fsql.Insert().AppendData(new Topic2()).ToSql(); + //INSERT INTO "Topic2"("Id", "Title", "CreateTime") VALUES(@Id0, @Title0, @CreateTime0) - using (var db = new Topic1Context()) { - db.Topic1s.Add(new Topic1()); - } - using (var db = new Topic2Context()) { - db.Topic2s.Add(new Topic2()); - } + using (var db = new Topic1Context()) + { + db.Topic1s.Add(new Topic1()); + } + using (var db = new Topic2Context()) + { + db.Topic2s.Add(new Topic2()); + } - var sql13 = Fsql.Select().ToSql(); - //SELECT a."topic1_id", a."Title", a."CreateTime" FROM "topic1_sss" a - var sql14 = Fsql.Insert().AppendData(new Topic1()).ToSql(); - //INSERT INTO "topic1_sss"("Title", "CreateTime") VALUES(@Title0, @CreateTime0) + var sql13 = Fsql.Select().ToSql(); + //SELECT a."topic1_id", a."Title", a."CreateTime" FROM "topic1_sss" a + var sql14 = Fsql.Insert().AppendData(new Topic1()).ToSql(); + //INSERT INTO "topic1_sss"("Title", "CreateTime") VALUES(@Title0, @CreateTime0) - var sql23 = Fsql.Select().ToSql(); - //SELECT a."topic2_id", a."Title", a."CreateTime" FROM "topic2_sss" a - var sql24 = Fsql.Insert().AppendData(new Topic2()).ToSql(); - //INSERT INTO "topic2_sss"("Title", "CreateTime") VALUES(@Title0, @CreateTime0) - } + var sql23 = Fsql.Select().ToSql(); + //SELECT a."topic2_id", a."Title", a."CreateTime" FROM "topic2_sss" a + var sql24 = Fsql.Insert().AppendData(new Topic2()).ToSql(); + //INSERT INTO "topic2_sss"("Title", "CreateTime") VALUES(@Title0, @CreateTime0) + } - public IConfiguration Configuration { get; } - public IFreeSql Fsql { get; } + public IConfiguration Configuration { get; } + public IFreeSql Fsql { get; } - public void ConfigureServices(IServiceCollection services) + public void ConfigureServices(IServiceCollection services) { - services.AddSingleton(Fsql); - services.AddMvc(); + services.AddSingleton(Fsql); + services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); - app.UseDeveloperExceptionPage(); - app.UseMvc(); - } + app.UseDeveloperExceptionPage(); + app.UseMvc(); + } } } diff --git a/Examples/efcore_to_freesql/appsettings.Development.json b/Examples/efcore_to_freesql/appsettings.Development.json index e203e940..6ba02f3f 100644 --- a/Examples/efcore_to_freesql/appsettings.Development.json +++ b/Examples/efcore_to_freesql/appsettings.Development.json @@ -1,9 +1,9 @@ { - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } } - } } diff --git a/Examples/efcore_to_freesql/appsettings.json b/Examples/efcore_to_freesql/appsettings.json index def9159a..6d451ac2 100644 --- a/Examples/efcore_to_freesql/appsettings.json +++ b/Examples/efcore_to_freesql/appsettings.json @@ -1,8 +1,8 @@ { - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" } diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index e90b1aaf..729b9c36 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -14,288 +14,317 @@ namespace orm_vs { class Program { - static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") - .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=20") - .UseAutoSyncStructure(false) - .UseNoneCommandParameter(true) - //.UseConfigEntityFromDbFirst(true) - .Build(); + static IFreeSql fsql = new FreeSql.FreeSqlBuilder() + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + .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=20") + .UseAutoSyncStructure(false) + .UseNoneCommandParameter(true) + //.UseConfigEntityFromDbFirst(true) + .Build(); - static SqlSugarClient sugar { - get => new SqlSugarClient(new ConnectionConfig() { - //不欺负,让连接池100个最小 - //ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", - //DbType = DbType.SqlServer, - ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", - DbType = DbType.MySql, - IsAutoCloseConnection = true, - InitKeyType = InitKeyType.Attribute - }); - } + static SqlSugarClient sugar + { + get => new SqlSugarClient(new ConnectionConfig() + { + //不欺负,让连接池100个最小 + //ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + //DbType = DbType.SqlServer, + ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + DbType = DbType.MySql, + IsAutoCloseConnection = true, + InitKeyType = InitKeyType.Attribute + }); + } - class SongContext : DbContext { - public DbSet Songs { get; set; } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - //optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); - optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); - } - } + class SongContext : DbContext + { + public DbSet Songs { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + //optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); + optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); + } + } - static void Main(string[] args) { + static void Main(string[] args) + { - fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); - //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); - //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements + fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements - sugar.Aop.OnLogExecuted = (s, e) => { - Trace.WriteLine(s); - }; - //测试前清空数据 - fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); - sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); - fsql.Ado.ExecuteNonQuery("delete from efcore_song"); + sugar.Aop.OnLogExecuted = (s, e) => + { + Trace.WriteLine(s); + }; + //测试前清空数据 + fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); + sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); + fsql.Ado.ExecuteNonQuery("delete from efcore_song"); - var sb = new StringBuilder(); - Console.WriteLine("插入性能:"); - Insert(sb, 1000, 1); - Console.Write(sb.ToString()); - sb.Clear(); - Insert(sb, 1000, 10); - Console.Write(sb.ToString()); - sb.Clear(); + var sb = new StringBuilder(); + Console.WriteLine("插入性能:"); + Insert(sb, 1000, 1); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(sb, 1000, 10); + Console.Write(sb.ToString()); + sb.Clear(); - Insert(sb, 1, 1000); - Console.Write(sb.ToString()); - sb.Clear(); - Insert(sb, 1, 10000); - Console.Write(sb.ToString()); - sb.Clear(); - Insert(sb, 1, 50000); - Console.Write(sb.ToString()); - sb.Clear(); - Insert(sb, 1, 100000); - Console.Write(sb.ToString()); - sb.Clear(); + Insert(sb, 1, 1000); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(sb, 1, 10000); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(sb, 1, 50000); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(sb, 1, 100000); + Console.Write(sb.ToString()); + sb.Clear(); - Console.WriteLine("查询性能:"); - Select(sb, 1000, 1); - Console.Write(sb.ToString()); - sb.Clear(); - Select(sb, 1000, 10); - Console.Write(sb.ToString()); - sb.Clear(); + Console.WriteLine("查询性能:"); + Select(sb, 1000, 1); + Console.Write(sb.ToString()); + sb.Clear(); + Select(sb, 1000, 10); + Console.Write(sb.ToString()); + sb.Clear(); - Select(sb, 1, 1000); - Console.Write(sb.ToString()); - sb.Clear(); - Select(sb, 1, 10000); - Console.Write(sb.ToString()); - sb.Clear(); - Select(sb, 1, 50000); - Console.Write(sb.ToString()); - sb.Clear(); - Select(sb, 1, 100000); - Console.Write(sb.ToString()); - sb.Clear(); + Select(sb, 1, 1000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(sb, 1, 10000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(sb, 1, 50000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(sb, 1, 100000); + Console.Write(sb.ToString()); + sb.Clear(); - Console.WriteLine("更新:"); - Update(sb, 1000, 1); - Console.Write(sb.ToString()); - sb.Clear(); - Update(sb, 1000, 10); - Console.Write(sb.ToString()); - sb.Clear(); + Console.WriteLine("更新:"); + Update(sb, 1000, 1); + Console.Write(sb.ToString()); + sb.Clear(); + Update(sb, 1000, 10); + Console.Write(sb.ToString()); + sb.Clear(); - Update(sb, 1, 1000); - Console.Write(sb.ToString()); - sb.Clear(); - Update(sb, 1, 10000); - Console.Write(sb.ToString()); - sb.Clear(); - Update(sb, 1, 50000); - Console.Write(sb.ToString()); - sb.Clear(); - Update(sb, 1, 100000); - Console.Write(sb.ToString()); - sb.Clear(); + Update(sb, 1, 1000); + Console.Write(sb.ToString()); + sb.Clear(); + Update(sb, 1, 10000); + Console.Write(sb.ToString()); + sb.Clear(); + Update(sb, 1, 50000); + Console.Write(sb.ToString()); + sb.Clear(); + Update(sb, 1, 100000); + Console.Write(sb.ToString()); + sb.Clear(); - Console.WriteLine("测试结束,按任意键退出..."); - Console.ReadKey(); - } + Console.WriteLine("测试结束,按任意键退出..."); + Console.ReadKey(); + } - static void Select(StringBuilder sb, int forTime, int size) { - Stopwatch sw = new Stopwatch(); - sw.Restart(); - for (var a = 0; a < forTime; a++) - fsql.Select().Limit(size).ToList(); - sw.Stop(); - sb.AppendLine($"FreeSql Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + static void Select(StringBuilder sb, int forTime, int size) + { + Stopwatch sw = new Stopwatch(); + sw.Restart(); + for (var a = 0; a < forTime; a++) + fsql.Select().Limit(size).ToList(); + sw.Stop(); + sb.AppendLine($"FreeSql Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); - sw.Restart(); - for (var a = 0; a < forTime; a++) - sugar.Queryable().Take(size).ToList(); - sw.Stop(); - sb.AppendLine($"SqlSugar Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + sw.Restart(); + for (var a = 0; a < forTime; a++) + sugar.Queryable().Take(size).ToList(); + sw.Stop(); + sb.AppendLine($"SqlSugar Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); - sw.Restart(); - for (var a = 0; a < forTime; a++) { - using (var db = new SongContext()) { - db.Songs.Take(size).AsNoTracking().ToList(); - } - } - sw.Stop(); - sb.AppendLine($"EFCore Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); - } + sw.Restart(); + for (var a = 0; a < forTime; a++) + { + using (var db = new SongContext()) + { + db.Songs.Take(size).AsNoTracking().ToList(); + } + } + sw.Stop(); + sb.AppendLine($"EFCore Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); + } - static void Insert(StringBuilder sb, int forTime, int size) { - var songs = Enumerable.Range(0, size).Select(a => new Song { - Create_time = DateTime.Now, - Is_deleted = false, - Title = $"Insert_{a}", - Url = $"Url_{a}" - }); + static void Insert(StringBuilder sb, int forTime, int size) + { + var songs = Enumerable.Range(0, size).Select(a => new Song + { + Create_time = DateTime.Now, + Is_deleted = false, + Title = $"Insert_{a}", + Url = $"Url_{a}" + }); - //预热 - fsql.Insert(songs.First()).ExecuteAffrows(); - sugar.Insertable(songs.First()).ExecuteCommand(); - using (var db = new SongContext()) { - //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.AddRange(songs.First()); - db.SaveChanges(); - } - Stopwatch sw = new Stopwatch(); + //预热 + fsql.Insert(songs.First()).ExecuteAffrows(); + sugar.Insertable(songs.First()).ExecuteCommand(); + using (var db = new SongContext()) + { + //db.Configuration.AutoDetectChangesEnabled = false; + db.Songs.AddRange(songs.First()); + db.SaveChanges(); + } + Stopwatch sw = new Stopwatch(); - sw.Restart(); - for (var a = 0; a < forTime; a++) { - fsql.Insert(songs).ExecuteAffrows(); - //using (var db = new FreeSongContext()) { - // //db.Configuration.AutoDetectChangesEnabled = false; - // db.Songs.AddRange(songs.ToArray()); - // db.SaveChanges(); - //} - } - sw.Stop(); - sb.AppendLine($"FreeSql Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + sw.Restart(); + for (var a = 0; a < forTime; a++) + { + fsql.Insert(songs).ExecuteAffrows(); + //using (var db = new FreeSongContext()) { + // //db.Configuration.AutoDetectChangesEnabled = false; + // db.Songs.AddRange(songs.ToArray()); + // db.SaveChanges(); + //} + } + sw.Stop(); + sb.AppendLine($"FreeSql Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); - sw.Restart(); - Exception sugarEx = null; - try { - for (var a = 0; a < forTime; a++) - sugar.Insertable(songs.ToArray()).ExecuteCommand(); - } catch (Exception ex) { - sugarEx = ex; - } - sw.Stop(); - sb.AppendLine($"SqlSugar Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms" + (sugarEx != null ? $"成绩无效,错误:{sugarEx.Message}" : "")); + sw.Restart(); + Exception sugarEx = null; + try + { + for (var a = 0; a < forTime; a++) + sugar.Insertable(songs.ToArray()).ExecuteCommand(); + } + catch (Exception ex) + { + sugarEx = ex; + } + sw.Stop(); + sb.AppendLine($"SqlSugar Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms" + (sugarEx != null ? $"成绩无效,错误:{sugarEx.Message}" : "")); - sw.Restart(); - for (var a = 0; a < forTime; a++) { + sw.Restart(); + for (var a = 0; a < forTime; a++) + { - using (var db = new SongContext()) { - //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.AddRange(songs.ToArray()); - db.SaveChanges(); - } - } - sw.Stop(); - sb.AppendLine($"EFCore Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); - } + using (var db = new SongContext()) + { + //db.Configuration.AutoDetectChangesEnabled = false; + db.Songs.AddRange(songs.ToArray()); + db.SaveChanges(); + } + } + sw.Stop(); + sb.AppendLine($"EFCore Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); + } - static void Update(StringBuilder sb, int forTime, int size) { - Stopwatch sw = new Stopwatch(); + static void Update(StringBuilder sb, int forTime, int size) + { + Stopwatch sw = new Stopwatch(); - var songs = fsql.Select().Limit(size).ToList(); - sw.Restart(); - for (var a = 0; a < forTime; a++) { - fsql.Update().SetSource(songs).ExecuteAffrows(); - } - sw.Stop(); - sb.AppendLine($"FreeSql Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + var songs = fsql.Select().Limit(size).ToList(); + sw.Restart(); + for (var a = 0; a < forTime; a++) + { + fsql.Update().SetSource(songs).ExecuteAffrows(); + } + sw.Stop(); + sb.AppendLine($"FreeSql Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); - songs = sugar.Queryable().Take(size).ToList(); - sw.Restart(); - Exception sugarEx = null; - try { - for (var a = 0; a < forTime; a++) - sugar.Updateable(songs).ExecuteCommand(); - } catch (Exception ex) { - sugarEx = ex; - } - sw.Stop(); - sb.AppendLine($"SqlSugar Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms" + (sugarEx != null ? $"成绩无效,错误:{sugarEx.Message}" : "")); + songs = sugar.Queryable().Take(size).ToList(); + sw.Restart(); + Exception sugarEx = null; + try + { + for (var a = 0; a < forTime; a++) + sugar.Updateable(songs).ExecuteCommand(); + } + catch (Exception ex) + { + sugarEx = ex; + } + sw.Stop(); + sb.AppendLine($"SqlSugar Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms" + (sugarEx != null ? $"成绩无效,错误:{sugarEx.Message}" : "")); - using (var db = new SongContext()) { - songs = db.Songs.Take(size).AsNoTracking().ToList(); - } - sw.Restart(); - for (var a = 0; a < forTime; a++) { + using (var db = new SongContext()) + { + songs = db.Songs.Take(size).AsNoTracking().ToList(); + } + sw.Restart(); + for (var a = 0; a < forTime; a++) + { - using (var db = new SongContext()) { - //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.UpdateRange(songs.ToArray()); - db.SaveChanges(); - } - } - sw.Stop(); - sb.AppendLine($"EFCore Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); - } - } + using (var db = new SongContext()) + { + //db.Configuration.AutoDetectChangesEnabled = false; + db.Songs.UpdateRange(songs.ToArray()); + db.SaveChanges(); + } + } + sw.Stop(); + sb.AppendLine($"EFCore Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); + } + } - [FreeSql.DataAnnotations.Table(Name = "freesql_song")] - [SugarTable("sugar_song")] - [Table("efcore_song")] - public class Song { - [FreeSql.DataAnnotations.Column(IsIdentity = true)] - [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } + [FreeSql.DataAnnotations.Table(Name = "freesql_song")] + [SugarTable("sugar_song")] + [Table("efcore_song")] + public class Song + { + [FreeSql.DataAnnotations.Column(IsIdentity = true)] + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } - [SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual ICollection Tags { get; set; } - } - [FreeSql.DataAnnotations.Table(Name = "freesql_song_tag")] - [SugarTable("sugar_song_tag")] - [Table("efcore_song_tag")] - public class Song_tag { - public int Song_id { get; set; } - [SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual Song Song { get; set; } + [SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual ICollection Tags { get; set; } + } + [FreeSql.DataAnnotations.Table(Name = "freesql_song_tag")] + [SugarTable("sugar_song_tag")] + [Table("efcore_song_tag")] + public class Song_tag + { + public int Song_id { get; set; } + [SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual Song Song { get; set; } - public int Tag_id { get; set; } - [SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual Tag Tag { get; set; } - } - [FreeSql.DataAnnotations.Table(Name = "freesql_tag")] - [SugarTable("sugar_tag")] - [Table("efcore_tag")] - public class Tag { - [FreeSql.DataAnnotations.Column(IsIdentity = true)] - [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - public int? Parent_id { get; set; } - [SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual Tag Parent { get; set; } + public int Tag_id { get; set; } + [SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual Tag Tag { get; set; } + } + [FreeSql.DataAnnotations.Table(Name = "freesql_tag")] + [SugarTable("sugar_tag")] + [Table("efcore_tag")] + public class Tag + { + [FreeSql.DataAnnotations.Column(IsIdentity = true)] + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + public int? Parent_id { get; set; } + [SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual Tag Parent { get; set; } - public decimal? Ddd { get; set; } - public string Name { get; set; } + public decimal? Ddd { get; set; } + public string Name { get; set; } - [SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual ICollection Songs { get; set; } - [SugarColumn(IsIgnore = true)] - [NotMapped] - public virtual ICollection Tags { get; set; } - } + [SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual ICollection Songs { get; set; } + [SugarColumn(IsIgnore = true)] + [NotMapped] + public virtual ICollection Tags { get; set; } + } } diff --git a/Examples/repository_01/Controllers/SongController.cs b/Examples/repository_01/Controllers/SongController.cs index d162c33c..51d9b9c8 100644 --- a/Examples/repository_01/Controllers/SongController.cs +++ b/Examples/repository_01/Controllers/SongController.cs @@ -6,93 +6,107 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace restful.Controllers { +namespace restful.Controllers +{ - public class SongRepository : GuidRepository { - public SongRepository(IFreeSql fsql) : base(fsql) { - } - } + public class SongRepository : GuidRepository + { + public SongRepository(IFreeSql fsql) : base(fsql) + { + } + } - [Route("restapi/[controller]")] - public class SongsController : Controller { + [Route("restapi/[controller]")] + public class SongsController : Controller + { - BaseRepository _songRepository; + BaseRepository _songRepository; - public class xxxx { - public int Id { get; set; } + public class xxxx + { + public int Id { get; set; } - public bool IsDeleted { get; set; } - } + public bool IsDeleted { get; set; } + } - - public SongsController(IFreeSql fsql, - GuidRepository repos1, - GuidRepository repos2, - DefaultRepository repos11, - DefaultRepository repos21, + public SongsController(IFreeSql fsql, + GuidRepository repos1, + GuidRepository repos2, - BaseRepository repos3, BaseRepository repos4, - IBasicRepository repos31, IBasicRepository repos41, - IReadOnlyRepository repos311, IReadOnlyRepository repos411, + DefaultRepository repos11, + DefaultRepository repos21, - SongRepository reposSong - ) { - _songRepository = repos4; + BaseRepository repos3, BaseRepository repos4, + IBasicRepository repos31, IBasicRepository repos41, + IReadOnlyRepository repos311, IReadOnlyRepository repos411, - //test code - var curd1 = fsql.GetRepository(); - var curd2 = fsql.GetRepository(); - var curd3 = fsql.GetRepository(); - var curd4 = fsql.GetGuidRepository(); + SongRepository reposSong + ) + { + _songRepository = repos4; - Console.WriteLine(repos1.Select.ToSql()); - Console.WriteLine(reposSong.Select.ToSql()); + //test code + var curd1 = fsql.GetRepository(); + var curd2 = fsql.GetRepository(); + var curd3 = fsql.GetRepository(); + var curd4 = fsql.GetGuidRepository(); - Console.WriteLine(repos2.Select.ToSql()); - Console.WriteLine(repos21.Select.ToSql()); + Console.WriteLine(repos1.Select.ToSql()); + Console.WriteLine(reposSong.Select.ToSql()); - using (reposSong.DataFilter.DisableAll()) { - Console.WriteLine(reposSong.Select.ToSql()); - } - } + Console.WriteLine(repos2.Select.ToSql()); + Console.WriteLine(repos21.Select.ToSql()); - [HttpGet] - public Task> GetItems([FromQuery] string key, [FromQuery] int page = 1, [FromQuery] int limit = 20) { - return _songRepository.Select.WhereIf(!string.IsNullOrEmpty(key), a => a.Title.Contains(key)).Page(page, limit).ToListAsync(); - } + using (reposSong.DataFilter.DisableAll()) + { + Console.WriteLine(reposSong.Select.ToSql()); + } + } - [HttpGet("{id}")] - public Task GetItem([FromRoute] int id) { - return _songRepository.FindAsync(id); - } + [HttpGet] + public Task> GetItems([FromQuery] string key, [FromQuery] int page = 1, [FromQuery] int limit = 20) + { + return _songRepository.Select.WhereIf(!string.IsNullOrEmpty(key), a => a.Title.Contains(key)).Page(page, limit).ToListAsync(); + } - public class ModelSong { - public string title { get; set; } - } + [HttpGet("{id}")] + public Task GetItem([FromRoute] int id) + { + return _songRepository.FindAsync(id); + } - [HttpPost, ProducesResponseType(201)] - public Task Create([FromBody] ModelSong model) { - return _songRepository.InsertAsync(new Song { Title = model.title }); - } + public class ModelSong + { + public string title { get; set; } + } - [HttpPut("{id}")] - public Task Update([FromRoute] int id, [FromBody] ModelSong model) { - return _songRepository.UpdateAsync(new Song { Id = id, Title = model.title }); - } + [HttpPost, ProducesResponseType(201)] + public Task Create([FromBody] ModelSong model) + { + return _songRepository.InsertAsync(new Song { Title = model.title }); + } - [HttpPatch("{id}")] - async public Task UpdateDiy([FromRoute] int id, [FromForm] string title) { - var up = _songRepository.UpdateDiy.Where(a => a.Id == id); - if (!string.IsNullOrEmpty(title)) up.Set(a => a.Title, title); - var ret = await up.ExecuteUpdatedAsync(); - return ret.FirstOrDefault(); - } + [HttpPut("{id}")] + public Task Update([FromRoute] int id, [FromBody] ModelSong model) + { + return _songRepository.UpdateAsync(new Song { Id = id, Title = model.title }); + } - [HttpDelete("{id}"), ProducesResponseType(204)] - public Task Delete([FromRoute] int id) { - return _songRepository.DeleteAsync(a => a.Id == id); - } - } + [HttpPatch("{id}")] + async public Task UpdateDiy([FromRoute] int id, [FromForm] string title) + { + var up = _songRepository.UpdateDiy.Where(a => a.Id == id); + if (!string.IsNullOrEmpty(title)) up.Set(a => a.Title, title); + var ret = await up.ExecuteUpdatedAsync(); + return ret.FirstOrDefault(); + } + + [HttpDelete("{id}"), ProducesResponseType(204)] + public Task Delete([FromRoute] int id) + { + return _songRepository.DeleteAsync(a => a.Id == id); + } + } } diff --git a/Examples/repository_01/Entitys/Song.cs b/Examples/repository_01/Entitys/Song.cs index 8c8a8a14..0ac4f16a 100644 --- a/Examples/repository_01/Entitys/Song.cs +++ b/Examples/repository_01/Entitys/Song.cs @@ -1,11 +1,13 @@ using FreeSql.DataAnnotations; using repository_01; -namespace restful.Entitys { - public class Song { +namespace restful.Entitys +{ + public class Song + { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Title { get; set; } - } + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + } } diff --git a/Examples/repository_01/Properties/launchSettings.json b/Examples/repository_01/Properties/launchSettings.json index 0426ce6f..e58a6fc7 100644 --- a/Examples/repository_01/Properties/launchSettings.json +++ b/Examples/repository_01/Properties/launchSettings.json @@ -1,27 +1,27 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:52751/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:52751/", + "sslPort": 0 + } }, - "repository_01": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:52752/" + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "repository_01": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:52752/" + } } - } } \ No newline at end of file diff --git a/Examples/repository_01/Startup.cs b/Examples/repository_01/Startup.cs index 07243127..24b5b025 100644 --- a/Examples/repository_01/Startup.cs +++ b/Examples/repository_01/Startup.cs @@ -13,86 +13,98 @@ using System.Diagnostics; using System.Linq; using System.Text; -namespace repository_01 { +namespace repository_01 +{ - /// - /// 用户密码信息 - /// - public class Sys1UserLogOn { - [Column(IsPrimary = true, Name = "Id")] - public Guid UserLogOnId { get; set; } - public virtual Sys1User User { get; set; } - } - public class Sys1User { - [Column(IsPrimary = true, Name = "Id")] - public Guid UserId { get; set; } - public virtual Sys1UserLogOn UserLogOn { get; set; } - } - - public class Startup { - public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) { - Configuration = configuration; + /// + /// 用户密码信息 + /// + public class Sys1UserLogOn + { + [Column(IsPrimary = true, Name = "Id")] + public Guid UserLogOnId { get; set; } + public virtual Sys1User User { get; set; } + } + public class Sys1User + { + [Column(IsPrimary = true, Name = "Id")] + public Guid UserId { get; set; } + public virtual Sys1UserLogOn UserLogOn { get; set; } + } - Fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) + public class Startup + { + public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) + { + Configuration = configuration; - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) - .Build(); + Fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) - var sysu = new Sys1User { }; - Fsql.Insert().AppendData(sysu).ExecuteAffrows(); - Fsql.Insert().AppendData(new Sys1UserLogOn { UserLogOnId = sysu.UserId }).ExecuteAffrows(); - var a = Fsql.Select().ToList(); - var b = Fsql.Select().Any(); - } + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .Build(); - public IConfiguration Configuration { get; } - public static IFreeSql Fsql { get; private set; } + var sysu = new Sys1User { }; + Fsql.Insert().AppendData(sysu).ExecuteAffrows(); + Fsql.Insert().AppendData(new Sys1UserLogOn { UserLogOnId = sysu.UserId }).ExecuteAffrows(); + var a = Fsql.Select().ToList(); + var b = Fsql.Select().Any(); + } - public void ConfigureServices(IServiceCollection services) { + public IConfiguration Configuration { get; } + public static IFreeSql Fsql { get; private set; } - //services.AddTransient(s => s.) + public void ConfigureServices(IServiceCollection services) + { - services.AddMvc(); - services.AddSwaggerGen(options => { - options.SwaggerDoc("v1", new Info { - Version = "v1", - Title = "FreeSql.RESTful API" - }); - //options.IncludeXmlComments(xmlPath); - }); + //services.AddTransient(s => s.) - services.AddSingleton(Fsql); + services.AddMvc(); + services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new Info + { + Version = "v1", + Title = "FreeSql.RESTful API" + }); + //options.IncludeXmlComments(xmlPath); + }); - services.AddFreeRepository(filter => { - filter - //.Apply("test", a => a.Title == DateTime.Now.ToString() + System.Threading.Thread.CurrentThread.ManagedThreadId) - .Apply("softdelete", a => a.IsDeleted == false); - }, this.GetType().Assembly); - } + services.AddSingleton(Fsql); - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - Console.OutputEncoding = Encoding.GetEncoding("GB2312"); - Console.InputEncoding = Encoding.GetEncoding("GB2312"); + services.AddFreeRepository(filter => + { + filter + //.Apply("test", a => a.Title == DateTime.Now.ToString() + System.Threading.Thread.CurrentThread.ManagedThreadId) + .Apply("softdelete", a => a.IsDeleted == false); + }, this.GetType().Assembly); + } - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Console.OutputEncoding = Encoding.GetEncoding("GB2312"); + Console.InputEncoding = Encoding.GetEncoding("GB2312"); - app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); - app.UseDeveloperExceptionPage(); - app.UseMvc(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); - app.UseSwagger(); - app.UseSwaggerUI(c => { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); - }); - } - } + app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); + app.UseDeveloperExceptionPage(); + app.UseMvc(); - public interface ISoftDelete { - bool IsDeleted { get; set; } - } + app.UseSwagger(); + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); + }); + } + } + + public interface ISoftDelete + { + bool IsDeleted { get; set; } + } } diff --git a/Examples/repository_01/appsettings.Development.json b/Examples/repository_01/appsettings.Development.json index 86f6b8f7..2d586cdf 100644 --- a/Examples/repository_01/appsettings.Development.json +++ b/Examples/repository_01/appsettings.Development.json @@ -1,9 +1,9 @@ { - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Warning", - "Microsoft": "Warning" - } - } + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Warning", + "Microsoft": "Warning" + } + } } diff --git a/Examples/repository_01/appsettings.json b/Examples/repository_01/appsettings.json index def9159a..6d451ac2 100644 --- a/Examples/repository_01/appsettings.json +++ b/Examples/repository_01/appsettings.json @@ -1,8 +1,8 @@ { - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" } diff --git a/Examples/restful/Controllers/SongController.cs b/Examples/restful/Controllers/SongController.cs index 8954e800..0cd631ae 100644 --- a/Examples/restful/Controllers/SongController.cs +++ b/Examples/restful/Controllers/SongController.cs @@ -4,56 +4,66 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace restful.Controllers { +namespace restful.Controllers +{ - [Route("restapi/[controller]")] - public class SongsController : Controller { + [Route("restapi/[controller]")] + public class SongsController : Controller + { - IFreeSql _fsql; + IFreeSql _fsql; - public SongsController(IFreeSql fsql) { - _fsql = fsql; - } + public SongsController(IFreeSql fsql) + { + _fsql = fsql; + } - [HttpGet] - public Task> GetItems([FromQuery] string key, [FromQuery] int page = 1, [FromQuery] int limit = 20) { - return _fsql.Select().WhereIf(!string.IsNullOrEmpty(key), a => a.Title.Contains(key)).Page(page, limit).ToListAsync(); - } + [HttpGet] + public Task> GetItems([FromQuery] string key, [FromQuery] int page = 1, [FromQuery] int limit = 20) + { + return _fsql.Select().WhereIf(!string.IsNullOrEmpty(key), a => a.Title.Contains(key)).Page(page, limit).ToListAsync(); + } - [HttpGet("{id}")] - public Task GetItem([FromRoute] int id) { - return _fsql.Select().Where(a => a.Id == id).ToOneAsync(); - } + [HttpGet("{id}")] + public Task GetItem([FromRoute] int id) + { + return _fsql.Select().Where(a => a.Id == id).ToOneAsync(); + } - public class ModelSong { - public string title { get; set; } - } + public class ModelSong + { + public string title { get; set; } + } - [HttpPost, ProducesResponseType(201)] - async public Task Create([FromBody] ModelSong model) { - var ret = await _fsql.Insert().AppendData(new Song { Title = model.title }).ExecuteInsertedAsync(); - return ret.FirstOrDefault(); - } + [HttpPost, ProducesResponseType(201)] + async public Task Create([FromBody] ModelSong model) + { + var ret = await _fsql.Insert().AppendData(new Song { Title = model.title }).ExecuteInsertedAsync(); + return ret.FirstOrDefault(); + } - [HttpPut("{id}")] - async public Task Update([FromRoute] int id, [FromBody] ModelSong model) { - var ret = await _fsql.Update().SetSource(new Song { Id = id, Title = model.title }).ExecuteUpdatedAsync(); - return ret.FirstOrDefault(); - } + [HttpPut("{id}")] + async public Task Update([FromRoute] int id, [FromBody] ModelSong model) + { + var ret = await _fsql.Update().SetSource(new Song { Id = id, Title = model.title }).ExecuteUpdatedAsync(); + return ret.FirstOrDefault(); + } - [HttpPatch("{id}")] - async public Task UpdateDiy([FromRoute] int id, [FromForm] string title) { - var up = _fsql.Update().Where(a => a.Id == id); - if (!string.IsNullOrEmpty(title)) up.Set(a => a.Title, title); - var ret = await up.ExecuteUpdatedAsync(); - return ret.FirstOrDefault(); - } + [HttpPatch("{id}")] + async public Task UpdateDiy([FromRoute] int id, [FromForm] string title) + { + var up = _fsql.Update().Where(a => a.Id == id); + if (!string.IsNullOrEmpty(title)) up.Set(a => a.Title, title); + var ret = await up.ExecuteUpdatedAsync(); + return ret.FirstOrDefault(); + } - [HttpDelete("{id}"), ProducesResponseType(204)] - async public Task Delete([FromRoute] int id) { - var ret = await _fsql.Delete().Where(a => a.Id == id).ExecuteDeletedAsync(); - return ret.FirstOrDefault(); - } - } + [HttpDelete("{id}"), ProducesResponseType(204)] + async public Task Delete([FromRoute] int id) + { + var ret = await _fsql.Delete().Where(a => a.Id == id).ExecuteDeletedAsync(); + return ret.FirstOrDefault(); + } + } } diff --git a/Examples/restful/Entitys/Song.cs b/Examples/restful/Entitys/Song.cs index f91f2505..3c85aae1 100644 --- a/Examples/restful/Entitys/Song.cs +++ b/Examples/restful/Entitys/Song.cs @@ -1,10 +1,12 @@ using FreeSql.DataAnnotations; -namespace restful.Entitys { - public class Song { +namespace restful.Entitys +{ + public class Song + { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Title { get; set; } - } + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + } } diff --git a/Examples/restful/Properties/launchSettings.json b/Examples/restful/Properties/launchSettings.json index 06b7366a..789f1c93 100644 --- a/Examples/restful/Properties/launchSettings.json +++ b/Examples/restful/Properties/launchSettings.json @@ -1,27 +1,27 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:49778/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:49778/", + "sslPort": 0 + } }, - "FreeSql.RESTful.Demo": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:49779/" + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "FreeSql.RESTful.Demo": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:49779/" + } } - } } \ No newline at end of file diff --git a/Examples/restful/Startup.cs b/Examples/restful/Startup.cs index 88b7777d..89e8977e 100644 --- a/Examples/restful/Startup.cs +++ b/Examples/restful/Startup.cs @@ -7,61 +7,71 @@ using Swashbuckle.AspNetCore.Swagger; using System; using System.Text; -namespace restful { - public class Startup { - public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) { - Configuration = configuration; +namespace restful +{ + public class Startup + { + public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) + { + Configuration = configuration; - Fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .Build(); + Fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .Build(); - Fsql.Aop.CurdAfter = (s, e) => { - if (e.ElapsedMilliseconds > 200) { - //记录日志 - //发送短信给负责人 - } - }; + Fsql.Aop.CurdAfter = (s, e) => + { + if (e.ElapsedMilliseconds > 200) + { + //记录日志 + //发送短信给负责人 + } + }; - //Fsql.Aop.Where = (s, e) => { - // if (e.Parameters[0]?.ToString() == "1") - // e.IsCancel = true; - //}; - } + //Fsql.Aop.Where = (s, e) => { + // if (e.Parameters[0]?.ToString() == "1") + // e.IsCancel = true; + //}; + } - public IConfiguration Configuration { get; } - public IFreeSql Fsql { get; } + public IConfiguration Configuration { get; } + public IFreeSql Fsql { get; } - public void ConfigureServices(IServiceCollection services) { - services.AddSingleton(Fsql); + public void ConfigureServices(IServiceCollection services) + { + services.AddSingleton(Fsql); - services.AddMvc(); - services.AddSwaggerGen(options => { - options.SwaggerDoc("v1", new Info { - Version = "v1", - Title = "FreeSql.RESTful API" - }); - //options.IncludeXmlComments(xmlPath); - }); - } + services.AddMvc(); + services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new Info + { + Version = "v1", + Title = "FreeSql.RESTful API" + }); + //options.IncludeXmlComments(xmlPath); + }); + } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - Console.OutputEncoding = Encoding.GetEncoding("GB2312"); - Console.InputEncoding = Encoding.GetEncoding("GB2312"); + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Console.OutputEncoding = Encoding.GetEncoding("GB2312"); + Console.InputEncoding = Encoding.GetEncoding("GB2312"); - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); - app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); - app.UseDeveloperExceptionPage(); - app.UseMvc(); + app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); + app.UseDeveloperExceptionPage(); + app.UseMvc(); - app.UseSwagger(); - app.UseSwaggerUI(c => { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); - }); - } - } + app.UseSwagger(); + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); + }); + } + } } diff --git a/Examples/restful/appsettings.Development.json b/Examples/restful/appsettings.Development.json index e203e940..6ba02f3f 100644 --- a/Examples/restful/appsettings.Development.json +++ b/Examples/restful/appsettings.Development.json @@ -1,9 +1,9 @@ { - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } } - } } diff --git a/Examples/restful/appsettings.json b/Examples/restful/appsettings.json index def9159a..6d451ac2 100644 --- a/Examples/restful/appsettings.json +++ b/Examples/restful/appsettings.json @@ -1,8 +1,8 @@ { - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" } diff --git a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs index 90ebbd32..dc388bf4 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs +++ b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs @@ -5,30 +5,34 @@ using System.Collections.Generic; using System.Reflection; using System.Text; -namespace FreeSql.Extensions.LazyLoading { +namespace FreeSql.Extensions.LazyLoading +{ - public class LazyLoadingComplier { + public class LazyLoadingComplier + { #if ns20 - internal static Lazy _compiler = new Lazy(() => { - //var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll"); - var compiler = new CSScriptLib.RoslynEvaluator(); - compiler.DisableReferencingFromCode = false; - //compiler.DebugBuild = true; - //foreach (var dll in dlls) { - // Console.WriteLine(dll); - // var ass = Assembly.LoadFile(dll); - // compiler.ReferenceAssembly(ass); - //} - compiler - .ReferenceAssemblyOf() - .ReferenceDomainAssemblies(); - return compiler; - }); + internal static Lazy _compiler = new Lazy(() => + { + //var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll"); + var compiler = new CSScriptLib.RoslynEvaluator(); + compiler.DisableReferencingFromCode = false; + //compiler.DebugBuild = true; + //foreach (var dll in dlls) { + // Console.WriteLine(dll); + // var ass = Assembly.LoadFile(dll); + // compiler.ReferenceAssembly(ass); + //} + compiler + .ReferenceAssemblyOf() + .ReferenceDomainAssemblies(); + return compiler; + }); - public static Assembly CompileCode(string cscode) { - return _compiler.Value.CompileCode(cscode); - } + public static Assembly CompileCode(string cscode) + { + return _compiler.Value.CompileCode(cscode); + } #else @@ -52,5 +56,5 @@ namespace FreeSql.Extensions.LazyLoading { } #endif - } + } } diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 90625e87..6c6867d7 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -5,150 +5,168 @@ using System.Linq; using System.Reflection; using System.Threading.Tasks; -namespace FreeSql { - public abstract partial class DbContext : IDisposable { +namespace FreeSql +{ + public abstract partial class DbContext : IDisposable + { - internal IFreeSql _orm; - internal IFreeSql _fsql => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); + internal IFreeSql _orm; + internal IFreeSql _fsql => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); - public IFreeSql Orm => _fsql; + public IFreeSql Orm => _fsql; - protected IUnitOfWork _uowPriv; - internal IUnitOfWork _uow => _isUseUnitOfWork ? (_uowPriv ?? (_uowPriv = new UnitOfWork(_fsql))) : null; - internal bool _isUseUnitOfWork = true; //不使用工作单元事务 + protected IUnitOfWork _uowPriv; + internal IUnitOfWork _uow => _isUseUnitOfWork ? (_uowPriv ?? (_uowPriv = new UnitOfWork(_fsql))) : null; + internal bool _isUseUnitOfWork = true; //不使用工作单元事务 - public IUnitOfWork UnitOfWork => _uow; + public IUnitOfWork UnitOfWork => _uow; - DbContextOptions _options; - internal DbContextOptions Options { - get { - if (_options != null) return _options; - if (FreeSqlDbContextExtenssions._dicSetDbContextOptions.TryGetValue(Orm, out _options)) return _options; - _options = new DbContextOptions(); - return _options; - } - } + DbContextOptions _options; + internal DbContextOptions Options + { + get + { + if (_options != null) return _options; + if (FreeSqlDbContextExtenssions._dicSetDbContextOptions.TryGetValue(Orm, out _options)) return _options; + _options = new DbContextOptions(); + return _options; + } + } - static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); - protected DbContext() { + static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); + protected DbContext() + { - var builder = new DbContextOptionsBuilder(); - OnConfiguring(builder); - _orm = builder._fsql; + var builder = new DbContextOptionsBuilder(); + OnConfiguring(builder); + _orm = builder._fsql; - if (_orm != null) InitPropSets(); - } + if (_orm != null) InitPropSets(); + } - internal void InitPropSets() { - var props = _dicGetDbSetProps.GetOrAdd(this.GetType(), tp => - tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) - .Where(a => a.PropertyType.IsGenericType && - a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GenericTypeArguments[0])).ToArray()); + internal void InitPropSets() + { + var props = _dicGetDbSetProps.GetOrAdd(this.GetType(), tp => + tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) + .Where(a => a.PropertyType.IsGenericType && + a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GenericTypeArguments[0])).ToArray()); - foreach (var prop in props) { - var set = this.Set(prop.PropertyType.GenericTypeArguments[0]); + foreach (var prop in props) + { + var set = this.Set(prop.PropertyType.GenericTypeArguments[0]); - prop.SetValue(this, set); - AllSets.Add(prop.Name, set); - } - } + prop.SetValue(this, set); + AllSets.Add(prop.Name, set); + } + } - protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { - - } + protected virtual void OnConfiguring(DbContextOptionsBuilder builder) + { - protected Dictionary _dicSet = new Dictionary(); - public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; - public virtual IDbSet Set(Type entityType) { - if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; - var sd = Activator.CreateInstance(typeof(DbContextDbSet<>).MakeGenericType(entityType), this) as IDbSet; - if (entityType != typeof(object)) _dicSet.Add(entityType, sd); - return sd; - } - protected Dictionary AllSets { get; } = new Dictionary(); + } - #region DbSet 快速代理 - /// - /// 添加 - /// - /// - /// - public void Add(TEntity data) where TEntity : class => this.Set().Add(data); - public void AddRange(IEnumerable data) where TEntity : class => this.Set().AddRange(data); - public Task AddAsync(TEntity data) where TEntity : class => this.Set().AddAsync(data); - public Task AddRangeAsync(IEnumerable data) where TEntity : class => this.Set().AddRangeAsync(data); + protected Dictionary _dicSet = new Dictionary(); + public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; + public virtual IDbSet Set(Type entityType) + { + if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; + var sd = Activator.CreateInstance(typeof(DbContextDbSet<>).MakeGenericType(entityType), this) as IDbSet; + if (entityType != typeof(object)) _dicSet.Add(entityType, sd); + return sd; + } + protected Dictionary AllSets { get; } = new Dictionary(); - /// - /// 更新 - /// - /// - /// - public void Update(TEntity data) where TEntity : class => this.Set().Update(data); - public void UpdateRange(IEnumerable data) where TEntity : class => this.Set().UpdateRange(data); - public Task UpdateAsync(TEntity data) where TEntity : class => this.Set().UpdateAsync(data); - public Task UpdateRangeAsync(IEnumerable data) where TEntity : class => this.Set().UpdateRangeAsync(data); + #region DbSet 快速代理 + /// + /// 添加 + /// + /// + /// + public void Add(TEntity data) where TEntity : class => this.Set().Add(data); + public void AddRange(IEnumerable data) where TEntity : class => this.Set().AddRange(data); + public Task AddAsync(TEntity data) where TEntity : class => this.Set().AddAsync(data); + public Task AddRangeAsync(IEnumerable data) where TEntity : class => this.Set().AddRangeAsync(data); - /// - /// 删除 - /// - /// - /// - public void Remove(TEntity data) where TEntity : class => this.Set().Remove(data); - public void RemoveRange(IEnumerable data) where TEntity : class => this.Set().RemoveRange(data); + /// + /// 更新 + /// + /// + /// + public void Update(TEntity data) where TEntity : class => this.Set().Update(data); + public void UpdateRange(IEnumerable data) where TEntity : class => this.Set().UpdateRange(data); + public Task UpdateAsync(TEntity data) where TEntity : class => this.Set().UpdateAsync(data); + public Task UpdateRangeAsync(IEnumerable data) where TEntity : class => this.Set().UpdateRangeAsync(data); - /// - /// 添加或更新 - /// - /// - /// - public void AddOrUpdate(TEntity data) where TEntity : class => this.Set().AddOrUpdate(data); - public Task AddOrUpdateAsync(TEntity data) where TEntity : class => this.Set().AddOrUpdateAsync(data); + /// + /// 删除 + /// + /// + /// + public void Remove(TEntity data) where TEntity : class => this.Set().Remove(data); + public void RemoveRange(IEnumerable data) where TEntity : class => this.Set().RemoveRange(data); - /// - /// 附加实体,可用于不查询就更新或删除 - /// - /// - /// - public void Attach(TEntity data) where TEntity : class => this.Set().Attach(data); - public void AttachRange(IEnumerable data) where TEntity : class => this.Set().AttachRange(data); - #endregion + /// + /// 添加或更新 + /// + /// + /// + public void AddOrUpdate(TEntity data) where TEntity : class => this.Set().AddOrUpdate(data); + public Task AddOrUpdateAsync(TEntity data) where TEntity : class => this.Set().AddOrUpdateAsync(data); - internal class ExecCommandInfo { - public ExecCommandInfoType actionType { get; set; } - public IDbSet dbSet { get; set; } - public Type stateType { get; set; } - public object state { get; set; } - } - internal enum ExecCommandInfoType { Insert, Update, Delete } - Queue _actions = new Queue(); - internal int _affrows = 0; + /// + /// 附加实体,可用于不查询就更新或删除 + /// + /// + /// + public void Attach(TEntity data) where TEntity : class => this.Set().Attach(data); + public void AttachRange(IEnumerable data) where TEntity : class => this.Set().AttachRange(data); + #endregion - internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, object state) { - _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); - } + internal class ExecCommandInfo + { + public ExecCommandInfoType actionType { get; set; } + public IDbSet dbSet { get; set; } + public Type stateType { get; set; } + public object state { get; set; } + } + internal enum ExecCommandInfoType { Insert, Update, Delete } + Queue _actions = new Queue(); + internal int _affrows = 0; - ~DbContext() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - _actions.Clear(); + internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, object state) + { + _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); + } - foreach (var set in _dicSet) - try { - set.Value.Dispose(); - } catch { } + ~DbContext() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + try + { + _actions.Clear(); - _dicSet.Clear(); - AllSets.Clear(); - - _uow?.Rollback(); - } finally { - _isdisposed = true; - GC.SuppressFinalize(this); - } - } - } + foreach (var set in _dicSet) + try + { + set.Value.Dispose(); + } + catch { } + + _dicSet.Clear(); + AllSets.Clear(); + + _uow?.Rollback(); + } + finally + { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + } } diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 269486f9..50deeacd 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -5,115 +5,133 @@ using System.Reflection; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - partial class DbContext { +namespace FreeSql +{ + partial class DbContext + { - async public virtual Task SaveChangesAsync() { - await ExecCommandAsync(); - _uow?.Commit(); - var ret = _affrows; - _affrows = 0; - return ret; - } + async public virtual Task SaveChangesAsync() + { + await ExecCommandAsync(); + _uow?.Commit(); + var ret = _affrows; + _affrows = 0; + return ret; + } - static Dictionary>>> _dicExecCommandDbContextBetchAsync = new Dictionary>>>(); - async internal Task ExecCommandAsync() { - if (isExecCommanding) return; - if (_actions.Any() == false) return; - isExecCommanding = true; + static Dictionary>>> _dicExecCommandDbContextBetchAsync = new Dictionary>>>(); + async internal Task ExecCommandAsync() + { + if (isExecCommanding) return; + if (_actions.Any() == false) return; + isExecCommanding = true; - ExecCommandInfo oldinfo = null; - var states = new List(); + ExecCommandInfo oldinfo = null; + var states = new List(); - Func> dbContextBetch = methodName => { - if (_dicExecCommandDbContextBetchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + Func> dbContextBetch = methodName => + { + if (_dicExecCommandDbContextBetchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false) + trydic = new Dictionary>>(); + if (trydic.TryGetValue(methodName, out var tryfunc) == false) + { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - var returnTarget = Expression.Label(typeof(Task)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(Task))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } - return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Func funcDelete = async () => { - _affrows += await dbContextBetch("DbContextBetchRemoveAsync"); - states.Clear(); - }; - Func funcInsert = async () => { - _affrows += await dbContextBetch("DbContextBetchAddAsync"); - states.Clear(); - }; - Func funcUpdate = async (isLiveUpdate) => { - var affrows = 0; - if (isLiveUpdate) affrows = await dbContextBetch("DbContextBetchUpdateNowAsync"); - else affrows = await dbContextBetch("DbContextBetchUpdateAsync"); - if (affrows == -999) { //最后一个元素已被删除 - states.RemoveAt(states.Count - 1); - return; - } - if (affrows == -998 || affrows == -997) { //没有执行更新 - var laststate = states[states.Count - 1]; - states.Clear(); - if (affrows == -997) states.Add(laststate); //保留最后一个 - } - if (affrows > 0) { - _affrows += affrows; - var islastNotUpdated = states.Count != affrows; - var laststate = states[states.Count - 1]; - states.Clear(); - if (islastNotUpdated) states.Add(laststate); //保留最后一个 - } - }; + var returnTarget = Expression.Label(typeof(Task)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + tryfunc = Expression.Lambda>>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(Task))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + trydic.Add(methodName, tryfunc); + } + return tryfunc(oldinfo.dbSet, states.ToArray()); + }; + Func funcDelete = async () => + { + _affrows += await dbContextBetch("DbContextBetchRemoveAsync"); + states.Clear(); + }; + Func funcInsert = async () => + { + _affrows += await dbContextBetch("DbContextBetchAddAsync"); + states.Clear(); + }; + Func funcUpdate = async (isLiveUpdate) => + { + var affrows = 0; + if (isLiveUpdate) affrows = await dbContextBetch("DbContextBetchUpdateNowAsync"); + else affrows = await dbContextBetch("DbContextBetchUpdateAsync"); + if (affrows == -999) + { //最后一个元素已被删除 + states.RemoveAt(states.Count - 1); + return; + } + if (affrows == -998 || affrows == -997) + { //没有执行更新 + var laststate = states[states.Count - 1]; + states.Clear(); + if (affrows == -997) states.Add(laststate); //保留最后一个 + } + if (affrows > 0) + { + _affrows += affrows; + var islastNotUpdated = states.Count != affrows; + var laststate = states[states.Count - 1]; + states.Clear(); + if (islastNotUpdated) states.Add(laststate); //保留最后一个 + } + }; - while (_actions.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; - if (oldinfo == null) oldinfo = info; - var isLiveUpdate = false; + while (_actions.Any() || states.Any()) + { + var info = _actions.Any() ? _actions.Dequeue() : null; + if (oldinfo == null) oldinfo = info; + var isLiveUpdate = false; - if (_actions.Any() == false && states.Any() || - info != null && oldinfo.actionType != info.actionType || - info != null && oldinfo.stateType != info.stateType) { + if (_actions.Any() == false && states.Any() || + info != null && oldinfo.actionType != info.actionType || + info != null && oldinfo.stateType != info.stateType) + { - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { - //最后一个,合起来发送 - states.Add(info.state); - info = null; - } + if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) + { + //最后一个,合起来发送 + states.Add(info.state); + info = null; + } - switch (oldinfo.actionType) { - case ExecCommandInfoType.Insert: - await funcInsert(); - break; - case ExecCommandInfoType.Delete: - await funcDelete(); - break; - } - isLiveUpdate = true; - } + switch (oldinfo.actionType) + { + case ExecCommandInfoType.Insert: + await funcInsert(); + break; + case ExecCommandInfoType.Delete: + await funcDelete(); + break; + } + isLiveUpdate = true; + } - if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { - if (states.Any()) - await funcUpdate(isLiveUpdate); - } + if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) + { + if (states.Any()) + await funcUpdate(isLiveUpdate); + } - if (info != null) { - states.Add(info.state); - oldinfo = info; - } - } - isExecCommanding = false; - } - } + if (info != null) + { + states.Add(info.state); + oldinfo = info; + } + } + isExecCommanding = false; + } + } } diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index 47095091..9ff21d0c 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -1,10 +1,12 @@  -namespace FreeSql { - public class DbContextOptions { +namespace FreeSql +{ + public class DbContextOptions + { - /// - /// 是否开启一对多,联级保存功能 - /// - public bool EnableAddOrUpdateNavigateList { get; set; } = true; - } + /// + /// 是否开启一对多,联级保存功能 + /// + public bool EnableAddOrUpdateNavigateList { get; set; } = true; + } } diff --git a/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs b/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs index a003f65d..0801cfe2 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs @@ -1,13 +1,16 @@  -namespace FreeSql { - public class DbContextOptionsBuilder { +namespace FreeSql +{ + public class DbContextOptionsBuilder + { - internal IFreeSql _fsql; + internal IFreeSql _fsql; - public DbContextOptionsBuilder UseFreeSql(IFreeSql orm) { - _fsql = orm; - return this; - } - } + public DbContextOptionsBuilder UseFreeSql(IFreeSql orm) + { + _fsql = orm; + return this; + } + } } diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs index 6eec203b..65a00f16 100644 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -4,116 +4,134 @@ using System.Linq; using System.Reflection; using System.Linq.Expressions; -namespace FreeSql { - partial class DbContext { +namespace FreeSql +{ + partial class DbContext + { - public virtual int SaveChanges() { - ExecCommand(); - _uow?.Commit(); - var ret = _affrows; - _affrows = 0; - return ret; - } + public virtual int SaveChanges() + { + ExecCommand(); + _uow?.Commit(); + var ret = _affrows; + _affrows = 0; + return ret; + } - static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); - bool isExecCommanding = false; - internal void ExecCommand() { - if (isExecCommanding) return; - if (_actions.Any() == false) return; - isExecCommanding = true; + static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); + bool isExecCommanding = false; + internal void ExecCommand() + { + if (isExecCommanding) return; + if (_actions.Any() == false) return; + isExecCommanding = true; - ExecCommandInfo oldinfo = null; - var states = new List(); + ExecCommandInfo oldinfo = null; + var states = new List(); - Func dbContextBetch = methodName => { - if (_dicExecCommandDbContextBetch.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + Func dbContextBetch = methodName => + { + if (_dicExecCommandDbContextBetch.TryGetValue(oldinfo.stateType, out var trydic) == false) + trydic = new Dictionary>(); + if (trydic.TryGetValue(methodName, out var tryfunc) == false) + { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - var returnTarget = Expression.Label(typeof(int)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(int))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } - return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Action funcDelete = () => { - _affrows += dbContextBetch("DbContextBetchRemove"); - states.Clear(); - }; - Action funcInsert = () => { - _affrows += dbContextBetch("DbContextBetchAdd"); - states.Clear(); - }; - Action funcUpdate = isLiveUpdate => { - var affrows = 0; - if (isLiveUpdate) affrows = dbContextBetch("DbContextBetchUpdateNow"); - else affrows = dbContextBetch("DbContextBetchUpdate"); - if (affrows == -999) { //最后一个元素已被删除 - states.RemoveAt(states.Count - 1); - return; - } - if (affrows == -998 || affrows == -997) { //没有执行更新 - var laststate = states[states.Count - 1]; - states.Clear(); - if (affrows == -997) states.Add(laststate); //保留最后一个 - } - if (affrows > 0) { - _affrows += affrows; - var islastNotUpdated = states.Count != affrows; - var laststate = states[states.Count - 1]; - states.Clear(); - if (islastNotUpdated) states.Add(laststate); //保留最后一个 - } - }; + var returnTarget = Expression.Label(typeof(int)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + tryfunc = Expression.Lambda>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(int))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + trydic.Add(methodName, tryfunc); + } + return tryfunc(oldinfo.dbSet, states.ToArray()); + }; + Action funcDelete = () => + { + _affrows += dbContextBetch("DbContextBetchRemove"); + states.Clear(); + }; + Action funcInsert = () => + { + _affrows += dbContextBetch("DbContextBetchAdd"); + states.Clear(); + }; + Action funcUpdate = isLiveUpdate => + { + var affrows = 0; + if (isLiveUpdate) affrows = dbContextBetch("DbContextBetchUpdateNow"); + else affrows = dbContextBetch("DbContextBetchUpdate"); + if (affrows == -999) + { //最后一个元素已被删除 + states.RemoveAt(states.Count - 1); + return; + } + if (affrows == -998 || affrows == -997) + { //没有执行更新 + var laststate = states[states.Count - 1]; + states.Clear(); + if (affrows == -997) states.Add(laststate); //保留最后一个 + } + if (affrows > 0) + { + _affrows += affrows; + var islastNotUpdated = states.Count != affrows; + var laststate = states[states.Count - 1]; + states.Clear(); + if (islastNotUpdated) states.Add(laststate); //保留最后一个 + } + }; - while (_actions.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; - if (oldinfo == null) oldinfo = info; - var isLiveUpdate = false; + while (_actions.Any() || states.Any()) + { + var info = _actions.Any() ? _actions.Dequeue() : null; + if (oldinfo == null) oldinfo = info; + var isLiveUpdate = false; - if (_actions.Any() == false && states.Any() || - info != null && oldinfo.actionType != info.actionType || - info != null && oldinfo.stateType != info.stateType) { + if (_actions.Any() == false && states.Any() || + info != null && oldinfo.actionType != info.actionType || + info != null && oldinfo.stateType != info.stateType) + { - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { - //最后一个,合起来发送 - states.Add(info.state); - info = null; - } + if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) + { + //最后一个,合起来发送 + states.Add(info.state); + info = null; + } - switch (oldinfo.actionType) { - case ExecCommandInfoType.Insert: - funcInsert(); - break; - case ExecCommandInfoType.Delete: - funcDelete(); - break; - } - isLiveUpdate = true; - } + switch (oldinfo.actionType) + { + case ExecCommandInfoType.Insert: + funcInsert(); + break; + case ExecCommandInfoType.Delete: + funcDelete(); + break; + } + isLiveUpdate = true; + } - if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { - if (states.Any()) - funcUpdate(isLiveUpdate); - } + if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) + { + if (states.Any()) + funcUpdate(isLiveUpdate); + } - if (info != null) { - states.Add(info.state); - oldinfo = info; - } - } - isExecCommanding = false; - } - } + if (info != null) + { + states.Add(info.state); + oldinfo = info; + } + } + isExecCommanding = false; + } + } } diff --git a/FreeSql.DbContext/DbContext/FreeContext.cs b/FreeSql.DbContext/DbContext/FreeContext.cs index a6b0549d..38e23bc0 100644 --- a/FreeSql.DbContext/DbContext/FreeContext.cs +++ b/FreeSql.DbContext/DbContext/FreeContext.cs @@ -1,10 +1,13 @@  -namespace FreeSql { - public class FreeContext : DbContext { +namespace FreeSql +{ + public class FreeContext : DbContext + { - public FreeContext(IFreeSql orm) { - _orm = orm; - } - } + public FreeContext(IFreeSql orm) + { + _orm = orm; + } + } } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index b115f424..dbac00d5 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -8,274 +8,326 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; -namespace FreeSql { +namespace FreeSql +{ - internal class DbContextDbSet : DbSet where TEntity : class { + internal class DbContextDbSet : DbSet where TEntity : class + { - public DbContextDbSet(DbContext ctx) { - _ctx = ctx; - _uow = ctx._uow; - _fsql = ctx._fsql; - } - } + public DbContextDbSet(DbContext ctx) + { + _ctx = ctx; + _uow = ctx._uow; + _fsql = ctx._fsql; + } + } - public interface IDbSet : IDisposable { - Type EntityType { get; } - } - public abstract partial class DbSet : IDbSet where TEntity : class { + public interface IDbSet : IDisposable + { + Type EntityType { get; } + } + public abstract partial class DbSet : IDbSet where TEntity : class + { - internal DbContext _ctx; - internal IUnitOfWork _uow; - internal IFreeSql _fsql; + internal DbContext _ctx; + internal IUnitOfWork _uow; + internal IFreeSql _fsql; - protected virtual ISelect OrmSelect(object dywhere) { - DbContextExecCommand(); //查询前先提交,否则会出脏读 - return _fsql.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); - } + protected virtual ISelect OrmSelect(object dywhere) + { + DbContextExecCommand(); //查询前先提交,否则会出脏读 + return _fsql.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); + } - ~DbSet() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - this._dicUpdateTimes.Clear(); - this._states.Clear(); - } finally { - _isdisposed = true; - GC.SuppressFinalize(this); - } - } + ~DbSet() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + try + { + this._dicUpdateTimes.Clear(); + this._states.Clear(); + } + finally + { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } - protected virtual IInsert OrmInsert() => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); - protected virtual IInsert OrmInsert(TEntity data) => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); - protected virtual IInsert OrmInsert(IEnumerable data) => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); + protected virtual IInsert OrmInsert() => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); + protected virtual IInsert OrmInsert(TEntity data) => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); + protected virtual IInsert OrmInsert(IEnumerable data) => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); - protected virtual IUpdate OrmUpdate(IEnumerable entitys) => _fsql.Update().AsType(_entityType).SetSource(entitys).WithTransaction(_uow?.GetOrBeginTransaction()); - protected virtual IDelete OrmDelete(object dywhere) => _fsql.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); + protected virtual IUpdate OrmUpdate(IEnumerable entitys) => _fsql.Update().AsType(_entityType).SetSource(entitys).WithTransaction(_uow?.GetOrBeginTransaction()); + protected virtual IDelete OrmDelete(object dywhere) => _fsql.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); - internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) { - _ctx.EnqueueAction(actionType, this, typeof(EntityState), state); - } - internal void IncrAffrows(int affrows) { - _ctx._affrows += affrows; - } + internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) + { + _ctx.EnqueueAction(actionType, this, typeof(EntityState), state); + } + internal void IncrAffrows(int affrows) + { + _ctx._affrows += affrows; + } - internal void TrackToList(object list) { - if (list == null) return; - var ls = list as IList; - if (ls == null) { - var ie = list as IEnumerable; - if (ie == null) return; - foreach (var item in ie) { - if (item == null) return; - var itemType = item.GetType(); - if (itemType == typeof(object)) return; - if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; - var dbset = _ctx.Set(itemType); - dbset?.GetType().GetMethod("TrackToList", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dbset, new object[] { list }); - return; - } - return; - } + internal void TrackToList(object list) + { + if (list == null) return; + var ls = list as IList; + if (ls == null) + { + var ie = list as IEnumerable; + if (ie == null) return; + foreach (var item in ie) + { + if (item == null) return; + var itemType = item.GetType(); + if (itemType == typeof(object)) return; + if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + var dbset = _ctx.Set(itemType); + dbset?.GetType().GetMethod("TrackToList", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dbset, new object[] { list }); + return; + } + return; + } - foreach (var item in ls) { - var key = _fsql.GetEntityKeyString(_entityType, item, false); - if (key == null) continue; - _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { - _fsql.MapEntityValue(_entityType, item, ov.Value); - ov.Time = DateTime.Now; - return ov; - }); - } - } + foreach (var item in ls) + { + var key = _fsql.GetEntityKeyString(_entityType, item, false); + if (key == null) continue; + _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => + { + _fsql.MapEntityValue(_entityType, item, ov.Value); + ov.Time = DateTime.Now; + return ov; + }); + } + } - public ISelect Select => this.OrmSelect(null); - public ISelect Where(Expression> exp) => this.OrmSelect(null).Where(exp); - public ISelect WhereIf(bool condition, Expression> exp) => this.OrmSelect(null).WhereIf(condition, exp); + public ISelect Select => this.OrmSelect(null); + public ISelect Where(Expression> exp) => this.OrmSelect(null).Where(exp); + public ISelect WhereIf(bool condition, Expression> exp) => this.OrmSelect(null).WhereIf(condition, exp); - protected ConcurrentDictionary _states = new ConcurrentDictionary(); - internal ConcurrentDictionary _statesInternal => _states; - TableInfo _tablePriv; - protected TableInfo _table => _tablePriv ?? (_tablePriv = _fsql.CodeFirst.GetTableByEntity(_entityType)); - ColumnInfo[] _tableIdentitysPriv; - protected ColumnInfo[] _tableIdentitys => _tableIdentitysPriv ?? (_tableIdentitysPriv = _table.Primarys.Where(a => a.Attribute.IsIdentity).ToArray()); - protected Type _entityType = typeof(TEntity); - public Type EntityType => _entityType; + protected ConcurrentDictionary _states = new ConcurrentDictionary(); + internal ConcurrentDictionary _statesInternal => _states; + TableInfo _tablePriv; + protected TableInfo _table => _tablePriv ?? (_tablePriv = _fsql.CodeFirst.GetTableByEntity(_entityType)); + ColumnInfo[] _tableIdentitysPriv; + protected ColumnInfo[] _tableIdentitys => _tableIdentitysPriv ?? (_tableIdentitysPriv = _table.Primarys.Where(a => a.Attribute.IsIdentity).ToArray()); + protected Type _entityType = typeof(TEntity); + public Type EntityType => _entityType; - /// - /// 动态Type,在使用 DbSet<object> 后使用本方法,指定实体类型 - /// - /// - /// - public void AsType(Type entityType) { - if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); - if (entityType == _entityType) return; - var newtb = _fsql.CodeFirst.GetTableByEntity(entityType); - _entityType = entityType; - _tablePriv = newtb ?? throw new Exception("DbSet.AsType 参数错误,请传入正确的实体类型"); - _tableIdentitysPriv = null; - } + /// + /// 动态Type,在使用 DbSet<object> 后使用本方法,指定实体类型 + /// + /// + /// + public void AsType(Type entityType) + { + if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); + if (entityType == _entityType) return; + var newtb = _fsql.CodeFirst.GetTableByEntity(entityType); + _entityType = entityType; + _tablePriv = newtb ?? throw new Exception("DbSet.AsType 参数错误,请传入正确的实体类型"); + _tableIdentitysPriv = null; + } - public class EntityState { - public EntityState(TEntity value, string key) { - this.Value = value; - this.Key = key; - this.Time = DateTime.Now; - } - public TEntity OldValue { get; set; } - public TEntity Value { get; set; } - public string Key { get; set; } - public DateTime Time { get; set; } - } - /// - /// 附加实体,可用于不查询就更新或删除 - /// - /// - public void Attach(TEntity data) => AttachRange(new[] { data }); - public void AttachRange(IEnumerable data) { - if (data == null || data.Any() == false) return; - if (_table.Primarys.Any() == false) throw new Exception($"不可附加,实体没有主键:{_fsql.GetEntityString(_entityType, data.First())}"); - foreach (var item in data) { - var key = _fsql.GetEntityKeyString(_entityType, item, false); - if (string.IsNullOrEmpty(key)) throw new Exception($"不可附加,未设置主键的值:{_fsql.GetEntityString(_entityType, item)}"); + public class EntityState + { + public EntityState(TEntity value, string key) + { + this.Value = value; + this.Key = key; + this.Time = DateTime.Now; + } + public TEntity OldValue { get; set; } + public TEntity Value { get; set; } + public string Key { get; set; } + public DateTime Time { get; set; } + } + /// + /// 附加实体,可用于不查询就更新或删除 + /// + /// + public void Attach(TEntity data) => AttachRange(new[] { data }); + public void AttachRange(IEnumerable data) + { + if (data == null || data.Any() == false) return; + if (_table.Primarys.Any() == false) throw new Exception($"不可附加,实体没有主键:{_fsql.GetEntityString(_entityType, data.First())}"); + foreach (var item in data) + { + var key = _fsql.GetEntityKeyString(_entityType, item, false); + if (string.IsNullOrEmpty(key)) throw new Exception($"不可附加,未设置主键的值:{_fsql.GetEntityString(_entityType, item)}"); - _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { - _fsql.MapEntityValue(_entityType, item, ov.Value); - ov.Time = DateTime.Now; - return ov; - }); - } - } - /// - /// 清空状态数据 - /// - public void FlushState() { - _states.Clear(); - } + _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => + { + _fsql.MapEntityValue(_entityType, item, ov.Value); + ov.Time = DateTime.Now; + return ov; + }); + } + } + /// + /// 清空状态数据 + /// + public void FlushState() + { + _states.Clear(); + } - #region Utils - EntityState CreateEntityState(TEntity data) { - if (data == null) throw new ArgumentNullException(nameof(data)); - var key = _fsql.GetEntityKeyString(_entityType, data, false); - var state = new EntityState((TEntity)Activator.CreateInstance(_entityType), key); - _fsql.MapEntityValue(_entityType, data, state.Value); - return state; - } - bool? ExistsInStates(TEntity data) { - if (data == null) throw new ArgumentNullException(nameof(data)); - var key = _fsql.GetEntityKeyString(_entityType, data, false); - if (string.IsNullOrEmpty(key)) return null; - return _states.ContainsKey(key); - } + #region Utils + EntityState CreateEntityState(TEntity data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + var key = _fsql.GetEntityKeyString(_entityType, data, false); + var state = new EntityState((TEntity)Activator.CreateInstance(_entityType), key); + _fsql.MapEntityValue(_entityType, data, state.Value); + return state; + } + bool? ExistsInStates(TEntity data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + var key = _fsql.GetEntityKeyString(_entityType, data, false); + if (string.IsNullOrEmpty(key)) return null; + return _states.ContainsKey(key); + } - bool CanAdd(IEnumerable data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - if (data.Any() == false) return false; - foreach (var s in data) if (CanAdd(s, isThrow) == false) return false; - return true; - } - bool CanAdd(TEntity data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - var key = _fsql.GetEntityKeyString(_entityType, data, true); - if (string.IsNullOrEmpty(key)) { - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - return true; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - return true; - } - if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - } else { - if (_states.ContainsKey(key)) { - if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - var idval = _fsql.GetEntityIdentityValueWithPrimary(_entityType, data); - if (idval > 0) { - if (isThrow) throw new Exception($"不可添加,自增属性有值:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - } - return true; - } + bool CanAdd(IEnumerable data, bool isThrow) + { + if (data == null) + { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (data.Any() == false) return false; + foreach (var s in data) if (CanAdd(s, isThrow) == false) return false; + return true; + } + bool CanAdd(TEntity data, bool isThrow) + { + if (data == null) + { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (_table.Primarys.Any() == false) + { + if (isThrow) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + var key = _fsql.GetEntityKeyString(_entityType, data, true); + if (string.IsNullOrEmpty(key)) + { + switch (_fsql.Ado.DataType) + { + case DataType.SqlServer: + case DataType.PostgreSQL: + return true; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) + { + return true; + } + if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + } + else + { + if (_states.ContainsKey(key)) + { + if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + var idval = _fsql.GetEntityIdentityValueWithPrimary(_entityType, data); + if (idval > 0) + { + if (isThrow) throw new Exception($"不可添加,自增属性有值:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + } + return true; + } - bool CanUpdate(IEnumerable data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - if (data.Any() == false) return false; - foreach (var s in data) if (CanUpdate(s, isThrow) == false) return false; - return true; - } - bool CanUpdate(TEntity data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可更新,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - var key = _fsql.GetEntityKeyString(_entityType, data, false); - if (string.IsNullOrEmpty(key)) { - if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - if (_states.TryGetValue(key, out var tryval) == false) { - if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询 或者 Attach:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - return true; - } + bool CanUpdate(IEnumerable data, bool isThrow) + { + if (data == null) + { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (data.Any() == false) return false; + foreach (var s in data) if (CanUpdate(s, isThrow) == false) return false; + return true; + } + bool CanUpdate(TEntity data, bool isThrow) + { + if (data == null) + { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (_table.Primarys.Any() == false) + { + if (isThrow) throw new Exception($"不可更新,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + var key = _fsql.GetEntityKeyString(_entityType, data, false); + if (string.IsNullOrEmpty(key)) + { + if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + if (_states.TryGetValue(key, out var tryval) == false) + { + if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询 或者 Attach:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + return true; + } - bool CanRemove(IEnumerable data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - if (data.Any() == false) return false; - foreach (var s in data) if (CanRemove(s, isThrow) == false) return false; - return true; - } - bool CanRemove(TEntity data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可删除,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - var key = _fsql.GetEntityKeyString(_entityType, data, false); - if (string.IsNullOrEmpty(key)) { - if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); - return false; - } - //if (_states.TryGetValue(key, out var tryval) == false) { - // if (isThrow) throw new Exception($"不可删除,数据未被跟踪,应该先查询:{_fsql.GetEntityString(_entityType, data)}"); - // return false; - //} - return true; - } - #endregion - } + bool CanRemove(IEnumerable data, bool isThrow) + { + if (data == null) + { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (data.Any() == false) return false; + foreach (var s in data) if (CanRemove(s, isThrow) == false) return false; + return true; + } + bool CanRemove(TEntity data, bool isThrow) + { + if (data == null) + { + if (isThrow) throw new ArgumentNullException(nameof(data)); + return false; + } + if (_table.Primarys.Any() == false) + { + if (isThrow) throw new Exception($"不可删除,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + var key = _fsql.GetEntityKeyString(_entityType, data, false); + if (string.IsNullOrEmpty(key)) + { + if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + return false; + } + //if (_states.TryGetValue(key, out var tryval) == false) { + // if (isThrow) throw new Exception($"不可删除,数据未被跟踪,应该先查询:{_fsql.GetEntityString(_entityType, data)}"); + // return false; + //} + return true; + } + #endregion + } } diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 2b5978f9..309046c8 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -6,263 +6,303 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace FreeSql { - partial class DbSet { +namespace FreeSql +{ + partial class DbSet + { - Task DbContextExecCommandAsync() { - _dicUpdateTimes.Clear(); - return _ctx.ExecCommandAsync(); - } + Task DbContextExecCommandAsync() + { + _dicUpdateTimes.Clear(); + return _ctx.ExecCommandAsync(); + } - async Task DbContextBetchAddAsync(EntityState[] adds) { - if (adds.Any() == false) return 0; - var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(); - return affrows; - } + async Task DbContextBetchAddAsync(EntityState[] adds) + { + if (adds.Any() == false) return 0; + var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(); + return affrows; + } - #region Add - async Task AddPrivAsync(TEntity data, bool isCheck) { - if (isCheck && CanAdd(data, true) == false) return; - if (_tableIdentitys.Length > 0) { - //有自增,马上执行 - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - await DbContextExecCommandAsync(); - var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); - IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); - Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data); - } else { - await DbContextExecCommandAsync(); - var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); - IncrAffrows(1); - _fsql.MapEntityValue(_entityType, newval, data); - Attach(newval); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data); - } - return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - await DbContextExecCommandAsync(); - var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); - IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); - Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data); - } - return; - } - } - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); - Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data); - } - public Task AddAsync(TEntity data) => AddPrivAsync(data, true); - async public Task AddRangeAsync(IEnumerable data) { - if (CanAdd(data, true) == false) return; - if (data.ElementAtOrDefault(1) == default(TEntity)) { - await AddAsync(data.First()); - return; - } - if (_tableIdentitys.Length > 0) { - //有自增,马上执行 - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - await DbContextExecCommandAsync(); - var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); - if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); - var idx = 0; - foreach (var s in data) - _fsql.MapEntityValue(_entityType, rets[idx++], s); - IncrAffrows(rets.Count); - AttachRange(rets); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - foreach (var item in data) - await AddOrUpdateNavigateListAsync(item); - return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - foreach (var s in data) - await AddPrivAsync(s, false); - return; - } - } else { - //进入队列,等待 SaveChanges 时执行 - foreach (var item in data) - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); - AttachRange(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - foreach (var item in data) - await AddOrUpdateNavigateListAsync(item); - } - } - async Task AddOrUpdateNavigateListAsync(TEntity item) { - Type itemType = null; - foreach (var prop in _table.Properties) { - if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; - if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; - var tref = _table.GetTableRef(prop.Key, true); - if (tref == null) continue; + #region Add + async Task AddPrivAsync(TEntity data, bool isCheck) + { + if (isCheck && CanAdd(data, true) == false) return; + if (_tableIdentitys.Length > 0) + { + //有自增,马上执行 + switch (_fsql.Ado.DataType) + { + case DataType.SqlServer: + case DataType.PostgreSQL: + if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) + { + await DbContextExecCommandAsync(); + var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); + IncrAffrows(1); + _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + await AddOrUpdateNavigateListAsync(data); + } + else + { + await DbContextExecCommandAsync(); + var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); + IncrAffrows(1); + _fsql.MapEntityValue(_entityType, newval, data); + Attach(newval); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + await AddOrUpdateNavigateListAsync(data); + } + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) + { + await DbContextExecCommandAsync(); + var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); + IncrAffrows(1); + _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + await AddOrUpdateNavigateListAsync(data); + } + return; + } + } + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + await AddOrUpdateNavigateListAsync(data); + } + public Task AddAsync(TEntity data) => AddPrivAsync(data, true); + async public Task AddRangeAsync(IEnumerable data) + { + if (CanAdd(data, true) == false) return; + if (data.ElementAtOrDefault(1) == default(TEntity)) + { + await AddAsync(data.First()); + return; + } + if (_tableIdentitys.Length > 0) + { + //有自增,马上执行 + switch (_fsql.Ado.DataType) + { + case DataType.SqlServer: + case DataType.PostgreSQL: + await DbContextExecCommandAsync(); + var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); + var idx = 0; + foreach (var s in data) + _fsql.MapEntityValue(_entityType, rets[idx++], s); + IncrAffrows(rets.Count); + AttachRange(rets); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + await AddOrUpdateNavigateListAsync(item); + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + foreach (var s in data) + await AddPrivAsync(s, false); + return; + } + } + else + { + //进入队列,等待 SaveChanges 时执行 + foreach (var item in data) + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); + AttachRange(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + await AddOrUpdateNavigateListAsync(item); + } + } + async Task AddOrUpdateNavigateListAsync(TEntity item) + { + Type itemType = null; + foreach (var prop in _table.Properties) + { + if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; + if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; + var tref = _table.GetTableRef(prop.Key, true); + if (tref == null) continue; - switch (tref.RefType) { - case Internal.Model.TableRefType.OneToOne: - case Internal.Model.TableRefType.ManyToOne: - case Internal.Model.TableRefType.ManyToMany: - continue; - case Internal.Model.TableRefType.OneToMany: - if (itemType == null) itemType = item.GetType(); - if (_table.TypeLazy != null && itemType == _table.TypeLazy) { - var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => - _table.TypeLazy.GetField($"__lazy__{propName}", System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); - if (lazyField != null) { - var lazyFieldValue = (bool)lazyField.GetValue(item); - if (lazyFieldValue == false) continue; - } - } - var propVal = prop.Value.GetValue(item); - var propValEach = propVal as IEnumerable; - if (propValEach == null) continue; - object dbset = null; - System.Reflection.MethodInfo dbsetAddOrUpdate = null; - foreach (var propValItem in propValEach) { - if (dbset == null) { - dbset = _ctx.Set(tref.RefEntityType); - dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdateAsync", new Type[] { tref.RefEntityType }); - } - for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { - tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName] - .SetValue(propValItem, tref.Columns[colidx].Table.Properties[tref.Columns[colidx].CsName].GetValue(item)); - } - Task task = dbsetAddOrUpdate.Invoke(dbset, new object[] { propValItem }) as Task; - await task; - } - break; - } - } - } - #endregion + switch (tref.RefType) + { + case Internal.Model.TableRefType.OneToOne: + case Internal.Model.TableRefType.ManyToOne: + case Internal.Model.TableRefType.ManyToMany: + continue; + case Internal.Model.TableRefType.OneToMany: + if (itemType == null) itemType = item.GetType(); + if (_table.TypeLazy != null && itemType == _table.TypeLazy) + { + var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => + _table.TypeLazy.GetField($"__lazy__{propName}", System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); + if (lazyField != null) + { + var lazyFieldValue = (bool)lazyField.GetValue(item); + if (lazyFieldValue == false) continue; + } + } + var propVal = prop.Value.GetValue(item); + var propValEach = propVal as IEnumerable; + if (propValEach == null) continue; + object dbset = null; + System.Reflection.MethodInfo dbsetAddOrUpdate = null; + foreach (var propValItem in propValEach) + { + if (dbset == null) + { + dbset = _ctx.Set(tref.RefEntityType); + dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdateAsync", new Type[] { tref.RefEntityType }); + } + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) + { + tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName] + .SetValue(propValItem, tref.Columns[colidx].Table.Properties[tref.Columns[colidx].CsName].GetValue(item)); + } + Task task = dbsetAddOrUpdate.Invoke(dbset, new object[] { propValItem }) as Task; + await task; + } + break; + } + } + } + #endregion - #region UpdateAsync - Task DbContextBetchUpdateAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, false); - Task DbContextBetchUpdateNowAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, true); - async Task DbContextBetchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate) { - if (ups.Any() == false) return 0; - var uplst1 = ups[ups.Length - 1]; - var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; + #region UpdateAsync + Task DbContextBetchUpdateAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, false); + Task DbContextBetchUpdateNowAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, true); + async Task DbContextBetchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate) + { + if (ups.Any() == false) return 0; + var uplst1 = ups[ups.Length - 1]; + var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; - if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; - var lstval2 = default(EntityState); - if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(_entityType, uplst2.Value)}"); + if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; + var lstval2 = default(EntityState); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(_entityType, uplst2.Value)}"); - var cuig1 = _fsql.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; + var cuig1 = _fsql.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; - List data = null; - string[] cuig = null; - if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { - //最后一个不保存 - data = ups.ToList(); - data.RemoveAt(ups.Length - 1); - cuig = cuig2; - } else if (isLiveUpdate) { - //立即保存 - data = ups.ToList(); - cuig = cuig1; - } + List data = null; + string[] cuig = null; + if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) + { + //最后一个不保存 + data = ups.ToList(); + data.RemoveAt(ups.Length - 1); + cuig = cuig2; + } + else if (isLiveUpdate) + { + //立即保存 + data = ups.ToList(); + cuig = cuig1; + } - if (data?.Count > 0) { + if (data?.Count > 0) + { - if (cuig.Length == _table.Columns.Count) - return ups.Length == data.Count ? -998 : -997; + if (cuig.Length == _table.Columns.Count) + return ups.Length == data.Count ? -998 : -997; - var updateSource = data.Select(a => a.Value).ToArray(); - var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); + var updateSource = data.Select(a => a.Value).ToArray(); + var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); - var affrows = await update.ExecuteAffrowsAsync(); + var affrows = await update.ExecuteAffrowsAsync(); - foreach (var newval in data) { - if (_states.TryGetValue(newval.Key, out var tryold)) - _fsql.MapEntityValue(_entityType, newval.Value, tryold.Value); - if (newval.OldValue != null) - _fsql.MapEntityValue(_entityType, newval.Value, newval.OldValue); - } - return affrows; - } + foreach (var newval in data) + { + if (_states.TryGetValue(newval.Key, out var tryold)) + _fsql.MapEntityValue(_entityType, newval.Value, tryold.Value); + if (newval.OldValue != null) + _fsql.MapEntityValue(_entityType, newval.Value, newval.OldValue); + } + return affrows; + } - //等待下次对比再保存 - return 0; - } - async public Task UpdateAsync(TEntity data) { - var exists = ExistsInStates(data); - if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); - if (exists == false) { - var olddata = await OrmSelect(data).FirstAsync(); - if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_fsql.GetEntityString(_entityType, data)}"); - } + //等待下次对比再保存 + return 0; + } + async public Task UpdateAsync(TEntity data) + { + var exists = ExistsInStates(data); + if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (exists == false) + { + var olddata = await OrmSelect(data).FirstAsync(); + if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_fsql.GetEntityString(_entityType, data)}"); + } - await UpdateRangePrivAsync(new[] { data }, true); - } - public Task UpdateRangeAsync(IEnumerable data) => UpdateRangePrivAsync(data, true); - async Task UpdateRangePrivAsync(IEnumerable data, bool isCheck) { - if (CanUpdate(data, true) == false) return; - foreach (var item in data) { - if (_dicUpdateTimes.ContainsKey(item)) - await DbContextExecCommandAsync(); - _dicUpdateTimes.Add(item, 1); + await UpdateRangePrivAsync(new[] { data }, true); + } + public Task UpdateRangeAsync(IEnumerable data) => UpdateRangePrivAsync(data, true); + async Task UpdateRangePrivAsync(IEnumerable data, bool isCheck) + { + if (CanUpdate(data, true) == false) return; + foreach (var item in data) + { + if (_dicUpdateTimes.ContainsKey(item)) + await DbContextExecCommandAsync(); + _dicUpdateTimes.Add(item, 1); - var state = CreateEntityState(item); - state.OldValue = item; - EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); - } - if (_ctx.Options.EnableAddOrUpdateNavigateList) - foreach (var item in data) - await AddOrUpdateNavigateListAsync(item); - } - #endregion + var state = CreateEntityState(item); + state.OldValue = item; + EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); + } + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + await AddOrUpdateNavigateListAsync(item); + } + #endregion - #region RemoveAsync - async Task DbContextBetchRemoveAsync(EntityState[] dels) { - if (dels.Any() == false) return 0; - var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); - return Math.Max(dels.Length, affrows); - } - #endregion + #region RemoveAsync + async Task DbContextBetchRemoveAsync(EntityState[] dels) + { + if (dels.Any() == false) return 0; + var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); + return Math.Max(dels.Length, affrows); + } + #endregion - #region AddOrUpdateAsync - async public Task AddOrUpdateAsync(TEntity data) { - if (data == null) throw new ArgumentNullException(nameof(data)); - if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + #region AddOrUpdateAsync + async public Task AddOrUpdateAsync(TEntity data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); - var flagExists = ExistsInStates(data); - if (flagExists == false) { - var olddata = await OrmSelect(data).FirstAsync(); - if (olddata == null) flagExists = false; - } + var flagExists = ExistsInStates(data); + if (flagExists == false) + { + var olddata = await OrmSelect(data).FirstAsync(); + if (olddata == null) flagExists = false; + } - if (flagExists == true && CanUpdate(data, false)) { - await DbContextExecCommandAsync(); - var affrows = _ctx._affrows; - await UpdateRangePrivAsync(new[] { data }, false); - await DbContextExecCommandAsync(); - affrows = _ctx._affrows - affrows; - if (affrows > 0) return; - } - if (CanAdd(data, false)) { - _fsql.ClearEntityPrimaryValueWithIdentity(_entityType, data); - await AddPrivAsync(data, false); - } - } - #endregion - } + if (flagExists == true && CanUpdate(data, false)) + { + await DbContextExecCommandAsync(); + var affrows = _ctx._affrows; + await UpdateRangePrivAsync(new[] { data }, false); + await DbContextExecCommandAsync(); + affrows = _ctx._affrows - affrows; + if (affrows > 0) return; + } + if (CanAdd(data, false)) + { + _fsql.ClearEntityPrimaryValueWithIdentity(_entityType, data); + await AddPrivAsync(data, false); + } + } + #endregion + } } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index c41c1d77..b056583b 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -6,300 +6,344 @@ using System.Collections.Concurrent; using System.Linq; using System.Reflection; -namespace FreeSql { - partial class DbSet { +namespace FreeSql +{ + partial class DbSet + { - void DbContextExecCommand() { - _dicUpdateTimes.Clear(); - _ctx.ExecCommand(); - } + void DbContextExecCommand() + { + _dicUpdateTimes.Clear(); + _ctx.ExecCommand(); + } - int DbContextBetchAdd(EntityState[] adds) { - if (adds.Any() == false) return 0; - var affrows = this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrows(); - return affrows; - } + int DbContextBetchAdd(EntityState[] adds) + { + if (adds.Any() == false) return 0; + var affrows = this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrows(); + return affrows; + } - #region Add - void AddPriv(TEntity data, bool isCheck) { - if (isCheck && CanAdd(data, true) == false) return; - if (_tableIdentitys.Length > 0) { - //有自增,马上执行 - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - if (_tableIdentitys.Length == 1) { - DbContextExecCommand(); - var idtval = this.OrmInsert(data).ExecuteIdentity(); - IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); - Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data); - } else { - DbContextExecCommand(); - var newval = this.OrmInsert(data).ExecuteInserted().First(); - IncrAffrows(1); - _fsql.MapEntityValue(_entityType, newval, data); - Attach(newval); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data); - } - return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - if (_tableIdentitys.Length == 1) { - DbContextExecCommand(); - var idtval = this.OrmInsert(data).ExecuteIdentity(); - IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); - Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data); - } - return; - } - } - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); - Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data); - } - /// - /// 添加 - /// - /// - public void Add(TEntity data) => AddPriv(data, true); - public void AddRange(IEnumerable data) { - if (CanAdd(data, true) == false) return; - if (data.ElementAtOrDefault(1) == default(TEntity)) { - Add(data.First()); - return; - } - if (_tableIdentitys.Length > 0) { - //有自增,马上执行 - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - DbContextExecCommand(); - var rets = this.OrmInsert(data).ExecuteInserted(); - if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); - var idx = 0; - foreach (var s in data) - _fsql.MapEntityValue(_entityType, rets[idx++], s); - IncrAffrows(rets.Count); - AttachRange(rets); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - foreach (var item in data) - AddOrUpdateNavigateList(item); - return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - foreach (var s in data) - AddPriv(s, false); - return; - } - } else { - //进入队列,等待 SaveChanges 时执行 - foreach (var item in data) - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); - AttachRange(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) - foreach (var item in data) - AddOrUpdateNavigateList(item); - } - } - static ConcurrentDictionary> _dicLazyIsSetField = new ConcurrentDictionary>(); - void AddOrUpdateNavigateList(TEntity item) { - Type itemType = null; - foreach (var prop in _table.Properties) { - if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; - if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; + #region Add + void AddPriv(TEntity data, bool isCheck) + { + if (isCheck && CanAdd(data, true) == false) return; + if (_tableIdentitys.Length > 0) + { + //有自增,马上执行 + switch (_fsql.Ado.DataType) + { + case DataType.SqlServer: + case DataType.PostgreSQL: + if (_tableIdentitys.Length == 1) + { + DbContextExecCommand(); + var idtval = this.OrmInsert(data).ExecuteIdentity(); + IncrAffrows(1); + _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + AddOrUpdateNavigateList(data); + } + else + { + DbContextExecCommand(); + var newval = this.OrmInsert(data).ExecuteInserted().First(); + IncrAffrows(1); + _fsql.MapEntityValue(_entityType, newval, data); + Attach(newval); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + AddOrUpdateNavigateList(data); + } + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + if (_tableIdentitys.Length == 1) + { + DbContextExecCommand(); + var idtval = this.OrmInsert(data).ExecuteIdentity(); + IncrAffrows(1); + _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + AddOrUpdateNavigateList(data); + } + return; + } + } + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); + Attach(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + AddOrUpdateNavigateList(data); + } + /// + /// 添加 + /// + /// + public void Add(TEntity data) => AddPriv(data, true); + public void AddRange(IEnumerable data) + { + if (CanAdd(data, true) == false) return; + if (data.ElementAtOrDefault(1) == default(TEntity)) + { + Add(data.First()); + return; + } + if (_tableIdentitys.Length > 0) + { + //有自增,马上执行 + switch (_fsql.Ado.DataType) + { + case DataType.SqlServer: + case DataType.PostgreSQL: + DbContextExecCommand(); + var rets = this.OrmInsert(data).ExecuteInserted(); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); + var idx = 0; + foreach (var s in data) + _fsql.MapEntityValue(_entityType, rets[idx++], s); + IncrAffrows(rets.Count); + AttachRange(rets); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + AddOrUpdateNavigateList(item); + return; + case DataType.MySql: + case DataType.Oracle: + case DataType.Sqlite: + foreach (var s in data) + AddPriv(s, false); + return; + } + } + else + { + //进入队列,等待 SaveChanges 时执行 + foreach (var item in data) + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); + AttachRange(data); + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + AddOrUpdateNavigateList(item); + } + } + static ConcurrentDictionary> _dicLazyIsSetField = new ConcurrentDictionary>(); + void AddOrUpdateNavigateList(TEntity item) + { + Type itemType = null; + foreach (var prop in _table.Properties) + { + if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; + if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; - object propVal = null; + object propVal = null; - if (itemType == null) itemType = item.GetType(); - if (_table.TypeLazy != null && itemType == _table.TypeLazy) { - var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => - _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); - if (lazyField != null) { - var lazyFieldValue = (bool)lazyField.GetValue(item); - if (lazyFieldValue == false) continue; - } - propVal = prop.Value.GetValue(item); - } else { - propVal = prop.Value.GetValue(item); - if (propVal == null) continue; - } + if (itemType == null) itemType = item.GetType(); + if (_table.TypeLazy != null && itemType == _table.TypeLazy) + { + var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => + _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); + if (lazyField != null) + { + var lazyFieldValue = (bool)lazyField.GetValue(item); + if (lazyFieldValue == false) continue; + } + propVal = prop.Value.GetValue(item); + } + else + { + propVal = prop.Value.GetValue(item); + if (propVal == null) continue; + } - var tref = _table.GetTableRef(prop.Key, true); - if (tref == null) continue; + var tref = _table.GetTableRef(prop.Key, true); + if (tref == null) continue; - switch(tref.RefType) { - case Internal.Model.TableRefType.OneToOne: - case Internal.Model.TableRefType.ManyToOne: - case Internal.Model.TableRefType.ManyToMany: - continue; - case Internal.Model.TableRefType.OneToMany: - var propValEach = propVal as IEnumerable; - if (propValEach == null) continue; - object dbset = null; - MethodInfo dbsetAddOrUpdate = null; - foreach (var propValItem in propValEach) { - if (dbset == null) { - dbset = _ctx.Set(tref.RefEntityType); - dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdate", new Type[] { tref.RefEntityType }); - } - for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { - tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName] - .SetValue(propValItem, tref.Columns[colidx].Table.Properties[tref.Columns[colidx].CsName].GetValue(item)); - } - dbsetAddOrUpdate.Invoke(dbset, new object[] { propValItem }); - } - break; - } - } - } - #endregion + switch (tref.RefType) + { + case Internal.Model.TableRefType.OneToOne: + case Internal.Model.TableRefType.ManyToOne: + case Internal.Model.TableRefType.ManyToMany: + continue; + case Internal.Model.TableRefType.OneToMany: + var propValEach = propVal as IEnumerable; + if (propValEach == null) continue; + object dbset = null; + MethodInfo dbsetAddOrUpdate = null; + foreach (var propValItem in propValEach) + { + if (dbset == null) + { + dbset = _ctx.Set(tref.RefEntityType); + dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdate", new Type[] { tref.RefEntityType }); + } + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) + { + tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName] + .SetValue(propValItem, tref.Columns[colidx].Table.Properties[tref.Columns[colidx].CsName].GetValue(item)); + } + dbsetAddOrUpdate.Invoke(dbset, new object[] { propValItem }); + } + break; + } + } + } + #endregion - #region Update - int DbContextBetchUpdate(EntityState[] ups) => DbContextBetchUpdatePriv(ups, false); - int DbContextBetchUpdateNow(EntityState[] ups) => DbContextBetchUpdatePriv(ups, true); - int DbContextBetchUpdatePriv(EntityState[] ups, bool isLiveUpdate) { - if (ups.Any() == false) return 0; - var uplst1 = ups[ups.Length - 1]; - var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; + #region Update + int DbContextBetchUpdate(EntityState[] ups) => DbContextBetchUpdatePriv(ups, false); + int DbContextBetchUpdateNow(EntityState[] ups) => DbContextBetchUpdatePriv(ups, true); + int DbContextBetchUpdatePriv(EntityState[] ups, bool isLiveUpdate) + { + if (ups.Any() == false) return 0; + var uplst1 = ups[ups.Length - 1]; + var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; - if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; - var lstval2 = default(EntityState); - if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(_entityType, uplst2.Value)}"); + if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; + var lstval2 = default(EntityState); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(_entityType, uplst2.Value)}"); - var cuig1 = _fsql.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; + var cuig1 = _fsql.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; - List data = null; - string[] cuig = null; - if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { - //最后一个不保存 - data = ups.ToList(); - data.RemoveAt(ups.Length - 1); - cuig = cuig2; - } else if (isLiveUpdate) { - //立即保存 - data = ups.ToList(); - cuig = cuig1; - } + List data = null; + string[] cuig = null; + if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) + { + //最后一个不保存 + data = ups.ToList(); + data.RemoveAt(ups.Length - 1); + cuig = cuig2; + } + else if (isLiveUpdate) + { + //立即保存 + data = ups.ToList(); + cuig = cuig1; + } - if (data?.Count > 0) { + if (data?.Count > 0) + { - if (cuig.Length == _table.Columns.Count) - return ups.Length == data.Count ? -998 : -997; + if (cuig.Length == _table.Columns.Count) + return ups.Length == data.Count ? -998 : -997; - var updateSource = data.Select(a => a.Value).ToArray(); - var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); + var updateSource = data.Select(a => a.Value).ToArray(); + var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); - var affrows = update.ExecuteAffrows(); + var affrows = update.ExecuteAffrows(); - foreach (var newval in data) { - if (_states.TryGetValue(newval.Key, out var tryold)) - _fsql.MapEntityValue(_entityType, newval.Value, tryold.Value); - if (newval.OldValue != null) - _fsql.MapEntityValue(_entityType, newval.Value, newval.OldValue); - } - return affrows; - } + foreach (var newval in data) + { + if (_states.TryGetValue(newval.Key, out var tryold)) + _fsql.MapEntityValue(_entityType, newval.Value, tryold.Value); + if (newval.OldValue != null) + _fsql.MapEntityValue(_entityType, newval.Value, newval.OldValue); + } + return affrows; + } - //等待下次对比再保存 - return 0; - } + //等待下次对比再保存 + return 0; + } - Dictionary _dicUpdateTimes = new Dictionary(); - /// - /// 更新 - /// - /// - public void Update(TEntity data) { - var exists = ExistsInStates(data); - if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); - if (exists == false) { - var olddata = OrmSelect(data).First(); - if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_fsql.GetEntityString(_entityType, data)}"); - } + Dictionary _dicUpdateTimes = new Dictionary(); + /// + /// 更新 + /// + /// + public void Update(TEntity data) + { + var exists = ExistsInStates(data); + if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (exists == false) + { + var olddata = OrmSelect(data).First(); + if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_fsql.GetEntityString(_entityType, data)}"); + } - UpdateRangePriv(new[] { data }, true); - } - public void UpdateRange(IEnumerable data) => UpdateRangePriv(data, true); - void UpdateRangePriv(IEnumerable data, bool isCheck) { - if (CanUpdate(data, true) == false) return; - foreach (var item in data) { - if (_dicUpdateTimes.ContainsKey(item)) - DbContextExecCommand(); - _dicUpdateTimes.Add(item, 1); + UpdateRangePriv(new[] { data }, true); + } + public void UpdateRange(IEnumerable data) => UpdateRangePriv(data, true); + void UpdateRangePriv(IEnumerable data, bool isCheck) + { + if (CanUpdate(data, true) == false) return; + foreach (var item in data) + { + if (_dicUpdateTimes.ContainsKey(item)) + DbContextExecCommand(); + _dicUpdateTimes.Add(item, 1); - var state = CreateEntityState(item); - state.OldValue = item; - EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); - } - if (_ctx.Options.EnableAddOrUpdateNavigateList) - foreach (var item in data) - AddOrUpdateNavigateList(item); - } - #endregion + var state = CreateEntityState(item); + state.OldValue = item; + EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); + } + if (_ctx.Options.EnableAddOrUpdateNavigateList) + foreach (var item in data) + AddOrUpdateNavigateList(item); + } + #endregion - #region Remove - int DbContextBetchRemove(EntityState[] dels) { - if (dels.Any() == false) return 0; - var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); - return Math.Max(dels.Length, affrows); - } + #region Remove + int DbContextBetchRemove(EntityState[] dels) + { + if (dels.Any() == false) return 0; + var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); + return Math.Max(dels.Length, affrows); + } - /// - /// 删除 - /// - /// - public void Remove(TEntity data) => RemoveRange(new[] { data }); - public void RemoveRange(IEnumerable data) { - if (CanRemove(data, true) == false) return; - foreach (var item in data) { - var state = CreateEntityState(item); - _states.TryRemove(state.Key, out var trystate); - _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, item); + /// + /// 删除 + /// + /// + public void Remove(TEntity data) => RemoveRange(new[] { data }); + public void RemoveRange(IEnumerable data) + { + if (CanRemove(data, true) == false) return; + foreach (var item in data) + { + var state = CreateEntityState(item); + _states.TryRemove(state.Key, out var trystate); + _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, item); - EnqueueToDbContext(DbContext.ExecCommandInfoType.Delete, state); - } - } - #endregion + EnqueueToDbContext(DbContext.ExecCommandInfoType.Delete, state); + } + } + #endregion - #region AddOrUpdate - /// - /// 添加或更新 - /// - /// - public void AddOrUpdate(TEntity data) { - if (data == null) throw new ArgumentNullException(nameof(data)); - if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + #region AddOrUpdate + /// + /// 添加或更新 + /// + /// + public void AddOrUpdate(TEntity data) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); - var flagExists = ExistsInStates(data); - if (flagExists == false) { - var olddata = OrmSelect(data).First(); - if (olddata == null) flagExists = false; - } + var flagExists = ExistsInStates(data); + if (flagExists == false) + { + var olddata = OrmSelect(data).First(); + if (olddata == null) flagExists = false; + } - if (flagExists == true && CanUpdate(data, false)) { - DbContextExecCommand(); - var affrows = _ctx._affrows; - UpdateRangePriv(new[] { data }, false); - DbContextExecCommand(); - affrows = _ctx._affrows - affrows; - if (affrows > 0) return; - } - if (CanAdd(data, false)) { - _fsql.ClearEntityPrimaryValueWithIdentity(_entityType, data); - AddPriv(data, false); - } - } - #endregion - } + if (flagExists == true && CanUpdate(data, false)) + { + DbContextExecCommand(); + var affrows = _ctx._affrows; + UpdateRangePriv(new[] { data }, false); + DbContextExecCommand(); + affrows = _ctx._affrows - affrows; + if (affrows > 0) return; + } + if (CanAdd(data, false)) + { + _fsql.ClearEntityPrimaryValueWithIdentity(_entityType, data); + AddPriv(data, false); + } + } + #endregion + } } diff --git a/FreeSql.DbContext/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Extenssions/DependencyInjection.cs index a91635a5..bf92a08e 100644 --- a/FreeSql.DbContext/Extenssions/DependencyInjection.cs +++ b/FreeSql.DbContext/Extenssions/DependencyInjection.cs @@ -3,30 +3,35 @@ using Microsoft.Extensions.DependencyInjection; using System; -namespace FreeSql { - public static class DbContextDependencyInjection { +namespace FreeSql +{ + public static class DbContextDependencyInjection + { - public static IServiceCollection AddFreeDbContext(this IServiceCollection services, Action options) where TDbContext : DbContext { + public static IServiceCollection AddFreeDbContext(this IServiceCollection services, Action options) where TDbContext : DbContext + { - services.AddScoped(sp => { - var ctx = Activator.CreateInstance(); + services.AddScoped(sp => + { + var ctx = Activator.CreateInstance(); - if (ctx._orm == null) { - var builder = new DbContextOptionsBuilder(); - options(builder); - ctx._orm = builder._fsql; + if (ctx._orm == null) + { + var builder = new DbContextOptionsBuilder(); + options(builder); + ctx._orm = builder._fsql; - if (ctx._orm == null) - throw new Exception("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); + if (ctx._orm == null) + throw new Exception("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); - ctx.InitPropSets(); - } + ctx.InitPropSets(); + } - return ctx; - }); + return ctx; + }); - return services; - } - } + return services; + } + } } #endif \ No newline at end of file diff --git a/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs b/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs index 7fae5c66..af755db5 100644 --- a/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs +++ b/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs @@ -2,37 +2,41 @@ using System; using System.Collections.Concurrent; -public static class FreeSqlDbContextExtenssions { +public static class FreeSqlDbContextExtenssions +{ - /// - /// 创建普通数据上下文档对象 - /// - /// - /// - public static DbContext CreateDbContext(this IFreeSql that) { - return new FreeContext(that); - } + /// + /// 创建普通数据上下文档对象 + /// + /// + /// + public static DbContext CreateDbContext(this IFreeSql that) + { + return new FreeContext(that); + } - /// - /// 不跟踪查询的实体数据(在不需要更新其数据时使用),可提长查询性能 - /// - /// - /// - /// - public static ISelect NoTracking(this ISelect select) where T : class { - return select.TrackToList(null); - } + /// + /// 不跟踪查询的实体数据(在不需要更新其数据时使用),可提长查询性能 + /// + /// + /// + /// + public static ISelect NoTracking(this ISelect select) where T : class + { + return select.TrackToList(null); + } - /// - /// 设置 DbContext 选项设置 - /// - /// - /// - public static void SetDbContextOptions(this IFreeSql that, Action options) { - if (options == null) return; - var cfg = _dicSetDbContextOptions.GetOrAdd(that, t => new DbContextOptions()); - options(cfg); - _dicSetDbContextOptions.AddOrUpdate(that, cfg, (t, o) => cfg); - } - internal static ConcurrentDictionary _dicSetDbContextOptions = new ConcurrentDictionary(); + /// + /// 设置 DbContext 选项设置 + /// + /// + /// + public static void SetDbContextOptions(this IFreeSql that, Action options) + { + if (options == null) return; + var cfg = _dicSetDbContextOptions.GetOrAdd(that, t => new DbContextOptions()); + options(cfg); + _dicSetDbContextOptions.AddOrUpdate(that, cfg, (t, o) => cfg); + } + internal static ConcurrentDictionary _dicSetDbContextOptions = new ConcurrentDictionary(); } \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index ac3dbf7a..643850d2 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -3,60 +3,69 @@ using System.Collections.Concurrent; using System.Reflection; using System.Threading.Tasks; -namespace FreeSql { - internal class RepositoryDbContext : DbContext { +namespace FreeSql +{ + internal class RepositoryDbContext : DbContext + { - protected IBaseRepository _repos; - public RepositoryDbContext(IFreeSql orm, IBaseRepository repos) : base() { - _orm = orm; - _repos = repos; - _isUseUnitOfWork = false; - _uowPriv = _repos.UnitOfWork; - } + protected IBaseRepository _repos; + public RepositoryDbContext(IFreeSql orm, IBaseRepository repos) : base() + { + _orm = orm; + _repos = repos; + _isUseUnitOfWork = false; + _uowPriv = _repos.UnitOfWork; + } - static ConcurrentDictionary _dicGetRepositoryDbField = new ConcurrentDictionary(); - static FieldInfo GetRepositoryDbField(Type type) => _dicGetRepositoryDbField.GetOrAdd(type, tp => typeof(BaseRepository<,>).MakeGenericType(tp, typeof(int)).GetField("_dbPriv", BindingFlags.Instance | BindingFlags.NonPublic)); - public override IDbSet Set(Type entityType) { - if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; + static ConcurrentDictionary _dicGetRepositoryDbField = new ConcurrentDictionary(); + static FieldInfo GetRepositoryDbField(Type type) => _dicGetRepositoryDbField.GetOrAdd(type, tp => typeof(BaseRepository<,>).MakeGenericType(tp, typeof(int)).GetField("_dbPriv", BindingFlags.Instance | BindingFlags.NonPublic)); + public override IDbSet Set(Type entityType) + { + if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; - var tb = _orm.CodeFirst.GetTableByEntity(entityType); - if (tb == null) return null; + var tb = _orm.CodeFirst.GetTableByEntity(entityType); + if (tb == null) return null; - object repos = _repos; - if (entityType != _repos.EntityType) { - repos = Activator.CreateInstance(typeof(DefaultRepository<,>).MakeGenericType(entityType, typeof(int)), _repos.Orm); - (repos as IBaseRepository).UnitOfWork = _repos.UnitOfWork; - GetRepositoryDbField(entityType).SetValue(repos, this); + object repos = _repos; + if (entityType != _repos.EntityType) + { + repos = Activator.CreateInstance(typeof(DefaultRepository<,>).MakeGenericType(entityType, typeof(int)), _repos.Orm); + (repos as IBaseRepository).UnitOfWork = _repos.UnitOfWork; + GetRepositoryDbField(entityType).SetValue(repos, this); - typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repos.EntityType) - .Invoke(null, new object[] { repos, _repos }); - } + typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repos.EntityType) + .Invoke(null, new object[] { repos, _repos }); + } - var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repos) as IDbSet; - if (entityType != typeof(object)) _dicSet.Add(entityType, sd); - return sd; - } + var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repos) as IDbSet; + if (entityType != typeof(object)) _dicSet.Add(entityType, sd); + return sd; + } - public static void SetRepositoryDataFilter(object repos, BaseRepository baseRepo) where TEntity : class { - var filter = baseRepo.DataFilter as DataFilter; - DataFilterUtil.SetRepositoryDataFilter(repos, fl => { - foreach (var f in filter._filters) - fl.Apply(f.Key, f.Value.Expression); - }); - } + public static void SetRepositoryDataFilter(object repos, BaseRepository baseRepo) where TEntity : class + { + var filter = baseRepo.DataFilter as DataFilter; + DataFilterUtil.SetRepositoryDataFilter(repos, fl => + { + foreach (var f in filter._filters) + fl.Apply(f.Key, f.Value.Expression); + }); + } - public override int SaveChanges() { - ExecCommand(); - var ret = _affrows; - _affrows = 0; - return ret; - } - async public override Task SaveChangesAsync() { - await ExecCommandAsync(); - var ret = _affrows; - _affrows = 0; - return ret; - } - } + public override int SaveChanges() + { + ExecCommand(); + var ret = _affrows; + _affrows = 0; + return ret; + } + async public override Task SaveChangesAsync() + { + await ExecCommandAsync(); + var ret = _affrows; + _affrows = 0; + return ret; + } + } } diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs index b50225ed..d88188ba 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs @@ -3,58 +3,67 @@ using System; using System.Collections.Generic; using System.Linq; -namespace FreeSql { - internal class RepositoryDbSet : DbSet where TEntity : class { +namespace FreeSql +{ + internal class RepositoryDbSet : DbSet where TEntity : class + { - protected BaseRepository _repos; - public RepositoryDbSet(BaseRepository repos) { - _ctx = repos._db; - _fsql = repos.Orm; - _uow = repos.UnitOfWork; - _repos = repos; - } + protected BaseRepository _repos; + public RepositoryDbSet(BaseRepository repos) + { + _ctx = repos._db; + _fsql = repos.Orm; + _uow = repos.UnitOfWork; + _repos = repos; + } - protected override ISelect OrmSelect(object dywhere) { - var select = base.OrmSelect(dywhere); + protected override ISelect OrmSelect(object dywhere) + { + var select = base.OrmSelect(dywhere); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) select.Where(filter.Value.Expression); - return select.AsTable(_repos.AsTableSelectInternal); - } - internal ISelect OrmSelectInternal(object dywhere) => OrmSelect(dywhere); - protected override IUpdate OrmUpdate(IEnumerable entitys) { - var update = base.OrmUpdate(entitys); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) { - if (entitys != null) - foreach (var entity in entitys) - if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) - throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_fsql.GetEntityString(_entityType, entity)}"); - update.Where(filter.Value.Expression); - } - return update.AsTable(_repos.AsTableInternal); - } - internal IUpdate OrmUpdateInternal(IEnumerable entitys) => OrmUpdate(entitys); - protected override IDelete OrmDelete(object dywhere) { - var delete = base.OrmDelete(dywhere); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) delete.Where(filter.Value.Expression); - return delete.AsTable(_repos.AsTableInternal); - } - internal IDelete OrmDeleteInternal(object dywhere) => OrmDelete(dywhere); - protected override IInsert OrmInsert(TEntity entity) => OrmInsert(new[] { entity }); - protected override IInsert OrmInsert(IEnumerable entitys) { - var insert = base.OrmInsert(entitys); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) { - if (entitys != null) - foreach (var entity in entitys) - if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) - throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_fsql.GetEntityString(_entityType, entity)}"); - } - return insert.AsTable(_repos.AsTableInternal); - } - internal IInsert OrmInsertInternal(TEntity entity) => OrmInsert(entity); - internal IInsert OrmInsertInternal(IEnumerable entitys) => OrmInsert(entitys); - } + var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) select.Where(filter.Value.Expression); + return select.AsTable(_repos.AsTableSelectInternal); + } + internal ISelect OrmSelectInternal(object dywhere) => OrmSelect(dywhere); + protected override IUpdate OrmUpdate(IEnumerable entitys) + { + var update = base.OrmUpdate(entitys); + var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) + { + if (entitys != null) + foreach (var entity in entitys) + if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) + throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_fsql.GetEntityString(_entityType, entity)}"); + update.Where(filter.Value.Expression); + } + return update.AsTable(_repos.AsTableInternal); + } + internal IUpdate OrmUpdateInternal(IEnumerable entitys) => OrmUpdate(entitys); + protected override IDelete OrmDelete(object dywhere) + { + var delete = base.OrmDelete(dywhere); + var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) delete.Where(filter.Value.Expression); + return delete.AsTable(_repos.AsTableInternal); + } + internal IDelete OrmDeleteInternal(object dywhere) => OrmDelete(dywhere); + protected override IInsert OrmInsert(TEntity entity) => OrmInsert(new[] { entity }); + protected override IInsert OrmInsert(IEnumerable entitys) + { + var insert = base.OrmInsert(entitys); + var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) + { + if (entitys != null) + foreach (var entity in entitys) + if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) + throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_fsql.GetEntityString(_entityType, entity)}"); + } + return insert.AsTable(_repos.AsTableInternal); + } + internal IInsert OrmInsertInternal(TEntity entity) => OrmInsert(entity); + internal IInsert OrmInsertInternal(IEnumerable entitys) => OrmInsert(entitys); + } } diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs index d36c4887..7166ef2c 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs @@ -1,57 +1,64 @@ using System; using System.Linq.Expressions; -namespace FreeSql { +namespace FreeSql +{ - public interface IRepositoryUnitOfWork : IUnitOfWork { - /// - /// 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点 - /// - /// - /// - /// 数据过滤 + 验证 - /// - DefaultRepository GetRepository(Expression> filter = null) where TEntity : class; + public interface IRepositoryUnitOfWork : IUnitOfWork + { + /// + /// 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点 + /// + /// + /// + /// 数据过滤 + 验证 + /// + DefaultRepository GetRepository(Expression> filter = null) where TEntity : class; - /// - /// 在工作单元内创建联合主键的仓储类,工作单元下的仓储操作具有事务特点 - /// - /// - /// 数据过滤 + 验证 - /// - BaseRepository GetRepository(Expression> filter = null) where TEntity : class; + /// + /// 在工作单元内创建联合主键的仓储类,工作单元下的仓储操作具有事务特点 + /// + /// + /// 数据过滤 + 验证 + /// + BaseRepository GetRepository(Expression> filter = null) where TEntity : class; - /// - /// 在工作单元内创建仓库类,工作单元下的仓储操作具有事务特点 - /// - /// - /// 数据过滤 + 验证 - /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - /// - GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class; - } + /// + /// 在工作单元内创建仓库类,工作单元下的仓储操作具有事务特点 + /// + /// + /// 数据过滤 + 验证 + /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + /// + GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class; + } - class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork { + class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork + { - public RepositoryUnitOfWork(IFreeSql fsql) : base(fsql) { - } + public RepositoryUnitOfWork(IFreeSql fsql) : base(fsql) + { + } - public GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class { - var repos = new GuidRepository(_fsql, filter, asTable); - repos.UnitOfWork = this; - return repos; - } + public GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class + { + var repos = new GuidRepository(_fsql, filter, asTable); + repos.UnitOfWork = this; + return repos; + } - public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class { - var repos = new DefaultRepository(_fsql, filter); - repos.UnitOfWork = this; - return repos; - } + public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class + { + var repos = new DefaultRepository(_fsql, filter); + repos.UnitOfWork = this; + return repos; + } - public BaseRepository GetRepository(Expression> filter = null) where TEntity : class { - var repos = new DefaultRepository(_fsql, filter); - repos.UnitOfWork = this; - return repos; - } - } + public BaseRepository GetRepository(Expression> filter = null) where TEntity : class + { + var repos = new DefaultRepository(_fsql, filter); + repos.UnitOfWork = this; + return repos; + } + } } diff --git a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs index d65a3b0a..b03874bd 100644 --- a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs +++ b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs @@ -4,149 +4,178 @@ using System.Collections.Concurrent; using System.Linq.Expressions; using System.Linq; -namespace FreeSql { - public interface IDataFilter : IDisposable where TEntity : class { +namespace FreeSql +{ + public interface IDataFilter : IDisposable where TEntity : class + { - IDataFilter Apply(string filterName, Expression> filterAndValidateExp); + IDataFilter Apply(string filterName, Expression> filterAndValidateExp); - /// - /// 开启过滤器,若使用 using 则使用完后,恢复为原有状态 - /// - /// 过滤器名称 - /// - IDisposable Enable(params string[] filterName); - /// - /// 开启所有过滤器,若使用 using 则使用完后,恢复为原有状态 - /// - /// - IDisposable EnableAll(); + /// + /// 开启过滤器,若使用 using 则使用完后,恢复为原有状态 + /// + /// 过滤器名称 + /// + IDisposable Enable(params string[] filterName); + /// + /// 开启所有过滤器,若使用 using 则使用完后,恢复为原有状态 + /// + /// + IDisposable EnableAll(); - /// - /// 禁用过滤器,若使用 using 则使用完后,恢复为原有状态 - /// - /// - /// - IDisposable Disable(params string[] filterName); - /// - /// 禁用所有过滤器,若使用 using 则使用完后,恢复为原有状态 - /// - /// - IDisposable DisableAll(); + /// + /// 禁用过滤器,若使用 using 则使用完后,恢复为原有状态 + /// + /// + /// + IDisposable Disable(params string[] filterName); + /// + /// 禁用所有过滤器,若使用 using 则使用完后,恢复为原有状态 + /// + /// + IDisposable DisableAll(); - bool IsEnabled(string filterName); - } + bool IsEnabled(string filterName); + } - internal class DataFilter : IDataFilter where TEntity : class { + internal class DataFilter : IDataFilter where TEntity : class + { - internal class FilterItem { - public Expression> Expression { get; set; } - Func _expressionDelegate; - public Func ExpressionDelegate => _expressionDelegate ?? (_expressionDelegate = Expression?.Compile()); - public bool IsEnabled { get; set; } - } + internal class FilterItem + { + public Expression> Expression { get; set; } + Func _expressionDelegate; + public Func ExpressionDelegate => _expressionDelegate ?? (_expressionDelegate = Expression?.Compile()); + public bool IsEnabled { get; set; } + } - internal ConcurrentDictionary _filters = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - public IDataFilter Apply(string filterName, Expression> filterAndValidateExp) { + internal ConcurrentDictionary _filters = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + public IDataFilter Apply(string filterName, Expression> filterAndValidateExp) + { - if (filterName == null) - throw new ArgumentNullException(nameof(filterName)); - if (filterAndValidateExp == null) return this; + if (filterName == null) + throw new ArgumentNullException(nameof(filterName)); + if (filterAndValidateExp == null) return this; - var filterItem = new FilterItem { Expression = filterAndValidateExp, IsEnabled = true }; - _filters.AddOrUpdate(filterName, filterItem, (k, v) => filterItem); - return this; - } + var filterItem = new FilterItem { Expression = filterAndValidateExp, IsEnabled = true }; + _filters.AddOrUpdate(filterName, filterItem, (k, v) => filterItem); + return this; + } - public IDisposable Disable(params string[] filterName) { - if (filterName == null || filterName.Any() == false) return new UsingAny(() => { }); + public IDisposable Disable(params string[] filterName) + { + if (filterName == null || filterName.Any() == false) return new UsingAny(() => { }); - List restore = new List(); - foreach (var name in filterName) { - if (_filters.TryGetValue(name, out var tryfi)) { - if (tryfi.IsEnabled) { - restore.Add(name); - tryfi.IsEnabled = false; - } - } - } - return new UsingAny(() => this.Enable(restore.ToArray())); - } - public IDisposable DisableAll() { - List restore = new List(); - foreach (var val in _filters) { - if (val.Value.IsEnabled) { - restore.Add(val.Key); - val.Value.IsEnabled = false; - } - } - return new UsingAny(() => this.Enable(restore.ToArray())); - } - class UsingAny : IDisposable { - Action _ondis; - public UsingAny(Action ondis) { - _ondis = ondis; - } - public void Dispose() { - _ondis?.Invoke(); - } - } + List restore = new List(); + foreach (var name in filterName) + { + if (_filters.TryGetValue(name, out var tryfi)) + { + if (tryfi.IsEnabled) + { + restore.Add(name); + tryfi.IsEnabled = false; + } + } + } + return new UsingAny(() => this.Enable(restore.ToArray())); + } + public IDisposable DisableAll() + { + List restore = new List(); + foreach (var val in _filters) + { + if (val.Value.IsEnabled) + { + restore.Add(val.Key); + val.Value.IsEnabled = false; + } + } + return new UsingAny(() => this.Enable(restore.ToArray())); + } + class UsingAny : IDisposable + { + Action _ondis; + public UsingAny(Action ondis) + { + _ondis = ondis; + } + public void Dispose() + { + _ondis?.Invoke(); + } + } - public IDisposable Enable(params string[] filterName) { - if (filterName == null || filterName.Any() == false) return new UsingAny(() => { }); + public IDisposable Enable(params string[] filterName) + { + if (filterName == null || filterName.Any() == false) return new UsingAny(() => { }); - List restore = new List(); - foreach (var name in filterName) { - if (_filters.TryGetValue(name, out var tryfi)) { - if (tryfi.IsEnabled == false) { - restore.Add(name); - tryfi.IsEnabled = true; - } - } - } - return new UsingAny(() => this.Disable(restore.ToArray())); - } - public IDisposable EnableAll() { - List restore = new List(); - foreach (var val in _filters) { - if (val.Value.IsEnabled == false) { - restore.Add(val.Key); - val.Value.IsEnabled = true; - } - } - return new UsingAny(() => this.Disable(restore.ToArray())); - } + List restore = new List(); + foreach (var name in filterName) + { + if (_filters.TryGetValue(name, out var tryfi)) + { + if (tryfi.IsEnabled == false) + { + restore.Add(name); + tryfi.IsEnabled = true; + } + } + } + return new UsingAny(() => this.Disable(restore.ToArray())); + } + public IDisposable EnableAll() + { + List restore = new List(); + foreach (var val in _filters) + { + if (val.Value.IsEnabled == false) + { + restore.Add(val.Key); + val.Value.IsEnabled = true; + } + } + return new UsingAny(() => this.Disable(restore.ToArray())); + } - public bool IsEnabled(string filterName) { - if (filterName == null) return false; - return _filters.TryGetValue(filterName, out var tryfi) ? tryfi.IsEnabled : false; - } + public bool IsEnabled(string filterName) + { + if (filterName == null) return false; + return _filters.TryGetValue(filterName, out var tryfi) ? tryfi.IsEnabled : false; + } - ~DataFilter() { - this.Dispose(); - } - public void Dispose() { - _filters.Clear(); - } - } + ~DataFilter() + { + this.Dispose(); + } + public void Dispose() + { + _filters.Clear(); + } + } - public class FluentDataFilter : IDisposable { + public class FluentDataFilter : IDisposable + { - internal List<(Type type, string name, LambdaExpression exp)> _filters = new List<(Type type, string name, LambdaExpression exp)>(); + internal List<(Type type, string name, LambdaExpression exp)> _filters = new List<(Type type, string name, LambdaExpression exp)>(); - public FluentDataFilter Apply(string filterName, Expression> filterAndValidateExp) where TEntity : class { - if (filterName == null) - throw new ArgumentNullException(nameof(filterName)); - if (filterAndValidateExp == null) return this; + public FluentDataFilter Apply(string filterName, Expression> filterAndValidateExp) where TEntity : class + { + if (filterName == null) + throw new ArgumentNullException(nameof(filterName)); + if (filterAndValidateExp == null) return this; - _filters.Add((typeof(TEntity), filterName, filterAndValidateExp)); - return this; - } + _filters.Add((typeof(TEntity), filterName, filterAndValidateExp)); + return this; + } - ~FluentDataFilter() { - this.Dispose(); - } - public void Dispose() { - _filters.Clear(); - } - } + ~FluentDataFilter() + { + this.Dispose(); + } + public void Dispose() + { + _filters.Clear(); + } + } } diff --git a/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs b/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs index b94905b4..f626bc3a 100644 --- a/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs +++ b/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs @@ -5,85 +5,100 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; -namespace FreeSql { +namespace FreeSql +{ - internal class DataFilterUtil { + internal class DataFilterUtil + { - internal static Action _globalDataFilter; + internal static Action _globalDataFilter; - static ConcurrentDictionary _dicSetRepositoryDataFilterApplyDataFilterFunc = new ConcurrentDictionary(); - static ConcurrentDictionary> _dicSetRepositoryDataFilterConvertFilterNotExists = new ConcurrentDictionary>(); - internal static void SetRepositoryDataFilter(object repos, Action scopedDataFilter) { - if (scopedDataFilter != null) { - SetRepositoryDataFilter(repos, null); - } - if (scopedDataFilter == null) { - scopedDataFilter = _globalDataFilter; - } - if (scopedDataFilter == null) return; - using (var globalFilter = new FluentDataFilter()) { - scopedDataFilter(globalFilter); + static ConcurrentDictionary _dicSetRepositoryDataFilterApplyDataFilterFunc = new ConcurrentDictionary(); + static ConcurrentDictionary> _dicSetRepositoryDataFilterConvertFilterNotExists = new ConcurrentDictionary>(); + internal static void SetRepositoryDataFilter(object repos, Action scopedDataFilter) + { + if (scopedDataFilter != null) + { + SetRepositoryDataFilter(repos, null); + } + if (scopedDataFilter == null) + { + scopedDataFilter = _globalDataFilter; + } + if (scopedDataFilter == null) return; + using (var globalFilter = new FluentDataFilter()) + { + scopedDataFilter(globalFilter); - var type = repos.GetType(); - Type entityType = (repos as IBaseRepository).EntityType; - if (entityType == null) throw new Exception("FreeSql.Repository 设置过滤器失败,原因是对象不属于 IRepository"); + var type = repos.GetType(); + Type entityType = (repos as IBaseRepository).EntityType; + if (entityType == null) throw new Exception("FreeSql.Repository 设置过滤器失败,原因是对象不属于 IRepository"); - var notExists = _dicSetRepositoryDataFilterConvertFilterNotExists.GetOrAdd(type, t => new ConcurrentDictionary()); - var newFilter = new Dictionary(); - foreach (var gf in globalFilter._filters) { - if (notExists.ContainsKey(gf.name)) continue; + var notExists = _dicSetRepositoryDataFilterConvertFilterNotExists.GetOrAdd(type, t => new ConcurrentDictionary()); + var newFilter = new Dictionary(); + foreach (var gf in globalFilter._filters) + { + if (notExists.ContainsKey(gf.name)) continue; - LambdaExpression newExp = null; - var filterParameter1 = Expression.Parameter(entityType, gf.exp.Parameters[0].Name); - try { - newExp = Expression.Lambda( - typeof(Func<,>).MakeGenericType(entityType, typeof(bool)), - new ReplaceVisitor().Modify(gf.exp.Body, filterParameter1), - filterParameter1 - ); - } catch { - notExists.TryAdd(gf.name, true); //防止第二次错误 - continue; - } - newFilter.Add(gf.name, newExp); - } - if (newFilter.Any() == false) return; + LambdaExpression newExp = null; + var filterParameter1 = Expression.Parameter(entityType, gf.exp.Parameters[0].Name); + try + { + newExp = Expression.Lambda( + typeof(Func<,>).MakeGenericType(entityType, typeof(bool)), + new ReplaceVisitor().Modify(gf.exp.Body, filterParameter1), + filterParameter1 + ); + } + catch + { + notExists.TryAdd(gf.name, true); //防止第二次错误 + continue; + } + newFilter.Add(gf.name, newExp); + } + if (newFilter.Any() == false) return; - var del = _dicSetRepositoryDataFilterApplyDataFilterFunc.GetOrAdd(type, t => { - var reposParameter = Expression.Parameter(type); - var nameParameter = Expression.Parameter(typeof(string)); - var expressionParameter = Expression.Parameter( - typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(entityType, typeof(bool))) - ); - return Expression.Lambda( - Expression.Block( - Expression.Call(reposParameter, type.GetMethod("ApplyDataFilter", BindingFlags.Instance | BindingFlags.NonPublic), nameParameter, expressionParameter) - ), - new[] { - reposParameter, nameParameter, expressionParameter - } - ).Compile(); - }); - foreach (var nf in newFilter) { - del.DynamicInvoke(repos, nf.Key, nf.Value); - } - newFilter.Clear(); - } - } - } + var del = _dicSetRepositoryDataFilterApplyDataFilterFunc.GetOrAdd(type, t => + { + var reposParameter = Expression.Parameter(type); + var nameParameter = Expression.Parameter(typeof(string)); + var expressionParameter = Expression.Parameter( + typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(entityType, typeof(bool))) + ); + return Expression.Lambda( + Expression.Block( + Expression.Call(reposParameter, type.GetMethod("ApplyDataFilter", BindingFlags.Instance | BindingFlags.NonPublic), nameParameter, expressionParameter) + ), + new[] { + reposParameter, nameParameter, expressionParameter + } + ).Compile(); + }); + foreach (var nf in newFilter) + { + del.DynamicInvoke(repos, nf.Key, nf.Value); + } + newFilter.Clear(); + } + } + } - class ReplaceVisitor : ExpressionVisitor { - private ParameterExpression parameter; + class ReplaceVisitor : ExpressionVisitor + { + private ParameterExpression parameter; - public Expression Modify(Expression expression, ParameterExpression parameter) { - this.parameter = parameter; - return Visit(expression); - } + public Expression Modify(Expression expression, ParameterExpression parameter) + { + this.parameter = parameter; + return Visit(expression); + } - protected override Expression VisitMember(MemberExpression node) { - if (node.Expression?.NodeType == ExpressionType.Parameter) - return Expression.Property(parameter, node.Member.Name); - return base.VisitMember(node); - } - } + protected override Expression VisitMember(MemberExpression node) + { + if (node.Expression?.NodeType == ExpressionType.Parameter) + return Expression.Property(parameter, node.Member.Name); + return base.VisitMember(node); + } + } } diff --git a/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs index 9265774d..f37848a8 100644 --- a/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs +++ b/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs @@ -5,35 +5,41 @@ using System.Reflection; using System.Linq; using Microsoft.Extensions.DependencyInjection; -namespace FreeSql { - public static class FreeSqlRepositoryDependencyInjection { +namespace FreeSql +{ + public static class FreeSqlRepositoryDependencyInjection + { - public static IServiceCollection AddFreeRepository(this IServiceCollection services, Action globalDataFilter = null, params Assembly[] assemblies) { + public static IServiceCollection AddFreeRepository(this IServiceCollection services, Action globalDataFilter = null, params Assembly[] assemblies) + { - DataFilterUtil._globalDataFilter = globalDataFilter; + DataFilterUtil._globalDataFilter = globalDataFilter; - services.AddScoped(typeof(IReadOnlyRepository<>), typeof(GuidRepository<>)); - services.AddScoped(typeof(IBasicRepository<>), typeof(GuidRepository<>)); - services.AddScoped(typeof(BaseRepository<>), typeof(GuidRepository<>)); - services.AddScoped(typeof(GuidRepository<>)); + services.AddScoped(typeof(IReadOnlyRepository<>), typeof(GuidRepository<>)); + services.AddScoped(typeof(IBasicRepository<>), typeof(GuidRepository<>)); + services.AddScoped(typeof(BaseRepository<>), typeof(GuidRepository<>)); + services.AddScoped(typeof(GuidRepository<>)); - services.AddScoped(typeof(IReadOnlyRepository<,>), typeof(DefaultRepository<,>)); - services.AddScoped(typeof(IBasicRepository<,>), typeof(DefaultRepository<,>)); - services.AddScoped(typeof(BaseRepository<,>), typeof(DefaultRepository<,>)); - services.AddScoped(typeof(DefaultRepository<,>)); + services.AddScoped(typeof(IReadOnlyRepository<,>), typeof(DefaultRepository<,>)); + services.AddScoped(typeof(IBasicRepository<,>), typeof(DefaultRepository<,>)); + services.AddScoped(typeof(BaseRepository<,>), typeof(DefaultRepository<,>)); + services.AddScoped(typeof(DefaultRepository<,>)); - if (assemblies?.Any() == true) { - foreach(var asse in assemblies) { - foreach (var repos in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(IBaseRepository).IsAssignableFrom(a))) { + if (assemblies?.Any() == true) + { + foreach (var asse in assemblies) + { + foreach (var repos in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(IBaseRepository).IsAssignableFrom(a))) + { - services.AddScoped(repos); - } - } - } + services.AddScoped(repos); + } + } + } - return services; - } - } + return services; + } + } } #endif \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs index 5c4fedd3..e34af18e 100644 --- a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs +++ b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs @@ -3,63 +3,69 @@ using System; using System.Linq.Expressions; using System.Linq; -public static class FreeSqlRepositoryExtenssions { +public static class FreeSqlRepositoryExtenssions +{ - /// - /// 返回默认仓库类 - /// - /// - /// - /// - /// 数据过滤 + 验证 - /// - public static DefaultRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { - return new DefaultRepository(that, filter); - } + /// + /// 返回默认仓库类 + /// + /// + /// + /// + /// 数据过滤 + 验证 + /// + public static DefaultRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class + { + return new DefaultRepository(that, filter); + } - /// - /// 返回默认仓库类,适用联合主键的仓储类 - /// - /// - /// - /// 数据过滤 + 验证 - /// - public static BaseRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { - return new DefaultRepository(that, filter); - } + /// + /// 返回默认仓库类,适用联合主键的仓储类 + /// + /// + /// + /// 数据过滤 + 验证 + /// + public static BaseRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class + { + return new DefaultRepository(that, filter); + } - /// - /// 返回仓库类 - /// - /// - /// - /// 数据过滤 + 验证 - /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - /// - public static GuidRepository GetGuidRepository(this IFreeSql that, Expression> filter = null, Func asTable = null) where TEntity : class { - return new GuidRepository(that, filter, asTable); - } + /// + /// 返回仓库类 + /// + /// + /// + /// 数据过滤 + 验证 + /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + /// + public static GuidRepository GetGuidRepository(this IFreeSql that, Expression> filter = null, Func asTable = null) where TEntity : class + { + return new GuidRepository(that, filter, asTable); + } - /// - /// 合并两个仓储的设置(过滤+分表),以便查询 - /// - /// - /// - /// - /// - /// - public static ISelect FromRepository(this ISelect that, BaseRepository repos) where TEntity : class where T2 : class { - var filters = (repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) that.Where(filter.Value.Expression); - return that.AsTable(repos.AsTableSelectInternal); - } + /// + /// 合并两个仓储的设置(过滤+分表),以便查询 + /// + /// + /// + /// + /// + /// + public static ISelect FromRepository(this ISelect that, BaseRepository repos) where TEntity : class where T2 : class + { + var filters = (repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) that.Where(filter.Value.Expression); + return that.AsTable(repos.AsTableSelectInternal); + } - /// - /// 创建基于仓储功能的工作单元,务必使用 using 包含使用 - /// - /// - /// - public static IRepositoryUnitOfWork CreateUnitOfWork(this IFreeSql that) { - return new RepositoryUnitOfWork(that); - } + /// + /// 创建基于仓储功能的工作单元,务必使用 using 包含使用 + /// + /// + /// + public static IRepositoryUnitOfWork CreateUnitOfWork(this IFreeSql that) + { + return new RepositoryUnitOfWork(that); + } } \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 5ecbd52d..78021b76 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -4,157 +4,185 @@ using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public abstract class BaseRepository : IBaseRepository - where TEntity : class { +namespace FreeSql +{ + public abstract class BaseRepository : IBaseRepository + where TEntity : class + { - internal RepositoryDbContext _dbPriv; - internal RepositoryDbContext _db => _dbPriv ?? (_dbPriv = new RepositoryDbContext(Orm, this)); - internal RepositoryDbSet _dbsetPriv; - internal RepositoryDbSet _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set() as RepositoryDbSet); - public IDataFilter DataFilter { get; } = new DataFilter(); - Func _asTableVal; - protected Func AsTable { - get => _asTableVal; - set { - _asTableVal = value; - AsTableSelect = value == null ? null : new Func((a, b) => a == EntityType ? value(b) : null); - } - } - internal Func AsTableInternal => AsTable; - protected Func AsTableSelect { get; private set; } - internal Func AsTableSelectInternal => AsTableSelect; + internal RepositoryDbContext _dbPriv; + internal RepositoryDbContext _db => _dbPriv ?? (_dbPriv = new RepositoryDbContext(Orm, this)); + internal RepositoryDbSet _dbsetPriv; + internal RepositoryDbSet _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set() as RepositoryDbSet); + public IDataFilter DataFilter { get; } = new DataFilter(); + Func _asTableVal; + protected Func AsTable + { + get => _asTableVal; + set + { + _asTableVal = value; + AsTableSelect = value == null ? null : new Func((a, b) => a == EntityType ? value(b) : null); + } + } + internal Func AsTableInternal => AsTable; + protected Func AsTableSelect { get; private set; } + internal Func AsTableSelectInternal => AsTableSelect; - protected void ApplyDataFilter(string name, Expression> exp) => DataFilter.Apply(name, exp); + protected void ApplyDataFilter(string name, Expression> exp) => DataFilter.Apply(name, exp); - protected BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) { - Orm = fsql; - DataFilterUtil.SetRepositoryDataFilter(this, null); - DataFilter.Apply("", filter); - AsTable = asTable; - } + protected BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) + { + Orm = fsql; + DataFilterUtil.SetRepositoryDataFilter(this, null); + DataFilter.Apply("", filter); + AsTable = asTable; + } - ~BaseRepository() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - _dbsetPriv?.Dispose(); - _dbPriv?.Dispose(); - this.DataFilter.Dispose(); - } finally { - _isdisposed = true; - GC.SuppressFinalize(this); - } - } - public Type EntityType => _dbsetPriv?.EntityType ?? typeof(TEntity); - public void AsType(Type entityType) => _dbset.AsType(entityType); + ~BaseRepository() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + try + { + _dbsetPriv?.Dispose(); + _dbPriv?.Dispose(); + this.DataFilter.Dispose(); + } + finally + { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + public Type EntityType => _dbsetPriv?.EntityType ?? typeof(TEntity); + public void AsType(Type entityType) => _dbset.AsType(entityType); - public IFreeSql Orm { get; private set; } - public IUnitOfWork UnitOfWork { get; set; } - public IUpdate UpdateDiy => _dbset.OrmUpdateInternal(null); + public IFreeSql Orm { get; private set; } + public IUnitOfWork UnitOfWork { get; set; } + public IUpdate UpdateDiy => _dbset.OrmUpdateInternal(null); - public ISelect Select => _dbset.OrmSelectInternal(null); - public ISelect Where(Expression> exp) => _dbset.OrmSelectInternal(null).Where(exp); - public ISelect WhereIf(bool condition, Expression> exp) => _dbset.OrmSelectInternal(null).WhereIf(condition, exp); + public ISelect Select => _dbset.OrmSelectInternal(null); + public ISelect Where(Expression> exp) => _dbset.OrmSelectInternal(null).Where(exp); + public ISelect WhereIf(bool condition, Expression> exp) => _dbset.OrmSelectInternal(null).WhereIf(condition, exp); - public int Delete(Expression> predicate) => _dbset.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows(); - public Task DeleteAsync(Expression> predicate) => _dbset.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync(); + public int Delete(Expression> predicate) => _dbset.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows(); + public Task DeleteAsync(Expression> predicate) => _dbset.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync(); - public int Delete(TEntity entity) { - _dbset.Remove(entity); - return _db.SaveChanges(); - } - public Task DeleteAsync(TEntity entity) { - _dbset.Remove(entity); - return _db.SaveChangesAsync(); - } - public int Delete(IEnumerable entitys) { - _dbset.RemoveRange(entitys); - return _db.SaveChanges(); - } - public Task DeleteAsync(IEnumerable entitys) { - _dbset.RemoveRange(entitys); - return _db.SaveChangesAsync(); - } + public int Delete(TEntity entity) + { + _dbset.Remove(entity); + return _db.SaveChanges(); + } + public Task DeleteAsync(TEntity entity) + { + _dbset.Remove(entity); + return _db.SaveChangesAsync(); + } + public int Delete(IEnumerable entitys) + { + _dbset.RemoveRange(entitys); + return _db.SaveChanges(); + } + public Task DeleteAsync(IEnumerable entitys) + { + _dbset.RemoveRange(entitys); + return _db.SaveChangesAsync(); + } - public virtual TEntity Insert(TEntity entity) { - _dbset.Add(entity); - _db.SaveChanges(); - return entity; - } - async public virtual Task InsertAsync(TEntity entity) { - await _dbset.AddAsync(entity); - _db.SaveChanges(); - return entity; - } - public virtual List Insert(IEnumerable entitys) { - _dbset.AddRange(entitys); - _db.SaveChanges(); - return entitys.ToList(); - } - async public virtual Task> InsertAsync(IEnumerable entitys) { - await _dbset.AddRangeAsync(entitys); - await _db.SaveChangesAsync(); - return entitys.ToList(); - } + public virtual TEntity Insert(TEntity entity) + { + _dbset.Add(entity); + _db.SaveChanges(); + return entity; + } + async public virtual Task InsertAsync(TEntity entity) + { + await _dbset.AddAsync(entity); + _db.SaveChanges(); + return entity; + } + public virtual List Insert(IEnumerable entitys) + { + _dbset.AddRange(entitys); + _db.SaveChanges(); + return entitys.ToList(); + } + async public virtual Task> InsertAsync(IEnumerable entitys) + { + await _dbset.AddRangeAsync(entitys); + await _db.SaveChangesAsync(); + return entitys.ToList(); + } - public int Update(TEntity entity) { - _dbset.Update(entity); - return _db.SaveChanges(); - } - public Task UpdateAsync(TEntity entity) { - _dbset.Update(entity); - return _db.SaveChangesAsync(); - } - public int Update(IEnumerable entitys) { - _dbset.UpdateRange(entitys); - return _db.SaveChanges(); - } - public Task UpdateAsync(IEnumerable entitys) { - _dbset.UpdateRange(entitys); - return _db.SaveChangesAsync(); - } + public int Update(TEntity entity) + { + _dbset.Update(entity); + return _db.SaveChanges(); + } + public Task UpdateAsync(TEntity entity) + { + _dbset.Update(entity); + return _db.SaveChangesAsync(); + } + public int Update(IEnumerable entitys) + { + _dbset.UpdateRange(entitys); + return _db.SaveChanges(); + } + public Task UpdateAsync(IEnumerable entitys) + { + _dbset.UpdateRange(entitys); + return _db.SaveChangesAsync(); + } - public void Attach(TEntity data) => _db.Attach(data); - public void Attach(IEnumerable data) => _db.AttachRange(data); - public void FlushState() => _dbset.FlushState(); + public void Attach(TEntity data) => _db.Attach(data); + public void Attach(IEnumerable data) => _db.AttachRange(data); + public void FlushState() => _dbset.FlushState(); - public TEntity InsertOrUpdate(TEntity entity) { - _dbset.AddOrUpdate(entity); - _db.SaveChanges(); - return entity; - } - async public Task InsertOrUpdateAsync(TEntity entity) { - await _dbset.AddOrUpdateAsync(entity); - _db.SaveChanges(); - return entity; - } - } + public TEntity InsertOrUpdate(TEntity entity) + { + _dbset.AddOrUpdate(entity); + _db.SaveChanges(); + return entity; + } + async public Task InsertOrUpdateAsync(TEntity entity) + { + await _dbset.AddOrUpdateAsync(entity); + _db.SaveChanges(); + return entity; + } + } - public abstract class BaseRepository : BaseRepository, IBaseRepository - where TEntity : class { + public abstract class BaseRepository : BaseRepository, IBaseRepository + where TEntity : class + { - public BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base(fsql, filter, asTable) { - } + public BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base(fsql, filter, asTable) + { + } - public int Delete(TKey id) { - var stateKey = string.Concat(id); - _dbset._statesInternal.TryRemove(stateKey, out var trystate); - return _dbset.OrmDeleteInternal(id).ExecuteAffrows(); - } - public Task DeleteAsync(TKey id) { - var stateKey = string.Concat(id); - _dbset._statesInternal.TryRemove(stateKey, out var trystate); - return _dbset.OrmDeleteInternal(id).ExecuteAffrowsAsync(); - } + public int Delete(TKey id) + { + var stateKey = string.Concat(id); + _dbset._statesInternal.TryRemove(stateKey, out var trystate); + return _dbset.OrmDeleteInternal(id).ExecuteAffrows(); + } + public Task DeleteAsync(TKey id) + { + var stateKey = string.Concat(id); + _dbset._statesInternal.TryRemove(stateKey, out var trystate); + return _dbset.OrmDeleteInternal(id).ExecuteAffrowsAsync(); + } - public TEntity Find(TKey id) => _dbset.OrmSelectInternal(id).ToOne(); - public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(id).ToOneAsync(); + public TEntity Find(TKey id) => _dbset.OrmSelectInternal(id).ToOne(); + public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(id).ToOneAsync(); - public TEntity Get(TKey id) => Find(id); - public Task GetAsync(TKey id) => FindAsync(id); - } + public TEntity Get(TKey id) => Find(id); + public Task GetAsync(TKey id) => FindAsync(id); + } } diff --git a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs index 8a711e2f..a1f69e07 100644 --- a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs @@ -1,16 +1,20 @@ using System; using System.Linq.Expressions; -namespace FreeSql { - public class DefaultRepository : - BaseRepository - where TEntity : class { +namespace FreeSql +{ + public class DefaultRepository : + BaseRepository + where TEntity : class + { - public DefaultRepository(IFreeSql fsql) : base(fsql, null, null) { + public DefaultRepository(IFreeSql fsql) : base(fsql, null, null) + { - } + } - public DefaultRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter, null) { - } - } + public DefaultRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter, null) + { + } + } } diff --git a/FreeSql.DbContext/Repository/Repository/GuidRepository.cs b/FreeSql.DbContext/Repository/Repository/GuidRepository.cs index f7eba195..1025f961 100644 --- a/FreeSql.DbContext/Repository/Repository/GuidRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/GuidRepository.cs @@ -1,15 +1,19 @@ using System; using System.Linq.Expressions; -namespace FreeSql { - public class GuidRepository : - BaseRepository - where TEntity : class { +namespace FreeSql +{ + public class GuidRepository : + BaseRepository + where TEntity : class + { - public GuidRepository(IFreeSql fsql) : this(fsql, null, null) { + public GuidRepository(IFreeSql fsql) : this(fsql, null, null) + { - } - public GuidRepository(IFreeSql fsql, Expression> filter, Func asTable) : base(fsql, filter, asTable) { - } - } + } + public GuidRepository(IFreeSql fsql, Expression> filter, Func asTable) : base(fsql, filter, asTable) + { + } + } } diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index f1919f29..432697d8 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -2,29 +2,33 @@ using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { +namespace FreeSql +{ - public interface IBaseRepository : IDisposable { - Type EntityType { get; } - IUnitOfWork UnitOfWork { get; set; } - IFreeSql Orm { get; } + public interface IBaseRepository : IDisposable + { + Type EntityType { get; } + IUnitOfWork UnitOfWork { get; set; } + IFreeSql Orm { get; } - /// - /// 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 - /// - /// - /// - void AsType(Type entityType); - } + /// + /// 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 + /// + /// + /// + void AsType(Type entityType); + } - public interface IBaseRepository : IReadOnlyRepository, IBasicRepository - where TEntity : class { - int Delete(Expression> predicate); + public interface IBaseRepository : IReadOnlyRepository, IBasicRepository + where TEntity : class + { + int Delete(Expression> predicate); - Task DeleteAsync(Expression> predicate); - } + Task DeleteAsync(Expression> predicate); + } - public interface IBaseRepository : IBaseRepository, IReadOnlyRepository, IBasicRepository - where TEntity : class { - } + public interface IBaseRepository : IBaseRepository, IReadOnlyRepository, IBasicRepository + where TEntity : class + { + } } \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs index 33d79ec6..21aecb89 100644 --- a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs @@ -1,45 +1,48 @@ using System.Collections.Generic; using System.Threading.Tasks; -namespace FreeSql { - public interface IBasicRepository : IReadOnlyRepository - where TEntity : class { - TEntity Insert(TEntity entity); - List Insert(IEnumerable entitys); - Task InsertAsync(TEntity entity); - Task> InsertAsync(IEnumerable entitys); +namespace FreeSql +{ + public interface IBasicRepository : IReadOnlyRepository + where TEntity : class + { + TEntity Insert(TEntity entity); + List Insert(IEnumerable entitys); + Task InsertAsync(TEntity entity); + Task> InsertAsync(IEnumerable entitys); - /// - /// 清空状态数据 - /// - void FlushState(); - /// - /// 附加实体,可用于不查询就更新或删除 - /// - /// - void Attach(TEntity entity); - void Attach(IEnumerable entity); - int Update(TEntity entity); - int Update(IEnumerable entitys); - Task UpdateAsync(TEntity entity); - Task UpdateAsync(IEnumerable entitys); + /// + /// 清空状态数据 + /// + void FlushState(); + /// + /// 附加实体,可用于不查询就更新或删除 + /// + /// + void Attach(TEntity entity); + void Attach(IEnumerable entity); + int Update(TEntity entity); + int Update(IEnumerable entitys); + Task UpdateAsync(TEntity entity); + Task UpdateAsync(IEnumerable entitys); - TEntity InsertOrUpdate(TEntity entity); - Task InsertOrUpdateAsync(TEntity entity); + TEntity InsertOrUpdate(TEntity entity); + Task InsertOrUpdateAsync(TEntity entity); - IUpdate UpdateDiy { get; } + IUpdate UpdateDiy { get; } - int Delete(TEntity entity); - int Delete(IEnumerable entitys); - Task DeleteAsync(TEntity entity); - Task DeleteAsync(IEnumerable entitys); - } + int Delete(TEntity entity); + int Delete(IEnumerable entitys); + Task DeleteAsync(TEntity entity); + Task DeleteAsync(IEnumerable entitys); + } - public interface IBasicRepository : IBasicRepository, IReadOnlyRepository - where TEntity : class { - int Delete(TKey id); + public interface IBasicRepository : IBasicRepository, IReadOnlyRepository + where TEntity : class + { + int Delete(TKey id); - Task DeleteAsync(TKey id); - } + Task DeleteAsync(TKey id); + } } diff --git a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs b/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs index 8b2f47ee..76728a9c 100644 --- a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs @@ -2,26 +2,29 @@ using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface IReadOnlyRepository : IBaseRepository - where TEntity : class { +namespace FreeSql +{ + public interface IReadOnlyRepository : IBaseRepository + where TEntity : class + { - IDataFilter DataFilter { get; } + IDataFilter DataFilter { get; } - ISelect Select { get; } + ISelect Select { get; } - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - } + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + } - public interface IReadOnlyRepository : IReadOnlyRepository - where TEntity : class { - TEntity Get(TKey id); + public interface IReadOnlyRepository : IReadOnlyRepository + where TEntity : class + { + TEntity Get(TKey id); - Task GetAsync(TKey id); + Task GetAsync(TKey id); - TEntity Find(TKey id); + TEntity Find(TKey id); - Task FindAsync(TKey id); - } + Task FindAsync(TKey id); + } } diff --git a/FreeSql.DbContext/TempExtensions.cs b/FreeSql.DbContext/TempExtensions.cs index fbb7bd53..43528138 100644 --- a/FreeSql.DbContext/TempExtensions.cs +++ b/FreeSql.DbContext/TempExtensions.cs @@ -1,5 +1,7 @@  -namespace FreeSql.Extensions.EntityUtil { - public static class TempExtensions { - } +namespace FreeSql.Extensions.EntityUtil +{ + public static class TempExtensions + { + } } diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index 8ded92ff..ca1a7acd 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -2,12 +2,14 @@ using System.Data; using System.Data.Common; -namespace FreeSql { - public interface IUnitOfWork : IDisposable { +namespace FreeSql +{ + public interface IUnitOfWork : IDisposable + { - DbTransaction GetOrBeginTransaction(bool isCreate = true); + DbTransaction GetOrBeginTransaction(bool isCreate = true); - IsolationLevel? IsolationLevel { get; set; } + IsolationLevel? IsolationLevel { get; set; } /// /// 是否启用工作单元 @@ -16,7 +18,7 @@ namespace FreeSql { void Commit(); - void Rollback(); + void Rollback(); /// /// 禁用工作单元 diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 5cbaf016..a11edae8 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -3,22 +3,26 @@ using System; using System.Data; using System.Data.Common; -namespace FreeSql { - class UnitOfWork : IUnitOfWork { +namespace FreeSql +{ + class UnitOfWork : IUnitOfWork + { - protected IFreeSql _fsql; - protected Object _conn; - protected DbTransaction _tran; + protected IFreeSql _fsql; + protected Object _conn; + protected DbTransaction _tran; - public UnitOfWork(IFreeSql fsql) { - _fsql = fsql; - } + public UnitOfWork(IFreeSql fsql) + { + _fsql = fsql; + } - void ReturnObject() { - _fsql.Ado.MasterPool.Return(_conn); - _tran = null; - _conn = null; - } + void ReturnObject() + { + _fsql.Ado.MasterPool.Return(_conn); + _tran = null; + _conn = null; + } /// @@ -49,55 +53,74 @@ namespace FreeSql { public IsolationLevel? IsolationLevel { get; set; } - public DbTransaction GetOrBeginTransaction(bool isCreate = true) { + public DbTransaction GetOrBeginTransaction(bool isCreate = true) + { - if (_tran != null) return _tran; - if (isCreate == false) return null; + if (_tran != null) return _tran; + if (isCreate == false) return null; if (!Enable) return null; - if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); + if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); - _conn = _fsql.Ado.MasterPool.Get(); - try { - _tran = IsolationLevel == null ? - _conn.Value.BeginTransaction() : - _conn.Value.BeginTransaction(IsolationLevel.Value); - } catch { - ReturnObject(); - throw; - } - return _tran; - } + _conn = _fsql.Ado.MasterPool.Get(); + try + { + _tran = IsolationLevel == null ? + _conn.Value.BeginTransaction() : + _conn.Value.BeginTransaction(IsolationLevel.Value); + } + catch + { + ReturnObject(); + throw; + } + return _tran; + } - public void Commit() { - if (_tran != null) { - try { - _tran.Commit(); - } finally { - ReturnObject(); - } - } - } - public void Rollback() { - if (_tran != null) { - try { - _tran.Rollback(); - } finally { - ReturnObject(); - } - } - } - ~UnitOfWork() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - this.Rollback(); - } finally { - _isdisposed = true; - GC.SuppressFinalize(this); - } - } - } + public void Commit() + { + if (_tran != null) + { + try + { + _tran.Commit(); + } + finally + { + ReturnObject(); + } + } + } + public void Rollback() + { + if (_tran != null) + { + try + { + _tran.Rollback(); + } + finally + { + ReturnObject(); + } + } + } + ~UnitOfWork() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + try + { + this.Rollback(); + } + finally + { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index da499384..b2be4440 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -1,118 +1,132 @@ using System; using Xunit; -namespace FreeSql.Tests { - public class RepositoryTests { +namespace FreeSql.Tests +{ + public class RepositoryTests + { - [Fact] - public void AddUpdate() { - var repos = g.sqlite.GetGuidRepository(); + [Fact] + public void AddUpdate() + { + var repos = g.sqlite.GetGuidRepository(); - var item = repos.Insert(new AddUpdateInfo()); - Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + var item = repos.Insert(new AddUpdateInfo()); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); - item = repos.Insert(new AddUpdateInfo { Id = Guid.NewGuid() }); - Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + item = repos.Insert(new AddUpdateInfo { Id = Guid.NewGuid() }); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); - item.Title = "xxx"; - repos.Update(item); - Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + item.Title = "xxx"; + repos.Update(item); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); - Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql()); - repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows(); + Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql()); + repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows(); - item = repos.Find(item.Id); - Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); - } + item = repos.Find(item.Id); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + } - [Fact] - public void UpdateAttach() { - var repos = g.sqlite.GetGuidRepository(); + [Fact] + public void UpdateAttach() + { + var repos = g.sqlite.GetGuidRepository(); - var item = new AddUpdateInfo { Id = Guid.NewGuid() }; - repos.Attach(item); + var item = new AddUpdateInfo { Id = Guid.NewGuid() }; + repos.Attach(item); - item.Title = "xxx"; - repos.Update(item); - Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + item.Title = "xxx"; + repos.Update(item); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); - Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql()); - repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows(); + Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql()); + repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows(); - item = repos.Find(item.Id); - Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); - } + item = repos.Find(item.Id); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + } - [Fact] - public void UpdateWhenNotExists() { - var repos = g.sqlite.GetGuidRepository(); + [Fact] + public void UpdateWhenNotExists() + { + var repos = g.sqlite.GetGuidRepository(); - var item = new AddUpdateInfo { Id = Guid.NewGuid() }; - item.Title = "xxx"; - Assert.Throws(() => repos.Update(item)); - } + var item = new AddUpdateInfo { Id = Guid.NewGuid() }; + item.Title = "xxx"; + Assert.Throws(() => repos.Update(item)); + } - [Fact] - public void Update() { - g.sqlite.Insert(new AddUpdateInfo()).ExecuteAffrows(); + [Fact] + public void Update() + { + g.sqlite.Insert(new AddUpdateInfo()).ExecuteAffrows(); - var repos = g.sqlite.GetGuidRepository(); + var repos = g.sqlite.GetGuidRepository(); - var item = new AddUpdateInfo { Id = g.sqlite.Select().First().Id }; + var item = new AddUpdateInfo { Id = g.sqlite.Select().First().Id }; - item.Title = "xxx"; - repos.Update(item); - Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); - } + item.Title = "xxx"; + repos.Update(item); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + } - public class AddUpdateInfo { + public class AddUpdateInfo + { - public Guid Id { get; set; } - public string Title { get; set; } + public Guid Id { get; set; } + public string Title { get; set; } - public int Clicks { get; set; } = 10; - } + public int Clicks { get; set; } = 10; + } - [Fact] - public void UnitOfWorkRepository() { - foreach (var fsql in new[] { g.sqlite, /*g.mysql, g.pgsql, g.oracle, g.sqlserver*/ }) { + [Fact] + public void UnitOfWorkRepository() + { + foreach (var fsql in new[] { g.sqlite, /*g.mysql, g.pgsql, g.oracle, g.sqlserver*/ }) + { - fsql.CodeFirst.ConfigEntity(f => { - f.Property(b => b.UserId).IsPrimary(true); - f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); - f.Property(b => b.Name).IsNullable(false); - }); + fsql.CodeFirst.ConfigEntity(f => + { + f.Property(b => b.UserId).IsPrimary(true); + f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); + f.Property(b => b.Name).IsNullable(false); + }); - FlowModel flow = new FlowModel() { - CreateTime = DateTime.Now, - Name = "aaa", - LastModifyTime = DateTime.Now, - UserId = 1, - }; - var flowRepos = fsql.GetRepository(); - flowRepos.Insert(flow); + FlowModel flow = new FlowModel() + { + CreateTime = DateTime.Now, + Name = "aaa", + LastModifyTime = DateTime.Now, + UserId = 1, + }; + var flowRepos = fsql.GetRepository(); + flowRepos.Insert(flow); - // - flow = new FlowModel() { - CreateTime = DateTime.Now, - Name = "aaa", - LastModifyTime = DateTime.Now, - UserId = 1, - }; - using (var uow = fsql.CreateUnitOfWork()) { - flowRepos = uow.GetRepository(); - flowRepos.Insert(flow); - uow.Commit(); - } + // + flow = new FlowModel() + { + CreateTime = DateTime.Now, + Name = "aaa", + LastModifyTime = DateTime.Now, + UserId = 1, + }; + using (var uow = fsql.CreateUnitOfWork()) + { + flowRepos = uow.GetRepository(); + flowRepos.Insert(flow); + uow.Commit(); + } } - } + } [Fact] public void UnitOfWorkRepositoryWithDisableBeforeInsert() { - foreach (var fsql in new[] { g.sqlite, }) + foreach (var fsql in new[] { g.sqlite, }) { - fsql.CodeFirst.ConfigEntity(f => { + fsql.CodeFirst.ConfigEntity(f => + { f.Property(b => b.UserId).IsPrimary(true); f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); f.Property(b => b.Name).IsNullable(false); @@ -129,7 +143,7 @@ namespace FreeSql.Tests { }; //ݿѴڵݣΪ˽IJ - flowRepos.Delete(a => a.UserId == 1 &&a.Name== "aaa"); + flowRepos.Delete(a => a.UserId == 1 && a.Name == "aaa"); using (var uow = fsql.CreateUnitOfWork()) { @@ -140,7 +154,7 @@ namespace FreeSql.Tests { //ѹرչԪ᲻ύûӰ죬˴עȷԪǷЧرˣCommitҲӦò //uow.Commit(); } - + Assert.True(flowRepos.Select.Any(a => a.UserId == 1 && a.Name == "aaa")); } @@ -149,7 +163,7 @@ namespace FreeSql.Tests { [Fact] public void UnitOfWorkRepositoryWithDisableAfterInsert() { - foreach (var fsql in new[] {g.sqlite,}) + foreach (var fsql in new[] { g.sqlite, }) { fsql.CodeFirst.ConfigEntity(f => { @@ -227,35 +241,37 @@ namespace FreeSql.Tests { } - public partial class FlowModel { - public int UserId { get; set; } - public int Id { get; set; } - public int? ParentId { get; set; } - public string Name { get; set; } - public DateTime CreateTime { get; set; } - public DateTime LastModifyTime { get; set; } - public string Desc { get; set; } - } + public partial class FlowModel + { + public int UserId { get; set; } + public int Id { get; set; } + public int? ParentId { get; set; } + public string Name { get; set; } + public DateTime CreateTime { get; set; } + public DateTime LastModifyTime { get; set; } + public string Desc { get; set; } + } - [Fact] - public void AsType() { - g.sqlite.Insert(new AddUpdateInfo()).ExecuteAffrows(); + [Fact] + public void AsType() + { + g.sqlite.Insert(new AddUpdateInfo()).ExecuteAffrows(); - var repos = g.sqlite.GetGuidRepository(); - repos.AsType(typeof(AddUpdateInfo)); + var repos = g.sqlite.GetGuidRepository(); + repos.AsType(typeof(AddUpdateInfo)); - var item = new AddUpdateInfo(); - repos.Insert(item); - repos.Update(item); + var item = new AddUpdateInfo(); + repos.Insert(item); + repos.Update(item); - item.Clicks += 1; - repos.InsertOrUpdate(item); + item.Clicks += 1; + repos.InsertOrUpdate(item); - var item2 = repos.Find(item.Id) as AddUpdateInfo; - Assert.Equal(item.Clicks, item2.Clicks); + var item2 = repos.Find(item.Id) as AddUpdateInfo; + Assert.Equal(item.Clicks, item2.Clicks); - repos.DataFilter.Apply("xxx", a => (a as AddUpdateInfo).Clicks == 2); - Assert.Null(repos.Find(item.Id)); - } - } + repos.DataFilter.Apply("xxx", a => (a as AddUpdateInfo).Clicks == 2); + Assert.Null(repos.Find(item.Id)); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index 0bbc0c4a..ea2a7435 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -6,155 +6,175 @@ using Xunit; using System.Linq; using Newtonsoft.Json.Linq; -namespace FreeSql.Tests { - public class UnitTest1 { +namespace FreeSql.Tests +{ + public class UnitTest1 + { - class testenumWhere { - public Guid id { get; set; } - public testenumWhereType type { get; set; } - } - public enum testenumWhereType { Menu, Class, Blaaa } + class testenumWhere + { + public Guid id { get; set; } + public testenumWhereType type { get; set; } + } + public enum testenumWhereType { Menu, Class, Blaaa } - [Fact] - public void Include_ManyToMany() { + [Fact] + public void Include_ManyToMany() + { - g.sqlite.CodeFirst.SyncStructure(); - g.sqlite.CodeFirst.SyncStructure(); - g.sqlite.CodeFirst.SyncStructure(); + g.sqlite.CodeFirst.SyncStructure(); + g.sqlite.CodeFirst.SyncStructure(); + g.sqlite.CodeFirst.SyncStructure(); - using (var ctx = g.sqlite.CreateDbContext()) { + using (var ctx = g.sqlite.CreateDbContext()) + { - var songs = ctx.Set().Select - .IncludeMany(a => a.Tags) - .ToList(); + var songs = ctx.Set().Select + .IncludeMany(a => a.Tags) + .ToList(); - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_01_й" - }; - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_02_" - }; - var tag3 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_03_ձ" - }; - ctx.AddRange(new[] { tag1, tag2, tag3 }); + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_й" + }; + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_" + }; + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_ձ" + }; + ctx.AddRange(new[] { tag1, tag2, tag3 }); - var song1 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_01_й.mp3", - Url = "http://ww.baidu.com/" - }; - var song2 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_02_һ.mp3", - Url = "http://ww.163.com/" - }; - var song3 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_03_ǧһ.mp3", - Url = "http://ww.sina.com/" - }; - ctx.AddRange(new[] { song1, song2, song3 }); + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_й.mp3", + Url = "http://ww.baidu.com/" + }; + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_һ.mp3", + Url = "http://ww.163.com/" + }; + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_ǧһ.mp3", + Url = "http://ww.sina.com/" + }; + ctx.AddRange(new[] { song1, song2, song3 }); - ctx.AddRange( - new[] { - new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }, - new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }, - new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }, - new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }, - new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }, - new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }, - } - ); - ctx.SaveChanges(); - } - } + ctx.AddRange( + new[] { + new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }, + new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }, + new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }, + new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }, + new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }, + new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }, + } + ); + ctx.SaveChanges(); + } + } - [Fact] - public void Add() { + [Fact] + public void Add() + { - g.sqlite.SetDbContextOptions(opt => { - //opt.EnableAddOrUpdateNavigateList = false; - }); + g.sqlite.SetDbContextOptions(opt => + { + //opt.EnableAddOrUpdateNavigateList = false; + }); - g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); + g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); - var sql = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); - var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); + var sql = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); + var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); - //֧ 1Զ + //֧ 1Զ - using (var ctx = new FreeContext(g.sqlite)) { + using (var ctx = new FreeContext(g.sqlite)) + { - var tags = ctx.Set().Select.IncludeMany(a => a.Tags).ToList(); + var tags = ctx.Set().Select.IncludeMany(a => a.Tags).ToList(); - var tag = new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } - } - }; - ctx.Add(tag); - ctx.SaveChanges(); - } - } + var tag = new Tag + { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", + Tags = new[] { + new Tag { Name = "sub3_01" } + } + } + } + }; + ctx.Add(tag); + ctx.SaveChanges(); + } + } - [Fact] - public void Update() { - //ѯ 1Զ࣬ + [Fact] + public void Update() + { + //ѯ 1Զ࣬ - using (var ctx = new FreeContext(g.sqlite)) { + using (var ctx = new FreeContext(g.sqlite)) + { - var tag = ctx.Set().Select.First(); - tag.Tags.Add(new Tag { Name = "sub3" }); - ctx.Update(tag); - ctx.SaveChanges(); - } - } + var tag = ctx.Set().Select.First(); + tag.Tags.Add(new Tag { Name = "sub3" }); + ctx.Update(tag); + ctx.SaveChanges(); + } + } - public class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } + public class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } - public virtual ICollection Tags { get; set; } + public virtual ICollection Tags { get; set; } - [Column(IsVersion = true)] - public long versionRow { get; set; } - } - public class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } + [Column(IsVersion = true)] + public long versionRow { get; set; } + } + public class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } - } + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } - public class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } + public class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } - public decimal? Ddd { get; set; } - public string Name { get; set; } + public decimal? Ddd { get; set; } + public string Name { get; set; } - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } - } - } + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs index 4aec7356..6bb48a5e 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs @@ -4,83 +4,94 @@ using System.Diagnostics; using System.Text; -public class g { +public class g +{ - static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseLazyLoading(true) - .UseNoneCommandParameter(true) - .Build()); - public static IFreeSql sqlserver => sqlserverLazy.Value; + static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .UseNoneCommandParameter(true) + .Build()); + public static IFreeSql sqlserver => sqlserverLazy.Value; - static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .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") - .UseAutoSyncStructure(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseLazyLoading(true) - .UseNoneCommandParameter(true) - .Build()); - public static IFreeSql mysql => mysqlLazy.Value; + static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .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") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .UseNoneCommandParameter(true) + .Build()); + public static IFreeSql mysql => mysqlLazy.Value; - static Lazy pgsqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") - .UseAutoSyncStructure(true) - .UseSyncStructureToLower(true) - .UseLazyLoading(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseNoneCommandParameter(true) - .Build()); - public static IFreeSql pgsql => pgsqlLazy.Value; + static Lazy pgsqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") + .UseAutoSyncStructure(true) + .UseSyncStructureToLower(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseNoneCommandParameter(true) + .Build()); + public static IFreeSql pgsql => pgsqlLazy.Value; - static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseSyncStructureToUpper(true) - .UseNoneCommandParameter(true) + static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseSyncStructureToUpper(true) + .UseNoneCommandParameter(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build()); - public static IFreeSql oracle => oracleLazy.Value; + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .Build()); + public static IFreeSql oracle => oracleLazy.Value; - static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|/document22.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseNoneCommandParameter(true) - .Build()); - public static IFreeSql sqlite => sqliteLazy.Value; + static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|/document22.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseNoneCommandParameter(true) + .Build()); + public static IFreeSql sqlite => sqliteLazy.Value; } diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs index e523097f..147241ad 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs @@ -9,191 +9,216 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Threading; -namespace FreeSql.Tests.PerformanceTest { - public class MySqlAdoTest { +namespace FreeSql.Tests.PerformanceTest +{ + public class MySqlAdoTest + { - [Fact] - public void Query() { - var sb = new StringBuilder(); - var time = new Stopwatch(); + [Fact] + public void Query() + { + var sb = new StringBuilder(); + var time = new Stopwatch(); - time.Restart(); - List dplist1 = null; - using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); + time.Restart(); + List dplist1 = null; + using (var conn = g.mysql.Ado.MasterPool.Get()) + { + dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); - time.Restart(); - List<(int, string, string)> dplist2 = null; - using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist2 = Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from song").ToList(); - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {dplist2.Count}; ORM: Dapper"); + time.Restart(); + List<(int, string, string)> dplist2 = null; + using (var conn = g.mysql.Ado.MasterPool.Get()) + { + dplist2 = Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from song").ToList(); + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {dplist2.Count}; ORM: Dapper"); - time.Restart(); - List dplist3 = null; - using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist3 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {dplist3.Count}; ORM: Dapper"); + time.Restart(); + List dplist3 = null; + using (var conn = g.mysql.Ado.MasterPool.Get()) + { + dplist3 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {dplist3.Count}; ORM: Dapper"); - var t31 = g.mysql.Ado.Query("select * from song limit 1"); + var t31 = g.mysql.Ado.Query("select * from song limit 1"); - time.Restart(); - var t3 = g.mysql.Ado.Query("select * from song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {t3.Count}; ORM: FreeSql*"); + time.Restart(); + var t3 = g.mysql.Ado.Query("select * from song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {t3.Count}; ORM: FreeSql*"); - time.Restart(); - var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*"); + time.Restart(); + var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*"); - time.Restart(); - var t41 = g.mysql.Select().ToList<(int, string, string)>("id,title,url"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query ToList Counts: {t41.Count}; ORM: FreeSql*"); + time.Restart(); + var t41 = g.mysql.Select().ToList<(int, string, string)>("id,title,url"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query ToList Counts: {t41.Count}; ORM: FreeSql*"); - time.Restart(); - var t5 = g.mysql.Ado.Query("select * from song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*"); + time.Restart(); + var t5 = g.mysql.Ado.Query("select * from song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*"); - } + } - [Fact] - public void QueryLimit10() { - var sb = new StringBuilder(); - var time = new Stopwatch(); + [Fact] + public void QueryLimit10() + { + var sb = new StringBuilder(); + var time = new Stopwatch(); - time.Restart(); - List dplist1 = new List(); - for (var a = 0; a < 10000; a++) { - using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist1.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 10").ToList()); - } - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); + time.Restart(); + List dplist1 = new List(); + for (var a = 0; a < 10000; a++) + { + using (var conn = g.mysql.Ado.MasterPool.Get()) + { + dplist1.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 10").ToList()); + } + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); - time.Restart(); - List<(int, string, string)> dplist2 = new List<(int, string, string)>(); - for (var a = 0; a < 10000; a++) { - using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist2.AddRange(Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from song limit 10").ToList()); - } - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {dplist2.Count}; ORM: Dapper"); + time.Restart(); + List<(int, string, string)> dplist2 = new List<(int, string, string)>(); + for (var a = 0; a < 10000; a++) + { + using (var conn = g.mysql.Ado.MasterPool.Get()) + { + dplist2.AddRange(Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from song limit 10").ToList()); + } + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {dplist2.Count}; ORM: Dapper"); - time.Restart(); - List dplist3 = new List(); - for (var a = 0; a < 10000; a++) { - using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist3.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 10").ToList()); - } - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {dplist3.Count}; ORM: Dapper"); + time.Restart(); + List dplist3 = new List(); + for (var a = 0; a < 10000; a++) + { + using (var conn = g.mysql.Ado.MasterPool.Get()) + { + dplist3.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 10").ToList()); + } + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {dplist3.Count}; ORM: Dapper"); - time.Restart(); - List t3 = new List(); - for (var a = 0; a < 10000; a++) { - t3.AddRange(g.mysql.Ado.Query("select * from song limit 10")); - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {t3.Count}; ORM: FreeSql*"); + time.Restart(); + List t3 = new List(); + for (var a = 0; a < 10000; a++) + { + t3.AddRange(g.mysql.Ado.Query("select * from song limit 10")); + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {t3.Count}; ORM: FreeSql*"); - time.Restart(); - List<(int, string, string)> t4 = new List<(int, string, string)>(); - for (var a = 0; a < 10000; a++) { - t4.AddRange(g.mysql.Ado.Query<(int, string, string)>("select * from song limit 10")); - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*"); + time.Restart(); + List<(int, string, string)> t4 = new List<(int, string, string)>(); + for (var a = 0; a < 10000; a++) + { + t4.AddRange(g.mysql.Ado.Query<(int, string, string)>("select * from song limit 10")); + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*"); - time.Restart(); - List t5 = new List(); - for (var a = 0; a < 10000; a++) { - t5.AddRange(g.mysql.Ado.Query("select * from song limit 10")); - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*"); + time.Restart(); + List t5 = new List(); + for (var a = 0; a < 10000; a++) + { + t5.AddRange(g.mysql.Ado.Query("select * from song limit 10")); + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*"); - } + } - [Fact] - public void ToList() { - var sb = new StringBuilder(); - var time = new Stopwatch(); + [Fact] + public void ToList() + { + var sb = new StringBuilder(); + var time = new Stopwatch(); - //var t31 = g.mysql.Select().ToList(); + //var t31 = g.mysql.Select().ToList(); - time.Restart(); - var t3 = g.mysql.Select().ToList(); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); + time.Restart(); + var t3 = g.mysql.Select().ToList(); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); - time.Restart(); - List dplist1 = null; - using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); - } + time.Restart(); + List dplist1 = null; + using (var conn = g.mysql.Ado.MasterPool.Get()) + { + dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); + } - [Fact] - public void ToListLimit10() { - var sb = new StringBuilder(); - var time = new Stopwatch(); + [Fact] + public void ToListLimit10() + { + var sb = new StringBuilder(); + var time = new Stopwatch(); - time.Restart(); - var t3Count = 0; - var p3 = Parallel.For(1, 50, b => { - List t3 = new List(); - for (var a = 0; a < 1000; a++) { - t3.AddRange(g.mysql.Select().Limit(50).ToList()); - } - Interlocked.Add(ref t3Count, t3.Count); - }); - while (p3.IsCompleted == false) ; - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3Count}; ORM: FreeSql*"); + time.Restart(); + var t3Count = 0; + var p3 = Parallel.For(1, 50, b => + { + List t3 = new List(); + for (var a = 0; a < 1000; a++) + { + t3.AddRange(g.mysql.Select().Limit(50).ToList()); + } + Interlocked.Add(ref t3Count, t3.Count); + }); + while (p3.IsCompleted == false) ; + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3Count}; ORM: FreeSql*"); - time.Restart(); - var dplist1Count = 0; - var p1 = Parallel.For(1, 50, b => { - List dplist1 = new List(); - for (var a = 0; a < 1000; a++) { - using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist1.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 50").ToList()); - } - } - Interlocked.Add(ref dplist1Count, dplist1.Count); - }); - while (p1.IsCompleted == false) ; - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1Count}; ORM: Dapper"); - } + time.Restart(); + var dplist1Count = 0; + var p1 = Parallel.For(1, 50, b => + { + List dplist1 = new List(); + for (var a = 0; a < 1000; a++) + { + using (var conn = g.mysql.Ado.MasterPool.Get()) + { + dplist1.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 50").ToList()); + } + } + Interlocked.Add(ref dplist1Count, dplist1.Count); + }); + while (p1.IsCompleted == false) ; + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1Count}; ORM: Dapper"); + } - [Table(Name = "song")] - class xxx { - public int Id { get; set; } - public string Title { get; set; } - //public string Url { get; set; } - public DateTime Create_time { get; set; } - public bool Is_deleted { get; set; } - } - } + [Table(Name = "song")] + class xxx + { + public int Id { get; set; } + public string Title { get; set; } + //public string Url { get; set; } + public DateTime Create_time { get; set; } + public bool Is_deleted { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/g.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/g.cs index ceb1c0a1..8a8d4d3e 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/g.cs @@ -3,31 +3,32 @@ using System.Collections.Generic; using System.Text; -public class g { +public class g +{ - public static IFreeSql mysql = new FreeSql.FreeSqlBuilder() - .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") - .UseAutoSyncStructure(false) - .Build(); + public static IFreeSql mysql = new FreeSql.FreeSqlBuilder() + .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") + .UseAutoSyncStructure(false) + .Build(); - //public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder() - // .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=10") - // .UseAutoSyncStructure(false) - // .Build(); + //public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder() + // .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=10") + // .UseAutoSyncStructure(false) + // .Build(); - //public static IFreeSql pgsql = new FreeSql.FreeSqlBuilder() - // .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") - // .UseAutoSyncStructure(false) - // .UseSyncStructureToLower(true) - // .Build(); + //public static IFreeSql pgsql = new FreeSql.FreeSqlBuilder() + // .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") + // .UseAutoSyncStructure(false) + // .UseSyncStructureToLower(true) + // .Build(); - //public static IFreeSql oracle = new FreeSql.FreeSqlBuilder() - // .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") - // .UseAutoSyncStructure(false) - // .Build(); + //public static IFreeSql oracle = new FreeSql.FreeSqlBuilder() + // .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") + // .UseAutoSyncStructure(false) + // .Build(); - //public static IFreeSql sqlite = new FreeSql.FreeSqlBuilder() - // .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") - // .UseAutoSyncStructure(false) - // .Build(); + //public static IFreeSql sqlite = new FreeSql.FreeSqlBuilder() + // .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") + // .UseAutoSyncStructure(false) + // .Build(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs index fe402ce3..52704fea 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs @@ -4,84 +4,93 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnector { - public class MySqlDeleteTest { +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlDeleteTest + { - IDelete delete => g.mysql.Delete(); //�������� + IDelete delete => g.mysql.Delete(); //�������� - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void Dywhere() { - Assert.Null(g.mysql.Delete().ToSql()); - var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); - sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); - sql = g.mysql.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - } + sql = g.mysql.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + } - [Fact] - public void Where() { - var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - var id = g.mysql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); - Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); - } - [Fact] - public void ExecuteDeleted() { + var id = g.mysql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { - //delete.Where(a => a.Id > 0).ExecuteDeleted(); - } + //delete.Where(a => a.Id > 0).ExecuteDeleted(); + } - [Fact] - public void AsTable() { - Assert.Null(g.mysql.Delete().ToSql()); - var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + [Fact] + public void AsTable() + { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); - sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); - sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); - sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); - } - } + sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs index ff222517..26ac73fa 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs @@ -4,132 +4,143 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnector { - public class MySqlInsertTest { +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlInsertTest + { - IInsert insert => g.mysql.Insert(); //�������� + IInsert insert => g.mysql.Insert(); //�������� - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestEnumInsertTb { - [Column(IsIdentity = true)] - public int id { get; set; } - public TestEnumInserTbType type { get; set; } - public DateTime time { get; set; } = new DateTime(); - } - enum TestEnumInserTbType { str1, biggit, sum211 } - - [Fact] - public void AppendData() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumInsertTb + { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumInserTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumInserTbType { str1, biggit, sum211 } - var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Now }).ToSql(); - Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES(@type_0, @time_0)", sql); + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ToSql(); - Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); - } + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Now }).ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES(@type_0, @time_0)", sql); - [Fact] - public void InsertColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + } - var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - } - [Fact] - public void IgnoreColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); - } - [Fact] - public void ExecuteAffrows() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); - Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); - } - [Fact] - public void ExecuteIdentity() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); - Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - var id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); - Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select< TestEnumInsertTb>().Where(a => a.id == id).First()?.type); - id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); - Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); - } - [Fact] - public void ExecuteInserted() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); - //insert.AppendData(items.First()).ExecuteInserted(); - } + var id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - [Fact] - public void AsTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + //insert.AppendData(items.First()).ExecuteInserted(); + } - var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); - } - } + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 19b22f96..ef2bda75 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -5,1227 +5,1307 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnector { - - public class MySqlSelectTest { - - ISelect select => g.mysql.Select(); - - [Table(Name = "tb_topic")] - public class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - [Column(OldName = "TypeGuid")] - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - - public virtual TopicFields Fields { get; set; } - } - public class TopicFields { - [Column(IsPrimary = true)] - public int TopicId { get; set; } - public virtual Topic Topic { get; set; } - } - public class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - - public int ParentId { get; set; } - public virtual TestTypeParentInfo Parent { get; set; } - - public string Name { get; set; } - - public virtual ICollection Topics { get; set; } - } - public class TestTypeParentInfo { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - - public partial class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } - - public virtual ICollection Tags { get; set; } - } - public partial class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } - - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } - } - public partial class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public decimal? Ddd { get; set; } - public string Name { get; set; } - - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } - } - - [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] - class TestInfo { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - - [Fact] - public void AsSelect() { - //OneToOne、ManyToOne - var t0 = g.mysql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 - //FROM `Tag` a - //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` - //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` - //WHERE (a__Parent__Parent.`Name` = '粤语') - - //OneToMany - var t1 = g.mysql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` - //FROM `Tag` a - //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) - - //ManyToMany - var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); - //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` - //FROM `Song` a - //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) - } - - [Fact] - public void Lazy() { - var tags = g.mysql.Select().Where(a => a.Parent.Name == "xxx") - .LeftJoin(a => a.Parent_id == a.Parent.Id) - .ToSql(); - - var songs = g.mysql.Select().Limit(10).ToList(); - } - - [Fact] - public void ToDataTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - - Assert.Equal(1, g.mysql.Insert().AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, g.mysql.Insert().AppendData(items).ExecuteAffrows()); - - //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //Assert.Equal(9989, g.mysql.Insert(items).ExecuteAffrows()); - - var dt1 = select.Limit(10).ToDataTable(); - var dt2 = select.Limit(10).ToDataTable("id, 111222"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); - } - - class TestDto { - public int id { get; set; } - public string name { get; set; } //这是join表的属性 - public int ParentId { get; set; } //这是join表的属性 - } - [Fact] - public void ToList() { - - var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto2 = select.Limit(10).ToList(a => new TestDto()); - var testDto3 = select.Limit(10).ToList(a => new TestDto { }); - var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); - var testDto5 = select.Limit(10).ToList(); - - var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); - var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); - var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); - var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); - - var t0 = select.Limit(50).ToList(); - - - var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - - - var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); - var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); - var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); - - //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( - // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, - // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") - //); - - //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) - //.Where(a => a.Id == 1).ToSql(); - - var sql4 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name == "xxx")).ToSql(); - //.Where(a => a.Id == 1).ToSql(); - - - var list111 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name != "xxx")); - var list111sql = list111.ToSql(); - var list111data = list111.ToList((a, b, c) => new { - a.Id, - title_substring = a.Title.Substring(0, 1), - a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new { - a.Id, - tp2 = a.Type.Name - }, - tp3 = new { - a.Id, - tp33 = new { - a.Id - } - } - }); - - var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); - var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); - var t11112 = g.mysql.Select().ToList(a => new { - a.Id, - a.Title, - a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new { - a.Id, - tp2 = a.Type.Name - }, - tp3 = new { - a.Id, - tp33 = new { - a.Id - } - } - - }); - - var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - - - var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); - - var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); - - g.mysql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); - var testGuidId5 = g.mysql.Select().ToList(); - var testGuidId6 = g.mysql.Select().ToList(a => a.id); - - var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); - var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); - } - class TestGuidIdToList { - public Guid id { get; set; } - public string title { get; set; } = Guid.NewGuid().ToString(); - } - [Fact] - public void ToOne() { - var testnotfind = select.Where("1=2").First(a => a.CreateTime); - Assert.Equal(default(DateTime), testnotfind); - } - [Fact] - public void ToSql() { - g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); - - var sql1 = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); - var sql2 = g.mysql.Select().Where(a => testenumWhereType.Blaaa == a.type).ToSql(); - - var sql3 = g.mysql.Select().Where(a => a.type.Equals(testenumWhereType.Blaaa)).ToSql(); - var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); - } - class testenumWhere { - public Guid id { get; set; } - public testenumWhereType type { get; set; } - } - public enum testenumWhereType { Menu, Class, Blaaa } - - [Fact] - public void Any() { - var count = select.Where(a => 1 == 1).Count(); - Assert.False(select.Where(a => 1 == 2).Any()); - Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); - - var sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && - select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - //.Offset(a.Id) - .Any() - ).Any(c => c.Id == a.Id + 10) - ); - var sql2222Tolist = sql2222.ToList(); - - var collectionSelect = select.Where(a => - a.Type.Guid == a.TypeGuid && - a.Type.Parent.Id == a.Type.ParentId && - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) - ); - collectionSelect.ToList(); - } - [Fact] - public void Count() { - var count = select.Where(a => 1 == 1).Count(); - select.Where(a => 1 == 1).Count(out var count2); - Assert.Equal(count, count2); - Assert.Equal(0, select.Where(a => 1 == 2).Count()); - } - [Fact] - public void Master() { - Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); - } - [Fact] - public void From() { - var query2 = select.From((s, b) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - ); - var sql2 = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid`", sql2); - query2.ToList(); - - var query3 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id) - ); - var sql3 = query3.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql3); - query3.ToList(); - } - [Fact] - public void LeftJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); - query.ToList(); - } - [Fact] - public void InnerJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //������� - query = select - .InnerJoin(a => a.Type.Guid == a.TypeGuid) - .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - query = select - .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .InnerJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .InnerJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); - query.ToList(); - - } - [Fact] - public void RightJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //������� - query = select - .RightJoin(a => a.Type.Guid == a.TypeGuid) - .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - query = select - .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .RightJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .RightJoin(a => a.TypeGuid == b.Guid) - .RightJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); - query.ToList(); - - } - [Fact] - public void Where() { - - var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); - var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); - var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); - - var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.Where(a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); - query.ToList(); - - query = select.Where(a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); - query.ToList(); - - //���û�е������ԣ��򵥶������ - query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TypeGuid` AND b.`Name` = 'typeTitle')", sql); - query.ToList(); - - query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TypeGuid`)", sql); - query.ToList(); - - query = select.Where((a, b, c) => c.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .Where(a => a.Id == 10 && c.Name == "xxx") - .Where(a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.Where("a.clicks > 100 and a.id = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = @id)", sql); - query.ToList(); - } - [Fact] - public void WhereIf() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.WhereIf(true, a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(true, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(true, "a.clicks > 100 and a.id = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = @id)", sql); - query.ToList(); - - // ==========================================WhereIf(false) - - //����е�������a.Type��a.Type.Parent ���ǵ������� - query = select.WhereIf(false, a => a.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - query2 = select.From((s, b, c) => s - .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(false, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(false, "a.clicks > 100 and a.id = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - } - [Fact] - public void WhereExists() { - var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); - - sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - - //.Offset(a.Id) - - .Any() - ).Any() - ).ToList(); - } - [Fact] - public void GroupBy() { - var groupby = select.From((s, b, c) => s - .Where(a => a.Id == 1) - ) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()) - .Offset(10) - .Limit(2) - .ToList(a => new { - a.Key.tt2, - cou1 = a.Count(), - arg1 = a.Avg(a.Key.mod4), - ccc2 = a.Key.tt2 ?? "now()", - //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") - ccc3 = a.Max(a.Value.Item3.Id) - }); - - var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); - - var aggsql1 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist1 = select - .GroupBy(a => a.Title) - .ToList(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToSql(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToList(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql3 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid), - sum3 = b.Sum(b.Value.Type.Parent.Id) - }); - } - [Fact] - public void ToAggregate() { - var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - } - - [Fact] - public void OrderBy() { - var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); - } - [Fact] - public void Skip_Offset() { - var sql = select.Offset(10).Limit(10).ToList(); - } - [Fact] - public void Take_Limit() { - var sql = select.Limit(10).ToList(); - } - [Fact] - public void Page() { - var sql1 = select.Page(1, 10).ToList(); - var sql2 = select.Page(2, 10).ToList(); - var sql3 = select.Page(3, 10).ToList(); - - var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); - var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); - var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); - } - [Fact] - public void Distinct() { - var t1 = select.Distinct().ToList(a => a.Title); - var t2 = select.Distinct().Limit(10).ToList(a => a.Title); - } - - [Fact] - public void Sum() { - } - [Fact] - public void Min() { - } - [Fact] - public void Max() { - } - [Fact] - public void Avg() { - } - [Fact] - public void As() { - } - - [Fact] - public void AsTable() { - - var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); - - Func tableRule = (type, oldname) => { - if (type == typeof(Topic)) return oldname + "AsTable1"; - else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; - return oldname + "AsTable"; - }; - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid`", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); - - query = select - .LeftJoin((a, b) => b.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` c ON c.`Id` = a__Type.`ParentId`", sql); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfoAsTable` c ON b.`ParentId` = c.`Id`", sql); - - //������϶����㲻�� - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); - } - - public class TestInclude_OneToManyModel1 { - [Column(IsIdentity = true)] - public int id { get; set; } - public virtual TestInclude_OneToManyModel2 model2 { get; set; } - - public string m1name { get; set; } - } - public class TestInclude_OneToManyModel2 { - [Column(IsPrimary = true)] - public int model2id { get; set; } - public virtual TestInclude_OneToManyModel1 model1 { get; set; } - - public string m2setting { get; set; } - - public List childs { get; set; } - } - public class TestInclude_OneToManyModel3 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model2111Idaaa { get; set; } - public string title { get; set; } - - public List childs2 { get; set; } - } - public class TestInclude_OneToManyModel4 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model3333Id333 { get; set; } - public string title444 { get; set; } - } - - [Fact] - public void Include_OneToMany() { - var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; - model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); - var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; - g.mysql.Insert(model2).ExecuteAffrows(); - - var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; - model3_1.id = (int)g.mysql.Insert(model3_1).ExecuteIdentity(); - var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; - model3_2.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); - var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; - model3_3.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); - - var model4s = new[] { - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } - }; - Assert.Equal(5, g.mysql.Insert(model4s).ExecuteAffrows()); - - var t0 = g.mysql.Select() - .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t1 = g.mysql.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t2 = g.mysql.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - - var t00 = g.mysql.Select() - .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t11 = g.mysql.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t22 = g.mysql.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - } - - public class TestInclude_OneToManyModel11 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2id { get; set; } - public string m3setting { get; set; } - public TestInclude_OneToManyModel22 model2 { get; set; } - public string m1name { get; set; } - } - - public class TestInclude_OneToManyModel22 { - [Column(IsIdentity = true)] - public int id { get; set; } - public string m2setting { get; set; } - public List childs { get; set; } - } - public class TestInclude_OneToManyModel33 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2Id { get; set; } - public string title { get; set; } - public string setting { get; set; } - } - [Fact] - public void Include_OneToMany2() { - string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; - model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); - - var model3s = new[] - { - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} - }; - Assert.Equal(3, g.mysql.Insert(model3s).ExecuteAffrows()); - - var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; - model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); - - var t1 = g.mysql.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - - var t11 = g.mysql.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - } - - [Fact] - public void Include_OneToChilds() { - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_中国" - }; - tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); - var tag1_1 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_北京" - }; - tag1_1.Id = (int)g.mysql.Insert(tag1_1).ExecuteIdentity(); - var tag1_2 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_上海" - }; - tag1_2.Id = (int)g.mysql.Insert(tag1_2).ExecuteIdentity(); - - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_美国" - }; - tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); - var tag2_1 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_纽约" - }; - tag2_1.Id = (int)g.mysql.Insert(tag2_1).ExecuteIdentity(); - var tag2_2 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_华盛顿" - }; - tag2_2.Id = (int)g.mysql.Insert(tag2_2).ExecuteIdentity(); - - var tags0 = g.mysql.Select() - .Include(a => a.Parent) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags1 = g.mysql.Select() - .IncludeMany(a => a.Tags) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags2 = g.mysql.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags3 = g.mysql.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags11 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags22 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags33 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - } - - [Fact] - public void Include_ManyToMany() { - - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_01_中国" - }; - tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_02_美国" - }; - tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); - var tag3 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_03_日本" - }; - tag3.Id = (int)g.mysql.Insert(tag3).ExecuteIdentity(); - - var song1 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_01_我是中国人.mp3", - Url = "http://ww.baidu.com/" - }; - song1.Id = (int)g.mysql.Insert(song1).ExecuteIdentity(); - var song2 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_02_爱你一万年.mp3", - Url = "http://ww.163.com/" - }; - song2.Id = (int)g.mysql.Insert(song2).ExecuteIdentity(); - var song3 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_03_千年等一回.mp3", - Url = "http://ww.sina.com/" - }; - song3.Id = (int)g.mysql.Insert(song3).ExecuteIdentity(); - - g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); - - var songs1 = g.mysql.Select() - .IncludeMany(a => a.Tags) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs1.Count); - Assert.Equal(2, songs1[0].Tags.Count); - Assert.Equal(1, songs1[1].Tags.Count); - Assert.Equal(3, songs1[2].Tags.Count); - - var songs2 = g.mysql.Select() - .IncludeMany(a => a.Tags, - then => then.IncludeMany(t => t.Songs)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs2.Count); - Assert.Equal(2, songs2[0].Tags.Count); - Assert.Equal(1, songs2[1].Tags.Count); - Assert.Equal(3, songs2[2].Tags.Count); - - var tags3 = g.mysql.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - - - var songs11 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs11.Count); - Assert.Equal(1, songs11[0].Tags.Count); - Assert.Equal(1, songs11[1].Tags.Count); - Assert.Equal(1, songs11[2].Tags.Count); - - var songs22 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.IncludeMany(t => t.Songs.Take(1))) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs22.Count); - Assert.Equal(1, songs22[0].Tags.Count); - Assert.Equal(1, songs22[1].Tags.Count); - Assert.Equal(1, songs22[2].Tags.Count); - - var tags33 = g.mysql.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs.Take(1)) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - } - } +namespace FreeSql.Tests.MySqlConnector +{ + + public class MySqlSelectTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + public class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + [Column(OldName = "TypeGuid")] + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + + public virtual TopicFields Fields { get; set; } + } + public class TopicFields + { + [Column(IsPrimary = true)] + public int TopicId { get; set; } + public virtual Topic Topic { get; set; } + } + public class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + + public int ParentId { get; set; } + public virtual TestTypeParentInfo Parent { get; set; } + + public string Name { get; set; } + + public virtual ICollection Topics { get; set; } + } + public class TestTypeParentInfo + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] + class TestInfo + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.mysql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.mysql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.mysql.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.mysql.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, g.mysql.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, g.mysql.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.mysql.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + var testDto5 = select.Limit(10).ToList(); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + var t0 = select.Limit(50).ToList(); + + + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new + { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.mysql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.mysql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.mysql.Select().ToList(); + var testGuidId6 = g.mysql.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); + + var sql1 = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); + var sql2 = g.mysql.Select().Where(a => testenumWhereType.Blaaa == a.type).ToSql(); + + var sql3 = g.mysql.Select().Where(a => a.type.Equals(testenumWhereType.Blaaa)).ToSql(); + var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); + } + class testenumWhere + { + public Guid id { get; set; } + public testenumWhereType type { get; set; } + } + public enum testenumWhereType { Menu, Class, Blaaa } + + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid`", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TypeGuid` AND b.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = @id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = @id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + } + [Fact] + public void Min() + { + } + [Fact] + public void Max() + { + } + [Fact] + public void Avg() + { + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` c ON c.`Id` = a__Type.`ParentId`", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfoAsTable` c ON b.`ParentId` = c.`Id`", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.mysql.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.mysql.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.mysql.Insert(model4s).ExecuteAffrows()); + + var t0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.mysql.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + + var t1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.mysql.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.mysql.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.mysql.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.mysql.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.mysql.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.mysql.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.mysql.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.mysql.Insert(song3).ExecuteIdentity(); + + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index f8f12a20..844e7210 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -3,184 +3,199 @@ using System; using System.Collections.Generic; using Xunit; -namespace FreeSql.Tests.MySqlConnector { - public class MySqlUpdateTest { - IUpdate update => g.mysql.Update(); +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlUpdateTest + { + IUpdate update => g.mysql.Update(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestEnumUpdateTb { - [Column(IsIdentity = true)] - public int id { get; set; } - public TestEnumUpdateTbType type { get; set; } - public DateTime time { get; set; } = new DateTime(); - } - enum TestEnumUpdateTbType { str1, biggit, sum211 } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumUpdateTb + { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumUpdateTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumUpdateTbType { str1, biggit, sum211 } - [Fact] - public void Dywhere() { - Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); - } + [Fact] + public void Dywhere() + { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } - [Fact] - public void SetSource() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = @p_0, `Title` = @p_1, `CreateTime` = @p_2 WHERE (`Id` = 1)", sql); + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = @p_0, `Title` = @p_1, `CreateTime` = @p_2 WHERE (`Id` = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.SetSource(items).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, `Title` = CASE `Id` WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, `CreateTime` = CASE `Id` WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, `Title` = CASE `Id` WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, `CreateTime` = CASE `Id` WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = CASE `Id` WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = CASE `Id` WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `CreateTime` = @p_0 WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `CreateTime` = @p_0 WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); - Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES(@type_0, @time_0)", sql); - var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); - Assert.True(id > 0); - Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + sql = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES(@type_0, @time_0)", sql); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); - sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0, `time` = @p_1 WHERE (`id` = 0)", sql); - g.mysql.Update().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); - Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0, `time` = @p_1 WHERE (`id` = 0)", sql); + g.mysql.Update().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); - sql = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); - Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); - id = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); - Assert.True(id > 0); - Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + sql = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + id = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); - sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); - g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); - Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); - } - [Fact] - public void IgnoreColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); + g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); - sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = 0)", sql); + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = 0)", sql); - sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); - } - [Fact] - public void UpdateColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); - sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = 0)", sql); + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = 0)", sql); - sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); - } - [Fact] - public void Set() { - var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0 WHERE (`Id` = 1)", sql); - sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0, `CreateTime` = @p_1 WHERE (`Id` = 1)", sql); + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0, `CreateTime` = @p_1 WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); - int incrv = 10; - sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 / 1 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 / 1 WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); - var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); - Assert.True(id > 0); - sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); - Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = {id})", sql); - g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ExecuteAffrows(); - Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = @p_0 WHERE (`id` = {id})", sql); + g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); - sql = g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ToSql().Replace("\r\n", ""); - Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'str1' WHERE (`id` = {id})", sql); - g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); - Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); - } - [Fact] - public void SetRaw() { - var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET clicks = clicks + @incrClick WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'str1' WHERE (`id` = {id})", sql); + g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET clicks = clicks + @incrClick WHERE (`Id` = 1)", sql); - sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0).SetRaw("`type` = {0}".FormatMySql(TestEnumUpdateTbType.sum211)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); - } - [Fact] - public void Where() { - var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0).SetRaw("`type` = {0}".FormatMySql(TestEnumUpdateTbType.sum211)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); - sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (id = @id)", sql); + sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (id = @id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) - .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); - } - [Fact] - public void WhereExists() { + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) + .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - } - [Fact] - public void ExecuteUpdated() { + } + [Fact] + public void ExecuteUpdated() + { - } + } - [Fact] - public void AsTable() { - Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - } - } + [Fact] + public void AsTable() + { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs index 5202b06c..7748ad80 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolNullableTest.cs @@ -2,1561 +2,1595 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.MySqlConnectorMapType { - public class BoolNullableTest { - class BoolNullableMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool))] - public bool? tobool { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool? tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool? tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool? toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool? toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool? toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool? tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool? tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool? tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool? tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool? tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool? toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool? toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool? touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool? touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool? toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool? toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool? tostring { get; set; } = true; - } - [Fact] - public void Bool() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item = new BoolNullableMap { tobool = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item = new BoolNullableMap { tobool = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update all - item.tobool = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item.tobool = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item.tobool = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item = new BoolNullableMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item = new BoolNullableMap { tosbyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item.tosbyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item.tosbytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item = new BoolNullableMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item = new BoolNullableMap { toshort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item.toshort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item.toshortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item = new BoolNullableMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item = new BoolNullableMap { toint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item.toint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item = new BoolNullableMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item = new BoolNullableMap { tointnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item.tointnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item = new BoolNullableMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item = new BoolNullableMap { tolong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item.tolong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item.tolongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item = new BoolNullableMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item = new BoolNullableMap { tobyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item.tobyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item.tobytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item = new BoolNullableMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item = new BoolNullableMap { toushort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item.toushort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item.toushortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item = new BoolNullableMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item = new BoolNullableMap { touint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item.touint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item = new BoolNullableMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item = new BoolNullableMap { touintnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item.touintnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item = new BoolNullableMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item = new BoolNullableMap { toulong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item.toulong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item.toulongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item = new BoolNullableMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item = new BoolNullableMap { tostring = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item.tostring = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.MySqlConnectorMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs index f6e7bdfe..75a4ca88 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/BoolTest.cs @@ -2,1095 +2,1129 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.MySqlConnectorMapType { - public class BoolTest { - - class BoolMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool?))] - public bool toboolnullable { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool tostring { get; set; } = true; - } - - [Fact] - public void BoolNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item = new BoolMap { toboolnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update all - item.toboolnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item.toboolnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toboolnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toboolnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item = new BoolMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item = new BoolMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item = new BoolMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item = new BoolMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item = new BoolMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item = new BoolMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item = new BoolMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item = new BoolMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item = new BoolMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item = new BoolMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item = new BoolMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item = new BoolMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item = new BoolMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item = new BoolMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item = new BoolMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item = new BoolMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item = new BoolMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.MySqlConnectorMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs index a5115406..7c3bcba2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/EnumTest.cs @@ -3,252 +3,259 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.MySqlConnectorMapType { - public class EnumTest { - class EnumTestMap { - public Guid id { get; set; } +namespace FreeSql.Tests.MySqlConnectorMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(int))] - public ToStringMapEnum enum_to_int { get; set; } - [Column(MapType = typeof(int?))] - public ToStringMapEnum? enumnullable_to_int { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void EnumToString() { - //insert - var orm = g.mysql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToString() { - //insert - var orm = g.mysql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void EnumToInt() { - //insert - var orm = g.mysql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + [Fact] + public void EnumToInt() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //update all - item.enum_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - item.enum_to_int = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToInt() { - //insert - var orm = g.mysql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); - //update all - item.enumnullable_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); - item.enumnullable_to_int = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs index ae9f6796..4aadc666 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/ToStringTest.cs @@ -3,555 +3,568 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.MySqlConnectorMapType { - public class ToStringTest { - class ToStringMap { - public Guid id { get; set; } +namespace FreeSql.Tests.MySqlConnectorMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan timespan_to_string { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan? timespannullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime datetime_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime? datetimenullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid guid_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid? guidnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger biginteger_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger? bigintegernullable_to_string { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void Enum1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigInteger1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(0, find.biginteger_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); - item = new ToStringMap { biginteger_to_string = 100 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(100, find.biginteger_to_string); + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); - //update all - item.biginteger_to_string = 200; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(200, find.biginteger_to_string); + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); - item.biginteger_to_string = 205; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(205, find.biginteger_to_string); + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(522, find.biginteger_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(10005, find.biginteger_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigIntegerNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - item = new ToStringMap { bigintegernullable_to_string = 101 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(101, find.bigintegernullable_to_string); + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); - //update all - item.bigintegernullable_to_string = 2004; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(2004, find.bigintegernullable_to_string); + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); - item.bigintegernullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(998, find.bigintegernullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.bigintegernullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpan1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); - item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); - //update all - item.timespan_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpanNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); - //update all - item.timespannullable_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); - item.timespannullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.timespannullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTime1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.MinValue, find.datetime_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); - item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); - //update all - item.datetime_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTimeNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); - //update all - item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); - item.datetimenullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.datetimenullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void Guid1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(Guid.Empty, find.guid_to_string); + [Fact] + public void Guid1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guid_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update all - newid = Guid.NewGuid(); - item.guid_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guid_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void GuidNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guidnullable_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - //update all - newid = Guid.NewGuid(); - item.guidnullable_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - item.guidnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guidnullable_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.guidnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 6d9b8a46..48e209f0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -6,80 +6,91 @@ using System.Linq; using System.Text; using Xunit; -namespace FreeSql.Tests.MySqlConnector { - public class MySqlCodeFirstTest { +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlCodeFirstTest + { - [Fact] - public void ı_ֶ() { - var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<ı2>(); - g.mysql.CodeFirst.SyncStructure<ı2>(); + [Fact] + public void ı_ֶ() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<ı2>(); + g.mysql.CodeFirst.SyncStructure<ı2>(); - var item = new ı2 { - = "Ա", - ʱ = DateTime.Now - }; - Assert.Equal(1, g.mysql.Insert<ı2>().AppendData(item).ExecuteAffrows()); - Assert.NotEqual(Guid.Empty, item.); - var item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); - Assert.NotNull(item2); - Assert.Equal(item., item2.); - Assert.Equal(item., item2.); - } - class ı2 { - [Column(IsPrimary = true)] - public Guid { get; set; } + var item = new ı2 + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.mysql.Insert<ı2>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı2 + { + [Column(IsPrimary = true)] + public Guid { get; set; } - public string { get; set; } + public string { get; set; } - public DateTime ʱ { get; set; } - } + public DateTime ʱ { get; set; } + } - [Fact] - public void AddUniques() { - var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - g.mysql.CodeFirst.SyncStructure(); - } - [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - class AddUniquesInfo { - public Guid id { get; set; } - [Column(Unique = "uk_phone")] - public string phone { get; set; } + [Fact] + public void AddUniques() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] - public string group { get; set; } - [Column(Unique = "uk_group_index")] - public int index { get; set; } - [Column(Unique = "uk_group_index22")] - public string index22 { get; set; } - } + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } - [Fact] - public void AddField() { - var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + [Fact] + public void AddField() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - var id = g.mysql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); - } + var id = g.mysql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } - [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] - public class TopicAddField { - [Column(IsIdentity = true)] - public int? Id { get; set; } + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int? Id { get; set; } - public string name { get; set; } + public string name { get; set; } - [Column(DbType = "varchar(200) not null", OldName = "title")] - public string title222 { get; set; } = "10"; + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title222 { get; set; } = "10"; - [Column(IsIgnore = true)] - public DateTime ct { get; set; } = DateTime.Now; - } + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } - [Fact] - public void GetComparisonDDLStatements() { + [Fact] + public void GetComparisonDDLStatements() + { - var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( `Id` INT(11) NOT NULL AUTO_INCREMENT, `testFieldBool` BIT(1) NOT NULL, `testFieldSByte` TINYINT(3) NOT NULL, @@ -126,352 +137,363 @@ namespace FreeSql.Tests.MySqlConnector { PRIMARY KEY (`Id`) ) Engine=InnoDB; ", sql); - } - - sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - } - - IInsert insert => g.mysql.Insert(); - ISelect select => g.mysql.Select(); - - [Fact] - public void CurdAllField() { - var item = new TableAllType { }; - item.Id = (int)insert.AppendData(item).ExecuteIdentity(); - - var newitem = select.Where(a => a.Id == item.Id).ToOne(); - - var item2 = new TableAllType { - testFieldBool = true, - testFieldBoolNullable = true, - testFieldByte = 255, - testFieldByteNullable = 127, - testFieldBytes = Encoding.UTF8.GetBytes("й"), - testFieldDateTime = DateTime.Now, - testFieldDateTimeNullable = DateTime.Now.AddHours(-1), - testFieldDecimal = 99.99M, - testFieldDecimalNullable = 99.98M, - testFieldDouble = 999.99, - testFieldDoubleNullable = 999.98, - testFieldEnum1 = TableAllTypeEnumType1.e5, - testFieldEnum1Nullable = TableAllTypeEnumType1.e3, - testFieldEnum2 = TableAllTypeEnumType2.f2, - testFieldEnum2Nullable = TableAllTypeEnumType2.f3, - testFieldFloat = 19.99F, - testFieldFloatNullable = 19.98F, - testFieldGuid = Guid.NewGuid(), - testFieldGuidNullable = Guid.NewGuid(), - testFieldInt = int.MaxValue, - testFieldIntNullable = int.MinValue, - testFieldLineString = new MygisLineString(new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }), - testFieldLong = long.MaxValue, - testFieldMultiLineString = new MygisMultiLineString(new[] { - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }, - new[] { new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 100) } }), - testFieldMultiPoint = new MygisMultiPoint(new[] { new MygisCoordinate2D(11, 11), new MygisCoordinate2D(51, 11) }), - testFieldMultiPolygon = new MygisMultiPolygon(new[] { - new MygisPolygon(new[] { - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), - new MygisPolygon(new[] { - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }) }), - testFieldPoint = new MygisPoint(99, 99), - testFieldPolygon = new MygisPolygon(new[] { - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), - testFieldSByte = 100, - testFieldSByteNullable = 99, - testFieldShort = short.MaxValue, - testFieldShortNullable = short.MinValue, - testFieldString = "йstring", - testFieldTimeSpan = TimeSpan.FromSeconds(999), - testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), - testFieldUInt = uint.MaxValue, - testFieldUIntNullable = uint.MinValue, - testFieldULong = ulong.MaxValue, - testFieldULongNullable = ulong.MinValue, - testFieldUShort = ushort.MaxValue, - testFieldUShortNullable = ushort.MinValue, - testFielLongNullable = long.MinValue - }; - item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); - var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + } + + sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.mysql.Insert(); + ISelect select => g.mysql.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = 255, + testFieldByteNullable = 127, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(-1), + testFieldDecimal = 99.99M, + testFieldDecimalNullable = 99.98M, + testFieldDouble = 999.99, + testFieldDoubleNullable = 999.98, + testFieldEnum1 = TableAllTypeEnumType1.e5, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 19.99F, + testFieldFloatNullable = 19.98F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldLineString = new MygisLineString(new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }), + testFieldLong = long.MaxValue, + testFieldMultiLineString = new MygisMultiLineString(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }, + new[] { new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 100) } }), + testFieldMultiPoint = new MygisMultiPoint(new[] { new MygisCoordinate2D(11, 11), new MygisCoordinate2D(51, 11) }), + testFieldMultiPolygon = new MygisMultiPolygon(new[] { + new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), + new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }) }), + testFieldPoint = new MygisPoint(99, 99), + testFieldPolygon = new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), + testFieldSByte = 100, + testFieldSByteNullable = 99, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "йstring", + testFieldTimeSpan = TimeSpan.FromSeconds(999), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); - var items = select.ToList(); - } + var items = select.ToList(); + } - [JsonObject(MemberSerialization.OptIn), Table(Name = "tb_alltype")] - public partial class Tb_alltype { + [JsonObject(MemberSerialization.OptIn), Table(Name = "tb_alltype")] + public partial class Tb_alltype + { - [JsonProperty, Column(Name = "Id", DbType = "int(11)", IsPrimary = true, IsIdentity = true)] - public int Id { get; set; } + [JsonProperty, Column(Name = "Id", DbType = "int(11)", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } - [JsonProperty, Column(Name = "testFieldBool", DbType = "bit(1)")] - public bool TestFieldBool { get; set; } + [JsonProperty, Column(Name = "testFieldBool", DbType = "bit(1)")] + public bool TestFieldBool { get; set; } - [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit(1)", IsNullable = true)] - public bool? TestFieldBoolNullable { get; set; } + [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit(1)", IsNullable = true)] + public bool? TestFieldBoolNullable { get; set; } - [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint(3) unsigned")] - public byte TestFieldByte { get; set; } + [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint(3) unsigned")] + public byte TestFieldByte { get; set; } - [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint(3) unsigned", IsNullable = true)] - public byte? TestFieldByteNullable { get; set; } + [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint(3) unsigned", IsNullable = true)] + public byte? TestFieldByteNullable { get; set; } - [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] - public byte[] TestFieldBytes { get; set; } + [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] + public byte[] TestFieldBytes { get; set; } - [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] - public DateTime TestFieldDateTime { get; set; } + [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] + public DateTime TestFieldDateTime { get; set; } - [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] - public DateTime? TestFieldDateTimeNullable { get; set; } + [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] + public DateTime? TestFieldDateTimeNullable { get; set; } - [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] - public decimal TestFieldDecimal { get; set; } + [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] + public decimal TestFieldDecimal { get; set; } - [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] - public decimal? TestFieldDecimalNullable { get; set; } + [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] + public decimal? TestFieldDecimalNullable { get; set; } - [JsonProperty, Column(Name = "testFieldDouble", DbType = "double")] - public double TestFieldDouble { get; set; } + [JsonProperty, Column(Name = "testFieldDouble", DbType = "double")] + public double TestFieldDouble { get; set; } - [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "double", IsNullable = true)] - public double? TestFieldDoubleNullable { get; set; } + [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "double", IsNullable = true)] + public double? TestFieldDoubleNullable { get; set; } - [JsonProperty, Column(Name = "testFieldEnum1", DbType = "enum('E1','E2','E3','E5')")] - public Tb_alltypeTESTFIELDENUM1 TestFieldEnum1 { get; set; } + [JsonProperty, Column(Name = "testFieldEnum1", DbType = "enum('E1','E2','E3','E5')")] + public Tb_alltypeTESTFIELDENUM1 TestFieldEnum1 { get; set; } - [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "enum('E1','E2','E3','E5')", IsNullable = true)] - public Tb_alltypeTESTFIELDENUM1NULLABLE? TestFieldEnum1Nullable { get; set; } + [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "enum('E1','E2','E3','E5')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM1NULLABLE? TestFieldEnum1Nullable { get; set; } - [JsonProperty, Column(Name = "testFieldEnum2", DbType = "set('F1','F2','F3')")] - public Tb_alltypeTESTFIELDENUM2 TestFieldEnum2 { get; set; } + [JsonProperty, Column(Name = "testFieldEnum2", DbType = "set('F1','F2','F3')")] + public Tb_alltypeTESTFIELDENUM2 TestFieldEnum2 { get; set; } - [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "set('F1','F2','F3')", IsNullable = true)] - public Tb_alltypeTESTFIELDENUM2NULLABLE? TestFieldEnum2Nullable { get; set; } + [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "set('F1','F2','F3')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM2NULLABLE? TestFieldEnum2Nullable { get; set; } - [JsonProperty, Column(Name = "testFieldFloat", DbType = "float")] - public float TestFieldFloat { get; set; } + [JsonProperty, Column(Name = "testFieldFloat", DbType = "float")] + public float TestFieldFloat { get; set; } - [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "float", IsNullable = true)] - public float? TestFieldFloatNullable { get; set; } + [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "float", IsNullable = true)] + public float? TestFieldFloatNullable { get; set; } - [JsonProperty, Column(Name = "testFieldGuid", DbType = "char(36)")] - public Guid TestFieldGuid { get; set; } + [JsonProperty, Column(Name = "testFieldGuid", DbType = "char(36)")] + public Guid TestFieldGuid { get; set; } - [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "char(36)", IsNullable = true)] - public Guid? TestFieldGuidNullable { get; set; } + [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "char(36)", IsNullable = true)] + public Guid? TestFieldGuidNullable { get; set; } - [JsonProperty, Column(Name = "testFieldInt", DbType = "int(11)")] - public int TestFieldInt { get; set; } + [JsonProperty, Column(Name = "testFieldInt", DbType = "int(11)")] + public int TestFieldInt { get; set; } - [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int(11)", IsNullable = true)] - public int? TestFieldIntNullable { get; set; } + [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int(11)", IsNullable = true)] + public int? TestFieldIntNullable { get; set; } - [JsonProperty, Column(Name = "testFieldLineString", DbType = "linestring", IsNullable = true)] - public MygisGeometry TestFieldLineString { get; set; } + [JsonProperty, Column(Name = "testFieldLineString", DbType = "linestring", IsNullable = true)] + public MygisGeometry TestFieldLineString { get; set; } - [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint(20)")] - public long TestFieldLong { get; set; } + [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint(20)")] + public long TestFieldLong { get; set; } - [JsonProperty, Column(Name = "testFieldMultiLineString", DbType = "multilinestring", IsNullable = true)] - public MygisGeometry TestFieldMultiLineString { get; set; } + [JsonProperty, Column(Name = "testFieldMultiLineString", DbType = "multilinestring", IsNullable = true)] + public MygisGeometry TestFieldMultiLineString { get; set; } - [JsonProperty, Column(Name = "testFieldMultiPoint", DbType = "multipoint", IsNullable = true)] - public MygisGeometry TestFieldMultiPoint { get; set; } + [JsonProperty, Column(Name = "testFieldMultiPoint", DbType = "multipoint", IsNullable = true)] + public MygisGeometry TestFieldMultiPoint { get; set; } - [JsonProperty, Column(Name = "testFieldMultiPolygon", DbType = "multipolygon", IsNullable = true)] - public MygisGeometry TestFieldMultiPolygon { get; set; } + [JsonProperty, Column(Name = "testFieldMultiPolygon", DbType = "multipolygon", IsNullable = true)] + public MygisGeometry TestFieldMultiPolygon { get; set; } - [JsonProperty, Column(Name = "testFieldPoint", DbType = "point", IsNullable = true)] - public MygisGeometry TestFieldPoint { get; set; } + [JsonProperty, Column(Name = "testFieldPoint", DbType = "point", IsNullable = true)] + public MygisGeometry TestFieldPoint { get; set; } - [JsonProperty, Column(Name = "testFieldPolygon", DbType = "polygon", IsNullable = true)] - public MygisGeometry TestFieldPolygon { get; set; } + [JsonProperty, Column(Name = "testFieldPolygon", DbType = "polygon", IsNullable = true)] + public MygisGeometry TestFieldPolygon { get; set; } - [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint(3)")] - public sbyte TestFieldSByte { get; set; } + [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint(3)")] + public sbyte TestFieldSByte { get; set; } - [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint(3)", IsNullable = true)] - public sbyte? TestFieldSByteNullable { get; set; } + [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint(3)", IsNullable = true)] + public sbyte? TestFieldSByteNullable { get; set; } - [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint(6)")] - public short TestFieldShort { get; set; } + [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint(6)")] + public short TestFieldShort { get; set; } - [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint(6)", IsNullable = true)] - public short? TestFieldShortNullable { get; set; } + [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint(6)", IsNullable = true)] + public short? TestFieldShortNullable { get; set; } - [JsonProperty, Column(Name = "testFieldString", DbType = "varchar(255)", IsNullable = true)] - public string TestFieldString { get; set; } + [JsonProperty, Column(Name = "testFieldString", DbType = "varchar(255)", IsNullable = true)] + public string TestFieldString { get; set; } - [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] - public TimeSpan TestFieldTimeSpan { get; set; } + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] + public TimeSpan TestFieldTimeSpan { get; set; } - [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] - public TimeSpan? TestFieldTimeSpanNullable { get; set; } + [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] + public TimeSpan? TestFieldTimeSpanNullable { get; set; } - [JsonProperty, Column(Name = "testFieldUInt", DbType = "int(10) unsigned")] - public uint TestFieldUInt { get; set; } + [JsonProperty, Column(Name = "testFieldUInt", DbType = "int(10) unsigned")] + public uint TestFieldUInt { get; set; } - [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int(10) unsigned", IsNullable = true)] - public uint? TestFieldUIntNullable { get; set; } + [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int(10) unsigned", IsNullable = true)] + public uint? TestFieldUIntNullable { get; set; } - [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint(20) unsigned")] - public ulong TestFieldULong { get; set; } + [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint(20) unsigned")] + public ulong TestFieldULong { get; set; } - [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint(20) unsigned", IsNullable = true)] - public ulong? TestFieldULongNullable { get; set; } + [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint(20) unsigned", IsNullable = true)] + public ulong? TestFieldULongNullable { get; set; } - [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint(5) unsigned")] - public ushort TestFieldUShort { get; set; } + [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint(5) unsigned")] + public ushort TestFieldUShort { get; set; } - [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint(5) unsigned", IsNullable = true)] - public ushort? TestFieldUShortNullable { get; set; } + [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint(5) unsigned", IsNullable = true)] + public ushort? TestFieldUShortNullable { get; set; } - [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint(20)", IsNullable = true)] - public long? TestFielLongNullable { get; set; } + [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint(20)", IsNullable = true)] + public long? TestFielLongNullable { get; set; } - internal static IFreeSql mysql => null; - public static FreeSql.ISelect Select => mysql.Select(); + internal static IFreeSql mysql => null; + public static FreeSql.ISelect Select => mysql.Select(); - public static long Delete(int Id) { - var affrows = mysql.Delete().Where(a => a.Id == Id).ExecuteAffrows(); - return affrows; - } + public static long Delete(int Id) + { + var affrows = mysql.Delete().Where(a => a.Id == Id).ExecuteAffrows(); + return affrows; + } - /// - /// ӣֵ UpdateӰΪ 0 Insert - /// - public void Save() { - if (this.Id != default(int)) { - var affrows = mysql.Update().Where(a => a.Id == Id).ExecuteAffrows(); - if (affrows > 0) return; - } - this.Id = (int)mysql.Insert().AppendData(this).ExecuteIdentity(); - } + /// + /// ӣֵ UpdateӰΪ 0 Insert + /// + public void Save() + { + if (this.Id != default(int)) + { + var affrows = mysql.Update().Where(a => a.Id == Id).ExecuteAffrows(); + if (affrows > 0) return; + } + this.Id = (int)mysql.Insert().AppendData(this).ExecuteIdentity(); + } - } + } - public enum Tb_alltypeTESTFIELDENUM1 { - E1 = 1, E2, E3, E5 - } - public enum Tb_alltypeTESTFIELDENUM1NULLABLE { - E1 = 1, E2, E3, E5 - } - [Flags] - public enum Tb_alltypeTESTFIELDENUM2 : long { - F1 = 1, F2 = 2, F3 = 4 - } - [Flags] - public enum Tb_alltypeTESTFIELDENUM2NULLABLE : long { - F1 = 1, F2 = 2, F3 = 4 - } + public enum Tb_alltypeTESTFIELDENUM1 + { + E1 = 1, E2, E3, E5 + } + public enum Tb_alltypeTESTFIELDENUM1NULLABLE + { + E1 = 1, E2, E3, E5 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2 : long + { + F1 = 1, F2 = 2, F3 = 4 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2NULLABLE : long + { + F1 = 1, F2 = 2, F3 = 4 + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - - public bool testFieldBool { get; set; } - public sbyte testFieldSByte { get; set; } - public short testFieldShort { get; set; } - public int testFieldInt { get; set; } - public long testFieldLong { get; set; } - public byte testFieldByte { get; set; } - public ushort testFieldUShort { get; set; } - public uint testFieldUInt { get; set; } - public ulong testFieldULong { get; set; } - public double testFieldDouble { get; set; } - public float testFieldFloat { get; set; } - public decimal testFieldDecimal { get; set; } - public TimeSpan testFieldTimeSpan { get; set; } - public DateTime testFieldDateTime { get; set; } - public byte[] testFieldBytes { get; set; } - public string testFieldString { get; set; } - public Guid testFieldGuid { get; set; } - - public bool? testFieldBoolNullable { get; set; } - public sbyte? testFieldSByteNullable { get; set; } - public short? testFieldShortNullable { get; set; } - public int? testFieldIntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? testFieldByteNullable { get; set; } - public ushort? testFieldUShortNullable { get; set; } - public uint? testFieldUIntNullable { get; set; } - public ulong? testFieldULongNullable { get; set; } - public double? testFieldDoubleNullable { get; set; } - public float? testFieldFloatNullable { get; set; } - public decimal? testFieldDecimalNullable { get; set; } - public TimeSpan? testFieldTimeSpanNullable { get; set; } - public DateTime? testFieldDateTimeNullable { get; set; } - public Guid? testFieldGuidNullable { get; set; } - - public MygisPoint testFieldPoint { get; set; } - public MygisLineString testFieldLineString { get; set; } - public MygisPolygon testFieldPolygon { get; set; } - public MygisMultiPoint testFieldMultiPoint { get; set; } - public MygisMultiLineString testFieldMultiLineString { get; set; } - public MygisMultiPolygon testFieldMultiPolygon { get; set; } - - public TableAllTypeEnumType1 testFieldEnum1 { get; set; } - public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } - public TableAllTypeEnumType2 testFieldEnum2 { get; set; } - public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - } - - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public MygisPoint testFieldPoint { get; set; } + public MygisLineString testFieldLineString { get; set; } + public MygisPolygon testFieldPolygon { get; set; } + public MygisMultiPoint testFieldMultiPoint { get; set; } + public MygisMultiLineString testFieldMultiLineString { get; set; } + public MygisMultiPolygon testFieldMultiPolygon { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs index e2ec87e4..f1d59702 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs @@ -2,53 +2,64 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.MySqlConnector { - public class MySqlAdoTest { - [Fact] - public void Pool() { - var t1 = g.mysql.Ado.MasterPool.StatisticsFullily; - } +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.mysql.Ado.MasterPool.StatisticsFullily; + } - [Fact] - public void SlavePools() { - var t2 = g.mysql.Ado.SlavePools.Count; - } + [Fact] + public void SlavePools() + { + var t2 = g.mysql.Ado.SlavePools.Count; + } - [Fact] - public void ExecuteReader() { - - } - [Fact] - public void ExecuteArray() { - - } - [Fact] - public void ExecuteNonQuery() { - - } - [Fact] - public void ExecuteScalar() { - - } + [Fact] + public void ExecuteReader() + { - [Fact] - public void Query() { - var t3 = g.mysql.Ado.Query("select * from song"); + } + [Fact] + public void ExecuteArray() + { - var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + } + [Fact] + public void ExecuteNonQuery() + { - var t5 = g.mysql.Ado.Query("select * from song"); - } + } + [Fact] + public void ExecuteScalar() + { - [Fact] - public void QueryMultipline() { - var t3 = g.mysql.Ado.Query("select * from song; select * from song; select * from song"); - } + } - class xxx { - public int Id { get; set; } - public string Path { get; set; } - public string Title2 { get; set; } - } - } + [Fact] + public void Query() + { + var t3 = g.mysql.Ado.Query("select * from song"); + + var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + + var t5 = g.mysql.Ado.Query("select * from song"); + } + + [Fact] + public void QueryMultipline() + { + var t3 = g.mysql.Ado.Query("select * from song; select * from song; select * from song"); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs index 8aff8e08..4fdc2304 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/ConvertTest.cs @@ -4,143 +4,166 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnectorExpression { - public class ConvertTest { +namespace FreeSql.Tests.MySqlConnectorExpression +{ + public class ConvertTest + { - ISelect select => g.mysql.Select(); + ISelect select => g.mysql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void ToBoolean() { - var data = new List(); - data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); - data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); - } - [Fact] - public void ToByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); - data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); - } - [Fact] - public void ToChar() { - var data = new List(); - data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); - data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); - } - [Fact] - public void ToDateTime() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); - } - [Fact] - public void ToDecimal() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToDouble() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt32() { - var data = new List(); - data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); - data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToSByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); - data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); - } - [Fact] - public void ToSingle() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); - data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); - } - [Fact] - public void ToUInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt32() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); - } + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } - [Fact] - public void Guid_Parse() { - var data = new List(); - data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); - } + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } - [Fact] - public void Guid_NewGuid() { - var data = new List(); - //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); - } + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } - [Fact] - public void Random() { - var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); - } - } + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs index 5dcbc74b..fbb5e47b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs @@ -4,620 +4,658 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnectorExpression { - public class DateTimeTest { - - ISelect select => g.mysql.Select(); - - [Table(Name = "tb_topic111333")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - [Table(Name = "TestTypeInfo333")] - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - public DateTime Time { get; set; } - } - [Table(Name = "TestTypeParentInfo23123")] - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - public DateTime Time2 { get; set; } - } - [Fact] - public void Now() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void UtcNow() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void Date() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) - } - [Fact] - public void TimeOfDay() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) - } - [Fact] - public void DayOfWeek() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) - } - [Fact] - public void Day() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) - } - [Fact] - public void DayOfYear() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) - } - [Fact] - public void Month() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (month(a.`CreateTime`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (month(a__Type.`Time`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (month(a__Type__Parent.`Time2`) > month(now())) - } - [Fact] - public void Year() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (year(a.`CreateTime`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (year(a__Type.`Time`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (year(a__Type__Parent.`Time2`) > year(now())) - } - [Fact] - public void Hour() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (hour(a.`CreateTime`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (hour(a__Type.`Time`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) - } - [Fact] - public void Minute() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (minute(a.`CreateTime`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (minute(a__Type.`Time`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) - } - [Fact] - public void Second() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (second(a.`CreateTime`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (second(a__Type.`Time`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (second(a__Type__Parent.`Time2`) > second(now())) - } - [Fact] - public void Millisecond() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) - } - [Fact] - public void AddDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) - } - [Fact] - public void AddHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) - } - [Fact] - public void AddMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) - } - [Fact] - public void AddMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) - } - [Fact] - public void AddMonths() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) - } - [Fact] - public void AddSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) - } - [Fact] - public void AddTicks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) - } - [Fact] - public void AddYears() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - - [Fact] - public void DateTime_Compare() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((a.`CreateTime`) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) - } - [Fact] - public void DateTime_DaysInMonth() { - var data = new List(); - data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) - } - [Fact] - public void DateTime_Equals() { - var data = new List(); - data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void DateTime_IsLeapYear() { - var data = new List(); - data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) - } - [Fact] - public void DateTime_Parse() { - var data = new List(); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) - } - } +namespace FreeSql.Tests.MySqlConnectorExpression +{ + public class DateTimeTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs index 83d333b5..7a70825a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/MathTest.cs @@ -4,129 +4,153 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnectorExpression { - public class MathTest { +namespace FreeSql.Tests.MySqlConnectorExpression +{ + public class MathTest + { - ISelect select => g.mysql.Select(); + ISelect select => g.mysql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void PI() { - var data = new List(); - data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); - } - [Fact] - public void Abs() { - var data = new List(); - data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Sign() { - var data = new List(); - data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Floor() { - var data = new List(); - data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); - } - [Fact] - public void Ceiling() { - var data = new List(); - data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Round() { - var data = new List(); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); - } - [Fact] - public void Exp() { - var data = new List(); - data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log() { - var data = new List(); - data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log10() { - var data = new List(); - data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Pow() { - var data = new List(); - data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sqrt() { - var data = new List(); - data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Cos() { - var data = new List(); - data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sin() { - var data = new List(); - data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Tan() { - var data = new List(); - data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Acos() { - var data = new List(); - data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Asin() { - var data = new List(); - data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan() { - var data = new List(); - data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan2() { - var data = new List(); - data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Truncate() { - var data = new List(); - data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); - } - } + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs index ad037e00..8fc9d3eb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs @@ -5,117 +5,123 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnectorExpression { - public class OtherTest { +namespace FreeSql.Tests.MySqlConnectorExpression +{ + public class OtherTest + { - ISelect select => g.mysql.Select(); + ISelect select => g.mysql.Select(); - public OtherTest() { - - } + public OtherTest() + { - [Fact] - public void Boolean() { - var t1 = select.Where(a => a.testFieldBool == true).ToList(); - var t2 = select.Where(a => a.testFieldBool != true).ToList(); - var t3 = select.Where(a => a.testFieldBool == false).ToList(); - var t4 = select.Where(a => !a.testFieldBool).ToList(); - var t5 = select.Where(a => a.testFieldBool).ToList(); + } - var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); - var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); - var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); - var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); - var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); - } + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); - [Fact] - public void Array() { - int[] nullarr = null; - Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); - Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } - IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); - var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + [Fact] + public void Array() + { + int[] nullarr = null; + Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); - //in not in - var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); - var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); - var inarray = new[] { 1, 2, 3 }; - var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); - var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - //in not in - var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); - var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); - var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); - var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); - var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var inarray2 = new List() { 1, 2, 3 }; - var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); - var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); - } + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + } - public bool testFieldBool { get; set; } - public sbyte testFieldSByte { get; set; } - public short testFieldShort { get; set; } - public int testFieldInt { get; set; } - public long testFieldLong { get; set; } - public byte testFieldByte { get; set; } - public ushort testFieldUShort { get; set; } - public uint testFieldUInt { get; set; } - public ulong testFieldULong { get; set; } - public double testFieldDouble { get; set; } - public float testFieldFloat { get; set; } - public decimal testFieldDecimal { get; set; } - public TimeSpan testFieldTimeSpan { get; set; } - public DateTime testFieldDateTime { get; set; } - public byte[] testFieldBytes { get; set; } - public string testFieldString { get; set; } - public Guid testFieldGuid { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - public bool? testFieldBoolNullable { get; set; } - public sbyte? testFieldSByteNullable { get; set; } - public short? testFieldShortNullable { get; set; } - public int? testFieldIntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? testFieldByteNullable { get; set; } - public ushort? testFieldUShortNullable { get; set; } - public uint? testFieldUIntNullable { get; set; } - public ulong? testFieldULongNullable { get; set; } - public double? testFieldDoubleNullable { get; set; } - public float? testFieldFloatNullable { get; set; } - public decimal? testFieldDecimalNullable { get; set; } - public TimeSpan? testFieldTimeSpanNullable { get; set; } - public DateTime? testFieldDateTimeNullable { get; set; } - public Guid? testFieldGuidNullable { get; set; } + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } - public MygisPoint testFieldPoint { get; set; } - public MygisLineString testFieldLineString { get; set; } - public MygisPolygon testFieldPolygon { get; set; } - public MygisMultiPoint testFieldMultiPoint { get; set; } - public MygisMultiLineString testFieldMultiLineString { get; set; } - public MygisMultiPolygon testFieldMultiPolygon { get; set; } + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } - public TableAllTypeEnumType1 testFieldEnum1 { get; set; } - public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } - public TableAllTypeEnumType2 testFieldEnum2 { get; set; } - public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - } + public MygisPoint testFieldPoint { get; set; } + public MygisLineString testFieldLineString { get; set; } + public MygisPolygon testFieldPolygon { get; set; } + public MygisMultiPoint testFieldMultiPoint { get; set; } + public MygisMultiLineString testFieldMultiLineString { get; set; } + public MygisMultiPolygon testFieldMultiPolygon { get; set; } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 331170d1..2ceacb9d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -4,693 +4,717 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnectorExpression { - public class StringTest { - - ISelect select => g.mysql.Select(); - - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - class TestEqualsGuid { - public Guid id { get; set; } - public bool IsDeleted { get; set; } - } - - [Fact] - public void Equals__() { - var list = new List(); - list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); - list.Add(g.mysql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); - list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); - } - - [Fact] - public void Empty() { - var data = new List(); - data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ifnull(a.`Title`, '') = '') - } - - [Fact] - public void StartsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) - list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) - } - [Fact] - public void EndsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) - } - [Fact] - public void Contains() { - var list = new List(); - list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) - } - [Fact] - public void ToLower() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void ToUpper() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void Substring() { - var data = new List(); - data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) - } - [Fact] - public void Length() { - var data = new List(); - data.Add(select.Where(a => a.Title.Length == 0).ToList()); - data.Add(select.Where(a => a.Title.Length == 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); - data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) - } - [Fact] - public void IndexOf() { - var data = new List(); - data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) - } - [Fact] - public void PadLeft() { - var data = new List(); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void PadRight() { - var data = new List(); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void Trim() { - var data = new List(); - data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void TrimStart() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) - } - [Fact] - public void TrimEnd() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void Replace() { - var data = new List(); - data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) - } - - [Fact] - public void string_IsNullOrEmpty() { - var data = new List(); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); - data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); - } - } +namespace FreeSql.Tests.MySqlConnectorExpression +{ + public class StringTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + public bool IsDeleted { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.mysql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs index 2f4431c3..0712d905 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/TimeSpanTest.cs @@ -4,257 +4,290 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlConnectorExpression { - public class TimeSpanTest { +namespace FreeSql.Tests.MySqlConnectorExpression +{ + public class TimeSpanTest + { - ISelect select => g.mysql.Select(); + ISelect select => g.mysql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } - [Fact] - public void Zero() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) - } - [Fact] - public void Days() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) - } - [Fact] - public void Hours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) - } - [Fact] - public void Milliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) - } - [Fact] - public void Minutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) - } - [Fact] - public void Seconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) - } - [Fact] - public void TotalDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) - } - [Fact] - public void TotalHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) - } - [Fact] - public void TotalMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) - } - [Fact] - public void TotalMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) - } - [Fact] - public void TotalSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') - } + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } - [Fact] - public void TimeSpan_Compare() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void TimeSpan_Equals() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromDays() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromHours() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) - } - [Fact] - public void TimeSpan_FromMilliseconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) - } - [Fact] - public void TimeSpan_FromMinutes() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) - } - [Fact] - public void TimeSpan_FromSeconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) - } - [Fact] - public void TimeSpan_FromTicks() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) - } - [Fact] - public void TimeSpan_Parse() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) - } - } + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs index 86a3aa7d..5ce6d981 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs @@ -2,20 +2,24 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.MySqlConnector { - public class MySqlDbFirstTest { - [Fact] - public void GetDatabases() { +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlDbFirstTest + { + [Fact] + public void GetDatabases() + { - var t1 = g.mysql.DbFirst.GetDatabases(); + var t1 = g.mysql.DbFirst.GetDatabases(); - } + } - [Fact] - public void GetTablesByDatabase() { + [Fact] + public void GetTablesByDatabase() + { - var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); + var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); - } - } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs index 7f1750d7..ee572d0d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs @@ -4,19 +4,22 @@ using System.Diagnostics; using System.Text; -public class g { +public class g +{ - static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") - .UseAutoSyncStructure(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseLazyLoading(true) - .Build()); - public static IFreeSql mysql => mysqlLazy.Value; + static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .Build()); + public static IFreeSql mysql => mysqlLazy.Value; } diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index 815821ec..2dac212c 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -4,117 +4,134 @@ using System; using System.Linq; using Xunit; -namespace FreeSql.Tests.DataAnnotations { - public class MySqlFluentTest { +namespace FreeSql.Tests.DataAnnotations +{ + public class MySqlFluentTest + { - public MySqlFluentTest() { - } + public MySqlFluentTest() + { + } - [Fact] - public void DisableSyncStructure() { - Assert.Throws(() => g.mysql.Select().ToList()); + [Fact] + public void DisableSyncStructure() + { + Assert.Throws(() => g.mysql.Select().ToList()); - g.mysql.Select().ToList(); - } - [Table(DisableSyncStructure = true)] - class ModelDisableSyncStructure { - [Column(IsPrimary = false)] - public int pkid { get; set; } - } - class ModelSyncStructure { - [Column(IsPrimary = false)] - public int pkid { get; set; } - } + g.mysql.Select().ToList(); + } + [Table(DisableSyncStructure = true)] + class ModelDisableSyncStructure + { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + class ModelSyncStructure + { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } - [Fact] - public void AopConfigEntity() { - g.mysql.CodeFirst.ConfigEntity(a => a.Property(b => b.pkid).IsPrimary(true)); + [Fact] + public void AopConfigEntity() + { + g.mysql.CodeFirst.ConfigEntity(a => a.Property(b => b.pkid).IsPrimary(true)); - g.mysql.Aop.ConfigEntity = (s, e) => { - var attr = e.EntityType.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute), false).FirstOrDefault() as System.ComponentModel.DataAnnotations.Schema.TableAttribute; - if (attr != null) { - e.ModifyResult.Name = attr.Name; - } - }; - g.mysql.Aop.ConfigEntityProperty = (s, e) => { - if (e.Property.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.KeyAttribute), false).Any()) { - e.ModifyResult.IsPrimary = true; - } - }; + g.mysql.Aop.ConfigEntity = (s, e) => + { + var attr = e.EntityType.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute), false).FirstOrDefault() as System.ComponentModel.DataAnnotations.Schema.TableAttribute; + if (attr != null) + { + e.ModifyResult.Name = attr.Name; + } + }; + g.mysql.Aop.ConfigEntityProperty = (s, e) => + { + if (e.Property.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.KeyAttribute), false).Any()) + { + e.ModifyResult.IsPrimary = true; + } + }; - var tsql1 = g.mysql.Select().WhereDynamic(1).ToSql(); - } - [System.ComponentModel.DataAnnotations.Schema.Table("xxx")] - class ModelAopConfigEntity { - [System.ComponentModel.DataAnnotations.Key] - [Column(IsPrimary = false)] - public int pkid { get; set; } - } + var tsql1 = g.mysql.Select().WhereDynamic(1).ToSql(); + } + [System.ComponentModel.DataAnnotations.Schema.Table("xxx")] + class ModelAopConfigEntity + { + [System.ComponentModel.DataAnnotations.Key] + [Column(IsPrimary = false)] + public int pkid { get; set; } + } - [Fact] - public void Fluent() { - g.mysql.CodeFirst - //.ConfigEntity(a => { - // a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0"); - // a.Property(b => b.Id).Name("Id22").IsIdentity(true); - // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); - //}) + [Fact] + public void Fluent() + { + g.mysql.CodeFirst + //.ConfigEntity(a => { + // a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0"); + // a.Property(b => b.Id).Name("Id22").IsIdentity(true); + // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); + //}) - .ConfigEntity(typeof(TestFluenttb1), a => { - a.Name("xxdkdkdk1222").SelectFilter("a.Id22dd > 1"); - a.Property("Id").Name("Id22dd").IsIdentity(true); - a.Property("Name").DbType("varchar(101)").IsNullable(true); - }) + .ConfigEntity(typeof(TestFluenttb1), a => + { + a.Name("xxdkdkdk1222").SelectFilter("a.Id22dd > 1"); + a.Property("Id").Name("Id22dd").IsIdentity(true); + a.Property("Name").DbType("varchar(101)").IsNullable(true); + }) - .ConfigEntity(a => { - a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0"); - a.Property(b => b.Id).Name("Id22").IsIdentity(true); - a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); - }) - ; + .ConfigEntity(a => + { + a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0"); + a.Property(b => b.Id).Name("Id22").IsIdentity(true); + a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); + }) + ; - var ddl1 = g.mysql.CodeFirst.GetComparisonDDLStatements(); - var ddl2 = g.mysql.CodeFirst.GetComparisonDDLStatements(); + var ddl1 = g.mysql.CodeFirst.GetComparisonDDLStatements(); + var ddl2 = g.mysql.CodeFirst.GetComparisonDDLStatements(); - var t1id = g.mysql.Insert().AppendData(new TestFluenttb1 { }).ExecuteIdentity(); - var t1 = g.mysql.Select(t1id).ToOne(); + var t1id = g.mysql.Insert().AppendData(new TestFluenttb1 { }).ExecuteIdentity(); + var t1 = g.mysql.Select(t1id).ToOne(); - var t2lastId = g.mysql.Select().Max(a => a.Id); - var t2affrows = g.mysql.Insert().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows(); - var t2 = g.mysql.Select(t2lastId + 1).ToOne(); - } + var t2lastId = g.mysql.Select().Max(a => a.Id); + var t2affrows = g.mysql.Insert().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows(); + var t2 = g.mysql.Select(t2lastId + 1).ToOne(); + } - class TestFluenttb1 - { - public int Id { get; set; } + class TestFluenttb1 + { + public int Id { get; set; } - public string name { get; set; } = "defaultValue"; - } + public string name { get; set; } = "defaultValue"; + } - [Table(Name = "cccccdddwww")] - class TestFluenttb2 - { - [Column(Name = "Idx", IsPrimary = true, IsIdentity = false)] - public int Id { get; set; } + [Table(Name = "cccccdddwww")] + class TestFluenttb2 + { + [Column(Name = "Idx", IsPrimary = true, IsIdentity = false)] + public int Id { get; set; } - public string name { get; set; } = "defaultValue"; - } + public string name { get; set; } = "defaultValue"; + } - [Fact] - public void IsIgnore() { - var item = new TestIsIgnore { }; - Assert.Equal(1, g.mysql.Insert().AppendData(item).ExecuteAffrows()); + [Fact] + public void IsIgnore() + { + var item = new TestIsIgnore { }; + Assert.Equal(1, g.mysql.Insert().AppendData(item).ExecuteAffrows()); - var find = g.mysql.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - } + var find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + } - class TestIsIgnore { - public Guid id { get; set; } + class TestIsIgnore + { + public Guid id { get; set; } - [Column(IsIgnore = true)] - public bool isignore { get; set; } - } - } + [Column(IsIgnore = true)] + public bool isignore { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs index f4354f51..cd6aee48 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs @@ -4,118 +4,130 @@ using System; using System.Data.SqlClient; using Xunit; -namespace FreeSql.Tests.DataAnnotations { - [Collection("SqlServerCollection")] - public class SqlServerFluentTest { +namespace FreeSql.Tests.DataAnnotations +{ + [Collection("SqlServerCollection")] + public class SqlServerFluentTest + { - SqlServerFixture _sqlserverFixture; + SqlServerFixture _sqlserverFixture; - public SqlServerFluentTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public SqlServerFluentTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - [Fact] - public void DisableSyncStructure() { - Assert.Throws(() => _sqlserverFixture.SqlServer.Select().ToList()); + [Fact] + public void DisableSyncStructure() + { + Assert.Throws(() => _sqlserverFixture.SqlServer.Select().ToList()); - _sqlserverFixture.SqlServer.Select().ToList(); - } - [Table(DisableSyncStructure = true)] - class ModelDisableSyncStructure { - [Column(IsPrimary = false)] - public int pkid { get; set; } - } - class ModelSyncStructure { - [Column(IsPrimary = false)] - public int pkid { get; set; } - } + _sqlserverFixture.SqlServer.Select().ToList(); + } + [Table(DisableSyncStructure = true)] + class ModelDisableSyncStructure + { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + class ModelSyncStructure + { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } - [Fact] - public void Fluent() { - _sqlserverFixture.SqlServer.CodeFirst - //.ConfigEntity(a => { - // a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0"); - // a.Property(b => b.Id).Name("Id22").IsIdentity(true); - // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); - //}) + [Fact] + public void Fluent() + { + _sqlserverFixture.SqlServer.CodeFirst + //.ConfigEntity(a => { + // a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0"); + // a.Property(b => b.Id).Name("Id22").IsIdentity(true); + // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); + //}) - .ConfigEntity(typeof(TestFluenttb1), a => { - a.Name("xxdkdkdk1222").SelectFilter("a.Id22dd > 1"); - a.Property("Id").Name("Id22dd").IsIdentity(true); - a.Property("Name").DbType("varchar(101)").IsNullable(true); - }) + .ConfigEntity(typeof(TestFluenttb1), a => + { + a.Name("xxdkdkdk1222").SelectFilter("a.Id22dd > 1"); + a.Property("Id").Name("Id22dd").IsIdentity(true); + a.Property("Name").DbType("varchar(101)").IsNullable(true); + }) - .ConfigEntity(a => { - a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0"); - a.Property(b => b.Id).Name("Id22").IsIdentity(true); - a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); - }) - ; + .ConfigEntity(a => + { + a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0"); + a.Property(b => b.Id).Name("Id22").IsIdentity(true); + a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); + }) + ; - var ddl1 = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); - var ddl2 = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + var ddl1 = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + var ddl2 = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); - var t1id = _sqlserverFixture.SqlServer.Insert().AppendData(new TestFluenttb1 { }).ExecuteIdentity(); - var t1 = _sqlserverFixture.SqlServer.Select(t1id).ToOne(); + var t1id = _sqlserverFixture.SqlServer.Insert().AppendData(new TestFluenttb1 { }).ExecuteIdentity(); + var t1 = _sqlserverFixture.SqlServer.Select(t1id).ToOne(); - var t2lastId = _sqlserverFixture.SqlServer.Select().Max(a => a.Id); - var t2affrows = _sqlserverFixture.SqlServer.Insert().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows(); - var t2 = _sqlserverFixture.SqlServer.Select(t2lastId + 1).ToOne(); - } + var t2lastId = _sqlserverFixture.SqlServer.Select().Max(a => a.Id); + var t2affrows = _sqlserverFixture.SqlServer.Insert().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows(); + var t2 = _sqlserverFixture.SqlServer.Select(t2lastId + 1).ToOne(); + } - [Fact] - public void GroupPrimaryKey() { - _sqlserverFixture.SqlServer.CodeFirst.SyncStructure(); - g.mysql.CodeFirst.SyncStructure(); - g.pgsql.CodeFirst.SyncStructure(); - g.sqlite.CodeFirst.SyncStructure(); - g.oracle.CodeFirst.SyncStructure(); - } + [Fact] + public void GroupPrimaryKey() + { + _sqlserverFixture.SqlServer.CodeFirst.SyncStructure(); + g.mysql.CodeFirst.SyncStructure(); + g.pgsql.CodeFirst.SyncStructure(); + g.sqlite.CodeFirst.SyncStructure(); + g.oracle.CodeFirst.SyncStructure(); + } - class TestFluenttb1 - { - public int Id { get; set; } + class TestFluenttb1 + { + public int Id { get; set; } - public string name { get; set; } = "defaultValue"; - } + public string name { get; set; } = "defaultValue"; + } - [Table(Name = "cccccdddwww")] - class TestFluenttb2 - { - [Column(Name = "Idx", IsPrimary = true, IsIdentity = false)] - public int Id { get; set; } + [Table(Name = "cccccdddwww")] + class TestFluenttb2 + { + [Column(Name = "Idx", IsPrimary = true, IsIdentity = false)] + public int Id { get; set; } - public string name { get; set; } = "defaultValue"; - } + public string name { get; set; } = "defaultValue"; + } - [Table(Name = "test_groupkey")] - class TestgroupkeyTb { - [Column(IsPrimary = true)] - public int Id { get; set; } - [Column(IsPrimary = true)] - public int id2 { get; set; } + [Table(Name = "test_groupkey")] + class TestgroupkeyTb + { + [Column(IsPrimary = true)] + public int Id { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } - public string name { get; set; } = "defaultValue"; - } + public string name { get; set; } = "defaultValue"; + } - [Fact] - public void IsIgnore() { - var item = new TestIsIgnore { }; - Assert.Equal(1, _sqlserverFixture.SqlServer.Insert().AppendData(item).ExecuteAffrows()); + [Fact] + public void IsIgnore() + { + var item = new TestIsIgnore { }; + Assert.Equal(1, _sqlserverFixture.SqlServer.Insert().AppendData(item).ExecuteAffrows()); - var find = _sqlserverFixture.SqlServer.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - } + var find = _sqlserverFixture.SqlServer.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + } - class TestIsIgnore { - public Guid id { get; set; } + class TestIsIgnore + { + public Guid id { get; set; } - [Column(IsIgnore = true)] - public bool isignore { get; set; } - } - } + [Column(IsIgnore = true)] + public bool isignore { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerCollection.cs b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerCollection.cs index 68b6163e..11c2627f 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerCollection.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerCollection.cs @@ -5,11 +5,11 @@ using Xunit; namespace FreeSql.Tests.DataContext.SqlServer { - [CollectionDefinition("SqlServerCollection")] - public class SqlServerCollection : ICollectionFixture - { - // This class has no code, and is never created. Its purpose is simply - // to be the place to apply [CollectionDefinition] and all the - // ICollectionFixture<> interfaces. - } + [CollectionDefinition("SqlServerCollection")] + public class SqlServerCollection : ICollectionFixture + { + // This class has no code, and is never created. Its purpose is simply + // to be the place to apply [CollectionDefinition] and all the + // ICollectionFixture<> interfaces. + } } diff --git a/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs index bb00942c..712e8b35 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs @@ -6,56 +6,56 @@ using System.Text; namespace FreeSql.Tests.DataContext.SqlServer { - public class SqlServerFixture : IDisposable - { - public SqlServerFixture() - { - sqlServerLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=(localdb)\\mssqllocaldb;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseMonitorCommand(t => Trace.WriteLine(t.CommandText)) - .Build()); + public class SqlServerFixture : IDisposable + { + public SqlServerFixture() + { + sqlServerLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=(localdb)\\mssqllocaldb;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseMonitorCommand(t => Trace.WriteLine(t.CommandText)) + .Build()); - // ... initialize data in the test database ... - } + // ... initialize data in the test database ... + } - public void Dispose() - { - // ... clean up test data from the database ... - ClearDataBase(); - } + public void Dispose() + { + // ... clean up test data from the database ... + ClearDataBase(); + } - private void ClearDataBase() - { - var dataTables = SqlServer.DbFirst.GetTablesByDatabase(); - if (dataTables.Any(item => item.Name == "TopicAddField" && item.Schema == "dbo2")) - { - SqlServer.Ado.ExecuteNonQuery("TRUNCATE TABLE dbo2.TopicAddField "); - SqlServer.Ado.ExecuteNonQuery("DROP TABLE dbo2.TopicAddField"); - SqlServer.Ado.ExecuteNonQuery("DROP SCHEMA dbo2"); - } + private void ClearDataBase() + { + var dataTables = SqlServer.DbFirst.GetTablesByDatabase(); + if (dataTables.Any(item => item.Name == "TopicAddField" && item.Schema == "dbo2")) + { + SqlServer.Ado.ExecuteNonQuery("TRUNCATE TABLE dbo2.TopicAddField "); + SqlServer.Ado.ExecuteNonQuery("DROP TABLE dbo2.TopicAddField"); + SqlServer.Ado.ExecuteNonQuery("DROP SCHEMA dbo2"); + } - var tempTables = new string[] { "cccccdddwww", "song", "tag", "Song_tag", "tb_alltype", "tb_topic", "tb_topic22", - "tb_topic22211", "tb_topic111333", "TestTypeInfo", "TestTypeInfo333", "TestTypeParentInfo", - "TestTypeParentInfo23123", "xxdkdkdk1222", "xxx"}; - foreach (var tempTable in tempTables) - { - DeleteTmpTable(dataTables, tempTable); - } - } + var tempTables = new string[] { "cccccdddwww", "song", "tag", "Song_tag", "tb_alltype", "tb_topic", "tb_topic22", + "tb_topic22211", "tb_topic111333", "TestTypeInfo", "TestTypeInfo333", "TestTypeParentInfo", + "TestTypeParentInfo23123", "xxdkdkdk1222", "xxx"}; + foreach (var tempTable in tempTables) + { + DeleteTmpTable(dataTables, tempTable); + } + } - private void DeleteTmpTable(List dbTables, string deleteTableName, string schemaName = "dbo") - { - if (dbTables.Any(item => item.Name.ToLower() == deleteTableName.ToLower() && item.Schema.ToLower() == schemaName.ToLower())) - { - SqlServer.Ado.ExecuteNonQuery($"TRUNCATE TABLE {schemaName.ToLower()}.{deleteTableName}"); - SqlServer.Ado.ExecuteNonQuery($"DROP TABLE {schemaName.ToLower()}.{deleteTableName}"); - } - } + private void DeleteTmpTable(List dbTables, string deleteTableName, string schemaName = "dbo") + { + if (dbTables.Any(item => item.Name.ToLower() == deleteTableName.ToLower() && item.Schema.ToLower() == schemaName.ToLower())) + { + SqlServer.Ado.ExecuteNonQuery($"TRUNCATE TABLE {schemaName.ToLower()}.{deleteTableName}"); + SqlServer.Ado.ExecuteNonQuery($"DROP TABLE {schemaName.ToLower()}.{deleteTableName}"); + } + } - private Lazy sqlServerLazy; - public IFreeSql SqlServer => sqlServerLazy.Value; - } + private Lazy sqlServerLazy; + public IFreeSql SqlServer => sqlServerLazy.Value; + } } diff --git a/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs b/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs index 04939deb..6ae782b5 100644 --- a/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs @@ -10,423 +10,440 @@ using Npgsql.LegacyPostgis; using FreeSql.Internal; using System.Linq.Expressions; -namespace FreeSql.ExpressionTree { - public class GetDataReaderValueBlockExpressionTest { +namespace FreeSql.ExpressionTree +{ + public class GetDataReaderValueBlockExpressionTest + { - [Fact] - public void Guid2() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.Empty)); - Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), Guid.Empty)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.NewGuid())); - var newguid = Guid.NewGuid(); - Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid), newguid)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(null)); - Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), null)); + [Fact] + public void Guid2() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.Empty)); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), Guid.Empty)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.NewGuid())); + var newguid = Guid.NewGuid(); + Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid), newguid)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(null)); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), null)); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(Guid.Empty)); - Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid?), Guid.Empty)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(newguid)); - Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid?), newguid)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(Guid?), null)); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(Guid.Empty)); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid?), Guid.Empty)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(newguid)); + Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid?), newguid)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(Guid?), null)); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.Empty.ToString())); - Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), Guid.Empty.ToString())); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(newguid.ToString())); - Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid), newguid.ToString())); - var exp333 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant("-1")); - Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), "-1")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.Empty.ToString())); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), Guid.Empty.ToString())); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(newguid.ToString())); + Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid), newguid.ToString())); + var exp333 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant("-1")); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), "-1")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(Guid.Empty.ToString())); - Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid?), Guid.Empty.ToString())); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(newguid.ToString())); - Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid?), newguid.ToString())); - var exp3333 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant("-1")); - Assert.Null(Utils.GetDataReaderValue(typeof(Guid?), "-1")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(Guid.Empty.ToString())); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid?), Guid.Empty.ToString())); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(newguid.ToString())); + Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid?), newguid.ToString())); + var exp3333 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant("-1")); + Assert.Null(Utils.GetDataReaderValue(typeof(Guid?), "-1")); + } - [Fact] - public void Boolean() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant(true)); - Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool), true)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant(false)); - Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool), false)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant(null)); - Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool), null)); + [Fact] + public void Boolean() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant(true)); + Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool), true)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant(false)); + Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool), false)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant(null)); + Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool), null)); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(bool?), Expression.Constant(true)); - Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool?), true)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(bool?), Expression.Constant(false)); - Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool?), false)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(bool?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(bool?), null)); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(bool?), Expression.Constant(true)); + Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool?), true)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(bool?), Expression.Constant(false)); + Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool?), false)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(bool?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(bool?), null)); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("1")); - Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool), true)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("0")); - Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool), false)); - var exp333 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("-1")); - Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool), true)); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("1")); + Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool), true)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("0")); + Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool), false)); + var exp333 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("-1")); + Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool), true)); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("true")); - Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool?), true)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("True")); - Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool?), true)); - var exp3333 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("false")); - Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool?), false)); - var exp4444 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("False")); - Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool?), false)); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("true")); + Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool?), true)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("True")); + Assert.Equal(true, Utils.GetDataReaderValue(typeof(bool?), true)); + var exp3333 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("false")); + Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool?), false)); + var exp4444 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant("False")); + Assert.Equal(false, Utils.GetDataReaderValue(typeof(bool?), false)); + } - [Fact] - public void SByte() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant(sbyte.MinValue)); - Assert.Equal(sbyte.MinValue, Utils.GetDataReaderValue(typeof(sbyte), sbyte.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant(sbyte.MaxValue)); - Assert.Equal(sbyte.MaxValue, Utils.GetDataReaderValue(typeof(sbyte), sbyte.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant("127")); - Assert.Equal((sbyte)127, Utils.GetDataReaderValue(typeof(sbyte), "127")); + [Fact] + public void SByte() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant(sbyte.MinValue)); + Assert.Equal(sbyte.MinValue, Utils.GetDataReaderValue(typeof(sbyte), sbyte.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant(sbyte.MaxValue)); + Assert.Equal(sbyte.MaxValue, Utils.GetDataReaderValue(typeof(sbyte), sbyte.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant("127")); + Assert.Equal((sbyte)127, Utils.GetDataReaderValue(typeof(sbyte), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant(sbyte.MinValue)); - Assert.Equal(sbyte.MinValue, Utils.GetDataReaderValue(typeof(sbyte?), sbyte.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant(sbyte.MaxValue)); - Assert.Equal(sbyte.MaxValue, Utils.GetDataReaderValue(typeof(sbyte?), sbyte.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant("127")); - Assert.Equal((sbyte)127, Utils.GetDataReaderValue(typeof(sbyte?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant(sbyte.MinValue)); + Assert.Equal(sbyte.MinValue, Utils.GetDataReaderValue(typeof(sbyte?), sbyte.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant(sbyte.MaxValue)); + Assert.Equal(sbyte.MaxValue, Utils.GetDataReaderValue(typeof(sbyte?), sbyte.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant("127")); + Assert.Equal((sbyte)127, Utils.GetDataReaderValue(typeof(sbyte?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant(null)); - Assert.Equal(default(sbyte), Utils.GetDataReaderValue(typeof(sbyte), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant("aaa")); - Assert.Equal(default(sbyte), Utils.GetDataReaderValue(typeof(sbyte), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant(null)); + Assert.Equal(default(sbyte), Utils.GetDataReaderValue(typeof(sbyte), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte), Expression.Constant("aaa")); + Assert.Equal(default(sbyte), Utils.GetDataReaderValue(typeof(sbyte), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(sbyte?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(sbyte?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(sbyte?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(sbyte?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(sbyte?), "aaa")); + } - [Fact] - public void Short() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant(short.MinValue)); - Assert.Equal(short.MinValue, Utils.GetDataReaderValue(typeof(short), short.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant(short.MaxValue)); - Assert.Equal(short.MaxValue, Utils.GetDataReaderValue(typeof(short), short.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant("127")); - Assert.Equal((short)127, Utils.GetDataReaderValue(typeof(short), "127")); + [Fact] + public void Short() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant(short.MinValue)); + Assert.Equal(short.MinValue, Utils.GetDataReaderValue(typeof(short), short.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant(short.MaxValue)); + Assert.Equal(short.MaxValue, Utils.GetDataReaderValue(typeof(short), short.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant("127")); + Assert.Equal((short)127, Utils.GetDataReaderValue(typeof(short), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant(short.MinValue)); - Assert.Equal(short.MinValue, Utils.GetDataReaderValue(typeof(short?), short.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant(short.MaxValue)); - Assert.Equal(short.MaxValue, Utils.GetDataReaderValue(typeof(short?), short.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant("127")); - Assert.Equal((short)127, Utils.GetDataReaderValue(typeof(short?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant(short.MinValue)); + Assert.Equal(short.MinValue, Utils.GetDataReaderValue(typeof(short?), short.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant(short.MaxValue)); + Assert.Equal(short.MaxValue, Utils.GetDataReaderValue(typeof(short?), short.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant("127")); + Assert.Equal((short)127, Utils.GetDataReaderValue(typeof(short?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant(null)); - Assert.Equal(default(short), Utils.GetDataReaderValue(typeof(short), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant("aaa")); - Assert.Equal(default(short), Utils.GetDataReaderValue(typeof(short), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant(null)); + Assert.Equal(default(short), Utils.GetDataReaderValue(typeof(short), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(short), Expression.Constant("aaa")); + Assert.Equal(default(short), Utils.GetDataReaderValue(typeof(short), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(short?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(short?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(short?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(short?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(short?), "aaa")); + } - [Fact] - public void Int() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant(int.MinValue)); - Assert.Equal(int.MinValue, Utils.GetDataReaderValue(typeof(int), int.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant(int.MaxValue)); - Assert.Equal(int.MaxValue, Utils.GetDataReaderValue(typeof(int), int.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant("127")); - Assert.Equal((int)127, Utils.GetDataReaderValue(typeof(int), "127")); + [Fact] + public void Int() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant(int.MinValue)); + Assert.Equal(int.MinValue, Utils.GetDataReaderValue(typeof(int), int.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant(int.MaxValue)); + Assert.Equal(int.MaxValue, Utils.GetDataReaderValue(typeof(int), int.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant("127")); + Assert.Equal((int)127, Utils.GetDataReaderValue(typeof(int), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant(int.MinValue)); - Assert.Equal(int.MinValue, Utils.GetDataReaderValue(typeof(int?), int.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant(int.MaxValue)); - Assert.Equal(int.MaxValue, Utils.GetDataReaderValue(typeof(int?), int.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant("127")); - Assert.Equal((int)127, Utils.GetDataReaderValue(typeof(int?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant(int.MinValue)); + Assert.Equal(int.MinValue, Utils.GetDataReaderValue(typeof(int?), int.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant(int.MaxValue)); + Assert.Equal(int.MaxValue, Utils.GetDataReaderValue(typeof(int?), int.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant("127")); + Assert.Equal((int)127, Utils.GetDataReaderValue(typeof(int?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant(null)); - Assert.Equal(default(int), Utils.GetDataReaderValue(typeof(int), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant("aaa")); - Assert.Equal(default(int), Utils.GetDataReaderValue(typeof(int), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant(null)); + Assert.Equal(default(int), Utils.GetDataReaderValue(typeof(int), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(int), Expression.Constant("aaa")); + Assert.Equal(default(int), Utils.GetDataReaderValue(typeof(int), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(int?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(int?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(int?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(int?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(int?), "aaa")); + } - [Fact] - public void Long() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant(long.MinValue)); - Assert.Equal(long.MinValue, Utils.GetDataReaderValue(typeof(long), long.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant(long.MaxValue)); - Assert.Equal(long.MaxValue, Utils.GetDataReaderValue(typeof(long), long.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant("127")); - Assert.Equal((long)127, Utils.GetDataReaderValue(typeof(long), "127")); + [Fact] + public void Long() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant(long.MinValue)); + Assert.Equal(long.MinValue, Utils.GetDataReaderValue(typeof(long), long.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant(long.MaxValue)); + Assert.Equal(long.MaxValue, Utils.GetDataReaderValue(typeof(long), long.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant("127")); + Assert.Equal((long)127, Utils.GetDataReaderValue(typeof(long), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant(long.MinValue)); - Assert.Equal(long.MinValue, Utils.GetDataReaderValue(typeof(long?), long.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant(long.MaxValue)); - Assert.Equal(long.MaxValue, Utils.GetDataReaderValue(typeof(long?), long.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant("127")); - Assert.Equal((long)127, Utils.GetDataReaderValue(typeof(long?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant(long.MinValue)); + Assert.Equal(long.MinValue, Utils.GetDataReaderValue(typeof(long?), long.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant(long.MaxValue)); + Assert.Equal(long.MaxValue, Utils.GetDataReaderValue(typeof(long?), long.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant("127")); + Assert.Equal((long)127, Utils.GetDataReaderValue(typeof(long?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant(null)); - Assert.Equal(default(long), Utils.GetDataReaderValue(typeof(long), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant("aaa")); - Assert.Equal(default(long), Utils.GetDataReaderValue(typeof(long), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant(null)); + Assert.Equal(default(long), Utils.GetDataReaderValue(typeof(long), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(long), Expression.Constant("aaa")); + Assert.Equal(default(long), Utils.GetDataReaderValue(typeof(long), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(long?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(long?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(long?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(long?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(long?), "aaa")); + } - [Fact] - public void Byte() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant(byte.MinValue)); - Assert.Equal(byte.MinValue, Utils.GetDataReaderValue(typeof(byte), byte.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant(byte.MaxValue)); - Assert.Equal(byte.MaxValue, Utils.GetDataReaderValue(typeof(byte), byte.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant("127")); - Assert.Equal((byte)127, Utils.GetDataReaderValue(typeof(byte), "127")); + [Fact] + public void Byte() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant(byte.MinValue)); + Assert.Equal(byte.MinValue, Utils.GetDataReaderValue(typeof(byte), byte.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant(byte.MaxValue)); + Assert.Equal(byte.MaxValue, Utils.GetDataReaderValue(typeof(byte), byte.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant("127")); + Assert.Equal((byte)127, Utils.GetDataReaderValue(typeof(byte), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant(byte.MinValue)); - Assert.Equal(byte.MinValue, Utils.GetDataReaderValue(typeof(byte?), byte.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant(byte.MaxValue)); - Assert.Equal(byte.MaxValue, Utils.GetDataReaderValue(typeof(byte?), byte.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant("127")); - Assert.Equal((byte)127, Utils.GetDataReaderValue(typeof(byte?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant(byte.MinValue)); + Assert.Equal(byte.MinValue, Utils.GetDataReaderValue(typeof(byte?), byte.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant(byte.MaxValue)); + Assert.Equal(byte.MaxValue, Utils.GetDataReaderValue(typeof(byte?), byte.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant("127")); + Assert.Equal((byte)127, Utils.GetDataReaderValue(typeof(byte?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant(null)); - Assert.Equal(default(byte), Utils.GetDataReaderValue(typeof(byte), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant("aaa")); - Assert.Equal(default(byte), Utils.GetDataReaderValue(typeof(byte), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant(null)); + Assert.Equal(default(byte), Utils.GetDataReaderValue(typeof(byte), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(byte), Expression.Constant("aaa")); + Assert.Equal(default(byte), Utils.GetDataReaderValue(typeof(byte), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(byte?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(byte?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(byte?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(byte?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(byte?), "aaa")); + } - [Fact] - public void UShort() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant(ushort.MinValue)); - Assert.Equal(ushort.MinValue, Utils.GetDataReaderValue(typeof(ushort), ushort.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant(ushort.MaxValue)); - Assert.Equal(ushort.MaxValue, Utils.GetDataReaderValue(typeof(ushort), ushort.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant("127")); - Assert.Equal((ushort)127, Utils.GetDataReaderValue(typeof(ushort), "127")); + [Fact] + public void UShort() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant(ushort.MinValue)); + Assert.Equal(ushort.MinValue, Utils.GetDataReaderValue(typeof(ushort), ushort.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant(ushort.MaxValue)); + Assert.Equal(ushort.MaxValue, Utils.GetDataReaderValue(typeof(ushort), ushort.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant("127")); + Assert.Equal((ushort)127, Utils.GetDataReaderValue(typeof(ushort), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant(ushort.MinValue)); - Assert.Equal(ushort.MinValue, Utils.GetDataReaderValue(typeof(ushort?), ushort.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant(ushort.MaxValue)); - Assert.Equal(ushort.MaxValue, Utils.GetDataReaderValue(typeof(ushort?), ushort.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant("127")); - Assert.Equal((ushort)127, Utils.GetDataReaderValue(typeof(ushort?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant(ushort.MinValue)); + Assert.Equal(ushort.MinValue, Utils.GetDataReaderValue(typeof(ushort?), ushort.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant(ushort.MaxValue)); + Assert.Equal(ushort.MaxValue, Utils.GetDataReaderValue(typeof(ushort?), ushort.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant("127")); + Assert.Equal((ushort)127, Utils.GetDataReaderValue(typeof(ushort?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant(null)); - Assert.Equal(default(ushort), Utils.GetDataReaderValue(typeof(ushort), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant("aaa")); - Assert.Equal(default(ushort), Utils.GetDataReaderValue(typeof(ushort), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant(null)); + Assert.Equal(default(ushort), Utils.GetDataReaderValue(typeof(ushort), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(ushort), Expression.Constant("aaa")); + Assert.Equal(default(ushort), Utils.GetDataReaderValue(typeof(ushort), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(ushort?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(ushort?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(ushort?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(ushort?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(ushort?), "aaa")); + } - [Fact] - public void UInt() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant(uint.MinValue)); - Assert.Equal(uint.MinValue, Utils.GetDataReaderValue(typeof(uint), uint.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant(uint.MaxValue)); - Assert.Equal(uint.MaxValue, Utils.GetDataReaderValue(typeof(uint), uint.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant("127")); - Assert.Equal((uint)127, Utils.GetDataReaderValue(typeof(uint), "127")); + [Fact] + public void UInt() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant(uint.MinValue)); + Assert.Equal(uint.MinValue, Utils.GetDataReaderValue(typeof(uint), uint.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant(uint.MaxValue)); + Assert.Equal(uint.MaxValue, Utils.GetDataReaderValue(typeof(uint), uint.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant("127")); + Assert.Equal((uint)127, Utils.GetDataReaderValue(typeof(uint), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant(uint.MinValue)); - Assert.Equal(uint.MinValue, Utils.GetDataReaderValue(typeof(uint?), uint.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant(uint.MaxValue)); - Assert.Equal(uint.MaxValue, Utils.GetDataReaderValue(typeof(uint?), uint.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant("127")); - Assert.Equal((uint)127, Utils.GetDataReaderValue(typeof(uint?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant(uint.MinValue)); + Assert.Equal(uint.MinValue, Utils.GetDataReaderValue(typeof(uint?), uint.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant(uint.MaxValue)); + Assert.Equal(uint.MaxValue, Utils.GetDataReaderValue(typeof(uint?), uint.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant("127")); + Assert.Equal((uint)127, Utils.GetDataReaderValue(typeof(uint?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant(null)); - Assert.Equal(default(uint), Utils.GetDataReaderValue(typeof(uint), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant("aaa")); - Assert.Equal(default(uint), Utils.GetDataReaderValue(typeof(uint), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant(null)); + Assert.Equal(default(uint), Utils.GetDataReaderValue(typeof(uint), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(uint), Expression.Constant("aaa")); + Assert.Equal(default(uint), Utils.GetDataReaderValue(typeof(uint), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(uint?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(uint?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(uint?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(uint?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(uint?), "aaa")); + } - [Fact] - public void ULong() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant(ulong.MinValue)); - Assert.Equal(ulong.MinValue, Utils.GetDataReaderValue(typeof(ulong), ulong.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant(ulong.MaxValue)); - Assert.Equal(ulong.MaxValue, Utils.GetDataReaderValue(typeof(ulong), ulong.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant("127")); - Assert.Equal((ulong)127, Utils.GetDataReaderValue(typeof(ulong), "127")); + [Fact] + public void ULong() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant(ulong.MinValue)); + Assert.Equal(ulong.MinValue, Utils.GetDataReaderValue(typeof(ulong), ulong.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant(ulong.MaxValue)); + Assert.Equal(ulong.MaxValue, Utils.GetDataReaderValue(typeof(ulong), ulong.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant("127")); + Assert.Equal((ulong)127, Utils.GetDataReaderValue(typeof(ulong), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant(ulong.MinValue)); - Assert.Equal(ulong.MinValue, Utils.GetDataReaderValue(typeof(ulong?), ulong.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant(ulong.MaxValue)); - Assert.Equal(ulong.MaxValue, Utils.GetDataReaderValue(typeof(ulong?), ulong.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant("127")); - Assert.Equal((ulong)127, Utils.GetDataReaderValue(typeof(ulong?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant(ulong.MinValue)); + Assert.Equal(ulong.MinValue, Utils.GetDataReaderValue(typeof(ulong?), ulong.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant(ulong.MaxValue)); + Assert.Equal(ulong.MaxValue, Utils.GetDataReaderValue(typeof(ulong?), ulong.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant("127")); + Assert.Equal((ulong)127, Utils.GetDataReaderValue(typeof(ulong?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant(null)); - Assert.Equal(default(ulong), Utils.GetDataReaderValue(typeof(ulong), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant("aaa")); - Assert.Equal(default(ulong), Utils.GetDataReaderValue(typeof(ulong), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant(null)); + Assert.Equal(default(ulong), Utils.GetDataReaderValue(typeof(ulong), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(ulong), Expression.Constant("aaa")); + Assert.Equal(default(ulong), Utils.GetDataReaderValue(typeof(ulong), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(ulong?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(ulong?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(ulong?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(ulong?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(ulong?), "aaa")); + } - [Fact] - public void Float() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant(float.MinValue)); - Assert.Equal(float.MinValue, Utils.GetDataReaderValue(typeof(float), float.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant(float.MaxValue)); - Assert.Equal(float.MaxValue, Utils.GetDataReaderValue(typeof(float), float.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant("127")); - Assert.Equal((float)127, Utils.GetDataReaderValue(typeof(float), "127")); + [Fact] + public void Float() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant(float.MinValue)); + Assert.Equal(float.MinValue, Utils.GetDataReaderValue(typeof(float), float.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant(float.MaxValue)); + Assert.Equal(float.MaxValue, Utils.GetDataReaderValue(typeof(float), float.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant("127")); + Assert.Equal((float)127, Utils.GetDataReaderValue(typeof(float), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant(float.MinValue)); - Assert.Equal(float.MinValue, Utils.GetDataReaderValue(typeof(float?), float.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant(float.MaxValue)); - Assert.Equal(float.MaxValue, Utils.GetDataReaderValue(typeof(float?), float.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant("127")); - Assert.Equal((float)127, Utils.GetDataReaderValue(typeof(float?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant(float.MinValue)); + Assert.Equal(float.MinValue, Utils.GetDataReaderValue(typeof(float?), float.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant(float.MaxValue)); + Assert.Equal(float.MaxValue, Utils.GetDataReaderValue(typeof(float?), float.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant("127")); + Assert.Equal((float)127, Utils.GetDataReaderValue(typeof(float?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant(null)); - Assert.Equal(default(float), Utils.GetDataReaderValue(typeof(float), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant("aaa")); - Assert.Equal(default(float), Utils.GetDataReaderValue(typeof(float), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant(null)); + Assert.Equal(default(float), Utils.GetDataReaderValue(typeof(float), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(float), Expression.Constant("aaa")); + Assert.Equal(default(float), Utils.GetDataReaderValue(typeof(float), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(float?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(float?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(float?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(float?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(float?), "aaa")); + } - [Fact] - public void Double() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant(double.MinValue)); - Assert.Equal(double.MinValue, Utils.GetDataReaderValue(typeof(double), double.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant(double.MaxValue)); - Assert.Equal(double.MaxValue, Utils.GetDataReaderValue(typeof(double), double.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant("127")); - Assert.Equal((double)127, Utils.GetDataReaderValue(typeof(double), "127")); + [Fact] + public void Double() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant(double.MinValue)); + Assert.Equal(double.MinValue, Utils.GetDataReaderValue(typeof(double), double.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant(double.MaxValue)); + Assert.Equal(double.MaxValue, Utils.GetDataReaderValue(typeof(double), double.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant("127")); + Assert.Equal((double)127, Utils.GetDataReaderValue(typeof(double), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant(double.MinValue)); - Assert.Equal(double.MinValue, Utils.GetDataReaderValue(typeof(double?), double.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant(double.MaxValue)); - Assert.Equal(double.MaxValue, Utils.GetDataReaderValue(typeof(double?), double.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant("127")); - Assert.Equal((double)127, Utils.GetDataReaderValue(typeof(double?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant(double.MinValue)); + Assert.Equal(double.MinValue, Utils.GetDataReaderValue(typeof(double?), double.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant(double.MaxValue)); + Assert.Equal(double.MaxValue, Utils.GetDataReaderValue(typeof(double?), double.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant("127")); + Assert.Equal((double)127, Utils.GetDataReaderValue(typeof(double?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant(null)); - Assert.Equal(default(double), Utils.GetDataReaderValue(typeof(double), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant("aaa")); - Assert.Equal(default(double), Utils.GetDataReaderValue(typeof(double), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant(null)); + Assert.Equal(default(double), Utils.GetDataReaderValue(typeof(double), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(double), Expression.Constant("aaa")); + Assert.Equal(default(double), Utils.GetDataReaderValue(typeof(double), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(double?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(double?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(double?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(double?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(double?), "aaa")); + } - [Fact] - public void Decimal() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant(decimal.MinValue)); - Assert.Equal(decimal.MinValue, Utils.GetDataReaderValue(typeof(decimal), decimal.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant(decimal.MaxValue)); - Assert.Equal(decimal.MaxValue, Utils.GetDataReaderValue(typeof(decimal), decimal.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant("127")); - Assert.Equal((decimal)127, Utils.GetDataReaderValue(typeof(decimal), "127")); + [Fact] + public void Decimal() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant(decimal.MinValue)); + Assert.Equal(decimal.MinValue, Utils.GetDataReaderValue(typeof(decimal), decimal.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant(decimal.MaxValue)); + Assert.Equal(decimal.MaxValue, Utils.GetDataReaderValue(typeof(decimal), decimal.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant("127")); + Assert.Equal((decimal)127, Utils.GetDataReaderValue(typeof(decimal), "127")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant(decimal.MinValue)); - Assert.Equal(decimal.MinValue, Utils.GetDataReaderValue(typeof(decimal?), decimal.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant(decimal.MaxValue)); - Assert.Equal(decimal.MaxValue, Utils.GetDataReaderValue(typeof(decimal?), decimal.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant("127")); - Assert.Equal((decimal)127, Utils.GetDataReaderValue(typeof(decimal?), "127")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant(decimal.MinValue)); + Assert.Equal(decimal.MinValue, Utils.GetDataReaderValue(typeof(decimal?), decimal.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant(decimal.MaxValue)); + Assert.Equal(decimal.MaxValue, Utils.GetDataReaderValue(typeof(decimal?), decimal.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant("127")); + Assert.Equal((decimal)127, Utils.GetDataReaderValue(typeof(decimal?), "127")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant(null)); - Assert.Equal(default(decimal), Utils.GetDataReaderValue(typeof(decimal), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant("aaa")); - Assert.Equal(default(decimal), Utils.GetDataReaderValue(typeof(decimal), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant(null)); + Assert.Equal(default(decimal), Utils.GetDataReaderValue(typeof(decimal), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(decimal), Expression.Constant("aaa")); + Assert.Equal(default(decimal), Utils.GetDataReaderValue(typeof(decimal), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(decimal?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(decimal?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(decimal?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(decimal?), "aaa")); + } - [Fact] - public void DateTime2() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(DateTime.MinValue)); - Assert.Equal(DateTime.MinValue, Utils.GetDataReaderValue(typeof(DateTime), DateTime.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(DateTime.MaxValue)); - Assert.Equal(DateTime.MaxValue, Utils.GetDataReaderValue(typeof(DateTime), DateTime.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant("2000-1-1")); - Assert.Equal(DateTime.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTime), "2000-1-1")); + [Fact] + public void DateTime2() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(DateTime.MinValue)); + Assert.Equal(DateTime.MinValue, Utils.GetDataReaderValue(typeof(DateTime), DateTime.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(DateTime.MaxValue)); + Assert.Equal(DateTime.MaxValue, Utils.GetDataReaderValue(typeof(DateTime), DateTime.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant("2000-1-1")); + Assert.Equal(DateTime.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTime), "2000-1-1")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(DateTime.MinValue)); - Assert.Equal(DateTime.MinValue, Utils.GetDataReaderValue(typeof(DateTime?), DateTime.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(DateTime.MaxValue)); - Assert.Equal(DateTime.MaxValue, Utils.GetDataReaderValue(typeof(DateTime?), DateTime.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant("2000-1-1")); - Assert.Equal(DateTime.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTime?), "2000-1-1")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(DateTime.MinValue)); + Assert.Equal(DateTime.MinValue, Utils.GetDataReaderValue(typeof(DateTime?), DateTime.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(DateTime.MaxValue)); + Assert.Equal(DateTime.MaxValue, Utils.GetDataReaderValue(typeof(DateTime?), DateTime.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant("2000-1-1")); + Assert.Equal(DateTime.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTime?), "2000-1-1")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(null)); - Assert.Equal(default(DateTime), Utils.GetDataReaderValue(typeof(DateTime), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant("aaa")); - Assert.Equal(default(DateTime), Utils.GetDataReaderValue(typeof(DateTime), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(null)); + Assert.Equal(default(DateTime), Utils.GetDataReaderValue(typeof(DateTime), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant("aaa")); + Assert.Equal(default(DateTime), Utils.GetDataReaderValue(typeof(DateTime), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), "aaa")); - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), "aaa")); + } - [Fact] - public void DateTimeOffset2() { - var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(DateTimeOffset.MinValue)); - Assert.Equal(DateTimeOffset.MinValue, Utils.GetDataReaderValue(typeof(DateTimeOffset), DateTimeOffset.MinValue)); - var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(DateTimeOffset.MaxValue)); - Assert.Equal(DateTimeOffset.MaxValue, Utils.GetDataReaderValue(typeof(DateTimeOffset), DateTimeOffset.MaxValue)); - var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant("2000-1-1")); - Assert.Equal(DateTimeOffset.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTimeOffset), "2000-1-1")); + [Fact] + public void DateTimeOffset2() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(DateTimeOffset.MinValue)); + Assert.Equal(DateTimeOffset.MinValue, Utils.GetDataReaderValue(typeof(DateTimeOffset), DateTimeOffset.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(DateTimeOffset.MaxValue)); + Assert.Equal(DateTimeOffset.MaxValue, Utils.GetDataReaderValue(typeof(DateTimeOffset), DateTimeOffset.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant("2000-1-1")); + Assert.Equal(DateTimeOffset.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTimeOffset), "2000-1-1")); - var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(DateTimeOffset.MinValue)); - Assert.Equal(DateTimeOffset.MinValue, Utils.GetDataReaderValue(typeof(DateTimeOffset?), DateTimeOffset.MinValue)); - var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(DateTimeOffset.MaxValue)); - Assert.Equal(DateTimeOffset.MaxValue, Utils.GetDataReaderValue(typeof(DateTimeOffset?), DateTimeOffset.MaxValue)); - var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("2000-1-1")); - Assert.Equal(DateTimeOffset.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTimeOffset?), "2000-1-1")); + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(DateTimeOffset.MinValue)); + Assert.Equal(DateTimeOffset.MinValue, Utils.GetDataReaderValue(typeof(DateTimeOffset?), DateTimeOffset.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(DateTimeOffset.MaxValue)); + Assert.Equal(DateTimeOffset.MaxValue, Utils.GetDataReaderValue(typeof(DateTimeOffset?), DateTimeOffset.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("2000-1-1")); + Assert.Equal(DateTimeOffset.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTimeOffset?), "2000-1-1")); - var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(null)); - Assert.Equal(default(DateTimeOffset), Utils.GetDataReaderValue(typeof(DateTimeOffset), null)); - var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant("aaa")); - Assert.Equal(default(DateTimeOffset), Utils.GetDataReaderValue(typeof(DateTimeOffset), "aaa")); + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(null)); + Assert.Equal(default(DateTimeOffset), Utils.GetDataReaderValue(typeof(DateTimeOffset), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant("aaa")); + Assert.Equal(default(DateTimeOffset), Utils.GetDataReaderValue(typeof(DateTimeOffset), "aaa")); - var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(null)); - Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), null)); - var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("aaa")); - Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), "aaa")); - } - } + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), "aaa")); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs index ca387c1e..4c6d8e38 100644 --- a/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs @@ -3,41 +3,47 @@ using System.Collections.Generic; using System.Linq.Expressions; using Xunit; -namespace FreeSql.Tests.Extensions { - public class LambadaExpressionExtensionsTest { +namespace FreeSql.Tests.Extensions +{ + public class LambadaExpressionExtensionsTest + { - [Fact] - public void And() { - Expression> where = a => a.id == Guid.Empty; + [Fact] + public void And() + { + Expression> where = a => a.id == Guid.Empty; - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" > 0)", g.sqlite.Select().Where(where.And(b => b.num > 0)).ToSql().Replace("\r\n", "")); - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.And(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" = 1 AND a.\"num\" = 2)", g.sqlite.Select().Where(where.And(b => b.num == 1).And(b => b.num == 2)).ToSql().Replace("\r\n", "")); - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.And(false, b => b.num == 1).And(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); - } + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" > 0)", g.sqlite.Select().Where(where.And(b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.And(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" = 1 AND a.\"num\" = 2)", g.sqlite.Select().Where(where.And(b => b.num == 1).And(b => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.And(false, b => b.num == 1).And(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); + } - [Fact] - public void Or() { - Expression> where = a => a.id == Guid.Empty; + [Fact] + public void Or() + { + Expression> where = a => a.id == Guid.Empty; - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE ((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" > 0))", g.sqlite.Select().Where(where.Or(b => b.num > 0)).ToSql().Replace("\r\n", "")); - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Or(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" = 1) OR a.\"num\" = 2))", g.sqlite.Select().Where(where.Or(b => b.num == 1).Or(b => b.num == 2)).ToSql().Replace("\r\n", "")); - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Or(false, b => b.num == 1).Or(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); - } + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE ((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" > 0))", g.sqlite.Select().Where(where.Or(b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Or(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" = 1) OR a.\"num\" = 2))", g.sqlite.Select().Where(where.Or(b => b.num == 1).Or(b => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Or(false, b => b.num == 1).Or(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); + } - [Fact] - public void Not() { - Expression> where = a => a.id == Guid.Empty; + [Fact] + public void Not() + { + Expression> where = a => a.id == Guid.Empty; - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (not(a.\"id\" = '00000000-0000-0000-0000-000000000000'))", g.sqlite.Select().Where(where.Not()).ToSql().Replace("\r\n", "")); - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Not(false)).ToSql().Replace("\r\n", "")); - } + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (not(a.\"id\" = '00000000-0000-0000-0000-000000000000'))", g.sqlite.Select().Where(where.Not()).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Not(false)).ToSql().Replace("\r\n", "")); + } - class testExpAddOr { - public Guid id { get; set; } + class testExpAddOr + { + public Guid id { get; set; } - public int num { get; set; } - } - } + public int num { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Extensions/StringExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/Extensions/StringExtensionsTest.cs index c7352c24..5b885fca 100644 --- a/FreeSql.Tests/FreeSql.Tests/Extensions/StringExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Extensions/StringExtensionsTest.cs @@ -1,65 +1,70 @@ using Xunit; -namespace FreeSql.Tests.Extensions { - public class StringExtensionsTest { - [Fact] - public void FormatMySql() { +namespace FreeSql.Tests.Extensions +{ + public class StringExtensionsTest + { + [Fact] + public void FormatMySql() + { - Assert.Empty(((string)null).FormatMySql("11")); - Assert.Equal("a=1", "a={0}".FormatMySql(1)); - Assert.Equal("a =1", "a ={0}".FormatMySql(1)); - Assert.Equal("a = 1", "a = {0}".FormatMySql(1)); - Assert.Equal("a='a'", "a={0}".FormatMySql('a')); - Assert.Equal("a ='a'", "a ={0}".FormatMySql('a')); - Assert.Equal("a = 'a'", "a = {0}".FormatMySql('a')); + Assert.Empty(((string)null).FormatMySql("11")); + Assert.Equal("a=1", "a={0}".FormatMySql(1)); + Assert.Equal("a =1", "a ={0}".FormatMySql(1)); + Assert.Equal("a = 1", "a = {0}".FormatMySql(1)); + Assert.Equal("a='a'", "a={0}".FormatMySql('a')); + Assert.Equal("a ='a'", "a ={0}".FormatMySql('a')); + Assert.Equal("a = 'a'", "a = {0}".FormatMySql('a')); - Assert.Equal("a=1 and b IS NULL", "a={0} and b={1}".FormatMySql(1, null)); - Assert.Equal("a =1 and b IS NULL", "a ={0} and b ={1}".FormatMySql(1, null)); - Assert.Equal("a = 1 and b IS NULL", "a = {0} and b = {1}".FormatMySql(1, null)); + Assert.Equal("a=1 and b IS NULL", "a={0} and b={1}".FormatMySql(1, null)); + Assert.Equal("a =1 and b IS NULL", "a ={0} and b ={1}".FormatMySql(1, null)); + Assert.Equal("a = 1 and b IS NULL", "a = {0} and b = {1}".FormatMySql(1, null)); - Assert.Equal("a=1 and b IS NULL and c in (1,2,3,4)", "a={0} and b={1} and c in {2}".FormatMySql(1, null, new[] { 1, 2, 3, 4 })); - Assert.Equal("a=1 and b IS NULL and c IS NULL", "a={0} and b={1} and c in {2}".FormatMySql(1, null, null)); - Assert.Equal("a=1 and b IS NULL and c not IS NULL", "a={0} and b={1} and c not in {2}".FormatMySql(1, null, null)); - } + Assert.Equal("a=1 and b IS NULL and c in (1,2,3,4)", "a={0} and b={1} and c in {2}".FormatMySql(1, null, new[] { 1, 2, 3, 4 })); + Assert.Equal("a=1 and b IS NULL and c IS NULL", "a={0} and b={1} and c in {2}".FormatMySql(1, null, null)); + Assert.Equal("a=1 and b IS NULL and c not IS NULL", "a={0} and b={1} and c not in {2}".FormatMySql(1, null, null)); + } - [Fact] - public void FormatSqlServer() { + [Fact] + public void FormatSqlServer() + { - Assert.Empty(((string)null).FormatSqlServer("11")); - Assert.Equal("a=1", "a={0}".FormatSqlServer(1)); - Assert.Equal("a =1", "a ={0}".FormatSqlServer(1)); - Assert.Equal("a = 1", "a = {0}".FormatSqlServer(1)); - Assert.Equal("a='a'", "a={0}".FormatSqlServer('a')); - Assert.Equal("a ='a'", "a ={0}".FormatSqlServer('a')); - Assert.Equal("a = 'a'", "a = {0}".FormatSqlServer('a')); + Assert.Empty(((string)null).FormatSqlServer("11")); + Assert.Equal("a=1", "a={0}".FormatSqlServer(1)); + Assert.Equal("a =1", "a ={0}".FormatSqlServer(1)); + Assert.Equal("a = 1", "a = {0}".FormatSqlServer(1)); + Assert.Equal("a='a'", "a={0}".FormatSqlServer('a')); + Assert.Equal("a ='a'", "a ={0}".FormatSqlServer('a')); + Assert.Equal("a = 'a'", "a = {0}".FormatSqlServer('a')); - Assert.Equal("a=1 and b IS NULL", "a={0} and b={1}".FormatSqlServer(1, null)); - Assert.Equal("a =1 and b IS NULL", "a ={0} and b ={1}".FormatSqlServer(1, null)); - Assert.Equal("a = 1 and b IS NULL", "a = {0} and b = {1}".FormatSqlServer(1, null)); + Assert.Equal("a=1 and b IS NULL", "a={0} and b={1}".FormatSqlServer(1, null)); + Assert.Equal("a =1 and b IS NULL", "a ={0} and b ={1}".FormatSqlServer(1, null)); + Assert.Equal("a = 1 and b IS NULL", "a = {0} and b = {1}".FormatSqlServer(1, null)); - Assert.Equal("a=1 and b IS NULL and c in (1,2,3,4)", "a={0} and b={1} and c in {2}".FormatSqlServer(1, null, new[] { 1, 2, 3, 4 })); - Assert.Equal("a=1 and b IS NULL and c IS NULL", "a={0} and b={1} and c in {2}".FormatSqlServer(1, null, null)); - Assert.Equal("a=1 and b IS NULL and c not IS NULL", "a={0} and b={1} and c not in {2}".FormatSqlServer(1, null, null)); - } + Assert.Equal("a=1 and b IS NULL and c in (1,2,3,4)", "a={0} and b={1} and c in {2}".FormatSqlServer(1, null, new[] { 1, 2, 3, 4 })); + Assert.Equal("a=1 and b IS NULL and c IS NULL", "a={0} and b={1} and c in {2}".FormatSqlServer(1, null, null)); + Assert.Equal("a=1 and b IS NULL and c not IS NULL", "a={0} and b={1} and c not in {2}".FormatSqlServer(1, null, null)); + } - [Fact] - public void FormatPostgreSQL() { + [Fact] + public void FormatPostgreSQL() + { - Assert.Empty(((string)null).FormatPostgreSQL("11")); - Assert.Equal("a=1", "a={0}".FormatPostgreSQL(1)); - Assert.Equal("a =1", "a ={0}".FormatPostgreSQL(1)); - Assert.Equal("a = 1", "a = {0}".FormatPostgreSQL(1)); - Assert.Equal("a='a'", "a={0}".FormatPostgreSQL('a')); - Assert.Equal("a ='a'", "a ={0}".FormatPostgreSQL('a')); - Assert.Equal("a = 'a'", "a = {0}".FormatPostgreSQL('a')); + Assert.Empty(((string)null).FormatPostgreSQL("11")); + Assert.Equal("a=1", "a={0}".FormatPostgreSQL(1)); + Assert.Equal("a =1", "a ={0}".FormatPostgreSQL(1)); + Assert.Equal("a = 1", "a = {0}".FormatPostgreSQL(1)); + Assert.Equal("a='a'", "a={0}".FormatPostgreSQL('a')); + Assert.Equal("a ='a'", "a ={0}".FormatPostgreSQL('a')); + Assert.Equal("a = 'a'", "a = {0}".FormatPostgreSQL('a')); - Assert.Equal("a=1 and b IS NULL", "a={0} and b={1}".FormatPostgreSQL(1, null)); - Assert.Equal("a =1 and b IS NULL", "a ={0} and b ={1}".FormatPostgreSQL(1, null)); - Assert.Equal("a = 1 and b IS NULL", "a = {0} and b = {1}".FormatPostgreSQL(1, null)); + Assert.Equal("a=1 and b IS NULL", "a={0} and b={1}".FormatPostgreSQL(1, null)); + Assert.Equal("a =1 and b IS NULL", "a ={0} and b ={1}".FormatPostgreSQL(1, null)); + Assert.Equal("a = 1 and b IS NULL", "a = {0} and b = {1}".FormatPostgreSQL(1, null)); - Assert.Equal("a=1 and b IS NULL and c in (1,2,3,4)", "a={0} and b={1} and c in {2}".FormatPostgreSQL(1, null, new[] { 1, 2, 3, 4 })); - Assert.Equal("a=1 and b IS NULL and c IS NULL", "a={0} and b={1} and c in {2}".FormatSqlServer(1, null, null)); - Assert.Equal("a=1 and b IS NULL and c not IS NULL", "a={0} and b={1} and c not in {2}".FormatSqlServer(1, null, null)); - } - } + Assert.Equal("a=1 and b IS NULL and c in (1,2,3,4)", "a={0} and b={1} and c in {2}".FormatPostgreSQL(1, null, new[] { 1, 2, 3, 4 })); + Assert.Equal("a=1 and b IS NULL and c IS NULL", "a={0} and b={1} and c in {2}".FormatSqlServer(1, null, null)); + Assert.Equal("a=1 and b IS NULL and c not IS NULL", "a={0} and b={1} and c not in {2}".FormatSqlServer(1, null, null)); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs b/FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs index 40efaa79..555d7c83 100644 --- a/FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs +++ b/FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs @@ -3,185 +3,200 @@ using System; using System.Linq; using Xunit; -namespace FreeSql.Tests.LinqToSql { +namespace FreeSql.Tests.LinqToSql +{ - class TestLinqToSql { - public Guid id { get; set; } + class TestLinqToSql + { + public Guid id { get; set; } - public string name { get; set; } + public string name { get; set; } - public int click { get; set; } = 10; + public int click { get; set; } = 10; - public DateTime createtime { get; set; } = DateTime.Now; - } - class TestLinqToSqlComment { - public Guid id { get; set; } + public DateTime createtime { get; set; } = DateTime.Now; + } + class TestLinqToSqlComment + { + public Guid id { get; set; } - public Guid TestLinqToSqlId { get; set; } - public TestLinqToSql TEstLinqToSql { get; set; } + public Guid TestLinqToSqlId { get; set; } + public TestLinqToSql TEstLinqToSql { get; set; } - public string text { get; set; } - - public DateTime createtime { get; set; } = DateTime.Now; - } + public string text { get; set; } - public class SqliteLinqToSqlTests { + public DateTime createtime { get; set; } = DateTime.Now; + } - [Fact] - public void Where() { - var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + public class SqliteLinqToSqlTests + { - var t1 = (from a in g.sqlite.Select() - where a.id == item.id - select a).ToList(); - Assert.True(t1.Any()); - Assert.Equal(item.id, t1[0].id); - } + [Fact] + public void Where() + { + var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); - [Fact] - public void Select() { - var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var t1 = (from a in g.sqlite.Select() + where a.id == item.id + select a).ToList(); + Assert.True(t1.Any()); + Assert.Equal(item.id, t1[0].id); + } - var t1 = (from a in g.sqlite.Select() - where a.id == item.id - select new { a.id }).ToList(); - Assert.True(t1.Any()); - Assert.Equal(item.id, t1[0].id); - } + [Fact] + public void Select() + { + var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); - [Fact] - public void GroupBy() { - var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var t1 = (from a in g.sqlite.Select() + where a.id == item.id + select new { a.id }).ToList(); + Assert.True(t1.Any()); + Assert.Equal(item.id, t1[0].id); + } - var t1 = (from a in g.sqlite.Select() - where a.id == item.id - group a by new {a.id, a.name } into g - select new { - g.Key.id, g.Key.name, - cou = g.Count(), - avg = g.Avg(g.Value.click), - sum = g.Sum(g.Value.click), - max = g.Max(g.Value.click), - min = g.Min(g.Value.click) - }).ToList(); - Assert.True(t1.Any()); - Assert.Equal(item.id, t1.First().id); - } + [Fact] + public void GroupBy() + { + var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); - [Fact] - public void CaseWhen() { - var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var t1 = (from a in g.sqlite.Select() + where a.id == item.id + group a by new { a.id, a.name } into g + select new + { + g.Key.id, + g.Key.name, + cou = g.Count(), + avg = g.Avg(g.Value.click), + sum = g.Sum(g.Value.click), + max = g.Max(g.Value.click), + min = g.Min(g.Value.click) + }).ToList(); + Assert.True(t1.Any()); + Assert.Equal(item.id, t1.First().id); + } - var t1 = (from a in g.sqlite.Select() - where a.id == item.id - select new { - a.id, - a.name, - testsub = new { - time = a.click > 10 ? "" : "Сڻ" - } - }).ToList(); - Assert.True(t1.Any()); - Assert.Equal(item.id, t1[0].id); - Assert.Equal("Сڻ", t1[0].testsub.time); - } + [Fact] + public void CaseWhen() + { + var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); - [Fact] - public void Join() { - var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(item).ExecuteAffrows(); - var comment = new TestLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); + var t1 = (from a in g.sqlite.Select() + where a.id == item.id + select new + { + a.id, + a.name, + testsub = new + { + time = a.click > 10 ? "" : "Сڻ" + } + }).ToList(); + Assert.True(t1.Any()); + Assert.Equal(item.id, t1[0].id); + Assert.Equal("Сڻ", t1[0].testsub.time); + } - var t1 = (from a in g.sqlite.Select() - join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId - select a).ToList(); - Assert.True(t1.Any()); - //Assert.Equal(item.id, t1[0].id); + [Fact] + public void Join() + { + var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var comment = new TestLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); - var t2 = (from a in g.sqlite.Select() - join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId - select new { a.id, bid = b.id }).ToList(); - Assert.True(t2.Any()); - //Assert.Equal(item.id, t2[0].id); - //Assert.Equal(comment.id, t2[0].bid); + var t1 = (from a in g.sqlite.Select() + join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId + select a).ToList(); + Assert.True(t1.Any()); + //Assert.Equal(item.id, t1[0].id); - var t3 = (from a in g.sqlite.Select() - join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId - where a.id == item.id - select new { a.id, bid = b.id }).ToList(); - Assert.True(t3.Any()); - Assert.Equal(item.id, t3[0].id); - Assert.Equal(comment.id, t3[0].bid); - } + var t2 = (from a in g.sqlite.Select() + join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId + select new { a.id, bid = b.id }).ToList(); + Assert.True(t2.Any()); + //Assert.Equal(item.id, t2[0].id); + //Assert.Equal(comment.id, t2[0].bid); - [Fact] - public void LeftJoin() { - var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(item).ExecuteAffrows(); - var comment = new TestLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); + var t3 = (from a in g.sqlite.Select() + join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId + where a.id == item.id + select new { a.id, bid = b.id }).ToList(); + Assert.True(t3.Any()); + Assert.Equal(item.id, t3[0].id); + Assert.Equal(comment.id, t3[0].bid); + } - var t1 = (from a in g.sqlite.Select() - join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId into temp - from tc in temp.DefaultIfEmpty() - select a).ToList(); - Assert.True(t1.Any()); - //Assert.Equal(item.id, t1[0].id); + [Fact] + public void LeftJoin() + { + var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var comment = new TestLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); - var t2 = (from a in g.sqlite.Select() - join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId into temp - from tc in temp.DefaultIfEmpty() - select new { a.id, bid = tc.id }).ToList(); - Assert.True(t2.Any()); - //Assert.Equal(item.id, t2[0].id); - //Assert.Equal(comment.id, t2[0].bid); + var t1 = (from a in g.sqlite.Select() + join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId into temp + from tc in temp.DefaultIfEmpty() + select a).ToList(); + Assert.True(t1.Any()); + //Assert.Equal(item.id, t1[0].id); - var t3 = (from a in g.sqlite.Select() - join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId into temp - from tc in temp.DefaultIfEmpty() - where a.id == item.id - select new { a.id, bid = tc.id }).ToList(); - Assert.True(t3.Any()); - Assert.Equal(item.id, t3[0].id); - Assert.Equal(comment.id, t3[0].bid); - } + var t2 = (from a in g.sqlite.Select() + join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId into temp + from tc in temp.DefaultIfEmpty() + select new { a.id, bid = tc.id }).ToList(); + Assert.True(t2.Any()); + //Assert.Equal(item.id, t2[0].id); + //Assert.Equal(comment.id, t2[0].bid); - [Fact] - public void From() { - var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(item).ExecuteAffrows(); - var comment = new TestLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; - g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); + var t3 = (from a in g.sqlite.Select() + join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId into temp + from tc in temp.DefaultIfEmpty() + where a.id == item.id + select new { a.id, bid = tc.id }).ToList(); + Assert.True(t3.Any()); + Assert.Equal(item.id, t3[0].id); + Assert.Equal(comment.id, t3[0].bid); + } - var t1 = (from a in g.sqlite.Select() - from b in g.sqlite.Select() - where a.id == b.TestLinqToSqlId - select a).ToList(); - Assert.True(t1.Any()); - //Assert.Equal(item.id, t1[0].id); + [Fact] + public void From() + { + var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var comment = new TestLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); - var t2 = (from a in g.sqlite.Select() - from b in g.sqlite.Select() - where a.id == b.TestLinqToSqlId - select new { a.id, bid = b.id }).ToList(); - Assert.True(t2.Any()); - //Assert.Equal(item.id, t2[0].id); - //Assert.Equal(comment.id, t2[0].bid); + var t1 = (from a in g.sqlite.Select() + from b in g.sqlite.Select() + where a.id == b.TestLinqToSqlId + select a).ToList(); + Assert.True(t1.Any()); + //Assert.Equal(item.id, t1[0].id); - var t3 = (from a in g.sqlite.Select() - from b in g.sqlite.Select() - where a.id == b.TestLinqToSqlId - where a.id == item.id - select new { a.id, bid = b.id }).ToList(); - Assert.True(t3.Any()); - Assert.Equal(item.id, t3[0].id); - Assert.Equal(comment.id, t3[0].bid); - } - } + var t2 = (from a in g.sqlite.Select() + from b in g.sqlite.Select() + where a.id == b.TestLinqToSqlId + select new { a.id, bid = b.id }).ToList(); + Assert.True(t2.Any()); + //Assert.Equal(item.id, t2[0].id); + //Assert.Equal(comment.id, t2[0].bid); + + var t3 = (from a in g.sqlite.Select() + from b in g.sqlite.Select() + where a.id == b.TestLinqToSqlId + where a.id == item.id + select new { a.id, bid = b.id }).ToList(); + Assert.True(t3.Any()); + Assert.Equal(item.id, t3[0].id); + Assert.Equal(comment.id, t3[0].bid); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs index d9c34893..329cb3aa 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs @@ -4,85 +4,94 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySql { - public class MySqlDeleteTest { +namespace FreeSql.Tests.MySql +{ + public class MySqlDeleteTest + { - IDelete delete => g.mysql.Delete(); //�������� + IDelete delete => g.mysql.Delete(); //�������� - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void Dywhere() { - Assert.Null(g.mysql.Delete().ToSql()); - var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); - sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); - sql = g.mysql.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - } + sql = g.mysql.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + } - [Fact] - public void Where() { - var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - var id = g.mysql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); - Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); - } - [Fact] - public void ExecuteDeleted() { + var id = g.mysql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { - //delete.Where(a => a.Id > 0).ExecuteDeleted(); - } + //delete.Where(a => a.Id > 0).ExecuteDeleted(); + } - [Fact] - public void AsTable() { - Assert.Null(g.mysql.Delete().ToSql()); - var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + [Fact] + public void AsTable() + { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); - sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); - sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); - sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); - } - } + sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs index cbfa3930..76fe633a 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs @@ -4,133 +4,144 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySql { - public class MySqlInsertTest { +namespace FreeSql.Tests.MySql +{ + public class MySqlInsertTest + { - IInsert insert => g.mysql.Insert(); //�������� + IInsert insert => g.mysql.Insert(); //�������� - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestEnumInsertTb { - [Column(IsIdentity = true)] - public int id { get; set; } - public TestEnumInserTbType type { get; set; } - public DateTime time { get; set; } = new DateTime(); - } - enum TestEnumInserTbType { str1, biggit, sum211 } - - [Fact] - public void AppendData() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumInsertTb + { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumInserTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumInserTbType { str1, biggit, sum211 } - var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0)", sql); + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0), (?Clicks_1, ?Title_1, ?CreateTime_1), (?Clicks_2, ?Title_2, ?CreateTime_2), (?Clicks_3, ?Title_3, ?CreateTime_3), (?Clicks_4, ?Title_4, ?CreateTime_4), (?Clicks_5, ?Title_5, ?CreateTime_5), (?Clicks_6, ?Title_6, ?CreateTime_6), (?Clicks_7, ?Title_7, ?CreateTime_7), (?Clicks_8, ?Title_8, ?CreateTime_8), (?Clicks_9, ?Title_9, ?CreateTime_9)", sql); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0), (?Clicks_1, ?Title_1, ?CreateTime_1), (?Clicks_2, ?Title_2, ?CreateTime_2), (?Clicks_3, ?Title_3, ?CreateTime_3), (?Clicks_4, ?Title_4, ?CreateTime_4), (?Clicks_5, ?Title_5, ?CreateTime_5), (?Clicks_6, ?Title_6, ?CreateTime_6), (?Clicks_7, ?Title_7, ?CreateTime_7), (?Clicks_8, ?Title_8, ?CreateTime_8), (?Clicks_9, ?Title_9, ?CreateTime_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); - sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Now }).ToSql(); - Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES(?type_0, ?time_0)", sql); + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); - sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ToSql(); - Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); - } + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Now }).ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES(?type_0, ?time_0)", sql); - [Fact] - public void InsertColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + } - var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); - } - [Fact] - public void IgnoreColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); - var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); - } - [Fact] - public void ExecuteAffrows() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); - Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); - Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); - } - [Fact] - public void ExecuteIdentity() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); - Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - var id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); - Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select< TestEnumInsertTb>().Where(a => a.id == id).First()?.type); - id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); - Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); - } - [Fact] - public void ExecuteInserted() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); - //insert.AppendData(items.First()).ExecuteInserted(); - } + var id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - [Fact] - public void AsTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + //insert.AppendData(items.First()).ExecuteInserted(); + } - var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0)", sql); + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0), (?Clicks_1, ?Title_1, ?CreateTime_1), (?Clicks_2, ?Title_2, ?CreateTime_2), (?Clicks_3, ?Title_3, ?CreateTime_3), (?Clicks_4, ?Title_4, ?CreateTime_4), (?Clicks_5, ?Title_5, ?CreateTime_5), (?Clicks_6, ?Title_6, ?CreateTime_6), (?Clicks_7, ?Title_7, ?CreateTime_7), (?Clicks_8, ?Title_8, ?CreateTime_8), (?Clicks_9, ?Title_9, ?CreateTime_9)", sql); + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0), (?Clicks_1, ?Title_1, ?CreateTime_1), (?Clicks_2, ?Title_2, ?CreateTime_2), (?Clicks_3, ?Title_3, ?CreateTime_3), (?Clicks_4, ?Title_4, ?CreateTime_4), (?Clicks_5, ?Title_5, ?CreateTime_5), (?Clicks_6, ?Title_6, ?CreateTime_6), (?Clicks_7, ?Title_7, ?CreateTime_7), (?Clicks_8, ?Title_8, ?CreateTime_8), (?Clicks_9, ?Title_9, ?CreateTime_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); - } - } + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 382dca0c..05d89b37 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -5,1218 +5,1297 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySql { - - public class MySqlSelectTest { - - ISelect select => g.mysql.Select(); - - [Table(Name = "tb_topic")] - public class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - [Column(OldName = "TypeGuid")] - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - - public virtual TopicFields Fields { get; set; } - } - public class TopicFields { - [Column(IsPrimary = true)] - public int TopicId { get; set; } - public virtual Topic Topic { get; set; } - } - public class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - - public int ParentId { get; set; } - public virtual TestTypeParentInfo Parent { get; set; } - - public string Name { get; set; } - - public virtual ICollection Topics { get; set; } - } - public class TestTypeParentInfo { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - - public partial class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } - - public virtual ICollection Tags { get; set; } - } - public partial class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } - - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } - } - public partial class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public decimal? Ddd { get; set; } - public string Name { get; set; } - - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } - } - - - [Fact] - public void AsSelect() { - //OneToOne、ManyToOne - var t0 = g.mysql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 - //FROM `Tag` a - //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` - //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` - //WHERE (a__Parent__Parent.`Name` = '粤语') - - //OneToMany - var t1 = g.mysql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` - //FROM `Tag` a - //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) - - //ManyToMany - var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); - //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` - //FROM `Song` a - //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) - } - - [Fact] - public void Lazy() { - var tags = g.mysql.Select().Where(a => a.Parent.Name == "xxx") - .LeftJoin(a => a.Parent_id == a.Parent.Id) - .ToSql(); - - var songs = g.mysql.Select().Limit(10).ToList(); - } - - [Fact] - public void ToDataTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - - Assert.Equal(1, g.mysql.Insert().AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, g.mysql.Insert().AppendData(items).ExecuteAffrows()); - - //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //Assert.Equal(9989, g.mysql.Insert(items).ExecuteAffrows()); - - var dt1 = select.Limit(10).ToDataTable(); - var dt2 = select.Limit(10).ToDataTable("id, 111222"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); - } - - class TestDto { - public int id { get; set; } - public string name { get; set; } //这是join表的属性 - public int ParentId { get; set; } //这是join表的属性 - } - [Fact] - public void ToList() { - - var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto2 = select.Limit(10).ToList(a => new TestDto()); - var testDto3 = select.Limit(10).ToList(a => new TestDto { }); - var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); - var testDto5 = select.Limit(10).ToList(); - - var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); - var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); - var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); - var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); - - var t0 = select.Limit(50).ToList(); - - - var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - - - var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); - var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); - var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); - - //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( - // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, - // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") - //); - - //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) - //.Where(a => a.Id == 1).ToSql(); - - var sql4 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name == "xxx")).ToSql(); - //.Where(a => a.Id == 1).ToSql(); - - - var list111 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name != "xxx")); - var list111sql = list111.ToSql(); - var list111data = list111.ToList((a, b, c) => new { - a.Id, - title_substring = a.Title.Substring(0, 1), - a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new { - a.Id, - tp2 = a.Type.Name - }, - tp3 = new { - a.Id, - tp33 = new { - a.Id - } - } - }); - - var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); - var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); - var t11112 = g.mysql.Select().ToList(a => new { - a.Id, - a.Title, - a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new { - a.Id, - tp2 = a.Type.Name - }, - tp3 = new { - a.Id, - tp33 = new { - a.Id - } - } - - }); - - var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - - - var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); - - var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); - - g.mysql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); - var testGuidId5 = g.mysql.Select().ToList(); - var testGuidId6 = g.mysql.Select().ToList(a => a.id); - - var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); - var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); - } - class TestGuidIdToList { - public Guid id { get; set; } - public string title { get; set; } = Guid.NewGuid().ToString(); - } - [Fact] - public void ToOne() { - var testnotfind = select.Where("1=2").First(a => a.CreateTime); - Assert.Equal(default(DateTime), testnotfind); - } - [Fact] - public void ToSql() { - g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); - - var sql1 = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); - var sql2 = g.mysql.Select().Where(a => testenumWhereType.Blaaa == a.type).ToSql(); - - var sql3 = g.mysql.Select().Where(a => a.type.Equals(testenumWhereType.Blaaa)).ToSql(); - var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); - } - class testenumWhere { - public Guid id { get; set; } - public testenumWhereType type { get; set; } - } - public enum testenumWhereType { Menu, Class, Blaaa } - - [Fact] - public void Any() { - var count = select.Where(a => 1 == 1).Count(); - Assert.False(select.Where(a => 1 == 2).Any()); - Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); - - var sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && - select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - //.Offset(a.Id) - .Any() - ).Any(c => c.Id == a.Id + 10) - ); - var sql2222Tolist = sql2222.ToList(); - - var collectionSelect = select.Where(a => - a.Type.Guid == a.TypeGuid && - a.Type.Parent.Id == a.Type.ParentId && - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) - ); - collectionSelect.ToList(); - } - [Fact] - public void Count() { - var count = select.Where(a => 1 == 1).Count(); - select.Where(a => 1 == 1).Count(out var count2); - Assert.Equal(count, count2); - Assert.Equal(0, select.Where(a => 1 == 2).Count()); - } - [Fact] - public void Master() { - Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); - } - [Fact] - public void From() { - var query2 = select.From((s, b) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - ); - var sql2 = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid`", sql2); - query2.ToList(); - - var query3 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id) - ); - var sql3 = query3.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql3); - query3.ToList(); - } - [Fact] - public void LeftJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); - query.ToList(); - } - [Fact] - public void InnerJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //������� - query = select - .InnerJoin(a => a.Type.Guid == a.TypeGuid) - .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - query = select - .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .InnerJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .InnerJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); - query.ToList(); - - } - [Fact] - public void RightJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); - query.ToList(); - - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - query.ToList(); - - //������� - query = select - .RightJoin(a => a.Type.Guid == a.TypeGuid) - .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - query = select - .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .RightJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .RightJoin(a => a.TypeGuid == b.Guid) - .RightJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); - query.ToList(); - - } - [Fact] - public void Where() { - - var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); - var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); - var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); - - var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.Where(a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); - query.ToList(); - - query = select.Where(a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); - query.ToList(); - - //���û�е������ԣ��򵥶������ - query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TypeGuid` AND b.`Name` = 'typeTitle')", sql); - query.ToList(); - - query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TypeGuid`)", sql); - query.ToList(); - - query = select.Where((a, b, c) => c.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .Where(a => a.Id == 10 && c.Name == "xxx") - .Where(a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.Where("a.clicks > 100 and a.id = ?id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql); - query.ToList(); - } - [Fact] - public void WhereIf() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.WhereIf(true, a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(true, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(true, "a.clicks > 100 and a.id = ?id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql); - query.ToList(); - - // ==========================================WhereIf(false) - - //����е�������a.Type��a.Type.Parent ���ǵ������� - query = select.WhereIf(false, a => a.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - query2 = select.From((s, b, c) => s - .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(false, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(false, "a.clicks > 100 and a.id = ?id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); - } - [Fact] - public void WhereExists() { - var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); - - sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - - //.Offset(a.Id) - - .Any() - ).Any() - ).ToList(); - } - [Fact] - public void GroupBy() { - var groupby = select.From((s, b, c) => s - .Where(a => a.Id == 1) - ) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()) - .Offset(10) - .Limit(2) - .ToList(a => new { - a.Key.tt2, - cou1 = a.Count(), - arg1 = a.Avg(a.Key.mod4), - ccc2 = a.Key.tt2 ?? "now()", - //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") - ccc3 = a.Max(a.Value.Item3.Id) - }); - - var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); - - var aggsql1 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist1 = select - .GroupBy(a => a.Title) - .ToList(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToSql(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToList(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql3 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid), - sum3 = b.Sum(b.Value.Type.Parent.Id) - }); - } - [Fact] - public void ToAggregate() { - var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - } - - [Fact] - public void OrderBy() { - var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); - } - [Fact] - public void Skip_Offset() { - var sql = select.Offset(10).Limit(10).ToList(); - } - [Fact] - public void Take_Limit() { - var sql = select.Limit(10).ToList(); - } - [Fact] - public void Page() { - var sql1 = select.Page(1, 10).ToList(); - var sql2 = select.Page(2, 10).ToList(); - var sql3 = select.Page(3, 10).ToList(); - - var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); - var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); - var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); - } - [Fact] - public void Distinct() { - var t1 = select.Distinct().ToList(a => a.Title); - var t2 = select.Distinct().Limit(10).ToList(a => a.Title); - } - - [Fact] - public void Sum() { - } - [Fact] - public void Min() { - } - [Fact] - public void Max() { - } - [Fact] - public void Avg() { - } - [Fact] - public void As() { - } - - [Fact] - public void AsTable() { - - var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); - - Func tableRule = (type, oldname) => { - if (type == typeof(Topic)) return oldname + "AsTable1"; - else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; - return oldname + "AsTable"; - }; - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid`", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); - - query = select - .LeftJoin((a, b) => b.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` c ON c.`Id` = a__Type.`ParentId`", sql); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfoAsTable` c ON b.`ParentId` = c.`Id`", sql); - - //������϶����㲻�� - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); - } - - public class TestInclude_OneToManyModel1 { - [Column(IsIdentity = true)] - public int id { get; set; } - public virtual TestInclude_OneToManyModel2 model2 { get; set; } - - public string m1name { get; set; } - } - public class TestInclude_OneToManyModel2 { - [Column(IsPrimary = true)] - public int model2id { get; set; } - public virtual TestInclude_OneToManyModel1 model1 { get; set; } - - public string m2setting { get; set; } - - public List childs { get; set; } - } - public class TestInclude_OneToManyModel3 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model2111Idaaa { get; set; } - public string title { get; set; } - - public List childs2 { get; set; } - } - public class TestInclude_OneToManyModel4 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model3333Id333 { get; set; } - public string title444 { get; set; } - } - - [Fact] - public void Include_OneToMany() { - var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; - model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); - var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; - g.mysql.Insert(model2).ExecuteAffrows(); - - var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; - model3_1.id = (int)g.mysql.Insert(model3_1).ExecuteIdentity(); - var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; - model3_2.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); - var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; - model3_3.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); - - var model4s = new[] { - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } - }; - Assert.Equal(5, g.mysql.Insert(model4s).ExecuteAffrows()); - - var t0 = g.mysql.Select() - .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t1 = g.mysql.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t2 = g.mysql.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - - var t00 = g.mysql.Select() - .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t11 = g.mysql.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t22 = g.mysql.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - } - - public class TestInclude_OneToManyModel11 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2id { get; set; } - public string m3setting { get; set; } - public TestInclude_OneToManyModel22 model2 { get; set; } - public string m1name { get; set; } - } - - public class TestInclude_OneToManyModel22 { - [Column(IsIdentity = true)] - public int id { get; set; } - public string m2setting { get; set; } - public List childs { get; set; } - } - public class TestInclude_OneToManyModel33 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2Id { get; set; } - public string title { get; set; } - public string setting { get; set; } - } - [Fact] - public void Include_OneToMany2() { - string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; - model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); - - var model3s = new[] - { - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} - }; - Assert.Equal(3, g.mysql.Insert(model3s).ExecuteAffrows()); - - var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; - model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); - - var t1 = g.mysql.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - - var t11 = g.mysql.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - } - - [Fact] - public void Include_OneToChilds() { - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_中国" - }; - tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); - var tag1_1 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_北京" - }; - tag1_1.Id = (int)g.mysql.Insert(tag1_1).ExecuteIdentity(); - var tag1_2 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_上海" - }; - tag1_2.Id = (int)g.mysql.Insert(tag1_2).ExecuteIdentity(); - - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_美国" - }; - tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); - var tag2_1 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_纽约" - }; - tag2_1.Id = (int)g.mysql.Insert(tag2_1).ExecuteIdentity(); - var tag2_2 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_华盛顿" - }; - tag2_2.Id = (int)g.mysql.Insert(tag2_2).ExecuteIdentity(); - - var tags0 = g.mysql.Select() - .Include(a => a.Parent) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags1 = g.mysql.Select() - .IncludeMany(a => a.Tags) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags2 = g.mysql.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags3 = g.mysql.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags11 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags22 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags33 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - } - - [Fact] - public void Include_ManyToMany() { - - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_01_中国" - }; - tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_02_美国" - }; - tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); - var tag3 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_03_日本" - }; - tag3.Id = (int)g.mysql.Insert(tag3).ExecuteIdentity(); - - var song1 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_01_我是中国人.mp3", - Url = "http://ww.baidu.com/" - }; - song1.Id = (int)g.mysql.Insert(song1).ExecuteIdentity(); - var song2 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_02_爱你一万年.mp3", - Url = "http://ww.163.com/" - }; - song2.Id = (int)g.mysql.Insert(song2).ExecuteIdentity(); - var song3 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_03_千年等一回.mp3", - Url = "http://ww.sina.com/" - }; - song3.Id = (int)g.mysql.Insert(song3).ExecuteIdentity(); - - g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); - - var songs1 = g.mysql.Select() - .IncludeMany(a => a.Tags) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs1.Count); - Assert.Equal(2, songs1[0].Tags.Count); - Assert.Equal(1, songs1[1].Tags.Count); - Assert.Equal(3, songs1[2].Tags.Count); - - var songs2 = g.mysql.Select() - .IncludeMany(a => a.Tags, - then => then.IncludeMany(t => t.Songs)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs2.Count); - Assert.Equal(2, songs2[0].Tags.Count); - Assert.Equal(1, songs2[1].Tags.Count); - Assert.Equal(3, songs2[2].Tags.Count); - - var tags3 = g.mysql.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - - - var songs11 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs11.Count); - Assert.Equal(1, songs11[0].Tags.Count); - Assert.Equal(1, songs11[1].Tags.Count); - Assert.Equal(1, songs11[2].Tags.Count); - - var songs22 = g.mysql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.IncludeMany(t => t.Songs.Take(1))) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs22.Count); - Assert.Equal(1, songs22[0].Tags.Count); - Assert.Equal(1, songs22[1].Tags.Count); - Assert.Equal(1, songs22[2].Tags.Count); - - var tags33 = g.mysql.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs.Take(1)) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - } - } +namespace FreeSql.Tests.MySql +{ + + public class MySqlSelectTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + public class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + [Column(OldName = "TypeGuid")] + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + + public virtual TopicFields Fields { get; set; } + } + public class TopicFields + { + [Column(IsPrimary = true)] + public int TopicId { get; set; } + public virtual Topic Topic { get; set; } + } + public class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + + public int ParentId { get; set; } + public virtual TestTypeParentInfo Parent { get; set; } + + public string Name { get; set; } + + public virtual ICollection Topics { get; set; } + } + public class TestTypeParentInfo + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.mysql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.mysql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.mysql.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.mysql.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, g.mysql.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, g.mysql.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.mysql.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + var testDto5 = select.Limit(10).ToList(); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + var t0 = select.Limit(50).ToList(); + + + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new + { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.mysql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.mysql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.mysql.Select().ToList(); + var testGuidId6 = g.mysql.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); + + var sql1 = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); + var sql2 = g.mysql.Select().Where(a => testenumWhereType.Blaaa == a.type).ToSql(); + + var sql3 = g.mysql.Select().Where(a => a.type.Equals(testenumWhereType.Blaaa)).ToSql(); + var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); + } + class testenumWhere + { + public Guid id { get; set; } + public testenumWhereType type { get; set; } + } + public enum testenumWhereType { Menu, Class, Blaaa } + + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid`", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TypeGuid` AND b.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.clicks > 100 and a.id = ?id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.clicks > 100 and a.id = ?id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.clicks > 100 and a.id = ?id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + } + [Fact] + public void Min() + { + } + [Fact] + public void Max() + { + } + [Fact] + public void Avg() + { + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` c ON c.`Id` = a__Type.`ParentId`", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfoAsTable` c ON b.`ParentId` = c.`Id`", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.mysql.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.mysql.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.mysql.Insert(model4s).ExecuteAffrows()); + + var t0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.mysql.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + + var t1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.mysql.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.mysql.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.mysql.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.mysql.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.mysql.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.mysql.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.mysql.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.mysql.Insert(song3).ExecuteIdentity(); + + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 95f65f3f..55808901 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -3,185 +3,200 @@ using System; using System.Collections.Generic; using Xunit; -namespace FreeSql.Tests.MySql { - public class MySqlUpdateTest { - IUpdate update => g.mysql.Update(); +namespace FreeSql.Tests.MySql +{ + public class MySqlUpdateTest + { + IUpdate update => g.mysql.Update(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestEnumUpdateTb { - [Column(IsIdentity = true)] - public int id { get; set; } - public TestEnumUpdateTbType type { get; set; } - public DateTime time { get; set; } = new DateTime(); - } - enum TestEnumUpdateTbType { str1, biggit, sum211 } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumUpdateTb + { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumUpdateTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumUpdateTbType { str1, biggit, sum211 } - [Fact] - public void Dywhere() { - Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); - } + [Fact] + public void Dywhere() + { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } - [Fact] - public void SetSource() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ?p_0, `Title` = ?p_1, `CreateTime` = ?p_2 WHERE (`Id` = 1)", sql); + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ?p_0, `Title` = ?p_1, `CreateTime` = ?p_2 WHERE (`Id` = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.SetSource(items).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN ?p_0 WHEN 2 THEN ?p_1 WHEN 3 THEN ?p_2 WHEN 4 THEN ?p_3 WHEN 5 THEN ?p_4 WHEN 6 THEN ?p_5 WHEN 7 THEN ?p_6 WHEN 8 THEN ?p_7 WHEN 9 THEN ?p_8 WHEN 10 THEN ?p_9 END, `Title` = CASE `Id` WHEN 1 THEN ?p_10 WHEN 2 THEN ?p_11 WHEN 3 THEN ?p_12 WHEN 4 THEN ?p_13 WHEN 5 THEN ?p_14 WHEN 6 THEN ?p_15 WHEN 7 THEN ?p_16 WHEN 8 THEN ?p_17 WHEN 9 THEN ?p_18 WHEN 10 THEN ?p_19 END, `CreateTime` = CASE `Id` WHEN 1 THEN ?p_20 WHEN 2 THEN ?p_21 WHEN 3 THEN ?p_22 WHEN 4 THEN ?p_23 WHEN 5 THEN ?p_24 WHEN 6 THEN ?p_25 WHEN 7 THEN ?p_26 WHEN 8 THEN ?p_27 WHEN 9 THEN ?p_28 WHEN 10 THEN ?p_29 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN ?p_0 WHEN 2 THEN ?p_1 WHEN 3 THEN ?p_2 WHEN 4 THEN ?p_3 WHEN 5 THEN ?p_4 WHEN 6 THEN ?p_5 WHEN 7 THEN ?p_6 WHEN 8 THEN ?p_7 WHEN 9 THEN ?p_8 WHEN 10 THEN ?p_9 END, `Title` = CASE `Id` WHEN 1 THEN ?p_10 WHEN 2 THEN ?p_11 WHEN 3 THEN ?p_12 WHEN 4 THEN ?p_13 WHEN 5 THEN ?p_14 WHEN 6 THEN ?p_15 WHEN 7 THEN ?p_16 WHEN 8 THEN ?p_17 WHEN 9 THEN ?p_18 WHEN 10 THEN ?p_19 END, `CreateTime` = CASE `Id` WHEN 1 THEN ?p_20 WHEN 2 THEN ?p_21 WHEN 3 THEN ?p_22 WHEN 4 THEN ?p_23 WHEN 5 THEN ?p_24 WHEN 6 THEN ?p_25 WHEN 7 THEN ?p_26 WHEN 8 THEN ?p_27 WHEN 9 THEN ?p_28 WHEN 10 THEN ?p_29 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = CASE `Id` WHEN 1 THEN ?p_0 WHEN 2 THEN ?p_1 WHEN 3 THEN ?p_2 WHEN 4 THEN ?p_3 WHEN 5 THEN ?p_4 WHEN 6 THEN ?p_5 WHEN 7 THEN ?p_6 WHEN 8 THEN ?p_7 WHEN 9 THEN ?p_8 WHEN 10 THEN ?p_9 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = CASE `Id` WHEN 1 THEN ?p_0 WHEN 2 THEN ?p_1 WHEN 3 THEN ?p_2 WHEN 4 THEN ?p_3 WHEN 5 THEN ?p_4 WHEN 6 THEN ?p_5 WHEN 7 THEN ?p_6 WHEN 8 THEN ?p_7 WHEN 9 THEN ?p_8 WHEN 10 THEN ?p_9 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `CreateTime` = ?p_0 WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `CreateTime` = ?p_0 WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); - Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES(?type_0, ?time_0)", sql); - var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); - Assert.True(id > 0); - Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + sql = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES(?type_0, ?time_0)", sql); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); - sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = ?p_0, `time` = ?p_1 WHERE (`id` = 0)", sql); - g.mysql.Update().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); - Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = ?p_0, `time` = ?p_1 WHERE (`id` = 0)", sql); + g.mysql.Update().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); - sql = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); - Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); - id = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); - Assert.True(id > 0); - Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + sql = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + id = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); - sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); - g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); - Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); - } - [Fact] - public void IgnoreColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0 WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); + g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0 WHERE (`Id` = 1)", sql); - sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = ?p_0 WHERE (`id` = 0)", sql); + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = ?p_0 WHERE (`id` = 0)", sql); - sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); - } - [Fact] - public void UpdateColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0 WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0 WHERE (`Id` = 1)", sql); - sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = ?p_0 WHERE (`id` = 0)", sql); + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = ?p_0 WHERE (`id` = 0)", sql); - sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); - } - [Fact] - public void Set() { - var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0 WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0 WHERE (`Id` = 1)", sql); - sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0, `CreateTime` = ?p_1 WHERE (`Id` = 1)", sql); + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0, `CreateTime` = ?p_1 WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); - int incrv = 10; - sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 / 1 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 / 1 WHERE (`Id` = 1)", sql); - sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); - var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); - Assert.True(id > 0); - sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); - Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = ?p_0 WHERE (`id` = {id})", sql); - g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ExecuteAffrows(); - Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = ?p_0 WHERE (`id` = {id})", sql); + g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); - sql = g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ToSql().Replace("\r\n", ""); - Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'str1' WHERE (`id` = {id})", sql); - g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); - Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); - } - [Fact] - public void SetRaw() { - var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET clicks = clicks + ?incrClick WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'str1' WHERE (`id` = {id})", sql); + g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET clicks = clicks + ?incrClick WHERE (`Id` = 1)", sql); - sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0).SetRaw("`type` = {0}".FormatMySql(TestEnumUpdateTbType.sum211)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); - } - [Fact] - public void Where() { - var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0).SetRaw("`type` = {0}".FormatMySql(TestEnumUpdateTbType.sum211)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); - sql = update.Where("id = ?id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (id = ?id)", sql); + sql = update.Where("id = ?id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (id = ?id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) - .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); - } - [Fact] - public void WhereExists() { + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) + .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - } - [Fact] - public void ExecuteUpdated() { + } + [Fact] + public void ExecuteUpdated() + { - } + } - [Fact] - public void AsTable() { - Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - } - } + [Fact] + public void AsTable() + { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs index bcff25e2..b4f476c2 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs @@ -2,1561 +2,1595 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.MySqlMapType { - public class BoolNullableTest { - class BoolNullableMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool))] - public bool? tobool { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool? tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool? tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool? toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool? toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool? toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool? tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool? tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool? tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool? tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool? tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool? toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool? toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool? touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool? touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool? toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool? toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool? tostring { get; set; } = true; - } - [Fact] - public void Bool() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item = new BoolNullableMap { tobool = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item = new BoolNullableMap { tobool = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update all - item.tobool = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item.tobool = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item.tobool = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item = new BoolNullableMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item = new BoolNullableMap { tosbyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item.tosbyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item.tosbytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item = new BoolNullableMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item = new BoolNullableMap { toshort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item.toshort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item.toshortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item = new BoolNullableMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item = new BoolNullableMap { toint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item.toint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item = new BoolNullableMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item = new BoolNullableMap { tointnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item.tointnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item = new BoolNullableMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item = new BoolNullableMap { tolong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item.tolong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item.tolongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item = new BoolNullableMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item = new BoolNullableMap { tobyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item.tobyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item.tobytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item = new BoolNullableMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item = new BoolNullableMap { toushort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item.toushort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item.toushortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item = new BoolNullableMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item = new BoolNullableMap { touint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item.touint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item = new BoolNullableMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item = new BoolNullableMap { touintnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item.touintnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item = new BoolNullableMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item = new BoolNullableMap { toulong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item.toulong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item.toulongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.mysql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item = new BoolNullableMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item = new BoolNullableMap { tostring = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item.tostring = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.MySqlMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolTest.cs index 44cdd2cb..b65dd1be 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/BoolTest.cs @@ -2,1095 +2,1129 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.MySqlMapType { - public class BoolTest { - - class BoolMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool?))] - public bool toboolnullable { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool tostring { get; set; } = true; - } - - [Fact] - public void BoolNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item = new BoolMap { toboolnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update all - item.toboolnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item.toboolnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toboolnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toboolnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item = new BoolMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item = new BoolMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item = new BoolMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item = new BoolMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item = new BoolMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item = new BoolMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item = new BoolMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item = new BoolMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item = new BoolMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item = new BoolMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item = new BoolMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item = new BoolMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item = new BoolMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item = new BoolMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item = new BoolMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item = new BoolMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.mysql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item = new BoolMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.MySqlMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/EnumTest.cs index 58ac7908..cf34a3e4 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/EnumTest.cs @@ -3,252 +3,259 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.MySqlMapType { - public class EnumTest { - class EnumTestMap { - public Guid id { get; set; } +namespace FreeSql.Tests.MySqlMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(int))] - public ToStringMapEnum enum_to_int { get; set; } - [Column(MapType = typeof(int?))] - public ToStringMapEnum? enumnullable_to_int { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void EnumToString() { - //insert - var orm = g.mysql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToString() { - //insert - var orm = g.mysql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void EnumToInt() { - //insert - var orm = g.mysql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + [Fact] + public void EnumToInt() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //update all - item.enum_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - item.enum_to_int = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToInt() { - //insert - var orm = g.mysql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); - //update all - item.enumnullable_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); - item.enumnullable_to_int = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/ToStringTest.cs index b18962e7..fb4db4ca 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/ToStringTest.cs @@ -3,555 +3,568 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.MySqlMapType { - public class ToStringTest { - class ToStringMap { - public Guid id { get; set; } +namespace FreeSql.Tests.MySqlMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan timespan_to_string { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan? timespannullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime datetime_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime? datetimenullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid guid_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid? guidnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger biginteger_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger? bigintegernullable_to_string { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void Enum1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigInteger1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(0, find.biginteger_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); - item = new ToStringMap { biginteger_to_string = 100 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(100, find.biginteger_to_string); + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); - //update all - item.biginteger_to_string = 200; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(200, find.biginteger_to_string); + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); - item.biginteger_to_string = 205; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(205, find.biginteger_to_string); + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(522, find.biginteger_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(10005, find.biginteger_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigIntegerNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - item = new ToStringMap { bigintegernullable_to_string = 101 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(101, find.bigintegernullable_to_string); + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); - //update all - item.bigintegernullable_to_string = 2004; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(2004, find.bigintegernullable_to_string); + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); - item.bigintegernullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(998, find.bigintegernullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.bigintegernullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpan1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); - item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); - //update all - item.timespan_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpanNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); - //update all - item.timespannullable_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); - item.timespannullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.timespannullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTime1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.MinValue, find.datetime_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); - item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); - //update all - item.datetime_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTimeNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); - //update all - item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); - item.datetimenullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.datetimenullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void Guid1() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(Guid.Empty, find.guid_to_string); + [Fact] + public void Guid1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guid_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update all - newid = Guid.NewGuid(); - item.guid_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guid_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void GuidNullable() { - //insert - var orm = g.mysql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guidnullable_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - //update all - newid = Guid.NewGuid(); - item.guidnullable_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - item.guidnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guidnullable_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.guidnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs index b6053ea3..ab37eda6 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs @@ -2,53 +2,64 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.MySql { - public class MySqlAdoTest { - [Fact] - public void Pool() { - var t1 = g.mysql.Ado.MasterPool.StatisticsFullily; - } +namespace FreeSql.Tests.MySql +{ + public class MySqlAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.mysql.Ado.MasterPool.StatisticsFullily; + } - [Fact] - public void SlavePools() { - var t2 = g.mysql.Ado.SlavePools.Count; - } + [Fact] + public void SlavePools() + { + var t2 = g.mysql.Ado.SlavePools.Count; + } - [Fact] - public void ExecuteReader() { - - } - [Fact] - public void ExecuteArray() { - - } - [Fact] - public void ExecuteNonQuery() { - - } - [Fact] - public void ExecuteScalar() { - - } + [Fact] + public void ExecuteReader() + { - [Fact] - public void Query() { - var t3 = g.mysql.Ado.Query("select * from song"); + } + [Fact] + public void ExecuteArray() + { - var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + } + [Fact] + public void ExecuteNonQuery() + { - var t5 = g.mysql.Ado.Query("select * from song"); - } + } + [Fact] + public void ExecuteScalar() + { - [Fact] - public void QueryMultipline() { - var t3 = g.mysql.Ado.Query("select * from song; select * from song; select * from song"); - } + } - class xxx { - public int Id { get; set; } - public string Path { get; set; } - public string Title2 { get; set; } - } - } + [Fact] + public void Query() + { + var t3 = g.mysql.Ado.Query("select * from song"); + + var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + + var t5 = g.mysql.Ado.Query("select * from song"); + } + + [Fact] + public void QueryMultipline() + { + var t3 = g.mysql.Ado.Query("select * from song; select * from song; select * from song"); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 11b7c086..123f782e 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -6,80 +6,91 @@ using System.Linq; using System.Text; using Xunit; -namespace FreeSql.Tests.MySql { - public class MySqlCodeFirstTest { +namespace FreeSql.Tests.MySql +{ + public class MySqlCodeFirstTest + { - [Fact] - public void ı_ֶ() { - var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<ı2>(); - g.mysql.CodeFirst.SyncStructure<ı2>(); + [Fact] + public void ı_ֶ() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<ı2>(); + g.mysql.CodeFirst.SyncStructure<ı2>(); - var item = new ı2 { - = "Ա", - ʱ = DateTime.Now - }; - Assert.Equal(1, g.mysql.Insert<ı2>().AppendData(item).ExecuteAffrows()); - Assert.NotEqual(Guid.Empty, item.); - var item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); - Assert.NotNull(item2); - Assert.Equal(item., item2.); - Assert.Equal(item., item2.); - } - class ı2 { - [Column(IsPrimary = true)] - public Guid { get; set; } + var item = new ı2 + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.mysql.Insert<ı2>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı2 + { + [Column(IsPrimary = true)] + public Guid { get; set; } - public string { get; set; } + public string { get; set; } - public DateTime ʱ { get; set; } - } + public DateTime ʱ { get; set; } + } - [Fact] - public void AddUniques() { - var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - g.mysql.CodeFirst.SyncStructure(); - } - [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - class AddUniquesInfo { - public Guid id { get; set; } - [Column(Unique = "uk_phone")] - public string phone { get; set; } + [Fact] + public void AddUniques() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] - public string group { get; set; } - [Column(Unique = "uk_group_index")] - public int index { get; set; } - [Column(Unique = "uk_group_index22")] - public string index22 { get; set; } - } + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } - [Fact] - public void AddField() { - var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + [Fact] + public void AddField() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - var id = g.mysql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); - } + var id = g.mysql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } - [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] - public class TopicAddField { - [Column(IsIdentity = true)] - public int? Id { get; set; } + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int? Id { get; set; } - public string name { get; set; } + public string name { get; set; } - [Column(DbType = "varchar(200) not null", OldName = "title")] - public string title222 { get; set; } = "10"; + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title222 { get; set; } = "10"; - [Column(IsIgnore = true)] - public DateTime ct { get; set; } = DateTime.Now; - } + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } - [Fact] - public void GetComparisonDDLStatements() { + [Fact] + public void GetComparisonDDLStatements() + { - var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( `Id` INT(11) NOT NULL AUTO_INCREMENT, `testFieldBool` BIT(1) NOT NULL, `testFieldSByte` TINYINT(3) NOT NULL, @@ -126,352 +137,363 @@ namespace FreeSql.Tests.MySql { PRIMARY KEY (`Id`) ) Engine=InnoDB; ", sql); - } - - sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - } - - IInsert insert => g.mysql.Insert(); - ISelect select => g.mysql.Select(); - - [Fact] - public void CurdAllField() { - var item = new TableAllType { }; - item.Id = (int)insert.AppendData(item).ExecuteIdentity(); - - var newitem = select.Where(a => a.Id == item.Id).ToOne(); - - var item2 = new TableAllType { - testFieldBool = true, - testFieldBoolNullable = true, - testFieldByte = 255, - testFieldByteNullable = 127, - testFieldBytes = Encoding.UTF8.GetBytes("й"), - testFieldDateTime = DateTime.Now, - testFieldDateTimeNullable = DateTime.Now.AddHours(-1), - testFieldDecimal = 99.99M, - testFieldDecimalNullable = 99.98M, - testFieldDouble = 999.99, - testFieldDoubleNullable = 999.98, - testFieldEnum1 = TableAllTypeEnumType1.e5, - testFieldEnum1Nullable = TableAllTypeEnumType1.e3, - testFieldEnum2 = TableAllTypeEnumType2.f2, - testFieldEnum2Nullable = TableAllTypeEnumType2.f3, - testFieldFloat = 19.99F, - testFieldFloatNullable = 19.98F, - testFieldGuid = Guid.NewGuid(), - testFieldGuidNullable = Guid.NewGuid(), - testFieldInt = int.MaxValue, - testFieldIntNullable = int.MinValue, - testFieldLineString = new MygisLineString(new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }), - testFieldLong = long.MaxValue, - testFieldMultiLineString = new MygisMultiLineString(new[] { - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }, - new[] { new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 100) } }), - testFieldMultiPoint = new MygisMultiPoint(new[] { new MygisCoordinate2D(11, 11), new MygisCoordinate2D(51, 11) }), - testFieldMultiPolygon = new MygisMultiPolygon(new[] { - new MygisPolygon(new[] { - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), - new MygisPolygon(new[] { - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }) }), - testFieldPoint = new MygisPoint(99, 99), - testFieldPolygon = new MygisPolygon(new[] { - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, - new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), - testFieldSByte = 100, - testFieldSByteNullable = 99, - testFieldShort = short.MaxValue, - testFieldShortNullable = short.MinValue, - testFieldString = "йstring", - testFieldTimeSpan = TimeSpan.FromSeconds(999), - testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), - testFieldUInt = uint.MaxValue, - testFieldUIntNullable = uint.MinValue, - testFieldULong = ulong.MaxValue, - testFieldULongNullable = ulong.MinValue, - testFieldUShort = ushort.MaxValue, - testFieldUShortNullable = ushort.MinValue, - testFielLongNullable = long.MinValue - }; - item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); - var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + } + + sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.mysql.Insert(); + ISelect select => g.mysql.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = 255, + testFieldByteNullable = 127, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(-1), + testFieldDecimal = 99.99M, + testFieldDecimalNullable = 99.98M, + testFieldDouble = 999.99, + testFieldDoubleNullable = 999.98, + testFieldEnum1 = TableAllTypeEnumType1.e5, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 19.99F, + testFieldFloatNullable = 19.98F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldLineString = new MygisLineString(new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }), + testFieldLong = long.MaxValue, + testFieldMultiLineString = new MygisMultiLineString(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }, + new[] { new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 100) } }), + testFieldMultiPoint = new MygisMultiPoint(new[] { new MygisCoordinate2D(11, 11), new MygisCoordinate2D(51, 11) }), + testFieldMultiPolygon = new MygisMultiPolygon(new[] { + new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), + new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }) }), + testFieldPoint = new MygisPoint(99, 99), + testFieldPolygon = new MygisPolygon(new[] { + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) }, + new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }), + testFieldSByte = 100, + testFieldSByteNullable = 99, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "йstring", + testFieldTimeSpan = TimeSpan.FromSeconds(999), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); - var items = select.ToList(); - } + var items = select.ToList(); + } - [JsonObject(MemberSerialization.OptIn), Table(Name = "tb_alltype")] - public partial class Tb_alltype { + [JsonObject(MemberSerialization.OptIn), Table(Name = "tb_alltype")] + public partial class Tb_alltype + { - [JsonProperty, Column(Name = "Id", DbType = "int(11)", IsPrimary = true, IsIdentity = true)] - public int Id { get; set; } + [JsonProperty, Column(Name = "Id", DbType = "int(11)", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } - [JsonProperty, Column(Name = "testFieldBool", DbType = "bit(1)")] - public bool TestFieldBool { get; set; } + [JsonProperty, Column(Name = "testFieldBool", DbType = "bit(1)")] + public bool TestFieldBool { get; set; } - [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit(1)", IsNullable = true)] - public bool? TestFieldBoolNullable { get; set; } + [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit(1)", IsNullable = true)] + public bool? TestFieldBoolNullable { get; set; } - [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint(3) unsigned")] - public byte TestFieldByte { get; set; } + [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint(3) unsigned")] + public byte TestFieldByte { get; set; } - [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint(3) unsigned", IsNullable = true)] - public byte? TestFieldByteNullable { get; set; } + [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint(3) unsigned", IsNullable = true)] + public byte? TestFieldByteNullable { get; set; } - [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] - public byte[] TestFieldBytes { get; set; } + [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] + public byte[] TestFieldBytes { get; set; } - [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] - public DateTime TestFieldDateTime { get; set; } + [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] + public DateTime TestFieldDateTime { get; set; } - [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] - public DateTime? TestFieldDateTimeNullable { get; set; } + [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] + public DateTime? TestFieldDateTimeNullable { get; set; } - [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] - public decimal TestFieldDecimal { get; set; } + [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] + public decimal TestFieldDecimal { get; set; } - [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] - public decimal? TestFieldDecimalNullable { get; set; } + [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] + public decimal? TestFieldDecimalNullable { get; set; } - [JsonProperty, Column(Name = "testFieldDouble", DbType = "double")] - public double TestFieldDouble { get; set; } + [JsonProperty, Column(Name = "testFieldDouble", DbType = "double")] + public double TestFieldDouble { get; set; } - [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "double", IsNullable = true)] - public double? TestFieldDoubleNullable { get; set; } + [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "double", IsNullable = true)] + public double? TestFieldDoubleNullable { get; set; } - [JsonProperty, Column(Name = "testFieldEnum1", DbType = "enum('E1','E2','E3','E5')")] - public Tb_alltypeTESTFIELDENUM1 TestFieldEnum1 { get; set; } + [JsonProperty, Column(Name = "testFieldEnum1", DbType = "enum('E1','E2','E3','E5')")] + public Tb_alltypeTESTFIELDENUM1 TestFieldEnum1 { get; set; } - [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "enum('E1','E2','E3','E5')", IsNullable = true)] - public Tb_alltypeTESTFIELDENUM1NULLABLE? TestFieldEnum1Nullable { get; set; } + [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "enum('E1','E2','E3','E5')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM1NULLABLE? TestFieldEnum1Nullable { get; set; } - [JsonProperty, Column(Name = "testFieldEnum2", DbType = "set('F1','F2','F3')")] - public Tb_alltypeTESTFIELDENUM2 TestFieldEnum2 { get; set; } + [JsonProperty, Column(Name = "testFieldEnum2", DbType = "set('F1','F2','F3')")] + public Tb_alltypeTESTFIELDENUM2 TestFieldEnum2 { get; set; } - [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "set('F1','F2','F3')", IsNullable = true)] - public Tb_alltypeTESTFIELDENUM2NULLABLE? TestFieldEnum2Nullable { get; set; } + [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "set('F1','F2','F3')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM2NULLABLE? TestFieldEnum2Nullable { get; set; } - [JsonProperty, Column(Name = "testFieldFloat", DbType = "float")] - public float TestFieldFloat { get; set; } + [JsonProperty, Column(Name = "testFieldFloat", DbType = "float")] + public float TestFieldFloat { get; set; } - [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "float", IsNullable = true)] - public float? TestFieldFloatNullable { get; set; } + [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "float", IsNullable = true)] + public float? TestFieldFloatNullable { get; set; } - [JsonProperty, Column(Name = "testFieldGuid", DbType = "char(36)")] - public Guid TestFieldGuid { get; set; } + [JsonProperty, Column(Name = "testFieldGuid", DbType = "char(36)")] + public Guid TestFieldGuid { get; set; } - [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "char(36)", IsNullable = true)] - public Guid? TestFieldGuidNullable { get; set; } + [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "char(36)", IsNullable = true)] + public Guid? TestFieldGuidNullable { get; set; } - [JsonProperty, Column(Name = "testFieldInt", DbType = "int(11)")] - public int TestFieldInt { get; set; } + [JsonProperty, Column(Name = "testFieldInt", DbType = "int(11)")] + public int TestFieldInt { get; set; } - [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int(11)", IsNullable = true)] - public int? TestFieldIntNullable { get; set; } + [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int(11)", IsNullable = true)] + public int? TestFieldIntNullable { get; set; } - [JsonProperty, Column(Name = "testFieldLineString", DbType = "linestring", IsNullable = true)] - public MygisGeometry TestFieldLineString { get; set; } + [JsonProperty, Column(Name = "testFieldLineString", DbType = "linestring", IsNullable = true)] + public MygisGeometry TestFieldLineString { get; set; } - [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint(20)")] - public long TestFieldLong { get; set; } + [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint(20)")] + public long TestFieldLong { get; set; } - [JsonProperty, Column(Name = "testFieldMultiLineString", DbType = "multilinestring", IsNullable = true)] - public MygisGeometry TestFieldMultiLineString { get; set; } + [JsonProperty, Column(Name = "testFieldMultiLineString", DbType = "multilinestring", IsNullable = true)] + public MygisGeometry TestFieldMultiLineString { get; set; } - [JsonProperty, Column(Name = "testFieldMultiPoint", DbType = "multipoint", IsNullable = true)] - public MygisGeometry TestFieldMultiPoint { get; set; } + [JsonProperty, Column(Name = "testFieldMultiPoint", DbType = "multipoint", IsNullable = true)] + public MygisGeometry TestFieldMultiPoint { get; set; } - [JsonProperty, Column(Name = "testFieldMultiPolygon", DbType = "multipolygon", IsNullable = true)] - public MygisGeometry TestFieldMultiPolygon { get; set; } + [JsonProperty, Column(Name = "testFieldMultiPolygon", DbType = "multipolygon", IsNullable = true)] + public MygisGeometry TestFieldMultiPolygon { get; set; } - [JsonProperty, Column(Name = "testFieldPoint", DbType = "point", IsNullable = true)] - public MygisGeometry TestFieldPoint { get; set; } + [JsonProperty, Column(Name = "testFieldPoint", DbType = "point", IsNullable = true)] + public MygisGeometry TestFieldPoint { get; set; } - [JsonProperty, Column(Name = "testFieldPolygon", DbType = "polygon", IsNullable = true)] - public MygisGeometry TestFieldPolygon { get; set; } + [JsonProperty, Column(Name = "testFieldPolygon", DbType = "polygon", IsNullable = true)] + public MygisGeometry TestFieldPolygon { get; set; } - [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint(3)")] - public sbyte TestFieldSByte { get; set; } + [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint(3)")] + public sbyte TestFieldSByte { get; set; } - [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint(3)", IsNullable = true)] - public sbyte? TestFieldSByteNullable { get; set; } + [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint(3)", IsNullable = true)] + public sbyte? TestFieldSByteNullable { get; set; } - [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint(6)")] - public short TestFieldShort { get; set; } + [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint(6)")] + public short TestFieldShort { get; set; } - [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint(6)", IsNullable = true)] - public short? TestFieldShortNullable { get; set; } + [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint(6)", IsNullable = true)] + public short? TestFieldShortNullable { get; set; } - [JsonProperty, Column(Name = "testFieldString", DbType = "varchar(255)", IsNullable = true)] - public string TestFieldString { get; set; } + [JsonProperty, Column(Name = "testFieldString", DbType = "varchar(255)", IsNullable = true)] + public string TestFieldString { get; set; } - [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] - public TimeSpan TestFieldTimeSpan { get; set; } + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] + public TimeSpan TestFieldTimeSpan { get; set; } - [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] - public TimeSpan? TestFieldTimeSpanNullable { get; set; } + [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] + public TimeSpan? TestFieldTimeSpanNullable { get; set; } - [JsonProperty, Column(Name = "testFieldUInt", DbType = "int(10) unsigned")] - public uint TestFieldUInt { get; set; } + [JsonProperty, Column(Name = "testFieldUInt", DbType = "int(10) unsigned")] + public uint TestFieldUInt { get; set; } - [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int(10) unsigned", IsNullable = true)] - public uint? TestFieldUIntNullable { get; set; } + [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int(10) unsigned", IsNullable = true)] + public uint? TestFieldUIntNullable { get; set; } - [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint(20) unsigned")] - public ulong TestFieldULong { get; set; } + [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint(20) unsigned")] + public ulong TestFieldULong { get; set; } - [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint(20) unsigned", IsNullable = true)] - public ulong? TestFieldULongNullable { get; set; } + [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint(20) unsigned", IsNullable = true)] + public ulong? TestFieldULongNullable { get; set; } - [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint(5) unsigned")] - public ushort TestFieldUShort { get; set; } + [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint(5) unsigned")] + public ushort TestFieldUShort { get; set; } - [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint(5) unsigned", IsNullable = true)] - public ushort? TestFieldUShortNullable { get; set; } + [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint(5) unsigned", IsNullable = true)] + public ushort? TestFieldUShortNullable { get; set; } - [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint(20)", IsNullable = true)] - public long? TestFielLongNullable { get; set; } + [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint(20)", IsNullable = true)] + public long? TestFielLongNullable { get; set; } - internal static IFreeSql mysql => null; - public static FreeSql.ISelect Select => mysql.Select(); + internal static IFreeSql mysql => null; + public static FreeSql.ISelect Select => mysql.Select(); - public static long Delete(int Id) { - var affrows = mysql.Delete().Where(a => a.Id == Id).ExecuteAffrows(); - return affrows; - } + public static long Delete(int Id) + { + var affrows = mysql.Delete().Where(a => a.Id == Id).ExecuteAffrows(); + return affrows; + } - /// - /// ӣֵ UpdateӰΪ 0 Insert - /// - public void Save() { - if (this.Id != default(int)) { - var affrows = mysql.Update().Where(a => a.Id == Id).ExecuteAffrows(); - if (affrows > 0) return; - } - this.Id = (int)mysql.Insert().AppendData(this).ExecuteIdentity(); - } + /// + /// ӣֵ UpdateӰΪ 0 Insert + /// + public void Save() + { + if (this.Id != default(int)) + { + var affrows = mysql.Update().Where(a => a.Id == Id).ExecuteAffrows(); + if (affrows > 0) return; + } + this.Id = (int)mysql.Insert().AppendData(this).ExecuteIdentity(); + } - } + } - public enum Tb_alltypeTESTFIELDENUM1 { - E1 = 1, E2, E3, E5 - } - public enum Tb_alltypeTESTFIELDENUM1NULLABLE { - E1 = 1, E2, E3, E5 - } - [Flags] - public enum Tb_alltypeTESTFIELDENUM2 : long { - F1 = 1, F2 = 2, F3 = 4 - } - [Flags] - public enum Tb_alltypeTESTFIELDENUM2NULLABLE : long { - F1 = 1, F2 = 2, F3 = 4 - } + public enum Tb_alltypeTESTFIELDENUM1 + { + E1 = 1, E2, E3, E5 + } + public enum Tb_alltypeTESTFIELDENUM1NULLABLE + { + E1 = 1, E2, E3, E5 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2 : long + { + F1 = 1, F2 = 2, F3 = 4 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2NULLABLE : long + { + F1 = 1, F2 = 2, F3 = 4 + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - - public bool testFieldBool { get; set; } - public sbyte testFieldSByte { get; set; } - public short testFieldShort { get; set; } - public int testFieldInt { get; set; } - public long testFieldLong { get; set; } - public byte testFieldByte { get; set; } - public ushort testFieldUShort { get; set; } - public uint testFieldUInt { get; set; } - public ulong testFieldULong { get; set; } - public double testFieldDouble { get; set; } - public float testFieldFloat { get; set; } - public decimal testFieldDecimal { get; set; } - public TimeSpan testFieldTimeSpan { get; set; } - public DateTime testFieldDateTime { get; set; } - public byte[] testFieldBytes { get; set; } - public string testFieldString { get; set; } - public Guid testFieldGuid { get; set; } - - public bool? testFieldBoolNullable { get; set; } - public sbyte? testFieldSByteNullable { get; set; } - public short? testFieldShortNullable { get; set; } - public int? testFieldIntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? testFieldByteNullable { get; set; } - public ushort? testFieldUShortNullable { get; set; } - public uint? testFieldUIntNullable { get; set; } - public ulong? testFieldULongNullable { get; set; } - public double? testFieldDoubleNullable { get; set; } - public float? testFieldFloatNullable { get; set; } - public decimal? testFieldDecimalNullable { get; set; } - public TimeSpan? testFieldTimeSpanNullable { get; set; } - public DateTime? testFieldDateTimeNullable { get; set; } - public Guid? testFieldGuidNullable { get; set; } - - public MygisPoint testFieldPoint { get; set; } - public MygisLineString testFieldLineString { get; set; } - public MygisPolygon testFieldPolygon { get; set; } - public MygisMultiPoint testFieldMultiPoint { get; set; } - public MygisMultiLineString testFieldMultiLineString { get; set; } - public MygisMultiPolygon testFieldMultiPolygon { get; set; } - - public TableAllTypeEnumType1 testFieldEnum1 { get; set; } - public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } - public TableAllTypeEnumType2 testFieldEnum2 { get; set; } - public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - } - - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public MygisPoint testFieldPoint { get; set; } + public MygisLineString testFieldLineString { get; set; } + public MygisPolygon testFieldPolygon { get; set; } + public MygisMultiPoint testFieldMultiPoint { get; set; } + public MygisMultiLineString testFieldMultiLineString { get; set; } + public MygisMultiPolygon testFieldMultiPolygon { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs index cff6585d..fc0859ae 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs @@ -2,20 +2,24 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.MySql { - public class MySqlDbFirstTest { - [Fact] - public void GetDatabases() { +namespace FreeSql.Tests.MySql +{ + public class MySqlDbFirstTest + { + [Fact] + public void GetDatabases() + { - var t1 = g.mysql.DbFirst.GetDatabases(); + var t1 = g.mysql.DbFirst.GetDatabases(); - } + } - [Fact] - public void GetTablesByDatabase() { + [Fact] + public void GetTablesByDatabase() + { - var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); + var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); - } - } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/ConvertTest.cs index 79462ef0..86df8ad1 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/ConvertTest.cs @@ -4,143 +4,166 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlExpression { - public class ConvertTest { +namespace FreeSql.Tests.MySqlExpression +{ + public class ConvertTest + { - ISelect select => g.mysql.Select(); + ISelect select => g.mysql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void ToBoolean() { - var data = new List(); - data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); - data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); - } - [Fact] - public void ToByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); - data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); - } - [Fact] - public void ToChar() { - var data = new List(); - data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); - data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); - } - [Fact] - public void ToDateTime() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); - } - [Fact] - public void ToDecimal() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToDouble() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt32() { - var data = new List(); - data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); - data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToSByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); - data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); - } - [Fact] - public void ToSingle() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); - data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); - } - [Fact] - public void ToUInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt32() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); - } + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } - [Fact] - public void Guid_Parse() { - var data = new List(); - data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); - } + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } - [Fact] - public void Guid_NewGuid() { - var data = new List(); - //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); - } + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } - [Fact] - public void Random() { - var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); - } - } + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs index 2b1e8d4c..c1aebfb4 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs @@ -4,652 +4,691 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlExpression { - public class DateTimeTest { - - ISelect select => g.mysql.Select(); - - [Table(Name = "tb_topic111333")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - [Table(Name = "TestTypeInfo333")] - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - public DateTime Time { get; set; } - } - [Table(Name = "TestTypeParentInfo23123")] - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - public DateTime Time2 { get; set; } - } - [Fact] - public void Now() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void UtcNow() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void Date() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) - } - [Fact] - public void TimeOfDay() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) - } - [Fact] - public void DayOfWeek() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) - } - [Fact] - public void Day() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) - } - [Fact] - public void DayOfYear() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) - } - [Fact] - public void Month() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (month(a.`CreateTime`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (month(a__Type.`Time`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (month(a__Type__Parent.`Time2`) > month(now())) - } - [Fact] - public void Year() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (year(a.`CreateTime`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (year(a__Type.`Time`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (year(a__Type__Parent.`Time2`) > year(now())) - } - [Fact] - public void Hour() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (hour(a.`CreateTime`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (hour(a__Type.`Time`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) - } - [Fact] - public void Minute() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (minute(a.`CreateTime`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (minute(a__Type.`Time`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) - } - [Fact] - public void Second() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (second(a.`CreateTime`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (second(a__Type.`Time`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (second(a__Type__Parent.`Time2`) > second(now())) - } - [Fact] - public void Millisecond() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) - } - [Fact] - public void AddDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) - } - [Fact] - public void AddHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) - } - [Fact] - public void AddMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) - } - [Fact] - public void AddMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) - } - [Fact] - public void AddMonths() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) - } - [Fact] - public void AddSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) - } - [Fact] - public void AddTicks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) - } - [Fact] - public void AddYears() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) - } - [Fact] - public void _ЧͬSubtract() { - var data = new List(); - data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - - [Fact] - public void DateTime_Compare() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((a.`CreateTime`) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) - } - [Fact] - public void DateTime_DaysInMonth() { - var data = new List(); - data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) - } - [Fact] - public void DateTime_Equals() { - var data = new List(); - data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void DateTime_IsLeapYear() { - var data = new List(); - data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) - } - [Fact] - public void DateTime_Parse() { - var data = new List(); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) - } - } +namespace FreeSql.Tests.MySqlExpression +{ + public class DateTimeTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/MathTest.cs index 321c9212..53490eaa 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/MathTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/MathTest.cs @@ -4,129 +4,153 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlExpression { - public class MathTest { +namespace FreeSql.Tests.MySqlExpression +{ + public class MathTest + { - ISelect select => g.mysql.Select(); + ISelect select => g.mysql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void PI() { - var data = new List(); - data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); - } - [Fact] - public void Abs() { - var data = new List(); - data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Sign() { - var data = new List(); - data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Floor() { - var data = new List(); - data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); - } - [Fact] - public void Ceiling() { - var data = new List(); - data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Round() { - var data = new List(); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); - } - [Fact] - public void Exp() { - var data = new List(); - data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log() { - var data = new List(); - data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log10() { - var data = new List(); - data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Pow() { - var data = new List(); - data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sqrt() { - var data = new List(); - data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Cos() { - var data = new List(); - data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sin() { - var data = new List(); - data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Tan() { - var data = new List(); - data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Acos() { - var data = new List(); - data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Asin() { - var data = new List(); - data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan() { - var data = new List(); - data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan2() { - var data = new List(); - data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Truncate() { - var data = new List(); - data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); - } - } + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs index f8907726..44345f68 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs @@ -5,117 +5,123 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlExpression { - public class OtherTest { +namespace FreeSql.Tests.MySqlExpression +{ + public class OtherTest + { - ISelect select => g.mysql.Select(); + ISelect select => g.mysql.Select(); - public OtherTest() { - - } + public OtherTest() + { - [Fact] - public void Boolean() { - var t1 = select.Where(a => a.testFieldBool == true).ToList(); - var t2 = select.Where(a => a.testFieldBool != true).ToList(); - var t3 = select.Where(a => a.testFieldBool == false).ToList(); - var t4 = select.Where(a => !a.testFieldBool).ToList(); - var t5 = select.Where(a => a.testFieldBool).ToList(); + } - var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); - var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); - var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); - var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); - var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); - } + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); - [Fact] - public void Array() { - int[] nullarr = null; - Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); - Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } - IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); - var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + [Fact] + public void Array() + { + int[] nullarr = null; + Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); - //in not in - var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); - var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); - var inarray = new[] { 1, 2, 3 }; - var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); - var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - //in not in - var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); - var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); - var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); - var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); - var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var inarray2 = new List() { 1, 2, 3 }; - var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); - var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); - } + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + } - public bool testFieldBool { get; set; } - public sbyte testFieldSByte { get; set; } - public short testFieldShort { get; set; } - public int testFieldInt { get; set; } - public long testFieldLong { get; set; } - public byte testFieldByte { get; set; } - public ushort testFieldUShort { get; set; } - public uint testFieldUInt { get; set; } - public ulong testFieldULong { get; set; } - public double testFieldDouble { get; set; } - public float testFieldFloat { get; set; } - public decimal testFieldDecimal { get; set; } - public TimeSpan testFieldTimeSpan { get; set; } - public DateTime testFieldDateTime { get; set; } - public byte[] testFieldBytes { get; set; } - public string testFieldString { get; set; } - public Guid testFieldGuid { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - public bool? testFieldBoolNullable { get; set; } - public sbyte? testFieldSByteNullable { get; set; } - public short? testFieldShortNullable { get; set; } - public int? testFieldIntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? testFieldByteNullable { get; set; } - public ushort? testFieldUShortNullable { get; set; } - public uint? testFieldUIntNullable { get; set; } - public ulong? testFieldULongNullable { get; set; } - public double? testFieldDoubleNullable { get; set; } - public float? testFieldFloatNullable { get; set; } - public decimal? testFieldDecimalNullable { get; set; } - public TimeSpan? testFieldTimeSpanNullable { get; set; } - public DateTime? testFieldDateTimeNullable { get; set; } - public Guid? testFieldGuidNullable { get; set; } + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } - public MygisPoint testFieldPoint { get; set; } - public MygisLineString testFieldLineString { get; set; } - public MygisPolygon testFieldPolygon { get; set; } - public MygisMultiPoint testFieldMultiPoint { get; set; } - public MygisMultiLineString testFieldMultiLineString { get; set; } - public MygisMultiPolygon testFieldMultiPolygon { get; set; } + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } - public TableAllTypeEnumType1 testFieldEnum1 { get; set; } - public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } - public TableAllTypeEnumType2 testFieldEnum2 { get; set; } - public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - } + public MygisPoint testFieldPoint { get; set; } + public MygisLineString testFieldLineString { get; set; } + public MygisPolygon testFieldPolygon { get; set; } + public MygisMultiPoint testFieldMultiPoint { get; set; } + public MygisMultiLineString testFieldMultiLineString { get; set; } + public MygisMultiPolygon testFieldMultiPolygon { get; set; } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index 1b70d10e..558605cc 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -4,693 +4,717 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlExpression { - public class StringTest { - - ISelect select => g.mysql.Select(); - - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - class TestEqualsGuid { - public Guid id { get; set; } - public bool IsDeleted { get; set; } - } - - [Fact] - public void Equals__() { - var list = new List(); - list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); - list.Add(g.mysql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); - list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); - } - - [Fact] - public void Empty() { - var data = new List(); - data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ifnull(a.`Title`, '') = '') - } - - [Fact] - public void StartsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) - list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) - } - [Fact] - public void EndsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) - } - [Fact] - public void Contains() { - var list = new List(); - list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) - } - [Fact] - public void ToLower() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void ToUpper() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void Substring() { - var data = new List(); - data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) - } - [Fact] - public void Length() { - var data = new List(); - data.Add(select.Where(a => a.Title.Length == 0).ToList()); - data.Add(select.Where(a => a.Title.Length == 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); - data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) - } - [Fact] - public void IndexOf() { - var data = new List(); - data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) - } - [Fact] - public void PadLeft() { - var data = new List(); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void PadRight() { - var data = new List(); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void Trim() { - var data = new List(); - data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void TrimStart() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) - } - [Fact] - public void TrimEnd() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void Replace() { - var data = new List(); - data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) - } - - [Fact] - public void string_IsNullOrEmpty() { - var data = new List(); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); - data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); - } - } +namespace FreeSql.Tests.MySqlExpression +{ + public class StringTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + public bool IsDeleted { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.mysql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/TimeSpanTest.cs index cc96d772..8e0a2d4f 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/TimeSpanTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/TimeSpanTest.cs @@ -4,257 +4,290 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.MySqlExpression { - public class TimeSpanTest { +namespace FreeSql.Tests.MySqlExpression +{ + public class TimeSpanTest + { - ISelect select => g.mysql.Select(); + ISelect select => g.mysql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } - [Fact] - public void Zero() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) - } - [Fact] - public void Days() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) - } - [Fact] - public void Hours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) - } - [Fact] - public void Milliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) - } - [Fact] - public void Minutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) - } - [Fact] - public void Seconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) - } - [Fact] - public void TotalDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) - } - [Fact] - public void TotalHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) - } - [Fact] - public void TotalMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) - } - [Fact] - public void TotalMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) - } - [Fact] - public void TotalSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') - } + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } - [Fact] - public void TimeSpan_Compare() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void TimeSpan_Equals() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromDays() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromHours() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) - } - [Fact] - public void TimeSpan_FromMilliseconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) - } - [Fact] - public void TimeSpan_FromMinutes() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) - } - [Fact] - public void TimeSpan_FromSeconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) - } - [Fact] - public void TimeSpan_FromTicks() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) - } - [Fact] - public void TimeSpan_Parse() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) - } - } + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs index ece0e712..881c176c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs @@ -4,86 +4,95 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.Oracle { - public class OracleDeleteTest { +namespace FreeSql.Tests.Oracle +{ + public class OracleDeleteTest + { - IDelete delete => g.oracle.Delete(); //�������� + IDelete delete => g.oracle.Delete(); //�������� - [Table(Name = "tb_topic22211")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void Dywhere() { - Assert.Null(g.oracle.Delete().ToSql()); - var sql = g.oracle.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(g.oracle.Delete().ToSql()); + var sql = g.oracle.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); - sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); - sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); - sql = g.oracle.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); - } + sql = g.oracle.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + } - [Fact] - public void Where() { - var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); - sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); + sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - var id = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); - Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); - } - [Fact] - public void ExecuteDeleted() { + var id = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { - //var item = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); - //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); - } + //var item = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } - [Fact] - public void AsTable() { - Assert.Null(g.oracle.Delete().ToSql()); - var sql = g.oracle.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + [Fact] + public void AsTable() + { + Assert.Null(g.oracle.Delete().ToSql()); + var sql = g.oracle.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); - sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1)", sql); + sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1)", sql); - sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); - sql = g.oracle.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1)", sql); - } - } + sql = g.oracle.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs index 331a9703..a87cedbf 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs @@ -4,33 +4,37 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.Oracle { - public class OracleInsertTest { +namespace FreeSql.Tests.Oracle +{ + public class OracleInsertTest + { - IInsert insert => g.oracle.Insert(); //�������� + IInsert insert => g.oracle.Insert(); //�������� - [Table(Name = "tb_topic_insert")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - - [Fact] - public void AppendData() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - var data = new List(); - var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks_0, :Title_0, :CreateTime_0)", sql); - data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - sql = insert.AppendData(items).ToSql(); - Assert.Equal(@"INSERT ALL + var data = new List(); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks_0, :Title_0, :CreateTime_0)", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal(@"INSERT ALL INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_0, :Title_0, :CreateTime_0) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_1, :Title_1, :CreateTime_1) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_2, :Title_2, :CreateTime_2) @@ -42,10 +46,10 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_7 INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_8, :Title_8, :CreateTime_8) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_9, :Title_9, :CreateTime_9) SELECT 1 FROM DUAL", sql); - data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); - sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_0) INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_1) INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_2) @@ -57,10 +61,10 @@ INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_7) INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_8) INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); - data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) @@ -72,17 +76,18 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); - data.Add(insert.AppendData(items.First()).ExecuteIdentity()); - } + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } - [Fact] - public void InsertColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - var data = new List(); - var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal(@"INSERT ALL + var data = new List(); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_0) INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_1) INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_2) @@ -94,10 +99,10 @@ INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_7) INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_8) INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); - data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); - sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal(@"INSERT ALL INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) @@ -109,16 +114,17 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); - data.Add(insert.AppendData(items.First()).ExecuteIdentity()); - } - [Fact] - public void IgnoreColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - var data = new List(); - var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal(@"INSERT ALL + var data = new List(); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) @@ -130,10 +136,10 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); - data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal(@"INSERT ALL INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_0) INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_1) INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_2) @@ -145,41 +151,45 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_7) INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_8) INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_9) SELECT 1 FROM DUAL", sql); - data.Add(insert.AppendData(items.First()).ExecuteIdentity()); - } - [Fact] - public void ExecuteAffrows() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); - } - [Fact] - public void ExecuteIdentity() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); - } - [Fact] - public void ExecuteInserted() { - //var items = new List(); - //for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + //var items = new List(); + //for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - //var items2 = insert.AppendData(items).ExecuteInserted(); - } + //var items2 = insert.AppendData(items).ExecuteInserted(); + } - [Fact] - public void AsTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks_0, :Title_0, :CreateTime_0)", sql); + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks_0, :Title_0, :CreateTime_0)", sql); - sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_0, :Title_0, :CreateTime_0) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_1, :Title_1, :CreateTime_1) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_2, :Title_2, :CreateTime_2) @@ -192,8 +202,8 @@ INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clic INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_9, :Title_9, :CreateTime_9) SELECT 1 FROM DUAL", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_0) INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_1) INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_2) @@ -206,8 +216,8 @@ INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_8) INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) @@ -220,8 +230,8 @@ INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_0) INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_1) INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_2) @@ -234,8 +244,8 @@ INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_8) INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); - sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) @@ -248,8 +258,8 @@ INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) @@ -262,8 +272,8 @@ INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal(@"INSERT ALL + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_0) INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_1) INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_2) @@ -275,6 +285,6 @@ INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_7) INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_8) INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_9) SELECT 1 FROM DUAL", sql); - } - } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 22397b90..cafc9e54 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -4,1112 +4,1182 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.Oracle { - public class OracleSelectTest { - - ISelect select => g.oracle.Select(); - - [Table(Name = "tb_topic22")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - - class TopicInserts { - public Guid Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - public partial class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } - - public virtual ICollection Tags { get; set; } - } - public partial class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } - - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } - } - public partial class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public decimal? Ddd { get; set; } - public string Name { get; set; } - - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } - } - - [Fact] - public void AsSelect() { - //OneToOne、ManyToOne - var t0 = g.oracle.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 - //FROM `Tag` a - //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` - //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` - //WHERE (a__Parent__Parent.`Name` = '粤语') - - //OneToMany - var t1 = g.oracle.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` - //FROM `Tag` a - //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) - - //ManyToMany - var t2 = g.oracle.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); - //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` - //FROM `Song` a - //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) - } - - [Fact] - public void Lazy() { - var tags = g.oracle.Select().Where(a => a.Parent.Name == "xxx") - .LeftJoin(a => a.Parent_id == a.Parent.Id) - .ToSql(); - - var songs = g.oracle.Select().Limit(10).ToList(); - } - - [Fact] - public void ToDataTable() { - var items = new List(); - for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - - //Assert.Equal(1, g.oracle.Insert().AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(11, g.oracle.Insert().AppendData(items).ExecuteAffrows()); - - //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //Assert.Equal(9989, g.oracle.Insert(items).ExecuteAffrows()); - - var dt1 = select.Limit(10).ToDataTable(); - var dt2 = select.Limit(10).ToDataTable("id, 111222"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); - } - class TestDto { - public int id { get; set; } - public string name { get; set; } //这是join表的属性 - public int ParentId { get; set; } //这是join表的属性 - } - [Fact] - public void ToList() { - - var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto2 = select.Limit(10).ToList(a => new TestDto()); - var testDto3 = select.Limit(10).ToList(a => new TestDto { }); - var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); - - var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); - var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); - var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); - - g.oracle.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); - var testGuidId5 = g.oracle.Select().ToList(); - var testGuidId6 = g.oracle.Select().ToList(a => a.id); - - var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); - var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); - } - class TestGuidIdToList { - public Guid id { get; set; } - public string title { get; set; } = Guid.NewGuid().ToString(); - } - [Fact] - public void ToOne() { - var testnotfind = select.Where("1=2").First(a => a.CreateTime); - Assert.Equal(default(DateTime), testnotfind); - } - [Fact] - public void ToSql() { - } - [Fact] - public void Any() { - var count = select.Where(a => 1 == 1).Count(); - Assert.False(select.Where(a => 1 == 2).Any()); - Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); - - var sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && - select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - //.Offset(a.Id) - .Any() - ).Any(c => c.Id == a.Id + 10) - ); - var sql2222Tolist = sql2222.ToList(); - - var collectionSelect = select.Where(a => - a.Type.Guid == a.TypeGuid && - a.Type.Parent.Id == a.Type.ParentId && - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) - ); - collectionSelect.ToList(); - } - [Fact] - public void Count() { - var count = select.Where(a => 1 == 1).Count(); - select.Where(a => 1 == 1).Count(out var count2); - Assert.Equal(count, count2); - Assert.Equal(0, select.Where(a => 1 == 2).Count()); - } - [Fact] - public void Master() { - Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); - } - [Fact] - public void From() { - var query2 = select.From((s, b) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - ); - var sql2 = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); - query2.ToList(); - - var query3 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id) - ); - var sql3 = query3.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); - query3.ToList(); - } - [Fact] - public void LeftJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); - query.ToList(); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); - query.ToList(); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); - query.ToList(); - } - [Fact] - public void InnerJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); - query.ToList(); - - //������� - query = select - .InnerJoin(a => a.Type.Guid == a.TypeGuid) - .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); - query.ToList(); - - query = select - .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .InnerJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .InnerJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); - query.ToList(); - - } - [Fact] - public void RightJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); - query.ToList(); - - //������� - query = select - .RightJoin(a => a.Type.Guid == a.TypeGuid) - .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); - query.ToList(); - - query = select - .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .RightJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .RightJoin(a => a.TypeGuid == b.Guid) - .RightJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); - query.ToList(); - - query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); - query.ToList(); - - } - [Fact] - public void Where() { - var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); - var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); - var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); - - var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.Where(a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); - query.ToList(); - - query = select.Where(a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); - query.ToList(); - - //���û�е������ԣ��򵥶������ - query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); - query.ToList(); - - query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); - query.ToList(); - - query = select.Where((a, b, c) => c.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .Where(a => a.Id == 10 && c.Name == "xxx") - .Where(a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); - query.ToList(); - } - [Fact] - public void WhereIf() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.WhereIf(true, a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(true, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); - query.ToList(); - - // ==========================================WhereIf(false) - - //����е�������a.Type��a.Type.Parent ���ǵ������� - query = select.WhereIf(false, a => a.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - query2 = select.From((s, b, c) => s - .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(false, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); - query.ToList(); - } - [Fact] - public void WhereExists() { - var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); - - sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - - //.Offset(a.Id) - - .Any() - ).Any() - ).ToList(); - } - [Fact] - public void GroupBy() { - var groupby = select.From((s, b, c) => s - .Where(a => a.Id == 1) - ) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()) - .Offset(10) - .Limit(2) - .ToList(a => new { - a.Key.tt2, - cou1 = a.Count(), - arg1 = a.Avg(a.Key.mod4), - ccc2 = a.Key.tt2 ?? "now()", - //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") - ccc3 = a.Max(a.Value.Item3.Id) - }); - - var testpid1 = g.oracle.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - g.oracle.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); - - var aggsql1 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist1 = select - .GroupBy(a => a.Title) - .ToList(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToSql(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToList(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql3 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid), - sum3 = b.Sum(b.Value.Type.Parent.Id) - }); - } - [Fact] - public void ToAggregate() { - var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - } - [Fact] - public void OrderBy() { - var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); - } - [Fact] - public void Skip_Offset() { - var sql = select.Offset(10).ToList(); - } - [Fact] - public void Take_Limit() { - var sql = select.Limit(10).ToList(); - } - [Fact] - public void Page() { - var sql1 = select.Page(1, 10).ToList(); - var sql2 = select.Page(2, 10).ToList(); - var sql3 = select.Page(3, 10).ToList(); - - var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); - var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); - var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); - } - [Fact] - public void Distinct() { - var t1 = select.Distinct().ToList(a => a.Title); - var t2 = select.Distinct().Limit(10).ToList(a => a.Title); - } - - [Fact] - public void Sum() { - } - [Fact] - public void Min() { - } - [Fact] - public void Max() { - } - [Fact] - public void Avg() { - } - [Fact] - public void As() { - } - - [Fact] - public void AsTable() { - - var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); - - Func tableRule = (type, oldname) => { - if (type == typeof(Topic)) return oldname + "AsTable1"; - else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; - return oldname + "AsTable"; - }; - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); - - query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" c ON b.\"PARENTID\" = c.\"ID\"", sql); - - //������϶����㲻�� - query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); - - query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); - } - - public class TiOtmModel1 { - [Column(IsIdentity = true)] - public int id { get; set; } - public virtual TiOtmModel2 model2 { get; set; } - - public string m1name { get; set; } - } - public class TiOtmModel2 { - [Column(IsPrimary = true)] - public int model2id { get; set; } - public virtual TiOtmModel1 model1 { get; set; } - - public string m2setting { get; set; } - - public List childs { get; set; } - } - public class TiOtmModel3 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model2111Idaaa { get; set; } - public string title { get; set; } - - public List childs2 { get; set; } - } - public class TiOtmModel4 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model3333Id333 { get; set; } - public string title444 { get; set; } - } - - [Fact] - public void Include_OneToMany() { - var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; - model1.id = (int)g.oracle.Insert(model1).ExecuteIdentity(); - var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; - g.oracle.Insert(model2).ExecuteAffrows(); - - var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; - model3_1.id = (int)g.oracle.Insert(model3_1).ExecuteIdentity(); - var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; - model3_2.id = (int)g.oracle.Insert(model3_2).ExecuteIdentity(); - var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; - model3_3.id = (int)g.oracle.Insert(model3_2).ExecuteIdentity(); - - var model4s = new[] { - new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, - new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, - new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, - new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, - new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } - }; - Assert.Equal(5, g.oracle.Insert(model4s).ExecuteAffrows()); - - var t0 = g.oracle.Select() - .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t1 = g.oracle.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t2 = g.oracle.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - - var t00 = g.oracle.Select() - .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t11 = g.oracle.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t22 = g.oracle.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - } - - public class TiOtmModel11 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2id { get; set; } - public string m3setting { get; set; } - public TiOtmModel22 model2 { get; set; } - public string m1name { get; set; } - } - - public class TiOtmModel22 { - [Column(IsIdentity = true)] - public int id { get; set; } - public string m2setting { get; set; } - public List childs { get; set; } - } - public class TiOtmModel33 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2Id { get; set; } - public string title { get; set; } - public string setting { get; set; } - } - [Fact] - public void Include_OneToMany2() { - string setting = "x"; - var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString() }; - model2.id = (int)g.oracle.Insert(model2).ExecuteIdentity(); - - var model3s = new[] - { - new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, - new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, - new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} - }; - Assert.Equal(3, g.oracle.Insert(model3s).ExecuteAffrows()); - - var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; - model1.id = (int)g.oracle.Insert(model1).ExecuteIdentity(); - - var t1 = g.oracle.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - - var t11 = g.oracle.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - } - - [Fact] - public void Include_OneToChilds() { - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_中国" - }; - tag1.Id = (int)g.oracle.Insert(tag1).ExecuteIdentity(); - var tag1_1 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_北京" - }; - tag1_1.Id = (int)g.oracle.Insert(tag1_1).ExecuteIdentity(); - var tag1_2 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_上海" - }; - tag1_2.Id = (int)g.oracle.Insert(tag1_2).ExecuteIdentity(); - - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_美国" - }; - tag2.Id = (int)g.oracle.Insert(tag2).ExecuteIdentity(); - var tag2_1 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_纽约" - }; - tag2_1.Id = (int)g.oracle.Insert(tag2_1).ExecuteIdentity(); - var tag2_2 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_华盛顿" - }; - tag2_2.Id = (int)g.oracle.Insert(tag2_2).ExecuteIdentity(); - - var tags0 = g.oracle.Select() - .Include(a => a.Parent) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags1 = g.oracle.Select() - .IncludeMany(a => a.Tags) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags2 = g.oracle.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags3 = g.oracle.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags11 = g.oracle.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags22 = g.oracle.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags33 = g.oracle.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - } - - [Fact] - public void Include_ManyToMany() { - - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_01_中国" - }; - tag1.Id = (int)g.oracle.Insert(tag1).ExecuteIdentity(); - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_02_美国" - }; - tag2.Id = (int)g.oracle.Insert(tag2).ExecuteIdentity(); - var tag3 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_03_日本" - }; - tag3.Id = (int)g.oracle.Insert(tag3).ExecuteIdentity(); - - var song1 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_01_我是中国人.mp3", - Url = "http://ww.baidu.com/" - }; - song1.Id = (int)g.oracle.Insert(song1).ExecuteIdentity(); - var song2 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_02_爱你一万年.mp3", - Url = "http://ww.163.com/" - }; - song2.Id = (int)g.oracle.Insert(song2).ExecuteIdentity(); - var song3 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_03_千年等一回.mp3", - Url = "http://ww.sina.com/" - }; - song3.Id = (int)g.oracle.Insert(song3).ExecuteIdentity(); - - g.oracle.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.oracle.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.oracle.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); - - var songs1 = g.oracle.Select() - .IncludeMany(a => a.Tags) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs1.Count); - Assert.Equal(2, songs1[0].Tags.Count); - Assert.Equal(1, songs1[1].Tags.Count); - Assert.Equal(3, songs1[2].Tags.Count); - - var songs2 = g.oracle.Select() - .IncludeMany(a => a.Tags, - then => then.IncludeMany(t => t.Songs)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs2.Count); - Assert.Equal(2, songs2[0].Tags.Count); - Assert.Equal(1, songs2[1].Tags.Count); - Assert.Equal(3, songs2[2].Tags.Count); - - var tags3 = g.oracle.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - - - var songs11 = g.oracle.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs11.Count); - Assert.Equal(1, songs11[0].Tags.Count); - Assert.Equal(1, songs11[1].Tags.Count); - Assert.Equal(1, songs11[2].Tags.Count); - - var songs22 = g.oracle.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.IncludeMany(t => t.Songs.Take(1))) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs22.Count); - Assert.Equal(1, songs22[0].Tags.Count); - Assert.Equal(1, songs22[1].Tags.Count); - Assert.Equal(1, songs22[2].Tags.Count); - - var tags33 = g.oracle.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs.Take(1)) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - } - } +namespace FreeSql.Tests.Oracle +{ + public class OracleSelectTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.oracle.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.oracle.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.oracle.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.oracle.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.oracle.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.oracle.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.oracle.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.oracle.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + g.oracle.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.oracle.Select().ToList(); + var testGuidId6 = g.oracle.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.oracle.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.oracle.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + } + [Fact] + public void Min() + { + } + [Fact] + public void Max() + { + } + [Fact] + public void Avg() + { + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.oracle.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.oracle.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.oracle.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.oracle.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.oracle.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.oracle.Insert(model4s).ExecuteAffrows()); + + var t0 = g.oracle.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.oracle.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.oracle.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.oracle.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.oracle.Insert(model1).ExecuteIdentity(); + + var t1 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.oracle.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.oracle.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.oracle.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.oracle.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.oracle.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.oracle.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.oracle.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.oracle.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.oracle.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.oracle.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.oracle.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.oracle.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.oracle.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.oracle.Insert(song3).ExecuteIdentity(); + + g.oracle.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.oracle.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 2fb79001..22f204aa 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -3,125 +3,139 @@ using System; using System.Collections.Generic; using Xunit; -namespace FreeSql.Tests.Oracle { - public class OracleUpdateTest { - IUpdate update => g.oracle.Update(); +namespace FreeSql.Tests.Oracle +{ + public class OracleUpdateTest + { + IUpdate update => g.oracle.Update(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - - [Fact] - public void Dywhere() { - Assert.Null(g.oracle.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); - } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void SetSource() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = :p_0, \"TITLE\" = :p_1, \"CREATETIME\" = :p_2 WHERE (\"ID\" = 1)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(g.oracle.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = :p_0, \"TITLE\" = :p_1, \"CREATETIME\" = :p_2 WHERE (\"ID\" = 1)", sql); - sql = update.SetSource(items).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN :p_0 WHEN 2 THEN :p_1 WHEN 3 THEN :p_2 WHEN 4 THEN :p_3 WHEN 5 THEN :p_4 WHEN 6 THEN :p_5 WHEN 7 THEN :p_6 WHEN 8 THEN :p_7 WHEN 9 THEN :p_8 WHEN 10 THEN :p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN :p_10 WHEN 2 THEN :p_11 WHEN 3 THEN :p_12 WHEN 4 THEN :p_13 WHEN 5 THEN :p_14 WHEN 6 THEN :p_15 WHEN 7 THEN :p_16 WHEN 8 THEN :p_17 WHEN 9 THEN :p_18 WHEN 10 THEN :p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN :p_20 WHEN 2 THEN :p_21 WHEN 3 THEN :p_22 WHEN 4 THEN :p_23 WHEN 5 THEN :p_24 WHEN 6 THEN :p_25 WHEN 7 THEN :p_26 WHEN 8 THEN :p_27 WHEN 9 THEN :p_28 WHEN 10 THEN :p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN :p_0 WHEN 2 THEN :p_1 WHEN 3 THEN :p_2 WHEN 4 THEN :p_3 WHEN 5 THEN :p_4 WHEN 6 THEN :p_5 WHEN 7 THEN :p_6 WHEN 8 THEN :p_7 WHEN 9 THEN :p_8 WHEN 10 THEN :p_9 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN :p_0 WHEN 2 THEN :p_1 WHEN 3 THEN :p_2 WHEN 4 THEN :p_3 WHEN 5 THEN :p_4 WHEN 6 THEN :p_5 WHEN 7 THEN :p_6 WHEN 8 THEN :p_7 WHEN 9 THEN :p_8 WHEN 10 THEN :p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN :p_10 WHEN 2 THEN :p_11 WHEN 3 THEN :p_12 WHEN 4 THEN :p_13 WHEN 5 THEN :p_14 WHEN 6 THEN :p_15 WHEN 7 THEN :p_16 WHEN 8 THEN :p_17 WHEN 9 THEN :p_18 WHEN 10 THEN :p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN :p_20 WHEN 2 THEN :p_21 WHEN 3 THEN :p_22 WHEN 4 THEN :p_23 WHEN 5 THEN :p_24 WHEN 6 THEN :p_25 WHEN 7 THEN :p_26 WHEN 8 THEN :p_27 WHEN 9 THEN :p_28 WHEN 10 THEN :p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = :p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void IgnoreColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0 WHERE (\"ID\" = 1)", sql); - } - [Fact] - public void UpdateColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0 WHERE (\"ID\" = 1)", sql); - } - [Fact] - public void Set() { - var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0 WHERE (\"ID\" = 1)", sql); + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN :p_0 WHEN 2 THEN :p_1 WHEN 3 THEN :p_2 WHEN 4 THEN :p_3 WHEN 5 THEN :p_4 WHEN 6 THEN :p_5 WHEN 7 THEN :p_6 WHEN 8 THEN :p_7 WHEN 9 THEN :p_8 WHEN 10 THEN :p_9 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0, \"CREATETIME\" = :p_1 WHERE (\"ID\" = 1)", sql); + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = :p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0 WHERE (\"ID\" = 1)", sql); - sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = nvl(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0, \"CREATETIME\" = :p_1 WHERE (\"ID\" = 1)", sql); - sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = nvl(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); - int incrv = 10; - sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = nvl(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); - sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = nvl(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); - sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = \"CLICKS\" * 10 / 1 WHERE (\"ID\" = 1)", sql); + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); - sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); - } - [Fact] - public void SetRaw() { - var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + :incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + :incrClick WHERE (\"ID\" = 1)", sql); - } - [Fact] - public void Where() { - var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = \"CLICKS\" * 10 / 1 WHERE (\"ID\" = 1)", sql); - sql = update.Where("id = :id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = :id)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + :incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + :incrClick WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + sql = update.Where("id = :id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = :id)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); - } - [Fact] - public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteUpdated() { + } + [Fact] + public void ExecuteAffrows() + { - } + } + [Fact] + public void ExecuteUpdated() + { - [Fact] - public void AsTable() { - Assert.Null(g.oracle.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - } - } + } + + [Fact] + public void AsTable() + { + Assert.Null(g.oracle.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs index e5943264..d3da1a49 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs @@ -2,1561 +2,1595 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.OracleMapType { - public class BoolNullableTest { - class BoolNullableMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool))] - public bool? tobool { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool? tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool? tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool? toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool? toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool? toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool? tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool? tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool? tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool? tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool? tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool? toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool? toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool? touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool? touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool? toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool? toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool? tostring { get; set; } = true; - } - [Fact] - public void Bool() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item = new BoolNullableMap { tobool = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item = new BoolNullableMap { tobool = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update all - item.tobool = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item.tobool = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item.tobool = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item = new BoolNullableMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item = new BoolNullableMap { tosbyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item.tosbyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item.tosbytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item = new BoolNullableMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item = new BoolNullableMap { toshort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item.toshort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item.toshortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item = new BoolNullableMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item = new BoolNullableMap { toint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item.toint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item = new BoolNullableMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item = new BoolNullableMap { tointnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item.tointnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item = new BoolNullableMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item = new BoolNullableMap { tolong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item.tolong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item.tolongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item = new BoolNullableMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item = new BoolNullableMap { tobyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item.tobyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item.tobytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item = new BoolNullableMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item = new BoolNullableMap { toushort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item.toushort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item.toushortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item = new BoolNullableMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item = new BoolNullableMap { touint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item.touint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item = new BoolNullableMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item = new BoolNullableMap { touintnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item.touintnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item = new BoolNullableMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item = new BoolNullableMap { toulong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item.toulong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item.toulongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.oracle; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item = new BoolNullableMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item = new BoolNullableMap { tostring = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item.tostring = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.OracleMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs index b94db356..0aab5f9f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs @@ -2,1095 +2,1129 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.OracleMapType { - public class BoolTest { - - class BoolMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool?))] - public bool toboolnullable { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool tostring { get; set; } = true; - } - - [Fact] - public void BoolNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item = new BoolMap { toboolnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update all - item.toboolnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item.toboolnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toboolnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toboolnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item = new BoolMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item = new BoolMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item = new BoolMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item = new BoolMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item = new BoolMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item = new BoolMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item = new BoolMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item = new BoolMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item = new BoolMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item = new BoolMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item = new BoolMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item = new BoolMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item = new BoolMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item = new BoolMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item = new BoolMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item = new BoolMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.oracle; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item = new BoolMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.OracleMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/EnumTest.cs index eb87ac61..5665ab31 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/EnumTest.cs @@ -3,252 +3,259 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.OracleMapType { - public class EnumTest { - class EnumTestMap { - public Guid id { get; set; } +namespace FreeSql.Tests.OracleMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(int))] - public ToStringMapEnum enum_to_int { get; set; } - [Column(MapType = typeof(int?))] - public ToStringMapEnum? enumnullable_to_int { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void EnumToString() { - //insert - var orm = g.oracle; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToString() { - //insert - var orm = g.oracle; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void EnumToInt() { - //insert - var orm = g.oracle; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + [Fact] + public void EnumToInt() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //update all - item.enum_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - item.enum_to_int = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToInt() { - //insert - var orm = g.oracle; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); - //update all - item.enumnullable_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); - item.enumnullable_to_int = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/ToStringTest.cs index 261d8746..5b5c8540 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/ToStringTest.cs @@ -3,555 +3,568 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.OracleMapType { - public class ToStringTest { - class ToStringMap { - public Guid id { get; set; } +namespace FreeSql.Tests.OracleMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan timespan_to_string { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan? timespannullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime datetime_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime? datetimenullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid guid_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid? guidnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger biginteger_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger? bigintegernullable_to_string { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void Enum1() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullable() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigInteger1() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(0, find.biginteger_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); - item = new ToStringMap { biginteger_to_string = 100 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(100, find.biginteger_to_string); + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); - //update all - item.biginteger_to_string = 200; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(200, find.biginteger_to_string); + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); - item.biginteger_to_string = 205; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(205, find.biginteger_to_string); + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(522, find.biginteger_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(10005, find.biginteger_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigIntegerNullable() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - item = new ToStringMap { bigintegernullable_to_string = 101 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(101, find.bigintegernullable_to_string); + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); - //update all - item.bigintegernullable_to_string = 2004; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(2004, find.bigintegernullable_to_string); + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); - item.bigintegernullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(998, find.bigintegernullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.bigintegernullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpan1() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); - item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); - //update all - item.timespan_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpanNullable() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); - //update all - item.timespannullable_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); - item.timespannullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.timespannullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTime1() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.MinValue, find.datetime_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); - item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); - //update all - item.datetime_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTimeNullable() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); - //update all - item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); - item.datetimenullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.datetimenullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void Guid1() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(Guid.Empty, find.guid_to_string); + [Fact] + public void Guid1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guid_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update all - newid = Guid.NewGuid(); - item.guid_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guid_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void GuidNullable() { - //insert - var orm = g.oracle; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guidnullable_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - //update all - newid = Guid.NewGuid(); - item.guidnullable_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - item.guidnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guidnullable_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.guidnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs index 3fd79377..a2c24d8e 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs @@ -2,54 +2,65 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.Oracle { - public class OracleAdoTest { - [Fact] - public void Pool() { - var t1 = g.oracle.Ado.MasterPool.StatisticsFullily; - } +namespace FreeSql.Tests.Oracle +{ + public class OracleAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.oracle.Ado.MasterPool.StatisticsFullily; + } - [Fact] - public void SlavePools() { - var t2 = g.oracle.Ado.SlavePools.Count; - } + [Fact] + public void SlavePools() + { + var t2 = g.oracle.Ado.SlavePools.Count; + } - [Fact] - public void ExecuteReader() { - - } - [Fact] - public void ExecuteArray() { - - } - [Fact] - public void ExecuteNonQuery() { - - } - [Fact] - public void ExecuteScalar() { - - } + [Fact] + public void ExecuteReader() + { - [Fact] - public void Query() { + } + [Fact] + public void ExecuteArray() + { - var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + } + [Fact] + public void ExecuteNonQuery() + { - var t4 = g.oracle.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + } + [Fact] + public void ExecuteScalar() + { - var t5 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); - } + } - [Fact] - public void QueryMultipline() { - //var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); - } + [Fact] + public void Query() + { - class xxx { - public int Id { get; set; } - public string Path { get; set; } - public string Title2 { get; set; } - } - } + var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + + var t4 = g.oracle.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + + var t5 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 32b94b6f..9dcd8f9d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -6,81 +6,92 @@ using System.Linq; using System.Text; using Xunit; -namespace FreeSql.Tests.Oracle { - public class OracleCodeFirstTest { +namespace FreeSql.Tests.Oracle +{ + public class OracleCodeFirstTest + { - [Fact] - public void ı_ֶ() { - var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<ı>(); - g.oracle.CodeFirst.SyncStructure<ı>(); + [Fact] + public void ı_ֶ() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<ı>(); + g.oracle.CodeFirst.SyncStructure<ı>(); - var item = new ı { - = "Ա", - ʱ = DateTime.Now - }; - Assert.Equal(1, g.oracle.Insert<ı>().AppendData(item).ExecuteAffrows()); - Assert.NotEqual(Guid.Empty, item.); - var item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); - Assert.NotNull(item2); - Assert.Equal(item., item2.); - Assert.Equal(item., item2.); - } - class ı { - [Column(IsPrimary = true)] - public Guid { get; set; } + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.oracle.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } - public string { get; set; } + public string { get; set; } - public DateTime ʱ { get; set; } - } + public DateTime ʱ { get; set; } + } - [Fact] - public void AddUniques() { - var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); - g.oracle.CodeFirst.SyncStructure(); - } - [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - class AddUniquesInfo { - public Guid id { get; set; } - [Column(Unique = "uk_phone")] - public string phone { get; set; } + [Fact] + public void AddUniques() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + g.oracle.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] - public string group { get; set; } - [Column(Unique = "uk_group_index")] - public int index { get; set; } - [Column(Unique = "uk_group_index22")] - public string index22 { get; set; } - } - [Fact] - public void AddField() { - var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); - var id = g.oracle.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + var id = g.oracle.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); - //var inserted = g.oracle.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); - } + //var inserted = g.oracle.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } - [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] - public class TopicAddField { - [Column(IsIdentity = true)] - public int Id { get; set; } + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } - public string name { get; set; } + public string name { get; set; } - [Column(DbType = "varchar2(200 char) not null", OldName = "title")] - public string title2 { get; set; } = "10"; + [Column(DbType = "varchar2(200 char) not null", OldName = "title")] + public string title2 { get; set; } = "10"; - [Column(IsIgnore = true)] - public DateTime ct { get; set; } = DateTime.Now; - } + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } - [Fact] - public void GetComparisonDDLStatements() { + [Fact] + public void GetComparisonDDLStatements() + { - var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( `Id` INT(11) NOT NULL AUTO_INCREMENT, `Bool` BIT(1) NOT NULL, `SByte` TINYINT(3) NOT NULL, @@ -127,114 +138,117 @@ namespace FreeSql.Tests.Oracle { PRIMARY KEY (`Id`) ) Engine=InnoDB; ", sql); - } + } - //sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); - } + //sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + } - IInsert insert => g.oracle.Insert(); - ISelect select => g.oracle.Select(); + IInsert insert => g.oracle.Insert(); + ISelect select => g.oracle.Select(); - [Fact] - public void CurdAllField() { - var item = new TableAllType { }; - item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); - var newitem = select.Where(a => a.Id == item.Id).ToOne(); + var newitem = select.Where(a => a.Id == item.Id).ToOne(); - var item2 = new TableAllType { - Bool = true, - BoolNullable = true, - Byte = 255, - ByteNullable = 127, - Bytes = Encoding.UTF8.GetBytes("й"), - DateTime = DateTime.Now, - DateTimeNullable = DateTime.Now.AddHours(-1), - Decimal = 99.99M, - DecimalNullable = 99.98M, - Double = 999.99, - DoubleNullable = 999.98, - Enum1 = TableAllTypeEnumType1.e5, - Enum1Nullable = TableAllTypeEnumType1.e3, - Enum2 = TableAllTypeEnumType2.f2, - Enum2Nullable = TableAllTypeEnumType2.f3, - Float = 19.99F, - FloatNullable = 19.98F, - Guid = Guid.NewGuid(), - GuidNullable = Guid.NewGuid(), - Int = int.MaxValue, - IntNullable = int.MinValue, - SByte = 100, - SByteNullable = 99, - Short = short.MaxValue, - ShortNullable = short.MinValue, - String = "йstring", - TimeSpan = TimeSpan.FromSeconds(999), - TimeSpanNullable = TimeSpan.FromSeconds(60), - UInt = uint.MaxValue, - UIntNullable = uint.MinValue, - ULong = ulong.MaxValue, - ULongNullable = ulong.MinValue, - UShort = ushort.MaxValue, - UShortNullable = ushort.MinValue, - testFielLongNullable = long.MinValue - }; - item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); - var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); - var items = select.ToList(); - } + var items = select.ToList(); + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - public string id2 { get; set; } = "id2=10"; + public string id2 { get; set; } = "id2=10"; - public bool Bool { get; set; } - public sbyte SByte { get; set; } - public short Short { get; set; } - public int Int { get; set; } - public long Long { get; set; } - public byte Byte { get; set; } - public ushort UShort { get; set; } - public uint UInt { get; set; } - public ulong ULong { get; set; } - public double Double { get; set; } - public float Float { get; set; } - public decimal Decimal { get; set; } - public TimeSpan TimeSpan { get; set; } - public DateTime DateTime { get; set; } - public DateTime DateTimeOffSet { get; set; } - public byte[] Bytes { get; set; } - public string String { get; set; } - public Guid Guid { get; set; } + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } - public bool? BoolNullable { get; set; } - public sbyte? SByteNullable { get; set; } - public short? ShortNullable { get; set; } - public int? IntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? ByteNullable { get; set; } - public ushort? UShortNullable { get; set; } - public uint? UIntNullable { get; set; } - public ulong? ULongNullable { get; set; } - public double? DoubleNullable { get; set; } - public float? FloatNullable { get; set; } - public decimal? DecimalNullable { get; set; } - public TimeSpan? TimeSpanNullable { get; set; } - public DateTime? DateTimeNullable { get; set; } - public DateTime? DateTimeOffSetNullable { get; set; } - public Guid? GuidNullable { get; set; } + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } - public TableAllTypeEnumType1 Enum1 { get; set; } - public TableAllTypeEnumType1? Enum1Nullable { get; set; } - public TableAllTypeEnumType2 Enum2 { get; set; } - public TableAllTypeEnumType2? Enum2Nullable { get; set; } - } + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs index 639e37ee..841ef36b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs @@ -2,20 +2,24 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.Oracle { - public class OracleDbFirstTest { - [Fact] - public void GetDatabases() { +namespace FreeSql.Tests.Oracle +{ + public class OracleDbFirstTest + { + [Fact] + public void GetDatabases() + { - var t1 = g.oracle.DbFirst.GetDatabases(); + var t1 = g.oracle.DbFirst.GetDatabases(); - } + } - [Fact] - public void GetTablesByDatabase() { + [Fact] + public void GetTablesByDatabase() + { - var t2 = g.oracle.DbFirst.GetTablesByDatabase(); + var t2 = g.oracle.DbFirst.GetTablesByDatabase(); - } - } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/ConvertTest.cs index e01de2fe..af5cc3f0 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/ConvertTest.cs @@ -4,143 +4,166 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.OracleExpression { - public class ConvertTest { +namespace FreeSql.Tests.OracleExpression +{ + public class ConvertTest + { - ISelect select => g.oracle.Select(); + ISelect select => g.oracle.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void ToBoolean() { - var data = new List(); - //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); - //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); - } - [Fact] - public void ToByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); - data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); - } - [Fact] - public void ToChar() { - var data = new List(); - data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); - data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); - } - [Fact] - public void ToDateTime() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); - } - [Fact] - public void ToDecimal() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToDouble() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt32() { - var data = new List(); - data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); - data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToSByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); - data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); - } - [Fact] - public void ToSingle() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); - data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); - } - [Fact] - public void ToUInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt32() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); - } + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } - [Fact] - public void Guid_Parse() { - var data = new List(); - data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); - } + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } - [Fact] - public void Guid_NewGuid() { - var data = new List(); - //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); - } + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } - [Fact] - public void Random() { - var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); - } - } + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs index 48bedc9e..0fe69d3a 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs @@ -4,664 +4,703 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.OracleExpression { - public class DateTimeTest { - - ISelect select => g.oracle.Select(); - - [Table(Name = "tb_topic111333")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - [Table(Name = "TestTypeInfo333")] - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - public DateTime Time { get; set; } - } - [Table(Name = "TestTypeParentInf1")] - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - public DateTime Time2 { get; set; } - } - [Fact] - public void Now() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void UtcNow() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void Date() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) - } - [Fact] - public void TimeOfDay() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) - } - [Fact] - public void DayOfWeek() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) - } - [Fact] - public void Day() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) - } - [Fact] - public void DayOfYear() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) - } - [Fact] - public void Month() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (month(a.`CreateTime`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (month(a__Type.`Time`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (month(a__Type__Parent.`Time2`) > month(now())) - } - [Fact] - public void Year() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (year(a.`CreateTime`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (year(a__Type.`Time`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (year(a__Type__Parent.`Time2`) > year(now())) - } - [Fact] - public void Hour() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (hour(a.`CreateTime`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (hour(a__Type.`Time`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) - } - [Fact] - public void Minute() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (minute(a.`CreateTime`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (minute(a__Type.`Time`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) - } - [Fact] - public void Second() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (second(a.`CreateTime`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (second(a__Type.`Time`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (second(a__Type__Parent.`Time2`) > second(now())) - } - [Fact] - public void Millisecond() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) - } - [Fact] - public void AddDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) - } - [Fact] - public void AddHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) - } - [Fact] - public void AddMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) - } - [Fact] - public void AddMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) - } - [Fact] - public void AddMonths() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) - } - [Fact] - public void AddSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) - } - [Fact] - public void AddTicks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) - } - [Fact] - public void AddYears() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - } - [Fact] - public void _ЧͬSubtract() { - var data = new List(); - data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - - [Fact] - public void DateTime_Compare() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((a.`CreateTime`) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) - } - [Fact] - public void DateTime_DaysInMonth() { - var data = new List(); - data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) - } - [Fact] - public void DateTime_Equals() { - var data = new List(); - data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void DateTime_IsLeapYear() { - var data = new List(); - data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) - } - [Fact] - public void DateTime_Parse() { - var data = new List(); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) - } - } +namespace FreeSql.Tests.OracleExpression +{ + public class DateTimeTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/MathTest.cs index 51bd9fb1..ca9156ca 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/MathTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/MathTest.cs @@ -4,129 +4,153 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.OracleExpression { - public class MathTest { +namespace FreeSql.Tests.OracleExpression +{ + public class MathTest + { - ISelect select => g.oracle.Select(); + ISelect select => g.oracle.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void PI() { - var data = new List(); - data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); - } - [Fact] - public void Abs() { - var data = new List(); - data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Sign() { - var data = new List(); - data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Floor() { - var data = new List(); - data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); - } - [Fact] - public void Ceiling() { - var data = new List(); - data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Round() { - var data = new List(); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); - } - [Fact] - public void Exp() { - var data = new List(); - data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log() { - var data = new List(); - data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log10() { - var data = new List(); - data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Pow() { - var data = new List(); - data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sqrt() { - var data = new List(); - data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Cos() { - var data = new List(); - data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sin() { - var data = new List(); - data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Tan() { - var data = new List(); - data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Acos() { - var data = new List(); - //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Asin() { - var data = new List(); - //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan() { - var data = new List(); - data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan2() { - var data = new List(); - //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Truncate() { - var data = new List(); - data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); - } - } + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs index 60af2b04..512c1441 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs @@ -4,110 +4,116 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.OracleExpression { - public class OtherTest { +namespace FreeSql.Tests.OracleExpression +{ + public class OtherTest + { - ISelect select => g.oracle.Select(); + ISelect select => g.oracle.Select(); - public OtherTest() { - } + public OtherTest() + { + } - [Fact] - public void Boolean() { - var t1 = select.Where(a => a.Bool == true).ToList(); - var t2 = select.Where(a => a.Bool != true).ToList(); - var t3 = select.Where(a => a.Bool == false).ToList(); - var t4 = select.Where(a => !a.Bool).ToList(); - var t5 = select.Where(a => a.Bool).ToList(); + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); - var t11 = select.Where(a => a.BoolNullable == true).ToList(); - var t22 = select.Where(a => a.BoolNullable != true).ToList(); - var t33 = select.Where(a => a.BoolNullable == false).ToList(); - var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); - var t55 = select.Where(a => a.BoolNullable.Value).ToList(); - } + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + } - [Fact] - public void Array() { - IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); - var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); - //in not in - var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); - //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); - var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); - var inarray = new[] { 1, 2, 3 }; - var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); - //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); - var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); - //in not in - var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); - //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); - var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); - var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); - //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); - var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); - var inarray2 = new List() { 1, 2, 3 }; - var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); - //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); - var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); - } + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - public string id2 { get; set; } = "id2=10"; + public string id2 { get; set; } = "id2=10"; - public bool Bool { get; set; } - public sbyte SByte { get; set; } - public short Short { get; set; } - public int Int { get; set; } - public long Long { get; set; } - public byte Byte { get; set; } - public ushort UShort { get; set; } - public uint UInt { get; set; } - public ulong ULong { get; set; } - public double Double { get; set; } - public float Float { get; set; } - public decimal Decimal { get; set; } - public TimeSpan TimeSpan { get; set; } - public DateTime DateTime { get; set; } - public DateTime DateTimeOffSet { get; set; } - public byte[] Bytes { get; set; } - public string String { get; set; } - public Guid Guid { get; set; } + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } - public bool? BoolNullable { get; set; } - public sbyte? SByteNullable { get; set; } - public short? ShortNullable { get; set; } - public int? IntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? ByteNullable { get; set; } - public ushort? UShortNullable { get; set; } - public uint? UIntNullable { get; set; } - public ulong? ULongNullable { get; set; } - public double? DoubleNullable { get; set; } - public float? FloatNullable { get; set; } - public decimal? DecimalNullable { get; set; } - public TimeSpan? TimeSpanNullable { get; set; } - public DateTime? DateTimeNullable { get; set; } - public DateTime? DateTimeOffSetNullable { get; set; } - public Guid? GuidNullable { get; set; } + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } - public TableAllTypeEnumType1 Enum1 { get; set; } - public TableAllTypeEnumType1? Enum1Nullable { get; set; } - public TableAllTypeEnumType2 Enum2 { get; set; } - public TableAllTypeEnumType2? Enum2Nullable { get; set; } - } + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index 0fb3456c..7d2017d1 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -4,692 +4,716 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.OracleExpression { - public class StringTest { - - ISelect select => g.oracle.Select(); - - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - class TestEqualsGuid { - public Guid id { get; set; } - } - - [Fact] - public void Equals__() { - var list = new List(); - list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); - list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); - } - - - [Fact] - public void Empty() { - var data = new List(); - data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ifnull(a.`Title`, '') = '') - } - - [Fact] - public void StartsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) - list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) - } - [Fact] - public void EndsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) - } - [Fact] - public void Contains() { - var list = new List(); - list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) - } - [Fact] - public void ToLower() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void ToUpper() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void Substring() { - var data = new List(); - data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) - } - [Fact] - public void Length() { - var data = new List(); - data.Add(select.Where(a => a.Title.Length == 0).ToList()); - data.Add(select.Where(a => a.Title.Length == 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); - data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) - } - [Fact] - public void IndexOf() { - var data = new List(); - data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) - } - [Fact] - public void PadLeft() { - var data = new List(); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void PadRight() { - var data = new List(); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void Trim() { - var data = new List(); - data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void TrimStart() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) - } - [Fact] - public void TrimEnd() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void Replace() { - var data = new List(); - data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) - } - - [Fact] - public void string_IsNullOrEmpty() { - var data = new List(); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); - //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); - data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); - } - } +namespace FreeSql.Tests.OracleExpression +{ + public class StringTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/TimeSpanTest.cs index 00e5491e..b1745d13 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/TimeSpanTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/TimeSpanTest.cs @@ -4,257 +4,290 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.OracleExpression { - public class TimeSpanTest { +namespace FreeSql.Tests.OracleExpression +{ + public class TimeSpanTest + { - ISelect select => g.oracle.Select(); + ISelect select => g.oracle.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } - [Fact] - public void Zero() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) - } - [Fact] - public void Days() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) - } - [Fact] - public void Hours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) - } - [Fact] - public void Milliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) - } - [Fact] - public void Minutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) - } - [Fact] - public void Seconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) - } - [Fact] - public void TotalDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) - } - [Fact] - public void TotalHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) - } - [Fact] - public void TotalMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) - } - [Fact] - public void TotalMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) - } - [Fact] - public void TotalSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') - } + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } - [Fact] - public void TimeSpan_Compare() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void TimeSpan_Equals() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromDays() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromHours() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) - } - [Fact] - public void TimeSpan_FromMilliseconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) - } - [Fact] - public void TimeSpan_FromMinutes() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) - } - [Fact] - public void TimeSpan_FromSeconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) - } - [Fact] - public void TimeSpan_FromTicks() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) - } - [Fact] - public void TimeSpan_Parse() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) - } - } + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index aad0a58b..360024bc 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -4,85 +4,94 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQL { - public class PostgreSQLDeleteTest { +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLDeleteTest + { - IDelete delete => g.pgsql.Delete(); + IDelete delete => g.pgsql.Delete(); - [Table(Name = "tb_topic_del")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } + [Table(Name = "tb_topic_del")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void Dywhere() { - Assert.Null(g.pgsql.Delete().ToSql()); - var sql = g.pgsql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(g.pgsql.Delete().ToSql()); + var sql = g.pgsql.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); - sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); - sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); - sql = g.pgsql.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); - } + sql = g.pgsql.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + } - [Fact] - public void Where() { - var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); - sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (id = @id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (id = @id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - var id = g.pgsql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); - Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); - } - [Fact] - public void ExecuteDeleted() { + var id = g.pgsql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { - delete.Where(a => a.Id > 0).ExecuteDeleted(); - } + delete.Where(a => a.Id > 0).ExecuteDeleted(); + } - [Fact] - public void AsTable() { - Assert.Null(g.pgsql.Delete().ToSql()); - var sql = g.pgsql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + [Fact] + public void AsTable() + { + Assert.Null(g.pgsql.Delete().ToSql()); + var sql = g.pgsql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); - sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1)", sql); + sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1)", sql); - sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); - sql = g.pgsql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1)", sql); - } - } + sql = g.pgsql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs index b9de2ad9..877650ac 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -4,112 +4,122 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQL { - public class PostgreSQLInsertTest { +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLInsertTest + { - IInsert insert => g.pgsql.Insert(); + IInsert insert => g.pgsql.Insert(); - [Table(Name = "tb_topic_insert")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - - [Fact] - public void AppendData() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); - } + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); - [Fact] - public void InsertColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + } - var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); - } - [Fact] - public void IgnoreColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); - var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); - } - [Fact] - public void ExecuteAffrows() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); - Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); - } - [Fact] - public void ExecuteIdentity() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); - } - [Fact] - public void ExecuteInserted() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - insert.AppendData(items.First()).ExecuteInserted(); - } + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - [Fact] - public void AsTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + insert.AppendData(items.First()).ExecuteInserted(); + } - var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); - } - } + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index b4ac0f9f..a6bc17c1 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -4,1179 +4,1256 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQL { - public class PostgreSQLSelectTest { - - ISelect select => g.pgsql.Select(); - - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - public partial class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } - - public virtual ICollection Tags { get; set; } - } - public partial class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } - - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } - } - public partial class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public decimal? Ddd { get; set; } - public string Name { get; set; } - - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } - } - - [Fact] - public void AsSelect() { - //OneToOne、ManyToOne - var t0 = g.pgsql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 - //FROM `Tag` a - //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` - //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` - //WHERE (a__Parent__Parent.`Name` = '粤语') - - //OneToMany - var t1 = g.pgsql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` - //FROM `Tag` a - //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) - - //ManyToMany - var t2 = g.pgsql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); - //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` - //FROM `Song` a - //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) - } - - [Fact] - public void Lazy() { - var tags = g.pgsql.Select().Where(a => a.Parent.Name == "xxx") - .LeftJoin(a => a.Parent_id == a.Parent.Id) - .ToSql(); - - var songs = g.pgsql.Select().Limit(10).ToList(); - } - - [Fact] - public void ToDataTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - - Assert.Single(g.pgsql.Insert().AppendData(items.First()).ExecuteInserted()); - Assert.Equal(10, g.pgsql.Insert().AppendData(items).ExecuteInserted().Count); - - //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //Assert.Equal(9989, g.pgsql.Insert(items).ExecuteAffrows()); - - var dt1 = select.Limit(10).ToDataTable(); - var dt2 = select.Limit(10).ToDataTable("id, 222"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); - } - class TestDto { - public int id { get; set; } - public string name { get; set; } //这是join表的属性 - public int ParentId { get; set; } //这是join表的属性 - } - [Fact] - public void ToList() { - - var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto2 = select.Limit(10).ToList(a => new TestDto()); - var testDto3 = select.Limit(10).ToList(a => new TestDto { }); - var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); - - var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); - var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); - var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); - - - var t1 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - var t2 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - - - var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); - var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); - var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); - - //g.pgsql.Select().Join((a, b, c) => new Model.JoinResult3( - // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, - // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") - //); - - //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) - //.Where(a => a.Id == 1).ToSql(); - - var sql4 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name == "xxx")).ToSql(); - //.Where(a => a.Id == 1).ToSql(); - - - var list111 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name != "xxx")); - var list111sql = list111.ToSql(); - var list111data = list111.ToList((a, b, c) => new { - a.Id, - title_substring = a.Title.Substring(0, 1), - a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new { - a.Id, - tp2 = a.Type.Name - }, - tp3 = new { - a.Id, - tp33 = new { - a.Id - } - } - }); - - var ttt122 = g.pgsql.Select().Where(a => a.Id > 0).ToSql(); - var sql5 = g.pgsql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); - var t11112 = g.pgsql.Select().ToList(a => new { - a.Id, - a.Title, - a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new { - a.Id, - tp2 = a.Type.Name - }, - tp3 = new { - a.Id, - tp33 = new { - a.Id - } - } - - }); - - var t100 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - var t101 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - - - var t1111 = g.pgsql.Select().ToList(a => new { a.Id, a.Title, a.Type }); - - var t2222 = g.pgsql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); - - g.pgsql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); - var testGuidId5 = g.pgsql.Select().ToList(); - var testGuidId6 = g.pgsql.Select().ToList(a => a.id); - - var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); - var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); - } - class TestGuidIdToList { - public Guid id { get; set; } - public string title { get; set; } = Guid.NewGuid().ToString(); - } - [Fact] - public void ToOne() { - var testnotfind = select.Where("1=2").First(a => a.CreateTime); - Assert.Equal(default(DateTime), testnotfind); - } - [Fact] - public void ToSql() { - } - [Fact] - public void Any() { - var count = select.Where(a => 1 == 1).Count(); - Assert.False(select.Where(a => 1 == 2).Any()); - Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); - - var sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && - select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - //.Offset(a.Id) - .Any() - ).Any(c => c.Id == a.Id + 10) - ); - var sql2222Tolist = sql2222.ToList(); - - var collectionSelect = select.Where(a => - a.Type.Guid == a.TypeGuid && - a.Type.Parent.Id == a.Type.ParentId && - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) - ); - collectionSelect.ToList(); - } - [Fact] - public void Count() { - var count = select.Where(a => 1 == 1).Count(); - select.Where(a => 1 == 1).Count(out var count2); - Assert.Equal(count, count2); - Assert.Equal(0, select.Where(a => 1 == 2).Count()); - } - [Fact] - public void Master() { - Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); - } - - [Fact] - public void From() { - - var query2 = select.From((s, b) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - ); - var sql2 = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\"", sql2); - query2.ToList(); - - var query3 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id) - ); - var sql3 = query3.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql3); - query3.ToList(); - } - [Fact] - public void LeftJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); - query.ToList(); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); - query.ToList(); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); - query.ToList(); - } - [Fact] - public void InnerJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); - query.ToList(); - - //������� - query = select - .InnerJoin(a => a.Type.Guid == a.TypeGuid) - .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" INNER JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); - query.ToList(); - - query = select - .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .InnerJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" INNER JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .InnerJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" INNER JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.InnerJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.InnerJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); - query.ToList(); - - } - [Fact] - public void RightJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); - query.ToList(); - - //������� - query = select - .RightJoin(a => a.Type.Guid == a.TypeGuid) - .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" RIGHT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); - query.ToList(); - - query = select - .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .RightJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" RIGHT JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .RightJoin(a => a.TypeGuid == b.Guid) - .RightJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" RIGHT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.RightJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); - query.ToList(); - - query = select.RightJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); - query.ToList(); - - } - [Fact] - public void Where() { - var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); - var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); - var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); - - var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.Where(a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10)", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE ((a.\"id\" = 10 AND a.\"id\" > 10 OR a.\"clicks\" > 100))", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10) AND (a.\"clicks\" > 100)", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle')", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle' AND a__Type.\"guid\" = a.\"typeguid\")", sql); - query.ToList(); - - query = select.Where(a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"name\" = 'tparent')", sql); - query.ToList(); - - //���û�е������ԣ��򵥶������ - query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b WHERE (b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'typeTitle')", sql); - query.ToList(); - - query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b WHERE (b.\"name\" = 'typeTitle' AND b.\"guid\" = a.\"typeguid\")", sql); - query.ToList(); - - query = select.Where((a, b, c) => c.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeparentinfo\" c WHERE (c.\"name\" = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .Where(a => a.Id == 10 && c.Name == "xxx") - .Where(a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c WHERE (a.\"id\" = 10 AND c.\"name\" = 'xxx') AND (b.\"parentid\" = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.Where("a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = @id)", sql); - query.ToList(); - } - [Fact] - public void WhereIf() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.WhereIf(true, a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE ((a.\"id\" = 10 AND a.\"id\" > 10 OR a.\"clicks\" > 100))", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10) AND (a.\"clicks\" > 100)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle')", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle' AND a__Type.\"guid\" = a.\"typeguid\")", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"name\" = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(true, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c WHERE (a.\"id\" = 10 AND c.\"name\" = 'xxx') AND (b.\"parentid\" = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(true, "a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = @id)", sql); - query.ToList(); - - // ==========================================WhereIf(false) - - //����е�������a.Type��a.Type.Parent ���ǵ������� - query = select.WhereIf(false, a => a.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - query2 = select.From((s, b, c) => s - .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(false, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(false, "a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); - query.ToList(); - } - [Fact] - public void WhereExists() { - var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); - - sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - - //.Offset(a.Id) - - .Any() - ).Any() - ).ToList(); - } - [Fact] - public void GroupBy() { - var groupby = select.From((s, b, c) => s - .Where(a => a.Id == 1) - ) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()) - .Offset(10) - .Limit(2) - .ToList(a => new { - a.Key.tt2, - cou1 = a.Count(), - arg1 = a.Avg(a.Key.mod4), - ccc2 = a.Key.tt2 ?? "now()", - //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") - ccc3 = a.Max(a.Value.Item3.Id) - }); - - var testpid1 = g.pgsql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - g.pgsql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); - - var aggsql1 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist1 = select - .GroupBy(a => a.Title) - .ToList(b => new { - b.Key, - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToSql(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToList(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql3 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid), - sum3 = b.Sum(b.Value.Type.Parent.Id) - }); - } - [Fact] - public void ToAggregate() { - var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - } - [Fact] - public void OrderBy() { - var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); - } - [Fact] - public void Skip_Offset() { - var sql = select.Offset(10).Limit(10).ToList(); - } - [Fact] - public void Take_Limit() { - var sql = select.Limit(10).ToList(); - } - [Fact] - public void Page() { - var sql1 = select.Page(1, 10).ToList(); - var sql2 = select.Page(2, 10).ToList(); - var sql3 = select.Page(3, 10).ToList(); - - var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); - var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); - var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); - } - [Fact] - public void Distinct() { - var t1 = select.Distinct().ToList(a => a.Title); - var t2 = select.Distinct().Limit(10).ToList(a => a.Title); - } - - [Fact] - public void Sum() { - } - [Fact] - public void Min() { - } - [Fact] - public void Max() { - } - [Fact] - public void Avg() { - } - [Fact] - public void As() { - } - - [Fact] - public void AsTable() { - - var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); - - Func tableRule = (type, oldname) => { - if (type == typeof(Topic)) return oldname + "AsTable1"; - else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; - return oldname + "AsTable"; - }; - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON b.\"guid\" = a.\"typeguid\"", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); - - query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoAsTable\" c ON c.\"id\" = a__Type.\"parentid\"", sql); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfoAsTable\" c ON b.\"parentid\" = c.\"id\"", sql); - - //������϶����㲻�� - query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); - - query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); - } - - public class TestInclude_OneToManyModel1 { - [Column(IsIdentity = true)] - public int id { get; set; } - public virtual TestInclude_OneToManyModel2 model2 { get; set; } - - public string m1name { get; set; } - } - public class TestInclude_OneToManyModel2 { - [Column(IsPrimary = true)] - public int model2id { get; set; } - public virtual TestInclude_OneToManyModel1 model1 { get; set; } - - public string m2setting { get; set; } - - public List childs { get; set; } - } - public class TestInclude_OneToManyModel3 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model2111Idaaa { get; set; } - public string title { get; set; } - - public List childs2 { get; set; } - } - public class TestInclude_OneToManyModel4 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model3333Id333 { get; set; } - public string title444 { get; set; } - } - - [Fact] - public void Include_OneToMany() { - var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; - model1.id = (int)g.pgsql.Insert(model1).ExecuteIdentity(); - var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; - g.pgsql.Insert(model2).ExecuteAffrows(); - - var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; - model3_1.id = (int)g.pgsql.Insert(model3_1).ExecuteIdentity(); - var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; - model3_2.id = (int)g.pgsql.Insert(model3_2).ExecuteIdentity(); - var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; - model3_3.id = (int)g.pgsql.Insert(model3_2).ExecuteIdentity(); - - var model4s = new[] { - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } - }; - Assert.Equal(5, g.pgsql.Insert(model4s).ExecuteAffrows()); - - var t0 = g.pgsql.Select() - .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t1 = g.pgsql.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t2 = g.pgsql.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - - var t00 = g.pgsql.Select() - .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t11 = g.pgsql.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t22 = g.pgsql.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - } - - public class TestInclude_OneToManyModel11 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2id { get; set; } - public string m3setting { get; set; } - public TestInclude_OneToManyModel22 model2 { get; set; } - public string m1name { get; set; } - } - - public class TestInclude_OneToManyModel22 { - [Column(IsIdentity = true)] - public int id { get; set; } - public string m2setting { get; set; } - public List childs { get; set; } - } - public class TestInclude_OneToManyModel33 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2Id { get; set; } - public string title { get; set; } - public string setting { get; set; } - } - [Fact] - public void Include_OneToMany2() { - string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; - model2.id = (int)g.pgsql.Insert(model2).ExecuteIdentity(); - - var model3s = new[] - { - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} - }; - Assert.Equal(3, g.pgsql.Insert(model3s).ExecuteAffrows()); - - var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; - model1.id = (int)g.pgsql.Insert(model1).ExecuteIdentity(); - - var t1 = g.pgsql.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - - var t11 = g.pgsql.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - } - - [Fact] - public void Include_OneToChilds() { - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_中国" - }; - tag1.Id = (int)g.pgsql.Insert(tag1).ExecuteIdentity(); - var tag1_1 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_北京" - }; - tag1_1.Id = (int)g.pgsql.Insert(tag1_1).ExecuteIdentity(); - var tag1_2 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_上海" - }; - tag1_2.Id = (int)g.pgsql.Insert(tag1_2).ExecuteIdentity(); - - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_美国" - }; - tag2.Id = (int)g.pgsql.Insert(tag2).ExecuteIdentity(); - var tag2_1 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_纽约" - }; - tag2_1.Id = (int)g.pgsql.Insert(tag2_1).ExecuteIdentity(); - var tag2_2 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_华盛顿" - }; - tag2_2.Id = (int)g.pgsql.Insert(tag2_2).ExecuteIdentity(); - - var tags0 = g.pgsql.Select() - .Include(a => a.Parent) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags1 = g.pgsql.Select() - .IncludeMany(a => a.Tags) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags2 = g.pgsql.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags3 = g.pgsql.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags11 = g.pgsql.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags22 = g.pgsql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags33 = g.pgsql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - } - - [Fact] - public void Include_ManyToMany() { - - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_01_中国" - }; - tag1.Id = (int)g.pgsql.Insert(tag1).ExecuteIdentity(); - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_02_美国" - }; - tag2.Id = (int)g.pgsql.Insert(tag2).ExecuteIdentity(); - var tag3 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_03_日本" - }; - tag3.Id = (int)g.pgsql.Insert(tag3).ExecuteIdentity(); - - var song1 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_01_我是中国人.mp3", - Url = "http://ww.baidu.com/" - }; - song1.Id = (int)g.pgsql.Insert(song1).ExecuteIdentity(); - var song2 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_02_爱你一万年.mp3", - Url = "http://ww.163.com/" - }; - song2.Id = (int)g.pgsql.Insert(song2).ExecuteIdentity(); - var song3 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_03_千年等一回.mp3", - Url = "http://ww.sina.com/" - }; - song3.Id = (int)g.pgsql.Insert(song3).ExecuteIdentity(); - - g.pgsql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.pgsql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.pgsql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); - - var songs1 = g.pgsql.Select() - .IncludeMany(a => a.Tags) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs1.Count); - Assert.Equal(2, songs1[0].Tags.Count); - Assert.Equal(1, songs1[1].Tags.Count); - Assert.Equal(3, songs1[2].Tags.Count); - - var songs2 = g.pgsql.Select() - .IncludeMany(a => a.Tags, - then => then.IncludeMany(t => t.Songs)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs2.Count); - Assert.Equal(2, songs2[0].Tags.Count); - Assert.Equal(1, songs2[1].Tags.Count); - Assert.Equal(3, songs2[2].Tags.Count); - - var tags3 = g.pgsql.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - - - var songs11 = g.pgsql.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs11.Count); - Assert.Equal(1, songs11[0].Tags.Count); - Assert.Equal(1, songs11[1].Tags.Count); - Assert.Equal(1, songs11[2].Tags.Count); - - var songs22 = g.pgsql.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.IncludeMany(t => t.Songs.Take(1))) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs22.Count); - Assert.Equal(1, songs22[0].Tags.Count); - Assert.Equal(1, songs22[1].Tags.Count); - Assert.Equal(1, songs22[2].Tags.Count); - - var tags33 = g.pgsql.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs.Take(1)) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - } - } +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLSelectTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.pgsql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.pgsql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.pgsql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.pgsql.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.pgsql.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Single(g.pgsql.Insert().AppendData(items.First()).ExecuteInserted()); + Assert.Equal(10, g.pgsql.Insert().AppendData(items).ExecuteInserted().Count); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.pgsql.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + + var t1 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t2 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.pgsql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new + { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.pgsql.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.pgsql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.pgsql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.pgsql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.pgsql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.pgsql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.pgsql.Select().ToList(); + var testGuidId6 = g.pgsql.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" INNER JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" INNER JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" INNER JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.InnerJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" RIGHT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" RIGHT JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" RIGHT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.RightJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE ((a.\"id\" = 10 AND a.\"id\" > 10 OR a.\"clicks\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10) AND (a.\"clicks\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle' AND a__Type.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"name\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b WHERE (b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b WHERE (b.\"name\" = 'typeTitle' AND b.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeparentinfo\" c WHERE (c.\"name\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c WHERE (a.\"id\" = 10 AND c.\"name\" = 'xxx') AND (b.\"parentid\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = @id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE ((a.\"id\" = 10 AND a.\"id\" > 10 OR a.\"clicks\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10) AND (a.\"clicks\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle' AND a__Type.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"name\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c WHERE (a.\"id\" = 10 AND c.\"name\" = 'xxx') AND (b.\"parentid\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = @id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.pgsql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.pgsql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + } + [Fact] + public void Min() + { + } + [Fact] + public void Max() + { + } + [Fact] + public void Avg() + { + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON b.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoAsTable\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfoAsTable\" c ON b.\"parentid\" = c.\"id\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.pgsql.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.pgsql.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.pgsql.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.pgsql.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.pgsql.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.pgsql.Insert(model4s).ExecuteAffrows()); + + var t0 = g.pgsql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.pgsql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.pgsql.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.pgsql.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.pgsql.Insert(model1).ExecuteIdentity(); + + var t1 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.pgsql.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.pgsql.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.pgsql.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.pgsql.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.pgsql.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.pgsql.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.pgsql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.pgsql.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.pgsql.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.pgsql.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.pgsql.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.pgsql.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.pgsql.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.pgsql.Insert(song3).ExecuteIdentity(); + + g.pgsql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.pgsql.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index d1e96cc0..8d26b835 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -3,125 +3,139 @@ using System; using System.Collections.Generic; using Xunit; -namespace FreeSql.Tests.PostgreSQL { - public class PostgreSQLUpdateTest { - IUpdate update => g.pgsql.Update(); +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLUpdateTest + { + IUpdate update => g.pgsql.Update(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - - [Fact] - public void Dywhere() { - Assert.Null(g.pgsql.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); - } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void SetSource() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = @p_0, \"title\" = @p_1, \"createtime\" = @p_2 WHERE (\"id\" = 1)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(g.pgsql.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = @p_0, \"title\" = @p_1, \"createtime\" = @p_2 WHERE (\"id\" = 1)", sql); - sql = update.SetSource(items).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = CASE \"id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"title\" = CASE \"id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"createtime\" = CASE \"id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = CASE \"id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = CASE \"id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"title\" = CASE \"id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"createtime\" = CASE \"id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"createtime\" = @p_0 WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void IgnoreColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = @p_0 WHERE (\"id\" = 1)", sql); - } - [Fact] - public void UpdateColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = @p_0 WHERE (\"id\" = 1)", sql); - } - [Fact] - public void Set() { - var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = @p_0 WHERE (\"id\" = 1)", sql); + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = CASE \"id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = @p_0, \"createtime\" = @p_1 WHERE (\"id\" = 1)", sql); + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"createtime\" = @p_0 WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = @p_0 WHERE (\"id\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = @p_0 WHERE (\"id\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = @p_0 WHERE (\"id\" = 1)", sql); - sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = coalesce(\"clicks\", 0) * 10 / 1 WHERE (\"id\" = 1)", sql); + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = @p_0, \"createtime\" = @p_1 WHERE (\"id\" = 1)", sql); - sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = (\"id\" - 10) WHERE (\"id\" = 1)", sql); + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = coalesce(\"clicks\", 0) * 10 / 1 WHERE (\"id\" = 1)", sql); - int incrv = 10; - sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = coalesce(\"clicks\", 0) * 10 / 1 WHERE (\"id\" = 1)", sql); + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = (\"id\" - 10) WHERE (\"id\" = 1)", sql); - sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = (\"id\" - 10) WHERE (\"id\" = 1)", sql); + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = coalesce(\"clicks\", 0) * 10 / 1 WHERE (\"id\" = 1)", sql); - sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = \"clicks\" * 10 / 1 WHERE (\"id\" = 1)", sql); + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = (\"id\" - 10) WHERE (\"id\" = 1)", sql); - sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = 10 WHERE (\"id\" = 1)", sql); - } - [Fact] - public void SetRaw() { - var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + @incrClick WHERE (\"id\" = 1)", sql); - } - [Fact] - public void Where() { - var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" = 1)", sql); + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = \"clicks\" * 10 / 1 WHERE (\"id\" = 1)", sql); - sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (id = @id)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = 10 WHERE (\"id\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + @incrClick WHERE (\"id\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" = 1)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" = 1)", sql); + sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (id = @id)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" = 1)", sql); - } - [Fact] - public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteUpdated() { + } + [Fact] + public void ExecuteAffrows() + { - } + } + [Fact] + public void ExecuteUpdated() + { - [Fact] - public void AsTable() { - Assert.Null(g.pgsql.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - } - } + } + + [Fact] + public void AsTable() + { + Assert.Null(g.pgsql.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs index 564d592c..73804ba1 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs @@ -2,1561 +2,1595 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.PostgreSQLMapType { - public class BoolNullableTest { - class BoolNullableMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool))] - public bool? tobool { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool? tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool? tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool? toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool? toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool? toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool? tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool? tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool? tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool? tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool? tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool? toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool? toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool? touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool? touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool? toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool? toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool? tostring { get; set; } = true; - } - [Fact] - public void Bool() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item = new BoolNullableMap { tobool = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item = new BoolNullableMap { tobool = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update all - item.tobool = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item.tobool = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item.tobool = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item = new BoolNullableMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item = new BoolNullableMap { tosbyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item.tosbyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item.tosbytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item = new BoolNullableMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item = new BoolNullableMap { toshort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item.toshort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item.toshortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item = new BoolNullableMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item = new BoolNullableMap { toint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item.toint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item = new BoolNullableMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item = new BoolNullableMap { tointnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item.tointnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item = new BoolNullableMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item = new BoolNullableMap { tolong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item.tolong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item.tolongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item = new BoolNullableMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item = new BoolNullableMap { tobyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item.tobyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item.tobytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item = new BoolNullableMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item = new BoolNullableMap { toushort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item.toushort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item.toushortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item = new BoolNullableMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item = new BoolNullableMap { touint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item.touint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item = new BoolNullableMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item = new BoolNullableMap { touintnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item.touintnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item = new BoolNullableMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item = new BoolNullableMap { toulong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item.toulong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item.toulongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.pgsql; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item = new BoolNullableMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item = new BoolNullableMap { tostring = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item.tostring = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.PostgreSQLMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs index 23d48807..37ce2ca4 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs @@ -2,1095 +2,1129 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.PostgreSQLMapType { - public class BoolTest { - - class BoolMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool?))] - public bool toboolnullable { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool tostring { get; set; } = true; - } - - [Fact] - public void BoolNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item = new BoolMap { toboolnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update all - item.toboolnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item.toboolnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toboolnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toboolnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item = new BoolMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item = new BoolMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item = new BoolMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item = new BoolMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item = new BoolMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item = new BoolMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item = new BoolMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item = new BoolMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item = new BoolMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item = new BoolMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item = new BoolMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item = new BoolMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item = new BoolMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item = new BoolMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item = new BoolMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item = new BoolMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.pgsql; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item = new BoolMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.PostgreSQLMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/EnumTest.cs index 05e7d229..8ecd87a7 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/EnumTest.cs @@ -3,252 +3,259 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.PostgreSQLMapType { - public class EnumTest { - class EnumTestMap { - public Guid id { get; set; } +namespace FreeSql.Tests.PostgreSQLMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(int))] - public ToStringMapEnum enum_to_int { get; set; } - [Column(MapType = typeof(int?))] - public ToStringMapEnum? enumnullable_to_int { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void EnumToString() { - //insert - var orm = g.pgsql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToString() { - //insert - var orm = g.pgsql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void EnumToInt() { - //insert - var orm = g.pgsql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + [Fact] + public void EnumToInt() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //update all - item.enum_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - item.enum_to_int = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToInt() { - //insert - var orm = g.pgsql; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); - //update all - item.enumnullable_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); - item.enumnullable_to_int = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/JTokenTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/JTokenTest.cs index ec3f4465..6a8fb1cf 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/JTokenTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/JTokenTest.cs @@ -4,421 +4,431 @@ using System; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQLMapType { - public class JTokenTest { - class JTokenTestMap { - public Guid id { get; set; } +namespace FreeSql.Tests.PostgreSQLMapType +{ + public class JTokenTest + { + class JTokenTestMap + { + public Guid id { get; set; } - [Column(MapType = typeof(JToken))] - public string string_to_jtoken { get; set; } - [Column(MapType = typeof(JArray))] - public string string_to_jarray { get; set; } - [Column(MapType = typeof(JObject))] - public string string_to_jobject { get; set; } + [Column(MapType = typeof(JToken))] + public string string_to_jtoken { get; set; } + [Column(MapType = typeof(JArray))] + public string string_to_jarray { get; set; } + [Column(MapType = typeof(JObject))] + public string string_to_jobject { get; set; } - [Column(MapType = typeof(string))] - public JToken jtoken_to_string { get; set; } - [Column(MapType = typeof(string))] - public JArray jarray_to_string { get; set; } - [Column(MapType = typeof(string))] - public JObject jobject_to_string { get; set; } - } - [Fact] - public void JTokenWithObjectToString() { - //insert - var orm = g.pgsql; - var item = new JTokenTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jtoken_to_string); + [Column(MapType = typeof(string))] + public JToken jtoken_to_string { get; set; } + [Column(MapType = typeof(string))] + public JArray jarray_to_string { get; set; } + [Column(MapType = typeof(string))] + public JObject jobject_to_string { get; set; } + } + [Fact] + public void JTokenWithObjectToString() + { + //insert + var orm = g.pgsql; + var item = new JTokenTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jtoken_to_string); - var json = JToken.FromObject(new { test1 = 1, test2 = "222" }); - item = new JTokenTestMap { jtoken_to_string = json }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jtoken_to_string); + var json = JToken.FromObject(new { test1 = 1, test2 = "222" }); + item = new JTokenTestMap { jtoken_to_string = json }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jtoken_to_string); - //update - json = JToken.FromObject(new { test2 = 33, test3 = "333" }); - item.jtoken_to_string = json; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jtoken_to_string); + //update + json = JToken.FromObject(new { test2 = 33, test3 = "333" }); + item.jtoken_to_string = json; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jtoken_to_string); - item.jtoken_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == json).First()); - find = orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jtoken_to_string); + item.jtoken_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == json).First()); + find = orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jtoken_to_string); - //update set - json = JToken.FromObject(new { testa = 455, test31 = "666" }); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jtoken_to_string, json).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jtoken_to_string); + //update set + json = JToken.FromObject(new { testa = 455, test31 = "666" }); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jtoken_to_string, json).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jtoken_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jtoken_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == json).First()); - find = orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jtoken_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jtoken_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == json).First()); + find = orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jtoken_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.jtoken_to_string == json).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.jtoken_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void JTokenWithArrayToString() { - //insert - var orm = g.pgsql; - var item = new JTokenTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jtoken_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.jtoken_to_string == json).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.jtoken_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void JTokenWithArrayToString() + { + //insert + var orm = g.pgsql; + var item = new JTokenTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jtoken_to_string); - var json = JArray.FromObject(new[] { "a", "b" }); - item = new JTokenTestMap { jtoken_to_string = json }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jtoken_to_string); + var json = JArray.FromObject(new[] { "a", "b" }); + item = new JTokenTestMap { jtoken_to_string = json }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jtoken_to_string); - //update - json = JArray.FromObject(new[] { "333", "zzz" }); - item.jtoken_to_string = json; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jtoken_to_string); + //update + json = JArray.FromObject(new[] { "333", "zzz" }); + item.jtoken_to_string = json; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jtoken_to_string); - item.jtoken_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == json).First()); - find = orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jtoken_to_string); + item.jtoken_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == json).First()); + find = orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jtoken_to_string); - //update set - json = JArray.FromObject(new[] { "zxzz", "sdfsdf" }); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jtoken_to_string, json).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jtoken_to_string); + //update set + json = JArray.FromObject(new[] { "zxzz", "sdfsdf" }); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jtoken_to_string, json).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jtoken_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jtoken_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == json).First()); - find = orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jtoken_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jtoken_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == json).First()); + find = orm.Select().Where(a => a.id == item.id && a.jtoken_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jtoken_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.jtoken_to_string == json).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.jtoken_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.jtoken_to_string == json).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.jtoken_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void JArrayToString() { - //insert - var orm = g.pgsql; - var item = new JTokenTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jarray_to_string); + [Fact] + public void JArrayToString() + { + //insert + var orm = g.pgsql; + var item = new JTokenTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jarray_to_string); - var json = JArray.FromObject(new[] { "a", "b" }); - item = new JTokenTestMap { jarray_to_string = json }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jarray_to_string); + var json = JArray.FromObject(new[] { "a", "b" }); + item = new JTokenTestMap { jarray_to_string = json }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jarray_to_string); - //update - json = JArray.FromObject(new[] { "333", "zzz" }); - item.jarray_to_string = json; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jarray_to_string); + //update + json = JArray.FromObject(new[] { "333", "zzz" }); + item.jarray_to_string = json; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jarray_to_string); - item.jarray_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.jarray_to_string == json).First()); - find = orm.Select().Where(a => a.id == item.id && a.jarray_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jarray_to_string); + item.jarray_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.jarray_to_string == json).First()); + find = orm.Select().Where(a => a.id == item.id && a.jarray_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jarray_to_string); - //update set - json = JArray.FromObject(new[] { "zxzz", "sdfsdf" }); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jarray_to_string, json).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jarray_to_string); + //update set + json = JArray.FromObject(new[] { "zxzz", "sdfsdf" }); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jarray_to_string, json).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jarray_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jarray_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.jarray_to_string == json).First()); - find = orm.Select().Where(a => a.id == item.id && a.jarray_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jarray_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jarray_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.jarray_to_string == json).First()); + find = orm.Select().Where(a => a.id == item.id && a.jarray_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jarray_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.jarray_to_string == json).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.jarray_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void JObjectToString() { - //insert - var orm = g.pgsql; - var item = new JTokenTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jobject_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.jarray_to_string == json).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.jarray_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void JObjectToString() + { + //insert + var orm = g.pgsql; + var item = new JTokenTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jobject_to_string); - var json = JObject.FromObject(new { test1 = 1, test2 = "222" }); - item = new JTokenTestMap { jobject_to_string = json }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jobject_to_string); + var json = JObject.FromObject(new { test1 = 1, test2 = "222" }); + item = new JTokenTestMap { jobject_to_string = json }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jobject_to_string); - //update - json = JObject.FromObject(new { test2 = 33, test3 = "333" }); - item.jobject_to_string = json; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jobject_to_string); + //update + json = JObject.FromObject(new { test2 = 33, test3 = "333" }); + item.jobject_to_string = json; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jobject_to_string); - item.jobject_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.jobject_to_string == json).First()); - find = orm.Select().Where(a => a.id == item.id && a.jobject_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jobject_to_string); + item.jobject_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.jobject_to_string == json).First()); + find = orm.Select().Where(a => a.id == item.id && a.jobject_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jobject_to_string); - //update set - json = JObject.FromObject(new { testa = 455, test31 = "666" }); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jobject_to_string, json).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json, find.jobject_to_string); + //update set + json = JObject.FromObject(new { testa = 455, test31 = "666" }); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jobject_to_string, json).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json, find.jobject_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jobject_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.jobject_to_string == json).First()); - find = orm.Select().Where(a => a.id == item.id && a.jobject_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.jobject_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.jobject_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.jobject_to_string == json).First()); + find = orm.Select().Where(a => a.id == item.id && a.jobject_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.jobject_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.jobject_to_string == json).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.jobject_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.jobject_to_string == json).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.jobject_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void StringToJToken() { - //insert - var orm = g.pgsql; - var item = new JTokenTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jtoken); + [Fact] + public void StringToJToken() + { + //insert + var orm = g.pgsql; + var item = new JTokenTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jtoken); - var json = JToken.FromObject(new { test1 = 1, test2 = "222" }); - var whereJson = JToken.FromObject(new { test2 = "222" }); - item = new JTokenTestMap { string_to_jtoken = json.ToString() }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json["test2"], JToken.Parse(find.string_to_jtoken)["test2"]); + var json = JToken.FromObject(new { test1 = 1, test2 = "222" }); + var whereJson = JToken.FromObject(new { test2 = "222" }); + item = new JTokenTestMap { string_to_jtoken = json.ToString() }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json["test2"], JToken.Parse(find.string_to_jtoken)["test2"]); - //update - json = JToken.FromObject(new { test2 = 33, test3 = "333" }); - whereJson = JToken.FromObject(new { test3 = "333" }); - item.string_to_jtoken = json.ToString(); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json["test3"], JToken.Parse(find.string_to_jtoken)["test3"]); + //update + json = JToken.FromObject(new { test2 = 33, test3 = "333" }); + whereJson = JToken.FromObject(new { test3 = "333" }); + item.string_to_jtoken = json.ToString(); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json["test3"], JToken.Parse(find.string_to_jtoken)["test3"]); - item.string_to_jtoken = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First()); - find = orm.Select().Where(a => a.id == item.id && a.string_to_jtoken == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jtoken); + item.string_to_jtoken = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First()); + find = orm.Select().Where(a => a.id == item.id && a.string_to_jtoken == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jtoken); - //update set - json = JToken.FromObject(new { testa = 455, test31 = "666" }); - whereJson = JToken.FromObject(new { test31 = "666" }); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jtoken, json.ToString()).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json["test31"], JToken.Parse(find.string_to_jtoken)["test31"]); + //update set + json = JToken.FromObject(new { testa = 455, test31 = "666" }); + whereJson = JToken.FromObject(new { test31 = "666" }); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jtoken, json.ToString()).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json["test31"], JToken.Parse(find.string_to_jtoken)["test31"]); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jtoken, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First()); - find = orm.Select().Where(a => a.id == item.id && a.string_to_jtoken == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jtoken); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jtoken, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).First()); + find = orm.Select().Where(a => a.id == item.id && a.string_to_jtoken == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jtoken); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.string_to_jtoken == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void StringToJObject() { - //insert - var orm = g.pgsql; - var item = new JTokenTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jobject); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && JToken.Parse(a.string_to_jtoken).Contains(whereJson)).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.string_to_jtoken == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void StringToJObject() + { + //insert + var orm = g.pgsql; + var item = new JTokenTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jobject); - var json = JObject.FromObject(new { test1 = 1, test2 = "222" }); - item = new JTokenTestMap { string_to_jobject = json.ToString() }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test1")).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json["test2"], JObject.Parse(find.string_to_jobject)["test2"]); + var json = JObject.FromObject(new { test1 = 1, test2 = "222" }); + item = new JTokenTestMap { string_to_jobject = json.ToString() }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test1")).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json["test2"], JObject.Parse(find.string_to_jobject)["test2"]); - //update - json = JObject.FromObject(new { test2 = 33, test3 = "333" }); - item.string_to_jobject = json.ToString(); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test3")).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json["test3"], JObject.Parse(find.string_to_jobject)["test3"]); + //update + json = JObject.FromObject(new { test2 = 33, test3 = "333" }); + item.string_to_jobject = json.ToString(); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test3")).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json["test3"], JObject.Parse(find.string_to_jobject)["test3"]); - item.string_to_jobject = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test3")).First()); - find = orm.Select().Where(a => a.id == item.id && a.string_to_jobject == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jobject); + item.string_to_jobject = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test3")).First()); + find = orm.Select().Where(a => a.id == item.id && a.string_to_jobject == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jobject); - //update set - json = JObject.FromObject(new { testa = 455, test31 = "666" }); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jobject, json.ToString()).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test31")).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json["test31"], JObject.Parse(find.string_to_jobject)["test31"]); + //update set + json = JObject.FromObject(new { testa = 455, test31 = "666" }); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jobject, json.ToString()).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test31")).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json["test31"], JObject.Parse(find.string_to_jobject)["test31"]); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jobject, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test31")).First()); - find = orm.Select().Where(a => a.id == item.id && a.string_to_jobject == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jobject); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jobject, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test31")).First()); + find = orm.Select().Where(a => a.id == item.id && a.string_to_jobject == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jobject); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test31")).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.string_to_jobject == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void StringToJArray() { - //insert - var orm = g.pgsql; - var item = new JTokenTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jarray); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && JObject.Parse(a.string_to_jobject).ContainsKey("test31")).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.string_to_jobject == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void StringToJArray() + { + //insert + var orm = g.pgsql; + var item = new JTokenTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jarray); - var json = JArray.FromObject(new[] { "aa", "bb" }); - item = new JTokenTestMap { string_to_jarray = json.ToString() }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("bb")).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json[1], JArray.Parse(find.string_to_jarray)[1]); + var json = JArray.FromObject(new[] { "aa", "bb" }); + item = new JTokenTestMap { string_to_jarray = json.ToString() }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("bb")).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json[1], JArray.Parse(find.string_to_jarray)[1]); - //update - json = JArray.FromObject(new[] { "aa", "dddd" }); - item.string_to_jarray = json.ToString(); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("dddd")).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json[1], JArray.Parse(find.string_to_jarray)[1]); + //update + json = JArray.FromObject(new[] { "aa", "dddd" }); + item.string_to_jarray = json.ToString(); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("dddd")).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json[1], JArray.Parse(find.string_to_jarray)[1]); - item.string_to_jarray = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("dddd")).First()); - find = orm.Select().Where(a => a.id == item.id && a.string_to_jarray == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jarray); + item.string_to_jarray = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("dddd")).First()); + find = orm.Select().Where(a => a.id == item.id && a.string_to_jarray == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jarray); - //update set - json = JArray.FromObject(new[] { "aa", "bdfdfb" }); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jarray, json.ToString()).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("bdfdfb")).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(json[1], JArray.Parse(find.string_to_jarray)[1]); + //update set + json = JArray.FromObject(new[] { "aa", "bdfdfb" }); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jarray, json.ToString()).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("bdfdfb")).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(json[1], JArray.Parse(find.string_to_jarray)[1]); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jarray, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("bdfdfb")).First()); - find = orm.Select().Where(a => a.id == item.id && a.string_to_jarray == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.string_to_jarray); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.string_to_jarray, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("bdfdfb")).First()); + find = orm.Select().Where(a => a.id == item.id && a.string_to_jarray == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.string_to_jarray); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("bdfdfb")).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.string_to_jarray == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && JArray.Parse(a.string_to_jarray).Contains("bdfdfb")).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.string_to_jarray == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/ToStringTest.cs index 814a7acf..56888345 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/ToStringTest.cs @@ -3,555 +3,568 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.PostgreSQLMapType { - public class ToStringTest { - class ToStringMap { - public Guid id { get; set; } +namespace FreeSql.Tests.PostgreSQLMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan timespan_to_string { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan? timespannullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime datetime_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime? datetimenullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid guid_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid? guidnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger biginteger_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger? bigintegernullable_to_string { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void Enum1() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullable() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigInteger1() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(0, find.biginteger_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); - item = new ToStringMap { biginteger_to_string = 100 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(100, find.biginteger_to_string); + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); - //update all - item.biginteger_to_string = 200; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(200, find.biginteger_to_string); + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); - item.biginteger_to_string = 205; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(205, find.biginteger_to_string); + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(522, find.biginteger_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(10005, find.biginteger_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigIntegerNullable() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - item = new ToStringMap { bigintegernullable_to_string = 101 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(101, find.bigintegernullable_to_string); + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); - //update all - item.bigintegernullable_to_string = 2004; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(2004, find.bigintegernullable_to_string); + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); - item.bigintegernullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(998, find.bigintegernullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.bigintegernullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpan1() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); - item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); - //update all - item.timespan_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpanNullable() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); - //update all - item.timespannullable_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); - item.timespannullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.timespannullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTime1() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.MinValue, find.datetime_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); - item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); - //update all - item.datetime_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTimeNullable() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); - //update all - item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); - item.datetimenullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.datetimenullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void Guid1() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(Guid.Empty, find.guid_to_string); + [Fact] + public void Guid1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guid_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update all - newid = Guid.NewGuid(); - item.guid_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guid_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void GuidNullable() { - //insert - var orm = g.pgsql; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guidnullable_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - //update all - newid = Guid.NewGuid(); - item.guidnullable_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - item.guidnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guidnullable_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.guidnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs index a2da682d..7d8f4d28 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs @@ -2,56 +2,67 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.PostgreSQL { - public class PostgreSQLAdoTest { - [Fact] - public void Pool() { - var t1 = g.pgsql.Ado.MasterPool.StatisticsFullily; - } +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.pgsql.Ado.MasterPool.StatisticsFullily; + } - [Fact] - public void SlavePools() { - var t2 = g.pgsql.Ado.SlavePools.Count; - } + [Fact] + public void SlavePools() + { + var t2 = g.pgsql.Ado.SlavePools.Count; + } - [Fact] - public void ExecuteReader() { - - } - [Fact] - public void ExecuteArray() { - - } - [Fact] - public void ExecuteNonQuery() { - - } - [Fact] - public void ExecuteScalar() { - - } + [Fact] + public void ExecuteReader() + { - [Fact] - public void Query() { + } + [Fact] + public void ExecuteArray() + { - g.pgsql.CodeFirst.SyncStructure(); - var t3 = g.pgsql.Ado.Query("select * from xxx"); + } + [Fact] + public void ExecuteNonQuery() + { - var t4 = g.pgsql.Ado.Query<(int, string, string)>("select * from xxx"); + } + [Fact] + public void ExecuteScalar() + { - var t5 = g.pgsql.Ado.Query("select * from xxx"); - } + } - [Fact] - public void QueryMultipline() { - g.pgsql.CodeFirst.SyncStructure(); - var t3 = g.pgsql.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); - } + [Fact] + public void Query() + { - class xxx { - public int Id { get; set; } - public string Path { get; set; } - public string Title2 { get; set; } - } - } + g.pgsql.CodeFirst.SyncStructure(); + var t3 = g.pgsql.Ado.Query("select * from xxx"); + + var t4 = g.pgsql.Ado.Query<(int, string, string)>("select * from xxx"); + + var t5 = g.pgsql.Ado.Query("select * from xxx"); + } + + [Fact] + public void QueryMultipline() + { + g.pgsql.CodeFirst.SyncStructure(); + var t3 = g.pgsql.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index 423dd33c..d8471901 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -13,491 +13,504 @@ using System.Net.NetworkInformation; using System.Text; using Xunit; -namespace FreeSql.Tests.PostgreSQL { - public class PostgreSQLCodeFirstTest { +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLCodeFirstTest + { - [Fact] - public void ı_ֶ() { - var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements<ı>(); - g.pgsql.CodeFirst.SyncStructure<ı>(); + [Fact] + public void ı_ֶ() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements<ı>(); + g.pgsql.CodeFirst.SyncStructure<ı>(); - var item = new ı { - = "Ա", - ʱ = DateTime.Now - }; - Assert.Equal(1, g.pgsql.Insert<ı>().AppendData(item).ExecuteAffrows()); - Assert.NotEqual(Guid.Empty, item.); - var item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); - Assert.NotNull(item2); - Assert.Equal(item., item2.); - Assert.Equal(item., item2.); - } - class ı { - [Column(IsPrimary = true)] - public Guid { get; set; } + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.pgsql.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } - public string { get; set; } + public string { get; set; } - public DateTime ʱ { get; set; } - } + public DateTime ʱ { get; set; } + } - [Fact] - public void AddUniques() { - var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); - g.pgsql.CodeFirst.SyncStructure(); - } - [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - class AddUniquesInfo { - public Guid id { get; set; } - [Column(Unique = "uk_phone")] - public string phone { get; set; } + [Fact] + public void AddUniques() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] - public string group { get; set; } - [Column(Unique = "uk_group_index")] - public int index { get; set; } - [Column(Unique = "uk_group_index22")] - public string index22 { get; set; } - } + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } - [Fact] - public void AddField() { - var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); - g.pgsql.Select(); + [Fact] + public void AddField() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.Select(); - var id = g.pgsql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); - } + var id = g.pgsql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } - [Table(Name = "ccc.TopicAddField", OldName = "TopicAddField")] - public class TopicAddField { - [Column(IsIdentity = true)] - public int Id { get; set; } + [Table(Name = "ccc.TopicAddField", OldName = "TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } - public string name { get; set; } = "xxx"; + public string name { get; set; } = "xxx"; - public int clicks { get; set; } = 10; - //public int name { get; set; } = 3000; + public int clicks { get; set; } = 10; + //public int name { get; set; } = 3000; - //[Column(DbType = "varchar(200) not null", OldName = "title")] - //public string title222 { get; set; } = "333"; + //[Column(DbType = "varchar(200) not null", OldName = "title")] + //public string title222 { get; set; } = "333"; - //[Column(DbType = "varchar(200) not null")] - //public string title222333 { get; set; } = "xxx"; + //[Column(DbType = "varchar(200) not null")] + //public string title222333 { get; set; } = "xxx"; - //[Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] - //public string titleaaa { get; set; } = "fsdf"; + //[Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] + //public string titleaaa { get; set; } = "fsdf"; - [Column(IsIgnore = true)] - public DateTime ct { get; set; } = DateTime.Now; - } + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } - [Fact] - public void GetComparisonDDLStatements() { + [Fact] + public void GetComparisonDDLStatements() + { - var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); - g.pgsql.Select(); - } + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.Select(); + } - IInsert insert => g.pgsql.Insert(); - ISelect select => g.pgsql.Select(); + IInsert insert => g.pgsql.Insert(); + ISelect select => g.pgsql.Select(); - [Fact] - public void CurdAllField() { - NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); + [Fact] + public void CurdAllField() + { + NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); - var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql(); - var sql2 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql(); + var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql(); + var sql2 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql(); - var item = new TableAllType { }; - item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); - var newitem = select.Where(a => a.Id == item.Id).ToOne(); + var newitem = select.Where(a => a.Id == item.Id).ToOne(); - var item2 = new TableAllType { - testFieldBitArray = new BitArray(Encoding.UTF8.GetBytes("")), - testFieldBitArrayArray = new[] { new BitArray(Encoding.UTF8.GetBytes("й")), new BitArray(Encoding.UTF8.GetBytes("")) }, - testFieldBool = true, - testFieldBoolArray = new[] { true, true, false, false }, - testFieldBoolArrayNullable = new bool?[] { true, true, null, false, false }, - testFieldBoolNullable = true, - testFieldByte = byte.MaxValue, - testFieldByteArray = new byte[] { 0, 1, 2, 3, 4, 5, 6 }, - testFieldByteArrayNullable = new byte?[] { 0, 1, 2, 3, null, 4, 5, 6 }, - testFieldByteNullable = byte.MinValue, - testFieldBytes = Encoding.UTF8.GetBytes("й"), - testFieldBytesArray = new[] { Encoding.UTF8.GetBytes("й"), Encoding.UTF8.GetBytes("й") }, - testFieldCidr = (IPAddress.Parse("10.0.0.0"), 8), - testFieldCidrArray = new[] { (IPAddress.Parse("10.0.0.0"), 8), (IPAddress.Parse("192.168.0.0"), 16) }, - testFieldCidrArrayNullable = new (IPAddress, int)?[] { (IPAddress.Parse("10.0.0.0"), 8), null, (IPAddress.Parse("192.168.0.0"), 16) }, - testFieldCidrNullable = (IPAddress.Parse("192.168.0.0"), 16), - testFieldDateTime = DateTime.Now, - testFieldDateTimeArray = new[] { DateTime.Now, DateTime.Now.AddHours(2) }, - testFieldDateTimeArrayNullable = new DateTime?[] { DateTime.Now, null, DateTime.Now.AddHours(2) }, - testFieldDateTimeNullable = DateTime.Now.AddDays(-1), - testFieldDecimal = 999.99M, - testFieldDecimalArray = new[] { 999.91M, 999.92M, 999.93M }, - testFieldDecimalArrayNullable = new decimal?[] { 998.11M, 998.12M, 998.13M }, - testFieldDecimalNullable = 111.11M, - testFieldDouble = 888.88, - testFieldDoubleArray = new[] { 888.81, 888.82, 888.83 }, - testFieldDoubleArrayNullable = new double?[] { 888.11, 888.12, null, 888.13 }, - testFieldDoubleNullable = 222.22, - testFieldEnum1 = TableAllTypeEnumType1.e3, - testFieldEnum1Array = new[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, TableAllTypeEnumType1.e1 }, - testFieldEnum1ArrayNullable = new TableAllTypeEnumType1?[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, null, TableAllTypeEnumType1.e1 }, - testFieldEnum1Nullable = TableAllTypeEnumType1.e2, - testFieldEnum2 = TableAllTypeEnumType2.f2, - testFieldEnum2Array = new[] { TableAllTypeEnumType2.f3, TableAllTypeEnumType2.f1 }, - testFieldEnum2ArrayNullable = new TableAllTypeEnumType2?[] { TableAllTypeEnumType2.f3, null, TableAllTypeEnumType2.f1 }, - testFieldEnum2Nullable = TableAllTypeEnumType2.f3, - testFieldFloat = 777.77F, - testFieldFloatArray = new[] { 777.71F, 777.72F, 777.73F }, - testFieldFloatArrayNullable = new float?[] { 777.71F, 777.72F, null, 777.73F }, - testFieldFloatNullable = 333.33F, - testFieldGuid = Guid.NewGuid(), - testFieldGuidArray = new[] { Guid.NewGuid(), Guid.NewGuid() }, - testFieldGuidArrayNullable = new Guid?[] { Guid.NewGuid(), null, Guid.NewGuid() }, - testFieldGuidNullable = Guid.NewGuid(), - testFieldHStore = new Dictionary { { "111", "value111" }, { "222", "value222" }, { "333", "value333" } }, - testFieldHStoreArray = new[] { new Dictionary { { "111", "value111" }, { "222", "value222" }, { "333", "value333" } }, new Dictionary { { "444", "value444" }, { "555", "value555" }, { "666", "value666" } } }, - testFieldInet = IPAddress.Parse("192.168.1.1"), - testFieldInetArray = new[] { IPAddress.Parse("192.168.1.1"), IPAddress.Parse("192.168.1.2"), IPAddress.Parse("192.168.1.3") }, - testFieldInt = int.MaxValue, - testFieldInt4range = new NpgsqlRange(10, 20), - testFieldInt4rangeArray = new[] { new NpgsqlRange(10, 20), new NpgsqlRange(50, 100), new NpgsqlRange(200, 300) }, - testFieldInt4rangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(10, 20), new NpgsqlRange(50, 100), null, new NpgsqlRange(200, 300) }, - testFieldInt4rangeNullable = new NpgsqlRange(100, 200), - testFieldInt8range = new NpgsqlRange(100, 200), - testFieldInt8rangeArray = new[] { new NpgsqlRange(100, 200), new NpgsqlRange(500, 1000), new NpgsqlRange(2000, 3000) }, - testFieldInt8rangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(100, 200), new NpgsqlRange(500, 1000), null, new NpgsqlRange(2000, 3000) }, - testFieldInt8rangeNullable = new NpgsqlRange(1000, 2000), - testFieldIntArray = new[] { 1, 2, 3, 4, 5 }, - testFieldIntArrayNullable = new int?[] { 1, 2, 3, null, 4, 5 }, - testFieldIntNullable = int.MinValue, - testFieldJArray = JArray.Parse("[1,2,3,4,5]"), - testFieldJArrayArray = new[] { JArray.Parse("[1,2,3,4,5]"), JArray.Parse("[10,20,30,40,50]") }, - testFieldJObject = JObject.Parse("{ \"a\":1, \"b\":2, \"c\":3 }"), - testFieldJObjectArray = new[] { JObject.Parse("{ \"a\":1, \"b\":2, \"c\":3 }"), JObject.Parse("{ \"a\":10, \"b\":20, \"c\":30 }") }, - testFieldJToken = JToken.Parse("{ \"a\":1, \"b\":2, \"c\":3, \"d\":[1,2,3,4,5] }"), - testFieldJTokenArray = new[] { JToken.Parse("{ \"a\":1, \"b\":2, \"c\":3, \"d\":[1,2,3,4,5] }"), JToken.Parse("{ \"a\":10, \"b\":20, \"c\":30, \"d\":[10,20,30,40,50] }") }, - testFieldLong = long.MaxValue, - testFieldLongArray = new long[] { 10, 20, 30, 40, 50 }, - testFieldMacaddr = PhysicalAddress.Parse("A1-A2-CD-DD-FF-02"), - testFieldMacaddrArray = new[] { PhysicalAddress.Parse("A1-A2-CD-DD-FF-02"), PhysicalAddress.Parse("A2-22-22-22-22-02") }, - testFieldNpgsqlBox = new NpgsqlBox(10, 100, 100, 10), - testFieldNpgsqlBoxArray = new[] { new NpgsqlBox(10, 100, 100, 10), new NpgsqlBox(200, 2000, 2000, 200) }, - testFieldNpgsqlBoxArrayNullable = new NpgsqlBox?[] { new NpgsqlBox(10, 100, 100, 10), null, new NpgsqlBox(200, 2000, 2000, 200) }, - testFieldNpgsqlBoxNullable = new NpgsqlBox(200, 2000, 2000, 200), - testFieldNpgsqlCircle = new NpgsqlCircle(50, 50, 100), - testFieldNpgsqlCircleArray = new[] { new NpgsqlCircle(50, 50, 100), new NpgsqlCircle(80, 80, 100) }, - testFieldNpgsqlCircleArrayNullable = new NpgsqlCircle?[] { new NpgsqlCircle(50, 50, 100), null, new NpgsqlCircle(80, 80, 100) }, - testFieldNpgsqlCircleNullable = new NpgsqlCircle(80, 80, 100), - testFieldNpgsqlLine = new NpgsqlLine(30, 30, 30), - testFieldNpgsqlLineArray = new[] { new NpgsqlLine(30, 30, 30), new NpgsqlLine(35, 35, 35) }, - testFieldNpgsqlLineArrayNullable = new NpgsqlLine?[] { new NpgsqlLine(30, 30, 30), null, new NpgsqlLine(35, 35, 35) }, - testFieldNpgsqlLineNullable = new NpgsqlLine(60, 60, 60), - testFieldNpgsqlLSeg = new NpgsqlLSeg(80, 10, 800, 20), - testFieldNpgsqlLSegArray = new[] { new NpgsqlLSeg(80, 10, 800, 20), new NpgsqlLSeg(180, 20, 260, 50) }, - testFieldNpgsqlLSegArrayNullable = new NpgsqlLSeg?[] { new NpgsqlLSeg(80, 10, 800, 20), null, new NpgsqlLSeg(180, 20, 260, 50) }, - testFieldNpgsqlLSegNullable = new NpgsqlLSeg(180, 20, 260, 50), - testFieldNpgsqlPath = new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), - testFieldNpgsqlPathArray = new[] { new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)) }, - testFieldNpgsqlPathArrayNullable = new NpgsqlPath?[] { new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), null, new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)) }, - testFieldNpgsqlPathNullable = new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)), - testFieldNpgsqlPoint = new NpgsqlPoint(666, 666), - testFieldNpgsqlPointArray = new[] { new NpgsqlPoint(666, 666), new NpgsqlPoint(888, 888) }, - testFieldNpgsqlPointArrayNullable = new NpgsqlPoint?[] { new NpgsqlPoint(666, 666), null, new NpgsqlPoint(888, 888) }, - testFieldNpgsqlPointNullable = new NpgsqlPoint(888, 888), - testFieldNpgsqlPolygon = new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), - testFieldNpgsqlPolygonArray = new[] { new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)) }, - testFieldNpgsqlPolygonArrayNullable = new NpgsqlPolygon?[] { new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), null, new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)) }, - testFieldNpgsqlPolygonNullable = new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)), - testFieldNumrange = new NpgsqlRange(888.88M, 999.99M), - testFieldNumrangeArray = new[] { new NpgsqlRange(888.88M, 999.99M), new NpgsqlRange(18888.88M, 19998.99M) }, - testFieldNumrangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(888.88M, 999.99M), null, new NpgsqlRange(18888.88M, 19998.99M) }, - testFieldNumrangeNullable = new NpgsqlRange(18888.88M, 19998.99M), - testFieldPostgisGeometry = new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), - testFieldPostgisGeometryArray = new PostgisGeometry[] { - new PostgisPoint(555,551), - new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), - new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), - new PostgisMultiPolygon(new []{ - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) - }) - }, - testFieldPostgisGeometryCollection = new PostgisGeometryCollection(new PostgisGeometry[] { - new PostgisPoint(555,551), - new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), - new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), - new PostgisMultiPolygon(new []{ - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) - }) - }), - testFieldPostgisGeometryCollectionArray = new[] { - new PostgisGeometryCollection(new PostgisGeometry[] { - new PostgisPoint(555,551), - new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), - new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), - new PostgisMultiPolygon(new []{ - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) - }) - }),new PostgisGeometryCollection(new PostgisGeometry[] { - new PostgisPoint(555,551), - new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), - new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), - new PostgisMultiPolygon(new []{ - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) - }) - }) - }, - testFieldPostgisLineString = new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), - testFieldPostgisLineStringArray = new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 220) }) }, - testFieldPostgisMultiPoint = new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), - testFieldPostgisMultiPointArray = new[] { new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), new PostgisMultiPoint(new[] { new Coordinate2D(120, 121), new Coordinate2D(1210, 1220) }) }, - testFieldPostgisPoint = new PostgisPoint(555, 551), - testFieldPostgisPointArray = new[] { new PostgisPoint(555, 551), new PostgisPoint(53355, 3551) }, - testFieldPostgisPolygon = new PostgisPolygon(new[] { new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - testFieldPostgisPolygonArray = new[]{ - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) - }, - testFieldPostgisPostgisMultiLineString = new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), - testFieldPostgisPostgisMultiLineStringArray = new[] { - new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), - new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 220) }) , new PostgisLineString(new[] { new Coordinate2D(820, 821), new Coordinate2D(800, 810) }) }) - }, - testFieldPostgisPostgisMultiPolygon = new PostgisMultiPolygon(new[]{ - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) - }), - testFieldPostgisPostgisMultiPolygonArray = new[] { - new PostgisMultiPolygon(new[]{ - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) - }), - new PostgisMultiPolygon(new[]{ - new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), - new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) - }) - }, - testFieldSByte = sbyte.MaxValue, - testFieldSByteArray = new sbyte[] { 1, 2, 3, 4, 5 }, - testFieldSByteArrayNullable = new sbyte?[] { 1, 2, 3, null, 4, 5 }, - testFieldSByteNullable = sbyte.MinValue, - testFieldShort = short.MaxValue, - testFieldShortArray = new short[] { 1, 2, 3, 4, 5 }, - testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 }, - testFieldShortNullable = short.MinValue, - testFieldString = "йString", - testFieldStringArray = new[] { "йString1", "йString2", null, "йString3" }, - testFieldTimeSpan = TimeSpan.FromDays(1), - testFieldTimeSpanArray = new[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }, - testFieldTimeSpanArrayNullable = new TimeSpan?[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), null, TimeSpan.FromSeconds(60) }, - testFieldTimeSpanNullable = TimeSpan.FromSeconds(90), - testFieldTsrange = new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), - testFieldTsrangeArray = new[] { new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)) }, - testFieldTsrangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), null, new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)) }, - testFieldTsrangeNullable = new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)), - testFieldUInt = uint.MaxValue, - testFieldUIntArray = new uint[] { 1, 2, 3, 4, 5 }, - testFieldUIntArrayNullable = new uint?[] { 1, 2, 3, null, 4, 5 }, - testFieldUIntNullable = uint.MinValue, - testFieldULong = ulong.MaxValue, - testFieldULongArray = new ulong[] { 10, 20, 30, 40, 50 }, - testFieldULongArrayNullable = new ulong?[] { 10, 20, 30, null, 40, 50 }, - testFieldULongNullable = ulong.MinValue, - testFieldUShort = ushort.MaxValue, - testFieldUShortArray = new ushort[] { 11, 12, 13, 14, 15 }, - testFieldUShortArrayNullable = new ushort?[] { 11, 12, 13, null, 14, 15 }, - testFieldUShortNullable = ushort.MinValue, - testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 }, - testFielLongNullable = long.MinValue - }; - var item3 = insert.AppendData(item2).ExecuteInserted().First(); - var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + var item2 = new TableAllType + { + testFieldBitArray = new BitArray(Encoding.UTF8.GetBytes("")), + testFieldBitArrayArray = new[] { new BitArray(Encoding.UTF8.GetBytes("й")), new BitArray(Encoding.UTF8.GetBytes("")) }, + testFieldBool = true, + testFieldBoolArray = new[] { true, true, false, false }, + testFieldBoolArrayNullable = new bool?[] { true, true, null, false, false }, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + testFieldByteArray = new byte[] { 0, 1, 2, 3, 4, 5, 6 }, + testFieldByteArrayNullable = new byte?[] { 0, 1, 2, 3, null, 4, 5, 6 }, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + testFieldBytesArray = new[] { Encoding.UTF8.GetBytes("й"), Encoding.UTF8.GetBytes("й") }, + testFieldCidr = (IPAddress.Parse("10.0.0.0"), 8), + testFieldCidrArray = new[] { (IPAddress.Parse("10.0.0.0"), 8), (IPAddress.Parse("192.168.0.0"), 16) }, + testFieldCidrArrayNullable = new (IPAddress, int)?[] { (IPAddress.Parse("10.0.0.0"), 8), null, (IPAddress.Parse("192.168.0.0"), 16) }, + testFieldCidrNullable = (IPAddress.Parse("192.168.0.0"), 16), + testFieldDateTime = DateTime.Now, + testFieldDateTimeArray = new[] { DateTime.Now, DateTime.Now.AddHours(2) }, + testFieldDateTimeArrayNullable = new DateTime?[] { DateTime.Now, null, DateTime.Now.AddHours(2) }, + testFieldDateTimeNullable = DateTime.Now.AddDays(-1), + testFieldDecimal = 999.99M, + testFieldDecimalArray = new[] { 999.91M, 999.92M, 999.93M }, + testFieldDecimalArrayNullable = new decimal?[] { 998.11M, 998.12M, 998.13M }, + testFieldDecimalNullable = 111.11M, + testFieldDouble = 888.88, + testFieldDoubleArray = new[] { 888.81, 888.82, 888.83 }, + testFieldDoubleArrayNullable = new double?[] { 888.11, 888.12, null, 888.13 }, + testFieldDoubleNullable = 222.22, + testFieldEnum1 = TableAllTypeEnumType1.e3, + testFieldEnum1Array = new[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, TableAllTypeEnumType1.e1 }, + testFieldEnum1ArrayNullable = new TableAllTypeEnumType1?[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, null, TableAllTypeEnumType1.e1 }, + testFieldEnum1Nullable = TableAllTypeEnumType1.e2, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Array = new[] { TableAllTypeEnumType2.f3, TableAllTypeEnumType2.f1 }, + testFieldEnum2ArrayNullable = new TableAllTypeEnumType2?[] { TableAllTypeEnumType2.f3, null, TableAllTypeEnumType2.f1 }, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 777.77F, + testFieldFloatArray = new[] { 777.71F, 777.72F, 777.73F }, + testFieldFloatArrayNullable = new float?[] { 777.71F, 777.72F, null, 777.73F }, + testFieldFloatNullable = 333.33F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidArray = new[] { Guid.NewGuid(), Guid.NewGuid() }, + testFieldGuidArrayNullable = new Guid?[] { Guid.NewGuid(), null, Guid.NewGuid() }, + testFieldGuidNullable = Guid.NewGuid(), + testFieldHStore = new Dictionary { { "111", "value111" }, { "222", "value222" }, { "333", "value333" } }, + testFieldHStoreArray = new[] { new Dictionary { { "111", "value111" }, { "222", "value222" }, { "333", "value333" } }, new Dictionary { { "444", "value444" }, { "555", "value555" }, { "666", "value666" } } }, + testFieldInet = IPAddress.Parse("192.168.1.1"), + testFieldInetArray = new[] { IPAddress.Parse("192.168.1.1"), IPAddress.Parse("192.168.1.2"), IPAddress.Parse("192.168.1.3") }, + testFieldInt = int.MaxValue, + testFieldInt4range = new NpgsqlRange(10, 20), + testFieldInt4rangeArray = new[] { new NpgsqlRange(10, 20), new NpgsqlRange(50, 100), new NpgsqlRange(200, 300) }, + testFieldInt4rangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(10, 20), new NpgsqlRange(50, 100), null, new NpgsqlRange(200, 300) }, + testFieldInt4rangeNullable = new NpgsqlRange(100, 200), + testFieldInt8range = new NpgsqlRange(100, 200), + testFieldInt8rangeArray = new[] { new NpgsqlRange(100, 200), new NpgsqlRange(500, 1000), new NpgsqlRange(2000, 3000) }, + testFieldInt8rangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(100, 200), new NpgsqlRange(500, 1000), null, new NpgsqlRange(2000, 3000) }, + testFieldInt8rangeNullable = new NpgsqlRange(1000, 2000), + testFieldIntArray = new[] { 1, 2, 3, 4, 5 }, + testFieldIntArrayNullable = new int?[] { 1, 2, 3, null, 4, 5 }, + testFieldIntNullable = int.MinValue, + testFieldJArray = JArray.Parse("[1,2,3,4,5]"), + testFieldJArrayArray = new[] { JArray.Parse("[1,2,3,4,5]"), JArray.Parse("[10,20,30,40,50]") }, + testFieldJObject = JObject.Parse("{ \"a\":1, \"b\":2, \"c\":3 }"), + testFieldJObjectArray = new[] { JObject.Parse("{ \"a\":1, \"b\":2, \"c\":3 }"), JObject.Parse("{ \"a\":10, \"b\":20, \"c\":30 }") }, + testFieldJToken = JToken.Parse("{ \"a\":1, \"b\":2, \"c\":3, \"d\":[1,2,3,4,5] }"), + testFieldJTokenArray = new[] { JToken.Parse("{ \"a\":1, \"b\":2, \"c\":3, \"d\":[1,2,3,4,5] }"), JToken.Parse("{ \"a\":10, \"b\":20, \"c\":30, \"d\":[10,20,30,40,50] }") }, + testFieldLong = long.MaxValue, + testFieldLongArray = new long[] { 10, 20, 30, 40, 50 }, + testFieldMacaddr = PhysicalAddress.Parse("A1-A2-CD-DD-FF-02"), + testFieldMacaddrArray = new[] { PhysicalAddress.Parse("A1-A2-CD-DD-FF-02"), PhysicalAddress.Parse("A2-22-22-22-22-02") }, + testFieldNpgsqlBox = new NpgsqlBox(10, 100, 100, 10), + testFieldNpgsqlBoxArray = new[] { new NpgsqlBox(10, 100, 100, 10), new NpgsqlBox(200, 2000, 2000, 200) }, + testFieldNpgsqlBoxArrayNullable = new NpgsqlBox?[] { new NpgsqlBox(10, 100, 100, 10), null, new NpgsqlBox(200, 2000, 2000, 200) }, + testFieldNpgsqlBoxNullable = new NpgsqlBox(200, 2000, 2000, 200), + testFieldNpgsqlCircle = new NpgsqlCircle(50, 50, 100), + testFieldNpgsqlCircleArray = new[] { new NpgsqlCircle(50, 50, 100), new NpgsqlCircle(80, 80, 100) }, + testFieldNpgsqlCircleArrayNullable = new NpgsqlCircle?[] { new NpgsqlCircle(50, 50, 100), null, new NpgsqlCircle(80, 80, 100) }, + testFieldNpgsqlCircleNullable = new NpgsqlCircle(80, 80, 100), + testFieldNpgsqlLine = new NpgsqlLine(30, 30, 30), + testFieldNpgsqlLineArray = new[] { new NpgsqlLine(30, 30, 30), new NpgsqlLine(35, 35, 35) }, + testFieldNpgsqlLineArrayNullable = new NpgsqlLine?[] { new NpgsqlLine(30, 30, 30), null, new NpgsqlLine(35, 35, 35) }, + testFieldNpgsqlLineNullable = new NpgsqlLine(60, 60, 60), + testFieldNpgsqlLSeg = new NpgsqlLSeg(80, 10, 800, 20), + testFieldNpgsqlLSegArray = new[] { new NpgsqlLSeg(80, 10, 800, 20), new NpgsqlLSeg(180, 20, 260, 50) }, + testFieldNpgsqlLSegArrayNullable = new NpgsqlLSeg?[] { new NpgsqlLSeg(80, 10, 800, 20), null, new NpgsqlLSeg(180, 20, 260, 50) }, + testFieldNpgsqlLSegNullable = new NpgsqlLSeg(180, 20, 260, 50), + testFieldNpgsqlPath = new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), + testFieldNpgsqlPathArray = new[] { new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)) }, + testFieldNpgsqlPathArrayNullable = new NpgsqlPath?[] { new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), null, new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)) }, + testFieldNpgsqlPathNullable = new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)), + testFieldNpgsqlPoint = new NpgsqlPoint(666, 666), + testFieldNpgsqlPointArray = new[] { new NpgsqlPoint(666, 666), new NpgsqlPoint(888, 888) }, + testFieldNpgsqlPointArrayNullable = new NpgsqlPoint?[] { new NpgsqlPoint(666, 666), null, new NpgsqlPoint(888, 888) }, + testFieldNpgsqlPointNullable = new NpgsqlPoint(888, 888), + testFieldNpgsqlPolygon = new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), + testFieldNpgsqlPolygonArray = new[] { new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)) }, + testFieldNpgsqlPolygonArrayNullable = new NpgsqlPolygon?[] { new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), null, new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)) }, + testFieldNpgsqlPolygonNullable = new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)), + testFieldNumrange = new NpgsqlRange(888.88M, 999.99M), + testFieldNumrangeArray = new[] { new NpgsqlRange(888.88M, 999.99M), new NpgsqlRange(18888.88M, 19998.99M) }, + testFieldNumrangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(888.88M, 999.99M), null, new NpgsqlRange(18888.88M, 19998.99M) }, + testFieldNumrangeNullable = new NpgsqlRange(18888.88M, 19998.99M), + testFieldPostgisGeometry = new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), + testFieldPostgisGeometryArray = new PostgisGeometry[] { + new PostgisPoint(555,551), + new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), + new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), + new PostgisMultiPolygon(new []{ + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) + }) + }, + testFieldPostgisGeometryCollection = new PostgisGeometryCollection(new PostgisGeometry[] { + new PostgisPoint(555,551), + new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), + new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), + new PostgisMultiPolygon(new []{ + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) + }) + }), + testFieldPostgisGeometryCollectionArray = new[] { + new PostgisGeometryCollection(new PostgisGeometry[] { + new PostgisPoint(555,551), + new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), + new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), + new PostgisMultiPolygon(new []{ + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) + }) + }),new PostgisGeometryCollection(new PostgisGeometry[] { + new PostgisPoint(555,551), + new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), + new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), + new PostgisMultiPolygon(new []{ + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) + }) + }) + }, + testFieldPostgisLineString = new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), + testFieldPostgisLineStringArray = new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 220) }) }, + testFieldPostgisMultiPoint = new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), + testFieldPostgisMultiPointArray = new[] { new PostgisMultiPoint(new[] { new Coordinate2D(20, 21), new Coordinate2D(210, 220) }), new PostgisMultiPoint(new[] { new Coordinate2D(120, 121), new Coordinate2D(1210, 1220) }) }, + testFieldPostgisPoint = new PostgisPoint(555, 551), + testFieldPostgisPointArray = new[] { new PostgisPoint(555, 551), new PostgisPoint(53355, 3551) }, + testFieldPostgisPolygon = new PostgisPolygon(new[] { new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + testFieldPostgisPolygonArray = new[]{ + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) + }, + testFieldPostgisPostgisMultiLineString = new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }), new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), + testFieldPostgisPostgisMultiLineStringArray = new[] { + new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110) }) , new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 210) }) }), + new PostgisMultiLineString(new[] { new PostgisLineString(new[] { new Coordinate2D(20, 21), new Coordinate2D(200, 220) }) , new PostgisLineString(new[] { new Coordinate2D(820, 821), new Coordinate2D(800, 810) }) }) + }, + testFieldPostgisPostgisMultiPolygon = new PostgisMultiPolygon(new[]{ + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) + }), + testFieldPostgisPostgisMultiPolygonArray = new[] { + new PostgisMultiPolygon(new[]{ + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) + }), + new PostgisMultiPolygon(new[]{ + new PostgisPolygon(new []{ new[] { new Coordinate2D(10, 11), new Coordinate2D(100, 110), new Coordinate2D(300, 310), new Coordinate2D(10, 11) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }), + new PostgisPolygon(new []{ new[] { new Coordinate2D(50, 51), new Coordinate2D(500, 510), new Coordinate2D(800, 810), new Coordinate2D(50, 51) }, new[] { new Coordinate2D(20, 11), new Coordinate2D(200, 110), new Coordinate2D(100, 310), new Coordinate2D(20, 11) } }) + }) + }, + testFieldSByte = sbyte.MaxValue, + testFieldSByteArray = new sbyte[] { 1, 2, 3, 4, 5 }, + testFieldSByteArrayNullable = new sbyte?[] { 1, 2, 3, null, 4, 5 }, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + testFieldShortArray = new short[] { 1, 2, 3, 4, 5 }, + testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 }, + testFieldShortNullable = short.MinValue, + testFieldString = "йString", + testFieldStringArray = new[] { "йString1", "йString2", null, "йString3" }, + testFieldTimeSpan = TimeSpan.FromDays(1), + testFieldTimeSpanArray = new[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }, + testFieldTimeSpanArrayNullable = new TimeSpan?[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), null, TimeSpan.FromSeconds(60) }, + testFieldTimeSpanNullable = TimeSpan.FromSeconds(90), + testFieldTsrange = new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), + testFieldTsrangeArray = new[] { new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)) }, + testFieldTsrangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), null, new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)) }, + testFieldTsrangeNullable = new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)), + testFieldUInt = uint.MaxValue, + testFieldUIntArray = new uint[] { 1, 2, 3, 4, 5 }, + testFieldUIntArrayNullable = new uint?[] { 1, 2, 3, null, 4, 5 }, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongArray = new ulong[] { 10, 20, 30, 40, 50 }, + testFieldULongArrayNullable = new ulong?[] { 10, 20, 30, null, 40, 50 }, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortArray = new ushort[] { 11, 12, 13, 14, 15 }, + testFieldUShortArrayNullable = new ushort?[] { 11, 12, 13, null, 14, 15 }, + testFieldUShortNullable = ushort.MinValue, + testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 }, + testFielLongNullable = long.MinValue + }; + var item3 = insert.AppendData(item2).ExecuteInserted().First(); + var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); - var items = select.ToList(); - } + var items = select.ToList(); + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - public bool testFieldBool { get; set; } - public sbyte testFieldSByte { get; set; } - public short testFieldShort { get; set; } - public int testFieldInt { get; set; } - public long testFieldLong { get; set; } - public byte testFieldByte { get; set; } - public ushort testFieldUShort { get; set; } - public uint testFieldUInt { get; set; } - public ulong testFieldULong { get; set; } - public double testFieldDouble { get; set; } - public float testFieldFloat { get; set; } - public decimal testFieldDecimal { get; set; } - public TimeSpan testFieldTimeSpan { get; set; } - public DateTime testFieldDateTime { get; set; } - public byte[] testFieldBytes { get; set; } - public string testFieldString { get; set; } - public Guid testFieldGuid { get; set; } - public NpgsqlPoint testFieldNpgsqlPoint { get; set; } - public NpgsqlLine testFieldNpgsqlLine { get; set; } - public NpgsqlLSeg testFieldNpgsqlLSeg { get; set; } - public NpgsqlBox testFieldNpgsqlBox { get; set; } - public NpgsqlPath testFieldNpgsqlPath { get; set; } - public NpgsqlPolygon testFieldNpgsqlPolygon { get; set; } - public NpgsqlCircle testFieldNpgsqlCircle { get; set; } - public (IPAddress Address, int Subnet) testFieldCidr { get; set; } - public NpgsqlRange testFieldInt4range { get; set; } - public NpgsqlRange testFieldInt8range { get; set; } - public NpgsqlRange testFieldNumrange { get; set; } - public NpgsqlRange testFieldTsrange { get; set; } + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + public NpgsqlPoint testFieldNpgsqlPoint { get; set; } + public NpgsqlLine testFieldNpgsqlLine { get; set; } + public NpgsqlLSeg testFieldNpgsqlLSeg { get; set; } + public NpgsqlBox testFieldNpgsqlBox { get; set; } + public NpgsqlPath testFieldNpgsqlPath { get; set; } + public NpgsqlPolygon testFieldNpgsqlPolygon { get; set; } + public NpgsqlCircle testFieldNpgsqlCircle { get; set; } + public (IPAddress Address, int Subnet) testFieldCidr { get; set; } + public NpgsqlRange testFieldInt4range { get; set; } + public NpgsqlRange testFieldInt8range { get; set; } + public NpgsqlRange testFieldNumrange { get; set; } + public NpgsqlRange testFieldTsrange { get; set; } - public bool? testFieldBoolNullable { get; set; } - public sbyte? testFieldSByteNullable { get; set; } - public short? testFieldShortNullable { get; set; } - public int? testFieldIntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? testFieldByteNullable { get; set; } - public ushort? testFieldUShortNullable { get; set; } - public uint? testFieldUIntNullable { get; set; } - public ulong? testFieldULongNullable { get; set; } - public double? testFieldDoubleNullable { get; set; } - public float? testFieldFloatNullable { get; set; } - public decimal? testFieldDecimalNullable { get; set; } - public TimeSpan? testFieldTimeSpanNullable { get; set; } - public DateTime? testFieldDateTimeNullable { get; set; } - public Guid? testFieldGuidNullable { get; set; } - public NpgsqlPoint? testFieldNpgsqlPointNullable { get; set; } - public NpgsqlLine? testFieldNpgsqlLineNullable { get; set; } - public NpgsqlLSeg? testFieldNpgsqlLSegNullable { get; set; } - public NpgsqlBox? testFieldNpgsqlBoxNullable { get; set; } - public NpgsqlPath? testFieldNpgsqlPathNullable { get; set; } - public NpgsqlPolygon? testFieldNpgsqlPolygonNullable { get; set; } - public NpgsqlCircle? testFieldNpgsqlCircleNullable { get; set; } - public (IPAddress Address, int Subnet)? testFieldCidrNullable { get; set; } - public NpgsqlRange? testFieldInt4rangeNullable { get; set; } - public NpgsqlRange? testFieldInt8rangeNullable { get; set; } - public NpgsqlRange? testFieldNumrangeNullable { get; set; } - public NpgsqlRange? testFieldTsrangeNullable { get; set; } + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + public NpgsqlPoint? testFieldNpgsqlPointNullable { get; set; } + public NpgsqlLine? testFieldNpgsqlLineNullable { get; set; } + public NpgsqlLSeg? testFieldNpgsqlLSegNullable { get; set; } + public NpgsqlBox? testFieldNpgsqlBoxNullable { get; set; } + public NpgsqlPath? testFieldNpgsqlPathNullable { get; set; } + public NpgsqlPolygon? testFieldNpgsqlPolygonNullable { get; set; } + public NpgsqlCircle? testFieldNpgsqlCircleNullable { get; set; } + public (IPAddress Address, int Subnet)? testFieldCidrNullable { get; set; } + public NpgsqlRange? testFieldInt4rangeNullable { get; set; } + public NpgsqlRange? testFieldInt8rangeNullable { get; set; } + public NpgsqlRange? testFieldNumrangeNullable { get; set; } + public NpgsqlRange? testFieldTsrangeNullable { get; set; } - public BitArray testFieldBitArray { get; set; } - public IPAddress testFieldInet { get; set; } - public PhysicalAddress testFieldMacaddr { get; set; } - public JToken testFieldJToken { get; set; } - public JObject testFieldJObject { get; set; } - public JArray testFieldJArray { get; set; } - public Dictionary testFieldHStore { get; set; } - public PostgisPoint testFieldPostgisPoint { get; set; } - public PostgisLineString testFieldPostgisLineString { get; set; } - public PostgisPolygon testFieldPostgisPolygon { get; set; } - public PostgisMultiPoint testFieldPostgisMultiPoint { get; set; } - public PostgisMultiLineString testFieldPostgisPostgisMultiLineString { get; set; } - public PostgisMultiPolygon testFieldPostgisPostgisMultiPolygon { get; set; } - public PostgisGeometry testFieldPostgisGeometry { get; set; } - public PostgisGeometryCollection testFieldPostgisGeometryCollection { get; set; } + public BitArray testFieldBitArray { get; set; } + public IPAddress testFieldInet { get; set; } + public PhysicalAddress testFieldMacaddr { get; set; } + public JToken testFieldJToken { get; set; } + public JObject testFieldJObject { get; set; } + public JArray testFieldJArray { get; set; } + public Dictionary testFieldHStore { get; set; } + public PostgisPoint testFieldPostgisPoint { get; set; } + public PostgisLineString testFieldPostgisLineString { get; set; } + public PostgisPolygon testFieldPostgisPolygon { get; set; } + public PostgisMultiPoint testFieldPostgisMultiPoint { get; set; } + public PostgisMultiLineString testFieldPostgisPostgisMultiLineString { get; set; } + public PostgisMultiPolygon testFieldPostgisPostgisMultiPolygon { get; set; } + public PostgisGeometry testFieldPostgisGeometry { get; set; } + public PostgisGeometryCollection testFieldPostgisGeometryCollection { get; set; } - public TableAllTypeEnumType1 testFieldEnum1 { get; set; } - public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } - public TableAllTypeEnumType2 testFieldEnum2 { get; set; } - public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - /* array */ - public bool[] testFieldBoolArray { get; set; } - public sbyte[] testFieldSByteArray { get; set; } - public short[] testFieldShortArray { get; set; } - public int[] testFieldIntArray { get; set; } - public long[] testFieldLongArray { get; set; } - public byte[] testFieldByteArray { get; set; } - public ushort[] testFieldUShortArray { get; set; } - public uint[] testFieldUIntArray { get; set; } - public ulong[] testFieldULongArray { get; set; } - public double[] testFieldDoubleArray { get; set; } - public float[] testFieldFloatArray { get; set; } - public decimal[] testFieldDecimalArray { get; set; } - public TimeSpan[] testFieldTimeSpanArray { get; set; } - public DateTime[] testFieldDateTimeArray { get; set; } - public byte[][] testFieldBytesArray { get; set; } - public string[] testFieldStringArray { get; set; } - public Guid[] testFieldGuidArray { get; set; } - public NpgsqlPoint[] testFieldNpgsqlPointArray { get; set; } - public NpgsqlLine[] testFieldNpgsqlLineArray { get; set; } - public NpgsqlLSeg[] testFieldNpgsqlLSegArray { get; set; } - public NpgsqlBox[] testFieldNpgsqlBoxArray { get; set; } - public NpgsqlPath[] testFieldNpgsqlPathArray { get; set; } - public NpgsqlPolygon[] testFieldNpgsqlPolygonArray { get; set; } - public NpgsqlCircle[] testFieldNpgsqlCircleArray { get; set; } - public (IPAddress Address, int Subnet)[] testFieldCidrArray { get; set; } - public NpgsqlRange[] testFieldInt4rangeArray { get; set; } - public NpgsqlRange[] testFieldInt8rangeArray { get; set; } - public NpgsqlRange[] testFieldNumrangeArray { get; set; } - public NpgsqlRange[] testFieldTsrangeArray { get; set; } + /* array */ + public bool[] testFieldBoolArray { get; set; } + public sbyte[] testFieldSByteArray { get; set; } + public short[] testFieldShortArray { get; set; } + public int[] testFieldIntArray { get; set; } + public long[] testFieldLongArray { get; set; } + public byte[] testFieldByteArray { get; set; } + public ushort[] testFieldUShortArray { get; set; } + public uint[] testFieldUIntArray { get; set; } + public ulong[] testFieldULongArray { get; set; } + public double[] testFieldDoubleArray { get; set; } + public float[] testFieldFloatArray { get; set; } + public decimal[] testFieldDecimalArray { get; set; } + public TimeSpan[] testFieldTimeSpanArray { get; set; } + public DateTime[] testFieldDateTimeArray { get; set; } + public byte[][] testFieldBytesArray { get; set; } + public string[] testFieldStringArray { get; set; } + public Guid[] testFieldGuidArray { get; set; } + public NpgsqlPoint[] testFieldNpgsqlPointArray { get; set; } + public NpgsqlLine[] testFieldNpgsqlLineArray { get; set; } + public NpgsqlLSeg[] testFieldNpgsqlLSegArray { get; set; } + public NpgsqlBox[] testFieldNpgsqlBoxArray { get; set; } + public NpgsqlPath[] testFieldNpgsqlPathArray { get; set; } + public NpgsqlPolygon[] testFieldNpgsqlPolygonArray { get; set; } + public NpgsqlCircle[] testFieldNpgsqlCircleArray { get; set; } + public (IPAddress Address, int Subnet)[] testFieldCidrArray { get; set; } + public NpgsqlRange[] testFieldInt4rangeArray { get; set; } + public NpgsqlRange[] testFieldInt8rangeArray { get; set; } + public NpgsqlRange[] testFieldNumrangeArray { get; set; } + public NpgsqlRange[] testFieldTsrangeArray { get; set; } - public bool?[] testFieldBoolArrayNullable { get; set; } - public sbyte?[] testFieldSByteArrayNullable { get; set; } - public short?[] testFieldShortArrayNullable { get; set; } - public int?[] testFieldIntArrayNullable { get; set; } - public long?[] testFielLongArrayNullable { get; set; } - public byte?[] testFieldByteArrayNullable { get; set; } - public ushort?[] testFieldUShortArrayNullable { get; set; } - public uint?[] testFieldUIntArrayNullable { get; set; } - public ulong?[] testFieldULongArrayNullable { get; set; } - public double?[] testFieldDoubleArrayNullable { get; set; } - public float?[] testFieldFloatArrayNullable { get; set; } - public decimal?[] testFieldDecimalArrayNullable { get; set; } - public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; } - public DateTime?[] testFieldDateTimeArrayNullable { get; set; } - public Guid?[] testFieldGuidArrayNullable { get; set; } - public NpgsqlPoint?[] testFieldNpgsqlPointArrayNullable { get; set; } - public NpgsqlLine?[] testFieldNpgsqlLineArrayNullable { get; set; } - public NpgsqlLSeg?[] testFieldNpgsqlLSegArrayNullable { get; set; } - public NpgsqlBox?[] testFieldNpgsqlBoxArrayNullable { get; set; } - public NpgsqlPath?[] testFieldNpgsqlPathArrayNullable { get; set; } - public NpgsqlPolygon?[] testFieldNpgsqlPolygonArrayNullable { get; set; } - public NpgsqlCircle?[] testFieldNpgsqlCircleArrayNullable { get; set; } - public (IPAddress Address, int Subnet)?[] testFieldCidrArrayNullable { get; set; } - public NpgsqlRange?[] testFieldInt4rangeArrayNullable { get; set; } - public NpgsqlRange?[] testFieldInt8rangeArrayNullable { get; set; } - public NpgsqlRange?[] testFieldNumrangeArrayNullable { get; set; } - public NpgsqlRange?[] testFieldTsrangeArrayNullable { get; set; } + public bool?[] testFieldBoolArrayNullable { get; set; } + public sbyte?[] testFieldSByteArrayNullable { get; set; } + public short?[] testFieldShortArrayNullable { get; set; } + public int?[] testFieldIntArrayNullable { get; set; } + public long?[] testFielLongArrayNullable { get; set; } + public byte?[] testFieldByteArrayNullable { get; set; } + public ushort?[] testFieldUShortArrayNullable { get; set; } + public uint?[] testFieldUIntArrayNullable { get; set; } + public ulong?[] testFieldULongArrayNullable { get; set; } + public double?[] testFieldDoubleArrayNullable { get; set; } + public float?[] testFieldFloatArrayNullable { get; set; } + public decimal?[] testFieldDecimalArrayNullable { get; set; } + public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; } + public DateTime?[] testFieldDateTimeArrayNullable { get; set; } + public Guid?[] testFieldGuidArrayNullable { get; set; } + public NpgsqlPoint?[] testFieldNpgsqlPointArrayNullable { get; set; } + public NpgsqlLine?[] testFieldNpgsqlLineArrayNullable { get; set; } + public NpgsqlLSeg?[] testFieldNpgsqlLSegArrayNullable { get; set; } + public NpgsqlBox?[] testFieldNpgsqlBoxArrayNullable { get; set; } + public NpgsqlPath?[] testFieldNpgsqlPathArrayNullable { get; set; } + public NpgsqlPolygon?[] testFieldNpgsqlPolygonArrayNullable { get; set; } + public NpgsqlCircle?[] testFieldNpgsqlCircleArrayNullable { get; set; } + public (IPAddress Address, int Subnet)?[] testFieldCidrArrayNullable { get; set; } + public NpgsqlRange?[] testFieldInt4rangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldInt8rangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldNumrangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldTsrangeArrayNullable { get; set; } - public BitArray[] testFieldBitArrayArray { get; set; } - public IPAddress[] testFieldInetArray { get; set; } - public PhysicalAddress[] testFieldMacaddrArray { get; set; } - public JToken[] testFieldJTokenArray { get; set; } - public JObject[] testFieldJObjectArray { get; set; } - public JArray[] testFieldJArrayArray { get; set; } - public Dictionary[] testFieldHStoreArray { get; set; } - public PostgisPoint[] testFieldPostgisPointArray { get; set; } - public PostgisLineString[] testFieldPostgisLineStringArray { get; set; } - public PostgisPolygon[] testFieldPostgisPolygonArray { get; set; } - public PostgisMultiPoint[] testFieldPostgisMultiPointArray { get; set; } - public PostgisMultiLineString[] testFieldPostgisPostgisMultiLineStringArray { get; set; } - public PostgisMultiPolygon[] testFieldPostgisPostgisMultiPolygonArray { get; set; } - public PostgisGeometry[] testFieldPostgisGeometryArray { get; set; } - public PostgisGeometryCollection[] testFieldPostgisGeometryCollectionArray { get; set; } + public BitArray[] testFieldBitArrayArray { get; set; } + public IPAddress[] testFieldInetArray { get; set; } + public PhysicalAddress[] testFieldMacaddrArray { get; set; } + public JToken[] testFieldJTokenArray { get; set; } + public JObject[] testFieldJObjectArray { get; set; } + public JArray[] testFieldJArrayArray { get; set; } + public Dictionary[] testFieldHStoreArray { get; set; } + public PostgisPoint[] testFieldPostgisPointArray { get; set; } + public PostgisLineString[] testFieldPostgisLineStringArray { get; set; } + public PostgisPolygon[] testFieldPostgisPolygonArray { get; set; } + public PostgisMultiPoint[] testFieldPostgisMultiPointArray { get; set; } + public PostgisMultiLineString[] testFieldPostgisPostgisMultiLineStringArray { get; set; } + public PostgisMultiPolygon[] testFieldPostgisPostgisMultiPolygonArray { get; set; } + public PostgisGeometry[] testFieldPostgisGeometryArray { get; set; } + public PostgisGeometryCollection[] testFieldPostgisGeometryCollectionArray { get; set; } - public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; } - public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; } - public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; } - public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; } - } + public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; } + public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; } + public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; } + public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; } + } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs index 52aa48bc..f6c823c4 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -2,20 +2,24 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.PostgreSQL { - public class PostgreSQLDbFirstTest { - [Fact] - public void GetDatabases() { +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLDbFirstTest + { + [Fact] + public void GetDatabases() + { - var t1 = g.pgsql.DbFirst.GetDatabases(); + var t1 = g.pgsql.DbFirst.GetDatabases(); - } + } - [Fact] - public void GetTablesByDatabase() { + [Fact] + public void GetTablesByDatabase() + { - var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[1]); + var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[1]); - } - } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/ConvertTest.cs index 02c98b7c..2a61c16a 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/ConvertTest.cs @@ -4,143 +4,166 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQLExpression { - public class ConvertTest { +namespace FreeSql.Tests.PostgreSQLExpression +{ + public class ConvertTest + { - ISelect select => g.pgsql.Select(); + ISelect select => g.pgsql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void ToBoolean() { - var data = new List(); - data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); - data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); - } - [Fact] - public void ToByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); - data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); - } - [Fact] - public void ToChar() { - var data = new List(); - //data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); - //data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); - } - [Fact] - public void ToDateTime() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); - } - [Fact] - public void ToDecimal() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToDouble() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt32() { - var data = new List(); - data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); - data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToSByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); - data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); - } - [Fact] - public void ToSingle() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); - data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); - } - [Fact] - public void ToUInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt32() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); - } + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + //data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } - [Fact] - public void Guid_Parse() { - var data = new List(); - data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); - } + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } - [Fact] - public void Guid_NewGuid() { - var data = new List(); - //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); - } + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } - [Fact] - public void Random() { - var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); - } - } + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs index ee70bad6..d99dd64c 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs @@ -4,664 +4,703 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQLExpression { - public class DateTimeTest { - - ISelect select => g.pgsql.Select(); - - [Table(Name = "tb_topic111333")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - [Table(Name = "TestTypeInfo333")] - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - public DateTime Time { get; set; } - } - [Table(Name = "TestTypeParentInfo23123")] - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - public DateTime Time2 { get; set; } - } - [Fact] - public void Now() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void UtcNow() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void Date() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) - } - [Fact] - public void TimeOfDay() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) - } - [Fact] - public void DayOfWeek() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) - } - [Fact] - public void Day() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) - } - [Fact] - public void DayOfYear() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) - } - [Fact] - public void Month() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (month(a.`CreateTime`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (month(a__Type.`Time`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (month(a__Type__Parent.`Time2`) > month(now())) - } - [Fact] - public void Year() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (year(a.`CreateTime`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (year(a__Type.`Time`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (year(a__Type__Parent.`Time2`) > year(now())) - } - [Fact] - public void Hour() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (hour(a.`CreateTime`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (hour(a__Type.`Time`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) - } - [Fact] - public void Minute() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (minute(a.`CreateTime`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (minute(a__Type.`Time`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) - } - [Fact] - public void Second() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (second(a.`CreateTime`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (second(a__Type.`Time`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (second(a__Type__Parent.`Time2`) > second(now())) - } - [Fact] - public void Millisecond() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) - } - [Fact] - public void AddDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) - } - [Fact] - public void AddHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) - } - [Fact] - public void AddMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) - } - [Fact] - public void AddMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) - } - [Fact] - public void AddMonths() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) - } - [Fact] - public void AddSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) - } - [Fact] - public void AddTicks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) - } - [Fact] - public void AddYears() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" - //FROM "tb_topic111333" a - //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) - - //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" - //FROM "tb_topic111333" a - //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" - //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) - - //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" - //FROM "tb_topic111333" a - //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" - //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" - //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" - //FROM "tb_topic111333" a - //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") - - //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" - //FROM "tb_topic111333" a - //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" - //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") - - //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" - //FROM "tb_topic111333" a - //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" - //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" - //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") - } - [Fact] - public void _ЧͬSubtract() { - var data = new List(); - data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" - //FROM "tb_topic111333" a - //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) - - //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" - //FROM "tb_topic111333" a - //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" - //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) - - //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" - //FROM "tb_topic111333" a - //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" - //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" - //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" - //FROM "tb_topic111333" a - //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") - - //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" - //FROM "tb_topic111333" a - //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" - //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") - - //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" - //FROM "tb_topic111333" a - //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" - //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" - //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - - [Fact] - public void DateTime_Compare() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((a.`CreateTime`) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) - } - [Fact] - public void DateTime_DaysInMonth() { - var data = new List(); - data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) - } - [Fact] - public void DateTime_Equals() { - var data = new List(); - data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void DateTime_IsLeapYear() { - var data = new List(); - data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) - } - [Fact] - public void DateTime_Parse() { - var data = new List(); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) - } - } +namespace FreeSql.Tests.PostgreSQLExpression +{ + public class DateTimeTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs index 731fa99a..edc58bd3 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs @@ -4,129 +4,153 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQLExpression { - public class MathTest { +namespace FreeSql.Tests.PostgreSQLExpression +{ + public class MathTest + { - ISelect select => g.pgsql.Select(); + ISelect select => g.pgsql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void PI() { - var data = new List(); - data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); - } - [Fact] - public void Abs() { - var data = new List(); - data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Sign() { - var data = new List(); - data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Floor() { - var data = new List(); - data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); - } - [Fact] - public void Ceiling() { - var data = new List(); - data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Round() { - var data = new List(); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); - } - [Fact] - public void Exp() { - var data = new List(); - data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log() { - var data = new List(); - //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log10() { - var data = new List(); - //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Pow() { - var data = new List(); - data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sqrt() { - var data = new List(); - data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Cos() { - var data = new List(); - data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sin() { - var data = new List(); - data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Tan() { - var data = new List(); - data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Acos() { - var data = new List(); - //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Asin() { - var data = new List(); - //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan() { - var data = new List(); - data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan2() { - var data = new List(); - data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Truncate() { - var data = new List(); - data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); - } - } + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index aa45e936..6a31499a 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -12,286 +12,294 @@ using System.Net; using System.Net.NetworkInformation; using Xunit; -namespace FreeSql.Tests.PostgreSQLExpression { - public class OtherTest { +namespace FreeSql.Tests.PostgreSQLExpression +{ + public class OtherTest + { - ISelect select => g.pgsql.Select(); + ISelect select => g.pgsql.Select(); - public OtherTest() { - NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); - } + public OtherTest() + { + NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); + } - [Fact] - public void Boolean() { - var t1 = select.Where(a => a.testFieldBool == true).ToList(); - var t2 = select.Where(a => a.testFieldBool != true).ToList(); - var t3 = select.Where(a => a.testFieldBool == false).ToList(); - var t4 = select.Where(a => !a.testFieldBool).ToList(); - var t5 = select.Where(a => a.testFieldBool).ToList(); + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); - var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); - var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); - var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); - var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); - var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); - } + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } - [Fact] - public void Array() { - //g.pgsql.Aop.CurdAfter = (s, e) => { - // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); - //}; - IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); - var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + [Fact] + public void Array() + { + //g.pgsql.Aop.CurdAfter = (s, e) => { + // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); + //}; + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); - var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList(); - var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList(); + var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList(); + var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList(); - //in not in - var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); - var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var inarray = new[] { 1, 2, 3 }; - var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToSql(); - var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToSql(); - var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToSql(); + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToSql(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToSql(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToSql(); - //in not in - var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); - var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); - var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); - var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); - var inarray2 = new List() { 1, 2, 3 }; - var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); - var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); - var sql1111112 = select.ToList(a => inarray); - var sql1111113 = select.ToList(a => a.testFieldIntArray); + var sql1111112 = select.ToList(a => inarray); + var sql1111113 = select.ToList(a => a.testFieldIntArray); - var sql3 = select.Where(a => a.testFieldIntArray.Any()).ToList(); - var sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList(); + var sql3 = select.Where(a => a.testFieldIntArray.Any()).ToList(); + var sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList(); - var sql5 = select.ToList(a => a.testFieldIntArray.Concat(new[] { 1, 2, 3 })); + var sql5 = select.ToList(a => a.testFieldIntArray.Concat(new[] { 1, 2, 3 })); - var sql6 = select.Where(a => a.testFieldIntArray.GetLength(1) > 0).ToList(); - var sql7 = select.Where(a => a.testFieldIntArray.GetLongLength(1) > 0).ToList(); - var sql8 = select.Where(a => a.testFieldIntArray.Length > 0).ToList(); - var sql9 = select.Where(a => a.testFieldIntArray.Count() > 0).ToList(); - } + var sql6 = select.Where(a => a.testFieldIntArray.GetLength(1) > 0).ToList(); + var sql7 = select.Where(a => a.testFieldIntArray.GetLongLength(1) > 0).ToList(); + var sql8 = select.Where(a => a.testFieldIntArray.Length > 0).ToList(); + var sql9 = select.Where(a => a.testFieldIntArray.Count() > 0).ToList(); + } - [Fact] - public void Jsonb() { + [Fact] + public void Jsonb() + { - var sql1 = select.Where(a => a.testFieldJToken.Contains(JToken.Parse("{a:1}"))).ToList(); - var sql2 = select.Where(a => a.testFieldJToken.Contains(JToken.Parse("{a:1}")) == false).ToList(); - var sql111 = select.Where(a => a.testFieldJToken.Contains("{a:1}")).ToList(); - var sql222 = select.Where(a => a.testFieldJToken.Contains("{a:1}") == false).ToList(); + var sql1 = select.Where(a => a.testFieldJToken.Contains(JToken.Parse("{a:1}"))).ToList(); + var sql2 = select.Where(a => a.testFieldJToken.Contains(JToken.Parse("{a:1}")) == false).ToList(); + var sql111 = select.Where(a => a.testFieldJToken.Contains("{a:1}")).ToList(); + var sql222 = select.Where(a => a.testFieldJToken.Contains("{a:1}") == false).ToList(); - var sql3 = select.Where(a => a.testFieldJObject.ContainsKey("a")).ToList(); - var sql4 = select.Where(a => a.testFieldJObject.ContainsKey("a") == false).ToList(); + var sql3 = select.Where(a => a.testFieldJObject.ContainsKey("a")).ToList(); + var sql4 = select.Where(a => a.testFieldJObject.ContainsKey("a") == false).ToList(); - var sql5 = select.Where(a => a.testFieldJArray.Contains(1)).ToList(); - var sql6 = select.Where(a => a.testFieldJArray.Contains(1) == false).ToList(); - var sql555 = select.Where(a => a.testFieldJArray.Contains(1)).ToList(); - var sql666 = select.Where(a => a.testFieldJArray.Contains(1) == false).ToList(); + var sql5 = select.Where(a => a.testFieldJArray.Contains(1)).ToList(); + var sql6 = select.Where(a => a.testFieldJArray.Contains(1) == false).ToList(); + var sql555 = select.Where(a => a.testFieldJArray.Contains(1)).ToList(); + var sql666 = select.Where(a => a.testFieldJArray.Contains(1) == false).ToList(); - //var sql7 = select.Where(a => a.testFieldJToken.Any()).ToList(); - //var sql8 = select.Where(a => a.testFieldJToken.Any() == false).ToList(); + //var sql7 = select.Where(a => a.testFieldJToken.Any()).ToList(); + //var sql8 = select.Where(a => a.testFieldJToken.Any() == false).ToList(); - var sql9 = select.Where(a => a.testFieldJArray.Any()).ToList(); - var sql10 = select.Where(a => a.testFieldJArray.Any() == false).ToList(); + var sql9 = select.Where(a => a.testFieldJArray.Any()).ToList(); + var sql10 = select.Where(a => a.testFieldJArray.Any() == false).ToList(); - //var sql11 = select.ToList(a => a.testFieldJToken.Concat(JToken.Parse("{a:1}"))); - //var sql12 = select.ToList(a => a.testFieldJObject.Concat(JToken.Parse("{a:1}"))); - //var sql13 = select.ToList(a => a.testFieldJArray.Concat(JToken.Parse("{a:1}"))); + //var sql11 = select.ToList(a => a.testFieldJToken.Concat(JToken.Parse("{a:1}"))); + //var sql12 = select.ToList(a => a.testFieldJObject.Concat(JToken.Parse("{a:1}"))); + //var sql13 = select.ToList(a => a.testFieldJArray.Concat(JToken.Parse("{a:1}"))); - //var sql14 = select.Where(a => a.testFieldJToken.Count() > 0).ToList(); - //var sql15 = select.Where(a => a.testFieldJObject.Count > 0).ToList(); - var sql16 = select.Where(a => a.testFieldJArray.Count() > 0).ToList(); - var sql17 = select.Where(a => a.testFieldJArray.LongCount() > 0).ToList(); - var sql18 = select.Where(a => a.testFieldJArray.Count > 0).ToList(); - } + //var sql14 = select.Where(a => a.testFieldJToken.Count() > 0).ToList(); + //var sql15 = select.Where(a => a.testFieldJObject.Count > 0).ToList(); + var sql16 = select.Where(a => a.testFieldJArray.Count() > 0).ToList(); + var sql17 = select.Where(a => a.testFieldJArray.LongCount() > 0).ToList(); + var sql18 = select.Where(a => a.testFieldJArray.Count > 0).ToList(); + } - [Fact] - public void HStore() { + [Fact] + public void HStore() + { - var sql1 = select.Where(a => a.testFieldHStore.ContainsKey("a")).ToList(); - var sql2 = select.Where(a => a.testFieldHStore.ContainsKey("a") == false).ToList(); - } + var sql1 = select.Where(a => a.testFieldHStore.ContainsKey("a")).ToList(); + var sql2 = select.Where(a => a.testFieldHStore.ContainsKey("a") == false).ToList(); + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - public bool testFieldBool { get; set; } - public sbyte testFieldSByte { get; set; } - public short testFieldShort { get; set; } - public int testFieldInt { get; set; } - public long testFieldLong { get; set; } - public byte testFieldByte { get; set; } - public ushort testFieldUShort { get; set; } - public uint testFieldUInt { get; set; } - public ulong testFieldULong { get; set; } - public double testFieldDouble { get; set; } - public float testFieldFloat { get; set; } - public decimal testFieldDecimal { get; set; } - public TimeSpan testFieldTimeSpan { get; set; } - public DateTime testFieldDateTime { get; set; } - public byte[] testFieldBytes { get; set; } - public string testFieldString { get; set; } - public Guid testFieldGuid { get; set; } - public NpgsqlPoint testFieldNpgsqlPoint { get; set; } - public NpgsqlLine testFieldNpgsqlLine { get; set; } - public NpgsqlLSeg testFieldNpgsqlLSeg { get; set; } - public NpgsqlBox testFieldNpgsqlBox { get; set; } - public NpgsqlPath testFieldNpgsqlPath { get; set; } - public NpgsqlPolygon testFieldNpgsqlPolygon { get; set; } - public NpgsqlCircle testFieldNpgsqlCircle { get; set; } - public (IPAddress Address, int Subnet) testFieldCidr { get; set; } - public NpgsqlRange testFieldInt4range { get; set; } - public NpgsqlRange testFieldInt8range { get; set; } - public NpgsqlRange testFieldNumrange { get; set; } - public NpgsqlRange testFieldTsrange { get; set; } + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + public NpgsqlPoint testFieldNpgsqlPoint { get; set; } + public NpgsqlLine testFieldNpgsqlLine { get; set; } + public NpgsqlLSeg testFieldNpgsqlLSeg { get; set; } + public NpgsqlBox testFieldNpgsqlBox { get; set; } + public NpgsqlPath testFieldNpgsqlPath { get; set; } + public NpgsqlPolygon testFieldNpgsqlPolygon { get; set; } + public NpgsqlCircle testFieldNpgsqlCircle { get; set; } + public (IPAddress Address, int Subnet) testFieldCidr { get; set; } + public NpgsqlRange testFieldInt4range { get; set; } + public NpgsqlRange testFieldInt8range { get; set; } + public NpgsqlRange testFieldNumrange { get; set; } + public NpgsqlRange testFieldTsrange { get; set; } - public bool? testFieldBoolNullable { get; set; } - public sbyte? testFieldSByteNullable { get; set; } - public short? testFieldShortNullable { get; set; } - public int? testFieldIntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? testFieldByteNullable { get; set; } - public ushort? testFieldUShortNullable { get; set; } - public uint? testFieldUIntNullable { get; set; } - public ulong? testFieldULongNullable { get; set; } - public double? testFieldDoubleNullable { get; set; } - public float? testFieldFloatNullable { get; set; } - public decimal? testFieldDecimalNullable { get; set; } - public TimeSpan? testFieldTimeSpanNullable { get; set; } - public DateTime? testFieldDateTimeNullable { get; set; } - public Guid? testFieldGuidNullable { get; set; } - public NpgsqlPoint? testFieldNpgsqlPointNullable { get; set; } - public NpgsqlLine? testFieldNpgsqlLineNullable { get; set; } - public NpgsqlLSeg? testFieldNpgsqlLSegNullable { get; set; } - public NpgsqlBox? testFieldNpgsqlBoxNullable { get; set; } - public NpgsqlPath? testFieldNpgsqlPathNullable { get; set; } - public NpgsqlPolygon? testFieldNpgsqlPolygonNullable { get; set; } - public NpgsqlCircle? testFieldNpgsqlCircleNullable { get; set; } - public (IPAddress Address, int Subnet)? testFieldCidrNullable { get; set; } - public NpgsqlRange? testFieldInt4rangeNullable { get; set; } - public NpgsqlRange? testFieldInt8rangeNullable { get; set; } - public NpgsqlRange? testFieldNumrangeNullable { get; set; } - public NpgsqlRange? testFieldTsrangeNullable { get; set; } + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + public NpgsqlPoint? testFieldNpgsqlPointNullable { get; set; } + public NpgsqlLine? testFieldNpgsqlLineNullable { get; set; } + public NpgsqlLSeg? testFieldNpgsqlLSegNullable { get; set; } + public NpgsqlBox? testFieldNpgsqlBoxNullable { get; set; } + public NpgsqlPath? testFieldNpgsqlPathNullable { get; set; } + public NpgsqlPolygon? testFieldNpgsqlPolygonNullable { get; set; } + public NpgsqlCircle? testFieldNpgsqlCircleNullable { get; set; } + public (IPAddress Address, int Subnet)? testFieldCidrNullable { get; set; } + public NpgsqlRange? testFieldInt4rangeNullable { get; set; } + public NpgsqlRange? testFieldInt8rangeNullable { get; set; } + public NpgsqlRange? testFieldNumrangeNullable { get; set; } + public NpgsqlRange? testFieldTsrangeNullable { get; set; } - public BitArray testFieldBitArray { get; set; } - public IPAddress testFieldInet { get; set; } - public PhysicalAddress testFieldMacaddr { get; set; } - public JToken testFieldJToken { get; set; } - public JObject testFieldJObject { get; set; } - public JArray testFieldJArray { get; set; } - public Dictionary testFieldHStore { get; set; } - public PostgisPoint testFieldPostgisPoint { get; set; } - public PostgisLineString testFieldPostgisLineString { get; set; } - public PostgisPolygon testFieldPostgisPolygon { get; set; } - public PostgisMultiPoint testFieldPostgisMultiPoint { get; set; } - public PostgisMultiLineString testFieldPostgisPostgisMultiLineString { get; set; } - public PostgisMultiPolygon testFieldPostgisPostgisMultiPolygon { get; set; } - public PostgisGeometry testFieldPostgisGeometry { get; set; } - public PostgisGeometryCollection testFieldPostgisGeometryCollection { get; set; } + public BitArray testFieldBitArray { get; set; } + public IPAddress testFieldInet { get; set; } + public PhysicalAddress testFieldMacaddr { get; set; } + public JToken testFieldJToken { get; set; } + public JObject testFieldJObject { get; set; } + public JArray testFieldJArray { get; set; } + public Dictionary testFieldHStore { get; set; } + public PostgisPoint testFieldPostgisPoint { get; set; } + public PostgisLineString testFieldPostgisLineString { get; set; } + public PostgisPolygon testFieldPostgisPolygon { get; set; } + public PostgisMultiPoint testFieldPostgisMultiPoint { get; set; } + public PostgisMultiLineString testFieldPostgisPostgisMultiLineString { get; set; } + public PostgisMultiPolygon testFieldPostgisPostgisMultiPolygon { get; set; } + public PostgisGeometry testFieldPostgisGeometry { get; set; } + public PostgisGeometryCollection testFieldPostgisGeometryCollection { get; set; } - public TableAllTypeEnumType1 testFieldEnum1 { get; set; } - public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } - public TableAllTypeEnumType2 testFieldEnum2 { get; set; } - public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - /* array */ - public bool[] testFieldBoolArray { get; set; } - public sbyte[] testFieldSByteArray { get; set; } - public short[] testFieldShortArray { get; set; } - public int[] testFieldIntArray { get; set; } - public long[] testFieldLongArray { get; set; } - public byte[] testFieldByteArray { get; set; } - public ushort[] testFieldUShortArray { get; set; } - public uint[] testFieldUIntArray { get; set; } - public ulong[] testFieldULongArray { get; set; } - public double[] testFieldDoubleArray { get; set; } - public float[] testFieldFloatArray { get; set; } - public decimal[] testFieldDecimalArray { get; set; } - public TimeSpan[] testFieldTimeSpanArray { get; set; } - public DateTime[] testFieldDateTimeArray { get; set; } - public byte[][] testFieldBytesArray { get; set; } - public string[] testFieldStringArray { get; set; } - public Guid[] testFieldGuidArray { get; set; } - public NpgsqlPoint[] testFieldNpgsqlPointArray { get; set; } - public NpgsqlLine[] testFieldNpgsqlLineArray { get; set; } - public NpgsqlLSeg[] testFieldNpgsqlLSegArray { get; set; } - public NpgsqlBox[] testFieldNpgsqlBoxArray { get; set; } - public NpgsqlPath[] testFieldNpgsqlPathArray { get; set; } - public NpgsqlPolygon[] testFieldNpgsqlPolygonArray { get; set; } - public NpgsqlCircle[] testFieldNpgsqlCircleArray { get; set; } - public (IPAddress Address, int Subnet)[] testFieldCidrArray { get; set; } - public NpgsqlRange[] testFieldInt4rangeArray { get; set; } - public NpgsqlRange[] testFieldInt8rangeArray { get; set; } - public NpgsqlRange[] testFieldNumrangeArray { get; set; } - public NpgsqlRange[] testFieldTsrangeArray { get; set; } + /* array */ + public bool[] testFieldBoolArray { get; set; } + public sbyte[] testFieldSByteArray { get; set; } + public short[] testFieldShortArray { get; set; } + public int[] testFieldIntArray { get; set; } + public long[] testFieldLongArray { get; set; } + public byte[] testFieldByteArray { get; set; } + public ushort[] testFieldUShortArray { get; set; } + public uint[] testFieldUIntArray { get; set; } + public ulong[] testFieldULongArray { get; set; } + public double[] testFieldDoubleArray { get; set; } + public float[] testFieldFloatArray { get; set; } + public decimal[] testFieldDecimalArray { get; set; } + public TimeSpan[] testFieldTimeSpanArray { get; set; } + public DateTime[] testFieldDateTimeArray { get; set; } + public byte[][] testFieldBytesArray { get; set; } + public string[] testFieldStringArray { get; set; } + public Guid[] testFieldGuidArray { get; set; } + public NpgsqlPoint[] testFieldNpgsqlPointArray { get; set; } + public NpgsqlLine[] testFieldNpgsqlLineArray { get; set; } + public NpgsqlLSeg[] testFieldNpgsqlLSegArray { get; set; } + public NpgsqlBox[] testFieldNpgsqlBoxArray { get; set; } + public NpgsqlPath[] testFieldNpgsqlPathArray { get; set; } + public NpgsqlPolygon[] testFieldNpgsqlPolygonArray { get; set; } + public NpgsqlCircle[] testFieldNpgsqlCircleArray { get; set; } + public (IPAddress Address, int Subnet)[] testFieldCidrArray { get; set; } + public NpgsqlRange[] testFieldInt4rangeArray { get; set; } + public NpgsqlRange[] testFieldInt8rangeArray { get; set; } + public NpgsqlRange[] testFieldNumrangeArray { get; set; } + public NpgsqlRange[] testFieldTsrangeArray { get; set; } - public bool?[] testFieldBoolArrayNullable { get; set; } - public sbyte?[] testFieldSByteArrayNullable { get; set; } - public short?[] testFieldShortArrayNullable { get; set; } - public int?[] testFieldIntArrayNullable { get; set; } - public long?[] testFielLongArrayNullable { get; set; } - public byte?[] testFieldByteArrayNullable { get; set; } - public ushort?[] testFieldUShortArrayNullable { get; set; } - public uint?[] testFieldUIntArrayNullable { get; set; } - public ulong?[] testFieldULongArrayNullable { get; set; } - public double?[] testFieldDoubleArrayNullable { get; set; } - public float?[] testFieldFloatArrayNullable { get; set; } - public decimal?[] testFieldDecimalArrayNullable { get; set; } - public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; } - public DateTime?[] testFieldDateTimeArrayNullable { get; set; } - public Guid?[] testFieldGuidArrayNullable { get; set; } - public NpgsqlPoint?[] testFieldNpgsqlPointArrayNullable { get; set; } - public NpgsqlLine?[] testFieldNpgsqlLineArrayNullable { get; set; } - public NpgsqlLSeg?[] testFieldNpgsqlLSegArrayNullable { get; set; } - public NpgsqlBox?[] testFieldNpgsqlBoxArrayNullable { get; set; } - public NpgsqlPath?[] testFieldNpgsqlPathArrayNullable { get; set; } - public NpgsqlPolygon?[] testFieldNpgsqlPolygonArrayNullable { get; set; } - public NpgsqlCircle?[] testFieldNpgsqlCircleArrayNullable { get; set; } - public (IPAddress Address, int Subnet)?[] testFieldCidrArrayNullable { get; set; } - public NpgsqlRange?[] testFieldInt4rangeArrayNullable { get; set; } - public NpgsqlRange?[] testFieldInt8rangeArrayNullable { get; set; } - public NpgsqlRange?[] testFieldNumrangeArrayNullable { get; set; } - public NpgsqlRange?[] testFieldTsrangeArrayNullable { get; set; } + public bool?[] testFieldBoolArrayNullable { get; set; } + public sbyte?[] testFieldSByteArrayNullable { get; set; } + public short?[] testFieldShortArrayNullable { get; set; } + public int?[] testFieldIntArrayNullable { get; set; } + public long?[] testFielLongArrayNullable { get; set; } + public byte?[] testFieldByteArrayNullable { get; set; } + public ushort?[] testFieldUShortArrayNullable { get; set; } + public uint?[] testFieldUIntArrayNullable { get; set; } + public ulong?[] testFieldULongArrayNullable { get; set; } + public double?[] testFieldDoubleArrayNullable { get; set; } + public float?[] testFieldFloatArrayNullable { get; set; } + public decimal?[] testFieldDecimalArrayNullable { get; set; } + public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; } + public DateTime?[] testFieldDateTimeArrayNullable { get; set; } + public Guid?[] testFieldGuidArrayNullable { get; set; } + public NpgsqlPoint?[] testFieldNpgsqlPointArrayNullable { get; set; } + public NpgsqlLine?[] testFieldNpgsqlLineArrayNullable { get; set; } + public NpgsqlLSeg?[] testFieldNpgsqlLSegArrayNullable { get; set; } + public NpgsqlBox?[] testFieldNpgsqlBoxArrayNullable { get; set; } + public NpgsqlPath?[] testFieldNpgsqlPathArrayNullable { get; set; } + public NpgsqlPolygon?[] testFieldNpgsqlPolygonArrayNullable { get; set; } + public NpgsqlCircle?[] testFieldNpgsqlCircleArrayNullable { get; set; } + public (IPAddress Address, int Subnet)?[] testFieldCidrArrayNullable { get; set; } + public NpgsqlRange?[] testFieldInt4rangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldInt8rangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldNumrangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldTsrangeArrayNullable { get; set; } - public BitArray[] testFieldBitArrayArray { get; set; } - public IPAddress[] testFieldInetArray { get; set; } - public PhysicalAddress[] testFieldMacaddrArray { get; set; } - public JToken[] testFieldJTokenArray { get; set; } - public JObject[] testFieldJObjectArray { get; set; } - public JArray[] testFieldJArrayArray { get; set; } - public Dictionary[] testFieldHStoreArray { get; set; } - public PostgisPoint[] testFieldPostgisPointArray { get; set; } - public PostgisLineString[] testFieldPostgisLineStringArray { get; set; } - public PostgisPolygon[] testFieldPostgisPolygonArray { get; set; } - public PostgisMultiPoint[] testFieldPostgisMultiPointArray { get; set; } - public PostgisMultiLineString[] testFieldPostgisPostgisMultiLineStringArray { get; set; } - public PostgisMultiPolygon[] testFieldPostgisPostgisMultiPolygonArray { get; set; } - public PostgisGeometry[] testFieldPostgisGeometryArray { get; set; } - public PostgisGeometryCollection[] testFieldPostgisGeometryCollectionArray { get; set; } + public BitArray[] testFieldBitArrayArray { get; set; } + public IPAddress[] testFieldInetArray { get; set; } + public PhysicalAddress[] testFieldMacaddrArray { get; set; } + public JToken[] testFieldJTokenArray { get; set; } + public JObject[] testFieldJObjectArray { get; set; } + public JArray[] testFieldJArrayArray { get; set; } + public Dictionary[] testFieldHStoreArray { get; set; } + public PostgisPoint[] testFieldPostgisPointArray { get; set; } + public PostgisLineString[] testFieldPostgisLineStringArray { get; set; } + public PostgisPolygon[] testFieldPostgisPolygonArray { get; set; } + public PostgisMultiPoint[] testFieldPostgisMultiPointArray { get; set; } + public PostgisMultiLineString[] testFieldPostgisPostgisMultiLineStringArray { get; set; } + public PostgisMultiPolygon[] testFieldPostgisPostgisMultiPolygonArray { get; set; } + public PostgisGeometry[] testFieldPostgisGeometryArray { get; set; } + public PostgisGeometryCollection[] testFieldPostgisGeometryCollectionArray { get; set; } - public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; } - public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; } - public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; } - public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; } - } + public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; } + public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; } + public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; } + public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; } + } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index 16ad0aee..b4976d92 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -4,692 +4,716 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQLExpression { - public class StringTest { - - ISelect select => g.pgsql.Select(); - - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - class TestEqualsGuid { - public Guid id { get; set; } - } - - [Fact] - public void Equals__() { - var list = new List(); - list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); - list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); - } - - - [Fact] - public void Empty() { - var data = new List(); - data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ifnull(a.`Title`, '') = '') - } - - [Fact] - public void StartsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) - list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) - } - [Fact] - public void EndsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) - } - [Fact] - public void Contains() { - var list = new List(); - list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) - } - [Fact] - public void ToLower() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void ToUpper() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void Substring() { - var data = new List(); - data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) - } - [Fact] - public void Length() { - var data = new List(); - data.Add(select.Where(a => a.Title.Length == 0).ToList()); - data.Add(select.Where(a => a.Title.Length == 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); - data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) - } - [Fact] - public void IndexOf() { - var data = new List(); - data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) - } - [Fact] - public void PadLeft() { - var data = new List(); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void PadRight() { - var data = new List(); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void Trim() { - var data = new List(); - data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void TrimStart() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) - } - [Fact] - public void TrimEnd() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void Replace() { - var data = new List(); - data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) - } - - [Fact] - public void string_IsNullOrEmpty() { - var data = new List(); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); - data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); - } - } +namespace FreeSql.Tests.PostgreSQLExpression +{ + public class StringTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs index 320cca13..3ff2ad7a 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs @@ -4,257 +4,290 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.PostgreSQLExpression { - public class TimeSpanTest { +namespace FreeSql.Tests.PostgreSQLExpression +{ + public class TimeSpanTest + { - ISelect select => g.pgsql.Select(); + ISelect select => g.pgsql.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } - [Fact] - public void Zero() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) - } - [Fact] - public void Days() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) - } - [Fact] - public void Hours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) - } - [Fact] - public void Milliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) - } - [Fact] - public void Minutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) - } - [Fact] - public void Seconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) - } - [Fact] - public void TotalDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) - } - [Fact] - public void TotalHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) - } - [Fact] - public void TotalMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) - } - [Fact] - public void TotalMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) - } - [Fact] - public void TotalSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') - } + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } - [Fact] - public void TimeSpan_Compare() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void TimeSpan_Equals() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromDays() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromHours() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) - } - [Fact] - public void TimeSpan_FromMilliseconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) - } - [Fact] - public void TimeSpan_FromMinutes() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) - } - [Fact] - public void TimeSpan_FromSeconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) - } - [Fact] - public void TimeSpan_FromTicks() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) - } - [Fact] - public void TimeSpan_Parse() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) - } - } + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs index 5b11406e..5a5bbcb8 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs @@ -5,100 +5,108 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServer { - [Collection("SqlServerCollection")] - public class SqlServerDeleteTest - { - SqlServerFixture _sqlserverFixture; +namespace FreeSql.Tests.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerDeleteTest + { + SqlServerFixture _sqlserverFixture; - public SqlServerDeleteTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public SqlServerDeleteTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - IDelete delete => _sqlserverFixture.SqlServer.Delete(); //�������� + IDelete delete => _sqlserverFixture.SqlServer.Delete(); //�������� - [Table(Name = "tb_topic22211")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void Dywhere() { - Assert.Null(_sqlserverFixture.SqlServer.Delete().ToSql()); - var sql = _sqlserverFixture.SqlServer.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(_sqlserverFixture.SqlServer.Delete().ToSql()); + var sql = _sqlserverFixture.SqlServer.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + sql = _sqlserverFixture.SqlServer.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + sql = _sqlserverFixture.SqlServer.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); - } + sql = _sqlserverFixture.SqlServer.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + } - [Fact] - public void Where() { - var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); - sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = @id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = @id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - var id = _sqlserverFixture.SqlServer.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); - Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); - } - [Fact] - public void ExecuteDeleted() { + var id = _sqlserverFixture.SqlServer.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { - var item = _sqlserverFixture.SqlServer.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); - Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + var item = _sqlserverFixture.SqlServer.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); - var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }); - var itemsInserted = _sqlserverFixture.SqlServer.Insert(items).ExecuteInserted(); - Assert.Equal(items.First().Title, itemsInserted[0].Title); + var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }); + var itemsInserted = _sqlserverFixture.SqlServer.Insert(items).ExecuteInserted(); + Assert.Equal(items.First().Title, itemsInserted[0].Title); - Assert.Equal(itemsInserted[0].Id, delete.Where(a => a.Id == itemsInserted[0].Id).ExecuteDeleted()[0].Id); - } + Assert.Equal(itemsInserted[0].Id, delete.Where(a => a.Id == itemsInserted[0].Id).ExecuteDeleted()[0].Id); + } - [Fact] - public void AsTable() { - Assert.Null(_sqlserverFixture.SqlServer.Delete().ToSql()); - var sql = _sqlserverFixture.SqlServer.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + [Fact] + public void AsTable() + { + Assert.Null(_sqlserverFixture.SqlServer.Delete().ToSql()); + var sql = _sqlserverFixture.SqlServer.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); + sql = _sqlserverFixture.SqlServer.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + sql = _sqlserverFixture.SqlServer.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); - } - } + sql = _sqlserverFixture.SqlServer.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index 3b47f1f1..f1d3748b 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -5,134 +5,143 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServer { - [Collection("SqlServerCollection")] - public class SqlServerInsertTest - { - SqlServerFixture _sqlserverFixture; +namespace FreeSql.Tests.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerInsertTest + { + SqlServerFixture _sqlserverFixture; - public SqlServerInsertTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public SqlServerInsertTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - IInsert insert => _sqlserverFixture.SqlServer.Insert(); //�������� + IInsert insert => _sqlserverFixture.SqlServer.Insert(); //�������� - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - - [Fact] - public void AppendData() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); - sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - } + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - [Fact] - public void InsertColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + } - var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - } - [Fact] - public void IgnoreColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - var sql = insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); - Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); - } - [Fact] - public void ExecuteAffrows() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + var sql = insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //Assert.Equal(9989, _sqlserverFixture.SqlServer.Insert(items).ExecuteAffrows()); - } - [Fact] - public void ExecuteIdentity() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); - Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, _sqlserverFixture.SqlServer.Insert(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); - //items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //var lastId = g.sqlite.Select().Max(a => a.Id); - //Assert.NotEqual(lastId, _sqlserverFixture.SqlServer.Insert(items).ExecuteIdentity()); - } - [Fact] - public void ExecuteInserted() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + //items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //var lastId = g.sqlite.Select().Max(a => a.Id); + //Assert.NotEqual(lastId, _sqlserverFixture.SqlServer.Insert(items).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - var items2 = insert.AppendData(items).ExecuteInserted(); + var items2 = insert.AppendData(items).ExecuteInserted(); - items = Enumerable.Range(0, 90).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - var itemsInserted = _sqlserverFixture.SqlServer.Insert(items).ExecuteInserted(); - Assert.Equal(items.First().Title, itemsInserted.First().Title); - Assert.Equal(items.Last().Title, itemsInserted.Last().Title); - } + items = Enumerable.Range(0, 90).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + var itemsInserted = _sqlserverFixture.SqlServer.Insert(items).ExecuteInserted(); + Assert.Equal(items.First().Title, itemsInserted.First().Title); + Assert.Equal(items.Last().Title, itemsInserted.Last().Title); + } - [Fact] - public void AsTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); - sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); - sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.IgnoreColumns(a => new { a.Title, a.TypeGuid }).InsertColumns(a => a.Title).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.IgnoreColumns(a => new { a.Title, a.TypeGuid }).InsertColumns(a => a.Title).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.IgnoreColumns(a => new { a.CreateTime, a.Title, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); - Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); - } - } + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.Title, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index bdc0325b..09f7855a 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -5,1109 +5,1178 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServer { - [Collection("SqlServerCollection")] - public class SqlServerSelectTest { - - SqlServerFixture _sqlserverFixture; - - public SqlServerSelectTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } - - ISelect select => _sqlserverFixture.SqlServer.Select(); - - [Table(Name = "tb_topic22")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - public partial class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } - - public virtual ICollection Tags { get; set; } - } - public partial class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } - - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } - } - public partial class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public decimal? Ddd { get; set; } - public string Name { get; set; } - - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } - } - - [Fact] - public void AsSelect() { - //OneToOne、ManyToOne - var t0 = _sqlserverFixture.SqlServer.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); - //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 - //FROM [Tag] a - //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] - //LEFT JOIN [Tag] a__Parent__Parent ON a__Parent__Parent.[Id] = a__Parent.[Parent_id] - //WHERE (a__Parent__Parent.[Name] = '粤语') - - //OneToMany - var t1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); - //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] - //FROM [Tag] a - //WHERE (exists(SELECT 1 - // FROM [Tag] t - // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] - // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) - // limit 0,1)) - - //ManyToMany - var t2 = _sqlserverFixture.SqlServer.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); - //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] - //FROM [Song] a - //WHERE(exists(SELECT 1 - // FROM [Song_tag] Mt_Ms - // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 - // FROM [Tag] t - // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) - // limit 0, 1)) - // limit 0, 1)) - } - - [Fact] - public void Lazy() { - var tags = _sqlserverFixture.SqlServer.Select().Where(a => a.Parent.Name == "xxx") - .LeftJoin(a => a.Parent_id == a.Parent.Id) - .ToSql(); - - var songs = _sqlserverFixture.SqlServer.Select().Limit(10).ToList(); - - - } - [Fact] - public void ToDataTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - - Assert.Single(_sqlserverFixture.SqlServer.Insert().AppendData(items.First()).ExecuteInserted()); - Assert.Equal(10, _sqlserverFixture.SqlServer.Insert().AppendData(items).ExecuteInserted().Count); - - //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //; - //Assert.Equal(9989, _sqlserverFixture.SqlServer.Insert(items).NoneParameter().ExecuteAffrows()); - - var dt1 = select.Limit(10).ToDataTable(); - var dt2 = select.Limit(10).ToDataTable("id, getdate()"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); - } - class TestDto { - public int id { get; set; } - public string name { get; set; } //这是join表的属性 - public int ParentId { get; set; } //这是join表的属性 - } - [Fact] - public void ToList() { - - var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto2 = select.Limit(10).ToList(a => new TestDto()); - var testDto3 = select.Limit(10).ToList(a => new TestDto { }); - var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); - - var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); - var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); - var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); - - _sqlserverFixture.SqlServer.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); - var testGuidId5 = _sqlserverFixture.SqlServer.Select().ToList(); - var testGuidId6 = _sqlserverFixture.SqlServer.Select().ToList(a => a.id); - - var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); - var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); - } - class TestGuidIdToList { - public Guid id { get; set; } - public string title { get; set; } = Guid.NewGuid().ToString(); - } - [Fact] - public void ToOne() { - var testnotfind = select.Where("1=2").First(a => a.CreateTime); - Assert.Equal(default(DateTime), testnotfind); - } - [Fact] - public void ToSql() { - } - [Fact] - public void Any() { - var count = select.Where(a => 1 == 1).Count(); - Assert.False(select.Where(a => 1 == 2).Any()); - Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); - - var sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && - select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - //.Offset(a.Id) - .Any() - ).Any(c => c.Id == a.Id + 10) - ); - var sql2222Tolist = sql2222.ToList(); - - var collectionSelect = select.Where(a => - a.Type.Guid == a.TypeGuid && - a.Type.Parent.Id == a.Type.ParentId && - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) - ); - collectionSelect.ToList(); - } - [Fact] - public void Count() { - var count = select.Where(a => 1 == 1).Count(); - select.Where(a => 1 == 1).Count(out var count2); - Assert.Equal(count, count2); - Assert.Equal(0, select.Where(a => 1 == 2).Count()); - } - [Fact] - public void Master() { - Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); - } - - [Fact] - public void From() { - var query2 = select.From((s, b) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - ); - var sql2 = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid]", sql2); - query2.ToList(); - - var query3 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id) - ); - var sql3 = query3.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql3); - query3.ToList(); - } - [Fact] - public void LeftJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); - query.ToList(); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); - query.ToList(); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); - query.ToList(); - } - [Fact] - public void InnerJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); - query.ToList(); - - //������� - query = select - .InnerJoin(a => a.Type.Guid == a.TypeGuid) - .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); - query.ToList(); - - query = select - .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .InnerJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .InnerJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] INNER JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); - query.ToList(); - - } - [Fact] - public void RightJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); - query.ToList(); - - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); - query.ToList(); - - query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); - query.ToList(); - - //������� - query = select - .RightJoin(a => a.Type.Guid == a.TypeGuid) - .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); - query.ToList(); - - query = select - .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .RightJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .RightJoin(a => a.TypeGuid == b.Guid) - .RightJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] RIGHT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query.ToList(); - - query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); - query.ToList(); - - } - [Fact] - public void Where() { - var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); - var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); - var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); - - var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.Where(a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle')", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); - query.ToList(); - - query = select.Where(a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = 'tparent')", sql); - query.ToList(); - - //���û�е������ԣ��򵥶������ - query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'typeTitle')", sql); - query.ToList(); - - query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = 'typeTitle' AND b.[Guid] = a.[TypeGuid])", sql); - query.ToList(); - - query = select.Where((a, b, c) => c.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .Where(a => a.Id == 10 && c.Name == "xxx") - .Where(a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.Where("a.clicks > 100 and a.id = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql); - query.ToList(); - } - [Fact] - public void WhereIf() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.WhereIf(true, a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle')", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(true, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(true, "a.clicks > 100 and a.id = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql); - query.ToList(); - - // ==========================================WhereIf(false) - - //����е�������a.Type��a.Type.Parent ���ǵ������� - query = select.WhereIf(false, a => a.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); - query.ToList(); - - query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - query2 = select.From((s, b, c) => s - .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(false, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(false, "a.clicks > 100 and a.id = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); - query.ToList(); - } - [Fact] - public void WhereExists() { - var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); - - sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - - //.Offset(a.Id) - - .Any() - ).Any() - ).ToList(); - } - [Fact] - public void GroupBy() { - var groupby = select.From((s, b, c) => s - .Where(a => a.Id == 1) - ) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()) - .Offset(10) - .Limit(2) - .ToList(a => new { - a.Key.tt2, - cou1 = a.Count(), - arg1 = a.Avg(a.Key.mod4), - ccc2 = a.Key.tt2 ?? "now()", - //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") - ccc3 = a.Max(a.Value.Item3.Id) - }); - - var testpid1 = _sqlserverFixture.SqlServer.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - _sqlserverFixture.SqlServer.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); - - var aggsql1 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist1 = select - .GroupBy(a => a.Title) - .ToList(b => new { - b.Key, - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToSql(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToList(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql3 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum2 = b.Sum(b.Value.TypeGuid), - sum3 = b.Sum(b.Value.Type.Parent.Id) - }); - } - [Fact] - public void ToAggregate() { - var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(Convert.ToInt64(a.Key.Id)), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - } - [Fact] - public void OrderBy() { - var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); - } - [Fact] - public void Skip_Offset() { - var sql = select.Offset(10).Limit(10).ToList(); - } - [Fact] - public void Take_Limit() { - var sql = select.Limit(10).ToList(); - } - [Fact] - public void Page() { - var sql1 = select.Page(1, 10).ToList(); - var sql2 = select.Page(2, 10).ToList(); - var sql3 = select.Page(3, 10).ToList(); - - var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); - var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); - var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); - } - [Fact] - public void Distinct() { - var t1 = select.Distinct().ToList(a => a.Title); - var t2 = select.Distinct().Limit(10).ToList(a => a.Title); - } - - [Fact] - public void Sum() { - } - [Fact] - public void Min() { - } - [Fact] - public void Max() { - } - [Fact] - public void Avg() { - } - [Fact] - public void As() { - } - - [Fact] - public void AsTable() { - - var listt = select.AsTable((a, b) => "(select * from tb_topic22 where clicks > 10)").Page(1, 10).ToList(); - - Func tableRule = (type, oldname) => { - if (type == typeof(Topic)) return oldname + "AsTable1"; - else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; - return oldname + "AsTable"; - }; - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid]", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); - - query = select - .LeftJoin((a, b) => b.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] c ON c.[Id] = a__Type.[ParentId]", sql); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfoAsTable] c ON b.[ParentId] = c.[Id]", sql); - - //������϶����㲻�� - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); - } - - public class TestInclude_OneToManyModel1 { - [Column(IsIdentity = true)] - public int id { get; set; } - public virtual TestInclude_OneToManyModel2 model2 { get; set; } - - public string m1name { get; set; } - } - public class TestInclude_OneToManyModel2 { - [Column(IsPrimary = true)] - public int model2id { get; set; } - public virtual TestInclude_OneToManyModel1 model1 { get; set; } - - public string m2setting { get; set; } - - public List childs { get; set; } - } - public class TestInclude_OneToManyModel3 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model2111Idaaa { get; set; } - public string title { get; set; } - - public List childs2 { get; set; } - } - public class TestInclude_OneToManyModel4 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model3333Id333 { get; set; } - public string title444 { get; set; } - } - - [Fact] - public void Include_OneToMany() { - var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; - model1.id = (int)_sqlserverFixture.SqlServer.Insert(model1).ExecuteIdentity(); - var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; - _sqlserverFixture.SqlServer.Insert(model2).ExecuteAffrows(); - - var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; - model3_1.id = (int)_sqlserverFixture.SqlServer.Insert(model3_1).ExecuteIdentity(); - var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; - model3_2.id = (int)_sqlserverFixture.SqlServer.Insert(model3_2).ExecuteIdentity(); - var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; - model3_3.id = (int)_sqlserverFixture.SqlServer.Insert(model3_2).ExecuteIdentity(); - - var model4s = new[] { - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } - }; - Assert.Equal(5, _sqlserverFixture.SqlServer.Insert(model4s).ExecuteAffrows()); - - var t0 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t1 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t2 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - - var t00 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t11 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t22 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - } - - public class TestInclude_OneToManyModel11 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2id { get; set; } - public string m3setting { get; set; } - public TestInclude_OneToManyModel22 model2 { get; set; } - public string m1name { get; set; } - } - - public class TestInclude_OneToManyModel22 { - [Column(IsIdentity = true)] - public int id { get; set; } - public string m2setting { get; set; } - public List childs { get; set; } - } - public class TestInclude_OneToManyModel33 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2Id { get; set; } - public string title { get; set; } - public string setting { get; set; } - } - [Fact] - public void Include_OneToMany2() { - string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; - model2.id = (int)_sqlserverFixture.SqlServer.Insert(model2).ExecuteIdentity(); - - var model3s = new[] - { - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} - }; - Assert.Equal(3, _sqlserverFixture.SqlServer.Insert(model3s).ExecuteAffrows()); - - var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; - model1.id = (int)_sqlserverFixture.SqlServer.Insert(model1).ExecuteIdentity(); - - var t1 = _sqlserverFixture.SqlServer.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - - var t11 = _sqlserverFixture.SqlServer.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - } - - [Fact] - public void Include_OneToChilds() { - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_中国" - }; - tag1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1).ExecuteIdentity(); - var tag1_1 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_北京" - }; - tag1_1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1_1).ExecuteIdentity(); - var tag1_2 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_上海" - }; - tag1_2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1_2).ExecuteIdentity(); - - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_美国" - }; - tag2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2).ExecuteIdentity(); - var tag2_1 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_纽约" - }; - tag2_1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2_1).ExecuteIdentity(); - var tag2_2 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_华盛顿" - }; - tag2_2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2_2).ExecuteIdentity(); - - var tags0 = _sqlserverFixture.SqlServer.Select() - .Include(a => a.Parent) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags1 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags2 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags3 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags11 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags22 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags33 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - } - - [Fact] - public void Include_ManyToMany() { - - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_01_中国" - }; - tag1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1).ExecuteIdentity(); - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_02_美国" - }; - tag2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2).ExecuteIdentity(); - var tag3 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_03_日本" - }; - tag3.Id = (int)_sqlserverFixture.SqlServer.Insert(tag3).ExecuteIdentity(); - - var song1 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_01_我是中国人.mp3", - Url = "http://ww.baidu.com/" - }; - song1.Id = (int)_sqlserverFixture.SqlServer.Insert(song1).ExecuteIdentity(); - var song2 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_02_爱你一万年.mp3", - Url = "http://ww.163.com/" - }; - song2.Id = (int)_sqlserverFixture.SqlServer.Insert(song2).ExecuteIdentity(); - var song3 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_03_千年等一回.mp3", - Url = "http://ww.sina.com/" - }; - song3.Id = (int)_sqlserverFixture.SqlServer.Insert(song3).ExecuteIdentity(); - - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); - - var songs1 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs1.Count); - Assert.Equal(2, songs1[0].Tags.Count); - Assert.Equal(1, songs1[1].Tags.Count); - Assert.Equal(3, songs1[2].Tags.Count); - - var songs2 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags, - then => then.IncludeMany(t => t.Songs)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs2.Count); - Assert.Equal(2, songs2[0].Tags.Count); - Assert.Equal(1, songs2[1].Tags.Count); - Assert.Equal(3, songs2[2].Tags.Count); - - var tags3 = _sqlserverFixture.SqlServer.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - - - var songs11 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs11.Count); - Assert.Equal(1, songs11[0].Tags.Count); - Assert.Equal(1, songs11[1].Tags.Count); - Assert.Equal(1, songs11[2].Tags.Count); - - var songs22 = _sqlserverFixture.SqlServer.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.IncludeMany(t => t.Songs.Take(1))) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs22.Count); - Assert.Equal(1, songs22[0].Tags.Count); - Assert.Equal(1, songs22[1].Tags.Count); - Assert.Equal(1, songs22[2].Tags.Count); - - var tags33 = _sqlserverFixture.SqlServer.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs.Take(1)) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - } - } +namespace FreeSql.Tests.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerSelectTest + { + + SqlServerFixture _sqlserverFixture; + + public SqlServerSelectTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } + + ISelect select => _sqlserverFixture.SqlServer.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = _sqlserverFixture.SqlServer.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 + //FROM [Tag] a + //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] + //LEFT JOIN [Tag] a__Parent__Parent ON a__Parent__Parent.[Id] = a__Parent.[Parent_id] + //WHERE (a__Parent__Parent.[Name] = '粤语') + + //OneToMany + var t1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] + //FROM [Tag] a + //WHERE (exists(SELECT 1 + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) + + //ManyToMany + var t2 = _sqlserverFixture.SqlServer.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] + //FROM [Song] a + //WHERE(exists(SELECT 1 + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = _sqlserverFixture.SqlServer.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = _sqlserverFixture.SqlServer.Select().Limit(10).ToList(); + + + } + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Single(_sqlserverFixture.SqlServer.Insert().AppendData(items.First()).ExecuteInserted()); + Assert.Equal(10, _sqlserverFixture.SqlServer.Insert().AppendData(items).ExecuteInserted().Count); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //; + //Assert.Equal(9989, _sqlserverFixture.SqlServer.Insert(items).NoneParameter().ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, getdate()"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + _sqlserverFixture.SqlServer.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = _sqlserverFixture.SqlServer.Select().ToList(); + var testGuidId6 = _sqlserverFixture.SqlServer.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid]", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] INNER JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] RIGHT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = 'typeTitle' AND b.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.clicks > 100 and a.id = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = _sqlserverFixture.SqlServer.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + _sqlserverFixture.SqlServer.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(Convert.ToInt64(a.Key.Id)), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + } + [Fact] + public void Min() + { + } + [Fact] + public void Max() + { + } + [Fact] + public void Avg() + { + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic22 where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid]", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] c ON c.[Id] = a__Type.[ParentId]", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfoAsTable] c ON b.[ParentId] = c.[Id]", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)_sqlserverFixture.SqlServer.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + _sqlserverFixture.SqlServer.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)_sqlserverFixture.SqlServer.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)_sqlserverFixture.SqlServer.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)_sqlserverFixture.SqlServer.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, _sqlserverFixture.SqlServer.Insert(model4s).ExecuteAffrows()); + + var t0 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)_sqlserverFixture.SqlServer.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, _sqlserverFixture.SqlServer.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)_sqlserverFixture.SqlServer.Insert(model1).ExecuteIdentity(); + + var t1 = _sqlserverFixture.SqlServer.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = _sqlserverFixture.SqlServer.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = _sqlserverFixture.SqlServer.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)_sqlserverFixture.SqlServer.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)_sqlserverFixture.SqlServer.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)_sqlserverFixture.SqlServer.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)_sqlserverFixture.SqlServer.Insert(song3).ExecuteIdentity(); + + _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = _sqlserverFixture.SqlServer.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = _sqlserverFixture.SqlServer.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = _sqlserverFixture.SqlServer.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 7522065d..cac3f57b 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -4,135 +4,149 @@ using System; using System.Collections.Generic; using Xunit; -namespace FreeSql.Tests.SqlServer { - [Collection("SqlServerCollection")] - public class SqlServerUpdateTest { +namespace FreeSql.Tests.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerUpdateTest + { - SqlServerFixture _sqlserverFixture; + SqlServerFixture _sqlserverFixture; - public SqlServerUpdateTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public SqlServerUpdateTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - IUpdate update => _sqlserverFixture.SqlServer.Update(); + IUpdate update => _sqlserverFixture.SqlServer.Update(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - - [Fact] - public void Dywhere() { - Assert.Null(_sqlserverFixture.SqlServer.Update().ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); - } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void SetSource() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Clicks] = @p_0, [Title] = @p_1, [CreateTime] = @p_2 WHERE ([Id] = 1)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(_sqlserverFixture.SqlServer.Update().ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = @p_0, [Title] = @p_1, [CreateTime] = @p_2 WHERE ([Id] = 1)", sql); - sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, [Title] = CASE [Id] WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, [CreateTime] = CASE [Id] WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, [Title] = CASE [Id] WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, [CreateTime] = CASE [Id] WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = @p_0 WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void IgnoreColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql); - } - [Fact] - public void UpdateColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql); - } - [Fact] - public void Set() { - var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql); + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0, [CreateTime] = @p_1 WHERE ([Id] = 1)", sql); + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = @p_0 WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql); - sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0, [CreateTime] = @p_1 WHERE ([Id] = 1)", sql); - sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); - int incrv = 10; - sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); - sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); - sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); - sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); - } - [Fact] - public void SetRaw() { - var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + @incrClick WHERE ([Id] = 1)", sql); - } - [Fact] - public void Where() { - var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); - sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE (id = @id)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + @incrClick WHERE ([Id] = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE (id = @id)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); - } - [Fact] - public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteUpdated() { + } + [Fact] + public void ExecuteAffrows() + { - } + } + [Fact] + public void ExecuteUpdated() + { - [Fact] - public void AsTable() { - Assert.Null(_sqlserverFixture.SqlServer.Update().ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - } - } + } + + [Fact] + public void AsTable() + { + Assert.Null(_sqlserverFixture.SqlServer.Update().ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs index fb573c7b..aa6468a1 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs @@ -3,1569 +3,1604 @@ using FreeSql.Tests.DataContext.SqlServer; using System; using Xunit; -namespace FreeSql.Tests.SqlServerMapType { - [Collection("SqlServerCollection")] - public class BoolNullableTest { - - SqlServerFixture _sqlserverFixture; - - public BoolNullableTest(SqlServerFixture sqlserverFixture) { - _sqlserverFixture = sqlserverFixture; - } - - class BoolNullableMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool))] - public bool? tobool { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool? tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool? tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool? toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool? toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool? toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool? tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool? tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool? tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool? tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool? tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool? toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool? toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool? touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool? touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool? toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool? toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool? tostring { get; set; } = true; - } - [Fact] - public void Bool() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item = new BoolNullableMap { tobool = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item = new BoolNullableMap { tobool = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update all - item.tobool = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item.tobool = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item.tobool = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item = new BoolNullableMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item = new BoolNullableMap { tosbyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item.tosbyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item.tosbytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item = new BoolNullableMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item = new BoolNullableMap { toshort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item.toshort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item.toshortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item = new BoolNullableMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item = new BoolNullableMap { toint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item.toint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item = new BoolNullableMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item = new BoolNullableMap { tointnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item.tointnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item = new BoolNullableMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item = new BoolNullableMap { tolong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item.tolong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item.tolongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item = new BoolNullableMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item = new BoolNullableMap { tobyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item.tobyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item.tobytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item = new BoolNullableMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item = new BoolNullableMap { toushort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item.toushort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item.toushortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item = new BoolNullableMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item = new BoolNullableMap { touint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item.touint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item = new BoolNullableMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item = new BoolNullableMap { touintnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item.touintnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item = new BoolNullableMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item = new BoolNullableMap { toulong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item.toulong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item.toulongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item = new BoolNullableMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item = new BoolNullableMap { tostring = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item.tostring = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class BoolNullableTest + { + + SqlServerFixture _sqlserverFixture; + + public BoolNullableTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } + + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs index 99d60295..dd843638 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs @@ -3,1102 +3,1137 @@ using FreeSql.Tests.DataContext.SqlServer; using System; using Xunit; -namespace FreeSql.Tests.SqlServerMapType { - [Collection("SqlServerCollection")] - public class BoolTest { - - SqlServerFixture _sqlserverFixture; - - public BoolTest(SqlServerFixture sqlserverFixture) { - _sqlserverFixture = sqlserverFixture; - } - - class BoolMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool?))] - public bool toboolnullable { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool tostring { get; set; } = true; - } - - [Fact] - public void BoolNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item = new BoolMap { toboolnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update all - item.toboolnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item.toboolnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toboolnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toboolnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item = new BoolMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item = new BoolMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item = new BoolMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item = new BoolMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item = new BoolMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item = new BoolMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item = new BoolMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item = new BoolMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item = new BoolMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item = new BoolMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item = new BoolMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item = new BoolMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item = new BoolMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item = new BoolMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item = new BoolMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item = new BoolMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item = new BoolMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class BoolTest + { + + SqlServerFixture _sqlserverFixture; + + public BoolTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs index f7fc4950..49e629b6 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs @@ -4,260 +4,268 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.SqlServerMapType { - [Collection("SqlServerCollection")] - public class EnumTest { +namespace FreeSql.Tests.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class EnumTest + { - SqlServerFixture _sqlserverFixture; + SqlServerFixture _sqlserverFixture; - public EnumTest(SqlServerFixture sqlserverFixture) { - _sqlserverFixture = sqlserverFixture; - } + public EnumTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - class EnumTestMap { - public Guid id { get; set; } + class EnumTestMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(int))] - public ToStringMapEnum enum_to_int { get; set; } - [Column(MapType = typeof(int?))] - public ToStringMapEnum? enumnullable_to_int { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void EnumToString() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToString() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void EnumToInt() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + [Fact] + public void EnumToInt() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //update all - item.enum_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - item.enum_to_int = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToInt() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); - //update all - item.enumnullable_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); - item.enumnullable_to_int = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs index 5fec98c7..1d5a1c3c 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs @@ -4,562 +4,576 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.SqlServerMapType { - [Collection("SqlServerCollection")] - public class ToStringTest { - SqlServerFixture _sqlserverFixture; +namespace FreeSql.Tests.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class ToStringTest + { + SqlServerFixture _sqlserverFixture; - public ToStringTest(SqlServerFixture sqlserverFixture) { - _sqlserverFixture = sqlserverFixture; - } + public ToStringTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - class ToStringMap { - public Guid id { get; set; } + class ToStringMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan timespan_to_string { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan? timespannullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime datetime_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime? datetimenullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid guid_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid? guidnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger biginteger_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger? bigintegernullable_to_string { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void Enum1() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigInteger1() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(0, find.biginteger_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); - item = new ToStringMap { biginteger_to_string = 100 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(100, find.biginteger_to_string); + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); - //update all - item.biginteger_to_string = 200; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(200, find.biginteger_to_string); + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); - item.biginteger_to_string = 205; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(205, find.biginteger_to_string); + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(522, find.biginteger_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(10005, find.biginteger_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigIntegerNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - item = new ToStringMap { bigintegernullable_to_string = 101 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(101, find.bigintegernullable_to_string); + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); - //update all - item.bigintegernullable_to_string = 2004; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(2004, find.bigintegernullable_to_string); + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); - item.bigintegernullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(998, find.bigintegernullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.bigintegernullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpan1() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); - item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); - //update all - item.timespan_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpanNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); - //update all - item.timespannullable_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); - item.timespannullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.timespannullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTime1() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.MinValue, find.datetime_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); - item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); - //update all - item.datetime_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTimeNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); - //update all - item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); - item.datetimenullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.datetimenullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void Guid1() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(Guid.Empty, find.guid_to_string); + [Fact] + public void Guid1() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guid_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update all - newid = Guid.NewGuid(); - item.guid_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guid_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void GuidNullable() { - //insert - var orm = _sqlserverFixture.SqlServer; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = _sqlserverFixture.SqlServer; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guidnullable_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - //update all - newid = Guid.NewGuid(); - item.guidnullable_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - item.guidnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guidnullable_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.guidnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index b9559070..95a6006c 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -3,91 +3,101 @@ using FreeSql.Tests.DataContext.SqlServer; using System; using Xunit; -namespace FreeSql.Tests.SqlServer { - [Collection("SqlServerCollection")] - public class SqlServerAdoTest - { - SqlServerFixture _sqlserverFixture; +namespace FreeSql.Tests.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerAdoTest + { + SqlServerFixture _sqlserverFixture; - public SqlServerAdoTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public SqlServerAdoTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - [Fact] - public void Pool() { - var t1 = _sqlserverFixture.SqlServer.Ado.MasterPool.StatisticsFullily; - } + [Fact] + public void Pool() + { + var t1 = _sqlserverFixture.SqlServer.Ado.MasterPool.StatisticsFullily; + } - [Fact] - public void SlavePools() { - var t2 = _sqlserverFixture.SqlServer.Ado.SlavePools.Count; - } + [Fact] + public void SlavePools() + { + var t2 = _sqlserverFixture.SqlServer.Ado.SlavePools.Count; + } - [Fact] - public void ExecuteReader() { - - } - [Fact] - public void ExecuteArray() { - - } - [Fact] - public void ExecuteNonQuery() { - - } - [Fact] - public void ExecuteScalar() { - - } + [Fact] + public void ExecuteReader() + { - [Fact] - public void Query() { + } + [Fact] + public void ExecuteArray() + { - //var tt1 = _sqlserverFixture.SqlServer.Select() - // .LeftJoin(a => a.ParentId == a.Parent.Id) - // .ToSql(a => new { a.Id, a.Title }); + } + [Fact] + public void ExecuteNonQuery() + { - //var tt2result = _sqlserverFixture.SqlServer.Select() - // .LeftJoin(a => a.ParentId == a.Parent.Id) - // .ToList(a => new { a.Id, a.Title }); + } + [Fact] + public void ExecuteScalar() + { - //var tt = _sqlserverFixture.SqlServer.Select() - // .LeftJoin((a, b) => b.Id == a.Id) - // .ToSql(a => new { a.Id, a.Title }); + } - //var ttresult = _sqlserverFixture.SqlServer.Select() - // .LeftJoin((a, b) => b.Id == a.Id) - // .ToList(a => new { a.Id, a.Title }); + [Fact] + public void Query() + { - var tnsql1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); - var tnsql2 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToSql(a => a.Id); + //var tt1 = _sqlserverFixture.SqlServer.Select() + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToSql(a => new { a.Id, a.Title }); - var tn1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToList(a => a.Id); - var tn2 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToList(a => a.Id); + //var tt2result = _sqlserverFixture.SqlServer.Select() + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToList(a => new { a.Id, a.Title }); - var t3 = _sqlserverFixture.SqlServer.Ado.Query("select * from xxx"); + //var tt = _sqlserverFixture.SqlServer.Select() + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToSql(a => new { a.Id, a.Title }); - var t4 = _sqlserverFixture.SqlServer.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); + //var ttresult = _sqlserverFixture.SqlServer.Select() + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToList(a => new { a.Id, a.Title }); - var t5 = _sqlserverFixture.SqlServer.Ado.Query(System.Data.CommandType.Text, "select * from xxx where Id = @Id", - new System.Data.SqlClient.SqlParameter("Id", 1)); - } + var tnsql1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + var tnsql2 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToSql(a => a.Id); - [Fact] - public void QueryMultipline() { - var tnsql1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + var tn1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToList(a => a.Id); + var tn2 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToList(a => a.Id); - var t3 = _sqlserverFixture.SqlServer.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); - } + var t3 = _sqlserverFixture.SqlServer.Ado.Query("select * from xxx"); - class xxx { - public int Id { get; set; } - public int ParentId { get; set; } - public xxx Parent { get; set; } - public string Title { get; set; } - public string Url { get; set; } - public DateTime Create_time { get; set; } - } - } + var t4 = _sqlserverFixture.SqlServer.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); + + var t5 = _sqlserverFixture.SqlServer.Ado.Query(System.Data.CommandType.Text, "select * from xxx where Id = @Id", + new System.Data.SqlClient.SqlParameter("Id", 1)); + } + + [Fact] + public void QueryMultipline() + { + var tnsql1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + + var t3 = _sqlserverFixture.SqlServer.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + } + + class xxx + { + public int Id { get; set; } + public int ParentId { get; set; } + public xxx Parent { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime Create_time { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 7d097c0d..e5d79172 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -7,366 +7,380 @@ using System.Linq; using System.Text; using Xunit; -namespace FreeSql.Tests.SqlServer { +namespace FreeSql.Tests.SqlServer +{ + + [Collection("SqlServerCollection")] + public class SqlServerCodeFirstTest + { + + SqlServerFixture _sqlserverFixture; + + public SqlServerCodeFirstTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } + + [Fact] + public void ı_ֶ() + { + var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements<ı>(); + _sqlserverFixture.SqlServer.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, _sqlserverFixture.SqlServer.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = _sqlserverFixture.SqlServer.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + + [Fact] + public void AddUniques() + { + var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + _sqlserverFixture.SqlServer.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } + + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } + + [Fact] + public void AddField() + { + var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + + var id = _sqlserverFixture.SqlServer.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } + + [Table(Name = "dbo2.TopicAddField", OldName = "tedb1.dbo.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int name { get; set; } = 3000; + + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title222 { get; set; } = "333"; + + [Column(DbType = "varchar(200) not null")] + public string title222333 { get; set; } = "xxx"; + + [Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] + public string titleaaa { get; set; } = "fsdf"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + + sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => _sqlserverFixture.SqlServer.Insert(); + ISelect select => _sqlserverFixture.SqlServer.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.GetEncoding("gb2312").GetBytes("й"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(1), + testFieldDateTimeNullableOffset = new DateTimeOffset(DateTime.Now.AddHours(1), TimeSpan.FromHours(8)), + testFieldDateTimeOffset = new DateTimeOffset(DateTime.Now, TimeSpan.FromHours(8)), + testFieldDecimal = 998.99M, + testFieldDecimalNullable = 999.12M, + testFieldDouble = 99.199, + testFieldDoubleNullable = 99.211, + testFieldEnum1 = TableAllTypeEnumType1.e2, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f3, + testFieldEnum2Nullable = TableAllTypeEnumType2.f2, + testFieldFloat = 0.99F, + testFieldFloatNullable = 0.11F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldLong = long.MaxValue, + testFieldSByte = sbyte.MaxValue, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "йstring", + testFieldTimeSpan = TimeSpan.FromSeconds(999), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(30), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; - [Collection("SqlServerCollection")] - public class SqlServerCodeFirstTest { - - SqlServerFixture _sqlserverFixture; - - public SqlServerCodeFirstTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } - - [Fact] - public void ı_ֶ() { - var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements<ı>(); - _sqlserverFixture.SqlServer.CodeFirst.SyncStructure<ı>(); - - var item = new ı { - = "Ա", - ʱ = DateTime.Now - }; - Assert.Equal(1, _sqlserverFixture.SqlServer.Insert<ı>().AppendData(item).ExecuteAffrows()); - Assert.NotEqual(Guid.Empty, item.); - var item2 = _sqlserverFixture.SqlServer.Select<ı>().Where(a => a. == item.).First(); - Assert.NotNull(item2); - Assert.Equal(item., item2.); - Assert.Equal(item., item2.); - } - class ı { - [Column(IsPrimary = true)] - public Guid { get; set; } - - public string { get; set; } - - public DateTime ʱ { get; set; } - } - - - [Fact] - public void AddUniques() { - var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); - _sqlserverFixture.SqlServer.CodeFirst.SyncStructure(); - } - [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - class AddUniquesInfo { - public Guid id { get; set; } - [Column(Unique = "uk_phone")] - public string phone { get; set; } - - [Column(Unique = "uk_group_index, uk_group_index22")] - public string group { get; set; } - [Column(Unique = "uk_group_index")] - public int index { get; set; } - [Column(Unique = "uk_group_index22")] - public string index22 { get; set; } - } - - [Fact] - public void AddField() { - var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); - - var id = _sqlserverFixture.SqlServer.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); - } - - [Table(Name = "dbo2.TopicAddField", OldName = "tedb1.dbo.TopicAddField")] - public class TopicAddField { - [Column(IsIdentity = true)] - public int Id { get; set; } - - public int name { get; set; } = 3000; - - [Column(DbType = "varchar(200) not null", OldName = "title")] - public string title222 { get; set; } = "333"; - - [Column(DbType = "varchar(200) not null")] - public string title222333 { get; set; } = "xxx"; - - [Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] - public string titleaaa { get; set; } = "fsdf"; - - [Column(IsIgnore = true)] - public DateTime ct { get; set; } = DateTime.Now; - } - - [Fact] - public void GetComparisonDDLStatements() { + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); - var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); - - sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); - } + var item3 = insert.AppendData(item2).ExecuteInserted(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); - IInsert insert => _sqlserverFixture.SqlServer.Insert(); - ISelect select => _sqlserverFixture.SqlServer.Select(); + var items = select.ToList(); + } - [Fact] - public void CurdAllField() { - var item = new TableAllType { }; - item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + [JsonObject(MemberSerialization.OptIn), Table(Name = "dbo.tb_alltype")] + public partial class Tb_alltype + { - var newitem = select.Where(a => a.Id == item.Id).ToOne(); + [JsonProperty, Column(Name = "Id", DbType = "int", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } - var item2 = new TableAllType { - testFieldBool = true, - testFieldBoolNullable = true, - testFieldByte = byte.MaxValue, - testFieldByteNullable = byte.MinValue, - testFieldBytes = Encoding.GetEncoding("gb2312").GetBytes("й"), - testFieldDateTime = DateTime.Now, - testFieldDateTimeNullable = DateTime.Now.AddHours(1), - testFieldDateTimeNullableOffset = new DateTimeOffset(DateTime.Now.AddHours(1), TimeSpan.FromHours(8)), - testFieldDateTimeOffset = new DateTimeOffset(DateTime.Now, TimeSpan.FromHours(8)), - testFieldDecimal = 998.99M, - testFieldDecimalNullable = 999.12M, - testFieldDouble = 99.199, - testFieldDoubleNullable = 99.211, - testFieldEnum1 = TableAllTypeEnumType1.e2, - testFieldEnum1Nullable = TableAllTypeEnumType1.e3, - testFieldEnum2 = TableAllTypeEnumType2.f3, - testFieldEnum2Nullable = TableAllTypeEnumType2.f2, - testFieldFloat = 0.99F, - testFieldFloatNullable = 0.11F, - testFieldGuid = Guid.NewGuid(), - testFieldGuidNullable = Guid.NewGuid(), - testFieldInt = int.MaxValue, - testFieldIntNullable = int.MinValue, - testFieldLong = long.MaxValue, - testFieldSByte = sbyte.MaxValue, - testFieldSByteNullable = sbyte.MinValue, - testFieldShort = short.MaxValue, - testFieldShortNullable = short.MinValue, - testFieldString = "йstring", - testFieldTimeSpan = TimeSpan.FromSeconds(999), - testFieldTimeSpanNullable = TimeSpan.FromSeconds(30), - testFieldUInt = uint.MaxValue, - testFieldUIntNullable = uint.MinValue, - testFieldULong = ulong.MaxValue, - testFieldULongNullable = ulong.MinValue, - testFieldUShort = ushort.MaxValue, - testFieldUShortNullable = ushort.MinValue, - testFielLongNullable = long.MinValue - }; - var sqlPar = insert.AppendData(item2).ToSql(); - var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + [JsonProperty, Column(Name = "testFieldBool1111", DbType = "bit")] + public bool TestFieldBool1111 { get; set; } - var item3 = insert.AppendData(item2).ExecuteInserted(); - var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); - var items = select.ToList(); - } + [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit", IsNullable = true)] + public bool? TestFieldBoolNullable { get; set; } - [JsonObject(MemberSerialization.OptIn), Table(Name = "dbo.tb_alltype")] - public partial class Tb_alltype { - [JsonProperty, Column(Name = "Id", DbType = "int", IsPrimary = true, IsIdentity = true)] - public int Id { get; set; } + [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint")] + public sbyte TestFieldByte { get; set; } - [JsonProperty, Column(Name = "testFieldBool1111", DbType = "bit")] - public bool TestFieldBool1111 { get; set; } + [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint", IsNullable = true)] + public sbyte? TestFieldByteNullable { get; set; } - [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit", IsNullable = true)] - public bool? TestFieldBoolNullable { get; set; } + [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] + public byte[] TestFieldBytes { get; set; } - [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint")] - public sbyte TestFieldByte { get; set; } + [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] + public DateTime TestFieldDateTime { get; set; } - [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint", IsNullable = true)] - public sbyte? TestFieldByteNullable { get; set; } + [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] + public DateTime? TestFieldDateTimeNullable { get; set; } - [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] - public byte[] TestFieldBytes { get; set; } + [JsonProperty, Column(Name = "testFieldDateTimeNullableOffset", DbType = "datetimeoffset", IsNullable = true)] + public DateTime? TestFieldDateTimeNullableOffset { get; set; } - [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] - public DateTime TestFieldDateTime { get; set; } + [JsonProperty, Column(Name = "testFieldDateTimeOffset", DbType = "datetimeoffset")] + public DateTime TestFieldDateTimeOffset { get; set; } - [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] - public DateTime? TestFieldDateTimeNullable { get; set; } + [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] + public decimal TestFieldDecimal { get; set; } - [JsonProperty, Column(Name = "testFieldDateTimeNullableOffset", DbType = "datetimeoffset", IsNullable = true)] - public DateTime? TestFieldDateTimeNullableOffset { get; set; } + [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] + public decimal? TestFieldDecimalNullable { get; set; } - [JsonProperty, Column(Name = "testFieldDateTimeOffset", DbType = "datetimeoffset")] - public DateTime TestFieldDateTimeOffset { get; set; } + [JsonProperty, Column(Name = "testFieldDouble", DbType = "float")] + public double TestFieldDouble { get; set; } - [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] - public decimal TestFieldDecimal { get; set; } + [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "float", IsNullable = true)] + public double? TestFieldDoubleNullable { get; set; } - [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] - public decimal? TestFieldDecimalNullable { get; set; } + [JsonProperty, Column(Name = "testFieldEnum1", DbType = "int")] + public int TestFieldEnum1 { get; set; } - [JsonProperty, Column(Name = "testFieldDouble", DbType = "float")] - public double TestFieldDouble { get; set; } + [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "int", IsNullable = true)] + public int? TestFieldEnum1Nullable { get; set; } - [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "float", IsNullable = true)] - public double? TestFieldDoubleNullable { get; set; } + [JsonProperty, Column(Name = "testFieldEnum2", DbType = "bigint")] + public long TestFieldEnum2 { get; set; } - [JsonProperty, Column(Name = "testFieldEnum1", DbType = "int")] - public int TestFieldEnum1 { get; set; } + [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "bigint", IsNullable = true)] + public long? TestFieldEnum2Nullable { get; set; } - [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "int", IsNullable = true)] - public int? TestFieldEnum1Nullable { get; set; } + [JsonProperty, Column(Name = "testFieldFloat", DbType = "real")] + public float TestFieldFloat { get; set; } - [JsonProperty, Column(Name = "testFieldEnum2", DbType = "bigint")] - public long TestFieldEnum2 { get; set; } + [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "real", IsNullable = true)] + public float? TestFieldFloatNullable { get; set; } - [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "bigint", IsNullable = true)] - public long? TestFieldEnum2Nullable { get; set; } + [JsonProperty, Column(Name = "testFieldGuid", DbType = "uniqueidentifier")] + public Guid TestFieldGuid { get; set; } - [JsonProperty, Column(Name = "testFieldFloat", DbType = "real")] - public float TestFieldFloat { get; set; } + [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "uniqueidentifier", IsNullable = true)] + public Guid? TestFieldGuidNullable { get; set; } - [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "real", IsNullable = true)] - public float? TestFieldFloatNullable { get; set; } + [JsonProperty, Column(Name = "testFieldInt", DbType = "int")] + public int TestFieldInt { get; set; } - [JsonProperty, Column(Name = "testFieldGuid", DbType = "uniqueidentifier")] - public Guid TestFieldGuid { get; set; } + [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int", IsNullable = true)] + public int? TestFieldIntNullable { get; set; } - [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "uniqueidentifier", IsNullable = true)] - public Guid? TestFieldGuidNullable { get; set; } + [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint")] + public long TestFieldLong { get; set; } - [JsonProperty, Column(Name = "testFieldInt", DbType = "int")] - public int TestFieldInt { get; set; } + [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint")] + public sbyte TestFieldSByte { get; set; } - [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int", IsNullable = true)] - public int? TestFieldIntNullable { get; set; } + [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint", IsNullable = true)] + public sbyte? TestFieldSByteNullable { get; set; } - [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint")] - public long TestFieldLong { get; set; } + [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint")] + public short TestFieldShort { get; set; } - [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint")] - public sbyte TestFieldSByte { get; set; } + [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint", IsNullable = true)] + public short? TestFieldShortNullable { get; set; } - [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint", IsNullable = true)] - public sbyte? TestFieldSByteNullable { get; set; } + [JsonProperty, Column(Name = "testFieldString", DbType = "nvarchar(255)", IsNullable = true)] + public string TestFieldString { get; set; } - [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint")] - public short TestFieldShort { get; set; } + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] + public TimeSpan TestFieldTimeSpan { get; set; } - [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint", IsNullable = true)] - public short? TestFieldShortNullable { get; set; } + [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] + public TimeSpan? TestFieldTimeSpanNullable { get; set; } - [JsonProperty, Column(Name = "testFieldString", DbType = "nvarchar(255)", IsNullable = true)] - public string TestFieldString { get; set; } + [JsonProperty, Column(Name = "testFieldUInt", DbType = "int")] + public int TestFieldUInt { get; set; } - [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] - public TimeSpan TestFieldTimeSpan { get; set; } + [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int", IsNullable = true)] + public int? TestFieldUIntNullable { get; set; } - [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] - public TimeSpan? TestFieldTimeSpanNullable { get; set; } + [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint")] + public long TestFieldULong { get; set; } - [JsonProperty, Column(Name = "testFieldUInt", DbType = "int")] - public int TestFieldUInt { get; set; } + [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint", IsNullable = true)] + public long? TestFieldULongNullable { get; set; } - [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int", IsNullable = true)] - public int? TestFieldUIntNullable { get; set; } + [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint")] + public short TestFieldUShort { get; set; } - [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint")] - public long TestFieldULong { get; set; } + [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint", IsNullable = true)] + public short? TestFieldUShortNullable { get; set; } - [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint", IsNullable = true)] - public long? TestFieldULongNullable { get; set; } + [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint", IsNullable = true)] + public long? TestFielLongNullable { get; set; } + } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint")] - public short TestFieldUShort { get; set; } + [Column(Name = "testFieldBool1111")] + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public DateTimeOffset testFieldDateTimeOffset { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } + public Guid? testFieldGuidNullable { get; set; } - [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint", IsNullable = true)] - public short? TestFieldUShortNullable { get; set; } + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } - - [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint", IsNullable = true)] - public long? TestFielLongNullable { get; set; } - } - - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - - [Column(Name = "testFieldBool1111")] - public bool testFieldBool { get; set; } - public sbyte testFieldSByte { get; set; } - public short testFieldShort { get; set; } - public int testFieldInt { get; set; } - public long testFieldLong { get; set; } - public byte testFieldByte { get; set; } - public ushort testFieldUShort { get; set; } - public uint testFieldUInt { get; set; } - public ulong testFieldULong { get; set; } - public double testFieldDouble { get; set; } - public float testFieldFloat { get; set; } - public decimal testFieldDecimal { get; set; } - public TimeSpan testFieldTimeSpan { get; set; } - public DateTime testFieldDateTime { get; set; } - public DateTimeOffset testFieldDateTimeOffset { get; set; } - public byte[] testFieldBytes { get; set; } - public string testFieldString { get; set; } - public Guid testFieldGuid { get; set; } - - public bool? testFieldBoolNullable { get; set; } - public sbyte? testFieldSByteNullable { get; set; } - public short? testFieldShortNullable { get; set; } - public int? testFieldIntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? testFieldByteNullable { get; set; } - public ushort? testFieldUShortNullable { get; set; } - public uint? testFieldUIntNullable { get; set; } - public ulong? testFieldULongNullable { get; set; } - public double? testFieldDoubleNullable { get; set; } - public float? testFieldFloatNullable { get; set; } - public decimal? testFieldDecimalNullable { get; set; } - public TimeSpan? testFieldTimeSpanNullable { get; set; } - public DateTime? testFieldDateTimeNullable { get; set; } - public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } - public Guid? testFieldGuidNullable { get; set; } - - public TableAllTypeEnumType1 testFieldEnum1 { get; set; } - public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } - public TableAllTypeEnumType2 testFieldEnum2 { get; set; } - public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - } - - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs index 1cac9136..43227e68 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs @@ -3,29 +3,33 @@ using FreeSql.Tests.DataContext.SqlServer; using System; using Xunit; -namespace FreeSql.Tests.SqlServer { - [Collection("SqlServerCollection")] - public class SqlServerDbFirstTest { +namespace FreeSql.Tests.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerDbFirstTest + { - SqlServerFixture _sqlserverFixture; + SqlServerFixture _sqlserverFixture; - public SqlServerDbFirstTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public SqlServerDbFirstTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - [Fact] - public void GetDatabases() { + [Fact] + public void GetDatabases() + { - var t1 = _sqlserverFixture.SqlServer.DbFirst.GetDatabases(); + var t1 = _sqlserverFixture.SqlServer.DbFirst.GetDatabases(); - } + } - [Fact] - public void GetTablesByDatabase() { + [Fact] + public void GetTablesByDatabase() + { - var t2 = _sqlserverFixture.SqlServer.DbFirst.GetTablesByDatabase(); + var t2 = _sqlserverFixture.SqlServer.DbFirst.GetTablesByDatabase(); - } - } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs index f5ed9207..f8abe2ed 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs @@ -5,151 +5,174 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServerExpression { - [Collection("SqlServerCollection")] - public class ConvertTest { +namespace FreeSql.Tests.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class ConvertTest + { - SqlServerFixture _sqlserverFixture; + SqlServerFixture _sqlserverFixture; - public ConvertTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public ConvertTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => _sqlserverFixture.SqlServer.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void ToBoolean() { - var data = new List(); - data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); - data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); - } - [Fact] - public void ToByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); - data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); - } - [Fact] - public void ToChar() { - var data = new List(); - data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); - data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); - } - [Fact] - public void ToDateTime() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); - } - [Fact] - public void ToDecimal() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToDouble() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt32() { - var data = new List(); - data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); - data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToSByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); - data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); - } - [Fact] - public void ToSingle() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); - data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); - } - [Fact] - public void ToUInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt32() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); - } + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } - [Fact] - public void Guid_Parse() { - var data = new List(); - data.Add(select.Where(a => Guid.Parse(Guid.NewGuid().ToString()) == Guid.Empty).ToList()); - } + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.NewGuid().ToString()) == Guid.Empty).ToList()); + } - [Fact] - public void Guid_NewGuid() { - var data = new List(); - data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); - } + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } - [Fact] - public void Random() { - var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); - } - } + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs index ef9d4708..1f36c181 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -5,288 +5,326 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServerExpression { - [Collection("SqlServerCollection")] - public class DateTimeTest - { - SqlServerFixture _sqlserverFixture; +namespace FreeSql.Tests.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class DateTimeTest + { + SqlServerFixture _sqlserverFixture; - public DateTimeTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public DateTimeTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => _sqlserverFixture.SqlServer.Select(); - [Table(Name = "tb_topic111333")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - [Table(Name = "TestTypeInfo333")] - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - public DateTime Time { get; set; } - } - [Table(Name = "TestTypeParentInfo23123")] - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - public DateTime Time2 { get; set; } - } - [Fact] - public void Now() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - } - [Fact] - public void UtcNow() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); - } - [Fact] - public void Date() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); - } - [Fact] - public void TimeOfDay() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - } - [Fact] - public void DayOfWeek() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - } - [Fact] - public void Day() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); - } - [Fact] - public void DayOfYear() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); - } - [Fact] - public void Month() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); - } - [Fact] - public void Year() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); - } - [Fact] - public void Hour() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); - } - [Fact] - public void Minute() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); - } - [Fact] - public void Second() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); - } - [Fact] - public void Millisecond() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - } - [Fact] - public void AddDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); - } - [Fact] - public void AddHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); - } - [Fact] - public void AddMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); - } - [Fact] - public void AddMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); - } - [Fact] - public void AddMonths() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); - } - [Fact] - public void AddSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); - } - [Fact] - public void AddTicks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); - } - [Fact] - public void AddYears() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - } - [Fact] - public void _ЧͬSubtract() { - var data = new List(); - data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - } + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + } - [Fact] - public void DateTime_Compare() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - } - [Fact] - public void DateTime_DaysInMonth() { - var data = new List(); - data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); - } - [Fact] - public void DateTime_Equals() { - var data = new List(); - data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); - } - [Fact] - public void DateTime_IsLeapYear() { - var data = new List(); - data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); - } - [Fact] - public void DateTime_Parse() { - var data = new List(); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); - } - } + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs index 7bab4502..87481aeb 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs @@ -5,137 +5,160 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServerExpression { - [Collection("SqlServerCollection")] - public class MathTest - { - SqlServerFixture _sqlserverFixture; +namespace FreeSql.Tests.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class MathTest + { + SqlServerFixture _sqlserverFixture; - public MathTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public MathTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => _sqlserverFixture.SqlServer.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void PI() { - var data = new List(); - data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); - } - [Fact] - public void Abs() { - var data = new List(); - data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Sign() { - var data = new List(); - data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Floor() { - var data = new List(); - data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); - } - [Fact] - public void Ceiling() { - var data = new List(); - data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Round() { - var data = new List(); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); - } - [Fact] - public void Exp() { - var data = new List(); - data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log() { - //var data = new List(); - //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log10() { - //var data = new List(); - //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Pow() { - var data = new List(); - //data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sqrt() { - var data = new List(); - //data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Cos() { - var data = new List(); - //data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sin() { - var data = new List(); - //data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Tan() { - var data = new List(); - //data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Acos() { - var data = new List(); - //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Asin() { - var data = new List(); - //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan() { - var data = new List(); - //data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan2() { - var data = new List(); - //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Truncate() { - var data = new List(); - data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); - } - } + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + //data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + //data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + //data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs index 9e480695..ef10ff43 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs @@ -5,113 +5,118 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServerExpression { - [Collection("SqlServerCollection")] - public class OtherTest { +namespace FreeSql.Tests.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class OtherTest + { - SqlServerFixture _sqlserverFixture; + SqlServerFixture _sqlserverFixture; - public OtherTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public OtherTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => _sqlserverFixture.SqlServer.Select(); - [Fact] - public void Boolean() { - var t1 = select.Where(a => a.testFieldBool == true).ToList(); - var t2 = select.Where(a => a.testFieldBool != true).ToList(); - var t3 = select.Where(a => a.testFieldBool == false).ToList(); - var t4 = select.Where(a => !a.testFieldBool).ToList(); - var t5 = select.Where(a => a.testFieldBool).ToList(); + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); - var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); - var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); - var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); - var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); - var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); - } + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } - [Fact] - public void Array() { - IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); - var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); - //in not in - var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); - var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var inarray = new[] { 1, 2, 3 }; - var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); - var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); - //in not in - var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); - var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); - var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); - var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); - var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); - var inarray2 = new List() { 1, 2, 3 }; - var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); - var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); - } + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - [Column(Name = "testFieldBool1111")] - public bool testFieldBool { get; set; } - public sbyte testFieldSByte { get; set; } - public short testFieldShort { get; set; } - public int testFieldInt { get; set; } - public long testFieldLong { get; set; } - public byte testFieldByte { get; set; } - public ushort testFieldUShort { get; set; } - public uint testFieldUInt { get; set; } - public ulong testFieldULong { get; set; } - public double testFieldDouble { get; set; } - public float testFieldFloat { get; set; } - public decimal testFieldDecimal { get; set; } - public TimeSpan testFieldTimeSpan { get; set; } - public DateTime testFieldDateTime { get; set; } - public DateTimeOffset testFieldDateTimeOffset { get; set; } - public byte[] testFieldBytes { get; set; } - public string testFieldString { get; set; } - public Guid testFieldGuid { get; set; } + [Column(Name = "testFieldBool1111")] + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public DateTimeOffset testFieldDateTimeOffset { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } - public bool? testFieldBoolNullable { get; set; } - public sbyte? testFieldSByteNullable { get; set; } - public short? testFieldShortNullable { get; set; } - public int? testFieldIntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? testFieldByteNullable { get; set; } - public ushort? testFieldUShortNullable { get; set; } - public uint? testFieldUIntNullable { get; set; } - public ulong? testFieldULongNullable { get; set; } - public double? testFieldDoubleNullable { get; set; } - public float? testFieldFloatNullable { get; set; } - public decimal? testFieldDecimalNullable { get; set; } - public TimeSpan? testFieldTimeSpanNullable { get; set; } - public DateTime? testFieldDateTimeNullable { get; set; } - public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } - public Guid? testFieldGuidNullable { get; set; } + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } + public Guid? testFieldGuidNullable { get; set; } - public TableAllTypeEnumType1 testFieldEnum1 { get; set; } - public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } - public TableAllTypeEnumType2 testFieldEnum2 { get; set; } - public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - } + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index 1338612a..3cd5b5d9 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -5,261 +5,285 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServerExpression { - [Collection("SqlServerCollection")] - public class StringTest { +namespace FreeSql.Tests.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class StringTest + { - SqlServerFixture _sqlserverFixture; + SqlServerFixture _sqlserverFixture; - public StringTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public StringTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => _sqlserverFixture.SqlServer.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } - class TestEqualsGuid { - public Guid id { get; set; } - } + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } - [Fact] - public void Equals__() { - var list = new List(); - list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); - list.Add(_sqlserverFixture.SqlServer.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); - } + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(_sqlserverFixture.SqlServer.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } - [Fact] - public void Empty() { - var data = new List(); - data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); - } + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + } - [Fact] - public void StartsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); - } - [Fact] - public void EndsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); - } - [Fact] - public void Contains() { - var list = new List(); - list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); - } - [Fact] - public void ToLower() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); - } - [Fact] - public void ToUpper() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); - } - [Fact] - public void Substring() { - var data = new List(); - data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); - } - [Fact] - public void Length() { - var data = new List(); - data.Add(select.Where(a => a.Title.Length == 0).ToList()); - data.Add(select.Where(a => a.Title.Length == 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); - } - [Fact] - public void IndexOf() { - var data = new List(); - data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - } - [Fact] - public void PadLeft() { - //var data = new List(); - //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); - //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); - //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); - //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + } + [Fact] + public void PadLeft() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); - //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); - //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); - //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); - //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); - } - [Fact] - public void PadRight() { - //var data = new List(); - //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); - //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); - //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); - //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + } + [Fact] + public void PadRight() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); - //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); - //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); - //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); - //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); - } - [Fact] - public void Trim() { - var data = new List(); - data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); - data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); - } - [Fact] - public void TrimStart() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - } - [Fact] - public void TrimEnd() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - } - [Fact] - public void Replace() { - var data = new List(); - data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - } - [Fact] - public void CompareTo() { - //var data = new List(); - //data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); - //data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); - //data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); - //data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void CompareTo() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); - //data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); - //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); - //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); - //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); - } + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + } - [Fact] - public void string_IsNullOrEmpty() { - var data = new List(); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); - //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); - data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); - } - } + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs index 7490b5ea..7d5b6779 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs @@ -5,181 +5,214 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqlServerExpression { - [Collection("SqlServerCollection")] - public class TimeSpanTest { +namespace FreeSql.Tests.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class TimeSpanTest + { - SqlServerFixture _sqlserverFixture; + SqlServerFixture _sqlserverFixture; - public TimeSpanTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } + public TimeSpanTest(SqlServerFixture sqlserverFixture) + { + _sqlserverFixture = sqlserverFixture; + } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => _sqlserverFixture.SqlServer.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } - [Fact] - public void Zero() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); - } - [Fact] - public void Days() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); - } - [Fact] - public void Hours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); - } - [Fact] - public void Milliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); - } - [Fact] - public void Minutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); - } - [Fact] - public void Seconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); - } - [Fact] - public void TotalDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); - } - [Fact] - public void TotalHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); - } - [Fact] - public void TotalMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); - } - [Fact] - public void TotalMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); - } - [Fact] - public void TotalSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); - } + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + } - [Fact] - public void TimeSpan_Compare() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); - } - [Fact] - public void TimeSpan_Equals() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - } - [Fact] - public void TimeSpan_FromDays() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - } - [Fact] - public void TimeSpan_FromHours() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); - } - [Fact] - public void TimeSpan_FromMilliseconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); - } - [Fact] - public void TimeSpan_FromMinutes() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); - } - [Fact] - public void TimeSpan_FromSeconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); - } - [Fact] - public void TimeSpan_FromTicks() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); - } - [Fact] - public void TimeSpan_Parse() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); - } - } + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs index fca1ae13..8a58358e 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs @@ -4,86 +4,95 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.Sqlite { - public class SqliteDeleteTest { +namespace FreeSql.Tests.Sqlite +{ + public class SqliteDeleteTest + { - IDelete delete => g.sqlite.Delete(); //�������� + IDelete delete => g.sqlite.Delete(); //�������� - [Table(Name = "tb_topic22211")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void Dywhere() { - Assert.Null(g.sqlite.Delete().ToSql()); - var sql = g.sqlite.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); + [Fact] + public void Dywhere() + { + Assert.Null(g.sqlite.Delete().ToSql()); + var sql = g.sqlite.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); - sql = g.sqlite.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); + sql = g.sqlite.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); - sql = g.sqlite.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); + sql = g.sqlite.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); - sql = g.sqlite.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); - } + sql = g.sqlite.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); + } - [Fact] - public void Where() { - var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); - sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (id = @id)", sql); + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (id = @id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - var id = g.sqlite.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); - Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); - } - [Fact] - public void ExecuteDeleted() { + var id = g.sqlite.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { - //var item = g.Sqlite.Delete(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); - //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); - } + //var item = g.Sqlite.Delete(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } - [Fact] - public void AsTable() { - Assert.Null(g.sqlite.Delete().AsTable(a => "TopicAsTable").ToSql()); - var sql = g.sqlite.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); + [Fact] + public void AsTable() + { + Assert.Null(g.sqlite.Delete().AsTable(a => "TopicAsTable").ToSql()); + var sql = g.sqlite.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); - sql = g.sqlite.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1)", sql); + sql = g.sqlite.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1)", sql); - sql = g.sqlite.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); + sql = g.sqlite.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); - sql = g.sqlite.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1)", sql); - } - } + sql = g.sqlite.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs index c400746d..57b3b869 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs @@ -4,108 +4,118 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.Sqlite { - public class SqliteInsertTest { +namespace FreeSql.Tests.Sqlite +{ + public class SqliteInsertTest + { - IInsert insert => g.sqlite.Insert(); + IInsert insert => g.sqlite.Insert(); - [Table(Name = "tb_topic_insert")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void AppendData() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); - sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - } + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + } - [Fact] - public void InsertColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - } - [Fact] - public void IgnoreColumns() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); - } - [Fact] - public void ExecuteAffrows() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); - } - [Fact] - public void ExecuteIdentity() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); - } - [Fact] - public void ExecuteInserted() { - } + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + } - [Fact] - public void AsTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); - var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); - sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\", \"CreateTime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); - sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\", \"Title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); - sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); - } - } + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"Clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index de328f03..c943800d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -4,1075 +4,1146 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.Sqlite { - public class SqliteSelectTest { - - ISelect select => g.sqlite.Select(); - - [Table(Name = "tb_topic22")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - - public partial class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } - - public virtual ICollection Tags { get; set; } - } - public partial class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } - - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } - } - public partial class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public decimal? Ddd { get; set; } - public string Name { get; set; } - - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } - } - - [Fact] - public void AsSelect() { - //OneToOne、ManyToOne - var t0 = g.sqlite.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 - //FROM `Tag` a - //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` - //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` - //WHERE (a__Parent__Parent.`Name` = '粤语') - - //OneToMany - var t1 = g.sqlite.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); - //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` - //FROM `Tag` a - //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) - - //ManyToMany - var t2 = g.sqlite.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); - //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` - //FROM `Song` a - //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) - } - - [Fact] - public void Lazy() { - var tags = g.sqlite.Select().Where(a => a.Parent.Name == "xxx") - .LeftJoin(a => a.Parent_id == a.Parent.Id) - .ToSql(); - - var songs = g.sqlite.Select().Limit(10).ToList(); - - - } - - [Fact] - public void ToDataTable() { - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - - Assert.Equal(1, g.sqlite.Insert().AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, g.sqlite.Insert().AppendData(items).ExecuteAffrows()); - - //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //Assert.Equal(9989, g.sqlite.Insert(items).ExecuteAffrows()); - - var dt1 = select.Limit(10).ToDataTable(); - var dt2 = select.Limit(10).ToDataTable("id, 111222"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); - } - class TestDto { - public int id { get; set; } - public string name { get; set; } //这是join表的属性 - public int ParentId { get; set; } //这是join表的属性 - - public bool? testBool1 { get; set; } - public bool? testBool2 { get; set; } - } - class TestDtoLeftJoin { - [Column(IsPrimary = true)] - public int Guid { get; set; } - public bool? testBool1 { get; set; } - public bool? testBool2 { get; set; } - } - [Fact] - public void ToList() { - - g.sqlite.Delete().Where("1=1").ExecuteAffrows(); - var testlist = select.Limit(10).ToList(); - foreach(var testitem in testlist) { - var testdtolj = new TestDtoLeftJoin { Guid = testitem.TypeGuid, testBool1 = true }; - if (g.sqlite.Select().Where(a => a.Guid == testitem.TypeGuid).Any() == false) - g.sqlite.Insert(testdtolj).ExecuteAffrows(); - } - - var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto2 = select.Limit(10).ToList(a => new TestDto()); - var testDto3 = select.Limit(10).ToList(a => new TestDto { }); - var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); - - var testDto11 = select.LeftJoin((a,b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto22 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); - var testDto33 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); - var testDto44 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); - - g.sqlite.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); - var testGuidId5 = g.sqlite.Select().ToList(); - var testGuidId6 = g.sqlite.Select().ToList(a => a.id); - - var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); - var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); - } - class TestGuidIdToList { - public Guid id { get; set; } - public string title { get; set; } = Guid.NewGuid().ToString(); - } - [Fact] - public void ToOne() { - var testnotfind = select.Where("1=2").First(a => a.CreateTime); - Assert.Equal(default(DateTime), testnotfind); - } - [Fact] - public void ToSql() { - } - [Fact] - public void Any() { - var count = select.Where(a => 1 == 1).Count(); - Assert.False(select.Where(a => 1 == 2).Any()); - Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); - - var sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && - select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - //.Offset(a.Id) - .Any() - ).Any(c => c.Id == a.Id + 10) - ); - var sql2222Tolist = sql2222.ToList(); - - var collectionSelect = select.Where(a => - a.Type.Guid == a.TypeGuid && - a.Type.Parent.Id == a.Type.ParentId && - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) - ); - collectionSelect.ToList(); - } - [Fact] - public void Count() { - var count = select.Where(a => 1 == 1).Count(); - select.Where(a => 1 == 1).Count(out var count2); - Assert.Equal(count, count2); - Assert.Equal(0, select.Where(a => 1 == 2).Count()); - } - [Fact] - public void Master() { - Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); - } - [Fact] - public void From() { - var query2 = select.From((s, b) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - ); - var sql2 = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON a.\"TypeGuid\" = b.\"Guid\"", sql2); - query2.ToList(); - - var query3 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id) - ); - var sql3 = query3.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON a.\"TypeGuid\" = b.\"Guid\" LEFT JOIN \"TestTypeParentInfo\" c ON b.\"ParentId\" = c.\"Id\"", sql3); - query3.ToList(); - } - [Fact] - public void LeftJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\"", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON b.\"Guid\" = a.\"TypeGuid\"", sql); - query.ToList(); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON b.\"Guid\" = a.\"TypeGuid\" AND b.\"Name\" = 'xxx'", sql); - query.ToList(); - - query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); - query.ToList(); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\"", sql); - query.ToList(); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfo\" c ON c.\"Id\" = a__Type.\"ParentId\"", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON a.\"TypeGuid\" = b.\"Guid\" LEFT JOIN \"TestTypeParentInfo\" c ON b.\"ParentId\" = c.\"Id\"", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\""); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\"", sql); - query.ToList(); - - query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", sql); - query.ToList(); - } - [Fact] - public void InnerJoin() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\"", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); - query.ToList(); - - //���û�е������� - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b ON b.\"Guid\" = a.\"TypeGuid\"", sql); - query.ToList(); - - query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b ON b.\"Guid\" = a.\"TypeGuid\" AND b.\"Name\" = 'xxx'", sql); - query.ToList(); - - query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); - query.ToList(); - - //������� - query = select - .InnerJoin(a => a.Type.Guid == a.TypeGuid) - .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" INNER JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\"", sql); - query.ToList(); - - query = select - .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .InnerJoin((a, c) => c.Id == a.Type.ParentId); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" INNER JOIN \"TestTypeParentInfo\" c ON c.\"Id\" = a__Type.\"ParentId\"", sql); - query.ToList(); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .InnerJoin(a => b.ParentId == c.Id)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b ON a.\"TypeGuid\" = b.\"Guid\" INNER JOIN \"TestTypeParentInfo\" c ON b.\"ParentId\" = c.\"Id\"", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.InnerJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\""); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\"", sql); - query.ToList(); - - query = select.InnerJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", sql); - query.ToList(); - - } - [Fact] - public void RightJoin() { - - } - [Fact] - public void Where() { - var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); - var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); - var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); - - var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.Where(a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Id\" = 10)", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE ((a.\"Id\" = 10 AND a.\"Id\" > 10 OR a.\"Clicks\" > 100))", sql); - query.ToList(); - - query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Id\" = 10) AND (a.\"Clicks\" > 100)", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" WHERE (a__Type.\"Name\" = 'typeTitle')", sql); - query.ToList(); - - query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" WHERE (a__Type.\"Name\" = 'typeTitle' AND a__Type.\"Guid\" = a.\"TypeGuid\")", sql); - query.ToList(); - - query = select.Where(a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Name\" = 'tparent')", sql); - query.ToList(); - - //���û�е������ԣ��򵥶������ - query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b WHERE (b.\"Guid\" = a.\"TypeGuid\" AND b.\"Name\" = 'typeTitle')", sql); - query.ToList(); - - query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b WHERE (b.\"Name\" = 'typeTitle' AND b.\"Guid\" = a.\"TypeGuid\")", sql); - query.ToList(); - - query = select.Where((a, b, c) => c.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeParentInfo\" c WHERE (c.\"Name\" = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .Where(a => a.Id == 10 && c.Name == "xxx") - .Where(a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b, \"TestTypeParentInfo\" c WHERE (a.\"Id\" = 10 AND c.\"Name\" = 'xxx') AND (b.\"ParentId\" = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.Where("a.\"Clicks\" > 100 and a.\"Id\" = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Clicks\" > 100 and a.\"Id\" = @id)", sql); - query.ToList(); - } - [Fact] - public void WhereIf() { - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.WhereIf(true, a => a.Id == 10); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Id\" = 10)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE ((a.\"Id\" = 10 AND a.\"Id\" > 10 OR a.\"Clicks\" > 100))", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Id\" = 10) AND (a.\"Clicks\" > 100)", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" WHERE (a__Type.\"Name\" = 'typeTitle')", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" WHERE (a__Type.\"Name\" = 'typeTitle' AND a__Type.\"Guid\" = a.\"TypeGuid\")", sql); - query.ToList(); - - query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Name\" = 'tparent')", sql); - query.ToList(); - - //����һ�� From ��Ķ������ - var query2 = select.From((s, b, c) => s - .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(true, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b, \"TestTypeParentInfo\" c WHERE (a.\"Id\" = 10 AND c.\"Name\" = 'xxx') AND (b.\"ParentId\" = 20)", sql); - query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(true, "a.\"Clicks\" > 100 and a.\"Id\" = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Clicks\" > 100 and a.\"Id\" = @id)", sql); - query.ToList(); - - // ==========================================WhereIf(false) - - //����е�������a.Type��a.Type.Parent ���ǵ������� - query = select.WhereIf(false, a => a.Id == 10); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.First(); - - query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.First(); - - query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.First(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.First(); - - query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.First(); - - query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.First(); - - //����һ�� From ��Ķ������ - query2 = select.From((s, b, c) => s - .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") - .WhereIf(false, a => b.ParentId == 20)); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b, \"TestTypeParentInfo\" c", sql); - query2.First(); - - //������϶����㲻�� - query = select.WhereIf(false, "a.\"Clicks\" > 100 and a.\"Id\" = @id", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); - query.First(); - } - [Fact] - public void WhereExists() { - var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); - - sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - - //.Offset(a.Id) - - .Any() - ).Any() - ).ToList(); - } - [Fact] - public void GroupBy() { - var groupby = select.From((s, b, c) => s - .Where(a => a.Id == 1) - ) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()) - .Offset(10) - .Limit(2) - .ToList(a => new { - a.Key.tt2, - cou1 = a.Count(), - arg1 = a.Avg(a.Key.mod4), - ccc2 = a.Key.tt2 ?? "now()", - //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") - ccc3 = a.Max(a.Value.Item3.Id) - }); - - var testpid1 = g.sqlite.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - g.sqlite.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); - - var aggsql1 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist1 = select - .GroupBy(a => a.Title) - .ToList(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToSql(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToList(b => new { - b.Key.Title, - b.Key.yyyy, - - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - - var aggsql3 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid), - sum3 = b.Sum(b.Value.Type.Parent.Id) - }); - } - [Fact] - public void ToAggregate() { - var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - } - [Fact] - public void OrderBy() { - var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); - } - [Fact] - public void Skip_Offset() { - var sql = select.Offset(10).Limit(10).ToList(); - } - [Fact] - public void Take_Limit() { - var sql = select.Limit(10).ToList(); - } - [Fact] - public void Page() { - var sql1 = select.Page(1, 10).ToList(); - var sql2 = select.Page(2, 10).ToList(); - var sql3 = select.Page(3, 10).ToList(); - - var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); - var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); - var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); - } - [Fact] - public void Distinct() { - var t1 = select.Distinct().ToList(a => a.Title); - var t2 = select.Distinct().Limit(10).ToList(a => a.Title); - } - - [Fact] - public void Sum() { - } - [Fact] - public void Min() { - } - [Fact] - public void Max() { - } - [Fact] - public void Avg() { - } - [Fact] - public void As() { - } - - [Fact] - public void AsTable() { - - var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); - - var tenantId = 1; - var reposTopic = g.sqlite.GetGuidRepository(null, oldname => $"{oldname}_{tenantId}"); - var reposType = g.sqlite.GetGuidRepository(null, oldname => $"{oldname}_{tenantId}"); - - //reposTopic.Delete(Guid.Empty); - //reposTopic.Find(Guid.Empty); - //reposTopic.Update(new Topic { TypeGuid = 1 }); - var sql11 = reposTopic.Select - - .FromRepository(reposType) - .From((s,b,c) => s) - - .LeftJoin(a => a.TypeGuid == a.Type.Guid) - .ToSql(); - - - - Func tableRule = (type, oldname) => { - if (type == typeof(Topic)) return oldname + "AsTable1"; - else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; - return oldname + "AsTable"; - }; - - //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); - var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\"", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx'", sql); - - query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfoAsTable\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); - - //���û�е������� - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" b ON b.\"Guid\" = a.\"TypeGuid\"", sql); - - query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" b ON b.\"Guid\" = a.\"TypeGuid\" AND b.\"Name\" = 'xxx'", sql); - - query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfoAsTable\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); - - //������� - query = select - .LeftJoin(a => a.Type.Guid == a.TypeGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfoAsTable\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\"", sql); - - query = select - .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfoAsTable\" c ON c.\"Id\" = a__Type.\"ParentId\"", sql); - - //���û�е�������b��c������ϵ - var query2 = select.From((s, b, c) => s - .LeftJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); - sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" b ON a.\"TypeGuid\" = b.\"Guid\" LEFT JOIN \"TestTypeParentInfoAsTable\" c ON b.\"ParentId\" = c.\"Id\"", sql); - - //������϶����㲻�� - query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\"").AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\"", sql); - - query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", sql); - } - - public class TestInclude_OneToManyModel1 { - [Column(IsIdentity = true)] - public int id { get; set; } - public virtual TestInclude_OneToManyModel2 model2 { get; set; } - - public string m1name { get; set; } - } - public class TestInclude_OneToManyModel2 { - [Column(IsPrimary = true)] - public int model2id { get; set; } - public virtual TestInclude_OneToManyModel1 model1 { get; set; } - - public string m2setting { get; set; } - - public List childs { get; set; } - } - public class TestInclude_OneToManyModel3 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model2111Idaaa { get; set; } - public string title { get; set; } - - public List childs2 { get; set; } - } - public class TestInclude_OneToManyModel4 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public int model3333Id333 { get; set; } - public string title444 { get; set; } - } - - [Fact] - public void Include_OneToMany() { - var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; - model1.id = (int)g.sqlite.Insert(model1).ExecuteIdentity(); - var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; - g.sqlite.Insert(model2).ExecuteAffrows(); - - var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; - model3_1.id = (int)g.sqlite.Insert(model3_1).ExecuteIdentity(); - var model3_2 =new TestInclude_OneToManyModel3{ model2111Idaaa = model1.id, title = "testmodel3__222" }; - model3_2.id = (int)g.sqlite.Insert(model3_2).ExecuteIdentity(); - var model3_3 = new TestInclude_OneToManyModel3{ model2111Idaaa = model1.id, title = "testmodel3__333" }; - model3_3.id = (int)g.sqlite.Insert(model3_2).ExecuteIdentity(); - - var model4s = new[] { - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, - new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } - }; - Assert.Equal(5, g.sqlite.Insert(model4s).ExecuteAffrows()); - - var t0 = g.sqlite.Select() - .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t1 = g.sqlite.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t2 = g.sqlite.Select() - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - - var t00 = g.sqlite.Select() - .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) - .Where(a => a.model2id <= model1.id) - .ToList(); - - var t11 = g.sqlite.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) - .Where(a => a.id <= model1.id) - .ToList(); - - var t22 = g.sqlite.Select() - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), - then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) - .Where(a => a.id <= model1.id) - .ToList(); - } - - public class TestInclude_OneToManyModel11 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2id { get; set; } - public string m3setting { get; set; } - public TestInclude_OneToManyModel22 model2 { get; set; } - public string m1name { get; set; } - } - - public class TestInclude_OneToManyModel22 { - [Column(IsIdentity = true)] - public int id { get; set; } - public string m2setting { get; set; } - public List childs { get; set; } - } - public class TestInclude_OneToManyModel33 { - [Column(IsIdentity = true)] - public int id { get; set; } - public int model2Id { get; set; } - public string title { get; set; } - public string setting { get; set; } - } - [Fact] - public void Include_OneToMany2() { - string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; - model2.id = (int)g.sqlite.Insert(model2).ExecuteIdentity(); - - var model3s = new[] - { - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, - new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} - }; - Assert.Equal(3, g.sqlite.Insert(model3s).ExecuteAffrows()); - - var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; - model1.id = (int)g.sqlite.Insert(model1).ExecuteIdentity(); - - var t1 = g.sqlite.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - - var t11 = g.sqlite.Select() - .LeftJoin(a => a.model2id == a.model2.id) - .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) - .Where(a => a.id <= model1.id) - .ToList(true); - } - - [Fact] - public void Include_OneToChilds() { - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_中国" - }; - tag1.Id = (int)g.sqlite.Insert(tag1).ExecuteIdentity(); - var tag1_1 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_北京" - }; - tag1_1.Id = (int)g.sqlite.Insert(tag1_1).ExecuteIdentity(); - var tag1_2 = new Tag { - Parent_id = tag1.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_01_上海" - }; - tag1_2.Id = (int)g.sqlite.Insert(tag1_2).ExecuteIdentity(); - - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_美国" - }; - tag2.Id = (int)g.sqlite.Insert(tag2).ExecuteIdentity(); - var tag2_1 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_纽约" - }; - tag2_1.Id = (int)g.sqlite.Insert(tag2_1).ExecuteIdentity(); - var tag2_2 = new Tag { - Parent_id = tag2.Id, - Ddd = DateTime.Now.Second, - Name = "test_oneToChilds_02_华盛顿" - }; - tag2_2.Id = (int)g.sqlite.Insert(tag2_2).ExecuteIdentity(); - - var tags0 = g.sqlite.Select() - .Include(a => a.Parent) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags1 = g.sqlite.Select() - .IncludeMany(a => a.Tags) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags2 = g.sqlite.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags3 = g.sqlite.Select() - .IncludeMany(a => a.Tags, - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags11 = g.sqlite.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags22 = g.sqlite.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - - var tags33 = g.sqlite.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) - .Include(a => a.Parent) - .IncludeMany(a => a.Songs.Take(1)) - .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) - .ToList(); - } - - [Fact] - public void Include_ManyToMany() { - - var tag1 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_01_中国" - }; - tag1.Id = (int)g.sqlite.Insert(tag1).ExecuteIdentity(); - var tag2 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_02_美国" - }; - tag2.Id = (int)g.sqlite.Insert(tag2).ExecuteIdentity(); - var tag3 = new Tag { - Ddd = DateTime.Now.Second, - Name = "test_manytoMany_03_日本" - }; - tag3.Id = (int)g.sqlite.Insert(tag3).ExecuteIdentity(); - - var song1 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_01_我是中国人.mp3", - Url = "http://ww.baidu.com/" - }; - song1.Id = (int)g.sqlite.Insert(song1).ExecuteIdentity(); - var song2 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_02_爱你一万年.mp3", - Url = "http://ww.163.com/" - }; - song2.Id = (int)g.sqlite.Insert(song2).ExecuteIdentity(); - var song3 = new Song { - Create_time = DateTime.Now, - Title = "test_manytoMany_03_千年等一回.mp3", - Url = "http://ww.sina.com/" - }; - song3.Id = (int)g.sqlite.Insert(song3).ExecuteIdentity(); - - g.sqlite.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.sqlite.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - g.sqlite.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); - - var songs1 = g.sqlite.Select() - .IncludeMany(a => a.Tags) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs1.Count); - Assert.Equal(2, songs1[0].Tags.Count); - Assert.Equal(1, songs1[1].Tags.Count); - Assert.Equal(3, songs1[2].Tags.Count); - - var songs2 = g.sqlite.Select() - .IncludeMany(a => a.Tags, - then => then.IncludeMany(t => t.Songs)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs2.Count); - Assert.Equal(2, songs2[0].Tags.Count); - Assert.Equal(1, songs2[1].Tags.Count); - Assert.Equal(3, songs2[2].Tags.Count); - - var tags3 = g.sqlite.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - - - var songs11 = g.sqlite.Select() - .IncludeMany(a => a.Tags.Take(1)) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs11.Count); - Assert.Equal(1, songs11[0].Tags.Count); - Assert.Equal(1, songs11[1].Tags.Count); - Assert.Equal(1, songs11[2].Tags.Count); - - var songs22 = g.sqlite.Select() - .IncludeMany(a => a.Tags.Take(1), - then => then.IncludeMany(t => t.Songs.Take(1))) - .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) - .ToList(); - Assert.Equal(3, songs22.Count); - Assert.Equal(1, songs22[0].Tags.Count); - Assert.Equal(1, songs22[1].Tags.Count); - Assert.Equal(1, songs22[2].Tags.Count); - - var tags33 = g.sqlite.Select() - .Include(a => a.Tag.Parent) - .IncludeMany(a => a.Tag.Songs.Take(1)) - .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) - .ToList(true); - } - } +namespace FreeSql.Tests.Sqlite +{ + public class SqliteSelectTest + { + + ISelect select => g.sqlite.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.sqlite.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.sqlite.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.sqlite.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.sqlite.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.sqlite.Select().Limit(10).ToList(); + + + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, g.sqlite.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, g.sqlite.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.sqlite.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public bool? testBool1 { get; set; } + public bool? testBool2 { get; set; } + } + class TestDtoLeftJoin + { + [Column(IsPrimary = true)] + public int Guid { get; set; } + public bool? testBool1 { get; set; } + public bool? testBool2 { get; set; } + } + [Fact] + public void ToList() + { + + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var testlist = select.Limit(10).ToList(); + foreach (var testitem in testlist) + { + var testdtolj = new TestDtoLeftJoin { Guid = testitem.TypeGuid, testBool1 = true }; + if (g.sqlite.Select().Where(a => a.Guid == testitem.TypeGuid).Any() == false) + g.sqlite.Insert(testdtolj).ExecuteAffrows(); + } + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + g.sqlite.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.sqlite.Select().ToList(); + var testGuidId6 = g.sqlite.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON a.\"TypeGuid\" = b.\"Guid\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON a.\"TypeGuid\" = b.\"Guid\" LEFT JOIN \"TestTypeParentInfo\" c ON b.\"ParentId\" = c.\"Id\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON b.\"Guid\" = a.\"TypeGuid\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON b.\"Guid\" = a.\"TypeGuid\" AND b.\"Name\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfo\" c ON c.\"Id\" = a__Type.\"ParentId\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b ON a.\"TypeGuid\" = b.\"Guid\" LEFT JOIN \"TestTypeParentInfo\" c ON b.\"ParentId\" = c.\"Id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\"", sql); + query.ToList(); + + query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b ON b.\"Guid\" = a.\"TypeGuid\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b ON b.\"Guid\" = a.\"TypeGuid\" AND b.\"Name\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" INNER JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" INNER JOIN \"TestTypeParentInfo\" c ON c.\"Id\" = a__Type.\"ParentId\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b ON a.\"TypeGuid\" = b.\"Guid\" INNER JOIN \"TestTypeParentInfo\" c ON b.\"ParentId\" = c.\"Id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\"", sql); + query.ToList(); + + query = select.InnerJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a INNER JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Id\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE ((a.\"Id\" = 10 AND a.\"Id\" > 10 OR a.\"Clicks\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Id\" = 10) AND (a.\"Clicks\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" WHERE (a__Type.\"Name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" WHERE (a__Type.\"Name\" = 'typeTitle' AND a__Type.\"Guid\" = a.\"TypeGuid\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Name\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b WHERE (b.\"Guid\" = a.\"TypeGuid\" AND b.\"Name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b WHERE (b.\"Name\" = 'typeTitle' AND b.\"Guid\" = a.\"TypeGuid\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeParentInfo\" c WHERE (c.\"Name\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b, \"TestTypeParentInfo\" c WHERE (a.\"Id\" = 10 AND c.\"Name\" = 'xxx') AND (b.\"ParentId\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"Clicks\" > 100 and a.\"Id\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Clicks\" > 100 and a.\"Id\" = @id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Id\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE ((a.\"Id\" = 10 AND a.\"Id\" > 10 OR a.\"Clicks\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Id\" = 10) AND (a.\"Clicks\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" WHERE (a__Type.\"Name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" WHERE (a__Type.\"Name\" = 'typeTitle' AND a__Type.\"Guid\" = a.\"TypeGuid\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a LEFT JOIN \"TestTypeInfo\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfo\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Name\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b, \"TestTypeParentInfo\" c WHERE (a.\"Id\" = 10 AND c.\"Name\" = 'xxx') AND (b.\"ParentId\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"Clicks\" > 100 and a.\"Id\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a WHERE (a.\"Clicks\" > 100 and a.\"Id\" = @id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); + query.First(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); + query.First(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); + query.First(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); + query.First(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); + query.First(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); + query.First(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a, \"TestTypeInfo\" b, \"TestTypeParentInfo\" c", sql); + query2.First(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"Clicks\" > 100 and a.\"Id\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); + query.First(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.sqlite.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.sqlite.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + } + [Fact] + public void Min() + { + } + [Fact] + public void Max() + { + } + [Fact] + public void Avg() + { + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + var tenantId = 1; + var reposTopic = g.sqlite.GetGuidRepository(null, oldname => $"{oldname}_{tenantId}"); + var reposType = g.sqlite.GetGuidRepository(null, oldname => $"{oldname}_{tenantId}"); + + //reposTopic.Delete(Guid.Empty); + //reposTopic.Find(Guid.Empty); + //reposTopic.Update(new Topic { TypeGuid = 1 }); + var sql11 = reposTopic.Select + + .FromRepository(reposType) + .From((s, b, c) => s) + + .LeftJoin(a => a.TypeGuid == a.Type.Guid) + .ToSql(); + + + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfoAsTable\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" b ON b.\"Guid\" = a.\"TypeGuid\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" b ON b.\"Guid\" = a.\"TypeGuid\" AND b.\"Name\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" AND a__Type.\"Name\" = 'xxx' LEFT JOIN \"TestTypeParentInfoAsTable\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\" WHERE (a__Type__Parent.\"Id\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfoAsTable\" a__Type__Parent ON a__Type__Parent.\"Id\" = a__Type.\"ParentId\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\" LEFT JOIN \"TestTypeParentInfoAsTable\" c ON c.\"Id\" = a__Type.\"ParentId\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", b.\"Guid\", b.\"ParentId\", b.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" b ON a.\"TypeGuid\" = b.\"Guid\" LEFT JOIN \"TestTypeParentInfoAsTable\" c ON b.\"ParentId\" = c.\"Id\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\"", sql); + + query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.sqlite.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.sqlite.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.sqlite.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.sqlite.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.sqlite.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.sqlite.Insert(model4s).ExecuteAffrows()); + + var t0 = g.sqlite.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.sqlite.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.sqlite.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.sqlite.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.sqlite.Insert(model1).ExecuteIdentity(); + + var t1 = g.sqlite.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.sqlite.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.sqlite.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.sqlite.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.sqlite.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.sqlite.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.sqlite.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.sqlite.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.sqlite.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.sqlite.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.sqlite.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.sqlite.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.sqlite.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.sqlite.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.sqlite.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.sqlite.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.sqlite.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.sqlite.Insert(song3).ExecuteIdentity(); + + g.sqlite.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlite.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlite.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.sqlite.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.sqlite.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index 05d00ce3..e6ac094e 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -3,129 +3,143 @@ using System; using System.Collections.Generic; using Xunit; -namespace FreeSql.Tests.Sqlite { - public class SqliteUpdateTest { - IUpdate update => g.sqlite.Update(); +namespace FreeSql.Tests.Sqlite +{ + public class SqliteUpdateTest + { + IUpdate update => g.sqlite.Update(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int? Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void Dywhere() { - Assert.Null(g.sqlite.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); - } + [Fact] + public void Dywhere() + { + Assert.Null(g.sqlite.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } - [Fact] - public void SetSource() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = @p_0, \"Title\" = @p_1, \"CreateTime\" = @p_2 WHERE (\"Id\" = 1)", sql); + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = @p_0, \"Title\" = @p_1, \"CreateTime\" = @p_2 WHERE (\"Id\" = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"Title\" = CASE \"Id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CreateTime\" = CASE \"Id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"Title\" = CASE \"Id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CreateTime\" = CASE \"Id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"CreateTime\" = @p_0 WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void IgnoreColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); - } - [Fact] - public void UpdateColumns() { - var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); - } - [Fact] - public void Set() { - var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"CreateTime\" = @p_0 WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); - sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0, \"CreateTime\" = @p_1 WHERE (\"Id\" = 1)", sql); + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0, \"CreateTime\" = @p_1 WHERE (\"Id\" = 1)", sql); - sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = ifnull(\"Clicks\", 0) * 10 / 1 WHERE (\"Id\" = 1)", sql); + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = ifnull(\"Clicks\", 0) * 10 / 1 WHERE (\"Id\" = 1)", sql); - sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Id\" = (\"Id\" - 10) WHERE (\"Id\" = 1)", sql); + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Id\" = (\"Id\" - 10) WHERE (\"Id\" = 1)", sql); - int incrv = 10; - sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = ifnull(\"Clicks\", 0) * 10 / 1 WHERE (\"Id\" = 1)", sql); + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = ifnull(\"Clicks\", 0) * 10 / 1 WHERE (\"Id\" = 1)", sql); - sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Id\" = (\"Id\" - 10) WHERE (\"Id\" = 1)", sql); + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Id\" = (\"Id\" - 10) WHERE (\"Id\" = 1)", sql); - sql = update.Set(a => a.CreateTime.AddYears(1)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"CreateTime\" = datetime(\"CreateTime\",(1)||' years') WHERE (\"Id\" = 1)", sql); + sql = update.Set(a => a.CreateTime.AddYears(1)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"CreateTime\" = datetime(\"CreateTime\",(1)||' years') WHERE (\"Id\" = 1)", sql); - sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = \"Clicks\" * 10 / 1 WHERE (\"Id\" = 1)", sql); + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = \"Clicks\" * 10 / 1 WHERE (\"Id\" = 1)", sql); - sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"Id\" = 10 WHERE (\"Id\" = 1)", sql); - } - [Fact] - public void SetRaw() { - var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + :incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + :incrClick WHERE (\"Id\" = 1)", sql); - } - [Fact] - public void Where() { - var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"Id\" = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Id\" = 10 WHERE (\"Id\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + :incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + :incrClick WHERE (\"Id\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"Id\" = 1)", sql); - sql = update.Where("id = :id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (id = :id)", sql); + sql = update.Where("id = :id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (id = :id)", sql); - var item = new Topic { Id = 1, Title = "newtitle" }; - sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"Id\" = 1)", sql); + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"Id\" = 1)", sql); - var items = new List(); - for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { - } - [Fact] - public void ExecuteAffrows() { + } + [Fact] + public void ExecuteAffrows() + { - } - [Fact] - public void ExecuteUpdated() { + } + [Fact] + public void ExecuteUpdated() + { - } + } - [Fact] - public void AsTable() { - Assert.Null(g.sqlite.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - } - } + [Fact] + public void AsTable() + { + Assert.Null(g.sqlite.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs index 07fd2dab..1d261272 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs @@ -2,1561 +2,1595 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.SqliteMapType { - public class BoolNullableTest { - class BoolNullableMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool))] - public bool? tobool { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool? tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool? tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool? toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool? toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool? toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool? tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool? tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool? tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool? tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool? tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool? toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool? toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool? touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool? touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool? toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool? toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool? tostring { get; set; } = true; - } - [Fact] - public void Bool() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item = new BoolNullableMap { tobool = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item = new BoolNullableMap { tobool = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update all - item.tobool = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(true, find.tobool); - - item.tobool = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - item.tobool = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobool, find.tobool); - Assert.Equal(false, find.tobool); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobool); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item = new BoolNullableMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item = new BoolNullableMap { tosbyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(true, find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - item.tosbyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tosbyte, find.tosbyte); - Assert.Equal(false, find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item = new BoolNullableMap { tosbytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(true, find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Equal(false, find.tosbytenullable); - - item.tosbytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.Null(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item = new BoolNullableMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item = new BoolNullableMap { toshort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(true, find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - item.toshort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toshort, find.toshort); - Assert.Equal(false, find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item = new BoolNullableMap { toshortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(true, find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Equal(false, find.toshortnullable); - - item.toshortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.Null(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item = new BoolNullableMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item = new BoolNullableMap { toint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(true, find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.Equal(false, find.toint); - - item.toint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toint, find.toint); - Assert.Equal(false, find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item = new BoolNullableMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item = new BoolNullableMap { tointnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(true, find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Equal(false, find.tointnullable); - - item.tointnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.Null(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item = new BoolNullableMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item = new BoolNullableMap { tolong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(true, find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - item.tolong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tolong, find.tolong); - Assert.Equal(false, find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item = new BoolNullableMap { tolongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(true, find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Equal(false, find.tolongnullable); - - item.tolongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.Null(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item = new BoolNullableMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item = new BoolNullableMap { tobyte = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(true, find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - item.tobyte = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.tobyte, find.tobyte); - Assert.Equal(false, find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item = new BoolNullableMap { tobytenullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(true, find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Equal(false, find.tobytenullable); - - item.tobytenullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.Null(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item = new BoolNullableMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item = new BoolNullableMap { toushort = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(true, find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - item.toushort = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toushort, find.toushort); - Assert.Equal(false, find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item = new BoolNullableMap { toushortnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(true, find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Equal(false, find.toushortnullable); - - item.toushortnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.Null(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item = new BoolNullableMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item = new BoolNullableMap { touint = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(true, find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.Equal(false, find.touint); - - item.touint = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.touint, find.touint); - Assert.Equal(false, find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item = new BoolNullableMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item = new BoolNullableMap { touintnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(true, find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Equal(false, find.touintnullable); - - item.touintnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.Null(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item = new BoolNullableMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item = new BoolNullableMap { toulong = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(true, find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - item.toulong = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.NotEqual(item.toulong, find.toulong); - Assert.Equal(false, find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item = new BoolNullableMap { toulongnullable = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(true, find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Equal(false, find.toulongnullable); - - item.toulongnullable = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.Null(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.sqlite; - var item = new BoolNullableMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item = new BoolNullableMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item = new BoolNullableMap { tostring = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(true, find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Equal(false, find.tostring); - - item.tostring = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(true, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(false, find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.SqliteMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.sqlite; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs index 58f1cf1c..846817f5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs @@ -2,1095 +2,1129 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.SqliteMapType { - public class BoolTest { - - class BoolMap { - public Guid id { get; set; } - [Column(MapType = typeof(bool?))] - public bool toboolnullable { get; set; } = true; - - [Column(MapType = typeof(sbyte))] - public bool tosbyte { get; set; } = true; - [Column(MapType = typeof(sbyte?))] - public bool tosbytenullable { get; set; } = true; - - [Column(MapType = typeof(short))] - public bool toshort { get; set; } = true; - - [Column(MapType = typeof(short?))] - public bool toshortnullable { get; set; } = true; - - [Column(MapType = typeof(int))] - public bool toint { get; set; } = true; - - [Column(MapType = typeof(int?))] - public bool tointnullable { get; set; } = true; - - [Column(MapType = typeof(long))] - public bool tolong { get; set; } = true; - [Column(MapType = typeof(long?))] - public bool tolongnullable { get; set; } = true; - - [Column(MapType = typeof(byte))] - public bool tobyte { get; set; } = true; - [Column(MapType = typeof(byte?))] - public bool tobytenullable { get; set; } = true; - - [Column(MapType = typeof(ushort))] - public bool toushort { get; set; } = true; - - [Column(MapType = typeof(ushort?))] - public bool toushortnullable { get; set; } = true; - - [Column(MapType = typeof(uint))] - public bool touint { get; set; } = true; - - [Column(MapType = typeof(uint?))] - public bool touintnullable { get; set; } = true; - - [Column(MapType = typeof(ulong))] - public bool toulong { get; set; } = true; - [Column(MapType = typeof(ulong?))] - public bool toulongnullable { get; set; } = true; - - [Column(MapType = typeof(string))] - public bool tostring { get; set; } = true; - } - - [Fact] - public void BoolNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item = new BoolMap { toboolnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update all - item.toboolnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.True(find.toboolnullable); - - item.toboolnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toboolnullable, find.toboolnullable); - Assert.False(find.toboolnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toboolnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toboolnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByte() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item = new BoolMap { tosbyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update all - item.tosbyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.True(find.tosbyte); - - item.tosbyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbyte, find.tosbyte); - Assert.False(find.tosbyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void SByteNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item = new BoolMap { tosbytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update all - item.tosbytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.True(find.tosbytenullable); - - item.tosbytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tosbytenullable, find.tosbytenullable); - Assert.False(find.tosbytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tosbytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tosbytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Short() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item = new BoolMap { toshort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update all - item.toshort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.True(find.toshort); - - item.toshort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshort, find.toshort); - Assert.False(find.toshort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ShortNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item = new BoolMap { toshortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update all - item.toshortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.True(find.toshortnullable); - - item.toshortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toshortnullable, find.toshortnullable); - Assert.False(find.toshortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toshortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toshortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Int() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item = new BoolMap { toint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update all - item.toint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.True(find.toint); - - item.toint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toint, find.toint); - Assert.False(find.toint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void IntNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item = new BoolMap { tointnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update all - item.tointnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.True(find.tointnullable); - - item.tointnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tointnullable, find.tointnullable); - Assert.False(find.tointnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tointnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tointnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void Long() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item = new BoolMap { tolong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update all - item.tolong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.True(find.tolong); - - item.tolong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolong, find.tolong); - Assert.False(find.tolong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void LongNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item = new BoolMap { tolongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update all - item.tolongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.True(find.tolongnullable); - - item.tolongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tolongnullable, find.tolongnullable); - Assert.False(find.tolongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tolongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tolongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Byte() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item = new BoolMap { tobyte = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update all - item.tobyte = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.True(find.tobyte); - - item.tobyte = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobyte, find.tobyte); - Assert.False(find.tobyte); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobyte); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobyte); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ByteNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item = new BoolMap { tobytenullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update all - item.tobytenullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.True(find.tobytenullable); - - item.tobytenullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tobytenullable, find.tobytenullable); - Assert.False(find.tobytenullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tobytenullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tobytenullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShort() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item = new BoolMap { toushort = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update all - item.toushort = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.True(find.toushort); - - item.toushort = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushort, find.toushort); - Assert.False(find.toushort); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushort); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushort); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UShortNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item = new BoolMap { toushortnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update all - item.toushortnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.True(find.toushortnullable); - - item.toushortnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toushortnullable, find.toushortnullable); - Assert.False(find.toushortnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toushortnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toushortnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UInt() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item = new BoolMap { touint = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update all - item.touint = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.True(find.touint); - - item.touint = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touint, find.touint); - Assert.False(find.touint); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touint); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touint); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void UIntNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item = new BoolMap { touintnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update all - item.touintnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.True(find.touintnullable); - - item.touintnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.touintnullable, find.touintnullable); - Assert.False(find.touintnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.touintnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.touintnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULong() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item = new BoolMap { toulong = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update all - item.toulong = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.True(find.toulong); - - item.toulong = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulong, find.toulong); - Assert.False(find.toulong); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulong); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulong); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void ULongNullable() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item = new BoolMap { toulongnullable = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update all - item.toulongnullable = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.True(find.toulongnullable); - - item.toulongnullable = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.toulongnullable, find.toulongnullable); - Assert.False(find.toulongnullable); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.toulongnullable); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.toulongnullable); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void TimeSpan() { - } - [Fact] - public void TimeSpanNullable() { - } - [Fact] - public void DateTime() { - } - [Fact] - public void DateTimeNullable() { - } - - [Fact] - public void ByteArray() { - } - [Fact] - public void String() { - //insert - var orm = g.sqlite; - var item = new BoolMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item = new BoolMap { tostring = false }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update all - item.tostring = true; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.True(find.tostring); - - item.tostring = false; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.False(find.tostring); - - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.True(find.tostring); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.False(find.tostring); - - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - - [Fact] - public void Guid() { - } - [Fact] - public void GuidNullable() { - } - - [Fact] - public void MygisPoint() { - } - [Fact] - public void MygisLineString() { - } - [Fact] - public void MygisPolygon() { - } - [Fact] - public void MygisMultiPoint() { - } - [Fact] - public void MygisMultiLineString() { - } - [Fact] - public void MygisMultiPolygon() { - } - } +namespace FreeSql.Tests.SqliteMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.sqlite; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/EnumTest.cs index ebb4b471..1797019c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/EnumTest.cs @@ -3,252 +3,259 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.SqliteMapType { - public class EnumTest { - class EnumTestMap { - public Guid id { get; set; } +namespace FreeSql.Tests.SqliteMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(int))] - public ToStringMapEnum enum_to_int { get; set; } - [Column(MapType = typeof(int?))] - public ToStringMapEnum? enumnullable_to_int { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void EnumToString() { - //insert - var orm = g.sqlite; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.sqlite; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToString() { - //insert - var orm = g.sqlite; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.sqlite; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void EnumToInt() { - //insert - var orm = g.sqlite; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + [Fact] + public void EnumToInt() + { + //insert + var orm = g.sqlite; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //update all - item.enum_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - item.enum_to_int = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_int, find.enum_to_int); - Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullableToInt() { - //insert - var orm = g.sqlite; - var item = new EnumTestMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.sqlite; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); - //update all - item.enumnullable_to_int = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); - item.enumnullable_to_int = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); - Assert.Null(find.enumnullable_to_int); + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_int); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/ToStringTest.cs index 0b83f04a..c71a4753 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/ToStringTest.cs @@ -3,555 +3,568 @@ using System; using System.Numerics; using Xunit; -namespace FreeSql.Tests.SqliteMapType { - public class ToStringTest { - class ToStringMap { - public Guid id { get; set; } +namespace FreeSql.Tests.SqliteMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan timespan_to_string { get; set; } - [Column(MapType = typeof(string))] - public TimeSpan? timespannullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime datetime_to_string { get; set; } - [Column(MapType = typeof(string))] - public DateTime? datetimenullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid guid_to_string { get; set; } - [Column(MapType = typeof(string))] - public Guid? guidnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum enum_to_string { get; set; } - [Column(MapType = typeof(string))] - public ToStringMapEnum? enumnullable_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger biginteger_to_string { get; set; } - [Column(MapType = typeof(string))] - public BigInteger? bigintegernullable_to_string { get; set; } - } - public enum ToStringMapEnum { й, abc, } - [Fact] - public void Enum1() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //update all - item.enum_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - item.enum_to_string = ToStringMapEnum.й; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enum_to_string, find.enum_to_string); - Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum., find.enum_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void EnumNullable() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); - //update all - item.enumnullable_to_string = ToStringMapEnum.; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigInteger1() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(0, find.biginteger_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); - item = new ToStringMap { biginteger_to_string = 100 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(100, find.biginteger_to_string); + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); - //update all - item.biginteger_to_string = 200; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(200, find.biginteger_to_string); + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); - item.biginteger_to_string = 205; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); - Assert.Equal(205, find.biginteger_to_string); + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(522, find.biginteger_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(10005, find.biginteger_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void BigIntegerNullable() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - item = new ToStringMap { bigintegernullable_to_string = 101 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(101, find.bigintegernullable_to_string); + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); - //update all - item.bigintegernullable_to_string = 2004; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Equal(2004, find.bigintegernullable_to_string); + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); - item.bigintegernullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(998, find.bigintegernullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.bigintegernullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpan1() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); - item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); - //update all - item.timespan_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespan_to_string, find.timespan_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void TimeSpanNullable() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); - //update all - item.timespannullable_to_string = TimeSpan.FromHours(10); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); - item.timespannullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); - Assert.Null(find.timespannullable_to_string); + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.timespannullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTime1() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.MinValue, find.datetime_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); - item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); - //update all - item.datetime_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetime_to_string, find.datetime_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void DateTimeNullable() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); - //update all - item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); - item.datetimenullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); - Assert.Null(find.datetimenullable_to_string); + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); - //update set - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.datetimenullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } - [Fact] - public void Guid1() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(Guid.Empty, find.guid_to_string); + [Fact] + public void Guid1() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guid_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update all - newid = Guid.NewGuid(); - item.guid_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guid_to_string, find.guid_to_string); - Assert.Equal(newid, find.guid_to_string); + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guid_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - [Fact] - public void GuidNullable() { - //insert - var orm = g.sqlite; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.sqlite; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guidnullable_to_string = newid }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - //update all - newid = Guid.NewGuid(); - item.guidnullable_to_string = newid; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Equal(newid, find.guidnullable_to_string); + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); - item.guidnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); - //update set - newid = Guid.NewGuid(); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(newid, find.guidnullable_to_string); + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.guidnullable_to_string); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); - } - } + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs index 59dafe55..02bb40dc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs @@ -2,68 +2,80 @@ using FreeSql.DataAnnotations; using System; using Xunit; -namespace FreeSql.Tests.Sqlite { - public class SqliteAdoTest { - [Fact] - public void Pool() { - var t1 = g.sqlite.Ado.MasterPool.StatisticsFullily; - } +namespace FreeSql.Tests.Sqlite +{ + public class SqliteAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.sqlite.Ado.MasterPool.StatisticsFullily; + } - [Fact] - public void SlavePools() { - var t2 = g.sqlite.Ado.SlavePools.Count; - } - [Fact] - public void ExecuteReader() { - - } - [Fact] - public void ExecuteArray() { - - } - [Fact] - public void ExecuteNonQuery() { - - } - [Fact] - public void ExecuteScalar() { - - } + [Fact] + public void SlavePools() + { + var t2 = g.sqlite.Ado.SlavePools.Count; + } + [Fact] + public void ExecuteReader() + { - [Fact] - public void Query() { + } + [Fact] + public void ExecuteArray() + { - var t0 = g.sqlite.Ado.Query("select * from \"song\""); + } + [Fact] + public void ExecuteNonQuery() + { - var t1 = g.sqlite.Ado.Query("select id, url, create_time from \"song\""); + } + [Fact] + public void ExecuteScalar() + { - var t2 = g.sqlite.Ado.Query("select id, url, create_time test_time from \"song\""); + } - var t3 = g.sqlite.Ado.Query("select * from \"song\""); + [Fact] + public void Query() + { - var t4 = g.sqlite.Ado.Query<(int, string, string)>("select * from \"song\""); + var t0 = g.sqlite.Ado.Query("select * from \"song\""); - var t5 = g.sqlite.Ado.Query("select * from \"song\""); - } + var t1 = g.sqlite.Ado.Query("select id, url, create_time from \"song\""); - [Fact] - public void QueryMultipline() { - var t3 = g.sqlite.Ado.Query("select * from song; select * from song; select * from song"); - } + var t2 = g.sqlite.Ado.Query("select id, url, create_time test_time from \"song\""); - class xxx { - public int Id { get; set; } - public string Path { get; set; } - public string Title2 { get; set; } - } + var t3 = g.sqlite.Ado.Query("select * from \"song\""); - class testallDto { - public int Id { get; set; } - public string Title { get; set; } - public string Url { get; set; } - public DateTime Test_time { get; set; } - public DateTime Create_time { get; set; } - public bool Is_deleted { get; set; } - } - } + var t4 = g.sqlite.Ado.Query<(int, string, string)>("select * from \"song\""); + + var t5 = g.sqlite.Ado.Query("select * from \"song\""); + } + + [Fact] + public void QueryMultipline() + { + var t3 = g.sqlite.Ado.Query("select * from song; select * from song; select * from song"); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + + class testallDto + { + public int Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime Test_time { get; set; } + public DateTime Create_time { get; set; } + public bool Is_deleted { get; set; } + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index b6a3e8bd..ef0597df 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -6,125 +6,140 @@ using System.Linq; using System.Text; using Xunit; -namespace FreeSql.Tests.Sqlite { - public class SqliteCodeFirstTest { +namespace FreeSql.Tests.Sqlite +{ + public class SqliteCodeFirstTest + { - [Fact] - public void ı_ֶ() { - var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements<ı>(); - g.sqlite.CodeFirst.SyncStructure<ı>(); + [Fact] + public void ı_ֶ() + { + var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements<ı>(); + g.sqlite.CodeFirst.SyncStructure<ı>(); - var item = new ı { - = "Ա", - ʱ = DateTime.Now - }; - Assert.Equal(1, g.sqlite.Insert<ı>().AppendData(item).ExecuteAffrows()); - Assert.NotEqual(Guid.Empty, item.); - var item2 = g.sqlite.Select<ı>().Where(a => a. == item.).First(); - Assert.NotNull(item2); - Assert.Equal(item., item2.); - Assert.Equal(item., item2.); - } - class ı { - [Column(IsPrimary = true)] - public Guid { get; set; } + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.sqlite.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.sqlite.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } - public string { get; set; } + public string { get; set; } - public DateTime ʱ { get; set; } - } + public DateTime ʱ { get; set; } + } - [Fact] - public void AddUniques() { - var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements(); - g.sqlite.CodeFirst.SyncStructure(); - } - [Table(Name = "AddUniquesInfo2", OldName = "AddUniquesInfo")] - class AddUniquesInfo { - public Guid id { get; set; } - [Column(Unique = "uk_phone")] - public string phone { get; set; } + [Fact] + public void AddUniques() + { + var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements(); + g.sqlite.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo2", OldName = "AddUniquesInfo")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] - public string group { get; set; } - [Column(Unique = "uk_group_index")] - public int index { get; set; } - [Column(Unique = "uk_group_index22")] - public string index22 { get; set; } - } + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } - public class Topic { - public Guid Id { get; set; } - public string Title { get; set; } - public string Content { get; set; } - public DateTime CreateTime { get; set; } - } - [Table(Name = "xxxtb.Comment")] - public class Comment { - public Guid Id { get; set; } - public Guid TopicId { get; set; } - public virtual Topic Topic { get; set; } - public string Nickname { get; set; } - public string Content { get; set; } - public DateTime CreateTime { get; set; } - } + public class Topic + { + public Guid Id { get; set; } + public string Title { get; set; } + public string Content { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "xxxtb.Comment")] + public class Comment + { + public Guid Id { get; set; } + public Guid TopicId { get; set; } + public virtual Topic Topic { get; set; } + public string Nickname { get; set; } + public string Content { get; set; } + public DateTime CreateTime { get; set; } + } - [Fact] - public void AddField() { + [Fact] + public void AddField() + { - //һ FreeSql.Repository չdotnet add package FreeSql.Repository - var topicRepository = g.sqlite.GetGuidRepository(); - var commentRepository = g.sqlite.GetGuidRepository(); + //һ FreeSql.Repository չdotnet add package FreeSql.Repository + var topicRepository = g.sqlite.GetGuidRepository(); + var commentRepository = g.sqlite.GetGuidRepository(); - //Ӳ - var topic = topicRepository.Insert(new Topic { - Title = "±1", - Content = "1", - CreateTime = DateTime.Now - }); + //Ӳ + var topic = topicRepository.Insert(new Topic + { + Title = "±1", + Content = "1", + CreateTime = DateTime.Now + }); - //10 - var comments = Enumerable.Range(0, 10).Select(a => new Comment { - TopicId = topic.Id, - Nickname = $"dz{a}", - Content = $"{a}", - CreateTime = DateTime.Now - }).ToArray(); - var affrows = commentRepository.Insert(comments); + //10 + var comments = Enumerable.Range(0, 10).Select(a => new Comment + { + TopicId = topic.Id, + Nickname = $"dz{a}", + Content = $"{a}", + CreateTime = DateTime.Now + }).ToArray(); + var affrows = commentRepository.Insert(comments); - var find = commentRepository.Select.Where(a => a.Topic.Title == "±1").ToList(); + var find = commentRepository.Select.Where(a => a.Topic.Title == "±1").ToList(); - var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements(); + var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements(); - var id = g.sqlite.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + var id = g.sqlite.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); - //var inserted = g.Sqlite.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); - } + //var inserted = g.Sqlite.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } - [Table(Name = "xxxtb.TopicAddField", OldName = "TopicAddField")] - public class TopicAddField { - [Column(IsIdentity = true)] - public int Id { get; set; } + [Table(Name = "xxxtb.TopicAddField", OldName = "TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } - public string name { get; set; } + public string name { get; set; } - [Column(DbType = "varchar(200) not null", OldName = "title2")] - public string title3223 { get; set; } = "10"; + [Column(DbType = "varchar(200) not null", OldName = "title2")] + public string title3223 { get; set; } = "10"; - [Column(IsIgnore = true)] - public DateTime ct { get; set; } = DateTime.Now; - } + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } - [Fact] - public void GetComparisonDDLStatements() { + [Fact] + public void GetComparisonDDLStatements() + { - var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS ""main"".""tb_alltype"" ( + var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS ""main"".""tb_alltype"" ( ""Id"" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ""Bool"" BOOLEAN NOT NULL, ""SByte"" SMALLINT NOT NULL, @@ -167,114 +182,117 @@ namespace FreeSql.Tests.Sqlite { ) ; ", sql); - } + } - //sql = g.Sqlite.CodeFirst.GetComparisonDDLStatements(); - } + //sql = g.Sqlite.CodeFirst.GetComparisonDDLStatements(); + } - IInsert insert => g.sqlite.Insert(); - ISelect select => g.sqlite.Select(); + IInsert insert => g.sqlite.Insert(); + ISelect select => g.sqlite.Select(); - [Fact] - public void CurdAllField() { - var item = new TableAllType { }; - item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); - var newitem = select.Where(a => a.Id == item.Id).ToOne(); + var newitem = select.Where(a => a.Id == item.Id).ToOne(); - var item2 = new TableAllType { - Bool = true, - BoolNullable = true, - Byte = 255, - ByteNullable = 127, - Bytes = Encoding.UTF8.GetBytes("й"), - DateTime = DateTime.Now, - DateTimeNullable = DateTime.Now.AddHours(-1), - Decimal = 99.99M, - DecimalNullable = 99.98M, - Double = 999.99, - DoubleNullable = 999.98, - Enum1 = TableAllTypeEnumType1.e5, - Enum1Nullable = TableAllTypeEnumType1.e3, - Enum2 = TableAllTypeEnumType2.f2, - Enum2Nullable = TableAllTypeEnumType2.f3, - Float = 19.99F, - FloatNullable = 19.98F, - Guid = Guid.NewGuid(), - GuidNullable = Guid.NewGuid(), - Int = int.MaxValue, - IntNullable = int.MinValue, - SByte = 100, - SByteNullable = 99, - Short = short.MaxValue, - ShortNullable = short.MinValue, - String = "йstring", - TimeSpan = TimeSpan.FromSeconds(999), - TimeSpanNullable = TimeSpan.FromSeconds(60), - UInt = uint.MaxValue, - UIntNullable = uint.MinValue, - ULong = ulong.MaxValue - 10000000, - ULongNullable = ulong.MinValue, - UShort = ushort.MaxValue, - UShortNullable = ushort.MinValue, - testFielLongNullable = long.MinValue - }; - item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); - var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue - 10000000, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); - var items = select.ToList(); - } + var items = select.ToList(); + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - //public string id2 { get; set; } = "id2=10"; + //public string id2 { get; set; } = "id2=10"; - public bool Bool { get; set; } - public sbyte SByte { get; set; } - public short Short { get; set; } - public int Int { get; set; } - public long Long { get; set; } - public byte Byte { get; set; } - public ushort UShort { get; set; } - public uint UInt { get; set; } - public ulong ULong { get; set; } - public double Double { get; set; } - public float Float { get; set; } - public decimal Decimal { get; set; } - public TimeSpan TimeSpan { get; set; } - public DateTime DateTime { get; set; } - public DateTime DateTimeOffSet { get; set; } - public byte[] Bytes { get; set; } - public string String { get; set; } - public Guid Guid { get; set; } + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } - public bool? BoolNullable { get; set; } - public sbyte? SByteNullable { get; set; } - public short? ShortNullable { get; set; } - public int? IntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? ByteNullable { get; set; } - public ushort? UShortNullable { get; set; } - public uint? UIntNullable { get; set; } - public ulong? ULongNullable { get; set; } - public double? DoubleNullable { get; set; } - public float? FloatNullable { get; set; } - public decimal? DecimalNullable { get; set; } - public TimeSpan? TimeSpanNullable { get; set; } - public DateTime? DateTimeNullable { get; set; } - public DateTime? DateTimeOffSetNullable { get; set; } - public Guid? GuidNullable { get; set; } + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } - public TableAllTypeEnumType1 Enum1 { get; set; } - public TableAllTypeEnumType1? Enum1Nullable { get; set; } - public TableAllTypeEnumType2 Enum2 { get; set; } - public TableAllTypeEnumType2? Enum2Nullable { get; set; } - } + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/ConvertTest.cs index 0ce1de72..6f881231 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/ConvertTest.cs @@ -4,143 +4,166 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqliteExpression { - public class ConvertTest { +namespace FreeSql.Tests.SqliteExpression +{ + public class ConvertTest + { - ISelect select => g.sqlite.Select(); + ISelect select => g.sqlite.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void ToBoolean() { - var data = new List(); - data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); - data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); - } - [Fact] - public void ToByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); - data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); - } - [Fact] - public void ToChar() { - var data = new List(); - data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); - data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); - } - [Fact] - public void ToDateTime() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); - } - [Fact] - public void ToDecimal() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToDouble() { - var data = new List(); - data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt32() { - var data = new List(); - data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); - data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToSByte() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); - data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); - } - [Fact] - public void ToSingle() { - var data = new List(); - data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); - data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); - } - [Fact] - public void ToUInt16() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt32() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); - } - [Fact] - public void ToUInt64() { - var data = new List(); - data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); - } + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } - [Fact] - public void Guid_Parse() { - var data = new List(); - data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); - } + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } - [Fact] - public void Guid_NewGuid() { - var data = new List(); - //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); - } + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } - [Fact] - public void Random() { - var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); - } - } + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs index 7577bd3e..7afc0189 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs @@ -4,664 +4,703 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqliteExpression { - public class DateTimeTest { - - ISelect select => g.sqlite.Select(); - - [Table(Name = "tb_topic111333")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - [Table(Name = "TestTypeInfo333")] - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - public DateTime Time { get; set; } - } - [Table(Name = "TestTypeParentInfo23123")] - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - public DateTime Time2 { get; set; } - } - [Fact] - public void Now() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void UtcNow() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) - } - [Fact] - public void Date() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) - } - [Fact] - public void TimeOfDay() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) - } - [Fact] - public void DayOfWeek() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) - } - [Fact] - public void Day() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) - } - [Fact] - public void DayOfYear() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) - } - [Fact] - public void Month() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (month(a.`CreateTime`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (month(a__Type.`Time`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (month(a__Type__Parent.`Time2`) > month(now())) - } - [Fact] - public void Year() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (year(a.`CreateTime`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (year(a__Type.`Time`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (year(a__Type__Parent.`Time2`) > year(now())) - } - [Fact] - public void Hour() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (hour(a.`CreateTime`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (hour(a__Type.`Time`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) - } - [Fact] - public void Minute() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (minute(a.`CreateTime`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (minute(a__Type.`Time`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) - } - [Fact] - public void Second() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (second(a.`CreateTime`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (second(a__Type.`Time`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (second(a__Type__Parent.`Time2`) > second(now())) - } - [Fact] - public void Millisecond() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) - } - [Fact] - public void AddDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) - } - [Fact] - public void AddHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) - } - [Fact] - public void AddMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) - } - [Fact] - public void AddMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) - } - [Fact] - public void AddMonths() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) - } - [Fact] - public void AddSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) - } - [Fact] - public void AddTicks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) - } - [Fact] - public void AddYears() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" - //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" - //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") - } - [Fact] - public void _ЧͬSubtract() { - var data = new List(); - data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" - //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" - //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - - [Fact] - public void DateTime_Compare() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((a.`CreateTime`) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) - } - [Fact] - public void DateTime_DaysInMonth() { - var data = new List(); - data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) - } - [Fact] - public void DateTime_Equals() { - var data = new List(); - data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); - data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void DateTime_IsLeapYear() { - var data = new List(); - data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); - data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) - } - [Fact] - public void DateTime_Parse() { - var data = new List(); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) - } - } +namespace FreeSql.Tests.SqliteExpression +{ + public class DateTimeTest + { + + ISelect select => g.sqlite.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/MathTest.cs index 0f0bb32a..3183a14d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/MathTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/MathTest.cs @@ -4,129 +4,153 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqliteExpression { - public class MathTest { +namespace FreeSql.Tests.SqliteExpression +{ + public class MathTest + { - ISelect select => g.sqlite.Select(); + ISelect select => g.sqlite.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } + public List Types { get; set; } + } - [Fact] - public void PI() { - var data = new List(); - data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); - } - [Fact] - public void Abs() { - var data = new List(); - data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Sign() { - var data = new List(); - data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); - } - [Fact] - public void Floor() { - var data = new List(); - data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); - } - [Fact] - public void Ceiling() { - var data = new List(); - data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Round() { - var data = new List(); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); - data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); - } - [Fact] - public void Exp() { - var data = new List(); - data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log() { - var data = new List(); - data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Log10() { - var data = new List(); - data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Pow() { - var data = new List(); - data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sqrt() { - var data = new List(); - data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Cos() { - var data = new List(); - data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Sin() { - var data = new List(); - data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Tan() { - var data = new List(); - data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Acos() { - var data = new List(); - //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Asin() { - var data = new List(); - //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan() { - var data = new List(); - data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); - } - [Fact] - public void Atan2() { - var data = new List(); - //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); - } - [Fact] - public void Truncate() { - var data = new List(); - //data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); - } - } + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + //data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs index 60985b66..020d405b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs @@ -4,109 +4,115 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqliteExpression { - public class OtherTest { +namespace FreeSql.Tests.SqliteExpression +{ + public class OtherTest + { - ISelect select => g.sqlite.Select(); + ISelect select => g.sqlite.Select(); - public OtherTest() { - } + public OtherTest() + { + } - [Fact] - public void Boolean() { - var t1 = select.Where(a => a.Bool == true).ToList(); - var t2 = select.Where(a => a.Bool != true).ToList(); - var t3 = select.Where(a => a.Bool == false).ToList(); - var t4 = select.Where(a => !a.Bool).ToList(); - var t5 = select.Where(a => a.Bool).ToList(); + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); - var t11 = select.Where(a => a.BoolNullable == true).ToList(); - var t22 = select.Where(a => a.BoolNullable != true).ToList(); - var t33 = select.Where(a => a.BoolNullable == false).ToList(); - var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); - var t55 = select.Where(a => a.BoolNullable.Value).ToList(); - } + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + } - [Fact] - public void Array() { - IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); - var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); - //in not in - var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); - var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); - var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); - var inarray = new[] { 1, 2, 3 }; - var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); - var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); - var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); - //in not in - var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); - var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); - var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); - var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); - var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); - var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); - var inarray2 = new List() { 1, 2, 3 }; - var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); - var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); - var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); - } + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + } - [Table(Name = "tb_alltype")] - class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } - public string id2 { get; set; } = "id2=10"; + public string id2 { get; set; } = "id2=10"; - public bool Bool { get; set; } - public sbyte SByte { get; set; } - public short Short { get; set; } - public int Int { get; set; } - public long Long { get; set; } - public byte Byte { get; set; } - public ushort UShort { get; set; } - public uint UInt { get; set; } - public ulong ULong { get; set; } - public double Double { get; set; } - public float Float { get; set; } - public decimal Decimal { get; set; } - public TimeSpan TimeSpan { get; set; } - public DateTime DateTime { get; set; } - public DateTime DateTimeOffSet { get; set; } - public byte[] Bytes { get; set; } - public string String { get; set; } - public Guid Guid { get; set; } + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } - public bool? BoolNullable { get; set; } - public sbyte? SByteNullable { get; set; } - public short? ShortNullable { get; set; } - public int? IntNullable { get; set; } - public long? testFielLongNullable { get; set; } - public byte? ByteNullable { get; set; } - public ushort? UShortNullable { get; set; } - public uint? UIntNullable { get; set; } - public ulong? ULongNullable { get; set; } - public double? DoubleNullable { get; set; } - public float? FloatNullable { get; set; } - public decimal? DecimalNullable { get; set; } - public TimeSpan? TimeSpanNullable { get; set; } - public DateTime? DateTimeNullable { get; set; } - public DateTime? DateTimeOffSetNullable { get; set; } - public Guid? GuidNullable { get; set; } + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } - public TableAllTypeEnumType1 Enum1 { get; set; } - public TableAllTypeEnumType1? Enum1Nullable { get; set; } - public TableAllTypeEnumType2 Enum2 { get; set; } - public TableAllTypeEnumType2? Enum2Nullable { get; set; } - } + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } - public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } - [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } - } + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index b8cc9920..182433ed 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -4,691 +4,715 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqliteExpression { - public class StringTest { - - ISelect select => g.sqlite.Select(); - - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } - } - class TestEqualsGuid { - public Guid id { get; set; } - } - - [Fact] - public void Equals__() { - var list = new List(); - list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); - list.Add(g.sqlite.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); - } - - [Fact] - public void Empty() { - var data = new List(); - data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ifnull(a.`Title`, '') = '') - } - - [Fact] - public void StartsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) - list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) - } - [Fact] - public void EndsWith() { - var list = new List(); - list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) - } - [Fact] - public void Contains() { - var list = new List(); - list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) - list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); - list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) - } - [Fact] - public void ToLower() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void ToUpper() { - var data = new List(); - data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(a.`Title`) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) - } - [Fact] - public void Substring() { - var data = new List(); - data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) - } - [Fact] - public void Length() { - var data = new List(); - data.Add(select.Where(a => a.Title.Length == 0).ToList()); - data.Add(select.Where(a => a.Title.Length == 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); - data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) - } - [Fact] - public void IndexOf() { - var data = new List(); - data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) - } - [Fact] - public void PadLeft() { - //var data = new List(); - //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); - //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); - //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); - //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - ////FROM `tb_topic` a, `TestTypeInfo` a__Type - ////WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); - //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); - //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); - //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); - //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - ////FROM `tb_topic` a, `TestTypeInfo` a__Type - ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void PadRight() { - //var data = new List(); - //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); - //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); - //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); - //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - ////FROM `tb_topic` a, `TestTypeInfo` a__Type - ////WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); - //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); - //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); - //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); - //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - ////FROM `tb_topic` a - ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); - - ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - ////FROM `tb_topic` a, `TestTypeInfo` a__Type - ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) - } - [Fact] - public void Trim() { - var data = new List(); - data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void TrimStart() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) - } - [Fact] - public void TrimEnd() { - var data = new List(); - data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(a.`Title`) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) - } - [Fact] - public void Replace() { - var data = new List(); - data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); - data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); - data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); - data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); - data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 - //FROM `tb_topic` a, `TestTypeInfo` a__Type - //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) - } - - [Fact] - public void string_IsNullOrEmpty() { - var data = new List(); - data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); - //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); - data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); - } - } +namespace FreeSql.Tests.SqliteExpression +{ + public class StringTest + { + + ISelect select => g.sqlite.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.sqlite.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/TimeSpanTest.cs index 74b1fe35..8ad219f6 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/TimeSpanTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/TimeSpanTest.cs @@ -4,257 +4,290 @@ using System.Collections.Generic; using System.Linq; using Xunit; -namespace FreeSql.Tests.SqliteExpression { - public class TimeSpanTest { +namespace FreeSql.Tests.SqliteExpression +{ + public class TimeSpanTest + { - ISelect select => g.sqlite.Select(); + ISelect select => g.sqlite.Select(); - [Table(Name = "tb_topic")] - class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } - public List Types { get; set; } - } - [Fact] - public void Zero() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) - } - [Fact] - public void MinValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) - } - [Fact] - public void MaxValue() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) - } - [Fact] - public void Days() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) - } - [Fact] - public void Hours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) - } - [Fact] - public void Milliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) - } - [Fact] - public void Minutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) - } - [Fact] - public void Seconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) - } - [Fact] - public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) - } - [Fact] - public void TotalDays() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) - } - [Fact] - public void TotalHours() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) - } - [Fact] - public void TotalMilliseconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) - } - [Fact] - public void TotalMinutes() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) - } - [Fact] - public void TotalSeconds() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) - } - [Fact] - public void Add() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) - } - [Fact] - public void Subtract() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) - } - [Fact] - public void CompareTo() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void this_Equals() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void this_ToString() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') - } + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } - [Fact] - public void TimeSpan_Compare() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) - } - [Fact] - public void TimeSpan_Equals() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromDays() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) - } - [Fact] - public void TimeSpan_FromHours() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) - } - [Fact] - public void TimeSpan_FromMilliseconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) - } - [Fact] - public void TimeSpan_FromMinutes() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) - } - [Fact] - public void TimeSpan_FromSeconds() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) - } - [Fact] - public void TimeSpan_FromTicks() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) - } - [Fact] - public void TimeSpan_Parse() { - var data = new List(); - data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic` a - //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) - } - } + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 9695c6a0..e5e93ff3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -11,428 +11,468 @@ using System.Linq.Expressions; using System.Threading.Tasks; using System.Collections; -namespace FreeSql.Tests { - public class UnitTest1 { - - public class Order { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string OrderTitle { get; set; } - public string CustomerName { get; set; } - public DateTime TransactionDate { get; set; } - public virtual List OrderDetails { get; set; } - } - public class OrderDetail { - [Column(IsIdentity = true)] - public int Id { get; set; } - - public int OrderId { get; set; } - public virtual Order Order { get; set; } - } - - ISelect select => g.mysql.Select(); - - class TestUser { - [Column(IsIdentity = true)] - public int stringid { get; set; } - public string accname { get; set; } - public LogUserOn LogOn { get; set; } - - } - class LogUserOn { - public int id { get; set; } - public int userstrId { get; set; } - } - - class ServiceRequestNew { - public Guid id { get; set; } - public string acptStaffDeptId { get; set; } - public DateTime acptTime { get; set; } - public int crtWrkfmFlag { get; set; } - [Column(DbType = "nvarchar2(1500)")] - public string srvReqstCntt { get; set; } - } - - public class TestEntity : EntityBase { - public int Test { get; set; } - public string Title { get; set; } - public override Task Persistent(IRepositoryUnitOfWork uof) { - uof.GetGuidRepository().Insert(this); - return Task.CompletedTask; - } - public override Task Persistent() { - var res = FreeSqlDb.Insert(this); - res.ExecuteInserted(); - return Task.CompletedTask; - } - } - public abstract class EntityBase : DomainInfrastructure { - [Column(IsPrimary = true, IsIdentity = true)] - public TKey Id { get; set; } - public Guid CompanyId { get; set; } - [Column(IsVersion = true)] - public int Version { get; set; } - } - - public abstract class DomainInfrastructure { - [Column(IsIgnore = true)] - public IFreeSql FreeSqlDb { - get { - return g.sqlite; - } - } - - - public abstract Task Persistent(IRepositoryUnitOfWork uof); - public abstract Task Persistent(); - } - - public class Model1 { - [Column(IsIdentity = true)] - public int id { get; set; } - - public string title { get; set; } - - public ICollection Childs { get; set; } - - public int M2Id { get; set; } - - [Column(IsIgnore = true)] - public List TestManys { get; set; } - - } - - public class Model2 { - - [Column(IsIdentity = true)] - public int id { get; set; } - public string Title { get; set; } - - public Model1 Parent { get; set; } - public int Parent_id { get; set; } - - public string Ccc { get; set; } - public DateTime Date { get; set; } - - [Column(Name = "Waxxx2")] - public int Wa_xxx2 { get; set; } - } - - public class TestEnumable : IEnumerable { - public IEnumerator GetEnumerator() { - throw new NotImplementedException(); - } - - IEnumerator IEnumerable.GetEnumerator() { - throw new NotImplementedException(); - } - } - - public class TestEnum { - public Guid id { get; set; } - public Enum em { get; set; } - } - - /// - /// - /// - [Table(Name = "news_article")] - public class NewsArticle { - /// - /// - /// - [Column(Name = "article_id", IsIdentity = true, IsPrimary = true)] - public int ArticleId { get; set; } - - /// - /// - /// - [Column(Name = "article_title")] - public string ArticleTitle { get; set; } - - /// - /// - /// - [Column(Name = "category_id")] - public int CategoryId { get; set; } - - /// - /// - /// - [Column(Name = "channel_id")] - public int ChannelId { get; set; } - - /// - /// 类型 - /// - [Column(Name = "type_id")] - public int TypeId { get; set; } - - /// - /// 内容简介 - /// - [Column(Name = "summary")] - public string Summary { get; set; } - - /// - /// 缩略图 - /// - [Column(Name = "thumbnail")] - public string Thumbnail { get; set; } - - /// - /// 点击量 - /// - [Column(Name = "hits")] - public int Hits { get; set; } - - /// - /// - /// - [Column(Name = "is_display")] - public int IsDisplay { get; set; } - - /// - /// - /// - [Column(Name = "status")] - public int Status { get; set; } - - /// - /// - /// - [Column(Name = "create_time")] - public int CreateTime { get; set; } - - /// - /// - /// - [Column(Name = "release_time")] - public int ReleaseTime { get; set; } - - public DateTime testaddtime { get; set; } - public DateTime? testaddtime2 { get; set; } - } - - public class NewsArticleDto : NewsArticle { - - } - - - public class TaskBuildInfo { - [FreeSql.DataAnnotations.Column(IsPrimary = true)] - public Guid Id { get; set; } - public Guid TbId { get; set; } - public Guid DataBaseConfigId { get; set; } - public string Name { get; set; } - public int Level { get; set; } - - [Column(IsIgnore = true)] - public virtual TaskBuild TaskBuild { get; set; } - } - public class Templates { - /// - /// 测试中文重命名id - /// - [Column(IsPrimary = true, OldName = "Id")] - public Guid Id2 { get; set; } - public string Title { get; set; } - public DateTime AddTime { get; set; } = DateTime.Now; - public DateTime EditTime { get; set; } - public string Code { get; set; } - } - public class TaskBuild { - - [FreeSql.DataAnnotations.Column(IsPrimary = true)] - public Guid Id { get; set; } - public string TaskName { get; set; } - public Guid TemplatesId { get; set; } - public string GeneratePath { get; set; } - public string FileName { get; set; } - public string NamespaceName { get; set; } - public bool OptionsEntity01 { get; set; } = false; - public bool OptionsEntity02 { get; set; } = false; - public bool OptionsEntity03 { get; set; } = false; - public int OptionsEntity04 { get; set; } - - [Navigate("TbId")] - public virtual ICollection Builds { get; set; } - public Templates Templates { get; set; } - } - - public class SqlFunc { - public static string FormatDateTime() { - return ""; - } - } - - [Fact] - public void Test1() { - - var dcksdkdsk = g.sqlite.Select().Where(a => a.testaddtime2.HasValue).ToSql(); - var dcksdkdsk2 = g.sqlite.Select().Where(a => !a.testaddtime2.HasValue).ToSql(); - - var testgrpsql = g.sqlite.Select() - .From((a, b) => a.InnerJoin(aa => aa.TemplatesId - == b.Id2)) - .GroupBy((a, b) => b.Code) - .ToSql(a => new { - a.Key, - sss = a.Sum(a.Value.Item1.Id), - sss2 = a.Sum(a.Value.Item2.Id2) - }); - - var testgrpsql2 = g.sqlite.Select() - .From((a, b) => a.InnerJoin(aa => aa.TemplatesId - == b.Id2)) - .GroupBy((a, b) => b.Code) - .ToList(a => new { - a.Key, - sss = a.Sum(a.Value.Item1.Id), - sss2 = a.Sum(a.Value.Item2.Id2) - }); - - - var tbid = g.sqlite.Select().First()?.Id ?? Guid.Empty; - - var testarray = new[] { 1, 2, 3 }; - var tbidsql = g.sqlite.Update().Where(a => a.Id == tbid) - .Set(a => new TaskBuild { - FileName = "111", - TaskName = a.TaskName + "333", - OptionsEntity02 = false, - OptionsEntity04 = testarray[0] - }).ToSql(); - - - var dkdkdkd = g.oracle.Select().ToList(); - - - - //var testaddlist = new List(); - //for(var a = 0; a < 133905; a++) { - // testaddlist.Add(new NewsArticle { - // ArticleTitle = "testaddlist_topic" + a, - // Hits = a, - // }); - //} - //g.sqlite.Insert(testaddlist) - // //.NoneParameter() - // .ExecuteAffrows(); - - -g.mysql.Aop.ParseExpression = (s, e) => { - if (e.Expression.NodeType == ExpressionType.Call) { - var callExp = e.Expression as MethodCallExpression; - if (callExp.Object?.Type == typeof(DateTime) && - callExp.Method.Name == "ToString" && - callExp.Arguments.Count == 1 && - callExp.Arguments[0].Type == typeof(string) && - callExp.Arguments[0].NodeType == ExpressionType.Constant) { - var format = (callExp.Arguments[0] as ConstantExpression)?.Value?.ToString(); - - if (string.IsNullOrEmpty(format) == false) { - var tmp = e.FreeParse(callExp.Object); - - switch(format) { - case "yyyy-MM-dd HH:mm": - tmp = $"date_format({tmp}, '%Y-%m-%d %H:%i')"; - break; - } - e.Result = tmp; - } - } - } -}; +namespace FreeSql.Tests +{ + public class UnitTest1 + { + + public class Order + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string OrderTitle { get; set; } + public string CustomerName { get; set; } + public DateTime TransactionDate { get; set; } + public virtual List OrderDetails { get; set; } + } + public class OrderDetail + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int OrderId { get; set; } + public virtual Order Order { get; set; } + } + + ISelect select => g.mysql.Select(); + + class TestUser + { + [Column(IsIdentity = true)] + public int stringid { get; set; } + public string accname { get; set; } + public LogUserOn LogOn { get; set; } + + } + class LogUserOn + { + public int id { get; set; } + public int userstrId { get; set; } + } + + class ServiceRequestNew + { + public Guid id { get; set; } + public string acptStaffDeptId { get; set; } + public DateTime acptTime { get; set; } + public int crtWrkfmFlag { get; set; } + [Column(DbType = "nvarchar2(1500)")] + public string srvReqstCntt { get; set; } + } + + public class TestEntity : EntityBase + { + public int Test { get; set; } + public string Title { get; set; } + public override Task Persistent(IRepositoryUnitOfWork uof) + { + uof.GetGuidRepository().Insert(this); + return Task.CompletedTask; + } + public override Task Persistent() + { + var res = FreeSqlDb.Insert(this); + res.ExecuteInserted(); + return Task.CompletedTask; + } + } + public abstract class EntityBase : DomainInfrastructure + { + [Column(IsPrimary = true, IsIdentity = true)] + public TKey Id { get; set; } + public Guid CompanyId { get; set; } + [Column(IsVersion = true)] + public int Version { get; set; } + } + + public abstract class DomainInfrastructure + { + [Column(IsIgnore = true)] + public IFreeSql FreeSqlDb + { + get + { + return g.sqlite; + } + } + + + public abstract Task Persistent(IRepositoryUnitOfWork uof); + public abstract Task Persistent(); + } + + public class Model1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public string title { get; set; } + + public ICollection Childs { get; set; } + + public int M2Id { get; set; } + + [Column(IsIgnore = true)] + public List TestManys { get; set; } + + } + + public class Model2 + { + + [Column(IsIdentity = true)] + public int id { get; set; } + public string Title { get; set; } + + public Model1 Parent { get; set; } + public int Parent_id { get; set; } + + public string Ccc { get; set; } + public DateTime Date { get; set; } + + [Column(Name = "Waxxx2")] + public int Wa_xxx2 { get; set; } + } + + public class TestEnumable : IEnumerable + { + public IEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } + } + + public class TestEnum + { + public Guid id { get; set; } + public Enum em { get; set; } + } + + /// + /// + /// + [Table(Name = "news_article")] + public class NewsArticle + { + /// + /// + /// + [Column(Name = "article_id", IsIdentity = true, IsPrimary = true)] + public int ArticleId { get; set; } + + /// + /// + /// + [Column(Name = "article_title")] + public string ArticleTitle { get; set; } + + /// + /// + /// + [Column(Name = "category_id")] + public int CategoryId { get; set; } + + /// + /// + /// + [Column(Name = "channel_id")] + public int ChannelId { get; set; } + + /// + /// 类型 + /// + [Column(Name = "type_id")] + public int TypeId { get; set; } + + /// + /// 内容简介 + /// + [Column(Name = "summary")] + public string Summary { get; set; } + + /// + /// 缩略图 + /// + [Column(Name = "thumbnail")] + public string Thumbnail { get; set; } + + /// + /// 点击量 + /// + [Column(Name = "hits")] + public int Hits { get; set; } + + /// + /// + /// + [Column(Name = "is_display")] + public int IsDisplay { get; set; } + + /// + /// + /// + [Column(Name = "status")] + public int Status { get; set; } + + /// + /// + /// + [Column(Name = "create_time")] + public int CreateTime { get; set; } + + /// + /// + /// + [Column(Name = "release_time")] + public int ReleaseTime { get; set; } + + public DateTime testaddtime { get; set; } + public DateTime? testaddtime2 { get; set; } + } + + public class NewsArticleDto : NewsArticle + { + + } + + + public class TaskBuildInfo + { + [FreeSql.DataAnnotations.Column(IsPrimary = true)] + public Guid Id { get; set; } + public Guid TbId { get; set; } + public Guid DataBaseConfigId { get; set; } + public string Name { get; set; } + public int Level { get; set; } + + [Column(IsIgnore = true)] + public virtual TaskBuild TaskBuild { get; set; } + } + public class Templates + { + /// + /// 测试中文重命名id + /// + [Column(IsPrimary = true, OldName = "Id")] + public Guid Id2 { get; set; } + public string Title { get; set; } + public DateTime AddTime { get; set; } = DateTime.Now; + public DateTime EditTime { get; set; } + public string Code { get; set; } + } + public class TaskBuild + { + + [FreeSql.DataAnnotations.Column(IsPrimary = true)] + public Guid Id { get; set; } + public string TaskName { get; set; } + public Guid TemplatesId { get; set; } + public string GeneratePath { get; set; } + public string FileName { get; set; } + public string NamespaceName { get; set; } + public bool OptionsEntity01 { get; set; } = false; + public bool OptionsEntity02 { get; set; } = false; + public bool OptionsEntity03 { get; set; } = false; + public int OptionsEntity04 { get; set; } + + [Navigate("TbId")] + public virtual ICollection Builds { get; set; } + public Templates Templates { get; set; } + } + + public class SqlFunc + { + public static string FormatDateTime() + { + return ""; + } + } + + [Fact] + public void Test1() + { + + var dcksdkdsk = g.sqlite.Select().Where(a => a.testaddtime2.HasValue).ToSql(); + var dcksdkdsk2 = g.sqlite.Select().Where(a => !a.testaddtime2.HasValue).ToSql(); + + var testgrpsql = g.sqlite.Select() + .From((a, b) => a.InnerJoin(aa => aa.TemplatesId + == b.Id2)) + .GroupBy((a, b) => b.Code) + .ToSql(a => new + { + a.Key, + sss = a.Sum(a.Value.Item1.Id), + sss2 = a.Sum(a.Value.Item2.Id2) + }); + + var testgrpsql2 = g.sqlite.Select() + .From((a, b) => a.InnerJoin(aa => aa.TemplatesId + == b.Id2)) + .GroupBy((a, b) => b.Code) + .ToList(a => new + { + a.Key, + sss = a.Sum(a.Value.Item1.Id), + sss2 = a.Sum(a.Value.Item2.Id2) + }); + + + var tbid = g.sqlite.Select().First()?.Id ?? Guid.Empty; + + var testarray = new[] { 1, 2, 3 }; + var tbidsql = g.sqlite.Update().Where(a => a.Id == tbid) + .Set(a => new TaskBuild + { + FileName = "111", + TaskName = a.TaskName + "333", + OptionsEntity02 = false, + OptionsEntity04 = testarray[0] + }).ToSql(); + + + var dkdkdkd = g.oracle.Select().ToList(); + + + + //var testaddlist = new List(); + //for(var a = 0; a < 133905; a++) { + // testaddlist.Add(new NewsArticle { + // ArticleTitle = "testaddlist_topic" + a, + // Hits = a, + // }); + //} + //g.sqlite.Insert(testaddlist) + // //.NoneParameter() + // .ExecuteAffrows(); + + + g.mysql.Aop.ParseExpression = (s, e) => + { + if (e.Expression.NodeType == ExpressionType.Call) + { + var callExp = e.Expression as MethodCallExpression; + if (callExp.Object?.Type == typeof(DateTime) && + callExp.Method.Name == "ToString" && + callExp.Arguments.Count == 1 && + callExp.Arguments[0].Type == typeof(string) && + callExp.Arguments[0].NodeType == ExpressionType.Constant) + { + var format = (callExp.Arguments[0] as ConstantExpression)?.Value?.ToString(); + + if (string.IsNullOrEmpty(format) == false) + { + var tmp = e.FreeParse(callExp.Object); + + switch (format) + { + case "yyyy-MM-dd HH:mm": + tmp = $"date_format({tmp}, '%Y-%m-%d %H:%i')"; + break; + } + e.Result = tmp; + } + } + } + }; + + g.mysql.Select().ToList(a => new + { + testaddtime = a.testaddtime.ToString("yyyy-MM-dd HH:mm") + }); - g.mysql.Select().ToList(a => new { - testaddtime = a.testaddtime.ToString("yyyy-MM-dd HH:mm") - }); + var ttdkdk = g.mysql.Select().Where(a => a.NamespaceName == "ddd").ToSql(); - var ttdkdk = g.mysql.Select().Where(a => a.NamespaceName == "ddd").ToSql(); + var tsqlddd = g.sqlite.Select().Where(a => + g.sqlite.Select().Where(b => b.NamespaceName == a.ArticleTitle) + .Where("@id=1", new { id = 1 }).Any() + ).ToSql(); - var tsqlddd = g.sqlite.Select().Where(a => - g.sqlite.Select().Where(b => b.NamespaceName == a.ArticleTitle) - .Where("@id=1", new { id = 1 }).Any() - ).ToSql(); + g.sqlite.SetDbContextOptions(opt => opt.EnableAddOrUpdateNavigateList = true); + var trepo = g.sqlite.GetGuidRepository(); + trepo.Insert(new TaskBuild + { + TaskName = "tt11", + Builds = new[] { + new TaskBuildInfo { + Level = 1, + Name = "t111_11" + } + } + }); - g.sqlite.SetDbContextOptions(opt => opt.EnableAddOrUpdateNavigateList = true); - var trepo = g.sqlite.GetGuidRepository(); - trepo.Insert(new TaskBuild { - TaskName = "tt11", - Builds = new[] { - new TaskBuildInfo { - Level = 1, - Name = "t111_11" - } - } - }); + var ttdkdkd = trepo.Select.Where(a => a.Builds.AsSelect().Any()).ToList(); - var ttdkdkd = trepo.Select.Where(a => a.Builds.AsSelect().Any()).ToList(); + var list1113233 = trepo.Select.ToList(); - var list1113233 = trepo.Select.ToList(); + var entity = new NewsArticle + { + ArticleId = 1, + ArticleTitle = "测试标题" + }; + var where = new NewsArticle + { + ArticleId = 1, + ChannelId = 1, + }; - var entity = new NewsArticle { - ArticleId = 1, - ArticleTitle = "测试标题" - }; - var where = new NewsArticle { - ArticleId = 1, - ChannelId = 1, - }; + g.mysql.Insert(new[] { entity }).ExecuteAffrows(); - g.mysql.Insert(new[] { entity }).ExecuteAffrows(); + var sqldddkdk = g.mysql.Update(where) + .SetSource(entity) + .UpdateColumns(x => new { x.Status, x.CategoryId, x.ArticleTitle }) + .ToSql(); - var sqldddkdk = g.mysql.Update(where) - .SetSource(entity) - .UpdateColumns(x => new { x.Status, x.CategoryId, x.ArticleTitle }) - .ToSql(); + var sqldddklist = g.mysql.Select().Select(a => new NewsArticleDto { }).ToList(); - var sqldddklist = g.mysql.Select().Select(a => new NewsArticleDto { }).ToList(); + var sql1111333 = g.mysql.Update() + .SetSource(new Model2 { id = 1, Title = "xxx", Parent_id = 0 }) + .UpdateColumns(x => new { x.Parent_id, x.Date, x.Wa_xxx2 }) + .NoneParameter() + .ToSql(); - var sql1111333 = g.mysql.Update() - .SetSource(new Model2 { id = 1, Title = "xxx", Parent_id = 0 }) - .UpdateColumns(x => new { x.Parent_id, x.Date, x.Wa_xxx2 }) - .NoneParameter() - .ToSql(); - - g.sqlite.Insert(new TestEnum { }).ExecuteAffrows(); - var telist = g.sqlite.Select().ToList(); + g.sqlite.Insert(new TestEnum { }).ExecuteAffrows(); + var telist = g.sqlite.Select().ToList(); - Assert.Throws(() => g.sqlite.CodeFirst.SyncStructure()); + Assert.Throws(() => g.sqlite.CodeFirst.SyncStructure()); - var TestEnumable = new TestEnumable(); - + var TestEnumable = new TestEnumable(); - g.sqlite.GetRepository().Insert(new Model1 { - title = "test_" + DateTime.Now.ToString("yyyyMMddHHmmss"), - M2Id = DateTime.Now.Second + DateTime.Now.Minute, - Childs = new[] { - new Model2 { - Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0001", - }, - new Model2 { - Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0002", - }, - new Model2 { - Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0003", - }, - new Model2 { - Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0004", - } - } - }); - var includet1 = g.sqlite.Select() - .IncludeMany(a => a.Childs.Take(2), s => s.Where(a => a.id > 0)) - .IncludeMany(a => a.TestManys.Take(1).Where(b => b.id == a.id)) - .Where(a => a.id > 10) - .ToList(); + g.sqlite.GetRepository().Insert(new Model1 + { + title = "test_" + DateTime.Now.ToString("yyyyMMddHHmmss"), + M2Id = DateTime.Now.Second + DateTime.Now.Minute, + Childs = new[] { + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0001", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0002", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0003", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0004", + } + } + }); + var includet1 = g.sqlite.Select() + .IncludeMany(a => a.Childs.Take(2), s => s.Where(a => a.id > 0)) + .IncludeMany(a => a.TestManys.Take(1).Where(b => b.id == a.id)) + .Where(a => a.id > 10) + .ToList(); @@ -451,116 +491,124 @@ g.mysql.Aop.ParseExpression = (s, e) => { - var ttt1 = g.sqlite.Select().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList(); + var ttt1 = g.sqlite.Select().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList(); - var linqto1 = - from p in g.sqlite.Select() - where p.Id >= 0 - // && p.OrderDetails.AsSelect().Where(c => c.Id > 10).Any() - orderby p.Id descending - orderby p.CustomerName ascending - select new { Name = p.CustomerName, Length = p.Id }; + var linqto1 = + from p in g.sqlite.Select() + where p.Id >= 0 + // && p.OrderDetails.AsSelect().Where(c => c.Id > 10).Any() + orderby p.Id descending + orderby p.CustomerName ascending + select new { Name = p.CustomerName, Length = p.Id }; - var testddd = new TestEntity { - Test = 22, - Title = "xxx" - }; - //testddd.Persistent().Wait(); - g.sqlite.GetRepository().Insert(testddd); - var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var testddd = new TestEntity + { + Test = 22, + Title = "xxx" + }; + //testddd.Persistent().Wait(); + g.sqlite.GetRepository().Insert(testddd); - var aggsql1 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist1 = select - .GroupBy(a => a.Title) - .ToList(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid) - }); + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); - var aggsql2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToSql(b => new { - b.Key.Title, - b.Key.yyyy, + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); - var aggtolist2 = select - .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) - .ToList(b => new { - b.Key.Title, - b.Key.yyyy, + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), - sum2 = b.Sum(b.Value.TypeGuid) - }); + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, - var aggsql3 = select - .GroupBy(a => a.Title) - .ToSql(b => new { - b.Key, - cou = b.Count(), - sum = b.Sum(b.Key), - sum2 = b.Sum(b.Value.TypeGuid), - sum3 = b.Sum(b.Value.Type.Parent.Parent.Id) - }); + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); - var sqlrepos = g.sqlite.GetRepository(); - sqlrepos.Insert(new TestTypeParentInfo { - Name = "testroot", - Childs = new[] { - new TestTypeParentInfo { - Name = "testpath2", - Childs = new[] { - new TestTypeParentInfo { - Name = "testpath3", - Childs = new[] { - new TestTypeParentInfo { - Name = "11" - } - } - } - } - } - } - }); + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Parent.Id) + }); - var sql = g.sqlite.Select().Where(a => a.Parent.Parent.Parent.Name == "testroot").ToSql(); - var sql222 = g.sqlite.Select().Where(a => a.Parent.Parent.Parent.Name == "testroot").ToList(); - - - Expression> orderBy = null; - orderBy = a => a.CreateTime; - var testsql1 = select.OrderBy(orderBy).ToSql(); - - orderBy = a => a.Title; - - var testsql2 = select.OrderBy(orderBy).ToSql(); - - - var testjson = @"[ + var sqlrepos = g.sqlite.GetRepository(); + sqlrepos.Insert(new TestTypeParentInfo + { + Name = "testroot", + Childs = new[] { + new TestTypeParentInfo { + Name = "testpath2", + Childs = new[] { + new TestTypeParentInfo { + Name = "testpath3", + Childs = new[] { + new TestTypeParentInfo { + Name = "11" + } + } + } + } + } + } + }); + + var sql = g.sqlite.Select().Where(a => a.Parent.Parent.Parent.Name == "testroot").ToSql(); + var sql222 = g.sqlite.Select().Where(a => a.Parent.Parent.Parent.Name == "testroot").ToList(); + + + Expression> orderBy = null; + orderBy = a => a.CreateTime; + var testsql1 = select.OrderBy(orderBy).ToSql(); + + orderBy = a => a.Title; + + var testsql2 = select.OrderBy(orderBy).ToSql(); + + + var testjson = @"[ { ""acptNumBelgCityName"":""泰州"", ""concPrsnName"":""常**"", @@ -578,325 +626,355 @@ g.mysql.Aop.ParseExpression = (s, e) => { ""acptStaffDeptId"":""0003002101010001000600020023"" } ]"; - //var dic = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); - var reqs = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); - reqs.ForEach(t => { - g.oracle.Insert(t).ExecuteAffrows(); - - }); - - - - var sql111 = g.sqlite.Select().AsTable((a, b) => "(select * from TestUser where stringid > 10)").Page(1, 10).ToSql(); - - - var xxx = g.sqlite.Select().GroupBy(a => new { a.stringid }).ToList(a => a.Key.stringid); - - var tuser = g.sqlite.Select().Where(u => u.accname == "admin") - .InnerJoin(a => a.LogOn.id == a.stringid).ToSql(); - - - var parentSelect1 = select.Where(a => a.Type.Parent.Parent.Parent.Parent.Name == "").Where(b => b.Type.Name == "").ToSql(); - - - var collSelect1 = g.mysql.Select().Where(a => - a.OrderDetails.AsSelect().Any(b => b.Id > 100) - ); - - var collectionSelect = select.Where(a => - //a.Type.Guid == a.TypeGuid && - //a.Type.Parent.Id == a.Type.ParentId && - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( - //b => b.ParentId == a.Type.Parent.Id - ) - ); - - var collectionSelect2 = select.Where(a => - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( - b => b.Parent.Name == "xxx" && b.Parent.Parent.Name == "ccc" - && b.Parent.Parent.Parent.Types.AsSelect().Any(cb => cb.Name == "yyy") - ) - ); - - var collectionSelect3 = select.Where(a => - a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( - bbb => bbb.Parent.Types.AsSelect().Where(lv2 => lv2.Name == bbb.Name + "111").Any( - ) - ) - ); - - - var neworder = new Order { - CustomerName = "testCustomer", - OrderTitle = "xxx#cccksksk", - TransactionDate = DateTime.Now, - OrderDetails = new List(new[] { - new OrderDetail { - - }, - new OrderDetail { - - } - }) - }; - - g.mysql.GetRepository().Insert(neworder); - - var order = g.mysql.Select().Where(a => a.Id == neworder.Id).ToOne(); //查询订单表 - if (order == null) { - var orderId = g.mysql.Insert(new Order { }).ExecuteIdentity(); - order = g.mysql.Select(orderId).ToOne(); - } - - - var orderDetail1 = order.OrderDetails; //第一次访问,查询数据库 - var orderDetail2 = order.OrderDetails; //第二次访问,不查 - var order1 = orderDetail1.FirstOrDefault().Order; //访问导航属性,此时不查数据库,因为 OrderDetails 查询出来的时候已填充了该属性 - - - var queryable = g.mysql.Queryable().Where(a => a.Id == 1).ToList(); - - var sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && - select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - //.Offset(a.Id) - .Any() - ).Any() - ).ToList(); - - - var groupbysql = g.mysql.Select().From((s, b, c) => s - .Where(a => a.Id == 1) - .WhereIf(false, a => a.Id == 2) - ) - .WhereIf(true, (a, b, c) => a.Id == 3) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()).ToSql(a => new { - cou = a.Sum(a.Value.Item1.Id), - a.Key.mod4, a.Key.tt2, max = a.Max("a.id"), max2 = Convert.ToInt64("max(a.id)") }); - - var groupbysql2 = g.mysql.Select().From((s, b, c) => s - .Where(a => a.Id == 1) - .WhereIf(true, a => a.Id == 2) - ) - .WhereIf(false, (a, b, c) => a.Id == 3) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()).ToSql(a => a.Key.mod4); - - var groupby = g.mysql.Select().From((s, b, c) => s - .Where(a => a.Id == 1) - .WhereIf(true, a => a.Id == 2) - ) - .WhereIf(true, (a,b,c) => a.Id == 3) - .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()) - .ToList(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4), - ccc2 = a.Key.tt2 ?? "now()", - //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") - }); - - var arrg = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - - var arrg222 = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - - var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - - - var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToList(); - var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToList(); - var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToList(); - - //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( - // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, - // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") - //); - - //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) - //.Where(a => a.Id == 1).ToSql(); - - var sql4 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name == "xxx")).ToList(); - //.Where(a => a.Id == 1).ToSql(); - - - var list111 = select.From((s, b, c) => s - .InnerJoin(a => a.TypeGuid == b.Guid) - .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name != "xxx")) - .ToList((a, b, c) => new { - a.Id, - a.Title, - a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new { - a.Id, - tp2 = a.Type.Name - }, - tp3 = new { - a.Id, - tp33 = new { - a.Id - } - } - }); - - var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToList(); - - - - - var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToList(); - - - - - - //((JoinType.LeftJoin, a.TypeGuid == b.Guid), (JoinType.InnerJoin, b.ParentId == c.Id) - - var t11112 = g.mysql.Select().ToList(a => new { - a.Id, a.Title, a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new { - a.Id, tp2 = a.Type.Name - }, - tp3 = new { - a.Id, - tp33 = new { - a.Id - } - } - - }); - - var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - - - var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); - - var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); - - var t3 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => a.Title).ToSql(); - var t4 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - var t5 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => new { a.Title, a.TypeGuid, a.CreateTime }).ToSql(); - var t6 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).InsertColumns(a => new { a.Title }).ToSql(); - - var t7 = g.mysql.Update().ToSql(); - var t8 = g.mysql.Update().Where(new TestInfo { }).ToSql(); - var t9 = g.mysql.Update().Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); - var t10 = g.mysql.Update().Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); - var t11 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).ToSql(); - var t12 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Where(a => a.Title == "111").ToSql(); - - var t13 = g.mysql.Update().Set(a => a.Title, "222111").ToSql(); - var t14 = g.mysql.Update().Set(a => a.Title, "222111").Where(new TestInfo { }).ToSql(); - var t15 = g.mysql.Update().Set(a => a.Title, "222111").Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); - var t16 = g.mysql.Update().Set(a => a.Title, "222111").Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); - var t17 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.Title, "222111").ToSql(); - var t18 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.Title, "222111").Where(a => a.Title == "111").ToSql(); - - var t19 = g.mysql.Update().Set(a => a.TypeGuid + 222111).ToSql(); - var t20 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new TestInfo { }).ToSql(); - var t21 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); - var t22 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); - var t23 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.TypeGuid + 222111).ToSql(); - var t24 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.TypeGuid + 222111).Where(a => a.Title == "111").ToSql(); - - - var t1000 = g.sqlite.Select().ToSql(); - var t1001 = g.sqlite.Insert().AppendData(new ExamPaper()).ToSql(); - } - } - class NullAggreTestTable { - [Column(IsIdentity = true)] - public int Id { get; set; } - } - - - [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] - class TestInfo { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } - - [Table(Name = "TestTypeInfoT1")] - class TestTypeInfo { - [Column(IsIdentity = true)] - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } - } - - [Table(Name = "TestTypeParentInfoT1")] - class TestTypeParentInfo { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Name { get; set; } - - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public ICollection Childs { get; set; } - - public List Types { get; set; } - } - - - /// - /// 试卷表 - /// - [Table(Name = "exam_paper")] - public class ExamPaper { - - public long id { get; set; } - - /// - /// 考核计划ID - /// - public long AssessmentPlanId { get; set; } - /// - /// 总分 - /// - public int TotalScore { get; set; } - - public DateTime BeginTime { get; set; } - - public DateTime? EndTime { get; set; } - - //[Column(IsIgnore = true)] - //public ExamStatus Status { get; set; } - public ExamStatus Status { - get { - if (DateTime.Now <= BeginTime) - return ExamStatus.Wait; - if (BeginTime <= DateTime.Now && (!EndTime.HasValue || DateTime.Now < EndTime)) - return ExamStatus.Started; - if (BeginTime <= DateTime.Now && (EndTime.HasValue && EndTime <= DateTime.Now)) - return ExamStatus.End; - return ExamStatus.Wait; - } - } - } - public enum ExamStatus { Wait, Started, End } + //var dic = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); + var reqs = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); + reqs.ForEach(t => + { + g.oracle.Insert(t).ExecuteAffrows(); + + }); + + + + var sql111 = g.sqlite.Select().AsTable((a, b) => "(select * from TestUser where stringid > 10)").Page(1, 10).ToSql(); + + + var xxx = g.sqlite.Select().GroupBy(a => new { a.stringid }).ToList(a => a.Key.stringid); + + var tuser = g.sqlite.Select().Where(u => u.accname == "admin") + .InnerJoin(a => a.LogOn.id == a.stringid).ToSql(); + + + var parentSelect1 = select.Where(a => a.Type.Parent.Parent.Parent.Parent.Name == "").Where(b => b.Type.Name == "").ToSql(); + + + var collSelect1 = g.mysql.Select().Where(a => + a.OrderDetails.AsSelect().Any(b => b.Id > 100) + ); + + var collectionSelect = select.Where(a => + //a.Type.Guid == a.TypeGuid && + //a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + //b => b.ParentId == a.Type.Parent.Id + ) + ); + + var collectionSelect2 = select.Where(a => + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + b => b.Parent.Name == "xxx" && b.Parent.Parent.Name == "ccc" + && b.Parent.Parent.Parent.Types.AsSelect().Any(cb => cb.Name == "yyy") + ) + ); + + var collectionSelect3 = select.Where(a => + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + bbb => bbb.Parent.Types.AsSelect().Where(lv2 => lv2.Name == bbb.Name + "111").Any( + ) + ) + ); + + + var neworder = new Order + { + CustomerName = "testCustomer", + OrderTitle = "xxx#cccksksk", + TransactionDate = DateTime.Now, + OrderDetails = new List(new[] { + new OrderDetail { + + }, + new OrderDetail { + + } + }) + }; + + g.mysql.GetRepository().Insert(neworder); + + var order = g.mysql.Select().Where(a => a.Id == neworder.Id).ToOne(); //查询订单表 + if (order == null) + { + var orderId = g.mysql.Insert(new Order { }).ExecuteIdentity(); + order = g.mysql.Select(orderId).ToOne(); + } + + + var orderDetail1 = order.OrderDetails; //第一次访问,查询数据库 + var orderDetail2 = order.OrderDetails; //第二次访问,不查 + var order1 = orderDetail1.FirstOrDefault().Order; //访问导航属性,此时不查数据库,因为 OrderDetails 查询出来的时候已填充了该属性 + + + var queryable = g.mysql.Queryable().Where(a => a.Id == 1).ToList(); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any() + ).ToList(); + + + var groupbysql = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(false, a => a.Id == 2) + ) + .WhereIf(true, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()).ToSql(a => new + { + cou = a.Sum(a.Value.Item1.Id), + a.Key.mod4, + a.Key.tt2, + max = a.Max("a.id"), + max2 = Convert.ToInt64("max(a.id)") + }); + + var groupbysql2 = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(true, a => a.Id == 2) + ) + .WhereIf(false, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()).ToSql(a => a.Key.mod4); + + var groupby = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(true, a => a.Id == 2) + ) + .WhereIf(true, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + }); + + var arrg = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + + var arrg222 = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToList(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToList(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToList(); + + //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToList(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")) + .ToList((a, b, c) => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToList(); + + + + + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToList(); + + + + + + //((JoinType.LeftJoin, a.TypeGuid == b.Guid), (JoinType.InnerJoin, b.ParentId == c.Id) + + var t11112 = g.mysql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + var t3 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => a.Title).ToSql(); + var t4 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + var t5 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => new { a.Title, a.TypeGuid, a.CreateTime }).ToSql(); + var t6 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).InsertColumns(a => new { a.Title }).ToSql(); + + var t7 = g.mysql.Update().ToSql(); + var t8 = g.mysql.Update().Where(new TestInfo { }).ToSql(); + var t9 = g.mysql.Update().Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t10 = g.mysql.Update().Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t11 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).ToSql(); + var t12 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Where(a => a.Title == "111").ToSql(); + + var t13 = g.mysql.Update().Set(a => a.Title, "222111").ToSql(); + var t14 = g.mysql.Update().Set(a => a.Title, "222111").Where(new TestInfo { }).ToSql(); + var t15 = g.mysql.Update().Set(a => a.Title, "222111").Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t16 = g.mysql.Update().Set(a => a.Title, "222111").Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t17 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.Title, "222111").ToSql(); + var t18 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.Title, "222111").Where(a => a.Title == "111").ToSql(); + + var t19 = g.mysql.Update().Set(a => a.TypeGuid + 222111).ToSql(); + var t20 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new TestInfo { }).ToSql(); + var t21 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t22 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t23 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.TypeGuid + 222111).ToSql(); + var t24 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.TypeGuid + 222111).Where(a => a.Title == "111").ToSql(); + + + var t1000 = g.sqlite.Select().ToSql(); + var t1001 = g.sqlite.Insert().AppendData(new ExamPaper()).ToSql(); + } + } + class NullAggreTestTable + { + [Column(IsIdentity = true)] + public int Id { get; set; } + } + + + [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] + class TestInfo + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Table(Name = "TestTypeInfoT1")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + + [Table(Name = "TestTypeParentInfoT1")] + class TestTypeParentInfo + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public ICollection Childs { get; set; } + + public List Types { get; set; } + } + + + /// + /// 试卷表 + /// + [Table(Name = "exam_paper")] + public class ExamPaper + { + + public long id { get; set; } + + /// + /// 考核计划ID + /// + public long AssessmentPlanId { get; set; } + /// + /// 总分 + /// + public int TotalScore { get; set; } + + public DateTime BeginTime { get; set; } + + public DateTime? EndTime { get; set; } + + //[Column(IsIgnore = true)] + //public ExamStatus Status { get; set; } + public ExamStatus Status + { + get + { + if (DateTime.Now <= BeginTime) + return ExamStatus.Wait; + if (BeginTime <= DateTime.Now && (!EndTime.HasValue || DateTime.Now < EndTime)) + return ExamStatus.Started; + if (BeginTime <= DateTime.Now && (EndTime.HasValue && EndTime <= DateTime.Now)) + return ExamStatus.End; + return ExamStatus.Wait; + } + } + } + public enum ExamStatus { Wait, Started, End } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 1b1b056a..5234ee72 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -11,10 +11,13 @@ using System.Linq.Expressions; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; -namespace FreeSql.Tests { - public class UnitTest2 { +namespace FreeSql.Tests +{ + public class UnitTest2 + { - public partial class SysModulePermission { + public partial class SysModulePermission + { /// /// 菜单权限ID /// @@ -35,7 +38,8 @@ namespace FreeSql.Tests { /// public Int32 Status { get; set; } } - public partial class SysModule { + public partial class SysModule + { /// /// 主键 /// @@ -83,7 +87,8 @@ namespace FreeSql.Tests { public DateTime CreateTime { get; set; } } - public partial class SysModuleButton { + public partial class SysModuleButton + { /// /// 按钮主键 /// @@ -120,17 +125,21 @@ namespace FreeSql.Tests { /// public DateTime CreateTime { get; set; } } - partial class SysModulePermission { + partial class SysModulePermission + { public SysModuleButton Button { get; set; } } - partial class SysModule { + partial class SysModule + { public List Permissions { get; set; } } - partial class SysModuleButton { + partial class SysModuleButton + { } [Fact] - public void Test02() { + public void Test02() + { g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); @@ -164,7 +173,7 @@ namespace FreeSql.Tests { // .ToList(); var list = g.sqlite.Select() - .IncludeMany(m => m.Permissions.Where(p => p.SysModuleId == m.SysModuleId), + .IncludeMany(m => m.Permissions.Where(p => p.SysModuleId == m.SysModuleId), then => then.LeftJoin(p => p.Button.SysModuleButtonId == p.SysModuleButtonId)) .ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 7396b139..037e941f 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -5,82 +5,94 @@ using System.Diagnostics; using System.Text; -public class g { +public class g +{ - static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .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") - .UseAutoSyncStructure(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseLazyLoading(true) - .Build()); - public static IFreeSql mysql => mysqlLazy.Value; + static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .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") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .Build()); + public static IFreeSql mysql => mysqlLazy.Value; - static Lazy pgsqlLazy = new Lazy(() => { - NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); - return new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") - .UseAutoSyncStructure(true) - .UseSyncStructureToLower(true) - .UseLazyLoading(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build(); - }); - public static IFreeSql pgsql => pgsqlLazy.Value; + static Lazy pgsqlLazy = new Lazy(() => + { + NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); + return new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") + .UseAutoSyncStructure(true) + .UseSyncStructureToLower(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .Build(); + }); + public static IFreeSql pgsql => pgsqlLazy.Value; - static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseLazyLoading(true) - .Build()); - public static IFreeSql sqlserver => sqlserverLazy.Value; + static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .Build()); + public static IFreeSql sqlserver => sqlserverLazy.Value; - static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseSyncStructureToUpper(true) - //.UseNoneCommandParameter(true) + static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseSyncStructureToUpper(true) + //.UseNoneCommandParameter(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build()); - public static IFreeSql oracle => oracleLazy.Value; + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .Build()); + public static IFreeSql oracle => oracleLazy.Value; - static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build()); - public static IFreeSql sqlite => sqliteLazy.Value; + static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => + { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => + { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .Build()); + public static IFreeSql sqlite => sqliteLazy.Value; } diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 412b3bde..dc2300e2 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -1,76 +1,83 @@ using System; using System.Linq; -namespace FreeSql.DataAnnotations { - public class ColumnAttribute : Attribute { +namespace FreeSql.DataAnnotations +{ + public class ColumnAttribute : Attribute + { - /// - /// 数据库列名 - /// - public string Name { get; set; } - /// - /// 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - /// - public string OldName { get; set; } - /// - /// 数据库类型,如: varchar(255) - /// - public string DbType { get; set; } + /// + /// 数据库列名 + /// + public string Name { get; set; } + /// + /// 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + /// + public string OldName { get; set; } + /// + /// 数据库类型,如: varchar(255) + /// + public string DbType { get; set; } - internal bool? _IsPrimary, _IsIdentity, _IsNullable, _IsIgnore, _IsVersion; - /// - /// 主键 - /// - public bool IsPrimary { get => _IsPrimary ?? false; set => _IsPrimary = value; } - /// - /// 自增标识 - /// - public bool IsIdentity { get => _IsIdentity ?? false; set => _IsIdentity = value; } - /// - /// 是否可DBNull - /// - public bool IsNullable { get => _IsNullable ?? false; set => _IsNullable = value; } - /// - /// 忽略此列,不迁移、不插入 - /// - public bool IsIgnore { get => _IsIgnore ?? false; set => _IsIgnore = value; } - /// - /// 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) - /// - public bool IsVersion { get => _IsVersion ?? false; set => _IsVersion = value; } + internal bool? _IsPrimary, _IsIdentity, _IsNullable, _IsIgnore, _IsVersion; + /// + /// 主键 + /// + public bool IsPrimary { get => _IsPrimary ?? false; set => _IsPrimary = value; } + /// + /// 自增标识 + /// + public bool IsIdentity { get => _IsIdentity ?? false; set => _IsIdentity = value; } + /// + /// 是否可DBNull + /// + public bool IsNullable { get => _IsNullable ?? false; set => _IsNullable = value; } + /// + /// 忽略此列,不迁移、不插入 + /// + public bool IsIgnore { get => _IsIgnore ?? false; set => _IsIgnore = value; } + /// + /// 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) + /// + public bool IsVersion { get => _IsVersion ?? false; set => _IsVersion = value; } - internal string[] _Uniques; - /// - /// 唯一键,在多个属性指定相同的标识,代表联合键;可使用逗号分割多个 UniqueKey 名。 - /// - public string Unique { - get => _Uniques == null ? null : string.Join(", ", _Uniques); - set { - if (string.IsNullOrEmpty(value)) { - _Uniques = null; - return; - } - var val = value?.Trim(' ', '\t', ','); - if (string.IsNullOrEmpty(val)) { - _Uniques = null; - return; - } - var arr = val.Split(',').Select(a => a.Trim(' ', '\t').Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); - if (arr.Any() == false) { - _Uniques = null; - return; - } - _Uniques = arr; - } - } - /// - /// 数据库默认值 - /// - public object DbDefautValue { get; internal set; } + internal string[] _Uniques; + /// + /// 唯一键,在多个属性指定相同的标识,代表联合键;可使用逗号分割多个 UniqueKey 名。 + /// + public string Unique + { + get => _Uniques == null ? null : string.Join(", ", _Uniques); + set + { + if (string.IsNullOrEmpty(value)) + { + _Uniques = null; + return; + } + var val = value?.Trim(' ', '\t', ','); + if (string.IsNullOrEmpty(val)) + { + _Uniques = null; + return; + } + var arr = val.Split(',').Select(a => a.Trim(' ', '\t').Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); + if (arr.Any() == false) + { + _Uniques = null; + return; + } + _Uniques = arr; + } + } + /// + /// 数据库默认值 + /// + public object DbDefautValue { get; internal set; } - /// - /// 类型映射,比如:可将 enum 属性映射成 typeof(string) - /// - public Type MapType { get; set; } - } + /// + /// 类型映射,比如:可将 enum 属性映射成 typeof(string) + /// + public Type MapType { get; set; } + } } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index 6894cde1..67b3d885 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -1,87 +1,100 @@ using System; -namespace FreeSql.DataAnnotations { - public class ColumnFluent { +namespace FreeSql.DataAnnotations +{ + public class ColumnFluent + { - public ColumnFluent(ColumnAttribute column) { - _column = column; - } + public ColumnFluent(ColumnAttribute column) + { + _column = column; + } - ColumnAttribute _column; - /// - /// 数据库列名 - /// - public ColumnFluent Name(string value) { - _column.Name = value; - return this; - } - /// - /// 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - /// - public ColumnFluent OldName(string value) { - _column.OldName = value; - return this; - } - /// - /// 数据库类型,如: varchar(255) - /// - public ColumnFluent DbType(string value) { - _column.DbType = value; - return this; - } + ColumnAttribute _column; + /// + /// 数据库列名 + /// + public ColumnFluent Name(string value) + { + _column.Name = value; + return this; + } + /// + /// 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + /// + public ColumnFluent OldName(string value) + { + _column.OldName = value; + return this; + } + /// + /// 数据库类型,如: varchar(255) + /// + public ColumnFluent DbType(string value) + { + _column.DbType = value; + return this; + } - /// - /// 主键 - /// - public ColumnFluent IsPrimary(bool value) { - _column.IsPrimary = value; - return this; - } - /// - /// 自增标识 - /// - public ColumnFluent IsIdentity(bool value) { - _column.IsIdentity = value; - return this; - } - /// - /// 是否可DBNull - /// - public ColumnFluent IsNullable(bool value) { - _column.IsNullable = value; - return this; - } - /// - /// 忽略此列,不迁移、不插入 - /// - public ColumnFluent IsIgnore(bool value) { - _column.IsIgnore = value; - return this; - } - /// - /// 乐观锁 - /// - public ColumnFluent IsVersion(bool value) { - _column.IsVersion = value; - return this; - } - /// - /// 唯一键,在多个属性指定相同的标识,代表联合键;可使用逗号分割多个 UniqueKey 名。 - /// - /// 标识 - /// - public ColumnFluent Unique(string value) { - _column.Unique = value; - return this; - } - /// - /// 类型映射,比如:可将 enum 属性映射成 typeof(string) - /// - /// - /// - public ColumnFluent MapType(Type type) { - _column.MapType = type; - return this; - } - } + /// + /// 主键 + /// + public ColumnFluent IsPrimary(bool value) + { + _column.IsPrimary = value; + return this; + } + /// + /// 自增标识 + /// + public ColumnFluent IsIdentity(bool value) + { + _column.IsIdentity = value; + return this; + } + /// + /// 是否可DBNull + /// + public ColumnFluent IsNullable(bool value) + { + _column.IsNullable = value; + return this; + } + /// + /// 忽略此列,不迁移、不插入 + /// + public ColumnFluent IsIgnore(bool value) + { + _column.IsIgnore = value; + return this; + } + /// + /// 乐观锁 + /// + public ColumnFluent IsVersion(bool value) + { + _column.IsVersion = value; + return this; + } + /// + /// 唯一键,在多个属性指定相同的标识,代表联合键;可使用逗号分割多个 UniqueKey 名。 + /// + /// 标识 + /// + public ColumnFluent Unique(string value) + { + _column.Unique = value; + return this; + } + /// + /// 类型映射,比如:可将 enum 属性映射成 typeof(string) + /// + /// + /// + public ColumnFluent MapType(Type type) + { + _column.MapType = type; + return this; + } + } } diff --git a/FreeSql/DataAnnotations/NavigateAttribute.cs b/FreeSql/DataAnnotations/NavigateAttribute.cs index d9b052f5..d908a627 100644 --- a/FreeSql/DataAnnotations/NavigateAttribute.cs +++ b/FreeSql/DataAnnotations/NavigateAttribute.cs @@ -1,16 +1,19 @@ using System; using System.Linq; -namespace FreeSql.DataAnnotations { - public class NavigateAttribute : Attribute { +namespace FreeSql.DataAnnotations +{ + public class NavigateAttribute : Attribute + { - /// - /// 导航属性,手工绑定 - /// - public string Bind { get; set; } + /// + /// 导航属性,手工绑定 + /// + public string Bind { get; set; } - public NavigateAttribute(string bind) { - this.Bind = bind; - } - } + public NavigateAttribute(string bind) + { + this.Bind = bind; + } + } } diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index c1061e93..b70858b4 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -1,28 +1,30 @@ using System; using System.Collections.Concurrent; -namespace FreeSql.DataAnnotations { - public class TableAttribute : Attribute { +namespace FreeSql.DataAnnotations +{ + public class TableAttribute : Attribute + { - /// - /// 数据库表名 - /// - public string Name { get; set; } - /// - /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - /// - public string OldName { get; set; } - /// - /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - /// - public string SelectFilter { get; set; } + /// + /// 数据库表名 + /// + public string Name { get; set; } + /// + /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + /// + public string OldName { get; set; } + /// + /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + /// + public string SelectFilter { get; set; } - internal bool? _DisableSyncStructure; - /// - /// 禁用 CodeFirst 同步结构迁移 - /// - public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; } + internal bool? _DisableSyncStructure; + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; } - internal ConcurrentDictionary _columns { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - } + internal ConcurrentDictionary _columns { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + } } diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 64383cd4..0e6d1155 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -4,97 +4,112 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; -namespace FreeSql.DataAnnotations { - public class TableFluent { +namespace FreeSql.DataAnnotations +{ + public class TableFluent + { - public TableFluent(Type entityType, TableAttribute table) { - _entityType = entityType; - _properties = _entityType.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); - _table = table; - } + public TableFluent(Type entityType, TableAttribute table) + { + _entityType = entityType; + _properties = _entityType.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); + _table = table; + } - Type _entityType; - Dictionary _properties; - TableAttribute _table; - /// - /// 数据库表名 - /// - public TableFluent Name(string value) { - _table.Name = value; - return this; - } - /// - /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - /// - public TableFluent OldName(string value) { - _table.OldName = value; - return this; - } - /// - /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - /// - public TableFluent SelectFilter(string value) { - _table.SelectFilter = value; - return this; - } + Type _entityType; + Dictionary _properties; + TableAttribute _table; + /// + /// 数据库表名 + /// + public TableFluent Name(string value) + { + _table.Name = value; + return this; + } + /// + /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + /// + public TableFluent OldName(string value) + { + _table.OldName = value; + return this; + } + /// + /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + /// + public TableFluent SelectFilter(string value) + { + _table.SelectFilter = value; + return this; + } - /// - /// 禁用 CodeFirst 同步结构迁移 - /// - public TableFluent DisableSyncStructure(bool value) { - _table.DisableSyncStructure = value; - return this; - } + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public TableFluent DisableSyncStructure(bool value) + { + _table.DisableSyncStructure = value; + return this; + } - public ColumnFluent Property(string proto) { - if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); - var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto }); - return new ColumnFluent(col); - } - } + public ColumnFluent Property(string proto) + { + if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); + var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto }); + return new ColumnFluent(col); + } + } - public class TableFluent { + public class TableFluent + { - public TableFluent(TableAttribute table) { - _table = table; - } + public TableFluent(TableAttribute table) + { + _table = table; + } - TableAttribute _table; - /// - /// 数据库表名 - /// - public TableFluent Name(string value) { - _table.Name = value; - return this; - } - /// - /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - /// - public TableFluent OldName(string value) { - _table.OldName = value; - return this; - } - /// - /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - /// - public TableFluent SelectFilter(string value) { - _table.SelectFilter = value; - return this; - } + TableAttribute _table; + /// + /// 数据库表名 + /// + public TableFluent Name(string value) + { + _table.Name = value; + return this; + } + /// + /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + /// + public TableFluent OldName(string value) + { + _table.OldName = value; + return this; + } + /// + /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + /// + public TableFluent SelectFilter(string value) + { + _table.SelectFilter = value; + return this; + } - /// - /// 禁用 CodeFirst 同步结构迁移 - /// - public TableFluent DisableSyncStructure(bool value) { - _table.DisableSyncStructure = value; - return this; - } + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public TableFluent DisableSyncStructure(bool value) + { + _table.DisableSyncStructure = value; + return this; + } - public ColumnFluent Property(Expression> column) { - var proto = (column.Body as MemberExpression)?.Member; - if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); - var col = _table._columns.GetOrAdd(proto.Name, name => new ColumnAttribute { Name = proto.Name }); - return new ColumnFluent(col); - } - } + public ColumnFluent Property(Expression> column) + { + var proto = (column.Body as MemberExpression)?.Member; + if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); + var col = _table._columns.GetOrAdd(proto.Name, name => new ColumnAttribute { Name = proto.Name }); + return new ColumnFluent(col); + } + } } diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 12ec3c06..32a769f3 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace FreeSql { - public enum DataType { MySql, SqlServer, PostgreSQL, Oracle, Sqlite } +namespace FreeSql +{ + public enum DataType { MySql, SqlServer, PostgreSQL, Oracle, Sqlite } } diff --git a/FreeSql/DatabaseModel/DBColumnInfo.cs b/FreeSql/DatabaseModel/DBColumnInfo.cs index 2fd9f6af..4ede12b5 100644 --- a/FreeSql/DatabaseModel/DBColumnInfo.cs +++ b/FreeSql/DatabaseModel/DBColumnInfo.cs @@ -1,50 +1,52 @@ using System; -namespace FreeSql.DatabaseModel { - public class DbColumnInfo { - /// - /// 所属表 - /// - public DbTableInfo Table { get; set; } - /// - /// 列名 - /// - public string Name { get; set; } - /// - /// 映射到 C# 类型 - /// - public Type CsType { get; set; } - /// - /// 数据库枚举类型int值 - /// - public int DbType { get; set; } - /// - /// 数据库类型,字符串,varchar - /// - public string DbTypeText { get; set; } - /// - /// 数据库类型,字符串,varchar(255) - /// - public string DbTypeTextFull { get; set; } - /// - /// 最大长度 - /// - public int MaxLength { get; set; } - /// - /// 主键 - /// - public bool IsPrimary { get; set; } - /// - /// 自增标识 - /// - public bool IsIdentity { get; set; } - /// - /// 是否可DBNull - /// - public bool IsNullable { get; set; } - /// - /// 备注 - /// - public string Coment { get; set; } - } +namespace FreeSql.DatabaseModel +{ + public class DbColumnInfo + { + /// + /// 所属表 + /// + public DbTableInfo Table { get; set; } + /// + /// 列名 + /// + public string Name { get; set; } + /// + /// 映射到 C# 类型 + /// + public Type CsType { get; set; } + /// + /// 数据库枚举类型int值 + /// + public int DbType { get; set; } + /// + /// 数据库类型,字符串,varchar + /// + public string DbTypeText { get; set; } + /// + /// 数据库类型,字符串,varchar(255) + /// + public string DbTypeTextFull { get; set; } + /// + /// 最大长度 + /// + public int MaxLength { get; set; } + /// + /// 主键 + /// + public bool IsPrimary { get; set; } + /// + /// 自增标识 + /// + public bool IsIdentity { get; set; } + /// + /// 是否可DBNull + /// + public bool IsNullable { get; set; } + /// + /// 备注 + /// + public string Coment { get; set; } + } } diff --git a/FreeSql/DatabaseModel/DBTableInfo.cs b/FreeSql/DatabaseModel/DBTableInfo.cs index 01a602f6..10dc42e0 100644 --- a/FreeSql/DatabaseModel/DBTableInfo.cs +++ b/FreeSql/DatabaseModel/DBTableInfo.cs @@ -1,59 +1,62 @@ using System.Collections.Generic; using System.Linq; -namespace FreeSql.DatabaseModel { - public class DbTableInfo { - /// - /// 唯一标识 - /// - public string Id { get; set; } - /// - /// SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 - /// - public string Schema { get; set; } - /// - /// 表名 - /// - public string Name { get; set; } - /// - /// 表备注,SqlServer下是扩展属性 MS_Description - /// - public string Comment { get; set; } - /// - /// 表/视图 - /// - public DbTableType Type { get; set; } - /// - /// 列 - /// - public List Columns { get; set; } = new List(); - /// - /// 自增列 - /// - public List Identitys { get; set; } = new List(); - /// - /// 主键/组合 - /// - public List Primarys { get; set; } = new List(); - /// - /// 唯一键/组合 - /// - public Dictionary> UniquesDict { get; set; } = new Dictionary>(); - /// - /// 索引/组合 - /// - public Dictionary> IndexesDict { get; set; } = new Dictionary>(); - /// - /// 外键 - /// - public Dictionary ForeignsDict { get; set; } = new Dictionary(); +namespace FreeSql.DatabaseModel +{ + public class DbTableInfo + { + /// + /// 唯一标识 + /// + public string Id { get; set; } + /// + /// SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 + /// + public string Schema { get; set; } + /// + /// 表名 + /// + public string Name { get; set; } + /// + /// 表备注,SqlServer下是扩展属性 MS_Description + /// + public string Comment { get; set; } + /// + /// 表/视图 + /// + public DbTableType Type { get; set; } + /// + /// 列 + /// + public List Columns { get; set; } = new List(); + /// + /// 自增列 + /// + public List Identitys { get; set; } = new List(); + /// + /// 主键/组合 + /// + public List Primarys { get; set; } = new List(); + /// + /// 唯一键/组合 + /// + public Dictionary> UniquesDict { get; set; } = new Dictionary>(); + /// + /// 索引/组合 + /// + public Dictionary> IndexesDict { get; set; } = new Dictionary>(); + /// + /// 外键 + /// + public Dictionary ForeignsDict { get; set; } = new Dictionary(); - public List> Uniques => UniquesDict.Values.ToList(); - public List> Indexes => IndexesDict.Values.ToList(); - public List Foreigns => ForeignsDict.Values.ToList(); - } + public List> Uniques => UniquesDict.Values.ToList(); + public List> Indexes => IndexesDict.Values.ToList(); + public List Foreigns => ForeignsDict.Values.ToList(); + } - public enum DbTableType { - TABLE, VIEW, StoreProcedure - } + public enum DbTableType + { + TABLE, VIEW, StoreProcedure + } } diff --git a/FreeSql/DatabaseModel/DbEnumInfo.cs b/FreeSql/DatabaseModel/DbEnumInfo.cs index 93638af0..b3eb30a4 100644 --- a/FreeSql/DatabaseModel/DbEnumInfo.cs +++ b/FreeSql/DatabaseModel/DbEnumInfo.cs @@ -1,16 +1,18 @@ using System.Collections.Generic; -namespace FreeSql.DatabaseModel { - public class DbEnumInfo { +namespace FreeSql.DatabaseModel +{ + public class DbEnumInfo + { - /// - /// 枚举类型标识 - /// - public string Name { get; set; } + /// + /// 枚举类型标识 + /// + public string Name { get; set; } - /// - /// 枚举项 - /// - public Dictionary Labels { get; set; } - } + /// + /// 枚举项 + /// + public Dictionary Labels { get; set; } + } } diff --git a/FreeSql/DatabaseModel/DbForeignInfo.cs b/FreeSql/DatabaseModel/DbForeignInfo.cs index 70dca1f5..b4a86c8f 100644 --- a/FreeSql/DatabaseModel/DbForeignInfo.cs +++ b/FreeSql/DatabaseModel/DbForeignInfo.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; -namespace FreeSql.DatabaseModel { - public class DbForeignInfo { - public DbTableInfo Table { get; set; } - public List Columns { get; set; } = new List(); - public DbTableInfo ReferencedTable { get; set; } - public List ReferencedColumns { get; set; } = new List(); +namespace FreeSql.DatabaseModel +{ + public class DbForeignInfo + { + public DbTableInfo Table { get; set; } + public List Columns { get; set; } = new List(); + public DbTableInfo ReferencedTable { get; set; } + public List ReferencedColumns { get; set; } = new List(); - } + } } diff --git a/FreeSql/DatabaseModel/DbTypeInfo.cs b/FreeSql/DatabaseModel/DbTypeInfo.cs index 425a8821..eb319c02 100644 --- a/FreeSql/DatabaseModel/DbTypeInfo.cs +++ b/FreeSql/DatabaseModel/DbTypeInfo.cs @@ -1,16 +1,18 @@ using System.Collections.Generic; -namespace FreeSql.DatabaseModel { - public class DbTypeInfo { +namespace FreeSql.DatabaseModel +{ + public class DbTypeInfo + { - /// - /// 类型标识 - /// - public string Name { get; set; } + /// + /// 类型标识 + /// + public string Name { get; set; } - /// - /// 枚举项 - /// - public List<(string label, string value)> Labels { get; set; } - } + /// + /// 枚举项 + /// + public List<(string label, string value)> Labels { get; set; } + } } diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index f7bb3f2d..98ab49e7 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -6,655 +6,715 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; -namespace FreeSql.Extensions.EntityUtil { - public static class EntityUtilExtensions { +namespace FreeSql.Extensions.EntityUtil +{ + public static class EntityUtilExtensions + { - static readonly MethodInfo MethodStringBuilderAppend = typeof(StringBuilder).GetMethod("Append", new Type[] { typeof(object) }); - static readonly MethodInfo MethodStringBuilderToString = typeof(StringBuilder).GetMethod("ToString", new Type[0]); - static readonly PropertyInfo MethodStringBuilderLength = typeof(StringBuilder).GetProperty("Length"); - static readonly MethodInfo MethodStringConcat = typeof(string).GetMethod("Concat", new Type[] { typeof(object) }); - static readonly MethodInfo MethodFreeUtilNewMongodbId = typeof(FreeUtil).GetMethod("NewMongodbId"); + static readonly MethodInfo MethodStringBuilderAppend = typeof(StringBuilder).GetMethod("Append", new Type[] { typeof(object) }); + static readonly MethodInfo MethodStringBuilderToString = typeof(StringBuilder).GetMethod("ToString", new Type[0]); + static readonly PropertyInfo MethodStringBuilderLength = typeof(StringBuilder).GetProperty("Length"); + static readonly MethodInfo MethodStringConcat = typeof(string).GetMethod("Concat", new Type[] { typeof(object) }); + static readonly MethodInfo MethodFreeUtilNewMongodbId = typeof(FreeUtil).GetMethod("NewMongodbId"); - static ConcurrentDictionary>> _dicGetEntityKeyString = new ConcurrentDictionary>>(); - /// - /// 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null - /// - /// - /// - /// - /// 当Guid无值时,会生成有序的新值 - /// - /// - //public static string GetEntityKeyString(this IFreeSql orm, TEntity entity, string splitString = "*|_,[,_|*") => GetEntityKeyString(orm, typeof(TEntity), entity, splitString); - public static string GetEntityKeyString(this IFreeSql orm, Type entityType, object entity, bool genGuid, string splitString = "*|_,[,_|*") { - if (entity == null) return null; - if (entityType == null) entityType = entity.GetType(); - var func = _dicGetEntityKeyString.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var pks = _table.Primarys; - var returnTarget = Expression.Label(typeof(string)); - var parm1 = Expression.Parameter(typeof(object)); - var parm2 = Expression.Parameter(typeof(bool)); - var var1Parm = Expression.Variable(t); - var var2Sb = Expression.Variable(typeof(StringBuilder)); - var var3IsNull = Expression.Variable(typeof(bool)); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), - Expression.Assign(var2Sb, Expression.New(typeof(StringBuilder))), - Expression.Assign(var3IsNull, Expression.Constant(false)) - }); - for (var a = 0; a < pks.Length; a++) { - var isguid = pks[a].Attribute.MapType.NullableTypeOrThis() == typeof(Guid) || pks[a].CsType.NullableTypeOrThis() == typeof(Guid); - Expression expthen = null; - if (isguid) { - if (pks[a].Attribute.MapType == pks[a].CsType) { - expthen = Expression.Block( - new Expression[]{ - Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Call(MethodFreeUtilNewMongodbId)), - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ); - } else { - expthen = Expression.Block( - new Expression[]{ - Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pks[a].CsType, Expression.Call(MethodFreeUtilNewMongodbId))), - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ); - } - } else if (pks.Length > 1 && pks[a].Attribute.IsIdentity) { - expthen = Expression.Block( - new Expression[]{ - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ); - } else { - expthen = Expression.Assign(var3IsNull, Expression.Constant(true)); - } - if (pks[a].Attribute.IsIdentity || isguid || pks[a].CsType == typeof(string) || pks[a].CsType.IsNullableType()) { - exps.Add( - Expression.IfThen( - Expression.IsFalse(var3IsNull), - Expression.IfThenElse( - Expression.Equal(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Default(pks[a].CsType)), - Expression.IfThen( - Expression.IsTrue(parm2), - expthen - ), - Expression.Block( - new Expression[]{ - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ) - ) - ) - ); - } else { - exps.Add( - Expression.IfThen( - Expression.IsFalse(var3IsNull), - Expression.Block( - new Expression[]{ - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ) - ) - ); - } - } - exps.Add( - Expression.IfThen( - Expression.IsFalse(var3IsNull), - Expression.Return(returnTarget, Expression.Call(var2Sb, MethodStringBuilderToString)) - ) - ); - exps.Add(Expression.Label(returnTarget, Expression.Default(typeof(string)))); - return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb, var3IsNull }, exps), new[] { parm1, parm2 }).Compile(); - }); - return func(entity, genGuid); - } - static ConcurrentDictionary>> _dicGetEntityKeyValues = new ConcurrentDictionary>>(); - /// - /// 获取实体的主键值,多个主键返回数组 - /// - /// - /// - /// - /// - //public static object[] GetEntityKeyValues(this IFreeSql orm, TEntity entity) => GetEntityKeyValues(orm, typeof(TEntity), entity); - public static object[] GetEntityKeyValues(this IFreeSql orm, Type entityType, object entity) { - if (entity == null) return null; - if (entityType == null) entityType = entity.GetType(); - var func = _dicGetEntityKeyValues.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var pks = _table.Primarys; - var returnTarget = Expression.Label(typeof(object[])); - var parm1 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(t); - var var2Ret = Expression.Variable(typeof(object[])); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), - Expression.Assign(var2Ret, Expression.NewArrayBounds(typeof(object), Expression.Constant(pks.Length))), - }); - for (var a = 0; a < pks.Length; a++) { - exps.Add( - Expression.Assign( - Expression.ArrayAccess(var2Ret, Expression.Constant(a)), - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - ); - } - exps.AddRange(new Expression[] { - Expression.Return(returnTarget, var2Ret), - Expression.Label(returnTarget, Expression.Default(typeof(object[]))) - }); - return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Ret }, exps), new[] { parm1 }).Compile(); - }); - return func(entity); - } - static ConcurrentDictionary>>> _dicGetEntityValueWithPropertyName = new ConcurrentDictionary>>>(); - /// - /// 获取实体的属性值 - /// - /// - /// - /// - /// - /// - //public static object GetEntityValueWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName) => GetEntityKeyValues(orm, typeof(TEntity), entity, propertyName); - public static object GetEntityValueWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName) { - if (entity == null) return null; - if (entityType == null) entityType = entity.GetType(); - var func = _dicGetEntityValueWithPropertyName - .GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>>()) - .GetOrAdd(entityType, et => new ConcurrentDictionary>()) - .GetOrAdd(propertyName, pn => { - var _table = orm.CodeFirst.GetTableByEntity(entityType); - var pks = _table.Primarys; - var returnTarget = Expression.Label(typeof(object)); - var parm1 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(entityType); - var var2Ret = Expression.Variable(typeof(object)); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, entityType)), - Expression.Assign( - var2Ret, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pn]), typeof(object)) - ) - }); - exps.AddRange(new Expression[] { - Expression.Return(returnTarget, var2Ret), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - }); - return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Ret }, exps), new[] { parm1 }).Compile(); - }); - return func(entity); - } - static ConcurrentDictionary>> _dicGetEntityString = new ConcurrentDictionary>>(); - /// - /// 获取实体的所有数据,以 (1, 2, xxx) 的形式 - /// - /// - /// - /// - /// - //public static string GetEntityString(this IFreeSql orm, TEntity entity) => GetEntityString(orm, typeof(TEntity), entity); - public static string GetEntityString(this IFreeSql orm, Type entityType, object entity) { - if (entity == null) return null; - if (entityType == null) entityType = entity.GetType(); - var func = _dicGetEntityString.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var cols = _table.Columns; - var returnTarget = Expression.Label(typeof(string)); - var parm1 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(t); - var var2Sb = Expression.Variable(typeof(StringBuilder)); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), - Expression.Assign(var2Sb, Expression.New(typeof(StringBuilder))), - Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant("(" )) - }); - var a = 0; - foreach (var col in cols.Values) { - exps.Add( - Expression.Block( - new Expression[]{ - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(", " )) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[col.CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ) - ); - a++; - } - exps.AddRange(new Expression[] { - Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(")" )), - Expression.Return(returnTarget, Expression.Call(var2Sb, MethodStringBuilderToString)), - Expression.Label(returnTarget, Expression.Default(typeof(string))) - }); - return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb }, exps), new[] { parm1 }).Compile(); - }); - return func(entity); - } + static ConcurrentDictionary>> _dicGetEntityKeyString = new ConcurrentDictionary>>(); + /// + /// 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null + /// + /// + /// + /// + /// 当Guid无值时,会生成有序的新值 + /// + /// + //public static string GetEntityKeyString(this IFreeSql orm, TEntity entity, string splitString = "*|_,[,_|*") => GetEntityKeyString(orm, typeof(TEntity), entity, splitString); + public static string GetEntityKeyString(this IFreeSql orm, Type entityType, object entity, bool genGuid, string splitString = "*|_,[,_|*") + { + if (entity == null) return null; + if (entityType == null) entityType = entity.GetType(); + var func = _dicGetEntityKeyString.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var pks = _table.Primarys; + var returnTarget = Expression.Label(typeof(string)); + var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(bool)); + var var1Parm = Expression.Variable(t); + var var2Sb = Expression.Variable(typeof(StringBuilder)); + var var3IsNull = Expression.Variable(typeof(bool)); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), + Expression.Assign(var2Sb, Expression.New(typeof(StringBuilder))), + Expression.Assign(var3IsNull, Expression.Constant(false)) + }); + for (var a = 0; a < pks.Length; a++) + { + var isguid = pks[a].Attribute.MapType.NullableTypeOrThis() == typeof(Guid) || pks[a].CsType.NullableTypeOrThis() == typeof(Guid); + Expression expthen = null; + if (isguid) + { + if (pks[a].Attribute.MapType == pks[a].CsType) + { + expthen = Expression.Block( + new Expression[]{ + Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Call(MethodFreeUtilNewMongodbId)), + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) + ) + }.Where(c => c != null).ToArray() + ); + } + else + { + expthen = Expression.Block( + new Expression[]{ + Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pks[a].CsType, Expression.Call(MethodFreeUtilNewMongodbId))), + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) + ) + }.Where(c => c != null).ToArray() + ); + } + } + else if (pks.Length > 1 && pks[a].Attribute.IsIdentity) + { + expthen = Expression.Block( + new Expression[]{ + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) + ) + }.Where(c => c != null).ToArray() + ); + } + else + { + expthen = Expression.Assign(var3IsNull, Expression.Constant(true)); + } + if (pks[a].Attribute.IsIdentity || isguid || pks[a].CsType == typeof(string) || pks[a].CsType.IsNullableType()) + { + exps.Add( + Expression.IfThen( + Expression.IsFalse(var3IsNull), + Expression.IfThenElse( + Expression.Equal(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Default(pks[a].CsType)), + Expression.IfThen( + Expression.IsTrue(parm2), + expthen + ), + Expression.Block( + new Expression[]{ + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) + ) + }.Where(c => c != null).ToArray() + ) + ) + ) + ); + } + else + { + exps.Add( + Expression.IfThen( + Expression.IsFalse(var3IsNull), + Expression.Block( + new Expression[]{ + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) + ) + }.Where(c => c != null).ToArray() + ) + ) + ); + } + } + exps.Add( + Expression.IfThen( + Expression.IsFalse(var3IsNull), + Expression.Return(returnTarget, Expression.Call(var2Sb, MethodStringBuilderToString)) + ) + ); + exps.Add(Expression.Label(returnTarget, Expression.Default(typeof(string)))); + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb, var3IsNull }, exps), new[] { parm1, parm2 }).Compile(); + }); + return func(entity, genGuid); + } + static ConcurrentDictionary>> _dicGetEntityKeyValues = new ConcurrentDictionary>>(); + /// + /// 获取实体的主键值,多个主键返回数组 + /// + /// + /// + /// + /// + //public static object[] GetEntityKeyValues(this IFreeSql orm, TEntity entity) => GetEntityKeyValues(orm, typeof(TEntity), entity); + public static object[] GetEntityKeyValues(this IFreeSql orm, Type entityType, object entity) + { + if (entity == null) return null; + if (entityType == null) entityType = entity.GetType(); + var func = _dicGetEntityKeyValues.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var pks = _table.Primarys; + var returnTarget = Expression.Label(typeof(object[])); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var var2Ret = Expression.Variable(typeof(object[])); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), + Expression.Assign(var2Ret, Expression.NewArrayBounds(typeof(object), Expression.Constant(pks.Length))), + }); + for (var a = 0; a < pks.Length; a++) + { + exps.Add( + Expression.Assign( + Expression.ArrayAccess(var2Ret, Expression.Constant(a)), + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) + ) + ); + } + exps.AddRange(new Expression[] { + Expression.Return(returnTarget, var2Ret), + Expression.Label(returnTarget, Expression.Default(typeof(object[]))) + }); + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Ret }, exps), new[] { parm1 }).Compile(); + }); + return func(entity); + } + static ConcurrentDictionary>>> _dicGetEntityValueWithPropertyName = new ConcurrentDictionary>>>(); + /// + /// 获取实体的属性值 + /// + /// + /// + /// + /// + /// + //public static object GetEntityValueWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName) => GetEntityKeyValues(orm, typeof(TEntity), entity, propertyName); + public static object GetEntityValueWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName) + { + if (entity == null) return null; + if (entityType == null) entityType = entity.GetType(); + var func = _dicGetEntityValueWithPropertyName + .GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>>()) + .GetOrAdd(entityType, et => new ConcurrentDictionary>()) + .GetOrAdd(propertyName, pn => + { + var _table = orm.CodeFirst.GetTableByEntity(entityType); + var pks = _table.Primarys; + var returnTarget = Expression.Label(typeof(object)); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(entityType); + var var2Ret = Expression.Variable(typeof(object)); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, entityType)), + Expression.Assign( + var2Ret, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pn]), typeof(object)) + ) + }); + exps.AddRange(new Expression[] { + Expression.Return(returnTarget, var2Ret), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + }); + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Ret }, exps), new[] { parm1 }).Compile(); + }); + return func(entity); + } + static ConcurrentDictionary>> _dicGetEntityString = new ConcurrentDictionary>>(); + /// + /// 获取实体的所有数据,以 (1, 2, xxx) 的形式 + /// + /// + /// + /// + /// + //public static string GetEntityString(this IFreeSql orm, TEntity entity) => GetEntityString(orm, typeof(TEntity), entity); + public static string GetEntityString(this IFreeSql orm, Type entityType, object entity) + { + if (entity == null) return null; + if (entityType == null) entityType = entity.GetType(); + var func = _dicGetEntityString.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var cols = _table.Columns; + var returnTarget = Expression.Label(typeof(string)); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var var2Sb = Expression.Variable(typeof(StringBuilder)); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), + Expression.Assign(var2Sb, Expression.New(typeof(StringBuilder))), + Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant("(" )) + }); + var a = 0; + foreach (var col in cols.Values) + { + exps.Add( + Expression.Block( + new Expression[]{ + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(", " )) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[col.CsName]), typeof(object)) + ) + }.Where(c => c != null).ToArray() + ) + ); + a++; + } + exps.AddRange(new Expression[] { + Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(")" )), + Expression.Return(returnTarget, Expression.Call(var2Sb, MethodStringBuilderToString)), + Expression.Label(returnTarget, Expression.Default(typeof(string))) + }); + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb }, exps), new[] { parm1 }).Compile(); + }); + return func(entity); + } - /// - /// 使用新实体的值,复盖旧实体的值 - /// - static ConcurrentDictionary>> _dicMapEntityValue = new ConcurrentDictionary>>(); - //public static void MapEntityValue(this IFreeSql orm, TEntity entityFrom, TEntity entityTo) => MapEntityValue(orm, typeof(TEntity), entityFrom, entityTo); - public static void MapEntityValue(this IFreeSql orm, Type entityType, object entityFrom, object entityTo) { - if (entityType == null) entityType = entityFrom?.GetType() ?? entityTo?.GetType(); - var func = _dicMapEntityValue.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var parm1 = Expression.Parameter(typeof(object)); - var parm2 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(t); - var var2Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), - Expression.Assign(var2Parm, Expression.TypeAs(parm2, t)) - }); - foreach (var prop in _table.Properties.Values) { - if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue; - if (_table.ColumnsByCs.ContainsKey(prop.Name)) { - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var2Parm, prop), - Expression.MakeMemberAccess(var1Parm, prop) - ) - ); - } - - //else if (prop.GetSetMethod() != null) { - // exps.Add( - // Expression.Assign( - // Expression.MakeMemberAccess(var2Parm, prop), - // Expression.Default(prop.PropertyType) - // ) - // ); - //} - } - return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Parm }, exps), new[] { parm1, parm2 }).Compile(); - }); - func(entityFrom, entityTo); - } + /// + /// 使用新实体的值,复盖旧实体的值 + /// + static ConcurrentDictionary>> _dicMapEntityValue = new ConcurrentDictionary>>(); + //public static void MapEntityValue(this IFreeSql orm, TEntity entityFrom, TEntity entityTo) => MapEntityValue(orm, typeof(TEntity), entityFrom, entityTo); + public static void MapEntityValue(this IFreeSql orm, Type entityType, object entityFrom, object entityTo) + { + if (entityType == null) entityType = entityFrom?.GetType() ?? entityTo?.GetType(); + var func = _dicMapEntityValue.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var var2Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), + Expression.Assign(var2Parm, Expression.TypeAs(parm2, t)) + }); + foreach (var prop in _table.Properties.Values) + { + if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue; + if (_table.ColumnsByCs.ContainsKey(prop.Name)) + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var2Parm, prop), + Expression.MakeMemberAccess(var1Parm, prop) + ) + ); + } - static ConcurrentDictionary>> _dicMapEntityKeyValue = new ConcurrentDictionary>>(); - /// - /// 使用新实体的主键值,复盖旧实体的主键值 - /// - //public static void MapEntityKeyValue(this IFreeSql orm, TEntity entityFrom, TEntity entityTo) => MapEntityKeyValue(orm, typeof(TEntity), entityFrom, entityTo); - public static void MapEntityKeyValue(this IFreeSql orm, Type entityType, object entityFrom, object entityTo) { - if (entityType == null) entityType = entityFrom?.GetType() ?? entityTo?.GetType(); - var func = _dicMapEntityKeyValue.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var pks = _table.Primarys; - var parm1 = Expression.Parameter(typeof(object)); - var parm2 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(t); - var var2Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), - Expression.Assign(var2Parm, Expression.TypeAs(parm2, t)) - }); - foreach (var pk in pks) { - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var2Parm, _table.Properties[pk.CsName]), - Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]) - ) - ); - } - return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Parm }, exps), new[] { parm1, parm2 }).Compile(); - }); - func(entityFrom, entityTo); - } + //else if (prop.GetSetMethod() != null) { + // exps.Add( + // Expression.Assign( + // Expression.MakeMemberAccess(var2Parm, prop), + // Expression.Default(prop.PropertyType) + // ) + // ); + //} + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Parm }, exps), new[] { parm1, parm2 }).Compile(); + }); + func(entityFrom, entityTo); + } - static ConcurrentDictionary>> _dicSetEntityIdentityValueWithPrimary = new ConcurrentDictionary>>(); - /// - /// 设置实体中主键内的自增字段值(若存在) - /// - /// - /// - /// - /// - //public static void SetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity entity, long idtval) => SetEntityIdentityValueWithPrimary(orm, typeof(TEntity), entity, idtval); - public static void SetEntityIdentityValueWithPrimary(this IFreeSql orm, Type entityType, object entity, long idtval) { - if (entity == null) return; - if (entityType == null) entityType = entity.GetType(); - var func = _dicSetEntityIdentityValueWithPrimary.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); - var parm1 = Expression.Parameter(typeof(object)); - var parm2 = Expression.Parameter(typeof(long)); - var var1Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) - }); - if (identitys.Any()) { - var idts0 = identitys.First(); - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), - Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(idts0.CsType, Expression.Convert(parm2, typeof(object))), idts0.CsType) - ) - ); - } - return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2 }).Compile(); - }); - func(entity, idtval); - } - static ConcurrentDictionary>> _dicGetEntityIdentityValueWithPrimary = new ConcurrentDictionary>>(); - /// - /// 获取实体中主键内的自增字段值(若存在) - /// - /// - /// - /// - //public static long GetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity entity) => GetEntityIdentityValueWithPrimary(orm, typeof(TEntity), entity); - public static long GetEntityIdentityValueWithPrimary(this IFreeSql orm, Type entityType, object entity) { - if (entity == null) return 0; - if (entityType == null) entityType = entity.GetType(); - var func = _dicGetEntityIdentityValueWithPrimary.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); - var returnTarget = Expression.Label(typeof(long)); - var parm1 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) - }); - if (identitys.Any()) { - var idts0 = identitys.First(); - exps.Add( - Expression.IfThen( - Expression.NotEqual( - Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), - Expression.Default(idts0.CsType) - ), - Expression.Return( - returnTarget, - Expression.Convert( - FreeSql.Internal.Utils.GetDataReaderValueBlockExpression( - typeof(long), - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), typeof(object)) - ), - typeof(long) - ) - ) - ) - ); - } - exps.Add(Expression.Label(returnTarget, Expression.Default(typeof(long)))); - return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); - }); - return func(entity); - } + static ConcurrentDictionary>> _dicMapEntityKeyValue = new ConcurrentDictionary>>(); + /// + /// 使用新实体的主键值,复盖旧实体的主键值 + /// + //public static void MapEntityKeyValue(this IFreeSql orm, TEntity entityFrom, TEntity entityTo) => MapEntityKeyValue(orm, typeof(TEntity), entityFrom, entityTo); + public static void MapEntityKeyValue(this IFreeSql orm, Type entityType, object entityFrom, object entityTo) + { + if (entityType == null) entityType = entityFrom?.GetType() ?? entityTo?.GetType(); + var func = _dicMapEntityKeyValue.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var pks = _table.Primarys; + var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var var2Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), + Expression.Assign(var2Parm, Expression.TypeAs(parm2, t)) + }); + foreach (var pk in pks) + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var2Parm, _table.Properties[pk.CsName]), + Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]) + ) + ); + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Parm }, exps), new[] { parm1, parm2 }).Compile(); + }); + func(entityFrom, entityTo); + } - static ConcurrentDictionary>> _dicClearEntityPrimaryValueWithIdentityAndGuid = new ConcurrentDictionary>>(); - /// - /// 清除实体的主键值,将自增、Guid类型的主键值清除 - /// - /// - /// - /// - //public static void ClearEntityPrimaryValueWithIdentityAndGuid(this IFreeSql orm, TEntity entity) => ClearEntityPrimaryValueWithIdentityAndGuid(orm, typeof(TEntity), entity); - public static void ClearEntityPrimaryValueWithIdentityAndGuid(this IFreeSql orm, Type entityType, object entity) { - if (entity == null) return; - if (entityType == null) entityType = entity.GetType(); - var func = _dicClearEntityPrimaryValueWithIdentityAndGuid.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); - var parm1 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) - }); - foreach (var pk in _table.Primarys) { - if (pk.Attribute.IsIdentity || pk.Attribute.MapType == pk.CsType && pk.Attribute.MapType.NullableTypeOrThis() == typeof(Guid)) { - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]), - Expression.Default(pk.CsType) - ) - ); - continue; - } - if (pk.Attribute.MapType != pk.CsType && (pk.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) || pk.CsType.NullableTypeOrThis() == typeof(Guid))) { - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]), - FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pk.CsType, Expression.Default(pk.Attribute.MapType)) - ) - ); - continue; - } - } - return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); - }); - func(entity); - } + static ConcurrentDictionary>> _dicSetEntityIdentityValueWithPrimary = new ConcurrentDictionary>>(); + /// + /// 设置实体中主键内的自增字段值(若存在) + /// + /// + /// + /// + /// + //public static void SetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity entity, long idtval) => SetEntityIdentityValueWithPrimary(orm, typeof(TEntity), entity, idtval); + public static void SetEntityIdentityValueWithPrimary(this IFreeSql orm, Type entityType, object entity, long idtval) + { + if (entity == null) return; + if (entityType == null) entityType = entity.GetType(); + var func = _dicSetEntityIdentityValueWithPrimary.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); + var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(long)); + var var1Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) + }); + if (identitys.Any()) + { + var idts0 = identitys.First(); + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), + Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(idts0.CsType, Expression.Convert(parm2, typeof(object))), idts0.CsType) + ) + ); + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2 }).Compile(); + }); + func(entity, idtval); + } + static ConcurrentDictionary>> _dicGetEntityIdentityValueWithPrimary = new ConcurrentDictionary>>(); + /// + /// 获取实体中主键内的自增字段值(若存在) + /// + /// + /// + /// + //public static long GetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity entity) => GetEntityIdentityValueWithPrimary(orm, typeof(TEntity), entity); + public static long GetEntityIdentityValueWithPrimary(this IFreeSql orm, Type entityType, object entity) + { + if (entity == null) return 0; + if (entityType == null) entityType = entity.GetType(); + var func = _dicGetEntityIdentityValueWithPrimary.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); + var returnTarget = Expression.Label(typeof(long)); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) + }); + if (identitys.Any()) + { + var idts0 = identitys.First(); + exps.Add( + Expression.IfThen( + Expression.NotEqual( + Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), + Expression.Default(idts0.CsType) + ), + Expression.Return( + returnTarget, + Expression.Convert( + FreeSql.Internal.Utils.GetDataReaderValueBlockExpression( + typeof(long), + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[idts0.CsName]), typeof(object)) + ), + typeof(long) + ) + ) + ) + ); + } + exps.Add(Expression.Label(returnTarget, Expression.Default(typeof(long)))); + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); + }); + return func(entity); + } - static ConcurrentDictionary>> _dicClearEntityPrimaryValueWithIdentity = new ConcurrentDictionary>>(); - /// - /// 清除实体的主键值,将自增、Guid类型的主键值清除 - /// - /// - /// - /// - //public static void ClearEntityPrimaryValueWithIdentity(this IFreeSql orm, TEntity entity) => ClearEntityPrimaryValueWithIdentity(orm, typeof(TEntity), entity); - public static void ClearEntityPrimaryValueWithIdentity(this IFreeSql orm, Type entityType, object entity) { - if (entity == null) return; - if (entityType == null) entityType = entity.GetType(); - var func = _dicClearEntityPrimaryValueWithIdentity.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); - var parm1 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) - }); - foreach (var pk in _table.Primarys) { - if (pk.Attribute.IsIdentity) { - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]), - Expression.Default(pk.CsType) - ) - ); - } - } - return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); - }); - func(entity); - } + static ConcurrentDictionary>> _dicClearEntityPrimaryValueWithIdentityAndGuid = new ConcurrentDictionary>>(); + /// + /// 清除实体的主键值,将自增、Guid类型的主键值清除 + /// + /// + /// + /// + //public static void ClearEntityPrimaryValueWithIdentityAndGuid(this IFreeSql orm, TEntity entity) => ClearEntityPrimaryValueWithIdentityAndGuid(orm, typeof(TEntity), entity); + public static void ClearEntityPrimaryValueWithIdentityAndGuid(this IFreeSql orm, Type entityType, object entity) + { + if (entity == null) return; + if (entityType == null) entityType = entity.GetType(); + var func = _dicClearEntityPrimaryValueWithIdentityAndGuid.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) + }); + foreach (var pk in _table.Primarys) + { + if (pk.Attribute.IsIdentity || pk.Attribute.MapType == pk.CsType && pk.Attribute.MapType.NullableTypeOrThis() == typeof(Guid)) + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]), + Expression.Default(pk.CsType) + ) + ); + continue; + } + if (pk.Attribute.MapType != pk.CsType && (pk.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) || pk.CsType.NullableTypeOrThis() == typeof(Guid))) + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]), + FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pk.CsType, Expression.Default(pk.Attribute.MapType)) + ) + ); + continue; + } + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); + }); + func(entity); + } - static ConcurrentDictionary>> _dicCompareEntityValueReturnColumns = new ConcurrentDictionary>>(); - /// - /// 对比两个实体值,返回相同/或不相同的列名 - /// - /// - /// - /// - /// - /// - /// - //public static string[] CompareEntityValueReturnColumns(this IFreeSql orm, TEntity entity1, TEntity entity2, bool isEqual) => CompareEntityValueReturnColumns(orm, typeof(TEntity), entity1, entity2, isEqual); - public static string[] CompareEntityValueReturnColumns(this IFreeSql orm, Type entityType, object entity1, object entity2, bool isEqual) { - if (entityType == null) entityType = entity1?.GetType() ?? entity2?.GetType(); - var func = _dicCompareEntityValueReturnColumns.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var returnTarget = Expression.Label(typeof(string[])); - var parm1 = Expression.Parameter(typeof(object)); - var parm2 = Expression.Parameter(typeof(object)); - var parm3 = Expression.Parameter(typeof(bool)); - var var1Ret = Expression.Variable(typeof(List)); - var var1Parm = Expression.Variable(t); - var var2Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), - Expression.Assign(var2Parm, Expression.TypeAs(parm2, t)), - Expression.Assign(var1Ret, Expression.New(typeof(List))) - }); - var a = 0; - foreach (var prop in _table.Properties.Values) { - if (_table.ColumnsByCs.TryGetValue(prop.Name, out var trycol) == false) continue; - exps.Add( - Expression.IfThenElse( - Expression.Equal( - Expression.MakeMemberAccess(var1Parm, prop), - Expression.MakeMemberAccess(var2Parm, prop) - ), - Expression.IfThen( - Expression.IsTrue(parm3), - Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) - ), - Expression.IfThen( - Expression.IsFalse(parm3), - Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) - ) - ) - ); - a++; - } - exps.Add(Expression.Return(returnTarget, Expression.Call(var1Ret, typeof(List).GetMethod("ToArray", new Type[0])))); - exps.Add(Expression.Label(returnTarget, Expression.Constant(new string[0]))); - return Expression.Lambda>(Expression.Block(new[] { var1Ret, var1Parm, var2Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); - }); - return func(entity1, entity2, isEqual); - } + static ConcurrentDictionary>> _dicClearEntityPrimaryValueWithIdentity = new ConcurrentDictionary>>(); + /// + /// 清除实体的主键值,将自增、Guid类型的主键值清除 + /// + /// + /// + /// + //public static void ClearEntityPrimaryValueWithIdentity(this IFreeSql orm, TEntity entity) => ClearEntityPrimaryValueWithIdentity(orm, typeof(TEntity), entity); + public static void ClearEntityPrimaryValueWithIdentity(this IFreeSql orm, Type entityType, object entity) + { + if (entity == null) return; + if (entityType == null) entityType = entity.GetType(); + var func = _dicClearEntityPrimaryValueWithIdentity.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) + }); + foreach (var pk in _table.Primarys) + { + if (pk.Attribute.IsIdentity) + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]), + Expression.Default(pk.CsType) + ) + ); + } + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); + }); + func(entity); + } - static ConcurrentDictionary>> _dicSetEntityIncrByWithPropertyName = new ConcurrentDictionary>>(); - /// - /// 设置实体中某属性的数值增加指定的值 - /// - /// - /// - /// - /// - /// - //public static void SetEntityIncrByWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName, int incrBy) => SetEntityIncrByWithPropertyName(orm, typeof(TEntity), entity, propertyName, incrBy); - public static void SetEntityIncrByWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName, int incrBy) { - if (entity == null) return; - if (entityType == null) entityType = entity.GetType(); - var func = _dicSetEntityIncrByWithPropertyName.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => { - var _table = orm.CodeFirst.GetTableByEntity(t); - var parm1 = Expression.Parameter(typeof(object)); - var parm2 = Expression.Parameter(typeof(string)); - var parm3 = Expression.Parameter(typeof(int)); - var var1Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) - }); - if (_table.Properties.ContainsKey(propertyName)) { - var prop = _table.Properties[propertyName]; - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var1Parm, prop), - Expression.Add( - Expression.MakeMemberAccess(var1Parm, prop), - Expression.Convert( - FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Convert(parm3, typeof(object))), - prop.PropertyType - ) - ) - ) - ); - } - return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); - }); - func(entity, propertyName, incrBy); - } + static ConcurrentDictionary>> _dicCompareEntityValueReturnColumns = new ConcurrentDictionary>>(); + /// + /// 对比两个实体值,返回相同/或不相同的列名 + /// + /// + /// + /// + /// + /// + /// + //public static string[] CompareEntityValueReturnColumns(this IFreeSql orm, TEntity entity1, TEntity entity2, bool isEqual) => CompareEntityValueReturnColumns(orm, typeof(TEntity), entity1, entity2, isEqual); + public static string[] CompareEntityValueReturnColumns(this IFreeSql orm, Type entityType, object entity1, object entity2, bool isEqual) + { + if (entityType == null) entityType = entity1?.GetType() ?? entity2?.GetType(); + var func = _dicCompareEntityValueReturnColumns.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var returnTarget = Expression.Label(typeof(string[])); + var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(object)); + var parm3 = Expression.Parameter(typeof(bool)); + var var1Ret = Expression.Variable(typeof(List)); + var var1Parm = Expression.Variable(t); + var var2Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)), + Expression.Assign(var2Parm, Expression.TypeAs(parm2, t)), + Expression.Assign(var1Ret, Expression.New(typeof(List))) + }); + var a = 0; + foreach (var prop in _table.Properties.Values) + { + if (_table.ColumnsByCs.TryGetValue(prop.Name, out var trycol) == false) continue; + exps.Add( + Expression.IfThenElse( + Expression.Equal( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.MakeMemberAccess(var2Parm, prop) + ), + Expression.IfThen( + Expression.IsTrue(parm3), + Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) + ), + Expression.IfThen( + Expression.IsFalse(parm3), + Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) + ) + ) + ); + a++; + } + exps.Add(Expression.Return(returnTarget, Expression.Call(var1Ret, typeof(List).GetMethod("ToArray", new Type[0])))); + exps.Add(Expression.Label(returnTarget, Expression.Constant(new string[0]))); + return Expression.Lambda>(Expression.Block(new[] { var1Ret, var1Parm, var2Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); + }); + return func(entity1, entity2, isEqual); + } - static ConcurrentDictionary>>> _dicSetEntityValueWithPropertyName = new ConcurrentDictionary>>>(); - /// - /// 设置实体中某属性的值 - /// - /// - /// - /// - /// - /// - //public static void SetEntityValueWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName, object value) => SetEntityValueWithPropertyName(orm, typeof(TEntity), entity, propertyName, value); - public static void SetEntityValueWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName, object value) { - if (entity == null) return; - if (entityType == null) entityType = entity.GetType(); - var func = _dicSetEntityValueWithPropertyName.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>>()) - .GetOrAdd(entityType, et => new ConcurrentDictionary>()) - .GetOrAdd(propertyName, pn => { - var t = entityType; - var _table = orm.CodeFirst.GetTableByEntity(t); - var parm1 = Expression.Parameter(typeof(object)); - var parm2 = Expression.Parameter(typeof(string)); - var parm3 = Expression.Parameter(typeof(object)); - var var1Parm = Expression.Variable(t); - var exps = new List(new Expression[] { - Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) - }); - if (_table.Properties.ContainsKey(pn)) { - var prop = _table.Properties[pn]; + static ConcurrentDictionary>> _dicSetEntityIncrByWithPropertyName = new ConcurrentDictionary>>(); + /// + /// 设置实体中某属性的数值增加指定的值 + /// + /// + /// + /// + /// + /// + //public static void SetEntityIncrByWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName, int incrBy) => SetEntityIncrByWithPropertyName(orm, typeof(TEntity), entity, propertyName, incrBy); + public static void SetEntityIncrByWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName, int incrBy) + { + if (entity == null) return; + if (entityType == null) entityType = entity.GetType(); + var func = _dicSetEntityIncrByWithPropertyName.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(entityType, t => + { + var _table = orm.CodeFirst.GetTableByEntity(t); + var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(string)); + var parm3 = Expression.Parameter(typeof(int)); + var var1Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) + }); + if (_table.Properties.ContainsKey(propertyName)) + { + var prop = _table.Properties[propertyName]; + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.Add( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.Convert( + FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Convert(parm3, typeof(object))), + prop.PropertyType + ) + ) + ) + ); + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); + }); + func(entity, propertyName, incrBy); + } - if (_table.ColumnsByCs.ContainsKey(pn)) { - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var1Parm, prop), - Expression.Convert( - FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(prop.PropertyType, parm3), - prop.PropertyType - ) - ) - ); - } else { - exps.Add( - Expression.Assign( - Expression.MakeMemberAccess(var1Parm, prop), - Expression.Convert( - parm3, - prop.PropertyType - ) - ) - ); - } - } - return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); - }); - func(entity, propertyName, value); - } + static ConcurrentDictionary>>> _dicSetEntityValueWithPropertyName = new ConcurrentDictionary>>>(); + /// + /// 设置实体中某属性的值 + /// + /// + /// + /// + /// + /// + //public static void SetEntityValueWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName, object value) => SetEntityValueWithPropertyName(orm, typeof(TEntity), entity, propertyName, value); + public static void SetEntityValueWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName, object value) + { + if (entity == null) return; + if (entityType == null) entityType = entity.GetType(); + var func = _dicSetEntityValueWithPropertyName.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>>()) + .GetOrAdd(entityType, et => new ConcurrentDictionary>()) + .GetOrAdd(propertyName, pn => + { + var t = entityType; + var _table = orm.CodeFirst.GetTableByEntity(t); + var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(string)); + var parm3 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) + }); + if (_table.Properties.ContainsKey(pn)) + { + var prop = _table.Properties[pn]; - static ConcurrentDictionary _dicAppendEntityUpdateSetWithColumnMethods = new ConcurrentDictionary(); - static ConcurrentDictionary> _dicAppendEntityUpdateSetWithColumnMethod = new ConcurrentDictionary>(); - /// - /// 缓存执行 IUpdate.Set - /// - /// - /// - /// - /// - public static void AppendEntityUpdateSetWithColumn(this IUpdate update, Type columnType, LambdaExpression setExp) where TEntity : class { + if (_table.ColumnsByCs.ContainsKey(pn)) + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.Convert( + FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(prop.PropertyType, parm3), + prop.PropertyType + ) + ) + ); + } + else + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.Convert( + parm3, + prop.PropertyType + ) + ) + ); + } + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); + }); + func(entity, propertyName, value); + } - var setMethod = _dicAppendEntityUpdateSetWithColumnMethod.GetOrAdd(typeof(IUpdate), uptp => new ConcurrentDictionary()).GetOrAdd(columnType, coltp => { - var allMethods = _dicAppendEntityUpdateSetWithColumnMethods.GetOrAdd(typeof(IUpdate), uptp => uptp.GetMethods()); - return allMethods.Where(a => a.Name == "Set" && a.IsGenericMethod && a.GetParameters().Length == 1 && a.GetGenericArguments().First().Name == "TMember").FirstOrDefault() - .MakeGenericMethod(columnType); - }); + static ConcurrentDictionary _dicAppendEntityUpdateSetWithColumnMethods = new ConcurrentDictionary(); + static ConcurrentDictionary> _dicAppendEntityUpdateSetWithColumnMethod = new ConcurrentDictionary>(); + /// + /// 缓存执行 IUpdate.Set + /// + /// + /// + /// + /// + public static void AppendEntityUpdateSetWithColumn(this IUpdate update, Type columnType, LambdaExpression setExp) where TEntity : class + { - setMethod.Invoke(update, new object[] { setExp }); - } - } + var setMethod = _dicAppendEntityUpdateSetWithColumnMethod.GetOrAdd(typeof(IUpdate), uptp => new ConcurrentDictionary()).GetOrAdd(columnType, coltp => + { + var allMethods = _dicAppendEntityUpdateSetWithColumnMethods.GetOrAdd(typeof(IUpdate), uptp => uptp.GetMethods()); + return allMethods.Where(a => a.Name == "Set" && a.IsGenericMethod && a.GetParameters().Length == 1 && a.GetGenericArguments().First().Name == "TMember").FirstOrDefault() + .MakeGenericMethod(columnType); + }); + + setMethod.Invoke(update, new object[] { setExp }); + } + } } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index c5fde52a..68855572 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -8,84 +8,105 @@ using System.Drawing; using System.Linq; using System.Reflection; -public static partial class FreeSqlGlobalExtensions { +public static partial class FreeSqlGlobalExtensions +{ - public static FreeSql.ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); + public static FreeSql.ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); - static Lazy> dicIsNumberType = new Lazy>(() => new Dictionary { - [typeof(sbyte)] = true, [typeof(sbyte?)] = true, - [typeof(short)] = true, [typeof(short?)] = true, - [typeof(int)] = true, [typeof(int?)] = true, - [typeof(long)] = true, [typeof(long?)] = true, - [typeof(byte)] = true, [typeof(byte?)] = true, - [typeof(ushort)] = true, [typeof(ushort?)] = true, - [typeof(uint)] = true, [typeof(uint?)] = true, - [typeof(ulong)] = true, [typeof(ulong?)] = true, - [typeof(double)] = true, [typeof(double?)] = true, - [typeof(float)] = true, [typeof(float?)] = true, - [typeof(decimal)] = true, [typeof(decimal?)] = true - }); - public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that); - public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true; - public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; - public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GenericTypeArguments.First() : that; + static Lazy> dicIsNumberType = new Lazy>(() => new Dictionary + { + [typeof(sbyte)] = true, + [typeof(sbyte?)] = true, + [typeof(short)] = true, + [typeof(short?)] = true, + [typeof(int)] = true, + [typeof(int?)] = true, + [typeof(long)] = true, + [typeof(long?)] = true, + [typeof(byte)] = true, + [typeof(byte?)] = true, + [typeof(ushort)] = true, + [typeof(ushort?)] = true, + [typeof(uint)] = true, + [typeof(uint?)] = true, + [typeof(ulong)] = true, + [typeof(ulong?)] = true, + [typeof(double)] = true, + [typeof(double?)] = true, + [typeof(float)] = true, + [typeof(float?)] = true, + [typeof(decimal)] = true, + [typeof(decimal?)] = true + }); + public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that); + public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true; + public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; + public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GenericTypeArguments.First() : that; - /// - /// 测量两个经纬度的距离,返回单位:米 - /// - /// 经纬坐标1 - /// 经纬坐标2 - /// 返回距离(单位:米) - public static double Distance(this Point that, Point point) { - double radLat1 = (double)(that.Y) * Math.PI / 180d; - double radLng1 = (double)(that.X) * Math.PI / 180d; - double radLat2 = (double)(point.Y) * Math.PI / 180d; - double radLng2 = (double)(point.X) * Math.PI / 180d; - 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; - } + /// + /// 测量两个经纬度的距离,返回单位:米 + /// + /// 经纬坐标1 + /// 经纬坐标2 + /// 返回距离(单位:米) + public static double Distance(this Point that, Point point) + { + double radLat1 = (double)(that.Y) * Math.PI / 180d; + double radLng1 = (double)(that.X) * Math.PI / 180d; + double radLat2 = (double)(point.Y) * Math.PI / 180d; + double radLng2 = (double)(point.X) * Math.PI / 180d; + 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; + } - static ConcurrentDictionary _dicGetFields = new ConcurrentDictionary(); - public static object GetEnum(this IDataReader dr, int index) { - var value = dr.GetString(index); - var t = typeof(T); - var fs = _dicGetFields.GetOrAdd(t, t2 => t2.GetFields()); - foreach (var f in fs) - if (f.GetCustomAttribute()?.Description == value || f.Name == value) return Enum.Parse(t, f.Name, true); - return null; - } + static ConcurrentDictionary _dicGetFields = new ConcurrentDictionary(); + public static object GetEnum(this IDataReader dr, int index) + { + var value = dr.GetString(index); + var t = typeof(T); + var fs = _dicGetFields.GetOrAdd(t, t2 => t2.GetFields()); + foreach (var f in fs) + if (f.GetCustomAttribute()?.Description == value || f.Name == value) return Enum.Parse(t, f.Name, true); + return null; + } - public static string ToDescriptionOrString(this Enum item) { - string name = item.ToString(); - var desc = item.GetType().GetField(name)?.GetCustomAttribute(); - return desc?.Description ?? name; - } - public static long ToInt64(this Enum item) { - return Convert.ToInt64(item); - } - public static IEnumerable ToSet(this long value) { - var ret = new List(); - if (value == 0) return ret; - var t = typeof(T); - var fs = _dicGetFields.GetOrAdd(t, t2 => t2.GetFields()); - foreach (var f in fs) { - if (f.FieldType != t) continue; - object o = Enum.Parse(t, f.Name, true); - long v = (long)o; - if ((value & v) == v) ret.Add((T)o); - } - return ret; - } + public static string ToDescriptionOrString(this Enum item) + { + string name = item.ToString(); + var desc = item.GetType().GetField(name)?.GetCustomAttribute(); + return desc?.Description ?? name; + } + public static long ToInt64(this Enum item) + { + return Convert.ToInt64(item); + } + public static IEnumerable ToSet(this long value) + { + var ret = new List(); + if (value == 0) return ret; + var t = typeof(T); + var fs = _dicGetFields.GetOrAdd(t, t2 => t2.GetFields()); + foreach (var f in fs) + { + if (f.FieldType != t) continue; + object o = Enum.Parse(t, f.Name, true); + long v = (long)o; + if ((value & v) == v) ret.Add((T)o); + } + return ret; + } - /// - /// 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 - /// - /// - /// - /// - public static ISelect AsSelect(this IEnumerable that) where TEntity : class { - throw new NotImplementedException(); - } - public static ISelect AsSelect(this IEnumerable that, IFreeSql orm = null) where TEntity : class { - return orm?.Select(); - } + /// + /// 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + /// + /// + /// + /// + public static ISelect AsSelect(this IEnumerable that) where TEntity : class + { + throw new NotImplementedException(); + } + public static ISelect AsSelect(this IEnumerable that, IFreeSql orm = null) where TEntity : class + { + return orm?.Select(); + } } \ No newline at end of file diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 8a00b022..ff8e9b89 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -9,90 +9,99 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; -namespace System.Linq.Expressions { - public static partial class LambadaExpressionExtensions { +namespace System.Linq.Expressions +{ + public static partial class LambadaExpressionExtensions + { - /// - /// 使用 and 拼接两个 lambda 表达式 - /// - /// - public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); - /// - /// 使用 and 拼接两个 lambda 表达式 - /// - /// - /// - /// true 时生效 - /// - /// - public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) { - if (condition == false) return exp1; - if (exp1 == null) return exp2; - if (exp2 == null) return exp1; + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + /// + /// true 时生效 + /// + /// + public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) + { + if (condition == false) return exp1; + if (exp1 == null) return exp2; + if (exp2 == null) return exp1; - ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); - NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); + ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); + NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); - var left = visitor.Replace(exp1.Body); - var right = visitor.Replace(exp2.Body); - var body = Expression.AndAlso(left, right); - return Expression.Lambda>(body, newParameter); - } + var left = visitor.Replace(exp1.Body); + var right = visitor.Replace(exp2.Body); + var body = Expression.AndAlso(left, right); + return Expression.Lambda>(body, newParameter); + } - /// - /// 使用 or 拼接两个 lambda 表达式 - /// - /// - public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); - /// - /// 使用 or 拼接两个 lambda 表达式 - /// - /// - /// - /// true 时生效 - /// - /// - public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) { - if (condition == false) return exp1; - if (exp1 == null) return exp2; - if (exp2 == null) return exp1; + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + /// + /// true 时生效 + /// + /// + public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) + { + if (condition == false) return exp1; + if (exp1 == null) return exp2; + if (exp2 == null) return exp1; - ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); - NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); + ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); + NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); - var left = visitor.Replace(exp1.Body); - var right = visitor.Replace(exp2.Body); - var body = Expression.OrElse(left, right); - return Expression.Lambda>(body, newParameter); - } + var left = visitor.Replace(exp1.Body); + var right = visitor.Replace(exp2.Body); + var body = Expression.OrElse(left, right); + return Expression.Lambda>(body, newParameter); + } - /// - /// 将 lambda 表达式取反 - /// - /// - /// - /// true 时生效 - /// - public static Expression> Not(this Expression> exp, bool condition = true) { - if (condition == false) return exp; - if (exp == null) return null; + /// + /// 将 lambda 表达式取反 + /// + /// + /// + /// true 时生效 + /// + public static Expression> Not(this Expression> exp, bool condition = true) + { + if (condition == false) return exp; + if (exp == null) return null; - var candidateExpr = exp.Parameters[0]; - var body = Expression.Not(exp.Body); - return Expression.Lambda>(body, candidateExpr); - } - } + var candidateExpr = exp.Parameters[0]; + var body = Expression.Not(exp.Body); + return Expression.Lambda>(body, candidateExpr); + } + } - internal class NewExpressionVisitor : ExpressionVisitor { - public ParameterExpression _newParameter { get; private set; } - public NewExpressionVisitor(ParameterExpression param) { - this._newParameter = param; - } - public Expression Replace(Expression exp) { - return this.Visit(exp); - } - protected override Expression VisitParameter(ParameterExpression node) { - return this._newParameter; - } - } + internal class NewExpressionVisitor : ExpressionVisitor + { + public ParameterExpression _newParameter { get; private set; } + public NewExpressionVisitor(ParameterExpression param) + { + this._newParameter = param; + } + public Expression Replace(Expression exp) + { + return this.Visit(exp); + } + protected override Expression VisitParameter(ParameterExpression node) + { + return this._newParameter; + } + } } \ No newline at end of file diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 56fca2a8..3235583c 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -5,106 +5,117 @@ using System.Reflection; using FreeSql.DataAnnotations; using FreeSql.Internal; -namespace FreeSql { - public class FreeSqlBuilder { - DataType _dataType; - string _masterConnectionString; - string[] _slaveConnectionString; - bool _isAutoSyncStructure = false; - bool _isSyncStructureToLower = false; - bool _isSyncStructureToUpper = false; - bool _isConfigEntityFromDbFirst = false; - bool _isNoneCommandParameter = false; - bool _isLazyLoading = false; +namespace FreeSql +{ + public class FreeSqlBuilder + { + DataType _dataType; + string _masterConnectionString; + string[] _slaveConnectionString; + bool _isAutoSyncStructure = false; + bool _isSyncStructureToLower = false; + bool _isSyncStructureToUpper = false; + bool _isConfigEntityFromDbFirst = false; + bool _isNoneCommandParameter = false; + bool _isLazyLoading = false; StringConvertType _entityPropertyConvertType = StringConvertType.None; - Action _aopCommandExecuting = null; - Action _aopCommandExecuted = null; + Action _aopCommandExecuting = null; + Action _aopCommandExecuted = null; - /// - /// 使用连接串 - /// - /// 数据库类型 - /// 数据库连接串 - /// - public FreeSqlBuilder UseConnectionString(DataType dataType, string connectionString) { - _dataType = dataType; - _masterConnectionString = connectionString; - return this; - } - /// - /// 使用从数据库,支持多个 - /// - /// 从数据库连接串 - /// - public FreeSqlBuilder UseSlave(params string[] slaveConnectionString) { - _slaveConnectionString = slaveConnectionString; - return this; - } - /// - /// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - /// - /// true:运行时检查自动同步结构, false:不同步结构 - /// - public FreeSqlBuilder UseAutoSyncStructure(bool value) { - _isAutoSyncStructure = value; - return this; - } - /// - /// 转小写同步结构 - /// - /// true:转小写, false:不转 - /// - public FreeSqlBuilder UseSyncStructureToLower(bool value) { - _isSyncStructureToLower = value; - return this; - } - /// - /// 转大写同步结构 - /// - /// true:转大写, false:不转 - /// - public FreeSqlBuilder UseSyncStructureToUpper(bool value) { - _isSyncStructureToUpper = value; - return this; - } - /// - /// 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 - /// - /// - /// - public FreeSqlBuilder UseConfigEntityFromDbFirst(bool value) { - _isConfigEntityFromDbFirst = value; - return this; - } - /// - /// 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() - /// - /// - /// - public FreeSqlBuilder UseNoneCommandParameter(bool value) { - _isNoneCommandParameter = value; - return this; - } - /// - /// 延时加载导航属性对象,导航属性需要声明 virtual - /// - /// - /// - public FreeSqlBuilder UseLazyLoading(bool value) { - _isLazyLoading = value; - return this; - } - /// - /// 监视数据库命令对象 - /// - /// 执行前 - /// 执行后,可监视执行性能 - /// - public FreeSqlBuilder UseMonitorCommand(Action executing, Action executed = null) { - _aopCommandExecuting = executing; - _aopCommandExecuted = executed; - return this; - } + /// + /// 使用连接串 + /// + /// 数据库类型 + /// 数据库连接串 + /// + public FreeSqlBuilder UseConnectionString(DataType dataType, string connectionString) + { + _dataType = dataType; + _masterConnectionString = connectionString; + return this; + } + /// + /// 使用从数据库,支持多个 + /// + /// 从数据库连接串 + /// + public FreeSqlBuilder UseSlave(params string[] slaveConnectionString) + { + _slaveConnectionString = slaveConnectionString; + return this; + } + /// + /// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + /// + /// true:运行时检查自动同步结构, false:不同步结构 + /// + public FreeSqlBuilder UseAutoSyncStructure(bool value) + { + _isAutoSyncStructure = value; + return this; + } + /// + /// 转小写同步结构 + /// + /// true:转小写, false:不转 + /// + public FreeSqlBuilder UseSyncStructureToLower(bool value) + { + _isSyncStructureToLower = value; + return this; + } + /// + /// 转大写同步结构 + /// + /// true:转大写, false:不转 + /// + public FreeSqlBuilder UseSyncStructureToUpper(bool value) + { + _isSyncStructureToUpper = value; + return this; + } + /// + /// 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 + /// + /// + /// + public FreeSqlBuilder UseConfigEntityFromDbFirst(bool value) + { + _isConfigEntityFromDbFirst = value; + return this; + } + /// + /// 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() + /// + /// + /// + public FreeSqlBuilder UseNoneCommandParameter(bool value) + { + _isNoneCommandParameter = value; + return this; + } + /// + /// 延时加载导航属性对象,导航属性需要声明 virtual + /// + /// + /// + public FreeSqlBuilder UseLazyLoading(bool value) + { + _isLazyLoading = value; + return this; + } + /// + /// 监视数据库命令对象 + /// + /// 执行前 + /// 执行后,可监视执行性能 + /// + public FreeSqlBuilder UseMonitorCommand(Action executing, Action executed = null) + { + _aopCommandExecuting = executing; + _aopCommandExecuted = executed; + return this; + } /// /// 自动转换实体属性名称 Entity Property -> Db Filed @@ -120,78 +131,92 @@ namespace FreeSql { } public IFreeSql Build() => Build(); - public IFreeSql Build() { - if (string.IsNullOrEmpty(_masterConnectionString)) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString"); - IFreeSql ret = null; - Type type = null; - switch(_dataType) { - case DataType.MySql: - type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); - if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); - break; - case DataType.SqlServer: type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); - break; - case DataType.PostgreSQL: type = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); - break; - case DataType.Oracle: type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); - break; - case DataType.Sqlite: type = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); - break; - default: throw new Exception("未指定 UseConnectionString"); - } - ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql; - if (ret != null) { - ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure; + public IFreeSql Build() + { + if (string.IsNullOrEmpty(_masterConnectionString)) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString"); + IFreeSql ret = null; + Type type = null; + switch (_dataType) + { + case DataType.MySql: + type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); + if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); + break; + case DataType.SqlServer: + type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); + break; + case DataType.PostgreSQL: + type = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); + break; + case DataType.Oracle: + type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); + break; + case DataType.Sqlite: + type = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); + break; + default: throw new Exception("未指定 UseConnectionString"); + } + ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql; + if (ret != null) + { + ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure; - ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower; - ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper; - ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst; - ret.CodeFirst.IsNoneCommandParameter = _isNoneCommandParameter; - ret.CodeFirst.IsLazyLoading = _isLazyLoading; - var ado = ret.Ado as Internal.CommonProvider.AdoProvider; - ado.AopCommandExecuting += _aopCommandExecuting; - ado.AopCommandExecuted += _aopCommandExecuted; + ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower; + ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper; + ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst; + ret.CodeFirst.IsNoneCommandParameter = _isNoneCommandParameter; + ret.CodeFirst.IsLazyLoading = _isLazyLoading; + var ado = ret.Ado as Internal.CommonProvider.AdoProvider; + ado.AopCommandExecuting += _aopCommandExecuting; + ado.AopCommandExecuted += _aopCommandExecuted; - //添加实体属性名全局AOP转换处理 - if (_entityPropertyConvertType != StringConvertType.None) { - switch (_entityPropertyConvertType) { - case StringConvertType.Lower: - ret.Aop.ConfigEntityProperty = (s, e) => { - e.ModifyResult.Name = e.Property.Name.ToLower(); - }; - break; - case StringConvertType.Upper: - ret.Aop.ConfigEntityProperty = (s, e) => { - e.ModifyResult.Name = e.Property.Name.ToUpper(); - }; - break; - case StringConvertType.PascalCaseToUnderscore: - ret.Aop.ConfigEntityProperty = (s, e) => { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); - }; - break; - case StringConvertType.PascalCaseToUnderscoreWithLower: - ret.Aop.ConfigEntityProperty = (s, e) => { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); - }; - break; - case StringConvertType.PascalCaseToUnderscoreWithUpper: - ret.Aop.ConfigEntityProperty = (s, e) => { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); - }; - break; - default: - break; - } - } - } + //添加实体属性名全局AOP转换处理 + if (_entityPropertyConvertType != StringConvertType.None) + { + switch (_entityPropertyConvertType) + { + case StringConvertType.Lower: + ret.Aop.ConfigEntityProperty = (s, e) => + { + e.ModifyResult.Name = e.Property.Name.ToLower(); + }; + break; + case StringConvertType.Upper: + ret.Aop.ConfigEntityProperty = (s, e) => + { + e.ModifyResult.Name = e.Property.Name.ToUpper(); + }; + break; + case StringConvertType.PascalCaseToUnderscore: + ret.Aop.ConfigEntityProperty = (s, e) => + { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); + }; + break; + case StringConvertType.PascalCaseToUnderscoreWithLower: + ret.Aop.ConfigEntityProperty = (s, e) => + { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); + }; + break; + case StringConvertType.PascalCaseToUnderscoreWithUpper: + ret.Aop.ConfigEntityProperty = (s, e) => + { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); + }; + break; + default: + break; + } + } + } - return ret; - } - } + return ret; + } + } } diff --git a/FreeSql/FreeUtil.cs b/FreeSql/FreeUtil.cs index 11a82798..d6007789 100644 --- a/FreeSql/FreeUtil.cs +++ b/FreeSql/FreeUtil.cs @@ -6,29 +6,31 @@ using System.Diagnostics; using System.Threading; using System.Threading.Tasks; -public static class FreeUtil { +public static class FreeUtil +{ - private static DateTime dt1970 = new DateTime(1970, 1, 1); - private static ThreadLocal rnd = new ThreadLocal(() => new Random()); - private static readonly int __staticMachine = ((0x00ffffff & Environment.MachineName.GetHashCode()) + + private static DateTime dt1970 = new DateTime(1970, 1, 1); + private static ThreadLocal rnd = new ThreadLocal(() => new Random()); + private static readonly int __staticMachine = ((0x00ffffff & Environment.MachineName.GetHashCode()) + #if NETSTANDARD1_5 || NETSTANDARD1_6 1 #else - AppDomain.CurrentDomain.Id + AppDomain.CurrentDomain.Id #endif - ) & 0x00ffffff; - private static readonly int __staticPid = Process.GetCurrentProcess().Id; - private static int __staticIncrement = rnd.Value.Next(); - /// - /// 生成类似Mongodb的ObjectId有序、不重复Guid - /// - /// - public static Guid NewMongodbId() { - var now = DateTime.Now; - var uninxtime = (int)now.Subtract(dt1970).TotalSeconds; - int increment = Interlocked.Increment(ref __staticIncrement) & 0x00ffffff; - var rand = rnd.Value.Next(0, int.MaxValue); - 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')}"; - return Guid.Parse(guid); - } + ) & 0x00ffffff; + private static readonly int __staticPid = Process.GetCurrentProcess().Id; + private static int __staticIncrement = rnd.Value.Next(); + /// + /// 生成类似Mongodb的ObjectId有序、不重复Guid + /// + /// + public static Guid NewMongodbId() + { + var now = DateTime.Now; + var uninxtime = (int)now.Subtract(dt1970).TotalSeconds; + int increment = Interlocked.Increment(ref __staticIncrement) & 0x00ffffff; + var rand = rnd.Value.Next(0, int.MaxValue); + 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')}"; + return Guid.Parse(guid); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 5218d0ce..b038153f 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -4,90 +4,92 @@ using System.Data.Common; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface IDelete where T1 : class { +namespace FreeSql +{ + public interface IDelete where T1 : class + { - /// - /// 指定事务对象 - /// - /// - /// - IDelete WithTransaction(DbTransaction transaction); - /// - /// 指定事务对象 - /// - /// - /// - IDelete WithConnection(DbConnection connection); + /// + /// 指定事务对象 + /// + /// + /// + IDelete WithTransaction(DbTransaction transaction); + /// + /// 指定事务对象 + /// + /// + /// + IDelete WithConnection(DbConnection connection); - /// - /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) - /// - /// lambda表达式条件 - /// - IDelete Where(Expression> exp); - /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) - /// - /// sql语法条件 - /// 参数 - /// - IDelete Where(string sql, object parms = null); - /// - /// 传入实体,将主键作为条件 - /// - /// 实体 - /// - IDelete Where(T1 item); - /// - /// 传入实体集合,将主键作为条件 - /// - /// 实体集合 - /// - IDelete Where(IEnumerable items); - /// - /// 子查询是否存在 - /// - /// - /// 子查询 - /// 不存在 - /// - IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class; - /// - /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - IDelete WhereDynamic(object dywhere); + /// + /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) + /// + /// lambda表达式条件 + /// + IDelete Where(Expression> exp); + /// + /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// + /// sql语法条件 + /// 参数 + /// + IDelete Where(string sql, object parms = null); + /// + /// 传入实体,将主键作为条件 + /// + /// 实体 + /// + IDelete Where(T1 item); + /// + /// 传入实体集合,将主键作为条件 + /// + /// 实体集合 + /// + IDelete Where(IEnumerable items); + /// + /// 子查询是否存在 + /// + /// + /// 子查询 + /// 不存在 + /// + IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class; + /// + /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + IDelete WhereDynamic(object dywhere); - /// - /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - /// - /// - /// - IDelete AsTable(Func tableRule); - /// - /// 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 - /// - /// - /// - IDelete AsType(Type entityType); - /// - /// 返回即将执行的SQL语句 - /// - /// - string ToSql(); - /// - /// 执行SQL语句,返回影响的行数 - /// - /// - int ExecuteAffrows(); - Task ExecuteAffrowsAsync(); - /// - /// 执行SQL语句,返回被删除的记录 - /// - /// - List ExecuteDeleted(); - Task> ExecuteDeletedAsync(); - } + /// + /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + /// + /// + /// + IDelete AsTable(Func tableRule); + /// + /// 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 + /// + /// + /// + IDelete AsType(Type entityType); + /// + /// 返回即将执行的SQL语句 + /// + /// + string ToSql(); + /// + /// 执行SQL语句,返回影响的行数 + /// + /// + int ExecuteAffrows(); + Task ExecuteAffrowsAsync(); + /// + /// 执行SQL语句,返回被删除的记录 + /// + /// + List ExecuteDeleted(); + Task> ExecuteDeletedAsync(); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 90c0239d..09184d67 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -4,94 +4,96 @@ using System.Data.Common; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface IInsert where T1 : class { +namespace FreeSql +{ + public interface IInsert where T1 : class + { - /// - /// 指定事务对象 - /// - /// - /// - IInsert WithTransaction(DbTransaction transaction); - /// - /// 指定事务对象 - /// - /// - /// - IInsert WithConnection(DbConnection connection); + /// + /// 指定事务对象 + /// + /// + /// + IInsert WithTransaction(DbTransaction transaction); + /// + /// 指定事务对象 + /// + /// + /// + IInsert WithConnection(DbConnection connection); - /// - /// 追加准备插入的实体 - /// - /// 实体 - /// - IInsert AppendData(T1 source); - /// - /// 追加准备插入的实体 - /// - /// 实体 - /// - IInsert AppendData(T1[] source); - /// - /// 追加准备插入的实体集合 - /// - /// 实体集合 - /// - IInsert AppendData(IEnumerable source); + /// + /// 追加准备插入的实体 + /// + /// 实体 + /// + IInsert AppendData(T1 source); + /// + /// 追加准备插入的实体 + /// + /// 实体 + /// + IInsert AppendData(T1[] source); + /// + /// 追加准备插入的实体集合 + /// + /// 实体集合 + /// + IInsert AppendData(IEnumerable source); - /// - /// 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) - /// - /// lambda选择列 - /// - IInsert InsertColumns(Expression> columns); - /// - /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - /// - /// lambda选择列 - /// - IInsert IgnoreColumns(Expression> columns); + /// + /// 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) + /// + /// lambda选择列 + /// + IInsert InsertColumns(Expression> columns); + /// + /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + /// + /// lambda选择列 + /// + IInsert IgnoreColumns(Expression> columns); - /// - /// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - /// - /// - IInsert NoneParameter(); + /// + /// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + /// + /// + IInsert NoneParameter(); - /// - /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - /// - /// - /// - IInsert AsTable(Func tableRule); - /// - /// 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 - /// - /// - /// - IInsert AsType(Type entityType); - /// - /// 返回即将执行的SQL语句 - /// - /// - string ToSql(); - /// - /// 执行SQL语句,返回影响的行数 - /// - /// - int ExecuteAffrows(); - Task ExecuteAffrowsAsync(); - /// - /// 执行SQL语句,返回自增值 - /// - /// - long ExecuteIdentity(); - Task ExecuteIdentityAsync(); - /// - /// 执行SQL语句,返回插入后的记录 - /// - /// - List ExecuteInserted(); - Task> ExecuteInsertedAsync(); - } + /// + /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + /// + /// + /// + IInsert AsTable(Func tableRule); + /// + /// 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 + /// + /// + /// + IInsert AsType(Type entityType); + /// + /// 返回即将执行的SQL语句 + /// + /// + string ToSql(); + /// + /// 执行SQL语句,返回影响的行数 + /// + /// + int ExecuteAffrows(); + Task ExecuteAffrowsAsync(); + /// + /// 执行SQL语句,返回自增值 + /// + /// + long ExecuteIdentity(); + Task ExecuteIdentityAsync(); + /// + /// 执行SQL语句,返回插入后的记录 + /// + /// + List ExecuteInserted(); + Task> ExecuteInsertedAsync(); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ILinqToSql.cs b/FreeSql/Interface/Curd/ISelect/ILinqToSql.cs index 9d0bea94..bba2d4e0 100644 --- a/FreeSql/Interface/Curd/ISelect/ILinqToSql.cs +++ b/FreeSql/Interface/Curd/ISelect/ILinqToSql.cs @@ -3,27 +3,29 @@ using System.Collections.Generic; using System.Linq.Expressions; using System.Text; -namespace FreeSql { - public interface ILinqToSql where T1 : class { - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect Select(Expression> select) where TReturn : class; - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect Join(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector) where TInner : class where TResult : class; - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect GroupJoin(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector) where TInner : class where TResult : class; - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect DefaultIfEmpty(); - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect SelectMany(Expression>> collectionSelector, Expression> resultSelector) where TCollection : class where TResult : class; - } +namespace FreeSql +{ + public interface ILinqToSql where T1 : class + { + /// + /// 【linq to sql】专用方法,不建议直接使用 + /// + ISelect Select(Expression> select) where TReturn : class; + /// + /// 【linq to sql】专用方法,不建议直接使用 + /// + ISelect Join(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector) where TInner : class where TResult : class; + /// + /// 【linq to sql】专用方法,不建议直接使用 + /// + ISelect GroupJoin(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector) where TInner : class where TResult : class; + /// + /// 【linq to sql】专用方法,不建议直接使用 + /// + ISelect DefaultIfEmpty(); + /// + /// 【linq to sql】专用方法,不建议直接使用 + /// + ISelect SelectMany(Expression>> collectionSelector, Expression> resultSelector) where TCollection : class where TResult : class; + } } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index d162d72a..8e1567b3 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -6,255 +6,257 @@ using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; -namespace FreeSql { - public interface ISelect0 { +namespace FreeSql +{ + public interface ISelect0 + { - /// - /// 指定事务对象 - /// - /// - /// - TSelect WithTransaction(DbTransaction transaction); - /// - /// 指定连接对象 - /// - /// - /// - TSelect WithConnection(DbConnection connection); + /// + /// 指定事务对象 + /// + /// + /// + TSelect WithTransaction(DbTransaction transaction); + /// + /// 指定连接对象 + /// + /// + /// + TSelect WithConnection(DbConnection connection); - /// - /// 审核或跟踪 ToList 即将返回的数据 - /// - /// - /// - TSelect TrackToList(Action action); + /// + /// 审核或跟踪 ToList 即将返回的数据 + /// + /// + /// + TSelect TrackToList(Action action); - /// - /// 执行SQL查询,返回 DataTable - /// - /// - DataTable ToDataTable(string field = null); - Task ToDataTableAsync(string field = null); + /// + /// 执行SQL查询,返回 DataTable + /// + /// + DataTable ToDataTable(string field = null); + Task ToDataTableAsync(string field = null); - /// - /// 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 - /// - /// false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - /// - List ToList(bool includeNestedMembers = false); - Task> ToListAsync(bool includeNestedMembers = false); - /// - /// 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 - /// - /// - /// - /// - List ToList(string field); - Task> ToListAsync(string field); - /// - /// 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - /// - /// - T1 ToOne(); - Task ToOneAsync(); + /// + /// 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + /// + /// false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + /// + List ToList(bool includeNestedMembers = false); + Task> ToListAsync(bool includeNestedMembers = false); + /// + /// 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 + /// + /// + /// + /// + List ToList(string field); + Task> ToListAsync(string field); + /// + /// 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + /// + /// + T1 ToOne(); + Task ToOneAsync(); - /// - /// 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - /// - /// - T1 First(); - Task FirstAsync(); + /// + /// 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + /// + /// + T1 First(); + Task FirstAsync(); - /// - /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; - /// - /// - /// - TSelect AsTable(Func tableRule); - /// - /// 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 - /// - /// - /// - TSelect AsType(Type entityType); - /// - /// 返回即将执行的SQL语句 - /// - /// 指定字段 - /// - string ToSql(string field = null); - /// - /// 执行SQL查询,是否有记录 - /// - /// - bool Any(); - Task AnyAsync(); + /// + /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + /// + /// + /// + TSelect AsTable(Func tableRule); + /// + /// 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 + /// + /// + /// + TSelect AsType(Type entityType); + /// + /// 返回即将执行的SQL语句 + /// + /// 指定字段 + /// + string ToSql(string field = null); + /// + /// 执行SQL查询,是否有记录 + /// + /// + bool Any(); + Task AnyAsync(); - /// - /// 查询的记录数量 - /// - /// - long Count(); - Task CountAsync(); - /// - /// 查询的记录数量,以参数out形式返回 - /// - /// 返回的变量 - /// - TSelect Count(out long count); + /// + /// 查询的记录数量 + /// + /// + long Count(); + Task CountAsync(); + /// + /// 查询的记录数量,以参数out形式返回 + /// + /// 返回的变量 + /// + TSelect Count(out long count); - /// - /// 指定从主库查询(默认查询从库) - /// - /// - TSelect Master(); + /// + /// 指定从主库查询(默认查询从库) + /// + /// + TSelect Master(); - /// - /// 左联查询,使用导航属性自动生成SQL - /// - /// 表达式 - /// - TSelect LeftJoin(Expression> exp); - /// - /// 联接查询,使用导航属性自动生成SQL - /// - /// 表达式 - /// - TSelect InnerJoin(Expression> exp); - /// - /// 右联查询,使用导航属性自动生成SQL - /// - /// 表达式 - /// - TSelect RightJoin(Expression> exp); - /// - /// 左联查询,指定关联的实体类型 - /// - /// 关联的实体类型 - /// 表达式 - /// - TSelect LeftJoin(Expression> exp); - /// - /// 联接查询,指定关联的实体类型 - /// - /// 关联的实体类型 - /// 表达式 - /// - TSelect InnerJoin(Expression> exp); - /// - /// 右联查询,指定关联的实体类型 - /// - /// 关联的实体类型 - /// 表达式 - /// - TSelect RightJoin(Expression> exp); + /// + /// 左联查询,使用导航属性自动生成SQL + /// + /// 表达式 + /// + TSelect LeftJoin(Expression> exp); + /// + /// 联接查询,使用导航属性自动生成SQL + /// + /// 表达式 + /// + TSelect InnerJoin(Expression> exp); + /// + /// 右联查询,使用导航属性自动生成SQL + /// + /// 表达式 + /// + TSelect RightJoin(Expression> exp); + /// + /// 左联查询,指定关联的实体类型 + /// + /// 关联的实体类型 + /// 表达式 + /// + TSelect LeftJoin(Expression> exp); + /// + /// 联接查询,指定关联的实体类型 + /// + /// 关联的实体类型 + /// 表达式 + /// + TSelect InnerJoin(Expression> exp); + /// + /// 右联查询,指定关联的实体类型 + /// + /// 关联的实体类型 + /// 表达式 + /// + TSelect RightJoin(Expression> exp); - /// - /// 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - /// - /// sql语法条件 - /// 参数 - /// - TSelect LeftJoin(string sql, object parms = null); - /// - /// 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - /// - /// sql语法条件 - /// 参数 - /// - TSelect InnerJoin(string sql, object parms = null); - /// - /// 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - /// - /// sql语法条件 - /// 参数 - /// - TSelect RightJoin(string sql, object parms = null); + /// + /// 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// + /// sql语法条件 + /// 参数 + /// + TSelect LeftJoin(string sql, object parms = null); + /// + /// 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// + /// sql语法条件 + /// 参数 + /// + TSelect InnerJoin(string sql, object parms = null); + /// + /// 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// + /// sql语法条件 + /// 参数 + /// + TSelect RightJoin(string sql, object parms = null); - /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) - /// - /// sql语法条件 - /// 参数 - /// - TSelect Where(string sql, object parms = null); - /// - /// 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) - /// - /// true 时生效 - /// sql语法条件 - /// 参数 - /// - TSelect WhereIf(bool condition, string sql, object parms = null); + /// + /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// + /// sql语法条件 + /// 参数 + /// + TSelect Where(string sql, object parms = null); + /// + /// 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + /// + /// true 时生效 + /// sql语法条件 + /// 参数 + /// + TSelect WhereIf(bool condition, string sql, object parms = null); - /// - /// 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) - /// - /// sql语法 - /// 参数 - /// - TSelect GroupBy(string sql, object parms = null); - /// - /// 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) - /// - /// sql语法条件 - /// 参数 - /// - TSelect Having(string sql, object parms = null); + /// + /// 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + /// + /// sql语法 + /// 参数 + /// + TSelect GroupBy(string sql, object parms = null); + /// + /// 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + /// + /// sql语法条件 + /// 参数 + /// + TSelect Having(string sql, object parms = null); - /// - /// 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) - /// - /// sql语法 - /// 参数 - /// - TSelect OrderBy(string sql, object parms = null); - /// - /// 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) - /// - /// true 时生效 - /// sql语法 - /// 参数 - /// - TSelect OrderBy(bool condition, string sql, object parms = null); + /// + /// 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + /// + /// sql语法 + /// 参数 + /// + TSelect OrderBy(string sql, object parms = null); + /// + /// 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + /// + /// true 时生效 + /// sql语法 + /// 参数 + /// + TSelect OrderBy(bool condition, string sql, object parms = null); - /// - /// 查询向后偏移行数 - /// - /// - /// - TSelect Skip(int offset); - /// - /// 查询向后偏移行数 - /// - /// 行数 - /// - TSelect Offset(int offset); - /// - /// 查询多少条数据 - /// - /// - /// - TSelect Limit(int limit); - /// - /// 查询多少条数据 - /// - /// - /// - TSelect Take(int limit); + /// + /// 查询向后偏移行数 + /// + /// + /// + TSelect Skip(int offset); + /// + /// 查询向后偏移行数 + /// + /// 行数 + /// + TSelect Offset(int offset); + /// + /// 查询多少条数据 + /// + /// + /// + TSelect Limit(int limit); + /// + /// 查询多少条数据 + /// + /// + /// + TSelect Take(int limit); - /// - /// 分页 - /// - /// 第几页 - /// 每页多少 - /// - TSelect Page(int pageNumber, int pageSize); + /// + /// 分页 + /// + /// 第几页 + /// 每页多少 + /// + TSelect Page(int pageNumber, int pageSize); - /// - /// 查询数据前,去重 - /// - /// - TSelect Distinct(); - } + /// + /// 查询数据前,去重 + /// + /// + TSelect Distinct(); + } } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 0c5f2ce2..ffc07e50 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -4,325 +4,327 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface ISelect : ISelect0, T1>, ILinqToSql where T1 : class { +namespace FreeSql +{ + public interface ISelect : ISelect0, T1>, ILinqToSql where T1 : class + { - /// - /// 执行SQL查询,是否有记录 - /// - /// lambda表达式 - /// - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + /// + /// 执行SQL查询,是否有记录 + /// + /// lambda表达式 + /// + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - /// - /// 执行SQL查询,返回 DataTable - /// - /// - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + /// + /// 执行SQL查询,返回 DataTable + /// + /// + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - /// - /// 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - /// - /// 返回类型 - /// 选择列 - /// - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - /// - /// 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 - /// - /// - /// - List ToList(); - Task> ToListAsync(); + /// + /// 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + /// + /// 返回类型 + /// 选择列 + /// + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + /// + /// 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 + /// + /// + /// + List ToList(); + Task> ToListAsync(); - /// - /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - /// - /// 返回类型 - /// 选择列 - /// - TReturn ToOne(Expression> select); - Task ToOneAsync(Expression> select); + /// + /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + /// + /// 返回类型 + /// 选择列 + /// + TReturn ToOne(Expression> select); + Task ToOneAsync(Expression> select); - /// - /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - /// - /// 返回类型 - /// 选择列 - /// - TReturn First(Expression> select); - Task FirstAsync(Expression> select); + /// + /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + /// + /// 返回类型 + /// 选择列 + /// + TReturn First(Expression> select); + Task FirstAsync(Expression> select); - /// - /// 返回即将执行的SQL语句 - /// - /// 返回类型 - /// 选择列 - /// - string ToSql(Expression> select); + /// + /// 返回即将执行的SQL语句 + /// + /// 返回类型 + /// 选择列 + /// + string ToSql(Expression> select); - /// - /// 执行SQL查询,返回指定字段的聚合结果 - /// - /// - /// - /// - TReturn ToAggregate(Expression, TReturn>> select); - Task ToAggregateAsync(Expression, TReturn>> select); + /// + /// 执行SQL查询,返回指定字段的聚合结果 + /// + /// + /// + /// + TReturn ToAggregate(Expression, TReturn>> select); + Task ToAggregateAsync(Expression, TReturn>> select); - /// - /// 求和 - /// - /// 返回类型 - /// 列 - /// - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - /// - /// 最小值 - /// - /// 返回类型 - /// 列 - /// - TMember Min(Expression> column); - Task MinAsync(Expression> column); - /// - /// 最大值 - /// - /// 返回类型 - /// 列 - /// - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - /// - /// 平均值 - /// - /// 返回类型 - /// 列 - /// - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + /// + /// 求和 + /// + /// 返回类型 + /// 列 + /// + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + /// + /// 最小值 + /// + /// 返回类型 + /// 列 + /// + TMember Min(Expression> column); + Task MinAsync(Expression> column); + /// + /// 最大值 + /// + /// 返回类型 + /// 列 + /// + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + /// + /// 平均值 + /// + /// 返回类型 + /// 列 + /// + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - /// - /// 指定别名 - /// - /// 别名 - /// - ISelect As(string alias = "a"); + /// + /// 指定别名 + /// + /// 别名 + /// + ISelect As(string alias = "a"); - /// - /// 多表查询 - /// - /// - /// - /// - ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - /// - ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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; + /// + /// 多表查询 + /// + /// + /// + /// + ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class; + /// + /// 多表查询 + /// + /// + /// + /// + /// + ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class; + /// + /// 多表查询 + /// + /// + /// + /// + /// + /// + ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class; + /// + /// 多表查询 + /// + /// + /// + /// + /// + /// + /// + ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class; + /// + /// 多表查询 + /// + /// + /// + /// + /// + /// + /// + /// + ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; + /// + /// 多表查询 + /// + /// + /// + /// + /// + /// + /// + /// + /// + ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; + /// + /// 多表查询 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; + /// + /// 多表查询 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; + /// + /// 多表查询 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - /// - /// lambda表达式 - /// - ISelect Where(Expression> exp); - /// - /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - /// - /// true 时生效 - /// lambda表达式 - /// - ISelect WhereIf(bool condition, Expression> exp); - /// - /// 多表条件查询 - /// - /// - /// lambda表达式 - /// - ISelect Where(Expression> exp) where T2 : class; - /// - /// 多表条件查询 - /// - /// - /// lambda表达式 - /// - ISelect Where(Expression> exp) where T2 : class; - /// - /// 多表条件查询 - /// - /// - /// - /// lambda表达式 - /// - ISelect Where(Expression> exp) where T2 : class where T3 : class; - /// - /// 多表条件查询 - /// - /// - /// - /// - /// lambda表达式 - /// - ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class; - /// - /// 多表条件查询 - /// - /// - /// - /// - /// lambda表达式 - /// - ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class where T5 : class; - /// - /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - ISelect WhereDynamic(object dywhere); + /// + /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + /// + /// lambda表达式 + /// + ISelect Where(Expression> exp); + /// + /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + /// + /// true 时生效 + /// lambda表达式 + /// + ISelect WhereIf(bool condition, Expression> exp); + /// + /// 多表条件查询 + /// + /// + /// lambda表达式 + /// + ISelect Where(Expression> exp) where T2 : class; + /// + /// 多表条件查询 + /// + /// + /// lambda表达式 + /// + ISelect Where(Expression> exp) where T2 : class; + /// + /// 多表条件查询 + /// + /// + /// + /// lambda表达式 + /// + ISelect Where(Expression> exp) where T2 : class where T3 : class; + /// + /// 多表条件查询 + /// + /// + /// + /// + /// lambda表达式 + /// + ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class; + /// + /// 多表条件查询 + /// + /// + /// + /// + /// lambda表达式 + /// + ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class where T5 : class; + /// + /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + ISelect WhereDynamic(object dywhere); - /// - /// 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) - /// - /// - /// - ISelectGrouping GroupBy(Expression> exp); + /// + /// 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) + /// + /// + /// + ISelectGrouping GroupBy(Expression> exp); - /// - /// 按列排序,OrderBy(a => a.Time) - /// - /// - /// - /// - ISelect OrderBy(Expression> column); - /// - /// 按列排序,OrderBy(true, a => a.Time) - /// - /// - /// true 时生效 - /// - /// - ISelect OrderBy(bool condition, Expression> column); - /// - /// 按列倒向排序,OrderByDescending(a => a.Time) - /// - /// 列 - /// - ISelect OrderByDescending(Expression> column); - /// - /// 按列倒向排序,OrderByDescending(true, a => a.Time) - /// - /// true 时生效 - /// 列 - /// - ISelect OrderByDescending(bool condition, Expression> column); + /// + /// 按列排序,OrderBy(a => a.Time) + /// + /// + /// + /// + ISelect OrderBy(Expression> column); + /// + /// 按列排序,OrderBy(true, a => a.Time) + /// + /// + /// true 时生效 + /// + /// + ISelect OrderBy(bool condition, Expression> column); + /// + /// 按列倒向排序,OrderByDescending(a => a.Time) + /// + /// 列 + /// + ISelect OrderByDescending(Expression> column); + /// + /// 按列倒向排序,OrderByDescending(true, a => a.Time) + /// + /// true 时生效 + /// 列 + /// + ISelect OrderByDescending(bool condition, Expression> column); - /// - /// 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 - /// - /// - /// 选择一个导航属性 - /// - ISelect Include(Expression> navigateSelector) where TNavigate : class; - /// - /// 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 - /// - /// - /// 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 - /// 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - /// - ISelect IncludeMany(Expression>> navigateSelector, Action> then = null) where TNavigate : class; - } + /// + /// 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 + /// + /// + /// 选择一个导航属性 + /// + ISelect Include(Expression> navigateSelector) where TNavigate : class; + /// + /// 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + /// + /// + /// 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 + /// 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + /// + ISelect IncludeMany(Expression>> navigateSelector, Action> then = null) where TNavigate : class; + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 0d4ef4cb..15a8f4dd 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -4,39 +4,41 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - 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 { +namespace FreeSql +{ + 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 + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); - string ToSql(Expression> select); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 3ca335e5..c13f1b71 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -4,40 +4,42 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class { +namespace FreeSql +{ + public interface ISelect : ISelect0, T1> where T1 : class where T2 : class + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); - string ToSql(Expression> select); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index ae8c0c31..0d036dd6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -4,39 +4,41 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class { +namespace FreeSql +{ + public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); - string ToSql(Expression> select); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 9e0ef889..7787cf39 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -4,39 +4,41 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class { +namespace FreeSql +{ + public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); - string ToSql(Expression> select); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index 56fde4d2..c579b50a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -4,39 +4,41 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { +namespace FreeSql +{ + public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); - string ToSql(Expression> select); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index e56ed98d..05e42d96 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -4,39 +4,41 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { +namespace FreeSql +{ + public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); - string ToSql(Expression> select); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index 318b6ee9..25356edb 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -4,39 +4,41 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - 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 { +namespace FreeSql +{ + 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 + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); - string ToSql(Expression> select); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 55db9df2..1404be93 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -4,39 +4,41 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - 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 { +namespace FreeSql +{ + 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 + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); - string ToSql(Expression> select); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 5546f566..b6ed09ba 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -4,39 +4,41 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - 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 { +namespace FreeSql +{ + 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 + { - bool Any(Expression> exp); - Task AnyAsync(Expression> exp); + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); - List ToList(Expression> select); - Task> ToListAsync(Expression> select); - List ToList(); - Task> ToListAsync(); - string ToSql(Expression> select); + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + List ToList(); + Task> ToListAsync(); + string ToSql(Expression> select); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); - Task SumAsync(Expression> column); - TMember Min(Expression> column); - Task MinAsync(Expression> column); - TMember Max(Expression> column); - Task MaxAsync(Expression> column); - TMember Avg(Expression> column); - Task AvgAsync(Expression> column); + TMember Sum(Expression> column); + Task SumAsync(Expression> column); + TMember Min(Expression> column); + Task MinAsync(Expression> column); + TMember Max(Expression> column); + Task MaxAsync(Expression> column); + TMember Avg(Expression> column); + Task AvgAsync(Expression> column); - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping GroupBy(Expression> exp); - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - } + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs b/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs index 9150034e..6020ae4f 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs @@ -2,39 +2,41 @@ using System.Collections.Generic; using System.Linq.Expressions; -namespace FreeSql { - public interface ISelectFromExpression where T1 : class { +namespace FreeSql +{ + public interface ISelectFromExpression where T1 : class + { - ISelectFromExpression LeftJoin(Expression> exp); - ISelectFromExpression InnerJoin(Expression> exp); - ISelectFromExpression RightJoin(Expression> exp); + ISelectFromExpression LeftJoin(Expression> exp); + ISelectFromExpression InnerJoin(Expression> exp); + ISelectFromExpression RightJoin(Expression> exp); - /// - /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - /// - /// lambda表达式 - /// - ISelectFromExpression Where(Expression> exp); - /// - /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - /// - /// true 时生效 - /// lambda表达式 - /// - ISelectFromExpression WhereIf(bool condition, Expression> exp); + /// + /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + /// + /// lambda表达式 + /// + ISelectFromExpression Where(Expression> exp); + /// + /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + /// + /// true 时生效 + /// lambda表达式 + /// + ISelectFromExpression WhereIf(bool condition, Expression> exp); - /// - /// 按列排序,OrderBy(a => a.Time) - /// - /// - /// - /// - ISelectFromExpression OrderBy(Expression> column); - /// - /// 按列倒向排序,OrderByDescending(a => a.Time) - /// - /// 列 - /// - ISelectFromExpression OrderByDescending(Expression> column); - } + /// + /// 按列排序,OrderBy(a => a.Time) + /// + /// + /// + /// + ISelectFromExpression OrderBy(Expression> column); + /// + /// 按列倒向排序,OrderByDescending(a => a.Time) + /// + /// 列 + /// + ISelectFromExpression OrderByDescending(Expression> column); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 17c8ec0f..0b52dfbf 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -4,128 +4,132 @@ using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; -namespace FreeSql { - public interface ISelectGrouping { - /// - /// 按聚合条件过滤,Where(a => a.Count() > 10) - /// - /// lambda表达式 - /// - ISelectGrouping Having(Expression, bool>> exp); +namespace FreeSql +{ + public interface ISelectGrouping + { + /// + /// 按聚合条件过滤,Where(a => a.Count() > 10) + /// + /// lambda表达式 + /// + ISelectGrouping Having(Expression, bool>> exp); - /// - /// 按列排序,OrderBy(a => a.Time) - /// - /// - /// - /// - ISelectGrouping OrderBy(Expression, TMember>> column); - /// - /// 按列倒向排序,OrderByDescending(a => a.Time) - /// - /// 列 - /// - ISelectGrouping OrderByDescending(Expression, TMember>> column); + /// + /// 按列排序,OrderBy(a => a.Time) + /// + /// + /// + /// + ISelectGrouping OrderBy(Expression, TMember>> column); + /// + /// 按列倒向排序,OrderByDescending(a => a.Time) + /// + /// 列 + /// + ISelectGrouping OrderByDescending(Expression, TMember>> column); - /// - /// 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - /// - /// 返回类型 - /// 选择列 - /// - List ToList(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); + /// + /// 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + /// + /// 返回类型 + /// 选择列 + /// + List ToList(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - List Select(Expression, TReturn>> select); + /// + /// 【linq to sql】专用方法,不建议直接使用 + /// + List Select(Expression, TReturn>> select); - /// - /// 返回即将执行的SQL语句 - /// - /// 返回类型 - /// 选择列 - /// - string ToSql(Expression, TReturn>> select); + /// + /// 返回即将执行的SQL语句 + /// + /// 返回类型 + /// 选择列 + /// + string ToSql(Expression, TReturn>> select); - /// - /// 查询向后偏移行数 - /// - /// - /// - ISelectGrouping Skip(int offset); - /// - /// 查询向后偏移行数 - /// - /// 行数 - /// - ISelectGrouping Offset(int offset); - /// - /// 查询多少条数据 - /// - /// - /// - ISelectGrouping Limit(int limit); - /// - /// 查询多少条数据 - /// - /// - /// - ISelectGrouping Take(int limit); + /// + /// 查询向后偏移行数 + /// + /// + /// + ISelectGrouping Skip(int offset); + /// + /// 查询向后偏移行数 + /// + /// 行数 + /// + ISelectGrouping Offset(int offset); + /// + /// 查询多少条数据 + /// + /// + /// + ISelectGrouping Limit(int limit); + /// + /// 查询多少条数据 + /// + /// + /// + ISelectGrouping Take(int limit); - /// - /// 分页 - /// - /// 第几页 - /// 每页多少 - /// - ISelectGrouping Page(int pageNumber, int pageSize); - } + /// + /// 分页 + /// + /// 第几页 + /// 每页多少 + /// + ISelectGrouping Page(int pageNumber, int pageSize); + } - public interface ISelectGroupingAggregate { - /// - /// 分组的数据 - /// - TKey Key { get; set; } - /// - /// 记录总数 - /// - /// - int Count(); - /// - /// 求和 - /// - /// - /// - /// - T3 Sum(T3 column); - /// - /// 平均值 - /// - /// - /// - /// - T3 Avg(T3 column); - /// - /// 最大值 - /// - /// - /// - /// - T3 Max(T3 column); - /// - /// 最小值 - /// - /// - /// - T3 Min(T3 column); - } - public interface ISelectGroupingAggregate : ISelectGroupingAggregate { - /// - /// 所有元素 - /// - TValue Value { get; set; } - } + public interface ISelectGroupingAggregate + { + /// + /// 分组的数据 + /// + TKey Key { get; set; } + /// + /// 记录总数 + /// + /// + int Count(); + /// + /// 求和 + /// + /// + /// + /// + T3 Sum(T3 column); + /// + /// 平均值 + /// + /// + /// + /// + T3 Avg(T3 column); + /// + /// 最大值 + /// + /// + /// + /// + T3 Max(T3 column); + /// + /// 最小值 + /// + /// + /// + T3 Min(T3 column); + } + public interface ISelectGroupingAggregate : ISelectGroupingAggregate + { + /// + /// 所有元素 + /// + TValue Value { get; set; } + } } diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index d1708055..6e546d4d 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -4,159 +4,161 @@ using System.Data.Common; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql { - public interface IUpdate where T1 : class { +namespace FreeSql +{ + public interface IUpdate where T1 : class + { - /// - /// 指定事务对象 - /// - /// - /// - IUpdate WithTransaction(DbTransaction transaction); - /// - /// 指定事务对象 - /// - /// - /// - IUpdate WithConnection(DbConnection connection); + /// + /// 指定事务对象 + /// + /// + /// + IUpdate WithTransaction(DbTransaction transaction); + /// + /// 指定事务对象 + /// + /// + /// + IUpdate WithConnection(DbConnection connection); - /// - /// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - /// - /// - IUpdate NoneParameter(); + /// + /// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + /// + /// + IUpdate NoneParameter(); - /// - /// 更新数据,设置更新的实体 - /// - /// 实体 - /// - IUpdate SetSource(T1 source); - /// - /// 更新数据,设置更新的实体集合 - /// - /// 实体集合 - /// - IUpdate SetSource(IEnumerable source); - /// - /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - /// - /// lambda选择列 - /// - IUpdate IgnoreColumns(Expression> columns); - /// - /// 忽略的列 - /// - /// - /// - IUpdate IgnoreColumns(string[] columns); + /// + /// 更新数据,设置更新的实体 + /// + /// 实体 + /// + IUpdate SetSource(T1 source); + /// + /// 更新数据,设置更新的实体集合 + /// + /// 实体集合 + /// + IUpdate SetSource(IEnumerable source); + /// + /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + /// + /// lambda选择列 + /// + IUpdate IgnoreColumns(Expression> columns); + /// + /// 忽略的列 + /// + /// + /// + IUpdate IgnoreColumns(string[] columns); - /// - /// 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) - /// - /// lambda选择列 - /// - IUpdate UpdateColumns(Expression> columns); - /// - /// 指定的列 - /// - /// - /// - IUpdate UpdateColumns(string[] columns); + /// + /// 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + /// + /// lambda选择列 + /// + IUpdate UpdateColumns(Expression> columns); + /// + /// 指定的列 + /// + /// + /// + IUpdate UpdateColumns(string[] columns); - /// - /// 设置列的新值,Set(a => a.Name, "newvalue") - /// - /// - /// lambda选择列 - /// 新值 - /// - IUpdate Set(Expression> column, TMember value); - /// - /// 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 - /// - /// 指定更新,格式:Set(a => new { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' - /// - /// - /// - /// - IUpdate Set(Expression> exp); - /// - /// 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) - /// - /// sql语法 - /// 参数 - /// - IUpdate SetRaw(string sql, object parms = null); + /// + /// 设置列的新值,Set(a => a.Name, "newvalue") + /// + /// + /// lambda选择列 + /// 新值 + /// + IUpdate Set(Expression> column, TMember value); + /// + /// 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + /// + /// 指定更新,格式:Set(a => new { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + /// + /// + /// + /// + IUpdate Set(Expression> exp); + /// + /// 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + /// + /// sql语法 + /// 参数 + /// + IUpdate SetRaw(string sql, object parms = null); - /// - /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) - /// - /// lambda表达式条件 - /// - IUpdate Where(Expression> exp); - /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) - /// - /// sql语法条件 - /// 参数 - /// - IUpdate Where(string sql, object parms = null); - /// - /// 传入实体,将主键作为条件 - /// - /// 实体 - /// - IUpdate Where(T1 item); - /// - /// 传入实体集合,将主键作为条件 - /// - /// 实体集合 - /// - IUpdate Where(IEnumerable items); - /// - /// 子查询是否存在 - /// - /// - /// 子查询 - /// 不存在 - /// - IUpdate WhereExists(ISelect select, bool notExists = false) where TEntity2 : class; - /// - /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - IUpdate WhereDynamic(object dywhere); + /// + /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) + /// + /// lambda表达式条件 + /// + IUpdate Where(Expression> exp); + /// + /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// + /// sql语法条件 + /// 参数 + /// + IUpdate Where(string sql, object parms = null); + /// + /// 传入实体,将主键作为条件 + /// + /// 实体 + /// + IUpdate Where(T1 item); + /// + /// 传入实体集合,将主键作为条件 + /// + /// 实体集合 + /// + IUpdate Where(IEnumerable items); + /// + /// 子查询是否存在 + /// + /// + /// 子查询 + /// 不存在 + /// + IUpdate WhereExists(ISelect select, bool notExists = false) where TEntity2 : class; + /// + /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + IUpdate WhereDynamic(object dywhere); - /// - /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - /// - /// - /// - IUpdate AsTable(Func tableRule); - /// - /// 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 - /// - /// - /// - IUpdate AsType(Type entityType); - /// - /// 返回即将执行的SQL语句 - /// - /// - string ToSql(); - /// - /// 执行SQL语句,返回影响的行数 - /// - /// - int ExecuteAffrows(); - Task ExecuteAffrowsAsync(); - /// - /// 执行SQL语句,返回更新后的记录 - /// - /// - List ExecuteUpdated(); - Task> ExecuteUpdatedAsync(); - } + /// + /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + /// + /// + /// + IUpdate AsTable(Func tableRule); + /// + /// 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + /// + /// + /// + IUpdate AsType(Type entityType); + /// + /// 返回即将执行的SQL语句 + /// + /// + string ToSql(); + /// + /// 执行SQL语句,返回影响的行数 + /// + /// + int ExecuteAffrows(); + Task ExecuteAffrowsAsync(); + /// + /// 执行SQL语句,返回更新后的记录 + /// + /// + List ExecuteUpdated(); + Task> ExecuteUpdatedAsync(); + } } \ No newline at end of file diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 2eb67472..a1d16be1 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -7,385 +7,387 @@ using System.Data.Common; using System.Text; using System.Threading.Tasks; -namespace FreeSql { - public partial interface IAdo { - /// - /// 主库连接池 - /// - ObjectPool MasterPool { get; } - /// - /// 从库连接池 - /// - List> SlavePools { get; } - /// - /// 监视数据库命令对象(执行前,调试) - /// - Action AopCommandExecuting { get; set; } - /// - /// 监视数据库命令对象(执行后,用于监视执行性能) - /// - Action AopCommandExecuted { get; set; } - /// - /// 数据库类型 - /// - DataType DataType { get; } +namespace FreeSql +{ + public partial interface IAdo + { + /// + /// 主库连接池 + /// + ObjectPool MasterPool { get; } + /// + /// 从库连接池 + /// + List> SlavePools { get; } + /// + /// 监视数据库命令对象(执行前,调试) + /// + Action AopCommandExecuting { get; set; } + /// + /// 监视数据库命令对象(执行后,用于监视执行性能) + /// + Action AopCommandExecuted { get; set; } + /// + /// 数据库类型 + /// + DataType DataType { get; } - #region 事务 - /// - /// 开启事务(不支持异步),60秒未执行完将自动提交 - /// - /// 事务体 () => {} - void Transaction(Action handler); - /// - /// 开启事务(不支持异步) - /// - /// 事务体 () => {} - /// 超时,未执行完将自动提交 - void Transaction(Action handler, TimeSpan timeout); - /// - /// 当前线程的事务 - /// - DbTransaction TransactionCurrentThread { get; } - #endregion + #region 事务 + /// + /// 开启事务(不支持异步),60秒未执行完将自动提交 + /// + /// 事务体 () => {} + void Transaction(Action handler); + /// + /// 开启事务(不支持异步) + /// + /// 事务体 () => {} + /// 超时,未执行完将自动提交 + void Transaction(Action handler, TimeSpan timeout); + /// + /// 当前线程的事务 + /// + DbTransaction TransactionCurrentThread { get; } + #endregion - /// - /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - /// - /// - /// - /// - /// - void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 }) - /// - /// - /// - void ExecuteReader(Action readerHander, string cmdText, object parms = null); - void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null); - void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, string cmdText, object parms = null); - /// - /// 查询 - /// - /// - /// - object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 查询,ExecuteArray("select * from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - object[][] ExecuteArray(string cmdText, object parms = null); - object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null); - object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 查询 - /// - /// - /// - DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 查询,ExecuteDataSet("select * from user where age > @age; select 2", new { age = 25 }) - /// - /// - /// - /// - DataSet ExecuteDataSet(string cmdText, object parms = null); - DataSet ExecuteDataSet(DbTransaction transaction, string cmdText, object parms = null); - DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 查询 - /// - /// - /// - DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - DataTable ExecuteDataTable(string cmdText, object parms = null); - DataTable ExecuteDataTable(DbTransaction transaction, string cmdText, object parms = null); - DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 在【主库】执行 - /// - /// - /// - /// - int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - int ExecuteNonQuery(string cmdText, object parms = null); - int ExecuteNonQuery(DbTransaction transaction, string cmdText, object parms = null); - int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 在【主库】执行 - /// - /// - /// - /// - object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - object ExecuteScalar(string cmdText, object parms = null); - object ExecuteScalar(DbTransaction transaction, string cmdText, object parms = null); - object ExecuteScalar(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + /// + /// + /// + /// + /// + void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 }) + /// + /// + /// + void ExecuteReader(Action readerHander, string cmdText, object parms = null); + void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null); + void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, string cmdText, object parms = null); + /// + /// 查询 + /// + /// + /// + object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 查询,ExecuteArray("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + object[][] ExecuteArray(string cmdText, object parms = null); + object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null); + object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 查询 + /// + /// + /// + DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 查询,ExecuteDataSet("select * from user where age > @age; select 2", new { age = 25 }) + /// + /// + /// + /// + DataSet ExecuteDataSet(string cmdText, object parms = null); + DataSet ExecuteDataSet(DbTransaction transaction, string cmdText, object parms = null); + DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 查询 + /// + /// + /// + DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + DataTable ExecuteDataTable(string cmdText, object parms = null); + DataTable ExecuteDataTable(DbTransaction transaction, string cmdText, object parms = null); + DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 在【主库】执行 + /// + /// + /// + /// + int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + int ExecuteNonQuery(string cmdText, object parms = null); + int ExecuteNonQuery(DbTransaction transaction, string cmdText, object parms = null); + int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 在【主库】执行 + /// + /// + /// + /// + object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + object ExecuteScalar(string cmdText, object parms = null); + object ExecuteScalar(DbTransaction transaction, string cmdText, object parms = null); + object ExecuteScalar(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) - /// - /// - /// - /// - /// - /// - List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - /// - List Query(string cmdText, object parms = null); - List Query(DbTransaction transaction, string cmdText, object parms = null); - List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) + /// + /// + /// + /// + /// + /// + List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + /// + List Query(string cmdText, object parms = null); + List Query(DbTransaction transaction, string cmdText, object parms = null); + List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - /// - /// - /// - /// - /// - /// - (List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) - /// - /// - /// - /// - /// - (List, List) Query(string cmdText, object parms = null); - (List, List) Query(DbTransaction transaction, string cmdText, object parms = null); - (List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + /// + /// + /// + /// + /// + /// + (List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) + /// + /// + /// + /// + /// + (List, List) Query(string cmdText, object parms = null); + (List, List) Query(DbTransaction transaction, string cmdText, object parms = null); + (List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - (List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List) Query(string cmdText, object parms = null); - (List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); - (List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - (List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List) Query(string cmdText, object parms = null); - (List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); - (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - (List, List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List, List) Query(string cmdText, object parms = null); - (List, List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); - (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + (List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List) Query(string cmdText, object parms = null); + (List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); + (List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + (List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List, List) Query(string cmdText, object parms = null); + (List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); + (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + (List, List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + (List, List, List, List, List) Query(string cmdText, object parms = null); + (List, List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); + (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - #region async - /// - /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - /// - /// - /// - /// - /// - Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) - /// - /// - /// - Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null); - Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, string cmdText, object parms = null); - /// - /// 查询 - /// - /// - /// - Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - Task ExecuteArrayAsync(string cmdText, object parms = null); - Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 查询 - /// - /// - /// - Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) - /// - /// - /// - /// - Task ExecuteDataSetAsync(string cmdText, object parms = null); - Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 查询 - /// - /// - /// - Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - Task ExecuteDataTableAsync(string cmdText, object parms = null); - Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 在【主库】执行 - /// - /// - /// - /// - Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - Task ExecuteNonQueryAsync(string cmdText, object parms = null); - Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 在【主库】执行 - /// - /// - /// - /// - Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - Task ExecuteScalarAsync(string cmdText, object parms = null); - Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + #region async + /// + /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + /// + /// + /// + /// + /// + Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) + /// + /// + /// + Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, string cmdText, object parms = null); + /// + /// 查询 + /// + /// + /// + Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteArrayAsync(string cmdText, object parms = null); + Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 查询 + /// + /// + /// + Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteDataSetAsync(string cmdText, object parms = null); + Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 查询 + /// + /// + /// + Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteDataTableAsync(string cmdText, object parms = null); + Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 在【主库】执行 + /// + /// + /// + /// + Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteNonQueryAsync(string cmdText, object parms = null); + Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 在【主库】执行 + /// + /// + /// + /// + Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteScalarAsync(string cmdText, object parms = null); + Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) - /// - /// - /// - /// - /// - /// - Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) - /// - /// - /// - /// - /// - Task> QueryAsync(string cmdText, object parms = null); - Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) + /// + /// + /// + /// + /// + /// + Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + /// + Task> QueryAsync(string cmdText, object parms = null); + Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - /// - /// - /// - /// - /// - /// - Task<(List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) - /// - /// - /// - /// - /// - Task<(List, List)> QueryAsync(string cmdText, object parms = null); - Task<(List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + /// + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + /// + /// + /// + /// + /// + /// + Task<(List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) + /// + /// + /// + /// + /// + Task<(List, List)> QueryAsync(string cmdText, object parms = null); + Task<(List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List)> QueryAsync(string cmdText, object parms = null); - Task<(List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List)> QueryAsync(string cmdText, object parms = null); - Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List, List)> QueryAsync(string cmdText, object parms = null); - Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - #endregion - } + Task<(List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List)> QueryAsync(string cmdText, object parms = null); + Task<(List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task<(List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List, List)> QueryAsync(string cmdText, object parms = null); + Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task<(List, List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task<(List, List, List, List, List)> QueryAsync(string cmdText, object parms = null); + Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + #endregion + } } diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index 6fb82996..4b777b2f 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -7,238 +7,261 @@ using System.Diagnostics; using System.Linq.Expressions; using System.Reflection; -namespace FreeSql { - public interface IAop { +namespace FreeSql +{ + public interface IAop + { - /// - /// 监控 ToList 返回的的数据,用于拦截重新装饰 - /// - EventHandler ToList { get; set; } + /// + /// 监控 ToList 返回的的数据,用于拦截重新装饰 + /// + EventHandler ToList { get; set; } - /// - /// 监视 Where,包括 select/update/delete,可控制使上层不被执行。 - /// - EventHandler Where { get; set; } + /// + /// 监视 Where,包括 select/update/delete,可控制使上层不被执行。 + /// + EventHandler Where { get; set; } - /// - /// 可自定义解析表达式 - /// - EventHandler ParseExpression { get; set; } + /// + /// 可自定义解析表达式 + /// + EventHandler ParseExpression { get; set; } - /// - /// 自定义实体的配置,方便和多个 ORM 共同使用 - /// - EventHandler ConfigEntity { get; set; } - /// - /// 自定义实体的属性配置,方便和多个 ORM 共同使用 - /// - EventHandler ConfigEntityProperty { get; set; } + /// + /// 自定义实体的配置,方便和多个 ORM 共同使用 + /// + EventHandler ConfigEntity { get; set; } + /// + /// 自定义实体的属性配置,方便和多个 ORM 共同使用 + /// + EventHandler ConfigEntityProperty { get; set; } - /// - /// 增删查改,执行命令之前触发 - /// - EventHandler CurdBefore { get; set; } - /// - /// 增删查改,执行命令完成后触发 - /// - EventHandler CurdAfter { get; set; } + /// + /// 增删查改,执行命令之前触发 + /// + EventHandler CurdBefore { get; set; } + /// + /// 增删查改,执行命令完成后触发 + /// + EventHandler CurdAfter { get; set; } - /// - /// CodeFirst迁移,执行之前触发 - /// - EventHandler SyncStructureBefore { get; set; } - /// - /// CodeFirst迁移,执行完成触发 - /// - EventHandler SyncStructureAfter { get; set; } - } + /// + /// CodeFirst迁移,执行之前触发 + /// + EventHandler SyncStructureBefore { get; set; } + /// + /// CodeFirst迁移,执行完成触发 + /// + EventHandler SyncStructureAfter { get; set; } + } } -namespace FreeSql.Aop { - public class ToListEventArgs : EventArgs { - public ToListEventArgs(object list) { - this.List = list; - } - /// - /// 可重新装饰的引用数据 - /// - public object List { get; } - } - public class WhereEventArgs : EventArgs { - public WhereEventArgs(params object[] parameters) { - this.Parameters = parameters; - } - public object[] Parameters { get; } - /// - /// 可使上层不被执行这个条件 - /// - public bool IsCancel { get; set; } - } - public class ParseExpressionEventArgs : EventArgs { - public ParseExpressionEventArgs(Expression expression, Func freeParse) { - this.Expression = expression; - this.FreeParse = freeParse; - } +namespace FreeSql.Aop +{ + public class ToListEventArgs : EventArgs + { + public ToListEventArgs(object list) + { + this.List = list; + } + /// + /// 可重新装饰的引用数据 + /// + public object List { get; } + } + public class WhereEventArgs : EventArgs + { + public WhereEventArgs(params object[] parameters) + { + this.Parameters = parameters; + } + public object[] Parameters { get; } + /// + /// 可使上层不被执行这个条件 + /// + public bool IsCancel { get; set; } + } + public class ParseExpressionEventArgs : EventArgs + { + public ParseExpressionEventArgs(Expression expression, Func freeParse) + { + this.Expression = expression; + this.FreeParse = freeParse; + } - /// - /// 内置解析功能,可辅助您进行解析 - /// - public Func FreeParse { get; } + /// + /// 内置解析功能,可辅助您进行解析 + /// + public Func FreeParse { get; } - /// - /// 需要您解析的表达式 - /// - public Expression Expression { get; } - /// - /// 解析后的内容 - /// - public string Result { get; set; } - } - public class ConfigEntityEventArgs : EventArgs { - public ConfigEntityEventArgs(Type entityType) { - this.EntityType = entityType; - this.ModifyResult = new TableAttribute(); - } + /// + /// 需要您解析的表达式 + /// + public Expression Expression { get; } + /// + /// 解析后的内容 + /// + public string Result { get; set; } + } + public class ConfigEntityEventArgs : EventArgs + { + public ConfigEntityEventArgs(Type entityType) + { + this.EntityType = entityType; + this.ModifyResult = new TableAttribute(); + } - /// - /// 实体类型 - /// - public Type EntityType { get; } - /// - /// 实体配置 - /// - public TableAttribute ModifyResult { get; } - } - public class ConfigEntityPropertyEventArgs : EventArgs { - public ConfigEntityPropertyEventArgs(Type entityType, PropertyInfo property) { - this.EntityType = entityType; - this.Property = property; - this.ModifyResult = new ColumnAttribute(); - } + /// + /// 实体类型 + /// + public Type EntityType { get; } + /// + /// 实体配置 + /// + public TableAttribute ModifyResult { get; } + } + public class ConfigEntityPropertyEventArgs : EventArgs + { + public ConfigEntityPropertyEventArgs(Type entityType, PropertyInfo property) + { + this.EntityType = entityType; + this.Property = property; + this.ModifyResult = new ColumnAttribute(); + } - /// - /// 实体类型 - /// - public Type EntityType { get; } - /// - /// 实体的属性 - /// - public PropertyInfo Property { get; } - /// - /// 实体的属性配置 - /// - public ColumnAttribute ModifyResult { get; } - } + /// + /// 实体类型 + /// + public Type EntityType { get; } + /// + /// 实体的属性 + /// + public PropertyInfo Property { get; } + /// + /// 实体的属性配置 + /// + public ColumnAttribute ModifyResult { get; } + } - public class CurdBeforeEventArgs : EventArgs { - public CurdBeforeEventArgs(Type entityType, CurdType curdType, string sql, DbParameter[] dbParms) : - this(Guid.NewGuid(), new Stopwatch(), entityType, curdType, sql, dbParms) { - this.Stopwatch.Start(); - } - protected CurdBeforeEventArgs(Guid identifier, Stopwatch stopwatch, Type entityType, CurdType curdType, string sql, DbParameter[] dbParms) { - this.Identifier = identifier; - this.Stopwatch = stopwatch; - this.EntityType = entityType; - this.CurdType = curdType; - this.Sql = sql; - this.DbParms = dbParms; - } + public class CurdBeforeEventArgs : EventArgs + { + public CurdBeforeEventArgs(Type entityType, CurdType curdType, string sql, DbParameter[] dbParms) : + this(Guid.NewGuid(), new Stopwatch(), entityType, curdType, sql, dbParms) + { + this.Stopwatch.Start(); + } + protected CurdBeforeEventArgs(Guid identifier, Stopwatch stopwatch, Type entityType, CurdType curdType, string sql, DbParameter[] dbParms) + { + this.Identifier = identifier; + this.Stopwatch = stopwatch; + this.EntityType = entityType; + this.CurdType = curdType; + this.Sql = sql; + this.DbParms = dbParms; + } - /// - /// 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - /// - public Guid Identifier { get; protected set; } - protected Stopwatch Stopwatch { get; } - internal Stopwatch StopwatchInternal => Stopwatch; - /// - /// 操作类型 - /// - public CurdType CurdType { get; } - /// - /// 实体类型 - /// - public Type EntityType { get; } - /// - /// 执行的 SQL - /// - public string Sql { get; } - /// - /// 参数化命令 - /// - public DbParameter[] DbParms { get; } - } - public enum CurdType { Select, Delete, Update, Insert } - public class CurdAfterEventArgs : CurdBeforeEventArgs { - public CurdAfterEventArgs(CurdBeforeEventArgs before, Exception exception, object executeResult) : - base(before.Identifier, before.StopwatchInternal, before.EntityType, before.CurdType, before.Sql, before.DbParms) { - this.Exception = exception; - this.ExecuteResult = executeResult; - this.Stopwatch.Stop(); - } + /// + /// 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + /// + public Guid Identifier { get; protected set; } + protected Stopwatch Stopwatch { get; } + internal Stopwatch StopwatchInternal => Stopwatch; + /// + /// 操作类型 + /// + public CurdType CurdType { get; } + /// + /// 实体类型 + /// + public Type EntityType { get; } + /// + /// 执行的 SQL + /// + public string Sql { get; } + /// + /// 参数化命令 + /// + public DbParameter[] DbParms { get; } + } + public enum CurdType { Select, Delete, Update, Insert } + public class CurdAfterEventArgs : CurdBeforeEventArgs + { + public CurdAfterEventArgs(CurdBeforeEventArgs before, Exception exception, object executeResult) : + base(before.Identifier, before.StopwatchInternal, before.EntityType, before.CurdType, before.Sql, before.DbParms) + { + this.Exception = exception; + this.ExecuteResult = executeResult; + this.Stopwatch.Stop(); + } - /// - /// 发生的错误 - /// - public Exception Exception { get; } - /// - /// 执行SQL命令,返回的结果 - /// - public object ExecuteResult { get; set; } - /// - /// 耗时(单位:Ticks) - /// - public long ElapsedTicks => this.Stopwatch.ElapsedTicks; - /// - /// 耗时(单位:毫秒) - /// - public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; - } + /// + /// 发生的错误 + /// + public Exception Exception { get; } + /// + /// 执行SQL命令,返回的结果 + /// + public object ExecuteResult { get; set; } + /// + /// 耗时(单位:Ticks) + /// + public long ElapsedTicks => this.Stopwatch.ElapsedTicks; + /// + /// 耗时(单位:毫秒) + /// + public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; + } - public class SyncStructureBeforeEventArgs : EventArgs { - public SyncStructureBeforeEventArgs(Type[] entityTypes) : - this(Guid.NewGuid(), new Stopwatch(), entityTypes) { - this.Stopwatch.Start(); - } - protected SyncStructureBeforeEventArgs(Guid identifier, Stopwatch stopwatch, Type[] entityTypes) { - this.Identifier = identifier; - this.Stopwatch = stopwatch; - this.EntityTypes = entityTypes; - } + public class SyncStructureBeforeEventArgs : EventArgs + { + public SyncStructureBeforeEventArgs(Type[] entityTypes) : + this(Guid.NewGuid(), new Stopwatch(), entityTypes) + { + this.Stopwatch.Start(); + } + protected SyncStructureBeforeEventArgs(Guid identifier, Stopwatch stopwatch, Type[] entityTypes) + { + this.Identifier = identifier; + this.Stopwatch = stopwatch; + this.EntityTypes = entityTypes; + } - /// - /// 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - /// - public Guid Identifier { get; protected set; } - protected Stopwatch Stopwatch { get; } - internal Stopwatch StopwatchInternal => Stopwatch; - /// - /// 实体类型 - /// - public Type[] EntityTypes { get; } - } - public class SyncStructureAfterEventArgs : SyncStructureBeforeEventArgs { - public SyncStructureAfterEventArgs(SyncStructureBeforeEventArgs before, string sql, Exception exception) : - base(before.Identifier, before.StopwatchInternal, before.EntityTypes) { - this.Sql = sql; - this.Exception = exception; - this.Stopwatch.Stop(); - } + /// + /// 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + /// + public Guid Identifier { get; protected set; } + protected Stopwatch Stopwatch { get; } + internal Stopwatch StopwatchInternal => Stopwatch; + /// + /// 实体类型 + /// + public Type[] EntityTypes { get; } + } + public class SyncStructureAfterEventArgs : SyncStructureBeforeEventArgs + { + public SyncStructureAfterEventArgs(SyncStructureBeforeEventArgs before, string sql, Exception exception) : + base(before.Identifier, before.StopwatchInternal, before.EntityTypes) + { + this.Sql = sql; + this.Exception = exception; + this.Stopwatch.Stop(); + } - /// - /// 执行的 SQL - /// - public string Sql { get; } - /// - /// 发生的错误 - /// - public Exception Exception { get; } - /// - /// 耗时(单位:Ticks) - /// - public long ElapsedTicks => this.Stopwatch.ElapsedTicks; - /// - /// 耗时(单位:毫秒) - /// - public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; - } + /// + /// 执行的 SQL + /// + public string Sql { get; } + /// + /// 发生的错误 + /// + public Exception Exception { get; } + /// + /// 耗时(单位:Ticks) + /// + public long ElapsedTicks => this.Stopwatch.ElapsedTicks; + /// + /// 耗时(单位:毫秒) + /// + public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; + } } \ No newline at end of file diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 5e0c06dd..de49488a 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -2,91 +2,93 @@ using FreeSql.Internal.Model; using System; -namespace FreeSql { - public interface ICodeFirst { +namespace FreeSql +{ + public interface ICodeFirst + { - /// - /// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - /// - bool IsAutoSyncStructure { get; set; } + /// + /// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + /// + bool IsAutoSyncStructure { get; set; } - /// - /// 转小写同步结构 - /// - bool IsSyncStructureToLower { get; set; } - /// - /// 转大写同步结构 - /// - bool IsSyncStructureToUpper { get; set; } - /// - /// 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 - /// - bool IsConfigEntityFromDbFirst { get; set; } - /// - /// 不使用命令参数化执行,针对 Insert/Update - /// - bool IsNoneCommandParameter { get; set; } - /// - /// 延时加载导航属性对象,导航属性需要声明 virtual - /// - bool IsLazyLoading { get; set; } + /// + /// 转小写同步结构 + /// + bool IsSyncStructureToLower { get; set; } + /// + /// 转大写同步结构 + /// + bool IsSyncStructureToUpper { get; set; } + /// + /// 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 + /// + bool IsConfigEntityFromDbFirst { get; set; } + /// + /// 不使用命令参数化执行,针对 Insert/Update + /// + bool IsNoneCommandParameter { get; set; } + /// + /// 延时加载导航属性对象,导航属性需要声明 virtual + /// + bool IsLazyLoading { get; set; } - /// - /// 将实体类型与数据库对比,返回DDL语句 - /// - /// - /// - string GetComparisonDDLStatements(); - /// - /// 将实体类型集合与数据库对比,返回DDL语句 - /// - /// - /// - string GetComparisonDDLStatements(params Type[] entityTypes); - /// - /// 同步实体类型到数据库 - /// - /// - /// - bool SyncStructure(); - /// - /// 同步实体类型集合到数据库 - /// - /// - /// - bool SyncStructure(params Type[] entityTypes); + /// + /// 将实体类型与数据库对比,返回DDL语句 + /// + /// + /// + string GetComparisonDDLStatements(); + /// + /// 将实体类型集合与数据库对比,返回DDL语句 + /// + /// + /// + string GetComparisonDDLStatements(params Type[] entityTypes); + /// + /// 同步实体类型到数据库 + /// + /// + /// + bool SyncStructure(); + /// + /// 同步实体类型集合到数据库 + /// + /// + /// + bool SyncStructure(params Type[] entityTypes); - /// - /// 根据 System.Type 获取数据库信息 - /// - /// - /// - (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); - /// - /// 在外部配置实体的特性 - /// - /// - /// - /// - ICodeFirst ConfigEntity(Action> entity); - /// - /// 在外部配置实体的特性 - /// - /// - /// - /// - ICodeFirst ConfigEntity(Type type, Action entity); - /// - /// 获取在外部配置实体的特性 - /// - /// - /// 未使用ConfigEntity配置时,返回null - TableAttribute GetConfigEntity(Type type); - /// - /// 获取实体类核心配置 - /// - /// - /// - TableInfo GetTableByEntity(Type type); - } + /// + /// 根据 System.Type 获取数据库信息 + /// + /// + /// + (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); + /// + /// 在外部配置实体的特性 + /// + /// + /// + /// + ICodeFirst ConfigEntity(Action> entity); + /// + /// 在外部配置实体的特性 + /// + /// + /// + /// + ICodeFirst ConfigEntity(Type type, Action entity); + /// + /// 获取在外部配置实体的特性 + /// + /// + /// 未使用ConfigEntity配置时,返回null + TableAttribute GetConfigEntity(Type type); + /// + /// 获取实体类核心配置 + /// + /// + /// + TableInfo GetTableByEntity(Type type); + } } diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index 5b489424..bf5c9260 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -4,104 +4,105 @@ using System.Collections.Generic; public interface IFreeSql : IFreeSql { } -public interface IFreeSql : IDisposable { - /// - /// 插入数据 - /// - /// - /// - IInsert Insert() where T1 : class; - /// - /// 插入数据,传入实体 - /// - /// - /// - /// - IInsert Insert(T1 source) where T1 : class; - /// - /// 插入数据,传入实体数组 - /// - /// - /// - /// - IInsert Insert(T1[] source) where T1 : class; - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - IInsert Insert(IEnumerable source) where T1 : class; +public interface IFreeSql : IDisposable +{ + /// + /// 插入数据 + /// + /// + /// + IInsert Insert() where T1 : class; + /// + /// 插入数据,传入实体 + /// + /// + /// + /// + IInsert Insert(T1 source) where T1 : class; + /// + /// 插入数据,传入实体数组 + /// + /// + /// + /// + IInsert Insert(T1[] source) where T1 : class; + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + IInsert Insert(IEnumerable source) where T1 : class; - /// - /// 修改数据 - /// - /// - /// - IUpdate Update() where T1 : class; - /// - /// 修改数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - IUpdate Update(object dywhere) where T1 : class; + /// + /// 修改数据 + /// + /// + /// + IUpdate Update() where T1 : class; + /// + /// 修改数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + IUpdate Update(object dywhere) where T1 : class; - /// - /// 查询数据 - /// - /// - /// - ISelect Select() where T1 : class; - /// - /// 查询数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - ISelect Select(object dywhere) where T1 : class; + /// + /// 查询数据 + /// + /// + /// + ISelect Select() where T1 : class; + /// + /// 查询数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + ISelect Select(object dywhere) where T1 : class; - /// - /// 删除数据 - /// - /// - /// - IDelete Delete() where T1 : class; - /// - /// 删除数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - IDelete Delete(object dywhere) where T1 : class; + /// + /// 删除数据 + /// + /// + /// + IDelete Delete() where T1 : class; + /// + /// 删除数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + IDelete Delete(object dywhere) where T1 : class; - /// - /// 开启事务(不支持异步),60秒未执行完将自动提交 - /// - /// 事务体 () => {} - void Transaction(Action handler); - /// - /// 开启事务(不支持异步) - /// - /// 事务体 () => {} - /// 超时,未执行完将自动提交 - void Transaction(Action handler, TimeSpan timeout); + /// + /// 开启事务(不支持异步),60秒未执行完将自动提交 + /// + /// 事务体 () => {} + void Transaction(Action handler); + /// + /// 开启事务(不支持异步) + /// + /// 事务体 () => {} + /// 超时,未执行完将自动提交 + void Transaction(Action handler, TimeSpan timeout); - /// - /// 数据库访问对象 - /// - IAdo Ado { get; } - /// - /// 所有拦截方法都在这里 - /// - IAop Aop { get; } + /// + /// 数据库访问对象 + /// + IAdo Ado { get; } + /// + /// 所有拦截方法都在这里 + /// + IAop Aop { get; } - /// - /// CodeFirst 模式开发相关方法 - /// - ICodeFirst CodeFirst { get; } - /// - /// DbFirst 模式开发相关方法 - /// - IDbFirst DbFirst { get; } + /// + /// CodeFirst 模式开发相关方法 + /// + ICodeFirst CodeFirst { get; } + /// + /// DbFirst 模式开发相关方法 + /// + IDbFirst DbFirst { get; } } \ No newline at end of file diff --git a/FreeSql/Interface/iDbFirst.cs b/FreeSql/Interface/iDbFirst.cs index 2aa495a8..1c444593 100644 --- a/FreeSql/Interface/iDbFirst.cs +++ b/FreeSql/Interface/iDbFirst.cs @@ -2,76 +2,78 @@ using System; using System.Collections.Generic; -namespace FreeSql { - public interface IDbFirst { +namespace FreeSql +{ + public interface IDbFirst + { - /// - /// 获取所有数据库 - /// - /// - List GetDatabases(); - /// - /// 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 - /// - /// - /// - List GetTablesByDatabase(params string[] database); + /// + /// 获取所有数据库 + /// + /// + List GetDatabases(); + /// + /// 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 + /// + /// + /// + List GetTablesByDatabase(params string[] database); - /// - /// 获取数据库枚举类型int值 - /// - /// - /// - int GetDbType(DbColumnInfo column); + /// + /// 获取数据库枚举类型int值 + /// + /// + /// + int GetDbType(DbColumnInfo column); - /// - /// 获取c#转换,(int)、(long) - /// - /// - /// - string GetCsConvert(DbColumnInfo column); - /// - /// 获取c#值 - /// - /// - /// - string GetCsTypeValue(DbColumnInfo column); - /// - /// 获取c#类型,int、long - /// - /// - /// - string GetCsType(DbColumnInfo column); - /// - /// 获取c#类型对象 - /// - /// - /// - Type GetCsTypeInfo(DbColumnInfo column); - /// - /// 获取ado.net读取方法, GetBoolean、GetInt64 - /// - /// - /// - string GetDataReaderMethod(DbColumnInfo column); - /// - /// 序列化 - /// - /// - /// - string GetCsStringify(DbColumnInfo column); - /// - /// 反序列化 - /// - /// - /// - string GetCsParse(DbColumnInfo column); + /// + /// 获取c#转换,(int)、(long) + /// + /// + /// + string GetCsConvert(DbColumnInfo column); + /// + /// 获取c#值 + /// + /// + /// + string GetCsTypeValue(DbColumnInfo column); + /// + /// 获取c#类型,int、long + /// + /// + /// + string GetCsType(DbColumnInfo column); + /// + /// 获取c#类型对象 + /// + /// + /// + Type GetCsTypeInfo(DbColumnInfo column); + /// + /// 获取ado.net读取方法, GetBoolean、GetInt64 + /// + /// + /// + string GetDataReaderMethod(DbColumnInfo column); + /// + /// 序列化 + /// + /// + /// + string GetCsStringify(DbColumnInfo column); + /// + /// 反序列化 + /// + /// + /// + string GetCsParse(DbColumnInfo column); - /// - /// 获取数据库枚举类型,适用 PostgreSQL - /// - /// - /// - List GetEnumsByDatabase(params string[] database); - } + /// + /// 获取数据库枚举类型,适用 PostgreSQL + /// + /// + /// + List GetEnumsByDatabase(params string[] database); + } } diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 740bab69..6f89f5e1 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -9,962 +9,1113 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; -namespace FreeSql.Internal { - public abstract class CommonExpression { +namespace FreeSql.Internal +{ + public abstract class CommonExpression + { - public CommonUtils _common; - public CommonProvider.AdoProvider _ado => _adoPriv ?? (_adoPriv = _common._orm.Ado as CommonProvider.AdoProvider); - CommonProvider.AdoProvider _adoPriv; - public CommonExpression(CommonUtils common) { - _common = common; - } + public CommonUtils _common; + public CommonProvider.AdoProvider _ado => _adoPriv ?? (_adoPriv = _common._orm.Ado as CommonProvider.AdoProvider); + CommonProvider.AdoProvider _adoPriv; + public CommonExpression(CommonUtils common) + { + _common = common; + } - static ConcurrentDictionary _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary(); - public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString) { - Func getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }; - switch (exp.NodeType) { - case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); - case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString); - case ExpressionType.Negate: - case ExpressionType.NegateChecked: - parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; - field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - return false; - case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); - case ExpressionType.Constant: - var constExp = exp as ConstantExpression; - //处理自定义SQL语句,如: ToList(new { - // ccc = "now()", - // partby = "sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)" - //}),有缺点即 ccc partby 接受类型都是 string,可配合 Convert.ToXxx 类型转换,请看下面的兼容 - parent.DbField = constExp.Type.FullName == "System.String" ? (constExp.Value?.ToString() ?? "NULL") : _common.FormatSql("{0}", constExp?.Value); - field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - return false; - case ExpressionType.Call: - var callExp = exp as MethodCallExpression; - //处理自定义SQL语句,如: ToList(new { - // ccc = Convert.ToDateTime("now()"), - // partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") - //}) - if (callExp.Method?.DeclaringType.FullName == "System.Convert" && - callExp.Method.Name.StartsWith("To") && - callExp.Arguments[0].NodeType == ExpressionType.Constant && - callExp.Arguments[0].Type.FullName == "System.String") - parent.DbField = (callExp.Arguments[0] as ConstantExpression).Value?.ToString() ?? "NULL"; - else - parent.DbField = ExpressionLambdaToSql(exp, getTSC()); - field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - return false; - case ExpressionType.Parameter: - case ExpressionType.MemberAccess: - if (_common.GetTableByEntity(exp.Type) != null) { //加载表所有字段 - var map = new List(); - ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString); - var tb = parent.Table = map.First().Table.Table; - parent.Consturctor = tb.Type.GetConstructor(new Type[0]); - parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - for (var idx = 0; idx < map.Count; idx++) { - var child = new ReadAnonymousTypeInfo { - Property = tb.Properties.TryGetValue(map[idx].Column.CsName, out var tryprop) ? tryprop : tb.Type.GetProperty(map[idx].Column.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), - CsName = map[idx].Column.CsName, DbField = $"{map[idx].Table.Alias}.{_common.QuoteSqlName(map[idx].Column.Attribute.Name)}", - CsType = map[idx].Column.CsType, - MapType = map[idx].Column.Attribute.MapType - }; - field.Append(", ").Append(_common.QuoteReadColumn(child.MapType, child.DbField)); - if (index >= 0) field.Append(" as").Append(++index); - parent.Childs.Add(child); - } - } else { - parent.CsType = exp.Type; - parent.DbField = ExpressionLambdaToSql(exp, getTSC()); - field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - parent.MapType = SearchColumnByField(_tables, null, parent.DbField)?.Attribute.MapType ?? exp.Type; - return false; - } - return false; - case ExpressionType.MemberInit: - var initExp = exp as MemberInitExpression; - parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0]; - parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - if (initExp.Bindings?.Count > 0) { - //指定 dto映射 - for (var a = 0; a < initExp.Bindings.Count; a++) { - var initAssignExp = (initExp.Bindings[a] as MemberAssignment); - if (initAssignExp == null) continue; - var child = new ReadAnonymousTypeInfo { - Property = initExp.Type.GetProperty(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), - CsName = initExp.Bindings[a].Member.Name, - CsType = initAssignExp.Expression.Type, - MapType = initAssignExp.Expression.Type - }; - parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString); - } - } else { - //dto 映射 - var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(initExp.NewExpression.Type, dtoType => dtoType.GetProperties()); - foreach (var dtoProp in dtoProps) { - foreach (var dtTb in _tables) { - if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) { - var child = new ReadAnonymousTypeInfo { - Property = dtoProp, - CsName = dtoProp.Name, - CsType = dtoProp.PropertyType, - MapType = trydtocol.Attribute.MapType - }; - parent.Childs.Add(child); - if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString); - else { - child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; - field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(" as").Append(++index); - } - break; - } - } - } - if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); - } - return true; - case ExpressionType.New: - var newExp = exp as NewExpression; - parent.Consturctor = newExp.Type.GetConstructors()[0]; - parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments; - if (newExp.Members?.Count > 0) { - for (var a = 0; a < newExp.Members.Count; a++) { - var child = new ReadAnonymousTypeInfo { - Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), - CsName = newExp.Members[a].Name, - CsType = newExp.Arguments[a].Type, - MapType = newExp.Arguments[a].Type - }; - parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString); - } - } else { - //dto 映射 - parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(newExp.Type, dtoType => dtoType.GetProperties()); - foreach (var dtoProp in dtoProps) { - foreach(var dtTb in _tables) { - if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol)) { - var child = new ReadAnonymousTypeInfo { - Property = dtoProp, - CsName = dtoProp.Name, - CsType = dtoProp.PropertyType, - MapType = trydtocol.Attribute.MapType - }; - parent.Childs.Add(child); - if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString); - else { - child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; - field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(" as").Append(++index); - } - break; - } - } - } - if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名相同"); - } - return true; - } - parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})"; - field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - return false; - } - public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead) { - if (parent.Childs.Any() == false) { - if (notRead) { - ++index; - return Utils.GetDataReaderValue(parent.CsType, null); - } - if (parent.CsType == parent.MapType) - return Utils.GetDataReaderValue(parent.CsType, dr.GetValue(++index)); - return Utils.GetDataReaderValue(parent.CsType, Utils.GetDataReaderValue(parent.MapType, dr.GetValue(++index))); - } - switch (parent.ConsturctorType) { - case ReadAnonymousTypeInfoConsturctorType.Arguments: - var args = new object[parent.Childs.Count]; - for (var a = 0; a < parent.Childs.Count; a++) { - var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead); - if (notRead == false) - args[a] = objval; - } - return parent.Consturctor.Invoke(args); - case ReadAnonymousTypeInfoConsturctorType.Properties: - var ret = parent.Consturctor.Invoke(null); - var isnull = notRead; - for (var b = 0; b < parent.Childs.Count; b++) { - var prop = parent.Childs[b].Property; - var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead); - if (isnull == false && objval == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) - isnull = true; - if (isnull == false) - prop.SetValue(ret, objval, null); - } - return isnull ? null : ret; - } - return null; - } + static ConcurrentDictionary _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary(); + public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString) + { + Func getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }; + switch (exp.NodeType) + { + case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); + case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString); + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; + field.Append(", ").Append(parent.DbField); + if (index >= 0) field.Append(" as").Append(++index); + return false; + case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); + case ExpressionType.Constant: + var constExp = exp as ConstantExpression; + //处理自定义SQL语句,如: ToList(new { + // ccc = "now()", + // partby = "sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)" + //}),有缺点即 ccc partby 接受类型都是 string,可配合 Convert.ToXxx 类型转换,请看下面的兼容 + parent.DbField = constExp.Type.FullName == "System.String" ? (constExp.Value?.ToString() ?? "NULL") : _common.FormatSql("{0}", constExp?.Value); + field.Append(", ").Append(parent.DbField); + if (index >= 0) field.Append(" as").Append(++index); + return false; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + //处理自定义SQL语句,如: ToList(new { + // ccc = Convert.ToDateTime("now()"), + // partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + //}) + if (callExp.Method?.DeclaringType.FullName == "System.Convert" && + callExp.Method.Name.StartsWith("To") && + callExp.Arguments[0].NodeType == ExpressionType.Constant && + callExp.Arguments[0].Type.FullName == "System.String") + parent.DbField = (callExp.Arguments[0] as ConstantExpression).Value?.ToString() ?? "NULL"; + else + parent.DbField = ExpressionLambdaToSql(exp, getTSC()); + field.Append(", ").Append(parent.DbField); + if (index >= 0) field.Append(" as").Append(++index); + return false; + case ExpressionType.Parameter: + case ExpressionType.MemberAccess: + if (_common.GetTableByEntity(exp.Type) != null) + { //加载表所有字段 + var map = new List(); + ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString); + var tb = parent.Table = map.First().Table.Table; + parent.Consturctor = tb.Type.GetConstructor(new Type[0]); + parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + for (var idx = 0; idx < map.Count; idx++) + { + var child = new ReadAnonymousTypeInfo + { + Property = tb.Properties.TryGetValue(map[idx].Column.CsName, out var tryprop) ? tryprop : tb.Type.GetProperty(map[idx].Column.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), + CsName = map[idx].Column.CsName, + DbField = $"{map[idx].Table.Alias}.{_common.QuoteSqlName(map[idx].Column.Attribute.Name)}", + CsType = map[idx].Column.CsType, + MapType = map[idx].Column.Attribute.MapType + }; + field.Append(", ").Append(_common.QuoteReadColumn(child.MapType, child.DbField)); + if (index >= 0) field.Append(" as").Append(++index); + parent.Childs.Add(child); + } + } + else + { + parent.CsType = exp.Type; + parent.DbField = ExpressionLambdaToSql(exp, getTSC()); + field.Append(", ").Append(parent.DbField); + if (index >= 0) field.Append(" as").Append(++index); + parent.MapType = SearchColumnByField(_tables, null, parent.DbField)?.Attribute.MapType ?? exp.Type; + return false; + } + return false; + case ExpressionType.MemberInit: + var initExp = exp as MemberInitExpression; + parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0]; + parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + if (initExp.Bindings?.Count > 0) + { + //指定 dto映射 + for (var a = 0; a < initExp.Bindings.Count; a++) + { + var initAssignExp = (initExp.Bindings[a] as MemberAssignment); + if (initAssignExp == null) continue; + var child = new ReadAnonymousTypeInfo + { + Property = initExp.Type.GetProperty(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), + CsName = initExp.Bindings[a].Member.Name, + CsType = initAssignExp.Expression.Type, + MapType = initAssignExp.Expression.Type + }; + parent.Childs.Add(child); + ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString); + } + } + else + { + //dto 映射 + var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(initExp.NewExpression.Type, dtoType => dtoType.GetProperties()); + foreach (var dtoProp in dtoProps) + { + foreach (var dtTb in _tables) + { + if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) + { + var child = new ReadAnonymousTypeInfo + { + Property = dtoProp, + CsName = dtoProp.Name, + CsType = dtoProp.PropertyType, + MapType = trydtocol.Attribute.MapType + }; + parent.Childs.Add(child); + if (dtTb.Parameter != null) + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString); + else + { + child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; + field.Append(", ").Append(child.DbField); + if (index >= 0) field.Append(" as").Append(++index); + } + break; + } + } + } + if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); + } + return true; + case ExpressionType.New: + var newExp = exp as NewExpression; + parent.Consturctor = newExp.Type.GetConstructors()[0]; + parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments; + if (newExp.Members?.Count > 0) + { + for (var a = 0; a < newExp.Members.Count; a++) + { + var child = new ReadAnonymousTypeInfo + { + Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), + CsName = newExp.Members[a].Name, + CsType = newExp.Arguments[a].Type, + MapType = newExp.Arguments[a].Type + }; + parent.Childs.Add(child); + ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString); + } + } + else + { + //dto 映射 + parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(newExp.Type, dtoType => dtoType.GetProperties()); + foreach (var dtoProp in dtoProps) + { + foreach (var dtTb in _tables) + { + if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol)) + { + var child = new ReadAnonymousTypeInfo + { + Property = dtoProp, + CsName = dtoProp.Name, + CsType = dtoProp.PropertyType, + MapType = trydtocol.Attribute.MapType + }; + parent.Childs.Add(child); + if (dtTb.Parameter != null) + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString); + else + { + child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; + field.Append(", ").Append(child.DbField); + if (index >= 0) field.Append(" as").Append(++index); + } + break; + } + } + } + if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名相同"); + } + return true; + } + parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})"; + field.Append(", ").Append(parent.DbField); + if (index >= 0) field.Append(" as").Append(++index); + return false; + } + public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead) + { + if (parent.Childs.Any() == false) + { + if (notRead) + { + ++index; + return Utils.GetDataReaderValue(parent.CsType, null); + } + if (parent.CsType == parent.MapType) + return Utils.GetDataReaderValue(parent.CsType, dr.GetValue(++index)); + return Utils.GetDataReaderValue(parent.CsType, Utils.GetDataReaderValue(parent.MapType, dr.GetValue(++index))); + } + switch (parent.ConsturctorType) + { + case ReadAnonymousTypeInfoConsturctorType.Arguments: + var args = new object[parent.Childs.Count]; + for (var a = 0; a < parent.Childs.Count; a++) + { + var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead); + if (notRead == false) + args[a] = objval; + } + return parent.Consturctor.Invoke(args); + case ReadAnonymousTypeInfoConsturctorType.Properties: + var ret = parent.Consturctor.Invoke(null); + var isnull = notRead; + for (var b = 0; b < parent.Childs.Count; b++) + { + var prop = parent.Childs[b].Property; + var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead); + if (isnull == false && objval == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) + isnull = true; + if (isnull == false) + prop.SetValue(ret, objval, null); + } + return isnull ? null : ret; + } + return null; + } - public ColumnInfo SearchColumnByField(List _tables, TableInfo currentTable, string field) { - if (_tables != null) { - var testCol = _common.TrimQuoteSqlName(field).Split(new[] { '.' }, 2); - if (testCol.Length == 2) { - var testTb = _tables.Where(a => a.Alias == testCol[0]).ToArray(); - if (testTb.Length == 1 && testTb[0].Table.Columns.TryGetValue(testCol[1], out var trytstcol)) - return trytstcol; - } - } - if (currentTable != null) { - var testCol = _common.TrimQuoteSqlName(field); - if (currentTable.Columns.TryGetValue(testCol, out var trytstcol)) - return trytstcol; - } - return null; - } + public ColumnInfo SearchColumnByField(List _tables, TableInfo currentTable, string field) + { + if (_tables != null) + { + var testCol = _common.TrimQuoteSqlName(field).Split(new[] { '.' }, 2); + if (testCol.Length == 2) + { + var testTb = _tables.Where(a => a.Alias == testCol[0]).ToArray(); + if (testTb.Length == 1 && testTb[0].Table.Columns.TryGetValue(testCol[1], out var trytstcol)) + return trytstcol; + } + } + if (currentTable != null) + { + var testCol = _common.TrimQuoteSqlName(field); + if (currentTable.Columns.TryGetValue(testCol, out var trytstcol)) + return trytstcol; + } + return null; + } - public string ExpressionSelectColumn_MemberAccess(List _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, Func getSelectGroupingMapString) { - return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns }); - } + public string ExpressionSelectColumn_MemberAccess(List _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, Func getSelectGroupingMapString) + { + return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns }); + } - public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List _tables, Expression exp, bool isQuoteName, Func getSelectGroupingMapString) { - switch (exp?.NodeType) { - case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); - case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, getSelectGroupingMapString); - case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); - case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString) }; - case ExpressionType.MemberAccess: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString) }; - case ExpressionType.New: - var newExp = exp as NewExpression; - if (newExp == null) break; - var newExpMembers = new string[newExp.Members.Count]; - for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, getSelectGroupingMapString); - return newExpMembers; - case ExpressionType.NewArrayInit: - var newArr = exp as NewArrayExpression; - if (newArr == null) break; - var newArrMembers = new List(); - foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, getSelectGroupingMapString)); - return newArrMembers.ToArray(); - } - return new string[0]; - } + public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List _tables, Expression exp, bool isQuoteName, Func getSelectGroupingMapString) + { + switch (exp?.NodeType) + { + case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); + case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, getSelectGroupingMapString); + case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); + case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString) }; + case ExpressionType.MemberAccess: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString) }; + case ExpressionType.New: + var newExp = exp as NewExpression; + if (newExp == null) break; + var newExpMembers = new string[newExp.Members.Count]; + for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, getSelectGroupingMapString); + return newExpMembers; + case ExpressionType.NewArrayInit: + var newArr = exp as NewArrayExpression; + if (newArr == null) break; + var newArrMembers = new List(); + foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, getSelectGroupingMapString)); + return newArrMembers.ToArray(); + } + return new string[0]; + } - static readonly Dictionary dicExpressionOperator = new Dictionary() { - { ExpressionType.OrElse, "OR" }, - { ExpressionType.Or, "|" }, - { ExpressionType.AndAlso, "AND" }, - { ExpressionType.And, "&" }, - { ExpressionType.GreaterThan, ">" }, - { ExpressionType.GreaterThanOrEqual, ">=" }, - { ExpressionType.LessThan, "<" }, - { ExpressionType.LessThanOrEqual, "<=" }, - { ExpressionType.NotEqual, "<>" }, - { ExpressionType.Add, "+" }, - { ExpressionType.Subtract, "-" }, - { ExpressionType.Multiply, "*" }, - { ExpressionType.Divide, "/" }, - { ExpressionType.Modulo, "%" }, - { ExpressionType.Equal, "=" }, - }; - public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table }); - var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); - if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - return $"{sql} = {formatSql(true, null)}"; - if (isBool) { - switch (sql) { - case "1": - case "'t'": return "1=1"; - case "0": - case "'f'": return "1=2"; - default: return sql; - } - } - return sql; - } + static readonly Dictionary dicExpressionOperator = new Dictionary() { + { ExpressionType.OrElse, "OR" }, + { ExpressionType.Or, "|" }, + { ExpressionType.AndAlso, "AND" }, + { ExpressionType.And, "&" }, + { ExpressionType.GreaterThan, ">" }, + { ExpressionType.GreaterThanOrEqual, ">=" }, + { ExpressionType.LessThan, "<" }, + { ExpressionType.LessThanOrEqual, "<=" }, + { ExpressionType.NotEqual, "<>" }, + { ExpressionType.Add, "+" }, + { ExpressionType.Subtract, "-" }, + { ExpressionType.Multiply, "*" }, + { ExpressionType.Divide, "/" }, + { ExpressionType.Modulo, "%" }, + { ExpressionType.Equal, "=" }, + }; + public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString) + { + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table }); + var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); + if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) + return $"{sql} = {formatSql(true, null)}"; + if (isBool) + { + switch (sql) + { + case "1": + case "'t'": return "1=1"; + case "0": + case "'f'": return "1=2"; + default: return sql; + } + } + return sql; + } - public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); - var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); - if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - return $"{sql} = {formatSql(true, null)}"; - if (isBool) { - switch (sql) { - case "1": - case "'t'": return "1=1"; - case "0": - case "'f'": return "1=2"; - default: return sql; - } - } - return sql; - } - public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString) { - var tbidx = _tables.Count; - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); - var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); - if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - sql = $"{sql} = {formatSql(true, null)}"; - if (isBool) { - switch (sql) { - case "1": - case "'t'": sql = "1=1"; break; - case "0": - case "'f'": sql = "1=2"; break; - default: break; - } - } - if (_tables.Count > tbidx) { - _tables[tbidx].Type = tbtype; - _tables[tbidx].On = sql; - for (var a = tbidx + 1; a < _tables.Count; a++) - _tables[a].Type = SelectTableInfoType.From; - } else { - var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On)).LastOrDefault(); - if (find != null) { - find.Type = tbtype; - find.On = sql; - } - } - } - static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectMethodInfo = new ConcurrentDictionary(); - static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectWhereMethodInfo = new ConcurrentDictionary(); - static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo = new ConcurrentDictionary(); - static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectAnyMethodInfo = new ConcurrentDictionary(); - internal static ConcurrentDictionary _dicNullableValueProperty = new ConcurrentDictionary(); - static ConcurrentDictionary _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary(); - static MethodInfo MethodDateTimeSubtractDateTime = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(DateTime) }); - static MethodInfo MethodDateTimeSubtractTimeSpan = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(TimeSpan) }); + public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString) + { + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); + var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); + if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) + return $"{sql} = {formatSql(true, null)}"; + if (isBool) + { + switch (sql) + { + case "1": + case "'t'": return "1=1"; + case "0": + case "'f'": return "1=2"; + default: return sql; + } + } + return sql; + } + public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString) + { + var tbidx = _tables.Count; + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); + var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); + if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) + sql = $"{sql} = {formatSql(true, null)}"; + if (isBool) + { + switch (sql) + { + case "1": + case "'t'": sql = "1=1"; break; + case "0": + case "'f'": sql = "1=2"; break; + default: break; + } + } + if (_tables.Count > tbidx) + { + _tables[tbidx].Type = tbtype; + _tables[tbidx].On = sql; + for (var a = tbidx + 1; a < _tables.Count; a++) + _tables[a].Type = SelectTableInfoType.From; + } + else + { + var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On)).LastOrDefault(); + if (find != null) + { + find.Type = tbtype; + find.On = sql; + } + } + } + static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectMethodInfo = new ConcurrentDictionary(); + static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectWhereMethodInfo = new ConcurrentDictionary(); + static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo = new ConcurrentDictionary(); + static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectAnyMethodInfo = new ConcurrentDictionary(); + internal static ConcurrentDictionary _dicNullableValueProperty = new ConcurrentDictionary(); + static ConcurrentDictionary _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary(); + static MethodInfo MethodDateTimeSubtractDateTime = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(DateTime) }); + static MethodInfo MethodDateTimeSubtractTimeSpan = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(TimeSpan) }); - public string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) { - switch (oper) { - case "OR": - case "|": - case "&": - case "+": - case "-": - if (oper == "+" && (leftExp.Type == typeof(string) || rightExp.Type == typeof(string))) - return _common.StringConcat(new[] { ExpressionLambdaToSql(leftExp, tsc), ExpressionLambdaToSql(rightExp, tsc) }, new[] { leftExp.Type, rightExp.Type }); - if (oper == "-" && leftExp.Type.NullableTypeOrThis() == typeof(DateTime)) { - if (rightExp.Type.NullableTypeOrThis() == typeof(DateTime)) - return ExpressionLambdaToSql(Expression.Call(leftExp, MethodDateTimeSubtractDateTime, rightExp), tsc); - if (rightExp.Type.NullableTypeOrThis() == typeof(TimeSpan)) - return ExpressionLambdaToSql(Expression.Call(leftExp, MethodDateTimeSubtractTimeSpan, rightExp), tsc); - } - return $"({ExpressionLambdaToSql(leftExp, tsc)} {oper} {ExpressionLambdaToSql(rightExp, tsc)})"; - } + public string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) + { + switch (oper) + { + case "OR": + case "|": + case "&": + case "+": + case "-": + if (oper == "+" && (leftExp.Type == typeof(string) || rightExp.Type == typeof(string))) + return _common.StringConcat(new[] { ExpressionLambdaToSql(leftExp, tsc), ExpressionLambdaToSql(rightExp, tsc) }, new[] { leftExp.Type, rightExp.Type }); + if (oper == "-" && leftExp.Type.NullableTypeOrThis() == typeof(DateTime)) + { + if (rightExp.Type.NullableTypeOrThis() == typeof(DateTime)) + return ExpressionLambdaToSql(Expression.Call(leftExp, MethodDateTimeSubtractDateTime, rightExp), tsc); + if (rightExp.Type.NullableTypeOrThis() == typeof(TimeSpan)) + return ExpressionLambdaToSql(Expression.Call(leftExp, MethodDateTimeSubtractTimeSpan, rightExp), tsc); + } + return $"({ExpressionLambdaToSql(leftExp, tsc)} {oper} {ExpressionLambdaToSql(rightExp, tsc)})"; + } - var left = ExpressionLambdaToSql(leftExp, tsc); - var leftMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, left); - var isLeftMapType = leftMapColumn != null && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type); - ColumnInfo rightMapColumn = null; - var isRightMapType = false; - if (isLeftMapType) tsc.mapType = leftMapColumn.Attribute.MapType; + var left = ExpressionLambdaToSql(leftExp, tsc); + var leftMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, left); + var isLeftMapType = leftMapColumn != null && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type); + ColumnInfo rightMapColumn = null; + var isRightMapType = false; + if (isLeftMapType) tsc.mapType = leftMapColumn.Attribute.MapType; - var right = ExpressionLambdaToSql(rightExp, tsc); - if (right != "NULL" && isLeftMapType) { - var enumType = leftMapColumn.CsType.NullableTypeOrThis(); - if (enumType.IsEnum) - right = formatSql(Enum.Parse(enumType, right.Trim('\'')), leftMapColumn.Attribute.MapType); - } - if (leftMapColumn == null) { - rightMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, right); - isRightMapType = rightMapColumn != null && (rightMapColumn.Attribute.MapType != leftExp.Type || rightMapColumn.CsType != leftExp.Type); - if (isRightMapType) { - tsc.mapType = rightMapColumn.Attribute.MapType; - left = ExpressionLambdaToSql(leftExp, tsc); - if (left != "NULL" && isRightMapType) { - var enumType = rightMapColumn.CsType.NullableTypeOrThis(); - if (enumType.IsEnum) - left = formatSql(Enum.Parse(enumType, left.Trim('\'')), rightMapColumn.Attribute.MapType); - } - } - } - if (leftExp.Type.NullableTypeOrThis() == typeof(bool) && (leftExp.NodeType != ExpressionType.MemberAccess && rightExp.NodeType != ExpressionType.MemberAccess)) { - if (oper == "=") { - var trueVal = formatSql(true, null); - var falseVal = formatSql(false, null); - if (left == trueVal) return right; - else if (left == falseVal) return $"not({right})"; - else if (right == trueVal) return left; - else if (right == falseVal) return $"not({left})"; - } else if (oper == "<>") { - var trueVal = formatSql(true, null); - var falseVal = formatSql(false, null); - if (left == trueVal) return $"not({right})"; - else if (left == falseVal) return right; - else if (right == trueVal) return $"not({left})"; - else if (right == falseVal) return left; - } - } + var right = ExpressionLambdaToSql(rightExp, tsc); + if (right != "NULL" && isLeftMapType) + { + var enumType = leftMapColumn.CsType.NullableTypeOrThis(); + if (enumType.IsEnum) + right = formatSql(Enum.Parse(enumType, right.Trim('\'')), leftMapColumn.Attribute.MapType); + } + if (leftMapColumn == null) + { + rightMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, right); + isRightMapType = rightMapColumn != null && (rightMapColumn.Attribute.MapType != leftExp.Type || rightMapColumn.CsType != leftExp.Type); + if (isRightMapType) + { + tsc.mapType = rightMapColumn.Attribute.MapType; + left = ExpressionLambdaToSql(leftExp, tsc); + if (left != "NULL" && isRightMapType) + { + var enumType = rightMapColumn.CsType.NullableTypeOrThis(); + if (enumType.IsEnum) + left = formatSql(Enum.Parse(enumType, left.Trim('\'')), rightMapColumn.Attribute.MapType); + } + } + } + if (leftExp.Type.NullableTypeOrThis() == typeof(bool) && (leftExp.NodeType != ExpressionType.MemberAccess && rightExp.NodeType != ExpressionType.MemberAccess)) + { + if (oper == "=") + { + var trueVal = formatSql(true, null); + var falseVal = formatSql(false, null); + if (left == trueVal) return right; + else if (left == falseVal) return $"not({right})"; + else if (right == trueVal) return left; + else if (right == falseVal) return $"not({left})"; + } + else if (oper == "<>") + { + var trueVal = formatSql(true, null); + var falseVal = formatSql(false, null); + if (left == trueVal) return $"not({right})"; + else if (left == falseVal) return right; + else if (right == trueVal) return $"not({left})"; + else if (right == falseVal) return left; + } + } - if (left == "NULL") { - var tmp = right; - right = left; - left = tmp; - } - if (right == "NULL") oper = oper == "=" ? " IS " : " IS NOT "; - if (oper == "%") return _common.Mod(left, right, leftExp.Type, rightExp.Type); - tsc.mapType = null; - return $"{left} {oper} {right}"; - } - public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) { - if (exp == null) return ""; - if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpression != null) { - var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, tsc.CloneDisableDiyParse())); - _common._orm.Aop.ParseExpression?.Invoke(this, args); - if (string.IsNullOrEmpty(args.Result) == false) return args.Result; - } - switch (exp.NodeType) { - case ExpressionType.Not: - var notExp = (exp as UnaryExpression)?.Operand; - if (notExp.NodeType == ExpressionType.MemberAccess) { - var notBody = ExpressionLambdaToSql(notExp, tsc); - if (notBody.Contains(" IS NULL")) return notBody.Replace(" IS NULL", " IS NOT NULL"); - if (notBody.Contains(" IS NOT NULL")) return notBody.Replace(" IS NOT NULL", " IS NULL"); - if (notBody.Contains("=")) return notBody.Replace("=", "!="); - if (notBody.Contains("!=")) return notBody.Replace("!=", "="); - return $"{notBody} = {formatSql(false, null)}"; - } - return $"not({ExpressionLambdaToSql(notExp, tsc)})"; - case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); - case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc); - case ExpressionType.TypeAs: - case ExpressionType.Convert: - //var othercExp = ExpressionLambdaToSqlOther(exp, tsc); - //if (string.IsNullOrEmpty(othercExp) == false) return othercExp; - return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); - case ExpressionType.Negate: - case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); - case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType); - case ExpressionType.Conditional: - var condExp = exp as ConditionalExpression; - return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end"; - case ExpressionType.Call: - var exp3 = exp as MethodCallExpression; - var callType = exp3.Object?.Type ?? exp3.Method.DeclaringType; - switch (callType.FullName) { - case "System.String": return ExpressionLambdaToSqlCallString(exp3, tsc); - case "System.Math": return ExpressionLambdaToSqlCallMath(exp3, tsc); - case "System.DateTime": return ExpressionLambdaToSqlCallDateTime(exp3, tsc); - case "System.TimeSpan": return ExpressionLambdaToSqlCallTimeSpan(exp3, tsc); - case "System.Convert": return ExpressionLambdaToSqlCallConvert(exp3, tsc); - } - if (exp3.Method.Name == "Equals" && exp3.Object != null && exp3.Arguments.Count > 0) - return ExpressionBinary("=", exp3.Object, exp3.Arguments[0], tsc); - if (callType.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { - //if (exp3.Type == typeof(string) && exp3.Arguments.Any() && exp3.Arguments[0].NodeType == ExpressionType.Constant) { - // switch (exp3.Method.Name) { - // case "Sum": return $"sum({(exp3.Arguments[0] as ConstantExpression)?.Value})"; - // case "Avg": return $"avg({(exp3.Arguments[0] as ConstantExpression)?.Value})"; - // case "Max": return $"max({(exp3.Arguments[0] as ConstantExpression)?.Value})"; - // case "Min": return $"min({(exp3.Arguments[0] as ConstantExpression)?.Value})"; - // } - //} - switch (exp3.Method.Name) { - case "Count": return "count(1)"; - case "Sum": return $"sum({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; - case "Avg": return $"avg({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; - case "Max": return $"max({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; - case "Min": return $"min({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; - } - } - if (callType.FullName.StartsWith("FreeSql.ISelect`")) { //子表查询 - if (exp3.Method.Name == "Any") { //exists - var anyArgs = exp3.Arguments; - var exp3Stack = new Stack(); - var exp3tmp = exp3.Object; - if (exp3tmp != null && anyArgs.Any()) - exp3Stack.Push(Expression.Call(exp3tmp, callType.GetMethod("Where", anyArgs.Select(a => a.Type).ToArray()), anyArgs.ToArray())); - while (exp3tmp != null) { - exp3Stack.Push(exp3tmp); - switch (exp3tmp.NodeType) { - case ExpressionType.Call: - var exp3tmpCall = (exp3tmp as MethodCallExpression); - exp3tmp = exp3tmpCall.Object == null ? exp3tmpCall.Arguments.FirstOrDefault() : exp3tmpCall.Object; - continue; - case ExpressionType.MemberAccess: exp3tmp = (exp3tmp as MemberExpression).Expression; continue; - } - break; - } - object fsql = null; - List fsqltables = null; - var fsqltable1SetAlias = false; - Type fsqlType = null; - Stack asSelectBefores = new Stack(); - var asSelectSql = ""; - Type asSelectEntityType = null; - MemberExpression asSelectParentExp1 = null; - Expression asSelectParentExp = null; - while (exp3Stack.Any()) { - exp3tmp = exp3Stack.Pop(); - if (exp3tmp.Type.FullName.StartsWith("FreeSql.ISelect`") && fsql == null) { - if (exp3tmp.NodeType == ExpressionType.Call) { - var exp3tmpCall = (exp3tmp as MethodCallExpression); - if (exp3tmpCall.Method.Name == "AsSelect" && exp3tmpCall.Object == null) { - var exp3tmpArg1Type = exp3tmpCall.Arguments.FirstOrDefault()?.Type; - if (exp3tmpArg1Type != null) { - asSelectEntityType = exp3tmpArg1Type.GetElementType() ?? exp3tmpArg1Type.GenericTypeArguments.FirstOrDefault(); - if (asSelectEntityType != null) { - fsql = _dicExpressionLambdaToSqlAsSelectMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType2 => typeof(IFreeSql).GetMethod("Select", new Type[0]).MakeGenericMethod(asSelectEntityType2)) - .Invoke(_common._orm, null); + if (left == "NULL") + { + var tmp = right; + right = left; + left = tmp; + } + if (right == "NULL") oper = oper == "=" ? " IS " : " IS NOT "; + if (oper == "%") return _common.Mod(left, right, leftExp.Type, rightExp.Type); + tsc.mapType = null; + return $"{left} {oper} {right}"; + } + public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) + { + if (exp == null) return ""; + if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpression != null) + { + var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, tsc.CloneDisableDiyParse())); + _common._orm.Aop.ParseExpression?.Invoke(this, args); + if (string.IsNullOrEmpty(args.Result) == false) return args.Result; + } + switch (exp.NodeType) + { + case ExpressionType.Not: + var notExp = (exp as UnaryExpression)?.Operand; + if (notExp.NodeType == ExpressionType.MemberAccess) + { + var notBody = ExpressionLambdaToSql(notExp, tsc); + if (notBody.Contains(" IS NULL")) return notBody.Replace(" IS NULL", " IS NOT NULL"); + if (notBody.Contains(" IS NOT NULL")) return notBody.Replace(" IS NOT NULL", " IS NULL"); + if (notBody.Contains("=")) return notBody.Replace("=", "!="); + if (notBody.Contains("!=")) return notBody.Replace("!=", "="); + return $"{notBody} = {formatSql(false, null)}"; + } + return $"not({ExpressionLambdaToSql(notExp, tsc)})"; + case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); + case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc); + case ExpressionType.TypeAs: + case ExpressionType.Convert: + //var othercExp = ExpressionLambdaToSqlOther(exp, tsc); + //if (string.IsNullOrEmpty(othercExp) == false) return othercExp; + return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); + case ExpressionType.Negate: + case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); + case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType); + case ExpressionType.Conditional: + var condExp = exp as ConditionalExpression; + return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end"; + case ExpressionType.Call: + var exp3 = exp as MethodCallExpression; + var callType = exp3.Object?.Type ?? exp3.Method.DeclaringType; + switch (callType.FullName) + { + case "System.String": return ExpressionLambdaToSqlCallString(exp3, tsc); + case "System.Math": return ExpressionLambdaToSqlCallMath(exp3, tsc); + case "System.DateTime": return ExpressionLambdaToSqlCallDateTime(exp3, tsc); + case "System.TimeSpan": return ExpressionLambdaToSqlCallTimeSpan(exp3, tsc); + case "System.Convert": return ExpressionLambdaToSqlCallConvert(exp3, tsc); + } + if (exp3.Method.Name == "Equals" && exp3.Object != null && exp3.Arguments.Count > 0) + return ExpressionBinary("=", exp3.Object, exp3.Arguments[0], tsc); + if (callType.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) + { + //if (exp3.Type == typeof(string) && exp3.Arguments.Any() && exp3.Arguments[0].NodeType == ExpressionType.Constant) { + // switch (exp3.Method.Name) { + // case "Sum": return $"sum({(exp3.Arguments[0] as ConstantExpression)?.Value})"; + // case "Avg": return $"avg({(exp3.Arguments[0] as ConstantExpression)?.Value})"; + // case "Max": return $"max({(exp3.Arguments[0] as ConstantExpression)?.Value})"; + // case "Min": return $"min({(exp3.Arguments[0] as ConstantExpression)?.Value})"; + // } + //} + switch (exp3.Method.Name) + { + case "Count": return "count(1)"; + case "Sum": return $"sum({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; + case "Avg": return $"avg({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; + case "Max": return $"max({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; + case "Min": return $"min({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; + } + } + if (callType.FullName.StartsWith("FreeSql.ISelect`")) + { //子表查询 + if (exp3.Method.Name == "Any") + { //exists + var anyArgs = exp3.Arguments; + var exp3Stack = new Stack(); + var exp3tmp = exp3.Object; + if (exp3tmp != null && anyArgs.Any()) + exp3Stack.Push(Expression.Call(exp3tmp, callType.GetMethod("Where", anyArgs.Select(a => a.Type).ToArray()), anyArgs.ToArray())); + while (exp3tmp != null) + { + exp3Stack.Push(exp3tmp); + switch (exp3tmp.NodeType) + { + case ExpressionType.Call: + var exp3tmpCall = (exp3tmp as MethodCallExpression); + exp3tmp = exp3tmpCall.Object == null ? exp3tmpCall.Arguments.FirstOrDefault() : exp3tmpCall.Object; + continue; + case ExpressionType.MemberAccess: exp3tmp = (exp3tmp as MemberExpression).Expression; continue; + } + break; + } + object fsql = null; + List fsqltables = null; + var fsqltable1SetAlias = false; + Type fsqlType = null; + Stack asSelectBefores = new Stack(); + var asSelectSql = ""; + Type asSelectEntityType = null; + MemberExpression asSelectParentExp1 = null; + Expression asSelectParentExp = null; + while (exp3Stack.Any()) + { + exp3tmp = exp3Stack.Pop(); + if (exp3tmp.Type.FullName.StartsWith("FreeSql.ISelect`") && fsql == null) + { + if (exp3tmp.NodeType == ExpressionType.Call) + { + var exp3tmpCall = (exp3tmp as MethodCallExpression); + if (exp3tmpCall.Method.Name == "AsSelect" && exp3tmpCall.Object == null) + { + var exp3tmpArg1Type = exp3tmpCall.Arguments.FirstOrDefault()?.Type; + if (exp3tmpArg1Type != null) + { + asSelectEntityType = exp3tmpArg1Type.GetElementType() ?? exp3tmpArg1Type.GenericTypeArguments.FirstOrDefault(); + if (asSelectEntityType != null) + { + fsql = _dicExpressionLambdaToSqlAsSelectMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType2 => typeof(IFreeSql).GetMethod("Select", new Type[0]).MakeGenericMethod(asSelectEntityType2)) + .Invoke(_common._orm, null); - if (asSelectBefores.Any()) { - asSelectParentExp1 = asSelectBefores.Pop() as MemberExpression; - if (asSelectBefores.Any()) { - asSelectParentExp = asSelectBefores.Pop(); - if (asSelectParentExp != null) { - var testExecuteExp = asSelectParentExp; - if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联 - testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key); - var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List(), tsc.getSelectGroupingMapString, SelectTableInfoType.LeftJoin); - tsc2.isDisableDiyParse = true; - tsc2.style = ExpressionStyle.AsSelect; - asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2); - } - } - } - } - } - } - } - if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke(); - fsqlType = fsql?.GetType(); - if (fsqlType == null) break; - fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); - fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; - //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; - fsqltables.AddRange(tsc._tables.Select(a => new SelectTableInfo { - Alias = a.Alias, - On = "1=1", - Table = a.Table, - Type = SelectTableInfoType.Parent, - Parameter = a.Parameter - })); - } else if (fsqlType != null) { - var call3Exp = exp3tmp as MethodCallExpression; - var method = fsqlType.GetMethod(call3Exp.Method.Name, call3Exp.Arguments.Select(a => a.Type).ToArray()); - if (call3Exp.Method.ContainsGenericParameters) method.MakeGenericMethod(call3Exp.Method.GetGenericArguments()); - var parms = method.GetParameters(); - var args = new object[call3Exp.Arguments.Count]; - for (var a = 0; a < args.Length; a++) { - var arg3Exp = call3Exp.Arguments[a]; - if (arg3Exp.NodeType == ExpressionType.Constant) { - args[a] = (arg3Exp as ConstantExpression)?.Value; - } else { - var argExp = (arg3Exp as UnaryExpression)?.Operand; - if (argExp != null && argExp.NodeType == ExpressionType.Lambda) { - if (fsqltable1SetAlias == false) { - fsqltables[0].Alias = (argExp as LambdaExpression).Parameters.First().Name; - fsqltable1SetAlias = true; - } - } - args[a] = argExp ?? Expression.Lambda(arg3Exp).Compile().DynamicInvoke(); - //if (args[a] == null) ExpressionLambdaToSql(call3Exp.Arguments[a], fsqltables, null, null, SelectTableInfoType.From, true); - } - } - method.Invoke(fsql, args); - } - if (fsql == null) asSelectBefores.Push(exp3tmp); - } - if (fsql != null) { - if (asSelectParentExp != null) { //执行 asSelect() 的关联,OneToMany,ManyToMany - if (fsqltables[0].Parameter == null) { - fsqltables[0].Alias = $"tb_{fsqltables.Count}"; - fsqltables[0].Parameter = Expression.Parameter(asSelectEntityType, fsqltables[0].Alias); - } - var fsqlWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType3 => - typeof(ISelect<>).MakeGenericType(asSelectEntityType3).GetMethod("Where", new[] { - typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool))) - })); - var parm123Tb = _common.GetTableByEntity(asSelectParentExp.Type); - var parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true); - var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType); - Expression fsqlWhereExp = null; - if (parm123Ref.RefType == TableRefType.ManyToMany) { - //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); - var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType); - var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] { - typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool))) - })); - var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); - var manySubSelectAny = _dicExpressionLambdaToSqlAsSelectAnyMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Any", new Type[0])); - var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - Expression.Call( - typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3), - Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3))) - )); - var manyMainParam = tsc._tables[0].Parameter; - var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__"); - Expression manySubSelectWhereExp = null; - for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) { - var col1 = parm123Ref.MiddleColumns[mn]; - var col2 = parm123Ref.Columns[mn]; - var pexp1 = Expression.Property(manySubSelectWhereParam, col1.CsName); - var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); - if (col1.CsType != col2.CsType) { - if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); - if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); - } - var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) manySubSelectWhereExp = tmpExp; - else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp); - } - var manySubSelectExpBoy = Expression.Call( - manySubSelectAsSelectExp, - manySubSelectWhere, - Expression.Lambda( - manySubSelectWhereExp, - manySubSelectWhereParam - ) - ); - Expression fsqlManyWhereExp = null; - for (var mn = 0; mn < parm123Ref.RefColumns.Count; mn++) { - var col1 = parm123Ref.RefColumns[mn]; - var col2 = parm123Ref.MiddleColumns[mn + parm123Ref.Columns.Count + mn]; - var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); - var pexp2 = Expression.Property(manySubSelectWhereParam, col2.CsName); - if (col1.CsType != col2.CsType) { - if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); - if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); - } - var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) fsqlManyWhereExp = tmpExp; - else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp); - } - fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent }); - fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); - var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); - if (string.IsNullOrEmpty(sql2) == false) - manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace("\r\n", "\r\n\t")})"), Expression.Constant(null)); - manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAny); - asSelectBefores.Clear(); + if (asSelectBefores.Any()) + { + asSelectParentExp1 = asSelectBefores.Pop() as MemberExpression; + if (asSelectBefores.Any()) + { + asSelectParentExp = asSelectBefores.Pop(); + if (asSelectParentExp != null) + { + var testExecuteExp = asSelectParentExp; + if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联 + testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key); + var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List(), tsc.getSelectGroupingMapString, SelectTableInfoType.LeftJoin); + tsc2.isDisableDiyParse = true; + tsc2.style = ExpressionStyle.AsSelect; + asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2); + } + } + } + } + } + } + } + if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke(); + fsqlType = fsql?.GetType(); + if (fsqlType == null) break; + fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); + fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; + //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; + fsqltables.AddRange(tsc._tables.Select(a => new SelectTableInfo + { + Alias = a.Alias, + On = "1=1", + Table = a.Table, + Type = SelectTableInfoType.Parent, + Parameter = a.Parameter + })); + } + else if (fsqlType != null) + { + var call3Exp = exp3tmp as MethodCallExpression; + var method = fsqlType.GetMethod(call3Exp.Method.Name, call3Exp.Arguments.Select(a => a.Type).ToArray()); + if (call3Exp.Method.ContainsGenericParameters) method.MakeGenericMethod(call3Exp.Method.GetGenericArguments()); + var parms = method.GetParameters(); + var args = new object[call3Exp.Arguments.Count]; + for (var a = 0; a < args.Length; a++) + { + var arg3Exp = call3Exp.Arguments[a]; + if (arg3Exp.NodeType == ExpressionType.Constant) + { + args[a] = (arg3Exp as ConstantExpression)?.Value; + } + else + { + var argExp = (arg3Exp as UnaryExpression)?.Operand; + if (argExp != null && argExp.NodeType == ExpressionType.Lambda) + { + if (fsqltable1SetAlias == false) + { + fsqltables[0].Alias = (argExp as LambdaExpression).Parameters.First().Name; + fsqltable1SetAlias = true; + } + } + args[a] = argExp ?? Expression.Lambda(arg3Exp).Compile().DynamicInvoke(); + //if (args[a] == null) ExpressionLambdaToSql(call3Exp.Arguments[a], fsqltables, null, null, SelectTableInfoType.From, true); + } + } + method.Invoke(fsql, args); + } + if (fsql == null) asSelectBefores.Push(exp3tmp); + } + if (fsql != null) + { + if (asSelectParentExp != null) + { //执行 asSelect() 的关联,OneToMany,ManyToMany + if (fsqltables[0].Parameter == null) + { + fsqltables[0].Alias = $"tb_{fsqltables.Count}"; + fsqltables[0].Parameter = Expression.Parameter(asSelectEntityType, fsqltables[0].Alias); + } + var fsqlWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType3 => + typeof(ISelect<>).MakeGenericType(asSelectEntityType3).GetMethod("Where", new[] { + typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool))) + })); + var parm123Tb = _common.GetTableByEntity(asSelectParentExp.Type); + var parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true); + var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType); + Expression fsqlWhereExp = null; + if (parm123Ref.RefType == TableRefType.ManyToMany) + { + //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); + var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType); + var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] { + typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool))) + })); + var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); + var manySubSelectAny = _dicExpressionLambdaToSqlAsSelectAnyMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Any", new Type[0])); + var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + Expression.Call( + typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3), + Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3))) + )); + var manyMainParam = tsc._tables[0].Parameter; + var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__"); + Expression manySubSelectWhereExp = null; + for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) + { + var col1 = parm123Ref.MiddleColumns[mn]; + var col2 = parm123Ref.Columns[mn]; + var pexp1 = Expression.Property(manySubSelectWhereParam, col1.CsName); + var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); + if (col1.CsType != col2.CsType) + { + if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); + if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); + } + var tmpExp = Expression.Equal(pexp1, pexp2); + if (mn == 0) manySubSelectWhereExp = tmpExp; + else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp); + } + var manySubSelectExpBoy = Expression.Call( + manySubSelectAsSelectExp, + manySubSelectWhere, + Expression.Lambda( + manySubSelectWhereExp, + manySubSelectWhereParam + ) + ); + Expression fsqlManyWhereExp = null; + for (var mn = 0; mn < parm123Ref.RefColumns.Count; mn++) + { + var col1 = parm123Ref.RefColumns[mn]; + var col2 = parm123Ref.MiddleColumns[mn + parm123Ref.Columns.Count + mn]; + var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); + var pexp2 = Expression.Property(manySubSelectWhereParam, col2.CsName); + if (col1.CsType != col2.CsType) + { + if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); + if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); + } + var tmpExp = Expression.Equal(pexp1, pexp2); + if (mn == 0) fsqlManyWhereExp = tmpExp; + else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp); + } + fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent }); + fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); + var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); + if (string.IsNullOrEmpty(sql2) == false) + manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace("\r\n", "\r\n\t")})"), Expression.Constant(null)); + manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAny); + asSelectBefores.Clear(); - return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); - } - for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) { - var col1 = parm123Ref.RefColumns[mn]; - var col2 = parm123Ref.Columns[mn]; - var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); - var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); - if (col1.CsType != col2.CsType) { - if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); - if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); - } - var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) fsqlWhereExp = tmpExp; - else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp); - } - fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) }); - } - asSelectBefores.Clear(); - var sql = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); - if (string.IsNullOrEmpty(sql) == false) - return $"exists({sql.Replace("\r\n", "\r\n\t")})"; - } - asSelectBefores.Clear(); - } - } - //var eleType = callType.GetElementType() ?? callType.GenericTypeArguments.FirstOrDefault(); - //if (eleType != null && typeof(IEnumerable<>).MakeGenericType(eleType).IsAssignableFrom(callType)) { //集合导航属性子查询 - // if (exp3.Method.Name == "Any") { //exists - - // } - //} - var other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); - if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; - throw new Exception($"未实现函数表达式 {exp3} 解析"); - case ExpressionType.Parameter: - case ExpressionType.MemberAccess: - var exp4 = exp as MemberExpression; - if (exp4 != null) { - if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) - return exp4.Member.Name == "HasValue" ? $"{ExpressionLambdaToSql(exp4.Expression, tsc)} IS NOT NULL" : ExpressionLambdaToSql(exp4.Expression, tsc); - var extRet = ""; - var memberType = exp4.Expression?.Type ?? exp4.Type; - switch (memberType.FullName) { - case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, tsc); break; - case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, tsc); break; - case "System.TimeSpan": extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, tsc); break; - } - if (string.IsNullOrEmpty(extRet) == false) return extRet; - var other4Exp = ExpressionLambdaToSqlOther(exp4, tsc); - if (string.IsNullOrEmpty(other4Exp) == false) return other4Exp; - } - var expStack = new Stack(); - expStack.Push(exp); - MethodCallExpression callExp = null; - var exp2 = exp4?.Expression; - while (true) { - switch(exp2?.NodeType) { - case ExpressionType.Constant: - expStack.Push(exp2); - break; - case ExpressionType.Parameter: - expStack.Push(exp2); - break; - case ExpressionType.MemberAccess: - expStack.Push(exp2); - exp2 = (exp2 as MemberExpression).Expression; - if (exp2 == null) break; - continue; - case ExpressionType.Call: - callExp = exp2 as MethodCallExpression; - expStack.Push(exp2); - exp2 = callExp.Object; - if (exp2 == null) break; - continue; - case ExpressionType.TypeAs: - case ExpressionType.Convert: - var oper2 = (exp2 as UnaryExpression).Operand; - if (oper2.NodeType == ExpressionType.Parameter) { - var oper2Parm = oper2 as ParameterExpression; - expStack.Push(Expression.Parameter(exp2.Type, oper2Parm.Name)); - } else - expStack.Push(oper2); - break; - } - break; - } - if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType); - if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); - if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { - if (tsc.getSelectGroupingMapString != null) { - var expText = tsc.getSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray()); - if (string.IsNullOrEmpty(expText) == false) return expText; - } - } + return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); + } + for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) + { + var col1 = parm123Ref.RefColumns[mn]; + var col2 = parm123Ref.Columns[mn]; + var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); + var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); + if (col1.CsType != col2.CsType) + { + if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); + if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); + } + var tmpExp = Expression.Equal(pexp1, pexp2); + if (mn == 0) fsqlWhereExp = tmpExp; + else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp); + } + fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) }); + } + asSelectBefores.Clear(); + var sql = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); + if (string.IsNullOrEmpty(sql) == false) + return $"exists({sql.Replace("\r\n", "\r\n\t")})"; + } + asSelectBefores.Clear(); + } + } + //var eleType = callType.GetElementType() ?? callType.GenericTypeArguments.FirstOrDefault(); + //if (eleType != null && typeof(IEnumerable<>).MakeGenericType(eleType).IsAssignableFrom(callType)) { //集合导航属性子查询 + // if (exp3.Method.Name == "Any") { //exists - if (tsc._tables == null) { - var pp = expStack.Pop() as ParameterExpression; - var memberExp = expStack.Pop() as MemberExpression; - var tb = _common.GetTableByEntity(pp.Type); - if (tb.ColumnsByCs.ContainsKey(memberExp.Member.Name) == false) throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}"); - if (tsc._selectColumnMap != null) { - tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = tb.ColumnsByCs[memberExp.Member.Name] }); - } - var name = tb.ColumnsByCs[memberExp.Member.Name].Attribute.Name; - if (tsc.isQuoteName) name = _common.QuoteSqlName(name); - return name; - } - Func getOrAddTable = (tbtmp, alias, isa, parmExp, mp) => { - var finds = new SelectTableInfo[0]; - if (tsc.style == ExpressionStyle.SelectColumns) { - finds = tsc._tables.Where(a => a.Table.Type == tbtmp.Type).ToArray(); - if (finds.Any()) finds = new[] { finds.First() }; - } - if (finds.Length != 1 && isa && parmExp != null) - finds = tsc._tables.Where(a => a.Parameter == parmExp).ToArray(); - if (finds.Length != 1) { - var navdot = string.IsNullOrEmpty(alias) ? new SelectTableInfo[0] : tsc._tables.Where(a2 => a2.Parameter != null && alias.StartsWith($"{a2.Alias}__")).ToArray(); - if (navdot.Length > 0) { - var isthis = navdot[0] == tsc._tables[0]; - finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || !isa && a2.Parameter == null) && - a2.Table.Type == tbtmp.Type && a2.Alias == alias && a2.Alias.StartsWith($"{navdot[0].Alias}__") && - (isthis && a2.Type != SelectTableInfoType.Parent || !isthis && a2.Type == SelectTableInfoType.Parent)).ToArray(); - if (finds.Length == 0) - finds = tsc._tables.Where(a2 => - a2.Table.Type == tbtmp.Type && a2.Alias == alias && a2.Alias.StartsWith($"{navdot[0].Alias}__") && - (isthis && a2.Type != SelectTableInfoType.Parent || !isthis && a2.Type == SelectTableInfoType.Parent)).ToArray(); - } else { - finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) && - a2.Table.Type == tbtmp.Type && a2.Alias == alias).ToArray(); - if (finds.Length != 1) { - finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) && - a2.Table.Type == tbtmp.Type).ToArray(); - if (finds.Length != 1) { - finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) && - a2.Table.Type == tbtmp.Type).ToArray(); - if (finds.Length != 1) - finds = tsc._tables.Where(a2 => a2.Table.Type == tbtmp.Type).ToArray(); - } - } - } - //finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && (isthis && a2.Type != SelectTableInfoType.Parent || !isthis)).ToArray(); //外部表,内部表一起查 - //if (finds.Length > 1) { - // finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type == SelectTableInfoType.Parent && a2.Alias == alias).ToArray(); //查询外部表 - // if (finds.Any() == false) { - // finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent).ToArray(); //查询内部表 - // if (finds.Length > 1) - // finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent && a2.Alias == alias).ToArray(); - // } - //} - } - var find = finds.Length == 1 ? finds.First() : null; - if (find != null && isa && parmExp != null && find.Parameter != parmExp) - find.Parameter = parmExp; - if (find == null) { - tsc._tables.Add(find = new SelectTableInfo { Table = tbtmp, Alias = alias, On = null, Type = mp == null ? tsc.tbtype : SelectTableInfoType.LeftJoin, Parameter = isa ? parmExp : null }); - if (mp?.Expression != null) { //导航条件,OneToOne、ManyToOne - var firstTb = tsc._tables.First().Table; - var parentTb = _common.GetTableByEntity(mp.Expression.Type); - var parentTbRef = parentTb?.GetTableRef(mp.Member.Name, tsc.style == ExpressionStyle.AsSelect); - if (parentTbRef != null) { - Expression navCondExp = null; - for (var mn = 0; mn < parentTbRef.Columns.Count; mn++) { - var col1 = parentTbRef.RefColumns[mn]; - var col2 = parentTbRef.Columns[mn]; - var pexp1 = Expression.Property(mp, col1.CsName); - var pexp2 = Expression.Property(mp.Expression, col2.CsName); - if (col1.CsType != col2.CsType) { - if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); - if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); - } - var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) navCondExp = tmpExp; - else navCondExp = Expression.AndAlso(navCondExp, tmpExp); - } - if (find.Type == SelectTableInfoType.InnerJoin || - find.Type == SelectTableInfoType.LeftJoin || - find.Type == SelectTableInfoType.RightJoin) - find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type)); - else - find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type)); - } - } - } - return find; - }; + // } + //} + var other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); + if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; + throw new Exception($"未实现函数表达式 {exp3} 解析"); + case ExpressionType.Parameter: + case ExpressionType.MemberAccess: + var exp4 = exp as MemberExpression; + if (exp4 != null) + { + if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) + return exp4.Member.Name == "HasValue" ? $"{ExpressionLambdaToSql(exp4.Expression, tsc)} IS NOT NULL" : ExpressionLambdaToSql(exp4.Expression, tsc); + var extRet = ""; + var memberType = exp4.Expression?.Type ?? exp4.Type; + switch (memberType.FullName) + { + case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, tsc); break; + case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, tsc); break; + case "System.TimeSpan": extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, tsc); break; + } + if (string.IsNullOrEmpty(extRet) == false) return extRet; + var other4Exp = ExpressionLambdaToSqlOther(exp4, tsc); + if (string.IsNullOrEmpty(other4Exp) == false) return other4Exp; + } + var expStack = new Stack(); + expStack.Push(exp); + MethodCallExpression callExp = null; + var exp2 = exp4?.Expression; + while (true) + { + switch (exp2?.NodeType) + { + case ExpressionType.Constant: + expStack.Push(exp2); + break; + case ExpressionType.Parameter: + expStack.Push(exp2); + break; + case ExpressionType.MemberAccess: + expStack.Push(exp2); + exp2 = (exp2 as MemberExpression).Expression; + if (exp2 == null) break; + continue; + case ExpressionType.Call: + callExp = exp2 as MethodCallExpression; + expStack.Push(exp2); + exp2 = callExp.Object; + if (exp2 == null) break; + continue; + case ExpressionType.TypeAs: + case ExpressionType.Convert: + var oper2 = (exp2 as UnaryExpression).Operand; + if (oper2.NodeType == ExpressionType.Parameter) + { + var oper2Parm = oper2 as ParameterExpression; + expStack.Push(Expression.Parameter(exp2.Type, oper2Parm.Name)); + } + else + expStack.Push(oper2); + break; + } + break; + } + if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType); + if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); + if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) + { + if (tsc.getSelectGroupingMapString != null) + { + var expText = tsc.getSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray()); + if (string.IsNullOrEmpty(expText) == false) return expText; + } + } - TableInfo tb2 = null; - ParameterExpression parmExp2 = null; - string alias2 = "", name2 = ""; - SelectTableInfo find2 = null; - while (expStack.Count > 0) { - exp2 = expStack.Pop(); - switch (exp2.NodeType) { - case ExpressionType.Constant: - throw new NotImplementedException("未实现 MemberAccess 下的 Constant"); - case ExpressionType.Parameter: - case ExpressionType.MemberAccess: - - var exp2Type = exp2.Type; - if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GenericTypeArguments.LastOrDefault() ?? exp2.Type; - var tb2tmp = _common.GetTableByEntity(exp2Type); - var mp2 = exp2 as MemberExpression; - if (mp2?.Member.Name == "Key" && mp2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) continue; - if (tb2tmp != null) { - if (exp2.NodeType == ExpressionType.Parameter) { - parmExp2 = (exp2 as ParameterExpression); - alias2 = parmExp2.Name; - } else alias2 = $"{alias2}__{mp2.Member.Name}"; - find2 = getOrAddTable(tb2tmp, alias2, exp2.NodeType == ExpressionType.Parameter, parmExp2, mp2); - alias2 = find2.Alias; - tb2 = tb2tmp; - } - if (exp2.NodeType == ExpressionType.Parameter && expStack.Any() == false) { //附加选择的参数所有列 - if (tsc._selectColumnMap != null) { - foreach (var tb2c in tb2.Columns.Values) - tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = tb2c }); - if (tb2.Columns.Any()) return ""; - } - } - if (mp2 == null || expStack.Any()) continue; - if (tb2.ColumnsByCs.ContainsKey(mp2.Member.Name) == false) { //如果选的是对象,附加所有列 - if (tsc._selectColumnMap != null) { - var tb3 = _common.GetTableByEntity(mp2.Type); - if (tb3 != null) { - var find3 = getOrAddTable(tb2tmp, alias2 /*$"{alias2}__{mp2.Member.Name}"*/, exp2.NodeType == ExpressionType.Parameter, parmExp2, mp2); + if (tsc._tables == null) + { + var pp = expStack.Pop() as ParameterExpression; + var memberExp = expStack.Pop() as MemberExpression; + var tb = _common.GetTableByEntity(pp.Type); + if (tb.ColumnsByCs.ContainsKey(memberExp.Member.Name) == false) throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}"); + if (tsc._selectColumnMap != null) + { + tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = tb.ColumnsByCs[memberExp.Member.Name] }); + } + var name = tb.ColumnsByCs[memberExp.Member.Name].Attribute.Name; + if (tsc.isQuoteName) name = _common.QuoteSqlName(name); + return name; + } + Func getOrAddTable = (tbtmp, alias, isa, parmExp, mp) => + { + var finds = new SelectTableInfo[0]; + if (tsc.style == ExpressionStyle.SelectColumns) + { + finds = tsc._tables.Where(a => a.Table.Type == tbtmp.Type).ToArray(); + if (finds.Any()) finds = new[] { finds.First() }; + } + if (finds.Length != 1 && isa && parmExp != null) + finds = tsc._tables.Where(a => a.Parameter == parmExp).ToArray(); + if (finds.Length != 1) + { + var navdot = string.IsNullOrEmpty(alias) ? new SelectTableInfo[0] : tsc._tables.Where(a2 => a2.Parameter != null && alias.StartsWith($"{a2.Alias}__")).ToArray(); + if (navdot.Length > 0) + { + var isthis = navdot[0] == tsc._tables[0]; + finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || !isa && a2.Parameter == null) && + a2.Table.Type == tbtmp.Type && a2.Alias == alias && a2.Alias.StartsWith($"{navdot[0].Alias}__") && + (isthis && a2.Type != SelectTableInfoType.Parent || !isthis && a2.Type == SelectTableInfoType.Parent)).ToArray(); + if (finds.Length == 0) + finds = tsc._tables.Where(a2 => + a2.Table.Type == tbtmp.Type && a2.Alias == alias && a2.Alias.StartsWith($"{navdot[0].Alias}__") && + (isthis && a2.Type != SelectTableInfoType.Parent || !isthis && a2.Type == SelectTableInfoType.Parent)).ToArray(); + } + else + { + finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) && + a2.Table.Type == tbtmp.Type && a2.Alias == alias).ToArray(); + if (finds.Length != 1) + { + finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) && + a2.Table.Type == tbtmp.Type).ToArray(); + if (finds.Length != 1) + { + finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) && + a2.Table.Type == tbtmp.Type).ToArray(); + if (finds.Length != 1) + finds = tsc._tables.Where(a2 => a2.Table.Type == tbtmp.Type).ToArray(); + } + } + } + //finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && (isthis && a2.Type != SelectTableInfoType.Parent || !isthis)).ToArray(); //外部表,内部表一起查 + //if (finds.Length > 1) { + // finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type == SelectTableInfoType.Parent && a2.Alias == alias).ToArray(); //查询外部表 + // if (finds.Any() == false) { + // finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent).ToArray(); //查询内部表 + // if (finds.Length > 1) + // finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent && a2.Alias == alias).ToArray(); + // } + //} + } + var find = finds.Length == 1 ? finds.First() : null; + if (find != null && isa && parmExp != null && find.Parameter != parmExp) + find.Parameter = parmExp; + if (find == null) + { + tsc._tables.Add(find = new SelectTableInfo { Table = tbtmp, Alias = alias, On = null, Type = mp == null ? tsc.tbtype : SelectTableInfoType.LeftJoin, Parameter = isa ? parmExp : null }); + if (mp?.Expression != null) + { //导航条件,OneToOne、ManyToOne + var firstTb = tsc._tables.First().Table; + var parentTb = _common.GetTableByEntity(mp.Expression.Type); + var parentTbRef = parentTb?.GetTableRef(mp.Member.Name, tsc.style == ExpressionStyle.AsSelect); + if (parentTbRef != null) + { + Expression navCondExp = null; + for (var mn = 0; mn < parentTbRef.Columns.Count; mn++) + { + var col1 = parentTbRef.RefColumns[mn]; + var col2 = parentTbRef.Columns[mn]; + var pexp1 = Expression.Property(mp, col1.CsName); + var pexp2 = Expression.Property(mp.Expression, col2.CsName); + if (col1.CsType != col2.CsType) + { + if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); + if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); + } + var tmpExp = Expression.Equal(pexp1, pexp2); + if (mn == 0) navCondExp = tmpExp; + else navCondExp = Expression.AndAlso(navCondExp, tmpExp); + } + if (find.Type == SelectTableInfoType.InnerJoin || + find.Type == SelectTableInfoType.LeftJoin || + find.Type == SelectTableInfoType.RightJoin) + find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type)); + else + find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type)); + } + } + } + return find; + }; - foreach (var tb3c in tb3.Columns.Values) - tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find3, Column = tb3c }); - if (tb3.Columns.Any()) return ""; - } - } - throw new ArgumentException($"{tb2.DbName} 找不到列 {mp2.Member.Name}"); - } - var col2 = tb2.ColumnsByCs[mp2.Member.Name]; - if (tsc._selectColumnMap != null && find2 != null) { - tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 }); - return ""; - } - name2 = tb2.ColumnsByCs[mp2.Member.Name].Attribute.Name; - break; - case ExpressionType.Call:break; - } - } - if (tsc.isQuoteName) name2 = _common.QuoteSqlName(name2); - return $"{alias2}.{name2}"; - } - var expBinary = exp as BinaryExpression; - if (expBinary == null) { - var other99Exp = ExpressionLambdaToSqlOther(exp, tsc); - if (string.IsNullOrEmpty(other99Exp) == false) return other99Exp; - return ""; - } - switch (expBinary.NodeType) { - case ExpressionType.Coalesce: - return _common.IsNull(ExpressionLambdaToSql(expBinary.Left, tsc), ExpressionLambdaToSql(expBinary.Right, tsc)); - } - if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false) return ""; - return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc); - } + TableInfo tb2 = null; + ParameterExpression parmExp2 = null; + string alias2 = "", name2 = ""; + SelectTableInfo find2 = null; + while (expStack.Count > 0) + { + exp2 = expStack.Pop(); + switch (exp2.NodeType) + { + case ExpressionType.Constant: + throw new NotImplementedException("未实现 MemberAccess 下的 Constant"); + case ExpressionType.Parameter: + case ExpressionType.MemberAccess: - public abstract string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc); - public abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc); - public abstract string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc); - public abstract string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc); - public abstract string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc); - public abstract string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc); - public abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc); - public abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc); - public abstract string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc); + var exp2Type = exp2.Type; + if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GenericTypeArguments.LastOrDefault() ?? exp2.Type; + var tb2tmp = _common.GetTableByEntity(exp2Type); + var mp2 = exp2 as MemberExpression; + if (mp2?.Member.Name == "Key" && mp2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) continue; + if (tb2tmp != null) + { + if (exp2.NodeType == ExpressionType.Parameter) + { + parmExp2 = (exp2 as ParameterExpression); + alias2 = parmExp2.Name; + } + else alias2 = $"{alias2}__{mp2.Member.Name}"; + find2 = getOrAddTable(tb2tmp, alias2, exp2.NodeType == ExpressionType.Parameter, parmExp2, mp2); + alias2 = find2.Alias; + tb2 = tb2tmp; + } + if (exp2.NodeType == ExpressionType.Parameter && expStack.Any() == false) + { //附加选择的参数所有列 + if (tsc._selectColumnMap != null) + { + foreach (var tb2c in tb2.Columns.Values) + tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = tb2c }); + if (tb2.Columns.Any()) return ""; + } + } + if (mp2 == null || expStack.Any()) continue; + if (tb2.ColumnsByCs.ContainsKey(mp2.Member.Name) == false) + { //如果选的是对象,附加所有列 + if (tsc._selectColumnMap != null) + { + var tb3 = _common.GetTableByEntity(mp2.Type); + if (tb3 != null) + { + var find3 = getOrAddTable(tb2tmp, alias2 /*$"{alias2}__{mp2.Member.Name}"*/, exp2.NodeType == ExpressionType.Parameter, parmExp2, mp2); - public enum ExpressionStyle { - Where, AsSelect, SelectColumns - } - public class ExpTSC { - public List _tables { get; set; } - public List _selectColumnMap { get; set; } - public Func getSelectGroupingMapString { get; set; } - public SelectTableInfoType tbtype { get; set; } - public bool isQuoteName { get; set; } - public bool isDisableDiyParse { get; set; } - public ExpressionStyle style { get; set; } - public Type mapType { get; set; } - public TableInfo currentTable { get; set; } + foreach (var tb3c in tb3.Columns.Values) + tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find3, Column = tb3c }); + if (tb3.Columns.Any()) return ""; + } + } + throw new ArgumentException($"{tb2.DbName} 找不到列 {mp2.Member.Name}"); + } + var col2 = tb2.ColumnsByCs[mp2.Member.Name]; + if (tsc._selectColumnMap != null && find2 != null) + { + tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 }); + return ""; + } + name2 = tb2.ColumnsByCs[mp2.Member.Name].Attribute.Name; + break; + case ExpressionType.Call: break; + } + } + if (tsc.isQuoteName) name2 = _common.QuoteSqlName(name2); + return $"{alias2}.{name2}"; + } + var expBinary = exp as BinaryExpression; + if (expBinary == null) + { + var other99Exp = ExpressionLambdaToSqlOther(exp, tsc); + if (string.IsNullOrEmpty(other99Exp) == false) return other99Exp; + return ""; + } + switch (expBinary.NodeType) + { + case ExpressionType.Coalesce: + return _common.IsNull(ExpressionLambdaToSql(expBinary.Left, tsc), ExpressionLambdaToSql(expBinary.Right, tsc)); + } + if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false) return ""; + return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc); + } - public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List v1, Func v2, SelectTableInfoType v3 ) { - return new ExpTSC { - _tables = this._tables, - _selectColumnMap = v1, - getSelectGroupingMapString = v2, - tbtype = v3, - isQuoteName = this.isQuoteName, - isDisableDiyParse = this.isDisableDiyParse, - style = this.style, - currentTable = this.currentTable - }; - } - public ExpTSC CloneDisableDiyParse() { - return new ExpTSC { - _tables = this._tables, - _selectColumnMap = this._selectColumnMap, - getSelectGroupingMapString = this.getSelectGroupingMapString, - tbtype = this.tbtype, - isQuoteName = this.isQuoteName, - isDisableDiyParse = true, - style = this.style, - currentTable = this.currentTable - }; - } - } + public abstract string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc); + public abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc); + public abstract string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc); + public abstract string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc); + public abstract string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc); + public abstract string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc); + public abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc); + public abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc); + public abstract string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc); - public string formatSql(object obj, Type mapType) { - return string.Concat(_ado.AddslashesProcessParam(obj, mapType)); - } - } + public enum ExpressionStyle + { + Where, AsSelect, SelectColumns + } + public class ExpTSC + { + public List _tables { get; set; } + public List _selectColumnMap { get; set; } + public Func getSelectGroupingMapString { get; set; } + public SelectTableInfoType tbtype { get; set; } + public bool isQuoteName { get; set; } + public bool isDisableDiyParse { get; set; } + public ExpressionStyle style { get; set; } + public Type mapType { get; set; } + public TableInfo currentTable { get; set; } + + public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List v1, Func v2, SelectTableInfoType v3) + { + return new ExpTSC + { + _tables = this._tables, + _selectColumnMap = v1, + getSelectGroupingMapString = v2, + tbtype = v3, + isQuoteName = this.isQuoteName, + isDisableDiyParse = this.isDisableDiyParse, + style = this.style, + currentTable = this.currentTable + }; + } + public ExpTSC CloneDisableDiyParse() + { + return new ExpTSC + { + _tables = this._tables, + _selectColumnMap = this._selectColumnMap, + getSelectGroupingMapString = this.getSelectGroupingMapString, + tbtype = this.tbtype, + isQuoteName = this.isQuoteName, + isDisableDiyParse = true, + style = this.style, + currentTable = this.currentTable + }; + } + } + + public string formatSql(object obj, Type mapType) + { + return string.Concat(_ado.AddslashesProcessParam(obj, mapType)); + } + } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 1f0d5236..1ab01b5d 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -9,694 +9,795 @@ using System.Linq; using System.Text; using System.Reflection; -namespace FreeSql.Internal.CommonProvider { - public abstract partial class AdoProvider : IAdo, IDisposable { +namespace FreeSql.Internal.CommonProvider +{ + public abstract partial class AdoProvider : IAdo, IDisposable + { - protected abstract void ReturnConnection(ObjectPool pool, Object conn, Exception ex); - protected abstract DbCommand CreateCommand(); - protected abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); - public Action AopCommandExecuting { get; set; } - public Action AopCommandExecuted { get; set; } + protected abstract void ReturnConnection(ObjectPool pool, Object conn, Exception ex); + protected abstract DbCommand CreateCommand(); + protected abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); + public Action AopCommandExecuting { get; set; } + public Action AopCommandExecuted { get; set; } - protected bool IsTracePerformance => AopCommandExecuted != null; - - public ObjectPool MasterPool { get; protected set; } - public List> SlavePools { get; } = new List>(); - public DataType DataType { get; } - protected CommonUtils _util { get; set; } - protected int slaveUnavailables = 0; - private object slaveLock = new object(); - private Random slaveRandom = new Random(); + protected bool IsTracePerformance => AopCommandExecuted != null; - public AdoProvider(DataType dataType) { - this.DataType = dataType; - } + public ObjectPool MasterPool { get; protected set; } + public List> SlavePools { get; } = new List>(); + public DataType DataType { get; } + protected CommonUtils _util { get; set; } + protected int slaveUnavailables = 0; + private object slaveLock = new object(); + private Random slaveRandom = new Random(); - void LoggerException(ObjectPool pool, (DbCommand cmd, bool isclose) pc, Exception e, DateTime dt, StringBuilder logtxt, bool isThrowException = true) { - var cmd = pc.cmd; - if (pc.isclose) pc.cmd.Connection.Close(); - if (IsTracePerformance) { - TimeSpan ts = DateTime.Now.Subtract(dt); - if (e == null && ts.TotalMilliseconds > 100) - Trace.WriteLine(logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString()); - else - logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)耗时{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString(); - } + public AdoProvider(DataType dataType) + { + this.DataType = dataType; + } - if (e == null) { - AopCommandExecuted?.Invoke(cmd, logtxt.ToString()); - return; - } + void LoggerException(ObjectPool pool, (DbCommand cmd, bool isclose) pc, Exception e, DateTime dt, StringBuilder logtxt, bool isThrowException = true) + { + var cmd = pc.cmd; + if (pc.isclose) pc.cmd.Connection.Close(); + if (IsTracePerformance) + { + TimeSpan ts = DateTime.Now.Subtract(dt); + if (e == null && ts.TotalMilliseconds > 100) + Trace.WriteLine(logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString()); + else + logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)耗时{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString(); + } - StringBuilder log = new StringBuilder(); - log.Append(pool?.Policy.Name).Append("数据库出错(执行SQL)〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\r\n").Append(cmd.CommandText).Append("\r\n"); - foreach (DbParameter parm in cmd.Parameters) - log.Append(parm.ParameterName.PadRight(20, ' ')).Append(" = ").Append((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value).Append("\r\n"); + if (e == null) + { + AopCommandExecuted?.Invoke(cmd, logtxt.ToString()); + return; + } - log.Append(e.Message); - Trace.WriteLine(log.ToString()); + StringBuilder log = new StringBuilder(); + log.Append(pool?.Policy.Name).Append("数据库出错(执行SQL)〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\r\n").Append(cmd.CommandText).Append("\r\n"); + foreach (DbParameter parm in cmd.Parameters) + log.Append(parm.ParameterName.PadRight(20, ' ')).Append(" = ").Append((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value).Append("\r\n"); - if (cmd.Transaction != null) { - var curTran = TransactionCurrentThread; - if (cmd.Transaction != TransactionCurrentThread) { - //cmd.Transaction.Rollback(); - } else - RollbackTransaction(); - } + log.Append(e.Message); + Trace.WriteLine(log.ToString()); - AopCommandExecuted?.Invoke(cmd, log.ToString()); + if (cmd.Transaction != null) + { + var curTran = TransactionCurrentThread; + if (cmd.Transaction != TransactionCurrentThread) + { + //cmd.Transaction.Rollback(); + } + else + RollbackTransaction(); + } - cmd.Parameters.Clear(); - if (isThrowException) throw e; - } + AopCommandExecuted?.Invoke(cmd, log.ToString()); - internal static ConcurrentDictionary> dicQueryTypeGetProperties = new ConcurrentDictionary>(); - internal Dictionary GetQueryTypeProperties(Type type) { - var tb = _util.GetTableByEntity(type); - var props = tb?.Properties ?? dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase)); - return props; - } - public List Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - var ret = new List(); - if (string.IsNullOrEmpty(cmdText)) return ret; - var type = typeof(T); - string flag = null; - int[] indexes = null; - var props = GetQueryTypeProperties(type); - ExecuteReader(connection, transaction, dr => { - if (indexes == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes = props.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag = sbflag.ToString(); - } - ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); - }, cmdType, cmdText, cmdParms); - return ret; - } - #region query multi - public (List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public (List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public (List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List()); - var ret1 = new List(); - var type1 = typeof(T1); - string flag1 = null; - int[] indexes1 = null; - var props1 = GetQueryTypeProperties(type1); + cmd.Parameters.Clear(); + if (isThrowException) throw e; + } - var ret2 = new List(); - var type2 = typeof(T2); - string flag2 = null; - int[] indexes2 = null; - var props2 = GetQueryTypeProperties(type2); - ExecuteReaderMultiple(2, connection, transaction, (dr, result) => { - switch(result) { - case 0: - if (indexes1 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag1 = sbflag.ToString(); - } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); - break; - case 1: - if (indexes2 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag2 = sbflag.ToString(); - } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); - break; - } - }, cmdType, cmdText, cmdParms); - return (ret1, ret2); - } + internal static ConcurrentDictionary> dicQueryTypeGetProperties = new ConcurrentDictionary>(); + internal Dictionary GetQueryTypeProperties(Type type) + { + var tb = _util.GetTableByEntity(type); + var props = tb?.Properties ?? dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase)); + return props; + } + public List Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + var ret = new List(); + if (string.IsNullOrEmpty(cmdText)) return ret; + var type = typeof(T); + string flag = null; + int[] indexes = null; + var props = GetQueryTypeProperties(type); + ExecuteReader(connection, transaction, dr => + { + if (indexes == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes = props.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag = sbflag.ToString(); + } + ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); + }, cmdType, cmdText, cmdParms); + return ret; + } + #region query multi + public (List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public (List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public (List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return (new List(), new List()); + var ret1 = new List(); + var type1 = typeof(T1); + string flag1 = null; + int[] indexes1 = null; + var props1 = GetQueryTypeProperties(type1); - public (List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public (List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public (List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List()); - var ret1 = new List(); - var type1 = typeof(T1); - string flag1 = null; - int[] indexes1 = null; - var props1 = GetQueryTypeProperties(type1); + var ret2 = new List(); + var type2 = typeof(T2); + string flag2 = null; + int[] indexes2 = null; + var props2 = GetQueryTypeProperties(type2); + ExecuteReaderMultiple(2, connection, transaction, (dr, result) => + { + switch (result) + { + case 0: + if (indexes1 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag1 = sbflag.ToString(); + } + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + break; + case 1: + if (indexes2 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag2 = sbflag.ToString(); + } + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + break; + } + }, cmdType, cmdText, cmdParms); + return (ret1, ret2); + } - var ret2 = new List(); - var type2 = typeof(T2); - string flag2 = null; - int[] indexes2 = null; - var props2 = GetQueryTypeProperties(type2); + public (List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public (List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public (List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List()); + var ret1 = new List(); + var type1 = typeof(T1); + string flag1 = null; + int[] indexes1 = null; + var props1 = GetQueryTypeProperties(type1); - var ret3 = new List(); - var type3 = typeof(T3); - string flag3 = null; - int[] indexes3 = null; - var props3 = GetQueryTypeProperties(type3); - ExecuteReaderMultiple(3, connection, transaction, (dr, result) => { - switch (result) { - case 0: - if (indexes1 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag1 = sbflag.ToString(); - } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); - break; - case 1: - if (indexes2 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag2 = sbflag.ToString(); - } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); - break; - case 2: - if (indexes3 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag3 = sbflag.ToString(); - } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); - break; - } - }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3); - } + var ret2 = new List(); + var type2 = typeof(T2); + string flag2 = null; + int[] indexes2 = null; + var props2 = GetQueryTypeProperties(type2); - public (List, List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public (List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List()); - var ret1 = new List(); - var type1 = typeof(T1); - string flag1 = null; - int[] indexes1 = null; - var props1 = GetQueryTypeProperties(type1); + var ret3 = new List(); + var type3 = typeof(T3); + string flag3 = null; + int[] indexes3 = null; + var props3 = GetQueryTypeProperties(type3); + ExecuteReaderMultiple(3, connection, transaction, (dr, result) => + { + switch (result) + { + case 0: + if (indexes1 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag1 = sbflag.ToString(); + } + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + break; + case 1: + if (indexes2 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag2 = sbflag.ToString(); + } + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + break; + case 2: + if (indexes3 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag3 = sbflag.ToString(); + } + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + break; + } + }, cmdType, cmdText, cmdParms); + return (ret1, ret2, ret3); + } - var ret2 = new List(); - var type2 = typeof(T2); - string flag2 = null; - int[] indexes2 = null; - var props2 = GetQueryTypeProperties(type2); + public (List, List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public (List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List()); + var ret1 = new List(); + var type1 = typeof(T1); + string flag1 = null; + int[] indexes1 = null; + var props1 = GetQueryTypeProperties(type1); - var ret3 = new List(); - var type3 = typeof(T3); - string flag3 = null; - int[] indexes3 = null; - var props3 = GetQueryTypeProperties(type3); + var ret2 = new List(); + var type2 = typeof(T2); + string flag2 = null; + int[] indexes2 = null; + var props2 = GetQueryTypeProperties(type2); - var ret4 = new List(); - var type4 = typeof(T4); - string flag4 = null; - int[] indexes4 = null; - var props4 = GetQueryTypeProperties(type4); - ExecuteReaderMultiple(4, connection, transaction, (dr, result) => { - switch (result) { - case 0: - if (indexes1 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag1 = sbflag.ToString(); - } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); - break; - case 1: - if (indexes2 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag2 = sbflag.ToString(); - } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); - break; - case 2: - if (indexes3 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag3 = sbflag.ToString(); - } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); - break; - case 3: - if (indexes4 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag4 = sbflag.ToString(); - } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); - break; - } - }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3, ret4); - } + var ret3 = new List(); + var type3 = typeof(T3); + string flag3 = null; + int[] indexes3 = null; + var props3 = GetQueryTypeProperties(type3); - public (List, List, List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public (List, List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List(), new List()); - var ret1 = new List(); - var type1 = typeof(T1); - string flag1 = null; - int[] indexes1 = null; - var props1 = GetQueryTypeProperties(type1); + var ret4 = new List(); + var type4 = typeof(T4); + string flag4 = null; + int[] indexes4 = null; + var props4 = GetQueryTypeProperties(type4); + ExecuteReaderMultiple(4, connection, transaction, (dr, result) => + { + switch (result) + { + case 0: + if (indexes1 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag1 = sbflag.ToString(); + } + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + break; + case 1: + if (indexes2 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag2 = sbflag.ToString(); + } + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + break; + case 2: + if (indexes3 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag3 = sbflag.ToString(); + } + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + break; + case 3: + if (indexes4 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag4 = sbflag.ToString(); + } + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + break; + } + }, cmdType, cmdText, cmdParms); + return (ret1, ret2, ret3, ret4); + } - var ret2 = new List(); - var type2 = typeof(T2); - string flag2 = null; - int[] indexes2 = null; - var props2 = GetQueryTypeProperties(type2); + public (List, List, List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public (List, List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public (List, List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List(), new List()); + var ret1 = new List(); + var type1 = typeof(T1); + string flag1 = null; + int[] indexes1 = null; + var props1 = GetQueryTypeProperties(type1); - var ret3 = new List(); - var type3 = typeof(T3); - string flag3 = null; - int[] indexes3 = null; - var props3 = GetQueryTypeProperties(type3); + var ret2 = new List(); + var type2 = typeof(T2); + string flag2 = null; + int[] indexes2 = null; + var props2 = GetQueryTypeProperties(type2); - var ret4 = new List(); - var type4 = typeof(T4); - string flag4 = null; - int[] indexes4 = null; - var props4 = GetQueryTypeProperties(type4); + var ret3 = new List(); + var type3 = typeof(T3); + string flag3 = null; + int[] indexes3 = null; + var props3 = GetQueryTypeProperties(type3); - var ret5 = new List(); - var type5 = typeof(T5); - string flag5 = null; - int[] indexes5 = null; - var props5 = GetQueryTypeProperties(type5); - ExecuteReaderMultiple(5, connection, transaction, (dr, result) => { - switch (result) { - case 0: - if (indexes1 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag1 = sbflag.ToString(); - } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); - break; - case 1: - if (indexes2 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag2 = sbflag.ToString(); - } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); - break; - case 2: - if (indexes3 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag3 = sbflag.ToString(); - } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); - break; - case 3: - if (indexes4 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag4 = sbflag.ToString(); - } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); - break; - case 4: - if (indexes5 == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes5 = props5.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag5 = sbflag.ToString(); - } - ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); - break; - } - }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3, ret4, ret5); - } - #endregion + var ret4 = new List(); + var type4 = typeof(T4); + string flag4 = null; + int[] indexes4 = null; + var props4 = GetQueryTypeProperties(type4); - public void ExecuteReader(Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(connection, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, readerHander, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, readerHander, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (dr, result) => readerHander(dr), cmdType, cmdText, cmdParms); - void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return; - var dt = DateTime.Now; - var logtxt = new StringBuilder(); - var logtxt_dt = DateTime.Now; - var pool = this.MasterPool; - var isSlave = false; + var ret5 = new List(); + var type5 = typeof(T5); + string flag5 = null; + int[] indexes5 = null; + var props5 = GetQueryTypeProperties(type5); + ExecuteReaderMultiple(5, connection, transaction, (dr, result) => + { + switch (result) + { + case 0: + if (indexes1 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag1 = sbflag.ToString(); + } + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + break; + case 1: + if (indexes2 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag2 = sbflag.ToString(); + } + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + break; + case 2: + if (indexes3 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag3 = sbflag.ToString(); + } + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + break; + case 3: + if (indexes4 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag4 = sbflag.ToString(); + } + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + break; + case 4: + if (indexes5 == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes5 = props5.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag5 = sbflag.ToString(); + } + ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); + break; + } + }, cmdType, cmdText, cmdParms); + return (ret1, ret2, ret3, ret4, ret5); + } + #endregion - if (transaction == null && connection == null) { - //读写分离规则 - if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) { - var availables = slaveUnavailables == 0 ? - //查从库 - this.SlavePools : ( - //查主库 - slaveUnavailables == this.SlavePools.Count ? new List>() : - //查从库可用 - this.SlavePools.Where(sp => sp.IsAvailable).ToList()); - if (availables.Any()) { - isSlave = true; - pool = availables.Count == 1 ? availables[0] : availables[slaveRandom.Next(availables.Count)]; - } - } - } + public void ExecuteReader(Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(connection, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, readerHander, cmdType, cmdText, cmdParms); + public void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, readerHander, cmdType, cmdText, cmdParms); + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (dr, result) => readerHander(dr), cmdType, cmdText, cmdParms); + void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return; + var dt = DateTime.Now; + var logtxt = new StringBuilder(); + var logtxt_dt = DateTime.Now; + var pool = this.MasterPool; + var isSlave = false; - Object conn = null; - var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); - if (IsTracePerformance) logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - Exception ex = null; - try { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - if (isSlave) { - //从库查询切换,恢复 - bool isSlaveFail = false; - try { - if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = pool.Get()).Value; - //if (slaveRandom.Next(100) % 2 == 0) throw new Exception("测试从库抛出异常"); - } catch { - isSlaveFail = true; - } - if (isSlaveFail) { - if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); - } - LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); - pc.cmd.Parameters.Clear(); - ExecuteReaderMultiple(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); - return; - } - } else { - //主库查询 - if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = pool.Get()).Value; - } - if (IsTracePerformance) { - logtxt.Append("Open: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - logtxt_dt = DateTime.Now; - } - using (var dr = pc.cmd.ExecuteReader()) { - if (IsTracePerformance) logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - int resultIndex = 0; - while (true) { - while (true) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - bool isread = dr.Read(); - if (IsTracePerformance) logtxt.Append(" dr.Read: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - if (isread == false) break; + if (transaction == null && connection == null) + { + //读写分离规则 + if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) + { + var availables = slaveUnavailables == 0 ? + //查从库 + this.SlavePools : ( + //查主库 + slaveUnavailables == this.SlavePools.Count ? new List>() : + //查从库可用 + this.SlavePools.Where(sp => sp.IsAvailable).ToList()); + if (availables.Any()) + { + isSlave = true; + pool = availables.Count == 1 ? availables[0] : availables[slaveRandom.Next(availables.Count)]; + } + } + } - if (readerHander != null) { - object[] values = null; - if (IsTracePerformance) { - logtxt_dt = DateTime.Now; - values = new object[dr.FieldCount]; - dr.GetValues(values); - logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - logtxt_dt = DateTime.Now; - } - readerHander(dr, resultIndex); - if (IsTracePerformance) logtxt.Append(" readerHander: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n"); - } - } - if (++resultIndex >= multipleResult || dr.NextResult() == false) break; - } - if (IsTracePerformance) logtxt_dt = DateTime.Now; - dr.Close(); - } - if (IsTracePerformance) logtxt.Append("ExecuteReader_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - } catch (Exception ex2) { - ex = ex2; - } + Object conn = null; + var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + if (IsTracePerformance) logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + Exception ex = null; + try + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + if (isSlave) + { + //从库查询切换,恢复 + bool isSlaveFail = false; + try + { + if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = pool.Get()).Value; + //if (slaveRandom.Next(100) % 2 == 0) throw new Exception("测试从库抛出异常"); + } + catch + { + isSlaveFail = true; + } + if (isSlaveFail) + { + if (conn != null) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); + if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + } + LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); + pc.cmd.Parameters.Clear(); + ExecuteReaderMultiple(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); + return; + } + } + else + { + //主库查询 + if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = pool.Get()).Value; + } + if (IsTracePerformance) + { + logtxt.Append("Open: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt_dt = DateTime.Now; + } + using (var dr = pc.cmd.ExecuteReader()) + { + if (IsTracePerformance) logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + int resultIndex = 0; + while (true) + { + while (true) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + bool isread = dr.Read(); + if (IsTracePerformance) logtxt.Append(" dr.Read: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + if (isread == false) break; - if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); - } - LoggerException(pool, pc, ex, dt, logtxt); - pc.cmd.Parameters.Clear(); - } - public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, null, cmdType, cmdText, cmdParms); - public object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, transaction, cmdType, cmdText, cmdParms); - public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - List ret = new List(); - ExecuteReader(connection, transaction, dr => { - object[] values = new object[dr.FieldCount]; - dr.GetValues(values); - ret.Add(values); - }, cmdType, cmdText, cmdParms); - return ret.ToArray(); - } - public DataSet ExecuteDataSet(string cmdText, object parms = null) => ExecuteDataSet(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataSet ExecuteDataSet(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSet(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSet(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSet(null, null, cmdType, cmdText, cmdParms); - public DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSet(null, transaction, cmdType, cmdText, cmdParms); - public DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - var ret = new DataSet(); - DataTable dt = null; - ExecuteReaderMultiple(16, connection, transaction, (dr, result) => { - if (ret.Tables.Count <= result) { - dt = ret.Tables.Add(); - for (var a = 0; a < dr.FieldCount; a++) dt.Columns.Add(dr.GetName(a)); - } - object[] values = new object[dt.Columns.Count]; - dr.GetValues(values); - dt.Rows.Add(values); - }, cmdType, cmdText, cmdParms); - return ret; - } - public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataTable ExecuteDataTable(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, null, cmdType, cmdText, cmdParms); - public DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, transaction, cmdType, cmdText, cmdParms); - public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - var ret = new DataTable(); - ExecuteReader(connection, transaction, dr => { - if (ret.Columns.Count == 0) - for (var a = 0; a < dr.FieldCount; a++) ret.Columns.Add(dr.GetName(a)); - object[] values = new object[ret.Columns.Count]; - dr.GetValues(values); - ret.Rows.Add(values); - }, cmdType, cmdText, cmdParms); - return ret; - } - public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public int ExecuteNonQuery(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, null, cmdType, cmdText, cmdParms); - public int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, transaction, cmdType, cmdText, cmdParms); - public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return 0; - var dt = DateTime.Now; - var logtxt = new StringBuilder(); - var logtxt_dt = DateTime.Now; - Object conn = null; - var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); - int val = 0; - Exception ex = null; - try { - if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = this.MasterPool.Get()).Value; - val = pc.cmd.ExecuteNonQuery(); - } catch (Exception ex2) { - ex = ex2; - } + if (readerHander != null) + { + object[] values = null; + if (IsTracePerformance) + { + logtxt_dt = DateTime.Now; + values = new object[dr.FieldCount]; + dr.GetValues(values); + logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt_dt = DateTime.Now; + } + readerHander(dr, resultIndex); + if (IsTracePerformance) logtxt.Append(" readerHander: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n"); + } + } + if (++resultIndex >= multipleResult || dr.NextResult() == false) break; + } + if (IsTracePerformance) logtxt_dt = DateTime.Now; + dr.Close(); + } + if (IsTracePerformance) logtxt.Append("ExecuteReader_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + } + catch (Exception ex2) + { + ex = ex2; + } - if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); - } - LoggerException(this.MasterPool, pc, ex, dt, logtxt); - pc.cmd.Parameters.Clear(); - return val; - } - public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object ExecuteScalar(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object ExecuteScalar(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, null, cmdType, cmdText, cmdParms); - public object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, transaction, cmdType, cmdText, cmdParms); - public object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return null; - var dt = DateTime.Now; - var logtxt = new StringBuilder(); - var logtxt_dt = DateTime.Now; - Object conn = null; - var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); - object val = null; - Exception ex = null; - try { - if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = this.MasterPool.Get()).Value; - val = pc.cmd.ExecuteScalar(); - } catch (Exception ex2) { - ex = ex2; - } + if (conn != null) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); + if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + } + LoggerException(pool, pc, ex, dt, logtxt); + pc.cmd.Parameters.Clear(); + } + public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, null, cmdType, cmdText, cmdParms); + public object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, transaction, cmdType, cmdText, cmdParms); + public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + List ret = new List(); + ExecuteReader(connection, transaction, dr => + { + object[] values = new object[dr.FieldCount]; + dr.GetValues(values); + ret.Add(values); + }, cmdType, cmdText, cmdParms); + return ret.ToArray(); + } + public DataSet ExecuteDataSet(string cmdText, object parms = null) => ExecuteDataSet(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public DataSet ExecuteDataSet(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSet(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSet(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSet(null, null, cmdType, cmdText, cmdParms); + public DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSet(null, transaction, cmdType, cmdText, cmdParms); + public DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + var ret = new DataSet(); + DataTable dt = null; + ExecuteReaderMultiple(16, connection, transaction, (dr, result) => + { + if (ret.Tables.Count <= result) + { + dt = ret.Tables.Add(); + for (var a = 0; a < dr.FieldCount; a++) dt.Columns.Add(dr.GetName(a)); + } + object[] values = new object[dt.Columns.Count]; + dr.GetValues(values); + dt.Rows.Add(values); + }, cmdType, cmdText, cmdParms); + return ret; + } + public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public DataTable ExecuteDataTable(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, null, cmdType, cmdText, cmdParms); + public DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, transaction, cmdType, cmdText, cmdParms); + public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + var ret = new DataTable(); + ExecuteReader(connection, transaction, dr => + { + if (ret.Columns.Count == 0) + for (var a = 0; a < dr.FieldCount; a++) ret.Columns.Add(dr.GetName(a)); + object[] values = new object[ret.Columns.Count]; + dr.GetValues(values); + ret.Rows.Add(values); + }, cmdType, cmdText, cmdParms); + return ret; + } + public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public int ExecuteNonQuery(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, null, cmdType, cmdText, cmdParms); + public int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, transaction, cmdType, cmdText, cmdParms); + public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return 0; + var dt = DateTime.Now; + var logtxt = new StringBuilder(); + var logtxt_dt = DateTime.Now; + Object conn = null; + var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + int val = 0; + Exception ex = null; + try + { + if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = this.MasterPool.Get()).Value; + val = pc.cmd.ExecuteNonQuery(); + } + catch (Exception ex2) + { + ex = ex2; + } - if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); - } - LoggerException(this.MasterPool, pc, ex, dt, logtxt); - pc.cmd.Parameters.Clear(); - return val; - } + if (conn != null) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); + if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + } + LoggerException(this.MasterPool, pc, ex, dt, logtxt); + pc.cmd.Parameters.Clear(); + return val; + } + public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public object ExecuteScalar(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public object ExecuteScalar(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, null, cmdType, cmdText, cmdParms); + public object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, transaction, cmdType, cmdText, cmdParms); + public object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return null; + var dt = DateTime.Now; + var logtxt = new StringBuilder(); + var logtxt_dt = DateTime.Now; + Object conn = null; + var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + object val = null; + Exception ex = null; + try + { + if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = this.MasterPool.Get()).Value; + val = pc.cmd.ExecuteScalar(); + } + catch (Exception ex2) + { + ex = ex2; + } - (DbCommand cmd, bool isclose) PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { - var dt = DateTime.Now; - DbCommand cmd = CreateCommand(); - bool isclose = false; - cmd.CommandType = cmdType; - cmd.CommandText = cmdText; + if (conn != null) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); + if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + } + LoggerException(this.MasterPool, pc, ex, dt, logtxt); + pc.cmd.Parameters.Clear(); + return val; + } - if (cmdParms != null) { - foreach (var parm in cmdParms) { - if (parm == null) continue; - if (parm.Value == null) parm.Value = DBNull.Value; - cmd.Parameters.Add(parm); - } - } + (DbCommand cmd, bool isclose) PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) + { + var dt = DateTime.Now; + DbCommand cmd = CreateCommand(); + bool isclose = false; + cmd.CommandType = cmdType; + cmd.CommandText = cmdText; - if (connection == null) { - var tran = transaction ?? TransactionCurrentThread; - if (IsTracePerformance) logtxt.Append(" PrepareCommand_part1: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); + if (cmdParms != null) + { + foreach (var parm in cmdParms) + { + if (parm == null) continue; + if (parm.Value == null) parm.Value = DBNull.Value; + cmd.Parameters.Add(parm); + } + } - if (tran != null && connection == null) { - if (IsTracePerformance) dt = DateTime.Now; - cmd.Connection = tran.Connection; - cmd.Transaction = tran; - if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - } - } else { - if (connection.State != ConnectionState.Open) { - if (IsTracePerformance) dt = DateTime.Now; - connection.Open(); - if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpen: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - isclose = true; - } - cmd.Connection = connection; - if (transaction?.Connection == connection) - cmd.Transaction = transaction; - } + if (connection == null) + { + var tran = transaction ?? TransactionCurrentThread; + if (IsTracePerformance) logtxt.Append(" PrepareCommand_part1: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); - if (IsTracePerformance) dt = DateTime.Now; - AutoCommitTransaction(); - if (IsTracePerformance) logtxt.Append(" AutoCommitTransaction: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + if (tran != null && connection == null) + { + if (IsTracePerformance) dt = DateTime.Now; + cmd.Connection = tran.Connection; + cmd.Transaction = tran; + if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + } + } + else + { + if (connection.State != ConnectionState.Open) + { + if (IsTracePerformance) dt = DateTime.Now; + connection.Open(); + if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpen: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + isclose = true; + } + cmd.Connection = connection; + if (transaction?.Connection == connection) + cmd.Transaction = transaction; + } - AopCommandExecuting?.Invoke(cmd); - return (cmd, isclose); - } - } + if (IsTracePerformance) dt = DateTime.Now; + AutoCommitTransaction(); + if (IsTracePerformance) logtxt.Append(" AutoCommitTransaction: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + + AopCommandExecuting?.Invoke(cmd); + return (cmd, isclose); + } + } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 956ac42b..4a672d94 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -7,632 +7,725 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { - partial class AdoProvider { - public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - var ret = new List(); - if (string.IsNullOrEmpty(cmdText)) return ret; - var type = typeof(T); - string flag = null; - int[] indexes = null; - var props = GetQueryTypeProperties(type); - await ExecuteReaderAsync(connection, transaction, dr => { - if (indexes == null) { - var sbflag = new StringBuilder().Append("query"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes = props.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag = sbflag.ToString(); - } - ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); - return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); - return ret; - } - #region QueryAsync multi - public Task<(List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task<(List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List()); - var ret1 = new List(); - var type1 = typeof(T1); - string flag1 = null; - int[] indexes1 = null; - var props1 = GetQueryTypeProperties(type1); +namespace FreeSql.Internal.CommonProvider +{ + partial class AdoProvider + { + public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + var ret = new List(); + if (string.IsNullOrEmpty(cmdText)) return ret; + var type = typeof(T); + string flag = null; + int[] indexes = null; + var props = GetQueryTypeProperties(type); + await ExecuteReaderAsync(connection, transaction, dr => + { + if (indexes == null) + { + var sbflag = new StringBuilder().Append("query"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes = props.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag = sbflag.ToString(); + } + ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); + return Task.FromResult(false); + }, cmdType, cmdText, cmdParms); + return ret; + } + #region QueryAsync multi + public Task<(List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task<(List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return (new List(), new List()); + var ret1 = new List(); + var type1 = typeof(T1); + string flag1 = null; + int[] indexes1 = null; + var props1 = GetQueryTypeProperties(type1); - var ret2 = new List(); - var type2 = typeof(T2); - string flag2 = null; - int[] indexes2 = null; - var props2 = GetQueryTypeProperties(type2); - await ExecuteReaderMultipleAsync(2, connection, transaction, (dr, result) => { - switch (result) { - case 0: - if (indexes1 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag1 = sbflag.ToString(); - } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); - break; - case 1: - if (indexes2 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag2 = sbflag.ToString(); - } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); - break; - } - return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); - return (ret1, ret2); - } + var ret2 = new List(); + var type2 = typeof(T2); + string flag2 = null; + int[] indexes2 = null; + var props2 = GetQueryTypeProperties(type2); + await ExecuteReaderMultipleAsync(2, connection, transaction, (dr, result) => + { + switch (result) + { + case 0: + if (indexes1 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag1 = sbflag.ToString(); + } + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + break; + case 1: + if (indexes2 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag2 = sbflag.ToString(); + } + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + break; + } + return Task.FromResult(false); + }, cmdType, cmdText, cmdParms); + return (ret1, ret2); + } - public Task<(List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task<(List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List()); - var ret1 = new List(); - var type1 = typeof(T1); - string flag1 = null; - int[] indexes1 = null; - var props1 = GetQueryTypeProperties(type1); + public Task<(List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task<(List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List()); + var ret1 = new List(); + var type1 = typeof(T1); + string flag1 = null; + int[] indexes1 = null; + var props1 = GetQueryTypeProperties(type1); - var ret2 = new List(); - var type2 = typeof(T2); - string flag2 = null; - int[] indexes2 = null; - var props2 = GetQueryTypeProperties(type2); + var ret2 = new List(); + var type2 = typeof(T2); + string flag2 = null; + int[] indexes2 = null; + var props2 = GetQueryTypeProperties(type2); - var ret3 = new List(); - var type3 = typeof(T3); - string flag3 = null; - int[] indexes3 = null; - var props3 = GetQueryTypeProperties(type3); - await ExecuteReaderMultipleAsync(3, connection, transaction, (dr, result) => { - switch (result) { - case 0: - if (indexes1 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag1 = sbflag.ToString(); - } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); - break; - case 1: - if (indexes2 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag2 = sbflag.ToString(); - } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); - break; - case 2: - if (indexes3 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag3 = sbflag.ToString(); - } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); - break; - } - return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3); - } + var ret3 = new List(); + var type3 = typeof(T3); + string flag3 = null; + int[] indexes3 = null; + var props3 = GetQueryTypeProperties(type3); + await ExecuteReaderMultipleAsync(3, connection, transaction, (dr, result) => + { + switch (result) + { + case 0: + if (indexes1 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag1 = sbflag.ToString(); + } + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + break; + case 1: + if (indexes2 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag2 = sbflag.ToString(); + } + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + break; + case 2: + if (indexes3 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag3 = sbflag.ToString(); + } + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + break; + } + return Task.FromResult(false); + }, cmdType, cmdText, cmdParms); + return (ret1, ret2, ret3); + } - public Task<(List, List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List()); - var ret1 = new List(); - var type1 = typeof(T1); - string flag1 = null; - int[] indexes1 = null; - var props1 = GetQueryTypeProperties(type1); + public Task<(List, List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List()); + var ret1 = new List(); + var type1 = typeof(T1); + string flag1 = null; + int[] indexes1 = null; + var props1 = GetQueryTypeProperties(type1); - var ret2 = new List(); - var type2 = typeof(T2); - string flag2 = null; - int[] indexes2 = null; - var props2 = GetQueryTypeProperties(type2); + var ret2 = new List(); + var type2 = typeof(T2); + string flag2 = null; + int[] indexes2 = null; + var props2 = GetQueryTypeProperties(type2); - var ret3 = new List(); - var type3 = typeof(T3); - string flag3 = null; - int[] indexes3 = null; - var props3 = GetQueryTypeProperties(type3); + var ret3 = new List(); + var type3 = typeof(T3); + string flag3 = null; + int[] indexes3 = null; + var props3 = GetQueryTypeProperties(type3); - var ret4 = new List(); - var type4 = typeof(T4); - string flag4 = null; - int[] indexes4 = null; - var props4 = GetQueryTypeProperties(type4); - await ExecuteReaderMultipleAsync(4, connection, transaction, (dr, result) => { - switch (result) { - case 0: - if (indexes1 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag1 = sbflag.ToString(); - } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); - break; - case 1: - if (indexes2 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag2 = sbflag.ToString(); - } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); - break; - case 2: - if (indexes3 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag3 = sbflag.ToString(); - } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); - break; - case 3: - if (indexes4 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag4 = sbflag.ToString(); - } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); - break; - } - return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3, ret4); - } + var ret4 = new List(); + var type4 = typeof(T4); + string flag4 = null; + int[] indexes4 = null; + var props4 = GetQueryTypeProperties(type4); + await ExecuteReaderMultipleAsync(4, connection, transaction, (dr, result) => + { + switch (result) + { + case 0: + if (indexes1 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag1 = sbflag.ToString(); + } + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + break; + case 1: + if (indexes2 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag2 = sbflag.ToString(); + } + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + break; + case 2: + if (indexes3 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag3 = sbflag.ToString(); + } + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + break; + case 3: + if (indexes4 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag4 = sbflag.ToString(); + } + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + break; + } + return Task.FromResult(false); + }, cmdType, cmdText, cmdParms); + return (ret1, ret2, ret3, ret4); + } - public Task<(List, List, List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List(), new List()); - var ret1 = new List(); - var type1 = typeof(T1); - string flag1 = null; - int[] indexes1 = null; - var props1 = GetQueryTypeProperties(type1); + public Task<(List, List, List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task<(List, List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List(), new List()); + var ret1 = new List(); + var type1 = typeof(T1); + string flag1 = null; + int[] indexes1 = null; + var props1 = GetQueryTypeProperties(type1); - var ret2 = new List(); - var type2 = typeof(T2); - string flag2 = null; - int[] indexes2 = null; - var props2 = GetQueryTypeProperties(type2); + var ret2 = new List(); + var type2 = typeof(T2); + string flag2 = null; + int[] indexes2 = null; + var props2 = GetQueryTypeProperties(type2); - var ret3 = new List(); - var type3 = typeof(T3); - string flag3 = null; - int[] indexes3 = null; - var props3 = GetQueryTypeProperties(type3); + var ret3 = new List(); + var type3 = typeof(T3); + string flag3 = null; + int[] indexes3 = null; + var props3 = GetQueryTypeProperties(type3); - var ret4 = new List(); - var type4 = typeof(T4); - string flag4 = null; - int[] indexes4 = null; - var props4 = GetQueryTypeProperties(type4); + var ret4 = new List(); + var type4 = typeof(T4); + string flag4 = null; + int[] indexes4 = null; + var props4 = GetQueryTypeProperties(type4); - var ret5 = new List(); - var type5 = typeof(T5); - string flag5 = null; - int[] indexes5 = null; - var props5 = GetQueryTypeProperties(type5); - await ExecuteReaderMultipleAsync(5, connection, transaction, (dr, result) => { - switch (result) { - case 0: - if (indexes1 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag1 = sbflag.ToString(); - } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); - break; - case 1: - if (indexes2 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag2 = sbflag.ToString(); - } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); - break; - case 2: - if (indexes3 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag3 = sbflag.ToString(); - } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); - break; - case 3: - if (indexes4 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag4 = sbflag.ToString(); - } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); - break; - case 4: - if (indexes5 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); - var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) { - var name = dr.GetName(a); - sbflag.Append(name).Append(":").Append(a).Append(","); - dic.Add(name, a); - } - indexes5 = props5.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); - flag5 = sbflag.ToString(); - } - ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); - break; - } - return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3, ret4, ret5); - } - #endregion + var ret5 = new List(); + var type5 = typeof(T5); + string flag5 = null; + int[] indexes5 = null; + var props5 = GetQueryTypeProperties(type5); + await ExecuteReaderMultipleAsync(5, connection, transaction, (dr, result) => + { + switch (result) + { + case 0: + if (indexes1 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag1 = sbflag.ToString(); + } + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + break; + case 1: + if (indexes2 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag2 = sbflag.ToString(); + } + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + break; + case 2: + if (indexes3 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag3 = sbflag.ToString(); + } + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + break; + case 3: + if (indexes4 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag4 = sbflag.ToString(); + } + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + break; + case 4: + if (indexes5 == null) + { + var sbflag = new StringBuilder().Append("QueryAsync"); + var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + sbflag.Append(name).Append(":").Append(a).Append(","); + dic.Add(name, a); + } + indexes5 = props5.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); + flag5 = sbflag.ToString(); + } + ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); + break; + } + return Task.FromResult(false); + }, cmdType, cmdText, cmdParms); + return (ret1, ret2, ret3, ret4, ret5); + } + #endregion - public Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, readerHander, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, readerHander, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (dr, result) => readerHander(dr), cmdType, cmdText, cmdParms); - async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return; - var dt = DateTime.Now; - var logtxt = new StringBuilder(); - var logtxt_dt = DateTime.Now; - var pool = this.MasterPool; - var isSlave = false; + public Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, readerHander, cmdType, cmdText, cmdParms); + public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, readerHander, cmdType, cmdText, cmdParms); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (dr, result) => readerHander(dr), cmdType, cmdText, cmdParms); + async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return; + var dt = DateTime.Now; + var logtxt = new StringBuilder(); + var logtxt_dt = DateTime.Now; + var pool = this.MasterPool; + var isSlave = false; - if (transaction == null && connection == null) { - //读写分离规则 - if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) { - var availables = slaveUnavailables == 0 ? - //查从库 - this.SlavePools : ( - //查主库 - slaveUnavailables == this.SlavePools.Count ? new List>() : - //查从库可用 - this.SlavePools.Where(sp => sp.IsAvailable).ToList()); - if (availables.Any()) { - isSlave = true; - pool = availables.Count == 1 ? this.SlavePools[0] : availables[slaveRandom.Next(availables.Count)]; - } - } - } + if (transaction == null && connection == null) + { + //读写分离规则 + if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) + { + var availables = slaveUnavailables == 0 ? + //查从库 + this.SlavePools : ( + //查主库 + slaveUnavailables == this.SlavePools.Count ? new List>() : + //查从库可用 + this.SlavePools.Where(sp => sp.IsAvailable).ToList()); + if (availables.Any()) + { + isSlave = true; + pool = availables.Count == 1 ? this.SlavePools[0] : availables[slaveRandom.Next(availables.Count)]; + } + } + } - Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); - if (IsTracePerformance) logtxt.Append("PrepareCommandAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - Exception ex = null; - try { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - if (isSlave) { - //从库查询切换,恢复 - bool isSlaveFail = false; - try { - if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await pool.GetAsync()).Value; - //if (slaveRandom.Next(100) % 2 == 0) throw new Exception("测试从库抛出异常"); - } catch { - isSlaveFail = true; - } - if (isSlaveFail) { - if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); - } - LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); - pc.cmd.Parameters.Clear(); - await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); - return; - } - } else { - //主库查询 - if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await pool.GetAsync()).Value; - } - if (IsTracePerformance) { - logtxt.Append("OpenAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - logtxt_dt = DateTime.Now; - } - using (var dr = await pc.cmd.ExecuteReaderAsync()) { - if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - int resultIndex = 0; - while (true) { - while (true) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - bool isread = await dr.ReadAsync(); - if (IsTracePerformance) logtxt.Append(" dr.ReadAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - if (isread == false) break; + Object conn = null; + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + if (IsTracePerformance) logtxt.Append("PrepareCommandAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + Exception ex = null; + try + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + if (isSlave) + { + //从库查询切换,恢复 + bool isSlaveFail = false; + try + { + if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await pool.GetAsync()).Value; + //if (slaveRandom.Next(100) % 2 == 0) throw new Exception("测试从库抛出异常"); + } + catch + { + isSlaveFail = true; + } + if (isSlaveFail) + { + if (conn != null) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); + if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + } + LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); + pc.cmd.Parameters.Clear(); + await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); + return; + } + } + else + { + //主库查询 + if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await pool.GetAsync()).Value; + } + if (IsTracePerformance) + { + logtxt.Append("OpenAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt_dt = DateTime.Now; + } + using (var dr = await pc.cmd.ExecuteReaderAsync()) + { + if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + int resultIndex = 0; + while (true) + { + while (true) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + bool isread = await dr.ReadAsync(); + if (IsTracePerformance) logtxt.Append(" dr.ReadAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + if (isread == false) break; - if (readerHander != null) { - object[] values = null; - if (IsTracePerformance) { - logtxt_dt = DateTime.Now; - values = new object[dr.FieldCount]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); - logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - logtxt_dt = DateTime.Now; - } - await readerHander(dr, resultIndex); - if (IsTracePerformance) logtxt.Append(" readerHanderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n"); - } - } - if (++resultIndex >= multipleResult || dr.NextResult() == false) break; - } - if (IsTracePerformance) logtxt_dt = DateTime.Now; - dr.Close(); - } - if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - } catch (Exception ex2) { - ex = ex2; - } + if (readerHander != null) + { + object[] values = null; + if (IsTracePerformance) + { + logtxt_dt = DateTime.Now; + values = new object[dr.FieldCount]; + for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt_dt = DateTime.Now; + } + await readerHander(dr, resultIndex); + if (IsTracePerformance) logtxt.Append(" readerHanderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n"); + } + } + if (++resultIndex >= multipleResult || dr.NextResult() == false) break; + } + if (IsTracePerformance) logtxt_dt = DateTime.Now; + dr.Close(); + } + if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + } + catch (Exception ex2) + { + ex = ex2; + } - if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); - } - LoggerException(pool, pc, ex, dt, logtxt); - pc.cmd.Parameters.Clear(); - } - public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - List ret = new List(); - await ExecuteReaderAsync(connection, transaction, async dr => { - object[] values = new object[dr.FieldCount]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); - ret.Add(values); - }, cmdType, cmdText, cmdParms); - return ret.ToArray(); - } + if (conn != null) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); + if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + } + LoggerException(pool, pc, ex, dt, logtxt); + pc.cmd.Parameters.Clear(); + } + public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, null, cmdType, cmdText, cmdParms); + public Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + List ret = new List(); + await ExecuteReaderAsync(connection, transaction, async dr => + { + object[] values = new object[dr.FieldCount]; + for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + ret.Add(values); + }, cmdType, cmdText, cmdParms); + return ret.ToArray(); + } - public Task ExecuteDataSetAsync(string cmdText, object parms = null) => ExecuteDataSetAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - var ret = new DataSet(); - DataTable dt = null; - await ExecuteReaderMultipleAsync(16, connection, transaction, async (dr, result) => { - if (ret.Tables.Count <= result) { - dt = ret.Tables.Add(); - for (var a = 0; a < dr.FieldCount; a++) dt.Columns.Add(dr.GetName(a)); - } - object[] values = new object[dt.Columns.Count]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); - dt.Rows.Add(values); - }, cmdType, cmdText, cmdParms); - return ret; - } - public Task ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - var ret = new DataTable(); - await ExecuteReaderAsync(connection, transaction, async dr => { - if (ret.Columns.Count == 0) - for (var a = 0; a < dr.FieldCount; a++) ret.Columns.Add(dr.GetName(a)); - object[] values = new object[ret.Columns.Count]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); - ret.Rows.Add(values); - }, cmdType, cmdText, cmdParms); - return ret; - } - public Task ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return 0; - var dt = DateTime.Now; - var logtxt = new StringBuilder(); - var logtxt_dt = DateTime.Now; - Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); - int val = 0; - Exception ex = null; - try { - if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await this.MasterPool.GetAsync()).Value; - val = await pc.cmd.ExecuteNonQueryAsync(); - } catch (Exception ex2) { - ex = ex2; - } + public Task ExecuteDataSetAsync(string cmdText, object parms = null) => ExecuteDataSetAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, null, cmdType, cmdText, cmdParms); + public Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + var ret = new DataSet(); + DataTable dt = null; + await ExecuteReaderMultipleAsync(16, connection, transaction, async (dr, result) => + { + if (ret.Tables.Count <= result) + { + dt = ret.Tables.Add(); + for (var a = 0; a < dr.FieldCount; a++) dt.Columns.Add(dr.GetName(a)); + } + object[] values = new object[dt.Columns.Count]; + for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + dt.Rows.Add(values); + }, cmdType, cmdText, cmdParms); + return ret; + } + public Task ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, null, cmdType, cmdText, cmdParms); + public Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + var ret = new DataTable(); + await ExecuteReaderAsync(connection, transaction, async dr => + { + if (ret.Columns.Count == 0) + for (var a = 0; a < dr.FieldCount; a++) ret.Columns.Add(dr.GetName(a)); + object[] values = new object[ret.Columns.Count]; + for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + ret.Rows.Add(values); + }, cmdType, cmdText, cmdParms); + return ret; + } + public Task ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return 0; + var dt = DateTime.Now; + var logtxt = new StringBuilder(); + var logtxt_dt = DateTime.Now; + Object conn = null; + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + int val = 0; + Exception ex = null; + try + { + if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await this.MasterPool.GetAsync()).Value; + val = await pc.cmd.ExecuteNonQueryAsync(); + } + catch (Exception ex2) + { + ex = ex2; + } - if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); - } - LoggerException(this.MasterPool, pc, ex, dt, logtxt); - pc.cmd.Parameters.Clear(); - return val; - } - public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return null; - var dt = DateTime.Now; - var logtxt = new StringBuilder(); - var logtxt_dt = DateTime.Now; - Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); - object val = null; - Exception ex = null; - try { - if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await this.MasterPool.GetAsync()).Value; - val = await pc.cmd.ExecuteScalarAsync(); - } catch (Exception ex2) { - ex = ex2; - } + if (conn != null) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); + if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + } + LoggerException(this.MasterPool, pc, ex, dt, logtxt); + pc.cmd.Parameters.Clear(); + return val; + } + public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, null, cmdType, cmdText, cmdParms); + public Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + { + if (string.IsNullOrEmpty(cmdText)) return null; + var dt = DateTime.Now; + var logtxt = new StringBuilder(); + var logtxt_dt = DateTime.Now; + Object conn = null; + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + object val = null; + Exception ex = null; + try + { + if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await this.MasterPool.GetAsync()).Value; + val = await pc.cmd.ExecuteScalarAsync(); + } + catch (Exception ex2) + { + ex = ex2; + } - if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; - ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); - } - LoggerException(this.MasterPool, pc, ex, dt, logtxt); - pc.cmd.Parameters.Clear(); - return val; - } + if (conn != null) + { + if (IsTracePerformance) logtxt_dt = DateTime.Now; + ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); + if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + } + LoggerException(this.MasterPool, pc, ex, dt, logtxt); + pc.cmd.Parameters.Clear(); + return val; + } - async Task<(DbCommand cmd, bool isclose)> PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { - DateTime dt = DateTime.Now; - DbCommand cmd = CreateCommand(); - bool isclose = false; - cmd.CommandType = cmdType; - cmd.CommandText = cmdText; + async Task<(DbCommand cmd, bool isclose)> PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) + { + DateTime dt = DateTime.Now; + DbCommand cmd = CreateCommand(); + bool isclose = false; + cmd.CommandType = cmdType; + cmd.CommandText = cmdText; - if (cmdParms != null) { - foreach (var parm in cmdParms) { - if (parm == null) continue; - if (parm.Value == null) parm.Value = DBNull.Value; - cmd.Parameters.Add(parm); - } - } + if (cmdParms != null) + { + foreach (var parm in cmdParms) + { + if (parm == null) continue; + if (parm.Value == null) parm.Value = DBNull.Value; + cmd.Parameters.Add(parm); + } + } - if (connection == null) { - var tran = transaction; + if (connection == null) + { + var tran = transaction; - if (tran != null) { - if (IsTracePerformance) dt = DateTime.Now; - cmd.Connection = tran.Connection; - cmd.Transaction = tran; - if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - } - } else { - if (connection.State != ConnectionState.Open) { - if (IsTracePerformance) dt = DateTime.Now; - await connection.OpenAsync(); - if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpenAsync: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - isclose = true; - } - cmd.Connection = connection; - if (transaction?.Connection == connection) - cmd.Transaction = transaction; - } + if (tran != null) + { + if (IsTracePerformance) dt = DateTime.Now; + cmd.Connection = tran.Connection; + cmd.Transaction = tran; + if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + } + } + else + { + if (connection.State != ConnectionState.Open) + { + if (IsTracePerformance) dt = DateTime.Now; + await connection.OpenAsync(); + if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpenAsync: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + isclose = true; + } + cmd.Connection = connection; + if (transaction?.Connection == connection) + cmd.Transaction = transaction; + } - if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); + if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); - AopCommandExecuting?.Invoke(cmd); - return (cmd, isclose); - } - } + AopCommandExecuting?.Invoke(cmd); + return (cmd, isclose); + } + } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index a6082fa9..9fb1b7c2 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -6,126 +6,158 @@ using System.Diagnostics; using System.Linq; using System.Threading; -namespace FreeSql.Internal.CommonProvider { - partial class AdoProvider { +namespace FreeSql.Internal.CommonProvider +{ + partial class AdoProvider + { - class Transaction2 { - internal Object Conn; - internal DbTransaction Transaction; - internal DateTime RunTime; - internal TimeSpan Timeout; + class Transaction2 + { + internal Object Conn; + internal DbTransaction Transaction; + internal DateTime RunTime; + internal TimeSpan Timeout; - public Transaction2(Object conn, DbTransaction tran, TimeSpan timeout) { - Conn = conn; - Transaction = tran; - RunTime = DateTime.Now; - Timeout = timeout; - } - } + public Transaction2(Object conn, DbTransaction tran, TimeSpan timeout) + { + Conn = conn; + Transaction = tran; + RunTime = DateTime.Now; + Timeout = timeout; + } + } - private Dictionary _trans = new Dictionary(); - private object _trans_lock = new object(); + private Dictionary _trans = new Dictionary(); + private object _trans_lock = new object(); - public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null; + public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null; - public void BeginTransaction(TimeSpan timeout) { - if (TransactionCurrentThread != null) return; + public void BeginTransaction(TimeSpan timeout) + { + if (TransactionCurrentThread != null) return; - int tid = Thread.CurrentThread.ManagedThreadId; - Transaction2 tran = null; - Object conn = null; + int tid = Thread.CurrentThread.ManagedThreadId; + Transaction2 tran = null; + Object conn = null; - try { - conn = MasterPool.Get(); - tran = new Transaction2(conn, conn.Value.BeginTransaction(), timeout); - } catch(Exception ex) { - Trace.WriteLine($"数据库出错(开启事务){ex.Message} \r\n{ex.StackTrace}"); - MasterPool.Return(conn); - throw ex; - } - if (_trans.ContainsKey(tid)) CommitTransaction(); + try + { + conn = MasterPool.Get(); + tran = new Transaction2(conn, conn.Value.BeginTransaction(), timeout); + } + catch (Exception ex) + { + Trace.WriteLine($"数据库出错(开启事务){ex.Message} \r\n{ex.StackTrace}"); + MasterPool.Return(conn); + throw ex; + } + if (_trans.ContainsKey(tid)) CommitTransaction(); - lock (_trans_lock) - _trans.Add(tid, tran); - } + lock (_trans_lock) + _trans.Add(tid, tran); + } - private void AutoCommitTransaction() { - if (_trans.Count > 0) { - Transaction2[] trans = null; - lock (_trans_lock) - trans = _trans.Values.Where(st2 => DateTime.Now.Subtract(st2.RunTime) > st2.Timeout).ToArray(); - foreach (Transaction2 tran in trans) CommitTransaction(true, tran); - } - } - private void CommitTransaction(bool isCommit, Transaction2 tran) { - if (tran == null || tran.Transaction == null || tran.Transaction.Connection == null) return; + private void AutoCommitTransaction() + { + if (_trans.Count > 0) + { + Transaction2[] trans = null; + lock (_trans_lock) + trans = _trans.Values.Where(st2 => DateTime.Now.Subtract(st2.RunTime) > st2.Timeout).ToArray(); + foreach (Transaction2 tran in trans) CommitTransaction(true, tran); + } + } + private void CommitTransaction(bool isCommit, Transaction2 tran) + { + if (tran == null || tran.Transaction == null || tran.Transaction.Connection == null) return; - if (_trans.ContainsKey(tran.Conn.LastGetThreadId)) - lock (_trans_lock) - if (_trans.ContainsKey(tran.Conn.LastGetThreadId)) - _trans.Remove(tran.Conn.LastGetThreadId); + if (_trans.ContainsKey(tran.Conn.LastGetThreadId)) + lock (_trans_lock) + if (_trans.ContainsKey(tran.Conn.LastGetThreadId)) + _trans.Remove(tran.Conn.LastGetThreadId); - Exception ex = null; - var f001 = isCommit ? "提交" : "回滚"; - try { - Trace.WriteLine($"线程{tran.Conn.LastGetThreadId}事务{f001}"); - if (isCommit) tran.Transaction.Commit(); - else tran.Transaction.Rollback(); - } catch (Exception ex2) { - ex = ex2; - Trace.WriteLine($"数据库出错({f001}事务):{ex.Message} {ex.StackTrace}"); - } finally { - ReturnConnection(MasterPool, tran.Conn, ex); //MasterPool.Return(tran.Conn, ex); - } - } - private void CommitTransaction(bool isCommit) { - if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(isCommit, tran); - } - public void CommitTransaction() => CommitTransaction(true); - public void RollbackTransaction() => CommitTransaction(false); + Exception ex = null; + var f001 = isCommit ? "提交" : "回滚"; + try + { + Trace.WriteLine($"线程{tran.Conn.LastGetThreadId}事务{f001}"); + if (isCommit) tran.Transaction.Commit(); + else tran.Transaction.Rollback(); + } + catch (Exception ex2) + { + ex = ex2; + Trace.WriteLine($"数据库出错({f001}事务):{ex.Message} {ex.StackTrace}"); + } + finally + { + ReturnConnection(MasterPool, tran.Conn, ex); //MasterPool.Return(tran.Conn, ex); + } + } + private void CommitTransaction(bool isCommit) + { + if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(isCommit, tran); + } + public void CommitTransaction() => CommitTransaction(true); + public void RollbackTransaction() => CommitTransaction(false); - public void Transaction(Action handler) { - Transaction(handler, TimeSpan.FromSeconds(60)); - } - public void Transaction(Action handler, TimeSpan timeout) { - try { - BeginTransaction(timeout); - handler(); - CommitTransaction(); - } catch (Exception ex) { - RollbackTransaction(); - throw ex; - } - } + public void Transaction(Action handler) + { + Transaction(handler, TimeSpan.FromSeconds(60)); + } + public void Transaction(Action handler, TimeSpan timeout) + { + try + { + BeginTransaction(timeout); + handler(); + CommitTransaction(); + } + catch (Exception ex) + { + RollbackTransaction(); + throw ex; + } + } - ~AdoProvider() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - Transaction2[] trans = null; - lock (_trans_lock) - trans = _trans.Values.ToArray(); - foreach (Transaction2 tran in trans) CommitTransaction(false, tran); - } catch { } + ~AdoProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + try + { + Transaction2[] trans = null; + lock (_trans_lock) + trans = _trans.Values.ToArray(); + foreach (Transaction2 tran in trans) CommitTransaction(false, tran); + } + catch { } - ObjectPool[] pools = null; - for (var a = 0; a < 10; a++) { - try { - pools = SlavePools.ToArray(); - SlavePools.Clear(); - break; - } catch { - } - } - if (pools != null) { - foreach (var pool in pools) { - try { pool.Dispose(); } catch { } - } - } - try { MasterPool.Dispose(); } catch { } - } - } + ObjectPool[] pools = null; + for (var a = 0; a < 10; a++) + { + try + { + pools = SlavePools.ToArray(); + SlavePools.Clear(); + break; + } + catch + { + } + } + if (pools != null) + { + foreach (var pool in pools) + { + try { pool.Dispose(); } catch { } + } + } + try { MasterPool.Dispose(); } catch { } + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs index c9b7311e..4d5aae64 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs @@ -2,21 +2,25 @@ using System.Collections.Concurrent; using System.Text.RegularExpressions; -namespace FreeSql.Internal.CommonProvider { - partial class AdoProvider { - public abstract object AddslashesProcessParam(object param, Type mapType); - public string Addslashes(string filter, params object[] parms) { - if (filter == null || parms == null) return string.Empty; - if (parms.Length == 0) return filter; - var nparms = new object[parms.Length]; - for (int a = 0; a < parms.Length; a++) { - if (parms[a] == null) - filter = _dicAddslashesReplaceIsNull.GetOrAdd(a, b => new Regex(@"\s*(=|IN)\s*\{" + b + @"\}", RegexOptions.IgnoreCase | RegexOptions.Compiled)) - .Replace(filter, $" IS {{{a}}}"); - nparms[a] = AddslashesProcessParam(parms[a], null); - } - try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; } - } - static ConcurrentDictionary _dicAddslashesReplaceIsNull = new ConcurrentDictionary(); - } +namespace FreeSql.Internal.CommonProvider +{ + partial class AdoProvider + { + public abstract object AddslashesProcessParam(object param, Type mapType); + public string Addslashes(string filter, params object[] parms) + { + if (filter == null || parms == null) return string.Empty; + if (parms.Length == 0) return filter; + var nparms = new object[parms.Length]; + for (int a = 0; a < parms.Length; a++) + { + if (parms[a] == null) + filter = _dicAddslashesReplaceIsNull.GetOrAdd(a, b => new Regex(@"\s*(=|IN)\s*\{" + b + @"\}", RegexOptions.IgnoreCase | RegexOptions.Compiled)) + .Replace(filter, $" IS {{{a}}}"); + nparms[a] = AddslashesProcessParam(parms[a], null); + } + try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; } + } + static ConcurrentDictionary _dicAddslashesReplaceIsNull = new ConcurrentDictionary(); + } } diff --git a/FreeSql/Internal/CommonProvider/AopProvider.cs b/FreeSql/Internal/CommonProvider/AopProvider.cs index bf49f3ba..3f6d15b2 100644 --- a/FreeSql/Internal/CommonProvider/AopProvider.cs +++ b/FreeSql/Internal/CommonProvider/AopProvider.cs @@ -4,16 +4,18 @@ using System.Collections.Generic; using System.Linq.Expressions; using System.Text; -namespace FreeSql.Internal.CommonProvider { - public class AopProvider : IAop { - public EventHandler ToList { get; set; } - public EventHandler Where { get; set; } - public EventHandler ParseExpression { get; set; } - public EventHandler ConfigEntity { get; set; } - public EventHandler ConfigEntityProperty { get; set; } - public EventHandler CurdBefore { get; set; } - public EventHandler CurdAfter { get; set; } - public EventHandler SyncStructureBefore { get; set; } - public EventHandler SyncStructureAfter { get; set; } - } +namespace FreeSql.Internal.CommonProvider +{ + public class AopProvider : IAop + { + public EventHandler ToList { get; set; } + public EventHandler Where { get; set; } + public EventHandler ParseExpression { get; set; } + public EventHandler ConfigEntity { get; set; } + public EventHandler ConfigEntityProperty { get; set; } + public EventHandler CurdBefore { get; set; } + public EventHandler CurdAfter { get; set; } + public EventHandler SyncStructureBefore { get; set; } + public EventHandler SyncStructureAfter { get; set; } + } } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 6f611883..e7edfceb 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -11,65 +11,76 @@ using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract partial class CodeFirstProvider : ICodeFirst { + public abstract partial class CodeFirstProvider : ICodeFirst + { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public CodeFirstProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } + protected IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public CodeFirstProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } - public bool IsAutoSyncStructure { get; set; } = false; - public bool IsSyncStructureToLower { get; set; } = false; - public bool IsSyncStructureToUpper { get; set; } = false; - public bool IsConfigEntityFromDbFirst { get; set; } = false; - public bool IsNoneCommandParameter { get; set; } = false; - public bool IsLazyLoading { get; set; } = false; + public bool IsAutoSyncStructure { get; set; } = false; + public bool IsSyncStructureToLower { get; set; } = false; + public bool IsSyncStructureToUpper { get; set; } = false; + public bool IsConfigEntityFromDbFirst { get; set; } = false; + public bool IsNoneCommandParameter { get; set; } = false; + public bool IsLazyLoading { get; set; } = false; - public abstract (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); + public abstract (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); - public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); - public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); - public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); - public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); + public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); + public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); + public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); + public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); - public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); - public abstract string GetComparisonDDLStatements(params Type[] entityTypes); + public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); + public abstract string GetComparisonDDLStatements(params Type[] entityTypes); - static object syncStructureLock = new object(); - internal ConcurrentDictionary dicSyced = new ConcurrentDictionary(); - public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); - public bool SyncStructure(params Type[] entityTypes) { - if (entityTypes == null) return false; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray(); - if (syncTypes.Any() == false) return false; - var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); - _orm.Aop.SyncStructureBefore?.Invoke(this, before); - Exception exception = null; - string ddl = null; - try { - lock (syncStructureLock) { - ddl = this.GetComparisonDDLStatements(syncTypes); - if (string.IsNullOrEmpty(ddl)) { - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return true; - } - var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return affrows > 0; - } - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); - _orm.Aop.SyncStructureAfter?.Invoke(this, after); - } - } - } + static object syncStructureLock = new object(); + internal ConcurrentDictionary dicSyced = new ConcurrentDictionary(); + public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); + public bool SyncStructure(params Type[] entityTypes) + { + if (entityTypes == null) return false; + var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray(); + if (syncTypes.Any() == false) return false; + var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); + _orm.Aop.SyncStructureBefore?.Invoke(this, before); + Exception exception = null; + string ddl = null; + try + { + lock (syncStructureLock) + { + ddl = this.GetComparisonDDLStatements(syncTypes); + if (string.IsNullOrEmpty(ddl)) + { + foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); + return true; + } + var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); + foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); + return affrows > 0; + } + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); + _orm.Aop.SyncStructureAfter?.Invoke(this, after); + } + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 43753aa4..e21168c1 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -7,119 +7,140 @@ using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract partial class DeleteProvider : IDelete where T1 : class { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected TableInfo _table; - protected Func _tableRule; - protected StringBuilder _where = new StringBuilder(); - protected int _whereTimes = 0; - protected List _params = new List(); - protected DbTransaction _transaction; - protected DbConnection _connection; + public abstract partial class DeleteProvider : IDelete where T1 : class + { + protected IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + protected TableInfo _table; + protected Func _tableRule; + protected StringBuilder _where = new StringBuilder(); + protected int _whereTimes = 0; + protected List _params = new List(); + protected DbTransaction _transaction; + protected DbConnection _connection; - public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - _table = _commonUtils.GetTableByEntity(typeof(T1)); - this.Where(_commonUtils.WhereObject(_table, "", dywhere)); - if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); - } + public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + _table = _commonUtils.GetTableByEntity(typeof(T1)); + this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + } - protected void ClearData() { - _where.Clear(); - _whereTimes = 0; - _params.Clear(); - } + protected void ClearData() + { + _where.Clear(); + _whereTimes = 0; + _params.Clear(); + } - public IDelete WithTransaction(DbTransaction transaction) { - _transaction = transaction; - _connection = _transaction?.Connection; - return this; - } - public IDelete WithConnection(DbConnection connection) { - if (_transaction?.Connection != connection) _transaction = null; - _connection = connection; - return this; - } + public IDelete WithTransaction(DbTransaction transaction) + { + _transaction = transaction; + _connection = _transaction?.Connection; + return this; + } + public IDelete WithConnection(DbConnection connection) + { + if (_transaction?.Connection != connection) _transaction = null; + _connection = connection; + return this; + } - public int ExecuteAffrows() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return affrows; - } - async public Task ExecuteAffrowsAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return affrows; - } - public abstract List ExecuteDeleted(); - public abstract Task> ExecuteDeletedAsync(); + public int ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return affrows; + } + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return affrows; + } + public abstract List ExecuteDeleted(); + public abstract Task> ExecuteDeletedAsync(); - public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null)); - public IDelete Where(string sql, object parms = null) { - if (string.IsNullOrEmpty(sql)) return this; - var args = new Aop.WhereEventArgs(sql, parms); - _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); - if (args.IsCancel == true) return this; + public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null)); + public IDelete Where(string sql, object parms = null) + { + if (string.IsNullOrEmpty(sql)) return this; + var args = new Aop.WhereEventArgs(sql, parms); + _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); + if (args.IsCancel == true) return this; - if (++_whereTimes > 1) _where.Append(" AND "); - _where.Append("(").Append(sql).Append(")"); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this; - } - public IDelete Where(T1 item) => this.Where(new[] { item }); - public IDelete Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); - public IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); - public IDelete WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + if (++_whereTimes > 1) _where.Append(" AND "); + _where.Append("(").Append(sql).Append(")"); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this; + } + public IDelete Where(T1 item) => this.Where(new[] { item }); + public IDelete Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); + public IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); + public IDelete WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); - public IDelete AsTable(Func tableRule) { - _tableRule = tableRule; - return this; - } - public IDelete AsType(Type entityType) { - if (entityType == typeof(object)) throw new Exception("IDelete.AsType 参数不支持指定为 object"); - if (entityType == _table.Type) return this; - var newtb = _commonUtils.GetTableByEntity(entityType); - _table = newtb ?? throw new Exception("IDelete.AsType 参数错误,请传入正确的实体类型"); - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); - return this; - } + public IDelete AsTable(Func tableRule) + { + _tableRule = tableRule; + return this; + } + public IDelete AsType(Type entityType) + { + if (entityType == typeof(object)) throw new Exception("IDelete.AsType 参数不支持指定为 object"); + if (entityType == _table.Type) return this; + var newtb = _commonUtils.GetTableByEntity(entityType); + _table = newtb ?? throw new Exception("IDelete.AsType 参数错误,请传入正确的实体类型"); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); + return this; + } - public string ToSql() => _whereTimes <= 0 ? null : new StringBuilder().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append(" WHERE ").Append(_where).ToString(); - } + public string ToSql() => _whereTimes <= 0 ? null : new StringBuilder().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append(" WHERE ").Append(_where).ToString(); + } } diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 9ebdc0ed..f3363db3 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -9,436 +9,545 @@ using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract partial class InsertProvider : IInsert where T1 : class { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected List _source = new List(); - protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - protected TableInfo _table; - protected Func _tableRule; - protected bool _noneParameter; - protected DbParameter[] _params; - protected DbTransaction _transaction; - protected DbConnection _connection; + public abstract partial class InsertProvider : IInsert where T1 : class + { + protected IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + protected List _source = new List(); + protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + protected TableInfo _table; + protected Func _tableRule; + protected bool _noneParameter; + protected DbParameter[] _params; + protected DbTransaction _transaction; + protected DbConnection _connection; - public InsertProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - _table = _commonUtils.GetTableByEntity(typeof(T1)); - _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; - if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); - } + public InsertProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + _table = _commonUtils.GetTableByEntity(typeof(T1)); + _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; + if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + } - protected void ClearData() { - _source.Clear(); - _ignore.Clear(); - _params = null; - } + protected void ClearData() + { + _source.Clear(); + _ignore.Clear(); + _params = null; + } - public IInsert WithTransaction(DbTransaction transaction) { - _transaction = transaction; - _connection = _transaction?.Connection; - return this; - } - public IInsert WithConnection(DbConnection connection) { - if (_transaction?.Connection != connection) _transaction = null; - _connection = connection; - return this; - } + public IInsert WithTransaction(DbTransaction transaction) + { + _transaction = transaction; + _connection = _transaction?.Connection; + return this; + } + public IInsert WithConnection(DbConnection connection) + { + if (_transaction?.Connection != connection) _transaction = null; + _connection = connection; + return this; + } - public IInsert NoneParameter() { - _noneParameter = true; - return this; - } + public IInsert NoneParameter() + { + _noneParameter = true; + return this; + } - public IInsert AppendData(T1 source) { - if (source != null) _source.Add(source); - return this; - } - public IInsert AppendData(T1[] source) { - if (source != null) _source.AddRange(source); - return this; - } - public IInsert AppendData(IEnumerable source) { - if (source != null) _source.AddRange(source.Where(a => a != null)); - return this; - } + public IInsert AppendData(T1 source) + { + if (source != null) _source.Add(source); + return this; + } + public IInsert AppendData(T1[] source) + { + if (source != null) _source.AddRange(source); + return this; + } + public IInsert AppendData(IEnumerable source) + { + if (source != null) _source.AddRange(source.Where(a => a != null)); + return this; + } - #region 参数化数据限制,或values数量限制 - protected List[] SplitSource(int valuesLimit, int parameterLimit) { - valuesLimit = valuesLimit - 1; - parameterLimit = parameterLimit - 1; - if (_source == null || _source.Any() == false) return new List[0]; - if (_source.Count == 1) return new[] { _source }; - if (_noneParameter) { - if (_source.Count < valuesLimit) return new[] { _source }; + #region 参数化数据限制,或values数量限制 + protected List[] SplitSource(int valuesLimit, int parameterLimit) + { + valuesLimit = valuesLimit - 1; + parameterLimit = parameterLimit - 1; + if (_source == null || _source.Any() == false) return new List[0]; + if (_source.Count == 1) return new[] { _source }; + if (_noneParameter) + { + if (_source.Count < valuesLimit) return new[] { _source }; - var execCount = (int)Math.Ceiling(1.0 * _source.Count / valuesLimit); - var ret = new List[execCount]; - for (var a = 0; a < execCount; a++) { - var subSource = new List(); - subSource = _source.GetRange(a * valuesLimit, Math.Min(valuesLimit, _source.Count - a * valuesLimit)); - ret[a] = subSource; - } - return ret; - } else { - var colSum = _table.Columns.Count - _ignore.Count; - var takeMax = parameterLimit / colSum; - var pamTotal = colSum * _source.Count; - if (pamTotal < parameterLimit) return new[] { _source }; + var execCount = (int)Math.Ceiling(1.0 * _source.Count / valuesLimit); + var ret = new List[execCount]; + for (var a = 0; a < execCount; a++) + { + var subSource = new List(); + subSource = _source.GetRange(a * valuesLimit, Math.Min(valuesLimit, _source.Count - a * valuesLimit)); + ret[a] = subSource; + } + return ret; + } + else + { + var colSum = _table.Columns.Count - _ignore.Count; + var takeMax = parameterLimit / colSum; + var pamTotal = colSum * _source.Count; + if (pamTotal < parameterLimit) return new[] { _source }; - var execCount = (int)Math.Ceiling(1.0 * pamTotal / takeMax / colSum); - var ret = new List[execCount]; - for (var a = 0; a < execCount; a++) { - var subSource = new List(); - subSource = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); - ret[a] = subSource; - } - return ret; - } - } - protected int SplitExecuteAffrows(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = 0; - if (ss.Any() == false) { - ClearData(); - return ret; - } - if (ss.Length == 1) { - ret = this.RawExecuteAffrows(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret += this.RawExecuteAffrows(); - } - } else { - using (var conn = _orm.Ado.MasterPool.Get()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret += this.RawExecuteAffrows(); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = 0; - if (ss.Any() == false) { - ClearData(); - return ret; - } - if (ss.Length == 1) { - ret = await this.RawExecuteAffrowsAsync(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - } else { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - protected long SplitExecuteIdentity(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - long ret = 0; - if (ss.Any() == false) { - ClearData(); - return ret; - } - if (ss.Length == 1) { - ret = this.RawExecuteIdentity(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - if (a < ss.Length - 1) this.RawExecuteAffrows(); - else ret = this.RawExecuteIdentity(); - } - } else { - using (var conn = _orm.Ado.MasterPool.Get()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - if (a < ss.Length - 1) this.RawExecuteAffrows(); - else ret = this.RawExecuteIdentity(); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - async protected Task SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - long ret = 0; - if (ss.Any() == false) { - ClearData(); - return ret; - } - if (ss.Length == 1) { - ret = await this.RawExecuteIdentityAsync(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); - else ret = await this.RawExecuteIdentityAsync(); - } - } else { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); - else ret = await this.RawExecuteIdentityAsync(); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - protected List SplitExecuteInserted(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = new List(); - if (ss.Any() == false) { - ClearData(); - return ret; - } - if (ss.Length == 1) { - ret = this.RawExecuteInserted(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret.AddRange(this.RawExecuteInserted()); - } - } else { - using (var conn = _orm.Ado.MasterPool.Get()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret.AddRange(this.RawExecuteInserted()); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - async protected Task> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = new List(); - if (ss.Any() == false) { - ClearData(); - return ret; - } - if (ss.Length == 1) { - ret = await this.RawExecuteInsertedAsync(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret.AddRange(await this.RawExecuteInsertedAsync()); - } - } else { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret.AddRange(await this.RawExecuteInsertedAsync()); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - #endregion + var execCount = (int)Math.Ceiling(1.0 * pamTotal / takeMax / colSum); + var ret = new List[execCount]; + for (var a = 0; a < execCount; a++) + { + var subSource = new List(); + subSource = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); + ret[a] = subSource; + } + return ret; + } + } + protected int SplitExecuteAffrows(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = 0; + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = this.RawExecuteAffrows(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += this.RawExecuteAffrows(); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += this.RawExecuteAffrows(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = 0; + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = await this.RawExecuteAffrowsAsync(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + protected long SplitExecuteIdentity(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + long ret = 0; + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = this.RawExecuteIdentity(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) this.RawExecuteAffrows(); + else ret = this.RawExecuteIdentity(); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) this.RawExecuteAffrows(); + else ret = this.RawExecuteIdentity(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + async protected Task SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + long ret = 0; + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = await this.RawExecuteIdentityAsync(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); + else ret = await this.RawExecuteIdentityAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); + else ret = await this.RawExecuteIdentityAsync(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + protected List SplitExecuteInserted(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = new List(); + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = this.RawExecuteInserted(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(this.RawExecuteInserted()); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(this.RawExecuteInserted()); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + async protected Task> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = new List(); + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = await this.RawExecuteInsertedAsync(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteInsertedAsync()); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteInsertedAsync()); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + #endregion - protected int RawExecuteAffrows() { - var sql = ToSql(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return affrows; - } - async protected Task RawExecuteAffrowsAsync() { - var sql = ToSql(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return affrows; - } - protected abstract long RawExecuteIdentity(); - protected abstract Task RawExecuteIdentityAsync(); - protected abstract List RawExecuteInserted(); - protected abstract Task> RawExecuteInsertedAsync(); + protected int RawExecuteAffrows() + { + var sql = ToSql(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return affrows; + } + async protected Task RawExecuteAffrowsAsync() + { + var sql = ToSql(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return affrows; + } + protected abstract long RawExecuteIdentity(); + protected abstract Task RawExecuteIdentityAsync(); + protected abstract List RawExecuteInserted(); + protected abstract Task> RawExecuteInsertedAsync(); - public abstract int ExecuteAffrows(); - public abstract Task ExecuteAffrowsAsync(); - public abstract long ExecuteIdentity(); - public abstract Task ExecuteIdentityAsync(); - public abstract List ExecuteInserted(); - public abstract Task> ExecuteInsertedAsync(); + public abstract int ExecuteAffrows(); + public abstract Task ExecuteAffrowsAsync(); + public abstract long ExecuteIdentity(); + public abstract Task ExecuteIdentityAsync(); + public abstract List ExecuteInserted(); + public abstract Task> ExecuteInsertedAsync(); - public IInsert IgnoreColumns(Expression> columns) { - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).Distinct(); - _ignore.Clear(); - foreach (var col in cols) _ignore.Add(col, true); - return this; - } - public IInsert InsertColumns(Expression> columns) { - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); - _ignore.Clear(); - foreach (var col in _table.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name) == false) - _ignore.Add(col.Attribute.Name, true); - return this; - } + public IInsert IgnoreColumns(Expression> columns) + { + var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).Distinct(); + _ignore.Clear(); + foreach (var col in cols) _ignore.Add(col, true); + return this; + } + public IInsert InsertColumns(Expression> columns) + { + var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); + _ignore.Clear(); + foreach (var col in _table.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name) == false) + _ignore.Add(col.Attribute.Name, true); + return this; + } - public IInsert AsTable(Func tableRule) { - _tableRule = tableRule; - return this; - } - public IInsert AsType(Type entityType) { - if (entityType == typeof(object)) throw new Exception("IInsert.AsType 参数不支持指定为 object"); - if (entityType == _table.Type) return this; - var newtb = _commonUtils.GetTableByEntity(entityType); - _table = newtb ?? throw new Exception("IInsert.AsType 参数错误,请传入正确的实体类型"); - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); - return this; - } + public IInsert AsTable(Func tableRule) + { + _tableRule = tableRule; + return this; + } + public IInsert AsType(Type entityType) + { + if (entityType == typeof(object)) throw new Exception("IInsert.AsType 参数不支持指定为 object"); + if (entityType == _table.Type) return this; + var newtb = _commonUtils.GetTableByEntity(entityType); + _table = newtb ?? throw new Exception("IInsert.AsType 参数错误,请传入正确的实体类型"); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); + return this; + } - public virtual string ToSql() { - if (_source == null || _source.Any() == false) return null; - var sb = new StringBuilder(); - sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append("("); - var colidx = 0; - foreach (var col in _table.Columns.Values) - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); - ++colidx; - } - sb.Append(") VALUES"); - _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; - var specialParams = new List(); - var didx = 0; - foreach (var d in _source) { - if (didx > 0) sb.Append(", "); - sb.Append("("); - var colidx2 = 0; - foreach (var col in _table.Columns.Values) - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) { - if (colidx2 > 0) sb.Append(", "); - object val = col.GetMapValue(d); - if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) - col.SetMapValue(d, val = FreeUtil.NewMongodbId()); - if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); - else { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); - } - ++colidx2; - } - sb.Append(")"); - ++didx; - } - if (_noneParameter && specialParams.Any()) - _params = specialParams.ToArray(); - return sb.ToString(); - } - } + public virtual string ToSql() + { + if (_source == null || _source.Any() == false) return null; + var sb = new StringBuilder(); + sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append("("); + var colidx = 0; + foreach (var col in _table.Columns.Values) + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); + ++colidx; + } + sb.Append(") VALUES"); + _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; + var specialParams = new List(); + var didx = 0; + foreach (var d in _source) + { + if (didx > 0) sb.Append(", "); + sb.Append("("); + var colidx2 = 0; + foreach (var col in _table.Columns.Values) + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) + { + if (colidx2 > 0) sb.Append(", "); + object val = col.GetMapValue(d); + if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) + col.SetMapValue(d, val = FreeUtil.NewMongodbId()); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); + } + ++colidx2; + } + sb.Append(")"); + ++didx; + } + if (_noneParameter && specialParams.Any()) + _params = specialParams.ToArray(); + return sb.ToString(); + } + } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index bb43b573..32b794e6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -12,889 +12,1035 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select0Provider : ISelect0 where TSelect : class where T1 : class { + public abstract class Select0Provider : ISelect0 where TSelect : class where T1 : class + { - protected int _limit, _skip; - protected string _select = "SELECT ", _orderby, _groupby, _having; - protected StringBuilder _where = new StringBuilder(); - protected List _params = new List(); - protected List _tables = new List(); - protected List> _tableRules = new List>(); - protected StringBuilder _join = new StringBuilder(); - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected DbTransaction _transaction; - protected DbConnection _connection; - protected Action _trackToList; - protected Queue> _includeToList = new Queue>(); - protected bool _distinct; - protected Expression _selectExpression; + protected int _limit, _skip; + protected string _select = "SELECT ", _orderby, _groupby, _having; + protected StringBuilder _where = new StringBuilder(); + protected List _params = new List(); + protected List _tables = new List(); + protected List> _tableRules = new List>(); + protected StringBuilder _join = new StringBuilder(); + protected IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + protected DbTransaction _transaction; + protected DbConnection _connection; + protected Action _trackToList; + protected Queue> _includeToList = new Queue>(); + protected bool _distinct; + protected Expression _selectExpression; - public static void CopyData(Select0Provider from, object to, ReadOnlyCollection lambParms) { - var toType = to?.GetType(); - if (toType == null) return; - toType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._limit); - toType.GetField("_skip", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._skip); - toType.GetField("_select", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._select); - toType.GetField("_orderby", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orderby); - toType.GetField("_groupby", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._groupby); - toType.GetField("_having", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._having); - toType.GetField("_where", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._where.ToString())); - toType.GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._params.ToArray())); - if (lambParms == null) - toType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._tables.ToArray())); - else { - var _multiTables = toType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(to) as List; - _multiTables[0] = from._tables[0]; - for (var a = 1; a < lambParms.Count; a++) { - var tb = from._tables.Where(b => b.Alias == lambParms[a].Name && b.Table.Type == lambParms[a].Type).FirstOrDefault(); - if (tb != null) _multiTables[a] = tb; - else { - _multiTables[a].Alias = lambParms[a].Name; - _multiTables[a].Parameter = lambParms[a]; - } - } - if (_multiTables.Count < from._tables.Count) - _multiTables.AddRange(from._tables.GetRange(_multiTables.Count, from._tables.Count - _multiTables.Count)); - } - toType.GetField("_tableRules", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._tableRules); - toType.GetField("_join", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._join.ToString())); - //toType.GetField("_orm", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orm); - //toType.GetField("_commonUtils", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonUtils); - //toType.GetField("_commonExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonExpression); - toType.GetField("_transaction", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._transaction); - toType.GetField("_connection", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._connection); - toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList); - toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); - toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); - toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); - } + public static void CopyData(Select0Provider from, object to, ReadOnlyCollection lambParms) + { + var toType = to?.GetType(); + if (toType == null) return; + toType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._limit); + toType.GetField("_skip", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._skip); + toType.GetField("_select", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._select); + toType.GetField("_orderby", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orderby); + toType.GetField("_groupby", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._groupby); + toType.GetField("_having", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._having); + toType.GetField("_where", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._where.ToString())); + toType.GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._params.ToArray())); + if (lambParms == null) + toType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._tables.ToArray())); + else + { + var _multiTables = toType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(to) as List; + _multiTables[0] = from._tables[0]; + for (var a = 1; a < lambParms.Count; a++) + { + var tb = from._tables.Where(b => b.Alias == lambParms[a].Name && b.Table.Type == lambParms[a].Type).FirstOrDefault(); + if (tb != null) _multiTables[a] = tb; + else + { + _multiTables[a].Alias = lambParms[a].Name; + _multiTables[a].Parameter = lambParms[a]; + } + } + if (_multiTables.Count < from._tables.Count) + _multiTables.AddRange(from._tables.GetRange(_multiTables.Count, from._tables.Count - _multiTables.Count)); + } + toType.GetField("_tableRules", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._tableRules); + toType.GetField("_join", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._join.ToString())); + //toType.GetField("_orm", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orm); + //toType.GetField("_commonUtils", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonUtils); + //toType.GetField("_commonExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonExpression); + toType.GetField("_transaction", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._transaction); + toType.GetField("_connection", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._connection); + toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList); + toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); + toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); + toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); + } - public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T1)), Alias = "a", On = null, Type = SelectTableInfoType.From }); - this.Where(_commonUtils.WhereObject(_tables.First().Table, "a.", dywhere)); - if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); - } + public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T1)), Alias = "a", On = null, Type = SelectTableInfoType.From }); + this.Where(_commonUtils.WhereObject(_tables.First().Table, "a.", dywhere)); + if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + } - public TSelect TrackToList(Action track) { - _trackToList = track; - return this as TSelect; - } + public TSelect TrackToList(Action track) + { + _trackToList = track; + return this as TSelect; + } - public TSelect WithTransaction(DbTransaction transaction) { - _transaction = transaction; - _connection = _transaction?.Connection; - return this as TSelect; - } - public TSelect WithConnection(DbConnection connection) { - if (_transaction?.Connection != connection) _transaction = null; - _connection = connection; - return this as TSelect; - } + public TSelect WithTransaction(DbTransaction transaction) + { + _transaction = transaction; + _connection = _transaction?.Connection; + return this as TSelect; + } + public TSelect WithConnection(DbConnection connection) + { + if (_transaction?.Connection != connection) _transaction = null; + _connection = connection; + return this as TSelect; + } - public bool Any() { - this.Limit(1); - return this.ToList("1").FirstOrDefault() == 1; - } - async public Task AnyAsync() { - this.Limit(1); - return (await this.ToListAsync("1")).FirstOrDefault() == 1; - } + public bool Any() + { + this.Limit(1); + return this.ToList("1").FirstOrDefault() == 1; + } + async public Task AnyAsync() + { + this.Limit(1); + return (await this.ToListAsync("1")).FirstOrDefault() == 1; + } - public long Count() => this.ToList("count(1)").FirstOrDefault(); - async public Task CountAsync() => (await this.ToListAsync("count(1)")).FirstOrDefault(); + public long Count() => this.ToList("count(1)").FirstOrDefault(); + async public Task CountAsync() => (await this.ToListAsync("count(1)")).FirstOrDefault(); - public TSelect Count(out long count) { - count = this.Count(); - return this as TSelect; - } + public TSelect Count(out long count) + { + count = this.Count(); + return this as TSelect; + } - public TSelect GroupBy(string sql, object parms = null) { - _groupby = sql; - if (string.IsNullOrEmpty(_groupby)) return this as TSelect; - _groupby = string.Concat(" \r\nGROUP BY ", _groupby); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(_groupby, parms)); - return this as TSelect; - } - public TSelect Having(string sql, object parms = null) { - if (string.IsNullOrEmpty(_groupby) || string.IsNullOrEmpty(sql)) return this as TSelect; - _having = string.Concat(_having, " AND (", sql, ")"); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this as TSelect; - } + public TSelect GroupBy(string sql, object parms = null) + { + _groupby = sql; + if (string.IsNullOrEmpty(_groupby)) return this as TSelect; + _groupby = string.Concat(" \r\nGROUP BY ", _groupby); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(_groupby, parms)); + return this as TSelect; + } + public TSelect Having(string sql, object parms = null) + { + if (string.IsNullOrEmpty(_groupby) || string.IsNullOrEmpty(sql)) return this as TSelect; + _having = string.Concat(_having, " AND (", sql, ")"); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this as TSelect; + } - public TSelect LeftJoin(Expression> exp) { - if (exp == null) return this as TSelect; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - public TSelect InnerJoin(Expression> exp) { - if (exp == null) return this as TSelect; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - public TSelect RightJoin(Expression> exp) { - if (exp == null) return this as TSelect; _tables[0].Parameter = exp.Parameters[0]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - public TSelect LeftJoin(Expression> exp) { - if (exp == null) return this as TSelect; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - public TSelect InnerJoin(Expression> exp) { - if (exp == null) return this as TSelect; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - public TSelect RightJoin(Expression> exp) { - if (exp == null) return this as TSelect; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } + public TSelect LeftJoin(Expression> exp) + { + if (exp == null) return this as TSelect; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + public TSelect InnerJoin(Expression> exp) + { + if (exp == null) return this as TSelect; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + public TSelect RightJoin(Expression> exp) + { + if (exp == null) return this as TSelect; _tables[0].Parameter = exp.Parameters[0]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + public TSelect LeftJoin(Expression> exp) + { + if (exp == null) return this as TSelect; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + public TSelect InnerJoin(Expression> exp) + { + if (exp == null) return this as TSelect; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + public TSelect RightJoin(Expression> exp) + { + if (exp == null) return this as TSelect; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } - public TSelect InnerJoin(string sql, object parms = null) { - if (string.IsNullOrEmpty(sql)) return this as TSelect; - _join.Append(" \r\nINNER JOIN ").Append(sql); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this as TSelect; - } - public TSelect LeftJoin(string sql, object parms = null) { - if (string.IsNullOrEmpty(sql)) return this as TSelect; - _join.Append(" \r\nLEFT JOIN ").Append(sql); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this as TSelect; - } + public TSelect InnerJoin(string sql, object parms = null) + { + if (string.IsNullOrEmpty(sql)) return this as TSelect; + _join.Append(" \r\nINNER JOIN ").Append(sql); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this as TSelect; + } + public TSelect LeftJoin(string sql, object parms = null) + { + if (string.IsNullOrEmpty(sql)) return this as TSelect; + _join.Append(" \r\nLEFT JOIN ").Append(sql); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this as TSelect; + } - public TSelect Limit(int limit) { - _limit = limit; - return this as TSelect; - } - public TSelect Master() { - _select = " SELECT "; - return this as TSelect; - } - public TSelect Offset(int offset) => this.Skip(offset) as TSelect; + public TSelect Limit(int limit) + { + _limit = limit; + return this as TSelect; + } + public TSelect Master() + { + _select = " SELECT "; + return this as TSelect; + } + public TSelect Offset(int offset) => this.Skip(offset) as TSelect; - public TSelect OrderBy(string sql, object parms = null) => this.OrderBy(true, sql, parms); - public TSelect OrderBy(bool condition, string sql, object parms = null) { - if (condition == false) return this as TSelect; - if (string.IsNullOrEmpty(sql)) _orderby = null; - var isnull = string.IsNullOrEmpty(_orderby); - _orderby = string.Concat(isnull ? " \r\nORDER BY " : "", _orderby, isnull ? "" : ", ", sql); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this as TSelect; - } - public TSelect Page(int pageNumber, int pageSize) { - this.Skip(Math.Max(0, pageNumber - 1) * pageSize); - return this.Limit(pageSize) as TSelect; - } + public TSelect OrderBy(string sql, object parms = null) => this.OrderBy(true, sql, parms); + public TSelect OrderBy(bool condition, string sql, object parms = null) + { + if (condition == false) return this as TSelect; + if (string.IsNullOrEmpty(sql)) _orderby = null; + var isnull = string.IsNullOrEmpty(_orderby); + _orderby = string.Concat(isnull ? " \r\nORDER BY " : "", _orderby, isnull ? "" : ", ", sql); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this as TSelect; + } + public TSelect Page(int pageNumber, int pageSize) + { + this.Skip(Math.Max(0, pageNumber - 1) * pageSize); + return this.Limit(pageSize) as TSelect; + } - public TSelect RightJoin(string sql, object parms = null) { - if (string.IsNullOrEmpty(sql)) return this as TSelect; - _join.Append(" \r\nRIGHT JOIN ").Append(sql); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this as TSelect; - } + public TSelect RightJoin(string sql, object parms = null) + { + if (string.IsNullOrEmpty(sql)) return this as TSelect; + _join.Append(" \r\nRIGHT JOIN ").Append(sql); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this as TSelect; + } - public TSelect Skip(int offset) { - _skip = offset; - return this as TSelect; - } - public TSelect Take(int limit) => this.Limit(limit) as TSelect; + public TSelect Skip(int offset) + { + _skip = offset; + return this as TSelect; + } + public TSelect Take(int limit) => this.Limit(limit) as TSelect; - public TSelect Distinct() { - _distinct = true; - return this as TSelect; - } + public TSelect Distinct() + { + _distinct = true; + return this as TSelect; + } - public DataTable ToDataTable(string field = null) { - var sql = this.ToSql(field); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; - try { - ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } - async public Task ToDataTableAsync(string field = null) { - var sql = this.ToSql(field); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; - try { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } + public DataTable ToDataTable(string field = null) + { + var sql = this.ToSql(field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async public Task ToDataTableAsync(string field = null) + { + var sql = this.ToSql(field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } - public List ToList(string field) { - var sql = this.ToSql(field); - var type = typeof(TTuple); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - var flagStr = $"ToListField:{field}"; - Exception exception = null; - try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); - ret.Add((TTuple)read.Value); - }, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } - async public Task> ToListAsync(string field) { - var sql = this.ToSql(field); - var type = typeof(TTuple); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - var flagStr = $"ToListField:{field}"; - Exception exception = null; - try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); - ret.Add((TTuple)read.Value); - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } - internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => { - ret.Add(af.Read(_orm, dr)); - if (otherData != null) { - var idx = af.FieldCount - 1; - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); - } - }, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret); - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); - _trackToList?.Invoke(ret); - return ret; - } - async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => { - ret.Add(af.Read(_orm, dr)); - if (otherData != null) { - var idx = af.FieldCount - 1; - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); - } - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret); - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); - _trackToList?.Invoke(ret); - return ret; - } - internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { - string sql = null; - if (otherData?.Length > 0) { - var sbField = new StringBuilder().Append(af.Field); - foreach (var other in otherData) - sbField.Append(other.field); - sql = this.ToSql(sbField.ToString()); - } else - sql = this.ToSql(af.Field); + public List ToList(string field) + { + var sql = this.ToSql(field); + var type = typeof(TTuple); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + var flagStr = $"ToListField:{field}"; + Exception exception = null; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, dr => + { + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); + ret.Add((TTuple)read.Value); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async public Task> ToListAsync(string field) + { + var sql = this.ToSql(field); + var type = typeof(TTuple); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + var flagStr = $"ToListField:{field}"; + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + { + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); + ret.Add((TTuple)read.Value); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, dr => + { + ret.Add(af.Read(_orm, dr)); + if (otherData != null) + { + var idx = af.FieldCount - 1; + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + } + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret); + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); + _trackToList?.Invoke(ret); + return ret; + } + async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + { + ret.Add(af.Read(_orm, dr)); + if (otherData != null) + { + var idx = af.FieldCount - 1; + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + } + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret); + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); + _trackToList?.Invoke(ret); + return ret; + } + internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.Field); - return ToListAfPrivate(sql, af, otherData); - } - internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { - string sql = null; - if (otherData?.Length > 0) { - var sbField = new StringBuilder().Append(af.Field); - foreach (var other in otherData) - sbField.Append(other.field); - sql = this.ToSql(sbField.ToString()); - } else - sql = this.ToSql(af.Field); + return ToListAfPrivate(sql, af, otherData); + } + internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.Field); - return ToListAfPrivateAsync(sql, af, otherData); - } - public List ToList(bool includeNestedMembers = false) { - if (_selectExpression != null) return this.InternalToList(_selectExpression); - return this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); - } - public Task> ToListAsync(bool includeNestedMembers = false) { - if (_selectExpression != null) return this.InternalToListAsync(_selectExpression); - return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); - } - public T1 ToOne() { - this.Limit(1); - return this.ToList().FirstOrDefault(); - } - async public Task ToOneAsync() { - this.Limit(1); - return (await this.ToListAsync()).FirstOrDefault(); - } + return ToListAfPrivateAsync(sql, af, otherData); + } + public List ToList(bool includeNestedMembers = false) + { + if (_selectExpression != null) return this.InternalToList(_selectExpression); + return this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); + } + public Task> ToListAsync(bool includeNestedMembers = false) + { + if (_selectExpression != null) return this.InternalToListAsync(_selectExpression); + return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); + } + public T1 ToOne() + { + this.Limit(1); + return this.ToList().FirstOrDefault(); + } + async public Task ToOneAsync() + { + this.Limit(1); + return (await this.ToListAsync()).FirstOrDefault(); + } - public T1 First() => this.ToOne(); - public Task FirstAsync() => this.ToOneAsync(); + public T1 First() => this.ToOne(); + public Task FirstAsync() => this.ToOneAsync(); - protected List ToListMapReader((ReadAnonymousTypeInfo map, string field) af) { - var sql = this.ToSql(af.field); - var type = typeof(TReturn); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => { - var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); - }, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); - _trackToList?.Invoke(ret); - return ret; - } - async protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) { - var sql = this.ToSql(af.field); - var type = typeof(TReturn); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => { - var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); - _trackToList?.Invoke(ret); - return ret; - } - protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; + protected List ToListMapReader((ReadAnonymousTypeInfo map, string field) af) + { + var sql = this.ToSql(af.field); + var type = typeof(TReturn); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, dr => + { + var index = -1; + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); + _trackToList?.Invoke(ret); + return ret; + } + async protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) + { + var sql = this.ToSql(af.field); + var type = typeof(TReturn); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + { + var index = -1; + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); + _trackToList?.Invoke(ret); + return ret; + } + protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null); - return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); - } - static ConcurrentDictionary _dicConstructor = new ConcurrentDictionary(); - static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); - public class GetAllFieldExpressionTreeInfo { - public string Field { get; set; } - public int FieldCount { get; set; } - public Func Read { get; set; } - } - protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevelAll() { - return _dicGetAllFieldExpressionTree.GetOrAdd($"*{string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}"))}", s => { - var type = _tables.First().Table.TypeLazy ?? _tables.First().Table.Type; - var ormExp = Expression.Parameter(typeof(IFreeSql), "orm"); - var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); - var returnTarget = Expression.Label(type); - var retExp = Expression.Variable(type, "ret"); - var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); - var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); - var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); - var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); - var blockExp = new List(); - var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); - blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))), - Expression.Assign(dataIndexExp, Expression.Constant(0)) - }); - //typeof(Topic).GetMethod("get_Type").IsVirtual + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null); + return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); + } + static ConcurrentDictionary _dicConstructor = new ConcurrentDictionary(); + static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); + public class GetAllFieldExpressionTreeInfo + { + public string Field { get; set; } + public int FieldCount { get; set; } + public Func Read { get; set; } + } + protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevelAll() + { + return _dicGetAllFieldExpressionTree.GetOrAdd($"*{string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}"))}", s => + { + var type = _tables.First().Table.TypeLazy ?? _tables.First().Table.Type; + var ormExp = Expression.Parameter(typeof(IFreeSql), "orm"); + var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); + var returnTarget = Expression.Label(type); + var retExp = Expression.Variable(type, "ret"); + var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); + var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); + var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); + var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); + var blockExp = new List(); + var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); + blockExp.AddRange(new Expression[] { + Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))), + Expression.Assign(dataIndexExp, Expression.Constant(0)) + }); + //typeof(Topic).GetMethod("get_Type").IsVirtual - var field = new StringBuilder(); - var dicfield = new Dictionary(); - var tb = _tables.First(); - var index = 0; + var field = new StringBuilder(); + var dicfield = new Dictionary(); + var tb = _tables.First(); + var index = 0; - var tborder = new[] { tb }.Concat(_tables.ToArray().Where((a, b) => b > 0).OrderBy(a => a.Alias)); - var tbiindex = 0; - foreach (var tbi in tborder) { - if (tbiindex > 0 && tbi.Type == SelectTableInfoType.From) continue; - if (tbiindex > 0 && tbi.Alias.StartsWith($"{tb.Alias}__") == false) continue; + var tborder = new[] { tb }.Concat(_tables.ToArray().Where((a, b) => b > 0).OrderBy(a => a.Alias)); + var tbiindex = 0; + foreach (var tbi in tborder) + { + if (tbiindex > 0 && tbi.Type == SelectTableInfoType.From) continue; + if (tbiindex > 0 && tbi.Alias.StartsWith($"{tb.Alias}__") == false) continue; - var typei = tbi.Table.TypeLazy ?? tbi.Table.Type; - Expression curExp = retExp; + var typei = tbi.Table.TypeLazy ?? tbi.Table.Type; + Expression curExp = retExp; - var colidx = 0; - foreach (var col in tbi.Table.Columns.Values) { - if (index > 0) { - field.Append(", "); - if (tbiindex > 0 && colidx == 0) field.Append("\r\n"); - } - var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); - else dicfield.Add(quoteName, true); - ++colidx; - } - tbiindex++; + var colidx = 0; + foreach (var col in tbi.Table.Columns.Values) + { + if (index > 0) + { + field.Append(", "); + if (tbiindex > 0 && colidx == 0) field.Append("\r\n"); + } + var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + else dicfield.Add(quoteName, true); + ++colidx; + } + tbiindex++; - if (tbiindex == 0) - blockExp.AddRange(new Expression[] { - Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), - Expression.IfThen( - Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex) - ), - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Assign(retExp, Expression.Convert(readExpValue, typei)) - ) - }); - else { - Expression curExpIfNotNull = Expression.IsTrue(Expression.Constant(true)); - var curTb = tb; - var parentNameSplits = tbi.Alias.Split(new[] { "__" }, StringSplitOptions.None); - var iscontinue = false; - for (var k = 1; k < parentNameSplits.Length; k++) { - var curPropName = parentNameSplits[k]; - if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out var tryprop) == false) { - k++; - curPropName = $"{curPropName}__{parentNameSplits[k]}"; - if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out tryprop) == false) { - iscontinue = true; - break; - } - } - curExp = Expression.MakeMemberAccess(curExp, tryprop); - if (k + 1 < parentNameSplits.Length) - curExpIfNotNull = Expression.AndAlso(curExpIfNotNull, Expression.NotEqual(curExp, Expression.Default(tryprop.PropertyType))); - curTb = _tables.Where(a => a.Alias == $"{curTb.Alias}__{curPropName}" && a.Table.Type == tryprop.PropertyType).FirstOrDefault(); - if (curTb == null) { - iscontinue = true; - break; - } - } - if (iscontinue) continue; + if (tbiindex == 0) + blockExp.AddRange(new Expression[] { + Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), + Expression.IfThen( + Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex) + ), + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Assign(retExp, Expression.Convert(readExpValue, typei)) + ) + }); + else + { + Expression curExpIfNotNull = Expression.IsTrue(Expression.Constant(true)); + var curTb = tb; + var parentNameSplits = tbi.Alias.Split(new[] { "__" }, StringSplitOptions.None); + var iscontinue = false; + for (var k = 1; k < parentNameSplits.Length; k++) + { + var curPropName = parentNameSplits[k]; + if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out var tryprop) == false) + { + k++; + curPropName = $"{curPropName}__{parentNameSplits[k]}"; + if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out tryprop) == false) + { + iscontinue = true; + break; + } + } + curExp = Expression.MakeMemberAccess(curExp, tryprop); + if (k + 1 < parentNameSplits.Length) + curExpIfNotNull = Expression.AndAlso(curExpIfNotNull, Expression.NotEqual(curExp, Expression.Default(tryprop.PropertyType))); + curTb = _tables.Where(a => a.Alias == $"{curTb.Alias}__{curPropName}" && a.Table.Type == tryprop.PropertyType).FirstOrDefault(); + if (curTb == null) + { + iscontinue = true; + break; + } + } + if (iscontinue) continue; - blockExp.Add( - Expression.IfThenElse( - curExpIfNotNull, - Expression.Block(new Expression[] { - Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), - Expression.IfThen( - Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex) - ), - Expression.IfThenElse( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Assign(curExp, Expression.Convert(readExpValue, typei)), - Expression.Assign(curExp, Expression.Constant(null, typei)) - ) - }), - Expression.Block( - Expression.Assign(readExpValue, Expression.Constant(null, typeof(object))), - Expression.Assign(dataIndexExp, Expression.Constant(index)) - ) - ) - ); - } + blockExp.Add( + Expression.IfThenElse( + curExpIfNotNull, + Expression.Block(new Expression[] { + Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), + Expression.IfThen( + Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex) + ), + Expression.IfThenElse( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Assign(curExp, Expression.Convert(readExpValue, typei)), + Expression.Assign(curExp, Expression.Constant(null, typei)) + ) + }), + Expression.Block( + Expression.Assign(readExpValue, Expression.Constant(null, typeof(object))), + Expression.Assign(dataIndexExp, Expression.Constant(index)) + ) + ) + ); + } - if (tbi.Table.TypeLazy != null) - blockExp.Add( - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(Expression.TypeAs(readExpValue, typei), tbi.Table.TypeLazySetOrm, ormExp) - ) - ); //将 orm 传递给 lazy - } + if (tbi.Table.TypeLazy != null) + blockExp.Add( + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(Expression.TypeAs(readExpValue, typei), tbi.Table.TypeLazySetOrm, ormExp) + ) + ); //将 orm 传递给 lazy + } - blockExp.AddRange(new Expression[] { - Expression.Return(returnTarget, retExp), - Expression.Label(returnTarget, Expression.Default(type)) - }); - return new GetAllFieldExpressionTreeInfo { - Field = field.ToString(), - FieldCount = index, - Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile() - }; - }); - } - protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2() { - return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s => { - var tb1 = _tables.First().Table; - var type = tb1.TypeLazy ?? tb1.Type; - var props = tb1.Properties; + blockExp.AddRange(new Expression[] { + Expression.Return(returnTarget, retExp), + Expression.Label(returnTarget, Expression.Default(type)) + }); + return new GetAllFieldExpressionTreeInfo + { + Field = field.ToString(), + FieldCount = index, + Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile() + }; + }); + } + protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2() + { + return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s => + { + var tb1 = _tables.First().Table; + var type = tb1.TypeLazy ?? tb1.Type; + var props = tb1.Properties; - var ormExp = Expression.Parameter(typeof(IFreeSql), "orm"); - var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); - var returnTarget = Expression.Label(type); - var retExp = Expression.Variable(type, "ret"); - var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); - var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); - var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); - var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); - var blockExp = new List(); - var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); - blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))), - Expression.Assign(dataIndexExp, Expression.Constant(0)) - }); - //typeof(Topic).GetMethod("get_Type").IsVirtual + var ormExp = Expression.Parameter(typeof(IFreeSql), "orm"); + var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); + var returnTarget = Expression.Label(type); + var retExp = Expression.Variable(type, "ret"); + var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); + var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); + var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); + var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); + var blockExp = new List(); + var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); + blockExp.AddRange(new Expression[] { + Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))), + Expression.Assign(dataIndexExp, Expression.Constant(0)) + }); + //typeof(Topic).GetMethod("get_Type").IsVirtual - var field = new StringBuilder(); - var dicfield = new Dictionary(); - var tb = _tables.First(); - var index = 0; - var otherindex = 0; - foreach (var prop in props.Values) { - if (tb.Table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue; + var field = new StringBuilder(); + var dicfield = new Dictionary(); + var tb = _tables.First(); + var index = 0; + var otherindex = 0; + foreach (var prop in props.Values) + { + if (tb.Table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue; - if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) { //普通字段 - if (index > 0) field.Append(", "); - var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); - else dicfield.Add(quoteName, true); - } else { - var tb2 = _tables.Where((a, b) => b > 0 && - (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) && - string.IsNullOrEmpty(a.On) == false && - a.Alias.StartsWith($"{tb.Alias}__") && //开头结尾完全匹配 - a.Alias.EndsWith($"__{prop.Name}") //不清楚会不会有其他情况 求大佬优化 - ).FirstOrDefault(); //判断 b > 0 防止 parent 递归关系 - if (tb2 == null && props.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) - tb2 = _tables.Where((a, b) => b > 0 && - (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) && - string.IsNullOrEmpty(a.On) == false && - a.Table.Type == prop.PropertyType).FirstOrDefault(); - if (tb2 == null) continue; - foreach (var col2 in tb2.Table.Columns.Values) { - if (index > 0) field.Append(", "); - var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); - ++index; - ++otherindex; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); - else dicfield.Add(quoteName, true); - } - } - //只读到二级属性 - var propGetSetMethod = prop.GetSetMethod(); - Expression readExpAssign = null; //加速缓存 - if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor, - Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ); - else { - var proptypeGeneric = prop.PropertyType; - if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); - if (proptypeGeneric.IsEnum || - Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor, - Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ); - else { - var propLazyType = _commonUtils.GetTableByEntity(prop.PropertyType)?.TypeLazy ?? prop.PropertyType; - readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(propLazyType), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) }); - } - } - blockExp.AddRange(new Expression[] { - Expression.Assign(readExp, readExpAssign), - Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex)), + if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) + { //普通字段 + if (index > 0) field.Append(", "); + var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + else dicfield.Add(quoteName, true); + } + else + { + var tb2 = _tables.Where((a, b) => b > 0 && + (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) && + string.IsNullOrEmpty(a.On) == false && + a.Alias.StartsWith($"{tb.Alias}__") && //开头结尾完全匹配 + a.Alias.EndsWith($"__{prop.Name}") //不清楚会不会有其他情况 求大佬优化 + ).FirstOrDefault(); //判断 b > 0 防止 parent 递归关系 + if (tb2 == null && props.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) + tb2 = _tables.Where((a, b) => b > 0 && + (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) && + string.IsNullOrEmpty(a.On) == false && + a.Table.Type == prop.PropertyType).FirstOrDefault(); + if (tb2 == null) continue; + foreach (var col2 in tb2.Table.Columns.Values) + { + if (index > 0) field.Append(", "); + var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); + ++index; + ++otherindex; + if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + else dicfield.Add(quoteName, true); + } + } + //只读到二级属性 + var propGetSetMethod = prop.GetSetMethod(); + Expression readExpAssign = null; //加速缓存 + if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor, + Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)), + //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else + { + var proptypeGeneric = prop.PropertyType; + if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsEnum || + Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor, + Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)), + //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else + { + var propLazyType = _commonUtils.GetTableByEntity(prop.PropertyType)?.TypeLazy ?? prop.PropertyType; + readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(propLazyType), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) }); + } + } + blockExp.AddRange(new Expression[] { + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex)), //Expression.Call(typeof(Trace).GetMethod("WriteLine", new Type[]{typeof(string)}), Expression.Call(typeof(string).GetMethod("Concat", new Type[]{typeof(object) }), readExpValue)), tb1.TypeLazy != null ? - Expression.IfThenElse( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Constant(null)), prop.PropertyType)) - ) : - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)) - ) - }); - } - if (otherindex == 0) { //不读导航属性,优化单表读取性能 - blockExp.Clear(); - blockExp.AddRange(new Expression[] { - Expression.Assign(dataIndexExp, Expression.Constant(0)), - Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(type), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Assign(retExp, Expression.Convert(readExpValue, type)) - ) - }); - } - if (tb1.TypeLazy != null) - blockExp.Add( - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(retExp, tb1.TypeLazySetOrm, ormExp) - ) - ); //将 orm 传递给 lazy - blockExp.AddRange(new Expression[] { - Expression.Return(returnTarget, retExp), - Expression.Label(returnTarget, Expression.Default(type)) - }); - return new GetAllFieldExpressionTreeInfo { - Field = field.ToString(), - Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile() - }; - }); - } - protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() { - var tb1 = _tables.First().Table; - var type = tb1.Type; - var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0])); - var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties }; + Expression.IfThenElse( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Constant(null)), prop.PropertyType)) + ) : + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)) + ) + }); + } + if (otherindex == 0) + { //不读导航属性,优化单表读取性能 + blockExp.Clear(); + blockExp.AddRange(new Expression[] { + Expression.Assign(dataIndexExp, Expression.Constant(0)), + Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(type), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Assign(retExp, Expression.Convert(readExpValue, type)) + ) + }); + } + if (tb1.TypeLazy != null) + blockExp.Add( + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, tb1.TypeLazySetOrm, ormExp) + ) + ); //将 orm 传递给 lazy + blockExp.AddRange(new Expression[] { + Expression.Return(returnTarget, retExp), + Expression.Label(returnTarget, Expression.Default(type)) + }); + return new GetAllFieldExpressionTreeInfo + { + Field = field.ToString(), + Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile() + }; + }); + } + protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() + { + var tb1 = _tables.First().Table; + var type = tb1.Type; + var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0])); + var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties }; - var field = new StringBuilder(); - var dicfield = new Dictionary(); - var tb = _tables.First(); - var index = 0; - var ps = tb1.Properties; - foreach (var p in ps.Values) { - var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name }; - if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段 - if (index > 0) field.Append(", "); - var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); - else dicfield.Add(quoteName, true); - } else { - var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault(); - if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault(); - if (tb2 == null) continue; - child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]); - child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - foreach (var col2 in tb2.Table.Columns.Values) { - if (index > 0) field.Append(", "); - var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); - else dicfield.Add(quoteName, true); - child.Childs.Add(new ReadAnonymousTypeInfo { - Property = tb2.Table.Type.GetProperty(col2.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), - CsName = col2.CsName - }); - } - } - map.Childs.Add(child); - } - return (map, field.ToString()); - } + var field = new StringBuilder(); + var dicfield = new Dictionary(); + var tb = _tables.First(); + var index = 0; + var ps = tb1.Properties; + foreach (var p in ps.Values) + { + var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name }; + if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) + { //普通字段 + if (index > 0) field.Append(", "); + var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + else dicfield.Add(quoteName, true); + } + else + { + var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault(); + if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault(); + if (tb2 == null) continue; + child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]); + child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + foreach (var col2 in tb2.Table.Columns.Values) + { + if (index > 0) field.Append(", "); + var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + else dicfield.Add(quoteName, true); + child.Childs.Add(new ReadAnonymousTypeInfo + { + Property = tb2.Table.Type.GetProperty(col2.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), + CsName = col2.CsName + }); + } + } + map.Childs.Add(child); + } + return (map, field.ToString()); + } - protected string TableRuleInvoke(Type type, string oldname) { - for (var a = _tableRules.Count - 1; a >= 0; a--) { - var newname = _tableRules[a]?.Invoke(type, oldname); - if (!string.IsNullOrEmpty(newname)) return newname; - } - return oldname; - } + protected string TableRuleInvoke(Type type, string oldname) + { + for (var a = _tableRules.Count - 1; a >= 0; a--) + { + var newname = _tableRules[a]?.Invoke(type, oldname); + if (!string.IsNullOrEmpty(newname)) return newname; + } + return oldname; + } - public TSelect AsTable(Func tableRule) { - if (tableRule != null) _tableRules.Add(tableRule); - return this as TSelect; - } - public TSelect AsType(Type entityType) { - if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); - if (entityType == _tables[0].Table.Type) return this as TSelect; - var newtb = _commonUtils.GetTableByEntity(entityType); - _tables[0].Table = newtb ?? throw new Exception("ISelect.AsType 参数错误,请传入正确的实体类型"); - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); - return this as TSelect; - } - public abstract string ToSql(string field = null); + public TSelect AsTable(Func tableRule) + { + if (tableRule != null) _tableRules.Add(tableRule); + return this as TSelect; + } + public TSelect AsType(Type entityType) + { + if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); + if (entityType == _tables[0].Table.Type) return this as TSelect; + var newtb = _commonUtils.GetTableByEntity(entityType); + _tables[0].Table = newtb ?? throw new Exception("ISelect.AsType 参数错误,请传入正确的实体类型"); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); + return this as TSelect; + } + public abstract string ToSql(string field = null); - public TSelect Where(string sql, object parms = null) => this.WhereIf(true, sql, parms); - public TSelect WhereIf(bool condition, string sql, object parms = null) { - if (condition == false || string.IsNullOrEmpty(sql)) return this as TSelect; - var args = new Aop.WhereEventArgs(sql, parms); - _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); - if (args.IsCancel == true) return this as TSelect; + public TSelect Where(string sql, object parms = null) => this.WhereIf(true, sql, parms); + public TSelect WhereIf(bool condition, string sql, object parms = null) + { + if (condition == false || string.IsNullOrEmpty(sql)) return this as TSelect; + var args = new Aop.WhereEventArgs(sql, parms); + _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); + if (args.IsCancel == true) return this as TSelect; - _where.Append(" AND (").Append(sql).Append(")"); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this as TSelect; - } - #region common + _where.Append(" AND (").Append(sql).Append(")"); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this as TSelect; + } + #region common - protected TMember InternalAvg(Expression exp) => this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - async protected Task InternalAvgAsync(Expression exp) => (await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); - protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); - protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); - protected TMember InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + protected TMember InternalAvg(Expression exp) => this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); + async protected Task InternalAvgAsync(Expression exp) => (await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); + async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); + async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + protected TMember InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); + async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); - protected ISelectGrouping InternalGroupBy(Expression columns) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = -10000; //临时规则,不返回 as1 + protected ISelectGrouping InternalGroupBy(Expression columns) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null); - this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null); - return new SelectGroupingProvider(this, map, _commonExpression, _tables); - } - protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { - _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null); - return this as TSelect; - } - protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { - var tb = _commonUtils.GetTableByEntity(typeof(T2)); - if (tb == null) throw new ArgumentException("T2 类型错误"); - _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType }); - _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null); - return this as TSelect; - } - protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); - protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null); + this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null); + return new SelectGroupingProvider(this, map, _commonExpression, _tables); + } + protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) + { + _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null); + return this as TSelect; + } + protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) + { + var tb = _commonUtils.GetTableByEntity(typeof(T2)); + if (tb == null) throw new ArgumentException("T2 类型错误"); + _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType }); + _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null); + return this as TSelect; + } + protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); + protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); - protected List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); - protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); - protected string InternalToSql(Expression select) { - var af = this.GetExpressionField(select); - return this.ToSql(af.field); - } + protected List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); + protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); + protected string InternalToSql(Expression select) + { + var af = this.GetExpressionField(select); + return this.ToSql(af.field); + } - protected DataTable InternalToDataTable(Expression select) { - var sql = this.InternalToSql(select); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; - try { - ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } - async protected Task InternalToDataTableAsync(Expression select) { - var sql = this.InternalToSql(select); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; - try { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } + protected DataTable InternalToDataTable(Expression select) + { + var sql = this.InternalToSql(select); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected Task InternalToDataTableAsync(Expression select) + { + var sql = this.InternalToSql(select); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } - protected TReturn InternalToAggregate(Expression select) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; + protected TReturn InternalToAggregate(Expression select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null); - return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); - } - async protected Task InternalToAggregateAsync(Expression select) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null); + return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); + } + async protected Task InternalToAggregateAsync(Expression select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null); - return (await this.ToListMapReaderAsync((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); - } + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null); + return (await this.ToListMapReaderAsync((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); + } - protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null)); - - protected TSelect InternalJoin(Expression exp) { - return this as TSelect; - } - #endregion - } + protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null)); + #endregion + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index efb1af06..a2e67382 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -5,178 +5,204 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select10Provider : Select0Provider, T1>, ISelect - 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 { + public abstract class Select10Provider : Select0Provider, T1>, ISelect + 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 + { - public Select10Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); - } + public Select10Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy (exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i"), - Expression.Parameter(typeof(T10), "j")); - } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h"), + Expression.Parameter(typeof(T9), "i"), + Expression.Parameter(typeof(T10), "j")); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)) : this; - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)) : this; + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 0f2ee90e..5885b69e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -14,784 +14,911 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select1Provider : Select0Provider, T1>, ISelect - where T1 : class { - public Select1Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { + public abstract class Select1Provider : Select0Provider, T1>, ISelect + where T1 : class + { + public Select1Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { - } + } - protected ISelect InternalFrom(Expression exp) { - if (exp.NodeType == ExpressionType.Call) { - var expCall = exp as MethodCallExpression; - var stockCall = new Stack(); - while (expCall != null) { - stockCall.Push(expCall); - expCall = expCall.Object as MethodCallExpression; - } - while (stockCall.Any()) { - expCall = stockCall.Pop(); + protected ISelect InternalFrom(Expression exp) + { + if (exp.NodeType == ExpressionType.Call) + { + var expCall = exp as MethodCallExpression; + var stockCall = new Stack(); + while (expCall != null) + { + stockCall.Push(expCall); + expCall = expCall.Object as MethodCallExpression; + } + while (stockCall.Any()) + { + expCall = stockCall.Pop(); - switch (expCall.Method.Name) { - case "Where": this.InternalWhere(expCall.Arguments[0]); break; - case "WhereIf": - var whereIfCond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); - if (whereIfCond == "1" || whereIfCond == "'t'") - this.InternalWhere(expCall.Arguments[1]); - break; - case "OrderBy": - if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) { - var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); - if (ifcond == "1" || ifcond == "'t'") - this.InternalOrderBy(expCall.Arguments.LastOrDefault()); - break; - } - this.InternalOrderBy(expCall.Arguments.LastOrDefault()); - break; - case "OrderByDescending": - if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) { - var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); - if (ifcond == "1" || ifcond == "'t'") - this.InternalOrderByDescending(expCall.Arguments.LastOrDefault()); - break; - } - this.InternalOrderByDescending(expCall.Arguments.LastOrDefault()); - break; + switch (expCall.Method.Name) + { + case "Where": this.InternalWhere(expCall.Arguments[0]); break; + case "WhereIf": + var whereIfCond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); + if (whereIfCond == "1" || whereIfCond == "'t'") + this.InternalWhere(expCall.Arguments[1]); + break; + case "OrderBy": + if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) + { + var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); + if (ifcond == "1" || ifcond == "'t'") + this.InternalOrderBy(expCall.Arguments.LastOrDefault()); + break; + } + this.InternalOrderBy(expCall.Arguments.LastOrDefault()); + break; + case "OrderByDescending": + if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) + { + var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); + if (ifcond == "1" || ifcond == "'t'") + this.InternalOrderByDescending(expCall.Arguments.LastOrDefault()); + break; + } + this.InternalOrderByDescending(expCall.Arguments.LastOrDefault()); + break; - case "LeftJoin": this.InternalJoin(expCall.Arguments[0], SelectTableInfoType.LeftJoin); break; - case "InnerJoin": this.InternalJoin(expCall.Arguments[0], SelectTableInfoType.InnerJoin); break; - case "RightJoin": this.InternalJoin(expCall.Arguments[0], SelectTableInfoType.RightJoin); break; + case "LeftJoin": this.InternalJoin(expCall.Arguments[0], SelectTableInfoType.LeftJoin); break; + case "InnerJoin": this.InternalJoin(expCall.Arguments[0], SelectTableInfoType.InnerJoin); break; + case "RightJoin": this.InternalJoin(expCall.Arguments[0], SelectTableInfoType.RightJoin); break; - default: throw new NotImplementedException($"未实现 {expCall.Method.Name}"); - } - } - } - return this; - } + default: throw new NotImplementedException($"未实现 {expCall.Method.Name}"); + } + } + } + return this; + } - public ISelect As(string alias) { - var oldAs = _tables.First().Alias; - var newAs = string.IsNullOrEmpty(alias) ? "a" : alias; - if (oldAs != newAs) { - _tables.First().Alias = newAs; - var wh = _where.ToString(); - _where.Replace($" {oldAs}.", $" {newAs}."); - } - return this; - } + public ISelect As(string alias) + { + var oldAs = _tables.First().Alias; + var newAs = string.IsNullOrEmpty(alias) ? "a" : alias; + if (oldAs != newAs) + { + _tables.First().Alias = newAs; + var wh = _where.ToString(); + _where.Replace($" {oldAs}.", $" {newAs}."); + } + return this; + } - public TMember Avg(Expression> column) { - if (column == null) return default(TMember); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalAvg(column?.Body); - } - public Task AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalAvgAsync(column?.Body); - } + public TMember Avg(Expression> column) + { + if (column == null) return default(TMember); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalAvg(column?.Body); + } + public Task AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalAvgAsync(column?.Body); + } - public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class;// { this.InternalFrom(exp?.Body); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class;// { this.InternalFrom(exp?.Body); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class;// { this.InternalFrom(exp?.Body); var ret = new Select4Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class;// { this.InternalFrom(exp?.Body); var ret = new Select5Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class;// { this.InternalFrom(exp?.Body); var ret = new Select6Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class;// { this.InternalFrom(exp?.Body); var ret = new Select7Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class;// { this.InternalFrom(exp?.Body); var ret = new Select8Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class;// { this.InternalFrom(exp?.Body); var ret = new Select9Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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;// { this.InternalFrom(exp?.Body); var ret = new Select10Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class;// { this.InternalFrom(exp?.Body); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class;// { this.InternalFrom(exp?.Body); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class;// { this.InternalFrom(exp?.Body); var ret = new Select4Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class;// { this.InternalFrom(exp?.Body); var ret = new Select5Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class;// { this.InternalFrom(exp?.Body); var ret = new Select6Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class;// { this.InternalFrom(exp?.Body); var ret = new Select7Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class;// { this.InternalFrom(exp?.Body); var ret = new Select8Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class;// { this.InternalFrom(exp?.Body); var ret = new Select9Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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;// { this.InternalFrom(exp?.Body); var ret = new Select10Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public ISelectGrouping GroupBy(Expression> columns) { - if (columns == null) return this.InternalGroupBy(columns); - _tables[0].Parameter = columns.Parameters[0]; - return this.InternalGroupBy(columns); - } + public ISelectGrouping GroupBy(Expression> columns) + { + if (columns == null) return this.InternalGroupBy(columns); + _tables[0].Parameter = columns.Parameters[0]; + return this.InternalGroupBy(columns); + } - public TMember Max(Expression> column) { - if (column == null) return default(TMember); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalMax(column?.Body); - } - public Task MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalMaxAsync(column?.Body); - } + public TMember Max(Expression> column) + { + if (column == null) return default(TMember); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalMax(column?.Body); + } + public Task MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalMaxAsync(column?.Body); + } - public TMember Min(Expression> column) { - if (column == null) return default(TMember); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalMin(column?.Body); - } - public Task MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalMinAsync(column?.Body); - } - public ISelect OrderBy(Expression> column) => this.OrderBy(true, column); - public ISelect OrderBy(bool condition, Expression> column) { - if (condition == false || column == null) return this; - _tables[0].Parameter = column.Parameters[0]; - return this.InternalOrderBy(column?.Body); - } - public ISelect OrderByDescending(Expression> column) => this.OrderByDescending(true, column); - public ISelect OrderByDescending(bool condition, Expression> column) { - if (condition == false || column == null) return this; - _tables[0].Parameter = column.Parameters[0]; - return this.InternalOrderByDescending(column?.Body); - } + public TMember Min(Expression> column) + { + if (column == null) return default(TMember); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalMin(column?.Body); + } + public Task MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalMinAsync(column?.Body); + } + public ISelect OrderBy(Expression> column) => this.OrderBy(true, column); + public ISelect OrderBy(bool condition, Expression> column) + { + if (condition == false || column == null) return this; + _tables[0].Parameter = column.Parameters[0]; + return this.InternalOrderBy(column?.Body); + } + public ISelect OrderByDescending(Expression> column) => this.OrderByDescending(true, column); + public ISelect OrderByDescending(bool condition, Expression> column) + { + if (condition == false || column == null) return this; + _tables[0].Parameter = column.Parameters[0]; + return this.InternalOrderByDescending(column?.Body); + } - public TMember Sum(Expression> column) { - if (column == null) return default(TMember); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalSum(column?.Body); - } - public Task SumAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalSumAsync(column?.Body); - } + public TMember Sum(Expression> column) + { + if (column == null) return default(TMember); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalSum(column?.Body); + } + public Task SumAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalSumAsync(column?.Body); + } - public List ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToList(select?.Body); - } - public Task> ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToListAsync(select?.Body); - } - public List ToList() => ToList(GetToListDtoSelector()); - public Task> ToListAsync() => ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a")); - } + public List ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToList(select?.Body); + } + public Task> ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToListAsync(select?.Body); + } + public List ToList() => ToList(GetToListDtoSelector()); + public Task> ToListAsync() => ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a")); + } - #region linq to sql - public ISelect Select(Expression> select) where TReturn : class { - if (typeof(TReturn) == typeof(T1)) return this as ISelect; - _tables[0].Parameter = select.Parameters[0]; - _selectExpression = select.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TReturn).FullName, true); - var ret = _orm.Select(); - Select0Provider, T1>.CopyData(this, ret, null); - return ret; - } - public ISelect Join(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector) where TInner : class where TResult : class { - _tables[0].Parameter = resultSelector.Parameters[0]; - _commonExpression.ExpressionLambdaToSql(outerKeySelector, new CommonExpression.ExpTSC { _tables = _tables }); - this.InternalJoin(Expression.Lambda>( - Expression.Equal(outerKeySelector.Body, innerKeySelector.Body), - new[] { outerKeySelector.Parameters[0], innerKeySelector.Parameters[0] } - ), SelectTableInfoType.InnerJoin); - if (typeof(TResult) == typeof(T1)) return this as ISelect; - _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); - var ret = _orm.Select() as Select1Provider; - Select0Provider, T1>.CopyData(this, ret, null); - return ret; - } - public ISelect GroupJoin(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector) where TInner : class where TResult : class { - _tables[0].Parameter = resultSelector.Parameters[0]; - _commonExpression.ExpressionLambdaToSql(outerKeySelector, new CommonExpression.ExpTSC { _tables = _tables }); - this.InternalJoin(Expression.Lambda>( - Expression.Equal(outerKeySelector.Body, innerKeySelector.Body), - new[] { outerKeySelector.Parameters[0], innerKeySelector.Parameters[0] } - ), SelectTableInfoType.InnerJoin); - if (typeof(TResult) == typeof(T1)) return this as ISelect; - _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); - var ret = _orm.Select() as Select1Provider; - Select0Provider, T1>.CopyData(this, ret, null); - return ret; - } - public ISelect SelectMany(Expression>> collectionSelector, Expression> resultSelector) where TCollection : class where TResult : class { - SelectTableInfo find = null; - if (collectionSelector.Body.NodeType == ExpressionType.Call) { - var callExp = collectionSelector.Body as MethodCallExpression; - if (callExp.Method.Name == "DefaultIfEmpty" && callExp.Object.Type.GenericTypeArguments.Any()) { - find = _tables.Where((a, idx) => idx > 0 && a.Type == SelectTableInfoType.InnerJoin && a.Table.Type == callExp.Object.Type.GenericTypeArguments[0]).LastOrDefault(); - if (find != null) { - if (!string.IsNullOrEmpty(find.On)) find.On = Regex.Replace(find.On, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); - if (!string.IsNullOrEmpty(find.NavigateCondition)) find.NavigateCondition = Regex.Replace(find.NavigateCondition, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); - find.Type = SelectTableInfoType.LeftJoin; - find.Alias = resultSelector.Parameters[1].Name; - find.Parameter = resultSelector.Parameters[1]; - } - } - } - if (find == null) { - var tb = _commonUtils.GetTableByEntity(typeof(TCollection)); - if (tb == null) throw new Exception($"SelectMany 错误的类型:{typeof(TCollection).FullName}"); - _tables.Add(new SelectTableInfo { Alias = resultSelector.Parameters[1].Name, AliasInit = resultSelector.Parameters[1].Name, Parameter = resultSelector.Parameters[1], Table = tb, Type = SelectTableInfoType.From }); - } - if (typeof(TResult) == typeof(T1)) return this as ISelect; - _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); - var ret = _orm.Select() as Select1Provider; - Select0Provider, T1>.CopyData(this, ret, null); - return ret; - } - public ISelect DefaultIfEmpty() { - return this; - } - #endregion + #region linq to sql + public ISelect Select(Expression> select) where TReturn : class + { + if (typeof(TReturn) == typeof(T1)) return this as ISelect; + _tables[0].Parameter = select.Parameters[0]; + _selectExpression = select.Body; + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TReturn).FullName, true); + var ret = _orm.Select(); + Select0Provider, T1>.CopyData(this, ret, null); + return ret; + } + public ISelect Join(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector) where TInner : class where TResult : class + { + _tables[0].Parameter = resultSelector.Parameters[0]; + _commonExpression.ExpressionLambdaToSql(outerKeySelector, new CommonExpression.ExpTSC { _tables = _tables }); + this.InternalJoin(Expression.Lambda>( + Expression.Equal(outerKeySelector.Body, innerKeySelector.Body), + new[] { outerKeySelector.Parameters[0], innerKeySelector.Parameters[0] } + ), SelectTableInfoType.InnerJoin); + if (typeof(TResult) == typeof(T1)) return this as ISelect; + _selectExpression = resultSelector.Body; + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); + var ret = _orm.Select() as Select1Provider; + Select0Provider, T1>.CopyData(this, ret, null); + return ret; + } + public ISelect GroupJoin(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector) where TInner : class where TResult : class + { + _tables[0].Parameter = resultSelector.Parameters[0]; + _commonExpression.ExpressionLambdaToSql(outerKeySelector, new CommonExpression.ExpTSC { _tables = _tables }); + this.InternalJoin(Expression.Lambda>( + Expression.Equal(outerKeySelector.Body, innerKeySelector.Body), + new[] { outerKeySelector.Parameters[0], innerKeySelector.Parameters[0] } + ), SelectTableInfoType.InnerJoin); + if (typeof(TResult) == typeof(T1)) return this as ISelect; + _selectExpression = resultSelector.Body; + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); + var ret = _orm.Select() as Select1Provider; + Select0Provider, T1>.CopyData(this, ret, null); + return ret; + } + public ISelect SelectMany(Expression>> collectionSelector, Expression> resultSelector) where TCollection : class where TResult : class + { + SelectTableInfo find = null; + if (collectionSelector.Body.NodeType == ExpressionType.Call) + { + var callExp = collectionSelector.Body as MethodCallExpression; + if (callExp.Method.Name == "DefaultIfEmpty" && callExp.Object.Type.GenericTypeArguments.Any()) + { + find = _tables.Where((a, idx) => idx > 0 && a.Type == SelectTableInfoType.InnerJoin && a.Table.Type == callExp.Object.Type.GenericTypeArguments[0]).LastOrDefault(); + if (find != null) + { + if (!string.IsNullOrEmpty(find.On)) find.On = Regex.Replace(find.On, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); + if (!string.IsNullOrEmpty(find.NavigateCondition)) find.NavigateCondition = Regex.Replace(find.NavigateCondition, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); + find.Type = SelectTableInfoType.LeftJoin; + find.Alias = resultSelector.Parameters[1].Name; + find.Parameter = resultSelector.Parameters[1]; + } + } + } + if (find == null) + { + var tb = _commonUtils.GetTableByEntity(typeof(TCollection)); + if (tb == null) throw new Exception($"SelectMany 错误的类型:{typeof(TCollection).FullName}"); + _tables.Add(new SelectTableInfo { Alias = resultSelector.Parameters[1].Name, AliasInit = resultSelector.Parameters[1].Name, Parameter = resultSelector.Parameters[1], Table = tb, Type = SelectTableInfoType.From }); + } + if (typeof(TResult) == typeof(T1)) return this as ISelect; + _selectExpression = resultSelector.Body; + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); + var ret = _orm.Select() as Select1Provider; + Select0Provider, T1>.CopyData(this, ret, null); + return ret; + } + public ISelect DefaultIfEmpty() + { + return this; + } + #endregion - public DataTable ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToDataTable(select?.Body); - } + public DataTable ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToDataTable(select?.Body); + } - public Task ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToDataTableAsync(select?.Body); - } + public Task ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToDataTableAsync(select?.Body); + } - public string ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToSql(select?.Body); - } + public string ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToSql(select?.Body); + } - public TReturn ToAggregate(Expression, TReturn>> select) { - if (select == null) return default(TReturn); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToAggregate(select?.Body); - } + public TReturn ToAggregate(Expression, TReturn>> select) + { + if (select == null) return default(TReturn); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToAggregate(select?.Body); + } - public Task ToAggregateAsync(Expression, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToAggregateAsync(select?.Body); - } + public Task ToAggregateAsync(Expression, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToAggregateAsync(select?.Body); + } - public ISelect Where(Expression> exp) { - if (exp == null) return this; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalWhere(exp?.Body); - } + public ISelect Where(Expression> exp) + { + if (exp == null) return this; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalWhere(exp?.Body); + } - public ISelect Where(Expression> exp) where T2 : class { - if (exp == null) return this; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalWhere(exp?.Body); - } + public ISelect Where(Expression> exp) where T2 : class + { + if (exp == null) return this; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalWhere(exp?.Body); + } - public ISelect Where(Expression> exp) where T2 : class { - if (exp == null) return this; - //_tables[0].Parameter = exp.Parameters[0]; - return this.InternalWhere(exp?.Body); - } + public ISelect Where(Expression> exp) where T2 : class + { + if (exp == null) return this; + //_tables[0].Parameter = exp.Parameters[0]; + return this.InternalWhere(exp?.Body); + } - public ISelect Where(Expression> exp) where T2 : class where T3 : class { - if (exp == null) return this; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalWhere(exp?.Body); - } + public ISelect Where(Expression> exp) where T2 : class where T3 : class + { + if (exp == null) return this; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalWhere(exp?.Body); + } - public ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class { - if (exp == null) return this; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalWhere(exp?.Body); - } + public ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class + { + if (exp == null) return this; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalWhere(exp?.Body); + } - public ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class where T5 : class { - if (exp == null) return this; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalWhere(exp?.Body); - } - public ISelect WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere)); + public ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class where T5 : class + { + if (exp == null) return this; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalWhere(exp?.Body); + } + public ISelect WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere)); - public ISelect WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalWhere(exp?.Body); - } + public ISelect WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + _tables[0].Parameter = exp.Parameters[0]; + return this.InternalWhere(exp?.Body); + } - public bool Any(Expression> exp) => this.Where(exp).Any(); + public bool Any(Expression> exp) => this.Where(exp).Any(); - public Task AnyAsync(Expression> exp) => this.Where(exp).AnyAsync(); + public Task AnyAsync(Expression> exp) => this.Where(exp).AnyAsync(); - public TReturn ToOne(Expression> select) => this.Limit(1).ToList(select).FirstOrDefault(); + public TReturn ToOne(Expression> select) => this.Limit(1).ToList(select).FirstOrDefault(); - async public Task ToOneAsync(Expression> select) => (await this.Limit(1).ToListAsync(select)).FirstOrDefault(); + async public Task ToOneAsync(Expression> select) => (await this.Limit(1).ToListAsync(select)).FirstOrDefault(); - public TReturn First(Expression> select) => this.ToOne(select); + public TReturn First(Expression> select) => this.ToOne(select); - public Task FirstAsync(Expression> select) => this.ToOneAsync(select); + public Task FirstAsync(Expression> select) => this.ToOneAsync(select); - public ISelect Include(Expression> navigateSelector) where TNavigate : class { - var expBody = navigateSelector?.Body; - if (expBody == null) return this; - var tb = _commonUtils.GetTableByEntity(expBody.Type); - if (tb == null) throw new Exception("Include 参数类型错误"); + public ISelect Include(Expression> navigateSelector) where TNavigate : class + { + var expBody = navigateSelector?.Body; + if (expBody == null) return this; + var tb = _commonUtils.GetTableByEntity(expBody.Type); + if (tb == null) throw new Exception("Include 参数类型错误"); - _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); - return this; - } + _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); + return this; + } - static (ParameterExpression param, List members) GetExpressionStack(Expression exp) { - Expression tmpExp = exp; - ParameterExpression param = null; - var members = new List(); - var isbreak = false; - while (isbreak == false) { - switch (tmpExp.NodeType) { - case ExpressionType.MemberAccess: - var memExp = tmpExp as MemberExpression; - tmpExp = memExp.Expression; - members.Add(memExp); - continue; - case ExpressionType.Parameter: - param = tmpExp as ParameterExpression; - isbreak = true; - break; - default: - throw new Exception($"表达式错误,它不是连续的 MemberAccess 类型:{exp}"); - } - } - if (param == null) throw new Exception($"表达式错误,它的顶级对象不是 ParameterExpression:{exp}"); - return (param, members); - } - static MethodInfo GetEntityValueWithPropertyNameMethod = typeof(EntityUtilExtensions).GetMethod("GetEntityValueWithPropertyName"); - static ConcurrentDictionary> _dicTypeMethod = new ConcurrentDictionary>(); - public ISelect IncludeMany(Expression>> navigateSelector, Action> then = null) where TNavigate : class { - var throwNavigateSelector = new Exception("IncludeMany 参数1 类型错误,表达式类型应该为 MemberAccess"); + static (ParameterExpression param, List members) GetExpressionStack(Expression exp) + { + Expression tmpExp = exp; + ParameterExpression param = null; + var members = new List(); + var isbreak = false; + while (isbreak == false) + { + switch (tmpExp.NodeType) + { + case ExpressionType.MemberAccess: + var memExp = tmpExp as MemberExpression; + tmpExp = memExp.Expression; + members.Add(memExp); + continue; + case ExpressionType.Parameter: + param = tmpExp as ParameterExpression; + isbreak = true; + break; + default: + throw new Exception($"表达式错误,它不是连续的 MemberAccess 类型:{exp}"); + } + } + if (param == null) throw new Exception($"表达式错误,它的顶级对象不是 ParameterExpression:{exp}"); + return (param, members); + } + static MethodInfo GetEntityValueWithPropertyNameMethod = typeof(EntityUtilExtensions).GetMethod("GetEntityValueWithPropertyName"); + static ConcurrentDictionary> _dicTypeMethod = new ConcurrentDictionary>(); + public ISelect IncludeMany(Expression>> navigateSelector, Action> then = null) where TNavigate : class + { + var throwNavigateSelector = new Exception("IncludeMany 参数1 类型错误,表达式类型应该为 MemberAccess"); - var expBody = navigateSelector?.Body; - if (expBody == null) return this; - MethodCallExpression whereExp = null; - int takeNumber = 0; - while (expBody.NodeType == ExpressionType.Call) { - throwNavigateSelector = new Exception($"IncludeMany {nameof(navigateSelector)} 参数类型错误,表达式格式应该是 a.collections.Take(1).Where(c => c.aid == a.id)"); - var callExp = (expBody as MethodCallExpression); - switch (callExp.Method.Name) { - case "Where": - whereExp = callExp; - break; - case "Take": takeNumber = int.Parse((callExp.Arguments[1] as ConstantExpression)?.Value?.ToString() ?? "0"); break; - default: throw throwNavigateSelector; - } - expBody = callExp.Object ?? callExp.Arguments.FirstOrDefault(); - } + var expBody = navigateSelector?.Body; + if (expBody == null) return this; + MethodCallExpression whereExp = null; + int takeNumber = 0; + while (expBody.NodeType == ExpressionType.Call) + { + throwNavigateSelector = new Exception($"IncludeMany {nameof(navigateSelector)} 参数类型错误,表达式格式应该是 a.collections.Take(1).Where(c => c.aid == a.id)"); + var callExp = (expBody as MethodCallExpression); + switch (callExp.Method.Name) + { + case "Where": + whereExp = callExp; + break; + case "Take": takeNumber = int.Parse((callExp.Arguments[1] as ConstantExpression)?.Value?.ToString() ?? "0"); break; + default: throw throwNavigateSelector; + } + expBody = callExp.Object ?? callExp.Arguments.FirstOrDefault(); + } - if (expBody.NodeType != ExpressionType.MemberAccess) throw throwNavigateSelector; - var collMem = expBody as MemberExpression; - var (membersParam, members) = GetExpressionStack(collMem.Expression); - var tb = _commonUtils.GetTableByEntity(collMem.Expression.Type); - if (tb == null) throw throwNavigateSelector; - var tbNav = _commonUtils.GetTableByEntity(typeof(TNavigate)); - if (tbNav == null) throw new Exception($"类型 {typeof(TNavigate).FullName} 错误,不能使用 IncludeMany"); + if (expBody.NodeType != ExpressionType.MemberAccess) throw throwNavigateSelector; + var collMem = expBody as MemberExpression; + var (membersParam, members) = GetExpressionStack(collMem.Expression); + var tb = _commonUtils.GetTableByEntity(collMem.Expression.Type); + if (tb == null) throw throwNavigateSelector; + var tbNav = _commonUtils.GetTableByEntity(typeof(TNavigate)); + if (tbNav == null) throw new Exception($"类型 {typeof(TNavigate).FullName} 错误,不能使用 IncludeMany"); - if (collMem.Expression.NodeType != ExpressionType.Parameter) - _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); + if (collMem.Expression.NodeType != ExpressionType.Parameter) + _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); - TableRef tbref = null; - var tbrefOneToManyColumns = new List>(); //临时 OneToMany 三个表关联,第三个表需要前两个表确定 - if (whereExp == null) { + TableRef tbref = null; + var tbrefOneToManyColumns = new List>(); //临时 OneToMany 三个表关联,第三个表需要前两个表确定 + if (whereExp == null) + { - tbref = tb.GetTableRef(collMem.Member.Name, true); + tbref = tb.GetTableRef(collMem.Member.Name, true); - } else { - //处理临时关系映射 - tbref = new TableRef { - RefType = TableRefType.OneToMany, - Property = tb.Properties[collMem.Member.Name], - RefEntityType = tbNav.Type - }; - foreach (var whereExpArg in whereExp.Arguments) { - if (whereExpArg.NodeType != ExpressionType.Lambda) continue; - var whereExpArgLamb = whereExpArg as LambdaExpression; + } + else + { + //处理临时关系映射 + tbref = new TableRef + { + RefType = TableRefType.OneToMany, + Property = tb.Properties[collMem.Member.Name], + RefEntityType = tbNav.Type + }; + foreach (var whereExpArg in whereExp.Arguments) + { + if (whereExpArg.NodeType != ExpressionType.Lambda) continue; + var whereExpArgLamb = whereExpArg as LambdaExpression; - Action actWeiParse = null; - actWeiParse = expOrg => { - var binaryExp = expOrg as BinaryExpression; - if (binaryExp == null) throw throwNavigateSelector; + Action actWeiParse = null; + actWeiParse = expOrg => + { + var binaryExp = expOrg as BinaryExpression; + if (binaryExp == null) throw throwNavigateSelector; - switch (binaryExp.NodeType) { - case ExpressionType.AndAlso: - actWeiParse(binaryExp.Left); - actWeiParse(binaryExp.Right); - break; - case ExpressionType.Equal: - var leftP1MemberExp = binaryExp.Left as MemberExpression; - var rightP1MemberExp = binaryExp.Right as MemberExpression; - if (leftP1MemberExp == null || rightP1MemberExp == null) throw throwNavigateSelector; + switch (binaryExp.NodeType) + { + case ExpressionType.AndAlso: + actWeiParse(binaryExp.Left); + actWeiParse(binaryExp.Right); + break; + case ExpressionType.Equal: + var leftP1MemberExp = binaryExp.Left as MemberExpression; + var rightP1MemberExp = binaryExp.Right as MemberExpression; + if (leftP1MemberExp == null || rightP1MemberExp == null) throw throwNavigateSelector; - if (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) { - var (rightMembersParam, rightMembers) = GetExpressionStack(rightP1MemberExp.Expression); - if (rightMembersParam != membersParam) throw throwNavigateSelector; - var isCollMemEquals = rightMembers.Count == members.Count; - if (isCollMemEquals) { - for (var l = 0; l < members.Count; l++) - if (members[l].Member != rightMembers[l].Member) { - isCollMemEquals = false; - break; - } - } - if (isCollMemEquals) { - tbref.Columns.Add(tb.ColumnsByCs[rightP1MemberExp.Member.Name]); - tbrefOneToManyColumns.Add(null); - } else { - var tmpTb = _commonUtils.GetTableByEntity(rightP1MemberExp.Expression.Type); - if (tmpTb == null) throw throwNavigateSelector; - tbref.Columns.Add(tmpTb.ColumnsByCs[rightP1MemberExp.Member.Name]); - tbrefOneToManyColumns.Add(rightMembers); - } - tbref.RefColumns.Add(tbNav.ColumnsByCs[leftP1MemberExp.Member.Name]); - return; - } - if (rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) { - var (leftMembersParam, leftMembers) = GetExpressionStack(leftP1MemberExp.Expression); - if (leftMembersParam != membersParam) throw throwNavigateSelector; - var isCollMemEquals = leftMembers.Count == members.Count; - if (isCollMemEquals) { - for (var l = 0; l < members.Count; l++) - if (members[l].Member != leftMembers[l].Member) { - isCollMemEquals = false; - break; - } - } - if (isCollMemEquals) { - tbref.Columns.Add(tb.ColumnsByCs[leftP1MemberExp.Member.Name]); - tbrefOneToManyColumns.Add(null); - } else { - var tmpTb = _commonUtils.GetTableByEntity(leftP1MemberExp.Expression.Type); - if (tmpTb == null) throw throwNavigateSelector; - tbref.Columns.Add(tmpTb.ColumnsByCs[leftP1MemberExp.Member.Name]); - tbrefOneToManyColumns.Add(leftMembers); - } - tbref.RefColumns.Add(tbNav.ColumnsByCs[rightP1MemberExp.Member.Name]); - return; - } + if (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) + { + var (rightMembersParam, rightMembers) = GetExpressionStack(rightP1MemberExp.Expression); + if (rightMembersParam != membersParam) throw throwNavigateSelector; + var isCollMemEquals = rightMembers.Count == members.Count; + if (isCollMemEquals) + { + for (var l = 0; l < members.Count; l++) + if (members[l].Member != rightMembers[l].Member) + { + isCollMemEquals = false; + break; + } + } + if (isCollMemEquals) + { + tbref.Columns.Add(tb.ColumnsByCs[rightP1MemberExp.Member.Name]); + tbrefOneToManyColumns.Add(null); + } + else + { + var tmpTb = _commonUtils.GetTableByEntity(rightP1MemberExp.Expression.Type); + if (tmpTb == null) throw throwNavigateSelector; + tbref.Columns.Add(tmpTb.ColumnsByCs[rightP1MemberExp.Member.Name]); + tbrefOneToManyColumns.Add(rightMembers); + } + tbref.RefColumns.Add(tbNav.ColumnsByCs[leftP1MemberExp.Member.Name]); + return; + } + if (rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) + { + var (leftMembersParam, leftMembers) = GetExpressionStack(leftP1MemberExp.Expression); + if (leftMembersParam != membersParam) throw throwNavigateSelector; + var isCollMemEquals = leftMembers.Count == members.Count; + if (isCollMemEquals) + { + for (var l = 0; l < members.Count; l++) + if (members[l].Member != leftMembers[l].Member) + { + isCollMemEquals = false; + break; + } + } + if (isCollMemEquals) + { + tbref.Columns.Add(tb.ColumnsByCs[leftP1MemberExp.Member.Name]); + tbrefOneToManyColumns.Add(null); + } + else + { + var tmpTb = _commonUtils.GetTableByEntity(leftP1MemberExp.Expression.Type); + if (tmpTb == null) throw throwNavigateSelector; + tbref.Columns.Add(tmpTb.ColumnsByCs[leftP1MemberExp.Member.Name]); + tbrefOneToManyColumns.Add(leftMembers); + } + tbref.RefColumns.Add(tbNav.ColumnsByCs[rightP1MemberExp.Member.Name]); + return; + } - throw throwNavigateSelector; - default: throw throwNavigateSelector; - } - }; - actWeiParse(whereExpArgLamb.Body); - break; - } - if (tbref.Columns.Any() == false) throw throwNavigateSelector; - } + throw throwNavigateSelector; + default: throw throwNavigateSelector; + } + }; + actWeiParse(whereExpArgLamb.Body); + break; + } + if (tbref.Columns.Any() == false) throw throwNavigateSelector; + } - _includeToList.Enqueue(listObj => { - var list = listObj as List; - if (list == null) return; - if (list.Any() == false) return; - if (tbref.Columns.Any() == false) return; + _includeToList.Enqueue(listObj => + { + var list = listObj as List; + if (list == null) return; + if (list.Any() == false) return; + if (tbref.Columns.Any() == false) return; - var t1parm = Expression.Parameter(typeof(T1)); - Expression membersExp = t1parm; - foreach (var mem in members) membersExp = Expression.MakeMemberAccess(membersExp, mem.Member); - members.Clear(); + var t1parm = Expression.Parameter(typeof(T1)); + Expression membersExp = t1parm; + foreach (var mem in members) membersExp = Expression.MakeMemberAccess(membersExp, mem.Member); + members.Clear(); - var listValueExp = Expression.Parameter(typeof(List), "listValue"); - var setListValue = Expression.Lambda>>( - Expression.Assign( - Expression.MakeMemberAccess(membersExp, collMem.Member), - Expression.TypeAs(listValueExp, collMem.Type) - ), t1parm, listValueExp).Compile(); + var listValueExp = Expression.Parameter(typeof(List), "listValue"); + var setListValue = Expression.Lambda>>( + Expression.Assign( + Expression.MakeMemberAccess(membersExp, collMem.Member), + Expression.TypeAs(listValueExp, collMem.Type) + ), t1parm, listValueExp).Compile(); - var returnTarget = Expression.Label(typeof(object)); - var propertyNameExp = Expression.Parameter(typeof(string), "propertyName"); - var getListValue1 = Expression.Lambda>( - Expression.Block( - Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - ), t1parm, propertyNameExp).Compile(); + var returnTarget = Expression.Label(typeof(object)); + var propertyNameExp = Expression.Parameter(typeof(string), "propertyName"); + var getListValue1 = Expression.Lambda>( + Expression.Block( + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile(); - var getListValue2 = new List>(); - for (var j = 0; j < tbrefOneToManyColumns.Count; j++) { - if (tbrefOneToManyColumns[j] == null) { - getListValue2.Add(null); - continue; - } - Expression tbrefOneToManyColumnsMembers = t1parm; - foreach (var mem in tbrefOneToManyColumns[j]) tbrefOneToManyColumnsMembers = Expression.MakeMemberAccess(tbrefOneToManyColumnsMembers, mem.Member); - tbrefOneToManyColumns[j].Clear(); - getListValue2.Add(Expression.Lambda>( - Expression.Block( - Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - ), t1parm, propertyNameExp).Compile()); - } - tbrefOneToManyColumns.Clear(); - Func getListValue = (item, propName, colIndex) => { - if (getListValue2.Any() && getListValue2[colIndex] != null) return getListValue2[colIndex](item, propName); - return getListValue1(item, propName); - }; + var getListValue2 = new List>(); + for (var j = 0; j < tbrefOneToManyColumns.Count; j++) + { + if (tbrefOneToManyColumns[j] == null) + { + getListValue2.Add(null); + continue; + } + Expression tbrefOneToManyColumnsMembers = t1parm; + foreach (var mem in tbrefOneToManyColumns[j]) tbrefOneToManyColumnsMembers = Expression.MakeMemberAccess(tbrefOneToManyColumnsMembers, mem.Member); + tbrefOneToManyColumns[j].Clear(); + getListValue2.Add(Expression.Lambda>( + Expression.Block( + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile()); + } + tbrefOneToManyColumns.Clear(); + Func getListValue = (item, propName, colIndex) => + { + if (getListValue2.Any() && getListValue2[colIndex] != null) return getListValue2[colIndex](item, propName); + return getListValue1(item, propName); + }; - foreach (var item in list) - setListValue(item, null); + foreach (var item in list) + setListValue(item, null); - var subSelect = _orm.Select().WithConnection(_connection).WithTransaction(_transaction).TrackToList(_trackToList) as Select1Provider; - if (_tableRules?.Any() == true) - foreach (var tr in _tableRules) subSelect.AsTable(tr); - then?.Invoke(subSelect); - var subSelectT1Alias = subSelect._tables[0].Alias; - var oldWhere = subSelect._where.ToString(); - if (oldWhere.StartsWith(" AND ")) oldWhere = oldWhere.Remove(0, 5); + var subSelect = _orm.Select().WithConnection(_connection).WithTransaction(_transaction).TrackToList(_trackToList) as Select1Provider; + if (_tableRules?.Any() == true) + foreach (var tr in _tableRules) subSelect.AsTable(tr); + then?.Invoke(subSelect); + var subSelectT1Alias = subSelect._tables[0].Alias; + var oldWhere = subSelect._where.ToString(); + if (oldWhere.StartsWith(" AND ")) oldWhere = oldWhere.Remove(0, 5); - switch (tbref.RefType) { - case TableRefType.OneToMany: - if (true) { - var subList = new List(); - var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType); - Func> getWhereDic = () => { - var sbDic = new Dictionary(); - for (var y = 0; y < list.Count; y++) { - var sbWhereOne = new StringBuilder(); - sbWhereOne.Append("("); - for (var z = 0; z < tbref.Columns.Count; z++) { - if (z > 0) sbWhereOne.Append(" AND "); - sbWhereOne.Append(_commonUtils.FormatSql($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}={{0}}", getListValue(list[y], tbref.Columns[z].CsName, z))); - } - sbWhereOne.Append(")"); - var whereOne = sbWhereOne.ToString(); - sbWhereOne.Clear(); - if (sbDic.ContainsKey(whereOne) == false) sbDic.Add(whereOne, true); - } - return sbDic; - }; - if (takeNumber > 0) { - var af = subSelect.GetAllFieldExpressionTreeLevelAll(); - var sbSql = new StringBuilder(); - var sbDic = getWhereDic(); - foreach (var sbd in sbDic) { - subSelect._where.Clear(); - subSelect.Where(sbd.Key).Where(oldWhere).Limit(takeNumber); - sbSql.Append("\r\nUNION ALL\r\nselect * from (").Append(subSelect.ToSql(af.Field)).Append(") ftb"); - } - sbSql.Remove(0, 13); - if (sbDic.Count == 1) sbSql.Remove(0, 15).Remove(sbSql.Length - 5, 5); - sbDic.Clear(); - subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, null); - sbSql.Clear(); - } else { - subSelect._where.Clear(); - if (tbref.Columns.Count == 1) { - var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, - list.Select(a => getListValue(a, tbref.Columns[0].CsName, 0)).Distinct() - .Select(a => Expression.Constant(Convert.ChangeType(a, tbref.Columns[0].CsType))).ToArray()); - var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a"); - var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary()).GetOrAdd("Contains", mn => - typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.Columns[0].CsType); - var refCol = Expression.MakeMemberAccess(otmExpParm1, tbref2.Properties[tbref.RefColumns[0].CsName]); - if (refCol.Type.IsNullableType()) refCol = Expression.Property(refCol, CommonExpression._dicNullableValueProperty.GetOrAdd(refCol.Type, ct1 => ct1.GetProperty("Value"))); - subSelect.Where(Expression.Lambda>( - Expression.Call(null, containsMethod, arrExp, refCol), otmExpParm1)); - } else { - var sbDic = getWhereDic(); - var sbWhere = new StringBuilder(); - foreach (var sbd in sbDic) - sbWhere.Append(" OR ").Append(sbd.Key); - subSelect.Where(sbWhere.Remove(0, 4).ToString()); - sbWhere.Clear(); - sbDic.Clear(); - } - subSelect.Where(oldWhere); - subList = subSelect.ToList(true); - } + switch (tbref.RefType) + { + case TableRefType.OneToMany: + if (true) + { + var subList = new List(); + var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType); + Func> getWhereDic = () => + { + var sbDic = new Dictionary(); + for (var y = 0; y < list.Count; y++) + { + var sbWhereOne = new StringBuilder(); + sbWhereOne.Append("("); + for (var z = 0; z < tbref.Columns.Count; z++) + { + if (z > 0) sbWhereOne.Append(" AND "); + sbWhereOne.Append(_commonUtils.FormatSql($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}={{0}}", getListValue(list[y], tbref.Columns[z].CsName, z))); + } + sbWhereOne.Append(")"); + var whereOne = sbWhereOne.ToString(); + sbWhereOne.Clear(); + if (sbDic.ContainsKey(whereOne) == false) sbDic.Add(whereOne, true); + } + return sbDic; + }; + if (takeNumber > 0) + { + var af = subSelect.GetAllFieldExpressionTreeLevelAll(); + var sbSql = new StringBuilder(); + var sbDic = getWhereDic(); + foreach (var sbd in sbDic) + { + subSelect._where.Clear(); + subSelect.Where(sbd.Key).Where(oldWhere).Limit(takeNumber); + sbSql.Append("\r\nUNION ALL\r\nselect * from (").Append(subSelect.ToSql(af.Field)).Append(") ftb"); + } + sbSql.Remove(0, 13); + if (sbDic.Count == 1) sbSql.Remove(0, 15).Remove(sbSql.Length - 5, 5); + sbDic.Clear(); + subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, null); + sbSql.Clear(); + } + else + { + subSelect._where.Clear(); + if (tbref.Columns.Count == 1) + { + var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, + list.Select(a => getListValue(a, tbref.Columns[0].CsName, 0)).Distinct() + .Select(a => Expression.Constant(Convert.ChangeType(a, tbref.Columns[0].CsType))).ToArray()); + var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a"); + var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary()).GetOrAdd("Contains", mn => + typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.Columns[0].CsType); + var refCol = Expression.MakeMemberAccess(otmExpParm1, tbref2.Properties[tbref.RefColumns[0].CsName]); + if (refCol.Type.IsNullableType()) refCol = Expression.Property(refCol, CommonExpression._dicNullableValueProperty.GetOrAdd(refCol.Type, ct1 => ct1.GetProperty("Value"))); + subSelect.Where(Expression.Lambda>( + Expression.Call(null, containsMethod, arrExp, refCol), otmExpParm1)); + } + else + { + var sbDic = getWhereDic(); + var sbWhere = new StringBuilder(); + foreach (var sbd in sbDic) + sbWhere.Append(" OR ").Append(sbd.Key); + subSelect.Where(sbWhere.Remove(0, 4).ToString()); + sbWhere.Clear(); + sbDic.Clear(); + } + subSelect.Where(oldWhere); + subList = subSelect.ToList(true); + } - if (subList.Any() == false) { - foreach (var item in list) - setListValue(item, new List()); - return; - } + if (subList.Any() == false) + { + foreach (var item in list) + setListValue(item, new List()); + return; + } - Dictionary>> dicList = new Dictionary>>(); - foreach (var item in list) { - if (tbref.Columns.Count == 1) { - dicList.Add(getListValue(item, tbref.Columns[0].CsName, 0).ToString(), Tuple.Create(item, new List())); - } else { - var sb = new StringBuilder(); - for (var z = 0; z < tbref.Columns.Count; z++) { - if (z > 0) sb.Append("*$*"); - sb.Append(getListValue(item, tbref.Columns[z].CsName, z)); - } - dicList.Add(sb.ToString(), Tuple.Create(item, new List())); - sb.Clear(); - } - } - var parentNavs = new List(); - foreach (var navProp in tbref2.Properties) { - if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue; - if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue; - var tr2ref = tbref2.GetTableRef(navProp.Key, false); - if (tr2ref == null) continue; - if (tr2ref.RefType != TableRefType.ManyToOne) continue; - if (tr2ref.RefEntityType != tb.Type) continue; - parentNavs.Add(navProp.Key); - } - foreach (var nav in subList) { - string key = null; - if (tbref.RefColumns.Count == 1) { - key = _orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[0].CsName).ToString(); - } else { - var sb = new StringBuilder(); - for (var z = 0; z < tbref.RefColumns.Count; z++) { - if (z > 0) sb.Append("*$*"); - sb.Append(_orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[z].CsName)); - } - key = sb.ToString(); - sb.Clear(); - } - if (dicList.TryGetValue(key, out var t1item) == false) return; - t1item.Item2.Add(nav); + Dictionary>> dicList = new Dictionary>>(); + foreach (var item in list) + { + if (tbref.Columns.Count == 1) + { + dicList.Add(getListValue(item, tbref.Columns[0].CsName, 0).ToString(), Tuple.Create(item, new List())); + } + else + { + var sb = new StringBuilder(); + for (var z = 0; z < tbref.Columns.Count; z++) + { + if (z > 0) sb.Append("*$*"); + sb.Append(getListValue(item, tbref.Columns[z].CsName, z)); + } + dicList.Add(sb.ToString(), Tuple.Create(item, new List())); + sb.Clear(); + } + } + var parentNavs = new List(); + foreach (var navProp in tbref2.Properties) + { + if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue; + if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue; + var tr2ref = tbref2.GetTableRef(navProp.Key, false); + if (tr2ref == null) continue; + if (tr2ref.RefType != TableRefType.ManyToOne) continue; + if (tr2ref.RefEntityType != tb.Type) continue; + parentNavs.Add(navProp.Key); + } + foreach (var nav in subList) + { + string key = null; + if (tbref.RefColumns.Count == 1) + { + key = _orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[0].CsName).ToString(); + } + else + { + var sb = new StringBuilder(); + for (var z = 0; z < tbref.RefColumns.Count; z++) + { + if (z > 0) sb.Append("*$*"); + sb.Append(_orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[z].CsName)); + } + key = sb.ToString(); + sb.Clear(); + } + if (dicList.TryGetValue(key, out var t1item) == false) return; + t1item.Item2.Add(nav); - //将子集合的,多对一,对象设置为当前对象 - foreach (var parentNav in parentNavs) - _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1); - } - foreach (var t1item in dicList.Values) - setListValue(t1item.Item1, t1item.Item2); - dicList.Clear(); - } - break; - case TableRefType.ManyToMany: - if (true) { - List subList = null; - List midList = new List(); - var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType); - var tbrefMid = _commonUtils.GetTableByEntity(tbref.RefMiddleEntityType); - var sbJoin = new StringBuilder().Append($"{_commonUtils.QuoteSqlName(tbrefMid.DbName)} midtb ON "); - for (var z = 0; z < tbref.RefColumns.Count; z++) { - if (z > 0) sbJoin.Append(" AND "); - sbJoin.Append($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}"); - } - subSelect.InnerJoin(sbJoin.ToString()); - sbJoin.Clear(); + //将子集合的,多对一,对象设置为当前对象 + foreach (var parentNav in parentNavs) + _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1); + } + foreach (var t1item in dicList.Values) + setListValue(t1item.Item1, t1item.Item2); + dicList.Clear(); + } + break; + case TableRefType.ManyToMany: + if (true) + { + List subList = null; + List midList = new List(); + var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType); + var tbrefMid = _commonUtils.GetTableByEntity(tbref.RefMiddleEntityType); + var sbJoin = new StringBuilder().Append($"{_commonUtils.QuoteSqlName(tbrefMid.DbName)} midtb ON "); + for (var z = 0; z < tbref.RefColumns.Count; z++) + { + if (z > 0) sbJoin.Append(" AND "); + sbJoin.Append($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}"); + } + subSelect.InnerJoin(sbJoin.ToString()); + sbJoin.Clear(); - var af = subSelect.GetAllFieldExpressionTreeLevelAll(); - (string field, ReadAnonymousTypeInfo read)? otherData = null; - var sbSql = new StringBuilder(); + var af = subSelect.GetAllFieldExpressionTreeLevelAll(); + (string field, ReadAnonymousTypeInfo read)? otherData = null; + var sbSql = new StringBuilder(); - if (_selectExpression == null) {// return this.InternalToList(_selectExpression).Select(a => (a, ()).ToList(); - var field = new StringBuilder(); - var read = new ReadAnonymousTypeInfo(); - read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - read.Consturctor = (tbrefMid.TypeLazy ?? tbrefMid.Type).GetConstructor(new Type[0]); - read.Table = tbrefMid; - foreach (var col in tbrefMid.Columns.Values) { - if (tbref.MiddleColumns.Where(a => a.CsName == col.CsName).Any() == false) continue; - var child = new ReadAnonymousTypeInfo { - CsName = col.CsName, - CsType = col.CsType, - DbField = $"midtb.{_commonUtils.QuoteSqlName(col.Attribute.Name)}", - MapType = col.Attribute.MapType, - Property = tbrefMid.Properties[col.CsName] - }; - read.Childs.Add(child); - field.Append(", ").Append(_commonUtils.QuoteReadColumn(child.MapType, child.DbField)); - } - otherData = (field.ToString(), read); - } - Func> getWhereDic = () => { - var sbDic = new Dictionary(); - for (var y = 0; y < list.Count; y++) { - var sbWhereOne = new StringBuilder(); - sbWhereOne.Append("("); - for (var z = 0; z < tbref.Columns.Count; z++) { - if (z > 0) sbWhereOne.Append(" AND "); - sbWhereOne.Append(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", getListValue1(list[y], tbref.Columns[z].CsName))); - } - sbWhereOne.Append(")"); - var whereOne = sbWhereOne.ToString(); - sbWhereOne.Clear(); - if (sbDic.ContainsKey(whereOne) == false) sbDic.Add(whereOne, true); - } - return sbDic; - }; + if (_selectExpression == null) + {// return this.InternalToList(_selectExpression).Select(a => (a, ()).ToList(); + var field = new StringBuilder(); + var read = new ReadAnonymousTypeInfo(); + read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + read.Consturctor = (tbrefMid.TypeLazy ?? tbrefMid.Type).GetConstructor(new Type[0]); + read.Table = tbrefMid; + foreach (var col in tbrefMid.Columns.Values) + { + if (tbref.MiddleColumns.Where(a => a.CsName == col.CsName).Any() == false) continue; + var child = new ReadAnonymousTypeInfo + { + CsName = col.CsName, + CsType = col.CsType, + DbField = $"midtb.{_commonUtils.QuoteSqlName(col.Attribute.Name)}", + MapType = col.Attribute.MapType, + Property = tbrefMid.Properties[col.CsName] + }; + read.Childs.Add(child); + field.Append(", ").Append(_commonUtils.QuoteReadColumn(child.MapType, child.DbField)); + } + otherData = (field.ToString(), read); + } + Func> getWhereDic = () => + { + var sbDic = new Dictionary(); + for (var y = 0; y < list.Count; y++) + { + var sbWhereOne = new StringBuilder(); + sbWhereOne.Append("("); + for (var z = 0; z < tbref.Columns.Count; z++) + { + if (z > 0) sbWhereOne.Append(" AND "); + sbWhereOne.Append(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", getListValue1(list[y], tbref.Columns[z].CsName))); + } + sbWhereOne.Append(")"); + var whereOne = sbWhereOne.ToString(); + sbWhereOne.Clear(); + if (sbDic.ContainsKey(whereOne) == false) sbDic.Add(whereOne, true); + } + return sbDic; + }; - if (takeNumber > 0) { - var sbDic = getWhereDic(); - foreach (var sbd in sbDic) { - subSelect._where.Clear(); - subSelect.Where(sbd.Key).Where(oldWhere).Limit(takeNumber); - sbSql.Append("\r\nUNION ALL\r\nselect * from (").Append(subSelect.ToSql($"{af.Field}{otherData?.field}")).Append(") ftb"); - } - sbSql.Remove(0, 13); - if (sbDic.Count == 1) sbSql.Remove(0, 15).Remove(sbSql.Length - 5, 5); - sbDic.Clear(); - } else { - subSelect._where.Clear(); - if (tbref.Columns.Count == 1) { - subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue1(a, tbref.Columns[0].CsName)).Distinct())); - } else { - var sbDic = getWhereDic(); - var sbWhere = new StringBuilder(); - foreach (var sbd in sbDic) - sbWhere.Append(" OR ").Append(sbd.Key); - subSelect.Where(sbWhere.Remove(0, 4).ToString()); - sbWhere.Clear(); - sbDic.Clear(); - } - subSelect.Where(oldWhere); - sbSql.Append(subSelect.ToSql($"{af.Field}{otherData?.field}")); - } + if (takeNumber > 0) + { + var sbDic = getWhereDic(); + foreach (var sbd in sbDic) + { + subSelect._where.Clear(); + subSelect.Where(sbd.Key).Where(oldWhere).Limit(takeNumber); + sbSql.Append("\r\nUNION ALL\r\nselect * from (").Append(subSelect.ToSql($"{af.Field}{otherData?.field}")).Append(") ftb"); + } + sbSql.Remove(0, 13); + if (sbDic.Count == 1) sbSql.Remove(0, 15).Remove(sbSql.Length - 5, 5); + sbDic.Clear(); + } + else + { + subSelect._where.Clear(); + if (tbref.Columns.Count == 1) + { + subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue1(a, tbref.Columns[0].CsName)).Distinct())); + } + else + { + var sbDic = getWhereDic(); + var sbWhere = new StringBuilder(); + foreach (var sbd in sbDic) + sbWhere.Append(" OR ").Append(sbd.Key); + subSelect.Where(sbWhere.Remove(0, 4).ToString()); + sbWhere.Clear(); + sbDic.Clear(); + } + subSelect.Where(oldWhere); + sbSql.Append(subSelect.ToSql($"{af.Field}{otherData?.field}")); + } - subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); - if (subList.Any() == false) { - foreach (var item in list) - setListValue(item, new List()); - return; - } + subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + if (subList.Any() == false) + { + foreach (var item in list) + setListValue(item, new List()); + return; + } - Dictionary>>> dicList = new Dictionary>>>(); - foreach (var item in list) { - if (tbref.Columns.Count == 1) { - var dicListKey = getListValue1(item, tbref.Columns[0].CsName).ToString(); - var dicListVal = Tuple.Create(item, new List()); - if (dicList.TryGetValue(dicListKey, out var items) == false) - dicList.Add(dicListKey, items = new List>>()); - items.Add(dicListVal); - } else { - var sb = new StringBuilder(); - for (var z = 0; z < tbref.Columns.Count; z++) { - if (z > 0) sb.Append("*$*"); - sb.Append(getListValue1(item, tbref.Columns[z].CsName)); - } - var dicListKey = sb.ToString(); - var dicListVal = Tuple.Create(item, new List()); - if (dicList.TryGetValue(dicListKey, out var items) == false) - dicList.Add(dicListKey, items = new List>>()); - items.Add(dicListVal); - sb.Clear(); - } - } - for (var a = 0; a < subList.Count; a++) { - string key = null; - if (tbref.Columns.Count == 1) { - key = _orm.GetEntityValueWithPropertyName(tbref.RefMiddleEntityType, midList[a], tbref.MiddleColumns[0].CsName).ToString(); - } else { - var sb = new StringBuilder(); - for (var z = 0; z < tbref.Columns.Count; z++) { - if (z > 0) sb.Append("*$*"); - sb.Append(_orm.GetEntityValueWithPropertyName(tbref.RefMiddleEntityType, midList[a], tbref.MiddleColumns[z].CsName)); - } - key = sb.ToString(); - sb.Clear(); - } - if (dicList.TryGetValue(key, out var t1items) == false) return; - foreach (var t1item in t1items) - t1item.Item2.Add(subList[a]); - } - foreach (var t1items in dicList.Values) - foreach (var t1item in t1items) - setListValue(t1item.Item1, t1item.Item2); - dicList.Clear(); - } - break; - } - }); - return this; - } - } + Dictionary>>> dicList = new Dictionary>>>(); + foreach (var item in list) + { + if (tbref.Columns.Count == 1) + { + var dicListKey = getListValue1(item, tbref.Columns[0].CsName).ToString(); + var dicListVal = Tuple.Create(item, new List()); + if (dicList.TryGetValue(dicListKey, out var items) == false) + dicList.Add(dicListKey, items = new List>>()); + items.Add(dicListVal); + } + else + { + var sb = new StringBuilder(); + for (var z = 0; z < tbref.Columns.Count; z++) + { + if (z > 0) sb.Append("*$*"); + sb.Append(getListValue1(item, tbref.Columns[z].CsName)); + } + var dicListKey = sb.ToString(); + var dicListVal = Tuple.Create(item, new List()); + if (dicList.TryGetValue(dicListKey, out var items) == false) + dicList.Add(dicListKey, items = new List>>()); + items.Add(dicListVal); + sb.Clear(); + } + } + for (var a = 0; a < subList.Count; a++) + { + string key = null; + if (tbref.Columns.Count == 1) + { + key = _orm.GetEntityValueWithPropertyName(tbref.RefMiddleEntityType, midList[a], tbref.MiddleColumns[0].CsName).ToString(); + } + else + { + var sb = new StringBuilder(); + for (var z = 0; z < tbref.Columns.Count; z++) + { + if (z > 0) sb.Append("*$*"); + sb.Append(_orm.GetEntityValueWithPropertyName(tbref.RefMiddleEntityType, midList[a], tbref.MiddleColumns[z].CsName)); + } + key = sb.ToString(); + sb.Clear(); + } + if (dicList.TryGetValue(key, out var t1items) == false) return; + foreach (var t1item in t1items) + t1item.Item2.Add(subList[a]); + } + foreach (var t1items in dicList.Values) + foreach (var t1item in t1items) + setListValue(t1item.Item1, t1item.Item2); + dicList.Clear(); + } + break; + } + }); + return this; + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index bcb5a1fd..d8a756ea 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -5,154 +5,180 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select2Provider : Select0Provider, T1>, ISelect - where T1 : class - where T2 : class { + public abstract class Select2Provider : Select0Provider, T1>, ISelect + where T1 : class + where T2 : class + { - public Select2Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - } + public Select2Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b")); - } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b")); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 74fcf00a..32f58181 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -5,157 +5,183 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select3Provider : Select0Provider, T1>, ISelect - where T1 : class - where T2 : class - where T3 : class { + public abstract class Select3Provider : Select0Provider, T1>, ISelect + where T1 : class + where T2 : class + where T3 : class + { - public Select3Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - } + public Select3Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c")); - } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c")); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index e32cf2b0..92260a34 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -5,160 +5,186 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select4Provider : Select0Provider, T1>, ISelect - where T1 : class - where T2 : class - where T3 : class - where T4 : class { + public abstract class Select4Provider : Select0Provider, T1>, ISelect + where T1 : class + where T2 : class + where T3 : class + where T4 : class + { - public Select4Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - } + public Select4Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d")); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d")); + } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index f7658f27..b59a67c2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -5,163 +5,189 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select5Provider : Select0Provider, T1>, ISelect - where T1 : class - where T2 : class - where T3 : class - where T4 : class - where T5 : class { + public abstract class Select5Provider : Select0Provider, T1>, ISelect + where T1 : class + where T2 : class + where T3 : class + where T4 : class + where T5 : class + { - public Select5Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - } + public Select5Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e")); - } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e")); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 129f85db..10f315ee 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -5,166 +5,192 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select6Provider : Select0Provider, T1>, ISelect - where T1 : class - where T2 : class - where T3 : class - where T4 : class - where T5 : class - where T6 : class { + public abstract class Select6Provider : Select0Provider, T1>, ISelect + where T1 : class + where T2 : class + where T3 : class + where T4 : class + where T5 : class + where T6 : class + { - public Select6Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - } + public Select6Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f")); - } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f")); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 12989751..a3b8705a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -5,169 +5,195 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select7Provider : Select0Provider, T1>, ISelect - where T1 : class - where T2 : class - where T3 : class - where T4 : class - where T5 : class - where T6 : class - where T7 : class { + public abstract class Select7Provider : Select0Provider, T1>, ISelect + where T1 : class + where T2 : class + where T3 : class + where T4 : class + where T5 : class + where T6 : class + where T7 : class + { - public Select7Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - } + public Select7Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g")); - } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g")); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 3815c2d5..3926173e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -5,172 +5,198 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select8Provider : Select0Provider, T1>, ISelect - where T1 : class - where T2 : class - where T3 : class - where T4 : class - where T5 : class - where T6 : class - where T7 : class - where T8 : class { + public abstract class Select8Provider : Select0Provider, T1>, ISelect + where T1 : class + where T2 : class + where T3 : class + where T4 : class + where T5 : class + where T6 : class + where T7 : class + where T8 : class + { - public Select8Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - } + public Select8Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h")); - } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h")); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index f9223ee3..3c953b74 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -5,175 +5,201 @@ using System.Data; using System.Linq.Expressions; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract class Select9Provider : Select0Provider, T1>, ISelect - 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 { + public abstract class Select9Provider : Select0Provider, T1>, ISelect + 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 + { - public Select9Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - } + public Select9Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + } - TMember ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } + TMember ISelect.Avg(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } - Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } - ISelectGrouping ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); - } + ISelectGrouping ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy(exp?.Body); + } - TMember ISelect.Max(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } - Task ISelect.MaxAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } - TMember ISelect.Min(Expression> column) { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } - Task ISelect.MinAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } - ISelect ISelect.OrderBy(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } - ISelect ISelect.OrderByDescending(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } - TMember ISelect.Sum(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } + TMember ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } - Task ISelect.SumAsync(Expression> column) { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } - List ISelect.ToList(Expression> select) { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - Task> ISelect.ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i")); - } + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + var ctor = typeof(TDto).GetConstructor(new Type[0]); + return Expression.Lambda>(Expression.New(ctor), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h"), + Expression.Parameter(typeof(T9), "i")); + } - DataTable ISelect.ToDataTable(Expression> select) { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } - Task ISelect.ToDataTableAsync(Expression> select) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } - string ISelect.ToSql(Expression> select) { - if (select == null) return this.InternalToSql(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); - } + string ISelect.ToSql(Expression> select) + { + if (select == null) return this.InternalToSql(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body); + } - ISelect ISelect.Where(Expression> exp) { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); - } + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + } - bool ISelect.Any(Expression> exp) { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); - } + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + } - Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); - } - } + Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 9389c832..810c9069 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -7,140 +7,161 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { - public class SelectGroupingProvider : ISelectGrouping { +namespace FreeSql.Internal.CommonProvider +{ + public class SelectGroupingProvider : ISelectGrouping + { - internal object _select; - internal ReadAnonymousTypeInfo _map; - internal CommonExpression _comonExp; - internal List _tables; - public SelectGroupingProvider(object select, ReadAnonymousTypeInfo map, CommonExpression comonExp, List tables) { - _select = select; - _map = map; - _comonExp = comonExp; - _tables = tables; - } + internal object _select; + internal ReadAnonymousTypeInfo _map; + internal CommonExpression _comonExp; + internal List _tables; + public SelectGroupingProvider(object select, ReadAnonymousTypeInfo map, CommonExpression comonExp, List tables) + { + _select = select; + _map = map; + _comonExp = comonExp; + _tables = tables; + } - string getSelectGroupingMapString(Expression[] members) { - if (members.Any() == false) return _map.DbField; - var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name; - switch (parentName) { - case "Key": - var read = _map; - for (var a = 0; a < members.Length; a++) { - read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault(); - if (read == null) return null; - } - return read.DbField; - case "Value": - var tb = _tables.First(); - var foridx = 0; - if (members.Length > 1) { - var mem0 = (members.FirstOrDefault() as MemberExpression); - var mem0Name = mem0?.Member.Name; - if (mem0Name?.StartsWith("Item") == true && int.TryParse(mem0Name.Substring(4), out var tryitemidx)) { - if (tryitemidx == 1) foridx++; - else { - //var alias = $"SP10{(char)(96 + tryitemidx)}"; - var tmptb = _tables.Where((a,idx) => //a.AliasInit == alias && - a.Table.Type == mem0.Type && idx == tryitemidx - 1).FirstOrDefault(); - if (tmptb != null) { - tb = tmptb; - foridx++; - } - } - } - } - var parmExp = Expression.Parameter(tb.Table.Type, tb.Alias); - Expression retExp = parmExp; - for (var a = foridx; a < members.Length; a++) { - switch (members[a].NodeType) { - case ExpressionType.Call: - retExp = Expression.Call(retExp, (members[a] as MethodCallExpression).Method); - break; - case ExpressionType.MemberAccess: - retExp = Expression.MakeMemberAccess(retExp, (members[a] as MemberExpression).Member); - break; - default: - return null; - } - } - return _comonExp.ExpressionLambdaToSql(retExp, new CommonExpression.ExpTSC { _tables = _tables, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = true, style = CommonExpression.ExpressionStyle.Where }); - } - return null; - } + string getSelectGroupingMapString(Expression[] members) + { + if (members.Any() == false) return _map.DbField; + var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name; + switch (parentName) + { + case "Key": + var read = _map; + for (var a = 0; a < members.Length; a++) + { + read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault(); + if (read == null) return null; + } + return read.DbField; + case "Value": + var tb = _tables.First(); + var foridx = 0; + if (members.Length > 1) + { + var mem0 = (members.FirstOrDefault() as MemberExpression); + var mem0Name = mem0?.Member.Name; + if (mem0Name?.StartsWith("Item") == true && int.TryParse(mem0Name.Substring(4), out var tryitemidx)) + { + if (tryitemidx == 1) foridx++; + else + { + //var alias = $"SP10{(char)(96 + tryitemidx)}"; + var tmptb = _tables.Where((a, idx) => //a.AliasInit == alias && + a.Table.Type == mem0.Type && idx == tryitemidx - 1).FirstOrDefault(); + if (tmptb != null) + { + tb = tmptb; + foridx++; + } + } + } + } + var parmExp = Expression.Parameter(tb.Table.Type, tb.Alias); + Expression retExp = parmExp; + for (var a = foridx; a < members.Length; a++) + { + switch (members[a].NodeType) + { + case ExpressionType.Call: + retExp = Expression.Call(retExp, (members[a] as MethodCallExpression).Method); + break; + case ExpressionType.MemberAccess: + retExp = Expression.MakeMemberAccess(retExp, (members[a] as MemberExpression).Member); + break; + default: + return null; + } + } + return _comonExp.ExpressionLambdaToSql(retExp, new CommonExpression.ExpTSC { _tables = _tables, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = true, style = CommonExpression.ExpressionStyle.Where }); + } + return null; + } - public ISelectGrouping Having(Expression, bool>> exp) { - var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString); - var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) }); - method.Invoke(_select, new object[] { sql, null }); - return this; - } + public ISelectGrouping Having(Expression, bool>> exp) + { + var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString); + var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) }); + method.Invoke(_select, new object[] { sql, null }); + return this; + } - public ISelectGrouping OrderBy(Expression, TMember>> column) { - var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString); - var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); - method.Invoke(_select, new object[] { sql, null }); - return this; - } + public ISelectGrouping OrderBy(Expression, TMember>> column) + { + var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString); + var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); + method.Invoke(_select, new object[] { sql, null }); + return this; + } - public ISelectGrouping OrderByDescending(Expression, TMember>> column) { - var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString); - var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); - method.Invoke(_select, new object[] { $"{sql} DESC", null }); - return this; - } + public ISelectGrouping OrderByDescending(Expression, TMember>> column) + { + var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString); + var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); + method.Invoke(_select, new object[] { $"{sql} DESC", null }); + return this; + } - public List ToList(Expression, TReturn>> select) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; + public List ToList(Expression, TReturn>> select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); - var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(typeof(TReturn)); - return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; - } - public Task> ToListAsync(Expression, TReturn>> select) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); + var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(typeof(TReturn)); + return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; + } + public Task> ToListAsync(Expression, TReturn>> select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); - var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(typeof(TReturn)); - return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; - } - public List Select(Expression, TReturn>> select) => ToList(select); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); + var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(typeof(TReturn)); + return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; + } + public List Select(Expression, TReturn>> select) => ToList(select); - public string ToSql(Expression, TReturn>> select) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; + public string ToSql(Expression, TReturn>> select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); - var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); - return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; - } + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); + var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); + return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; + } - public ISelectGrouping Skip(int offset) { - var method = _select.GetType().GetMethod("Skip", new[] { typeof(int) }); - method.Invoke(_select, new object[] { offset }); - return this; - } - public ISelectGrouping Offset(int offset) => this.Skip(offset); + public ISelectGrouping Skip(int offset) + { + var method = _select.GetType().GetMethod("Skip", new[] { typeof(int) }); + method.Invoke(_select, new object[] { offset }); + return this; + } + public ISelectGrouping Offset(int offset) => this.Skip(offset); - public ISelectGrouping Limit(int limit) { - var method = _select.GetType().GetMethod("Limit", new[] { typeof(int) }); - method.Invoke(_select, new object[] { limit }); - return this; - } - public ISelectGrouping Take(int limit) => this.Limit(limit); + public ISelectGrouping Limit(int limit) + { + var method = _select.GetType().GetMethod("Limit", new[] { typeof(int) }); + method.Invoke(_select, new object[] { limit }); + return this; + } + public ISelectGrouping Take(int limit) => this.Limit(limit); - public ISelectGrouping Page(int pageNumber, int pageSize) { - var method = _select.GetType().GetMethod("Page", new[] { typeof(int), typeof(int) }); - method.Invoke(_select, new object[] { pageNumber, pageSize }); - return this; - } - } + public ISelectGrouping Page(int pageNumber, int pageSize) + { + var method = _select.GetType().GetMethod("Page", new[] { typeof(int), typeof(int) }); + method.Invoke(_select, new object[] { pageNumber, pageSize }); + return this; + } + } } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 9843e35b..1c06ebcb 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -10,552 +10,668 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Internal.CommonProvider { +namespace FreeSql.Internal.CommonProvider +{ - public abstract partial class UpdateProvider : IUpdate where T1 : class { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected List _source = new List(); - protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - protected TableInfo _table; - protected Func _tableRule; - protected StringBuilder _where = new StringBuilder(); - protected StringBuilder _set = new StringBuilder(); - protected StringBuilder _setIncr = new StringBuilder(); - protected List _params = new List(); - protected List _paramsSource = new List(); - protected bool _noneParameter; - protected DbTransaction _transaction; - protected DbConnection _connection; + public abstract partial class UpdateProvider : IUpdate where T1 : class + { + protected IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + protected List _source = new List(); + protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + protected TableInfo _table; + protected Func _tableRule; + protected StringBuilder _where = new StringBuilder(); + protected StringBuilder _set = new StringBuilder(); + protected StringBuilder _setIncr = new StringBuilder(); + protected List _params = new List(); + protected List _paramsSource = new List(); + protected bool _noneParameter; + protected DbTransaction _transaction; + protected DbConnection _connection; - public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - _table = _commonUtils.GetTableByEntity(typeof(T1)); - _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; - this.Where(_commonUtils.WhereObject(_table, "", dywhere)); - if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); - } + public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + _table = _commonUtils.GetTableByEntity(typeof(T1)); + _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; + this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + } - protected void ClearData() { - _source.Clear(); - _ignore.Clear(); - _where.Clear(); - _set.Clear(); - _setIncr.Clear(); - _params.Clear(); - _paramsSource.Clear(); - } + protected void ClearData() + { + _source.Clear(); + _ignore.Clear(); + _where.Clear(); + _set.Clear(); + _setIncr.Clear(); + _params.Clear(); + _paramsSource.Clear(); + } - public IUpdate WithTransaction(DbTransaction transaction) { - _transaction = transaction; - _connection = _transaction?.Connection; - return this; - } - public IUpdate WithConnection(DbConnection connection) { - if (_transaction?.Connection != connection) _transaction = null; - _connection = connection; - return this; - } + public IUpdate WithTransaction(DbTransaction transaction) + { + _transaction = transaction; + _connection = _transaction?.Connection; + return this; + } + public IUpdate WithConnection(DbConnection connection) + { + if (_transaction?.Connection != connection) _transaction = null; + _connection = connection; + return this; + } - public IUpdate NoneParameter() { - _noneParameter = true; - return this; - } + public IUpdate NoneParameter() + { + _noneParameter = true; + return this; + } - protected void ValidateVersionAndThrow(int affrows) { - if (_table.VersionColumn != null && _source.Count > 0) { - if (affrows != _source.Count) - throw new Exception($"记录可能不存在,或者【行级乐观锁】版本过旧,更新数量{_source.Count},影响的行数{affrows}。"); - foreach (var d in _source) - _orm.SetEntityIncrByWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, 1); - } - } + protected void ValidateVersionAndThrow(int affrows) + { + if (_table.VersionColumn != null && _source.Count > 0) + { + if (affrows != _source.Count) + throw new Exception($"记录可能不存在,或者【行级乐观锁】版本过旧,更新数量{_source.Count},影响的行数{affrows}。"); + foreach (var d in _source) + _orm.SetEntityIncrByWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, 1); + } + } - #region 参数化数据限制,或values数量限制 - internal List[] SplitSource(int valuesLimit, int parameterLimit) { - valuesLimit = valuesLimit - 1; - parameterLimit = parameterLimit - 1; - if (_source == null || _source.Any() == false) return new List[0]; - if (_source.Count == 1) return new[] { _source }; - if (_noneParameter) { - if (_source.Count < valuesLimit) return new[] { _source }; + #region 参数化数据限制,或values数量限制 + internal List[] SplitSource(int valuesLimit, int parameterLimit) + { + valuesLimit = valuesLimit - 1; + parameterLimit = parameterLimit - 1; + if (_source == null || _source.Any() == false) return new List[0]; + if (_source.Count == 1) return new[] { _source }; + if (_noneParameter) + { + if (_source.Count < valuesLimit) return new[] { _source }; - var execCount = (int)Math.Ceiling(1.0 * _source.Count / valuesLimit); - var ret = new List[execCount]; - for (var a = 0; a < execCount; a++) { - var subSource = new List(); - subSource = _source.GetRange(a * valuesLimit, Math.Min(valuesLimit, _source.Count - a * valuesLimit)); - ret[a] = subSource; - } - return ret; - } else { - var colSum = _table.Columns.Count - _ignore.Count; - var takeMax = parameterLimit / colSum; - var pamTotal = colSum * _source.Count; - if (pamTotal < parameterLimit) return new[] { _source }; + var execCount = (int)Math.Ceiling(1.0 * _source.Count / valuesLimit); + var ret = new List[execCount]; + for (var a = 0; a < execCount; a++) + { + var subSource = new List(); + subSource = _source.GetRange(a * valuesLimit, Math.Min(valuesLimit, _source.Count - a * valuesLimit)); + ret[a] = subSource; + } + return ret; + } + else + { + var colSum = _table.Columns.Count - _ignore.Count; + var takeMax = parameterLimit / colSum; + var pamTotal = colSum * _source.Count; + if (pamTotal < parameterLimit) return new[] { _source }; - var execCount = (int)Math.Ceiling(1.0 * pamTotal / takeMax / colSum); - var ret = new List[execCount]; - for (var a = 0; a < execCount; a++) { - var subSource = new List(); - subSource = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); - ret[a] = subSource; - } - return ret; - } - } - protected int SplitExecuteAffrows(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = 0; - if (ss.Length <= 1) { - ret = this.RawExecuteAffrows(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret += this.RawExecuteAffrows(); - } - } else { - using (var conn = _orm.Ado.MasterPool.Get()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret += this.RawExecuteAffrows(); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = 0; - if (ss.Length <= 1) { - ret = await this.RawExecuteAffrowsAsync(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - } else { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - protected List SplitExecuteUpdated(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = new List(); - if (ss.Length <= 1) { - ret = this.RawExecuteUpdated(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret.AddRange(this.RawExecuteUpdated()); - } - } else { - using (var conn = _orm.Ado.MasterPool.Get()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret.AddRange(this.RawExecuteUpdated()); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - async protected Task> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = new List(); - if (ss.Length <= 1) { - ret = await this.RawExecuteUpdatedAsync(); - ClearData(); - return ret; - } - if (_transaction != null) { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret.AddRange(await this.RawExecuteUpdatedAsync()); - } - } else { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) { - _transaction = conn.Value.BeginTransaction(); - try { - for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; - ret.AddRange(await this.RawExecuteUpdatedAsync()); - } - _transaction.Commit(); - } catch { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } - #endregion + var execCount = (int)Math.Ceiling(1.0 * pamTotal / takeMax / colSum); + var ret = new List[execCount]; + for (var a = 0; a < execCount; a++) + { + var subSource = new List(); + subSource = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); + ret[a] = subSource; + } + return ret; + } + } + protected int SplitExecuteAffrows(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = 0; + if (ss.Length <= 1) + { + ret = this.RawExecuteAffrows(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += this.RawExecuteAffrows(); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += this.RawExecuteAffrows(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = 0; + if (ss.Length <= 1) + { + ret = await this.RawExecuteAffrowsAsync(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + protected List SplitExecuteUpdated(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = new List(); + if (ss.Length <= 1) + { + ret = this.RawExecuteUpdated(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(this.RawExecuteUpdated()); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(this.RawExecuteUpdated()); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + async protected Task> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = new List(); + if (ss.Length <= 1) + { + ret = await this.RawExecuteUpdatedAsync(); + ClearData(); + return ret; + } + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteUpdatedAsync()); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteUpdatedAsync()); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + #endregion - protected int RawExecuteAffrows() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(affrows); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return affrows; - } - async protected Task RawExecuteAffrowsAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(affrows); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return affrows; - } - protected abstract List RawExecuteUpdated(); - protected abstract Task> RawExecuteUpdatedAsync(); + protected int RawExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(affrows); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return affrows; + } + async protected Task RawExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(affrows); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return affrows; + } + protected abstract List RawExecuteUpdated(); + protected abstract Task> RawExecuteUpdatedAsync(); - public abstract int ExecuteAffrows(); - public abstract Task ExecuteAffrowsAsync(); - public abstract List ExecuteUpdated(); - public abstract Task> ExecuteUpdatedAsync(); + public abstract int ExecuteAffrows(); + public abstract Task ExecuteAffrowsAsync(); + public abstract List ExecuteUpdated(); + public abstract Task> ExecuteUpdatedAsync(); - public IUpdate IgnoreColumns(Expression> columns) { - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).Distinct(); - _ignore.Clear(); - foreach (var col in cols) _ignore.Add(col, true); - return this; - } - public IUpdate UpdateColumns(Expression> columns) { - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); - _ignore.Clear(); - foreach (var col in _table.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name) == false) - _ignore.Add(col.Attribute.Name, true); - return this; - } + public IUpdate IgnoreColumns(Expression> columns) + { + var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).Distinct(); + _ignore.Clear(); + foreach (var col in cols) _ignore.Add(col, true); + return this; + } + public IUpdate UpdateColumns(Expression> columns) + { + var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); + _ignore.Clear(); + foreach (var col in _table.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name) == false) + _ignore.Add(col.Attribute.Name, true); + return this; + } - public IUpdate IgnoreColumns(string[] columns) { - _ignore.Clear(); - foreach (var col in columns) _ignore.Add(col, true); - return this; - } - public IUpdate UpdateColumns(string[] columns) { - var cols = columns.ToDictionary(a => a); - _ignore.Clear(); - foreach (var col in _table.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name) == false) - _ignore.Add(col.Attribute.Name, true); - return this; - } + public IUpdate IgnoreColumns(string[] columns) + { + _ignore.Clear(); + foreach (var col in columns) _ignore.Add(col, true); + return this; + } + public IUpdate UpdateColumns(string[] columns) + { + var cols = columns.ToDictionary(a => a); + _ignore.Clear(); + foreach (var col in _table.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name) == false) + _ignore.Add(col.Attribute.Name, true); + return this; + } - public IUpdate SetSource(T1 source) => this.SetSource(new[] { source }); - public IUpdate SetSource(IEnumerable source) { - if (source == null || source.Any() == false) return this; - _source.AddRange(source.Where(a => a != null)); - return this; - } + public IUpdate SetSource(T1 source) => this.SetSource(new[] { source }); + public IUpdate SetSource(IEnumerable source) + { + if (source == null || source.Any() == false) return this; + _source.AddRange(source.Where(a => a != null)); + return this; + } - public IUpdate Set(Expression> column, TMember value) { - var cols = new List(); - _commonExpression.ExpressionSelectColumn_MemberAccess(null, cols, SelectTableInfoType.From, column?.Body, true, null); - if (cols.Count != 1) return this; - var col = cols.First(); - object paramVal = null; - if (col.Column.Attribute.MapType == typeof(TMember)) paramVal = value; - else paramVal = Utils.GetDataReaderValue(col.Column.Attribute.MapType, value); - _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Column.Attribute.Name)).Append(" = "); - if (_noneParameter) { - _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, col.Column.Attribute.MapType, paramVal)); - } else { - _set.Append(_commonUtils.QuoteWriteParamter(col.Column.Attribute.MapType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}")); - _commonUtils.AppendParamter(_params, null, col.Column.Attribute.MapType, paramVal); - } - //foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value); - return this; - } - public IUpdate Set(Expression> exp) { - var body = exp?.Body; - var nodeType = body?.NodeType; - if (nodeType == ExpressionType.Equal) { - _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp, null)); - return this; - } - - if (nodeType == ExpressionType.MemberInit) { - var initExp = body as MemberInitExpression; - if (initExp.Bindings?.Count > 0) { - for (var a = 0; a < initExp.Bindings.Count; a++) { - var initAssignExp = (initExp.Bindings[a] as MemberAssignment); - if (initAssignExp == null) continue; - var memberName = initExp.Bindings[a].Member.Name; - if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; - if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); - var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { }); - _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); - } - } - return this; - } - if (body is BinaryExpression == false && - nodeType != ExpressionType.Call) return this; - var cols = new List(); - var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, exp, null); - if (cols.Any() == false) return this; - foreach (var col in cols) { - if (col.Column.Attribute.IsNullable == true && col.Column.Attribute.MapType.IsNullableType()) { - var replval = _orm.CodeFirst.GetDbInfo(col.Column.Attribute.MapType.GenericTypeArguments.FirstOrDefault())?.defaultValue; - if (replval == null) continue; - var replname = _commonUtils.QuoteSqlName(col.Column.Attribute.Name); - expt = expt.Replace(replname, _commonUtils.IsNull(replname, _commonUtils.FormatSql("{0}", replval))); - } - } - _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(cols.First().Column.Attribute.Name)).Append(" = ").Append(expt); - return this; - } - public IUpdate SetRaw(string sql, object parms = null) { - if (string.IsNullOrEmpty(sql)) return this; - _set.Append(", ").Append(sql); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this; - } + public IUpdate Set(Expression> column, TMember value) + { + var cols = new List(); + _commonExpression.ExpressionSelectColumn_MemberAccess(null, cols, SelectTableInfoType.From, column?.Body, true, null); + if (cols.Count != 1) return this; + var col = cols.First(); + object paramVal = null; + if (col.Column.Attribute.MapType == typeof(TMember)) paramVal = value; + else paramVal = Utils.GetDataReaderValue(col.Column.Attribute.MapType, value); + _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Column.Attribute.Name)).Append(" = "); + if (_noneParameter) + { + _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, col.Column.Attribute.MapType, paramVal)); + } + else + { + _set.Append(_commonUtils.QuoteWriteParamter(col.Column.Attribute.MapType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}")); + _commonUtils.AppendParamter(_params, null, col.Column.Attribute.MapType, paramVal); + } + //foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value); + return this; + } + public IUpdate Set(Expression> exp) + { + var body = exp?.Body; + var nodeType = body?.NodeType; + if (nodeType == ExpressionType.Equal) + { + _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp, null)); + return this; + } - public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null)); - public IUpdate Where(string sql, object parms = null) { - if (string.IsNullOrEmpty(sql)) return this; - var args = new Aop.WhereEventArgs(sql, parms); - _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); - if (args.IsCancel == true) return this; + if (nodeType == ExpressionType.MemberInit) + { + var initExp = body as MemberInitExpression; + if (initExp.Bindings?.Count > 0) + { + for (var a = 0; a < initExp.Bindings.Count; a++) + { + var initAssignExp = (initExp.Bindings[a] as MemberAssignment); + if (initAssignExp == null) continue; + var memberName = initExp.Bindings[a].Member.Name; + if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; + if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); + var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { }); + _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); + } + } + return this; + } + if (body is BinaryExpression == false && + nodeType != ExpressionType.Call) return this; + var cols = new List(); + var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, exp, null); + if (cols.Any() == false) return this; + foreach (var col in cols) + { + if (col.Column.Attribute.IsNullable == true && col.Column.Attribute.MapType.IsNullableType()) + { + var replval = _orm.CodeFirst.GetDbInfo(col.Column.Attribute.MapType.GenericTypeArguments.FirstOrDefault())?.defaultValue; + if (replval == null) continue; + var replname = _commonUtils.QuoteSqlName(col.Column.Attribute.Name); + expt = expt.Replace(replname, _commonUtils.IsNull(replname, _commonUtils.FormatSql("{0}", replval))); + } + } + _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(cols.First().Column.Attribute.Name)).Append(" = ").Append(expt); + return this; + } + public IUpdate SetRaw(string sql, object parms = null) + { + if (string.IsNullOrEmpty(sql)) return this; + _set.Append(", ").Append(sql); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this; + } - _where.Append(" AND (").Append(sql).Append(")"); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this; - } - public IUpdate Where(T1 item) => this.Where(new[] { item }); - public IUpdate Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); - public IUpdate WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); - public IUpdate WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null)); + public IUpdate Where(string sql, object parms = null) + { + if (string.IsNullOrEmpty(sql)) return this; + var args = new Aop.WhereEventArgs(sql, parms); + _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); + if (args.IsCancel == true) return this; - protected string WhereCaseSource(string CsName, Func thenValue) { - if (_source.Any() == false) return null; - if (_table.ColumnsByCs.ContainsKey(CsName) == false) throw new Exception($"找不到 {CsName} 对应的列"); - if (thenValue == null) throw new ArgumentNullException("thenValue 参数不可为 null"); + _where.Append(" AND (").Append(sql).Append(")"); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this; + } + public IUpdate Where(T1 item) => this.Where(new[] { item }); + public IUpdate Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); + public IUpdate WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); + public IUpdate WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); - if (_source.Count == 0) return null; - if (_source.Count == 1) { + protected string WhereCaseSource(string CsName, Func thenValue) + { + if (_source.Any() == false) return null; + if (_table.ColumnsByCs.ContainsKey(CsName) == false) throw new Exception($"找不到 {CsName} 对应的列"); + if (thenValue == null) throw new ArgumentNullException("thenValue 参数不可为 null"); - var col = _table.ColumnsByCs[CsName]; - var sb = new StringBuilder(); + if (_source.Count == 0) return null; + if (_source.Count == 1) + { - sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, col.GetMapValue(_source.First())))); + var col = _table.ColumnsByCs[CsName]; + var sb = new StringBuilder(); - return sb.ToString(); + sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); + sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, col.GetMapValue(_source.First())))); - } else { - var caseWhen = new StringBuilder(); - caseWhen.Append("CASE "); - ToSqlCase(caseWhen, _table.Primarys); - var cw = caseWhen.ToString(); + return sb.ToString(); - var col = _table.ColumnsByCs[CsName]; - var sb = new StringBuilder(); - sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); + } + else + { + var caseWhen = new StringBuilder(); + caseWhen.Append("CASE "); + ToSqlCase(caseWhen, _table.Primarys); + var cw = caseWhen.ToString(); - var isnull = false; - var cwsb = new StringBuilder().Append(cw); - foreach (var d in _source) { - cwsb.Append(" \r\nWHEN "); - ToSqlWhen(cwsb, _table.Primarys, d); - cwsb.Append(" THEN "); - var value = col.GetMapValue(d); - cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value))); - if (isnull == false) isnull = value == null || value == DBNull.Value; - } - cwsb.Append(" END"); - if (isnull == false) sb.Append(cwsb.ToString()); - else sb.Append("NULL"); - cwsb.Clear(); + var col = _table.ColumnsByCs[CsName]; + var sb = new StringBuilder(); + sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - return sb.ToString(); - } - } + var isnull = false; + var cwsb = new StringBuilder().Append(cw); + foreach (var d in _source) + { + cwsb.Append(" \r\nWHEN "); + ToSqlWhen(cwsb, _table.Primarys, d); + cwsb.Append(" THEN "); + var value = col.GetMapValue(d); + cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value))); + if (isnull == false) isnull = value == null || value == DBNull.Value; + } + cwsb.Append(" END"); + if (isnull == false) sb.Append(cwsb.ToString()); + else sb.Append("NULL"); + cwsb.Clear(); - protected abstract void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys); - protected abstract void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d); + return sb.ToString(); + } + } - public IUpdate AsTable(Func tableRule) { - _tableRule = tableRule; - return this; - } - public IUpdate AsType(Type entityType) { - if (entityType == typeof(object)) throw new Exception("IUpdate.AsType 参数不支持指定为 object"); - if (entityType == _table.Type) return this; - var newtb = _commonUtils.GetTableByEntity(entityType); - _table = newtb ?? throw new Exception("IUpdate.AsType 参数错误,请传入正确的实体类型"); - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); - return this; - } + protected abstract void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys); + protected abstract void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d); - public string ToSql() { - if (_where.Length == 0 && _source.Any() == false) return null; + public IUpdate AsTable(Func tableRule) + { + _tableRule = tableRule; + return this; + } + public IUpdate AsType(Type entityType) + { + if (entityType == typeof(object)) throw new Exception("IUpdate.AsType 参数不支持指定为 object"); + if (entityType == _table.Type) return this; + var newtb = _commonUtils.GetTableByEntity(entityType); + _table = newtb ?? throw new Exception("IUpdate.AsType 参数错误,请传入正确的实体类型"); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); + return this; + } - var sb = new StringBuilder(); - sb.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append(" SET "); + public string ToSql() + { + if (_where.Length == 0 && _source.Any() == false) return null; - if (_set.Length > 0) { //指定 set 更新 - sb.Append(_set.ToString().Substring(2)); + var sb = new StringBuilder(); + sb.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append(" SET "); - } else if (_source.Count == 1) { //保存 Source - _paramsSource.Clear(); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - var value = col.GetMapValue(_source.First()); - if (_noneParameter) { - sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value)); - } else { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); - _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, value); - } - ++colidx; - } - } - if (colidx == 0) return null; + if (_set.Length > 0) + { //指定 set 更新 + sb.Append(_set.ToString().Substring(2)); - } else if (_source.Count > 1) { //批量保存 Source - if (_table.Primarys.Any() == false) return null; + } + else if (_source.Count == 1) + { //保存 Source + _paramsSource.Clear(); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); + var value = col.GetMapValue(_source.First()); + if (_noneParameter) + { + sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value)); + } + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); + _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, value); + } + ++colidx; + } + } + if (colidx == 0) return null; - var caseWhen = new StringBuilder(); - caseWhen.Append("CASE "); - ToSqlCase(caseWhen, _table.Primarys); - var cw = caseWhen.ToString(); + } + else if (_source.Count > 1) + { //批量保存 Source + if (_table.Primarys.Any() == false) return null; - _paramsSource.Clear(); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); + var caseWhen = new StringBuilder(); + caseWhen.Append("CASE "); + ToSqlCase(caseWhen, _table.Primarys); + var cw = caseWhen.ToString(); - var isnull = false; - var cwsb = new StringBuilder().Append(cw); - foreach (var d in _source) { - cwsb.Append(" \r\nWHEN "); - ToSqlWhen(cwsb, _table.Primarys, d); - cwsb.Append(" THEN "); - var value = col.GetMapValue(d); - if (_noneParameter) { - cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value)); - } else { - cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); - _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, value); - } - if (isnull == false) isnull = value == null || value == DBNull.Value; - } - cwsb.Append(" END"); - if (isnull == false) sb.Append(cwsb.ToString()); - else sb.Append("NULL"); - cwsb.Clear(); + _paramsSource.Clear(); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - ++colidx; - } - } - if (colidx == 0) return null; - } else if (_setIncr.Length == 0) - return null; + var isnull = false; + var cwsb = new StringBuilder().Append(cw); + foreach (var d in _source) + { + cwsb.Append(" \r\nWHEN "); + ToSqlWhen(cwsb, _table.Primarys, d); + cwsb.Append(" THEN "); + var value = col.GetMapValue(d); + if (_noneParameter) + { + cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value)); + } + else + { + cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); + _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, value); + } + if (isnull == false) isnull = value == null || value == DBNull.Value; + } + cwsb.Append(" END"); + if (isnull == false) sb.Append(cwsb.ToString()); + else sb.Append("NULL"); + cwsb.Clear(); - if (_setIncr.Length > 0) - sb.Append(_set.Length > 0 ? _setIncr.ToString() : _setIncr.ToString().Substring(2)); + ++colidx; + } + } + if (colidx == 0) return null; + } + else if (_setIncr.Length == 0) + return null; - if (_table.VersionColumn != null) { - var vcname = _commonUtils.QuoteSqlName(_table.VersionColumn.Attribute.Name); - sb.Append(", ").Append(vcname).Append(" = ").Append(vcname).Append(" + 1"); - } + if (_setIncr.Length > 0) + sb.Append(_set.Length > 0 ? _setIncr.ToString() : _setIncr.ToString().Substring(2)); - sb.Append(" \r\nWHERE "); - if (_source.Any()) - sb.Append("(").Append(_commonUtils.WhereItems(_table, "", _source)).Append(")"); + if (_table.VersionColumn != null) + { + var vcname = _commonUtils.QuoteSqlName(_table.VersionColumn.Attribute.Name); + sb.Append(", ").Append(vcname).Append(" = ").Append(vcname).Append(" + 1"); + } - if (_where.Length > 0) - sb.Append(_source.Any() ? _where.ToString() : _where.ToString().Substring(5)); + sb.Append(" \r\nWHERE "); + if (_source.Any()) + sb.Append("(").Append(_commonUtils.WhereItems(_table, "", _source)).Append(")"); - if (_table.VersionColumn != null) { - var versionCondi = WhereCaseSource(_table.VersionColumn.CsName, sqlval => sqlval); - if (string.IsNullOrEmpty(versionCondi) == false) - sb.Append(" AND ").Append(versionCondi); - } + if (_where.Length > 0) + sb.Append(_source.Any() ? _where.ToString() : _where.ToString().Substring(5)); - return sb.ToString(); - } - } + if (_table.VersionColumn != null) + { + var versionCondi = WhereCaseSource(_table.VersionColumn.CsName, sqlval => sqlval); + if (string.IsNullOrEmpty(versionCondi) == false) + sb.Append(" AND ").Append(versionCondi); + } + + return sb.ToString(); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index c16f0104..132ce338 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -17,293 +17,339 @@ using System.Threading.Tasks; using System.Xml; using System.Xml.XPath; -namespace FreeSql.Internal { - public abstract class CommonUtils { +namespace FreeSql.Internal +{ + public abstract class CommonUtils + { - public abstract string GetNoneParamaterSqlValue(List specialParams, Type type, object value); - public abstract DbParameter AppendParamter(List _params, string parameterName, Type type, object value); - public abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); - public abstract string FormatSql(string sql, params object[] args); - public abstract string QuoteSqlName(string name); - public abstract string TrimQuoteSqlName(string name); - public abstract string QuoteParamterName(string name); - public abstract string IsNull(string sql, object value); - public abstract string StringConcat(string[] objs, Type[] types); - public abstract string Mod(string left, string right, Type leftType, Type rightType); - public abstract string QuoteWriteParamter(Type type, string paramterName); - public abstract string QuoteReadColumn(Type type, string columnName); + public abstract string GetNoneParamaterSqlValue(List specialParams, Type type, object value); + public abstract DbParameter AppendParamter(List _params, string parameterName, Type type, object value); + public abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); + public abstract string FormatSql(string sql, params object[] args); + public abstract string QuoteSqlName(string name); + public abstract string TrimQuoteSqlName(string name); + public abstract string QuoteParamterName(string name); + public abstract string IsNull(string sql, object value); + public abstract string StringConcat(string[] objs, Type[] types); + public abstract string Mod(string left, string right, Type leftType, Type rightType); + public abstract string QuoteWriteParamter(Type type, string paramterName); + public abstract string QuoteReadColumn(Type type, string columnName); - public IFreeSql _orm { get; set; } - public ICodeFirst CodeFirst => _orm.CodeFirst; - public TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this); - public List dbTables { get; set; } - public object dbTablesLock = new object(); + public IFreeSql _orm { get; set; } + public ICodeFirst CodeFirst => _orm.CodeFirst; + public TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this); + public List dbTables { get; set; } + public object dbTablesLock = new object(); - public CommonUtils(IFreeSql orm) { - _orm = orm; - } + public CommonUtils(IFreeSql orm) + { + _orm = orm; + } - ConcurrentDictionary dicConfigEntity = new ConcurrentDictionary(); - public ICodeFirst ConfigEntity(Action> entity) { - if (entity == null) return _orm.CodeFirst; - var type = typeof(T); - var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); - var fluent = new TableFluent(table); - entity.Invoke(fluent); - Utils.RemoveTableByEntity(type, this); //remove cache - return _orm.CodeFirst; - } - public ICodeFirst ConfigEntity(Type type, Action entity) { - if (entity == null) return _orm.CodeFirst; - var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); - var fluent = new TableFluent(type, table); - entity.Invoke(fluent); - Utils.RemoveTableByEntity(type, this); //remove cache - return _orm.CodeFirst; - } - public TableAttribute GetConfigEntity(Type type) { - return dicConfigEntity.TryGetValue(type, out var trytb) ? trytb : null; - } - public TableAttribute GetEntityTableAttribute(Type type) { - TableAttribute attr = null; - if (_orm.Aop.ConfigEntity != null) { - var aope = new Aop.ConfigEntityEventArgs(type); - _orm.Aop.ConfigEntity(_orm, aope); - attr = aope.ModifyResult; - } - if (attr == null) attr = new TableAttribute(); - if (dicConfigEntity.TryGetValue(type, out var trytb)) { - if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name; - if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; - if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter; - if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; + ConcurrentDictionary dicConfigEntity = new ConcurrentDictionary(); + public ICodeFirst ConfigEntity(Action> entity) + { + if (entity == null) return _orm.CodeFirst; + var type = typeof(T); + var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); + var fluent = new TableFluent(table); + entity.Invoke(fluent); + Utils.RemoveTableByEntity(type, this); //remove cache + return _orm.CodeFirst; + } + public ICodeFirst ConfigEntity(Type type, Action entity) + { + if (entity == null) return _orm.CodeFirst; + var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); + var fluent = new TableFluent(type, table); + entity.Invoke(fluent); + Utils.RemoveTableByEntity(type, this); //remove cache + return _orm.CodeFirst; + } + public TableAttribute GetConfigEntity(Type type) + { + return dicConfigEntity.TryGetValue(type, out var trytb) ? trytb : null; + } + public TableAttribute GetEntityTableAttribute(Type type) + { + TableAttribute attr = null; + if (_orm.Aop.ConfigEntity != null) + { + var aope = new Aop.ConfigEntityEventArgs(type); + _orm.Aop.ConfigEntity(_orm, aope); + attr = aope.ModifyResult; + } + if (attr == null) attr = new TableAttribute(); + if (dicConfigEntity.TryGetValue(type, out var trytb)) + { + if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name; + if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; + if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter; + if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; - } - var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); - foreach (var tryattrobj in attrs) { - var tryattr = tryattrobj as TableAttribute; - if (tryattr == null) continue; - if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; - if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; - if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter; - if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure; - } - if (!string.IsNullOrEmpty(attr.Name)) return attr; - if (!string.IsNullOrEmpty(attr.OldName)) return attr; - if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr; - if (attr._DisableSyncStructure != null) return attr; - return null; - } - public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) { - ColumnAttribute attr = null; - if (_orm.Aop.ConfigEntityProperty != null) { - var aope = new Aop.ConfigEntityPropertyEventArgs(type, proto); - _orm.Aop.ConfigEntityProperty(_orm, aope); - attr = aope.ModifyResult; - } - if (attr == null) attr = new ColumnAttribute(); - if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._columns.TryGetValue(proto.Name, out var trycol)) { - if (!string.IsNullOrEmpty(trycol.Name)) attr.Name = trycol.Name; - if (!string.IsNullOrEmpty(trycol.OldName)) attr.OldName = trycol.OldName; - if (!string.IsNullOrEmpty(trycol.DbType)) attr.DbType = trycol.DbType; - if (trycol._IsPrimary != null) attr._IsPrimary = trycol.IsPrimary; - if (trycol._IsIdentity != null) attr._IsIdentity = trycol.IsIdentity; - if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable; - if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore; - if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion; - if (trycol._Uniques != null) attr._Uniques = trycol._Uniques; - if (trycol.MapType != null) attr.MapType = trycol.MapType; - if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue; - } - var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); - foreach (var tryattrobj in attrs) { - var tryattr = tryattrobj as ColumnAttribute; - if (tryattr == null) continue; - if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; - if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; - if (!string.IsNullOrEmpty(tryattr.DbType)) attr.DbType = tryattr.DbType; - if (tryattr._IsPrimary != null) attr._IsPrimary = tryattr.IsPrimary; - if (tryattr._IsIdentity != null) attr._IsIdentity = tryattr.IsIdentity; - if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable; - if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore; - if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion; - if (tryattr._Uniques != null) attr._Uniques = tryattr._Uniques; - if (tryattr.MapType != null) attr.MapType = tryattr.MapType; - if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue; - } - ColumnAttribute ret = null; - if (!string.IsNullOrEmpty(attr.Name)) ret = attr; - if (!string.IsNullOrEmpty(attr.OldName)) ret = attr; - if (!string.IsNullOrEmpty(attr.DbType)) ret = attr; - if (attr._IsPrimary != null) ret = attr; - if (attr._IsIdentity != null) ret = attr; - if (attr._IsNullable != null) ret = attr; - if (attr._IsIgnore != null) ret = attr; - if (attr._IsVersion != null) ret = attr; - if (attr._Uniques != null) ret = attr; - if (attr.MapType != null) ret = attr; - if (attr.DbDefautValue != null) ret = attr; - if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; - return ret; - } + } + var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); + foreach (var tryattrobj in attrs) + { + var tryattr = tryattrobj as TableAttribute; + if (tryattr == null) continue; + if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; + if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; + if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter; + if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure; + } + if (!string.IsNullOrEmpty(attr.Name)) return attr; + if (!string.IsNullOrEmpty(attr.OldName)) return attr; + if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr; + if (attr._DisableSyncStructure != null) return attr; + return null; + } + public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) + { + ColumnAttribute attr = null; + if (_orm.Aop.ConfigEntityProperty != null) + { + var aope = new Aop.ConfigEntityPropertyEventArgs(type, proto); + _orm.Aop.ConfigEntityProperty(_orm, aope); + attr = aope.ModifyResult; + } + if (attr == null) attr = new ColumnAttribute(); + if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._columns.TryGetValue(proto.Name, out var trycol)) + { + if (!string.IsNullOrEmpty(trycol.Name)) attr.Name = trycol.Name; + if (!string.IsNullOrEmpty(trycol.OldName)) attr.OldName = trycol.OldName; + if (!string.IsNullOrEmpty(trycol.DbType)) attr.DbType = trycol.DbType; + if (trycol._IsPrimary != null) attr._IsPrimary = trycol.IsPrimary; + if (trycol._IsIdentity != null) attr._IsIdentity = trycol.IsIdentity; + if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable; + if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore; + if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion; + if (trycol._Uniques != null) attr._Uniques = trycol._Uniques; + if (trycol.MapType != null) attr.MapType = trycol.MapType; + if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue; + } + var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); + foreach (var tryattrobj in attrs) + { + var tryattr = tryattrobj as ColumnAttribute; + if (tryattr == null) continue; + if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; + if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; + if (!string.IsNullOrEmpty(tryattr.DbType)) attr.DbType = tryattr.DbType; + if (tryattr._IsPrimary != null) attr._IsPrimary = tryattr.IsPrimary; + if (tryattr._IsIdentity != null) attr._IsIdentity = tryattr.IsIdentity; + if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable; + if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore; + if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion; + if (tryattr._Uniques != null) attr._Uniques = tryattr._Uniques; + if (tryattr.MapType != null) attr.MapType = tryattr.MapType; + if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue; + } + ColumnAttribute ret = null; + if (!string.IsNullOrEmpty(attr.Name)) ret = attr; + if (!string.IsNullOrEmpty(attr.OldName)) ret = attr; + if (!string.IsNullOrEmpty(attr.DbType)) ret = attr; + if (attr._IsPrimary != null) ret = attr; + if (attr._IsIdentity != null) ret = attr; + if (attr._IsNullable != null) ret = attr; + if (attr._IsIgnore != null) ret = attr; + if (attr._IsVersion != null) ret = attr; + if (attr._Uniques != null) ret = attr; + if (attr.MapType != null) ret = attr; + if (attr.DbDefautValue != null) ret = attr; + if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; + return ret; + } - public string WhereObject(TableInfo table, string aliasAndDot, object dywhere) { - if (dywhere == null) return ""; - var type = dywhere.GetType(); - var primarys = table.Primarys; - var pk1 = primarys.FirstOrDefault(); - if (primarys.Length == 1 && (type == pk1.CsType || type.IsNumberType() && pk1.CsType.IsNumberType())) { - return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}"; - } else if (primarys.Length > 0 && (type == table.Type || type.BaseType == table.Type)) { - var sb = new StringBuilder(); - var pkidx = 0; - foreach (var pk in primarys) { - if (pkidx > 0) sb.Append(" AND "); - sb.Append(aliasAndDot).Append(this.QuoteSqlName(pk.Attribute.Name)); - sb.Append(this.FormatSql(" = {0}", pk.GetMapValue(dywhere))); - ++pkidx; - } - return sb.ToString(); - } else if (dywhere is IEnumerable) { - var sb = new StringBuilder(); - var ie = dywhere as IEnumerable; - var ieidx = 0; - foreach (var i in ie) { - var fw = WhereObject(table, aliasAndDot, i); - if (string.IsNullOrEmpty(fw)) continue; - if (ieidx > 0) sb.Append(" OR "); - sb.Append(fw); - ++ieidx; - } - return sb.ToString(); - } else { - var sb = new StringBuilder(); - var ps = type.GetProperties(); - var psidx = 0; - foreach (var p in ps) { - if (table.Columns.TryGetValue(p.Name, out var trycol) == false) continue; - if (psidx > 0) sb.Append(" AND "); - sb.Append(aliasAndDot).Append(this.QuoteSqlName(trycol.Attribute.Name)); - sb.Append(this.FormatSql(" = {0}", Utils.GetDataReaderValue(trycol.Attribute.MapType, p.GetValue(dywhere)))); - ++psidx; - } - if (psidx == 0) return ""; - return sb.ToString(); - } - } + public string WhereObject(TableInfo table, string aliasAndDot, object dywhere) + { + if (dywhere == null) return ""; + var type = dywhere.GetType(); + var primarys = table.Primarys; + var pk1 = primarys.FirstOrDefault(); + if (primarys.Length == 1 && (type == pk1.CsType || type.IsNumberType() && pk1.CsType.IsNumberType())) + { + return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}"; + } + else if (primarys.Length > 0 && (type == table.Type || type.BaseType == table.Type)) + { + var sb = new StringBuilder(); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) sb.Append(" AND "); + sb.Append(aliasAndDot).Append(this.QuoteSqlName(pk.Attribute.Name)); + sb.Append(this.FormatSql(" = {0}", pk.GetMapValue(dywhere))); + ++pkidx; + } + return sb.ToString(); + } + else if (dywhere is IEnumerable) + { + var sb = new StringBuilder(); + var ie = dywhere as IEnumerable; + var ieidx = 0; + foreach (var i in ie) + { + var fw = WhereObject(table, aliasAndDot, i); + if (string.IsNullOrEmpty(fw)) continue; + if (ieidx > 0) sb.Append(" OR "); + sb.Append(fw); + ++ieidx; + } + return sb.ToString(); + } + else + { + var sb = new StringBuilder(); + var ps = type.GetProperties(); + var psidx = 0; + foreach (var p in ps) + { + if (table.Columns.TryGetValue(p.Name, out var trycol) == false) continue; + if (psidx > 0) sb.Append(" AND "); + sb.Append(aliasAndDot).Append(this.QuoteSqlName(trycol.Attribute.Name)); + sb.Append(this.FormatSql(" = {0}", Utils.GetDataReaderValue(trycol.Attribute.MapType, p.GetValue(dywhere)))); + ++psidx; + } + if (psidx == 0) return ""; + return sb.ToString(); + } + } - public string WhereItems(TableInfo table, string aliasAndDot, IEnumerable items) { - if (items == null || items.Any() == false) return null; - if (table.Primarys.Any() == false) return null; - var its = items.Where(a => a != null).ToArray(); + public string WhereItems(TableInfo table, string aliasAndDot, IEnumerable items) + { + if (items == null || items.Any() == false) return null; + if (table.Primarys.Any() == false) return null; + var its = items.Where(a => a != null).ToArray(); - var pk1 = table.Primarys.FirstOrDefault(); - if (table.Primarys.Length == 1) { - var sbin = new StringBuilder(); - sbin.Append(aliasAndDot).Append(this.QuoteSqlName(pk1.Attribute.Name)); - var indt = its.Select(a => pk1.GetMapValue(a)).Where(a => a != null).ToArray(); - if (indt.Any() == false) return null; - if (indt.Length == 1) sbin.Append(" = ").Append(this.FormatSql("{0}", indt.First())); - else sbin.Append(" IN (").Append(string.Join(",", indt.Select(a => this.FormatSql("{0}", a)))).Append(")"); - return sbin.ToString(); - } - var dicpk = its.Length > 5 ? new Dictionary() : null; - var sb = its.Length > 5 ? null : new StringBuilder(); - var iidx = 0; - foreach (var item in its) { - var filter = ""; - foreach (var pk in table.Primarys) - filter += $" AND {aliasAndDot}{this.QuoteSqlName(pk.Attribute.Name)} = {this.FormatSql("{0}", pk.GetMapValue(item))}"; - if (string.IsNullOrEmpty(filter)) continue; - if (sb != null) { - sb.Append(" OR ("); - sb.Append(filter.Substring(5)); - sb.Append(")"); - ++iidx; - } - if (dicpk != null) { - filter = filter.Substring(5); - if (dicpk.ContainsKey(filter) == false) { - dicpk.Add(filter, true); - ++iidx; - } - } - //++iidx; - } - if (iidx == 0) return null; - if (sb == null) { - sb = new StringBuilder(); - foreach (var fil in dicpk) { - sb.Append(" OR ("); - sb.Append(fil.Key); - sb.Append(")"); - } - } - return iidx == 1 ? sb.Remove(0, 5).Remove(sb.Length - 1, 1).ToString() : sb.Remove(0, 4).ToString(); - } + var pk1 = table.Primarys.FirstOrDefault(); + if (table.Primarys.Length == 1) + { + var sbin = new StringBuilder(); + sbin.Append(aliasAndDot).Append(this.QuoteSqlName(pk1.Attribute.Name)); + var indt = its.Select(a => pk1.GetMapValue(a)).Where(a => a != null).ToArray(); + if (indt.Any() == false) return null; + if (indt.Length == 1) sbin.Append(" = ").Append(this.FormatSql("{0}", indt.First())); + else sbin.Append(" IN (").Append(string.Join(",", indt.Select(a => this.FormatSql("{0}", a)))).Append(")"); + return sbin.ToString(); + } + var dicpk = its.Length > 5 ? new Dictionary() : null; + var sb = its.Length > 5 ? null : new StringBuilder(); + var iidx = 0; + foreach (var item in its) + { + var filter = ""; + foreach (var pk in table.Primarys) + filter += $" AND {aliasAndDot}{this.QuoteSqlName(pk.Attribute.Name)} = {this.FormatSql("{0}", pk.GetMapValue(item))}"; + if (string.IsNullOrEmpty(filter)) continue; + if (sb != null) + { + sb.Append(" OR ("); + sb.Append(filter.Substring(5)); + sb.Append(")"); + ++iidx; + } + if (dicpk != null) + { + filter = filter.Substring(5); + if (dicpk.ContainsKey(filter) == false) + { + dicpk.Add(filter, true); + ++iidx; + } + } + //++iidx; + } + if (iidx == 0) return null; + if (sb == null) + { + sb = new StringBuilder(); + foreach (var fil in dicpk) + { + sb.Append(" OR ("); + sb.Append(fil.Key); + sb.Append(")"); + } + } + return iidx == 1 ? sb.Remove(0, 5).Remove(sb.Length - 1, 1).ToString() : sb.Remove(0, 4).ToString(); + } - /// - /// 通过属性的注释文本,通过 xml 读取 - /// - /// - /// Dict:key=属性名,value=注释 - public static Dictionary GetProperyCommentBySummary(Type type) { - var xmlPath = type.Assembly.Location.Replace(".dll", ".xml"); - if (File.Exists(xmlPath) == false) return null; + /// + /// 通过属性的注释文本,通过 xml 读取 + /// + /// + /// Dict:key=属性名,value=注释 + public static Dictionary GetProperyCommentBySummary(Type type) + { + var xmlPath = type.Assembly.Location.Replace(".dll", ".xml"); + if (File.Exists(xmlPath) == false) return null; - var dic = new Dictionary(); - var className = type.IsNested ? $"{type.Namespace}.{type.DeclaringType.Name}.{type.Name}" : $"{type.Namespace}.{type.Name}"; - var sReader = new StringReader(File.ReadAllText(xmlPath)); - using (var xmlReader = XmlReader.Create(sReader)) { - var xpath = new XPathDocument(xmlReader); - var xmlNav = xpath.CreateNavigator(); + var dic = new Dictionary(); + var className = type.IsNested ? $"{type.Namespace}.{type.DeclaringType.Name}.{type.Name}" : $"{type.Namespace}.{type.Name}"; + var sReader = new StringReader(File.ReadAllText(xmlPath)); + using (var xmlReader = XmlReader.Create(sReader)) + { + var xpath = new XPathDocument(xmlReader); + var xmlNav = xpath.CreateNavigator(); - var props = type.GetProperties(); - foreach (var prop in props) { - var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); - if (node == null) continue; - var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); - if (string.IsNullOrEmpty(comment)) continue; + var props = type.GetProperties(); + foreach (var prop in props) + { + var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); + if (node == null) continue; + var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); + if (string.IsNullOrEmpty(comment)) continue; - dic.Add(prop.Name, comment); - } - } + dic.Add(prop.Name, comment); + } + } - return dic; - } + return dic; + } - public static void PrevReheatConnectionPool(ObjectPool pool, int minPoolSize) { - if (minPoolSize <= 0) minPoolSize = Math.Min(5, pool.Policy.PoolSize); - if (minPoolSize > pool.Policy.PoolSize) minPoolSize = pool.Policy.PoolSize; - var initTestOk = true; - var initStartTime = DateTime.Now; - var initConns = new ConcurrentBag>(); + public static void PrevReheatConnectionPool(ObjectPool pool, int minPoolSize) + { + if (minPoolSize <= 0) minPoolSize = Math.Min(5, pool.Policy.PoolSize); + if (minPoolSize > pool.Policy.PoolSize) minPoolSize = pool.Policy.PoolSize; + var initTestOk = true; + var initStartTime = DateTime.Now; + var initConns = new ConcurrentBag>(); - try { - var conn = pool.Get(); - initConns.Add(conn); - pool.Policy.OnCheckAvailable(conn); - } catch { - initTestOk = false; //预热一次失败,后面将不进行 - } - for (var a = 1; initTestOk && a < minPoolSize; a += 10) { - if (initStartTime.Subtract(DateTime.Now).TotalSeconds > 3) break; //预热耗时超过3秒,退出 - var b = Math.Min(minPoolSize - a, 10); //每10个预热 - var initTasks = new Task[b]; - for (var c = 0; c < b; c++) { - initTasks[c] = Task.Run(() => { - try { - var conn = pool.Get(); - initConns.Add(conn); - pool.Policy.OnCheckAvailable(conn); - } catch { - initTestOk = false; //有失败,下一组退出预热 - } - }); - } - Task.WaitAll(initTasks); - } - while (initConns.TryTake(out var conn)) pool.Return(conn); - } - } + try + { + var conn = pool.Get(); + initConns.Add(conn); + pool.Policy.OnCheckAvailable(conn); + } + catch + { + initTestOk = false; //预热一次失败,后面将不进行 + } + for (var a = 1; initTestOk && a < minPoolSize; a += 10) + { + if (initStartTime.Subtract(DateTime.Now).TotalSeconds > 3) break; //预热耗时超过3秒,退出 + var b = Math.Min(minPoolSize - a, 10); //每10个预热 + var initTasks = new Task[b]; + for (var c = 0; c < b; c++) + { + initTasks[c] = Task.Run(() => + { + try + { + var conn = pool.Get(); + initConns.Add(conn); + pool.Policy.OnCheckAvailable(conn); + } + catch + { + initTestOk = false; //有失败,下一组退出预热 + } + }); + } + Task.WaitAll(initTasks); + } + while (initConns.TryTake(out var conn)) pool.Return(conn); + } + } } diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index fe17b231..8ff71303 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -4,71 +4,77 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq.Expressions; -namespace FreeSql.Internal.Model { - public class ColumnInfo { - public TableInfo Table { get; set; } - public string CsName { get; set; } - public Type CsType { get; set; } - public ColumnAttribute Attribute { get; set; } - public string Comment { get; internal set; } +namespace FreeSql.Internal.Model +{ + public class ColumnInfo + { + public TableInfo Table { get; set; } + public string CsName { get; set; } + public Type CsType { get; set; } + public ColumnAttribute Attribute { get; set; } + public string Comment { get; internal set; } - static ConcurrentDictionary> _dicGetMapValue = new ConcurrentDictionary>(); - public object GetMapValue(object obj) { - var func = _dicGetMapValue.GetOrAdd(this, col => { - var paramExp = Expression.Parameter(typeof(object)); - var returnTarget = Expression.Label(typeof(object)); + static ConcurrentDictionary> _dicGetMapValue = new ConcurrentDictionary>(); + public object GetMapValue(object obj) + { + var func = _dicGetMapValue.GetOrAdd(this, col => + { + var paramExp = Expression.Parameter(typeof(object)); + var returnTarget = Expression.Label(typeof(object)); - if (Attribute.MapType == CsType) - return Expression.Lambda>( - Expression.Block( - Expression.Return(returnTarget, Expression.Convert( - Expression.MakeMemberAccess( - Expression.TypeAs(paramExp, col.Table.Type), - Table.Properties[col.CsName] - ), typeof(object))), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - ), new[] { paramExp }).Compile(); + if (Attribute.MapType == CsType) + return Expression.Lambda>( + Expression.Block( + Expression.Return(returnTarget, Expression.Convert( + Expression.MakeMemberAccess( + Expression.TypeAs(paramExp, col.Table.Type), + Table.Properties[col.CsName] + ), typeof(object))), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), new[] { paramExp }).Compile(); - var retExp = Expression.Variable(typeof(object), "ret"); - var blockExp = new List(); - blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, Utils.GetDataReaderValueBlockExpression(Attribute.MapType, - Expression.MakeMemberAccess( - Expression.TypeAs(paramExp, col.Table.Type), - Table.Properties[col.CsName] - ) - )), - Expression.Return(returnTarget, retExp), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - }); - return Expression.Lambda>(Expression.Block(new[] { retExp }, blockExp), new[] { paramExp }).Compile(); - }); - return func(obj); - } - static ConcurrentDictionary> _dicSetMapValue = new ConcurrentDictionary>(); - public void SetMapValue(object obj, object val) { - var func = _dicSetMapValue.GetOrAdd(this, col => { - var objExp = Expression.Parameter(typeof(object), "obj"); - var valExp = Expression.Parameter(typeof(object), "val"); + var retExp = Expression.Variable(typeof(object), "ret"); + var blockExp = new List(); + blockExp.AddRange(new Expression[] { + Expression.Assign(retExp, Utils.GetDataReaderValueBlockExpression(Attribute.MapType, + Expression.MakeMemberAccess( + Expression.TypeAs(paramExp, col.Table.Type), + Table.Properties[col.CsName] + ) + )), + Expression.Return(returnTarget, retExp), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + }); + return Expression.Lambda>(Expression.Block(new[] { retExp }, blockExp), new[] { paramExp }).Compile(); + }); + return func(obj); + } + static ConcurrentDictionary> _dicSetMapValue = new ConcurrentDictionary>(); + public void SetMapValue(object obj, object val) + { + var func = _dicSetMapValue.GetOrAdd(this, col => + { + var objExp = Expression.Parameter(typeof(object), "obj"); + var valExp = Expression.Parameter(typeof(object), "val"); - if (Attribute.MapType == CsType) - return Expression.Lambda>( - Expression.Assign(Expression.MakeMemberAccess( - Expression.TypeAs(objExp, col.Table.Type), - Table.Properties[col.CsName] - ), Expression.Convert( - valExp, - Attribute.MapType)), objExp, valExp).Compile(); + if (Attribute.MapType == CsType) + return Expression.Lambda>( + Expression.Assign(Expression.MakeMemberAccess( + Expression.TypeAs(objExp, col.Table.Type), + Table.Properties[col.CsName] + ), Expression.Convert( + valExp, + Attribute.MapType)), objExp, valExp).Compile(); - return Expression.Lambda>( - Expression.Assign(Expression.MakeMemberAccess( - Expression.TypeAs(objExp, col.Table.Type), - Table.Properties[col.CsName] - ), Expression.Convert( - Utils.GetDataReaderValueBlockExpression(Attribute.MapType, valExp), - Attribute.MapType)), objExp, valExp).Compile(); - }); - func(obj, val); - } - } + return Expression.Lambda>( + Expression.Assign(Expression.MakeMemberAccess( + Expression.TypeAs(objExp, col.Table.Type), + Table.Properties[col.CsName] + ), Expression.Convert( + Utils.GetDataReaderValueBlockExpression(Attribute.MapType, valExp), + Attribute.MapType)), objExp, valExp).Compile(); + }); + func(obj, val); + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index 722fc1b1..d3c1fb3a 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -3,17 +3,19 @@ using System.Collections.Generic; using System.Reflection; using System.Text; -namespace FreeSql.Internal.Model { - public class ReadAnonymousTypeInfo { - public PropertyInfo Property { get; set; } - public string CsName { get; set; } - public Type CsType { get; set; } - public Type MapType { get; set; } - public string DbField { get; set; } - public ConstructorInfo Consturctor { get; set; } - public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; } - public List Childs = new List(); - public TableInfo Table { get; set; } - } - public enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties } +namespace FreeSql.Internal.Model +{ + public class ReadAnonymousTypeInfo + { + public PropertyInfo Property { get; set; } + public string CsName { get; set; } + public Type CsType { get; set; } + public Type MapType { get; set; } + public string DbField { get; set; } + public ConstructorInfo Consturctor { get; set; } + public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; } + public List Childs = new List(); + public TableInfo Table { get; set; } + } + public enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties } } diff --git a/FreeSql/Internal/Model/SelectColumnInfo.cs b/FreeSql/Internal/Model/SelectColumnInfo.cs index a92947a2..16075a85 100644 --- a/FreeSql/Internal/Model/SelectColumnInfo.cs +++ b/FreeSql/Internal/Model/SelectColumnInfo.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.Text; -namespace FreeSql.Internal.Model { - public class SelectColumnInfo { - public ColumnInfo Column { get; set; } - public SelectTableInfo Table { get; set; } - } +namespace FreeSql.Internal.Model +{ + public class SelectColumnInfo + { + public ColumnInfo Column { get; set; } + public SelectTableInfo Table { get; set; } + } } diff --git a/FreeSql/Internal/Model/SelectTableInfo.cs b/FreeSql/Internal/Model/SelectTableInfo.cs index 0c1d4172..b3e61254 100644 --- a/FreeSql/Internal/Model/SelectTableInfo.cs +++ b/FreeSql/Internal/Model/SelectTableInfo.cs @@ -1,22 +1,26 @@ using System.Linq.Expressions; -namespace FreeSql.Internal.Model { - public class SelectTableInfo { - public TableInfo Table { get; set; } +namespace FreeSql.Internal.Model +{ + public class SelectTableInfo + { + public TableInfo Table { get; set; } - private string _alias; - public string Alias { - get => _alias; - set { - _alias = value; - if (string.IsNullOrEmpty(AliasInit)) AliasInit = value; - } - } - public string AliasInit { get; set; } - public string On { get; set; } - public string NavigateCondition { get; set; } - public ParameterExpression Parameter { get; set; } - public SelectTableInfoType Type { get; set; } - } - public enum SelectTableInfoType { From, LeftJoin, InnerJoin, RightJoin, Parent } + private string _alias; + public string Alias + { + get => _alias; + set + { + _alias = value; + if (string.IsNullOrEmpty(AliasInit)) AliasInit = value; + } + } + public string AliasInit { get; set; } + public string On { get; set; } + public string NavigateCondition { get; set; } + public ParameterExpression Parameter { get; set; } + public SelectTableInfoType Type { get; set; } + } + public enum SelectTableInfoType { From, LeftJoin, InnerJoin, RightJoin, Parent } } diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index c08cfdb7..d1b5bb90 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -3,58 +3,65 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Reflection; -namespace FreeSql.Internal.Model { - public class TableInfo { - public Type Type { get; set; } - public Type TypeLazy { get; set; } - public MethodInfo TypeLazySetOrm { get; set; } - public Dictionary Properties { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - public Dictionary Columns { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - public Dictionary ColumnsByCs { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - public Dictionary ColumnsByCsIgnore { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - public ColumnInfo[] Primarys { get; set; } - public Dictionary> Uniques { get; set; } - public string CsName { get; set; } - public string DbName { get; set; } - public string DbOldName { get; set; } - public string SelectFilter { get; set; } - public bool DisableSyncStructure { get; set; } +namespace FreeSql.Internal.Model +{ + public class TableInfo + { + public Type Type { get; set; } + public Type TypeLazy { get; set; } + public MethodInfo TypeLazySetOrm { get; set; } + public Dictionary Properties { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public Dictionary Columns { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public Dictionary ColumnsByCs { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public Dictionary ColumnsByCsIgnore { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public ColumnInfo[] Primarys { get; set; } + public Dictionary> Uniques { get; set; } + public string CsName { get; set; } + public string DbName { get; set; } + public string DbOldName { get; set; } + public string SelectFilter { get; set; } + public bool DisableSyncStructure { get; set; } - public ColumnInfo VersionColumn { get; set; } + public ColumnInfo VersionColumn { get; set; } - ConcurrentDictionary _refs { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + ConcurrentDictionary _refs { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - internal void AddOrUpdateTableRef(string propertyName, TableRef tbref) { - _refs.AddOrUpdate(propertyName, tbref, (ok, ov) => tbref); - } - public TableRef GetTableRef(string propertyName, bool isThrowException) { - if (_refs.TryGetValue(propertyName, out var tryref) == false) return null; - if (tryref.Exception != null) { - if (isThrowException) throw tryref.Exception; - return null; - } - return tryref; - } - } + internal void AddOrUpdateTableRef(string propertyName, TableRef tbref) + { + _refs.AddOrUpdate(propertyName, tbref, (ok, ov) => tbref); + } + public TableRef GetTableRef(string propertyName, bool isThrowException) + { + if (_refs.TryGetValue(propertyName, out var tryref) == false) return null; + if (tryref.Exception != null) + { + if (isThrowException) throw tryref.Exception; + return null; + } + return tryref; + } + } - public class TableRef { - public PropertyInfo Property { get; set; } + public class TableRef + { + public PropertyInfo Property { get; set; } - public TableRefType RefType { get; set; } + public TableRefType RefType { get; set; } - public Type RefEntityType { get; set; } - /// - /// 中间表,多对多 - /// - public Type RefMiddleEntityType { get; set; } + public Type RefEntityType { get; set; } + /// + /// 中间表,多对多 + /// + public Type RefMiddleEntityType { get; set; } - public List Columns { get; set; } = new List(); - public List MiddleColumns { get; set; } = new List(); - public List RefColumns { get; set; } = new List(); + public List Columns { get; set; } = new List(); + public List MiddleColumns { get; set; } = new List(); + public List RefColumns { get; set; } = new List(); - public Exception Exception { get; set; } - } - public enum TableRefType { - OneToOne, ManyToOne, OneToMany, ManyToMany - } + public Exception Exception { get; set; } + } + public enum TableRefType + { + OneToOne, ManyToOne, OneToMany, ManyToMany + } } \ No newline at end of file diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 1899dcb2..8f3ee4cb 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -12,862 +12,990 @@ using System.Reflection; using System.Text; using System.Text.RegularExpressions; -namespace FreeSql.Internal { - public class Utils { +namespace FreeSql.Internal +{ + public class Utils + { - static ConcurrentDictionary> _cacheGetTableByEntity = new ConcurrentDictionary>(); - internal static void RemoveTableByEntity(Type entity, CommonUtils common) { - if (entity.IsAnonymousType() || - entity.IsValueType || - entity.IsNullableType() || - entity.NullableTypeOrThis() == typeof(BigInteger) - ) return; - var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary()); //区分数据库类型缓存 - if (tbc.TryRemove(entity, out var trytb) && trytb?.TypeLazy != null) tbc.TryRemove(trytb.TypeLazy, out var trylz); - } - internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) { - if (entity.IsAnonymousType() || - entity.IsValueType || - entity.IsNullableType() || - entity.NullableTypeOrThis() == typeof(BigInteger) - ) return null; - var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary()); //区分数据库类型缓存 - if (tbc.TryGetValue(entity, out var trytb)) return trytb; - if (common.CodeFirst.GetDbInfo(entity) != null) return null; - if (typeof(IEnumerable).IsAssignableFrom(entity) && entity.IsGenericParameter == true) return null; - if (entity.IsArray) return null; + static ConcurrentDictionary> _cacheGetTableByEntity = new ConcurrentDictionary>(); + internal static void RemoveTableByEntity(Type entity, CommonUtils common) + { + if (entity.IsAnonymousType() || + entity.IsValueType || + entity.IsNullableType() || + entity.NullableTypeOrThis() == typeof(BigInteger) + ) return; + var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary()); //区分数据库类型缓存 + if (tbc.TryRemove(entity, out var trytb) && trytb?.TypeLazy != null) tbc.TryRemove(trytb.TypeLazy, out var trylz); + } + internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) + { + if (entity.IsAnonymousType() || + entity.IsValueType || + entity.IsNullableType() || + entity.NullableTypeOrThis() == typeof(BigInteger) + ) return null; + var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary()); //区分数据库类型缓存 + if (tbc.TryGetValue(entity, out var trytb)) return trytb; + if (common.CodeFirst.GetDbInfo(entity) != null) return null; + if (typeof(IEnumerable).IsAssignableFrom(entity) && entity.IsGenericParameter == true) return null; + if (entity.IsArray) return null; - var tbattr = common.GetEntityTableAttribute(entity); - trytb = new TableInfo(); - trytb.Type = entity; - trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); - trytb.CsName = entity.Name; - trytb.DbName = (tbattr?.Name ?? entity.Name); - trytb.DbOldName = tbattr?.OldName; - if (common.CodeFirst.IsSyncStructureToLower) { - trytb.DbName = trytb.DbName.ToLower(); - trytb.DbOldName = trytb.DbOldName?.ToLower(); - } - if (common.CodeFirst.IsSyncStructureToUpper) { - trytb.DbName = trytb.DbName.ToUpper(); - trytb.DbOldName = trytb.DbOldName?.ToUpper(); - } - trytb.SelectFilter = tbattr?.SelectFilter; - if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; - var propsLazy = new List<(PropertyInfo, bool, bool)>(); - var propsNavObjs = new List(); - var propsComment = CommonUtils.GetProperyCommentBySummary(entity); - foreach (var p in trytb.Properties.Values) { - var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); - var colattr = common.GetEntityColumnAttribute(entity, p); - var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType); - //if (tp == null) continue; - if (tp == null && colattr == null) { - if (common.CodeFirst.IsLazyLoading) { - var getIsVirtual = trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; - var setIsVirtual = setMethod?.IsVirtual; - if (getIsVirtual == true || setIsVirtual == true) - propsLazy.Add((p, getIsVirtual == true, setIsVirtual == true)); - } - propsNavObjs.Add(p); - continue; - } - if (colattr == null) - colattr = new ColumnAttribute { - Name = p.Name, - DbType = tp.Value.dbtypeFull, - IsIdentity = false, - IsNullable = tp.Value.isnullable ?? true, - IsPrimary = false, - IsIgnore = false, - Unique = null, - MapType = p.PropertyType - }; - if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable; - if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)"; - if (colattr.DbType.StartsWith("set(") || colattr.DbType.StartsWith("enum(")) { - var leftBt = colattr.DbType.IndexOf('('); - colattr.DbType = colattr.DbType.Substring(0, leftBt).ToUpper() + colattr.DbType.Substring(leftBt); - } - else - colattr.DbType = colattr.DbType.ToUpper(); + var tbattr = common.GetEntityTableAttribute(entity); + trytb = new TableInfo(); + trytb.Type = entity; + trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); + trytb.CsName = entity.Name; + trytb.DbName = (tbattr?.Name ?? entity.Name); + trytb.DbOldName = tbattr?.OldName; + if (common.CodeFirst.IsSyncStructureToLower) + { + trytb.DbName = trytb.DbName.ToLower(); + trytb.DbOldName = trytb.DbOldName?.ToLower(); + } + if (common.CodeFirst.IsSyncStructureToUpper) + { + trytb.DbName = trytb.DbName.ToUpper(); + trytb.DbOldName = trytb.DbOldName?.ToUpper(); + } + trytb.SelectFilter = tbattr?.SelectFilter; + if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; + var propsLazy = new List<(PropertyInfo, bool, bool)>(); + var propsNavObjs = new List(); + var propsComment = CommonUtils.GetProperyCommentBySummary(entity); + foreach (var p in trytb.Properties.Values) + { + var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); + var colattr = common.GetEntityColumnAttribute(entity, p); + var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType); + //if (tp == null) continue; + if (tp == null && colattr == null) + { + if (common.CodeFirst.IsLazyLoading) + { + var getIsVirtual = trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; + var setIsVirtual = setMethod?.IsVirtual; + if (getIsVirtual == true || setIsVirtual == true) + propsLazy.Add((p, getIsVirtual == true, setIsVirtual == true)); + } + propsNavObjs.Add(p); + continue; + } + if (colattr == null) + colattr = new ColumnAttribute + { + Name = p.Name, + DbType = tp.Value.dbtypeFull, + IsIdentity = false, + IsNullable = tp.Value.isnullable ?? true, + IsPrimary = false, + IsIgnore = false, + Unique = null, + MapType = p.PropertyType + }; + if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable; + if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)"; + if (colattr.DbType.StartsWith("set(") || colattr.DbType.StartsWith("enum(")) + { + var leftBt = colattr.DbType.IndexOf('('); + colattr.DbType = colattr.DbType.Substring(0, leftBt).ToUpper() + colattr.DbType.Substring(leftBt); + } + else + colattr.DbType = colattr.DbType.ToUpper(); - if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; - if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; - if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; - if (common.CodeFirst.IsSyncStructureToLower) { - colattr.Name = colattr.Name.ToLower(); - colattr.Unique = colattr.Unique?.ToLower(); - } - if (common.CodeFirst.IsSyncStructureToUpper) { - colattr.Name = colattr.Name.ToUpper(); - colattr.Unique = colattr.Unique?.ToUpper(); - } + if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; + if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; + if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; + if (common.CodeFirst.IsSyncStructureToLower) + { + colattr.Name = colattr.Name.ToLower(); + colattr.Unique = colattr.Unique?.ToLower(); + } + if (common.CodeFirst.IsSyncStructureToUpper) + { + colattr.Name = colattr.Name.ToUpper(); + colattr.Unique = colattr.Unique?.ToUpper(); + } - if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) { - colattr.IsNullable = false; - colattr.DbType += " NOT NULL"; - } - if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", ""); - colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => { - var tmpLt = Regex.Replace(m.Groups[0].Value, @"\s", ""); - if (tmpLt.Contains("CHAR")) tmpLt = tmpLt.Replace("CHAR", " CHAR"); - if (tmpLt.Contains("BYTE")) tmpLt = tmpLt.Replace("BYTE", " BYTE"); - return tmpLt; - }); - if (colattr.IsIdentity == true && colattr.MapType.IsNumberType() == false) - colattr.IsIdentity = false; - if (setMethod == null) colattr.IsIgnore = true; + if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) + { + colattr.IsNullable = false; + colattr.DbType += " NOT NULL"; + } + if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", ""); + colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => + { + var tmpLt = Regex.Replace(m.Groups[0].Value, @"\s", ""); + if (tmpLt.Contains("CHAR")) tmpLt = tmpLt.Replace("CHAR", " CHAR"); + if (tmpLt.Contains("BYTE")) tmpLt = tmpLt.Replace("BYTE", " BYTE"); + return tmpLt; + }); + if (colattr.IsIdentity == true && colattr.MapType.IsNumberType() == false) + colattr.IsIdentity = false; + if (setMethod == null) colattr.IsIgnore = true; - var col = new ColumnInfo { - Table = trytb, - CsName = p.Name, - CsType = p.PropertyType, - Attribute = colattr - }; - if (propsComment != null && propsComment.TryGetValue(p.Name, out var trycomment)) - col.Comment = trycomment; - if (colattr.IsIgnore) { - trytb.ColumnsByCsIgnore.Add(p.Name, col); - continue; - } - colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type)); - if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue); - if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; - if (colattr.IsNullable == false && colattr.DbDefautValue == null) { - var citype = colattr.MapType.IsNullableType() ? colattr.MapType.GenericTypeArguments.FirstOrDefault() : colattr.MapType; - if (citype.IsArray) - colattr.DbDefautValue = Array.CreateInstance(citype, 0); - else - colattr.DbDefautValue = Activator.CreateInstance(citype); - } + var col = new ColumnInfo + { + Table = trytb, + CsName = p.Name, + CsType = p.PropertyType, + Attribute = colattr + }; + if (propsComment != null && propsComment.TryGetValue(p.Name, out var trycomment)) + col.Comment = trycomment; + if (colattr.IsIgnore) + { + trytb.ColumnsByCsIgnore.Add(p.Name, col); + continue; + } + colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type)); + if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue); + if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; + if (colattr.IsNullable == false && colattr.DbDefautValue == null) + { + var citype = colattr.MapType.IsNullableType() ? colattr.MapType.GenericTypeArguments.FirstOrDefault() : colattr.MapType; + if (citype.IsArray) + colattr.DbDefautValue = Array.CreateInstance(citype, 0); + else + colattr.DbDefautValue = Activator.CreateInstance(citype); + } - trytb.Columns.Add(colattr.Name, col); - trytb.ColumnsByCs.Add(p.Name, col); - } - trytb.VersionColumn = trytb.Columns.Values.Where(a => a.Attribute.IsVersion == true).LastOrDefault(); - if (trytb.VersionColumn != null) { - if (trytb.VersionColumn.Attribute.MapType.IsNullableType() || trytb.VersionColumn.Attribute.MapType.IsNumberType() == false) - throw new Exception($"属性{trytb.VersionColumn.CsName} 被标注为行锁(乐观锁)(IsVersion),但其必须为数字类型,并且不可为 Nullable"); - } - trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); - if (trytb.Primarys.Any() == false) { - var identcol = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).FirstOrDefault(); - if (identcol != null) trytb.Primarys = new[] { identcol }; - if (trytb.Primarys.Any() == false) { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, "id", true) == 0).ToArray(); - if (trytb.Primarys.Any() == false) { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}id", true) == 0).ToArray(); - if (trytb.Primarys.Any() == false) { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}_id", true) == 0).ToArray(); - } - } - } - foreach (var col in trytb.Primarys) - col.Attribute.IsPrimary = true; - } - //从数据库查找主键、自增 - if (common.CodeFirst.IsConfigEntityFromDbFirst) { - try { - if (common._orm.DbFirst != null) { - if (common.dbTables == null) - lock (common.dbTablesLock) - if (common.dbTables == null) - common.dbTables = common._orm.DbFirst.GetTablesByDatabase(); + trytb.Columns.Add(colattr.Name, col); + trytb.ColumnsByCs.Add(p.Name, col); + } + trytb.VersionColumn = trytb.Columns.Values.Where(a => a.Attribute.IsVersion == true).LastOrDefault(); + if (trytb.VersionColumn != null) + { + if (trytb.VersionColumn.Attribute.MapType.IsNullableType() || trytb.VersionColumn.Attribute.MapType.IsNumberType() == false) + throw new Exception($"属性{trytb.VersionColumn.CsName} 被标注为行锁(乐观锁)(IsVersion),但其必须为数字类型,并且不可为 Nullable"); + } + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + if (trytb.Primarys.Any() == false) + { + var identcol = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).FirstOrDefault(); + if (identcol != null) trytb.Primarys = new[] { identcol }; + if (trytb.Primarys.Any() == false) + { + trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, "id", true) == 0).ToArray(); + if (trytb.Primarys.Any() == false) + { + trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}id", true) == 0).ToArray(); + if (trytb.Primarys.Any() == false) + { + trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}_id", true) == 0).ToArray(); + } + } + } + foreach (var col in trytb.Primarys) + col.Attribute.IsPrimary = true; + } + //从数据库查找主键、自增 + if (common.CodeFirst.IsConfigEntityFromDbFirst) + { + try + { + if (common._orm.DbFirst != null) + { + if (common.dbTables == null) + lock (common.dbTablesLock) + if (common.dbTables == null) + common.dbTables = common._orm.DbFirst.GetTablesByDatabase(); - var finddbtbs = common.dbTables.Where(a => string.Compare(a.Name, trytb.CsName, true) == 0 || string.Compare(a.Name, trytb.DbName, true) == 0); - foreach (var dbtb in finddbtbs) { - foreach (var dbident in dbtb.Identitys) { - if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.Attribute.MapType == dbident.CsType || - trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.Attribute.MapType == dbident.CsType) { - trycol.Attribute.IsIdentity = true; - } - } - foreach (var dbpk in dbtb.Primarys) { - if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.Attribute.MapType == dbpk.CsType || - trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.Attribute.MapType == dbpk.CsType) { - trycol.Attribute.IsPrimary = true; - } - } - foreach(var dbuk in dbtb.UniquesDict) { - foreach (var dbcol in dbuk.Value) { - if (trytb.Columns.TryGetValue(dbcol.Name, out var trycol) && trycol.Attribute.MapType == dbcol.CsType || - trytb.ColumnsByCs.TryGetValue(dbcol.Name, out trycol) && trycol.Attribute.MapType == dbcol.CsType) { - if (trycol.Attribute._Uniques?.Contains(dbuk.Key) != true) - trycol.Attribute.Unique += $"," + dbuk.Key; - } - } - } - } - } - } catch { } - trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); - } - var allunique = trytb.Columns.Values.Where(a => a.Attribute._Uniques != null).SelectMany(a => a.Attribute._Uniques).Distinct(); - trytb.Uniques = allunique.ToDictionary(a => a, a => trytb.Columns.Values.Where(b => b.Attribute._Uniques != null && b.Attribute._Uniques.Contains(a)).ToList()); - tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); + var finddbtbs = common.dbTables.Where(a => string.Compare(a.Name, trytb.CsName, true) == 0 || string.Compare(a.Name, trytb.DbName, true) == 0); + foreach (var dbtb in finddbtbs) + { + foreach (var dbident in dbtb.Identitys) + { + if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.Attribute.MapType == dbident.CsType || + trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.Attribute.MapType == dbident.CsType) + { + trycol.Attribute.IsIdentity = true; + } + } + foreach (var dbpk in dbtb.Primarys) + { + if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.Attribute.MapType == dbpk.CsType || + trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.Attribute.MapType == dbpk.CsType) + { + trycol.Attribute.IsPrimary = true; + } + } + foreach (var dbuk in dbtb.UniquesDict) + { + foreach (var dbcol in dbuk.Value) + { + if (trytb.Columns.TryGetValue(dbcol.Name, out var trycol) && trycol.Attribute.MapType == dbcol.CsType || + trytb.ColumnsByCs.TryGetValue(dbcol.Name, out trycol) && trycol.Attribute.MapType == dbcol.CsType) + { + if (trycol.Attribute._Uniques?.Contains(dbuk.Key) != true) + trycol.Attribute.Unique += $"," + dbuk.Key; + } + } + } + } + } + } + catch { } + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + } + var allunique = trytb.Columns.Values.Where(a => a.Attribute._Uniques != null).SelectMany(a => a.Attribute._Uniques).Distinct(); + trytb.Uniques = allunique.ToDictionary(a => a, a => trytb.Columns.Values.Where(b => b.Attribute._Uniques != null && b.Attribute._Uniques.Contains(a)).ToList()); + tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); - #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 - var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace}.{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace}.{trytb.Type.Name}"; - var trytbTypeLazyName = default(string); - var overrieds = 0; - StringBuilder cscode = null; - if (common.CodeFirst.IsLazyLoading && propsLazy.Any()) { - if (trytb.Type.IsPublic == false && trytb.Type.IsNestedPublic == false) throw new Exception($"【延时加载】实体类型 {trytbTypeName} 必须声明为 public"); + #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 + var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace}.{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace}.{trytb.Type.Name}"; + var trytbTypeLazyName = default(string); + var overrieds = 0; + StringBuilder cscode = null; + if (common.CodeFirst.IsLazyLoading && propsLazy.Any()) + { + if (trytb.Type.IsPublic == false && trytb.Type.IsNestedPublic == false) throw new Exception($"【延时加载】实体类型 {trytbTypeName} 必须声明为 public"); - trytbTypeLazyName = $"FreeSqlLazyEntity__{Regex.Replace(trytbTypeName, @"[^\w\d]", "_")}"; - - cscode = new StringBuilder(); - cscode.AppendLine("using System;") - .AppendLine("using FreeSql.DataAnnotations;") - .AppendLine("using System.Collections.Generic;") - .AppendLine("using System.Linq;") - .AppendLine("using Newtonsoft.Json;") - .AppendLine() - .Append("public class ").Append(trytbTypeLazyName).Append(" : ").Append(trytbTypeName).AppendLine(" {") - .AppendLine(" [JsonIgnore] private IFreeSql __fsql_orm__ { get; set; }\r\n"); - } + trytbTypeLazyName = $"FreeSqlLazyEntity__{Regex.Replace(trytbTypeName, @"[^\w\d]", "_")}"; - foreach(var pnv in propsNavObjs) { - var vp = propsLazy.Where(a => a.Item1 == pnv).FirstOrDefault(); - var isLazy = vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName); - var propTypeName = pnv.PropertyType.IsGenericType ? - $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace}.{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace}.{a.Name}"))}>" : - (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace}.{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name}"); + cscode = new StringBuilder(); + cscode.AppendLine("using System;") + .AppendLine("using FreeSql.DataAnnotations;") + .AppendLine("using System.Collections.Generic;") + .AppendLine("using System.Linq;") + .AppendLine("using Newtonsoft.Json;") + .AppendLine() + .Append("public class ").Append(trytbTypeLazyName).Append(" : ").Append(trytbTypeName).AppendLine(" {") + .AppendLine(" [JsonIgnore] private IFreeSql __fsql_orm__ { get; set; }\r\n"); + } - var pnvBind = pnv.GetCustomAttribute()?.Bind.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); - var nvref = new TableRef(); - nvref.Property = pnv; + foreach (var pnv in propsNavObjs) + { + var vp = propsLazy.Where(a => a.Item1 == pnv).FirstOrDefault(); + var isLazy = vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName); + var propTypeName = pnv.PropertyType.IsGenericType ? + $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace}.{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace}.{a.Name}"))}>" : + (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace}.{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name}"); - //List 或 ICollection,一对多、多对多 - var propElementType = pnv.PropertyType.GenericTypeArguments.FirstOrDefault() ?? pnv.PropertyType.GetElementType(); - if (propElementType != null) { - if (typeof(IEnumerable).IsAssignableFrom(pnv.PropertyType) == false) continue; - if (trytb.Primarys.Any() == false) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {trytbTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - continue; - } + var pnvBind = pnv.GetCustomAttribute()?.Bind.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); + var nvref = new TableRef(); + nvref.Property = pnv; - var tbref = propElementType == trytb.Type ? trytb : GetTableByEntity(propElementType, common); //可能是父子关系 - if (tbref == null) continue; + //List 或 ICollection,一对多、多对多 + var propElementType = pnv.PropertyType.GenericTypeArguments.FirstOrDefault() ?? pnv.PropertyType.GetElementType(); + if (propElementType != null) + { + if (typeof(IEnumerable).IsAssignableFrom(pnv.PropertyType) == false) continue; + if (trytb.Primarys.Any() == false) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {trytbTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + continue; + } - var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}"; - Type midType = null; - var isManyToMany = propElementType != trytb.Type && - pnv.Name.EndsWith($"{tbref.CsName}s") && - tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && - z.Key.EndsWith($"{trytb.CsName}s", StringComparison.CurrentCultureIgnoreCase) && - typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); - if (isManyToMany) { - if (tbref.Primarys.Any() == false) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - continue; - } + var tbref = propElementType == trytb.Type ? trytb : GetTableByEntity(propElementType, common); //可能是父子关系 + if (tbref == null) continue; - //中间表怎么查询,比如 Song、Tag、SongTag - var midFlagStr = pnv.Name.Remove(pnv.Name.Length - tbref.CsName.Length - 1); + var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}"; + Type midType = null; + var isManyToMany = propElementType != trytb.Type && + pnv.Name.EndsWith($"{tbref.CsName}s") && + tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && + z.Key.EndsWith($"{trytb.CsName}s", StringComparison.CurrentCultureIgnoreCase) && + typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); + if (isManyToMany) + { + if (tbref.Primarys.Any() == false) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + continue; + } - #region 在 trytb 命名空间下查找中间类 - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); - if (midType != null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - if (midType == null) { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - if (midType != null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - if (midType == null) { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); - if (midType != null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - if (midType == null) { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - if (midType != null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - #endregion + //中间表怎么查询,比如 Song、Tag、SongTag + var midFlagStr = pnv.Name.Remove(pnv.Name.Length - tbref.CsName.Length - 1); - #region 在 tbref 命名空间下查找中间类 - if (midType == null) { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); - if (midType != null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - if (midType == null) { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - if (midType != null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - if (midType == null) { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); - if (midType != null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - if (midType == null) { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - if (midType != null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - #endregion + #region 在 trytb 命名空间下查找中间类 + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + } + #endregion - isManyToMany = midType != null; - } - if (isManyToMany) { - var tbmid = GetTableByEntity(midType, common); - var midTypePropsTrytb = tbmid.Properties.Where(a => a.Value.PropertyType == trytb.Type).FirstOrDefault().Value; - //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); - var lmbdWhere = isLazy ? new StringBuilder() : null; - for (var a = 0; a < trytb.Primarys.Length; a++) { - var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); - if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); - if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}{findtrytbPkCsName}", out var trycol) == false && //骆峰命名 - tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}_{findtrytbPkCsName}", out trycol) == false //下划线命名 - ) { + #region 在 tbref 命名空间下查找中间类 + if (midType == null) + { + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + } + if (midType == null) + { + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + } + if (midType == null) + { + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + } + if (midType == null) + { + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + } + #endregion - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {trytb.CsName}.{trytb.Primarys[a].CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - if (trycol == null) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTrytb.Name}{findtrytbPkCsName}、{midTypePropsTrytb.Name}_{findtrytbPkCsName}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } + isManyToMany = midType != null; + } + if (isManyToMany) + { + var tbmid = GetTableByEntity(midType, common); + var midTypePropsTrytb = tbmid.Properties.Where(a => a.Value.PropertyType == trytb.Type).FirstOrDefault().Value; + //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); + var lmbdWhere = isLazy ? new StringBuilder() : null; + for (var a = 0; a < trytb.Primarys.Length; a++) + { + var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); + if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); + if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}{findtrytbPkCsName}", out var trycol) == false && //骆峰命名 + tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}_{findtrytbPkCsName}", out trycol) == false //下划线命名 + ) + { - nvref.Columns.Add(trytb.Primarys[a]); - nvref.MiddleColumns.Add(trycol); - if (tbmid.Primarys.Any() == false) - trycol.Attribute.IsPrimary = true; + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {trytb.CsName}.{trytb.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTrytb.Name}{findtrytbPkCsName}、{midTypePropsTrytb.Name}_{findtrytbPkCsName}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } - if (isLazy) { - if (a > 0) lmbdWhere.Append(" && "); - lmbdWhere.Append("b.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); - } - } + nvref.Columns.Add(trytb.Primarys[a]); + nvref.MiddleColumns.Add(trycol); + if (tbmid.Primarys.Any() == false) + trycol.Attribute.IsPrimary = true; - if (nvref.Exception == null) { - var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; - for (var a = 0; a < tbref.Primarys.Length; a++) { - var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); - if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); - if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 - tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名 - ) { + if (isLazy) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("b.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); + } + } - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - if (trycol == null) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTbref.Name}{findtbrefPkCsName}、{midTypePropsTbref.Name}_{findtbrefPkCsName}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } + if (nvref.Exception == null) + { + var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; + for (var a = 0; a < tbref.Primarys.Length; a++) + { + var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); + if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); + if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 + tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名 + ) + { - nvref.RefColumns.Add(tbref.Primarys[a]); - nvref.MiddleColumns.Add(trycol); - if (tbmid.Primarys.Any() == false) - trycol.Attribute.IsPrimary = true; + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTbref.Name}{findtbrefPkCsName}、{midTypePropsTbref.Name}_{findtbrefPkCsName}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } - if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); - } - } - if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) { - nvref.RefMiddleEntityType = tbmid.Type; - nvref.RefEntityType = tbref.Type; - nvref.RefType = TableRefType.ManyToMany; - trytb.AddOrUpdateTableRef(pnv.Name, nvref); + nvref.RefColumns.Add(tbref.Primarys[a]); + nvref.MiddleColumns.Add(trycol); + if (tbmid.Primarys.Any() == false) + trycol.Attribute.IsPrimary = true; - if (tbmid.Primarys.Any() == false) - tbmid.Primarys = tbmid.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); - } + if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); + } + } + if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) + { + nvref.RefMiddleEntityType = tbmid.Type; + nvref.RefEntityType = tbref.Type; + nvref.RefType = TableRefType.ManyToMany; + trytb.AddOrUpdateTableRef(pnv.Name, nvref); - if (isLazy) { - cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); - if (vp.Item2) { //get 重写 - cscode.Append(" get {\r\n") - .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); + if (tbmid.Primarys.Any() == false) + tbmid.Primarys = tbmid.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + } - if (nvref.Exception == null) - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}") - .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace}.{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") - .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();") - .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); - else - cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); + if (isLazy) + { + cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + if (vp.Item2) + { //get 重写 + cscode.Append(" get {\r\n") + .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); - cscode.Append(" }\r\n") - .Append(" return base.").Append(pnv.Name).AppendLine(";") - .Append(" }\r\n"); - } - if (vp.Item3) { //set 重写 - cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); - } - cscode.AppendLine(" }"); - } - } else { //One To Many - List bindColumns = new List(); - if (pnvBind != null) { - foreach(var bi in pnvBind) { - if (tbref.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {tbrefTypeName} 未找到属性:{bi}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - bindColumns.Add(trybindcol); - } - } + if (nvref.Exception == null) + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}") + .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace}.{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") + .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); + else + cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); - PropertyInfo refprop = null; - var refcols = tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type); - refprop = refcols.Count() == 1 ? refcols.First().Value : null; - var lmbdWhere = isLazy ? new StringBuilder() : null; + cscode.Append(" }\r\n") + .Append(" return base.").Append(pnv.Name).AppendLine(";") + .Append(" }\r\n"); + } + if (vp.Item3) + { //set 重写 + cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); + } + cscode.AppendLine(" }"); + } + } + else + { //One To Many + List bindColumns = new List(); + if (pnvBind != null) + { + foreach (var bi in pnvBind) + { + if (tbref.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {tbrefTypeName} 未找到属性:{bi}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + bindColumns.Add(trybindcol); + } + } - if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != trytb.Primarys.Length) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 内部主键数目({trytb.Primarys.Length}) 不相同"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - for (var a = 0; nvref.Exception == null && a < trytb.Primarys.Length; a++) { - var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); - if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); - var findtrytb = pnv.Name; - if (findtrytb.EndsWith(tbref.CsName + "s")) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1); - findtrytb += trytb.CsName; + PropertyInfo refprop = null; + var refcols = tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type); + refprop = refcols.Count() == 1 ? refcols.First().Value : null; + var lmbdWhere = isLazy ? new StringBuilder() : null; - var trycol = bindColumns.Any() ? bindColumns[a] : null; - if (trycol == null && - tbref.ColumnsByCs.TryGetValue($"{findtrytb}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 - tbref.ColumnsByCs.TryGetValue($"{findtrytb}_{findtrytbPkCsName}", out trycol) == false //下划线命名 - ) { - if (refprop != null && - tbref.ColumnsByCs.TryGetValue($"{refprop.Name}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 - tbref.ColumnsByCs.TryGetValue($"{refprop.Name}_{findtrytbPkCsName}", out trycol) == false) //下划线命名 - { + if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != trytb.Primarys.Length) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 内部主键数目({trytb.Primarys.Length}) 不相同"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + for (var a = 0; nvref.Exception == null && a < trytb.Primarys.Length; a++) + { + var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); + if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); + var findtrytb = pnv.Name; + if (findtrytb.EndsWith(tbref.CsName + "s")) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1); + findtrytb += trytb.CsName; - } - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) { - nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trytb.Primarys[a].CsName} 和 {tbref.CsName}.{trycol.CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - if (trycol == null) { - nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbref.CsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}" + (refprop == null ? "" : $"、{refprop.Name}{findtrytbPkCsName}、{refprop.Name}_{findtrytbPkCsName}。或者使用 [Navigate] 特性指定关系映射。")); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } + var trycol = bindColumns.Any() ? bindColumns[a] : null; + if (trycol == null && + tbref.ColumnsByCs.TryGetValue($"{findtrytb}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 + tbref.ColumnsByCs.TryGetValue($"{findtrytb}_{findtrytbPkCsName}", out trycol) == false //下划线命名 + ) + { + if (refprop != null && + tbref.ColumnsByCs.TryGetValue($"{refprop.Name}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 + tbref.ColumnsByCs.TryGetValue($"{refprop.Name}_{findtrytbPkCsName}", out trycol) == false) //下划线命名 + { - nvref.Columns.Add(trytb.Primarys[a]); - nvref.RefColumns.Add(trycol); + } + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) + { + nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trytb.Primarys[a].CsName} 和 {tbref.CsName}.{trycol.CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbref.CsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}" + (refprop == null ? "" : $"、{refprop.Name}{findtrytbPkCsName}、{refprop.Name}_{findtrytbPkCsName}。或者使用 [Navigate] 特性指定关系映射。")); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } - if (isLazy && nvref.Exception == null) { - if (a > 0) lmbdWhere.Append(" && "); - lmbdWhere.Append("a.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); + nvref.Columns.Add(trytb.Primarys[a]); + nvref.RefColumns.Add(trycol); - if (refprop == null) { //加载成功后,把列表对应的导航属性值设置为 this,比如 Select().ToOne().Topics 下的 TopicType 属性值全部为 this - var findtrytbName = trycol.CsName; - if (findtrytbName.EndsWith(trytb.Primarys.First().CsName)) { - findtrytbName = findtrytbName.Remove(findtrytbName.Length - trytb.Primarys.First().CsName.Length).TrimEnd('_'); - if (tbref.Properties.TryGetValue(findtrytbName, out refprop) && refprop.PropertyType != trytb.Type) - refprop = null; - } - } - } - } - if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) { - nvref.RefEntityType = tbref.Type; - nvref.RefType = TableRefType.OneToMany; - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - } + if (isLazy && nvref.Exception == null) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("a.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); - if (isLazy) { - cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); - if (vp.Item2) { //get 重写 - cscode.Append(" get {\r\n") - .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); + if (refprop == null) + { //加载成功后,把列表对应的导航属性值设置为 this,比如 Select().ToOne().Topics 下的 TopicType 属性值全部为 this + var findtrytbName = trycol.CsName; + if (findtrytbName.EndsWith(trytb.Primarys.First().CsName)) + { + findtrytbName = findtrytbName.Remove(findtrytbName.Length - trytb.Primarys.First().CsName.Length).TrimEnd('_'); + if (tbref.Properties.TryGetValue(findtrytbName, out refprop) && refprop.PropertyType != trytb.Type) + refprop = null; + } + } + } + } + if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) + { + nvref.RefEntityType = tbref.Type; + nvref.RefType = TableRefType.OneToMany; + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + } - if (nvref.Exception == null) { - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}").Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();"); - if (refprop != null) { - cscode.Append(" foreach (var loc1 in base.").Append(pnv.Name).AppendLine(")") - .Append(" loc1.").Append(refprop.Name).AppendLine(" = this;") - .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); - } - } else - cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); + if (isLazy) + { + cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + if (vp.Item2) + { //get 重写 + cscode.Append(" get {\r\n") + .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); - cscode - .Append(" }\r\n") - .Append(" return base.").Append(pnv.Name).AppendLine(";") - .Append(" }\r\n"); - } - if (vp.Item3) { //set 重写 - cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); - } - cscode.AppendLine(" }"); - } - } - } else { //一对一、多对一 - var tbref = pnv.PropertyType == trytb.Type ? trytb : GetTableByEntity(pnv.PropertyType, common); //可能是父子关系 - if (tbref == null) continue; - if (tbref.Primarys.Any() == false) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {propTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}"; - var isOnoToOne = pnv.PropertyType != trytb.Type && - tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type).Any() && - tbref.Primarys.Length == trytb.Primarys.Length && - string.Join(",", tbref.Primarys.Select(a => a.CsType.FullName).OrderBy(a => a)) == string.Join(",", trytb.Primarys.Select(a => a.CsType.FullName).OrderBy(a => a)); + if (nvref.Exception == null) + { + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}").Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();"); + if (refprop != null) + { + cscode.Append(" foreach (var loc1 in base.").Append(pnv.Name).AppendLine(")") + .Append(" loc1.").Append(refprop.Name).AppendLine(" = this;") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); + } + } + else + cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); - List bindColumns = new List(); - if (pnvBind != null) { - foreach(var bi in pnvBind) { - if (trytb.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {trytbTypeName} 未找到属性:{bi}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - bindColumns.Add(trybindcol); - } - } - var lmbdWhere = new StringBuilder(); + cscode + .Append(" }\r\n") + .Append(" return base.").Append(pnv.Name).AppendLine(";") + .Append(" }\r\n"); + } + if (vp.Item3) + { //set 重写 + cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); + } + cscode.AppendLine(" }"); + } + } + } + else + { //一对一、多对一 + var tbref = pnv.PropertyType == trytb.Type ? trytb : GetTableByEntity(pnv.PropertyType, common); //可能是父子关系 + if (tbref == null) continue; + if (tbref.Primarys.Any() == false) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {propTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}"; + var isOnoToOne = pnv.PropertyType != trytb.Type && + tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type).Any() && + tbref.Primarys.Length == trytb.Primarys.Length && + string.Join(",", tbref.Primarys.Select(a => a.CsType.FullName).OrderBy(a => a)) == string.Join(",", trytb.Primarys.Select(a => a.CsType.FullName).OrderBy(a => a)); - if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != tbref.Primarys.Length) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 外部主键数目({tbref.Primarys.Length}) 不相同"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - for (var a = 0; nvref.Exception == null && a < tbref.Primarys.Length; a++) { - var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); - if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); + List bindColumns = new List(); + if (pnvBind != null) + { + foreach (var bi in pnvBind) + { + if (trytb.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {trytbTypeName} 未找到属性:{bi}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + bindColumns.Add(trybindcol); + } + } + var lmbdWhere = new StringBuilder(); - var trycol = bindColumns.Any() ? bindColumns[a] : null; - if (trycol == null && - trytb.ColumnsByCs.TryGetValue($"{pnv.Name}{findtbrefPkCsName}", out trycol) == false && //骆峰命名 - trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_{findtbrefPkCsName}", out trycol) == false && //下划线命名 - //tbref.Primarys.Length == 1 && - trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_Id", out trycol) == false && - trytb.ColumnsByCs.TryGetValue($"{pnv.Name}Id", out trycol) == false - ) { - //一对一,主键与主键查找 - if (isOnoToOne) { - var trytbpks = trytb.Primarys.Where(z => z.CsType == tbref.Primarys[a].CsType); //一对一,按类型 - if (trytbpks.Count() == 1) trycol = trytbpks.First(); - else { - trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, tbref.Primarys[a].CsName, true) == 0); //一对一,按主键名相同 - if (trytbpks.Count() == 1) trycol = trytbpks.First(); - else { - trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, $"{tbref.CsName}{tbref.Primarys[a].CsName}", true) == 0); //一对一,主键名 = 表+主键名 - if (trytbpks.Count() == 1) trycol = trytbpks.First(); - else { - trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, $"{tbref.CsName}_{tbref.Primarys[a].CsName}", true) == 0); //一对一,主键名 = 表+_主键名 - if (trytbpks.Count() == 1) trycol = trytbpks.First(); - } - } - } - } - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - if (trycol == null) { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 没有找到对应的字段,如:{pnv.Name}{findtbrefPkCsName}、{pnv.Name}_{findtbrefPkCsName}。或者使用 [Navigate] 特性指定关系映射。"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } + if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != tbref.Primarys.Length) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 外部主键数目({tbref.Primarys.Length}) 不相同"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + for (var a = 0; nvref.Exception == null && a < tbref.Primarys.Length; a++) + { + var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); + if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); - nvref.Columns.Add(trycol); - nvref.RefColumns.Add(tbref.Primarys[a]); + var trycol = bindColumns.Any() ? bindColumns[a] : null; + if (trycol == null && + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}{findtbrefPkCsName}", out trycol) == false && //骆峰命名 + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_{findtbrefPkCsName}", out trycol) == false && //下划线命名 + //tbref.Primarys.Length == 1 && + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_Id", out trycol) == false && + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}Id", out trycol) == false + ) + { + //一对一,主键与主键查找 + if (isOnoToOne) + { + var trytbpks = trytb.Primarys.Where(z => z.CsType == tbref.Primarys[a].CsType); //一对一,按类型 + if (trytbpks.Count() == 1) trycol = trytbpks.First(); + else + { + trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, tbref.Primarys[a].CsName, true) == 0); //一对一,按主键名相同 + if (trytbpks.Count() == 1) trycol = trytbpks.First(); + else + { + trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, $"{tbref.CsName}{tbref.Primarys[a].CsName}", true) == 0); //一对一,主键名 = 表+主键名 + if (trytbpks.Count() == 1) trycol = trytbpks.First(); + else + { + trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, $"{tbref.CsName}_{tbref.Primarys[a].CsName}", true) == 0); //一对一,主键名 = 表+_主键名 + if (trytbpks.Count() == 1) trycol = trytbpks.First(); + } + } + } + } + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 没有找到对应的字段,如:{pnv.Name}{findtbrefPkCsName}、{pnv.Name}_{findtbrefPkCsName}。或者使用 [Navigate] 特性指定关系映射。"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } - if (isLazy && nvref.Exception == null) { - if (a > 0) lmbdWhere.Append(" && "); - lmbdWhere.Append("a.").Append(tbref.Primarys[a].CsName).Append(" == this.").Append(trycol.CsName); - } - } - if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) { - nvref.RefEntityType = tbref.Type; - nvref.RefType = isOnoToOne ? TableRefType.OneToOne : TableRefType.ManyToOne; - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - } + nvref.Columns.Add(trycol); + nvref.RefColumns.Add(tbref.Primarys[a]); - if (isLazy) { - cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); - if (vp.Item2) { //get 重写 - cscode.Append(" get {\r\n") - .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); + if (isLazy && nvref.Exception == null) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("a.").Append(tbref.Primarys[a].CsName).Append(" == this.").Append(trycol.CsName); + } + } + if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) + { + nvref.RefEntityType = tbref.Type; + nvref.RefType = isOnoToOne ? TableRefType.OneToOne : TableRefType.ManyToOne; + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + } - if (nvref.Exception == null) - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propTypeName).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToOne();") - .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); - else - cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); - - cscode - .Append(" }\r\n") - .Append(" return base.").Append(pnv.Name).AppendLine(";") - .Append(" }\r\n"); - } - if (vp.Item3) { //set 重写 - cscode.Append(" set {\r\n") - .Append(" base.").Append(pnv.Name).AppendLine(" = value;") - .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;") - .Append(" }\r\n"); - } - cscode.AppendLine(" }"); - } - } + if (isLazy) + { + cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + if (vp.Item2) + { //get 重写 + cscode.Append(" get {\r\n") + .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); - if (isLazy)++overrieds; - } - if (overrieds > 0) { - cscode.AppendLine("}"); - Assembly assembly = null; - if (MethodLazyLoadingComplier.Value == null) throw new Exception("【延时加载】功能需要安装 FreeSql.Extensions.LazyLoading.dll,可前往 nuget 下载"); - try { - assembly = MethodLazyLoadingComplier.Value.Invoke(null, new object[] { cscode.ToString() }) as Assembly; - } catch (Exception ex) { - throw new Exception($"【延时加载】{trytbTypeName} 编译错误:{ex.Message}\r\n\r\n{cscode}"); - } - var type = assembly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault(); - trytb.TypeLazy = type; - trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true); - tbc.AddOrUpdate(type, trytb, (oldkey, oldval) => trytb); - } - #endregion + if (nvref.Exception == null) + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propTypeName).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToOne();") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); + else + cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); - return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb; - } - static Lazy MethodLazyLoadingComplier = new Lazy(() => { - var type = Type.GetType("FreeSql.Extensions.LazyLoading.LazyLoadingComplier,FreeSql.Extensions.LazyLoading"); - return type?.GetMethod("CompileCode"); - }); + cscode + .Append(" }\r\n") + .Append(" return base.").Append(pnv.Name).AppendLine(";") + .Append(" }\r\n"); + } + if (vp.Item3) + { //set 重写 + cscode.Append(" set {\r\n") + .Append(" base.").Append(pnv.Name).AppendLine(" = value;") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;") + .Append(" }\r\n"); + } + cscode.AppendLine(" }"); + } + } - public static T[] GetDbParamtersByObject(string sql, object obj, string paramPrefix, Func constructorParamter) { - if (string.IsNullOrEmpty(sql) || obj == null) return new T[0]; - var ttype = typeof(T); - var type = obj.GetType(); - if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) }; - var ret = new List(); - var ps = type.GetProperties(); - foreach (var p in ps) { - if (sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; - var pvalue = p.GetValue(obj); - if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype)); - else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue)); - } - return ret.ToArray(); - } + if (isLazy) ++overrieds; + } + if (overrieds > 0) + { + cscode.AppendLine("}"); + Assembly assembly = null; + if (MethodLazyLoadingComplier.Value == null) throw new Exception("【延时加载】功能需要安装 FreeSql.Extensions.LazyLoading.dll,可前往 nuget 下载"); + try + { + assembly = MethodLazyLoadingComplier.Value.Invoke(null, new object[] { cscode.ToString() }) as Assembly; + } + catch (Exception ex) + { + throw new Exception($"【延时加载】{trytbTypeName} 编译错误:{ex.Message}\r\n\r\n{cscode}"); + } + var type = assembly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault(); + trytb.TypeLazy = type; + trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true); + tbc.AddOrUpdate(type, trytb, (oldkey, oldval) => trytb); + } + #endregion - public static Dictionary dicExecuteArrayRowReadClassOrTuple = new Dictionary { - [typeof(bool)] = true, - [typeof(sbyte)] = true, - [typeof(short)] = true, - [typeof(int)] = true, - [typeof(long)] = true, - [typeof(byte)] = true, - [typeof(ushort)] = true, - [typeof(uint)] = true, - [typeof(ulong)] = true, - [typeof(double)] = true, - [typeof(float)] = true, - [typeof(decimal)] = true, - [typeof(TimeSpan)] = true, - [typeof(DateTime)] = true, - [typeof(DateTimeOffset)] = true, - [typeof(byte[])] = true, - [typeof(string)] = true, - [typeof(Guid)] = true, - //[typeof(MygisPoint)] = true, - //[typeof(MygisLineString)] = true, - //[typeof(MygisPolygon)] = true, - //[typeof(MygisMultiPoint)] = true, - //[typeof(MygisMultiLineString)] = true, - //[typeof(MygisMultiPolygon)] = true, - //[typeof(BitArray)] = true, - //[typeof(NpgsqlPoint)] = true, - //[typeof(NpgsqlLine)] = true, - //[typeof(NpgsqlLSeg)] = true, - //[typeof(NpgsqlBox)] = true, - //[typeof(NpgsqlPath)] = true, - //[typeof(NpgsqlPolygon)] = true, - //[typeof(NpgsqlCircle)] = true, - //[typeof((IPAddress Address, int Subnet))] = true, - //[typeof(IPAddress)] = true, - //[typeof(PhysicalAddress)] = true, - //[typeof(NpgsqlRange)] = true, - //[typeof(NpgsqlRange)] = true, - //[typeof(NpgsqlRange)] = true, - //[typeof(NpgsqlRange)] = true, - //[typeof(PostgisPoint)] = true, - //[typeof(PostgisLineString)] = true, - //[typeof(PostgisPolygon)] = true, - //[typeof(PostgisMultiPoint)] = true, - //[typeof(PostgisMultiLineString)] = true, - //[typeof(PostgisMultiPolygon)] = true, - //[typeof(PostgisGeometry)] = true, - //[typeof(PostgisGeometryCollection)] = true, - //[typeof(Dictionary)] = true, - //[typeof(JToken)] = true, - //[typeof(JObject)] = true, - //[typeof(JArray)] = true, - }; - internal static ConcurrentDictionary>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary>>(); - internal class RowInfo { - public object Value { get; set; } - public int DataIndex { get; set; } - public RowInfo(object value, int dataIndex) { - this.Value = value; - this.DataIndex = dataIndex; - } - public static ConstructorInfo Constructor = typeof(RowInfo).GetConstructor(new[] { typeof(object), typeof(int) }); - public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value"); - public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex"); - } - internal static MethodInfo MethodDataReaderGetValue = typeof(DbDataReader).GetMethod("GetValue"); - internal static RowInfo ExecuteArrayRowReadClassOrTuple(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) { - if (string.IsNullOrEmpty(flagStr)) flagStr = "all"; - var func = _dicExecuteArrayRowReadClassOrTuple - .GetOrAdd(flagStr, flag => new ConcurrentDictionary>()) - .GetOrAdd(typeOrg, type => { - var returnTarget = Expression.Label(typeof(RowInfo)); - var typeExp = Expression.Parameter(typeof(Type), "type"); - var indexesExp = Expression.Parameter(typeof(int[]), "indexes"); - var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); - var dataIndexExp = Expression.Parameter(typeof(int), "dataIndex"); - var commonUtilExp = Expression.Parameter(typeof(CommonUtils), "commonUtil"); + return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb; + } + static Lazy MethodLazyLoadingComplier = new Lazy(() => + { + var type = Type.GetType("FreeSql.Extensions.LazyLoading.LazyLoadingComplier,FreeSql.Extensions.LazyLoading"); + return type?.GetMethod("CompileCode"); + }); - if (type.IsArray) return Expression.Lambda>( - Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); + public static T[] GetDbParamtersByObject(string sql, object obj, string paramPrefix, Func constructorParamter) + { + if (string.IsNullOrEmpty(sql) || obj == null) return new T[0]; + var ttype = typeof(T); + var type = obj.GetType(); + if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) }; + var ret = new List(); + var ps = type.GetProperties(); + foreach (var p in ps) + { + if (sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; + var pvalue = p.GetValue(obj); + if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype)); + else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue)); + } + return ret.ToArray(); + } - var typeGeneric = type; - if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First(); - if (typeGeneric.IsEnum || - dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric)) - return Expression.Lambda>( - Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); + public static Dictionary dicExecuteArrayRowReadClassOrTuple = new Dictionary + { + [typeof(bool)] = true, + [typeof(sbyte)] = true, + [typeof(short)] = true, + [typeof(int)] = true, + [typeof(long)] = true, + [typeof(byte)] = true, + [typeof(ushort)] = true, + [typeof(uint)] = true, + [typeof(ulong)] = true, + [typeof(double)] = true, + [typeof(float)] = true, + [typeof(decimal)] = true, + [typeof(TimeSpan)] = true, + [typeof(DateTime)] = true, + [typeof(DateTimeOffset)] = true, + [typeof(byte[])] = true, + [typeof(string)] = true, + [typeof(Guid)] = true, + //[typeof(MygisPoint)] = true, + //[typeof(MygisLineString)] = true, + //[typeof(MygisPolygon)] = true, + //[typeof(MygisMultiPoint)] = true, + //[typeof(MygisMultiLineString)] = true, + //[typeof(MygisMultiPolygon)] = true, + //[typeof(BitArray)] = true, + //[typeof(NpgsqlPoint)] = true, + //[typeof(NpgsqlLine)] = true, + //[typeof(NpgsqlLSeg)] = true, + //[typeof(NpgsqlBox)] = true, + //[typeof(NpgsqlPath)] = true, + //[typeof(NpgsqlPolygon)] = true, + //[typeof(NpgsqlCircle)] = true, + //[typeof((IPAddress Address, int Subnet))] = true, + //[typeof(IPAddress)] = true, + //[typeof(PhysicalAddress)] = true, + //[typeof(NpgsqlRange)] = true, + //[typeof(NpgsqlRange)] = true, + //[typeof(NpgsqlRange)] = true, + //[typeof(NpgsqlRange)] = true, + //[typeof(PostgisPoint)] = true, + //[typeof(PostgisLineString)] = true, + //[typeof(PostgisPolygon)] = true, + //[typeof(PostgisMultiPoint)] = true, + //[typeof(PostgisMultiLineString)] = true, + //[typeof(PostgisMultiPolygon)] = true, + //[typeof(PostgisGeometry)] = true, + //[typeof(PostgisGeometryCollection)] = true, + //[typeof(Dictionary)] = true, + //[typeof(JToken)] = true, + //[typeof(JObject)] = true, + //[typeof(JArray)] = true, + }; + internal static ConcurrentDictionary>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary>>(); + internal class RowInfo + { + public object Value { get; set; } + public int DataIndex { get; set; } + public RowInfo(object value, int dataIndex) + { + this.Value = value; + this.DataIndex = dataIndex; + } + public static ConstructorInfo Constructor = typeof(RowInfo).GetConstructor(new[] { typeof(object), typeof(int) }); + public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value"); + public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex"); + } + internal static MethodInfo MethodDataReaderGetValue = typeof(DbDataReader).GetMethod("GetValue"); + internal static RowInfo ExecuteArrayRowReadClassOrTuple(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) + { + if (string.IsNullOrEmpty(flagStr)) flagStr = "all"; + var func = _dicExecuteArrayRowReadClassOrTuple + .GetOrAdd(flagStr, flag => new ConcurrentDictionary>()) + .GetOrAdd(typeOrg, type => + { + var returnTarget = Expression.Label(typeof(RowInfo)); + var typeExp = Expression.Parameter(typeof(Type), "type"); + var indexesExp = Expression.Parameter(typeof(int[]), "indexes"); + var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); + var dataIndexExp = Expression.Parameter(typeof(int), "dataIndex"); + var commonUtilExp = Expression.Parameter(typeof(CommonUtils), "commonUtil"); - if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组 - bool isTuple = type.Name.StartsWith("ValueTuple`"); - if (isTuple) { - var ret2Exp = Expression.Variable(type, "ret"); - var read2Exp = Expression.Variable(typeof(RowInfo), "read"); - var read2ExpValue = Expression.MakeMemberAccess(read2Exp, RowInfo.PropertyValue); - var read2ExpDataIndex = Expression.MakeMemberAccess(read2Exp, RowInfo.PropertyDataIndex); - var block2Exp = new List(); + if (type.IsArray) return Expression.Lambda>( + Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); - var fields = type.GetFields(); - foreach (var field in fields) { - Expression read2ExpAssign = null; //加速缓存 - if (field.FieldType.IsArray) read2ExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ); - else { - var fieldtypeGeneric = field.FieldType; - if (fieldtypeGeneric.IsNullableType()) fieldtypeGeneric = fieldtypeGeneric.GenericTypeArguments.First(); - if (fieldtypeGeneric.IsEnum || - dicExecuteArrayRowReadClassOrTuple.ContainsKey(fieldtypeGeneric)) read2ExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ); - else { - read2ExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(flagStr), Expression.Constant(field.FieldType), indexesExp, rowExp, dataIndexExp, commonUtilExp }); - } - } - block2Exp.AddRange(new Expression[] { + var typeGeneric = type; + if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First(); + if (typeGeneric.IsEnum || + dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric)) + return Expression.Lambda>( + Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); + + if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) + { //值类型,或者元组 + bool isTuple = type.Name.StartsWith("ValueTuple`"); + if (isTuple) + { + var ret2Exp = Expression.Variable(type, "ret"); + var read2Exp = Expression.Variable(typeof(RowInfo), "read"); + var read2ExpValue = Expression.MakeMemberAccess(read2Exp, RowInfo.PropertyValue); + var read2ExpDataIndex = Expression.MakeMemberAccess(read2Exp, RowInfo.PropertyDataIndex); + var block2Exp = new List(); + + var fields = type.GetFields(); + foreach (var field in fields) + { + Expression read2ExpAssign = null; //加速缓存 + if (field.FieldType.IsArray) read2ExpAssign = Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else + { + var fieldtypeGeneric = field.FieldType; + if (fieldtypeGeneric.IsNullableType()) fieldtypeGeneric = fieldtypeGeneric.GenericTypeArguments.First(); + if (fieldtypeGeneric.IsEnum || + dicExecuteArrayRowReadClassOrTuple.ContainsKey(fieldtypeGeneric)) read2ExpAssign = Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else + { + read2ExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(flagStr), Expression.Constant(field.FieldType), indexesExp, rowExp, dataIndexExp, commonUtilExp }); + } + } + block2Exp.AddRange(new Expression[] { //Expression.TryCatch(Expression.Block( // typeof(void), Expression.Assign(read2Exp, read2ExpAssign), - Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, read2ExpDataIndex)), - Expression.IfThenElse(Expression.Equal(read2ExpValue, Expression.Constant(null)), - Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Default(field.FieldType)), - Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType))) + Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, read2ExpDataIndex)), + Expression.IfThenElse(Expression.Equal(read2ExpValue, Expression.Constant(null)), + Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Default(field.FieldType)), + Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType))) //), //Expression.Catch(typeof(Exception), Expression.Block( // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(0)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 0)))), @@ -878,636 +1006,666 @@ namespace FreeSql.Internal { // ) //)) }); - } - block2Exp.AddRange(new Expression[] { - Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)), - Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) - }); - return Expression.Lambda>( - Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); - } - var rowLenExp = Expression.ArrayLength(rowExp); - return Expression.Lambda>( - Expression.Block( - Expression.IfThen( - Expression.LessThan(dataIndexExp, rowLenExp), - Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)))) - ), - Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) - ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); - } + } + block2Exp.AddRange(new Expression[] { + Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)), + Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) + }); + return Expression.Lambda>( + Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); + } + var rowLenExp = Expression.ArrayLength(rowExp); + return Expression.Lambda>( + Expression.Block( + Expression.IfThen( + Expression.LessThan(dataIndexExp, rowLenExp), + Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)))) + ), + Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) + ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); + } - if (type == typeof(object) && indexes != null) { - Func dynamicFunc = (type2, indexes2, row2, dataindex2, commonUtils2) => { - //dynamic expando = new DynamicDictionary(); //动态类型字段 可读可写 - var expandodic = new Dictionary();// (IDictionary)expando; - var fc = row2.FieldCount; - for (var a = 0; a < fc; a++) - //expando[row2.GetName(a)] = row2.GetValue(a); - expandodic.Add(row2.GetName(a), row2.GetValue(a)); - //expando = expandodic; - return new RowInfo(expandodic, fc); - }; - return dynamicFunc;// Expression.Lambda>(null); - } + if (type == typeof(object) && indexes != null) + { + Func dynamicFunc = (type2, indexes2, row2, dataindex2, commonUtils2) => + { + //dynamic expando = new DynamicDictionary(); //动态类型字段 可读可写 + var expandodic = new Dictionary();// (IDictionary)expando; + var fc = row2.FieldCount; + for (var a = 0; a < fc; a++) + //expando[row2.GetName(a)] = row2.GetValue(a); + expandodic.Add(row2.GetName(a), row2.GetValue(a)); + //expando = expandodic; + return new RowInfo(expandodic, fc); + }; + return dynamicFunc;// Expression.Lambda>(null); + } - //类注入属性 - var typetb = GetTableByEntity(type, _commonUtils); - var retExp = Expression.Variable(type, "ret"); - var readExp = Expression.Variable(typeof(RowInfo), "read"); - var readExpValue = Expression.MakeMemberAccess(readExp, RowInfo.PropertyValue); - var readExpDataIndex = Expression.MakeMemberAccess(readExp, RowInfo.PropertyDataIndex); - var readExpValueParms = new List(); - var readExpsIndex = Expression.Variable(typeof(int), "readsIndex"); - var tryidxExp = Expression.Variable(typeof(int), "tryidx"); - var readpknullExp = Expression.Variable(typeof(bool), "isnull2"); - var readpkvalExp = Expression.Variable(typeof(object), "isnull3val"); - var indexesLengthExp = Expression.Variable(typeof(int), "indexesLength"); - var blockExp = new List(); - var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); - var ctorParms = ctor.GetParameters(); - if (ctorParms.Length > 0) { - blockExp.AddRange(new Expression[] { - Expression.Assign(readpknullExp, Expression.Constant(false)) - }); - foreach (var ctorParm in ctorParms) { - if (typetb.ColumnsByCsIgnore.ContainsKey(ctorParm.Name)) continue; - var readType = typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) ? trycol.Attribute.MapType : ctorParm.ParameterType; + //类注入属性 + var typetb = GetTableByEntity(type, _commonUtils); + var retExp = Expression.Variable(type, "ret"); + var readExp = Expression.Variable(typeof(RowInfo), "read"); + var readExpValue = Expression.MakeMemberAccess(readExp, RowInfo.PropertyValue); + var readExpDataIndex = Expression.MakeMemberAccess(readExp, RowInfo.PropertyDataIndex); + var readExpValueParms = new List(); + var readExpsIndex = Expression.Variable(typeof(int), "readsIndex"); + var tryidxExp = Expression.Variable(typeof(int), "tryidx"); + var readpknullExp = Expression.Variable(typeof(bool), "isnull2"); + var readpkvalExp = Expression.Variable(typeof(object), "isnull3val"); + var indexesLengthExp = Expression.Variable(typeof(int), "indexesLength"); + var blockExp = new List(); + var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); + var ctorParms = ctor.GetParameters(); + if (ctorParms.Length > 0) + { + blockExp.AddRange(new Expression[] { + Expression.Assign(readpknullExp, Expression.Constant(false)) + }); + foreach (var ctorParm in ctorParms) + { + if (typetb.ColumnsByCsIgnore.ContainsKey(ctorParm.Name)) continue; + var readType = typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) ? trycol.Attribute.MapType : ctorParm.ParameterType; - var ispkExp = new List(); - Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)); - Expression readExpAssign = null; //加速缓存 - if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(readType, readpkvalExp), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ); - else { - var proptypeGeneric = readType; - if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); - if (proptypeGeneric.IsEnum || - dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) { + var ispkExp = new List(); + Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)); + Expression readExpAssign = null; //加速缓存 + if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(readType, readpkvalExp), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else + { + var proptypeGeneric = readType; + if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsEnum || + dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) + { - //判断主键为空,则整个对象不读取 - //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp))); - if (trycol?.Attribute.IsPrimary == true) { - ispkExp.Add( - Expression.IfThen( - Expression.AndAlso( - Expression.IsFalse(readpknullExp), - Expression.Or( - Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), - Expression.Equal(readpkvalExp, Expression.Constant(null)) - ) - ), - Expression.Assign(readpknullExp, Expression.Constant(true)) - ) - ); - } + //判断主键为空,则整个对象不读取 + //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp))); + if (trycol?.Attribute.IsPrimary == true) + { + ispkExp.Add( + Expression.IfThen( + Expression.AndAlso( + Expression.IsFalse(readpknullExp), + Expression.Or( + Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), + Expression.Equal(readpkvalExp, Expression.Constant(null)) + ) + ), + Expression.Assign(readpknullExp, Expression.Constant(true)) + ) + ); + } - readExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(readType, readpkvalExp), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ); - } else { - readExpAssign = Expression.New(RowInfo.Constructor, - Expression.MakeMemberAccess(Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(flagStr), Expression.Constant(readType), indexesExp, rowExp, dataIndexExp, commonUtilExp }), RowInfo.PropertyValue), - Expression.Add(dataIndexExp, Expression.Constant(1))); - } - } - var varctorParm = Expression.Variable(ctorParm.ParameterType, $"ctorParm{ctorParm.Name}"); - readExpValueParms.Add(varctorParm); + readExpAssign = Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(readType, readpkvalExp), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + } + else + { + readExpAssign = Expression.New(RowInfo.Constructor, + Expression.MakeMemberAccess(Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(flagStr), Expression.Constant(readType), indexesExp, rowExp, dataIndexExp, commonUtilExp }), RowInfo.PropertyValue), + Expression.Add(dataIndexExp, Expression.Constant(1))); + } + } + var varctorParm = Expression.Variable(ctorParm.ParameterType, $"ctorParm{ctorParm.Name}"); + readExpValueParms.Add(varctorParm); - if (trycol != null && trycol.Attribute.MapType != ctorParm.ParameterType) - ispkExp.Add(Expression.Assign(readExpValue, GetDataReaderValueBlockExpression(ctorParm.ParameterType, readExpValue))); + if (trycol != null && trycol.Attribute.MapType != ctorParm.ParameterType) + ispkExp.Add(Expression.Assign(readExpValue, GetDataReaderValueBlockExpression(ctorParm.ParameterType, readExpValue))); - ispkExp.Add( - Expression.IfThen( - Expression.IsFalse(readpknullExp), - Expression.IfThenElse( - Expression.Equal(readExpValue, Expression.Constant(null)), - Expression.Assign(varctorParm, Expression.Default(ctorParm.ParameterType)), - Expression.Assign(varctorParm, Expression.Convert(readExpValue, ctorParm.ParameterType)) - ) - ) - ); + ispkExp.Add( + Expression.IfThen( + Expression.IsFalse(readpknullExp), + Expression.IfThenElse( + Expression.Equal(readExpValue, Expression.Constant(null)), + Expression.Assign(varctorParm, Expression.Default(ctorParm.ParameterType)), + Expression.Assign(varctorParm, Expression.Convert(readExpValue, ctorParm.ParameterType)) + ) + ) + ); - blockExp.AddRange(new Expression[] { - Expression.Assign(tryidxExp, dataIndexExp), - readVal, - Expression.Assign(readExp, readExpAssign), - Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex) - ), - Expression.Block(ispkExp) - }); - } - blockExp.Add( - Expression.IfThen( - Expression.IsFalse(readpknullExp), - Expression.Assign(retExp, Expression.New(ctor, readExpValueParms)) - ) - ); - } else { - blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, Expression.New(ctor)), - Expression.Assign(indexesLengthExp, Expression.Constant(0)), - Expression.IfThen( - Expression.NotEqual(indexesExp, Expression.Constant(null)), - Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp)) - ), - Expression.Assign(readpknullExp, Expression.Constant(false)) - }); - - var props = type.GetProperties();//.ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); - var propIndex = 0; - foreach (var prop in props) { - if (typetb.ColumnsByCsIgnore.ContainsKey(prop.Name)) { - ++propIndex; - continue; - } - var readType = typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) ? trycol.Attribute.MapType : prop.PropertyType; + blockExp.AddRange(new Expression[] { + Expression.Assign(tryidxExp, dataIndexExp), + readVal, + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex) + ), + Expression.Block(ispkExp) + }); + } + blockExp.Add( + Expression.IfThen( + Expression.IsFalse(readpknullExp), + Expression.Assign(retExp, Expression.New(ctor, readExpValueParms)) + ) + ); + } + else + { + blockExp.AddRange(new Expression[] { + Expression.Assign(retExp, Expression.New(ctor)), + Expression.Assign(indexesLengthExp, Expression.Constant(0)), + Expression.IfThen( + Expression.NotEqual(indexesExp, Expression.Constant(null)), + Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp)) + ), + Expression.Assign(readpknullExp, Expression.Constant(false)) + }); - var ispkExp = new List(); - var propGetSetMethod = prop.GetSetMethod(); - Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp)); - Expression readExpAssign = null; //加速缓存 - if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(readType, readpkvalExp), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }), - Expression.Add(tryidxExp, Expression.Constant(1)) - ); - else { - var proptypeGeneric = readType; - if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); - if (proptypeGeneric.IsEnum || - dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) { + var props = type.GetProperties();//.ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); + var propIndex = 0; + foreach (var prop in props) + { + if (typetb.ColumnsByCsIgnore.ContainsKey(prop.Name)) + { + ++propIndex; + continue; + } + var readType = typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) ? trycol.Attribute.MapType : prop.PropertyType; - //判断主键为空,则整个对象不读取 - //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp))); - if (trycol?.Attribute.IsPrimary == true) { - ispkExp.Add( - Expression.IfThen( - Expression.AndAlso( - Expression.IsFalse(readpknullExp), - Expression.Or( - Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), - Expression.Equal(readpkvalExp, Expression.Constant(null)) - ) - ), - Expression.Block( - Expression.Assign(readpknullExp, Expression.Constant(true)), - Expression.Assign(retExp, Expression.Constant(null, type)) - ) - ) - ); - } + var ispkExp = new List(); + var propGetSetMethod = prop.GetSetMethod(); + Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp)); + Expression readExpAssign = null; //加速缓存 + if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(readType, readpkvalExp), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }), + Expression.Add(tryidxExp, Expression.Constant(1)) + ); + else + { + var proptypeGeneric = readType; + if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsEnum || + dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) + { - readExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(readType, readpkvalExp), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }), - Expression.Add(tryidxExp, Expression.Constant(1)) - ); - } else { - ++propIndex; - continue; - //readExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(flagStr), Expression.Constant(readType), indexesExp, rowExp, tryidxExp }); - } - } + //判断主键为空,则整个对象不读取 + //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp))); + if (trycol?.Attribute.IsPrimary == true) + { + ispkExp.Add( + Expression.IfThen( + Expression.AndAlso( + Expression.IsFalse(readpknullExp), + Expression.Or( + Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), + Expression.Equal(readpkvalExp, Expression.Constant(null)) + ) + ), + Expression.Block( + Expression.Assign(readpknullExp, Expression.Constant(true)), + Expression.Assign(retExp, Expression.Constant(null, type)) + ) + ) + ); + } - if (trycol != null && trycol.Attribute.MapType != prop.PropertyType) - ispkExp.Add(Expression.Assign(readExpValue, GetDataReaderValueBlockExpression(prop.PropertyType, readExpValue))); + readExpAssign = Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(readType, readpkvalExp), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }), + Expression.Add(tryidxExp, Expression.Constant(1)) + ); + } + else + { + ++propIndex; + continue; + //readExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(flagStr), Expression.Constant(readType), indexesExp, rowExp, tryidxExp }); + } + } - ispkExp.Add( - Expression.IfThen( - Expression.IsFalse(readpknullExp), - Expression.IfThenElse( - Expression.Equal(readExpValue, Expression.Constant(null)), - Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)) - ) - ) - ); - blockExp.AddRange(new Expression[] { + if (trycol != null && trycol.Attribute.MapType != prop.PropertyType) + ispkExp.Add(Expression.Assign(readExpValue, GetDataReaderValueBlockExpression(prop.PropertyType, readExpValue))); + + ispkExp.Add( + Expression.IfThen( + Expression.IsFalse(readpknullExp), + Expression.IfThenElse( + Expression.Equal(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)) + ) + ) + ); + blockExp.AddRange(new Expression[] { //以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值 Expression.IfThenElse( - Expression.LessThan(Expression.Constant(propIndex), indexesLengthExp), - Expression.Assign(tryidxExp, Expression.ArrayAccess(indexesExp, Expression.Constant(propIndex))), - Expression.Assign(tryidxExp, dataIndexExp) - ), - Expression.IfThen( - Expression.GreaterThanOrEqual(tryidxExp, Expression.Constant(0)), - Expression.Block( - readVal, - Expression.Assign(readExp, readExpAssign), - Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex)), - Expression.Block(ispkExp) - ) - ) - }); - ++propIndex; - } - } - blockExp.AddRange(new Expression[] { - Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)), - Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) - }); - return Expression.Lambda>( - Expression.Block(new[] { retExp, readExp, tryidxExp, readpknullExp, readpkvalExp, readExpsIndex, indexesLengthExp }.Concat(readExpValueParms), blockExp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); - }); - return func(typeOrg, indexes, row, dataIndex, _commonUtils); - } + Expression.LessThan(Expression.Constant(propIndex), indexesLengthExp), + Expression.Assign(tryidxExp, Expression.ArrayAccess(indexesExp, Expression.Constant(propIndex))), + Expression.Assign(tryidxExp, dataIndexExp) + ), + Expression.IfThen( + Expression.GreaterThanOrEqual(tryidxExp, Expression.Constant(0)), + Expression.Block( + readVal, + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex)), + Expression.Block(ispkExp) + ) + ) + }); + ++propIndex; + } + } + blockExp.AddRange(new Expression[] { + Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)), + Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) + }); + return Expression.Lambda>( + Expression.Block(new[] { retExp, readExp, tryidxExp, readpknullExp, readpkvalExp, readExpsIndex, indexesLengthExp }.Concat(readExpValueParms), blockExp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); + }); + return func(typeOrg, indexes, row, dataIndex, _commonUtils); + } - internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic); - internal static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.NonPublic); + internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic); + internal static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.NonPublic); - static ConcurrentDictionary> _dicFillPropertyValue = new ConcurrentDictionary>(); - internal static void FillPropertyValue(object info, string memberAccessPath, object value) { - var typeObj = info.GetType(); - var typeValue = value.GetType(); - var key = "FillPropertyValue_" + typeObj.FullName + "_" + typeValue.FullName; - var act = _dicFillPropertyValue.GetOrAdd($"{key}.{memberAccessPath}", s => { - var parmInfo = Expression.Parameter(typeof(object), "info"); - var parmValue = Expression.Parameter(typeof(object), "value"); - Expression exp = Expression.Convert(parmInfo, typeObj); - foreach (var pro in memberAccessPath.Split('.')) - exp = Expression.PropertyOrField(exp, pro) ?? throw new Exception(string.Concat(exp.Type.FullName, " 没有定义属性 ", pro)); + static ConcurrentDictionary> _dicFillPropertyValue = new ConcurrentDictionary>(); + internal static void FillPropertyValue(object info, string memberAccessPath, object value) + { + var typeObj = info.GetType(); + var typeValue = value.GetType(); + var key = "FillPropertyValue_" + typeObj.FullName + "_" + typeValue.FullName; + var act = _dicFillPropertyValue.GetOrAdd($"{key}.{memberAccessPath}", s => + { + var parmInfo = Expression.Parameter(typeof(object), "info"); + var parmValue = Expression.Parameter(typeof(object), "value"); + Expression exp = Expression.Convert(parmInfo, typeObj); + foreach (var pro in memberAccessPath.Split('.')) + exp = Expression.PropertyOrField(exp, pro) ?? throw new Exception(string.Concat(exp.Type.FullName, " 没有定义属性 ", pro)); - var value2 = Expression.Call(MethodGetDataReaderValue, Expression.Constant(exp.Type), parmValue); - var value3 = Expression.Convert(parmValue, typeValue); - exp = Expression.Assign(exp, value3); - return Expression.Lambda>(exp, parmInfo, parmValue).Compile(); - }); - act(info, value); - } + var value2 = Expression.Call(MethodGetDataReaderValue, Expression.Constant(exp.Type), parmValue); + var value3 = Expression.Convert(parmValue, typeValue); + exp = Expression.Assign(exp, value3); + return Expression.Lambda>(exp, parmInfo, parmValue).Compile(); + }); + act(info, value); + } - static BigInteger ToBigInteger(string that) { - if (string.IsNullOrEmpty(that)) return 0; - if (BigInteger.TryParse(that, System.Globalization.NumberStyles.Any, null, out var trybigint)) return trybigint; - return 0; - } - static string ToStringConcat(object obj) { - if (obj == null) return null; - return string.Concat(obj); - } + static BigInteger ToBigInteger(string that) + { + if (string.IsNullOrEmpty(that)) return 0; + if (BigInteger.TryParse(that, System.Globalization.NumberStyles.Any, null, out var trybigint)) return trybigint; + return 0; + } + static string ToStringConcat(object obj) + { + if (obj == null) return null; + return string.Concat(obj); + } - static ConcurrentDictionary>> _dicGetDataReaderValue = new ConcurrentDictionary>>(); - static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) }); - static MethodInfo MethodArrayGetLength = typeof(Array).GetMethod("GetLength", new[] { typeof(int) }); - static MethodInfo MethodGuidTryParse = typeof(Guid).GetMethod("TryParse", new[] { typeof(string), typeof(Guid).MakeByRefType() }); - static MethodInfo MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) }); - static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) }); - static MethodInfo MethodTimeSpanFromSeconds = typeof(TimeSpan).GetMethod("FromSeconds"); - static MethodInfo MethodSByteTryParse = typeof(sbyte).GetMethod("TryParse", new[] { typeof(string), typeof(sbyte).MakeByRefType() }); - static MethodInfo MethodShortTryParse = typeof(short).GetMethod("TryParse", new[] { typeof(string), typeof(short).MakeByRefType() }); - static MethodInfo MethodIntTryParse = typeof(int).GetMethod("TryParse", new[] { typeof(string), typeof(int).MakeByRefType() }); - static MethodInfo MethodLongTryParse = typeof(long).GetMethod("TryParse", new[] { typeof(string), typeof(long).MakeByRefType() }); - static MethodInfo MethodByteTryParse = typeof(byte).GetMethod("TryParse", new[] { typeof(string), typeof(byte).MakeByRefType() }); - static MethodInfo MethodUShortTryParse = typeof(ushort).GetMethod("TryParse", new[] { typeof(string), typeof(ushort).MakeByRefType() }); - static MethodInfo MethodUIntTryParse = typeof(uint).GetMethod("TryParse", new[] { typeof(string), typeof(uint).MakeByRefType() }); - static MethodInfo MethodULongTryParse = typeof(ulong).GetMethod("TryParse", new[] { typeof(string), typeof(ulong).MakeByRefType() }); - static MethodInfo MethodDoubleTryParse = typeof(double).GetMethod("TryParse", new[] { typeof(string), typeof(double).MakeByRefType() }); - static MethodInfo MethodFloatTryParse = typeof(float).GetMethod("TryParse", new[] { typeof(string), typeof(float).MakeByRefType() }); - static MethodInfo MethodDecimalTryParse = typeof(decimal).GetMethod("TryParse", new[] { typeof(string), typeof(decimal).MakeByRefType() }); - static MethodInfo MethodTimeSpanTryParse = typeof(TimeSpan).GetMethod("TryParse", new[] { typeof(string), typeof(TimeSpan).MakeByRefType() }); - static MethodInfo MethodDateTimeTryParse = typeof(DateTime).GetMethod("TryParse", new[] { typeof(string), typeof(DateTime).MakeByRefType() }); - static MethodInfo MethodDateTimeOffsetTryParse = typeof(DateTimeOffset).GetMethod("TryParse", new[] { typeof(string), typeof(DateTimeOffset).MakeByRefType() }); - static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null); - static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); + static ConcurrentDictionary>> _dicGetDataReaderValue = new ConcurrentDictionary>>(); + static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) }); + static MethodInfo MethodArrayGetLength = typeof(Array).GetMethod("GetLength", new[] { typeof(int) }); + static MethodInfo MethodGuidTryParse = typeof(Guid).GetMethod("TryParse", new[] { typeof(string), typeof(Guid).MakeByRefType() }); + static MethodInfo MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) }); + static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) }); + static MethodInfo MethodTimeSpanFromSeconds = typeof(TimeSpan).GetMethod("FromSeconds"); + static MethodInfo MethodSByteTryParse = typeof(sbyte).GetMethod("TryParse", new[] { typeof(string), typeof(sbyte).MakeByRefType() }); + static MethodInfo MethodShortTryParse = typeof(short).GetMethod("TryParse", new[] { typeof(string), typeof(short).MakeByRefType() }); + static MethodInfo MethodIntTryParse = typeof(int).GetMethod("TryParse", new[] { typeof(string), typeof(int).MakeByRefType() }); + static MethodInfo MethodLongTryParse = typeof(long).GetMethod("TryParse", new[] { typeof(string), typeof(long).MakeByRefType() }); + static MethodInfo MethodByteTryParse = typeof(byte).GetMethod("TryParse", new[] { typeof(string), typeof(byte).MakeByRefType() }); + static MethodInfo MethodUShortTryParse = typeof(ushort).GetMethod("TryParse", new[] { typeof(string), typeof(ushort).MakeByRefType() }); + static MethodInfo MethodUIntTryParse = typeof(uint).GetMethod("TryParse", new[] { typeof(string), typeof(uint).MakeByRefType() }); + static MethodInfo MethodULongTryParse = typeof(ulong).GetMethod("TryParse", new[] { typeof(string), typeof(ulong).MakeByRefType() }); + static MethodInfo MethodDoubleTryParse = typeof(double).GetMethod("TryParse", new[] { typeof(string), typeof(double).MakeByRefType() }); + static MethodInfo MethodFloatTryParse = typeof(float).GetMethod("TryParse", new[] { typeof(string), typeof(float).MakeByRefType() }); + static MethodInfo MethodDecimalTryParse = typeof(decimal).GetMethod("TryParse", new[] { typeof(string), typeof(decimal).MakeByRefType() }); + static MethodInfo MethodTimeSpanTryParse = typeof(TimeSpan).GetMethod("TryParse", new[] { typeof(string), typeof(TimeSpan).MakeByRefType() }); + static MethodInfo MethodDateTimeTryParse = typeof(DateTime).GetMethod("TryParse", new[] { typeof(string), typeof(DateTime).MakeByRefType() }); + static MethodInfo MethodDateTimeOffsetTryParse = typeof(DateTimeOffset).GetMethod("TryParse", new[] { typeof(string), typeof(DateTimeOffset).MakeByRefType() }); + static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null); + static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); - public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); - public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) { - var returnTarget = Expression.Label(typeof(object)); - var valueExp = Expression.Variable(typeof(object), "locvalue"); - Func funcGetExpression = () => { - if (type.FullName == "System.Byte[]") return Expression.Return(returnTarget, valueExp); - if (type.IsArray) { - var elementType = type.GetElementType(); - var arrNewExp = Expression.Variable(type, "arrNew"); - var arrExp = Expression.Variable(typeof(Array), "arr"); - var arrLenExp = Expression.Variable(typeof(int), "arrLen"); - var arrXExp = Expression.Variable(typeof(int), "arrX"); - var arrReadValExp = Expression.Variable(typeof(object), "arrReadVal"); - var label = Expression.Label(typeof(int)); - return Expression.IfThenElse( - Expression.TypeEqual(valueExp, type), - Expression.Return(returnTarget, valueExp), - Expression.Block( - new[] { arrNewExp, arrExp, arrLenExp, arrXExp, arrReadValExp }, - Expression.Assign(arrExp, Expression.TypeAs(valueExp, typeof(Array))), - Expression.Assign(arrLenExp, Expression.Call(arrExp, MethodArrayGetLength, Expression.Constant(0))), - Expression.Assign(arrXExp, Expression.Constant(0)), - Expression.Assign(arrNewExp, Expression.NewArrayBounds(elementType, arrLenExp)), - Expression.Loop( - Expression.IfThenElse( - Expression.LessThan(arrXExp, arrLenExp), - Expression.Block( - Expression.Assign(arrReadValExp, GetDataReaderValueBlockExpression(elementType, Expression.Call(arrExp, MethodArrayGetValue, arrXExp))), - Expression.IfThenElse( - Expression.Equal(arrReadValExp, Expression.Constant(null)), - Expression.Assign(Expression.ArrayAccess(arrNewExp, arrXExp), Expression.Default(elementType)), - Expression.Assign(Expression.ArrayAccess(arrNewExp, arrXExp), Expression.Convert(arrReadValExp, elementType)) - ), - Expression.PostIncrementAssign(arrXExp) - ), - Expression.Break(label, arrXExp) - ), - label - ), - Expression.Return(returnTarget, arrNewExp) - ) - ); - } - var typeOrg = type; - if (type.IsNullableType()) type = type.GenericTypeArguments.First(); - if (type.IsEnum) - return Expression.Block( - Expression.IfThenElse( - Expression.Equal(Expression.TypeAs(valueExp, typeof(string)), Expression.Constant(string.Empty)), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(type), typeof(object))), - Expression.Return(returnTarget, Expression.Call(MethodEnumParse, Expression.Constant(type, typeof(Type)), Expression.Call(MethodToString, valueExp), Expression.Constant(true, typeof(bool)))) - ) - ); - Expression tryparseExp = null; - Expression tryparseBooleanExp = null; - ParameterExpression tryparseVarExp = null; - switch (type.FullName) { - case "System.Guid": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(Guid)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodGuidTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Numerics.BigInteger": return Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodBigIntegerParse, Expression.Call(MethodToString, valueExp)), typeof(object))); - case "System.TimeSpan": - ParameterExpression tryparseVarTsExp, valueStrExp; - return Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(double)), tryparseVarTsExp = Expression.Variable(typeof(TimeSpan)), valueStrExp = Expression.Variable(typeof(string)) }, - new Expression[] { - Expression.Assign(valueStrExp, Expression.Call(MethodToString, valueExp)), - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodDoubleTryParse, valueStrExp, tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodTimeSpanFromSeconds, tryparseVarExp), typeof(object))), - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodTimeSpanTryParse, valueStrExp, tryparseVarTsExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarTsExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - ) - } - ); - case "System.SByte": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(sbyte)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodSByteTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Int16": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(short)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodShortTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Int32": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(int)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodIntTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Int64": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(long)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodLongTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Byte": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(byte)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodByteTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.UInt16": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(ushort)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodUShortTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.UInt32": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(uint)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodUIntTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.UInt64": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(ulong)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodULongTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Single": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(float)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodFloatTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Double": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(double)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodDoubleTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Decimal": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(decimal)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodDecimalTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.DateTime": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(DateTime)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodDateTimeTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.DateTimeOffset": - tryparseExp = Expression.Block( - new[] { tryparseVarExp = Expression.Variable(typeof(DateTimeOffset)) }, - new Expression[] { - Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodDateTimeOffsetTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), - Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) - ) - } - ); - break; - case "System.Boolean": - tryparseBooleanExp = Expression.Return(returnTarget, - Expression.Convert( - Expression.Not( - Expression.Or( - Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("False")), - Expression.Or( - Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("false")), - Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("0"))))), - typeof(object)) - ); - break; - default: - foreach (var switchFunc in GetDataReaderValueBlockExpressionSwitchTypeFullName) { - var switchFuncRet = switchFunc(returnTarget, valueExp, type.FullName); - if (switchFuncRet != null) return switchFuncRet; - } - break; - } - Expression switchExp = null; - if (tryparseExp != null) - switchExp = Expression.Switch( - Expression.Constant(type), - Expression.SwitchCase(tryparseExp, - Expression.Constant(typeof(Guid)), - Expression.Constant(typeof(sbyte)), Expression.Constant(typeof(short)), Expression.Constant(typeof(int)), Expression.Constant(typeof(long)), - Expression.Constant(typeof(byte)), Expression.Constant(typeof(ushort)), Expression.Constant(typeof(uint)), Expression.Constant(typeof(ulong)), - Expression.Constant(typeof(double)), Expression.Constant(typeof(float)), Expression.Constant(typeof(decimal)), - Expression.Constant(typeof(DateTime)), Expression.Constant(typeof(DateTimeOffset)) - ), - Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type)) - ); - else if (tryparseBooleanExp != null) - switchExp = Expression.Switch( - Expression.Constant(type), - Expression.SwitchCase(tryparseBooleanExp, Expression.Constant(typeof(bool))), - Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type)) - ); - else if (type == typeof(string)) - switchExp = Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))); - else - switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); + public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); + public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) + { + var returnTarget = Expression.Label(typeof(object)); + var valueExp = Expression.Variable(typeof(object), "locvalue"); + Func funcGetExpression = () => + { + if (type.FullName == "System.Byte[]") return Expression.Return(returnTarget, valueExp); + if (type.IsArray) + { + var elementType = type.GetElementType(); + var arrNewExp = Expression.Variable(type, "arrNew"); + var arrExp = Expression.Variable(typeof(Array), "arr"); + var arrLenExp = Expression.Variable(typeof(int), "arrLen"); + var arrXExp = Expression.Variable(typeof(int), "arrX"); + var arrReadValExp = Expression.Variable(typeof(object), "arrReadVal"); + var label = Expression.Label(typeof(int)); + return Expression.IfThenElse( + Expression.TypeEqual(valueExp, type), + Expression.Return(returnTarget, valueExp), + Expression.Block( + new[] { arrNewExp, arrExp, arrLenExp, arrXExp, arrReadValExp }, + Expression.Assign(arrExp, Expression.TypeAs(valueExp, typeof(Array))), + Expression.Assign(arrLenExp, Expression.Call(arrExp, MethodArrayGetLength, Expression.Constant(0))), + Expression.Assign(arrXExp, Expression.Constant(0)), + Expression.Assign(arrNewExp, Expression.NewArrayBounds(elementType, arrLenExp)), + Expression.Loop( + Expression.IfThenElse( + Expression.LessThan(arrXExp, arrLenExp), + Expression.Block( + Expression.Assign(arrReadValExp, GetDataReaderValueBlockExpression(elementType, Expression.Call(arrExp, MethodArrayGetValue, arrXExp))), + Expression.IfThenElse( + Expression.Equal(arrReadValExp, Expression.Constant(null)), + Expression.Assign(Expression.ArrayAccess(arrNewExp, arrXExp), Expression.Default(elementType)), + Expression.Assign(Expression.ArrayAccess(arrNewExp, arrXExp), Expression.Convert(arrReadValExp, elementType)) + ), + Expression.PostIncrementAssign(arrXExp) + ), + Expression.Break(label, arrXExp) + ), + label + ), + Expression.Return(returnTarget, arrNewExp) + ) + ); + } + var typeOrg = type; + if (type.IsNullableType()) type = type.GenericTypeArguments.First(); + if (type.IsEnum) + return Expression.Block( + Expression.IfThenElse( + Expression.Equal(Expression.TypeAs(valueExp, typeof(string)), Expression.Constant(string.Empty)), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(type), typeof(object))), + Expression.Return(returnTarget, Expression.Call(MethodEnumParse, Expression.Constant(type, typeof(Type)), Expression.Call(MethodToString, valueExp), Expression.Constant(true, typeof(bool)))) + ) + ); + Expression tryparseExp = null; + Expression tryparseBooleanExp = null; + ParameterExpression tryparseVarExp = null; + switch (type.FullName) + { + case "System.Guid": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(Guid)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodGuidTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Numerics.BigInteger": return Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodBigIntegerParse, Expression.Call(MethodToString, valueExp)), typeof(object))); + case "System.TimeSpan": + ParameterExpression tryparseVarTsExp, valueStrExp; + return Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(double)), tryparseVarTsExp = Expression.Variable(typeof(TimeSpan)), valueStrExp = Expression.Variable(typeof(string)) }, + new Expression[] { + Expression.Assign(valueStrExp, Expression.Call(MethodToString, valueExp)), + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodDoubleTryParse, valueStrExp, tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodTimeSpanFromSeconds, tryparseVarExp), typeof(object))), + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodTimeSpanTryParse, valueStrExp, tryparseVarTsExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarTsExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + ) + } + ); + case "System.SByte": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(sbyte)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodSByteTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Int16": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(short)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodShortTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Int32": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(int)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodIntTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Int64": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(long)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodLongTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Byte": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(byte)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodByteTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.UInt16": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(ushort)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodUShortTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.UInt32": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(uint)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodUIntTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.UInt64": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(ulong)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodULongTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Single": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(float)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodFloatTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Double": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(double)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodDoubleTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Decimal": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(decimal)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodDecimalTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.DateTime": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(DateTime)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodDateTimeTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.DateTimeOffset": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(DateTimeOffset)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodDateTimeOffsetTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.Boolean": + tryparseBooleanExp = Expression.Return(returnTarget, + Expression.Convert( + Expression.Not( + Expression.Or( + Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("False")), + Expression.Or( + Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("false")), + Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("0"))))), + typeof(object)) + ); + break; + default: + foreach (var switchFunc in GetDataReaderValueBlockExpressionSwitchTypeFullName) + { + var switchFuncRet = switchFunc(returnTarget, valueExp, type.FullName); + if (switchFuncRet != null) return switchFuncRet; + } + break; + } + Expression switchExp = null; + if (tryparseExp != null) + switchExp = Expression.Switch( + Expression.Constant(type), + Expression.SwitchCase(tryparseExp, + Expression.Constant(typeof(Guid)), + Expression.Constant(typeof(sbyte)), Expression.Constant(typeof(short)), Expression.Constant(typeof(int)), Expression.Constant(typeof(long)), + Expression.Constant(typeof(byte)), Expression.Constant(typeof(ushort)), Expression.Constant(typeof(uint)), Expression.Constant(typeof(ulong)), + Expression.Constant(typeof(double)), Expression.Constant(typeof(float)), Expression.Constant(typeof(decimal)), + Expression.Constant(typeof(DateTime)), Expression.Constant(typeof(DateTimeOffset)) + ), + Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type)) + ); + else if (tryparseBooleanExp != null) + switchExp = Expression.Switch( + Expression.Constant(type), + Expression.SwitchCase(tryparseBooleanExp, Expression.Constant(typeof(bool))), + Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type)) + ); + else if (type == typeof(string)) + switchExp = Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))); + else + switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); - var defaultRetExp = type == typeof(string) ? - Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))) : - Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); + var defaultRetExp = type == typeof(string) ? + Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))) : + Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); - return Expression.IfThenElse( - Expression.TypeEqual(valueExp, type), - Expression.Return(returnTarget, valueExp), - Expression.IfThenElse( - Expression.TypeEqual(valueExp, typeof(string)), - switchExp, - defaultRetExp - ) - ); - }; + return Expression.IfThenElse( + Expression.TypeEqual(valueExp, type), + Expression.Return(returnTarget, valueExp), + Expression.IfThenElse( + Expression.TypeEqual(valueExp, typeof(string)), + switchExp, + defaultRetExp + ) + ); + }; - return Expression.Block( - new[] { valueExp }, - Expression.Assign(valueExp, Expression.Convert(value, typeof(object))), - Expression.IfThenElse( - Expression.Or( - Expression.Equal(valueExp, Expression.Constant(null)), - Expression.Equal(valueExp, Expression.Constant(DBNull.Value)) - ), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(type), typeof(object))), - funcGetExpression() - ), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - ); - } - public static object GetDataReaderValue(Type type, object value) { - //if (value == null || value == DBNull.Value) return Activator.CreateInstance(type); - if (type == null) return value; - var func = _dicGetDataReaderValue.GetOrAdd(type, k1 => new ConcurrentDictionary>()).GetOrAdd(value?.GetType() ?? type, valueType => { - var parmExp = Expression.Parameter(typeof(object), "value"); - var exp = GetDataReaderValueBlockExpression(type, parmExp); - return Expression.Lambda>(exp, parmExp).Compile(); - }); - return func(value); - } - public static string GetCsName(string name) { - name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_"); - return char.IsLetter(name, 0) ? name : string.Concat("_", name); - } - } + return Expression.Block( + new[] { valueExp }, + Expression.Assign(valueExp, Expression.Convert(value, typeof(object))), + Expression.IfThenElse( + Expression.Or( + Expression.Equal(valueExp, Expression.Constant(null)), + Expression.Equal(valueExp, Expression.Constant(DBNull.Value)) + ), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(type), typeof(object))), + funcGetExpression() + ), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ); + } + public static object GetDataReaderValue(Type type, object value) + { + //if (value == null || value == DBNull.Value) return Activator.CreateInstance(type); + if (type == null) return value; + var func = _dicGetDataReaderValue.GetOrAdd(type, k1 => new ConcurrentDictionary>()).GetOrAdd(value?.GetType() ?? type, valueType => + { + var parmExp = Expression.Parameter(typeof(object), "value"); + var exp = GetDataReaderValueBlockExpression(type, parmExp); + return Expression.Lambda>(exp, parmExp).Compile(); + }); + return func(value); + } + public static string GetCsName(string name) + { + name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_"); + return char.IsLetter(name, 0) ? name : string.Concat("_", name); + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index db2eaa24..2b63f5b6 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -5,74 +5,91 @@ using System.Data; using System.Text; using System.Threading.Tasks; -namespace FreeSql.MySql.Curd { +namespace FreeSql.MySql.Curd +{ - class MySqlDelete : Internal.CommonProvider.DeleteProvider where T1 : class { - public MySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + class MySqlDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public MySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async public override Task> ExecuteDeletedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - } + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 0371246f..35747893 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -5,122 +5,151 @@ using System.Data; using System.Text; using System.Threading.Tasks; -namespace FreeSql.MySql.Curd { +namespace FreeSql.MySql.Curd +{ - class MySqlInsert : Internal.CommonProvider.InsertProvider where T1 : class { - public MySqlInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) - : base(orm, commonUtils, commonExpression) { - } + class MySqlInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public MySqlInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); - protected override long RawExecuteIdentity() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try { - ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0; - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task RawExecuteIdentityAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try { - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0; - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - protected override List RawExecuteInserted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task> RawExecuteInsertedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - } + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index 2a856b34..f9463f3d 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -6,123 +6,145 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.MySql.Curd { +namespace FreeSql.MySql.Curd +{ - class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { + class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) { - if (_orm.CodeFirst.IsAutoSyncStructure) - _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field).Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - } - break; - } else { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + var sb = new StringBuilder(); + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); + else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); - sbnav.Append(_where); - foreach (var tb in _tables) { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } - if (sbnav.Length > 0) { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); - if (_skip > 0 || _limit > 0) - sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); + sbnav.Append(_where); + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_skip > 0 || _limit > 0) + sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); - sbnav.Clear(); - return sb.ToString(); - } + sbnav.Clear(); + return sb.ToString(); + } - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 2b227538..3015a0e3 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -7,113 +7,136 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.MySql.Curd { +namespace FreeSql.MySql.Curd +{ - class MySqlUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { + class MySqlUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { - public MySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + public MySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); - protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task> RawExecuteUpdatedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } - protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { - if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); - return; - } - caseWhen.Append("CONCAT("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); - ++pkidx; - } - caseWhen.Append(")"); - } + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(", "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } - protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { - if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); - return; - } - sb.Append("CONCAT("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); - ++pkidx; - } - sb.Append(")"); - } - } + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(", "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + ++pkidx; + } + sb.Append(")"); + } + } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index c04aa5ca..3e0154ac 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -7,57 +7,66 @@ using System.Data.Common; using System.Text; using System.Threading; -namespace FreeSql.MySql { - class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider { +namespace FreeSql.MySql +{ + class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider + { - public MySqlAdo() : base(DataType.MySql) { } - public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.MySql) { - base._util = util; - if (!string.IsNullOrEmpty(masterConnectionString)) - MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null); - if (slaveConnectionStrings != null) { - foreach (var slaveConnectionString in slaveConnectionStrings) { - var slavePool = new MySqlConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); - SlavePools.Add(slavePool); - } - } - } - static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) { - if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) - param = Utils.GetDataReaderValue(mapType, param); - if (param is bool || param is bool?) - return (bool)param ? 1 : 0; - else if (param is string || param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - else if (param is Enum) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)val).ToInt64(); - else if (decimal.TryParse(string.Concat(param), out var trydec)) - return param; - else if (param is DateTime || param is DateTime?) - return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); - else if (param is TimeSpan || param is TimeSpan?) - return ((TimeSpan)param).Ticks / 10; - else if (param is MygisGeometry) - return string.Concat("ST_GeomFromText('", (param as MygisGeometry).AsText().Replace("'", "''"), "')"); - else if (param is IEnumerable) { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - } + public MySqlAdo() : base(DataType.MySql) { } + public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.MySql) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new MySqlConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)val).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is MygisGeometry) + return string.Concat("ST_GeomFromText('", (param as MygisGeometry).AsText().Replace("'", "''"), "')"); + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } - protected override DbCommand CreateCommand() { - return new MySqlCommand(); - } + protected override DbCommand CreateCommand() + { + return new MySqlCommand(); + } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { - (pool as MySqlConnectionPool).Return(conn, ex); - } + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as MySqlConnectionPool).Return(conn, ex); + } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); - } + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 548ff1aa..6d231602 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -8,170 +8,210 @@ using System.Data.Common; using System.Text.RegularExpressions; using System.Threading.Tasks; -namespace FreeSql.MySql { +namespace FreeSql.MySql +{ - class MySqlConnectionPool : ObjectPool { + class MySqlConnectionPool : ObjectPool + { - internal Action availableHandler; - internal Action unavailableHandler; + internal Action availableHandler; + internal Action unavailableHandler; - public MySqlConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - var policy = new MySqlConnectionPoolPolicy { - _pool = this, - Name = name - }; - this.Policy = policy; - policy.ConnectionString = connectionString; + public MySqlConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new MySqlConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; - } + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } - public void Return(Object obj, Exception exception, bool isRecreate = false) { - if (exception != null && exception is MySqlException) { - try { if (obj.Value.Ping() == false) obj.Value.Open(); } catch { base.SetUnavailable(exception); } - } - base.Return(obj, isRecreate); - } - } + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is MySqlException) + { + try { if (obj.Value.Ping() == false) obj.Value.Open(); } catch { base.SetUnavailable(exception); } + } + base.Return(obj, isRecreate); + } + } - class MySqlConnectionPoolPolicy : IPolicy { + class MySqlConnectionPoolPolicy : IPolicy + { - internal MySqlConnectionPool _pool; - public string Name { get; set; } = "MySql MySqlConnection 对象池"; - public int PoolSize { get; set; } = 100; - public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; - public int AsyncGetCapacity { get; set; } = 10000; - public bool IsThrowGetTimeoutException { get; set; } = true; - public int CheckAvailableInterval { get; set; } = 5; + internal MySqlConnectionPool _pool; + public string Name { get; set; } = "MySql MySqlConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; - static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - private string _connectionString; - public string ConnectionString { - get => _connectionString; - set { - _connectionString = value ?? ""; + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; - var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; - var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); - PoolSize = poolsize + connStrIncr; - _connectionString = m.Success ? - Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : - $"{_connectionString};Max pool size={PoolSize}"; + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; - pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - var minPoolSize = 0; - pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - minPoolSize = int.Parse(m.Groups[1].Value); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); - } - } + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } - public bool OnCheckAvailable(Object obj) { - if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); - return obj.Value.Ping(true); - } + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } - public DbConnection OnCreate() { - var conn = new MySqlConnection(_connectionString); - return conn; - } + public DbConnection OnCreate() + { + var conn = new MySqlConnection(_connectionString); + return conn; + } - public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); - obj.Dispose(); - } + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } - public void OnGet(Object obj) { + public void OnGet(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { - try { - obj.Value.Open(); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - async public Task OnGetAsync(Object obj) { + async public Task OnGetAsync(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { - try { - await obj.Value.OpenAsync(); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - public void OnGetTimeout() { + public void OnGetTimeout() + { - } + } - public void OnReturn(Object obj) { + public void OnReturn(Object obj) + { - } + } - public void OnAvailable() { - _pool.availableHandler?.Invoke(); - } + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } - public void OnUnavailable() { - _pool.unavailableHandler?.Invoke(); - } - } + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } - static class DbConnectionExtensions { + static class DbConnectionExtensions + { - static DbCommand PingCommand(DbConnection conn) { - var cmd = conn.CreateCommand(); - cmd.CommandTimeout = 5; - cmd.CommandText = "select 1"; - return cmd; - } - public static bool Ping(this DbConnection that, bool isThrow = false) { - try { - PingCommand(that).ExecuteNonQuery(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - async public static Task PingAsync(this DbConnection that, bool isThrow = false) { - try { - await PingCommand(that).ExecuteNonQueryAsync(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - } + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MygisTypes.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MygisTypes.cs index e412141a..6672b628 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MygisTypes.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MygisTypes.cs @@ -4,289 +4,338 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; -public struct MygisCoordinate2D : IEquatable { - public double X { get; } - public double Y { get; } - public MygisCoordinate2D(double x, double y) { X = x; Y = y; } +public struct MygisCoordinate2D : IEquatable +{ + public double X { get; } + public double Y { get; } + public MygisCoordinate2D(double x, double y) { X = x; Y = y; } - public bool Equals(MygisCoordinate2D c) => X == c.X && Y == c.Y; - public override int GetHashCode() => X.GetHashCode() ^ MygisGeometry.RotateShift(Y.GetHashCode(), sizeof(int) / 2); - public override bool Equals(object obj) => obj is MygisCoordinate2D && Equals((MygisCoordinate2D) obj); - public static bool operator ==(MygisCoordinate2D left, MygisCoordinate2D right) => Equals(left, right); - public static bool operator !=(MygisCoordinate2D left, MygisCoordinate2D right) => !Equals(left, right); + public bool Equals(MygisCoordinate2D c) => X == c.X && Y == c.Y; + public override int GetHashCode() => X.GetHashCode() ^ MygisGeometry.RotateShift(Y.GetHashCode(), sizeof(int) / 2); + public override bool Equals(object obj) => obj is MygisCoordinate2D && Equals((MygisCoordinate2D)obj); + public static bool operator ==(MygisCoordinate2D left, MygisCoordinate2D right) => Equals(left, right); + public static bool operator !=(MygisCoordinate2D left, MygisCoordinate2D right) => !Equals(left, right); } -public abstract class MygisGeometry { - protected abstract int GetLenHelper(); - internal int GetLen(bool includeSRID) => 5 + (SRID == 0 || !includeSRID ? 0 : 4) + GetLenHelper(); - public uint SRID { get; set; } = 0; - internal static int RotateShift(int val, int shift) => (val << shift) | (val >> (sizeof(int) - shift)); - public override string ToString() => this.AsText(); - public string AsText() { - if (this is MygisPoint) { - var obj = this as MygisPoint; - return $"POINT({obj.X} {obj.Y})"; - } - if (this is MygisLineString) { - var obj = this as MygisLineString; - return obj?.PointCount > 0 ? $"LINESTRING({string.Join(",", obj.Select(a => $"{a.X} {a.Y}"))})" : null; - } - if (this is MygisPolygon) { - var obj = (this as MygisPolygon).Where(z => z.Count() > 1 && z.First().Equals(z.Last())); - return obj.Any() ? $"POLYGON(({string.Join("),(", obj.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))}))" : null; - } - if (this is MygisMultiPoint) { - var obj = this as MygisMultiPoint; - return obj?.PointCount > 0 ? $"MULTIPOINT({string.Join(",", obj.Select(a => $"{a.X} {a.Y}"))})" : null; - } - if (this is MygisMultiLineString) { - var obj = this as MygisMultiLineString; - return obj.LineCount > 0 ? $"MULTILINESTRING(({string.Join("),(", obj.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))}))" : null; - } - if (this is MygisMultiPolygon) { - var obj = (this as MygisMultiPolygon)?.Where(z => z.Where(y => y.Count() > 1 && y.First().Equals(y.Last())).Any()); - return obj.Any() ? $"MULTIPOLYGON((({string.Join(")),((", obj.Select(d => string.Join("),(", d.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))))})))" : null; - } - return base.ToString(); - } - static readonly Regex regexMygisPoint = new Regex(@"\s*(-?\d+\.?\d*)\s+(-?\d+\.?\d*)\s*"); - static readonly Regex regexSplit1 = new Regex(@"\)\s*,\s*\("); - static readonly Regex regexSplit2 = new Regex(@"\)\s*\)\s*,\s*\(\s*\("); - public static MygisGeometry Parse(string wkt) { - if (string.IsNullOrEmpty(wkt)) return null; - wkt = wkt.Trim(); - if (wkt.StartsWith("point", StringComparison.CurrentCultureIgnoreCase)) return ParsePoint(wkt.Substring(5).Trim('(', ')')); - else if (wkt.StartsWith("linestring", StringComparison.CurrentCultureIgnoreCase)) return new MygisLineString(ParseLineString(wkt.Substring(10).Trim('(', ')'))); - else if (wkt.StartsWith("polygon", StringComparison.CurrentCultureIgnoreCase)) return new MygisPolygon(ParsePolygon(wkt.Substring(7).Trim('(', ')'))); - else if (wkt.StartsWith("multipoint", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiPoint(ParseLineString(wkt.Substring(10).Trim('(', ')'))); - else if (wkt.StartsWith("multilinestring", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiLineString(ParseMultiLineString(wkt.Substring(15).Trim('(', ')'))); - else if (wkt.StartsWith("multipolygon", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiPolygon(ParseMultiPolygon(wkt.Substring(12).Trim('(', ')'))); - throw new NotImplementedException($"MygisGeometry.Parse 未实现 \"{wkt}\""); - } - static MygisPoint ParsePoint(string str) { - var m = regexMygisPoint.Match(str); - if (m.Success == false) return null; - return new MygisPoint(double.TryParse(m.Groups[1].Value, out var tryd) ? tryd : 0, double.TryParse(m.Groups[2].Value, out tryd) ? tryd : 0); - } - static MygisCoordinate2D[] ParseLineString(string str) { - var ms = regexMygisPoint.Matches(str); - var points = new MygisCoordinate2D[ms.Count]; - for (var a = 0; a < ms.Count; a++) points[a] = new MygisCoordinate2D(double.TryParse(ms[a].Groups[1].Value, out var tryd) ? tryd : 0, double.TryParse(ms[a].Groups[2].Value, out tryd) ? tryd : 0); - return points; - } - static MygisCoordinate2D[][] ParsePolygon(string str) { - return regexSplit1.Split(str).Select(s => ParseLineString(s)).Where(a => a.Length > 1 && a.First().Equals(a.Last())).ToArray(); - } - static MygisLineString[] ParseMultiLineString(string str) { - return regexSplit1.Split(str).Select(s => new MygisLineString(ParseLineString(s))).ToArray(); - } - static MygisPolygon[] ParseMultiPolygon(string str) { - return regexSplit2.Split(str).Select(s => new MygisPolygon(ParsePolygon(s))).ToArray(); - } +public abstract class MygisGeometry +{ + protected abstract int GetLenHelper(); + internal int GetLen(bool includeSRID) => 5 + (SRID == 0 || !includeSRID ? 0 : 4) + GetLenHelper(); + public uint SRID { get; set; } = 0; + internal static int RotateShift(int val, int shift) => (val << shift) | (val >> (sizeof(int) - shift)); + public override string ToString() => this.AsText(); + public string AsText() + { + if (this is MygisPoint) + { + var obj = this as MygisPoint; + return $"POINT({obj.X} {obj.Y})"; + } + if (this is MygisLineString) + { + var obj = this as MygisLineString; + return obj?.PointCount > 0 ? $"LINESTRING({string.Join(",", obj.Select(a => $"{a.X} {a.Y}"))})" : null; + } + if (this is MygisPolygon) + { + var obj = (this as MygisPolygon).Where(z => z.Count() > 1 && z.First().Equals(z.Last())); + return obj.Any() ? $"POLYGON(({string.Join("),(", obj.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))}))" : null; + } + if (this is MygisMultiPoint) + { + var obj = this as MygisMultiPoint; + return obj?.PointCount > 0 ? $"MULTIPOINT({string.Join(",", obj.Select(a => $"{a.X} {a.Y}"))})" : null; + } + if (this is MygisMultiLineString) + { + var obj = this as MygisMultiLineString; + return obj.LineCount > 0 ? $"MULTILINESTRING(({string.Join("),(", obj.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))}))" : null; + } + if (this is MygisMultiPolygon) + { + var obj = (this as MygisMultiPolygon)?.Where(z => z.Where(y => y.Count() > 1 && y.First().Equals(y.Last())).Any()); + return obj.Any() ? $"MULTIPOLYGON((({string.Join(")),((", obj.Select(d => string.Join("),(", d.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))))})))" : null; + } + return base.ToString(); + } + static readonly Regex regexMygisPoint = new Regex(@"\s*(-?\d+\.?\d*)\s+(-?\d+\.?\d*)\s*"); + static readonly Regex regexSplit1 = new Regex(@"\)\s*,\s*\("); + static readonly Regex regexSplit2 = new Regex(@"\)\s*\)\s*,\s*\(\s*\("); + public static MygisGeometry Parse(string wkt) + { + if (string.IsNullOrEmpty(wkt)) return null; + wkt = wkt.Trim(); + if (wkt.StartsWith("point", StringComparison.CurrentCultureIgnoreCase)) return ParsePoint(wkt.Substring(5).Trim('(', ')')); + else if (wkt.StartsWith("linestring", StringComparison.CurrentCultureIgnoreCase)) return new MygisLineString(ParseLineString(wkt.Substring(10).Trim('(', ')'))); + else if (wkt.StartsWith("polygon", StringComparison.CurrentCultureIgnoreCase)) return new MygisPolygon(ParsePolygon(wkt.Substring(7).Trim('(', ')'))); + else if (wkt.StartsWith("multipoint", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiPoint(ParseLineString(wkt.Substring(10).Trim('(', ')'))); + else if (wkt.StartsWith("multilinestring", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiLineString(ParseMultiLineString(wkt.Substring(15).Trim('(', ')'))); + else if (wkt.StartsWith("multipolygon", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiPolygon(ParseMultiPolygon(wkt.Substring(12).Trim('(', ')'))); + throw new NotImplementedException($"MygisGeometry.Parse 未实现 \"{wkt}\""); + } + static MygisPoint ParsePoint(string str) + { + var m = regexMygisPoint.Match(str); + if (m.Success == false) return null; + return new MygisPoint(double.TryParse(m.Groups[1].Value, out var tryd) ? tryd : 0, double.TryParse(m.Groups[2].Value, out tryd) ? tryd : 0); + } + static MygisCoordinate2D[] ParseLineString(string str) + { + var ms = regexMygisPoint.Matches(str); + var points = new MygisCoordinate2D[ms.Count]; + for (var a = 0; a < ms.Count; a++) points[a] = new MygisCoordinate2D(double.TryParse(ms[a].Groups[1].Value, out var tryd) ? tryd : 0, double.TryParse(ms[a].Groups[2].Value, out tryd) ? tryd : 0); + return points; + } + static MygisCoordinate2D[][] ParsePolygon(string str) + { + return regexSplit1.Split(str).Select(s => ParseLineString(s)).Where(a => a.Length > 1 && a.First().Equals(a.Last())).ToArray(); + } + static MygisLineString[] ParseMultiLineString(string str) + { + return regexSplit1.Split(str).Select(s => new MygisLineString(ParseLineString(s))).ToArray(); + } + static MygisPolygon[] ParseMultiPolygon(string str) + { + return regexSplit2.Split(str).Select(s => new MygisPolygon(ParsePolygon(s))).ToArray(); + } } -public class MygisPoint : MygisGeometry, IEquatable { - MygisCoordinate2D _coord; - protected override int GetLenHelper() => 16; - public double X => _coord.X; - public double Y => _coord.Y; +public class MygisPoint : MygisGeometry, IEquatable +{ + MygisCoordinate2D _coord; + protected override int GetLenHelper() => 16; + public double X => _coord.X; + public double Y => _coord.Y; - public MygisPoint(double x, double y) { - _coord = new MygisCoordinate2D(x, y); - } + public MygisPoint(double x, double y) + { + _coord = new MygisCoordinate2D(x, y); + } - public bool Equals(MygisPoint other) => !ReferenceEquals(other, null) && _coord.Equals(other._coord); - public override bool Equals(object obj) => Equals(obj as MygisPoint); - public static bool operator ==(MygisPoint x, MygisPoint y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); - public static bool operator !=(MygisPoint x, MygisPoint y) => !(x == y); - public override int GetHashCode() => X.GetHashCode() ^ RotateShift(Y.GetHashCode(), sizeof(int) / 2); + public bool Equals(MygisPoint other) => !ReferenceEquals(other, null) && _coord.Equals(other._coord); + public override bool Equals(object obj) => Equals(obj as MygisPoint); + public static bool operator ==(MygisPoint x, MygisPoint y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); + public static bool operator !=(MygisPoint x, MygisPoint y) => !(x == y); + public override int GetHashCode() => X.GetHashCode() ^ RotateShift(Y.GetHashCode(), sizeof(int) / 2); } -public class MygisLineString : MygisGeometry, IEquatable, IEnumerable { - readonly MygisCoordinate2D[] _points; - protected override int GetLenHelper() => 4 + _points.Length * 16; - public IEnumerator GetEnumerator() => ((IEnumerable) _points).GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public MygisCoordinate2D this[int index] => _points[index]; - public int PointCount => _points.Length; +public class MygisLineString : MygisGeometry, IEquatable, IEnumerable +{ + readonly MygisCoordinate2D[] _points; + protected override int GetLenHelper() => 4 + _points.Length * 16; + public IEnumerator GetEnumerator() => ((IEnumerable)_points).GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public MygisCoordinate2D this[int index] => _points[index]; + public int PointCount => _points.Length; - public MygisLineString(IEnumerable points) { - _points = points.ToArray(); - } - public MygisLineString(MygisCoordinate2D[] points) { - _points = points; - } + public MygisLineString(IEnumerable points) + { + _points = points.ToArray(); + } + public MygisLineString(MygisCoordinate2D[] points) + { + _points = points; + } - public bool Equals(MygisLineString other) { - if (ReferenceEquals(other, null)) return false; - if (_points.Length != other._points.Length) return false; - for (var i = 0; i < _points.Length; i++) - if (!_points[i].Equals(other._points[i])) return false; - return true; - } - public override bool Equals(object obj) => Equals(obj as MygisLineString); - public static bool operator ==(MygisLineString x, MygisLineString y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); - public static bool operator !=(MygisLineString x, MygisLineString y) => !(x == y); - public override int GetHashCode() { - var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. - foreach (var t in _points) ret ^= RotateShift(t.GetHashCode(), ret % sizeof(int)); - return ret; - } + public bool Equals(MygisLineString other) + { + if (ReferenceEquals(other, null)) return false; + if (_points.Length != other._points.Length) return false; + for (var i = 0; i < _points.Length; i++) + if (!_points[i].Equals(other._points[i])) return false; + return true; + } + public override bool Equals(object obj) => Equals(obj as MygisLineString); + public static bool operator ==(MygisLineString x, MygisLineString y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); + public static bool operator !=(MygisLineString x, MygisLineString y) => !(x == y); + public override int GetHashCode() + { + var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. + foreach (var t in _points) ret ^= RotateShift(t.GetHashCode(), ret % sizeof(int)); + return ret; + } } -public class MygisPolygon : MygisGeometry, IEquatable, IEnumerable> { - readonly MygisCoordinate2D[][] _rings; - protected override int GetLenHelper() => 4 + _rings.Length * 4 + TotalPointCount * 16; - public MygisCoordinate2D this[int ringIndex, int pointIndex] => _rings[ringIndex][pointIndex]; - public MygisCoordinate2D[] this[int ringIndex] => _rings[ringIndex]; - public IEnumerator> GetEnumerator() => ((IEnumerable>) _rings).GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public int RingCount => _rings.Length; - public int TotalPointCount => _rings.Sum(r => r.Length); +public class MygisPolygon : MygisGeometry, IEquatable, IEnumerable> +{ + readonly MygisCoordinate2D[][] _rings; + protected override int GetLenHelper() => 4 + _rings.Length * 4 + TotalPointCount * 16; + public MygisCoordinate2D this[int ringIndex, int pointIndex] => _rings[ringIndex][pointIndex]; + public MygisCoordinate2D[] this[int ringIndex] => _rings[ringIndex]; + public IEnumerator> GetEnumerator() => ((IEnumerable>)_rings).GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public int RingCount => _rings.Length; + public int TotalPointCount => _rings.Sum(r => r.Length); - public MygisPolygon(MygisCoordinate2D[][] rings) { - _rings = rings; - } - public MygisPolygon(IEnumerable> rings) { - _rings = rings.Select(x => x.ToArray()).ToArray(); - } + public MygisPolygon(MygisCoordinate2D[][] rings) + { + _rings = rings; + } + public MygisPolygon(IEnumerable> rings) + { + _rings = rings.Select(x => x.ToArray()).ToArray(); + } - public bool Equals(MygisPolygon other) { - if (ReferenceEquals(other, null)) return false; - if (_rings.Length != other._rings.Length) return false; - for (var i = 0; i < _rings.Length; i++) { - if (_rings[i].Length != other._rings[i].Length) return false; - for (var j = 0; j < _rings[i].Length; j++) - if (!_rings[i][j].Equals(other._rings[i][j])) return false; - } - return true; - } - public override bool Equals(object obj) => Equals(obj as MygisPolygon); - public static bool operator ==(MygisPolygon x, MygisPolygon y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); - public static bool operator !=(MygisPolygon x, MygisPolygon y) => !(x == y); - public override int GetHashCode() { - var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. - for (var i = 0; i < _rings.Length; i++) - for (var j = 0; j < _rings[i].Length; j++) - ret ^= RotateShift(_rings[i][j].GetHashCode(), ret % sizeof(int)); - return ret; - } + public bool Equals(MygisPolygon other) + { + if (ReferenceEquals(other, null)) return false; + if (_rings.Length != other._rings.Length) return false; + for (var i = 0; i < _rings.Length; i++) + { + if (_rings[i].Length != other._rings[i].Length) return false; + for (var j = 0; j < _rings[i].Length; j++) + if (!_rings[i][j].Equals(other._rings[i][j])) return false; + } + return true; + } + public override bool Equals(object obj) => Equals(obj as MygisPolygon); + public static bool operator ==(MygisPolygon x, MygisPolygon y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); + public static bool operator !=(MygisPolygon x, MygisPolygon y) => !(x == y); + public override int GetHashCode() + { + var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. + for (var i = 0; i < _rings.Length; i++) + for (var j = 0; j < _rings[i].Length; j++) + ret ^= RotateShift(_rings[i][j].GetHashCode(), ret % sizeof(int)); + return ret; + } } -public class MygisMultiPoint : MygisGeometry, IEquatable, IEnumerable { - readonly MygisCoordinate2D[] _points; - protected override int GetLenHelper() => 4 + _points.Length * 21; - public IEnumerator GetEnumerator() => ((IEnumerable) _points).GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public MygisCoordinate2D this[int indexer] => _points[indexer]; - public int PointCount => _points.Length; +public class MygisMultiPoint : MygisGeometry, IEquatable, IEnumerable +{ + readonly MygisCoordinate2D[] _points; + protected override int GetLenHelper() => 4 + _points.Length * 21; + public IEnumerator GetEnumerator() => ((IEnumerable)_points).GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public MygisCoordinate2D this[int indexer] => _points[indexer]; + public int PointCount => _points.Length; - public MygisMultiPoint(MygisCoordinate2D[] points) { - _points = points; - } - public MygisMultiPoint(IEnumerable points) { - _points = points.Select(x => new MygisCoordinate2D(x.X, x.Y)).ToArray(); - } - public MygisMultiPoint(IEnumerable points) { - _points = points.ToArray(); - } + public MygisMultiPoint(MygisCoordinate2D[] points) + { + _points = points; + } + public MygisMultiPoint(IEnumerable points) + { + _points = points.Select(x => new MygisCoordinate2D(x.X, x.Y)).ToArray(); + } + public MygisMultiPoint(IEnumerable points) + { + _points = points.ToArray(); + } - public bool Equals(MygisMultiPoint other) { - if (ReferenceEquals(other, null)) return false; - if (_points.Length != other._points.Length) return false; - for (var i = 0; i < _points.Length; i++) - if (!_points[i].Equals(other._points[i])) return false; - return true; - } - public override bool Equals(object obj) => Equals(obj as MygisMultiPoint); - public static bool operator ==(MygisMultiPoint x, MygisMultiPoint y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); - public static bool operator !=(MygisMultiPoint x, MygisMultiPoint y) => !(x == y); - public override int GetHashCode() { - var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. - for (var i = 0; i < _points.Length; i++) ret ^= RotateShift(_points[i].GetHashCode(), ret % sizeof(int)); - return ret; - } + public bool Equals(MygisMultiPoint other) + { + if (ReferenceEquals(other, null)) return false; + if (_points.Length != other._points.Length) return false; + for (var i = 0; i < _points.Length; i++) + if (!_points[i].Equals(other._points[i])) return false; + return true; + } + public override bool Equals(object obj) => Equals(obj as MygisMultiPoint); + public static bool operator ==(MygisMultiPoint x, MygisMultiPoint y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); + public static bool operator !=(MygisMultiPoint x, MygisMultiPoint y) => !(x == y); + public override int GetHashCode() + { + var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. + for (var i = 0; i < _points.Length; i++) ret ^= RotateShift(_points[i].GetHashCode(), ret % sizeof(int)); + return ret; + } } public sealed class MygisMultiLineString : MygisGeometry, - IEquatable, IEnumerable { - readonly MygisLineString[] _lineStrings; - protected override int GetLenHelper() { - var n = 4; - for (var i = 0; i < _lineStrings.Length; i++) n += _lineStrings[i].GetLen(false); - return n; - } - public IEnumerator GetEnumerator() => ((IEnumerable) _lineStrings).GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public MygisLineString this[int index] => _lineStrings[index]; - public int LineCount => _lineStrings.Length; + IEquatable, IEnumerable +{ + readonly MygisLineString[] _lineStrings; + protected override int GetLenHelper() + { + var n = 4; + for (var i = 0; i < _lineStrings.Length; i++) n += _lineStrings[i].GetLen(false); + return n; + } + public IEnumerator GetEnumerator() => ((IEnumerable)_lineStrings).GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public MygisLineString this[int index] => _lineStrings[index]; + public int LineCount => _lineStrings.Length; - internal MygisMultiLineString(MygisCoordinate2D[][] pointArray) { - _lineStrings = new MygisLineString[pointArray.Length]; - for (var i = 0; i < pointArray.Length; i++) - _lineStrings[i] = new MygisLineString(pointArray[i]); - } - public MygisMultiLineString(MygisLineString[] linestrings) { - _lineStrings = linestrings; - } - public MygisMultiLineString(IEnumerable linestrings) { - _lineStrings = linestrings.ToArray(); - } - public MygisMultiLineString(IEnumerable> pointList) { - _lineStrings = pointList.Select(x => new MygisLineString(x)).ToArray(); - } + internal MygisMultiLineString(MygisCoordinate2D[][] pointArray) + { + _lineStrings = new MygisLineString[pointArray.Length]; + for (var i = 0; i < pointArray.Length; i++) + _lineStrings[i] = new MygisLineString(pointArray[i]); + } + public MygisMultiLineString(MygisLineString[] linestrings) + { + _lineStrings = linestrings; + } + public MygisMultiLineString(IEnumerable linestrings) + { + _lineStrings = linestrings.ToArray(); + } + public MygisMultiLineString(IEnumerable> pointList) + { + _lineStrings = pointList.Select(x => new MygisLineString(x)).ToArray(); + } - public bool Equals(MygisMultiLineString other) { - if (ReferenceEquals(other, null)) return false; - if (_lineStrings.Length != other._lineStrings.Length) return false; - for (var i = 0; i < _lineStrings.Length; i++) - if (_lineStrings[i] != other._lineStrings[i]) return false; - return true; - } - public override bool Equals(object obj) => Equals(obj as MygisMultiLineString); - public static bool operator ==(MygisMultiLineString x, MygisMultiLineString y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); - public static bool operator !=(MygisMultiLineString x, MygisMultiLineString y) => !(x == y); - public override int GetHashCode() { - var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. - for (var i = 0; i < _lineStrings.Length; i++) ret ^= RotateShift(_lineStrings[i].GetHashCode(), ret % sizeof(int)); - return ret; - } + public bool Equals(MygisMultiLineString other) + { + if (ReferenceEquals(other, null)) return false; + if (_lineStrings.Length != other._lineStrings.Length) return false; + for (var i = 0; i < _lineStrings.Length; i++) + if (_lineStrings[i] != other._lineStrings[i]) return false; + return true; + } + public override bool Equals(object obj) => Equals(obj as MygisMultiLineString); + public static bool operator ==(MygisMultiLineString x, MygisMultiLineString y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); + public static bool operator !=(MygisMultiLineString x, MygisMultiLineString y) => !(x == y); + public override int GetHashCode() + { + var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. + for (var i = 0; i < _lineStrings.Length; i++) ret ^= RotateShift(_lineStrings[i].GetHashCode(), ret % sizeof(int)); + return ret; + } } -public class MygisMultiPolygon : MygisGeometry, IEquatable, IEnumerable { - readonly MygisPolygon[] _polygons; - protected override int GetLenHelper() { - var n = 4; - for (var i = 0; i < _polygons.Length; i++) n += _polygons[i].GetLen(false); - return n; - } - public IEnumerator GetEnumerator() => ((IEnumerable) _polygons).GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public MygisPolygon this[int index] => _polygons[index]; - public int PolygonCount => _polygons.Length; +public class MygisMultiPolygon : MygisGeometry, IEquatable, IEnumerable +{ + readonly MygisPolygon[] _polygons; + protected override int GetLenHelper() + { + var n = 4; + for (var i = 0; i < _polygons.Length; i++) n += _polygons[i].GetLen(false); + return n; + } + public IEnumerator GetEnumerator() => ((IEnumerable)_polygons).GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public MygisPolygon this[int index] => _polygons[index]; + public int PolygonCount => _polygons.Length; - public MygisMultiPolygon(MygisPolygon[] polygons) { - _polygons = polygons; - } - public MygisMultiPolygon(IEnumerable polygons) { - _polygons = polygons.ToArray(); - } - public MygisMultiPolygon(IEnumerable>> ringList) { - _polygons = ringList.Select(x => new MygisPolygon(x)).ToArray(); - } + public MygisMultiPolygon(MygisPolygon[] polygons) + { + _polygons = polygons; + } + public MygisMultiPolygon(IEnumerable polygons) + { + _polygons = polygons.ToArray(); + } + public MygisMultiPolygon(IEnumerable>> ringList) + { + _polygons = ringList.Select(x => new MygisPolygon(x)).ToArray(); + } - public bool Equals(MygisMultiPolygon other) { - if (ReferenceEquals(other, null)) return false; - if (_polygons.Length != other._polygons.Length) return false; - for (var i = 0; i < _polygons.Length; i++) if (_polygons[i] != other._polygons[i]) return false; - return true; - } - public override bool Equals(object obj) => obj is MygisMultiPolygon && Equals((MygisMultiPolygon) obj); - public static bool operator ==(MygisMultiPolygon x, MygisMultiPolygon y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); - public static bool operator !=(MygisMultiPolygon x, MygisMultiPolygon y) => !(x == y); - public override int GetHashCode() { - var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. - for (var i = 0; i < _polygons.Length; i++) ret ^= RotateShift(_polygons[i].GetHashCode(), ret % sizeof(int)); - return ret; - } + public bool Equals(MygisMultiPolygon other) + { + if (ReferenceEquals(other, null)) return false; + if (_polygons.Length != other._polygons.Length) return false; + for (var i = 0; i < _polygons.Length; i++) if (_polygons[i] != other._polygons[i]) return false; + return true; + } + public override bool Equals(object obj) => obj is MygisMultiPolygon && Equals((MygisMultiPolygon)obj); + public static bool operator ==(MygisMultiPolygon x, MygisMultiPolygon y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y); + public static bool operator !=(MygisMultiPolygon x, MygisMultiPolygon y) => !(x == y); + public override int GetHashCode() + { + var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently. + for (var i = 0; i < _polygons.Length; i++) ret ^= RotateShift(_polygons[i].GetHashCode(), ret % sizeof(int)); + return ret; + } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MygisTypesExtensions.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MygisTypesExtensions.cs index 5047e62e..ec45d367 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MygisTypesExtensions.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MygisTypesExtensions.cs @@ -6,18 +6,20 @@ using System.Drawing; using System.Reflection; using System.Text; -public static partial class MygisTypesExtensions { - /// - /// 测量两个经纬度的距离,返回单位:米 - /// - /// 经纬坐标1 - /// 经纬坐标2 - /// 返回距离(单位:米) - public static double Distance(this MygisPoint that, MygisPoint point) { - double radLat1 = (double)(that.Y) * Math.PI / 180d; - double radLng1 = (double)(that.X) * Math.PI / 180d; - double radLat2 = (double)(point.Y) * Math.PI / 180d; - double radLng2 = (double)(point.X) * Math.PI / 180d; - 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; - } +public static partial class MygisTypesExtensions +{ + /// + /// 测量两个经纬度的距离,返回单位:米 + /// + /// 经纬坐标1 + /// 经纬坐标2 + /// 返回距离(单位:米) + public static double Distance(this MygisPoint that, MygisPoint point) + { + double radLat1 = (double)(that.Y) * Math.PI / 180d; + double radLng1 = (double)(that.X) * Math.PI / 180d; + double radLat2 = (double)(point.Y) * Math.PI / 180d; + double radLng2 = (double)(point.X) * Math.PI / 180d; + 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; + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 8fed3c85..f4c5acc0 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -11,143 +11,165 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; -namespace FreeSql.MySql { +namespace FreeSql.MySql +{ - class MySqlCodeFirst : Internal.CommonProvider.CodeFirstProvider { + class MySqlCodeFirst : Internal.CommonProvider.CodeFirstProvider + { - public MySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + public MySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } - static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (MySqlDbType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (MySqlDbType.Bit, "bit","bit(1)", null, true, null) }, + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (MySqlDbType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (MySqlDbType.Bit, "bit","bit(1)", null, true, null) }, - { typeof(sbyte).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3)", false, true, null) }, - { typeof(short).FullName, (MySqlDbType.Int16, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (MySqlDbType.Int16, "smallint", "smallint(6)", false, true, null) }, - { typeof(int).FullName, (MySqlDbType.Int32, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (MySqlDbType.Int32, "int", "int(11)", false, true, null) }, - { typeof(long).FullName, (MySqlDbType.Int64, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (MySqlDbType.Int64, "bigint","bigint(20)", false, true, null) }, + { typeof(sbyte).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3)", false, true, null) }, + { typeof(short).FullName, (MySqlDbType.Int16, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (MySqlDbType.Int16, "smallint", "smallint(6)", false, true, null) }, + { typeof(int).FullName, (MySqlDbType.Int32, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (MySqlDbType.Int32, "int", "int(11)", false, true, null) }, + { typeof(long).FullName, (MySqlDbType.Int64, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (MySqlDbType.Int64, "bigint","bigint(20)", false, true, null) }, - { typeof(byte).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned", true, true, null) }, - { typeof(ushort).FullName, (MySqlDbType.UInt16, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (MySqlDbType.UInt16, "smallint", "smallint(5) unsigned", true, true, null) }, - { typeof(uint).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned", true, true, null) }, - { typeof(ulong).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned", true, true, null) }, + { typeof(byte).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned", true, true, null) }, + { typeof(ushort).FullName, (MySqlDbType.UInt16, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (MySqlDbType.UInt16, "smallint", "smallint(5) unsigned", true, true, null) }, + { typeof(uint).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned", true, true, null) }, + { typeof(ulong).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned", true, true, null) }, - { typeof(double).FullName, (MySqlDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (MySqlDbType.Double, "double", "double", false, true, null) }, - { typeof(float).FullName, (MySqlDbType.Float, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (MySqlDbType.Float, "float","float", false, true, null) }, - { typeof(decimal).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(double).FullName, (MySqlDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (MySqlDbType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, (MySqlDbType.Float, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (MySqlDbType.Float, "float","float", false, true, null) }, + { typeof(decimal).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(TimeSpan).FullName, (MySqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (MySqlDbType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3)", false, true, null) }, + { typeof(TimeSpan).FullName, (MySqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (MySqlDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3)", false, true, null) }, - { typeof(byte[]).FullName, (MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, - { typeof(string).FullName, (MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(byte[]).FullName, (MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, (MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, - { typeof(Guid).FullName, (MySqlDbType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (MySqlDbType.VarChar, "char", "char(36)", false, true, null) }, + { typeof(Guid).FullName, (MySqlDbType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (MySqlDbType.VarChar, "char", "char(36)", false, true, null) }, - { typeof(MygisPoint).FullName, (MySqlDbType.Geometry, "point", "point", false, null, new MygisPoint(0, 0)) }, - { typeof(MygisLineString).FullName, (MySqlDbType.Geometry, "linestring", "linestring", false, null, new MygisLineString(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) }, - { typeof(MygisPolygon).FullName, (MySqlDbType.Geometry, "polygon", "polygon", false, null, new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) }, - { typeof(MygisMultiPoint).FullName, (MySqlDbType.Geometry, "multipoint","multipoint", false, null, new MygisMultiPoint(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) }, - { typeof(MygisMultiLineString).FullName, (MySqlDbType.Geometry, "multilinestring","multilinestring", false, null, new MygisMultiLineString(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) }, - { typeof(MygisMultiPolygon).FullName, (MySqlDbType.Geometry, "multipolygon", "multipolygon", false, null, new MygisMultiPolygon(new[]{new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}}),new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})})) }, - }; + { typeof(MygisPoint).FullName, (MySqlDbType.Geometry, "point", "point", false, null, new MygisPoint(0, 0)) }, + { typeof(MygisLineString).FullName, (MySqlDbType.Geometry, "linestring", "linestring", false, null, new MygisLineString(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) }, + { typeof(MygisPolygon).FullName, (MySqlDbType.Geometry, "polygon", "polygon", false, null, new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) }, + { typeof(MygisMultiPoint).FullName, (MySqlDbType.Geometry, "multipoint","multipoint", false, null, new MygisMultiPoint(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) }, + { typeof(MygisMultiLineString).FullName, (MySqlDbType.Geometry, "multilinestring","multilinestring", false, null, new MygisMultiLineString(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) }, + { typeof(MygisMultiPolygon).FullName, (MySqlDbType.Geometry, "multipolygon", "multipolygon", false, null, new MygisMultiPolygon(new[]{new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}}),new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})})) }, + }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); - if (type.IsArray) return null; - var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); - if (enumType != null) { - var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); - var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (MySqlDbType.Set, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); - if (_dicCsToDb.ContainsKey(type.FullName) == false) { - lock (_dicCsToDbLock) { - if (_dicCsToDb.ContainsKey(type.FullName) == false) - _dicCsToDb.Add(type.FullName, newItem); - } - } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); - } - return null; - } + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (MySqlDbType.Set, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } - public override string GetComparisonDDLStatements(params Type[] entityTypes) { - var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); - var database = conn.Value.Database; - Func ExecuteScalar = (db, sql) => { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); - try { - using (var cmd = conn.Value.CreateCommand()) { - cmd.CommandText = sql; - cmd.CommandType = CommandType.Text; - return cmd.ExecuteScalar(); - } - } finally { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); - } - }; - var sb = new StringBuilder(); - try { - foreach (var entityType in entityTypes) { - if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); - if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + var database = conn.Value.Database; + Func ExecuteScalar = (db, sql) => + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + }; + var sb = new StringBuilder(); + try + { + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; - if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 - sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n"); + if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 + sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n"); - var sbalter = new StringBuilder(); - var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (ExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) { //表不存在 - if (tboldname != null) { - if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null || - ExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null) - //数据库或表不存在 - tboldname = null; - } - if (tboldname == null) { - //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); - if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); - sb.Append(","); - } - if (tb.Primarys.Any()) { - sb.Append(" \r\n PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); - continue; - } - //如果新表,旧表在一个数据库下,直接修改表名 - if (string.Compare(tbname[0], tboldname[0], true) == 0) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); - else { - //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 - istmpatler = true; - } - } else - tboldname = null; //如果新表已经存在,不走改表名逻辑 + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (ExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null || + ExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null) + //数据库或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) Engine=InnoDB;\r\n"); + continue; + } + //如果新表,旧表在一个数据库下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 - //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = _commonUtils.FormatSql(@" + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql(@" select a.column_name, a.column_type, @@ -156,131 +178,153 @@ case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', a.column_comment 'comment' from information_schema.columns a where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { - var a1 = string.Concat(a[1]); - if (a1 == "datetime") a1 = string.Concat(a1, "(0)"); - return new { - column = string.Concat(a[0]), - sqlType = a1, - is_nullable = string.Concat(a[2]) == "1", - is_identity = string.Concat(a[3]) == "1", - is_unsigned = string.Concat(a[1]).EndsWith(" unsigned"), - comment = string.Concat(a[4]) - }; - }, StringComparer.CurrentCultureIgnoreCase); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var a1 = string.Concat(a[1]); + if (a1 == "datetime") a1 = string.Concat(a1, "(0)"); + return new + { + column = string.Concat(a[0]), + sqlType = a1, + is_nullable = string.Concat(a[2]) == "1", + is_identity = string.Concat(a[3]) == "1", + is_unsigned = string.Concat(a[1]).EndsWith(" unsigned"), + comment = string.Concat(a[4]) + }; + }, StringComparer.CurrentCultureIgnoreCase); - if (istmpatler == false) { - var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql("select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); - foreach (var tbcol in tb.Columns.Values) { - var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); - if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || - tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || - tbcol.Attribute.IsNullable != tbstructcol.is_nullable || - tbcol.Attribute.IsIdentity != tbstructcol.is_identity || - isCommentChanged) { - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); - if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(")"); - sbalter.Append(";\r\n"); - } - if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) { - //修改列名 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); - sbalter.Append(";\r\n"); - } - continue; - } - //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); - if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); - sbalter.Append(";\r\n"); - } - var dsuksql = _commonUtils.FormatSql(@" + if (istmpatler == false) + { + var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql("select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); + foreach (var tbcol in tb.Columns.Values) + { + var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || + tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.IsNullable != tbstructcol.is_nullable || + tbcol.Attribute.IsIdentity != tbstructcol.is_identity || + isCommentChanged) + { + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); + if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(")"); + sbalter.Append(";\r\n"); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + sbalter.Append(";\r\n"); + } + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + sbalter.Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" select a.column_name, a.constraint_name 'index_id' from information_schema.key_column_usage a where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) { - if (uk.Key == "PRIMARY" || string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); - } - } - } - if (istmpatler == false) { - sb.Append(sbalter); - continue; - } + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); + foreach (var uk in tb.Uniques) + { + if (uk.Key == "PRIMARY" || string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } - //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); - //创建临时表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); - if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); - sb.Append(","); - } - if (tb.Primarys.Any()) { - sb.Append(" \r\n PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); - sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) - sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.Columns.Values) { - var insertvalue = "NULL"; - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) { - //insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; - } - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; - } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); - sb.Append(insertvalue).Append(", "); - } - sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); - sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); - } - return sb.Length == 0 ? null : sb.ToString(); - } finally { - try { - conn.Value.ChangeDatabase(database); - _orm.Ado.MasterPool.Return(conn); - } catch { - _orm.Ado.MasterPool.Return(conn, true); - } - } - } - } + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.Columns.Values) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + //insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } + finally + { + try + { + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } + catch + { + _orm.Ado.MasterPool.Return(conn, true); + } + } + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 760aedc3..2f2a339a 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -7,149 +7,158 @@ using System.Data; using System.Linq; using System.Text.RegularExpressions; -namespace FreeSql.MySql { - class MySqlDbFirst : IDbFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public MySqlDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } +namespace FreeSql.MySql +{ + class MySqlDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public MySqlDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } - public int GetDbType(DbColumnInfo column) => (int)GetMySqlDbType(column); - MySqlDbType GetMySqlDbType(DbColumnInfo column) { - var is_unsigned = column.DbTypeTextFull.ToLower().EndsWith(" unsigned"); - switch (column.DbTypeText.ToLower()) { - case "bit": return MySqlDbType.Bit; + public int GetDbType(DbColumnInfo column) => (int)GetMySqlDbType(column); + MySqlDbType GetMySqlDbType(DbColumnInfo column) + { + var is_unsigned = column.DbTypeTextFull.ToLower().EndsWith(" unsigned"); + switch (column.DbTypeText.ToLower()) + { + case "bit": return MySqlDbType.Bit; - case "tinyint": return is_unsigned ? MySqlDbType.UByte : MySqlDbType.Byte; - case "smallint": return is_unsigned ? MySqlDbType.UInt16 : MySqlDbType.Int16; - case "mediumint": return is_unsigned ? MySqlDbType.UInt24 : MySqlDbType.Int24; - case "int": return is_unsigned ? MySqlDbType.UInt32 : MySqlDbType.Int32; - case "bigint": return is_unsigned ? MySqlDbType.UInt64 : MySqlDbType.Int64; + case "tinyint": return is_unsigned ? MySqlDbType.UByte : MySqlDbType.Byte; + case "smallint": return is_unsigned ? MySqlDbType.UInt16 : MySqlDbType.Int16; + case "mediumint": return is_unsigned ? MySqlDbType.UInt24 : MySqlDbType.Int24; + case "int": return is_unsigned ? MySqlDbType.UInt32 : MySqlDbType.Int32; + case "bigint": return is_unsigned ? MySqlDbType.UInt64 : MySqlDbType.Int64; - case "real": - case "double": return MySqlDbType.Double; - case "float": return MySqlDbType.Float; - case "numeric": - case "decimal": return MySqlDbType.Decimal; + case "real": + case "double": return MySqlDbType.Double; + case "float": return MySqlDbType.Float; + case "numeric": + case "decimal": return MySqlDbType.Decimal; - case "year": return MySqlDbType.Year; - case "time": return MySqlDbType.Time; - case "date": return MySqlDbType.Date; - case "timestamp": return MySqlDbType.Timestamp; - case "datetime": return MySqlDbType.DateTime; + case "year": return MySqlDbType.Year; + case "time": return MySqlDbType.Time; + case "date": return MySqlDbType.Date; + case "timestamp": return MySqlDbType.Timestamp; + case "datetime": return MySqlDbType.DateTime; - case "tinyblob": return MySqlDbType.TinyBlob; - case "blob": return MySqlDbType.Blob; - case "mediumblob": return MySqlDbType.MediumBlob; - case "longblob": return MySqlDbType.LongBlob; + case "tinyblob": return MySqlDbType.TinyBlob; + case "blob": return MySqlDbType.Blob; + case "mediumblob": return MySqlDbType.MediumBlob; + case "longblob": return MySqlDbType.LongBlob; - case "binary": return MySqlDbType.Binary; - case "varbinary": return MySqlDbType.VarBinary; + case "binary": return MySqlDbType.Binary; + case "varbinary": return MySqlDbType.VarBinary; - case "tinytext": return MySqlDbType.TinyText; - case "text": return MySqlDbType.Text; - case "mediumtext": return MySqlDbType.MediumText; - case "longtext": return MySqlDbType.LongText; + case "tinytext": return MySqlDbType.TinyText; + case "text": return MySqlDbType.Text; + case "mediumtext": return MySqlDbType.MediumText; + case "longtext": return MySqlDbType.LongText; - case "char": return column.MaxLength == 36 ? MySqlDbType.Guid : MySqlDbType.String; - case "varchar": return MySqlDbType.VarChar; + case "char": return column.MaxLength == 36 ? MySqlDbType.Guid : MySqlDbType.String; + case "varchar": return MySqlDbType.VarChar; - case "set": return MySqlDbType.Set; - case "enum": return MySqlDbType.Enum; + case "set": return MySqlDbType.Set; + case "enum": return MySqlDbType.Enum; - case "point": return MySqlDbType.Geometry; - case "linestring": return MySqlDbType.Geometry; - case "polygon": return MySqlDbType.Geometry; - case "geometry": return MySqlDbType.Geometry; - case "multipoint": return MySqlDbType.Geometry; - case "multilinestring": return MySqlDbType.Geometry; - case "multipolygon": return MySqlDbType.Geometry; - case "geometrycollection": return MySqlDbType.Geometry; - default: return MySqlDbType.String; - } - } + case "point": return MySqlDbType.Geometry; + case "linestring": return MySqlDbType.Geometry; + case "polygon": return MySqlDbType.Geometry; + case "geometry": return MySqlDbType.Geometry; + case "multipoint": return MySqlDbType.Geometry; + case "multilinestring": return MySqlDbType.Geometry; + case "multipolygon": return MySqlDbType.Geometry; + case "geometrycollection": return MySqlDbType.Geometry; + default: return MySqlDbType.String; + } + } - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)MySqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)MySqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)MySqlDbType.Byte, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, - { (int)MySqlDbType.Int16, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)MySqlDbType.Int24, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Int32, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Int64, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)MySqlDbType.Byte, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, + { (int)MySqlDbType.Int16, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)MySqlDbType.Int24, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.Int32, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.Int64, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)MySqlDbType.UByte, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { (int)MySqlDbType.UInt16, ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") }, - { (int)MySqlDbType.UInt24, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.UInt32, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.UInt64, ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, + { (int)MySqlDbType.UByte, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)MySqlDbType.UInt16, ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") }, + { (int)MySqlDbType.UInt24, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.UInt32, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.UInt64, ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, - { (int)MySqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)MySqlDbType.Float, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)MySqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)MySqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)MySqlDbType.Float, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)MySqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)MySqlDbType.Year, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)MySqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)MySqlDbType.Year, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)MySqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)MySqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)MySqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.TinyBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.Blob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.MediumBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.LongBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.TinyBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.Blob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.MediumBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.LongBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.TinyText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.MediumText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.LongText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.TinyText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.MediumText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.LongText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.Guid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, - { (int)MySqlDbType.String, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.VarString, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.Guid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + { (int)MySqlDbType.String, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.VarString, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.Set, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Set", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, - { (int)MySqlDbType.Enum, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Enum", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, + { (int)MySqlDbType.Set, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Set", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, + { (int)MySqlDbType.Enum, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Enum", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, - { (int)MySqlDbType.Geometry, ("(MygisGeometry)", "MygisGeometry.Parse({0}.Replace(StringifySplit, \"|\"))", "{0}.AsText().Replace(\"|\", StringifySplit)", "MygisGeometry", typeof(MygisGeometry), typeof(MygisGeometry), "{0}", "GetString") }, - }; + { (int)MySqlDbType.Geometry, ("(MygisGeometry)", "MygisGeometry.Parse({0}.Replace(StringifySplit, \"|\"))", "{0}.AsText().Replace(\"|\", StringifySplit)", "MygisGeometry", typeof(MygisGeometry), typeof(MygisGeometry), "{0}", "GetString") }, + }; - public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; - public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; - public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; - public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; - public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; - public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; - public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; - public List GetDatabases() { - var sql = @" select schema_name from information_schema.schemata where schema_name not in ('information_schema', 'mysql', 'performance_schema')"; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); - } + public List GetDatabases() + { + var sql = @" select schema_name from information_schema.schemata where schema_name not in ('information_schema', 'mysql', 'performance_schema')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } - public List GetTablesByDatabase(params string[] database2) { - var loc1 = new List(); - var loc2 = new Dictionary(); - var loc3 = new Dictionary>(); - var database = database2?.ToArray(); + public List GetTablesByDatabase(params string[] database2) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + var database = database2?.ToArray(); - if (database == null || database.Any() == false) { - using (var conn = _orm.Ado.MasterPool.Get()) { - if (string.IsNullOrEmpty(conn.Value.Database)) return loc1; - database = new[] { conn.Value.Database }; - } - } - var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); - var sql = string.Format(@" + if (database == null || database.Any() == false) + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + if (string.IsNullOrEmpty(conn.Value.Database)) return loc1; + database = new[] { conn.Value.Database }; + } + } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); + var sql = string.Format(@" select concat(a.table_schema, '.', a.table_name) 'id', a.table_schema 'schema', @@ -158,38 +167,41 @@ a.table_comment, a.table_type 'type' from information_schema.tables a where a.table_schema in ({0})", databaseIn); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); - foreach (var row in ds) { - var table_id = string.Concat(row[0]); - var schema = string.Concat(row[1]); - var table = string.Concat(row[2]); - var comment = string.Concat(row[3]); - var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - schema = ""; - } - loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); - loc3.Add(table_id, new Dictionary()); - switch (type) { - case DbTableType.TABLE: - case DbTableType.VIEW: - loc6.Add(table.Replace("'", "''")); - break; - case DbTableType.StoreProcedure: - loc66.Add(table.Replace("'", "''")); - break; - } - } - if (loc6.Count == 0) return loc1; - var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc6 = new List(); + var loc66 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6.Add(table.Replace("'", "''")); + break; + case DbTableType.StoreProcedure: + loc66.Add(table.Replace("'", "''")); + break; + } + } + if (loc6.Count == 0) return loc1; + var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; + var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; - sql = string.Format(@" + sql = string.Format(@" select concat(a.table_schema, '.', a.table_name), a.column_name, @@ -202,40 +214,43 @@ a.column_comment 'comment' from information_schema.columns a where a.table_schema in ({1}) and a.table_name in ({0}) ", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string type = string.Concat(row[2]); - //long max_length = long.Parse(string.Concat(row[3])); - string sqlType = string.Concat(row[4]); - var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); - int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; - bool is_nullable = string.Concat(row[5]) == "1"; - bool is_identity = string.Concat(row[6]) == "1"; - string comment = string.Concat(row[7]); - if (max_length == 0) max_length = -1; - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } - loc3[table_id].Add(column, new DbColumnInfo { - Name = column, - MaxLength = max_length, - IsIdentity = is_identity, - IsNullable = is_nullable, - IsPrimary = false, - DbTypeText = type, - DbTypeTextFull = sqlType, - Table = loc2[table_id], - Coment = comment - }); - loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); - loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); - } + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + if (max_length == 0) max_length = -1; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } - sql = string.Format(@" + sql = string.Format(@" select concat(a.constraint_schema, '.', a.table_name) 'table_id', a.column_name, @@ -247,53 +262,59 @@ case when a.constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', from information_schema.key_column_usage a where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position_in_unique_constraint) ", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string index_id = string.Concat(row[2]); - bool is_unique = string.Concat(row[3]) == "1"; - bool is_primary_key = string.Concat(row[4]) == "1"; - bool is_clustered = string.Concat(row[5]) == "1"; - int is_desc = int.Parse(string.Concat(row[6])); - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + int is_desc = int.Parse(string.Concat(row[6])); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; - if (!indexColumns.TryGetValue(table_id, out loc10)) - indexColumns.Add(table_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - if (is_unique && !is_primary_key) { - if (!uniqueColumns.TryGetValue(table_id, out loc10)) - uniqueColumns.Add(table_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - } - } - foreach (string table_id in indexColumns.Keys) { - foreach (var column in indexColumns[table_id]) - loc2[table_id].IndexesDict.Add(column.Key, column.Value); - } - foreach (string table_id in uniqueColumns.Keys) { - foreach (var column in uniqueColumns[table_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[table_id].UniquesDict.Add(column.Key, column.Value); - } - } + Dictionary> loc10 = null; + List loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } - sql = string.Format(@" + sql = string.Format(@" select concat(a.constraint_schema, '.', a.table_name) 'table_id', a.column_name, @@ -304,80 +325,91 @@ a.referenced_column_name 'ref_column' from information_schema.key_column_usage a where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(position_in_unique_constraint) ", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + var fkColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); - } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); - foreach (var table_id in loc3.Keys) { - foreach (var loc5 in loc3[table_id].Values) { - loc2[table_id].Columns.Add(loc5); - if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); - if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); - } - } - foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) { - foreach (var loc5 in loc4.UniquesDict.First().Value) { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } - loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc4.Columns.Sort((c1, c2) => { - int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); - if (compare == 0) { - bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); - bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); - compare = b2.CompareTo(b1); - } - if (compare == 0) compare = c1.Name.CompareTo(c2.Name); - return compare; - }); - loc1.Add(loc4); - } - loc1.Sort((t1, t2) => { - var ret = t1.Schema.CompareTo(t2.Schema); - if (ret == 0) ret = t1.Name.CompareTo(t2.Name); - return ret; - }); + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + { + foreach (var loc5 in loc4.UniquesDict.First().Value) + { + loc5.IsPrimary = true; + loc4.Primarys.Add(loc5); + } + } + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); - loc2.Clear(); - loc3.Clear(); - return loc1; - } + loc2.Clear(); + loc3.Clear(); + return loc1; + } - public List GetEnumsByDatabase(params string[] database) { - return new List(); - } - } + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 1f67704f..10b93e5a 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -7,392 +7,447 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.MySql { - class MySqlExpression : CommonExpression { +namespace FreeSql.MySql +{ + class MySqlExpression : CommonExpression + { - public MySqlExpression(CommonUtils common) : base(common) { } + public MySqlExpression(CommonUtils common) : base(common) { } - public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.NodeType) { - case ExpressionType.Convert: - var operandExp = (exp as UnaryExpression)?.Operand; - var gentype = exp.Type.NullableTypeOrThis(); - if (gentype != operandExp.Type.NullableTypeOrThis()) { - switch (gentype.ToString()) { - case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; - case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)"; - case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)"; - case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; - case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; - case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; - case "System.Int16": - case "System.Int32": - case "System.Int64": - case "System.SByte": return $"cast({getExp(operandExp)} as signed)"; - case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; - case "System.String": return $"cast({getExp(operandExp)} as char)"; - case "System.UInt16": - case "System.UInt32": - case "System.UInt64": return $"cast({getExp(operandExp)} as unsigned)"; - case "System.Guid": return $"substr(cast({getExp(operandExp)} as char), 1, 36)"; - } - } - break; - case ExpressionType.Call: - var callExp = exp as MethodCallExpression; + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)"; + case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)"; + case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as signed)"; + case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; + case "System.String": return $"cast({getExp(operandExp)} as char)"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(operandExp)} as unsigned)"; + case "System.Guid": return $"substr(cast({getExp(operandExp)} as char), 1, 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; - switch (callExp.Method.Name) { - case "Parse": - case "TryParse": - switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { - case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; - case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; - case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)"; - case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; - case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; - case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; - case "System.Int16": - case "System.Int32": - case "System.Int64": - case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as signed)"; - case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; - case "System.UInt16": - case "System.UInt32": - case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; - case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)"; - } - break; - case "NewGuid": - break; - case "Next": - if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)"; - break; - case "NextDouble": - if (callExp.Object?.Type == typeof(Random)) return "rand()"; - break; - case "Random": - if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; - break; - case "ToString": - if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as char)"; - break; - } + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; + case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)"; + case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as signed)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; + case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)"; + } + break; + case "NewGuid": + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "rand()"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; + break; + case "ToString": + if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as char)"; + break; + } - var objExp = callExp.Object; - var objType = objExp?.Type; - if (objType?.FullName == "System.Byte[]") return null; + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; - var argIndex = 0; - if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) { - objExp = callExp.Arguments.FirstOrDefault(); - objType = objExp?.Type; - argIndex++; - } - if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) { - var left = objExp == null ? null : getExp(objExp); - switch (callExp.Method.Name) { - case "Contains": - //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; - } - } - break; - case ExpressionType.NewArrayInit: - var arrExp = exp as NewArrayExpression; - var arrSb = new StringBuilder(); - arrSb.Append("("); - for (var a = 0; a < arrExp.Expressions.Count; a++) { - if (a > 0) arrSb.Append(","); - arrSb.Append(getExp(arrExp.Expressions[a])); - } - if (arrSb.Length == 1) arrSb.Append("NULL"); - return arrSb.Append(")").ToString(); - case ExpressionType.ListInit: - var listExp = exp as ListInitExpression; - var listSb = new StringBuilder(); - listSb.Append("("); - for (var a = 0; a < listExp.Initializers.Count; a++) { - if (listExp.Initializers[a].Arguments.Any() == false) continue; - if (a > 0) listSb.Append(","); - listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); - } - if (listSb.Length == 1) listSb.Append("NULL"); - return listSb.Append(")").ToString(); - case ExpressionType.New: - var newExp = exp as NewExpression; - if (typeof(IList).IsAssignableFrom(newExp.Type)) { - if (newExp.Arguments.Count == 0) return "(NULL)"; - if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; - return getExp(newExp.Arguments[0]); - } - return null; - } - return null; - } + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in + return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } - public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Empty": return "''"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Length": return $"char_length({left})"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Now": return "now()"; - case "UtcNow": return "utc_timestamp()"; - case "Today": return "curdate()"; - case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)"; - case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Date": return $"cast(date_format({left},'%Y-%m-%d') as datetime)"; - case "TimeOfDay": return $"timestampdiff(microsecond, date_format({left},'%Y-%m-%d'), {left})"; - case "DayOfWeek": return $"(dayofweek({left})-1)"; - case "Day": return $"dayofmonth({left})"; - case "DayOfYear": return $"dayofyear({left})"; - case "Month": return $"month({left})"; - case "Year": return $"year({left})"; - case "Hour": return $"hour({left})"; - case "Minute": return $"minute({left})"; - case "Second": return $"second({left})"; - case "Millisecond": return $"floor(microsecond({left})/1000)"; - case "Ticks": return $"(timestampdiff(microsecond, '0001-1-1', {left})*10)"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Zero": return "0"; - case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 - case "MaxValue": return "922337203685477580"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Days": return $"(({left}) div {(long)1000000 * 60 * 60 * 24})"; - case "Hours": return $"(({left}) div {(long)1000000 * 60 * 60} mod 24)"; - case "Milliseconds": return $"(({left}) div 1000 mod 1000)"; - case "Minutes": return $"(({left}) div {(long)1000000 * 60} mod 60)"; - case "Seconds": return $"(({left}) div 1000000 mod 60)"; - case "Ticks": return $"(({left}) * 10)"; - case "TotalDays": return $"(({left}) / {(long)1000000 * 60 * 60 * 24})"; - case "TotalHours": return $"(({left}) / {(long)1000000 * 60 * 60})"; - case "TotalMilliseconds": return $"(({left}) / 1000)"; - case "TotalMinutes": return $"(({left}) / {(long)1000000 * 60})"; - case "TotalSeconds": return $"(({left}) / 1000000)"; - } - return null; - } + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "now()"; + case "UtcNow": return "utc_timestamp()"; + case "Today": return "curdate()"; + case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)"; + case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"cast(date_format({left},'%Y-%m-%d') as datetime)"; + case "TimeOfDay": return $"timestampdiff(microsecond, date_format({left},'%Y-%m-%d'), {left})"; + case "DayOfWeek": return $"(dayofweek({left})-1)"; + case "Day": return $"dayofmonth({left})"; + case "DayOfYear": return $"dayofyear({left})"; + case "Month": return $"month({left})"; + case "Year": return $"year({left})"; + case "Hour": return $"hour({left})"; + case "Minute": return $"minute({left})"; + case "Second": return $"second({left})"; + case "Millisecond": return $"floor(microsecond({left})/1000)"; + case "Ticks": return $"(timestampdiff(microsecond, '0001-1-1', {left})*10)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"(({left}) div {(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"(({left}) div {(long)1000000 * 60 * 60} mod 24)"; + case "Milliseconds": return $"(({left}) div 1000 mod 1000)"; + case "Minutes": return $"(({left}) div {(long)1000000 * 60} mod 60)"; + case "Seconds": return $"(({left}) div 1000000 mod 60)"; + case "Ticks": return $"(({left}) * 10)"; + case "TotalDays": return $"(({left}) / {(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left}) / {(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left}) / 1000)"; + case "TotalMinutes": return $"(({left}) / {(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left}) / 1000000)"; + } + return null; + } - public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "IsNullOrEmpty": - var arg1 = getExp(exp.Arguments[0]); - return $"({arg1} is null or {arg1} = '')"; - case "Concat": - return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); - } - } else { - var left = getExp(exp.Object); - switch (exp.Method.Name) { - case "StartsWith": - case "EndsWith": - case "Contains": - var args0Value = getExp(exp.Arguments[0]); - if (args0Value == "NULL") return $"({left}) IS NULL"; - if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}"; - if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) LIKE concat('%', {args0Value}, '%')"; - case "ToLower": return $"lower({left})"; - case "ToUpper": return $"upper({left})"; - case "Substring": - var substrArgs1 = getExp(exp.Arguments[0]); - if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); - else substrArgs1 += "+1"; - if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; - return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; - case "IndexOf": - var indexOfFindStr = getExp(exp.Arguments[0]); - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") { - var locateArgs1 = getExp(exp.Arguments[1]); - if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); - else locateArgs1 += "+1"; - return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)"; - } - return $"(locate({left}, {indexOfFindStr})-1)"; - case "PadLeft": - if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; - return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "PadRight": - if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; - return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Trim": - case "TrimStart": - case "TrimEnd": - if (exp.Arguments.Count == 0) { - if (exp.Method.Name == "Trim") return $"trim({left})"; - if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; - if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; - } - foreach (var argsTrim02 in exp.Arguments) { - var argsTrim01s = new[] { argsTrim02 }; - if (argsTrim02.NodeType == ExpressionType.NewArrayInit) { - var arritem = argsTrim02 as NewArrayExpression; - argsTrim01s = arritem.Expressions.ToArray(); - } - foreach (var argsTrim01 in argsTrim01s) { - if (exp.Method.Name == "Trim") left = $"trim({getExp(argsTrim01)} from {left})"; - if (exp.Method.Name == "TrimStart") left = $"trim(leading {getExp(argsTrim01)} from {left})"; - if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {getExp(argsTrim01)} from {left})"; - } - } - return left; - case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "CompareTo": return $"strcmp({left}, {getExp(exp.Arguments[0])})"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - } - } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.Method.Name) { - case "Abs": return $"abs({getExp(exp.Arguments[0])})"; - case "Sign": return $"sign({getExp(exp.Arguments[0])})"; - case "Floor": return $"floor({getExp(exp.Arguments[0])})"; - case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; - case "Round": - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - return $"round({getExp(exp.Arguments[0])})"; - case "Exp": return $"exp({getExp(exp.Arguments[0])})"; - case "Log": return $"log({getExp(exp.Arguments[0])})"; - case "Log10": return $"log10({getExp(exp.Arguments[0])})"; - case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; - case "Cos": return $"cos({getExp(exp.Arguments[0])})"; - case "Sin": return $"sin({getExp(exp.Arguments[0])})"; - case "Tan": return $"tan({getExp(exp.Arguments[0])})"; - case "Acos": return $"acos({getExp(exp.Arguments[0])})"; - case "Asin": return $"asin({getExp(exp.Arguments[0])})"; - case "Atan": return $"atan({getExp(exp.Arguments[0])})"; - case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)"; - } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; - case "DaysInMonth": return $"dayofmonth(last_day(concat({getExp(exp.Arguments[0])}, '-', {getExp(exp.Arguments[1])}, '-01')))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE concat('%', {args0Value}, '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)"; + } + return $"(locate({left}, {indexOfFindStr})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim({getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"trim(leading {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {getExp(argsTrim01)} from {left})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"strcmp({left}, {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)"; + } + throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"dayofmonth(last_day(concat({getExp(exp.Arguments[0])}, '-', {getExp(exp.Arguments[1])}, '-01')))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "IsLeapYear": - var isLeapYearArgs1 = getExp(exp.Arguments[0]); - return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"date_add({left}, interval ({args1}) microsecond)"; - case "AddDays": return $"date_add({left}, interval ({args1}) day)"; - case "AddHours": return $"date_add({left}, interval ({args1}) hour)"; - case "AddMilliseconds": return $"date_add({left}, interval ({args1})*1000 microsecond)"; - case "AddMinutes": return $"date_add({left}, interval ({args1}) minute)"; - case "AddMonths": return $"date_add({left}, interval ({args1}) month)"; - case "AddSeconds": return $"date_add({left}, interval ({args1}) second)"; - case "AddTicks": return $"date_add({left}, interval ({args1})/10 microsecond)"; - case "AddYears": return $"date_add({left}, interval ({args1}) year)"; - case "Subtract": - switch((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { - case "System.DateTime": return $"timestampdiff(microsecond, {args1}, {left})"; - case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)"; - } - break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; - case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; - } - } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; - case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; - case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; - case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; - case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; - case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as signed)"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as signed)"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"({left}+{args1})"; - case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; - case "ToString": return $"cast({left} as char)"; - } - } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; - case "ToByte": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; - case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)"; - case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; - case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; - case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; - case "ToInt16": - case "ToInt32": - case "ToInt64": - case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as signed)"; - case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; - case "ToString": return $"cast({getExp(exp.Arguments[0])} as char)"; - case "ToUInt16": - case "ToUInt32": - case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; - } - } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); - } - } + case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"date_add({left}, interval ({args1}) microsecond)"; + case "AddDays": return $"date_add({left}, interval ({args1}) day)"; + case "AddHours": return $"date_add({left}, interval ({args1}) hour)"; + case "AddMilliseconds": return $"date_add({left}, interval ({args1})*1000 microsecond)"; + case "AddMinutes": return $"date_add({left}, interval ({args1}) minute)"; + case "AddMonths": return $"date_add({left}, interval ({args1}) month)"; + case "AddSeconds": return $"date_add({left}, interval ({args1}) second)"; + case "AddTicks": return $"date_add({left}, interval ({args1})/10 microsecond)"; + case "AddYears": return $"date_add({left}, interval ({args1}) year)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"timestampdiff(microsecond, {args1}, {left})"; + case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)"; + } + break; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; + case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; + } + } + throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as signed)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as signed)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "ToString": return $"cast({left} as char)"; + } + } + throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; + case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)"; + case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as signed)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; + case "ToString": return $"cast({getExp(exp.Arguments[0])} as char)"; + case "ToUInt16": + case "ToUInt32": + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; + } + } + throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + } + } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs b/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs index ad1bf1f1..38857891 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs @@ -1,11 +1,12 @@ -public static partial class FreeSqlGlobalExtensions { +public static partial class FreeSqlGlobalExtensions +{ - /// - /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 - /// - /// - /// - /// - public static string FormatMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args); - static FreeSql.MySql.MySqlAdo _mysqlAdo = new FreeSql.MySql.MySqlAdo(); + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args); + static FreeSql.MySql.MySqlAdo _mysqlAdo = new FreeSql.MySql.MySqlAdo(); } diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index 461274fc..f53a0ebe 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -6,72 +6,80 @@ using System.Collections.Generic; using System.Data.Common; using System.Linq.Expressions; -namespace FreeSql.MySql { +namespace FreeSql.MySql +{ - public class MySqlProvider : IFreeSql { + public class MySqlProvider : IFreeSql + { - static MySqlProvider() { - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPoint)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisLineString)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPolygon)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPoint)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiLineString)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPolygon)] = true; + static MySqlProvider() + { + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPoint)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisLineString)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPolygon)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPoint)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiLineString)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPolygon)] = true; - var MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) }); - Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => { - switch (typeFullName) { - case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint))); - case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString))); - case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon))); - case "MygisMultiPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPoint))); - case "MygisMultiLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiLineString))); - case "MygisMultiPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPolygon))); - } - return null; - }); - } + var MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) }); + Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => + { + switch (typeFullName) + { + case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint))); + case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString))); + case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon))); + case "MygisMultiPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPoint))); + case "MygisMultiLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiLineString))); + case "MygisMultiPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPolygon))); + } + return null; + }); + } - public ISelect Select() where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new MySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public ISelect Select() where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new MySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } - public MySqlProvider(string masterConnectionString, string[] slaveConnectionString) { - this.InternalCommonUtils = new MySqlUtils(this); - this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils); + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public MySqlProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new MySqlUtils(this); + this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils); - this.Ado = new MySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); - this.Aop = new AopProvider(); + this.Ado = new MySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); - this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - this.CodeFirst = new MySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - } + this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new MySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } - public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); - ~MySqlProvider() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - (this.Ado as AdoProvider)?.Dispose(); - } - } + ~MySqlProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 3b6eb16b..2afaf09e 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -9,97 +9,119 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; -namespace FreeSql.MySql { +namespace FreeSql.MySql +{ - class MySqlUtils : CommonUtils { - public MySqlUtils(IFreeSql orm) : base(orm) { - } + class MySqlUtils : CommonUtils + { + public MySqlUtils(IFreeSql orm) : base(orm) + { + } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { - if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) { - if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { - ret.MySqlDbType = MySqlDbType.Text; - if (value != null) ret.Value = (value as MygisGeometry).AsText(); - } else - ret.MySqlDbType = (MySqlDbType)tp.Value; - } - _params?.Add(ret); - return ret; - } + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) + { + if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) + { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } + else + ret.MySqlDbType = (MySqlDbType)tp.Value; + } + _params?.Add(ret); + return ret; + } - public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, "?", (name, type, value) => { - var ret = new MySqlParameter { ParameterName = $"?{name}", Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) { - if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { - ret.MySqlDbType = MySqlDbType.Text; - if (value != null) ret.Value = (value as MygisGeometry).AsText(); - } else - ret.MySqlDbType = (MySqlDbType)tp.Value; - } - return ret; - }); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, "?", (name, type, value) => + { + var ret = new MySqlParameter { ParameterName = $"?{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) + { + if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) + { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } + else + ret.MySqlDbType = (MySqlDbType)tp.Value; + } + return ret; + }); - public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); - public override string QuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; - } - public override string TrimQuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; - } - public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; - public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; - public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; - public override string QuoteWriteParamter(Type type, string paramterName) { - switch (type.FullName) { - case "MygisPoint": - case "MygisLineString": - case "MygisPolygon": - case "MygisMultiPoint": - case "MygisMultiLineString": - case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})"; - } - return paramterName; - } + public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; + } + public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string QuoteWriteParamter(Type type, string paramterName) + { + switch (type.FullName) + { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})"; + } + return paramterName; + } - public override string QuoteReadColumn(Type type, string columnName) { - switch (type.FullName) { - case "MygisPoint": - case "MygisLineString": - case "MygisPolygon": - case "MygisMultiPoint": - case "MygisMultiLineString": - case "MygisMultiPolygon": return $"AsText({columnName})"; - } - return columnName; - } + public override string QuoteReadColumn(Type type, string columnName) + { + switch (type.FullName) + { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"AsText({columnName})"; + } + return columnName; + } - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { - if (value == null) return "NULL"; - if (type == typeof(byte[])) { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } - return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { - var ts = (TimeSpan)value; - value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; - } - return FormatSql("{0}", value, 1); - } - } + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); + } + else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; + } + return FormatSql("{0}", value, 1); + } + } } diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 37a02a57..2624d701 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -9,103 +9,127 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; -namespace FreeSql.MySql { +namespace FreeSql.MySql +{ - class MySqlUtils : CommonUtils { - public MySqlUtils(IFreeSql orm) : base(orm) { - } + class MySqlUtils : CommonUtils + { + public MySqlUtils(IFreeSql orm) : base(orm) + { + } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { - if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) { - if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { - ret.MySqlDbType = MySqlDbType.Text; - if (value != null) ret.Value = (value as MygisGeometry).AsText(); - } else { - ret.MySqlDbType = (MySqlDbType)tp.Value; - if (ret.MySqlDbType == MySqlDbType.Enum && value != null) - ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; - } - } - _params?.Add(ret); - return ret; - } + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) + { + if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) + { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } + else + { + ret.MySqlDbType = (MySqlDbType)tp.Value; + if (ret.MySqlDbType == MySqlDbType.Enum && value != null) + ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + } + } + _params?.Add(ret); + return ret; + } - public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { - var ret = new MySqlParameter { ParameterName = $"@{name}", Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) { - if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { - ret.MySqlDbType = MySqlDbType.Text; - if (value != null) ret.Value = (value as MygisGeometry).AsText(); - } else { - ret.MySqlDbType = (MySqlDbType)tp.Value; - if (ret.MySqlDbType == MySqlDbType.Enum && value != null) - ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; - } - } - return ret; - }); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => + { + var ret = new MySqlParameter { ParameterName = $"@{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) + { + if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) + { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } + else + { + ret.MySqlDbType = (MySqlDbType)tp.Value; + if (ret.MySqlDbType == MySqlDbType.Enum && value != null) + ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + } + } + return ret; + }); - public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); - public override string QuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; - } - public override string TrimQuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; - } - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; - public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; - public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; - public override string QuoteWriteParamter(Type type, string paramterName) { - switch (type.FullName) { - case "MygisPoint": - case "MygisLineString": - case "MygisPolygon": - case "MygisMultiPoint": - case "MygisMultiLineString": - case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})"; - } - return paramterName; - } + public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string QuoteWriteParamter(Type type, string paramterName) + { + switch (type.FullName) + { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})"; + } + return paramterName; + } - public override string QuoteReadColumn(Type type, string columnName) { - switch (type.FullName) { - case "MygisPoint": - case "MygisLineString": - case "MygisPolygon": - case "MygisMultiPoint": - case "MygisMultiLineString": - case "MygisMultiPolygon": return $"AsText({columnName})"; - } - return columnName; - } + public override string QuoteReadColumn(Type type, string columnName) + { + switch (type.FullName) + { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"AsText({columnName})"; + } + return columnName; + } - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { - if (value == null) return "NULL"; - if (type == typeof(byte[])) { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } - return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { - var ts = (TimeSpan)value; - value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; - } - return FormatSql("{0}", value, 1); - } - } + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); + } + else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; + } + return FormatSql("{0}", value, 1); + } + } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs index 7525b00e..3f6be169 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs @@ -5,18 +5,23 @@ using System.Data; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Oracle.Curd { +namespace FreeSql.Oracle.Curd +{ - class OracleDelete : Internal.CommonProvider.DeleteProvider where T1 : class { - public OracleDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + class OracleDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OracleDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override List ExecuteDeleted() { - throw new NotImplementedException(); - } - public override Task> ExecuteDeletedAsync() { - throw new NotImplementedException(); - } - } + public override List ExecuteDeleted() + { + throw new NotImplementedException(); + } + public override Task> ExecuteDeletedAsync() + { + throw new NotImplementedException(); + } + } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index a8b1e480..8daaf144 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -9,177 +9,214 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Oracle.Curd { +namespace FreeSql.Oracle.Curd +{ - class OracleInsert : Internal.CommonProvider.InsertProvider where T1 : class { - public OracleInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) - : base(orm, commonUtils, commonExpression) { - } + class OracleInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public OracleInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); - public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); - public override string ToSql() { - if (_source == null || _source.Any() == false) return null; - var sb = new StringBuilder(); - sb.Append("INSERT "); - if (_source.Count > 1) sb.Append("ALL"); + public override string ToSql() + { + if (_source == null || _source.Any() == false) return null; + var sb = new StringBuilder(); + sb.Append("INSERT "); + if (_source.Count > 1) sb.Append("ALL"); - _identCol = null; - var sbtb = new StringBuilder(); - sbtb.Append("INTO "); - sbtb.Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append("("); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity == true) { - _identCol = col; - continue; - } - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) { - if (colidx > 0) sbtb.Append(", "); - sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); - ++colidx; - } - } - sbtb.Append(") "); + _identCol = null; + var sbtb = new StringBuilder(); + sbtb.Append("INTO "); + sbtb.Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append("("); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity == true) + { + _identCol = col; + continue; + } + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) + { + if (colidx > 0) sbtb.Append(", "); + sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); + ++colidx; + } + } + sbtb.Append(") "); - _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; - var specialParams = new List(); - var didx = 0; - foreach (var d in _source) { - if (_source.Count > 1) sb.Append("\r\n"); - sb.Append(sbtb); - sb.Append("VALUES"); - sb.Append("("); - var colidx2 = 0; - foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) { - if (colidx2 > 0) sb.Append(", "); - object val = col.GetMapValue(d); - if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) - col.SetMapValue(d, val = FreeUtil.NewMongodbId()); - if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); - else { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); - } - ++colidx2; - } - } - sb.Append(")"); - ++didx; - } - if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); - return sb.ToString(); - } + _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; + var specialParams = new List(); + var didx = 0; + foreach (var d in _source) + { + if (_source.Count > 1) sb.Append("\r\n"); + sb.Append(sbtb); + sb.Append("VALUES"); + sb.Append("("); + var colidx2 = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) + { + if (colidx2 > 0) sb.Append(", "); + object val = col.GetMapValue(d); + if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) + col.SetMapValue(d, val = FreeUtil.NewMongodbId()); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); + } + ++colidx2; + } + } + sb.Append(")"); + ++didx; + } + if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); + return sb.ToString(); + } - ColumnInfo _identCol; - protected override long RawExecuteIdentity() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + ColumnInfo _identCol; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - long ret = 0; - Exception exception = null; - Aop.CurdBeforeEventArgs before = null; + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; - if (_identCol == null || _source.Count > 1) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return 0; - } - var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); - var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0) as OracleParameter; - identParam.Direction = ParameterDirection.Output; - sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; - var dbParms = _params.Concat(new[] { identParam }).ToArray(); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - try { - _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); - long.TryParse(string.Concat(identParam.Value), out ret); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task RawExecuteIdentityAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0) as OracleParameter; + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - long ret = 0; - Exception exception = null; - Aop.CurdBeforeEventArgs before = null; + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; - if (_identCol == null || _source.Count > 1) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return 0; - } - var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); - var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0) as OracleParameter; - identParam.Direction = ParameterDirection.Output; - sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; - var dbParms = _params.Concat(new[] { identParam }).ToArray(); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - long.TryParse(string.Concat(identParam.Value), out ret); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0) as OracleParameter; + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } - protected override List RawExecuteInserted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - this.RawExecuteAffrows(); - return _source; - } - async protected override Task> RawExecuteInsertedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + this.RawExecuteAffrows(); + return _source; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - await this.RawExecuteAffrowsAsync(); - return _source; - } - } + await this.RawExecuteAffrowsAsync(); + return _source; + } + } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 24dcecda..d11da9a0 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -6,135 +6,161 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.Oracle.Curd { +namespace FreeSql.Oracle.Curd +{ - class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { + class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) { - if (_orm.CodeFirst.IsAutoSyncStructure) - _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field); - if (string.IsNullOrEmpty(_orderby) && _skip > 0) sb.Append(", ROWNUM AS \"__rownum__\""); - sb.Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - } - break; - } else { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + var sb = new StringBuilder(); + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field); + if (string.IsNullOrEmpty(_orderby) && _skip > 0) sb.Append(", ROWNUM AS \"__rownum__\""); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); + else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); - sbnav.Append(_where); - foreach (var tb in _tables) { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } - if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) { - sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); - } - if (sbnav.Length > 0) { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); + sbnav.Append(_where); + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) + { + sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); - if (string.IsNullOrEmpty(_orderby)) { - if (_skip > 0) - sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); - } else { - if (_skip > 0 && _limit > 0) sb.Insert(0, "SELECT t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); - else if (_skip > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); - else if (_limit > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); - } + if (string.IsNullOrEmpty(_orderby)) + { + if (_skip > 0) + sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + } + else + { + if (_skip > 0 && _limit > 0) sb.Insert(0, "SELECT t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + else if (_skip > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); + else if (_limit > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); + } - sbnav.Clear(); - return sb.ToString(); - } + sbnav.Clear(); + return sb.ToString(); + } - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index 0347b8ca..7338509f 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -7,55 +7,66 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Oracle.Curd { +namespace FreeSql.Oracle.Curd +{ - class OracleUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { + class OracleUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { - public OracleUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + public OracleUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); - protected override List RawExecuteUpdated() { - throw new NotImplementedException(); - } - protected override Task> RawExecuteUpdatedAsync() { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() + { + throw new NotImplementedException(); + } + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } - protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { - if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); - return; - } - caseWhen.Append("("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(" || "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); - ++pkidx; - } - caseWhen.Append(")"); - } + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } - protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { - if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); - return; - } - sb.Append("("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(" || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); - ++pkidx; - } - sb.Append(")"); - } - } + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + ++pkidx; + } + sb.Append(")"); + } + } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 249be02a..db16fada 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -7,55 +7,64 @@ using System.Data.Common; using System.Text; using System.Threading; -namespace FreeSql.Oracle { - class OracleAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OracleAdo() : base(DataType.Oracle) { } - public OracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Oracle) { - base._util = util; - if (!string.IsNullOrEmpty(masterConnectionString)) - MasterPool = new OracleConnectionPool("主库", masterConnectionString, null, null); - if (slaveConnectionStrings != null) { - foreach (var slaveConnectionString in slaveConnectionStrings) { - var slavePool = new OracleConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); - SlavePools.Add(slavePool); - } - } - } - static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) { - if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) - param = Utils.GetDataReaderValue(mapType, param); - if (param is bool || param is bool?) - return (bool)param ? 1 : 0; - else if (param is string || param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - else if (param is Enum) - return ((Enum)param).ToInt64(); - else if (decimal.TryParse(string.Concat(param), out var trydec)) - return param; - else if (param is DateTime || param is DateTime?) - return string.Concat("to_timestamp('", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "','YYYY-MM-DD HH24:MI:SS.FF6')"); - else if (param is TimeSpan || param is TimeSpan?) - return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; - else if (param is IEnumerable) { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - //if (param is string) return string.Concat('N', nparms[a]); - } +namespace FreeSql.Oracle +{ + class OracleAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public OracleAdo() : base(DataType.Oracle) { } + public OracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Oracle) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OracleConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OracleConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("to_timestamp('", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "','YYYY-MM-DD HH24:MI:SS.FF6')"); + else if (param is TimeSpan || param is TimeSpan?) + return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + //if (param is string) return string.Concat('N', nparms[a]); + } - protected override DbCommand CreateCommand() { - return new OracleCommand(); - } + protected override DbCommand CreateCommand() + { + return new OracleCommand(); + } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { - (pool as OracleConnectionPool).Return(conn, ex); - } + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as OracleConnectionPool).Return(conn, ex); + } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); - } + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index 61b60d55..18b1502e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -9,183 +9,226 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; -namespace FreeSql.Oracle { +namespace FreeSql.Oracle +{ - class OracleConnectionPool : ObjectPool { + class OracleConnectionPool : ObjectPool + { - internal Action availableHandler; - internal Action unavailableHandler; - internal string UserId { get; set; } + internal Action availableHandler; + internal Action unavailableHandler; + internal string UserId { get; set; } - public OracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - var userIdMatch = Regex.Match(connectionString, @"User\s+Id\s*=\s*([^;]+)", RegexOptions.IgnoreCase); - if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 User\s+Id\s+=([^;]+)"); - this.UserId = userIdMatch.Groups[1].Value.Trim().ToUpper(); + public OracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var userIdMatch = Regex.Match(connectionString, @"User\s+Id\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 User\s+Id\s+=([^;]+)"); + this.UserId = userIdMatch.Groups[1].Value.Trim().ToUpper(); - var policy = new OracleConnectionPoolPolicy { - _pool = this, - Name = name - }; - this.Policy = policy; - policy.ConnectionString = connectionString; + var policy = new OracleConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; - } + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } - public void Return(Object obj, Exception exception, bool isRecreate = false) { - if (exception != null && exception is OracleException) { + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OracleException) + { - if (exception is System.IO.IOException) { + if (exception is System.IO.IOException) + { - base.SetUnavailable(exception); + base.SetUnavailable(exception); - } else if (obj.Value.Ping() == false) { + } + else if (obj.Value.Ping() == false) + { - base.SetUnavailable(exception); - } - } - base.Return(obj, isRecreate); - } - } + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } - class OracleConnectionPoolPolicy : IPolicy { + class OracleConnectionPoolPolicy : IPolicy + { - internal OracleConnectionPool _pool; - public string Name { get; set; } = "Oracle Connection 对象池"; - public int PoolSize { get; set; } = 100; - public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; - public int AsyncGetCapacity { get; set; } = 10000; - public bool IsThrowGetTimeoutException { get; set; } = true; - public int CheckAvailableInterval { get; set; } = 5; + internal OracleConnectionPool _pool; + public string Name { get; set; } = "Oracle Connection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; - static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - private string _connectionString; - public string ConnectionString { - get => _connectionString; - set { - _connectionString = value ?? ""; + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; - var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; - Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); - PoolSize = poolsize + connStrIncr; - _connectionString = m.Success ? - Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : - $"{_connectionString};Max pool size={PoolSize}"; + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; - pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - var minPoolSize = 0; - pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - minPoolSize = int.Parse(m.Groups[1].Value); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); - } - } + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } - public bool OnCheckAvailable(Object obj) { - if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); - return obj.Value.Ping(true); - } + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } - public DbConnection OnCreate() { - var conn = new OracleConnection(_connectionString); - return conn; - } + public DbConnection OnCreate() + { + var conn = new OracleConnection(_connectionString); + return conn; + } - public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); - obj.Dispose(); - } + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } - public void OnGet(Object obj) { + public void OnGet(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { - try { - obj.Value.Open(); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - async public Task OnGetAsync(Object obj) { + async public Task OnGetAsync(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { - try { - await obj.Value.OpenAsync(); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - public void OnGetTimeout() { + public void OnGetTimeout() + { - } + } - public void OnReturn(Object obj) { + public void OnReturn(Object obj) + { - } + } - public void OnAvailable() { - _pool.availableHandler?.Invoke(); - } + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } - public void OnUnavailable() { - _pool.unavailableHandler?.Invoke(); - } - } + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } - static class DbConnectionExtensions { + static class DbConnectionExtensions + { - static DbCommand PingCommand(DbConnection conn) { - var cmd = conn.CreateCommand(); - cmd.CommandTimeout = 5; - cmd.CommandText = "select 1 from dual"; - return cmd; - } - public static bool Ping(this DbConnection that, bool isThrow = false) { - try { - PingCommand(that).ExecuteNonQuery(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - async public static Task PingAsync(this DbConnection that, bool isThrow = false) { - try { - await PingCommand(that).ExecuteNonQueryAsync(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - } + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1 from dual"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 7d59e1c1..ec8f0dc9 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -11,126 +11,143 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; -namespace FreeSql.Oracle { +namespace FreeSql.Oracle +{ - class OracleCodeFirst : Internal.CommonProvider.CodeFirstProvider { + class OracleCodeFirst : Internal.CommonProvider.CodeFirstProvider + { - public OracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + public OracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } - static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (OracleDbType.Boolean, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OracleDbType.Boolean, "number","number(1) NULL", null, true, null) }, + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (OracleDbType.Boolean, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OracleDbType.Boolean, "number","number(1) NULL", null, true, null) }, - { typeof(sbyte).FullName, (OracleDbType.Decimal, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OracleDbType.Decimal, "number", "number(4) NULL", false, true, null) }, - { typeof(short).FullName, (OracleDbType.Int16, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OracleDbType.Int16, "number", "number(6) NULL", false, true, null) }, - { typeof(int).FullName, (OracleDbType.Int32, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OracleDbType.Int32, "number", "number(11) NULL", false, true, null) }, - { typeof(long).FullName, (OracleDbType.Int64, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OracleDbType.Int64, "number","number(21) NULL", false, true, null) }, + { typeof(sbyte).FullName, (OracleDbType.Decimal, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OracleDbType.Decimal, "number", "number(4) NULL", false, true, null) }, + { typeof(short).FullName, (OracleDbType.Int16, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OracleDbType.Int16, "number", "number(6) NULL", false, true, null) }, + { typeof(int).FullName, (OracleDbType.Int32, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OracleDbType.Int32, "number", "number(11) NULL", false, true, null) }, + { typeof(long).FullName, (OracleDbType.Int64, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OracleDbType.Int64, "number","number(21) NULL", false, true, null) }, - { typeof(byte).FullName, (OracleDbType.Byte, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OracleDbType.Byte, "number","number(3) NULL", true, true, null) }, - { typeof(ushort).FullName, (OracleDbType.Decimal, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OracleDbType.Decimal, "number", "number(5) NULL", true, true, null) }, - { typeof(uint).FullName, (OracleDbType.Decimal, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OracleDbType.Decimal, "number", "number(10) NULL", true, true, null) }, - { typeof(ulong).FullName, (OracleDbType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OracleDbType.Decimal, "number", "number(20) NULL", true, true, null) }, + { typeof(byte).FullName, (OracleDbType.Byte, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OracleDbType.Byte, "number","number(3) NULL", true, true, null) }, + { typeof(ushort).FullName, (OracleDbType.Decimal, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OracleDbType.Decimal, "number", "number(5) NULL", true, true, null) }, + { typeof(uint).FullName, (OracleDbType.Decimal, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OracleDbType.Decimal, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong).FullName, (OracleDbType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OracleDbType.Decimal, "number", "number(20) NULL", true, true, null) }, - { typeof(double).FullName, (OracleDbType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OracleDbType.Double, "float", "float(126) NULL", false, true, null) }, - { typeof(float).FullName, (OracleDbType.Single, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OracleDbType.Single, "float","float(63) NULL", false, true, null) }, - { typeof(decimal).FullName, (OracleDbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OracleDbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + { typeof(double).FullName, (OracleDbType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OracleDbType.Double, "float", "float(126) NULL", false, true, null) }, + { typeof(float).FullName, (OracleDbType.Single, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OracleDbType.Single, "float","float(63) NULL", false, true, null) }, + { typeof(decimal).FullName, (OracleDbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OracleDbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, - { typeof(TimeSpan).FullName, (OracleDbType.IntervalDS, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OracleDbType.IntervalDS, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, - { typeof(DateTime).FullName, (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NULL", false, true, null) }, - { typeof(DateTimeOffset).FullName, (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, + { typeof(TimeSpan).FullName, (OracleDbType.IntervalDS, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OracleDbType.IntervalDS, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime).FullName, (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset).FullName, (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, - { typeof(byte[]).FullName, (OracleDbType.Blob, "blob", "blob NULL", false, null, new byte[0]) }, - { typeof(string).FullName, (OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(byte[]).FullName, (OracleDbType.Blob, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string).FullName, (OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, - { typeof(Guid).FullName, (OracleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OracleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, - }; + { typeof(Guid).FullName, (OracleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OracleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, + }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); - if (type.IsArray) return null; - var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); - if (enumType != null) { - var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OracleDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OracleDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); - if (_dicCsToDb.ContainsKey(type.FullName) == false) { - lock (_dicCsToDbLock) { - if (_dicCsToDb.ContainsKey(type.FullName) == false) - _dicCsToDb.Add(type.FullName, newItem); - } - } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); - } - return null; - } + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OracleDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OracleDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } - public override string GetComparisonDDLStatements(params Type[] entityTypes) { - var userId = (_orm.Ado.MasterPool as OracleConnectionPool).UserId; - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var userId = (_orm.Ado.MasterPool as OracleConnectionPool).UserId; + var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 - var sb = new StringBuilder(); - var sbDeclare = new StringBuilder(); - foreach (var entityType in entityTypes) { - if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); - if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; + var sb = new StringBuilder(); + var sbDeclare = new StringBuilder(); + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; - if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 - throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); + if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 + throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); - var sbalter = new StringBuilder(); - var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null) { //表不存在 - if (tboldname != null) { - if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tboldname)) == null) - //模式或表不存在 - tboldname = null; - } - if (tboldname == null) { - //创建表 - sb.Append("execute immediate 'CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); - } - if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk1 PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); - //备注 - foreach (var tbcol in tb.Columns.Values) { - if (string.IsNullOrEmpty(tbcol.Comment) == false) - sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); - } - continue; - } - //如果新表,旧表在一个模式下,直接修改表名 - if (string.Compare(tbname[0], tboldname[0], true) == 0) - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); - else { - //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 - istmpatler = true; - } - } else - tboldname = null; //如果新表已经存在,不走改表名逻辑 + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tboldname)) == null) + //模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + sb.Append("execute immediate 'CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk1 PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + continue; + } + //如果新表,旧表在一个模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 - //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = _commonUtils.FormatSql($@" + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql($@" select a.column_name, a.data_type, @@ -145,51 +162,58 @@ b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { - var sqlType = GetOracleSqlTypeFullName(a); - return new { - column = string.Concat(a[0]), - sqlType, - is_nullable = string.Concat(a[6]) == "1", - is_identity = string.Concat(a[7]) == "1" && string.Concat(a[8]) == "1", - comment = string.Concat(a[9]) - }; - }, StringComparer.CurrentCultureIgnoreCase); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var sqlType = GetOracleSqlTypeFullName(a); + return new + { + column = string.Concat(a[0]), + sqlType, + is_nullable = string.Concat(a[6]) == "1", + is_identity = string.Concat(a[7]) == "1" && string.Concat(a[8]) == "1", + comment = string.Concat(a[9]) + }; + }, StringComparer.CurrentCultureIgnoreCase); - if (istmpatler == false) { - foreach (var tbcol in tb.Columns.Values) { - var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) - istmpatler = true; - //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { - if (tbcol.Attribute.IsNullable == false) - sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); - } - if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) - //修改列名 - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); - if (isCommentChanged) - sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); - continue; - } - //添加列 - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); - if (tbcol.Attribute.IsNullable == false) { - sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append("';\r\n"); - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); - } - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); - } - var dsuksql = _commonUtils.FormatSql(@" + if (istmpatler == false) + { + foreach (var tbcol in tb.Columns.Values) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + istmpatler = true; + //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); + } + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); + if (isCommentChanged) + sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + continue; + } + //添加列 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable == false) + { + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append("';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); + } + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" select c.column_name, c.constraint_name @@ -202,139 +226,165 @@ and a.owner = c.owner and a.table_name = c.table_name and a.constraint_type in ('U') and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) { - if (dsukfind1.Any()) sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("';\r\n"); - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n"); - } - } - } - if (istmpatler == false) { - sb.Append(sbalter); - continue; - } - var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); - if (string.IsNullOrEmpty(oldpk) == false) - sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); + foreach (var uk in tb.Uniques) + { + if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + if (dsukfind1.Any()) sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); - //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); - //创建临时表 - sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); - } - if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk2 PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); - //备注 - foreach (var tbcol in tb.Columns.Values) { - if (string.IsNullOrEmpty(tbcol.Comment) == false) - sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); - } - sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) - sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.Columns.Values) { - var insertvalue = "NULL"; - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) { - var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); - insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; - } - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"nvl({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; - } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); - sb.Append(insertvalue.Replace("'", "''")).Append(", "); - } - sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); - sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n"); - sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); - } - Dictionary dicDeclare = new Dictionary(); - foreach (var seqcol in seqcols) { - var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); - var tiggerName = seqname + "TI"; - var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); - var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); - if (dicDeclare.ContainsKey(seqname) == false) { - sbDeclare.Append("\r\n").Append(seqname).Append("IS NUMBER; \r\n"); - dicDeclare.Add(seqname, true); - } - sb.Append(seqname).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(seqname).Append(_commonUtils.FormatSql("IS from user_sequences where sequence_name={0}; \r\n", seqname)) - .Append("if ").Append(seqname).Append("IS > 0 then \r\n") - .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") - .Append("end if; \r\n"); - if (seqcol.Item3) { - var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null ? 1 : - _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}"); - sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n"); - sb.Append("execute immediate 'CREATE OR REPLACE TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)) - .Append(" \r\nbefore insert on ").Append(tbname2) - .Append(" \r\nfor each row \r\nbegin\r\nselect ").Append(_commonUtils.QuoteSqlName(seqname)) - .Append(".nextval into :new.").Append(colname2).Append(" from dual;\r\nend;';\r\n"); - } else { - if (dicDeclare.ContainsKey(tiggerName) == false) { - sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); - dicDeclare.Add(tiggerName, true); - } - sb.Append(tiggerName).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) - .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") - .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") - .Append("end if; \r\n"); - } - } - if (sbDeclare.Length > 0) sbDeclare.Insert(0, "declare "); - return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString(); - } + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); + //创建临时表 + sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk2 PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.Columns.Values) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); + insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"nvl({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + sb.Append(insertvalue.Replace("'", "''")).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + } + Dictionary dicDeclare = new Dictionary(); + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var tiggerName = seqname + "TI"; + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + if (dicDeclare.ContainsKey(seqname) == false) + { + sbDeclare.Append("\r\n").Append(seqname).Append("IS NUMBER; \r\n"); + dicDeclare.Add(seqname, true); + } + sb.Append(seqname).Append("IS := 0; \r\n") + .Append(" select count(1) into ").Append(seqname).Append(_commonUtils.FormatSql("IS from user_sequences where sequence_name={0}; \r\n", seqname)) + .Append("if ").Append(seqname).Append("IS > 0 then \r\n") + .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") + .Append("end if; \r\n"); + if (seqcol.Item3) + { + var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null ? 1 : + _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}"); + sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n"); + sb.Append("execute immediate 'CREATE OR REPLACE TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)) + .Append(" \r\nbefore insert on ").Append(tbname2) + .Append(" \r\nfor each row \r\nbegin\r\nselect ").Append(_commonUtils.QuoteSqlName(seqname)) + .Append(".nextval into :new.").Append(colname2).Append(" from dual;\r\nend;';\r\n"); + } + else + { + if (dicDeclare.ContainsKey(tiggerName) == false) + { + sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); + dicDeclare.Add(tiggerName, true); + } + sb.Append(tiggerName).Append("IS := 0; \r\n") + .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") + .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") + .Append("end if; \r\n"); + } + } + if (sbDeclare.Length > 0) sbDeclare.Insert(0, "declare "); + return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString(); + } - internal static string GetOracleSqlTypeFullName(object[] row) { - var a = row; - var sqlType = string.Concat(a[1]).ToUpper(); - var data_length = long.Parse(string.Concat(a[2])); - long.TryParse(string.Concat(a[3]), out var data_precision); - long.TryParse(string.Concat(a[4]), out var data_scale); - var char_used = string.Concat(a[5]); - if (Regex.IsMatch(sqlType, @"INTERVAL DAY\(\d+\) TO SECOND\(\d+\)", RegexOptions.IgnoreCase)) { - } else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) { - } else if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) { - } else if (sqlType.StartsWith("BLOB")) { - } else if (char_used.ToLower() == "c") - sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; - else if (char_used.ToLower() == "b") - sqlType += $"({data_length} BYTE)"; - else if (sqlType.ToLower() == "float") - sqlType += $"({data_precision})"; - else if (data_precision > 0 && data_scale > 0) - sqlType += $"({data_precision},{data_scale})"; - else if (data_precision > 0) - sqlType += $"({data_precision})"; - else - sqlType += $"({data_length})"; - return sqlType; - } - } + internal static string GetOracleSqlTypeFullName(object[] row) + { + var a = row; + var sqlType = string.Concat(a[1]).ToUpper(); + var data_length = long.Parse(string.Concat(a[2])); + long.TryParse(string.Concat(a[3]), out var data_precision); + long.TryParse(string.Concat(a[4]), out var data_scale); + var char_used = string.Concat(a[5]); + if (Regex.IsMatch(sqlType, @"INTERVAL DAY\(\d+\) TO SECOND\(\d+\)", RegexOptions.IgnoreCase)) + { + } + else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) + { + } + else if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) + { + } + else if (sqlType.StartsWith("BLOB")) + { + } + else if (char_used.ToLower() == "c") + sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; + else if (char_used.ToLower() == "b") + sqlType += $"({data_length} BYTE)"; + else if (sqlType.ToLower() == "float") + sqlType += $"({data_precision})"; + else if (data_precision > 0 && data_scale > 0) + sqlType += $"({data_precision},{data_scale})"; + else if (data_precision > 0) + sqlType += $"({data_precision})"; + else + sqlType += $"({data_length})"; + return sqlType; + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 4d008622..4a3cf4e1 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -8,148 +8,158 @@ using System.Data; using System.Linq; using System.Text.RegularExpressions; -namespace FreeSql.Oracle { - class OracleDbFirst : IDbFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public OracleDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } +namespace FreeSql.Oracle +{ + class OracleDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public OracleDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } - public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); - OracleDbType GetSqlDbType(DbColumnInfo column) { - var dbfull = column.DbTypeTextFull.ToLower(); - switch (dbfull) { - case "number(1)": return OracleDbType.Boolean; + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + OracleDbType GetSqlDbType(DbColumnInfo column) + { + var dbfull = column.DbTypeTextFull.ToLower(); + switch (dbfull) + { + case "number(1)": return OracleDbType.Boolean; - case "number(4)": return OracleDbType.Decimal; - case "number(6)": return OracleDbType.Int16; - case "number(11)": return OracleDbType.Int32; - case "number(21)": return OracleDbType.Int64; + case "number(4)": return OracleDbType.Decimal; + case "number(6)": return OracleDbType.Int16; + case "number(11)": return OracleDbType.Int32; + case "number(21)": return OracleDbType.Int64; - case "number(3)": return OracleDbType.Byte; - case "number(5)": return OracleDbType.Decimal; - case "number(10)": return OracleDbType.Decimal; - case "number(20)": return OracleDbType.Decimal; + case "number(3)": return OracleDbType.Byte; + case "number(5)": return OracleDbType.Decimal; + case "number(10)": return OracleDbType.Decimal; + case "number(20)": return OracleDbType.Decimal; - case "float(126)": return OracleDbType.Double; - case "float(63)": return OracleDbType.Single; - case "number(10,2)": return OracleDbType.Decimal; + case "float(126)": return OracleDbType.Double; + case "float(63)": return OracleDbType.Single; + case "number(10,2)": return OracleDbType.Decimal; - case "interval day(2) to second(6)": return OracleDbType.IntervalDS; - case "timestamp(6)": return OracleDbType.TimeStamp; - case "timestamp(6) with local time zone": return OracleDbType.TimeStampLTZ; + case "interval day(2) to second(6)": return OracleDbType.IntervalDS; + case "timestamp(6)": return OracleDbType.TimeStamp; + case "timestamp(6) with local time zone": return OracleDbType.TimeStampLTZ; - case "blob": return OracleDbType.Blob; - case "nvarchar2(255)": return OracleDbType.NVarchar2; + case "blob": return OracleDbType.Blob; + case "nvarchar2(255)": return OracleDbType.NVarchar2; - case "char(36 char)": return OracleDbType.Char; - } - switch (column.DbTypeText.ToLower()) { - case "number": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(10,2)"]); - return OracleDbType.Decimal; - case "float": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); - return OracleDbType.Double; - case "interval day to second": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); - return OracleDbType.IntervalDS; - case "date": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["date(7)"]); - return OracleDbType.IntervalDS; - case "timestamp": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); - return OracleDbType.TimeStamp; - case "timestamp with local time zone": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6) with local time zone"]); - return OracleDbType.TimeStampLTZ; - case "blob": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); - return OracleDbType.Blob; - case "nvarchar2": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); - return OracleDbType.NVarchar2; - case "varchar2": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); - return OracleDbType.Varchar2; - case "char": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["char(36 char)"]); - return OracleDbType.Char; - case "clob": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); - return OracleDbType.Clob; - case "nclob": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); - return OracleDbType.NClob; - } - throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); - } + case "char(36 char)": return OracleDbType.Char; + } + switch (column.DbTypeText.ToLower()) + { + case "number": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(10,2)"]); + return OracleDbType.Decimal; + case "float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return OracleDbType.Double; + case "interval day to second": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); + return OracleDbType.IntervalDS; + case "date": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["date(7)"]); + return OracleDbType.IntervalDS; + case "timestamp": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); + return OracleDbType.TimeStamp; + case "timestamp with local time zone": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6) with local time zone"]); + return OracleDbType.TimeStampLTZ; + case "blob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OracleDbType.Blob; + case "nvarchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OracleDbType.NVarchar2; + case "varchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OracleDbType.Varchar2; + case "char": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["char(36 char)"]); + return OracleDbType.Char; + case "clob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OracleDbType.Clob; + case "nclob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OracleDbType.NClob; + } + throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); + } - static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(); - static OracleDbFirst() { - var defaultDbToCs = new Dictionary() { - { "number(1)", ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(); + static OracleDbFirst() + { + var defaultDbToCs = new Dictionary() { + { "number(1)", ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { "number(4)", ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, - { "number(6)", ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { "number(11)", ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { "number(21)", ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { "number(4)", ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { "number(6)", ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "number(11)", ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "number(21)", ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { "number(3)", ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { "number(5)", ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, - { "number(10)", ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, - { "number(20)", ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + { "number(3)", ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "number(5)", ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "number(10)", ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "number(20)", ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, - { "float(126)", ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { "float(63)", ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { "number(10,2)", ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { "float(126)", ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float(63)", ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "number(10,2)", ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { "interval day(2) to second(6)", ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { "date(7)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "timestamp(6)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "timestamp(6) with local time zone", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "interval day(2) to second(6)", ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date(7)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6) with local time zone", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "blob", ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { "blob", ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { "nvarchar2(255)", ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { "char(36 char)", ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, - }; - foreach (var kv in defaultDbToCs) - _dicDbToCs.TryAdd(kv.Key, kv.Value); - } - + { "nvarchar2(255)", ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "char(36 char)", ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } - public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; - public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null; - public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null; - public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; - public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null; - public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null; - public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null; - public List GetDatabases() { - var sql = @" select username from all_users"; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); - } + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null; - public List GetTablesByDatabase(params string[] database2) { - var loc1 = new List(); - var loc2 = new Dictionary(); - var loc3 = new Dictionary>(); - var database = database2?.ToArray(); + public List GetDatabases() + { + var sql = @" select username from all_users"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } - if (database == null || database.Any() == false) { - var userUsers = _orm.Ado.ExecuteScalar("select username from user_users")?.ToString(); - if (string.IsNullOrEmpty(userUsers)) return loc1; - database = new[] { userUsers }; - } - var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); - var sql = string.Format(@" + public List GetTablesByDatabase(params string[] database2) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + var database = database2?.ToArray(); + + if (database == null || database.Any() == false) + { + var userUsers = _orm.Ado.ExecuteScalar("select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + database = new[] { userUsers }; + } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); + var sql = string.Format(@" select a.owner || '.' || a.table_name, a.owner, @@ -159,38 +169,41 @@ b.comments, from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' where a.owner in ({0})", databaseIn); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); - foreach (var row in ds) { - var table_id = string.Concat(row[0]); - var schema = string.Concat(row[1]); - var table = string.Concat(row[2]); - var comment = string.Concat(row[3]); - var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - schema = ""; - } - loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); - loc3.Add(table_id, new Dictionary()); - switch (type) { - case DbTableType.TABLE: - case DbTableType.VIEW: - loc6.Add(table.Replace("'", "''")); - break; - case DbTableType.StoreProcedure: - loc66.Add(table.Replace("'", "''")); - break; - } - } - if (loc6.Count == 0) return loc1; - var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc6 = new List(); + var loc66 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6.Add(table.Replace("'", "''")); + break; + case DbTableType.StoreProcedure: + loc66.Add(table.Replace("'", "''")); + break; + } + } + if (loc6.Count == 0) return loc1; + var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; + var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; - sql = string.Format(@" + sql = string.Format(@" select a.owner || '.' || a.table_name, a.column_name, @@ -206,52 +219,56 @@ from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name where a.owner in ({1}) and a.table_name in ({0}) ", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var ds2 = new List(); - foreach (var row in ds) { - var ds2item = new object[8]; - ds2item[0] = row[0]; - ds2item[1] = row[1]; - ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); - ds2item[4] = OracleCodeFirst.GetOracleSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); - ds2item[5] = string.Concat(row[7]) == "1"; - ds2item[6] = string.Concat(row[8]) == "1"; - ds2item[7] = string.Concat(row[9]); - ds2.Add(ds2item); - } - foreach (var row in ds2) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string type = string.Concat(row[2]); - //long max_length = long.Parse(string.Concat(row[3])); - string sqlType = string.Concat(row[4]); - var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); - int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; - bool is_nullable = string.Concat(row[5]) == "1"; - bool is_identity = string.Concat(row[6]) == "1"; - string comment = string.Concat(row[7]); - if (max_length == 0) max_length = -1; - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } - loc3[table_id].Add(column, new DbColumnInfo { - Name = column, - MaxLength = max_length, - IsIdentity = is_identity, - IsNullable = is_nullable, - IsPrimary = false, - DbTypeText = type, - DbTypeTextFull = sqlType, - Table = loc2[table_id], - Coment = comment - }); - loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); - loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); - } + var ds2 = new List(); + foreach (var row in ds) + { + var ds2item = new object[8]; + ds2item[0] = row[0]; + ds2item[1] = row[1]; + ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); + ds2item[4] = OracleCodeFirst.GetOracleSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); + ds2item[5] = string.Concat(row[7]) == "1"; + ds2item[6] = string.Concat(row[8]) == "1"; + ds2item[7] = string.Concat(row[9]); + ds2.Add(ds2item); + } + foreach (var row in ds2) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + if (max_length == 0) max_length = -1; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } - sql = string.Format(@" + sql = string.Format(@" select a.owner || '.' || a.table_name, c.column_name, @@ -270,53 +287,59 @@ and a.table_name = c.table_name and a.constraint_type in ('P', 'U') and a.owner in ({1}) and a.table_name in ({0}) ", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string index_id = string.Concat(row[2]); - bool is_unique = string.Concat(row[3]) == "1"; - bool is_primary_key = string.Concat(row[4]) == "1"; - bool is_clustered = string.Concat(row[5]) == "1"; - int is_desc = int.Parse(string.Concat(row[6])); - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + int is_desc = int.Parse(string.Concat(row[6])); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; - if (!indexColumns.TryGetValue(table_id, out loc10)) - indexColumns.Add(table_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - if (is_unique && !is_primary_key) { - if (!uniqueColumns.TryGetValue(table_id, out loc10)) - uniqueColumns.Add(table_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - } - } - foreach (string table_id in indexColumns.Keys) { - foreach (var column in indexColumns[table_id]) - loc2[table_id].IndexesDict.Add(column.Key, column.Value); - } - foreach (string table_id in uniqueColumns.Keys) { - foreach (var column in uniqueColumns[table_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[table_id].UniquesDict.Add(column.Key, column.Value); - } - } + Dictionary> loc10 = null; + List loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } - sql = string.Format(@" + sql = string.Format(@" select a.owner || '.' || a.table_name, c.column_name, @@ -352,80 +375,91 @@ and b.owner = d.owner    and b.table_name = d.table_name and a.owner in ({1}) and a.table_name in ({0}) ", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + var fkColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); - } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); - foreach (var table_id in loc3.Keys) { - foreach (var loc5 in loc3[table_id].Values) { - loc2[table_id].Columns.Add(loc5); - if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); - if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); - } - } - foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) { - foreach (var loc5 in loc4.UniquesDict.First().Value) { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } - loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc4.Columns.Sort((c1, c2) => { - int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); - if (compare == 0) { - bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); - bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); - compare = b2.CompareTo(b1); - } - if (compare == 0) compare = c1.Name.CompareTo(c2.Name); - return compare; - }); - loc1.Add(loc4); - } - loc1.Sort((t1, t2) => { - var ret = t1.Schema.CompareTo(t2.Schema); - if (ret == 0) ret = t1.Name.CompareTo(t2.Name); - return ret; - }); + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + { + foreach (var loc5 in loc4.UniquesDict.First().Value) + { + loc5.IsPrimary = true; + loc4.Primarys.Add(loc5); + } + } + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); - loc2.Clear(); - loc3.Clear(); - return loc1; - } + loc2.Clear(); + loc3.Clear(); + return loc1; + } - public List GetEnumsByDatabase(params string[] database) { - return new List(); - } - } + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index f5f333c6..e4752a68 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -7,393 +7,449 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.Oracle { - class OracleExpression : CommonExpression { +namespace FreeSql.Oracle +{ + class OracleExpression : CommonExpression + { - public OracleExpression(CommonUtils common) : base(common) { } + public OracleExpression(CommonUtils common) : base(common) { } - public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.NodeType) { - case ExpressionType.Convert: - var operandExp = (exp as UnaryExpression)?.Operand; - var gentype = exp.Type.NullableTypeOrThis(); - if (gentype != operandExp.Type.NullableTypeOrThis()) { - switch (exp.Type.NullableTypeOrThis().ToString()) { - //case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; - case "System.Byte": return $"cast({getExp(operandExp)} as number)"; - case "System.Char": return $"substr(to_char({getExp(operandExp)}), 1, 1)"; - case "System.DateTime": return $"to_timestamp({getExp(operandExp)},'YYYY-MM-DD HH24:MI:SS.FF6')"; - case "System.Decimal": return $"cast({getExp(operandExp)} as number)"; - case "System.Double": return $"cast({getExp(operandExp)} as number)"; - case "System.Int16": - case "System.Int32": - case "System.Int64": - case "System.SByte": return $"cast({getExp(operandExp)} as number)"; - case "System.Single": return $"cast({getExp(operandExp)} as number)"; - case "System.String": return $"to_char({getExp(operandExp)})"; - case "System.UInt16": - case "System.UInt32": - case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; - case "System.Guid": return $"substr(to_char({getExp(operandExp)}), 1, 36)"; - } - } - break; - case ExpressionType.Call: - var callExp = exp as MethodCallExpression; + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as number)"; + case "System.Char": return $"substr(to_char({getExp(operandExp)}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(operandExp)},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(operandExp)} as number)"; + case "System.Double": return $"cast({getExp(operandExp)} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as number)"; + case "System.Single": return $"cast({getExp(operandExp)} as number)"; + case "System.String": return $"to_char({getExp(operandExp)})"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; + case "System.Guid": return $"substr(to_char({getExp(operandExp)}), 1, 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; - switch (callExp.Method.Name) { - case "Parse": - case "TryParse": - switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { - //case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; - case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Char": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 1)"; - case "System.DateTime": return $"to_timestamp({getExp(callExp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; - case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Int16": - case "System.Int32": - case "System.Int64": - case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.UInt16": - case "System.UInt32": - case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; - } - break; - case "NewGuid": - break; - case "Next": - if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; - break; - case "NextDouble": - if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; - break; - case "Random": - if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; - break; - case "ToString": - if (callExp.Object != null) return $"to_char({getExp(callExp.Object)})"; - break; - } + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Char": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(callExp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; + } + break; + case "NewGuid": + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; + break; + case "ToString": + if (callExp.Object != null) return $"to_char({getExp(callExp.Object)})"; + break; + } - var objExp = callExp.Object; - var objType = objExp?.Type; - if (objType?.FullName == "System.Byte[]") return null; + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; - var argIndex = 0; - if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) { - objExp = callExp.Arguments.FirstOrDefault(); - objType = objExp?.Type; - argIndex++; - } - if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) { - var left = objExp == null ? null : getExp(objExp); - switch (callExp.Method.Name) { - case "Contains": - //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; - } - } - break; - case ExpressionType.NewArrayInit: - var arrExp = exp as NewArrayExpression; - var arrSb = new StringBuilder(); - arrSb.Append("("); - for (var a = 0; a < arrExp.Expressions.Count; a++) { - if (a > 0) arrSb.Append(","); - arrSb.Append(getExp(arrExp.Expressions[a])); - } - if (arrSb.Length == 1) arrSb.Append("NULL"); - return arrSb.Append(")").ToString(); - case ExpressionType.ListInit: - var listExp = exp as ListInitExpression; - var listSb = new StringBuilder(); - listSb.Append("("); - for (var a = 0; a < listExp.Initializers.Count; a++) { - if (listExp.Initializers[a].Arguments.Any() == false) continue; - if (a > 0) listSb.Append(","); - listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); - } - if (listSb.Length == 1) listSb.Append("NULL"); - return listSb.Append(")").ToString(); - case ExpressionType.New: - var newExp = exp as NewExpression; - if (typeof(IList).IsAssignableFrom(newExp.Type)) { - if (newExp.Arguments.Count == 0) return "(NULL)"; - if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; - return getExp(newExp.Arguments[0]); - } - return null; - } - return null; - } + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in + return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } - public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Empty": return "''"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Length": return $"length({left})"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Now": return "systimestamp"; - case "UtcNow": return "sys_extract_utc(systimestamp)"; - case "Today": return "trunc(systimestamp)"; - case "MinValue": return "to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')"; - case "MaxValue": return "to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Date": return $"trunc({left})"; - case "TimeOfDay": return $"({left}-trunc({left}))"; - case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; - case "Day": return $"cast(to_char({left},'DD') as number)"; - case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; - case "Month": return $"cast(to_char({left},'MM') as number)"; - case "Year": return $"cast(to_char({left},'YYYY') as number)"; - case "Hour": return $"cast(to_char({left},'HH24') as number)"; - case "Minute": return $"cast(to_char({left},'MI') as number)"; - case "Second": return $"cast(to_char({left},'SS') as number)"; - case "Millisecond": return $"cast(to_char({left},'FF3') as number)"; - case "Ticks": return $"cast(to_char({left},'FF7') as number)"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Zero": return "numtodsinterval(0,'second')"; - case "MinValue": return "numtodsinterval(-233720368.5477580,'second')"; - case "MaxValue": return "numtodsinterval(233720368.5477580,'second')"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Days": return $"extract(day from {left})"; - case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; - case "Minutes": return $"extract(minute from {left})"; - case "Seconds": return $"floor(extract(second from {left}))"; - case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; - case "TotalDays": return $"extract(day from {left})"; - case "TotalHours": return $"(extract(day from {left})*24+extract(hour from {left}))"; - case "TotalMilliseconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*1000"; - case "TotalMinutes": return $"(extract(day from {left})*1440+extract(hour from {left})*60+extract(minute from {left}))"; - case "TotalSeconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))"; - } - return null; - } + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "systimestamp"; + case "UtcNow": return "sys_extract_utc(systimestamp)"; + case "Today": return "trunc(systimestamp)"; + case "MinValue": return "to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')"; + case "MaxValue": return "to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"trunc({left})"; + case "TimeOfDay": return $"({left}-trunc({left}))"; + case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; + case "Day": return $"cast(to_char({left},'DD') as number)"; + case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; + case "Month": return $"cast(to_char({left},'MM') as number)"; + case "Year": return $"cast(to_char({left},'YYYY') as number)"; + case "Hour": return $"cast(to_char({left},'HH24') as number)"; + case "Minute": return $"cast(to_char({left},'MI') as number)"; + case "Second": return $"cast(to_char({left},'SS') as number)"; + case "Millisecond": return $"cast(to_char({left},'FF3') as number)"; + case "Ticks": return $"cast(to_char({left},'FF7') as number)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "numtodsinterval(0,'second')"; + case "MinValue": return "numtodsinterval(-233720368.5477580,'second')"; + case "MaxValue": return "numtodsinterval(233720368.5477580,'second')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"extract(day from {left})"; + case "Hours": return $"extract(hour from {left})"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Minutes": return $"extract(minute from {left})"; + case "Seconds": return $"floor(extract(second from {left}))"; + case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; + case "TotalDays": return $"extract(day from {left})"; + case "TotalHours": return $"(extract(day from {left})*24+extract(hour from {left}))"; + case "TotalMilliseconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*1000"; + case "TotalMinutes": return $"(extract(day from {left})*1440+extract(hour from {left})*60+extract(minute from {left}))"; + case "TotalSeconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))"; + } + return null; + } - public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "IsNullOrEmpty": - var arg1 = getExp(exp.Arguments[0]); - return $"({arg1} is null or {arg1} = '')"; - case "Concat": - return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); - } - } else { - var left = getExp(exp.Object); - switch (exp.Method.Name) { - case "StartsWith": - case "EndsWith": - case "Contains": - var args0Value = getExp(exp.Arguments[0]); - if (args0Value == "NULL") return $"({left}) IS NULL"; - if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(to_char({args0Value})||'%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'||to_char({args0Value}))")}"; - if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) LIKE ('%'||to_char({args0Value})||'%')"; - case "ToLower": return $"lower({left})"; - case "ToUpper": return $"upper({left})"; - case "Substring": - var substrArgs1 = getExp(exp.Arguments[0]); - if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); - else substrArgs1 += "+1"; - if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; - return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; - case "IndexOf": - var indexOfFindStr = getExp(exp.Arguments[0]); - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") { - var locateArgs1 = getExp(exp.Arguments[1]); - if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); - else locateArgs1 += "+1"; - return $"(instr({left}, {indexOfFindStr}, {locateArgs1}, 1)-1)"; - } - return $"(instr({left}, {indexOfFindStr}, 1, 1))-1"; - case "PadLeft": - if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])}, ' ')"; - return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "PadRight": - if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])}, ' ')"; - return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Trim": - case "TrimStart": - case "TrimEnd": - if (exp.Arguments.Count == 0) { - if (exp.Method.Name == "Trim") return $"trim({left})"; - if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; - if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; - } - foreach (var argsTrim02 in exp.Arguments) { - var argsTrim01s = new[] { argsTrim02 }; - if (argsTrim02.NodeType == ExpressionType.NewArrayInit) { - var arritem = argsTrim02 as NewArrayExpression; - argsTrim01s = arritem.Expressions.ToArray(); - } - foreach (var argsTrim01 in argsTrim01s) { - if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})"; - if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})"; - if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})"; - } - } - return left; - case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - } - } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.Method.Name) { - case "Abs": return $"abs({getExp(exp.Arguments[0])})"; - case "Sign": return $"sign({getExp(exp.Arguments[0])})"; - case "Floor": return $"floor({getExp(exp.Arguments[0])})"; - case "Ceiling": return $"ceil({getExp(exp.Arguments[0])})"; - case "Round": - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - return $"round({getExp(exp.Arguments[0])})"; - case "Exp": return $"exp({getExp(exp.Arguments[0])})"; - case "Log": if (exp.Arguments.Count > 1) return $"log({getExp(exp.Arguments[1])},{getExp(exp.Arguments[0])})"; - return $"log(2.7182818284590451,{getExp(exp.Arguments[0])})"; - case "Log10": return $"log(10,{getExp(exp.Arguments[0])})"; - case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; - case "Cos": return $"cos({getExp(exp.Arguments[0])})"; - case "Sin": return $"sin({getExp(exp.Arguments[0])})"; - case "Tan": return $"tan({getExp(exp.Arguments[0])})"; - case "Acos": return $"acos({getExp(exp.Arguments[0])})"; - case "Asin": return $"asin({getExp(exp.Arguments[0])})"; - case "Atan": return $"atan({getExp(exp.Arguments[0])})"; - //case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; - } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; - case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(to_char({args0Value})||'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'||to_char({args0Value}))")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'||to_char({args0Value})||'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(instr({left}, {indexOfFindStr}, {locateArgs1}, 1)-1)"; + } + return $"(instr({left}, {indexOfFindStr}, 1, 1))-1"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceil({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": + if (exp.Arguments.Count > 1) return $"log({getExp(exp.Arguments[1])},{getExp(exp.Arguments[0])})"; + return $"log(2.7182818284590451,{getExp(exp.Arguments[0])})"; + case "Log10": return $"log(10,{getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + //case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "IsLeapYear": - var isLeapYearArgs1 = getExp(exp.Arguments[0]); - return $"(mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0)"; + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0)"; - case "Parse": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"({left}+{args1})"; - case "AddDays": return $"({left}+{args1})"; - case "AddHours": return $"({left}+({args1})/24)"; - case "AddMilliseconds": return $"({left}+({args1})/86400000)"; - case "AddMinutes": return $"({left}+({args1})/1440)"; - case "AddMonths": return $"add_months({left},{args1})"; - case "AddSeconds": return $"({left}+({args1})/86400)"; - case "AddTicks": return $"({left}+({args1})/864000000000)"; - case "AddYears": return $"add_months({left},({args1})*12)"; - case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { - case "System.DateTime": return $"({args1}-{left})"; - case "System.TimeSpan": return $"({left}-{args1})"; - } - break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; - case "ToString": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; - } - } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "FromDays": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60 * 24},'second')"; - case "FromHours": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60},'second')"; - case "FromMilliseconds": return $"numtodsinterval(({getExp(exp.Arguments[0])})/1000,'second')"; - case "FromMinutes": return $"numtodsinterval(({getExp(exp.Arguments[0])})*60,'second')"; - case "FromSeconds": return $"numtodsinterval(({getExp(exp.Arguments[0])}),'second')"; - case "FromTicks": return $"numtodsinterval(({getExp(exp.Arguments[0])})/10000000,'second')"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(7))"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(7))"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"({left}+{args1})"; - case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; - case "ToString": return $"to_char({left})"; - } - } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - //case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; - case "ToByte": return $"cast({getExp(exp.Arguments[0])} as number)"; - case "ToChar": return $"substr(to_char({getExp(exp.Arguments[0])}), 1, 1)"; - case "ToDateTime": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; - case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as number)"; - case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as number)"; - case "ToInt16": - case "ToInt32": - case "ToInt64": - case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as number)"; - case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as number)"; - case "ToString": return $"to_char({getExp(exp.Arguments[0])})"; - case "ToUInt16": - case "ToUInt32": - case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as number)"; - } - } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); - } - } + case "Parse": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "AddDays": return $"({left}+{args1})"; + case "AddHours": return $"({left}+({args1})/24)"; + case "AddMilliseconds": return $"({left}+({args1})/86400000)"; + case "AddMinutes": return $"({left}+({args1})/1440)"; + case "AddMonths": return $"add_months({left},{args1})"; + case "AddSeconds": return $"({left}+({args1})/86400)"; + case "AddTicks": return $"({left}+({args1})/864000000000)"; + case "AddYears": return $"add_months({left},({args1})*12)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"({args1}-{left})"; + case "System.TimeSpan": return $"({left}-{args1})"; + } + break; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; + case "ToString": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + } + } + throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60 * 24},'second')"; + case "FromHours": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60},'second')"; + case "FromMilliseconds": return $"numtodsinterval(({getExp(exp.Arguments[0])})/1000,'second')"; + case "FromMinutes": return $"numtodsinterval(({getExp(exp.Arguments[0])})*60,'second')"; + case "FromSeconds": return $"numtodsinterval(({getExp(exp.Arguments[0])}),'second')"; + case "FromTicks": return $"numtodsinterval(({getExp(exp.Arguments[0])})/10000000,'second')"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(7))"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(7))"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; + case "ToString": return $"to_char({left})"; + } + } + throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + //case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToChar": return $"substr(to_char({getExp(exp.Arguments[0])}), 1, 1)"; + case "ToDateTime": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToString": return $"to_char({getExp(exp.Arguments[0])})"; + case "ToUInt16": + case "ToUInt32": + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as number)"; + } + } + throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + } + } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs index 35c61de6..1d93ccaa 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs @@ -1,11 +1,12 @@ -public static partial class FreeSqlGlobalExtensions { +public static partial class FreeSqlGlobalExtensions +{ - /// - /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 - /// - /// - /// - /// - public static string FormatOracleSQL(this string that, params object[] args) => _oracleAdo.Addslashes(that, args); - static FreeSql.Oracle.OracleAdo _oracleAdo = new FreeSql.Oracle.OracleAdo(); + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatOracleSQL(this string that, params object[] args) => _oracleAdo.Addslashes(that, args); + static FreeSql.Oracle.OracleAdo _oracleAdo = new FreeSql.Oracle.OracleAdo(); } diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index 16ae24c3..28ad4744 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -5,50 +5,55 @@ using System; using System.Collections.Generic; using System.Data.Common; -namespace FreeSql.Oracle { +namespace FreeSql.Oracle +{ - public class OracleProvider : IFreeSql { + public class OracleProvider : IFreeSql + { - public ISelect Select() where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public ISelect Select() where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } - public OracleProvider(string masterConnectionString, string[] slaveConnectionString) { - this.InternalCommonUtils = new OracleUtils(this); - this.InternalCommonExpression = new OracleExpression(this.InternalCommonUtils); + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public OracleProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new OracleUtils(this); + this.InternalCommonExpression = new OracleExpression(this.InternalCommonUtils); - this.Ado = new OracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); - this.Aop = new AopProvider(); + this.Ado = new OracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); - this.DbFirst = new OracleDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - } + this.DbFirst = new OracleDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } - public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); - ~OracleProvider() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - (this.Ado as AdoProvider)?.Dispose(); - } - } + ~OracleProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 60b73a7c..c9deb887 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -7,70 +7,82 @@ using System.Data.Common; using System.Linq.Expressions; using System.Text; -namespace FreeSql.Oracle { +namespace FreeSql.Oracle +{ - class OracleUtils : CommonUtils { - public OracleUtils(IFreeSql orm) : base(orm) { - } + class OracleUtils : CommonUtils + { + public OracleUtils(IFreeSql orm) : base(orm) + { + } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { - if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; - if (dbtype == OracleDbType.Boolean) { - if (value == null) value = null; - else value = (bool)value == true ? 1 : 0; - dbtype = OracleDbType.Int16; - } - var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype, Value = value }; - _params?.Add(ret); - return ret; - } + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + if (dbtype == OracleDbType.Boolean) + { + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = OracleDbType.Int16; + } + var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype, Value = value }; + _params?.Add(ret); + return ret; + } - public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, ":", (name, type, value) => { - var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; - if (dbtype == OracleDbType.Boolean) { - if (value == null) value = null; - else value = (bool)value == true ? 1 : 0; - dbtype = OracleDbType.Int16; - } - var ret = new OracleParameter { ParameterName = $":{name}", OracleDbType = dbtype, Value = value }; - return ret; - }); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, ":", (name, type, value) => + { + var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + if (dbtype == OracleDbType.Boolean) + { + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = OracleDbType.Int16; + } + var ret = new OracleParameter { ParameterName = $":{name}", OracleDbType = dbtype, Value = value }; + return ret; + }); - public override string FormatSql(string sql, params object[] args) => sql?.FormatOracleSQL(args); - public override string QuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; - } - public override string TrimQuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; - } - public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; - public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; - public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; + public override string FormatSql(string sql, params object[] args) => sql?.FormatOracleSQL(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; - public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { - if (value == null) return "NULL"; - if (type == typeof(byte[])) { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("rawtohex('0x"); - foreach (var vc in bytes) { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } - return sb.Append("')").ToString(); - } - return FormatSql("{0}", value, 1); - } - } + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("rawtohex('0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.Append("')").ToString(); + } + return FormatSql("{0}", value, 1); + } + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index e7011753..251cc918 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -5,74 +5,91 @@ using System.Data; using System.Text; using System.Threading.Tasks; -namespace FreeSql.PostgreSQL.Curd { +namespace FreeSql.PostgreSQL.Curd +{ - class PostgreSQLDelete : Internal.CommonProvider.DeleteProvider where T1 : class { - public PostgreSQLDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + class PostgreSQLDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public PostgreSQLDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async public override Task> ExecuteDeletedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - } + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index 40e48e7c..3038a2c2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -6,159 +6,200 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.PostgreSQL.Curd { +namespace FreeSql.PostgreSQL.Curd +{ - class PostgreSQLInsert : Internal.CommonProvider.InsertProvider where T1 : class { - public PostgreSQLInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) - : base(orm, commonUtils, commonExpression) { - } + class PostgreSQLInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public PostgreSQLInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); - protected override long RawExecuteIdentity() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - long ret = 0; - Exception exception = null; - Aop.CurdBeforeEventArgs before = null; + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; - var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); - if (identCols.Any() == false) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return 0; - } - sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task RawExecuteIdentityAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - long ret = 0; - Exception exception = null; - Aop.CurdBeforeEventArgs before = null; + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; - var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); - if (identCols.Any() == false) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return 0; - } - sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } - protected override List RawExecuteInserted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task> RawExecuteInsertedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - } + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index d51e7fa7..d58b098e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -6,125 +6,147 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.PostgreSQL.Curd { +namespace FreeSql.PostgreSQL.Curd +{ - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) { - if (_orm.CodeFirst.IsAutoSyncStructure) - _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field).Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - } - break; - } else { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + var sb = new StringBuilder(); + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); + else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); - sbnav.Append(_where); - foreach (var tb in _tables) { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } - if (sbnav.Length > 0) { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); - if (_limit > 0) - sb.Append(" \r\nlimit ").Append(_limit); - if (_skip > 0) - sb.Append(" \r\noffset ").Append(_skip); + sbnav.Append(_where); + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_limit > 0) + sb.Append(" \r\nlimit ").Append(_limit); + if (_skip > 0) + sb.Append(" \r\noffset ").Append(_skip); - sbnav.Clear(); - return sb.ToString(); - } + sbnav.Clear(); + return sb.ToString(); + } - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 985faca3..ad9fce0b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -7,113 +7,136 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.PostgreSQL.Curd { +namespace FreeSql.PostgreSQL.Curd +{ - class PostgreSQLUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { + class PostgreSQLUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { - public PostgreSQLUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + public PostgreSQLUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); - protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task> RawExecuteUpdatedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } - protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { - if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); - return; - } - caseWhen.Append("("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(" || "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); - ++pkidx; - } - caseWhen.Append(")"); - } + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + ++pkidx; + } + caseWhen.Append(")"); + } - protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { - if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); - return; - } - sb.Append("("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(" || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); - ++pkidx; - } - sb.Append(")"); - } - } + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + ++pkidx; + } + sb.Append(")"); + } + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index b3940097..0c3b492e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -9,69 +9,80 @@ using System.Data.Common; using System.Text; using System.Threading; -namespace FreeSql.PostgreSQL { - class PostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public PostgreSQLAdo() : base(DataType.PostgreSQL) { } - public PostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.PostgreSQL) { - base._util = util; - if (!string.IsNullOrEmpty(masterConnectionString)) - MasterPool = new PostgreSQLConnectionPool("主库", masterConnectionString, null, null); - if (slaveConnectionStrings != null) { - foreach (var slaveConnectionString in slaveConnectionStrings) { - var slavePool = new PostgreSQLConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); - SlavePools.Add(slavePool); - } - } - } +namespace FreeSql.PostgreSQL +{ + class PostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public PostgreSQLAdo() : base(DataType.PostgreSQL) { } + public PostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.PostgreSQL) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new PostgreSQLConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new PostgreSQLConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } - static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) { - if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) - param = Utils.GetDataReaderValue(mapType, param); - bool isdic = false; - if (param is bool || param is bool?) - return (bool)param ? "'t'" : "'f'"; - else if (param is string || param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - else if (param is Enum) - return ((Enum)param).ToInt64(); - else if (decimal.TryParse(string.Concat(param), out var trydec)) - return param; - else if (param is DateTime || param is DateTime?) - return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); - else if (param is TimeSpan || param is TimeSpan?) - return ((TimeSpan)param).Ticks / 10; - else if (param is JToken || param is JObject || param is JArray) - return string.Concat("'", param.ToString().Replace("'", "''"), "'::jsonb"); - else if ((isdic = param is Dictionary) || - param is IEnumerable>) { - var pgdics = isdic ? param as Dictionary : - param as IEnumerable>; - if (pgdics == null) return string.Concat("''::hstore"); - var pghstore = new StringBuilder(); - pghstore.Append("'"); - foreach (var dic in pgdics) - pghstore.Append("\"").Append(dic.Key.Replace("'", "''")).Append("\"=>") - .Append(dic.Key.Replace("'", "''")).Append(","); - return pghstore.Append("'::hstore"); - } else if (param is IEnumerable) { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + bool isdic = false; + if (param is bool || param is bool?) + return (bool)param ? "'t'" : "'f'"; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is JToken || param is JObject || param is JArray) + return string.Concat("'", param.ToString().Replace("'", "''"), "'::jsonb"); + else if ((isdic = param is Dictionary) || + param is IEnumerable>) + { + var pgdics = isdic ? param as Dictionary : + param as IEnumerable>; + if (pgdics == null) return string.Concat("''::hstore"); + var pghstore = new StringBuilder(); + pghstore.Append("'"); + foreach (var dic in pgdics) + pghstore.Append("\"").Append(dic.Key.Replace("'", "''")).Append("\"=>") + .Append(dic.Key.Replace("'", "''")).Append(","); + return pghstore.Append("'::hstore"); + } + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } - protected override DbCommand CreateCommand() { - return new NpgsqlCommand(); - } + protected override DbCommand CreateCommand() + { + return new NpgsqlCommand(); + } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { - (pool as PostgreSQLConnectionPool).Return(conn, ex); - } + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as PostgreSQLConnectionPool).Return(conn, ex); + } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); - } + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index 3eba3ebf..cd145f8b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -9,178 +9,221 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; -namespace FreeSql.PostgreSQL { +namespace FreeSql.PostgreSQL +{ - class PostgreSQLConnectionPool : ObjectPool { + class PostgreSQLConnectionPool : ObjectPool + { - internal Action availableHandler; - internal Action unavailableHandler; + internal Action availableHandler; + internal Action unavailableHandler; - public PostgreSQLConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - var policy = new PostgreSQLConnectionPoolPolicy { - _pool = this, - Name = name - }; - this.Policy = policy; - policy.ConnectionString = connectionString; + public PostgreSQLConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new PostgreSQLConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; - } + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } - public void Return(Object obj, Exception exception, bool isRecreate = false) { - if (exception != null && exception is NpgsqlException) { + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is NpgsqlException) + { - if (exception is System.IO.IOException) { + if (exception is System.IO.IOException) + { - base.SetUnavailable(exception); + base.SetUnavailable(exception); - } else if (obj.Value.Ping() == false) { + } + else if (obj.Value.Ping() == false) + { - base.SetUnavailable(exception); - } - } - base.Return(obj, isRecreate); - } - } + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } - class PostgreSQLConnectionPoolPolicy : IPolicy { + class PostgreSQLConnectionPoolPolicy : IPolicy + { - internal PostgreSQLConnectionPool _pool; - public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池"; - public int PoolSize { get; set; } = 50; - public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; - public int AsyncGetCapacity { get; set; } = 10000; - public bool IsThrowGetTimeoutException { get; set; } = true; - public int CheckAvailableInterval { get; set; } = 5; + internal PostgreSQLConnectionPool _pool; + public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池"; + public int PoolSize { get; set; } = 50; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; - static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - private string _connectionString; - public string ConnectionString { - get => _connectionString; - set { - _connectionString = value ?? ""; + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; - var pattern = @"Max(imum)?\s*pool\s*size\s*=\s*(\d+)"; - Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success == false || int.TryParse(m.Groups[2].Value, out var poolsize) == false || poolsize <= 0) poolsize = 50; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); - PoolSize = poolsize + connStrIncr; - _connectionString = m.Success ? - Regex.Replace(_connectionString, pattern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) : - $"{_connectionString};Maximum pool size={PoolSize}"; + var pattern = @"Max(imum)?\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[2].Value, out var poolsize) == false || poolsize <= 0) poolsize = 50; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Maximum pool size={PoolSize}"; - pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - var minPoolSize = 0; - pattern = @"Min(imum)?\s*pool\s*size\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - minPoolSize = int.Parse(m.Groups[2].Value); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + var minPoolSize = 0; + pattern = @"Min(imum)?\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[2].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); - } - } + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } - public bool OnCheckAvailable(Object obj) { - if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); - return obj.Value.Ping(true); - } + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } - public DbConnection OnCreate() { - var conn = new NpgsqlConnection(_connectionString); - return conn; - } + public DbConnection OnCreate() + { + var conn = new NpgsqlConnection(_connectionString); + return conn; + } - public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); - obj.Dispose(); - } + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } - public void OnGet(Object obj) { + public void OnGet(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { - try { - obj.Value.Open(); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - async public Task OnGetAsync(Object obj) { + async public Task OnGetAsync(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { - try { - await obj.Value.OpenAsync(); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - public void OnGetTimeout() { + public void OnGetTimeout() + { - } + } - public void OnReturn(Object obj) { + public void OnReturn(Object obj) + { - } + } - public void OnAvailable() { - _pool.availableHandler?.Invoke(); - } + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } - public void OnUnavailable() { - _pool.unavailableHandler?.Invoke(); - } - } + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } - static class DbConnectionExtensions { + static class DbConnectionExtensions + { - static DbCommand PingCommand(DbConnection conn) { - var cmd = conn.CreateCommand(); - cmd.CommandTimeout = 5; - cmd.CommandText = "select 1"; - return cmd; - } - public static bool Ping(this DbConnection that, bool isThrow = false) { - try { - PingCommand(that).ExecuteNonQuery(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - async public static Task PingAsync(this DbConnection that, bool isThrow = false) { - try { - await PingCommand(that).ExecuteNonQueryAsync(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - } + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesConverter.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesConverter.cs index cd0fc698..16e05bd0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesConverter.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesConverter.cs @@ -7,134 +7,151 @@ using System.Linq; using System.Net; using System.Net.NetworkInformation; -namespace Newtonsoft.Json { - public class PostgreSQLTypesConverter : JsonConverter { - private static readonly Type typeof_BitArray = typeof(BitArray); +namespace Newtonsoft.Json +{ + public class PostgreSQLTypesConverter : JsonConverter + { + private static readonly Type typeof_BitArray = typeof(BitArray); - private static readonly Type typeof_NpgsqlPoint = typeof(NpgsqlPoint); - private static readonly Type typeof_NpgsqlLine = typeof(NpgsqlLine); - private static readonly Type typeof_NpgsqlLSeg = typeof(NpgsqlLSeg); - private static readonly Type typeof_NpgsqlBox = typeof(NpgsqlBox); - private static readonly Type typeof_NpgsqlPath = typeof(NpgsqlPath); - private static readonly Type typeof_NpgsqlPolygon = typeof(NpgsqlPolygon); - private static readonly Type typeof_NpgsqlCircle = typeof(NpgsqlCircle); + private static readonly Type typeof_NpgsqlPoint = typeof(NpgsqlPoint); + private static readonly Type typeof_NpgsqlLine = typeof(NpgsqlLine); + private static readonly Type typeof_NpgsqlLSeg = typeof(NpgsqlLSeg); + private static readonly Type typeof_NpgsqlBox = typeof(NpgsqlBox); + private static readonly Type typeof_NpgsqlPath = typeof(NpgsqlPath); + private static readonly Type typeof_NpgsqlPolygon = typeof(NpgsqlPolygon); + private static readonly Type typeof_NpgsqlCircle = typeof(NpgsqlCircle); - private static readonly Type typeof_Cidr = typeof((IPAddress, int)); - private static readonly Type typeof_IPAddress = typeof(IPAddress); - private static readonly Type typeof_PhysicalAddress = typeof(PhysicalAddress); + private static readonly Type typeof_Cidr = typeof((IPAddress, int)); + private static readonly Type typeof_IPAddress = typeof(IPAddress); + private static readonly Type typeof_PhysicalAddress = typeof(PhysicalAddress); - private static readonly Type typeof_String = typeof(string); + private static readonly Type typeof_String = typeof(string); - private static readonly Type typeof_NpgsqlRange_int = typeof(NpgsqlRange); - private static readonly Type typeof_NpgsqlRange_long = typeof(NpgsqlRange); - private static readonly Type typeof_NpgsqlRange_decimal = typeof(NpgsqlRange); - private static readonly Type typeof_NpgsqlRange_DateTime = typeof(NpgsqlRange); - public override bool CanConvert(Type objectType) { - Type ctype = objectType.IsArray ? objectType.GetElementType() : objectType; - var ctypeGenericType1 = ctype.GenericTypeArguments.FirstOrDefault(); + private static readonly Type typeof_NpgsqlRange_int = typeof(NpgsqlRange); + private static readonly Type typeof_NpgsqlRange_long = typeof(NpgsqlRange); + private static readonly Type typeof_NpgsqlRange_decimal = typeof(NpgsqlRange); + private static readonly Type typeof_NpgsqlRange_DateTime = typeof(NpgsqlRange); + public override bool CanConvert(Type objectType) + { + Type ctype = objectType.IsArray ? objectType.GetElementType() : objectType; + var ctypeGenericType1 = ctype.GenericTypeArguments.FirstOrDefault(); - if (ctype == typeof_BitArray) return true; + if (ctype == typeof_BitArray) return true; - if (ctype == typeof_NpgsqlPoint || ctypeGenericType1 == typeof_NpgsqlPoint) return true; - if (ctype == typeof_NpgsqlLine || ctypeGenericType1 == typeof_NpgsqlLine) return true; - if (ctype == typeof_NpgsqlLSeg || ctypeGenericType1 == typeof_NpgsqlLSeg) return true; - if (ctype == typeof_NpgsqlBox || ctypeGenericType1 == typeof_NpgsqlBox) return true; - if (ctype == typeof_NpgsqlPath || ctypeGenericType1 == typeof_NpgsqlPath) return true; - if (ctype == typeof_NpgsqlPolygon || ctypeGenericType1 == typeof_NpgsqlPolygon) return true; - if (ctype == typeof_NpgsqlCircle || ctypeGenericType1 == typeof_NpgsqlCircle) return true; + if (ctype == typeof_NpgsqlPoint || ctypeGenericType1 == typeof_NpgsqlPoint) return true; + if (ctype == typeof_NpgsqlLine || ctypeGenericType1 == typeof_NpgsqlLine) return true; + if (ctype == typeof_NpgsqlLSeg || ctypeGenericType1 == typeof_NpgsqlLSeg) return true; + if (ctype == typeof_NpgsqlBox || ctypeGenericType1 == typeof_NpgsqlBox) return true; + if (ctype == typeof_NpgsqlPath || ctypeGenericType1 == typeof_NpgsqlPath) return true; + if (ctype == typeof_NpgsqlPolygon || ctypeGenericType1 == typeof_NpgsqlPolygon) return true; + if (ctype == typeof_NpgsqlCircle || ctypeGenericType1 == typeof_NpgsqlCircle) return true; - if (ctype == typeof_Cidr || ctypeGenericType1 == typeof_Cidr) return true; - if (ctype == typeof_IPAddress) return true; - if (ctype == typeof_PhysicalAddress) return true; + if (ctype == typeof_Cidr || ctypeGenericType1 == typeof_Cidr) return true; + if (ctype == typeof_IPAddress) return true; + if (ctype == typeof_PhysicalAddress) return true; - if (ctype == typeof_NpgsqlRange_int || ctypeGenericType1 == typeof_NpgsqlRange_int) return true; - if (ctype == typeof_NpgsqlRange_long || ctypeGenericType1 == typeof_NpgsqlRange_long) return true; - if (ctype == typeof_NpgsqlRange_decimal || ctypeGenericType1 == typeof_NpgsqlRange_decimal) return true; - if (ctype == typeof_NpgsqlRange_DateTime || ctypeGenericType1 == typeof_NpgsqlRange_DateTime) return true; + if (ctype == typeof_NpgsqlRange_int || ctypeGenericType1 == typeof_NpgsqlRange_int) return true; + if (ctype == typeof_NpgsqlRange_long || ctypeGenericType1 == typeof_NpgsqlRange_long) return true; + if (ctype == typeof_NpgsqlRange_decimal || ctypeGenericType1 == typeof_NpgsqlRange_decimal) return true; + if (ctype == typeof_NpgsqlRange_DateTime || ctypeGenericType1 == typeof_NpgsqlRange_DateTime) return true; - return false; - } - private object YieldJToken(Type ctype, JToken jt, int rank) { - if (jt.Type == JTokenType.Null) return null; - if (rank == 0) { - var ctypeGenericType1 = ctype.GenericTypeArguments.FirstOrDefault();//ctype.Namespace == "System" && ctype.Name.StartsWith("Nullable`") ? ctype.GenericTypeArguments.FirstOrDefault() : null; - if (ctype == typeof_BitArray) return jt.ToString().ToBitArray(); + return false; + } + private object YieldJToken(Type ctype, JToken jt, int rank) + { + if (jt.Type == JTokenType.Null) return null; + if (rank == 0) + { + var ctypeGenericType1 = ctype.GenericTypeArguments.FirstOrDefault();//ctype.Namespace == "System" && ctype.Name.StartsWith("Nullable`") ? ctype.GenericTypeArguments.FirstOrDefault() : null; + if (ctype == typeof_BitArray) return jt.ToString().ToBitArray(); - if (ctype == typeof_NpgsqlPoint || ctypeGenericType1 == typeof_NpgsqlPoint) return NpgsqlPoint.Parse(jt.ToString()); - if (ctype == typeof_NpgsqlLine || ctypeGenericType1 == typeof_NpgsqlLine) return NpgsqlLine.Parse(jt.ToString()); - if (ctype == typeof_NpgsqlLSeg || ctypeGenericType1 == typeof_NpgsqlLSeg) return NpgsqlLSeg.Parse(jt.ToString()); - if (ctype == typeof_NpgsqlBox || ctypeGenericType1 == typeof_NpgsqlBox) return NpgsqlBox.Parse(jt.ToString()); - if (ctype == typeof_NpgsqlPath || ctypeGenericType1 == typeof_NpgsqlPath) return NpgsqlPath.Parse(jt.ToString()); - if (ctype == typeof_NpgsqlPolygon || ctypeGenericType1 == typeof_NpgsqlPolygon) return NpgsqlPolygon.Parse(jt.ToString()); - if (ctype == typeof_NpgsqlCircle || ctypeGenericType1 == typeof_NpgsqlCircle) return NpgsqlCircle.Parse(jt.ToString()); + if (ctype == typeof_NpgsqlPoint || ctypeGenericType1 == typeof_NpgsqlPoint) return NpgsqlPoint.Parse(jt.ToString()); + if (ctype == typeof_NpgsqlLine || ctypeGenericType1 == typeof_NpgsqlLine) return NpgsqlLine.Parse(jt.ToString()); + if (ctype == typeof_NpgsqlLSeg || ctypeGenericType1 == typeof_NpgsqlLSeg) return NpgsqlLSeg.Parse(jt.ToString()); + if (ctype == typeof_NpgsqlBox || ctypeGenericType1 == typeof_NpgsqlBox) return NpgsqlBox.Parse(jt.ToString()); + if (ctype == typeof_NpgsqlPath || ctypeGenericType1 == typeof_NpgsqlPath) return NpgsqlPath.Parse(jt.ToString()); + if (ctype == typeof_NpgsqlPolygon || ctypeGenericType1 == typeof_NpgsqlPolygon) return NpgsqlPolygon.Parse(jt.ToString()); + if (ctype == typeof_NpgsqlCircle || ctypeGenericType1 == typeof_NpgsqlCircle) return NpgsqlCircle.Parse(jt.ToString()); - if (ctype == typeof_Cidr || ctypeGenericType1 == typeof_Cidr) { - var cidrArgs = jt.ToString().Split(new[] { '/' }, 2); - return (IPAddress.Parse(cidrArgs.First()), cidrArgs.Length >= 2 ? int.TryParse(cidrArgs[1], out var tryCdirSubnet) ? tryCdirSubnet : 0 : 0); - } - if (ctype == typeof_IPAddress) return IPAddress.Parse(jt.ToString()); - if (ctype == typeof_PhysicalAddress) return PhysicalAddress.Parse(jt.ToString()); + if (ctype == typeof_Cidr || ctypeGenericType1 == typeof_Cidr) + { + var cidrArgs = jt.ToString().Split(new[] { '/' }, 2); + return (IPAddress.Parse(cidrArgs.First()), cidrArgs.Length >= 2 ? int.TryParse(cidrArgs[1], out var tryCdirSubnet) ? tryCdirSubnet : 0 : 0); + } + if (ctype == typeof_IPAddress) return IPAddress.Parse(jt.ToString()); + if (ctype == typeof_PhysicalAddress) return PhysicalAddress.Parse(jt.ToString()); - if (ctype == typeof_NpgsqlRange_int || ctypeGenericType1 == typeof_NpgsqlRange_int) return jt.ToString().ToNpgsqlRange(); - if (ctype == typeof_NpgsqlRange_long || ctypeGenericType1 == typeof_NpgsqlRange_long) return jt.ToString().ToNpgsqlRange(); - if (ctype == typeof_NpgsqlRange_decimal || ctypeGenericType1 == typeof_NpgsqlRange_decimal) return jt.ToString().ToNpgsqlRange(); - if (ctype == typeof_NpgsqlRange_DateTime || ctypeGenericType1 == typeof_NpgsqlRange_DateTime) return jt.ToString().ToNpgsqlRange(); + if (ctype == typeof_NpgsqlRange_int || ctypeGenericType1 == typeof_NpgsqlRange_int) return jt.ToString().ToNpgsqlRange(); + if (ctype == typeof_NpgsqlRange_long || ctypeGenericType1 == typeof_NpgsqlRange_long) return jt.ToString().ToNpgsqlRange(); + if (ctype == typeof_NpgsqlRange_decimal || ctypeGenericType1 == typeof_NpgsqlRange_decimal) return jt.ToString().ToNpgsqlRange(); + if (ctype == typeof_NpgsqlRange_DateTime || ctypeGenericType1 == typeof_NpgsqlRange_DateTime) return jt.ToString().ToNpgsqlRange(); - return null; - } - - var jtarr = jt.ToArray(); - var ret = Array.CreateInstance(ctype, jtarr.Length); - var jtarrIdx = 0; - foreach (var a in jtarr) { - var t2 = YieldJToken(ctype, a, rank - 1); - ret.SetValue(t2, jtarrIdx++); - } - return ret; - } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - int rank = objectType.IsArray ? objectType.GetArrayRank() : 0; - Type ctype = objectType.IsArray ? objectType.GetElementType() : objectType; + return null; + } - var ret = YieldJToken(ctype, JToken.Load(reader), rank); - if (ret != null && rank > 0) return ret; - return ret; - } - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - Type objectType = value.GetType(); - if (objectType.IsArray) { - int rank = objectType.GetArrayRank(); - int[] indices = new int[rank]; - GetJObject(value as Array, indices, 0).WriteTo(writer); - } else - GetJObject(value).WriteTo(writer); - } - public static JToken GetJObject(object value) { - if (value is BitArray) return JToken.FromObject((value as BitArray)?.To1010()); - if (value is IPAddress) return JToken.FromObject((value as IPAddress)?.ToString()); - if (value is ValueTuple || value is ValueTuple?) { - ValueTuple? cidrValue = (ValueTuple?)value; - return JToken.FromObject(cidrValue == null ? null : $"{cidrValue.Value.Item1.ToString()}/{cidrValue.Value.Item2.ToString()}"); - } - return JToken.FromObject(value?.ToString()); - } - public static JToken GetJObject(Array value, int[] indices, int idx) { - if (idx == indices.Length) { - return GetJObject(value.GetValue(indices)); - } - JArray ja = new JArray(); - if (indices.Length == 1) { - foreach(object a in value) - ja.Add(GetJObject(a)); - return ja; - } - int lb = value.GetLowerBound(idx); - int ub = value.GetUpperBound(idx); - for (int b = lb; b <= ub; b++) { - indices[idx] = b; - ja.Add(GetJObject(value, indices, idx + 1)); - } - return ja; - } - } + var jtarr = jt.ToArray(); + var ret = Array.CreateInstance(ctype, jtarr.Length); + var jtarrIdx = 0; + foreach (var a in jtarr) + { + var t2 = YieldJToken(ctype, a, rank - 1); + ret.SetValue(t2, jtarrIdx++); + } + return ret; + } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + int rank = objectType.IsArray ? objectType.GetArrayRank() : 0; + Type ctype = objectType.IsArray ? objectType.GetElementType() : objectType; + + var ret = YieldJToken(ctype, JToken.Load(reader), rank); + if (ret != null && rank > 0) return ret; + return ret; + } + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + Type objectType = value.GetType(); + if (objectType.IsArray) + { + int rank = objectType.GetArrayRank(); + int[] indices = new int[rank]; + GetJObject(value as Array, indices, 0).WriteTo(writer); + } + else + GetJObject(value).WriteTo(writer); + } + public static JToken GetJObject(object value) + { + if (value is BitArray) return JToken.FromObject((value as BitArray)?.To1010()); + if (value is IPAddress) return JToken.FromObject((value as IPAddress)?.ToString()); + if (value is ValueTuple || value is ValueTuple?) + { + ValueTuple? cidrValue = (ValueTuple?)value; + return JToken.FromObject(cidrValue == null ? null : $"{cidrValue.Value.Item1.ToString()}/{cidrValue.Value.Item2.ToString()}"); + } + return JToken.FromObject(value?.ToString()); + } + public static JToken GetJObject(Array value, int[] indices, int idx) + { + if (idx == indices.Length) + { + return GetJObject(value.GetValue(indices)); + } + JArray ja = new JArray(); + if (indices.Length == 1) + { + foreach (object a in value) + ja.Add(GetJObject(a)); + return ja; + } + int lb = value.GetLowerBound(idx); + int ub = value.GetUpperBound(idx); + for (int b = lb; b <= ub; b++) + { + indices[idx] = b; + ja.Add(GetJObject(value, indices, idx + 1)); + } + return ja; + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs index 1eda91d1..ab1fb921 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs @@ -3,63 +3,69 @@ using NpgsqlTypes; using System; using System.Collections; -public static partial class PostgreSQLTypesExtensions { - /// - /// 测量两个经纬度的距离,返回单位:米 - /// - /// 经纬坐标1 - /// 经纬坐标2 - /// 返回距离(单位:米) - public static double Distance(this NpgsqlPoint that, NpgsqlPoint point) { - double radLat1 = (double)(that.Y) * Math.PI / 180d; - double radLng1 = (double)(that.X) * Math.PI / 180d; - double radLat2 = (double)(point.Y) * Math.PI / 180d; - double radLng2 = (double)(point.X) * Math.PI / 180d; - 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; - } +public static partial class PostgreSQLTypesExtensions +{ + /// + /// 测量两个经纬度的距离,返回单位:米 + /// + /// 经纬坐标1 + /// 经纬坐标2 + /// 返回距离(单位:米) + public static double Distance(this NpgsqlPoint that, NpgsqlPoint point) + { + double radLat1 = (double)(that.Y) * Math.PI / 180d; + double radLng1 = (double)(that.X) * Math.PI / 180d; + double radLat2 = (double)(point.Y) * Math.PI / 180d; + double radLng2 = (double)(point.X) * Math.PI / 180d; + 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; + } - /// - /// 测量两个经纬度的距离,返回单位:米 - /// - /// 经纬坐标1 - /// 经纬坐标2 - /// 返回距离(单位:米) - public static double Distance(this PostgisPoint that, PostgisPoint point) { - double radLat1 = (double)(that.Y) * Math.PI / 180d; - double radLng1 = (double)(that.X) * Math.PI / 180d; - double radLat2 = (double)(point.Y) * Math.PI / 180d; - double radLng2 = (double)(point.X) * Math.PI / 180d; - 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; - } + /// + /// 测量两个经纬度的距离,返回单位:米 + /// + /// 经纬坐标1 + /// 经纬坐标2 + /// 返回距离(单位:米) + public static double Distance(this PostgisPoint that, PostgisPoint point) + { + double radLat1 = (double)(that.Y) * Math.PI / 180d; + double radLng1 = (double)(that.X) * Math.PI / 180d; + double radLat2 = (double)(point.Y) * Math.PI / 180d; + double radLng2 = (double)(point.X) * Math.PI / 180d; + 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; + } - public static string To1010(this BitArray ba) { - char[] ret = new char[ba.Length]; - for (int a = 0; a < ba.Length; a++) ret[a] = ba[a] ? '1' : '0'; - return new string(ret); - } + public static string To1010(this BitArray ba) + { + char[] ret = new char[ba.Length]; + for (int a = 0; a < ba.Length; a++) ret[a] = ba[a] ? '1' : '0'; + return new string(ret); + } - /// - /// 将 1010101010 这样的二进制字符串转换成 BitArray - /// - /// 1010101010 - /// - public static BitArray ToBitArray(this string _1010Str) { - if (_1010Str == null) return null; - BitArray ret = new BitArray(_1010Str.Length); - for (int a = 0; a < _1010Str.Length; a++) ret[a] = _1010Str[a] == '1'; - return ret; - } + /// + /// 将 1010101010 这样的二进制字符串转换成 BitArray + /// + /// 1010101010 + /// + public static BitArray ToBitArray(this string _1010Str) + { + if (_1010Str == null) return null; + BitArray ret = new BitArray(_1010Str.Length); + for (int a = 0; a < _1010Str.Length; a++) ret[a] = _1010Str[a] == '1'; + return ret; + } - public static NpgsqlRange ToNpgsqlRange(this string that) { - var s = that; - if (string.IsNullOrEmpty(s) || s == "empty") return NpgsqlRange.Empty; - string s1 = s.Trim('(', ')', '[', ']'); - string[] ss = s1.Split(new char[] { ',' }, 2); - if (ss.Length != 2) return NpgsqlRange.Empty; - T t1 = default(T); - T t2 = default(T); - if (!string.IsNullOrEmpty(ss[0])) t1 = (T)Convert.ChangeType(ss[0], typeof(T)); - if (!string.IsNullOrEmpty(ss[1])) t2 = (T)Convert.ChangeType(ss[1], typeof(T)); - return new NpgsqlRange(t1, s[0] == '[', s[0] == '(', t2, s[s.Length - 1] == ']', s[s.Length - 1] == ')'); - } + public static NpgsqlRange ToNpgsqlRange(this string that) + { + var s = that; + if (string.IsNullOrEmpty(s) || s == "empty") return NpgsqlRange.Empty; + string s1 = s.Trim('(', ')', '[', ']'); + string[] ss = s1.Split(new char[] { ',' }, 2); + if (ss.Length != 2) return NpgsqlRange.Empty; + T t1 = default(T); + T t2 = default(T); + if (!string.IsNullOrEmpty(ss[0])) t1 = (T)Convert.ChangeType(ss[0], typeof(T)); + if (!string.IsNullOrEmpty(ss[1])) t2 = (T)Convert.ChangeType(ss[1], typeof(T)); + return new NpgsqlRange(t1, s[0] == '[', s[0] == '(', t2, s[s.Length - 1] == ']', s[s.Length - 1] == ')'); + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 708f73a3..78742220 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -16,164 +16,182 @@ using System.Net.NetworkInformation; using System.Text; using System.Text.RegularExpressions; -namespace FreeSql.PostgreSQL { +namespace FreeSql.PostgreSQL +{ - class PostgreSQLCodeFirst : Internal.CommonProvider.CodeFirstProvider { + class PostgreSQLCodeFirst : Internal.CommonProvider.CodeFirstProvider + { - public PostgreSQLCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + public PostgreSQLCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } - static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { - { typeof(sbyte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, - { typeof(short).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, - { typeof(int).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true, null) }, - { typeof(long).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true, null) }, + { typeof(sbyte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(short).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(int).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true, null) }, + { typeof(long).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true, null) }, - { typeof(byte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, - { typeof(ushort).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true, null) }, - { typeof(uint).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true, null) }, - { typeof(ulong).FullName, (NpgsqlDbType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, + { typeof(byte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(ushort).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true, null) }, + { typeof(uint).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, (NpgsqlDbType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, - { typeof(float).FullName, (NpgsqlDbType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, (NpgsqlDbType.Real, "float4", "float4", false, true, null) }, - { typeof(double).FullName, (NpgsqlDbType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, (NpgsqlDbType.Double, "float8", "float8", false, true, null) }, - { typeof(decimal).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, + { typeof(float).FullName, (NpgsqlDbType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, (NpgsqlDbType.Real, "float4", "float4", false, true, null) }, + { typeof(double).FullName, (NpgsqlDbType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, (NpgsqlDbType.Double, "float8", "float8", false, true, null) }, + { typeof(decimal).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, - { typeof(string).FullName, (NpgsqlDbType.Varchar, "varchar", "varchar(255)", false, null, "") }, + { typeof(string).FullName, (NpgsqlDbType.Varchar, "varchar", "varchar(255)", false, null, "") }, - { typeof(TimeSpan).FullName, (NpgsqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (NpgsqlDbType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp", false, true, null) }, + { typeof(TimeSpan).FullName, (NpgsqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (NpgsqlDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp", false, true, null) }, - { typeof(bool).FullName, (NpgsqlDbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, (NpgsqlDbType.Boolean, "bool","bool", null, true, null) }, - { typeof(Byte[]).FullName, (NpgsqlDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) }, - { typeof(BitArray).FullName, (NpgsqlDbType.Varbit, "varbit", "varbit(64)", false, null, new BitArray(new byte[64])) }, + { typeof(bool).FullName, (NpgsqlDbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, (NpgsqlDbType.Boolean, "bool","bool", null, true, null) }, + { typeof(Byte[]).FullName, (NpgsqlDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) }, + { typeof(BitArray).FullName, (NpgsqlDbType.Varbit, "varbit", "varbit(64)", false, null, new BitArray(new byte[64])) }, - { typeof(NpgsqlPoint).FullName, (NpgsqlDbType.Point, "point", "point NOT NULL", false, false, new NpgsqlPoint(0, 0)) },{ typeof(NpgsqlPoint?).FullName, (NpgsqlDbType.Point, "point", "point", false, true, null) }, - { typeof(NpgsqlLine).FullName, (NpgsqlDbType.Line, "line", "line NOT NULL", false, false, new NpgsqlLine(0, 0, 1)) },{ typeof(NpgsqlLine?).FullName, (NpgsqlDbType.Line, "line", "line", false, true, null) }, - { typeof(NpgsqlLSeg).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg NOT NULL", false, false, new NpgsqlLSeg(0, 0, 0, 0)) },{ typeof(NpgsqlLSeg?).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg", false, true, null) }, - { typeof(NpgsqlBox).FullName, (NpgsqlDbType.Box, "box", "box NOT NULL", false, false, new NpgsqlBox(0, 0, 0, 0)) },{ typeof(NpgsqlBox?).FullName, (NpgsqlDbType.Box, "box", "box", false, true, null) }, - { typeof(NpgsqlPath).FullName, (NpgsqlDbType.Path, "path", "path NOT NULL", false, false, new NpgsqlPath(new NpgsqlPoint(0, 0))) },{ typeof(NpgsqlPath?).FullName, (NpgsqlDbType.Path, "path", "path", false, true, null) }, - { typeof(NpgsqlPolygon).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon NOT NULL", false, false, new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0))) },{ typeof(NpgsqlPolygon?).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon", false, true, null) }, - { typeof(NpgsqlCircle).FullName, (NpgsqlDbType.Circle, "circle", "circle NOT NULL", false, false, new NpgsqlCircle(0, 0, 0)) },{ typeof(NpgsqlCircle?).FullName, (NpgsqlDbType.Circle, "circle", "circle", false, true, null) }, + { typeof(NpgsqlPoint).FullName, (NpgsqlDbType.Point, "point", "point NOT NULL", false, false, new NpgsqlPoint(0, 0)) },{ typeof(NpgsqlPoint?).FullName, (NpgsqlDbType.Point, "point", "point", false, true, null) }, + { typeof(NpgsqlLine).FullName, (NpgsqlDbType.Line, "line", "line NOT NULL", false, false, new NpgsqlLine(0, 0, 1)) },{ typeof(NpgsqlLine?).FullName, (NpgsqlDbType.Line, "line", "line", false, true, null) }, + { typeof(NpgsqlLSeg).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg NOT NULL", false, false, new NpgsqlLSeg(0, 0, 0, 0)) },{ typeof(NpgsqlLSeg?).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg", false, true, null) }, + { typeof(NpgsqlBox).FullName, (NpgsqlDbType.Box, "box", "box NOT NULL", false, false, new NpgsqlBox(0, 0, 0, 0)) },{ typeof(NpgsqlBox?).FullName, (NpgsqlDbType.Box, "box", "box", false, true, null) }, + { typeof(NpgsqlPath).FullName, (NpgsqlDbType.Path, "path", "path NOT NULL", false, false, new NpgsqlPath(new NpgsqlPoint(0, 0))) },{ typeof(NpgsqlPath?).FullName, (NpgsqlDbType.Path, "path", "path", false, true, null) }, + { typeof(NpgsqlPolygon).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon NOT NULL", false, false, new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0))) },{ typeof(NpgsqlPolygon?).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon", false, true, null) }, + { typeof(NpgsqlCircle).FullName, (NpgsqlDbType.Circle, "circle", "circle NOT NULL", false, false, new NpgsqlCircle(0, 0, 0)) },{ typeof(NpgsqlCircle?).FullName, (NpgsqlDbType.Circle, "circle", "circle", false, true, null) }, - { typeof((IPAddress Address, int Subnet)).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr NOT NULL", false, false, (IPAddress.Any, 0)) },{ typeof((IPAddress Address, int Subnet)?).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr", false, true, null) }, - { typeof(IPAddress).FullName, (NpgsqlDbType.Inet, "inet", "inet", false, null, IPAddress.Any) }, - { typeof(PhysicalAddress).FullName, (NpgsqlDbType.MacAddr, "macaddr", "macaddr", false, null, PhysicalAddress.None) }, + { typeof((IPAddress Address, int Subnet)).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr NOT NULL", false, false, (IPAddress.Any, 0)) },{ typeof((IPAddress Address, int Subnet)?).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr", false, true, null) }, + { typeof(IPAddress).FullName, (NpgsqlDbType.Inet, "inet", "inet", false, null, IPAddress.Any) }, + { typeof(PhysicalAddress).FullName, (NpgsqlDbType.MacAddr, "macaddr", "macaddr", false, null, PhysicalAddress.None) }, - { typeof(JToken).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JToken.Parse("{}")) }, - { typeof(JObject).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JObject.Parse("{}")) }, - { typeof(JArray).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JArray.Parse("[]")) }, - { typeof(Guid).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid", false, true, null) }, + { typeof(JToken).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JToken.Parse("{}")) }, + { typeof(JObject).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JObject.Parse("{}")) }, + { typeof(JArray).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JArray.Parse("[]")) }, + { typeof(Guid).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid", false, true, null) }, - { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range", false, true, null) }, - { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range", false, true, null) }, - { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange", false, true, null) }, - { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange", false, true, null) }, + { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range", false, true, null) }, + { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range", false, true, null) }, + { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange", false, true, null) }, + { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange", false, true, null) }, - { typeof(Dictionary).FullName, (NpgsqlDbType.Hstore, "hstore", "hstore", false, null, new Dictionary()) }, - { typeof(PostgisPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, - { typeof(PostgisLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, - { typeof(PostgisPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } })) }, - { typeof(PostgisMultiPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPoint(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, - { typeof(PostgisMultiLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiLineString(new[]{new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }),new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }) })) }, - { typeof(PostgisMultiPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPolygon(new[]{new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }),new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }) })) }, - { typeof(PostgisGeometry).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, - { typeof(PostgisGeometryCollection).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisGeometryCollection(new[]{new PostgisPoint(0, 0),new PostgisPoint(0, 0) })) }, - }; + { typeof(Dictionary).FullName, (NpgsqlDbType.Hstore, "hstore", "hstore", false, null, new Dictionary()) }, + { typeof(PostgisPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, + { typeof(PostgisLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, + { typeof(PostgisPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } })) }, + { typeof(PostgisMultiPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPoint(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, + { typeof(PostgisMultiLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiLineString(new[]{new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }),new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }) })) }, + { typeof(PostgisMultiPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPolygon(new[]{new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }),new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }) })) }, + { typeof(PostgisGeometry).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, + { typeof(PostgisGeometryCollection).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisGeometryCollection(new[]{new PostgisPoint(0, 0),new PostgisPoint(0, 0) })) }, + }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { - var isarray = type.FullName != "System.Byte[]" && type.IsArray; - var elementType = isarray ? type.GetElementType() : type; - var info = GetDbInfoNoneArray(elementType); - if (info == null) return null; - if (isarray == false) return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable, info.Value.defaultValue); - var dbtypefull = Regex.Replace(info.Value.dbtypeFull, $@"{info.Value.dbtype}(\s*\([^\)]+\))?", "$0[]").Replace(" NOT NULL", ""); - return ((int)(info.Value.type | NpgsqlDbType.Array), $"{info.Value.dbtype}[]", dbtypefull, null, Array.CreateInstance(elementType, 0)); - } - (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfoNoneArray(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (NpgsqlDbType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); - if (type.IsArray) return null; - var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); - if (enumType != null) { - var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (NpgsqlDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); - if (_dicCsToDb.ContainsKey(type.FullName) == false) { - lock (_dicCsToDbLock) { - if (_dicCsToDb.ContainsKey(type.FullName) == false) - _dicCsToDb.Add(type.FullName, newItem); - } - } - return (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); - } - return null; - } - - public override string GetComparisonDDLStatements(params Type[] entityTypes) { - var sb = new StringBuilder(); - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + var isarray = type.FullName != "System.Byte[]" && type.IsArray; + var elementType = isarray ? type.GetElementType() : type; + var info = GetDbInfoNoneArray(elementType); + if (info == null) return null; + if (isarray == false) return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable, info.Value.defaultValue); + var dbtypefull = Regex.Replace(info.Value.dbtypeFull, $@"{info.Value.dbtype}(\s*\([^\)]+\))?", "$0[]").Replace(" NOT NULL", ""); + return ((int)(info.Value.type | NpgsqlDbType.Array), $"{info.Value.dbtype}[]", dbtypefull, null, Array.CreateInstance(elementType, 0)); + } + (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfoNoneArray(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (NpgsqlDbType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (NpgsqlDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } - foreach (var entityType in entityTypes) { - if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); - if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var sb = new StringBuilder(); + var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; - if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 - sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; - var sbalter = new StringBuilder(); - var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tbname)) == null) { //表不存在 - if (tboldname != null) { - if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tboldname)) == null) - //旧表不存在 - tboldname = null; - } - if (tboldname == null) { - //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); - } - if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); - //备注 - foreach (var tbcol in tb.Columns.Values) { - if (string.IsNullOrEmpty(tbcol.Comment) == false) - sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); - } - continue; - } - //如果新表,旧表在一个数据库和模式下,直接修改表名 - if (string.Compare(tbname[0], tboldname[0], true) == 0) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); - else { - //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 - istmpatler = true; - } - } else - tboldname = null; //如果新表已经存在,不走改表名逻辑 + if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 + sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); - //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = _commonUtils.FormatSql(@" + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tboldname)) == null) + //旧表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql(@" select a.attname, t.typname, @@ -192,59 +210,66 @@ left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum inner join pg_namespace ns on ns.oid = c.relnamespace inner join pg_namespace ns2 on ns2.oid = t.typnamespace where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { - var attndims = int.Parse(string.Concat(a[6])); - var type = string.Concat(a[1]); - var sqlType = string.Concat(a[3]); - var max_length = long.Parse(string.Concat(a[2])); - switch (sqlType.ToLower()) { - case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; - default: max_length *= 8; break; - } - if (type.StartsWith("_")) { - type = type.Substring(1); - if (attndims == 0) attndims++; - } - if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); - return new { - column = string.Concat(a[0]), - sqlType = string.Concat(sqlType), - max_length = long.Parse(string.Concat(a[2])), - is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), - attndims, - comment = string.Concat(a[7]) - }; - }, StringComparer.CurrentCultureIgnoreCase); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var attndims = int.Parse(string.Concat(a[6])); + var type = string.Concat(a[1]); + var sqlType = string.Concat(a[3]); + var max_length = long.Parse(string.Concat(a[2])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + return new + { + column = string.Concat(a[0]), + sqlType = string.Concat(sqlType), + max_length = long.Parse(string.Concat(a[2])), + is_nullable = string.Concat(a[4]) == "1", + is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + attndims, + comment = string.Concat(a[7]) + }; + }, StringComparer.CurrentCultureIgnoreCase); - if (istmpatler == false) { - foreach (var tbcol in tb.Columns.Values) { - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || - tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) - //修改列名 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); - if (isCommentChanged) - sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); - continue; - } - //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0};\r\n", tbcol.Attribute.DbDefautValue)); - if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); - } - var dsuksql = _commonUtils.FormatSql(@" + if (istmpatler == false) + { + foreach (var tbcol in tb.Columns.Values) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (isCommentChanged) + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0};\r\n", tbcol.Attribute.DbDefautValue)); + if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" select c.attname, b.relname @@ -254,91 +279,103 @@ inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid where ns.nspname in ({0}) and d.relname in ({1}) and a.indisunique = 't'", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); - } - } - } - if (istmpatler == false) { - sb.Append(sbalter); - continue; - } - var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select pg_constraint.conname as pk_name from pg_constraint + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); + foreach (var uk in tb.Uniques) + { + if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select pg_constraint.conname as pk_name from pg_constraint inner join pg_class on pg_constraint.conrelid = pg_class.oid inner join pg_namespace on pg_namespace.oid = pg_class.relnamespace where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contype='p' ", tbname))?.ToString(); - if (string.IsNullOrEmpty(oldpk) == false) - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); - //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); - //创建临时表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); - } - if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); - //备注 - foreach (var tbcol in tb.Columns.Values) { - if (string.IsNullOrEmpty(tbcol.Comment) == false) - sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); - } - sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) - sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.Columns.Values) { - var insertvalue = "NULL"; - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) - insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"coalesce({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; - } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); - sb.Append(insertvalue).Append(", "); - } - sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); - sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); - } - foreach (var seqcol in seqcols) { - var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); - var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); - var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); - sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); - sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); - if (seqcol.Item3) { - sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);\r\n"); - sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); - } - } - return sb.Length == 0 ? null : sb.ToString(); - } - } + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.Columns.Values) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"coalesce({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); + sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); + if (seqcol.Item3) + { + sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);\r\n"); + sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); + } + } + return sb.Length == 0 ? null : sb.ToString(); + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 2db33d75..517b8370 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -14,211 +14,220 @@ using System.Net; using System.Net.NetworkInformation; using System.Text.RegularExpressions; -namespace FreeSql.PostgreSQL { - class PostgreSQLDbFirst : IDbFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public PostgreSQLDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } +namespace FreeSql.PostgreSQL +{ + class PostgreSQLDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public PostgreSQLDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } - public int GetDbType(DbColumnInfo column) => (int)GetNpgsqlDbType(column); - NpgsqlDbType GetNpgsqlDbType(DbColumnInfo column) { - var dbtype = column.DbTypeText; - var isarray = dbtype.EndsWith("[]"); - if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); - NpgsqlDbType ret = NpgsqlDbType.Unknown; - switch (dbtype.ToLower().TrimStart('_')) { - case "int2": ret = NpgsqlDbType.Smallint;break; - case "int4": ret = NpgsqlDbType.Integer; break; - case "int8": ret = NpgsqlDbType.Bigint; break; - case "numeric": ret = NpgsqlDbType.Numeric; break; - case "float4": ret = NpgsqlDbType.Real; break; - case "float8": ret = NpgsqlDbType.Double; break; - case "money": ret = NpgsqlDbType.Money; break; + public int GetDbType(DbColumnInfo column) => (int)GetNpgsqlDbType(column); + NpgsqlDbType GetNpgsqlDbType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + var isarray = dbtype.EndsWith("[]"); + if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); + NpgsqlDbType ret = NpgsqlDbType.Unknown; + switch (dbtype.ToLower().TrimStart('_')) + { + case "int2": ret = NpgsqlDbType.Smallint; break; + case "int4": ret = NpgsqlDbType.Integer; break; + case "int8": ret = NpgsqlDbType.Bigint; break; + case "numeric": ret = NpgsqlDbType.Numeric; break; + case "float4": ret = NpgsqlDbType.Real; break; + case "float8": ret = NpgsqlDbType.Double; break; + case "money": ret = NpgsqlDbType.Money; break; - case "bpchar": ret = NpgsqlDbType.Char; break; - case "varchar": ret = NpgsqlDbType.Varchar; break; - case "text": ret = NpgsqlDbType.Text; break; + case "bpchar": ret = NpgsqlDbType.Char; break; + case "varchar": ret = NpgsqlDbType.Varchar; break; + case "text": ret = NpgsqlDbType.Text; break; - case "timestamp": ret = NpgsqlDbType.Timestamp; break; - case "timestamptz": ret = NpgsqlDbType.TimestampTz; break; - case "date": ret = NpgsqlDbType.Date; break; - case "time": ret = NpgsqlDbType.Time; break; - case "timetz": ret = NpgsqlDbType.TimeTz; break; - case "interval": ret = NpgsqlDbType.Interval; break; + case "timestamp": ret = NpgsqlDbType.Timestamp; break; + case "timestamptz": ret = NpgsqlDbType.TimestampTz; break; + case "date": ret = NpgsqlDbType.Date; break; + case "time": ret = NpgsqlDbType.Time; break; + case "timetz": ret = NpgsqlDbType.TimeTz; break; + case "interval": ret = NpgsqlDbType.Interval; break; - case "bool": ret = NpgsqlDbType.Boolean; break; - case "bytea": ret = NpgsqlDbType.Bytea; break; - case "bit": ret = NpgsqlDbType.Bit; break; - case "varbit": ret = NpgsqlDbType.Varbit; break; + case "bool": ret = NpgsqlDbType.Boolean; break; + case "bytea": ret = NpgsqlDbType.Bytea; break; + case "bit": ret = NpgsqlDbType.Bit; break; + case "varbit": ret = NpgsqlDbType.Varbit; break; - case "point": ret = NpgsqlDbType.Point; break; - case "line": ret = NpgsqlDbType.Line; break; - case "lseg": ret = NpgsqlDbType.LSeg; break; - case "box": ret = NpgsqlDbType.Box; break; - case "path": ret = NpgsqlDbType.Path; break; - case "polygon": ret = NpgsqlDbType.Polygon; break; - case "circle": ret = NpgsqlDbType.Circle; break; + case "point": ret = NpgsqlDbType.Point; break; + case "line": ret = NpgsqlDbType.Line; break; + case "lseg": ret = NpgsqlDbType.LSeg; break; + case "box": ret = NpgsqlDbType.Box; break; + case "path": ret = NpgsqlDbType.Path; break; + case "polygon": ret = NpgsqlDbType.Polygon; break; + case "circle": ret = NpgsqlDbType.Circle; break; - case "cidr": ret = NpgsqlDbType.Cidr; break; - case "inet": ret = NpgsqlDbType.Inet; break; - case "macaddr": ret = NpgsqlDbType.MacAddr; break; + case "cidr": ret = NpgsqlDbType.Cidr; break; + case "inet": ret = NpgsqlDbType.Inet; break; + case "macaddr": ret = NpgsqlDbType.MacAddr; break; - case "json": ret = NpgsqlDbType.Json; break; - case "jsonb": ret = NpgsqlDbType.Jsonb; break; - case "uuid": ret = NpgsqlDbType.Uuid; break; + case "json": ret = NpgsqlDbType.Json; break; + case "jsonb": ret = NpgsqlDbType.Jsonb; break; + case "uuid": ret = NpgsqlDbType.Uuid; break; - case "int4range": ret = NpgsqlDbType.Range | NpgsqlDbType.Integer; break; - case "int8range": ret = NpgsqlDbType.Range | NpgsqlDbType.Bigint; break; - case "numrange": ret = NpgsqlDbType.Range | NpgsqlDbType.Numeric; break; - case "tsrange": ret = NpgsqlDbType.Range | NpgsqlDbType.Timestamp; break; - case "tstzrange": ret = NpgsqlDbType.Range | NpgsqlDbType.TimestampTz; break; - case "daterange": ret = NpgsqlDbType.Range | NpgsqlDbType.Date; break; + case "int4range": ret = NpgsqlDbType.Range | NpgsqlDbType.Integer; break; + case "int8range": ret = NpgsqlDbType.Range | NpgsqlDbType.Bigint; break; + case "numrange": ret = NpgsqlDbType.Range | NpgsqlDbType.Numeric; break; + case "tsrange": ret = NpgsqlDbType.Range | NpgsqlDbType.Timestamp; break; + case "tstzrange": ret = NpgsqlDbType.Range | NpgsqlDbType.TimestampTz; break; + case "daterange": ret = NpgsqlDbType.Range | NpgsqlDbType.Date; break; - case "hstore": ret = NpgsqlDbType.Hstore; break; - case "geometry": ret = NpgsqlDbType.Geometry; break; - } - return isarray ? (ret | NpgsqlDbType.Array) : ret; - } + case "hstore": ret = NpgsqlDbType.Hstore; break; + case "geometry": ret = NpgsqlDbType.Geometry; break; + } + return isarray ? (ret | NpgsqlDbType.Array) : ret; + } - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)NpgsqlDbType.Smallint, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)NpgsqlDbType.Integer, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)NpgsqlDbType.Bigint, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)NpgsqlDbType.Numeric, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)NpgsqlDbType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)NpgsqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)NpgsqlDbType.Money, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)NpgsqlDbType.Smallint, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)NpgsqlDbType.Integer, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)NpgsqlDbType.Bigint, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)NpgsqlDbType.Numeric, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)NpgsqlDbType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)NpgsqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)NpgsqlDbType.Money, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)NpgsqlDbType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)NpgsqlDbType.Varchar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)NpgsqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)NpgsqlDbType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)NpgsqlDbType.Varchar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)NpgsqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)NpgsqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)NpgsqlDbType.TimestampTz, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)NpgsqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)NpgsqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)NpgsqlDbType.TimeTz, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)NpgsqlDbType.Interval, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)NpgsqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)NpgsqlDbType.TimestampTz, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)NpgsqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)NpgsqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)NpgsqlDbType.TimeTz, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)NpgsqlDbType.Interval, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)NpgsqlDbType.Boolean, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)NpgsqlDbType.Bytea, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Bit, ("(BitArray)", "{0}.ToBitArray()", "{0}.To1010()", "BitArray", typeof(BitArray), typeof(BitArray), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Varbit, ("(BitArray)", "{0}.ToBitArray()", "{0}.To1010()", "BitArray", typeof(BitArray), typeof(BitArray), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Boolean, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)NpgsqlDbType.Bytea, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Bit, ("(BitArray)", "{0}.ToBitArray()", "{0}.To1010()", "BitArray", typeof(BitArray), typeof(BitArray), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Varbit, ("(BitArray)", "{0}.ToBitArray()", "{0}.To1010()", "BitArray", typeof(BitArray), typeof(BitArray), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Point, ("(NpgsqlPoint?)", "NpgsqlPoint.Parse({0})", "{0}.ToString()", "NpgsqlPoint", typeof(NpgsqlPoint), typeof(NpgsqlPoint?), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Line, ("(NpgsqlLine?)", "NpgsqlLine.Parse({0})", "{0}.ToString()", "NpgsqlLine", typeof(NpgsqlLine), typeof(NpgsqlLine?), "{0}", "GetValue") }, - { (int)NpgsqlDbType.LSeg, ("(NpgsqlLSeg?)", "NpgsqlLSeg.Parse({0})", "{0}.ToString()", "NpgsqlLSeg", typeof(NpgsqlLSeg), typeof(NpgsqlLSeg?), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Box, ("(NpgsqlBox?)", "NpgsqlBox.Parse({0})", "{0}.ToString()", "NpgsqlBox", typeof(NpgsqlBox), typeof(NpgsqlBox?), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Path, ("(NpgsqlPath?)", "NpgsqlPath.Parse({0})", "{0}.ToString()", "NpgsqlPath", typeof(NpgsqlPath), typeof(NpgsqlPath?), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Polygon, ("(NpgsqlPolygon?)", "NpgsqlPolygon.Parse({0})", "{0}.ToString()", "NpgsqlPolygon", typeof(NpgsqlPolygon), typeof(NpgsqlPolygon?), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Circle, ("(NpgsqlCircle?)", "NpgsqlCircle.Parse({0})", "{0}.ToString()", "NpgsqlCircle", typeof(NpgsqlCircle), typeof(NpgsqlCircle?), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Point, ("(NpgsqlPoint?)", "NpgsqlPoint.Parse({0})", "{0}.ToString()", "NpgsqlPoint", typeof(NpgsqlPoint), typeof(NpgsqlPoint?), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Line, ("(NpgsqlLine?)", "NpgsqlLine.Parse({0})", "{0}.ToString()", "NpgsqlLine", typeof(NpgsqlLine), typeof(NpgsqlLine?), "{0}", "GetValue") }, + { (int)NpgsqlDbType.LSeg, ("(NpgsqlLSeg?)", "NpgsqlLSeg.Parse({0})", "{0}.ToString()", "NpgsqlLSeg", typeof(NpgsqlLSeg), typeof(NpgsqlLSeg?), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Box, ("(NpgsqlBox?)", "NpgsqlBox.Parse({0})", "{0}.ToString()", "NpgsqlBox", typeof(NpgsqlBox), typeof(NpgsqlBox?), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Path, ("(NpgsqlPath?)", "NpgsqlPath.Parse({0})", "{0}.ToString()", "NpgsqlPath", typeof(NpgsqlPath), typeof(NpgsqlPath?), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Polygon, ("(NpgsqlPolygon?)", "NpgsqlPolygon.Parse({0})", "{0}.ToString()", "NpgsqlPolygon", typeof(NpgsqlPolygon), typeof(NpgsqlPolygon?), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Circle, ("(NpgsqlCircle?)", "NpgsqlCircle.Parse({0})", "{0}.ToString()", "NpgsqlCircle", typeof(NpgsqlCircle), typeof(NpgsqlCircle?), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Cidr, ("((IPAddress, int)?)", "(IPAddress, int)({0})", "{0}.ToString()", "(IPAddress, int)", typeof((IPAddress, int)), typeof((IPAddress, int)?), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Inet, ("(IPAddress)", "IPAddress.Parse({0})", "{0}.ToString()", "IPAddress", typeof(IPAddress), typeof(IPAddress), "{0}", "GetValue") }, - { (int)NpgsqlDbType.MacAddr, ("(PhysicalAddress?)", "PhysicalAddress.Parse({0})", "{0}.ToString()", "PhysicalAddress", typeof(PhysicalAddress), typeof(PhysicalAddress), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Cidr, ("((IPAddress, int)?)", "(IPAddress, int)({0})", "{0}.ToString()", "(IPAddress, int)", typeof((IPAddress, int)), typeof((IPAddress, int)?), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Inet, ("(IPAddress)", "IPAddress.Parse({0})", "{0}.ToString()", "IPAddress", typeof(IPAddress), typeof(IPAddress), "{0}", "GetValue") }, + { (int)NpgsqlDbType.MacAddr, ("(PhysicalAddress?)", "PhysicalAddress.Parse({0})", "{0}.ToString()", "PhysicalAddress", typeof(PhysicalAddress), typeof(PhysicalAddress), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Json, ("(JToken)", "JToken.Parse({0})", "{0}.ToString()", "JToken", typeof(JToken), typeof(JToken), "{0}", "GetString") }, - { (int)NpgsqlDbType.Jsonb, ("(JToken)", "JToken.Parse({0})", "{0}.ToString()", "JToken", typeof(JToken), typeof(JToken), "{0}", "GetString") }, - { (int)NpgsqlDbType.Uuid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + { (int)NpgsqlDbType.Json, ("(JToken)", "JToken.Parse({0})", "{0}.ToString()", "JToken", typeof(JToken), typeof(JToken), "{0}", "GetString") }, + { (int)NpgsqlDbType.Jsonb, ("(JToken)", "JToken.Parse({0})", "{0}.ToString()", "JToken", typeof(JToken), typeof(JToken), "{0}", "GetString") }, + { (int)NpgsqlDbType.Uuid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Integer), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Bigint), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Numeric), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Timestamp), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.TimestampTz), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Date), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Integer), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Bigint), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Numeric), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Timestamp), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.TimestampTz), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Date), ("(NpgsqlRange?)", "{0}.ToNpgsqlRange()", "{0}.ToString()", "NpgsqlRange", typeof(NpgsqlRange), typeof(NpgsqlRange?), "{0}", "GetString") }, - { (int)NpgsqlDbType.Hstore, ("(Dictionary)", "JsonConvert.DeserializeObject>({0})", "JsonConvert.SerializeObject({0})", "Dictionary", typeof(Dictionary), typeof(Dictionary), "{0}", "GetValue") }, - { (int)NpgsqlDbType.Geometry, ("(PostgisGeometry)", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "PostgisGeometry", typeof(PostgisGeometry), typeof(PostgisGeometry), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Hstore, ("(Dictionary)", "JsonConvert.DeserializeObject>({0})", "JsonConvert.SerializeObject({0})", "Dictionary", typeof(Dictionary), typeof(Dictionary), "{0}", "GetValue") }, + { (int)NpgsqlDbType.Geometry, ("(PostgisGeometry)", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "PostgisGeometry", typeof(PostgisGeometry), typeof(PostgisGeometry), "{0}", "GetValue") }, /*** array ***/ { (int)(NpgsqlDbType.Smallint | NpgsqlDbType.Array), ("(short[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "short[]", typeof(short[]), typeof(short[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Integer | NpgsqlDbType.Array), ("(int[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "int[]", typeof(int[]), typeof(int[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Bigint | NpgsqlDbType.Array), ("(long[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "long[]", typeof(long[]), typeof(long[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Numeric | NpgsqlDbType.Array), ("(decimal[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "decimal[]", typeof(decimal[]), typeof(decimal[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Real | NpgsqlDbType.Array), ("(float[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "float[]", typeof(float[]), typeof(float[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Double | NpgsqlDbType.Array), ("(double[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "double[]", typeof(double[]), typeof(double[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Money | NpgsqlDbType.Array), ("(decimal[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "decimal[]", typeof(decimal[]), typeof(decimal[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Integer | NpgsqlDbType.Array), ("(int[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "int[]", typeof(int[]), typeof(int[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Bigint | NpgsqlDbType.Array), ("(long[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "long[]", typeof(long[]), typeof(long[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Numeric | NpgsqlDbType.Array), ("(decimal[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "decimal[]", typeof(decimal[]), typeof(decimal[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Real | NpgsqlDbType.Array), ("(float[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "float[]", typeof(float[]), typeof(float[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Double | NpgsqlDbType.Array), ("(double[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "double[]", typeof(double[]), typeof(double[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Money | NpgsqlDbType.Array), ("(decimal[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "decimal[]", typeof(decimal[]), typeof(decimal[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Char | NpgsqlDbType.Array), ("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Varchar | NpgsqlDbType.Array), ("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Text | NpgsqlDbType.Array), ("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Char | NpgsqlDbType.Array), ("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Varchar | NpgsqlDbType.Array), ("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Text | NpgsqlDbType.Array), ("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Timestamp | NpgsqlDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.TimestampTz | NpgsqlDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Date | NpgsqlDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Time | NpgsqlDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.TimeTz | NpgsqlDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Interval | NpgsqlDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Timestamp | NpgsqlDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.TimestampTz | NpgsqlDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Date | NpgsqlDbType.Array), ("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Time | NpgsqlDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.TimeTz | NpgsqlDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Interval | NpgsqlDbType.Array), ("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Boolean | NpgsqlDbType.Array), ("(bool[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "bool[]", typeof(bool[]), typeof(bool[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Bytea | NpgsqlDbType.Array), ("(byte[][])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "byte[][]", typeof(byte[][]), typeof(byte[][]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Bit | NpgsqlDbType.Array), ("(BitArray[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "BitArray[]", typeof(BitArray[]), typeof(BitArray[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Varbit | NpgsqlDbType.Array), ("(BitArray[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "BitArray[]", typeof(BitArray[]), typeof(BitArray[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Boolean | NpgsqlDbType.Array), ("(bool[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "bool[]", typeof(bool[]), typeof(bool[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Bytea | NpgsqlDbType.Array), ("(byte[][])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "byte[][]", typeof(byte[][]), typeof(byte[][]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Bit | NpgsqlDbType.Array), ("(BitArray[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "BitArray[]", typeof(BitArray[]), typeof(BitArray[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Varbit | NpgsqlDbType.Array), ("(BitArray[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "BitArray[]", typeof(BitArray[]), typeof(BitArray[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Point | NpgsqlDbType.Array), ("(NpgsqlPoint[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlPoint[]", typeof(NpgsqlPoint[]), typeof(NpgsqlPoint[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Line | NpgsqlDbType.Array), ("(NpgsqlLine[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlLine[]", typeof(NpgsqlLine[]), typeof(NpgsqlLine[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.LSeg | NpgsqlDbType.Array), ("(NpgsqlLSeg[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlLSeg[]", typeof(NpgsqlLSeg[]), typeof(NpgsqlLSeg[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Box | NpgsqlDbType.Array), ("(NpgsqlBox[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlBox[]", typeof(NpgsqlBox[]), typeof(NpgsqlBox[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Path | NpgsqlDbType.Array), ("(NpgsqlPath[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlPath[]", typeof(NpgsqlPath[]), typeof(NpgsqlPath[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Polygon | NpgsqlDbType.Array), ("(NpgsqlPolygon[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlPolygon[]", typeof(NpgsqlPolygon[]), typeof(NpgsqlPolygon[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Circle | NpgsqlDbType.Array), ("(NpgsqlCircle[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlCircle[]", typeof(NpgsqlCircle[]), typeof(NpgsqlCircle[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Point | NpgsqlDbType.Array), ("(NpgsqlPoint[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlPoint[]", typeof(NpgsqlPoint[]), typeof(NpgsqlPoint[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Line | NpgsqlDbType.Array), ("(NpgsqlLine[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlLine[]", typeof(NpgsqlLine[]), typeof(NpgsqlLine[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.LSeg | NpgsqlDbType.Array), ("(NpgsqlLSeg[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlLSeg[]", typeof(NpgsqlLSeg[]), typeof(NpgsqlLSeg[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Box | NpgsqlDbType.Array), ("(NpgsqlBox[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlBox[]", typeof(NpgsqlBox[]), typeof(NpgsqlBox[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Path | NpgsqlDbType.Array), ("(NpgsqlPath[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlPath[]", typeof(NpgsqlPath[]), typeof(NpgsqlPath[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Polygon | NpgsqlDbType.Array), ("(NpgsqlPolygon[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlPolygon[]", typeof(NpgsqlPolygon[]), typeof(NpgsqlPolygon[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Circle | NpgsqlDbType.Array), ("(NpgsqlCircle[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "NpgsqlCircle[]", typeof(NpgsqlCircle[]), typeof(NpgsqlCircle[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Cidr | NpgsqlDbType.Array), ("((IPAddress, int)[])", "JsonConvert.DeserializeObject<(IPAddress, int)[]>({0})", "JsonConvert.SerializeObject({0})", "(IPAddress, int)[]", typeof((IPAddress, int)[]), typeof((IPAddress, int)[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Inet | NpgsqlDbType.Array), ("(IPAddress[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "IPAddress[]", typeof(IPAddress[]), typeof(IPAddress[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.MacAddr | NpgsqlDbType.Array), ("(PhysicalAddress[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "PhysicalAddress[]", typeof(PhysicalAddress[]), typeof(PhysicalAddress[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Cidr | NpgsqlDbType.Array), ("((IPAddress, int)[])", "JsonConvert.DeserializeObject<(IPAddress, int)[]>({0})", "JsonConvert.SerializeObject({0})", "(IPAddress, int)[]", typeof((IPAddress, int)[]), typeof((IPAddress, int)[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Inet | NpgsqlDbType.Array), ("(IPAddress[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "IPAddress[]", typeof(IPAddress[]), typeof(IPAddress[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.MacAddr | NpgsqlDbType.Array), ("(PhysicalAddress[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "PhysicalAddress[]", typeof(PhysicalAddress[]), typeof(PhysicalAddress[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Json | NpgsqlDbType.Array), ("(JToken[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "JToken[]", typeof(JToken[]), typeof(JToken[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Jsonb | NpgsqlDbType.Array), ("(JToken[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "JToken[]", typeof(JToken[]), typeof(JToken[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Uuid | NpgsqlDbType.Array), ("(Guid[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "Guid[]", typeof(Guid[]), typeof(Guid[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Json | NpgsqlDbType.Array), ("(JToken[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "JToken[]", typeof(JToken[]), typeof(JToken[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Jsonb | NpgsqlDbType.Array), ("(JToken[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "JToken[]", typeof(JToken[]), typeof(JToken[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Uuid | NpgsqlDbType.Array), ("(Guid[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "Guid[]", typeof(Guid[]), typeof(Guid[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Integer | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Bigint | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Numeric | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Timestamp | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.TimestampTz | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Range | NpgsqlDbType.Date | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Integer | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Bigint | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Numeric | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Timestamp | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.TimestampTz | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Range | NpgsqlDbType.Date | NpgsqlDbType.Array), ("(NpgsqlRange[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "NpgsqlRange[]", typeof(NpgsqlRange[]), typeof(NpgsqlRange[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Hstore | NpgsqlDbType.Array), ("(Dictionary[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "Dictionary[]", typeof(Dictionary[]), typeof(Dictionary[]), "{0}", "GetValue") }, - { (int)(NpgsqlDbType.Geometry | NpgsqlDbType.Array), ("(PostgisGeometry[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "PostgisGeometry[]", typeof(PostgisGeometry[]), typeof(PostgisGeometry[]), "{0}", "GetValue") }, - }; + { (int)(NpgsqlDbType.Hstore | NpgsqlDbType.Array), ("(Dictionary[])", "JsonConvert.DeserializeObject[]>({0})", "JsonConvert.SerializeObject({0})", "Dictionary[]", typeof(Dictionary[]), typeof(Dictionary[]), "{0}", "GetValue") }, + { (int)(NpgsqlDbType.Geometry | NpgsqlDbType.Array), ("(PostgisGeometry[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "PostgisGeometry[]", typeof(PostgisGeometry[]), typeof(PostgisGeometry[]), "{0}", "GetValue") }, + }; - public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; - public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; - public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; - public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; - public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; - public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; - public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; - public List GetDatabases() { - var sql = @" select datname from pg_database where datname not in ('template1', 'template0')"; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); - } + public List GetDatabases() + { + var sql = @" select datname from pg_database where datname not in ('template1', 'template0')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } - public List GetTablesByDatabase(params string[] database) { - var olddatabase = ""; - using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { - olddatabase = conn.Value.Database; - } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; - var tables = new List(); + public List GetTablesByDatabase(params string[] database) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + var tables = new List(); - foreach (var db in dbs) { - if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; - var loc1 = new List(); - var loc2 = new Dictionary(); - var loc3 = new Dictionary>(); + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); - var sql = $@" + var sql = $@" select b.nspname || '.' || a.tablename, a.schemaname, @@ -246,34 +255,36 @@ left join pg_description d on d.objoid = a.oid and objsubid = 0 where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('m','v') and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews') "; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); - foreach (object[] row in ds) { - var object_id = string.Concat(row[0]); - var owner = string.Concat(row[1]); - var table = string.Concat(row[2]); - var comment = string.Concat(row[3]); - Enum.TryParse(string.Concat(row[4]), out var type); - loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); - loc3.Add(object_id, new Dictionary()); - switch (type) { - case DbTableType.VIEW: - case DbTableType.TABLE: - loc6.Add(object_id); - break; - case DbTableType.StoreProcedure: - loc66.Add(object_id); - break; - } - } - if (loc6.Count == 0) return loc1; - string loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - string loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc6 = new List(); + var loc66 = new List(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6.Add(object_id); + break; + case DbTableType.StoreProcedure: + loc66.Add(object_id); + break; + } + } + if (loc6.Count == 0) return loc1; + string loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; + string loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; - sql = $@" + sql = $@" select ns.nspname || '.' || c.relname as id, a.attname, @@ -297,49 +308,53 @@ left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum inner join pg_namespace ns on ns.oid = c.relnamespace inner join pg_namespace ns2 on ns2.oid = t.typnamespace where ns.nspname || '.' || c.relname in ({loc8})"; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - foreach (object[] row in ds) { - var object_id = string.Concat(row[0]); - var column = string.Concat(row[1]); - var type = string.Concat(row[2]); - var max_length = int.Parse(string.Concat(row[3])); - var sqlType = string.Concat(row[4]); - var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); - var comment = string.Concat(row[7]); - int attndims = int.Parse(string.Concat(row[8])); - string typtype = string.Concat(row[9]); - string owner = string.Concat(row[10]); - int attnum = int.Parse(string.Concat(row[11])); - switch (sqlType.ToLower()) { - case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; - default: max_length *= 8; break; - } - if (max_length <= 0) max_length = -1; - if (type.StartsWith("_")) { - type = type.Substring(1); - if (attndims == 0) attndims++; - } - if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var type = string.Concat(row[2]); + var max_length = int.Parse(string.Concat(row[3])); + var sqlType = string.Concat(row[4]); + var is_nullable = string.Concat(row[5]) == "1"; + var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var comment = string.Concat(row[7]); + int attndims = int.Parse(string.Concat(row[8])); + string typtype = string.Concat(row[9]); + string owner = string.Concat(row[10]); + int attnum = int.Parse(string.Concat(row[11])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (max_length <= 0) max_length = -1; + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); - loc3[object_id].Add(column, new DbColumnInfo { - Name = column, - MaxLength = max_length, - IsIdentity = is_identity, - IsNullable = is_nullable, - IsPrimary = false, - DbTypeText = type, - DbTypeTextFull = sqlType, - Table = loc2[object_id], - Coment = comment - }); - loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); - loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); - } + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Coment = comment + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } - sql = $@" + sql = $@" select ns.nspname || '.' || d.relname as table_id, c.attname, @@ -357,59 +372,66 @@ inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid where ns.nspname || '.' || d.relname in ({loc8}) "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); - foreach (object[] row in ds) { - var object_id = string.Concat(row[0]); - var column = string.Concat(row[1]); - var index_id = string.Concat(row[2]); - var is_unique = string.Concat(row[3]) == "1"; - var is_primary_key = string.Concat(row[4]) == "1"; - var is_clustered = string.Concat(row[5]) == "1"; - var is_desc = int.Parse(string.Concat(row[6])); - var inkey = string.Concat(row[7]).Split(' '); - var attnum = int.Parse(string.Concat(row[8])); - attnum = int.Parse(inkey[attnum - 1]); - foreach (string tc in loc3[object_id].Keys) { - if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) { - column = tc; - break; - } - } - if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; - var loc9 = loc3[object_id][column]; - if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var index_id = string.Concat(row[2]); + var is_unique = string.Concat(row[3]) == "1"; + var is_primary_key = string.Concat(row[4]) == "1"; + var is_clustered = string.Concat(row[5]) == "1"; + var is_desc = int.Parse(string.Concat(row[6])); + var inkey = string.Concat(row[7]).Split(' '); + var attnum = int.Parse(string.Concat(row[8])); + attnum = int.Parse(inkey[attnum - 1]); + foreach (string tc in loc3[object_id].Keys) + { + if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) + { + column = tc; + break; + } + } + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + var loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; - if (!indexColumns.TryGetValue(object_id, out loc10)) - indexColumns.Add(object_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - if (is_unique && !is_primary_key) { - if (!uniqueColumns.TryGetValue(object_id, out loc10)) - uniqueColumns.Add(object_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - } - } - foreach (var object_id in indexColumns.Keys) { - foreach (var column in indexColumns[object_id]) - loc2[object_id].IndexesDict.Add(column.Key, column.Value); - } - foreach (var object_id in uniqueColumns.Keys) { - foreach (var column in uniqueColumns[object_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[object_id].UniquesDict.Add(column.Key, column.Value); - } - } + Dictionary> loc10 = null; + List loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } - sql = $@" + sql = $@" select ns.nspname || '.' || b.relname as table_id, array(select attname from pg_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, @@ -426,81 +448,92 @@ inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_namespace ns2 on ns2.oid = c.relnamespace where ns.nspname || '.' || b.relname in ({loc8}) "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (object[] row in ds) { - var table_id = string.Concat(row[0]); - var column = row[1] as string[]; - var fk_id = string.Concat(row[2]); - var ref_table_id = string.Concat(row[3]); - var is_foreign_key = string.Concat(row[4]) == "1"; - var referenced_column = row[5] as string[]; - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); - if (loc2.ContainsKey(ref_table_id) == false) continue; + if (loc2.ContainsKey(ref_table_id) == false) continue; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); - for (int a = 0; a < column.Length; a++) { - loc13.Columns.Add(loc3[table_id][column[a]]); - loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); - } - } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); - foreach (var table_id in loc3.Keys) { - foreach (var loc5 in loc3[table_id].Values) { - loc2[table_id].Columns.Add(loc5); - if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); - if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); - } - } - foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) { - foreach (var loc5 in loc4.UniquesDict.First().Value) { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } - loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc4.Columns.Sort((c1, c2) => { - int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); - if (compare == 0) { - bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); - bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); - compare = b2.CompareTo(b1); - } - if (compare == 0) compare = c1.Name.CompareTo(c2.Name); - return compare; - }); - loc1.Add(loc4); - } - loc1.Sort((t1, t2) => { - var ret = t1.Schema.CompareTo(t2.Schema); - if (ret == 0) ret = t1.Name.CompareTo(t2.Name); - return ret; - }); + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + { + foreach (var loc5 in loc4.UniquesDict.First().Value) + { + loc5.IsPrimary = true; + loc4.Primarys.Add(loc5); + } + } + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); - loc2.Clear(); - loc3.Clear(); - tables.AddRange(loc1); - } - return tables; - } + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } - public List GetEnumsByDatabase(params string[] database) { - if (database == null || database.Length == 0) return new List(); - var drs = _orm.Ado.Query<(string name, string label)>(CommandType.Text, _commonUtils.FormatSql(@" + public List GetEnumsByDatabase(params string[] database) + { + if (database == null || database.Length == 0) return new List(); + var drs = _orm.Ado.Query<(string name, string label)>(CommandType.Text, _commonUtils.FormatSql(@" select ns.nspname || '.' || a.typname, b.enumlabel @@ -508,15 +541,16 @@ from pg_type a inner join pg_enum b on b.enumtypid = a.oid inner join pg_namespace ns on ns.oid = a.typnamespace where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information_schema.schemata where catalog_name in {0})", database)); - var ret = new Dictionary>(); - foreach (var dr in drs) { - if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); - var key = dr.label; - if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) - key = $"Unkown{ret[dr.name].Count + 1}"; - if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); - } - return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); - } - } + var ret = new Dictionary>(); + foreach (var dr in drs) + { + if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); + var key = dr.label; + if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) + key = $"Unkown{ret[dr.name].Count + 1}"; + if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); + } + return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index cc3af126..28f59721 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -8,491 +8,557 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.PostgreSQL { - class PostgreSQLExpression : CommonExpression { +namespace FreeSql.PostgreSQL +{ + class PostgreSQLExpression : CommonExpression + { - public PostgreSQLExpression(CommonUtils common) : base(common) { } + public PostgreSQLExpression(CommonUtils common) : base(common) { } - public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.NodeType) { - case ExpressionType.Convert: - var operandExp = (exp as UnaryExpression)?.Operand; - var gentype = exp.Type.NullableTypeOrThis(); - if (gentype != operandExp.Type.NullableTypeOrThis()) { - switch (exp.Type.NullableTypeOrThis().ToString()) { - case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; - case "System.Byte": return $"({getExp(operandExp)})::int2"; - case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; - case "System.Decimal": return $"({getExp(operandExp)})::numeric"; - case "System.Double": return $"({getExp(operandExp)})::float8"; - case "System.Int16": return $"({getExp(operandExp)})::int2"; - case "System.Int32": return $"({getExp(operandExp)})::int4"; - case "System.Int64": return $"({getExp(operandExp)})::int8"; - case "System.SByte": return $"({getExp(operandExp)})::int2"; - case "System.Single": return $"({getExp(operandExp)})::float4"; - case "System.String": return $"({getExp(operandExp)})::varchar"; - case "System.UInt16": return $"({getExp(operandExp)})::int2"; - case "System.UInt32": return $"({getExp(operandExp)})::int4"; - case "System.UInt64": return $"({getExp(operandExp)})::int8"; - case "System.Guid": return $"({getExp(operandExp)})::uuid"; - } - } - break; - case ExpressionType.ArrayLength: - var arrOperExp = getExp((exp as UnaryExpression).Operand); - if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; - return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; - case ExpressionType.Call: - var callExp = exp as MethodCallExpression; + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(operandExp)})::int2"; + case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.Decimal": return $"({getExp(operandExp)})::numeric"; + case "System.Double": return $"({getExp(operandExp)})::float8"; + case "System.Int16": return $"({getExp(operandExp)})::int2"; + case "System.Int32": return $"({getExp(operandExp)})::int4"; + case "System.Int64": return $"({getExp(operandExp)})::int8"; + case "System.SByte": return $"({getExp(operandExp)})::int2"; + case "System.Single": return $"({getExp(operandExp)})::float4"; + case "System.String": return $"({getExp(operandExp)})::varchar"; + case "System.UInt16": return $"({getExp(operandExp)})::int2"; + case "System.UInt32": return $"({getExp(operandExp)})::int4"; + case "System.UInt64": return $"({getExp(operandExp)})::int8"; + case "System.Guid": return $"({getExp(operandExp)})::uuid"; + } + } + break; + case ExpressionType.ArrayLength: + var arrOperExp = getExp((exp as UnaryExpression).Operand); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; - switch (callExp.Method.Name) { - case "Parse": - case "TryParse": - switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { - case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; - case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; - case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; - case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; - case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; - case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; - case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; - case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; - case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; - case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; - case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; - case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; - case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; - case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid"; - } - break; - case "NewGuid": - break; - case "Next": - if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; - break; - case "NextDouble": - if (callExp.Object?.Type == typeof(Random)) return "random()"; - break; - case "Random": - if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; - break; - case "ToString": - if (callExp.Object != null) return $"({getExp(callExp.Object)})::varchar"; - break; - } + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; + case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; + case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; + case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid"; + } + break; + case "NewGuid": + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + break; + case "ToString": + if (callExp.Object != null) return $"({getExp(callExp.Object)})::varchar"; + break; + } - var objExp = callExp.Object; - var objType = objExp?.Type; - if (objType?.FullName == "System.Byte[]") return null; + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; - var argIndex = 0; - if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) { - objExp = callExp.Arguments.FirstOrDefault(); - objType = objExp?.Type; - argIndex++; - } - if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) { - var left = objExp == null ? null : getExp(objExp); - switch (objType.FullName) { - case "Newtonsoft.Json.Linq.JToken": - case "Newtonsoft.Json.Linq.JObject": - case "Newtonsoft.Json.Linq.JArray": - switch (callExp.Method.Name) { - case "Any": return $"(jsonb_array_length(coalesce({left},'[]')) > 0)"; - case "Contains": - var json = getExp(callExp.Arguments[argIndex]); - if (objType == typeof(JArray)) - return $"(coalesce({left},'[]') ? ({json})::varchar)"; - if (json.StartsWith("'") && json.EndsWith("'")) - return $"(coalesce({left},'{{}}') @> {_common.FormatSql("{0}", JToken.Parse(json.Trim('\'')))})"; - return $"(coalesce({left},'{{}}') @> ({json})::jsonb)"; - case "ContainsKey": return $"(coalesce({left},'{{}}') ? {getExp(callExp.Arguments[argIndex])})"; - case "Concat": - var right2 = getExp(callExp.Arguments[argIndex]); - return $"(coalesce({left},'{{}}') || {right2})"; - case "LongCount": - case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; - case "Parse": - var json2 = getExp(callExp.Arguments[argIndex]); - if (json2.StartsWith("'") && json2.EndsWith("'")) return _common.FormatSql("{0}", JToken.Parse(json2.Trim('\''))); - return $"({json2})::jsonb"; - } - break; - } - if (objType.FullName == typeof(Dictionary).FullName) { - switch (callExp.Method.Name) { - case "Contains": - var right = getExp(callExp.Arguments[argIndex]); - return $"({left} @> ({right}))"; - case "ContainsKey": return $"({left} ? {getExp(callExp.Arguments[argIndex])})"; - case "Concat": return $"({left} || {getExp(callExp.Arguments[argIndex])})"; - case "GetLength": - case "GetLongLength": - case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; - case "Keys": return $"akeys({left})"; - case "Values": return $"avals({left})"; - } - } - switch (callExp.Method.Name) { - case "Any": - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; - case "Contains": - //判断 in 或 array @> array - var right1 = getExp(callExp.Arguments[argIndex]); - if (left.StartsWith("array[") || left.EndsWith("]")) - return $"{right1} in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) - return $"{right1} in {left}"; - if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; - return $"({left} @> array[{right1}])"; - case "Concat": - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - var right2 = getExp(callExp.Arguments[argIndex]); - if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; - return $"({left} || {right2})"; - case "GetLength": - case "GetLongLength": - case "Length": - case "Count": - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - return $"case when {left} is null then 0 else array_length({left},1) end"; - } - } - break; - case ExpressionType.MemberAccess: - var memExp = exp as MemberExpression; - var memParentExp = memExp.Expression?.Type; - if (memParentExp?.FullName == "System.Byte[]") return null; - if (memParentExp != null) { - if (memParentExp.IsArray == true) { - var left = getExp(memExp.Expression); - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - switch (memExp.Member.Name) { - case "Length": - case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; - } - } - switch (memParentExp.FullName) { - case "Newtonsoft.Json.Linq.JToken": - case "Newtonsoft.Json.Linq.JObject": - case "Newtonsoft.Json.Linq.JArray": - var left = getExp(memExp.Expression); - switch (memExp.Member.Name) { - case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; - } - break; - } - if (memParentExp.FullName == typeof(Dictionary).FullName) { - var left = getExp(memExp.Expression); - switch (memExp.Member.Name) { - case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; - case "Keys": return $"akeys({left})"; - case "Values": return $"avals({left})"; - } - } - } - break; - case ExpressionType.NewArrayInit: - var arrExp = exp as NewArrayExpression; - var arrSb = new StringBuilder(); - arrSb.Append("array["); - for (var a = 0; a < arrExp.Expressions.Count; a++) { - if (a > 0) arrSb.Append(","); - arrSb.Append(getExp(arrExp.Expressions[a])); - } - if (arrSb.Length == 1) arrSb.Append("NULL"); - return arrSb.Append("]").ToString(); - case ExpressionType.ListInit: - var listExp = exp as ListInitExpression; - var listSb = new StringBuilder(); - listSb.Append("("); - for (var a = 0; a < listExp.Initializers.Count; a++) { - if (listExp.Initializers[a].Arguments.Any() == false) continue; - if (a > 0) listSb.Append(","); - listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); - } - if (listSb.Length == 1) listSb.Append("NULL"); - return listSb.Append(")").ToString(); - case ExpressionType.New: - var newExp = exp as NewExpression; - if (typeof(IList).IsAssignableFrom(newExp.Type)) { - if (newExp.Arguments.Count == 0) return "(NULL)"; - if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; - return getExp(newExp.Arguments[0]); - } - return null; - } - return null; - } + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (objType.FullName) + { + case "Newtonsoft.Json.Linq.JToken": + case "Newtonsoft.Json.Linq.JObject": + case "Newtonsoft.Json.Linq.JArray": + switch (callExp.Method.Name) + { + case "Any": return $"(jsonb_array_length(coalesce({left},'[]')) > 0)"; + case "Contains": + var json = getExp(callExp.Arguments[argIndex]); + if (objType == typeof(JArray)) + return $"(coalesce({left},'[]') ? ({json})::varchar)"; + if (json.StartsWith("'") && json.EndsWith("'")) + return $"(coalesce({left},'{{}}') @> {_common.FormatSql("{0}", JToken.Parse(json.Trim('\'')))})"; + return $"(coalesce({left},'{{}}') @> ({json})::jsonb)"; + case "ContainsKey": return $"(coalesce({left},'{{}}') ? {getExp(callExp.Arguments[argIndex])})"; + case "Concat": + var right2 = getExp(callExp.Arguments[argIndex]); + return $"(coalesce({left},'{{}}') || {right2})"; + case "LongCount": + case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; + case "Parse": + var json2 = getExp(callExp.Arguments[argIndex]); + if (json2.StartsWith("'") && json2.EndsWith("'")) return _common.FormatSql("{0}", JToken.Parse(json2.Trim('\''))); + return $"({json2})::jsonb"; + } + break; + } + if (objType.FullName == typeof(Dictionary).FullName) + { + switch (callExp.Method.Name) + { + case "Contains": + var right = getExp(callExp.Arguments[argIndex]); + return $"({left} @> ({right}))"; + case "ContainsKey": return $"({left} ? {getExp(callExp.Arguments[argIndex])})"; + case "Concat": return $"({left} || {getExp(callExp.Arguments[argIndex])})"; + case "GetLength": + case "GetLongLength": + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + switch (callExp.Method.Name) + { + case "Any": + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; + case "Contains": + //判断 in 或 array @> array + var right1 = getExp(callExp.Arguments[argIndex]); + if (left.StartsWith("array[") || left.EndsWith("]")) + return $"{right1} in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) + return $"{right1} in {left}"; + if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; + return $"({left} @> array[{right1}])"; + case "Concat": + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + var right2 = getExp(callExp.Arguments[argIndex]); + if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; + return $"({left} || {right2})"; + case "GetLength": + case "GetLongLength": + case "Length": + case "Count": + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + break; + case ExpressionType.MemberAccess: + var memExp = exp as MemberExpression; + var memParentExp = memExp.Expression?.Type; + if (memParentExp?.FullName == "System.Byte[]") return null; + if (memParentExp != null) + { + if (memParentExp.IsArray == true) + { + var left = getExp(memExp.Expression); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + switch (memExp.Member.Name) + { + case "Length": + case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + switch (memParentExp.FullName) + { + case "Newtonsoft.Json.Linq.JToken": + case "Newtonsoft.Json.Linq.JObject": + case "Newtonsoft.Json.Linq.JArray": + var left = getExp(memExp.Expression); + switch (memExp.Member.Name) + { + case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; + } + break; + } + if (memParentExp.FullName == typeof(Dictionary).FullName) + { + var left = getExp(memExp.Expression); + switch (memExp.Member.Name) + { + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("array["); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append("]").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } - public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Empty": return "''"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Length": return $"char_length({left})"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Now": return "current_timestamp"; - case "UtcNow": return "(current_timestamp at time zone 'UTC')"; - case "Today": return "current_date"; - case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; - case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Date": return $"({left})::date"; - case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)"; - case "DayOfWeek": return $"extract(dow from ({left})::timestamp)"; - case "Day": return $"extract(day from ({left})::timestamp)"; - case "DayOfYear": return $"extract(doy from ({left})::timestamp)"; - case "Month": return $"extract(month from ({left})::timestamp)"; - case "Year": return $"extract(year from ({left})::timestamp)"; - case "Hour": return $"extract(hour from ({left})::timestamp)"; - case "Minute": return $"extract(minute from ({left})::timestamp)"; - case "Second": return $"extract(second from ({left})::timestamp)"; - case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)"; - case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Zero": return "0"; - case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 - case "MaxValue": return "922337203685477580"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})"; - case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)"; - case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)"; - case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)"; - case "Seconds": return $"(floor(({left})/1000000)::int8%60)"; - case "Ticks": return $"(({left})*10)"; - case "TotalDays": return $"(({left})/{(long)1000000 * 60 * 60 * 24})"; - case "TotalHours": return $"(({left})/{(long)1000000 * 60 * 60})"; - case "TotalMilliseconds": return $"(({left})/1000)"; - case "TotalMinutes": return $"(({left})/{(long)1000000 * 60})"; - case "TotalSeconds": return $"(({left})/1000000)"; - } - return null; - } + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "current_timestamp"; + case "UtcNow": return "(current_timestamp at time zone 'UTC')"; + case "Today": return "current_date"; + case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; + case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"({left})::date"; + case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)"; + case "DayOfWeek": return $"extract(dow from ({left})::timestamp)"; + case "Day": return $"extract(day from ({left})::timestamp)"; + case "DayOfYear": return $"extract(doy from ({left})::timestamp)"; + case "Month": return $"extract(month from ({left})::timestamp)"; + case "Year": return $"extract(year from ({left})::timestamp)"; + case "Hour": return $"extract(hour from ({left})::timestamp)"; + case "Minute": return $"extract(minute from ({left})::timestamp)"; + case "Second": return $"extract(second from ({left})::timestamp)"; + case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)"; + case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)"; + case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)"; + case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)"; + case "Seconds": return $"(floor(({left})/1000000)::int8%60)"; + case "Ticks": return $"(({left})*10)"; + case "TotalDays": return $"(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left})/1000)"; + case "TotalMinutes": return $"(({left})/{(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left})/1000000)"; + } + return null; + } - public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "IsNullOrEmpty": - var arg1 = getExp(exp.Arguments[0]); - return $"({arg1} is null or {arg1} = '')"; - case "Concat": - return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); - } - } else { - var left = getExp(exp.Object); - switch (exp.Method.Name) { - case "StartsWith": - case "EndsWith": - case "Contains": - var args0Value = getExp(exp.Arguments[0]); - if (args0Value == "NULL") return $"({left}) IS NULL"; - var likeOpt = "LIKE"; - if (exp.Arguments.Count > 1) { - if (exp.Arguments[1].Type == typeof(bool) || - exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; - } - if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; - if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; - case "ToLower": return $"lower({left})"; - case "ToUpper": return $"upper({left})"; - case "Substring": - var substrArgs1 = getExp(exp.Arguments[0]); - if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); - else substrArgs1 += "+1"; - if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; - return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; - case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; - case "PadLeft": - if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; - return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "PadRight": - if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; - return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Trim": - case "TrimStart": - case "TrimEnd": - if (exp.Arguments.Count == 0) { - if (exp.Method.Name == "Trim") return $"trim({left})"; - if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; - if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; - } - var trimArg1 = ""; - var trimArg2 = ""; - foreach (var argsTrim02 in exp.Arguments) { - var argsTrim01s = new[] { argsTrim02 }; - if (argsTrim02.NodeType == ExpressionType.NewArrayInit) { - var arritem = argsTrim02 as NewArrayExpression; - argsTrim01s = arritem.Expressions.ToArray(); - } - foreach (var argsTrim01 in argsTrim01s) { - var trimChr = getExp(argsTrim01).Trim('\''); - if (trimChr.Length == 1) trimArg1 += trimChr; - else trimArg2 += $" || ({trimChr})"; - } - } - if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - return left; - case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; - case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; - } - } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.Method.Name) { - case "Abs": return $"abs({getExp(exp.Arguments[0])})"; - case "Sign": return $"sign({getExp(exp.Arguments[0])})"; - case "Floor": return $"floor({getExp(exp.Arguments[0])})"; - case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; - case "Round": - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - return $"round({getExp(exp.Arguments[0])})"; - case "Exp": return $"exp({getExp(exp.Arguments[0])})"; - case "Log": return $"log({getExp(exp.Arguments[0])})"; - case "Log10": return $"log10({getExp(exp.Arguments[0])})"; - case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; - case "Cos": return $"cos({getExp(exp.Arguments[0])})"; - case "Sin": return $"sin({getExp(exp.Arguments[0])})"; - case "Tan": return $"tan({getExp(exp.Arguments[0])})"; - case "Acos": return $"acos({getExp(exp.Arguments[0])})"; - case "Asin": return $"asin({getExp(exp.Arguments[0])})"; - case "Atan": return $"atan({getExp(exp.Arguments[0])})"; - case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; - } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)"; - case "DaysInMonth": return $"extract(day from ({getExp(exp.Arguments[0])} || '-' || {getExp(exp.Arguments[1])} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)"; - case "Equals": return $"(({getExp(exp.Arguments[0])})::timestamp = ({getExp(exp.Arguments[1])})::timestamp)"; + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + var likeOpt = "LIKE"; + if (exp.Arguments.Count > 1) + { + if (exp.Arguments[1].Type == typeof(bool) || + exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + var trimArg1 = ""; + var trimArg2 = ""; + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + var trimChr = getExp(argsTrim01).Trim('\''); + if (trimChr.Length == 1) trimArg1 += trimChr; + else trimArg2 += $" || ({trimChr})"; + } + } + if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; + } + } + throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)"; + case "DaysInMonth": return $"extract(day from ({getExp(exp.Arguments[0])} || '-' || {getExp(exp.Arguments[1])} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)"; + case "Equals": return $"(({getExp(exp.Arguments[0])})::timestamp = ({getExp(exp.Arguments[1])})::timestamp)"; - case "IsLeapYear": - var isLeapYearArgs1 = getExp(exp.Arguments[0]); - return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; - case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"(({left})::timestamp+(({args1})||' microseconds')::interval)"; - case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; - case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; - case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; - case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)"; - case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)"; - case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)"; - case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; - case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; - case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { - case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; - case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; - } - break; - case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::timestamp)"; - case "CompareTo": return $"extract(epoch from ({left})::timestamp-({getExp(exp.Arguments[0])})::timestamp)"; - case "ToString": return $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')"; - } - } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; - case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; - case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; - case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; - case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; - case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; - case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"({left}+{args1})"; - case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; - case "ToString": return $"({left})::varchar"; - } - } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; - case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; - case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; - case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; - case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; - case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; - case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; - case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; - case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; - case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; - case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; - case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; - case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; - case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; - case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; - } - } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); - } - } + case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"(({left})::timestamp+(({args1})||' microseconds')::interval)"; + case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; + case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; + case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; + case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)"; + case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)"; + case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)"; + case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; + case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; + case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; + } + break; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::timestamp)"; + case "CompareTo": return $"extract(epoch from ({left})::timestamp-({getExp(exp.Arguments[0])})::timestamp)"; + case "ToString": return $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')"; + } + } + throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "ToString": return $"({left})::varchar"; + } + } + throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; + case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; + case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; + case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; + case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; + case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; + case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + } + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs index adba0afb..40c5af93 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs @@ -1,11 +1,12 @@ -public static partial class FreeSqlGlobalExtensions { +public static partial class FreeSqlGlobalExtensions +{ - /// - /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 - /// - /// - /// - /// - public static string FormatPostgreSQL(this string that, params object[] args) => _postgresqlAdo.Addslashes(that, args); - static FreeSql.PostgreSQL.PostgreSQLAdo _postgresqlAdo = new FreeSql.PostgreSQL.PostgreSQLAdo(); + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatPostgreSQL(this string that, params object[] args) => _postgresqlAdo.Addslashes(that, args); + static FreeSql.PostgreSQL.PostgreSQLAdo _postgresqlAdo = new FreeSql.PostgreSQL.PostgreSQLAdo(); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index 7f73ee10..b3f949aa 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -12,93 +12,101 @@ using System.Linq.Expressions; using System.Net; using System.Net.NetworkInformation; -namespace FreeSql.PostgreSQL { +namespace FreeSql.PostgreSQL +{ - public class PostgreSQLProvider : IFreeSql { + public class PostgreSQLProvider : IFreeSql + { - static PostgreSQLProvider() { - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BitArray)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPoint)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlLine)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlLSeg)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlBox)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPath)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPolygon)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlCircle)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof((IPAddress Address, int Subnet))] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(IPAddress)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PhysicalAddress)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPoint)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisLineString)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPolygon)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPoint)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiLineString)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPolygon)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometry)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometryCollection)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Dictionary)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JToken)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JObject)] = true; - Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JArray)] = true; + static PostgreSQLProvider() + { + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BitArray)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPoint)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlLine)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlLSeg)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlBox)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPath)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPolygon)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlCircle)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof((IPAddress Address, int Subnet))] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(IPAddress)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PhysicalAddress)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPoint)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisLineString)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPolygon)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPoint)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiLineString)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPolygon)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometry)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometryCollection)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Dictionary)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JToken)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JObject)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JArray)] = true; - var MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) }); - var MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) }); - var MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) }); - Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => { - switch (typeFullName) { - case "Newtonsoft.Json.Linq.JToken": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken))); - case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject))); - case "Newtonsoft.Json.Linq.JArray": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray))); - case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Return(returnTarget, valueExp); - } - return null; - }); - } + var MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) }); + var MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) }); + var MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) }); + Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => + { + switch (typeFullName) + { + case "Newtonsoft.Json.Linq.JToken": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken))); + case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject))); + case "Newtonsoft.Json.Linq.JArray": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray))); + case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Return(returnTarget, valueExp); + } + return null; + }); + } - public ISelect Select() where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new PostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public ISelect Select() where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new PostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } - public PostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString) { - this.InternalCommonUtils = new PostgreSQLUtils(this); - this.InternalCommonExpression = new PostgreSQLExpression(this.InternalCommonUtils); + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public PostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new PostgreSQLUtils(this); + this.InternalCommonExpression = new PostgreSQLExpression(this.InternalCommonUtils); - this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); - this.Aop = new AopProvider(); + this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); - this.DbFirst = new PostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - this.CodeFirst = new PostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - } + this.DbFirst = new PostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new PostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } - public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); - ~PostgreSQLProvider() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - (this.Ado as AdoProvider)?.Dispose(); - } - } + ~PostgreSQLProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 89817e27..3069d618 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -14,157 +14,185 @@ using System.Text; using System.Linq.Expressions; using System.Reflection; -namespace FreeSql.PostgreSQL { +namespace FreeSql.PostgreSQL +{ - class PostgreSQLUtils : CommonUtils { - public PostgreSQLUtils(IFreeSql orm) : base(orm) { - } + class PostgreSQLUtils : CommonUtils + { + public PostgreSQLUtils(IFreeSql orm) : base(orm) + { + } - static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) { - var valueArr = value as Array; - var len = valueArr.GetLength(0); - var ret = Array.CreateInstance(arrayType, len); - for (var a = 0; a < len; a++) { - var item = valueArr.GetValue(a); - ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); - } - return ret; - } - static Dictionary> dicGetParamterValue = new Dictionary> { - { typeof(JToken).FullName, a => string.Concat(a) }, { typeof(JToken[]).FullName, a => getParamterArrayValue(typeof(string), a, null) }, - { typeof(JObject).FullName, a => string.Concat(a) }, { typeof(JObject[]).FullName, a => getParamterArrayValue(typeof(string), a, null) }, - { typeof(JArray).FullName, a => string.Concat(a) }, { typeof(JArray[]).FullName, a => getParamterArrayValue(typeof(string), a, null) }, - { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, - { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, - { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, - { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, - { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, - { typeof(NpgsqlPath).FullName, a => { - var path = (NpgsqlPath)a; - try { int count = path.Count; return path; } catch { return new NpgsqlPath(new NpgsqlPoint(0, 0)); } - } }, { typeof(NpgsqlPath[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPath), a, new NpgsqlPath(new NpgsqlPoint(0, 0))) }, { typeof(NpgsqlPath?[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPath?), a, null) }, - { typeof(NpgsqlPolygon).FullName, a => { - var polygon = (NpgsqlPolygon)a; - try { int count = polygon.Count; return polygon; } catch { return new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0)); } - } }, { typeof(NpgsqlPolygon[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPolygon), a, new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0))) }, { typeof(NpgsqlPolygon?[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPolygon?), a, null) }, - { typeof((IPAddress Address, int Subnet)).FullName, a => { - var inet = ((IPAddress Address, int Subnet))a; - if (inet.Address == null) return (IPAddress.Any, inet.Subnet); - return inet; - } }, { typeof((IPAddress Address, int Subnet)[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)), a, (IPAddress.Any, 0)) }, { typeof((IPAddress Address, int Subnet)?[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)?), a, null) }, - }; - static object getParamterValue(Type type, object value, int level = 0) { - if (type.FullName == "System.Byte[]") return value; - if (type.IsArray && level == 0) { - var elementType = type.GetElementType(); - Type enumType = null; - if (elementType.IsEnum) enumType = elementType; - else if (elementType.IsNullableType() && elementType.GenericTypeArguments.First().IsEnum) enumType = elementType.GenericTypeArguments.First(); - if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)) : - getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)); - return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; - } - if (type.IsNullableType()) type = type.GenericTypeArguments.First(); - if (type.IsEnum) return (int)value; - if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); - return value; - } + static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) + { + var valueArr = value as Array; + var len = valueArr.GetLength(0); + var ret = Array.CreateInstance(arrayType, len); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); + } + return ret; + } + static Dictionary> dicGetParamterValue = new Dictionary> { + { typeof(JToken).FullName, a => string.Concat(a) }, { typeof(JToken[]).FullName, a => getParamterArrayValue(typeof(string), a, null) }, + { typeof(JObject).FullName, a => string.Concat(a) }, { typeof(JObject[]).FullName, a => getParamterArrayValue(typeof(string), a, null) }, + { typeof(JArray).FullName, a => string.Concat(a) }, { typeof(JArray[]).FullName, a => getParamterArrayValue(typeof(string), a, null) }, + { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, + { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, + { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, + { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(NpgsqlPath).FullName, a => { + var path = (NpgsqlPath)a; + try { int count = path.Count; return path; } catch { return new NpgsqlPath(new NpgsqlPoint(0, 0)); } + } }, { typeof(NpgsqlPath[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPath), a, new NpgsqlPath(new NpgsqlPoint(0, 0))) }, { typeof(NpgsqlPath?[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPath?), a, null) }, + { typeof(NpgsqlPolygon).FullName, a => { + var polygon = (NpgsqlPolygon)a; + try { int count = polygon.Count; return polygon; } catch { return new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0)); } + } }, { typeof(NpgsqlPolygon[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPolygon), a, new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0))) }, { typeof(NpgsqlPolygon?[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPolygon?), a, null) }, + { typeof((IPAddress Address, int Subnet)).FullName, a => { + var inet = ((IPAddress Address, int Subnet))a; + if (inet.Address == null) return (IPAddress.Any, inet.Subnet); + return inet; + } }, { typeof((IPAddress Address, int Subnet)[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)), a, (IPAddress.Any, 0)) }, { typeof((IPAddress Address, int Subnet)?[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)?), a, null) }, + }; + static object getParamterValue(Type type, object value, int level = 0) + { + if (type.FullName == "System.Byte[]") return value; + if (type.IsArray && level == 0) + { + var elementType = type.GetElementType(); + Type enumType = null; + if (elementType.IsEnum) enumType = elementType; + else if (elementType.IsNullableType() && elementType.GenericTypeArguments.First().IsEnum) enumType = elementType.GenericTypeArguments.First(); + if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)); + return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; + } + if (type.IsNullableType()) type = type.GenericTypeArguments.First(); + if (type.IsEnum) return (int)value; + if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); + return value; + } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { - if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (value != null) value = getParamterValue(type, value); - var ret = new NpgsqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { - // ret.DataTypeName = ""; - //} else { - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; - //} - _params?.Add(ret); - return ret; - } + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value != null) value = getParamterValue(type, value); + var ret = new NpgsqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; + //} + _params?.Add(ret); + return ret; + } - public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { - if (value != null) value = getParamterValue(type, value); - var ret = new NpgsqlParameter { ParameterName = $"@{name}", Value = value }; - //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { - // ret.DataTypeName = ""; - //} else { - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; - //} - return ret; - }); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => + { + if (value != null) value = getParamterValue(type, value); + var ret = new NpgsqlParameter { ParameterName = $"@{name}", Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; + //} + return ret; + }); - public override string FormatSql(string sql, params object[] args) => sql?.FormatPostgreSQL(args); - public override string QuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; - } - public override string TrimQuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; - } - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; - public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; - public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string FormatSql(string sql, params object[] args) => sql?.FormatPostgreSQL(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; - public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; - static ConcurrentDictionary _dicIsAssignableFromPostgisGeometry = new ConcurrentDictionary(); - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { - if (value == null) return "NULL"; - if (_dicIsAssignableFromPostgisGeometry.GetOrAdd(type, t2 => typeof(PostgisGeometry).IsAssignableFrom(type.IsArray ? type.GetElementType() : type))) { - var pam = AppendParamter(specialParams, null, type, value); - return pam.ParameterName; - } - value = getParamterValue(type, value); - var type2 = value.GetType(); - if (type2 == typeof(byte[])) { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("'\\x"); - foreach (var vc in bytes) { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } - return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) { - var ts = (TimeSpan)value; - return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; - } else if (value is Array) { - var valueArr = value as Array; - var eleType = type2.GetElementType(); - var len = valueArr.GetLength(0); - var sb = new StringBuilder().Append("ARRAY["); - for (var a = 0; a < len; a++) { - var item = valueArr.GetValue(a); - if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); - } - sb.Append("]"); - var dbinfo = _orm.CodeFirst.GetDbInfo(type); - if (dbinfo.HasValue) sb.Append("::").Append(dbinfo.Value.dbtype); - return sb.ToString(); - } else if (type2 == typeof(BitArray)) { - return $"'{(value as BitArray).To1010()}'"; - } else if (type2 == typeof(NpgsqlLine) || type2 == typeof(NpgsqlLine?)) { - var line = value.ToString(); - return line == "{0,0,0}" ? "'{0,-1,-1}'" : $"'{line}'"; - } else if (type2 == typeof((IPAddress Address, int Subnet)) || type2 == typeof((IPAddress Address, int Subnet)?)) { - var cidr = ((IPAddress Address, int Subnet))value; - return $"'{cidr.Address}/{cidr.Subnet}'"; - } else if (dicGetParamterValue.ContainsKey(type2.FullName)) { - value = string.Concat(value); - } - return FormatSql("{0}", value, 1); - } - } + static ConcurrentDictionary _dicIsAssignableFromPostgisGeometry = new ConcurrentDictionary(); + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (_dicIsAssignableFromPostgisGeometry.GetOrAdd(type, t2 => typeof(PostgisGeometry).IsAssignableFrom(type.IsArray ? type.GetElementType() : type))) + { + var pam = AppendParamter(specialParams, null, type, value); + return pam.ParameterName; + } + value = getParamterValue(type, value); + var type2 = value.GetType(); + if (type2 == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("'\\x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); + } + else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; + } + else if (value is Array) + { + var valueArr = value as Array; + var eleType = type2.GetElementType(); + var len = valueArr.GetLength(0); + var sb = new StringBuilder().Append("ARRAY["); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + if (a > 0) sb.Append(","); + sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + } + sb.Append("]"); + var dbinfo = _orm.CodeFirst.GetDbInfo(type); + if (dbinfo.HasValue) sb.Append("::").Append(dbinfo.Value.dbtype); + return sb.ToString(); + } + else if (type2 == typeof(BitArray)) + { + return $"'{(value as BitArray).To1010()}'"; + } + else if (type2 == typeof(NpgsqlLine) || type2 == typeof(NpgsqlLine?)) + { + var line = value.ToString(); + return line == "{0,0,0}" ? "'{0,-1,-1}'" : $"'{line}'"; + } + else if (type2 == typeof((IPAddress Address, int Subnet)) || type2 == typeof((IPAddress Address, int Subnet)?)) + { + var cidr = ((IPAddress Address, int Subnet))value; + return $"'{cidr.Address}/{cidr.Subnet}'"; + } + else if (dicGetParamterValue.ContainsKey(type2.FullName)) + { + value = string.Concat(value); + } + return FormatSql("{0}", value, 1); + } + } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index f604a4f2..b227068f 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -5,84 +5,101 @@ using System.Data; using System.Text; using System.Threading.Tasks; -namespace FreeSql.SqlServer.Curd { +namespace FreeSql.SqlServer.Curd +{ - class SqlServerDelete : Internal.CommonProvider.DeleteProvider where T1 : class { - public SqlServerDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + class SqlServerDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public SqlServerDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async public override Task> ExecuteDeletedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index a0c71ca1..4fe5ba0b 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -7,133 +7,162 @@ using System.Data.Common; using System.Text; using System.Threading.Tasks; -namespace FreeSql.SqlServer.Curd { +namespace FreeSql.SqlServer.Curd +{ - class SqlServerInsert : Internal.CommonProvider.InsertProvider where T1 : class { - public SqlServerInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) - : base(orm, commonUtils, commonExpression) { - } + class SqlServerInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public SqlServerInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(1000, 2100); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); - public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(1000, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); + public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); - protected override long RawExecuteIdentity() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task RawExecuteIdentityAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } + sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } - protected override List RawExecuteInserted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } - var validx = sql.IndexOf(") VALUES"); - if (validx == -1) throw new ArgumentException("找不到 VALUES"); - sb.Insert(0, sql.Substring(0, validx + 1)); - sb.Append(sql.Substring(validx + 1)); + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException("找不到 VALUES"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); - sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task> RawExecuteInsertedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } - var validx = sql.IndexOf(") VALUES"); - if (validx == -1) throw new ArgumentException("找不到 VALUES"); - sb.Insert(0, sql.Substring(0, validx + 1)); - sb.Append(sql.Substring(validx + 1)); + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException("找不到 VALUES"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); - sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 1586f0af..afc7347f 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -6,220 +6,259 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.SqlServer.Curd { +namespace FreeSql.SqlServer.Curd +{ - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) - => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _orm); + internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? + ToSqlStaticRowNumber(_commonUtils, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _orm); - #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) { - if (_orm.CodeFirst.IsAutoSyncStructure) - _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + #region SqlServer 2005 row_number + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); - sb.Append(field); - if (_skip > 0) { - if (string.IsNullOrEmpty(_orderby)) { - var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); - if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); - else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); - } - sb.Append(", ROW_NUMBER() OVER(").Append(_orderby).Append(") AS __rownum__"); - } - sb.Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - } - break; - } else { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + var sb = new StringBuilder(); + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); + sb.Append(field); + if (_skip > 0) + { + if (string.IsNullOrEmpty(_orderby)) + { + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); + } + sb.Append(", ROW_NUMBER() OVER(").Append(_orderby).Append(") AS __rownum__"); + } + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); + else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); - sbnav.Append(_where); - foreach (var tb in _tables) { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } - if (sbnav.Length > 0) { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - if (_skip <= 0) - sb.Append(_orderby); - else - sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); + sbnav.Append(_where); + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip <= 0) + sb.Append(_orderby); + else + sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); - sbnav.Clear(); - return sb.ToString(); - } - #endregion + sbnav.Clear(); + return sb.ToString(); + } + #endregion - #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) { - if (_orm.CodeFirst.IsAutoSyncStructure) - _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + #region SqlServer 2012+ offset feach next + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); - sb.Append(field); - sb.Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - } - break; - } else { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + var sb = new StringBuilder(); + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); + sb.Append(field); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); + else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); - sbnav.Append(_where); - foreach (var tb in _tables) { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } - if (sbnav.Length > 0) { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - if (_skip > 0) { - if (string.IsNullOrEmpty(_orderby)) { - var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); - if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); - else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); - } - sb.Append(_orderby).Append($" \r\nOFFSET {_skip} ROW"); - if (_limit > 0) sb.Append($" \r\nFETCH NEXT {_limit} ROW ONLY"); - } else { - sb.Append(_orderby); - } + sbnav.Append(_where); + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip > 0) + { + if (string.IsNullOrEmpty(_orderby)) + { + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); + } + sb.Append(_orderby).Append($" \r\nOFFSET {_skip} ROW"); + if (_limit > 0) sb.Append($" \r\nFETCH NEXT {_limit} ROW ONLY"); + } + else + { + sb.Append(_orderby); + } - sbnav.Clear(); - return sb.ToString(); - } - #endregion + sbnav.Clear(); + return sb.ToString(); + } + #endregion - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index 871ea913..a079557a 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -7,121 +7,144 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.SqlServer.Curd { +namespace FreeSql.SqlServer.Curd +{ - class SqlServerUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { + class SqlServerUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { - public SqlServerUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + public SqlServerUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 2100); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 2100); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 2100); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); - protected override List RawExecuteUpdated() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task> RawExecuteUpdatedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } - protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { - if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); - return; - } - caseWhen.Append("("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); - ++pkidx; - } - caseWhen.Append(")"); - } + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(", "); + caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); + ++pkidx; + } + caseWhen.Append(")"); + } - protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { - if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); - return; - } - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); - sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append(" as varchar)"); - ++pkidx; - } - } - } + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(", "); + sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append(" as varchar)"); + ++pkidx; + } + } + } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 9168c070..1849c39e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -7,59 +7,72 @@ using System.Data.SqlClient; using System.Text; using System.Threading; -namespace FreeSql.SqlServer { - class SqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public SqlServerAdo() : base(DataType.SqlServer) { } - public SqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.SqlServer) { - base._util = util; - if (!string.IsNullOrEmpty(masterConnectionString)) - MasterPool = new SqlServerConnectionPool("主库", masterConnectionString, null, null); - if (slaveConnectionStrings != null) { - foreach (var slaveConnectionString in slaveConnectionStrings) { - var slavePool = new SqlServerConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); - SlavePools.Add(slavePool); - } - } - } - static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) { - if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) - param = Utils.GetDataReaderValue(mapType, param); - if (param is bool || param is bool?) - return (bool)param ? 1 : 0; - else if (param is string || param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - else if (param is Enum) - return ((Enum)param).ToInt64(); - else if (decimal.TryParse(string.Concat(param), out var trydec)) - return param; - else if (param is DateTime || param is DateTime?) { - if (param.Equals(DateTime.MinValue) == true) param = new DateTime(1970, 1, 1); - return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); - } else if (param is DateTimeOffset || param is DateTimeOffset?) { - if (param.Equals(DateTimeOffset.MinValue) == true) param = new DateTimeOffset(new DateTime(1970, 1, 1), TimeSpan.Zero); - return string.Concat("'", ((DateTimeOffset)param).ToString("yyyy-MM-dd HH:mm:ss.fff zzzz"), "'"); - } else if (param is TimeSpan || param is TimeSpan?) - return ((TimeSpan)param).TotalSeconds; - else if (param is IEnumerable) { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - //if (param is string) return string.Concat('N', nparms[a]); - } +namespace FreeSql.SqlServer +{ + class SqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public SqlServerAdo() : base(DataType.SqlServer) { } + public SqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.SqlServer) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new SqlServerConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new SqlServerConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + { + if (param.Equals(DateTime.MinValue) == true) param = new DateTime(1970, 1, 1); + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); + } + else if (param is DateTimeOffset || param is DateTimeOffset?) + { + if (param.Equals(DateTimeOffset.MinValue) == true) param = new DateTimeOffset(new DateTime(1970, 1, 1), TimeSpan.Zero); + return string.Concat("'", ((DateTimeOffset)param).ToString("yyyy-MM-dd HH:mm:ss.fff zzzz"), "'"); + } + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).TotalSeconds; + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + //if (param is string) return string.Concat('N', nparms[a]); + } - protected override DbCommand CreateCommand() { - return new SqlCommand(); - } + protected override DbCommand CreateCommand() + { + return new SqlCommand(); + } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { - (pool as SqlServerConnectionPool).Return(conn, ex); - } + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as SqlServerConnectionPool).Return(conn, ex); + } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); - } + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index f3f6b6d1..605f0eb9 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -8,174 +8,215 @@ using System.Data.SqlClient; using System.Text.RegularExpressions; using System.Threading.Tasks; -namespace FreeSql.SqlServer { +namespace FreeSql.SqlServer +{ - class SqlServerConnectionPool : ObjectPool { + class SqlServerConnectionPool : ObjectPool + { - internal Action availableHandler; - internal Action unavailableHandler; + internal Action availableHandler; + internal Action unavailableHandler; - public SqlServerConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - var policy = new SqlServerConnectionPoolPolicy { - _pool = this, - Name = name - }; - this.Policy = policy; - policy.ConnectionString = connectionString; + public SqlServerConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new SqlServerConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; - } + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } - public void Return(Object obj, Exception exception, bool isRecreate = false) { - if (exception != null && exception is SqlException) { + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is SqlException) + { - if (obj.Value.Ping() == false) { + if (obj.Value.Ping() == false) + { - base.SetUnavailable(exception); - } - } - base.Return(obj, isRecreate); - } - } + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } - class SqlServerConnectionPoolPolicy : IPolicy { + class SqlServerConnectionPoolPolicy : IPolicy + { - internal SqlServerConnectionPool _pool; - public string Name { get; set; } = "SqlServer SqlConnection 对象池"; - public int PoolSize { get; set; } = 100; - public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; - public int AsyncGetCapacity { get; set; } = 10000; - public bool IsThrowGetTimeoutException { get; set; } = true; - public int CheckAvailableInterval { get; set; } = 5; + internal SqlServerConnectionPool _pool; + public string Name { get; set; } = "SqlServer SqlConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; - static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - private string _connectionString; - public string ConnectionString { - get => _connectionString; - set { - _connectionString = value ?? ""; + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; - var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; - Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); - PoolSize = poolsize + connStrIncr; - _connectionString = m.Success ? - Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : - $"{_connectionString};Max pool size={PoolSize}"; + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; - pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - var minPoolSize = 0; - pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - minPoolSize = int.Parse(m.Groups[1].Value); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); - } - } + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } - public bool OnCheckAvailable(Object obj) { - if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); - return obj.Value.Ping(true); - } + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } - public DbConnection OnCreate() { - var conn = new SqlConnection(_connectionString); - return conn; - } + public DbConnection OnCreate() + { + var conn = new SqlConnection(_connectionString); + return conn; + } - public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); - obj.Dispose(); - } + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } - public void OnGet(Object obj) { + public void OnGet(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { - try { - obj.Value.Open(); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - async public Task OnGetAsync(Object obj) { + async public Task OnGetAsync(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { - try { - await obj.Value.OpenAsync(); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - public void OnGetTimeout() { + public void OnGetTimeout() + { - } + } - public void OnReturn(Object obj) { - if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } - } + public void OnReturn(Object obj) + { + if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } - public void OnAvailable() { - _pool.availableHandler?.Invoke(); - } + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } - public void OnUnavailable() { - _pool.unavailableHandler?.Invoke(); - } - } + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } - static class DbConnectionExtensions { + static class DbConnectionExtensions + { - static DbCommand PingCommand(DbConnection conn) { - var cmd = conn.CreateCommand(); - cmd.CommandTimeout = 5; - cmd.CommandText = "select 1"; - return cmd; - } - public static bool Ping(this DbConnection that, bool isThrow = false) { - try { - PingCommand(that).ExecuteNonQuery(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - async public static Task PingAsync(this DbConnection that, bool isThrow = false) { - try { - await PingCommand(that).ExecuteNonQueryAsync(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - } + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 6df8fd72..ea78f7f4 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -10,63 +10,71 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; -namespace FreeSql.SqlServer { +namespace FreeSql.SqlServer +{ - class SqlServerCodeFirst : Internal.CommonProvider.CodeFirstProvider { - - public SqlServerCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + class SqlServerCodeFirst : Internal.CommonProvider.CodeFirstProvider + { - static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (SqlDbType.Bit, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, (SqlDbType.Bit, "bit","bit", null, true, null) }, + public SqlServerCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } - { typeof(sbyte).FullName, (SqlDbType.SmallInt, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true, null) }, - { typeof(short).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true, null) }, - { typeof(int).FullName, (SqlDbType.Int, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, (SqlDbType.Int, "int", "int", false, true, null) }, - { typeof(long).FullName, (SqlDbType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, (SqlDbType.BigInt, "bigint","bigint", false, true, null) }, + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (SqlDbType.Bit, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, (SqlDbType.Bit, "bit","bit", null, true, null) }, - { typeof(byte).FullName, (SqlDbType.TinyInt, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (SqlDbType.TinyInt, "tinyint","tinyint", true, true, null) }, - { typeof(ushort).FullName, (SqlDbType.Int, "int","int NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (SqlDbType.Int, "int", "int", true, true, null) }, - { typeof(uint).FullName, (SqlDbType.BigInt, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (SqlDbType.BigInt, "bigint", "bigint", true, true, null) }, - { typeof(ulong).FullName, (SqlDbType.Decimal, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (SqlDbType.Decimal, "decimal", "decimal(20,0)", true, true, null) }, + { typeof(sbyte).FullName, (SqlDbType.SmallInt, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, (SqlDbType.Int, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, (SqlDbType.Int, "int", "int", false, true, null) }, + { typeof(long).FullName, (SqlDbType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, (SqlDbType.BigInt, "bigint","bigint", false, true, null) }, - { typeof(double).FullName, (SqlDbType.Float, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, (SqlDbType.Float, "float", "float", false, true, null) }, - { typeof(float).FullName, (SqlDbType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, (SqlDbType.Real, "real","real", false, true, null) }, - { typeof(decimal).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(byte).FullName, (SqlDbType.TinyInt, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (SqlDbType.TinyInt, "tinyint","tinyint", true, true, null) }, + { typeof(ushort).FullName, (SqlDbType.Int, "int","int NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (SqlDbType.Int, "int", "int", true, true, null) }, + { typeof(uint).FullName, (SqlDbType.BigInt, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (SqlDbType.BigInt, "bigint", "bigint", true, true, null) }, + { typeof(ulong).FullName, (SqlDbType.Decimal, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (SqlDbType.Decimal, "decimal", "decimal(20,0)", true, true, null) }, - { typeof(TimeSpan).FullName, (SqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (SqlDbType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (SqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (SqlDbType.DateTime, "datetime", "datetime", false, true, null) }, - { typeof(DateTimeOffset).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true, null) }, + { typeof(double).FullName, (SqlDbType.Float, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, (SqlDbType.Float, "float", "float", false, true, null) }, + { typeof(float).FullName, (SqlDbType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, (SqlDbType.Real, "real","real", false, true, null) }, + { typeof(decimal).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(byte[]).FullName, (SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, - { typeof(string).FullName, (SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(TimeSpan).FullName, (SqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (SqlDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, (SqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (SqlDbType.DateTime, "datetime", "datetime", false, true, null) }, + { typeof(DateTimeOffset).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true, null) }, - { typeof(Guid).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, - }; + { typeof(byte[]).FullName, (SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, (SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); - if (type.IsArray) return null; - var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); - if (enumType != null) { - var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (SqlDbType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); - if (_dicCsToDb.ContainsKey(type.FullName) == false) { - lock (_dicCsToDbLock) { - if (_dicCsToDb.ContainsKey(type.FullName) == false) - _dicCsToDb.Add(type.FullName, newItem); - } - } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); - } - return null; - } + { typeof(Guid).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, + }; - void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) { - if (string.IsNullOrEmpty(comment)) { - sb.AppendFormat(@" + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (SqlDbType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) + { + if (string.IsNullOrEmpty(comment)) + { + sb.AppendFormat(@" IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', 'SCHEMA', N'{0}', 'TABLE', N'{1}', @@ -76,9 +84,9 @@ IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', , @level1type = 'TABLE', @level1name = N'{1}' , @level2type = 'COLUMN', @level2name = N'{2}' ", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''")); - return; - } - sb.AppendFormat(@" + return; + } + sb.AppendFormat(@" IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', 'SCHEMA', N'{0}', 'TABLE', N'{1}', @@ -93,96 +101,115 @@ ELSE , @level1type = 'TABLE', @level1name = N'{1}' , @level2type = 'COLUMN', @level2name = N'{2}' ", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); - } - public override string GetComparisonDDLStatements(params Type[] entityTypes) { - var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); - var database = conn.Value.Database; - Func ExecuteScalar = (db, sql) => { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); - try { - using (var cmd = conn.Value.CreateCommand()) { - cmd.CommandText = sql; - cmd.CommandType = CommandType.Text; - return cmd.ExecuteScalar(); - } - } finally { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); - } - }; - var sb = new StringBuilder(); - try { - foreach (var entityType in entityTypes) { - if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 3); - if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] }; - if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] }; + } + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + var database = conn.Value.Database; + Func ExecuteScalar = (db, sql) => + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + }; + var sb = new StringBuilder(); + try + { + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 3); + if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] }; - if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] }; + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] }; + if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] }; - if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 - ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); - if (string.Compare(tbname[1], "dbo", true) != 0 && ExecuteScalar(tbname[0], $" select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 - ExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); + if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 + ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); + if (string.Compare(tbname[1], "dbo", true) != 0 && ExecuteScalar(tbname[0], $" select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 + ExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); - var sbalter = new StringBuilder(); - var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (ExecuteScalar(tbname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tbname[1]}].[{tbname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) { //表不存在 - if (tboldname != null) { - if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tboldname[0]}'") == null || - string.Compare(tboldname[1], tbname[1], true) != 0 && ExecuteScalar(tboldname[0], $" select 1 from sys.schemas where name='{tboldname[1]}'") == null || - ExecuteScalar(tboldname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tboldname[1]}].[{tboldname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) - //数据库或模式或表不存在 - tboldname = null; - } - if (tboldname == null) { - //创建新表 - sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(" ( "); - var pkidx = 0; - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); - if (tbcol.Attribute.IsPrimary == true) { - if (tb.Primarys.Length > 1) { - if (pkidx == tb.Primarys.Length - 1) - sb.Append(" primary key (").Append(string.Join(", ", tb.Primarys.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(")"); - } else - sb.Append(" primary key"); - pkidx++; - } - sb.Append(","); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); - //备注 - foreach (var tbcol in tb.Columns.Values) { - if (string.IsNullOrEmpty(tbcol.Comment) == false) - AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); - } - continue; - } - //如果新表,旧表在一个数据库和模式下,直接修改表名 - if (string.Compare(tbname[0], tboldname[0], true) == 0 && - string.Compare(tbname[1], tboldname[1], true) == 0) - sbalter.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(_commonUtils.FormatSql(";\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"), tbname[2])); - else { - //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 - istmpatler = true; - } - } else - tboldname = null; //如果新表已经存在,不走改表名逻辑 + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (ExecuteScalar(tbname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tbname[1]}].[{tbname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + { //表不存在 + if (tboldname != null) + { + if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tboldname[0]}'") == null || + string.Compare(tboldname[1], tbname[1], true) != 0 && ExecuteScalar(tboldname[0], $" select 1 from sys.schemas where name='{tboldname[1]}'") == null || + ExecuteScalar(tboldname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tboldname[1]}].[{tboldname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + //数据库或模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建新表 + sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(" ( "); + var pkidx = 0; + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary == true) + { + if (tb.Primarys.Length > 1) + { + if (pkidx == tb.Primarys.Length - 1) + sb.Append(" primary key (").Append(string.Join(", ", tb.Primarys.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(")"); + } + else + sb.Append(" primary key"); + pkidx++; + } + sb.Append(","); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + } + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0 && + string.Compare(tbname[1], tboldname[1], true) == 0) + sbalter.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(_commonUtils.FormatSql(";\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"), tbname[2])); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 - //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = string.Format(@" + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = string.Format(@" use [{0}]; select a.name 'Column' @@ -203,45 +230,51 @@ left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id where a.object_id in (object_id(N'[{1}].[{2}]')); use " + database, tboldname ?? tbname); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new { - column = string.Concat(a[0]), - sqlType = string.Concat(a[1]), - is_nullable = string.Concat(a[2]) == "1", - is_identity = string.Concat(a[3]) == "1", - comment = string.Concat(a[4]) - }, StringComparer.CurrentCultureIgnoreCase); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new + { + column = string.Concat(a[0]), + sqlType = string.Concat(a[1]), + is_nullable = string.Concat(a[2]) == "1", + is_identity = string.Concat(a[3]) == "1", + comment = string.Concat(a[4]) + }, StringComparer.CurrentCultureIgnoreCase); - if (istmpatler == false) { - foreach (var tbcol in tb.Columns.Values) { - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || - tbcol.Attribute.IsNullable != tbstructcol.is_nullable || - tbcol.Attribute.IsIdentity != tbstructcol.is_identity) { - istmpatler = true; - break; - } - if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) - //修改列名 - sbalter.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN';\r\n", $"{tbname[0]}.{tbname[1]}.{tbname[2]}.{tbstructcol.column}", tbcol.Attribute.Name)); - if (isCommentChanged) - //修改备备注 - AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); - continue; - } - //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); - if (tbcol.Attribute.IsNullable == false) { - var addcoldbdefault = tbcol.Attribute.DbDefautValue; - if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); - } - sbalter.Append(";\r\n"); - if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); - } - var dsuksql = string.Format(@" + if (istmpatler == false) + { + foreach (var tbcol in tb.Columns.Values) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.IsNullable != tbstructcol.is_nullable || + tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + { + istmpatler = true; + break; + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN';\r\n", $"{tbname[0]}.{tbname[1]}.{tbname[2]}.{tbstructcol.column}", tbcol.Attribute.Name)); + if (isCommentChanged) + //修改备备注 + AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); + if (tbcol.Attribute.IsNullable == false) + { + var addcoldbdefault = tbcol.Attribute.DbDefautValue; + if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); + } + sbalter.Append(";\r\n"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + } + var dsuksql = string.Format(@" use [{0}]; select c.name @@ -252,111 +285,130 @@ left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_ left join sys.key_constraints d on d.parent_object_id = b.object_id and d.unique_index_id = b.index_id where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_unique = 1; use " + database, tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); - } - } - } - if (istmpatler == false) { - sb.Append(sbalter).Append("\r\nuse " + database); - continue; - } - //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - bool idents = false; - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.FreeSqlTmp_{tbname[2]}"); - sb.Append("BEGIN TRANSACTION\r\n") - .Append("SET QUOTED_IDENTIFIER ON\r\n") - .Append("SET ARITHABORT ON\r\n") - .Append("SET NUMERIC_ROUNDABORT OFF\r\n") - .Append("SET CONCAT_NULL_YIELDS_NULL ON\r\n") - .Append("SET ANSI_NULLS ON\r\n") - .Append("SET ANSI_PADDING ON\r\n") - .Append("SET ANSI_WARNINGS ON\r\n") - .Append("COMMIT\r\n"); - sb.Append("BEGIN TRANSACTION;\r\n"); - //创建临时表 - sb.Append("CREATE TABLE ").Append(tmptablename).Append(" ( "); - var pkidx2 = 0; - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); - if (tbcol.Attribute.IsPrimary == true) { - if (tb.Primarys.Length > 1) { - if (pkidx2 == tb.Primarys.Length - 1) - sb.Append(" primary key (").Append(string.Join(", ", tb.Primarys.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(")"); - } else - sb.Append(" primary key"); - pkidx2++; - } - sb.Append(","); - idents = idents || tbcol.Attribute.IsIdentity == true; - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); - //备注 - foreach (var tbcol in tb.Columns.Values) { - if (string.IsNullOrEmpty(tbcol.Comment) == false) - AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); - } - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); - if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); - sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); - sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) - sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append(")\r\n\t\tSELECT "); - foreach (var tbcol in tb.Columns.Values) { - var insertvalue = "NULL"; - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) - insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol))})"; - } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol)); - sb.Append(insertvalue.Replace("'", "''")).Append(", "); - } - sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n"); - if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" OFF;\r\n"); - sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("EXECUTE sp_rename N'").Append(tmptablename).Append("', N'").Append(tbname[2]).Append("', 'OBJECT';\r\n"); - sb.Append("COMMIT;\r\n"); - } - return sb.Length == 0 ? null : sb.ToString(); - } finally { - try { - conn.Value.ChangeDatabase(database); - _orm.Ado.MasterPool.Return(conn); - } catch { - _orm.Ado.MasterPool.Return(conn, true); - } - } - } - object GetTransferDbDefaultValue(ColumnInfo col) { - var ddv = col.Attribute.DbDefautValue; - if (ddv == null) return ddv; - if (ddv is DateTime || ddv is DateTime?) { - var dt = (DateTime)ddv; - if (col.Attribute.DbType.Contains("SMALLDATETIME") && dt < new DateTime(1900, 1, 1)) ddv = new DateTime(1900, 1, 1); - else if (col.Attribute.DbType.Contains("DATETIME") && dt < new DateTime(1753, 1, 1)) ddv = new DateTime(1753, 1, 1); - else if (col.Attribute.DbType.Contains("DATE") && dt < new DateTime(0001, 1, 1)) ddv = new DateTime(0001, 1, 1); - } - return ddv; - } - } + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); + foreach (var uk in tb.Uniques) + { + if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter).Append("\r\nuse " + database); + continue; + } + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + bool idents = false; + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.FreeSqlTmp_{tbname[2]}"); + sb.Append("BEGIN TRANSACTION\r\n") + .Append("SET QUOTED_IDENTIFIER ON\r\n") + .Append("SET ARITHABORT ON\r\n") + .Append("SET NUMERIC_ROUNDABORT OFF\r\n") + .Append("SET CONCAT_NULL_YIELDS_NULL ON\r\n") + .Append("SET ANSI_NULLS ON\r\n") + .Append("SET ANSI_PADDING ON\r\n") + .Append("SET ANSI_WARNINGS ON\r\n") + .Append("COMMIT\r\n"); + sb.Append("BEGIN TRANSACTION;\r\n"); + //创建临时表 + sb.Append("CREATE TABLE ").Append(tmptablename).Append(" ( "); + var pkidx2 = 0; + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary == true) + { + if (tb.Primarys.Length > 1) + { + if (pkidx2 == tb.Primarys.Length - 1) + sb.Append(" primary key (").Append(string.Join(", ", tb.Primarys.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(")"); + } + else + sb.Append(" primary key"); + pkidx2++; + } + sb.Append(","); + idents = idents || tbcol.Attribute.IsIdentity == true; + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //备注 + foreach (var tbcol in tb.Columns.Values) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); + } + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); + if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); + sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); + sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\n\t\tSELECT "); + foreach (var tbcol in tb.Columns.Values) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol))})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol)); + sb.Append(insertvalue.Replace("'", "''")).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n"); + if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" OFF;\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("EXECUTE sp_rename N'").Append(tmptablename).Append("', N'").Append(tbname[2]).Append("', 'OBJECT';\r\n"); + sb.Append("COMMIT;\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } + finally + { + try + { + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } + catch + { + _orm.Ado.MasterPool.Return(conn, true); + } + } + } + object GetTransferDbDefaultValue(ColumnInfo col) + { + var ddv = col.Attribute.DbDefautValue; + if (ddv == null) return ddv; + if (ddv is DateTime || ddv is DateTime?) + { + var dt = (DateTime)ddv; + if (col.Attribute.DbType.Contains("SMALLDATETIME") && dt < new DateTime(1900, 1, 1)) ddv = new DateTime(1900, 1, 1); + else if (col.Attribute.DbType.Contains("DATETIME") && dt < new DateTime(1753, 1, 1)) ddv = new DateTime(1753, 1, 1); + else if (col.Attribute.DbType.Contains("DATE") && dt < new DateTime(0001, 1, 1)) ddv = new DateTime(0001, 1, 1); + } + return ddv; + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 56405a7e..35b91bee 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -6,118 +6,127 @@ using System.Data; using System.Linq; using System.Text.RegularExpressions; -namespace FreeSql.SqlServer { - class SqlServerDbFirst : IDbFirst { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public SqlServerDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } +namespace FreeSql.SqlServer +{ + class SqlServerDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public SqlServerDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } - public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); - SqlDbType GetSqlDbType(DbColumnInfo column) { - switch (column.DbTypeText.ToLower()) { - case "bit": return SqlDbType.Bit; - case "tinyint": return SqlDbType.TinyInt; - case "smallint": return SqlDbType.SmallInt; - case "int": return SqlDbType.Int; - case "bigint": return SqlDbType.BigInt; - case "numeric": - case "decimal": return SqlDbType.Decimal; - case "smallmoney": return SqlDbType.SmallMoney; - case "money": return SqlDbType.Money; - case "float": return SqlDbType.Float; - case "real": return SqlDbType.Real; - case "date": return SqlDbType.Date; - case "datetime": - case "datetime2": return SqlDbType.DateTime; - case "datetimeoffset": return SqlDbType.DateTimeOffset; - case "smalldatetime": return SqlDbType.SmallDateTime; - case "time": return SqlDbType.Time; - case "char": return SqlDbType.Char; - case "varchar": return SqlDbType.VarChar; - case "text": return SqlDbType.Text; - case "nchar": return SqlDbType.NChar; - case "nvarchar": return SqlDbType.NVarChar; - case "ntext": return SqlDbType.NText; - case "binary": return SqlDbType.Binary; - case "varbinary": return SqlDbType.VarBinary; - case "image": return SqlDbType.Image; - case "timestamp": return SqlDbType.Timestamp; - case "uniqueidentifier": return SqlDbType.UniqueIdentifier; - default: return SqlDbType.Variant; - } - } + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + SqlDbType GetSqlDbType(DbColumnInfo column) + { + switch (column.DbTypeText.ToLower()) + { + case "bit": return SqlDbType.Bit; + case "tinyint": return SqlDbType.TinyInt; + case "smallint": return SqlDbType.SmallInt; + case "int": return SqlDbType.Int; + case "bigint": return SqlDbType.BigInt; + case "numeric": + case "decimal": return SqlDbType.Decimal; + case "smallmoney": return SqlDbType.SmallMoney; + case "money": return SqlDbType.Money; + case "float": return SqlDbType.Float; + case "real": return SqlDbType.Real; + case "date": return SqlDbType.Date; + case "datetime": + case "datetime2": return SqlDbType.DateTime; + case "datetimeoffset": return SqlDbType.DateTimeOffset; + case "smalldatetime": return SqlDbType.SmallDateTime; + case "time": return SqlDbType.Time; + case "char": return SqlDbType.Char; + case "varchar": return SqlDbType.VarChar; + case "text": return SqlDbType.Text; + case "nchar": return SqlDbType.NChar; + case "nvarchar": return SqlDbType.NVarChar; + case "ntext": return SqlDbType.NText; + case "binary": return SqlDbType.Binary; + case "varbinary": return SqlDbType.VarBinary; + case "image": return SqlDbType.Image; + case "timestamp": return SqlDbType.Timestamp; + case "uniqueidentifier": return SqlDbType.UniqueIdentifier; + default: return SqlDbType.Variant; + } + } - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)SqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)SqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)SqlDbType.TinyInt, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { (int)SqlDbType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)SqlDbType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)SqlDbType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)SqlDbType.TinyInt, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)SqlDbType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)SqlDbType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)SqlDbType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)SqlDbType.SmallMoney, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)SqlDbType.Money, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)SqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)SqlDbType.Float, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)SqlDbType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)SqlDbType.SmallMoney, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)SqlDbType.Money, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)SqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)SqlDbType.Float, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)SqlDbType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)SqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)SqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)SqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)SqlDbType.DateTime2, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)SqlDbType.SmallDateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)SqlDbType.DateTimeOffset, ("(DateTimeOffset?)", "new DateTimeOffset(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTimeOffset), typeof(DateTimeOffset?), "{0}.Value", "GetDateTimeOffset") }, + { (int)SqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)SqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)SqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)SqlDbType.DateTime2, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)SqlDbType.SmallDateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)SqlDbType.DateTimeOffset, ("(DateTimeOffset?)", "new DateTimeOffset(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTimeOffset), typeof(DateTimeOffset?), "{0}.Value", "GetDateTimeOffset") }, - { (int)SqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)SqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)SqlDbType.Image, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)SqlDbType.Timestamp, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)SqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)SqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)SqlDbType.Image, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)SqlDbType.Timestamp, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)SqlDbType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.NChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.NVarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.NText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.NChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.NVarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.NText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, - }; + { (int)SqlDbType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; - public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; - public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; - public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; - public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; - public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; - public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; - public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; - public List GetDatabases() { - var sql = @" select name from sys.databases where name not in ('master','tempdb','model','msdb')"; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); - } + public List GetDatabases() + { + var sql = @" select name from sys.databases where name not in ('master','tempdb','model','msdb')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } - public List GetTablesByDatabase(params string[] database) { - var olddatabase = ""; - using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { - olddatabase = conn.Value.Database; - } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; - var tables = new List(); + public List GetTablesByDatabase(params string[] database) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + var tables = new List(); - foreach (var db in dbs) { - if (string.IsNullOrEmpty(db)) continue; + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db)) continue; - var loc1 = new List(); - var loc2 = new Dictionary(); - var loc3 = new Dictionary>(); + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); - var sql = $@" + var sql = $@" use [{db}]; select a.Object_id @@ -154,34 +163,36 @@ order by type desc, b.name, a.name ; use [{olddatabase}]; "; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); - foreach (object[] row in ds) { - int object_id = int.Parse(string.Concat(row[0])); - var owner = string.Concat(row[1]); - var table = string.Concat(row[2]); - var comment = string.Concat(row[3]); - Enum.TryParse(string.Concat(row[4]), out var type); - loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); - loc3.Add(object_id, new Dictionary()); - switch (type) { - case DbTableType.VIEW: - case DbTableType.TABLE: - loc6.Add(object_id); - break; - case DbTableType.StoreProcedure: - loc66.Add(object_id); - break; - } - } - if (loc6.Count == 0) return loc1; - var loc8 = string.Join(",", loc6.Select(a => string.Concat(a))); - var loc88 = string.Join(",", loc66.Select(a => string.Concat(a))); + var loc6 = new List(); + var loc66 = new List(); + foreach (object[] row in ds) + { + int object_id = int.Parse(string.Concat(row[0])); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6.Add(object_id); + break; + case DbTableType.StoreProcedure: + loc66.Add(object_id); + break; + } + } + if (loc6.Count == 0) return loc1; + var loc8 = string.Join(",", loc6.Select(a => string.Concat(a))); + var loc88 = string.Join(",", loc66.Select(a => string.Concat(a))); - var tsql_place = @" + var tsql_place = @" select isnull(e.name,'') + '.' + isnull(d.name,'') @@ -207,51 +218,54 @@ left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id where a.object_id in ({1}) "; - sql = string.Format(tsql_place, @" + sql = string.Format(tsql_place, @" ,a.is_nullable 'IsNullable' ,a.is_identity 'IsIdentity' from sys.columns", loc8); - if (loc88.Length > 0) { - sql += "union all" + - string.Format(tsql_place.Replace( - "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id", - "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @" + if (loc88.Length > 0) + { + sql += "union all" + + string.Format(tsql_place.Replace( + "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id", + "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' from sys.parameters", loc88); - } - sql = $"use [{db}];{sql};use [{olddatabase}]; "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + } + sql = $"use [{db}];{sql};use [{olddatabase}]; "; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - foreach (object[] row in ds) { - var table_id = string.Concat(row[0]); - var object_id = int.Parse(string.Concat(row[1])); - var column = string.Concat(row[2]); - var type = string.Concat(row[3]); - var max_length = int.Parse(string.Concat(row[4])); - var sqlType = string.Concat(row[5]); - var comment = string.Concat(row[6]); - var is_nullable = bool.Parse(string.Concat(row[7])); - var is_identity = bool.Parse(string.Concat(row[8])); - if (max_length == 0) max_length = -1; + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var object_id = int.Parse(string.Concat(row[1])); + var column = string.Concat(row[2]); + var type = string.Concat(row[3]); + var max_length = int.Parse(string.Concat(row[4])); + var sqlType = string.Concat(row[5]); + var comment = string.Concat(row[6]); + var is_nullable = bool.Parse(string.Concat(row[7])); + var is_identity = bool.Parse(string.Concat(row[8])); + if (max_length == 0) max_length = -1; - loc3[object_id].Add(column, new DbColumnInfo { - Name = column, - MaxLength = max_length, - IsIdentity = is_identity, - IsNullable = is_nullable, - IsPrimary = false, - DbTypeText = type, - DbTypeTextFull = sqlType, - Table = loc2[object_id], - Coment = comment - }); - loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); - loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); - } + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Coment = comment + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } - sql = $@" + sql = $@" use [{db}]; select a.object_id 'Object_id' @@ -269,51 +283,56 @@ where a.object_id in ({loc8}) ; use [{olddatabase}]; "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); - foreach (object[] row in ds) { - int object_id = int.Parse(string.Concat(row[0])); - string column = string.Concat(row[1]); - string index_id = string.Concat(row[2]); - bool is_unique = bool.Parse(string.Concat(row[3])); - bool is_primary_key = bool.Parse(string.Concat(row[4])); - bool is_clustered = bool.Parse(string.Concat(row[5])); - int is_desc = int.Parse(string.Concat(row[6])); + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); + foreach (object[] row in ds) + { + int object_id = int.Parse(string.Concat(row[0])); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = bool.Parse(string.Concat(row[3])); + bool is_primary_key = bool.Parse(string.Concat(row[4])); + bool is_clustered = bool.Parse(string.Concat(row[5])); + int is_desc = int.Parse(string.Concat(row[6])); - if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; - DbColumnInfo loc9 = loc3[object_id][column]; - if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + DbColumnInfo loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; - if (!indexColumns.TryGetValue(object_id, out loc10)) - indexColumns.Add(object_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - if (is_unique && !is_primary_key) { - if (!uniqueColumns.TryGetValue(object_id, out loc10)) - uniqueColumns.Add(object_id, loc10 = new Dictionary>()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); - } - } - foreach (var object_id in indexColumns.Keys) { - foreach (var column in indexColumns[object_id]) - loc2[object_id].IndexesDict.Add(column.Key, column.Value); - } - foreach (var object_id in uniqueColumns.Keys) { - foreach (var column in uniqueColumns[object_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[object_id].UniquesDict.Add(column.Key, column.Value); - } - } + Dictionary> loc10 = null; + List loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } - sql = $@" + sql = $@" use [{db}]; select b.object_id 'Object_id' @@ -333,86 +352,99 @@ where b.object_id in ({loc8}) ; use [{olddatabase}]; "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (object[] row in ds) { - int object_id, referenced_object_id; - int.TryParse(string.Concat(row[0]), out object_id); - var column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - int.TryParse(string.Concat(row[3]), out referenced_object_id); - var is_foreign_key = bool.Parse(string.Concat(row[4])); - var referenced_column = string.Concat(row[5]); - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); - DbColumnInfo loc9 = loc3[object_id][column]; - DbTableInfo loc10 = null; - DbColumnInfo loc11 = null; - bool isThisSln = referenced_object_id != 0; + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + int object_id, referenced_object_id; + int.TryParse(string.Concat(row[0]), out object_id); + var column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + int.TryParse(string.Concat(row[3]), out referenced_object_id); + var is_foreign_key = bool.Parse(string.Concat(row[4])); + var referenced_column = string.Concat(row[5]); + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + DbColumnInfo loc9 = loc3[object_id][column]; + DbTableInfo loc10 = null; + DbColumnInfo loc11 = null; + bool isThisSln = referenced_object_id != 0; - if (isThisSln) { - loc10 = loc2[referenced_object_id]; - loc11 = loc3[referenced_object_id][referenced_column]; - } else { + if (isThisSln) + { + loc10 = loc2[referenced_object_id]; + loc11 = loc3[referenced_object_id][referenced_column]; + } + else + { - } - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(object_id, out loc12)) - fkColumns.Add(object_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); - } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + } + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(object_id, out loc12)) + fkColumns.Add(object_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); - foreach (var table_id in loc3.Keys) { - foreach (var loc5 in loc3[table_id].Values) { - loc2[table_id].Columns.Add(loc5); - if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); - if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); - } - } - foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) { - foreach (var loc5 in loc4.UniquesDict.First().Value) { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } - loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc4.Columns.Sort((c1, c2) => { - int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); - if (compare == 0) { - bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); - bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); - compare = b2.CompareTo(b1); - } - if (compare == 0) compare = c1.Name.CompareTo(c2.Name); - return compare; - }); - loc1.Add(loc4); - } - loc1.Sort((t1, t2) => { - var ret = t1.Schema.CompareTo(t2.Schema); - if (ret == 0) ret = t1.Name.CompareTo(t2.Name); - return ret; - }); + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + { + foreach (var loc5 in loc4.UniquesDict.First().Value) + { + loc5.IsPrimary = true; + loc4.Primarys.Add(loc5); + } + } + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); - loc2.Clear(); - loc3.Clear(); - tables.AddRange(loc1); - } - return tables; - } + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } - public List GetEnumsByDatabase(params string[] database) { - return new List(); - } - } + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index d0d6b6f4..8af8d56a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -7,377 +7,429 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.SqlServer { - class SqlServerExpression : CommonExpression { +namespace FreeSql.SqlServer +{ + class SqlServerExpression : CommonExpression + { - public SqlServerExpression(CommonUtils common) : base(common) { } + public SqlServerExpression(CommonUtils common) : base(common) { } - public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.NodeType) { - case ExpressionType.Convert: - var operandExp = (exp as UnaryExpression)?.Operand; - var gentype = exp.Type.NullableTypeOrThis(); - if (gentype != operandExp.Type.NullableTypeOrThis()) { - switch (gentype.ToString()) { - case "System.Boolean": return $"(cast({getExp(operandExp)} as varchar) not in ('0','false'))"; - case "System.Byte": return $"cast({getExp(operandExp)} as tinyint)"; - case "System.Char": return $"substring(cast({getExp(operandExp)} as nvarchar),1,1)"; - case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; - case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; - case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; - case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; - case "System.Int32": return $"cast({getExp(operandExp)} as int)"; - case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; - case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)"; - case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; - case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)"; - case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)"; - case "System.UInt32": return $"cast({getExp(operandExp)} as int)"; - case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)"; - case "System.Guid": return $"cast({getExp(operandExp)} as uniqueidentifier)"; - } - } - break; - case ExpressionType.Call: - var callExp = exp as MethodCallExpression; + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return $"(cast({getExp(operandExp)} as varchar) not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as tinyint)"; + case "System.Char": return $"substring(cast({getExp(operandExp)} as nvarchar),1,1)"; + case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; + case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Int32": return $"cast({getExp(operandExp)} as int)"; + case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; + case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)"; + case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; + case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)"; + case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)"; + case "System.UInt32": return $"cast({getExp(operandExp)} as int)"; + case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)"; + case "System.Guid": return $"cast({getExp(operandExp)} as uniqueidentifier)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; - switch(callExp.Method.Name) { - case "Parse": - case "TryParse": - switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { - case "System.Boolean": return $"(cast({getExp(callExp.Arguments[0])} as varchar) not in ('0','false'))"; - case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; - case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as nvarchar),1,1)"; - case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; - case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; - case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; - case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; - case "System.Int32": return $"cast({getExp(callExp.Arguments[0])} as int)"; - case "System.Int64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; - case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; - case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; - case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; - case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as int)"; - case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; - case "System.Guid": return $"cast({getExp(callExp.Arguments[0])} as uniqueidentifier)"; - } - break; - case "NewGuid": - switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { - case "System.Guid": return $"newid()"; - } - break; - case "Next": - if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as int)"; - break; - case "NextDouble": - if (callExp.Object?.Type == typeof(Random)) return "rand()"; - break; - case "Random": - if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; - break; - case "ToString": - if (callExp.Object != null) return callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)"; - break; - } + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(cast({getExp(callExp.Arguments[0])} as varchar) not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; + case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as nvarchar),1,1)"; + case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; + case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Int32": return $"cast({getExp(callExp.Arguments[0])} as int)"; + case "System.Int64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; + case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as int)"; + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.Guid": return $"cast({getExp(callExp.Arguments[0])} as uniqueidentifier)"; + } + break; + case "NewGuid": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Guid": return $"newid()"; + } + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as int)"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "rand()"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; + break; + case "ToString": + if (callExp.Object != null) return callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)"; + break; + } - var objExp = callExp.Object; - var objType = objExp?.Type; - if (objType?.FullName == "System.Byte[]") return null; + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; - var argIndex = 0; - if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) { - objExp = callExp.Arguments.FirstOrDefault(); - objType = objExp?.Type; - argIndex++; - } - if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) { - var left = objExp == null ? null : getExp(objExp); - switch (callExp.Method.Name) { - case "Contains": - //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; - } - } - break; - case ExpressionType.NewArrayInit: - var arrExp = exp as NewArrayExpression; - var arrSb = new StringBuilder(); - arrSb.Append("("); - for (var a = 0; a < arrExp.Expressions.Count; a++) { - if (a > 0) arrSb.Append(","); - arrSb.Append(getExp(arrExp.Expressions[a])); - } - if (arrSb.Length == 1) arrSb.Append("NULL"); - return arrSb.Append(")").ToString(); - case ExpressionType.ListInit: - var listExp = exp as ListInitExpression; - var listSb = new StringBuilder(); - listSb.Append("("); - for (var a = 0; a < listExp.Initializers.Count; a++) { - if (listExp.Initializers[a].Arguments.Any() == false) continue; - if (a > 0) listSb.Append(","); - listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); - } - if (listSb.Length == 1) listSb.Append("NULL"); - return listSb.Append(")").ToString(); - case ExpressionType.New: - var newExp = exp as NewExpression; - if (typeof(IList).IsAssignableFrom(newExp.Type)) { - if (newExp.Arguments.Count == 0) return "(NULL)"; - if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; - return getExp(newExp.Arguments[0]); - } - return null; - } - return null; - } + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in + return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } - public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Empty": return "''"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Length": return $"len({left})"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Now": return "getdate()"; - case "UtcNow": return "getutcdate()"; - case "Today": return "convert(char(10),getdate(),120)"; - case "MinValue": return "'1753/1/1 0:00:00'"; - case "MaxValue": return "'9999/12/31 23:59:59'"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Date": return $"convert(char(10),{left},120)"; - case "TimeOfDay": return $"datediff(second, convert(char(10),{left},120), {left})"; - case "DayOfWeek": return $"(datepart(weekday, {left})-1)"; - case "Day": return $"datepart(day, {left})"; - case "DayOfYear": return $"datepart(dayofyear, {left})"; - case "Month": return $"datepart(month, {left})"; - case "Year": return $"datepart(year, {left})"; - case "Hour": return $"datepart(hour, {left})"; - case "Minute": return $"datepart(minute, {left})"; - case "Second": return $"datepart(second, {left})"; - case "Millisecond": return $"(datepart(millisecond, {left})/1000)"; - case "Ticks": return $"(cast(datediff(second, '1970-1-1', {left}) as bigint)*10000000+621355968000000000)"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Zero": return "0"; - case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 - case "MaxValue": return "922337203685477580"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Days": return $"floor(({left})/{60 * 60 * 24})"; - case "Hours": return $"floor(({left})/{60 * 60}%24)"; - case "Milliseconds": return $"(cast({left} as bigint)*1000)"; - case "Minutes": return $"floor(({left})/60%60)"; - case "Seconds": return $"(({left})%60)"; - case "Ticks": return $"(cast({left} as bigint)*10000000)"; - case "TotalDays": return $"(({left})/{60 * 60 * 24})"; - case "TotalHours": return $"(({left})/{60 * 60})"; - case "TotalMilliseconds": return $"(cast({left} as bigint)*1000)"; - case "TotalMinutes": return $"(({left})/60)"; - case "TotalSeconds": return $"({left})"; - } - return null; - } + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"len({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "getdate()"; + case "UtcNow": return "getutcdate()"; + case "Today": return "convert(char(10),getdate(),120)"; + case "MinValue": return "'1753/1/1 0:00:00'"; + case "MaxValue": return "'9999/12/31 23:59:59'"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"convert(char(10),{left},120)"; + case "TimeOfDay": return $"datediff(second, convert(char(10),{left},120), {left})"; + case "DayOfWeek": return $"(datepart(weekday, {left})-1)"; + case "Day": return $"datepart(day, {left})"; + case "DayOfYear": return $"datepart(dayofyear, {left})"; + case "Month": return $"datepart(month, {left})"; + case "Year": return $"datepart(year, {left})"; + case "Hour": return $"datepart(hour, {left})"; + case "Minute": return $"datepart(minute, {left})"; + case "Second": return $"datepart(second, {left})"; + case "Millisecond": return $"(datepart(millisecond, {left})/1000)"; + case "Ticks": return $"(cast(datediff(second, '1970-1-1', {left}) as bigint)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{60 * 60}%24)"; + case "Milliseconds": return $"(cast({left} as bigint)*1000)"; + case "Minutes": return $"floor(({left})/60%60)"; + case "Seconds": return $"(({left})%60)"; + case "Ticks": return $"(cast({left} as bigint)*10000000)"; + case "TotalDays": return $"(({left})/{60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{60 * 60})"; + case "TotalMilliseconds": return $"(cast({left} as bigint)*1000)"; + case "TotalMinutes": return $"(({left})/60)"; + case "TotalSeconds": return $"({left})"; + } + return null; + } - public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "IsNullOrEmpty": - var arg1 = getExp(exp.Arguments[0]); - return $"({arg1} is null or {arg1} = '')"; - case "Concat": - return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); - } - } else { - var left = getExp(exp.Object); - switch (exp.Method.Name) { - case "StartsWith": - case "EndsWith": - case "Contains": - var args0Value = getExp(exp.Arguments[0]); - if (args0Value == "NULL") return $"({left}) IS NULL"; - if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}"; - if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')"; - case "ToLower": return $"lower({left})"; - case "ToUpper": return $"upper({left})"; - case "Substring": - var substrArgs1 = getExp(exp.Arguments[0]); - if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); - else substrArgs1 += "+1"; - if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})"; - return $"substring({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; - case "IndexOf": - var indexOfFindStr = getExp(exp.Arguments[0]); - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") { - var locateArgs1 = getExp(exp.Arguments[1]); - if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); - else locateArgs1 += "+1"; - return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)"; - } - return $"(charindex({left}, {indexOfFindStr})-1)"; - case "PadLeft": - if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; - return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "PadRight": - if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; - return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Trim": return $"ltrim(rtrim({left}))"; - case "TrimStart": return $"ltrim({left})"; - case "TrimEnd": return $"rtrim({left})"; - case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "CompareTo": return $"({left} - {getExp(exp.Arguments[0])})"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - } - } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.Method.Name) { - case "Abs": return $"abs({getExp(exp.Arguments[0])})"; - case "Sign": return $"sign({getExp(exp.Arguments[0])})"; - case "Floor": return $"floor({getExp(exp.Arguments[0])})"; - case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; - case "Round": - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - return $"round({getExp(exp.Arguments[0])}, 0)"; - case "Exp": return $"exp({getExp(exp.Arguments[0])})"; - case "Log": return $"log({getExp(exp.Arguments[0])})"; - case "Log10": return $"log10({getExp(exp.Arguments[0])})"; - case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; - case "Cos": return $"cos({getExp(exp.Arguments[0])})"; - case "Sin": return $"sin({getExp(exp.Arguments[0])})"; - case "Tan": return $"tan({getExp(exp.Arguments[0])})"; - case "Acos": return $"acos({getExp(exp.Arguments[0])})"; - case "Asin": return $"asin({getExp(exp.Arguments[0])})"; - case "Atan": return $"atan({getExp(exp.Arguments[0])})"; - case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Truncate": return $"floor({getExp(exp.Arguments[0])})"; - } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; - case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})"; + return $"substring({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)"; + } + return $"(charindex({left}, {indexOfFindStr})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": return $"ltrim(rtrim({left}))"; + case "TrimStart": return $"ltrim({left})"; + case "TrimEnd": return $"rtrim({left})"; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"({left} - {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])}, 0)"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"floor({getExp(exp.Arguments[0])})"; + } + throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "IsLeapYear": - var isLeapYearArgs1 = getExp(exp.Arguments[0]); - return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"dateadd(second, {args1}, {left})"; - case "AddDays": return $"dateadd(day, {args1}, {left})"; - case "AddHours": return $"dateadd(hour, {args1}, {left})"; - case "AddMilliseconds": return $"dateadd(second, ({args1})/1000, {left})"; - case "AddMinutes": return $"dateadd(minute, {args1}, {left})"; - case "AddMonths": return $"dateadd(month, {args1}, {left})"; - case "AddSeconds": return $"dateadd(second, {args1}, {left})"; - case "AddTicks": return $"dateadd(second, ({args1})/10000000, {left})"; - case "AddYears": return $"dateadd(year, {args1}, {left})"; - case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { - case "System.DateTime": return $"datediff(second, {args1}, {left})"; - case "System.TimeSpan": return $"dateadd(second, {args1}*-1, {left})"; - } - break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"datediff(second,{getExp(exp.Arguments[0])},{left})"; - case "ToString": return $"convert(varchar, {left}, 121)"; - } - } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; - case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; - case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; - case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; - case "FromSeconds": return $"({getExp(exp.Arguments[0])})"; - case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as bigint)"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as bigint)"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"({left}+{args1})"; - case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; - case "ToString": return $"cast({left} as varchar)"; - } - } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "ToBoolean": return $"(cast({getExp(exp.Arguments[0])} as varchar) not in ('0','false'))"; - case "ToByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; - case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as nvarchar),1,1)"; - case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; - case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; - case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; - case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; - case "ToInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; - case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; - case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; - case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; - case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)"; - case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; - case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; - case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; - } - } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); - } - } + case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"dateadd(second, {args1}, {left})"; + case "AddDays": return $"dateadd(day, {args1}, {left})"; + case "AddHours": return $"dateadd(hour, {args1}, {left})"; + case "AddMilliseconds": return $"dateadd(second, ({args1})/1000, {left})"; + case "AddMinutes": return $"dateadd(minute, {args1}, {left})"; + case "AddMonths": return $"dateadd(month, {args1}, {left})"; + case "AddSeconds": return $"dateadd(second, {args1}, {left})"; + case "AddTicks": return $"dateadd(second, ({args1})/10000000, {left})"; + case "AddYears": return $"dateadd(year, {args1}, {left})"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"datediff(second, {args1}, {left})"; + case "System.TimeSpan": return $"dateadd(second, {args1}*-1, {left})"; + } + break; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"datediff(second,{getExp(exp.Arguments[0])},{left})"; + case "ToString": return $"convert(varchar, {left}, 121)"; + } + } + throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; + case "FromSeconds": return $"({getExp(exp.Arguments[0])})"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "ToString": return $"cast({left} as varchar)"; + } + } + throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(cast({getExp(exp.Arguments[0])} as varchar) not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; + case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as nvarchar),1,1)"; + case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; + case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; + case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; + case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)"; + case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + } + } + throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + } + } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index c9fe63b4..e7d5dd5f 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -1,11 +1,12 @@ -public static partial class FreeSqlGlobalExtensions { +public static partial class FreeSqlGlobalExtensions +{ - /// - /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 - /// - /// - /// - /// - public static string FormatSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args); - static FreeSql.SqlServer.SqlServerAdo _sqlserverAdo = new FreeSql.SqlServer.SqlServerAdo(); + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args); + static FreeSql.SqlServer.SqlServerAdo _sqlserverAdo = new FreeSql.SqlServer.SqlServerAdo(); } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index f6abcc0d..f0e2fe85 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -4,58 +4,67 @@ using FreeSql.SqlServer.Curd; using System; using System.Collections.Generic; -namespace FreeSql.SqlServer { +namespace FreeSql.SqlServer +{ - public class SqlServerProvider : IFreeSql { + public class SqlServerProvider : IFreeSql + { - public ISelect Select() where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new SqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public ISelect Select() where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new SqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } - public SqlServerProvider(string masterConnectionString, string[] slaveConnectionString) { - this.InternalCommonUtils = new SqlServerUtils(this); - this.InternalCommonExpression = new SqlServerExpression(this.InternalCommonUtils); + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public SqlServerProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new SqlServerUtils(this); + this.InternalCommonExpression = new SqlServerExpression(this.InternalCommonUtils); - this.Ado = new SqlServerAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); - this.Aop = new AopProvider(); + this.Ado = new SqlServerAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); - this.DbFirst = new SqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - this.CodeFirst = new SqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.DbFirst = new SqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new SqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - if (this.Ado.MasterPool != null) - using (var conn = this.Ado.MasterPool.Get()) { - try { - (this.InternalCommonUtils as SqlServerUtils).IsSelectRowNumber = int.Parse(conn.Value.ServerVersion.Split('.')[0]) <= 10; - } catch { - } - } - } + if (this.Ado.MasterPool != null) + using (var conn = this.Ado.MasterPool.Get()) + { + try + { + (this.InternalCommonUtils as SqlServerUtils).IsSelectRowNumber = int.Parse(conn.Value.ServerVersion.Split('.')[0]) <= 10; + } + catch + { + } + } + } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } - public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); - ~SqlServerProvider() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - (this.Ado as AdoProvider)?.Dispose(); - } - } + ~SqlServerProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 5c0812e6..5bef8a09 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -8,75 +8,88 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.SqlServer { +namespace FreeSql.SqlServer +{ - class SqlServerUtils : CommonUtils { - public SqlServerUtils(IFreeSql orm) : base(orm) { - } + class SqlServerUtils : CommonUtils + { + public SqlServerUtils(IFreeSql orm) : base(orm) + { + } - public bool IsSelectRowNumber = true; + public bool IsSelectRowNumber = true; - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { - if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); - var ret = new SqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; - _params?.Add(ret); - return ret; - } + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = new SqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; + _params?.Add(ret); + return ret; + } - public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { - if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); - var ret = new SqlParameter { ParameterName = $"@{name}", Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; - return ret; - }); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => + { + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = new SqlParameter { ParameterName = $"@{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; + return ret; + }); - public override string FormatSql(string sql, params object[] args) => sql?.FormatSqlServer(args); - public override string QuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; - } - public override string TrimQuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; - } - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; - public override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) { - var sb = new StringBuilder(); - var news = new string[objs.Length]; - for (var a = 0; a < objs.Length; a++) - news[a] = types[a] == typeof(string) ? objs[a] : $"cast({objs[a]} as nvarchar)"; - return string.Join(" + ", news); - } - public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string FormatSql(string sql, params object[] args) => sql?.FormatSqlServer(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) + { + var sb = new StringBuilder(); + var news = new string[objs.Length]; + for (var a = 0; a < objs.Length; a++) + news[a] = types[a] == typeof(string) ? objs[a] : $"cast({objs[a]} as nvarchar)"; + return string.Join(" + ", news); + } + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; - public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { - if (value == null) return "NULL"; - if (type == typeof(byte[])) { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } - return sb.ToString(); - } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { - var ts = (TimeSpan)value; - value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; - } - return FormatSql("{0}", value, 1); - } - } + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.ToString(); + } + else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; + } + return FormatSql("{0}", value, 1); + } + } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs index 13f60c51..f582cb6b 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs @@ -5,18 +5,23 @@ using System.Data; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Sqlite.Curd { +namespace FreeSql.Sqlite.Curd +{ - class SqliteDelete : Internal.CommonProvider.DeleteProvider where T1 : class { - public SqliteDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + class SqliteDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public SqliteDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override List ExecuteDeleted() { - throw new NotImplementedException(); - } - public override Task> ExecuteDeletedAsync() { - throw new NotImplementedException(); - } - } + public override List ExecuteDeleted() + { + throw new NotImplementedException(); + } + public override Task> ExecuteDeletedAsync() + { + throw new NotImplementedException(); + } + } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index 80ec45dc..ab43f919 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -6,76 +6,93 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Sqlite.Curd { +namespace FreeSql.Sqlite.Curd +{ - class SqliteInsert : Internal.CommonProvider.InsertProvider where T1 : class { - public SqliteInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) - : base(orm, commonUtils, commonExpression) { - } + class SqliteInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public SqliteInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 999); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 999); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 999); - protected override long RawExecuteIdentity() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - sql = string.Concat(sql, "; SELECT last_insert_rowid();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - async protected override Task RawExecuteIdentityAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; + sql = string.Concat(sql, "; SELECT last_insert_rowid();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; - sql = string.Concat(sql, "; SELECT last_insert_rowid();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } catch (Exception ex) { - exception = ex; - throw ex; - } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; - } - protected override List RawExecuteInserted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + sql = string.Concat(sql, "; SELECT last_insert_rowid();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - this.RawExecuteAffrows(); - return _source; - } - async protected override Task> RawExecuteInsertedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); + this.RawExecuteAffrows(); + return _source; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); - await this.RawExecuteAffrowsAsync(); - return _source; - } - } + await this.RawExecuteAffrowsAsync(); + return _source; + } + } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index d7dd6253..e21a1b36 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -6,123 +6,145 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.Sqlite.Curd { +namespace FreeSql.Sqlite.Curd +{ - class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { + class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) { - if (_orm.CodeFirst.IsAutoSyncStructure) - _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field).Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - } - break; - } else { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + var sb = new StringBuilder(); + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); + else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); - sbnav.Append(_where); - foreach (var tb in _tables) { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } - if (sbnav.Length > 0) { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); - if (_skip > 0 || _limit > 0) - sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); + sbnav.Append(_where); + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_skip > 0 || _limit > 0) + sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); - sbnav.Clear(); - return sb.ToString(); - } + sbnav.Clear(); + return sb.ToString(); + } - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); - } + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index 0915c757..a7a568a4 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -7,55 +7,66 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FreeSql.Sqlite.Curd { +namespace FreeSql.Sqlite.Curd +{ - class SqliteUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { + class SqliteUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { - public SqliteUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) { - } + public SqliteUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); - protected override List RawExecuteUpdated() { - throw new NotImplementedException(); - } - protected override Task> RawExecuteUpdatedAsync() { - throw new NotImplementedException(); - } + protected override List RawExecuteUpdated() + { + throw new NotImplementedException(); + } + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } - protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { - if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); - return; - } - caseWhen.Append("CONCAT("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); - ++pkidx; - } - caseWhen.Append(")"); - } + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(", "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } - protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { - if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); - return; - } - sb.Append("CONCAT("); - var pkidx = 0; - foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); - ++pkidx; - } - sb.Append(")"); - } - } + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(", "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + ++pkidx; + } + sb.Append(")"); + } + } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 1bc44c5f..137dd99e 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -7,54 +7,63 @@ using System.Data.SQLite; using System.Text; using System.Threading; -namespace FreeSql.Sqlite { - class SqliteAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public SqliteAdo() : base(DataType.Sqlite) { } - public SqliteAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Sqlite) { - base._util = util; - if (!string.IsNullOrEmpty(masterConnectionString)) - MasterPool = new SqliteConnectionPool("主库", masterConnectionString, null, null); - if (slaveConnectionStrings != null) { - foreach (var slaveConnectionString in slaveConnectionStrings) { - var slavePool = new SqliteConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); - SlavePools.Add(slavePool); - } - } - } - static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) { - if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) - param = Utils.GetDataReaderValue(mapType, param); - if (param is bool || param is bool?) - return (bool)param ? 1 : 0; - else if (param is string || param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - else if (param is Enum) - return ((Enum)param).ToInt64(); - else if (decimal.TryParse(string.Concat(param), out var trydec)) - return param; - else if (param is DateTime || param is DateTime?) - return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss"), "'"); - else if (param is TimeSpan || param is TimeSpan?) - return ((TimeSpan)param).Ticks / 10000; - else if (param is IEnumerable) { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - } +namespace FreeSql.Sqlite +{ + class SqliteAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public SqliteAdo() : base(DataType.Sqlite) { } + public SqliteAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Sqlite) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new SqliteConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new SqliteConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10000; + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } - protected override DbCommand CreateCommand() { - return new SQLiteCommand(); - } + protected override DbCommand CreateCommand() + { + return new SQLiteCommand(); + } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { - (pool as SqliteConnectionPool).Return(conn, ex); - } + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as SqliteConnectionPool).Return(conn, ex); + } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); - } + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index c65580f7..8cad9db5 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -10,205 +10,250 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; -namespace FreeSql.Sqlite { +namespace FreeSql.Sqlite +{ - class SqliteConnectionPool : ObjectPool { + class SqliteConnectionPool : ObjectPool + { - internal Action availableHandler; - internal Action unavailableHandler; + internal Action availableHandler; + internal Action unavailableHandler; - public SqliteConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - policy = new SqliteConnectionPoolPolicy { - _pool = this, - Name = name - }; - this.Policy = policy; - policy.ConnectionString = connectionString; + public SqliteConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + policy = new SqliteConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; - } + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } - public void Return(Object obj, Exception exception, bool isRecreate = false) { - if (exception != null && exception is SQLiteException) { - try { if (obj.Value.Ping() == false) obj.Value.OpenAndAttach(policy.Attaches); } catch { base.SetUnavailable(exception); } - } - base.Return(obj, isRecreate); - } + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is SQLiteException) + { + try { if (obj.Value.Ping() == false) obj.Value.OpenAndAttach(policy.Attaches); } catch { base.SetUnavailable(exception); } + } + base.Return(obj, isRecreate); + } - internal SqliteConnectionPoolPolicy policy; - } + internal SqliteConnectionPoolPolicy policy; + } - class SqliteConnectionPoolPolicy : IPolicy { + class SqliteConnectionPoolPolicy : IPolicy + { - internal SqliteConnectionPool _pool; - public string Name { get; set; } = "Sqlite SQLiteConnection 对象池"; - public int PoolSize { get; set; } = 100; - public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; - public int AsyncGetCapacity { get; set; } = 10000; - public bool IsThrowGetTimeoutException { get; set; } = true; - public int CheckAvailableInterval { get; set; } = 5; - public string[] Attaches = new string[0]; + internal SqliteConnectionPool _pool; + public string Name { get; set; } = "Sqlite SQLiteConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + public string[] Attaches = new string[0]; - static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - private string _connectionString; - public string ConnectionString { - get => _connectionString; - set { - _connectionString = value ?? ""; + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; - var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; - Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); - PoolSize = poolsize + connStrIncr; - _connectionString = m.Success ? - Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : - $"{_connectionString};Max pool size={PoolSize}"; + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; - pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - var minPoolSize = 0; - pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) { - minPoolSize = int.Parse(m.Groups[1].Value); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } - var att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase); - if (att.Length == 2) { - var idx = att[1].IndexOf(';'); - Attaches = (idx == -1 ? att[1] : att[1].Substring(0, idx)).Split(','); - } + var att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase); + if (att.Length == 2) + { + var idx = att[1].IndexOf(';'); + Attaches = (idx == -1 ? att[1] : att[1].Substring(0, idx)).Split(','); + } - FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); - } - } + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } - public bool OnCheckAvailable(Object obj) { - if (obj.Value.State == ConnectionState.Closed) obj.Value.OpenAndAttach(Attaches); - return obj.Value.Ping(true); - } + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.OpenAndAttach(Attaches); + return obj.Value.Ping(true); + } - public DbConnection OnCreate() { - var conn = new SQLiteConnection(_connectionString); - return conn; - } + public DbConnection OnCreate() + { + var conn = new SQLiteConnection(_connectionString); + return conn; + } - public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); - obj.Dispose(); - } + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } - public void OnGet(Object obj) { + public void OnGet(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { - try { - obj.Value.OpenAndAttach(Attaches); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + obj.Value.OpenAndAttach(Attaches); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - async public Task OnGetAsync(Object obj) { + async public Task OnGetAsync(Object obj) + { - if (_pool.IsAvailable) { + if (_pool.IsAvailable) + { - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { - try { - await obj.Value.OpenAndAttachAsync(Attaches); - } catch (Exception ex) { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } + try + { + await obj.Value.OpenAndAttachAsync(Attaches); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } - public void OnGetTimeout() { + public void OnGetTimeout() + { - } + } - public void OnReturn(Object obj) { + public void OnReturn(Object obj) + { - } + } - public void OnAvailable() { - _pool.availableHandler?.Invoke(); - } + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } - public void OnUnavailable() { - _pool.unavailableHandler?.Invoke(); - } - } - static class DbConnectionExtensions { + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + static class DbConnectionExtensions + { - static DbCommand PingCommand(DbConnection conn) { - var cmd = conn.CreateCommand(); - cmd.CommandTimeout = 5; - cmd.CommandText = "select 1"; - return cmd; - } - public static bool Ping(this DbConnection that, bool isThrow = false) { - try { - PingCommand(that).ExecuteNonQuery(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - async public static Task PingAsync(this DbConnection that, bool isThrow = false) { - try { - await PingCommand(that).ExecuteNonQueryAsync(); - return true; - } catch { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } - public static void OpenAndAttach(this DbConnection that, string[] attach) { - that.Open(); + public static void OpenAndAttach(this DbConnection that, string[] attach) + { + that.Open(); - if (attach?.Any() == true) { - var sb = new StringBuilder(); - foreach(var att in attach) - sb.Append($"attach database [{att}] as [{att.Split('.').First()}];\r\n"); + if (attach?.Any() == true) + { + var sb = new StringBuilder(); + foreach (var att in attach) + sb.Append($"attach database [{att}] as [{att.Split('.').First()}];\r\n"); - var cmd = that.CreateCommand(); - cmd.CommandText = sb.ToString(); - cmd.ExecuteNonQuery(); - } - } - async public static Task OpenAndAttachAsync(this DbConnection that, string[] attach) { - await that.OpenAsync(); + var cmd = that.CreateCommand(); + cmd.CommandText = sb.ToString(); + cmd.ExecuteNonQuery(); + } + } + async public static Task OpenAndAttachAsync(this DbConnection that, string[] attach) + { + await that.OpenAsync(); - if (attach?.Any() == true) { - var sb = new StringBuilder(); - foreach (var att in attach) - sb.Append($"attach database [{att}] as [{att.Split('.').First()}];\r\n"); + if (attach?.Any() == true) + { + var sb = new StringBuilder(); + foreach (var att in attach) + sb.Append($"attach database [{att}] as [{att.Split('.').First()}];\r\n"); - var cmd = that.CreateCommand(); - cmd.CommandText = sb.ToString(); - await cmd.ExecuteNonQueryAsync(); - } - } - } + var cmd = that.CreateCommand(); + cmd.CommandText = sb.ToString(); + await cmd.ExecuteNonQueryAsync(); + } + } + } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index e3488b89..85d684d4 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -10,231 +10,267 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; -namespace FreeSql.Sqlite { +namespace FreeSql.Sqlite +{ - class SqliteCodeFirst : Internal.CommonProvider.CodeFirstProvider { + class SqliteCodeFirst : Internal.CommonProvider.CodeFirstProvider + { - public SqliteCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + public SqliteCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } - static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (DbType.Boolean, "boolean","boolean NOT NULL", null, false, false) },{ typeof(bool?).FullName, (DbType.Boolean, "boolean","boolean", null, true, null) }, + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (DbType.Boolean, "boolean","boolean NOT NULL", null, false, false) },{ typeof(bool?).FullName, (DbType.Boolean, "boolean","boolean", null, true, null) }, - { typeof(sbyte).FullName, (DbType.SByte, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (DbType.SByte, "smallint", "smallint", false, true, null) }, - { typeof(short).FullName, (DbType.Int16, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (DbType.Int16, "smallint", "smallint", false, true, null) }, - { typeof(int).FullName, (DbType.Int32, "integer", "integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, (DbType.Int32, "integer", "integer", false, true, null) }, - { typeof(long).FullName, (DbType.Int64, "integer","integer NOT NULL", false, false, 0) },{ typeof(long?).FullName, (DbType.Int64, "integer","integer", false, true, null) }, + { typeof(sbyte).FullName, (DbType.SByte, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (DbType.SByte, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, (DbType.Int16, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (DbType.Int16, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, (DbType.Int32, "integer", "integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, (DbType.Int32, "integer", "integer", false, true, null) }, + { typeof(long).FullName, (DbType.Int64, "integer","integer NOT NULL", false, false, 0) },{ typeof(long?).FullName, (DbType.Int64, "integer","integer", false, true, null) }, - { typeof(byte).FullName, (DbType.Byte, "int2","int2 NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (DbType.Byte, "int2","int2", true, true, null) }, - { typeof(ushort).FullName, (DbType.UInt16, "unsigned","unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (DbType.UInt16, "unsigned", "unsigned", true, true, null) }, - { typeof(uint).FullName, (DbType.Decimal, "decimal(10,0)", "decimal(10,0) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (DbType.Decimal, "decimal(10,0)", "decimal(10,0)", true, true, null) }, - { typeof(ulong).FullName, (DbType.Decimal, "decimal(21,0)", "decimal(21,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (DbType.Decimal, "decimal(21,0)", "decimal(21,0)", true, true, null) }, + { typeof(byte).FullName, (DbType.Byte, "int2","int2 NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (DbType.Byte, "int2","int2", true, true, null) }, + { typeof(ushort).FullName, (DbType.UInt16, "unsigned","unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (DbType.UInt16, "unsigned", "unsigned", true, true, null) }, + { typeof(uint).FullName, (DbType.Decimal, "decimal(10,0)", "decimal(10,0) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (DbType.Decimal, "decimal(10,0)", "decimal(10,0)", true, true, null) }, + { typeof(ulong).FullName, (DbType.Decimal, "decimal(21,0)", "decimal(21,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (DbType.Decimal, "decimal(21,0)", "decimal(21,0)", true, true, null) }, - { typeof(double).FullName, (DbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (DbType.Double, "double", "double", false, true, null) }, - { typeof(float).FullName, (DbType.Single, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (DbType.Single, "float","float", false, true, null) }, - { typeof(decimal).FullName, (DbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (DbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(double).FullName, (DbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (DbType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, (DbType.Single, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (DbType.Single, "float","float", false, true, null) }, + { typeof(decimal).FullName, (DbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (DbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(TimeSpan).FullName, (DbType.Time, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (DbType.Time, "bigint", "bigint",false, true, null) }, - { typeof(DateTime).FullName, (DbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (DbType.DateTime, "datetime", "datetime", false, true, null) }, + { typeof(TimeSpan).FullName, (DbType.Time, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (DbType.Time, "bigint", "bigint",false, true, null) }, + { typeof(DateTime).FullName, (DbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (DbType.DateTime, "datetime", "datetime", false, true, null) }, - { typeof(byte[]).FullName, (DbType.Binary, "blob", "blob", false, null, new byte[0]) }, - { typeof(string).FullName, (DbType.String, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(byte[]).FullName, (DbType.Binary, "blob", "blob", false, null, new byte[0]) }, + { typeof(string).FullName, (DbType.String, "nvarchar", "nvarchar(255)", false, null, "") }, - { typeof(Guid).FullName, (DbType.Guid, "character", "character(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (DbType.Guid, "character", "character(36)", false, true, null) }, - }; + { typeof(Guid).FullName, (DbType.Guid, "character", "character(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (DbType.Guid, "character", "character(36)", false, true, null) }, + }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); - if (type.IsArray) return null; - var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); - if (enumType != null) { - var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (DbType.Int64, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (DbType.Int32, "mediumint", $"mediumint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); - if (_dicCsToDb.ContainsKey(type.FullName) == false) { - lock (_dicCsToDbLock) { - if (_dicCsToDb.ContainsKey(type.FullName) == false) - _dicCsToDb.Add(type.FullName, newItem); - } - } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); - } - return null; - } - - public override string GetComparisonDDLStatements(params Type[] entityTypes) { - var sb = new StringBuilder(); - var sbDeclare = new StringBuilder(); - foreach (var entityType in entityTypes) { - if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); - if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] }; + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (DbType.Int64, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (DbType.Int32, "mediumint", $"mediumint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { "main", tboldname[0] }; + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var sb = new StringBuilder(); + var sbDeclare = new StringBuilder(); + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] }; - var sbalter = new StringBuilder(); - var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - var isIndent = false; - if (_orm.Ado.ExecuteScalar(CommandType.Text, $" select 1 from {tbname[0]}.sqlite_master where type='table' and name='{tbname[1]}'") == null) { //表不存在 - if (tboldname != null) { - if (_orm.Ado.ExecuteScalar(CommandType.Text, $" select 1 from {tboldname[0]}.sqlite_master where type='table' and name='{tboldname[1]}'") == null) - //模式或表不存在 - tboldname = null; - } - if (tboldname == null) { - //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) { - isIndent = true; - sb.Append(" PRIMARY KEY AUTOINCREMENT"); - } - sb.Append(","); - } - if (isIndent == false && tb.Primarys.Any()) { - sb.Append(" \r\n PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) \r\n;\r\n"); - continue; - } - //如果新表,旧表在一个模式下,直接修改表名 - if (string.Compare(tbname[0], tboldname[0], true) == 0) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); - else { - //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 - istmpatler = true; - } - } else - tboldname = null; //如果新表已经存在,不走改表名逻辑 + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { "main", tboldname[0] }; - //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var tbtmp = tboldname ?? tbname; - var dsql = _orm.Ado.ExecuteScalar(CommandType.Text, $" select sql from {tbtmp[0]}.sqlite_master where type='table' and name='{tbtmp[1]}'")?.ToString(); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.table_info({_commonUtils.QuoteSqlName(tbtmp[1])})"); - var tbstruct = ds.ToDictionary(a => string.Concat(a[1]), a => { - var is_identity = false; - var dsqlIdx = dsql?.IndexOf($"\"{a[1]}\" "); - if (dsqlIdx > 0) { - var dsqlLastIdx = dsql.IndexOf('\n', dsqlIdx.Value); - if (dsqlLastIdx > 0) is_identity = dsql.Substring(dsqlIdx.Value, dsqlLastIdx - dsqlIdx.Value).Contains("AUTOINCREMENT"); - } - return new { - column = string.Concat(a[1]), - sqlType = string.Concat(a[2]).ToUpper(), - is_nullable = string.Concat(a[3]) == "0", - is_identity - }; - }, StringComparer.CurrentCultureIgnoreCase); + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + var isIndent = false; + if (_orm.Ado.ExecuteScalar(CommandType.Text, $" select 1 from {tbname[0]}.sqlite_master where type='table' and name='{tbname[1]}'") == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, $" select 1 from {tboldname[0]}.sqlite_master where type='table' and name='{tboldname[1]}'") == null) + //模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) + { + isIndent = true; + sb.Append(" PRIMARY KEY AUTOINCREMENT"); + } + sb.Append(","); + } + if (isIndent == false && tb.Primarys.Any()) + { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) \r\n;\r\n"); + continue; + } + //如果新表,旧表在一个模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 - if (istmpatler == false) { - foreach (var tbcol in tb.Columns.Values) { - var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) - istmpatler = true; - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - istmpatler = true; - if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - istmpatler = true; - if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) - //修改列名 - istmpatler = true; - continue; - } - //添加列 - istmpatler = true; - } - var dsukMatches = _regexUK.Matches(dsql); - var dsuk = new List(); - foreach (Match dsukm in dsukMatches) { - var dbsukmg2 = dsukm.Groups[2].Value.Split(','); - if (dbsukmg2.Any() == false) continue; - foreach (var dbfield in dbsukmg2) { - dsuk.Add(new[] { Regex.Match(dbfield, @"""([^""]+)""").Groups[1].Value, dsukm.Groups[1].Value }); - } - } - foreach (var uk in tb.Uniques) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) { - istmpatler = true; - } - } - } - if (istmpatler == false) { - sb.Append(sbalter); - continue; - } + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var tbtmp = tboldname ?? tbname; + var dsql = _orm.Ado.ExecuteScalar(CommandType.Text, $" select sql from {tbtmp[0]}.sqlite_master where type='table' and name='{tbtmp[1]}'")?.ToString(); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.table_info({_commonUtils.QuoteSqlName(tbtmp[1])})"); + var tbstruct = ds.ToDictionary(a => string.Concat(a[1]), a => + { + var is_identity = false; + var dsqlIdx = dsql?.IndexOf($"\"{a[1]}\" "); + if (dsqlIdx > 0) + { + var dsqlLastIdx = dsql.IndexOf('\n', dsqlIdx.Value); + if (dsqlLastIdx > 0) is_identity = dsql.Substring(dsqlIdx.Value, dsqlLastIdx - dsqlIdx.Value).Contains("AUTOINCREMENT"); + } + return new + { + column = string.Concat(a[1]), + sqlType = string.Concat(a[2]).ToUpper(), + is_nullable = string.Concat(a[3]) == "0", + is_identity + }; + }, StringComparer.CurrentCultureIgnoreCase); - //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}._FreeSqlTmp_{tbname[1]}"); - //创建临时表 - //创建表 - isIndent = false; - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) { - isIndent = true; - sb.Append(" PRIMARY KEY AUTOINCREMENT"); - } - sb.Append(","); - } - if (isIndent == false && tb.Primarys.Any()) { - sb.Append(" \r\n PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - foreach (var uk in tb.Uniques) { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) \r\n;\r\n"); - sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) - sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.Columns.Values) { - var insertvalue = "NULL"; - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) { - var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); - insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; - } - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; - } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); - sb.Append(insertvalue).Append(", "); - } - sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); - sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); - } - return sb.Length == 0 ? null : sb.ToString(); - } - static Regex _regexUK = new Regex(@"CONSTRAINT\s*""([^""]+)""\s*UNIQUE\s*\(([^\)]+)\)", RegexOptions.IgnoreCase | RegexOptions.Compiled); - } + if (istmpatler == false) + { + foreach (var tbcol in tb.Columns.Values) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + istmpatler = true; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + istmpatler = true; + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + istmpatler = true; + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + istmpatler = true; + continue; + } + //添加列 + istmpatler = true; + } + var dsukMatches = _regexUK.Matches(dsql); + var dsuk = new List(); + foreach (Match dsukm in dsukMatches) + { + var dbsukmg2 = dsukm.Groups[2].Value.Split(','); + if (dbsukmg2.Any() == false) continue; + foreach (var dbfield in dbsukmg2) + { + dsuk.Add(new[] { Regex.Match(dbfield, @"""([^""]+)""").Groups[1].Value, dsukm.Groups[1].Value }); + } + } + foreach (var uk in tb.Uniques) + { + if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + istmpatler = true; + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}._FreeSqlTmp_{tbname[1]}"); + //创建临时表 + //创建表 + isIndent = false; + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.Columns.Values) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) + { + isIndent = true; + sb.Append(" PRIMARY KEY AUTOINCREMENT"); + } + sb.Append(","); + } + if (isIndent == false && tb.Primarys.Any()) + { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) \r\n;\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.Columns.Values) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); + insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } + static Regex _regexUK = new Regex(@"CONSTRAINT\s*""([^""]+)""\s*UNIQUE\s*\(([^\)]+)\)", RegexOptions.IgnoreCase | RegexOptions.Compiled); + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index d44576b9..5a0d21a4 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -7,397 +7,451 @@ using System.Linq; using System.Linq.Expressions; using System.Text; -namespace FreeSql.Sqlite { - class SqliteExpression : CommonExpression { +namespace FreeSql.Sqlite +{ + class SqliteExpression : CommonExpression + { - public SqliteExpression(CommonUtils common) : base(common) { } + public SqliteExpression(CommonUtils common) : base(common) { } - public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.NodeType) { - case ExpressionType.Convert: - var operandExp = (exp as UnaryExpression)?.Operand; - var gentype = exp.Type.NullableTypeOrThis(); - if (gentype != operandExp.Type.NullableTypeOrThis()) { - switch (exp.Type.NullableTypeOrThis().ToString()) { - case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; - case "System.Byte": return $"cast({getExp(operandExp)} as int2)"; - case "System.Char": return $"substr(cast({getExp(operandExp)} as character), 1, 1)"; - case "System.DateTime": return $"datetime({getExp(operandExp)})"; - case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; - case "System.Double": return $"cast({getExp(operandExp)} as double)"; - case "System.Int16": - case "System.Int32": - case "System.Int64": - case "System.SByte": return $"cast({getExp(operandExp)} as smallint)"; - case "System.Single": return $"cast({getExp(operandExp)} as float)"; - case "System.String": return $"cast({getExp(operandExp)} as character)"; - case "System.UInt16": return $"cast({getExp(operandExp)} as unsigned)"; - case "System.UInt32": return $"cast({getExp(operandExp)} as decimal(10,0))"; - case "System.UInt64": return $"cast({getExp(operandExp)} as decimal(21,0))"; - case "System.Guid": return $"substr(cast({getExp(operandExp)} as character), 1, 36)"; - } - } - break; - case ExpressionType.Call: - var callExp = exp as MethodCallExpression; + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as int2)"; + case "System.Char": return $"substr(cast({getExp(operandExp)} as character), 1, 1)"; + case "System.DateTime": return $"datetime({getExp(operandExp)})"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(operandExp)} as double)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Single": return $"cast({getExp(operandExp)} as float)"; + case "System.String": return $"cast({getExp(operandExp)} as character)"; + case "System.UInt16": return $"cast({getExp(operandExp)} as unsigned)"; + case "System.UInt32": return $"cast({getExp(operandExp)} as decimal(10,0))"; + case "System.UInt64": return $"cast({getExp(operandExp)} as decimal(21,0))"; + case "System.Guid": return $"substr(cast({getExp(operandExp)} as character), 1, 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; - switch (callExp.Method.Name) { - case "Parse": - case "TryParse": - switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { - case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; - case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as int2)"; - case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as character), 1, 1)"; - case "System.DateTime": return $"datetime({getExp(callExp.Arguments[0])})"; - case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; - case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as double)"; - case "System.Int16": - case "System.Int32": - case "System.Int64": - case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; - case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as float)"; - case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; - case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as decimal(10,0))"; - case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as decimal(21,0))"; - case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as character), 1, 36)"; - } - break; - case "NewGuid": - break; - case "Next": - if (callExp.Object?.Type == typeof(Random)) return "cast(random()*1000000000 as int)"; - break; - case "NextDouble": - if (callExp.Object?.Type == typeof(Random)) return "random()"; - break; - case "Random": - if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; - break; - case "ToString": - if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as character)"; - break; - } + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as int2)"; + case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as character), 1, 1)"; + case "System.DateTime": return $"datetime({getExp(callExp.Arguments[0])})"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as double)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as float)"; + case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; + case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as decimal(10,0))"; + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as decimal(21,0))"; + case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as character), 1, 36)"; + } + break; + case "NewGuid": + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(random()*1000000000 as int)"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + break; + case "ToString": + if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as character)"; + break; + } - var objExp = callExp.Object; - var objType = objExp?.Type; - if (objType?.FullName == "System.Byte[]") return null; + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; - var argIndex = 0; - if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) { - objExp = callExp.Arguments.FirstOrDefault(); - objType = objExp?.Type; - argIndex++; - } - if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) { - var left = objExp == null ? null : getExp(objExp); - switch (callExp.Method.Name) { - case "Contains": - //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; - } - } - break; - case ExpressionType.NewArrayInit: - var arrExp = exp as NewArrayExpression; - var arrSb = new StringBuilder(); - arrSb.Append("("); - for (var a = 0; a < arrExp.Expressions.Count; a++) { - if (a > 0) arrSb.Append(","); - arrSb.Append(getExp(arrExp.Expressions[a])); - } - if (arrSb.Length == 1) arrSb.Append("NULL"); - return arrSb.Append(")").ToString(); - case ExpressionType.ListInit: - var listExp = exp as ListInitExpression; - var listSb = new StringBuilder(); - listSb.Append("("); - for (var a = 0; a < listExp.Initializers.Count; a++) { - if (listExp.Initializers[a].Arguments.Any() == false) continue; - if (a > 0) listSb.Append(","); - listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); - } - if (listSb.Length == 1) listSb.Append("NULL"); - return listSb.Append(")").ToString(); - case ExpressionType.New: - var newExp = exp as NewExpression; - if (typeof(IList).IsAssignableFrom(newExp.Type)) { - if (newExp.Arguments.Count == 0) return "(NULL)"; - if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; - return getExp(newExp.Arguments[0]); - } - return null; - } - return null; - } + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in + return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } - public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Empty": return "''"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Length": return $"length({left})"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Now": return "datetime(current_timestamp,'localtime')"; - case "UtcNow": return "current_timestamp"; - case "Today": return "date(current_timestamp,'localtime')"; - case "MinValue": return "datetime('0001-01-01 00:00:00.000')"; - case "MaxValue": return "datetime('9999-12-31 23:59:59.999')"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Date": return $"date({left})"; - case "TimeOfDay": return $"strftime('%s',{left})"; - case "DayOfWeek": return $"strftime('%w',{left})"; - case "Day": return $"strftime('%d',{left})"; - case "DayOfYear": return $"strftime('%j',{left})"; - case "Month": return $"strftime('%m',{left})"; - case "Year": return $"strftime('%Y',{left})"; - case "Hour": return $"strftime('%H',{left})"; - case "Minute": return $"strftime('%M',{left})"; - case "Second": return $"strftime('%S',{left})"; - case "Millisecond": return $"(strftime('%f',{left})-strftime('%S',{left}))"; - case "Ticks": return $"(strftime('%s',{left})*10000000+621355968000000000)"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) { - if (exp.Expression == null) { - switch (exp.Member.Name) { - case "Zero": return "0"; - case "MinValue": return "-922337203685.477580"; //秒 Ticks / 1000,000,0 - case "MaxValue": return "922337203685.477580"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) { - case "Days": return $"floor(({left})/{60 * 60 * 24})"; - case "Hours": return $"floor(({left})/{60 * 60}%24)"; - case "Milliseconds": return $"(cast({left} as bigint)*1000)"; - case "Minutes": return $"floor(({left})/60%60)"; - case "Seconds": return $"(({left})%60)"; - case "Ticks": return $"(cast({left} as bigint)*10000000)"; - case "TotalDays": return $"(({left})/{60 * 60 * 24})"; - case "TotalHours": return $"(({left})/{60 * 60})"; - case "TotalMilliseconds": return $"(cast({left} as bigint)*1000)"; - case "TotalMinutes": return $"(({left})/60)"; - case "TotalSeconds": return $"({left})"; - } - return null; - } + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "datetime(current_timestamp,'localtime')"; + case "UtcNow": return "current_timestamp"; + case "Today": return "date(current_timestamp,'localtime')"; + case "MinValue": return "datetime('0001-01-01 00:00:00.000')"; + case "MaxValue": return "datetime('9999-12-31 23:59:59.999')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"date({left})"; + case "TimeOfDay": return $"strftime('%s',{left})"; + case "DayOfWeek": return $"strftime('%w',{left})"; + case "Day": return $"strftime('%d',{left})"; + case "DayOfYear": return $"strftime('%j',{left})"; + case "Month": return $"strftime('%m',{left})"; + case "Year": return $"strftime('%Y',{left})"; + case "Hour": return $"strftime('%H',{left})"; + case "Minute": return $"strftime('%M',{left})"; + case "Second": return $"strftime('%S',{left})"; + case "Millisecond": return $"(strftime('%f',{left})-strftime('%S',{left}))"; + case "Ticks": return $"(strftime('%s',{left})*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685.477580"; //秒 Ticks / 1000,000,0 + case "MaxValue": return "922337203685.477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{60 * 60}%24)"; + case "Milliseconds": return $"(cast({left} as bigint)*1000)"; + case "Minutes": return $"floor(({left})/60%60)"; + case "Seconds": return $"(({left})%60)"; + case "Ticks": return $"(cast({left} as bigint)*10000000)"; + case "TotalDays": return $"(({left})/{60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{60 * 60})"; + case "TotalMilliseconds": return $"(cast({left} as bigint)*1000)"; + case "TotalMinutes": return $"(({left})/60)"; + case "TotalSeconds": return $"({left})"; + } + return null; + } - public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "IsNullOrEmpty": - var arg1 = getExp(exp.Arguments[0]); - return $"({arg1} is null or {arg1} = '')"; - case "Concat": - return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); - } - } else { - var left = getExp(exp.Object); - switch (exp.Method.Name) { - case "StartsWith": - case "EndsWith": - case "Contains": - var args0Value = getExp(exp.Arguments[0]); - if (args0Value == "NULL") return $"({left}) IS NULL"; - if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"({args0Value})||'%'")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"'%'||({args0Value})")}"; - if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) LIKE '%'||({args0Value})||'%'"; - case "ToLower": return $"lower({left})"; - case "ToUpper": return $"upper({left})"; - case "Substring": - var substrArgs1 = getExp(exp.Arguments[0]); - if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); - else substrArgs1 += "+1"; - if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; - return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; - case "IndexOf": - var indexOfFindStr = getExp(exp.Arguments[0]); - //if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") { - // var locateArgs1 = getExp(exp.Arguments[1]); - // if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); - // else locateArgs1 += "+1"; - // return $"(instr({left}, {indexOfFindStr}, {locateArgs1})-1)"; - //} - return $"(instr({left}, {indexOfFindStr})-1)"; - case "PadLeft": - if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; - return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "PadRight": - if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; - return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Trim": - case "TrimStart": - case "TrimEnd": - if (exp.Arguments.Count == 0) { - if (exp.Method.Name == "Trim") return $"trim({left})"; - if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; - if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; - } - var trimArg1 = ""; - var trimArg2 = ""; - foreach (var argsTrim02 in exp.Arguments) { - var argsTrim01s = new[] { argsTrim02 }; - if (argsTrim02.NodeType == ExpressionType.NewArrayInit) { - var arritem = argsTrim02 as NewArrayExpression; - argsTrim01s = arritem.Expressions.ToArray(); - } - foreach (var argsTrim01 in argsTrim01s) { - var trimChr = getExp(argsTrim01).Trim('\''); - if (trimChr.Length == 1) trimArg1 += trimChr; - else trimArg2 += $" || ({trimChr})"; - } - } - if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - return left; - case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - } - } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.Method.Name) { - case "Abs": return $"abs({getExp(exp.Arguments[0])})"; - case "Sign": return $"sign({getExp(exp.Arguments[0])})"; - case "Floor": return $"floor({getExp(exp.Arguments[0])})"; - case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; - case "Round": - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - return $"round({getExp(exp.Arguments[0])})"; - case "Exp": return $"exp({getExp(exp.Arguments[0])})"; - case "Log": return $"log({getExp(exp.Arguments[0])})"; - case "Log10": return $"log10({getExp(exp.Arguments[0])})"; - case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; - case "Cos": return $"cos({getExp(exp.Arguments[0])})"; - case "Sin": return $"sin({getExp(exp.Arguments[0])})"; - case "Tan": return $"tan({getExp(exp.Arguments[0])})"; - case "Acos": return $"acos({getExp(exp.Arguments[0])})"; - case "Asin": return $"asin({getExp(exp.Arguments[0])})"; - case "Atan": return $"atan({getExp(exp.Arguments[0])})"; - case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - //case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)"; - } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"(strftime('%s',{getExp(exp.Arguments[0])}) -strftime('%s',{getExp(exp.Arguments[1])}))"; - case "DaysInMonth": return $"strftime('%d',date({getExp(exp.Arguments[0])}||'-01-01',{getExp(exp.Arguments[1])}||' months','-1 days'))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"({args0Value})||'%'")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"'%'||({args0Value})")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE '%'||({args0Value})||'%'"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + //if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") { + // var locateArgs1 = getExp(exp.Arguments[1]); + // if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + // else locateArgs1 += "+1"; + // return $"(instr({left}, {indexOfFindStr}, {locateArgs1})-1)"; + //} + return $"(instr({left}, {indexOfFindStr})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + var trimArg1 = ""; + var trimArg2 = ""; + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + var trimChr = getExp(argsTrim01).Trim('\''); + if (trimChr.Length == 1) trimArg1 += trimChr; + else trimArg2 += $" || ({trimChr})"; + } + } + if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + //case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)"; + } + throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"(strftime('%s',{getExp(exp.Arguments[0])}) -strftime('%s',{getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"strftime('%d',date({getExp(exp.Arguments[0])}||'-01-01',{getExp(exp.Arguments[1])}||' months','-1 days'))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "IsLeapYear": - var isLeapYearArgs1 = getExp(exp.Arguments[0]); - return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; - case "Parse": return $"datetime({getExp(exp.Arguments[0])})"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"datetime({getExp(exp.Arguments[0])})"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"datetime({left},({args1})||' seconds')"; - case "AddDays": return $"datetime({left},({args1})||' days')"; - case "AddHours": return $"datetime({left},({args1})||' hours')"; - case "AddMilliseconds": return $"datetime({left},(({args1})/1000)||' seconds')"; - case "AddMinutes": return $"datetime({left},({args1})||' seconds')"; - case "AddMonths": return $"datetime({left},({args1})||' months')"; - case "AddSeconds": return $"datetime({left},({args1})||' seconds')"; - case "AddTicks": return $"datetime({left},(({args1})/10000000)||' seconds')"; - case "AddYears": return $"datetime({left},({args1})||' years')"; - case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { - case "System.DateTime": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; - case "System.TimeSpan": return $"datetime({left},(-{args1})||' seconds')"; - } - break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; - case "ToString": return $"strftime('%Y-%m-%d %H:%M.%f',{left})"; - } - } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; - case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; - case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; - case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; - case "FromSeconds": return $"(({getExp(exp.Arguments[0])}))"; - case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; - case "Parse": return $"cast({getExp(exp.Arguments[0])} as bigint)"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as bigint)"; - } - } else { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) { - case "Add": return $"({left}+{args1})"; - case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; - case "ToString": return $"cast({left} as character)"; - } - } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); - } - public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) { - switch (exp.Method.Name) { - case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; - case "ToByte": return $"cast({getExp(exp.Arguments[0])} as int2)"; - case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as character), 1, 1)"; - case "ToDateTime": return $"datetime({getExp(exp.Arguments[0])})"; - case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; - case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as double)"; - case "ToInt16": - case "ToInt32": - case "ToInt64": - case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as smallint)"; - case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as float)"; - case "ToString": return $"cast({getExp(exp.Arguments[0])} as character)"; - case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; - case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as decimal(10,0))"; - case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as decimal(21,0))"; - } - } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); - } - } + case "Parse": return $"datetime({getExp(exp.Arguments[0])})"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"datetime({getExp(exp.Arguments[0])})"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"datetime({left},({args1})||' seconds')"; + case "AddDays": return $"datetime({left},({args1})||' days')"; + case "AddHours": return $"datetime({left},({args1})||' hours')"; + case "AddMilliseconds": return $"datetime({left},(({args1})/1000)||' seconds')"; + case "AddMinutes": return $"datetime({left},({args1})||' seconds')"; + case "AddMonths": return $"datetime({left},({args1})||' months')"; + case "AddSeconds": return $"datetime({left},({args1})||' seconds')"; + case "AddTicks": return $"datetime({left},(({args1})/10000000)||' seconds')"; + case "AddYears": return $"datetime({left},({args1})||' years')"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; + case "System.TimeSpan": return $"datetime({left},(-{args1})||' seconds')"; + } + break; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; + case "ToString": return $"strftime('%Y-%m-%d %H:%M.%f',{left})"; + } + } + throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])}))"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "ToString": return $"cast({left} as character)"; + } + } + throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as int2)"; + case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as character), 1, 1)"; + case "ToDateTime": return $"datetime({getExp(exp.Arguments[0])})"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as double)"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as float)"; + case "ToString": return $"cast({getExp(exp.Arguments[0])} as character)"; + case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; + case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as decimal(10,0))"; + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as decimal(21,0))"; + } + } + throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + } + } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExtensions.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExtensions.cs index c9224c1b..a988dd50 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExtensions.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExtensions.cs @@ -1,11 +1,12 @@ -public static partial class FreeSqlGlobalExtensions { +public static partial class FreeSqlGlobalExtensions +{ - /// - /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 - /// - /// - /// - /// - public static string FormatSqlite (this string that, params object[] args) => _sqliteAdo.Addslashes(that, args); - static FreeSql.Sqlite.SqliteAdo _sqliteAdo = new FreeSql.Sqlite.SqliteAdo(); + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatSqlite(this string that, params object[] args) => _sqliteAdo.Addslashes(that, args); + static FreeSql.Sqlite.SqliteAdo _sqliteAdo = new FreeSql.Sqlite.SqliteAdo(); } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 73948db3..7ecf5db6 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -5,49 +5,54 @@ using System; using System.Collections.Generic; using System.Data.Common; -namespace FreeSql.Sqlite { +namespace FreeSql.Sqlite +{ - public class SqliteProvider : IFreeSql { + public class SqliteProvider : IFreeSql + { - public ISelect Select() where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new SqliteInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public ISelect Select() where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new SqliteInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst => null; - public SqliteProvider(string masterConnectionString, string[] slaveConnectionString) { - this.InternalCommonUtils = new SqliteUtils(this); - this.InternalCommonExpression = new SqliteExpression(this.InternalCommonUtils); + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst => null; + public SqliteProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new SqliteUtils(this); + this.InternalCommonExpression = new SqliteExpression(this.InternalCommonUtils); - this.Ado = new SqliteAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); - this.Aop = new AopProvider(); + this.Ado = new SqliteAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); - this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - } + this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } - public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); - ~SqliteProvider() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - (this.Ado as AdoProvider)?.Dispose(); - } - } + ~SqliteProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index dc3e633c..0ce0b722 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -8,76 +8,86 @@ using System.Data.SQLite; using System.Linq.Expressions; using System.Text; -namespace FreeSql.Sqlite { +namespace FreeSql.Sqlite +{ - class SqliteUtils : CommonUtils { - public SqliteUtils(IFreeSql orm) : base(orm) { - } + class SqliteUtils : CommonUtils + { + public SqliteUtils(IFreeSql orm) : base(orm) + { + } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { - if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; - switch (dbtype) { - case DbType.Guid: - if (value == null) value = null; - else value = ((Guid)value).ToString(); - dbtype = DbType.String; - break; - case DbType.Time: - if (value == null) value = null; - else value = ((TimeSpan)value).Ticks / 10000; - dbtype = DbType.Int64; - break; - } - var ret = new SQLiteParameter { ParameterName = QuoteParamterName(parameterName), DbType = dbtype, Value = value }; - _params?.Add(ret); - return ret; - } + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case DbType.Guid: + if (value == null) value = null; + else value = ((Guid)value).ToString(); + dbtype = DbType.String; + break; + case DbType.Time: + if (value == null) value = null; + else value = ((TimeSpan)value).Ticks / 10000; + dbtype = DbType.Int64; + break; + } + var ret = new SQLiteParameter { ParameterName = QuoteParamterName(parameterName), DbType = dbtype, Value = value }; + _params?.Add(ret); + return ret; + } - public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { - var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; - switch (dbtype) { - case DbType.Guid: - if (value == null) value = null; - else value = ((Guid)value).ToString(); - dbtype = DbType.String; - break; - case DbType.Time: - if (value == null) value = null; - else value = ((TimeSpan)value).Ticks / 10000; - dbtype = DbType.Int64; - break; - } - var ret = new SQLiteParameter { ParameterName = $"@{name}", DbType = dbtype, Value = value }; - return ret; - }); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => + { + var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case DbType.Guid: + if (value == null) value = null; + else value = ((Guid)value).ToString(); + dbtype = DbType.String; + break; + case DbType.Time: + if (value == null) value = null; + else value = ((TimeSpan)value).Ticks / 10000; + dbtype = DbType.Int64; + break; + } + var ret = new SQLiteParameter { ParameterName = $"@{name}", DbType = dbtype, Value = value }; + return ret; + }); - public override string FormatSql(string sql, params object[] args) => sql?.FormatSqlite(args); - public override string QuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; - } - public override string TrimQuoteSqlName(string name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; - } - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; - public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; - public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string FormatSql(string sql, params object[] args) => sql?.FormatSqlite(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; - public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { - if (value == null) return "NULL"; - if (type == typeof(byte[])) value = Encoding.UTF8.GetString(value as byte[]); - return FormatSql("{0}", value, 1); - } - } + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) value = Encoding.UTF8.GetString(value as byte[]); + return FormatSql("{0}", value, 1); + } + } } From 0a206b588f7658318f65eed1f871662331905b52 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 2 Jul 2019 14:56:40 +0800 Subject: [PATCH 0032/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A=EF=BC=8C=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E5=88=B0=E6=95=B0=E6=8D=AE=E5=BA=93=E5=A4=87=E6=B3=A8?= =?UTF-8?q?=EF=BC=8C=E5=BD=93=E5=AE=9E=E4=BD=93=E7=B1=BB=E5=B1=9E=E4=BA=8E?= =?UTF-8?q?=20.exe=20=E7=A8=8B=E5=BA=8F=E9=9B=86=E6=97=B6=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/ftTests.xml | 198 ------------------ FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonUtils.cs | 12 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 12 files changed, 20 insertions(+), 210 deletions(-) delete mode 100644 FreeSql.Tests/FreeSql.Tests/ftTests.xml diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 4d94d32d..5a063f1e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 3371ed37..66031d34 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index a0b504d7..51d9d711 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.1 + 0.7.2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/ftTests.xml b/FreeSql.Tests/FreeSql.Tests/ftTests.xml deleted file mode 100644 index 55568931..00000000 --- a/FreeSql.Tests/FreeSql.Tests/ftTests.xml +++ /dev/null @@ -1,198 +0,0 @@ - - - - FreeSql.Tests - - - - - 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 类型 - - - - - 内容简介 - - - - - 缩略图 - - - - - 点击量 - - - - - - - - - - - - - - - - - - - - - - - - - 主键,ID - - - - - 试卷表 - - - - - 考核计划ID - - - - - 总分 - - - - - 菜单权限ID - - - - - 菜单主键ID - - - - - 按钮主键ID - - - - - 菜单权限 - - - - - 主键 - - - - - 父级ID - - - - - 名称 - - - - - 图标 - - - - - 链接地址 - - - - - 是否公开 - - - - - 排序 - - - - - 备注 - - - - - 创建日期 - - - - - 按钮主键 - - - - - 名称 - - - - - 事件名称 - - - - - 编码 - - - - - 图标 - - - - - 排序 - - - - - 创建日期 - - - - diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 657f4034..995764ae 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 132ce338..d3ab7304 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -282,7 +282,7 @@ namespace FreeSql.Internal /// Dict:key=属性名,value=注释 public static Dictionary GetProperyCommentBySummary(Type type) { - var xmlPath = type.Assembly.Location.Replace(".dll", ".xml"); + var xmlPath = type.Assembly.Location.Replace(".dll", ".xml").Replace(".exe", ".xml"); if (File.Exists(xmlPath) == false) return null; var dic = new Dictionary(); @@ -290,7 +290,15 @@ namespace FreeSql.Internal var sReader = new StringReader(File.ReadAllText(xmlPath)); using (var xmlReader = XmlReader.Create(sReader)) { - var xpath = new XPathDocument(xmlReader); + XPathDocument xpath = null; + try + { + xpath = new XPathDocument(xmlReader); + } + catch + { + return null; + } var xmlNav = xpath.CreateNavigator(); var props = type.GetProperties(); diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index dc32780a..4a2bb3f0 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 86e4ba0f..ffc58266 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a2fbdd88..f2db0b01 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index efd7c307..d24c5e15 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0cc24814..1b30b0c3 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a3423442..988d58c5 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.1 + 0.7.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 2a61415f06736f8a64e55d0c321488f84229dd66 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 2 Jul 2019 18:15:43 +0800 Subject: [PATCH 0033/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect.From?= =?UTF-8?q?=20=E5=BD=93=E4=BC=A0=E5=85=A5=E7=9B=B8=E5=90=8C?= =?UTF-8?q?=E7=9A=84=E4=B8=A4=E4=B8=AA=E5=AE=9E=E4=BD=93=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=EF=BC=8C=E5=8F=AF=E8=83=BD=E5=AF=BC=E8=87=B4=E5=86=85=E9=83=A8?= =?UTF-8?q?=20Join=20=E6=97=A0=E6=B3=95=E5=8C=B9=E9=85=8D=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20IGroupSelect=20ToSql(strin?= =?UTF-8?q?g)=20=E9=87=8D=E8=BD=BD=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 7 ++++ FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 7 ++++ .../Interface/Curd/ISelect/ISelectGrouping.cs | 6 ++++ FreeSql/Internal/CommonExpression.cs | 2 +- .../SelectProvider/Select1Provider.cs | 32 ++++++++++++------- .../SelectProvider/SelectGroupingProvider.cs | 8 +++++ .../Curd/MySqlSelect.cs | 18 +++++------ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../Curd/OracleSelect.cs | 18 +++++------ .../FreeSql.Provider.Oracle.csproj | 2 +- .../Curd/PostgreSQLSelect.cs | 18 +++++------ .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../Curd/SqlServerSelect.cs | 18 +++++------ .../FreeSql.Provider.SqlServer.csproj | 2 +- .../Curd/SqliteSelect.cs | 18 +++++------ .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 105 insertions(+), 67 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5a063f1e..ac53e4ed 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 66031d34..cd7b1179 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 51d9d711..71443e69 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.2 + 0.7.3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index e5e93ff3..4a011e01 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -296,6 +296,13 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var tkdkdksql = g.sqlite.Select().From((a, b, c) => + a.LeftJoin(aa => aa.TemplatesId == b.Id2 && b.Code == "xx") + .LeftJoin(aa => aa.TemplatesId == c.Id2)) + .GroupBy((a, b, c) => new { a.NamespaceName, c.Code }) + .ToSql("a.id"); + + var dcksdkdsk = g.sqlite.Select().Where(a => a.testaddtime2.HasValue).ToSql(); var dcksdkdsk2 = g.sqlite.Select().Where(a => !a.testaddtime2.HasValue).ToSql(); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 995764ae..381b5e22 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9ce72c3a..9da53f94 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1377,6 +1377,13 @@ 选择列 + + + 返回即将执行的SQL语句 + + 指定字段 + + 查询向后偏移行数 diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 0b52dfbf..eac8339d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -50,6 +50,12 @@ namespace FreeSql /// 选择列 /// string ToSql(Expression, TReturn>> select); + /// + /// 返回即将执行的SQL语句 + /// + /// 指定字段 + /// + string ToSql(string field); /// diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6f89f5e1..5566635b 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -386,7 +386,7 @@ namespace FreeSql.Internal } else { - var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On)).LastOrDefault(); + var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On) && sql.Contains(a.Alias + ".")).LastOrDefault(); if (find != null) { find.Type = tbtype; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 5885b69e..aba152e5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -25,9 +25,19 @@ namespace FreeSql.Internal.CommonProvider } - protected ISelect InternalFrom(Expression exp) + protected ISelect InternalFrom(LambdaExpression lambdaExp) { - if (exp.NodeType == ExpressionType.Call) + if (lambdaExp != null) + { + for (var a = 1; a < lambdaExp.Parameters.Count; a++) + { + var tb = _commonUtils.GetTableByEntity(lambdaExp.Parameters[a].Type); + if (tb == null) throw new ArgumentException($"{lambdaExp.Parameters[a].Name} 类型错误"); + _tables.Add(new SelectTableInfo { Table = tb, Alias = lambdaExp.Parameters[a].Name, On = null, Type = SelectTableInfoType.From }); + } + } + var exp = lambdaExp?.Body; + if (exp?.NodeType == ExpressionType.Call) { var expCall = exp as MethodCallExpression; var stockCall = new Stack(); @@ -106,15 +116,15 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvgAsync(column?.Body); } - public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class;// { this.InternalFrom(exp?.Body); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class;// { this.InternalFrom(exp?.Body); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class;// { this.InternalFrom(exp?.Body); var ret = new Select4Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class;// { this.InternalFrom(exp?.Body); var ret = new Select5Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class;// { this.InternalFrom(exp?.Body); var ret = new Select6Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class;// { this.InternalFrom(exp?.Body); var ret = new Select7Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class;// { this.InternalFrom(exp?.Body); var ret = new Select8Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class;// { this.InternalFrom(exp?.Body); var ret = new Select9Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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;// { this.InternalFrom(exp?.Body); var ret = new Select10Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class;// { this.InternalFrom(exp); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class;// { this.InternalFrom(exp); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class;// { this.InternalFrom(exp); var ret = new Select4Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class;// { this.InternalFrom(exp); var ret = new Select5Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class;// { this.InternalFrom(exp); var ret = new Select6Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class;// { this.InternalFrom(exp); var ret = new Select7Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class;// { this.InternalFrom(exp); var ret = new Select8Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class;// { this.InternalFrom(exp); var ret = new Select9Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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;// { this.InternalFrom(exp); var ret = new Select10Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } public ISelectGrouping GroupBy(Expression> columns) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 810c9069..0dd4533b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -140,6 +140,14 @@ namespace FreeSql.Internal.CommonProvider var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; } + public string ToSql(string field) + { + if (string.IsNullOrEmpty(field)) + throw new ArgumentException("参数 field 未指定"); + + var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); + return method.Invoke(_select, new object[] { field }) as string; + } public ISelectGrouping Skip(int offset) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index f9463f3d..3292efc6 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -91,15 +91,15 @@ namespace FreeSql.MySql.Curd } public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 4a2bb3f0..38e648f5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ffc58266..8b8168a3 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index d11da9a0..df385797 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -107,15 +107,15 @@ namespace FreeSql.Oracle.Curd } public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index f2db0b01..215453b5 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index d58b098e..e5bb3f9d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -93,15 +93,15 @@ namespace FreeSql.PostgreSQL.Curd } public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d24c5e15..6d6e39a5 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index afc7347f..50791ab9 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -205,15 +205,15 @@ namespace FreeSql.SqlServer.Curd #endregion public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 1b30b0c3..0438731c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index e21a1b36..1cdf4651 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -91,15 +91,15 @@ namespace FreeSql.Sqlite.Curd } public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 988d58c5..8c7333ce 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.2 + 0.7.3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 250d13c330402e63a7c763b3455eb8c8180508cd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 3 Jul 2019 09:56:22 +0800 Subject: [PATCH 0034/1029] =?UTF-8?q?=E5=AE=8C=E5=96=84=20Distinct=20?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 8e1567b3..09350041 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -255,6 +255,12 @@ namespace FreeSql /// /// 查询数据前,去重 + /// + /// .Distinct().ToList(x => x.GroupName) 对指定字段去重 + /// + /// + /// .Distinct().ToList() 对整个查询去重 + /// /// /// TSelect Distinct(); From b04a4e7266d18d6ef2d96f87ce254c7986abfe35 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 3 Jul 2019 16:38:29 +0800 Subject: [PATCH 0035/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Insert=20Cle?= =?UTF-8?q?arData=20=E9=87=8D=E5=A4=8D=E5=88=A9=E7=94=A8=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=88=E4=BD=BF=E7=94=A8=20IgnoreColumns=20=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E5=A4=A7=E6=89=B9=E9=87=8F=E6=8F=92=E5=85=A5=E6=97=B6?= =?UTF-8?q?=E4=BC=9A=E5=8F=91=E7=94=9F=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../MySqlConnector/Curd/MySqlInsertTest.cs | 16 ++++++++++++++++ .../FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs | 16 ++++++++++++++++ .../Oracle/Curd/OracleInsertTest.cs | 16 ++++++++++++++++ .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 16 ++++++++++++++++ .../SqlServer/Curd/SqlServerInsertTest.cs | 16 ++++++++++++++++ .../SqlServer/SqlServerExpression/ConvertTest.cs | 8 ++++---- .../Sqlite/Curd/SqliteInsertTest.cs | 16 ++++++++++++++++ FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 6 ++++++ .../Internal/CommonProvider/InsertProvider.cs | 2 -- .../Internal/CommonProvider/UpdateProvider.cs | 2 -- .../FreeSql.Provider.MySql/Curd/MySqlInsert.cs | 4 ---- .../FreeSql.Provider.MySql/Curd/MySqlUpdate.cs | 2 -- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/Curd/OracleInsert.cs | 4 ---- .../FreeSql.Provider.Oracle.csproj | 2 +- .../Curd/PostgreSQLInsert.cs | 6 ------ .../Curd/PostgreSQLUpdate.cs | 2 -- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../Curd/SqlServerInsert.cs | 4 ---- .../Curd/SqlServerUpdate.cs | 2 -- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs | 2 -- .../FreeSql.Provider.Sqlite.csproj | 2 +- 28 files changed, 116 insertions(+), 44 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ac53e4ed..81724648 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index cd7b1179..8bd9afbd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 71443e69..26d817d8 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.3 + 0.7.4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs index 26ac73fa..f80add2f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs @@ -77,6 +77,22 @@ namespace FreeSql.Tests.MySqlConnector sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.mysql.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.mysql.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs index 76fe633a..d0e746de 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs @@ -78,6 +78,22 @@ namespace FreeSql.Tests.MySql sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); + + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.mysql.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.mysql.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs index a87cedbf..ceaca63c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs @@ -152,6 +152,22 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_8) INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_9) SELECT 1 FROM DUAL", sql); data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.oracle.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.oracle.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicICs")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs index 877650ac..536a2231 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -64,6 +64,22 @@ namespace FreeSql.Tests.PostgreSQL sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); + + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.pgsql.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.pgsql.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index f1d3748b..c8e485c5 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -73,6 +73,22 @@ namespace FreeSql.Tests.SqlServer sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + + _sqlserverFixture.SqlServer.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + _sqlserverFixture.SqlServer.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, _sqlserverFixture.SqlServer.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs index f8abe2ed..824ce26f 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs @@ -92,8 +92,8 @@ namespace FreeSql.Tests.SqlServerExpression public void ToInt16() { var data = new List(); - data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + //data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + //data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); } [Fact] public void ToInt32() @@ -135,8 +135,8 @@ namespace FreeSql.Tests.SqlServerExpression public void ToUInt16() { var data = new List(); - data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); - data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + //data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + //data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); } [Fact] public void ToUInt32() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs index 57b3b869..ac532f9d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs @@ -64,6 +64,22 @@ namespace FreeSql.Tests.Sqlite sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"Clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.sqlite.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.sqlite.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] public void ExecuteAffrows() diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 381b5e22..dd1cc070 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9da53f94..b8babb01 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -971,6 +971,12 @@ 查询数据前,去重 + + .Distinct().ToList(x => x.GroupName) 对指定字段去重 + + + .Distinct().ToList() 对整个查询去重 + diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index f3363db3..9a2494f6 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -432,7 +432,6 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, affrows); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return affrows; } async protected Task RawExecuteAffrowsAsync() @@ -456,7 +455,6 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, affrows); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return affrows; } protected abstract long RawExecuteIdentity(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 1c06ebcb..01c03f51 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -320,7 +320,6 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, affrows); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return affrows; } async protected Task RawExecuteAffrowsAsync() @@ -347,7 +346,6 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, affrows); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return affrows; } protected abstract List RawExecuteUpdated(); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 35747893..ab8df3c2 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -47,7 +47,6 @@ namespace FreeSql.MySql.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task RawExecuteIdentityAsync() @@ -74,7 +73,6 @@ namespace FreeSql.MySql.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } protected override List RawExecuteInserted() @@ -111,7 +109,6 @@ namespace FreeSql.MySql.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task> RawExecuteInsertedAsync() @@ -148,7 +145,6 @@ namespace FreeSql.MySql.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 3015a0e3..4b820e1c 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -60,7 +60,6 @@ namespace FreeSql.MySql.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task> RawExecuteUpdatedAsync() @@ -99,7 +98,6 @@ namespace FreeSql.MySql.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 38e648f5..5e7285af 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8b8168a3..7b7b1100 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 8daaf144..df1d18c4 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -118,7 +118,6 @@ namespace FreeSql.Oracle.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); @@ -143,7 +142,6 @@ namespace FreeSql.Oracle.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task RawExecuteIdentityAsync() @@ -173,7 +171,6 @@ namespace FreeSql.Oracle.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); @@ -198,7 +195,6 @@ namespace FreeSql.Oracle.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 215453b5..ae11b3d7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index 3038a2c2..b9ee9379 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -52,7 +52,6 @@ namespace FreeSql.PostgreSQL.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); @@ -72,7 +71,6 @@ namespace FreeSql.PostgreSQL.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task RawExecuteIdentityAsync() @@ -103,7 +101,6 @@ namespace FreeSql.PostgreSQL.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); @@ -123,7 +120,6 @@ namespace FreeSql.PostgreSQL.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } @@ -161,7 +157,6 @@ namespace FreeSql.PostgreSQL.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task> RawExecuteInsertedAsync() @@ -198,7 +193,6 @@ namespace FreeSql.PostgreSQL.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index ad9fce0b..88554df2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -60,7 +60,6 @@ namespace FreeSql.PostgreSQL.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task> RawExecuteUpdatedAsync() @@ -99,7 +98,6 @@ namespace FreeSql.PostgreSQL.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 6d6e39a5..fb5c968f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 4fe5ba0b..9210ee7f 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -49,7 +49,6 @@ namespace FreeSql.SqlServer.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task RawExecuteIdentityAsync() @@ -76,7 +75,6 @@ namespace FreeSql.SqlServer.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } @@ -119,7 +117,6 @@ namespace FreeSql.SqlServer.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task> RawExecuteInsertedAsync() @@ -161,7 +158,6 @@ namespace FreeSql.SqlServer.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index a079557a..6e91a800 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -65,7 +65,6 @@ namespace FreeSql.SqlServer.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task> RawExecuteUpdatedAsync() @@ -109,7 +108,6 @@ namespace FreeSql.SqlServer.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0438731c..c3bda0b4 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index ab43f919..7fc0e3b9 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -48,7 +48,6 @@ namespace FreeSql.Sqlite.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } async protected override Task RawExecuteIdentityAsync() @@ -75,7 +74,6 @@ namespace FreeSql.Sqlite.Curd var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - this.ClearData(); return ret; } protected override List RawExecuteInserted() diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 8c7333ce..fd5b543b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.3 + 0.7.4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 619c57c254ed37ef2ddfcb2bd972fdf6d656fd5f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 4 Jul 2019 14:13:15 +0800 Subject: [PATCH 0036/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Insert/Updat?= =?UTF-8?q?e=20=E5=A4=A7=E6=89=B9=E9=87=8F=E6=93=8D=E4=BD=9C=E5=88=86?= =?UTF-8?q?=E6=89=B9=E6=89=A7=E8=A1=8C=E6=97=B6=EF=BC=8C=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E5=A4=96=E9=83=A8=E4=BD=BF=E7=94=A8=E4=BA=86=20Ado.Transaction?= =?UTF-8?q?=EF=BC=8C=E6=B2=A1=E6=9C=89=E4=BD=BF=E7=94=A8=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E5=AF=B9=E8=B1=A1=EF=BC=8C=E8=80=8C=E6=98=AF?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BA=86=E6=96=B0=E4=BA=8B=E5=8A=A1=E7=9A=84?= =?UTF-8?q?=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../Internal/CommonProvider/InsertProvider.cs | 18 ++++++++++++++++++ .../Internal/CommonProvider/UpdateProvider.cs | 12 ++++++++++++ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 12 files changed, 40 insertions(+), 10 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 81724648..ac4b783f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8bd9afbd..99c37e9c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 26d817d8..acb5b2fd 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.4 + 0.7.5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index dd1cc070..5ef4f348 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 9a2494f6..ee4a3d4b 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -132,6 +132,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) @@ -180,6 +183,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) @@ -228,6 +234,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) @@ -278,6 +287,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) @@ -328,6 +340,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) @@ -376,6 +391,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 01c03f51..80da28c1 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -132,6 +132,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) @@ -175,6 +178,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) @@ -218,6 +224,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) @@ -261,6 +270,9 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { for (var a = 0; a < ss.Length; a++) diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5e7285af..18eb5909 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7b7b1100..0a3fd69b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ae11b3d7..119e72f9 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index fb5c968f..1070d36e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c3bda0b4..089db883 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fd5b543b..5dda69b3 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.4 + 0.7.5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 3ebc01f88d9889ee078675bdb898bc7a7beea978 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 4 Jul 2019 19:46:51 +0800 Subject: [PATCH 0037/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=20true=20&&=20...=20=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=EF=BC=9B=20-=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20Navigate=20=E6=8C=87=E5=AE=9A=E8=81=94=E5=90=88=E9=94=AE?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E6=97=B6=EF=BC=8C=E5=AF=B9=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E7=9A=84=E8=A6=81=E6=B1=82=EF=BC=8C=E5=BD=93?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E4=B8=8D=E4=B8=80=E6=A0=B7=E3=80=81=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E4=B8=80=E6=A0=B7=E6=97=B6=E6=97=A0=E9=A1=BB=E6=8C=87?= =?UTF-8?q?=E6=98=8E=E5=B1=9E=E6=80=A7=E7=9A=84=E9=A1=BA=E5=BA=8F=EF=BC=8C?= =?UTF-8?q?=E5=A6=82=EF=BC=9A[Navigate("MemberId,=20ShopId")]=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/FreeSql.Tests.csproj | 1 - .../Other/CustomerCheckupGroup.cs | 89 +++++++++++++++ .../FreeSql.Tests/Other/CustomerMember.cs | 108 ++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 8 ++ FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 55 ++++----- FreeSql/Internal/UtilsExpressionTree.cs | 26 +++++ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 265 insertions(+), 42 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ac4b783f..90b5313a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 99c37e9c..548e045c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index acb5b2fd..2c3d3f9a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 902899b6..cee654fa 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -21,7 +21,6 @@ - diff --git a/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs b/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs new file mode 100644 index 00000000..788cafab --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs @@ -0,0 +1,89 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// Website: http://www.freesql.net +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; + +namespace ZX.Model { + + [JsonObject(MemberSerialization.OptIn)] + public class CustomerCheckupGroup { + + [JsonProperty, Column(IsPrimary = true)] + public short ShopId { get => _ShopId; set { + if (_ShopId == value) return; + _ShopId = value; + } } + private short _ShopId; + + [JsonProperty, Column(DbType = "varchar(50)", IsPrimary = true)] + public string Id { get; set; } + + [JsonProperty, Column(DbType = "nvarchar(50)")] + public string MemberId { get => _MemberId; set { + if (_MemberId == value) return; + _MemberId = value; + } } + private string _MemberId; + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Discount { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Doctor { get; set; } + + [JsonProperty] + public DateTime? FirstTime { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Group { get; set; } + + [JsonProperty] + public DateTime? InsertTime { get; set; } + + [JsonProperty, Column(Name = "isOK")] + public bool? IsOK { get; set; } + + [JsonProperty, Column(Name = "isPay", DbType = "varchar(50)")] + public string IsPay { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Office { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string PayType { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? Price { get; set; } + + [JsonProperty] + public DateTime? UpdateTime { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? Value { get; set; } + + + #region 外键 => 导航属性,ManyToOne/OneToOne + + [Navigate("ShopId, MemberId")] + public virtual CustomerMember CustomerMember { get; set; } + #endregion + + #region 外键 => 导航属性,ManyToMany + + #endregion + } + +} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs b/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs new file mode 100644 index 00000000..fabf1500 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs @@ -0,0 +1,108 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// Website: http://www.freesql.net +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; + +namespace ZX.Model { + + [JsonObject(MemberSerialization.OptIn)] + public class CustomerMember { + public CustomerMember() + { + CheckupGroups = new List(); + } + + [JsonProperty, Column(DbType = "nvarchar(50)", IsPrimary = true)] + public string MemberId { get; set; } + + [JsonProperty, Column(IsPrimary = true)] + public short ShopId { get; set; } + + [JsonProperty] + public long? CustomerId { get => _CustomerId; set { + if (_CustomerId == value) return; + _CustomerId = value; + } } + private long? _CustomerId; + + [JsonProperty, Column(DbType = "varchar(500)")] + public string Address { get; set; } + + [JsonProperty, Column(DbType = "smalldatetime")] + public DateTime? Birthday { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string CardNo { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string CardType { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Doctor { get; set; } + + [JsonProperty] + public DateTime? EndDate { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Group { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Marry { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Name { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Part { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string PayType { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Phone { get; set; } + + [JsonProperty, Column(DbType = "varchar(10)")] + public string Sex { get; set; } + + [JsonProperty] + public DateTime? StartDate { get; set; } + + [JsonProperty, Column(DbType = "text")] + public string Suggest { get; set; } + + [JsonProperty, Column(DbType = "text")] + public string SumUp { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Team { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? TotalFee { get; set; } + + + #region 外键 => 导航属性,ManyToOne/OneToOne + + [Navigate("MemberId,ShopId")] + public virtual List CheckupGroups { get; set; } + + #endregion + + #region 外键 => 导航属性,ManyToMany + + #endregion + } + +} diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 4a011e01..858210f7 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -296,6 +296,14 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var teklksjdg = g.sqlite.Select() + .Where(a => true && a.CustomerMember.Group == "xxx") + .ToSql(); + + var sklgjlskdg = g.sqlite.Select() + .Where(a => a.CheckupGroups.AsSelect().Any()) + .ToSql(); + var tkdkdksql = g.sqlite.Select().From((a, b, c) => a.LeftJoin(aa => aa.TemplatesId == b.Id2 && b.Code == "xx") .LeftJoin(aa => aa.TemplatesId == c.Id2)) diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 5ef4f348..f5ebe4dc 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 5566635b..44fcb327 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -327,16 +327,7 @@ namespace FreeSql.Internal if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; if (isBool) - { - switch (sql) - { - case "1": - case "'t'": return "1=1"; - case "0": - case "'f'": return "1=2"; - default: return sql; - } - } + return GetBoolString(sql); return sql; } @@ -347,16 +338,7 @@ namespace FreeSql.Internal if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; if (isBool) - { - switch (sql) - { - case "1": - case "'t'": return "1=1"; - case "0": - case "'f'": return "1=2"; - default: return sql; - } - } + return GetBoolString(sql); return sql; } public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString) @@ -367,16 +349,8 @@ namespace FreeSql.Internal if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) sql = $"{sql} = {formatSql(true, null)}"; if (isBool) - { - switch (sql) - { - case "1": - case "'t'": sql = "1=1"; break; - case "0": - case "'f'": sql = "1=2"; break; - default: break; - } - } + sql = GetBoolString(sql); + if (_tables.Count > tbidx) { _tables[tbidx].Type = tbtype; @@ -403,6 +377,17 @@ namespace FreeSql.Internal static MethodInfo MethodDateTimeSubtractDateTime = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(DateTime) }); static MethodInfo MethodDateTimeSubtractTimeSpan = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(TimeSpan) }); + static string GetBoolString(string sql) + { + switch (sql) + { + case "1": + case "'t'": return "1=1"; + case "0": + case "'f'": return "1=2"; + default: return sql; + } + } public string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) { switch (oper) @@ -483,7 +468,15 @@ namespace FreeSql.Internal left = tmp; } if (right == "NULL") oper = oper == "=" ? " IS " : " IS NOT "; - if (oper == "%") return _common.Mod(left, right, leftExp.Type, rightExp.Type); + switch(oper) + { + case "%": return _common.Mod(left, right, leftExp.Type, rightExp.Type); + case "AND": + case "OR": + left = GetBoolString(left); + right = GetBoolString(right); + break; + } tsc.mapType = null; return $"{left} {oper} {right}"; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 8f3ee4cb..6fc8eb7a 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -568,6 +568,19 @@ namespace FreeSql.Internal trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; } + if (trytb.Primarys.Length > 1) + { + if (trytb.Primarys.Select(a => a.CsType).Distinct().Count() == trytb.Primarys.Length) + { + var pkList = trytb.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType))); + } + else if (string.Compare(string.Join(",", trytb.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) + { + var pkList = trytb.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => string.Compare(c.CsName, a.CsName, true) == 0).CompareTo(pkList.FindIndex(c => string.Compare(c.CsName, b.CsName, true) == 0))); + } + } for (var a = 0; nvref.Exception == null && a < trytb.Primarys.Length; a++) { var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); @@ -705,6 +718,19 @@ namespace FreeSql.Internal trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; } + if (tbref.Primarys.Length > 1) + { + if (tbref.Primarys.Select(a => a.CsType).Distinct().Count() == tbref.Primarys.Length) + { + var pkList = tbref.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType))); + } + else if (string.Compare(string.Join(",", tbref.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) + { + var pkList = tbref.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => string.Compare(c.CsName, a.CsName, true) == 0).CompareTo(pkList.FindIndex(c => string.Compare(c.CsName, b.CsName, true) == 0))); + } + } for (var a = 0; nvref.Exception == null && a < tbref.Primarys.Length; a++) { var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 18eb5909..44ffbd57 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0a3fd69b..07ee9fc6 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 119e72f9..379531f7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1070d36e..83927cbf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 089db883..1bb32c90 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5dda69b3..d7328e69 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 272e55ecbfe104006c6c7f1df1da3e6fc754d774 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 9 Jul 2019 10:49:37 +0800 Subject: [PATCH 0038/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20Oracle=20DbF?= =?UTF-8?q?irst=20raw=20=E7=AD=89=E7=B1=BB=E5=9E=8B=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=8C=E5=85=B6=E4=BB=96=E6=9C=AA=E5=A4=84?= =?UTF-8?q?=E7=90=86=E7=9A=84=E7=B1=BB=E5=9E=8B=E5=B0=86=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E4=B8=BA=20string=EF=BC=9B#70?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/Oracle/OracleDbFirstTest.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 21 ++++++++++++++++++- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 12 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 90b5313a..2912e3ea 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 548e045c..90f2f59f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 2c3d3f9a..3a709873 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.6 + 0.7.7 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs index 841ef36b..53bd72fb 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs @@ -19,7 +19,7 @@ namespace FreeSql.Tests.Oracle { var t2 = g.oracle.DbFirst.GetTablesByDatabase(); - + //var tb = g.oracle.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f5ebe4dc..2f028eb2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 44ffbd57..161e58bf 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 07ee9fc6..2cbf60e4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 379531f7..a5224839 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 4a3cf4e1..0a0a1a14 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -83,14 +83,33 @@ namespace FreeSql.Oracle _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); return OracleDbType.Varchar2; case "char": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["char(36 char)"]); + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); return OracleDbType.Char; + case "nchar": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OracleDbType.NChar; case "clob": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); return OracleDbType.Clob; case "nclob": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); return OracleDbType.NClob; + case "raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OracleDbType.Raw; + case "long raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OracleDbType.LongRaw; + case "binary_float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]); + return OracleDbType.BinaryFloat; + case "binary_double": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return OracleDbType.BinaryDouble; + case "rowid": + default: + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OracleDbType.NVarchar2; } throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 83927cbf..24a64f94 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 1bb32c90..0b961858 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index d7328e69..e1970201 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.6 + 0.7.7 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 87c9ccf5c335ed611170f68e2bb8a4d531ce3d27 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 9 Jul 2019 16:46:11 +0800 Subject: [PATCH 0039/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E5=AD=90?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=87=BD=E6=95=B0=20First=E3=80=81Count?= =?UTF-8?q?=E3=80=81Min=E3=80=81Max=E3=80=81Sum=E3=80=81Avg=20=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 51 +++ .../MySql/Curd/MySqlSelectTest.cs | 51 +++ .../Oracle/Curd/OracleSelectTest.cs | 51 +++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 51 +++ .../SqlServer/Curd/SqlServerSelectTest.cs | 51 +++ .../Sqlite/Curd/SqliteSelectTest.cs | 51 +++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 17 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 420 ++++++++++-------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 558 insertions(+), 205 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 2912e3ea..f030d113 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 90f2f59f..98c92e77 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3a709873..c7ec9b73 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.7 + 0.7.8 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index ef2bda75..6e4180c8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -336,6 +336,17 @@ namespace FreeSql.Tests.MySqlConnector select.Where(a => 1 == 1).Count(out var count2); Assert.Equal(count, count2); Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); } [Fact] public void Master() @@ -870,18 +881,58 @@ namespace FreeSql.Tests.MySqlConnector [Fact] public void Sum() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); } [Fact] public void Min() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); } [Fact] public void Max() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); } [Fact] public void Avg() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); } [Fact] public void As() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 05d89b37..a6006fdb 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -326,6 +326,17 @@ namespace FreeSql.Tests.MySql select.Where(a => 1 == 1).Count(out var count2); Assert.Equal(count, count2); Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); } [Fact] public void Master() @@ -860,18 +871,58 @@ namespace FreeSql.Tests.MySql [Fact] public void Sum() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); } [Fact] public void Min() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); } [Fact] public void Max() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); } [Fact] public void Avg() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); } [Fact] public void As() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index cafc9e54..a0a7a1a1 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -212,6 +212,17 @@ namespace FreeSql.Tests.Oracle select.Where(a => 1 == 1).Count(out var count2); Assert.Equal(count, count2); Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); } [Fact] public void Master() @@ -744,18 +755,58 @@ namespace FreeSql.Tests.Oracle [Fact] public void Sum() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); } [Fact] public void Min() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); } [Fact] public void Max() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); } [Fact] public void Avg() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); } [Fact] public void As() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index a6bc17c1..42ff5ad9 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -289,6 +289,17 @@ namespace FreeSql.Tests.PostgreSQL select.Where(a => 1 == 1).Count(out var count2); Assert.Equal(count, count2); Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); } [Fact] public void Master() @@ -818,18 +829,58 @@ namespace FreeSql.Tests.PostgreSQL [Fact] public void Sum() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); } [Fact] public void Min() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); } [Fact] public void Max() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); } [Fact] public void Avg() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); } [Fact] public void As() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 09f7855a..622fa1c6 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -213,6 +213,17 @@ namespace FreeSql.Tests.SqlServer select.Where(a => 1 == 1).Count(out var count2); Assert.Equal(count, count2); Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); } [Fact] public void Master() @@ -741,18 +752,58 @@ namespace FreeSql.Tests.SqlServer [Fact] public void Sum() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); } [Fact] public void Min() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); } [Fact] public void Max() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); } [Fact] public void Avg() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); } [Fact] public void As() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index c943800d..debdb67b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -224,6 +224,17 @@ namespace FreeSql.Tests.Sqlite select.Where(a => 1 == 1).Count(out var count2); Assert.Equal(count, count2); Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); } [Fact] public void Master() @@ -691,18 +702,58 @@ namespace FreeSql.Tests.Sqlite [Fact] public void Sum() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); } [Fact] public void Min() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); } [Fact] public void Max() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); } [Fact] public void Avg() { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); } [Fact] public void As() diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 858210f7..c2450eac 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -296,9 +296,24 @@ namespace FreeSql.Tests [Fact] public void Test1() { + + var teklksjdg = g.sqlite.Select() .Where(a => true && a.CustomerMember.Group == "xxx") - .ToSql(); + .ToSql(a => new + { + all = a, + subquery = g.sqlite.Select().Where(b => b.Id == a.Id).First(b => b.Group) + }); + + var teklksjdg333 = g.sqlite.Select() + .Where(a => true && a.CustomerMember.Group == "xxx") + .OrderBy(a => g.sqlite.Select().Where(b => b.Id == a.Id).First(b => b.Group)) + .ToSql(a => new + { + all = a, + subquery = g.sqlite.Select().Where(b => b.Id == a.Id).First(b => b.Group) + }); var sklgjlskdg = g.sqlite.Select() .Where(a => a.CheckupGroups.AsSelect().Any()) diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2f028eb2..01607391 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 44fcb327..ac0d8c95 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -550,166 +550,222 @@ namespace FreeSql.Internal } if (callType.FullName.StartsWith("FreeSql.ISelect`")) { //子表查询 - if (exp3.Method.Name == "Any") - { //exists - var anyArgs = exp3.Arguments; - var exp3Stack = new Stack(); - var exp3tmp = exp3.Object; - if (exp3tmp != null && anyArgs.Any()) - exp3Stack.Push(Expression.Call(exp3tmp, callType.GetMethod("Where", anyArgs.Select(a => a.Type).ToArray()), anyArgs.ToArray())); - while (exp3tmp != null) - { - exp3Stack.Push(exp3tmp); - switch (exp3tmp.NodeType) + switch (exp3.Method.Name) + { + case "Any": //exists + case "Count": + case "Sum": + case "Min": + case "Max": + case "Avg": + case "First": + var anyArgs = exp3.Arguments; + var exp3Stack = new Stack(); + 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())); + while (exp3tmp != null) { - case ExpressionType.Call: - var exp3tmpCall = (exp3tmp as MethodCallExpression); - exp3tmp = exp3tmpCall.Object == null ? exp3tmpCall.Arguments.FirstOrDefault() : exp3tmpCall.Object; - continue; - case ExpressionType.MemberAccess: exp3tmp = (exp3tmp as MemberExpression).Expression; continue; - } - break; - } - object fsql = null; - List fsqltables = null; - var fsqltable1SetAlias = false; - Type fsqlType = null; - Stack asSelectBefores = new Stack(); - var asSelectSql = ""; - Type asSelectEntityType = null; - MemberExpression asSelectParentExp1 = null; - Expression asSelectParentExp = null; - while (exp3Stack.Any()) - { - exp3tmp = exp3Stack.Pop(); - if (exp3tmp.Type.FullName.StartsWith("FreeSql.ISelect`") && fsql == null) - { - if (exp3tmp.NodeType == ExpressionType.Call) + exp3Stack.Push(exp3tmp); + switch (exp3tmp.NodeType) { - var exp3tmpCall = (exp3tmp as MethodCallExpression); - if (exp3tmpCall.Method.Name == "AsSelect" && exp3tmpCall.Object == null) + case ExpressionType.Call: + var exp3tmpCall = (exp3tmp as MethodCallExpression); + exp3tmp = exp3tmpCall.Object == null ? exp3tmpCall.Arguments.FirstOrDefault() : exp3tmpCall.Object; + continue; + case ExpressionType.MemberAccess: exp3tmp = (exp3tmp as MemberExpression).Expression; continue; + } + break; + } + object fsql = null; + List fsqltables = null; + var fsqltable1SetAlias = false; + Type fsqlType = null; + Stack asSelectBefores = new Stack(); + var asSelectSql = ""; + Type asSelectEntityType = null; + MemberExpression asSelectParentExp1 = null; + Expression asSelectParentExp = null; + while (exp3Stack.Any()) + { + exp3tmp = exp3Stack.Pop(); + if (exp3tmp.Type.FullName.StartsWith("FreeSql.ISelect`") && fsql == null) + { + if (exp3tmp.NodeType == ExpressionType.Call) { - var exp3tmpArg1Type = exp3tmpCall.Arguments.FirstOrDefault()?.Type; - if (exp3tmpArg1Type != null) + var exp3tmpCall = (exp3tmp as MethodCallExpression); + if (exp3tmpCall.Method.Name == "AsSelect" && exp3tmpCall.Object == null) { - asSelectEntityType = exp3tmpArg1Type.GetElementType() ?? exp3tmpArg1Type.GenericTypeArguments.FirstOrDefault(); - if (asSelectEntityType != null) + var exp3tmpArg1Type = exp3tmpCall.Arguments.FirstOrDefault()?.Type; + if (exp3tmpArg1Type != null) { - fsql = _dicExpressionLambdaToSqlAsSelectMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType2 => typeof(IFreeSql).GetMethod("Select", new Type[0]).MakeGenericMethod(asSelectEntityType2)) - .Invoke(_common._orm, null); - - if (asSelectBefores.Any()) + asSelectEntityType = exp3tmpArg1Type.GetElementType() ?? exp3tmpArg1Type.GenericTypeArguments.FirstOrDefault(); + if (asSelectEntityType != null) { - asSelectParentExp1 = asSelectBefores.Pop() as MemberExpression; + fsql = _dicExpressionLambdaToSqlAsSelectMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType2 => typeof(IFreeSql).GetMethod("Select", new Type[0]).MakeGenericMethod(asSelectEntityType2)) + .Invoke(_common._orm, null); + if (asSelectBefores.Any()) { - asSelectParentExp = asSelectBefores.Pop(); - if (asSelectParentExp != null) + asSelectParentExp1 = asSelectBefores.Pop() as MemberExpression; + if (asSelectBefores.Any()) { - var testExecuteExp = asSelectParentExp; - if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联 - testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key); - var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List(), tsc.getSelectGroupingMapString, SelectTableInfoType.LeftJoin); - tsc2.isDisableDiyParse = true; - tsc2.style = ExpressionStyle.AsSelect; - asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2); + asSelectParentExp = asSelectBefores.Pop(); + if (asSelectParentExp != null) + { + var testExecuteExp = asSelectParentExp; + if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联 + testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key); + var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List(), tsc.getSelectGroupingMapString, SelectTableInfoType.LeftJoin); + tsc2.isDisableDiyParse = true; + tsc2.style = ExpressionStyle.AsSelect; + asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2); + } } } } } } } - } - if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke(); - fsqlType = fsql?.GetType(); - if (fsqlType == null) break; - fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); - fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; - //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; - fsqltables.AddRange(tsc._tables.Select(a => new SelectTableInfo - { - Alias = a.Alias, - On = "1=1", - Table = a.Table, - Type = SelectTableInfoType.Parent, - Parameter = a.Parameter - })); - } - else if (fsqlType != null) - { - var call3Exp = exp3tmp as MethodCallExpression; - var method = fsqlType.GetMethod(call3Exp.Method.Name, call3Exp.Arguments.Select(a => a.Type).ToArray()); - if (call3Exp.Method.ContainsGenericParameters) method.MakeGenericMethod(call3Exp.Method.GetGenericArguments()); - var parms = method.GetParameters(); - var args = new object[call3Exp.Arguments.Count]; - for (var a = 0; a < args.Length; a++) - { - var arg3Exp = call3Exp.Arguments[a]; - if (arg3Exp.NodeType == ExpressionType.Constant) + if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke(); + fsqlType = fsql?.GetType(); + if (fsqlType == null) break; + fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); + fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; + //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; + fsqltables.AddRange(tsc._tables.Select(a => new SelectTableInfo { - args[a] = (arg3Exp as ConstantExpression)?.Value; - } - else - { - var argExp = (arg3Exp as UnaryExpression)?.Operand; - if (argExp != null && argExp.NodeType == ExpressionType.Lambda) - { - if (fsqltable1SetAlias == false) - { - fsqltables[0].Alias = (argExp as LambdaExpression).Parameters.First().Name; - fsqltable1SetAlias = true; - } - } - args[a] = argExp ?? Expression.Lambda(arg3Exp).Compile().DynamicInvoke(); - //if (args[a] == null) ExpressionLambdaToSql(call3Exp.Arguments[a], fsqltables, null, null, SelectTableInfoType.From, true); - } - } - method.Invoke(fsql, args); - } - if (fsql == null) asSelectBefores.Push(exp3tmp); - } - if (fsql != null) - { - if (asSelectParentExp != null) - { //执行 asSelect() 的关联,OneToMany,ManyToMany - if (fsqltables[0].Parameter == null) - { - fsqltables[0].Alias = $"tb_{fsqltables.Count}"; - fsqltables[0].Parameter = Expression.Parameter(asSelectEntityType, fsqltables[0].Alias); - } - var fsqlWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType3 => - typeof(ISelect<>).MakeGenericType(asSelectEntityType3).GetMethod("Where", new[] { - typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool))) - })); - var parm123Tb = _common.GetTableByEntity(asSelectParentExp.Type); - var parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true); - var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType); - Expression fsqlWhereExp = null; - if (parm123Ref.RefType == TableRefType.ManyToMany) - { - //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); - var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType); - var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] { - typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool))) + Alias = a.Alias, + On = "1=1", + Table = a.Table, + Type = SelectTableInfoType.Parent, + Parameter = a.Parameter })); - var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); - var manySubSelectAny = _dicExpressionLambdaToSqlAsSelectAnyMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Any", new Type[0])); - var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - Expression.Call( - typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3), - Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3))) - )); - var manyMainParam = tsc._tables[0].Parameter; - var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__"); - Expression manySubSelectWhereExp = null; + } + else if (fsqlType != null) + { + var call3Exp = exp3tmp as MethodCallExpression; + var method = fsqlType.GetMethod(call3Exp.Method.Name, call3Exp.Arguments.Select(a => a.Type).ToArray()); + if (call3Exp.Method.ContainsGenericParameters) method.MakeGenericMethod(call3Exp.Method.GetGenericArguments()); + var parms = method.GetParameters(); + var args = new object[call3Exp.Arguments.Count]; + for (var a = 0; a < args.Length; a++) + { + var arg3Exp = call3Exp.Arguments[a]; + if (arg3Exp.NodeType == ExpressionType.Constant) + { + args[a] = (arg3Exp as ConstantExpression)?.Value; + } + else + { + var argExp = (arg3Exp as UnaryExpression)?.Operand; + if (argExp != null && argExp.NodeType == ExpressionType.Lambda) + { + if (fsqltable1SetAlias == false) + { + fsqltables[0].Alias = (argExp as LambdaExpression).Parameters.First().Name; + fsqltable1SetAlias = true; + } + } + args[a] = argExp ?? Expression.Lambda(arg3Exp).Compile().DynamicInvoke(); + //if (args[a] == null) ExpressionLambdaToSql(call3Exp.Arguments[a], fsqltables, null, null, SelectTableInfoType.From, true); + } + } + method.Invoke(fsql, args); + } + if (fsql == null) asSelectBefores.Push(exp3tmp); + } + if (fsql != null) + { + if (asSelectParentExp != null) + { //执行 asSelect() 的关联,OneToMany,ManyToMany + if (fsqltables[0].Parameter == null) + { + fsqltables[0].Alias = $"tb_{fsqltables.Count}"; + fsqltables[0].Parameter = Expression.Parameter(asSelectEntityType, fsqltables[0].Alias); + } + var fsqlWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType3 => + typeof(ISelect<>).MakeGenericType(asSelectEntityType3).GetMethod("Where", new[] { + typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool))) + })); + var parm123Tb = _common.GetTableByEntity(asSelectParentExp.Type); + var parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true); + var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType); + Expression fsqlWhereExp = null; + if (parm123Ref.RefType == TableRefType.ManyToMany) + { + //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); + var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType); + var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] { + typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool))) + })); + var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); + var manySubSelectAny = _dicExpressionLambdaToSqlAsSelectAnyMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Any", new Type[0])); + var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + Expression.Call( + typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3), + Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3))) + )); + var manyMainParam = tsc._tables[0].Parameter; + var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__"); + Expression manySubSelectWhereExp = null; + for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) + { + var col1 = parm123Ref.MiddleColumns[mn]; + var col2 = parm123Ref.Columns[mn]; + var pexp1 = Expression.Property(manySubSelectWhereParam, col1.CsName); + var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); + if (col1.CsType != col2.CsType) + { + if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); + if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); + } + var tmpExp = Expression.Equal(pexp1, pexp2); + if (mn == 0) manySubSelectWhereExp = tmpExp; + else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp); + } + var manySubSelectExpBoy = Expression.Call( + manySubSelectAsSelectExp, + manySubSelectWhere, + Expression.Lambda( + manySubSelectWhereExp, + manySubSelectWhereParam + ) + ); + Expression fsqlManyWhereExp = null; + for (var mn = 0; mn < parm123Ref.RefColumns.Count; mn++) + { + var col1 = parm123Ref.RefColumns[mn]; + var col2 = parm123Ref.MiddleColumns[mn + parm123Ref.Columns.Count + mn]; + var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); + var pexp2 = Expression.Property(manySubSelectWhereParam, col2.CsName); + if (col1.CsType != col2.CsType) + { + if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); + if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); + } + var tmpExp = Expression.Equal(pexp1, pexp2); + if (mn == 0) fsqlManyWhereExp = tmpExp; + else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp); + } + fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent }); + fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); + var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); + if (string.IsNullOrEmpty(sql2) == false) + manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace("\r\n", "\r\n\t")})"), Expression.Constant(null)); + manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAny); + asSelectBefores.Clear(); + + return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); + } for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) { - var col1 = parm123Ref.MiddleColumns[mn]; + var col1 = parm123Ref.RefColumns[mn]; var col2 = parm123Ref.Columns[mn]; - var pexp1 = Expression.Property(manySubSelectWhereParam, col1.CsName); + var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); if (col1.CsType != col2.CsType) { @@ -717,66 +773,42 @@ namespace FreeSql.Internal if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); } var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) manySubSelectWhereExp = tmpExp; - else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp); + if (mn == 0) fsqlWhereExp = tmpExp; + else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp); } - var manySubSelectExpBoy = Expression.Call( - manySubSelectAsSelectExp, - manySubSelectWhere, - Expression.Lambda( - manySubSelectWhereExp, - manySubSelectWhereParam - ) - ); - Expression fsqlManyWhereExp = null; - for (var mn = 0; mn < parm123Ref.RefColumns.Count; mn++) - { - var col1 = parm123Ref.RefColumns[mn]; - var col2 = parm123Ref.MiddleColumns[mn + parm123Ref.Columns.Count + mn]; - var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); - var pexp2 = Expression.Property(manySubSelectWhereParam, col2.CsName); - if (col1.CsType != col2.CsType) - { - if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); - if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); - } - var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) fsqlManyWhereExp = tmpExp; - else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp); - } - fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent }); - fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); - var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); - if (string.IsNullOrEmpty(sql2) == false) - manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace("\r\n", "\r\n\t")})"), Expression.Constant(null)); - manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAny); - asSelectBefores.Clear(); + fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) }); + } + asSelectBefores.Clear(); - return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); - } - for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) + switch (exp3.Method.Name) { - var col1 = parm123Ref.RefColumns[mn]; - var col2 = parm123Ref.Columns[mn]; - var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); - var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); - if (col1.CsType != col2.CsType) - { - if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); - if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); - } - var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) fsqlWhereExp = tmpExp; - else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp); + case "Any": + var sql = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); + if (string.IsNullOrEmpty(sql) == false) + return $"exists({sql.Replace("\r\n", "\r\n\t")})"; + break; + case "Count": + var sqlCount = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "count(1)" })?.ToString(); + if (string.IsNullOrEmpty(sqlCount) == false) + return $"({sqlCount.Replace("\r\n", "\r\n\t")})"; + break; + case "Sum": + case "Min": + case "Max": + case "Avg": + var sqlSum = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tsc)})" })?.ToString(); + if (string.IsNullOrEmpty(sqlSum) == false) + return $"({sqlSum.Replace("\r\n", "\r\n\t")})"; + break; + case "First": + var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tsc) })?.ToString(); + if (string.IsNullOrEmpty(sqlFirst) == false) + return $"({sqlFirst.Replace("\r\n", "\r\n\t")})"; + break; } - fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) }); } asSelectBefores.Clear(); - var sql = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); - if (string.IsNullOrEmpty(sql) == false) - return $"exists({sql.Replace("\r\n", "\r\n\t")})"; - } - asSelectBefores.Clear(); + break; } } //var eleType = callType.GetElementType() ?? callType.GenericTypeArguments.FirstOrDefault(); diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 161e58bf..358dca55 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 2cbf60e4..1deab0d1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a5224839..64c33afb 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 24a64f94..fb69e0c4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0b961858..383bd572 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e1970201..f0cae953 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.7 + 0.7.8 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 42aa700b443f92e759a0740590c6e1f5a8095893 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 10 Jul 2019 16:12:49 +0800 Subject: [PATCH 0040/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20LambadaExpre?= =?UTF-8?q?ssionExtensions=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=20And/Or?= =?UTF-8?q?=20=E5=BD=93=E5=AD=98=E5=9C=A8=E4=BA=8C=E7=BA=A7=20lambada=20?= =?UTF-8?q?=E6=97=B6=E6=9B=BF=E6=8D=A2=E9=94=99=E8=AF=AF=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B=20>=20=E5=A6=82=EF=BC=9Awhere.Add(a=20=3D>=20a.Tags.A?= =?UTF-8?q?ny(b=20=3D>=20...))=EF=BC=8Cb=20=E6=9B=BF=E6=8D=A2=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/LambadaExpressionExtensions.cs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index ff8e9b89..9ad328ee 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -34,7 +34,7 @@ namespace System.Linq.Expressions if (exp2 == null) return exp1; ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); - NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); + NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter, exp2.Parameters.FirstOrDefault()); var left = visitor.Replace(exp1.Body); var right = visitor.Replace(exp2.Body); @@ -62,7 +62,7 @@ namespace System.Linq.Expressions if (exp2 == null) return exp1; ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); - NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter); + NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter, exp2.Parameters.FirstOrDefault()); var left = visitor.Replace(exp1.Body); var right = visitor.Replace(exp2.Body); @@ -90,18 +90,16 @@ namespace System.Linq.Expressions internal class NewExpressionVisitor : ExpressionVisitor { - public ParameterExpression _newParameter { get; private set; } - public NewExpressionVisitor(ParameterExpression param) + ParameterExpression _newParameter; + ParameterExpression _oldParameter; + public NewExpressionVisitor(ParameterExpression newParam, ParameterExpression oldParam) { - this._newParameter = param; - } - public Expression Replace(Expression exp) - { - return this.Visit(exp); - } - protected override Expression VisitParameter(ParameterExpression node) - { - return this._newParameter; + this._newParameter = newParam; + this._oldParameter = oldParam; } + public Expression Replace(Expression exp) => this.Visit(exp); + + protected override Expression VisitParameter(ParameterExpression node) => + node == _oldParameter ? this._newParameter : node; } } \ No newline at end of file From 179b7d9851e59dcfd64fc21e52dc55de23b223d0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 12 Jul 2019 15:11:20 +0800 Subject: [PATCH 0041/1029] =?UTF-8?q?=E6=99=AE=E9=80=9A=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.MySqlConnector.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 1deab0d1..6e2a2afe 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -23,7 +23,6 @@ - From b62afec7bb170b7b5a0aa054d62a0d8252baaa3f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 15 Jul 2019 18:10:59 +0800 Subject: [PATCH 0042/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20Navigate(Man?= =?UTF-8?q?yToMany=20=3D=20typeof(=E4=B8=AD=E9=97=B4=E8=A1=A8))=20?= =?UTF-8?q?=E5=A4=9A=E5=AF=B9=E5=A4=9A=E8=87=AA=E5=AE=9A=E4=B9=89=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../Navigate/ManyToManyTest.cs | 252 ++++++++++++ .../DataAnnotations/Navigate/ManyToOneTest.cs | 141 +++++++ .../DataAnnotations/Navigate/OneToManyTest.cs | 138 +++++++ .../DataAnnotations/Navigate/OneToOneTest.cs | 60 +++ FreeSql/DataAnnotations/NavigateAttribute.cs | 9 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 7 +- .../SelectProvider/Select1Provider.cs | 2 - FreeSql/Internal/UtilsExpressionTree.cs | 376 +++++++++++------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 841 insertions(+), 164 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/ManyToManyTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/ManyToOneTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/OneToManyTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/OneToOneTest.cs diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index f030d113..b5919bdc 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 98c92e77..249cb8ff 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c7ec9b73..11d8c3c7 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.8 + 0.7.9 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/ManyToManyTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/ManyToManyTest.cs new file mode 100644 index 00000000..6d55f1c0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/ManyToManyTest.cs @@ -0,0 +1,252 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.DataAnnotations +{ + public class ManyToManyTest + { + Random rnd = new Random(); + + #region ԼԶ + [Fact] + public void Select() + { + var users = new mtm_user[10]; + var roles = new mtm_role[10]; + var urs = new List(); + for (var a = 0; a < users.Length; a++) + { + var uid = Guid.NewGuid(); + users[a] = new mtm_user + { + id = uid, + username = "û" + a + "_" + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(users).ExecuteAffrows(); + for (var a = 0; a < roles.Length; a++) + { + var uid = Guid.NewGuid(); + roles[a] = new mtm_role + { + id = uid, + name = "ɫ" + a + "_" + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(roles).ExecuteAffrows(); + + for (var a = 0; a < users.Length; a++) + { + for (var b = roles.Length; b >= 0; b--) + { + var ur = new mtm_user_mtm_role + { + mtm_user_id = users[a].id, + mtm_role_id = roles[rnd.Next(roles.Length)].id + }; + if (urs.Where(c => c.mtm_role_id == ur.mtm_role_id && c.mtm_user_id == ur.mtm_user_id).Any() == false) + urs.Add(ur); + } + } + g.sqlite.Insert(urs.ToArray()).ExecuteAffrows(); + + var select1 = g.sqlite.Select().Limit(10).OrderByDescending(a => a.createtime).ToList(true); + + var select2 = g.sqlite.Select().IncludeMany(a => a.mtm_roles).Limit(10).OrderByDescending(a => a.createtime).ToList(true); + } + + public class mtm_user + { + public Guid id { get; set; } + public string username { get; set; } + public DateTime createtime { get; set; } + + public virtual List mtm_roles { get; set; } + } + public class mtm_user_mtm_role + { + public Guid mtm_user_id { get; set; } + public Guid mtm_role_id { get; set; } + + public mtm_user mtm_user { get; set; } + public mtm_role mtm_role { get; set; } + } + public class mtm_role + { + public Guid id { get; set; } + + public string name { get; set; } + public DateTime createtime { get; set; } + + public virtual List mtm_users { get; set; } + } + #endregion + + #region ԶԶ࣬мΪԼ + [Fact] + public void Navigate1() + { + var users = new mtm_user_nav1[10]; + var roles = new mtm_role_nav1[10]; + var urs = new List(); + for (var a = 0; a < users.Length; a++) + { + var uid = Guid.NewGuid(); + users[a] = new mtm_user_nav1 + { + id = uid, + username = "û" + a + "_" + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(users).ExecuteAffrows(); + for (var a = 0; a < roles.Length; a++) + { + var uid = Guid.NewGuid(); + roles[a] = new mtm_role_nav1 + { + id = uid, + name = "ɫ" + a + "_" + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(roles).ExecuteAffrows(); + + for (var a = 0; a < users.Length; a++) + { + for (var b = roles.Length; b >= 0; b--) + { + var ur = new user_role_nav1 + { + user_id = users[a].id, + role_id = roles[rnd.Next(roles.Length)].id + }; + if (urs.Where(c => c.role_id == ur.role_id && c.user_id == ur.user_id).Any() == false) + urs.Add(ur); + } + } + g.sqlite.Insert(urs.ToArray()).ExecuteAffrows(); + + var select1 = g.sqlite.Select().Limit(10).OrderByDescending(a => a.createtime).ToList(true); + + var select2 = g.sqlite.Select().IncludeMany(a => a.roles).Limit(10).OrderByDescending(a => a.createtime).ToList(true); + } + + public class mtm_user_nav1 + { + public Guid id { get; set; } + public string username { get; set; } + public DateTime createtime { get; set; } + + [Navigate(ManyToMany = typeof(user_role_nav1))] + public virtual List roles { get; set; } + } + public class user_role_nav1 + { + public Guid user_id { get; set; } + public Guid role_id { get; set; } + + public mtm_user_nav1 user { get; set; } + public mtm_role_nav1 role { get; set; } + } + public class mtm_role_nav1 + { + public Guid id { get; set; } + + public string name { get; set; } + public DateTime createtime { get; set; } + + [Navigate(ManyToMany = typeof(user_role_nav1))] + public virtual List users { get; set; } + } + #endregion + + #region ԶԶ࣬мΪԶ + [Fact] + public void Navigate() + { + var users = new mtm_user_nav[10]; + var roles = new mtm_role_nav[10]; + var urs = new List(); + for (var a = 0; a < users.Length; a++) + { + var uid = Guid.NewGuid(); + users[a] = new mtm_user_nav + { + id = uid, + username = "û" + a + "_" + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(users).ExecuteAffrows(); + for (var a = 0; a < roles.Length; a++) + { + var uid = Guid.NewGuid(); + roles[a] = new mtm_role_nav + { + id = uid, + name = "ɫ" + a + "_" + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(roles).ExecuteAffrows(); + + for (var a = 0; a < users.Length; a++) + { + for (var b = roles.Length; b >= 0; b--) + { + var ur = new user_role_nav + { + user_pkid = users[a].id, + role_pkid = roles[rnd.Next(roles.Length)].id + }; + if (urs.Where(c => c.role_pkid == ur.role_pkid && c.user_pkid == ur.user_pkid).Any() == false) + urs.Add(ur); + } + } + g.sqlite.Insert(urs.ToArray()).ExecuteAffrows(); + + var select1 = g.sqlite.Select().Limit(10).OrderByDescending(a => a.createtime).ToList(true); + + var select2 = g.sqlite.Select().IncludeMany(a => a.roles).Limit(10).OrderByDescending(a => a.createtime).ToList(true); + } + + public class mtm_user_nav + { + public Guid id { get; set; } + public string username { get; set; } + public DateTime createtime { get; set; } + + [Navigate(ManyToMany = typeof(user_role_nav))] + public virtual List roles { get; set; } + } + public class user_role_nav + { + public Guid user_pkid { get; set; } + public Guid role_pkid { get; set; } + + [Navigate("user_pkid")] + public mtm_user_nav user { get; set; } + [Navigate("role_pkid")] + public mtm_role_nav role { get; set; } + } + public class mtm_role_nav + { + public Guid id { get; set; } + + public string name { get; set; } + public DateTime createtime { get; set; } + + [Navigate(ManyToMany = typeof(user_role_nav))] + public virtual List users { get; set; } + } + #endregion + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/ManyToOneTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/ManyToOneTest.cs new file mode 100644 index 00000000..dce116e9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/ManyToOneTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.DataAnnotations +{ + public class ManyToOneTest + { + #region Լһ + [Fact] + public void Select() + { + var users = new mto_user[10]; + var topics = new mto_topic[30]; + for (var a = 0; a < users.Length; a++) + { + var uid = Guid.NewGuid(); + users[a] = new mto_user + { + id = uid, + username = Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3] = new mto_topic + { + id = Guid.NewGuid(), + userid = uid, + title = "Ա" + (a * 3) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3 + 1] = new mto_topic + { + id = Guid.NewGuid(), + userid = uid, + title = "Ա" + (a * 3 + 1) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3 + 2] = new mto_topic + { + id = Guid.NewGuid(), + userid = uid, + title = "Ա" + (a * 3 + 2) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(users).ExecuteAffrows(); + g.sqlite.Insert(topics).ExecuteAffrows(); + + var select1 = g.sqlite.Select().Limit(30).OrderByDescending(a => a.createtime).ToList(true); + + var select2 = g.sqlite.Select().Include(a => a.user).Limit(30).OrderByDescending(a => a.createtime).ToList(true); + + var firstct = users[0].createtime.AddSeconds(-1); + var select3 = g.sqlite.Select().Where(a => a.user.createtime > firstct).Limit(30).OrderByDescending(a => a.createtime).ToList(true); + } + + public class mto_user + { + public Guid id { get; set; } + public string username { get; set; } + public DateTime createtime { get; set; } + } + public class mto_topic + { + public Guid id { get; set; } + public Guid userid { get; set; } + public virtual mto_user user { get; set; } + + public string title { get; set; } + public DateTime createtime { get; set; } + } + #endregion + + #region Զһ + [Fact] + public void Navigate() + { + var users = new mto_user_nav[10]; + var topics = new mto_topic_nav[30]; + for (var a = 0; a < users.Length; a++) + { + var uid = Guid.NewGuid(); + users[a] = new mto_user_nav + { + id = uid, + username = Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3] = new mto_topic_nav + { + id = Guid.NewGuid(), + user_nav_pkid = uid, + title = "Ա" + (a * 3) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3 + 1] = new mto_topic_nav + { + id = Guid.NewGuid(), + user_nav_pkid = uid, + title = "Ա" + (a * 3 + 1) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3 + 2] = new mto_topic_nav + { + id = Guid.NewGuid(), + user_nav_pkid = uid, + title = "Ա" + (a * 3 + 2) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(users).ExecuteAffrows(); + g.sqlite.Insert(topics).ExecuteAffrows(); + + var select1 = g.sqlite.Select().Limit(30).OrderByDescending(a => a.createtime).ToList(true); + + var select2 = g.sqlite.Select().Include(a => a.user).Limit(30).OrderByDescending(a => a.createtime).ToList(true); + + var firstct = users[0].createtime.AddSeconds(-1); + var select3 = g.sqlite.Select().Where(a => a.user.createtime > firstct).Limit(30).OrderByDescending(a => a.createtime).ToList(true); + } + + public class mto_user_nav + { + public Guid id { get; set; } + public string username { get; set; } + public DateTime createtime { get; set; } + } + public class mto_topic_nav + { + public Guid id { get; set; } + public Guid user_nav_pkid { get; set; } + [Navigate("user_nav_pkid")] + public virtual mto_user_nav user { get; set; } + + public string title { get; set; } + public DateTime createtime { get; set; } + } + #endregion + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/OneToManyTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/OneToManyTest.cs new file mode 100644 index 00000000..2597db78 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/OneToManyTest.cs @@ -0,0 +1,138 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.DataAnnotations +{ + public class OneToManyTest + { + #region ԼһԶ + [Fact] + public void Select() + { + var users = new mto_user[10]; + var topics = new mto_topic[30]; + for (var a = 0; a < users.Length; a++) + { + var uid = Guid.NewGuid(); + users[a] = new mto_user + { + id = uid, + username = Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3] = new mto_topic + { + id = Guid.NewGuid(), + mto_userid = uid, + title = "Ա" + (a * 3) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3 + 1] = new mto_topic + { + id = Guid.NewGuid(), + mto_userid = uid, + title = "Ա" + (a * 3 + 1) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3 + 2] = new mto_topic + { + id = Guid.NewGuid(), + mto_userid = uid, + title = "Ա" + (a * 3 + 2) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(users).ExecuteAffrows(); + g.sqlite.Insert(topics).ExecuteAffrows(); + + var select1 = g.sqlite.Select().Limit(10).OrderByDescending(a => a.createtime).ToList(true); + + var select2 = g.sqlite.Select().IncludeMany(a => a.mto_topics).Limit(10).OrderByDescending(a => a.createtime).ToList(true); + } + + public class mto_user + { + public Guid id { get; set; } + public string username { get; set; } + public DateTime createtime { get; set; } + + public virtual List mto_topics { get; set; } + } + public class mto_topic + { + public Guid id { get; set; } + public Guid mto_userid { get; set; } + + public string title { get; set; } + public DateTime createtime { get; set; } + } + #endregion + + #region ԶһԶ + [Fact] + public void Navigate() + { + var users = new otm_user_nav[10]; + var topics = new otm_topic_nav[30]; + for (var a = 0; a < users.Length; a++) + { + var uid = Guid.NewGuid(); + users[a] = new otm_user_nav + { + id = uid, + username = Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3] = new otm_topic_nav + { + id = Guid.NewGuid(), + user_nav_pkid = uid, + title = "Ա" + (a * 3) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3 + 1] = new otm_topic_nav + { + id = Guid.NewGuid(), + user_nav_pkid = uid, + title = "Ա" + (a * 3 + 1) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + topics[a * 3 + 2] = new otm_topic_nav + { + id = Guid.NewGuid(), + user_nav_pkid = uid, + title = "Ա" + (a * 3 + 2) + Guid.NewGuid().ToString("N"), + createtime = DateTime.Now + }; + } + g.sqlite.Insert(users).ExecuteAffrows(); + g.sqlite.Insert(topics).ExecuteAffrows(); + + var select1 = g.sqlite.Select().Limit(10).OrderByDescending(a => a.createtime).ToList(true); + + var select2 = g.sqlite.Select().IncludeMany(a => a.topics).Limit(10).OrderByDescending(a => a.createtime).ToList(true); + } + + public class otm_user_nav + { + public Guid id { get; set; } + public string username { get; set; } + public DateTime createtime { get; set; } + + [Navigate("user_nav_pkid")] + public virtual List topics { get; set; } + } + public class otm_topic_nav + { + public Guid id { get; set; } + public Guid user_nav_pkid { get; set; } + + public string title { get; set; } + public DateTime createtime { get; set; } + } + #endregion + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/OneToOneTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/OneToOneTest.cs new file mode 100644 index 00000000..83b855b0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/Navigate/OneToOneTest.cs @@ -0,0 +1,60 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.DataAnnotations +{ + public class OneToOneTest + { + [Fact] + public void Select() + { + var users = new oto_user[10]; + for (var a = 0; a < users.Length; a++) + { + var uid = Guid.NewGuid(); + users[a] = new oto_user + { + id = uid, + username = Guid.NewGuid().ToString("N"), + createtime = DateTime.Now, + ext = new oto_user_field + { + userid = uid, + age = a, + createtime = DateTime.Now + } + }; + } + g.sqlite.Insert(users).ExecuteAffrows(); + g.sqlite.Insert(users.Select(a => a.ext).ToArray()).ExecuteAffrows(); + + var select1 = g.sqlite.Select().Include(a => a.ext).Limit(10).OrderByDescending(a => a.createtime).ToList(true); + + var select2 = g.sqlite.Select().Limit(10).OrderByDescending(a => a.createtime).ToList(true); + + var select3 = g.sqlite.Select().Include(a => a.user).Limit(10).OrderByDescending(a => a.createtime).ToList(true); + } + + public class oto_user + { + public Guid id { get; set; } + public string username { get; set; } + public DateTime createtime { get; set; } + public oto_user_field ext { get; set; } + } + public class oto_user_field + { + [Column(IsPrimary = true)] + public Guid userid { get; set; } + public virtual oto_user user { get; set; } + + public int age { get; set; } + public DateTime createtime { get; set; } + } + } + +} diff --git a/FreeSql/DataAnnotations/NavigateAttribute.cs b/FreeSql/DataAnnotations/NavigateAttribute.cs index d908a627..f17b4348 100644 --- a/FreeSql/DataAnnotations/NavigateAttribute.cs +++ b/FreeSql/DataAnnotations/NavigateAttribute.cs @@ -7,13 +7,20 @@ namespace FreeSql.DataAnnotations { /// - /// 导航属性,手工绑定 + /// 手工绑定 OneToMany、ManyToOne 导航关系 /// public string Bind { get; set; } + /// + /// 手工绑定 ManyToMany 导航关系 + /// + public Type ManyToMany { get; set; } public NavigateAttribute(string bind) { this.Bind = bind; } + public NavigateAttribute() + { + } } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 01607391..cf80f4d7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b8babb01..6b0870ec 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -115,7 +115,12 @@ - 导航属性,手工绑定 + 手工绑定 OneToMany、ManyToOne 导航关系 + + + + + 手工绑定 ManyToMany 导航关系 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index aba152e5..49f0a87d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -902,9 +902,7 @@ namespace FreeSql.Internal.CommonProvider { string key = null; if (tbref.Columns.Count == 1) - { key = _orm.GetEntityValueWithPropertyName(tbref.RefMiddleEntityType, midList[a], tbref.MiddleColumns[0].CsName).ToString(); - } else { var sb = new StringBuilder(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6fc8eb7a..473a82bb 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -208,28 +208,22 @@ namespace FreeSql.Internal { if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.Attribute.MapType == dbident.CsType || trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.Attribute.MapType == dbident.CsType) - { trycol.Attribute.IsIdentity = true; - } } foreach (var dbpk in dbtb.Primarys) { if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.Attribute.MapType == dbpk.CsType || trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.Attribute.MapType == dbpk.CsType) - { trycol.Attribute.IsPrimary = true; - } } foreach (var dbuk in dbtb.UniquesDict) { foreach (var dbcol in dbuk.Value) { if (trytb.Columns.TryGetValue(dbcol.Name, out var trycol) && trycol.Attribute.MapType == dbcol.CsType || - trytb.ColumnsByCs.TryGetValue(dbcol.Name, out trycol) && trycol.Attribute.MapType == dbcol.CsType) - { + trytb.ColumnsByCs.TryGetValue(dbcol.Name, out trycol) && trycol.Attribute.MapType == dbcol.CsType) if (trycol.Attribute._Uniques?.Contains(dbuk.Key) != true) trycol.Attribute.Unique += $"," + dbuk.Key; - } } } } @@ -272,7 +266,8 @@ namespace FreeSql.Internal $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace}.{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace}.{a.Name}"))}>" : (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace}.{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name}"); - var pnvBind = pnv.GetCustomAttribute()?.Bind.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); + var pnvAttr = pnv.GetCustomAttribute(); + var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); var nvref = new TableRef(); nvref.Property = pnv; @@ -294,11 +289,47 @@ namespace FreeSql.Internal var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}"; Type midType = null; - var isManyToMany = propElementType != trytb.Type && - pnv.Name.EndsWith($"{tbref.CsName}s") && - tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && - z.Key.EndsWith($"{trytb.CsName}s", StringComparison.CurrentCultureIgnoreCase) && - typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); + var isManyToMany = false; + + Action valiManyToMany = () => + { + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + }; + + if (pnvAttr?.ManyToMany != null) + { + isManyToMany = propElementType != trytb.Type && + tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && + z.Value.GetCustomAttribute()?.ManyToMany == pnvAttr.ManyToMany && + typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); + + if (isManyToMany == false) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 必须存在对应的 [Navigate(ManyToMany = x)] 集合属性"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + continue; + } + if (isManyToMany) + { + midType = pnvAttr.ManyToMany; + valiManyToMany(); + } + } + else + { + isManyToMany = propElementType != trytb.Type && + pnv.Name.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase) && + tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && + z.Key.EndsWith($"{trytb.CsName}s", StringComparison.CurrentCultureIgnoreCase) && + typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); + } if (isManyToMany) { if (tbref.Primarys.Any() == false) @@ -308,116 +339,75 @@ namespace FreeSql.Internal //if (isLazy) throw nvref.Exception; continue; } + if (pnvAttr?.ManyToMany == null) + { + //中间表怎么查询,比如 Song、Tag、SongTag + var midFlagStr = string.Empty; + if (pnv.Name.Length >= tbref.CsName.Length - 1) + midFlagStr = pnv.Name.Remove(pnv.Name.Length - tbref.CsName.Length - 1); - //中间表怎么查询,比如 Song、Tag、SongTag - var midFlagStr = pnv.Name.Remove(pnv.Name.Length - tbref.CsName.Length - 1); + #region 在 trytb 命名空间下查找中间类 + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + valiManyToMany(); + } + #endregion - #region 在 trytb 命名空间下查找中间类 - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); - if (midType != null) - { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - if (midType == null) - { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - if (midType != null) + #region 在 tbref 命名空间下查找中间类 + if (midType == null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); + valiManyToMany(); } - } - if (midType == null) - { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); - if (midType != null) + if (midType == null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + valiManyToMany(); } - } - if (midType == null) - { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - if (midType != null) + if (midType == null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); + valiManyToMany(); } - } - #endregion - - #region 在 tbref 命名空间下查找中间类 - if (midType == null) - { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); - if (midType != null) + if (midType == null) { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + valiManyToMany(); } + #endregion } - if (midType == null) - { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - if (midType != null) - { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - if (midType == null) - { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); - if (midType != null) - { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - if (midType == null) - { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - if (midType != null) - { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - } - #endregion isManyToMany = midType != null; } @@ -427,78 +417,164 @@ namespace FreeSql.Internal var midTypePropsTrytb = tbmid.Properties.Where(a => a.Value.PropertyType == trytb.Type).FirstOrDefault().Value; //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); var lmbdWhere = isLazy ? new StringBuilder() : null; - for (var a = 0; a < trytb.Primarys.Length; a++) + + if (pnvAttr?.ManyToMany != null) { - var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); - if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); - if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}{findtrytbPkCsName}", out var trycol) == false && //骆峰命名 - tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}_{findtrytbPkCsName}", out trycol) == false //下划线命名 - ) + #region 指定 Navigate[ManyToMany = x] 配置多对多关系 + TableRef trytbTf = null; + try { - + trytbTf = tbmid.GetTableRef(midTypePropsTrytb.Name, true); } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) + catch (Exception ex) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {trytb.CsName}.{trytb.Primarys[a].CsName} 类型不一致"); + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTrytb.Name} 错误:{ex.Message}"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; - break; } - if (trycol == null) + if (nvref.Exception == null) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTrytb.Name}{findtrytbPkCsName}、{midTypePropsTrytb.Name}_{findtrytbPkCsName}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; + if (trytbTf.RefType != TableRefType.ManyToOne && trytbTf.RefType != TableRefType.OneToOne) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTrytb.Name} 导航属性不是【ManyToOne】或【OneToOne】"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + else + { + nvref.Columns.AddRange(trytbTf.RefColumns); + nvref.MiddleColumns.AddRange(trytbTf.Columns); + + if (tbmid.Primarys.Any() == false) + trytbTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true); + if (isLazy) + { + for (var a = 0; a < trytbTf.RefColumns.Count; a++) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("b.").Append(trytbTf.Columns[a].CsName).Append(" == this.").Append(trytbTf.RefColumns[a].CsName); + } + } + } } - - nvref.Columns.Add(trytb.Primarys[a]); - nvref.MiddleColumns.Add(trycol); - if (tbmid.Primarys.Any() == false) - trycol.Attribute.IsPrimary = true; - - if (isLazy) + if (nvref.Exception == null) { - if (a > 0) lmbdWhere.Append(" && "); - lmbdWhere.Append("b.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); + var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; + + TableRef tbrefTf = null; + try + { + tbrefTf = tbmid.GetTableRef(midTypePropsTbref.Name, true); + } + catch (Exception ex) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTbref.Name} 错误:{ex.Message}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + if (nvref.Exception == null) + { + if (tbrefTf.RefType != TableRefType.ManyToOne && tbrefTf.RefType != TableRefType.OneToOne) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTbref.Name} 导航属性不是【ManyToOne】或【OneToOne】"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + else + { + nvref.RefColumns.AddRange(tbrefTf.RefColumns); + nvref.MiddleColumns.AddRange(tbrefTf.Columns); + + if (tbmid.Primarys.Any() == false) + tbrefTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true); + + if (isLazy) + { + for (var a = 0; a < tbrefTf.RefColumns.Count; a++) + lmbdWhere.Append(" && b.").Append(tbrefTf.Columns[a].CsName).Append(" == a.").Append(tbrefTf.RefColumns[a].CsName); + } + } + } } + #endregion } - - if (nvref.Exception == null) + else { - var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; - for (var a = 0; a < tbref.Primarys.Length; a++) + #region 约定配置 + for (var a = 0; a < trytb.Primarys.Length; a++) { - var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); - if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); - if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 - tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名 + var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); + if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); + if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}{findtrytbPkCsName}", out var trycol) == false && //骆峰命名 + tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}_{findtrytbPkCsName}", out trycol) == false //下划线命名 ) { } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) + if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {trytb.CsName}.{trytb.Primarys[a].CsName} 类型不一致"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; break; } if (trycol == null) { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTbref.Name}{findtbrefPkCsName}、{midTypePropsTbref.Name}_{findtbrefPkCsName}"); + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTrytb.Name}{findtrytbPkCsName}、{midTypePropsTrytb.Name}_{findtrytbPkCsName}"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; break; } - nvref.RefColumns.Add(tbref.Primarys[a]); + nvref.Columns.Add(trytb.Primarys[a]); nvref.MiddleColumns.Add(trycol); if (tbmid.Primarys.Any() == false) trycol.Attribute.IsPrimary = true; - if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); + if (isLazy) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("b.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); + } } + + if (nvref.Exception == null) + { + var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; + for (var a = 0; a < tbref.Primarys.Length; a++) + { + var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); + if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); + if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 + tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名 + ) + { + + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTbref.Name}{findtbrefPkCsName}、{midTypePropsTbref.Name}_{findtbrefPkCsName}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + + nvref.RefColumns.Add(tbref.Primarys[a]); + nvref.MiddleColumns.Add(trycol); + if (tbmid.Primarys.Any() == false) + trycol.Attribute.IsPrimary = true; + + if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); + } + } + #endregion } if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) { @@ -586,7 +662,7 @@ namespace FreeSql.Internal var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); var findtrytb = pnv.Name; - if (findtrytb.EndsWith(tbref.CsName + "s")) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1); + if (findtrytb.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase)) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1); findtrytb += trytb.CsName; var trycol = bindColumns.Any() ? bindColumns[a] : null; diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 358dca55..bfb97595 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6e2a2afe..e09830e6 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 64c33afb..dcdbff8f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index fb69e0c4..b21b82fe 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 383bd572..d2e507d3 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f0cae953..4c53f365 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.8 + 0.7.9 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From f92cfa72f4b396eb56e35d7b57b1e138cb30faa5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 15 Jul 2019 18:36:16 +0800 Subject: [PATCH 0043/1029] update --- readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 6ab84261..89cc00a8 100644 --- a/readme.md +++ b/readme.md @@ -7,12 +7,12 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore # Features - [x] 支持 CodeFirst 迁移; -- [x] 支持 DbFirst 从数据库导入实体类,提供失血、贫血、充血三种生成模板; -- [x] 大量采用 ExpressionTree 技术提升性能; +- [x] 支持 DbFirst 从数据库导入实体类; +- [x] 大量采用 ExpressionTree 提升性能; - [x] 支持深入的类型映射,比如pgsql的数组类型,堪称匠心制作; - [x] 支持丰富的表达式函数; -- [x] 支持导航属性查询,和延时加载; -- [x] 支持同步/异步数据库操作方法,链式查询方法; +- [x] 支持导航属性一对多、多对多贪婪加载,以及延时加载; +- [x] 支持同步/异步数据库操作方法; - [x] 支持读写分离、分表分库,租户设计,过滤器,乐观锁; - [x] 支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite; From 6dccb909302667e823ea30eb8b8dccb5ca579bf1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 16 Jul 2019 17:31:54 +0800 Subject: [PATCH 0044/1029] =?UTF-8?q?=E5=8A=A0=E4=B8=AA=E5=88=A4=E6=96=AD?= =?UTF-8?q?=EF=BC=8C=E5=AD=90=E6=9F=A5=E8=AF=A2=E5=A6=82=E6=9E=9C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E4=BA=86=E7=9B=B8=E5=90=8C=20ISelect=20=E4=BC=9A?= =?UTF-8?q?=E6=AD=BB=E5=BE=AA=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonExpression.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index ac0d8c95..4a205ec9 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -633,14 +633,15 @@ namespace FreeSql.Internal fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; - fsqltables.AddRange(tsc._tables.Select(a => new SelectTableInfo - { - Alias = a.Alias, - On = "1=1", - Table = a.Table, - Type = SelectTableInfoType.Parent, - Parameter = a.Parameter - })); + if (fsqltables != tsc._tables) + fsqltables.AddRange(tsc._tables.Select(a => new SelectTableInfo + { + Alias = a.Alias, + On = "1=1", + Table = a.Table, + Type = SelectTableInfoType.Parent, + Parameter = a.Parameter + })); } else if (fsqlType != null) { From ecffd9840ac08637012d1bb2fe8f9a65debca3c6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 17 Jul 2019 09:42:57 +0800 Subject: [PATCH 0045/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20SqlServer=20?= =?UTF-8?q?=E6=9C=AA=E5=A4=84=E7=90=86=E5=AD=97=E7=AC=A6=E4=B8=B2=E5=89=8D?= =?UTF-8?q?=E9=9D=A2=E5=8A=A0N=20=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b5919bdc..55099f35 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 249cb8ff..df58f4ae 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 11d8c3c7..22630ed6 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.9 + 0.7.10 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cf80f4d7..39218d04 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index bfb97595..49999719 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index e09830e6..700a4eca 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index dcdbff8f..6cc77acb 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b21b82fe..53d3b823 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d2e507d3..839f960d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 1849c39e..a8ccf895 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -59,8 +59,8 @@ namespace FreeSql.SqlServer foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } + else if (param is string) return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - //if (param is string) return string.Concat('N', nparms[a]); } protected override DbCommand CreateCommand() diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4c53f365..516e5313 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.9 + 0.7.10 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From a5f524d154c119798d20c1ac58a527cbb4691725 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 17 Jul 2019 09:57:39 +0800 Subject: [PATCH 0046/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20SqlServer=20?= =?UTF-8?q?=E6=9C=AA=E5=A4=84=E7=90=86=E5=AD=97=E7=AC=A6=E4=B8=B2=E5=89=8D?= =?UTF-8?q?=E9=9D=A2=E5=8A=A0N=20=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs | 5 +++-- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 55099f35..bff801e7 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index df58f4ae..b28331ff 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 22630ed6..adc96357 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.10 + 0.7.11 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 39218d04..208b3288 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 49999719..61abc8e4 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 700a4eca..8c562199 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6cc77acb..d3343a81 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 53d3b823..f365c9af 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 839f960d..469863d4 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index a8ccf895..adfc89be 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -34,7 +34,9 @@ namespace FreeSql.SqlServer param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; - else if (param is string || param is char) + else if (param is string) + return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); @@ -59,7 +61,6 @@ namespace FreeSql.SqlServer foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } - else if (param is string) return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 516e5313..73ede2bc 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.10 + 0.7.11 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 558d154486c3dad50fdf593f288decb8352fa1b8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 17 Jul 2019 18:01:52 +0800 Subject: [PATCH 0047/1029] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20.From=20?= =?UTF-8?q?=E5=A4=9A=E8=A1=A8=E6=9F=A5=E8=AF=A2=E5=88=AB=E5=90=8D=E7=9A=84?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 24 +++++++++++++++++++++++- FreeSql/Internal/CommonExpression.cs | 7 ++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index c2450eac..0d15f2ee 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -283,6 +283,8 @@ namespace FreeSql.Tests [Navigate("TbId")] public virtual ICollection Builds { get; set; } public Templates Templates { get; set; } + + public TaskBuild Parent { get; set; } } public class SqlFunc @@ -296,7 +298,27 @@ namespace FreeSql.Tests [Fact] public void Test1() { - + var sqksdkfjl = g.sqlite.Select() + .LeftJoin(a => a.Templates.Id2 == a.TemplatesId) + .LeftJoin(a => a.Parent.Id == a.Id) + .LeftJoin(a => a.Parent.Templates.Id2 == a.Parent.TemplatesId) + .ToSql(a => new + { + code1 = a.Templates.Code, + code2 = a.Parent.Templates.Code + }); + + + var sqksdkfjl2223 = g.sqlite.Select().From((s1, tb2, b1, b2) => s1 + .LeftJoin(a => a.Id == tb2.TemplatesId) + .LeftJoin(a => a.TemplatesId == b1.Id2) + .LeftJoin(a => a.TemplatesId == b2.Id2) + ).ToSql((a, tb2, b1, b2) => new + { + code1 = b1.Code, + code2 = b2.Code + }); + var teklksjdg = g.sqlite.Select() .Where(a => true && a.CustomerMember.Group == "xxx") diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 4a205ec9..fd306228 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Internal { @@ -341,6 +342,7 @@ namespace FreeSql.Internal return GetBoolString(sql); return sql; } + static ConcurrentDictionary dicRegexAlias = new ConcurrentDictionary(); public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString) { var tbidx = _tables.Count; @@ -360,7 +362,10 @@ namespace FreeSql.Internal } else { - var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On) && sql.Contains(a.Alias + ".")).LastOrDefault(); + var find = _tables.Where((a, c) => c > 0 && + (a.Type == tbtype || a.Type == SelectTableInfoType.From) && + string.IsNullOrEmpty(a.On) && + dicRegexAlias.GetOrAdd(a.Alias, alias => new Regex($@"\b{alias}\.", RegexOptions.Compiled)).IsMatch(sql)).LastOrDefault(); if (find != null) { find.Type = tbtype; From de28c38d70f81d1166d5fb8f61b13dd7fc94546b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 18 Jul 2019 11:30:14 +0800 Subject: [PATCH 0048/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=94=99=E8=AF=AF=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E5=8F=8B=E5=A5=BD=E6=8F=90=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../DataContext/SqlServer/SqlServerFixture.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 54 +++++++++---------- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 6 +-- FreeSql.Tests/FreeSql.Tests/g.cs | 10 ++-- FreeSql/FreeSql.csproj | 4 +- FreeSql/Internal/CommonExpression.cs | 4 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../MySqlAdo/MySqlConnectionPool.cs | 12 +++++ .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../OracleAdo/OracleConnectionPool.cs | 12 +++++ .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 12 +++++ .../FreeSql.Provider.SqlServer.csproj | 2 +- .../SqlServerAdo/SqlServerConnectionPool.cs | 14 +++++ .../FreeSql.Provider.Sqlite.csproj | 2 +- .../SqliteAdo/SqliteConnectionPool.cs | 12 +++++ 20 files changed, 110 insertions(+), 50 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index bff801e7..69b25f0a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b28331ff..7e3e53a9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index adc96357..2565ee4c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.11 + 0.7.12 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs index 712e8b35..4cdefe0c 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs @@ -11,7 +11,7 @@ namespace FreeSql.Tests.DataContext.SqlServer public SqlServerFixture() { sqlServerLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=2") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=(localdb)\\mssqllocaldb;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") .UseAutoSyncStructure(true) .UseLazyLoading(true) diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 622fa1c6..38217d09 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -260,12 +260,12 @@ namespace FreeSql.Tests.SqlServer query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); query.ToList(); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //���û�е������� @@ -276,12 +276,12 @@ namespace FreeSql.Tests.SqlServer query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); query.ToList(); query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //������� @@ -329,12 +329,12 @@ namespace FreeSql.Tests.SqlServer query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); query.ToList(); query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //���û�е������� @@ -345,12 +345,12 @@ namespace FreeSql.Tests.SqlServer query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); query.ToList(); query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //������� @@ -399,12 +399,12 @@ namespace FreeSql.Tests.SqlServer query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); query.ToList(); query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //���û�е������� @@ -415,12 +415,12 @@ namespace FreeSql.Tests.SqlServer query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); query.ToList(); query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //������� @@ -485,33 +485,33 @@ namespace FreeSql.Tests.SqlServer query = select.Where(a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle')", sql); query.ToList(); query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); query.ToList(); query = select.Where(a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = 'tparent')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = N'tparent')", sql); query.ToList(); //���û�е������ԣ��򵥶������ query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'typeTitle')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TypeGuid] AND b.[Name] = N'typeTitle')", sql); query.ToList(); query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = 'typeTitle' AND b.[Guid] = a.[TypeGuid])", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = N'typeTitle' AND b.[Guid] = a.[TypeGuid])", sql); query.ToList(); query = select.Where((a, b, c) => c.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = 'tparent')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = N'tparent')", sql); query.ToList(); //����һ�� From ��Ķ������ @@ -519,7 +519,7 @@ namespace FreeSql.Tests.SqlServer .Where(a => a.Id == 10 && c.Name == "xxx") .Where(a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); query2.ToList(); //������϶����㲻�� @@ -549,17 +549,17 @@ namespace FreeSql.Tests.SqlServer query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle')", sql); query.ToList(); query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); query.ToList(); query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = 'tparent')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = N'tparent')", sql); query.ToList(); //����һ�� From ��Ķ������ @@ -567,7 +567,7 @@ namespace FreeSql.Tests.SqlServer .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") .WhereIf(true, a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); query2.ToList(); //������϶����㲻�� @@ -830,11 +830,11 @@ namespace FreeSql.Tests.SqlServer query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx' LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); //���û�е������� query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); @@ -843,11 +843,11 @@ namespace FreeSql.Tests.SqlServer query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx' LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); //������� query = select diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 0d15f2ee..fbdda02a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -359,8 +359,7 @@ namespace FreeSql.Tests .ToSql(a => new { a.Key, - sss = a.Sum(a.Value.Item1.Id), - sss2 = a.Sum(a.Value.Item2.Id2) + sss = a.Sum(a.Value.Item1.OptionsEntity04) }); var testgrpsql2 = g.sqlite.Select() @@ -370,8 +369,7 @@ namespace FreeSql.Tests .ToList(a => new { a.Key, - sss = a.Sum(a.Value.Item1.Id), - sss2 = a.Sum(a.Value.Item2.Id2) + sss = a.Sum(a.Value.Item1.OptionsEntity04) }); diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 037e941f..a7fa43f3 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -9,7 +9,7 @@ public class g { static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .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") + .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=2") .UseAutoSyncStructure(true) .UseMonitorCommand( cmd => @@ -28,7 +28,7 @@ public class g { NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); return new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") .UseAutoSyncStructure(true) .UseSyncStructureToLower(true) .UseLazyLoading(true) @@ -46,7 +46,7 @@ public class g public static IFreeSql pgsql => pgsqlLazy.Value; static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") .UseAutoSyncStructure(true) .UseMonitorCommand( cmd => @@ -62,7 +62,7 @@ public class g public static IFreeSql sqlserver => sqlserverLazy.Value; static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") + .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseSyncStructureToUpper(true) @@ -81,7 +81,7 @@ public class g public static IFreeSql oracle => oracleLazy.Value; static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=2") .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseMonitorCommand( diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 208b3288..fce6cd72 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. @@ -23,7 +23,7 @@ - + diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index fd306228..9be121fd 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -426,7 +426,7 @@ namespace FreeSql.Internal { var enumType = leftMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) - right = formatSql(Enum.Parse(enumType, right.Trim('\'')), leftMapColumn.Attribute.MapType); + right = formatSql(Enum.Parse(enumType, right.StartsWith("N'") ? right.Substring(1).Trim('\'') : right.Trim('\'')), leftMapColumn.Attribute.MapType); } if (leftMapColumn == null) { @@ -440,7 +440,7 @@ namespace FreeSql.Internal { var enumType = rightMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) - left = formatSql(Enum.Parse(enumType, left.Trim('\'')), rightMapColumn.Attribute.MapType); + left = formatSql(Enum.Parse(enumType, left.StartsWith("N'") ? left.Substring(1).Trim('\'') : left.Trim('\'')), rightMapColumn.Attribute.MapType); } } } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 61abc8e4..c78c7c8f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 6d231602..35613bdd 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -115,6 +115,12 @@ namespace FreeSql.MySql if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { @@ -137,6 +143,12 @@ namespace FreeSql.MySql if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8c562199..df550ef1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d3343a81..cedfe9b0 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index 18b1502e..ea880517 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -132,6 +132,12 @@ namespace FreeSql.Oracle if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { @@ -154,6 +160,12 @@ namespace FreeSql.Oracle if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f365c9af..93790dff 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index cd145f8b..74a2d707 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -127,6 +127,12 @@ namespace FreeSql.PostgreSQL if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { @@ -149,6 +155,12 @@ namespace FreeSql.PostgreSQL if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 469863d4..1edc84ba 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 605f0eb9..e8412eb8 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -121,6 +121,13 @@ namespace FreeSql.SqlServer if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { @@ -143,6 +150,13 @@ namespace FreeSql.SqlServer if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 73ede2bc..8d58039c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.11 + 0.7.12 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 8cad9db5..8f53eb91 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -127,6 +127,12 @@ namespace FreeSql.Sqlite if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) { @@ -149,6 +155,12 @@ namespace FreeSql.Sqlite if (_pool.IsAvailable) { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) { From c403fa6fad435633630705dbdec0754bdf4d45c7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 18 Jul 2019 19:46:04 +0800 Subject: [PATCH 0049/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E5=AF=B9=E5=9F=BA=E7=B1=BB=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E7=9A=84=E8=A7=A3=E6=9E=90=EF=BC=8C=E5=A6=82=EF=BC=9AWhere(a?= =?UTF-8?q?=20=3D>=20(a=20as=20BaseEntity).IsDeleted=20=3D=3D=20true)?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonExpression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 9be121fd..499db885 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -876,7 +876,7 @@ namespace FreeSql.Internal if (oper2.NodeType == ExpressionType.Parameter) { var oper2Parm = oper2 as ParameterExpression; - expStack.Push(Expression.Parameter(exp2.Type, oper2Parm.Name)); + expStack.Push(exp2.Type.IsAbstract || exp2.Type.IsInterface ? oper2Parm : Expression.Parameter(exp2.Type, oper2Parm.Name)); } else expStack.Push(oper2); From b37919be80949b54cdc15358d3c0d3119f565dcf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 19 Jul 2019 18:35:58 +0800 Subject: [PATCH 0050/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.Wher?= =?UTF-8?q?eCascade=20=E5=AE=9E=E7=8E=B0=E5=A4=9A=E8=A1=A8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=97=B6=EF=BC=8C=E5=90=91=E6=AF=8F=E4=B8=AA=E8=A1=A8?= =?UTF-8?q?=E4=B8=AD=E9=99=84=E5=8A=A0=E6=9D=A1=E4=BB=B6=EF=BC=9B=20-=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20Examples=20=E9=A1=B9=E7=9B=AE=20base=5Fent?= =?UTF-8?q?ity=EF=BC=8C=E5=88=A9=E7=94=A8=20BaseEntity=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=AE=80=E6=B4=81=E7=9A=84=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/BaseEntity.cs | 163 ++++++++++++++++++ Examples/base_entity/Entities/User.cs | 91 ++++++++++ Examples/base_entity/Program.cs | 82 +++++++++ Examples/base_entity/base_entity.csproj | 18 ++ .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../Sqlite/Curd/SqliteSelectTest.cs | 1 + FreeSql.sln | 15 ++ FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 15 ++ FreeSql/FreeUtil.cs | 14 ++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 15 ++ FreeSql/Internal/CommonExpression.cs | 84 +++++++-- .../SelectProvider/Select0Provider.cs | 37 ++-- .../SelectProvider/Select10Provider.cs | 8 +- .../SelectProvider/Select1Provider.cs | 31 ++-- .../SelectProvider/Select2Provider.cs | 8 +- .../SelectProvider/Select3Provider.cs | 8 +- .../SelectProvider/Select4Provider.cs | 8 +- .../SelectProvider/Select5Provider.cs | 8 +- .../SelectProvider/Select6Provider.cs | 8 +- .../SelectProvider/Select7Provider.cs | 8 +- .../SelectProvider/Select8Provider.cs | 8 +- .../SelectProvider/Select9Provider.cs | 8 +- .../SelectProvider/SelectGroupingProvider.cs | 12 +- FreeSql/Internal/Model/SelectTableInfo.cs | 2 + FreeSql/Internal/UtilsExpressionTree.cs | 10 +- .../Curd/MySqlSelect.cs | 40 +++-- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySql/MySqlUtils.cs | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../MySqlConnectorUtils.cs | 2 +- .../Curd/OracleSelect.cs | 44 +++-- .../FreeSql.Provider.Oracle.csproj | 2 +- .../Curd/PostgreSQLSelect.cs | 40 +++-- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../Curd/SqlServerSelect.cs | 66 +++++-- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../Curd/SqliteSelect.cs | 40 +++-- .../FreeSql.Provider.Sqlite.csproj | 2 +- 41 files changed, 745 insertions(+), 171 deletions(-) create mode 100644 Examples/base_entity/BaseEntity.cs create mode 100644 Examples/base_entity/Entities/User.cs create mode 100644 Examples/base_entity/Program.cs create mode 100644 Examples/base_entity/base_entity.csproj diff --git a/Examples/base_entity/BaseEntity.cs b/Examples/base_entity/BaseEntity.cs new file mode 100644 index 00000000..34eca502 --- /dev/null +++ b/Examples/base_entity/BaseEntity.cs @@ -0,0 +1,163 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Diagnostics; +using System.Linq.Expressions; + +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity +{ + private static Lazy _ormLazy = new Lazy(() => + { + var orm = new FreeSqlBuilder() + .UseAutoSyncStructure(true) + .UseNoneCommandParameter(true) + .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") + .Build(); + orm.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); + return orm; + }); + public static IFreeSql Orm => _ormLazy.Value; + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + /// + /// 更新时间 + /// + public DateTime UpdateTime { get; set; } + /// + /// 逻辑删除 + /// + public bool IsDeleted { get; set; } +} + +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity : BaseEntity where TEntity : class +{ + public static ISelect Select => Orm.Select().WhereCascade(a => (a as BaseEntity).IsDeleted == false); + public static ISelect Where(Expression> exp) => Select.Where(exp); + public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); + + [JsonIgnore] + protected IBaseRepository Repository { get; set; } + + bool UpdateIsDeleted(bool value) + { + if (this.Repository == null) + return Orm.Update(this as TEntity).Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; + this.IsDeleted = value; + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 删除数据 + /// + /// + public virtual bool Delete() => this.UpdateIsDeleted(true); + /// + /// 恢复删除的数据 + /// + /// + public virtual bool Restore() => this.UpdateIsDeleted(false); + + /// + /// 附加实体,在更新数据时,只更新变化的部分 + /// + public void Attach() + { + if (this.Repository == null) this.Repository = Orm.GetRepository(); + this.Repository.Attach(this as TEntity); + } + /// + /// 更新数据 + /// + /// + public virtual bool Update() + { + if (this.Repository == null) + return Orm.Update().SetSource(this as TEntity).ExecuteAffrows() == 1; + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 插入数据 + /// + public virtual void Insert() + { + if (this.Repository == null) this.Repository = Orm.GetRepository(); + this.Repository.Insert(this as TEntity); + } + + /// + /// 更新或插入 + /// + /// + public virtual void Save() + { + if (this.Repository == null) this.Repository = Orm.GetRepository(); + this.Repository.InsertOrUpdate(this as TEntity); + } +} + +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity : BaseEntity where TEntity : class +{ + static BaseEntity() + { + var tkeyType = typeof(TKey)?.NullableTypeOrThis(); + if (tkeyType == typeof(int) || tkeyType == typeof(long)) + Orm.CodeFirst.ConfigEntity(typeof(TEntity), + t => t.Property("Id").IsIdentity(true)); + } + + /// + /// 主键 + /// + public virtual TKey Id { get; set; } + + /// + /// 根据主键值获取数据 + /// + /// + /// + public static TEntity Find(TKey id) + { + var item = Select.WhereDynamic(id).First(); + (item as BaseEntity)?.Attach(); + return item; + } +} + +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity : BaseEntity where TEntity : class +{ + + /// + /// 主键1 + /// + [Column(IsPrimary = true)] + public virtual TKey1 PkId1 { get; set; } + /// + /// 主键2 + /// + [Column(IsPrimary = true)] + public virtual TKey2 PkId2 { get; set; } + + /// + /// 根据主键值获取数据 + /// + /// 主键1 + /// 主键2 + /// + public static TEntity Find(TKey1 pkid1, TKey1 pkid2) + { + var item = Select.WhereDynamic(new + { + PkId1 = pkid1, + PkId2 = pkid2 + }).First(); + (item as BaseEntity).Attach(); + return item; + } +} \ No newline at end of file diff --git a/Examples/base_entity/Entities/User.cs b/Examples/base_entity/Entities/User.cs new file mode 100644 index 00000000..a062d1a0 --- /dev/null +++ b/Examples/base_entity/Entities/User.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Text; + +public class UserGroup : BaseEntity +{ + /// + /// 组名 + /// + public string GroupName { get; set; } + + public List User1s { get; set; } + + public List User2s { get; set; } +} + +public class Role : BaseEntity +{ + public List User1s { get; set; } +} +public class RoleUser1 : BaseEntity +{ + public string RoleId { get; set; } + public Guid User1Id { get; set; } + + public Role Role { get; set; } + public User1 User1 { get; set; } +} + +public class User1 : BaseEntity +{ + public int GroupId { get; set; } + public UserGroup Group { get; set; } + + public List Roles { get; set; } + + /// + /// 登陆名 + /// + public string Username { get; set; } + + /// + /// 昵称 + /// + public string Nickname { get; set; } + + /// + /// 头像 + /// + public string Avatar { get; set; } + + /// + /// 描述 + /// + public string Description { get; set; } +} + +public class User2 : BaseEntity +{ + static User2() + { + User2.Orm.CodeFirst.ConfigEntity(t => + { + t.Property(a => a.PkId1).Name("UserId"); + t.Property(a => a.PkId2).Name("Index"); + }); + } + + public int GroupId { get; set; } + public UserGroup Group { get; set; } + + /// + /// 登陆名 + /// + public string Username { get; set; } + + /// + /// 昵称 + /// + public string Nickname { get; set; } + + /// + /// 头像 + /// + public string Avatar { get; set; } + + /// + /// 描述 + /// + public string Description { get; set; } +} \ No newline at end of file diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs new file mode 100644 index 00000000..7de6d4d4 --- /dev/null +++ b/Examples/base_entity/Program.cs @@ -0,0 +1,82 @@ +using System; + +namespace base_entity +{ + class Program + { + static void Main(string[] args) + { + var ug1 = new UserGroup(); + ug1.GroupName = "分组一"; + ug1.Insert(); + + var ug2 = new UserGroup(); + ug2.GroupName = "分组二"; + ug2.Insert(); + + var u1 = new User1(); + var u2 = new User2(); + + u1.GroupId = ug1.Id; + u1.Save(); + + u2.GroupId = ug2.Id; + u2.Save(); + + u1.Delete(); + u1.Restore(); + + u1.Nickname = "x1"; + u1.Update(); + + u2.Delete(); + u2.Restore(); + + u2.Username = "x2"; + u2.Update(); + + var u11 = User1.Find(u1.Id); + u11.Description = "备注"; + u11.Save(); + + u11.Delete(); + + var u11null = User1.Find(u1.Id); + + var u11s = User1.Where(a => a.Group.Id == ug1.Id).Limit(10).ToList(); + var u22s = User2.Where(a => a.Group.Id == ug2.Id).Limit(10).ToList(); + + var u11s2 = User1.Select.LeftJoin((a, b) => a.GroupId == b.Id).Limit(10).ToList(); + var u22s2 = User2.Select.LeftJoin((a, b) => a.GroupId == b.Id).Limit(10).ToList(); + + var ug1s = UserGroup.Select + .IncludeMany(a => a.User1s) + .IncludeMany(a => a.User2s) + .Limit(10).ToList(); + + var ug1s2 = UserGroup.Select.Where(a => a.User1s.AsSelect().Any(b => b.Nickname == "x1")).Limit(10).ToList(); + + var r1 = new Role(); + r1.Id = "管理员"; + r1.Save(); + + var r2 = new Role(); + r2.Id = "超级会员"; + r2.Save(); + + var ru1 = new RoleUser1(); + ru1.User1Id = u1.Id; + ru1.RoleId = r1.Id; + ru1.Save(); + + ru1.RoleId = r2.Id; + ru1.Save(); + + var u1roles = User1.Select.IncludeMany(a => a.Roles).ToList(); + var u1roles2 = User1.Select.Where(a => a.Roles.AsSelect().Any(b => b.Id == "xx")).ToList(); + + Console.WriteLine("按任意键结束。。。"); + Console.ReadKey(); + } + } +} diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj new file mode 100644 index 00000000..63acf723 --- /dev/null +++ b/Examples/base_entity/base_entity.csproj @@ -0,0 +1,18 @@ + + + + Exe + netcoreapp2.2 + + + + + + + + + + + + + diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 69b25f0a..da93ab7b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 7e3e53a9..c3bd55bb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 2565ee4c..508bcf13 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.12 + 0.7.13 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index debdb67b..e0c46327 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -568,6 +568,7 @@ namespace FreeSql.Tests.Sqlite Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a", sql); query.First(); } + [Fact] public void WhereExists() { diff --git a/FreeSql.sln b/FreeSql.sln index 00fecbec..749a39d2 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -54,6 +54,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.PerformanceTe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.MySqlConnector", "FreeSql.Tests\FreeSql.Tests.Provider.MySqlConnector\FreeSql.Tests.Provider.MySqlConnector.csproj", "{0F45294A-34FF-4FB8-A046-20E09E3A4D5C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "base_entity", "Examples\base_entity\base_entity.csproj", "{D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -304,6 +306,18 @@ Global {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|x64.Build.0 = Release|Any CPU {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|x86.ActiveCfg = Release|Any CPU {0F45294A-34FF-4FB8-A046-20E09E3A4D5C}.Release|x86.Build.0 = Release|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Debug|x64.ActiveCfg = Debug|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Debug|x64.Build.0 = Debug|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Debug|x86.ActiveCfg = Debug|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Debug|x86.Build.0 = Debug|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|Any CPU.Build.0 = Release|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x64.ActiveCfg = Release|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x64.Build.0 = Release|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x86.ActiveCfg = Release|Any CPU + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -322,6 +336,7 @@ Global {D2A41321-5E84-410B-B25C-3AA122D4CA27} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {690F89E0-A721-423F-8F5D-D262F73235EA} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fce6cd72..b7d711ee 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6b0870ec..b7748311 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1259,6 +1259,21 @@ 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + 多表查询时,该方法标记后,表达式条件将对所有表进行附加 + + 例如:软删除、租户,每个表都给条件,挺麻烦的 + + fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) + + 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) + + 当其中的实体可附加表达式才会进行,表越多时收益越大 + + + + 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) diff --git a/FreeSql/FreeUtil.cs b/FreeSql/FreeUtil.cs index d6007789..145b8243 100644 --- a/FreeSql/FreeUtil.cs +++ b/FreeSql/FreeUtil.cs @@ -3,6 +3,8 @@ using System; using System.Collections.Concurrent; using System.Data.Common; using System.Diagnostics; +using System.Security.Cryptography; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -33,4 +35,16 @@ public static class FreeUtil 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')}"; return Guid.Parse(guid); } + + public static string Sha1(string str) + { + var buffer = Encoding.UTF8.GetBytes(str); + var data = SHA1.Create().ComputeHash(buffer); + + var sub = new StringBuilder(); + foreach (var t in data) + sub.Append(t.ToString("X2")); + + return sub.ToString(); + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index ffc07e50..aee69f3a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -275,6 +275,21 @@ namespace FreeSql /// ISelect WhereDynamic(object dywhere); + /// + /// 多表查询时,该方法标记后,表达式条件将对所有表进行附加 + /// + /// 例如:软删除、租户,每个表都给条件,挺麻烦的 + /// + /// fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) + /// + /// 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) + /// + /// 当其中的实体可附加表达式才会进行,表越多时收益越大 + /// + /// + /// + ISelect WhereCascade(Expression> exp); + /// /// 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) /// diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 499db885..cfaf858e 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -24,20 +24,20 @@ namespace FreeSql.Internal } static ConcurrentDictionary _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary(); - public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString) + public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression) { - Func getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }; + Func getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; switch (exp.NodeType) { - case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); - case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString); + case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression); + case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString, whereCascadeExpression); case ExpressionType.Negate: case ExpressionType.NegateChecked: parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); return false; - case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); + case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression); case ExpressionType.Constant: var constExp = exp as ConstantExpression; //处理自定义SQL语句,如: ToList(new { @@ -117,7 +117,7 @@ namespace FreeSql.Internal MapType = initAssignExp.Expression.Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString); + ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString, whereCascadeExpression); } } else @@ -139,7 +139,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -169,7 +169,7 @@ namespace FreeSql.Internal MapType = newExp.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString); + ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString, whereCascadeExpression); } } else @@ -192,7 +192,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -332,9 +332,9 @@ namespace FreeSql.Internal return sql; } - public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString) + public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; @@ -343,10 +343,10 @@ namespace FreeSql.Internal return sql; } static ConcurrentDictionary dicRegexAlias = new ConcurrentDictionary(); - public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString) + public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression) { var tbidx = _tables.Count; - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) sql = $"{sql} = {formatSql(true, null)}"; @@ -362,8 +362,8 @@ namespace FreeSql.Internal } else { - var find = _tables.Where((a, c) => c > 0 && - (a.Type == tbtype || a.Type == SelectTableInfoType.From) && + var find = _tables.Where((a, c) => c > 0 && + (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On) && dicRegexAlias.GetOrAdd(a.Alias, alias => new Regex($@"\b{alias}\.", RegexOptions.Compiled)).IsMatch(sql)).LastOrDefault(); if (find != null) @@ -473,7 +473,7 @@ namespace FreeSql.Internal left = tmp; } if (right == "NULL") oper = oper == "=" ? " IS " : " IS NOT "; - switch(oper) + switch (oper) { case "%": return _common.Mod(left, right, leftExp.Type, rightExp.Type); case "AND": @@ -647,6 +647,12 @@ namespace FreeSql.Internal Type = SelectTableInfoType.Parent, Parameter = a.Parameter })); + if (tsc.whereCascadeExpression?.Any() == true) + { + var fsqlCascade = fsqlType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; + if (fsqlCascade != tsc.whereCascadeExpression) + fsqlCascade.AddRange(tsc.whereCascadeExpression); + } } else if (fsqlType != null) { @@ -907,7 +913,8 @@ namespace FreeSql.Internal } var name = tb.ColumnsByCs[memberExp.Member.Name].Attribute.Name; if (tsc.isQuoteName) name = _common.QuoteSqlName(name); - return name; + if (string.IsNullOrEmpty(tsc.alias001)) return name; + return $"{tsc.alias001}.{name}"; } Func getOrAddTable = (tbtmp, alias, isa, parmExp, mp) => { @@ -1113,6 +1120,8 @@ namespace FreeSql.Internal public ExpressionStyle style { get; set; } public Type mapType { get; set; } public TableInfo currentTable { get; set; } + public List whereCascadeExpression { get; set; } + public string alias001 { get; set; } //单表字段的表别名 public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List v1, Func v2, SelectTableInfoType v3) { @@ -1125,7 +1134,9 @@ namespace FreeSql.Internal isQuoteName = this.isQuoteName, isDisableDiyParse = this.isDisableDiyParse, style = this.style, - currentTable = this.currentTable + currentTable = this.currentTable, + whereCascadeExpression = this.whereCascadeExpression, + alias001 = this.alias001 }; } public ExpTSC CloneDisableDiyParse() @@ -1139,11 +1150,46 @@ namespace FreeSql.Internal isQuoteName = this.isQuoteName, isDisableDiyParse = true, style = this.style, - currentTable = this.currentTable + currentTable = this.currentTable, + whereCascadeExpression = this.whereCascadeExpression, + alias001 = this.alias001 }; } } + static ConcurrentDictionary _dicGetWhereCascadeSqlError = new ConcurrentDictionary(); + public string GetWhereCascadeSql(SelectTableInfo tb, List _whereCascadeExpression) + { + if (_whereCascadeExpression.Any()) + { + var newParameter = Expression.Parameter(tb.Table.Type, "c"); + Expression newExp = null; + + foreach (var fl in _whereCascadeExpression) + { + var errorKey = FreeUtil.Sha1($"{tb.Table.Type.FullName},{fl.ToString()}"); + if (_dicGetWhereCascadeSqlError.ContainsKey(errorKey)) continue; + + var visitor = new NewExpressionVisitor(newParameter, fl.Parameters.FirstOrDefault()); + try + { + var andExp = visitor.Replace(fl.Body); + if (newExp == null) newExp = andExp; + else newExp = Expression.AndAlso(newExp, andExp); + } + catch + { + _dicGetWhereCascadeSqlError.TryAdd(errorKey, true); + continue; + } + } + + if (newExp != null) + return ExpressionLambdaToSql(newExp, new ExpTSC { _tables = null, _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + } + return null; + } + public string formatSql(object obj, Type mapType) { return string.Concat(_ado.AddslashesProcessParam(obj, mapType)); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 32b794e6..fde203e8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -31,10 +31,26 @@ namespace FreeSql.Internal.CommonProvider protected DbTransaction _transaction; protected DbConnection _connection; protected Action _trackToList; - protected Queue> _includeToList = new Queue>(); + protected List> _includeToList = new List>(); protected bool _distinct; protected Expression _selectExpression; + protected List _whereCascadeExpression = new List(); + bool _isDisponse = false; + ~Select0Provider() + { + if (_isDisponse) return; + _isDisponse = false; + _where.Clear(); + _params.Clear(); + _tables.Clear(); + _tableRules.Clear(); + _join.Clear(); + _trackToList = null; + _includeToList.Clear(); + _selectExpression = null; + _whereCascadeExpression.Clear(); + } public static void CopyData(Select0Provider from, object to, ReadOnlyCollection lambParms) { var toType = to?.GetType(); @@ -77,6 +93,7 @@ namespace FreeSql.Internal.CommonProvider toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); + toType.GetField("_whereMultiExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression); } public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) @@ -384,7 +401,7 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret); + foreach (var include in _includeToList) include?.Invoke(ret); _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); _trackToList?.Invoke(ret); return ret; @@ -420,7 +437,7 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret); + foreach (var include in _includeToList) include?.Invoke(ret); _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); _trackToList?.Invoke(ret); return ret; @@ -548,7 +565,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression); return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); } static ConcurrentDictionary _dicConstructor = new ConcurrentDictionary(); @@ -944,13 +961,13 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression); this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null); return new SelectGroupingProvider(this, map, _commonExpression, _tables); } protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { - _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null); + _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); return this as TSelect; } protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) @@ -958,7 +975,7 @@ namespace FreeSql.Internal.CommonProvider var tb = _commonUtils.GetTableByEntity(typeof(T2)); if (tb == null) throw new ArgumentException("T2 类型错误"); _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType }); - _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null); + _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); return this as TSelect; } protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); @@ -1027,7 +1044,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression); return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } async protected Task InternalToAggregateAsync(Expression select) @@ -1036,11 +1053,11 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression); return (await this.ToListMapReaderAsync((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); } - protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null)); + protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression)); #endregion } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index a2e67382..a73fea3a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -181,28 +181,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)) : this; } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 49f0a87d..13725c82 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -321,9 +321,10 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregateAsync(select?.Body); } - public ISelect Where(Expression> exp) + public ISelect Where(Expression> exp) => WhereIf(true, exp); + public ISelect WhereIf(bool condition, Expression> exp) { - if (exp == null) return this; + if (condition == false || exp == null) return this; _tables[0].Parameter = exp.Parameters[0]; return this.InternalWhere(exp?.Body); } @@ -364,11 +365,10 @@ namespace FreeSql.Internal.CommonProvider } public ISelect WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere)); - public ISelect WhereIf(bool condition, Expression> exp) + public ISelect WhereCascade(Expression> exp) { - if (condition == false || exp == null) return this; - _tables[0].Parameter = exp.Parameters[0]; - return this.InternalWhere(exp?.Body); + if (exp != null) _whereCascadeExpression.Add(exp); + return this; } public bool Any(Expression> exp) => this.Where(exp).Any(); @@ -390,7 +390,7 @@ namespace FreeSql.Internal.CommonProvider var tb = _commonUtils.GetTableByEntity(expBody.Type); if (tb == null) throw new Exception("Include 参数类型错误"); - _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); + _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null); return this; } @@ -454,15 +454,13 @@ namespace FreeSql.Internal.CommonProvider if (tbNav == null) throw new Exception($"类型 {typeof(TNavigate).FullName} 错误,不能使用 IncludeMany"); if (collMem.Expression.NodeType != ExpressionType.Parameter) - _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); + _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null); TableRef tbref = null; var tbrefOneToManyColumns = new List>(); //临时 OneToMany 三个表关联,第三个表需要前两个表确定 if (whereExp == null) { - tbref = tb.GetTableRef(collMem.Member.Name, true); - } else { @@ -563,8 +561,8 @@ namespace FreeSql.Internal.CommonProvider } if (tbref.Columns.Any() == false) throw throwNavigateSelector; } - - _includeToList.Enqueue(listObj => + + _includeToList.Add(listObj => { var list = listObj as List; if (list == null) return; @@ -621,6 +619,10 @@ namespace FreeSql.Internal.CommonProvider var subSelect = _orm.Select().WithConnection(_connection).WithTransaction(_transaction).TrackToList(_trackToList) as Select1Provider; if (_tableRules?.Any() == true) foreach (var tr in _tableRules) subSelect.AsTable(tr); + + if (_whereCascadeExpression.Any()) + subSelect._whereCascadeExpression.AddRange(_whereCascadeExpression.ToArray()); + then?.Invoke(subSelect); var subSelectT1Alias = subSelect._tables[0].Alias; var oldWhere = subSelect._where.ToString(); @@ -778,6 +780,11 @@ namespace FreeSql.Internal.CommonProvider { if (z > 0) sbJoin.Append(" AND "); sbJoin.Append($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}"); + if (_whereCascadeExpression.Any()) { + var cascade = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Alias = "midtb", AliasInit = "midtb", Table = tbrefMid, Type = SelectTableInfoType.InnerJoin }, _whereCascadeExpression); + if (string.IsNullOrEmpty(cascade) == false) + sbJoin.Append(" AND (").Append(cascade).Append(")"); + } } subSelect.InnerJoin(sbJoin.ToString()); sbJoin.Clear(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index d8a756ea..25a82a0c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -157,28 +157,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 32f58181..82a0f6a5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -160,28 +160,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 92260a34..1efcdb3c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -163,28 +163,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index b59a67c2..ef30f98a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -166,28 +166,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 10f315ee..0572ee69 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -169,28 +169,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index a3b8705a..c0b9161e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -172,28 +172,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 3926173e..a5bf2c74 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -175,28 +175,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 3c953b74..da94f75a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -178,28 +178,28 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 0dd4533b..cac92d53 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -84,7 +84,7 @@ namespace FreeSql.Internal.CommonProvider public ISelectGrouping Having(Expression, bool>> exp) { - var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString); + var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null); var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { sql, null }); return this; @@ -92,7 +92,7 @@ namespace FreeSql.Internal.CommonProvider public ISelectGrouping OrderBy(Expression, TMember>> column) { - var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString); + var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { sql, null }); return this; @@ -100,7 +100,7 @@ namespace FreeSql.Internal.CommonProvider public ISelectGrouping OrderByDescending(Expression, TMember>> column) { - var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString); + var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { $"{sql} DESC", null }); return this; @@ -112,7 +112,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null); var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; @@ -123,7 +123,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null); var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; @@ -136,7 +136,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null); var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; } diff --git a/FreeSql/Internal/Model/SelectTableInfo.cs b/FreeSql/Internal/Model/SelectTableInfo.cs index b3e61254..346181dc 100644 --- a/FreeSql/Internal/Model/SelectTableInfo.cs +++ b/FreeSql/Internal/Model/SelectTableInfo.cs @@ -21,6 +21,8 @@ namespace FreeSql.Internal.Model public string NavigateCondition { get; set; } public ParameterExpression Parameter { get; set; } public SelectTableInfoType Type { get; set; } + + public string Cascade { get; set; } } public enum SelectTableInfoType { From, LeftJoin, InnerJoin, RightJoin, Parent } } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 473a82bb..a62e0eb6 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -41,6 +41,13 @@ namespace FreeSql.Internal if (typeof(IEnumerable).IsAssignableFrom(entity) && entity.IsGenericParameter == true) return null; if (entity.IsArray) return null; + object entityDefault = null; + try + { + if (entity.IsAbstract == false && entity.IsInterface == false) + entityDefault = Activator.CreateInstance(entity); + } + catch { } var tbattr = common.GetEntityTableAttribute(entity); trytb = new TableInfo(); trytb.Type = entity; @@ -148,7 +155,8 @@ namespace FreeSql.Internal trytb.ColumnsByCsIgnore.Add(p.Name, col); continue; } - colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type)); + if (entityDefault == null) entityDefault = Activator.CreateInstance(entity); + colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(entityDefault); if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue); if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; if (colattr.IsNullable == false && colattr.DbDefautValue == null) diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index 3292efc6..6c5557ba 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -12,11 +12,15 @@ namespace FreeSql.MySql.Curd class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + var sb = new StringBuilder(); var sbnav = new StringBuilder(); sb.Append(_select); @@ -33,8 +37,13 @@ namespace FreeSql.MySql.Curd for (var b = 1; b < tbsfrom.Length; b++) { sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } break; } @@ -42,6 +51,7 @@ namespace FreeSql.MySql.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -61,11 +71,15 @@ namespace FreeSql.MySql.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + foreach (var tb in _tables) { if (tb.Type == SelectTableInfoType.Parent) continue; @@ -100,51 +114,51 @@ namespace FreeSql.MySql.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c78c7c8f..ea19f7f5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 2afaf09e..d2b75c78 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -97,7 +97,7 @@ namespace FreeSql.MySql case "MygisPolygon": case "MygisMultiPoint": case "MygisMultiLineString": - case "MygisMultiPolygon": return $"AsText({columnName})"; + case "MygisMultiPolygon": return $"ST_AsText({columnName})"; } return columnName; } diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index df550ef1..74eb71ae 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 2624d701..05a8374f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -105,7 +105,7 @@ namespace FreeSql.MySql case "MygisPolygon": case "MygisMultiPoint": case "MygisMultiLineString": - case "MygisMultiPolygon": return $"AsText({columnName})"; + case "MygisMultiPolygon": return $"ST_AsText({columnName})"; } return columnName; } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index df385797..14911f36 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -12,11 +12,15 @@ namespace FreeSql.Oracle.Curd class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + var sb = new StringBuilder(); var sbnav = new StringBuilder(); sb.Append(_select); @@ -35,8 +39,13 @@ namespace FreeSql.Oracle.Curd for (var b = 1; b < tbsfrom.Length; b++) { sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } break; } @@ -44,6 +53,7 @@ namespace FreeSql.Oracle.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -63,11 +73,15 @@ namespace FreeSql.Oracle.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + foreach (var tb in _tables) { if (tb.Type == SelectTableInfoType.Parent) continue; @@ -75,13 +89,9 @@ namespace FreeSql.Oracle.Curd sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); } if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) - { sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); - } if (sbnav.Length > 0) - { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } if (string.IsNullOrEmpty(_groupby) == false) { sb.Append(_groupby); @@ -116,51 +126,51 @@ namespace FreeSql.Oracle.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index cedfe9b0..20dee896 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index e5bb3f9d..21d9eca8 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -12,11 +12,15 @@ namespace FreeSql.PostgreSQL.Curd class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + var sb = new StringBuilder(); var sbnav = new StringBuilder(); sb.Append(_select); @@ -33,8 +37,13 @@ namespace FreeSql.PostgreSQL.Curd for (var b = 1; b < tbsfrom.Length; b++) { sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } break; } @@ -42,6 +51,7 @@ namespace FreeSql.PostgreSQL.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -61,11 +71,15 @@ namespace FreeSql.PostgreSQL.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + foreach (var tb in _tables) { if (tb.Type == SelectTableInfoType.Parent) continue; @@ -102,51 +116,51 @@ namespace FreeSql.PostgreSQL.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 93790dff..2d860988 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 50791ab9..4228689a 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -12,17 +12,21 @@ namespace FreeSql.SqlServer.Curd class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _orm); + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _whereCascadeExpression, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _whereCascadeExpression, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + var sb = new StringBuilder(); var sbnav = new StringBuilder(); sb.Append(_select); @@ -51,8 +55,13 @@ namespace FreeSql.SqlServer.Curd for (var b = 1; b < tbsfrom.Length; b++) { sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } break; } @@ -60,6 +69,7 @@ namespace FreeSql.SqlServer.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -79,11 +89,15 @@ namespace FreeSql.SqlServer.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + foreach (var tb in _tables) { if (tb.Type == SelectTableInfoType.Parent) continue; @@ -111,11 +125,15 @@ namespace FreeSql.SqlServer.Curd #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + var sb = new StringBuilder(); var sbnav = new StringBuilder(); sb.Append(_select); @@ -134,8 +152,13 @@ namespace FreeSql.SqlServer.Curd for (var b = 1; b < tbsfrom.Length; b++) { sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } break; } @@ -143,6 +166,7 @@ namespace FreeSql.SqlServer.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -162,11 +186,15 @@ namespace FreeSql.SqlServer.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + foreach (var tb in _tables) { if (tb.Type == SelectTableInfoType.Parent) continue; @@ -214,51 +242,51 @@ namespace FreeSql.SqlServer.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 1edc84ba..a76b05ed 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index 1cdf4651..20b2e833 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -12,11 +12,15 @@ namespace FreeSql.Sqlite.Curd class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + var sb = new StringBuilder(); var sbnav = new StringBuilder(); sb.Append(_select); @@ -33,8 +37,13 @@ namespace FreeSql.Sqlite.Curd for (var b = 1; b < tbsfrom.Length; b++) { sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1"); - else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } break; } @@ -42,6 +51,7 @@ namespace FreeSql.Sqlite.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -61,11 +71,15 @@ namespace FreeSql.Sqlite.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + foreach (var tb in _tables) { if (tb.Type == SelectTableInfoType.Parent) continue; @@ -100,51 +114,51 @@ namespace FreeSql.Sqlite.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 8d58039c..06c1f7b3 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.12 + 0.7.13 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 9cc8da637dfa5633da32e4ffd8cbdf64d5801d09 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 19 Jul 2019 18:45:41 +0800 Subject: [PATCH 0051/1029] =?UTF-8?q?base=5Fentity=20=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=EF=BC=8C=E9=80=9A=E8=BF=875=E7=A7=8D?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/BaseEntity.cs | 6 +++++- Examples/base_entity/base_entity.csproj | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Examples/base_entity/BaseEntity.cs b/Examples/base_entity/BaseEntity.cs index 34eca502..018c7d58 100644 --- a/Examples/base_entity/BaseEntity.cs +++ b/Examples/base_entity/BaseEntity.cs @@ -13,7 +13,11 @@ public abstract class BaseEntity var orm = new FreeSqlBuilder() .UseAutoSyncStructure(true) .UseNoneCommandParameter(true) - .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") + .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=2") + //.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=2") + //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=2") + //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") .Build(); orm.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); return orm; diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index 63acf723..f5ecc34b 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -12,7 +12,11 @@ + + + + From 2550611410e5ef7e7e4007f640f5acaea17729a9 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 20 Jul 2019 15:19:21 +0800 Subject: [PATCH 0052/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ExpressionTr?= =?UTF-8?q?ee=20=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2=E7=9A=84=E5=8F=8B?= =?UTF-8?q?=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/UtilsExpressionTree.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index a62e0eb6..a9d8715f 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1770,7 +1770,14 @@ namespace FreeSql.Internal var exp = GetDataReaderValueBlockExpression(type, parmExp); return Expression.Lambda>(exp, parmExp).Compile(); }); - return func(value); + try + { + return func(value); + } + catch (Exception ex) + { + throw new ArgumentException($"ExpressionTree 转换类型错误,值({string.Concat(value)}),类型({value.GetType().FullName}),目标类型({type.FullName}),{ex.Message}"); + } } public static string GetCsName(string name) { From c092de21d11ff109d9dfdad89b8f8ed0ee9ef4fa Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 22 Jul 2019 15:00:01 +0800 Subject: [PATCH 0053/1029] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20BaseEntity=20rea?= =?UTF-8?q?dme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/readme.md | 111 +++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Examples/base_entity/readme.md diff --git a/Examples/base_entity/readme.md b/Examples/base_entity/readme.md new file mode 100644 index 00000000..87946f7f --- /dev/null +++ b/Examples/base_entity/readme.md @@ -0,0 +1,111 @@ +# 前言 + +尝试过 ado.net、dapper、ef,以及Repository仓储,甚至自己还写过生成器工具,以便做常规CRUD操作。 + +它们日常操作不方便之处: + +- 每次使用前需要声明,再操作; + +- 很多人一个实体类,对应一个操作类(或DAL、DbContext、Repository); + +本文介绍 BaseEntity 一种极简约的 CRUD 操作方法。 + +# 功能特点 + +- 自动迁移实体结构(CodeFirst),到数据库; + +- 直接操作实体的方法,进行 CRUD 操作; + +- 简化用户定义实体类型,省去主键、常用字段的配置(如CreateTime、UpdateTime); + +- 实现单表、多表查询的软删除逻辑; + +# 声明 + +参考 BaseEntity.cs 源码(约100行),copy 到项目中使用,然后添加 nuget 引用包: + +> dotnet add package FreeSql.Repository + +> dotnet add package FreeSql.Provider.Sqlite + +1、定义一个主键 int 并且自增的实体类型,BaseEntity TKey 指定为 int/long 时,会认为主键是自增; + +```csharp +public class UserGroup : BaseEntity +{ + public string GroupName { get; set; } +} +``` + +如果不想主键是自增键,可以重写属性: + +```csharp +public class UserGroup : BaseEntity +{ + [Column(IsIdentity = false)] + public override int Id { get; set; } + public string GroupName { get; set; } +} +``` +> 有关更多实体的特性配置,请参考资料:https://github.com/2881099/FreeSql/wiki/%e5%ae%9e%e4%bd%93%e7%89%b9%e6%80%a7 + +2、定义一个主键 Guid 的实体类型,保存数据时会自动产生有序不重复的 Guid 值(不用自己指定 Guid.NewGuid()); + +```csharp +public class User : BaseEntity +{ + public string UserName { get; set; } +} +``` + +3、定义多主键的实体类型,可以在 static 构造函数中重写字段名; + +```csharp +public class User2 : BaseEntity +{ + static User2() + { + User2.Orm.CodeFirst.ConfigEntity(t => + { + t.Property(a => a.PkId1).Name("UserId"); + t.Property(a => a.PkId2).Name("Index"); + }); + } + + public string Username { get; set; } +} +``` + + +# CRUD 使用 + +```csharp +//添加 +var item = new UserGroup { GroupName = "组一" }; +item.Insert(); + +//更新 +item.GroupName = "组二"; +item.Update(); + +//添加或更新 +item.Save(); + +//软删除 +item.Delete(); + +//恢复软删除 +item.Restore(); + +//根据主键获取对象 +var item = UserGroup.Find(1); + +//查询数据 +var items = UserGroup.Where(a => a.Id > 10).ToList(); +``` + +实体类型.Select 是一个查询对象,使用方法和 FreeSql.ISelect 一样; + +支持多表查询时,软删除条件会附加在每个表中; + +> 有关更多查询方法,请参考资料:https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2 From 31f1c22aab7d05af36e07eec77a0e2d81fe06907 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 22 Jul 2019 15:10:00 +0800 Subject: [PATCH 0054/1029] update readme --- Examples/base_entity/readme.md | 2 ++ readme.md | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/base_entity/readme.md b/Examples/base_entity/readme.md index 87946f7f..69786f07 100644 --- a/Examples/base_entity/readme.md +++ b/Examples/base_entity/readme.md @@ -8,6 +8,8 @@ - 很多人一个实体类,对应一个操作类(或DAL、DbContext、Repository); +BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用; + 本文介绍 BaseEntity 一种极简约的 CRUD 操作方法。 # 功能特点 diff --git a/readme.md b/readme.md index 89cc00a8..42427188 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,5 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577)。 -据了解,用户使用很少问问题,编码过程中,因业务阻塞,情有可原;因框架使用问题阻塞,得不偿失。我们的口号:做 .net 最方便的 ORM!愿每一位开发者嘴角上扬😏! - 扶摇直上,至强ORM只为自由编码;鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) # Features @@ -19,7 +17,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | | | | - | - | | ![image](https://user-images.githubusercontent.com/16286519/55138232-f5e19e80-516d-11e9-9144-173cc7e52845.png) | [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| ![image](https://user-images.githubusercontent.com/16286519/55138241-faa65280-516d-11e9-8b27-139dea46e4df.png) | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) | +| ![image](https://user-images.githubusercontent.com/16286519/55138241-faa65280-516d-11e9-8b27-139dea46e4df.png) | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | | ![image](https://user-images.githubusercontent.com/16286519/55138263-06921480-516e-11e9-8da9-81f18a18b694.png) | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | | ![image](https://user-images.githubusercontent.com/16286519/55138284-0eea4f80-516e-11e9-8764-29264807f402.png) | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | From 96c7ef3845865dcbd9be2f7d05ba9af3e2cb94dd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 23 Jul 2019 19:50:18 +0800 Subject: [PATCH 0055/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20SqlServer=20?= =?UTF-8?q?IUpdate.ExecuteUpdated=20=E6=8B=BC=E6=8E=A5SQL=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs | 9 +++++++++ FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs | 4 ++-- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 12 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index da93ab7b..a288e048 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index c3bd55bb..200e4fc2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 508bcf13..5d1af530 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.13 + 0.7.15 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index cac3f57b..7d6de208 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -136,7 +136,16 @@ namespace FreeSql.Tests.SqlServer [Fact] public void ExecuteUpdated() { + _sqlserverFixture.SqlServer.Insert().AppendData(new Topic()).ExecuteAffrows(); + _sqlserverFixture.SqlServer.Insert().AppendData(new Topic()).ExecuteAffrows(); + _sqlserverFixture.SqlServer.Insert().AppendData(new Topic()).ExecuteAffrows(); + _sqlserverFixture.SqlServer.Insert().AppendData(new Topic()).ExecuteAffrows(); + var items = _sqlserverFixture.SqlServer.Select().Limit(2).ToList(); + _sqlserverFixture.SqlServer.Update(items).SetRaw("title='test'").ExecuteUpdated(); + + items = _sqlserverFixture.SqlServer.Select().Limit(2).ToList(); + var result = _sqlserverFixture.SqlServer.Update(items).SetRaw("title='test'").ExecuteUpdatedAsync().Result; } [Fact] diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b7d711ee..e9c181df 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index ea19f7f5..168a9740 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 74eb71ae..a128bef8 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 20dee896..fd0976bd 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2d860988..569f9d20 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index 6e91a800..8827213d 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -39,7 +39,7 @@ namespace FreeSql.SqlServer.Curd ++colidx; } - var validx = sql.IndexOf(" WHERE "); + var validx = sql.IndexOf(" \r\nWHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); @@ -82,7 +82,7 @@ namespace FreeSql.SqlServer.Curd ++colidx; } - var validx = sql.IndexOf(" WHERE "); + var validx = sql.IndexOf(" \r\nWHERE "); if (validx == -1) throw new ArgumentException("找不到 WHERE "); sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a76b05ed..bdfecdd7 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 06c1f7b3..931adeb8 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.13 + 0.7.15 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 762bd0df2b4334159c35426da1f2423b3af26b76 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 25 Jul 2019 10:11:50 +0800 Subject: [PATCH 0056/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ToList?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=9F=A5=E8=AF=A2=E8=B5=8B=E5=80=BC?= =?UTF-8?q?string.Empty=E5=90=8E=E4=BA=A7=E7=94=9F=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84SQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 44 ++++++++++++++++++++---- FreeSql/Internal/CommonExpression.cs | 8 ++++- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index fbdda02a..31210d4f 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -13,6 +13,19 @@ using System.Collections; namespace FreeSql.Tests { + public static class SqlFunc + { + public static T TryTo(this string that) + { + return default(T); + } + + public static string FormatDateTime() + { + return ""; + } + } + public class UnitTest1 { @@ -287,17 +300,32 @@ namespace FreeSql.Tests public TaskBuild Parent { get; set; } } - public class SqlFunc - { - public static string FormatDateTime() - { - return ""; - } - } + + void parseExp(object sender, Aop.ParseExpressionEventArgs e) + { + if (e.Expression.NodeType == ExpressionType.Call) + { + var callExp = e.Expression as MethodCallExpression; + if (callExp.Object == null && callExp.Arguments.Any() && callExp.Arguments[0].Type == typeof(string)) + { + if (callExp.Method.Name == "TryTo") + { + e.Result = Expression.Lambda( + typeof(Func<>).MakeGenericType(callExp.Method.GetGenericArguments().FirstOrDefault()), + e.Expression).Compile().DynamicInvoke()?.ToString(); + return; + } + } + } + } [Fact] public void Test1() { + g.sqlite.Aop.ParseExpression += parseExp; + + var sqddddl = g.sqlite.Select().ToSql(t => t.OptionsEntity04 == "1".TryTo()); + var sqksdkfjl = g.sqlite.Select() .LeftJoin(a => a.Templates.Id2 == a.TemplatesId) .LeftJoin(a => a.Parent.Id == a.Id) @@ -809,6 +837,8 @@ namespace FreeSql.Tests { a.Key.tt2, cou1 = a.Count(), + empty = "", + nil = (string)null, arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index cfaf858e..2d7360f5 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -44,7 +44,13 @@ namespace FreeSql.Internal // ccc = "now()", // partby = "sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)" //}),有缺点即 ccc partby 接受类型都是 string,可配合 Convert.ToXxx 类型转换,请看下面的兼容 - parent.DbField = constExp.Type.FullName == "System.String" ? (constExp.Value?.ToString() ?? "NULL") : _common.FormatSql("{0}", constExp?.Value); + if (constExp.Type.FullName == "System.String") + { + var constExpValue = constExp.Value?.ToString() ?? "NULL"; + if (constExpValue == string.Empty) constExpValue = _common.FormatSql("{0}", ""); + parent.DbField = constExpValue; + } else + parent.DbField = _common.FormatSql("{0}", constExp?.Value); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); return false; From f9600d6c76782bd0b84d3e2951584c5be36864fd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 25 Jul 2019 12:43:07 +0800 Subject: [PATCH 0057/1029] =?UTF-8?q?BaseEntity=20+=20=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/BaseEntity.cs | 114 +++++++++-------- Examples/base_entity/BaseEntityUnitOfWork.cs | 124 +++++++++++++++++++ Examples/base_entity/Entities/User.cs | 37 ------ Examples/base_entity/Program.cs | 95 +++++++------- 4 files changed, 230 insertions(+), 140 deletions(-) create mode 100644 Examples/base_entity/BaseEntityUnitOfWork.cs diff --git a/Examples/base_entity/BaseEntity.cs b/Examples/base_entity/BaseEntity.cs index 018c7d58..84df35b2 100644 --- a/Examples/base_entity/BaseEntity.cs +++ b/Examples/base_entity/BaseEntity.cs @@ -2,8 +2,10 @@ using FreeSql.DataAnnotations; using Newtonsoft.Json; using System; +using System.Data; using System.Diagnostics; using System.Linq.Expressions; +using System.Threading.Tasks; [Table(DisableSyncStructure = true)] public abstract class BaseEntity @@ -13,7 +15,7 @@ public abstract class BaseEntity var orm = new FreeSqlBuilder() .UseAutoSyncStructure(true) .UseNoneCommandParameter(true) - .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=2") + .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=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=2") //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=2") @@ -36,71 +38,108 @@ public abstract class BaseEntity /// 逻辑删除 /// public bool IsDeleted { get; set; } + + /// + /// 开启工作单元事务 + /// + /// + /// + public static IUnitOfWork Begin() => Begin(null); + public static IUnitOfWork Begin(IsolationLevel? level) + { + var uow = new BaseEntityUnitOfWork(Orm); + uow.IsolationLevel = level; + return uow; + } + protected static IUnitOfWork CurrentUow => BaseEntityUnitOfWork._asyncUow.Value; } [Table(DisableSyncStructure = true)] public abstract class BaseEntity : BaseEntity where TEntity : class { - public static ISelect Select => Orm.Select().WhereCascade(a => (a as BaseEntity).IsDeleted == false); + public static ISelect Select => Orm.Select() + .WithTransaction(CurrentUow?.GetOrBeginTransaction(false)) + .WhereCascade(a => (a as BaseEntity).IsDeleted == false); public static ISelect Where(Expression> exp) => Select.Where(exp); public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); [JsonIgnore] protected IBaseRepository Repository { get; set; } - bool UpdateIsDeleted(bool value) + async Task UpdateIsDeleted(bool value) { if (this.Repository == null) - return Orm.Update(this as TEntity).Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; + return await Orm.Update(this as TEntity) + .WithTransaction(CurrentUow?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; + this.IsDeleted = value; - return this.Repository.Update(this as TEntity) == 1; + this.Repository.UnitOfWork = CurrentUow; + return await this.Repository.UpdateAsync(this as TEntity) == 1; } /// /// 删除数据 /// /// - public virtual bool Delete() => this.UpdateIsDeleted(true); + public virtual Task Delete() => this.UpdateIsDeleted(true); /// /// 恢复删除的数据 /// /// - public virtual bool Restore() => this.UpdateIsDeleted(false); + public virtual Task Restore() => this.UpdateIsDeleted(false); /// /// 附加实体,在更新数据时,只更新变化的部分 /// - public void Attach() + public TEntity Attach() { - if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.Attach(this as TEntity); + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + var item = this as TEntity; + this.Repository.Attach(item); + return item; } /// /// 更新数据 /// /// - public virtual bool Update() + async public virtual Task Update() { + this.UpdateTime = DateTime.Now; if (this.Repository == null) - return Orm.Update().SetSource(this as TEntity).ExecuteAffrows() == 1; - return this.Repository.Update(this as TEntity) == 1; + return await Orm.Update() + .WithTransaction(CurrentUow?.GetOrBeginTransaction()) + .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; + + this.Repository.UnitOfWork = CurrentUow; + return await this.Repository.UpdateAsync(this as TEntity) == 1; } /// /// 插入数据 /// - public virtual void Insert() + async public virtual Task Insert() { - if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.Insert(this as TEntity); + this.CreateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.UnitOfWork = CurrentUow; + await this.Repository.InsertAsync(this as TEntity); } /// /// 更新或插入 /// /// - public virtual void Save() + async public virtual Task Save() { - if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.InsertOrUpdate(this as TEntity); + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.UnitOfWork = CurrentUow; + await this.Repository.InsertOrUpdateAsync(this as TEntity); } } @@ -125,43 +164,10 @@ public abstract class BaseEntity : BaseEntity where TEnt /// /// /// - public static TEntity Find(TKey id) + async public static Task Find(TKey id) { - var item = Select.WhereDynamic(id).First(); + var item = await Select.WhereDynamic(id).FirstAsync(); (item as BaseEntity)?.Attach(); return item; } -} - -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity : BaseEntity where TEntity : class -{ - - /// - /// 主键1 - /// - [Column(IsPrimary = true)] - public virtual TKey1 PkId1 { get; set; } - /// - /// 主键2 - /// - [Column(IsPrimary = true)] - public virtual TKey2 PkId2 { get; set; } - - /// - /// 根据主键值获取数据 - /// - /// 主键1 - /// 主键2 - /// - public static TEntity Find(TKey1 pkid1, TKey1 pkid2) - { - var item = Select.WhereDynamic(new - { - PkId1 = pkid1, - PkId2 = pkid2 - }).First(); - (item as BaseEntity).Attach(); - return item; - } } \ No newline at end of file diff --git a/Examples/base_entity/BaseEntityUnitOfWork.cs b/Examples/base_entity/BaseEntityUnitOfWork.cs new file mode 100644 index 00000000..0199b2c1 --- /dev/null +++ b/Examples/base_entity/BaseEntityUnitOfWork.cs @@ -0,0 +1,124 @@ +using FreeSql; +using SafeObjectPool; +using System; +using System.Data; +using System.Data.Common; +using System.Threading; + +class BaseEntityUnitOfWork : IUnitOfWork +{ + internal readonly static AsyncLocal _asyncUow = new AsyncLocal(); + + protected IFreeSql _fsql; + protected Object _conn; + protected DbTransaction _tran; + + public BaseEntityUnitOfWork(IFreeSql fsql) + { + _fsql = fsql; + _asyncUow.Value = this; + } + + void ReturnObject() + { + _fsql.Ado.MasterPool.Return(_conn); + _tran = null; + _conn = null; + _asyncUow.Value = null; + } + + + /// + /// 是否启用工作单元 + /// + public bool Enable { get; private set; } = true; + + /// + /// 禁用工作单元 + /// + /// + /// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 + /// + public void Close() + { + if (_tran != null) + throw new Exception("已开启事务,不能禁用工作单元"); + + Enable = false; + } + + public void Open() => + Enable = true; + + public IsolationLevel? IsolationLevel { get; set; } + + public DbTransaction GetOrBeginTransaction(bool isCreate = true) + { + + if (_tran != null) return _tran; + if (isCreate == false) return null; + if (!Enable) return null; + if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); + + _conn = _fsql.Ado.MasterPool.Get(); + try + { + _tran = IsolationLevel == null ? + _conn.Value.BeginTransaction() : + _conn.Value.BeginTransaction(IsolationLevel.Value); + } + catch + { + ReturnObject(); + throw; + } + return _tran; + } + + public void Commit() + { + if (_tran != null) + { + try + { + _tran.Commit(); + } + finally + { + ReturnObject(); + } + } + } + public void Rollback() + { + if (_tran != null) + { + try + { + _tran.Rollback(); + } + finally + { + ReturnObject(); + } + } + } + ~BaseEntityUnitOfWork() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + _isdisposed = true; + try + { + this.Rollback(); + } + finally + { + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Examples/base_entity/Entities/User.cs b/Examples/base_entity/Entities/User.cs index a062d1a0..7db6ab8c 100644 --- a/Examples/base_entity/Entities/User.cs +++ b/Examples/base_entity/Entities/User.cs @@ -10,8 +10,6 @@ public class UserGroup : BaseEntity public string GroupName { get; set; } public List User1s { get; set; } - - public List User2s { get; set; } } public class Role : BaseEntity @@ -54,38 +52,3 @@ public class User1 : BaseEntity /// public string Description { get; set; } } - -public class User2 : BaseEntity -{ - static User2() - { - User2.Orm.CodeFirst.ConfigEntity(t => - { - t.Property(a => a.PkId1).Name("UserId"); - t.Property(a => a.PkId2).Name("Index"); - }); - } - - public int GroupId { get; set; } - public UserGroup Group { get; set; } - - /// - /// 登陆名 - /// - public string Username { get; set; } - - /// - /// 昵称 - /// - public string Nickname { get; set; } - - /// - /// 头像 - /// - public string Avatar { get; set; } - - /// - /// 描述 - /// - public string Description { get; set; } -} \ No newline at end of file diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 7de6d4d4..c09610de 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; namespace base_entity { @@ -6,74 +7,70 @@ namespace base_entity { static void Main(string[] args) { - var ug1 = new UserGroup(); - ug1.GroupName = "分组一"; - ug1.Insert(); + Task.Run(async () => + { + using (var uow = BaseEntity.Begin()) + { + var itt = await UserGroup.Find(1); + } - var ug2 = new UserGroup(); - ug2.GroupName = "分组二"; - ug2.Insert(); + var ug1 = new UserGroup(); + ug1.GroupName = "分组一"; + await ug1.Insert(); - var u1 = new User1(); - var u2 = new User2(); + var ug2 = new UserGroup(); + ug2.GroupName = "分组二"; + await ug2.Insert(); - u1.GroupId = ug1.Id; - u1.Save(); + var u1 = new User1(); - u2.GroupId = ug2.Id; - u2.Save(); + u1.GroupId = ug1.Id; + await u1.Save(); - u1.Delete(); - u1.Restore(); + await u1.Delete(); + await u1.Restore(); - u1.Nickname = "x1"; - u1.Update(); + u1.Nickname = "x1"; + await u1.Update(); - u2.Delete(); - u2.Restore(); + var u11 = await User1.Find(u1.Id); + u11.Description = "备注"; + await u11.Save(); - u2.Username = "x2"; - u2.Update(); + await u11.Delete(); - var u11 = User1.Find(u1.Id); - u11.Description = "备注"; - u11.Save(); + var u11null = User1.Find(u1.Id); - u11.Delete(); + var u11s = User1.Where(a => a.Group.Id == ug1.Id).Limit(10).ToList(); - var u11null = User1.Find(u1.Id); + var u11s2 = User1.Select.LeftJoin((a, b) => a.GroupId == b.Id).Limit(10).ToList(); - var u11s = User1.Where(a => a.Group.Id == ug1.Id).Limit(10).ToList(); - var u22s = User2.Where(a => a.Group.Id == ug2.Id).Limit(10).ToList(); + var ug1s = UserGroup.Select + .IncludeMany(a => a.User1s) + .Limit(10).ToList(); - var u11s2 = User1.Select.LeftJoin((a, b) => a.GroupId == b.Id).Limit(10).ToList(); - var u22s2 = User2.Select.LeftJoin((a, b) => a.GroupId == b.Id).Limit(10).ToList(); + var ug1s2 = UserGroup.Select.Where(a => a.User1s.AsSelect().Any(b => b.Nickname == "x1")).Limit(10).ToList(); - var ug1s = UserGroup.Select - .IncludeMany(a => a.User1s) - .IncludeMany(a => a.User2s) - .Limit(10).ToList(); + var r1 = new Role(); + r1.Id = "管理员"; + await r1.Save(); - var ug1s2 = UserGroup.Select.Where(a => a.User1s.AsSelect().Any(b => b.Nickname == "x1")).Limit(10).ToList(); + var r2 = new Role(); + r2.Id = "超级会员"; + await r2.Save(); - var r1 = new Role(); - r1.Id = "管理员"; - r1.Save(); + var ru1 = new RoleUser1(); + ru1.User1Id = u1.Id; + ru1.RoleId = r1.Id; + await ru1.Save(); - var r2 = new Role(); - r2.Id = "超级会员"; - r2.Save(); + ru1.RoleId = r2.Id; + await ru1.Save(); - var ru1 = new RoleUser1(); - ru1.User1Id = u1.Id; - ru1.RoleId = r1.Id; - ru1.Save(); + var u1roles = User1.Select.IncludeMany(a => a.Roles).ToList(); + var u1roles2 = User1.Select.Where(a => a.Roles.AsSelect().Any(b => b.Id == "xx")).ToList(); - ru1.RoleId = r2.Id; - ru1.Save(); - - var u1roles = User1.Select.IncludeMany(a => a.Roles).ToList(); - var u1roles2 = User1.Select.Where(a => a.Roles.AsSelect().Any(b => b.Id == "xx")).ToList(); + }).Wait(); Console.WriteLine("按任意键结束。。。"); Console.ReadKey(); From fc84f68f3a92513e1c13bc9f3744a82bf67348f6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 25 Jul 2019 16:45:07 +0800 Subject: [PATCH 0058/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20UnitOfWork.C?= =?UTF-8?q?urrent=20=E9=9D=99=E6=80=81=E5=B1=9E=E6=80=A7=EF=BC=8CAsyncLoca?= =?UTF-8?q?l=20=E5=AE=9E=E7=8E=B0=20[NETStandard=202.0]=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/BaseEntity.cs | 18 +-- Examples/base_entity/BaseEntityUnitOfWork.cs | 124 ------------------ FreeSql.DbContext/FreeSql.DbContext.csproj | 62 ++++----- FreeSql.DbContext/FreeSql.DbContext.xml | 13 -- .../Extenssions/DependencyInjection.cs | 11 +- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 69 ++++------ 6 files changed, 69 insertions(+), 228 deletions(-) delete mode 100644 Examples/base_entity/BaseEntityUnitOfWork.cs diff --git a/Examples/base_entity/BaseEntity.cs b/Examples/base_entity/BaseEntity.cs index 84df35b2..a6618026 100644 --- a/Examples/base_entity/BaseEntity.cs +++ b/Examples/base_entity/BaseEntity.cs @@ -47,18 +47,18 @@ public abstract class BaseEntity public static IUnitOfWork Begin() => Begin(null); public static IUnitOfWork Begin(IsolationLevel? level) { - var uow = new BaseEntityUnitOfWork(Orm); + var uow = Orm.CreateUnitOfWork(); uow.IsolationLevel = level; + UnitOfWork.Current.Value = uow; return uow; } - protected static IUnitOfWork CurrentUow => BaseEntityUnitOfWork._asyncUow.Value; } [Table(DisableSyncStructure = true)] public abstract class BaseEntity : BaseEntity where TEntity : class { public static ISelect Select => Orm.Select() - .WithTransaction(CurrentUow?.GetOrBeginTransaction(false)) + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)) .WhereCascade(a => (a as BaseEntity).IsDeleted == false); public static ISelect Where(Expression> exp) => Select.Where(exp); public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); @@ -70,11 +70,11 @@ public abstract class BaseEntity : BaseEntity where TEntity : class { if (this.Repository == null) return await Orm.Update(this as TEntity) - .WithTransaction(CurrentUow?.GetOrBeginTransaction()) + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; this.IsDeleted = value; - this.Repository.UnitOfWork = CurrentUow; + this.Repository.UnitOfWork = UnitOfWork.Current.Value; return await this.Repository.UpdateAsync(this as TEntity) == 1; } /// @@ -109,10 +109,10 @@ public abstract class BaseEntity : BaseEntity where TEntity : class this.UpdateTime = DateTime.Now; if (this.Repository == null) return await Orm.Update() - .WithTransaction(CurrentUow?.GetOrBeginTransaction()) + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; - this.Repository.UnitOfWork = CurrentUow; + this.Repository.UnitOfWork = UnitOfWork.Current.Value; return await this.Repository.UpdateAsync(this as TEntity) == 1; } /// @@ -124,7 +124,7 @@ public abstract class BaseEntity : BaseEntity where TEntity : class if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = CurrentUow; + this.Repository.UnitOfWork = UnitOfWork.Current.Value; await this.Repository.InsertAsync(this as TEntity); } @@ -138,7 +138,7 @@ public abstract class BaseEntity : BaseEntity where TEntity : class if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = CurrentUow; + this.Repository.UnitOfWork = UnitOfWork.Current.Value; await this.Repository.InsertOrUpdateAsync(this as TEntity); } } diff --git a/Examples/base_entity/BaseEntityUnitOfWork.cs b/Examples/base_entity/BaseEntityUnitOfWork.cs deleted file mode 100644 index 0199b2c1..00000000 --- a/Examples/base_entity/BaseEntityUnitOfWork.cs +++ /dev/null @@ -1,124 +0,0 @@ -using FreeSql; -using SafeObjectPool; -using System; -using System.Data; -using System.Data.Common; -using System.Threading; - -class BaseEntityUnitOfWork : IUnitOfWork -{ - internal readonly static AsyncLocal _asyncUow = new AsyncLocal(); - - protected IFreeSql _fsql; - protected Object _conn; - protected DbTransaction _tran; - - public BaseEntityUnitOfWork(IFreeSql fsql) - { - _fsql = fsql; - _asyncUow.Value = this; - } - - void ReturnObject() - { - _fsql.Ado.MasterPool.Return(_conn); - _tran = null; - _conn = null; - _asyncUow.Value = null; - } - - - /// - /// 是否启用工作单元 - /// - public bool Enable { get; private set; } = true; - - /// - /// 禁用工作单元 - /// - /// - /// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 - /// - public void Close() - { - if (_tran != null) - throw new Exception("已开启事务,不能禁用工作单元"); - - Enable = false; - } - - public void Open() => - Enable = true; - - public IsolationLevel? IsolationLevel { get; set; } - - public DbTransaction GetOrBeginTransaction(bool isCreate = true) - { - - if (_tran != null) return _tran; - if (isCreate == false) return null; - if (!Enable) return null; - if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); - - _conn = _fsql.Ado.MasterPool.Get(); - try - { - _tran = IsolationLevel == null ? - _conn.Value.BeginTransaction() : - _conn.Value.BeginTransaction(IsolationLevel.Value); - } - catch - { - ReturnObject(); - throw; - } - return _tran; - } - - public void Commit() - { - if (_tran != null) - { - try - { - _tran.Commit(); - } - finally - { - ReturnObject(); - } - } - } - public void Rollback() - { - if (_tran != null) - { - try - { - _tran.Rollback(); - } - finally - { - ReturnObject(); - } - } - } - ~BaseEntityUnitOfWork() - { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() - { - if (_isdisposed) return; - _isdisposed = true; - try - { - this.Rollback(); - } - finally - { - GC.SuppressFinalize(this); - } - } -} \ No newline at end of file diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 200e4fc2..2355211c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -1,36 +1,36 @@  - - netstandard2.0;net45 - 0.7.15 - true - YeXiangQin - FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. - https://github.com/2881099/FreeSql.DbContext - FreeSql ORM DbContext - git - MIT - $(AssemblyName) - $(AssemblyName) - true - true - + + netstandard2.0;net45 + 0.7.15 + true + YeXiangQin + FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. + https://github.com/2881099/FreeSql.DbContext + FreeSql ORM DbContext + git + MIT + $(AssemblyName) + $(AssemblyName) + true + true + - - FreeSql.DbContext.xml - 3 - + + FreeSql.DbContext.xml + 3 + + + + ns20;netstandard20 + + + + + + + + + - - ns20;netstandard20 - - - - - - - - - - diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index bdb7a92e..e603c8d0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -174,19 +174,6 @@ 开启工作单元 - - - 是否启用工作单元 - - - - - 禁用工作单元 - - - 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 - - 创建普通数据上下文档对象 diff --git a/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs index f37848a8..9781bee9 100644 --- a/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs +++ b/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs @@ -26,16 +26,9 @@ namespace FreeSql services.AddScoped(typeof(DefaultRepository<,>)); if (assemblies?.Any() == true) - { foreach (var asse in assemblies) - { - foreach (var repos in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(IBaseRepository).IsAssignableFrom(a))) - { - - services.AddScoped(repos); - } - } - } + foreach (var repo in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(IBaseRepository).IsAssignableFrom(a))) + services.AddScoped(repo); return services; } diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index a11edae8..493c9bf5 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -2,11 +2,15 @@ using System; using System.Data; using System.Data.Common; +using System.Threading; namespace FreeSql { - class UnitOfWork : IUnitOfWork + public class UnitOfWork : IUnitOfWork { +#if ns20 + public static readonly AsyncLocal Current = new AsyncLocal(); +#endif protected IFreeSql _fsql; protected Object _conn; @@ -15,6 +19,9 @@ namespace FreeSql public UnitOfWork(IFreeSql fsql) { _fsql = fsql; +#if ns20 + Current.Value = this; +#endif } void ReturnObject() @@ -22,30 +29,20 @@ namespace FreeSql _fsql.Ado.MasterPool.Return(_conn); _tran = null; _conn = null; +#if ns20 + Current.Value = null; +#endif } - - /// - /// 是否启用工作单元 - /// public bool Enable { get; private set; } = true; - /// - /// 禁用工作单元 - /// - /// - /// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 - /// public void Close() { if (_tran != null) - { throw new Exception("已开启事务,不能禁用工作单元"); - } Enable = false; } - public void Open() { Enable = true; @@ -55,7 +52,6 @@ namespace FreeSql public DbTransaction GetOrBeginTransaction(bool isCreate = true) { - if (_tran != null) return _tran; if (isCreate == false) return null; if (!Enable) return null; @@ -78,30 +74,24 @@ namespace FreeSql public void Commit() { - if (_tran != null) + try { - try - { - _tran.Commit(); - } - finally - { - ReturnObject(); - } + if (_tran != null) _tran.Commit(); + } + finally + { + ReturnObject(); } } public void Rollback() { - if (_tran != null) + try { - try - { - _tran.Rollback(); - } - finally - { - ReturnObject(); - } + if (_tran != null) _tran.Rollback(); + } + finally + { + ReturnObject(); } } ~UnitOfWork() @@ -112,15 +102,10 @@ namespace FreeSql public void Dispose() { if (_isdisposed) return; - try - { - this.Rollback(); - } - finally - { - _isdisposed = true; - GC.SuppressFinalize(this); - } + _isdisposed = true; + this.Rollback(); + this.Close(); + GC.SuppressFinalize(this); } } } From 380534dfd54284d5b81d5d5aafe7779fc1dbf7e8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 25 Jul 2019 17:14:44 +0800 Subject: [PATCH 0059/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20CodeFirst=20?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A=E5=88=B0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=EF=BC=8C=E7=BB=A7=E6=89=BF=E7=9A=84?= =?UTF-8?q?=E5=9F=BA=E7=B1=BB=E6=9C=AA=E7=94=9F=E6=95=88=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/base_entity.csproj | 4 + Examples/base_entity/base_entity.xml | 101 ++++++++++++++++++++++++ FreeSql/Internal/CommonUtils.cs | 2 +- 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 Examples/base_entity/base_entity.xml diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index f5ecc34b..55a58ed3 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -5,6 +5,10 @@ netcoreapp2.2 + + C:\Users\28810\Desktop\github\FreeSql\Examples\base_entity\base_entity.xml + + diff --git a/Examples/base_entity/base_entity.xml b/Examples/base_entity/base_entity.xml new file mode 100644 index 00000000..90fc0a20 --- /dev/null +++ b/Examples/base_entity/base_entity.xml @@ -0,0 +1,101 @@ + + + + base_entity + + + + + 创建时间 + + + + + 更新时间 + + + + + 逻辑删除 + + + + + 开启工作单元事务 + + + + + + + 删除数据 + + + + + + 恢复删除的数据 + + + + + + 附加实体,在更新数据时,只更新变化的部分 + + + + + 更新数据 + + + + + + 插入数据 + + + + + 更新或插入 + + + + + + 主键 + + + + + 根据主键值获取数据 + + + + + + + 组名 + + + + + 登陆名 + + + + + 昵称 + + + + + 头像 + + + + + 描述 + + + + diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index d3ab7304..39aa7f7a 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -286,7 +286,6 @@ namespace FreeSql.Internal if (File.Exists(xmlPath) == false) return null; var dic = new Dictionary(); - var className = type.IsNested ? $"{type.Namespace}.{type.DeclaringType.Name}.{type.Name}" : $"{type.Namespace}.{type.Name}"; var sReader = new StringReader(File.ReadAllText(xmlPath)); using (var xmlReader = XmlReader.Create(sReader)) { @@ -304,6 +303,7 @@ namespace FreeSql.Internal var props = type.GetProperties(); foreach (var prop in props) { + var className = (prop.DeclaringType.IsNested ? $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.DeclaringType.Name}.{prop.DeclaringType.Name}" : $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.Name}").Trim('.'); var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); if (node == null) continue; var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); From 7460ffffaa315da938190e4a72511c080efd4cac Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 25 Jul 2019 17:41:55 +0800 Subject: [PATCH 0060/1029] v0.7.16 --- Examples/base_entity/BaseEntity.cs | 9 ++++----- Examples/base_entity/Program.cs | 3 ++- Examples/base_entity/base_entity.xml | 1 - .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Examples/base_entity/BaseEntity.cs b/Examples/base_entity/BaseEntity.cs index a6618026..e6763f88 100644 --- a/Examples/base_entity/BaseEntity.cs +++ b/Examples/base_entity/BaseEntity.cs @@ -42,7 +42,6 @@ public abstract class BaseEntity /// /// 开启工作单元事务 /// - /// /// public static IUnitOfWork Begin() => Begin(null); public static IUnitOfWork Begin(IsolationLevel? level) @@ -118,28 +117,28 @@ public abstract class BaseEntity : BaseEntity where TEntity : class /// /// 插入数据 /// - async public virtual Task Insert() + public virtual Task Insert() { this.CreateTime = DateTime.Now; if (this.Repository == null) this.Repository = Orm.GetRepository(); this.Repository.UnitOfWork = UnitOfWork.Current.Value; - await this.Repository.InsertAsync(this as TEntity); + return this.Repository.InsertAsync(this as TEntity); } /// /// 更新或插入 /// /// - async public virtual Task Save() + public virtual Task Save() { this.UpdateTime = DateTime.Now; if (this.Repository == null) this.Repository = Orm.GetRepository(); this.Repository.UnitOfWork = UnitOfWork.Current.Value; - await this.Repository.InsertOrUpdateAsync(this as TEntity); + return this.Repository.InsertOrUpdateAsync(this as TEntity); } } diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index c09610de..0139cd32 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -11,7 +11,8 @@ namespace base_entity { using (var uow = BaseEntity.Begin()) { - var itt = await UserGroup.Find(1); + var id = (await new User1().Save()).Id; + uow.Commit(); } var ug1 = new UserGroup(); diff --git a/Examples/base_entity/base_entity.xml b/Examples/base_entity/base_entity.xml index 90fc0a20..f138510a 100644 --- a/Examples/base_entity/base_entity.xml +++ b/Examples/base_entity/base_entity.xml @@ -23,7 +23,6 @@ 开启工作单元事务 - diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a288e048..7bb704a8 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2355211c..331aa1b2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5d1af530..25c1c69f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.15 + 0.7.16 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e9c181df..92092bc0 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 168a9740..29274716 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a128bef8..2f8833ba 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fd0976bd..2f610bb1 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 569f9d20..f0f6b28e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index bdfecdd7..d84f4d53 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 931adeb8..f8441f7d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.15 + 0.7.16 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 4609c910dde0d045e536892216c8d4ce0030311d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 26 Jul 2019 14:30:03 +0800 Subject: [PATCH 0061/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IUpdate.Set?= =?UTF-8?q?=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E4=BC=A0=E5=85=A5=E5=8C=BF?= =?UTF-8?q?=E5=90=8D=E7=B1=BB=E6=9B=B4=E6=96=B0=E5=A4=9A=E4=B8=AA=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/BaseEntity.cs | 1 - FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 10 +++- FreeSql/FreeSql.xml | 2 +- FreeSql/Interface/Curd/IUpdate.cs | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 52 ++++++++++++------- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/Examples/base_entity/BaseEntity.cs b/Examples/base_entity/BaseEntity.cs index e6763f88..54201ec4 100644 --- a/Examples/base_entity/BaseEntity.cs +++ b/Examples/base_entity/BaseEntity.cs @@ -48,7 +48,6 @@ public abstract class BaseEntity { var uow = Orm.CreateUnitOfWork(); uow.IsolationLevel = level; - UnitOfWork.Current.Value = uow; return uow; } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 31210d4f..1a384f60 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -404,7 +404,7 @@ namespace FreeSql.Tests var tbid = g.sqlite.Select().First()?.Id ?? Guid.Empty; var testarray = new[] { 1, 2, 3 }; - var tbidsql = g.sqlite.Update().Where(a => a.Id == tbid) + var tbidsql1 = g.sqlite.Update().Where(a => a.Id == tbid) .Set(a => new TaskBuild { FileName = "111", @@ -412,6 +412,14 @@ namespace FreeSql.Tests OptionsEntity02 = false, OptionsEntity04 = testarray[0] }).ToSql(); + var tbidsql2 = g.sqlite.Update().Where(a => a.Id == tbid) + .Set(a => new + { + FileName = "111", + TaskName = a.TaskName + "333", + OptionsEntity02 = false, + OptionsEntity04 = testarray[0] + }).ToSql(); var dkdkdkd = g.oracle.Select().ToList(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b7748311..e03bc565 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1568,7 +1568,7 @@ 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 - 指定更新,格式:Set(a => new { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 6e546d4d..26f11dd8 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -77,7 +77,7 @@ namespace FreeSql /// /// 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 /// - /// 指定更新,格式:Set(a => new { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + /// 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' /// /// /// diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 80da28c1..fa470488 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -435,29 +435,41 @@ namespace FreeSql.Internal.CommonProvider { var body = exp?.Body; var nodeType = body?.NodeType; - if (nodeType == ExpressionType.Equal) + switch (nodeType) { - _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp, null)); - return this; - } - - if (nodeType == ExpressionType.MemberInit) - { - var initExp = body as MemberInitExpression; - if (initExp.Bindings?.Count > 0) - { - for (var a = 0; a < initExp.Bindings.Count; a++) + case ExpressionType.Equal: + _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp, null)); + return this; + case ExpressionType.MemberInit: + var initExp = body as MemberInitExpression; + if (initExp.Bindings?.Count > 0) { - var initAssignExp = (initExp.Bindings[a] as MemberAssignment); - if (initAssignExp == null) continue; - var memberName = initExp.Bindings[a].Member.Name; - if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; - if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); - var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { }); - _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); + for (var a = 0; a < initExp.Bindings.Count; a++) + { + var initAssignExp = (initExp.Bindings[a] as MemberAssignment); + if (initAssignExp == null) continue; + var memberName = initExp.Bindings[a].Member.Name; + if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; + if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); + var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { }); + _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); + } } - } - return this; + return this; + case ExpressionType.New: + var newExp = body as NewExpression; + if (newExp.Members?.Count > 0) + { + for (var a = 0; a < newExp.Members.Count; a++) + { + var memberName = newExp.Members[a].Name; + if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; + if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); + var memberValue = _commonExpression.ExpressionLambdaToSql(newExp.Arguments[a], new CommonExpression.ExpTSC { }); + _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); + } + } + return this; } if (body is BinaryExpression == false && nodeType != ExpressionType.Call) return this; From 256963907e65aa496a7d116f30809d72222c6a13 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 29 Jul 2019 10:27:39 +0800 Subject: [PATCH 0062/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E4=B8=AD=E4=B8=8D=E8=83=BD=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20c#=20=E5=87=BD=E6=95=B0=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=20>=20=E5=A6=82=EF=BC=9Awhere(a=20=3D>=20HttpContext.Session.G?= =?UTF-8?q?etString("UserID")=20=3D=3D=20a.UserId)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 4 +++- .../Extensions/LambadaExpressionExtensions.cs | 18 ++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 7 ++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 1a384f60..5bd98ca9 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -322,10 +322,12 @@ namespace FreeSql.Tests [Fact] public void Test1() { - g.sqlite.Aop.ParseExpression += parseExp; + //g.sqlite.Aop.ParseExpression += parseExp; var sqddddl = g.sqlite.Select().ToSql(t => t.OptionsEntity04 == "1".TryTo()); + //var sqdddd2 = g.sqlite.Select().ToSql(t => t.OptionsEntity04 == t.NamespaceName.TryTo()); + var sqksdkfjl = g.sqlite.Select() .LeftJoin(a => a.Templates.Id2 == a.TemplatesId) .LeftJoin(a => a.Parent.Id == a.Id) diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 9ad328ee..1dd7864e 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -86,6 +86,13 @@ namespace System.Linq.Expressions var body = Expression.Not(exp.Body); return Expression.Lambda>(body, candidateExpr); } + + internal static bool IsParameter(this Expression exp) + { + var test = new TextParameterExpressionVisitor(); + test.Visit(exp); + return test.Result; + } } internal class NewExpressionVisitor : ExpressionVisitor @@ -102,4 +109,15 @@ namespace System.Linq.Expressions protected override Expression VisitParameter(ParameterExpression node) => node == _oldParameter ? this._newParameter : node; } + + internal class TextParameterExpressionVisitor : ExpressionVisitor + { + public bool Result { get; private set; } + + protected override Expression VisitParameter(ParameterExpression node) + { + if (!Result) Result = true; + return node; + } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 2d7360f5..deb5cb77 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -837,6 +837,7 @@ namespace FreeSql.Internal //} var other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; + if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType); throw new Exception($"未实现函数表达式 {exp3} 解析"); case ExpressionType.Parameter: case ExpressionType.MemberAccess: @@ -1097,7 +1098,11 @@ namespace FreeSql.Internal case ExpressionType.Coalesce: return _common.IsNull(ExpressionLambdaToSql(expBinary.Left, tsc), ExpressionLambdaToSql(expBinary.Right, tsc)); } - if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false) return ""; + if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false) + { + if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType); + return ""; + } return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc); } From 8573f642d5458bba530a049462815c0ace9619ab Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 29 Jul 2019 11:54:43 +0800 Subject: [PATCH 0063/1029] add Examples: base_entity_net45 --- Examples/base_entity_net45/App.config | 6 + Examples/base_entity_net45/BaseEntitySync.cs | 153 ++++++++++++++++++ Examples/base_entity_net45/Program.cs | 15 ++ .../Properties/AssemblyInfo.cs | 36 +++++ .../base_entity_net45.csproj | 73 +++++++++ FreeSql.sln | 17 +- 6 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 Examples/base_entity_net45/App.config create mode 100644 Examples/base_entity_net45/BaseEntitySync.cs create mode 100644 Examples/base_entity_net45/Program.cs create mode 100644 Examples/base_entity_net45/Properties/AssemblyInfo.cs create mode 100644 Examples/base_entity_net45/base_entity_net45.csproj diff --git a/Examples/base_entity_net45/App.config b/Examples/base_entity_net45/App.config new file mode 100644 index 00000000..88fa4027 --- /dev/null +++ b/Examples/base_entity_net45/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Examples/base_entity_net45/BaseEntitySync.cs b/Examples/base_entity_net45/BaseEntitySync.cs new file mode 100644 index 00000000..112c26b1 --- /dev/null +++ b/Examples/base_entity_net45/BaseEntitySync.cs @@ -0,0 +1,153 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Data; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity +{ + private static Lazy _ormLazy = new Lazy(() => + { + var orm = new FreeSqlBuilder() + .UseAutoSyncStructure(true) + .UseNoneCommandParameter(true) + .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=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=2") + //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=2") + //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") + .Build(); + orm.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); + return orm; + }); + public static IFreeSql Orm => _ormLazy.Value; + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + /// + /// 更新时间 + /// + public DateTime UpdateTime { get; set; } + /// + /// 逻辑删除 + /// + public bool IsDeleted { get; set; } +} + +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity : BaseEntity where TEntity : class +{ + public static ISelect Select => Orm.Select() + .WhereCascade(a => (a as BaseEntity).IsDeleted == false); + public static ISelect Where(Expression> exp) => Select.Where(exp); + public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); + + [JsonIgnore] + protected IBaseRepository Repository { get; set; } + + bool UpdateIsDeleted(bool value) + { + if (this.Repository == null) + return Orm.Update(this as TEntity) + .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; + + this.IsDeleted = value; + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 删除数据 + /// + /// + public virtual bool Delete() => this.UpdateIsDeleted(true); + /// + /// 恢复删除的数据 + /// + /// + public virtual bool Restore() => this.UpdateIsDeleted(false); + + /// + /// 附加实体,在更新数据时,只更新变化的部分 + /// + public TEntity Attach() + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + var item = this as TEntity; + this.Repository.Attach(item); + return item; + } + /// + /// 更新数据 + /// + /// + public virtual bool Update() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + return Orm.Update() + .SetSource(this as TEntity).ExecuteAffrows() == 1; + + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 插入数据 + /// + public virtual TEntity Insert() + { + this.CreateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + return this.Repository.Insert(this as TEntity); + } + + /// + /// 更新或插入 + /// + /// + public virtual TEntity Save() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + return this.Repository.InsertOrUpdate(this as TEntity); + } +} + +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity : BaseEntity where TEntity : class +{ + static BaseEntity() + { + var tkeyType = typeof(TKey)?.NullableTypeOrThis(); + if (tkeyType == typeof(int) || tkeyType == typeof(long)) + Orm.CodeFirst.ConfigEntity(typeof(TEntity), + t => t.Property("Id").IsIdentity(true)); + } + + /// + /// 主键 + /// + public virtual TKey Id { get; set; } + + /// + /// 根据主键值获取数据 + /// + /// + /// + public static TEntity Find(TKey id) + { + var item = Select.WhereDynamic(id).First(); + (item as BaseEntity)?.Attach(); + return item; + } +} \ No newline at end of file diff --git a/Examples/base_entity_net45/Program.cs b/Examples/base_entity_net45/Program.cs new file mode 100644 index 00000000..468b7804 --- /dev/null +++ b/Examples/base_entity_net45/Program.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace base_entity_net45 +{ + class Program + { + static void Main(string[] args) + { + } + } +} diff --git a/Examples/base_entity_net45/Properties/AssemblyInfo.cs b/Examples/base_entity_net45/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..6fa2e439 --- /dev/null +++ b/Examples/base_entity_net45/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("base_entity_net45")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("base_entity_net45")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("7e091544-ec38-4a41-a3be-bdc693070be7")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Examples/base_entity_net45/base_entity_net45.csproj b/Examples/base_entity_net45/base_entity_net45.csproj new file mode 100644 index 00000000..474dc221 --- /dev/null +++ b/Examples/base_entity_net45/base_entity_net45.csproj @@ -0,0 +1,73 @@ + + + + + Debug + AnyCPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7} + Exe + base_entity_net45 + base_entity_net45 + v4.5.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + {82885c27-23c8-4a6e-92cf-80fe61a041e1} + FreeSql.DbContext + + + {af9c50ec-6eb6-494b-9b3b-7edba6fd0ebb} + FreeSql + + + {559b6369-1868-4a06-a590-f80ba7b80a1b} + FreeSql.Provider.Sqlite + + + + + 12.0.2 + + + + \ No newline at end of file diff --git a/FreeSql.sln b/FreeSql.sln index 749a39d2..868aa88e 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -54,7 +54,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.PerformanceTe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.MySqlConnector", "FreeSql.Tests\FreeSql.Tests.Provider.MySqlConnector\FreeSql.Tests.Provider.MySqlConnector.csproj", "{0F45294A-34FF-4FB8-A046-20E09E3A4D5C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "base_entity", "Examples\base_entity\base_entity.csproj", "{D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "base_entity", "Examples\base_entity\base_entity.csproj", "{D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "base_entity_net45", "Examples\base_entity_net45\base_entity_net45.csproj", "{7E091544-EC38-4A41-A3BE-BDC693070BE7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -318,6 +320,18 @@ Global {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x64.Build.0 = Release|Any CPU {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x86.ActiveCfg = Release|Any CPU {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x86.Build.0 = Release|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|x64.ActiveCfg = Debug|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|x64.Build.0 = Debug|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|x86.ActiveCfg = Debug|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|x86.Build.0 = Debug|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|Any CPU.Build.0 = Release|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|x64.ActiveCfg = Release|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|x64.Build.0 = Release|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|x86.ActiveCfg = Release|Any CPU + {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -337,6 +351,7 @@ Global {690F89E0-A721-423F-8F5D-D262F73235EA} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {7E091544-EC38-4A41-A3BE-BDC693070BE7} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} From 5fc603a18b793a040e2b1fd6ccf26826ac14c284 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 29 Jul 2019 15:35:04 +0800 Subject: [PATCH 0064/1029] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20FreeSql.Extensio?= =?UTF-8?q?ns.BaseEntity=20=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/BaseEntity.cs | 171 -------------- Examples/base_entity/Program.cs | 34 +-- Examples/base_entity/base_entity.csproj | 1 + Examples/base_entity/base_entity.xml | 67 ------ Examples/base_entity/readme.md | 23 +- Examples/base_entity_net45/App.config | 6 - Examples/base_entity_net45/BaseEntitySync.cs | 153 ------------- Examples/base_entity_net45/Program.cs | 15 -- .../Properties/AssemblyInfo.cs | 36 --- .../base_entity_net45.csproj | 73 ------ .../BaseEntity.cs | 71 ++++++ .../BaseEntityAsync.cs | 121 ++++++++++ .../BaseEntityAsyncTKey.cs | 44 ++++ .../BaseEntitySync.cs | 80 +++++++ .../BaseEntitySyncTKey.cs | 56 +++++ .../FreeSql.Extensions.BaseEntity.csproj | 28 +++ .../FreeSql.Extensions.BaseEntity.xml | 212 ++++++++++++++++++ .../FreeSql.Extensions.BaseEntity/readme.md | 92 ++++++++ FreeSql.sln | 28 +-- 19 files changed, 740 insertions(+), 571 deletions(-) delete mode 100644 Examples/base_entity/BaseEntity.cs delete mode 100644 Examples/base_entity_net45/App.config delete mode 100644 Examples/base_entity_net45/BaseEntitySync.cs delete mode 100644 Examples/base_entity_net45/Program.cs delete mode 100644 Examples/base_entity_net45/Properties/AssemblyInfo.cs delete mode 100644 Examples/base_entity_net45/base_entity_net45.csproj create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsyncTKey.cs create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySync.cs create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySyncTKey.cs create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/readme.md diff --git a/Examples/base_entity/BaseEntity.cs b/Examples/base_entity/BaseEntity.cs deleted file mode 100644 index 54201ec4..00000000 --- a/Examples/base_entity/BaseEntity.cs +++ /dev/null @@ -1,171 +0,0 @@ -using FreeSql; -using FreeSql.DataAnnotations; -using Newtonsoft.Json; -using System; -using System.Data; -using System.Diagnostics; -using System.Linq.Expressions; -using System.Threading.Tasks; - -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity -{ - private static Lazy _ormLazy = new Lazy(() => - { - var orm = new FreeSqlBuilder() - .UseAutoSyncStructure(true) - .UseNoneCommandParameter(true) - .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=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=2") - //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=2") - //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") - .Build(); - orm.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); - return orm; - }); - public static IFreeSql Orm => _ormLazy.Value; - - /// - /// 创建时间 - /// - public DateTime CreateTime { get; set; } - /// - /// 更新时间 - /// - public DateTime UpdateTime { get; set; } - /// - /// 逻辑删除 - /// - public bool IsDeleted { get; set; } - - /// - /// 开启工作单元事务 - /// - /// - public static IUnitOfWork Begin() => Begin(null); - public static IUnitOfWork Begin(IsolationLevel? level) - { - var uow = Orm.CreateUnitOfWork(); - uow.IsolationLevel = level; - return uow; - } -} - -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity : BaseEntity where TEntity : class -{ - public static ISelect Select => Orm.Select() - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)) - .WhereCascade(a => (a as BaseEntity).IsDeleted == false); - public static ISelect Where(Expression> exp) => Select.Where(exp); - public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); - - [JsonIgnore] - protected IBaseRepository Repository { get; set; } - - async Task UpdateIsDeleted(bool value) - { - if (this.Repository == null) - return await Orm.Update(this as TEntity) - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) - .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; - - this.IsDeleted = value; - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return await this.Repository.UpdateAsync(this as TEntity) == 1; - } - /// - /// 删除数据 - /// - /// - public virtual Task Delete() => this.UpdateIsDeleted(true); - /// - /// 恢复删除的数据 - /// - /// - public virtual Task Restore() => this.UpdateIsDeleted(false); - - /// - /// 附加实体,在更新数据时,只更新变化的部分 - /// - public TEntity Attach() - { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - var item = this as TEntity; - this.Repository.Attach(item); - return item; - } - /// - /// 更新数据 - /// - /// - async public virtual Task Update() - { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - return await Orm.Update() - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) - .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; - - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return await this.Repository.UpdateAsync(this as TEntity) == 1; - } - /// - /// 插入数据 - /// - public virtual Task Insert() - { - this.CreateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return this.Repository.InsertAsync(this as TEntity); - } - - /// - /// 更新或插入 - /// - /// - public virtual Task Save() - { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return this.Repository.InsertOrUpdateAsync(this as TEntity); - } -} - -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity : BaseEntity where TEntity : class -{ - static BaseEntity() - { - var tkeyType = typeof(TKey)?.NullableTypeOrThis(); - if (tkeyType == typeof(int) || tkeyType == typeof(long)) - Orm.CodeFirst.ConfigEntity(typeof(TEntity), - t => t.Property("Id").IsIdentity(true)); - } - - /// - /// 主键 - /// - public virtual TKey Id { get; set; } - - /// - /// 根据主键值获取数据 - /// - /// - /// - async public static Task Find(TKey id) - { - var item = await Select.WhereDynamic(id).FirstAsync(); - (item as BaseEntity)?.Attach(); - return item; - } -} \ No newline at end of file diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 0139cd32..76297250 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -7,39 +7,45 @@ namespace base_entity { static void Main(string[] args) { + BaseEntity.Initialization(new FreeSql.FreeSqlBuilder() + .UseAutoSyncStructure(true) + .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=5") + .Build()); + Task.Run(async () => { using (var uow = BaseEntity.Begin()) { - var id = (await new User1().Save()).Id; + var id = (await new User1().SaveAsync()).Id; uow.Commit(); } var ug1 = new UserGroup(); ug1.GroupName = "分组一"; - await ug1.Insert(); + await ug1.InsertAsync(); var ug2 = new UserGroup(); ug2.GroupName = "分组二"; - await ug2.Insert(); + await ug2.InsertAsync(); var u1 = new User1(); u1.GroupId = ug1.Id; - await u1.Save(); + await u1.SaveAsync(); - await u1.Delete(); - await u1.Restore(); + await u1.DeleteAsync(); + await u1.RestoreAsync(); u1.Nickname = "x1"; - await u1.Update(); + await u1.UpdateAsync(); - var u11 = await User1.Find(u1.Id); + var u11 = await User1.FindAsync(u1.Id); u11.Description = "备注"; - await u11.Save(); + await u11.SaveAsync(); - await u11.Delete(); + await u11.DeleteAsync(); + var slslsl = Newtonsoft.Json.JsonConvert.SerializeObject(u1); var u11null = User1.Find(u1.Id); var u11s = User1.Where(a => a.Group.Id == ug1.Id).Limit(10).ToList(); @@ -54,19 +60,19 @@ namespace base_entity var r1 = new Role(); r1.Id = "管理员"; - await r1.Save(); + await r1.SaveAsync(); var r2 = new Role(); r2.Id = "超级会员"; - await r2.Save(); + await r2.SaveAsync(); var ru1 = new RoleUser1(); ru1.User1Id = u1.Id; ru1.RoleId = r1.Id; - await ru1.Save(); + await ru1.SaveAsync(); ru1.RoleId = r2.Id; - await ru1.Save(); + await ru1.SaveAsync(); var u1roles = User1.Select.IncludeMany(a => a.Roles).ToList(); var u1roles2 = User1.Select.Where(a => a.Roles.AsSelect().Any(b => b.Id == "xx")).ToList(); diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index 55a58ed3..c05b214a 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -14,6 +14,7 @@ + diff --git a/Examples/base_entity/base_entity.xml b/Examples/base_entity/base_entity.xml index f138510a..682b4b8a 100644 --- a/Examples/base_entity/base_entity.xml +++ b/Examples/base_entity/base_entity.xml @@ -4,73 +4,6 @@ base_entity - - - 创建时间 - - - - - 更新时间 - - - - - 逻辑删除 - - - - - 开启工作单元事务 - - - - - - 删除数据 - - - - - - 恢复删除的数据 - - - - - - 附加实体,在更新数据时,只更新变化的部分 - - - - - 更新数据 - - - - - - 插入数据 - - - - - 更新或插入 - - - - - - 主键 - - - - - 根据主键值获取数据 - - - - 组名 diff --git a/Examples/base_entity/readme.md b/Examples/base_entity/readme.md index 69786f07..a9ace8ac 100644 --- a/Examples/base_entity/readme.md +++ b/Examples/base_entity/readme.md @@ -24,9 +24,7 @@ BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多 # 声明 -参考 BaseEntity.cs 源码(约100行),copy 到项目中使用,然后添加 nuget 引用包: - -> dotnet add package FreeSql.Repository +> dotnet add package FreeSql.Extensions.BaseEntity > dotnet add package FreeSql.Provider.Sqlite @@ -60,25 +58,6 @@ public class User : BaseEntity } ``` -3、定义多主键的实体类型,可以在 static 构造函数中重写字段名; - -```csharp -public class User2 : BaseEntity -{ - static User2() - { - User2.Orm.CodeFirst.ConfigEntity(t => - { - t.Property(a => a.PkId1).Name("UserId"); - t.Property(a => a.PkId2).Name("Index"); - }); - } - - public string Username { get; set; } -} -``` - - # CRUD 使用 ```csharp diff --git a/Examples/base_entity_net45/App.config b/Examples/base_entity_net45/App.config deleted file mode 100644 index 88fa4027..00000000 --- a/Examples/base_entity_net45/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Examples/base_entity_net45/BaseEntitySync.cs b/Examples/base_entity_net45/BaseEntitySync.cs deleted file mode 100644 index 112c26b1..00000000 --- a/Examples/base_entity_net45/BaseEntitySync.cs +++ /dev/null @@ -1,153 +0,0 @@ -using FreeSql; -using FreeSql.DataAnnotations; -using Newtonsoft.Json; -using System; -using System.Data; -using System.Diagnostics; -using System.Linq.Expressions; -using System.Threading; -using System.Threading.Tasks; - -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity -{ - private static Lazy _ormLazy = new Lazy(() => - { - var orm = new FreeSqlBuilder() - .UseAutoSyncStructure(true) - .UseNoneCommandParameter(true) - .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=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=2") - //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=2") - //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") - .Build(); - orm.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); - return orm; - }); - public static IFreeSql Orm => _ormLazy.Value; - - /// - /// 创建时间 - /// - public DateTime CreateTime { get; set; } - /// - /// 更新时间 - /// - public DateTime UpdateTime { get; set; } - /// - /// 逻辑删除 - /// - public bool IsDeleted { get; set; } -} - -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity : BaseEntity where TEntity : class -{ - public static ISelect Select => Orm.Select() - .WhereCascade(a => (a as BaseEntity).IsDeleted == false); - public static ISelect Where(Expression> exp) => Select.Where(exp); - public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); - - [JsonIgnore] - protected IBaseRepository Repository { get; set; } - - bool UpdateIsDeleted(bool value) - { - if (this.Repository == null) - return Orm.Update(this as TEntity) - .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; - - this.IsDeleted = value; - return this.Repository.Update(this as TEntity) == 1; - } - /// - /// 删除数据 - /// - /// - public virtual bool Delete() => this.UpdateIsDeleted(true); - /// - /// 恢复删除的数据 - /// - /// - public virtual bool Restore() => this.UpdateIsDeleted(false); - - /// - /// 附加实体,在更新数据时,只更新变化的部分 - /// - public TEntity Attach() - { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - var item = this as TEntity; - this.Repository.Attach(item); - return item; - } - /// - /// 更新数据 - /// - /// - public virtual bool Update() - { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - return Orm.Update() - .SetSource(this as TEntity).ExecuteAffrows() == 1; - - return this.Repository.Update(this as TEntity) == 1; - } - /// - /// 插入数据 - /// - public virtual TEntity Insert() - { - this.CreateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - return this.Repository.Insert(this as TEntity); - } - - /// - /// 更新或插入 - /// - /// - public virtual TEntity Save() - { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - return this.Repository.InsertOrUpdate(this as TEntity); - } -} - -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity : BaseEntity where TEntity : class -{ - static BaseEntity() - { - var tkeyType = typeof(TKey)?.NullableTypeOrThis(); - if (tkeyType == typeof(int) || tkeyType == typeof(long)) - Orm.CodeFirst.ConfigEntity(typeof(TEntity), - t => t.Property("Id").IsIdentity(true)); - } - - /// - /// 主键 - /// - public virtual TKey Id { get; set; } - - /// - /// 根据主键值获取数据 - /// - /// - /// - public static TEntity Find(TKey id) - { - var item = Select.WhereDynamic(id).First(); - (item as BaseEntity)?.Attach(); - return item; - } -} \ No newline at end of file diff --git a/Examples/base_entity_net45/Program.cs b/Examples/base_entity_net45/Program.cs deleted file mode 100644 index 468b7804..00000000 --- a/Examples/base_entity_net45/Program.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace base_entity_net45 -{ - class Program - { - static void Main(string[] args) - { - } - } -} diff --git a/Examples/base_entity_net45/Properties/AssemblyInfo.cs b/Examples/base_entity_net45/Properties/AssemblyInfo.cs deleted file mode 100644 index 6fa2e439..00000000 --- a/Examples/base_entity_net45/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的一般信息由以下 -// 控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("base_entity_net45")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("base_entity_net45")] -[assembly: AssemblyCopyright("Copyright © 2019")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 会使此程序集中的类型 -//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 -//请将此类型的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("7e091544-ec38-4a41-a3be-bdc693070be7")] - -// 程序集的版本信息由下列四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 -// 方法是按如下所示使用“*”: : -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Examples/base_entity_net45/base_entity_net45.csproj b/Examples/base_entity_net45/base_entity_net45.csproj deleted file mode 100644 index 474dc221..00000000 --- a/Examples/base_entity_net45/base_entity_net45.csproj +++ /dev/null @@ -1,73 +0,0 @@ - - - - - Debug - AnyCPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7} - Exe - base_entity_net45 - base_entity_net45 - v4.5.2 - 512 - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - {82885c27-23c8-4a6e-92cf-80fe61a041e1} - FreeSql.DbContext - - - {af9c50ec-6eb6-494b-9b3b-7edba6fd0ebb} - FreeSql - - - {559b6369-1868-4a06-a590-f80ba7b80a1b} - FreeSql.Provider.Sqlite - - - - - 12.0.2 - - - - \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs new file mode 100644 index 00000000..1015bd55 --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -0,0 +1,71 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Data; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +/// +/// 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 +/// +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity +{ + static IFreeSql _ormPriv; + /// + /// 全局 IFreeSql orm 对象 + /// + public static IFreeSql Orm => _ormPriv ?? throw new Exception(@"使用前请初始化 BaseEntity.Initialization(new FreeSqlBuilder() +.UseAutoSyncStructure(true) +.UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") +.Build());"); + + /// + /// 初始化BaseEntity + /// BaseEntity.Initialization(new FreeSqlBuilder() + /// + /// .UseAutoSyncStructure(true) + /// + /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") + /// + /// .Build()); + /// + /// IFreeSql orm 对象 + public static void Initialization(IFreeSql fsql) + { + _ormPriv = fsql; + _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); + } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + /// + /// 更新时间 + /// + public DateTime UpdateTime { get; set; } + /// + /// 逻辑删除 + /// + public bool IsDeleted { get; set; } + + /// + /// 开启工作单元事务 + /// + /// + public static IUnitOfWork Begin() => Begin(null); + /// + /// 开启工作单元事务 + /// + /// 事务等级 + /// + public static IUnitOfWork Begin(IsolationLevel? level) + { + var uow = Orm.CreateUnitOfWork(); + uow.IsolationLevel = level; + return uow; + } +} diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs new file mode 100644 index 00000000..8d5f2399 --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -0,0 +1,121 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Data; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +/// +/// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步方法的实体基类 +/// +/// +[Table(DisableSyncStructure = true)] +public abstract class BaseEntityAsync : BaseEntity where TEntity : class +{ + /// + /// 查询数据 + /// + /// + public static ISelect Select => Orm.Select() + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)) + .WhereCascade(a => (a as BaseEntity).IsDeleted == false); + /// + /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + /// + /// lambda表达式 + /// + public static ISelect Where(Expression> exp) => Select.Where(exp); + /// + /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + /// + /// true 时生效 + /// lambda表达式 + /// + public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); + + /// + /// 仓储对象 + /// + protected IBaseRepository Repository { get; set; } + + /// + /// 附加实体,在更新数据时,只更新变化的部分 + /// + public TEntity Attach() + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + var item = this as TEntity; + this.Repository.Attach(item); + return item; + } + + /** async **/ + + async Task UpdateIsDeletedAsync(bool value) + { + if (this.Repository == null) + return await Orm.Update(this as TEntity) + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; + + this.IsDeleted = value; + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return await this.Repository.UpdateAsync(this as TEntity) == 1; + } + /// + /// 删除数据 + /// + /// + public virtual Task DeleteAsync() => this.UpdateIsDeletedAsync(true); + /// + /// 恢复删除的数据 + /// + /// + public virtual Task RestoreAsync() => this.UpdateIsDeletedAsync(false); + + /// + /// 更新数据 + /// + /// + async public virtual Task UpdateAsync() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + return await Orm.Update() + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; + + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return await this.Repository.UpdateAsync(this as TEntity) == 1; + } + /// + /// 插入数据 + /// + public virtual Task InsertAsync() + { + this.CreateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.InsertAsync(this as TEntity); + } + + /// + /// 更新或插入 + /// + /// + public virtual Task SaveAsync() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.InsertOrUpdateAsync(this as TEntity); + } +} diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsyncTKey.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsyncTKey.cs new file mode 100644 index 00000000..cb1b8b3e --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsyncTKey.cs @@ -0,0 +1,44 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Data; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +/// +/// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 异步方法、以及 ID 主键定义 的实体基类 +/// +/// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 +/// +/// +/// +[Table(DisableSyncStructure = true)] +public abstract class BaseEntityAsync : BaseEntityAsync where TEntity : class +{ + static BaseEntityAsync() + { + var tkeyType = typeof(TKey)?.NullableTypeOrThis(); + if (tkeyType == typeof(int) || tkeyType == typeof(long)) + Orm.CodeFirst.ConfigEntity(typeof(TEntity), + t => t.Property("Id").IsIdentity(true)); + } + + /// + /// 主键 + /// + public virtual TKey Id { get; set; } + + /// + /// 根据主键值获取数据 + /// + /// + /// + async public static Task FindAsync(TKey id) + { + var item = await Select.WhereDynamic(id).FirstAsync(); + (item as BaseEntity)?.Attach(); + return item; + } +} diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySync.cs new file mode 100644 index 00000000..eab376b7 --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySync.cs @@ -0,0 +1,80 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Data; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +/// +/// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 +/// +/// +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity : BaseEntityAsync where TEntity : class +{ + bool UpdateIsDeleted(bool value) + { + if (this.Repository == null) + return Orm.Update(this as TEntity) + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; + + this.IsDeleted = value; + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 删除数据 + /// + /// + public virtual bool Delete() => this.UpdateIsDeleted(true); + /// + /// 恢复删除的数据 + /// + /// + public virtual bool Restore() => this.UpdateIsDeleted(false); + + /// + /// 更新数据 + /// + /// + public virtual bool Update() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + return Orm.Update() + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .SetSource(this as TEntity).ExecuteAffrows() == 1; + + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 插入数据 + /// + public virtual TEntity Insert() + { + this.CreateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.Insert(this as TEntity); + } + + /// + /// 更新或插入 + /// + /// + public virtual TEntity Save() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.InsertOrUpdate(this as TEntity); + } +} diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySyncTKey.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySyncTKey.cs new file mode 100644 index 00000000..359e155a --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySyncTKey.cs @@ -0,0 +1,56 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Data; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +/// +/// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 +/// +/// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 +/// +/// +/// +[Table(DisableSyncStructure = true)] +public abstract class BaseEntity : BaseEntity where TEntity : class +{ + static BaseEntity() + { + var tkeyType = typeof(TKey)?.NullableTypeOrThis(); + if (tkeyType == typeof(int) || tkeyType == typeof(long)) + Orm.CodeFirst.ConfigEntity(typeof(TEntity), + t => t.Property("Id").IsIdentity(true)); + } + + /// + /// 主键 + /// + public virtual TKey Id { get; set; } + + /// + /// 根据主键值获取数据 + /// + /// + /// + async public static Task FindAsync(TKey id) + { + var item = await Select.WhereDynamic(id).FirstAsync(); + (item as BaseEntity)?.Attach(); + return item; + } + + /// + /// 根据主键值获取数据 + /// + /// + /// + public static TEntity Find(TKey id) + { + var item = Select.WhereDynamic(id).First(); + (item as BaseEntity)?.Attach(); + return item; + } +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj new file mode 100644 index 00000000..18be6163 --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -0,0 +1,28 @@ + + + + netstandard2.0 + 0.7.16 + true + YeXiangQin + BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. + https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity + https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity + git + MIT + FreeSql;ORM;BaseEntity + $(AssemblyName) + $(AssemblyName) + true + true + + + + FreeSql.Extensions.BaseEntity.xml + + + + + + + diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml new file mode 100644 index 00000000..6a86cb7c --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml @@ -0,0 +1,212 @@ + + + + FreeSql.Extensions.BaseEntity + + + + + 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 + + + + + 全局 IFreeSql orm 对象 + + + + + 初始化BaseEntity + BaseEntity.Initialization(new FreeSqlBuilder() + + .UseAutoSyncStructure(true) + + .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") + + .Build()); + + IFreeSql orm 对象 + + + + 创建时间 + + + + + 更新时间 + + + + + 逻辑删除 + + + + + 开启工作单元事务 + + + + + + 开启工作单元事务 + + 事务等级 + + + + + 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步方法的实体基类 + + + + + + 查询数据 + + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 仓储对象 + + + + + 附加实体,在更新数据时,只更新变化的部分 + + + + async * + + + + 删除数据 + + + + + + 恢复删除的数据 + + + + + + 更新数据 + + + + + + 插入数据 + + + + + 更新或插入 + + + + + + 包括 CreateTime/UpdateTime/IsDeleted、CRUD 异步方法、以及 ID 主键定义 的实体基类 + + 当 TKey 为 int/long 时,Id 主键被设为自增值主键 + + + + + + + 主键 + + + + + 根据主键值获取数据 + + + + + + + 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 + + + + + + 删除数据 + + + + + + 恢复删除的数据 + + + + + + 更新数据 + + + + + + 插入数据 + + + + + 更新或插入 + + + + + + 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 + + 当 TKey 为 int/long 时,Id 主键被设为自增值主键 + + + + + + + 主键 + + + + + 根据主键值获取数据 + + + + + + + 根据主键值获取数据 + + + + + + diff --git a/Extensions/FreeSql.Extensions.BaseEntity/readme.md b/Extensions/FreeSql.Extensions.BaseEntity/readme.md new file mode 100644 index 00000000..a9ace8ac --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/readme.md @@ -0,0 +1,92 @@ +# 前言 + +尝试过 ado.net、dapper、ef,以及Repository仓储,甚至自己还写过生成器工具,以便做常规CRUD操作。 + +它们日常操作不方便之处: + +- 每次使用前需要声明,再操作; + +- 很多人一个实体类,对应一个操作类(或DAL、DbContext、Repository); + +BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用; + +本文介绍 BaseEntity 一种极简约的 CRUD 操作方法。 + +# 功能特点 + +- 自动迁移实体结构(CodeFirst),到数据库; + +- 直接操作实体的方法,进行 CRUD 操作; + +- 简化用户定义实体类型,省去主键、常用字段的配置(如CreateTime、UpdateTime); + +- 实现单表、多表查询的软删除逻辑; + +# 声明 + +> dotnet add package FreeSql.Extensions.BaseEntity + +> dotnet add package FreeSql.Provider.Sqlite + +1、定义一个主键 int 并且自增的实体类型,BaseEntity TKey 指定为 int/long 时,会认为主键是自增; + +```csharp +public class UserGroup : BaseEntity +{ + public string GroupName { get; set; } +} +``` + +如果不想主键是自增键,可以重写属性: + +```csharp +public class UserGroup : BaseEntity +{ + [Column(IsIdentity = false)] + public override int Id { get; set; } + public string GroupName { get; set; } +} +``` +> 有关更多实体的特性配置,请参考资料:https://github.com/2881099/FreeSql/wiki/%e5%ae%9e%e4%bd%93%e7%89%b9%e6%80%a7 + +2、定义一个主键 Guid 的实体类型,保存数据时会自动产生有序不重复的 Guid 值(不用自己指定 Guid.NewGuid()); + +```csharp +public class User : BaseEntity +{ + public string UserName { get; set; } +} +``` + +# CRUD 使用 + +```csharp +//添加 +var item = new UserGroup { GroupName = "组一" }; +item.Insert(); + +//更新 +item.GroupName = "组二"; +item.Update(); + +//添加或更新 +item.Save(); + +//软删除 +item.Delete(); + +//恢复软删除 +item.Restore(); + +//根据主键获取对象 +var item = UserGroup.Find(1); + +//查询数据 +var items = UserGroup.Where(a => a.Id > 10).ToList(); +``` + +实体类型.Select 是一个查询对象,使用方法和 FreeSql.ISelect 一样; + +支持多表查询时,软删除条件会附加在每个表中; + +> 有关更多查询方法,请参考资料:https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2 diff --git a/FreeSql.sln b/FreeSql.sln index 868aa88e..78427fa6 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -56,7 +56,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.MySq EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "base_entity", "Examples\base_entity\base_entity.csproj", "{D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "base_entity_net45", "Examples\base_entity_net45\base_entity_net45.csproj", "{7E091544-EC38-4A41-A3BE-BDC693070BE7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.BaseEntity", "Extensions\FreeSql.Extensions.BaseEntity\FreeSql.Extensions.BaseEntity.csproj", "{FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -320,18 +320,18 @@ Global {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x64.Build.0 = Release|Any CPU {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x86.ActiveCfg = Release|Any CPU {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0}.Release|x86.Build.0 = Release|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|x64.ActiveCfg = Debug|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|x64.Build.0 = Debug|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|x86.ActiveCfg = Debug|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Debug|x86.Build.0 = Debug|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|Any CPU.Build.0 = Release|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|x64.ActiveCfg = Release|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|x64.Build.0 = Release|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|x86.ActiveCfg = Release|Any CPU - {7E091544-EC38-4A41-A3BE-BDC693070BE7}.Release|x86.Build.0 = Release|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Debug|x64.ActiveCfg = Debug|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Debug|x64.Build.0 = Debug|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Debug|x86.ActiveCfg = Debug|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Debug|x86.Build.0 = Debug|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|Any CPU.Build.0 = Release|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|x64.ActiveCfg = Release|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|x64.Build.0 = Release|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|x86.ActiveCfg = Release|Any CPU + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -351,7 +351,7 @@ Global {690F89E0-A721-423F-8F5D-D262F73235EA} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} - {7E091544-EC38-4A41-A3BE-BDC693070BE7} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} From 9b80f8cd53ec2485faf89afc9c4ce3afb3a1e038 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 29 Jul 2019 16:35:36 +0800 Subject: [PATCH 0065/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IInsert.Inse?= =?UTF-8?q?rtIdentity=20=E5=8F=AF=E6=8F=92=E5=85=A5=E8=87=AA=E5=A2=9E?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 1 + FreeSql/FreeSql.xml | 6 +++ FreeSql/Interface/Curd/IInsert.cs | 6 +++ .../Internal/CommonProvider/InsertProvider.cs | 51 +++++++++++-------- .../Curd/OracleInsert.cs | 44 ++++++++-------- 5 files changed, 64 insertions(+), 44 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 5bd98ca9..45a2077c 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -322,6 +322,7 @@ namespace FreeSql.Tests [Fact] public void Test1() { + //g.sqlite.Aop.ParseExpression += parseExp; var sqddddl = g.sqlite.Select().ToSql(t => t.OptionsEntity04 == "1".TryTo()); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e03bc565..5c6d9d2b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -649,6 +649,12 @@ lambda选择列 + + + 指定可插入自增字段 + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 09184d67..aa43198c 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -54,6 +54,12 @@ namespace FreeSql /// IInsert IgnoreColumns(Expression> columns); + /// + /// 指定可插入自增字段 + /// + /// + IInsert InsertIdentity(); + /// /// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 /// diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index ee4a3d4b..04ae09d6 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -21,7 +21,7 @@ namespace FreeSql.Internal.CommonProvider protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); protected TableInfo _table; protected Func _tableRule; - protected bool _noneParameter; + protected bool _noneParameter, _insertIdentity; protected DbParameter[] _params; protected DbTransaction _transaction; protected DbConnection _connection; @@ -38,6 +38,7 @@ namespace FreeSql.Internal.CommonProvider protected void ClearData() { + _insertIdentity = false; _source.Clear(); _ignore.Clear(); _params = null; @@ -56,6 +57,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IInsert InsertIdentity() + { + _insertIdentity = true; + return this; + } + public IInsert NoneParameter() { _noneParameter = true; @@ -526,12 +533,14 @@ namespace FreeSql.Internal.CommonProvider sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append("("); var colidx = 0; foreach (var col in _table.Columns.Values) - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); - ++colidx; - } + { + if (_ignore.ContainsKey(col.Attribute.Name)) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); + ++colidx; + } sb.Append(") VALUES"); _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; var specialParams = new List(); @@ -542,21 +551,23 @@ namespace FreeSql.Internal.CommonProvider sb.Append("("); var colidx2 = 0; foreach (var col in _table.Columns.Values) - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) + { + if (_ignore.ContainsKey(col.Attribute.Name)) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + + if (colidx2 > 0) sb.Append(", "); + object val = col.GetMapValue(d); + if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) + col.SetMapValue(d, val = FreeUtil.NewMongodbId()); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else { - if (colidx2 > 0) sb.Append(", "); - object val = col.GetMapValue(d); - if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) - col.SetMapValue(d, val = FreeUtil.NewMongodbId()); - if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); - else - { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); - } - ++colidx2; + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); } + ++colidx2; + } sb.Append(")"); ++didx; } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index df1d18c4..79cc3192 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -41,17 +41,13 @@ namespace FreeSql.Oracle.Curd var colidx = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity == true) - { - _identCol = col; - continue; - } - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) - { - if (colidx > 0) sbtb.Append(", "); - sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); - ++colidx; - } + if (col.Attribute.IsIdentity) _identCol = col; + if (_ignore.ContainsKey(col.Attribute.Name)) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + + if (colidx > 0) sbtb.Append(", "); + sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); + ++colidx; } sbtb.Append(") "); @@ -67,21 +63,21 @@ namespace FreeSql.Oracle.Curd var colidx2 = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) + if (_ignore.ContainsKey(col.Attribute.Name)) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + + if (colidx2 > 0) sb.Append(", "); + object val = col.GetMapValue(d); + if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) + col.SetMapValue(d, val = FreeUtil.NewMongodbId()); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else { - if (colidx2 > 0) sb.Append(", "); - object val = col.GetMapValue(d); - if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) - col.SetMapValue(d, val = FreeUtil.NewMongodbId()); - if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); - else - { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); - } - ++colidx2; + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); } + ++colidx2; } sb.Append(")"); ++didx; From 77ae9d0024c71b825f201b2d091ca5ce16b6f328 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 29 Jul 2019 18:43:59 +0800 Subject: [PATCH 0066/1029] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=20Oracle=20Cod?= =?UTF-8?q?eFirst=20=E4=BD=BF=E7=94=A8=20OldName=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E8=87=AA=E5=A2=9E=E5=AD=97=E6=AE=B5=E6=97=B6=EF=BC=8C=E6=9C=AA?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A7=E7=9A=84=E8=A7=A6=E5=8F=91=E5=99=A8?= =?UTF-8?q?=E5=92=8C=E5=BA=8F=E5=88=97=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 5 ++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 25 +++++++- .../OracleCodeFirst.cs | 62 ++++++++++++------- 3 files changed, 69 insertions(+), 23 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 6b525395..52359271 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -79,6 +79,11 @@ 测试中文重命名id + + + 姓名 + + 试卷表 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 45a2077c..29a072ab 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -10,6 +10,7 @@ using Npgsql.LegacyPostgis; using System.Linq.Expressions; using System.Threading.Tasks; using System.Collections; +using System.Diagnostics; namespace FreeSql.Tests { @@ -318,10 +319,32 @@ namespace FreeSql.Tests } } } - } + } + + public class Class1 + { + [Column(IsIdentity = true)] + public long ID { set; get; } + + [Column(IsIdentity = true, OldName = "stu_id_log")] + public long stu_id { set; get; } + /// + /// 姓名 + /// + public string name { set; get; } + + public int age { set; get; } + + public DateTime class2 { set; get; } + } + [Fact] public void Test1() { + g.oracle.Aop.SyncStructureAfter += (s, e) => + Trace.WriteLine(e.Sql); + + g.oracle.CodeFirst.SyncStructure(); //g.sqlite.Aop.ParseExpression += parseExp; diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index ec8f0dc9..6f6dbf94 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -74,7 +74,8 @@ namespace FreeSql.Oracle public override string GetComparisonDDLStatements(params Type[] entityTypes) { var userId = (_orm.Ado.MasterPool as OracleConnectionPool).UserId; - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 + var seqnameDel = new List(); //要删除的序列+触发器 var sb = new StringBuilder(); var sbDeclare = new StringBuilder(); @@ -194,11 +195,17 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + if (tbstructcol.is_identity) + seqnameDel.Add(Utils.GetCsName($"{tbname[1]}_seq_{tbstructcol.column}")); //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); + if (tbcol.Attribute.IsIdentity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } + else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; @@ -307,13 +314,8 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); } Dictionary dicDeclare = new Dictionary(); - foreach (var seqcol in seqcols) + Action dropSequence = seqname => { - var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); - var tiggerName = seqname + "TI"; - var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); - var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); if (dicDeclare.ContainsKey(seqname) == false) { sbDeclare.Append("\r\n").Append(seqname).Append("IS NUMBER; \r\n"); @@ -324,9 +326,36 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); .Append("if ").Append(seqname).Append("IS > 0 then \r\n") .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") .Append("end if; \r\n"); + }; + Action dropTrigger = tiggerName => + { + if (dicDeclare.ContainsKey(tiggerName) == false) + { + sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); + dicDeclare.Add(tiggerName, true); + } + sb.Append(tiggerName).Append("IS := 0; \r\n") + .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") + .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") + .Append("end if; \r\n"); + }; + foreach (var seqname in seqnameDel) + { + dropSequence(seqname); + dropTrigger(seqname + "TI"); + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var tiggerName = seqname + "TI"; + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + dropSequence(seqname); if (seqcol.Item3) { - var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null ? 1 : + var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_columns where owner={0} and table_name={1} and column_name={2}", tbname[0], tbname[1], colname2)) == null ? 1 : _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}"); sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n"); sb.Append("execute immediate 'CREATE OR REPLACE TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)) @@ -335,18 +364,7 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); .Append(".nextval into :new.").Append(colname2).Append(" from dual;\r\nend;';\r\n"); } else - { - if (dicDeclare.ContainsKey(tiggerName) == false) - { - sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); - dicDeclare.Add(tiggerName, true); - } - sb.Append(tiggerName).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) - .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") - .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") - .Append("end if; \r\n"); - } + dropTrigger(tiggerName); } if (sbDeclare.Length > 0) sbDeclare.Insert(0, "declare "); return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString(); From 157a0c2805ca70888fd321fe01b228ac71a908a9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 29 Jul 2019 18:45:30 +0800 Subject: [PATCH 0067/1029] v0.8.1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 18be6163..ebd78721 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.7.16 + 0.8.1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7bb704a8..ef2b3dda 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 331aa1b2..9cbe875e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 25c1c69f..f76afe3c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.16 + 0.8.1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 92092bc0..b1e1b0f6 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 29274716..86f3ae6b 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 2f8833ba..480d4049 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2f610bb1..08cfae80 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f0f6b28e..45b6362f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d84f4d53..95cf2248 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f8441f7d..4c38ce92 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.16 + 0.8.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 53cd4f17e13494deb3d8532300bd9f5510c668e8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 30 Jul 2019 09:14:50 +0800 Subject: [PATCH 0068/1029] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20SyncStructure=20?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/CodeFirstProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index e7edfceb..c1b7830e 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -68,7 +68,7 @@ namespace FreeSql.Internal.CommonProvider } var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); - return affrows > 0; + return true; } } catch (Exception ex) From fcf52f3998c9e3a7db016d4ceea0edb4748a9809 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 30 Jul 2019 18:31:39 +0800 Subject: [PATCH 0069/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Oracle=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=20DateTime.Subtract(DateTime)=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 3 +++ Providers/FreeSql.Provider.Oracle/OracleExpression.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 29a072ab..2d38490e 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -341,6 +341,9 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var kfkfjdfg = g.oracle.Select().Where(a => (DateTime.Now - a.EditTime).TotalMinutes > 100).ToSql(); + + g.oracle.Aop.SyncStructureAfter += (s, e) => Trace.WriteLine(e.Sql); diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index e4752a68..3dee8d3f 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -378,7 +378,7 @@ namespace FreeSql.Oracle case "Subtract": switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { - case "System.DateTime": return $"({args1}-{left})"; + case "System.DateTime": return $"numtodsinterval(({left}+0)-({args1}+0),'day')"; case "System.TimeSpan": return $"({left}-{args1})"; } break; From 8a11e9c7944a8c958283803243da87f419590c33 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 31 Jul 2019 11:24:41 +0800 Subject: [PATCH 0070/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IFreeSql.Sel?= =?UTF-8?q?ect`T1...T10=20=E7=9A=84=E5=A4=9A=E8=A1=A8=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 2 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 62 ++++++++++++++++++- FreeSql/FreeSql.xml | 54 ++++++++++++++++ 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 2d38490e..351dda5e 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -342,7 +342,7 @@ namespace FreeSql.Tests public void Test1() { var kfkfjdfg = g.oracle.Select().Where(a => (DateTime.Now - a.EditTime).TotalMinutes > 100).ToSql(); - + g.oracle.Aop.SyncStructureAfter += (s, e) => Trace.WriteLine(e.Sql); diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 68855572..02fba7c2 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -10,9 +10,6 @@ using System.Reflection; public static partial class FreeSqlGlobalExtensions { - - public static FreeSql.ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); - static Lazy> dicIsNumberType = new Lazy>(() => new Dictionary { [typeof(sbyte)] = true, @@ -109,4 +106,63 @@ public static partial class FreeSqlGlobalExtensions { return orm?.Select(); } + + public static FreeSql.ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); + + #region 多表查询 + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class => + freesql.Select().From((s, b) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class => + freesql.Select().From((s, b, c) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class => + freesql.Select().From((s, b, c, d) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => + freesql.Select().From((s, b, c, d, e) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => + freesql.Select().From((s, b, c, d, e, f) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => + freesql.Select().From((s, b, c, d, e, f, g) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => + freesql.Select().From((s, b, c, d, e, f, g, h) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) 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 => + freesql.Select().From((s, b, c, d, e, f, g, h, i) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IFreeSql freesql) 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 => + freesql.Select().From((s, b, c, d, e, f, g, h, i, j) => s); + #endregion } \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5c6d9d2b..6818bf46 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2388,6 +2388,60 @@ + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + 使用 and 拼接两个 lambda 表达式 From 49a1eecb45bf28b9c487539bacbd3d00395a4b10 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 1 Aug 2019 10:05:08 +0800 Subject: [PATCH 0071/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=86=85?= =?UTF-8?q?=E9=83=A8=E5=AE=9E=E4=BD=93=E7=AE=A1=E7=90=86=E7=9A=84=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=EF=BC=8C=E9=98=B2=E6=AD=A2=E5=AF=BC=E8=88=AA?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E4=BD=BF=E7=94=A8=E6=8A=BD=E8=B1=A1=E7=B1=BB?= =?UTF-8?q?/=E6=8E=A5=E5=8F=A3=E6=97=B6=E5=87=BA=E7=8E=B0=E9=94=99?= =?UTF-8?q?=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/UtilsExpressionTree.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index a9d8715f..5a74b980 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -155,8 +155,7 @@ namespace FreeSql.Internal trytb.ColumnsByCsIgnore.Add(p.Name, col); continue; } - if (entityDefault == null) entityDefault = Activator.CreateInstance(entity); - colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(entityDefault); + if (entityDefault != null) colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(entityDefault); if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue); if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; if (colattr.IsNullable == false && colattr.DbDefautValue == null) From b6ca81bfb91e15be156bca1480894eabdaf7b5fe Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 1 Aug 2019 12:14:52 +0800 Subject: [PATCH 0072/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E5=87=BD=E6=95=B0=20string.IsNullOrWhiteSpac?= =?UTF-8?q?e=20=E8=A7=A3=E6=9E=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../MySqlConnectorExpression/StringTest.cs | 9 +++++++++ .../FreeSql.Tests/MySql/MySqlExpression/StringTest.cs | 9 +++++++++ .../FreeSql.Tests/Oracle/OracleExpression/StringTest.cs | 9 ++++++++- .../PostgreSQL/PostgreSQLExpression/StringTest.cs | 9 +++++++++ .../SqlServer/SqlServerExpression/StringTest.cs | 9 +++++++++ .../FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs | 9 +++++++++ FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- Providers/FreeSql.Provider.MySql/MySqlExpression.cs | 3 +++ .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- Providers/FreeSql.Provider.Oracle/OracleExpression.cs | 3 +++ .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs | 3 +++ .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServer/SqlServerExpression.cs | 3 +++ .../FreeSql.Provider.Sqlite.csproj | 2 +- Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs | 3 +++ 22 files changed, 79 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index ebd78721..516444e7 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.1 + 0.8.2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ef2b3dda..0a87347a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 9cbe875e..9403be5a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index f76afe3c..59160cb1 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.1 + 0.8.2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 2ceacb9d..485a1d4f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -716,5 +716,14 @@ namespace FreeSql.Tests.MySqlConnectorExpression data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index 558605cc..f7610659 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -716,5 +716,14 @@ namespace FreeSql.Tests.MySqlExpression data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index 7d2017d1..d46de5c1 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -712,8 +712,15 @@ namespace FreeSql.Tests.OracleExpression { var data = new List(); data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); - //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index b4976d92..3facac11 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -715,5 +715,14 @@ namespace FreeSql.Tests.PostgreSQLExpression data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index 3cd5b5d9..ef1a110f 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -285,5 +285,14 @@ namespace FreeSql.Tests.SqlServerExpression //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index 182433ed..0143271c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -714,5 +714,14 @@ namespace FreeSql.Tests.SqliteExpression //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b1e1b0f6..8c04e0e0 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 86f3ae6b..0987bf7d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 10b93e5a..d9fb104f 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -235,6 +235,9 @@ namespace FreeSql.MySql case "IsNullOrEmpty": var arg1 = getExp(exp.Arguments[0]); return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); } diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 480d4049..4ec262c5 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 08cfae80..bef79663 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 3dee8d3f..3bf13ec4 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -235,6 +235,9 @@ namespace FreeSql.Oracle case "IsNullOrEmpty": var arg1 = getExp(exp.Arguments[0]); return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 45b6362f..bdcd1e08 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 28f59721..e0bc9eab 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -344,6 +344,9 @@ namespace FreeSql.PostgreSQL case "IsNullOrEmpty": var arg1 = getExp(exp.Arguments[0]); return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); } diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 95cf2248..e2d588f6 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 8af8d56a..24fd1a33 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -239,6 +239,9 @@ namespace FreeSql.SqlServer case "IsNullOrEmpty": var arg1 = getExp(exp.Arguments[0]); return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); } diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4c38ce92..4ba1b90c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.1 + 0.8.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 5a0d21a4..b3f1541e 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -235,6 +235,9 @@ namespace FreeSql.Sqlite case "IsNullOrEmpty": var arg1 = getExp(exp.Arguments[0]); return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); } From 430618dcb7caa7f53d31ebe1b8ed5189cedbbe2b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 1 Aug 2019 18:29:54 +0800 Subject: [PATCH 0073/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Prov?= =?UTF-8?q?ider.Oracle=20=E4=B8=8B=E7=9A=84=20OraclePrimaryKeyName=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7=EF=BC=8C=E6=89=8B=E5=B7=A5=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E4=B8=BB=E9=94=AE=E5=90=8D=E9=98=B2=E6=AD=A2=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=90=8D=E8=BF=87=E9=95=BF=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OraclePrimaryKeyNameAttribute.cs | 17 +++++++++++++++++ .../FreeSql.Provider.Oracle/OracleCodeFirst.cs | 8 ++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 Providers/FreeSql.Provider.Oracle/DataAnnotations/OraclePrimaryKeyNameAttribute.cs diff --git a/Providers/FreeSql.Provider.Oracle/DataAnnotations/OraclePrimaryKeyNameAttribute.cs b/Providers/FreeSql.Provider.Oracle/DataAnnotations/OraclePrimaryKeyNameAttribute.cs new file mode 100644 index 00000000..fd2aa735 --- /dev/null +++ b/Providers/FreeSql.Provider.Oracle/DataAnnotations/OraclePrimaryKeyNameAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace FreeSql.DataAnnotations +{ + public class OraclePrimaryKeyNameAttribute : Attribute + { + public OraclePrimaryKeyNameAttribute(string name) + { + this.Name = name; + } + + /// + /// 主键名 + /// + public string Name { get; set; } + } +} diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 6f6dbf94..daf4d3f4 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -8,6 +8,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Linq; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; @@ -90,6 +91,7 @@ namespace FreeSql.Oracle var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; + var primaryKeyName = entityType.GetCustomAttribute()?.Name; if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); @@ -115,7 +117,8 @@ namespace FreeSql.Oracle } if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk1 PRIMARY KEY ("); + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; + sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -268,7 +271,8 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); } if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk2 PRIMARY KEY ("); + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; + sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } From 68ab6738702baf83b42375b9b7b2cd25d5be594b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 2 Aug 2019 10:49:07 +0800 Subject: [PATCH 0074/1029] =?UTF-8?q?=E8=B0=83=E6=95=B4=20OraclePrimaryKey?= =?UTF-8?q?Name=20=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataAnnotations/Special}/OraclePrimaryKeyNameAttribute.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {Providers/FreeSql.Provider.Oracle/DataAnnotations => FreeSql/DataAnnotations/Special}/OraclePrimaryKeyNameAttribute.cs (100%) diff --git a/Providers/FreeSql.Provider.Oracle/DataAnnotations/OraclePrimaryKeyNameAttribute.cs b/FreeSql/DataAnnotations/Special/OraclePrimaryKeyNameAttribute.cs similarity index 100% rename from Providers/FreeSql.Provider.Oracle/DataAnnotations/OraclePrimaryKeyNameAttribute.cs rename to FreeSql/DataAnnotations/Special/OraclePrimaryKeyNameAttribute.cs From 4213761c6216a7f6606ce3351df01895b52f1776 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 5 Aug 2019 13:57:53 +0800 Subject: [PATCH 0075/1029] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E9=87=8D=E5=A4=8D=E6=95=B0=E6=8D=AE=E6=97=B6=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20IncludeMany=20=E5=87=BA=E7=8E=B0=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=B7=BB=E5=8A=A0=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 5 ++++ .../SelectProvider/Select1Provider.cs | 27 +++++++++++++------ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6818bf46..14783b73 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -123,6 +123,11 @@ 手工绑定 ManyToMany 导航关系 + + + 主键名 + + 数据库表名 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 13725c82..39313640 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -708,12 +708,16 @@ namespace FreeSql.Internal.CommonProvider return; } - Dictionary>> dicList = new Dictionary>>(); + Dictionary>>> dicList = new Dictionary>>>(); foreach (var item in list) { if (tbref.Columns.Count == 1) { - dicList.Add(getListValue(item, tbref.Columns[0].CsName, 0).ToString(), Tuple.Create(item, new List())); + var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0).ToString(); + var dicListVal = Tuple.Create(item, new List()); + if (dicList.TryGetValue(dicListKey, out var items) == false) + dicList.Add(dicListKey, items = new List>>()); + items.Add(dicListVal); } else { @@ -723,7 +727,11 @@ namespace FreeSql.Internal.CommonProvider if (z > 0) sb.Append("*$*"); sb.Append(getListValue(item, tbref.Columns[z].CsName, z)); } - dicList.Add(sb.ToString(), Tuple.Create(item, new List())); + var dicListKey = sb.ToString(); + var dicListVal = Tuple.Create(item, new List()); + if (dicList.TryGetValue(dicListKey, out var items) == false) + dicList.Add(dicListKey, items = new List>>()); + items.Add(dicListVal); sb.Clear(); } } @@ -756,15 +764,18 @@ namespace FreeSql.Internal.CommonProvider key = sb.ToString(); sb.Clear(); } - if (dicList.TryGetValue(key, out var t1item) == false) return; - t1item.Item2.Add(nav); + if (dicList.TryGetValue(key, out var t1items) == false) return; + foreach (var t1item in t1items) + t1item.Item2.Add(nav); //将子集合的,多对一,对象设置为当前对象 foreach (var parentNav in parentNavs) - _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1); + foreach (var t1item in t1items) + _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1); } - foreach (var t1item in dicList.Values) - setListValue(t1item.Item1, t1item.Item2); + foreach (var t1items in dicList.Values) + foreach (var t1item in t1items) + setListValue(t1item.Item1, t1item.Item2); dicList.Clear(); } break; From 6c0bdc0e9ecf38a862164a8c279f817c57e3e129 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 6 Aug 2019 10:32:36 +0800 Subject: [PATCH 0076/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20ISelect`T1..?= =?UTF-8?q?.T10=20LeftJoin/InnerJoin/RightJoin=20=E5=A4=9A=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 5 ++++- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 4 ++++ FreeSql/Interface/Curd/ISelect/ISelect2.cs | 4 ++++ FreeSql/Interface/Curd/ISelect/ISelect3.cs | 4 ++++ FreeSql/Interface/Curd/ISelect/ISelect4.cs | 4 ++++ FreeSql/Interface/Curd/ISelect/ISelect5.cs | 4 ++++ FreeSql/Interface/Curd/ISelect/ISelect6.cs | 4 ++++ FreeSql/Interface/Curd/ISelect/ISelect7.cs | 4 ++++ FreeSql/Interface/Curd/ISelect/ISelect8.cs | 4 ++++ FreeSql/Interface/Curd/ISelect/ISelect9.cs | 4 ++++ .../SelectProvider/Select10Provider.cs | 21 +++++++++++++++++++ .../SelectProvider/Select2Provider.cs | 21 +++++++++++++++++++ .../SelectProvider/Select3Provider.cs | 21 +++++++++++++++++++ .../SelectProvider/Select4Provider.cs | 21 +++++++++++++++++++ .../SelectProvider/Select5Provider.cs | 21 +++++++++++++++++++ .../SelectProvider/Select6Provider.cs | 21 +++++++++++++++++++ .../SelectProvider/Select7Provider.cs | 21 +++++++++++++++++++ .../SelectProvider/Select8Provider.cs | 21 +++++++++++++++++++ .../SelectProvider/Select9Provider.cs | 21 +++++++++++++++++++ 19 files changed, 229 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 351dda5e..d127a26d 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -341,7 +341,10 @@ namespace FreeSql.Tests [Fact] public void Test1() { - var kfkfjdfg = g.oracle.Select().Where(a => (DateTime.Now - a.EditTime).TotalMinutes > 100).ToSql(); + g.oracle.Select() + .InnerJoin((a,b) => true) + .Where((a,b) => (DateTime.Now - a.EditTime).TotalMinutes > 100) + .ToSql(); g.oracle.Aop.SyncStructureAfter += (s, e) => diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 15a8f4dd..11cb5e76 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -33,6 +33,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index c13f1b71..0b6c271b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -34,6 +34,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index 0d036dd6..e890ca75 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -33,6 +33,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 7787cf39..da0a140e 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -33,6 +33,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index c579b50a..28198dd0 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -33,6 +33,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 05e42d96..01a2b3ed 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -33,6 +33,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index 25356edb..ca2f6a82 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -33,6 +33,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 1404be93..c77040b1 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -33,6 +33,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index b6ed09ba..feba4958 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -33,6 +33,10 @@ namespace FreeSql TMember Avg(Expression> column); Task AvgAsync(Expression> column); + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index a73fea3a..8aec418b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -177,6 +177,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 25a82a0c..552f7660 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -153,6 +153,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 82a0f6a5..cd80bc19 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -156,6 +156,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 1efcdb3c..707080a6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -159,6 +159,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index ef30f98a..60a3c5e6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -162,6 +162,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 0572ee69..ee59440c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -165,6 +165,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index c0b9161e..2118ee36 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -168,6 +168,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index a5bf2c74..cc611d62 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -171,6 +171,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index da94f75a..3c3a8c1d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -174,6 +174,27 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToSql(select?.Body); } + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + ISelect ISelect.Where(Expression> exp) { if (exp == null) return this.Where(null); From d22bed3494bcbe5583af56613a8812d8ae3dfd16 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 6 Aug 2019 10:42:32 +0800 Subject: [PATCH 0077/1029] v0.8.3 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 516444e7..623a7342 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.2 + 0.8.3 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0a87347a..6100dd18 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 9403be5a..6eccf866 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 59160cb1..cd97e44c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.2 + 0.8.3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8c04e0e0..281fd49c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0987bf7d..2f8eafea 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4ec262c5..59a6d684 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index bef79663..8727ab1b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index bdcd1e08..65e25750 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e2d588f6..cc41e7de 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4ba1b90c..fddaa662 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.2 + 0.8.3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 71a0552871574ebb2d2f92d2976ff6ad2201ffc4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 6 Aug 2019 13:37:12 +0800 Subject: [PATCH 0078/1029] =?UTF-8?q?=E5=86=85=E9=83=A8=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/CodeFirstProvider.cs | 8 ++++---- .../CommonProvider/SelectProvider/Select1Provider.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index c1b7830e..1a07f0d0 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -45,12 +45,12 @@ namespace FreeSql.Internal.CommonProvider public abstract string GetComparisonDDLStatements(params Type[] entityTypes); static object syncStructureLock = new object(); - internal ConcurrentDictionary dicSyced = new ConcurrentDictionary(); + internal ConcurrentDictionary dicSyced = new ConcurrentDictionary(); public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); public bool SyncStructure(params Type[] entityTypes) { if (entityTypes == null) return false; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray(); + var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray(); if (syncTypes.Any() == false) return false; var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); _orm.Aop.SyncStructureBefore?.Invoke(this, before); @@ -63,11 +63,11 @@ namespace FreeSql.Internal.CommonProvider ddl = this.GetComparisonDDLStatements(syncTypes); if (string.IsNullOrEmpty(ddl)) { - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); + foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true); return true; } var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType.FullName, true); + foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true); return true; } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 39313640..ef72a209 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -213,7 +213,7 @@ namespace FreeSql.Internal.CommonProvider if (typeof(TReturn) == typeof(T1)) return this as ISelect; _tables[0].Parameter = select.Parameters[0]; _selectExpression = select.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TReturn).FullName, true); + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TReturn), true); var ret = _orm.Select(); Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -228,7 +228,7 @@ namespace FreeSql.Internal.CommonProvider ), SelectTableInfoType.InnerJoin); if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -243,7 +243,7 @@ namespace FreeSql.Internal.CommonProvider ), SelectTableInfoType.InnerJoin); if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -275,7 +275,7 @@ namespace FreeSql.Internal.CommonProvider } if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult).FullName, true); + (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; From b2cb1629226ed2e11f655bc31a9e22a9ea8e7f7a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 7 Aug 2019 10:06:07 +0800 Subject: [PATCH 0079/1029] update SafeObjectPool v2.1.1 --- FreeSql/FreeSql.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 281fd49c..5b12604f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -23,7 +23,7 @@ - + From bf4f0886b41aba841ebe5c88e8fc38045585eaf6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 8 Aug 2019 09:15:03 +0800 Subject: [PATCH 0080/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IUpdate.Set?= =?UTF-8?q?=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E4=BC=A0=E5=85=A5=E5=8C=BF?= =?UTF-8?q?=E5=90=8D=E7=B1=BB=E6=9B=B4=E6=96=B0=E5=A4=9A=E4=B8=AA=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=8C=E5=90=8E=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=9C=AA?= =?UTF-8?q?=E5=8A=A0[]=E6=88=96""=E7=9A=84=20bug=EF=BC=9B=20-=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20Aop.ConfigEntityProperty=20=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=AF=BC=E8=88=AA=E5=B1=9E=E6=80=A7=E5=90=8E=EF=BC=8C=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=20insert=20=E8=AF=AD=E5=8F=A5=E8=AE=A4=E4=B8=BA?= =?UTF-8?q?=E5=AE=83=E4=B9=9F=E6=98=AF=E5=AD=97=E6=AE=B5=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/UpdateProvider.cs | 4 ++-- FreeSql/Internal/UtilsExpressionTree.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index fa470488..5b8e1071 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -451,7 +451,7 @@ namespace FreeSql.Internal.CommonProvider var memberName = initExp.Bindings[a].Member.Name; if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); - var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { }); + var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { isQuoteName = true }); _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); } } @@ -465,7 +465,7 @@ namespace FreeSql.Internal.CommonProvider var memberName = newExp.Members[a].Name; if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); - var memberValue = _commonExpression.ExpressionLambdaToSql(newExp.Arguments[a], new CommonExpression.ExpTSC { }); + var memberValue = _commonExpression.ExpressionLambdaToSql(newExp.Arguments[a], new CommonExpression.ExpTSC { isQuoteName = true }); _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); } } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 5a74b980..6129bfe7 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -75,7 +75,7 @@ namespace FreeSql.Internal var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); var colattr = common.GetEntityColumnAttribute(entity, p); var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType); - //if (tp == null) continue; + if (tp == null && colattr != null) colattr.IsIgnore = true; //无法匹配的属性,认定是导航属性,且自动过滤 if (tp == null && colattr == null) { if (common.CodeFirst.IsLazyLoading) From ea79084de31f3f0f11ba5ac057d53c479f9e3a3c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 8 Aug 2019 09:21:21 +0800 Subject: [PATCH 0081/1029] v0.8.4 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 623a7342..723659d9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.3 + 0.8.4 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6100dd18..69698d0a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6eccf866..51a737fe 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index cd97e44c..b0a0c35d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.3 + 0.8.4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 5b12604f..0f3a4731 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 2f8eafea..0ae86b5b 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 59a6d684..c4fe39b8 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8727ab1b..3a271873 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 65e25750..14d2c7e4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cc41e7de..209c1b00 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fddaa662..c9e4597e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.3 + 0.8.4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From ecda6d8f492a3b3477c8d1073d3232ecb85dc28c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 9 Aug 2019 16:05:20 +0800 Subject: [PATCH 0082/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect.Wher?= =?UTF-8?q?eCascade=20=E5=BD=93=E5=86=85=E9=83=A8=E4=BD=BF=E7=94=A8=20(a?= =?UTF-8?q?=20as=20BaseEntity).TenantId=20=E6=97=B6=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 3 +- FreeSql/Internal/CommonExpression.cs | 166 ++++++++++++----------- 2 files changed, 89 insertions(+), 80 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index d127a26d..f203537a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -341,9 +341,10 @@ namespace FreeSql.Tests [Fact] public void Test1() { - g.oracle.Select() + var xxxkdkd = g.oracle.Select() .InnerJoin((a,b) => true) .Where((a,b) => (DateTime.Now - a.EditTime).TotalMinutes > 100) + .OrderBy((a,b) => g.oracle.Select().Where(c => b.Id == c.Id2).Count()) .ToSql(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index deb5cb77..887c48f3 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -708,33 +708,84 @@ namespace FreeSql.Internal })); var parm123Tb = _common.GetTableByEntity(asSelectParentExp.Type); var parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true); - var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType); - Expression fsqlWhereExp = null; - if (parm123Ref.RefType == TableRefType.ManyToMany) + if (parm123Ref != null) { - //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); - var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType); - var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] { + var fsqlWhereParam = fsqltables.First().Parameter; //Expression.Parameter(asSelectEntityType); + Expression fsqlWhereExp = null; + if (parm123Ref.RefType == TableRefType.ManyToMany) + { + //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); + var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType); + var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] { typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool))) - })); - var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); - var manySubSelectAny = _dicExpressionLambdaToSqlAsSelectAnyMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Any", new Type[0])); - var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - Expression.Call( - typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3), - Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3))) - )); - var manyMainParam = tsc._tables[0].Parameter; - var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__"); - Expression manySubSelectWhereExp = null; + })); + var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); + var manySubSelectAny = _dicExpressionLambdaToSqlAsSelectAnyMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Any", new Type[0])); + var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => + Expression.Call( + typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3), + Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3))) + )); + var manyMainParam = tsc._tables[0].Parameter; + var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__"); + Expression manySubSelectWhereExp = null; + for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) + { + var col1 = parm123Ref.MiddleColumns[mn]; + var col2 = parm123Ref.Columns[mn]; + var pexp1 = Expression.Property(manySubSelectWhereParam, col1.CsName); + var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); + if (col1.CsType != col2.CsType) + { + if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); + if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); + } + var tmpExp = Expression.Equal(pexp1, pexp2); + if (mn == 0) manySubSelectWhereExp = tmpExp; + else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp); + } + var manySubSelectExpBoy = Expression.Call( + manySubSelectAsSelectExp, + manySubSelectWhere, + Expression.Lambda( + manySubSelectWhereExp, + manySubSelectWhereParam + ) + ); + Expression fsqlManyWhereExp = null; + for (var mn = 0; mn < parm123Ref.RefColumns.Count; mn++) + { + var col1 = parm123Ref.RefColumns[mn]; + var col2 = parm123Ref.MiddleColumns[mn + parm123Ref.Columns.Count + mn]; + var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); + var pexp2 = Expression.Property(manySubSelectWhereParam, col2.CsName); + if (col1.CsType != col2.CsType) + { + if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); + if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); + } + var tmpExp = Expression.Equal(pexp1, pexp2); + if (mn == 0) fsqlManyWhereExp = tmpExp; + else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp); + } + fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent }); + fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); + var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); + if (string.IsNullOrEmpty(sql2) == false) + manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace("\r\n", "\r\n\t")})"), Expression.Constant(null)); + manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAny); + asSelectBefores.Clear(); + + return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); + } for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) { - var col1 = parm123Ref.MiddleColumns[mn]; + var col1 = parm123Ref.RefColumns[mn]; var col2 = parm123Ref.Columns[mn]; - var pexp1 = Expression.Property(manySubSelectWhereParam, col1.CsName); + var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); if (col1.CsType != col2.CsType) { @@ -742,59 +793,11 @@ namespace FreeSql.Internal if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); } var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) manySubSelectWhereExp = tmpExp; - else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp); + if (mn == 0) fsqlWhereExp = tmpExp; + else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp); } - var manySubSelectExpBoy = Expression.Call( - manySubSelectAsSelectExp, - manySubSelectWhere, - Expression.Lambda( - manySubSelectWhereExp, - manySubSelectWhereParam - ) - ); - Expression fsqlManyWhereExp = null; - for (var mn = 0; mn < parm123Ref.RefColumns.Count; mn++) - { - var col1 = parm123Ref.RefColumns[mn]; - var col2 = parm123Ref.MiddleColumns[mn + parm123Ref.Columns.Count + mn]; - var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); - var pexp2 = Expression.Property(manySubSelectWhereParam, col2.CsName); - if (col1.CsType != col2.CsType) - { - if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); - if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); - } - var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) fsqlManyWhereExp = tmpExp; - else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp); - } - fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent }); - fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); - var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); - if (string.IsNullOrEmpty(sql2) == false) - manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace("\r\n", "\r\n\t")})"), Expression.Constant(null)); - manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAny); - asSelectBefores.Clear(); - - return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); + fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) }); } - for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) - { - var col1 = parm123Ref.RefColumns[mn]; - var col2 = parm123Ref.Columns[mn]; - var pexp1 = Expression.Property(fsqlWhereParam, col1.CsName); - var pexp2 = Expression.Property(asSelectParentExp, col2.CsName); - if (col1.CsType != col2.CsType) - { - if (col1.CsType.IsNullableType()) pexp1 = Expression.Property(pexp1, _dicNullableValueProperty.GetOrAdd(col1.CsType, ct1 => ct1.GetProperty("Value"))); - if (col2.CsType.IsNullableType()) pexp2 = Expression.Property(pexp2, _dicNullableValueProperty.GetOrAdd(col2.CsType, ct2 => ct2.GetProperty("Value"))); - } - var tmpExp = Expression.Equal(pexp1, pexp2); - if (mn == 0) fsqlWhereExp = tmpExp; - else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp); - } - fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) }); } asSelectBefores.Clear(); @@ -1174,7 +1177,8 @@ namespace FreeSql.Internal if (_whereCascadeExpression.Any()) { var newParameter = Expression.Parameter(tb.Table.Type, "c"); - Expression newExp = null; + var sb = new StringBuilder(); + var isEmpty = true; foreach (var fl in _whereCascadeExpression) { @@ -1184,9 +1188,13 @@ namespace FreeSql.Internal var visitor = new NewExpressionVisitor(newParameter, fl.Parameters.FirstOrDefault()); try { - var andExp = visitor.Replace(fl.Body); - if (newExp == null) newExp = andExp; - else newExp = Expression.AndAlso(newExp, andExp); + var expExp = visitor.Replace(fl.Body); + var whereSql = ExpressionLambdaToSql(expExp, new ExpTSC { _tables = null, _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + if (isEmpty == false) + sb.Append(" AND "); + else + isEmpty = false; + sb.Append("(").Append(whereSql).Append(")"); } catch { @@ -1195,8 +1203,8 @@ namespace FreeSql.Internal } } - if (newExp != null) - return ExpressionLambdaToSql(newExp, new ExpTSC { _tables = null, _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + if (isEmpty == false) + return sb.ToString(); } return null; } From 6d9b6b66709dea883608b1ff074d1ab85bc86378 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 12 Aug 2019 16:53:13 +0800 Subject: [PATCH 0083/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect=20Su?= =?UTF-8?q?m/First=20=E5=AD=90=E6=9F=A5=E8=AF=A2=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E8=8B=A5=E5=AD=90=E6=9F=A5=E8=AF=A2=E5=AE=9E=E4=BD=93=E7=B1=BB?= =?UTF-8?q?=E4=B8=8E=E4=B8=BB=E6=9F=A5=E8=AF=A2=E4=B8=80=E6=A0=B7=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E8=87=B4=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 4 ++-- .../FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 4 ++-- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 4 ++-- FreeSql/Internal/CommonExpression.cs | 10 ++++++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 6e4180c8..66c05d41 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -884,12 +884,12 @@ namespace FreeSql.Tests.MySqlConnector var subquery = select.ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.Sum(b => b.Id) }); var subqueryList = select.ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.Sum(b => b.Id) }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index a6006fdb..b98117d7 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -874,12 +874,12 @@ namespace FreeSql.Tests.MySql var subquery = select.ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.Sum(b => b.Id) }); var subqueryList = select.ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.Sum(b => b.Id) }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 42ff5ad9..a898a01e 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -832,12 +832,12 @@ namespace FreeSql.Tests.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.Sum(b => b.Id) }); var subqueryList = select.ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.Sum(b => b.Id) }); } [Fact] diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 887c48f3..a08490a0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -817,12 +817,18 @@ namespace FreeSql.Internal case "Min": case "Max": case "Avg": - var sqlSum = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tsc)})" })?.ToString(); + var tscClone1 = tsc.CloneDisableDiyParse(); + tscClone1.isDisableDiyParse = false; + tscClone1._tables = fsqltables; + var sqlSum = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone1)})" })?.ToString(); if (string.IsNullOrEmpty(sqlSum) == false) return $"({sqlSum.Replace("\r\n", "\r\n\t")})"; break; case "First": - var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tsc) })?.ToString(); + var tscClone2 = tsc.CloneDisableDiyParse(); + tscClone2.isDisableDiyParse = false; + tscClone2._tables = fsqltables; + var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone2) })?.ToString(); if (string.IsNullOrEmpty(sqlFirst) == false) return $"({sqlFirst.Replace("\r\n", "\r\n\t")})"; break; From 328824216b801c634df2bd3becf124dab8c6e6c8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Aug 2019 10:53:09 +0800 Subject: [PATCH 0084/1029] v0.8.5 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 723659d9..7fa794b1 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.4 + 0.8.5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 69698d0a..5ad41619 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 51a737fe..49e5689b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index b0a0c35d..c619fa87 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.4 + 0.8.5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0f3a4731..6cbdc646 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0ae86b5b..292ba9b1 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index c4fe39b8..71124f9b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 3a271873..b47a9358 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 14d2c7e4..d19e1215 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 209c1b00..554af458 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c9e4597e..07db3243 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.4 + 0.8.5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From dce7496b014c08b95b75ffa94c1e7e19548da3e4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Aug 2019 10:54:35 +0800 Subject: [PATCH 0085/1029] v0.8.5 --- .../BaseEntity.cs | 168 +++++++---- .../BaseEntityAsync.cs | 203 +++++++------ .../BaseEntityAsyncTKey.cs | 44 --- .../BaseEntityReadOnly.cs | 160 ++++++++++ .../BaseEntitySync.cs | 80 ----- .../BaseEntitySyncTKey.cs | 56 ---- .../BaseEntityTree.cs | 164 ++++++++++ .../FreeSql.Extensions.BaseEntity.xml | 279 ++++++++++-------- 8 files changed, 704 insertions(+), 450 deletions(-) delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsyncTKey.cs create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySync.cs delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySyncTKey.cs create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index 1015bd55..213fb038 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -7,65 +7,129 @@ using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; -/// -/// 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 -/// -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity +namespace FreeSql { - static IFreeSql _ormPriv; /// - /// 全局 IFreeSql orm 对象 + /// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 + /// + /// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 /// - public static IFreeSql Orm => _ormPriv ?? throw new Exception(@"使用前请初始化 BaseEntity.Initialization(new FreeSqlBuilder() -.UseAutoSyncStructure(true) -.UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") -.Build());"); - - /// - /// 初始化BaseEntity - /// BaseEntity.Initialization(new FreeSqlBuilder() - /// - /// .UseAutoSyncStructure(true) - /// - /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") - /// - /// .Build()); - /// - /// IFreeSql orm 对象 - public static void Initialization(IFreeSql fsql) + /// + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntity : BaseEntity where TEntity : class { - _ormPriv = fsql; - _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); + static BaseEntity() + { + var tkeyType = typeof(TKey)?.NullableTypeOrThis(); + if (tkeyType == typeof(int) || tkeyType == typeof(long)) + Orm.CodeFirst.ConfigEntity(typeof(TEntity), + t => t.Property("Id").IsIdentity(true)); + } + + /// + /// 主键 + /// + public virtual TKey Id { get; set; } + + /// + /// 根据主键值获取数据 + /// + /// + /// + async public static Task FindAsync(TKey id) + { + var item = await Select.WhereDynamic(id).FirstAsync(); + (item as BaseEntity)?.Attach(); + return item; + } + + /// + /// 根据主键值获取数据 + /// + /// + /// + public static TEntity Find(TKey id) + { + var item = Select.WhereDynamic(id).First(); + (item as BaseEntity)?.Attach(); + return item; + } } /// - /// 创建时间 + /// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 /// - public DateTime CreateTime { get; set; } - /// - /// 更新时间 - /// - public DateTime UpdateTime { get; set; } - /// - /// 逻辑删除 - /// - public bool IsDeleted { get; set; } - - /// - /// 开启工作单元事务 - /// - /// - public static IUnitOfWork Begin() => Begin(null); - /// - /// 开启工作单元事务 - /// - /// 事务等级 - /// - public static IUnitOfWork Begin(IsolationLevel? level) + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntity : BaseEntityAsync where TEntity : class { - var uow = Orm.CreateUnitOfWork(); - uow.IsolationLevel = level; - return uow; + bool UpdateIsDeleted(bool value) + { + if (this.Repository == null) + return Orm.Update(this as TEntity) + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; + + this.SetTenantId(); + this.IsDeleted = value; + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 删除数据 + /// + /// + public virtual bool Delete() => this.UpdateIsDeleted(true); + /// + /// 恢复删除的数据 + /// + /// + public virtual bool Restore() => this.UpdateIsDeleted(false); + + /// + /// 更新数据 + /// + /// + public virtual bool Update() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + return Orm.Update() + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .SetSource(this as TEntity).ExecuteAffrows() == 1; + + this.SetTenantId(); + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 插入数据 + /// + public virtual TEntity Insert() + { + this.CreateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.SetTenantId(); + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.Insert(this as TEntity); + } + + /// + /// 更新或插入 + /// + /// + public virtual TEntity Save() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.SetTenantId(); + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.InsertOrUpdate(this as TEntity); + } } -} +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index 8d5f2399..4b98dca2 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -1,121 +1,118 @@ using FreeSql; using FreeSql.DataAnnotations; using System; -using System.Data; -using System.Diagnostics; -using System.Linq.Expressions; -using System.Threading; using System.Threading.Tasks; -/// -/// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步方法的实体基类 -/// -/// -[Table(DisableSyncStructure = true)] -public abstract class BaseEntityAsync : BaseEntity where TEntity : class +namespace FreeSql { /// - /// 查询数据 + /// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 异步方法、以及 ID 主键定义 的实体基类 + /// + /// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 /// - /// - public static ISelect Select => Orm.Select() - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)) - .WhereCascade(a => (a as BaseEntity).IsDeleted == false); - /// - /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - /// - /// lambda表达式 - /// - public static ISelect Where(Expression> exp) => Select.Where(exp); - /// - /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - /// - /// true 时生效 - /// lambda表达式 - /// - public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); - - /// - /// 仓储对象 - /// - protected IBaseRepository Repository { get; set; } - - /// - /// 附加实体,在更新数据时,只更新变化的部分 - /// - public TEntity Attach() + /// + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntityAsync : BaseEntityAsync where TEntity : class { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); + static BaseEntityAsync() + { + var tkeyType = typeof(TKey)?.NullableTypeOrThis(); + if (tkeyType == typeof(int) || tkeyType == typeof(long)) + Orm.CodeFirst.ConfigEntity(typeof(TEntity), + t => t.Property("Id").IsIdentity(true)); + } - var item = this as TEntity; - this.Repository.Attach(item); - return item; - } + /// + /// 主键 + /// + public virtual TKey Id { get; set; } - /** async **/ - - async Task UpdateIsDeletedAsync(bool value) - { - if (this.Repository == null) - return await Orm.Update(this as TEntity) - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) - .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; - - this.IsDeleted = value; - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return await this.Repository.UpdateAsync(this as TEntity) == 1; - } - /// - /// 删除数据 - /// - /// - public virtual Task DeleteAsync() => this.UpdateIsDeletedAsync(true); - /// - /// 恢复删除的数据 - /// - /// - public virtual Task RestoreAsync() => this.UpdateIsDeletedAsync(false); - - /// - /// 更新数据 - /// - /// - async public virtual Task UpdateAsync() - { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - return await Orm.Update() - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) - .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; - - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return await this.Repository.UpdateAsync(this as TEntity) == 1; - } - /// - /// 插入数据 - /// - public virtual Task InsertAsync() - { - this.CreateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return this.Repository.InsertAsync(this as TEntity); + /// + /// 根据主键值获取数据 + /// + /// + /// + async public static Task FindAsync(TKey id) + { + var item = await Select.WhereDynamic(id).FirstAsync(); + (item as BaseEntity)?.Attach(); + return item; + } } /// - /// 更新或插入 + /// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步方法的实体基类 /// - /// - public virtual Task SaveAsync() + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntityAsync : BaseEntityReadOnly where TEntity : class { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); + async Task UpdateIsDeletedAsync(bool value) + { + if (this.Repository == null) + return await Orm.Update(this as TEntity) + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return this.Repository.InsertOrUpdateAsync(this as TEntity); + this.IsDeleted = value; + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return await this.Repository.UpdateAsync(this as TEntity) == 1; + } + /// + /// 删除数据 + /// + /// + public virtual Task DeleteAsync() => this.UpdateIsDeletedAsync(true); + /// + /// 恢复删除的数据 + /// + /// + public virtual Task RestoreAsync() => this.UpdateIsDeletedAsync(false); + + /// + /// 更新数据 + /// + /// + async public virtual Task UpdateAsync() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + return await Orm.Update() + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; + + this.SetTenantId(); + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return await this.Repository.UpdateAsync(this as TEntity) == 1; + } + /// + /// 插入数据 + /// + public virtual Task InsertAsync() + { + this.CreateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.SetTenantId(); + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.InsertAsync(this as TEntity); + } + + /// + /// 更新或插入 + /// + /// + public virtual Task SaveAsync() + { + this.UpdateTime = DateTime.Now; + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.SetTenantId(); + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.InsertOrUpdateAsync(this as TEntity); + } } -} +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsyncTKey.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsyncTKey.cs deleted file mode 100644 index cb1b8b3e..00000000 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsyncTKey.cs +++ /dev/null @@ -1,44 +0,0 @@ -using FreeSql; -using FreeSql.DataAnnotations; -using System; -using System.Data; -using System.Diagnostics; -using System.Linq.Expressions; -using System.Threading; -using System.Threading.Tasks; - -/// -/// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 异步方法、以及 ID 主键定义 的实体基类 -/// -/// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 -/// -/// -/// -[Table(DisableSyncStructure = true)] -public abstract class BaseEntityAsync : BaseEntityAsync where TEntity : class -{ - static BaseEntityAsync() - { - var tkeyType = typeof(TKey)?.NullableTypeOrThis(); - if (tkeyType == typeof(int) || tkeyType == typeof(long)) - Orm.CodeFirst.ConfigEntity(typeof(TEntity), - t => t.Property("Id").IsIdentity(true)); - } - - /// - /// 主键 - /// - public virtual TKey Id { get; set; } - - /// - /// 根据主键值获取数据 - /// - /// - /// - async public static Task FindAsync(TKey id) - { - var item = await Select.WhereDynamic(id).FirstAsync(); - (item as BaseEntity)?.Attach(); - return item; - } -} diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs new file mode 100644 index 00000000..21d35c1f --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -0,0 +1,160 @@ +using FreeSql.DataAnnotations; +using System; +using System.Data; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Threading; + +namespace FreeSql +{ + /// + /// 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntity + { + static IFreeSql _ormPriv; + /// + /// 全局 IFreeSql orm 对象 + /// + public static IFreeSql Orm => _ormPriv ?? throw new Exception(@"使用前请初始化 BaseEntity.Initialization(new FreeSqlBuilder() +.UseAutoSyncStructure(true) +.UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") +.Build());"); + + /// + /// 初始化BaseEntity + /// BaseEntity.Initialization(new FreeSqlBuilder() + /// + /// .UseAutoSyncStructure(true) + /// + /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") + /// + /// .Build()); + /// + /// IFreeSql orm 对象 + public static void Initialization(IFreeSql fsql) + { + _ormPriv = fsql; + _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); + } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + /// + /// 更新时间 + /// + public DateTime UpdateTime { get; set; } + /// + /// 逻辑删除 + /// + public bool IsDeleted { get; set; } + /// + /// 排序 + /// + public int Sort { get; set; } + + /// + /// 开启工作单元事务 + /// + /// + public static IUnitOfWork Begin() => Begin(null); + /// + /// 开启工作单元事务 + /// + /// 事务等级 + /// + public static IUnitOfWork Begin(IsolationLevel? level) + { + var uow = Orm.CreateUnitOfWork(); + uow.IsolationLevel = level; + return uow; + } + + static readonly AsyncLocal _AsyncTenantId = new AsyncLocal(); + /// + /// 获取或设置当前租户id + /// + public static string CurrentTenantId + { + get => _AsyncTenantId.Value; + set => _AsyncTenantId.Value = value; + } + } + + /// + /// 租户 + /// + public interface ITenant + { + /// + /// 租户id + /// + string TenantId { get; set; } + } + + public abstract class BaseEntityReadOnly : BaseEntity where TEntity : class + { + /// + /// 查询数据 + /// + /// + public static ISelect Select + { + get + { + var select = Orm.Select().WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)); + if (string.IsNullOrEmpty(CurrentTenantId) == false) + select.WhereCascade(a => (a as ITenant).TenantId == CurrentTenantId); + return select.WhereCascade(a => (a as BaseEntity).IsDeleted == false); + } + } + /// + /// 设置当前租户id + /// + protected void SetTenantId() + { + if (string.IsNullOrEmpty(CurrentTenantId) == false) + { + var ten = this as ITenant; + if (ten != null) + ten.TenantId = CurrentTenantId; + } + } + + /// + /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + /// + /// lambda表达式 + /// + public static ISelect Where(Expression> exp) => Select.Where(exp); + /// + /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + /// + /// true 时生效 + /// lambda表达式 + /// + public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); + + /// + /// 仓储对象 + /// + protected IBaseRepository Repository { get; set; } + + /// + /// 附加实体,在更新数据时,只更新变化的部分 + /// + public TEntity Attach() + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + var item = this as TEntity; + this.SetTenantId(); + this.Repository.Attach(item); + return item; + } + } +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySync.cs deleted file mode 100644 index eab376b7..00000000 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySync.cs +++ /dev/null @@ -1,80 +0,0 @@ -using FreeSql; -using FreeSql.DataAnnotations; -using System; -using System.Data; -using System.Diagnostics; -using System.Linq.Expressions; -using System.Threading; -using System.Threading.Tasks; - -/// -/// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 -/// -/// -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity : BaseEntityAsync where TEntity : class -{ - bool UpdateIsDeleted(bool value) - { - if (this.Repository == null) - return Orm.Update(this as TEntity) - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) - .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; - - this.IsDeleted = value; - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return this.Repository.Update(this as TEntity) == 1; - } - /// - /// 删除数据 - /// - /// - public virtual bool Delete() => this.UpdateIsDeleted(true); - /// - /// 恢复删除的数据 - /// - /// - public virtual bool Restore() => this.UpdateIsDeleted(false); - - /// - /// 更新数据 - /// - /// - public virtual bool Update() - { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - return Orm.Update() - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) - .SetSource(this as TEntity).ExecuteAffrows() == 1; - - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return this.Repository.Update(this as TEntity) == 1; - } - /// - /// 插入数据 - /// - public virtual TEntity Insert() - { - this.CreateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return this.Repository.Insert(this as TEntity); - } - - /// - /// 更新或插入 - /// - /// - public virtual TEntity Save() - { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - this.Repository.UnitOfWork = UnitOfWork.Current.Value; - return this.Repository.InsertOrUpdate(this as TEntity); - } -} diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySyncTKey.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySyncTKey.cs deleted file mode 100644 index 359e155a..00000000 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntitySyncTKey.cs +++ /dev/null @@ -1,56 +0,0 @@ -using FreeSql; -using FreeSql.DataAnnotations; -using System; -using System.Data; -using System.Diagnostics; -using System.Linq.Expressions; -using System.Threading; -using System.Threading.Tasks; - -/// -/// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 -/// -/// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 -/// -/// -/// -[Table(DisableSyncStructure = true)] -public abstract class BaseEntity : BaseEntity where TEntity : class -{ - static BaseEntity() - { - var tkeyType = typeof(TKey)?.NullableTypeOrThis(); - if (tkeyType == typeof(int) || tkeyType == typeof(long)) - Orm.CodeFirst.ConfigEntity(typeof(TEntity), - t => t.Property("Id").IsIdentity(true)); - } - - /// - /// 主键 - /// - public virtual TKey Id { get; set; } - - /// - /// 根据主键值获取数据 - /// - /// - /// - async public static Task FindAsync(TKey id) - { - var item = await Select.WhereDynamic(id).FirstAsync(); - (item as BaseEntity)?.Attach(); - return item; - } - - /// - /// 根据主键值获取数据 - /// - /// - /// - public static TEntity Find(TKey id) - { - var item = Select.WhereDynamic(id).First(); - (item as BaseEntity)?.Attach(); - return item; - } -} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs new file mode 100644 index 00000000..fa7bd5b1 --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs @@ -0,0 +1,164 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql +{ + /// + /// 树状基类 + /// + /// + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntityTree : BaseEntity where TEntity : class + { + /// + /// 父级id + /// + public TKey ParentId + { + get => _ParentId; + set + { + if (Equals(value, default(TKey)) == false && Equals(value, Id)) + throw new ArgumentException("ParentId 值不能与 Id 相同"); + _ParentId = value; + } + } + public TEntity Parent { get; set; } + private TKey _ParentId; + + /// + /// 下级列表 + /// + [Navigate("ParentId")] + public List Childs { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + /// + /// 名称:技术部-前端 + /// + public string FullName { get; set; } + + public List GetAllChilds() => Select.WhereDynamic(this) + .IncludeMany(a => (a as BaseEntityTree).Childs, + t1 => t1.IncludeMany(a1 => (a1 as BaseEntityTree).Childs, + t2 => t2.IncludeMany(a2 => (a2 as BaseEntityTree).Childs, + t3 => t3.IncludeMany(a3 => (a3 as BaseEntityTree).Childs, + t4 => t4.IncludeMany(a4 => (a4 as BaseEntityTree).Childs, + t5 => t5.IncludeMany(a5 => (a5 as BaseEntityTree).Childs, + t6 => t6.IncludeMany(a6 => (a6 as BaseEntityTree).Childs, + t7 => t7.IncludeMany(a7 => (a7 as BaseEntityTree).Childs, + t8 => t8.IncludeMany(a8 => (a8 as BaseEntityTree).Childs, + t9 => t9.IncludeMany(a9 => (a9 as BaseEntityTree).Childs, + t10 => t10.IncludeMany(a10 => (a10 as BaseEntityTree).Childs))))))))))).ToList() + .SelectMany(a => (a as BaseEntityTree).Childs + .SelectMany(a1 => (a1 as BaseEntityTree)?.Childs + .SelectMany(a2 => (a2 as BaseEntityTree)?.Childs + .SelectMany(a3 => (a3 as BaseEntityTree)?.Childs + .SelectMany(a4 => (a4 as BaseEntityTree)?.Childs + .SelectMany(a5 => (a5 as BaseEntityTree)?.Childs + .SelectMany(a6 => (a6 as BaseEntityTree)?.Childs + .SelectMany(a7 => (a7 as BaseEntityTree)?.Childs + .SelectMany(a8 => (a8 as BaseEntityTree)?.Childs + .SelectMany(a9 => (a9 as BaseEntityTree)?.Childs + .SelectMany(a10 => (a10 as BaseEntityTree)?.Childs))))))))))).Where(a => a != null).ToList(); + + protected void RefershFullName() + { + var buf = new List(); + buf.Add(this as TEntity); + buf.AddRange(this.GetAllChilds()); + var repo = Orm.GetRepository(); + repo.UnitOfWork = UnitOfWork.Current.Value; + buf = repo.Select.WhereDynamic(buf) + .Include(a => ((((((((((a as BaseEntityTree).Parent + as BaseEntityTree).Parent + as BaseEntityTree).Parent + as BaseEntityTree).Parent + as BaseEntityTree).Parent + as BaseEntityTree).Parent + as BaseEntityTree).Parent + as BaseEntityTree).Parent + as BaseEntityTree).Parent + as BaseEntityTree).Parent).ToList(true); + foreach (var item in buf) + { + var up = item as BaseEntityTree; + up.Name = up.Name; + var cur = up.Parent as BaseEntityTree; + while (cur != null) + { + up.Name = $"{cur.Name}-{up.Name}"; + cur = cur.Parent as BaseEntityTree; + } + } + repo.Update(buf); + } + + T UpdateIsDelete(bool value, Func, List, T> func) + { + var childs = GetAllChilds(); + childs.Add(this as TEntity); + var repo = Orm.GetRepository(); + repo.UnitOfWork = UnitOfWork.Current.Value; + repo.Attach(childs); + foreach (var item in childs) + (item as BaseEntity).IsDeleted = false; + return func(repo, childs); + } + public override bool Delete() => UpdateIsDelete(true, (repo, chis) => repo.Update(chis)) > 0; + async public override Task DeleteAsync() => await UpdateIsDelete(true, (repo, chis) => repo.UpdateAsync(chis)) > 0; + + public override bool Restore() => UpdateIsDelete(false, (repo, chis) => repo.Update(chis)) > 0; + async public override Task RestoreAsync() => await UpdateIsDelete(false, (repo, chis) => repo.UpdateAsync(chis)) > 0; + + public override TEntity Insert() + { + var ret = base.Insert(); + RefershFullName(); + return ret; + } + async public override Task InsertAsync() + { + var ret = await base.InsertAsync(); + RefershFullName(); + return ret; + } + public override bool Update() + { + var old = Find(this.Id) as BaseEntityTree; + var ret = base.Update(); + if (old.Name != this.Name || Equals(old.ParentId, old.ParentId) == false) RefershFullName(); + return ret; + } + async public override Task UpdateAsync() + { + var old = Find(this.Id) as BaseEntityTree; + var ret = await base.UpdateAsync(); + if (old.Name != this.Name || Equals(old.ParentId, old.ParentId) == false) RefershFullName(); + return ret; + } + public override TEntity Save() + { + var old = Find(this.Id) as BaseEntityTree; + var ret = base.Save(); + if (old.Name != this.Name || Equals(old.ParentId, old.ParentId) == false) RefershFullName(); + return ret; + } + async public override Task SaveAsync() + { + var old = Find(this.Id) as BaseEntityTree; + var ret = await base.SaveAsync(); + if (old.Name != this.Name || Equals(old.ParentId, old.ParentId) == false) RefershFullName(); + return ret; + } + } +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml index 6a86cb7c..a03b9ba3 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml @@ -4,17 +4,136 @@ FreeSql.Extensions.BaseEntity - + + + 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 + + 当 TKey 为 int/long 时,Id 主键被设为自增值主键 + + + + + + + 主键 + + + + + 根据主键值获取数据 + + + + + + + 根据主键值获取数据 + + + + + + + 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 + + + + + + 删除数据 + + + + + + 恢复删除的数据 + + + + + + 更新数据 + + + + + + 插入数据 + + + + + 更新或插入 + + + + + + 包括 CreateTime/UpdateTime/IsDeleted、CRUD 异步方法、以及 ID 主键定义 的实体基类 + + 当 TKey 为 int/long 时,Id 主键被设为自增值主键 + + + + + + + 主键 + + + + + 根据主键值获取数据 + + + + + + + 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步方法的实体基类 + + + + + + 删除数据 + + + + + + 恢复删除的数据 + + + + + + 更新数据 + + + + + + 插入数据 + + + + + 更新或插入 + + + + 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 - + 全局 IFreeSql orm 对象 - + 初始化BaseEntity BaseEntity.Initialization(new FreeSqlBuilder() @@ -27,54 +146,73 @@ IFreeSql orm 对象 - + 创建时间 - + 更新时间 - + 逻辑删除 - + + + 排序 + + + 开启工作单元事务 - + 开启工作单元事务 事务等级 - + - 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步方法的实体基类 + 获取或设置当前租户id - - + + + 租户 + + + + + 租户id + + + 查询数据 - + + + 设置当前租户id + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") lambda表达式 - + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") @@ -82,131 +220,42 @@ lambda表达式 - + 仓储对象 - + 附加实体,在更新数据时,只更新变化的部分 - - async * - - + - 删除数据 - - - - - - 恢复删除的数据 - - - - - - 更新数据 - - - - - - 插入数据 - - - - - 更新或插入 - - - - - - 包括 CreateTime/UpdateTime/IsDeleted、CRUD 异步方法、以及 ID 主键定义 的实体基类 - - 当 TKey 为 int/long 时,Id 主键被设为自增值主键 + 树状基类 - + - 主键 + 父级id - + - 根据主键值获取数据 - - - - - - - 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 - - - - - - 删除数据 - - - - - - 恢复删除的数据 - - - - - - 更新数据 - - - - - - 插入数据 + 下级列表 - + - 更新或插入 - - - - - - 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 - - 当 TKey 为 int/long 时,Id 主键被设为自增值主键 - - - - - - - 主键 + 名称 - + - 根据主键值获取数据 + 名称:技术部-前端 - - - - - - 根据主键值获取数据 - - - From 79ab3ae2178b23bc290152df52ad40717fbf4a93 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Aug 2019 17:17:38 +0800 Subject: [PATCH 0086/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20IsIgnore=20=E5=BF=BD=E7=95=A5=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=86=8D=E4=BD=BF=E7=94=A8=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E5=8F=8B=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 29 +++++++------------ .../DbContext/DbContextOptionsBuilder.cs | 6 ++++ FreeSql.DbContext/DbSet/DbSet.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 16 +++++++++- FreeSql/Internal/CommonExpression.cs | 9 +++++- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 6c6867d7..e979d460 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -11,18 +11,16 @@ namespace FreeSql { internal IFreeSql _orm; - internal IFreeSql _fsql => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); - - public IFreeSql Orm => _fsql; + public IFreeSql Orm => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); protected IUnitOfWork _uowPriv; - internal IUnitOfWork _uow => _isUseUnitOfWork ? (_uowPriv ?? (_uowPriv = new UnitOfWork(_fsql))) : null; + internal IUnitOfWork _uow => _isUseUnitOfWork ? (_uowPriv ?? (_uowPriv = new UnitOfWork(Orm))) : null; internal bool _isUseUnitOfWork = true; //不使用工作单元事务 public IUnitOfWork UnitOfWork => _uow; DbContextOptions _options; - internal DbContextOptions Options + public DbContextOptions Options { get { @@ -31,19 +29,22 @@ namespace FreeSql _options = new DbContextOptions(); return _options; } + set => _options = value; } - - static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); + protected DbContext() { var builder = new DbContextOptionsBuilder(); OnConfiguring(builder); _orm = builder._fsql; + _options = builder._options; if (_orm != null) InitPropSets(); } + protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { } + static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); internal void InitPropSets() { var props = _dicGetDbSetProps.GetOrAdd(this.GetType(), tp => @@ -60,11 +61,6 @@ namespace FreeSql } } - protected virtual void OnConfiguring(DbContextOptionsBuilder builder) - { - - } - protected Dictionary _dicSet = new Dictionary(); public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; public virtual IDbSet Set(Type entityType) @@ -133,15 +129,10 @@ namespace FreeSql Queue _actions = new Queue(); internal int _affrows = 0; - internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, object state) - { + internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, object state) => _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); - } - ~DbContext() - { - this.Dispose(); - } + ~DbContext() => this.Dispose(); bool _isdisposed = false; public void Dispose() { diff --git a/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs b/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs index 0801cfe2..02735dff 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs @@ -6,11 +6,17 @@ namespace FreeSql { internal IFreeSql _fsql; + internal DbContextOptions _options; public DbContextOptionsBuilder UseFreeSql(IFreeSql orm) { _fsql = orm; return this; } + public DbContextOptionsBuilder UseOptions(DbContextOptions options) + { + _options = options; + return this; + } } } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index dbac00d5..59abb863 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -18,7 +18,7 @@ namespace FreeSql { _ctx = ctx; _uow = ctx._uow; - _fsql = ctx._fsql; + _fsql = ctx.Orm; } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index f203537a..741f66f8 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -283,7 +283,7 @@ namespace FreeSql.Tests { [FreeSql.DataAnnotations.Column(IsPrimary = true)] - public Guid Id { get; set; } + public Guid Id { get; protected set; } public string TaskName { get; set; } public Guid TemplatesId { get; set; } public string GeneratePath { get; set; } @@ -338,9 +338,23 @@ namespace FreeSql.Tests public DateTime class2 { set; get; } } + class TestDto + { + public Guid Id { get; set; } + public bool IsLeaf { get; set; } + } + [Fact] public void Test1() { + var dkdkd = g.mysql.Select().AsTable((t,old) => "TaskBuild22") + .ToList< TestDto>(a => new TestDto() + { + Id = a.Id, + IsLeaf = g.mysql.Select().AsTable((t, old) => "TaskBuild22").Any(b => b.TemplatesId == a.Id) + }); + + var xxxkdkd = g.oracle.Select() .InnerJoin((a,b) => true) .Where((a,b) => (DateTime.Now - a.EditTime).TotalMinutes > 100) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index a08490a0..e9b4b6fe 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -922,7 +922,12 @@ namespace FreeSql.Internal var pp = expStack.Pop() as ParameterExpression; var memberExp = expStack.Pop() as MemberExpression; var tb = _common.GetTableByEntity(pp.Type); - if (tb.ColumnsByCs.ContainsKey(memberExp.Member.Name) == false) throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}"); + if (tb.ColumnsByCs.ContainsKey(memberExp.Member.Name) == false) + { + if (tb.ColumnsByCsIgnore.ContainsKey(memberExp.Member.Name)) + throw new ArgumentException($"{tb.DbName}.{memberExp.Member.Name} 被忽略,请检查 IsIgnore 设置,确认 get/set 为 public"); + throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}"); + } if (tsc._selectColumnMap != null) { tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = tb.ColumnsByCs[memberExp.Member.Name] }); @@ -1079,6 +1084,8 @@ namespace FreeSql.Internal if (tb3.Columns.Any()) return ""; } } + if (tb2.ColumnsByCsIgnore.ContainsKey(mp2.Member.Name)) + throw new ArgumentException($"{tb2.DbName}.{mp2.Member.Name} 被忽略,请检查 IsIgnore 设置,确认 get/set 为 public"); throw new ArgumentException($"{tb2.DbName} 找不到列 {mp2.Member.Name}"); } var col2 = tb2.ColumnsByCs[mp2.Member.Name]; From a79ee52b4f450293e467b2b4cdc7e10482f0dd39 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Aug 2019 19:13:48 +0800 Subject: [PATCH 0087/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20DbContext/Re?= =?UTF-8?q?pository=20=E5=B1=80=E9=83=A8=E8=B0=83=E6=95=B4=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Entities/User.cs | 4 +- Examples/base_entity/Program.cs | 3 +- FreeSql.DbContext/DbContext/DbContext.cs | 66 ++++++++----- FreeSql.DbContext/DbContext/DbContextAsync.cs | 2 +- FreeSql.DbContext/DbContext/DbContextSync.cs | 2 +- FreeSql.DbContext/DbContext/FreeContext.cs | 2 +- FreeSql.DbContext/DbSet/DbSet.cs | 98 +++++++++---------- FreeSql.DbContext/DbSet/DbSetAsync.cs | 54 +++++----- FreeSql.DbContext/DbSet/DbSetSync.cs | 56 +++++------ .../Extenssions/DependencyInjection.cs | 31 +++--- .../ContextSet/RepositoryDbContext.cs | 29 +++--- .../Repository/ContextSet/RepositoryDbSet.cs | 31 +++--- .../ContextSet/RepositoryUnitOfWork.cs | 18 ++-- .../Repository/Repository/BaseRepository.cs | 12 +-- 14 files changed, 211 insertions(+), 197 deletions(-) diff --git a/Examples/base_entity/Entities/User.cs b/Examples/base_entity/Entities/User.cs index 7db6ab8c..687feb55 100644 --- a/Examples/base_entity/Entities/User.cs +++ b/Examples/base_entity/Entities/User.cs @@ -1,6 +1,6 @@ -using System; +using FreeSql; +using System; using System.Collections.Generic; -using System.Text; public class UserGroup : BaseEntity { diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 76297250..d6868178 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql; +using System; using System.Threading.Tasks; namespace base_entity diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index e979d460..364326eb 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -9,41 +9,51 @@ namespace FreeSql { public abstract partial class DbContext : IDisposable { + internal IFreeSql _ormPriv; + public IFreeSql Orm => _ormPriv ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); - internal IFreeSql _orm; - public IFreeSql Orm => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); - - protected IUnitOfWork _uowPriv; - internal IUnitOfWork _uow => _isUseUnitOfWork ? (_uowPriv ?? (_uowPriv = new UnitOfWork(Orm))) : null; - internal bool _isUseUnitOfWork = true; //不使用工作单元事务 - - public IUnitOfWork UnitOfWork => _uow; - - DbContextOptions _options; - public DbContextOptions Options + #region Property UnitOfWork + internal bool _isUseUnitOfWork = true; //是否使用工作单元事务 + IUnitOfWork _uowPriv; + public IUnitOfWork UnitOfWork { + set => _uowPriv = value; get { - if (_options != null) return _options; - if (FreeSqlDbContextExtenssions._dicSetDbContextOptions.TryGetValue(Orm, out _options)) return _options; - _options = new DbContextOptions(); - return _options; + if (_uowPriv != null) return _uowPriv; + if (_isUseUnitOfWork == false) return null; + return _uowPriv = new UnitOfWork(Orm); } - set => _options = value; } - + #endregion + + #region Property Options + internal DbContextOptions _optionsPriv; + public DbContextOptions Options + { + set => _optionsPriv = value; + get + { + if (_optionsPriv != null) return _optionsPriv; + if (FreeSqlDbContextExtenssions._dicSetDbContextOptions.TryGetValue(Orm, out _optionsPriv)) return _optionsPriv; + _optionsPriv = new DbContextOptions(); + return _optionsPriv; + } + } + #endregion + protected DbContext() { - var builder = new DbContextOptionsBuilder(); OnConfiguring(builder); - _orm = builder._fsql; - _options = builder._options; + _ormPriv = builder._fsql; + _optionsPriv = builder._options; - if (_orm != null) InitPropSets(); + if (_ormPriv != null) InitPropSets(); } protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { } + #region Set static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); internal void InitPropSets() { @@ -61,16 +71,19 @@ namespace FreeSql } } + protected List _listSet = new List(); protected Dictionary _dicSet = new Dictionary(); public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; public virtual IDbSet Set(Type entityType) { if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; var sd = Activator.CreateInstance(typeof(DbContextDbSet<>).MakeGenericType(entityType), this) as IDbSet; + _listSet.Add(sd); if (entityType != typeof(object)) _dicSet.Add(entityType, sd); return sd; } protected Dictionary AllSets { get; } = new Dictionary(); + #endregion #region DbSet 快速代理 /// @@ -118,6 +131,7 @@ namespace FreeSql public void AttachRange(IEnumerable data) where TEntity : class => this.Set().AttachRange(data); #endregion + #region Queue Action internal class ExecCommandInfo { public ExecCommandInfoType actionType { get; set; } @@ -131,31 +145,33 @@ namespace FreeSql internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, object state) => _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); + #endregion ~DbContext() => this.Dispose(); bool _isdisposed = false; public void Dispose() { if (_isdisposed) return; + _isdisposed = true; try { _actions.Clear(); - foreach (var set in _dicSet) + foreach (var set in _listSet) try { - set.Value.Dispose(); + set.Dispose(); } catch { } + _listSet.Clear(); _dicSet.Clear(); AllSets.Clear(); - _uow?.Rollback(); + UnitOfWork?.Rollback(); } finally { - _isdisposed = true; GC.SuppressFinalize(this); } } diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 50deeacd..698a1200 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -13,7 +13,7 @@ namespace FreeSql async public virtual Task SaveChangesAsync() { await ExecCommandAsync(); - _uow?.Commit(); + UnitOfWork?.Commit(); var ret = _affrows; _affrows = 0; return ret; diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs index 65a00f16..4c8f2c3b 100644 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -12,7 +12,7 @@ namespace FreeSql public virtual int SaveChanges() { ExecCommand(); - _uow?.Commit(); + UnitOfWork?.Commit(); var ret = _affrows; _affrows = 0; return ret; diff --git a/FreeSql.DbContext/DbContext/FreeContext.cs b/FreeSql.DbContext/DbContext/FreeContext.cs index 38e23bc0..62fbe1c7 100644 --- a/FreeSql.DbContext/DbContext/FreeContext.cs +++ b/FreeSql.DbContext/DbContext/FreeContext.cs @@ -7,7 +7,7 @@ namespace FreeSql public FreeContext(IFreeSql orm) { - _orm = orm; + _ormPriv = orm; } } } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 59abb863..9a5d208e 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -11,14 +11,12 @@ using System.Reflection; namespace FreeSql { - internal class DbContextDbSet : DbSet where TEntity : class + class DbContextDbSet : DbSet where TEntity : class { - public DbContextDbSet(DbContext ctx) { - _ctx = ctx; - _uow = ctx._uow; - _fsql = ctx.Orm; + _db = ctx; + _uow = ctx.UnitOfWork; } } @@ -28,25 +26,21 @@ namespace FreeSql } public abstract partial class DbSet : IDbSet where TEntity : class { - - internal DbContext _ctx; - internal IUnitOfWork _uow; - internal IFreeSql _fsql; + internal DbContext _db { get; set; } + internal IUnitOfWork _uow { get; set; } protected virtual ISelect OrmSelect(object dywhere) { DbContextExecCommand(); //查询前先提交,否则会出脏读 - return _fsql.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); + return _db.Orm.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); } - ~DbSet() - { - this.Dispose(); - } + ~DbSet() => this.Dispose(); bool _isdisposed = false; public void Dispose() { if (_isdisposed) return; + _isdisposed = true; try { this._dicUpdateTimes.Clear(); @@ -54,26 +48,22 @@ namespace FreeSql } finally { - _isdisposed = true; GC.SuppressFinalize(this); } } - protected virtual IInsert OrmInsert() => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); - protected virtual IInsert OrmInsert(TEntity data) => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); - protected virtual IInsert OrmInsert(IEnumerable data) => _fsql.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); + protected virtual IInsert OrmInsert() => _db.Orm.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); + protected virtual IInsert OrmInsert(TEntity data) => _db.Orm.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); + protected virtual IInsert OrmInsert(IEnumerable data) => _db.Orm.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); - protected virtual IUpdate OrmUpdate(IEnumerable entitys) => _fsql.Update().AsType(_entityType).SetSource(entitys).WithTransaction(_uow?.GetOrBeginTransaction()); - protected virtual IDelete OrmDelete(object dywhere) => _fsql.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); + protected virtual IUpdate OrmUpdate(IEnumerable entitys) => _db.Orm.Update().AsType(_entityType).SetSource(entitys).WithTransaction(_uow?.GetOrBeginTransaction()); + protected virtual IDelete OrmDelete(object dywhere) => _db.Orm.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); - internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) - { - _ctx.EnqueueAction(actionType, this, typeof(EntityState), state); - } - internal void IncrAffrows(int affrows) - { - _ctx._affrows += affrows; - } + internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) => + _db.EnqueueAction(actionType, this, typeof(EntityState), state); + + internal void IncrAffrows(int affrows) => + _db._affrows += affrows; internal void TrackToList(object list) { @@ -89,7 +79,7 @@ namespace FreeSql var itemType = item.GetType(); if (itemType == typeof(object)) return; if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; - var dbset = _ctx.Set(itemType); + var dbset = _db.Set(itemType); dbset?.GetType().GetMethod("TrackToList", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dbset, new object[] { list }); return; } @@ -98,11 +88,11 @@ namespace FreeSql foreach (var item in ls) { - var key = _fsql.GetEntityKeyString(_entityType, item, false); + var key = _db.Orm.GetEntityKeyString(_entityType, item, false); if (key == null) continue; _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { - _fsql.MapEntityValue(_entityType, item, ov.Value); + _db.Orm.MapEntityValue(_entityType, item, ov.Value); ov.Time = DateTime.Now; return ov; }); @@ -116,7 +106,7 @@ namespace FreeSql protected ConcurrentDictionary _states = new ConcurrentDictionary(); internal ConcurrentDictionary _statesInternal => _states; TableInfo _tablePriv; - protected TableInfo _table => _tablePriv ?? (_tablePriv = _fsql.CodeFirst.GetTableByEntity(_entityType)); + protected TableInfo _table => _tablePriv ?? (_tablePriv = _db.Orm.CodeFirst.GetTableByEntity(_entityType)); ColumnInfo[] _tableIdentitysPriv; protected ColumnInfo[] _tableIdentitys => _tableIdentitysPriv ?? (_tableIdentitysPriv = _table.Primarys.Where(a => a.Attribute.IsIdentity).ToArray()); protected Type _entityType = typeof(TEntity); @@ -131,7 +121,7 @@ namespace FreeSql { if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); if (entityType == _entityType) return; - var newtb = _fsql.CodeFirst.GetTableByEntity(entityType); + var newtb = _db.Orm.CodeFirst.GetTableByEntity(entityType); _entityType = entityType; _tablePriv = newtb ?? throw new Exception("DbSet.AsType 参数错误,请传入正确的实体类型"); _tableIdentitysPriv = null; @@ -158,15 +148,15 @@ namespace FreeSql public void AttachRange(IEnumerable data) { if (data == null || data.Any() == false) return; - if (_table.Primarys.Any() == false) throw new Exception($"不可附加,实体没有主键:{_fsql.GetEntityString(_entityType, data.First())}"); + if (_table.Primarys.Any() == false) throw new Exception($"不可附加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data.First())}"); foreach (var item in data) { - var key = _fsql.GetEntityKeyString(_entityType, item, false); - if (string.IsNullOrEmpty(key)) throw new Exception($"不可附加,未设置主键的值:{_fsql.GetEntityString(_entityType, item)}"); + var key = _db.Orm.GetEntityKeyString(_entityType, item, false); + if (string.IsNullOrEmpty(key)) throw new Exception($"不可附加,未设置主键的值:{_db.Orm.GetEntityString(_entityType, item)}"); _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { - _fsql.MapEntityValue(_entityType, item, ov.Value); + _db.Orm.MapEntityValue(_entityType, item, ov.Value); ov.Time = DateTime.Now; return ov; }); @@ -184,15 +174,15 @@ namespace FreeSql EntityState CreateEntityState(TEntity data) { if (data == null) throw new ArgumentNullException(nameof(data)); - var key = _fsql.GetEntityKeyString(_entityType, data, false); + var key = _db.Orm.GetEntityKeyString(_entityType, data, false); var state = new EntityState((TEntity)Activator.CreateInstance(_entityType), key); - _fsql.MapEntityValue(_entityType, data, state.Value); + _db.Orm.MapEntityValue(_entityType, data, state.Value); return state; } bool? ExistsInStates(TEntity data) { if (data == null) throw new ArgumentNullException(nameof(data)); - var key = _fsql.GetEntityKeyString(_entityType, data, false); + var key = _db.Orm.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) return null; return _states.ContainsKey(key); } @@ -217,13 +207,13 @@ namespace FreeSql } if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可添加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } - var key = _fsql.GetEntityKeyString(_entityType, data, true); + var key = _db.Orm.GetEntityKeyString(_entityType, data, true); if (string.IsNullOrEmpty(key)) { - switch (_fsql.Ado.DataType) + switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: @@ -235,7 +225,7 @@ namespace FreeSql { return true; } - if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } } @@ -243,13 +233,13 @@ namespace FreeSql { if (_states.ContainsKey(key)) { - if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } - var idval = _fsql.GetEntityIdentityValueWithPrimary(_entityType, data); + var idval = _db.Orm.GetEntityIdentityValueWithPrimary(_entityType, data); if (idval > 0) { - if (isThrow) throw new Exception($"不可添加,自增属性有值:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可添加,自增属性有值:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } } @@ -276,18 +266,18 @@ namespace FreeSql } if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可更新,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可更新,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } - var key = _fsql.GetEntityKeyString(_entityType, data, false); + var key = _db.Orm.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) { - if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } if (_states.TryGetValue(key, out var tryval) == false) { - if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询 或者 Attach:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询 或者 Attach:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } return true; @@ -313,13 +303,13 @@ namespace FreeSql } if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可删除,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可删除,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } - var key = _fsql.GetEntityKeyString(_entityType, data, false); + var key = _db.Orm.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) { - if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } //if (_states.TryGetValue(key, out var tryval) == false) { diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 309046c8..0bad6548 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -14,7 +14,7 @@ namespace FreeSql Task DbContextExecCommandAsync() { _dicUpdateTimes.Clear(); - return _ctx.ExecCommandAsync(); + return _db.ExecCommandAsync(); } async Task DbContextBetchAddAsync(EntityState[] adds) @@ -31,7 +31,7 @@ namespace FreeSql if (_tableIdentitys.Length > 0) { //有自增,马上执行 - switch (_fsql.Ado.DataType) + switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: @@ -40,9 +40,9 @@ namespace FreeSql await DbContextExecCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data); } else @@ -50,9 +50,9 @@ namespace FreeSql await DbContextExecCommandAsync(); var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); IncrAffrows(1); - _fsql.MapEntityValue(_entityType, newval, data); + _db.Orm.MapEntityValue(_entityType, newval, data); Attach(newval); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data); } return; @@ -64,9 +64,9 @@ namespace FreeSql await DbContextExecCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data); } return; @@ -74,7 +74,7 @@ namespace FreeSql } EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data); } public Task AddAsync(TEntity data) => AddPrivAsync(data, true); @@ -89,19 +89,19 @@ namespace FreeSql if (_tableIdentitys.Length > 0) { //有自增,马上执行 - switch (_fsql.Ado.DataType) + switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: await DbContextExecCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); - if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); var idx = 0; foreach (var s in data) - _fsql.MapEntityValue(_entityType, rets[idx++], s); + _db.Orm.MapEntityValue(_entityType, rets[idx++], s); IncrAffrows(rets.Count); AttachRange(rets); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) await AddOrUpdateNavigateListAsync(item); return; @@ -119,7 +119,7 @@ namespace FreeSql foreach (var item in data) EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); AttachRange(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) await AddOrUpdateNavigateListAsync(item); } @@ -161,7 +161,7 @@ namespace FreeSql { if (dbset == null) { - dbset = _ctx.Set(tref.RefEntityType); + dbset = _db.Set(tref.RefEntityType); dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdateAsync", new Type[] { tref.RefEntityType }); } for (var colidx = 0; colidx < tref.Columns.Count; colidx++) @@ -189,10 +189,10 @@ namespace FreeSql if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; var lstval2 = default(EntityState); - if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(_entityType, uplst2.Value)}"); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_db.Orm.GetEntityString(_entityType, uplst2.Value)}"); - var cuig1 = _fsql.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; + var cuig1 = _db.Orm.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _db.Orm.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; List data = null; string[] cuig = null; @@ -224,9 +224,9 @@ namespace FreeSql foreach (var newval in data) { if (_states.TryGetValue(newval.Key, out var tryold)) - _fsql.MapEntityValue(_entityType, newval.Value, tryold.Value); + _db.Orm.MapEntityValue(_entityType, newval.Value, tryold.Value); if (newval.OldValue != null) - _fsql.MapEntityValue(_entityType, newval.Value, newval.OldValue); + _db.Orm.MapEntityValue(_entityType, newval.Value, newval.OldValue); } return affrows; } @@ -237,11 +237,11 @@ namespace FreeSql async public Task UpdateAsync(TEntity data) { var exists = ExistsInStates(data); - if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); if (exists == false) { var olddata = await OrmSelect(data).FirstAsync(); - if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_fsql.GetEntityString(_entityType, data)}"); + if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_db.Orm.GetEntityString(_entityType, data)}"); } await UpdateRangePrivAsync(new[] { data }, true); @@ -260,7 +260,7 @@ namespace FreeSql state.OldValue = item; EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); } - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) await AddOrUpdateNavigateListAsync(item); } @@ -279,7 +279,7 @@ namespace FreeSql async public Task AddOrUpdateAsync(TEntity data) { if (data == null) throw new ArgumentNullException(nameof(data)); - if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); var flagExists = ExistsInStates(data); if (flagExists == false) @@ -291,15 +291,15 @@ namespace FreeSql if (flagExists == true && CanUpdate(data, false)) { await DbContextExecCommandAsync(); - var affrows = _ctx._affrows; + var affrows = _db._affrows; await UpdateRangePrivAsync(new[] { data }, false); await DbContextExecCommandAsync(); - affrows = _ctx._affrows - affrows; + affrows = _db._affrows - affrows; if (affrows > 0) return; } if (CanAdd(data, false)) { - _fsql.ClearEntityPrimaryValueWithIdentity(_entityType, data); + _db.Orm.ClearEntityPrimaryValueWithIdentity(_entityType, data); await AddPrivAsync(data, false); } } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index b056583b..ff404f54 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -14,7 +14,7 @@ namespace FreeSql void DbContextExecCommand() { _dicUpdateTimes.Clear(); - _ctx.ExecCommand(); + _db.ExecCommand(); } int DbContextBetchAdd(EntityState[] adds) @@ -31,7 +31,7 @@ namespace FreeSql if (_tableIdentitys.Length > 0) { //有自增,马上执行 - switch (_fsql.Ado.DataType) + switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: @@ -40,9 +40,9 @@ namespace FreeSql DbContextExecCommand(); var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data); } else @@ -50,9 +50,9 @@ namespace FreeSql DbContextExecCommand(); var newval = this.OrmInsert(data).ExecuteInserted().First(); IncrAffrows(1); - _fsql.MapEntityValue(_entityType, newval, data); + _db.Orm.MapEntityValue(_entityType, newval, data); Attach(newval); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data); } return; @@ -64,9 +64,9 @@ namespace FreeSql DbContextExecCommand(); var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data); } return; @@ -74,7 +74,7 @@ namespace FreeSql } EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); Attach(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data); } /// @@ -93,19 +93,19 @@ namespace FreeSql if (_tableIdentitys.Length > 0) { //有自增,马上执行 - switch (_fsql.Ado.DataType) + switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: DbContextExecCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); - if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); var idx = 0; foreach (var s in data) - _fsql.MapEntityValue(_entityType, rets[idx++], s); + _db.Orm.MapEntityValue(_entityType, rets[idx++], s); IncrAffrows(rets.Count); AttachRange(rets); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) AddOrUpdateNavigateList(item); return; @@ -123,7 +123,7 @@ namespace FreeSql foreach (var item in data) EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); AttachRange(data); - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) AddOrUpdateNavigateList(item); } @@ -175,7 +175,7 @@ namespace FreeSql { if (dbset == null) { - dbset = _ctx.Set(tref.RefEntityType); + dbset = _db.Set(tref.RefEntityType); dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdate", new Type[] { tref.RefEntityType }); } for (var colidx = 0; colidx < tref.Columns.Count; colidx++) @@ -202,10 +202,10 @@ namespace FreeSql if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; var lstval2 = default(EntityState); - if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(_entityType, uplst2.Value)}"); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_db.Orm.GetEntityString(_entityType, uplst2.Value)}"); - var cuig1 = _fsql.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; + var cuig1 = _db.Orm.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _db.Orm.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; List data = null; string[] cuig = null; @@ -237,9 +237,9 @@ namespace FreeSql foreach (var newval in data) { if (_states.TryGetValue(newval.Key, out var tryold)) - _fsql.MapEntityValue(_entityType, newval.Value, tryold.Value); + _db.Orm.MapEntityValue(_entityType, newval.Value, tryold.Value); if (newval.OldValue != null) - _fsql.MapEntityValue(_entityType, newval.Value, newval.OldValue); + _db.Orm.MapEntityValue(_entityType, newval.Value, newval.OldValue); } return affrows; } @@ -256,11 +256,11 @@ namespace FreeSql public void Update(TEntity data) { var exists = ExistsInStates(data); - if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(_entityType, data)}"); + if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); if (exists == false) { var olddata = OrmSelect(data).First(); - if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_fsql.GetEntityString(_entityType, data)}"); + if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_db.Orm.GetEntityString(_entityType, data)}"); } UpdateRangePriv(new[] { data }, true); @@ -279,7 +279,7 @@ namespace FreeSql state.OldValue = item; EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); } - if (_ctx.Options.EnableAddOrUpdateNavigateList) + if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) AddOrUpdateNavigateList(item); } @@ -305,7 +305,7 @@ namespace FreeSql { var state = CreateEntityState(item); _states.TryRemove(state.Key, out var trystate); - _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, item); + _db.Orm.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, item); EnqueueToDbContext(DbContext.ExecCommandInfoType.Delete, state); } @@ -320,7 +320,7 @@ namespace FreeSql public void AddOrUpdate(TEntity data) { if (data == null) throw new ArgumentNullException(nameof(data)); - if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_fsql.GetEntityString(_entityType, data)}"); + if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); var flagExists = ExistsInStates(data); if (flagExists == false) @@ -332,15 +332,15 @@ namespace FreeSql if (flagExists == true && CanUpdate(data, false)) { DbContextExecCommand(); - var affrows = _ctx._affrows; + var affrows = _db._affrows; UpdateRangePriv(new[] { data }, false); DbContextExecCommand(); - affrows = _ctx._affrows - affrows; + affrows = _db._affrows - affrows; if (affrows > 0) return; } if (CanAdd(data, false)) { - _fsql.ClearEntityPrimaryValueWithIdentity(_entityType, data); + _db.Orm.ClearEntityPrimaryValueWithIdentity(_entityType, data); AddPriv(data, false); } } diff --git a/FreeSql.DbContext/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Extenssions/DependencyInjection.cs index bf92a08e..54ba7447 100644 --- a/FreeSql.DbContext/Extenssions/DependencyInjection.cs +++ b/FreeSql.DbContext/Extenssions/DependencyInjection.cs @@ -1,35 +1,44 @@ #if ns20 - using Microsoft.Extensions.DependencyInjection; using System; +using System.Linq; +using System.Reflection; namespace FreeSql { public static class DbContextDependencyInjection { - - public static IServiceCollection AddFreeDbContext(this IServiceCollection services, Action options) where TDbContext : DbContext + static IServiceCollection AddFreeDbContext(this IServiceCollection services, Type dbContextType, Action options) { - - services.AddScoped(sp => + services.AddScoped(dbContextType, sp => { - var ctx = Activator.CreateInstance(); - - if (ctx._orm == null) + var ctx = Activator.CreateInstance(dbContextType) as DbContext; + if (ctx != null && ctx._ormPriv == null) { var builder = new DbContextOptionsBuilder(); options(builder); - ctx._orm = builder._fsql; + ctx._ormPriv = builder._fsql; + ctx._optionsPriv = builder._options; - if (ctx._orm == null) + if (ctx._ormPriv == null) throw new Exception("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); ctx.InitPropSets(); } - return ctx; }); + return services; + } + public static IServiceCollection AddFreeDbContext(this IServiceCollection services, Action options) where TDbContext : DbContext => + AddFreeDbContext(services, typeof(TDbContext), options); + + public static IServiceCollection AddFreeDbContext(this IServiceCollection services, Action options, Assembly[] assemblies) + { + if (assemblies?.Any() == true) + foreach (var asse in assemblies) + foreach (var dbType in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(DbContext).IsAssignableFrom(a))) + AddFreeDbContext(services, dbType, options); return services; } } diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 643850d2..6b31772a 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -8,13 +8,13 @@ namespace FreeSql internal class RepositoryDbContext : DbContext { - protected IBaseRepository _repos; - public RepositoryDbContext(IFreeSql orm, IBaseRepository repos) : base() + protected IBaseRepository _repo; + public RepositoryDbContext(IFreeSql orm, IBaseRepository repo) : base() { - _orm = orm; - _repos = repos; + _ormPriv = orm; _isUseUnitOfWork = false; - _uowPriv = _repos.UnitOfWork; + UnitOfWork = _repo.UnitOfWork; + _repo = repo; } @@ -24,21 +24,22 @@ namespace FreeSql { if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; - var tb = _orm.CodeFirst.GetTableByEntity(entityType); + var tb = _ormPriv.CodeFirst.GetTableByEntity(entityType); if (tb == null) return null; - object repos = _repos; - if (entityType != _repos.EntityType) + object repo = _repo; + if (entityType != _repo.EntityType) { - repos = Activator.CreateInstance(typeof(DefaultRepository<,>).MakeGenericType(entityType, typeof(int)), _repos.Orm); - (repos as IBaseRepository).UnitOfWork = _repos.UnitOfWork; - GetRepositoryDbField(entityType).SetValue(repos, this); + repo = Activator.CreateInstance(typeof(DefaultRepository<,>).MakeGenericType(entityType, typeof(int)), _repo.Orm); + (repo as IBaseRepository).UnitOfWork = _repo.UnitOfWork; + GetRepositoryDbField(entityType).SetValue(repo, this); - typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repos.EntityType) - .Invoke(null, new object[] { repos, _repos }); + typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repo.EntityType) + .Invoke(null, new object[] { repo, _repo }); } - var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repos) as IDbSet; + var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repo) as IDbSet; + _listSet.Add(sd); if (entityType != typeof(object)) _dicSet.Add(entityType, sd); return sd; } diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs index d88188ba..195ae85a 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs @@ -8,60 +8,59 @@ namespace FreeSql internal class RepositoryDbSet : DbSet where TEntity : class { - protected BaseRepository _repos; - public RepositoryDbSet(BaseRepository repos) + protected BaseRepository _repo; + public RepositoryDbSet(BaseRepository repo) { - _ctx = repos._db; - _fsql = repos.Orm; - _uow = repos.UnitOfWork; - _repos = repos; + _db = repo._db; + _uow = repo.UnitOfWork; + _repo = repo; } protected override ISelect OrmSelect(object dywhere) { var select = base.OrmSelect(dywhere); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + var filters = (_repo.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); foreach (var filter in filters) select.Where(filter.Value.Expression); - return select.AsTable(_repos.AsTableSelectInternal); + return select.AsTable(_repo.AsTableSelectInternal); } internal ISelect OrmSelectInternal(object dywhere) => OrmSelect(dywhere); protected override IUpdate OrmUpdate(IEnumerable entitys) { var update = base.OrmUpdate(entitys); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + var filters = (_repo.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); foreach (var filter in filters) { if (entitys != null) foreach (var entity in entitys) if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) - throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_fsql.GetEntityString(_entityType, entity)}"); + throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_db.Orm.GetEntityString(_entityType, entity)}"); update.Where(filter.Value.Expression); } - return update.AsTable(_repos.AsTableInternal); + return update.AsTable(_repo.AsTableInternal); } internal IUpdate OrmUpdateInternal(IEnumerable entitys) => OrmUpdate(entitys); protected override IDelete OrmDelete(object dywhere) { var delete = base.OrmDelete(dywhere); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + var filters = (_repo.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); foreach (var filter in filters) delete.Where(filter.Value.Expression); - return delete.AsTable(_repos.AsTableInternal); + return delete.AsTable(_repo.AsTableInternal); } internal IDelete OrmDeleteInternal(object dywhere) => OrmDelete(dywhere); protected override IInsert OrmInsert(TEntity entity) => OrmInsert(new[] { entity }); protected override IInsert OrmInsert(IEnumerable entitys) { var insert = base.OrmInsert(entitys); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + var filters = (_repo.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); foreach (var filter in filters) { if (entitys != null) foreach (var entity in entitys) if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) - throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_fsql.GetEntityString(_entityType, entity)}"); + throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_db.Orm.GetEntityString(_entityType, entity)}"); } - return insert.AsTable(_repos.AsTableInternal); + return insert.AsTable(_repo.AsTableInternal); } internal IInsert OrmInsertInternal(TEntity entity) => OrmInsert(entity); internal IInsert OrmInsertInternal(IEnumerable entitys) => OrmInsert(entitys); diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs index 7166ef2c..5fcebda7 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs @@ -42,23 +42,23 @@ namespace FreeSql public GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class { - var repos = new GuidRepository(_fsql, filter, asTable); - repos.UnitOfWork = this; - return repos; + var repo = new GuidRepository(_fsql, filter, asTable); + repo.UnitOfWork = this; + return repo; } public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class { - var repos = new DefaultRepository(_fsql, filter); - repos.UnitOfWork = this; - return repos; + var repo = new DefaultRepository(_fsql, filter); + repo.UnitOfWork = this; + return repo; } public BaseRepository GetRepository(Expression> filter = null) where TEntity : class { - var repos = new DefaultRepository(_fsql, filter); - repos.UnitOfWork = this; - return repos; + var repo = new DefaultRepository(_fsql, filter); + repo.UnitOfWork = this; + return repo; } } } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 78021b76..95184e44 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -10,10 +10,11 @@ namespace FreeSql where TEntity : class { - internal RepositoryDbContext _dbPriv; + RepositoryDbContext _dbPriv; internal RepositoryDbContext _db => _dbPriv ?? (_dbPriv = new RepositoryDbContext(Orm, this)); - internal RepositoryDbSet _dbsetPriv; + RepositoryDbSet _dbsetPriv; internal RepositoryDbSet _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set() as RepositoryDbSet); + public IDataFilter DataFilter { get; } = new DataFilter(); Func _asTableVal; protected Func AsTable @@ -39,14 +40,12 @@ namespace FreeSql AsTable = asTable; } - ~BaseRepository() - { - this.Dispose(); - } + ~BaseRepository() => this.Dispose(); bool _isdisposed = false; public void Dispose() { if (_isdisposed) return; + _isdisposed = true; try { _dbsetPriv?.Dispose(); @@ -55,7 +54,6 @@ namespace FreeSql } finally { - _isdisposed = true; GC.SuppressFinalize(this); } } From 176b60b71968558932269cb675bb5af4cce2fe05 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Aug 2019 19:17:10 +0800 Subject: [PATCH 0088/1029] =?UTF-8?q?RepositoryDbContext=20=E6=94=B9?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 6b31772a..632a87f7 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -13,7 +13,7 @@ namespace FreeSql { _ormPriv = orm; _isUseUnitOfWork = false; - UnitOfWork = _repo.UnitOfWork; + UnitOfWork = repo.UnitOfWork; _repo = repo; } From 710b12c3e84e61cbc65e3c347a9d35889a509249 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Aug 2019 19:25:11 +0800 Subject: [PATCH 0089/1029] =?UTF-8?q?BaseRepository=20=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/Repository/Repository/BaseRepository.cs | 4 ++-- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 95184e44..e2f38254 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -10,9 +10,9 @@ namespace FreeSql where TEntity : class { - RepositoryDbContext _dbPriv; + internal RepositoryDbContext _dbPriv; //这个不能私有化,有地方需要反射获取它 internal RepositoryDbContext _db => _dbPriv ?? (_dbPriv = new RepositoryDbContext(Orm, this)); - RepositoryDbSet _dbsetPriv; + internal RepositoryDbSet _dbsetPriv; internal RepositoryDbSet _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set() as RepositoryDbSet); public IDataFilter DataFilter { get; } = new DataFilter(); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 741f66f8..34636f8d 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -283,7 +283,7 @@ namespace FreeSql.Tests { [FreeSql.DataAnnotations.Column(IsPrimary = true)] - public Guid Id { get; protected set; } + public Guid Id { get; set; } public string TaskName { get; set; } public Guid TemplatesId { get; set; } public string GeneratePath { get; set; } From a62d07d2b7b931d7835039532c7c9a0043d53b25 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 14 Aug 2019 11:22:34 +0800 Subject: [PATCH 0090/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbContext.Sa?= =?UTF-8?q?ve=20=E5=8F=AA=E6=9F=A5=E8=AF=A2=E4=B8=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=9A=84bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 2 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7fa794b1..6d7c5219 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.5 + 0.8.6 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5ad41619..a2c9977e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 0bad6548..c80ccf72 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -285,7 +285,7 @@ namespace FreeSql if (flagExists == false) { var olddata = await OrmSelect(data).FirstAsync(); - if (olddata == null) flagExists = false; + flagExists = olddata != null; } if (flagExists == true && CanUpdate(data, false)) diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index ff404f54..8a1f1ae0 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -326,7 +326,7 @@ namespace FreeSql if (flagExists == false) { var olddata = OrmSelect(data).First(); - if (olddata == null) flagExists = false; + flagExists = olddata != null; } if (flagExists == true && CanUpdate(data, false)) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 49e5689b..6afc0aed 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c619fa87..27e9da59 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.5 + 0.8.6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 6cbdc646..c11d65d0 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 292ba9b1..98fe9d85 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 71124f9b..d7c2bb49 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b47a9358..2ca3797c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d19e1215..d2550091 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 554af458..3822600f 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 07db3243..412f904f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.5 + 0.8.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From b0314f643eeb2ee225df77df932c028bec637d6b Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 16 Aug 2019 11:09:48 +0800 Subject: [PATCH 0091/1029] ## v0.8.7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 导航关系多属性时的错序 bug; - 修复 延时属性的类,没有设置Namespace时的 bug; --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../Other/AnswerQuestionnaire.cs | 67 +++++++++++++++++++ .../FreeSql.Tests/Other/MedicalRecord.cs | 50 ++++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 4 ++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 1 + FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/UtilsExpressionTree.cs | 50 +++++++------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 158 insertions(+), 36 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/AnswerQuestionnaire.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/MedicalRecord.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6d7c5219..73ad9756 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.6 + 0.8.7 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a2c9977e..44735320 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6afc0aed..0778f7ef 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 27e9da59..d8268faf 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.6 + 0.8.7 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/Other/AnswerQuestionnaire.cs b/FreeSql.Tests/FreeSql.Tests/Other/AnswerQuestionnaire.cs new file mode 100644 index 00000000..ee03c632 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/AnswerQuestionnaire.cs @@ -0,0 +1,67 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// Website: http://www.freesql.net +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; + + [JsonObject(MemberSerialization.OptIn)] + public partial class AnswerQuestionnaire + { + + [JsonProperty, Column(IsPrimary = true)] + public long Id { get; set; } + + + [JsonProperty, Column(DbType = "varchar(50)")] + public string RecordId + { + get => _recordid; + set + { + if (_recordid != value) + { + _recordid = value; + } + } + } + private string _recordid; + + [JsonProperty] + public short? TypeId + { + get => _typeid; + set + { + if (_typeid != value) + { + _typeid = value; + } + } + } + private short? _typeid; + + [JsonProperty] + public DateTime CreateTime { get; set; } + + + #region 外键 => 导航属性,ManyToOne/OneToOne + + + [Navigate("RecordId, TypeId")] + public virtual MedicalRecord MedicalRecord { get; set; } + + #endregion + + #region 外键 => 导航属性,ManyToMany + + #endregion + } + diff --git a/FreeSql.Tests/FreeSql.Tests/Other/MedicalRecord.cs b/FreeSql.Tests/FreeSql.Tests/Other/MedicalRecord.cs new file mode 100644 index 00000000..ed77f1a9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/MedicalRecord.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// Website: http://www.freesql.net +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; + + [JsonObject(MemberSerialization.OptIn)] + public partial class MedicalRecord + { + + [JsonProperty, Column(DbType = "varchar(50)", IsPrimary = true)] + public string RecordId { get; set; } + + [JsonProperty, Column(IsPrimary = true)] + public short TypeId { get; set; } + + [JsonProperty] + public DateTime? CreateTime { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal InsuranceAmount { get; set; } + + [JsonProperty] + public DateTime? LastModifyTime { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal SelfAmount { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal TotalAmount { get; set; } + + #region 外键 => 导航属性,OneToMany + + [Navigate("TypeId, RecordId")] + public virtual List AnswerQuestionnaires { get; set; } + + #endregion + + #region 外键 => 导航属性,ManyToMany + + #endregion + } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 34636f8d..b40ecf8b 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -347,6 +347,10 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var kdkdfm = g.sqlite.Select() + .Include(a => a.MedicalRecord) + .ToSql(); + var dkdkd = g.mysql.Select().AsTable((t,old) => "TaskBuild22") .ToList< TestDto>(a => new TestDto() { diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 02fba7c2..1c145a27 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -39,6 +39,7 @@ public static partial class FreeSqlGlobalExtensions public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true; public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GenericTypeArguments.First() : that; + internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args)); /// /// 测量两个经纬度的距离,返回单位:米 diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c11d65d0..84b735f8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6129bfe7..db0f3618 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -244,7 +244,7 @@ namespace FreeSql.Internal tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 - var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace}.{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace}.{trytb.Type.Name}"; + var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}"; var trytbTypeLazyName = default(string); var overrieds = 0; StringBuilder cscode = null; @@ -270,8 +270,8 @@ namespace FreeSql.Internal var vp = propsLazy.Where(a => a.Item1 == pnv).FirstOrDefault(); var isLazy = vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName); var propTypeName = pnv.PropertyType.IsGenericType ? - $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace}.{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace}.{a.Name}"))}>" : - (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace}.{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name}"); + $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" : + (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name}"); var pnvAttr = pnv.GetCustomAttribute(); var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); @@ -294,7 +294,7 @@ namespace FreeSql.Internal var tbref = propElementType == trytb.Type ? trytb : GetTableByEntity(propElementType, common); //可能是父子关系 if (tbref == null) continue; - var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}"; + var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}"; Type midType = null; var isManyToMany = false; @@ -357,29 +357,29 @@ namespace FreeSql.Internal if (midType == null) { midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); valiManyToMany(); } if (midType == null) { midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); valiManyToMany(); } if (midType == null) { midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); valiManyToMany(); } if (midType == null) { midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); valiManyToMany(); } #endregion @@ -388,29 +388,29 @@ namespace FreeSql.Internal if (midType == null) { midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); valiManyToMany(); } if (midType == null) { midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); valiManyToMany(); } if (midType == null) { midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); valiManyToMany(); } if (midType == null) { midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); valiManyToMany(); } #endregion @@ -605,7 +605,7 @@ namespace FreeSql.Internal if (nvref.Exception == null) cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}") - .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace}.{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") + .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();") .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); else @@ -656,7 +656,7 @@ namespace FreeSql.Internal if (trytb.Primarys.Select(a => a.CsType).Distinct().Count() == trytb.Primarys.Length) { var pkList = trytb.Primarys.ToList(); - bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType))); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType.NullableTypeOrThis()))); } else if (string.Compare(string.Join(",", trytb.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) { @@ -738,7 +738,7 @@ namespace FreeSql.Internal if (nvref.Exception == null) { - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}").Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();"); + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace?.NotNullAndConcat(".")}{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace?.NotNullAndConcat(".")}{propElementType.Name}").Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();"); if (refprop != null) { cscode.Append(" foreach (var loc1 in base.").Append(pnv.Name).AppendLine(")") @@ -772,7 +772,7 @@ namespace FreeSql.Internal trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; } - var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}"; + var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}"; var isOnoToOne = pnv.PropertyType != trytb.Type && tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type).Any() && tbref.Primarys.Length == trytb.Primarys.Length && @@ -806,7 +806,7 @@ namespace FreeSql.Internal if (tbref.Primarys.Select(a => a.CsType).Distinct().Count() == tbref.Primarys.Length) { var pkList = tbref.Primarys.ToList(); - bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType))); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType.NullableTypeOrThis()))); } else if (string.Compare(string.Join(",", tbref.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) { diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 98fe9d85..2aa2b6d6 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d7c2bb49..94e86c60 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2ca3797c..d396be09 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d2550091..ccbdfb38 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 3822600f..dedbd86d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 412f904f..70271d2d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.6 + 0.8.7 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From da1d7f782a2eadf540503b677e0ebbcee47fcf6f Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 16 Aug 2019 19:51:09 +0800 Subject: [PATCH 0092/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IncludeMany?= =?UTF-8?q?=20=E5=8F=98=E5=BC=82=20Where=20=E6=8C=87=E5=AE=9A=E7=9A=84?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E7=B1=BB=E5=9E=8B=E4=B8=8D=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B=EF=BC=88=E5=A6=82=20int=20=E5=92=8C=20?= =?UTF-8?q?int=3F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 2 +- .../CommonProvider/SelectProvider/Select1Provider.cs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index e0c46327..61912683 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -870,7 +870,7 @@ namespace FreeSql.Tests.Sqlite [Column(IsIdentity = true)] public int id { get; set; } - public int model2111Idaaa { get; set; } + public int? model2111Idaaa { get; set; } public string title { get; set; } public List childs2 { get; set; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index ef72a209..dc445c2a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -489,8 +489,12 @@ namespace FreeSql.Internal.CommonProvider actWeiParse(binaryExp.Right); break; case ExpressionType.Equal: - var leftP1MemberExp = binaryExp.Left as MemberExpression; - var rightP1MemberExp = binaryExp.Right as MemberExpression; + Expression leftExp = binaryExp.Left; + Expression rightExp = binaryExp.Right; + while (leftExp.NodeType == ExpressionType.Convert) leftExp = (leftExp as UnaryExpression)?.Operand; + while (rightExp.NodeType == ExpressionType.Convert) rightExp = (rightExp as UnaryExpression)?.Operand; + var leftP1MemberExp = leftExp as MemberExpression; + var rightP1MemberExp = rightExp as MemberExpression; if (leftP1MemberExp == null || rightP1MemberExp == null) throw throwNavigateSelector; if (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) From f80308a6eb48974d7eee023ec21a531b7379b1d0 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 16 Aug 2019 20:33:59 +0800 Subject: [PATCH 0093/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E5=B1=9E=E6=80=A7=E7=9A=84=E5=85=B3=E7=B3=BB=EF=BC=8C?= =?UTF-8?q?=E5=8F=8B=E5=A5=BD=E6=94=AF=E6=8C=81=20int/int=3F=20=E6=98=A0?= =?UTF-8?q?=E5=B0=84=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sqlite/Curd/SqliteSelectTest.cs | 4 ++-- .../SelectProvider/Select1Provider.cs | 10 +++++----- FreeSql/Internal/UtilsExpressionTree.cs | 20 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 61912683..45e0f362 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -858,7 +858,7 @@ namespace FreeSql.Tests.Sqlite public class TestInclude_OneToManyModel2 { [Column(IsPrimary = true)] - public int model2id { get; set; } + public int? model2id { get; set; } public virtual TestInclude_OneToManyModel1 model1 { get; set; } public string m2setting { get; set; } @@ -870,7 +870,7 @@ namespace FreeSql.Tests.Sqlite [Column(IsIdentity = true)] public int id { get; set; } - public int? model2111Idaaa { get; set; } + public int model2111Idaaa { get; set; } public string title { get; set; } public List childs2 { get; set; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index dc445c2a..e0a1a421 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -680,14 +680,14 @@ namespace FreeSql.Internal.CommonProvider subSelect._where.Clear(); if (tbref.Columns.Count == 1) { - var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, + var arrExp = Expression.NewArrayInit(tbref.RefColumns[0].CsType, list.Select(a => getListValue(a, tbref.Columns[0].CsName, 0)).Distinct() - .Select(a => Expression.Constant(Convert.ChangeType(a, tbref.Columns[0].CsType))).ToArray()); + .Select(a => Expression.Constant(Utils.GetDataReaderValue(tbref.RefColumns[0].CsType, a), tbref.RefColumns[0].CsType)).ToArray()); var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a"); - var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary()).GetOrAdd("Contains", mn => - typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.Columns[0].CsType); + var containsMethod = _dicTypeMethod.GetOrAdd(tbref.RefColumns[0].CsType, et => new ConcurrentDictionary()).GetOrAdd("Contains", mn => + typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.RefColumns[0].CsType); var refCol = Expression.MakeMemberAccess(otmExpParm1, tbref2.Properties[tbref.RefColumns[0].CsName]); - if (refCol.Type.IsNullableType()) refCol = Expression.Property(refCol, CommonExpression._dicNullableValueProperty.GetOrAdd(refCol.Type, ct1 => ct1.GetProperty("Value"))); + //if (refCol.Type.IsNullableType()) refCol = Expression.Property(refCol, CommonExpression._dicNullableValueProperty.GetOrAdd(refCol.Type, ct1 => ct1.GetProperty("Value"))); subSelect.Where(Expression.Lambda>( Expression.Call(null, containsMethod, arrExp, refCol), otmExpParm1)); } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index db0f3618..ec2d91f5 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -518,7 +518,7 @@ namespace FreeSql.Internal { } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) + if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType.NullableTypeOrThis()) { nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {trytb.CsName}.{trytb.Primarys[a].CsName} 类型不一致"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); @@ -558,7 +558,7 @@ namespace FreeSql.Internal { } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType.NullableTypeOrThis()) { nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); @@ -653,10 +653,10 @@ namespace FreeSql.Internal } if (trytb.Primarys.Length > 1) { - if (trytb.Primarys.Select(a => a.CsType).Distinct().Count() == trytb.Primarys.Length) + if (trytb.Primarys.Select(a => a.CsType.NullableTypeOrThis()).Distinct().Count() == trytb.Primarys.Length) { var pkList = trytb.Primarys.ToList(); - bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType.NullableTypeOrThis()))); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == b.CsType.NullableTypeOrThis()))); } else if (string.Compare(string.Join(",", trytb.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) { @@ -685,7 +685,7 @@ namespace FreeSql.Internal } } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType) + if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType.NullableTypeOrThis()) { nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trytb.Primarys[a].CsName} 和 {tbref.CsName}.{trycol.CsName} 类型不一致"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); @@ -776,7 +776,7 @@ namespace FreeSql.Internal var isOnoToOne = pnv.PropertyType != trytb.Type && tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type).Any() && tbref.Primarys.Length == trytb.Primarys.Length && - string.Join(",", tbref.Primarys.Select(a => a.CsType.FullName).OrderBy(a => a)) == string.Join(",", trytb.Primarys.Select(a => a.CsType.FullName).OrderBy(a => a)); + string.Join(",", tbref.Primarys.Select(a => a.CsType.NullableTypeOrThis().FullName).OrderBy(a => a)) == string.Join(",", trytb.Primarys.Select(a => a.CsType.NullableTypeOrThis().FullName).OrderBy(a => a)); List bindColumns = new List(); if (pnvBind != null) @@ -803,10 +803,10 @@ namespace FreeSql.Internal } if (tbref.Primarys.Length > 1) { - if (tbref.Primarys.Select(a => a.CsType).Distinct().Count() == tbref.Primarys.Length) + if (tbref.Primarys.Select(a => a.CsType.NullableTypeOrThis()).Distinct().Count() == tbref.Primarys.Length) { var pkList = tbref.Primarys.ToList(); - bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType.NullableTypeOrThis()))); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == b.CsType.NullableTypeOrThis()))); } else if (string.Compare(string.Join(",", tbref.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) { @@ -831,7 +831,7 @@ namespace FreeSql.Internal //一对一,主键与主键查找 if (isOnoToOne) { - var trytbpks = trytb.Primarys.Where(z => z.CsType == tbref.Primarys[a].CsType); //一对一,按类型 + var trytbpks = trytb.Primarys.Where(z => z.CsType.NullableTypeOrThis() == tbref.Primarys[a].CsType.NullableTypeOrThis()); //一对一,按类型 if (trytbpks.Count() == 1) trycol = trytbpks.First(); else { @@ -850,7 +850,7 @@ namespace FreeSql.Internal } } } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType) + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType.NullableTypeOrThis()) { nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); trytb.AddOrUpdateTableRef(pnv.Name, nvref); From 152543950ad169cbe1321a255d6f9df37af505c4 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 16 Aug 2019 20:44:32 +0800 Subject: [PATCH 0094/1029] v0.8.8 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 73ad9756..08d7b389 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.7 + 0.8.8 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 44735320..ebe40b9d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 0778f7ef..241d9651 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d8268faf..e06613ca 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.7 + 0.8.8 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 84b735f8..50730b75 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 2aa2b6d6..7c18b91d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 94e86c60..d3c2019a 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d396be09..ff7dc403 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ccbdfb38..372c6a12 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index dedbd86d..8a643027 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 70271d2d..cbb71730 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.7 + 0.8.8 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 0c36e2fe327896b97a806f4b42d233e4841c81f3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 18 Aug 2019 20:49:19 +0800 Subject: [PATCH 0095/1029] update --- readme.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/readme.md b/readme.md index 42427188..2c95bfe0 100644 --- a/readme.md +++ b/readme.md @@ -39,6 +39,14 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore - [ABP 使用 FreeSql ORM](https://github.com/gnsilence/JPGZService),测试中...; - [FreeSql 优势.pptx](https://github.com/2881099/FreeSql/files/3305852/FreeSql.pptx); +> FreeSql 提供了五种使用习惯,请根据实际情况选择团队合适的一种: + +- 要么FreeSql; +- 要么FreeSql.Repository(https://github.com/2881099/FreeSql/wiki/Repository),仓储习惯; +- 要么FreeSql.DbContext(https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; +- 要么FreeSql.Connection.Extensions(https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; +- 要么[BaseEntity](https://github.com/2881099/ojbk),我求简单现在使用的这个; + # Providers | Package Name | Version | From fafbfbe58e1bc5c1fecf15ccbcfd254e0ed2c88b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 18 Aug 2019 20:52:48 +0800 Subject: [PATCH 0096/1029] update --- readme.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/readme.md b/readme.md index 2c95bfe0..21f63e8e 100644 --- a/readme.md +++ b/readme.md @@ -31,22 +31,20 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | [FreeSql.AdminLTE](https://github.com/2881099/FreeSql.AdminLTE) | [![nuget](https://img.shields.io/nuget/v/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.AdminLTE) | [![stats](https://img.shields.io/nuget/dt/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.AdminLTE?groupby=Version) | | [FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Connection.Extensions) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Connection.Extensions?groupby=Version) | -- FreeSql 是核心,提供原始用法; -- FreeSql.DbContext 是扩展包,提供面向对象的用法(像EF); -- FreeSql.Repository 也是扩展包,提供仓储+工作单元用法; -- FreeSql.Connection.Extensions 也是扩展包,提供像 Dapper 一样的用法; +> FreeSql 提供了五种使用习惯,请根据实际情况选择团队合适的一种: + +- 要么FreeSql,原始用法; +- 要么[FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository),仓储+工作单元习惯; +- 要么[FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; +- 要么[FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; +- 要么[BaseEntity](https://github.com/2881099/ojbk),我求简单现在使用的这个; + +> 其他下载 + - [FreeSql.Tools 生成器](https://github.com/2881099/FreeSql.Tools),基于 razor 模板的生成器; - [ABP 使用 FreeSql ORM](https://github.com/gnsilence/JPGZService),测试中...; - [FreeSql 优势.pptx](https://github.com/2881099/FreeSql/files/3305852/FreeSql.pptx); -> FreeSql 提供了五种使用习惯,请根据实际情况选择团队合适的一种: - -- 要么FreeSql; -- 要么FreeSql.Repository(https://github.com/2881099/FreeSql/wiki/Repository),仓储习惯; -- 要么FreeSql.DbContext(https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; -- 要么FreeSql.Connection.Extensions(https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; -- 要么[BaseEntity](https://github.com/2881099/ojbk),我求简单现在使用的这个; - # Providers | Package Name | Version | From 0ceac25d55c5fd6f814b347df3d3eb7b96794436 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 18 Aug 2019 20:55:16 +0800 Subject: [PATCH 0097/1029] update --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 21f63e8e..8d2794f5 100644 --- a/readme.md +++ b/readme.md @@ -37,7 +37,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore - 要么[FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository),仓储+工作单元习惯; - 要么[FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; - 要么[FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; -- 要么[BaseEntity](https://github.com/2881099/ojbk),我求简单现在使用的这个; +- 要么[BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),我求简单现在使用的这个; > 其他下载 From 73ca47597414a24e7dabe115d2ecd0c3abce2e6c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 20 Aug 2019 13:35:50 +0800 Subject: [PATCH 0098/1029] update readme --- readme.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index 8d2794f5..5894292c 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577)。 +FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577) 扶摇直上,至强ORM只为自由编码;鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) @@ -7,26 +7,26 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore - [x] 支持 CodeFirst 迁移; - [x] 支持 DbFirst 从数据库导入实体类; - [x] 大量采用 ExpressionTree 提升性能; -- [x] 支持深入的类型映射,比如pgsql的数组类型,堪称匠心制作; -- [x] 支持丰富的表达式函数; -- [x] 支持导航属性一对多、多对多贪婪加载,以及延时加载; -- [x] 支持同步/异步数据库操作方法; -- [x] 支持读写分离、分表分库,租户设计,过滤器,乐观锁; -- [x] 支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite; +- [x] 支持 深入的类型映射,比如pgsql的数组类型; +- [x] 支持 丰富的表达式函数; +- [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; +- [x] 支持 同步/异步数据库操作方法; +- [x] 支持 读写分离、分表分库,租户设计,过滤器,乐观锁; +- [x] 支持 多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite; | | | | - | - | -| ![image](https://user-images.githubusercontent.com/16286519/55138232-f5e19e80-516d-11e9-9144-173cc7e52845.png) | [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| ![image](https://user-images.githubusercontent.com/16286519/55138241-faa65280-516d-11e9-8b27-139dea46e4df.png) | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | -| ![image](https://user-images.githubusercontent.com/16286519/55138263-06921480-516e-11e9-8da9-81f18a18b694.png) | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| ![image](https://user-images.githubusercontent.com/16286519/55138284-0eea4f80-516e-11e9-8764-29264807f402.png) | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | # Packages | Package Name | NuGet | Downloads | |--------------| ------- | ---- | | FreeSql | [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) | [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) | -| [FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Repository) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Repository?groupby=Version) | +| FreeSql.Repository | [![nuget](https://img.shields.io/nuget/v/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Repository) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Repository?groupby=Version) | | FreeSql.DbContext | [![nuget](https://img.shields.io/nuget/v/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.DbContext) | [![stats](https://img.shields.io/nuget/dt/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.DbContext?groupby=Version) | | [FreeSql.AdminLTE](https://github.com/2881099/FreeSql.AdminLTE) | [![nuget](https://img.shields.io/nuget/v/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.AdminLTE) | [![stats](https://img.shields.io/nuget/dt/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.AdminLTE?groupby=Version) | | [FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Connection.Extensions) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Connection.Extensions?groupby=Version) | @@ -42,7 +42,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore > 其他下载 - [FreeSql.Tools 生成器](https://github.com/2881099/FreeSql.Tools),基于 razor 模板的生成器; -- [ABP 使用 FreeSql ORM](https://github.com/gnsilence/JPGZService),测试中...; +- [Abp 中使用 FreeSql](https://github.com/gnsilence/JPGZService),测试中...; - [FreeSql 优势.pptx](https://github.com/2881099/FreeSql/files/3305852/FreeSql.pptx); # Providers From 858e3d3dbb2d450b2a3597a90fad1a8ccba05741 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 23 Aug 2019 13:49:54 +0800 Subject: [PATCH 0099/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Oracle=20DbF?= =?UTF-8?q?irst=20=E5=A4=A7=E5=B0=8F=E5=86=99=E9=97=AE=E9=A2=98=E6=B2=A1?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E8=8E=B7=E5=8F=96=E5=88=97=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=20CsType=20=E5=80=BC=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 08d7b389..5ab7db63 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.8 + 0.8.9 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ebe40b9d..89c2afd3 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 241d9651..29c08564 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e06613ca..a03b85e2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.8 + 0.8.9 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 50730b75..f9b6d022 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 7c18b91d..69ef351c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d3c2019a..14fc8a73 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ff7dc403..0f35c689 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 0a0a1a14..a1ece3c1 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -114,7 +114,7 @@ namespace FreeSql.Oracle throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); } - static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(); + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); static OracleDbFirst() { var defaultDbToCs = new Dictionary() { diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 372c6a12..0ae65de7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 8a643027..71726985 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index cbb71730..a2a60d29 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.8 + 0.8.9 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 8e33d80b5a4a4ef3ff16b9499cc788dfdd8d8fcb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 23 Aug 2019 18:17:17 +0800 Subject: [PATCH 0100/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Pgsql=20?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=9B=B4=E6=96=B0=E4=BD=BF=E7=94=A8=20NonePa?= =?UTF-8?q?rameter=20=E5=90=8E=E6=97=A5=E6=9C=9F=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E7=9A=84=E8=AF=AD=E6=B3=95=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 8 ++++++++ .../FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs | 8 ++++++++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 5 +++++ .../FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs | 8 ++++++++ .../FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs | 8 ++++++++ FreeSql/Internal/CommonProvider/UpdateProvider.cs | 7 ++++++- .../FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs | 9 +++++++++ 7 files changed, 52 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 844e7210..c89f2c76 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -1,6 +1,7 @@ using FreeSql.DataAnnotations; using System; using System.Collections.Generic; +using System.Linq; using Xunit; namespace FreeSql.Tests.MySqlConnector @@ -180,7 +181,14 @@ namespace FreeSql.Tests.MySqlConnector [Fact] public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var time = DateTime.Now; + var items222 = g.mysql.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); } [Fact] public void ExecuteUpdated() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 55808901..a1f6758a 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -1,6 +1,7 @@ using FreeSql.DataAnnotations; using System; using System.Collections.Generic; +using System.Linq; using Xunit; namespace FreeSql.Tests.MySql @@ -181,7 +182,14 @@ namespace FreeSql.Tests.MySql [Fact] public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var time = DateTime.Now; + var items222 = g.mysql.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); } [Fact] public void ExecuteUpdated() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 8d26b835..ff270d94 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -1,6 +1,7 @@ using FreeSql.DataAnnotations; using System; using System.Collections.Generic; +using System.Linq; using Xunit; namespace FreeSql.Tests.PostgreSQL @@ -120,7 +121,11 @@ namespace FreeSql.Tests.PostgreSQL [Fact] public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); } [Fact] public void ExecuteUpdated() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 7d6de208..88ad4cb0 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using FreeSql.Tests.DataContext.SqlServer; using System; using System.Collections.Generic; +using System.Linq; using Xunit; namespace FreeSql.Tests.SqlServer @@ -131,7 +132,14 @@ namespace FreeSql.Tests.SqlServer [Fact] public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var time = DateTime.Now; + var items222 = g.sqlserver.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); } [Fact] public void ExecuteUpdated() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index e6ac094e..e6c74398 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -1,6 +1,7 @@ using FreeSql.DataAnnotations; using System; using System.Collections.Generic; +using System.Linq; using Xunit; namespace FreeSql.Tests.Sqlite @@ -124,7 +125,14 @@ namespace FreeSql.Tests.Sqlite [Fact] public void ExecuteAffrows() { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + var time = DateTime.Now; + var items222 = g.sqlite.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); } [Fact] public void ExecuteUpdated() diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 5b8e1071..049e6cbd 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -566,6 +566,7 @@ namespace FreeSql.Internal.CommonProvider protected abstract void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys); protected abstract void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d); + protected virtual void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) { } public IUpdate AsTable(Func tableRule) { @@ -658,7 +659,11 @@ namespace FreeSql.Internal.CommonProvider if (isnull == false) isnull = value == null || value == DBNull.Value; } cwsb.Append(" END"); - if (isnull == false) sb.Append(cwsb.ToString()); + if (isnull == false) + { + ToSqlCaseWhenEnd(cwsb, col); + sb.Append(cwsb.ToString()); + } else sb.Append("NULL"); cwsb.Clear(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 88554df2..b1fc6740 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -136,5 +136,14 @@ namespace FreeSql.PostgreSQL.Curd } sb.Append(")"); } + + protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) + { + if (_noneParameter == false) return; + var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; + if (dbtype == null) return; + + sb.Append("::").Append(dbtype); + } } } From baa6c413a0442c3f303357302805d69bf6e84d18 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 23 Aug 2019 18:33:34 +0800 Subject: [PATCH 0101/1029] v0.8.10 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 4 ++-- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5ab7db63..8b2f5c3a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.9 + 0.8.10 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 89c2afd3..86b97d87 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 29c08564..af993212 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index a03b85e2..743510b5 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.9 + 0.8.10 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository @@ -17,7 +17,7 @@ - + diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f9b6d022..56e1f79b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 69ef351c..f2e7e9c5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 14fc8a73..935f1af5 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 0f35c689..4d8d5124 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0ae65de7..d8824a7e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 71726985..cbd197f0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a2a60d29..3fa1507e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.9 + 0.8.10 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From b57d35ae9b79d228593ec4632b62253dca739e3a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 25 Aug 2019 18:13:02 +0800 Subject: [PATCH 0102/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Aop.AuditVal?= =?UTF-8?q?ue=20=E4=BA=8B=E4=BB=B6=EF=BC=8C=E5=9C=A8=E6=8F=92=E5=85=A5/?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE=E6=97=B6=E5=AE=A1=E8=AE=A1?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlAopTest.cs | 40 +++++++++++++++++ .../FreeSql.Tests/MySql/MySqlAopTest.cs | 40 +++++++++++++++++ .../FreeSql.Tests/Oracle/OracleAopTest.cs | 40 +++++++++++++++++ .../PostgreSQL/PostgreSQLAopTest.cs | 40 +++++++++++++++++ .../SqlServer/SqlServerAopTest.cs | 40 +++++++++++++++++ .../FreeSql.Tests/Sqlite/SqliteAopTest.cs | 40 +++++++++++++++++ FreeSql/FreeSql.xml | 25 +++++++++++ FreeSql/Interface/IAop.cs | 45 +++++++++++++++++++ .../Internal/CommonProvider/AopProvider.cs | 1 + .../Internal/CommonProvider/InsertProvider.cs | 7 +++ .../Internal/CommonProvider/UpdateProvider.cs | 28 ++++++++---- .../Curd/OracleInsert.cs | 7 +++ 12 files changed, 344 insertions(+), 9 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlAopTest.cs new file mode 100644 index 00000000..2bec5373 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlAop + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var now = DateTime.Now; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now; + }; + g.mysql.Aop.AuditValue += audit; + + g.mysql.Insert(item).ExecuteAffrows(); + + g.mysql.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime.Date, now.Date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs new file mode 100644 index 00000000..a154f0a5 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.MySql +{ + public class MySqlAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var now = DateTime.Now; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now; + }; + g.mysql.Aop.AuditValue += audit; + + g.mysql.Insert(item).ExecuteAffrows(); + + g.mysql.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime.Date, now.Date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs new file mode 100644 index 00000000..5a30b033 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Oracle +{ + public class OracleAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var now = DateTime.Now; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now; + }; + g.oracle.Aop.AuditValue += audit; + + g.oracle.Insert(item).ExecuteAffrows(); + + g.oracle.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime.Date, now.Date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs new file mode 100644 index 00000000..ad0e5140 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var now = DateTime.Now; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now; + }; + g.pgsql.Aop.AuditValue += audit; + + g.pgsql.Insert(item).ExecuteAffrows(); + + g.pgsql.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime.Date, now.Date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs new file mode 100644 index 00000000..3c8b4511 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.SqlServer +{ + public class SqlServerAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var now = DateTime.Now; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now; + }; + g.sqlserver.Aop.AuditValue += audit; + + g.sqlserver.Insert(item).ExecuteAffrows(); + + g.sqlserver.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime.Date, now.Date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs new file mode 100644 index 00000000..5cddd046 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Sqlite +{ + public class SqliteAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var now = DateTime.Now; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now; + }; + g.sqlite.Aop.AuditValue += audit; + + g.sqlite.Insert(item).ExecuteAffrows(); + + g.sqlite.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime.Date, now.Date); + } + } +} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 14783b73..310ff7ed 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2020,6 +2020,11 @@ CodeFirst迁移,执行完成触发 + + + Insert/Update自动值处理, e.Column.SetMapValue( + + 可重新装饰的引用数据 @@ -2145,6 +2150,26 @@ 耗时(单位:毫秒) + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index 4b777b2f..23cfd63e 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using FreeSql.DatabaseModel; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data.Common; @@ -53,6 +54,11 @@ namespace FreeSql /// CodeFirst迁移,执行完成触发 /// EventHandler SyncStructureAfter { get; set; } + + /// + /// Insert/Update自动值处理, e.Column.SetMapValue( + /// + EventHandler AuditValue { get; set; } } } @@ -264,4 +270,43 @@ namespace FreeSql.Aop /// public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; } + + public class AuditValueEventArgs : EventArgs + { + public AuditValueEventArgs(AutoValueType autoValueType, ColumnInfo column, PropertyInfo property, object value) + { + this.AutoValueType = autoValueType; + this.Column = column; + this.Property = property; + this.Value = value; + } + + /// + /// 类型 + /// + public AutoValueType AutoValueType { get; } + /// + /// 属性列的元数据 + /// + public ColumnInfo Column { get; } + /// + /// 反射的属性信息 + /// + public PropertyInfo Property { get; } + /// + /// 获取实体的属性值,也可以设置实体的属性新值 + /// + public object Value + { + get => _value; + set + { + _value = value; + this.IsChanged = true; + } + } + private object _value; + internal bool IsChanged { get; private set; } + } + public enum AutoValueType { Update, Insert } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/AopProvider.cs b/FreeSql/Internal/CommonProvider/AopProvider.cs index 3f6d15b2..3312e50d 100644 --- a/FreeSql/Internal/CommonProvider/AopProvider.cs +++ b/FreeSql/Internal/CommonProvider/AopProvider.cs @@ -17,5 +17,6 @@ namespace FreeSql.Internal.CommonProvider public EventHandler CurdAfter { get; set; } public EventHandler SyncStructureBefore { get; set; } public EventHandler SyncStructureAfter { get; set; } + public EventHandler AuditValue { get; set; } } } diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 04ae09d6..4a3da08e 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -559,6 +559,13 @@ namespace FreeSql.Internal.CommonProvider object val = col.GetMapValue(d); if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) col.SetMapValue(d, val = FreeUtil.NewMongodbId()); + if (_orm.Aop.AuditValue != null) + { + var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Insert, col, _table.Properties[col.CsName], val); + _orm.Aop.AuditValue(this, auditArgs); + if (auditArgs.Value != null) + col.SetMapValue(d, val = auditArgs.Value); + } if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 049e6cbd..4d2ac1f2 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -605,15 +605,20 @@ namespace FreeSql.Internal.CommonProvider { if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - var value = col.GetMapValue(_source.First()); - if (_noneParameter) + var val = col.GetMapValue(_source.First()); + if (_orm.Aop.AuditValue != null) { - sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value)); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Update, col, _table.Properties[col.CsName], val); + _orm.Aop.AuditValue(this, auditArgs); + if (auditArgs.Value != null) + col.SetMapValue(_source.First(), val = auditArgs.Value); } + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); - _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, value); + _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, val); } ++colidx; } @@ -646,17 +651,22 @@ namespace FreeSql.Internal.CommonProvider cwsb.Append(" \r\nWHEN "); ToSqlWhen(cwsb, _table.Primarys, d); cwsb.Append(" THEN "); - var value = col.GetMapValue(d); - if (_noneParameter) + var val = col.GetMapValue(d); + if (_orm.Aop.AuditValue != null) { - cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value)); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Update, col, _table.Properties[col.CsName], val); + _orm.Aop.AuditValue(this, auditArgs); + if (auditArgs.Value != null) + col.SetMapValue(_source.First(), val = auditArgs.Value); } + if (_noneParameter) + cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); else { cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); - _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, value); + _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, val); } - if (isnull == false) isnull = value == null || value == DBNull.Value; + if (isnull == false) isnull = val == null || val == DBNull.Value; } cwsb.Append(" END"); if (isnull == false) diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 79cc3192..6980bab6 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -70,6 +70,13 @@ namespace FreeSql.Oracle.Curd object val = col.GetMapValue(d); if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) col.SetMapValue(d, val = FreeUtil.NewMongodbId()); + if (_orm.Aop.AuditValue != null) + { + var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Insert, col, _table.Properties[col.CsName], val); + _orm.Aop.AuditValue(this, auditArgs); + if (auditArgs.Value != null) + col.SetMapValue(d, val = auditArgs.Value); + } if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else From 33612bd8bdc98f3ccb067cd28583fd84b62c7589 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 25 Aug 2019 18:19:31 +0800 Subject: [PATCH 0103/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Aop.AuditVal?= =?UTF-8?q?ue=20=E4=BA=8B=E4=BB=B6=EF=BC=8C=E5=9C=A8=E6=8F=92=E5=85=A5/?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE=E6=97=B6=E5=AE=A1=E8=AE=A1?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Interface/IAop.cs | 2 +- FreeSql/Internal/CommonProvider/InsertProvider.cs | 2 +- FreeSql/Internal/CommonProvider/UpdateProvider.cs | 4 ++-- Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index 23cfd63e..5a910569 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -306,7 +306,7 @@ namespace FreeSql.Aop } } private object _value; - internal bool IsChanged { get; private set; } + public bool IsChanged { get; private set; } } public enum AutoValueType { Update, Insert } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 4a3da08e..70210226 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -563,7 +563,7 @@ namespace FreeSql.Internal.CommonProvider { var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Insert, col, _table.Properties[col.CsName], val); _orm.Aop.AuditValue(this, auditArgs); - if (auditArgs.Value != null) + if (auditArgs.IsChanged) col.SetMapValue(d, val = auditArgs.Value); } if (_noneParameter) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 4d2ac1f2..5589ede6 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -610,7 +610,7 @@ namespace FreeSql.Internal.CommonProvider { var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Update, col, _table.Properties[col.CsName], val); _orm.Aop.AuditValue(this, auditArgs); - if (auditArgs.Value != null) + if (auditArgs.IsChanged) col.SetMapValue(_source.First(), val = auditArgs.Value); } if (_noneParameter) @@ -656,7 +656,7 @@ namespace FreeSql.Internal.CommonProvider { var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Update, col, _table.Properties[col.CsName], val); _orm.Aop.AuditValue(this, auditArgs); - if (auditArgs.Value != null) + if (auditArgs.IsChanged) col.SetMapValue(_source.First(), val = auditArgs.Value); } if (_noneParameter) diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 6980bab6..97745f0f 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -74,7 +74,7 @@ namespace FreeSql.Oracle.Curd { var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Insert, col, _table.Properties[col.CsName], val); _orm.Aop.AuditValue(this, auditArgs); - if (auditArgs.Value != null) + if (auditArgs.IsChanged) col.SetMapValue(d, val = auditArgs.Value); } if (_noneParameter) From a7b15dd57deb248d4a0cbda79367246ad078e921 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 25 Aug 2019 18:21:58 +0800 Subject: [PATCH 0104/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20Aop.AuditVal?= =?UTF-8?q?ue=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlAopTest.cs | 6 +++--- FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs | 6 +++--- FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs | 6 +++--- FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs | 6 +++--- FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs | 6 +++--- FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlAopTest.cs index 2bec5373..46a3d7f1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlAopTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlAopTest.cs @@ -20,13 +20,13 @@ namespace FreeSql.Tests.MySqlConnector [Fact] public void AuditValue() { - var now = DateTime.Now; + var date = DateTime.Now.Date; var item = new TestAuditValue(); EventHandler audit = (s, e) => { if (e.Property.GetCustomAttribute(false) != null) - e.Value = DateTime.Now; + e.Value = DateTime.Now.Date; }; g.mysql.Aop.AuditValue += audit; @@ -34,7 +34,7 @@ namespace FreeSql.Tests.MySqlConnector g.mysql.Aop.AuditValue -= audit; - Assert.Equal(item.createtime.Date, now.Date); + Assert.Equal(item.createtime, date); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs index a154f0a5..43192a12 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAopTest.cs @@ -20,13 +20,13 @@ namespace FreeSql.Tests.MySql [Fact] public void AuditValue() { - var now = DateTime.Now; + var date = DateTime.Now.Date; var item = new TestAuditValue(); EventHandler audit = (s, e) => { if (e.Property.GetCustomAttribute(false) != null) - e.Value = DateTime.Now; + e.Value = DateTime.Now.Date; }; g.mysql.Aop.AuditValue += audit; @@ -34,7 +34,7 @@ namespace FreeSql.Tests.MySql g.mysql.Aop.AuditValue -= audit; - Assert.Equal(item.createtime.Date, now.Date); + Assert.Equal(item.createtime, date); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs index 5a30b033..05b6199d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAopTest.cs @@ -20,13 +20,13 @@ namespace FreeSql.Tests.Oracle [Fact] public void AuditValue() { - var now = DateTime.Now; + var date = DateTime.Now.Date; var item = new TestAuditValue(); EventHandler audit = (s, e) => { if (e.Property.GetCustomAttribute(false) != null) - e.Value = DateTime.Now; + e.Value = DateTime.Now.Date; }; g.oracle.Aop.AuditValue += audit; @@ -34,7 +34,7 @@ namespace FreeSql.Tests.Oracle g.oracle.Aop.AuditValue -= audit; - Assert.Equal(item.createtime.Date, now.Date); + Assert.Equal(item.createtime, date); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs index ad0e5140..d311a9b0 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAopTest.cs @@ -20,13 +20,13 @@ namespace FreeSql.Tests.PostgreSQL [Fact] public void AuditValue() { - var now = DateTime.Now; + var date = DateTime.Now.Date; var item = new TestAuditValue(); EventHandler audit = (s, e) => { if (e.Property.GetCustomAttribute(false) != null) - e.Value = DateTime.Now; + e.Value = DateTime.Now.Date; }; g.pgsql.Aop.AuditValue += audit; @@ -34,7 +34,7 @@ namespace FreeSql.Tests.PostgreSQL g.pgsql.Aop.AuditValue -= audit; - Assert.Equal(item.createtime.Date, now.Date); + Assert.Equal(item.createtime, date); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs index 3c8b4511..ca8ccc81 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAopTest.cs @@ -20,13 +20,13 @@ namespace FreeSql.Tests.SqlServer [Fact] public void AuditValue() { - var now = DateTime.Now; + var date = DateTime.Now.Date; var item = new TestAuditValue(); EventHandler audit = (s, e) => { if (e.Property.GetCustomAttribute(false) != null) - e.Value = DateTime.Now; + e.Value = DateTime.Now.Date; }; g.sqlserver.Aop.AuditValue += audit; @@ -34,7 +34,7 @@ namespace FreeSql.Tests.SqlServer g.sqlserver.Aop.AuditValue -= audit; - Assert.Equal(item.createtime.Date, now.Date); + Assert.Equal(item.createtime, date); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs index 5cddd046..dd5e9517 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAopTest.cs @@ -20,13 +20,13 @@ namespace FreeSql.Tests.Sqlite [Fact] public void AuditValue() { - var now = DateTime.Now; + var date = DateTime.Now.Date; var item = new TestAuditValue(); EventHandler audit = (s, e) => { if (e.Property.GetCustomAttribute(false) != null) - e.Value = DateTime.Now; + e.Value = DateTime.Now.Date; }; g.sqlite.Aop.AuditValue += audit; @@ -34,7 +34,7 @@ namespace FreeSql.Tests.Sqlite g.sqlite.Aop.AuditValue -= audit; - Assert.Equal(item.createtime.Date, now.Date); + Assert.Equal(item.createtime, date); } } } From 5b3820185f4f261647a3659a3c8b3e6453a67c4f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 25 Aug 2019 18:25:08 +0800 Subject: [PATCH 0105/1029] v0.8.11 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 8b2f5c3a..4770b772 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.10 + 0.8.11 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 86b97d87..28991bc3 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index af993212..35cc4aa9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 743510b5..a39e8330 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.10 + 0.8.11 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 56e1f79b..c69948ec 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index f2e7e9c5..0efc4963 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 935f1af5..61c778ee 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 4d8d5124..be225f91 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d8824a7e..f5ce7805 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cbd197f0..ab93ff3c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 3fa1507e..2dc3e42b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.10 + 0.8.11 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 2dd937303b89444088554ce7a355672f5bb39a2b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 29 Aug 2019 13:53:31 +0800 Subject: [PATCH 0106/1029] update readme --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 8 ++++++++ readme.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index b40ecf8b..1a86ff27 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -344,9 +344,17 @@ namespace FreeSql.Tests public bool IsLeaf { get; set; } } + public static int GetUNIX_TIMESTAMP() => 0; [Fact] public void Test1() { + g.mysql.Aop.ParseExpression += new EventHandler((s, e) => + { + if (e.Expression.NodeType == ExpressionType.Call && (e.Expression as MethodCallExpression).Method.Name == "GetUNIX_TIMESTAMP") + e.Result = "UNIX_TIMESTAMP(NOW())"; + }); + var dkkdksdjgj = g.mysql.Select().Where(a => a.OptionsEntity04 > GetUNIX_TIMESTAMP()).ToSql(); + var kdkdfm = g.sqlite.Select() .Include(a => a.MedicalRecord) .ToSql(); diff --git a/readme.md b/readme.md index 5894292c..67459e42 100644 --- a/readme.md +++ b/readme.md @@ -65,7 +65,7 @@ IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") .UseAutoSyncStructure(true) //自动同步实体结构到数据库 - .Build(); + .Build(); //请务必定义成 Singleton 单例模式 class Song { [Column(IsIdentity = true)] From 2db48bbcf995c26ccb0df2425c780a26d21e3f6a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 29 Aug 2019 14:55:42 +0800 Subject: [PATCH 0107/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.Firs?= =?UTF-8?q?t()=20=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 14 ++++++++++++++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 14 ++++++++++++++ .../SelectProvider/Select1Provider.cs | 7 ++++--- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 310ff7ed..be8774fe 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1032,6 +1032,13 @@ 选择列 + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 @@ -1040,6 +1047,13 @@ 选择列 + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + 返回即将执行的SQL语句 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index aee69f3a..0ec2e749 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -48,6 +48,13 @@ namespace FreeSql /// TReturn ToOne(Expression> select); Task ToOneAsync(Expression> select); + /// + /// 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + /// + /// + /// + TDto ToOne(); + Task ToOneAsync(); /// /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 @@ -57,6 +64,13 @@ namespace FreeSql /// TReturn First(Expression> select); Task FirstAsync(Expression> select); + /// + /// 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + /// + /// + /// + TDto First(); + Task FirstAsync(); /// /// 返回即将执行的SQL语句 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index e0a1a421..5f82840d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -372,16 +372,17 @@ namespace FreeSql.Internal.CommonProvider } public bool Any(Expression> exp) => this.Where(exp).Any(); - public Task AnyAsync(Expression> exp) => this.Where(exp).AnyAsync(); public TReturn ToOne(Expression> select) => this.Limit(1).ToList(select).FirstOrDefault(); - async public Task ToOneAsync(Expression> select) => (await this.Limit(1).ToListAsync(select)).FirstOrDefault(); + public TDto ToOne() => this.Limit(1).ToList().FirstOrDefault(); + async public Task ToOneAsync() => (await this.Limit(1).ToListAsync()).FirstOrDefault(); public TReturn First(Expression> select) => this.ToOne(select); - public Task FirstAsync(Expression> select) => this.ToOneAsync(select); + public TDto First() => this.ToOne(); + public Task FirstAsync() => this.ToOneAsync(); public ISelect Include(Expression> navigateSelector) where TNavigate : class { From ce392689d7fd6188c89703b933aa0bc4ed3fc353 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 29 Aug 2019 21:51:01 +0800 Subject: [PATCH 0108/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20MapType=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E5=B1=82=E7=BA=A7=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 3 +++ FreeSql/Internal/CommonExpression.cs | 1 + 2 files changed, 4 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 1a86ff27..6d8081d5 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -355,6 +355,9 @@ namespace FreeSql.Tests }); var dkkdksdjgj = g.mysql.Select().Where(a => a.OptionsEntity04 > GetUNIX_TIMESTAMP()).ToSql(); + var dt1970 = new DateTime(1970, 1, 1); + var dkkdksdjgj22 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.Subtract(dt1970).TotalSeconds).ToSql(); + var kdkdfm = g.sqlite.Select() .Include(a => a.MedicalRecord) .ToSql(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index e9b4b6fe..63ab1906 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -528,6 +528,7 @@ namespace FreeSql.Internal var condExp = exp as ConditionalExpression; return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end"; case ExpressionType.Call: + tsc.mapType = null; var exp3 = exp as MethodCallExpression; var callType = exp3.Object?.Type ?? exp3.Method.DeclaringType; switch (callType.FullName) From 16bd3941c5f6fc9a4d6b2c96a3f3620a5ac3ea55 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 29 Aug 2019 21:57:37 +0800 Subject: [PATCH 0109/1029] 0.9.1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 4770b772..701b4a55 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.8.11 + 0.9.1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 28991bc3..97737741 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 35cc4aa9..29286523 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index a39e8330..54753c62 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.11 + 0.9.1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c69948ec..65199c72 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0efc4963..0991ac50 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 61c778ee..f48e0c68 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index be225f91..300a56a9 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f5ce7805..4aa6bf90 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index ab93ff3c..b4e82967 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 2dc3e42b..fd955544 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.8.11 + 0.9.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From baf6d768a4d3ed1b9acc447d742db08e7fdc2ea5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 31 Aug 2019 03:00:17 +0800 Subject: [PATCH 0110/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Aop.AuditVal?= =?UTF-8?q?ue=20=E4=B8=8E=20FreeSql.Repository=20=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E7=AE=A1=E7=90=86=E7=9A=84=E5=86=B2=E7=AA=81?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSet.cs | 2 + FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 147 ++++++++++++++++++ .../FreeSql.Tests/Other/EntityBase.cs | 84 ++++++++++ FreeSql.Tests/FreeSql.Tests/Other/IEntity.cs | 21 +++ .../FreeSql.Tests/Other/IdentityType.cs | 16 ++ .../FreeSql.Tests/Other/SystemUser.cs | 60 +++++++ .../Other/SystemUserAuthentication.cs | 46 ++++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 49 ++++++ FreeSql/FreeSql.xml | 2 +- FreeSql/Interface/IAop.cs | 10 +- .../Internal/CommonProvider/InsertProvider.cs | 52 +++++-- .../Internal/CommonProvider/UpdateProvider.cs | 48 ++++-- FreeSql/Internal/Model/ColumnInfo.cs | 20 +-- .../Curd/OracleInsert.cs | 9 -- 14 files changed, 514 insertions(+), 52 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/EntityBase.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/IEntity.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/IdentityType.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/SystemUser.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/SystemUserAuthentication.cs diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 9a5d208e..32c69096 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -210,6 +210,7 @@ namespace FreeSql if (isThrow) throw new Exception($"不可添加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } + FreeSql.Internal.CommonProvider.InsertProvider.AuditDataValue(this, data, _db.Orm, _table); var key = _db.Orm.GetEntityKeyString(_entityType, data, true); if (string.IsNullOrEmpty(key)) { @@ -269,6 +270,7 @@ namespace FreeSql if (isThrow) throw new Exception($"不可更新,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } + FreeSql.Internal.CommonProvider.UpdateProvider.AuditDataValue(this, data, _db.Orm, _table); var key = _db.Orm.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) { diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 52359271..6f593095 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -199,5 +199,152 @@ 创建日期 + + + 实体类基类 + + + + + 初始化一个类型的新实例 + + + + + 获取或设置主键 + + + + + 创建时间 + + + + + 判断两个实体是否是同一数据记录的实体 + + 要比较的实体信息 + + + + + 实体Id是否相等 + + + + + 用作特定类型的哈希函数 + + + 当前 的哈希代码。
+ 如果Idnull则返回0, + 如果不为null则返回Id对应的哈希值 +
+
+ + + 数据模型接口 + + + + + 实体唯一标识,主键 + + + + + 创建时间 + + + + + 登录类型 + + + + + 用户表 + + + + + 显示名称 + + + + + 真实名称 + + + + + 性别 + + + + + 生日 + + + + + 头像URL地址 + + + + + 备注 + + + + + 启用标志 + + + + + 删除标志 + + + + + 所属用户认证记录 + + + + + 用户认证表 + + + + + 用户表ID + + + + + 用户 + + + + + 登录类型 + + + + + 登录标识 + + + + + 登录凭证 + + + + + 验证标志 + + diff --git a/FreeSql.Tests/FreeSql.Tests/Other/EntityBase.cs b/FreeSql.Tests/FreeSql.Tests/Other/EntityBase.cs new file mode 100644 index 00000000..06309501 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/EntityBase.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Text; + +namespace Zeus.Utility.Entity +{ + /// + /// 实体类基类 + /// + public abstract class EntityBase : IEntity where TKey : IEquatable + { + /// + /// 初始化一个类型的新实例 + /// + protected EntityBase() + { + + } + + /// + /// 获取或设置主键 + /// + [Key] + public virtual TKey ID { get; set; } + + /// + /// 创建时间 + /// + public virtual DateTime CreatedAt { get; set; } = DateTime.Now; + + /// + /// 判断两个实体是否是同一数据记录的实体 + /// + /// 要比较的实体信息 + /// + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + if (!(obj is EntityBase entity)) + { + return false; + } + return IsKeyEqual(entity.ID, ID); + } + + /// + /// 实体Id是否相等 + /// + public static bool IsKeyEqual(TKey id1, TKey id2) + { + if (id1 == null && id2 == null) + { + return true; + } + if (id1 == null || id2 == null) + { + return false; + } + + return Equals(id1, id2); + } + + /// + /// 用作特定类型的哈希函数 + /// + /// + /// 当前 的哈希代码。
+ /// 如果Idnull则返回0, + /// 如果不为null则返回Id对应的哈希值 + ///
+ public override int GetHashCode() + { + if (ID == null) + { + return 0; + } + return ID.ToString().GetHashCode(); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/IEntity.cs b/FreeSql.Tests/FreeSql.Tests/Other/IEntity.cs new file mode 100644 index 00000000..5851fb4a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/IEntity.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Zeus.Utility.Entity +{ + /// + /// 数据模型接口 + /// + public interface IEntity + { + /// + /// 实体唯一标识,主键 + /// + TKey ID { get; } + /// + /// 创建时间 + /// + DateTime CreatedAt { get; set; } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/IdentityType.cs b/FreeSql.Tests/FreeSql.Tests/Other/IdentityType.cs new file mode 100644 index 00000000..73c2622c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/IdentityType.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Zeus.Domain.Enum +{ + /// + /// 登录类型 + /// + public enum IdentityType + { + Account, + Email, + Mobile + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/SystemUser.cs b/FreeSql.Tests/FreeSql.Tests/Other/SystemUser.cs new file mode 100644 index 00000000..1b7a0a8a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/SystemUser.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using FreeSql.DataAnnotations; +using Zeus.Utility.Entity; + +namespace Zeus +{ + /// + /// 用户表 + /// + [Table(Name = "system_user")] + public partial class SystemUser : EntityBase + { + /// + /// 显示名称 + /// + [Column(DbType = "varchar(20)", IsNullable = false, Unique = "UK_DisplayName")] + public string DisplayName { get; set; } + /// + /// 真实名称 + /// + [Column(DbType = "varchar(20)")] + public string RealName { get; set; } + /// + /// 性别 + /// + [Column(DbType = "varchar(2)")] + public string Gender { get; set; } + /// + /// 生日 + /// + [Column(DbType = "datetime")] + public DateTime? Birthday { get; set; } + /// + /// 头像URL地址 + /// + [Column(DbType = "varchar(200)")] + public string AvaterURL { get; set; } + /// + /// 备注 + /// + [Column(DbType = "varchar(500)")] + public string Remark { get; set; } + /// + /// 启用标志 + /// + [Column(DbType = "bit(1)", IsNullable = false)] + public bool IsEnabled { get; set; } + /// + /// 删除标志 + /// + [Column(DbType = "bit(1)", IsNullable = false)] + public bool IsDeleted { get; set; } + /// + /// 所属用户认证记录 + /// + [Navigate("SystemUserID")] + public ICollection SystemUserAuthentication_List { get; set; } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/SystemUserAuthentication.cs b/FreeSql.Tests/FreeSql.Tests/Other/SystemUserAuthentication.cs new file mode 100644 index 00000000..5da122f7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/SystemUserAuthentication.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using FreeSql.DataAnnotations; +using Zeus.Domain.Enum; +using Zeus.Utility.Entity; + +namespace Zeus +{ + /// + /// 用户认证表 + /// + [Table(Name = "system_user_authentication")] + public partial class SystemUserAuthentication : EntityBase + { + /// + /// 用户表ID + /// + [Column(DbType = "bigint(20)", IsNullable = false)] + public long SystemUserID { get; set; } + /// + /// 用户 + /// + [Navigate("SystemUserID")] + public SystemUser SystemUser { get; set; } + /// + /// 登录类型 + /// + [Column(DbType = "varchar(10)", MapType = typeof(string), IsNullable = false)] + public IdentityType IdentityType { get; set; } + /// + /// 登录标识 + /// + [Column(DbType = "varchar(50)", IsNullable = false, Unique = "UK_Identifier")] + public string Identifier { get; set; } + /// + /// 登录凭证 + /// + [Column(DbType = "varchar(50)", IsNullable = false)] + public string Credential { get; set; } + /// + /// 验证标志 + /// + [Column(DbType = "bit(1)", IsNullable = false)] + public bool IsVerified { get; set; } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 6d8081d5..71b6e582 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -11,6 +11,10 @@ using System.Linq.Expressions; using System.Threading.Tasks; using System.Collections; using System.Diagnostics; +using Zeus; +using Zeus.Domain.Enum; +using System.ComponentModel.DataAnnotations; +using System.Reflection; namespace FreeSql.Tests { @@ -345,9 +349,54 @@ namespace FreeSql.Tests } public static int GetUNIX_TIMESTAMP() => 0; + + private List GetSystemUser() + { + SystemUser user = new SystemUser + { + DisplayName = "系统管理员", + RealName = "系统管理员", + Gender = "男", + Birthday = new DateTime(1984, 7, 1), + IsEnabled = true, + IsDeleted = false, + Remark = "禁止删除", + SystemUserAuthentication_List = new List() + }; + user.SystemUserAuthentication_List.Add(new SystemUserAuthentication() + { + IdentityType = IdentityType.Account, + Identifier = "admin", + Credential = "HyrPNXuCBaqZU3QIJqP9eThOHpFfm9p+", + IsVerified = true + }); + user.SystemUserAuthentication_List.Add(new SystemUserAuthentication() + { + IdentityType = IdentityType.Mobile, + Identifier = "13580592001", + Credential = "HyrPNXuCBaqZU3QIJqP9eThOHpFfm9p+", + IsVerified = true + }); + var users = new List + { + user + }; + return users; + } + + [Fact] public void Test1() { + //g.mysql.Aop.AuditValue += (s, e) => + //{ + // if (e.Column.CsType == typeof(long) + // && e.Property.GetCustomAttribute(false) != null + // && e.Value?.ToString() == "0") + // e.Value = new Random().Next(); + //}; + //g.mysql.GetRepository().Insert(GetSystemUser()); + g.mysql.Aop.ParseExpression += new EventHandler((s, e) => { if (e.Expression.NodeType == ExpressionType.Call && (e.Expression as MethodCallExpression).Method.Name == "GetUNIX_TIMESTAMP") diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index be8774fe..dc1ed173 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2164,7 +2164,7 @@ 耗时(单位:毫秒)
- + 类型 diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index 5a910569..cb8a4043 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -273,18 +273,18 @@ namespace FreeSql.Aop public class AuditValueEventArgs : EventArgs { - public AuditValueEventArgs(AutoValueType autoValueType, ColumnInfo column, PropertyInfo property, object value) + public AuditValueEventArgs(AuditValueType autoValueType, ColumnInfo column, PropertyInfo property, object value) { - this.AutoValueType = autoValueType; + this.AuditValueType = autoValueType; this.Column = column; this.Property = property; - this.Value = value; + this._value = value; } /// /// 类型 /// - public AutoValueType AutoValueType { get; } + public AuditValueType AuditValueType { get; } /// /// 属性列的元数据 /// @@ -308,5 +308,5 @@ namespace FreeSql.Aop private object _value; public bool IsChanged { get; private set; } } - public enum AutoValueType { Update, Insert } + public enum AuditValueType { Update, Insert } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 70210226..b41e4cd3 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -71,19 +71,56 @@ namespace FreeSql.Internal.CommonProvider public IInsert AppendData(T1 source) { - if (source != null) _source.Add(source); + if (source != null) + { + AuditDataValue(this, source, _orm, _table); + _source.Add(source); + } return this; } public IInsert AppendData(T1[] source) { - if (source != null) _source.AddRange(source); + if (source != null) + { + AuditDataValue(this, source, _orm, _table); + _source.AddRange(source); + } return this; } public IInsert AppendData(IEnumerable source) { - if (source != null) _source.AddRange(source.Where(a => a != null)); + if (source != null) + { + source = source.Where(a => a != null).ToList(); + AuditDataValue(this, source, _orm, _table); + _source.AddRange(source); + + } return this; } + public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table) + { + if (data?.Any() != true) return; + foreach (var d in data) + AuditDataValue(sender, d, orm, table); + } + public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table) + { + if (data == null) return; + foreach (var col in table.Columns.Values) + { + object val = col.GetMapValue(data); + if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) + col.SetMapValue(data, val = FreeUtil.NewMongodbId()); + if (orm.Aop.AuditValue != null) + { + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); + orm.Aop.AuditValue(sender, auditArgs); + if (auditArgs.IsChanged) + col.SetMapValue(data, val = auditArgs.Value); + } + } + } #region 参数化数据限制,或values数量限制 protected List[] SplitSource(int valuesLimit, int parameterLimit) @@ -557,15 +594,6 @@ namespace FreeSql.Internal.CommonProvider if (colidx2 > 0) sb.Append(", "); object val = col.GetMapValue(d); - if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) - col.SetMapValue(d, val = FreeUtil.NewMongodbId()); - if (_orm.Aop.AuditValue != null) - { - var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Insert, col, _table.Properties[col.CsName], val); - _orm.Aop.AuditValue(this, auditArgs); - if (auditArgs.IsChanged) - col.SetMapValue(d, val = auditArgs.Value); - } if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 5589ede6..ce358480 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -401,10 +401,42 @@ namespace FreeSql.Internal.CommonProvider return this; } + public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table) + { + if (data?.Any() != true) return; + if (orm.Aop.AuditValue == null) return; + foreach (var d in data) + { + if (d == null) continue; + foreach (var col in table.Columns.Values) + { + object val = col.GetMapValue(d); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); + orm.Aop.AuditValue(sender, auditArgs); + if (auditArgs.IsChanged) + col.SetMapValue(d, val = auditArgs.Value); + } + } + } + public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table) + { + if (orm.Aop.AuditValue == null) return; + if (data == null) return; + foreach (var col in table.Columns.Values) + { + object val = col.GetMapValue(data); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); + orm.Aop.AuditValue(sender, auditArgs); + if (auditArgs.IsChanged) + col.SetMapValue(data, val = auditArgs.Value); + } + } + public IUpdate SetSource(T1 source) => this.SetSource(new[] { source }); public IUpdate SetSource(IEnumerable source) { if (source == null || source.Any() == false) return this; + AuditDataValue(this, source, _orm, _table); _source.AddRange(source.Where(a => a != null)); return this; } @@ -606,13 +638,6 @@ namespace FreeSql.Internal.CommonProvider if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); var val = col.GetMapValue(_source.First()); - if (_orm.Aop.AuditValue != null) - { - var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Update, col, _table.Properties[col.CsName], val); - _orm.Aop.AuditValue(this, auditArgs); - if (auditArgs.IsChanged) - col.SetMapValue(_source.First(), val = auditArgs.Value); - } if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); else @@ -629,7 +654,7 @@ namespace FreeSql.Internal.CommonProvider else if (_source.Count > 1) { //批量保存 Source if (_table.Primarys.Any() == false) return null; - + var caseWhen = new StringBuilder(); caseWhen.Append("CASE "); ToSqlCase(caseWhen, _table.Primarys); @@ -652,13 +677,6 @@ namespace FreeSql.Internal.CommonProvider ToSqlWhen(cwsb, _table.Primarys, d); cwsb.Append(" THEN "); var val = col.GetMapValue(d); - if (_orm.Aop.AuditValue != null) - { - var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Update, col, _table.Properties[col.CsName], val); - _orm.Aop.AuditValue(this, auditArgs); - if (auditArgs.IsChanged) - col.SetMapValue(_source.First(), val = auditArgs.Value); - } if (_noneParameter) cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); else diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index 8ff71303..fbc26e05 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -57,22 +57,22 @@ namespace FreeSql.Internal.Model var objExp = Expression.Parameter(typeof(object), "obj"); var valExp = Expression.Parameter(typeof(object), "val"); - if (Attribute.MapType == CsType) - return Expression.Lambda>( - Expression.Assign(Expression.MakeMemberAccess( - Expression.TypeAs(objExp, col.Table.Type), - Table.Properties[col.CsName] - ), Expression.Convert( - valExp, - Attribute.MapType)), objExp, valExp).Compile(); + //if (Attribute.MapType == CsType) + // return Expression.Lambda>( + // Expression.Assign(Expression.MakeMemberAccess( + // Expression.TypeAs(objExp, col.Table.Type), + // Table.Properties[col.CsName] + // ), Expression.Convert( + // valExp, + // Attribute.MapType)), objExp, valExp).Compile(); return Expression.Lambda>( Expression.Assign(Expression.MakeMemberAccess( Expression.TypeAs(objExp, col.Table.Type), Table.Properties[col.CsName] ), Expression.Convert( - Utils.GetDataReaderValueBlockExpression(Attribute.MapType, valExp), - Attribute.MapType)), objExp, valExp).Compile(); + Utils.GetDataReaderValueBlockExpression(CsType, valExp), + CsType)), objExp, valExp).Compile(); }); func(obj, val); } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 97745f0f..61f68ec6 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -68,15 +68,6 @@ namespace FreeSql.Oracle.Curd if (colidx2 > 0) sb.Append(", "); object val = col.GetMapValue(d); - if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) - col.SetMapValue(d, val = FreeUtil.NewMongodbId()); - if (_orm.Aop.AuditValue != null) - { - var auditArgs = new Aop.AuditValueEventArgs(Aop.AutoValueType.Insert, col, _table.Properties[col.CsName], val); - _orm.Aop.AuditValue(this, auditArgs); - if (auditArgs.IsChanged) - col.SetMapValue(d, val = auditArgs.Value); - } if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else From 56cd333f6f17e55574838a79ffb91ff19f61f265 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 31 Aug 2019 03:01:50 +0800 Subject: [PATCH 0111/1029] v0.9.2 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 701b4a55..1daccdf0 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.1 + 0.9.2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 97737741..e5173f5e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 29286523..37b67775 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 54753c62..d00a8ab9 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.1 + 0.9.2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 65199c72..fd85f12c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0991ac50..f5a49e2b 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f48e0c68..6dce837c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 300a56a9..fbed4bb2 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 4aa6bf90..46e4f09f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b4e82967..7dc6501e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fd955544..7114dc55 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.1 + 0.9.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From de6e99c710df060453262eee1d84b231ac16c757 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 1 Sep 2019 11:12:52 +0800 Subject: [PATCH 0112/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E5=B1=9E=E6=80=A7=E9=85=8D=E7=BD=AE=E5=92=8CAop?= =?UTF-8?q?=E5=86=B2=E7=AA=81=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 32 ++++++++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 4 +-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 71b6e582..efc884c6 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -385,9 +385,41 @@ namespace FreeSql.Tests } + [Table(Name = "bz_web_post")] + public class Post + { + public int Id { get; set; } + public int AuthorId { get; set; } + [Navigate("AuthorId")] + public AuthorTest Author { get; set; } + } + [Table(Name = "bz_web_authortest")] + public class AuthorTest + { + public int Id { get; set; } + public string Name { get; set; } + [Navigate("AuthorId")] + public List Post { get; set; } + } + [Fact] public void Test1() { + IFreeSql fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=7") + .UseEntityPropertyNameConvert(Internal.StringConvertType.PascalCaseToUnderscoreWithLower) + .UseNoneCommandParameter(true) + .UseAutoSyncStructure(true) //自动同步实体结构到数据库 + .UseMonitorCommand(a => Trace.WriteLine(a.CommandText)) + .Build(); + + var data = fsql.Select().ToList(r => new + { + Id = r.Id, + Name = r.AuthorId.ToString(), + AuthorName = r.Author.Name, + }); + //g.mysql.Aop.AuditValue += (s, e) => //{ // if (e.Column.CsType == typeof(long) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index ec2d91f5..b6389fed 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -75,8 +75,7 @@ namespace FreeSql.Internal var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); var colattr = common.GetEntityColumnAttribute(entity, p); var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType); - if (tp == null && colattr != null) colattr.IsIgnore = true; //无法匹配的属性,认定是导航属性,且自动过滤 - if (tp == null && colattr == null) + if (tp == null && colattr?.IsIgnore != true) { if (common.CodeFirst.IsLazyLoading) { @@ -88,6 +87,7 @@ namespace FreeSql.Internal propsNavObjs.Add(p); continue; } + if (tp == null && colattr != null) colattr.IsIgnore = true; //无法匹配的属性,认定是导航属性,且自动过滤 if (colattr == null) colattr = new ColumnAttribute { From ef18b61e84aa8b7148e6cad37fd10db357c1b438 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 1 Sep 2019 11:22:08 +0800 Subject: [PATCH 0113/1029] v0.9.3 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1daccdf0..e9f55e4b 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.2 + 0.9.3 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e5173f5e..ce7f4ac6 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 37b67775..5ef66980 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d00a8ab9..4e869f59 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.2 + 0.9.3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fd85f12c..2a1f44fb 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index f5a49e2b..51c2fba8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6dce837c..7988997d 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fbed4bb2..b6fa0531 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 46e4f09f..0afc8bbf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 7dc6501e..ef6729d4 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7114dc55..40e646c1 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.2 + 0.9.3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 96796106d5d8d0834157b920f14a99c7fdb887dc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 1 Sep 2019 18:03:33 +0800 Subject: [PATCH 0114/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E5=B1=9E=E6=80=A7=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E5=85=B3=E7=B3=BB=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E5=AF=BC=E8=87=B4=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/UtilsExpressionTree.cs | 1304 ++++++++++++----------- 1 file changed, 659 insertions(+), 645 deletions(-) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index b6389fed..d4a2cc21 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -246,7 +246,6 @@ namespace FreeSql.Internal #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}"; var trytbTypeLazyName = default(string); - var overrieds = 0; StringBuilder cscode = null; if (common.CodeFirst.IsLazyLoading && propsLazy.Any()) { @@ -265,656 +264,15 @@ namespace FreeSql.Internal .AppendLine(" [JsonIgnore] private IFreeSql __fsql_orm__ { get; set; }\r\n"); } + var cscodeLength = cscode?.Length ?? 0; foreach (var pnv in propsNavObjs) { var vp = propsLazy.Where(a => a.Item1 == pnv).FirstOrDefault(); var isLazy = vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName); - var propTypeName = pnv.PropertyType.IsGenericType ? - $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" : - (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name}"); - var pnvAttr = pnv.GetCustomAttribute(); - var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); - var nvref = new TableRef(); - nvref.Property = pnv; - - //List 或 ICollection,一对多、多对多 - var propElementType = pnv.PropertyType.GenericTypeArguments.FirstOrDefault() ?? pnv.PropertyType.GetElementType(); - if (propElementType != null) - { - if (typeof(IEnumerable).IsAssignableFrom(pnv.PropertyType) == false) continue; - if (trytb.Primarys.Any() == false) - { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {trytbTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - continue; - } - - var tbref = propElementType == trytb.Type ? trytb : GetTableByEntity(propElementType, common); //可能是父子关系 - if (tbref == null) continue; - - var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}"; - Type midType = null; - var isManyToMany = false; - - Action valiManyToMany = () => - { - if (midType != null) - { - var midTypeProps = midType.GetProperties(); - var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); - var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); - if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; - } - }; - - if (pnvAttr?.ManyToMany != null) - { - isManyToMany = propElementType != trytb.Type && - tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && - z.Value.GetCustomAttribute()?.ManyToMany == pnvAttr.ManyToMany && - typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); - - if (isManyToMany == false) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 必须存在对应的 [Navigate(ManyToMany = x)] 集合属性"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - continue; - } - if (isManyToMany) - { - midType = pnvAttr.ManyToMany; - valiManyToMany(); - } - } - else - { - isManyToMany = propElementType != trytb.Type && - pnv.Name.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase) && - tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && - z.Key.EndsWith($"{trytb.CsName}s", StringComparison.CurrentCultureIgnoreCase) && - typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); - } - if (isManyToMany) - { - if (tbref.Primarys.Any() == false) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - continue; - } - if (pnvAttr?.ManyToMany == null) - { - //中间表怎么查询,比如 Song、Tag、SongTag - var midFlagStr = string.Empty; - if (pnv.Name.Length >= tbref.CsName.Length - 1) - midFlagStr = pnv.Name.Remove(pnv.Name.Length - tbref.CsName.Length - 1); - - #region 在 trytb 命名空间下查找中间类 - if (midType == null) - { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); - valiManyToMany(); - } - if (midType == null) - { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - valiManyToMany(); - } - if (midType == null) - { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); - valiManyToMany(); - } - if (midType == null) - { - midType = trytb.Type.IsNested ? - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song - trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - valiManyToMany(); - } - #endregion - - #region 在 tbref 命名空间下查找中间类 - if (midType == null) - { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); - valiManyToMany(); - } - if (midType == null) - { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - valiManyToMany(); - } - if (midType == null) - { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); - valiManyToMany(); - } - if (midType == null) - { - midType = tbref.Type.IsNested ? - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song - tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); - valiManyToMany(); - } - #endregion - } - - isManyToMany = midType != null; - } - if (isManyToMany) - { - var tbmid = GetTableByEntity(midType, common); - var midTypePropsTrytb = tbmid.Properties.Where(a => a.Value.PropertyType == trytb.Type).FirstOrDefault().Value; - //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); - var lmbdWhere = isLazy ? new StringBuilder() : null; - - if (pnvAttr?.ManyToMany != null) - { - #region 指定 Navigate[ManyToMany = x] 配置多对多关系 - TableRef trytbTf = null; - try - { - trytbTf = tbmid.GetTableRef(midTypePropsTrytb.Name, true); - } - catch (Exception ex) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTrytb.Name} 错误:{ex.Message}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - if (nvref.Exception == null) - { - if (trytbTf.RefType != TableRefType.ManyToOne && trytbTf.RefType != TableRefType.OneToOne) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTrytb.Name} 导航属性不是【ManyToOne】或【OneToOne】"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - else - { - nvref.Columns.AddRange(trytbTf.RefColumns); - nvref.MiddleColumns.AddRange(trytbTf.Columns); - - if (tbmid.Primarys.Any() == false) - trytbTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true); - if (isLazy) - { - for (var a = 0; a < trytbTf.RefColumns.Count; a++) - { - if (a > 0) lmbdWhere.Append(" && "); - lmbdWhere.Append("b.").Append(trytbTf.Columns[a].CsName).Append(" == this.").Append(trytbTf.RefColumns[a].CsName); - } - } - } - } - if (nvref.Exception == null) - { - var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; - - TableRef tbrefTf = null; - try - { - tbrefTf = tbmid.GetTableRef(midTypePropsTbref.Name, true); - } - catch (Exception ex) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTbref.Name} 错误:{ex.Message}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - if (nvref.Exception == null) - { - if (tbrefTf.RefType != TableRefType.ManyToOne && tbrefTf.RefType != TableRefType.OneToOne) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTbref.Name} 导航属性不是【ManyToOne】或【OneToOne】"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - else - { - nvref.RefColumns.AddRange(tbrefTf.RefColumns); - nvref.MiddleColumns.AddRange(tbrefTf.Columns); - - if (tbmid.Primarys.Any() == false) - tbrefTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true); - - if (isLazy) - { - for (var a = 0; a < tbrefTf.RefColumns.Count; a++) - lmbdWhere.Append(" && b.").Append(tbrefTf.Columns[a].CsName).Append(" == a.").Append(tbrefTf.RefColumns[a].CsName); - } - } - } - } - #endregion - } - else - { - #region 约定配置 - for (var a = 0; a < trytb.Primarys.Length; a++) - { - var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); - if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); - if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}{findtrytbPkCsName}", out var trycol) == false && //骆峰命名 - tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}_{findtrytbPkCsName}", out trycol) == false //下划线命名 - ) - { - - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType.NullableTypeOrThis()) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {trytb.CsName}.{trytb.Primarys[a].CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - if (trycol == null) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTrytb.Name}{findtrytbPkCsName}、{midTypePropsTrytb.Name}_{findtrytbPkCsName}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - - nvref.Columns.Add(trytb.Primarys[a]); - nvref.MiddleColumns.Add(trycol); - if (tbmid.Primarys.Any() == false) - trycol.Attribute.IsPrimary = true; - - if (isLazy) - { - if (a > 0) lmbdWhere.Append(" && "); - lmbdWhere.Append("b.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); - } - } - - if (nvref.Exception == null) - { - var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; - for (var a = 0; a < tbref.Primarys.Length; a++) - { - var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); - if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); - if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 - tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名 - ) - { - - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType.NullableTypeOrThis()) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - if (trycol == null) - { - nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTbref.Name}{findtbrefPkCsName}、{midTypePropsTbref.Name}_{findtbrefPkCsName}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - - nvref.RefColumns.Add(tbref.Primarys[a]); - nvref.MiddleColumns.Add(trycol); - if (tbmid.Primarys.Any() == false) - trycol.Attribute.IsPrimary = true; - - if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); - } - } - #endregion - } - if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) - { - nvref.RefMiddleEntityType = tbmid.Type; - nvref.RefEntityType = tbref.Type; - nvref.RefType = TableRefType.ManyToMany; - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - - if (tbmid.Primarys.Any() == false) - tbmid.Primarys = tbmid.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); - } - - if (isLazy) - { - cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); - if (vp.Item2) - { //get 重写 - cscode.Append(" get {\r\n") - .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); - - if (nvref.Exception == null) - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}") - .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") - .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();") - .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); - else - cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); - - cscode.Append(" }\r\n") - .Append(" return base.").Append(pnv.Name).AppendLine(";") - .Append(" }\r\n"); - } - if (vp.Item3) - { //set 重写 - cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); - } - cscode.AppendLine(" }"); - } - } - else - { //One To Many - List bindColumns = new List(); - if (pnvBind != null) - { - foreach (var bi in pnvBind) - { - if (tbref.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) - { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {tbrefTypeName} 未找到属性:{bi}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - bindColumns.Add(trybindcol); - } - } - - PropertyInfo refprop = null; - var refcols = tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type); - refprop = refcols.Count() == 1 ? refcols.First().Value : null; - var lmbdWhere = isLazy ? new StringBuilder() : null; - - if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != trytb.Primarys.Length) - { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 内部主键数目({trytb.Primarys.Length}) 不相同"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - if (trytb.Primarys.Length > 1) - { - if (trytb.Primarys.Select(a => a.CsType.NullableTypeOrThis()).Distinct().Count() == trytb.Primarys.Length) - { - var pkList = trytb.Primarys.ToList(); - bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == b.CsType.NullableTypeOrThis()))); - } - else if (string.Compare(string.Join(",", trytb.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) - { - var pkList = trytb.Primarys.ToList(); - bindColumns.Sort((a, b) => pkList.FindIndex(c => string.Compare(c.CsName, a.CsName, true) == 0).CompareTo(pkList.FindIndex(c => string.Compare(c.CsName, b.CsName, true) == 0))); - } - } - for (var a = 0; nvref.Exception == null && a < trytb.Primarys.Length; a++) - { - var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); - if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); - var findtrytb = pnv.Name; - if (findtrytb.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase)) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1); - findtrytb += trytb.CsName; - - var trycol = bindColumns.Any() ? bindColumns[a] : null; - if (trycol == null && - tbref.ColumnsByCs.TryGetValue($"{findtrytb}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 - tbref.ColumnsByCs.TryGetValue($"{findtrytb}_{findtrytbPkCsName}", out trycol) == false //下划线命名 - ) - { - if (refprop != null && - tbref.ColumnsByCs.TryGetValue($"{refprop.Name}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 - tbref.ColumnsByCs.TryGetValue($"{refprop.Name}_{findtrytbPkCsName}", out trycol) == false) //下划线命名 - { - - } - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType.NullableTypeOrThis()) - { - nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trytb.Primarys[a].CsName} 和 {tbref.CsName}.{trycol.CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - if (trycol == null) - { - nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbref.CsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}" + (refprop == null ? "" : $"、{refprop.Name}{findtrytbPkCsName}、{refprop.Name}_{findtrytbPkCsName}。或者使用 [Navigate] 特性指定关系映射。")); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - - nvref.Columns.Add(trytb.Primarys[a]); - nvref.RefColumns.Add(trycol); - - if (isLazy && nvref.Exception == null) - { - if (a > 0) lmbdWhere.Append(" && "); - lmbdWhere.Append("a.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); - - if (refprop == null) - { //加载成功后,把列表对应的导航属性值设置为 this,比如 Select().ToOne().Topics 下的 TopicType 属性值全部为 this - var findtrytbName = trycol.CsName; - if (findtrytbName.EndsWith(trytb.Primarys.First().CsName)) - { - findtrytbName = findtrytbName.Remove(findtrytbName.Length - trytb.Primarys.First().CsName.Length).TrimEnd('_'); - if (tbref.Properties.TryGetValue(findtrytbName, out refprop) && refprop.PropertyType != trytb.Type) - refprop = null; - } - } - } - } - if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) - { - nvref.RefEntityType = tbref.Type; - nvref.RefType = TableRefType.OneToMany; - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - } - - if (isLazy) - { - cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); - if (vp.Item2) - { //get 重写 - cscode.Append(" get {\r\n") - .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); - - if (nvref.Exception == null) - { - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace?.NotNullAndConcat(".")}{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace?.NotNullAndConcat(".")}{propElementType.Name}").Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();"); - if (refprop != null) - { - cscode.Append(" foreach (var loc1 in base.").Append(pnv.Name).AppendLine(")") - .Append(" loc1.").Append(refprop.Name).AppendLine(" = this;") - .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); - } - } - else - cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); - - cscode - .Append(" }\r\n") - .Append(" return base.").Append(pnv.Name).AppendLine(";") - .Append(" }\r\n"); - } - if (vp.Item3) - { //set 重写 - cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); - } - cscode.AppendLine(" }"); - } - } - } - else - { //一对一、多对一 - var tbref = pnv.PropertyType == trytb.Type ? trytb : GetTableByEntity(pnv.PropertyType, common); //可能是父子关系 - if (tbref == null) continue; - if (tbref.Primarys.Any() == false) - { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {propTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}"; - var isOnoToOne = pnv.PropertyType != trytb.Type && - tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type).Any() && - tbref.Primarys.Length == trytb.Primarys.Length && - string.Join(",", tbref.Primarys.Select(a => a.CsType.NullableTypeOrThis().FullName).OrderBy(a => a)) == string.Join(",", trytb.Primarys.Select(a => a.CsType.NullableTypeOrThis().FullName).OrderBy(a => a)); - - List bindColumns = new List(); - if (pnvBind != null) - { - foreach (var bi in pnvBind) - { - if (trytb.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) - { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {trytbTypeName} 未找到属性:{bi}"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - bindColumns.Add(trybindcol); - } - } - var lmbdWhere = new StringBuilder(); - - if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != tbref.Primarys.Length) - { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 外部主键数目({tbref.Primarys.Length}) 不相同"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - } - if (tbref.Primarys.Length > 1) - { - if (tbref.Primarys.Select(a => a.CsType.NullableTypeOrThis()).Distinct().Count() == tbref.Primarys.Length) - { - var pkList = tbref.Primarys.ToList(); - bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == b.CsType.NullableTypeOrThis()))); - } - else if (string.Compare(string.Join(",", tbref.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) - { - var pkList = tbref.Primarys.ToList(); - bindColumns.Sort((a, b) => pkList.FindIndex(c => string.Compare(c.CsName, a.CsName, true) == 0).CompareTo(pkList.FindIndex(c => string.Compare(c.CsName, b.CsName, true) == 0))); - } - } - for (var a = 0; nvref.Exception == null && a < tbref.Primarys.Length; a++) - { - var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); - if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); - - var trycol = bindColumns.Any() ? bindColumns[a] : null; - if (trycol == null && - trytb.ColumnsByCs.TryGetValue($"{pnv.Name}{findtbrefPkCsName}", out trycol) == false && //骆峰命名 - trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_{findtbrefPkCsName}", out trycol) == false && //下划线命名 - //tbref.Primarys.Length == 1 && - trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_Id", out trycol) == false && - trytb.ColumnsByCs.TryGetValue($"{pnv.Name}Id", out trycol) == false - ) - { - //一对一,主键与主键查找 - if (isOnoToOne) - { - var trytbpks = trytb.Primarys.Where(z => z.CsType.NullableTypeOrThis() == tbref.Primarys[a].CsType.NullableTypeOrThis()); //一对一,按类型 - if (trytbpks.Count() == 1) trycol = trytbpks.First(); - else - { - trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, tbref.Primarys[a].CsName, true) == 0); //一对一,按主键名相同 - if (trytbpks.Count() == 1) trycol = trytbpks.First(); - else - { - trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, $"{tbref.CsName}{tbref.Primarys[a].CsName}", true) == 0); //一对一,主键名 = 表+主键名 - if (trytbpks.Count() == 1) trycol = trytbpks.First(); - else - { - trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, $"{tbref.CsName}_{tbref.Primarys[a].CsName}", true) == 0); //一对一,主键名 = 表+_主键名 - if (trytbpks.Count() == 1) trycol = trytbpks.First(); - } - } - } - } - } - if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType.NullableTypeOrThis()) - { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - if (trycol == null) - { - nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 没有找到对应的字段,如:{pnv.Name}{findtbrefPkCsName}、{pnv.Name}_{findtbrefPkCsName}。或者使用 [Navigate] 特性指定关系映射。"); - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - //if (isLazy) throw nvref.Exception; - break; - } - - nvref.Columns.Add(trycol); - nvref.RefColumns.Add(tbref.Primarys[a]); - - if (isLazy && nvref.Exception == null) - { - if (a > 0) lmbdWhere.Append(" && "); - lmbdWhere.Append("a.").Append(tbref.Primarys[a].CsName).Append(" == this.").Append(trycol.CsName); - } - } - if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) - { - nvref.RefEntityType = tbref.Type; - nvref.RefType = isOnoToOne ? TableRefType.OneToOne : TableRefType.ManyToOne; - trytb.AddOrUpdateTableRef(pnv.Name, nvref); - } - - if (isLazy) - { - cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); - if (vp.Item2) - { //get 重写 - cscode.Append(" get {\r\n") - .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); - - if (nvref.Exception == null) - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propTypeName).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToOne();") - .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); - else - cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); - - cscode - .Append(" }\r\n") - .Append(" return base.").Append(pnv.Name).AppendLine(";") - .Append(" }\r\n"); - } - if (vp.Item3) - { //set 重写 - cscode.Append(" set {\r\n") - .Append(" base.").Append(pnv.Name).AppendLine(" = value;") - .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;") - .Append(" }\r\n"); - } - cscode.AppendLine(" }"); - } - } - - if (isLazy) ++overrieds; + AddTableRef(common, trytb, pnv, isLazy, vp, cscode); } - if (overrieds > 0) + if (cscode?.Length > cscodeLength) { cscode.AppendLine("}"); Assembly assembly = null; @@ -936,6 +294,662 @@ namespace FreeSql.Internal return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb; } + public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, (PropertyInfo, bool, bool)? vp, StringBuilder cscode) + { + var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}"; + var propTypeName = pnv.PropertyType.IsGenericType ? + $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" : + (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name}"); + + var pnvAttr = pnv.GetCustomAttribute(); + var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); + var nvref = new TableRef(); + nvref.Property = pnv; + + //List 或 ICollection,一对多、多对多 + var propElementType = pnv.PropertyType.GenericTypeArguments.FirstOrDefault() ?? pnv.PropertyType.GetElementType(); + if (propElementType != null) + { + if (typeof(IEnumerable).IsAssignableFrom(pnv.PropertyType) == false) return; + if (trytb.Primarys.Any() == false) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {trytbTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + return; + } + + var tbref = propElementType == trytb.Type ? trytb : GetTableByEntity(propElementType, common); //可能是父子关系 + if (tbref == null) return; + + var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}"; + Type midType = null; + var isManyToMany = false; + + Action valiManyToMany = () => + { + if (midType != null) + { + var midTypeProps = midType.GetProperties(); + var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); + var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); + if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; + } + }; + + if (pnvAttr?.ManyToMany != null) + { + isManyToMany = propElementType != trytb.Type && + tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && + z.Value.GetCustomAttribute()?.ManyToMany == pnvAttr.ManyToMany && + typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); + + if (isManyToMany == false) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 必须存在对应的 [Navigate(ManyToMany = x)] 集合属性"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + return; + } + if (isManyToMany) + { + midType = pnvAttr.ManyToMany; + valiManyToMany(); + } + } + else + { + isManyToMany = propElementType != trytb.Type && + pnv.Name.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase) && + tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && + z.Key.EndsWith($"{trytb.CsName}s", StringComparison.CurrentCultureIgnoreCase) && + typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); + } + if (isManyToMany) + { + if (tbref.Primarys.Any() == false) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + return; + } + if (pnvAttr?.ManyToMany == null) + { + //中间表怎么查询,比如 Song、Tag、SongTag + var midFlagStr = string.Empty; + if (pnv.Name.Length >= tbref.CsName.Length - 1) + midFlagStr = pnv.Name.Remove(pnv.Name.Length - tbref.CsName.Length - 1); + + #region 在 trytb 命名空间下查找中间类 + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = trytb.Type.IsNested ? + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song + trytb.Type.Assembly.GetType($"{trytb.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + valiManyToMany(); + } + #endregion + + #region 在 tbref 命名空间下查找中间类 + if (midType == null) + { + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true); + valiManyToMany(); + } + if (midType == null) + { + midType = tbref.Type.IsNested ? + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song + tbref.Type.Assembly.GetType($"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true); + valiManyToMany(); + } + #endregion + } + + isManyToMany = midType != null; + } + if (isManyToMany) + { + var tbmid = GetTableByEntity(midType, common); + var midTypePropsTrytb = tbmid.Properties.Where(a => a.Value.PropertyType == trytb.Type).FirstOrDefault().Value; + //g.mysql.Select().Where(a => g.mysql.Select().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any()); + var lmbdWhere = isLazy ? new StringBuilder() : null; + + if (pnvAttr?.ManyToMany != null) + { + #region 指定 Navigate[ManyToMany = x] 配置多对多关系 + TableRef trytbTf = null; + try + { + trytbTf = tbmid.GetTableRef(midTypePropsTrytb.Name, true); + if (trytbTf == null) + { + AddTableRef(common, tbmid, midTypePropsTrytb, false, null, null); + trytbTf = tbmid.GetTableRef(midTypePropsTrytb.Name, true); + } + } + catch (Exception ex) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTrytb.Name} 错误:{ex.Message}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + if (nvref.Exception == null) + { + if (trytbTf.RefType != TableRefType.ManyToOne && trytbTf.RefType != TableRefType.OneToOne) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTrytb.Name} 导航属性不是【ManyToOne】或【OneToOne】"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + else + { + nvref.Columns.AddRange(trytbTf.RefColumns); + nvref.MiddleColumns.AddRange(trytbTf.Columns); + + if (tbmid.Primarys.Any() == false) + trytbTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true); + if (isLazy) + { + for (var a = 0; a < trytbTf.RefColumns.Count; a++) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("b.").Append(trytbTf.Columns[a].CsName).Append(" == this.").Append(trytbTf.RefColumns[a].CsName); + } + } + } + } + if (nvref.Exception == null) + { + var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; + + TableRef tbrefTf = null; + try + { + tbrefTf = tbmid.GetTableRef(midTypePropsTbref.Name, true); + if (tbrefTf == null) + { + AddTableRef(common, tbmid, midTypePropsTbref, false, null, null); + tbrefTf = tbmid.GetTableRef(midTypePropsTbref.Name, true); + } + } + catch (Exception ex) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTbref.Name} 错误:{ex.Message}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + if (nvref.Exception == null) + { + if (tbrefTf.RefType != TableRefType.ManyToOne && tbrefTf.RefType != TableRefType.OneToOne) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTbref.Name} 导航属性不是【ManyToOne】或【OneToOne】"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + else + { + nvref.RefColumns.AddRange(tbrefTf.RefColumns); + nvref.MiddleColumns.AddRange(tbrefTf.Columns); + + if (tbmid.Primarys.Any() == false) + tbrefTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true); + + if (isLazy) + { + for (var a = 0; a < tbrefTf.RefColumns.Count; a++) + lmbdWhere.Append(" && b.").Append(tbrefTf.Columns[a].CsName).Append(" == a.").Append(tbrefTf.RefColumns[a].CsName); + } + } + } + } + #endregion + } + else + { + #region 约定配置 + for (var a = 0; a < trytb.Primarys.Length; a++) + { + var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); + if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); + if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}{findtrytbPkCsName}", out var trycol) == false && //骆峰命名 + tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTrytb.Name}_{findtrytbPkCsName}", out trycol) == false //下划线命名 + ) + { + + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType.NullableTypeOrThis()) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {trytb.CsName}.{trytb.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTrytb.Name}{findtrytbPkCsName}、{midTypePropsTrytb.Name}_{findtrytbPkCsName}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + + nvref.Columns.Add(trytb.Primarys[a]); + nvref.MiddleColumns.Add(trycol); + if (tbmid.Primarys.Any() == false) + trycol.Attribute.IsPrimary = true; + + if (isLazy) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("b.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); + } + } + + if (nvref.Exception == null) + { + var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value; + for (var a = 0; a < tbref.Primarys.Length; a++) + { + var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); + if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); + if (tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}{findtbrefPkCsName}", out var trycol) == false && //骆峰命名 + tbmid.ColumnsByCs.TryGetValue($"{midTypePropsTbref.Name}_{findtbrefPkCsName}", out trycol) == false //下划线命名 + ) + { + + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType.NullableTypeOrThis()) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{tbmid.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbmid.CsName} 中没有找到对应的字段,如:{midTypePropsTbref.Name}{findtbrefPkCsName}、{midTypePropsTbref.Name}_{findtbrefPkCsName}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + + nvref.RefColumns.Add(tbref.Primarys[a]); + nvref.MiddleColumns.Add(trycol); + if (tbmid.Primarys.Any() == false) + trycol.Attribute.IsPrimary = true; + + if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); + } + } + #endregion + } + if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) + { + nvref.RefMiddleEntityType = tbmid.Type; + nvref.RefEntityType = tbref.Type; + nvref.RefType = TableRefType.ManyToMany; + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + + if (tbmid.Primarys.Any() == false) + tbmid.Primarys = tbmid.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + } + + if (isLazy) + { + cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + if (vp?.Item2 == true) + { //get 重写 + cscode.Append(" get {\r\n") + .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); + + if (nvref.Exception == null) + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}") + .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") + .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); + else + cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); + + cscode.Append(" }\r\n") + .Append(" return base.").Append(pnv.Name).AppendLine(";") + .Append(" }\r\n"); + } + if (vp?.Item3 == true) + { //set 重写 + cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); + } + cscode.AppendLine(" }"); + } + } + else + { //One To Many + List bindColumns = new List(); + if (pnvBind != null) + { + foreach (var bi in pnvBind) + { + if (tbref.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {tbrefTypeName} 未找到属性:{bi}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + bindColumns.Add(trybindcol); + } + } + + PropertyInfo refprop = null; + var refcols = tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type); + refprop = refcols.Count() == 1 ? refcols.First().Value : null; + var lmbdWhere = isLazy ? new StringBuilder() : null; + + if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != trytb.Primarys.Length) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 内部主键数目({trytb.Primarys.Length}) 不相同"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + if (trytb.Primarys.Length > 1) + { + if (trytb.Primarys.Select(a => a.CsType.NullableTypeOrThis()).Distinct().Count() == trytb.Primarys.Length) + { + var pkList = trytb.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == b.CsType.NullableTypeOrThis()))); + } + else if (string.Compare(string.Join(",", trytb.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) + { + var pkList = trytb.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => string.Compare(c.CsName, a.CsName, true) == 0).CompareTo(pkList.FindIndex(c => string.Compare(c.CsName, b.CsName, true) == 0))); + } + } + for (var a = 0; nvref.Exception == null && a < trytb.Primarys.Length; a++) + { + var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); + if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_'); + var findtrytb = pnv.Name; + if (findtrytb.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase)) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1); + findtrytb += trytb.CsName; + + var trycol = bindColumns.Any() ? bindColumns[a] : null; + if (trycol == null && + tbref.ColumnsByCs.TryGetValue($"{findtrytb}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 + tbref.ColumnsByCs.TryGetValue($"{findtrytb}_{findtrytbPkCsName}", out trycol) == false //下划线命名 + ) + { + if (refprop != null && + tbref.ColumnsByCs.TryGetValue($"{refprop.Name}{findtrytbPkCsName}", out trycol) == false && //骆峰命名 + tbref.ColumnsByCs.TryGetValue($"{refprop.Name}_{findtrytbPkCsName}", out trycol) == false) //下划线命名 + { + + } + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != trytb.Primarys[a].CsType.NullableTypeOrThis()) + { + nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trytb.Primarys[a].CsName} 和 {tbref.CsName}.{trycol.CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"【OneToMany】导航属性 {trytbTypeName}.{pnv.Name} 在 {tbref.CsName} 中没有找到对应的字段,如:{findtrytb}{findtrytbPkCsName}、{findtrytb}_{findtrytbPkCsName}" + (refprop == null ? "" : $"、{refprop.Name}{findtrytbPkCsName}、{refprop.Name}_{findtrytbPkCsName}。或者使用 [Navigate] 特性指定关系映射。")); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + + nvref.Columns.Add(trytb.Primarys[a]); + nvref.RefColumns.Add(trycol); + + if (isLazy && nvref.Exception == null) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("a.").Append(trycol.CsName).Append(" == this.").Append(trytb.Primarys[a].CsName); + + if (refprop == null) + { //加载成功后,把列表对应的导航属性值设置为 this,比如 Select().ToOne().Topics 下的 TopicType 属性值全部为 this + var findtrytbName = trycol.CsName; + if (findtrytbName.EndsWith(trytb.Primarys.First().CsName)) + { + findtrytbName = findtrytbName.Remove(findtrytbName.Length - trytb.Primarys.First().CsName.Length).TrimEnd('_'); + if (tbref.Properties.TryGetValue(findtrytbName, out refprop) && refprop.PropertyType != trytb.Type) + refprop = null; + } + } + } + } + if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) + { + nvref.RefEntityType = tbref.Type; + nvref.RefType = TableRefType.OneToMany; + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + } + + if (isLazy) + { + cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + if (vp?.Item2 == true) + { //get 重写 + cscode.Append(" get {\r\n") + .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); + + if (nvref.Exception == null) + { + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace?.NotNullAndConcat(".")}{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace?.NotNullAndConcat(".")}{propElementType.Name}").Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();"); + if (refprop != null) + { + cscode.Append(" foreach (var loc1 in base.").Append(pnv.Name).AppendLine(")") + .Append(" loc1.").Append(refprop.Name).AppendLine(" = this;") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); + } + } + else + cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); + + cscode + .Append(" }\r\n") + .Append(" return base.").Append(pnv.Name).AppendLine(";") + .Append(" }\r\n"); + } + if (vp?.Item3 == true) + { //set 重写 + cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); + } + cscode.AppendLine(" }"); + } + } + } + else + { //一对一、多对一 + var tbref = pnv.PropertyType == trytb.Type ? trytb : GetTableByEntity(pnv.PropertyType, common); //可能是父子关系 + if (tbref == null) return; + if (tbref.Primarys.Any() == false) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {propTypeName} 缺少主键标识,[Column(IsPrimary = true)]"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}"; + var isOnoToOne = pnv.PropertyType != trytb.Type && + tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type).Any() && + tbref.Primarys.Length == trytb.Primarys.Length && + string.Join(",", tbref.Primarys.Select(a => a.CsType.NullableTypeOrThis().FullName).OrderBy(a => a)) == string.Join(",", trytb.Primarys.Select(a => a.CsType.NullableTypeOrThis().FullName).OrderBy(a => a)); + + List bindColumns = new List(); + if (pnvBind != null) + { + foreach (var bi in pnvBind) + { + if (trytb.ColumnsByCs.TryGetValue(bi, out var trybindcol) == false) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] 解析错误,在 {trytbTypeName} 未找到属性:{bi}"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + bindColumns.Add(trybindcol); + } + } + var lmbdWhere = new StringBuilder(); + + if (nvref.Exception == null && bindColumns.Any() && bindColumns.Count != tbref.Primarys.Length) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 特性 [Navigate] Bind 数目({bindColumns.Count}) 与 外部主键数目({tbref.Primarys.Length}) 不相同"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + } + if (tbref.Primarys.Length > 1) + { + if (tbref.Primarys.Select(a => a.CsType.NullableTypeOrThis()).Distinct().Count() == tbref.Primarys.Length) + { + var pkList = tbref.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == a.CsType.NullableTypeOrThis()).CompareTo(pkList.FindIndex(c => c.CsType.NullableTypeOrThis() == b.CsType.NullableTypeOrThis()))); + } + else if (string.Compare(string.Join(",", tbref.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) + { + var pkList = tbref.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => string.Compare(c.CsName, a.CsName, true) == 0).CompareTo(pkList.FindIndex(c => string.Compare(c.CsName, b.CsName, true) == 0))); + } + } + for (var a = 0; nvref.Exception == null && a < tbref.Primarys.Length; a++) + { + var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); + if (findtbrefPkCsName.StartsWith(tbref.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtbrefPkCsName = findtbrefPkCsName.Substring(tbref.Type.Name.Length).TrimStart('_'); + + var trycol = bindColumns.Any() ? bindColumns[a] : null; + if (trycol == null && + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}{findtbrefPkCsName}", out trycol) == false && //骆峰命名 + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_{findtbrefPkCsName}", out trycol) == false && //下划线命名 + //tbref.Primarys.Length == 1 && + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}_Id", out trycol) == false && + trytb.ColumnsByCs.TryGetValue($"{pnv.Name}Id", out trycol) == false + ) + { + //一对一,主键与主键查找 + if (isOnoToOne) + { + var trytbpks = trytb.Primarys.Where(z => z.CsType.NullableTypeOrThis() == tbref.Primarys[a].CsType.NullableTypeOrThis()); //一对一,按类型 + if (trytbpks.Count() == 1) trycol = trytbpks.First(); + else + { + trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, tbref.Primarys[a].CsName, true) == 0); //一对一,按主键名相同 + if (trytbpks.Count() == 1) trycol = trytbpks.First(); + else + { + trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, $"{tbref.CsName}{tbref.Primarys[a].CsName}", true) == 0); //一对一,主键名 = 表+主键名 + if (trytbpks.Count() == 1) trycol = trytbpks.First(); + else + { + trytbpks = trytb.Primarys.Where(z => string.Compare(z.CsName, $"{tbref.CsName}_{tbref.Primarys[a].CsName}", true) == 0); //一对一,主键名 = 表+_主键名 + if (trytbpks.Count() == 1) trycol = trytbpks.First(); + } + } + } + } + } + if (trycol != null && trycol.CsType.NullableTypeOrThis() != tbref.Primarys[a].CsType.NullableTypeOrThis()) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,{trytb.CsName}.{trycol.CsName} 和 {tbref.CsName}.{tbref.Primarys[a].CsName} 类型不一致"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + if (trycol == null) + { + nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 没有找到对应的字段,如:{pnv.Name}{findtbrefPkCsName}、{pnv.Name}_{findtbrefPkCsName}。或者使用 [Navigate] 特性指定关系映射。"); + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + //if (isLazy) throw nvref.Exception; + break; + } + + nvref.Columns.Add(trycol); + nvref.RefColumns.Add(tbref.Primarys[a]); + + if (isLazy && nvref.Exception == null) + { + if (a > 0) lmbdWhere.Append(" && "); + lmbdWhere.Append("a.").Append(tbref.Primarys[a].CsName).Append(" == this.").Append(trycol.CsName); + } + } + if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0) + { + nvref.RefEntityType = tbref.Type; + nvref.RefType = isOnoToOne ? TableRefType.OneToOne : TableRefType.ManyToOne; + trytb.AddOrUpdateTableRef(pnv.Name, nvref); + } + + if (isLazy) + { + cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + if (vp?.Item2 == true) + { //get 重写 + cscode.Append(" get {\r\n") + .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); + + if (nvref.Exception == null) + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propTypeName).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToOne();") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); + else + cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");"); + + cscode + .Append(" }\r\n") + .Append(" return base.").Append(pnv.Name).AppendLine(";") + .Append(" }\r\n"); + } + if (vp?.Item3 == true) + { //set 重写 + cscode.Append(" set {\r\n") + .Append(" base.").Append(pnv.Name).AppendLine(" = value;") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;") + .Append(" }\r\n"); + } + cscode.AppendLine(" }"); + } + } + } static Lazy MethodLazyLoadingComplier = new Lazy(() => { var type = Type.GetType("FreeSql.Extensions.LazyLoading.LazyLoadingComplier,FreeSql.Extensions.LazyLoading"); From 4d2406aa1e2342772b0a21e6a0f280409f439e1d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 1 Sep 2019 18:13:34 +0800 Subject: [PATCH 0115/1029] v0.9.4 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index e9f55e4b..0095e65f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.3 + 0.9.4 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ce7f4ac6..8b4906a8 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 5ef66980..29dd2004 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4e869f59..8f90cc48 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.3 + 0.9.4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2a1f44fb..c96eb335 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 51c2fba8..0043e1df 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7988997d..d2367b6e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b6fa0531..ade11155 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0afc8bbf..38f16fe4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index ef6729d4..a3ea81bb 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 40e646c1..ae73e66f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.3 + 0.9.4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 6e75a8cebc97debaa3d2d6c0d7bed1d7033d8379 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 4 Sep 2019 22:52:05 +0800 Subject: [PATCH 0116/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=A1=A8=E6=97=B6=E6=8C=87=E5=AE=9A=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=EF=BC=8C=E5=A6=82=EF=BC=9A[Column(Position?= =?UTF-8?q?=20=3D=201]=EF=BC=8C=E5=8F=AF=E4=B8=BA=E8=B4=9F=E6=95=B0?= =?UTF-8?q?=E5=8D=B3=E5=8F=8D=E6=96=B9=E5=90=91=E4=BD=8D=E7=BD=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseEntity.cs | 1 + .../BaseEntityReadOnly.cs | 4 +++ FreeSql/DataAnnotations/ColumnAttribute.cs | 14 +++++++++- FreeSql/DataAnnotations/ColumnFluent.cs | 23 +++++++++++++--- FreeSql/FreeSql.xml | 26 ++++++++++++++++++- FreeSql/Internal/CommonUtils.cs | 3 +++ FreeSql/Internal/Model/TableInfo.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 5 ++++ .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 10 +++---- .../OracleCodeFirst.cs | 14 +++++----- .../PostgreSQLCodeFirst.cs | 14 +++++----- .../SqlServerCodeFirst.cs | 14 +++++----- .../SqliteCodeFirst.cs | 10 +++---- 13 files changed, 103 insertions(+), 36 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index 213fb038..fa8f9669 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -30,6 +30,7 @@ namespace FreeSql /// /// 主键 /// + [Column(Position = 1)] public virtual TKey Id { get; set; } /// diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 21d35c1f..365ae1b0 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -42,18 +42,22 @@ namespace FreeSql /// /// 创建时间 /// + [Column(Position = -4)] public DateTime CreateTime { get; set; } /// /// 更新时间 /// + [Column(Position = -3)] public DateTime UpdateTime { get; set; } /// /// 逻辑删除 /// + [Column(Position = -2)] public bool IsDeleted { get; set; } /// /// 排序 /// + [Column(Position = -1)] public int Sort { get; set; } /// diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index dc2300e2..11a2d1c1 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -79,5 +79,17 @@ namespace FreeSql.DataAnnotations /// 类型映射,比如:可将 enum 属性映射成 typeof(string) /// public Type MapType { get; set; } - } + + internal short? _Position; + /// + /// 创建表时字段位置,规则如下: + /// + /// >0时排前面,1,2,3... + /// + /// =0时排中间(默认) + /// + /// <0时排后面,...-3,-2,-1 + /// + public short Position { get => _Position ?? 0; set => _Position = value; } +} } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index 67b3d885..bd731374 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -89,11 +89,28 @@ namespace FreeSql.DataAnnotations /// /// 类型映射,比如:可将 enum 属性映射成 typeof(string) /// - /// + /// /// - public ColumnFluent MapType(Type type) + public ColumnFluent MapType(Type value) { - _column.MapType = type; + _column.MapType = value; + return this; + } + + /// + /// 创建表时字段位置,规则如下: + /// + /// >0时排前面 + /// + /// =0时排中间(默认) + /// + /// <0时排后面 + /// + /// + /// + public ColumnFluent Position(short value) + { + _column.Position = value; return this; } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index dc1ed173..37ba8ffe 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -59,6 +59,17 @@ 类型映射,比如:可将 enum 属性映射成 typeof(string) + + + 创建表时字段位置,规则如下: + + >0时排前面,1,2,3... + + =0时排中间(默认) + + <0时排后面,...-3,-2,-1 + + 数据库列名 @@ -110,7 +121,20 @@ 类型映射,比如:可将 enum 属性映射成 typeof(string) - + + + + + + 创建表时字段位置,规则如下: + + >0时排前面 + + =0时排中间(默认) + + <0时排后面 + + diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 39aa7f7a..84c90381 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -126,6 +126,7 @@ namespace FreeSql.Internal if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion; if (trycol._Uniques != null) attr._Uniques = trycol._Uniques; if (trycol.MapType != null) attr.MapType = trycol.MapType; + if (trycol._Position != null) attr._Position = trycol.Position; if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue; } var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); @@ -143,6 +144,7 @@ namespace FreeSql.Internal if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion; if (tryattr._Uniques != null) attr._Uniques = tryattr._Uniques; if (tryattr.MapType != null) attr.MapType = tryattr.MapType; + if (tryattr._Position != null) attr._Position = tryattr.Position; if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue; } ColumnAttribute ret = null; @@ -156,6 +158,7 @@ namespace FreeSql.Internal if (attr._IsVersion != null) ret = attr; if (attr._Uniques != null) ret = attr; if (attr.MapType != null) ret = attr; + if (attr._Position != null) ret = attr; if (attr.DbDefautValue != null) ret = attr; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index d1b5bb90..1e1b3da8 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -14,6 +14,7 @@ namespace FreeSql.Internal.Model public Dictionary Columns { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public Dictionary ColumnsByCs { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public Dictionary ColumnsByCsIgnore { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public ColumnInfo[] ColumnsByPosition { get; set; } public ColumnInfo[] Primarys { get; set; } public Dictionary> Uniques { get; set; } public string CsName { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index d4a2cc21..e1c23f47 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -70,6 +70,7 @@ namespace FreeSql.Internal var propsLazy = new List<(PropertyInfo, bool, bool)>(); var propsNavObjs = new List(); var propsComment = CommonUtils.GetProperyCommentBySummary(entity); + var columnsList = new List(); foreach (var p in trytb.Properties.Values) { var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); @@ -169,6 +170,7 @@ namespace FreeSql.Internal trytb.Columns.Add(colattr.Name, col); trytb.ColumnsByCs.Add(p.Name, col); + columnsList.Add(col); } trytb.VersionColumn = trytb.Columns.Values.Where(a => a.Attribute.IsVersion == true).LastOrDefault(); if (trytb.VersionColumn != null) @@ -241,6 +243,9 @@ namespace FreeSql.Internal } var allunique = trytb.Columns.Values.Where(a => a.Attribute._Uniques != null).SelectMany(a => a.Attribute._Uniques).Distinct(); trytb.Uniques = allunique.ToDictionary(a => a, a => trytb.Columns.Values.Where(b => b.Attribute._Uniques != null && b.Attribute._Uniques.Contains(a)).ToList()); + trytb.ColumnsByPosition = columnsList.Where(a => a.Attribute.Position > 0).OrderBy(a => a.Attribute.Position) + .Concat(columnsList.Where(a => a.Attribute.Position == 0)) + .Concat(columnsList.Where(a => a.Attribute.Position < 0).OrderBy(a => a.Attribute.Position)).ToArray(); tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index f4c5acc0..ae762748 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -132,7 +132,7 @@ namespace FreeSql.MySql { //创建表 sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); @@ -197,7 +197,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); if (istmpatler == false) { var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql("select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || @@ -263,7 +263,7 @@ where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbna var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); //创建临时表 sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); @@ -286,10 +286,10 @@ where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbna sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) Engine=InnoDB;\r\n"); sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { var insertvalue = "NULL"; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index daf4d3f4..51901c67 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -110,7 +110,7 @@ namespace FreeSql.Oracle { //创建表 sb.Append("execute immediate 'CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); @@ -131,7 +131,7 @@ namespace FreeSql.Oracle sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); //备注 - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); @@ -182,7 +182,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (istmpatler == false) { - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || @@ -264,7 +264,7 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); //创建临时表 sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); @@ -285,16 +285,16 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); //备注 - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { var insertvalue = "NULL"; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 78742220..6678ba40 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -151,7 +151,7 @@ namespace FreeSql.PostgreSQL { //创建表 sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); @@ -171,7 +171,7 @@ namespace FreeSql.PostgreSQL sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); //备注 - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); @@ -242,7 +242,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); if (istmpatler == false) { - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) @@ -311,7 +311,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); //创建临时表 sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); @@ -331,16 +331,16 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); //备注 - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { var insertvalue = "NULL"; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index ea78f7f4..e0b0d18d 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -162,7 +162,7 @@ ELSE //创建新表 sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(" ( "); var pkidx = 0; - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); @@ -188,7 +188,7 @@ ELSE } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); //备注 - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); @@ -242,7 +242,7 @@ use " + database, tboldname ?? tbname); if (istmpatler == false) { - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) @@ -321,7 +321,7 @@ use " + database, tboldname ?? tbname); //创建临时表 sb.Append("CREATE TABLE ").Append(tmptablename).Append(" ( "); var pkidx2 = 0; - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); @@ -348,7 +348,7 @@ use " + database, tboldname ?? tbname); } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); //备注 - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); @@ -357,10 +357,10 @@ use " + database, tboldname ?? tbname); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append(")\r\n\t\tSELECT "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { var insertvalue = "NULL"; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 85d684d4..7ab66263 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -100,7 +100,7 @@ namespace FreeSql.Sqlite { //创建表 sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); @@ -163,7 +163,7 @@ namespace FreeSql.Sqlite if (istmpatler == false) { - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || @@ -217,7 +217,7 @@ namespace FreeSql.Sqlite //创建表 isIndent = false; sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); sb.Append(tbcol.Attribute.DbType); @@ -243,10 +243,10 @@ namespace FreeSql.Sqlite sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) \r\n;\r\n"); sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.Columns.Values) + foreach (var tbcol in tb.ColumnsByPosition) { var insertvalue = "NULL"; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || From 6d9f15372c51cd89ee26f964563ae5af99bb28ee Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 4 Sep 2019 22:58:59 +0800 Subject: [PATCH 0117/1029] v0.9.5 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 0095e65f..06aca8d5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.4 + 0.9.5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 8b4906a8..0f24dc52 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 29dd2004..6133a39a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8f90cc48..8fb6c2de 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.4 + 0.9.5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c96eb335..d93d5d56 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0043e1df..fb7534c9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d2367b6e..852de259 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ade11155..581b6f93 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 38f16fe4..bf8cc06c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a3ea81bb..88f9381c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ae73e66f..d5930c85 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.4 + 0.9.5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 39558e6ecc5246049fee87700aa153031cc417f6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Sep 2019 15:37:08 +0800 Subject: [PATCH 0118/1029] update test --- FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 4 ++++ FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs | 4 ++++ .../FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs | 5 +++++ .../FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs | 3 +++ 4 files changed, 16 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 123f782e..35f7e27d 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -214,6 +214,10 @@ namespace FreeSql.Tests.MySql testFieldUShortNullable = ushort.MinValue, testFielLongNullable = long.MinValue }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 9dcd8f9d..a7ccc99a 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -192,6 +192,10 @@ namespace FreeSql.Tests.Oracle UShortNullable = ushort.MinValue, testFielLongNullable = long.MinValue }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index d8471901..8b330b37 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -338,6 +338,11 @@ namespace FreeSql.Tests.PostgreSQL testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 }, testFielLongNullable = long.MinValue }; + + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); + var item3 = insert.AppendData(item2).ExecuteInserted().First(); var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index e5d79172..f4ec916e 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -164,6 +164,9 @@ namespace FreeSql.Tests.SqlServer var sqlPar = insert.AppendData(item2).ToSql(); var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); + + var sqlTestUpdate = g.sqlserver.Update().SetSource(item3NP).NoneParameter().ToSql(); var item3 = insert.AppendData(item2).ExecuteInserted(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); From d51aef2aa96b3d55a21ea659fb05509134f8b514 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Sep 2019 13:29:15 +0800 Subject: [PATCH 0119/1029] add test --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 6 ++++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 13 +++++++------ FreeSql/Internal/CommonExpression.cs | 5 +++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index efc884c6..3df650fb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -405,6 +405,12 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var floorSql = g.sqlite.Select().Where(a => a.OptionsEntity04 / 10000 == 121212 / 10000).ToSql(); + + var testBoolSql1 = g.sqlserver.Select().Where(a => a.OptionsEntity01).ToSql(); + var testBoolSql2 = g.sqlserver.Select().Where(a => a.Id == Guid.NewGuid() && a.OptionsEntity01).ToSql(); + + IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=7") .UseEntityPropertyNameConvert(Internal.StringConvertType.PascalCaseToUnderscoreWithLower) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 1c145a27..4611cd89 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -28,13 +28,14 @@ public static partial class FreeSqlGlobalExtensions [typeof(uint?)] = true, [typeof(ulong)] = true, [typeof(ulong?)] = true, - [typeof(double)] = true, - [typeof(double?)] = true, - [typeof(float)] = true, - [typeof(float?)] = true, - [typeof(decimal)] = true, - [typeof(decimal?)] = true + [typeof(double)] = false, + [typeof(double?)] = false, + [typeof(float)] = false, + [typeof(float?)] = false, + [typeof(decimal)] = false, + [typeof(decimal?)] = false }); + public static bool IsIntegerType(this Type that) => that == null ? false : (dicIsNumberType.Value.TryGetValue(that, out var tryval) ? tryval : false); public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that); public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true; public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 63ab1906..6e54b362 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -387,6 +387,7 @@ namespace FreeSql.Internal static ConcurrentDictionary _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary(); static MethodInfo MethodDateTimeSubtractDateTime = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(DateTime) }); static MethodInfo MethodDateTimeSubtractTimeSpan = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(TimeSpan) }); + static MethodInfo MethodMathFloor = typeof(Math).GetMethod("Floor", new Type[] { typeof(double) }); static string GetBoolString(string sql) { @@ -489,6 +490,10 @@ namespace FreeSql.Internal break; } tsc.mapType = null; + //switch(oper) + //{ + // case "/": return ExpressionLambdaToSqlCallMath(Expression.Call(MethodMathFloor, Expression.Constant(1213.1d, typeof(double))), tsc)?.Replace("1213.1", $"{left} {oper} {right}"); + //} return $"{left} {oper} {right}"; } public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) From d105041858363b20706443f83e49841cc0b1f104 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Sep 2019 14:48:37 +0800 Subject: [PATCH 0120/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E5=AF=B9=E6=95=B4=E6=95=B0=E9=99=A4=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=EF=BC=8C=E8=A7=A3=E6=9E=90=E4=B8=BA?= =?UTF-8?q?=E6=95=B4=E9=99=A4=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnectorExpression/OtherTest.cs | 16 ++++++++++++++++ .../MySql/MySqlExpression/OtherTest.cs | 16 ++++++++++++++++ .../Oracle/OracleExpression/OtherTest.cs | 16 ++++++++++++++++ .../PostgreSQL/PostgreSQLExpression/OtherTest.cs | 16 ++++++++++++++++ .../SqlServer/SqlServerExpression/OtherTest.cs | 16 ++++++++++++++++ .../Sqlite/SqliteExpression/OtherTest.cs | 16 ++++++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 3 ++- FreeSql/Internal/CommonExpression.cs | 7 +++---- FreeSql/Internal/CommonUtils.cs | 1 + Providers/FreeSql.Provider.MySql/MySqlUtils.cs | 3 ++- .../MySqlConnectorUtils.cs | 3 ++- Providers/FreeSql.Provider.Oracle/OracleUtils.cs | 1 + .../PostgreSQLUtils.cs | 1 + .../FreeSql.Provider.SqlServer/SqlServerUtils.cs | 1 + Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs | 1 + 15 files changed, 110 insertions(+), 7 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs index 8fc9d3eb..361c2c67 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs @@ -17,6 +17,22 @@ namespace FreeSql.Tests.MySqlConnectorExpression } + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + [Fact] public void Boolean() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs index 44345f68..83c2c2be 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs @@ -17,6 +17,22 @@ namespace FreeSql.Tests.MySqlExpression } + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + [Fact] public void Boolean() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs index 512c1441..ed6a76d7 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs @@ -15,6 +15,22 @@ namespace FreeSql.Tests.OracleExpression { } + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + [Fact] public void Boolean() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index 6a31499a..d1bbdd0d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -24,6 +24,22 @@ namespace FreeSql.Tests.PostgreSQLExpression NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); } + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + [Fact] public void Boolean() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs index ef10ff43..53427c37 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs @@ -20,6 +20,22 @@ namespace FreeSql.Tests.SqlServerExpression ISelect select => _sqlserverFixture.SqlServer.Select(); + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + [Fact] public void Boolean() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs index 020d405b..3e2c3e53 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs @@ -15,6 +15,22 @@ namespace FreeSql.Tests.SqliteExpression { } + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + [Fact] public void Boolean() { diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 3df650fb..a2b00e45 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -405,7 +405,8 @@ namespace FreeSql.Tests [Fact] public void Test1() { - var floorSql = g.sqlite.Select().Where(a => a.OptionsEntity04 / 10000 == 121212 / 10000).ToSql(); + var floorSql1 = g.mysql.Select().Where(a => a.OptionsEntity04 / 10000 == 121212 / 10000).ToSql(); + var floorSql2 = g.mysql.Select().Where(a => a.OptionsEntity04 / 10000.0 == 121212 / 10000).ToSql(); var testBoolSql1 = g.sqlserver.Select().Where(a => a.OptionsEntity01).ToSql(); var testBoolSql2 = g.sqlserver.Select().Where(a => a.Id == Guid.NewGuid() && a.OptionsEntity01).ToSql(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6e54b362..deada8a9 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -483,6 +483,9 @@ namespace FreeSql.Internal switch (oper) { case "%": return _common.Mod(left, right, leftExp.Type, rightExp.Type); + case "/": + if (leftExp.Type.IsIntegerType() && rightExp.Type.IsIntegerType()) return _common.Div(left, right, leftExp.Type, rightExp.Type); + break; case "AND": case "OR": left = GetBoolString(left); @@ -490,10 +493,6 @@ namespace FreeSql.Internal break; } tsc.mapType = null; - //switch(oper) - //{ - // case "/": return ExpressionLambdaToSqlCallMath(Expression.Call(MethodMathFloor, Expression.Constant(1213.1d, typeof(double))), tsc)?.Replace("1213.1", $"{left} {oper} {right}"); - //} return $"{left} {oper} {right}"; } public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 84c90381..a1bce7e8 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -32,6 +32,7 @@ namespace FreeSql.Internal public abstract string IsNull(string sql, object value); public abstract string StringConcat(string[] objs, Type[] types); public abstract string Mod(string left, string right, Type leftType, Type rightType); + public abstract string Div(string left, string right, Type leftType, Type rightType); public abstract string QuoteWriteParamter(Type type, string paramterName); public abstract string QuoteReadColumn(Type type, string columnName); diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index d2b75c78..52804544 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -74,6 +74,8 @@ namespace FreeSql.MySql public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} div {right}"; + public override string QuoteWriteParamter(Type type, string paramterName) { switch (type.FullName) @@ -87,7 +89,6 @@ namespace FreeSql.MySql } return paramterName; } - public override string QuoteReadColumn(Type type, string columnName) { switch (type.FullName) diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 05a8374f..f5646853 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -82,6 +82,8 @@ namespace FreeSql.MySql public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} div {right}"; + public override string QuoteWriteParamter(Type type, string paramterName) { switch (type.FullName) @@ -95,7 +97,6 @@ namespace FreeSql.MySql } return paramterName; } - public override string QuoteReadColumn(Type type, string columnName) { switch (type.FullName) diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index c9deb887..48a835a7 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -64,6 +64,7 @@ namespace FreeSql.Oracle public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left} / {right})"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 3069d618..7f0ed104 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -126,6 +126,7 @@ namespace FreeSql.PostgreSQL public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 5bef8a09..da59f6e0 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -66,6 +66,7 @@ namespace FreeSql.SqlServer return string.Join(" + ", news); } public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 0ce0b722..f861c6c6 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -79,6 +79,7 @@ namespace FreeSql.Sqlite public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; From d9cb932fae9002927084af8b34383a4c78f06348 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Sep 2019 16:07:28 +0800 Subject: [PATCH 0121/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20MapType=20Da?= =?UTF-8?q?teTime/DateTimeOffset=20=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E4=BA=92=E9=80=9A=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MapType/DateTimeOffSetTest.cs | 54 +++++++++++++++++++ .../MySql/MapType/DateTimeOffSetTest.cs | 54 +++++++++++++++++++ .../Oracle/MapType/DateTimeOffSetTest.cs | 54 +++++++++++++++++++ .../PostgreSQL/MapType/DateTimeOffSetTest.cs | 54 +++++++++++++++++++ .../SqlServer/MapType/DateTimeOffSetTest.cs | 54 +++++++++++++++++++ .../Sqlite/MapType/DateTimeOffSetTest.cs | 54 +++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 14 ++++- 7 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Oracle/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/DateTimeOffSetTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..91fb979a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MySqlConnectorMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.mysql; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..38fa8965 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MySqlMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.mysql; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..01b38345 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.OracleMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.oracle; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..53cf8548 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.PostgreSQLMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.pgsql; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..0c5455fa --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.SqlServerMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.sqlserver; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..d3b466dc --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.SqliteMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.sqlite; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index e1c23f47..e747b13d 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1457,6 +1457,8 @@ namespace FreeSql.Internal static MethodInfo MethodDateTimeOffsetTryParse = typeof(DateTimeOffset).GetMethod("TryParse", new[] { typeof(string), typeof(DateTimeOffset).MakeByRefType() }); static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null); static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); + static PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", BindingFlags.Instance | BindingFlags.Public); + static ConstructorInfo CtorDateTimeOffsetArgsDateTime = typeof(DateTimeOffset).GetConstructor(new[] { typeof(DateTime) }); public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) @@ -1752,14 +1754,22 @@ namespace FreeSql.Internal var defaultRetExp = type == typeof(string) ? Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))) : Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); - + return Expression.IfThenElse( Expression.TypeEqual(valueExp, type), Expression.Return(returnTarget, valueExp), Expression.IfThenElse( Expression.TypeEqual(valueExp, typeof(string)), switchExp, - defaultRetExp + Expression.IfThenElse( + Expression.AndAlso(Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(DateTime))), Expression.TypeEqual(valueExp, typeof(DateTimeOffset))), + Expression.Return(returnTarget, Expression.Convert(Expression.MakeMemberAccess(Expression.Convert(valueExp, typeof(DateTimeOffset)), PropertyDateTimeOffsetDateTime), typeof(object))), + Expression.IfThenElse( + Expression.AndAlso(Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(DateTimeOffset))), Expression.TypeEqual(valueExp, typeof(DateTime))), + Expression.Return(returnTarget, Expression.Convert(Expression.New(CtorDateTimeOffsetArgsDateTime, Expression.Convert(valueExp, typeof(DateTime))), typeof(object))), + defaultRetExp + ) + ) ) ); }; From 85595941ed34f6bba3bcc73123c6d7f91b6ac423 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Sep 2019 16:14:07 +0800 Subject: [PATCH 0122/1029] ## v0.9.6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 优化 表达式对整数除法的处理,解析为整除 #85; - 优化 MapType DateTime/DateTimeOffset 类型转换互通 #87; --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 06aca8d5..3c13c9a6 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.5 + 0.9.6 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0f24dc52..f54ae8ee 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6133a39a..fb452c6a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8fb6c2de..46115c6f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.5 + 0.9.6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index d93d5d56..b757b61d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index fb7534c9..1dc5260c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 852de259..63c00ba0 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 581b6f93..20eb90f5 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index bf8cc06c..4fa51a4a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 88f9381c..1912f94e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index d5930c85..41076be0 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.5 + 0.9.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 2855af3a43f50b2cc495716ed84407490be8a9c9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Sep 2019 16:16:36 +0800 Subject: [PATCH 0123/1029] update test --- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 6 +++--- FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs | 6 +++--- FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index c89f2c76..1a2242ab 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -112,20 +112,20 @@ namespace FreeSql.Tests.MySqlConnector Assert.Equal("UPDATE `tb_topic` SET `Title` = @p_0, `CreateTime` = @p_1 WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 div 1 WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); int incrv = 10; sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 div 1 WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 / 1 WHERE (`Id` = 1)", sql); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 div 1 WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index a1f6758a..381df6fa 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -113,20 +113,20 @@ namespace FreeSql.Tests.MySql Assert.Equal("UPDATE `tb_topic` SET `Title` = ?p_0, `CreateTime` = ?p_1 WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 div 1 WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); int incrv = 10; sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 / 1 WHERE (`Id` = 1)", sql); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 div 1 WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 / 1 WHERE (`Id` = 1)", sql); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 div 1 WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 22f204aa..11b061be 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -70,20 +70,20 @@ namespace FreeSql.Tests.Oracle Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = :p_0, \"CREATETIME\" = :p_1 WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = nvl(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); int incrv = 10; sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = nvl(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = \"CLICKS\" * 10 / 1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10 / 1) WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); From a266cdb10303c2fc003efdb64064a37640d6fd5f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Sep 2019 17:42:25 +0800 Subject: [PATCH 0124/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E3=80=90?= =?UTF-8?q?=E9=87=8D=E5=A4=A7=20bug=E3=80=91=20=E6=89=B9=E9=87=8F=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=20bug=EF=BC=8C=E5=BD=93=E5=AD=97=E6=AE=B5=E4=B8=AD?= =?UTF-8?q?=E6=9F=90=E4=B8=AA=E5=80=BC=E4=B8=BA=20null=EF=BC=8C=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E5=AD=97=E6=AE=B5=E4=B9=9F=E6=9B=B4=E6=96=B0=E6=88=90?= =?UTF-8?q?=E4=BA=86=20NULL=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 1 + .../FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs | 1 + .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 2 ++ .../Oracle/Curd/OracleUpdateTest.cs | 1 + .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 1 + .../SqlServer/Curd/SqlServerUpdateTest.cs | 1 + .../Sqlite/Curd/SqliteUpdateTest.cs | 1 + .../Internal/CommonProvider/UpdateProvider.cs | 16 ++++++++-------- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 1a2242ab..050e8e22 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -46,6 +46,7 @@ namespace FreeSql.Tests.MySqlConnector var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; sql = update.SetSource(items).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, `Title` = CASE `Id` WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, `CreateTime` = CASE `Id` WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 381df6fa..7d42b257 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -47,6 +47,7 @@ namespace FreeSql.Tests.MySql var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; sql = update.SetSource(items).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN ?p_0 WHEN 2 THEN ?p_1 WHEN 3 THEN ?p_2 WHEN 4 THEN ?p_3 WHEN 5 THEN ?p_4 WHEN 6 THEN ?p_5 WHEN 7 THEN ?p_6 WHEN 8 THEN ?p_7 WHEN 9 THEN ?p_8 WHEN 10 THEN ?p_9 END, `Title` = CASE `Id` WHEN 1 THEN ?p_10 WHEN 2 THEN ?p_11 WHEN 3 THEN ?p_12 WHEN 4 THEN ?p_13 WHEN 5 THEN ?p_14 WHEN 6 THEN ?p_15 WHEN 7 THEN ?p_16 WHEN 8 THEN ?p_17 WHEN 9 THEN ?p_18 WHEN 10 THEN ?p_19 END, `CreateTime` = CASE `Id` WHEN 1 THEN ?p_20 WHEN 2 THEN ?p_21 WHEN 3 THEN ?p_22 WHEN 4 THEN ?p_23 WHEN 5 THEN ?p_24 WHEN 6 THEN ?p_25 WHEN 7 THEN ?p_26 WHEN 8 THEN ?p_27 WHEN 9 THEN ?p_28 WHEN 10 THEN ?p_29 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 35f7e27d..a3017d2d 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -218,6 +218,8 @@ namespace FreeSql.Tests.MySql var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + var enumConvInt = select.Where(a => a.Id == (int)TableAllTypeEnumType1.e1).ToSql(); + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 11b061be..0f374c2b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -38,6 +38,7 @@ namespace FreeSql.Tests.Oracle var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; sql = update.SetSource(items).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN :p_0 WHEN 2 THEN :p_1 WHEN 3 THEN :p_2 WHEN 4 THEN :p_3 WHEN 5 THEN :p_4 WHEN 6 THEN :p_5 WHEN 7 THEN :p_6 WHEN 8 THEN :p_7 WHEN 9 THEN :p_8 WHEN 10 THEN :p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN :p_10 WHEN 2 THEN :p_11 WHEN 3 THEN :p_12 WHEN 4 THEN :p_13 WHEN 5 THEN :p_14 WHEN 6 THEN :p_15 WHEN 7 THEN :p_16 WHEN 8 THEN :p_17 WHEN 9 THEN :p_18 WHEN 10 THEN :p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN :p_20 WHEN 2 THEN :p_21 WHEN 3 THEN :p_22 WHEN 4 THEN :p_23 WHEN 5 THEN :p_24 WHEN 6 THEN :p_25 WHEN 7 THEN :p_26 WHEN 8 THEN :p_27 WHEN 9 THEN :p_28 WHEN 10 THEN :p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index ff270d94..7d7104d0 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -39,6 +39,7 @@ namespace FreeSql.Tests.PostgreSQL var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; sql = update.SetSource(items).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = CASE \"id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"title\" = CASE \"id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"createtime\" = CASE \"id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 88ad4cb0..2c2cfc31 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -50,6 +50,7 @@ namespace FreeSql.Tests.SqlServer var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, [Title] = CASE [Id] WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, [CreateTime] = CASE [Id] WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index e6c74398..136a4eb3 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -40,6 +40,7 @@ namespace FreeSql.Tests.Sqlite var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"Title\" = CASE \"Id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CreateTime\" = CASE \"Id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index ce358480..de0e6930 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -576,7 +576,7 @@ namespace FreeSql.Internal.CommonProvider var sb = new StringBuilder(); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - var isnull = false; + var nulls = 0; var cwsb = new StringBuilder().Append(cw); foreach (var d in _source) { @@ -585,11 +585,11 @@ namespace FreeSql.Internal.CommonProvider cwsb.Append(" THEN "); var value = col.GetMapValue(d); cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value))); - if (isnull == false) isnull = value == null || value == DBNull.Value; + if (value == null || value == DBNull.Value) nulls++; } cwsb.Append(" END"); - if (isnull == false) sb.Append(cwsb.ToString()); - else sb.Append("NULL"); + if (nulls == _source.Count) sb.Append("NULL"); + else sb.Append(cwsb.ToString()); cwsb.Clear(); return sb.ToString(); @@ -669,7 +669,7 @@ namespace FreeSql.Internal.CommonProvider if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - var isnull = false; + var nulls = 0; var cwsb = new StringBuilder().Append(cw); foreach (var d in _source) { @@ -684,15 +684,15 @@ namespace FreeSql.Internal.CommonProvider cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, val); } - if (isnull == false) isnull = val == null || val == DBNull.Value; + if (val == null || val == DBNull.Value) nulls++; } cwsb.Append(" END"); - if (isnull == false) + if (nulls == _source.Count) sb.Append("NULL"); + else { ToSqlCaseWhenEnd(cwsb, col); sb.Append(cwsb.ToString()); } - else sb.Append("NULL"); cwsb.Clear(); ++colidx; From bb387fd7f09e95d74a7b1272843d44486b8117a0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Sep 2019 17:51:09 +0800 Subject: [PATCH 0125/1029] =?UTF-8?q?v0.9.7=E3=80=90=E9=87=8D=E5=A4=A7=20b?= =?UTF-8?q?ug=20=E6=9B=B4=E6=96=B0=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 3c13c9a6..1e10a29e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.6 + 0.9.7 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index f54ae8ee..aa765cdf 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index fb452c6a..ae1508fb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 46115c6f..62bf3ccf 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.6 + 0.9.7 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b757b61d..40e5a24e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 1dc5260c..93de1702 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 63c00ba0..abbb0246 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 20eb90f5..80a29725 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 4fa51a4a..4a1a2389 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 1912f94e..eb48a66a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 41076be0..f5805e81 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.6 + 0.9.7 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 415e09f0daaa61af34e5358a7b804624ec1b48a0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Sep 2019 19:07:32 +0800 Subject: [PATCH 0126/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20ExpressionTr?= =?UTF-8?q?ee=20DateTime/DateTimeOffset=20=E6=95=B0=E6=8D=AE=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E6=B5=8B=E8=AF=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GetDataReaderValueBlockExpressionTest.cs | 56 +++++++++++++++++++ .../MySql/MapType/DateTimeOffSetTest.cs | 10 +++- FreeSql/Internal/UtilsExpressionTree.cs | 5 +- 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs b/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs index 6ae782b5..ee4873c3 100644 --- a/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs @@ -418,6 +418,34 @@ namespace FreeSql.ExpressionTree Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), "aaa")); } + [Fact] + public void DateTime2_By_DateTimeOffset() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(DateTimeOffset.MinValue)); + Assert.Equal(DateTime.MinValue, Utils.GetDataReaderValue(typeof(DateTime), DateTimeOffset.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(DateTimeOffset.MaxValue)); + Assert.Equal(DateTime.MaxValue, Utils.GetDataReaderValue(typeof(DateTime), DateTimeOffset.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant("2000-1-1")); + Assert.Equal(DateTime.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTime), "2000-1-1")); + + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(DateTimeOffset.MinValue)); + Assert.Equal(DateTime.MinValue, Utils.GetDataReaderValue(typeof(DateTime?), DateTimeOffset.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(DateTimeOffset.MaxValue)); + Assert.Equal(DateTime.MaxValue, Utils.GetDataReaderValue(typeof(DateTime?), DateTimeOffset.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant("2000-1-1")); + Assert.Equal(DateTime.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTime?), "2000-1-1")); + + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(null)); + Assert.Equal(default(DateTime), Utils.GetDataReaderValue(typeof(DateTime), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant("aaa")); + Assert.Equal(default(DateTime), Utils.GetDataReaderValue(typeof(DateTime), "aaa")); + + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), "aaa")); + } + [Fact] public void DateTimeOffset2() { @@ -445,5 +473,33 @@ namespace FreeSql.ExpressionTree var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("aaa")); Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), "aaa")); } + + [Fact] + public void DateTimeOffset2_By_DateTime() + { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(DateTime.MinValue)); + Assert.Equal(DateTimeOffset.MinValue, Utils.GetDataReaderValue(typeof(DateTimeOffset), DateTime.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(DateTime.MaxValue)); + Assert.Equal(DateTimeOffset.MaxValue, Utils.GetDataReaderValue(typeof(DateTimeOffset), DateTime.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant("2000-1-1")); + Assert.Equal(DateTimeOffset.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTimeOffset), "2000-1-1")); + + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(DateTime.MinValue)); + Assert.Equal(DateTimeOffset.MinValue, Utils.GetDataReaderValue(typeof(DateTimeOffset?), DateTime.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(DateTime.MaxValue)); + Assert.Equal(DateTimeOffset.MaxValue, Utils.GetDataReaderValue(typeof(DateTimeOffset?), DateTime.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("2000-1-1")); + Assert.Equal(DateTimeOffset.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTimeOffset?), "2000-1-1")); + + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(null)); + Assert.Equal(default(DateTimeOffset), Utils.GetDataReaderValue(typeof(DateTimeOffset), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant("aaa")); + Assert.Equal(default(DateTimeOffset), Utils.GetDataReaderValue(typeof(DateTimeOffset), "aaa")); + + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), "aaa")); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs index 38fa8965..5f9e4c63 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs @@ -21,7 +21,7 @@ namespace FreeSql.Tests.MySqlMapType { //insert var orm = g.mysql; - var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); Assert.NotNull(find); @@ -38,6 +38,14 @@ namespace FreeSql.Tests.MySqlMapType Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + item.dtosnullable_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + //update set Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); find = orm.Select().Where(a => a.id == item.id).First(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index e747b13d..76dd4aaf 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1458,7 +1458,7 @@ namespace FreeSql.Internal static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null); static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); static PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", BindingFlags.Instance | BindingFlags.Public); - static ConstructorInfo CtorDateTimeOffsetArgsDateTime = typeof(DateTimeOffset).GetConstructor(new[] { typeof(DateTime) }); + static ConstructorInfo CtorDateTimeOffsetArgsDateTime = typeof(DateTimeOffset).GetConstructor(new[] { typeof(DateTime), typeof(TimeSpan) }); public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) @@ -1766,7 +1766,8 @@ namespace FreeSql.Internal Expression.Return(returnTarget, Expression.Convert(Expression.MakeMemberAccess(Expression.Convert(valueExp, typeof(DateTimeOffset)), PropertyDateTimeOffsetDateTime), typeof(object))), Expression.IfThenElse( Expression.AndAlso(Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(DateTimeOffset))), Expression.TypeEqual(valueExp, typeof(DateTime))), - Expression.Return(returnTarget, Expression.Convert(Expression.New(CtorDateTimeOffsetArgsDateTime, Expression.Convert(valueExp, typeof(DateTime))), typeof(object))), + Expression.Return(returnTarget, Expression.Convert( + Expression.New(CtorDateTimeOffsetArgsDateTime, Expression.Convert(valueExp, typeof(DateTime)), Expression.Constant(TimeSpan.Zero)), typeof(object))), defaultRetExp ) ) From 915af57baaab2b96e5905c58481ad1ac0660fef3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Sep 2019 15:11:25 +0800 Subject: [PATCH 0127/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=97=A0set=E8=87=AA=E5=8A=A8=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E7=9A=84bug=EF=BC=9B=20-=20=E4=BC=98=E5=8C=96=20ISelect`1.Incl?= =?UTF-8?q?ude=E4=B9=8B=E5=90=8EToList=E5=8F=82=E6=95=B0includeNestedMembe?= =?UTF-8?q?rs=E9=BB=98=E8=AE=A4=E4=B8=BAtrue=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 4 ++++ .../CommonProvider/SelectProvider/Select0Provider.cs | 4 ++-- .../CommonProvider/SelectProvider/Select1Provider.cs | 5 +++++ FreeSql/Internal/UtilsExpressionTree.cs | 5 +++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index a2b00e45..a8af4dc3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -405,6 +405,10 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var testincludeMemberssql1 = g.sqlite.Select().Where(a => a.Templates.Title == "1").ToList(); + var testincludeMemberssql2 = g.sqlite.Select().Include(a => a.Templates).ToList(); + + var floorSql1 = g.mysql.Select().Where(a => a.OptionsEntity04 / 10000 == 121212 / 10000).ToSql(); var floorSql2 = g.mysql.Select().Where(a => a.OptionsEntity04 / 10000.0 == 121212 / 10000).ToSql(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index fde203e8..225c04c5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -472,12 +472,12 @@ namespace FreeSql.Internal.CommonProvider return ToListAfPrivateAsync(sql, af, otherData); } - public List ToList(bool includeNestedMembers = false) + public virtual List ToList(bool includeNestedMembers = false) { if (_selectExpression != null) return this.InternalToList(_selectExpression); return this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); } - public Task> ToListAsync(bool includeNestedMembers = false) + public virtual Task> ToListAsync(bool includeNestedMembers = false) { if (_selectExpression != null) return this.InternalToListAsync(_selectExpression); return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 5f82840d..76f84598 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -384,6 +384,10 @@ namespace FreeSql.Internal.CommonProvider public TDto First() => this.ToOne(); public Task FirstAsync() => this.ToOneAsync(); + public override List ToList(bool includeNestedMembers = false) => base.ToList(_isIncluded || includeNestedMembers); + public override Task> ToListAsync(bool includeNestedMembers = false) => base.ToListAsync(_isIncluded || includeNestedMembers); + + bool _isIncluded = false; public ISelect Include(Expression> navigateSelector) where TNavigate : class { var expBody = navigateSelector?.Body; @@ -391,6 +395,7 @@ namespace FreeSql.Internal.CommonProvider var tb = _commonUtils.GetTableByEntity(expBody.Type); if (tb == null) throw new Exception("Include 参数类型错误"); + _isIncluded = true; _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null); return this; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 76dd4aaf..6d1b55c1 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -76,6 +76,11 @@ namespace FreeSql.Internal var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); var colattr = common.GetEntityColumnAttribute(entity, p); var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType); + if (setMethod == null) // 属性没有 set自动忽略 + { + if (colattr == null) colattr = new ColumnAttribute { IsIgnore = true }; + else colattr.IsIgnore = true; + } if (tp == null && colattr?.IsIgnore != true) { if (common.CodeFirst.IsLazyLoading) From ebec260d9747d370556902b81f31357c780ec276 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Sep 2019 15:20:57 +0800 Subject: [PATCH 0128/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20ExpressionTr?= =?UTF-8?q?ee=20=E4=BB=8E=20DateTime=20=E8=BD=AC=E5=8C=96=20DateTimeOffset?= =?UTF-8?q?=20=E4=BD=BF=E7=94=A8=20ticks=EF=BC=9B#87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/UtilsExpressionTree.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6d1b55c1..f3dbe11d 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1463,7 +1463,8 @@ namespace FreeSql.Internal static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null); static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); static PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", BindingFlags.Instance | BindingFlags.Public); - static ConstructorInfo CtorDateTimeOffsetArgsDateTime = typeof(DateTimeOffset).GetConstructor(new[] { typeof(DateTime), typeof(TimeSpan) }); + static PropertyInfo PropertyDateTimeTicks = typeof(DateTime).GetProperty("Ticks", BindingFlags.Instance | BindingFlags.Public); + static ConstructorInfo CtorDateTimeOffsetArgsTicks = typeof(DateTimeOffset).GetConstructor(new[] { typeof(long), typeof(TimeSpan) }); public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) @@ -1772,7 +1773,7 @@ namespace FreeSql.Internal Expression.IfThenElse( Expression.AndAlso(Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(DateTimeOffset))), Expression.TypeEqual(valueExp, typeof(DateTime))), Expression.Return(returnTarget, Expression.Convert( - Expression.New(CtorDateTimeOffsetArgsDateTime, Expression.Convert(valueExp, typeof(DateTime)), Expression.Constant(TimeSpan.Zero)), typeof(object))), + Expression.New(CtorDateTimeOffsetArgsTicks, Expression.MakeMemberAccess(Expression.Convert(valueExp, typeof(DateTime)), PropertyDateTimeTicks), Expression.Constant(TimeSpan.Zero)), typeof(object))), defaultRetExp ) ) From bcc154ee4337b339af90ba9bec0472eac9846f12 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Sep 2019 18:30:55 +0800 Subject: [PATCH 0129/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20AsTable=20?= =?UTF-8?q?=E5=A4=9A=E6=AC=A1=EF=BC=8C=E5=8F=AF=E6=9F=A5=E8=AF=A2=E5=88=86?= =?UTF-8?q?=E8=A1=A8=E5=90=8E=E7=9A=84=E5=A4=9A=E4=B8=AA=E5=AD=90=E8=A1=A8?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=EF=BC=8C=E4=BB=A5=20UNION=20ALL=20=E5=BD=A2?= =?UTF-8?q?=E5=BC=8F=E6=89=A7=E8=A1=8C=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ExpressionTree/GetAllTableRuleTest.cs | 34 ++ .../MySql/MapType/DateTimeOffSetTest.cs | 6 +- .../Sqlite/Curd/SqliteSelectTest.cs | 16 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 3 + FreeSql/FreeSql.xml | 9 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 9 +- .../SelectProvider/Select0Provider.cs | 12 +- FreeSql/Internal/CommonUtils.cs | 31 ++ .../Curd/MySqlSelect.cs | 144 +++---- .../Curd/OracleSelect.cs | 172 +++++---- .../Curd/PostgreSQLSelect.cs | 148 ++++---- .../Curd/SqlServerSelect.cs | 356 +++++++++--------- .../Curd/SqliteSelect.cs | 144 +++---- 13 files changed, 620 insertions(+), 464 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetAllTableRuleTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetAllTableRuleTest.cs b/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetAllTableRuleTest.cs new file mode 100644 index 00000000..dcc5f640 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetAllTableRuleTest.cs @@ -0,0 +1,34 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +using FreeSql.Internal; +using System.Linq.Expressions; +using FreeSql.Internal.Model; + +namespace FreeSql.ExpressionTree +{ + public class GetAllTableRuleTest + { + + [Fact] + public void Test() + { + //var _tables = new List + //{ + // [0] = new SelectTableInfo { } + //}; + //var tableRuleInvoke = new Func((type, oldname) => + //{ + // return new[] { oldname }; + //}); + + //CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs index 5f9e4c63..6c17e72d 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MapType/DateTimeOffSetTest.cs @@ -13,7 +13,7 @@ namespace FreeSql.Tests.MySqlMapType [Column(MapType = typeof(DateTime))] public DateTimeOffset dtos_to_dt { get; set; } - [Column(MapType = typeof(DateTime))] + [Column(MapType = typeof(DateTime?))] public DateTimeOffset? dtosnullable_to_dt { get; set; } } [Fact] @@ -27,7 +27,7 @@ namespace FreeSql.Tests.MySqlMapType Assert.NotNull(find); Assert.Equal(item.id, find.id); Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); - Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt, find.dtosnullable_to_dt); //update all item.dtos_to_dt = DateTimeOffset.Now; @@ -36,7 +36,7 @@ namespace FreeSql.Tests.MySqlMapType Assert.NotNull(find); Assert.Equal(item.id, find.id); Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); - Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt, find.dtosnullable_to_dt); item.dtosnullable_to_dt = DateTimeOffset.Now; Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 45e0f362..22f92795 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -790,10 +790,22 @@ namespace FreeSql.Tests.Sqlite else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; return oldname + "AsTable"; }; + Func tableRule2 = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "Test2"; + else if (type == typeof(TestTypeInfo)) return oldname + "Test2"; + return oldname + "Test2"; + }; + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule).AsTable(tableRule2); + var sql = query.ToSql(); + + query = select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3"); + sql = query.ToSql(a => a.Id); + //����е�������a.Type��a.Type.Parent ���ǵ������� - var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); - var sql = query.ToSql().Replace("\r\n", ""); + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a__Type.\"Guid\", a__Type.\"ParentId\", a__Type.\"Name\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfoAsTable2\" a__Type ON a__Type.\"Guid\" = a.\"TypeGuid\"", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index a8af4dc3..4f95cf07 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -297,6 +297,7 @@ namespace FreeSql.Tests public bool OptionsEntity02 { get; set; } = false; public bool OptionsEntity03 { get; set; } = false; public int OptionsEntity04 { get; set; } + public int? score { get; set; } [Navigate("TbId")] public virtual ICollection Builds { get; set; } @@ -405,6 +406,8 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var testorderbysql = g.mysql.Select().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql(); + var testincludeMemberssql1 = g.sqlite.Select().Where(a => a.Templates.Title == "1").ToList(); var testincludeMemberssql2 = g.sqlite.Select().Include(a => a.Templates).ToList(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 37ba8ffe..140f0f0d 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -809,7 +809,14 @@ - 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + 设置后可查询分表后的多个子表记录,以 UNION ALL 形式执行。 + 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); + select * from (SELECT a."Id" as1 FROM "table_1" a) ftb + UNION ALL + select * from (SELECT a."Id" as1 FROM "table_2" a) ftb + UNION ALL + select * from (SELECT a."Id" as1 FROM "table_3" a) ftb diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 09350041..9cef1fde 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -68,7 +68,14 @@ namespace FreeSql Task FirstAsync(); /// - /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + /// 设置后可查询分表后的多个子表记录,以 UNION ALL 形式执行。 + /// 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); + /// select * from (SELECT a."Id" as1 FROM "table_1" a) ftb + /// UNION ALL + /// select * from (SELECT a."Id" as1 FROM "table_2" a) ftb + /// UNION ALL + /// select * from (SELECT a."Id" as1 FROM "table_3" a) ftb /// /// /// diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 225c04c5..4cc1da5b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -906,14 +906,16 @@ namespace FreeSql.Internal.CommonProvider return (map, field.ToString()); } - protected string TableRuleInvoke(Type type, string oldname) + protected string[] TableRuleInvoke(Type type, string oldname) { - for (var a = _tableRules.Count - 1; a >= 0; a--) + List newnames = new List(); + foreach (var tr in _tableRules) { - var newname = _tableRules[a]?.Invoke(type, oldname); - if (!string.IsNullOrEmpty(newname)) return newname; + var newname = tr?.Invoke(type, oldname); + if (!string.IsNullOrEmpty(newname)) newnames.Add(newname); } - return oldname; + if (newnames.Any() == false) return new[] { oldname }; + return newnames.Distinct().ToArray(); } public TSelect AsTable(Func tableRule) diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index a1bce7e8..034d3e45 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -363,5 +363,36 @@ namespace FreeSql.Internal } while (initConns.TryTake(out var conn)) pool.Return(conn); } + + public static List> GetAllTableRule(List _tables, Func tableRuleInvoke) + { + var tableRuleSorted = new List<(Type, string[])>(); + var tableRuleDict = new Dictionary(); + foreach(var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (tableRuleDict.ContainsKey(tb.Table.Type)) continue; + var names = tableRuleInvoke(tb.Table.Type, tb.Table.DbName); + tableRuleSorted.Add((tb.Table.Type, names)); + tableRuleDict.Add(tb.Table.Type, true); + } + var tableRules = new List>(); + tableRules.Add(tableRuleSorted.Select(a => (a.Item1, a.Item2.First())).ToDictionary(a => a.Item1, a => a.Item2)); + for (var z = tableRuleSorted.Count - 1; z >=0; z--) + { + var tbrd = tableRuleSorted[z]; + var curpos = tableRules.Count; + for (var a = 1; a < tbrd.Item2.Length; a++) + { + for (var b = 0; b < curpos; b++) + { + var tr = new Dictionary(); + foreach (var oldtd in tableRules[b]) tr.Add(oldtd.Key, tbrd.Item1 == oldtd.Key ? tbrd.Item2[a] : oldtd.Value); + tableRules.Add(tr); + } + } + } + return tableRules; + } } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index 6c5557ba..68cf90b9 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.MySql.Curd class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -22,85 +22,95 @@ namespace FreeSql.MySql.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field).Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) + var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); + var tbrulesGt0 = tbrules.Count > 1; + for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) + if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbrulesGt0) sb.Append("select * from ("); + var tbrule = tbrules[tbrulesIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) + sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); - else + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } + break; } - break; + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); } - else + foreach (var tb in tbsjoin) { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_skip > 0 || _limit > 0) + sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); - sbnav.Append(_where); - if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + sbnav.Clear(); + if (tbrulesGt0) sb.Append(") ftb"); } - if (sbnav.Length > 0) - { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) - { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); - if (_skip > 0 || _limit > 0) - sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); - - sbnav.Clear(); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 14911f36..a2d6904c 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Oracle.Curd class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -22,97 +22,107 @@ namespace FreeSql.Oracle.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field); - if (string.IsNullOrEmpty(_orderby) && _skip > 0) sb.Append(", ROWNUM AS \"__rownum__\""); - sb.Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) + var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); + var tbrulesGt0 = tbrules.Count > 1; + for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) - { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) - { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); + if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbrulesGt0) sb.Append("select * from ("); + var tbrule = tbrules[tbrulesIdx]; - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); - else + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field); + if (string.IsNullOrEmpty(_orderby) && _skip > 0) sb.Append(", ROWNUM AS \"__rownum__\""); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } + break; } - break; + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) + sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); + if (sbnav.Length > 0) + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + + if (string.IsNullOrEmpty(_orderby)) + { + if (_skip > 0) + sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); } else { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (_skip > 0 && _limit > 0) sb.Insert(0, "SELECT t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + else if (_skip > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); + else if (_limit > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) - { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); - sbnav.Append(_where); - if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + sbnav.Clear(); + if (tbrulesGt0) sb.Append(") ftb"); } - if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) - sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); - if (sbnav.Length > 0) - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - if (string.IsNullOrEmpty(_groupby) == false) - { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); - - if (string.IsNullOrEmpty(_orderby)) - { - if (_skip > 0) - sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); - } - else - { - if (_skip > 0 && _limit > 0) sb.Insert(0, "SELECT t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); - else if (_skip > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); - else if (_limit > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); - } - - sbnav.Clear(); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 21d9eca8..77672c61 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.PostgreSQL.Curd class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -22,87 +22,97 @@ namespace FreeSql.PostgreSQL.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field).Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) + var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); + var tbrulesGt0 = tbrules.Count > 1; + for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) + if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbrulesGt0) sb.Append("select * from ("); + var tbrule = tbrules[tbrulesIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) + sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); - else + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } + break; } - break; + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); } - else + foreach (var tb in tbsjoin) { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_limit > 0) + sb.Append(" \r\nlimit ").Append(_limit); + if (_skip > 0) + sb.Append(" \r\noffset ").Append(_skip); - sbnav.Append(_where); - if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + sbnav.Clear(); + if (tbrulesGt0) sb.Append(") ftb"); } - if (sbnav.Length > 0) - { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) - { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); - if (_limit > 0) - sb.Append(" \r\nlimit ").Append(_limit); - if (_skip > 0) - sb.Append(" \r\noffset ").Append(_skip); - - sbnav.Clear(); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 4228689a..620bc333 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -12,13 +12,13 @@ namespace FreeSql.SqlServer.Curd class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _whereCascadeExpression, _orm) : ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _whereCascadeExpression, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -28,104 +28,114 @@ namespace FreeSql.SqlServer.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); - sb.Append(field); - if (_skip > 0) + var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); + var tbrulesGt0 = tbrules.Count > 1; + for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) { - if (string.IsNullOrEmpty(_orderby)) + if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbrulesGt0) sb.Append("select * from ("); + var tbrule = tbrules[tbrulesIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); + sb.Append(field); + if (_skip > 0) { - var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); - if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); - else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); - } - sb.Append(", ROW_NUMBER() OVER(").Append(_orderby).Append(") AS __rownum__"); - } - sb.Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) - { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) - { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) + if (string.IsNullOrEmpty(_orderby)) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); - else - { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); - } + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); } - break; + sb.Append(", ROW_NUMBER() OVER(").Append(_orderby).Append(") AS __rownum__"); } + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip <= 0) + sb.Append(_orderby); else - { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); - } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) - { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); - sbnav.Append(_where); - if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + sbnav.Clear(); + if (tbrulesGt0) sb.Append(") ftb"); } - if (sbnav.Length > 0) - { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) - { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - if (_skip <= 0) - sb.Append(_orderby); - else - sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); - - sbnav.Clear(); return sb.ToString(); } #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -135,99 +145,109 @@ namespace FreeSql.SqlServer.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); - sb.Append(field); - sb.Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) + var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); + var tbrulesGt0 = tbrules.Count > 1; + for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) + if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbrulesGt0) sb.Append("select * from ("); + var tbrule = tbrules[tbrulesIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); + sb.Append(field); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) + sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); - else + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } + break; } - break; + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip > 0) + { + if (string.IsNullOrEmpty(_orderby)) + { + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); + } + sb.Append(_orderby).Append($" \r\nOFFSET {_skip} ROW"); + if (_limit > 0) sb.Append($" \r\nFETCH NEXT {_limit} ROW ONLY"); } else { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + sb.Append(_orderby); } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) - { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); - sbnav.Append(_where); - if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + sbnav.Clear(); + if (tbrulesGt0) sb.Append(") ftb"); } - if (sbnav.Length > 0) - { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) - { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - if (_skip > 0) - { - if (string.IsNullOrEmpty(_orderby)) - { - var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); - if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); - else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); - } - sb.Append(_orderby).Append($" \r\nOFFSET {_skip} ROW"); - if (_limit > 0) sb.Append($" \r\nFETCH NEXT {_limit} ROW ONLY"); - } - else - { - sb.Append(_orderby); - } - - sbnav.Clear(); return sb.ToString(); } #endregion diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index 20b2e833..463c593f 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Sqlite.Curd class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -22,85 +22,95 @@ namespace FreeSql.Sqlite.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var sbnav = new StringBuilder(); - sb.Append(_select); - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field).Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) + var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); + var tbrulesGt0 = tbrules.Count > 1; + for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) { - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias); - if (tbsjoin.Length > 0) + if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbrulesGt0) sb.Append("select * from ("); + var tbrule = tbrules[tbrulesIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) + sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias); - - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); - else + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } + break; } - break; + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); } - else + foreach (var tb in tbsjoin) { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); } - sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_skip > 0 || _limit > 0) + sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); - sbnav.Append(_where); - if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + sbnav.Clear(); + if (tbrulesGt0) sb.Append(") ftb"); } - if (sbnav.Length > 0) - { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) - { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); - if (_skip > 0 || _limit > 0) - sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); - - sbnav.Clear(); return sb.ToString(); } From 527303eede7873c63196584634bb645f6f1a5ed5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Sep 2019 18:32:22 +0800 Subject: [PATCH 0130/1029] v0.9.9 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1e10a29e..bfb0c92c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.7 + 0.9.8 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index aa765cdf..47da7323 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ae1508fb..c56195bc 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 62bf3ccf..3206a9a9 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.7 + 0.9.8 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 40e5a24e..589813d3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 93de1702..75694840 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index abbb0246..d0990a35 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 80a29725..a88907fe 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 4a1a2389..b4e2b588 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index eb48a66a..71663769 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f5805e81..9bea4f31 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.7 + 0.9.8 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From fe4874989c39a3f5e03a36384ac7cefe35a8a45a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Sep 2019 19:02:38 +0800 Subject: [PATCH 0131/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20AsTable=20?= =?UTF-8?q?=E4=B8=8D=E5=8F=97=20UseSyncStructureToLower/ToUpper=20?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=9A=84=20bug=EF=BC=9B#89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Oracle/Curd/OracleDeleteTest.cs | 8 +- .../Oracle/Curd/OracleInsertTest.cs | 142 +++++++++--------- .../Oracle/Curd/OracleSelectTest.cs | 22 +-- .../Oracle/Curd/OracleUpdateTest.cs | 8 +- .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 8 +- .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 16 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 22 +-- .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 8 +- .../Internal/CommonProvider/DeleteProvider.cs | 14 +- .../Internal/CommonProvider/InsertProvider.cs | 14 +- .../SelectProvider/Select0Provider.cs | 7 +- .../Internal/CommonProvider/UpdateProvider.cs | 14 +- .../Curd/OracleInsert.cs | 2 +- 13 files changed, 163 insertions(+), 122 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs index 881c176c..807d1c97 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs @@ -83,16 +83,16 @@ namespace FreeSql.Tests.Oracle { Assert.Null(g.oracle.Delete().ToSql()); var sql = g.oracle.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); sql = g.oracle.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"ID\" = 1)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs index ceaca63c..6f0bff0f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs @@ -202,104 +202,104 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_9) for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks_0, :Title_0, :CreateTime_0)", sql); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(:Clicks_0, :Title_0, :CreateTime_0)", sql); sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_0, :Title_0, :CreateTime_0) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_1, :Title_1, :CreateTime_1) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_2, :Title_2, :CreateTime_2) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_3, :Title_3, :CreateTime_3) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_4, :Title_4, :CreateTime_4) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_5, :Title_5, :CreateTime_5) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_6, :Title_6, :CreateTime_6) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_7, :Title_7, :CreateTime_7) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_8, :Title_8, :CreateTime_8) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_9, :Title_9, :CreateTime_9) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_0, :Title_0, :CreateTime_0) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_1, :Title_1, :CreateTime_1) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_2, :Title_2, :CreateTime_2) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_3, :Title_3, :CreateTime_3) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_4, :Title_4, :CreateTime_4) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_5, :Title_5, :CreateTime_5) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_6, :Title_6, :CreateTime_6) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_7, :Title_7, :CreateTime_7) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_8, :Title_8, :CreateTime_8) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(:Clicks_9, :Title_9, :CreateTime_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_0) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_1) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_2) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_3) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_4) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_5) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_6) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_7) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_8) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_9) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_0) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_1) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_2) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_3) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_4) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_5) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_6) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_7) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_8) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_0) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_1) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_2) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_3) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_4) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_5) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_6) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_7) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_8) -INTO ""Topic_InsertAsTable""(""TITLE"") VALUES(:Title_9) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_0) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_1) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_2) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_3) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_4) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_5) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_6) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_7) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_8) +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES(:Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) -INTO ""Topic_InsertAsTable""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_0, :Title_0) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_1, :Title_1) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_2, :Title_2) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_3, :Title_3) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_4, :Title_4) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_5, :Title_5) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_6, :Title_6) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_7, :Title_7) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_8, :Title_8) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(:Clicks_9, :Title_9) SELECT 1 FROM DUAL", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); Assert.Equal(@"INSERT ALL -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_0) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_1) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_2) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_3) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_4) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_5) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_6) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_7) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_8) -INTO ""Topic_InsertAsTable""(""CLICKS"") VALUES(:Clicks_9) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_0) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_1) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_2) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_3) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_4) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_5) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_6) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_7) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_8) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") VALUES(:Clicks_9) SELECT 1 FROM DUAL", sql); } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index a0a7a1a1..137ddcc7 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -829,57 +829,57 @@ namespace FreeSql.Tests.Oracle //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); //���û�е������� query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); //������� query = select .LeftJoin(a => a.Type.Guid == a.TypeGuid) .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); query = select .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); //���û�е�������b��c������ϵ var query2 = select.From((s, b, c) => s .LeftJoin(a => a.TypeGuid == b.Guid) .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFOAsTable2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOAsTable\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON b.\"PARENTID\" = c.\"ID\"", sql); //������϶����㲻�� query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22AsTable1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); } public class TiOtmModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 0f374c2b..05385ddd 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -133,10 +133,10 @@ namespace FreeSql.Tests.Oracle public void AsTable() { Assert.Null(g.oracle.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index 360024bc..4224dc32 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -82,16 +82,16 @@ namespace FreeSql.Tests.PostgreSQL { Assert.Null(g.pgsql.Delete().ToSql()); var sql = g.pgsql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1)", sql); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); sql = g.pgsql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"id\" = 1)", sql); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs index 536a2231..cb793719 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -114,28 +114,28 @@ namespace FreeSql.Tests.PostgreSQL for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"Topic_InsertAsTable\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index a898a01e..585e7335 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -903,57 +903,57 @@ namespace FreeSql.Tests.PostgreSQL //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); //���û�е������� query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON b.\"guid\" = a.\"typeguid\"", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON b.\"guid\" = a.\"typeguid\"", sql); query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); //������� query = select .LeftJoin(a => a.Type.Guid == a.TypeGuid) .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoAsTable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); query = select .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoAsTable\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoastable\" c ON c.\"id\" = a__Type.\"parentid\"", sql); //���û�е�������b��c������ϵ var query2 = select.From((s, b, c) => s .LeftJoin(a => a.TypeGuid == b.Guid) .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfoAsTable2\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfoAsTable\" c ON b.\"parentid\" = c.\"id\"", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfoastable\" c ON b.\"parentid\" = c.\"id\"", sql); //������϶����㲻�� query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicAsTable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 7d7104d0..f242ca7d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -138,10 +138,10 @@ namespace FreeSql.Tests.PostgreSQL public void AsTable() { Assert.Null(g.pgsql.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index e21168c1..5ef235c6 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -126,6 +126,18 @@ namespace FreeSql.Internal.CommonProvider public IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); public IDelete WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + protected string TableRuleInvoke() + { + if (_tableRule == null) return _table.DbName; + var newname = _tableRule(_table.DbName); + if (!string.IsNullOrEmpty(newname)) + { + if (_orm.CodeFirst.IsSyncStructureToLower) return newname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) return newname.ToUpper(); + return newname; + } + return _table.DbName; + } public IDelete AsTable(Func tableRule) { _tableRule = tableRule; @@ -141,6 +153,6 @@ namespace FreeSql.Internal.CommonProvider return this; } - public string ToSql() => _whereTimes <= 0 ? null : new StringBuilder().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append(" WHERE ").Append(_where).ToString(); + public string ToSql() => _whereTimes <= 0 ? null : new StringBuilder().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" WHERE ").Append(_where).ToString(); } } diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index b41e4cd3..991a4a95 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -548,6 +548,18 @@ namespace FreeSql.Internal.CommonProvider return this; } + protected string TableRuleInvoke() + { + if (_tableRule == null) return _table.DbName; + var newname = _tableRule(_table.DbName); + if (!string.IsNullOrEmpty(newname)) + { + if (_orm.CodeFirst.IsSyncStructureToLower) return newname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) return newname.ToUpper(); + return newname; + } + return _table.DbName; + } public IInsert AsTable(Func tableRule) { _tableRule = tableRule; @@ -567,7 +579,7 @@ namespace FreeSql.Internal.CommonProvider { if (_source == null || _source.Any() == false) return null; var sb = new StringBuilder(); - sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append("("); + sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("("); var colidx = 0; foreach (var col in _table.Columns.Values) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 4cc1da5b..abacddcf 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -912,7 +912,12 @@ namespace FreeSql.Internal.CommonProvider foreach (var tr in _tableRules) { var newname = tr?.Invoke(type, oldname); - if (!string.IsNullOrEmpty(newname)) newnames.Add(newname); + if (!string.IsNullOrEmpty(newname)) + { + if (_orm.CodeFirst.IsSyncStructureToLower) newnames.Add(newname.ToLower()); + else if (_orm.CodeFirst.IsSyncStructureToUpper) newnames.Add(newname.ToUpper()); + else newnames.Add(newname); + } } if (newnames.Any() == false) return new[] { oldname }; return newnames.Distinct().ToArray(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index de0e6930..78f39864 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -600,6 +600,18 @@ namespace FreeSql.Internal.CommonProvider protected abstract void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d); protected virtual void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) { } + protected string TableRuleInvoke() + { + if (_tableRule == null) return _table.DbName; + var newname = _tableRule(_table.DbName); + if (!string.IsNullOrEmpty(newname)) + { + if (_orm.CodeFirst.IsSyncStructureToLower) return newname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) return newname.ToUpper(); + return newname; + } + return _table.DbName; + } public IUpdate AsTable(Func tableRule) { _tableRule = tableRule; @@ -620,7 +632,7 @@ namespace FreeSql.Internal.CommonProvider if (_where.Length == 0 && _source.Any() == false) return null; var sb = new StringBuilder(); - sb.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append(" SET "); + sb.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" SET "); if (_set.Length > 0) { //指定 set 更新 diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 61f68ec6..345fc384 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -37,7 +37,7 @@ namespace FreeSql.Oracle.Curd _identCol = null; var sbtb = new StringBuilder(); sbtb.Append("INTO "); - sbtb.Append(_commonUtils.QuoteSqlName(_tableRule?.Invoke(_table.DbName) ?? _table.DbName)).Append("("); + sbtb.Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("("); var colidx = 0; foreach (var col in _table.Columns.Values) { From 7fcb2ed6019b148fdac42d1da095e08224f28613 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Sep 2019 19:04:20 +0800 Subject: [PATCH 0132/1029] v0.9.9 #89 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index bfb0c92c..c109f6cf 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.8 + 0.9.9 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 47da7323..3c521829 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index c56195bc..8e3d8d56 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3206a9a9..21d5df17 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.8 + 0.9.9 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 589813d3..6abb7a01 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 75694840..0532652f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d0990a35..1372db72 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a88907fe..202e3e5e 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b4e2b588..dd13d625 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 71663769..859f847b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9bea4f31..4273bd5a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.8 + 0.9.9 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From fa61d8a3d1b2a43788aadedd46477b9afe5020ff Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Sep 2019 09:26:08 +0800 Subject: [PATCH 0133/1029] =?UTF-8?q?-=20=E7=A7=BB=E9=99=A4=20FreeSql.Repo?= =?UTF-8?q?sitory=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=20FromRepository?= =?UTF-8?q?=EF=BC=9B=20-=20=E8=B0=83=E6=95=B4=20ISelect.AsTable=20?= =?UTF-8?q?=E8=A7=84=E5=88=99=EF=BC=8C=E6=AF=8F=E4=B8=80=E6=AC=A1=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=B0=86=E5=A2=9E=E5=8A=A0=20UNION=20ALL=20=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=EF=BC=9B=20-=20=E4=BC=98=E5=8C=96=20AsTable=20UseSync?= =?UTF-8?q?StructureToLower/ToUpper=20=E8=AE=BE=E7=BD=AE=EF=BC=8C=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=20AsTable((t,o)=20=3D>=20"(select=20*=20from=20tb)")?= =?UTF-8?q?=EF=BC=9B=20#89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 10 --- .../FreeSqlRepositoryExtenssions.cs | 28 ++++---- .../ExpressionTree/GetAllTableRuleTest.cs | 34 ---------- .../Sqlite/Curd/SqliteSelectTest.cs | 3 - FreeSql/FreeSql.xml | 9 ++- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 9 ++- .../Internal/CommonProvider/DeleteProvider.cs | 11 ++- .../Internal/CommonProvider/InsertProvider.cs | 11 ++- .../SelectProvider/Select0Provider.cs | 32 ++++++--- .../Internal/CommonProvider/UpdateProvider.cs | 11 ++- FreeSql/Internal/CommonUtils.cs | 31 --------- .../Curd/MySqlSelect.cs | 41 ++++++----- .../Curd/OracleSelect.cs | 41 ++++++----- .../Curd/PostgreSQLSelect.cs | 41 ++++++----- .../Curd/SqlServerSelect.cs | 68 +++++++++---------- .../Curd/SqliteSelect.cs | 41 ++++++----- 16 files changed, 168 insertions(+), 253 deletions(-) delete mode 100644 FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetAllTableRuleTest.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index e603c8d0..e0d4588c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -225,16 +225,6 @@ 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - - - 合并两个仓储的设置(过滤+分表),以便查询 - - - - - - - 创建基于仓储功能的工作单元,务必使用 using 包含使用 diff --git a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs index e34af18e..bafda690 100644 --- a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs +++ b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs @@ -44,20 +44,20 @@ public static class FreeSqlRepositoryExtenssions return new GuidRepository(that, filter, asTable); } - /// - /// 合并两个仓储的设置(过滤+分表),以便查询 - /// - /// - /// - /// - /// - /// - public static ISelect FromRepository(this ISelect that, BaseRepository repos) where TEntity : class where T2 : class - { - var filters = (repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) that.Where(filter.Value.Expression); - return that.AsTable(repos.AsTableSelectInternal); - } + ///// + ///// 合并两个仓储的设置(过滤+分表),以便查询 + ///// + ///// + ///// + ///// + ///// + ///// + //public static ISelect FromRepository(this ISelect that, BaseRepository repos) where TEntity : class where T2 : class + //{ + // var filters = (repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + // foreach (var filter in filters) that.Where(filter.Value.Expression); + // return that.AsTable(repos.AsTableSelectInternal); + //} /// /// 创建基于仓储功能的工作单元,务必使用 using 包含使用 diff --git a/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetAllTableRuleTest.cs b/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetAllTableRuleTest.cs deleted file mode 100644 index dcc5f640..00000000 --- a/FreeSql.Tests/FreeSql.Tests/ExpressionTree/GetAllTableRuleTest.cs +++ /dev/null @@ -1,34 +0,0 @@ -using FreeSql.DataAnnotations; -using FreeSql; -using System; -using System.Collections.Generic; -using Xunit; -using System.Linq; -using Newtonsoft.Json.Linq; -using NpgsqlTypes; -using Npgsql.LegacyPostgis; -using FreeSql.Internal; -using System.Linq.Expressions; -using FreeSql.Internal.Model; - -namespace FreeSql.ExpressionTree -{ - public class GetAllTableRuleTest - { - - [Fact] - public void Test() - { - //var _tables = new List - //{ - // [0] = new SelectTableInfo { } - //}; - //var tableRuleInvoke = new Func((type, oldname) => - //{ - // return new[] { oldname }; - //}); - - //CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); - } - } -} diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 22f92795..2ebc9a90 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -775,10 +775,7 @@ namespace FreeSql.Tests.Sqlite //reposTopic.Find(Guid.Empty); //reposTopic.Update(new Topic { TypeGuid = 1 }); var sql11 = reposTopic.Select - - .FromRepository(reposType) .From((s, b, c) => s) - .LeftJoin(a => a.TypeGuid == a.Type.Guid) .ToSql(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 140f0f0d..aeaf966c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -810,13 +810,12 @@ 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; - 设置后可查询分表后的多个子表记录,以 UNION ALL 形式执行。 + 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); select * from (SELECT a."Id" as1 FROM "table_1" a) ftb - UNION ALL - select * from (SELECT a."Id" as1 FROM "table_2" a) ftb - UNION ALL - select * from (SELECT a."Id" as1 FROM "table_3" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb + 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 9cef1fde..bc10a9ad 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -69,13 +69,12 @@ namespace FreeSql /// /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; - /// 设置后可查询分表后的多个子表记录,以 UNION ALL 形式执行。 + /// 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 /// 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); /// select * from (SELECT a."Id" as1 FROM "table_1" a) ftb - /// UNION ALL - /// select * from (SELECT a."Id" as1 FROM "table_2" a) ftb - /// UNION ALL - /// select * from (SELECT a."Id" as1 FROM "table_3" a) ftb + /// UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb + /// UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb + /// 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() /// /// /// diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 5ef235c6..8366cde9 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -130,13 +130,10 @@ namespace FreeSql.Internal.CommonProvider { if (_tableRule == null) return _table.DbName; var newname = _tableRule(_table.DbName); - if (!string.IsNullOrEmpty(newname)) - { - if (_orm.CodeFirst.IsSyncStructureToLower) return newname.ToLower(); - if (_orm.CodeFirst.IsSyncStructureToUpper) return newname.ToUpper(); - return newname; - } - return _table.DbName; + if (string.IsNullOrEmpty(newname)) return _table.DbName; + if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); + return newname; } public IDelete AsTable(Func tableRule) { diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 991a4a95..8247d3a5 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -552,13 +552,10 @@ namespace FreeSql.Internal.CommonProvider { if (_tableRule == null) return _table.DbName; var newname = _tableRule(_table.DbName); - if (!string.IsNullOrEmpty(newname)) - { - if (_orm.CodeFirst.IsSyncStructureToLower) return newname.ToLower(); - if (_orm.CodeFirst.IsSyncStructureToUpper) return newname.ToUpper(); - return newname; - } - return _table.DbName; + if (string.IsNullOrEmpty(newname)) return _table.DbName; + if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); + return newname; } public IInsert AsTable(Func tableRule) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index abacddcf..b5ce0b3c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -906,23 +906,33 @@ namespace FreeSql.Internal.CommonProvider return (map, field.ToString()); } - protected string[] TableRuleInvoke(Type type, string oldname) + protected List> GetTableRuleUnions() { - List newnames = new List(); - foreach (var tr in _tableRules) + var unions = new List>(); + var trs = _tableRules.Any() ? _tableRules : new List>(new[] { new Func((type, oldname) => oldname) }); + foreach (var tr in trs) { - var newname = tr?.Invoke(type, oldname); - if (!string.IsNullOrEmpty(newname)) + var dict = new Dictionary(); + foreach (var tb in _tables) { - if (_orm.CodeFirst.IsSyncStructureToLower) newnames.Add(newname.ToLower()); - else if (_orm.CodeFirst.IsSyncStructureToUpper) newnames.Add(newname.ToUpper()); - else newnames.Add(newname); + if (tb.Type == SelectTableInfoType.Parent) continue; + if (dict.ContainsKey(tb.Table.Type)) continue; + var name = tr?.Invoke(tb.Table.Type, tb.Table.DbName); + if (string.IsNullOrEmpty(name)) name = tb.Table.DbName; + else + { + if (name.IndexOf(' ') == -1) + { + if (_orm.CodeFirst.IsSyncStructureToLower) name = name.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) name = name.ToUpper(); + } + } + dict.Add(tb.Table.Type, name); } + unions.Add(dict); } - if (newnames.Any() == false) return new[] { oldname }; - return newnames.Distinct().ToArray(); + return unions; } - public TSelect AsTable(Func tableRule) { if (tableRule != null) _tableRules.Add(tableRule); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 78f39864..a4866392 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -604,13 +604,10 @@ namespace FreeSql.Internal.CommonProvider { if (_tableRule == null) return _table.DbName; var newname = _tableRule(_table.DbName); - if (!string.IsNullOrEmpty(newname)) - { - if (_orm.CodeFirst.IsSyncStructureToLower) return newname.ToLower(); - if (_orm.CodeFirst.IsSyncStructureToUpper) return newname.ToUpper(); - return newname; - } - return _table.DbName; + if (string.IsNullOrEmpty(newname)) return _table.DbName; + if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); + return newname; } public IUpdate AsTable(Func tableRule) { diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 034d3e45..a1bce7e8 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -363,36 +363,5 @@ namespace FreeSql.Internal } while (initConns.TryTake(out var conn)) pool.Return(conn); } - - public static List> GetAllTableRule(List _tables, Func tableRuleInvoke) - { - var tableRuleSorted = new List<(Type, string[])>(); - var tableRuleDict = new Dictionary(); - foreach(var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (tableRuleDict.ContainsKey(tb.Table.Type)) continue; - var names = tableRuleInvoke(tb.Table.Type, tb.Table.DbName); - tableRuleSorted.Add((tb.Table.Type, names)); - tableRuleDict.Add(tb.Table.Type, true); - } - var tableRules = new List>(); - tableRules.Add(tableRuleSorted.Select(a => (a.Item1, a.Item2.First())).ToDictionary(a => a.Item1, a => a.Item2)); - for (var z = tableRuleSorted.Count - 1; z >=0; z--) - { - var tbrd = tableRuleSorted[z]; - var curpos = tableRules.Count; - for (var a = 1; a < tbrd.Item2.Length; a++) - { - for (var b = 0; b < curpos; b++) - { - var tr = new Dictionary(); - foreach (var oldtd in tableRules[b]) tr.Add(oldtd.Key, tbrd.Item1 == oldtd.Key ? tbrd.Item2[a] : oldtd.Value); - tableRules.Add(tr); - } - } - } - return tableRules; - } } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index 68cf90b9..b0a3bd8c 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.MySql.Curd class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -22,13 +22,12 @@ namespace FreeSql.MySql.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); - var tbrulesGt0 = tbrules.Count > 1; - for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbrulesGt0) sb.Append("select * from ("); - var tbrule = tbrules[tbrulesIdx]; + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); sb.Append(_select); @@ -38,13 +37,13 @@ namespace FreeSql.MySql.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -78,7 +77,7 @@ namespace FreeSql.MySql.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -109,7 +108,7 @@ namespace FreeSql.MySql.Curd sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); sbnav.Clear(); - if (tbrulesGt0) sb.Append(") ftb"); + if (tbUnionsGt0) sb.Append(") ftb"); } return sb.ToString(); } @@ -124,51 +123,51 @@ namespace FreeSql.MySql.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index a2d6904c..517b14e3 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Oracle.Curd class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -22,13 +22,12 @@ namespace FreeSql.Oracle.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); - var tbrulesGt0 = tbrules.Count > 1; - for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbrulesGt0) sb.Append("select * from ("); - var tbrule = tbrules[tbrulesIdx]; + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); sb.Append(_select); @@ -40,13 +39,13 @@ namespace FreeSql.Oracle.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -80,7 +79,7 @@ namespace FreeSql.Oracle.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -121,7 +120,7 @@ namespace FreeSql.Oracle.Curd } sbnav.Clear(); - if (tbrulesGt0) sb.Append(") ftb"); + if (tbUnionsGt0) sb.Append(") ftb"); } return sb.ToString(); } @@ -136,51 +135,51 @@ namespace FreeSql.Oracle.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 77672c61..a170aa5c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.PostgreSQL.Curd class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -22,13 +22,12 @@ namespace FreeSql.PostgreSQL.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); - var tbrulesGt0 = tbrules.Count > 1; - for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbrulesGt0) sb.Append("select * from ("); - var tbrule = tbrules[tbrulesIdx]; + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); sb.Append(_select); @@ -38,13 +37,13 @@ namespace FreeSql.PostgreSQL.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -78,7 +77,7 @@ namespace FreeSql.PostgreSQL.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -111,7 +110,7 @@ namespace FreeSql.PostgreSQL.Curd sb.Append(" \r\noffset ").Append(_skip); sbnav.Clear(); - if (tbrulesGt0) sb.Append(") ftb"); + if (tbUnionsGt0) sb.Append(") ftb"); } return sb.ToString(); } @@ -126,51 +125,51 @@ namespace FreeSql.PostgreSQL.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 620bc333..ef13ba09 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -12,13 +12,13 @@ namespace FreeSql.SqlServer.Curd class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _whereCascadeExpression, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tableRuleInvoke, _whereCascadeExpression, _orm); + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _whereCascadeExpression, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _whereCascadeExpression, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -28,13 +28,12 @@ namespace FreeSql.SqlServer.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); - var tbrulesGt0 = tbrules.Count > 1; - for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbrulesGt0) sb.Append("select * from ("); - var tbrule = tbrules[tbrulesIdx]; + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); sb.Append(_select); @@ -56,13 +55,13 @@ namespace FreeSql.SqlServer.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -96,7 +95,7 @@ namespace FreeSql.SqlServer.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -128,14 +127,14 @@ namespace FreeSql.SqlServer.Curd sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); sbnav.Clear(); - if (tbrulesGt0) sb.Append(") ftb"); + if (tbUnionsGt0) sb.Append(") ftb"); } return sb.ToString(); } #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -145,13 +144,12 @@ namespace FreeSql.SqlServer.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); - var tbrulesGt0 = tbrules.Count > 1; - for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbrulesGt0) sb.Append("select * from ("); - var tbrule = tbrules[tbrulesIdx]; + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); sb.Append(_select); @@ -163,13 +161,13 @@ namespace FreeSql.SqlServer.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -203,7 +201,7 @@ namespace FreeSql.SqlServer.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -246,7 +244,7 @@ namespace FreeSql.SqlServer.Curd } sbnav.Clear(); - if (tbrulesGt0) sb.Append(") ftb"); + if (tbUnionsGt0) sb.Append(") ftb"); } return sb.ToString(); } @@ -262,51 +260,51 @@ namespace FreeSql.SqlServer.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index 463c593f..a5b3992b 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Sqlite.Curd class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, Func tableRuleInvoke, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -22,13 +22,12 @@ namespace FreeSql.Sqlite.Curd tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); var sb = new StringBuilder(); - var tbrules = CommonUtils.GetAllTableRule(_tables, tableRuleInvoke); - var tbrulesGt0 = tbrules.Count > 1; - for (var tbrulesIdx = 0; tbrulesIdx < tbrules.Count; tbrulesIdx++) + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbrulesIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbrulesGt0) sb.Append("select * from ("); - var tbrule = tbrules[tbrulesIdx]; + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); sb.Append(_select); @@ -38,13 +37,13 @@ namespace FreeSql.Sqlite.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbrule[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -78,7 +77,7 @@ namespace FreeSql.Sqlite.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbrule[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -109,7 +108,7 @@ namespace FreeSql.Sqlite.Curd sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); sbnav.Clear(); - if (tbrulesGt0) sb.Append(") ftb"); + if (tbUnionsGt0) sb.Append(") ftb"); } return sb.ToString(); } @@ -124,51 +123,51 @@ namespace FreeSql.Sqlite.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } } From e0a23accb09a2782fcb4eb832f4b59159a52d2cc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Sep 2019 09:29:12 +0800 Subject: [PATCH 0134/1029] v0.9.10 #89 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../Internal/CommonProvider/SelectProvider/Select0Provider.cs | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index c109f6cf..44f96479 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.9 + 0.9.10 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 3c521829..47b7c2ef 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8e3d8d56..cb607e84 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 21d5df17..c731ed1d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.9 + 0.9.10 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 6abb7a01..9dbc3b22 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index b5ce0b3c..c087b977 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -921,7 +921,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(name)) name = tb.Table.DbName; else { - if (name.IndexOf(' ') == -1) + if (name.IndexOf(' ') == -1) //还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() { if (_orm.CodeFirst.IsSyncStructureToLower) name = name.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) name = name.ToUpper(); diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0532652f..b8835164 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 1372db72..56277305 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 202e3e5e..5fc3745b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index dd13d625..ccfbf96b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 859f847b..3ef3322f 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4273bd5a..72abe8b9 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.9 + 0.9.10 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 564e1951d8c5a3bcaf13c1c4a8533beead2099b6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Sep 2019 16:01:01 +0800 Subject: [PATCH 0135/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.ToCh?= =?UTF-8?q?unk=20=E5=AE=9E=E7=8E=B0=E5=88=86=E5=9D=97=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=EF=BC=8C=E5=87=8F=E5=B0=91=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=87=E5=A4=A7=E6=97=B6=E5=86=85=E5=AD=98=E5=8D=A0=E7=94=A8?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs/Program.cs | 6 ++ FreeSql/FreeSql.xml | 8 ++ FreeSql/Interface/Curd/ISelect/ISelect0.cs | 7 ++ .../SelectProvider/Select0Provider.cs | 78 +++++++++++++++++++ 4 files changed, 99 insertions(+) diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 729b9c36..6530eb3e 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -48,6 +48,12 @@ namespace orm_vs static void Main(string[] args) { + var testlist1 = fsql.Select().OrderBy(a => a.Id).ToList(); + var testlist2 = new List(); + fsql.Select().OrderBy(a => a.Id).ToChunk(0, list => + { + testlist2.AddRange(list); + }); fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index aeaf966c..db077ae2 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -787,6 +787,14 @@ false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + + 数据块的大小 + 处理数据块 + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index bc10a9ad..eb1773ba 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -46,6 +46,13 @@ namespace FreeSql List ToList(bool includeNestedMembers = false); Task> ToListAsync(bool includeNestedMembers = false); /// + /// 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + /// + /// 数据块的大小 + /// 处理数据块 + /// false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + void ToChunk(int size, Action> done, bool includeNestedMembers = false); + /// /// 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 /// /// diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index c087b977..6ad66981 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -472,6 +472,84 @@ namespace FreeSql.Internal.CommonProvider return ToListAfPrivateAsync(sql, af, otherData); } + #region ToChunk + internal void ToListAfChunkPrivate(int chunkSize, Action> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + var retCount = 0; + Exception exception = null; + var checkDoneTimes = 0; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, dr => + { + ret.Add(af.Read(_orm, dr)); + retCount++; + if (otherData != null) + { + var idx = af.FieldCount - 1; + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + } + if (chunkSize > 0 && chunkSize == ret.Count) + { + checkDoneTimes++; + + foreach (var include in _includeToList) include?.Invoke(ret); + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); + _trackToList?.Invoke(ret); + chunkDone(ret); + + + ret.Clear(); + if (otherData != null) + foreach (var other in otherData) + other.retlist.Clear(); + } + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, retCount); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + if (ret.Any() || checkDoneTimes == 0) + { + foreach (var include in _includeToList) include?.Invoke(ret); + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); + _trackToList?.Invoke(ret); + chunkDone(ret); + } + } + internal void ToListChunkPrivate(int chunkSize, Action> chunkDone, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.Field); + + ToListAfChunkPrivate(chunkSize, chunkDone, sql, af, otherData); + } + public void ToChunk(int size, Action> done, bool includeNestedMembers = false) + { + if (_selectExpression != null) throw new ArgumentException("Chunk 功能之前不可使用 Select"); + this.ToListChunkPrivate(size, done, includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); + } + #endregion public virtual List ToList(bool includeNestedMembers = false) { if (_selectExpression != null) return this.InternalToList(_selectExpression); From 96bf97bb7f4b96ca337b8cdd9ff697a954e6fb93 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Sep 2019 16:06:15 +0800 Subject: [PATCH 0136/1029] v0.9.11 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 44f96479..441f4575 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.10 + 0.9.11 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 47b7c2ef..a1d87c4c 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index cb607e84..c5e0314d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c731ed1d..0eabb527 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.10 + 0.9.11 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9dbc3b22..4362872d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b8835164..d34f8bb3 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 56277305..af0b5fb2 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 5fc3745b..fef621c7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ccfbf96b..f579af01 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 3ef3322f..93a40193 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 72abe8b9..64ad18b7 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.10 + 0.9.11 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From bddcf9c0bc3406ba84f7d27f2c74c5ba43f708f9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Sep 2019 20:40:52 +0800 Subject: [PATCH 0137/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20MaxLength=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E7=9A=84=E8=A7=A3=E6=9E=90=EF=BC=8C=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=95=BF=E5=BA=A6=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Entities/User.cs | 5 +++ Examples/orm_vs/Program.cs | 4 +- FreeSql/DataAnnotations/ColumnAttribute.cs | 7 ++-- FreeSql/FreeSql.xml | 2 +- FreeSql/FreeSqlBuilder.cs | 49 +++++++++++++++++++--- 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/Examples/base_entity/Entities/User.cs b/Examples/base_entity/Entities/User.cs index 687feb55..7e7d741f 100644 --- a/Examples/base_entity/Entities/User.cs +++ b/Examples/base_entity/Entities/User.cs @@ -1,6 +1,7 @@ using FreeSql; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; public class UserGroup : BaseEntity { @@ -35,20 +36,24 @@ public class User1 : BaseEntity /// /// 登陆名 /// + [MaxLength(32)] public string Username { get; set; } /// /// 昵称 /// + [MaxLength(64)] public string Nickname { get; set; } /// /// 头像 /// + [MaxLength(1024)] public string Avatar { get; set; } /// /// 描述 /// + [MaxLength(4000)] public string Description { get; set; } } diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 6530eb3e..ee8470db 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -54,7 +54,7 @@ namespace orm_vs { testlist2.AddRange(list); }); - + fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements @@ -76,7 +76,7 @@ namespace orm_vs Insert(sb, 1000, 10); Console.Write(sb.ToString()); sb.Clear(); - + Insert(sb, 1, 1000); Console.Write(sb.ToString()); sb.Clear(); diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 11a2d1c1..21dede2d 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -15,7 +15,8 @@ namespace FreeSql.DataAnnotations /// public string OldName { get; set; } /// - /// 数据库类型,如: varchar(255) + /// 数据库类型,如: varchar(255) + /// 字符串长度,可使用特性 MaxLength(255) /// public string DbType { get; set; } @@ -82,7 +83,7 @@ namespace FreeSql.DataAnnotations internal short? _Position; /// - /// 创建表时字段位置,规则如下: + /// 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: /// /// >0时排前面,1,2,3... /// @@ -91,5 +92,5 @@ namespace FreeSql.DataAnnotations /// <0时排后面,...-3,-2,-1 /// public short Position { get => _Position ?? 0; set => _Position = value; } -} + } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index db077ae2..17f09e39 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -61,7 +61,7 @@ - 创建表时字段位置,规则如下: + 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: >0时排前面,1,2,3... diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 3235583c..55253b7b 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -181,31 +181,31 @@ namespace FreeSql switch (_entityPropertyConvertType) { case StringConvertType.Lower: - ret.Aop.ConfigEntityProperty = (s, e) => + ret.Aop.ConfigEntityProperty += (s, e) => { e.ModifyResult.Name = e.Property.Name.ToLower(); }; break; case StringConvertType.Upper: - ret.Aop.ConfigEntityProperty = (s, e) => + ret.Aop.ConfigEntityProperty += (s, e) => { e.ModifyResult.Name = e.Property.Name.ToUpper(); }; break; case StringConvertType.PascalCaseToUnderscore: - ret.Aop.ConfigEntityProperty = (s, e) => + ret.Aop.ConfigEntityProperty += (s, e) => { e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); }; break; case StringConvertType.PascalCaseToUnderscoreWithLower: - ret.Aop.ConfigEntityProperty = (s, e) => + ret.Aop.ConfigEntityProperty += (s, e) => { e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); }; break; case StringConvertType.PascalCaseToUnderscoreWithUpper: - ret.Aop.ConfigEntityProperty = (s, e) => + ret.Aop.ConfigEntityProperty += (s, e) => { e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); }; @@ -214,6 +214,45 @@ namespace FreeSql break; } } + //处理 MaxLength + ret.Aop.ConfigEntityProperty += new EventHandler((s, e) => + { + object[] attrs = null; + try + { + attrs = e.Property.GetCustomAttributes(false).ToArray(); //.net core 反射存在版本冲突问题,导致该方法异常 + } + catch { } + + var maxlenAttr = attrs.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.Name == "MaxLengthAttribute"; + }).FirstOrDefault(); + if (maxlenAttr != null) + { + var lenProp = maxlenAttr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).FirstOrDefault(); + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval) && tryval > 0) + { + switch (ret.Ado.DataType) + { + case DataType.MySql: + e.ModifyResult.DbType = $"varchar({tryval})"; + break; + case DataType.SqlServer: + e.ModifyResult.DbType = $"nvarchar({tryval})"; + break; + case DataType.PostgreSQL: + e.ModifyResult.DbType = $"varchar({tryval})"; + break; + case DataType.Oracle: + e.ModifyResult.DbType = $"nvarchar2({tryval})"; + break; + case DataType.Sqlite: + e.ModifyResult.DbType = $"nvarchar({tryval})"; + break; + } + } + } + }); } return ret; From 8520008b821016c98ad0065500484261abb22127 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Sep 2019 20:47:06 +0800 Subject: [PATCH 0138/1029] v0.9.12 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 3 ++- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 12 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 441f4575..d6d6f617 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.11 + 0.9.12 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a1d87c4c..1a3a82c9 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index c5e0314d..f979a9ec 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0eabb527..1f98a00a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.11 + 0.9.12 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4362872d..d5f2185f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 17f09e39..82735bc2 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -16,7 +16,8 @@ - 数据库类型,如: varchar(255) + 数据库类型,如: varchar(255) + 字符串长度,可使用特性 MaxLength(255) diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d34f8bb3..0a95f0f2 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index af0b5fb2..27540c59 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fef621c7..e33a267d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f579af01..14a68880 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 93a40193..94c9b532 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 64ad18b7..e22d4e66 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.11 + 0.9.12 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From aa832ba17a7a8feff8b234041805279726f6e6a6 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Thu, 12 Sep 2019 22:13:15 +0800 Subject: [PATCH 0139/1029] update logo --- readme.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 67459e42..87a3c2fa 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,7 @@ +

+ +

+ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577) 扶摇直上,至强ORM只为自由编码;鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) @@ -248,4 +252,4 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [movingsam](https://github.com/movingsam)、 [ALer-R](https://github.com/ALer-R)、 [zouql](https://github.com/zouql)、 -深圳|凉茶 \ No newline at end of file +深圳|凉茶 From 62a095df8f8a7a9c0bc66a8f65ae7d182d059a78 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 13 Sep 2019 00:23:52 +0800 Subject: [PATCH 0140/1029] v0.9.13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加 FreeSql.Extensions.JsonMap 扩展包,实现快速将对象映射为json字符串的方法; - 优化 表达式解析未实现的错误提醒,如 $""; --- Examples/base_entity/Program.cs | 31 ++++++++++ Examples/base_entity/base_entity.csproj | 1 + .../BaseEntityReadOnly.cs | 2 +- .../FreeSql.Extensions.BaseEntity.csproj | 3 +- .../DataAnnotations/JsonMapAttribute.cs | 13 ++++ .../FreeSql.Extensions.JsonMap.csproj | 29 +++++++++ .../FreeSql.Extensions.JsonMap/JsonMapCore.cs | 58 ++++++++++++++++++ .../FreeSql.Extensions.JsonMap/readme.md | 23 +++++++ .../FreeSql.Extensions.LazyLoading.csproj | 3 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 3 +- FreeSql.Repository/FreeSql.Repository.csproj | 3 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 3 + FreeSql.sln | 15 +++++ FreeSql/DataAnnotations/ColumnAttribute.cs | 4 +- FreeSql/FreeSql.csproj | 3 +- FreeSql/FreeSql.xml | 4 +- FreeSql/Internal/CommonExpression.cs | 14 +++-- FreeSql/Internal/UtilsExpressionTree.cs | 12 ++-- .../FreeSql.Provider.MySql.csproj | 3 +- .../FreeSql.Provider.MySql/MySqlExpression.cs | 10 +-- .../FreeSql.Provider.MySql/MySqlProvider.cs | 4 +- .../FreeSql.Provider.MySqlConnector.csproj | 3 +- .../FreeSql.Provider.Oracle.csproj | 3 +- .../OracleExpression.cs | 10 +-- .../FreeSql.Provider.PostgreSQL.csproj | 3 +- .../PostgreSQLExpression.cs | 10 +-- .../PostgreSQLProvider.cs | 4 +- .../FreeSql.Provider.SqlServer.csproj | 3 +- .../SqlServerExpression.cs | 10 +-- .../FreeSql.Provider.Sqlite.csproj | 3 +- .../SqliteExpression.cs | 10 +-- logo.png | Bin 0 -> 9201 bytes readme.md | 2 + 33 files changed, 249 insertions(+), 53 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.JsonMap/DataAnnotations/JsonMapAttribute.cs create mode 100644 Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj create mode 100644 Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs create mode 100644 Extensions/FreeSql.Extensions.JsonMap/readme.md create mode 100644 logo.png diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index d6868178..7312f114 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -1,17 +1,48 @@ using FreeSql; +using FreeSql.DataAnnotations; +using FreeSql.Extensions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; +using System.Linq.Expressions; using System.Threading.Tasks; namespace base_entity { class Program { + class TestConfig + { + public int clicks { get; set; } + public string title { get; set; } + } + [Table(Name = "sysconfig")] + public class S_SysConfig : BaseEntity> + { + [Column(IsPrimary = true)] + public string Name { get; set; } + + [JsonMap] + public T Config { get; set; } + } + static void Main(string[] args) { + #region 初始化 IFreeSql BaseEntity.Initialization(new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) + .UseNoneCommandParameter(true) .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=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=2") .Build()); + #endregion + + BaseEntity.Orm.UseJsonMap(); + + new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); + new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" } }.Save(); + new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" } }.Save(); + var testconfigs11 = S_SysConfig.Select.ToList(); Task.Run(async () => { diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index c05b214a..f177d568 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -15,6 +15,7 @@ + diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 365ae1b0..e7e82ce5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -43,7 +43,7 @@ namespace FreeSql /// 创建时间 ///
[Column(Position = -4)] - public DateTime CreateTime { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; /// /// 更新时间 /// diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d6d6f617..d293c21e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.12 + 0.9.15 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. @@ -12,6 +12,7 @@ MIT FreeSql;ORM;BaseEntity $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/Extensions/FreeSql.Extensions.JsonMap/DataAnnotations/JsonMapAttribute.cs b/Extensions/FreeSql.Extensions.JsonMap/DataAnnotations/JsonMapAttribute.cs new file mode 100644 index 00000000..44f5d8a1 --- /dev/null +++ b/Extensions/FreeSql.Extensions.JsonMap/DataAnnotations/JsonMapAttribute.cs @@ -0,0 +1,13 @@ +using System; +using System.Linq; + +namespace FreeSql.DataAnnotations +{ + + /// + /// 当实体类属性为【对象】时,以JSON形式映射存储 + /// + public class JsonMapAttribute : Attribute + { + } +} diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj new file mode 100644 index 00000000..a4e16229 --- /dev/null +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -0,0 +1,29 @@ + + + + netstandard2.0;net45 + 0.9.15 + true + YeXiangQin + FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png + $(AssemblyName) + true + true + + + + + + + + + + + diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs new file mode 100644 index 00000000..e5593617 --- /dev/null +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -0,0 +1,58 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Concurrent; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace FreeSql.Extensions +{ + public static class JsonMapCore + { + static bool _isAoped = false; + static object _isAopedLock = new object(); + static ConcurrentDictionary _dicTypes = new ConcurrentDictionary(); + static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); + static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object) }); + + /// + /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 + /// + /// + public static void UseJsonMap(this IFreeSql that) + { + if (_isAoped == false) + lock(_isAopedLock) + if (_isAoped == false) + { + _isAoped = true; + + FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => + { + if (_dicTypes.ContainsKey(type)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); + return null; + }); + + that.Aop.ConfigEntityProperty += new EventHandler((s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + { + e.ModifyResult.MapType = typeof(string); + if (_dicTypes.TryAdd(e.Property.PropertyType, true)) + { + FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => + { + return Expression.IfThenElse( + Expression.TypeEqual(valueExp, e.Property.PropertyType), + Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object))), typeof(object)), + elseExp); + }); + } + } + }); + } + } + } +} diff --git a/Extensions/FreeSql.Extensions.JsonMap/readme.md b/Extensions/FreeSql.Extensions.JsonMap/readme.md new file mode 100644 index 00000000..96906cd8 --- /dev/null +++ b/Extensions/FreeSql.Extensions.JsonMap/readme.md @@ -0,0 +1,23 @@ +FreeSql 扩展包,将值对象映射成 typeof(string),安装扩展包: + +> dotnet add package FreeSql.Extensions.JsonMap + +```csharp +fsql.UseJsonMap(); //开启功能 + +class TestConfig +{ + public int clicks { get; set; } + public string title { get; set; } +} + +[Table(Name = "sysconfig")] +public class S_SysConfig +{ + [Column(IsPrimary = true)] + public string Name { get; set; } + + [JsonMap] + public T Config { get; set; } +} +``` \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 1a3a82c9..c1d3828d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. @@ -12,6 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index f979a9ec..1b6415fb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. @@ -11,6 +11,7 @@ git MIT $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 1f98a00a..290e6b23 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.12 + 0.9.15 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository @@ -11,6 +11,7 @@ git MIT $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 4f95cf07..edf94e73 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -406,6 +406,9 @@ namespace FreeSql.Tests [Fact] public void Test1() { + + var testssargs1 = "10100"; + var testformatsql1 = g.mysql.Select().Where(a => a.NamespaceName == $"1_{10100}").ToSql(); var testorderbysql = g.mysql.Select().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql(); var testincludeMemberssql1 = g.sqlite.Select().Where(a => a.Templates.Title == "1").ToList(); diff --git a/FreeSql.sln b/FreeSql.sln index 78427fa6..42ee6d17 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -58,6 +58,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "base_entity", "Examples\bas EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.BaseEntity", "Extensions\FreeSql.Extensions.BaseEntity\FreeSql.Extensions.BaseEntity.csproj", "{FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.JsonMap", "Extensions\FreeSql.Extensions.JsonMap\FreeSql.Extensions.JsonMap.csproj", "{3043DEF1-85DF-47AD-8D5D-327270794356}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -332,6 +334,18 @@ Global {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|x64.Build.0 = Release|Any CPU {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|x86.ActiveCfg = Release|Any CPU {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6}.Release|x86.Build.0 = Release|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Debug|x64.ActiveCfg = Debug|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Debug|x64.Build.0 = Debug|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Debug|x86.ActiveCfg = Debug|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Debug|x86.Build.0 = Debug|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|Any CPU.Build.0 = Release|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|x64.ActiveCfg = Release|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|x64.Build.0 = Release|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|x86.ActiveCfg = Release|Any CPU + {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -352,6 +366,7 @@ Global {4C0973CB-BD49-4A5B-A6FE-EE0594BDD513} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} + {3043DEF1-85DF-47AD-8D5D-327270794356} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 21dede2d..9040fe96 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -77,7 +77,9 @@ namespace FreeSql.DataAnnotations public object DbDefautValue { get; internal set; } /// - /// 类型映射,比如:可将 enum 属性映射成 typeof(string) + /// 类型映射,除了可做基本的类型映射外,特别介绍的功能: + /// 1、将 enum 属性映射成 typeof(string) + /// 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap /// public Type MapType { get; set; } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index d5f2185f..ac1c46e2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. @@ -12,6 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 82735bc2..3ce7b5a3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -57,7 +57,9 @@
- 类型映射,比如:可将 enum 属性映射成 typeof(string) + 类型映射,除了可做基本的类型映射外,特别介绍的功能: + 1、将 enum 属性映射成 typeof(string) + 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index deada8a9..4fc329c6 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -535,14 +535,16 @@ namespace FreeSql.Internal tsc.mapType = null; var exp3 = exp as MethodCallExpression; var callType = exp3.Object?.Type ?? exp3.Method.DeclaringType; + string other3Exp = null; switch (callType.FullName) { - case "System.String": return ExpressionLambdaToSqlCallString(exp3, tsc); - case "System.Math": return ExpressionLambdaToSqlCallMath(exp3, tsc); - case "System.DateTime": return ExpressionLambdaToSqlCallDateTime(exp3, tsc); - case "System.TimeSpan": return ExpressionLambdaToSqlCallTimeSpan(exp3, tsc); - case "System.Convert": return ExpressionLambdaToSqlCallConvert(exp3, tsc); + case "System.String": other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); break; + case "System.Math": other3Exp = ExpressionLambdaToSqlCallMath(exp3, tsc); break; + case "System.DateTime": other3Exp = ExpressionLambdaToSqlCallDateTime(exp3, tsc); break; + case "System.TimeSpan": other3Exp = ExpressionLambdaToSqlCallTimeSpan(exp3, tsc); break; + case "System.Convert": other3Exp = ExpressionLambdaToSqlCallConvert(exp3, tsc); break; } + if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; if (exp3.Method.Name == "Equals" && exp3.Object != null && exp3.Arguments.Count > 0) return ExpressionBinary("=", exp3.Object, exp3.Arguments[0], tsc); if (callType.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) @@ -849,7 +851,7 @@ namespace FreeSql.Internal // } //} - var other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); + other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType); throw new Exception($"未实现函数表达式 {exp3} 解析"); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index f3dbe11d..6b7824c1 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1466,7 +1466,8 @@ namespace FreeSql.Internal static PropertyInfo PropertyDateTimeTicks = typeof(DateTime).GetProperty("Ticks", BindingFlags.Instance | BindingFlags.Public); static ConstructorInfo CtorDateTimeOffsetArgsTicks = typeof(DateTimeOffset).GetConstructor(new[] { typeof(long), typeof(TimeSpan) }); - public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); + public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); + public static ConcurrentBag> GetDataReaderValueBlockExpressionObjectToStringIfThenElse = new ConcurrentBag>(); public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) { var returnTarget = Expression.Label(typeof(object)); @@ -1728,11 +1729,14 @@ namespace FreeSql.Internal default: foreach (var switchFunc in GetDataReaderValueBlockExpressionSwitchTypeFullName) { - var switchFuncRet = switchFunc(returnTarget, valueExp, type.FullName); + var switchFuncRet = switchFunc(returnTarget, valueExp, type); if (switchFuncRet != null) return switchFuncRet; } break; } + Expression callToStringExp = Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))); + foreach (var toStringFunc in GetDataReaderValueBlockExpressionObjectToStringIfThenElse) + callToStringExp = toStringFunc(returnTarget, valueExp, callToStringExp, type); Expression switchExp = null; if (tryparseExp != null) switchExp = Expression.Switch( @@ -1753,12 +1757,12 @@ namespace FreeSql.Internal Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type)) ); else if (type == typeof(string)) - switchExp = Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))); + switchExp = callToStringExp; else switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); var defaultRetExp = type == typeof(string) ? - Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))) : + callToStringExp : Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); return Expression.IfThenElse( diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0a95f0f2..83500b51 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 @@ -12,6 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index d9fb104f..d74aa632 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -310,7 +310,7 @@ namespace FreeSql.MySql case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; } } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { @@ -338,7 +338,7 @@ namespace FreeSql.MySql case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)"; } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { @@ -388,7 +388,7 @@ namespace FreeSql.MySql case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; } } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { @@ -424,7 +424,7 @@ namespace FreeSql.MySql case "ToString": return $"cast({left} as char)"; } } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { @@ -450,7 +450,7 @@ namespace FreeSql.MySql case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; } } - throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析"); + return null; } } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index f53a0ebe..c62decfe 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -22,9 +22,9 @@ namespace FreeSql.MySql Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPolygon)] = true; var MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) }); - Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => + Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => { - switch (typeFullName) + switch (type.FullName) { case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint))); case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString))); diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 27540c59..7b1b720a 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 @@ -12,6 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index e33a267d..a5e45c58 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 @@ -12,6 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 3bf13ec4..d516f0a2 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -310,7 +310,7 @@ namespace FreeSql.Oracle case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; } } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { @@ -340,7 +340,7 @@ namespace FreeSql.Oracle //case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { @@ -390,7 +390,7 @@ namespace FreeSql.Oracle case "ToString": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; } } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { @@ -426,7 +426,7 @@ namespace FreeSql.Oracle case "ToString": return $"to_char({left})"; } } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { @@ -452,7 +452,7 @@ namespace FreeSql.Oracle case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as number)"; } } - throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析"); + return null; } } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 14a68880..31cadc17 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 @@ -12,6 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index e0bc9eab..e6c3bd02 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -421,7 +421,7 @@ namespace FreeSql.PostgreSQL case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; } } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { @@ -449,7 +449,7 @@ namespace FreeSql.PostgreSQL case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { @@ -499,7 +499,7 @@ namespace FreeSql.PostgreSQL case "ToString": return $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')"; } } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { @@ -535,7 +535,7 @@ namespace FreeSql.PostgreSQL case "ToString": return $"({left})::varchar"; } } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { @@ -561,7 +561,7 @@ namespace FreeSql.PostgreSQL case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; } } - throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析"); + return null; } } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index b3f949aa..21627b10 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -51,9 +51,9 @@ namespace FreeSql.PostgreSQL var MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) }); var MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) }); var MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) }); - Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => + Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => { - switch (typeFullName) + switch (type.FullName) { case "Newtonsoft.Json.Linq.JToken": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken))); case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject))); diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 94c9b532..a2067ff8 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -12,6 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 24fd1a33..28b7cc4e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -292,7 +292,7 @@ namespace FreeSql.SqlServer case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; } } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { @@ -320,7 +320,7 @@ namespace FreeSql.SqlServer case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; case "Truncate": return $"floor({getExp(exp.Arguments[0])})"; } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { @@ -370,7 +370,7 @@ namespace FreeSql.SqlServer case "ToString": return $"convert(varchar, {left}, 121)"; } } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { @@ -406,7 +406,7 @@ namespace FreeSql.SqlServer case "ToString": return $"cast({left} as varchar)"; } } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { @@ -432,7 +432,7 @@ namespace FreeSql.SqlServer case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; } } - throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析"); + return null; } } } diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e22d4e66..1bcc27a7 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.12 + 0.9.15 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 @@ -12,6 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index b3f1541e..cca89bb8 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -314,7 +314,7 @@ namespace FreeSql.Sqlite case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; } } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { @@ -342,7 +342,7 @@ namespace FreeSql.Sqlite case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; //case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)"; } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { @@ -392,7 +392,7 @@ namespace FreeSql.Sqlite case "ToString": return $"strftime('%Y-%m-%d %H:%M.%f',{left})"; } } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { @@ -428,7 +428,7 @@ namespace FreeSql.Sqlite case "ToString": return $"cast({left} as character)"; } } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + return null; } public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { @@ -454,7 +454,7 @@ namespace FreeSql.Sqlite case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as decimal(21,0))"; } } - throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析"); + return null; } } } diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d7e56b8dcd31aae9455d7441d9a9a33e380ea96a GIT binary patch literal 9201 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 Date: Fri, 13 Sep 2019 00:24:15 +0800 Subject: [PATCH 0141/1029] update logo --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 2b8d3b4b..510ca66c 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@

- +

FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577) From 8ad9198f0e3661811cdcd8f74e2ae65c9dc87052 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 13 Sep 2019 00:44:40 +0800 Subject: [PATCH 0142/1029] update logo url --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d293c21e..d3a4a065 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;BaseEntity $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a4e16229..af962199 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c1d3828d..0b738253 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 1b6415fb..83634ba5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -11,7 +11,7 @@ git MIT $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 290e6b23..193a211f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -11,7 +11,7 @@ git MIT $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index ac1c46e2..9480b01e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 83500b51..3540a11f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7b1b720a..99991aa5 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a5e45c58..12cfda8b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 31cadc17..5d1fdaba 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a2067ff8..b2f22df8 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 1bcc27a7..195b52c7 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true $(AssemblyName) true true From f43b7403921fcf719961a169f9fbb650e9dcaa5e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Sep 2019 22:49:24 +0800 Subject: [PATCH 0143/1029] update readme --- functions.png | Bin 0 -> 51130 bytes readme.md | 6 +++++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 functions.png diff --git a/functions.png b/functions.png new file mode 100644 index 0000000000000000000000000000000000000000..6dfce8c441a36330f38eec354992f2d5461130dc GIT binary patch literal 51130 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

!Vzkdh{0f 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 A$p8QV literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index 510ca66c..2669a2d8 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@

- +

FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577) @@ -62,6 +62,10 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | FreeSql.Extensions.JsonMap | NETStandard2.0、net45 | | FreeSql.Extensions.BaseEntity | NETStandard2.0 | +

+ +

+ # Quick start > dotnet add package FreeSql.Provider.Sqlite From 79b45b39fd5c132b14ff00dd11b2257e5074a943 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Sep 2019 22:51:19 +0800 Subject: [PATCH 0144/1029] update --- functions.png | Bin 51130 -> 51186 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/functions.png b/functions.png index 6dfce8c441a36330f38eec354992f2d5461130dc..5d538ff63a8b353b1a0bf51e14cb5604e07239ed 100644 GIT binary patch literal 51186 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⋘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 gavumAu6 literal 51130 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

!Vzkdh{0f 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 A$p8QV From f62625f14daead7c26c86a0ce9c654e626f33f03 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Sep 2019 22:54:45 +0800 Subject: [PATCH 0145/1029] update --- funcs.png | Bin 0 -> 51166 bytes functions.png | Bin 51186 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 funcs.png delete mode 100644 functions.png diff --git a/funcs.png b/funcs.png new file mode 100644 index 0000000000000000000000000000000000000000..e956d464ded6c3abc9dab3fce6688728c455bdc2 GIT binary patch literal 51166 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 b#1wXWCMe8PDGcL)LY>t!{F`v{`u+a{8veek literal 0 HcmV?d00001 diff --git a/functions.png b/functions.png deleted file mode 100644 index 5d538ff63a8b353b1a0bf51e14cb5604e07239ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51186 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⋘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 gavumAu6 From 0d761e02dea3516e34f4e9ee714138dc856ea61a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Sep 2019 22:55:13 +0800 Subject: [PATCH 0146/1029] update --- funcs.png => functions02.png | Bin readme.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename funcs.png => functions02.png (100%) diff --git a/funcs.png b/functions02.png similarity index 100% rename from funcs.png rename to functions02.png diff --git a/readme.md b/readme.md index 2669a2d8..8f19786d 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | FreeSql.Extensions.BaseEntity | NETStandard2.0 |

- +

# Quick start From d0fff882c8acd03fea8a36f35c1472079224fb06 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Sep 2019 22:56:55 +0800 Subject: [PATCH 0147/1029] update --- functions02.png | Bin 51166 -> 0 bytes functions03.png | Bin 0 -> 52032 bytes readme.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 functions02.png create mode 100644 functions03.png diff --git a/functions02.png b/functions02.png deleted file mode 100644 index e956d464ded6c3abc9dab3fce6688728c455bdc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51166 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 b#1wXWCMe8PDGcL)LY>t!{F`v{`u+a{8veek diff --git a/functions03.png b/functions03.png new file mode 100644 index 0000000000000000000000000000000000000000..d0aef2070114554f49dbb6b61e897bdd45b91b67 GIT binary patch literal 52032 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 PtcT~7HO^!znFanovp!`) literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index 8f19786d..c0319a0a 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | FreeSql.Extensions.BaseEntity | NETStandard2.0 |

- +

# Quick start From 9a95b2fafd1f4b18055b03fc07379d40f27b19f0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 17 Sep 2019 10:00:01 +0800 Subject: [PATCH 0148/1029] update --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index c0319a0a..cbdf2f23 100644 --- a/readme.md +++ b/readme.md @@ -20,7 +20,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | | | | - | - | -| | [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《新手上路](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | | | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | | | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | | | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | From 52450dc08a0c008826bde3c332d5304d8e44fd96 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 17 Sep 2019 10:01:01 +0800 Subject: [PATCH 0149/1029] update newman --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index cbdf2f23..2439c131 100644 --- a/readme.md +++ b/readme.md @@ -20,7 +20,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | | | | - | - | -| | [《新手上路](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《新手上路》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | | | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | | | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | | | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | From 8d92ccd7510fc8d4787a0065fad9937d0d11103c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 18 Sep 2019 16:58:13 +0800 Subject: [PATCH 0150/1029] ## v0.9.16 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加 BaseRepository.AttachOnlyPrimary 方法,只附加实体的主键值; > 在更新前使用可实现不查询数据库再更新、也可以实现更新时不更新值为 null 的字段 ```csharp class T { public int id { get; set; } public string name { get; set; } public string other { get; set; } } var item = new T { id = 1, name = "xx" }; fsql.GetRepository().AttachOnlyPrimary(item).Update(item); //只更新 name ``` - 修复 Lambda 表达式中 DateTime.Now.ToString("yyyyMMdd") 不能直接执行的 bug; --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/DbContext/DbContext.cs | 11 +++++++++++ FreeSql.DbContext/DbSet/DbSet.cs | 17 +++++++++++++++++ FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 19 +++++++++++++++++++ .../Repository/Repository/BaseRepository.cs | 5 +++++ .../Repository/Repository/IBasicRepository.cs | 6 ++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../RepositoryTests.cs | 6 +++++- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 8 +++++++- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySql/MySqlExpression.cs | 4 ++-- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../OracleExpression.cs | 4 ++-- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../PostgreSQLExpression.cs | 4 ++-- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../SqlServerExpression.cs | 4 ++-- .../FreeSql.Provider.Sqlite.csproj | 2 +- .../SqliteExpression.cs | 4 ++-- 24 files changed, 92 insertions(+), 24 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d3a4a065..2438312c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.15 + 0.9.16 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index af962199..16674c11 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0b738253..7b64f524 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 364326eb..0d0fcc75 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -129,6 +129,17 @@ namespace FreeSql /// public void Attach(TEntity data) where TEntity : class => this.Set().Attach(data); public void AttachRange(IEnumerable data) where TEntity : class => this.Set().AttachRange(data); + + /// + /// 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 + /// + /// + /// + public DbContext AttachOnlyPrimary(TEntity data) where TEntity : class + { + this.Set().AttachOnlyPrimary(data); + return this; + } #endregion #region Queue Action diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 32c69096..7795ba50 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -162,6 +162,23 @@ namespace FreeSql }); } } + /// + /// 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 + /// + /// + public DbSet AttachOnlyPrimary(TEntity data) + { + if (data == null) return this; + var pkitem = (TEntity)Activator.CreateInstance(_entityType); + foreach (var pk in _db.Orm.CodeFirst.GetTableByEntity(_entityType).Primarys) + { + var colVal = _db.Orm.GetEntityValueWithPropertyName(_entityType, data, pk.CsName); + _db.Orm.SetEntityValueWithPropertyName(_entityType, pkitem, pk.CsName, colVal); + } + this.Attach(pkitem); + return this; + } + /// /// 清空状态数据 /// diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 83634ba5..b7cf2d84 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index e0d4588c..42dd9adc 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -39,6 +39,13 @@
+ + + 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 + + + + 是否开启一对多,联级保存功能 @@ -57,6 +64,12 @@ + + + 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 + + + 清空状态数据 @@ -156,6 +169,12 @@ + + + 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 + + + 是否启用工作单元 diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index e2f38254..2fbcc0cc 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -140,6 +140,11 @@ namespace FreeSql public void Attach(TEntity data) => _db.Attach(data); public void Attach(IEnumerable data) => _db.AttachRange(data); + public IBasicRepository AttachOnlyPrimary(TEntity data) + { + _db.AttachOnlyPrimary(data); + return this; + } public void FlushState() => _dbset.FlushState(); public TEntity InsertOrUpdate(TEntity entity) diff --git a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs index 21aecb89..5f2ba98a 100644 --- a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs @@ -21,6 +21,12 @@ namespace FreeSql /// void Attach(TEntity entity); void Attach(IEnumerable entity); + /// + /// 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 + /// + /// + IBasicRepository AttachOnlyPrimary(TEntity data); + int Update(TEntity entity); int Update(IEnumerable entitys); Task UpdateAsync(TEntity entity); diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 193a211f..dab8e461 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index b2be4440..95319a9c 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -37,9 +37,13 @@ namespace FreeSql.Tests repos.Attach(item); item.Title = "xxx"; - repos.Update(item); + repos.Update(item); //ִ UPDATE "AddUpdateInfo" SET "Title" = 'xxx' WHERE("Id" = '1942fb53-9700-411d-8895-ce4cecdf3257') Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + repos.Update(item); //вִ SQLδ仯 + + repos.AttachOnlyPrimary(item).Update(item); //и״ֵֵֻ̬ڣִи set title = xxx + Console.WriteLine(repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ToSql()); repos.UpdateDiy.Where(a => a.Id == item.Id).Set(a => a.Clicks + 1).ExecuteAffrows(); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index edf94e73..9aa4e531 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -22,7 +22,7 @@ namespace FreeSql.Tests { public static T TryTo(this string that) { - return default(T); + return (T)Internal.Utils.GetDataReaderValue(typeof(T), that); } public static string FormatDateTime() @@ -407,6 +407,12 @@ namespace FreeSql.Tests public void Test1() { + var testrunsql1 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testrunsql2 = g.pgsql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testrunsql3 = g.sqlserver.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testrunsql4 = g.oracle.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testrunsql5 = g.sqlite.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testssargs1 = "10100"; var testformatsql1 = g.mysql.Select().Where(a => a.NamespaceName == $"1_{10100}").ToSql(); var testorderbysql = g.mysql.Select().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql(); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9480b01e..48308669 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3540a11f..ffe8dc73 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index d74aa632..4bfc1a4c 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -83,7 +83,7 @@ namespace FreeSql.MySql if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; break; case "ToString": - if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as char)"; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null; break; } @@ -385,7 +385,7 @@ namespace FreeSql.MySql break; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; - case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; + case "ToString": return exp.Arguments.Count == 0 ? $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')" : null; } } return null; diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 99991aa5..c4663edc 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 12cfda8b..3d5eba25 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index d516f0a2..139d1a6c 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -83,7 +83,7 @@ namespace FreeSql.Oracle if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; break; case "ToString": - if (callExp.Object != null) return $"to_char({getExp(callExp.Object)})"; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"to_char({getExp(callExp.Object)})" : null; break; } @@ -387,7 +387,7 @@ namespace FreeSql.Oracle break; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; - case "ToString": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; } } return null; diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 5d1fdaba..5c031066 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index e6c3bd02..5357d296 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -88,7 +88,7 @@ namespace FreeSql.PostgreSQL if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; break; case "ToString": - if (callExp.Object != null) return $"({getExp(callExp.Object)})::varchar"; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; break; } @@ -496,7 +496,7 @@ namespace FreeSql.PostgreSQL break; case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::timestamp)"; case "CompareTo": return $"extract(epoch from ({left})::timestamp-({getExp(exp.Arguments[0])})::timestamp)"; - case "ToString": return $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')"; + case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')" : null; } } return null; diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b2f22df8..985769e2 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 28b7cc4e..d5a1ccdd 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -87,7 +87,7 @@ namespace FreeSql.SqlServer if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; break; case "ToString": - if (callExp.Object != null) return callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)"; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null; break; } @@ -367,7 +367,7 @@ namespace FreeSql.SqlServer break; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "CompareTo": return $"datediff(second,{getExp(exp.Arguments[0])},{left})"; - case "ToString": return $"convert(varchar, {left}, 121)"; + case "ToString": return exp.Arguments.Count == 0 ? $"convert(varchar, {left}, 121)" : null; } } return null; diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 195b52c7..cb5d58d3 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.15 + 0.9.16 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index cca89bb8..db13908e 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -83,7 +83,7 @@ namespace FreeSql.Sqlite if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; break; case "ToString": - if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as character)"; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as character)" : null; break; } @@ -389,7 +389,7 @@ namespace FreeSql.Sqlite break; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; - case "ToString": return $"strftime('%Y-%m-%d %H:%M.%f',{left})"; + case "ToString": return exp.Arguments.Count == 0 ? $"strftime('%Y-%m-%d %H:%M.%f',{left})" : null; } } return null; From f434418b2ce579f6e4598c305268edfcc0230b70 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Sep 2019 23:14:30 +0800 Subject: [PATCH 0151/1029] ## v0.9.17 (ODBC) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加 FreeSql.Provider.Odbc,实现 Oracle/SqlServer/MySql 的 Odbc 访问提供; - 增加 FreeSqlBuilder.UseConnectionString 参数 providerType,可解决因包版本冲突时,可能无法反射获得 FreeSql.Provider 对应的类型,通常这个参数不需要设置; - 优化 MaxLength 特性,当指定为 -1 时 DbType 会分别映射类型 text/nvarchar(max)/nvarchar2(4000); --- Examples/base_entity/base_entity.csproj | 4 +- Examples/benchmarker/benchmarker.csproj | 2 +- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- ...eeSql.Tests.Provider.MySqlConnector.csproj | 4 +- .../FreeSql.Tests.Provider.Odbc.csproj | 22 + .../MySql/Curd/MySqlDeleteTest.cs | 96 + .../MySql/Curd/MySqlInsertTest.cs | 162 ++ .../MySql/Curd/MySqlSelectTest.cs | 1352 +++++++++++++ .../MySql/Curd/MySqlUpdateTest.cs | 210 ++ .../MySql/MapType/BoolNullableTest.cs | 1722 +++++++++++++++++ .../MySql/MapType/BoolTest.cs | 1130 +++++++++++ .../MySql/MapType/DateTimeOffSetTest.cs | 62 + .../MySql/MapType/EnumTest.cs | 261 +++ .../MySql/MapType/ToStringTest.cs | 570 ++++++ .../MySql/MySqlAdo/MySqlAdoTest.cs | 66 + .../MySql/MySqlAopTest.cs | 40 + .../MySql/MySqlCodeFirstTest.cs | 451 +++++ .../MySql/MySqlDbFirstTest.cs | 25 + .../MySql/MySqlExpression/ConvertTest.cs | 169 ++ .../MySql/MySqlExpression/DateTimeTest.cs | 694 +++++++ .../MySql/MySqlExpression/MathTest.cs | 156 ++ .../MySql/MySqlExpression/OtherTest.cs | 136 ++ .../MySql/MySqlExpression/StringTest.cs | 729 +++++++ .../MySql/MySqlExpression/TimeSpanTest.cs | 293 +++ .../Oracle/Curd/OracleDeleteTest.cs | 98 + .../Oracle/Curd/OracleInsertTest.cs | 278 +++ .../Oracle/Curd/OracleSelectTest.cs | 1236 ++++++++++++ .../Oracle/Curd/OracleUpdateTest.cs | 142 ++ .../Oracle/MapType/BoolNullableTest.cs | 1596 +++++++++++++++ .../Oracle/MapType/BoolTest.cs | 1130 +++++++++++ .../Oracle/MapType/DateTimeOffSetTest.cs | 54 + .../Oracle/MapType/EnumTest.cs | 261 +++ .../Oracle/MapType/ToStringTest.cs | 570 ++++++ .../Oracle/OracleAdo/OracleAdoTest.cs | 66 + .../Oracle/OracleAopTest.cs | 40 + .../Oracle/OracleCodeFirstTest.cs | 258 +++ .../Oracle/OracleDbFirstTest.cs | 25 + .../Oracle/OracleExpression/ConvertTest.cs | 169 ++ .../Oracle/OracleExpression/DateTimeTest.cs | 706 +++++++ .../Oracle/OracleExpression/MathTest.cs | 156 ++ .../Oracle/OracleExpression/OtherTest.cs | 135 ++ .../Oracle/OracleExpression/StringTest.cs | 726 +++++++ .../Oracle/OracleExpression/TimeSpanTest.cs | 293 +++ .../SqlServer/Curd/SqlServerDeleteTest.cs | 104 + .../SqlServer/Curd/SqlServerInsertTest.cs | 155 ++ .../SqlServer/Curd/SqlServerSelectTest.cs | 1224 ++++++++++++ .../SqlServer/Curd/SqlServerUpdateTest.cs | 161 ++ .../SqlServer/MapType/BoolNullableTest.cs | 1597 +++++++++++++++ .../SqlServer/MapType/BoolTest.cs | 1130 +++++++++++ .../SqlServer/MapType/DateTimeOffSetTest.cs | 54 + .../SqlServer/MapType/EnumTest.cs | 263 +++ .../SqlServer/MapType/ToStringTest.cs | 571 ++++++ .../SqlServerAdo/SqlServerAdoTest.cs | 96 + .../SqlServer/SqlServerAopTest.cs | 40 + .../SqlServer/SqlServerCodeFirstTest.cs | 380 ++++ .../SqlServer/SqlServerDbFirstTest.cs | 26 + .../SqlServerExpression/ConvertTest.cs | 169 ++ .../SqlServerExpression/DateTimeTest.cs | 322 +++ .../SqlServer/SqlServerExpression/MathTest.cs | 156 ++ .../SqlServerExpression/OtherTest.cs | 130 ++ .../SqlServerExpression/StringTest.cs | 290 +++ .../SqlServerExpression/TimeSpanTest.cs | 210 ++ .../FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 1081 +++++++++++ .../FreeSql.Tests.Provider.Odbc/g.cs | 41 + FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 25 + FreeSql.Tests/FreeSql.Tests/g.cs | 50 +- FreeSql.sln | 29 + FreeSql/DataType.cs | 7 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 3 +- FreeSql/FreeSqlBuilder.cs | 108 +- .../CommonProvider/CodeFirstProvider.cs | 8 +- FreeSql/Internal/UtilsExpressionTree.cs | 4 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 30 + .../FreeSqlOdbcGlobalExtensions.cs | 30 + .../MySql/Curd/OdbcMySqlDelete.cs | 95 + .../MySql/Curd/OdbcMySqlInsert.cs | 175 ++ .../MySql/Curd/OdbcMySqlSelect.cs | 173 ++ .../MySql/Curd/OdbcMySqlUpdate.cs | 140 ++ .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 70 + .../OdbcMySqlAdo/OdbcMySqlConnectionPool.cs | 229 +++ .../MySql/OdbcMySqlCodeFirst.cs | 337 ++++ .../MySql/OdbcMySqlDbFirst.cs | 385 ++++ .../MySql/OdbcMySqlExpression.cs | 456 +++++ .../MySql/OdbcMySqlProvider.cs | 63 + .../MySql/OdbcMySqlUtils.cs | 112 ++ .../Oracle/Curd/OdbcOracleDelete.cs | 27 + .../Oracle/Curd/OdbcOracleInsert.cs | 211 ++ .../Oracle/Curd/OdbcOracleSelect.cs | 185 ++ .../Oracle/Curd/OdbcOracleUpdate.cs | 72 + .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 70 + .../OdbcOracleAdo/OdbcOracleConnectionPool.cs | 246 +++ .../Oracle/OdbcOracleCodeFirst.cs | 412 ++++ .../Oracle/OdbcOracleDbFirst.cs | 484 +++++ .../Oracle/OdbcOracleExpression.cs | 458 +++++ .../Oracle/OdbcOracleProvider.cs | 64 + .../Oracle/OdbcOracleUtils.cs | 111 ++ .../SqlServer/Curd/OdbcSqlServerDelete.cs | 105 + .../SqlServer/Curd/OdbcSqlServerInsert.cs | 164 ++ .../SqlServer/Curd/OdbcSqlServerSelect.cs | 310 +++ .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 148 ++ .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 79 + .../OdbcSqlServerConnectionPool.cs | 236 +++ .../SqlServer/OdbcSqlServerCodeFirst.cs | 415 ++++ .../SqlServer/OdbcSqlServerDbFirst.cs | 447 +++++ .../SqlServer/OdbcSqlServerExpression.cs | 438 +++++ .../SqlServer/OdbcSqlServerProvider.cs | 69 + .../SqlServer/OdbcSqlServerUtils.cs | 96 + .../FreeSql.Provider.Oracle.csproj | 2 +- .../OracleAdo/OracleConnectionPool.cs | 6 +- .../OracleExtensions.cs | 2 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../SqlServerUtils.cs | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- readme.md | 1 + 123 files changed, 31796 insertions(+), 112 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAdo/OracleAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs create mode 100644 Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj create mode 100644 Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index f177d568..be75e076 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -1,8 +1,8 @@ - + Exe - netcoreapp2.2 + netcoreapp2.1 diff --git a/Examples/benchmarker/benchmarker.csproj b/Examples/benchmarker/benchmarker.csproj index cc9dde90..958667bd 100644 --- a/Examples/benchmarker/benchmarker.csproj +++ b/Examples/benchmarker/benchmarker.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.2 + netcoreapp2.1 diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2438312c..bcc8a520 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.16 + 0.9.17 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 16674c11..33f771f1 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7b64f524..a336e1ce 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b7cf2d84..da660319 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index dab8e461..244abcd6 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj index 1085dbcd..314fab71 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj @@ -1,7 +1,7 @@ - + - netcoreapp2.2 + netcoreapp2.1 false diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj new file mode 100644 index 00000000..3e1c4df1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs new file mode 100644 index 00000000..78318541 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs @@ -0,0 +1,96 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlDeleteTest + { + + IDelete delete => g.mysql.Delete(); //�������� + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + + sql = g.mysql.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.mysql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //delete.Where(a => a.Id > 0).ExecuteDeleted(); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + + sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertTest.cs new file mode 100644 index 00000000..9eeecd86 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertTest.cs @@ -0,0 +1,162 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlInsertTest + { + + IInsert insert => g.mysql.Insert(); //�������� + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumInsertTb + { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumInserTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumInserTbType { str1, biggit, sum211 } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000'), (100, 'newtitle1', '0001-01-01 00:00:00.000'), (200, 'newtitle2', '0001-01-01 00:00:00.000'), (300, 'newtitle3', '0001-01-01 00:00:00.000'), (400, 'newtitle4', '0001-01-01 00:00:00.000'), (500, 'newtitle5', '0001-01-01 00:00:00.000'), (600, 'newtitle6', '0001-01-01 00:00:00.000'), (700, 'newtitle7', '0001-01-01 00:00:00.000'), (800, 'newtitle8', '0001-01-01 00:00:00.000'), (900, 'newtitle9', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Parse("2019-09-19 21:26:51.030") }).ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '2019-09-19 21:26:51.030')", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.mysql.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.mysql.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + + var id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + //insert.AppendData(items.First()).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000'), (100, 'newTitle1', '0001-01-01 00:00:00.000'), (200, 'newTitle2', '0001-01-01 00:00:00.000'), (300, 'newTitle3', '0001-01-01 00:00:00.000'), (400, 'newTitle4', '0001-01-01 00:00:00.000'), (500, 'newTitle5', '0001-01-01 00:00:00.000'), (600, 'newTitle6', '0001-01-01 00:00:00.000'), (700, 'newTitle7', '0001-01-01 00:00:00.000'), (800, 'newTitle8', '0001-01-01 00:00:00.000'), (900, 'newTitle9', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs new file mode 100644 index 00000000..3c3813b2 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -0,0 +1,1352 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + + public class MySqlSelectTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + public class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + [Column(OldName = "TypeGuid")] + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + + public virtual TopicFields Fields { get; set; } + } + public class TopicFields + { + [Column(IsPrimary = true)] + public int TopicId { get; set; } + public virtual Topic Topic { get; set; } + } + public class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + + public int ParentId { get; set; } + public virtual TestTypeParentInfo Parent { get; set; } + + public string Name { get; set; } + + public virtual ICollection Topics { get; set; } + } + public class TestTypeParentInfo + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.mysql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.mysql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.mysql.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.mysql.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, g.mysql.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, g.mysql.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.mysql.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + var testDto5 = select.Limit(10).ToList(); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + var t0 = select.Limit(50).ToList(); + + + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new + { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.mysql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.mysql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.mysql.Select().ToList(); + var testGuidId6 = g.mysql.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); + + var sql1 = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); + var sql2 = g.mysql.Select().Where(a => testenumWhereType.Blaaa == a.type).ToSql(); + + var sql3 = g.mysql.Select().Where(a => a.type.Equals(testenumWhereType.Blaaa)).ToSql(); + var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); + } + class testenumWhere + { + public Guid id { get; set; } + public testenumWhereType type { get; set; } + } + public enum testenumWhereType { Menu, Class, Blaaa } + + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid`", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TypeGuid` AND b.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` c ON c.`Id` = a__Type.`ParentId`", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfoAsTable` c ON b.`ParentId` = c.`Id`", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.mysql.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.mysql.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.mysql.Insert(model4s).ExecuteAffrows()); + + var t0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.mysql.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + + var t1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.mysql.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.mysql.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.mysql.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.mysql.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.mysql.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.mysql.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.mysql.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.mysql.Insert(song3).ExecuteIdentity(); + + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs new file mode 100644 index 00000000..8513b170 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -0,0 +1,210 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlUpdateTest + { + IUpdate update => g.mysql.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumUpdateTb + { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumUpdateTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumUpdateTbType { str1, biggit, sum211 } + + [Fact] + public void Dywhere() + { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = NULL, `Title` = 'newtitle', `CreateTime` = '0001-01-01 00:00:00.000' WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, `Title` = CASE `Id` WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, `CreateTime` = CASE `Id` WHEN 1 THEN '0001-01-01 00:00:00.000' WHEN 2 THEN '0001-01-01 00:00:00.000' WHEN 3 THEN '0001-01-01 00:00:00.000' WHEN 4 THEN '0001-01-01 00:00:00.000' WHEN 5 THEN '0001-01-01 00:00:00.000' WHEN 6 THEN '0001-01-01 00:00:00.000' WHEN 7 THEN '0001-01-01 00:00:00.000' WHEN 8 THEN '0001-01-01 00:00:00.000' WHEN 9 THEN '0001-01-01 00:00:00.000' WHEN 10 THEN '0001-01-01 00:00:00.000' END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = CASE `Id` WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `CreateTime` = '2020-01-01 00:00:00.000' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); + g.mysql.Update().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + id = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); + g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = 'newtitle' WHERE (`Id` = 1)", sql); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = 'newtitle' WHERE (`Id` = 1)", sql); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = 'newtitle' WHERE (`Id` = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = 'newtitle', `CreateTime` = '2020-01-01 00:00:00.000' WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 div 1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 div 1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 div 1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); + + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'biggit' WHERE (`id` = {id})", sql); + g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'str1' WHERE (`id` = {id})", sql); + g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET clicks = clicks + ? WHERE (`Id` = 1)", sql); + + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0).SetRaw("`type` = {0}".FormatOdbcMySql(TestEnumUpdateTbType.sum211)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) + .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var time = DateTime.Now; + var items222 = g.mysql.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..558f3745 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/BoolNullableTest.cs @@ -0,0 +1,1722 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/BoolTest.cs new file mode 100644 index 00000000..6c649102 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/BoolTest.cs @@ -0,0 +1,1130 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..732a597c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,62 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime?))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.mysql; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt, find.dtosnullable_to_dt); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt, find.dtosnullable_to_dt); + + item.dtosnullable_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/EnumTest.cs new file mode 100644 index 00000000..23c09d0a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/ToStringTest.cs new file mode 100644 index 00000000..8fe6fbc2 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs new file mode 100644 index 00000000..c22ff2f9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs @@ -0,0 +1,66 @@ +using FreeSql.DataAnnotations; +using System; +using System.Data.Odbc; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.mysql.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.mysql.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + var t3 = g.mysql.Ado.Query("select * from song"); + + var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + + var t5 = g.mysql.Ado.Query("select * from song"); + } + + [Fact] + public void QueryMultipline() + { + Assert.Throws(() => g.mysql.Ado.Query("select * from song; select * from song; select * from song")); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAopTest.cs new file mode 100644 index 00000000..4f2e731a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.mysql.Aop.AuditValue += audit; + + g.mysql.Insert(item).ExecuteAffrows(); + + g.mysql.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs new file mode 100644 index 00000000..b857909c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -0,0 +1,451 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlCodeFirstTest + { + + [Fact] + public void ı_ֶ() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<ı2>(); + g.mysql.CodeFirst.SyncStructure<ı2>(); + + var item = new ı2 + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.mysql.Insert<ı2>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı2 + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } + + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } + + [Fact] + public void AddField() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + + var id = g.mysql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int? Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title222 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( + `Id` INT(11) NOT NULL AUTO_INCREMENT, + `testFieldBool` BIT(1) NOT NULL, + `testFieldSByte` TINYINT(3) NOT NULL, + `testFieldShort` SMALLINT(6) NOT NULL, + `testFieldInt` INT(11) NOT NULL, + `testFieldLong` BIGINT(20) NOT NULL, + `testFieldByte` TINYINT(3) UNSIGNED NOT NULL, + `testFieldUShort` SMALLINT(5) UNSIGNED NOT NULL, + `testFieldUInt` INT(10) UNSIGNED NOT NULL, + `testFieldULong` BIGINT(20) UNSIGNED NOT NULL, + `testFieldDouble` DOUBLE NOT NULL, + `testFieldFloat` FLOAT NOT NULL, + `testFieldDecimal` DECIMAL(10,2) NOT NULL, + `testFieldTimeSpan` TIME NOT NULL, + `testFieldDateTime` DATETIME(3) NOT NULL, + `testFieldBytes` VARBINARY(255), + `testFieldString` VARCHAR(255), + `testFieldGuid` VARCHAR(36), + `testFieldBoolNullable` BIT(1), + `testFieldSByteNullable` TINYINT(3), + `testFieldShortNullable` SMALLINT(6), + `testFieldIntNullable` INT(11), + `testFielLongNullable` BIGINT(20), + `testFieldByteNullable` TINYINT(3) UNSIGNED, + `testFieldUShortNullable` SMALLINT(5) UNSIGNED, + `testFieldUIntNullable` INT(10) UNSIGNED, + `testFieldULongNullable` BIGINT(20) UNSIGNED, + `testFieldDoubleNullable` DOUBLE, + `testFieldFloatNullable` FLOAT, + `testFieldDecimalNullable` DECIMAL(10,2), + `testFieldTimeSpanNullable` TIME, + `testFieldDateTimeNullable` DATETIME(3), + `testFieldGuidNullable` VARCHAR(36), + `testFieldPoint` POINT, + `testFieldLineString` LINESTRING, + `testFieldPolygon` POLYGON, + `testFieldMultiPoint` MULTIPOINT, + `testFieldMultiLineString` MULTILINESTRING, + `testFieldMultiPolygon` MULTIPOLYGON, + `testFieldEnum1` ENUM('E1','E2','E3') NOT NULL, + `testFieldEnum1Nullable` ENUM('E1','E2','E3'), + `testFieldEnum2` SET('F1','F2','F3') NOT NULL, + `testFieldEnum2Nullable` SET('F1','F2','F3'), + PRIMARY KEY (`Id`) +) Engine=InnoDB; +", sql); + } + + sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.mysql.Insert(); + ISelect select => g.mysql.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = 255, + testFieldByteNullable = 127, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(-1), + testFieldDecimal = 99.99M, + testFieldDecimalNullable = 99.98M, + testFieldDouble = 999.99, + testFieldDoubleNullable = 999.98, + testFieldEnum1 = TableAllTypeEnumType1.e5, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 19.99F, + testFieldFloatNullable = 19.98F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldSByte = 100, + testFieldSByteNullable = 99, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "йstring", + testFieldTimeSpan = TimeSpan.FromSeconds(999), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + var enumConvInt = select.Where(a => a.Id == (int)TableAllTypeEnumType1.e1).ToSql(); + + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + + var items = select.ToList(); + } + + + [JsonObject(MemberSerialization.OptIn), Table(Name = "tb_alltype")] + public partial class Tb_alltype + { + + [JsonProperty, Column(Name = "Id", DbType = "int(11)", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + + [JsonProperty, Column(Name = "testFieldBool", DbType = "bit(1)")] + public bool TestFieldBool { get; set; } + + + [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit(1)", IsNullable = true)] + public bool? TestFieldBoolNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint(3) unsigned")] + public byte TestFieldByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint(3) unsigned", IsNullable = true)] + public byte? TestFieldByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] + public byte[] TestFieldBytes { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] + public DateTime TestFieldDateTime { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] + public DateTime? TestFieldDateTimeNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] + public decimal TestFieldDecimal { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] + public decimal? TestFieldDecimalNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDouble", DbType = "double")] + public double TestFieldDouble { get; set; } + + + [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "double", IsNullable = true)] + public double? TestFieldDoubleNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1", DbType = "enum('E1','E2','E3','E5')")] + public Tb_alltypeTESTFIELDENUM1 TestFieldEnum1 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "enum('E1','E2','E3','E5')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM1NULLABLE? TestFieldEnum1Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2", DbType = "set('F1','F2','F3')")] + public Tb_alltypeTESTFIELDENUM2 TestFieldEnum2 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "set('F1','F2','F3')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM2NULLABLE? TestFieldEnum2Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloat", DbType = "float")] + public float TestFieldFloat { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "float", IsNullable = true)] + public float? TestFieldFloatNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuid", DbType = "char(36)")] + public Guid TestFieldGuid { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "char(36)", IsNullable = true)] + public Guid? TestFieldGuidNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldInt", DbType = "int(11)")] + public int TestFieldInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int(11)", IsNullable = true)] + public int? TestFieldIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint(20)")] + public long TestFieldLong { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint(3)")] + public sbyte TestFieldSByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint(3)", IsNullable = true)] + public sbyte? TestFieldSByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint(6)")] + public short TestFieldShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint(6)", IsNullable = true)] + public short? TestFieldShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldString", DbType = "varchar(255)", IsNullable = true)] + public string TestFieldString { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] + public TimeSpan TestFieldTimeSpan { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] + public TimeSpan? TestFieldTimeSpanNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUInt", DbType = "int(10) unsigned")] + public uint TestFieldUInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int(10) unsigned", IsNullable = true)] + public uint? TestFieldUIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint(20) unsigned")] + public ulong TestFieldULong { get; set; } + + + [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint(20) unsigned", IsNullable = true)] + public ulong? TestFieldULongNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint(5) unsigned")] + public ushort TestFieldUShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint(5) unsigned", IsNullable = true)] + public ushort? TestFieldUShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint(20)", IsNullable = true)] + public long? TestFielLongNullable { get; set; } + + internal static IFreeSql mysql => null; + public static FreeSql.ISelect Select => mysql.Select(); + + public static long Delete(int Id) + { + var affrows = mysql.Delete().Where(a => a.Id == Id).ExecuteAffrows(); + return affrows; + } + + /// + /// ӣֵ UpdateӰΪ 0 Insert + /// + public void Save() + { + if (this.Id != default(int)) + { + var affrows = mysql.Update().Where(a => a.Id == Id).ExecuteAffrows(); + if (affrows > 0) return; + } + this.Id = (int)mysql.Insert().AppendData(this).ExecuteIdentity(); + } + + } + + public enum Tb_alltypeTESTFIELDENUM1 + { + E1 = 1, E2, E3, E5 + } + public enum Tb_alltypeTESTFIELDENUM1NULLABLE + { + E1 = 1, E2, E3, E5 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2 : long + { + F1 = 1, F2 = 2, F3 = 4 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2NULLABLE : long + { + F1 = 1, F2 = 2, F3 = 4 + } + + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs new file mode 100644 index 00000000..a12f5ab3 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.mysql.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); + + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/ConvertTest.cs new file mode 100644 index 00000000..7c8073ec --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlExpression +{ + public class ConvertTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs new file mode 100644 index 00000000..f2ed19a4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs @@ -0,0 +1,694 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlExpression +{ + public class DateTimeTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/MathTest.cs new file mode 100644 index 00000000..688f01f0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlExpression +{ + public class MathTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs new file mode 100644 index 00000000..7d5f4293 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs @@ -0,0 +1,136 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Data.Odbc; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlExpression +{ + public class OtherTest + { + + ISelect select => g.mysql.Select(); + + public OtherTest() + { + + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + int[] nullarr = null; + Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); + + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs new file mode 100644 index 00000000..ff5fb312 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs @@ -0,0 +1,729 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlExpression +{ + public class StringTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + public bool IsDeleted { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.mysql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/TimeSpanTest.cs new file mode 100644 index 00000000..ba124ea2 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySqlExpression +{ + public class TimeSpanTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs new file mode 100644 index 00000000..4683aeac --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs @@ -0,0 +1,98 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleDeleteTest + { + + IDelete delete => g.oracle.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.oracle.Delete().ToSql()); + var sql = g.oracle.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.oracle.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //var item = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.oracle.Delete().ToSql()); + var sql = g.oracle.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + + sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.oracle.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertTest.cs new file mode 100644 index 00000000..f149fca4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertTest.cs @@ -0,0 +1,278 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleInsertTest + { + + IInsert insert => g.oracle.Insert(); //�������� + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 22:25:38.697071") }); + + var data = new List(); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newtitle0', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6'))", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(0, 'newtitle0', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(100, 'newtitle1', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(200, 'newtitle2', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(300, 'newtitle3', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(400, 'newtitle4', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(500, 'newtitle5', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(600, 'newtitle6', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(700, 'newtitle7', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(800, 'newtitle8', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(900, 'newtitle9', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle0') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle1') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle2') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle3') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle4') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle5') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle6') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle7') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle8') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var data = new List(); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle0') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle1') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle2') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle3') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle4') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle5') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle6') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle7') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle8') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var data = new List(); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(100) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(200) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(300) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(400) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(500) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(600) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(700) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(800) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(900) + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.oracle.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.oracle.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicICs")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + //var items = new List(); + //for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //var items2 = insert.AppendData(items).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newTitle0', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6'))", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(0, 'newTitle0', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(100, 'newTitle1', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(200, 'newTitle2', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(300, 'newTitle3', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(400, 'newTitle4', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(500, 'newTitle5', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(600, 'newTitle6', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(700, 'newTitle7', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(800, 'newTitle8', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(900, 'newTitle9', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(0, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(100, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(200, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(300, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(400, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(500, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(600, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(700, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(800, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(900, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle9') + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle9') + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(0, 'newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(100, 'newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(200, 'newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(300, 'newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(400, 'newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(500, 'newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(600, 'newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(700, 'newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(800, 'newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(900, 'newTitle9') + SELECT 1 FROM DUAL", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs new file mode 100644 index 00000000..ac553fd0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -0,0 +1,1236 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleSelectTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.oracle.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.oracle.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.oracle.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.oracle.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.oracle.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.oracle.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.oracle.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.oracle.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now.ToString() }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + g.oracle.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.oracle.Select().ToList(); + var testGuidId6 = g.oracle.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = ?", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = ?", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = ?)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = ?)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.oracle.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.oracle.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.oracle.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.oracle.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.oracle.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.oracle.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.oracle.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.oracle.Insert(model4s).ExecuteAffrows()); + + var t0 = g.oracle.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.oracle.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.oracle.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.oracle.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.oracle.Insert(model1).ExecuteIdentity(); + + var t1 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.oracle.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.oracle.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.oracle.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.oracle.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.oracle.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.oracle.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.oracle.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.oracle.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.oracle.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.oracle.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.oracle.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.oracle.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.oracle.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.oracle.Insert(song3).ExecuteIdentity(); + + g.oracle.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.oracle.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs new file mode 100644 index 00000000..a91f7dee --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -0,0 +1,142 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleUpdateTest + { + IUpdate update => g.oracle.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.oracle.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL, \"TITLE\" = 'newtitle', \"CREATETIME\" = to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 2 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 3 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 4 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 5 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 6 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 7 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 8 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 9 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 10 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle', \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + ? WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.oracle.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..e2c5c4ee --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs @@ -0,0 +1,1596 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs new file mode 100644 index 00000000..decd881f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs @@ -0,0 +1,1130 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..34f84858 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.oracle; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/EnumTest.cs new file mode 100644 index 00000000..026c1b00 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/ToStringTest.cs new file mode 100644 index 00000000..759bc72c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAdo/OracleAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAdo/OracleAdoTest.cs new file mode 100644 index 00000000..419dac02 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAdo/OracleAdoTest.cs @@ -0,0 +1,66 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.oracle.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.oracle.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + + var t4 = g.oracle.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + + var t5 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAopTest.cs new file mode 100644 index 00000000..4d49ee2a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.oracle.Aop.AuditValue += audit; + + g.oracle.Insert(item).ExecuteAffrows(); + + g.oracle.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs new file mode 100644 index 00000000..f34d6754 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -0,0 +1,258 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleCodeFirstTest + { + + [Fact] + public void ı_ֶ() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<ı>(); + g.oracle.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.oracle.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + g.oracle.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } + + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + + var id = g.oracle.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.oracle.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar2(200 char) not null", OldName = "title")] + public string title2 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( + `Id` INT(11) NOT NULL AUTO_INCREMENT, + `Bool` BIT(1) NOT NULL, + `SByte` TINYINT(3) NOT NULL, + `Short` SMALLINT(6) NOT NULL, + `Int` INT(11) NOT NULL, + `Long` BIGINT(20) NOT NULL, + `Byte` TINYINT(3) UNSIGNED NOT NULL, + `UShort` SMALLINT(5) UNSIGNED NOT NULL, + `UInt` INT(10) UNSIGNED NOT NULL, + `ULong` BIGINT(20) UNSIGNED NOT NULL, + `Double` DOUBLE NOT NULL, + `Float` FLOAT NOT NULL, + `Decimal` DECIMAL(10,2) NOT NULL, + `TimeSpan` TIME NOT NULL, + `DateTime` DATETIME NOT NULL, + `Bytes` VARBINARY(255), + `String` VARCHAR(255), + `Guid` VARCHAR(36), + `BoolNullable` BIT(1), + `SByteNullable` TINYINT(3), + `ShortNullable` SMALLINT(6), + `IntNullable` INT(11), + `testFielLongNullable` BIGINT(20), + `ByteNullable` TINYINT(3) UNSIGNED, + `UShortNullable` SMALLINT(5) UNSIGNED, + `UIntNullable` INT(10) UNSIGNED, + `ULongNullable` BIGINT(20) UNSIGNED, + `DoubleNullable` DOUBLE, + `FloatNullable` FLOAT, + `DecimalNullable` DECIMAL(10,2), + `TimeSpanNullable` TIME, + `DateTimeNullable` DATETIME, + `GuidNullable` VARCHAR(36), + `Point` POINT, + `LineString` LINESTRING, + `Polygon` POLYGON, + `MultiPoint` MULTIPOINT, + `MultiLineString` MULTILINESTRING, + `MultiPolygon` MULTIPOLYGON, + `Enum1` ENUM('E1','E2','E3') NOT NULL, + `Enum1Nullable` ENUM('E1','E2','E3'), + `Enum2` SET('F1','F2','F3') NOT NULL, + `Enum2Nullable` SET('F1','F2','F3'), + PRIMARY KEY (`Id`) +) Engine=InnoDB; +", sql); + } + + //sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.oracle.Insert(); + ISelect select => g.oracle.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs new file mode 100644 index 00000000..9b12a2c7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.oracle.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.oracle.DbFirst.GetTablesByDatabase(); + //var tb = g.oracle.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/ConvertTest.cs new file mode 100644 index 00000000..d3cca76c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleExpression +{ + public class ConvertTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs new file mode 100644 index 00000000..2e566ddd --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs @@ -0,0 +1,706 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleExpression +{ + public class DateTimeTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/MathTest.cs new file mode 100644 index 00000000..f0c11a01 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleExpression +{ + public class MathTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs new file mode 100644 index 00000000..3b8ef42d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs @@ -0,0 +1,135 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleExpression +{ + public class OtherTest + { + + ISelect select => g.oracle.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs new file mode 100644 index 00000000..f645a2da --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs @@ -0,0 +1,726 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleExpression +{ + public class StringTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/TimeSpanTest.cs new file mode 100644 index 00000000..8507145d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.OracleExpression +{ + public class TimeSpanTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs new file mode 100644 index 00000000..28f22b21 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs @@ -0,0 +1,104 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerDeleteTest + { + IDelete delete => g.sqlserver.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.sqlserver.Delete().ToSql()); + var sql = g.sqlserver.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.sqlserver.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + var item = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + + var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }); + var itemsInserted = g.sqlserver.Insert(items).ExecuteInserted(); + Assert.Equal(items.First().Title, itemsInserted[0].Title); + + Assert.Equal(itemsInserted[0].Id, delete.Where(a => a.Id == itemsInserted[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.sqlserver.Delete().ToSql()); + var sql = g.sqlserver.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); + + sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.sqlserver.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertTest.cs new file mode 100644 index 00000000..c2fcaac4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertTest.cs @@ -0,0 +1,155 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerInsertTest + { + IInsert insert => g.sqlserver.Insert(); //�������� + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 20:09:37.328") }); + + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:09:37.328')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:09:37.328'), (100, N'newtitle1', '2019-09-19 20:09:37.328'), (200, N'newtitle2', '2019-09-19 20:09:37.328'), (300, N'newtitle3', '2019-09-19 20:09:37.328'), (400, N'newtitle4', '2019-09-19 20:09:37.328'), (500, N'newtitle5', '2019-09-19 20:09:37.328'), (600, N'newtitle6', '2019-09-19 20:09:37.328'), (700, N'newtitle7', '2019-09-19 20:09:37.328'), (800, N'newtitle8', '2019-09-19 20:09:37.328'), (900, N'newtitle9', '2019-09-19 20:09:37.328')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var sql = insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.sqlserver.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.sqlserver.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.sqlserver.Insert(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + + + //items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //var lastId = g.sqlite.Select().Max(a => a.Id); + //Assert.NotEqual(lastId, g.sqlserver.Insert(items).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var items2 = insert.AppendData(items).ExecuteInserted(); + + items = Enumerable.Range(0, 90).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + var itemsInserted = g.sqlserver.Insert(items).ExecuteInserted(); + Assert.Equal(items.First().Title, itemsInserted.First().Title); + Assert.Equal(items.Last().Title, itemsInserted.Last().Title); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 20:01:51.149") }); + + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:01:51.149')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:01:51.149'), (100, N'newtitle1', '2019-09-19 20:01:51.149'), (200, N'newtitle2', '2019-09-19 20:01:51.149'), (300, N'newtitle3', '2019-09-19 20:01:51.149'), (400, N'newtitle4', '2019-09-19 20:01:51.149'), (500, N'newtitle5', '2019-09-19 20:01:51.149'), (600, N'newtitle6', '2019-09-19 20:01:51.149'), (700, N'newtitle7', '2019-09-19 20:01:51.149'), (800, N'newtitle8', '2019-09-19 20:01:51.149'), (900, N'newtitle9', '2019-09-19 20:01:51.149')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.Title, a.TypeGuid }).InsertColumns(a => a.Title).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.Title, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs new file mode 100644 index 00000000..07051350 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -0,0 +1,1224 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerSelectTest + { + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.sqlserver.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 + //FROM [Tag] a + //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] + //LEFT JOIN [Tag] a__Parent__Parent ON a__Parent__Parent.[Id] = a__Parent.[Parent_id] + //WHERE (a__Parent__Parent.[Name] = '粤语') + + //OneToMany + var t1 = g.sqlserver.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] + //FROM [Tag] a + //WHERE (exists(SELECT 1 + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) + + //ManyToMany + var t2 = g.sqlserver.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] + //FROM [Song] a + //WHERE(exists(SELECT 1 + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.sqlserver.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.sqlserver.Select().Limit(10).ToList(); + + + } + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Single(g.sqlserver.Insert().AppendData(items.First()).ExecuteInserted()); + Assert.Equal(10, g.sqlserver.Insert().AppendData(items).ExecuteInserted().Count); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //; + //Assert.Equal(9989, g.sqlserver.Insert(items).NoneParameter().ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, getdate()"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + g.sqlserver.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.sqlserver.Select().ToList(); + var testGuidId6 = g.sqlserver.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid]", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] INNER JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] RIGHT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = N'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TypeGuid] AND b.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = N'typeTitle' AND b.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = N'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = ?)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = N'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = ?)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.sqlserver.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.sqlserver.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(Convert.ToInt64(a.Key.Id)), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic22 where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid]", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] c ON c.[Id] = a__Type.[ParentId]", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfoAsTable] c ON b.[ParentId] = c.[Id]", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.sqlserver.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.sqlserver.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.sqlserver.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.sqlserver.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.sqlserver.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.sqlserver.Insert(model4s).ExecuteAffrows()); + + var t0 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.sqlserver.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.sqlserver.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.sqlserver.Insert(model1).ExecuteIdentity(); + + var t1 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.sqlserver.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.sqlserver.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.sqlserver.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.sqlserver.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.sqlserver.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.sqlserver.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.sqlserver.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.sqlserver.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.sqlserver.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.sqlserver.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.sqlserver.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.sqlserver.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.sqlserver.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.sqlserver.Insert(song3).ExecuteIdentity(); + + g.sqlserver.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs new file mode 100644 index 00000000..cd9c2d37 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs @@ -0,0 +1,161 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerUpdateTest + { + IUpdate update => g.sqlserver.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.sqlserver.Update().ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL, [Title] = N'newtitle', [CreateTime] = '1970-01-01 00:00:00.000' WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, [Title] = CASE [Id] WHEN 1 THEN N'newtitle0' WHEN 2 THEN N'newtitle1' WHEN 3 THEN N'newtitle2' WHEN 4 THEN N'newtitle3' WHEN 5 THEN N'newtitle4' WHEN 6 THEN N'newtitle5' WHEN 7 THEN N'newtitle6' WHEN 8 THEN N'newtitle7' WHEN 9 THEN N'newtitle8' WHEN 10 THEN N'newtitle9' END, [CreateTime] = CASE [Id] WHEN 1 THEN '1970-01-01 00:00:00.000' WHEN 2 THEN '1970-01-01 00:00:00.000' WHEN 3 THEN '1970-01-01 00:00:00.000' WHEN 4 THEN '1970-01-01 00:00:00.000' WHEN 5 THEN '1970-01-01 00:00:00.000' WHEN 6 THEN '1970-01-01 00:00:00.000' WHEN 7 THEN '1970-01-01 00:00:00.000' WHEN 8 THEN '1970-01-01 00:00:00.000' WHEN 9 THEN '1970-01-01 00:00:00.000' WHEN 10 THEN '1970-01-01 00:00:00.000' END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN N'newtitle0' WHEN 2 THEN N'newtitle1' WHEN 3 THEN N'newtitle2' WHEN 4 THEN N'newtitle3' WHEN 5 THEN N'newtitle4' WHEN 6 THEN N'newtitle5' WHEN 7 THEN N'newtitle6' WHEN 8 THEN N'newtitle7' WHEN 9 THEN N'newtitle8' WHEN 10 THEN N'newtitle9' END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = '2020-01-01 00:00:00.000' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle', [CreateTime] = '2020-01-01 00:00:00.000' WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + ? WHERE ([Id] = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var time = DateTime.Now; + var items222 = g.sqlserver.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + + var items = g.sqlserver.Select().Limit(2).ToList(); + g.sqlserver.Update(items).SetRaw("title='test'").ExecuteUpdated(); + + items = g.sqlserver.Select().Limit(2).ToList(); + var result = g.sqlserver.Update(items).SetRaw("title='test'").ExecuteUpdatedAsync().Result; + } + + [Fact] + public void AsTable() + { + Assert.Null(g.sqlserver.Update().ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..328f733b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs @@ -0,0 +1,1597 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs new file mode 100644 index 00000000..b7ec3e4e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs @@ -0,0 +1,1130 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class BoolTest + { + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..d3e6ef76 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.sqlserver; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/EnumTest.cs new file mode 100644 index 00000000..05b770ea --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/EnumTest.cs @@ -0,0 +1,263 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class EnumTest + { + + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.sqlserver; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.sqlserver; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.sqlserver; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.sqlserver; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/ToStringTest.cs new file mode 100644 index 00000000..7bb83faf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/ToStringTest.cs @@ -0,0 +1,571 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs new file mode 100644 index 00000000..5dd43624 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -0,0 +1,96 @@ +using FreeSql.DataAnnotations; +using System; +using System.Data.Odbc; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.sqlserver.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.sqlserver.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + //var tt1 = g.sqlserver.Select() + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToSql(a => new { a.Id, a.Title }); + + //var tt2result = g.sqlserver.Select() + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToList(a => new { a.Id, a.Title }); + + //var tt = g.sqlserver.Select() + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToSql(a => new { a.Id, a.Title }); + + //var ttresult = g.sqlserver.Select() + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToList(a => new { a.Id, a.Title }); + + var tnsql1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + var tnsql2 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToSql(a => a.Id); + + var tn1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToList(a => a.Id); + var tn2 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToList(a => a.Id); + + var t3 = g.sqlserver.Ado.Query("select * from xxx"); + + var t4 = g.sqlserver.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); + + var t5 = g.sqlserver.Ado.Query(System.Data.CommandType.Text, "select * from xxx where Id = ?", + new OdbcParameter("@Id", 1)); + } + + [Fact] + public void QueryMultipline() + { + var tnsql1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + + var t3 = g.sqlserver.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + } + + class xxx + { + public int Id { get; set; } + public int ParentId { get; set; } + public xxx Parent { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime Create_time { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAopTest.cs new file mode 100644 index 00000000..fd0f8fff --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + public class SqlServerAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.sqlserver.Aop.AuditValue += audit; + + g.sqlserver.Insert(item).ExecuteAffrows(); + + g.sqlserver.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs new file mode 100644 index 00000000..8ebc109e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -0,0 +1,380 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + + [Collection("SqlServerCollection")] + public class SqlServerCodeFirstTest + { + [Fact] + public void ı_ֶ() + { + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements<ı>(); + g.sqlserver.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.sqlserver.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.sqlserver.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + + [Fact] + public void AddUniques() + { + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + g.sqlserver.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } + + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } + + [Fact] + public void AddField() + { + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + + var id = g.sqlserver.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } + + [Table(Name = "dbo2.TopicAddField", OldName = "tedb1.dbo.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int name { get; set; } = 3000; + + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title222 { get; set; } = "333"; + + [Column(DbType = "varchar(200) not null")] + public string title222333 { get; set; } = "xxx"; + + [Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] + public string titleaaa { get; set; } = "fsdf"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + + sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.sqlserver.Insert(); + ISelect select => g.sqlserver.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(1), + testFieldDateTimeNullableOffset = new DateTimeOffset(DateTime.Now.AddHours(1), TimeSpan.FromHours(8)), + testFieldDateTimeOffset = new DateTimeOffset(DateTime.Now, TimeSpan.FromHours(8)), + testFieldDecimal = 998.99M, + testFieldDecimalNullable = 999.12M, + testFieldDouble = 99.199, + testFieldDoubleNullable = 99.211, + testFieldEnum1 = TableAllTypeEnumType1.e2, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f3, + testFieldEnum2Nullable = TableAllTypeEnumType2.f2, + testFieldFloat = 0.99F, + testFieldFloatNullable = 0.11F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldLong = long.MaxValue, + testFieldSByte = sbyte.MaxValue, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "йstring", + testFieldTimeSpan = TimeSpan.FromSeconds(999), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(30), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); + + var sqlTestUpdate = g.sqlserver.Update().SetSource(item3NP).NoneParameter().ToSql(); + + var item3 = insert.AppendData(item2).ExecuteInserted(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + + var items = select.ToList(); + } + + [JsonObject(MemberSerialization.OptIn), Table(Name = "dbo.tb_alltype")] + public partial class Tb_alltype + { + + [JsonProperty, Column(Name = "Id", DbType = "int", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + + [JsonProperty, Column(Name = "testFieldBool1111", DbType = "bit")] + public bool TestFieldBool1111 { get; set; } + + + [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit", IsNullable = true)] + public bool? TestFieldBoolNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint")] + public sbyte TestFieldByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint", IsNullable = true)] + public sbyte? TestFieldByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] + public byte[] TestFieldBytes { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] + public DateTime TestFieldDateTime { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] + public DateTime? TestFieldDateTimeNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeNullableOffset", DbType = "datetimeoffset", IsNullable = true)] + public DateTime? TestFieldDateTimeNullableOffset { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeOffset", DbType = "datetimeoffset")] + public DateTime TestFieldDateTimeOffset { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] + public decimal TestFieldDecimal { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] + public decimal? TestFieldDecimalNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDouble", DbType = "float")] + public double TestFieldDouble { get; set; } + + + [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "float", IsNullable = true)] + public double? TestFieldDoubleNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1", DbType = "int")] + public int TestFieldEnum1 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "int", IsNullable = true)] + public int? TestFieldEnum1Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2", DbType = "bigint")] + public long TestFieldEnum2 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "bigint", IsNullable = true)] + public long? TestFieldEnum2Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloat", DbType = "real")] + public float TestFieldFloat { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "real", IsNullable = true)] + public float? TestFieldFloatNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuid", DbType = "uniqueidentifier")] + public Guid TestFieldGuid { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "uniqueidentifier", IsNullable = true)] + public Guid? TestFieldGuidNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldInt", DbType = "int")] + public int TestFieldInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int", IsNullable = true)] + public int? TestFieldIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint")] + public long TestFieldLong { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint")] + public sbyte TestFieldSByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint", IsNullable = true)] + public sbyte? TestFieldSByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint")] + public short TestFieldShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint", IsNullable = true)] + public short? TestFieldShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldString", DbType = "nvarchar(255)", IsNullable = true)] + public string TestFieldString { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] + public TimeSpan TestFieldTimeSpan { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] + public TimeSpan? TestFieldTimeSpanNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUInt", DbType = "int")] + public int TestFieldUInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int", IsNullable = true)] + public int? TestFieldUIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint")] + public long TestFieldULong { get; set; } + + + [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint", IsNullable = true)] + public long? TestFieldULongNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint")] + public short TestFieldUShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint", IsNullable = true)] + public short? TestFieldUShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint", IsNullable = true)] + public long? TestFielLongNullable { get; set; } + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + [Column(Name = "testFieldBool1111")] + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public DateTimeOffset testFieldDateTimeOffset { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs new file mode 100644 index 00000000..c52f6e28 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs @@ -0,0 +1,26 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.sqlserver.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(); + + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/ConvertTest.cs new file mode 100644 index 00000000..d60aa45d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class ConvertTest + { + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + //data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + //data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.NewGuid().ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs new file mode 100644 index 00000000..ab4708bc --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -0,0 +1,322 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class DateTimeTest + { + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/MathTest.cs new file mode 100644 index 00000000..1f26d0db --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class MathTest + { + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + //data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + //data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + //data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs new file mode 100644 index 00000000..a4e1494e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs @@ -0,0 +1,130 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class OtherTest + { + + ISelect select => g.sqlserver.Select(); + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + [Column(Name = "testFieldBool1111")] + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public DateTimeOffset testFieldDateTimeOffset { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs new file mode 100644 index 00000000..4954105c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs @@ -0,0 +1,290 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class StringTest + { + + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + } + [Fact] + public void PadLeft() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + } + [Fact] + public void PadRight() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void CompareTo() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/TimeSpanTest.cs new file mode 100644 index 00000000..aed158c6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/TimeSpanTest.cs @@ -0,0 +1,210 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class TimeSpanTest + { + + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs new file mode 100644 index 00000000..d6c8286a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -0,0 +1,1081 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.Collections; +using System.Diagnostics; +using System.ComponentModel.DataAnnotations; +using System.Reflection; + +namespace FreeSql.Tests.Odbc +{ + public static class SqlFunc + { + public static T TryTo(this string that) + { + return (T)Internal.Utils.GetDataReaderValue(typeof(T), that); + } + + public static string FormatDateTime() + { + return ""; + } + } + + public class UnitTest1 + { + + public class Order + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string OrderTitle { get; set; } + public string CustomerName { get; set; } + public DateTime TransactionDate { get; set; } + public virtual List OrderDetails { get; set; } + } + public class OrderDetail + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int OrderId { get; set; } + public virtual Order Order { get; set; } + } + + ISelect select => g.mysql.Select(); + + class TestUser + { + [Column(IsIdentity = true)] + public int stringid { get; set; } + public string accname { get; set; } + public LogUserOn LogOn { get; set; } + + } + class LogUserOn + { + public int id { get; set; } + public int userstrId { get; set; } + } + + class ServiceRequestNew + { + public Guid id { get; set; } + public string acptStaffDeptId { get; set; } + public DateTime acptTime { get; set; } + public int crtWrkfmFlag { get; set; } + [Column(DbType = "nvarchar2(1500)")] + public string srvReqstCntt { get; set; } + } + + public class Model1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public string title { get; set; } + + public ICollection Childs { get; set; } + + public int M2Id { get; set; } + + [Column(IsIgnore = true)] + public List TestManys { get; set; } + + } + + public class Model2 + { + + [Column(IsIdentity = true)] + public int id { get; set; } + public string Title { get; set; } + + public Model1 Parent { get; set; } + public int Parent_id { get; set; } + + public string Ccc { get; set; } + public DateTime Date { get; set; } + + [Column(Name = "Waxxx2")] + public int Wa_xxx2 { get; set; } + } + + public class TestEnumable : IEnumerable + { + public IEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } + } + + public class TestEnum + { + public Guid id { get; set; } + public Enum em { get; set; } + } + + /// + /// + /// + [Table(Name = "news_article")] + public class NewsArticle + { + /// + /// + /// + [Column(Name = "article_id", IsIdentity = true, IsPrimary = true)] + public int ArticleId { get; set; } + + /// + /// + /// + [Column(Name = "article_title")] + public string ArticleTitle { get; set; } + + /// + /// + /// + [Column(Name = "category_id")] + public int CategoryId { get; set; } + + /// + /// + /// + [Column(Name = "channel_id")] + public int ChannelId { get; set; } + + /// + /// 类型 + /// + [Column(Name = "type_id")] + public int TypeId { get; set; } + + /// + /// 内容简介 + /// + [Column(Name = "summary")] + public string Summary { get; set; } + + /// + /// 缩略图 + /// + [Column(Name = "thumbnail")] + public string Thumbnail { get; set; } + + /// + /// 点击量 + /// + [Column(Name = "hits")] + public int Hits { get; set; } + + /// + /// + /// + [Column(Name = "is_display")] + public int IsDisplay { get; set; } + + /// + /// + /// + [Column(Name = "status")] + public int Status { get; set; } + + /// + /// + /// + [Column(Name = "create_time")] + public int CreateTime { get; set; } + + /// + /// + /// + [Column(Name = "release_time")] + public int ReleaseTime { get; set; } + + public DateTime testaddtime { get; set; } + public DateTime? testaddtime2 { get; set; } + } + + public class NewsArticleDto : NewsArticle + { + + } + + + public class TaskBuildInfo + { + [FreeSql.DataAnnotations.Column(IsPrimary = true)] + public Guid Id { get; set; } + public Guid TbId { get; set; } + public Guid DataBaseConfigId { get; set; } + public string Name { get; set; } + public int Level { get; set; } + + [Column(IsIgnore = true)] + public virtual TaskBuild TaskBuild { get; set; } + } + public class Templates + { + /// + /// 测试中文重命名id + /// + [Column(IsPrimary = true, OldName = "Id")] + public Guid Id2 { get; set; } + public string Title { get; set; } + public DateTime AddTime { get; set; } = DateTime.Now; + public DateTime EditTime { get; set; } + public string Code { get; set; } + } + public class TaskBuild + { + + [FreeSql.DataAnnotations.Column(IsPrimary = true)] + public Guid Id { get; set; } + public string TaskName { get; set; } + public Guid TemplatesId { get; set; } + public string GeneratePath { get; set; } + public string FileName { get; set; } + public string NamespaceName { get; set; } + public bool OptionsEntity01 { get; set; } = false; + public bool OptionsEntity02 { get; set; } = false; + public bool OptionsEntity03 { get; set; } = false; + public int OptionsEntity04 { get; set; } + public int? score { get; set; } + + [Navigate("TbId")] + public virtual ICollection Builds { get; set; } + public Templates Templates { get; set; } + + public TaskBuild Parent { get; set; } + } + + + + void parseExp(object sender, Aop.ParseExpressionEventArgs e) + { + if (e.Expression.NodeType == ExpressionType.Call) + { + var callExp = e.Expression as MethodCallExpression; + if (callExp.Object == null && callExp.Arguments.Any() && callExp.Arguments[0].Type == typeof(string)) + { + if (callExp.Method.Name == "TryTo") + { + e.Result = Expression.Lambda( + typeof(Func<>).MakeGenericType(callExp.Method.GetGenericArguments().FirstOrDefault()), + e.Expression).Compile().DynamicInvoke()?.ToString(); + return; + } + } + } + } + + public class Class1 + { + [Column(IsIdentity = true)] + public long ID { set; get; } + + [Column(IsIdentity = true, OldName = "stu_id_log")] + public long stu_id { set; get; } + /// + /// 姓名 + /// + public string name { set; get; } + + public int age { set; get; } + + public DateTime class2 { set; get; } + } + + class TestDto + { + public Guid Id { get; set; } + public bool IsLeaf { get; set; } + } + + public static int GetUNIX_TIMESTAMP() => 0; + + + [Table(Name = "bz_web_post")] + public class Post + { + public int Id { get; set; } + public int AuthorId { get; set; } + [Navigate("AuthorId")] + public AuthorTest Author { get; set; } + } + [Table(Name = "bz_web_authortest")] + public class AuthorTest + { + public int Id { get; set; } + public string Name { get; set; } + [Navigate("AuthorId")] + public List Post { get; set; } + } + + [Fact] + public void Test1() + { + + using (var conn = g.oracle.Ado.MasterPool.Get()) { + var cmd = conn.Value.CreateCommand(); + cmd.CommandText = @"SELECT a.""ID"" as1, a__Type.""NAME"" as2 +FROM ""TB_TOPIC22"" a +LEFT JOIN ""TESTTYPEINFO"" a__Type ON a__Type.""GUID"" = a.""TYPEGUID"" +WHERE ROWNUM < 11"; + var dr = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection); + + var eof = dr.Read(); + + dr.Close(); + } + + + var ttt = g.oracle.Select().ToList(); + + + var testrunsql1 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testrunsql3 = g.sqlserver.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testrunsql4 = g.oracle.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + + var testssargs1 = "10100"; + var testformatsql1 = g.mysql.Select().Where(a => a.NamespaceName == $"1_{10100}").ToSql(); + var testorderbysql = g.mysql.Select().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql(); + + var floorSql1 = g.mysql.Select().Where(a => a.OptionsEntity04 / 10000 == 121212 / 10000).ToSql(); + var floorSql2 = g.mysql.Select().Where(a => a.OptionsEntity04 / 10000.0 == 121212 / 10000).ToSql(); + + var testBoolSql1 = g.sqlserver.Select().Where(a => a.OptionsEntity01).ToSql(); + var testBoolSql2 = g.sqlserver.Select().Where(a => a.Id == Guid.NewGuid() && a.OptionsEntity01).ToSql(); + + //g.mysql.Aop.AuditValue += (s, e) => + //{ + // if (e.Column.CsType == typeof(long) + // && e.Property.GetCustomAttribute(false) != null + // && e.Value?.ToString() == "0") + // e.Value = new Random().Next(); + //}; + //g.mysql.GetRepository().Insert(GetSystemUser()); + + g.mysql.Aop.ParseExpression += new EventHandler((s, e) => + { + if (e.Expression.NodeType == ExpressionType.Call && (e.Expression as MethodCallExpression).Method.Name == "GetUNIX_TIMESTAMP") + e.Result = "UNIX_TIMESTAMP(NOW())"; + }); + var dkkdksdjgj = g.mysql.Select().Where(a => a.OptionsEntity04 > GetUNIX_TIMESTAMP()).ToSql(); + + var dt1970 = new DateTime(1970, 1, 1); + var dkkdksdjgj22 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.Subtract(dt1970).TotalSeconds).ToSql(); + + + var xxxkdkd = g.oracle.Select() + .InnerJoin((a,b) => true) + .Where((a,b) => (DateTime.Now - a.EditTime).TotalMinutes > 100) + .OrderBy((a,b) => g.oracle.Select().Where(c => b.Id == c.Id2).Count()) + .ToSql(); + + + g.oracle.Aop.SyncStructureAfter += (s, e) => + Trace.WriteLine(e.Sql); + + g.oracle.CodeFirst.SyncStructure(); + + //g.mysql.Aop.ParseExpression += parseExp; + + //var sqdddd2 = g.mysql.Select().ToSql(t => t.OptionsEntity04 == t.NamespaceName.TryTo()); + + var sqksdkfjl = g.mysql.Select() + .LeftJoin(a => a.Templates.Id2 == a.TemplatesId) + .LeftJoin(a => a.Parent.Id == a.Id) + .LeftJoin(a => a.Parent.Templates.Id2 == a.Parent.TemplatesId) + .ToSql(a => new + { + code1 = a.Templates.Code, + code2 = a.Parent.Templates.Code + }); + + + var sqksdkfjl2223 = g.mysql.Select().From((s1, tb2, b1, b2) => s1 + .LeftJoin(a => a.Id == tb2.TemplatesId) + .LeftJoin(a => a.TemplatesId == b1.Id2) + .LeftJoin(a => a.TemplatesId == b2.Id2) + ).ToSql((a, tb2, b1, b2) => new + { + code1 = b1.Code, + code2 = b2.Code + }); + + var tkdkdksql = g.mysql.Select().From((a, b, c) => + a.LeftJoin(aa => aa.TemplatesId == b.Id2 && b.Code == "xx") + .LeftJoin(aa => aa.TemplatesId == c.Id2)) + .GroupBy((a, b, c) => new { a.NamespaceName, c.Code }) + .ToSql("a.id"); + + + + var dcksdkdsk = g.mysql.Select().Where(a => a.testaddtime2.HasValue).ToSql(); + var dcksdkdsk2 = g.mysql.Select().Where(a => !a.testaddtime2.HasValue).ToSql(); + + var testgrpsql = g.mysql.Select() + .From((a, b) => a.InnerJoin(aa => aa.TemplatesId + == b.Id2)) + .GroupBy((a, b) => b.Code) + .ToSql(a => new + { + a.Key, + sss = a.Sum(a.Value.Item1.OptionsEntity04) + }); + + var testgrpsql2 = g.mysql.Select() + .From((a, b) => a.InnerJoin(aa => aa.TemplatesId + == b.Id2)) + .GroupBy((a, b) => b.Code) + .ToList(a => new + { + a.Key, + sss = a.Sum(a.Value.Item1.OptionsEntity04) + }); + + + var tbid = g.mysql.Select().First()?.Id ?? Guid.Empty; + + var testarray = new[] { 1, 2, 3 }; + var tbidsql1 = g.mysql.Update().Where(a => a.Id == tbid) + .Set(a => new TaskBuild + { + FileName = "111", + TaskName = a.TaskName + "333", + OptionsEntity02 = false, + OptionsEntity04 = testarray[0] + }).ToSql(); + var tbidsql2 = g.mysql.Update().Where(a => a.Id == tbid) + .Set(a => new + { + FileName = "111", + TaskName = a.TaskName + "333", + OptionsEntity02 = false, + OptionsEntity04 = testarray[0] + }).ToSql(); + + + var dkdkdkd = g.oracle.Select().ToList(); + + + + //var testaddlist = new List(); + //for(var a = 0; a < 133905; a++) { + // testaddlist.Add(new NewsArticle { + // ArticleTitle = "testaddlist_topic" + a, + // Hits = a, + // }); + //} + //g.mysql.Insert(testaddlist) + // //.NoneParameter() + // .ExecuteAffrows(); + + + g.mysql.Aop.ParseExpression = (s, e) => + { + if (e.Expression.NodeType == ExpressionType.Call) + { + var callExp = e.Expression as MethodCallExpression; + if (callExp.Object?.Type == typeof(DateTime) && + callExp.Method.Name == "ToString" && + callExp.Arguments.Count == 1 && + callExp.Arguments[0].Type == typeof(string) && + callExp.Arguments[0].NodeType == ExpressionType.Constant) + { + var format = (callExp.Arguments[0] as ConstantExpression)?.Value?.ToString(); + + if (string.IsNullOrEmpty(format) == false) + { + var tmp = e.FreeParse(callExp.Object); + + switch (format) + { + case "yyyy-MM-dd HH:mm": + tmp = $"date_format({tmp}, '%Y-%m-%d %H:%i')"; + break; + } + e.Result = tmp; + } + } + } + }; + + g.mysql.Select().ToList(a => new + { + testaddtime = a.testaddtime.ToString("yyyy-MM-dd HH:mm") + }); + + var ttdkdk = g.mysql.Select().Where(a => a.NamespaceName == "ddd").ToSql(); + + var tsqlddd = g.mysql.Select().Where(a => + g.mysql.Select().Where(b => b.NamespaceName == a.ArticleTitle) + .Where("@id=1", new { id = 1 }).Any() + ).ToSql(); + + + g.mysql.SetDbContextOptions(opt => opt.EnableAddOrUpdateNavigateList = true); + var trepo = g.mysql.GetGuidRepository(); + trepo.Insert(new TaskBuild + { + TaskName = "tt11", + Builds = new[] { + new TaskBuildInfo { + Level = 1, + Name = "t111_11" + } + } + }); + + var ttdkdkd = trepo.Select.Where(a => a.Builds.AsSelect().Any()).ToList(); + + var list1113233 = trepo.Select.ToList(); + + + var entity = new NewsArticle + { + ArticleId = 1, + ArticleTitle = "测试标题" + }; + var where = new NewsArticle + { + ArticleId = 1, + ChannelId = 1, + }; + + g.mysql.Insert(new[] { entity }).ExecuteAffrows(); + + var sqldddkdk = g.mysql.Update(where) + .SetSource(entity) + .UpdateColumns(x => new { x.Status, x.CategoryId, x.ArticleTitle }) + .ToSql(); + + var sqldddklist = g.mysql.Select().Select(a => new NewsArticleDto { }).ToList(); + + + var sql1111333 = g.mysql.Update() + .SetSource(new Model2 { id = 1, Title = "xxx", Parent_id = 0 }) + .UpdateColumns(x => new { x.Parent_id, x.Date, x.Wa_xxx2 }) + .NoneParameter() + .ToSql(); + + + g.mysql.Insert(new TestEnum { }).ExecuteAffrows(); + var telist = g.mysql.Select().ToList(); + + Assert.Throws(() => g.mysql.CodeFirst.SyncStructure()); + + var TestEnumable = new TestEnumable(); + + + g.mysql.GetRepository().Insert(new Model1 + { + title = "test_" + DateTime.Now.ToString("yyyyMMddHHmmss"), + M2Id = DateTime.Now.Second + DateTime.Now.Minute, + Childs = new[] { + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0001", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0002", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0003", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0004", + } + } + }); + + var includet1 = g.mysql.Select() + .IncludeMany(a => a.Childs.Take(2), s => s.Where(a => a.id > 0)) + .IncludeMany(a => a.TestManys.Take(1).Where(b => b.id == a.id)) + .Where(a => a.id > 10) + .ToList(); + + var ttt1 = g.mysql.Select().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList(); + + var linqto1 = + from p in g.mysql.Select() + where p.Id >= 0 + // && p.OrderDetails.AsSelect().Where(c => c.Id > 10).Any() + orderby p.Id descending + orderby p.CustomerName ascending + select new { Name = p.CustomerName, Length = p.Id }; + + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Parent.Id) + }); + + var sqlrepos = g.mysql.GetRepository(); + sqlrepos.Insert(new TestTypeParentInfo + { + Name = "testroot", + Childs = new[] { + new TestTypeParentInfo { + Name = "testpath2", + Childs = new[] { + new TestTypeParentInfo { + Name = "testpath3", + Childs = new[] { + new TestTypeParentInfo { + Name = "11" + } + } + } + } + } + } + }); + + var sql = g.mysql.Select().Where(a => a.Parent.Parent.Parent.Name == "testroot").ToSql(); + var sql222 = g.mysql.Select().Where(a => a.Parent.Parent.Parent.Name == "testroot").ToList(); + + + Expression> orderBy = null; + orderBy = a => a.CreateTime; + var testsql1 = select.OrderBy(orderBy).ToSql(); + + orderBy = a => a.Title; + + var testsql2 = select.OrderBy(orderBy).ToSql(); + + + var testjson = @"[ +{ +""acptNumBelgCityName"":""泰州"", +""concPrsnName"":""常**"", +""srvReqstTypeName"":""家庭业务→网络质量→家庭宽带→自有宽带→功能使用→游戏过程中频繁掉线→全局流转"", +""srvReqstCntt"":""客户来电表示宽带使用( 所有)出现(频繁掉线不稳定) ,客户所在地址为(安装地址泰州地区靖江靖城街道工农路科技小区科技3区176号2栋2单元502),联系方式(具体联系方式),烦请协调处理。"", +""acptTime"":""2019-04-15 15:17:05"", +""acptStaffDeptId"":""0003002101010001000600020023"" +}, +{ +""acptNumBelgCityName"":""苏州"", +""concPrsnName"":""龚**"", +""srvReqstTypeName"":""移动业务→基础服务→账/详单→全局流转→功能使用→账/详单信息不准确→全局流转"", +""srvReqstCntt"":""用户参与 2018年苏州任我用关怀活动 送的分钟数500分钟,说自己只使用了116分钟,但是我处查询到本月已经使用了306分钟\r\n,烦请处理"", +""acptTime"":""2019-04-15 15:12:05"", +""acptStaffDeptId"":""0003002101010001000600020023"" +} +]"; + //var dic = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); + var reqs = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); + reqs.ForEach(t => + { + g.oracle.Insert(t).ExecuteAffrows(); + + }); + + + + var sql111 = g.mysql.Select().AsTable((a, b) => "(select * from TestUser where stringid > 10)").Page(1, 10).ToSql(); + + + var xxx = g.mysql.Select().GroupBy(a => new { a.stringid }).ToList(a => a.Key.stringid); + + var tuser = g.mysql.Select().Where(u => u.accname == "admin") + .InnerJoin(a => a.LogOn.id == a.stringid).ToSql(); + + + var parentSelect1 = select.Where(a => a.Type.Parent.Parent.Parent.Parent.Name == "").Where(b => b.Type.Name == "").ToSql(); + + + var collSelect1 = g.mysql.Select().Where(a => + a.OrderDetails.AsSelect().Any(b => b.Id > 100) + ); + + var collectionSelect = select.Where(a => + //a.Type.Guid == a.TypeGuid && + //a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + //b => b.ParentId == a.Type.Parent.Id + ) + ); + + var collectionSelect2 = select.Where(a => + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + b => b.Parent.Name == "xxx" && b.Parent.Parent.Name == "ccc" + && b.Parent.Parent.Parent.Types.AsSelect().Any(cb => cb.Name == "yyy") + ) + ); + + var collectionSelect3 = select.Where(a => + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + bbb => bbb.Parent.Types.AsSelect().Where(lv2 => lv2.Name == bbb.Name + "111").Any( + ) + ) + ); + + + var neworder = new Order + { + CustomerName = "testCustomer", + OrderTitle = "xxx#cccksksk", + TransactionDate = DateTime.Now, + OrderDetails = new List(new[] { + new OrderDetail { + + }, + new OrderDetail { + + } + }) + }; + + g.mysql.GetRepository().Insert(neworder); + + var order = g.mysql.Select().Where(a => a.Id == neworder.Id).ToOne(); //查询订单表 + if (order == null) + { + var orderId = g.mysql.Insert(new Order { }).ExecuteIdentity(); + order = g.mysql.Select(orderId).ToOne(); + } + + + var orderDetail1 = order.OrderDetails; //第一次访问,查询数据库 + var orderDetail2 = order.OrderDetails; //第二次访问,不查 + var order1 = orderDetail1.FirstOrDefault().Order; //访问导航属性,此时不查数据库,因为 OrderDetails 查询出来的时候已填充了该属性 + + + var queryable = g.mysql.Queryable().Where(a => a.Id == 1).ToList(); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any() + ).ToList(); + + + var groupbysql = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(false, a => a.Id == 2) + ) + .WhereIf(true, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()).ToSql(a => new + { + cou = a.Sum(a.Value.Item1.Id), + a.Key.mod4, + a.Key.tt2, + max = a.Max("a.id"), + max2 = Convert.ToInt64("max(a.id)") + }); + + var groupbysql2 = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(true, a => a.Id == 2) + ) + .WhereIf(false, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()).ToSql(a => a.Key.mod4); + + var groupby = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(true, a => a.Id == 2) + ) + .WhereIf(true, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + empty = "", + nil = (string)null, + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + }); + + var arrg = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + + var arrg222 = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToList(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToList(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToList(); + + //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToList(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")) + .ToList((a, b, c) => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToList(); + + + + + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToList(); + + + + + + //((JoinType.LeftJoin, a.TypeGuid == b.Guid), (JoinType.InnerJoin, b.ParentId == c.Id) + + var t11112 = g.mysql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + var t3 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => a.Title).ToSql(); + var t4 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + var t5 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => new { a.Title, a.TypeGuid, a.CreateTime }).ToSql(); + var t6 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).InsertColumns(a => new { a.Title }).ToSql(); + + var t7 = g.mysql.Update().ToSql(); + var t8 = g.mysql.Update().Where(new TestInfo { }).ToSql(); + var t9 = g.mysql.Update().Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t10 = g.mysql.Update().Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t11 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).ToSql(); + var t12 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Where(a => a.Title == "111").ToSql(); + + var t13 = g.mysql.Update().Set(a => a.Title, "222111").ToSql(); + var t14 = g.mysql.Update().Set(a => a.Title, "222111").Where(new TestInfo { }).ToSql(); + var t15 = g.mysql.Update().Set(a => a.Title, "222111").Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t16 = g.mysql.Update().Set(a => a.Title, "222111").Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t17 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.Title, "222111").ToSql(); + var t18 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.Title, "222111").Where(a => a.Title == "111").ToSql(); + + var t19 = g.mysql.Update().Set(a => a.TypeGuid + 222111).ToSql(); + var t20 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new TestInfo { }).ToSql(); + var t21 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t22 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t23 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.TypeGuid + 222111).ToSql(); + var t24 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.TypeGuid + 222111).Where(a => a.Title == "111").ToSql(); + + + var t1000 = g.mysql.Select().ToSql(); + var t1001 = g.mysql.Insert().AppendData(new ExamPaper()).ToSql(); + } + } + class NullAggreTestTable + { + [Column(IsIdentity = true)] + public int Id { get; set; } + } + + + [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] + class TestInfo + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Table(Name = "TestTypeInfoT1")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + + [Table(Name = "TestTypeParentInfoT1")] + class TestTypeParentInfo + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public ICollection Childs { get; set; } + + public List Types { get; set; } + } + + + /// + /// 试卷表 + /// + [Table(Name = "exam_paper")] + public class ExamPaper + { + + public long id { get; set; } + + /// + /// 考核计划ID + /// + public long AssessmentPlanId { get; set; } + /// + /// 总分 + /// + public int TotalScore { get; set; } + + public DateTime BeginTime { get; set; } + + public DateTime? EndTime { get; set; } + + //[Column(IsIgnore = true)] + //public ExamStatus Status { get; set; } + public ExamStatus Status + { + get + { + if (DateTime.Now <= BeginTime) + return ExamStatus.Wait; + if (BeginTime <= DateTime.Now && (!EndTime.HasValue || DateTime.Now < EndTime)) + return ExamStatus.Started; + if (BeginTime <= DateTime.Now && (EndTime.HasValue && EndTime <= DateTime.Now)) + return ExamStatus.End; + return ExamStatus.Wait; + } + } + } + public enum ExamStatus { Wait, Started, End } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs new file mode 100644 index 00000000..bee62577 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + + +public class g +{ + static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.OdbcMySql, "Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Max pool size=2") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .UseLazyLoading(true) + .Build()); + public static IFreeSql mysql => mysqlLazy.Value; + + static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.OdbcSqlServer, "Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Max pool size=3") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .UseLazyLoading(true) + .Build()); + public static IFreeSql sqlserver => sqlserverLazy.Value; + + static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.OdbcOracle, "Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseSyncStructureToUpper(true) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql oracle => oracleLazy.Value; +} diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 6f593095..7f5a4d02 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -9,6 +9,31 @@ 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert + + + 用户Id + + + + + 人脸Id + + + + + 创建时间 + + + + + 创建时间 + + + + + 相似度 + + diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index a7fa43f3..6efd2d1e 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -12,14 +12,8 @@ public class g .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=2") .UseAutoSyncStructure(true) .UseMonitorCommand( - cmd => - { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => - { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) .UseLazyLoading(true) .Build()); public static IFreeSql mysql => mysqlLazy.Value; @@ -33,14 +27,8 @@ public class g .UseSyncStructureToLower(true) .UseLazyLoading(true) .UseMonitorCommand( - cmd => - { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => - { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) .Build(); }); public static IFreeSql pgsql => pgsqlLazy.Value; @@ -49,14 +37,8 @@ public class g .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") .UseAutoSyncStructure(true) .UseMonitorCommand( - cmd => - { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => - { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) .UseLazyLoading(true) .Build()); public static IFreeSql sqlserver => sqlserverLazy.Value; @@ -69,14 +51,8 @@ public class g //.UseNoneCommandParameter(true) .UseMonitorCommand( - cmd => - { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => - { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) .Build()); public static IFreeSql oracle => oracleLazy.Value; @@ -85,14 +61,8 @@ public class g .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseMonitorCommand( - cmd => - { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => - { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) .Build()); public static IFreeSql sqlite => sqliteLazy.Value; } diff --git a/FreeSql.sln b/FreeSql.sln index 42ee6d17..1d8b4c4c 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -60,6 +60,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.BaseEnti EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.JsonMap", "Extensions\FreeSql.Extensions.JsonMap\FreeSql.Extensions.JsonMap.csproj", "{3043DEF1-85DF-47AD-8D5D-327270794356}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Odbc", "Providers\FreeSql.Provider.Odbc\FreeSql.Provider.Odbc.csproj", "{C57444BA-8BF7-4790-A864-7F237123219B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Odbc", "FreeSql.Tests\FreeSql.Tests.Provider.Odbc\FreeSql.Tests.Provider.Odbc.csproj", "{FA5667B9-BA85-4970-8818-BF09DD8DA3B4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -346,6 +350,30 @@ Global {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|x64.Build.0 = Release|Any CPU {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|x86.ActiveCfg = Release|Any CPU {3043DEF1-85DF-47AD-8D5D-327270794356}.Release|x86.Build.0 = Release|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Debug|x64.ActiveCfg = Debug|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Debug|x64.Build.0 = Debug|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Debug|x86.ActiveCfg = Debug|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Debug|x86.Build.0 = Debug|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Release|Any CPU.Build.0 = Release|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Release|x64.ActiveCfg = Release|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Release|x64.Build.0 = Release|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Release|x86.ActiveCfg = Release|Any CPU + {C57444BA-8BF7-4790-A864-7F237123219B}.Release|x86.Build.0 = Release|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Debug|x64.ActiveCfg = Debug|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Debug|x64.Build.0 = Debug|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Debug|x86.ActiveCfg = Debug|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Debug|x86.Build.0 = Debug|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|Any CPU.Build.0 = Release|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|x64.ActiveCfg = Release|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|x64.Build.0 = Release|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|x86.ActiveCfg = Release|Any CPU + {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -367,6 +395,7 @@ Global {D3A1869C-A8DE-46D0-8587-89EBBE3E4DD0} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {3043DEF1-85DF-47AD-8D5D-327270794356} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} + {C57444BA-8BF7-4790-A864-7F237123219B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 32a769f3..a45c7609 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -4,5 +4,10 @@ using System.Text; namespace FreeSql { - public enum DataType { MySql, SqlServer, PostgreSQL, Oracle, Sqlite } + public enum DataType { + + MySql, SqlServer, PostgreSQL, Oracle, Sqlite, + + OdbcOracle, OdbcSqlServer, OdbcMySql + } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 48308669..fe720cbb 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3ce7b5a3..d2e8ac7d 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -467,12 +467,13 @@ - + 使用连接串 数据库类型 数据库连接串 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 55253b7b..a81d0767 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -21,17 +21,20 @@ namespace FreeSql StringConvertType _entityPropertyConvertType = StringConvertType.None; Action _aopCommandExecuting = null; Action _aopCommandExecuted = null; + Type _providerType = null; /// /// 使用连接串 /// /// 数据库类型 /// 数据库连接串 + /// 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 /// - public FreeSqlBuilder UseConnectionString(DataType dataType, string connectionString) + public FreeSqlBuilder UseConnectionString(DataType dataType, string connectionString, Type providerType = null) { _dataType = dataType; _masterConnectionString = connectionString; + _providerType = providerType; return this; } /// @@ -135,31 +138,49 @@ namespace FreeSql { if (string.IsNullOrEmpty(_masterConnectionString)) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString"); IFreeSql ret = null; - Type type = null; - switch (_dataType) + var type = _providerType; + if (type?.IsGenericType == true) type = type.MakeGenericType(typeof(TMark)); + if (type == null) { - case DataType.MySql: - type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); - if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); - break; - case DataType.SqlServer: - type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); - break; - case DataType.PostgreSQL: - type = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); - break; - case DataType.Oracle: - type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); - break; - case DataType.Sqlite: - type = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); - break; - default: throw new Exception("未指定 UseConnectionString"); + switch (_dataType) + { + case DataType.MySql: + type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); + if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); + break; + case DataType.SqlServer: + type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); + break; + case DataType.PostgreSQL: + type = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); + break; + case DataType.Oracle: + type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); + break; + case DataType.Sqlite: + type = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); + break; + + case DataType.OdbcOracle: + type = Type.GetType("FreeSql.Odbc.Oracle.OdbcOracleProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + break; + case DataType.OdbcSqlServer: + type = Type.GetType("FreeSql.Odbc.SqlServer.OdbcSqlServerProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + break; + case DataType.OdbcMySql: + type = Type.GetType("FreeSql.Odbc.MySql.OdbcMySqlProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + break; + + default: throw new Exception("未指定 UseConnectionString"); + } } ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql; if (ret != null) @@ -230,25 +251,28 @@ namespace FreeSql if (maxlenAttr != null) { var lenProp = maxlenAttr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).FirstOrDefault(); - if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval) && tryval > 0) + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval)) { - switch (ret.Ado.DataType) + if (tryval != 0) { - case DataType.MySql: - e.ModifyResult.DbType = $"varchar({tryval})"; - break; - case DataType.SqlServer: - e.ModifyResult.DbType = $"nvarchar({tryval})"; - break; - case DataType.PostgreSQL: - e.ModifyResult.DbType = $"varchar({tryval})"; - break; - case DataType.Oracle: - e.ModifyResult.DbType = $"nvarchar2({tryval})"; - break; - case DataType.Sqlite: - e.ModifyResult.DbType = $"nvarchar({tryval})"; - break; + switch (ret.Ado.DataType) + { + case DataType.MySql: + e.ModifyResult.DbType = tryval > 0 ? $"varchar({tryval})" : "text"; + break; + case DataType.SqlServer: + e.ModifyResult.DbType = tryval > 0 ? $"nvarchar({tryval})" : "nvarchar(max)"; + break; + case DataType.PostgreSQL: + e.ModifyResult.DbType = tryval > 0 ? $"varchar({tryval})" : "text"; + break; + case DataType.Oracle: + e.ModifyResult.DbType = tryval > 0 ? $"nvarchar2({tryval})" : "nvarchar2(4000)"; + break; + case DataType.Sqlite: + e.ModifyResult.DbType = tryval > 0 ? $"nvarchar({tryval})" : "text"; + break; + } } } } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 1a07f0d0..9e1304c0 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -31,7 +31,7 @@ namespace FreeSql.Internal.CommonProvider public bool IsSyncStructureToLower { get; set; } = false; public bool IsSyncStructureToUpper { get; set; } = false; public bool IsConfigEntityFromDbFirst { get; set; } = false; - public bool IsNoneCommandParameter { get; set; } = false; + public virtual bool IsNoneCommandParameter { get; set; } = false; public bool IsLazyLoading { get; set; } = false; public abstract (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); @@ -50,7 +50,7 @@ namespace FreeSql.Internal.CommonProvider public bool SyncStructure(params Type[] entityTypes) { if (entityTypes == null) return false; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray(); + var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray().Distinct().ToArray(); if (syncTypes.Any() == false) return false; var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); _orm.Aop.SyncStructureBefore?.Invoke(this, before); @@ -66,7 +66,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true); return true; } - var affrows = _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); + var affrows = ExecuteDDLStatements(ddl); foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true); return true; } @@ -82,5 +82,7 @@ namespace FreeSql.Internal.CommonProvider _orm.Aop.SyncStructureAfter?.Invoke(this, after); } } + + public virtual int ExecuteDDLStatements(string ddl) => _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); } } \ No newline at end of file diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6b7824c1..d958744f 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -76,7 +76,7 @@ namespace FreeSql.Internal var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); var colattr = common.GetEntityColumnAttribute(entity, p); var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType); - if (setMethod == null) // 属性没有 set自动忽略 + if (setMethod == null || (tp == null && p.PropertyType.IsValueType)) // 属性没有 set自动忽略 { if (colattr == null) colattr = new ColumnAttribute { IsIgnore = true }; else colattr.IsIgnore = true; @@ -976,7 +976,7 @@ namespace FreeSql.Internal var ps = type.GetProperties(); foreach (var p in ps) { - if (sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; + if (string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; var pvalue = p.GetValue(obj); if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype)); else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue)); diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index ffe8dc73..ba7074fa 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index c4663edc..5415bd7e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj new file mode 100644 index 00000000..70935433 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -0,0 +1,30 @@ + + + + netstandard2.0;net45 + 0.9.17 + true + YeXiangQin + FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver} + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + $(AssemblyName) + true + true + + + + + + + + + + + + diff --git a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs new file mode 100644 index 00000000..1f4cca13 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs @@ -0,0 +1,30 @@ +public static partial class FreeSqlOdbcGlobalExtensions +{ + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatOdbcOracle(this string that, params object[] args) => _odbcOracleAdo.Addslashes(that, args); + static FreeSql.Odbc.Oracle.OdbcOracleAdo _odbcOracleAdo = new FreeSql.Odbc.Oracle.OdbcOracleAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatOdbcSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args); + static FreeSql.Odbc.SqlServer.OdbcSqlServerAdo _sqlserverAdo = new FreeSql.Odbc.SqlServer.OdbcSqlServerAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatOdbcMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args); + static FreeSql.Odbc.MySql.OdbcMySqlAdo _mysqlAdo = new FreeSql.Odbc.MySql.OdbcMySqlAdo(); +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs new file mode 100644 index 00000000..1d19cd89 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -0,0 +1,95 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.MySql +{ + + class OdbcMySqlDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OdbcMySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs new file mode 100644 index 00000000..d48ce6ca --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -0,0 +1,175 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.MySql +{ + + class OdbcMySqlInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public OdbcMySqlInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + Object poolConn = null; + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + var conn = _connection; + if (_transaction != null) conn = _transaction.Connection; + if (conn == null) + { + poolConn = _orm.Ado.MasterPool.Get(); + conn = poolConn.Value; + } + _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _params); + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, "SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (poolConn != null) + _orm.Ado.MasterPool.Return(poolConn); + + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + Object poolConn = null; + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + var conn = _connection; + if (_transaction != null) conn = _transaction.Connection; + if (conn == null) + { + poolConn = _orm.Ado.MasterPool.Get(); + conn = poolConn.Value; + } + await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _params); + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, "SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (poolConn != null) + _orm.Ado.MasterPool.Return(poolConn); + + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs new file mode 100644 index 00000000..bae459b7 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -0,0 +1,173 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.MySql +{ + + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_skip > 0 || _limit > 0) + sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.ToString(); + } + + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs new file mode 100644 index 00000000..2179e2af --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -0,0 +1,140 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.MySql +{ + + class OdbcMySqlUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public OdbcMySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + + + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(", "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(", "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + ++pkidx; + } + sb.Append(")"); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs new file mode 100644 index 00000000..b6ee5b3c --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -0,0 +1,70 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.Odbc.MySql +{ + class OdbcMySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + + public OdbcMySqlAdo() : base(DataType.MySql) { } + public OdbcMySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.MySql) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OdbcMySqlConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OdbcMySqlConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)val).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new OdbcCommand(); + } + + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as OdbcMySqlConnectionPool).Return(conn, ex); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs new file mode 100644 index 00000000..2996681b --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -0,0 +1,229 @@ +using SafeObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.MySql +{ + + class OdbcMySqlConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public OdbcMySqlConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new OdbcMySqlConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + try { if (obj.Value.Ping() == false) obj.Value.Open(); } catch { base.SetUnavailable(exception); } + } + base.Return(obj, isRecreate); + } + } + + class OdbcMySqlConnectionPoolPolicy : IPolicy + { + + internal OdbcMySqlConnectionPool _pool; + public string Name { get; set; } = "MySql OdbcConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs new file mode 100644 index 00000000..57df27e5 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -0,0 +1,337 @@ +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.MySql +{ + + class OdbcMySqlCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public OdbcMySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (OdbcType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "bit","bit(1)", null, true, null) }, + + { typeof(sbyte).FullName, (OdbcType.SmallInt, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "tinyint", "tinyint(3)", false, true, null) }, + { typeof(short).FullName, (OdbcType.SmallInt, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "smallint", "smallint(6)", false, true, null) }, + { typeof(int).FullName, (OdbcType.Int, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "int", "int(11)", false, true, null) }, + { typeof(long).FullName, (OdbcType.BigInt, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "bigint","bigint(20)", false, true, null) }, + + { typeof(byte).FullName, (OdbcType.TinyInt, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, "tinyint","tinyint(3) unsigned", true, true, null) }, + { typeof(ushort).FullName, (OdbcType.Int, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "smallint", "smallint(5) unsigned", true, true, null) }, + { typeof(uint).FullName, (OdbcType.BigInt, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "int", "int(10) unsigned", true, true, null) }, + { typeof(ulong).FullName, (OdbcType.Decimal, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "bigint", "bigint(20) unsigned", true, true, null) }, + + { typeof(double).FullName, (OdbcType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, (OdbcType.Real, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "float","float", false, true, null) }, + { typeof(decimal).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + + { typeof(TimeSpan).FullName, (OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, (OdbcType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "datetime(3)", "datetime(3)", false, true, null) }, + + { typeof(byte[]).FullName, (OdbcType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, (OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + + { typeof(Guid).FullName, (OdbcType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.VarChar, "char", "char(36)", false, true, null) }, + }; + + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OdbcType.VarChar, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OdbcType.VarChar, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + var database = conn.Value.Database; + Func ExecuteScalar = (db, sql) => + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + }; + var sb = new StringBuilder(); + try + { + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; + + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; + + if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 + sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (ExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null || + ExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null) + //数据库或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) Engine=InnoDB;\r\n"); + continue; + } + //如果新表,旧表在一个数据库下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql(@" +select +a.column_name, +a.column_type, +case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', +case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', +a.column_comment 'comment' +from information_schema.columns a +where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var a1 = string.Concat(a[1]); + if (a1 == "datetime") a1 = string.Concat(a1, "(0)"); + return new + { + column = string.Concat(a[0]), + sqlType = a1, + is_nullable = string.Concat(a[2]) == "1", + is_identity = string.Concat(a[3]) == "1", + is_unsigned = string.Concat(a[1]).EndsWith(" unsigned"), + comment = string.Concat(a[4]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql("select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); + foreach (var tbcol in tb.ColumnsByPosition) + { + var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || + tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.IsNullable != tbstructcol.is_nullable || + tbcol.Attribute.IsIdentity != tbstructcol.is_identity || + isCommentChanged) + { + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); + if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(")"); + sbalter.Append(";\r\n"); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + sbalter.Append(";\r\n"); + } + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + sbalter.Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" +select +a.column_name, +a.constraint_name 'index_id' +from information_schema.key_column_usage a +where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); + foreach (var uk in tb.Uniques) + { + if (uk.Key == "PRIMARY" || string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + //insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } + finally + { + try + { + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } + catch + { + _orm.Ado.MasterPool.Return(conn, true); + } + } + } + + public override int ExecuteDDLStatements(string ddl) + { + if (string.IsNullOrEmpty(ddl)) return 0; + var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray(); + + if (scripts.Any() == false) return 0; + if (scripts.Length == 1) return base.ExecuteDDLStatements(ddl); + + var affrows = 0; + foreach (var script in scripts) + affrows += base.ExecuteDDLStatements(script); + return affrows; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs new file mode 100644 index 00000000..569df99f --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -0,0 +1,385 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.MySql +{ + class OdbcMySqlDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public OdbcMySqlDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetOdbcType(column); + OdbcType GetOdbcType(DbColumnInfo column) + { + var is_unsigned = column.DbTypeTextFull.ToLower().EndsWith(" unsigned"); + switch (column.DbTypeText.ToLower()) + { + case "bit": return OdbcType.Bit; + + case "tinyint": return is_unsigned ? OdbcType.TinyInt : OdbcType.SmallInt; + case "smallint": return is_unsigned ? OdbcType.Int : OdbcType.SmallInt; + case "mediumint": return is_unsigned ? OdbcType.Int : OdbcType.Int; + case "int": return is_unsigned ? OdbcType.BigInt : OdbcType.Int; + case "bigint": return is_unsigned ? OdbcType.Decimal : OdbcType.BigInt; + + case "real": + case "double": return OdbcType.Double; + case "float": return OdbcType.Real; + case "numeric": + case "decimal": return OdbcType.Decimal; + + case "year": return OdbcType.Int; + case "time": return OdbcType.Time; + case "date": return OdbcType.Date; + case "timestamp": return OdbcType.Timestamp; + case "datetime": return OdbcType.DateTime; + + case "tinyblob": return OdbcType.VarBinary; + case "blob": return OdbcType.VarBinary; + case "mediumblob": return OdbcType.VarBinary; + case "longblob": return OdbcType.VarBinary; + + case "binary": return OdbcType.Binary; + case "varbinary": return OdbcType.VarBinary; + + case "tinytext": return OdbcType.Text; + case "text": return OdbcType.Text; + case "mediumtext": return OdbcType.Text; + case "longtext": return OdbcType.Text; + + case "char": return column.MaxLength == 36 ? OdbcType.Char : OdbcType.VarChar; + case "varchar": return OdbcType.VarChar; + + case "set": return OdbcType.VarChar; + case "enum": return OdbcType.VarChar; + + default: return OdbcType.VarChar; + } + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OdbcType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { (int)OdbcType.TinyInt, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, + { (int)OdbcType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { (int)OdbcType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)OdbcType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OdbcType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { (int)OdbcType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)OdbcType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + + { (int)OdbcType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)OdbcType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)OdbcType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + { (int)OdbcType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select schema_name from information_schema.schemata where schema_name not in ('information_schema', 'mysql', 'performance_schema')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public List GetTablesByDatabase(params string[] database2) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + var database = database2?.ToArray(); + + if (database == null || database.Any() == false) + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + if (string.IsNullOrEmpty(conn.Value.Database)) return loc1; + database = new[] { conn.Value.Database }; + } + } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); + var sql = string.Format(@" +select +concat(a.table_schema, '.', a.table_name) 'id', +a.table_schema 'schema', +a.table_name 'table', +a.table_comment, +a.table_type 'type' +from information_schema.tables a +where a.table_schema in ({0})", databaseIn); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6.Add(table.Replace("'", "''")); + break; + case DbTableType.StoreProcedure: + loc66.Add(table.Replace("'", "''")); + break; + } + } + if (loc6.Count == 0) return loc1; + var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; + var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + + sql = string.Format(@" +select +concat(a.table_schema, '.', a.table_name), +a.column_name, +a.data_type, +ifnull(a.character_maximum_length, 0) 'len', +a.column_type, +case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', +case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', +a.column_comment 'comment' +from information_schema.columns a +where a.table_schema in ({1}) and a.table_name in ({0}) +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + if (max_length == 0) max_length = -1; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } + + sql = string.Format(@" +select +concat(a.constraint_schema, '.', a.table_name) 'table_id', +a.column_name, +a.constraint_name 'index_id', +1 'IsUnique', +case when a.constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', +0 'IsClustered', +0 'IsDesc' +from information_schema.key_column_usage a +where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position_in_unique_constraint) +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + int is_desc = int.Parse(string.Concat(row[6])); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary> loc10 = null; + List loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = string.Format(@" +select +concat(a.constraint_schema, '.', a.table_name) 'table_id', +a.column_name, +a.constraint_name 'FKId', +concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', +1 'IsForeignKey', +a.referenced_column_name 'ref_column' +from information_schema.key_column_usage a +where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(position_in_unique_constraint) +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + { + foreach (var loc5 in loc4.UniquesDict.First().Value) + { + loc5.IsPrimary = true; + loc4.Primarys.Add(loc5); + } + } + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs new file mode 100644 index 00000000..eed31446 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -0,0 +1,456 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.MySql +{ + class OdbcMySqlExpression : CommonExpression + { + + public OdbcMySqlExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)"; + case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)"; + case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as signed)"; + case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; + case "System.String": return $"cast({getExp(operandExp)} as char)"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(operandExp)} as unsigned)"; + case "System.Guid": return $"substr(cast({getExp(operandExp)} as char), 1, 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; + case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)"; + case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as signed)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; + case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)"; + } + break; + case "NewGuid": + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "rand()"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; + break; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null; + break; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in + return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "now()"; + case "UtcNow": return "utc_timestamp()"; + case "Today": return "curdate()"; + case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)"; + case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"cast(date_format({left},'%Y-%m-%d') as datetime)"; + case "TimeOfDay": return $"timestampdiff(microsecond, date_format({left},'%Y-%m-%d'), {left})"; + case "DayOfWeek": return $"(dayofweek({left})-1)"; + case "Day": return $"dayofmonth({left})"; + case "DayOfYear": return $"dayofyear({left})"; + case "Month": return $"month({left})"; + case "Year": return $"year({left})"; + case "Hour": return $"hour({left})"; + case "Minute": return $"minute({left})"; + case "Second": return $"second({left})"; + case "Millisecond": return $"floor(microsecond({left})/1000)"; + case "Ticks": return $"(timestampdiff(microsecond, '0001-1-1', {left})*10)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"(({left}) div {(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"(({left}) div {(long)1000000 * 60 * 60} mod 24)"; + case "Milliseconds": return $"(({left}) div 1000 mod 1000)"; + case "Minutes": return $"(({left}) div {(long)1000000 * 60} mod 60)"; + case "Seconds": return $"(({left}) div 1000000 mod 60)"; + case "Ticks": return $"(({left}) * 10)"; + case "TotalDays": return $"(({left}) / {(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left}) / {(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left}) / 1000)"; + case "TotalMinutes": return $"(({left}) / {(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left}) / 1000000)"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE concat('%', {args0Value}, '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)"; + } + return $"(locate({left}, {indexOfFindStr})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim({getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"trim(leading {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {getExp(argsTrim01)} from {left})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"strcmp({left}, {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"dayofmonth(last_day(concat({getExp(exp.Arguments[0])}, '-', {getExp(exp.Arguments[1])}, '-01')))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; + + case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"date_add({left}, interval ({args1}) microsecond)"; + case "AddDays": return $"date_add({left}, interval ({args1}) day)"; + case "AddHours": return $"date_add({left}, interval ({args1}) hour)"; + case "AddMilliseconds": return $"date_add({left}, interval ({args1})*1000 microsecond)"; + case "AddMinutes": return $"date_add({left}, interval ({args1}) minute)"; + case "AddMonths": return $"date_add({left}, interval ({args1}) month)"; + case "AddSeconds": return $"date_add({left}, interval ({args1}) second)"; + case "AddTicks": return $"date_add({left}, interval ({args1})/10 microsecond)"; + case "AddYears": return $"date_add({left}, interval ({args1}) year)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"timestampdiff(microsecond, {args1}, {left})"; + case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)"; + } + break; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; + case "ToString": return exp.Arguments.Count == 0 ? $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as signed)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as signed)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "ToString": return $"cast({left} as char)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; + case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)"; + case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as signed)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; + case "ToString": return $"cast({getExp(exp.Arguments[0])} as char)"; + case "ToUInt16": + case "ToUInt32": + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs new file mode 100644 index 00000000..bfd631a4 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -0,0 +1,63 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq.Expressions; + +namespace FreeSql.Odbc.MySql +{ + + public class OdbcMySqlProvider : IFreeSql + { + + static OdbcMySqlProvider() + { + } + + public ISelect Select() where T1 : class => new OdbcMySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OdbcMySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OdbcMySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public OdbcMySqlProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new OdbcMySqlUtils(this); + this.InternalCommonExpression = new OdbcMySqlExpression(this.InternalCommonUtils); + + this.Ado = new OdbcMySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); + + this.DbFirst = new OdbcMySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new OdbcMySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + + ~OdbcMySqlProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs new file mode 100644 index 00000000..fa6f7949 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -0,0 +1,112 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace FreeSql.Odbc.MySql +{ + + class OdbcMySqlUtils : CommonUtils + { + public OdbcMySqlUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) + ret.OdbcType = (OdbcType)tp.Value; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + var ret = new OdbcParameter { ParameterName = $"?{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) + ret.OdbcType = (OdbcType)tp.Value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcMySql(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; + } + public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} div {right}"; + + public override string QuoteWriteParamter(Type type, string paramterName) + { + switch (type.FullName) + { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})"; + } + return paramterName; + } + public override string QuoteReadColumn(Type type, string columnName) + { + switch (type.FullName) + { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"ST_AsText({columnName})"; + } + return columnName; + } + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); + } + else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs new file mode 100644 index 00000000..e042ef68 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs @@ -0,0 +1,27 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Oracle +{ + + class OdbcOracleDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OdbcOracleDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + throw new NotImplementedException(); + } + public override Task> ExecuteDeletedAsync() + { + throw new NotImplementedException(); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs new file mode 100644 index 00000000..8ca161d9 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -0,0 +1,211 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Oracle +{ + + class OdbcOracleInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public OdbcOracleInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + + + public override string ToSql() + { + if (_source == null || _source.Any() == false) return null; + var sb = new StringBuilder(); + sb.Append("INSERT "); + if (_source.Count > 1) sb.Append("ALL"); + + _identCol = null; + var sbtb = new StringBuilder(); + sbtb.Append("INTO "); + sbtb.Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("("); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity) _identCol = col; + if (_ignore.ContainsKey(col.Attribute.Name)) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + + if (colidx > 0) sbtb.Append(", "); + sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); + ++colidx; + } + sbtb.Append(") "); + + _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; + var specialParams = new List(); + var didx = 0; + foreach (var d in _source) + { + if (_source.Count > 1) sb.Append("\r\n"); + sb.Append(sbtb); + sb.Append("VALUES"); + sb.Append("("); + var colidx2 = 0; + foreach (var col in _table.Columns.Values) + { + if (_ignore.ContainsKey(col.Attribute.Name)) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + + if (colidx2 > 0) sb.Append(", "); + object val = col.GetMapValue(d); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); + } + ++colidx2; + } + sb.Append(")"); + ++didx; + } + if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); + return sb.ToString(); + } + + ColumnInfo _identCol; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0); + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0); + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + this.RawExecuteAffrows(); + return _source; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + await this.RawExecuteAffrowsAsync(); + return _source; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs new file mode 100644 index 00000000..88264d50 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -0,0 +1,185 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Oracle +{ + + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field); + if (string.IsNullOrEmpty(_orderby) && _skip > 0) sb.Append(", ROWNUM AS \"__rownum__\""); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) + sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); + if (sbnav.Length > 0) + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + + if (string.IsNullOrEmpty(_orderby)) + { + if (_skip > 0) + sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + } + else + { + if (_skip > 0 && _limit > 0) sb.Insert(0, "SELECT t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + else if (_skip > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); + else if (_limit > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); + } + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.ToString(); + } + + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs new file mode 100644 index 00000000..83fe3247 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -0,0 +1,72 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Oracle +{ + + class OdbcOracleUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public OdbcOracleUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + + + protected override List RawExecuteUpdated() + { + throw new NotImplementedException(); + } + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + ++pkidx; + } + sb.Append(")"); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs new file mode 100644 index 00000000..b9b4d6f9 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -0,0 +1,70 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.Odbc.Oracle +{ + class OdbcOracleAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public OdbcOracleAdo() : base(DataType.Oracle) { } + public OdbcOracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Oracle) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OdbcOracleConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OdbcOracleConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("to_timestamp('", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "','YYYY-MM-DD HH24:MI:SS.FF6')"); + else if (param is TimeSpan || param is TimeSpan?) + return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + //if (param is string) return string.Concat('N', nparms[a]); + } + + protected override DbCommand CreateCommand() + { + return new OdbcCommand(); + } + + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as OdbcOracleConnectionPool).Return(conn, ex); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs new file mode 100644 index 00000000..533973d2 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -0,0 +1,246 @@ +using SafeObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Oracle +{ + + class OdbcOracleConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + internal string UserId { get; set; } + + public OdbcOracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + this.UserId = userIdMatch.Groups[2].Value.Trim().ToUpper(); + + var policy = new OdbcOracleConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + + if (exception is System.IO.IOException) + { + + base.SetUnavailable(exception); + + } + else if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class OdbcOracleConnectionPoolPolicy : IPolicy + { + + internal OdbcOracleConnectionPool _pool; + public string Name { get; set; } = "Oracle OdbcConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1 from dual"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs new file mode 100644 index 00000000..1f579b29 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -0,0 +1,412 @@ +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.Oracle +{ + + class OdbcOracleCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public OdbcOracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (OdbcType.Bit, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "number","number(1) NULL", null, true, null) }, + + { typeof(sbyte).FullName, (OdbcType.SmallInt, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "number", "number(4) NULL", false, true, null) }, + { typeof(short).FullName, (OdbcType.SmallInt, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "number", "number(6) NULL", false, true, null) }, + { typeof(int).FullName, (OdbcType.Int, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "number", "number(11) NULL", false, true, null) }, + { typeof(long).FullName, (OdbcType.BigInt, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "number","number(21) NULL", false, true, null) }, + + { typeof(byte).FullName, (OdbcType.TinyInt, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, "number","number(3) NULL", true, true, null) }, + { typeof(ushort).FullName, (OdbcType.Int, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "number", "number(5) NULL", true, true, null) }, + { typeof(uint).FullName, (OdbcType.BigInt, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong).FullName, (OdbcType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "number", "number(20) NULL", true, true, null) }, + + { typeof(double).FullName, (OdbcType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "float", "float(126) NULL", false, true, null) }, + { typeof(float).FullName, (OdbcType.Real, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "float","float(63) NULL", false, true, null) }, + { typeof(decimal).FullName, (OdbcType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + + //{ typeof(TimeSpan).FullName, (OdbcType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset).FullName, (OdbcType.DateTime, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, (OdbcType.DateTime, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, + + { typeof(byte[]).FullName, (OdbcType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string).FullName, (OdbcType.NVarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + + { typeof(Guid).FullName, (OdbcType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, + }; + + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var userId = (_orm.Ado.MasterPool as OdbcOracleConnectionPool).UserId; + var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 + var seqnameDel = new List(); //要删除的序列+触发器 + + var sb = new StringBuilder(); + var sbDeclare = new StringBuilder(); + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; + + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; + var primaryKeyName = entityType.GetCustomAttribute()?.Name; + + if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 + throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tboldname)) == null) + //模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + sb.Append("execute immediate 'CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; + sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + continue; + } + //如果新表,旧表在一个模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql($@" +select +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'Y' then 1 else 0 end, +nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), +nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +b.comments +from all_tab_columns a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var sqlType = GetOracleSqlTypeFullName(a); + return new + { + column = string.Concat(a[0]), + sqlType, + is_nullable = string.Concat(a[6]) == "1", + is_identity = string.Concat(a[7]) == "1" && string.Concat(a[8]) == "1", + comment = string.Concat(a[9]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + istmpatler = true; + //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + if (tbstructcol.is_identity) + seqnameDel.Add(Utils.GetCsName($"{tbname[1]}_seq_{tbstructcol.column}")); + //修改列名 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); + if (tbcol.Attribute.IsIdentity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } + else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (isCommentChanged) + sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + continue; + } + //添加列 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable == false) + { + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append("';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); + } + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" +select +c.column_name, +c.constraint_name +from +all_constraints a, +all_cons_columns c +where +a.constraint_name = c.constraint_name +and a.owner = c.owner +and a.table_name = c.table_name +and a.constraint_type in ('U') +and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); + foreach (var uk in tb.Uniques) + { + if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + if (dsukfind1.Any()) sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); + //创建临时表 + sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; + sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); + insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"nvl({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + sb.Append(insertvalue.Replace("'", "''")).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + } + Dictionary dicDeclare = new Dictionary(); + Action dropSequence = seqname => + { + if (dicDeclare.ContainsKey(seqname) == false) + { + sbDeclare.Append("\r\n").Append(seqname).Append("IS NUMBER; \r\n"); + dicDeclare.Add(seqname, true); + } + sb.Append(seqname).Append("IS := 0; \r\n") + .Append(" select count(1) into ").Append(seqname).Append(_commonUtils.FormatSql("IS from user_sequences where sequence_name={0}; \r\n", seqname)) + .Append("if ").Append(seqname).Append("IS > 0 then \r\n") + .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") + .Append("end if; \r\n"); + }; + Action dropTrigger = tiggerName => + { + if (dicDeclare.ContainsKey(tiggerName) == false) + { + sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); + dicDeclare.Add(tiggerName, true); + } + sb.Append(tiggerName).Append("IS := 0; \r\n") + .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") + .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") + .Append("end if; \r\n"); + }; + foreach (var seqname in seqnameDel) + { + dropSequence(seqname); + dropTrigger(seqname + "TI"); + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var tiggerName = seqname + "TI"; + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + dropSequence(seqname); + if (seqcol.Item3) + { + var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_columns where owner={0} and table_name={1} and column_name={2}", tbname[0], tbname[1], colname2)) == null ? 1 : + _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}"); + sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n"); + sb.Append("execute immediate 'CREATE OR REPLACE TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)) + .Append(" \r\nbefore insert on ").Append(tbname2) + .Append(" \r\nfor each row \r\nbegin\r\nselect ").Append(_commonUtils.QuoteSqlName(seqname)) + .Append(".nextval into :new.").Append(colname2).Append(" from dual;\r\nend;';\r\n"); + } + else + dropTrigger(tiggerName); + } + if (sbDeclare.Length > 0) sbDeclare.Insert(0, "declare "); + return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString(); + } + + internal static string GetOracleSqlTypeFullName(object[] row) + { + var a = row; + var sqlType = string.Concat(a[1]).ToUpper(); + var data_length = long.Parse(string.Concat(a[2])); + long.TryParse(string.Concat(a[3]), out var data_precision); + long.TryParse(string.Concat(a[4]), out var data_scale); + var char_used = string.Concat(a[5]); + if (Regex.IsMatch(sqlType, @"INTERVAL DAY\(\d+\) TO SECOND\(\d+\)", RegexOptions.IgnoreCase)) + { + } + else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) + { + } + else if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) + { + } + else if (sqlType.StartsWith("BLOB")) + { + } + else if (char_used.ToLower() == "c") + sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; + else if (char_used.ToLower() == "b") + sqlType += $"({data_length} BYTE)"; + else if (sqlType.ToLower() == "float") + sqlType += $"({data_precision})"; + else if (data_precision > 0 && data_scale > 0) + sqlType += $"({data_precision},{data_scale})"; + else if (data_precision > 0) + sqlType += $"({data_precision})"; + else + sqlType += $"({data_length})"; + return sqlType; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs new file mode 100644 index 00000000..09c98ac7 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -0,0 +1,484 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.Oracle +{ + class OdbcOracleDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public OdbcOracleDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + OdbcType GetSqlDbType(DbColumnInfo column) + { + var dbfull = column.DbTypeTextFull.ToLower(); + switch (dbfull) + { + case "number(1)": return OdbcType.Bit; + + case "number(4)": return OdbcType.SmallInt; + case "number(6)": return OdbcType.SmallInt; + case "number(11)": return OdbcType.Int; + case "number(21)": return OdbcType.BigInt; + + case "number(3)": return OdbcType.TinyInt; + case "number(5)": return OdbcType.SmallInt; + case "number(10)": return OdbcType.BigInt; + case "number(20)": return OdbcType.Decimal; + + case "float(126)": return OdbcType.Double; + case "float(63)": return OdbcType.Real; + case "number(10,2)": return OdbcType.Decimal; + + case "interval day(2) to second(6)": return OdbcType.Time; + case "timestamp(6)": return OdbcType.DateTime; + case "timestamp(6) with local time zone": return OdbcType.DateTime; + + case "blob": return OdbcType.VarBinary; + case "nvarchar2(255)": return OdbcType.NVarChar; + + case "char(36 char)": return OdbcType.Char; + } + switch (column.DbTypeText.ToLower()) + { + case "number": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(10,2)"]); + return OdbcType.Decimal; + case "float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return OdbcType.Double; + case "interval day to second": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); + return OdbcType.Time; + case "date": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["date(7)"]); + return OdbcType.DateTime; + case "timestamp": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); + return OdbcType.DateTime; + case "timestamp with local time zone": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6) with local time zone"]); + return OdbcType.DateTime; + case "blob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OdbcType.VarBinary; + case "nvarchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + case "varchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + case "char": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.Char; + case "nchar": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NChar; + case "clob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + case "nclob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + case "raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OdbcType.VarBinary; + case "long raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OdbcType.VarBinary; + case "binary_float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]); + return OdbcType.Real; + case "binary_double": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return OdbcType.Double; + case "rowid": + default: + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + } + throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); + } + + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static OdbcOracleDbFirst() + { + var defaultDbToCs = new Dictionary() { + { "number(1)", ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { "number(4)", ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { "number(6)", ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "number(11)", ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "number(21)", ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { "number(3)", ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "number(5)", ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "number(10)", ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "number(20)", ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + + { "float(126)", ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float(63)", ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "number(10,2)", ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { "interval day(2) to second(6)", ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date(7)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6) with local time zone", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + + { "blob", ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { "nvarchar2(255)", ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "char(36 char)", ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } + + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select username from all_users"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public List GetTablesByDatabase(params string[] database2) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + var database = database2?.ToArray(); + + if (database == null || database.Any() == false) + { + var userUsers = _orm.Ado.ExecuteScalar("select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + database = new[] { userUsers }; + } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); + var sql = string.Format(@" +select +a.owner || '.' || a.table_name, +a.owner, +a.table_name, +b.comments, +'TABLE' +from all_tables a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' +where a.owner in ({0})", databaseIn); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6.Add(table.Replace("'", "''")); + break; + case DbTableType.StoreProcedure: + loc66.Add(table.Replace("'", "''")); + break; + } + } + if (loc6.Count == 0) return loc1; + var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; + var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + + sql = string.Format(@" +select +a.owner || '.' || a.table_name, +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'Y' then 1 else 0 end, +nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), +b.comments +from all_tab_cols a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner in ({1}) and a.table_name in ({0}) +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var ds2 = new List(); + foreach (var row in ds) + { + var ds2item = new object[8]; + ds2item[0] = row[0]; + ds2item[1] = row[1]; + ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); + ds2item[4] = OdbcOracleCodeFirst.GetOracleSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); + ds2item[5] = string.Concat(row[7]) == "1"; + ds2item[6] = string.Concat(row[8]) == "1"; + ds2item[7] = string.Concat(row[9]); + ds2.Add(ds2item); + } + foreach (var row in ds2) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + if (max_length == 0) max_length = -1; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } + + sql = string.Format(@" +select +a.owner || '.' || a.table_name, +c.column_name, +c.constraint_name, +case when a.constraint_type = 'U' then 1 else 0 end, +case when a.constraint_type = 'P' then 1 else 0 end, +0, +0 +from +all_constraints a, +all_cons_columns c +where +a.constraint_name = c.constraint_name +and a.owner = c.owner +and a.table_name = c.table_name +and a.constraint_type in ('P', 'U') +and a.owner in ({1}) and a.table_name in ({0}) +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + int is_desc = int.Parse(string.Concat(row[6])); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary> loc10 = null; + List loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = string.Format(@" +select +a.owner || '.' || a.table_name, +c.column_name, +c.constraint_name, +b.owner || '.' || b.table_name, +1, +d.column_name + +-- a.owner 外键拥有者, +-- a.table_name 外键表, +-- c.column_name 外键列, +-- b.owner 主键拥有者, +-- b.table_name 主键表, +-- d.column_name 主键列, +-- c.constraint_name 外键名, +-- d.constraint_name 主键名 + +from +all_constraints a, +all_constraints b, +all_cons_columns c, --外键表 +all_cons_columns d --主键表 +where +a.r_constraint_name = b.constraint_name    +and a.constraint_type = 'R'    +and b.constraint_type = 'P'    +and a.r_owner = b.owner    +and a.constraint_name = c.constraint_name    +and b.constraint_name = d.constraint_name    +and a.owner = c.owner    +and a.table_name = c.table_name    +and b.owner = d.owner    +and b.table_name = d.table_name +and a.owner in ({1}) and a.table_name in ({0}) +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + { + foreach (var loc5 in loc4.UniquesDict.First().Value) + { + loc5.IsPrimary = true; + loc4.Primarys.Add(loc5); + } + } + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs new file mode 100644 index 00000000..6408808e --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -0,0 +1,458 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Oracle +{ + class OdbcOracleExpression : CommonExpression + { + + public OdbcOracleExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as number)"; + case "System.Char": return $"substr(to_char({getExp(operandExp)}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(operandExp)},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(operandExp)} as number)"; + case "System.Double": return $"cast({getExp(operandExp)} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as number)"; + case "System.Single": return $"cast({getExp(operandExp)} as number)"; + case "System.String": return $"to_char({getExp(operandExp)})"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; + case "System.Guid": return $"substr(to_char({getExp(operandExp)}), 1, 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Char": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(callExp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; + } + break; + case "NewGuid": + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; + break; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"to_char({getExp(callExp.Object)})" : null; + break; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in + return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "systimestamp"; + case "UtcNow": return "sys_extract_utc(systimestamp)"; + case "Today": return "trunc(systimestamp)"; + case "MinValue": return "to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')"; + case "MaxValue": return "to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"trunc({left})"; + case "TimeOfDay": return $"({left}-trunc({left}))"; + case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; + case "Day": return $"cast(to_char({left},'DD') as number)"; + case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; + case "Month": return $"cast(to_char({left},'MM') as number)"; + case "Year": return $"cast(to_char({left},'YYYY') as number)"; + case "Hour": return $"cast(to_char({left},'HH24') as number)"; + case "Minute": return $"cast(to_char({left},'MI') as number)"; + case "Second": return $"cast(to_char({left},'SS') as number)"; + case "Millisecond": return $"cast(to_char({left},'FF3') as number)"; + case "Ticks": return $"cast(to_char({left},'FF7') as number)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "numtodsinterval(0,'second')"; + case "MinValue": return "numtodsinterval(-233720368.5477580,'second')"; + case "MaxValue": return "numtodsinterval(233720368.5477580,'second')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"extract(day from {left})"; + case "Hours": return $"extract(hour from {left})"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Minutes": return $"extract(minute from {left})"; + case "Seconds": return $"floor(extract(second from {left}))"; + case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; + case "TotalDays": return $"extract(day from {left})"; + case "TotalHours": return $"(extract(day from {left})*24+extract(hour from {left}))"; + case "TotalMilliseconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*1000"; + case "TotalMinutes": return $"(extract(day from {left})*1440+extract(hour from {left})*60+extract(minute from {left}))"; + case "TotalSeconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(to_char({args0Value})||'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'||to_char({args0Value}))")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'||to_char({args0Value})||'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(instr({left}, {indexOfFindStr}, {locateArgs1}, 1)-1)"; + } + return $"(instr({left}, {indexOfFindStr}, 1, 1))-1"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceil({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": + if (exp.Arguments.Count > 1) return $"log({getExp(exp.Arguments[1])},{getExp(exp.Arguments[0])})"; + return $"log(2.7182818284590451,{getExp(exp.Arguments[0])})"; + case "Log10": return $"log(10,{getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + //case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0)"; + + case "Parse": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "AddDays": return $"({left}+{args1})"; + case "AddHours": return $"({left}+({args1})/24)"; + case "AddMilliseconds": return $"({left}+({args1})/86400000)"; + case "AddMinutes": return $"({left}+({args1})/1440)"; + case "AddMonths": return $"add_months({left},{args1})"; + case "AddSeconds": return $"({left}+({args1})/86400)"; + case "AddTicks": return $"({left}+({args1})/864000000000)"; + case "AddYears": return $"add_months({left},({args1})*12)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"numtodsinterval(({left}+0)-({args1}+0),'day')"; + case "System.TimeSpan": return $"({left}-{args1})"; + } + break; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; + case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60 * 24},'second')"; + case "FromHours": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60},'second')"; + case "FromMilliseconds": return $"numtodsinterval(({getExp(exp.Arguments[0])})/1000,'second')"; + case "FromMinutes": return $"numtodsinterval(({getExp(exp.Arguments[0])})*60,'second')"; + case "FromSeconds": return $"numtodsinterval(({getExp(exp.Arguments[0])}),'second')"; + case "FromTicks": return $"numtodsinterval(({getExp(exp.Arguments[0])})/10000000,'second')"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(7))"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(7))"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; + case "ToString": return $"to_char({left})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + //case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToChar": return $"substr(to_char({getExp(exp.Arguments[0])}), 1, 1)"; + case "ToDateTime": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToString": return $"to_char({getExp(exp.Arguments[0])})"; + case "ToUInt16": + case "ToUInt32": + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as number)"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs new file mode 100644 index 00000000..38647e8b --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Data.Common; + +namespace FreeSql.Odbc.Oracle +{ + + public class OdbcOracleProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new OdbcOracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OdbcOracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OdbcOracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public OdbcOracleProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new OdbcOracleUtils(this); + this.InternalCommonExpression = new OdbcOracleExpression(this.InternalCommonUtils); + + this.Ado = new OdbcOracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); + + this.DbFirst = new OdbcOracleDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new OdbcOracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + + //this.Aop.AuditValue += new EventHandler((_, e) => + //{ + // if (e.Value == null && e.Column.Attribute.IsPrimary == false && e.Column.Attribute.IsIdentity == false) + // e.Value = Utils.GetDataReaderValue(e.Property.PropertyType.NullableTypeOrThis(), e.Column.Attribute.DbDefautValue); + //}); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + + ~OdbcOracleProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs new file mode 100644 index 00000000..3538f561 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -0,0 +1,111 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Oracle +{ + + class OdbcOracleUtils : CommonUtils + { + public OdbcOracleUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var dbtype = (OdbcType)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case OdbcType.Bit: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = OdbcType.Int; + break; + + case OdbcType.Char: + case OdbcType.NChar: + case OdbcType.VarChar: + case OdbcType.NVarChar: + case OdbcType.Text: + case OdbcType.NText: + value = string.Concat(value); + break; + } + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), OdbcType = dbtype, Value = value }; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + var dbtype = (OdbcType)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case OdbcType.Bit: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = OdbcType.Int; + break; + + case OdbcType.Char: + case OdbcType.NChar: + case OdbcType.VarChar: + case OdbcType.NVarChar: + case OdbcType.Text: + case OdbcType.NText: + value = string.Concat(value); + break; + } + var ret = new OdbcParameter { ParameterName = $":{name}", OdbcType = dbtype, Value = value }; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcOracle(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left} / {right})"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("rawtohex('0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.Append("')").ToString(); + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs new file mode 100644 index 00000000..68a16b50 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -0,0 +1,105 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.SqlServer +{ + + class OdbcSqlServerDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OdbcSqlServerDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); + + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); + + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs new file mode 100644 index 00000000..8a9cc4ea --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -0,0 +1,164 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.SqlServer +{ + + class OdbcSqlServerInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public OdbcSqlServerInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(1000, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); + public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException("找不到 VALUES"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException("找不到 VALUES"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs new file mode 100644 index 00000000..a6cebe01 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -0,0 +1,310 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.SqlServer +{ + + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + => (_commonUtils as OdbcSqlServerUtils).IsSelectRowNumber ? + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _whereCascadeExpression, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _whereCascadeExpression, _orm); + + #region SqlServer 2005 row_number + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); + sb.Append(field); + if (_skip > 0) + { + if (string.IsNullOrEmpty(_orderby)) + { + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); + } + sb.Append(", ROW_NUMBER() OVER(").Append(_orderby).Append(") AS __rownum__"); + } + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip <= 0) + sb.Append(_orderby); + else + sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.ToString(); + } + #endregion + + #region SqlServer 2012+ offset feach next + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); + sb.Append(field); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip > 0) + { + if (string.IsNullOrEmpty(_orderby)) + { + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); + } + sb.Append(_orderby).Append($" \r\nOFFSET {_skip} ROW"); + if (_limit > 0) sb.Append($" \r\nFETCH NEXT {_limit} ROW ONLY"); + } + else + { + sb.Append(_orderby); + } + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.ToString(); + } + #endregion + + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs new file mode 100644 index 00000000..8c19325c --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -0,0 +1,148 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.SqlServer +{ + + class OdbcSqlServerUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public OdbcSqlServerUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 2100); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); + + + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(" \r\nWHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); + + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(" \r\nWHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); + + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(", "); + caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(", "); + sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append(" as varchar)"); + ++pkidx; + } + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs new file mode 100644 index 00000000..360c7b47 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -0,0 +1,79 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.Odbc.SqlServer +{ + class OdbcSqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public OdbcSqlServerAdo() : base(DataType.SqlServer) { } + public OdbcSqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.SqlServer) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OdbcSqlServerConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OdbcSqlServerConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string) + return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + { + if (param.Equals(DateTime.MinValue) == true) param = new DateTime(1970, 1, 1); + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); + } + else if (param is DateTimeOffset || param is DateTimeOffset?) + { + if (param.Equals(DateTimeOffset.MinValue) == true) param = new DateTimeOffset(new DateTime(1970, 1, 1), TimeSpan.Zero); + return string.Concat("'", ((DateTimeOffset)param).ToString("yyyy-MM-dd HH:mm:ss.fff zzzz"), "'"); + } + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).TotalSeconds; + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new OdbcCommand(); + } + + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as OdbcSqlServerConnectionPool).Return(conn, ex); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs new file mode 100644 index 00000000..ba1481d0 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -0,0 +1,236 @@ +using SafeObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.SqlServer +{ + + class OdbcSqlServerConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public OdbcSqlServerConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new OdbcSqlServerConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + + if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class OdbcSqlServerConnectionPoolPolicy : IPolicy + { + + internal OdbcSqlServerConnectionPool _pool; + public string Name { get; set; } = "SqlServer OdbcConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs new file mode 100644 index 00000000..f3c9ad18 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -0,0 +1,415 @@ +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.SqlServer +{ + + class OdbcSqlServerCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public OdbcSqlServerCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (OdbcType.Bit, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "bit","bit", null, true, null) }, + + { typeof(sbyte).FullName, (OdbcType.SmallInt, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, (OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, (OdbcType.Int, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "int", "int", false, true, null) }, + { typeof(long).FullName, (OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "bigint","bigint", false, true, null) }, + + { typeof(byte).FullName, (OdbcType.TinyInt, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, "tinyint","tinyint", true, true, null) }, + { typeof(ushort).FullName, (OdbcType.Int, "int","int NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "int", "int", true, true, null) }, + { typeof(uint).FullName, (OdbcType.BigInt, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "bigint", "bigint", true, true, null) }, + { typeof(ulong).FullName, (OdbcType.Decimal, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "decimal", "decimal(20,0)", true, true, null) }, + + { typeof(double).FullName, (OdbcType.Double, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "float", "float", false, true, null) }, + { typeof(float).FullName, (OdbcType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "real","real", false, true, null) }, + { typeof(decimal).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + + { typeof(TimeSpan).FullName, (OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, (OdbcType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "datetime", "datetime", false, true, null) }, + { typeof(DateTimeOffset).FullName, (OdbcType.DateTime, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, (OdbcType.DateTime, "datetimeoffset", "datetimeoffset", false, true, null) }, + + { typeof(byte[]).FullName, (OdbcType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, (OdbcType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, + + { typeof(Guid).FullName, (OdbcType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, + }; + + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OdbcType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OdbcType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) + { + if (string.IsNullOrEmpty(comment)) + { + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + 'COLUMN', N'{2}')) > 0) + EXEC sp_dropextendedproperty @name = N'MS_Description' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''")); + return; + } + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + 'COLUMN', N'{2}')) > 0) + EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'{3}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +ELSE + EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'{3}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); + } + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + var database = conn.Value.Database; + Func ExecuteScalar = (db, sql) => + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + }; + var sb = new StringBuilder(); + try + { + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 3); + if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] }; + + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] }; + if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] }; + + if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 + ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); + if (string.Compare(tbname[1], "dbo", true) != 0 && ExecuteScalar(tbname[0], $" select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 + ExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (ExecuteScalar(tbname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tbname[1]}].[{tbname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + { //表不存在 + if (tboldname != null) + { + if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tboldname[0]}'") == null || + string.Compare(tboldname[1], tbname[1], true) != 0 && ExecuteScalar(tboldname[0], $" select 1 from sys.schemas where name='{tboldname[1]}'") == null || + ExecuteScalar(tboldname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tboldname[1]}].[{tboldname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + //数据库或模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建新表 + sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(" ( "); + var pkidx = 0; + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary == true) + { + if (tb.Primarys.Length > 1) + { + if (pkidx == tb.Primarys.Length - 1) + sb.Append(" primary key (").Append(string.Join(", ", tb.Primarys.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(")"); + } + else + sb.Append(" primary key"); + pkidx++; + } + sb.Append(","); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + } + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0 && + string.Compare(tbname[1], tboldname[1], true) == 0) + sbalter.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(_commonUtils.FormatSql(";\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"), tbname[2])); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = string.Format(@" +use [{0}]; +select +a.name 'Column' +,b.name + case + when b.name in ('Char', 'VarChar', 'NChar', 'NVarChar', 'Binary', 'VarBinary') then '(' + + case when a.max_length = -1 then 'MAX' + when b.name in ('NChar', 'NVarchar') then cast(a.max_length / 2 as varchar) + else cast(a.max_length as varchar) end + ')' + when b.name in ('Numeric', 'Decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')' + else '' end as 'SqlType' +,case when a.is_nullable = 1 then '1' else '0' end 'IsNullable' +,case when a.is_identity = 1 then '1' else '0' end 'IsIdentity' +,c.value +from sys.columns a +inner join sys.types b on b.user_type_id = a.user_type_id +left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id +left join sys.tables d on d.object_id = a.object_id +left join sys.schemas e on e.schema_id = d.schema_id +where a.object_id in (object_id(N'[{1}].[{2}]')); +use " + database, tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new + { + column = string.Concat(a[0]), + sqlType = string.Concat(a[1]), + is_nullable = string.Concat(a[2]) == "1", + is_identity = string.Concat(a[3]) == "1", + comment = string.Concat(a[4]) + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.IsNullable != tbstructcol.is_nullable || + tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + { + istmpatler = true; + break; + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN';\r\n", $"{tbname[0]}.{tbname[1]}.{tbname[2]}.{tbstructcol.column}", tbcol.Attribute.Name)); + if (isCommentChanged) + //修改备备注 + AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); + if (tbcol.Attribute.IsNullable == false) + { + var addcoldbdefault = tbcol.Attribute.DbDefautValue; + if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); + } + sbalter.Append(";\r\n"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + } + var dsuksql = string.Format(@" +use [{0}]; +select +c.name +,d.name +from sys.index_columns a +inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id +left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id +left join sys.key_constraints d on d.parent_object_id = b.object_id and d.unique_index_id = b.index_id +where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_unique = 1; +use " + database, tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); + foreach (var uk in tb.Uniques) + { + if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter).Append("\r\nuse " + database); + continue; + } + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + bool idents = false; + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.FreeSqlTmp_{tbname[2]}"); + sb.Append("BEGIN TRANSACTION\r\n") + .Append("SET QUOTED_IDENTIFIER ON\r\n") + .Append("SET ARITHABORT ON\r\n") + .Append("SET NUMERIC_ROUNDABORT OFF\r\n") + .Append("SET CONCAT_NULL_YIELDS_NULL ON\r\n") + .Append("SET ANSI_NULLS ON\r\n") + .Append("SET ANSI_PADDING ON\r\n") + .Append("SET ANSI_WARNINGS ON\r\n") + .Append("COMMIT\r\n"); + sb.Append("BEGIN TRANSACTION;\r\n"); + //创建临时表 + sb.Append("CREATE TABLE ").Append(tmptablename).Append(" ( "); + var pkidx2 = 0; + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary == true) + { + if (tb.Primarys.Length > 1) + { + if (pkidx2 == tb.Primarys.Length - 1) + sb.Append(" primary key (").Append(string.Join(", ", tb.Primarys.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(")"); + } + else + sb.Append(" primary key"); + pkidx2++; + } + sb.Append(","); + idents = idents || tbcol.Attribute.IsIdentity == true; + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); + } + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); + if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); + sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); + sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\n\t\tSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol))})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol)); + sb.Append(insertvalue.Replace("'", "''")).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n"); + if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" OFF;\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("EXECUTE sp_rename N'").Append(tmptablename).Append("', N'").Append(tbname[2]).Append("', 'OBJECT';\r\n"); + sb.Append("COMMIT;\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } + finally + { + try + { + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } + catch + { + _orm.Ado.MasterPool.Return(conn, true); + } + } + } + object GetTransferDbDefaultValue(ColumnInfo col) + { + var ddv = col.Attribute.DbDefautValue; + if (ddv == null) return ddv; + if (ddv is DateTime || ddv is DateTime?) + { + var dt = (DateTime)ddv; + if (col.Attribute.DbType.Contains("SMALLDATETIME") && dt < new DateTime(1900, 1, 1)) ddv = new DateTime(1900, 1, 1); + else if (col.Attribute.DbType.Contains("DATETIME") && dt < new DateTime(1753, 1, 1)) ddv = new DateTime(1753, 1, 1); + else if (col.Attribute.DbType.Contains("DATE") && dt < new DateTime(0001, 1, 1)) ddv = new DateTime(0001, 1, 1); + } + return ddv; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs new file mode 100644 index 00000000..337a424d --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -0,0 +1,447 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.SqlServer +{ + class OdbcSqlServerDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public OdbcSqlServerDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + OdbcType GetSqlDbType(DbColumnInfo column) + { + switch (column.DbTypeText.ToLower()) + { + case "bit": return OdbcType.Bit; + case "tinyint": return OdbcType.TinyInt; + case "smallint": return OdbcType.SmallInt; + case "int": return OdbcType.Int; + case "bigint": return OdbcType.BigInt; + case "numeric": + case "decimal": return OdbcType.Decimal; + case "smallmoney": return OdbcType.Decimal; + case "money": return OdbcType.Decimal; + case "float": return OdbcType.Double; + case "real": return OdbcType.Real; + case "date": return OdbcType.Date; + case "datetime": + case "datetime2": return OdbcType.DateTime; + case "datetimeoffset": return OdbcType.DateTime; + case "smalldatetime": return OdbcType.SmallDateTime; + case "time": return OdbcType.Time; + case "char": return OdbcType.Char; + case "varchar": return OdbcType.VarChar; + case "text": return OdbcType.Text; + case "nchar": return OdbcType.NChar; + case "nvarchar": return OdbcType.NVarChar; + case "ntext": return OdbcType.NText; + case "binary": return OdbcType.Binary; + case "varbinary": return OdbcType.VarBinary; + case "image": return OdbcType.Image; + case "timestamp": return OdbcType.Timestamp; + case "uniqueidentifier": return OdbcType.UniqueIdentifier; + default: return OdbcType.NVarChar; + } + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OdbcType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { (int)OdbcType.TinyInt, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)OdbcType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { (int)OdbcType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)OdbcType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)OdbcType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + + { (int)OdbcType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)OdbcType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.SmallDateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + + { (int)OdbcType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.Image, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.Timestamp, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)OdbcType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.NChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.NVarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.NText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)OdbcType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select name from sys.databases where name not in ('master','tempdb','model','msdb')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public List GetTablesByDatabase(params string[] database) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + var tables = new List(); + + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db)) continue; + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = $@" +use [{db}]; +select + a.Object_id +,b.name 'Owner' +,a.name 'Name' +,c.value +,'TABLE' type +from sys.tables a +inner join sys.schemas b on b.schema_id = a.schema_id +left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' +where not(b.name = 'dbo' and a.name = 'sysdiagrams') +union all +select + a.Object_id +,b.name 'Owner' +,a.name 'Name' +,c.value +,'VIEW' type +from sys.views a +inner join sys.schemas b on b.schema_id = a.schema_id +left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' +union all +select + a.Object_id +,b.name 'Owner' +,a.name 'Name' +,c.value +,'StoreProcedure' type +from sys.procedures a +inner join sys.schemas b on b.schema_id = a.schema_id +left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' +where a.type = 'P' and charindex('diagram', a.name) = 0 +order by type desc, b.name, a.name +; +use [{olddatabase}]; +"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + foreach (object[] row in ds) + { + int object_id = int.Parse(string.Concat(row[0])); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6.Add(object_id); + break; + case DbTableType.StoreProcedure: + loc66.Add(object_id); + break; + } + } + if (loc6.Count == 0) return loc1; + var loc8 = string.Join(",", loc6.Select(a => string.Concat(a))); + var loc88 = string.Join(",", loc66.Select(a => string.Concat(a))); + + var tsql_place = @" + +select +isnull(e.name,'') + '.' + isnull(d.name,'') +,a.Object_id +,a.name 'Column' +,b.name 'Type' +,case + when b.name in ('Text', 'NText', 'Image') then -1 + when b.name in ('NChar', 'NVarchar') then a.max_length / 2 + else a.max_length end 'Length' +,b.name + case + when b.name in ('Char', 'VarChar', 'NChar', 'NVarChar', 'Binary', 'VarBinary') then '(' + + case when a.max_length = -1 then 'MAX' + when b.name in ('NChar', 'NVarchar') then cast(a.max_length / 2 as varchar) + else cast(a.max_length as varchar) end + ')' + when b.name in ('Numeric', 'Decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')' + else '' end as 'SqlType' +,c.value +{0} a +inner join sys.types b on b.user_type_id = a.user_type_id +left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id +left join sys.tables d on d.object_id = a.object_id +left join sys.schemas e on e.schema_id = d.schema_id +where a.object_id in ({1}) +"; + sql = string.Format(tsql_place, @" +,a.is_nullable 'IsNullable' +,a.is_identity 'IsIdentity' +from sys.columns", loc8); + if (loc88.Length > 0) + { + sql += "union all" + + string.Format(tsql_place.Replace( + "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id", + "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @" +,cast(0 as bit) 'IsNullable' +,a.is_output 'IsIdentity' +from sys.parameters", loc88); + } + sql = $"use [{db}];{sql};use [{olddatabase}]; "; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var object_id = int.Parse(string.Concat(row[1])); + var column = string.Concat(row[2]); + var type = string.Concat(row[3]); + var max_length = int.Parse(string.Concat(row[4])); + var sqlType = string.Concat(row[5]); + var comment = string.Concat(row[6]); + var is_nullable = bool.Parse(string.Concat(row[7])); + var is_identity = bool.Parse(string.Concat(row[8])); + if (max_length == 0) max_length = -1; + + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Coment = comment + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } + + sql = $@" +use [{db}]; +select + a.object_id 'Object_id' +,c.name 'Column' +,d.name 'Index_id' +,b.is_unique 'IsUnique' +,b.is_primary_key 'IsPrimaryKey' +,cast(case when b.type_desc = 'CLUSTERED' then 1 else 0 end as bit) 'IsClustered' +,case when a.is_descending_key = 1 then 2 when a.is_descending_key = 0 then 1 else 0 end 'IsDesc' +from sys.index_columns a +inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id +left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id +left join sys.key_constraints d on d.parent_object_id = b.object_id and d.unique_index_id = b.index_id +where a.object_id in ({loc8}) +; +use [{olddatabase}]; +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); + foreach (object[] row in ds) + { + int object_id = int.Parse(string.Concat(row[0])); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = bool.Parse(string.Concat(row[3])); + bool is_primary_key = bool.Parse(string.Concat(row[4])); + bool is_clustered = bool.Parse(string.Concat(row[5])); + int is_desc = int.Parse(string.Concat(row[6])); + + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + DbColumnInfo loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary> loc10 = null; + List loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = $@" +use [{db}]; +select + b.object_id 'Object_id' +,c.name 'Column' +,e.name 'FKId' +,a.referenced_object_id +,cast(1 as bit) 'IsForeignKey' +,d.name 'Referenced_Column' +,null 'Referenced_Sln' +,null 'Referenced_Table' +from sys.foreign_key_columns a +inner join sys.tables b on b.object_id = a.parent_object_id +inner join sys.columns c on c.object_id = a.parent_object_id and c.column_id = a.parent_column_id +inner join sys.columns d on d.object_id = a.referenced_object_id and d.column_id = a.referenced_column_id +left join sys.foreign_keys e on e.object_id = a.constraint_object_id +where b.object_id in ({loc8}) +; +use [{olddatabase}]; +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + int object_id, referenced_object_id; + int.TryParse(string.Concat(row[0]), out object_id); + var column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + int.TryParse(string.Concat(row[3]), out referenced_object_id); + var is_foreign_key = bool.Parse(string.Concat(row[4])); + var referenced_column = string.Concat(row[5]); + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + DbColumnInfo loc9 = loc3[object_id][column]; + DbTableInfo loc10 = null; + DbColumnInfo loc11 = null; + bool isThisSln = referenced_object_id != 0; + + if (isThisSln) + { + loc10 = loc2[referenced_object_id]; + loc11 = loc3[referenced_object_id][referenced_column]; + } + else + { + + } + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(object_id, out loc12)) + fkColumns.Add(object_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + { + foreach (var loc5 in loc4.UniquesDict.First().Value) + { + loc5.IsPrimary = true; + loc4.Primarys.Add(loc5); + } + } + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs new file mode 100644 index 00000000..1e71ec5e --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -0,0 +1,438 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.SqlServer +{ + class OdbcSqlServerExpression : CommonExpression + { + + public OdbcSqlServerExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return $"(cast({getExp(operandExp)} as varchar) not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as tinyint)"; + case "System.Char": return $"substring(cast({getExp(operandExp)} as nvarchar),1,1)"; + case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; + case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Int32": return $"cast({getExp(operandExp)} as int)"; + case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; + case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)"; + case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; + case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)"; + case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)"; + case "System.UInt32": return $"cast({getExp(operandExp)} as int)"; + case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)"; + case "System.Guid": return $"cast({getExp(operandExp)} as uniqueidentifier)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(cast({getExp(callExp.Arguments[0])} as varchar) not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; + case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as nvarchar),1,1)"; + case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; + case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Int32": return $"cast({getExp(callExp.Arguments[0])} as int)"; + case "System.Int64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; + case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as int)"; + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.Guid": return $"cast({getExp(callExp.Arguments[0])} as uniqueidentifier)"; + } + break; + case "NewGuid": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Guid": return $"newid()"; + } + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as int)"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "rand()"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; + break; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null; + break; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in + return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"len({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "getdate()"; + case "UtcNow": return "getutcdate()"; + case "Today": return "convert(char(10),getdate(),120)"; + case "MinValue": return "'1753/1/1 0:00:00'"; + case "MaxValue": return "'9999/12/31 23:59:59'"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"convert(char(10),{left},120)"; + case "TimeOfDay": return $"datediff(second, convert(char(10),{left},120), {left})"; + case "DayOfWeek": return $"(datepart(weekday, {left})-1)"; + case "Day": return $"datepart(day, {left})"; + case "DayOfYear": return $"datepart(dayofyear, {left})"; + case "Month": return $"datepart(month, {left})"; + case "Year": return $"datepart(year, {left})"; + case "Hour": return $"datepart(hour, {left})"; + case "Minute": return $"datepart(minute, {left})"; + case "Second": return $"datepart(second, {left})"; + case "Millisecond": return $"(datepart(millisecond, {left})/1000)"; + case "Ticks": return $"(cast(datediff(second, '1970-1-1', {left}) as bigint)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{60 * 60}%24)"; + case "Milliseconds": return $"(cast({left} as bigint)*1000)"; + case "Minutes": return $"floor(({left})/60%60)"; + case "Seconds": return $"(({left})%60)"; + case "Ticks": return $"(cast({left} as bigint)*10000000)"; + case "TotalDays": return $"(({left})/{60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{60 * 60})"; + case "TotalMilliseconds": return $"(cast({left} as bigint)*1000)"; + case "TotalMinutes": return $"(({left})/60)"; + case "TotalSeconds": return $"({left})"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})"; + return $"substring({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)"; + } + return $"(charindex({left}, {indexOfFindStr})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": return $"ltrim(rtrim({left}))"; + case "TrimStart": return $"ltrim({left})"; + case "TrimEnd": return $"rtrim({left})"; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"({left} - {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])}, 0)"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"floor({getExp(exp.Arguments[0])})"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; + + case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"dateadd(second, {args1}, {left})"; + case "AddDays": return $"dateadd(day, {args1}, {left})"; + case "AddHours": return $"dateadd(hour, {args1}, {left})"; + case "AddMilliseconds": return $"dateadd(second, ({args1})/1000, {left})"; + case "AddMinutes": return $"dateadd(minute, {args1}, {left})"; + case "AddMonths": return $"dateadd(month, {args1}, {left})"; + case "AddSeconds": return $"dateadd(second, {args1}, {left})"; + case "AddTicks": return $"dateadd(second, ({args1})/10000000, {left})"; + case "AddYears": return $"dateadd(year, {args1}, {left})"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"datediff(second, {args1}, {left})"; + case "System.TimeSpan": return $"dateadd(second, {args1}*-1, {left})"; + } + break; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"datediff(second,{getExp(exp.Arguments[0])},{left})"; + case "ToString": return exp.Arguments.Count == 0 ? $"convert(varchar, {left}, 121)" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; + case "FromSeconds": return $"({getExp(exp.Arguments[0])})"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "ToString": return $"cast({left} as varchar)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(cast({getExp(exp.Arguments[0])} as varchar) not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; + case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as nvarchar),1,1)"; + case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; + case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; + case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; + case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)"; + case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs new file mode 100644 index 00000000..b6138ad9 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -0,0 +1,69 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; + +namespace FreeSql.Odbc.SqlServer +{ + + public class OdbcSqlServerProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new OdbcSqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OdbcSqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OdbcSqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public OdbcSqlServerProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new OdbcSqlServerUtils(this); + this.InternalCommonExpression = new OdbcSqlServerExpression(this.InternalCommonUtils); + + this.Ado = new OdbcSqlServerAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); + + this.DbFirst = new OdbcSqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new OdbcSqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + + if (this.Ado.MasterPool != null) + using (var conn = this.Ado.MasterPool.Get()) + { + try + { + (this.InternalCommonUtils as OdbcSqlServerUtils).IsSelectRowNumber = int.Parse(conn.Value.ServerVersion.Split('.')[0]) <= 10; + } + catch + { + } + } + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + + ~OdbcSqlServerProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs new file mode 100644 index 00000000..9ba86261 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -0,0 +1,96 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.SqlServer +{ + + public class OdbcSqlServerUtils : CommonUtils + { + public OdbcSqlServerUtils(IFreeSql orm) : base(orm) + { + } + + public bool IsSelectRowNumber = true; + + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = new OdbcParameter { ParameterName = $"@{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcSqlServer(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) + { + var sb = new StringBuilder(); + var news = new string[objs.Length]; + for (var a = 0; a < objs.Length; a++) + news[a] = types[a] == typeof(string) ? objs[a] : $"cast({objs[a]} as nvarchar)"; + return string.Join(" + ", news); + } + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.ToString(); + } + else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 3d5eba25..f319e013 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index ea880517..6f543c15 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -21,9 +21,9 @@ namespace FreeSql.Oracle public OracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - var userIdMatch = Regex.Match(connectionString, @"User\s+Id\s*=\s*([^;]+)", RegexOptions.IgnoreCase); - if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 User\s+Id\s+=([^;]+)"); - this.UserId = userIdMatch.Groups[1].Value.Trim().ToUpper(); + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + this.UserId = userIdMatch.Groups[2].Value.Trim().ToUpper(); var policy = new OracleConnectionPoolPolicy { diff --git a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs index 1d93ccaa..83b5d5ff 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs @@ -7,6 +7,6 @@ /// /// /// - public static string FormatOracleSQL(this string that, params object[] args) => _oracleAdo.Addslashes(that, args); + public static string FormatOracle(this string that, params object[] args) => _oracleAdo.Addslashes(that, args); static FreeSql.Oracle.OracleAdo _oracleAdo = new FreeSql.Oracle.OracleAdo(); } diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 48a835a7..4e4e7c8a 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -45,7 +45,7 @@ namespace FreeSql.Oracle return ret; }); - public override string FormatSql(string sql, params object[] args) => sql?.FormatOracleSQL(args); + public override string FormatSql(string sql, params object[] args) => sql?.FormatOracle(args); public override string QuoteSqlName(string name) { var nametrim = name.Trim(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 5c031066..fcbd11fa 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 985769e2..bcdb7754 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index da59f6e0..665aa487 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -11,7 +11,7 @@ using System.Text; namespace FreeSql.SqlServer { - class SqlServerUtils : CommonUtils + public class SqlServerUtils : CommonUtils { public SqlServerUtils(IFreeSql orm) : base(orm) { diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index cb5d58d3..bf879bd0 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.16 + 0.9.17 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/readme.md b/readme.md index 2439c131..944d81ad 100644 --- a/readme.md +++ b/readme.md @@ -58,6 +58,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | FreeSql.Provider.SqlServer | NETStandard2.0、net451 | | FreeSql.Provider.Sqlite | NETStandard2.0、net45 | | FreeSql.Provider.Oracle | NETStandard2.0、net45 | +| FreeSql.Provider.Odbc | NETStandard2.0、net45 | | FreeSql.Extensions.LazyLoading | NETStandard2.0、net45 | | FreeSql.Extensions.JsonMap | NETStandard2.0、net45 | | FreeSql.Extensions.BaseEntity | NETStandard2.0 | From 61dfa6fc6ac59c7dc5c592b8ae090e5bac35afa9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Sep 2019 23:21:53 +0800 Subject: [PATCH 0152/1029] update --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 7f5a4d02..6f593095 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -9,31 +9,6 @@ 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert - - - 用户Id - - - - - 人脸Id - - - - - 创建时间 - - - - - 创建时间 - - - - - 相似度 - - From dcd406d06abc607b27c705566f6254096d08f89d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Sep 2019 23:26:59 +0800 Subject: [PATCH 0153/1029] update --- Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 1f579b29..8697c4c3 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -38,6 +38,7 @@ namespace FreeSql.Odbc.Oracle { typeof(float).FullName, (OdbcType.Real, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "float","float(63) NULL", false, true, null) }, { typeof(decimal).FullName, (OdbcType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + //oracle odbc driver 不支持 TimeSpan 类型的读取 //{ typeof(TimeSpan).FullName, (OdbcType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, { typeof(DateTimeOffset).FullName, (OdbcType.DateTime, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, (OdbcType.DateTime, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, From 90458cca38fae99e995f783355fd6189c668f2f5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Sep 2019 15:08:37 +0800 Subject: [PATCH 0154/1029] update readme --- functions03.png | Bin 52032 -> 0 bytes functions04.png | Bin 0 -> 83323 bytes readme.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 functions03.png create mode 100644 functions04.png diff --git a/functions03.png b/functions03.png deleted file mode 100644 index d0aef2070114554f49dbb6b61e897bdd45b91b67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52032 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 PtcT~7HO^!znFanovp!`) diff --git a/functions04.png b/functions04.png new file mode 100644 index 0000000000000000000000000000000000000000..48b01f8c7a6e7286624ae12ebf0d6a340a53875f GIT binary patch literal 83323 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 UK1^ed2m<~o-Bpt-lQ9eae~KTb!~g&Q literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index 944d81ad..8deb5c9d 100644 --- a/readme.md +++ b/readme.md @@ -64,7 +64,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | FreeSql.Extensions.BaseEntity | NETStandard2.0 |

- +

# Quick start From dcf1da36d453c45c552b99ffa26d671308ad5dc7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Sep 2019 00:48:34 +0800 Subject: [PATCH 0155/1029] ## v0.9.18 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加 PostgreSQL 的 Odbc 访问提供,相比 FreeSql.Provider.PostgreSQL 支持的类型更少; - 增加 通用的 Odbc 访问提供,不能迁移实体到数据库,不能 Skip 这样来分页,理论上能 crud 所有 odbc 数据库; --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/DbSet/DbSet.cs | 8 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 12 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 12 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../Default/Curd/OdbcDeleteTest.cs | 90 + .../Default/Curd/OdbcInsertTest.cs | 141 ++ .../Default/Curd/OdbcSelectTest.cs | 1206 +++++++++++++ .../Default/Curd/OdbcUpdateTest.cs | 146 ++ .../Default/MapType/BoolNullableTest.cs | 1596 +++++++++++++++++ .../Default/MapType/BoolTest.cs | 1129 ++++++++++++ .../Default/MapType/EnumTest.cs | 263 +++ .../Default/MapType/ToStringTest.cs | 570 ++++++ .../Default/OdbcAdo/OdbcAdoTest.cs | 93 + .../Default/OdbcAopTest.cs | 40 + .../Default/OdbcCodeFirstTest.cs | 148 ++ .../Default/OdbcExpression/ConvertTest.cs | 168 ++ .../Default/OdbcExpression/DateTimeTest.cs | 321 ++++ .../Default/OdbcExpression/MathTest.cs | 155 ++ .../Default/OdbcExpression/OtherTest.cs | 129 ++ .../Default/OdbcExpression/StringTest.cs | 289 +++ .../Default/OdbcExpression/TimeSpanTest.cs | 209 +++ .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 97 + .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 141 ++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 1310 ++++++++++++++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 147 ++ .../PostgreSQL/MapType/BoolNullableTest.cs | 1596 +++++++++++++++++ .../PostgreSQL/MapType/BoolTest.cs | 1130 ++++++++++++ .../PostgreSQL/MapType/DateTimeOffSetTest.cs | 54 + .../PostgreSQL/MapType/EnumTest.cs | 261 +++ .../PostgreSQL/MapType/ToStringTest.cs | 570 ++++++ .../PostgreSQLAdo/PostgreSQLAdoTest.cs | 70 + .../PostgreSQL/PostgreSQLAopTest.cs | 40 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 220 +++ .../PostgreSQL/PostgreSQLDbFirstTest.cs | 25 + .../PostgreSQLExpression/ConvertTest.cs | 169 ++ .../PostgreSQLExpression/DateTimeTest.cs | 706 ++++++++ .../PostgreSQLExpression/MathTest.cs | 156 ++ .../PostgreSQLExpression/OtherTest.cs | 139 ++ .../PostgreSQLExpression/StringTest.cs | 728 ++++++++ .../PostgreSQLExpression/TimeSpanTest.cs | 293 +++ .../FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 1 - .../FreeSql.Tests.Provider.Odbc/g.cs | 23 + .../PostgreSQLAdo/PostgreSQLAdoTest.cs | 2 +- FreeSql/DataType.cs | 13 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 9 + FreeSql/FreeSqlBuilder.cs | 33 +- .../CommonProvider/CodeFirstProvider.cs | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySql/MySqlExpression.cs | 6 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../Default/Curd/OdbcDelete.cs | 21 + .../Default/Curd/OdbcInsert.cs | 107 ++ .../Default/Curd/OdbcSelect.cs | 189 ++ .../Default/Curd/OdbcUpdate.cs | 64 + .../Default/OdbcAdapter.cs | 173 ++ .../Default/OdbcAdo/OdbcAdo.cs | 73 + .../Default/OdbcAdo/OdbcConnectionPool.cs | 236 +++ .../Default/OdbcCodeFirst.cs | 90 + .../Default/OdbcExpression.cs | 441 +++++ .../Default/OdbcProvider.cs | 113 ++ .../Default/OdbcUtils.cs | 73 + .../FreeSql.Provider.Odbc.csproj | 4 +- .../FreeSqlOdbcGlobalExtensions.cs | 26 +- .../MySql/Curd/OdbcMySqlSelect.cs | 54 +- .../MySql/OdbcMySqlCodeFirst.cs | 7 +- .../MySql/OdbcMySqlExpression.cs | 6 +- .../Oracle/Curd/OdbcOracleSelect.cs | 54 +- .../Oracle/OdbcOracleCodeFirst.cs | 2 - .../Oracle/OdbcOracleExpression.cs | 8 +- .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 95 + .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 199 ++ .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 175 ++ .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 149 ++ .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 71 + .../OdbcPostgreSQLConnectionPool.cs | 241 +++ .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 342 ++++ .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 445 +++++ .../PostgreSQL/OdbcPostgreSQLExpression.cs | 538 ++++++ .../PostgreSQL/OdbcPostgreSQLProvider.cs | 61 + .../PostgreSQL/OdbcPostgreSQLUtils.cs | 160 ++ .../SqlServer/OdbcSqlServerCodeFirst.cs | 6 +- .../SqlServer/OdbcSqlServerExpression.cs | 10 +- Providers/FreeSql.Provider.Odbc/readme.md | 25 + .../FreeSql.Provider.Oracle.csproj | 2 +- .../OracleExpression.cs | 8 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../PostgreSQLCodeFirst.cs | 5 +- .../PostgreSQLExpression.cs | 8 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../SqlServerExpression.cs | 10 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- .../SqliteExpression.cs | 8 +- 97 files changed, 18833 insertions(+), 154 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs create mode 100644 Providers/FreeSql.Provider.Odbc/readme.md diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index bcc8a520..aefa1a32 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.17 + 0.9.18 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 33f771f1..a3ab5cfa 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a336e1ce..fab0214c 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 7795ba50..fa02eeb2 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -234,15 +234,13 @@ namespace FreeSql switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: + case DataType.OdbcSqlServer: case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: return true; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: + default: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) - { return true; - } if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index c80ccf72..0ae3f8d3 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -34,7 +34,9 @@ namespace FreeSql switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: + case DataType.OdbcSqlServer: case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { await DbContextExecCommandAsync(); @@ -56,9 +58,7 @@ namespace FreeSql await AddOrUpdateNavigateListAsync(data); } return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: + default: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { await DbContextExecCommandAsync(); @@ -92,7 +92,9 @@ namespace FreeSql switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: + case DataType.OdbcSqlServer: case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: await DbContextExecCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); @@ -105,9 +107,7 @@ namespace FreeSql foreach (var item in data) await AddOrUpdateNavigateListAsync(item); return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: + default: foreach (var s in data) await AddPrivAsync(s, false); return; diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 8a1f1ae0..7cb270b5 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -34,7 +34,9 @@ namespace FreeSql switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: + case DataType.OdbcSqlServer: case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: if (_tableIdentitys.Length == 1) { DbContextExecCommand(); @@ -56,9 +58,7 @@ namespace FreeSql AddOrUpdateNavigateList(data); } return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: + default: if (_tableIdentitys.Length == 1) { DbContextExecCommand(); @@ -96,7 +96,9 @@ namespace FreeSql switch (_db.Orm.Ado.DataType) { case DataType.SqlServer: + case DataType.OdbcSqlServer: case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: DbContextExecCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); @@ -109,9 +111,7 @@ namespace FreeSql foreach (var item in data) AddOrUpdateNavigateList(item); return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: + default: foreach (var s in data) AddPriv(s, false); return; diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index da660319..0d010977 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 244abcd6..74bb9355 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs new file mode 100644 index 00000000..fe33795c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs @@ -0,0 +1,90 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Default +{ + public class OdbcDeleteTest + { + IDelete delete => g.odbc.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.odbc.Delete().ToSql()); + var sql = g.odbc.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.odbc.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.odbc.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.odbc.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.odbc.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.odbc.Delete().ToSql()); + var sql = g.odbc.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.odbc.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); + + sql = g.odbc.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.odbc.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcInsertTest.cs new file mode 100644 index 00000000..aa042205 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcInsertTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Default +{ + public class OdbcInsertTest + { + IInsert insert => g.odbc.Insert(); //�������� + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 20:09:37") }); + + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:09:37')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:09:37'), (100, N'newtitle1', '2019-09-19 20:09:37'), (200, N'newtitle2', '2019-09-19 20:09:37'), (300, N'newtitle3', '2019-09-19 20:09:37'), (400, N'newtitle4', '2019-09-19 20:09:37'), (500, N'newtitle5', '2019-09-19 20:09:37'), (600, N'newtitle6', '2019-09-19 20:09:37'), (700, N'newtitle7', '2019-09-19 20:09:37'), (800, N'newtitle8', '2019-09-19 20:09:37'), (900, N'newtitle9', '2019-09-19 20:09:37')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var sql = insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.odbc.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.odbc.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.odbc.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.odbc.Insert(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + + + //items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //var lastId = g.sqlite.Select().Max(a => a.Id); + //Assert.NotEqual(lastId, g.odbc.Insert(items).ExecuteIdentity()); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 20:01:51") }); + + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:01:51')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:01:51'), (100, N'newtitle1', '2019-09-19 20:01:51'), (200, N'newtitle2', '2019-09-19 20:01:51'), (300, N'newtitle3', '2019-09-19 20:01:51'), (400, N'newtitle4', '2019-09-19 20:01:51'), (500, N'newtitle5', '2019-09-19 20:01:51'), (600, N'newtitle6', '2019-09-19 20:01:51'), (700, N'newtitle7', '2019-09-19 20:01:51'), (800, N'newtitle8', '2019-09-19 20:01:51'), (900, N'newtitle9', '2019-09-19 20:01:51')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.Title, a.TypeGuid }).InsertColumns(a => a.Title).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.Title, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs new file mode 100644 index 00000000..a9184ea1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -0,0 +1,1206 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Default +{ + public class OdbcSelectTest + { + ISelect select => g.odbc.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.odbc.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 + //FROM [Tag] a + //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] + //LEFT JOIN [Tag] a__Parent__Parent ON a__Parent__Parent.[Id] = a__Parent.[Parent_id] + //WHERE (a__Parent__Parent.[Name] = '粤语') + + //OneToMany + var t1 = g.odbc.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] + //FROM [Tag] a + //WHERE (exists(SELECT 1 + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) + + //ManyToMany + var t2 = g.odbc.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] + //FROM [Song] a + //WHERE(exists(SELECT 1 + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.odbc.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.odbc.Select().Limit(10).ToList(); + + + } + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, g.odbc.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, g.odbc.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //; + //Assert.Equal(9989, g.odbc.Insert(items).NoneParameter().ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, getdate()"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + g.odbc.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.odbc.Select().ToList(); + var testGuidId6 = g.odbc.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid]", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] INNER JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] RIGHT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = N'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TypeGuid] AND b.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = N'typeTitle' AND b.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = N'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = ?)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = N'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = ?)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.odbc.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.odbc.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(Convert.ToInt64(a.Key.Id)), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic22 where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid]", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] c ON c.[Id] = a__Type.[ParentId]", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfoAsTable] c ON b.[ParentId] = c.[Id]", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.odbc.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.odbc.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.odbc.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.odbc.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.odbc.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.odbc.Insert(model4s).ExecuteAffrows()); + + var t0 = g.odbc.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.odbc.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.odbc.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.odbc.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.odbc.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.odbc.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.odbc.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.odbc.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.odbc.Insert(model1).ExecuteIdentity(); + + var t1 = g.odbc.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.odbc.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.odbc.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.odbc.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.odbc.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.odbc.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.odbc.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.odbc.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.odbc.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.odbc.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.odbc.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.odbc.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.odbc.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.odbc.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.odbc.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.odbc.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.odbc.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.odbc.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.odbc.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.odbc.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.odbc.Insert(song3).ExecuteIdentity(); + + g.odbc.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.odbc.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.odbc.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.odbc.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.odbc.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.odbc.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.odbc.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.odbc.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.odbc.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.odbc.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.odbc.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.odbc.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs new file mode 100644 index 00000000..f5686dbd --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs @@ -0,0 +1,146 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Default +{ + public class OdbcUpdateTest + { + IUpdate update => g.odbc.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.odbc.Update().ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.odbc.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.odbc.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.odbc.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.odbc.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL, [Title] = N'newtitle', [CreateTime] = '1970-01-01 00:00:00' WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, [Title] = CASE [Id] WHEN 1 THEN N'newtitle0' WHEN 2 THEN N'newtitle1' WHEN 3 THEN N'newtitle2' WHEN 4 THEN N'newtitle3' WHEN 5 THEN N'newtitle4' WHEN 6 THEN N'newtitle5' WHEN 7 THEN N'newtitle6' WHEN 8 THEN N'newtitle7' WHEN 9 THEN N'newtitle8' WHEN 10 THEN N'newtitle9' END, [CreateTime] = CASE [Id] WHEN 1 THEN '1970-01-01 00:00:00' WHEN 2 THEN '1970-01-01 00:00:00' WHEN 3 THEN '1970-01-01 00:00:00' WHEN 4 THEN '1970-01-01 00:00:00' WHEN 5 THEN '1970-01-01 00:00:00' WHEN 6 THEN '1970-01-01 00:00:00' WHEN 7 THEN '1970-01-01 00:00:00' WHEN 8 THEN '1970-01-01 00:00:00' WHEN 9 THEN '1970-01-01 00:00:00' WHEN 10 THEN '1970-01-01 00:00:00' END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN N'newtitle0' WHEN 2 THEN N'newtitle1' WHEN 3 THEN N'newtitle2' WHEN 4 THEN N'newtitle3' WHEN 5 THEN N'newtitle4' WHEN 6 THEN N'newtitle5' WHEN 7 THEN N'newtitle6' WHEN 8 THEN N'newtitle7' WHEN 9 THEN N'newtitle8' WHEN 10 THEN N'newtitle9' END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = '2020-01-01 00:00:00' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle', [CreateTime] = '2020-01-01 00:00:00' WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + ? WHERE ([Id] = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var time = DateTime.Now; + var items222 = g.odbc.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.odbc.Update().ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.odbc.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.odbc.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.odbc.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.odbc.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..b13d90e9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs @@ -0,0 +1,1596 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.odbc; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs new file mode 100644 index 00000000..cf68b373 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs @@ -0,0 +1,1129 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultMapType +{ + public class BoolTest + { + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.odbc; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/EnumTest.cs new file mode 100644 index 00000000..927d4f73 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/EnumTest.cs @@ -0,0 +1,263 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultMapType +{ + public class EnumTest + { + + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { 中国人, abc, 香港 } + + [Fact] + public void EnumToString() + { + //insert + var orm = g.odbc; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.中国人, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.香港; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.香港, find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.中国人; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.中国人, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.香港).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.香港, find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.odbc; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.中国人 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.中国人, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.香港; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.香港, find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.中国人).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.odbc; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.中国人, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.香港; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.香港, find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.中国人; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.中国人, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.香港).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.香港, find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.中国人).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.香港).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.odbc; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.中国人 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.中国人, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.香港; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.香港, find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.香港).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.中国人).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.香港).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/ToStringTest.cs new file mode 100644 index 00000000..2b9ac5be --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { 中国人, abc, 香港 } + [Fact] + public void Enum1() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.中国人, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.香港; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.香港, find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.中国人; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.中国人, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.香港).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.香港, find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.中国人 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.中国人).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.中国人, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.香港; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.香港, find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.中国人).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.odbc; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs new file mode 100644 index 00000000..bec8f773 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs @@ -0,0 +1,93 @@ +using FreeSql.DataAnnotations; +using System; +using System.Data.Odbc; +using Xunit; + +namespace FreeSql.Tests.Odbc.Default +{ + public class OdbcAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.odbc.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.odbc.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + //var tt1 = g.odbc.Select() + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToSql(a => new { a.Id, a.Title }); + + //var tt2result = g.odbc.Select() + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToList(a => new { a.Id, a.Title }); + + //var tt = g.odbc.Select() + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToSql(a => new { a.Id, a.Title }); + + //var ttresult = g.odbc.Select() + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToList(a => new { a.Id, a.Title }); + + var tnsql1 = g.odbc.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + + var tn1 = g.odbc.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToList(a => a.Id); + + var t3 = g.odbc.Ado.Query("select * from xxx"); + + var t4 = g.odbc.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); + + var t5 = g.odbc.Ado.Query(System.Data.CommandType.Text, "select * from xxx where Id = ?", + new OdbcParameter("@Id", 1)); + } + + [Fact] + public void QueryMultipline() + { + var tnsql1 = g.odbc.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + + var t3 = g.odbc.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + } + + class xxx + { + public int Id { get; set; } + public int ParentId { get; set; } + public xxx Parent { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime Create_time { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAopTest.cs new file mode 100644 index 00000000..8669fdbe --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.Default +{ + public class OdbcAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.odbc.Aop.AuditValue += audit; + + g.odbc.Insert(item).ExecuteAffrows(); + + g.odbc.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs new file mode 100644 index 00000000..c26d27ff --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs @@ -0,0 +1,148 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.Default +{ + + public class OdbcCodeFirstTest + { + [Fact] + public void 中文表_字段() + { + var item = new 测试中文表 + { + 标题 = "测试标题", + 创建时间 = DateTime.Now + }; + Assert.Equal(1, g.odbc.Insert<测试中文表>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.编号); + var item2 = g.odbc.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + } + class 测试中文表 + { + [Column(IsPrimary = true)] + public Guid 编号 { get; set; } + + public string 标题 { get; set; } + + public DateTime 创建时间 { get; set; } + } + + IInsert insert => g.odbc.Insert(); + ISelect select => g.odbc.Select(); + + [Fact] + public void CurdAllField() + { + var item = new tb_alltype_notime { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new tb_alltype_notime + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.UTF8.GetBytes("我是中国人"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(1), + testFieldDecimal = 998.99M, + testFieldDecimalNullable = 999.12M, + testFieldDouble = 99.199, + testFieldDoubleNullable = 99.211, + testFieldEnum1 = TableAllTypeEnumType1.e2, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f3, + testFieldEnum2Nullable = TableAllTypeEnumType2.f2, + testFieldFloat = 0.99F, + testFieldFloatNullable = 0.11F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldLong = long.MaxValue, + testFieldSByte = sbyte.MaxValue, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "我是中国人string", + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + item2.Id = (int)insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + var sqlTestUpdate = g.odbc.Update().SetSource(item2).NoneParameter().ToSql(); + + var item3 = insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype_notime")] + class tb_alltype_notime + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + [Column(Name = "testFieldBool1111")] + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/ConvertTest.cs new file mode 100644 index 00000000..5e184bc0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/ConvertTest.cs @@ -0,0 +1,168 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultExpression +{ + public class ConvertTest + { + ISelect select => g.odbc.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + //data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + //data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.NewGuid().ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/DateTimeTest.cs new file mode 100644 index 00000000..10e80f5e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/DateTimeTest.cs @@ -0,0 +1,321 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultExpression +{ + public class DateTimeTest + { + ISelect select => g.odbc.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void 两个日期相减_效果同Subtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/MathTest.cs new file mode 100644 index 00000000..a7bdc266 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/MathTest.cs @@ -0,0 +1,155 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultExpression +{ + public class MathTest + { + ISelect select => g.odbc.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + //data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + //data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + //data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs new file mode 100644 index 00000000..fc29b831 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs @@ -0,0 +1,129 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultExpression +{ + public class OtherTest + { + + ISelect select => g.odbc.Select(); + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + [Column(Name = "testFieldBool1111")] + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public DateTimeOffset testFieldDateTimeOffset { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/StringTest.cs new file mode 100644 index 00000000..b88748f6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/StringTest.cs @@ -0,0 +1,289 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultExpression +{ + public class StringTest + { + + ISelect select => g.odbc.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.odbc.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + } + [Fact] + public void PadLeft() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + } + [Fact] + public void PadRight() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void CompareTo() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/TimeSpanTest.cs new file mode 100644 index 00000000..bb8c7936 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/TimeSpanTest.cs @@ -0,0 +1,209 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DefaultExpression +{ + public class TimeSpanTest + { + + ISelect select => g.odbc.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs new file mode 100644 index 00000000..0af7e64c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -0,0 +1,97 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLDeleteTest + { + + IDelete delete => g.pgsql.Delete(); + + [Table(Name = "tb_topic_del")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.pgsql.Delete().ToSql()); + var sql = g.pgsql.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + + sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + + sql = g.pgsql.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.pgsql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + delete.Where(a => a.Id > 0).ExecuteDeleted(); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.pgsql.Delete().ToSql()); + var sql = g.pgsql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + + sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); + + sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + + sql = g.pgsql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertTest.cs new file mode 100644 index 00000000..01e735a6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLInsertTest + { + + IInsert insert => g.pgsql.Insert(); + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000000'), (100, 'newtitle1', '0001-01-01 00:00:00.000000'), (200, 'newtitle2', '0001-01-01 00:00:00.000000'), (300, 'newtitle3', '0001-01-01 00:00:00.000000'), (400, 'newtitle4', '0001-01-01 00:00:00.000000'), (500, 'newtitle5', '0001-01-01 00:00:00.000000'), (600, 'newtitle6', '0001-01-01 00:00:00.000000'), (700, 'newtitle7', '0001-01-01 00:00:00.000000'), (800, 'newtitle8', '0001-01-01 00:00:00.000000'), (900, 'newtitle9', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.pgsql.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.pgsql.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + insert.AppendData(items.First()).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000000'), (100, 'newTitle1', '0001-01-01 00:00:00.000000'), (200, 'newTitle2', '0001-01-01 00:00:00.000000'), (300, 'newTitle3', '0001-01-01 00:00:00.000000'), (400, 'newTitle4', '0001-01-01 00:00:00.000000'), (500, 'newTitle5', '0001-01-01 00:00:00.000000'), (600, 'newTitle6', '0001-01-01 00:00:00.000000'), (700, 'newTitle7', '0001-01-01 00:00:00.000000'), (800, 'newTitle8', '0001-01-01 00:00:00.000000'), (900, 'newTitle9', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\") VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs new file mode 100644 index 00000000..1854ddee --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -0,0 +1,1310 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLSelectTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.pgsql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.pgsql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.pgsql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.pgsql.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.pgsql.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Single(g.pgsql.Insert().AppendData(items.First()).ExecuteInserted()); + Assert.Equal(10, g.pgsql.Insert().AppendData(items).ExecuteInserted().Count); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.pgsql.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + + var t1 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t2 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.pgsql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new + { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.pgsql.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.pgsql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.pgsql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.pgsql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.pgsql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.pgsql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.pgsql.Select().ToList(); + var testGuidId6 = g.pgsql.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" INNER JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" INNER JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" INNER JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.InnerJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" RIGHT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" RIGHT JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" RIGHT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.RightJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE ((a.\"id\" = 10 AND a.\"id\" > 10 OR a.\"clicks\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10) AND (a.\"clicks\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle' AND a__Type.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"name\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b WHERE (b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b WHERE (b.\"name\" = 'typeTitle' AND b.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeparentinfo\" c WHERE (c.\"name\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c WHERE (a.\"id\" = 10 AND c.\"name\" = 'xxx') AND (b.\"parentid\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"clicks\" > 100 and a.\"id\" = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = ?)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE ((a.\"id\" = 10 AND a.\"id\" > 10 OR a.\"clicks\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"id\" = 10) AND (a.\"clicks\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle' AND a__Type.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"name\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c WHERE (a.\"id\" = 10 AND c.\"name\" = 'xxx') AND (b.\"parentid\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"clicks\" > 100 and a.\"id\" = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = ?)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"clicks\" > 100 and a.\"id\" = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.pgsql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.pgsql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON b.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoastable\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfoastable\" c ON b.\"parentid\" = c.\"id\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", sql); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.pgsql.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.pgsql.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.pgsql.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.pgsql.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.pgsql.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.pgsql.Insert(model4s).ExecuteAffrows()); + + var t0 = g.pgsql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.pgsql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.pgsql.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.pgsql.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.pgsql.Insert(model1).ExecuteIdentity(); + + var t1 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.pgsql.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.pgsql.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.pgsql.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.pgsql.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.pgsql.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.pgsql.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.pgsql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.pgsql.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.pgsql.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.pgsql.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.pgsql.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.pgsql.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.pgsql.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.pgsql.Insert(song3).ExecuteIdentity(); + + g.pgsql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.pgsql.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs new file mode 100644 index 00000000..d775f9ab --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -0,0 +1,147 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLUpdateTest + { + IUpdate update => g.pgsql.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.pgsql.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = NULL, \"title\" = 'newtitle', \"createtime\" = '0001-01-01 00:00:00.000000' WHERE (\"id\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = CASE \"id\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END::int4, \"title\" = CASE \"id\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::varchar, \"createtime\" = CASE \"id\" WHEN 1 THEN '0001-01-01 00:00:00.000000' WHEN 2 THEN '0001-01-01 00:00:00.000000' WHEN 3 THEN '0001-01-01 00:00:00.000000' WHEN 4 THEN '0001-01-01 00:00:00.000000' WHEN 5 THEN '0001-01-01 00:00:00.000000' WHEN 6 THEN '0001-01-01 00:00:00.000000' WHEN 7 THEN '0001-01-01 00:00:00.000000' WHEN 8 THEN '0001-01-01 00:00:00.000000' WHEN 9 THEN '0001-01-01 00:00:00.000000' WHEN 10 THEN '0001-01-01 00:00:00.000000' END::timestamp WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = CASE \"id\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::varchar WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"createtime\" = '2020-01-01 00:00:00.000000' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = 'newtitle' WHERE (\"id\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = 'newtitle' WHERE (\"id\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = 'newtitle' WHERE (\"id\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = 'newtitle', \"createtime\" = '2020-01-01 00:00:00.000000' WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = coalesce(\"clicks\", 0) * 10 / 1 WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = (\"id\" - 10) WHERE (\"id\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = coalesce(\"clicks\", 0) * 10 / 1 WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = (\"id\" - 10) WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = \"clicks\" * 10 / 1 WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = 10 WHERE (\"id\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + ? WHERE (\"id\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void WhereExists() + { + + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.pgsql.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..0c8c0d7f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs @@ -0,0 +1,1596 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs new file mode 100644 index 00000000..a91a204f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs @@ -0,0 +1,1130 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..91038d56 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.pgsql; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/EnumTest.cs new file mode 100644 index 00000000..6d3490bd --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/ToStringTest.cs new file mode 100644 index 00000000..5dddee84 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs new file mode 100644 index 00000000..61f111de --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs @@ -0,0 +1,70 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.pgsql.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.pgsql.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + g.pgsql.CodeFirst.SyncStructure(); + var t3 = g.pgsql.Ado.Query("select * from xxx"); + + var t4 = g.pgsql.Ado.Query<(int, string, string)>("select * from xxx"); + + var t5 = g.pgsql.Ado.Query("select * from xxx"); + } + + [Fact] + public void QueryMultipline() + { + g.pgsql.CodeFirst.SyncStructure(); + var t3 = g.pgsql.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + } + + class xxx + { + public string Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + + public string testf { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAopTest.cs new file mode 100644 index 00000000..8b57b003 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.pgsql.Aop.AuditValue += audit; + + g.pgsql.Insert(item).ExecuteAffrows(); + + g.pgsql.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs new file mode 100644 index 00000000..6d0aa7ae --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -0,0 +1,220 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLCodeFirstTest + { + + [Fact] + public void ı_ֶ() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements<ı>(); + g.pgsql.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.pgsql.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + class AddUniquesInfo + { + public Guid id { get; set; } + [Column(Unique = "uk_phone")] + public string phone { get; set; } + + [Column(Unique = "uk_group_index, uk_group_index22")] + public string group { get; set; } + [Column(Unique = "uk_group_index")] + public int index { get; set; } + [Column(Unique = "uk_group_index22")] + public string index22 { get; set; } + } + + [Fact] + public void AddField() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.Select(); + + var id = g.pgsql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } + + [Table(Name = "ccc.TopicAddField", OldName = "TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } = "xxx"; + + public int clicks { get; set; } = 10; + //public int name { get; set; } = 3000; + + //[Column(DbType = "varchar(200) not null", OldName = "title")] + //public string title222 { get; set; } = "333"; + + //[Column(DbType = "varchar(200) not null")] + //public string title222333 { get; set; } = "xxx"; + + //[Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] + //public string titleaaa { get; set; } = "fsdf"; + + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.Select(); + } + + IInsert insert => g.pgsql.Insert(); + ISelect select => g.pgsql.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddDays(-1), + testFieldDecimal = 999.99M, + testFieldDecimalNullable = 111.11M, + testFieldDouble = 888.88, + testFieldDoubleNullable = 222.22, + testFieldEnum1 = TableAllTypeEnumType1.e3, + testFieldEnum1Nullable = TableAllTypeEnumType1.e2, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 777.77F, + testFieldFloatNullable = 333.33F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = 123, + testFieldLong = long.MaxValue, + + testFieldSByte = sbyte.MaxValue, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "йString", + testFieldTimeSpan = TimeSpan.FromDays(1), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(90), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue, + }; + + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); + + var item3 = insert.AppendData(item2).ExecuteInserted().First(); + var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs new file mode 100644 index 00000000..497e9c0f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.pgsql.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[1]); + + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/ConvertTest.cs new file mode 100644 index 00000000..4a04fbea --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLExpression +{ + public class ConvertTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + //data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs new file mode 100644 index 00000000..b70c220c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs @@ -0,0 +1,706 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLExpression +{ + public class DateTimeTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/MathTest.cs new file mode 100644 index 00000000..0a5cab9a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLExpression +{ + public class MathTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs new file mode 100644 index 00000000..39d3a70a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -0,0 +1,139 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLExpression +{ + public class OtherTest + { + + ISelect select => g.pgsql.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + //g.pgsql.Aop.CurdAfter = (s, e) => { + // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); + //}; + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToSql(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToSql(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToSql(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + } + + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs new file mode 100644 index 00000000..d4f3d51e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -0,0 +1,728 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLExpression +{ + public class StringTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs new file mode 100644 index 00000000..6613f1d8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQLExpression +{ + public class TimeSpanTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index d6c8286a..80203ae4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -349,7 +349,6 @@ WHERE ROWNUM < 11"; var testrunsql3 = g.sqlserver.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); var testrunsql4 = g.oracle.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); - var testssargs1 = "10100"; var testformatsql1 = g.mysql.Select().Where(a => a.NamespaceName == $"1_{10100}").ToSql(); var testorderbysql = g.mysql.Select().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index bee62577..e1ba8a33 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -38,4 +38,27 @@ public class g (cmd, traceLog) => Console.WriteLine(traceLog)) .Build()); public static IFreeSql oracle => oracleLazy.Value; + + static Lazy pgsqlLazy = new Lazy(() => + { + return new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.OdbcPostgreSQL, "Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Maximum Pool Size=2") + .UseAutoSyncStructure(true) + .UseSyncStructureToLower(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build(); + }); + public static IFreeSql pgsql => pgsqlLazy.Value; + + static Lazy odbcLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Odbc, "Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Max pool size=5") + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .UseLazyLoading(true) + .Build()); + public static IFreeSql odbc => odbcLazy.Value; } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs index 7d8f4d28..c84cf19d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs @@ -60,7 +60,7 @@ namespace FreeSql.Tests.PostgreSQL class xxx { - public int Id { get; set; } + public string Id { get; set; } public string Path { get; set; } public string Title2 { get; set; } } diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index a45c7609..6ea9bca0 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -8,6 +8,17 @@ namespace FreeSql MySql, SqlServer, PostgreSQL, Oracle, Sqlite, - OdbcOracle, OdbcSqlServer, OdbcMySql + OdbcOracle, OdbcSqlServer, OdbcMySql, OdbcPostgreSQL, + + /// + /// 通用的 Odbc 实现,只能做基本的 Crud 操作 + /// 不支持实体结构迁移、不支持分页(只能 Take 查询) + /// + /// 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 + /// 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 + /// + /// 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 + /// + Odbc } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fe720cbb..f7b69b75 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d2e8ac7d..ea546645 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -345,6 +345,15 @@ 枚举项 + + + 通用的 Odbc 实现,只能做基本的 Crud 操作 + 不支持实体结构迁移、不支持分页(只能 Take 查询) + 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 + + 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index a81d0767..12b4102f 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -178,6 +178,14 @@ namespace FreeSql type = Type.GetType("FreeSql.Odbc.MySql.OdbcMySqlProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); break; + case DataType.OdbcPostgreSQL: + type = Type.GetType("FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + break; + case DataType.Odbc: + type = Type.GetType("FreeSql.Odbc.Default.OdbcProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + break; default: throw new Exception("未指定 UseConnectionString"); } @@ -202,34 +210,24 @@ namespace FreeSql switch (_entityPropertyConvertType) { case StringConvertType.Lower: - ret.Aop.ConfigEntityProperty += (s, e) => - { + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToLower(); - }; break; case StringConvertType.Upper: - ret.Aop.ConfigEntityProperty += (s, e) => - { + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToUpper(); - }; break; case StringConvertType.PascalCaseToUnderscore: - ret.Aop.ConfigEntityProperty += (s, e) => - { + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); - }; break; case StringConvertType.PascalCaseToUnderscoreWithLower: - ret.Aop.ConfigEntityProperty += (s, e) => - { + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); - }; break; case StringConvertType.PascalCaseToUnderscoreWithUpper: - ret.Aop.ConfigEntityProperty += (s, e) => - { + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); - }; break; default: break; @@ -258,20 +256,25 @@ namespace FreeSql switch (ret.Ado.DataType) { case DataType.MySql: + case DataType.OdbcMySql: e.ModifyResult.DbType = tryval > 0 ? $"varchar({tryval})" : "text"; break; case DataType.SqlServer: + case DataType.OdbcSqlServer: e.ModifyResult.DbType = tryval > 0 ? $"nvarchar({tryval})" : "nvarchar(max)"; break; case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: e.ModifyResult.DbType = tryval > 0 ? $"varchar({tryval})" : "text"; break; case DataType.Oracle: + case DataType.OdbcOracle: e.ModifyResult.DbType = tryval > 0 ? $"nvarchar2({tryval})" : "nvarchar2(4000)"; break; case DataType.Sqlite: e.ModifyResult.DbType = tryval > 0 ? $"nvarchar({tryval})" : "text"; break; + } } } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 9e1304c0..a71c680a 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -27,7 +27,7 @@ namespace FreeSql.Internal.CommonProvider _commonExpression = commonExpression; } - public bool IsAutoSyncStructure { get; set; } = false; + public virtual bool IsAutoSyncStructure { get; set; } = false; public bool IsSyncStructureToLower { get; set; } = false; public bool IsSyncStructureToUpper { get; set; } = false; public bool IsConfigEntityFromDbFirst { get; set; } = false; diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index ba7074fa..0d3d8c05 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 4bfc1a4c..cb48f2a4 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -383,7 +383,7 @@ namespace FreeSql.MySql case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)"; } break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; case "ToString": return exp.Arguments.Count == 0 ? $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')" : null; } @@ -419,8 +419,8 @@ namespace FreeSql.MySql { case "Add": return $"({left}+{args1})"; case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; case "ToString": return $"cast({left} as char)"; } } diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 5415bd7e..615e6bd0 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs new file mode 100644 index 00000000..2d5168fa --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs @@ -0,0 +1,21 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Default +{ + + class OdbcDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OdbcDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + public override Task> ExecuteDeletedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs new file mode 100644 index 00000000..9b3e7f54 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -0,0 +1,107 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Default +{ + + class OdbcInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + OdbcUtils _utils; + public OdbcInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + _utils = _commonUtils as OdbcUtils; + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + public override List ExecuteInserted() => base.SplitExecuteInserted(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + Object poolConn = null; + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, string.Concat(sql, $"; {_utils.Adapter.InsertAfterGetIdentitySql}"), _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + var conn = _connection; + if (_transaction != null) conn = _transaction.Connection; + if (conn == null) + { + poolConn = _orm.Ado.MasterPool.Get(); + conn = poolConn.Value; + } + _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _params); + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, _utils.Adapter.InsertAfterGetIdentitySql)), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (poolConn != null) + _orm.Ado.MasterPool.Return(poolConn); + + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + Object poolConn = null; + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, string.Concat(sql, $"; {_utils.Adapter.InsertAfterGetIdentitySql}"), _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + var conn = _connection; + if (_transaction != null) conn = _transaction.Connection; + if (conn == null) + { + poolConn = _orm.Ado.MasterPool.Get(); + conn = poolConn.Value; + } + await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _params); + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, _utils.Adapter.InsertAfterGetIdentitySql)), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (poolConn != null) + _orm.Ado.MasterPool.Return(poolConn); + + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + protected override Task> RawExecuteInsertedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs new file mode 100644 index 00000000..14e8c520 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -0,0 +1,189 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Default +{ + + class OdbcSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + { + var _utils = _commonUtils as OdbcUtils; + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_limit > 0 && _utils.Adapter.SelectTopStyle == OdbcAdapter.SelecTopStyle.Top) sb.Append("TOP ").Append(_skip + _limit).Append(" "); + sb.Append(field); + if (_skip > 0) + { + if (string.IsNullOrEmpty(_orderby)) + { + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); + } + sb.Append(", ROW_NUMBER() OVER(").Append(_orderby).Append(") AS __rownum__"); + + throw new NotImplementedException("FreeSql.Odbc.Default 未实现 Skip/Offset 功能,如果需要分页请使用判断上一次 id"); + } + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip <= 0) + sb.Append(_orderby); + else + sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); + + sbnav.Clear(); + if (_limit > 0 && _utils.Adapter.SelectTopStyle == OdbcAdapter.SelecTopStyle.Limit) sb.Append(" \r\nLIMIT ").Append(_skip + _limit); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.ToString(); + } + + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs new file mode 100644 index 00000000..f0c73c20 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Default +{ + + class OdbcUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + OdbcUtils _utils; + public OdbcUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + _utils = _commonUtils as OdbcUtils; + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + + protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + protected override Task> RawExecuteUpdatedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(", "); + caseWhen.Append(_utils.Adapter.CastSql(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)), _utils.Adapter.MappingOdbcTypeVarChar)); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(", "); + sb.Append(_utils.Adapter.CastSql(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)), _utils.Adapter.MappingOdbcTypeVarChar)); + ++pkidx; + } + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs new file mode 100644 index 00000000..0e54cd1f --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.Odbc.Default +{ + public class OdbcAdapter + { + /// + /// Select TOP 1,或 Limit 1 风格 + /// + public virtual SelecTopStyle SelectTopStyle => SelecTopStyle.Top; + public enum SelecTopStyle { Top, Limit } + + /// + /// 插入成功后,获取自增值 + /// + public virtual string InsertAfterGetIdentitySql => "SELECT SCOPE_IDENTITY()"; + /// + /// 批量插入时,自动拆分的每次执行数量 + /// + public virtual int InsertBatchSplitLimit => 255; + /// + /// 批量更新时,自动拆分的每次执行数量 + /// + public virtual int UpdateBatchSplitLimit => 255; + + public virtual string MappingOdbcTypeBit => "int"; + public virtual string MappingOdbcTypeSmallInt => "smallint"; + public virtual string MappingOdbcTypeInt => "int"; + public virtual string MappingOdbcTypeBigInt => "bigint"; + public virtual string MappingOdbcTypeTinyInt => "tinyint"; + public virtual string MappingOdbcTypeDecimal => "decimal"; + public virtual string MappingOdbcTypeDouble => "float"; + public virtual string MappingOdbcTypeReal => "real"; + public virtual string MappingOdbcTypeDateTime => "datetime"; + public virtual string MappingOdbcTypeVarBinary => "varbinary"; + public virtual string MappingOdbcTypeVarChar => "nvarchar"; + public virtual string MappingOdbcTypeText => "nvarchar(max)"; + public virtual string MappingOdbcTypeUniqueIdentifier => "uniqueidentifier"; + + public virtual char QuoteSqlNameLeft => '['; + public virtual char QuoteSqlNameRight => ']'; + + public virtual string FieldSql(Type type, string columnName) => columnName; + public virtual string UnicodeStringRawSql(object value) => value == null ? "NULL" : string.Concat("N'", value.ToString().Replace("'", "''"), "'"); + public virtual string DateTimeRawSql(object value) + { + if (value == null) return "NULL"; + if (value.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + return string.Concat("'", ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss"), "'"); + } + public virtual string TimeSpanRawSql(object value) => value == null ? "NULL" : ((TimeSpan)value).TotalSeconds.ToString(); + public virtual string ByteRawSql(object value) + { + if (value == null) return "NULL"; + var bytes = value as byte[]; + var sb = new StringBuilder().Append("0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.ToString(); + } + + public virtual string CastSql(string sql, string to) => $"cast({sql} as {to})"; + public virtual string IsNullSql(string sql, object value) => $"isnull({sql}, {value})"; + public virtual string ConcatSql(string[] objs, Type[] types) + { + var sb = new StringBuilder(); + var news = new string[objs.Length]; + for (var a = 0; a < objs.Length; a++) + news[a] = types[a] == typeof(string) ? objs[a] : $"cast({objs[a]} as nvarchar)"; + return string.Join(" + ", news); + } + + public virtual string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public virtual string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + + public virtual string LambdaConvert_ToBoolean(Type type, string operand) => $"(cast({operand} as varchar) not in ('0','false'))"; + public virtual string LambdaConvert_ToByte(Type type, string operand) => $"cast({operand} as tinyint)"; + public virtual string LambdaConvert_ToChar(Type type, string operand) => $"substring(cast({operand} as varchar),1,1)"; + public virtual string LambdaConvert_ToDateTime(Type type, string operand) => $"cast({operand} as datetime)"; + public virtual string LambdaConvert_ToDecimal(Type type, string operand) => $"cast({operand} as decimal(36,18))"; + public virtual string LambdaConvert_ToDouble(Type type, string operand) => $"cast({operand} as decimal(32,16))"; + public virtual string LambdaConvert_ToInt16(Type type, string operand) => $"cast({operand} as smallint)"; + public virtual string LambdaConvert_ToInt32(Type type, string operand) => $"cast({operand} as int)"; + public virtual string LambdaConvert_ToInt64(Type type, string operand) => $"cast({operand} as bigint)"; + public virtual string LambdaConvert_ToSByte(Type type, string operand) => $"cast({operand} as tinyint)"; + public virtual string LambdaConvert_ToSingle(Type type, string operand) => $"cast({operand} as decimal(14,7))"; + public virtual string LambdaConvert_ToString(Type type, string operand) => type.NullableTypeOrThis() == typeof(Guid) ? $"cast({operand} as varchar(36))" : $"cast({operand} as nvarchar)"; + public virtual string LambdaConvert_ToUInt16(Type type, string operand) => $"cast({operand} as smallint)"; + public virtual string LambdaConvert_ToUInt32(Type type, string operand) => $"cast({operand} as int)"; + public virtual string LambdaConvert_ToUInt64(Type type, string operand) => $"cast({operand} as bigint)"; + public virtual string LambdaConvert_ToGuid(Type type, string operand) => $"cast({operand} as uniqueidentifier)"; + + public virtual string LambdaGuid_NewGuid => "newid()"; + public virtual string LambdaRandom_Next => "cast(rand()*1000000000 as int)"; + public virtual string LambdaRandom_NextDouble => "rand()"; + + public virtual string LambdaString_IsNullOrEmpty(string operand) => $"({operand} is null or {operand} = '')"; + public virtual string LambdaString_IsNullOrWhiteSpace(string operand) => $"({operand} is null or {operand} = '' or ltrim({operand}) = '')"; + public virtual string LambdaString_Length(string operand) => $"len({operand})"; + + public virtual string LambdaString_ToLower(string operand) => $"lower({operand})"; + public virtual string LambdaString_ToUpper(string operand) => $"upper({operand})"; + public virtual string LambdaString_Substring(string operand, string startIndex, string length) => string.IsNullOrEmpty(length) ? $"left({operand}, {startIndex})" : $"substring({operand}, {startIndex}, {length})"; + public virtual string LambdaString_IndexOf(string operand, string value, string startIndex) => string.IsNullOrEmpty(startIndex) ? $"(charindex({operand}, {value})-1)" : $"(charindex({operand}, {value}, {startIndex})-1)"; + public virtual string LambdaString_PadLeft(string operand, string length, string paddingChar) => string.IsNullOrEmpty(paddingChar) ? $"lpad({operand}, {length})" : $"lpad({operand}, {length}, {paddingChar})"; + public virtual string LambdaString_PadRight(string operand, string length, string paddingChar) => string.IsNullOrEmpty(paddingChar) ? $"rpad({operand}, {length})" : $"rpad({operand}, {length}, {paddingChar})"; + public virtual string LambdaString_Trim(string operand) => $"ltrim(rtrim({operand}))"; + public virtual string LambdaString_TrimStart(string operand) => $"ltrim({operand})"; + public virtual string LambdaString_TrimEnd(string operand) => $"rtrim({operand})"; + public virtual string LambdaString_Replace(string operand, string oldValue, string newValue) => $"replace({operand}, {oldValue}, {newValue})"; + public virtual string LambdaString_CompareTo(string operand, string value) => $"({operand} - {value})"; + public virtual string LambdaString_Equals(string operand, string value) => $"({operand} = {value})"; + + public virtual string LambdaDateTime_Now => "getdate()"; + public virtual string LambdaDateTime_UtcNow => "getutcdate()"; + public virtual string LambdaDateTime_Today => "convert(char(10),getdate(),120)"; + public virtual string LambdaDateTime_MinValue => "'1753/1/1 0:00:00'"; + public virtual string LambdaDateTime_MaxValue => "'9999/12/31 23:59:59'"; + public virtual string LambdaDateTime_Date(string operand) => $"convert(char(10),{operand},120)"; + public virtual string LambdaDateTime_TimeOfDay(string operand) => $"datediff(second, convert(char(10),{operand},120), {operand})"; + public virtual string LambdaDateTime_DayOfWeek(string operand) => $"(datepart(weekday, {operand})-1)"; + public virtual string LambdaDateTime_Day(string operand) => $"datepart(day, {operand})"; + public virtual string LambdaDateTime_DayOfYear(string operand) => $"datepart(dayofyear, {operand})"; + public virtual string LambdaDateTime_Month(string operand) => $"datepart(month, {operand})"; + public virtual string LambdaDateTime_Year(string operand) => $"datepart(year, {operand})"; + public virtual string LambdaDateTime_Hour(string operand) => $"datepart(hour, {operand})"; + public virtual string LambdaDateTime_Minute(string operand) => $"datepart(minute, {operand})"; + public virtual string LambdaDateTime_Second(string operand) => $"datepart(second, {operand})"; + public virtual string LambdaDateTime_Millisecond(string operand) => $"(datepart(millisecond, {operand})/1000)"; + public virtual string LambdaDateTime_Ticks(string operand) => $"(cast(datediff(second, '1970-1-1', {operand}) as bigint)*10000000+621355968000000000)"; + + public virtual string LambdaDateTime_DaysInMonth(string year, string month) => $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({year} as varchar) + '-' + cast({month} as varchar) + '-1')))"; + public virtual string LambdaDateTime_IsLeapYear(string year) => $"(({year})%4=0 AND ({year})%100<>0 OR ({year})%400=0)"; + public virtual string LambdaDateTime_Add(string operand, string value) => $"dateadd(second, {value}, {operand})"; + public virtual string LambdaDateTime_AddDays(string operand, string value) => $"dateadd(day, {value}, {operand})"; + public virtual string LambdaDateTime_AddHours(string operand, string value) => $"dateadd(hour, {value}, {operand})"; + public virtual string LambdaDateTime_AddMilliseconds(string operand, string value) => $"dateadd(second, ({value})/1000, {operand})"; + public virtual string LambdaDateTime_AddMinutes(string operand, string value) => $"dateadd(minute, {value}, {operand})"; + public virtual string LambdaDateTime_AddMonths(string operand, string value) => $"dateadd(month, {value}, {operand})"; + public virtual string LambdaDateTime_AddSeconds(string operand, string value) => $"dateadd(second, {value}, {operand})"; + public virtual string LambdaDateTime_AddTicks(string operand, string value) => $"dateadd(second, ({value})/10000000, {operand})"; + public virtual string LambdaDateTime_AddYears(string operand, string value) => $"dateadd(year, {value}, {operand})"; + public virtual string LambdaDateTime_Subtract(string operand, string value) => $"datediff(second, {value}, {operand})"; + public virtual string LambdaDateTime_SubtractTimeSpan(string operand, string value) => $"dateadd(second, ({value})*-1, {operand})"; + public virtual string LambdaDateTime_Equals(string operand, string value) => $"({operand} = {value})"; + public virtual string LambdaDateTime_CompareTo(string operand, string value) => $"datediff(second,{value},{operand})"; + public virtual string LambdaDateTime_ToString(string operand) => $"convert(varchar, {operand}, 121)"; + + public virtual string LambdaMath_Abs(string operand) => $"abs({operand})"; + public virtual string LambdaMath_Sign(string operand) => $"sign({operand})"; + public virtual string LambdaMath_Floor(string operand) => $"floor({operand})"; + public virtual string LambdaMath_Ceiling(string operand) => $"ceiling({ operand})"; + public virtual string LambdaMath_Round(string operand, string decimals) => $"round({operand}, {decimals})"; + public virtual string LambdaMath_Exp(string operand) => $"exp({operand})"; + public virtual string LambdaMath_Log(string operand) => $"log({operand})"; + public virtual string LambdaMath_Log10(string operand) => $"log10({operand})"; + public virtual string LambdaMath_Pow(string operand, string y) => $"power({operand}, {y})"; + public virtual string LambdaMath_Sqrt(string operand) => $"sqrt({operand})"; + public virtual string LambdaMath_Cos(string operand) => $"cos({operand})"; + public virtual string LambdaMath_Sin(string operand) => $"sin({operand})"; + public virtual string LambdaMath_Tan(string operand) => $"tan({operand})"; + public virtual string LambdaMath_Acos(string operand) => $"acos({operand})"; + public virtual string LambdaMath_Asin(string operand) => $"asin({operand})"; + public virtual string LambdaMath_Atan(string operand) => $"atan({operand})"; + public virtual string LambdaMath_Atan2(string operand, string x) => $"atan2({operand}, {x})"; + public virtual string LambdaMath_Truncate(string operand) => $"floor({operand})"; + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs new file mode 100644 index 00000000..a2fa7646 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -0,0 +1,73 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.Odbc.Default +{ + class OdbcAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public OdbcAdo() : base(DataType.Odbc) { } + public OdbcAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Odbc) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OdbcConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OdbcConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + OdbcAdapter Adapter => (_util == null ? FreeSqlOdbcGlobalExtensions.DefaultOdbcAdapter : _util._orm.GetOdbcAdapter()); + + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string) + return Adapter.UnicodeStringRawSql(param); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return Adapter.DateTimeRawSql(param); + else if (param is TimeSpan || param is TimeSpan?) + return Adapter.TimeSpanRawSql(param); + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new OdbcCommand(); + } + + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as OdbcConnectionPool).Return(conn, ex); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs new file mode 100644 index 00000000..dc8e581a --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -0,0 +1,236 @@ +using SafeObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Default +{ + + class OdbcConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public OdbcConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new OdbcConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + + if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class OdbcConnectionPoolPolicy : IPolicy + { + + internal OdbcConnectionPool _pool; + public string Name { get; set; } = "Default OdbcConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs new file mode 100644 index 00000000..9eee66a9 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs @@ -0,0 +1,90 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.Default +{ + + class OdbcCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsAutoSyncStructure { get => false; set => base.IsAutoSyncStructure = false; } + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public OdbcCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) + { + _utils = _commonUtils as OdbcUtils; + } + + OdbcUtils _utils; + object _dicCsToDbLock = new object(); + Dictionary _dicCsToDb; + + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb == null) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb == null) + { + var reg = new Regex(@"\([^\)]+\)", RegexOptions.IgnoreCase | RegexOptions.Compiled); + Func deleteBrackets = str => reg.Replace(str, ""); + + _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (OdbcType.Bit, _utils.Adapter.MappingOdbcTypeBit,$"{_utils.Adapter.MappingOdbcTypeBit} NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, _utils.Adapter.MappingOdbcTypeBit,_utils.Adapter.MappingOdbcTypeBit, null, true, null) }, + + { typeof(sbyte).FullName, (OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, $"{_utils.Adapter.MappingOdbcTypeSmallInt} NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, false, true, null) }, + { typeof(short).FullName, (OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt,$"{_utils.Adapter.MappingOdbcTypeSmallInt} NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, false, true, null) }, + { typeof(int).FullName, (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, $"{_utils.Adapter.MappingOdbcTypeInt} NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, _utils.Adapter.MappingOdbcTypeInt, false, true, null) }, + { typeof(long).FullName, (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt,$"{_utils.Adapter.MappingOdbcTypeBigInt} NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt,_utils.Adapter.MappingOdbcTypeBigInt, false, true, null) }, + + { typeof(byte).FullName, (OdbcType.TinyInt, _utils.Adapter.MappingOdbcTypeTinyInt,$"{_utils.Adapter.MappingOdbcTypeTinyInt} NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, _utils.Adapter.MappingOdbcTypeTinyInt,_utils.Adapter.MappingOdbcTypeTinyInt, true, true, null) }, + { typeof(ushort).FullName, (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt,$"{_utils.Adapter.MappingOdbcTypeInt} NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, _utils.Adapter.MappingOdbcTypeInt, true, true, null) }, + { typeof(uint).FullName, (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, $"{_utils.Adapter.MappingOdbcTypeBigInt} NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, _utils.Adapter.MappingOdbcTypeBigInt, true, true, null) }, + { typeof(ulong).FullName, (OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(20,0)", true, true, null) }, + + { typeof(double).FullName, (OdbcType.Double, _utils.Adapter.MappingOdbcTypeDouble, $"{_utils.Adapter.MappingOdbcTypeDouble} NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, _utils.Adapter.MappingOdbcTypeDouble, _utils.Adapter.MappingOdbcTypeDouble, false, true, null) }, + { typeof(float).FullName, (OdbcType.Real, _utils.Adapter.MappingOdbcTypeReal,$"{_utils.Adapter.MappingOdbcTypeReal} NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, _utils.Adapter.MappingOdbcTypeReal,_utils.Adapter.MappingOdbcTypeReal, false, true, null) }, + { typeof(decimal).FullName, (OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(10,2)", false, true, null) }, + + { typeof(DateTime).FullName, (OdbcType.DateTime, _utils.Adapter.MappingOdbcTypeDateTime, $"{_utils.Adapter.MappingOdbcTypeDateTime} NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, _utils.Adapter.MappingOdbcTypeDateTime, _utils.Adapter.MappingOdbcTypeDateTime, false, true, null) }, + + { typeof(byte[]).FullName, (OdbcType.VarBinary, _utils.Adapter.MappingOdbcTypeVarBinary, $"{_utils.Adapter.MappingOdbcTypeVarBinary}(255)", false, null, new byte[0]) }, + { typeof(string).FullName, (OdbcType.VarChar, _utils.Adapter.MappingOdbcTypeVarChar, $"{_utils.Adapter.MappingOdbcTypeVarChar}(255)", false, null, "") }, + + { typeof(Guid).FullName, (OdbcType.UniqueIdentifier, deleteBrackets(_utils.Adapter.MappingOdbcTypeUniqueIdentifier), $"{_utils.Adapter.MappingOdbcTypeUniqueIdentifier} NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.UniqueIdentifier, deleteBrackets(_utils.Adapter.MappingOdbcTypeUniqueIdentifier), _utils.Adapter.MappingOdbcTypeUniqueIdentifier, false, true, null) }, + }; + } + } + } + + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, $"{_utils.Adapter.MappingOdbcTypeBigInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, $"{_utils.Adapter.MappingOdbcTypeInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + public override string GetComparisonDDLStatements(params Type[] entityTypes) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs new file mode 100644 index 00000000..534bb1fa --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -0,0 +1,441 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Default +{ + class OdbcExpression : CommonExpression + { + OdbcUtils _utils; + public OdbcExpression(CommonUtils common) : base(common) + { + _utils = common as OdbcUtils; + } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return _utils.Adapter.LambdaConvert_ToBoolean(operandExp.Type, getExp(operandExp)); + case "System.Byte": return _utils.Adapter.LambdaConvert_ToByte(operandExp.Type, getExp(operandExp)); + case "System.Char": return _utils.Adapter.LambdaConvert_ToChar(operandExp.Type, getExp(operandExp)); + case "System.DateTime": return _utils.Adapter.LambdaConvert_ToDateTime(operandExp.Type, getExp(operandExp)); + case "System.Decimal": return _utils.Adapter.LambdaConvert_ToDecimal(operandExp.Type, getExp(operandExp)); + case "System.Double": return _utils.Adapter.LambdaConvert_ToDouble(operandExp.Type, getExp(operandExp)); + case "System.Int16": return _utils.Adapter.LambdaConvert_ToInt16(operandExp.Type, getExp(operandExp)); + case "System.Int32": return _utils.Adapter.LambdaConvert_ToInt32(operandExp.Type, getExp(operandExp)); + case "System.Int64": return _utils.Adapter.LambdaConvert_ToInt64(operandExp.Type, getExp(operandExp)); + case "System.SByte": return _utils.Adapter.LambdaConvert_ToSByte(operandExp.Type, getExp(operandExp)); + case "System.Single": return _utils.Adapter.LambdaConvert_ToSingle(operandExp.Type, getExp(operandExp)); + case "System.String": return _utils.Adapter.LambdaConvert_ToString(operandExp.Type, getExp(operandExp)); + case "System.UInt16": return _utils.Adapter.LambdaConvert_ToUInt16(operandExp.Type, getExp(operandExp)); + case "System.UInt32": return _utils.Adapter.LambdaConvert_ToUInt32(operandExp.Type, getExp(operandExp)); + case "System.UInt64": return _utils.Adapter.LambdaConvert_ToUInt64(operandExp.Type, getExp(operandExp)); + case "System.Guid": return _utils.Adapter.LambdaConvert_ToGuid(operandExp.Type, getExp(operandExp)); + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return _utils.Adapter.LambdaConvert_ToBoolean(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Byte": return _utils.Adapter.LambdaConvert_ToByte(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Char": return _utils.Adapter.LambdaConvert_ToChar(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.DateTime": return _utils.Adapter.LambdaConvert_ToDateTime(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Decimal": return _utils.Adapter.LambdaConvert_ToDecimal(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Double": return _utils.Adapter.LambdaConvert_ToDouble(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Int16": return _utils.Adapter.LambdaConvert_ToInt16(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Int32": return _utils.Adapter.LambdaConvert_ToInt32(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Int64": return _utils.Adapter.LambdaConvert_ToInt64(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.SByte": return _utils.Adapter.LambdaConvert_ToSByte(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Single": return _utils.Adapter.LambdaConvert_ToSingle(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.UInt16": return _utils.Adapter.LambdaConvert_ToUInt16(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.UInt32": return _utils.Adapter.LambdaConvert_ToUInt32(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.UInt64": return _utils.Adapter.LambdaConvert_ToUInt64(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + case "System.Guid": return _utils.Adapter.LambdaConvert_ToGuid(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); + } + break; + case "NewGuid": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Guid": return _utils.Adapter.LambdaGuid_NewGuid; + } + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return _utils.Adapter.LambdaRandom_Next; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return _utils.Adapter.LambdaRandom_NextDouble; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return _utils.Adapter.LambdaRandom_NextDouble; + break; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? _utils.Adapter.LambdaConvert_ToString(callExp.Object.Type, getExp(callExp.Object)) : null; + break; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in + return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return _utils.Adapter.LambdaString_Length(left); + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _utils.Adapter.LambdaDateTime_Now; + case "UtcNow": return _utils.Adapter.LambdaDateTime_UtcNow; + case "Today": return _utils.Adapter.LambdaDateTime_Today; + case "MinValue": return _utils.Adapter.LambdaDateTime_MinValue; + case "MaxValue": return _utils.Adapter.LambdaDateTime_MaxValue; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return _utils.Adapter.LambdaDateTime_Date(left); + case "TimeOfDay": return _utils.Adapter.LambdaDateTime_TimeOfDay(left); + case "DayOfWeek": return _utils.Adapter.LambdaDateTime_DayOfWeek(left); + case "Day": return _utils.Adapter.LambdaDateTime_Day(left); + case "DayOfYear": return _utils.Adapter.LambdaDateTime_DayOfYear(left); + case "Month": return _utils.Adapter.LambdaDateTime_Month(left); + case "Year": return _utils.Adapter.LambdaDateTime_Year(left); + case "Hour": return _utils.Adapter.LambdaDateTime_Hour(left); + case "Minute": return _utils.Adapter.LambdaDateTime_Minute(left); + case "Second": return _utils.Adapter.LambdaDateTime_Second(left); + case "Millisecond": return _utils.Adapter.LambdaDateTime_Millisecond(left); + case "Ticks": return _utils.Adapter.LambdaDateTime_Ticks(left); + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return _utils.Adapter.LambdaMath_Floor($"({left})/{60 * 60 * 24}"); + case "Hours": return _utils.Adapter.LambdaMath_Floor($"({left})/{60 * 60}%24"); + case "Milliseconds": return $"({_utils.Adapter.CastSql(left, _utils.Adapter.MappingOdbcTypeBigInt)}*1000)"; + case "Minutes": return _utils.Adapter.LambdaMath_Floor($"({left})/60%60"); + case "Seconds": return $"(({left})%60)"; + case "Ticks": return $"({_utils.Adapter.CastSql(left, _utils.Adapter.MappingOdbcTypeBigInt)}*10000000)"; + case "TotalDays": return $"(({left})/{60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{60 * 60})"; + case "TotalMilliseconds": return $"({_utils.Adapter.CastSql(left, _utils.Adapter.MappingOdbcTypeBigInt)}*1000)"; + case "TotalMinutes": return $"(({left})/60)"; + case "TotalSeconds": return $"({left})"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": return _utils.Adapter.LambdaString_IsNullOrEmpty(getExp(exp.Arguments[0])); + case "IsNullOrWhiteSpace": return _utils.Adapter.LambdaString_IsNullOrWhiteSpace(getExp(exp.Arguments[0])); + case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"({_common.StringConcat(new string[] { args0Value, "'%'" }, new[] { typeof(int), typeof(string) })})")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"({_common.StringConcat(new string[] { "'%'", args0Value }, new[] { typeof(string), typeof(int) })})")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ({_common.StringConcat(new string[] { "'%'", args0Value, "'%'" }, new[] { typeof(string), typeof(int), typeof(string)})})"; + case "ToLower": return _utils.Adapter.LambdaString_ToLower(left); + case "ToUpper": return _utils.Adapter.LambdaString_ToUpper(left); + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return _utils.Adapter.LambdaString_Substring(left, substrArgs1, null); + return _utils.Adapter.LambdaString_Substring(left, substrArgs1, getExp(exp.Arguments[1])); + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return _utils.Adapter.LambdaString_IndexOf(left, indexOfFindStr, locateArgs1); + } + return _utils.Adapter.LambdaString_IndexOf(left, indexOfFindStr, null); + case "PadLeft": + if (exp.Arguments.Count == 1) return _utils.Adapter.LambdaString_PadLeft(left, getExp(exp.Arguments[0]), null); + return _utils.Adapter.LambdaString_PadLeft(left, getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + case "PadRight": + if (exp.Arguments.Count == 1) return _utils.Adapter.LambdaString_PadRight(left, getExp(exp.Arguments[0]), null); + return _utils.Adapter.LambdaString_PadRight(left, getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + case "Trim": return _utils.Adapter.LambdaString_Trim(left); + case "TrimStart": return _utils.Adapter.LambdaString_TrimStart(left); + case "TrimEnd": return _utils.Adapter.LambdaString_TrimEnd(left); + case "Replace": return _utils.Adapter.LambdaString_Replace(left, getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + case "CompareTo": return _utils.Adapter.LambdaString_CompareTo(left, getExp(exp.Arguments[0])); + case "Equals": return _utils.Adapter.LambdaString_Equals(left, getExp(exp.Arguments[0])); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return _utils.Adapter.LambdaMath_Abs(getExp(exp.Arguments[0])); + case "Sign": return _utils.Adapter.LambdaMath_Sign(getExp(exp.Arguments[0])); + case "Floor": return _utils.Adapter.LambdaMath_Floor(getExp(exp.Arguments[0])); + case "Ceiling": return _utils.Adapter.LambdaMath_Ceiling(getExp(exp.Arguments[0])); + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return _utils.Adapter.LambdaMath_Round(getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + return _utils.Adapter.LambdaMath_Round(getExp(exp.Arguments[0]), "0"); + case "Exp": return _utils.Adapter.LambdaMath_Exp(getExp(exp.Arguments[0])); + case "Log": return _utils.Adapter.LambdaMath_Log(getExp(exp.Arguments[0])); + case "Log10": return _utils.Adapter.LambdaMath_Log10(getExp(exp.Arguments[0])); + case "Pow": return _utils.Adapter.LambdaMath_Pow(getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + case "Sqrt": return _utils.Adapter.LambdaMath_Sqrt(getExp(exp.Arguments[0])); + case "Cos": return _utils.Adapter.LambdaMath_Cos(getExp(exp.Arguments[0])); + case "Sin": return _utils.Adapter.LambdaMath_Sin(getExp(exp.Arguments[0])); + case "Tan": return _utils.Adapter.LambdaMath_Tan(getExp(exp.Arguments[0])); + case "Acos": return _utils.Adapter.LambdaMath_Acos(getExp(exp.Arguments[0])); + case "Asin": return _utils.Adapter.LambdaMath_Asin(getExp(exp.Arguments[0])); + case "Atan": return _utils.Adapter.LambdaMath_Atan(getExp(exp.Arguments[0])); + case "Atan2": return _utils.Adapter.LambdaMath_Atan2(getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + case "Truncate": return _utils.Adapter.LambdaMath_Truncate(getExp(exp.Arguments[0])); + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return _utils.Adapter.LambdaDateTime_CompareTo(getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + case "DaysInMonth": return _utils.Adapter.LambdaDateTime_DaysInMonth(getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + case "Equals": return _utils.Adapter.LambdaDateTime_Equals(getExp(exp.Arguments[0]), getExp(exp.Arguments[1])); + + case "IsLeapYear": return _utils.Adapter.LambdaDateTime_IsLeapYear(getExp(exp.Arguments[0])); + + case "Parse": return _utils.Adapter.LambdaConvert_ToDateTime(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ParseExact": + case "TryParse": + case "TryParseExact": return _utils.Adapter.LambdaConvert_ToDateTime(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return _utils.Adapter.LambdaDateTime_Add(left, args1); + case "AddDays": return _utils.Adapter.LambdaDateTime_AddDays(left, args1); + case "AddHours": return _utils.Adapter.LambdaDateTime_AddHours(left, args1); + case "AddMilliseconds": return _utils.Adapter.LambdaDateTime_AddMilliseconds(left, args1); + case "AddMinutes": return _utils.Adapter.LambdaDateTime_AddMinutes(left, args1); + case "AddMonths": return _utils.Adapter.LambdaDateTime_AddMonths(left, args1); + case "AddSeconds": return _utils.Adapter.LambdaDateTime_AddSeconds(left, args1); + case "AddTicks": return _utils.Adapter.LambdaDateTime_AddTicks(left, args1); + case "AddYears": return _utils.Adapter.LambdaDateTime_AddYears(left, args1); + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return _utils.Adapter.LambdaDateTime_Subtract(left, args1); + case "System.TimeSpan": return _utils.Adapter.LambdaDateTime_SubtractTimeSpan(left, args1); + } + break; + case "Equals": return _utils.Adapter.LambdaDateTime_Equals(left, args1); + case "CompareTo": return _utils.Adapter.LambdaDateTime_CompareTo(left, args1); + case "ToString": return exp.Arguments.Count == 0 ? _utils.Adapter.LambdaDateTime_ToString(left) : null; + } + } + return null; + } + + public virtual string LambdaDateSpan_Add(string operand, string value) => $"({operand}+{value})"; + public virtual string LambdaDateSpan_Subtract(string operand, string value) => $"({operand}-({value}))"; + public virtual string LambdaDateSpan_Equals(string oldvalue, string newvalue) => $"({oldvalue} = {newvalue})"; + public virtual string LambdaDateSpan_CompareTo(string oldvalue, string newvalue) => $"({oldvalue}-({newvalue}))"; + + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; + case "FromSeconds": return $"({getExp(exp.Arguments[0])})"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; + case "Parse": return _utils.Adapter.LambdaConvert_ToInt64(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ParseExact": + case "TryParse": + case "TryParseExact": return _utils.Adapter.LambdaConvert_ToInt64(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return _utils.Adapter.LambdaConvert_ToString(exp.Type, left); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return _utils.Adapter.LambdaConvert_ToBoolean(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToByte": return _utils.Adapter.LambdaConvert_ToByte(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToChar": return _utils.Adapter.LambdaConvert_ToChar(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToDateTime": return _utils.Adapter.LambdaConvert_ToDateTime(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToDecimal": return _utils.Adapter.LambdaConvert_ToDecimal(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToDouble": return _utils.Adapter.LambdaConvert_ToDouble(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToInt16": return _utils.Adapter.LambdaConvert_ToInt16(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToInt32": return _utils.Adapter.LambdaConvert_ToInt32(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToInt64": return _utils.Adapter.LambdaConvert_ToInt64(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToSByte": return _utils.Adapter.LambdaConvert_ToSByte(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToSingle": return _utils.Adapter.LambdaConvert_ToSingle(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToString": return _utils.Adapter.LambdaConvert_ToString(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToUInt16": return _utils.Adapter.LambdaConvert_ToUInt16(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToUInt32": return _utils.Adapter.LambdaConvert_ToUInt32(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + case "ToUInt64": return _utils.Adapter.LambdaConvert_ToUInt64(exp.Arguments[0].Type, getExp(exp.Arguments[0])); + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs new file mode 100644 index 00000000..de1daa60 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -0,0 +1,113 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; +using FreeSql.Odbc.Default; + +namespace FreeSql.Odbc.Default +{ + + public class OdbcProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new OdbcSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OdbcSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OdbcInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + + /// + /// 生成一个普通访问功能的 IFreeSql 对象,用来访问 odbc + /// + /// + /// + /// 适配器 + public OdbcProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new OdbcUtils(this); + this.InternalCommonExpression = new OdbcExpression(this.InternalCommonUtils); + + this.Ado = new OdbcAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); + + this.CodeFirst = new OdbcCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + + var _utils = InternalCommonUtils as OdbcUtils; + //处理 MaxLength + this.Aop.ConfigEntityProperty += new EventHandler((s, e) => + { + object[] attrs = null; + try + { + attrs = e.Property.GetCustomAttributes(false).ToArray(); //.net core 反射存在版本冲突问题,导致该方法异常 + } + catch { } + + var maxlenAttr = attrs.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.Name == "MaxLengthAttribute"; + }).FirstOrDefault(); + if (maxlenAttr != null) + { + var lenProp = maxlenAttr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).FirstOrDefault(); + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval)) + { + if (tryval != 0) + { + switch (this.Ado.DataType) + { + case DataType.Sqlite: + e.ModifyResult.DbType = tryval > 0 ? $"{_utils.Adapter.MappingOdbcTypeVarChar}({tryval})" : _utils.Adapter.MappingOdbcTypeText; + break; + } + } + } + } + }); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + + ~OdbcProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + try + { + (this.Ado as AdoProvider)?.Dispose(); + } + finally + { + FreeSqlOdbcGlobalExtensions._dicOdbcAdater.TryRemove(this as IFreeSql, out var tryada); + } + } + } +} + +partial class FreeSqlOdbcGlobalExtensions +{ + internal static OdbcAdapter DefaultOdbcAdapter = new OdbcAdapter(); + internal static ConcurrentDictionary _dicOdbcAdater = new ConcurrentDictionary(); + public static void SetOdbcAdapter(this IFreeSql that, OdbcAdapter adapter) => _dicOdbcAdater.AddOrUpdate(that, adapter, (fsql, old) => adapter); + internal static OdbcAdapter GetOdbcAdapter(this IFreeSql that) => _dicOdbcAdater.TryGetValue(that, out var tryada) ? tryada : DefaultOdbcAdapter; +} diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs new file mode 100644 index 00000000..299ed4b9 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -0,0 +1,73 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Default +{ + + public class OdbcUtils : CommonUtils + { + public OdbcUtils(IFreeSql orm) : base(orm) { } + public OdbcAdapter Adapter => _orm.GetOdbcAdapter(); + + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = new OdbcParameter { ParameterName = $"@{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbc(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + //return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; + return $"{Adapter.QuoteSqlNameLeft}{nametrim.TrimStart(Adapter.QuoteSqlNameLeft).TrimEnd(Adapter.QuoteSqlNameRight).Replace(".", $"{Adapter.QuoteSqlNameRight}.{Adapter.QuoteSqlNameLeft}")}{Adapter.QuoteSqlNameRight}"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + //return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; + return $"{nametrim.TrimStart(Adapter.QuoteSqlNameLeft).TrimEnd(Adapter.QuoteSqlNameRight).Replace($"{Adapter.QuoteSqlNameRight}.{Adapter.QuoteSqlNameLeft}", ".").Replace($".{Adapter.QuoteSqlNameLeft}", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => Adapter.IsNullSql(sql, value); + public override string StringConcat(string[] objs, Type[] types) => Adapter.ConcatSql(objs, types); + public override string Mod(string left, string right, Type leftType, Type rightType) => Adapter.Mod(left, right, leftType, rightType); + public override string Div(string left, string right, Type leftType, Type rightType) => Adapter.Div(left, right, leftType, rightType); + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => Adapter.FieldSql(type, columnName); + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) return Adapter.ByteRawSql(value); + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 70935433..d50c5a49 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,10 +2,10 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin - FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver} + FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git diff --git a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs index 1f4cca13..ec0fd1b2 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs @@ -16,8 +16,8 @@ /// /// /// - public static string FormatOdbcSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args); - static FreeSql.Odbc.SqlServer.OdbcSqlServerAdo _sqlserverAdo = new FreeSql.Odbc.SqlServer.OdbcSqlServerAdo(); + public static string FormatOdbcSqlServer(this string that, params object[] args) => _odbcSqlServerAdo.Addslashes(that, args); + static FreeSql.Odbc.SqlServer.OdbcSqlServerAdo _odbcSqlServerAdo = new FreeSql.Odbc.SqlServer.OdbcSqlServerAdo(); /// /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 @@ -25,6 +25,24 @@ /// /// /// - public static string FormatOdbcMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args); - static FreeSql.Odbc.MySql.OdbcMySqlAdo _mysqlAdo = new FreeSql.Odbc.MySql.OdbcMySqlAdo(); + public static string FormatOdbcMySql(this string that, params object[] args) => _odbcMySqlAdo.Addslashes(that, args); + static FreeSql.Odbc.MySql.OdbcMySqlAdo _odbcMySqlAdo = new FreeSql.Odbc.MySql.OdbcMySqlAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatOdbcPostgreSQL(this string that, params object[] args) => _odbcPostgreSQLAdo.Addslashes(that, args); + static FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLAdo _odbcPostgreSQLAdo = new FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatOdbc(this string that, params object[] args) => _odbcAdo.Addslashes(that, args); + static FreeSql.Odbc.Default.OdbcAdo _odbcAdo = new FreeSql.Odbc.Default.OdbcAdo(); } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index bae459b7..1d9707c3 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -114,60 +114,60 @@ namespace FreeSql.Odbc.MySql } public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 57df27e5..df99ba84 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -1,15 +1,10 @@ -using FreeSql.DataAnnotations; -using FreeSql.DatabaseModel; -using FreeSql.Internal; -using FreeSql.Internal.Model; +using FreeSql.Internal; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Data.Odbc; using System.Linq; using System.Text; -using System.Text.RegularExpressions; namespace FreeSql.Odbc.MySql { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index eed31446..cc27da38 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -383,7 +383,7 @@ namespace FreeSql.Odbc.MySql case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)"; } break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; case "ToString": return exp.Arguments.Count == 0 ? $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')" : null; } @@ -419,8 +419,8 @@ namespace FreeSql.Odbc.MySql { case "Add": return $"({left}+{args1})"; case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; case "ToString": return $"cast({left} as char)"; } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index 88264d50..6d523552 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -126,60 +126,60 @@ namespace FreeSql.Odbc.Oracle } public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 8697c4c3..e92eb774 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -1,9 +1,7 @@ using FreeSql.DataAnnotations; -using FreeSql.DatabaseModel; using FreeSql.Internal; using FreeSql.Internal.Model; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Data.Odbc; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 6408808e..af0c5748 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -385,8 +385,8 @@ namespace FreeSql.Odbc.Oracle case "System.TimeSpan": return $"({left}-{args1})"; } break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; } } @@ -421,8 +421,8 @@ namespace FreeSql.Odbc.Oracle { case "Add": return $"({left}+{args1})"; case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; case "ToString": return $"to_char({left})"; } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs new file mode 100644 index 00000000..f9feba9e --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -0,0 +1,95 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.PostgreSQL +{ + + class OdbcPostgreSQLDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OdbcPostgreSQLDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs new file mode 100644 index 00000000..ef447d69 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -0,0 +1,199 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.PostgreSQL +{ + + class OdbcPostgreSQLInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public OdbcPostgreSQLInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs new file mode 100644 index 00000000..d980d39e --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -0,0 +1,175 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.PostgreSQL +{ + + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append("select * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + foreach (var tb in _tables) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) + sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); + } + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_limit > 0) + sb.Append(" \r\nlimit ").Append(_limit); + if (_skip > 0) + sb.Append(" \r\noffset ").Append(_skip); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.ToString(); + } + + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs new file mode 100644 index 00000000..2ad90e96 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -0,0 +1,149 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.PostgreSQL +{ + + class OdbcPostgreSQLUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public OdbcPostgreSQLUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + + + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + ++pkidx; + } + sb.Append(")"); + } + + protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) + { + if (_noneParameter == false) return; + var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; + if (dbtype == null) return; + + sb.Append("::").Append(dbtype); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs new file mode 100644 index 00000000..3bef8669 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -0,0 +1,71 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.Odbc.PostgreSQL +{ + class OdbcPostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public OdbcPostgreSQLAdo() : base(DataType.PostgreSQL) { } + public OdbcPostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.PostgreSQL) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OdbcPostgreSQLConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OdbcPostgreSQLConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType()) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? "'t'" : "'f'"; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is IEnumerable) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new OdbcCommand(); + } + + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as OdbcPostgreSQLConnectionPool).Return(conn, ex); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs new file mode 100644 index 00000000..defc36a0 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -0,0 +1,241 @@ +using SafeObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.PostgreSQL +{ + + class OdbcPostgreSQLConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public OdbcPostgreSQLConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new OdbcPostgreSQLConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + + if (exception is System.IO.IOException) + { + + base.SetUnavailable(exception); + + } + else if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class OdbcPostgreSQLConnectionPoolPolicy : IPolicy + { + + internal OdbcPostgreSQLConnectionPool _pool; + public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池"; + public int PoolSize { get; set; } = 50; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max(imum)?\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[2].Value, out var poolsize) == false || poolsize <= 0) poolsize = 50; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Maximum pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min(imum)?\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[2].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs new file mode 100644 index 00000000..607938f8 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -0,0 +1,342 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text; + +namespace FreeSql.Odbc.PostgreSQL +{ + + class OdbcPostgreSQLCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public OdbcPostgreSQLCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + + { typeof(sbyte).FullName, (OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(short).FullName, (OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(int).FullName, (OdbcType.Int, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "int4", "int4", false, true, null) }, + { typeof(long).FullName, (OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "int8", "int8", false, true, null) }, + + { typeof(byte).FullName, (OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (OdbcType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(ushort).FullName, (OdbcType.Int, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "int4", "int4", false, true, null) }, + { typeof(uint).FullName, (OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, (OdbcType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, + + { typeof(float).FullName, (OdbcType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "float4", "float4", false, true, null) }, + { typeof(double).FullName, (OdbcType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "float8", "float8", false, true, null) }, + { typeof(decimal).FullName, (OdbcType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, + + { typeof(string).FullName, (OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + + { typeof(TimeSpan).FullName, (OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp", false, true, null) }, + + { typeof(bool).FullName, (OdbcType.Bit, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "bool","bool", null, true, null) }, + { typeof(Byte[]).FullName, (OdbcType.VarBinary, "bytea", "bytea", false, null, new byte[0]) }, + + { typeof(Guid).FullName, (OdbcType.UniqueIdentifier, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.UniqueIdentifier, "uuid", "uuid", false, true, null) }, + }; + + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + var isarray = type.FullName != "System.Byte[]" && type.IsArray; + var elementType = isarray ? type.GetElementType() : type; + var info = GetDbInfoNoneArray(elementType); + if (info == null) return null; + return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable, info.Value.defaultValue); + } + (OdbcType type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfoNoneArray(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (OdbcType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OdbcType.Int, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OdbcType.BigInt, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + public override string GetComparisonDDLStatements(params Type[] entityTypes) + { + var sb = new StringBuilder(); + var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + + foreach (var entityType in entityTypes) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; + + if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 + sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tboldname)) == null) + //旧表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql(@" +select +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, +case when a.attnotnull then '0' else '1' end as is_nullable, +e.adsrc, +a.attndims, +d.description as comment +from pg_class c +inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join pg_type t on t.oid = a.atttypid +left join pg_type t2 on t2.oid = t.typelem +left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join pg_namespace ns on ns.oid = c.relnamespace +inner join pg_namespace ns2 on ns2.oid = t.typnamespace +where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var attndims = int.Parse(string.Concat(a[6])); + var type = string.Concat(a[1]); + var sqlType = string.Concat(a[3]); + var max_length = long.Parse(string.Concat(a[2])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + return new + { + column = string.Concat(a[0]), + sqlType = string.Concat(sqlType), + max_length = long.Parse(string.Concat(a[2])), + is_nullable = string.Concat(a[4]) == "1", + is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + attndims, + comment = string.Concat(a[7]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (isCommentChanged) + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0};\r\n", tbcol.Attribute.DbDefautValue)); + if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" +select +c.attname, +b.relname +from pg_index a +inner join pg_class b on b.oid = a.indexrelid +inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_class d on d.oid = a.indrelid +where ns.nspname in ({0}) and d.relname in ({1}) and a.indisunique = 't'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); + foreach (var uk in tb.Uniques) + { + if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + { + if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select pg_constraint.conname as pk_name from pg_constraint +inner join pg_class on pg_constraint.conrelid = pg_class.oid +inner join pg_namespace on pg_namespace.oid = pg_class.relnamespace +where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contype='p' +", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + foreach (var uk in tb.Uniques) + { + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); + foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"coalesce({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); + sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); + if (seqcol.Item3) + { + sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);\r\n"); + sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); + } + } + return sb.Length == 0 ? null : sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs new file mode 100644 index 00000000..94c26fa5 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -0,0 +1,445 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.PostgreSQL +{ + class OdbcPostgreSQLDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public OdbcPostgreSQLDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetOdbcType(column); + OdbcType GetOdbcType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + var isarray = dbtype.EndsWith("[]"); + if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); + OdbcType ret = OdbcType.VarChar; + switch (dbtype.ToLower().TrimStart('_')) + { + case "int2": ret = OdbcType.SmallInt; break; + case "int4": ret = OdbcType.Int; break; + case "int8": ret = OdbcType.BigInt; break; + case "numeric": ret = OdbcType.Numeric; break; + case "float4": ret = OdbcType.Real; break; + case "float8": ret = OdbcType.Double; break; + case "money": ret = OdbcType.Numeric; break; + + case "bpchar": ret = OdbcType.Char; break; + case "varchar": ret = OdbcType.VarChar; break; + case "text": ret = OdbcType.Text; break; + + case "timestamp": ret = OdbcType.DateTime; break; + case "timestamptz": ret = OdbcType.DateTime; break; + case "date": ret = OdbcType.Date; break; + case "time": ret = OdbcType.Time; break; + case "timetz": ret = OdbcType.Time; break; + case "interval": ret = OdbcType.Time; break; + + case "bool": ret = OdbcType.Bit; break; + case "bytea": ret = OdbcType.VarBinary; break; + case "bit": ret = OdbcType.Bit; break; + case "varbit": ret = OdbcType.VarBinary; break; + + case "json": ret = OdbcType.VarChar; break; + case "jsonb": ret = OdbcType.VarChar; break; + case "uuid": ret = OdbcType.UniqueIdentifier; break; + } + return ret; + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OdbcType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)OdbcType.Numeric, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)OdbcType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OdbcType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + + { (int)OdbcType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)OdbcType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + + { (int)OdbcType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)OdbcType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)OdbcType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select datname from pg_database where datname not in ('template1', 'template0')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public List GetTablesByDatabase(params string[] database) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + var tables = new List(); + + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = $@" +select +b.nspname || '.' || a.tablename, +a.schemaname, +a.tablename , +d.description, +'TABLE' +from pg_tables a +inner join pg_namespace b on b.nspname = a.schemaname +inner join pg_class c on c.relnamespace = b.oid and c.relname = a.tablename +left join pg_description d on d.objoid = c.oid and objsubid = 0 +where a.schemaname not in ('pg_catalog', 'information_schema', 'topology') +and b.nspname || '.' || a.tablename not in ('public.spatial_ref_sys') + +union all + +select +b.nspname || '.' || a.relname, +b.nspname, +a.relname, +d.description, +'VIEW' +from pg_class a +inner join pg_namespace b on b.oid = a.relnamespace +left join pg_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('m','v') +and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews') +"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6.Add(object_id); + break; + case DbTableType.StoreProcedure: + loc66.Add(object_id); + break; + } + } + if (loc6.Count == 0) return loc1; + string loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; + string loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + + sql = $@" +select +ns.nspname || '.' || c.relname as id, +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem = 0 then t.typname else t2.typname end, +case when a.attnotnull then 0 else 1 end as is_nullable, +e.adsrc as is_identity, +--case when e.adsrc = 'nextval(''' || case when ns.nspname = 'public' then '' else ns.nspname || '.' end || c.relname || '_' || a.attname || '_seq''::regclass)' then 1 else 0 end as is_identity, +d.description as comment, +a.attndims, +case when t.typelem = 0 then t.typtype else t2.typtype end, +ns2.nspname, +a.attnum +from pg_class c +inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join pg_type t on t.oid = a.atttypid +left join pg_type t2 on t2.oid = t.typelem +left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join pg_namespace ns on ns.oid = c.relnamespace +inner join pg_namespace ns2 on ns2.oid = t.typnamespace +where ns.nspname || '.' || c.relname in ({loc8})"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var type = string.Concat(row[2]); + var max_length = int.Parse(string.Concat(row[3])); + var sqlType = string.Concat(row[4]); + var is_nullable = string.Concat(row[5]) == "1"; + var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var comment = string.Concat(row[7]); + int attndims = int.Parse(string.Concat(row[8])); + string typtype = string.Concat(row[9]); + string owner = string.Concat(row[10]); + int attnum = int.Parse(string.Concat(row[11])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (max_length <= 0) max_length = -1; + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Coment = comment + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } + + sql = $@" +select +ns.nspname || '.' || d.relname as table_id, +c.attname, +b.relname as index_id, +case when a.indisunique then 1 else 0 end IsUnique, +case when a.indisprimary then 1 else 0 end IsPrimary, +case when a.indisclustered then 0 else 1 end IsClustered, +0 IsDesc, +a.indkey::text, +c.attnum +from pg_index a +inner join pg_class b on b.oid = a.indexrelid +inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_class d on d.oid = a.indrelid +where ns.nspname || '.' || d.relname in ({loc8}) +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var index_id = string.Concat(row[2]); + var is_unique = string.Concat(row[3]) == "1"; + var is_primary_key = string.Concat(row[4]) == "1"; + var is_clustered = string.Concat(row[5]) == "1"; + var is_desc = int.Parse(string.Concat(row[6])); + var inkey = string.Concat(row[7]).Split(' '); + var attnum = int.Parse(string.Concat(row[8])); + attnum = int.Parse(inkey[attnum - 1]); + foreach (string tc in loc3[object_id].Keys) + { + if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) + { + column = tc; + break; + } + } + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + var loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary> loc10 = null; + List loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new List()); + loc11.Add(loc9); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = $@" +select +ns.nspname || '.' || b.relname as table_id, +array(select attname from pg_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, +a.conname as FKId, +ns2.nspname || '.' || c.relname as ref_table_id, +1 as IsForeignKey, +array(select attname from pg_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, +null ref_sln, +null ref_table +from pg_constraint a +inner join pg_class b on b.oid = a.conrelid +inner join pg_class c on c.oid = a.confrelid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_namespace ns2 on ns2.oid = c.relnamespace +where ns.nspname || '.' || b.relname in ({loc8}) +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + { + foreach (var loc5 in loc4.UniquesDict.First().Value) + { + loc5.IsPrimary = true; + loc4.Primarys.Add(loc5); + } + } + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } + + public List GetEnumsByDatabase(params string[] database) + { + if (database == null || database.Length == 0) return new List(); + var drs = _orm.Ado.Query<(string name, string label)>(CommandType.Text, _commonUtils.FormatSql(@" +select +ns.nspname || '.' || a.typname, +b.enumlabel +from pg_type a +inner join pg_enum b on b.enumtypid = a.oid +inner join pg_namespace ns on ns.oid = a.typnamespace +where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information_schema.schemata where catalog_name in {0})", database)); + var ret = new Dictionary>(); + foreach (var dr in drs) + { + if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); + var key = dr.label; + if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) + key = $"Unkown{ret[dr.name].Count + 1}"; + if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); + } + return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs new file mode 100644 index 00000000..5eca4047 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -0,0 +1,538 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.PostgreSQL +{ + class OdbcPostgreSQLExpression : CommonExpression + { + + public OdbcPostgreSQLExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(operandExp)})::int2"; + case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.Decimal": return $"({getExp(operandExp)})::numeric"; + case "System.Double": return $"({getExp(operandExp)})::float8"; + case "System.Int16": return $"({getExp(operandExp)})::int2"; + case "System.Int32": return $"({getExp(operandExp)})::int4"; + case "System.Int64": return $"({getExp(operandExp)})::int8"; + case "System.SByte": return $"({getExp(operandExp)})::int2"; + case "System.Single": return $"({getExp(operandExp)})::float4"; + case "System.String": return $"({getExp(operandExp)})::varchar"; + case "System.UInt16": return $"({getExp(operandExp)})::int2"; + case "System.UInt32": return $"({getExp(operandExp)})::int4"; + case "System.UInt64": return $"({getExp(operandExp)})::int8"; + case "System.Guid": return $"({getExp(operandExp)})::uuid"; + } + } + break; + case ExpressionType.ArrayLength: + var arrOperExp = getExp((exp as UnaryExpression).Operand); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; + case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; + case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; + case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid"; + } + break; + case "NewGuid": + break; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; + break; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + break; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + break; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; + break; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + { + var left = objExp == null ? null : getExp(objExp); + if (objType.FullName == typeof(Dictionary).FullName) + { + switch (callExp.Method.Name) + { + case "Contains": + var right = getExp(callExp.Arguments[argIndex]); + return $"({left} @> ({right}))"; + case "ContainsKey": return $"({left} ? {getExp(callExp.Arguments[argIndex])})"; + case "Concat": return $"({left} || {getExp(callExp.Arguments[argIndex])})"; + case "GetLength": + case "GetLongLength": + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + switch (callExp.Method.Name) + { + case "Any": + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; + case "Contains": + //判断 in 或 array @> array + var right1 = getExp(callExp.Arguments[argIndex]); + if (left.StartsWith("array[") || left.EndsWith("]")) + return $"{right1} in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) + return $"{right1} in {left}"; + if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; + return $"({left} @> array[{right1}])"; + case "Concat": + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + var right2 = getExp(callExp.Arguments[argIndex]); + if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; + return $"({left} || {right2})"; + case "GetLength": + case "GetLongLength": + case "Length": + case "Count": + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + break; + case ExpressionType.MemberAccess: + var memExp = exp as MemberExpression; + var memParentExp = memExp.Expression?.Type; + if (memParentExp?.FullName == "System.Byte[]") return null; + if (memParentExp != null) + { + if (memParentExp.IsArray == true) + { + var left = getExp(memExp.Expression); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + switch (memExp.Member.Name) + { + case "Length": + case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + switch (memParentExp.FullName) + { + case "Newtonsoft.Json.Linq.JToken": + case "Newtonsoft.Json.Linq.JObject": + case "Newtonsoft.Json.Linq.JArray": + var left = getExp(memExp.Expression); + switch (memExp.Member.Name) + { + case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; + } + break; + } + if (memParentExp.FullName == typeof(Dictionary).FullName) + { + var left = getExp(memExp.Expression); + switch (memExp.Member.Name) + { + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("array["); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append("]").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return "current_timestamp"; + case "UtcNow": return "(current_timestamp at time zone 'UTC')"; + case "Today": return "current_date"; + case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; + case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"({left})::date"; + case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)"; + case "DayOfWeek": return $"extract(dow from ({left})::timestamp)"; + case "Day": return $"extract(day from ({left})::timestamp)"; + case "DayOfYear": return $"extract(doy from ({left})::timestamp)"; + case "Month": return $"extract(month from ({left})::timestamp)"; + case "Year": return $"extract(year from ({left})::timestamp)"; + case "Hour": return $"extract(hour from ({left})::timestamp)"; + case "Minute": return $"extract(minute from ({left})::timestamp)"; + case "Second": return $"extract(second from ({left})::timestamp)"; + case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)"; + case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)"; + case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)"; + case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)"; + case "Seconds": return $"(floor(({left})/1000000)::int8%60)"; + case "Ticks": return $"(({left})*10)"; + case "TotalDays": return $"(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left})/1000)"; + case "TotalMinutes": return $"(({left})/{(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left})/1000000)"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + var likeOpt = "LIKE"; + if (exp.Arguments.Count > 1) + { + if (exp.Arguments[1].Type == typeof(bool) || + exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + var trimArg1 = ""; + var trimArg2 = ""; + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + var trimChr = getExp(argsTrim01).Trim('\''); + if (trimChr.Length == 1) trimArg1 += trimChr; + else trimArg2 += $" || ({trimChr})"; + } + } + if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)"; + case "DaysInMonth": return $"extract(day from ({getExp(exp.Arguments[0])} || '-' || {getExp(exp.Arguments[1])} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)"; + case "Equals": return $"(({getExp(exp.Arguments[0])})::timestamp = ({getExp(exp.Arguments[1])})::timestamp)"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; + + case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"(({left})::timestamp+(({args1})||' microseconds')::interval)"; + case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; + case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; + case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; + case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)"; + case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)"; + case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)"; + case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; + case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; + case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; + } + break; + case "Equals": return $"({left} = ({args1})::timestamp)"; + case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; + case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"({left})::varchar"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; + case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; + case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; + case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; + case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; + case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; + case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs new file mode 100644 index 00000000..42dc2c5c --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -0,0 +1,61 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; + +namespace FreeSql.Odbc.PostgreSQL +{ + + public class OdbcPostgreSQLProvider : IFreeSql + { + + static OdbcPostgreSQLProvider() + { + } + + public ISelect Select() where T1 : class => new OdbcPostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OdbcPostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OdbcPostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public OdbcPostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new OdbcPostgreSQLUtils(this); + this.InternalCommonExpression = new OdbcPostgreSQLExpression(this.InternalCommonUtils); + + this.Ado = new OdbcPostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); + + this.DbFirst = new OdbcPostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new OdbcPostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + + ~OdbcPostgreSQLProvider() + { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() + { + if (_isdisposed) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs new file mode 100644 index 00000000..1591c4c8 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -0,0 +1,160 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Data.Common; +using System.Linq; +using System.Net; +using System.Text; +using System.Linq.Expressions; +using System.Reflection; +using System.Data.Odbc; + +namespace FreeSql.Odbc.PostgreSQL +{ + + class OdbcPostgreSQLUtils : CommonUtils + { + public OdbcPostgreSQLUtils(IFreeSql orm) : base(orm) + { + } + + static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) + { + var valueArr = value as Array; + var len = valueArr.GetLength(0); + var ret = Array.CreateInstance(arrayType, len); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); + } + return ret; + } + static Dictionary> dicGetParamterValue = new Dictionary> { + { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, + { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, + { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, + { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + }; + static object getParamterValue(Type type, object value, int level = 0) + { + if (type.FullName == "System.Byte[]") return value; + if (type.IsArray && level == 0) + { + var elementType = type.GetElementType(); + Type enumType = null; + if (elementType.IsEnum) enumType = elementType; + else if (elementType.IsNullableType() && elementType.GenericTypeArguments.First().IsEnum) enumType = elementType.GenericTypeArguments.First(); + if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)); + return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; + } + if (type.IsNullableType()) type = type.GenericTypeArguments.First(); + if (type.IsEnum) return (int)value; + if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); + return value; + } + + public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value != null) value = getParamterValue(type, value); + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + //} + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value != null) value = getParamterValue(type, value); + var ret = new OdbcParameter { ParameterName = $"@{name}", Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + //} + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcPostgreSQL(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + value = getParamterValue(type, value); + var type2 = value.GetType(); + if (type2 == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("'\\x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); + } + else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; + } + else if (value is Array) + { + var valueArr = value as Array; + var eleType = type2.GetElementType(); + var len = valueArr.GetLength(0); + var sb = new StringBuilder().Append("ARRAY["); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + if (a > 0) sb.Append(","); + sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + } + sb.Append("]"); + var dbinfo = _orm.CodeFirst.GetDbInfo(type); + if (dbinfo.HasValue) sb.Append("::").Append(dbinfo.Value.dbtype); + return sb.ToString(); + } + else if (dicGetParamterValue.ContainsKey(type2.FullName)) + { + value = string.Concat(value); + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index f3c9ad18..82a9d7bc 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -1,15 +1,11 @@ -using FreeSql.DataAnnotations; -using FreeSql.DatabaseModel; -using FreeSql.Internal; +using FreeSql.Internal; using FreeSql.Internal.Model; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Data.Odbc; using System.Linq; using System.Text; -using System.Text.RegularExpressions; namespace FreeSql.Odbc.SqlServer { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 1e71ec5e..6496196c 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -362,11 +362,11 @@ namespace FreeSql.Odbc.SqlServer switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"datediff(second, {args1}, {left})"; - case "System.TimeSpan": return $"dateadd(second, {args1}*-1, {left})"; + case "System.TimeSpan": return $"dateadd(second, ({args1})*-1, {left})"; } break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"datediff(second,{getExp(exp.Arguments[0])},{left})"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"datediff(second,{args1},{left})"; case "ToString": return exp.Arguments.Count == 0 ? $"convert(varchar, {left}, 121)" : null; } } @@ -401,8 +401,8 @@ namespace FreeSql.Odbc.SqlServer { case "Add": return $"({left}+{args1})"; case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; case "ToString": return $"cast({left} as varchar)"; } } diff --git a/Providers/FreeSql.Provider.Odbc/readme.md b/Providers/FreeSql.Provider.Odbc/readme.md new file mode 100644 index 00000000..dc77244e --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/readme.md @@ -0,0 +1,25 @@ +FreeSql.Provider.Odbc 实现 ODBC 访问数据库,ODBC 属于比较原始的技术,更新慢,各大数据库厂支持得标准不一,不到万不得已最好别用 odbc,坑比较多。 + +FreeSql.Provider.Odbc 做了四种数据库的专用实现:SqlServer、PostgreSQL、Oracle、MySql,和一种通用实现。 + +专用实现比较有针对性,和原来的 FreeSql.Provider.SqlServer ado.net 相比,只支持较少的基础类型,其他功能几乎都有,包括 CodeFirst 自动迁移。 + +# 通用实现 + +通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库。 + +使用者只需求重写类 FreeSql.Odbc.Default.OdbcAdapter 就可以自定义访问不同的数据库。 + +我们默认做了一套 sqlserver 的语法和映射适配,代码在 Default/OdbcAdapter.cs,请查看代码了解。 + +```csharp +class Mssql2000Adapter : FreeSql.Odbc.Default.OdbcAdapter +{ + public override string InsertAfterGetIdentitySql => "SELECT SCOPE_IDENTITY()"; + //可以重写更多的设置 +} + +fsql.SetOdbcAdapter(new Mssql2000Adapter()); +``` + +适配好新的 OdbcAdapter 后,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法生效。 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index f319e013..eec4affd 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 139d1a6c..8fab54c3 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -385,8 +385,8 @@ namespace FreeSql.Oracle case "System.TimeSpan": return $"({left}-{args1})"; } break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; } } @@ -421,8 +421,8 @@ namespace FreeSql.Oracle { case "Add": return $"({left}+{args1})"; case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"extract(day from ({left}-({getExp(exp.Arguments[0])})))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; case "ToString": return $"to_char({left})"; } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index fcbd11fa..a4dc53bd 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 6678ba40..5ed26c61 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -252,7 +252,10 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + { + if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 5357d296..788f3ae2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -494,8 +494,8 @@ namespace FreeSql.PostgreSQL case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; } break; - case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::timestamp)"; - case "CompareTo": return $"extract(epoch from ({left})::timestamp-({getExp(exp.Arguments[0])})::timestamp)"; + case "Equals": return $"({left} = ({args1})::timestamp)"; + case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')" : null; } } @@ -530,8 +530,8 @@ namespace FreeSql.PostgreSQL { case "Add": return $"({left}+{args1})"; case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; case "ToString": return $"({left})::varchar"; } } diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index bcdb7754..4f14f344 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index d5a1ccdd..ce835798 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -362,11 +362,11 @@ namespace FreeSql.SqlServer switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"datediff(second, {args1}, {left})"; - case "System.TimeSpan": return $"dateadd(second, {args1}*-1, {left})"; + case "System.TimeSpan": return $"dateadd(second, ({args1})*-1, {left})"; } break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"datediff(second,{getExp(exp.Arguments[0])},{left})"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"datediff(second,{args1},{left})"; case "ToString": return exp.Arguments.Count == 0 ? $"convert(varchar, {left}, 121)" : null; } } @@ -401,8 +401,8 @@ namespace FreeSql.SqlServer { case "Add": return $"({left}+{args1})"; case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; case "ToString": return $"cast({left} as varchar)"; } } diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index bf879bd0..4204ab2b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.17 + 0.9.18 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index db13908e..4967e2d8 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -384,10 +384,10 @@ namespace FreeSql.Sqlite switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; - case "System.TimeSpan": return $"datetime({left},(-{args1})||' seconds')"; + case "System.TimeSpan": return $"datetime({left},(({args1})*-1)||' seconds')"; } break; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; case "ToString": return exp.Arguments.Count == 0 ? $"strftime('%Y-%m-%d %H:%M.%f',{left})" : null; } @@ -423,8 +423,8 @@ namespace FreeSql.Sqlite { case "Add": return $"({left}+{args1})"; case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; - case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; case "ToString": return $"cast({left} as character)"; } } From cedbf2abd82848e7c74a5d5981cc1aab3dcaf922 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Sep 2019 00:55:00 +0800 Subject: [PATCH 0156/1029] update --- FreeSql/FreeSql.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ea546645..f52a399d 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -349,6 +349,8 @@ 通用的 Odbc 实现,只能做基本的 Crud 操作 不支持实体结构迁移、不支持分页(只能 Take 查询) + + 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 From 44264882720f96d25bc4790b6d598709b14ee351 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Sep 2019 01:05:36 +0800 Subject: [PATCH 0157/1029] update --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 8deb5c9d..0983dc63 100644 --- a/readme.md +++ b/readme.md @@ -58,7 +58,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | FreeSql.Provider.SqlServer | NETStandard2.0、net451 | | FreeSql.Provider.Sqlite | NETStandard2.0、net45 | | FreeSql.Provider.Oracle | NETStandard2.0、net45 | -| FreeSql.Provider.Odbc | NETStandard2.0、net45 | +| [FreeSql.Provider.Odbc](https://github.com/2881099/FreeSql/tree/master/Providers/FreeSql.Provider.Odbc) | NETStandard2.0、net45 | | FreeSql.Extensions.LazyLoading | NETStandard2.0、net45 | | FreeSql.Extensions.JsonMap | NETStandard2.0、net45 | | FreeSql.Extensions.BaseEntity | NETStandard2.0 | From edf6e1caa21cd17760fa2ad844f33d3a89f6d6c0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Sep 2019 01:14:00 +0800 Subject: [PATCH 0158/1029] update --- Providers/FreeSql.Provider.Odbc/readme.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Providers/FreeSql.Provider.Odbc/readme.md b/Providers/FreeSql.Provider.Odbc/readme.md index dc77244e..3845b770 100644 --- a/Providers/FreeSql.Provider.Odbc/readme.md +++ b/Providers/FreeSql.Provider.Odbc/readme.md @@ -6,7 +6,12 @@ FreeSql.Provider.Odbc 做了四种数据库的专用实现:SqlServer、Postgre # 通用实现 -通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库。 +通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库,牺牲了一些功能: + +- 不支持 CodeFirst 自动迁移 +- 不支持 DbFirst 接口方法的实现 +- 不支持 原来的分页方法,需要自行判断 id 进行分页 +- 只支持较少的基础类型:bool,sbyte,short,int,long,byte,ushort,uint,ulong,double,float,decimal,DateTime,byte[],string,Guid 使用者只需求重写类 FreeSql.Odbc.Default.OdbcAdapter 就可以自定义访问不同的数据库。 From c55d76d3ed2660da1274caeb933191ae861fd827 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Sep 2019 01:18:20 +0800 Subject: [PATCH 0159/1029] update doc --- Providers/FreeSql.Provider.Odbc/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Providers/FreeSql.Provider.Odbc/readme.md b/Providers/FreeSql.Provider.Odbc/readme.md index 3845b770..68529582 100644 --- a/Providers/FreeSql.Provider.Odbc/readme.md +++ b/Providers/FreeSql.Provider.Odbc/readme.md @@ -15,7 +15,7 @@ FreeSql.Provider.Odbc 做了四种数据库的专用实现:SqlServer、Postgre 使用者只需求重写类 FreeSql.Odbc.Default.OdbcAdapter 就可以自定义访问不同的数据库。 -我们默认做了一套 sqlserver 的语法和映射适配,代码在 Default/OdbcAdapter.cs,请查看代码了解。 +我们默认做了一套 sqlserver 的语法和映射适配,代码在 [Default/OdbcAdapter.cs](https://github.com/2881099/FreeSql/blob/master/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs),请查看代码了解。 ```csharp class Mssql2000Adapter : FreeSql.Odbc.Default.OdbcAdapter From 7c281ce004a363eb8133f1604782d9ba520e6117 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Sep 2019 23:19:37 +0800 Subject: [PATCH 0160/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=20List\=20=E4=BD=9C=E4=B8=BA=20Curd=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=93=8D=E4=BD=9C=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 9aa4e531..d7ad7405 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -406,6 +406,7 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var gkjdjd = g.sqlite.Select().Where(a => a.Post.Count > 0).ToSql(); var testrunsql1 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); var testrunsql2 = g.pgsql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index d958744f..6c997710 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -38,7 +38,7 @@ namespace FreeSql.Internal var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary()); //区分数据库类型缓存 if (tbc.TryGetValue(entity, out var trytb)) return trytb; if (common.CodeFirst.GetDbInfo(entity) != null) return null; - if (typeof(IEnumerable).IsAssignableFrom(entity) && entity.IsGenericParameter == true) return null; + if (typeof(IEnumerable).IsAssignableFrom(entity) && entity.IsGenericType == true) return null; if (entity.IsArray) return null; object entityDefault = null; From 17913a584d6ca04ddc54846424eb8a8516eab672 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Sep 2019 23:32:23 +0800 Subject: [PATCH 0161/1029] update tests --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index d7ad7405..d13a42d1 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -406,7 +406,7 @@ namespace FreeSql.Tests [Fact] public void Test1() { - var gkjdjd = g.sqlite.Select().Where(a => a.Post.Count > 0).ToSql(); + var gkjdjd = g.sqlite.Select().Where(a => a.Post.AsSelect().Count() > 0).ToList(); var testrunsql1 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); var testrunsql2 = g.pgsql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); From 5acf0b9eb4bfbc4305e8494be44fc3d311d2bc5d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 23 Sep 2019 21:58:30 +0800 Subject: [PATCH 0162/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IUpdate.Igno?= =?UTF-8?q?reColumns/UpdateColumns=20=E5=8F=AF=E5=AF=B9=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=90=8D=EF=BC=8C=E6=88=96=E5=AD=97=E6=AE=B5=E5=90=8D=E5=81=9A?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=EF=BC=9B#95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 4 +-- FreeSql/Interface/Curd/IUpdate.cs | 4 +-- .../Internal/CommonProvider/UpdateProvider.cs | 25 ++++++------------- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index f52a399d..6ba2f4df 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1616,7 +1616,7 @@ 忽略的列 - + 属性名,或者字段名 @@ -1630,7 +1630,7 @@ 指定的列 - + 属性名,或者字段名 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 26f11dd8..857b6169 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -49,7 +49,7 @@ namespace FreeSql /// /// 忽略的列 /// - /// + /// 属性名,或者字段名 /// IUpdate IgnoreColumns(string[] columns); @@ -62,7 +62,7 @@ namespace FreeSql /// /// 指定的列 /// - /// + /// 属性名,或者字段名 /// IUpdate UpdateColumns(string[] columns); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index a4866392..e29c443a 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -368,27 +368,16 @@ namespace FreeSql.Internal.CommonProvider public abstract List ExecuteUpdated(); public abstract Task> ExecuteUpdatedAsync(); - public IUpdate IgnoreColumns(Expression> columns) - { - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).Distinct(); - _ignore.Clear(); - foreach (var col in cols) _ignore.Add(col, true); - return this; - } - public IUpdate UpdateColumns(Expression> columns) - { - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); - _ignore.Clear(); - foreach (var col in _table.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name) == false) - _ignore.Add(col.Attribute.Name, true); - return this; - } + public IUpdate IgnoreColumns(Expression> columns) => IgnoreColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null)); + public IUpdate UpdateColumns(Expression> columns) => UpdateColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null)); public IUpdate IgnoreColumns(string[] columns) { + var cols = columns.ToDictionary(a => a); _ignore.Clear(); - foreach (var col in columns) _ignore.Add(col, true); + foreach (var col in _table.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name) == true || cols.ContainsKey(col.CsName) == true) + _ignore.Add(col.Attribute.Name, true); return this; } public IUpdate UpdateColumns(string[] columns) @@ -396,7 +385,7 @@ namespace FreeSql.Internal.CommonProvider var cols = columns.ToDictionary(a => a); _ignore.Clear(); foreach (var col in _table.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name) == false) + if (cols.ContainsKey(col.Attribute.Name) == false && cols.ContainsKey(col.CsName) == false) _ignore.Add(col.Attribute.Name, true); return this; } From bd83f67b7b54a627802c2416d1e8667c49d8fb9a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 23 Sep 2019 22:03:12 +0800 Subject: [PATCH 0163/1029] v0.10.1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index aefa1a32..2ee3aa81 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.9.18 + 0.10.1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a3ab5cfa..7cb06326 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index fab0214c..5a7f09ea 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 0d010977..02057295 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 74bb9355..03eecbc2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f7b69b75..fa99d03a 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0d3d8c05..c5ad93ca 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 615e6bd0..f41bc199 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d50c5a49..4215ed9c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index eec4affd..c6ee65c6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a4dc53bd..946c412c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4f14f344..f69004bb 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4204ab2b..603470ea 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.9.18 + 0.10.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 0a3e173662832639a0c7cc02ef3895941b97672f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 24 Sep 2019 21:54:43 +0800 Subject: [PATCH 0164/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Pgsql=20stri?= =?UTF-8?q?ng[]=20=E5=B1=9E=E6=80=A7=E8=A1=A8=E8=BE=BE=E5=BC=8F=20Contains?= =?UTF-8?q?=20=E7=BC=BA=E5=B0=91=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E7=9A=84=20SQL=20=E8=AF=AD=E6=B3=95=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQL/PostgreSQLExpression/OtherTest.cs | 1 + .../PostgreSQL/OdbcPostgreSQLExpression.cs | 8 +++++++- .../FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs | 8 +++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index d1bbdd0d..f29fa7d3 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -67,6 +67,7 @@ namespace FreeSql.Tests.PostgreSQLExpression var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList(); var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList(); + var sql121 = select.Where(a => a.testFieldStringArray.Contains("aaa") == false).ToList(); //in not in var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 5eca4047..d610ba85 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -135,7 +135,13 @@ namespace FreeSql.Odbc.PostgreSQL if (left.StartsWith("(") || left.EndsWith(")")) return $"{right1} in {left}"; if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; - return $"({left} @> array[{right1}])"; + right1 = $"array[{right1}]"; + if (objExp != null) + { + var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); + if (dbinfo.HasValue) right1 = $"{right1}::{dbinfo.Value.dbtype}"; + } + return $"({left} @> {right1})"; case "Concat": if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; var right2 = getExp(callExp.Arguments[argIndex]); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 788f3ae2..6c203306 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -164,7 +164,13 @@ namespace FreeSql.PostgreSQL if (left.StartsWith("(") || left.EndsWith(")")) return $"{right1} in {left}"; if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; - return $"({left} @> array[{right1}])"; + right1 = $"array[{right1}]"; + if (objExp != null) + { + var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); + if (dbinfo.HasValue) right1 = $"{right1}::{dbinfo.Value.dbtype}"; + } + return $"({left} @> {right1})"; case "Concat": if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; var right2 = getExp(callExp.Arguments[argIndex]); From 574b3242c17c3662978beb15f09039f14ecd32fe Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 24 Sep 2019 21:58:14 +0800 Subject: [PATCH 0165/1029] v0.10.2 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 4 ++-- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2ee3aa81..5afa8208 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.1 + 0.10.2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 7cb06326..37d84323 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5a7f09ea..d08e658e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 02057295..ce5df131 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 03eecbc2..aad19d39 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fa99d03a..23c3dbbd 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,10 +2,10 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin - FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. + FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c5ad93ca..e1110a25 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f41bc199..402e5d92 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 4215ed9c..2b238345 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index c6ee65c6..7fd6c0e0 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 946c412c..d323db31 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index f69004bb..b3aa294d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 603470ea..7aad458e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.1 + 0.10.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 31a42e750e303268fd764323802f1a82b29f570d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Sep 2019 08:03:07 +0800 Subject: [PATCH 0166/1029] update nuget packages version --- Examples/dbcontext_01/dbcontext_01.csproj | 4 ++-- Examples/repository_01/repository_01.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 4 ++-- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj index 7d31fc7b..c343f9ed 100644 --- a/Examples/dbcontext_01/dbcontext_01.csproj +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/Examples/repository_01/repository_01.csproj b/Examples/repository_01/repository_01.csproj index 14435386..4c63f521 100644 --- a/Examples/repository_01/repository_01.csproj +++ b/Examples/repository_01/repository_01.csproj @@ -6,7 +6,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e1110a25..06a562dd 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 402e5d92..d8371404 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 2b238345..3d93afa4 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7fd6c0e0..e5524557 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -19,11 +19,11 @@ - + - + diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d323db31..a8218328 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -20,7 +20,7 @@ - + diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b3aa294d..1c70b120 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7aad458e..7ae15156 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -19,7 +19,7 @@ - + From c747d39db82401c64a21786586aad46e3ea08ce4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Sep 2019 11:51:50 +0800 Subject: [PATCH 0167/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20NavigateAttr?= =?UTF-8?q?ibute=20=E7=89=B9=E6=80=A7=E5=AF=B9=E5=BA=94=E7=9A=84=20Fluent?= =?UTF-8?q?=20=E5=8A=9F=E8=83=BD=EF=BC=9B#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/DataAnnotations/TableAttribute.cs | 1 + FreeSql/DataAnnotations/TableFluent.cs | 17 +++++++++++++++++ FreeSql/FreeSql.xml | 10 ++++++++++ FreeSql/Internal/CommonUtils.cs | 21 +++++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 4 ++-- 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index b70858b4..ef5a4dda 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -26,5 +26,6 @@ namespace FreeSql.DataAnnotations public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; } internal ConcurrentDictionary _columns { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + internal ConcurrentDictionary _navigates { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); } } diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 0e6d1155..9027d529 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -111,5 +111,22 @@ namespace FreeSql.DataAnnotations var col = _table._columns.GetOrAdd(proto.Name, name => new ColumnAttribute { Name = proto.Name }); return new ColumnFluent(col); } + + /// + /// 导航关系Fluent,与 NavigateAttribute 对应 + /// + /// + /// + /// + /// 多对多关系的中间实体类型 + /// + public TableFluent Navigate(Expression> proto, string bind, Type manyToMany = null) + { + var member = (proto.Body as MemberExpression)?.Member; + if (member == null) throw new FormatException($"错误的表达式格式 {proto}"); + var nav = new NavigateAttribute { Bind = bind, ManyToMany = manyToMany }; + _table._navigates.AddOrUpdate(member.Name, nav, (name, old) => nav); + return this; + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6ba2f4df..1bab4823 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -215,6 +215,16 @@ 禁用 CodeFirst 同步结构迁移 + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + + 多对多关系的中间实体类型 + + 所属表 diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index a1bce7e8..6f065895 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -164,6 +164,27 @@ namespace FreeSql.Internal if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; } + public NavigateAttribute GetEntityNavigateAttribute(Type type, PropertyInfo proto) + { + var attr = new NavigateAttribute(); + if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._navigates.TryGetValue(proto.Name, out var trynav)) + { + if (!string.IsNullOrEmpty(trynav.Bind)) attr.Bind = trynav.Bind; + if (trynav.ManyToMany != null) attr.ManyToMany = trynav.ManyToMany; + } + var attrs = proto.GetCustomAttributes(typeof(NavigateAttribute), false); + foreach (var tryattrobj in attrs) + { + trynav = tryattrobj as NavigateAttribute; + if (trynav == null) continue; + if (!string.IsNullOrEmpty(trynav.Bind)) attr.Bind = trynav.Bind; + if (trynav.ManyToMany != null) attr.ManyToMany = trynav.ManyToMany; + } + NavigateAttribute ret = null; + if (!string.IsNullOrEmpty(attr.Bind)) ret = attr; + if (attr.ManyToMany != null) ret = attr; + return ret; + } public string WhereObject(TableInfo table, string aliasAndDot, object dywhere) { diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6c997710..09a3fac4 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -311,7 +311,7 @@ namespace FreeSql.Internal $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" : (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name}"); - var pnvAttr = pnv.GetCustomAttribute(); + var pnvAttr = common.GetEntityNavigateAttribute(trytb.Type, pnv); var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); var nvref = new TableRef(); nvref.Property = pnv; @@ -351,7 +351,7 @@ namespace FreeSql.Internal { isManyToMany = propElementType != trytb.Type && tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && - z.Value.GetCustomAttribute()?.ManyToMany == pnvAttr.ManyToMany && + common.GetEntityNavigateAttribute(tbref.Type, z.Value)?.ManyToMany == pnvAttr.ManyToMany && typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); if (isManyToMany == false) From d4c766e0b666cea024a3640ca21be348f4d98924 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Sep 2019 12:34:08 +0800 Subject: [PATCH 0168/1029] v0.10.3 #96 --- Examples/base_entity/base_entity.csproj | 3 +- .../FreeSql.Extensions.BaseEntity.csproj | 51 ++++++++------- .../FreeSql.Extensions.JsonMap.csproj | 55 +++++++++------- .../FreeSql.Extensions.JsonMap.xml | 19 ++++++ .../FreeSql.Extensions.LazyLoading.csproj | 58 +++++++++-------- FreeSql.DbContext/FreeSql.DbContext.csproj | 62 ++++++++++--------- FreeSql.Repository/FreeSql.Repository.csproj | 42 +++++++------ .../FreeSql.Tests/FreeSql.Tests.csproj | 1 + FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 1 - FreeSql/FreeSql.csproj | 8 ++- .../FreeSql.Provider.MySql.csproj | 8 ++- .../FreeSql.Provider.MySqlConnector.csproj | 8 ++- .../FreeSql.Provider.Odbc.csproj | 8 ++- .../FreeSql.Provider.Oracle.csproj | 8 ++- .../FreeSql.Provider.PostgreSQL.csproj | 8 ++- .../FreeSql.Provider.SqlServer.csproj | 9 ++- .../FreeSql.Provider.Sqlite.csproj | 8 ++- 17 files changed, 217 insertions(+), 140 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index be75e076..2df960d9 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -6,7 +6,8 @@ - C:\Users\28810\Desktop\github\FreeSql\Examples\base_entity\base_entity.xml + base_entity.xml + 3 diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5afa8208..2207db49 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -1,29 +1,34 @@  - - netstandard2.0 - 0.10.2 - true - YeXiangQin - BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. - https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity - https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity - git - MIT - FreeSql;ORM;BaseEntity - $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true - $(AssemblyName) - true - true - + + netstandard2.0 + 0.10.3 + true + YeXiangQin + BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. + https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity + https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity + git + MIT + FreeSql;ORM;BaseEntity + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + - - FreeSql.Extensions.BaseEntity.xml - + + + + + + FreeSql.Extensions.BaseEntity.xml + 3 + - - - + + + diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 37d84323..ab2405bd 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -1,29 +1,38 @@  - - netstandard2.0;net45 - 0.10.2 - true - YeXiangQin - FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. - https://github.com/2881099/FreeSql - https://github.com/2881099/FreeSql - git - MIT - FreeSql;ORM - $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true - $(AssemblyName) - true - true - + + netstandard2.0;net45 + 0.10.3 + true + YeXiangQin + FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + - - - + + + + + + FreeSql.Extensions.JsonMap.xml + 3 + - - - + + + + + + + diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml new file mode 100644 index 00000000..6c47f3b3 --- /dev/null +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml @@ -0,0 +1,19 @@ + + + + FreeSql.Extensions.JsonMap + + + + + 当实体类属性为【对象】时,以JSON形式映射存储 + + + + + 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 + + + + + diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index d08e658e..4dffe65c 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -1,33 +1,37 @@  - - netstandard2.0;net45 - 0.10.2 - true - YeXiangQin - FreeSql 扩展包,可实现【延时加载】属性. - https://github.com/2881099/FreeSql - https://github.com/2881099/FreeSql - git - MIT - FreeSql;ORM - $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true - $(AssemblyName) - true - true - + + netstandard2.0;net45 + 0.10.3 + true + YeXiangQin + FreeSql 扩展包,可实现【延时加载】属性. + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + - - - + + + + + + + - - ns20;netstandard20 - - - - - + + ns20;netstandard20 + + + + + diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ce5df131..4fa928ad 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -1,37 +1,41 @@  - - netstandard2.0;net45 - 0.10.2 - true - YeXiangQin - FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. - https://github.com/2881099/FreeSql.DbContext - FreeSql ORM DbContext - git - MIT - $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true - $(AssemblyName) - true - true - + + netstandard2.0;net45 + 0.10.3 + true + YeXiangQin + FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. + https://github.com/2881099/FreeSql.DbContext + FreeSql ORM DbContext + git + MIT + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + - - FreeSql.DbContext.xml - 3 - + + + + + + FreeSql.DbContext.xml + 3 + - - ns20;netstandard20 - + + ns20;netstandard20 + - - - + + + - - - + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index aad19d39..f0d1a112 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -1,24 +1,28 @@  - - netstandard2.0;net45 - 0.10.2 - YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. - https://github.com/2881099/FreeSql/wiki/Repository - FreeSql ORM Repository - true - git - MIT - $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true - $(AssemblyName) - true - true - + + netstandard2.0;net45 + 0.10.3 + YeXiangQin + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. + https://github.com/2881099/FreeSql/wiki/Repository + FreeSql ORM Repository + true + git + MIT + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + - - - + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index cee654fa..364e968d 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -8,6 +8,7 @@ FreeSql.Tests.xml + 3 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index d13a42d1..8ea6aa71 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -414,7 +414,6 @@ namespace FreeSql.Tests var testrunsql4 = g.oracle.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); var testrunsql5 = g.sqlite.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); - var testssargs1 = "10100"; var testformatsql1 = g.mysql.Select().Where(a => a.NamespaceName == $"1_{10100}").ToSql(); var testorderbysql = g.mysql.Select().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql(); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 23c3dbbd..c749d7f8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.2 + 0.10.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. @@ -12,12 +12,16 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + logo.png $(AssemblyName) true true + + + + FreeSql.xml 3 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 06a562dd..0fc2a293 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.2 + 0.10.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 @@ -12,12 +12,16 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + logo.png $(AssemblyName) true true + + + + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d8371404..e845faed 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.2 + 0.10.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 @@ -12,12 +12,16 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + logo.png $(AssemblyName) true true + + + + diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3d93afa4..114a3e50 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.2 + 0.10.3 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 @@ -12,12 +12,16 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + logo.png $(AssemblyName) true true + + + + diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index e5524557..95cba443 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.2 + 0.10.3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 @@ -12,12 +12,16 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + logo.png $(AssemblyName) true true + + + + diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a8218328..a661cfd0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.2 + 0.10.3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 @@ -12,12 +12,16 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + logo.png $(AssemblyName) true true + + + + diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 1c70b120..34830f99 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.2 + 0.10.3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -12,16 +12,19 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + logo.png $(AssemblyName) true true + + + + - diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7ae15156..e211ad0e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.2 + 0.10.3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 @@ -12,12 +12,16 @@ MIT FreeSql;ORM $(AssemblyName) - https://github.com/2881099/FreeSql/blob/master/logo.png?raw=true + logo.png $(AssemblyName) true true + + + + From 6ca226a8e40193df016a8a98643fed83f313fae6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Sep 2019 15:45:40 +0800 Subject: [PATCH 0169/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ColumnAttrib?= =?UTF-8?q?ute=20=E5=8F=AF=E6=8F=92=E5=85=A5(CanInsert)=E3=80=81=E5=8F=AF?= =?UTF-8?q?=E6=9B=B4=E6=96=B0(CanUpdate)=EF=BC=9B#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataAnnotations/MySqlFluentTest.cs | 41 ++++++++++++++++++- FreeSql/DataAnnotations/ColumnAttribute.cs | 10 +++++ FreeSql/DataAnnotations/ColumnFluent.cs | 21 ++++++++++ FreeSql/FreeSql.xml | 34 +++++++++++++++ .../Internal/CommonProvider/InsertProvider.cs | 13 ++++++ .../Internal/CommonProvider/UpdateProvider.cs | 13 ++++++ FreeSql/Internal/CommonUtils.cs | 6 +++ 7 files changed, 137 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index 2dac212c..5f736963 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -125,7 +125,6 @@ namespace FreeSql.Tests.DataAnnotations Assert.NotNull(find); Assert.Equal(item.id, find.id); } - class TestIsIgnore { public Guid id { get; set; } @@ -133,5 +132,45 @@ namespace FreeSql.Tests.DataAnnotations [Column(IsIgnore = true)] public bool isignore { get; set; } } + + [Fact] + public void CanInsert_CanUpdate() + { + var item = new TestCanInsert { title = "testtitle", testfield1 = 1000, testfield2 = 1000 }; + var sql = g.mysql.Insert(item).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestCanInsert`(`id`, `title`, `testfield2`) VALUES(?id_0, ?title_0, ?testfield2_0)", sql); + + Assert.Equal(1, g.mysql.Insert(item).ExecuteAffrows()); + var find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.title, find.title); + Assert.NotEqual(item.testfield1, find.testfield1); + Assert.Equal(0, find.testfield1); + Assert.Equal(item.testfield2, find.testfield2); + + item.title = "testtitle_update"; + item.testfield2 = 0; + sql = g.mysql.Update().SetSource(item).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestCanInsert` SET `id` = ?p_0, `title` = ?p_1, `testfield1` = ?p_2 WHERE (`id` = '{item.id}')", sql); + + Assert.Equal(1, g.mysql.Update().SetSource(item).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.title, find.title); + Assert.Equal(item.testfield1, find.testfield1); + Assert.NotEqual(item.testfield2, find.testfield2); + Assert.Equal(1000, find.testfield1); + } + class TestCanInsert + { + public Guid id { get; set; } + public string title { get; set; } + [Column(CanInsert = false)] + public long testfield1 { get; set; } + [Column(CanUpdate = false)] + public long testfield2 { get; set; } + } } } diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 9040fe96..96955872 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -94,5 +94,15 @@ namespace FreeSql.DataAnnotations /// <0时排后面,...-3,-2,-1 /// public short Position { get => _Position ?? 0; set => _Position = value; } + + internal bool? _CanInsert, _CanUpdate; + /// + /// 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + /// + public bool CanInsert { get => _CanInsert ?? true; set => _CanInsert = value; } + /// + /// 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + /// + public bool CanUpdate { get => _CanUpdate ?? true; set => _CanUpdate = value; } } } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index bd731374..0f80bb02 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -113,5 +113,26 @@ namespace FreeSql.DataAnnotations _column.Position = value; return this; } + + /// + /// 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + /// + /// + /// + public ColumnFluent CanInsert(bool value) + { + _column.CanInsert = value; + return this; + } + /// + /// 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + /// + /// + /// + public ColumnFluent CanUpdate(bool value) + { + _column.CanUpdate = value; + return this; + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1bab4823..3d2a21c9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -73,6 +73,16 @@ <0时排后面,...-3,-2,-1 + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + 数据库列名 @@ -140,6 +150,20 @@ + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + 手工绑定 OneToMany、ManyToOne 导航关系 @@ -2418,6 +2442,16 @@ + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + 通过属性的注释文本,通过 xml 读取 diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 8247d3a5..c425d379 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -34,14 +34,26 @@ namespace FreeSql.Internal.CommonProvider _table = _commonUtils.GetTableByEntity(typeof(T1)); _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + IgnoreCanInsert(); } + /// + /// AsType, Ctor, ClearData 三处地方需要重新加载 + /// + protected void IgnoreCanInsert() + { + if (_table == null || _table.Type == typeof(object)) return; + foreach (var col in _table.Columns.Values) + if (col.Attribute.CanInsert == false) + _ignore.Add(col.Attribute.Name, true); + } protected void ClearData() { _insertIdentity = false; _source.Clear(); _ignore.Clear(); _params = null; + IgnoreCanInsert(); } public IInsert WithTransaction(DbTransaction transaction) @@ -569,6 +581,7 @@ namespace FreeSql.Internal.CommonProvider var newtb = _commonUtils.GetTableByEntity(entityType); _table = newtb ?? throw new Exception("IInsert.AsType 参数错误,请传入正确的实体类型"); if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); + IgnoreCanInsert(); return this; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index e29c443a..b021f6b1 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -40,8 +40,19 @@ namespace FreeSql.Internal.CommonProvider _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; this.Where(_commonUtils.WhereObject(_table, "", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + IgnoreCanUpdate(); } + /// + /// AsType, Ctor, ClearData 三处地方需要重新加载 + /// + protected void IgnoreCanUpdate() + { + if (_table == null || _table.Type == typeof(object)) return; + foreach (var col in _table.Columns.Values) + if (col.Attribute.CanUpdate == false) + _ignore.Add(col.Attribute.Name, true); + } protected void ClearData() { _source.Clear(); @@ -51,6 +62,7 @@ namespace FreeSql.Internal.CommonProvider _setIncr.Clear(); _params.Clear(); _paramsSource.Clear(); + IgnoreCanUpdate(); } public IUpdate WithTransaction(DbTransaction transaction) @@ -610,6 +622,7 @@ namespace FreeSql.Internal.CommonProvider var newtb = _commonUtils.GetTableByEntity(entityType); _table = newtb ?? throw new Exception("IUpdate.AsType 参数错误,请传入正确的实体类型"); if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); + IgnoreCanUpdate(); return this; } diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 6f065895..e976465d 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -128,6 +128,8 @@ namespace FreeSql.Internal if (trycol._Uniques != null) attr._Uniques = trycol._Uniques; if (trycol.MapType != null) attr.MapType = trycol.MapType; if (trycol._Position != null) attr._Position = trycol.Position; + if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert; + if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate; if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue; } var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); @@ -146,6 +148,8 @@ namespace FreeSql.Internal if (tryattr._Uniques != null) attr._Uniques = tryattr._Uniques; if (tryattr.MapType != null) attr.MapType = tryattr.MapType; if (tryattr._Position != null) attr._Position = tryattr.Position; + if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert; + if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate; if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue; } ColumnAttribute ret = null; @@ -160,6 +164,8 @@ namespace FreeSql.Internal if (attr._Uniques != null) ret = attr; if (attr.MapType != null) ret = attr; if (attr._Position != null) ret = attr; + if (attr._CanInsert != null) ret = attr; + if (attr._CanUpdate != null) ret = attr; if (attr.DbDefautValue != null) ret = attr; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; From e46ec8742e67525ec01db65d203425810a3c15f2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Sep 2019 15:47:42 +0800 Subject: [PATCH 0170/1029] v0.10.4 #99 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 4 ++-- FreeSql.Repository/FreeSql.Repository.csproj | 4 ++-- FreeSql/FreeSql.csproj | 4 ++-- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 4 ++-- .../FreeSql.Provider.SqlServer.csproj | 4 ++-- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 4 ++-- 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2207db49..e885c372 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.3 + 0.10.4 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ab2405bd..94031d1d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 4dffe65c..8a4a2161 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4fa928ad..b86d5199 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. @@ -18,7 +18,7 @@ - + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index f0d1a112..8a6e4551 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository @@ -18,7 +18,7 @@ - + diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c749d7f8..a790f3f5 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0fc2a293..5eb3b0f5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index e845faed..094d443b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 114a3e50..bac6db3e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 95cba443..228a8aa3 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a661cfd0..9e4ffebd 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 34830f99..5ea29ab6 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e211ad0e..8400ed9b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.3 + 0.10.4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 @@ -19,7 +19,7 @@ - + From 7514000490c97e704e0e06523e306d0e5fdbb55c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Sep 2019 12:43:43 +0800 Subject: [PATCH 0171/1029] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E5=91=BD=E5=90=8D=20#103?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 2 +- .../{Extenssions => Extensions}/DependencyInjection.cs | 0 .../FreeSqlDbContextExtensions.cs} | 2 +- readme.md | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename FreeSql.DbContext/{Extenssions => Extensions}/DependencyInjection.cs (100%) rename FreeSql.DbContext/{Extenssions/FreeSqlDbContextExtenssions.cs => Extensions/FreeSqlDbContextExtensions.cs} (96%) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 0d0fcc75..b5ab0cee 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -35,7 +35,7 @@ namespace FreeSql get { if (_optionsPriv != null) return _optionsPriv; - if (FreeSqlDbContextExtenssions._dicSetDbContextOptions.TryGetValue(Orm, out _optionsPriv)) return _optionsPriv; + if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(Orm, out _optionsPriv)) return _optionsPriv; _optionsPriv = new DbContextOptions(); return _optionsPriv; } diff --git a/FreeSql.DbContext/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Extensions/DependencyInjection.cs similarity index 100% rename from FreeSql.DbContext/Extenssions/DependencyInjection.cs rename to FreeSql.DbContext/Extensions/DependencyInjection.cs diff --git a/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs similarity index 96% rename from FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs rename to FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs index af755db5..e1b95f38 100644 --- a/FreeSql.DbContext/Extenssions/FreeSqlDbContextExtenssions.cs +++ b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Concurrent; -public static class FreeSqlDbContextExtenssions +public static class FreeSqlDbContextExtensions { /// diff --git a/readme.md b/readme.md index 0983dc63..a4a49e3b 100644 --- a/readme.md +++ b/readme.md @@ -20,7 +20,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | | | | - | - | -| | [《新手上路》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | | | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | | | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | | | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | From 33cb3e2dae5174c6834a387f4c514e59c29b07d5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Sep 2019 15:02:08 +0800 Subject: [PATCH 0172/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20DbContext/Re?= =?UTF-8?q?pository=20ManyToMany=E8=81=94=E7=BA=A7=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=88=E4=B9=8B=E5=89=8D=E5=B7=B2=E6=94=AF?= =?UTF-8?q?=E6=8C=81OneToMany=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 5 +- FreeSql.DbContext/DbContext/DbContextAsync.cs | 5 +- .../DbContext/DbContextOptions.cs | 11 +- FreeSql.DbContext/DbContext/DbContextSync.cs | 5 +- FreeSql.DbContext/DbSet/DbSet.cs | 7 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 140 +++++++++++--- FreeSql.DbContext/DbSet/DbSetSync.cs | 116 ++++++++++-- FreeSql.DbContext/FreeSql.DbContext.xml | 22 ++- .../Repository/Repository/BaseRepository.cs | 1 + .../Repository/Repository/IBaseRepository.cs | 5 + .../RepositoryTests.cs | 176 ++++++++++++++++++ 11 files changed, 435 insertions(+), 58 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index b5ab0cee..bce37fb8 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -148,14 +148,15 @@ namespace FreeSql public ExecCommandInfoType actionType { get; set; } public IDbSet dbSet { get; set; } public Type stateType { get; set; } + public Type entityType { get; set; } public object state { get; set; } } internal enum ExecCommandInfoType { Insert, Update, Delete } Queue _actions = new Queue(); internal int _affrows = 0; - internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, object state) => - _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); + internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, Type entityType, object state) => + _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state }); #endregion ~DbContext() => this.Dispose(); diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 698a1200..cf4bf849 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -97,10 +97,11 @@ namespace FreeSql if (_actions.Any() == false && states.Any() || info != null && oldinfo.actionType != info.actionType || - info != null && oldinfo.stateType != info.stateType) + info != null && oldinfo.stateType != info.stateType || + info != null && oldinfo.entityType != info.entityType) { - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) + if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType) { //最后一个,合起来发送 states.Add(info.state); diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index 9ff21d0c..4841ded3 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -5,7 +5,16 @@ namespace FreeSql { /// - /// 是否开启一对多,联级保存功能 + /// 是否开启一对多,多对多联级保存功能 + /// + /// 【一对多】模型下, 保存时可联级保存实体的属性集合。出于使用安全考虑我们没做完整对比,只实现实体属性集合的添加或更新操作,所以不会删除实体属性集合的数据。 + /// 完整对比的功能使用起来太危险,试想下面的场景: + /// - 保存的时候,实体的属性集合是空的,如何操作?记录全部删除? + /// - 保存的时候,由于数据库中记录非常之多,那么只想保存子表的部分数据,或者只需要添加,如何操作? + /// + /// 【多对多】模型下,我们对中间表的保存是完整对比操作,对外部实体的操作只作新增(注意不会更新) + /// - 属性集合为空时,删除他们的所有关联数据(中间表) + /// - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录 /// public bool EnableAddOrUpdateNavigateList { get; set; } = true; } diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs index 4c8f2c3b..3de59884 100644 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -97,10 +97,11 @@ namespace FreeSql if (_actions.Any() == false && states.Any() || info != null && oldinfo.actionType != info.actionType || - info != null && oldinfo.stateType != info.stateType) + info != null && oldinfo.stateType != info.stateType || + info != null && oldinfo.entityType != info.entityType) { - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) + if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType) { //最后一个,合起来发送 states.Add(info.state); diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index fa02eeb2..fbbbaa7c 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -60,7 +60,7 @@ namespace FreeSql protected virtual IDelete OrmDelete(object dywhere) => _db.Orm.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) => - _db.EnqueueAction(actionType, this, typeof(EntityState), state); + _db.EnqueueAction(actionType, this, typeof(EntityState), _entityType, state); internal void IncrAffrows(int affrows) => _db._affrows += affrows; @@ -117,14 +117,15 @@ namespace FreeSql /// /// /// - public void AsType(Type entityType) + public DbSet AsType(Type entityType) { if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); - if (entityType == _entityType) return; + if (entityType == _entityType) return this; var newtb = _db.Orm.CodeFirst.GetTableByEntity(entityType); _entityType = entityType; _tablePriv = newtb ?? throw new Exception("DbSet.AsType 参数错误,请传入正确的实体类型"); _tableIdentitysPriv = null; + return this; } public class EntityState diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 0ae3f8d3..dd385d01 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -4,6 +4,8 @@ using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; +using System.Reflection; using System.Threading.Tasks; namespace FreeSql @@ -131,46 +133,132 @@ namespace FreeSql { if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; + var tref = _table.GetTableRef(prop.Key, true); if (tref == null) continue; - switch (tref.RefType) { case Internal.Model.TableRefType.OneToOne: case Internal.Model.TableRefType.ManyToOne: - case Internal.Model.TableRefType.ManyToMany: continue; - case Internal.Model.TableRefType.OneToMany: - if (itemType == null) itemType = item.GetType(); - if (_table.TypeLazy != null && itemType == _table.TypeLazy) - { - var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => - _table.TypeLazy.GetField($"__lazy__{propName}", System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)); - if (lazyField != null) - { - var lazyFieldValue = (bool)lazyField.GetValue(item); - if (lazyFieldValue == false) continue; - } - } - var propVal = prop.Value.GetValue(item); - var propValEach = propVal as IEnumerable; - if (propValEach == null) continue; - object dbset = null; - System.Reflection.MethodInfo dbsetAddOrUpdate = null; + } + + object propVal = null; + if (itemType == null) itemType = item.GetType(); + if (_table.TypeLazy != null && itemType == _table.TypeLazy) + { + var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => + _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); + if (lazyField != null) + { + var lazyFieldValue = (bool)lazyField.GetValue(item); + if (lazyFieldValue == false) continue; + } + propVal = prop.Value.GetValue(item); + } + else + { + propVal = prop.Value.GetValue(item); + if (propVal == null) continue; + } + + var propValEach = propVal as IEnumerable; + if (propValEach == null) continue; + DbSet refSet = _db.Set().AsType(tref.RefEntityType); + switch (tref.RefType) + { + case Internal.Model.TableRefType.ManyToMany: + var curList = new List(); foreach (var propValItem in propValEach) { - if (dbset == null) + curList.Add(propValItem); + var flagExists = refSet.ExistsInStates(propValItem); + if (flagExists == false) + flagExists = await refSet.Select.WhereDynamic(propValItem).AnyAsync(); + if (refSet.CanAdd(propValItem, false) && flagExists != true) + await refSet.AddAsync(propValItem); + } + var midSelectParam = Expression.Parameter(typeof(object), "a"); + var midWheres = new List>>(); + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) + midWheres.Add(Expression.Lambda>(Expression.Equal( + Expression.MakeMemberAccess(Expression.Convert(midSelectParam, tref.RefMiddleEntityType), tref.MiddleColumns[colidx].Table.Properties[tref.MiddleColumns[colidx].CsName]), + Expression.Constant( + FreeSql.Internal.Utils.GetDataReaderValue( + tref.MiddleColumns[colidx].CsType, + _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.MiddleColumns[colidx].CsType) + ), midSelectParam)); + + if (curList.Any() == false) //全部删除 + { + var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType); + foreach (var midWhere in midWheres) delall.Where(midWhere); + await delall.ExecuteAffrowsAsync(); + } + else //保存 + { + var midSet = _db.Set().AsType(tref.RefMiddleEntityType); + var midSelect = midSet.Select; + foreach (var midWhere in midWheres) midSelect.Where(midWhere); + var midList = await midSelect.ToListAsync(); + var midListDel = new List(); + var midListAdd = new List(); + + foreach (var midItem in midList) { - dbset = _db.Set(tref.RefEntityType); - dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdateAsync", new Type[] { tref.RefEntityType }); + var curContains = new List(); + for (var curIdx = 0; curIdx < curList.Count; curIdx++) + { + var isEquals = true; + for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) + { + var refcol = tref.Columns[midcolidx - tref.Columns.Count]; + var midval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefMiddleEntityType, midItem, tref.MiddleColumns[midcolidx].CsName)); + var refval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curList[curIdx], tref.Columns[midcolidx - tref.Columns.Count].CsName)); + if (object.Equals(midval, refval) == false) + { + isEquals = false; + break; + } + } + if (isEquals) + curContains.Add(curIdx); + } + if (curContains.Any()) + foreach (var curIdx in curContains) + curList.RemoveAt(curIdx); + else + midListDel.Add(midItem); } + midSet.RemoveRange(midListDel); //删除未保存的项 + foreach (var curItem in curList) + { + var newItem = Activator.CreateInstance(tref.RefMiddleEntityType); + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) + { + var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[colidx].CsType, _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); + _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[colidx].CsName, val); + } + for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) + { + var refcol = tref.Columns[midcolidx - tref.Columns.Count]; + var refval = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[midcolidx].CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curItem, refcol.CsName)); + _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[midcolidx].CsName, refval); + } + midListAdd.Add(newItem); + } + await midSet.AddRangeAsync(midListAdd); + } + break; + case Internal.Model.TableRefType.OneToMany: + foreach (var propValItem in propValEach) + { for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { - tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName] - .SetValue(propValItem, tref.Columns[colidx].Table.Properties[tref.Columns[colidx].CsName].GetValue(item)); + var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); + _db.Orm.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val); } - Task task = dbsetAddOrUpdate.Invoke(dbset, new object[] { propValItem }) as Task; - await task; + await refSet.AddOrUpdateAsync(propValItem); } break; } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 7cb270b5..8e0a7729 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Collections.Concurrent; using System.Linq; using System.Reflection; +using System.Text; +using System.Linq.Expressions; namespace FreeSql { @@ -137,8 +139,16 @@ namespace FreeSql if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; - object propVal = null; + var tref = _table.GetTableRef(prop.Key, true); + if (tref == null) continue; + switch (tref.RefType) + { + case Internal.Model.TableRefType.OneToOne: + case Internal.Model.TableRefType.ManyToOne: + continue; + } + object propVal = null; if (itemType == null) itemType = item.GetType(); if (_table.TypeLazy != null && itemType == _table.TypeLazy) { @@ -157,33 +167,103 @@ namespace FreeSql if (propVal == null) continue; } - var tref = _table.GetTableRef(prop.Key, true); - if (tref == null) continue; - + var propValEach = propVal as IEnumerable; + if (propValEach == null) continue; + DbSet refSet = _db.Set().AsType(tref.RefEntityType); switch (tref.RefType) { - case Internal.Model.TableRefType.OneToOne: - case Internal.Model.TableRefType.ManyToOne: case Internal.Model.TableRefType.ManyToMany: - continue; - case Internal.Model.TableRefType.OneToMany: - var propValEach = propVal as IEnumerable; - if (propValEach == null) continue; - object dbset = null; - MethodInfo dbsetAddOrUpdate = null; + var curList = new List(); foreach (var propValItem in propValEach) { - if (dbset == null) + curList.Add(propValItem); + var flagExists = refSet.ExistsInStates(propValItem); + if (flagExists == false) + flagExists = refSet.Select.WhereDynamic(propValItem).Any(); + if (refSet.CanAdd(propValItem, false) && flagExists != true) + refSet.Add(propValItem); + } + var midSelectParam = Expression.Parameter(typeof(object), "a"); + var midWheres = new List>>(); + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) + midWheres.Add(Expression.Lambda>(Expression.Equal( + Expression.MakeMemberAccess(Expression.Convert(midSelectParam, tref.RefMiddleEntityType), tref.MiddleColumns[colidx].Table.Properties[tref.MiddleColumns[colidx].CsName]), + Expression.Constant( + FreeSql.Internal.Utils.GetDataReaderValue( + tref.MiddleColumns[colidx].CsType, + _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.MiddleColumns[colidx].CsType) + ), midSelectParam)); + + if (curList.Any() == false) //全部删除 + { + var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType); + foreach (var midWhere in midWheres) delall.Where(midWhere); + delall.ExecuteAffrows(); + } + else //保存 + { + var midSet = _db.Set().AsType(tref.RefMiddleEntityType); + var midSelect = midSet.Select; + foreach (var midWhere in midWheres) midSelect.Where(midWhere); + var midList = midSelect.ToList(); + var midListDel = new List(); + var midListAdd = new List(); + + foreach (var midItem in midList) { - dbset = _db.Set(tref.RefEntityType); - dbsetAddOrUpdate = dbset.GetType().GetMethod("AddOrUpdate", new Type[] { tref.RefEntityType }); + var curContains = new List(); + for(var curIdx = 0; curIdx < curList.Count; curIdx ++) + { + var isEquals = true; + for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) + { + var refcol = tref.Columns[midcolidx - tref.Columns.Count]; + var midval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefMiddleEntityType, midItem, tref.MiddleColumns[midcolidx].CsName)); + var refval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curList[curIdx], tref.Columns[midcolidx - tref.Columns.Count].CsName)); + if (object.Equals(midval, refval) == false) + { + isEquals = false; + break; + } + } + if (isEquals) + curContains.Add(curIdx); + } + if (curContains.Any()) + foreach (var curIdx in curContains) + curList.RemoveAt(curIdx); + else + midListDel.Add(midItem); } + midSet.RemoveRange(midListDel); //删除未保存的项 + foreach (var curItem in curList) + { + var newItem = Activator.CreateInstance(tref.RefMiddleEntityType); + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) + { + var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[colidx].CsType, _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); + _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[colidx].CsName, val); + } + for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) + { + var refcol = tref.Columns[midcolidx - tref.Columns.Count]; + var refval = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[midcolidx].CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curItem, refcol.CsName)); + _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[midcolidx].CsName, refval); + } + midListAdd.Add(newItem); + } + midSet.AddRange(midListAdd); + } + break; + case Internal.Model.TableRefType.OneToMany: + foreach (var propValItem in propValEach) + { for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { - tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName] - .SetValue(propValItem, tref.Columns[colidx].Table.Properties[tref.Columns[colidx].CsName].GetValue(item)); + var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); + _db.Orm.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val); } - dbsetAddOrUpdate.Invoke(dbset, new object[] { propValItem }); + refSet.AddOrUpdate(propValItem); } break; } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 42dd9adc..755141c4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -48,7 +48,16 @@ - 是否开启一对多,联级保存功能 + 是否开启一对多,多对多联级保存功能 + + 【一对多】模型下, 保存时可联级保存实体的属性集合。出于使用安全考虑我们没做完整对比,只实现实体属性集合的添加或更新操作,所以不会删除实体属性集合的数据。 + 完整对比的功能使用起来太危险,试想下面的场景: + - 保存的时候,实体的属性集合是空的,如何操作?记录全部删除? + - 保存的时候,由于数据库中记录非常之多,那么只想保存子表的部分数据,或者只需要添加,如何操作? + + 【多对多】模型下,我们对中间表的保存是完整对比操作,对外部实体的操作只作新增(注意不会更新) + - 属性集合为空时,删除他们的所有关联数据(中间表) + - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录 @@ -158,6 +167,11 @@ + + + 设置 DbContext 选项 + + 清空状态数据 @@ -193,14 +207,14 @@ 开启工作单元 - + 创建普通数据上下文档对象 - + 不跟踪查询的实体数据(在不需要更新其数据时使用),可提长查询性能 @@ -208,7 +222,7 @@ - + 设置 DbContext 选项设置 diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 2fbcc0cc..f7775429 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -59,6 +59,7 @@ namespace FreeSql } public Type EntityType => _dbsetPriv?.EntityType ?? typeof(TEntity); public void AsType(Type entityType) => _dbset.AsType(entityType); + public DbContextOptions DbContextOptions { get => _db.Options; set => _db.Options = value; } public IFreeSql Orm { get; private set; } public IUnitOfWork UnitOfWork { get; set; } diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index 432697d8..effe252b 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -17,6 +17,11 @@ namespace FreeSql /// /// void AsType(Type entityType); + + /// + /// 设置 DbContext 选项 + /// + DbContextOptions DbContextOptions { get; set; } } public interface IBaseRepository : IReadOnlyRepository, IBasicRepository diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 95319a9c..c16fda68 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -1,4 +1,6 @@ +using FreeSql.DataAnnotations; using System; +using System.Collections.Generic; using Xunit; namespace FreeSql.Tests @@ -277,5 +279,179 @@ namespace FreeSql.Tests repos.DataFilter.Apply("xxx", a => (a as AddUpdateInfo).Clicks == 2); Assert.Null(repos.Find(item.Id)); } + + [Fact] + public void EnableAddOrUpdateNavigateList_OneToMany() + { + var repo = g.sqlite.GetRepository(); + var cts = new[] { + new Cagetory + { + Name = "1", + Goodss = new List(new[] + { + new Goods { Name = "Ʒ1" }, + new Goods { Name = "Ʒ2" }, + new Goods { Name = "Ʒ3" } + }) + }, + new Cagetory + { + Name = "2", + Goodss = new List(new[] + { + new Goods { Name = "Ʒ4" }, + new Goods { Name = "Ʒ5" } + }) + } + }; + repo.Insert(cts); + cts[0].Name = "11"; + cts[0].Goodss.Clear(); + cts[1].Name = "22"; + cts[1].Goodss.Clear(); + repo.Update(cts); + cts[0].Name = "111"; + cts[0].Goodss.Clear(); + cts[0].Goodss.Add(new Goods { Name = "Ʒ33" }); + cts[1].Name = "222"; + cts[1].Goodss.Clear(); + cts[1].Goodss.Add(new Goods { Name = "Ʒ55" }); + repo.Update(cts); + } + [Table(Name = "EAUNL_OTM_CT")] + class Cagetory + { + public Guid Id { get; set; } + public string Name { get; set; } + + [Navigate("CagetoryId")] + public List Goodss { get; set; } + } + [Table(Name = "EAUNL_OTM_GD")] + class Goods + { + public Guid Id { get; set; } + public Guid CagetoryId { get; set; } + public string Name { get; set; } + } + + [Fact] + public void EnableAddOrUpdateNavigateList_OneToMany_Parent() + { + var repo = g.sqlite.GetRepository(); + var cts = new[] { + new CagetoryParent + { + Name = "1", + Childs = new List(new[] + { + new CagetoryParent { Name = "1_1" }, + new CagetoryParent { Name = "1_2" }, + new CagetoryParent { Name = "1_3" } + }) + }, + new CagetoryParent + { + Name = "2", + Childs = new List(new[] + { + new CagetoryParent { Name = "2_1" }, + new CagetoryParent { Name = "2_2" } + }) + } + }; + repo.Insert(cts); + cts[0].Name = "11"; + cts[0].Childs.Clear(); + cts[1].Name = "22"; + cts[1].Childs.Clear(); + repo.Update(cts); + cts[0].Name = "111"; + cts[0].Childs.Clear(); + cts[0].Childs.Add(new CagetoryParent { Name = "1_33" }); + cts[1].Name = "222"; + cts[1].Childs.Clear(); + cts[1].Childs.Add(new CagetoryParent { Name = "2_22" }); + repo.Update(cts); + } + [Table(Name = "EAUNL_OTMP_CT")] + class CagetoryParent + { + public Guid Id { get; set; } + public string Name { get; set; } + + public Guid ParentId { get; set; } + [Navigate("ParentId")] + public List Childs { get; set; } + } + + [Fact] + public void EnableAddOrUpdateNavigateList_ManyToMany() + { + var tags = new[] { + new Tag { TagName = "" }, + new Tag { TagName = "80" }, + new Tag { TagName = "00" }, + new Tag { TagName = "ҡ" } + }; + var ss = new[] + { + new Song + { + Name = "һ.mp3", + Tags = new List(new[] + { + tags[0], tags[1] + }) + }, + new Song + { + Name = ".mp3", + Tags = new List(new[] + { + tags[0], tags[2] + }) + } + }; + var repo = g.sqlite.GetRepository(); + repo.Insert(ss); + + ss[0].Name = "һ.mp5"; + ss[0].Tags.Clear(); + ss[0].Tags.Add(tags[0]); + ss[1].Name = ".mp5"; + ss[1].Tags.Clear(); + ss[1].Tags.Add(tags[3]); + repo.Update(ss); + + ss[0].Name = "һ.mp4"; + ss[0].Tags.Clear(); + ss[1].Name = ".mp4"; + ss[1].Tags.Clear(); + repo.Update(ss); + } + [Table(Name = "EAUNL_MTM_SONG")] + class Song + { + public Guid Id { get; set; } + public string Name { get; set; } + public List Tags { get; set; } + } + [Table(Name = "EAUNL_MTM_TAG")] + class Tag + { + public Guid Id { get; set; } + public string TagName { get; set; } + public List Songs { get; set; } + } + [Table(Name = "EAUNL_MTM_SONGTAG")] + class SongTag + { + public Guid SongId { get; set; } + public Song Song { get; set; } + public Guid TagId { get; set; } + public Tag Tag { get; set; } + } } } From da24b9f8e4ccdd6e71bd453b8a3ea30134237117 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Sep 2019 15:54:55 +0800 Subject: [PATCH 0173/1029] v0.10.5 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 1 + FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 1 + FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 15 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index e885c372..b57730be 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.4 + 0.10.5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 94031d1d..9988e51a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 8a4a2161..ef88b0a2 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b86d5199..32941dab 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8a6e4551..ab1f5a3a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index 80203ae4..f0abaf46 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -258,6 +258,7 @@ namespace FreeSql.Tests.Odbc public virtual ICollection Builds { get; set; } public Templates Templates { get; set; } + public Guid ParentId { get; set; } public TaskBuild Parent { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 8ea6aa71..e4aab4fb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -303,6 +303,7 @@ namespace FreeSql.Tests public virtual ICollection Builds { get; set; } public Templates Templates { get; set; } + public Guid ParentId { get; set; } public TaskBuild Parent { get; set; } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index a790f3f5..c6b574b2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5eb3b0f5..8996eee6 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 094d443b..341df213 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index bac6db3e..7647df50 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 228a8aa3..45390a40 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 9e4ffebd..e83ebb02 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5ea29ab6..cbef282f 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 8400ed9b..7a169a2c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.4 + 0.10.5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 5a8188739c286ae4e26a489be7e1ad355d0b19ee Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Sep 2019 19:06:31 +0800 Subject: [PATCH 0174/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20DbContext/Re?= =?UTF-8?q?pository=20ManyToMany=E8=81=94=E7=BA=A7=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=BD=93=E6=98=AF=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=97=B6=E4=B8=8D=E6=9F=A5=E8=AF=A2=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E8=A1=A8=E8=AE=B0=E5=BD=95=E5=AF=B9=E6=AF=94=E5=B7=AE?= =?UTF-8?q?=E5=BC=82=EF=BC=88=E7=9B=B4=E6=8E=A5=E6=8F=92=E5=85=A5=EF=BC=89?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 9 ++++-- FreeSql.DbContext/DbSet/DbSet.cs | 8 +++++ FreeSql.DbContext/DbSet/DbSetAsync.cs | 32 +++++++++++--------- FreeSql.DbContext/DbSet/DbSetSync.cs | 37 +++++++++++++++--------- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++ 5 files changed, 64 insertions(+), 29 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index bce37fb8..5aaa2b44 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -34,9 +34,12 @@ namespace FreeSql set => _optionsPriv = value; get { - if (_optionsPriv != null) return _optionsPriv; - if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(Orm, out _optionsPriv)) return _optionsPriv; - _optionsPriv = new DbContextOptions(); + if (_optionsPriv == null) + { + _optionsPriv = new DbContextOptions(); + if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(Orm, out var opt)) + _optionsPriv.EnableAddOrUpdateNavigateList = opt.EnableAddOrUpdateNavigateList; + } return _optionsPriv; } } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index fbbbaa7c..4500ae9b 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -128,6 +128,14 @@ namespace FreeSql return this; } + Dictionary> _dicDbSetObjects = new Dictionary>(); + DbSet GetDbSetObject(Type et) + { + if (_dicDbSetObjects.TryGetValue(et, out var tryds)) return tryds; + _dicDbSetObjects.Add(et, tryds = _db.Set().AsType(et)); + return tryds; + } + public class EntityState { public EntityState(TEntity value, string key) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index dd385d01..a283061c 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -47,7 +47,7 @@ namespace FreeSql _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data); + await AddOrUpdateNavigateListAsync(data, true); } else { @@ -57,7 +57,7 @@ namespace FreeSql _db.Orm.MapEntityValue(_entityType, newval, data); Attach(newval); if (_db.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data); + await AddOrUpdateNavigateListAsync(data, true); } return; default: @@ -69,7 +69,7 @@ namespace FreeSql _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data); + await AddOrUpdateNavigateListAsync(data, true); } return; } @@ -77,7 +77,7 @@ namespace FreeSql EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data); + await AddOrUpdateNavigateListAsync(data, true); } public Task AddAsync(TEntity data) => AddPrivAsync(data, true); async public Task AddRangeAsync(IEnumerable data) @@ -107,7 +107,7 @@ namespace FreeSql AttachRange(rets); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - await AddOrUpdateNavigateListAsync(item); + await AddOrUpdateNavigateListAsync(item, true); return; default: foreach (var s in data) @@ -123,10 +123,10 @@ namespace FreeSql AttachRange(data); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - await AddOrUpdateNavigateListAsync(item); + await AddOrUpdateNavigateListAsync(item, true); } } - async Task AddOrUpdateNavigateListAsync(TEntity item) + async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd) { Type itemType = null; foreach (var prop in _table.Properties) @@ -164,7 +164,7 @@ namespace FreeSql var propValEach = propVal as IEnumerable; if (propValEach == null) continue; - DbSet refSet = _db.Set().AsType(tref.RefEntityType); + DbSet refSet = GetDbSetObject(tref.RefEntityType); switch (tref.RefType) { case Internal.Model.TableRefType.ManyToMany: @@ -197,10 +197,16 @@ namespace FreeSql } else //保存 { - var midSet = _db.Set().AsType(tref.RefMiddleEntityType); - var midSelect = midSet.Select; - foreach (var midWhere in midWheres) midSelect.Where(midWhere); - var midList = await midSelect.ToListAsync(); + var midSet = GetDbSetObject(tref.RefMiddleEntityType); + List midList = null; + if (isAdd == false) + { + var midSelect = midSet.Select; + foreach (var midWhere in midWheres) midSelect.Where(midWhere); + midList = await midSelect.ToListAsync(); + } + else + midList = new List(); var midListDel = new List(); var midListAdd = new List(); @@ -350,7 +356,7 @@ namespace FreeSql } if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - await AddOrUpdateNavigateListAsync(item); + await AddOrUpdateNavigateListAsync(item, false); } #endregion diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 8e0a7729..9d2b46be 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -47,7 +47,7 @@ namespace FreeSql _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data); + AddOrUpdateNavigateList(data, true); } else { @@ -57,7 +57,7 @@ namespace FreeSql _db.Orm.MapEntityValue(_entityType, newval, data); Attach(newval); if (_db.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data); + AddOrUpdateNavigateList(data, true); } return; default: @@ -69,7 +69,7 @@ namespace FreeSql _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data); + AddOrUpdateNavigateList(data, true); } return; } @@ -77,7 +77,7 @@ namespace FreeSql EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data); + AddOrUpdateNavigateList(data, true); } /// /// 添加 @@ -111,7 +111,7 @@ namespace FreeSql AttachRange(rets); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - AddOrUpdateNavigateList(item); + AddOrUpdateNavigateList(item, true); return; default: foreach (var s in data) @@ -127,11 +127,16 @@ namespace FreeSql AttachRange(data); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - AddOrUpdateNavigateList(item); + AddOrUpdateNavigateList(item, true); } } static ConcurrentDictionary> _dicLazyIsSetField = new ConcurrentDictionary>(); - void AddOrUpdateNavigateList(TEntity item) + /// + /// 联级保存导航集合 + /// + /// 实体对象 + /// 是否为新增的实体对象 + void AddOrUpdateNavigateList(TEntity item, bool isAdd) { Type itemType = null; foreach (var prop in _table.Properties) @@ -169,7 +174,7 @@ namespace FreeSql var propValEach = propVal as IEnumerable; if (propValEach == null) continue; - DbSet refSet = _db.Set().AsType(tref.RefEntityType); + DbSet refSet = GetDbSetObject(tref.RefEntityType); switch (tref.RefType) { case Internal.Model.TableRefType.ManyToMany: @@ -202,10 +207,16 @@ namespace FreeSql } else //保存 { - var midSet = _db.Set().AsType(tref.RefMiddleEntityType); - var midSelect = midSet.Select; - foreach (var midWhere in midWheres) midSelect.Where(midWhere); - var midList = midSelect.ToList(); + var midSet = GetDbSetObject(tref.RefMiddleEntityType); + List midList = null; + if (isAdd == false) + { + var midSelect = midSet.Select; + foreach (var midWhere in midWheres) midSelect.Where(midWhere); + midList = midSelect.ToList(); + } + else + midList = new List(); var midListDel = new List(); var midListAdd = new List(); @@ -361,7 +372,7 @@ namespace FreeSql } if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - AddOrUpdateNavigateList(item); + AddOrUpdateNavigateList(item, false); } #endregion diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 755141c4..dad2ddeb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -90,6 +90,13 @@ + + + 联级保存导航集合 + + 实体对象 + 是否为新增的实体对象 + 更新 From cb18b74830f0d124551d38010b2c9f0c25bc76a3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Sep 2019 19:11:58 +0800 Subject: [PATCH 0175/1029] v0.10.6 --- .../FreeSql.Extensions.BaseEntity.csproj | 4 ++-- .../FreeSql.Extensions.JsonMap.csproj | 4 ++-- .../FreeSql.Extensions.LazyLoading.csproj | 4 ++-- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 4 ++-- .../FreeSql.Provider.MySqlConnector.csproj | 4 ++-- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 4 ++-- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 4 ++-- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b57730be..72c44052 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.5 + 0.10.6 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. @@ -19,7 +19,7 @@ - + diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 9988e51a..5878ad7d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. @@ -19,7 +19,7 @@ - + diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ef88b0a2..2f886e7a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. @@ -19,7 +19,7 @@ - + diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 32941dab..8acf14fc 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index ab1f5a3a..8c4fe26a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c6b574b2..2b2ce63a 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 8996eee6..0039301f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 341df213..ad2cbaea 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 7647df50..535120e5 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 45390a40..b684d13d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 @@ -19,7 +19,7 @@ - + diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e83ebb02..2d690ac5 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cbef282f..4779fdbf 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7a169a2c..da1002a2 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.5 + 0.10.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 78fded3f8e4f9169097d994dc8dfd3f04598395f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 3 Oct 2019 04:31:04 +0800 Subject: [PATCH 0176/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IndexAttribu?= =?UTF-8?q?te=20=E7=89=B9=E6=80=A7=EF=BC=8C=E8=87=AA=E5=8A=A8=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E7=B4=A2=E5=BC=95=EF=BC=8C=E4=BB=A5=E5=8F=8A=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E7=9A=84=20FluentApi=20=E6=96=B9=E6=B3=95=EF=BC=9B=20?= =?UTF-8?q?-=20=E7=A7=BB=E9=99=A4=20ColumnAttribute.Unique=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E8=AE=BE=E7=BD=AE=EF=BC=8C=E6=94=B9=E4=B8=BA=20IndexA?= =?UTF-8?q?ttribute=20=E7=89=B9=E6=80=A7=E8=AE=BE=E7=BD=AE=E5=94=AF?= =?UTF-8?q?=E4=B8=80=E9=94=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlCodeFirstTest.cs | 7 +- .../MySql/MySqlCodeFirstTest.cs | 7 +- .../Oracle/OracleCodeFirstTest.cs | 7 +- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 7 +- .../SqlServer/SqlServerCodeFirstTest.cs | 7 +- .../DataAnnotations/MySqlFluentTest.cs | 1 + .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 7 +- .../Oracle/OracleCodeFirstTest.cs | 7 +- .../FreeSql.Tests/Other/SystemUser.cs | 3 +- .../Other/SystemUserAuthentication.cs | 3 +- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 7 +- .../SqlServer/SqlServerCodeFirstTest.cs | 7 +- .../Sqlite/SqliteCodeFirstTest.cs | 7 +- FreeSql/DataAnnotations/ColumnAttribute.cs | 30 +---- FreeSql/DataAnnotations/ColumnFluent.cs | 10 -- FreeSql/DataAnnotations/TableAttribute.cs | 33 +++++ FreeSql/DataAnnotations/TableFluent.cs | 28 ++++ FreeSql/DatabaseModel/DBTableInfo.cs | 8 +- FreeSql/DatabaseModel/DbIndexInfo.cs | 21 +++ FreeSql/FreeSql.xml | 53 ++++++-- FreeSql/FreeSqlBuilder.cs | 4 +- FreeSql/Interface/ICodeFirst.cs | 4 +- FreeSql/Internal/CommonUtils.cs | 26 +++- FreeSql/Internal/Model/IndexInfo.cs | 21 +++ FreeSql/Internal/Model/TableInfo.cs | 5 +- FreeSql/Internal/UtilsExpressionTree.cs | 125 +++++++++++------- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 74 +++++++---- .../FreeSql.Provider.MySql/MySqlDbFirst.cs | 54 ++++---- .../MySql/OdbcMySqlCodeFirst.cs | 74 +++++++---- .../MySql/OdbcMySqlDbFirst.cs | 54 ++++---- .../Oracle/OdbcOracleCodeFirst.cs | 111 +++++++++++----- .../Oracle/OdbcOracleDbFirst.cs | 72 +++++----- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 72 ++++++---- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 44 +++--- .../SqlServer/OdbcSqlServerCodeFirst.cs | 78 +++++++---- .../SqlServer/OdbcSqlServerDbFirst.cs | 47 ++++--- .../OracleCodeFirst.cs | 109 ++++++++++----- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 72 +++++----- .../PostgreSQLCodeFirst.cs | 72 ++++++---- .../PostgreSQLDbFirst.cs | 44 +++--- .../SqlServerCodeFirst.cs | 78 +++++++---- .../SqlServerDbFirst.cs | 47 ++++--- .../SqliteCodeFirst.cs | 70 ++++++---- 43 files changed, 1010 insertions(+), 607 deletions(-) create mode 100644 FreeSql/DatabaseModel/DbIndexInfo.cs create mode 100644 FreeSql/Internal/Model/IndexInfo.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 48e209f0..7a8e141d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -46,17 +46,16 @@ namespace FreeSql.Tests.MySqlConnector g.mysql.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index b857909c..e28cb85f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -46,17 +46,16 @@ namespace FreeSql.Tests.Odbc.MySql g.mysql.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs index f34d6754..a5686eeb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -46,17 +46,16 @@ namespace FreeSql.Tests.Odbc.Oracle g.oracle.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs index 6d0aa7ae..81773eba 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -50,17 +50,16 @@ namespace FreeSql.Tests.Odbc.PostgreSQL g.pgsql.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index 8ebc109e..68ca3891 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -48,17 +48,16 @@ namespace FreeSql.Tests.Odbc.SqlServer g.sqlserver.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index 5f736963..596a5dc1 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -163,6 +163,7 @@ namespace FreeSql.Tests.DataAnnotations Assert.NotEqual(item.testfield2, find.testfield2); Assert.Equal(1000, find.testfield1); } + [Index("idx_xxx", "testfield1 ASC, testfield2 DESC")] class TestCanInsert { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index a3017d2d..3fe86a01 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -46,17 +46,16 @@ namespace FreeSql.Tests.MySql g.mysql.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", false)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index a7ccc99a..4cfd7adc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -46,17 +46,16 @@ namespace FreeSql.Tests.Oracle g.oracle.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22 desc", true)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Other/SystemUser.cs b/FreeSql.Tests/FreeSql.Tests/Other/SystemUser.cs index 1b7a0a8a..9091a97d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Other/SystemUser.cs +++ b/FreeSql.Tests/FreeSql.Tests/Other/SystemUser.cs @@ -9,12 +9,13 @@ namespace Zeus /// 用户表 /// [Table(Name = "system_user")] + [Index("UK_DisplayName", "DisplayName", true)] public partial class SystemUser : EntityBase { /// /// 显示名称 /// - [Column(DbType = "varchar(20)", IsNullable = false, Unique = "UK_DisplayName")] + [Column(DbType = "varchar(20)", IsNullable = false)] public string DisplayName { get; set; } /// /// 真实名称 diff --git a/FreeSql.Tests/FreeSql.Tests/Other/SystemUserAuthentication.cs b/FreeSql.Tests/FreeSql.Tests/Other/SystemUserAuthentication.cs index 5da122f7..594c3865 100644 --- a/FreeSql.Tests/FreeSql.Tests/Other/SystemUserAuthentication.cs +++ b/FreeSql.Tests/FreeSql.Tests/Other/SystemUserAuthentication.cs @@ -10,6 +10,7 @@ namespace Zeus /// 用户认证表 /// [Table(Name = "system_user_authentication")] + [Index("UK_Identifier", "Identifier", true)] public partial class SystemUserAuthentication : EntityBase { /// @@ -30,7 +31,7 @@ namespace Zeus /// /// 登录标识 /// - [Column(DbType = "varchar(50)", IsNullable = false, Unique = "UK_Identifier")] + [Column(DbType = "varchar(50)", IsNullable = false)] public string Identifier { get; set; } /// /// 登录凭证 diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index 8b330b37..d91dc319 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -53,17 +53,16 @@ namespace FreeSql.Tests.PostgreSQL g.pgsql.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", false)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index f4ec916e..6772988d 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -57,17 +57,16 @@ namespace FreeSql.Tests.SqlServer _sqlserverFixture.SqlServer.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", false)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index ef0597df..48281579 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -46,17 +46,16 @@ namespace FreeSql.Tests.Sqlite g.sqlite.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo2", OldName = "AddUniquesInfo")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group desc, index22", true)] class AddUniquesInfo { public Guid id { get; set; } - [Column(Unique = "uk_phone")] public string phone { get; set; } - [Column(Unique = "uk_group_index, uk_group_index22")] public string group { get; set; } - [Column(Unique = "uk_group_index")] public int index { get; set; } - [Column(Unique = "uk_group_index22")] public string index22 { get; set; } } diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 96955872..0c9944e1 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -3,6 +3,7 @@ using System.Linq; namespace FreeSql.DataAnnotations { + [AttributeUsage(AttributeTargets.Property)] public class ColumnAttribute : Attribute { @@ -42,35 +43,6 @@ namespace FreeSql.DataAnnotations /// public bool IsVersion { get => _IsVersion ?? false; set => _IsVersion = value; } - internal string[] _Uniques; - /// - /// 唯一键,在多个属性指定相同的标识,代表联合键;可使用逗号分割多个 UniqueKey 名。 - /// - public string Unique - { - get => _Uniques == null ? null : string.Join(", ", _Uniques); - set - { - if (string.IsNullOrEmpty(value)) - { - _Uniques = null; - return; - } - var val = value?.Trim(' ', '\t', ','); - if (string.IsNullOrEmpty(val)) - { - _Uniques = null; - return; - } - var arr = val.Split(',').Select(a => a.Trim(' ', '\t').Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); - if (arr.Any() == false) - { - _Uniques = null; - return; - } - _Uniques = arr; - } - } /// /// 数据库默认值 /// diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index 0f80bb02..3cebe19c 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -77,16 +77,6 @@ namespace FreeSql.DataAnnotations return this; } /// - /// 唯一键,在多个属性指定相同的标识,代表联合键;可使用逗号分割多个 UniqueKey 名。 - /// - /// 标识 - /// - public ColumnFluent Unique(string value) - { - _column.Unique = value; - return this; - } - /// /// 类型映射,比如:可将 enum 属性映射成 typeof(string) /// /// diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index ef5a4dda..18fb2e54 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Concurrent; +using System.Linq.Expressions; namespace FreeSql.DataAnnotations { + [AttributeUsage(AttributeTargets.Class)] public class TableAttribute : Attribute { @@ -27,5 +29,36 @@ namespace FreeSql.DataAnnotations internal ConcurrentDictionary _columns { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); internal ConcurrentDictionary _navigates { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + internal ConcurrentDictionary _indexs { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + } + + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + public class IndexAttribute : Attribute + { + public IndexAttribute(string name, string fields) + { + this.Name = name; + this.Fields = fields; + } + public IndexAttribute(string name, string fields, bool isUnique) + { + this.Name = name; + this.Fields = fields; + this.IsUnique = isUnique; + } + /// + /// 索引名 + /// + public string Name { get; set; } + /// + /// 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + /// + public string Fields { get; set; } + + internal bool? _IsUnique; + /// + /// 是否唯一 + /// + public bool IsUnique { get => _IsUnique ?? false; set => _IsUnique = value; } } } diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 9027d529..d29e94fa 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -59,6 +59,20 @@ namespace FreeSql.DataAnnotations var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto }); return new ColumnFluent(col); } + + /// + /// 设置实体的索引 + /// + /// 索引名 + /// 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + /// 是否唯一 + /// + public TableFluent Index(string name, string fields, bool isUnique = false) + { + var idx = new IndexAttribute(name, fields, isUnique); + _table._indexs.AddOrUpdate(name, idx, (_, __) => idx); + return this; + } } public class TableFluent @@ -128,5 +142,19 @@ namespace FreeSql.DataAnnotations _table._navigates.AddOrUpdate(member.Name, nav, (name, old) => nav); return this; } + + /// + /// 设置实体的索引 + /// + /// 索引名 + /// 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + /// 是否唯一 + /// + public TableFluent Index(string name, string fields, bool isUnique = false) + { + var idx = new IndexAttribute(name, fields, isUnique); + _table._indexs.AddOrUpdate(name, idx, (_, __) => idx); + return this; + } } } diff --git a/FreeSql/DatabaseModel/DBTableInfo.cs b/FreeSql/DatabaseModel/DBTableInfo.cs index 10dc42e0..f294b406 100644 --- a/FreeSql/DatabaseModel/DBTableInfo.cs +++ b/FreeSql/DatabaseModel/DBTableInfo.cs @@ -40,18 +40,18 @@ namespace FreeSql.DatabaseModel /// /// 唯一键/组合 /// - public Dictionary> UniquesDict { get; set; } = new Dictionary>(); + public Dictionary UniquesDict { get; set; } = new Dictionary(); /// /// 索引/组合 /// - public Dictionary> IndexesDict { get; set; } = new Dictionary>(); + public Dictionary IndexesDict { get; set; } = new Dictionary(); /// /// 外键 /// public Dictionary ForeignsDict { get; set; } = new Dictionary(); - public List> Uniques => UniquesDict.Values.ToList(); - public List> Indexes => IndexesDict.Values.ToList(); + public List Uniques => UniquesDict.Values.ToList(); + public List Indexes => IndexesDict.Values.ToList(); public List Foreigns => ForeignsDict.Values.ToList(); } diff --git a/FreeSql/DatabaseModel/DbIndexInfo.cs b/FreeSql/DatabaseModel/DbIndexInfo.cs new file mode 100644 index 00000000..f8de2c6a --- /dev/null +++ b/FreeSql/DatabaseModel/DbIndexInfo.cs @@ -0,0 +1,21 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace FreeSql.DatabaseModel +{ + public class DbIndexInfo + { + public string Name { get; set; } + public List Columns { get; } = new List(); + public bool IsUnique { get; set; } + } + + public class DbIndexColumnInfo + { + public DbColumnInfo Column { get; set; } + public bool IsDesc { get; set; } + } +} \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3d2a21c9..7a86ceb0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -45,11 +45,6 @@ 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) - - - 唯一键,在多个属性指定相同的标识,代表联合键;可使用逗号分割多个 UniqueKey 名。 - - 数据库默认值 @@ -123,13 +118,6 @@ 乐观锁 - - - 唯一键,在多个属性指定相同的标识,代表联合键;可使用逗号分割多个 UniqueKey 名。 - - 标识 - - 类型映射,比如:可将 enum 属性映射成 typeof(string) @@ -199,6 +187,21 @@ 禁用 CodeFirst 同步结构迁移 + + + 索引名 + + + + + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + + 是否唯一 + + 数据库表名 @@ -219,6 +222,15 @@ 禁用 CodeFirst 同步结构迁移 + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + 数据库表名 @@ -249,6 +261,15 @@ 多对多关系的中间实体类型 + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + 所属表 @@ -551,7 +572,9 @@ - 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 @@ -2288,7 +2311,9 @@ - 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 12b4102f..154ae22b 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -78,7 +78,9 @@ namespace FreeSql return this; } /// - /// 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 + /// 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + /// 本功能会影响 IFreeSql 首次访问的速度。 + /// 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 /// /// /// diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index de49488a..18b7b67e 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -21,7 +21,9 @@ namespace FreeSql /// bool IsSyncStructureToUpper { get; set; } /// - /// 使用数据库的主键和自增,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql。 + /// 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + /// 本功能会影响 IFreeSql 首次访问的速度。 + /// 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 /// bool IsConfigEntityFromDbFirst { get; set; } /// diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index e976465d..7c9ed240 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -125,7 +125,6 @@ namespace FreeSql.Internal if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable; if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore; if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion; - if (trycol._Uniques != null) attr._Uniques = trycol._Uniques; if (trycol.MapType != null) attr.MapType = trycol.MapType; if (trycol._Position != null) attr._Position = trycol.Position; if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert; @@ -145,7 +144,6 @@ namespace FreeSql.Internal if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable; if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore; if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion; - if (tryattr._Uniques != null) attr._Uniques = tryattr._Uniques; if (tryattr.MapType != null) attr.MapType = tryattr.MapType; if (tryattr._Position != null) attr._Position = tryattr.Position; if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert; @@ -161,7 +159,6 @@ namespace FreeSql.Internal if (attr._IsNullable != null) ret = attr; if (attr._IsIgnore != null) ret = attr; if (attr._IsVersion != null) ret = attr; - if (attr._Uniques != null) ret = attr; if (attr.MapType != null) ret = attr; if (attr._Position != null) ret = attr; if (attr._CanInsert != null) ret = attr; @@ -191,6 +188,29 @@ namespace FreeSql.Internal if (attr.ManyToMany != null) ret = attr; return ret; } + public IndexAttribute[] GetEntityIndexAttribute(Type type) + { + var ret = new Dictionary(); ; + if (dicConfigEntity.TryGetValue(type, out var trytb)) + { + foreach (var idxattr in trytb._indexs.Values) + { + if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields)) + ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique }); + } + } + var attrs = type.GetCustomAttributes(typeof(IndexAttribute), true); + foreach (var tryattrobj in attrs) + { + var idxattr = tryattrobj as IndexAttribute; + if (idxattr == null) continue; + if (string.IsNullOrEmpty(idxattr.Name)) continue; + if (string.IsNullOrEmpty(idxattr.Fields)) continue; + if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name); + ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique }); + } + return ret.Values.ToArray(); + } public string WhereObject(TableInfo table, string aliasAndDot, object dywhere) { diff --git a/FreeSql/Internal/Model/IndexInfo.cs b/FreeSql/Internal/Model/IndexInfo.cs new file mode 100644 index 00000000..149730f0 --- /dev/null +++ b/FreeSql/Internal/Model/IndexInfo.cs @@ -0,0 +1,21 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace FreeSql.Internal.Model +{ + public class IndexInfo + { + public string Name { get; set; } + public IndexColumnInfo[] Columns { get; set; } + public bool IsUnique { get; set; } + } + + public class IndexColumnInfo + { + public ColumnInfo Column { get; set; } + public bool IsDesc { get; set; } + } +} \ No newline at end of file diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index 1e1b3da8..398721a6 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.DataAnnotations; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Reflection; @@ -16,7 +17,7 @@ namespace FreeSql.Internal.Model public Dictionary ColumnsByCsIgnore { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public ColumnInfo[] ColumnsByPosition { get; set; } public ColumnInfo[] Primarys { get; set; } - public Dictionary> Uniques { get; set; } + public IndexInfo[] Indexes { get; set; } public string CsName { get; set; } public string DbName { get; set; } public string DbOldName { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 09a3fac4..862c3b62 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -103,7 +103,6 @@ namespace FreeSql.Internal IsNullable = tp.Value.isnullable ?? true, IsPrimary = false, IsIgnore = false, - Unique = null, MapType = p.PropertyType }; if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable; @@ -119,16 +118,8 @@ namespace FreeSql.Internal if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; - if (common.CodeFirst.IsSyncStructureToLower) - { - colattr.Name = colattr.Name.ToLower(); - colattr.Unique = colattr.Unique?.ToLower(); - } - if (common.CodeFirst.IsSyncStructureToUpper) - { - colattr.Name = colattr.Name.ToUpper(); - colattr.Unique = colattr.Unique?.ToUpper(); - } + if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower(); + if (common.CodeFirst.IsSyncStructureToUpper) colattr.Name = colattr.Name.ToUpper(); if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) { @@ -183,27 +174,9 @@ namespace FreeSql.Internal if (trytb.VersionColumn.Attribute.MapType.IsNullableType() || trytb.VersionColumn.Attribute.MapType.IsNumberType() == false) throw new Exception($"属性{trytb.VersionColumn.CsName} 被标注为行锁(乐观锁)(IsVersion),但其必须为数字类型,并且不可为 Nullable"); } - trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); - if (trytb.Primarys.Any() == false) - { - var identcol = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).FirstOrDefault(); - if (identcol != null) trytb.Primarys = new[] { identcol }; - if (trytb.Primarys.Any() == false) - { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, "id", true) == 0).ToArray(); - if (trytb.Primarys.Any() == false) - { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}id", true) == 0).ToArray(); - if (trytb.Primarys.Any() == false) - { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}_id", true) == 0).ToArray(); - } - } - } - foreach (var col in trytb.Primarys) - col.Attribute.IsPrimary = true; - } - //从数据库查找主键、自增 + + var indexesDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + //从数据库查找主键、自增、索引 if (common.CodeFirst.IsConfigEntityFromDbFirst) { try @@ -220,37 +193,99 @@ namespace FreeSql.Internal { foreach (var dbident in dbtb.Identitys) { - if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.Attribute.MapType == dbident.CsType || - trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.Attribute.MapType == dbident.CsType) + if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.Attribute.MapType.NullableTypeOrThis() == dbident.CsType.NullableTypeOrThis() || + trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.Attribute.MapType.NullableTypeOrThis() == dbident.CsType.NullableTypeOrThis()) trycol.Attribute.IsIdentity = true; } foreach (var dbpk in dbtb.Primarys) { - if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.Attribute.MapType == dbpk.CsType || - trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.Attribute.MapType == dbpk.CsType) + if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.Attribute.MapType.NullableTypeOrThis() == dbpk.CsType.NullableTypeOrThis() || + trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.Attribute.MapType.NullableTypeOrThis() == dbpk.CsType.NullableTypeOrThis()) trycol.Attribute.IsPrimary = true; } - foreach (var dbuk in dbtb.UniquesDict) + foreach (var dbidx in dbtb.IndexesDict) { - foreach (var dbcol in dbuk.Value) + var indexColumns = new List(); + foreach (var dbcol in dbidx.Value.Columns) { - if (trytb.Columns.TryGetValue(dbcol.Name, out var trycol) && trycol.Attribute.MapType == dbcol.CsType || - trytb.ColumnsByCs.TryGetValue(dbcol.Name, out trycol) && trycol.Attribute.MapType == dbcol.CsType) - if (trycol.Attribute._Uniques?.Contains(dbuk.Key) != true) - trycol.Attribute.Unique += $"," + dbuk.Key; + if (trytb.Columns.TryGetValue(dbcol.Column.Name, out var trycol) && trycol.Attribute.MapType.NullableTypeOrThis() == dbcol.Column.CsType.NullableTypeOrThis() || + trytb.ColumnsByCs.TryGetValue(dbcol.Column.Name, out trycol) && trycol.Attribute.MapType.NullableTypeOrThis() == dbcol.Column.CsType.NullableTypeOrThis()) + indexColumns.Add(new IndexColumnInfo + { + Column = trycol, + IsDesc = dbcol.IsDesc + }); } + if (indexColumns.Any() == false) continue; + if (indexesDict.ContainsKey(dbidx.Key)) indexesDict.Remove(dbidx.Key); + indexesDict.Add(dbidx.Key, new IndexInfo + { + Name = dbidx.Key, + Columns = indexColumns.ToArray(), + IsUnique = dbidx.Value.IsUnique + }); } } } } catch { } - trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); } - var allunique = trytb.Columns.Values.Where(a => a.Attribute._Uniques != null).SelectMany(a => a.Attribute._Uniques).Distinct(); - trytb.Uniques = allunique.ToDictionary(a => a, a => trytb.Columns.Values.Where(b => b.Attribute._Uniques != null && b.Attribute._Uniques.Contains(a)).ToList()); + //索引和唯一键 + var indexes = common.GetEntityIndexAttribute(trytb.Type); + foreach (var index in indexes) + { + var val = index.Fields?.Trim(' ', '\t', ','); + if (string.IsNullOrEmpty(val)) continue; + var arr = val.Split(',').Select(a => a.Trim(' ', '\t').Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); + if (arr.Any() == false) continue; + var indexColumns = new List(); + foreach (var field in arr) + { + var idxcol = new IndexColumnInfo(); + if (field.EndsWith(" DESC", StringComparison.CurrentCultureIgnoreCase)) idxcol.IsDesc = true; + var colname = Regex.Replace(field, " (DESC|ASC)", "", RegexOptions.IgnoreCase); + if (trytb.ColumnsByCs.TryGetValue(colname, out var trycol) || trytb.Columns.TryGetValue(colname, out trycol)) + { + idxcol.Column = trycol; + indexColumns.Add(idxcol); + } + } + if (indexColumns.Any() == false) continue; + var indexName = common.CodeFirst.IsSyncStructureToLower ? index.Name.ToLower() : (common.CodeFirst.IsSyncStructureToUpper ? index.Name.ToUpper() : index.Name); + if (indexesDict.ContainsKey(indexName)) indexesDict.Remove(indexName); + indexesDict.Add(indexName, new IndexInfo + { + Name = indexName, + Columns = indexColumns.ToArray(), + IsUnique = index.IsUnique + }); + } + trytb.Indexes = indexesDict.Values.ToArray(); trytb.ColumnsByPosition = columnsList.Where(a => a.Attribute.Position > 0).OrderBy(a => a.Attribute.Position) .Concat(columnsList.Where(a => a.Attribute.Position == 0)) .Concat(columnsList.Where(a => a.Attribute.Position < 0).OrderBy(a => a.Attribute.Position)).ToArray(); + + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + if (trytb.Primarys.Any() == false) + { + trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, "id", true) == 0).ToArray(); + if (trytb.Primarys.Any() == false) + { + var identcol = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).FirstOrDefault(); + if (identcol != null) trytb.Primarys = new[] { identcol }; + if (trytb.Primarys.Any() == false) + { + trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}id", true) == 0).ToArray(); + if (trytb.Primarys.Any() == false) + { + trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}_id", true) == 0).ToArray(); + } + } + } + foreach (var col in trytb.Primarys) + col.Attribute.IsPrimary = true; + } + foreach (var col in trytb.Primarys) col.Attribute.IsNullable = false; tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index ae762748..c718608b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -131,7 +131,8 @@ namespace FreeSql.MySql if (tboldname == null) { //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); @@ -146,14 +147,22 @@ namespace FreeSql.MySql foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) Engine=InnoDB;\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } continue; } //如果新表,旧表在一个数据库下,直接修改表名 @@ -235,19 +244,28 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); var dsuksql = _commonUtils.FormatSql(@" select a.column_name, -a.constraint_name 'index_id' -from information_schema.key_column_usage a -where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) +a.index_name 'index_id', +0 'IsDesc', +case when a.non_unique = 0 then 1 else 0 end 'IsUnique' +from information_schema.statistics a +where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRIMARY'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) { - if (uk.Key == "PRIMARY" || string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); } } @@ -277,12 +295,6 @@ where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbna foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) Engine=InnoDB;\r\n"); sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); @@ -310,6 +322,20 @@ where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbna sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } } return sb.Length == 0 ? null : sb.ToString(); } diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 2f2a339a..9df16ee1 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -252,21 +252,21 @@ where a.table_schema in ({1}) and a.table_name in ({0}) sql = string.Format(@" select -concat(a.constraint_schema, '.', a.table_name) 'table_id', +concat(a.table_schema, '.', a.table_name) 'table_id', a.column_name, -a.constraint_name 'index_id', -1 'IsUnique', -case when a.constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', +a.index_name 'index_id', +case when a.non_unique = 0 then 1 else 0 end 'IsUnique', +case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' -from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position_in_unique_constraint) +from information_schema.statistics a +where a.table_schema in ({1}) and a.table_name in ({0}) and a.index_name <> 'PRIMARY' ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); foreach (var row in ds) { string table_id = string.Concat(row[0]); @@ -275,29 +275,27 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position bool is_unique = string.Concat(row[3]) == "1"; bool is_primary_key = string.Concat(row[4]) == "1"; bool is_clustered = string.Concat(row[5]) == "1"; - int is_desc = int.Parse(string.Concat(row[6])); + bool is_desc = string.Concat(row[6]) == "1"; if (database.Length == 1) - { table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; var loc9 = loc3[table_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; + Dictionary loc10 = null; + DbIndexInfo loc11 = null; if (!indexColumns.TryGetValue(table_id, out loc10)) - indexColumns.Add(table_id, loc10 = new Dictionary>()); + indexColumns.Add(table_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); if (is_unique && !is_primary_key) { if (!uniqueColumns.TryGetValue(table_id, out loc10)) - uniqueColumns.Add(table_id, loc10 = new Dictionary>()); + uniqueColumns.Add(table_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); } } foreach (string table_id in indexColumns.Keys) @@ -309,7 +307,7 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position { foreach (var column in uniqueColumns[table_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); loc2[table_id].UniquesDict.Add(column.Key, column.Value); } } @@ -372,14 +370,14 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - { - foreach (var loc5 in loc4.UniquesDict.First().Value) - { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); loc4.Columns.Sort((c1, c2) => { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index df99ba84..36b06ec7 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -119,7 +119,8 @@ namespace FreeSql.Odbc.MySql if (tboldname == null) { //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); @@ -134,14 +135,22 @@ namespace FreeSql.Odbc.MySql foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) Engine=InnoDB;\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } continue; } //如果新表,旧表在一个数据库下,直接修改表名 @@ -223,19 +232,28 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); var dsuksql = _commonUtils.FormatSql(@" select a.column_name, -a.constraint_name 'index_id' -from information_schema.key_column_usage a -where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) +a.index_name 'index_id', +0 'IsDesc', +case when a.non_unique = 0 then 1 else 0 end 'IsUnique' +from information_schema.statistics a +where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRIMARY'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) { - if (uk.Key == "PRIMARY" || string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); } } @@ -265,12 +283,6 @@ where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbna foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) Engine=InnoDB;\r\n"); sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); @@ -298,6 +310,20 @@ where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbna sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } } return sb.Length == 0 ? null : sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index 569df99f..6e9d3621 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -222,21 +222,21 @@ where a.table_schema in ({1}) and a.table_name in ({0}) sql = string.Format(@" select -concat(a.constraint_schema, '.', a.table_name) 'table_id', +concat(a.table_schema, '.', a.table_name) 'table_id', a.column_name, -a.constraint_name 'index_id', -1 'IsUnique', -case when a.constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', +a.index_name 'index_id', +case when a.non_unique = 0 then 1 else 0 end 'IsUnique', +case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' -from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position_in_unique_constraint) +from information_schema.statistics a +where a.table_schema in ({1}) and a.table_name in ({0}) and a.index_name <> 'PRIMARY' ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); foreach (var row in ds) { string table_id = string.Concat(row[0]); @@ -245,29 +245,27 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position bool is_unique = string.Concat(row[3]) == "1"; bool is_primary_key = string.Concat(row[4]) == "1"; bool is_clustered = string.Concat(row[5]) == "1"; - int is_desc = int.Parse(string.Concat(row[6])); + bool is_desc = string.Concat(row[6]) == "1"; if (database.Length == 1) - { table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; var loc9 = loc3[table_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; + Dictionary loc10 = null; + DbIndexInfo loc11 = null; if (!indexColumns.TryGetValue(table_id, out loc10)) - indexColumns.Add(table_id, loc10 = new Dictionary>()); + indexColumns.Add(table_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); if (is_unique && !is_primary_key) { if (!uniqueColumns.TryGetValue(table_id, out loc10)) - uniqueColumns.Add(table_id, loc10 = new Dictionary>()); + uniqueColumns.Add(table_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); } } foreach (string table_id in indexColumns.Keys) @@ -279,7 +277,7 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position { foreach (var column in uniqueColumns[table_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); loc2[table_id].UniquesDict.Add(column.Key, column.Value); } } @@ -342,14 +340,14 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - { - foreach (var loc5 in loc4.UniquesDict.First().Value) - { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); loc4.Columns.Sort((c1, c2) => { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index e92eb774..c1646775 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -108,7 +108,8 @@ namespace FreeSql.Odbc.Oracle if (tboldname == null) { //创建表 - sb.Append("execute immediate 'CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("execute immediate 'CREATE TABLE ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); @@ -121,14 +122,22 @@ namespace FreeSql.Odbc.Oracle foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } //备注 foreach (var tbcol in tb.ColumnsByPosition) { @@ -222,29 +231,39 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } + + CreateOracleFunction(_orm); var dsuksql = _commonUtils.FormatSql(@" select -c.column_name, -c.constraint_name -from -all_constraints a, -all_cons_columns c -where -a.constraint_name = c.constraint_name -and a.owner = c.owner +nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), +a.index_name, +case when c.descend = 'DESC' then 1 else 0 end, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end, +c.column_position +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.constraint_type in ('U') -and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) +and a.owner in ({0}) and a.table_name in ({1}) +and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P')", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]).Trim('"'), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }).ToArray(); + foreach (var uk in tb.Indexes) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("';\r\n"); - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append("';\r\n"); + sbalter.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n"); } } @@ -275,12 +294,6 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); //备注 @@ -315,6 +328,20 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n"); sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } } Dictionary dicDeclare = new Dictionary(); Action dropSequence = seqname => @@ -407,5 +434,27 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); sqlType += $"({data_length})"; return sqlType; } + + internal static void CreateOracleFunction(IFreeSql fsql) + { + fsql.Ado.ExecuteNonQuery(CommandType.Text, @" +CREATE OR REPLACE FUNCTION freesql_long_2_varchar ( + p_index_name IN user_ind_expressions.index_name%TYPE, + p_table_name IN user_ind_expressions.table_name%TYPE, + p_COLUMN_POSITION IN user_ind_expressions.table_name%TYPE) + RETURN VARCHAR2 +AS + l_COLUMN_EXPRESSION LONG; +BEGIN + SELECT COLUMN_EXPRESSION + INTO l_COLUMN_EXPRESSION + FROM user_ind_expressions + WHERE index_name = p_index_name + AND table_name = p_table_name + AND COLUMN_POSITION = p_COLUMN_POSITION; + + RETURN SUBSTR (l_COLUMN_EXPRESSION, 1, 4000); +END;"); + } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index 09c98ac7..84ce0cd3 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -287,61 +287,59 @@ where a.owner in ({1}) and a.table_name in ({0}) loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); } + OdbcOracleCodeFirst.CreateOracleFunction(_orm); sql = string.Format(@" select -a.owner || '.' || a.table_name, -c.column_name, -c.constraint_name, -case when a.constraint_type = 'U' then 1 else 0 end, -case when a.constraint_type = 'P' then 1 else 0 end, +a.table_owner || '.' || a.table_name, +nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), +c.index_name, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end, 0, -0 -from -all_constraints a, -all_cons_columns c -where -a.constraint_name = c.constraint_name -and a.owner = c.owner +0, +case when c.descend = 'DESC' then 1 else 0 end, +c.column_position +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.constraint_type in ('P', 'U') -and a.owner in ({1}) and a.table_name in ({0}) +and a.table_owner in ({1}) and a.table_name in ({0}) +and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); foreach (var row in ds) { string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); + string column = string.Concat(row[1]).Trim('"'); string index_id = string.Concat(row[2]); bool is_unique = string.Concat(row[3]) == "1"; bool is_primary_key = string.Concat(row[4]) == "1"; bool is_clustered = string.Concat(row[5]) == "1"; - int is_desc = int.Parse(string.Concat(row[6])); + bool is_desc = string.Concat(row[6]) == "1"; if (database.Length == 1) - { table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; var loc9 = loc3[table_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; + Dictionary loc10 = null; + DbIndexInfo loc11 = null; if (!indexColumns.TryGetValue(table_id, out loc10)) - indexColumns.Add(table_id, loc10 = new Dictionary>()); + indexColumns.Add(table_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); if (is_unique && !is_primary_key) { if (!uniqueColumns.TryGetValue(table_id, out loc10)) - uniqueColumns.Add(table_id, loc10 = new Dictionary>()); + uniqueColumns.Add(table_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); } } foreach (string table_id in indexColumns.Keys) @@ -353,7 +351,7 @@ and a.owner in ({1}) and a.table_name in ({0}) { foreach (var column in uniqueColumns[table_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); loc2[table_id].UniquesDict.Add(column.Key, column.Value); } } @@ -441,14 +439,14 @@ and a.owner in ({1}) and a.table_name in ({0}) } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - { - foreach (var loc5 in loc4.UniquesDict.First().Value) - { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); loc4.Columns.Sort((c1, c2) => { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 607938f8..fdd063a8 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -108,7 +108,8 @@ namespace FreeSql.Odbc.PostgreSQL if (tboldname == null) { //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); @@ -120,14 +121,22 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } //备注 foreach (var tbcol in tb.ColumnsByPosition) { @@ -233,23 +242,32 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); var dsuksql = _commonUtils.FormatSql(@" select c.attname, -b.relname +b.relname, +case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +case when indisunique = 't' then 1 else 0 end IsUnique from pg_index a inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where ns.nspname in ({0}) and d.relname in ({1}) and a.indisunique = 't'", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) +where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); } } @@ -283,12 +301,6 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); //备注 @@ -320,6 +332,20 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } } foreach (var seqcol in seqcols) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 94c26fa5..27adf73a 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -251,7 +251,7 @@ b.relname as index_id, case when a.indisunique then 1 else 0 end IsUnique, case when a.indisprimary then 1 else 0 end IsPrimary, case when a.indisclustered then 0 else 1 end IsClustered, -0 IsDesc, +case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, a.indkey::text, c.attnum from pg_index a @@ -259,13 +259,13 @@ inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where ns.nspname || '.' || d.relname in ({loc8}) +where ns.nspname || '.' || d.relname in ({loc8}) and a.indisprimary = 'f' "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); foreach (object[] row in ds) { var object_id = string.Concat(row[0]); @@ -274,7 +274,7 @@ where ns.nspname || '.' || d.relname in ({loc8}) var is_unique = string.Concat(row[3]) == "1"; var is_primary_key = string.Concat(row[4]) == "1"; var is_clustered = string.Concat(row[5]) == "1"; - var is_desc = int.Parse(string.Concat(row[6])); + var is_desc = string.Concat(row[6]) == "1"; var inkey = string.Concat(row[7]).Split(' '); var attnum = int.Parse(string.Concat(row[8])); attnum = int.Parse(inkey[attnum - 1]); @@ -290,20 +290,20 @@ where ns.nspname || '.' || d.relname in ({loc8}) var loc9 = loc3[object_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; + Dictionary loc10 = null; + DbIndexInfo loc11 = null; if (!indexColumns.TryGetValue(object_id, out loc10)) - indexColumns.Add(object_id, loc10 = new Dictionary>()); + indexColumns.Add(object_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); if (is_unique && !is_primary_key) { if (!uniqueColumns.TryGetValue(object_id, out loc10)) - uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + uniqueColumns.Add(object_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); } } foreach (var object_id in indexColumns.Keys) @@ -315,7 +315,7 @@ where ns.nspname || '.' || d.relname in ({loc8}) { foreach (var column in uniqueColumns[object_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); loc2[object_id].UniquesDict.Add(column.Key, column.Value); } } @@ -382,14 +382,14 @@ where ns.nspname || '.' || b.relname in ({loc8}) } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - { - foreach (var loc5 in loc4.UniquesDict.First().Value) - { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); loc4.Columns.Sort((c1, c2) => { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 82a9d7bc..710d60e0 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -156,8 +156,9 @@ ELSE } if (tboldname == null) { - //创建新表 - sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(" ( "); + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}"); + sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(createTableName).Append(" ( "); var pkidx = 0; foreach (var tbcol in tb.ColumnsByPosition) { @@ -177,13 +178,21 @@ ELSE } sb.Append(","); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } //备注 foreach (var tbcol in tb.ColumnsByPosition) { @@ -275,30 +284,39 @@ use " + database, tboldname ?? tbname); use [{0}]; select c.name -,d.name +,b.name +,case when a.is_descending_key = 1 then 1 else 0 end +,case when b.is_unique = 1 then 1 else 0 end from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id -left join sys.key_constraints d on d.parent_object_id = b.object_id and d.unique_index_id = b.index_id -where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_unique = 1; +where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_primary_key = 0; use " + database, tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); } } } if (istmpatler == false) { - sb.Append(sbalter).Append("\r\nuse " + database); + if (sbalter.Length > 0) + sb.Append(sbalter).Append("\r\nuse " + database); continue; } //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 @@ -337,12 +355,6 @@ use " + database, tboldname ?? tbname); sb.Append(","); idents = idents || tbcol.Attribute.IsIdentity == true; } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); //备注 foreach (var tbcol in tb.ColumnsByPosition) @@ -377,6 +389,20 @@ use " + database, tboldname ?? tbname); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" OFF;\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); sb.Append("EXECUTE sp_rename N'").Append(tmptablename).Append("', N'").Append(tbname[2]).Append("', 'OBJECT';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } sb.Append("COMMIT;\r\n"); } return sb.Length == 0 ? null : sb.ToString(); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index 337a424d..e2135a4b 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -267,24 +267,23 @@ use [{db}]; select a.object_id 'Object_id' ,c.name 'Column' -,d.name 'Index_id' +,b.name 'Index_id' ,b.is_unique 'IsUnique' ,b.is_primary_key 'IsPrimaryKey' ,cast(case when b.type_desc = 'CLUSTERED' then 1 else 0 end as bit) 'IsClustered' -,case when a.is_descending_key = 1 then 2 when a.is_descending_key = 0 then 1 else 0 end 'IsDesc' +,case when a.is_descending_key = 1 then 1 else 0 end 'IsDesc' from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id -left join sys.key_constraints d on d.parent_object_id = b.object_id and d.unique_index_id = b.index_id -where a.object_id in ({loc8}) +where a.object_id in ({loc8}) and b.is_primary_key = 0 ; use [{olddatabase}]; "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); foreach (object[] row in ds) { int object_id = int.Parse(string.Concat(row[0])); @@ -293,26 +292,26 @@ use [{olddatabase}]; bool is_unique = bool.Parse(string.Concat(row[3])); bool is_primary_key = bool.Parse(string.Concat(row[4])); bool is_clustered = bool.Parse(string.Concat(row[5])); - int is_desc = int.Parse(string.Concat(row[6])); + bool is_desc = string.Concat(row[6]) == "1"; if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; DbColumnInfo loc9 = loc3[object_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; + Dictionary loc10 = null; + DbIndexInfo loc11 = null; if (!indexColumns.TryGetValue(object_id, out loc10)) - indexColumns.Add(object_id, loc10 = new Dictionary>()); + indexColumns.Add(object_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); if (is_unique && !is_primary_key) { if (!uniqueColumns.TryGetValue(object_id, out loc10)) - uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + uniqueColumns.Add(object_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); } } foreach (var object_id in indexColumns.Keys) @@ -324,7 +323,7 @@ use [{olddatabase}]; { foreach (var column in uniqueColumns[object_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); loc2[object_id].UniquesDict.Add(column.Key, column.Value); } } @@ -402,14 +401,14 @@ use [{olddatabase}]; } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - { - foreach (var loc5 in loc4.UniquesDict.First().Value) - { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); loc4.Columns.Sort((c1, c2) => { diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 51901c67..863b1cee 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -109,7 +109,8 @@ namespace FreeSql.Oracle if (tboldname == null) { //创建表 - sb.Append("execute immediate 'CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("execute immediate 'CREATE TABLE ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); @@ -122,14 +123,22 @@ namespace FreeSql.Oracle foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } //备注 foreach (var tbcol in tb.ColumnsByPosition) { @@ -223,29 +232,38 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } + + CreateOracleFunction(_orm); var dsuksql = _commonUtils.FormatSql(@" select -c.column_name, -c.constraint_name -from -all_constraints a, -all_cons_columns c -where -a.constraint_name = c.constraint_name -and a.owner = c.owner +nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), +a.index_name, +case when c.descend = 'DESC' then 1 else 0 end, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.constraint_type in ('U') -and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) +and a.owner in ({0}) and a.table_name in ({1}) +and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P')", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]).Trim('"'), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }).ToArray(); + foreach (var uk in tb.Indexes) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("';\r\n"); - sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append("';\r\n"); + sbalter.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n"); } } @@ -276,12 +294,6 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE ("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); //备注 @@ -316,6 +328,20 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n"); sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } } Dictionary dicDeclare = new Dictionary(); Action dropSequence = seqname => @@ -408,5 +434,26 @@ and a.owner in ({0}) and a.table_name in ({1})", tboldname ?? tbname); sqlType += $"({data_length})"; return sqlType; } + internal static void CreateOracleFunction(IFreeSql fsql) + { + fsql.Ado.ExecuteNonQuery(CommandType.Text, @" +CREATE OR REPLACE FUNCTION freesql_long_2_varchar ( + p_index_name IN user_ind_expressions.index_name%TYPE, + p_table_name IN user_ind_expressions.table_name%TYPE, + p_COLUMN_POSITION IN user_ind_expressions.table_name%TYPE) + RETURN VARCHAR2 +AS + l_COLUMN_EXPRESSION LONG; +BEGIN + SELECT COLUMN_EXPRESSION + INTO l_COLUMN_EXPRESSION + FROM user_ind_expressions + WHERE index_name = p_index_name + AND table_name = p_table_name + AND COLUMN_POSITION = p_COLUMN_POSITION; + + RETURN SUBSTR (l_COLUMN_EXPRESSION, 1, 4000); +END;"); + } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index a1ece3c1..e1bf1998 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -287,61 +287,59 @@ where a.owner in ({1}) and a.table_name in ({0}) loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); } + OracleCodeFirst.CreateOracleFunction(_orm); sql = string.Format(@" select -a.owner || '.' || a.table_name, -c.column_name, -c.constraint_name, -case when a.constraint_type = 'U' then 1 else 0 end, -case when a.constraint_type = 'P' then 1 else 0 end, +a.table_owner || '.' || a.table_name, +nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), +c.index_name, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end, 0, -0 -from -all_constraints a, -all_cons_columns c -where -a.constraint_name = c.constraint_name -and a.owner = c.owner +0, +case when c.descend = 'DESC' then 1 else 0 end, +c.column_position +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.constraint_type in ('P', 'U') -and a.owner in ({1}) and a.table_name in ({0}) +and a.table_owner in ({1}) and a.table_name in ({0}) +and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); foreach (var row in ds) { string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); + string column = string.Concat(row[1]).Trim('"'); string index_id = string.Concat(row[2]); bool is_unique = string.Concat(row[3]) == "1"; bool is_primary_key = string.Concat(row[4]) == "1"; bool is_clustered = string.Concat(row[5]) == "1"; - int is_desc = int.Parse(string.Concat(row[6])); + bool is_desc = string.Concat(row[6]) == "1"; if (database.Length == 1) - { table_id = table_id.Substring(table_id.IndexOf('.') + 1); - } if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; var loc9 = loc3[table_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; + Dictionary loc10 = null; + DbIndexInfo loc11 = null; if (!indexColumns.TryGetValue(table_id, out loc10)) - indexColumns.Add(table_id, loc10 = new Dictionary>()); + indexColumns.Add(table_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); if (is_unique && !is_primary_key) { if (!uniqueColumns.TryGetValue(table_id, out loc10)) - uniqueColumns.Add(table_id, loc10 = new Dictionary>()); + uniqueColumns.Add(table_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); } } foreach (string table_id in indexColumns.Keys) @@ -353,7 +351,7 @@ and a.owner in ({1}) and a.table_name in ({0}) { foreach (var column in uniqueColumns[table_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); loc2[table_id].UniquesDict.Add(column.Key, column.Value); } } @@ -441,14 +439,14 @@ and a.owner in ({1}) and a.table_name in ({0}) } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - { - foreach (var loc5 in loc4.UniquesDict.First().Value) - { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); loc4.Columns.Sort((c1, c2) => { diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 5ed26c61..1fd94504 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -150,7 +150,8 @@ namespace FreeSql.PostgreSQL if (tboldname == null) { //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); @@ -162,14 +163,22 @@ namespace FreeSql.PostgreSQL foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } //备注 foreach (var tbcol in tb.ColumnsByPosition) { @@ -275,23 +284,32 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); var dsuksql = _commonUtils.FormatSql(@" select c.attname, -b.relname +b.relname, +case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +case when indisunique = 't' then 1 else 0 end IsUnique from pg_index a inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where ns.nspname in ({0}) and d.relname in ({1}) and a.indisunique = 't'", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) +where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); } } @@ -325,12 +343,6 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); //备注 @@ -362,6 +374,20 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } } foreach (var seqcol in seqcols) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 517b8370..6c448916 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -362,7 +362,7 @@ b.relname as index_id, case when a.indisunique then 1 else 0 end IsUnique, case when a.indisprimary then 1 else 0 end IsPrimary, case when a.indisclustered then 0 else 1 end IsClustered, -0 IsDesc, +case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, a.indkey::text, c.attnum from pg_index a @@ -370,13 +370,13 @@ inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where ns.nspname || '.' || d.relname in ({loc8}) +where ns.nspname || '.' || d.relname in ({loc8}) and a.indisprimary = 'f' "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); foreach (object[] row in ds) { var object_id = string.Concat(row[0]); @@ -385,7 +385,7 @@ where ns.nspname || '.' || d.relname in ({loc8}) var is_unique = string.Concat(row[3]) == "1"; var is_primary_key = string.Concat(row[4]) == "1"; var is_clustered = string.Concat(row[5]) == "1"; - var is_desc = int.Parse(string.Concat(row[6])); + var is_desc = string.Concat(row[6]) == "1"; var inkey = string.Concat(row[7]).Split(' '); var attnum = int.Parse(string.Concat(row[8])); attnum = int.Parse(inkey[attnum - 1]); @@ -401,20 +401,20 @@ where ns.nspname || '.' || d.relname in ({loc8}) var loc9 = loc3[object_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; + Dictionary loc10 = null; + DbIndexInfo loc11 = null; if (!indexColumns.TryGetValue(object_id, out loc10)) - indexColumns.Add(object_id, loc10 = new Dictionary>()); + indexColumns.Add(object_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); if (is_unique && !is_primary_key) { if (!uniqueColumns.TryGetValue(object_id, out loc10)) - uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + uniqueColumns.Add(object_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); } } foreach (var object_id in indexColumns.Keys) @@ -426,7 +426,7 @@ where ns.nspname || '.' || d.relname in ({loc8}) { foreach (var column in uniqueColumns[object_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); loc2[object_id].UniquesDict.Add(column.Key, column.Value); } } @@ -493,14 +493,14 @@ where ns.nspname || '.' || b.relname in ({loc8}) } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - { - foreach (var loc5 in loc4.UniquesDict.First().Value) - { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); loc4.Columns.Sort((c1, c2) => { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index e0b0d18d..98954af7 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -159,8 +159,9 @@ ELSE } if (tboldname == null) { - //创建新表 - sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(" ( "); + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}"); + sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(createTableName).Append(" ( "); var pkidx = 0; foreach (var tbcol in tb.ColumnsByPosition) { @@ -180,13 +181,21 @@ ELSE } sb.Append(","); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } //备注 foreach (var tbcol in tb.ColumnsByPosition) { @@ -278,30 +287,39 @@ use " + database, tboldname ?? tbname); use [{0}]; select c.name -,d.name +,b.name +,case when a.is_descending_key = 1 then 1 else 0 end +,case when b.is_unique = 1 then 1 else 0 end from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id -left join sys.key_constraints d on d.parent_object_id = b.object_id and d.unique_index_id = b.index_id -where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_unique = 1; +where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_primary_key = 0; use " + database, tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) }); - foreach (var uk in tb.Uniques) + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); } } } if (istmpatler == false) { - sb.Append(sbalter).Append("\r\nuse " + database); + if (sbalter.Length > 0) + sb.Append(sbalter).Append("\r\nuse " + database); continue; } //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 @@ -340,12 +358,6 @@ use " + database, tboldname ?? tbname); sb.Append(","); idents = idents || tbcol.Attribute.IsIdentity == true; } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); //备注 foreach (var tbcol in tb.ColumnsByPosition) @@ -380,6 +392,20 @@ use " + database, tboldname ?? tbname); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" OFF;\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); sb.Append("EXECUTE sp_rename N'").Append(tmptablename).Append("', N'").Append(tbname[2]).Append("', 'OBJECT';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } sb.Append("COMMIT;\r\n"); } return sb.Length == 0 ? null : sb.ToString(); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 35b91bee..a91ca3c9 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -270,24 +270,23 @@ use [{db}]; select a.object_id 'Object_id' ,c.name 'Column' -,d.name 'Index_id' +,b.name 'Index_id' ,b.is_unique 'IsUnique' ,b.is_primary_key 'IsPrimaryKey' ,cast(case when b.type_desc = 'CLUSTERED' then 1 else 0 end as bit) 'IsClustered' -,case when a.is_descending_key = 1 then 2 when a.is_descending_key = 0 then 1 else 0 end 'IsDesc' +,case when a.is_descending_key = 1 then 1 else 0 end 'IsDesc' from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id -left join sys.key_constraints d on d.parent_object_id = b.object_id and d.unique_index_id = b.index_id -where a.object_id in ({loc8}) +where a.object_id in ({loc8}) and b.is_primary_key = 0 ; use [{olddatabase}]; "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); foreach (object[] row in ds) { int object_id = int.Parse(string.Concat(row[0])); @@ -296,26 +295,26 @@ use [{olddatabase}]; bool is_unique = bool.Parse(string.Concat(row[3])); bool is_primary_key = bool.Parse(string.Concat(row[4])); bool is_clustered = bool.Parse(string.Concat(row[5])); - int is_desc = int.Parse(string.Concat(row[6])); + bool is_desc = string.Concat(row[6]) == "1"; if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; DbColumnInfo loc9 = loc3[object_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; - List loc11 = null; + Dictionary loc10 = null; + DbIndexInfo loc11 = null; if (!indexColumns.TryGetValue(object_id, out loc10)) - indexColumns.Add(object_id, loc10 = new Dictionary>()); + indexColumns.Add(object_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); if (is_unique && !is_primary_key) { if (!uniqueColumns.TryGetValue(object_id, out loc10)) - uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + uniqueColumns.Add(object_id, loc10 = new Dictionary()); if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new List()); - loc11.Add(loc9); + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); } } foreach (var object_id in indexColumns.Keys) @@ -327,7 +326,7 @@ use [{olddatabase}]; { foreach (var column in uniqueColumns[object_id]) { - column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); loc2[object_id].UniquesDict.Add(column.Key, column.Value); } } @@ -405,14 +404,14 @@ use [{olddatabase}]; } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - { - foreach (var loc5 in loc4.UniquesDict.First().Value) - { - loc5.IsPrimary = true; - loc4.Primarys.Add(loc5); - } - } + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); loc4.Columns.Sort((c1, c2) => { diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 7ab66263..9d804e0c 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -99,7 +99,8 @@ namespace FreeSql.Sqlite if (tboldname == null) { //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); @@ -117,14 +118,22 @@ namespace FreeSql.Sqlite foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) \r\n;\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tbname[1]).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } continue; } //如果新表,旧表在一个模式下,直接修改表名 @@ -183,25 +192,26 @@ namespace FreeSql.Sqlite //添加列 istmpatler = true; } - var dsukMatches = _regexUK.Matches(dsql); var dsuk = new List(); - foreach (Match dsukm in dsukMatches) + var dbIndexes = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.INDEX_LIST({_commonUtils.QuoteSqlName(tbtmp[1])})"); + foreach (var dbIndex in dbIndexes) { - var dbsukmg2 = dsukm.Groups[2].Value.Split(','); - if (dbsukmg2.Any() == false) continue; - foreach (var dbfield in dbsukmg2) + if (string.Concat(dbIndex[3]) == "pk") continue; + var dbIndexesColumns = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.INDEX_INFO({dbIndex[1]})"); + var dbIndexesSql = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $"SELECT sql FROM sqlite_master WHERE name = '{dbIndex[1]}'")); + foreach (var dbcolumn in dbIndexesColumns) { - dsuk.Add(new[] { Regex.Match(dbfield, @"""([^""]+)""").Groups[1].Value, dsukm.Groups[1].Value }); + var dbcolumnName = string.Concat(dbcolumn[2]); + var isDesc = dbIndexesSql.IndexOf($@"{dbcolumnName}"" DESC", StringComparison.CurrentCultureIgnoreCase) == -1 ? "0" : "1"; + dsuk.Add(new[] { dbcolumnName, string.Concat(dbIndex[1]), isDesc, string.Concat(dbIndex[2]) }); ; } } - foreach (var uk in tb.Uniques) + foreach (var uk in tb.Indexes) { - if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) - { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) istmpatler = true; - } } } if (istmpatler == false) @@ -212,6 +222,7 @@ namespace FreeSql.Sqlite //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tablenameOnlyTb = tboldname == null ? _commonUtils.QuoteSqlName(tbname[1]) : _commonUtils.QuoteSqlName(tboldname[1]); var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}._FreeSqlTmp_{tbname[1]}"); //创建临时表 //创建表 @@ -234,12 +245,6 @@ namespace FreeSql.Sqlite foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - foreach (var uk in tb.Uniques) - { - sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE("); - foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } sb.Remove(sb.Length - 1, 1); sb.Append("\r\n) \r\n;\r\n"); sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); @@ -268,9 +273,22 @@ namespace FreeSql.Sqlite sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablenameOnlyTb).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } } return sb.Length == 0 ? null : sb.ToString(); } - static Regex _regexUK = new Regex(@"CONSTRAINT\s*""([^""]+)""\s*UNIQUE\s*\(([^\)]+)\)", RegexOptions.IgnoreCase | RegexOptions.Compiled); } } \ No newline at end of file From 2b72c849d928f0fdb87d5f241c5a69989947bda2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 6 Oct 2019 12:32:32 +0800 Subject: [PATCH 0177/1029] =?UTF-8?q?v0.10.7,=20-=20=E8=B0=83=E6=95=B4=20?= =?UTF-8?q?=20Insert(IEnumerable=20source)=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=94=B9=E6=88=90=E4=BA=86=20List=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../SqlServer/Curd/SqlServerDeleteTest.cs | 4 +- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 30 +++++++ .../FreeSql.Tests/Other/AdjustPriceOrder.cs | 86 +++++++++++++++++++ .../SqlServer/Curd/SqlServerDeleteTest.cs | 2 +- .../SqlServer/Curd/SqlServerInsertTest.cs | 36 ++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 6 ++ FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 2 +- FreeSql/Interface/IFreeSql.cs | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySql/MySqlProvider.cs | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../Default/OdbcProvider.cs | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../MySql/OdbcMySqlProvider.cs | 2 +- .../Oracle/OdbcOracleProvider.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLProvider.cs | 2 +- .../SqlServer/OdbcSqlServerProvider.cs | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.Oracle/OracleProvider.cs | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../PostgreSQLProvider.cs | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../SqlServerProvider.cs | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 2 +- 31 files changed, 186 insertions(+), 28 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/AdjustPriceOrder.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 72c44052..b7be3df6 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.6 + 0.10.7 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 5878ad7d..e7397020 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 2f886e7a..14c2aa4d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8acf14fc..4199d219 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8c4fe26a..e4d091cc 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs index 28f22b21..1105f760 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs @@ -77,8 +77,8 @@ namespace FreeSql.Tests.Odbc.SqlServer var item = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); - var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }); - var itemsInserted = g.sqlserver.Insert(items).ExecuteInserted(); + var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }).ToArray(); + var itemsInserted = g.sqlserver.Insert(items).ExecuteInserted(); Assert.Equal(items.First().Title, itemsInserted[0].Title); Assert.Equal(itemsInserted[0].Id, delete.Where(a => a.Id == itemsInserted[0].Id).ExecuteDeleted()[0].Id); diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 6f593095..b44b569a 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -199,6 +199,36 @@ 创建日期 + + + 调价单 + + + + + 调价单产品明细 + + + + + 原标签价 + + + + + 新的市场成本价 + + + + + 新的标签价倍率 + + + + + 新标签价 + + 实体类基类 diff --git a/FreeSql.Tests/FreeSql.Tests/Other/AdjustPriceOrder.cs b/FreeSql.Tests/FreeSql.Tests/Other/AdjustPriceOrder.cs new file mode 100644 index 00000000..b4b30512 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/AdjustPriceOrder.cs @@ -0,0 +1,86 @@ +using FreeSql.DataAnnotations; +using System; + +namespace SaleIDO.Entity.Storeage +{ + public class BaseEntity + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + } + + /// + /// 调价单 + /// + [Table(Name = "jxc_AdjustPriceOrder")] + public class AdjustPriceOrder : BaseEntity + { + public AdjustPriceOrder() + { + OrderStatus = 0; + } + + public string OrderSn { get; set; } + + public DateTime AdjustTime { get; set; } + + public string Handler { get; set; } + + public string StoreCode { get; set; } + + public int GoodsNum { get; set; } + + public string Remark { get; set; } + + public DateTime? CheckTime { get; set; } + + public string CheckMan { get; set; } + + public string CheckRemark { get; set; } + + public int OrderStatus { get; set; } + + } + + /// + /// 调价单产品明细 + /// + [Table(Name = "jxc_AdjustPriceDetail")] + public class AdjustPriceDetail : BaseEntity + { + public string OrderSn { get; set; } + + public string Barcode { get; set; } + + public string GoodsName { get; set; } + + public decimal GoodsWeight { get; set; } + + public decimal CostPrice { get; set; } + + public decimal MarketCostPrice { get; set; } + + /// + /// 原标签价 + /// + public decimal OldLabelPrice { get; set; } + + /// + /// 新的市场成本价 + /// + public decimal NewMarketCostPrice { get; set; } + + /// + /// 新的标签价倍率 + /// + public decimal NewLabelPriceRate { get; set; } + + /// + /// 新标签价 + /// + public decimal NewLabelPrice { get; set; } + + public string Remark { get; set; } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs index 5a5bbcb8..196ba9b0 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs @@ -85,7 +85,7 @@ namespace FreeSql.Tests.SqlServer var item = _sqlserverFixture.SqlServer.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); - var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }); + var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }).ToArray(); var itemsInserted = _sqlserverFixture.SqlServer.Insert(items).ExecuteInserted(); Assert.Equal(items.First().Title, itemsInserted[0].Title); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index c8e485c5..00a3ba88 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using FreeSql.Tests.DataContext.SqlServer; +using SaleIDO.Entity.Storeage; using System; using System.Collections.Generic; using System.Linq; @@ -101,6 +102,41 @@ namespace FreeSql.Tests.SqlServer //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); //Assert.Equal(9989, _sqlserverFixture.SqlServer.Insert(items).ExecuteAffrows()); + + //var bttype = new TestBetchInsertType { title = "testbttitle1" }; + //bttype.id = (int)_sqlserverFixture.SqlServer.Insert(bttype).ExecuteIdentity(); + //Assert.True(bttype.id > 0); + //var bttopic = Enumerable.Range(0, 10000).Select(a => new TestBetchInsertTopic { TypeId = bttype.id, Text = $"testtopic{a}" }).ToArray(); + //Assert.Equal(bttopic.Length, _sqlserverFixture.SqlServer.Insert(bttopic).ExecuteAffrows()); + + //_sqlserverFixture.SqlServer.Transaction(() => + //{ + // bttype = new TestBetchInsertType { title = "transaction_testbttitle2" }; + // bttype.id = (int)_sqlserverFixture.SqlServer.Insert(bttype).ExecuteIdentity(); + // Assert.True(bttype.id > 0); + // bttopic = Enumerable.Range(0, 10000).Select(a => new TestBetchInsertTopic { TypeId = bttype.id, Text = $"transaction_testtopic{a}" }).ToArray(); + // Assert.Equal(bttopic.Length, _sqlserverFixture.SqlServer.Insert(bttopic).ExecuteAffrows()); + //}); + + _sqlserverFixture.SqlServer.Transaction(() => + { + var order = new AdjustPriceOrder { }; + order.Id = (int)_sqlserverFixture.SqlServer.Insert(order).NoneParameter().ExecuteIdentity(); + Assert.True(order.Id > 0); + var detail = Enumerable.Range(0, 10000).Select(a => new AdjustPriceDetail { Remark = $"transaction_testdetail{a}" }).ToArray(); + Assert.Equal(detail.Length, _sqlserverFixture.SqlServer.Insert(detail).NoneParameter().ExecuteAffrows()); + }); + } + class TestBetchInsertType { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + } + class TestBetchInsertTopic + { + public Guid id { get; set; } + public int TypeId { get; set; } + public string Text { get; set; } } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index e4aab4fb..0d2dfc44 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -407,6 +407,12 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var testlistinsert = new List(); + g.sqlite.Insert(testlistinsert).ExecuteAffrows(); + + + + var gkjdjd = g.sqlite.Select().Where(a => a.Post.AsSelect().Count() > 0).ToList(); var testrunsql1 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2b2ce63a..4eae4899 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 7a86ceb0..a4a50a9c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2678,7 +2678,7 @@ - + 插入数据,传入实体集合 diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index bf5c9260..7910aa6a 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -32,7 +32,7 @@ public interface IFreeSql : IDisposable /// /// /// - IInsert Insert(IEnumerable source) where T1 : class; + IInsert Insert(List source) where T1 : class; /// /// 修改数据 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0039301f..65dbbe9c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index c62decfe..cfaa492b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -42,7 +42,7 @@ namespace FreeSql.MySql public IInsert Insert() where T1 : class => new MySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ad2cbaea..e20ab756 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index de1daa60..8dadf885 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -17,7 +17,7 @@ namespace FreeSql.Odbc.Default public IInsert Insert() where T1 : class => new OdbcInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 535120e5..773fb6b3 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index bfd631a4..f68bf0c8 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -20,7 +20,7 @@ namespace FreeSql.Odbc.MySql public IInsert Insert() where T1 : class => new OdbcMySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index 38647e8b..33004ad1 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -15,7 +15,7 @@ namespace FreeSql.Odbc.Oracle public IInsert Insert() where T1 : class => new OdbcOracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index 42dc2c5c..fb48307d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -18,7 +18,7 @@ namespace FreeSql.Odbc.PostgreSQL public IInsert Insert() where T1 : class => new OdbcPostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index b6138ad9..93e325ad 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -14,7 +14,7 @@ namespace FreeSql.Odbc.SqlServer public IInsert Insert() where T1 : class => new OdbcSqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b684d13d..bc6c9deb 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index 28ad4744..be867e3e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -16,7 +16,7 @@ namespace FreeSql.Oracle public IInsert Insert() where T1 : class => new OracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2d690ac5..88921584 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index 21627b10..83b31178 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -69,7 +69,7 @@ namespace FreeSql.PostgreSQL public IInsert Insert() where T1 : class => new PostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4779fdbf..34677619 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index f0e2fe85..33017c8e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -15,7 +15,7 @@ namespace FreeSql.SqlServer public IInsert Insert() where T1 : class => new SqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index da1002a2..cd24d147 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.6 + 0.10.7 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 7ecf5db6..6cb3524e 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -16,7 +16,7 @@ namespace FreeSql.Sqlite public IInsert Insert() where T1 : class => new SqliteInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); From 53d4332bc5dd1741c2cb479929a0c0b06f3607f5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 7 Oct 2019 21:14:18 +0800 Subject: [PATCH 0178/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20List\?= =?UTF-8?q?=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=20IncludeMany=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BB=8E=E5=B7=B2=E7=9F=A5=E7=9A=84=E5=86=85?= =?UTF-8?q?=E5=AD=98=20List=20=E6=95=B0=E6=8D=AE=EF=BC=8C=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E5=92=8C=20ISelect.IncludeMany=20=E7=9B=B8=E5=90=8C?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E7=9A=84=E8=B4=AA=E5=A9=AA=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sqlite/Curd/SqliteSelectTest.cs | 2 ++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 23 +++++++++++++++++++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 3 ++- .../SelectProvider/Select1Provider.cs | 7 ++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 2ebc9a90..c95152cd 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1155,6 +1155,8 @@ namespace FreeSql.Tests.Sqlite g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + new List(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + var songs1 = g.sqlite.Select() .IncludeMany(a => a.Tags) .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 4611cd89..071a0904 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; +using System.Linq.Expressions; using System.Reflection; public static partial class FreeSqlGlobalExtensions @@ -167,4 +168,26 @@ public static partial class FreeSqlGlobalExtensions public static ISelect Select(this IFreeSql freesql) 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 => freesql.Select().From((s, b, c, d, e, f, g, h, i, j) => s); #endregion + + #region IncludeMany + /// + /// 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 + /// 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + /// 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + /// + /// + /// + /// + /// + /// 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 + /// 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + /// + public static List IncludeMany(this List list, IFreeSql orm, Expression>> navigateSelector, Action> then = null) where T1 : class where TNavigate : class + { + if (list == null || list.Any() == false) return list; + var select = orm.Select().IncludeMany(navigateSelector, then) as FreeSql.Internal.CommonProvider.Select1Provider; + select.SetList(list); + return list; + } + #endregion } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 0ec2e749..8fc5e393 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -348,7 +348,8 @@ namespace FreeSql /// ISelect Include(Expression> navigateSelector) where TNavigate : class; /// - /// 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + /// 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + /// 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany /// /// /// 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 76f84598..2a17fde4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -956,5 +956,12 @@ namespace FreeSql.Internal.CommonProvider }); return this; } + + internal void SetList(IEnumerable list) + { + foreach (var include in _includeToList) include?.Invoke(list); + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(list)); + _trackToList?.Invoke(list); + } } } \ No newline at end of file From fa481700414312e300ad61e5201ddb659bf5216c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 8 Oct 2019 00:43:03 +0800 Subject: [PATCH 0179/1029] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=B1=BB=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=A7=BB=E5=8A=A8=EF=BC=88=E4=B8=8D=E5=BD=B1=E5=93=8D?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/DataAnnotations/IndexAttribute.cs | 36 +++++++++++++++++ FreeSql/DataAnnotations/TableAttribute.cs | 30 --------------- FreeSql/FreeSql.xml | 47 +++++++++++++++-------- 3 files changed, 67 insertions(+), 46 deletions(-) create mode 100644 FreeSql/DataAnnotations/IndexAttribute.cs diff --git a/FreeSql/DataAnnotations/IndexAttribute.cs b/FreeSql/DataAnnotations/IndexAttribute.cs new file mode 100644 index 00000000..9115dfd0 --- /dev/null +++ b/FreeSql/DataAnnotations/IndexAttribute.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.DataAnnotations +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + public class IndexAttribute : Attribute + { + public IndexAttribute(string name, string fields) + { + this.Name = name; + this.Fields = fields; + } + public IndexAttribute(string name, string fields, bool isUnique) + { + this.Name = name; + this.Fields = fields; + this.IsUnique = isUnique; + } + /// + /// 索引名 + /// + public string Name { get; set; } + /// + /// 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + /// + public string Fields { get; set; } + + internal bool? _IsUnique; + /// + /// 是否唯一 + /// + public bool IsUnique { get => _IsUnique ?? false; set => _IsUnique = value; } + } +} diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index 18fb2e54..7ec69bb0 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -31,34 +31,4 @@ namespace FreeSql.DataAnnotations internal ConcurrentDictionary _navigates { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); internal ConcurrentDictionary _indexs { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public class IndexAttribute : Attribute - { - public IndexAttribute(string name, string fields) - { - this.Name = name; - this.Fields = fields; - } - public IndexAttribute(string name, string fields, bool isUnique) - { - this.Name = name; - this.Fields = fields; - this.IsUnique = isUnique; - } - /// - /// 索引名 - /// - public string Name { get; set; } - /// - /// 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - /// - public string Fields { get; set; } - - internal bool? _IsUnique; - /// - /// 是否唯一 - /// - public bool IsUnique { get => _IsUnique ?? false; set => _IsUnique = value; } - } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a4a50a9c..6ae63c12 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -152,6 +152,21 @@ + + + 索引名 + + + + + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + + 是否唯一 + + 手工绑定 OneToMany、ManyToOne 导航关系 @@ -187,21 +202,6 @@ 禁用 CodeFirst 同步结构迁移 - - - 索引名 - - - - - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - - - - - 是否唯一 - - 数据库表名 @@ -1458,7 +1458,8 @@ - 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 @@ -2608,6 +2609,20 @@ + + + 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 + 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + + + + 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + 使用 and 拼接两个 lambda 表达式 From cf0dfae545b8d7acdbf6120d93eefa8ed0d3f685 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 8 Oct 2019 15:43:34 +0800 Subject: [PATCH 0180/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20FreeSql.DbCo?= =?UTF-8?q?ntext/FreeSql.Repository=20=E5=BD=93=E4=B8=BB=E9=94=AE=E4=B8=BA?= =?UTF-8?q?=20Guid=3F=20=E5=8F=AF=E7=A9=BA=E7=B1=BB=E5=9E=8B=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=8F=91=E7=94=9F=E5=8F=82=E6=95=B0=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=9B#105=20#106=20>=20System.ArgumentException:=E2=80=9CEx?= =?UTF-8?q?pression=20of=20type=20'System.Guid'=20cannot=20be=20used=20for?= =?UTF-8?q?=20assignment=20to=20type=20'System.Nullable`1[System.Guid]'?= =?UTF-8?q?=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 46 ++++++++++++++++++++ FreeSql/Extensions/EntityUtilExtensions.cs | 50 ++++++++-------------- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 0d2dfc44..13ed35bc 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -403,10 +403,56 @@ namespace FreeSql.Tests [Navigate("AuthorId")] public List Post { get; set; } } + public class TestGuidId + { + public Guid? Id { get; set; } + public string xxx { get; set; } + } [Fact] public void Test1() { + g.sqlite.Insert(new TestGuidId { xxx = "111" }).ExecuteAffrows(); + g.sqlite.Insert(new TestGuidId { xxx = "222" }).ExecuteAffrows(); + var gkkdk1 = g.sqlite.Select().Where(a => true).ToList(); + using (var testguididdb = g.sqlite.CreateDbContext()) + { + var gkkdk11 = testguididdb.Set().Select.Where(a => true).ToList(); + } + + g.oracle.Insert(new TestGuidId { xxx = "111" }).ExecuteAffrows(); + g.oracle.Insert(new TestGuidId { xxx = "222" }).ExecuteAffrows(); + var gkkdk2 = g.oracle.Select().Where(a => true).ToList(); + using (var testguididdb = g.sqlite.CreateDbContext()) + { + var gkkdk22 = testguididdb.Set().Select.Where(a => true).ToList(); + } + + g.pgsql.Insert(new TestGuidId { xxx = "111" }).ExecuteAffrows(); + g.pgsql.Insert(new TestGuidId { xxx = "222" }).ExecuteAffrows(); + var gkkdk3 = g.pgsql.Select().Where(a => true).ToList(); + using (var testguididdb = g.sqlite.CreateDbContext()) + { + var gkkdk22 = testguididdb.Set().Select.Where(a => true).ToList(); + } + + g.mysql.Insert(new TestGuidId { xxx = "111" }).ExecuteAffrows(); + g.mysql.Insert(new TestGuidId { xxx = "222" }).ExecuteAffrows(); + var gkkdk4 = g.mysql.Select().Where(a => true).ToList(); + using (var testguididdb = g.sqlite.CreateDbContext()) + { + var gkkdk22 = testguididdb.Set().Select.Where(a => true).ToList(); + } + + g.sqlserver.Insert(new TestGuidId { xxx = "111" }).ExecuteAffrows(); + g.sqlserver.Insert(new TestGuidId { xxx = "222" }).ExecuteAffrows(); + var gkkdk5 = g.sqlserver.Select().Where(a => true).ToList(); + using (var testguididdb = g.sqlite.CreateDbContext()) + { + var gkkdk22 = testguididdb.Set().Select.Where(a => true).ToList(); + } + + var testlistinsert = new List(); g.sqlite.Insert(testlistinsert).ExecuteAffrows(); diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 98ab49e7..7ec6cc31 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -53,41 +53,29 @@ namespace FreeSql.Extensions.EntityUtil Expression expthen = null; if (isguid) { - if (pks[a].Attribute.MapType == pks[a].CsType) - { - expthen = Expression.Block( - new Expression[]{ - Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Call(MethodFreeUtilNewMongodbId)), - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ); - } - else - { - expthen = Expression.Block( - new Expression[]{ - Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pks[a].CsType, Expression.Call(MethodFreeUtilNewMongodbId))), - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ); - } + Expression newguid = Expression.Call(MethodFreeUtilNewMongodbId); + if (pks[a].Attribute.MapType != pks[a].CsType) newguid = FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pks[a].CsType, newguid); + if (pks[a].CsType == typeof(Guid?)) newguid = Expression.Convert(newguid, typeof(Guid?)); + expthen = Expression.Block( + new Expression[]{ + Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), newguid), + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) + ) + }.Where(c => c != null).ToArray() + ); } else if (pks.Length > 1 && pks[a].Attribute.IsIdentity) { expthen = Expression.Block( - new Expression[]{ - a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, - Expression.Call(var2Sb, MethodStringBuilderAppend, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) - ) - }.Where(c => c != null).ToArray() - ); + new Expression[]{ + a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null, + Expression.Call(var2Sb, MethodStringBuilderAppend, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object)) + ) + }.Where(c => c != null).ToArray() + ); } else { From dde6562ef8a2e86778a29b474aa4000559bdcf1f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 8 Oct 2019 15:45:32 +0800 Subject: [PATCH 0181/1029] v0.10.8 #105 #106 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b7be3df6..154efd4e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.7 + 0.10.8 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e7397020..eef8a26b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 14c2aa4d..4fd7839a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4199d219..3310cad7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e4d091cc..cdb998a4 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4eae4899..013ca3f7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 65dbbe9c..a01eabb2 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index e20ab756..7e8d2cdc 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 773fb6b3..a9f48b3f 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index bc6c9deb..ba81e037 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 88921584..7b6327f3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 34677619..e821df69 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index cd24d147..ef2b950c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.7 + 0.10.8 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 47b8cd6d9a21731a42198899e64a6302638d744c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 8 Oct 2019 23:58:10 +0800 Subject: [PATCH 0182/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbFirst=20?= =?UTF-8?q?=E5=BD=93=E8=A1=A8=E6=95=B0=E9=87=8F=E8=BF=87=E5=A4=A7=E6=97=B6?= =?UTF-8?q?(=E5=A6=82=20oracle=20=E8=A1=A8=E6=95=B0=E9=87=8F=E5=A4=A7?= =?UTF-8?q?=E4=BA=8E=201000)=EF=BC=8C=E5=8F=AF=E8=83=BD=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.MySql/MySqlDbFirst.cs | 45 ++++++++++++--- .../MySql/OdbcMySqlDbFirst.cs | 45 ++++++++++++--- .../Oracle/OdbcOracleDbFirst.cs | 45 ++++++++++++--- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 45 ++++++++++++--- .../SqlServer/OdbcSqlServerDbFirst.cs | 56 +++++++++++++++---- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 45 ++++++++++++--- .../PostgreSQLDbFirst.cs | 45 ++++++++++++--- .../SqlServerDbFirst.cs | 56 +++++++++++++++---- 8 files changed, 306 insertions(+), 76 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 9df16ee1..04feb558 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.MySql @@ -170,8 +171,10 @@ where a.table_schema in ({0})", databaseIn); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); foreach (var row in ds) { var table_id = string.Concat(row[0]); @@ -190,16 +193,40 @@ where a.table_schema in ({0})", databaseIn); { case DbTableType.TABLE: case DbTableType.VIEW: - loc6.Add(table.Replace("'", "''")); + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } break; case DbTableType.StoreProcedure: - loc66.Add(table.Replace("'", "''")); + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } break; } } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + if (loc6.Count == 0) return loc1; - var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); sql = string.Format(@" select @@ -212,7 +239,7 @@ case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', a.column_comment 'comment' from information_schema.columns a -where a.table_schema in ({1}) and a.table_name in ({0}) +where a.table_schema in ({1}) and {0} ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -260,7 +287,7 @@ case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' from information_schema.statistics a -where a.table_schema in ({1}) and a.table_name in ({0}) and a.index_name <> 'PRIMARY' +where a.table_schema in ({1}) and {0} and a.index_name <> 'PRIMARY' ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -321,7 +348,7 @@ concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', 1 'IsForeignKey', a.referenced_column_name 'ref_column' from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(position_in_unique_constraint) +where a.constraint_schema in ({1}) and {0} and not isnull(position_in_unique_constraint) ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index 6e9d3621..afd2549b 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Odbc; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.Odbc.MySql @@ -140,8 +141,10 @@ where a.table_schema in ({0})", databaseIn); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); foreach (var row in ds) { var table_id = string.Concat(row[0]); @@ -160,16 +163,40 @@ where a.table_schema in ({0})", databaseIn); { case DbTableType.TABLE: case DbTableType.VIEW: - loc6.Add(table.Replace("'", "''")); + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } break; case DbTableType.StoreProcedure: - loc66.Add(table.Replace("'", "''")); + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } break; } } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + if (loc6.Count == 0) return loc1; - var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); sql = string.Format(@" select @@ -182,7 +209,7 @@ case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', a.column_comment 'comment' from information_schema.columns a -where a.table_schema in ({1}) and a.table_name in ({0}) +where a.table_schema in ({1}) and {0} ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -230,7 +257,7 @@ case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' from information_schema.statistics a -where a.table_schema in ({1}) and a.table_name in ({0}) and a.index_name <> 'PRIMARY' +where a.table_schema in ({1}) and {0} and a.index_name <> 'PRIMARY' ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -291,7 +318,7 @@ concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', 1 'IsForeignKey', a.referenced_column_name 'ref_column' from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(position_in_unique_constraint) +where a.constraint_schema in ({1}) and {0} and not isnull(position_in_unique_constraint) ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index 84ce0cd3..7d25d4ee 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Odbc; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.Odbc.Oracle @@ -191,8 +192,10 @@ where a.owner in ({0})", databaseIn); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); foreach (var row in ds) { var table_id = string.Concat(row[0]); @@ -211,16 +214,40 @@ where a.owner in ({0})", databaseIn); { case DbTableType.TABLE: case DbTableType.VIEW: - loc6.Add(table.Replace("'", "''")); + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 999) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } break; case DbTableType.StoreProcedure: - loc66.Add(table.Replace("'", "''")); + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 999) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } break; } } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + if (loc6.Count == 0) return loc1; - var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); sql = string.Format(@" select @@ -236,7 +263,7 @@ nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name| b.comments from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner in ({1}) and a.table_name in ({0}) +where a.owner in ({1}) and {0} ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -303,7 +330,7 @@ all_ind_columns c where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.table_owner in ({1}) and a.table_name in ({0}) +and a.table_owner in ({1}) and {0} and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -390,7 +417,7 @@ and a.owner = c.owner    and a.table_name = c.table_name    and b.owner = d.owner    and b.table_name = d.table_name -and a.owner in ({1}) and a.table_name in ({0}) +and a.owner in ({1}) and {0} ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 27adf73a..9c56304d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Odbc; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.Odbc.PostgreSQL @@ -147,8 +148,10 @@ and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geo var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); foreach (object[] row in ds) { var object_id = string.Concat(row[0]); @@ -162,16 +165,40 @@ and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geo { case DbTableType.VIEW: case DbTableType.TABLE: - loc6.Add(object_id); + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } break; case DbTableType.StoreProcedure: - loc66.Add(object_id); + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } break; } } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + if (loc6.Count == 0) return loc1; - string loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - string loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); sql = $@" select @@ -196,7 +223,7 @@ left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum inner join pg_namespace ns on ns.oid = c.relnamespace inner join pg_namespace ns2 on ns2.oid = t.typnamespace -where ns.nspname || '.' || c.relname in ({loc8})"; +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")}"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -259,7 +286,7 @@ inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where ns.nspname || '.' || d.relname in ({loc8}) and a.indisprimary = 'f' +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} and a.indisprimary = 'f' "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -335,7 +362,7 @@ inner join pg_class b on b.oid = a.conrelid inner join pg_class c on c.oid = a.confrelid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_namespace ns2 on ns2.oid = c.relnamespace -where ns.nspname || '.' || b.relname in ({loc8}) +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index e2135a4b..b24afe4a 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Odbc; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.Odbc.SqlServer @@ -163,8 +164,10 @@ use [{olddatabase}]; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); foreach (object[] row in ds) { int object_id = int.Parse(string.Concat(row[0])); @@ -178,16 +181,47 @@ use [{olddatabase}]; { case DbTableType.VIEW: case DbTableType.TABLE: - loc6.Add(object_id); + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } break; case DbTableType.StoreProcedure: - loc66.Add(object_id); + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } break; } } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + if (loc6.Count == 0) return loc1; - var loc8 = string.Join(",", loc6.Select(a => string.Concat(a))); - var loc88 = string.Join(",", loc66.Select(a => string.Concat(a))); + Func, StringBuilder> getloc8Sb = loclist => + { + if (loclist.Count == 0) return new StringBuilder(); + var loc8sb = new StringBuilder().Append("("); + for (var loc8sbidx = 0; loc8sbidx < loclist.Count; loc8sbidx++) + { + if (loc8sbidx > 0) loc8sb.Append(" OR "); + loc8sb.Append("a.table_name in ("); + for (var loc8sbidx2 = 0; loc8sbidx2 < loclist[loc8sbidx].Length; loc8sbidx2++) + { + if (loc8sbidx2 > 0) loc8sb.Append(","); + loc8sb.Append(loclist[loc8sbidx][loc8sbidx2]); + } + loc8sb.Append(")"); + } + loc8sb.Append(")"); + return loc8sb; + }; + var loc8 = getloc8Sb(loc6); + var loc88 = getloc8Sb(loc66); var tsql_place = @" @@ -213,12 +247,12 @@ inner join sys.types b on b.user_type_id = a.user_type_id left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id -where a.object_id in ({1}) +where {1} "; sql = string.Format(tsql_place, @" ,a.is_nullable 'IsNullable' ,a.is_identity 'IsIdentity' -from sys.columns", loc8); +from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); if (loc88.Length > 0) { sql += "union all" + @@ -227,7 +261,7 @@ from sys.columns", loc8); "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' -from sys.parameters", loc88); +from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); } sql = $"use [{db}];{sql};use [{olddatabase}]; "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -275,7 +309,7 @@ select from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id -where a.object_id in ({loc8}) and b.is_primary_key = 0 +where {loc8.ToString().Replace("a.table_name", "a.object_id")} and b.is_primary_key = 0 ; use [{olddatabase}]; "; @@ -344,7 +378,7 @@ inner join sys.tables b on b.object_id = a.parent_object_id inner join sys.columns c on c.object_id = a.parent_object_id and c.column_id = a.parent_column_id inner join sys.columns d on d.object_id = a.referenced_object_id and d.column_id = a.referenced_column_id left join sys.foreign_keys e on e.object_id = a.constraint_object_id -where b.object_id in ({loc8}) +where {loc8.ToString().Replace("a.table_name", "b.object_id")} ; use [{olddatabase}]; "; diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index e1bf1998..d76f4be5 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -6,6 +6,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.Oracle @@ -191,8 +192,10 @@ where a.owner in ({0})", databaseIn); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); foreach (var row in ds) { var table_id = string.Concat(row[0]); @@ -211,16 +214,40 @@ where a.owner in ({0})", databaseIn); { case DbTableType.TABLE: case DbTableType.VIEW: - loc6.Add(table.Replace("'", "''")); + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 999) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } break; case DbTableType.StoreProcedure: - loc66.Add(table.Replace("'", "''")); + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 999) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } break; } } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + if (loc6.Count == 0) return loc1; - var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); sql = string.Format(@" select @@ -236,7 +263,7 @@ nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name| b.comments from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner in ({1}) and a.table_name in ({0}) +where a.owner in ({1}) and {0} ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -303,7 +330,7 @@ all_ind_columns c where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.table_owner in ({1}) and a.table_name in ({0}) +and a.table_owner in ({1}) and {0} and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -390,7 +417,7 @@ and a.owner = c.owner    and a.table_name = c.table_name    and b.owner = d.owner    and b.table_name = d.table_name -and a.owner in ({1}) and a.table_name in ({0}) +and a.owner in ({1}) and {0} ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 6c448916..02a96a77 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -12,6 +12,7 @@ using System.Data.Common; using System.Linq; using System.Net; using System.Net.NetworkInformation; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.PostgreSQL @@ -258,8 +259,10 @@ and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geo var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); foreach (object[] row in ds) { var object_id = string.Concat(row[0]); @@ -273,16 +276,40 @@ and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geo { case DbTableType.VIEW: case DbTableType.TABLE: - loc6.Add(object_id); + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } break; case DbTableType.StoreProcedure: - loc66.Add(object_id); + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } break; } } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + if (loc6.Count == 0) return loc1; - string loc8 = "'" + string.Join("','", loc6.ToArray()) + "'"; - string loc88 = "'" + string.Join("','", loc66.ToArray()) + "'"; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); sql = $@" select @@ -307,7 +334,7 @@ left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum inner join pg_namespace ns on ns.oid = c.relnamespace inner join pg_namespace ns2 on ns2.oid = t.typnamespace -where ns.nspname || '.' || c.relname in ({loc8})"; +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")}"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -370,7 +397,7 @@ inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where ns.nspname || '.' || d.relname in ({loc8}) and a.indisprimary = 'f' +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} and a.indisprimary = 'f' "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -446,7 +473,7 @@ inner join pg_class b on b.oid = a.conrelid inner join pg_class c on c.oid = a.confrelid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_namespace ns2 on ns2.oid = c.relnamespace -where ns.nspname || '.' || b.relname in ({loc8}) +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index a91ca3c9..0a53e4f9 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.SqlServer @@ -166,8 +167,10 @@ use [{olddatabase}]; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var loc6 = new List(); - var loc66 = new List(); + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); foreach (object[] row in ds) { int object_id = int.Parse(string.Concat(row[0])); @@ -181,16 +184,47 @@ use [{olddatabase}]; { case DbTableType.VIEW: case DbTableType.TABLE: - loc6.Add(object_id); + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } break; case DbTableType.StoreProcedure: - loc66.Add(object_id); + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } break; } } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + if (loc6.Count == 0) return loc1; - var loc8 = string.Join(",", loc6.Select(a => string.Concat(a))); - var loc88 = string.Join(",", loc66.Select(a => string.Concat(a))); + Func, StringBuilder> getloc8Sb = loclist => + { + if (loclist.Count == 0) return new StringBuilder(); + var loc8sb = new StringBuilder().Append("("); + for (var loc8sbidx = 0; loc8sbidx < loclist.Count; loc8sbidx++) + { + if (loc8sbidx > 0) loc8sb.Append(" OR "); + loc8sb.Append("a.table_name in ("); + for (var loc8sbidx2 = 0; loc8sbidx2 < loclist[loc8sbidx].Length; loc8sbidx2++) + { + if (loc8sbidx2 > 0) loc8sb.Append(","); + loc8sb.Append(loclist[loc8sbidx][loc8sbidx2]); + } + loc8sb.Append(")"); + } + loc8sb.Append(")"); + return loc8sb; + }; + var loc8 = getloc8Sb(loc6); + var loc88 = getloc8Sb(loc66); var tsql_place = @" @@ -216,12 +250,12 @@ inner join sys.types b on b.user_type_id = a.user_type_id left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id -where a.object_id in ({1}) +where {1} "; sql = string.Format(tsql_place, @" ,a.is_nullable 'IsNullable' ,a.is_identity 'IsIdentity' -from sys.columns", loc8); +from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); if (loc88.Length > 0) { sql += "union all" + @@ -230,7 +264,7 @@ from sys.columns", loc8); "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' -from sys.parameters", loc88); +from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); } sql = $"use [{db}];{sql};use [{olddatabase}]; "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -278,7 +312,7 @@ select from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id -where a.object_id in ({loc8}) and b.is_primary_key = 0 +where {loc8.ToString().Replace("a.table_name", "a.object_id")} and b.is_primary_key = 0 ; use [{olddatabase}]; "; @@ -347,7 +381,7 @@ inner join sys.tables b on b.object_id = a.parent_object_id inner join sys.columns c on c.object_id = a.parent_object_id and c.column_id = a.parent_column_id inner join sys.columns d on d.object_id = a.referenced_object_id and d.column_id = a.referenced_column_id left join sys.foreign_keys e on e.object_id = a.constraint_object_id -where b.object_id in ({loc8}) +where {loc8.ToString().Replace("a.table_name", "b.object_id")} ; use [{olddatabase}]; "; From 731518c023569db46989465660e415a56f3b0c4c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 9 Oct 2019 00:13:16 +0800 Subject: [PATCH 0183/1029] v0.10.9 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 154efd4e..fcf66e5e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.8 + 0.10.9 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index eef8a26b..cabd3e1e 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 4fd7839a..28801fd7 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 3310cad7..f19f6b9e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index cdb998a4..b4050880 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 013ca3f7..cf45aa79 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index a01eabb2..a9e0097d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7e8d2cdc..86e8aa25 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a9f48b3f..d8722b08 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ba81e037..8bf9c403 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7b6327f3..4c77e21d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e821df69..a5deb12f 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ef2b950c..9d10216b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.8 + 0.10.9 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 00147be176894cc0059da62034a69bdba4cb376c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 9 Oct 2019 01:07:46 +0800 Subject: [PATCH 0184/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20PostgreSQL?= =?UTF-8?q?=20DbFirst=20=E8=8E=B7=E5=8F=96=E5=AD=97=E6=AE=B5=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=8B=BC=E5=BE=97=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=9A=84=E9=95=BF?= =?UTF-8?q?=E5=BA=A6(=E5=A6=82=20varchar(255))=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 8 ++++++++ .../FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 9c56304d..148d9d0d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -253,6 +253,14 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") if (attndims == 0) attndims++; } if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + if (max_length > 0) + { + switch (sqlType.ToLower()) + { + //case "numeric": sqlType += $"({max_length})"; break; + case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; + } + } loc3[object_id].Add(column, new DbColumnInfo { diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 02a96a77..97734719 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -364,6 +364,14 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") if (attndims == 0) attndims++; } if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + if (max_length > 0) + { + switch (sqlType.ToLower()) + { + //case "numeric": sqlType += $"({max_length})"; break; + case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; + } + } loc3[object_id].Add(column, new DbColumnInfo { From 236d03f98ce289225fe62d40e97f93a3a0a13863 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 9 Oct 2019 01:09:19 +0800 Subject: [PATCH 0185/1029] v0.10.10 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index fcf66e5e..11d79c65 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.9 + 0.10.10 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index cabd3e1e..38b9ecc7 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 28801fd7..a085991f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index f19f6b9e..35d5144e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index b4050880..74bbbd0f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cf45aa79..85801aba 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index a9e0097d..d0f8af73 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 86e8aa25..8be0be97 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d8722b08..6bffade8 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8bf9c403..35908c79 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 4c77e21d..c010a4c3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a5deb12f..56fc5078 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9d10216b..e7ef9281 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.9 + 0.10.10 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 1f2d4abdc723248135914d9840a866dca485cd06 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 9 Oct 2019 16:56:24 +0800 Subject: [PATCH 0186/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E5=B1=9E=E6=80=A7=E7=9A=84=E9=BB=98=E8=AE=A4=E5=80=BC?= =?UTF-8?q?=E5=AE=B9=E9=94=99=EF=BC=8C=E6=9E=9A=E4=B8=BE=E4=B8=8B=E6=A0=87?= =?UTF-8?q?=E4=B8=8D=E5=AD=98=E5=9C=A8=200=20=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=EF=BC=8Cmysql=20=E8=BF=81=E7=A7=BB=E7=BB=93=E6=9E=84=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E6=8A=A5=E9=94=99=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UnitTest1.cs | 37 +++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 8 ++++ FreeSql/Internal/UtilsExpressionTree.cs | 13 +++++++ 3 files changed, 58 insertions(+) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs new file mode 100644 index 00000000..d3300f9b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector +{ + + public class UnitTest1 + { + public class TestAddEnum + { + public Guid Id { get; set; } + public TestAddEnumType Type { get; set; } + public PermissionTypeEnum TestType { get; set; } + } + public enum TestAddEnumType { 中国人, 日本人 } + + public enum PermissionTypeEnum + { + /// + /// 菜单 + /// + Menu = 1, + /// + /// 接口 + /// + Api = 2 + } + + [Fact] + public void Test1() + { + g.mysql.Select().ToList(); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 13ed35bc..7010bd98 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -408,10 +408,18 @@ namespace FreeSql.Tests public Guid? Id { get; set; } public string xxx { get; set; } } + public class TestAddEnum + { + public Guid Id { get; set; } + public TestAddEnumType Type { get; set; } + } + public enum TestAddEnumType { 中国人, 日本人 } [Fact] public void Test1() { + g.mysql.Select().ToList(); + g.sqlite.Insert(new TestGuidId { xxx = "111" }).ExecuteAffrows(); g.sqlite.Insert(new TestGuidId { xxx = "222" }).ExecuteAffrows(); var gkkdk1 = g.sqlite.Select().Where(a => true).ToList(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 862c3b62..c73f3700 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -153,6 +153,19 @@ namespace FreeSql.Internal continue; } if (entityDefault != null) colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(entityDefault); + if (p.PropertyType.IsEnum) + { + var isEqualsEnumValue = false; + var enumValues = Enum.GetValues(p.PropertyType); + for (var a = 0; a < enumValues.Length; a++) + if (object.Equals(colattr.DbDefautValue, enumValues.GetValue(a))) + { + isEqualsEnumValue = true; + break; + } + if (isEqualsEnumValue == false) + colattr.DbDefautValue = enumValues.Length > 0 ? enumValues.GetValue(0) : null; + } if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue); if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; if (colattr.IsNullable == false && colattr.DbDefautValue == null) From 741c558d9112b4f18db2d5277422e7a9228e8438 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 9 Oct 2019 16:58:33 +0800 Subject: [PATCH 0187/1029] =?UTF-8?q?-=20=E7=BB=AD=E4=B8=8A=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20Enum=20=E9=BB=98=E8=AE=A4=E5=80=BC=E5=AE=B9?= =?UTF-8?q?=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/UtilsExpressionTree.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c73f3700..cccb47c9 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -163,8 +163,8 @@ namespace FreeSql.Internal isEqualsEnumValue = true; break; } - if (isEqualsEnumValue == false) - colattr.DbDefautValue = enumValues.Length > 0 ? enumValues.GetValue(0) : null; + if (isEqualsEnumValue == false && enumValues.Length > 0) + colattr.DbDefautValue = enumValues.GetValue(0); } if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue); if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; From c2ec5a34b16326f1dc37d759a7227999268aa671 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 9 Oct 2019 17:23:19 +0800 Subject: [PATCH 0188/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ORACLE=20Com?= =?UTF-8?q?mand=20=E7=BB=91=E5=AE=9A=E5=8F=98=E9=87=8F=20BindByName=20=3D?= =?UTF-8?q?=20true=EF=BC=9B#107?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index db16fada..dc0c4790 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -57,7 +57,9 @@ namespace FreeSql.Oracle protected override DbCommand CreateCommand() { - return new OracleCommand(); + var cmd = new OracleCommand(); + cmd.BindByName = true; + return cmd; } protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) From 9a8d51da50cb0cb5c47350892f54df03d3217157 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 9 Oct 2019 22:26:42 +0800 Subject: [PATCH 0189/1029] v0.10.11 #107 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 11d79c65..d4a5d7d6 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.10 + 0.10.11 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 38b9ecc7..da7864f4 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a085991f..1177d95c 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 35d5144e..e508a389 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 74bbbd0f..79b284f6 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 85801aba..ce8192ad 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d0f8af73..e2c95d0b 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8be0be97..194ee290 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 6bffade8..758ec2df 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 35908c79..c2e13788 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index c010a4c3..d6b12309 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 56fc5078..b36a59fd 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e7ef9281..be63fa3e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.10 + 0.10.11 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From e823f9dcd0fd0c8a767517ed086b282dd8b4e66c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 12 Oct 2019 01:02:42 +0800 Subject: [PATCH 0190/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.DbCo?= =?UTF-8?q?ntext=20=E5=AE=9E=E4=BD=93=E5=AF=B9=E8=B1=A1=E7=9A=84=E5=8F=98?= =?UTF-8?q?=E5=8C=96=E4=BA=8B=E4=BB=B6=EF=BC=9B=20>=20=E6=96=87=E6=A1=A3?= =?UTF-8?q?=EF=BC=9Ahttps://github.com/2881099/FreeSql/wiki/DbContext#%E5%?= =?UTF-8?q?AE%9E%E4%BD%93%E5%8F%98%E5%8C%96%E4%BA%8B%E4%BB%B6=20-=20?= =?UTF-8?q?=E8=A1=A5=E5=85=85=20Aop.CurdBefore=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8F=82=E6=95=B0=20Table=20=E5=AE=9E=E4=BD=93=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E5=85=83=E6=95=B0=E6=8D=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ValuesController.cs | 7 ++- Examples/dbcontext_01/dbcontext_01.csproj | 4 +- FreeSql.DbContext/DbContext/DbContext.cs | 23 +++++++-- FreeSql.DbContext/DbContext/DbContextAsync.cs | 17 +++---- .../DbContext/DbContextOptions.cs | 9 ++++ FreeSql.DbContext/DbContext/DbContextSync.cs | 34 +++++++++----- FreeSql.DbContext/DbSet/DbSet.cs | 4 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 15 ++++-- FreeSql.DbContext/DbSet/DbSetSync.cs | 17 +++++-- .../Extensions/FreeSqlDbContextExtensions.cs | 6 ++- FreeSql.DbContext/FreeSql.DbContext.xml | 15 ++++++ .../ContextSet/RepositoryDbContext.cs | 32 ++++++++++--- .../Repository/Repository/BaseRepository.cs | 47 +++++++++++++------ FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 6 +++ FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 15 +++++- FreeSql/FreeSql.xml | 5 ++ FreeSql/Interface/IAop.cs | 13 +++-- .../Internal/CommonProvider/DeleteProvider.cs | 4 +- .../Internal/CommonProvider/InsertProvider.cs | 4 +- .../SelectProvider/Select0Provider.cs | 22 ++++----- .../Internal/CommonProvider/UpdateProvider.cs | 4 +- .../Curd/MySqlDelete.cs | 4 +- .../Curd/MySqlInsert.cs | 8 ++-- .../Curd/MySqlUpdate.cs | 4 +- .../Default/Curd/OdbcInsert.cs | 4 +- .../MySql/Curd/OdbcMySqlDelete.cs | 4 +- .../MySql/Curd/OdbcMySqlInsert.cs | 8 ++-- .../MySql/Curd/OdbcMySqlUpdate.cs | 4 +- .../Oracle/Curd/OdbcOracleInsert.cs | 8 ++-- .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 12 ++--- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 8 ++-- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 4 +- .../Curd/OracleInsert.cs | 8 ++-- .../Curd/PostgreSQLDelete.cs | 4 +- .../Curd/PostgreSQLInsert.cs | 12 ++--- .../Curd/PostgreSQLUpdate.cs | 4 +- .../Curd/SqlServerDelete.cs | 4 +- .../Curd/SqlServerInsert.cs | 8 ++-- .../Curd/SqlServerUpdate.cs | 4 +- .../Curd/SqliteInsert.cs | 4 +- 43 files changed, 285 insertions(+), 146 deletions(-) diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs index 8d8e4299..3cbb6af6 100644 --- a/Examples/dbcontext_01/Controllers/ValuesController.cs +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -28,6 +28,11 @@ namespace dbcontext_01.Controllers [HttpGet] async public Task Get() { + _orm.SetDbContextOptions(opt => { + opt.OnEntityChange = changeReport => { + Console.WriteLine(changeReport); + }; + }); long id = 0; @@ -150,7 +155,7 @@ namespace dbcontext_01.Controllers using (var uow = _orm.CreateUnitOfWork()) { - + var reposSong = uow.GetRepository(); reposSong.Where(a => a.Id > 10).ToList(); //查询结果,进入 states diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj index c343f9ed..a90702b5 100644 --- a/Examples/dbcontext_01/dbcontext_01.csproj +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -6,8 +6,6 @@ - - @@ -15,7 +13,9 @@ + + diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 5aaa2b44..da822e03 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -38,11 +38,20 @@ namespace FreeSql { _optionsPriv = new DbContextOptions(); if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(Orm, out var opt)) + { _optionsPriv.EnableAddOrUpdateNavigateList = opt.EnableAddOrUpdateNavigateList; + _optionsPriv.OnEntityChange = opt.OnEntityChange; + } } return _optionsPriv; } } + internal void EmitOnEntityChange(List report) + { + var oec = UnitOfWork?.OnEntityChange ?? Options.OnEntityChange; + if (oec == null || report == null || report.Any() == false) return; + oec(report); + } #endregion protected DbContext() @@ -146,20 +155,26 @@ namespace FreeSql #endregion #region Queue Action + internal List _entityChangeReport = new List(); + public class EntityChangeInfo + { + public object Object { get; set; } + public EntityChangeType Type { get; set; } + } + public enum EntityChangeType { Insert, Update, Delete, SqlRaw } internal class ExecCommandInfo { - public ExecCommandInfoType actionType { get; set; } + public EntityChangeType changeType { get; set; } public IDbSet dbSet { get; set; } public Type stateType { get; set; } public Type entityType { get; set; } public object state { get; set; } } - internal enum ExecCommandInfoType { Insert, Update, Delete } Queue _actions = new Queue(); internal int _affrows = 0; - internal void EnqueueAction(ExecCommandInfoType actionType, IDbSet dbSet, Type stateType, Type entityType, object state) => - _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state }); + internal void EnqueueAction(EntityChangeType changeType, IDbSet dbSet, Type stateType, Type entityType, object state) => + _actions.Enqueue(new ExecCommandInfo { changeType = changeType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state }); #endregion ~DbContext() => this.Dispose(); diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index cf4bf849..61e6a258 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -13,10 +13,7 @@ namespace FreeSql async public virtual Task SaveChangesAsync() { await ExecCommandAsync(); - UnitOfWork?.Commit(); - var ret = _affrows; - _affrows = 0; - return ret; + return SaveChangesSuccess(); } static Dictionary>>> _dicExecCommandDbContextBetchAsync = new Dictionary>>>(); @@ -96,31 +93,31 @@ namespace FreeSql var isLiveUpdate = false; if (_actions.Any() == false && states.Any() || - info != null && oldinfo.actionType != info.actionType || + info != null && oldinfo.changeType != info.changeType || info != null && oldinfo.stateType != info.stateType || info != null && oldinfo.entityType != info.entityType) { - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType) + if (info != null && oldinfo.changeType == info.changeType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType) { //最后一个,合起来发送 states.Add(info.state); info = null; } - switch (oldinfo.actionType) + switch (oldinfo.changeType) { - case ExecCommandInfoType.Insert: + case EntityChangeType.Insert: await funcInsert(); break; - case ExecCommandInfoType.Delete: + case EntityChangeType.Delete: await funcDelete(); break; } isLiveUpdate = true; } - if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) + if (isLiveUpdate || oldinfo.changeType == EntityChangeType.Update) { if (states.Any()) await funcUpdate(isLiveUpdate); diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index 4841ded3..5c81e9f5 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -1,4 +1,8 @@  +using System; +using System.Collections.Generic; +using System.Linq; + namespace FreeSql { public class DbContextOptions @@ -17,5 +21,10 @@ namespace FreeSql /// - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录 /// public bool EnableAddOrUpdateNavigateList { get; set; } = true; + + /// + /// 实体变化事件 + /// + public Action> OnEntityChange { get; set; } } } diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs index 3de59884..cbec1023 100644 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -8,14 +8,26 @@ namespace FreeSql { partial class DbContext { - + int SaveChangesSuccess() + { + UnitOfWork?.Commit(); + int ret; + try + { + EmitOnEntityChange(_entityChangeReport); + } + finally + { + _entityChangeReport.Clear(); + ret = _affrows; + _affrows = 0; + } + return ret; + } public virtual int SaveChanges() { ExecCommand(); - UnitOfWork?.Commit(); - var ret = _affrows; - _affrows = 0; - return ret; + return SaveChangesSuccess(); } static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); @@ -96,31 +108,31 @@ namespace FreeSql var isLiveUpdate = false; if (_actions.Any() == false && states.Any() || - info != null && oldinfo.actionType != info.actionType || + info != null && oldinfo.changeType != info.changeType || info != null && oldinfo.stateType != info.stateType || info != null && oldinfo.entityType != info.entityType) { - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType) + if (info != null && oldinfo.changeType == info.changeType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType) { //最后一个,合起来发送 states.Add(info.state); info = null; } - switch (oldinfo.actionType) + switch (oldinfo.changeType) { - case ExecCommandInfoType.Insert: + case EntityChangeType.Insert: funcInsert(); break; - case ExecCommandInfoType.Delete: + case EntityChangeType.Delete: funcDelete(); break; } isLiveUpdate = true; } - if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) + if (isLiveUpdate || oldinfo.changeType == EntityChangeType.Update) { if (states.Any()) funcUpdate(isLiveUpdate); diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 4500ae9b..56651882 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -59,8 +59,8 @@ namespace FreeSql protected virtual IUpdate OrmUpdate(IEnumerable entitys) => _db.Orm.Update().AsType(_entityType).SetSource(entitys).WithTransaction(_uow?.GetOrBeginTransaction()); protected virtual IDelete OrmDelete(object dywhere) => _db.Orm.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); - internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) => - _db.EnqueueAction(actionType, this, typeof(EntityState), _entityType, state); + internal void EnqueueToDbContext(DbContext.EntityChangeType changeType, EntityState state) => + _db.EnqueueAction(changeType, this, typeof(EntityState), _entityType, state); internal void IncrAffrows(int affrows) => _db._affrows += affrows; diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index a283061c..cfa2ceb4 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -23,6 +23,7 @@ namespace FreeSql { if (adds.Any() == false) return 0; var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(); + _db._entityChangeReport.AddRange(adds.Select(a => new DbContext.EntityChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Insert })); return affrows; } @@ -45,6 +46,7 @@ namespace FreeSql var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data, true); @@ -53,6 +55,7 @@ namespace FreeSql { await DbContextExecCommandAsync(); var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); _db.Orm.MapEntityValue(_entityType, newval, data); Attach(newval); @@ -67,6 +70,7 @@ namespace FreeSql var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data, true); @@ -74,7 +78,7 @@ namespace FreeSql return; } } - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); + EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(data)); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data, true); @@ -100,6 +104,7 @@ namespace FreeSql await DbContextExecCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); + _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); var idx = 0; foreach (var s in data) _db.Orm.MapEntityValue(_entityType, rets[idx++], s); @@ -119,7 +124,7 @@ namespace FreeSql { //进入队列,等待 SaveChanges 时执行 foreach (var item in data) - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); + EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(item)); AttachRange(data); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) @@ -193,7 +198,9 @@ namespace FreeSql { var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType); foreach (var midWhere in midWheres) delall.Where(midWhere); + var sql = delall.ToSql(); await delall.ExecuteAffrowsAsync(); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); } else //保存 { @@ -314,6 +321,7 @@ namespace FreeSql var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); var affrows = await update.ExecuteAffrowsAsync(); + _db._entityChangeReport.AddRange(updateSource.Select(a => new DbContext.EntityChangeInfo { Object = a, Type = DbContext.EntityChangeType.Update })); foreach (var newval in data) { @@ -352,7 +360,7 @@ namespace FreeSql var state = CreateEntityState(item); state.OldValue = item; - EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); + EnqueueToDbContext(DbContext.EntityChangeType.Update, state); } if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) @@ -365,6 +373,7 @@ namespace FreeSql { if (dels.Any() == false) return 0; var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); + _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); return Math.Max(dels.Length, affrows); } #endregion diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 9d2b46be..2443717f 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -23,6 +23,7 @@ namespace FreeSql { if (adds.Any() == false) return 0; var affrows = this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrows(); + _db._entityChangeReport.AddRange(adds.Select(a => new DbContext.EntityChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Insert })); return affrows; } @@ -45,6 +46,7 @@ namespace FreeSql var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data, true); @@ -53,6 +55,7 @@ namespace FreeSql { DbContextExecCommand(); var newval = this.OrmInsert(data).ExecuteInserted().First(); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); _db.Orm.MapEntityValue(_entityType, newval, data); Attach(newval); @@ -67,6 +70,7 @@ namespace FreeSql var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data, true); @@ -74,7 +78,7 @@ namespace FreeSql return; } } - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); + EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(data)); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data, true); @@ -104,6 +108,7 @@ namespace FreeSql DbContextExecCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); + _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); var idx = 0; foreach (var s in data) _db.Orm.MapEntityValue(_entityType, rets[idx++], s); @@ -123,7 +128,7 @@ namespace FreeSql { //进入队列,等待 SaveChanges 时执行 foreach (var item in data) - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); + EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(item)); AttachRange(data); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) @@ -203,7 +208,9 @@ namespace FreeSql { var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType); foreach (var midWhere in midWheres) delall.Where(midWhere); + var sql = delall.ToSql(); delall.ExecuteAffrows(); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); } else //保存 { @@ -324,6 +331,7 @@ namespace FreeSql var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); var affrows = update.ExecuteAffrows(); + _db._entityChangeReport.AddRange(updateSource.Select(a => new DbContext.EntityChangeInfo { Object = a, Type = DbContext.EntityChangeType.Update })); foreach (var newval in data) { @@ -368,7 +376,7 @@ namespace FreeSql var state = CreateEntityState(item); state.OldValue = item; - EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); + EnqueueToDbContext(DbContext.EntityChangeType.Update, state); } if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) @@ -381,6 +389,7 @@ namespace FreeSql { if (dels.Any() == false) return 0; var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); + _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); return Math.Max(dels.Length, affrows); } @@ -398,7 +407,7 @@ namespace FreeSql _states.TryRemove(state.Key, out var trystate); _db.Orm.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, item); - EnqueueToDbContext(DbContext.ExecCommandInfoType.Delete, state); + EnqueueToDbContext(DbContext.EntityChangeType.Delete, state); } } #endregion diff --git a/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs index e1b95f38..b4658e20 100644 --- a/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs +++ b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs @@ -1,6 +1,7 @@ using FreeSql; using System; using System.Collections.Concurrent; +using System.Collections.Generic; public static class FreeSqlDbContextExtensions { @@ -31,12 +32,13 @@ public static class FreeSqlDbContextExtensions /// /// /// - public static void SetDbContextOptions(this IFreeSql that, Action options) + public static IFreeSql SetDbContextOptions(this IFreeSql that, Action options) { - if (options == null) return; + if (options == null) return that; var cfg = _dicSetDbContextOptions.GetOrAdd(that, t => new DbContextOptions()); options(cfg); _dicSetDbContextOptions.AddOrUpdate(that, cfg, (t, o) => cfg); + return that; } internal static ConcurrentDictionary _dicSetDbContextOptions = new ConcurrentDictionary(); } \ No newline at end of file diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dad2ddeb..9b3a3998 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -60,6 +60,11 @@ - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录 + + + 实体变化事件 + + 动态Type,在使用 DbSet<object> 后使用本方法,指定实体类型 @@ -214,6 +219,16 @@ 开启工作单元 + + + 实体变化事件 + + + + + 工作单元的实体变化记录 + + 创建普通数据上下文档对象 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 632a87f7..d18ceb68 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -54,19 +54,39 @@ namespace FreeSql }); } + int SaveChangesSuccess() + { + int ret; + try + { + if (UnitOfWork == null) EmitOnEntityChange(_entityChangeReport); + else + { + var uow = UnitOfWork as UnitOfWork; + if (uow != null) + { + uow.EntityChangeReport.AddRange(_entityChangeReport); + if (uow.OnEntityChange == null) uow.OnEntityChange = Options.OnEntityChange; + } + } + } + finally + { + _entityChangeReport.Clear(); + ret = _affrows; + _affrows = 0; + } + return ret; + } public override int SaveChanges() { ExecCommand(); - var ret = _affrows; - _affrows = 0; - return ret; + return SaveChangesSuccess(); } async public override Task SaveChangesAsync() { await ExecCommandAsync(); - var ret = _affrows; - _affrows = 0; - return ret; + return SaveChangesSuccess(); } } } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index f7775429..ea7dfa67 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Extensions.EntityUtil; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -69,8 +70,22 @@ namespace FreeSql public ISelect Where(Expression> exp) => _dbset.OrmSelectInternal(null).Where(exp); public ISelect WhereIf(bool condition, Expression> exp) => _dbset.OrmSelectInternal(null).WhereIf(condition, exp); - public int Delete(Expression> predicate) => _dbset.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows(); - public Task DeleteAsync(Expression> predicate) => _dbset.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync(); + public int Delete(Expression> predicate) + { + var delete = _dbset.OrmDeleteInternal(null).Where(predicate); + var sql = delete.ToSql(); + var affrows = delete.ExecuteAffrows(); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); + return affrows; + } + async public Task DeleteAsync(Expression> predicate) + { + var delete = _dbset.OrmDeleteInternal(null).Where(predicate); + var sql = delete.ToSql(); + var affrows = await delete.ExecuteAffrowsAsync(); + _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); + return affrows; + } public int Delete(TEntity entity) { @@ -170,21 +185,23 @@ namespace FreeSql { } - public int Delete(TKey id) + TEntity CheckTKeyAndReturnIdEntity(TKey id) { - var stateKey = string.Concat(id); - _dbset._statesInternal.TryRemove(stateKey, out var trystate); - return _dbset.OrmDeleteInternal(id).ExecuteAffrows(); - } - public Task DeleteAsync(TKey id) - { - var stateKey = string.Concat(id); - _dbset._statesInternal.TryRemove(stateKey, out var trystate); - return _dbset.OrmDeleteInternal(id).ExecuteAffrowsAsync(); + var tb = _db.Orm.CodeFirst.GetTableByEntity(EntityType); + if (tb.Primarys.Length != 1) throw new Exception($"实体类型 {EntityType.Name} 主键数量不为 1,无法使用该方法"); + if (tb.Primarys[0].CsType.NullableTypeOrThis() != typeof(TKey).NullableTypeOrThis()) throw new Exception($"实体类型 {EntityType.Name} 主键类型不为 {typeof(TKey).FullName},无法使用该方法"); + var obj = Activator.CreateInstance(tb.Type); + _db.Orm.SetEntityValueWithPropertyName(tb.Type, obj, tb.Primarys[0].CsName, id); + var ret = obj as TEntity; + if (ret == null) throw new Exception($"实体类型 {EntityType.Name} 无法转换为 {typeof(TEntity).Name},无法使用该方法"); + return ret; } - public TEntity Find(TKey id) => _dbset.OrmSelectInternal(id).ToOne(); - public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(id).ToOneAsync(); + public int Delete(TKey id) => Delete(CheckTKeyAndReturnIdEntity(id)); + public Task DeleteAsync(TKey id) => DeleteAsync(CheckTKeyAndReturnIdEntity(id)); + + public TEntity Find(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); + public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(); public TEntity Get(TKey id) => Find(id); public Task GetAsync(TKey id) => FindAsync(id); diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index ca1a7acd..f5c77638 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -32,5 +33,10 @@ namespace FreeSql /// 开启工作单元 /// void Open(); + + /// + /// 实体变化事件 + /// + Action> OnEntityChange { get; set; } } } diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 493c9bf5..9167368c 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -1,5 +1,6 @@ using SafeObjectPool; using System; +using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Threading; @@ -32,6 +33,7 @@ namespace FreeSql #if ns20 Current.Value = null; #endif + EntityChangeReport.Clear(); } public bool Enable { get; private set; } = true; @@ -76,7 +78,11 @@ namespace FreeSql { try { - if (_tran != null) _tran.Commit(); + if (_tran != null) + { + _tran.Commit(); + OnEntityChange?.Invoke(EntityChangeReport); + } } finally { @@ -94,6 +100,13 @@ namespace FreeSql ReturnObject(); } } + + public Action> OnEntityChange { get; set; } + /// + /// 工作单元的实体变化记录 + /// + public List EntityChangeReport { get; } = new List(); + ~UnitOfWork() { this.Dispose(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6ae63c12..53d85f09 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2215,6 +2215,11 @@ 实体类型 + + + 实体类型的元数据 + + 执行的 SQL diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index cb8a4043..c1c5c3f4 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -151,16 +151,17 @@ namespace FreeSql.Aop public class CurdBeforeEventArgs : EventArgs { - public CurdBeforeEventArgs(Type entityType, CurdType curdType, string sql, DbParameter[] dbParms) : - this(Guid.NewGuid(), new Stopwatch(), entityType, curdType, sql, dbParms) + public CurdBeforeEventArgs(Type entityType, TableInfo table, CurdType curdType, string sql, DbParameter[] dbParms) : + this(Guid.NewGuid(), new Stopwatch(), entityType, table, curdType, sql, dbParms) { this.Stopwatch.Start(); } - protected CurdBeforeEventArgs(Guid identifier, Stopwatch stopwatch, Type entityType, CurdType curdType, string sql, DbParameter[] dbParms) + protected CurdBeforeEventArgs(Guid identifier, Stopwatch stopwatch, Type entityType, TableInfo table, CurdType curdType, string sql, DbParameter[] dbParms) { this.Identifier = identifier; this.Stopwatch = stopwatch; this.EntityType = entityType; + this.Table = table; this.CurdType = curdType; this.Sql = sql; this.DbParms = dbParms; @@ -181,6 +182,10 @@ namespace FreeSql.Aop /// public Type EntityType { get; } /// + /// 实体类型的元数据 + /// + public TableInfo Table { get; set; } + /// /// 执行的 SQL /// public string Sql { get; } @@ -193,7 +198,7 @@ namespace FreeSql.Aop public class CurdAfterEventArgs : CurdBeforeEventArgs { public CurdAfterEventArgs(CurdBeforeEventArgs before, Exception exception, object executeResult) : - base(before.Identifier, before.StopwatchInternal, before.EntityType, before.CurdType, before.Sql, before.DbParms) + base(before.Identifier, before.StopwatchInternal, before.EntityType, before.Table, before.CurdType, before.Sql, before.DbParms) { this.Exception = exception; this.ExecuteResult = executeResult; diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 8366cde9..45af15e9 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -58,7 +58,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var affrows = 0; Exception exception = null; @@ -84,7 +84,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var affrows = 0; Exception exception = null; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index c425d379..a6e65ed5 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -488,7 +488,7 @@ namespace FreeSql.Internal.CommonProvider protected int RawExecuteAffrows() { var sql = ToSql(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var affrows = 0; Exception exception = null; @@ -511,7 +511,7 @@ namespace FreeSql.Internal.CommonProvider async protected Task RawExecuteAffrowsAsync() { var sql = ToSql(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var affrows = 0; Exception exception = null; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 6ad66981..2a1b90d3 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -265,7 +265,7 @@ namespace FreeSql.Internal.CommonProvider { var sql = this.ToSql(field); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); DataTable ret = null; Exception exception = null; @@ -289,7 +289,7 @@ namespace FreeSql.Internal.CommonProvider { var sql = this.ToSql(field); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); DataTable ret = null; Exception exception = null; @@ -315,7 +315,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(field); var type = typeof(TTuple); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); var flagStr = $"ToListField:{field}"; @@ -345,7 +345,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(field); var type = typeof(TTuple); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); var flagStr = $"ToListField:{field}"; @@ -374,7 +374,7 @@ namespace FreeSql.Internal.CommonProvider internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -409,7 +409,7 @@ namespace FreeSql.Internal.CommonProvider async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -476,7 +476,7 @@ namespace FreeSql.Internal.CommonProvider internal void ToListAfChunkPrivate(int chunkSize, Action> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); var retCount = 0; @@ -579,7 +579,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(af.field); var type = typeof(TReturn); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -610,7 +610,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(af.field); var type = typeof(TReturn); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -1088,7 +1088,7 @@ namespace FreeSql.Internal.CommonProvider { var sql = this.InternalToSql(select); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); DataTable ret = null; Exception exception = null; @@ -1112,7 +1112,7 @@ namespace FreeSql.Internal.CommonProvider { var sql = this.InternalToSql(select); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); DataTable ret = null; Exception exception = null; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index b021f6b1..14709887 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -325,7 +325,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var affrows = 0; Exception exception = null; @@ -351,7 +351,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var affrows = 0; Exception exception = null; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index 2b63f5b6..f3679435 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -32,7 +32,7 @@ namespace FreeSql.MySql.Curd } sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -70,7 +70,7 @@ namespace FreeSql.MySql.Curd } sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index ab8df3c2..64f9a0c8 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -29,7 +29,7 @@ namespace FreeSql.MySql.Curd if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -55,7 +55,7 @@ namespace FreeSql.MySql.Curd if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -91,7 +91,7 @@ namespace FreeSql.MySql.Curd ++colidx; } sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -127,7 +127,7 @@ namespace FreeSql.MySql.Curd ++colidx; } sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 4b820e1c..e3749b0a 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.MySql.Curd } sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -79,7 +79,7 @@ namespace FreeSql.MySql.Curd } sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index 9b3e7f54..f7c68d8f 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.Default if (string.IsNullOrEmpty(sql)) return 0; Object poolConn = null; - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, string.Concat(sql, $"; {_utils.Adapter.InsertAfterGetIdentitySql}"), _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, $"; {_utils.Adapter.InsertAfterGetIdentitySql}"), _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -69,7 +69,7 @@ namespace FreeSql.Odbc.Default if (string.IsNullOrEmpty(sql)) return 0; Object poolConn = null; - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, string.Concat(sql, $"; {_utils.Adapter.InsertAfterGetIdentitySql}"), _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, $"; {_utils.Adapter.InsertAfterGetIdentitySql}"), _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index 1d19cd89..84d7b968 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.MySql } sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -70,7 +70,7 @@ namespace FreeSql.Odbc.MySql } sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index d48ce6ca..cba7443d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -31,7 +31,7 @@ namespace FreeSql.Odbc.MySql if (string.IsNullOrEmpty(sql)) return 0; Object poolConn = null; - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -68,7 +68,7 @@ namespace FreeSql.Odbc.MySql if (string.IsNullOrEmpty(sql)) return 0; Object poolConn = null; - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -115,7 +115,7 @@ namespace FreeSql.Odbc.MySql ++colidx; } sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -151,7 +151,7 @@ namespace FreeSql.Odbc.MySql ++colidx; } sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index 2179e2af..35d854d3 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.Odbc.MySql } sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.MySql } sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index 8ca161d9..d74d87d2 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -95,7 +95,7 @@ namespace FreeSql.Odbc.Oracle if (_identCol == null || _source.Count > 1) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -118,7 +118,7 @@ namespace FreeSql.Odbc.Oracle identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -148,7 +148,7 @@ namespace FreeSql.Odbc.Oracle if (_identCol == null || _source.Count > 1) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -171,7 +171,7 @@ namespace FreeSql.Odbc.Oracle identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); try { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index f9feba9e..a9039ebe 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.PostgreSQL } sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -70,7 +70,7 @@ namespace FreeSql.Odbc.PostgreSQL } sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index ef447d69..430285a9 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -36,7 +36,7 @@ namespace FreeSql.Odbc.PostgreSQL var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); if (identCols.Any() == false) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -55,7 +55,7 @@ namespace FreeSql.Odbc.PostgreSQL return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -85,7 +85,7 @@ namespace FreeSql.Odbc.PostgreSQL var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); if (identCols.Any() == false) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -104,7 +104,7 @@ namespace FreeSql.Odbc.PostgreSQL return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -139,7 +139,7 @@ namespace FreeSql.Odbc.PostgreSQL ++colidx; } sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -175,7 +175,7 @@ namespace FreeSql.Odbc.PostgreSQL ++colidx; } sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 2ad90e96..6aab35a3 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.Odbc.PostgreSQL } sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.PostgreSQL } sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index 68a16b50..6134d2a9 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -80,7 +80,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 8a9cc4ea..986df69e 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -31,7 +31,7 @@ namespace FreeSql.Odbc.SqlServer if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -57,7 +57,7 @@ namespace FreeSql.Odbc.SqlServer if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -99,7 +99,7 @@ namespace FreeSql.Odbc.SqlServer sb.Append(sql.Substring(validx + 1)); sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -140,7 +140,7 @@ namespace FreeSql.Odbc.SqlServer sb.Append(sql.Substring(validx + 1)); sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index 8c19325c..bd0befb5 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -46,7 +46,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -89,7 +89,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 345fc384..03ab37b1 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -96,7 +96,7 @@ namespace FreeSql.Oracle.Curd if (_identCol == null || _source.Count > 1) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -119,7 +119,7 @@ namespace FreeSql.Oracle.Curd identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -149,7 +149,7 @@ namespace FreeSql.Oracle.Curd if (_identCol == null || _source.Count > 1) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -172,7 +172,7 @@ namespace FreeSql.Oracle.Curd identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, dbParms); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); try { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index 251cc918..f2b40940 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -32,7 +32,7 @@ namespace FreeSql.PostgreSQL.Curd } sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -70,7 +70,7 @@ namespace FreeSql.PostgreSQL.Curd } sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index b9ee9379..bb5ef651 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -36,7 +36,7 @@ namespace FreeSql.PostgreSQL.Curd var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); if (identCols.Any() == false) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -55,7 +55,7 @@ namespace FreeSql.PostgreSQL.Curd return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -85,7 +85,7 @@ namespace FreeSql.PostgreSQL.Curd var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); if (identCols.Any() == false) { - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -104,7 +104,7 @@ namespace FreeSql.PostgreSQL.Curd return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); - before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); try { @@ -139,7 +139,7 @@ namespace FreeSql.PostgreSQL.Curd ++colidx; } sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -175,7 +175,7 @@ namespace FreeSql.PostgreSQL.Curd ++colidx; } sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index b1fc6740..62343660 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.PostgreSQL.Curd } sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -79,7 +79,7 @@ namespace FreeSql.PostgreSQL.Curd } sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index b227068f..df944cc1 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -37,7 +37,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -80,7 +80,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 9210ee7f..46534b12 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -31,7 +31,7 @@ namespace FreeSql.SqlServer.Curd if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -57,7 +57,7 @@ namespace FreeSql.SqlServer.Curd if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -99,7 +99,7 @@ namespace FreeSql.SqlServer.Curd sb.Append(sql.Substring(validx + 1)); sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -140,7 +140,7 @@ namespace FreeSql.SqlServer.Curd sb.Append(sql.Substring(validx + 1)); sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index 8827213d..a8944a6c 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -46,7 +46,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; @@ -89,7 +89,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); _orm.Aop.CurdBefore?.Invoke(this, before); var ret = new List(); Exception exception = null; diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index 7fc0e3b9..8c09083b 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -30,7 +30,7 @@ namespace FreeSql.Sqlite.Curd if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT last_insert_rowid();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -56,7 +56,7 @@ namespace FreeSql.Sqlite.Curd if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT last_insert_rowid();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBefore?.Invoke(this, before); long ret = 0; Exception exception = null; From 0485a22a5cd58bb070c5cdaf49879b6af43f3765 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 12 Oct 2019 01:05:51 +0800 Subject: [PATCH 0191/1029] 0.10.12 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d4a5d7d6..b33135d5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.11 + 0.10.12 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index da7864f4..3fd0c41b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 1177d95c..ea334389 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e508a389..e797e1f6 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 79b284f6..1eb250ea 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index ce8192ad..e958b743 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e2c95d0b..c96e29c4 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 194ee290..1bd25993 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 758ec2df..66a7946e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index c2e13788..97dd177c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d6b12309..419b5489 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b36a59fd..ace11f6b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index be63fa3e..339a74e6 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.11 + 0.10.12 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 615023f012a8d14db0beba1363de09fdb745dc35 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 14 Oct 2019 13:21:47 +0800 Subject: [PATCH 0192/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20postgresql?= =?UTF-8?q?=2012=20=E7=A7=BB=E9=99=A4=20pg=5Fattrdef.adsrc=20=E5=88=97?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E8=87=B4=20CodeFirst=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E7=9A=84=20bug=EF=BC=9B=20-=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20Aop.ConfigEntity=20=E5=B1=9E=E6=80=A7=20ModifyIndex?= =?UTF-8?q?Result=20=E7=8E=B0=E5=AE=9E=20IndexAttribute=20=E7=9A=84?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 2 +- FreeSql/FreeSql.xml | 5 ++++ FreeSql/Interface/IAop.cs | 5 ++++ FreeSql/Internal/CommonUtils.cs | 28 +++++++++++++------ .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 5 ++-- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 6 ++-- .../PostgreSQLCodeFirst.cs | 5 ++-- .../PostgreSQLDbFirst.cs | 6 ++-- 8 files changed, 43 insertions(+), 19 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index d91dc319..c3dd0d2b 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -351,7 +351,7 @@ namespace FreeSql.Tests.PostgreSQL [Table(Name = "tb_alltype")] class TableAllType { - [Column(IsIdentity = true, IsPrimary = true)] + [Column(IsPrimary = true)] public int Id { get; set; } public bool testFieldBool { get; set; } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 53d85f09..6179f8fa 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2185,6 +2185,11 @@ 实体配置 + + + 索引配置 + + 实体类型 diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index c1c5c3f4..ce18c3ae 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -115,6 +115,7 @@ namespace FreeSql.Aop { this.EntityType = entityType; this.ModifyResult = new TableAttribute(); + this.ModifyIndexResult = new List(); } /// @@ -125,6 +126,10 @@ namespace FreeSql.Aop /// 实体配置 /// public TableAttribute ModifyResult { get; } + /// + /// 索引配置 + /// + public List ModifyIndexResult { get; } } public class ConfigEntityPropertyEventArgs : EventArgs { diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 7c9ed240..c19b4c28 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -87,7 +87,6 @@ namespace FreeSql.Internal if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter; if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; - } var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); foreach (var tryattrobj in attrs) @@ -190,24 +189,37 @@ namespace FreeSql.Internal } public IndexAttribute[] GetEntityIndexAttribute(Type type) { - var ret = new Dictionary(); ; + var ret = new Dictionary(); + if (_orm.Aop.ConfigEntity != null) + { + var aope = new Aop.ConfigEntityEventArgs(type); + _orm.Aop.ConfigEntity(_orm, aope); + foreach (var idxattr in aope.ModifyIndexResult) + if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields)) + { + if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name); + ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique }); + } + } if (dicConfigEntity.TryGetValue(type, out var trytb)) { foreach (var idxattr in trytb._indexs.Values) - { if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields)) + { + if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name); ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique }); - } + } } var attrs = type.GetCustomAttributes(typeof(IndexAttribute), true); foreach (var tryattrobj in attrs) { var idxattr = tryattrobj as IndexAttribute; if (idxattr == null) continue; - if (string.IsNullOrEmpty(idxattr.Name)) continue; - if (string.IsNullOrEmpty(idxattr.Fields)) continue; - if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name); - ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique }); + if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields)) + { + if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name); + ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique }); + } } return ret.Values.ToArray(); } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index fdd063a8..2d04cd90 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -165,7 +165,8 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -e.adsrc, +coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +--e.adsrc, a.attndims, d.description as comment from pg_class c @@ -201,7 +202,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + is_identity = string.Concat(a[5]) == "1", //string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), attndims, comment = string.Concat(a[7]) }; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 148d9d0d..d4229572 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -208,8 +208,8 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, -e.adsrc as is_identity, ---case when e.adsrc = 'nextval(''' || case when ns.nspname = 'public' then '' else ns.nspname || '.' end || c.relname || '_' || a.attname || '_seq''::regclass)' then 1 else 0 end as is_identity, +coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +--e.adsrc as is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, @@ -235,7 +235,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var is_identity = string.Concat(row[6]) == "1"; //string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); var comment = string.Concat(row[7]); int attndims = int.Parse(string.Concat(row[8])); string typtype = string.Concat(row[9]); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 1fd94504..961ef8b5 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -207,7 +207,8 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -e.adsrc, +coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +--e.adsrc, a.attndims, d.description as comment from pg_class c @@ -243,7 +244,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + is_identity = string.Concat(a[5]) == "1", //string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), attndims, comment = string.Concat(a[7]) }; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 97734719..5910c1d3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -319,8 +319,8 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, -e.adsrc as is_identity, ---case when e.adsrc = 'nextval(''' || case when ns.nspname = 'public' then '' else ns.nspname || '.' end || c.relname || '_' || a.attname || '_seq''::regclass)' then 1 else 0 end as is_identity, +coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +--e.adsrc as is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, @@ -346,7 +346,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var is_identity = string.Concat(row[6]) == "1"; //string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); var comment = string.Concat(row[7]); int attndims = int.Parse(string.Concat(row[8])); string typtype = string.Concat(row[9]); From 375ba5f3cbd9499a576d4bb8824b0ae380f26a15 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 14 Oct 2019 13:45:08 +0800 Subject: [PATCH 0193/1029] ## v0.10.13 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b33135d5..a218b192 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.12 + 0.10.13 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 3fd0c41b..c906cc6c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ea334389..ca680c76 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e797e1f6..814fbf7a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 1eb250ea..e3f5ad82 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index c3dd0d2b..d91dc319 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -351,7 +351,7 @@ namespace FreeSql.Tests.PostgreSQL [Table(Name = "tb_alltype")] class TableAllType { - [Column(IsPrimary = true)] + [Column(IsIdentity = true, IsPrimary = true)] public int Id { get; set; } public bool testFieldBool { get; set; } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e958b743..78a9429c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c96e29c4..4346f38d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 1bd25993..11382c83 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 66a7946e..1a53a5f2 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 97dd177c..73eae871 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 419b5489..3432f5d1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index ace11f6b..22f74037 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 339a74e6..464bac3f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.12 + 0.10.13 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From d7877924a5f0d6b5114bc4907cc07640baf828a1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 15 Oct 2019 19:18:31 +0800 Subject: [PATCH 0194/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20DbContext.En?= =?UTF-8?q?tityChangeInfo=20=E7=B1=BB=E5=90=8D=E4=B8=BA=20DbContext.Entity?= =?UTF-8?q?ChangeReport.ChangeInfo=EF=BC=9B=20-=20=E8=B0=83=E6=95=B4=20IUn?= =?UTF-8?q?itOfWork=20=E6=8E=A5=E5=8F=A3=EF=BC=8C=E7=A7=BB=E9=99=A4=20OnEn?= =?UTF-8?q?tityChange=20=E5=B1=9E=E6=80=A7=EF=BC=8C=E5=A2=9E=E5=8A=A0=20En?= =?UTF-8?q?tityChangeReport=20=E5=B1=9E=E6=80=A7=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 23 ++++++++++++++----- .../DbContext/DbContextOptions.cs | 2 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 16 ++++++------- FreeSql.DbContext/DbSet/DbSetSync.cs | 16 ++++++------- FreeSql.DbContext/FreeSql.DbContext.xml | 19 +++++++++------ .../ContextSet/RepositoryDbContext.cs | 14 ++++------- .../Repository/Repository/BaseRepository.cs | 4 ++-- FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 4 ++-- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 12 ++++------ 9 files changed, 60 insertions(+), 50 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index da822e03..f9d1d4f0 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -46,9 +46,9 @@ namespace FreeSql return _optionsPriv; } } - internal void EmitOnEntityChange(List report) + internal void EmitOnEntityChange(List report) { - var oec = UnitOfWork?.OnEntityChange ?? Options.OnEntityChange; + var oec = UnitOfWork?.EntityChangeReport?.OnChange ?? Options.OnEntityChange; if (oec == null || report == null || report.Any() == false) return; oec(report); } @@ -155,12 +155,23 @@ namespace FreeSql #endregion #region Queue Action - internal List _entityChangeReport = new List(); - public class EntityChangeInfo + public class EntityChangeReport { - public object Object { get; set; } - public EntityChangeType Type { get; set; } + public class ChangeInfo + { + public object Object { get; set; } + public EntityChangeType Type { get; set; } + } + /// + /// 实体变化记录 + /// + public List Report { get; } = new List(); + /// + /// 实体变化事件 + /// + public Action> OnChange { get; set; } } + internal List _entityChangeReport = new List(); public enum EntityChangeType { Insert, Update, Delete, SqlRaw } internal class ExecCommandInfo { diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index 5c81e9f5..95cd5630 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -25,6 +25,6 @@ namespace FreeSql /// /// 实体变化事件 /// - public Action> OnEntityChange { get; set; } + public Action> OnEntityChange { get; set; } } } diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index cfa2ceb4..1696fe30 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -23,7 +23,7 @@ namespace FreeSql { if (adds.Any() == false) return 0; var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(); - _db._entityChangeReport.AddRange(adds.Select(a => new DbContext.EntityChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Insert })); + _db._entityChangeReport.AddRange(adds.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Insert })); return affrows; } @@ -46,7 +46,7 @@ namespace FreeSql var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data, true); @@ -55,7 +55,7 @@ namespace FreeSql { await DbContextExecCommandAsync(); var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); _db.Orm.MapEntityValue(_entityType, newval, data); Attach(newval); @@ -70,7 +70,7 @@ namespace FreeSql var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data, true); @@ -104,7 +104,7 @@ namespace FreeSql await DbContextExecCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); - _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); + _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); var idx = 0; foreach (var s in data) _db.Orm.MapEntityValue(_entityType, rets[idx++], s); @@ -200,7 +200,7 @@ namespace FreeSql foreach (var midWhere in midWheres) delall.Where(midWhere); var sql = delall.ToSql(); await delall.ExecuteAffrowsAsync(); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); } else //保存 { @@ -321,7 +321,7 @@ namespace FreeSql var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); var affrows = await update.ExecuteAffrowsAsync(); - _db._entityChangeReport.AddRange(updateSource.Select(a => new DbContext.EntityChangeInfo { Object = a, Type = DbContext.EntityChangeType.Update })); + _db._entityChangeReport.AddRange(updateSource.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Update })); foreach (var newval in data) { @@ -373,7 +373,7 @@ namespace FreeSql { if (dels.Any() == false) return 0; var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); - _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); + _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); return Math.Max(dels.Length, affrows); } #endregion diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 2443717f..a0aeddf1 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -23,7 +23,7 @@ namespace FreeSql { if (adds.Any() == false) return 0; var affrows = this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrows(); - _db._entityChangeReport.AddRange(adds.Select(a => new DbContext.EntityChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Insert })); + _db._entityChangeReport.AddRange(adds.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Insert })); return affrows; } @@ -46,7 +46,7 @@ namespace FreeSql var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data, true); @@ -55,7 +55,7 @@ namespace FreeSql { DbContextExecCommand(); var newval = this.OrmInsert(data).ExecuteInserted().First(); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); _db.Orm.MapEntityValue(_entityType, newval, data); Attach(newval); @@ -70,7 +70,7 @@ namespace FreeSql var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data, true); @@ -108,7 +108,7 @@ namespace FreeSql DbContextExecCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); - _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); + _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); var idx = 0; foreach (var s in data) _db.Orm.MapEntityValue(_entityType, rets[idx++], s); @@ -210,7 +210,7 @@ namespace FreeSql foreach (var midWhere in midWheres) delall.Where(midWhere); var sql = delall.ToSql(); delall.ExecuteAffrows(); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); } else //保存 { @@ -331,7 +331,7 @@ namespace FreeSql var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); var affrows = update.ExecuteAffrows(); - _db._entityChangeReport.AddRange(updateSource.Select(a => new DbContext.EntityChangeInfo { Object = a, Type = DbContext.EntityChangeType.Update })); + _db._entityChangeReport.AddRange(updateSource.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Update })); foreach (var newval in data) { @@ -389,7 +389,7 @@ namespace FreeSql { if (dels.Any() == false) return 0; var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); - _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); + _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); return Math.Max(dels.Length, affrows); } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9b3a3998..5ae14b30 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -46,6 +46,16 @@ + + + 实体变化记录 + + + + + 实体变化事件 + + 是否开启一对多,多对多联级保存功能 @@ -219,14 +229,9 @@ 开启工作单元 - + - 实体变化事件 - - - - - 工作单元的实体变化记录 + 此工作单元内的实体变化跟踪 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index d18ceb68..b09d7463 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -59,16 +59,12 @@ namespace FreeSql int ret; try { - if (UnitOfWork == null) EmitOnEntityChange(_entityChangeReport); - else + if (UnitOfWork?.EntityChangeReport != null) { - var uow = UnitOfWork as UnitOfWork; - if (uow != null) - { - uow.EntityChangeReport.AddRange(_entityChangeReport); - if (uow.OnEntityChange == null) uow.OnEntityChange = Options.OnEntityChange; - } - } + UnitOfWork.EntityChangeReport.Report.AddRange(_entityChangeReport); + if (UnitOfWork.EntityChangeReport.OnChange == null) UnitOfWork.EntityChangeReport.OnChange = Options.OnEntityChange; + } else + EmitOnEntityChange(_entityChangeReport); } finally { diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index ea7dfa67..ff43c3b1 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -75,7 +75,7 @@ namespace FreeSql var delete = _dbset.OrmDeleteInternal(null).Where(predicate); var sql = delete.ToSql(); var affrows = delete.ExecuteAffrows(); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); return affrows; } async public Task DeleteAsync(Expression> predicate) @@ -83,7 +83,7 @@ namespace FreeSql var delete = _dbset.OrmDeleteInternal(null).Where(predicate); var sql = delete.ToSql(); var affrows = await delete.ExecuteAffrowsAsync(); - _db._entityChangeReport.Add(new DbContext.EntityChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); return affrows; } diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index f5c77638..2dc2b691 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -35,8 +35,8 @@ namespace FreeSql void Open(); /// - /// 实体变化事件 + /// 此工作单元内的实体变化跟踪 /// - Action> OnEntityChange { get; set; } + DbContext.EntityChangeReport EntityChangeReport { get; } } } diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 9167368c..8aeb4d6f 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Linq; using System.Threading; namespace FreeSql @@ -33,7 +34,7 @@ namespace FreeSql #if ns20 Current.Value = null; #endif - EntityChangeReport.Clear(); + EntityChangeReport?.Report.Clear(); } public bool Enable { get; private set; } = true; @@ -81,7 +82,8 @@ namespace FreeSql if (_tran != null) { _tran.Commit(); - OnEntityChange?.Invoke(EntityChangeReport); + if (EntityChangeReport != null && EntityChangeReport.OnChange != null && EntityChangeReport.Report.Any() == true) + EntityChangeReport.OnChange.Invoke(EntityChangeReport.Report); } } finally @@ -101,11 +103,7 @@ namespace FreeSql } } - public Action> OnEntityChange { get; set; } - /// - /// 工作单元的实体变化记录 - /// - public List EntityChangeReport { get; } = new List(); + public DbContext.EntityChangeReport EntityChangeReport { get; } = new DbContext.EntityChangeReport(); ~UnitOfWork() { From 46f290ca2ba2f66a6bca0c34a2f5b1442e1538b5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 16 Oct 2019 15:03:30 +0800 Subject: [PATCH 0195/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20FreeSqlBuild?= =?UTF-8?q?er=20=E5=A4=84=E7=90=86=20MaxLength=20=E7=89=B9=E6=80=A7?= =?UTF-8?q?=E7=9A=84=E5=AE=B9=E5=99=A8=E5=A4=84=E7=90=86=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSqlBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 154ae22b..f7e979ca 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -245,7 +245,7 @@ namespace FreeSql } catch { } - var maxlenAttr = attrs.Where(a => { + var maxlenAttr = attrs?.Where(a => { return ((a as Attribute)?.TypeId as Type)?.Name == "MaxLengthAttribute"; }).FirstOrDefault(); if (maxlenAttr != null) From 635245d3cd5e2bc0814911c5d81956c57bb09bf9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 16 Oct 2019 15:04:47 +0800 Subject: [PATCH 0196/1029] v0.10.14 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a218b192..b90f3d94 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.13 + 0.10.14 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index c906cc6c..952fb450 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ca680c76..dd2434e2 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 814fbf7a..389c9c3a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e3f5ad82..c4e0ff11 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 78a9429c..b247f583 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 4346f38d..235f8835 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 11382c83..43076597 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 1a53a5f2..e47e6604 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 73eae871..e8bf628b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 3432f5d1..7a1048ba 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 22f74037..40b3048e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 464bac3f..bd6e239f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.13 + 0.10.14 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From cb3e3b02efb52355b5619a361cc9197b2cf75700 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 16 Oct 2019 20:51:52 +0800 Subject: [PATCH 0197/1029] update functions.png --- functions04.png | Bin 83323 -> 0 bytes functions05.png | Bin 0 -> 95964 bytes readme.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 functions04.png create mode 100644 functions05.png diff --git a/functions04.png b/functions04.png deleted file mode 100644 index 48b01f8c7a6e7286624ae12ebf0d6a340a53875f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83323 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 UK1^ed2m<~o-Bpt-lQ9eae~KTb!~g&Q diff --git a/functions05.png b/functions05.png new file mode 100644 index 0000000000000000000000000000000000000000..fa3c97ba210863963376c652db5c3aedb4aa9b82 GIT binary patch literal 95964 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 - +

# Quick start From de8cf9e17da98ee171b4789b27a261d5c3580000 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 21 Oct 2019 15:14:18 +0800 Subject: [PATCH 0198/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20.Net=20Frame?= =?UTF-8?q?work=204.0=20=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=8C=E5=87=BA?= =?UTF-8?q?=E4=BA=8E=E7=8E=AF=E5=A2=83=E8=80=83=E8=99=91=20.Net=20Framewor?= =?UTF-8?q?k=204.0=20=E4=B8=8D=E6=94=AF=E6=8C=81=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20IFreeSql?= =?UTF-8?q?.Insert(IEnumerable=20source)=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs_net40/Program.cs | 261 +++++++++++++ .../orm_vs_net40/Properties/AssemblyInfo.cs | 36 ++ Examples/orm_vs_net40/orm_vs_net40.csproj | 67 ++++ .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.JsonMap/JsonMapCore.cs | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/DbContext/DbContext.cs | 21 +- FreeSql.DbContext/DbContext/DbContextAsync.cs | 4 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 4 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 4 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 7 +- .../ContextSet/RepositoryDbContext.cs | 3 + .../Repository/Repository/BaseRepository.cs | 53 +-- .../Repository/BaseRepositoryAsync.cs | 78 ++++ .../Repository/Repository/IBaseRepository.cs | 3 + .../Repository/Repository/IBasicRepository.cs | 19 +- .../Repository/IReadOnlyRepository.cs | 7 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.sln | 19 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 10 +- FreeSql/FreeSql.csproj | 8 +- FreeSql/FreeSql.xml | 8 + FreeSql/Interface/Curd/IDelete.cs | 6 +- FreeSql/Interface/Curd/IInsert.cs | 8 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 22 +- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 33 +- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 28 +- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 27 +- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 26 +- FreeSql/Interface/Curd/ISelect/ISelect4.cs | 26 +- FreeSql/Interface/Curd/ISelect/ISelect5.cs | 26 +- FreeSql/Interface/Curd/ISelect/ISelect6.cs | 26 +- FreeSql/Interface/Curd/ISelect/ISelect7.cs | 26 +- FreeSql/Interface/Curd/ISelect/ISelect8.cs | 26 +- FreeSql/Interface/Curd/ISelect/ISelect9.cs | 26 +- .../Interface/Curd/ISelect/ISelectGrouping.cs | 7 +- FreeSql/Interface/Curd/IUpdate.cs | 6 +- FreeSql/Interface/IAdo.cs | 3 + FreeSql/Interface/IFreeSql.cs | 7 + FreeSql/Internal/CommonExpression.cs | 4 +- .../AdoProvider/AdoProviderAsync.cs | 3 + .../Internal/CommonProvider/DeleteProvider.cs | 27 -- .../CommonProvider/DeleteProviderAsync.cs | 45 +++ .../Internal/CommonProvider/InsertProvider.cs | 182 +-------- .../CommonProvider/InsertProviderAsync.cs | 210 ++++++++++ .../SelectProvider/Select0Provider.cs | 365 +++++++++--------- .../SelectProvider/Select10Provider.cs | 102 ++--- .../SelectProvider/Select1Provider.cs | 112 +++--- .../SelectProvider/Select2Provider.cs | 103 ++--- .../SelectProvider/Select3Provider.cs | 103 ++--- .../SelectProvider/Select4Provider.cs | 103 ++--- .../SelectProvider/Select5Provider.cs | 103 ++--- .../SelectProvider/Select6Provider.cs | 103 ++--- .../SelectProvider/Select7Provider.cs | 103 ++--- .../SelectProvider/Select8Provider.cs | 104 ++--- .../SelectProvider/Select9Provider.cs | 107 ++--- .../SelectProvider/SelectGroupingProvider.cs | 27 +- .../Internal/CommonProvider/UpdateProvider.cs | 123 +----- .../CommonProvider/UpdateProviderAsync.cs | 145 +++++++ FreeSql/Internal/CommonUtils.cs | 4 +- FreeSql/Internal/UtilsExpressionTree.cs | 26 +- .../Curd/MySqlDelete.cs | 4 + .../Curd/MySqlInsert.cs | 63 +-- .../Curd/MySqlUpdate.cs | 86 +++-- .../FreeSql.Provider.MySql.csproj | 18 +- .../MySqlAdo/MySqlConnectionPool.cs | 7 + .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 6 +- .../FreeSql.Provider.MySql/MySqlExpression.cs | 2 +- .../FreeSql.Provider.MySql/MySqlProvider.cs | 1 + .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../Default/Curd/OdbcDelete.cs | 4 + .../Default/Curd/OdbcInsert.cs | 15 +- .../Default/Curd/OdbcUpdate.cs | 11 +- .../Default/OdbcAdo/OdbcConnectionPool.cs | 7 + .../Default/OdbcCodeFirst.cs | 6 +- .../Default/OdbcExpression.cs | 2 +- .../Default/OdbcProvider.cs | 1 + .../FreeSql.Provider.Odbc.csproj | 8 +- .../MySql/Curd/OdbcMySqlDelete.cs | 4 + .../MySql/Curd/OdbcMySqlInsert.cs | 85 ++-- .../MySql/Curd/OdbcMySqlUpdate.cs | 85 ++-- .../OdbcMySqlAdo/OdbcMySqlConnectionPool.cs | 7 + .../MySql/OdbcMySqlCodeFirst.cs | 6 +- .../MySql/OdbcMySqlExpression.cs | 2 +- .../MySql/OdbcMySqlProvider.cs | 1 + .../Oracle/Curd/OdbcOracleDelete.cs | 4 + .../Oracle/Curd/OdbcOracleInsert.cs | 30 +- .../Oracle/Curd/OdbcOracleUpdate.cs | 17 +- .../OdbcOracleAdo/OdbcOracleConnectionPool.cs | 7 + .../Oracle/OdbcOracleCodeFirst.cs | 8 +- .../Oracle/OdbcOracleExpression.cs | 2 +- .../Oracle/OdbcOracleProvider.cs | 1 + .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 4 + .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 86 +++-- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 86 +++-- .../OdbcPostgreSQLConnectionPool.cs | 7 + .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 6 +- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLProvider.cs | 1 + .../PostgreSQL/OdbcPostgreSQLUtils.cs | 8 +- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 4 + .../SqlServer/Curd/OdbcSqlServerInsert.cs | 65 ++-- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 96 ++--- .../OdbcSqlServerConnectionPool.cs | 7 + .../SqlServer/OdbcSqlServerCodeFirst.cs | 6 +- .../SqlServer/OdbcSqlServerExpression.cs | 2 +- .../SqlServer/OdbcSqlServerProvider.cs | 1 + .../Curd/OracleDelete.cs | 4 + .../Curd/OracleInsert.cs | 28 +- .../Curd/OracleUpdate.cs | 17 +- .../FreeSql.Provider.Oracle.csproj | 14 +- .../OracleAdo/OracleConnectionPool.cs | 7 + .../OracleCodeFirst.cs | 8 +- .../OracleExpression.cs | 2 +- .../FreeSql.Provider.Oracle/OracleProvider.cs | 1 + .../Curd/PostgreSQLDelete.cs | 4 + .../Curd/PostgreSQLInsert.cs | 86 +++-- .../Curd/PostgreSQLUpdate.cs | 86 +++-- .../FreeSql.Provider.PostgreSQL.csproj | 14 +- .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 7 + .../PostgreSQLTypesExtensions.cs | 36 +- .../PostgreSQLProvider.cs | 1 + .../Curd/SqlServerDelete.cs | 4 + .../Curd/SqlServerInsert.cs | 65 ++-- .../Curd/SqlServerUpdate.cs | 95 ++--- .../FreeSql.Provider.SqlServer.csproj | 16 +- .../SqlServerAdo/SqlServerConnectionPool.cs | 8 +- .../SqlServerCodeFirst.cs | 6 +- .../SqlServerExpression.cs | 2 +- .../SqlServerProvider.cs | 1 + .../Curd/SqliteDelete.cs | 4 + .../Curd/SqliteInsert.cs | 29 +- .../Curd/SqliteUpdate.cs | 17 +- .../FreeSql.Provider.Sqlite.csproj | 6 +- .../SqliteAdo/SqliteConnectionPool.cs | 36 +- .../SqliteCodeFirst.cs | 6 +- .../SqliteExpression.cs | 2 +- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 1 + readme.md | 17 +- 139 files changed, 2798 insertions(+), 1868 deletions(-) create mode 100644 Examples/orm_vs_net40/Program.cs create mode 100644 Examples/orm_vs_net40/Properties/AssemblyInfo.cs create mode 100644 Examples/orm_vs_net40/orm_vs_net40.csproj create mode 100644 FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs create mode 100644 FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs create mode 100644 FreeSql/Internal/CommonProvider/InsertProviderAsync.cs create mode 100644 FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs diff --git a/Examples/orm_vs_net40/Program.cs b/Examples/orm_vs_net40/Program.cs new file mode 100644 index 00000000..e3f572cb --- /dev/null +++ b/Examples/orm_vs_net40/Program.cs @@ -0,0 +1,261 @@ +//using SqlSugar; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace orm_vs +{ + class Program + { + static IFreeSql fsql = new FreeSql.FreeSqlBuilder() + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + .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=20") + .UseAutoSyncStructure(false) + .UseNoneCommandParameter(true) + //.UseConfigEntityFromDbFirst(true) + .Build(); + + //static SqlSugarClient sugar + //{ + // get => new SqlSugarClient(new ConnectionConfig() + // { + // //不欺负,让连接池100个最小 + // //ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + // //DbType = DbType.SqlServer, + // ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + // DbType = DbType.MySql, + // IsAutoCloseConnection = true, + // InitKeyType = InitKeyType.Attribute + // }); + //} + + static void Main(string[] args) + { + var testlist1 = fsql.Select().OrderBy(a => a.Id).ToList(); + var testlist2 = new List(); + fsql.Select().OrderBy(a => a.Id).ToChunk(0, list => + { + testlist2.AddRange(list); + }); + + fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements + + //sugar.Aop.OnLogExecuted = (s, e) => + //{ + // Trace.WriteLine(s); + //}; + //测试前清空数据 + fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); + //sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); + fsql.Ado.ExecuteNonQuery("delete from efcore_song"); + + var sb = new StringBuilder(); + Console.WriteLine("插入性能:"); + Insert(sb, 1000, 1); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(sb, 1000, 10); + Console.Write(sb.ToString()); + sb.Clear(); + + Insert(sb, 1, 1000); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(sb, 1, 10000); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(sb, 1, 50000); + Console.Write(sb.ToString()); + sb.Clear(); + Insert(sb, 1, 100000); + Console.Write(sb.ToString()); + sb.Clear(); + + Console.WriteLine("查询性能:"); + Select(sb, 1000, 1); + Console.Write(sb.ToString()); + sb.Clear(); + Select(sb, 1000, 10); + Console.Write(sb.ToString()); + sb.Clear(); + + Select(sb, 1, 1000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(sb, 1, 10000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(sb, 1, 50000); + Console.Write(sb.ToString()); + sb.Clear(); + Select(sb, 1, 100000); + Console.Write(sb.ToString()); + sb.Clear(); + + Console.WriteLine("更新:"); + Update(sb, 1000, 1); + Console.Write(sb.ToString()); + sb.Clear(); + Update(sb, 1000, 10); + Console.Write(sb.ToString()); + sb.Clear(); + + Update(sb, 1, 1000); + Console.Write(sb.ToString()); + sb.Clear(); + Update(sb, 1, 10000); + Console.Write(sb.ToString()); + sb.Clear(); + Update(sb, 1, 50000); + Console.Write(sb.ToString()); + sb.Clear(); + Update(sb, 1, 100000); + Console.Write(sb.ToString()); + sb.Clear(); + + Console.WriteLine("测试结束,按任意键退出..."); + Console.ReadKey(); + } + + static void Select(StringBuilder sb, int forTime, int size) + { + Stopwatch sw = new Stopwatch(); + sw.Restart(); + for (var a = 0; a < forTime; a++) + fsql.Select().Limit(size).ToList(); + sw.Stop(); + sb.AppendLine($"FreeSql Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + + //sw.Restart(); + //for (var a = 0; a < forTime; a++) + // sugar.Queryable().Take(size).ToList(); + //sw.Stop(); + //sb.AppendLine($"SqlSugar Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + } + + static void Insert(StringBuilder sb, int forTime, int size) + { + var songs = Enumerable.Range(0, size).Select(a => new Song + { + Create_time = DateTime.Now, + Is_deleted = false, + Title = $"Insert_{a}", + Url = $"Url_{a}" + }); + + //预热 + fsql.Insert(songs.First()).ExecuteAffrows(); + //sugar.Insertable(songs.First()).ExecuteCommand(); + Stopwatch sw = new Stopwatch(); + + sw.Restart(); + for (var a = 0; a < forTime; a++) + { + fsql.Insert(songs).ExecuteAffrows(); + //using (var db = new FreeSongContext()) { + // //db.Configuration.AutoDetectChangesEnabled = false; + // db.Songs.AddRange(songs.ToArray()); + // db.SaveChanges(); + //} + } + sw.Stop(); + sb.AppendLine($"FreeSql Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + + //sw.Restart(); + //Exception sugarEx = null; + //try + //{ + // for (var a = 0; a < forTime; a++) + // sugar.Insertable(songs.ToArray()).ExecuteCommand(); + //} + //catch (Exception ex) + //{ + // sugarEx = ex; + //} + //sw.Stop(); + //sb.AppendLine($"SqlSugar Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms" + (sugarEx != null ? $"成绩无效,错误:{sugarEx.Message}" : "")); + } + + static void Update(StringBuilder sb, int forTime, int size) + { + Stopwatch sw = new Stopwatch(); + + var songs = fsql.Select().Limit(size).ToList(); + sw.Restart(); + for (var a = 0; a < forTime; a++) + { + fsql.Update().SetSource(songs).ExecuteAffrows(); + } + sw.Stop(); + sb.AppendLine($"FreeSql Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + + //songs = sugar.Queryable().Take(size).ToList(); + //sw.Restart(); + //Exception sugarEx = null; + //try + //{ + // for (var a = 0; a < forTime; a++) + // sugar.Updateable(songs).ExecuteCommand(); + //} + //catch (Exception ex) + //{ + // sugarEx = ex; + //} + //sw.Stop(); + //sb.AppendLine($"SqlSugar Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms" + (sugarEx != null ? $"成绩无效,错误:{sugarEx.Message}" : "")); + } + } + + [FreeSql.DataAnnotations.Table(Name = "freesql_song")] + //[SugarTable("sugar_song")] + public class Song + { + [FreeSql.DataAnnotations.Column(IsIdentity = true)] + //[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + //[SugarColumn(IsIgnore = true)] + public virtual ICollection Tags { get; set; } + } + [FreeSql.DataAnnotations.Table(Name = "freesql_song_tag")] + //[SugarTable("sugar_song_tag")] + public class Song_tag + { + public int Song_id { get; set; } + //[SugarColumn(IsIgnore = true)] + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + //[SugarColumn(IsIgnore = true)] + public virtual Tag Tag { get; set; } + } + [FreeSql.DataAnnotations.Table(Name = "freesql_tag")] + //[SugarTable("sugar_tag")] + public class Tag + { + [FreeSql.DataAnnotations.Column(IsIdentity = true)] + //[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + //[SugarColumn(IsIgnore = true)] + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + //[SugarColumn(IsIgnore = true)] + public virtual ICollection Songs { get; set; } + //[SugarColumn(IsIgnore = true)] + public virtual ICollection Tags { get; set; } + } +} diff --git a/Examples/orm_vs_net40/Properties/AssemblyInfo.cs b/Examples/orm_vs_net40/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..608091ec --- /dev/null +++ b/Examples/orm_vs_net40/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("orm_vs_net40")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("orm_vs_net40")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("1674bce3-eeb4-4003-a2a7-06f51efaea23")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Examples/orm_vs_net40/orm_vs_net40.csproj b/Examples/orm_vs_net40/orm_vs_net40.csproj new file mode 100644 index 00000000..581a3ccb --- /dev/null +++ b/Examples/orm_vs_net40/orm_vs_net40.csproj @@ -0,0 +1,67 @@ + + + + + Debug + AnyCPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23} + Exe + orm_vs_net40 + orm_vs_net40 + v4.0 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + {af9c50ec-6eb6-494b-9b3b-7edba6fd0ebb} + FreeSql + + + {28c6a39c-7ae7-4210-b7b0-0970216637a8} + FreeSql.Provider.MySql + + + {b61aac9e-59e9-4f47-bbe3-97ac24112efe} + FreeSql.Provider.SqlServer + + + + + 12.0.2 + + + + \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 952fb450..0180cb68 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net45;net40 0.10.14 true YeXiangQin diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index e5593617..a8630d74 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -37,7 +37,7 @@ namespace FreeSql.Extensions that.Aop.ConfigEntityProperty += new EventHandler((s, e) => { - if (e.Property.GetCustomAttribute(false) != null) + if (e.Property.GetCustomAttributes(typeof(JsonMapAttribute), false).Any()) { e.ModifyResult.MapType = typeof(string); if (_dicTypes.TryAdd(e.Property.PropertyType, true)) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index dd2434e2..ee3d60bf 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net45;net40 0.10.14 true YeXiangQin diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index f9d1d4f0..c9d86010 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -72,13 +72,13 @@ namespace FreeSql var props = _dicGetDbSetProps.GetOrAdd(this.GetType(), tp => tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) .Where(a => a.PropertyType.IsGenericType && - a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GenericTypeArguments[0])).ToArray()); + a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GetGenericArguments()[0])).ToArray()); foreach (var prop in props) { - var set = this.Set(prop.PropertyType.GenericTypeArguments[0]); + var set = this.Set(prop.PropertyType.GetGenericArguments()[0]); - prop.SetValue(this, set); + prop.SetValue(this, set, null); AllSets.Add(prop.Name, set); } } @@ -105,8 +105,6 @@ namespace FreeSql /// public void Add(TEntity data) where TEntity : class => this.Set().Add(data); public void AddRange(IEnumerable data) where TEntity : class => this.Set().AddRange(data); - public Task AddAsync(TEntity data) where TEntity : class => this.Set().AddAsync(data); - public Task AddRangeAsync(IEnumerable data) where TEntity : class => this.Set().AddRangeAsync(data); /// /// 更新 @@ -115,8 +113,6 @@ namespace FreeSql /// public void Update(TEntity data) where TEntity : class => this.Set().Update(data); public void UpdateRange(IEnumerable data) where TEntity : class => this.Set().UpdateRange(data); - public Task UpdateAsync(TEntity data) where TEntity : class => this.Set().UpdateAsync(data); - public Task UpdateRangeAsync(IEnumerable data) where TEntity : class => this.Set().UpdateRangeAsync(data); /// /// 删除 @@ -132,7 +128,6 @@ namespace FreeSql /// /// public void AddOrUpdate(TEntity data) where TEntity : class => this.Set().AddOrUpdate(data); - public Task AddOrUpdateAsync(TEntity data) where TEntity : class => this.Set().AddOrUpdateAsync(data); /// /// 附加实体,可用于不查询就更新或删除 @@ -152,6 +147,16 @@ namespace FreeSql this.Set().AttachOnlyPrimary(data); return this; } +#if net40 +#else + public Task AddAsync(TEntity data) where TEntity : class => this.Set().AddAsync(data); + public Task AddRangeAsync(IEnumerable data) where TEntity : class => this.Set().AddRangeAsync(data); + + public Task UpdateAsync(TEntity data) where TEntity : class => this.Set().UpdateAsync(data); + public Task UpdateRangeAsync(IEnumerable data) where TEntity : class => this.Set().UpdateRangeAsync(data); + + public Task AddOrUpdateAsync(TEntity data) where TEntity : class => this.Set().AddOrUpdateAsync(data); +#endif #endregion #region Queue Action diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 61e6a258..4cac04a2 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -5,11 +5,12 @@ using System.Reflection; using System.Linq.Expressions; using System.Threading.Tasks; +#if net40 +#else namespace FreeSql { partial class DbContext { - async public virtual Task SaveChangesAsync() { await ExecCommandAsync(); @@ -133,3 +134,4 @@ namespace FreeSql } } } +#endif \ No newline at end of file diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 1696fe30..33f26e2a 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -8,11 +8,12 @@ using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; +#if net40 +#else namespace FreeSql { partial class DbSet { - Task DbContextExecCommandAsync() { _dicUpdateTimes.Clear(); @@ -409,3 +410,4 @@ namespace FreeSql #endregion } } +#endif \ No newline at end of file diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index a0aeddf1..35f8b091 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -169,11 +169,11 @@ namespace FreeSql var lazyFieldValue = (bool)lazyField.GetValue(item); if (lazyFieldValue == false) continue; } - propVal = prop.Value.GetValue(item); + propVal = prop.Value.GetValue(item, null); } else { - propVal = prop.Value.GetValue(item); + propVal = prop.Value.GetValue(item, null); if (propVal == null) continue; } diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 389c9c3a..002dc390 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net45;net40 0.10.14 true YeXiangQin @@ -29,7 +29,10 @@ ns20;netstandard20 - + + net40 + + diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index b09d7463..978a952b 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -79,10 +79,13 @@ namespace FreeSql ExecCommand(); return SaveChangesSuccess(); } +#if net40 +#else async public override Task SaveChangesAsync() { await ExecCommandAsync(); return SaveChangesSuccess(); } +#endif } } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index ff43c3b1..723b545e 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - public abstract class BaseRepository : IBaseRepository + public abstract partial class BaseRepository : IBaseRepository where TEntity : class { @@ -78,35 +78,17 @@ namespace FreeSql _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); return affrows; } - async public Task DeleteAsync(Expression> predicate) - { - var delete = _dbset.OrmDeleteInternal(null).Where(predicate); - var sql = delete.ToSql(); - var affrows = await delete.ExecuteAffrowsAsync(); - _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); - return affrows; - } public int Delete(TEntity entity) { _dbset.Remove(entity); return _db.SaveChanges(); } - public Task DeleteAsync(TEntity entity) - { - _dbset.Remove(entity); - return _db.SaveChangesAsync(); - } public int Delete(IEnumerable entitys) { _dbset.RemoveRange(entitys); return _db.SaveChanges(); } - public Task DeleteAsync(IEnumerable entitys) - { - _dbset.RemoveRange(entitys); - return _db.SaveChangesAsync(); - } public virtual TEntity Insert(TEntity entity) { @@ -114,45 +96,23 @@ namespace FreeSql _db.SaveChanges(); return entity; } - async public virtual Task InsertAsync(TEntity entity) - { - await _dbset.AddAsync(entity); - _db.SaveChanges(); - return entity; - } public virtual List Insert(IEnumerable entitys) { _dbset.AddRange(entitys); _db.SaveChanges(); return entitys.ToList(); } - async public virtual Task> InsertAsync(IEnumerable entitys) - { - await _dbset.AddRangeAsync(entitys); - await _db.SaveChangesAsync(); - return entitys.ToList(); - } public int Update(TEntity entity) { _dbset.Update(entity); return _db.SaveChanges(); } - public Task UpdateAsync(TEntity entity) - { - _dbset.Update(entity); - return _db.SaveChangesAsync(); - } public int Update(IEnumerable entitys) { _dbset.UpdateRange(entitys); return _db.SaveChanges(); } - public Task UpdateAsync(IEnumerable entitys) - { - _dbset.UpdateRange(entitys); - return _db.SaveChangesAsync(); - } public void Attach(TEntity data) => _db.Attach(data); public void Attach(IEnumerable data) => _db.AttachRange(data); @@ -169,15 +129,9 @@ namespace FreeSql _db.SaveChanges(); return entity; } - async public Task InsertOrUpdateAsync(TEntity entity) - { - await _dbset.AddOrUpdateAsync(entity); - _db.SaveChanges(); - return entity; - } } - public abstract class BaseRepository : BaseRepository, IBaseRepository + public abstract partial class BaseRepository : BaseRepository, IBaseRepository where TEntity : class { @@ -198,12 +152,9 @@ namespace FreeSql } public int Delete(TKey id) => Delete(CheckTKeyAndReturnIdEntity(id)); - public Task DeleteAsync(TKey id) => DeleteAsync(CheckTKeyAndReturnIdEntity(id)); public TEntity Find(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); - public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(); public TEntity Get(TKey id) => Find(id); - public Task GetAsync(TKey id) => FindAsync(id); } } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs new file mode 100644 index 00000000..0cfcba4d --- /dev/null +++ b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs @@ -0,0 +1,78 @@ +using FreeSql.Extensions.EntityUtil; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +#if net40 +#else +namespace FreeSql +{ + partial class BaseRepository + where TEntity : class + { + + async public Task DeleteAsync(Expression> predicate) + { + var delete = _dbset.OrmDeleteInternal(null).Where(predicate); + var sql = delete.ToSql(); + var affrows = await delete.ExecuteAffrowsAsync(); + _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); + return affrows; + } + + public Task DeleteAsync(TEntity entity) + { + _dbset.Remove(entity); + return _db.SaveChangesAsync(); + } + public Task DeleteAsync(IEnumerable entitys) + { + _dbset.RemoveRange(entitys); + return _db.SaveChangesAsync(); + } + + async public virtual Task InsertAsync(TEntity entity) + { + await _dbset.AddAsync(entity); + _db.SaveChanges(); + return entity; + } + async public virtual Task> InsertAsync(IEnumerable entitys) + { + await _dbset.AddRangeAsync(entitys); + await _db.SaveChangesAsync(); + return entitys.ToList(); + } + + public Task UpdateAsync(TEntity entity) + { + _dbset.Update(entity); + return _db.SaveChangesAsync(); + } + public Task UpdateAsync(IEnumerable entitys) + { + _dbset.UpdateRange(entitys); + return _db.SaveChangesAsync(); + } + + async public Task InsertOrUpdateAsync(TEntity entity) + { + await _dbset.AddOrUpdateAsync(entity); + _db.SaveChanges(); + return entity; + } + } + + partial class BaseRepository + { + + public Task DeleteAsync(TKey id) => DeleteAsync(CheckTKeyAndReturnIdEntity(id)); + + public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(); + + public Task GetAsync(TKey id) => FindAsync(id); + } +} +#endif \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index effe252b..5ea1f28b 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -29,7 +29,10 @@ namespace FreeSql { int Delete(Expression> predicate); +#if net40 +#else Task DeleteAsync(Expression> predicate); +#endif } public interface IBaseRepository : IBaseRepository, IReadOnlyRepository, IBasicRepository diff --git a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs index 5f2ba98a..6c56cd5c 100644 --- a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs @@ -8,8 +8,6 @@ namespace FreeSql { TEntity Insert(TEntity entity); List Insert(IEnumerable entitys); - Task InsertAsync(TEntity entity); - Task> InsertAsync(IEnumerable entitys); /// /// 清空状态数据 @@ -29,18 +27,26 @@ namespace FreeSql int Update(TEntity entity); int Update(IEnumerable entitys); - Task UpdateAsync(TEntity entity); - Task UpdateAsync(IEnumerable entitys); TEntity InsertOrUpdate(TEntity entity); - Task InsertOrUpdateAsync(TEntity entity); IUpdate UpdateDiy { get; } int Delete(TEntity entity); int Delete(IEnumerable entitys); + +#if net40 +#else + Task InsertAsync(TEntity entity); + Task> InsertAsync(IEnumerable entitys); + + Task UpdateAsync(TEntity entity); + Task UpdateAsync(IEnumerable entitys); + Task InsertOrUpdateAsync(TEntity entity); + Task DeleteAsync(TEntity entity); Task DeleteAsync(IEnumerable entitys); +#endif } public interface IBasicRepository : IBasicRepository, IReadOnlyRepository @@ -48,7 +54,10 @@ namespace FreeSql { int Delete(TKey id); +#if net40 +#else Task DeleteAsync(TKey id); +#endif } } diff --git a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs b/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs index 76728a9c..bd96458f 100644 --- a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs @@ -20,11 +20,12 @@ namespace FreeSql where TEntity : class { TEntity Get(TKey id); - - Task GetAsync(TKey id); - TEntity Find(TKey id); +#if net40 +#else + Task GetAsync(TKey id); Task FindAsync(TKey id); +#endif } } diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c4e0ff11..c42182df 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net45;net40 0.10.14 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. diff --git a/FreeSql.sln b/FreeSql.sln index 1d8b4c4c..3464c254 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29324.140 MinimumVisualStudioVersion = 15.0.26124.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql", "FreeSql\FreeSql.csproj", "{AF9C50EC-6EB6-494B-9B3B-7EDBA6FD0EBB}" EndProject @@ -64,6 +64,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Odbc", "Pr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Odbc", "FreeSql.Tests\FreeSql.Tests.Provider.Odbc\FreeSql.Tests.Provider.Odbc.csproj", "{FA5667B9-BA85-4970-8818-BF09DD8DA3B4}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "orm_vs_net40", "Examples\orm_vs_net40\orm_vs_net40.csproj", "{1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -374,6 +376,18 @@ Global {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|x64.Build.0 = Release|Any CPU {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|x86.ActiveCfg = Release|Any CPU {FA5667B9-BA85-4970-8818-BF09DD8DA3B4}.Release|x86.Build.0 = Release|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Debug|x64.ActiveCfg = Debug|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Debug|x64.Build.0 = Debug|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Debug|x86.ActiveCfg = Debug|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Debug|x86.Build.0 = Debug|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|Any CPU.Build.0 = Release|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|x64.ActiveCfg = Release|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|x64.Build.0 = Release|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|x86.ActiveCfg = Release|Any CPU + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -396,6 +410,7 @@ Global {FE0CB06E-493F-4CE8-B2D7-BF48CA8015C6} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {3043DEF1-85DF-47AD-8D5D-327270794356} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {C57444BA-8BF7-4790-A864-7F237123219B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 071a0904..1d935c43 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -40,7 +40,7 @@ public static partial class FreeSqlGlobalExtensions public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that); public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true; public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; - public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GenericTypeArguments.First() : that; + public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that; internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args)); /// @@ -64,15 +64,17 @@ public static partial class FreeSqlGlobalExtensions var value = dr.GetString(index); var t = typeof(T); var fs = _dicGetFields.GetOrAdd(t, t2 => t2.GetFields()); - foreach (var f in fs) - if (f.GetCustomAttribute()?.Description == value || f.Name == value) return Enum.Parse(t, f.Name, true); + foreach (var f in fs) { + var attr = f.GetCustomAttributes(typeof(DescriptionAttribute), false)?.FirstOrDefault() as DescriptionAttribute; + if (attr?.Description == value || f.Name == value) return Enum.Parse(t, f.Name, true); + } return null; } public static string ToDescriptionOrString(this Enum item) { string name = item.ToString(); - var desc = item.GetType().GetField(name)?.GetCustomAttribute(); + var desc = item.GetType().GetField(name)?.GetCustomAttributes(typeof(DescriptionAttribute), false)?.FirstOrDefault() as DescriptionAttribute; return desc?.Description ?? name; } public static long ToInt64(this Enum item) diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b247f583..0f97b3ca 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net45;net40 0.10.14 true YeXiangQin @@ -28,8 +28,12 @@ - + + + net40 + + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6179f8fa..003ef946 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2711,6 +2711,14 @@ + + + 插入数据,传入实体集合 + + + + + 修改数据 diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index b038153f..a9ba7831 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -84,12 +84,16 @@ namespace FreeSql /// /// int ExecuteAffrows(); - Task ExecuteAffrowsAsync(); /// /// 执行SQL语句,返回被删除的记录 /// /// List ExecuteDeleted(); + +#if net40 +#else + Task ExecuteAffrowsAsync(); Task> ExecuteDeletedAsync(); +#endif } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index aa43198c..9a246642 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -88,18 +88,22 @@ namespace FreeSql /// /// int ExecuteAffrows(); - Task ExecuteAffrowsAsync(); /// /// 执行SQL语句,返回自增值 /// /// long ExecuteIdentity(); - Task ExecuteIdentityAsync(); /// /// 执行SQL语句,返回插入后的记录 /// /// List ExecuteInserted(); + +#if net40 +#else + Task ExecuteAffrowsAsync(); + Task ExecuteIdentityAsync(); Task> ExecuteInsertedAsync(); +#endif } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index eb1773ba..e115fabf 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -8,9 +8,22 @@ using System.Threading.Tasks; namespace FreeSql { - public interface ISelect0 + public partial interface ISelect0 { +#if net40 +#else + Task ToDataTableAsync(string field = null); + Task> ToListAsync(bool includeNestedMembers = false); + Task> ToListAsync(string field); + + Task ToOneAsync(); + Task FirstAsync(); + + Task AnyAsync(); + Task CountAsync(); +#endif + /// /// 指定事务对象 /// @@ -36,7 +49,6 @@ namespace FreeSql /// /// DataTable ToDataTable(string field = null); - Task ToDataTableAsync(string field = null); /// /// 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 @@ -44,7 +56,6 @@ namespace FreeSql /// false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 /// List ToList(bool includeNestedMembers = false); - Task> ToListAsync(bool includeNestedMembers = false); /// /// 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 /// @@ -59,20 +70,17 @@ namespace FreeSql /// /// List ToList(string field); - Task> ToListAsync(string field); /// /// 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null /// /// T1 ToOne(); - Task ToOneAsync(); /// /// 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null /// /// T1 First(); - Task FirstAsync(); /// /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; @@ -103,14 +111,12 @@ namespace FreeSql /// /// bool Any(); - Task AnyAsync(); /// /// 查询的记录数量 /// /// long Count(); - Task CountAsync(); /// /// 查询的记录数量,以参数out形式返回 /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 8fc5e393..a5dc052c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -9,20 +9,38 @@ namespace FreeSql public interface ISelect : ISelect0, T1>, ILinqToSql where T1 : class { +#if net40 +#else + Task AnyAsync(Expression> exp); + + Task ToDataTableAsync(Expression> select); + Task> ToListAsync(Expression> select); + Task> ToListAsync(); + + Task ToOneAsync(Expression> select); + Task ToOneAsync(); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, TReturn>> select); + Task SumAsync(Expression> column); + Task MinAsync(Expression> column); + Task MaxAsync(Expression> column); + Task AvgAsync(Expression> column); +#endif + /// /// 执行SQL查询,是否有记录 /// /// lambda表达式 /// bool Any(Expression> exp); - Task AnyAsync(Expression> exp); /// /// 执行SQL查询,返回 DataTable /// /// DataTable ToDataTable(Expression> select); - Task ToDataTableAsync(Expression> select); /// /// 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 @@ -31,14 +49,12 @@ namespace FreeSql /// 选择列 /// List ToList(Expression> select); - Task> ToListAsync(Expression> select); /// /// 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 /// /// /// List ToList(); - Task> ToListAsync(); /// /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 @@ -47,14 +63,12 @@ namespace FreeSql /// 选择列 /// TReturn ToOne(Expression> select); - Task ToOneAsync(Expression> select); /// /// 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 /// /// /// TDto ToOne(); - Task ToOneAsync(); /// /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 @@ -63,14 +77,12 @@ namespace FreeSql /// 选择列 /// TReturn First(Expression> select); - Task FirstAsync(Expression> select); /// /// 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 /// /// /// TDto First(); - Task FirstAsync(); /// /// 返回即将执行的SQL语句 @@ -87,7 +99,6 @@ namespace FreeSql /// /// TReturn ToAggregate(Expression, TReturn>> select); - Task ToAggregateAsync(Expression, TReturn>> select); /// /// 求和 @@ -96,7 +107,6 @@ namespace FreeSql /// 列 /// TMember Sum(Expression> column); - Task SumAsync(Expression> column); /// /// 最小值 /// @@ -104,7 +114,6 @@ namespace FreeSql /// 列 /// TMember Min(Expression> column); - Task MinAsync(Expression> column); /// /// 最大值 /// @@ -112,7 +121,6 @@ namespace FreeSql /// 列 /// TMember Max(Expression> column); - Task MaxAsync(Expression> column); /// /// 平均值 /// @@ -120,7 +128,6 @@ namespace FreeSql /// 列 /// TMember Avg(Expression> column); - Task AvgAsync(Expression> column); /// /// 指定别名 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 11cb5e76..83cc7949 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -9,29 +9,31 @@ namespace FreeSql 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 { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - - TMember Sum(Expression> column); + Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 0b6c271b..98d24ad7 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -9,30 +9,31 @@ namespace FreeSql public interface ISelect : ISelect0, T1> where T1 : class where T2 : class { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index e890ca75..ee60a5b0 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -9,29 +9,31 @@ namespace FreeSql public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index da0a140e..57640478 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -9,29 +9,31 @@ namespace FreeSql public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index 28198dd0..3b94ff28 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -9,29 +9,31 @@ namespace FreeSql public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 01a2b3ed..97c6c05c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -9,29 +9,31 @@ namespace FreeSql public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index ca2f6a82..80d7bc72 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -9,29 +9,31 @@ namespace FreeSql 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 { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index c77040b1..976ca71b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -9,29 +9,31 @@ namespace FreeSql 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 { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index feba4958..0960ea22 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -9,29 +9,31 @@ namespace FreeSql 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 { - bool Any(Expression> exp); +#if net40 +#else Task AnyAsync(Expression> exp); - DataTable ToDataTable(Expression> select); Task ToDataTableAsync(Expression> select); - - List ToList(Expression> select); Task> ToListAsync(Expression> select); - List ToList(); Task> ToListAsync(); - string ToSql(Expression> select); - - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); Task SumAsync(Expression> column); - TMember Min(Expression> column); Task MinAsync(Expression> column); - TMember Max(Expression> column); Task MaxAsync(Expression> column); - TMember Avg(Expression> column); Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + string ToSql(Expression> select); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + TMember Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + TMember Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index eac8339d..7cfb0f7e 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -8,6 +8,12 @@ namespace FreeSql { public interface ISelectGrouping { + +#if net40 +#else + Task> ToListAsync(Expression, TReturn>> select); +#endif + /// /// 按聚合条件过滤,Where(a => a.Count() > 10) /// @@ -36,7 +42,6 @@ namespace FreeSql /// 选择列 /// List ToList(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); /// /// 【linq to sql】专用方法,不建议直接使用 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 857b6169..ff023c78 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -153,12 +153,16 @@ namespace FreeSql /// /// int ExecuteAffrows(); - Task ExecuteAffrowsAsync(); /// /// 执行SQL语句,返回更新后的记录 /// /// List ExecuteUpdated(); + +#if net40 +#else + Task ExecuteAffrowsAsync(); Task> ExecuteUpdatedAsync(); +#endif } } \ No newline at end of file diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index a1d16be1..fd86d18c 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -219,6 +219,8 @@ namespace FreeSql (List, List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); +#if net40 +#else #region async /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 @@ -389,5 +391,6 @@ namespace FreeSql Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); #endregion +#endif } } diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index 7910aa6a..f60fb182 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -33,6 +33,13 @@ public interface IFreeSql : IDisposable /// /// IInsert Insert(List source) where T1 : class; + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + IInsert Insert(IEnumerable source) where T1 : class; /// /// 修改数据 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 4fc329c6..bb2c63d0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -617,7 +617,7 @@ namespace FreeSql.Internal var exp3tmpArg1Type = exp3tmpCall.Arguments.FirstOrDefault()?.Type; if (exp3tmpArg1Type != null) { - asSelectEntityType = exp3tmpArg1Type.GetElementType() ?? exp3tmpArg1Type.GenericTypeArguments.FirstOrDefault(); + asSelectEntityType = exp3tmpArg1Type.GetElementType() ?? exp3tmpArg1Type.GetGenericArguments().FirstOrDefault(); if (asSelectEntityType != null) { fsql = _dicExpressionLambdaToSqlAsSelectMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType2 => typeof(IFreeSql).GetMethod("Select", new Type[0]).MakeGenericMethod(asSelectEntityType2)) @@ -1051,7 +1051,7 @@ namespace FreeSql.Internal case ExpressionType.MemberAccess: var exp2Type = exp2.Type; - if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GenericTypeArguments.LastOrDefault() ?? exp2.Type; + if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GetGenericArguments().LastOrDefault() ?? exp2.Type; var tb2tmp = _common.GetTableByEntity(exp2Type); var mp2 = exp2 as MemberExpression; if (mp2?.Member.Name == "Key" && mp2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) continue; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 4a672d94..a9b154ae 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -7,6 +7,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +#if net40 +#else namespace FreeSql.Internal.CommonProvider { partial class AdoProvider @@ -729,3 +731,4 @@ namespace FreeSql.Internal.CommonProvider } } } +#endif \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 45af15e9..a28e7a75 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -79,34 +79,7 @@ namespace FreeSql.Internal.CommonProvider this.ClearData(); return affrows; } - async public Task ExecuteAffrowsAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try - { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return affrows; - } public abstract List ExecuteDeleted(); - public abstract Task> ExecuteDeletedAsync(); public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null)); public IDelete Where(string sql, object parms = null) diff --git a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs new file mode 100644 index 00000000..9860c999 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs @@ -0,0 +1,45 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + partial class DeleteProvider + { +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return affrows; + } + public abstract Task> ExecuteDeletedAsync(); +#endif + } +} diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index a6e65ed5..1130da06 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -224,57 +224,7 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } - async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) - { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = 0; - if (ss.Any() == false) - { - ClearData(); - return ret; - } - if (ss.Length == 1) - { - ret = await this.RawExecuteAffrowsAsync(); - ClearData(); - return ret; - } - if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - } - else - { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } protected long SplitExecuteIdentity(int valuesLimit, int parameterLimit) { var ss = SplitSource(valuesLimit, parameterLimit); @@ -328,59 +278,7 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } - async protected Task SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit) - { - var ss = SplitSource(valuesLimit, parameterLimit); - long ret = 0; - if (ss.Any() == false) - { - ClearData(); - return ret; - } - if (ss.Length == 1) - { - ret = await this.RawExecuteIdentityAsync(); - ClearData(); - return ret; - } - if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); - else ret = await this.RawExecuteIdentityAsync(); - } - } - else - { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); - else ret = await this.RawExecuteIdentityAsync(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } protected List SplitExecuteInserted(int valuesLimit, int parameterLimit) { var ss = SplitSource(valuesLimit, parameterLimit); @@ -432,57 +330,6 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } - async protected Task> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) - { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = new List(); - if (ss.Any() == false) - { - ClearData(); - return ret; - } - if (ss.Length == 1) - { - ret = await this.RawExecuteInsertedAsync(); - ClearData(); - return ret; - } - if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); - - if (_transaction != null) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret.AddRange(await this.RawExecuteInsertedAsync()); - } - } - else - { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret.AddRange(await this.RawExecuteInsertedAsync()); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } #endregion protected int RawExecuteAffrows() @@ -508,40 +355,13 @@ namespace FreeSql.Internal.CommonProvider } return affrows; } - async protected Task RawExecuteAffrowsAsync() - { - var sql = ToSql(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try - { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return affrows; - } + protected abstract long RawExecuteIdentity(); - protected abstract Task RawExecuteIdentityAsync(); protected abstract List RawExecuteInserted(); - protected abstract Task> RawExecuteInsertedAsync(); public abstract int ExecuteAffrows(); - public abstract Task ExecuteAffrowsAsync(); public abstract long ExecuteIdentity(); - public abstract Task ExecuteIdentityAsync(); public abstract List ExecuteInserted(); - public abstract Task> ExecuteInsertedAsync(); public IInsert IgnoreColumns(Expression> columns) { diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs new file mode 100644 index 00000000..018cb81a --- /dev/null +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -0,0 +1,210 @@ +using FreeSql.Internal.Model; +using SafeObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + partial class InsertProvider + { +#if net40 +#else + async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = 0; + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = await this.RawExecuteAffrowsAsync(); + ClearData(); + return ret; + } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + + async protected Task SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + long ret = 0; + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = await this.RawExecuteIdentityAsync(); + ClearData(); + return ret; + } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); + else ret = await this.RawExecuteIdentityAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); + else ret = await this.RawExecuteIdentityAsync(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + + async protected Task> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = new List(); + if (ss.Any() == false) + { + ClearData(); + return ret; + } + if (ss.Length == 1) + { + ret = await this.RawExecuteInsertedAsync(); + ClearData(); + return ret; + } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteInsertedAsync()); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteInsertedAsync()); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + + async protected Task RawExecuteAffrowsAsync() + { + var sql = ToSql(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return affrows; + } + + protected abstract Task RawExecuteIdentityAsync(); + protected abstract Task> RawExecuteInsertedAsync(); + + public abstract Task ExecuteAffrowsAsync(); + public abstract Task ExecuteIdentityAsync(); + public abstract Task> ExecuteInsertedAsync(); +#endif + } +} + diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 2a1b90d3..93321ad1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -15,7 +15,7 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract class Select0Provider : ISelect0 where TSelect : class where T1 : class + public abstract partial class Select0Provider : ISelect0 where TSelect : class where T1 : class { protected int _limit, _skip; @@ -130,14 +130,8 @@ namespace FreeSql.Internal.CommonProvider this.Limit(1); return this.ToList("1").FirstOrDefault() == 1; } - async public Task AnyAsync() - { - this.Limit(1); - return (await this.ToListAsync("1")).FirstOrDefault() == 1; - } public long Count() => this.ToList("count(1)").FirstOrDefault(); - async public Task CountAsync() => (await this.ToListAsync("count(1)")).FirstOrDefault(); public TSelect Count(out long count) { @@ -285,30 +279,6 @@ namespace FreeSql.Internal.CommonProvider } return ret; } - async public Task ToDataTableAsync(string field = null) - { - var sql = this.ToSql(field); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; - try - { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } public List ToList(string field) { @@ -340,37 +310,6 @@ namespace FreeSql.Internal.CommonProvider } return ret; } - async public Task> ToListAsync(string field) - { - var sql = this.ToSql(field); - var type = typeof(TTuple); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - var flagStr = $"ToListField:{field}"; - Exception exception = null; - try - { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => - { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); - ret.Add((TTuple)read.Value); - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { var dbParms = _params.ToArray(); @@ -406,42 +345,6 @@ namespace FreeSql.Internal.CommonProvider _trackToList?.Invoke(ret); return ret; } - async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) - { - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => - { - ret.Add(af.Read(_orm, dr)); - if (otherData != null) - { - var idx = af.FieldCount - 1; - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); - } - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - foreach (var include in _includeToList) include?.Invoke(ret); - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); - _trackToList?.Invoke(ret); - return ret; - } internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { string sql = null; @@ -457,21 +360,6 @@ namespace FreeSql.Internal.CommonProvider return ToListAfPrivate(sql, af, otherData); } - internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) - { - string sql = null; - if (otherData?.Length > 0) - { - var sbField = new StringBuilder().Append(af.Field); - foreach (var other in otherData) - sbField.Append(other.field); - sql = this.ToSql(sbField.ToString()); - } - else - sql = this.ToSql(af.Field); - - return ToListAfPrivateAsync(sql, af, otherData); - } #region ToChunk internal void ToListAfChunkPrivate(int chunkSize, Action> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { @@ -555,24 +443,13 @@ namespace FreeSql.Internal.CommonProvider if (_selectExpression != null) return this.InternalToList(_selectExpression); return this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); } - public virtual Task> ToListAsync(bool includeNestedMembers = false) - { - if (_selectExpression != null) return this.InternalToListAsync(_selectExpression); - return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); - } public T1 ToOne() { this.Limit(1); return this.ToList().FirstOrDefault(); } - async public Task ToOneAsync() - { - this.Limit(1); - return (await this.ToListAsync()).FirstOrDefault(); - } public T1 First() => this.ToOne(); - public Task FirstAsync() => this.ToOneAsync(); protected List ToListMapReader((ReadAnonymousTypeInfo map, string field) af) { @@ -605,38 +482,6 @@ namespace FreeSql.Internal.CommonProvider _trackToList?.Invoke(ret); return ret; } - async protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) - { - var sql = this.ToSql(af.field); - var type = typeof(TReturn); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => - { - var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); - _trackToList?.Invoke(ret); - return ret; - } protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) { var map = new ReadAnonymousTypeInfo(); @@ -872,7 +717,7 @@ namespace FreeSql.Internal.CommonProvider else { var proptypeGeneric = prop.PropertyType; - if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GetGenericArguments().First(); if (proptypeGeneric.IsEnum || Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor, Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)), @@ -1042,13 +887,9 @@ namespace FreeSql.Internal.CommonProvider #region common protected TMember InternalAvg(Expression exp) => this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - async protected Task InternalAvgAsync(Expression exp) => (await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); protected TMember InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); protected ISelectGrouping InternalGroupBy(Expression columns) { @@ -1077,7 +918,6 @@ namespace FreeSql.Internal.CommonProvider protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); protected List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); - protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); protected string InternalToSql(Expression select) { var af = this.GetExpressionField(select); @@ -1108,6 +948,194 @@ namespace FreeSql.Internal.CommonProvider } return ret; } + + protected TReturn InternalToAggregate(Expression select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression); + return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); + } + + protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression)); + #endregion + +#if net40 +#else + async public Task AnyAsync() + { + this.Limit(1); + return (await this.ToListAsync("1")).FirstOrDefault() == 1; + } + + async public Task CountAsync() => (await this.ToListAsync("count(1)")).FirstOrDefault(); + + async public Task ToDataTableAsync(string field = null) + { + var sql = this.ToSql(field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + async public Task> ToListAsync(string field) + { + var sql = this.ToSql(field); + var type = typeof(TTuple); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + var flagStr = $"ToListField:{field}"; + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + { + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); + ret.Add((TTuple)read.Value); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + { + ret.Add(af.Read(_orm, dr)); + if (otherData != null) + { + var idx = af.FieldCount - 1; + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + } + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + foreach (var include in _includeToList) include?.Invoke(ret); + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); + _trackToList?.Invoke(ret); + return ret; + } + + internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.Field); + + return ToListAfPrivateAsync(sql, af, otherData); + } + + public virtual Task> ToListAsync(bool includeNestedMembers = false) + { + if (_selectExpression != null) return this.InternalToListAsync(_selectExpression); + return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); + } + + async public Task ToOneAsync() + { + this.Limit(1); + return (await this.ToListAsync()).FirstOrDefault(); + } + + public Task FirstAsync() => this.ToOneAsync(); + + async protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) + { + var sql = this.ToSql(af.field); + var type = typeof(TReturn); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + { + var index = -1; + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); + _trackToList?.Invoke(ret); + return ret; + } + + async protected Task InternalAvgAsync(Expression exp) => (await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + + protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); + async protected Task InternalToDataTableAsync(Expression select) { var sql = this.InternalToSql(select); @@ -1133,15 +1161,6 @@ namespace FreeSql.Internal.CommonProvider return ret; } - protected TReturn InternalToAggregate(Expression select) - { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; - - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression); - return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); - } async protected Task InternalToAggregateAsync(Expression select) { var map = new ReadAnonymousTypeInfo(); @@ -1151,8 +1170,6 @@ namespace FreeSql.Internal.CommonProvider _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression); return (await this.ToListMapReaderAsync((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); } - - protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression)); - #endregion +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 8aec418b..372b46dc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -42,13 +42,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -63,13 +56,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -77,13 +63,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -105,13 +84,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -119,27 +91,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -163,13 +121,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -219,11 +170,64 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 2a17fde4..ba3fdbe7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -109,12 +109,6 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = column.Parameters[0]; return this.InternalAvg(column?.Body); } - public Task AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalAvgAsync(column?.Body); - } public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class;// { this.InternalFrom(exp); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class;// { this.InternalFrom(exp); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } @@ -139,25 +133,12 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = column.Parameters[0]; return this.InternalMax(column?.Body); } - public Task MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalMaxAsync(column?.Body); - } - public TMember Min(Expression> column) { if (column == null) return default(TMember); _tables[0].Parameter = column.Parameters[0]; return this.InternalMin(column?.Body); } - public Task MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalMinAsync(column?.Body); - } public ISelect OrderBy(Expression> column) => this.OrderBy(true, column); public ISelect OrderBy(bool condition, Expression> column) { @@ -179,12 +160,6 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = column.Parameters[0]; return this.InternalSum(column?.Body); } - public Task SumAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - _tables[0].Parameter = column.Parameters[0]; - return this.InternalSumAsync(column?.Body); - } public List ToList(Expression> select) { @@ -192,14 +167,8 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = select.Parameters[0]; return this.InternalToList(select?.Body); } - public Task> ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToListAsync(select?.Body); - } + public List ToList() => ToList(GetToListDtoSelector()); - public Task> ToListAsync() => ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -254,9 +223,9 @@ namespace FreeSql.Internal.CommonProvider if (collectionSelector.Body.NodeType == ExpressionType.Call) { var callExp = collectionSelector.Body as MethodCallExpression; - if (callExp.Method.Name == "DefaultIfEmpty" && callExp.Object.Type.GenericTypeArguments.Any()) + if (callExp.Method.Name == "DefaultIfEmpty" && callExp.Object.Type.GetGenericArguments().Any()) { - find = _tables.Where((a, idx) => idx > 0 && a.Type == SelectTableInfoType.InnerJoin && a.Table.Type == callExp.Object.Type.GenericTypeArguments[0]).LastOrDefault(); + find = _tables.Where((a, idx) => idx > 0 && a.Type == SelectTableInfoType.InnerJoin && a.Table.Type == callExp.Object.Type.GetGenericArguments()[0]).LastOrDefault(); if (find != null) { if (!string.IsNullOrEmpty(find.On)) find.On = Regex.Replace(find.On, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); @@ -293,13 +262,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - public Task ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToDataTableAsync(select?.Body); - } - public string ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -314,13 +276,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - public Task ToAggregateAsync(Expression, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - _tables[0].Parameter = select.Parameters[0]; - return this.InternalToAggregateAsync(select?.Body); - } - public ISelect Where(Expression> exp) => WhereIf(true, exp); public ISelect WhereIf(bool condition, Expression> exp) { @@ -372,20 +327,14 @@ namespace FreeSql.Internal.CommonProvider } public bool Any(Expression> exp) => this.Where(exp).Any(); - public Task AnyAsync(Expression> exp) => this.Where(exp).AnyAsync(); public TReturn ToOne(Expression> select) => this.Limit(1).ToList(select).FirstOrDefault(); - async public Task ToOneAsync(Expression> select) => (await this.Limit(1).ToListAsync(select)).FirstOrDefault(); public TDto ToOne() => this.Limit(1).ToList().FirstOrDefault(); - async public Task ToOneAsync() => (await this.Limit(1).ToListAsync()).FirstOrDefault(); public TReturn First(Expression> select) => this.ToOne(select); - public Task FirstAsync(Expression> select) => this.ToOneAsync(select); public TDto First() => this.ToOne(); - public Task FirstAsync() => this.ToOneAsync(); public override List ToList(bool includeNestedMembers = false) => base.ToList(_isIncluded || includeNestedMembers); - public override Task> ToListAsync(bool includeNestedMembers = false) => base.ToListAsync(_isIncluded || includeNestedMembers); bool _isIncluded = false; public ISelect Include(Expression> navigateSelector) where TNavigate : class @@ -963,5 +912,60 @@ namespace FreeSql.Internal.CommonProvider _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(list)); _trackToList?.Invoke(list); } + +#if net40 +#else + public Task AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalAvgAsync(column?.Body); + } + public Task MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalMaxAsync(column?.Body); + } + public Task MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalMinAsync(column?.Body); + } + public Task SumAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + _tables[0].Parameter = column.Parameters[0]; + return this.InternalSumAsync(column?.Body); + } + public Task> ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToListAsync(select?.Body); + } + public Task> ToListAsync() => ToListAsync(GetToListDtoSelector()); + + public Task ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToDataTableAsync(select?.Body); + } + public Task ToAggregateAsync(Expression, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + _tables[0].Parameter = select.Parameters[0]; + return this.InternalToAggregateAsync(select?.Body); + } + + public Task AnyAsync(Expression> exp) => this.Where(exp).AnyAsync(); + async public Task ToOneAsync(Expression> select) => (await this.Limit(1).ToListAsync(select)).FirstOrDefault(); + async public Task ToOneAsync() => (await this.Limit(1).ToListAsync()).FirstOrDefault(); + public Task FirstAsync(Expression> select) => this.ToOneAsync(select); + public Task FirstAsync() => this.ToOneAsync(); + public override Task> ToListAsync(bool includeNestedMembers = false) => base.ToListAsync(_isIncluded || includeNestedMembers); +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 552f7660..1970e43c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -26,13 +26,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -47,13 +40,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -61,13 +47,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -89,13 +68,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -103,27 +75,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -139,13 +98,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -195,11 +147,64 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index cd80bc19..641df438 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -28,13 +28,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -49,13 +42,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -63,13 +49,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -91,13 +70,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -105,27 +77,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -142,13 +101,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -198,11 +150,64 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 707080a6..95b8195b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -30,13 +30,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -51,13 +44,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -65,13 +51,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -93,13 +72,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -107,20 +79,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -131,13 +97,6 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T4), "d")); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - DataTable ISelect.ToDataTable(Expression> select) { if (select == null) return this.InternalToDataTable(select?.Body); @@ -145,13 +104,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -201,11 +153,64 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 60a3c5e6..c78ce9be 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -32,13 +32,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -53,13 +46,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -67,13 +53,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -95,13 +74,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -109,27 +81,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -148,13 +107,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -204,11 +156,64 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index ee59440c..7a7a06be 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -34,13 +34,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -55,13 +48,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -69,13 +55,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -97,13 +76,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -111,27 +83,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -151,13 +110,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -207,11 +159,64 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 2118ee36..39fb0d10 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -36,13 +36,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -57,13 +50,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -71,13 +57,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -99,13 +78,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -113,27 +85,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -154,13 +113,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -210,11 +162,64 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index cc611d62..92c54153 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -38,13 +38,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -59,13 +52,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -73,13 +59,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -101,13 +80,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -115,27 +87,15 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -157,13 +117,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -213,11 +166,64 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 3c3a8c1d..8db15de2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -40,13 +40,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - ISelectGrouping ISelect.GroupBy(Expression> exp) { if (exp == null) return this.InternalGroupBy(exp?.Body); @@ -61,13 +54,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMax(column?.Body); } - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - TMember ISelect.Min(Expression> column) { if (column == null) return default(TMember); @@ -75,13 +61,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMin(column?.Body); } - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - ISelect ISelect.OrderBy(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); @@ -103,13 +82,6 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column?.Body); } - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) { if (select == null) return default(TReturn); @@ -117,27 +89,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregate(select?.Body); } - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - List ISelect.ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); Expression> GetToListDtoSelector() { var ctor = typeof(TDto).GetConstructor(new Type[0]); @@ -159,14 +117,6 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToDataTable(select?.Body); } - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - string ISelect.ToSql(Expression> select) { if (select == null) return this.InternalToSql(select?.Body); @@ -180,14 +130,12 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); } - ISelect ISelect.InnerJoin(Expression> exp) { if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); } - ISelect ISelect.RightJoin(Expression> exp) { if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); @@ -201,7 +149,6 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); } - ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; @@ -216,11 +163,65 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); } +#if net40 +#else Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); } + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } +#endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index cac92d53..4021b1d9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -117,17 +117,7 @@ namespace FreeSql.Internal.CommonProvider method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; } - public Task> ToListAsync(Expression, TReturn>> select) - { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; - - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null); - var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(typeof(TReturn)); - return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; - } + public List Select(Expression, TReturn>> select) => ToList(select); public string ToSql(Expression, TReturn>> select) @@ -171,5 +161,20 @@ namespace FreeSql.Internal.CommonProvider method.Invoke(_select, new object[] { pageNumber, pageSize }); return this; } + +#if net40 +#else + public Task> ToListAsync(Expression, TReturn>> select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null); + var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(typeof(TReturn)); + return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; + } +#endif } } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 14709887..1cd348f8 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -180,52 +180,7 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } - async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) - { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = 0; - if (ss.Length <= 1) - { - ret = await this.RawExecuteAffrowsAsync(); - ClearData(); - return ret; - } - if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - } - else - { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } protected List SplitExecuteUpdated(int valuesLimit, int parameterLimit) { var ss = SplitSource(valuesLimit, parameterLimit); @@ -272,52 +227,6 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } - async protected Task> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit) - { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = new List(); - if (ss.Length <= 1) - { - ret = await this.RawExecuteUpdatedAsync(); - ClearData(); - return ret; - } - if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); - - if (_transaction != null) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret.AddRange(await this.RawExecuteUpdatedAsync()); - } - } - else - { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret.AddRange(await this.RawExecuteUpdatedAsync()); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } - } - ClearData(); - return ret; - } #endregion protected int RawExecuteAffrows() @@ -346,39 +255,11 @@ namespace FreeSql.Internal.CommonProvider } return affrows; } - async protected Task RawExecuteAffrowsAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try - { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(affrows); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return affrows; - } + protected abstract List RawExecuteUpdated(); - protected abstract Task> RawExecuteUpdatedAsync(); public abstract int ExecuteAffrows(); - public abstract Task ExecuteAffrowsAsync(); public abstract List ExecuteUpdated(); - public abstract Task> ExecuteUpdatedAsync(); public IUpdate IgnoreColumns(Expression> columns) => IgnoreColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null)); public IUpdate UpdateColumns(Expression> columns) => UpdateColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null)); @@ -513,7 +394,7 @@ namespace FreeSql.Internal.CommonProvider { if (col.Column.Attribute.IsNullable == true && col.Column.Attribute.MapType.IsNullableType()) { - var replval = _orm.CodeFirst.GetDbInfo(col.Column.Attribute.MapType.GenericTypeArguments.FirstOrDefault())?.defaultValue; + var replval = _orm.CodeFirst.GetDbInfo(col.Column.Attribute.MapType.GetGenericArguments().FirstOrDefault())?.defaultValue; if (replval == null) continue; var replname = _commonUtils.QuoteSqlName(col.Column.Attribute.Name); expt = expt.Replace(replname, _commonUtils.IsNull(replname, _commonUtils.FormatSql("{0}", replval))); diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs new file mode 100644 index 00000000..5d2767f0 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -0,0 +1,145 @@ +using FreeSql.Extensions.EntityUtil; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + partial class UpdateProvider + { +#if net40 +#else + async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = 0; + if (ss.Length <= 1) + { + ret = await this.RawExecuteAffrowsAsync(); + ClearData(); + return ret; + } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + async protected Task> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit) + { + var ss = SplitSource(valuesLimit, parameterLimit); + var ret = new List(); + if (ss.Length <= 1) + { + ret = await this.RawExecuteUpdatedAsync(); + ClearData(); + return ret; + } + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + + if (_transaction != null) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteUpdatedAsync()); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteUpdatedAsync()); + } + _transaction.Commit(); + } + catch + { + _transaction.Rollback(); + throw; + } + _transaction = null; + } + } + ClearData(); + return ret; + } + + async protected Task RawExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(affrows); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return affrows; + } + protected abstract Task> RawExecuteUpdatedAsync(); + + public abstract Task ExecuteAffrowsAsync(); + public abstract Task> ExecuteUpdatedAsync(); +#endif + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index c19b4c28..656bd04a 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -272,7 +272,7 @@ namespace FreeSql.Internal if (table.Columns.TryGetValue(p.Name, out var trycol) == false) continue; if (psidx > 0) sb.Append(" AND "); sb.Append(aliasAndDot).Append(this.QuoteSqlName(trycol.Attribute.Name)); - sb.Append(this.FormatSql(" = {0}", Utils.GetDataReaderValue(trycol.Attribute.MapType, p.GetValue(dywhere)))); + sb.Append(this.FormatSql(" = {0}", Utils.GetDataReaderValue(trycol.Attribute.MapType, p.GetValue(dywhere, null)))); ++psidx; } if (psidx == 0) return ""; @@ -404,7 +404,7 @@ namespace FreeSql.Internal var initTasks = new Task[b]; for (var c = 0; c < b; c++) { - initTasks[c] = Task.Run(() => + initTasks[c] = Task.Factory.StartNew(() => { try { diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index cccb47c9..029d0518 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -152,7 +152,7 @@ namespace FreeSql.Internal trytb.ColumnsByCsIgnore.Add(p.Name, col); continue; } - if (entityDefault != null) colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(entityDefault); + if (entityDefault != null) colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(entityDefault, null); if (p.PropertyType.IsEnum) { var isEqualsEnumValue = false; @@ -170,7 +170,7 @@ namespace FreeSql.Internal if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; if (colattr.IsNullable == false && colattr.DbDefautValue == null) { - var citype = colattr.MapType.IsNullableType() ? colattr.MapType.GenericTypeArguments.FirstOrDefault() : colattr.MapType; + var citype = colattr.MapType.IsNullableType() ? colattr.MapType.GetGenericArguments().FirstOrDefault() : colattr.MapType; if (citype.IsArray) colattr.DbDefautValue = Array.CreateInstance(citype, 0); else @@ -343,7 +343,7 @@ namespace FreeSql.Internal { throw new Exception($"【延时加载】{trytbTypeName} 编译错误:{ex.Message}\r\n\r\n{cscode}"); } - var type = assembly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault(); + var type = assembly.GetExportedTypes()/*.DefinedTypes*/.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault(); trytb.TypeLazy = type; trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true); tbc.AddOrUpdate(type, trytb, (oldkey, oldval) => trytb); @@ -356,7 +356,7 @@ namespace FreeSql.Internal { var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}"; var propTypeName = pnv.PropertyType.IsGenericType ? - $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" : + $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GetGenericArguments().Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" : (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name}"); var pnvAttr = common.GetEntityNavigateAttribute(trytb.Type, pnv); @@ -365,7 +365,7 @@ namespace FreeSql.Internal nvref.Property = pnv; //List 或 ICollection,一对多、多对多 - var propElementType = pnv.PropertyType.GenericTypeArguments.FirstOrDefault() ?? pnv.PropertyType.GetElementType(); + var propElementType = pnv.PropertyType.GetGenericArguments().FirstOrDefault() ?? pnv.PropertyType.GetElementType(); if (propElementType != null) { if (typeof(IEnumerable).IsAssignableFrom(pnv.PropertyType) == false) return; @@ -398,7 +398,7 @@ namespace FreeSql.Internal if (pnvAttr?.ManyToMany != null) { isManyToMany = propElementType != trytb.Type && - tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && + tbref.Properties.Where(z => (z.Value.PropertyType.GetGenericArguments().FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && common.GetEntityNavigateAttribute(tbref.Type, z.Value)?.ManyToMany == pnvAttr.ManyToMany && typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); @@ -419,7 +419,7 @@ namespace FreeSql.Internal { isManyToMany = propElementType != trytb.Type && pnv.Name.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase) && - tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && + tbref.Properties.Where(z => (z.Value.PropertyType.GetGenericArguments().FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && z.Key.EndsWith($"{trytb.CsName}s", StringComparison.CurrentCultureIgnoreCase) && typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); } @@ -1025,7 +1025,7 @@ namespace FreeSql.Internal foreach (var p in ps) { if (string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; - var pvalue = p.GetValue(obj); + var pvalue = p.GetValue(obj, null); if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype)); else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue)); } @@ -1123,7 +1123,7 @@ namespace FreeSql.Internal ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); var typeGeneric = type; - if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First(); + if (typeGeneric.IsNullableType()) typeGeneric = type.GetGenericArguments().First(); if (typeGeneric.IsEnum || dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric)) return Expression.Lambda>( @@ -1156,7 +1156,7 @@ namespace FreeSql.Internal else { var fieldtypeGeneric = field.FieldType; - if (fieldtypeGeneric.IsNullableType()) fieldtypeGeneric = fieldtypeGeneric.GenericTypeArguments.First(); + if (fieldtypeGeneric.IsNullableType()) fieldtypeGeneric = fieldtypeGeneric.GetGenericArguments().First(); if (fieldtypeGeneric.IsEnum || dicExecuteArrayRowReadClassOrTuple.ContainsKey(fieldtypeGeneric)) read2ExpAssign = Expression.New(RowInfo.Constructor, GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), @@ -1261,7 +1261,7 @@ namespace FreeSql.Internal else { var proptypeGeneric = readType; - if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GetGenericArguments().First(); if (proptypeGeneric.IsEnum || dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) { @@ -1366,7 +1366,7 @@ namespace FreeSql.Internal else { var proptypeGeneric = readType; - if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GetGenericArguments().First(); if (proptypeGeneric.IsEnum || dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) { @@ -1562,7 +1562,7 @@ namespace FreeSql.Internal ); } var typeOrg = type; - if (type.IsNullableType()) type = type.GenericTypeArguments.First(); + if (type.IsNullableType()) type = type.GetGenericArguments().First(); if (type.IsEnum) return Expression.Block( Expression.IfThenElse( diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index f3679435..05dfc35d 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -53,6 +53,9 @@ namespace FreeSql.MySql.Curd this.ClearData(); return ret; } + +#if net40 +#else async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -91,5 +94,6 @@ namespace FreeSql.MySql.Curd this.ClearData(); return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 64f9a0c8..41b20ac4 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -16,11 +16,8 @@ namespace FreeSql.MySql.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); protected override long RawExecuteIdentity() @@ -49,32 +46,6 @@ namespace FreeSql.MySql.Curd } return ret; } - async protected override Task RawExecuteIdentityAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - - sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try - { - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0; - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override List RawExecuteInserted() { var sql = this.ToSql(); @@ -111,6 +82,39 @@ namespace FreeSql.MySql.Curd } return ret; } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -147,5 +151,6 @@ namespace FreeSql.MySql.Curd } return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index e3749b0a..dff4be5c 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -19,10 +19,7 @@ namespace FreeSql.MySql.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); - protected override List RawExecuteUpdated() { @@ -62,44 +59,6 @@ namespace FreeSql.MySql.Curd } return ret; } - async protected override Task> RawExecuteUpdatedAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -136,5 +95,50 @@ namespace FreeSql.MySql.Curd } sb.Append(")"); } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } +#endif } } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 235f8835..a6913955 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net452 + netstandard2.0;net452;net451;net45;net40 0.10.14 true YeXiangQin @@ -21,13 +21,21 @@ - - - - + + + + + + + + + + net40 + + diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 35613bdd..e8bbc3fc 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -138,6 +138,8 @@ namespace FreeSql.MySql } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -165,6 +167,7 @@ namespace FreeSql.MySql } } } +#endif public void OnGetTimeout() { @@ -211,6 +214,9 @@ namespace FreeSql.MySql return false; } } + +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -225,5 +231,6 @@ namespace FreeSql.MySql return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index c718608b..e8c38cb0 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -58,7 +58,11 @@ namespace FreeSql.MySql if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index cb48f2a4..e91917f3 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -377,7 +377,7 @@ namespace FreeSql.MySql case "AddTicks": return $"date_add({left}, interval ({args1})/10 microsecond)"; case "AddYears": return $"date_add({left}, interval ({args1}) year)"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"timestampdiff(microsecond, {args1}, {left})"; case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)"; diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index cfaa492b..8617ef5e 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -43,6 +43,7 @@ namespace FreeSql.MySql public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 43076597..852c0db1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -37,5 +37,5 @@ - + diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs index 2d5168fa..cfc4663d 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs @@ -16,6 +16,10 @@ namespace FreeSql.Odbc.Default } public override List ExecuteDeleted() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + +#if net40 +#else public override Task> ExecuteDeletedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index f7c68d8f..be1e79d3 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -20,11 +20,8 @@ namespace FreeSql.Odbc.Default } public override int ExecuteAffrows() => base.SplitExecuteAffrows(_utils.Adapter.InsertBatchSplitLimit, 255); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_utils.Adapter.InsertBatchSplitLimit, 255); public override long ExecuteIdentity() => base.SplitExecuteIdentity(_utils.Adapter.InsertBatchSplitLimit, 255); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_utils.Adapter.InsertBatchSplitLimit, 255); public override List ExecuteInserted() => base.SplitExecuteInserted(_utils.Adapter.InsertBatchSplitLimit, 255); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_utils.Adapter.InsertBatchSplitLimit, 255); protected override long RawExecuteIdentity() { @@ -63,6 +60,15 @@ namespace FreeSql.Odbc.Default } return ret; } + + protected override List RawExecuteInserted() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); @@ -100,8 +106,7 @@ namespace FreeSql.Odbc.Default } return ret; } - - protected override List RawExecuteInserted() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); protected override Task> RawExecuteInsertedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); +#endif } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs index f0c73c20..95cfc2fe 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs @@ -20,12 +20,9 @@ namespace FreeSql.Odbc.Default } public override int ExecuteAffrows() => base.SplitExecuteAffrows(_utils.Adapter.InsertBatchSplitLimit, 255); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_utils.Adapter.InsertBatchSplitLimit, 255); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_utils.Adapter.InsertBatchSplitLimit, 255); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_utils.Adapter.InsertBatchSplitLimit, 255); protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); - protected override Task> RawExecuteUpdatedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -60,5 +57,13 @@ namespace FreeSql.Odbc.Default ++pkidx; } } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + + protected override Task> RawExecuteUpdatedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs index dc8e581a..42d702a7 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -144,6 +144,8 @@ namespace FreeSql.Odbc.Default } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -172,6 +174,7 @@ namespace FreeSql.Odbc.Default } } } +#endif public void OnGetTimeout() { @@ -218,6 +221,9 @@ namespace FreeSql.Odbc.Default return false; } } + +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -232,5 +238,6 @@ namespace FreeSql.Odbc.Default return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs index 9eee66a9..b007fb41 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs @@ -66,7 +66,11 @@ namespace FreeSql.Odbc.Default if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs index 534bb1fa..50262556 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -356,7 +356,7 @@ namespace FreeSql.Odbc.Default case "AddTicks": return _utils.Adapter.LambdaDateTime_AddTicks(left, args1); case "AddYears": return _utils.Adapter.LambdaDateTime_AddYears(left, args1); case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return _utils.Adapter.LambdaDateTime_Subtract(left, args1); case "System.TimeSpan": return _utils.Adapter.LambdaDateTime_SubtractTimeSpan(left, args1); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index 8dadf885..740fbfab 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -18,6 +18,7 @@ namespace FreeSql.Odbc.Default public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e47e6604..216b1b5b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net45;net40 0.10.14 true YeXiangQin @@ -29,6 +29,10 @@ - + + + net40 + + diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index 84d7b968..e4daabfb 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -53,6 +53,9 @@ namespace FreeSql.Odbc.MySql this.ClearData(); return ret; } + +#if net40 +#else async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -91,5 +94,6 @@ namespace FreeSql.Odbc.MySql this.ClearData(); return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index cba7443d..72092283 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -18,11 +18,8 @@ namespace FreeSql.Odbc.MySql } public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); protected override long RawExecuteIdentity() @@ -62,43 +59,6 @@ namespace FreeSql.Odbc.MySql } return ret; } - async protected override Task RawExecuteIdentityAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - - Object poolConn = null; - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try - { - var conn = _connection; - if (_transaction != null) conn = _transaction.Connection; - if (conn == null) - { - poolConn = _orm.Ado.MasterPool.Get(); - conn = poolConn.Value; - } - await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, "SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - if (poolConn != null) - _orm.Ado.MasterPool.Return(poolConn); - - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override List RawExecuteInserted() { var sql = this.ToSql(); @@ -135,6 +95,50 @@ namespace FreeSql.Odbc.MySql } return ret; } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + Object poolConn = null; + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + var conn = _connection; + if (_transaction != null) conn = _transaction.Connection; + if (conn == null) + { + poolConn = _orm.Ado.MasterPool.Get(); + conn = poolConn.Value; + } + await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _params); + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, "SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (poolConn != null) + _orm.Ado.MasterPool.Return(poolConn); + + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -171,5 +175,6 @@ namespace FreeSql.Odbc.MySql } return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index 35d854d3..4194f4f0 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -19,9 +19,7 @@ namespace FreeSql.Odbc.MySql } public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); protected override List RawExecuteUpdated() @@ -62,44 +60,6 @@ namespace FreeSql.Odbc.MySql } return ret; } - async protected override Task> RawExecuteUpdatedAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -136,5 +96,50 @@ namespace FreeSql.Odbc.MySql } sb.Append(")"); } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs index 2996681b..9ad71a17 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -138,6 +138,8 @@ namespace FreeSql.Odbc.MySql } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -165,6 +167,7 @@ namespace FreeSql.Odbc.MySql } } } +#endif public void OnGetTimeout() { @@ -211,6 +214,9 @@ namespace FreeSql.Odbc.MySql return false; } } + +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -225,5 +231,6 @@ namespace FreeSql.Odbc.MySql return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 36b06ec7..1aeff28f 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -46,7 +46,11 @@ namespace FreeSql.Odbc.MySql if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index cc27da38..ca13a287 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -377,7 +377,7 @@ namespace FreeSql.Odbc.MySql case "AddTicks": return $"date_add({left}, interval ({args1})/10 microsecond)"; case "AddYears": return $"date_add({left}, interval ({args1}) year)"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"timestampdiff(microsecond, {args1}, {left})"; case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index f68bf0c8..ccc5830e 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -21,6 +21,7 @@ namespace FreeSql.Odbc.MySql public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs index e042ef68..73085e57 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs @@ -19,9 +19,13 @@ namespace FreeSql.Odbc.Oracle { throw new NotImplementedException(); } + +#if net40 +#else public override Task> ExecuteDeletedAsync() { throw new NotImplementedException(); } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index d74d87d2..0405c439 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -19,12 +19,8 @@ namespace FreeSql.Odbc.Oracle } public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); - public override string ToSql() { @@ -137,6 +133,22 @@ namespace FreeSql.Odbc.Oracle } return ret; } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + this.RawExecuteAffrows(); + return _source; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); @@ -190,15 +202,6 @@ namespace FreeSql.Odbc.Oracle } return ret; } - - protected override List RawExecuteInserted() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - this.RawExecuteAffrows(); - return _source; - } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -207,5 +210,6 @@ namespace FreeSql.Odbc.Oracle await this.RawExecuteAffrowsAsync(); return _source; } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index 83fe3247..51e66622 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -19,19 +19,13 @@ namespace FreeSql.Odbc.Oracle } public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); protected override List RawExecuteUpdated() { throw new NotImplementedException(); } - protected override Task> RawExecuteUpdatedAsync() - { - throw new NotImplementedException(); - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -68,5 +62,16 @@ namespace FreeSql.Odbc.Oracle } sb.Append(")"); } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index 533973d2..7ccfa7bd 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -155,6 +155,8 @@ namespace FreeSql.Odbc.Oracle } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -182,6 +184,7 @@ namespace FreeSql.Odbc.Oracle } } } +#endif public void OnGetTimeout() { @@ -228,6 +231,9 @@ namespace FreeSql.Odbc.Oracle return false; } } + +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -242,5 +248,6 @@ namespace FreeSql.Odbc.Oracle return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index c1646775..84394be6 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -52,7 +52,11 @@ namespace FreeSql.Odbc.Oracle if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? @@ -90,7 +94,7 @@ namespace FreeSql.Odbc.Oracle var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; - var primaryKeyName = entityType.GetCustomAttribute()?.Name; + var primaryKeyName = (entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index af0c5748..cd598adc 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -379,7 +379,7 @@ namespace FreeSql.Odbc.Oracle case "AddTicks": return $"({left}+({args1})/864000000000)"; case "AddYears": return $"add_months({left},({args1})*12)"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"numtodsinterval(({left}+0)-({args1}+0),'day')"; case "System.TimeSpan": return $"({left}-{args1})"; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index 33004ad1..be0e4c11 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -16,6 +16,7 @@ namespace FreeSql.Odbc.Oracle public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index a9039ebe..11250d19 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -53,6 +53,9 @@ namespace FreeSql.Odbc.PostgreSQL this.ClearData(); return ret; } + +#if net40 +#else async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -91,5 +94,6 @@ namespace FreeSql.Odbc.PostgreSQL this.ClearData(); return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index 430285a9..9ded50ef 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -17,12 +17,8 @@ namespace FreeSql.Odbc.PostgreSQL } public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); - protected override long RawExecuteIdentity() { @@ -73,6 +69,50 @@ namespace FreeSql.Odbc.PostgreSQL } return ret; } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); @@ -122,43 +162,6 @@ namespace FreeSql.Odbc.PostgreSQL } return ret; } - - protected override List RawExecuteInserted() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -195,5 +198,6 @@ namespace FreeSql.Odbc.PostgreSQL } return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 6aab35a3..8c13d6cf 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -19,10 +19,7 @@ namespace FreeSql.Odbc.PostgreSQL } public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); - protected override List RawExecuteUpdated() { @@ -62,44 +59,6 @@ namespace FreeSql.Odbc.PostgreSQL } return ret; } - async protected override Task> RawExecuteUpdatedAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -145,5 +104,50 @@ namespace FreeSql.Odbc.PostgreSQL sb.Append("::").Append(dbtype); } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index defc36a0..dfc21556 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -150,6 +150,8 @@ namespace FreeSql.Odbc.PostgreSQL } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -177,6 +179,7 @@ namespace FreeSql.Odbc.PostgreSQL } } } +#endif public void OnGetTimeout() { @@ -223,6 +226,9 @@ namespace FreeSql.Odbc.PostgreSQL return false; } } + +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -237,5 +243,6 @@ namespace FreeSql.Odbc.PostgreSQL return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 2d04cd90..964764a1 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -56,7 +56,11 @@ namespace FreeSql.Odbc.PostgreSQL if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (OdbcType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index d610ba85..449c1a52 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -465,7 +465,7 @@ namespace FreeSql.Odbc.PostgreSQL case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index fb48307d..5313d309 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -19,6 +19,7 @@ namespace FreeSql.Odbc.PostgreSQL public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 1591c4c8..fc3143cb 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -47,13 +47,17 @@ namespace FreeSql.Odbc.PostgreSQL var elementType = type.GetElementType(); Type enumType = null; if (elementType.IsEnum) enumType = elementType; - else if (elementType.IsNullableType() && elementType.GenericTypeArguments.First().IsEnum) enumType = elementType.GenericTypeArguments.First(); + else if (elementType.IsNullableType()) + { + var genericTypesFirst = elementType.GetGenericArguments().First(); + if (genericTypesFirst.IsEnum) enumType = genericTypesFirst; + } if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)) : getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)); return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; } - if (type.IsNullableType()) type = type.GenericTypeArguments.First(); + if (type.IsNullableType()) type = type.GetGenericArguments().First(); if (type.IsEnum) return (int)value; if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); return value; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index 6134d2a9..609591fa 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -58,6 +58,9 @@ namespace FreeSql.Odbc.SqlServer this.ClearData(); return ret; } + +#if net40 +#else async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -101,5 +104,6 @@ namespace FreeSql.Odbc.SqlServer this.ClearData(); return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 986df69e..dcd41e7d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -18,12 +18,8 @@ namespace FreeSql.Odbc.SqlServer } public override int ExecuteAffrows() => base.SplitExecuteAffrows(1000, 2100); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); - protected override long RawExecuteIdentity() { @@ -51,32 +47,6 @@ namespace FreeSql.Odbc.SqlServer } return ret; } - async protected override Task RawExecuteIdentityAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - - sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try - { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override List RawExecuteInserted() { @@ -119,6 +89,40 @@ namespace FreeSql.Odbc.SqlServer } return ret; } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -160,5 +164,6 @@ namespace FreeSql.Odbc.SqlServer } return ret; } +#endif } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index bd0befb5..52155aad 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -19,10 +19,7 @@ namespace FreeSql.Odbc.SqlServer } public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 2100); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 2100); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); - protected override List RawExecuteUpdated() { @@ -67,49 +64,6 @@ namespace FreeSql.Odbc.SqlServer } return ret; } - async protected override Task> RawExecuteUpdatedAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" \r\nWHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -144,5 +98,55 @@ namespace FreeSql.Odbc.SqlServer ++pkidx; } } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(" \r\nWHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); + + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs index ba1481d0..6a2516a6 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -144,6 +144,8 @@ namespace FreeSql.Odbc.SqlServer } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -172,6 +174,7 @@ namespace FreeSql.Odbc.SqlServer } } } +#endif public void OnGetTimeout() { @@ -218,6 +221,9 @@ namespace FreeSql.Odbc.SqlServer return false; } } + +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -232,5 +238,6 @@ namespace FreeSql.Odbc.SqlServer return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 710d60e0..20416a9b 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -48,7 +48,11 @@ namespace FreeSql.Odbc.SqlServer if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 6496196c..f96d7c83 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -359,7 +359,7 @@ namespace FreeSql.Odbc.SqlServer case "AddTicks": return $"dateadd(second, ({args1})/10000000, {left})"; case "AddYears": return $"dateadd(year, {args1}, {left})"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"datediff(second, {args1}, {left})"; case "System.TimeSpan": return $"dateadd(second, ({args1})*-1, {left})"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index 93e325ad..0f5c1203 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -15,6 +15,7 @@ namespace FreeSql.Odbc.SqlServer public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs index 3f6be169..8bd84136 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs @@ -19,9 +19,13 @@ namespace FreeSql.Oracle.Curd { throw new NotImplementedException(); } + +#if net40 +#else public override Task> ExecuteDeletedAsync() { throw new NotImplementedException(); } +#endif } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 03ab37b1..8585da3e 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -20,11 +20,8 @@ namespace FreeSql.Oracle.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); public override string ToSql() @@ -138,6 +135,21 @@ namespace FreeSql.Oracle.Curd } return ret; } + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + this.RawExecuteAffrows(); + return _source; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); @@ -191,15 +203,6 @@ namespace FreeSql.Oracle.Curd } return ret; } - - protected override List RawExecuteInserted() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - this.RawExecuteAffrows(); - return _source; - } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -208,5 +211,6 @@ namespace FreeSql.Oracle.Curd await this.RawExecuteAffrowsAsync(); return _source; } +#endif } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index 7338509f..57f85150 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -19,19 +19,13 @@ namespace FreeSql.Oracle.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); protected override List RawExecuteUpdated() { throw new NotImplementedException(); } - protected override Task> RawExecuteUpdatedAsync() - { - throw new NotImplementedException(); - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -68,5 +62,16 @@ namespace FreeSql.Oracle.Curd } sb.Append(")"); } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } +#endif } } diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index e8bf628b..d6a40e17 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net45;net40 0.10.14 true YeXiangQin @@ -23,16 +23,20 @@ - + - - + + - + + + net40 + + diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index 6f543c15..cf65eb94 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -155,6 +155,8 @@ namespace FreeSql.Oracle } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -182,6 +184,7 @@ namespace FreeSql.Oracle } } } +#endif public void OnGetTimeout() { @@ -228,6 +231,9 @@ namespace FreeSql.Oracle return false; } } + +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -242,5 +248,6 @@ namespace FreeSql.Oracle return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 863b1cee..6ac27090 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -53,7 +53,11 @@ namespace FreeSql.Oracle if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? @@ -91,7 +95,7 @@ namespace FreeSql.Oracle var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; - var primaryKeyName = entityType.GetCustomAttribute()?.Name; + var primaryKeyName = (entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 8fab54c3..80016c64 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -379,7 +379,7 @@ namespace FreeSql.Oracle case "AddTicks": return $"({left}+({args1})/864000000000)"; case "AddYears": return $"add_months({left},({args1})*12)"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"numtodsinterval(({left}+0)-({args1}+0),'day')"; case "System.TimeSpan": return $"({left}-{args1})"; diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index be867e3e..f425a362 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -17,6 +17,7 @@ namespace FreeSql.Oracle public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index f2b40940..f5478a2e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -53,6 +53,9 @@ namespace FreeSql.PostgreSQL.Curd this.ClearData(); return ret; } + +#if net40 +#else async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -91,5 +94,6 @@ namespace FreeSql.PostgreSQL.Curd this.ClearData(); return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index bb5ef651..af811633 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -17,12 +17,8 @@ namespace FreeSql.PostgreSQL.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); - protected override long RawExecuteIdentity() { @@ -73,6 +69,50 @@ namespace FreeSql.PostgreSQL.Curd } return ret; } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); @@ -122,43 +162,6 @@ namespace FreeSql.PostgreSQL.Curd } return ret; } - - protected override List RawExecuteInserted() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -195,5 +198,6 @@ namespace FreeSql.PostgreSQL.Curd } return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 62343660..e56c125c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -19,10 +19,7 @@ namespace FreeSql.PostgreSQL.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); - protected override List RawExecuteUpdated() { @@ -62,44 +59,6 @@ namespace FreeSql.PostgreSQL.Curd } return ret; } - async protected override Task> RawExecuteUpdatedAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(sql).Append(" RETURNING "); - - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -145,5 +104,50 @@ namespace FreeSql.PostgreSQL.Curd sb.Append("::").Append(dbtype); } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } +#endif } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7a1048ba..ef353458 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net461;net452;net451;net45 0.10.14 true YeXiangQin @@ -24,12 +24,18 @@ - - + + + + + + + + - + diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index 74a2d707..d9694fbe 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -150,6 +150,8 @@ namespace FreeSql.PostgreSQL } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -177,6 +179,7 @@ namespace FreeSql.PostgreSQL } } } +#endif public void OnGetTimeout() { @@ -223,6 +226,9 @@ namespace FreeSql.PostgreSQL return false; } } + +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -237,5 +243,6 @@ namespace FreeSql.PostgreSQL return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs index ab1fb921..d3796ea2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs @@ -1,5 +1,4 @@ -using Npgsql.LegacyPostgis; -using NpgsqlTypes; +using NpgsqlTypes; using System; using System.Collections; @@ -20,13 +19,15 @@ public static partial class PostgreSQLTypesExtensions 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; } +#if net40 +#else /// /// 测量两个经纬度的距离,返回单位:米 /// /// 经纬坐标1 /// 经纬坐标2 /// 返回距离(单位:米) - public static double Distance(this PostgisPoint that, PostgisPoint point) + public static double Distance(this Npgsql.LegacyPostgis.PostgisPoint that, Npgsql.LegacyPostgis.PostgisPoint point) { double radLat1 = (double)(that.Y) * Math.PI / 180d; double radLng1 = (double)(that.X) * Math.PI / 180d; @@ -34,6 +35,21 @@ public static partial class PostgreSQLTypesExtensions double radLng2 = (double)(point.X) * Math.PI / 180d; 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; } + + public static NpgsqlRange ToNpgsqlRange(this string that) + { + var s = that; + if (string.IsNullOrEmpty(s) || s == "empty") return NpgsqlRange.Empty; + string s1 = s.Trim('(', ')', '[', ']'); + string[] ss = s1.Split(new char[] { ',' }, 2); + if (ss.Length != 2) return NpgsqlRange.Empty; + T t1 = default(T); + T t2 = default(T); + if (!string.IsNullOrEmpty(ss[0])) t1 = (T)Convert.ChangeType(ss[0], typeof(T)); + if (!string.IsNullOrEmpty(ss[1])) t2 = (T)Convert.ChangeType(ss[1], typeof(T)); + return new NpgsqlRange(t1, s[0] == '[', s[0] == '(', t2, s[s.Length - 1] == ']', s[s.Length - 1] == ')'); + } +#endif public static string To1010(this BitArray ba) { @@ -54,18 +70,4 @@ public static partial class PostgreSQLTypesExtensions for (int a = 0; a < _1010Str.Length; a++) ret[a] = _1010Str[a] == '1'; return ret; } - - public static NpgsqlRange ToNpgsqlRange(this string that) - { - var s = that; - if (string.IsNullOrEmpty(s) || s == "empty") return NpgsqlRange.Empty; - string s1 = s.Trim('(', ')', '[', ']'); - string[] ss = s1.Split(new char[] { ',' }, 2); - if (ss.Length != 2) return NpgsqlRange.Empty; - T t1 = default(T); - T t2 = default(T); - if (!string.IsNullOrEmpty(ss[0])) t1 = (T)Convert.ChangeType(ss[0], typeof(T)); - if (!string.IsNullOrEmpty(ss[1])) t2 = (T)Convert.ChangeType(ss[1], typeof(T)); - return new NpgsqlRange(t1, s[0] == '[', s[0] == '(', t2, s[s.Length - 1] == ']', s[s.Length - 1] == ')'); - } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index 83b31178..b781993f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -70,6 +70,7 @@ namespace FreeSql.PostgreSQL public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index df944cc1..8656d908 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -58,6 +58,9 @@ namespace FreeSql.SqlServer.Curd this.ClearData(); return ret; } + +#if net40 +#else async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -101,5 +104,6 @@ namespace FreeSql.SqlServer.Curd this.ClearData(); return ret; } +#endif } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 46534b12..4c543635 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -18,12 +18,8 @@ namespace FreeSql.SqlServer.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(1000, 2100); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); - protected override long RawExecuteIdentity() { @@ -51,33 +47,6 @@ namespace FreeSql.SqlServer.Curd } return ret; } - async protected override Task RawExecuteIdentityAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - - sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - long ret = 0; - Exception exception = null; - try - { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } - protected override List RawExecuteInserted() { var sql = this.ToSql(); @@ -119,6 +88,39 @@ namespace FreeSql.SqlServer.Curd } return ret; } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -160,5 +162,6 @@ namespace FreeSql.SqlServer.Curd } return ret; } +#endif } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index a8944a6c..e16c5dec 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -19,9 +19,7 @@ namespace FreeSql.SqlServer.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 2100); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 2100); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); protected override List RawExecuteUpdated() @@ -67,49 +65,6 @@ namespace FreeSql.SqlServer.Curd } return ret; } - async protected override Task> RawExecuteUpdatedAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" \r\nWHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.Concat(_paramsSource).ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return ret; - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -144,5 +99,55 @@ namespace FreeSql.SqlServer.Curd ++pkidx; } } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(" \r\nWHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); + + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } +#endif } } diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 40b3048e..adb59a88 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net451 + netstandard2.0;net451;net45;net40 0.10.14 true YeXiangQin @@ -21,13 +21,17 @@ - - - - + + + + - + + + net40 + + diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index e8412eb8..6911e681 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -143,7 +143,8 @@ namespace FreeSql.SqlServer } } } - +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -172,7 +173,7 @@ namespace FreeSql.SqlServer } } } - +#endif public void OnGetTimeout() { @@ -218,6 +219,8 @@ namespace FreeSql.SqlServer return false; } } +#if net40 +#else async public static Task PingAsync(this DbConnection that, bool isThrow = false) { try @@ -232,5 +235,6 @@ namespace FreeSql.SqlServer return false; } } +#endif } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 98954af7..d786528b 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -51,7 +51,11 @@ namespace FreeSql.SqlServer if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index ce835798..4b0b0bb1 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -359,7 +359,7 @@ namespace FreeSql.SqlServer case "AddTicks": return $"dateadd(second, ({args1})/10000000, {left})"; case "AddYears": return $"dateadd(year, {args1}, {left})"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"datediff(second, {args1}, {left})"; case "System.TimeSpan": return $"dateadd(second, ({args1})*-1, {left})"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index 33017c8e..467f7c96 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -16,6 +16,7 @@ namespace FreeSql.SqlServer public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs index f582cb6b..d71498cf 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs @@ -19,9 +19,13 @@ namespace FreeSql.Sqlite.Curd { throw new NotImplementedException(); } + +#if net40 +#else public override Task> ExecuteDeletedAsync() { throw new NotImplementedException(); } +#endif } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index 8c09083b..034aeabb 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -17,12 +17,8 @@ namespace FreeSql.Sqlite.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 999); public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 999); public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 999); - protected override long RawExecuteIdentity() { @@ -50,6 +46,22 @@ namespace FreeSql.Sqlite.Curd } return ret; } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + this.RawExecuteAffrows(); + return _source; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 999); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); @@ -76,14 +88,6 @@ namespace FreeSql.Sqlite.Curd } return ret; } - protected override List RawExecuteInserted() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - this.RawExecuteAffrows(); - return _source; - } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); @@ -92,5 +96,6 @@ namespace FreeSql.Sqlite.Curd await this.RawExecuteAffrowsAsync(); return _source; } +#endif } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index a7a568a4..92e9bdc2 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -19,19 +19,13 @@ namespace FreeSql.Sqlite.Curd } public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); protected override List RawExecuteUpdated() { throw new NotImplementedException(); } - protected override Task> RawExecuteUpdatedAsync() - { - throw new NotImplementedException(); - } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { @@ -68,5 +62,16 @@ namespace FreeSql.Sqlite.Curd } sb.Append(")"); } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } +#endif } } diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index bd6e239f..289dfeb0 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net45;net40 0.10.14 true YeXiangQin @@ -30,4 +30,8 @@ + + net40 + + diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 8f53eb91..f5f200f8 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -150,6 +150,8 @@ namespace FreeSql.Sqlite } } +#if net40 +#else async public Task OnGetAsync(Object obj) { @@ -177,6 +179,7 @@ namespace FreeSql.Sqlite } } } +#endif public void OnGetTimeout() { @@ -222,21 +225,6 @@ namespace FreeSql.Sqlite return false; } } - async public static Task PingAsync(this DbConnection that, bool isThrow = false) - { - try - { - await PingCommand(that).ExecuteNonQueryAsync(); - return true; - } - catch - { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - public static void OpenAndAttach(this DbConnection that, string[] attach) { that.Open(); @@ -252,6 +240,23 @@ namespace FreeSql.Sqlite cmd.ExecuteNonQuery(); } } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } async public static Task OpenAndAttachAsync(this DbConnection that, string[] attach) { await that.OpenAsync(); @@ -267,5 +272,6 @@ namespace FreeSql.Sqlite await cmd.ExecuteNonQueryAsync(); } } +#endif } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 9d804e0c..68639935 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -50,7 +50,11 @@ namespace FreeSql.Sqlite if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 4967e2d8..9f451e0b 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -381,7 +381,7 @@ namespace FreeSql.Sqlite case "AddTicks": return $"datetime({left},(({args1})/10000000)||' seconds')"; case "AddYears": return $"datetime({left},({args1})||' years')"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; case "System.TimeSpan": return $"datetime({left},(({args1})*-1)||' seconds')"; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 6cb3524e..ef67538b 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -17,6 +17,7 @@ namespace FreeSql.Sqlite public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); public IUpdate Update() where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IUpdate Update(object dywhere) where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); diff --git a/readme.md b/readme.md index 3007ce80..fafa5822 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@

-FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.5+(QQ群:4336577) +FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+(QQ群:4336577) 扶摇直上,至强ORM只为自由编码;鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) @@ -53,14 +53,15 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | Package Name | Version | |--------------| ------- | -| FreeSql.Provider.MySql | NETStandard2.0、net452 | +| FreeSql.Provider.MySql | NETStandard2.0、net45、net40 | +| FreeSql.Provider.MySqlConnector | NETStandard2.0、net45 | | FreeSql.Provider.PostgreSQL | NETStandard2.0、net45 | -| FreeSql.Provider.SqlServer | NETStandard2.0、net451 | -| FreeSql.Provider.Sqlite | NETStandard2.0、net45 | -| FreeSql.Provider.Oracle | NETStandard2.0、net45 | -| [FreeSql.Provider.Odbc](https://github.com/2881099/FreeSql/tree/master/Providers/FreeSql.Provider.Odbc) | NETStandard2.0、net45 | -| FreeSql.Extensions.LazyLoading | NETStandard2.0、net45 | -| FreeSql.Extensions.JsonMap | NETStandard2.0、net45 | +| FreeSql.Provider.SqlServer | NETStandard2.0、net45、net40 | +| FreeSql.Provider.Sqlite | NETStandard2.0、net45、net40 | +| FreeSql.Provider.Oracle | NETStandard2.0、net45、net40 | +| [FreeSql.Provider.Odbc](https://github.com/2881099/FreeSql/tree/master/Providers/FreeSql.Provider.Odbc) | NETStandard2.0、net45、net40 | +| FreeSql.Extensions.LazyLoading | NETStandard2.0、net45、net40 | +| FreeSql.Extensions.JsonMap | NETStandard2.0、net45、net40 | | FreeSql.Extensions.BaseEntity | NETStandard2.0 |

From aaed0334b8c57ca6a08ba9eafdbb52d0139e5a57 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 21 Oct 2019 15:21:26 +0800 Subject: [PATCH 0199/1029] ## v0.10.15 (.Net Framework 4.0) --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b90f3d94..5076068f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.14 + 0.10.15 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0180cb68..28355931 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ee3d60bf..bac86127 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 002dc390..2b4f92a9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c42182df..e5ab042d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.14 + 0.10.15 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0f97b3ca..113edfb3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index a6913955..bd855314 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 852c0db1..afa51ea5 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 216b1b5b..f98a4958 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d6a40e17..e07d6985 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ef353458..72ea9b6f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index adb59a88..90a0da4b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 289dfeb0..83c2da35 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.14 + 0.10.15 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From cb55f51413380ffbab1a11f63704d04e854b6d82 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 23 Oct 2019 12:32:47 +0800 Subject: [PATCH 0200/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20FreeSql.DbCo?= =?UTF-8?q?ntext=20=E6=9E=84=E9=80=A0=E6=96=B9=E6=B3=95=EF=BC=8C=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E6=B3=A8=E5=85=A5=E4=BD=BF=E7=94=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ValuesController.cs | 37 ++++++++++--------- .../dbcontext_01/DbContexts/SongContext.cs | 9 +++-- FreeSql.DbContext/DbContext/DbContext.cs | 16 +++++--- .../Extensions/DependencyInjection.cs | 12 +++++- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs index 3cbb6af6..0df8ab90 100644 --- a/Examples/dbcontext_01/Controllers/ValuesController.cs +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -191,33 +191,34 @@ namespace dbcontext_01.Controllers - //using (var ctx = new SongContext()) { + using (ctx = new SongContext()) + { - // var song = new Song { }; - // await ctx.Songs.AddAsync(song); - // id = song.Id; + song = new Song { }; + await ctx.Songs.AddAsync(song); + id = song.Id; - // var adds = Enumerable.Range(0, 100) - // .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) - // .ToList(); - // await ctx.Songs.AddRangeAsync(adds); + adds = Enumerable.Range(0, 100) + .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .ToList(); + await ctx.Songs.AddRangeAsync(adds); - // for (var a = 0; a < adds.Count; a++) - // adds[a].Title = "dkdkdkdk" + a; + for (var a = 0; a < adds.Count; a++) + adds[a].Title = "dkdkdkdk" + a; - // ctx.Songs.UpdateRange(adds); + ctx.Songs.UpdateRange(adds); - // ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); + ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); - // //ctx.Songs.Update(adds.First()); + //ctx.Songs.Update(adds.First()); - // adds.Last().Url = "skldfjlksdjglkjjcccc"; - // ctx.Songs.Update(adds.Last()); + adds.Last().Url = "skldfjlksdjglkjjcccc"; + ctx.Songs.Update(adds.Last()); - // //throw new Exception("回滚"); + //throw new Exception("回滚"); - // await ctx.SaveChangesAsync(); - //} + await ctx.SaveChangesAsync(); + } } catch { diff --git a/Examples/dbcontext_01/DbContexts/SongContext.cs b/Examples/dbcontext_01/DbContexts/SongContext.cs index 2e0ddde9..da7da534 100644 --- a/Examples/dbcontext_01/DbContexts/SongContext.cs +++ b/Examples/dbcontext_01/DbContexts/SongContext.cs @@ -8,13 +8,16 @@ namespace dbcontext_01 public class SongContext : DbContext { + public SongContext() : base() { } + public SongContext(IFreeSql fsql) : base(fsql, null) { } public DbSet Songs { get; set; } public DbSet Tags { get; set; } - //protected override void OnConfiguring(DbContextOptionsBuilder builder) { - // builder.UseFreeSql(dbcontext_01.Startup.Fsql); - //} + protected override void OnConfiguring(DbContextOptionsBuilder builder) + { + builder.UseFreeSql(Startup.Fsql); + } } diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index c9d86010..ba543262 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -54,13 +54,19 @@ namespace FreeSql } #endregion - protected DbContext() + protected DbContext() : this(null, null) { } + protected DbContext(IFreeSql fsql, DbContextOptions options) { - var builder = new DbContextOptionsBuilder(); - OnConfiguring(builder); - _ormPriv = builder._fsql; - _optionsPriv = builder._options; + _ormPriv = fsql; + _optionsPriv = options; + if (_ormPriv == null) + { + var builder = new DbContextOptionsBuilder(); + OnConfiguring(builder); + _ormPriv = builder._fsql; + _optionsPriv = builder._options; + } if (_ormPriv != null) InitPropSets(); } protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { } diff --git a/FreeSql.DbContext/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Extensions/DependencyInjection.cs index 54ba7447..ebd575e1 100644 --- a/FreeSql.DbContext/Extensions/DependencyInjection.cs +++ b/FreeSql.DbContext/Extensions/DependencyInjection.cs @@ -12,7 +12,17 @@ namespace FreeSql { services.AddScoped(dbContextType, sp => { - var ctx = Activator.CreateInstance(dbContextType) as DbContext; + DbContext ctx = null; + try + { + var ctor = dbContextType.GetConstructors().FirstOrDefault(); + var ctorParams = ctor.GetParameters().Select(a => sp.GetService(a.ParameterType)).ToArray(); + ctx = Activator.CreateInstance(dbContextType, ctorParams) as DbContext; + } + catch(Exception ex) + { + throw new Exception($"AddFreeDbContext 发生错误,请检查 {dbContextType.Name} 的构造参数都已正确注入", ex); + } if (ctx != null && ctx._ormPriv == null) { var builder = new DbContextOptionsBuilder(); From 6f4262751b2b3bf01536f02066bb702c82e9fc20 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 23 Oct 2019 12:51:51 +0800 Subject: [PATCH 0201/1029] ## v0.11.1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5076068f..666e4154 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.10.15 + 0.11.1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 28355931..c980530c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index bac86127..95cd195b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2b4f92a9..58475c11 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e5ab042d..aa308763 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.15 + 0.11.1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 113edfb3..2a24dacf 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index bd855314..0d3d4bb0 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index afa51ea5..ce407f9f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index f98a4958..d0651c7d 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index e07d6985..cc3ea866 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 72ea9b6f..d1572c00 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 90a0da4b..e9d4b6d3 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 83c2da35..637f09ee 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.10.15 + 0.11.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 5b0b678c274ae3d3ad37ea3f08650057dcceb71c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 23 Oct 2019 21:05:50 +0800 Subject: [PATCH 0202/1029] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=20MySql/SqlSer?= =?UTF-8?q?ver=20CodeFirst=20=E5=90=8C=E6=AD=A5=E7=BB=93=E6=9E=84=20bug?= =?UTF-8?q?=EF=BC=9B=20=E5=BD=93=E8=A1=A8=E5=B7=B2=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E5=90=8E=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=A2=9E=E5=88=97=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E4=BA=A7=E7=94=9F=E7=9A=84=E8=84=9A=E6=9C=AC=E4=B8=8D?= =?UTF-8?q?=E5=BA=94=E8=AF=A5=E5=8C=85=E5=90=AB=E9=BB=98=E8=AE=A4=E8=AE=A4?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs | 2 +- Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs | 2 +- .../FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs | 2 +- Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index e8c38cb0..b7aa46a0 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -240,7 +240,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); } //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); + if (tbcol.Attribute.IsNullable == false && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 1aeff28f..b1f9b8c2 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -228,7 +228,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); } //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); + if (tbcol.Attribute.IsNullable == false && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 20416a9b..f9448e14 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -276,7 +276,7 @@ use " + database, tboldname ?? tbname); //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); - if (tbcol.Attribute.IsNullable == false) + if (tbcol.Attribute.IsNullable == false && tbcol.Attribute.IsIdentity == false) { var addcoldbdefault = tbcol.Attribute.DbDefautValue; if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index d786528b..e9249c2b 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -279,7 +279,7 @@ use " + database, tboldname ?? tbname); //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); - if (tbcol.Attribute.IsNullable == false) + if (tbcol.Attribute.IsNullable == false && tbcol.Attribute.IsIdentity == false) { var addcoldbdefault = tbcol.Attribute.DbDefautValue; if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); From b97156b482a205ed25dc2b72a75bd65e30270353 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 24 Oct 2019 02:17:22 +0800 Subject: [PATCH 0203/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IFreeSql.Glo?= =?UTF-8?q?balFilter=20=E5=85=A8=E5=B1=80=E8=BF=87=E6=BB=A4=E5=99=A8?= =?UTF-8?q?=EF=BC=9B=20-=20=E7=A7=BB=E9=99=A4=20TableAttribute.SelectFilte?= =?UTF-8?q?r=20=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 8 +-- .../DependencyInjection.cs | 0 .../FreeSqlRepositoryExtensions.cs} | 2 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 2 +- .../FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 2 +- .../DataAnnotations/MySqlFluentTest.cs | 6 +-- .../DataAnnotations/SqlServerFluentTest.cs | 6 +-- .../Sqlite/Curd/SqliteSelectTest.cs | 1 - FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 20 ++++++- FreeSql/DataAnnotations/TableAttribute.cs | 4 -- FreeSql/DataAnnotations/TableFluent.cs | 16 ------ FreeSql/FreeSql.xml | 52 +++++++++++++------ FreeSql/Interface/Curd/IDelete.cs | 7 +++ FreeSql/Interface/Curd/ISelect/ISelect0.cs | 7 +++ FreeSql/Interface/Curd/IUpdate.cs | 7 +++ FreeSql/Interface/IAop.cs | 2 +- FreeSql/Interface/IFreeSql.cs | 7 +++ FreeSql/Internal/CommonExpression.cs | 26 ++++++++-- .../Internal/CommonProvider/DeleteProvider.cs | 36 ++++++++++++- .../SelectProvider/Select0Provider.cs | 25 ++++++++- .../SelectProvider/Select1Provider.cs | 5 +- .../Internal/CommonProvider/UpdateProvider.cs | 28 ++++++++++ FreeSql/Internal/CommonUtils.cs | 3 -- FreeSql/Internal/GlobalFilter.cs | 43 +++++++++++++++ FreeSql/Internal/Model/TableInfo.cs | 1 - FreeSql/Internal/UtilsExpressionTree.cs | 1 - .../Curd/MySqlSelect.cs | 6 --- .../FreeSql.Provider.MySql/MySqlProvider.cs | 3 +- .../Default/Curd/OdbcSelect.cs | 6 --- .../Default/OdbcProvider.cs | 3 +- .../MySql/Curd/OdbcMySqlSelect.cs | 6 --- .../MySql/OdbcMySqlProvider.cs | 3 +- .../Oracle/Curd/OdbcOracleSelect.cs | 6 --- .../Oracle/OdbcOracleProvider.cs | 3 +- .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 6 --- .../PostgreSQL/OdbcPostgreSQLProvider.cs | 3 +- .../SqlServer/Curd/OdbcSqlServerSelect.cs | 12 ----- .../SqlServer/OdbcSqlServerProvider.cs | 3 +- .../Curd/OracleSelect.cs | 6 --- .../FreeSql.Provider.Oracle/OracleProvider.cs | 3 +- .../Curd/PostgreSQLSelect.cs | 6 --- .../PostgreSQLProvider.cs | 3 +- .../Curd/SqlServerSelect.cs | 12 ----- .../SqlServerProvider.cs | 3 +- .../Curd/SqliteSelect.cs | 6 --- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 3 +- 46 files changed, 271 insertions(+), 148 deletions(-) rename FreeSql.DbContext/Repository/{Extenssions => Extensions}/DependencyInjection.cs (100%) rename FreeSql.DbContext/Repository/{Extenssions/FreeSqlRepositoryExtenssions.cs => Extensions/FreeSqlRepositoryExtensions.cs} (98%) create mode 100644 FreeSql/Internal/GlobalFilter.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5ae14b30..8b5be7c7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -256,7 +256,7 @@ - +

返回默认仓库类 @@ -266,7 +266,7 @@ 数据过滤 + 验证 - + 返回默认仓库类,适用联合主键的仓储类 @@ -275,7 +275,7 @@ 数据过滤 + 验证 - + 返回仓库类 @@ -285,7 +285,7 @@ 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - + 创建基于仓储功能的工作单元,务必使用 using 包含使用 diff --git a/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs similarity index 100% rename from FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs rename to FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs diff --git a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs b/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs similarity index 98% rename from FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs rename to FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs index bafda690..9570ebdb 100644 --- a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs +++ b/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs @@ -3,7 +3,7 @@ using System; using System.Linq.Expressions; using System.Linq; -public static class FreeSqlRepositoryExtenssions +public static class FreeSqlRepositoryExtensions { /// diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 66c05d41..792618fc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -87,7 +87,7 @@ namespace FreeSql.Tests.MySqlConnector public virtual ICollection Tags { get; set; } } - [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] + [Table(Name = "TestInfoT1")] class TestInfo { [Column(IsIdentity = true, IsPrimary = true)] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index f0abaf46..4af3bc73 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -1003,7 +1003,7 @@ WHERE ROWNUM < 11"; } - [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] + [Table(Name = "TestInfoT1")] class TestInfo { [Column(IsIdentity = true, IsPrimary = true)] diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index 596a5dc1..efeca38c 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -68,21 +68,21 @@ namespace FreeSql.Tests.DataAnnotations { g.mysql.CodeFirst //.ConfigEntity(a => { - // a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0"); + // a.Name("xxdkdkdk1"); // a.Property(b => b.Id).Name("Id22").IsIdentity(true); // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); //}) .ConfigEntity(typeof(TestFluenttb1), a => { - a.Name("xxdkdkdk1222").SelectFilter("a.Id22dd > 1"); + a.Name("xxdkdkdk1222"); a.Property("Id").Name("Id22dd").IsIdentity(true); a.Property("Name").DbType("varchar(101)").IsNullable(true); }) .ConfigEntity(a => { - a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0"); + a.Name("xxdkdkdk2"); a.Property(b => b.Id).Name("Id22").IsIdentity(true); a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); }) diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs index cd6aee48..67effce4 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs @@ -41,21 +41,21 @@ namespace FreeSql.Tests.DataAnnotations { _sqlserverFixture.SqlServer.CodeFirst //.ConfigEntity(a => { - // a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0"); + // a.Name("xxdkdkdk1"); // a.Property(b => b.Id).Name("Id22").IsIdentity(true); // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); //}) .ConfigEntity(typeof(TestFluenttb1), a => { - a.Name("xxdkdkdk1222").SelectFilter("a.Id22dd > 1"); + a.Name("xxdkdkdk1222"); a.Property("Id").Name("Id22dd").IsIdentity(true); a.Property("Name").DbType("varchar(101)").IsNullable(true); }) .ConfigEntity(a => { - a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0"); + a.Name("xxdkdkdk2"); a.Property(b => b.Id).Name("Id22").IsIdentity(true); a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); }) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index c95152cd..15702301 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1106,7 +1106,6 @@ namespace FreeSql.Tests.Sqlite [Fact] public void Include_ManyToMany() { - var tag1 = new Tag { Ddd = DateTime.Now.Second, diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 7010bd98..214e0646 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -15,6 +15,7 @@ using Zeus; using Zeus.Domain.Enum; using System.ComponentModel.DataAnnotations; using System.Reflection; +using System.Threading; namespace FreeSql.Tests { @@ -415,10 +416,27 @@ namespace FreeSql.Tests } public enum TestAddEnumType { 中国人, 日本人 } + public static AsyncLocal TenrantId { get; set; } = new AsyncLocal(); [Fact] public void Test1() { + //g.mysql.GlobalFilter + // .Apply("test1", a => a.Id == TenrantId.Value) + // .Apply("test2", a => a.Id == 111) + // .Apply("test3", a => a.Name == "11"); + + TenrantId.Value = Guid.NewGuid(); g.mysql.Select().ToList(); + g.mysql.Select().DisableGlobalFilter("test1").ToList(); + g.mysql.Select().DisableGlobalFilter().ToList(); + + g.mysql.Delete().Where(a => a.Id == Guid.Empty).ExecuteAffrows(); + g.mysql.Delete().DisableGlobalFilter("test1").Where(a => a.Id == Guid.Empty).ExecuteAffrows(); + g.mysql.Delete().DisableGlobalFilter().Where(a => a.Id == Guid.Empty).ExecuteAffrows(); + + g.mysql.Update().SetSource(new TestAddEnum { Id = Guid.Empty }).ExecuteAffrows(); + g.mysql.Update().DisableGlobalFilter("test1").SetSource(new TestAddEnum { Id = Guid.Empty }).ExecuteAffrows(); + g.mysql.Update().DisableGlobalFilter().SetSource(new TestAddEnum { Id = Guid.Empty }).ExecuteAffrows(); g.sqlite.Insert(new TestGuidId { xxx = "111" }).ExecuteAffrows(); g.sqlite.Insert(new TestGuidId { xxx = "222" }).ExecuteAffrows(); @@ -1217,7 +1235,7 @@ namespace FreeSql.Tests } - [Table(Name = "TestInfoT1", SelectFilter = " a.id > 0")] + [Table(Name = "TestInfoT1")] class TestInfo { [Column(IsIdentity = true, IsPrimary = true)] diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index 7ec69bb0..b08b5c4f 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -16,10 +16,6 @@ namespace FreeSql.DataAnnotations /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 /// public string OldName { get; set; } - /// - /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - /// - public string SelectFilter { get; set; } internal bool? _DisableSyncStructure; /// diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index d29e94fa..633462b9 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -35,14 +35,6 @@ namespace FreeSql.DataAnnotations _table.OldName = value; return this; } - /// - /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - /// - public TableFluent SelectFilter(string value) - { - _table.SelectFilter = value; - return this; - } /// /// 禁用 CodeFirst 同步结构迁移 @@ -100,14 +92,6 @@ namespace FreeSql.DataAnnotations _table.OldName = value; return this; } - /// - /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - /// - public TableFluent SelectFilter(string value) - { - _table.SelectFilter = value; - return this; - } /// /// 禁用 CodeFirst 同步结构迁移 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 003ef946..19b0f167 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -192,11 +192,6 @@ 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - - 禁用 CodeFirst 同步结构迁移 @@ -212,11 +207,6 @@ 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - - 禁用 CodeFirst 同步结构迁移 @@ -241,11 +231,6 @@ 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 - - 禁用 CodeFirst 同步结构迁移 @@ -669,6 +654,13 @@ 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; @@ -1025,6 +1017,13 @@ 参数 + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) @@ -1763,6 +1762,13 @@ 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; @@ -2147,7 +2153,7 @@ - Insert/Update自动值处理, e.Column.SetMapValue( + Insert/Update自动值处理 @@ -2495,6 +2501,15 @@ Dict:key=属性名,value=注释 + + + 创建一个过滤器 + + + 名字 + 表达式 + + 中间表,多对多 @@ -2797,5 +2812,10 @@ DbFirst 模式开发相关方法 + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index a9ba7831..8dfda266 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -62,6 +62,13 @@ namespace FreeSql /// IDelete WhereDynamic(object dywhere); + /// + /// 禁用全局过滤功能,不传参数时将禁用所有 + /// + /// 零个或多个过滤器名字 + /// + IDelete DisableGlobalFilter(params string[] name); + /// /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index e115fabf..fad3ebe2 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -208,6 +208,13 @@ namespace FreeSql /// TSelect WhereIf(bool condition, string sql, object parms = null); + /// + /// 禁用全局过滤功能,不传参数时将禁用所有 + /// + /// 零个或多个过滤器名字 + /// + TSelect DisableGlobalFilter(params string[] name); + /// /// 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) /// diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index ff023c78..6b4d752a 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -131,6 +131,13 @@ namespace FreeSql /// IUpdate WhereDynamic(object dywhere); + /// + /// 禁用全局过滤功能,不传参数时将禁用所有 + /// + /// 零个或多个过滤器名字 + /// + IUpdate DisableGlobalFilter(params string[] name); + /// /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; /// diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index ce18c3ae..1135b633 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -56,7 +56,7 @@ namespace FreeSql EventHandler SyncStructureAfter { get; set; } /// - /// Insert/Update自动值处理, e.Column.SetMapValue( + /// Insert/Update自动值处理 /// EventHandler AuditValue { get; set; } } diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index f60fb182..e72033f9 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -1,6 +1,8 @@ using FreeSql; +using FreeSql.Internal; using System; using System.Collections.Generic; +using System.Linq.Expressions; public interface IFreeSql : IFreeSql { } @@ -112,4 +114,9 @@ public interface IFreeSql : IDisposable /// DbFirst 模式开发相关方法 /// IDbFirst DbFirst { get; } + + /// + /// 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + /// + GlobalFilter GlobalFilter { get; } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index bb2c63d0..1162d460 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1205,10 +1205,14 @@ namespace FreeSql.Internal var errorKey = FreeUtil.Sha1($"{tb.Table.Type.FullName},{fl.ToString()}"); if (_dicGetWhereCascadeSqlError.ContainsKey(errorKey)) continue; - var visitor = new NewExpressionVisitor(newParameter, fl.Parameters.FirstOrDefault()); + var visitor = new ReplaceVisitor(); try { - var expExp = visitor.Replace(fl.Body); + var expExp = Expression.Lambda( + typeof(Func<,>).MakeGenericType(tb.Table.Type, typeof(bool)), + new ReplaceVisitor().Modify(fl.Body, newParameter), + newParameter + ); var whereSql = ExpressionLambdaToSql(expExp, new ExpTSC { _tables = null, _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); if (isEmpty == false) sb.Append(" AND "); @@ -1228,10 +1232,22 @@ namespace FreeSql.Internal } return null; } - - public string formatSql(object obj, Type mapType) + class ReplaceVisitor : ExpressionVisitor { - return string.Concat(_ado.AddslashesProcessParam(obj, mapType)); + private ParameterExpression parameter; + public Expression Modify(Expression expression, ParameterExpression parameter) + { + this.parameter = parameter; + return Visit(expression); + } + protected override Expression VisitMember(MemberExpression node) + { + if (node.Expression?.NodeType == ExpressionType.Parameter) + return Expression.Property(parameter, node.Member.Name); + return base.VisitMember(node); + } } + + public string formatSql(object obj, Type mapType) => string.Concat(_ado.AddslashesProcessParam(obj, mapType)); } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index a28e7a75..dc25d95b 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; @@ -19,6 +20,7 @@ namespace FreeSql.Internal.CommonProvider protected Func _tableRule; protected StringBuilder _where = new StringBuilder(); protected int _whereTimes = 0; + protected List _whereGlobalFilter; protected List _params = new List(); protected DbTransaction _transaction; protected DbConnection _connection; @@ -31,6 +33,7 @@ namespace FreeSql.Internal.CommonProvider _table = _commonUtils.GetTableByEntity(typeof(T1)); this.Where(_commonUtils.WhereObject(_table, "", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); } protected void ClearData() @@ -38,6 +41,7 @@ namespace FreeSql.Internal.CommonProvider _where.Clear(); _whereTimes = 0; _params.Clear(); + _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); } public IDelete WithTransaction(DbTransaction transaction) @@ -99,6 +103,24 @@ namespace FreeSql.Internal.CommonProvider public IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); public IDelete WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + public IDelete DisableGlobalFilter(params string[] name) + { + if (_whereGlobalFilter.Any() == false) return this; + if (name?.Any() != true) + { + _whereGlobalFilter.Clear(); + return this; + } + foreach (var n in name) + { + if (n == null) continue; + var idx = _whereGlobalFilter.FindIndex(a => string.Compare(a.Name, n, true) == 0); + if (idx == -1) continue; + _whereGlobalFilter.RemoveAt(idx); + } + return this; + } + protected string TableRuleInvoke() { if (_tableRule == null) return _table.DbName; @@ -123,6 +145,18 @@ namespace FreeSql.Internal.CommonProvider return this; } - public string ToSql() => _whereTimes <= 0 ? null : new StringBuilder().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" WHERE ").Append(_where).ToString(); + public string ToSql() + { + if (_whereTimes <= 0) return null; + var sb = new StringBuilder().Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" WHERE ").Append(_where); + + if (_whereGlobalFilter.Any()) + { + var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList()); + if (string.IsNullOrEmpty(globalFilterCondi) == false) + sb.Append(" AND ").Append(globalFilterCondi); + } + return sb.ToString(); + } } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 93321ad1..0136eb97 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -35,6 +35,7 @@ namespace FreeSql.Internal.CommonProvider protected bool _distinct; protected Expression _selectExpression; protected List _whereCascadeExpression = new List(); + protected List _whereGlobalFilter; bool _isDisponse = false; ~Select0Provider() @@ -50,6 +51,8 @@ namespace FreeSql.Internal.CommonProvider _includeToList.Clear(); _selectExpression = null; _whereCascadeExpression.Clear(); + _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); + _whereCascadeExpression.AddRange(_whereGlobalFilter.Select(a => a.Where)); } public static void CopyData(Select0Provider from, object to, ReadOnlyCollection lambParms) { @@ -93,7 +96,8 @@ namespace FreeSql.Internal.CommonProvider toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); - toType.GetField("_whereMultiExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression); + toType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression); + toType.GetField("_whereGlobalFilter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereGlobalFilter); } public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) @@ -884,6 +888,25 @@ namespace FreeSql.Internal.CommonProvider if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); return this as TSelect; } + public TSelect DisableGlobalFilter(params string[] name) + { + if (_whereGlobalFilter.Any() == false) return this as TSelect; + if (name?.Any() != true) + { + _whereCascadeExpression.RemoveRange(0, _whereGlobalFilter.Count); + _whereGlobalFilter.Clear(); + return this as TSelect; + } + foreach (var n in name) + { + if (n == null) continue; + var idx = _whereGlobalFilter.FindIndex(a => string.Compare(a.Name, n, true) == 0); + if (idx == -1) continue; + _whereCascadeExpression.RemoveAt(idx); + _whereGlobalFilter.RemoveAt(idx); + } + return this as TSelect; + } #region common protected TMember InternalAvg(Expression exp) => this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index ba3fdbe7..15b20b4a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -22,7 +22,8 @@ namespace FreeSql.Internal.CommonProvider { public Select1Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - + _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); + _whereCascadeExpression.AddRange(_whereGlobalFilter.Select(a => a.Where)); } protected ISelect InternalFrom(LambdaExpression lambdaExp) @@ -575,7 +576,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var item in list) setListValue(item, null); - var subSelect = _orm.Select().WithConnection(_connection).WithTransaction(_transaction).TrackToList(_trackToList) as Select1Provider; + var subSelect = _orm.Select().DisableGlobalFilter().WithConnection(_connection).WithTransaction(_transaction).TrackToList(_trackToList) as Select1Provider; if (_tableRules?.Any() == true) foreach (var tr in _tableRules) subSelect.AsTable(tr); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 1cd348f8..d98b6392 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -23,6 +23,7 @@ namespace FreeSql.Internal.CommonProvider protected TableInfo _table; protected Func _tableRule; protected StringBuilder _where = new StringBuilder(); + protected List _whereGlobalFilter; protected StringBuilder _set = new StringBuilder(); protected StringBuilder _setIncr = new StringBuilder(); protected List _params = new List(); @@ -41,6 +42,7 @@ namespace FreeSql.Internal.CommonProvider this.Where(_commonUtils.WhereObject(_table, "", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); IgnoreCanUpdate(); + _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); } /// @@ -63,6 +65,7 @@ namespace FreeSql.Internal.CommonProvider _params.Clear(); _paramsSource.Clear(); IgnoreCanUpdate(); + _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); } public IUpdate WithTransaction(DbTransaction transaction) @@ -428,6 +431,24 @@ namespace FreeSql.Internal.CommonProvider public IUpdate WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); public IUpdate WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + public IUpdate DisableGlobalFilter(params string[] name) + { + if (_whereGlobalFilter.Any() == false) return this; + if (name?.Any() != true) + { + _whereGlobalFilter.Clear(); + return this; + } + foreach (var n in name) + { + if (n == null) continue; + var idx = _whereGlobalFilter.FindIndex(a => string.Compare(a.Name, n, true) == 0); + if (idx == -1) continue; + _whereGlobalFilter.RemoveAt(idx); + } + return this; + } + protected string WhereCaseSource(string CsName, Func thenValue) { if (_source.Any() == false) return null; @@ -611,6 +632,13 @@ namespace FreeSql.Internal.CommonProvider if (_where.Length > 0) sb.Append(_source.Any() ? _where.ToString() : _where.ToString().Substring(5)); + if (_whereGlobalFilter.Any()) + { + var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList()); + if (string.IsNullOrEmpty(globalFilterCondi) == false) + sb.Append(" AND ").Append(globalFilterCondi); + } + if (_table.VersionColumn != null) { var versionCondi = WhereCaseSource(_table.VersionColumn.CsName, sqlval => sqlval); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 656bd04a..cdfe4a34 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -85,7 +85,6 @@ namespace FreeSql.Internal { if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name; if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; - if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter; if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; } var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); @@ -95,12 +94,10 @@ namespace FreeSql.Internal if (tryattr == null) continue; if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; - if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter; if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure; } if (!string.IsNullOrEmpty(attr.Name)) return attr; if (!string.IsNullOrEmpty(attr.OldName)) return attr; - if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr; if (attr._DisableSyncStructure != null) return attr; return null; } diff --git a/FreeSql/Internal/GlobalFilter.cs b/FreeSql/Internal/GlobalFilter.cs new file mode 100644 index 00000000..40bab709 --- /dev/null +++ b/FreeSql/Internal/GlobalFilter.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Internal +{ + public class GlobalFilter + { + ConcurrentDictionary _filters = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + int _id = 0; + + public class Item + { + public int Id { get; internal set; } + public string Name { get; internal set; } + public LambdaExpression Where { get; internal set; } + } + /// + /// 创建一个过滤器 + /// + /// + /// 名字 + /// 表达式 + /// + public GlobalFilter Apply(string name, Expression> where) + { + if (name == null) throw new ArgumentNullException(nameof(name)); + if (where == null) return this; + + _filters.TryGetValue(name, out var item); + if (item == null) item = new Item { Id = ++_id, Name = name }; + item.Where = where; + _filters.AddOrUpdate(name, item, (_, __) => item); + return this; + } + public void Remove(string name) => _filters.TryRemove(name ?? throw new ArgumentNullException(nameof(name)), out var _); + + public List GetFilters() => _filters.Values.OrderBy(a => a.Id).ToList(); + } +} diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index 398721a6..09223d1d 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -21,7 +21,6 @@ namespace FreeSql.Internal.Model public string CsName { get; set; } public string DbName { get; set; } public string DbOldName { get; set; } - public string SelectFilter { get; set; } public bool DisableSyncStructure { get; set; } public ColumnInfo VersionColumn { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 029d0518..9d55d00d 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -65,7 +65,6 @@ namespace FreeSql.Internal trytb.DbName = trytb.DbName.ToUpper(); trytb.DbOldName = trytb.DbOldName?.ToUpper(); } - trytb.SelectFilter = tbattr?.SelectFilter; if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; var propsLazy = new List<(PropertyInfo, bool, bool)>(); var propsNavObjs = new List(); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index b0a3bd8c..002698bc 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -87,12 +87,6 @@ namespace FreeSql.MySql.Curd if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index 8617ef5e..1ce3cf0b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -69,9 +69,10 @@ namespace FreeSql.MySql internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~MySqlProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index 14e8c520..c233952c 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -101,12 +101,6 @@ namespace FreeSql.Odbc.Default if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index 740fbfab..a0c38cd9 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -82,9 +82,10 @@ namespace FreeSql.Odbc.Default internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~OdbcProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index 1d9707c3..a94e6935 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -87,12 +87,6 @@ namespace FreeSql.Odbc.MySql if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index ccc5830e..d1fa229f 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -47,9 +47,10 @@ namespace FreeSql.Odbc.MySql internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~OdbcMySqlProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index 6d523552..db466e69 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -89,12 +89,6 @@ namespace FreeSql.Odbc.Oracle if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); if (sbnav.Length > 0) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index be0e4c11..974bf391 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -48,9 +48,10 @@ namespace FreeSql.Odbc.Oracle internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~OdbcOracleProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index d980d39e..1e5a8fb1 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -87,12 +87,6 @@ namespace FreeSql.Odbc.PostgreSQL if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index 5313d309..26da3b6d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -45,9 +45,10 @@ namespace FreeSql.Odbc.PostgreSQL internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~OdbcPostgreSQLProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index a6cebe01..52f7322d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -105,12 +105,6 @@ namespace FreeSql.Odbc.SqlServer if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); @@ -211,12 +205,6 @@ namespace FreeSql.Odbc.SqlServer if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index 0f5c1203..a13e4e67 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -53,9 +53,10 @@ namespace FreeSql.Odbc.SqlServer internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~OdbcSqlServerProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 517b14e3..26e7ce7f 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -89,12 +89,6 @@ namespace FreeSql.Oracle.Curd if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); if (sbnav.Length > 0) diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index f425a362..6f938cf6 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -43,9 +43,10 @@ namespace FreeSql.Oracle internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~OracleProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index a170aa5c..23a04138 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -87,12 +87,6 @@ namespace FreeSql.PostgreSQL.Curd if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index b781993f..50f25473 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -96,9 +96,10 @@ namespace FreeSql.PostgreSQL internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~PostgreSQLProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index ef13ba09..25a584b9 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -105,12 +105,6 @@ namespace FreeSql.SqlServer.Curd if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); @@ -211,12 +205,6 @@ namespace FreeSql.SqlServer.Curd if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index 467f7c96..b9de151e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -54,9 +54,10 @@ namespace FreeSql.SqlServer internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~SqlServerProvider() { this.Dispose(); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index a5b3992b..74953e74 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -87,12 +87,6 @@ namespace FreeSql.Sqlite.Curd if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - foreach (var tb in _tables) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false) - sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")"); - } if (sbnav.Length > 0) { sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index ef67538b..9a8b665d 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -42,9 +42,10 @@ namespace FreeSql.Sqlite internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + ~SqliteProvider() { this.Dispose(); From 23f60732e0c3197f6a94b8ae6fdf6bad5c873410 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 24 Oct 2019 02:19:03 +0800 Subject: [PATCH 0204/1029] ## v0.11.2 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 666e4154..f4b0fd23 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.1 + 0.11.2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index c980530c..5cdd5ecf 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 95cd195b..f01968fd 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 58475c11..8aee5931 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index aa308763..dc2ed02d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.1 + 0.11.2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2a24dacf..41ebedf5 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0d3d4bb0..7367e568 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ce407f9f..6df19d62 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d0651c7d..4f60b323 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index cc3ea866..49e96ffc 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d1572c00..456c120b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e9d4b6d3..9e256818 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 637f09ee..27e70af4 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.1 + 0.11.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 96893cbcd1b5e6d275599c5c010e524b0a1199f4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 24 Oct 2019 02:26:48 +0800 Subject: [PATCH 0205/1029] update --- functions05.png | Bin 95964 -> 0 bytes functions06.png | Bin 0 -> 97690 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 functions05.png create mode 100644 functions06.png diff --git a/functions05.png b/functions05.png deleted file mode 100644 index fa3c97ba210863963376c652db5c3aedb4aa9b82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95964 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

U 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 literal 0 HcmV?d00001 From 3338c5806e0253c5a92cb6b9e1f184abe1efa612 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 24 Oct 2019 02:27:27 +0800 Subject: [PATCH 0206/1029] update --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index fafa5822..be21c33d 100644 --- a/readme.md +++ b/readme.md @@ -65,7 +65,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | FreeSql.Extensions.BaseEntity | NETStandard2.0 |

- +

# Quick start From 06fba16b4a6a40b674cd79decdd9102b182f8f53 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 24 Oct 2019 02:29:49 +0800 Subject: [PATCH 0207/1029] update functions png --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index be21c33d..7ce17a99 100644 --- a/readme.md +++ b/readme.md @@ -65,7 +65,7 @@ FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore | FreeSql.Extensions.BaseEntity | NETStandard2.0 |

- +

# Quick start From f7633e9f674da64309f8840f1b5880cbecc79858 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 26 Oct 2019 11:11:05 +0800 Subject: [PATCH 0208/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.DbCo?= =?UTF-8?q?ntext=20DbSet=20Remove=20=E5=8F=AF=E6=A0=B9=E6=8D=AE=20lambda?= =?UTF-8?q?=20=E6=9D=A1=E4=BB=B6=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetAsync.cs | 10 ++++++++++ FreeSql.DbContext/DbSet/DbSetSync.cs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 33f26e2a..de28479d 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -377,6 +377,16 @@ namespace FreeSql _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); return Math.Max(dels.Length, affrows); } + /// + /// 根据 lambda 条件删除数据 + /// + /// + /// + async public Task RemoveAsync(Expression> predicate) + { + await DbContextExecCommandAsync(); + return await this.OrmDelete(null).Where(predicate).ExecuteAffrowsAsync(); + } #endregion #region AddOrUpdateAsync diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 35f8b091..52068519 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -410,6 +410,16 @@ namespace FreeSql EnqueueToDbContext(DbContext.EntityChangeType.Delete, state); } } + /// + /// 根据 lambda 条件删除数据 + /// + /// + /// + public int Remove(Expression> predicate) + { + DbContextExecCommand(); + return this.OrmDelete(null).Where(predicate).ExecuteAffrows(); + } #endregion #region AddOrUpdate From 97351a4e6e99bb44b8ea980a4fb5cefe6d2f8859 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 29 Oct 2019 09:55:54 +0800 Subject: [PATCH 0209/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20Aop.AuditVal?= =?UTF-8?q?ue=20=E5=AE=A1=E8=AE=A1=E8=BF=87=E7=9A=84=E5=80=BC=EF=BC=8CIUpd?= =?UTF-8?q?ate.UpdateColumns=20=E5=8D=B3=E4=BD=BF=E4=B8=8D=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E8=AF=A5=E5=88=97=E4=B9=9F=E4=BC=9A=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSet.cs | 4 ++-- FreeSql.DbContext/FreeSql.DbContext.xml | 14 +++++++++++ .../Sqlite/Curd/SqliteSelectTest.cs | 4 +++- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 13 ++++++++++ .../Internal/CommonProvider/InsertProvider.cs | 20 ++++++++++------ .../Internal/CommonProvider/UpdateProvider.cs | 24 +++++++++++++------ 6 files changed, 62 insertions(+), 17 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 56651882..6150feb4 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -236,7 +236,7 @@ namespace FreeSql if (isThrow) throw new Exception($"不可添加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } - FreeSql.Internal.CommonProvider.InsertProvider.AuditDataValue(this, data, _db.Orm, _table); + FreeSql.Internal.CommonProvider.InsertProvider.AuditDataValue(this, data, _db.Orm, _table, null); var key = _db.Orm.GetEntityKeyString(_entityType, data, true); if (string.IsNullOrEmpty(key)) { @@ -294,7 +294,7 @@ namespace FreeSql if (isThrow) throw new Exception($"不可更新,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); return false; } - FreeSql.Internal.CommonProvider.UpdateProvider.AuditDataValue(this, data, _db.Orm, _table); + FreeSql.Internal.CommonProvider.UpdateProvider.AuditDataValue(this, data, _db.Orm, _table, null); var key = _db.Orm.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) { diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 8b5be7c7..2711e35d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,6 +99,13 @@ 清空状态数据
+ + + 根据 lambda 条件删除数据 + + + + 添加 @@ -124,6 +131,13 @@ + + + 根据 lambda 条件删除数据 + + + + 添加或更新 diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 15702301..2a29e6a0 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -141,6 +141,8 @@ namespace FreeSql.Tests.Sqlite public bool? testBool1 { get; set; } public bool? testBool2 { get; set; } + + public TestDtoLeftJoin Obj { get; set; } } class TestDtoLeftJoin { @@ -167,7 +169,7 @@ namespace FreeSql.Tests.Sqlite var testDto3 = select.Limit(10).ToList(a => new TestDto { }); var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); - var testDto11 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto11 = select.From((_, b) => _.LeftJoin(a => b.Guid == a.TypeGuid)).Limit(10).ToList((a, b) => new TestDto { id = a.Id, name = a.Title, Obj = b }); var testDto22 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); var testDto33 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 214e0646..df1dff9a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -408,6 +408,7 @@ namespace FreeSql.Tests { public Guid? Id { get; set; } public string xxx { get; set; } + public string yyy { get; set; } } public class TestAddEnum { @@ -420,6 +421,18 @@ namespace FreeSql.Tests [Fact] public void Test1() { + + //g.mysql.Aop.AuditValue += (_, e) => + //{ + // if (e.AuditValueType == FreeSql.Aop.AuditValueType.Update) + // { + // if (e.Property.Name == "xxx") + // e.Value = "xxx"; + // } + //}; + //var tttee = g.mysql.Select().Limit(5).ToList(); + //g.mysql.GetGuidRepository().UpdateDiy.SetSource(tttee).UpdateColumns(a => new { a.yyy }).NoneParameter().ExecuteAffrows(); + //g.mysql.GlobalFilter // .Apply("test1", a => a.Id == TenrantId.Value) // .Apply("test2", a => a.Id == 111) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 1130da06..f0389815 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -19,6 +19,7 @@ namespace FreeSql.Internal.CommonProvider protected CommonExpression _commonExpression; protected List _source = new List(); protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + protected Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); protected TableInfo _table; protected Func _tableRule; protected bool _noneParameter, _insertIdentity; @@ -52,6 +53,7 @@ namespace FreeSql.Internal.CommonProvider _insertIdentity = false; _source.Clear(); _ignore.Clear(); + _auditValueChangedDict.Clear(); _params = null; IgnoreCanInsert(); } @@ -85,7 +87,7 @@ namespace FreeSql.Internal.CommonProvider { if (source != null) { - AuditDataValue(this, source, _orm, _table); + AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.Add(source); } return this; @@ -94,7 +96,7 @@ namespace FreeSql.Internal.CommonProvider { if (source != null) { - AuditDataValue(this, source, _orm, _table); + AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.AddRange(source); } return this; @@ -104,19 +106,19 @@ namespace FreeSql.Internal.CommonProvider if (source != null) { source = source.Where(a => a != null).ToList(); - AuditDataValue(this, source, _orm, _table); + AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.AddRange(source); } return this; } - public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table) + public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data?.Any() != true) return; foreach (var d in data) - AuditDataValue(sender, d, orm, table); + AuditDataValue(sender, d, orm, table, changedDict); } - public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table) + public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data == null) return; foreach (var col in table.Columns.Values) @@ -129,7 +131,11 @@ namespace FreeSql.Internal.CommonProvider var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); orm.Aop.AuditValue(sender, auditArgs); if (auditArgs.IsChanged) + { col.SetMapValue(data, val = auditArgs.Value); + if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) + changedDict.Add(col.Attribute.Name, true); + } } } } @@ -375,7 +381,7 @@ namespace FreeSql.Internal.CommonProvider var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); _ignore.Clear(); foreach (var col in _table.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name) == false) + if (cols.ContainsKey(col.Attribute.Name) == false && _auditValueChangedDict.ContainsKey(col.Attribute.Name) == false) _ignore.Add(col.Attribute.Name, true); return this; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index d98b6392..c4ddd9d2 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -20,6 +20,7 @@ namespace FreeSql.Internal.CommonProvider protected CommonExpression _commonExpression; protected List _source = new List(); protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + protected Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); protected TableInfo _table; protected Func _tableRule; protected StringBuilder _where = new StringBuilder(); @@ -59,6 +60,7 @@ namespace FreeSql.Internal.CommonProvider { _source.Clear(); _ignore.Clear(); + _auditValueChangedDict.Clear(); _where.Clear(); _set.Clear(); _setIncr.Clear(); @@ -281,12 +283,12 @@ namespace FreeSql.Internal.CommonProvider var cols = columns.ToDictionary(a => a); _ignore.Clear(); foreach (var col in _table.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name) == false && cols.ContainsKey(col.CsName) == false) + if (cols.ContainsKey(col.Attribute.Name) == false && cols.ContainsKey(col.CsName) == false && _auditValueChangedDict.ContainsKey(col.Attribute.Name) == false) _ignore.Add(col.Attribute.Name, true); return this; } - public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table) + public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data?.Any() != true) return; if (orm.Aop.AuditValue == null) return; @@ -299,11 +301,15 @@ namespace FreeSql.Internal.CommonProvider var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); orm.Aop.AuditValue(sender, auditArgs); if (auditArgs.IsChanged) + { col.SetMapValue(d, val = auditArgs.Value); + if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) + changedDict.Add(col.Attribute.Name, true); + } } } } - public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table) + public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (orm.Aop.AuditValue == null) return; if (data == null) return; @@ -313,7 +319,11 @@ namespace FreeSql.Internal.CommonProvider var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); orm.Aop.AuditValue(sender, auditArgs); if (auditArgs.IsChanged) + { col.SetMapValue(data, val = auditArgs.Value); + if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) + changedDict.Add(col.Attribute.Name, true); + } } } @@ -321,7 +331,7 @@ namespace FreeSql.Internal.CommonProvider public IUpdate SetSource(IEnumerable source) { if (source == null || source.Any() == false) return this; - AuditDataValue(this, source, _orm, _table); + AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.AddRange(source.Where(a => a != null)); return this; } @@ -486,9 +496,9 @@ namespace FreeSql.Internal.CommonProvider cwsb.Append(" \r\nWHEN "); ToSqlWhen(cwsb, _table.Primarys, d); cwsb.Append(" THEN "); - var value = col.GetMapValue(d); - cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value))); - if (value == null || value == DBNull.Value) nulls++; + var val = col.GetMapValue(d); + cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val))); + if (val == null || val == DBNull.Value) nulls++; } cwsb.Append(" END"); if (nulls == _source.Count) sb.Append("NULL"); From 687db9ed7186523e3b44a1ed8e569a9167c5d500 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 29 Oct 2019 09:57:21 +0800 Subject: [PATCH 0210/1029] ## v0.11.3 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f4b0fd23..6d44215c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.2 + 0.11.3 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 5cdd5ecf..5567e93a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index f01968fd..93b15d89 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8aee5931..f14194e0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..3f9fb047 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,13 +99,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index dc2ed02d..3ed4b556 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.2 + 0.11.3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 41ebedf5..01aa0aee 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 7367e568..2fc9f349 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6df19d62..a4af4326 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 4f60b323..ef949047 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 49e96ffc..ec8ac908 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 456c120b..ec994e30 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9e256818..c7ef4573 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 27e70af4..e618839b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.2 + 0.11.3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From db7fe8240379c51f90102b0de4fd3de6a849b8b8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 30 Oct 2019 18:00:13 +0800 Subject: [PATCH 0211/1029] =?UTF-8?q?-=20=E7=A7=BB=E9=99=A4=20IUpdate/IDel?= =?UTF-8?q?ete=20WhereExists=20=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../MySqlConnector/Curd/MySqlDeleteTest.cs | 5 ----- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 5 ----- .../Default/Curd/OdbcDeleteTest.cs | 5 ----- .../Default/Curd/OdbcUpdateTest.cs | 5 ----- .../MySql/Curd/MySqlDeleteTest.cs | 5 ----- .../MySql/Curd/MySqlUpdateTest.cs | 5 ----- .../Oracle/Curd/OracleDeleteTest.cs | 5 ----- .../Oracle/Curd/OracleUpdateTest.cs | 5 ----- .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 5 ----- .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 5 ----- .../SqlServer/Curd/SqlServerDeleteTest.cs | 5 ----- .../SqlServer/Curd/SqlServerUpdateTest.cs | 5 ----- .../MySql/Curd/MySqlDeleteTest.cs | 5 ----- .../MySql/Curd/MySqlUpdateTest.cs | 5 ----- .../Oracle/Curd/OracleDeleteTest.cs | 5 ----- .../Oracle/Curd/OracleUpdateTest.cs | 5 ----- .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 5 ----- .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 5 ----- .../SqlServer/Curd/SqlServerDeleteTest.cs | 5 ----- .../SqlServer/Curd/SqlServerUpdateTest.cs | 5 ----- .../Sqlite/Curd/SqliteDeleteTest.cs | 5 ----- .../Sqlite/Curd/SqliteUpdateTest.cs | 5 ----- FreeSql/FreeSql.xml | 18 ------------------ FreeSql/Interface/Curd/IDelete.cs | 8 -------- FreeSql/Interface/Curd/IUpdate.cs | 8 -------- .../Internal/CommonProvider/DeleteProvider.cs | 1 - .../Internal/CommonProvider/UpdateProvider.cs | 1 - .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 33 files changed, 6 insertions(+), 152 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 93b15d89..8e7d115b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -23,7 +23,7 @@ - + diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index f14194e0..82760af8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45;net40 + netstandard2.1;netstandard2.0;net45;net40 0.11.3 true YeXiangQin diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3ed4b556..54a1d6fe 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45;net40 + netstandard2.1;netstandard2.0;net45;net40 0.11.3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs index 52704fea..6d098eb6 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs @@ -56,11 +56,6 @@ namespace FreeSql.Tests.MySqlConnector sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 050e8e22..992bc4cf 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -173,11 +173,6 @@ namespace FreeSql.Tests.MySqlConnector sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs index fe33795c..702039c4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs @@ -56,11 +56,6 @@ namespace FreeSql.Tests.Odbc.Default sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs index f5686dbd..6ebcd701 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs @@ -114,11 +114,6 @@ namespace FreeSql.Tests.Odbc.Default for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs index 78318541..84b5f642 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs @@ -56,11 +56,6 @@ namespace FreeSql.Tests.Odbc.MySql sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs index 8513b170..c6cf8693 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -173,11 +173,6 @@ namespace FreeSql.Tests.Odbc.MySql sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs index 4683aeac..0cc8be3b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs @@ -57,11 +57,6 @@ namespace FreeSql.Tests.Odbc.Oracle sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs index a91f7dee..ef16ca98 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -112,11 +112,6 @@ namespace FreeSql.Tests.Odbc.Oracle for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index 0af7e64c..33cbd7de 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -57,11 +57,6 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index d775f9ab..7808a318 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -113,11 +113,6 @@ namespace FreeSql.Tests.Odbc.PostgreSQL for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs index 1105f760..7de0c816 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs @@ -57,11 +57,6 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs index cd9c2d37..edf2bd99 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs @@ -115,11 +115,6 @@ namespace FreeSql.Tests.Odbc.SqlServer for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs index 329cb3aa..16380704 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs @@ -57,11 +57,6 @@ namespace FreeSql.Tests.MySql sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 7d42b257..ebcf418c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -174,11 +174,6 @@ namespace FreeSql.Tests.MySql sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs index 807d1c97..f3158cce 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs @@ -57,11 +57,6 @@ namespace FreeSql.Tests.Oracle sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 05385ddd..4d83817d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -112,11 +112,6 @@ namespace FreeSql.Tests.Oracle for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index 4224dc32..f9333d1e 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -57,11 +57,6 @@ namespace FreeSql.Tests.PostgreSQL sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index f242ca7d..6d10bf81 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -113,11 +113,6 @@ namespace FreeSql.Tests.PostgreSQL for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs index 196ba9b0..ea3c40f9 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs @@ -65,11 +65,6 @@ namespace FreeSql.Tests.SqlServer sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 2c2cfc31..8ca8a169 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -124,11 +124,6 @@ namespace FreeSql.Tests.SqlServer for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs index 8a58358e..5f1fd2f9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs @@ -57,11 +57,6 @@ namespace FreeSql.Tests.Sqlite sql = delete.Where(items).ToSql().Replace("\r\n", ""); Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index 136a4eb3..b752651c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -117,11 +117,6 @@ namespace FreeSql.Tests.Sqlite for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); - } - [Fact] - public void WhereExists() - { - } [Fact] public void ExecuteAffrows() diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 19b0f167..612a2210 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -638,15 +638,6 @@ 实体集合 - - - 子查询是否存在 - - - 子查询 - 不存在 - - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} @@ -1746,15 +1737,6 @@ 实体集合 - - - 子查询是否存在 - - - 子查询 - 不存在 - - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 8dfda266..37302573 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -48,14 +48,6 @@ namespace FreeSql /// IDelete Where(IEnumerable items); /// - /// 子查询是否存在 - /// - /// - /// 子查询 - /// 不存在 - /// - IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class; - /// /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 6b4d752a..b2d68ea6 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -117,14 +117,6 @@ namespace FreeSql /// IUpdate Where(IEnumerable items); /// - /// 子查询是否存在 - /// - /// - /// 子查询 - /// 不存在 - /// - IUpdate WhereExists(ISelect select, bool notExists = false) where TEntity2 : class; - /// /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index dc25d95b..5e2e5a50 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -100,7 +100,6 @@ namespace FreeSql.Internal.CommonProvider } public IDelete Where(T1 item) => this.Where(new[] { item }); public IDelete Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); - public IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); public IDelete WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); public IDelete DisableGlobalFilter(params string[] name) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index c4ddd9d2..a24fa28e 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -438,7 +438,6 @@ namespace FreeSql.Internal.CommonProvider } public IUpdate Where(T1 item) => this.Where(new[] { item }); public IUpdate Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); - public IUpdate WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); public IUpdate WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); public IUpdate DisableGlobalFilter(params string[] name) diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 2fc9f349..d343f971 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -23,7 +23,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a4af4326..f88b8754 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -23,7 +23,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e618839b..3543928b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -23,7 +23,7 @@ - + From 21b4b0d5d396b2a97c3dd2abea5f1e7bf8129935 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 30 Oct 2019 20:35:42 +0800 Subject: [PATCH 0212/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect=20To?= =?UTF-8?q?Delete/ToUpdate=20=E6=96=B9=E6=B3=95=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=9B=B4=E5=A4=8D=E6=9D=82=E7=9A=84=E5=88=A0=E9=99=A4/?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=93=8D=E4=BD=9C=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + .../MySqlConnector/Curd/MySqlSelectTest.cs | 134 ++++++++++++++++++ .../Default/Curd/OdbcSelectTest.cs | 134 ++++++++++++++++++ .../MySql/Curd/MySqlSelectTest.cs | 134 ++++++++++++++++++ .../Oracle/Curd/OracleSelectTest.cs | 134 ++++++++++++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 134 ++++++++++++++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 134 ++++++++++++++++++ .../MySql/Curd/MySqlSelectTest.cs | 134 ++++++++++++++++++ .../Oracle/Curd/OracleSelectTest.cs | 134 ++++++++++++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 134 ++++++++++++++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 134 ++++++++++++++++++ .../Sqlite/Curd/SqliteSelectTest.cs | 134 ++++++++++++++++++ FreeSql/FreeSql.xml | 30 +++- FreeSql/Interface/Curd/IDelete.cs | 3 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 25 +++- FreeSql/Interface/Curd/IUpdate.cs | 3 +- .../SelectProvider/Select0Provider.cs | 37 +++++ FreeSql/Internal/UtilsExpressionTree.cs | 6 +- .../Default/OdbcAdapter.cs | 6 +- .../SqlServer/OdbcSqlServerUtils.cs | 6 +- .../SqlServerUtils.cs | 6 +- 21 files changed, 1594 insertions(+), 9 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3f9fb047..2711e35d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,6 +99,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 792618fc..03ead48d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1358,5 +1358,139 @@ namespace FreeSql.Tests.MySqlConnector .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index a9184ea1..a381b2fa 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -1202,5 +1202,139 @@ namespace FreeSql.Tests.Odbc.Default .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.odbc.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.odbc.Select().Count()); + g.odbc.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.odbc.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.odbc.Select().Count()); + Assert.Equal(3, g.odbc.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.odbc.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.odbc.Select().Count()); + g.odbc.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.odbc.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.odbc.Select().Count()); + Assert.Equal(3, g.odbc.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.odbc.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.odbc.Select().Count()); + g.odbc.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.odbc.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.odbc.Select().Count()); + Assert.Equal(3, g.odbc.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.odbc.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.odbc.Select().Count()); + g.odbc.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.odbc.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.odbc.Select().Count()); + Assert.Equal(5, g.odbc.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.odbc.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.odbc.Select().Count()); + g.odbc.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.odbc.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.odbc.Select().Count()); + Assert.Equal(5, g.odbc.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.odbc.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.odbc.Select().Count()); + g.odbc.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.odbc.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.odbc.Select().Count()); + Assert.Equal(5, g.odbc.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 3c3813b2..6fc08172 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1348,5 +1348,139 @@ namespace FreeSql.Tests.Odbc.MySql .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index ac553fd0..9c9a7d8f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -1232,5 +1232,139 @@ namespace FreeSql.Tests.Odbc.Oracle .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 1854ddee..385cdef5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1306,5 +1306,139 @@ namespace FreeSql.Tests.Odbc.PostgreSQL .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 07051350..80be8d34 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -1220,5 +1220,139 @@ namespace FreeSql.Tests.Odbc.SqlServer .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index b98117d7..465996c9 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1348,5 +1348,139 @@ namespace FreeSql.Tests.MySql .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 137ddcc7..92ecbd0c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -1232,5 +1232,139 @@ namespace FreeSql.Tests.Oracle .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 585e7335..218713f8 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1306,5 +1306,139 @@ namespace FreeSql.Tests.PostgreSQL .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 38217d09..cafe5afa 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1229,5 +1229,139 @@ namespace FreeSql.Tests.SqlServer .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 2a29e6a0..8c5c0c86 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1209,5 +1209,139 @@ namespace FreeSql.Tests.Sqlite .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.sqlite.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlite.Select().Count()); + g.sqlite.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlite.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlite.Select().Count()); + Assert.Equal(3, g.sqlite.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlite.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlite.Select().Count()); + g.sqlite.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlite.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlite.Select().Count()); + Assert.Equal(3, g.sqlite.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlite.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlite.Select().Count()); + g.sqlite.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlite.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlite.Select().Count()); + Assert.Equal(3, g.sqlite.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.sqlite.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlite.Select().Count()); + g.sqlite.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlite.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlite.Select().Count()); + Assert.Equal(5, g.sqlite.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlite.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlite.Select().Count()); + g.sqlite.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlite.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlite.Select().Count()); + Assert.Equal(5, g.sqlite.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlite.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlite.Select().Count()); + g.sqlite.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlite.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlite.Select().Count()); + Assert.Equal(5, g.sqlite.Select().Where(a => a.name.StartsWith("nick")).Count()); + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 612a2210..eb505313 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -611,7 +611,8 @@ - lambda表达式条件,仅支持实体基础成员(不包含导航对象) + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToDelete() 方法 lambda表达式条件 @@ -870,6 +871,30 @@ + + + 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: + DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂删除使用该方案的好处: + 1、删除前可预览测试数据,防止错误删除操作; + 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); + + + + + + 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: + UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂更新使用该方案的好处: + 1、更新前可预览测试数据,防止错误更新操作; + 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); + + + 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; @@ -1710,7 +1735,8 @@ - lambda表达式条件,仅支持实体基础成员(不包含导航对象) + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 lambda表达式条件 diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 37302573..127abd7a 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -23,7 +23,8 @@ namespace FreeSql IDelete WithConnection(DbConnection connection); /// - /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) + /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) + /// 若想使用导航对象,请使用 ISelect.ToDelete() 方法 /// /// lambda表达式条件 /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index fad3ebe2..4ae07c6a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql { - public partial interface ISelect0 + public partial interface ISelect0 where T1 : class { #if net40 @@ -82,6 +82,29 @@ namespace FreeSql /// T1 First(); + /// + /// 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: + /// fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() + /// 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: + /// DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + /// 复杂删除使用该方案的好处: + /// 1、删除前可预览测试数据,防止错误删除操作; + /// 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); + /// + /// + IDelete ToDelete(); + /// + /// 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: + /// fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() + /// 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: + /// UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + /// 复杂更新使用该方案的好处: + /// 1、更新前可预览测试数据,防止错误更新操作; + /// 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); + /// + /// + IUpdate ToUpdate(); + /// /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; /// 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index b2d68ea6..2c47437d 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -92,7 +92,8 @@ namespace FreeSql IUpdate SetRaw(string sql, object parms = null); /// - /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) + /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) + /// 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 /// /// lambda表达式条件 /// diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 0136eb97..b7a34687 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -833,6 +833,43 @@ namespace FreeSql.Internal.CommonProvider return (map, field.ToString()); } + string GetToDeleteWhere(string alias) + { + var pks = _tables[0].Table.Primarys; + if (pks.Length == 1) + return $"{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)} in (select * from ({this.ToSql($"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)}")}) {alias})"; + else + { + var concatTypes = new Type[pks.Length * 2 - 1]; + var concatMainCols = new string[pks.Length * 2 - 1]; + var concatInCols = new string[pks.Length * 2 - 1]; + var concatSplit = _commonUtils.FormatSql("{0}", $",{alias},"); + for (var a = 0; a < pks.Length; a++) + { + concatTypes[a * 2] = pks[a].CsType; + concatMainCols[a * 2] = _commonUtils.QuoteSqlName(pks[a].Attribute.Name); + concatInCols[a * 2] = $"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(pks[a].Attribute.Name)}"; + if (a < pks.Length - 1) + { + concatTypes[a * 2 + 1] = typeof(string); + concatMainCols[a * 2 + 1] = concatSplit; + concatInCols[a * 2 + 1] = concatSplit; + } + } + return $"{_commonUtils.StringConcat(concatMainCols, concatTypes)} in (select * from ({this.ToSql($"{_commonUtils.StringConcat(concatInCols, concatTypes)} as as1")}) {alias})"; + } + } + public IDelete ToDelete() + { + if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToDelete 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); + return _orm.Delete().Where(GetToDeleteWhere("ftb_del")); + } + public IUpdate ToUpdate() + { + if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToUpdate 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); + return _orm.Update().Where(GetToDeleteWhere("ftb_upd")); + } + protected List> GetTableRuleUnions() { var unions = new List>(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 9d55d00d..ec6b39ef 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -297,7 +297,11 @@ namespace FreeSql.Internal foreach (var col in trytb.Primarys) col.Attribute.IsPrimary = true; } - foreach (var col in trytb.Primarys) col.Attribute.IsNullable = false; + foreach (var col in trytb.Primarys) + { + col.Attribute.IsNullable = false; + col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", ""); + } tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs index 0e54cd1f..6eade116 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs @@ -71,7 +71,11 @@ namespace FreeSql.Odbc.Default var sb = new StringBuilder(); var news = new string[objs.Length]; for (var a = 0; a < objs.Length; a++) - news[a] = types[a] == typeof(string) ? objs[a] : $"cast({objs[a]} as nvarchar)"; + { + if (types[a] == typeof(string)) news[a] = objs[a]; + else if (types[a].NullableTypeOrThis() == typeof(Guid)) news[a] = $"cast({objs[a]} as char(36))"; + else news[a] = $"cast({objs[a]} as nvarchar)"; + } return string.Join(" + ", news); } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index 9ba86261..7466fe40 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -62,7 +62,11 @@ namespace FreeSql.Odbc.SqlServer var sb = new StringBuilder(); var news = new string[objs.Length]; for (var a = 0; a < objs.Length; a++) - news[a] = types[a] == typeof(string) ? objs[a] : $"cast({objs[a]} as nvarchar)"; + { + if (types[a] == typeof(string)) news[a] = objs[a]; + else if (types[a].NullableTypeOrThis() == typeof(Guid)) news[a] = $"cast({objs[a]} as char(36))"; + else news[a] = $"cast({objs[a]} as nvarchar)"; + } return string.Join(" + ", news); } public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 665aa487..0c94f33e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -62,7 +62,11 @@ namespace FreeSql.SqlServer var sb = new StringBuilder(); var news = new string[objs.Length]; for (var a = 0; a < objs.Length; a++) - news[a] = types[a] == typeof(string) ? objs[a] : $"cast({objs[a]} as nvarchar)"; + { + if (types[a] == typeof(string)) news[a] = objs[a]; + else if (types[a].NullableTypeOrThis() == typeof(Guid)) news[a] = $"cast({objs[a]} as char(36))"; + else news[a] = $"cast({objs[a]} as nvarchar)"; + } return string.Join(" + ", news); } public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; From bf5b1034aeadd4d85f9a466e9757438ba301b04a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 30 Oct 2019 20:40:28 +0800 Subject: [PATCH 0213/1029] ## v0.11.4 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6d44215c..5faf632c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.3 + 0.11.4 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 5567e93a..f02f0231 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 8e7d115b..7f1f6c9a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 82760af8..884d5e9f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.1;netstandard2.0;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 54a1d6fe..5e48f8c4 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.1;netstandard2.0;net45;net40 - 0.11.3 + 0.11.4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 01aa0aee..8c27fbad 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d343f971..838c4633 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f88b8754..362f80eb 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index ef949047..c1427d9d 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ec8ac908..75b52d9c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ec994e30..7d558f55 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c7ef4573..3b0ce431 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 3543928b..4d174f71 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.3 + 0.11.4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 25d584ca39c9f5881999c8809e9b130193d6969d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 31 Oct 2019 13:28:04 +0800 Subject: [PATCH 0214/1029] =?UTF-8?q?FreeSql.DbContext=20=E5=B0=8F?= =?UTF-8?q?=E7=89=88=E6=9C=AC=20v0.11.4.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.csproj | 4 ++-- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 4 ++-- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 884d5e9f..426347e8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -1,8 +1,8 @@  - netstandard2.1;netstandard2.0;net45;net40 - 0.11.4 + netstandard2.0;net45;net40 + 0.11.4.2 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..3f9fb047 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,13 +99,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5e48f8c4..d001defb 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -1,8 +1,8 @@  - netstandard2.1;netstandard2.0;net45;net40 - 0.11.4 + netstandard2.0;net45;net40 + 0.11.4.2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository From b3316309544afbb19d5efcd85766ea3134fc3aa6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 1 Nov 2019 18:49:13 +0800 Subject: [PATCH 0215/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20FreeSql.DbCo?= =?UTF-8?q?ntext=20=E6=9E=90=E6=9E=84=E6=96=B9=E6=B3=95=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=8C=E9=94=99=E8=AF=AF=E7=9A=84=E5=9B=9E=E6=BB=9A=E4=BA=86?= =?UTF-8?q?=E5=A4=96=E9=83=A8=20UnitOfWork=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 5 +++-- .../PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index ba543262..449a6f32 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -13,7 +13,7 @@ namespace FreeSql public IFreeSql Orm => _ormPriv ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); #region Property UnitOfWork - internal bool _isUseUnitOfWork = true; //是否使用工作单元事务 + internal bool _isUseUnitOfWork = true; //是否创建工作单元事务 IUnitOfWork _uowPriv; public IUnitOfWork UnitOfWork { @@ -220,7 +220,8 @@ namespace FreeSql _dicSet.Clear(); AllSets.Clear(); - UnitOfWork?.Rollback(); + if (_isUseUnitOfWork) + UnitOfWork?.Rollback(); } finally { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs index 6613f1d8..81ebea29 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs @@ -284,7 +284,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression public void TimeSpan_Parse() { var data = new List(); - data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic` a //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) From 5518a717ed23271ed9321bafdc434bc483198979 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 1 Nov 2019 18:50:35 +0800 Subject: [PATCH 0216/1029] ## v0.11.5 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5faf632c..9fb5d039 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.4 + 0.11.5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index f02f0231..af490591 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7f1f6c9a..210a4e7b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 426347e8..99a0a93b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.4.2 + 0.11.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d001defb..35913551 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.4.2 + 0.11.5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8c27fbad..bc04aef9 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 838c4633..b9dba7ad 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 362f80eb..8b76f5ac 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c1427d9d..35092f89 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 75b52d9c..de1f0f4b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7d558f55..8dc55e8a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 3b0ce431..0ccf9287 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4d174f71..91a847c2 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.4 + 0.11.5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From ed2a1e3bd3d831a6a603ae7ea9a5bd6172e79110 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 4 Nov 2019 13:01:52 +0800 Subject: [PATCH 0217/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20ToList(a=20?= =?UTF-8?q?=3D>=20new=20Dto=20{=20id=20=3D=201,=20title=20=3D=20a.xx.Title?= =?UTF-8?q?})=EF=BC=8C=E4=B9=8B=E5=89=8D=E5=8F=AA=E6=98=A0=E5=B0=84=20id?= =?UTF-8?q?=E3=80=81title=EF=BC=8C=E7=8E=B0=E5=9C=A8=E6=98=AF=E5=85=88?= =?UTF-8?q?=E6=98=A0=E5=B0=84=20Dto=20=E6=89=80=E6=9C=89=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=EF=BC=8C=E5=86=8D=E6=98=A0=E5=B0=84=20id=E3=80=81title?= =?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 | 7 + .../Sqlite/Curd/SqliteSelectTest.cs | 1 + FreeSql/FreeSql.xml | 131 ------------------ FreeSql/Internal/CommonExpression.cs | 66 +++++---- 4 files changed, 40 insertions(+), 165 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3f9fb047..2711e35d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,6 +99,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 8c5c0c86..e2f3ae41 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -164,6 +164,7 @@ namespace FreeSql.Tests.Sqlite g.sqlite.Insert(testdtolj).ExecuteAffrows(); } + select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); var testDto2 = select.Limit(10).ToList(a => new TestDto()); var testDto3 = select.Limit(10).ToList(a => new TestDto { }); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index eb505313..a26aa3ae 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1983,137 +1983,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 监控 ToList 返回的的数据,用于拦截重新装饰 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 1162d460..f27ab45e 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -108,6 +108,35 @@ namespace FreeSql.Internal var initExp = exp as MemberInitExpression; parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0]; parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + + //dto 映射 + var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(initExp.NewExpression.Type, dtoType => dtoType.GetProperties()); + foreach (var dtoProp in dtoProps) + { + foreach (var dtTb in _tables) + { + if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) + { + var child = new ReadAnonymousTypeInfo + { + Property = dtoProp, + CsName = dtoProp.Name, + CsType = dtoProp.PropertyType, + MapType = trydtocol.Attribute.MapType + }; + parent.Childs.Add(child); + if (dtTb.Parameter != null) + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression); + else + { + child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; + field.Append(", ").Append(child.DbField); + if (index >= 0) field.Append(" as").Append(++index); + } + break; + } + } + } if (initExp.Bindings?.Count > 0) { //指定 dto映射 @@ -126,38 +155,7 @@ namespace FreeSql.Internal ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString, whereCascadeExpression); } } - else - { - //dto 映射 - var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(initExp.NewExpression.Type, dtoType => dtoType.GetProperties()); - foreach (var dtoProp in dtoProps) - { - foreach (var dtTb in _tables) - { - if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) - { - var child = new ReadAnonymousTypeInfo - { - Property = dtoProp, - CsName = dtoProp.Name, - CsType = dtoProp.PropertyType, - MapType = trydtocol.Attribute.MapType - }; - parent.Childs.Add(child); - if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression); - else - { - child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; - field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(" as").Append(++index); - } - break; - } - } - } - if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); - } + if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); return true; case ExpressionType.New: var newExp = exp as NewExpression; @@ -182,8 +180,8 @@ namespace FreeSql.Internal { //dto 映射 parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(newExp.Type, dtoType => dtoType.GetProperties()); - foreach (var dtoProp in dtoProps) + var dtoProps2 = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(newExp.Type, dtoType => dtoType.GetProperties()); + foreach (var dtoProp in dtoProps2) { foreach (var dtTb in _tables) { From a18041e69f6b2830891b1f370531bc630991aa67 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 4 Nov 2019 13:03:36 +0800 Subject: [PATCH 0218/1029] ## v0.11.6 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 131 ++++++++++++++++++ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 15 files changed, 144 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 9fb5d039..2930a310 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.5 + 0.11.6 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index af490591..cfcca783 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 210a4e7b..65a08102 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 99a0a93b..a0aa04b9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..3f9fb047 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,13 +99,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 35913551..d7bc8ec1 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.5 + 0.11.6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index bc04aef9..4801b5ef 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a26aa3ae..eb505313 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1983,6 +1983,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 }) + + + + + + 监控 ToList 返回的的数据,用于拦截重新装饰 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b9dba7ad..6f5016fe 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8b76f5ac..f3f8f034 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 35092f89..16f21f88 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index de1f0f4b..fa9a49e8 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8dc55e8a..b55dd9d9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0ccf9287..6fdf8e59 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 91a847c2..36017153 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.5 + 0.11.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 951613138393acba86af75d2c9de63d53b4c46a7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 5 Nov 2019 10:27:48 +0800 Subject: [PATCH 0219/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20MySql=20Code?= =?UTF-8?q?First=20DateTime=20=E5=90=8C=E6=AD=A5=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=88=A4=E6=96=AD=E7=9A=84=20bug=EF=BC=8C?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E6=AF=8F=E6=AC=A1=E9=83=BD=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=20alter=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs | 6 +++++- .../FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index b7aa46a0..8457e93d 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -217,8 +217,12 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + var isDbTypeChanged = tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false; + if (tbstructcol.sqlType == "datetime(0)" && Regex.IsMatch(tbcol.Attribute.DbType, @"datetime\s+\(", RegexOptions.IgnoreCase) == false) + isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase) == false; + if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || - tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + isDbTypeChanged || tbcol.Attribute.IsNullable != tbstructcol.is_nullable || tbcol.Attribute.IsIdentity != tbstructcol.is_identity || isCommentChanged) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index b1f9b8c2..06effe56 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -5,6 +5,7 @@ using System.Data; using System.Data.Odbc; using System.Linq; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Odbc.MySql { @@ -205,8 +206,12 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + var isDbTypeChanged = tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false; + if (tbstructcol.sqlType == "datetime(0)" && Regex.IsMatch(tbcol.Attribute.DbType, @"datetime\s+\(", RegexOptions.IgnoreCase) == false) + isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase) == false; + if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || - tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + isDbTypeChanged || tbcol.Attribute.IsNullable != tbstructcol.is_nullable || tbcol.Attribute.IsIdentity != tbstructcol.is_identity || isCommentChanged) From 0c341360b77c854e8d1272b0911ec0a28b3fe3e9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 6 Nov 2019 13:58:19 +0800 Subject: [PATCH 0220/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20SqlServer=20?= =?UTF-8?q?ISelect.WithLock=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=20with(nolock)=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20SqlServer=20IFreeSql.SetGl?= =?UTF-8?q?obalSelectWithLock=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=85=A8=E5=B1=80=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=20with(nock)=20=E6=9F=A5=E8=AF=A2=EF=BC=9B=20-=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=20Aop.ToList=EF=BC=9B=20-=20=E7=A7=BB=E9=99=A4=20Aop.?= =?UTF-8?q?Where=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++ .../SqlServer/Curd/SqlServerSelectTest.cs | 1 - FreeSql/FreeSql.xml | 28 ++++------- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 7 +++ FreeSql/Interface/IAop.cs | 34 -------------- .../Internal/CommonProvider/AopProvider.cs | 2 - .../Internal/CommonProvider/DeleteProvider.cs | 4 -- .../SelectProvider/Select0Provider.cs | 17 +++---- .../SelectProvider/Select1Provider.cs | 1 - .../Internal/CommonProvider/UpdateProvider.cs | 4 -- .../Curd/MySqlSelect.cs | 28 +++++------ .../FreeSql.Provider.MySql/MySqlExtensions.cs | 2 +- .../Default/Curd/OdbcSelect.cs | 28 +++++------ .../MySql/Curd/OdbcMySqlSelect.cs | 28 +++++------ .../Oracle/Curd/OdbcOracleSelect.cs | 28 +++++------ .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 28 +++++------ .../SqlServer/Curd/OdbcSqlServerSelect.cs | 42 ++++++++--------- .../Curd/OracleSelect.cs | 28 +++++------ .../OracleExtensions.cs | 2 +- .../Curd/PostgreSQLSelect.cs | 28 +++++------ .../PostgreSQLExtensions.cs | 2 +- .../Curd/SqlServerSelect.cs | 47 ++++++++++--------- .../SqlServerExtensions.cs | 38 ++++++++++++++- .../Curd/SqliteSelect.cs | 28 +++++------ .../SqliteExtensions.cs | 2 +- 25 files changed, 228 insertions(+), 236 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3f9fb047..2711e35d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,6 +99,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index cafe5afa..66fbdc20 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -150,7 +150,6 @@ namespace FreeSql.Tests.SqlServer [Fact] public void ToList() { - var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); var testDto2 = select.Limit(10).ToList(a => new TestDto()); var testDto3 = select.Limit(10).ToList(a => new TestDto { }); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index eb505313..419b56e3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -908,6 +908,14 @@ + + + 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 + 如:select.AsAlias((_, oldAlias) => oldAlias + " with(lock)") + + + + 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 @@ -2114,16 +2122,6 @@ - - - 监控 ToList 返回的的数据,用于拦截重新装饰 - - - - - 监视 Where,包括 select/update/delete,可控制使上层不被执行。 - - 可自定义解析表达式 @@ -2164,16 +2162,6 @@ Insert/Update自动值处理 - - - 可重新装饰的引用数据 - - - - - 可使上层不被执行这个条件 - - 内置解析功能,可辅助您进行解析 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 4ae07c6a..7444a54e 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -118,6 +118,13 @@ namespace FreeSql /// TSelect AsTable(Func tableRule); /// + /// 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 + /// 如:select.AsAlias((_, oldAlias) => oldAlias + " with(lock)") + /// + /// + /// + TSelect AsAlias(Func aliasRule); + /// /// 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 /// /// diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index 1135b633..9aeefb8d 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -12,17 +12,6 @@ namespace FreeSql { public interface IAop { - - /// - /// 监控 ToList 返回的的数据,用于拦截重新装饰 - /// - EventHandler ToList { get; set; } - - /// - /// 监视 Where,包括 select/update/delete,可控制使上层不被执行。 - /// - EventHandler Where { get; set; } - /// /// 可自定义解析表达式 /// @@ -64,29 +53,6 @@ namespace FreeSql namespace FreeSql.Aop { - public class ToListEventArgs : EventArgs - { - public ToListEventArgs(object list) - { - this.List = list; - } - /// - /// 可重新装饰的引用数据 - /// - public object List { get; } - } - public class WhereEventArgs : EventArgs - { - public WhereEventArgs(params object[] parameters) - { - this.Parameters = parameters; - } - public object[] Parameters { get; } - /// - /// 可使上层不被执行这个条件 - /// - public bool IsCancel { get; set; } - } public class ParseExpressionEventArgs : EventArgs { public ParseExpressionEventArgs(Expression expression, Func freeParse) diff --git a/FreeSql/Internal/CommonProvider/AopProvider.cs b/FreeSql/Internal/CommonProvider/AopProvider.cs index 3312e50d..168a0dcf 100644 --- a/FreeSql/Internal/CommonProvider/AopProvider.cs +++ b/FreeSql/Internal/CommonProvider/AopProvider.cs @@ -8,8 +8,6 @@ namespace FreeSql.Internal.CommonProvider { public class AopProvider : IAop { - public EventHandler ToList { get; set; } - public EventHandler Where { get; set; } public EventHandler ParseExpression { get; set; } public EventHandler ConfigEntity { get; set; } public EventHandler ConfigEntityProperty { get; set; } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 5e2e5a50..24c07bad 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -89,10 +89,6 @@ namespace FreeSql.Internal.CommonProvider public IDelete Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; - var args = new Aop.WhereEventArgs(sql, parms); - _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); - if (args.IsCancel == true) return this; - if (++_whereTimes > 1) _where.Append(" AND "); _where.Append("(").Append(sql).Append(")"); if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index b7a34687..365de89d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -24,6 +24,7 @@ namespace FreeSql.Internal.CommonProvider protected List _params = new List(); protected List _tables = new List(); protected List> _tableRules = new List>(); + protected Func _aliasRule; protected StringBuilder _join = new StringBuilder(); protected IFreeSql _orm; protected CommonUtils _commonUtils; @@ -86,6 +87,7 @@ namespace FreeSql.Internal.CommonProvider _multiTables.AddRange(from._tables.GetRange(_multiTables.Count, from._tables.Count - _multiTables.Count)); } toType.GetField("_tableRules", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._tableRules); + toType.GetField("_aliasRule", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._aliasRule); toType.GetField("_join", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._join.ToString())); //toType.GetField("_orm", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orm); //toType.GetField("_commonUtils", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonUtils); @@ -345,7 +347,6 @@ namespace FreeSql.Internal.CommonProvider _orm.Aop.CurdAfter?.Invoke(this, after); } foreach (var include in _includeToList) include?.Invoke(ret); - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); _trackToList?.Invoke(ret); return ret; } @@ -391,7 +392,6 @@ namespace FreeSql.Internal.CommonProvider checkDoneTimes++; foreach (var include in _includeToList) include?.Invoke(ret); - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); _trackToList?.Invoke(ret); chunkDone(ret); @@ -416,7 +416,6 @@ namespace FreeSql.Internal.CommonProvider if (ret.Any() || checkDoneTimes == 0) { foreach (var include in _includeToList) include?.Invoke(ret); - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); _trackToList?.Invoke(ret); chunkDone(ret); } @@ -482,7 +481,6 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); _trackToList?.Invoke(ret); return ret; } @@ -902,6 +900,11 @@ namespace FreeSql.Internal.CommonProvider if (tableRule != null) _tableRules.Add(tableRule); return this as TSelect; } + public TSelect AsAlias(Func aliasRule) + { + if (aliasRule != null) _aliasRule = aliasRule; + return this as TSelect; + } public TSelect AsType(Type entityType) { if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); @@ -917,10 +920,6 @@ namespace FreeSql.Internal.CommonProvider public TSelect WhereIf(bool condition, string sql, object parms = null) { if (condition == false || string.IsNullOrEmpty(sql)) return this as TSelect; - var args = new Aop.WhereEventArgs(sql, parms); - _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); - if (args.IsCancel == true) return this as TSelect; - _where.Append(" AND (").Append(sql).Append(")"); if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); return this as TSelect; @@ -1121,7 +1120,6 @@ namespace FreeSql.Internal.CommonProvider _orm.Aop.CurdAfter?.Invoke(this, after); } foreach (var include in _includeToList) include?.Invoke(ret); - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); _trackToList?.Invoke(ret); return ret; } @@ -1184,7 +1182,6 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); _trackToList?.Invoke(ret); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 15b20b4a..de88f2a9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -910,7 +910,6 @@ namespace FreeSql.Internal.CommonProvider internal void SetList(IEnumerable list) { foreach (var include in _includeToList) include?.Invoke(list); - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(list)); _trackToList?.Invoke(list); } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index a24fa28e..44313046 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -428,10 +428,6 @@ namespace FreeSql.Internal.CommonProvider public IUpdate Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; - var args = new Aop.WhereEventArgs(sql, parms); - _orm.Aop.Where?.Invoke(this, new Aop.WhereEventArgs(sql, parms)); - if (args.IsCancel == true) return this; - _where.Append(" AND (").Append(sql).Append(")"); if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); return this; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index 002698bc..d745db6d 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.MySql.Curd class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -37,13 +37,13 @@ namespace FreeSql.MySql.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -77,7 +77,7 @@ namespace FreeSql.MySql.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -117,51 +117,51 @@ namespace FreeSql.MySql.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs b/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs index 38857891..a08d689d 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs @@ -1,4 +1,4 @@ -public static partial class FreeSqlGlobalExtensions +public static partial class FreeSqlMySqlGlobalExtensions { /// diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index c233952c..bc1895ed 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -11,7 +11,7 @@ namespace FreeSql.Odbc.Default class OdbcSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { var _utils = _commonUtils as OdbcUtils; if (_orm.CodeFirst.IsAutoSyncStructure) @@ -51,13 +51,13 @@ namespace FreeSql.Odbc.Default var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -91,7 +91,7 @@ namespace FreeSql.Odbc.Default sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -133,51 +133,51 @@ namespace FreeSql.Odbc.Default public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index a94e6935..430e812f 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Odbc.MySql class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -37,13 +37,13 @@ namespace FreeSql.Odbc.MySql var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -77,7 +77,7 @@ namespace FreeSql.Odbc.MySql sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -117,51 +117,51 @@ namespace FreeSql.Odbc.MySql public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index db466e69..1e93f77c 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Odbc.Oracle class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -39,13 +39,13 @@ namespace FreeSql.Odbc.Oracle var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.Oracle sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -129,51 +129,51 @@ namespace FreeSql.Odbc.Oracle public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 1e5a8fb1..043feeda 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Odbc.PostgreSQL class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -37,13 +37,13 @@ namespace FreeSql.Odbc.PostgreSQL var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -77,7 +77,7 @@ namespace FreeSql.Odbc.PostgreSQL sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -119,51 +119,51 @@ namespace FreeSql.Odbc.PostgreSQL public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index 52f7322d..fa840a15 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -12,13 +12,13 @@ namespace FreeSql.Odbc.SqlServer class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) => (_commonUtils as OdbcSqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _whereCascadeExpression, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _whereCascadeExpression, _orm); + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _whereCascadeExpression, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _whereCascadeExpression, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -55,13 +55,13 @@ namespace FreeSql.Odbc.SqlServer var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -95,7 +95,7 @@ namespace FreeSql.Odbc.SqlServer sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -128,7 +128,7 @@ namespace FreeSql.Odbc.SqlServer #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -155,13 +155,13 @@ namespace FreeSql.Odbc.SqlServer var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -195,7 +195,7 @@ namespace FreeSql.Odbc.SqlServer sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -248,51 +248,51 @@ namespace FreeSql.Odbc.SqlServer public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 26e7ce7f..290dc859 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Oracle.Curd class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -39,13 +39,13 @@ namespace FreeSql.Oracle.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -79,7 +79,7 @@ namespace FreeSql.Oracle.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -129,51 +129,51 @@ namespace FreeSql.Oracle.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs index 83b5d5ff..8913644b 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs @@ -1,4 +1,4 @@ -public static partial class FreeSqlGlobalExtensions +public static partial class FreeSqlOracleGlobalExtensions { /// diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 23a04138..1e8faf08 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.PostgreSQL.Curd class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -37,13 +37,13 @@ namespace FreeSql.PostgreSQL.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -77,7 +77,7 @@ namespace FreeSql.PostgreSQL.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -119,51 +119,51 @@ namespace FreeSql.PostgreSQL.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs index 40c5af93..9794e60f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs @@ -1,4 +1,4 @@ -public static partial class FreeSqlGlobalExtensions +public static partial class FreeSqlPostgreSQLGlobalExtensions { /// diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 25a584b9..3eacc1e5 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -12,13 +12,13 @@ namespace FreeSql.SqlServer.Curd class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _whereCascadeExpression, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _whereCascadeExpression, _orm); + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _whereCascadeExpression, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _whereCascadeExpression, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -55,13 +55,13 @@ namespace FreeSql.SqlServer.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -95,7 +95,7 @@ namespace FreeSql.SqlServer.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -128,7 +128,7 @@ namespace FreeSql.SqlServer.Curd #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -155,13 +155,13 @@ namespace FreeSql.SqlServer.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -195,7 +195,7 @@ namespace FreeSql.SqlServer.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -238,7 +238,10 @@ namespace FreeSql.SqlServer.Curd } #endregion - public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { + if (FreeSqlSqlServerGlobalExtensions._dicSetGlobalSelectWithLock.TryGetValue(orm, out var tryval)) + this.WithLock(tryval.Item1, tryval.Item2); + } public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } @@ -248,51 +251,51 @@ namespace FreeSql.SqlServer.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index e7d5dd5f..2fef171e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -1,4 +1,9 @@ -public static partial class FreeSqlGlobalExtensions +using FreeSql; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; + +public static partial class FreeSqlSqlServerGlobalExtensions { /// @@ -9,4 +14,35 @@ /// public static string FormatSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args); static FreeSql.SqlServer.SqlServerAdo _sqlserverAdo = new FreeSql.SqlServer.SqlServerAdo(); + + /// + /// SqlServer with(nolock) 查询 + /// + /// + /// + /// + /// 多表查询时的锁规则 + /// + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T : class + => rule == null ? + that.AsAlias((type, old) => $"{old} with({lockType.ToString()})") : + that.AsAlias((type, old) => rule.TryGetValue(type, out var trybool) && trybool ? $"{old} with({lockType.ToString()})" : old); + + /// + /// 设置全局 SqlServer with(nolock) 查询 + /// + /// + /// + public static IFreeSql SetGlobalSelectWithLock(this IFreeSql that, SqlServerLock lockType, Dictionary rule) + { + var value = (lockType, rule); + _dicSetGlobalSelectWithLock.AddOrUpdate(that, value, (_, __) => value); + return that; + } + internal static ConcurrentDictionary)> _dicSetGlobalSelectWithLock = new ConcurrentDictionary)>(); } + +public enum SqlServerLock +{ + HoldLock, NoLock, PagLock, ReadCommitted, ReadPast, ReadUnCommitted, RepeaTableRead, RowLock, Serializable, TabLock, TabLockX, UpdLock, XLock +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index 74953e74..dc65ab68 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Sqlite.Curd class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -37,13 +37,13 @@ namespace FreeSql.Sqlite.Curd var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); for (var a = 0; a < tbsfrom.Length; a++) { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(tbsfrom[a].Alias); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); if (tbsjoin.Length > 0) { //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 for (var b = 1; b < tbsfrom.Length; b++) { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(tbsfrom[b].Alias); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else @@ -77,7 +77,7 @@ namespace FreeSql.Sqlite.Curd sb.Append(" \r\nRIGHT JOIN "); break; } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } @@ -117,51 +117,51 @@ namespace FreeSql.Sqlite.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExtensions.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExtensions.cs index a988dd50..6393545a 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExtensions.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExtensions.cs @@ -1,4 +1,4 @@ -public static partial class FreeSqlGlobalExtensions +public static partial class FreeSqlSqliteGlobalExtensions { /// From 28dfd782607caf6f8d2bf94aaf9bbf48348b44ee Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 6 Nov 2019 14:00:50 +0800 Subject: [PATCH 0221/1029] ## v0.11.7 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2930a310..a5163fdc 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.6 + 0.11.7 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index cfcca783..0f80a3db 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 65a08102..a1e113e1 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a0aa04b9..9a3a9ed4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..3f9fb047 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,13 +99,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d7bc8ec1..3328d190 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.6 + 0.11.7 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4801b5ef..a75d4580 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6f5016fe..25768963 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f3f8f034..c358b4b9 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 16f21f88..7aee84e2 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fa9a49e8..39f8ed36 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b55dd9d9..6466a394 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 6fdf8e59..d2ad47f4 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 36017153..7e19d440 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.6 + 0.11.7 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 35a663f5ef7c03bfb41fab085cfa61e7bec32ab5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 6 Nov 2019 16:45:29 +0800 Subject: [PATCH 0222/1029] =?UTF-8?q?=E8=A1=A5=E5=85=85=20ToList=20?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 7444a54e..163743bf 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -51,7 +51,12 @@ namespace FreeSql DataTable ToDataTable(string field = null); /// - /// 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + /// 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + /// 注意: + /// 1、ToList(a => a) 可以返回 a 所有实体 + /// 2、ToList(a => new { a }) 这样也可以 + /// 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 + /// 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() /// /// false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 /// From 13810c44227a2307e5fc5b55b15b8e16272078ce Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 Nov 2019 00:17:11 +0800 Subject: [PATCH 0223/1029] ## v0.11.8 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 4 +- FreeSql/FreeSql.xml | 138 +----------------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- .../SqliteCodeFirst.cs | 2 +- 15 files changed, 21 insertions(+), 147 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a5163fdc..54ca32bc 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.7 + 0.11.8 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0f80a3db..d8a1c703 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a1e113e1..6a79e22e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 9a3a9ed4..4f386e1b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3328d190..667523fa 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.7 + 0.11.8 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index a75d4580..471f9c63 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. @@ -28,7 +28,7 @@ - + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 419b56e3..ddf513b8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -838,7 +838,12 @@ - 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + 注意: + 1、ToList(a => a) 可以返回 a 所有实体 + 2、ToList(a => new { a }) 这样也可以 + 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 + 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 @@ -1991,137 +1996,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 25768963..e50474c2 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index c358b4b9..c9b01d0c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 7aee84e2..3ae1fa44 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 39f8ed36..5274ed2f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 6466a394..bd0ac5d3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d2ad47f4..a7fad835 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7e19d440..9673242b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.7 + 0.11.8 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 68639935..9b00b103 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -169,7 +169,7 @@ namespace FreeSql.Sqlite { column = string.Concat(a[1]), sqlType = string.Concat(a[2]).ToUpper(), - is_nullable = string.Concat(a[3]) == "0", + is_nullable = string.Concat(a[5]) == "0" && string.Concat(a[3]) == "0", is_identity }; }, StringComparer.CurrentCultureIgnoreCase); From 8ec8daa6be6b22299579cef9f17dd746aa229315 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 Nov 2019 02:33:27 +0800 Subject: [PATCH 0224/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Prov?= =?UTF-8?q?ider.Sqlite=20=E5=AF=B9=20Xamarin=20=E7=8E=AF=E5=A2=83=E4=B8=8B?= =?UTF-8?q?=E7=9A=84=E9=80=82=E9=85=8D=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 131 ++++++++++++++++++ .../FreeSql.Provider.Sqlite/MonoAdapter.cs | 72 ++++++++++ .../SqliteAdo/SqliteAdo.cs | 3 +- .../SqliteAdo/SqliteConnectionPool.cs | 5 +- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 13 +- 5 files changed, 215 insertions(+), 9 deletions(-) create mode 100644 Providers/FreeSql.Provider.Sqlite/MonoAdapter.cs diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ddf513b8..9675d56b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1996,6 +1996,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 }) + + + + + + 可自定义解析表达式 diff --git a/Providers/FreeSql.Provider.Sqlite/MonoAdapter.cs b/Providers/FreeSql.Provider.Sqlite/MonoAdapter.cs new file mode 100644 index 00000000..ae762497 --- /dev/null +++ b/Providers/FreeSql.Provider.Sqlite/MonoAdapter.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Reflection; +using System.Text; + +namespace FreeSql.Sqlite +{ + internal class MonoAdapter + { + + static bool? _isMono; + static object _isMonoLock = new object(); + static Assembly _monoAssemly; + static Type _monoSqliteConnectionType; + static Type _monoSqliteCommandType; + static Type _monoSqliteParameterType; + static Type _monoSqliteExceptionType; + + static bool IsMono + { + get + { + if (_isMono != null) return _isMono == true; + lock (_isMonoLock) + { + Assembly ass = null; + try + { + ass = Assembly.Load("Mono.Data.Sqlite"); + } + catch { } + _isMono = ass != null; + if (_isMono == false) return false; + + _monoAssemly = ass; + _monoSqliteConnectionType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteConnection"); + _monoSqliteCommandType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteCommand"); + _monoSqliteParameterType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteParameter"); + _monoSqliteExceptionType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteException"); + } + return true; + } + } + + public static DbConnection GetSqliteConnection(string connectionString) + { + if (IsMono == false) return new System.Data.SQLite.SQLiteConnection(connectionString); + return Activator.CreateInstance(_monoSqliteConnectionType, new object[] { connectionString }) as DbConnection; + } + + public static DbCommand GetSqliteCommand() + { + if (IsMono == false) return new System.Data.SQLite.SQLiteCommand(); + return Activator.CreateInstance(_monoSqliteCommandType, new object[0]) as DbCommand; + } + + public static DbParameter GetSqliteParameter() + { + if (IsMono == false) return new System.Data.SQLite.SQLiteParameter(); + return Activator.CreateInstance(_monoSqliteParameterType, new object[0]) as DbParameter; + } + + public static bool IsSqliteException(Exception exception) + { + if (exception == null) return false; + if (IsMono == false) return exception is System.Data.SQLite.SQLiteException; + return exception.GetType() == _monoSqliteExceptionType; + } + + } +} diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 137dd99e..f1217038 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -3,7 +3,6 @@ using SafeObjectPool; using System; using System.Collections; using System.Data.Common; -using System.Data.SQLite; using System.Text; using System.Threading; @@ -56,7 +55,7 @@ namespace FreeSql.Sqlite protected override DbCommand CreateCommand() { - return new SQLiteCommand(); + return MonoAdapter.GetSqliteCommand(); } protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index f5f200f8..0aac8b70 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -4,7 +4,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Data.SQLite; using System.Linq; using System.Text; using System.Text.RegularExpressions; @@ -35,7 +34,7 @@ namespace FreeSql.Sqlite public void Return(Object obj, Exception exception, bool isRecreate = false) { - if (exception != null && exception is SQLiteException) + if (exception != null && MonoAdapter.IsSqliteException(exception)) { try { if (obj.Value.Ping() == false) obj.Value.OpenAndAttach(policy.Attaches); } catch { base.SetUnavailable(exception); } } @@ -112,7 +111,7 @@ namespace FreeSql.Sqlite public DbConnection OnCreate() { - var conn = new SQLiteConnection(_connectionString); + var conn = MonoAdapter.GetSqliteConnection(_connectionString); return conn; } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index f861c6c6..e3c7b46e 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Data.SQLite; using System.Linq.Expressions; using System.Text; @@ -34,13 +33,16 @@ namespace FreeSql.Sqlite dbtype = DbType.Int64; break; } - var ret = new SQLiteParameter { ParameterName = QuoteParamterName(parameterName), DbType = dbtype, Value = value }; + var ret = MonoAdapter.GetSqliteParameter(); + ret.ParameterName = QuoteParamterName(parameterName); + ret.DbType = dbtype; + ret.Value = value; _params?.Add(ret); return ret; } public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; switch (dbtype) @@ -56,7 +58,10 @@ namespace FreeSql.Sqlite dbtype = DbType.Int64; break; } - var ret = new SQLiteParameter { ParameterName = $"@{name}", DbType = dbtype, Value = value }; + var ret = MonoAdapter.GetSqliteParameter(); + ret.ParameterName = $"@{name}"; + ret.DbType = dbtype; + ret.Value = value; return ret; }); From 5521d6d1003f46cf830d11f10afdb38508038891 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 Nov 2019 02:41:51 +0800 Subject: [PATCH 0225/1029] ## v0.11.9 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 54ca32bc..1b1c0cae 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.8 + 0.11.9 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index d8a1c703..bf8454b3 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6a79e22e..011089e1 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4f386e1b..84d0817a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 667523fa..c9dccf6c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.8 + 0.11.9 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 471f9c63..bd9c2bbe 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e50474c2..cb228ef9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index c9b01d0c..bd00819c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3ae1fa44..e52cb990 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 5274ed2f..a7d76d45 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index bd0ac5d3..2af99d90 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a7fad835..f0af41b1 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9673242b..f1d19624 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.8 + 0.11.9 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 From 8cc5a682da5296924a4fbd3ee6208bd71e1e2a48 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 Nov 2019 12:22:01 +0800 Subject: [PATCH 0226/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Prov?= =?UTF-8?q?ider.Sqlite=20=E5=AF=B9=20Xamarin=20=E7=8E=AF=E5=A2=83=E4=B8=8B?= =?UTF-8?q?=E7=9A=84=E9=80=82=E9=85=8D=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ++ .../FreeSql.Provider.Sqlite/AdonetPortable.cs | 61 ++++++++++++++++ .../FreeSql.Provider.Sqlite.csproj | 8 ++- .../FreeSql.Provider.Sqlite/MonoAdapter.cs | 72 ------------------- .../SqliteAdo/SqliteAdo.cs | 2 +- .../SqliteAdo/SqliteConnectionPool.cs | 30 +++++--- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 4 +- 7 files changed, 98 insertions(+), 86 deletions(-) create mode 100644 Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs delete mode 100644 Providers/FreeSql.Provider.Sqlite/MonoAdapter.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3f9fb047..2711e35d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,6 +99,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs b/Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs new file mode 100644 index 00000000..6d8dcbf4 --- /dev/null +++ b/Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Reflection; +using System.Text; + +namespace FreeSql.Sqlite +{ + internal class AdonetPortable + { + +#if ns20 + static bool _IsMicrosoft_Data_Sqlite; + static object _IsMicrosoft_Data_SqliteLock = new object(); + + static T PortableAction(Func systemCreate, Func microsoftCreate) + { + if (_IsMicrosoft_Data_Sqlite == false) + { + try + { + return systemCreate(); + } + catch + { + lock (_IsMicrosoft_Data_SqliteLock) + { + _IsMicrosoft_Data_Sqlite = true; + } + } + } + return microsoftCreate(); + } + + public static DbConnection GetSqliteConnection(string connectionString) => PortableAction( + () => new System.Data.SQLite.SQLiteConnection(connectionString), + () => new Microsoft.Data.Sqlite.SqliteConnection(connectionString)); + + public static DbCommand GetSqliteCommand() => PortableAction( + () => new System.Data.SQLite.SQLiteCommand(), + () => new Microsoft.Data.Sqlite.SqliteCommand()); + + public static DbParameter GetSqliteParameter() => PortableAction( + () => new System.Data.SQLite.SQLiteParameter(), + () => new Microsoft.Data.Sqlite.SqliteParameter()); + + public static bool IsSqliteException(Exception exception) => PortableAction( + () => exception is System.Data.SQLite.SQLiteException, + () => exception is Microsoft.Data.Sqlite.SqliteException); +#else + + public static DbConnection GetSqliteConnection(string connectionString) => new System.Data.SQLite.SQLiteConnection(connectionString); + + public static DbCommand GetSqliteCommand() => new System.Data.SQLite.SQLiteCommand(); + + public static DbParameter GetSqliteParameter() => new System.Data.SQLite.SQLiteParameter(); + + public static bool IsSqliteException(Exception exception) => exception is System.Data.SQLite.SQLiteException; +#endif + } +} diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f1d19624..640876ae 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9 + 0.11.9.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0 @@ -25,11 +25,17 @@ + + + + + ns20;netstandard20 + net40 diff --git a/Providers/FreeSql.Provider.Sqlite/MonoAdapter.cs b/Providers/FreeSql.Provider.Sqlite/MonoAdapter.cs deleted file mode 100644 index ae762497..00000000 --- a/Providers/FreeSql.Provider.Sqlite/MonoAdapter.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data.Common; -using System.Reflection; -using System.Text; - -namespace FreeSql.Sqlite -{ - internal class MonoAdapter - { - - static bool? _isMono; - static object _isMonoLock = new object(); - static Assembly _monoAssemly; - static Type _monoSqliteConnectionType; - static Type _monoSqliteCommandType; - static Type _monoSqliteParameterType; - static Type _monoSqliteExceptionType; - - static bool IsMono - { - get - { - if (_isMono != null) return _isMono == true; - lock (_isMonoLock) - { - Assembly ass = null; - try - { - ass = Assembly.Load("Mono.Data.Sqlite"); - } - catch { } - _isMono = ass != null; - if (_isMono == false) return false; - - _monoAssemly = ass; - _monoSqliteConnectionType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteConnection"); - _monoSqliteCommandType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteCommand"); - _monoSqliteParameterType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteParameter"); - _monoSqliteExceptionType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteException"); - } - return true; - } - } - - public static DbConnection GetSqliteConnection(string connectionString) - { - if (IsMono == false) return new System.Data.SQLite.SQLiteConnection(connectionString); - return Activator.CreateInstance(_monoSqliteConnectionType, new object[] { connectionString }) as DbConnection; - } - - public static DbCommand GetSqliteCommand() - { - if (IsMono == false) return new System.Data.SQLite.SQLiteCommand(); - return Activator.CreateInstance(_monoSqliteCommandType, new object[0]) as DbCommand; - } - - public static DbParameter GetSqliteParameter() - { - if (IsMono == false) return new System.Data.SQLite.SQLiteParameter(); - return Activator.CreateInstance(_monoSqliteParameterType, new object[0]) as DbParameter; - } - - public static bool IsSqliteException(Exception exception) - { - if (exception == null) return false; - if (IsMono == false) return exception is System.Data.SQLite.SQLiteException; - return exception.GetType() == _monoSqliteExceptionType; - } - - } -} diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index f1217038..d8df365d 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -55,7 +55,7 @@ namespace FreeSql.Sqlite protected override DbCommand CreateCommand() { - return MonoAdapter.GetSqliteCommand(); + return AdonetPortable.GetSqliteCommand(); } protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 0aac8b70..a6805118 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -34,7 +34,7 @@ namespace FreeSql.Sqlite public void Return(Object obj, Exception exception, bool isRecreate = false) { - if (exception != null && MonoAdapter.IsSqliteException(exception)) + if (exception != null && AdonetPortable.IsSqliteException(exception)) { try { if (obj.Value.Ping() == false) obj.Value.OpenAndAttach(policy.Attaches); } catch { base.SetUnavailable(exception); } } @@ -57,7 +57,6 @@ namespace FreeSql.Sqlite public int CheckAvailableInterval { get; set; } = 5; public string[] Attaches = new string[0]; - static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); private string _connectionString; public string ConnectionString { @@ -68,12 +67,11 @@ namespace FreeSql.Sqlite var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); - PoolSize = poolsize + connStrIncr; - _connectionString = m.Success ? - Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : - $"{_connectionString};Max pool size={PoolSize}"; + if (m.Success) + { + PoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); @@ -92,14 +90,26 @@ namespace FreeSql.Sqlite _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); } - var att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase); + var att = Regex.Split(_connectionString, @"Pooling\s*=\s*", RegexOptions.IgnoreCase); + if (att.Length == 2) + { + var idx = att[1].IndexOf(';'); + _connectionString = string.Concat(att[0], idx == -1 ? "" : att[1].Substring(idx)); + } + + att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase); if (att.Length == 2) { var idx = att[1].IndexOf(';'); Attaches = (idx == -1 ? att[1] : att[1].Substring(0, idx)).Split(','); + _connectionString = string.Concat(att[0], idx == -1 ? "" : att[1].Substring(idx)); } +#if ns20 + minPoolSize = 1; +#endif FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } } @@ -111,7 +121,7 @@ namespace FreeSql.Sqlite public DbConnection OnCreate() { - var conn = MonoAdapter.GetSqliteConnection(_connectionString); + var conn = AdonetPortable.GetSqliteConnection(_connectionString); return conn; } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index e3c7b46e..9f862c74 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -33,7 +33,7 @@ namespace FreeSql.Sqlite dbtype = DbType.Int64; break; } - var ret = MonoAdapter.GetSqliteParameter(); + var ret = AdonetPortable.GetSqliteParameter(); ret.ParameterName = QuoteParamterName(parameterName); ret.DbType = dbtype; ret.Value = value; @@ -58,7 +58,7 @@ namespace FreeSql.Sqlite dbtype = DbType.Int64; break; } - var ret = MonoAdapter.GetSqliteParameter(); + var ret = AdonetPortable.GetSqliteParameter(); ret.ParameterName = $"@{name}"; ret.DbType = dbtype; ret.Value = value; From d20b0689c26a2b037ac759407e19d7388c7ad2c9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 Nov 2019 12:48:40 +0800 Subject: [PATCH 0227/1029] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 84d0817a..1e943ac9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -5,7 +5,7 @@ 0.11.9 true YeXiangQin - FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. + FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. https://github.com/2881099/FreeSql.DbContext FreeSql ORM DbContext git diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index bd9c2bbe..a3bb7270 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -5,7 +5,7 @@ 0.11.9 true YeXiangQin - FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. + FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 640876ae..dbf7f665 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -5,12 +5,12 @@ 0.11.9.2 true YeXiangQin - FreeSql 数据库实现,基于 Sqlite 3.0 + FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;sqlite $(AssemblyName) logo.png $(AssemblyName) From e5289cc5851b66f996c8981550a4961bbeb8c2b3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 Nov 2019 12:51:58 +0800 Subject: [PATCH 0228/1029] update readme --- readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 7ce17a99..9191ebc7 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@

-FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+(QQ群:4336577) +FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+ 或 Xamarin 扶摇直上,至强ORM只为自由编码;鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) @@ -261,3 +261,5 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [ALer-R](https://github.com/ALer-R)、 [zouql](https://github.com/zouql)、 深圳|凉茶 + +(QQ群:4336577) \ No newline at end of file From 5ce037d31624a58b3e7cfeab198608a07a54fb99 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 8 Nov 2019 13:03:54 +0800 Subject: [PATCH 0229/1029] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=86=85=E9=83=A8?= =?UTF-8?q?=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Extensions/LambadaExpressionExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 1dd7864e..034efdd3 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -89,7 +89,7 @@ namespace System.Linq.Expressions internal static bool IsParameter(this Expression exp) { - var test = new TextParameterExpressionVisitor(); + var test = new TestParameterExpressionVisitor(); test.Visit(exp); return test.Result; } @@ -110,7 +110,7 @@ namespace System.Linq.Expressions node == _oldParameter ? this._newParameter : node; } - internal class TextParameterExpressionVisitor : ExpressionVisitor + internal class TestParameterExpressionVisitor : ExpressionVisitor { public bool Result { get; private set; } From 8a9a50ecb7fb43c14feb1ea8ed9f1e27099a0c60 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 10 Nov 2019 12:18:16 +0800 Subject: [PATCH 0230/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=B1=BB=E9=87=8D=E5=86=99=E5=B1=9E=E6=80=A7=20new=20?= =?UTF-8?q?=E5=A6=82=E6=9E=9C=E7=B1=BB=E5=9E=8B=E4=B8=8E=E5=9F=BA=E7=B1=BB?= =?UTF-8?q?=E4=B8=8D=E4=B8=80=E8=87=B4=EF=BC=8C=E6=97=A0=E6=B3=95=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 24 +++++++++++++++++++ FreeSql/DataAnnotations/TableFluent.cs | 2 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 13 ++++++++++ FreeSql/Internal/CommonExpression.cs | 5 ++-- .../CommonProvider/AdoProvider/AdoProvider.cs | 3 +-- FreeSql/Internal/CommonUtils.cs | 4 ++-- FreeSql/Internal/UtilsExpressionTree.cs | 10 ++++---- 8 files changed, 48 insertions(+), 20 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..3f9fb047 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,13 +99,6 @@ 清空状态数据
- - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index df1dff9a..287db677 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -418,9 +418,33 @@ namespace FreeSql.Tests public enum TestAddEnumType { 中国人, 日本人 } public static AsyncLocal TenrantId { get; set; } = new AsyncLocal(); + + public class TestAddEnumEx : TestAddEnum + { + public new int Id { get; set; } + } + [Fact] public void Test1() { + var testExNewRet1 = g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var testExNewRet2 = g.sqlite.Insert(new TestAddEnumEx { Id = 1, Type = TestAddEnumType.中国人 }).ExecuteAffrows(); + var testExNewRet3 = g.sqlite.Insert(new TestAddEnumEx { Id = 2, Type = TestAddEnumType.日本人 }).ExecuteAffrows(); + var testExNewRet4 = g.sqlite.Select().ToList(); + var testExNewRet5 = g.sqlite.Update(1).Set(a => a.Type == TestAddEnumType.日本人).ExecuteAffrows(); + var testExNewRet6 = g.sqlite.Select().ToList(); + var testExNewRet7 = g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var testExNewRet8 = g.sqlite.Select().ToList(); + + var testBaseRet1 = g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var testBaseRet2 = g.sqlite.Insert(new TestAddEnum { Type = TestAddEnumType.中国人 }).ExecuteAffrows(); + var testBaseRet3 = g.sqlite.Insert(new TestAddEnum { Type = TestAddEnumType.日本人 }).ExecuteAffrows(); + var testBaseRet4 = g.sqlite.Select().ToList(); + var testBaseRet5 = g.sqlite.Update(testBaseRet4[0]).Set(a => a.Type == TestAddEnumType.日本人).ExecuteAffrows(); + var testBaseRet6 = g.sqlite.Select().ToList(); + var testBaseRet7 = g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var testBaseRet8 = g.sqlite.Select().ToList(); + //g.mysql.Aop.AuditValue += (_, e) => //{ diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 633462b9..e2b199d5 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -12,7 +12,7 @@ namespace FreeSql.DataAnnotations public TableFluent(Type entityType, TableAttribute table) { _entityType = entityType; - _properties = _entityType.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); + _properties = _entityType.GetPropertiesDictIgnoreCase(); _table = table; } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 1d935c43..f6d27fac 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -43,6 +43,19 @@ public static partial class FreeSqlGlobalExtensions public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that; internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args)); + static ConcurrentDictionary> _dicGetPropertiesDictIgnoreCase = new ConcurrentDictionary>(); + public static Dictionary GetPropertiesDictIgnoreCase(this Type that) => that == null ? null : _dicGetPropertiesDictIgnoreCase.GetOrAdd(that, tp => + { + var props = that.GetProperties(); + var dict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + foreach (var prop in props) + { + if (dict.ContainsKey(prop.Name)) continue; + dict.Add(prop.Name, prop); + } + return dict; + }); + /// /// 测量两个经纬度的距离,返回单位:米 /// diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index f27ab45e..11cf1b65 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -23,7 +23,6 @@ namespace FreeSql.Internal _common = common; } - static ConcurrentDictionary _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary(); public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression) { Func getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; @@ -110,7 +109,7 @@ namespace FreeSql.Internal parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; //dto 映射 - var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(initExp.NewExpression.Type, dtoType => dtoType.GetProperties()); + var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values; foreach (var dtoProp in dtoProps) { foreach (var dtTb in _tables) @@ -180,7 +179,7 @@ namespace FreeSql.Internal { //dto 映射 parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - var dtoProps2 = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(newExp.Type, dtoType => dtoType.GetProperties()); + var dtoProps2 = newExp.Type.GetPropertiesDictIgnoreCase().Values; foreach (var dtoProp in dtoProps2) { foreach (var dtTb in _tables) diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 1ab01b5d..a8048150 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -79,11 +79,10 @@ namespace FreeSql.Internal.CommonProvider if (isThrowException) throw e; } - internal static ConcurrentDictionary> dicQueryTypeGetProperties = new ConcurrentDictionary>(); internal Dictionary GetQueryTypeProperties(Type type) { var tb = _util.GetTableByEntity(type); - var props = tb?.Properties ?? dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase)); + var props = tb?.Properties ?? type.GetPropertiesDictIgnoreCase(); return props; } public List Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index cdfe4a34..226d9c05 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -262,7 +262,7 @@ namespace FreeSql.Internal else { var sb = new StringBuilder(); - var ps = type.GetProperties(); + var ps = type.GetPropertiesDictIgnoreCase().Values; var psidx = 0; foreach (var p in ps) { @@ -360,7 +360,7 @@ namespace FreeSql.Internal } var xmlNav = xpath.CreateNavigator(); - var props = type.GetProperties(); + var props = type.GetPropertiesDictIgnoreCase().Values; foreach (var prop in props) { var className = (prop.DeclaringType.IsNested ? $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.DeclaringType.Name}.{prop.DeclaringType.Name}" : $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.Name}").Trim('.'); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index ec6b39ef..0e955ff1 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -51,7 +51,7 @@ namespace FreeSql.Internal var tbattr = common.GetEntityTableAttribute(entity); trytb = new TableInfo(); trytb.Type = entity; - trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); + trytb.Properties = entity.GetPropertiesDictIgnoreCase(); trytb.CsName = entity.Name; trytb.DbName = (tbattr?.Name ?? entity.Name); trytb.DbOldName = tbattr?.OldName; @@ -72,7 +72,7 @@ namespace FreeSql.Internal var columnsList = new List(); foreach (var p in trytb.Properties.Values) { - var setMethod = trytb.Type.GetMethod($"set_{p.Name}"); + var setMethod = p.GetSetMethod(); //trytb.Type.GetMethod($"set_{p.Name}"); var colattr = common.GetEntityColumnAttribute(entity, p); var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType); if (setMethod == null || (tp == null && p.PropertyType.IsValueType)) // 属性没有 set自动忽略 @@ -391,7 +391,7 @@ namespace FreeSql.Internal { if (midType != null) { - var midTypeProps = midType.GetProperties(); + var midTypeProps = midType.GetPropertiesDictIgnoreCase().Values; var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count(); var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count(); if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null; @@ -1024,7 +1024,7 @@ namespace FreeSql.Internal var type = obj.GetType(); if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) }; var ret = new List(); - var ps = type.GetProperties(); + var ps = type.GetPropertiesDictIgnoreCase().Values; foreach (var p in ps) { if (string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; @@ -1346,7 +1346,7 @@ namespace FreeSql.Internal Expression.Assign(readpknullExp, Expression.Constant(false)) }); - var props = type.GetProperties();//.ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase); + var props = type.GetPropertiesDictIgnoreCase().Values; var propIndex = 0; foreach (var prop in props) { From 08bd86ae407915d36cf31f8678b790da497d1168 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 10 Nov 2019 19:13:03 +0800 Subject: [PATCH 0231/1029] =?UTF-8?q?new=20=E9=87=8D=E6=96=B0=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E7=9A=84=E5=8F=8D=E5=B0=84=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/UtilsExpressionTree.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 0e955ff1..f0008742 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -84,7 +84,7 @@ namespace FreeSql.Internal { if (common.CodeFirst.IsLazyLoading) { - var getIsVirtual = trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; + var getIsVirtual = p.GetGetMethod()?.IsVirtual;// trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; var setIsVirtual = setMethod?.IsVirtual; if (getIsVirtual == true || setIsVirtual == true) propsLazy.Add((p, getIsVirtual == true, setIsVirtual == true)); From f2cb3bd5fe7887fb1ac6552333d71e1d2a558c42 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 10 Nov 2019 20:53:39 +0800 Subject: [PATCH 0232/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect=20.F?= =?UTF-8?q?rom=20=E6=96=B9=E6=B3=95=E4=B9=8B=E5=89=8D=E4=BD=BF=E7=94=A8=20?= =?UTF-8?q?.Include=20=E6=96=B9=E6=B3=95=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84=E5=A4=9A=E8=A1=A8=20JOIN=20?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E9=94=99=E8=AF=AF=E7=9A=84=20bug=EF=BC=9B#12?= =?UTF-8?q?8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 5 +++ FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 33 +++++++++++++++++++ .../SelectProvider/Select0Provider.cs | 16 ++++++--- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index b44b569a..21a0a7ed 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -199,6 +199,11 @@ 创建日期 + + + 回复的文本内容 + + 调价单 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 5234ee72..ba939607 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -137,10 +137,43 @@ namespace FreeSql.Tests { } + public class LinUser + { + public long id { get; set; } + } + + public class Comment + { + public Guid Id { get; set; } + /// + /// 回复的文本内容 + /// + public string Text { get; set; } + [Navigate("CreateUserId")] + public LinUser UserInfo { get; set; } + public long? CreateUserId { get; set; } + } + + public class UserLike + { + public Guid Id { get; set; } + public Guid SubjectId { get; set; } + public long? CreateUserId { get; set; } + } + [Fact] public void Test02() { + var comments1 = g.mysql.Select() + .LeftJoin((a, b) => a.Id == b.SubjectId) + .ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo }); + + var comments2 = g.mysql.Select() + .Include(r => r.UserInfo) + .From((z, b) => z.LeftJoin(u => u.Id == b.SubjectId)) + .ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo }); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 365de89d..4859985b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -71,20 +71,28 @@ namespace FreeSql.Internal.CommonProvider toType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._tables.ToArray())); else { + var findedIndexs = new List(); var _multiTables = toType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(to) as List; _multiTables[0] = from._tables[0]; for (var a = 1; a < lambParms.Count; a++) { - var tb = from._tables.Where(b => b.Alias == lambParms[a].Name && b.Table.Type == lambParms[a].Type).FirstOrDefault(); - if (tb != null) _multiTables[a] = tb; + var tbIndex = from._tables.FindIndex(b => b.Alias == lambParms[a].Name && b.Table.Type == lambParms[a].Type); ; + if (tbIndex != -1) + { + findedIndexs.Add(tbIndex); + _multiTables[a] = from._tables[tbIndex]; + } else { _multiTables[a].Alias = lambParms[a].Name; _multiTables[a].Parameter = lambParms[a]; } } - if (_multiTables.Count < from._tables.Count) - _multiTables.AddRange(from._tables.GetRange(_multiTables.Count, from._tables.Count - _multiTables.Count)); + for (var a = 1; a < from._tables.Count; a++) + { + if (findedIndexs.Contains(a)) continue; + _multiTables.Add(from._tables[a]); + } } toType.GetField("_tableRules", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._tableRules); toType.GetField("_aliasRule", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._aliasRule); From be77060ea878a48380595c2107152be184a51f29 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 11 Nov 2019 22:08:21 +0800 Subject: [PATCH 0233/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20MySql=20?= =?UTF-8?q?=E7=89=B9=E6=9C=89=E5=8A=9F=E8=83=BD=20On=20Duplicate=20Key=20U?= =?UTF-8?q?pdate=20=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + .../Curd/OnDuplicateKeyUpdateTest.cs | 201 ++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/.editorconfig | 4 + .../MySql/Curd/OnDuplicateKeyUpdateTest.cs | 201 ++++++++++++++++++ .../Internal/CommonProvider/InsertProvider.cs | 4 +- .../Curd/MySqlInsert.cs | 13 ++ .../Curd/MySqlUpdate.cs | 6 + .../Curd/OnDuplicateKeyUpdate.cs | 167 +++++++++++++++ .../FreeSql.Provider.MySql/MySqlExtensions.cs | 15 +- .../Oracle/Curd/OdbcOracleInsert.cs | 4 +- .../Curd/OracleInsert.cs | 4 +- 11 files changed, 619 insertions(+), 7 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/.editorconfig create mode 100644 FreeSql.Tests/FreeSql.Tests/MySql/Curd/OnDuplicateKeyUpdateTest.cs create mode 100644 Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3f9fb047..2711e35d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,6 +99,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs new file mode 100644 index 00000000..ff852737 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs @@ -0,0 +1,201 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector +{ + public class OnDuplicateKeyUpdateTest + { + class TestOnDuplicateKeyUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.mysql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = VALUES(`time`)"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = VALUES(`time`)"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = '2000-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = CASE `id` +WHEN 200 THEN '2000-01-01 00:00:00.000' +WHEN 201 THEN '2000-01-01 00:00:00.000' +WHEN 202 THEN '2000-01-01 00:00:00.000' END"); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') +ON DUPLICATE KEY UPDATE +`time` = '2000-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON DUPLICATE KEY UPDATE +`time` = CASE `id` +WHEN 200 THEN '2000-01-01 00:00:00.000' +WHEN 201 THEN '2000-01-01 00:00:00.000' +WHEN 202 THEN '2000-01-01 00:00:00.000' END"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = '2000-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = CASE `id` +WHEN 300 THEN '2000-01-01 00:00:00.000' +WHEN 301 THEN '2000-01-01 00:00:00.000' +WHEN 302 THEN '2000-01-01 00:00:00.000' END"); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') +ON DUPLICATE KEY UPDATE +`time` = '2000-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON DUPLICATE KEY UPDATE +`time` = CASE `id` +WHEN 300 THEN '2000-01-01 00:00:00.000' +WHEN 301 THEN '2000-01-01 00:00:00.000' +WHEN 302 THEN '2000-01-01 00:00:00.000' END"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'"); + odku2.ExecuteAffrows(); + + + var dt2020 = DateTime.Parse("2020-1-1"); + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'"); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void SetRaw() + { + + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/.editorconfig b/FreeSql.Tests/FreeSql.Tests/.editorconfig new file mode 100644 index 00000000..d2f6a096 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# xUnit2000: Constants and literals should be the expected argument +dotnet_diagnostic.xUnit2000.severity = none diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/OnDuplicateKeyUpdateTest.cs new file mode 100644 index 00000000..00ec83ad --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/OnDuplicateKeyUpdateTest.cs @@ -0,0 +1,201 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySql +{ + public class OnDuplicateKeyUpdateTest + { + class TestOnDuplicateKeyUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.mysql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = VALUES(`time`)"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = VALUES(`time`)"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = '2000-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = CASE `id` +WHEN 200 THEN '2000-01-01 00:00:00.000' +WHEN 201 THEN '2000-01-01 00:00:00.000' +WHEN 202 THEN '2000-01-01 00:00:00.000' END"); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') +ON DUPLICATE KEY UPDATE +`time` = '2000-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON DUPLICATE KEY UPDATE +`time` = CASE `id` +WHEN 200 THEN '2000-01-01 00:00:00.000' +WHEN 201 THEN '2000-01-01 00:00:00.000' +WHEN 202 THEN '2000-01-01 00:00:00.000' END"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = '2000-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = CASE `id` +WHEN 300 THEN '2000-01-01 00:00:00.000' +WHEN 301 THEN '2000-01-01 00:00:00.000' +WHEN 302 THEN '2000-01-01 00:00:00.000' END"); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') +ON DUPLICATE KEY UPDATE +`time` = '2000-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON DUPLICATE KEY UPDATE +`time` = CASE `id` +WHEN 300 THEN '2000-01-01 00:00:00.000' +WHEN 301 THEN '2000-01-01 00:00:00.000' +WHEN 302 THEN '2000-01-01 00:00:00.000' END"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'"); + odku2.ExecuteAffrows(); + + + var dt2020 = DateTime.Parse("2020-1-1"); + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'"); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void SetRaw() + { + + } + + } +} diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index f0389815..d7a95343 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -419,8 +419,8 @@ namespace FreeSql.Internal.CommonProvider var colidx = 0; foreach (var col in _table.Columns.Values) { - if (_ignore.ContainsKey(col.Attribute.Name)) continue; if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); @@ -437,8 +437,8 @@ namespace FreeSql.Internal.CommonProvider var colidx2 = 0; foreach (var col in _table.Columns.Values) { - if (_ignore.ContainsKey(col.Attribute.Name)) continue; if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); object val = col.GetMapValue(d); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 41b20ac4..c49a4597 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -1,7 +1,9 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Text; using System.Threading.Tasks; @@ -15,6 +17,17 @@ namespace FreeSql.MySql.Curd { } + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index dff4be5c..97e17653 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -18,6 +18,12 @@ namespace FreeSql.MySql.Curd { } + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs new file mode 100644 index 00000000..6b67e18d --- /dev/null +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -0,0 +1,167 @@ +using FreeSql.Aop; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.MySql.Curd +{ + public class OnDuplicateKeyUpdate where T1 : class + { + internal MySqlInsert _mysqlInsert; + internal MySqlUpdate _mysqlUpdatePriv; + internal MySqlUpdate _mysqlUpdate => _mysqlUpdatePriv ?? (_mysqlUpdatePriv = new MySqlUpdate(_mysqlInsert.InternalOrm, _mysqlInsert.InternalCommonUtils, _mysqlInsert.InternalCommonExpression, null).NoneParameter().SetSource(_mysqlInsert.InternalSource) as MySqlUpdate); + + public OnDuplicateKeyUpdate(IInsert insert) + { + _mysqlInsert = insert as MySqlInsert; + if (_mysqlInsert == null) throw new Exception("OnDuplicateKeyUpdate 是 FreeSql.Provider.MySql/FreeSql.Provider.MySqlConnector 特有的功能"); + } + + protected void ClearData() + { + _mysqlInsert.InternalClearData(); + _mysqlUpdatePriv = null; + } + + public OnDuplicateKeyUpdate IgnoreColumns(Expression> columns) + { + _mysqlUpdate.IgnoreColumns(columns); + return this; + } + public OnDuplicateKeyUpdate UpdateColumns(Expression> columns) + { + _mysqlUpdate.UpdateColumns(columns); + return this; + } + public OnDuplicateKeyUpdate IgnoreColumns(string[] columns) + { + _mysqlUpdate.IgnoreColumns(columns); + return this; + } + public OnDuplicateKeyUpdate UpdateColumns(string[] columns) + { + _mysqlUpdate.UpdateColumns(columns); + return this; + } + + public OnDuplicateKeyUpdate Set(Expression> column, TMember value) + { + _mysqlUpdate.Set(column, value); + return this; + } + public OnDuplicateKeyUpdate Set(Expression> exp) + { + _mysqlUpdate.Set(exp); + return this; + } + public OnDuplicateKeyUpdate SetRaw(string sql) + { + _mysqlUpdate.SetRaw(sql); + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + sb.Append(_mysqlInsert.ToSql()).Append("\r\nON DUPLICATE KEY UPDATE\r\n"); + + var sbSetEmpty = _mysqlUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _mysqlUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_mysqlUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _mysqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _mysqlUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _mysqlInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _mysqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true) + { + var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(field).Append(" + 1"); + } + else if (_mysqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + sb.Append(_mysqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim()); + else + { + var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = VALUES(").Append(field).Append(")"); + } + ++colidx; + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_mysqlInsert.InternalTable.Type, _mysqlInsert.InternalTable, CurdType.Insert, sql, _mysqlInsert.InternalParams); + _mysqlInsert.InternalOrm.Aop.CurdBefore?.Invoke(_mysqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _mysqlInsert.InternalOrm.Ado.ExecuteNonQuery(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _mysqlInsert.InternalOrm.Aop.CurdAfter?.Invoke(_mysqlInsert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_mysqlInsert.InternalTable.Type, _mysqlInsert.InternalTable, CurdType.Insert, sql, _mysqlInsert.InternalParams); + _mysqlInsert.InternalOrm.Aop.CurdBefore?.Invoke(_mysqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _mysqlInsert.InternalOrm.Aop.CurdAfter?.Invoke(_mysqlInsert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs b/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs index a08d689d..262aa716 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs @@ -1,4 +1,7 @@ -public static partial class FreeSqlMySqlGlobalExtensions +using FreeSql; +using FreeSql.MySql.Curd; + +public static partial class FreeSqlMySqlGlobalExtensions { /// @@ -9,4 +12,14 @@ /// public static string FormatMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args); static FreeSql.MySql.MySqlAdo _mysqlAdo = new FreeSql.MySql.MySqlAdo(); + + /// + /// MySql 特有的功能,On Duplicate Key Update + /// 注意:此功能会开启插入【自增列】 + /// + /// + /// + /// + public static OnDuplicateKeyUpdate OnDuplicateKeyUpdate(this IInsert that) where T1 : class => new FreeSql.MySql.Curd.OnDuplicateKeyUpdate(that.InsertIdentity()); + } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index 0405c439..9b542be3 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -37,8 +37,8 @@ namespace FreeSql.Odbc.Oracle foreach (var col in _table.Columns.Values) { if (col.Attribute.IsIdentity) _identCol = col; - if (_ignore.ContainsKey(col.Attribute.Name)) continue; if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx > 0) sbtb.Append(", "); sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); @@ -58,8 +58,8 @@ namespace FreeSql.Odbc.Oracle var colidx2 = 0; foreach (var col in _table.Columns.Values) { - if (_ignore.ContainsKey(col.Attribute.Name)) continue; if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); object val = col.GetMapValue(d); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 8585da3e..e1d632ca 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -39,8 +39,8 @@ namespace FreeSql.Oracle.Curd foreach (var col in _table.Columns.Values) { if (col.Attribute.IsIdentity) _identCol = col; - if (_ignore.ContainsKey(col.Attribute.Name)) continue; if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx > 0) sbtb.Append(", "); sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); @@ -60,8 +60,8 @@ namespace FreeSql.Oracle.Curd var colidx2 = 0; foreach (var col in _table.Columns.Values) { - if (_ignore.ContainsKey(col.Attribute.Name)) continue; if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); object val = col.GetMapValue(d); From 79ad890a62c012b9d00f370a3ada2e833cd8754e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 11 Nov 2019 22:12:44 +0800 Subject: [PATCH 0234/1029] ##0.11.11 #128 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1b1c0cae..1e34b352 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.9 + 0.11.11 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index bf8454b3..5ec6920a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 011089e1..428023bd 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 1e943ac9..eede07d7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c9dccf6c..82b2a542 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9 + 0.11.11 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index a3bb7270..16627c22 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index cb228ef9..3af5ebd8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index bd00819c..0d4c5d25 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e52cb990..faddd098 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a7d76d45..797dbbe6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2af99d90..2935c713 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index f0af41b1..d9e6a916 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.9 + 0.11.11 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index dbf7f665..2ba73a5b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.9.2 + 0.11.11 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From b43f9b668807b62bc97cd2de9f401c5c635c019a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 11 Nov 2019 23:13:10 +0800 Subject: [PATCH 0235/1029] update demo URL --- readme.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/readme.md b/readme.md index 9191ebc7..67cdcb46 100644 --- a/readme.md +++ b/readme.md @@ -49,6 +49,13 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [Abp 中使用 FreeSql](https://github.com/gnsilence/JPGZService),测试中...; - [FreeSql 优势.pptx](https://github.com/2881099/FreeSql/files/3305852/FreeSql.pptx); +> 学习项目 + +- [😃 A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) +- [内容管理系统](https://github.com/hejiyong/fscms) + +欢迎更多使用 FreeSql 的开源项目加入目录 + # Providers | Package Name | Version | From e0030b0c00e255c132ac81636cefc5f9adbda25f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 13 Nov 2019 16:21:30 +0800 Subject: [PATCH 0236/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20PostgreSQL?= =?UTF-8?q?=20=E7=89=B9=E6=9C=89=E5=8A=9F=E8=83=BD=20On=20Conflict=20Do=20?= =?UTF-8?q?Update=20=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 6 +- .../PostgreSQL/Curd/OnConflictDoUpdateTest.cs | 201 ++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 6 +- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 70 +++--- .../Curd/MySqlUpdate.cs | 1 + .../Curd/OnDuplicateKeyUpdate.cs | 6 +- .../Curd/OnConflictDoUpdate.cs | 197 +++++++++++++++++ .../Curd/PostgreSQLInsert.cs | 13 ++ .../Curd/PostgreSQLUpdate.cs | 10 + .../PostgreSQLExtensions.cs | 17 +- 10 files changed, 492 insertions(+), 35 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/OnConflictDoUpdateTest.cs create mode 100644 Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 21a0a7ed..6e6ec049 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -99,7 +99,7 @@ 总分 - + 菜单权限ID @@ -119,7 +119,7 @@ 菜单权限 - + 主键 @@ -164,7 +164,7 @@ 创建日期
- + 按钮主键 diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/OnConflictDoUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/OnConflictDoUpdateTest.cs new file mode 100644 index 00000000..25e46a99 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/OnConflictDoUpdateTest.cs @@ -0,0 +1,201 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.PostgreSQL +{ + public class OnConflictDoUpdateTest + { + class TestOnConflictDoUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime? time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.pgsql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = EXCLUDED.""time"""); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnConflictDoUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000'), (101, 'title-101', '2000-01-01 00:00:00.000000'), (102, 'title-102', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = EXCLUDED.""time"""); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.pgsql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = '2000-01-01 00:00:00.000000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = CASE EXCLUDED.""id"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp"); + odku2.ExecuteAffrows(); + + + g.pgsql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate().IgnoreColumns(a => a.title); + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2000-01-01 00:00:00.000000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate().IgnoreColumns(a => a.title); + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = CASE EXCLUDED.""id"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.pgsql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate(); + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = '2000-01-01 00:00:00.000000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate(); + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = CASE EXCLUDED.""id"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp"); + odku2.ExecuteAffrows(); + + + g.pgsql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate().UpdateColumns(a => a.time); + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2000-01-01 00:00:00.000000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate().UpdateColumns(a => a.time); + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = CASE EXCLUDED.""id"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp"); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.pgsql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2020-01-01 00:00:00.000000'"); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().OnConflictDoUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2020-01-01 00:00:00.000000'"); + odku2.ExecuteAffrows(); + + +// var dt2020 = DateTime.Parse("2020-1-1"); +// g.pgsql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); +// odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => a.time == dt2020); +// Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +//ON CONFLICT(""id"") DO UPDATE SET +//""time"" = '2020-01-01 00:00:00.000000'"); +// Assert.Equal(1, odku1.ExecuteAffrows()); + +// odku2 = g.pgsql.Insert(new[] { +// new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, +// new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, +// new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } +// }).NoneParameter().OnConflictDoUpdate().Set(a => a.time == dt2020); +// Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +//ON CONFLICT(""id"") DO UPDATE SET +//""time"" = '2020-01-01 00:00:00.000000'"); +// odku2.ExecuteAffrows(); + + +// g.pgsql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); +// odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); +// Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +//ON CONFLICT(""id"") DO UPDATE SET +//""time"" = '2020-01-01 00:00:00.000000', ""title"" = _ftb_.""title"" || '123'"); +// Assert.Equal(1, odku1.ExecuteAffrows()); + +// odku2 = g.pgsql.Insert(new[] { +// new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, +// new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, +// new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } +// }).NoneParameter().OnConflictDoUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); +// Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +//ON CONFLICT(""id"") DO UPDATE SET +//""time"" = '2020-01-01 00:00:00.000000', ""title"" = _ftb_.""title"" || '123'"); +// odku2.ExecuteAffrows(); + } + + [Fact] + public void SetRaw() + { + + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 287db677..c5321cd3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -427,6 +427,10 @@ namespace FreeSql.Tests [Fact] public void Test1() { + + + g.sqlite.Update(1).NoneParameter().Set(a => a.title, null).ExecuteAffrows(); + var testExNewRet1 = g.sqlite.Delete().Where("1=1").ExecuteAffrows(); var testExNewRet2 = g.sqlite.Insert(new TestAddEnumEx { Id = 1, Type = TestAddEnumType.中国人 }).ExecuteAffrows(); var testExNewRet3 = g.sqlite.Insert(new TestAddEnumEx { Id = 2, Type = TestAddEnumType.日本人 }).ExecuteAffrows(); @@ -858,8 +862,6 @@ namespace FreeSql.Tests - - var ttt1 = g.sqlite.Select().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index ba939607..3f1299b3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -21,7 +21,8 @@ namespace FreeSql.Tests /// /// 菜单权限ID /// - [Column(IsPrimary = true)] public String SysModulePermissionId { get; set; } + [Column(IsPrimary = true, OldName = "SysModulePermissionId")] + public String Id { get; set; } /// /// 菜单主键ID @@ -43,8 +44,8 @@ namespace FreeSql.Tests /// /// 主键 /// - [Column(IsPrimary = true)] - public String SysModuleId { get; set; } + [Column(IsPrimary = true, OldName = "SysModuleId")] + public String Id { get; set; } /// /// 父级ID @@ -92,8 +93,8 @@ namespace FreeSql.Tests /// /// 按钮主键 /// - [Column(IsPrimary = true)] - public String SysModuleButtonId { get; set; } + [Column(IsPrimary = true, OldName = "SysModuleButtonId")] + public String Id { get; set; } /// /// 名称 @@ -127,10 +128,12 @@ namespace FreeSql.Tests } partial class SysModulePermission { + [Navigate("SysModuleButtonId")] public SysModuleButton Button { get; set; } } partial class SysModule { + [Navigate("SysModuleId")] public List Permissions { get; set; } } partial class SysModuleButton @@ -164,10 +167,25 @@ namespace FreeSql.Tests [Fact] public void Test02() { + var list111 = g.sqlite.Select() + .Page(1, 10) + .ToList(a => new { Id = a.Id }) + .Select(a => new SysModule { Id = a.Id }).ToList() + .IncludeMany(g.sqlite, a => a.Permissions, then => then.Include(a => a.Button)); + + var list222 = g.sqlite.Select() + .IncludeMany(m => m.Permissions, then => then.Include(a => a.Button)) + .Page(1, 10) + .ToList(); + var comments1 = g.mysql.Select() - .LeftJoin((a, b) => a.Id == b.SubjectId) - .ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo }); + .LeftJoin((a, b) => a.Id == b.SubjectId) + .ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo }); + + + + var comments2 = g.mysql.Select() .Include(r => r.UserInfo) @@ -178,36 +196,32 @@ namespace FreeSql.Tests g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); - var menu1 = new SysModule { SysModuleId = "menu1", Name = "菜单1" }; - var menu2 = new SysModule { SysModuleId = "menu2", Name = "菜单2" }; + var menu1 = new SysModule { Id = "menu1", Name = "菜单1" }; + var menu2 = new SysModule { Id = "menu2", Name = "菜单2" }; g.sqlite.Insert(new[] { menu1, menu2 }).ExecuteAffrows(); - var button1 = new SysModuleButton { SysModuleButtonId = "button1", Name = "添加" }; - var button2 = new SysModuleButton { SysModuleButtonId = "button2", Name = "修改" }; - var button3 = new SysModuleButton { SysModuleButtonId = "button3", Name = "删除" }; - var button4 = new SysModuleButton { SysModuleButtonId = "button4", Name = "查询" }; + var button1 = new SysModuleButton { Id = "button1", Name = "添加" }; + var button2 = new SysModuleButton { Id = "button2", Name = "修改" }; + var button3 = new SysModuleButton { Id = "button3", Name = "删除" }; + var button4 = new SysModuleButton { Id = "button4", Name = "查询" }; g.sqlite.Insert(new[] { button1, button2, button3, button4 }).ExecuteAffrows(); g.sqlite.Insert(new[] { - new SysModulePermission { SysModulePermissionId = "menu1_button1", SysModuleId = menu1.SysModuleId, SysModuleButtonId = button1.SysModuleButtonId }, - new SysModulePermission { SysModulePermissionId = "menu1_button2", SysModuleId = menu1.SysModuleId, SysModuleButtonId = button2.SysModuleButtonId }, - new SysModulePermission { SysModulePermissionId = "menu1_button3", SysModuleId = menu1.SysModuleId, SysModuleButtonId = button3.SysModuleButtonId }, - new SysModulePermission { SysModulePermissionId = "menu1_button4", SysModuleId = menu1.SysModuleId, SysModuleButtonId = button4.SysModuleButtonId }, + new SysModulePermission { Id = "menu1_button1", SysModuleId = menu1.Id, SysModuleButtonId = button1.Id }, + new SysModulePermission { Id = "menu1_button2", SysModuleId = menu1.Id, SysModuleButtonId = button2.Id }, + new SysModulePermission { Id = "menu1_button3", SysModuleId = menu1.Id, SysModuleButtonId = button3.Id }, + new SysModulePermission { Id = "menu1_button4", SysModuleId = menu1.Id, SysModuleButtonId = button4.Id }, - new SysModulePermission { SysModulePermissionId = "menu2_button1", SysModuleId = menu2.SysModuleId, SysModuleButtonId = button1.SysModuleButtonId }, - new SysModulePermission { SysModulePermissionId = "menu2_button2", SysModuleId = menu2.SysModuleId, SysModuleButtonId = button2.SysModuleButtonId }, - new SysModulePermission { SysModulePermissionId = "menu2_button3", SysModuleId = menu2.SysModuleId, SysModuleButtonId = button3.SysModuleButtonId }, - new SysModulePermission { SysModulePermissionId = "menu2_button4", SysModuleId = menu2.SysModuleId, SysModuleButtonId = button4.SysModuleButtonId }, + new SysModulePermission { Id = "menu2_button1", SysModuleId = menu2.Id, SysModuleButtonId = button1.Id }, + new SysModulePermission { Id = "menu2_button2", SysModuleId = menu2.Id, SysModuleButtonId = button2.Id }, + new SysModulePermission { Id = "menu2_button3", SysModuleId = menu2.Id, SysModuleButtonId = button3.Id }, + new SysModulePermission { Id = "menu2_button4", SysModuleId = menu2.Id, SysModuleButtonId = button4.Id }, }).ExecuteAffrows(); - //var list = g.sqlite.Select() - // .IncludeMany(m => m.Buttons) - // .Page(1, 10) - // .ToList(); - var list = g.sqlite.Select() - .IncludeMany(m => m.Permissions.Where(p => p.SysModuleId == m.SysModuleId), - then => then.LeftJoin(p => p.Button.SysModuleButtonId == p.SysModuleButtonId)) + var list123123 = g.sqlite.Select() + .IncludeMany(m => m.Permissions.Where(p => p.SysModuleId == m.Id), + then => then.LeftJoin(p => p.Button.Id == p.SysModuleButtonId)) .ToList(); } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 97e17653..45ac940f 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -23,6 +23,7 @@ namespace FreeSql.MySql.Curd internal Dictionary InternalIgnore => _ignore; internal void InternalResetSource(List source) => _source = source; internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs index 6b67e18d..9804ce92 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -94,7 +94,11 @@ namespace FreeSql.MySql.Curd sb.Append(field).Append(" = ").Append(field).Append(" + 1"); } else if (_mysqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) - sb.Append(_mysqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim()); + { + var caseWhen = _mysqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _mysqlUpdate.InternalToSqlCaseWhenEnd(sb, col); + } else { var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs new file mode 100644 index 00000000..dc2a08d4 --- /dev/null +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -0,0 +1,197 @@ +using FreeSql.Aop; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.PostgreSQL.Curd +{ + public class OnConflictDoUpdate where T1 : class + { + internal PostgreSQLInsert _pgsqlInsert; + internal PostgreSQLUpdate _pgsqlUpdatePriv; + internal PostgreSQLUpdate _pgsqlUpdate => _pgsqlUpdatePriv ?? + (_pgsqlUpdatePriv = new PostgreSQLUpdate(_pgsqlInsert.InternalOrm, _pgsqlInsert.InternalCommonUtils, _pgsqlInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } + .NoneParameter().SetSource(_pgsqlInsert.InternalSource) as PostgreSQLUpdate); + ColumnInfo[] _columns; + + public OnConflictDoUpdate(IInsert insert, Expression> columns = null) + { + _pgsqlInsert = insert as PostgreSQLInsert; + if (_pgsqlInsert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.PostgreSQL 特有的功能"); + + if (columns != null) + { + var colsList = new List(); + var cols = _pgsqlInsert.InternalCommonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name)) + colsList.Add(col); + _columns = colsList.ToArray(); + } + if (_columns == null || _columns.Any() == false) + _columns = _pgsqlInsert.InternalTable.Primarys; + if (_columns.Any() == false) throw new Exception("OnConflictDoUpdate 功能要求实体类必须设置 IsPrimary 属性"); + } + + protected void ClearData() + { + _pgsqlInsert.InternalClearData(); + _pgsqlUpdatePriv = null; + } + + public OnConflictDoUpdate IgnoreColumns(Expression> columns) + { + _pgsqlUpdate.IgnoreColumns(columns); + return this; + } + public OnConflictDoUpdate UpdateColumns(Expression> columns) + { + _pgsqlUpdate.UpdateColumns(columns); + return this; + } + public OnConflictDoUpdate IgnoreColumns(string[] columns) + { + _pgsqlUpdate.IgnoreColumns(columns); + return this; + } + public OnConflictDoUpdate UpdateColumns(string[] columns) + { + _pgsqlUpdate.UpdateColumns(columns); + return this; + } + + public OnConflictDoUpdate Set(Expression> column, TMember value) + { + _pgsqlUpdate.Set(column, value); + return this; + } + //由于表达式解析问题,ON CONFLICT("id") DO UPDATE SET 需要指定表别名,如 Set(a => a.Clicks + 1) 解析会失败 + //暂时不开放这个功能,如有需要使用 SetRaw("click = t.click + 1") 替代该操作 + //public OnConflictDoUpdate Set(Expression> exp) + //{ + // _pgsqlUpdate.Set(exp); + // return this; + //} + public OnConflictDoUpdate SetRaw(string sql) + { + _pgsqlUpdate.SetRaw(sql); + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + var insertSql = _pgsqlInsert.ToSql(); + sb.Append(insertSql).Insert(insertSql.IndexOf('('), " AS _ftb_ ").Append("\r\nON CONFLICT("); + for (var a = 0; a < _columns.Length; a++) + { + if (a > 0) sb.Append(", "); + sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + } + sb.Append(") DO UPDATE SET\r\n"); + + var sbSetEmpty = _pgsqlUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _pgsqlUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_pgsqlUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _pgsqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _pgsqlUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _pgsqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true) + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = _ftb_.").Append(field).Append(" + 1"); + } + else if (_pgsqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _pgsqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _pgsqlUpdate.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = EXCLUDED.").Append(field); + } + ++colidx; + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); + _pgsqlInsert.InternalOrm.Aop.CurdBefore?.Invoke(_pgsqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _pgsqlInsert.InternalOrm.Aop.CurdAfter?.Invoke(_pgsqlInsert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); + _pgsqlInsert.InternalOrm.Aop.CurdBefore?.Invoke(_pgsqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _pgsqlInsert.InternalOrm.Aop.CurdAfter?.Invoke(_pgsqlInsert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index af811633..af39699c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -1,7 +1,9 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -16,6 +18,17 @@ namespace FreeSql.PostgreSQL.Curd { } + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index e56c125c..e2d85ce9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -18,6 +18,14 @@ namespace FreeSql.PostgreSQL.Curd { } + internal string InternalTableAlias; + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); @@ -64,6 +72,7 @@ namespace FreeSql.PostgreSQL.Curd { if (_table.Primarys.Length == 1) { + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); return; } @@ -72,6 +81,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(" || "); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); ++pkidx; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs index 9794e60f..5528b09c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs @@ -1,4 +1,9 @@ -public static partial class FreeSqlPostgreSQLGlobalExtensions +using FreeSql; +using FreeSql.PostgreSQL.Curd; +using System; +using System.Linq.Expressions; + +public static partial class FreeSqlPostgreSQLGlobalExtensions { /// @@ -9,4 +14,14 @@ /// public static string FormatPostgreSQL(this string that, params object[] args) => _postgresqlAdo.Addslashes(that, args); static FreeSql.PostgreSQL.PostgreSQLAdo _postgresqlAdo = new FreeSql.PostgreSQL.PostgreSQLAdo(); + + /// + /// PostgreSQL9.5+ 特有的功能,On Conflict Do Update + /// 注意:此功能会开启插入【自增列】 + /// + /// + /// + /// 默认是以主键作为重复判断,也可以指定其他列:a => a.Name | a => new{a.Name,a.Time} | a => new[]{"name","time"} + /// + public static OnConflictDoUpdate OnConflictDoUpdate(this IInsert that, Expression> columns = null) where T1 : class => new FreeSql.PostgreSQL.Curd.OnConflictDoUpdate(that.InsertIdentity(), columns); } From 24e2c098a44a77c05ecdfca802c241a0fea36a73 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 13 Nov 2019 16:35:13 +0800 Subject: [PATCH 0237/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20PostgreSQL?= =?UTF-8?q?=20=E7=89=B9=E6=9C=89=E5=8A=9F=E8=83=BD=20On=20Conflict=20Do=20?= =?UTF-8?q?Update=20=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQL/Curd/OnConflictDoUpdateTest.cs | 36 +++++++++---------- .../Curd/OnConflictDoUpdate.cs | 5 ++- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/OnConflictDoUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/OnConflictDoUpdateTest.cs index 25e46a99..1f54becc 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/OnConflictDoUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/OnConflictDoUpdateTest.cs @@ -21,7 +21,7 @@ namespace FreeSql.Tests.PostgreSQL { g.pgsql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000') + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000') ON CONFLICT(""id"") DO UPDATE SET ""title"" = EXCLUDED.""title"", ""time"" = EXCLUDED.""time"""); @@ -32,7 +32,7 @@ ON CONFLICT(""id"") DO UPDATE SET new TestOnConflictDoUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, new TestOnConflictDoUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnConflictDoUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000'), (101, 'title-101', '2000-01-01 00:00:00.000000'), (102, 'title-102', '2000-01-01 00:00:00.000000') + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000'), (101, 'title-101', '2000-01-01 00:00:00.000000'), (102, 'title-102', '2000-01-01 00:00:00.000000') ON CONFLICT(""id"") DO UPDATE SET ""title"" = EXCLUDED.""title"", ""time"" = EXCLUDED.""time"""); @@ -44,7 +44,7 @@ ON CONFLICT(""id"") DO UPDATE SET { g.pgsql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200') + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200') ON CONFLICT(""id"") DO UPDATE SET ""title"" = EXCLUDED.""title"", ""time"" = '2000-01-01 00:00:00.000000'"); @@ -55,7 +55,7 @@ ON CONFLICT(""id"") DO UPDATE SET new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON CONFLICT(""id"") DO UPDATE SET ""title"" = EXCLUDED.""title"", ""time"" = CASE EXCLUDED.""id"" @@ -67,7 +67,7 @@ WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp"); g.pgsql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate().IgnoreColumns(a => a.title); - Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200') + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200') ON CONFLICT(""id"") DO UPDATE SET ""time"" = '2000-01-01 00:00:00.000000'"); Assert.Equal(1, odku1.ExecuteAffrows()); @@ -77,7 +77,7 @@ ON CONFLICT(""id"") DO UPDATE SET new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnConflictDoUpdate().IgnoreColumns(a => a.title); - Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON CONFLICT(""id"") DO UPDATE SET ""time"" = CASE EXCLUDED.""id"" WHEN 200 THEN '2000-01-01 00:00:00.000000' @@ -91,7 +91,7 @@ WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp"); { g.pgsql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300') + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300') ON CONFLICT(""id"") DO UPDATE SET ""title"" = EXCLUDED.""title"", ""time"" = '2000-01-01 00:00:00.000000'"); @@ -102,7 +102,7 @@ ON CONFLICT(""id"") DO UPDATE SET new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON CONFLICT(""id"") DO UPDATE SET ""title"" = EXCLUDED.""title"", ""time"" = CASE EXCLUDED.""id"" @@ -114,7 +114,7 @@ WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp"); g.pgsql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate().UpdateColumns(a => a.time); - Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300') + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300') ON CONFLICT(""id"") DO UPDATE SET ""time"" = '2000-01-01 00:00:00.000000'"); Assert.Equal(1, odku1.ExecuteAffrows()); @@ -124,7 +124,7 @@ ON CONFLICT(""id"") DO UPDATE SET new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnConflictDoUpdate().UpdateColumns(a => a.time); - Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON CONFLICT(""id"") DO UPDATE SET ""time"" = CASE EXCLUDED.""id"" WHEN 300 THEN '2000-01-01 00:00:00.000000' @@ -138,7 +138,7 @@ WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp"); { g.pgsql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); var odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') + Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') ON CONFLICT(""id"") DO UPDATE SET ""time"" = '2020-01-01 00:00:00.000000'"); Assert.Equal(1, odku1.ExecuteAffrows()); @@ -148,7 +148,7 @@ ON CONFLICT(""id"") DO UPDATE SET new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnConflictDoUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') + Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') ON CONFLICT(""id"") DO UPDATE SET ""time"" = '2020-01-01 00:00:00.000000'"); odku2.ExecuteAffrows(); @@ -157,7 +157,7 @@ ON CONFLICT(""id"") DO UPDATE SET // var dt2020 = DateTime.Parse("2020-1-1"); // g.pgsql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); // odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => a.time == dt2020); -// Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +// Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') //ON CONFLICT(""id"") DO UPDATE SET //""time"" = '2020-01-01 00:00:00.000000'"); // Assert.Equal(1, odku1.ExecuteAffrows()); @@ -167,7 +167,7 @@ ON CONFLICT(""id"") DO UPDATE SET // new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, // new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } // }).NoneParameter().OnConflictDoUpdate().Set(a => a.time == dt2020); -// Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +// Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') //ON CONFLICT(""id"") DO UPDATE SET //""time"" = '2020-01-01 00:00:00.000000'"); // odku2.ExecuteAffrows(); @@ -175,9 +175,9 @@ ON CONFLICT(""id"") DO UPDATE SET // g.pgsql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); // odku1 = g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnConflictDoUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); -// Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +// Assert.Equal(odku1.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') //ON CONFLICT(""id"") DO UPDATE SET -//""time"" = '2020-01-01 00:00:00.000000', ""title"" = _ftb_.""title"" || '123'"); +//""time"" = '2020-01-01 00:00:00.000000', ""title"" = ""testonconflictdoupdateinfo"".""title"" || '123'"); // Assert.Equal(1, odku1.ExecuteAffrows()); // odku2 = g.pgsql.Insert(new[] { @@ -185,9 +185,9 @@ ON CONFLICT(""id"") DO UPDATE SET // new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, // new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } // }).NoneParameter().OnConflictDoUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); -// Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo"" AS _ftb_ (""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +// Assert.Equal(odku2.ToSql(), @"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') //ON CONFLICT(""id"") DO UPDATE SET -//""time"" = '2020-01-01 00:00:00.000000', ""title"" = _ftb_.""title"" || '123'"); +//""time"" = '2020-01-01 00:00:00.000000', ""title"" = ""testonconflictdoupdateinfo"".""title"" || '123'"); // odku2.ExecuteAffrows(); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index dc2a08d4..2e1dd474 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -89,8 +89,7 @@ namespace FreeSql.PostgreSQL.Curd public string ToSql() { var sb = new StringBuilder(); - var insertSql = _pgsqlInsert.ToSql(); - sb.Append(insertSql).Insert(insertSql.IndexOf('('), " AS _ftb_ ").Append("\r\nON CONFLICT("); + sb.Append(_pgsqlInsert.ToSql()).Append("\r\nON CONFLICT("); for (var a = 0; a < _columns.Length; a++) { if (a > 0) sb.Append(", "); @@ -117,7 +116,7 @@ namespace FreeSql.PostgreSQL.Curd if (col.Attribute.IsVersion == true) { var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); - sb.Append(field).Append(" = _ftb_.").Append(field).Append(" + 1"); + sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); } else if (_pgsqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) { From dda7c8bc9cd645b07ca6ca712949be1aebc6f520 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 13 Nov 2019 19:57:44 +0800 Subject: [PATCH 0238/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20AsTable=20?= =?UTF-8?q?=E5=92=8C=20Repository=20=E5=88=86=E8=A1=A8=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=BF=81=E7=A7=BB=E5=88=86=E8=A1=A8=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20ICodeFirst.SyncSt?= =?UTF-8?q?ructure(Type=20entityType,=20string=20tableName)=20=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E8=A1=A8=E5=90=8D=E6=9D=A5=E8=BF=81=E7=A7=BB=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=EF=BC=9B=20```csharp=20fsql.CodeFirst.SyncStructure(t?= =?UTF-8?q?ypeof(Log),=20"Log=5F1");=20//=E8=BF=81=E7=A7=BB=E5=88=B0=20Log?= =?UTF-8?q?=5F1=20=E8=A1=A8=20fsql.CodeFirst.SyncStructure(typeof(Log),=20?= =?UTF-8?q?"Log=5F2");=20//=E8=BF=81=E7=A7=BB=E5=88=B0=20Log=5F2=20?= =?UTF-8?q?=E8=A1=A8=20```?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 --- .../Oracle/Curd/OracleSelectTest.cs | 29 +++++----- .../Oracle/Curd/OracleSelectTest.cs | 29 +++++----- FreeSql/FreeSql.xml | 18 ++++++- FreeSql/Interface/ICodeFirst.cs | 16 +++++- .../CommonProvider/CodeFirstProvider.cs | 54 ++++++++++++++----- .../Internal/CommonProvider/DeleteProvider.cs | 1 + .../Internal/CommonProvider/InsertProvider.cs | 1 + .../SelectProvider/Select0Provider.cs | 1 + .../SelectProvider/Select1Provider.cs | 8 +-- .../Internal/CommonProvider/UpdateProvider.cs | 1 + .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 20 +++++-- .../Default/OdbcCodeFirst.cs | 2 +- .../MySql/OdbcMySqlCodeFirst.cs | 20 +++++-- .../Oracle/OdbcOracleCodeFirst.cs | 23 +++++--- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 20 +++++-- .../SqlServer/OdbcSqlServerCodeFirst.cs | 21 ++++++-- .../OracleCodeFirst.cs | 23 +++++--- .../PostgreSQLCodeFirst.cs | 20 +++++-- .../SqlServerCodeFirst.cs | 21 ++++++-- .../SqliteCodeFirst.cs | 20 +++++-- 21 files changed, 254 insertions(+), 101 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..3f9fb047 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,13 +99,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 9c9a7d8f..6894291e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -821,65 +821,66 @@ namespace FreeSql.Tests.Odbc.Oracle Func tableRule = (type, oldname) => { - if (type == typeof(Topic)) return oldname + "AsTable1"; - else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; - return oldname + "AsTable"; + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; }; //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); //���û�е������� query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); //������� query = select .LeftJoin(a => a.Type.Guid == a.TypeGuid) .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); query = select .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); //���û�е�������b��c������ϵ var query2 = select.From((s, b, c) => s .LeftJoin(a => a.TypeGuid == b.Guid) .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql); //������϶����㲻�� query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); } public class TiOtmModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 92ecbd0c..2314666d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -821,65 +821,66 @@ namespace FreeSql.Tests.Oracle Func tableRule = (type, oldname) => { - if (type == typeof(Topic)) return oldname + "AsTable1"; - else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; - return oldname + "AsTable"; + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; }; //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); //���û�е������� query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); //������� query = select .LeftJoin(a => a.Type.Guid == a.TypeGuid) .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); query = select .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); //���û�е�������b��c������ϵ var query2 = select.From((s, b, c) => s .LeftJoin(a => a.TypeGuid == b.Guid) .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql); //������϶����㲻�� query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); } public class TiOtmModel1 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9675d56b..185896b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2355,7 +2355,15 @@ 将实体类型集合与数据库对比,返回DDL语句 - + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 @@ -2372,6 +2380,14 @@ + + + 同步实体类型到数据库(指定表名) + + 实体类型 + 指定表名对比 + + 根据 System.Type 获取数据库信息 diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 18b7b67e..e79fe7cc 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -44,10 +44,17 @@ namespace FreeSql /// /// 将实体类型集合与数据库对比,返回DDL语句 /// - /// + /// 实体类型 /// string GetComparisonDDLStatements(params Type[] entityTypes); /// + /// 将实体类型与数据库对比,返回DDL语句(指定表名) + /// + /// 实体类型 + /// 指定表名对比 + /// + string GetComparisonDDLStatements(Type entityType, string tableName); + /// /// 同步实体类型到数据库 /// /// @@ -59,6 +66,13 @@ namespace FreeSql /// /// bool SyncStructure(params Type[] entityTypes); + /// + /// 同步实体类型到数据库(指定表名) + /// + /// 实体类型 + /// 指定表名对比 + /// + bool SyncStructure(Type entityType, string tableName); /// /// 根据 System.Type 获取数据库信息 diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index a71c680a..1f00f176 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -41,18 +41,48 @@ namespace FreeSql.Internal.CommonProvider public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type); public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type); - public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); - public abstract string GetComparisonDDLStatements(params Type[] entityTypes); + protected string GetTableNameLowerOrUpper(string tableName) + { + if (string.IsNullOrEmpty(tableName)) return ""; + if (IsSyncStructureToLower) tableName = tableName.ToLower(); + if (IsSyncStructureToUpper) tableName = tableName.ToUpper(); + return tableName; + } + public string GetComparisonDDLStatements() => + this.GetComparisonDDLStatements((typeof(TEntity), "")); + public string GetComparisonDDLStatements(params Type[] entityTypes) => entityTypes == null ? null : + this.GetComparisonDDLStatements(entityTypes.Distinct().Select(a => (a, "")).ToArray()); + public string GetComparisonDDLStatements(Type entityType, string tableName) => + this.GetComparisonDDLStatements((entityType, GetTableNameLowerOrUpper(tableName))); + protected abstract string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects); static object syncStructureLock = new object(); - internal ConcurrentDictionary dicSyced = new ConcurrentDictionary(); - public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); - public bool SyncStructure(params Type[] entityTypes) + object _dicSycedLock = new object(); + Dictionary> _dicSynced = new Dictionary>(); + internal ConcurrentDictionary _dicSycedGetOrAdd(Type entityType) { - if (entityTypes == null) return false; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray().Distinct().ToArray(); - if (syncTypes.Any() == false) return false; - var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); + if (_dicSynced.TryGetValue(entityType, out var trydic) == false) + lock (_dicSycedLock) + if (_dicSynced.TryGetValue(entityType, out trydic) == false) + _dicSynced.Add(entityType, trydic = new ConcurrentDictionary()); + return trydic; + } + internal void _dicSycedTryAdd(Type entityType, string tableName = null) => + _dicSycedGetOrAdd(entityType).TryAdd(GetTableNameLowerOrUpper(tableName), true); + + public bool SyncStructure() => + this.SyncStructure((typeof(TEntity), "")); + public bool SyncStructure(params Type[] entityTypes) => entityTypes == null ? false : + this.SyncStructure(entityTypes.Distinct().Select(a => (a, "")).ToArray()); + public bool SyncStructure(Type entityType, string tableName) => + this.SyncStructure((entityType, GetTableNameLowerOrUpper(tableName))); + protected bool SyncStructure(params (Type entityType, string tableName)[] objects) + { + if (objects == null) return false; + (Type entityType, string tableName)[] syncObjects = objects.Where(a => _dicSycedGetOrAdd(a.entityType).ContainsKey(GetTableNameLowerOrUpper(a.tableName)) == false && GetTableByEntity(a.entityType)?.DisableSyncStructure == false) + .Select(a => (a.entityType, GetTableNameLowerOrUpper(a.tableName))).ToArray(); + if (syncObjects.Any() == false) return false; + var before = new Aop.SyncStructureBeforeEventArgs(syncObjects.Select(a => a.entityType).ToArray()); _orm.Aop.SyncStructureBefore?.Invoke(this, before); Exception exception = null; string ddl = null; @@ -60,14 +90,14 @@ namespace FreeSql.Internal.CommonProvider { lock (syncStructureLock) { - ddl = this.GetComparisonDDLStatements(syncTypes); + ddl = this.GetComparisonDDLStatements(syncObjects); if (string.IsNullOrEmpty(ddl)) { - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true); + foreach (var syncObject in syncObjects) _dicSycedTryAdd(syncObject.entityType, syncObject.tableName); return true; } var affrows = ExecuteDDLStatements(ddl); - foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true); + foreach (var syncObject in syncObjects) _dicSycedTryAdd(syncObject.entityType, syncObject.tableName); return true; } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 24c07bad..b1b740af 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -123,6 +123,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(newname)) return _table.DbName; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname); return newname; } public IDelete AsTable(Func tableRule) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index d7a95343..e344d149 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -393,6 +393,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(newname)) return _table.DbName; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname); return newname; } public IInsert AsTable(Func tableRule) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 4859985b..47687449 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -895,6 +895,7 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsSyncStructureToLower) name = name.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) name = name.ToUpper(); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, name); } } dict.Add(tb.Table.Type, name); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index de88f2a9..96bee31f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -183,7 +183,7 @@ namespace FreeSql.Internal.CommonProvider if (typeof(TReturn) == typeof(T1)) return this as ISelect; _tables[0].Parameter = select.Parameters[0]; _selectExpression = select.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TReturn), true); + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TReturn)); //._dicSyced.TryAdd(typeof(TReturn), true); var ret = _orm.Select(); Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -198,7 +198,7 @@ namespace FreeSql.Internal.CommonProvider ), SelectTableInfoType.InnerJoin); if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true); + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -213,7 +213,7 @@ namespace FreeSql.Internal.CommonProvider ), SelectTableInfoType.InnerJoin); if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true); + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -245,7 +245,7 @@ namespace FreeSql.Internal.CommonProvider } if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true); + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 44313046..8823c5bc 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -515,6 +515,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(newname)) return _table.DbName; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname); return newname; } public IUpdate AsTable(Func tableRule) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 8457e93d..34dae9ea 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -82,7 +82,7 @@ namespace FreeSql.MySql return null; } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; @@ -106,17 +106,27 @@ namespace FreeSql.MySql var sb = new StringBuilder(); try { - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 2); if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { database, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs index b007fb41..47098780 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs @@ -89,6 +89,6 @@ namespace FreeSql.Odbc.Default return null; } - public override string GetComparisonDDLStatements(params Type[] entityTypes) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 06effe56..557692e9 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -71,7 +71,7 @@ namespace FreeSql.Odbc.MySql return null; } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; @@ -95,17 +95,27 @@ namespace FreeSql.Odbc.MySql var sb = new StringBuilder(); try { - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 2); if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { database, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 84394be6..a7fc5be4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -75,7 +75,7 @@ namespace FreeSql.Odbc.Oracle return null; } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var userId = (_orm.Ado.MasterPool as OdbcOracleConnectionPool).UserId; var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 @@ -83,18 +83,29 @@ namespace FreeSql.Odbc.Oracle var sb = new StringBuilder(); var sbDeclare = new StringBuilder(); - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 2); if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; - var primaryKeyName = (entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + primaryKeyName = null; + } + } if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 964764a1..2b5c557e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -79,22 +79,32 @@ namespace FreeSql.Odbc.PostgreSQL return null; } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var sb = new StringBuilder(); var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 2); if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index f9448e14..d8cd5f74 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -103,7 +103,7 @@ ELSE , @level2type = 'COLUMN', @level2name = N'{2}' ", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; @@ -127,12 +127,12 @@ ELSE var sb = new StringBuilder(); try { - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 3); if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] }; if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] }; @@ -140,6 +140,17 @@ ELSE var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] }; if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 3); + if (tbtmpname?.Length == 1) tbtmpname = new[] { database, "dbo", tbtmpname[0] }; + if (tbtmpname?.Length == 2) tbtmpname = new[] { database, tbtmpname[0], tbtmpname[1] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1] || tbname[2] != tbtmpname[2]) + { + tbname = tbtmpname; + tboldname = null; + } + } if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 6ac27090..ee4f2097 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -76,7 +76,7 @@ namespace FreeSql.Oracle return null; } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var userId = (_orm.Ado.MasterPool as OracleConnectionPool).UserId; var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 @@ -84,18 +84,29 @@ namespace FreeSql.Oracle var sb = new StringBuilder(); var sbDeclare = new StringBuilder(); - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 2); if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; - var primaryKeyName = (entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + primaryKeyName = null; + } + } if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 961ef8b5..fa57fdf1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -117,22 +117,32 @@ namespace FreeSql.PostgreSQL return null; } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var sb = new StringBuilder(); var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 2); if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index e9249c2b..bcc14338 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -106,7 +106,7 @@ ELSE , @level2type = 'COLUMN', @level2name = N'{2}' ", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; @@ -130,12 +130,12 @@ ELSE var sb = new StringBuilder(); try { - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 3); if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] }; if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] }; @@ -143,6 +143,17 @@ ELSE var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] }; if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 3); + if (tbtmpname?.Length == 1) tbtmpname = new[] { database, "dbo", tbtmpname[0] }; + if (tbtmpname?.Length == 2) tbtmpname = new[] { database, tbtmpname[0], tbtmpname[1] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1] || tbname[2] != tbtmpname[2]) + { + tbname = tbtmpname; + tboldname = null; + } + } if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 9b00b103..1c665dc7 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -73,21 +73,31 @@ namespace FreeSql.Sqlite return null; } - public override string GetComparisonDDLStatements(params Type[] entityTypes) + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var sb = new StringBuilder(); var sbDeclare = new StringBuilder(); - foreach (var entityType in entityTypes) + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = tb.DbName.Split(new[] { '.' }, 2); if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] }; var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { "main", tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { "main", tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } var sbalter = new StringBuilder(); var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 From b5efb387bd3e60014c12315308ef9ef6b657bfc4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 13 Nov 2019 20:21:49 +0800 Subject: [PATCH 0239/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20=E6=89=80?= =?UTF-8?q?=E6=9C=89=E5=8F=82=E6=95=B0=E5=8C=96=20object=20parms=20?= =?UTF-8?q?=E5=8F=AF=E4=BD=BF=E7=94=A8=20IDictionary=20=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E4=BC=A0=E5=85=A5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ++++++ FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 6 ++++++ FreeSql/Internal/UtilsExpressionTree.cs | 27 ++++++++++++++++++------ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3f9fb047..2711e35d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,6 +99,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 3f1299b3..c7b739ec 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -167,6 +167,12 @@ namespace FreeSql.Tests [Fact] public void Test02() { + + var dicParamslist = g.sqlite.Select().Page(1, 10) + .Where("id > @id and id > @id2 and id > @id3", + new Dictionary { ["id"] = 1, ["id2"] = 2, ["id3"] = 3 }) + .ToList(); + var list111 = g.sqlite.Select() .Page(1, 10) .ToList(a => new { Id = a.Id }) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index f0008742..a86fd69f 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1024,13 +1024,28 @@ namespace FreeSql.Internal var type = obj.GetType(); if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) }; var ret = new List(); - var ps = type.GetPropertiesDictIgnoreCase().Values; - foreach (var p in ps) + var dic = obj as IDictionary; + if (dic != null) { - if (string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; - var pvalue = p.GetValue(obj, null); - if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype)); - else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue)); + foreach (var key in dic.Keys) + { + if (string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{key}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; + var val = dic[key]; + var valType = val == null ? typeof(string) : val.GetType(); + if (valType == ttype) ret.Add((T)Convert.ChangeType(val, ttype)); + else ret.Add(constructorParamter(key.ToString(), valType, val)); + } + } + else + { + var ps = type.GetPropertiesDictIgnoreCase().Values; + foreach (var p in ps) + { + if (string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; + var pvalue = p.GetValue(obj, null); + if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype)); + else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue)); + } } return ret.ToArray(); } From 6a606a82aff78865106ef902031fe0c1fadf804b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 13 Nov 2019 20:25:43 +0800 Subject: [PATCH 0240/1029] ## v0.11.12 #119 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1e34b352..6536f0fa 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.11 + 0.11.12 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 5ec6920a..4c1c81c8 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 428023bd..0f75be11 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index eede07d7..d0e5a060 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..3f9fb047 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,13 +99,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 82b2a542..850b2c54 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.11 + 0.11.12 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 16627c22..6c31ed45 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3af5ebd8..e43f1ad5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0d4c5d25..4ed2dd82 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index faddd098..0f1128d4 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 797dbbe6..7b44f7af 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2935c713..f0b6e44e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d9e6a916..8de8fe6a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 2ba73a5b..f8b2dbc4 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.11 + 0.11.12 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 7d1f9b126fc61dd1dac3c576bfd3a157b7eeff9c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 15 Nov 2019 13:25:14 +0800 Subject: [PATCH 0241/1029] debug Destructor #131 --- FreeSql.DbContext/DbContext/DbContext.cs | 6 ++--- FreeSql.DbContext/DbSet/DbSet.cs | 6 ++--- .../Repository/DataFilter/DataFilter.cs | 10 ++------- .../Repository/Repository/BaseRepository.cs | 6 ++--- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 22 ++++++++++--------- .../AdoProvider/AdoProviderTransaction.cs | 9 +++----- .../SelectProvider/Select0Provider.cs | 6 ++--- .../FreeSql.Provider.MySql/MySqlProvider.cs | 10 ++++----- .../Default/OdbcProvider.cs | 18 +++++++-------- .../MySql/OdbcMySqlProvider.cs | 10 ++++----- .../Oracle/OdbcOracleProvider.cs | 10 ++++----- .../PostgreSQL/OdbcPostgreSQLProvider.cs | 10 ++++----- .../SqlServer/OdbcSqlServerProvider.cs | 10 ++++----- .../FreeSql.Provider.Oracle/OracleProvider.cs | 10 ++++----- .../PostgreSQLProvider.cs | 10 ++++----- .../SqlServerProvider.cs | 10 ++++----- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 10 ++++----- 17 files changed, 73 insertions(+), 100 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 449a6f32..f2913f53 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.Linq; using System.Reflection; using System.Threading.Tasks; +using System.Threading; namespace FreeSql { @@ -200,11 +201,10 @@ namespace FreeSql #endregion ~DbContext() => this.Dispose(); - bool _isdisposed = false; + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; - _isdisposed = true; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { _actions.Clear(); diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 6150feb4..fc31b1a8 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -7,6 +7,7 @@ using System.Collections.Concurrent; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Threading; namespace FreeSql { @@ -36,11 +37,10 @@ namespace FreeSql } ~DbSet() => this.Dispose(); - bool _isdisposed = false; + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; - _isdisposed = true; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { this._dicUpdateTimes.Clear(); diff --git a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs index b03874bd..c0e578ff 100644 --- a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs +++ b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs @@ -144,10 +144,7 @@ namespace FreeSql return _filters.TryGetValue(filterName, out var tryfi) ? tryfi.IsEnabled : false; } - ~DataFilter() - { - this.Dispose(); - } + ~DataFilter() => this.Dispose(); public void Dispose() { _filters.Clear(); @@ -169,10 +166,7 @@ namespace FreeSql return this; } - ~FluentDataFilter() - { - this.Dispose(); - } + ~FluentDataFilter() => this.Dispose(); public void Dispose() { _filters.Clear(); diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 723b545e..80145899 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -42,11 +43,10 @@ namespace FreeSql } ~BaseRepository() => this.Dispose(); - bool _isdisposed = false; + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; - _isdisposed = true; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { _dbsetPriv?.Dispose(); diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 8aeb4d6f..892d5e74 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -105,18 +105,20 @@ namespace FreeSql public DbContext.EntityChangeReport EntityChangeReport { get; } = new DbContext.EntityChangeReport(); - ~UnitOfWork() - { - this.Dispose(); - } - bool _isdisposed = false; + ~UnitOfWork() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; - _isdisposed = true; - this.Rollback(); - this.Close(); - GC.SuppressFinalize(this); + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + try + { + this.Rollback(); + this.Close(); + } + finally + { + GC.SuppressFinalize(this); + } } } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 9fb1b7c2..a2b807dd 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -120,14 +120,11 @@ namespace FreeSql.Internal.CommonProvider } } - ~AdoProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~AdoProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { Transaction2[] trans = null; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 47687449..44a32fc2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider @@ -38,11 +39,10 @@ namespace FreeSql.Internal.CommonProvider protected List _whereCascadeExpression = new List(); protected List _whereGlobalFilter; - bool _isDisponse = false; + int _disposeCounter; ~Select0Provider() { - if (_isDisponse) return; - _isDisponse = false; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; _where.Clear(); _params.Clear(); _tables.Clear(); diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index 1ce3cf0b..b5f2dd8d 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Linq.Expressions; +using System.Threading; namespace FreeSql.MySql { @@ -73,14 +74,11 @@ namespace FreeSql.MySql public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~MySqlProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~MySqlProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index a0c38cd9..cac216c5 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -1,10 +1,11 @@ using FreeSql.Internal; using FreeSql.Internal.CommonProvider; -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Linq; using FreeSql.Odbc.Default; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading; namespace FreeSql.Odbc.Default { @@ -86,14 +87,11 @@ namespace FreeSql.Odbc.Default public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~OdbcProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index d1fa229f..f779a505 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Linq.Expressions; +using System.Threading; namespace FreeSql.Odbc.MySql { @@ -51,14 +52,11 @@ namespace FreeSql.Odbc.MySql public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcMySqlProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~OdbcMySqlProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index 974bf391..9191ce78 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; using System.Data.Common; +using System.Threading; namespace FreeSql.Odbc.Oracle { @@ -52,14 +53,11 @@ namespace FreeSql.Odbc.Oracle public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcOracleProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~OdbcOracleProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index 26da3b6d..8358e646 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -2,6 +2,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; +using System.Threading; namespace FreeSql.Odbc.PostgreSQL { @@ -49,14 +50,11 @@ namespace FreeSql.Odbc.PostgreSQL public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcPostgreSQLProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~OdbcPostgreSQLProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index a13e4e67..8af1881a 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -2,6 +2,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; +using System.Threading; namespace FreeSql.Odbc.SqlServer { @@ -57,14 +58,11 @@ namespace FreeSql.Odbc.SqlServer public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcSqlServerProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~OdbcSqlServerProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index 6f938cf6..dfed6ce9 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -4,6 +4,7 @@ using FreeSql.Oracle.Curd; using System; using System.Collections.Generic; using System.Data.Common; +using System.Threading; namespace FreeSql.Oracle { @@ -47,14 +48,11 @@ namespace FreeSql.Oracle public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OracleProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~OracleProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index 50f25473..550e9284 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -11,6 +11,7 @@ using System.Data.Common; using System.Linq.Expressions; using System.Net; using System.Net.NetworkInformation; +using System.Threading; namespace FreeSql.PostgreSQL { @@ -100,14 +101,11 @@ namespace FreeSql.PostgreSQL public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~PostgreSQLProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~PostgreSQLProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index b9de151e..d5d87938 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using FreeSql.SqlServer.Curd; using System; using System.Collections.Generic; +using System.Threading; namespace FreeSql.SqlServer { @@ -58,14 +59,11 @@ namespace FreeSql.SqlServer public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~SqlServerProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~SqlServerProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 9a8b665d..5c17d9f9 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -4,6 +4,7 @@ using FreeSql.Sqlite.Curd; using System; using System.Collections.Generic; using System.Data.Common; +using System.Threading; namespace FreeSql.Sqlite { @@ -46,14 +47,11 @@ namespace FreeSql.Sqlite public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~SqliteProvider() - { - this.Dispose(); - } - bool _isdisposed = false; + ~SqliteProvider() => this.Dispose(); + int _disposeCounter; public void Dispose() { - if (_isdisposed) return; + if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); } } From 17241be66d2d754c483c85a3b491ca6458f3af55 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 15 Nov 2019 16:36:34 +0800 Subject: [PATCH 0242/1029] debug UnitOfWork Destructor #131 --- FreeSql.DbContext/DbContext/DbContext.cs | 2 +- .../CommonProvider/AdoProvider/AdoProviderTransaction.cs | 7 ++++--- FreeSql/Internal/CommonProvider/CodeFirstProvider.cs | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index f2913f53..88ef9f85 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -221,7 +221,7 @@ namespace FreeSql AllSets.Clear(); if (_isUseUnitOfWork) - UnitOfWork?.Rollback(); + UnitOfWork?.Dispose(); } finally { diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index a2b807dd..8ed0c1e2 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -1,6 +1,7 @@ using SafeObjectPool; using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Data.Common; using System.Diagnostics; using System.Linq; @@ -27,7 +28,7 @@ namespace FreeSql.Internal.CommonProvider } } - private Dictionary _trans = new Dictionary(); + private ConcurrentDictionary _trans = new ConcurrentDictionary(); private object _trans_lock = new object(); public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null; @@ -54,7 +55,7 @@ namespace FreeSql.Internal.CommonProvider if (_trans.ContainsKey(tid)) CommitTransaction(); lock (_trans_lock) - _trans.Add(tid, tran); + _trans.TryAdd(tid, tran); } private void AutoCommitTransaction() @@ -74,7 +75,7 @@ namespace FreeSql.Internal.CommonProvider if (_trans.ContainsKey(tran.Conn.LastGetThreadId)) lock (_trans_lock) if (_trans.ContainsKey(tran.Conn.LastGetThreadId)) - _trans.Remove(tran.Conn.LastGetThreadId); + _trans.TryRemove(tran.Conn.LastGetThreadId, out var oldtran); Exception ex = null; var f001 = isCommit ? "提交" : "回滚"; diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 1f00f176..3ecb796a 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -58,13 +58,13 @@ namespace FreeSql.Internal.CommonProvider static object syncStructureLock = new object(); object _dicSycedLock = new object(); - Dictionary> _dicSynced = new Dictionary>(); + ConcurrentDictionary> _dicSynced = new ConcurrentDictionary>(); internal ConcurrentDictionary _dicSycedGetOrAdd(Type entityType) { if (_dicSynced.TryGetValue(entityType, out var trydic) == false) lock (_dicSycedLock) if (_dicSynced.TryGetValue(entityType, out trydic) == false) - _dicSynced.Add(entityType, trydic = new ConcurrentDictionary()); + _dicSynced.TryAdd(entityType, trydic = new ConcurrentDictionary()); return trydic; } internal void _dicSycedTryAdd(Type entityType, string tableName = null) => From 9f7d8cbdc9af405e0d4b44b7569841d6de9b1cd3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 15 Nov 2019 16:57:00 +0800 Subject: [PATCH 0243/1029] ## v0.11.13 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6536f0fa..ce444eb4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.12 + 0.11.13 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 4c1c81c8..291d04e9 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0f75be11..cc7cad52 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d0e5a060..266c4fc8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 850b2c54..32abbca2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.12 + 0.11.13 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 6c31ed45..dbf67b28 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e43f1ad5..4c780858 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4ed2dd82..86127e58 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0f1128d4..ae4b7700 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7b44f7af..a26cdfd6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f0b6e44e..f2f75fd0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 8de8fe6a..c03ef1e7 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f8b2dbc4..fc07e7f9 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.12 + 0.11.13 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 6c1d532d096b07d079e0fdae4065731917c234f3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 16 Nov 2019 00:10:04 +0800 Subject: [PATCH 0244/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ManyToMany?= =?UTF-8?q?=20=E4=B8=AD=E9=97=B4=E8=A1=A8=E4=B8=8D=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E6=8C=87=E6=98=8E=20[Column(IsPrimary=20=3D=20true)]=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/UtilsExpressionTree.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index a86fd69f..0b999a83 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -547,7 +547,9 @@ namespace FreeSql.Internal nvref.MiddleColumns.AddRange(trytbTf.Columns); if (tbmid.Primarys.Any() == false) - trytbTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true); + foreach (var c in trytbTf.Columns) + tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true; + if (isLazy) { for (var a = 0; a < trytbTf.RefColumns.Count; a++) @@ -592,7 +594,8 @@ namespace FreeSql.Internal nvref.MiddleColumns.AddRange(tbrefTf.Columns); if (tbmid.Primarys.Any() == false) - tbrefTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true); + foreach (var c in tbrefTf.Columns) + tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true; if (isLazy) { From 0f7dd75e64f848d89cdf57bcfbfc1b17a8c67232 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 16 Nov 2019 00:16:18 +0800 Subject: [PATCH 0245/1029] ## v0.11.15 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index ce444eb4..4f291843 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.13 + 0.11.15 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 291d04e9..6cd441c3 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index cc7cad52..d698b807 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 266c4fc8..21d73394 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3f9fb047..2711e35d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,6 +99,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 32abbca2..3fad19f2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.13 + 0.11.15 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index dbf67b28..dda9a6ec 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 4c780858..5b0a0140 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 86127e58..0453986f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index ae4b7700..d7c8f0af 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a26cdfd6..6f219ea5 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f2f75fd0..fa974946 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c03ef1e7..b91d7974 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fc07e7f9..2c9482d6 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.13 + 0.11.15 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From e26dbfe5262adbc2b92ecdb04cee8ed41428bc21 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 16 Nov 2019 01:47:04 +0800 Subject: [PATCH 0246/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20DbContext?= =?UTF-8?q?=E3=80=81Repository=20SaveManyToMany=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E6=89=8B=E5=B7=A5=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=20ManyToMany=20=E5=85=B3=E8=81=94=E6=95=B0=E6=8D=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 8 +++ FreeSql.DbContext/DbSet/DbSetAsync.cs | 48 +++++++++++----- FreeSql.DbContext/DbSet/DbSetSync.cs | 56 ++++++++++++++----- FreeSql.DbContext/FreeSql.DbContext.xml | 31 +++++++--- .../Repository/Repository/BaseRepository.cs | 6 ++ .../Repository/BaseRepositoryAsync.cs | 10 +++- .../Repository/Repository/IBasicRepository.cs | 7 +++ .../RepositoryTests.cs | 2 + 8 files changed, 129 insertions(+), 39 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 88ef9f85..539f5183 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -136,6 +136,13 @@ namespace FreeSql /// public void AddOrUpdate(TEntity data) where TEntity : class => this.Set().AddOrUpdate(data); + /// + /// 保存实体的指定 ManyToMany 导航属性 + /// + /// 实体对象 + /// 属性名 + public void SaveManyToMany(TEntity data, string propertyName) where TEntity : class => this.Set().SaveManyToMany(data, propertyName); + /// /// 附加实体,可用于不查询就更新或删除 /// @@ -163,6 +170,7 @@ namespace FreeSql public Task UpdateRangeAsync(IEnumerable data) where TEntity : class => this.Set().UpdateRangeAsync(data); public Task AddOrUpdateAsync(TEntity data) where TEntity : class => this.Set().AddOrUpdateAsync(data); + public Task SaveManyToManyAsync(TEntity data, string propertyName) where TEntity : class => this.Set().SaveManyToManyAsync(data, propertyName); #endif #endregion diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index de28479d..0adf77f3 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -132,44 +132,58 @@ namespace FreeSql await AddOrUpdateNavigateListAsync(item, true); } } - async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd) + + async public Task SaveManyToManyAsync(TEntity item, string propertyName) + { + if (item == null) return; + if (_table.Properties.ContainsKey(propertyName) == false) throw new KeyNotFoundException($"{_table.Type.FullName} 不存在属性 {propertyName}"); + if (_table.ColumnsByCsIgnore.ContainsKey(propertyName)) throw new ArgumentException($"{_table.Type.FullName} 类型已设置属性 {propertyName} 忽略特性"); + var tref = _table.GetTableRef(propertyName, true); + if (tref.RefType != Internal.Model.TableRefType.ManyToMany) throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 ManyToMany 特性"); + DbContextExecCommand(); + var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; + _db.Options.EnableAddOrUpdateNavigateList = false; + await AddOrUpdateNavigateListAsync(item, false, propertyName); + _db.Options.EnableAddOrUpdateNavigateList = oldEnable; + } + async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd, string propertyName = null) { Type itemType = null; - foreach (var prop in _table.Properties) + Func action = async prop => { - if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; - if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; + if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) return; + if (_table.ColumnsByCs.ContainsKey(prop.Name)) return; - var tref = _table.GetTableRef(prop.Key, true); - if (tref == null) continue; + var tref = _table.GetTableRef(prop.Name, true); + if (tref == null) return; switch (tref.RefType) { case Internal.Model.TableRefType.OneToOne: case Internal.Model.TableRefType.ManyToOne: - continue; + return; } object propVal = null; if (itemType == null) itemType = item.GetType(); if (_table.TypeLazy != null && itemType == _table.TypeLazy) { - var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => + var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Name, propName => _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); if (lazyField != null) { var lazyFieldValue = (bool)lazyField.GetValue(item); - if (lazyFieldValue == false) continue; + if (lazyFieldValue == false) return; } - propVal = prop.Value.GetValue(item); + propVal = prop.GetValue(item); } else { - propVal = prop.Value.GetValue(item); - if (propVal == null) continue; + propVal = prop.GetValue(item); + if (propVal == null) return; } var propValEach = propVal as IEnumerable; - if (propValEach == null) continue; + if (propValEach == null) return; DbSet refSet = GetDbSetObject(tref.RefEntityType); switch (tref.RefType) { @@ -276,7 +290,13 @@ namespace FreeSql } break; } - } + }; + + if (string.IsNullOrEmpty(propertyName)) + foreach (var prop in _table.Properties) + await action(prop.Value); + else if (_table.Properties.TryGetValue(propertyName, out var prop)) + await action(prop); } #endregion diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 52068519..5be76522 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -135,50 +135,70 @@ namespace FreeSql AddOrUpdateNavigateList(item, true); } } + static ConcurrentDictionary> _dicLazyIsSetField = new ConcurrentDictionary>(); /// + /// 保存实体的指定 ManyToMany 导航属性 + /// + /// 实体对象 + /// 属性名 + public void SaveManyToMany(TEntity item, string propertyName) + { + if (item == null) return; + if (_table.Properties.ContainsKey(propertyName) == false) throw new KeyNotFoundException($"{_table.Type.FullName} 不存在属性 {propertyName}"); + if (_table.ColumnsByCsIgnore.ContainsKey(propertyName)) throw new ArgumentException($"{_table.Type.FullName} 类型已设置属性 {propertyName} 忽略特性"); + var tref = _table.GetTableRef(propertyName, true); + if (tref.RefType != Internal.Model.TableRefType.ManyToMany) throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 ManyToMany 特性"); + DbContextExecCommand(); + var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; + _db.Options.EnableAddOrUpdateNavigateList = false; + AddOrUpdateNavigateList(item, false, propertyName); + _db.Options.EnableAddOrUpdateNavigateList = oldEnable; + } + /// /// 联级保存导航集合 /// /// 实体对象 /// 是否为新增的实体对象 - void AddOrUpdateNavigateList(TEntity item, bool isAdd) + /// 指定保存的属性 + void AddOrUpdateNavigateList(TEntity item, bool isAdd, string propertyName = null) { Type itemType = null; - foreach (var prop in _table.Properties) + Action action = prop => { - if (_table.ColumnsByCsIgnore.ContainsKey(prop.Key)) continue; - if (_table.ColumnsByCs.ContainsKey(prop.Key)) continue; + if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) return; + if (_table.ColumnsByCs.ContainsKey(prop.Name)) return; - var tref = _table.GetTableRef(prop.Key, true); - if (tref == null) continue; + var tref = _table.GetTableRef(prop.Name, true); + if (tref == null) return; switch (tref.RefType) { case Internal.Model.TableRefType.OneToOne: case Internal.Model.TableRefType.ManyToOne: - continue; + return; } object propVal = null; if (itemType == null) itemType = item.GetType(); if (_table.TypeLazy != null && itemType == _table.TypeLazy) { - var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Key, propName => + var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Name, propName => _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); if (lazyField != null) { var lazyFieldValue = (bool)lazyField.GetValue(item); - if (lazyFieldValue == false) continue; + if (lazyFieldValue == false) return; } - propVal = prop.Value.GetValue(item, null); + propVal = prop.GetValue(item, null); } else { - propVal = prop.Value.GetValue(item, null); - if (propVal == null) continue; + propVal = prop.GetValue(item, null); + if (propVal == null) return; } var propValEach = propVal as IEnumerable; - if (propValEach == null) continue; + if (propValEach == null) return; DbSet refSet = GetDbSetObject(tref.RefEntityType); switch (tref.RefType) { @@ -230,7 +250,7 @@ namespace FreeSql foreach (var midItem in midList) { var curContains = new List(); - for(var curIdx = 0; curIdx < curList.Count; curIdx ++) + for (var curIdx = 0; curIdx < curList.Count; curIdx++) { var isEquals = true; for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) @@ -285,7 +305,13 @@ namespace FreeSql } break; } - } + }; + + if (string.IsNullOrEmpty(propertyName)) + foreach (var prop in _table.Properties) + action(prop.Value); + else if (_table.Properties.TryGetValue(propertyName, out var prop)) + action(prop); } #endregion diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..9c0597d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -32,6 +32,13 @@ + + + 保存实体的指定 ManyToMany 导航属性 + + 实体对象 + 属性名 + 附加实体,可用于不查询就更新或删除 @@ -99,25 +106,26 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 - + + + 保存实体的指定 ManyToMany 导航属性 + + 实体对象 + 属性名 + + 联级保存导航集合 实体对象 是否为新增的实体对象 + 指定保存的属性 @@ -225,6 +233,13 @@ + + + 保存实体的指定 ManyToMany 导航属性 + + 实体对象 + 属性名 + 是否启用工作单元 diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 80145899..38dd740b 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -129,6 +129,12 @@ namespace FreeSql _db.SaveChanges(); return entity; } + + public void SaveManyToMany(TEntity entity, string propertyName) + { + _dbset.SaveManyToMany(entity, propertyName); + _db.SaveChanges(); + } } public abstract partial class BaseRepository : BaseRepository, IBaseRepository diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs index 0cfcba4d..f848f89d 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs @@ -36,7 +36,7 @@ namespace FreeSql async public virtual Task InsertAsync(TEntity entity) { await _dbset.AddAsync(entity); - _db.SaveChanges(); + await _db.SaveChangesAsync(); return entity; } async public virtual Task> InsertAsync(IEnumerable entitys) @@ -60,9 +60,15 @@ namespace FreeSql async public Task InsertOrUpdateAsync(TEntity entity) { await _dbset.AddOrUpdateAsync(entity); - _db.SaveChanges(); + await _db.SaveChangesAsync(); return entity; } + + async public Task SaveManyToManyAsync(TEntity entity, string propertyName) + { + await _dbset.SaveManyToManyAsync(entity, propertyName); + await _db.SaveChangesAsync(); + } } partial class BaseRepository diff --git a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs index 6c56cd5c..24f7291c 100644 --- a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs @@ -29,6 +29,12 @@ namespace FreeSql int Update(IEnumerable entitys); TEntity InsertOrUpdate(TEntity entity); + /// + /// 保存实体的指定 ManyToMany 导航属性 + /// + /// 实体对象 + /// 属性名 + void SaveManyToMany(TEntity entity, string propertyName); IUpdate UpdateDiy { get; } @@ -43,6 +49,7 @@ namespace FreeSql Task UpdateAsync(TEntity entity); Task UpdateAsync(IEnumerable entitys); Task InsertOrUpdateAsync(TEntity entity); + Task SaveManyToManyAsync(TEntity entity, string propertyName); Task DeleteAsync(TEntity entity); Task DeleteAsync(IEnumerable entitys); diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index c16fda68..4fa4fbe5 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -415,7 +415,9 @@ namespace FreeSql.Tests } }; var repo = g.sqlite.GetRepository(); + //repo.DbContextOptions.EnableAddOrUpdateNavigateList = false; //ر湦 repo.Insert(ss); + repo.SaveManyToMany(ss[0], "Tags"); //ָ Tags Զ ss[0].Name = "һ.mp5"; ss[0].Tags.Clear(); From 330eb4028585e9d4e55d1e1424ee0b1e7fa69f7b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 16 Nov 2019 04:13:07 +0800 Subject: [PATCH 0247/1029] ## v0.11.18 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/DbContext/DbContext.cs | 68 +++++++-- FreeSql.DbContext/DbSet/DbSet.cs | 9 ++ FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 131 ------------------ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 86 insertions(+), 155 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 4f291843..d45b911c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.15 + 0.11.18 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 6cd441c3..d29b40e0 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index d698b807..4a5645aa 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 539f5183..7db324cf 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -92,6 +92,7 @@ namespace FreeSql protected List _listSet = new List(); protected Dictionary _dicSet = new Dictionary(); + internal Dictionary InternalDicSet => _dicSet; public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; public virtual IDbSet Set(Type entityType) { @@ -105,12 +106,21 @@ namespace FreeSql #endregion #region DbSet 快速代理 + void CheckEntityTypeOrThrow(Type entityType) + { + if (Orm.CodeFirst.GetTableByEntity(entityType) == null) + throw new ArgumentException($"参数 data 类型错误 {entityType.FullName} "); + } /// /// 添加 /// /// /// - public void Add(TEntity data) where TEntity : class => this.Set().Add(data); + public void Add(TEntity data) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + this.Set().Add(data); + } public void AddRange(IEnumerable data) where TEntity : class => this.Set().AddRange(data); /// @@ -118,7 +128,11 @@ namespace FreeSql /// /// /// - public void Update(TEntity data) where TEntity : class => this.Set().Update(data); + public void Update(TEntity data) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + this.Set().Update(data); + } public void UpdateRange(IEnumerable data) where TEntity : class => this.Set().UpdateRange(data); /// @@ -126,7 +140,11 @@ namespace FreeSql /// /// /// - public void Remove(TEntity data) where TEntity : class => this.Set().Remove(data); + public void Remove(TEntity data) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + this.Set().Remove(data); + } public void RemoveRange(IEnumerable data) where TEntity : class => this.Set().RemoveRange(data); /// @@ -134,21 +152,32 @@ namespace FreeSql /// /// /// - public void AddOrUpdate(TEntity data) where TEntity : class => this.Set().AddOrUpdate(data); - + public void AddOrUpdate(TEntity data) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + this.Set().AddOrUpdate(data); + } /// /// 保存实体的指定 ManyToMany 导航属性 /// /// 实体对象 /// 属性名 - public void SaveManyToMany(TEntity data, string propertyName) where TEntity : class => this.Set().SaveManyToMany(data, propertyName); + public void SaveManyToMany(TEntity data, string propertyName) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + this.Set().SaveManyToMany(data, propertyName); + } /// /// 附加实体,可用于不查询就更新或删除 /// /// /// - public void Attach(TEntity data) where TEntity : class => this.Set().Attach(data); + public void Attach(TEntity data) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + this.Set().Attach(data); + } public void AttachRange(IEnumerable data) where TEntity : class => this.Set().AttachRange(data); /// @@ -158,19 +187,36 @@ namespace FreeSql /// public DbContext AttachOnlyPrimary(TEntity data) where TEntity : class { + CheckEntityTypeOrThrow(typeof(TEntity)); this.Set().AttachOnlyPrimary(data); return this; } #if net40 #else - public Task AddAsync(TEntity data) where TEntity : class => this.Set().AddAsync(data); + public Task AddAsync(TEntity data) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + return this.Set().AddAsync(data); + } public Task AddRangeAsync(IEnumerable data) where TEntity : class => this.Set().AddRangeAsync(data); - public Task UpdateAsync(TEntity data) where TEntity : class => this.Set().UpdateAsync(data); + public Task UpdateAsync(TEntity data) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + return this.Set().UpdateAsync(data); + } public Task UpdateRangeAsync(IEnumerable data) where TEntity : class => this.Set().UpdateRangeAsync(data); - public Task AddOrUpdateAsync(TEntity data) where TEntity : class => this.Set().AddOrUpdateAsync(data); - public Task SaveManyToManyAsync(TEntity data, string propertyName) where TEntity : class => this.Set().SaveManyToManyAsync(data, propertyName); + public Task AddOrUpdateAsync(TEntity data) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + return this.Set().AddOrUpdateAsync(data); + } + public Task SaveManyToManyAsync(TEntity data, string propertyName) where TEntity : class + { + CheckEntityTypeOrThrow(typeof(TEntity)); + return this.Set().SaveManyToManyAsync(data, propertyName); + } #endif #endregion diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index fc31b1a8..e0728bef 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -133,8 +133,17 @@ namespace FreeSql { if (_dicDbSetObjects.TryGetValue(et, out var tryds)) return tryds; _dicDbSetObjects.Add(et, tryds = _db.Set().AsType(et)); + if (_db.InternalDicSet.TryGetValue(et, out var tryds2)) + { + var copyTo = typeof(DbSet<>).MakeGenericType(et).GetMethod("StatesCopyToDbSetObject", BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(DbSet) }, null); + copyTo?.Invoke(tryds2, new object[] { tryds }); + } return tryds; } + void StatesCopyToDbSetObject(DbSet ds) + { + ds.AttachRange(_states.Values.OrderBy(a => a.Time).Select(a => a.Value).ToArray()); + } public class EntityState { diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 21d73394..58aecfbe 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c0597d5..1a43f59e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -106,6 +106,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3fad19f2..858e358e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.15 + 0.11.18 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index dda9a6ec..28038e50 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 185896b3..e436e1d8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1996,137 +1996,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5b0a0140..3c4a8c90 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0453986f..da040f8c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d7c8f0af..f20e42f9 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6f219ea5..99dcb2cc 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index fa974946..9dc1a9e8 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b91d7974..5e10e7d9 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 2c9482d6..5eb15ef6 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.15 + 0.11.18 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 7c42c6779750d69cfe1ca9d74c7b23eb79d1b948 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 17 Nov 2019 17:14:00 +0800 Subject: [PATCH 0248/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20MapType=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E7=9A=84=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=20=E6=95=B0=E7=BB=84.Contains=20=E5=BE=97=E5=88=B0?= =?UTF-8?q?=E6=98=AF=E6=98=A0=E5=B0=84=E4=B9=8B=E5=89=8D=E7=9A=84=E5=80=BC?= =?UTF-8?q?=20bug=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20MapType=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=20=E4=B8=8E=20IncludeMany=20=E5=8F=98=E5=BC=82?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=9C=AA=E6=98=A0=E5=B0=84=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 + FreeSql/FreeSql.xml | 131 ++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 23 ++- .../SelectProvider/Select1Provider.cs | 6 +- .../MySqlAdo/MySqlAdo.cs | 2 +- .../FreeSql.Provider.MySql/MySqlExpression.cs | 8 +- .../Default/OdbcAdo/OdbcAdo.cs | 2 +- .../Default/OdbcExpression.cs | 8 +- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 2 +- .../MySql/OdbcMySqlExpression.cs | 8 +- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 2 +- .../Oracle/OdbcOracleExpression.cs | 8 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 26 ++-- .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 2 +- .../SqlServer/OdbcSqlServerExpression.cs | 8 +- .../OracleAdo/OracleAdo.cs | 2 +- .../OracleExpression.cs | 8 +- .../PostgreSQLAdo/PostgreSQLAdo.cs | 4 +- .../PostgreSQLExpression.cs | 29 ++-- .../SqlServerAdo/SqlServerAdo.cs | 2 +- .../SqlServerExpression.cs | 8 +- .../SqliteAdo/SqliteAdo.cs | 2 +- .../SqliteExpression.cs | 8 +- 24 files changed, 249 insertions(+), 54 deletions(-) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index f6d27fac..340f6565 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -1,5 +1,6 @@ using FreeSql; using System; +using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; @@ -40,6 +41,7 @@ public static partial class FreeSqlGlobalExtensions public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that); public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true; public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; + public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that)); public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that; internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args)); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e436e1d8..185896b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1996,6 +1996,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 }) + + + + + + 可自定义解析表达式 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 11cf1b65..85720257 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -932,12 +932,12 @@ namespace FreeSql.Internal throw new ArgumentException($"{tb.DbName}.{memberExp.Member.Name} 被忽略,请检查 IsIgnore 设置,确认 get/set 为 public"); throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}"); } + var curcol = tb.ColumnsByCs[memberExp.Member.Name]; if (tsc._selectColumnMap != null) - { - tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = tb.ColumnsByCs[memberExp.Member.Name] }); - } - var name = tb.ColumnsByCs[memberExp.Member.Name].Attribute.Name; + tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = curcol }); + var name = curcol.Attribute.Name; if (tsc.isQuoteName) name = _common.QuoteSqlName(name); + tsc.mapTypeTmp = curcol.Attribute.MapType == curcol.CsType ? null : curcol.Attribute.MapType; if (string.IsNullOrEmpty(tsc.alias001)) return name; return $"{tsc.alias001}.{name}"; } @@ -1098,7 +1098,8 @@ namespace FreeSql.Internal tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 }); return ""; } - name2 = tb2.ColumnsByCs[mp2.Member.Name].Attribute.Name; + name2 = col2.Attribute.Name; + tsc.mapTypeTmp = col2.Attribute.MapType == col2.CsType ? null : col2.Attribute.MapType; break; case ExpressionType.Call: break; } @@ -1150,10 +1151,22 @@ namespace FreeSql.Internal public bool isDisableDiyParse { get; set; } public ExpressionStyle style { get; set; } public Type mapType { get; set; } + public Type mapTypeTmp { get; set; } public TableInfo currentTable { get; set; } public List whereCascadeExpression { get; set; } public string alias001 { get; set; } //单表字段的表别名 + public void SetMapTypeTmp(Type newValue) + { + this.mapTypeTmp = null; + } + public Type SetMapTypeReturnOld(Type newValue) + { + var old = this.mapType; + this.mapType = newValue; + return old; + } + public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List v1, Func v2, SelectTableInfoType v3) { return new ExpTSC diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 96bee31f..a4e8d8f7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -605,7 +605,7 @@ namespace FreeSql.Internal.CommonProvider for (var z = 0; z < tbref.Columns.Count; z++) { if (z > 0) sbWhereOne.Append(" AND "); - sbWhereOne.Append(_commonUtils.FormatSql($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}={{0}}", getListValue(list[y], tbref.Columns[z].CsName, z))); + sbWhereOne.Append(_commonUtils.FormatSql($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}={{0}}", Utils.GetDataReaderValue(tbref.RefColumns[z].Attribute.MapType, getListValue(list[y], tbref.Columns[z].CsName, z)))); } sbWhereOne.Append(")"); var whereOne = sbWhereOne.ToString(); @@ -797,7 +797,7 @@ namespace FreeSql.Internal.CommonProvider for (var z = 0; z < tbref.Columns.Count; z++) { if (z > 0) sbWhereOne.Append(" AND "); - sbWhereOne.Append(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", getListValue1(list[y], tbref.Columns[z].CsName))); + sbWhereOne.Append(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", Utils.GetDataReaderValue(tbref.MiddleColumns[z].Attribute.MapType, getListValue1(list[y], tbref.Columns[z].CsName)))); } sbWhereOne.Append(")"); var whereOne = sbWhereOne.ToString(); @@ -825,7 +825,7 @@ namespace FreeSql.Internal.CommonProvider subSelect._where.Clear(); if (tbref.Columns.Count == 1) { - subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue1(a, tbref.Columns[0].CsName)).Distinct())); + subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => Utils.GetDataReaderValue(tbref.MiddleColumns[0].Attribute.MapType, getListValue1(a, tbref.Columns[0].CsName))).Distinct())); } else { diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index 3e0154ac..e061fe23 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -31,7 +31,7 @@ namespace FreeSql.MySql public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index e91917f3..b795dbaf 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -99,14 +99,18 @@ namespace FreeSql.MySql argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + return $"({args1}) in {left}"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index a2fa7646..b42c5b48 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.Default public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs index 50262556..574455f7 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -106,14 +106,18 @@ namespace FreeSql.Odbc.Default argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + return $"({args1}) in {left}"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index b6ee5b3c..0cd07d54 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -31,7 +31,7 @@ namespace FreeSql.Odbc.MySql public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index ca13a287..2bcd91b2 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -99,14 +99,18 @@ namespace FreeSql.Odbc.MySql argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + return $"({args1}) in {left}"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index b9b4d6f9..1bb9cfe0 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -30,7 +30,7 @@ namespace FreeSql.Odbc.Oracle public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index cd598adc..1c9f08e4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -99,14 +99,18 @@ namespace FreeSql.Odbc.Oracle argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + return $"({args1}) in {left}"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index 3bef8669..0d7027a6 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.PostgreSQL public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 449c1a52..cc7839cb 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -103,11 +103,12 @@ namespace FreeSql.Odbc.PostgreSQL argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { - var left = objExp == null ? null : getExp(objExp); + string left = null; if (objType.FullName == typeof(Dictionary).FullName) { + left = objExp == null ? null : getExp(objExp); switch (callExp.Method.Name) { case "Contains": @@ -125,24 +126,30 @@ namespace FreeSql.Odbc.PostgreSQL switch (callExp.Method.Name) { case "Any": + left = objExp == null ? null : getExp(objExp); if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; case "Contains": + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); //判断 in 或 array @> array - var right1 = getExp(callExp.Arguments[argIndex]); if (left.StartsWith("array[") || left.EndsWith("]")) - return $"{right1} in ({left.Substring(6, left.Length - 7)})"; + return $"{args1} in ({left.Substring(6, left.Length - 7)})"; if (left.StartsWith("(") || left.EndsWith(")")) - return $"{right1} in {left}"; - if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; - right1 = $"array[{right1}]"; + return $"{args1} in {left}"; + if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + args1 = $"array[{args1}]"; if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); - if (dbinfo.HasValue) right1 = $"{right1}::{dbinfo.Value.dbtype}"; + if (dbinfo.HasValue) args1 = $"{args1}::{dbinfo.Value.dbtype}"; } - return $"({left} @> {right1})"; + return $"({left} @> {args1})"; case "Concat": + left = objExp == null ? null : getExp(objExp); if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; var right2 = getExp(callExp.Arguments[argIndex]); if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; @@ -151,6 +158,7 @@ namespace FreeSql.Odbc.PostgreSQL case "GetLongLength": case "Length": case "Count": + left = objExp == null ? null : getExp(objExp); if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; return $"case when {left} is null then 0 else array_length({left},1) end"; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index 360c7b47..3920f4b6 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -30,7 +30,7 @@ namespace FreeSql.Odbc.SqlServer public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index f96d7c83..74a752c9 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -103,14 +103,18 @@ namespace FreeSql.Odbc.SqlServer argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + return $"({args1}) in {left}"; } } break; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index dc0c4790..8c45bb19 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -30,7 +30,7 @@ namespace FreeSql.Oracle public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 80016c64..a5f35911 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -99,14 +99,18 @@ namespace FreeSql.Oracle argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + return $"({args1}) in {left}"; } } break; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index 0c3b492e..eee3e5c9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -33,9 +33,9 @@ namespace FreeSql.PostgreSQL public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList() || param is JToken || param is JObject || param is JArray)) param = Utils.GetDataReaderValue(mapType, param); - bool isdic = false; + bool isdic; if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; else if (param is string || param is char) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 6c203306..4507cebe 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -104,14 +104,15 @@ namespace FreeSql.PostgreSQL argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { - var left = objExp == null ? null : getExp(objExp); + string left = null; switch (objType.FullName) { case "Newtonsoft.Json.Linq.JToken": case "Newtonsoft.Json.Linq.JObject": case "Newtonsoft.Json.Linq.JArray": + left = objExp == null ? null : getExp(objExp); switch (callExp.Method.Name) { case "Any": return $"(jsonb_array_length(coalesce({left},'[]')) > 0)"; @@ -137,6 +138,7 @@ namespace FreeSql.PostgreSQL } if (objType.FullName == typeof(Dictionary).FullName) { + left = objExp == null ? null : getExp(objExp); switch (callExp.Method.Name) { case "Contains": @@ -154,24 +156,30 @@ namespace FreeSql.PostgreSQL switch (callExp.Method.Name) { case "Any": + left = objExp == null ? null : getExp(objExp); if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; case "Contains": + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); //判断 in 或 array @> array - var right1 = getExp(callExp.Arguments[argIndex]); if (left.StartsWith("array[") || left.EndsWith("]")) - return $"{right1} in ({left.Substring(6, left.Length - 7)})"; + return $"{args1} in ({left.Substring(6, left.Length - 7)})"; if (left.StartsWith("(") || left.EndsWith(")")) - return $"{right1} in {left}"; - if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]"; - right1 = $"array[{right1}]"; + return $"{args1} in {left}"; + if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + args1 = $"array[{args1}]"; if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); - if (dbinfo.HasValue) right1 = $"{right1}::{dbinfo.Value.dbtype}"; + if (dbinfo.HasValue) args1 = $"{args1}::{dbinfo.Value.dbtype}"; } - return $"({left} @> {right1})"; + return $"({left} @> {args1})"; case "Concat": + left = objExp == null ? null : getExp(objExp); if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; var right2 = getExp(callExp.Arguments[argIndex]); if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; @@ -180,6 +188,7 @@ namespace FreeSql.PostgreSQL case "GetLongLength": case "Length": case "Count": + left = objExp == null ? null : getExp(objExp); if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; return $"case when {left} is null then 0 else array_length({left},1) end"; } @@ -494,7 +503,7 @@ namespace FreeSql.PostgreSQL case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index adfc89be..c6799a13 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -30,7 +30,7 @@ namespace FreeSql.SqlServer public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 4b0b0bb1..c775851f 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -103,14 +103,18 @@ namespace FreeSql.SqlServer argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + return $"({args1}) in {left}"; } } break; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index d8df365d..9e27fc13 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -29,7 +29,7 @@ namespace FreeSql.Sqlite public override object AddslashesProcessParam(object param, Type mapType) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType()) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? 1 : 0; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 9f451e0b..ce13a196 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -99,14 +99,18 @@ namespace FreeSql.Sqlite argIndex++; } if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) + if (objType != null || objType.IsArrayOrList()) { + tsc?.SetMapTypeTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); + tsc.SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": //判断 in - return $"({getExp(callExp.Arguments[argIndex])}) in {left}"; + return $"({args1}) in {left}"; } } break; From 1cb8bb92f0f6f9585957d3367c6c201a33851ba6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 17 Nov 2019 17:19:10 +0800 Subject: [PATCH 0249/1029] ## v0.11.19 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d45b911c..20bb9925 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.18 + 0.11.19 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index d29b40e0..a4a15414 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 4a5645aa..1d80efb0 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 58aecfbe..3e9fc002 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 858e358e..29654689 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.18 + 0.11.19 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 28038e50..519b4c03 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3c4a8c90..92206e33 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index da040f8c..e9475019 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index f20e42f9..7f4df8c9 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 99dcb2cc..d3fa8302 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 9dc1a9e8..7bc29e34 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5e10e7d9..286d32b7 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5eb15ef6..b17a6833 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.18 + 0.11.19 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 769c1f020cb1c085fa2e44db9320a7fb63186cba Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 17 Nov 2019 21:01:49 +0800 Subject: [PATCH 0250/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Where(a=20?= =?UTF-8?q?=3D>=20bool=20&&=20id=20>=200)=20bool=20=E6=9C=AA=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=AD=A3=E7=A1=AE=E7=9A=84=20bug=EF=BC=9B=20>=20?= =?UTF-8?q?=EF=BC=88=E4=B9=8B=E5=89=8D=E5=A4=A7=E5=A4=9A=E6=95=B0=E7=B1=BB?= =?UTF-8?q?=E4=BC=BC=E7=9A=84=E8=A1=A8=E8=BE=BE=E9=83=BD=E8=83=BD=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E8=BF=99=E6=AC=A1=E6=98=AF=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E6=83=85=E5=86=B5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 --- .../MySqlConnectorExpression/OtherTest.cs | 24 ++++++++++ .../MySql/MySqlExpression/OtherTest.cs | 24 ++++++++++ .../Oracle/OracleExpression/OtherTest.cs | 24 ++++++++++ .../PostgreSQLExpression/OtherTest.cs | 24 ++++++++++ .../SqlServerExpression/OtherTest.cs | 24 ++++++++++ .../MySql/MySqlExpression/OtherTest.cs | 24 ++++++++++ .../Oracle/OracleExpression/OtherTest.cs | 24 ++++++++++ .../PostgreSQLExpression/OtherTest.cs | 44 ++++++++++++++----- .../SqlServerExpression/OtherTest.cs | 24 ++++++++++ .../Sqlite/SqliteExpression/OtherTest.cs | 24 ++++++++++ FreeSql/Internal/CommonExpression.cs | 10 +++-- 12 files changed, 256 insertions(+), 21 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 1a43f59e..9c0597d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -106,13 +106,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs index 361c2c67..37b81c4d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs @@ -47,6 +47,30 @@ namespace FreeSql.Tests.MySqlConnectorExpression var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs index 7d5f4293..794f9e31 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs @@ -47,6 +47,30 @@ namespace FreeSql.Tests.Odbc.MySqlExpression var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs index 3b8ef42d..a3a42d06 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs @@ -45,6 +45,30 @@ namespace FreeSql.Tests.Odbc.OracleExpression var t33 = select.Where(a => a.BoolNullable == false).ToList(); var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs index 39d3a70a..4b9e66f8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -50,6 +50,30 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs index a4e1494e..63646aa8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs @@ -42,6 +42,30 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs index 83c2c2be..db07a187 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs @@ -47,6 +47,30 @@ namespace FreeSql.Tests.MySqlExpression var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs index ed6a76d7..1c7d9048 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs @@ -45,6 +45,30 @@ namespace FreeSql.Tests.OracleExpression var t33 = select.Where(a => a.BoolNullable == false).ToList(); var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index f29fa7d3..950c538c 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -43,17 +43,41 @@ namespace FreeSql.Tests.PostgreSQLExpression [Fact] public void Boolean() { - var t1 = select.Where(a => a.testFieldBool == true).ToList(); - var t2 = select.Where(a => a.testFieldBool != true).ToList(); - var t3 = select.Where(a => a.testFieldBool == false).ToList(); - var t4 = select.Where(a => !a.testFieldBool).ToList(); - var t5 = select.Where(a => a.testFieldBool).ToList(); + var t1 = select.Where(a => a.testFieldBool == true).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).Limit(10).ToList(); + var t4 = select.Where(a => !a.testFieldBool).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldBool).Limit(10).ToList(); - var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); - var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); - var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); - var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); - var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + var t11 = select.Where(a => a.testFieldBoolNullable == true).Limit(10).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).Limit(10).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).Limit(10).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).Limit(10).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).Limit(10).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).Limit(10).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).Limit(10).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).Limit(10).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).Limit(10).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).Limit(10).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).Limit(10).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).Limit(10).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).Limit(10).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).Limit(10).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).Limit(10).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).Limit(10).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).Limit(10).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).Limit(10).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).Limit(10).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).Limit(10).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).Limit(10).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).Limit(10).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).Limit(10).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).Limit(10).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).Limit(10).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs index 53427c37..7a21e3a0 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs @@ -50,6 +50,30 @@ namespace FreeSql.Tests.SqlServerExpression var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs index 3e2c3e53..3276034d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs @@ -45,6 +45,30 @@ namespace FreeSql.Tests.SqliteExpression var t33 = select.Where(a => a.BoolNullable == false).ToList(); var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); } [Fact] diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 85720257..8e9bbe8e 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -420,7 +420,7 @@ namespace FreeSql.Internal var left = ExpressionLambdaToSql(leftExp, tsc); var leftMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, left); - var isLeftMapType = leftMapColumn != null && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type); + var isLeftMapType = leftMapColumn != null && new[] { "AND", "OR" }.Contains(oper) == false && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type); ColumnInfo rightMapColumn = null; var isRightMapType = false; if (isLeftMapType) tsc.mapType = leftMapColumn.Attribute.MapType; @@ -435,7 +435,7 @@ namespace FreeSql.Internal if (leftMapColumn == null) { rightMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, right); - isRightMapType = rightMapColumn != null && (rightMapColumn.Attribute.MapType != leftExp.Type || rightMapColumn.CsType != leftExp.Type); + isRightMapType = rightMapColumn != null && new[] { "AND", "OR" }.Contains(oper) == false && (rightMapColumn.Attribute.MapType != leftExp.Type || rightMapColumn.CsType != leftExp.Type); if (isRightMapType) { tsc.mapType = rightMapColumn.Attribute.MapType; @@ -485,8 +485,10 @@ namespace FreeSql.Internal break; case "AND": case "OR": - left = GetBoolString(left); - right = GetBoolString(right); + if (leftMapColumn != null) left = $"{left} = {formatSql(true, null)}"; + else left = GetBoolString(left); + if (rightMapColumn != null) right = $"{right} = {formatSql(true, null)}"; + else right = GetBoolString(right); break; } tsc.mapType = null; From 1083f371a9e2ccaeeb02ddfaf79afaed83f18b3c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 18 Nov 2019 03:22:34 +0800 Subject: [PATCH 0251/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IncludeMany?= =?UTF-8?q?=20=E8=B4=AA=E5=A9=AA=E5=8A=A0=E8=BD=BD=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E5=80=99=E5=8F=AF=E6=8C=87=E5=AE=9A=E5=AD=90=E8=A1=A8=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=8C=E9=81=BF=E5=85=8D=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=AD=90=E8=A1=A8=E6=89=80=E6=9C=89=E5=AD=97=E6=AE=B5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 216 +++++++++---- .../MySql/Curd/MySqlSelectTest.cs | 191 +++++++++-- .../Oracle/Curd/OracleSelectTest.cs | 184 ++++++++++- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 191 +++++++++-- .../SqlServer/Curd/SqlServerSelectTest.cs | 197 +++++++++--- .../MySql/Curd/MySqlSelectTest.cs | 160 +++++++++- .../Oracle/Curd/OracleSelectTest.cs | 160 +++++++++- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 160 +++++++++- .../SqlServer/Curd/SqlServerSelectTest.cs | 160 +++++++++- .../Sqlite/Curd/SqliteSelectTest.cs | 160 +++++++++- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 9 +- FreeSql/FreeSql.xml | 302 ++++++++++-------- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 6 +- FreeSql/Internal/CommonExpression.cs | 43 +-- .../SelectProvider/Select0Provider.cs | 48 ++- .../SelectProvider/Select1Provider.cs | 55 +++- 16 files changed, 1899 insertions(+), 343 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 03ead48d..4c3e0afa 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -87,16 +87,6 @@ namespace FreeSql.Tests.MySqlConnector public virtual ICollection Tags { get; set; } } - [Table(Name = "TestInfoT1")] - class TestInfo - { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int TypeGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - } [Fact] public void AsSelect() @@ -183,20 +173,10 @@ namespace FreeSql.Tests.MySqlConnector var t0 = select.Limit(50).ToList(); - - var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - - var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); - //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( - // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, - // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") - //); - //var sql4 = select.From((a, b, c) => new SelectFrom() // .InnerJoin(a.TypeGuid == b.Guid) // .LeftJoin(c.Id == b.ParentId) @@ -238,37 +218,6 @@ namespace FreeSql.Tests.MySqlConnector }); var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); - var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); - var t11112 = g.mysql.Select().ToList(a => new - { - a.Id, - a.Title, - a.Type, - ccc = new { a.Id, a.Title }, - tp = a.Type, - tp2 = new - { - a.Id, - tp2 = a.Type.Name - }, - tp3 = new - { - a.Id, - tp33 = new - { - a.Id - } - } - - }); - - var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - - - var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); - - var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); g.mysql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.mysql.Select().ToList(); @@ -784,7 +733,6 @@ namespace FreeSql.Tests.MySqlConnector }); var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); var aggsql1 = select .GroupBy(a => a.Title) @@ -1003,9 +951,9 @@ namespace FreeSql.Tests.MySqlConnector sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); } public class TestInclude_OneToManyModel1 @@ -1100,6 +1048,40 @@ namespace FreeSql.Tests.MySqlConnector then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TestInclude_OneToManyModel11 @@ -1117,6 +1099,8 @@ namespace FreeSql.Tests.MySqlConnector [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TestInclude_OneToManyModel33 @@ -1131,7 +1115,7 @@ namespace FreeSql.Tests.MySqlConnector public void Include_OneToMany2() { string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1156,6 +1140,20 @@ namespace FreeSql.Tests.MySqlConnector .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1253,6 +1251,59 @@ namespace FreeSql.Tests.MySqlConnector .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1357,6 +1408,61 @@ namespace FreeSql.Tests.MySqlConnector .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.mysql, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 6fc08172..b8fca5e8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -425,10 +425,6 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); query.ToList(); - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); - query.ToList(); } [Fact] public void InnerJoin() @@ -494,11 +490,6 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); query.ToList(); - query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); - query.ToList(); - } [Fact] public void RightJoin() @@ -564,11 +555,6 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); query.ToList(); - query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); - query.ToList(); - } [Fact] public void Where() @@ -635,11 +621,6 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); query2.ToList(); - //������϶����㲻�� - query = select.Where("a.clicks > 100 and a.id = ?", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?)", sql); - query.ToList(); } [Fact] public void WhereIf() @@ -683,12 +664,6 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); query2.ToList(); - //������϶����㲻�� - query = select.WhereIf(true, "a.clicks > 100 and a.id = ?", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?)", sql); - query.ToList(); - // ==========================================WhereIf(false) //����е�������a.Type��a.Type.Parent ���ǵ������� @@ -729,12 +704,6 @@ namespace FreeSql.Tests.Odbc.MySql sql = query2.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(false, "a.clicks > 100 and a.id = ?", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); } [Fact] public void WhereExists() @@ -1090,6 +1059,40 @@ namespace FreeSql.Tests.Odbc.MySql then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TestInclude_OneToManyModel11 @@ -1107,6 +1110,8 @@ namespace FreeSql.Tests.Odbc.MySql [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TestInclude_OneToManyModel33 @@ -1121,7 +1126,7 @@ namespace FreeSql.Tests.Odbc.MySql public void Include_OneToMany2() { string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1146,6 +1151,20 @@ namespace FreeSql.Tests.Odbc.MySql .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1243,6 +1262,59 @@ namespace FreeSql.Tests.Odbc.MySql .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1347,6 +1419,61 @@ namespace FreeSql.Tests.Odbc.MySql .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.mysql, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 6894291e..0de86c1f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -136,9 +136,9 @@ namespace FreeSql.Tests.Odbc.Oracle //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); //Assert.Equal(9989, g.oracle.Insert(items).ExecuteAffrows()); - var dt1 = select.Limit(10).ToDataTable(); - var dt2 = select.Limit(10).ToDataTable("id, 111222"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now.ToString() }); + //var dt1 = select.ToDataTable(); + //var dt2 = select.ToDataTable("id, 111222"); + //var dt3 = select.ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); } class TestDto { @@ -380,9 +380,9 @@ namespace FreeSql.Tests.Odbc.Oracle Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); query.ToList(); - query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = ?", new { bname = "xxx" }); + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = ?", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); query.ToList(); } @@ -450,9 +450,9 @@ namespace FreeSql.Tests.Odbc.Oracle Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); query.ToList(); - query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = ?", new { bname = "xxx" }); + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = ?", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); query.ToList(); } @@ -521,9 +521,9 @@ namespace FreeSql.Tests.Odbc.Oracle query2.ToList(); //������϶����㲻�� - query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = ?", new { id = 10 }); + query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = ?)", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); query.ToList(); } [Fact] @@ -569,9 +569,9 @@ namespace FreeSql.Tests.Odbc.Oracle query2.ToList(); //������϶����㲻�� - query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = ?", new { id = 10 }); + query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = ?)", sql); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); query.ToList(); // ==========================================WhereIf(false) @@ -616,7 +616,7 @@ namespace FreeSql.Tests.Odbc.Oracle query2.ToList(); //������϶����㲻�� - query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = ?", new { id = 10 }); + query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); query.ToList(); @@ -975,6 +975,40 @@ namespace FreeSql.Tests.Odbc.Oracle then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.oracle.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.oracle.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TiOtmModel11 @@ -992,6 +1026,8 @@ namespace FreeSql.Tests.Odbc.Oracle [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TiOtmModel33 @@ -1006,7 +1042,7 @@ namespace FreeSql.Tests.Odbc.Oracle public void Include_OneToMany2() { string setting = "x"; - var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.oracle.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1031,6 +1067,20 @@ namespace FreeSql.Tests.Odbc.Oracle .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1128,6 +1178,59 @@ namespace FreeSql.Tests.Odbc.Oracle .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.oracle.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1232,6 +1335,61 @@ namespace FreeSql.Tests.Odbc.Oracle .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.oracle, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 385cdef5..639a59c5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -389,11 +389,6 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); query.ToList(); - - query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", sql); - query.ToList(); } [Fact] public void InnerJoin() @@ -458,12 +453,6 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); query.ToList(); - - query = select.InnerJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", sql); - query.ToList(); - } [Fact] public void RightJoin() @@ -528,12 +517,6 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); query.ToList(); - - query = select.RightJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", sql); - query.ToList(); - } [Fact] public void Where() @@ -600,9 +583,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL query2.ToList(); //������϶����㲻�� - query = select.Where("a.\"clicks\" > 100 and a.\"id\" = ?", new { id = 10 }); + query = select.Where("a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = ?)", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = @id)", sql); query.ToList(); } [Fact] @@ -648,9 +631,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL query2.ToList(); //������϶����㲻�� - query = select.WhereIf(true, "a.\"clicks\" > 100 and a.\"id\" = ?", new { id = 10 }); + query = select.WhereIf(true, "a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = ?)", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = @id)", sql); query.ToList(); // ==========================================WhereIf(false) @@ -695,7 +678,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL query2.ToList(); //������϶����㲻�� - query = select.WhereIf(false, "a.\"clicks\" > 100 and a.\"id\" = ?", new { id = 10 }); + query = select.WhereIf(false, "a.\"clicks\" > 100 and a.\"id\" = @id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); query.ToList(); @@ -951,9 +934,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); - query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", new { bname = "xxx" }).AsTable(tableRule); + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = ?", sql); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); } public class TestInclude_OneToManyModel1 @@ -1048,6 +1031,40 @@ namespace FreeSql.Tests.Odbc.PostgreSQL then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.pgsql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.pgsql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TestInclude_OneToManyModel11 @@ -1065,6 +1082,8 @@ namespace FreeSql.Tests.Odbc.PostgreSQL [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TestInclude_OneToManyModel33 @@ -1079,7 +1098,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public void Include_OneToMany2() { string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.pgsql.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1104,6 +1123,20 @@ namespace FreeSql.Tests.Odbc.PostgreSQL .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1201,6 +1234,59 @@ namespace FreeSql.Tests.Odbc.PostgreSQL .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.pgsql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1305,6 +1391,61 @@ namespace FreeSql.Tests.Odbc.PostgreSQL .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.pgsql, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 80be8d34..0174b4aa 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -6,7 +6,6 @@ using Xunit; namespace FreeSql.Tests.Odbc.SqlServer { - [Collection("SqlServerCollection")] public class SqlServerSelectTest { ISelect select => g.sqlserver.Select(); @@ -141,7 +140,6 @@ namespace FreeSql.Tests.Odbc.SqlServer [Fact] public void ToList() { - var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); var testDto2 = select.Limit(10).ToList(a => new TestDto()); var testDto3 = select.Limit(10).ToList(a => new TestDto { }); @@ -303,11 +301,6 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); query.ToList(); - - query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); - query.ToList(); } [Fact] public void InnerJoin() @@ -372,12 +365,6 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); query.ToList(); - - query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); - query.ToList(); - } [Fact] public void RightJoin() @@ -442,12 +429,6 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); query.ToList(); - - query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", new { bname = "xxx" }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?", sql); - query.ToList(); - } [Fact] public void Where() @@ -512,12 +493,6 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = query2.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); query2.ToList(); - - //������϶����㲻�� - query = select.Where("a.clicks > 100 and a.id = ?", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = ?)", sql); - query.ToList(); } [Fact] public void WhereIf() @@ -561,12 +536,6 @@ namespace FreeSql.Tests.Odbc.SqlServer Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); query2.ToList(); - //������϶����㲻�� - query = select.WhereIf(true, "a.clicks > 100 and a.id = ?", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = ?)", sql); - query.ToList(); - // ==========================================WhereIf(false) //����е�������a.Type��a.Type.Parent ���ǵ������� @@ -607,12 +576,6 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = query2.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c", sql); query2.ToList(); - - //������϶����㲻�� - query = select.WhereIf(false, "a.clicks > 100 and a.id = ?", new { id = 10 }); - sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); - query.ToList(); } [Fact] public void WhereExists() @@ -962,6 +925,40 @@ namespace FreeSql.Tests.Odbc.SqlServer then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TestInclude_OneToManyModel11 @@ -979,6 +976,8 @@ namespace FreeSql.Tests.Odbc.SqlServer [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TestInclude_OneToManyModel33 @@ -993,7 +992,7 @@ namespace FreeSql.Tests.Odbc.SqlServer public void Include_OneToMany2() { string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.sqlserver.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1018,6 +1017,20 @@ namespace FreeSql.Tests.Odbc.SqlServer .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1115,6 +1128,59 @@ namespace FreeSql.Tests.Odbc.SqlServer .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.sqlserver.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1219,6 +1285,61 @@ namespace FreeSql.Tests.Odbc.SqlServer .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.sqlserver, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 465996c9..618d02b2 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1090,6 +1090,40 @@ namespace FreeSql.Tests.MySql then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TestInclude_OneToManyModel11 @@ -1107,6 +1141,8 @@ namespace FreeSql.Tests.MySql [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TestInclude_OneToManyModel33 @@ -1121,7 +1157,7 @@ namespace FreeSql.Tests.MySql public void Include_OneToMany2() { string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1146,6 +1182,20 @@ namespace FreeSql.Tests.MySql .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1243,6 +1293,59 @@ namespace FreeSql.Tests.MySql .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1347,6 +1450,61 @@ namespace FreeSql.Tests.MySql .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.mysql, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 2314666d..b690941a 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -975,6 +975,40 @@ namespace FreeSql.Tests.Oracle then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.oracle.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.oracle.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TiOtmModel11 @@ -992,6 +1026,8 @@ namespace FreeSql.Tests.Oracle [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TiOtmModel33 @@ -1006,7 +1042,7 @@ namespace FreeSql.Tests.Oracle public void Include_OneToMany2() { string setting = "x"; - var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.oracle.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1031,6 +1067,20 @@ namespace FreeSql.Tests.Oracle .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1128,6 +1178,59 @@ namespace FreeSql.Tests.Oracle .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.oracle.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1232,6 +1335,61 @@ namespace FreeSql.Tests.Oracle .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.oracle, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 218713f8..613cfde5 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1048,6 +1048,40 @@ namespace FreeSql.Tests.PostgreSQL then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.pgsql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.pgsql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TestInclude_OneToManyModel11 @@ -1065,6 +1099,8 @@ namespace FreeSql.Tests.PostgreSQL [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TestInclude_OneToManyModel33 @@ -1079,7 +1115,7 @@ namespace FreeSql.Tests.PostgreSQL public void Include_OneToMany2() { string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.pgsql.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1104,6 +1140,20 @@ namespace FreeSql.Tests.PostgreSQL .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1201,6 +1251,59 @@ namespace FreeSql.Tests.PostgreSQL .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.pgsql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1305,6 +1408,61 @@ namespace FreeSql.Tests.PostgreSQL .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.pgsql, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 66fbdc20..e4a33fa9 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -970,6 +970,40 @@ namespace FreeSql.Tests.SqlServer then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TestInclude_OneToManyModel11 @@ -987,6 +1021,8 @@ namespace FreeSql.Tests.SqlServer [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TestInclude_OneToManyModel33 @@ -1001,7 +1037,7 @@ namespace FreeSql.Tests.SqlServer public void Include_OneToMany2() { string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)_sqlserverFixture.SqlServer.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1026,6 +1062,20 @@ namespace FreeSql.Tests.SqlServer .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1123,6 +1173,59 @@ namespace FreeSql.Tests.SqlServer .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.sqlserver.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1227,6 +1330,61 @@ namespace FreeSql.Tests.SqlServer .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.sqlserver, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index e2f3ae41..1d32c36c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -951,6 +951,40 @@ namespace FreeSql.Tests.Sqlite then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + + //---- Select ---- + + var at0 = g.sqlite.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.sqlite.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); } public class TestInclude_OneToManyModel11 @@ -968,6 +1002,8 @@ namespace FreeSql.Tests.Sqlite [Column(IsIdentity = true)] public int id { get; set; } public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } public List childs { get; set; } } public class TestInclude_OneToManyModel33 @@ -982,7 +1018,7 @@ namespace FreeSql.Tests.Sqlite public void Include_OneToMany2() { string setting = "x"; - var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.sqlite.Insert(model2).ExecuteIdentity(); var model3s = new[] @@ -1007,6 +1043,20 @@ namespace FreeSql.Tests.Sqlite .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); + + //---- Select ---- + + var at1 = g.sqlite.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.sqlite.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); } [Fact] @@ -1104,6 +1154,59 @@ namespace FreeSql.Tests.Sqlite .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); + + // --- Select --- + + var atags0 = g.sqlite.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -1209,6 +1312,61 @@ namespace FreeSql.Tests.Sqlite .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } public class ToDel1Pk diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 340f6565..684eb212 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -192,11 +192,12 @@ public static partial class FreeSqlGlobalExtensions /// 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); /// 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany /// - /// /// - /// - /// - /// 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 + /// 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + /// 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + /// 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + /// 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + /// /// 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) /// public static List IncludeMany(this List list, IFreeSql orm, Expression>> navigateSelector, Action> then = null) where T1 : class where TNavigate : class diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 185896b3..0f30703b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1490,7 +1490,11 @@ 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) @@ -1996,137 +2000,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2657,11 +2530,12 @@ 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - - 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) @@ -2836,3 +2710,159 @@ + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完将自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 事务体 () => {} + 超时,未执行完将自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index a5dc052c..ea1db65c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -359,7 +359,11 @@ namespace FreeSql /// 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany /// /// - /// 选择一个集合的导航属性,也可通过 .Where 设置临时的关系映射,还可以 .Take(5) 每个子集合只取5条 + /// 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + /// 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + /// 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + /// 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + /// /// 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) /// ISelect IncludeMany(Expression>> navigateSelector, Action> then = null) where TNavigate : class; diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 8e9bbe8e..084ac167 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -108,31 +108,34 @@ namespace FreeSql.Internal parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0]; parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - //dto 映射 - var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values; - foreach (var dtoProp in dtoProps) + if (initExp.NewExpression.Type != _tables.FirstOrDefault()?.Table.Type) { - foreach (var dtTb in _tables) + //dto 映射 + var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values; + foreach (var dtoProp in dtoProps) { - if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) + foreach (var dtTb in _tables) { - var child = new ReadAnonymousTypeInfo + if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) { - Property = dtoProp, - CsName = dtoProp.Name, - CsType = dtoProp.PropertyType, - MapType = trydtocol.Attribute.MapType - }; - parent.Childs.Add(child); - if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression); - else - { - child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; - field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(" as").Append(++index); + var child = new ReadAnonymousTypeInfo + { + Property = dtoProp, + CsName = dtoProp.Name, + CsType = dtoProp.PropertyType, + MapType = trydtocol.Attribute.MapType + }; + parent.Childs.Add(child); + if (dtTb.Parameter != null) + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression); + else + { + child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; + field.Append(", ").Append(child.DbField); + if (index >= 0) field.Append(" as").Append(++index); + } + break; } - break; } } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 44a32fc2..8255b6d8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -462,9 +462,8 @@ namespace FreeSql.Internal.CommonProvider public T1 First() => this.ToOne(); - protected List ToListMapReader((ReadAnonymousTypeInfo map, string field) af) + internal List ToListMrPrivate(string sql, (ReadAnonymousTypeInfo map, string field) af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { - var sql = this.ToSql(af.field); var type = typeof(TReturn); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); @@ -477,6 +476,9 @@ namespace FreeSql.Internal.CommonProvider { var index = -1; ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + if (otherData != null) + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false)); }, CommandType.Text, sql, dbParms); } catch (Exception ex) @@ -489,9 +491,27 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } + if (typeof(TReturn) == typeof(T1)) + foreach (var include in _includeToList) include?.Invoke(ret); _trackToList?.Invoke(ret); return ret; } + internal List ToListMapReaderPrivate((ReadAnonymousTypeInfo map, string field) af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.field); + + return ToListMrPrivate(sql, af, otherData); + } + protected List ToListMapReader((ReadAnonymousTypeInfo map, string field) af) => ToListMapReaderPrivate(af, null); protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) { var map = new ReadAnonymousTypeInfo(); @@ -1163,9 +1183,8 @@ namespace FreeSql.Internal.CommonProvider public Task FirstAsync() => this.ToOneAsync(); - async protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) + async internal Task> ToListMrPrivateAsync(string sql, (ReadAnonymousTypeInfo map, string field) af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { - var sql = this.ToSql(af.field); var type = typeof(TReturn); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); @@ -1178,6 +1197,9 @@ namespace FreeSql.Internal.CommonProvider { var index = -1; ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + if (otherData != null) + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false)); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } @@ -1191,9 +1213,27 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } + if (typeof(TReturn) == typeof(T1)) + foreach (var include in _includeToList) include?.Invoke(ret); _trackToList?.Invoke(ret); return ret; } + internal Task> ToListMapReaderPrivateAsync((ReadAnonymousTypeInfo map, string field) af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.field); + + return ToListMrPrivateAsync(sql, af, otherData); + } + protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) => ToListMapReaderPrivateAsync(af, null); async protected Task InternalAvgAsync(Expression exp) => (await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index a4e8d8f7..db153519 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -386,16 +386,23 @@ namespace FreeSql.Internal.CommonProvider if (expBody == null) return this; MethodCallExpression whereExp = null; int takeNumber = 0; + Expression> selectExp = null; while (expBody.NodeType == ExpressionType.Call) { - throwNavigateSelector = new Exception($"IncludeMany {nameof(navigateSelector)} 参数类型错误,表达式格式应该是 a.collections.Take(1).Where(c => c.aid == a.id)"); + throwNavigateSelector = new Exception($"IncludeMany {nameof(navigateSelector)} 参数类型错误,正确格式: a.collections.Take(1).Where(c => c.aid == a.id).Select(a => new TNavigate {{ }})"); var callExp = (expBody as MethodCallExpression); switch (callExp.Method.Name) { case "Where": whereExp = callExp; break; - case "Take": takeNumber = int.Parse((callExp.Arguments[1] as ConstantExpression)?.Value?.ToString() ?? "0"); break; + case "Take": + takeNumber = int.Parse(_commonExpression.ExpressionLambdaToSql(callExp.Arguments[1], new CommonExpression.ExpTSC { })); + break; + case "Select": + selectExp = (callExp.Arguments[1] as Expression>); + if (selectExp?.Parameters.Count != 1) throw new Exception($"IncludeMany {nameof(navigateSelector)} 参数错误,Select 只可以使用一个参数的方法,正确格式: .Select(t => new TNavigate {{ }})"); + break; default: throw throwNavigateSelector; } expBody = callExp.Object ?? callExp.Arguments.FirstOrDefault(); @@ -406,6 +413,9 @@ namespace FreeSql.Internal.CommonProvider var (membersParam, members) = GetExpressionStack(collMem.Expression); var tb = _commonUtils.GetTableByEntity(collMem.Expression.Type); if (tb == null) throw throwNavigateSelector; + var collMemElementType = (collMem.Type.IsGenericType ? collMem.Type.GetGenericArguments().FirstOrDefault() : collMem.Type.GetElementType()); + if (typeof(TNavigate) != collMemElementType) + throw new Exception($"IncludeMany {nameof(navigateSelector)} 参数错误,Select lambda参数返回值必须和 {collMemElementType} 类型一致"); var tbNav = _commonUtils.GetTableByEntity(typeof(TNavigate)); if (tbNav == null) throw new Exception($"类型 {typeof(TNavigate).FullName} 错误,不能使用 IncludeMany"); @@ -588,6 +598,22 @@ namespace FreeSql.Internal.CommonProvider var oldWhere = subSelect._where.ToString(); if (oldWhere.StartsWith(" AND ")) oldWhere = oldWhere.Remove(0, 5); + if (selectExp != null) + { + var tmpinitExp = selectExp.Body as MemberInitExpression; + var newinitExpBindings = tmpinitExp.Bindings.ToList(); + foreach (var tbrefCol in tbref.RefColumns) + { + if (newinitExpBindings.Any(a => a.Member.Name == tbrefCol.CsName)) continue; + var tmpMemberInfo = tbrefCol.Table.Properties[tbrefCol.CsName]; + newinitExpBindings.Add(Expression.Bind(tmpMemberInfo, Expression.MakeMemberAccess(selectExp.Parameters[0], tmpMemberInfo))); + } + Expression newinitExp = Expression.MemberInit(tmpinitExp.NewExpression, newinitExpBindings.ToList()); + var selectExpParam = subSelect._tables[0].Parameter ?? Expression.Parameter(typeof(TNavigate), subSelectT1Alias); + newinitExp = new NewExpressionVisitor(selectExpParam, selectExp.Parameters[0]).Replace(newinitExp); + selectExp = Expression.Lambda>(newinitExp, selectExpParam); + } + switch (tbref.RefType) { case TableRefType.OneToMany: @@ -616,19 +642,23 @@ namespace FreeSql.Internal.CommonProvider }; if (takeNumber > 0) { - var af = subSelect.GetAllFieldExpressionTreeLevelAll(); + Select0Provider, TNavigate>.GetAllFieldExpressionTreeInfo af = null; + (ReadAnonymousTypeInfo map, string field) mf = default; + if (selectExp == null) af = subSelect.GetAllFieldExpressionTreeLevelAll(); + else mf = subSelect.GetExpressionField(selectExp); var sbSql = new StringBuilder(); var sbDic = getWhereDic(); foreach (var sbd in sbDic) { subSelect._where.Clear(); subSelect.Where(sbd.Key).Where(oldWhere).Limit(takeNumber); - sbSql.Append("\r\nUNION ALL\r\nselect * from (").Append(subSelect.ToSql(af.Field)).Append(") ftb"); + sbSql.Append("\r\nUNION ALL\r\nselect * from (").Append(subSelect.ToSql(selectExp == null ? af.Field : mf.field)).Append(") ftb"); } sbSql.Remove(0, 13); if (sbDic.Count == 1) sbSql.Remove(0, 15).Remove(sbSql.Length - 5, 5); sbDic.Clear(); - subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, null); + if (selectExp == null) subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, null); + else subList = subSelect.ToListMrPrivate(sbSql.ToString(), mf, null); sbSql.Clear(); } else @@ -658,7 +688,8 @@ namespace FreeSql.Internal.CommonProvider sbDic.Clear(); } subSelect.Where(oldWhere); - subList = subSelect.ToList(true); + if (selectExp == null) subList = subSelect.ToList(true); + else subList = subSelect.ToList(selectExp); } if (subList.Any() == false) @@ -760,7 +791,10 @@ namespace FreeSql.Internal.CommonProvider subSelect.InnerJoin(sbJoin.ToString()); sbJoin.Clear(); - var af = subSelect.GetAllFieldExpressionTreeLevelAll(); + Select0Provider, TNavigate>.GetAllFieldExpressionTreeInfo af = null; + (ReadAnonymousTypeInfo map, string field) mf = default; + if (selectExp == null) af = subSelect.GetAllFieldExpressionTreeLevelAll(); + else mf = subSelect.GetExpressionField(selectExp); (string field, ReadAnonymousTypeInfo read)? otherData = null; var sbSql = new StringBuilder(); @@ -814,7 +848,7 @@ namespace FreeSql.Internal.CommonProvider { subSelect._where.Clear(); subSelect.Where(sbd.Key).Where(oldWhere).Limit(takeNumber); - sbSql.Append("\r\nUNION ALL\r\nselect * from (").Append(subSelect.ToSql($"{af.Field}{otherData?.field}")).Append(") ftb"); + sbSql.Append("\r\nUNION ALL\r\nselect * from (").Append(subSelect.ToSql($"{(selectExp == null ? af.Field : mf.field)}{otherData?.field}")).Append(") ftb"); } sbSql.Remove(0, 13); if (sbDic.Count == 1) sbSql.Remove(0, 15).Remove(sbSql.Length - 5, 5); @@ -838,10 +872,11 @@ namespace FreeSql.Internal.CommonProvider sbDic.Clear(); } subSelect.Where(oldWhere); - sbSql.Append(subSelect.ToSql($"{af.Field}{otherData?.field}")); + sbSql.Append(subSelect.ToSql($"{(selectExp == null ? af.Field : mf.field)}{otherData?.field}")); } - subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + if (selectExp == null) subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + else subList = subSelect.ToListMrPrivate(sbSql.ToString(), mf, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); if (subList.Any() == false) { foreach (var item in list) From 94e51d1dff82c110d0993b33f8ff515fc4e116ee Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 18 Nov 2019 03:24:16 +0800 Subject: [PATCH 0252/1029] ## v0.11.20 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 20bb9925..59d67193 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.19 + 0.11.20 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a4a15414..eee0aa50 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 1d80efb0..180f806d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 3e9fc002..10e0ada5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 29654689..0d81647e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.19 + 0.11.20 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 519b4c03..bd744483 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 92206e33..8bb682b3 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index e9475019..50045c53 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 7f4df8c9..afd125b9 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d3fa8302..641489ed 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7bc29e34..91df3399 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 286d32b7..c11692ce 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index b17a6833..c0966dcc 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.19 + 0.11.20 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From acd406164a35e8b64d1474c44c34c7ed8d0fe938 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 18 Nov 2019 19:12:50 +0800 Subject: [PATCH 0253/1029] Property set method not found #132 --- FreeSql/Internal/CommonExpression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 084ac167..b83db6ff 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -251,7 +251,7 @@ namespace FreeSql.Internal var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead); if (isnull == false && objval == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) isnull = true; - if (isnull == false) + if (isnull == false && prop.CanWrite) prop.SetValue(ret, objval, null); } return isnull ? null : ret; From d6010b4b51150e47b352feb298db4b1d0c207978 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 19 Nov 2019 00:38:34 +0800 Subject: [PATCH 0254/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20SqlServer=20?= =?UTF-8?q?DbFirst=E3=80=81CodeFirst=20=E6=9F=A5=E8=AF=A2=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E8=A1=A8=E7=9A=84=E5=88=97=E4=BF=A1=E6=81=AF=E9=94=99?= =?UTF-8?q?=E8=AF=AF=EF=BC=8C=E5=BD=93=E8=AE=BE=E7=BD=AE=E4=BA=86=E8=A1=A8?= =?UTF-8?q?/=E5=88=97=E5=A4=9A=E4=B8=AA=E6=89=A9=E5=B1=95=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=97=B6=E5=8F=91=E7=94=9F=EF=BC=9B=20-=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20SqlServer2005=20CodeFirst=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E4=B8=8D=E6=94=AF=E6=8C=81=20SET=20(LOCK=5FE?= =?UTF-8?q?SCALATION=20TABLE)=20=E7=9A=84=E9=94=99=E8=AF=AF=EF=BC=88?= =?UTF-8?q?=E5=B7=B2=E5=81=9A=E9=80=82=E9=85=8D=EF=BC=89=EF=BC=9B=20-=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20SqlServer2005=20=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E6=8F=92=E5=85=A5SQL=E8=AF=AD=E6=B3=95=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E6=94=AF=E6=8C=81=20Values(),()=EF=BC=88?= =?UTF-8?q?=E5=B7=B2=E5=81=9A=E9=80=82=E9=85=8D=EF=BC=89=EF=BC=9B=20-=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84=20SqlServer2005=20=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E8=B7=91=E9=80=9A=E4=BA=86=E6=89=80=E6=9C=89=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseEntity 纯净版源码.zip | Bin 0 -> 4088 bytes .../DataAnnotations/SqlServerFluentTest.cs | 26 +- .../SqlServer/Curd/SqlServerDeleteTest.cs | 28 +- .../SqlServer/Curd/SqlServerInsertTest.cs | 32 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 124 ++++---- .../SqlServer/Curd/SqlServerUpdateTest.cs | 38 +-- .../SqlServer/MapType/BoolNullableTest.cs | 36 +-- .../SqlServer/MapType/BoolTest.cs | 36 +-- .../SqlServer/MapType/EnumTest.cs | 8 +- .../SqlServer/MapType/ToStringTest.cs | 20 +- .../SqlServerAdo/SqlServerAdoTest.cs | 30 +- .../SqlServer/SqlServerCodeFirstTest.cs | 33 +- .../SqlServer/SqlServerDbFirstTest.cs | 4 +- .../SqlServerExpression/ConvertTest.cs | 2 +- .../SqlServerExpression/DateTimeTest.cs | 2 +- .../SqlServer/SqlServerExpression/MathTest.cs | 2 +- .../SqlServerExpression/OtherTest.cs | 2 +- .../SqlServerExpression/StringTest.cs | 4 +- .../SqlServerExpression/TimeSpanTest.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 4 + FreeSql/FreeSql.xml | 287 ++++++++---------- .../Internal/CommonProvider/InsertProvider.cs | 15 +- .../CommonProvider/InsertProviderAsync.cs | 2 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 100 +++++- .../SqlServer/OdbcSqlServerCodeFirst.cs | 49 +-- .../SqlServer/OdbcSqlServerDbFirst.cs | 16 +- .../SqlServer/OdbcSqlServerProvider.cs | 2 +- .../SqlServer/OdbcSqlServerUtils.cs | 4 +- .../Curd/SqlServerInsert.cs | 97 +++++- .../SqlServerCodeFirst.cs | 49 +-- .../SqlServerDbFirst.cs | 16 +- .../SqlServerProvider.cs | 2 +- .../SqlServerUtils.cs | 4 +- 34 files changed, 598 insertions(+), 480 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip new file mode 100644 index 0000000000000000000000000000000000000000..ab1fb53d6f3f718fcb89c9e829b10dcad851ac12 GIT binary patch literal 4088 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 => _sqlserverFixture.SqlServer.Select().ToList()); + Assert.Throws(() => g.sqlserver.Select().ToList()); - _sqlserverFixture.SqlServer.Select().ToList(); + g.sqlserver.Select().ToList(); } [Table(DisableSyncStructure = true)] class ModelDisableSyncStructure @@ -39,7 +39,7 @@ namespace FreeSql.Tests.DataAnnotations [Fact] public void Fluent() { - _sqlserverFixture.SqlServer.CodeFirst + g.sqlserver.CodeFirst //.ConfigEntity(a => { // a.Name("xxdkdkdk1"); // a.Property(b => b.Id).Name("Id22").IsIdentity(true); @@ -61,21 +61,21 @@ namespace FreeSql.Tests.DataAnnotations }) ; - var ddl1 = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); - var ddl2 = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + var ddl1 = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + var ddl2 = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); - var t1id = _sqlserverFixture.SqlServer.Insert().AppendData(new TestFluenttb1 { }).ExecuteIdentity(); - var t1 = _sqlserverFixture.SqlServer.Select(t1id).ToOne(); + var t1id = g.sqlserver.Insert().AppendData(new TestFluenttb1 { }).ExecuteIdentity(); + var t1 = g.sqlserver.Select(t1id).ToOne(); - var t2lastId = _sqlserverFixture.SqlServer.Select().Max(a => a.Id); - var t2affrows = _sqlserverFixture.SqlServer.Insert().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows(); - var t2 = _sqlserverFixture.SqlServer.Select(t2lastId + 1).ToOne(); + var t2lastId = g.sqlserver.Select().Max(a => a.Id); + var t2affrows = g.sqlserver.Insert().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows(); + var t2 = g.sqlserver.Select(t2lastId + 1).ToOne(); } [Fact] public void GroupPrimaryKey() { - _sqlserverFixture.SqlServer.CodeFirst.SyncStructure(); + g.sqlserver.CodeFirst.SyncStructure(); g.mysql.CodeFirst.SyncStructure(); g.pgsql.CodeFirst.SyncStructure(); g.sqlite.CodeFirst.SyncStructure(); @@ -114,9 +114,9 @@ namespace FreeSql.Tests.DataAnnotations public void IsIgnore() { var item = new TestIsIgnore { }; - Assert.Equal(1, _sqlserverFixture.SqlServer.Insert().AppendData(item).ExecuteAffrows()); + Assert.Equal(1, g.sqlserver.Insert().AppendData(item).ExecuteAffrows()); - var find = _sqlserverFixture.SqlServer.Select().Where(a => a.id == item.id).First(); + var find = g.sqlserver.Select().Where(a => a.id == item.id).First(); Assert.NotNull(find); Assert.Equal(item.id, find.id); } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs index ea3c40f9..9350ea81 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs @@ -17,7 +17,7 @@ namespace FreeSql.Tests.SqlServer _sqlserverFixture = sqlserverFixture; } - IDelete delete => _sqlserverFixture.SqlServer.Delete(); //�������� + IDelete delete => g.sqlserver.Delete(); //�������� [Table(Name = "tb_topic22211")] class Topic @@ -33,17 +33,17 @@ namespace FreeSql.Tests.SqlServer [Fact] public void Dywhere() { - Assert.Null(_sqlserverFixture.SqlServer.Delete().ToSql()); - var sql = _sqlserverFixture.SqlServer.Delete(new[] { 1, 2 }).ToSql(); + Assert.Null(g.sqlserver.Delete().ToSql()); + var sql = g.sqlserver.Delete(new[] { 1, 2 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new { id = 1 }).ToSql(); + sql = g.sqlserver.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); } @@ -70,18 +70,18 @@ namespace FreeSql.Tests.SqlServer public void ExecuteAffrows() { - var id = _sqlserverFixture.SqlServer.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + var id = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); } [Fact] public void ExecuteDeleted() { - var item = _sqlserverFixture.SqlServer.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + var item = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }).ToArray(); - var itemsInserted = _sqlserverFixture.SqlServer.Insert(items).ExecuteInserted(); + var itemsInserted = g.sqlserver.Insert(items).ExecuteInserted(); Assert.Equal(items.First().Title, itemsInserted[0].Title); Assert.Equal(itemsInserted[0].Id, delete.Where(a => a.Id == itemsInserted[0].Id).ExecuteDeleted()[0].Id); @@ -90,17 +90,17 @@ namespace FreeSql.Tests.SqlServer [Fact] public void AsTable() { - Assert.Null(_sqlserverFixture.SqlServer.Delete().ToSql()); - var sql = _sqlserverFixture.SqlServer.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Null(g.sqlserver.Delete().ToSql()); + var sql = g.sqlserver.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); + sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); + sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); - sql = _sqlserverFixture.SqlServer.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + sql = g.sqlserver.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index 00a3ba88..c17a1113 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.SqlServer _sqlserverFixture = sqlserverFixture; } - IInsert insert => _sqlserverFixture.SqlServer.Insert(); //�������� + IInsert insert => g.sqlserver.Insert(); //�������� [Table(Name = "tb_topic")] class Topic @@ -75,12 +75,12 @@ namespace FreeSql.Tests.SqlServer sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); - _sqlserverFixture.SqlServer.Delete().Where("1=1").ExecuteAffrows(); + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); var itemsIgnore = new List(); for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - _sqlserverFixture.SqlServer.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); Assert.Equal(2072, itemsIgnore.Count); - Assert.Equal(2072, _sqlserverFixture.SqlServer.Select().Where(a => a.Title == null).Count()); + Assert.Equal(2072, g.sqlserver.Select().Where(a => a.Title == null).Count()); } [Table(Name = "tb_topicIgnoreColumns")] class TopicIgnore @@ -98,33 +98,33 @@ namespace FreeSql.Tests.SqlServer for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); - Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).NoneParameter().ExecuteAffrows()); //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - //Assert.Equal(9989, _sqlserverFixture.SqlServer.Insert(items).ExecuteAffrows()); + //Assert.Equal(9989, g.sqlserver.Insert(items).ExecuteAffrows()); //var bttype = new TestBetchInsertType { title = "testbttitle1" }; - //bttype.id = (int)_sqlserverFixture.SqlServer.Insert(bttype).ExecuteIdentity(); + //bttype.id = (int)g.sqlserver.Insert(bttype).ExecuteIdentity(); //Assert.True(bttype.id > 0); //var bttopic = Enumerable.Range(0, 10000).Select(a => new TestBetchInsertTopic { TypeId = bttype.id, Text = $"testtopic{a}" }).ToArray(); - //Assert.Equal(bttopic.Length, _sqlserverFixture.SqlServer.Insert(bttopic).ExecuteAffrows()); + //Assert.Equal(bttopic.Length, g.sqlserver.Insert(bttopic).ExecuteAffrows()); - //_sqlserverFixture.SqlServer.Transaction(() => + //g.sqlserver.Transaction(() => //{ // bttype = new TestBetchInsertType { title = "transaction_testbttitle2" }; - // bttype.id = (int)_sqlserverFixture.SqlServer.Insert(bttype).ExecuteIdentity(); + // bttype.id = (int)g.sqlserver.Insert(bttype).ExecuteIdentity(); // Assert.True(bttype.id > 0); // bttopic = Enumerable.Range(0, 10000).Select(a => new TestBetchInsertTopic { TypeId = bttype.id, Text = $"transaction_testtopic{a}" }).ToArray(); - // Assert.Equal(bttopic.Length, _sqlserverFixture.SqlServer.Insert(bttopic).ExecuteAffrows()); + // Assert.Equal(bttopic.Length, g.sqlserver.Insert(bttopic).ExecuteAffrows()); //}); - _sqlserverFixture.SqlServer.Transaction(() => + g.sqlserver.Transaction(() => { var order = new AdjustPriceOrder { }; - order.Id = (int)_sqlserverFixture.SqlServer.Insert(order).NoneParameter().ExecuteIdentity(); + order.Id = (int)g.sqlserver.Insert(order).NoneParameter().ExecuteIdentity(); Assert.True(order.Id > 0); var detail = Enumerable.Range(0, 10000).Select(a => new AdjustPriceDetail { Remark = $"transaction_testdetail{a}" }).ToArray(); - Assert.Equal(detail.Length, _sqlserverFixture.SqlServer.Insert(detail).NoneParameter().ExecuteAffrows()); + Assert.Equal(detail.Length, g.sqlserver.Insert(detail).NoneParameter().ExecuteAffrows()); }); } class TestBetchInsertType { @@ -149,7 +149,7 @@ namespace FreeSql.Tests.SqlServer //items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); //var lastId = g.sqlite.Select().Max(a => a.Id); - //Assert.NotEqual(lastId, _sqlserverFixture.SqlServer.Insert(items).ExecuteIdentity()); + //Assert.NotEqual(lastId, g.sqlserver.Insert(items).ExecuteIdentity()); } [Fact] public void ExecuteInserted() @@ -160,7 +160,7 @@ namespace FreeSql.Tests.SqlServer var items2 = insert.AppendData(items).ExecuteInserted(); items = Enumerable.Range(0, 90).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); - var itemsInserted = _sqlserverFixture.SqlServer.Insert(items).ExecuteInserted(); + var itemsInserted = g.sqlserver.Insert(items).ExecuteInserted(); Assert.Equal(items.First().Title, itemsInserted.First().Title); Assert.Equal(items.Last().Title, itemsInserted.Last().Title); } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index e4a33fa9..a34a5924 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.SqlServer _sqlserverFixture = sqlserverFixture; } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => g.sqlserver.Select(); [Table(Name = "tb_topic22")] class Topic @@ -83,7 +83,7 @@ namespace FreeSql.Tests.SqlServer public void AsSelect() { //OneToOne、ManyToOne - var t0 = _sqlserverFixture.SqlServer.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + var t0 = g.sqlserver.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 //FROM [Tag] a //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] @@ -91,7 +91,7 @@ namespace FreeSql.Tests.SqlServer //WHERE (a__Parent__Parent.[Name] = '粤语') //OneToMany - var t1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + var t1 = g.sqlserver.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] //FROM [Tag] a //WHERE (exists(SELECT 1 @@ -101,7 +101,7 @@ namespace FreeSql.Tests.SqlServer // limit 0,1)) //ManyToMany - var t2 = _sqlserverFixture.SqlServer.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + var t2 = g.sqlserver.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] //FROM [Song] a //WHERE(exists(SELECT 1 @@ -116,11 +116,11 @@ namespace FreeSql.Tests.SqlServer [Fact] public void Lazy() { - var tags = _sqlserverFixture.SqlServer.Select().Where(a => a.Parent.Name == "xxx") + var tags = g.sqlserver.Select().Where(a => a.Parent.Name == "xxx") .LeftJoin(a => a.Parent_id == a.Parent.Id) .ToSql(); - var songs = _sqlserverFixture.SqlServer.Select().Limit(10).ToList(); + var songs = g.sqlserver.Select().Limit(10).ToList(); } @@ -130,12 +130,12 @@ namespace FreeSql.Tests.SqlServer var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); - Assert.Single(_sqlserverFixture.SqlServer.Insert().AppendData(items.First()).ExecuteInserted()); - Assert.Equal(10, _sqlserverFixture.SqlServer.Insert().AppendData(items).ExecuteInserted().Count); + Assert.Single(g.sqlserver.Insert().AppendData(items.First()).ExecuteInserted()); + Assert.Equal(10, g.sqlserver.Insert().AppendData(items).ExecuteInserted().Count); //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); //; - //Assert.Equal(9989, _sqlserverFixture.SqlServer.Insert(items).NoneParameter().ExecuteAffrows()); + //Assert.Equal(9989, g.sqlserver.Insert(items).NoneParameter().ExecuteAffrows()); var dt1 = select.Limit(10).ToDataTable(); var dt2 = select.Limit(10).ToDataTable("id, getdate()"); @@ -160,9 +160,9 @@ namespace FreeSql.Tests.SqlServer var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); - _sqlserverFixture.SqlServer.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); - var testGuidId5 = _sqlserverFixture.SqlServer.Select().ToList(); - var testGuidId6 = _sqlserverFixture.SqlServer.Select().ToList(a => a.id); + g.sqlserver.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.sqlserver.Select().ToList(); + var testGuidId6 = g.sqlserver.Select().ToList(a => a.id); var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); @@ -659,8 +659,8 @@ namespace FreeSql.Tests.SqlServer ccc3 = a.Max(a.Value.Item3.Id) }); - var testpid1 = _sqlserverFixture.SqlServer.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); - _sqlserverFixture.SqlServer.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var testpid1 = g.sqlserver.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.sqlserver.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); var aggsql1 = select .GroupBy(a => a.Title) @@ -919,16 +919,16 @@ namespace FreeSql.Tests.SqlServer public void Include_OneToMany() { var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; - model1.id = (int)_sqlserverFixture.SqlServer.Insert(model1).ExecuteIdentity(); + model1.id = (int)g.sqlserver.Insert(model1).ExecuteIdentity(); var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; - _sqlserverFixture.SqlServer.Insert(model2).ExecuteAffrows(); + g.sqlserver.Insert(model2).ExecuteAffrows(); var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; - model3_1.id = (int)_sqlserverFixture.SqlServer.Insert(model3_1).ExecuteIdentity(); + model3_1.id = (int)g.sqlserver.Insert(model3_1).ExecuteIdentity(); var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; - model3_2.id = (int)_sqlserverFixture.SqlServer.Insert(model3_2).ExecuteIdentity(); + model3_2.id = (int)g.sqlserver.Insert(model3_2).ExecuteIdentity(); var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; - model3_3.id = (int)_sqlserverFixture.SqlServer.Insert(model3_2).ExecuteIdentity(); + model3_3.id = (int)g.sqlserver.Insert(model3_2).ExecuteIdentity(); var model4s = new[] { new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, @@ -937,35 +937,35 @@ namespace FreeSql.Tests.SqlServer new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } }; - Assert.Equal(5, _sqlserverFixture.SqlServer.Insert(model4s).ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Insert(model4s).ExecuteAffrows()); - var t0 = _sqlserverFixture.SqlServer.Select() + var t0 = g.sqlserver.Select() .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) .Where(a => a.model2id <= model1.id) .ToList(); - var t1 = _sqlserverFixture.SqlServer.Select() + var t1 = g.sqlserver.Select() .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) .Where(a => a.id <= model1.id) .ToList(); - var t2 = _sqlserverFixture.SqlServer.Select() + var t2 = g.sqlserver.Select() .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); - var t00 = _sqlserverFixture.SqlServer.Select() + var t00 = g.sqlserver.Select() .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) .Where(a => a.model2id <= model1.id) .ToList(); - var t11 = _sqlserverFixture.SqlServer.Select() + var t11 = g.sqlserver.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) .Where(a => a.id <= model1.id) .ToList(); - var t22 = _sqlserverFixture.SqlServer.Select() + var t22 = g.sqlserver.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) @@ -1038,7 +1038,7 @@ namespace FreeSql.Tests.SqlServer { string setting = "x"; var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; - model2.id = (int)_sqlserverFixture.SqlServer.Insert(model2).ExecuteIdentity(); + model2.id = (int)g.sqlserver.Insert(model2).ExecuteIdentity(); var model3s = new[] { @@ -1046,18 +1046,18 @@ namespace FreeSql.Tests.SqlServer new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} }; - Assert.Equal(3, _sqlserverFixture.SqlServer.Insert(model3s).ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Insert(model3s).ExecuteAffrows()); var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; - model1.id = (int)_sqlserverFixture.SqlServer.Insert(model1).ExecuteIdentity(); + model1.id = (int)g.sqlserver.Insert(model1).ExecuteIdentity(); - var t1 = _sqlserverFixture.SqlServer.Select() + var t1 = g.sqlserver.Select() .LeftJoin(a => a.model2id == a.model2.id) .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) .ToList(true); - var t11 = _sqlserverFixture.SqlServer.Select() + var t11 = g.sqlserver.Select() .LeftJoin(a => a.model2id == a.model2.id) .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) @@ -1086,56 +1086,56 @@ namespace FreeSql.Tests.SqlServer Ddd = DateTime.Now.Second, Name = "test_oneToChilds_01_中国" }; - tag1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1).ExecuteIdentity(); + tag1.Id = (int)g.sqlserver.Insert(tag1).ExecuteIdentity(); var tag1_1 = new Tag { Parent_id = tag1.Id, Ddd = DateTime.Now.Second, Name = "test_oneToChilds_01_北京" }; - tag1_1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1_1).ExecuteIdentity(); + tag1_1.Id = (int)g.sqlserver.Insert(tag1_1).ExecuteIdentity(); var tag1_2 = new Tag { Parent_id = tag1.Id, Ddd = DateTime.Now.Second, Name = "test_oneToChilds_01_上海" }; - tag1_2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1_2).ExecuteIdentity(); + tag1_2.Id = (int)g.sqlserver.Insert(tag1_2).ExecuteIdentity(); var tag2 = new Tag { Ddd = DateTime.Now.Second, Name = "test_oneToChilds_02_美国" }; - tag2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2).ExecuteIdentity(); + tag2.Id = (int)g.sqlserver.Insert(tag2).ExecuteIdentity(); var tag2_1 = new Tag { Parent_id = tag2.Id, Ddd = DateTime.Now.Second, Name = "test_oneToChilds_02_纽约" }; - tag2_1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2_1).ExecuteIdentity(); + tag2_1.Id = (int)g.sqlserver.Insert(tag2_1).ExecuteIdentity(); var tag2_2 = new Tag { Parent_id = tag2.Id, Ddd = DateTime.Now.Second, Name = "test_oneToChilds_02_华盛顿" }; - tag2_2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2_2).ExecuteIdentity(); + tag2_2.Id = (int)g.sqlserver.Insert(tag2_2).ExecuteIdentity(); - var tags0 = _sqlserverFixture.SqlServer.Select() + var tags0 = g.sqlserver.Select() .Include(a => a.Parent) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); - var tags1 = _sqlserverFixture.SqlServer.Select() + var tags1 = g.sqlserver.Select() .IncludeMany(a => a.Tags) .Include(a => a.Parent) .IncludeMany(a => a.Songs) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); - var tags2 = _sqlserverFixture.SqlServer.Select() + var tags2 = g.sqlserver.Select() .IncludeMany(a => a.Tags, then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) .Include(a => a.Parent) @@ -1143,7 +1143,7 @@ namespace FreeSql.Tests.SqlServer .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); - var tags3 = _sqlserverFixture.SqlServer.Select() + var tags3 = g.sqlserver.Select() .IncludeMany(a => a.Tags, then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) .Include(a => a.Parent) @@ -1151,14 +1151,14 @@ namespace FreeSql.Tests.SqlServer .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); - var tags11 = _sqlserverFixture.SqlServer.Select() + var tags11 = g.sqlserver.Select() .IncludeMany(a => a.Tags.Take(1)) .Include(a => a.Parent) .IncludeMany(a => a.Songs.Take(1)) .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); - var tags22 = _sqlserverFixture.SqlServer.Select() + var tags22 = g.sqlserver.Select() .IncludeMany(a => a.Tags.Take(1), then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) .Include(a => a.Parent) @@ -1166,7 +1166,7 @@ namespace FreeSql.Tests.SqlServer .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) .ToList(); - var tags33 = _sqlserverFixture.SqlServer.Select() + var tags33 = g.sqlserver.Select() .IncludeMany(a => a.Tags.Take(1), then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) .Include(a => a.Parent) @@ -1237,19 +1237,19 @@ namespace FreeSql.Tests.SqlServer Ddd = DateTime.Now.Second, Name = "test_manytoMany_01_中国" }; - tag1.Id = (int)_sqlserverFixture.SqlServer.Insert(tag1).ExecuteIdentity(); + tag1.Id = (int)g.sqlserver.Insert(tag1).ExecuteIdentity(); var tag2 = new Tag { Ddd = DateTime.Now.Second, Name = "test_manytoMany_02_美国" }; - tag2.Id = (int)_sqlserverFixture.SqlServer.Insert(tag2).ExecuteIdentity(); + tag2.Id = (int)g.sqlserver.Insert(tag2).ExecuteIdentity(); var tag3 = new Tag { Ddd = DateTime.Now.Second, Name = "test_manytoMany_03_日本" }; - tag3.Id = (int)_sqlserverFixture.SqlServer.Insert(tag3).ExecuteIdentity(); + tag3.Id = (int)g.sqlserver.Insert(tag3).ExecuteIdentity(); var song1 = new Song { @@ -1257,30 +1257,30 @@ namespace FreeSql.Tests.SqlServer Title = "test_manytoMany_01_我是中国人.mp3", Url = "http://ww.baidu.com/" }; - song1.Id = (int)_sqlserverFixture.SqlServer.Insert(song1).ExecuteIdentity(); + song1.Id = (int)g.sqlserver.Insert(song1).ExecuteIdentity(); var song2 = new Song { Create_time = DateTime.Now, Title = "test_manytoMany_02_爱你一万年.mp3", Url = "http://ww.163.com/" }; - song2.Id = (int)_sqlserverFixture.SqlServer.Insert(song2).ExecuteIdentity(); + song2.Id = (int)g.sqlserver.Insert(song2).ExecuteIdentity(); var song3 = new Song { Create_time = DateTime.Now, Title = "test_manytoMany_03_千年等一回.mp3", Url = "http://ww.sina.com/" }; - song3.Id = (int)_sqlserverFixture.SqlServer.Insert(song3).ExecuteIdentity(); + song3.Id = (int)g.sqlserver.Insert(song3).ExecuteIdentity(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); - var songs1 = _sqlserverFixture.SqlServer.Select() + var songs1 = g.sqlserver.Select() .IncludeMany(a => a.Tags) .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) .ToList(); @@ -1289,7 +1289,7 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(1, songs1[1].Tags.Count); Assert.Equal(3, songs1[2].Tags.Count); - var songs2 = _sqlserverFixture.SqlServer.Select() + var songs2 = g.sqlserver.Select() .IncludeMany(a => a.Tags, then => then.IncludeMany(t => t.Songs)) .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) @@ -1299,14 +1299,14 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(1, songs2[1].Tags.Count); Assert.Equal(3, songs2[2].Tags.Count); - var tags3 = _sqlserverFixture.SqlServer.Select() + var tags3 = g.sqlserver.Select() .Include(a => a.Tag.Parent) .IncludeMany(a => a.Tag.Songs) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); - var songs11 = _sqlserverFixture.SqlServer.Select() + var songs11 = g.sqlserver.Select() .IncludeMany(a => a.Tags.Take(1)) .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) .ToList(); @@ -1315,7 +1315,7 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(1, songs11[1].Tags.Count); Assert.Equal(1, songs11[2].Tags.Count); - var songs22 = _sqlserverFixture.SqlServer.Select() + var songs22 = g.sqlserver.Select() .IncludeMany(a => a.Tags.Take(1), then => then.IncludeMany(t => t.Songs.Take(1))) .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) @@ -1325,7 +1325,7 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(1, songs22[1].Tags.Count); Assert.Equal(1, songs22[2].Tags.Count); - var tags33 = _sqlserverFixture.SqlServer.Select() + var tags33 = g.sqlserver.Select() .Include(a => a.Tag.Parent) .IncludeMany(a => a.Tag.Songs.Take(1)) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 8ca8a169..ad22de5e 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.SqlServer _sqlserverFixture = sqlserverFixture; } - IUpdate update => _sqlserverFixture.SqlServer.Update(); + IUpdate update => g.sqlserver.Update(); [Table(Name = "tb_topic")] class Topic @@ -35,11 +35,11 @@ namespace FreeSql.Tests.SqlServer [Fact] public void Dywhere() { - Assert.Null(_sqlserverFixture.SqlServer.Update().ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + Assert.Null(g.sqlserver.Update().ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } [Fact] @@ -140,26 +140,26 @@ namespace FreeSql.Tests.SqlServer [Fact] public void ExecuteUpdated() { - _sqlserverFixture.SqlServer.Insert().AppendData(new Topic()).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert().AppendData(new Topic()).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert().AppendData(new Topic()).ExecuteAffrows(); - _sqlserverFixture.SqlServer.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); - var items = _sqlserverFixture.SqlServer.Select().Limit(2).ToList(); - _sqlserverFixture.SqlServer.Update(items).SetRaw("title='test'").ExecuteUpdated(); + var items = g.sqlserver.Select().Limit(2).ToList(); + g.sqlserver.Update(items).SetRaw("title='test'").ExecuteUpdated(); - items = _sqlserverFixture.SqlServer.Select().Limit(2).ToList(); - var result = _sqlserverFixture.SqlServer.Update(items).SetRaw("title='test'").ExecuteUpdatedAsync().Result; + items = g.sqlserver.Select().Limit(2).ToList(); + var result = g.sqlserver.Update(items).SetRaw("title='test'").ExecuteUpdatedAsync().Result; } [Fact] public void AsTable() { - Assert.Null(_sqlserverFixture.SqlServer.Update().ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", _sqlserverFixture.SqlServer.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", _sqlserverFixture.SqlServer.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Null(g.sqlserver.Update().ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs index aa6468a1..ad683985 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs @@ -73,7 +73,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Bool() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); @@ -155,7 +155,7 @@ namespace FreeSql.Tests.SqlServerMapType public void SByte() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); @@ -237,7 +237,7 @@ namespace FreeSql.Tests.SqlServerMapType public void SByteNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); @@ -319,7 +319,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Short() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); @@ -401,7 +401,7 @@ namespace FreeSql.Tests.SqlServerMapType public void ShortNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); @@ -483,7 +483,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Int() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); @@ -565,7 +565,7 @@ namespace FreeSql.Tests.SqlServerMapType public void IntNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); @@ -647,7 +647,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Long() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); @@ -729,7 +729,7 @@ namespace FreeSql.Tests.SqlServerMapType public void LongNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); @@ -812,7 +812,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Byte() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); @@ -894,7 +894,7 @@ namespace FreeSql.Tests.SqlServerMapType public void ByteNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); @@ -976,7 +976,7 @@ namespace FreeSql.Tests.SqlServerMapType public void UShort() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); @@ -1058,7 +1058,7 @@ namespace FreeSql.Tests.SqlServerMapType public void UShortNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); @@ -1140,7 +1140,7 @@ namespace FreeSql.Tests.SqlServerMapType public void UInt() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); @@ -1222,7 +1222,7 @@ namespace FreeSql.Tests.SqlServerMapType public void UIntNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); @@ -1304,7 +1304,7 @@ namespace FreeSql.Tests.SqlServerMapType public void ULong() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); @@ -1386,7 +1386,7 @@ namespace FreeSql.Tests.SqlServerMapType public void ULongNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); @@ -1490,7 +1490,7 @@ namespace FreeSql.Tests.SqlServerMapType public void String() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs index dd843638..9d3e5d46 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs @@ -74,7 +74,7 @@ namespace FreeSql.Tests.SqlServerMapType public void BoolNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); @@ -130,7 +130,7 @@ namespace FreeSql.Tests.SqlServerMapType public void SByte() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); @@ -186,7 +186,7 @@ namespace FreeSql.Tests.SqlServerMapType public void SByteNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); @@ -242,7 +242,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Short() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); @@ -298,7 +298,7 @@ namespace FreeSql.Tests.SqlServerMapType public void ShortNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); @@ -354,7 +354,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Int() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); @@ -410,7 +410,7 @@ namespace FreeSql.Tests.SqlServerMapType public void IntNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); @@ -466,7 +466,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Long() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); @@ -522,7 +522,7 @@ namespace FreeSql.Tests.SqlServerMapType public void LongNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); @@ -579,7 +579,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Byte() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); @@ -635,7 +635,7 @@ namespace FreeSql.Tests.SqlServerMapType public void ByteNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); @@ -691,7 +691,7 @@ namespace FreeSql.Tests.SqlServerMapType public void UShort() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); @@ -747,7 +747,7 @@ namespace FreeSql.Tests.SqlServerMapType public void UShortNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); @@ -803,7 +803,7 @@ namespace FreeSql.Tests.SqlServerMapType public void UInt() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); @@ -859,7 +859,7 @@ namespace FreeSql.Tests.SqlServerMapType public void UIntNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); @@ -915,7 +915,7 @@ namespace FreeSql.Tests.SqlServerMapType public void ULong() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); @@ -971,7 +971,7 @@ namespace FreeSql.Tests.SqlServerMapType public void ULongNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); @@ -1049,7 +1049,7 @@ namespace FreeSql.Tests.SqlServerMapType public void String() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs index 49e629b6..3d657684 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/EnumTest.cs @@ -36,7 +36,7 @@ namespace FreeSql.Tests.SqlServerMapType public void EnumToString() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new EnumTestMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); @@ -93,7 +93,7 @@ namespace FreeSql.Tests.SqlServerMapType public void EnumNullableToString() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new EnumTestMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); @@ -154,7 +154,7 @@ namespace FreeSql.Tests.SqlServerMapType public void EnumToInt() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new EnumTestMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); @@ -211,7 +211,7 @@ namespace FreeSql.Tests.SqlServerMapType public void EnumNullableToInt() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new EnumTestMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs index 1d5a1c3c..ab17e685 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs @@ -50,7 +50,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Enum1() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); @@ -107,7 +107,7 @@ namespace FreeSql.Tests.SqlServerMapType public void EnumNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); @@ -167,7 +167,7 @@ namespace FreeSql.Tests.SqlServerMapType public void BigInteger1() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); @@ -224,7 +224,7 @@ namespace FreeSql.Tests.SqlServerMapType public void BigIntegerNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); @@ -284,7 +284,7 @@ namespace FreeSql.Tests.SqlServerMapType public void TimeSpan1() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); @@ -325,7 +325,7 @@ namespace FreeSql.Tests.SqlServerMapType public void TimeSpanNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); @@ -380,7 +380,7 @@ namespace FreeSql.Tests.SqlServerMapType public void DateTime1() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); @@ -421,7 +421,7 @@ namespace FreeSql.Tests.SqlServerMapType public void DateTimeNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); @@ -477,7 +477,7 @@ namespace FreeSql.Tests.SqlServerMapType public void Guid1() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); @@ -521,7 +521,7 @@ namespace FreeSql.Tests.SqlServerMapType public void GuidNullable() { //insert - var orm = _sqlserverFixture.SqlServer; + var orm = g.sqlserver; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index 95a6006c..31d25d6a 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -18,13 +18,13 @@ namespace FreeSql.Tests.SqlServer [Fact] public void Pool() { - var t1 = _sqlserverFixture.SqlServer.Ado.MasterPool.StatisticsFullily; + var t1 = g.sqlserver.Ado.MasterPool.StatisticsFullily; } [Fact] public void SlavePools() { - var t2 = _sqlserverFixture.SqlServer.Ado.SlavePools.Count; + var t2 = g.sqlserver.Ado.SlavePools.Count; } [Fact] @@ -52,42 +52,42 @@ namespace FreeSql.Tests.SqlServer public void Query() { - //var tt1 = _sqlserverFixture.SqlServer.Select() + //var tt1 = g.sqlserver.Select() // .LeftJoin(a => a.ParentId == a.Parent.Id) // .ToSql(a => new { a.Id, a.Title }); - //var tt2result = _sqlserverFixture.SqlServer.Select() + //var tt2result = g.sqlserver.Select() // .LeftJoin(a => a.ParentId == a.Parent.Id) // .ToList(a => new { a.Id, a.Title }); - //var tt = _sqlserverFixture.SqlServer.Select() + //var tt = g.sqlserver.Select() // .LeftJoin((a, b) => b.Id == a.Id) // .ToSql(a => new { a.Id, a.Title }); - //var ttresult = _sqlserverFixture.SqlServer.Select() + //var ttresult = g.sqlserver.Select() // .LeftJoin((a, b) => b.Id == a.Id) // .ToList(a => new { a.Id, a.Title }); - var tnsql1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); - var tnsql2 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToSql(a => a.Id); + var tnsql1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + var tnsql2 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToSql(a => a.Id); - var tn1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToList(a => a.Id); - var tn2 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToList(a => a.Id); + var tn1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToList(a => a.Id); + var tn2 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToList(a => a.Id); - var t3 = _sqlserverFixture.SqlServer.Ado.Query("select * from xxx"); + var t3 = g.sqlserver.Ado.Query("select * from xxx"); - var t4 = _sqlserverFixture.SqlServer.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); + var t4 = g.sqlserver.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); - var t5 = _sqlserverFixture.SqlServer.Ado.Query(System.Data.CommandType.Text, "select * from xxx where Id = @Id", + var t5 = g.sqlserver.Ado.Query(System.Data.CommandType.Text, "select * from xxx where Id = @Id", new System.Data.SqlClient.SqlParameter("Id", 1)); } [Fact] public void QueryMultipline() { - var tnsql1 = _sqlserverFixture.SqlServer.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + var tnsql1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); - var t3 = _sqlserverFixture.SqlServer.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + var t3 = g.sqlserver.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); } class xxx diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 6772988d..179d32e3 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -9,32 +9,23 @@ using Xunit; namespace FreeSql.Tests.SqlServer { - - [Collection("SqlServerCollection")] public class SqlServerCodeFirstTest { - SqlServerFixture _sqlserverFixture; - - public SqlServerCodeFirstTest(SqlServerFixture sqlserverFixture) - { - _sqlserverFixture = sqlserverFixture; - } - [Fact] public void ı_ֶ() { - var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements<ı>(); - _sqlserverFixture.SqlServer.CodeFirst.SyncStructure<ı>(); + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements<ı>(); + g.sqlserver.CodeFirst.SyncStructure<ı>(); var item = new ı { = "Ա", ʱ = DateTime.Now }; - Assert.Equal(1, _sqlserverFixture.SqlServer.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.Equal(1, g.sqlserver.Insert<ı>().AppendData(item).ExecuteAffrows()); Assert.NotEqual(Guid.Empty, item.); - var item2 = _sqlserverFixture.SqlServer.Select<ı>().Where(a => a. == item.).First(); + var item2 = g.sqlserver.Select<ı>().Where(a => a. == item.).First(); Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); @@ -53,8 +44,8 @@ namespace FreeSql.Tests.SqlServer [Fact] public void AddUniques() { - var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); - _sqlserverFixture.SqlServer.CodeFirst.SyncStructure(); + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + g.sqlserver.CodeFirst.SyncStructure(); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] [Index("uk_phone", "phone", true)] @@ -73,9 +64,9 @@ namespace FreeSql.Tests.SqlServer [Fact] public void AddField() { - var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); - var id = _sqlserverFixture.SqlServer.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + var id = g.sqlserver.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); } [Table(Name = "dbo2.TopicAddField", OldName = "tedb1.dbo.TopicAddField")] @@ -103,13 +94,13 @@ namespace FreeSql.Tests.SqlServer public void GetComparisonDDLStatements() { - var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); - sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements(); + sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); } - IInsert insert => _sqlserverFixture.SqlServer.Insert(); - ISelect select => _sqlserverFixture.SqlServer.Select(); + IInsert insert => g.sqlserver.Insert(); + ISelect select => g.sqlserver.Select(); [Fact] public void CurdAllField() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs index 43227e68..c78eebe7 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs @@ -20,7 +20,7 @@ namespace FreeSql.Tests.SqlServer public void GetDatabases() { - var t1 = _sqlserverFixture.SqlServer.DbFirst.GetDatabases(); + var t1 = g.sqlserver.DbFirst.GetDatabases(); } @@ -28,7 +28,7 @@ namespace FreeSql.Tests.SqlServer public void GetTablesByDatabase() { - var t2 = _sqlserverFixture.SqlServer.DbFirst.GetTablesByDatabase(); + var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(); } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs index 824ce26f..e640b63a 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/ConvertTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.SqlServerExpression _sqlserverFixture = sqlserverFixture; } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => g.sqlserver.Select(); [Table(Name = "tb_topic")] class Topic diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs index 1f36c181..aafaf6a9 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -17,7 +17,7 @@ namespace FreeSql.Tests.SqlServerExpression _sqlserverFixture = sqlserverFixture; } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => g.sqlserver.Select(); [Table(Name = "tb_topic111333")] class Topic diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs index 87481aeb..1a29da32 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/MathTest.cs @@ -17,7 +17,7 @@ namespace FreeSql.Tests.SqlServerExpression _sqlserverFixture = sqlserverFixture; } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => g.sqlserver.Select(); [Table(Name = "tb_topic")] class Topic diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs index 7a21e3a0..97562143 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.SqlServerExpression _sqlserverFixture = sqlserverFixture; } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => g.sqlserver.Select(); [Fact] public void Div() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index ef1a110f..c0272fa8 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.SqlServerExpression _sqlserverFixture = sqlserverFixture; } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => g.sqlserver.Select(); [Table(Name = "tb_topic")] class Topic @@ -56,7 +56,7 @@ namespace FreeSql.Tests.SqlServerExpression { var list = new List(); list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); - list.Add(_sqlserverFixture.SqlServer.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs index 7d5b6779..301fe9fd 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/TimeSpanTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.SqlServerExpression _sqlserverFixture = sqlserverFixture; } - ISelect select => _sqlserverFixture.SqlServer.Select(); + ISelect select => g.sqlserver.Select(); [Table(Name = "tb_topic")] class Topic diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index c5321cd3..894723ad 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -427,7 +427,7 @@ namespace FreeSql.Tests [Fact] public void Test1() { - + g.sqlserver.Select(); g.sqlite.Update(1).NoneParameter().Set(a => a.title, null).ExecuteAffrows(); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index c7b739ec..4a863174 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -168,6 +168,10 @@ namespace FreeSql.Tests public void Test02() { + + var dbs = g.sqlserver.DbFirst.GetDatabases(); + var tbs = g.sqlserver.DbFirst.GetTablesByDatabase("ds_shop"); + var dicParamslist = g.sqlite.Select().Page(1, 10) .Where("id > @id and id > @id2 and id > @id3", new Dictionary { ["id"] = 1, ["id2"] = 2, ["id3"] = 3 }) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 0f30703b..dd964856 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2000,6 +2000,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 }) + + + + + + 可自定义解析表达式 @@ -2710,159 +2841,3 @@ - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完将自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 事务体 () => {} - 超时,未执行完将自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index e344d149..fd4074c4 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -338,7 +338,7 @@ namespace FreeSql.Internal.CommonProvider } #endregion - protected int RawExecuteAffrows() + protected virtual int RawExecuteAffrows() { var sql = ToSql(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); @@ -412,7 +412,9 @@ namespace FreeSql.Internal.CommonProvider return this; } - public virtual string ToSql() + public virtual string ToSql() => ToSqlValuesOrSelectUnionAll(true); + + public string ToSqlValuesOrSelectUnionAll(bool isValues = true) { if (_source == null || _source.Any() == false) return null; var sb = new StringBuilder(); @@ -427,14 +429,15 @@ namespace FreeSql.Internal.CommonProvider sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); ++colidx; } - sb.Append(") VALUES"); + sb.Append(") "); + if (isValues) sb.Append(isValues ? "VALUES" : "SELECT "); _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; var specialParams = new List(); var didx = 0; foreach (var d in _source) { - if (didx > 0) sb.Append(", "); - sb.Append("("); + if (didx > 0) sb.Append(isValues ? ", " : " \r\nUNION ALL\r\n "); + sb.Append(isValues ? "(" : "SELECT "); var colidx2 = 0; foreach (var col in _table.Columns.Values) { @@ -452,7 +455,7 @@ namespace FreeSql.Internal.CommonProvider } ++colidx2; } - sb.Append(")"); + if (isValues) sb.Append(")"); ++didx; } if (_noneParameter && specialParams.Any()) diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index 018cb81a..14c5cff7 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -174,7 +174,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async protected Task RawExecuteAffrowsAsync() + async protected virtual Task RawExecuteAffrowsAsync() { var sql = ToSql(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index dcd41e7d..da09a6ab 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -21,9 +21,34 @@ namespace FreeSql.Odbc.SqlServer public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); + protected override int RawExecuteAffrows() + { + var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return affrows; + } protected override long RawExecuteIdentity() { - var sql = this.ToSql(); + var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); @@ -47,10 +72,10 @@ namespace FreeSql.Odbc.SqlServer } return ret; } - protected override List RawExecuteInserted() { - var sql = this.ToSql(); + var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); @@ -63,10 +88,20 @@ namespace FreeSql.Odbc.SqlServer ++colidx; } - var validx = sql.IndexOf(") VALUES"); - if (validx == -1) throw new ArgumentException("找不到 VALUES"); - sb.Insert(0, sql.Substring(0, validx + 1)); - sb.Append(sql.Substring(validx + 1)); + if (versionGreaterThan10) + { + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException("找不到 VALUES"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } + else + { + var validx = sql.IndexOf(") SELECT "); + if (validx == -1) throw new ArgumentException("找不到 SELECT"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); @@ -95,11 +130,35 @@ namespace FreeSql.Odbc.SqlServer public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); - - + + async protected override Task RawExecuteAffrowsAsync() + { + var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return affrows; + } async protected override Task RawExecuteIdentityAsync() { - var sql = this.ToSql(); + var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); @@ -125,7 +184,8 @@ namespace FreeSql.Odbc.SqlServer } async protected override Task> RawExecuteInsertedAsync() { - var sql = this.ToSql(); + var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); @@ -138,10 +198,20 @@ namespace FreeSql.Odbc.SqlServer ++colidx; } - var validx = sql.IndexOf(") VALUES"); - if (validx == -1) throw new ArgumentException("找不到 VALUES"); - sb.Insert(0, sql.Substring(0, validx + 1)); - sb.Append(sql.Substring(validx + 1)); + if (versionGreaterThan10) + { + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException("找不到 VALUES"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } + else + { + var validx = sql.IndexOf(") SELECT "); + if (validx == -1) throw new ArgumentException("找不到 SELECT"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index d8cd5f74..6403f544 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -106,27 +106,29 @@ ELSE protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); - var database = conn.Value.Database; - Func ExecuteScalar = (db, sql) => - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); - try - { - using (var cmd = conn.Value.CreateCommand()) - { - cmd.CommandText = sql; - cmd.CommandType = CommandType.Text; - return cmd.ExecuteScalar(); - } - } - finally - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); - } - }; - var sb = new StringBuilder(); + string database = null; try { + database = conn.Value.Database; + Func ExecuteScalar = (db, sql) => + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + }; + var sb = new StringBuilder(); + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -243,10 +245,9 @@ a.name 'Column' else '' end as 'SqlType' ,case when a.is_nullable = 1 then '1' else '0' end 'IsNullable' ,case when a.is_identity = 1 then '1' else '0' end 'IsIdentity' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'Comment' from sys.columns a inner join sys.types b on b.user_type_id = a.user_type_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id where a.object_id in (object_id(N'[{1}].[{2}]')); @@ -377,7 +378,8 @@ use " + database, tboldname ?? tbname); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); } - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); + if ((_commonUtils as OdbcSqlServerUtils).ServerVersion > 9) //SqlServer 2008+ + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" ("); @@ -426,7 +428,8 @@ use " + database, tboldname ?? tbname); { try { - conn.Value.ChangeDatabase(database); + if (string.IsNullOrEmpty(database) == false) + conn.Value.ChangeDatabase(database); _orm.Ado.MasterPool.Return(conn); } catch diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index b24afe4a..bf94f966 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -130,32 +130,29 @@ select a.Object_id ,b.name 'Owner' ,a.name 'Name' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'Comment' ,'TABLE' type from sys.tables a inner join sys.schemas b on b.schema_id = a.schema_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' where not(b.name = 'dbo' and a.name = 'sysdiagrams') union all select a.Object_id ,b.name 'Owner' ,a.name 'Name' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'Comment' ,'VIEW' type from sys.views a inner join sys.schemas b on b.schema_id = a.schema_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' union all select a.Object_id ,b.name 'Owner' ,a.name 'Name' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'Comment' ,'StoreProcedure' type from sys.procedures a inner join sys.schemas b on b.schema_id = a.schema_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' where a.type = 'P' and charindex('diagram', a.name) = 0 order by type desc, b.name, a.name ; @@ -241,10 +238,9 @@ isnull(e.name,'') + '.' + isnull(d.name,'') else cast(a.max_length as varchar) end + ')' when b.name in ('Numeric', 'Decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')' else '' end as 'SqlType' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'Comment' {0} a inner join sys.types b on b.user_type_id = a.user_type_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id where {1} @@ -257,8 +253,8 @@ from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); { sql += "union all" + string.Format(tsql_place.Replace( - "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id", - "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @" + "select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id", + "select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index 8af1881a..58c63d56 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -42,7 +42,7 @@ namespace FreeSql.Odbc.SqlServer { try { - (this.InternalCommonUtils as OdbcSqlServerUtils).IsSelectRowNumber = int.Parse(conn.Value.ServerVersion.Split('.')[0]) <= 10; + (this.InternalCommonUtils as OdbcSqlServerUtils).ServerVersion = int.Parse(conn.Value.ServerVersion.Split('.')[0]); } catch { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index 7466fe40..844b735f 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -17,7 +17,9 @@ namespace FreeSql.Odbc.SqlServer { } - public bool IsSelectRowNumber = true; + public bool IsSelectRowNumber => ServerVersion <= 10; + public bool IsSqlServer2005 => ServerVersion == 9; + public int ServerVersion = 0; public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 4c543635..73f2f92f 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Linq; using System.Text; using System.Threading.Tasks; @@ -21,9 +22,34 @@ namespace FreeSql.SqlServer.Curd public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); + protected override int RawExecuteAffrows() + { + var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return affrows; + } protected override long RawExecuteIdentity() { - var sql = this.ToSql(); + var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); @@ -49,7 +75,8 @@ namespace FreeSql.SqlServer.Curd } protected override List RawExecuteInserted() { - var sql = this.ToSql(); + var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql(): this.ToSqlValuesOrSelectUnionAll(false); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); @@ -62,10 +89,20 @@ namespace FreeSql.SqlServer.Curd ++colidx; } - var validx = sql.IndexOf(") VALUES"); - if (validx == -1) throw new ArgumentException("找不到 VALUES"); - sb.Insert(0, sql.Substring(0, validx + 1)); - sb.Append(sql.Substring(validx + 1)); + if (versionGreaterThan10) + { + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException("找不到 VALUES"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } + else + { + var validx = sql.IndexOf(") SELECT "); + if (validx == -1) throw new ArgumentException("找不到 SELECT"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); @@ -95,9 +132,34 @@ namespace FreeSql.SqlServer.Curd public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + async protected override Task RawExecuteAffrowsAsync() + { + var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return affrows; + } async protected override Task RawExecuteIdentityAsync() { - var sql = this.ToSql(); + var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); @@ -123,7 +185,8 @@ namespace FreeSql.SqlServer.Curd } async protected override Task> RawExecuteInsertedAsync() { - var sql = this.ToSql(); + var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; + var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); @@ -136,10 +199,20 @@ namespace FreeSql.SqlServer.Curd ++colidx; } - var validx = sql.IndexOf(") VALUES"); - if (validx == -1) throw new ArgumentException("找不到 VALUES"); - sb.Insert(0, sql.Substring(0, validx + 1)); - sb.Append(sql.Substring(validx + 1)); + if (versionGreaterThan10) + { + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException("找不到 VALUES"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } + else + { + var validx = sql.IndexOf(") SELECT "); + if (validx == -1) throw new ArgumentException("找不到 SELECT"); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index bcc14338..44747d23 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -109,27 +109,29 @@ ELSE protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); - var database = conn.Value.Database; - Func ExecuteScalar = (db, sql) => - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); - try - { - using (var cmd = conn.Value.CreateCommand()) - { - cmd.CommandText = sql; - cmd.CommandType = CommandType.Text; - return cmd.ExecuteScalar(); - } - } - finally - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); - } - }; - var sb = new StringBuilder(); + string database = null; try { + database = conn.Value.Database; + Func ExecuteScalar = (db, sql) => + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + }; + var sb = new StringBuilder(); + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -246,10 +248,9 @@ a.name 'Column' else '' end as 'SqlType' ,case when a.is_nullable = 1 then '1' else '0' end 'IsNullable' ,case when a.is_identity = 1 then '1' else '0' end 'IsIdentity' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'Comment' from sys.columns a inner join sys.types b on b.user_type_id = a.user_type_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id where a.object_id in (object_id(N'[{1}].[{2}]')); @@ -380,7 +381,8 @@ use " + database, tboldname ?? tbname); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); } - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); + if ((_commonUtils as SqlServerUtils).ServerVersion > 9) //SqlServer 2008+ + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" ("); @@ -429,7 +431,8 @@ use " + database, tboldname ?? tbname); { try { - conn.Value.ChangeDatabase(database); + if (string.IsNullOrEmpty(database) == false) + conn.Value.ChangeDatabase(database); _orm.Ado.MasterPool.Return(conn); } catch diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 0a53e4f9..2be0a2e9 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -133,32 +133,29 @@ select a.Object_id ,b.name 'Owner' ,a.name 'Name' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'Comment' ,'TABLE' type from sys.tables a inner join sys.schemas b on b.schema_id = a.schema_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' where not(b.name = 'dbo' and a.name = 'sysdiagrams') union all select a.Object_id ,b.name 'Owner' ,a.name 'Name' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'Comment' ,'VIEW' type from sys.views a inner join sys.schemas b on b.schema_id = a.schema_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' union all select a.Object_id ,b.name 'Owner' ,a.name 'Name' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'Comment' ,'StoreProcedure' type from sys.procedures a inner join sys.schemas b on b.schema_id = a.schema_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = 0 AND c.name = 'MS_Description' where a.type = 'P' and charindex('diagram', a.name) = 0 order by type desc, b.name, a.name ; @@ -244,10 +241,9 @@ isnull(e.name,'') + '.' + isnull(d.name,'') else cast(a.max_length as varchar) end + ')' when b.name in ('Numeric', 'Decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')' else '' end as 'SqlType' -,c.value +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'Comment' {0} a inner join sys.types b on b.user_type_id = a.user_type_id -left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id where {1} @@ -260,8 +256,8 @@ from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); { sql += "union all" + string.Format(tsql_place.Replace( - "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id", - "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @" + "select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id", + "select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index d5d87938..3efeae05 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -43,7 +43,7 @@ namespace FreeSql.SqlServer { try { - (this.InternalCommonUtils as SqlServerUtils).IsSelectRowNumber = int.Parse(conn.Value.ServerVersion.Split('.')[0]) <= 10; + (this.InternalCommonUtils as SqlServerUtils).ServerVersion = int.Parse(conn.Value.ServerVersion.Split('.')[0]); } catch { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 0c94f33e..e8b51ee5 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -17,7 +17,9 @@ namespace FreeSql.SqlServer { } - public bool IsSelectRowNumber = true; + public bool IsSelectRowNumber => ServerVersion <= 10; + public bool IsSqlServer2005 => ServerVersion == 9; + public int ServerVersion = 0; public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { From f7474c6e697bb95f0d08c6766b0c569f5f510733 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 19 Nov 2019 00:45:10 +0800 Subject: [PATCH 0255/1029] ## v0.11.21 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 59d67193..698bda6a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.20 + 0.11.21 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index eee0aa50..320fd7ef 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 180f806d..7fc0f8d4 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 10e0ada5..0f12df2c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0d81647e..31d71c12 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.20 + 0.11.21 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index bd744483..0ef262cb 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 8bb682b3..bbe766fa 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 50045c53..b8718e60 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index afd125b9..a5fdac25 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 641489ed..fe998940 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 91df3399..ec422203 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c11692ce..bdb70f84 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c0966dcc..efc17091 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.20 + 0.11.21 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From b338efc8a2c43267b9db5746861a61e184583ecf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 19 Nov 2019 12:14:56 +0800 Subject: [PATCH 0256/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20MySql=20?= =?UTF-8?q?=E7=89=B9=E6=9C=89=E5=8A=9F=E8=83=BD=20Insert=20Ignore=20Into?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 25 +++- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + .../FreeSql.Tests.Provider.Odbc/g.cs | 1 + .../MySql/Curd/MySqlInsertTest.cs | 23 +++ FreeSql.Tests/FreeSql.Tests/g.cs | 1 + FreeSql/FreeSql.xml | 131 ------------------ .../Curd/MySqlInsert.cs | 8 ++ .../FreeSql.Provider.MySql/MySqlExtensions.cs | 14 ++ .../Curd/SqlServerInsert.cs | 63 ++------- 9 files changed, 84 insertions(+), 189 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 7312f114..95dfcc5a 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -26,17 +26,32 @@ namespace base_entity public T Config { get; set; } } + public class Products : BaseEntity + { + public string title { get; set; } + } + static void Main(string[] args) { #region 初始化 IFreeSql - BaseEntity.Initialization(new FreeSql.FreeSqlBuilder() + var fsql = new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) .UseNoneCommandParameter(true) .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=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=2") - .Build()); + //.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=2") + .Build(); + BaseEntity.Initialization(fsql); #endregion + new Products { title = "product-1" }.Save(); + new Products { title = "product-2" }.Save(); + new Products { title = "product-3" }.Save(); + new Products { title = "product-4" }.Save(); + new Products { title = "product-5" }.Save(); + + var items1 = Products.Select.Limit(10).OrderByDescending(a => a.CreateTime).ToList(); + var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); + BaseEntity.Orm.UseJsonMap(); new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); @@ -44,6 +59,8 @@ namespace base_entity new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" } }.Save(); var testconfigs11 = S_SysConfig.Select.ToList(); + var repo = BaseEntity.Orm.Select().Limit(10).ToList(); + Task.Run(async () => { using (var uow = BaseEntity.Begin()) @@ -111,6 +128,8 @@ namespace base_entity }).Wait(); + + Console.WriteLine("按任意键结束。。。"); Console.ReadKey(); } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c0597d5..1a43f59e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -106,6 +106,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index e1ba8a33..3f1e5f78 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -18,6 +18,7 @@ public class g static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.OdbcSqlServer, "Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Max pool size=3") + //.UseConnectionString(FreeSql.DataType.OdbcSqlServer, "Driver={SQL Server};Server=192.168.164.129;Persist Security Info=False;Trusted_Connection=Yes;UID=sa;PWD=123456;DATABASE=ds_shop;") .UseAutoSyncStructure(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs index d0e746de..4e1c40ae 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs @@ -129,6 +129,29 @@ namespace FreeSql.Tests.MySql //insert.AppendData(items.First()).ExecuteInserted(); } + [Fact] + public void MySqlIgnoreInto() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.MySqlIgnoreInto().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.MySqlIgnoreInto().AppendData(items).ExecuteAffrows()); + + Assert.Equal(1, g.mysql.Insert().MySqlIgnoreInto().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); + Assert.Equal(1, g.mysql.Insert().MySqlIgnoreInto().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + + items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.MySqlIgnoreInto().AppendData(items.First()).ExecuteIdentity()); + + var id = g.mysql.Insert().MySqlIgnoreInto().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + id = g.mysql.Insert().MySqlIgnoreInto().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] public void AsTable() { diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 6efd2d1e..2fe6231a 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -35,6 +35,7 @@ public class g static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;Max Pool Size=3") .UseAutoSyncStructure(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index dd964856..ff488d7c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2000,137 +2000,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index c49a4597..20af4f0b 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -17,6 +17,7 @@ namespace FreeSql.MySql.Curd { } + internal bool InternalIsIgnoreInto = false; internal IFreeSql InternalOrm => _orm; internal TableInfo InternalTable => _table; internal DbParameter[] InternalParams => _params; @@ -33,6 +34,13 @@ namespace FreeSql.MySql.Curd public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override string ToSql() + { + if (InternalIsIgnoreInto == false) return base.ToSqlValuesOrSelectUnionAll(); + var sql = base.ToSqlValuesOrSelectUnionAll(); + return $"INSERT IGNORE INTO {sql.Substring(12)}"; + } + protected override long RawExecuteIdentity() { var sql = this.ToSql(); diff --git a/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs b/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs index 262aa716..40e19c5f 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExtensions.cs @@ -1,5 +1,6 @@ using FreeSql; using FreeSql.MySql.Curd; +using System; public static partial class FreeSqlMySqlGlobalExtensions { @@ -22,4 +23,17 @@ public static partial class FreeSqlMySqlGlobalExtensions /// public static OnDuplicateKeyUpdate OnDuplicateKeyUpdate(this IInsert that) where T1 : class => new FreeSql.MySql.Curd.OnDuplicateKeyUpdate(that.InsertIdentity()); + /// + /// MySql 特有的功能,Insert Ignore Into + /// + /// + /// + /// + public static IInsert MySqlIgnoreInto(this IInsert that) where T1 : class + { + var _mysqlInsert = that as MySqlInsert; + if (_mysqlInsert == null) throw new Exception("MySqlIgnoreInto 是 FreeSql.Provider.MySql/FreeSql.Provider.MySqlConnector 特有的功能"); + _mysqlInsert.InternalIsIgnoreInto = true; + return that; + } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 73f2f92f..a8432057 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -22,34 +22,14 @@ namespace FreeSql.SqlServer.Curd public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); - protected override int RawExecuteAffrows() + public override string ToSql() { var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try - { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return affrows; + return this.ToSqlValuesOrSelectUnionAll(versionGreaterThan10); } protected override long RawExecuteIdentity() { - var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); @@ -75,8 +55,7 @@ namespace FreeSql.SqlServer.Curd } protected override List RawExecuteInserted() { - var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql(): this.ToSqlValuesOrSelectUnionAll(false); + var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); @@ -89,7 +68,7 @@ namespace FreeSql.SqlServer.Curd ++colidx; } - if (versionGreaterThan10) + if ((_commonUtils as SqlServerUtils).ServerVersion > 10) { var validx = sql.IndexOf(") VALUES"); if (validx == -1) throw new ArgumentException("找不到 VALUES"); @@ -132,34 +111,9 @@ namespace FreeSql.SqlServer.Curd public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); - async protected override Task RawExecuteAffrowsAsync() - { - var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try - { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - return affrows; - } async protected override Task RawExecuteIdentityAsync() { - var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); @@ -185,8 +139,7 @@ namespace FreeSql.SqlServer.Curd } async protected override Task> RawExecuteInsertedAsync() { - var versionGreaterThan10 = (_commonUtils as SqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); @@ -199,7 +152,7 @@ namespace FreeSql.SqlServer.Curd ++colidx; } - if (versionGreaterThan10) + if ((_commonUtils as SqlServerUtils).ServerVersion > 10) { var validx = sql.IndexOf(") VALUES"); if (validx == -1) throw new ArgumentException("找不到 VALUES"); From efdc7c8c5d84dc6f81f0c44b9a538f7f5ad0b84e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 20 Nov 2019 03:34:55 +0800 Subject: [PATCH 0257/1029] =?UTF-8?q?-=20=E5=85=BC=E5=AE=B9=20SqlServer=20?= =?UTF-8?q?varchar/nvarchar=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E5=88=86=E5=88=AB=E8=A7=A3=E6=9E=90=E4=B8=BA?= =?UTF-8?q?=EF=BC=9AN''=20=E5=92=8C=20''=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - .../SqlServerExpression/OtherTest.cs | 61 +++++++- .../SqlServerExpression/StringTest.cs | 135 ++++++++++++++++++ FreeSql/FreeSql.xml | 131 +++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 54 ++++--- .../AdoProvider/AdoProviderUtils.cs | 7 +- .../MySqlAdo/MySqlAdo.cs | 5 +- .../FreeSql.Provider.MySql/MySqlExpression.cs | 6 +- .../Default/OdbcAdapter.cs | 5 +- .../Default/OdbcAdo/OdbcAdo.cs | 7 +- .../Default/OdbcExpression.cs | 6 +- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 5 +- .../MySql/OdbcMySqlExpression.cs | 6 +- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 5 +- .../Oracle/OdbcOracleExpression.cs | 6 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 5 +- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 6 +- .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 12 +- .../SqlServer/OdbcSqlServerExpression.cs | 6 +- .../OracleAdo/OracleAdo.cs | 5 +- .../OracleExpression.cs | 6 +- .../PostgreSQLAdo/PostgreSQLAdo.cs | 5 +- .../PostgreSQLExpression.cs | 6 +- .../SqlServerAdo/SqlServerAdo.cs | 12 +- .../SqlServerExpression.cs | 6 +- .../SqliteAdo/SqliteAdo.cs | 5 +- .../SqliteExpression.cs | 6 +- 27 files changed, 440 insertions(+), 86 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 1a43f59e..9c0597d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -106,13 +106,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs index 97562143..459fc7bf 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs @@ -105,9 +105,65 @@ namespace FreeSql.Tests.SqlServerExpression var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + //nvarchar + IEnumerable stringlinqlist = new List(new[] { "a1", "a2", "a3" }); + var ntestlinq = select.Where(a => stringlinqlist.Contains(a.testFieldString)).ToList(); + + //in not in + var nsql111 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + var nsql112 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldString) == false).ToList(); + var nsql113 = select.Where(a => !new[] { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + + var ninarray = new[] { "a1", "a2", "a3" }; + var nsql1111 = select.Where(a => ninarray.Contains(a.testFieldString)).ToList(); + var nsql1122 = select.Where(a => ninarray.Contains(a.testFieldString) == false).ToList(); + var nsql1133 = select.Where(a => !ninarray.Contains(a.testFieldString)).ToList(); + + //in not in + var nsql11111 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + var nsql11222 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldString) == false).ToList(); + var nsql11333 = select.Where(a => !new List() { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + + var nsql11111a = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString)).ToList(); + var nsql11222b = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString) == false).ToList(); + var nsql11333c = select.Where(a => !new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString)).ToList(); + + var ninarray2 = new List() { "a1", "a2", "a3" }; + var nsql111111 = select.Where(a => ninarray2.Contains(a.testFieldString)).ToList(); + var nsql112222 = select.Where(a => ninarray2.Contains(a.testFieldString) == false).ToList(); + var nsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldString)).ToList(); + + //varchar + IEnumerable vstringlinqlist = new List(new[] { "a1", "a2", "a3" }); + var vtestlinq = select.Where(a => vstringlinqlist.Contains(a.testFieldStringVarchar)).ToList(); + + //in not in + var vsql111 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + var vsql112 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql113 = select.Where(a => !new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray = new[] { "a1", "a2", "a3" }; + var vsql1111 = select.Where(a => ninarray.Contains(a.testFieldStringVarchar)).ToList(); + var vsql1122 = select.Where(a => ninarray.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql1133 = select.Where(a => !ninarray.Contains(a.testFieldStringVarchar)).ToList(); + + //in not in + var vsql11111 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + var vsql11222 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql11333 = select.Where(a => !new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + + var vsql11111a = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar)).ToList(); + var vsql11222b = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql11333c = select.Where(a => !new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray2 = new List() { "a1", "a2", "a3" }; + var vsql111111 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar)).ToList(); + var vsql112222 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldStringVarchar)).ToList(); } - [Table(Name = "tb_alltype")] + [Table(Name = "tb_alltypeOther")] class TableAllType { [Column(IsIdentity = true, IsPrimary = true)] @@ -131,6 +187,9 @@ namespace FreeSql.Tests.SqlServerExpression public DateTimeOffset testFieldDateTimeOffset { get; set; } public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + + [Column(DbType = "varchar(255)")] + public string testFieldStringVarchar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index c0272fa8..ecdadd3b 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -29,6 +29,8 @@ namespace FreeSql.Tests.SqlServerExpression public int TypeGuid { get; set; } public TestTypeInfo Type { get; set; } public string Title { get; set; } + [Column(DbType = "varchar(255)")] + public string TitleVarchar { get; set; } public DateTime CreateTime { get; set; } } class TestTypeInfo @@ -56,7 +58,11 @@ namespace FreeSql.Tests.SqlServerExpression { var list = new List(); list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(select.Where(a => a.TitleVarchar.Equals("aaa")).ToList()); list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + + list.Add(select.Where(a => a.Title == "aaa").ToList()); + list.Add(select.Where(a => a.TitleVarchar == "aaa").ToList()); } [Fact] @@ -64,6 +70,7 @@ namespace FreeSql.Tests.SqlServerExpression { var data = new List(); data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + data.Add(select.Where(a => (a.TitleVarchar ?? "") == string.Empty).ToSql()); } [Fact] @@ -79,6 +86,16 @@ namespace FreeSql.Tests.SqlServerExpression list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => a.TitleVarchar.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.TitleVarchar.StartsWith(a.TitleVarchar)).ToList()); + list.Add(select.Where(a => a.TitleVarchar.StartsWith(a.TitleVarchar + 1)).ToList()); + list.Add(select.Where(a => a.TitleVarchar.StartsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.TitleVarchar + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").StartsWith(a.TitleVarchar)).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").StartsWith(a.TitleVarchar + 1)).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").StartsWith(a.Type.Name)).ToList()); } [Fact] public void EndsWith() @@ -93,6 +110,16 @@ namespace FreeSql.Tests.SqlServerExpression list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => a.TitleVarchar.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.TitleVarchar.EndsWith(a.TitleVarchar)).ToList()); + list.Add(select.Where(a => a.TitleVarchar.EndsWith(a.TitleVarchar + 1)).ToList()); + list.Add(select.Where(a => a.TitleVarchar.EndsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.TitleVarchar + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").EndsWith(a.TitleVarchar)).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").EndsWith(a.TitleVarchar + 1)).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").EndsWith(a.Type.Name)).ToList()); } [Fact] public void Contains() @@ -107,6 +134,16 @@ namespace FreeSql.Tests.SqlServerExpression list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + + list.Add(select.Where(a => a.TitleVarchar.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.TitleVarchar.Contains(a.TitleVarchar)).ToList()); + list.Add(select.Where(a => a.TitleVarchar.Contains(a.TitleVarchar + 1)).ToList()); + list.Add(select.Where(a => a.TitleVarchar.Contains(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.TitleVarchar + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").Contains(a.TitleVarchar)).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").Contains(a.TitleVarchar + 1)).ToList()); + list.Add(select.Where(a => (a.TitleVarchar + "aaa").Contains(a.Type.Name)).ToList()); } [Fact] public void ToLower() @@ -121,6 +158,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.TitleVarchar.ToLower() == a.TitleVarchar).ToList()); + data.Add(select.Where(a => a.TitleVarchar.ToLower() == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => a.TitleVarchar.ToLower() == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.TitleVarchar.ToLower() + "aaa").ToLower() == a.TitleVarchar).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.ToLower() + "aaa").ToLower() == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); } [Fact] public void ToUpper() @@ -135,6 +182,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.TitleVarchar.ToUpper() == a.TitleVarchar).ToList()); + data.Add(select.Where(a => a.TitleVarchar.ToUpper() == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => a.TitleVarchar.ToUpper() == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.TitleVarchar.ToUpper() + "aaa").ToUpper() == a.TitleVarchar).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.ToUpper() + "aaa").ToUpper() == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); } [Fact] public void Substring() @@ -149,6 +206,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.TitleVarchar.Substring(0) == a.TitleVarchar).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Substring(0) == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Substring(0) == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar.Substring(0) + "aaa").Substring(a.TitleVarchar.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Substring(0) + "aaa").Substring(0, a.TitleVarchar.Length) == a.TitleVarchar).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Substring(0) + "aaa").Substring(0, 3) == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); } [Fact] public void Length() @@ -163,6 +230,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.Length == 0).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Length == 1).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Length == a.TitleVarchar.Length + 1).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Length == a.Type.Name.Length).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.TitleVarchar + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.TitleVarchar + "aaa").Length == a.TitleVarchar.Length + 1).ToList()); + data.Add(select.Where(a => (a.TitleVarchar + "aaa").Length == a.Type.Name.Length).ToList()); } [Fact] public void IndexOf() @@ -177,6 +254,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.TitleVarchar.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.TitleVarchar.IndexOf("aaa", 2) == (a.TitleVarchar.Length + 1)).ToList()); + data.Add(select.Where(a => a.TitleVarchar.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.TitleVarchar + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.TitleVarchar + "aaa").IndexOf("aaa", 2) == (a.TitleVarchar.Length + 1)).ToList()); + data.Add(select.Where(a => (a.TitleVarchar + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); } [Fact] public void PadLeft() @@ -219,6 +306,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.TitleVarchar.Trim('a') == a.TitleVarchar).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Trim('a', 'b') == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Trim('a') + "aaa").Trim('a') == a.TitleVarchar).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); } [Fact] public void TrimStart() @@ -233,6 +330,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.TitleVarchar.TrimStart('a') == a.TitleVarchar).ToList()); + data.Add(select.Where(a => a.TitleVarchar.TrimStart('a', 'b') == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => a.TitleVarchar.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.TitleVarchar.TrimStart('a') + "aaa").TrimStart('a') == a.TitleVarchar).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); } [Fact] public void TrimEnd() @@ -247,6 +354,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.TitleVarchar.TrimEnd('a') == a.TitleVarchar).ToList()); + data.Add(select.Where(a => a.TitleVarchar.TrimEnd('a', 'b') == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => a.TitleVarchar.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.TitleVarchar.TrimEnd('a') + "aaa").TrimEnd('a') == a.TitleVarchar).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); } [Fact] public void Replace() @@ -261,6 +378,16 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => a.TitleVarchar.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.TitleVarchar.Replace("a", "b").Replace("b", "c") == a.TitleVarchar).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => a.TitleVarchar.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.TitleVarchar.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.TitleVarchar).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.TitleVarchar + 1)).ToList()); + data.Add(select.Where(a => (a.TitleVarchar.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); } [Fact] public void CompareTo() @@ -284,6 +411,10 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + + data.Add(select.Where(a => string.IsNullOrEmpty(a.TitleVarchar)).ToList()); + //data.Add(select.Where(a => string.IsNullOrEmpty(a.TitleVarchar) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.TitleVarchar)).ToList()); } [Fact] @@ -293,6 +424,10 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.TitleVarchar)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.TitleVarchar) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.TitleVarchar)).ToList()); } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ff488d7c..dd964856 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2000,6 +2000,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 }) + + + + + + 可自定义解析表达式 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b83db6ff..759aaf19 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -332,7 +332,7 @@ namespace FreeSql.Internal var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table }); var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - return $"{sql} = {formatSql(true, null)}"; + return $"{sql} = {formatSql(true, null, null)}"; if (isBool) return GetBoolString(sql); return sql; @@ -343,7 +343,7 @@ namespace FreeSql.Internal var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - return $"{sql} = {formatSql(true, null)}"; + return $"{sql} = {formatSql(true, null, null)}"; if (isBool) return GetBoolString(sql); return sql; @@ -355,7 +355,7 @@ namespace FreeSql.Internal var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - sql = $"{sql} = {formatSql(true, null)}"; + sql = $"{sql} = {formatSql(true, null, null)}"; if (isBool) sql = GetBoolString(sql); @@ -433,7 +433,7 @@ namespace FreeSql.Internal { var enumType = leftMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) - right = formatSql(Enum.Parse(enumType, right.StartsWith("N'") ? right.Substring(1).Trim('\'') : right.Trim('\'')), leftMapColumn.Attribute.MapType); + right = formatSql(Enum.Parse(enumType, right.StartsWith("N'") ? right.Substring(1).Trim('\'') : right.Trim('\'')), leftMapColumn.Attribute.MapType, leftMapColumn); } if (leftMapColumn == null) { @@ -447,7 +447,7 @@ namespace FreeSql.Internal { var enumType = rightMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) - left = formatSql(Enum.Parse(enumType, left.StartsWith("N'") ? left.Substring(1).Trim('\'') : left.Trim('\'')), rightMapColumn.Attribute.MapType); + left = formatSql(Enum.Parse(enumType, left.StartsWith("N'") ? left.Substring(1).Trim('\'') : left.Trim('\'')), rightMapColumn.Attribute.MapType, rightMapColumn); } } } @@ -455,8 +455,8 @@ namespace FreeSql.Internal { if (oper == "=") { - var trueVal = formatSql(true, null); - var falseVal = formatSql(false, null); + var trueVal = formatSql(true, null, null); + var falseVal = formatSql(false, null, null); if (left == trueVal) return right; else if (left == falseVal) return $"not({right})"; else if (right == trueVal) return left; @@ -464,15 +464,14 @@ namespace FreeSql.Internal } else if (oper == "<>") { - var trueVal = formatSql(true, null); - var falseVal = formatSql(false, null); + var trueVal = formatSql(true, null, null); + var falseVal = formatSql(false, null, null); if (left == trueVal) return $"not({right})"; else if (left == falseVal) return right; else if (right == trueVal) return $"not({left})"; else if (right == falseVal) return left; } } - if (left == "NULL") { var tmp = right; @@ -488,9 +487,9 @@ namespace FreeSql.Internal break; case "AND": case "OR": - if (leftMapColumn != null) left = $"{left} = {formatSql(true, null)}"; + if (leftMapColumn != null) left = $"{left} = {formatSql(true, null, null)}"; else left = GetBoolString(left); - if (rightMapColumn != null) right = $"{right} = {formatSql(true, null)}"; + if (rightMapColumn != null) right = $"{right} = {formatSql(true, null, null)}"; else right = GetBoolString(right); break; } @@ -517,7 +516,7 @@ namespace FreeSql.Internal if (notBody.Contains(" IS NOT NULL")) return notBody.Replace(" IS NOT NULL", " IS NULL"); if (notBody.Contains("=")) return notBody.Replace("=", "!="); if (notBody.Contains("!=")) return notBody.Replace("!=", "="); - return $"{notBody} = {formatSql(false, null)}"; + return $"{notBody} = {formatSql(false, null, null)}"; } return $"not({ExpressionLambdaToSql(notExp, tsc)})"; case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); @@ -529,7 +528,7 @@ namespace FreeSql.Internal return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Negate: case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); - case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType); + case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp); case ExpressionType.Conditional: var condExp = exp as ConditionalExpression; return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end"; @@ -855,7 +854,7 @@ namespace FreeSql.Internal //} other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; - if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType); + if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp); throw new Exception($"未实现函数表达式 {exp3} 解析"); case ExpressionType.Parameter: case ExpressionType.MemberAccess: @@ -915,7 +914,7 @@ namespace FreeSql.Internal } break; } - if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType); + if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp); if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { @@ -942,7 +941,7 @@ namespace FreeSql.Internal tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = curcol }); var name = curcol.Attribute.Name; if (tsc.isQuoteName) name = _common.QuoteSqlName(name); - tsc.mapTypeTmp = curcol.Attribute.MapType == curcol.CsType ? null : curcol.Attribute.MapType; + tsc.SetMapColumnTmp(curcol); if (string.IsNullOrEmpty(tsc.alias001)) return name; return $"{tsc.alias001}.{name}"; } @@ -1104,7 +1103,7 @@ namespace FreeSql.Internal return ""; } name2 = col2.Attribute.Name; - tsc.mapTypeTmp = col2.Attribute.MapType == col2.CsType ? null : col2.Attribute.MapType; + tsc.SetMapColumnTmp(col2); break; case ExpressionType.Call: break; } @@ -1126,7 +1125,7 @@ namespace FreeSql.Internal } if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false) { - if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType); + if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp); return ""; } return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc); @@ -1157,13 +1156,24 @@ namespace FreeSql.Internal public ExpressionStyle style { get; set; } public Type mapType { get; set; } public Type mapTypeTmp { get; set; } + public ColumnInfo mapColumnTmp { get; set; } public TableInfo currentTable { get; set; } public List whereCascadeExpression { get; set; } public string alias001 { get; set; } //单表字段的表别名 - public void SetMapTypeTmp(Type newValue) + public ExpTSC SetMapColumnTmp(ColumnInfo col) { - this.mapTypeTmp = null; + if (col == null) + { + this.mapTypeTmp = null; + this.mapColumnTmp = null; + } + else + { + this.mapTypeTmp = col.Attribute.MapType == col.CsType ? null : col.Attribute.MapType; + this.mapColumnTmp = col; + } + return this; } public Type SetMapTypeReturnOld(Type newValue) { @@ -1263,6 +1273,6 @@ namespace FreeSql.Internal } } - public string formatSql(object obj, Type mapType) => string.Concat(_ado.AddslashesProcessParam(obj, mapType)); + public string formatSql(object obj, Type mapType, ColumnInfo mapColumn) => string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn)); } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs index 4d5aae64..56c43677 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Concurrent; using System.Text.RegularExpressions; @@ -6,7 +7,7 @@ namespace FreeSql.Internal.CommonProvider { partial class AdoProvider { - public abstract object AddslashesProcessParam(object param, Type mapType); + public abstract object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn); public string Addslashes(string filter, params object[] parms) { if (filter == null || parms == null) return string.Empty; @@ -17,7 +18,7 @@ namespace FreeSql.Internal.CommonProvider if (parms[a] == null) filter = _dicAddslashesReplaceIsNull.GetOrAdd(a, b => new Regex(@"\s*(=|IN)\s*\{" + b + @"\}", RegexOptions.IgnoreCase | RegexOptions.Compiled)) .Replace(filter, $" IS {{{a}}}"); - nparms[a] = AddslashesProcessParam(parms[a], null); + nparms[a] = AddslashesProcessParam(parms[a], null, null); } try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index e061fe23..602ed684 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using MySql.Data.MySqlClient; using SafeObjectPool; using System; @@ -28,7 +29,7 @@ namespace FreeSql.MySql } } static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -51,7 +52,7 @@ namespace FreeSql.MySql { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index b795dbaf..2f3f78a8 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -101,11 +101,11 @@ namespace FreeSql.MySql if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs index 6eade116..ddddb518 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Text; @@ -43,7 +44,7 @@ namespace FreeSql.Odbc.Default public virtual char QuoteSqlNameRight => ']'; public virtual string FieldSql(Type type, string columnName) => columnName; - public virtual string UnicodeStringRawSql(object value) => value == null ? "NULL" : string.Concat("N'", value.ToString().Replace("'", "''"), "'"); + public virtual string UnicodeStringRawSql(object value, ColumnInfo mapColumn) => value == null ? "NULL" : string.Concat("N'", value.ToString().Replace("'", "''"), "'"); public virtual string DateTimeRawSql(object value) { if (value == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index b42c5b48..2d7a2b0e 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections; @@ -29,7 +30,7 @@ namespace FreeSql.Odbc.Default OdbcAdapter Adapter => (_util == null ? FreeSqlOdbcGlobalExtensions.DefaultOdbcAdapter : _util._orm.GetOdbcAdapter()); static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -37,7 +38,7 @@ namespace FreeSql.Odbc.Default if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string) - return Adapter.UnicodeStringRawSql(param); + return Adapter.UnicodeStringRawSql(param, mapColumn); else if (param is char) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); else if (param is Enum) @@ -52,7 +53,7 @@ namespace FreeSql.Odbc.Default { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs index 574455f7..4d2bf9ea 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -108,11 +108,11 @@ namespace FreeSql.Odbc.Default if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 0cd07d54..0aa06d1a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections; @@ -28,7 +29,7 @@ namespace FreeSql.Odbc.MySql } } static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -49,7 +50,7 @@ namespace FreeSql.Odbc.MySql { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 2bcd91b2..14bce855 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -101,11 +101,11 @@ namespace FreeSql.Odbc.MySql if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index 1bb9cfe0..6a3cd58b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections; @@ -27,7 +28,7 @@ namespace FreeSql.Odbc.Oracle } } static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -48,7 +49,7 @@ namespace FreeSql.Odbc.Oracle { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 1c9f08e4..651fbef3 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -101,11 +101,11 @@ namespace FreeSql.Odbc.Oracle if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index 0d7027a6..862ea601 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections; @@ -29,7 +30,7 @@ namespace FreeSql.Odbc.PostgreSQL } static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -50,7 +51,7 @@ namespace FreeSql.Odbc.PostgreSQL { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index cc7839cb..28da1107 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -130,11 +130,11 @@ namespace FreeSql.Odbc.PostgreSQL if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; case "Contains": - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); //判断 in 或 array @> array if (left.StartsWith("array[") || left.EndsWith("]")) return $"{args1} in ({left.Substring(6, left.Length - 7)})"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index 3920f4b6..4ee2b561 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -1,9 +1,11 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections; using System.Data.Common; using System.Data.Odbc; +using System.Linq; using System.Text; using System.Threading; @@ -26,8 +28,10 @@ namespace FreeSql.Odbc.SqlServer } } } + static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + string[] ncharDbTypes = new[] { "NVARCHAR", "NCHAR", "NTEXT" }; + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -35,7 +39,11 @@ namespace FreeSql.Odbc.SqlServer if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string) + { + if (mapColumn != null && mapColumn.CsType.NullableTypeOrThis() == typeof(string) && ncharDbTypes.Any(a => mapColumn.Attribute.DbType.Contains(a)) == false) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); + } else if (param is char) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); else if (param is Enum) @@ -58,7 +66,7 @@ namespace FreeSql.Odbc.SqlServer { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 74a752c9..7c1712bc 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -105,11 +105,11 @@ namespace FreeSql.Odbc.SqlServer if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 8c45bb19..424b8175 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using Oracle.ManagedDataAccess.Client; using SafeObjectPool; using System; @@ -27,7 +28,7 @@ namespace FreeSql.Oracle } } static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -48,7 +49,7 @@ namespace FreeSql.Oracle { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index a5f35911..818dff2b 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -101,11 +101,11 @@ namespace FreeSql.Oracle if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index eee3e5c9..ae3c9e3f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; using Npgsql; using SafeObjectPool; @@ -30,7 +31,7 @@ namespace FreeSql.PostgreSQL } static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList() || param is JToken || param is JObject || param is JArray)) @@ -67,7 +68,7 @@ namespace FreeSql.PostgreSQL { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 4507cebe..86760acc 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -160,11 +160,11 @@ namespace FreeSql.PostgreSQL if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; case "Contains": - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); //判断 in 或 array @> array if (left.StartsWith("array[") || left.EndsWith("]")) return $"{args1} in ({left.Substring(6, left.Length - 7)})"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index c6799a13..b6e43640 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -1,9 +1,11 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections; using System.Data.Common; using System.Data.SqlClient; +using System.Linq; using System.Text; using System.Threading; @@ -26,8 +28,10 @@ namespace FreeSql.SqlServer } } } + static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + static string[] ncharDbTypes = new[] { "NVARCHAR", "NCHAR", "NTEXT" }; + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -35,7 +39,11 @@ namespace FreeSql.SqlServer if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string) + { + if (mapColumn != null && mapColumn.CsType.NullableTypeOrThis() == typeof(string) && ncharDbTypes.Any(a => mapColumn.Attribute.DbType.Contains(a)) == false) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); + } else if (param is char) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); else if (param is Enum) @@ -58,7 +66,7 @@ namespace FreeSql.SqlServer { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index c775851f..85edc86a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -105,11 +105,11 @@ namespace FreeSql.SqlServer if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 9e27fc13..b8175943 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections; @@ -26,7 +27,7 @@ namespace FreeSql.Sqlite } } static DateTime dt1970 = new DateTime(1970, 1, 1); - public override object AddslashesProcessParam(object param, Type mapType) + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) @@ -47,7 +48,7 @@ namespace FreeSql.Sqlite { var sb = new StringBuilder(); var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType)); + foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index ce13a196..1c2f821d 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -101,11 +101,11 @@ namespace FreeSql.Sqlite if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { - tsc?.SetMapTypeTmp(null); + tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc?.SetMapTypeReturnOld(tsc?.mapTypeTmp); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); var left = objExp == null ? null : getExp(objExp); - tsc.SetMapTypeReturnOld(oldMapType); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); switch (callExp.Method.Name) { case "Contains": From 91f0bb92a1934535b0220aa25bb32de0e1d2ca59 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 20 Nov 2019 03:40:14 +0800 Subject: [PATCH 0258/1029] ## v0.11.22 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 287 ++++++++++-------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 15 files changed, 176 insertions(+), 144 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 698bda6a..ad09dcce 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.21 + 0.11.22 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 320fd7ef..15fda555 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7fc0f8d4..23094f25 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 0f12df2c..e6d05efb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c0597d5..1a43f59e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -106,6 +106,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 31d71c12..e4477bcb 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.21 + 0.11.22 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0ef262cb..3a0ce8a3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index dd964856..0f30703b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2000,137 +2000,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2841,3 +2710,159 @@ + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完将自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 事务体 () => {} + 超时,未执行完将自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index bbe766fa..2760f044 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index b8718e60..185252b7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a5fdac25..d5932514 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fe998940..6dbcee1f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ec422203..fd33300f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index bdb70f84..09c91574 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index efc17091..1114ce0b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.21 + 0.11.22 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From d42b2fc2b886d751d33217cafc63ba456db20c10 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 20 Nov 2019 13:32:49 +0800 Subject: [PATCH 0259/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ExpressionCa?= =?UTF-8?q?llAttribute=20=E7=89=B9=E6=80=A7=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=87=BD=E6=95=B0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E8=A7=A3=E6=9E=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 44 +++ .../ExpressionCallAttribute.cs | 28 ++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 10 + FreeSql/FreeSql.xml | 303 +++++++++--------- FreeSql/Internal/CommonExpression.cs | 36 +++ FreeSql/Internal/UtilsExpressionTree.cs | 5 +- 6 files changed, 266 insertions(+), 160 deletions(-) create mode 100644 FreeSql/DataAnnotations/ExpressionCallAttribute.cs diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 4a863174..431e8818 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -10,6 +10,7 @@ using Npgsql.LegacyPostgis; using System.Linq.Expressions; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; +using System.Threading; namespace FreeSql.Tests { @@ -167,6 +168,34 @@ namespace FreeSql.Tests [Fact] public void Test02() { + g.mysql.Aop.ParseExpression = (s, e) => + { + if (e.Expression.NodeType == ExpressionType.Call) + { + var callExp = e.Expression as MethodCallExpression; + if (callExp.Object?.Type == typeof(DateTime) && + callExp.Method.Name == "ToString" && + callExp.Arguments.Count == 1 && + callExp.Arguments[0].Type == typeof(string) && + callExp.Arguments[0].NodeType == ExpressionType.Constant) + { + var format = (callExp.Arguments[0] as ConstantExpression)?.Value?.ToString(); + + if (string.IsNullOrEmpty(format) == false) + { + var tmp = e.FreeParse(callExp.Object); + + switch (format) + { + case "yyyy-MM-dd HH:mm": + tmp = $"date_format({tmp}, '%Y-%m-%d %H:%i')"; + break; + } + e.Result = tmp; + } + } + } + }; var dbs = g.sqlserver.DbFirst.GetDatabases(); @@ -233,6 +262,21 @@ namespace FreeSql.Tests .IncludeMany(m => m.Permissions.Where(p => p.SysModuleId == m.Id), then => then.LeftJoin(p => p.Button.Id == p.SysModuleButtonId)) .ToList(); + + + var sql = g.sqlite.Select() + .ToSql(a => a.CreateTime.FormatDateTime("yyyy-MM-dd")); + } + } + + [ExpressionCall] + public static class DbFunc + { + static ThreadLocal context = new ThreadLocal(); + + public static string FormatDateTime(this DateTime that, string arg1) + { + return $"date_format({context.Value.Values["arg1"]})"; } } } diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs new file mode 100644 index 00000000..4cd22f54 --- /dev/null +++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.DataAnnotations +{ + /// + /// 自定义表达式函数解析 + /// 注意:请使用静态扩展类 + /// + [AttributeUsage(AttributeTargets.Class)] + public class ExpressionCallAttribute : Attribute + { + } + + public class ExpressionCallContext + { + /// + /// 数据库类型,可用于适配多种数据库环境 + /// + public DataType DataType { get; set; } + + /// + /// 已解析的表达式中参数内容 + /// + public Dictionary Values { get; } = new Dictionary(); + } +} diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 684eb212..1bea2b5d 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -44,6 +44,16 @@ public static partial class FreeSqlGlobalExtensions public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that)); public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that; internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args)); + static ConcurrentDictionary _dicGetDefaultValueFirstConstructorsParameters = new ConcurrentDictionary(); + public static object CreateInstanceGetDefaultValue(this Type that) + { + if (that == null) return null; + if (that == typeof(string)) return default(string); + if (that.IsArray) return Array.CreateInstance(that, 0); + var ctorParms = _dicGetDefaultValueFirstConstructorsParameters.GetOrAdd(that, tp => tp.GetConstructors().FirstOrDefault()?.GetParameters()); + if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, null); + return Activator.CreateInstance(that, ctorParms.Select(a => Activator.CreateInstance(a.ParameterType, null)).ToArray()); + } static ConcurrentDictionary> _dicGetPropertiesDictIgnoreCase = new ConcurrentDictionary>(); public static Dictionary GetPropertiesDictIgnoreCase(this Type that) => that == null ? null : _dicGetPropertiesDictIgnoreCase.GetOrAdd(that, tp => diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 0f30703b..a773044d 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -152,6 +152,22 @@ + + + 自定义表达式函数解析 + 注意:请使用静态扩展类 + + + + + 数据库类型,可用于适配多种数据库环境 + + + + + 已解析的表达式中参数内容 + + 索引名 @@ -2000,6 +2016,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 }) + + + + + + 可自定义解析表达式 @@ -2710,159 +2857,3 @@ - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完将自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 事务体 () => {} - 超时,未执行完将自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 759aaf19..593693be 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -9,6 +9,8 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using FreeSql.DataAnnotations; +using System.Threading; namespace FreeSql.Internal { @@ -496,6 +498,8 @@ namespace FreeSql.Internal tsc.mapType = null; return $"{left} {oper} {right}"; } + static ConcurrentDictionary _dicTypeExistsExpressionCallAttribute = new ConcurrentDictionary(); + static ConcurrentDictionary _dicTypeExpressionCallClassContextFields = new ConcurrentDictionary(); public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) { if (exp == null) return ""; @@ -535,6 +539,38 @@ namespace FreeSql.Internal case ExpressionType.Call: tsc.mapType = null; var exp3 = exp as MethodCallExpression; + if (exp3.Object == null && _dicTypeExistsExpressionCallAttribute.GetOrAdd(exp3.Method.DeclaringType, dttp => dttp.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any())) + { + var ecc = new ExpressionCallContext { DataType = _ado.DataType }; + var exp3MethodParams = exp3.Method.GetParameters(); + for (var a = 0; a < exp3.Arguments.Count; a++) + if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) + ecc.Values.Add(exp3MethodParams[a].Name, ExpressionLambdaToSql(exp3.Arguments[a], tsc)); + + var exp3InvokeParams = new object[exp3.Arguments.Count]; + for (var a = 0; a < exp3.Arguments.Count; a++) + { + if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) + exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); + else + exp3InvokeParams[a] = ecc; + } + var eccFields = _dicTypeExpressionCallClassContextFields.GetOrAdd(exp3.Method.DeclaringType, dttp => + dttp.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Static).Where(a => a.FieldType == typeof(ThreadLocal)).ToArray()); + if (eccFields.Any() == false) + throw new Exception($"自定义表达式解析错误:类型 {exp3.Method.DeclaringType} 需要定义 static ThreadLocal 字段、字段、字段(重要三次提醒)"); + foreach (var eccField in eccFields) + typeof(ThreadLocal).GetProperty("Value").SetValue(eccField.GetValue(null), ecc, null); + try + { + return string.Concat(exp3.Method.Invoke(null, exp3InvokeParams)); + } + finally + { + foreach (var eccField in eccFields) + typeof(ThreadLocal).GetProperty("Value").SetValue(eccField.GetValue(null), null, null); + } + } var callType = exp3.Object?.Type ?? exp3.Method.DeclaringType; string other3Exp = null; switch (callType.FullName) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 0b999a83..271c3ac9 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -170,10 +170,7 @@ namespace FreeSql.Internal if (colattr.IsNullable == false && colattr.DbDefautValue == null) { var citype = colattr.MapType.IsNullableType() ? colattr.MapType.GetGenericArguments().FirstOrDefault() : colattr.MapType; - if (citype.IsArray) - colattr.DbDefautValue = Array.CreateInstance(citype, 0); - else - colattr.DbDefautValue = Activator.CreateInstance(citype); + colattr.DbDefautValue = citype.CreateInstanceGetDefaultValue(); } trytb.Columns.Add(colattr.Name, col); From 9f97d67cb23f2a9358a866650557d130e648ae01 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 20 Nov 2019 16:06:45 +0800 Subject: [PATCH 0260/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20Contains=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=E4=B8=BA=20where?= =?UTF-8?q?=20in=20=E8=87=AA=E5=8A=A8=E6=8B=86=E5=88=86=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E5=A4=A7=E4=BA=8E=201000=20=E7=9A=84=20SQL=20?= =?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnectorExpression/OtherTest.cs | 5 ++ .../Default/OdbcExpression/OtherTest.cs | 5 ++ .../MySql/MySqlExpression/OtherTest.cs | 7 +- .../Oracle/OracleExpression/OtherTest.cs | 5 ++ .../PostgreSQLExpression/OtherTest.cs | 7 +- .../SqlServerExpression/OtherTest.cs | 74 +++++++++++++++++++ .../MySql/MySqlExpression/OtherTest.cs | 5 ++ .../Oracle/OracleExpression/OtherTest.cs | 5 ++ .../PostgreSQLExpression/OtherTest.cs | 5 ++ .../SqlServerExpression/OtherTest.cs | 15 ++++ .../Sqlite/SqliteExpression/OtherTest.cs | 5 ++ .../AdoProvider/AdoProviderUtils.cs | 21 ++++++ .../MySqlAdo/MySqlAdo.cs | 8 +- .../FreeSql.Provider.MySql/MySqlExpression.cs | 4 +- .../Default/OdbcAdo/OdbcAdo.cs | 8 +- .../Default/OdbcExpression.cs | 4 +- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 10 +-- .../MySql/OdbcMySqlExpression.cs | 4 +- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 8 +- .../Oracle/OdbcOracleExpression.cs | 4 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 8 +- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 6 +- .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 10 +-- .../SqlServer/OdbcSqlServerExpression.cs | 4 +- .../OracleAdo/OracleAdo.cs | 8 +- .../OracleExpression.cs | 4 +- .../PostgreSQLAdo/PostgreSQLAdo.cs | 8 +- .../PostgreSQLExpression.cs | 6 +- .../SqlServerAdo/SqlServerAdo.cs | 8 +- .../SqlServerExpression.cs | 4 +- .../SqliteAdo/SqliteAdo.cs | 8 +- .../SqliteExpression.cs | 4 +- 32 files changed, 201 insertions(+), 86 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs index 37b81c4d..19ab9e10 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs @@ -106,6 +106,11 @@ namespace FreeSql.Tests.MySqlConnectorExpression var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs index fc29b831..cf22c6f2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs @@ -72,6 +72,11 @@ namespace FreeSql.Tests.Odbc.DefaultExpression var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs index 794f9e31..3c31f047 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs @@ -105,7 +105,12 @@ namespace FreeSql.Tests.Odbc.MySqlExpression var inarray2 = new List() { 1, 2, 3 }; var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs index a3a42d06..dcc2eccf 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs @@ -101,6 +101,11 @@ namespace FreeSql.Tests.Odbc.OracleExpression var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs index 4b9e66f8..f0062476 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -107,7 +107,12 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression var inarray2 = new List() { 1, 2, 3 }; var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); - var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs index 63646aa8..7d0167f1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs @@ -97,6 +97,77 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); + + //nvarchar + IEnumerable stringlinqlist = new List(new[] { "a1", "a2", "a3" }); + var ntestlinq = select.Where(a => stringlinqlist.Contains(a.testFieldString)).ToList(); + + //in not in + var nsql111 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + var nsql112 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldString) == false).ToList(); + var nsql113 = select.Where(a => !new[] { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + + var ninarray = new[] { "a1", "a2", "a3" }; + var nsql1111 = select.Where(a => ninarray.Contains(a.testFieldString)).ToList(); + var nsql1122 = select.Where(a => ninarray.Contains(a.testFieldString) == false).ToList(); + var nsql1133 = select.Where(a => !ninarray.Contains(a.testFieldString)).ToList(); + + //in not in + var nsql11111 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + var nsql11222 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldString) == false).ToList(); + var nsql11333 = select.Where(a => !new List() { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + + var nsql11111a = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString)).ToList(); + var nsql11222b = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString) == false).ToList(); + var nsql11333c = select.Where(a => !new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString)).ToList(); + + var ninarray2 = new List() { "a1", "a2", "a3" }; + var nsql111111 = select.Where(a => ninarray2.Contains(a.testFieldString)).ToList(); + var nsql112222 = select.Where(a => ninarray2.Contains(a.testFieldString) == false).ToList(); + var nsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldString)).ToList(); + + var ninarray2n = Enumerable.Range(1, 3333).Select(a => "testnvarchar" + a).ToArray(); + var nsql1111111 = select.Where(a => ninarray2n.Contains(a.testFieldString)).ToList(); + var nsql1122222 = select.Where(a => ninarray2n.Contains(a.testFieldString) == false).ToList(); + var nsql1133333 = select.Where(a => !ninarray2n.Contains(a.testFieldString)).ToList(); + + //varchar + IEnumerable vstringlinqlist = new List(new[] { "a1", "a2", "a3" }); + var vtestlinq = select.Where(a => vstringlinqlist.Contains(a.testFieldStringVarchar)).ToList(); + + //in not in + var vsql111 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + var vsql112 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql113 = select.Where(a => !new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray = new[] { "a1", "a2", "a3" }; + var vsql1111 = select.Where(a => ninarray.Contains(a.testFieldStringVarchar)).ToList(); + var vsql1122 = select.Where(a => ninarray.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql1133 = select.Where(a => !ninarray.Contains(a.testFieldStringVarchar)).ToList(); + + //in not in + var vsql11111 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + var vsql11222 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql11333 = select.Where(a => !new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + + var vsql11111a = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar)).ToList(); + var vsql11222b = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql11333c = select.Where(a => !new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray2 = new List() { "a1", "a2", "a3" }; + var vsql111111 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar)).ToList(); + var vsql112222 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray2n = Enumerable.Range(1, 3333).Select(a => "testvarchar" + a).ToArray(); + var vsql1111111 = select.Where(a => vinarray2n.Contains(a.testFieldStringVarchar)).ToList(); + var vsql1122222 = select.Where(a => vinarray2n.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql1133333 = select.Where(a => !vinarray2n.Contains(a.testFieldStringVarchar)).ToList(); } [Table(Name = "tb_alltype")] @@ -123,6 +194,9 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression public DateTimeOffset testFieldDateTimeOffset { get; set; } public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + + [Column(DbType = "varchar(255)")] + public string testFieldStringVarchar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs index db07a187..d926eed7 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs @@ -106,6 +106,11 @@ namespace FreeSql.Tests.MySqlExpression var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs index 1c7d9048..d8317ef1 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs @@ -101,6 +101,11 @@ namespace FreeSql.Tests.OracleExpression var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index 950c538c..4ba7feea 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -130,6 +130,11 @@ namespace FreeSql.Tests.PostgreSQLExpression var sql7 = select.Where(a => a.testFieldIntArray.GetLongLength(1) > 0).ToList(); var sql8 = select.Where(a => a.testFieldIntArray.Length > 0).ToList(); var sql9 = select.Where(a => a.testFieldIntArray.Count() > 0).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs index 459fc7bf..ce27dceb 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs @@ -106,6 +106,11 @@ namespace FreeSql.Tests.SqlServerExpression var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); + //nvarchar IEnumerable stringlinqlist = new List(new[] { "a1", "a2", "a3" }); var ntestlinq = select.Where(a => stringlinqlist.Contains(a.testFieldString)).ToList(); @@ -134,6 +139,11 @@ namespace FreeSql.Tests.SqlServerExpression var nsql112222 = select.Where(a => ninarray2.Contains(a.testFieldString) == false).ToList(); var nsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldString)).ToList(); + var ninarray2n = Enumerable.Range(1, 3333).Select(a => "testnvarchar" + a).ToArray(); + var nsql1111111 = select.Where(a => ninarray2n.Contains(a.testFieldString)).ToList(); + var nsql1122222 = select.Where(a => ninarray2n.Contains(a.testFieldString) == false).ToList(); + var nsql1133333 = select.Where(a => !ninarray2n.Contains(a.testFieldString)).ToList(); + //varchar IEnumerable vstringlinqlist = new List(new[] { "a1", "a2", "a3" }); var vtestlinq = select.Where(a => vstringlinqlist.Contains(a.testFieldStringVarchar)).ToList(); @@ -161,6 +171,11 @@ namespace FreeSql.Tests.SqlServerExpression var vsql111111 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar)).ToList(); var vsql112222 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar) == false).ToList(); var vsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray2n = Enumerable.Range(1, 3333).Select(a => "testvarchar" + a).ToArray(); + var vsql1111111 = select.Where(a => vinarray2n.Contains(a.testFieldStringVarchar)).ToList(); + var vsql1122222 = select.Where(a => vinarray2n.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql1133333 = select.Where(a => !vinarray2n.Contains(a.testFieldStringVarchar)).ToList(); } [Table(Name = "tb_alltypeOther")] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs index 3276034d..51aa61f6 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs @@ -100,6 +100,11 @@ namespace FreeSql.Tests.SqliteExpression var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs index 56c43677..9edce10c 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs @@ -1,6 +1,8 @@ using FreeSql.Internal.Model; using System; +using System.Collections; using System.Collections.Concurrent; +using System.Text; using System.Text.RegularExpressions; namespace FreeSql.Internal.CommonProvider @@ -23,5 +25,24 @@ namespace FreeSql.Internal.CommonProvider try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; } } static ConcurrentDictionary _dicAddslashesReplaceIsNull = new ConcurrentDictionary(); + + protected string AddslashesIEnumerable(object param, Type mapType, ColumnInfo mapColumn) + { + var sb = new StringBuilder(); + var ie = param as IEnumerable; + var idx = 0; + foreach (var z in ie) + { + sb.Append(","); + if (++idx > 500) + { + sb.Append(" \r\n \r\n"); //500元素分割, 3空格\r\n4空格 + idx = 1; + } + sb.Append(AddslashesProcessParam(z, mapType, mapColumn)); + } + + return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); + } } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index 602ed684..c101e092 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -49,12 +49,8 @@ namespace FreeSql.MySql else if (param is MygisGeometry) return string.Concat("ST_GeomFromText('", (param as MygisGeometry).AsText().Replace("'", "''"), "')"); else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 2f3f78a8..f8a2e19e 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -109,8 +109,8 @@ namespace FreeSql.MySql switch (callExp.Method.Name) { case "Contains": - //判断 in - return $"({args1}) in {left}"; + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index 2d7a2b0e..27352355 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -50,12 +50,8 @@ namespace FreeSql.Odbc.Default else if (param is TimeSpan || param is TimeSpan?) return Adapter.TimeSpanRawSql(param); else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs index 4d2bf9ea..f3aa470d 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -116,8 +116,8 @@ namespace FreeSql.Odbc.Default switch (callExp.Method.Name) { case "Contains": - //判断 in - return $"({args1}) in {left}"; + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 0aa06d1a..8c6f5c24 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -46,13 +46,9 @@ namespace FreeSql.Odbc.MySql return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10; - else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 14bce855..36c2261a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -109,8 +109,8 @@ namespace FreeSql.Odbc.MySql switch (callExp.Method.Name) { case "Contains": - //判断 in - return $"({args1}) in {left}"; + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index 6a3cd58b..98e7921a 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -46,12 +46,8 @@ namespace FreeSql.Odbc.Oracle else if (param is TimeSpan || param is TimeSpan?) return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //if (param is string) return string.Concat('N', nparms[a]); } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 651fbef3..71190478 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -109,8 +109,8 @@ namespace FreeSql.Odbc.Oracle switch (callExp.Method.Name) { case "Contains": - //判断 in - return $"({args1}) in {left}"; + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index 862ea601..0777ffb8 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -48,12 +48,8 @@ namespace FreeSql.Odbc.PostgreSQL else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10; else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 28da1107..bee2bacc 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -137,9 +137,9 @@ namespace FreeSql.Odbc.PostgreSQL tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); //判断 in 或 array @> array if (left.StartsWith("array[") || left.EndsWith("]")) - return $"{args1} in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) - return $"{args1} in {left}"; + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; args1 = $"array[{args1}]"; if (objExp != null) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index 4ee2b561..20e197c6 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -62,13 +62,9 @@ namespace FreeSql.Odbc.SqlServer } else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).TotalSeconds; - else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 7c1712bc..47df3413 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -113,8 +113,8 @@ namespace FreeSql.Odbc.SqlServer switch (callExp.Method.Name) { case "Contains": - //判断 in - return $"({args1}) in {left}"; + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; } } break; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 424b8175..3c637833 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -46,12 +46,8 @@ namespace FreeSql.Oracle else if (param is TimeSpan || param is TimeSpan?) return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //if (param is string) return string.Concat('N', nparms[a]); } diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 818dff2b..9ea04aaf 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -109,8 +109,8 @@ namespace FreeSql.Oracle switch (callExp.Method.Name) { case "Contains": - //判断 in - return $"({args1}) in {left}"; + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; } } break; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index ae3c9e3f..f1600c24 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -65,12 +65,8 @@ namespace FreeSql.PostgreSQL return pghstore.Append("'::hstore"); } else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 86760acc..78184791 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -167,9 +167,9 @@ namespace FreeSql.PostgreSQL tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); //判断 in 或 array @> array if (left.StartsWith("array[") || left.EndsWith("]")) - return $"{args1} in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) - return $"{args1} in {left}"; + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; args1 = $"array[{args1}]"; if (objExp != null) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index b6e43640..2d898e7a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -63,12 +63,8 @@ namespace FreeSql.SqlServer else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).TotalSeconds; else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 85edc86a..3e068d4a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -113,8 +113,8 @@ namespace FreeSql.SqlServer switch (callExp.Method.Name) { case "Contains": - //判断 in - return $"({args1}) in {left}"; + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; } } break; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index b8175943..d57c74ec 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -45,12 +45,8 @@ namespace FreeSql.Sqlite else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10000; else if (param is IEnumerable) - { - var sb = new StringBuilder(); - var ie = param as IEnumerable; - foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType, mapColumn)); - return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); - } + return AddslashesIEnumerable(param, mapType, mapColumn); + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 1c2f821d..922a7bef 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -109,8 +109,8 @@ namespace FreeSql.Sqlite switch (callExp.Method.Name) { case "Contains": - //判断 in - return $"({args1}) in {left}"; + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; } } break; From 152d41025bee9caf15c8bc68e7357e5517fe13dc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 20 Nov 2019 18:22:05 +0800 Subject: [PATCH 0261/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IsNulable=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B=20#137?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 18 ++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 431e8818..7cc880b5 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -165,9 +165,27 @@ namespace FreeSql.Tests public long? CreateUserId { get; set; } } + public class TestMySqlStringIsNullable + { + public Guid id { get; set; } + public string varchar { get; set; } + [Column(IsNullable = true)] + public string varchar_null { get; set; } + [Column(IsNullable = false)] + public string varchar_notnull { get; set; } + } + [Fact] public void Test02() { + g.mysql.Select(); + + var slsksd = g.mysql.Update().SetSource(new UserLike { Id = Guid.NewGuid(), CreateUserId = 1000, SubjectId = Guid.NewGuid() }) + .UpdateColumns(a => new + { + a.SubjectId + }).NoneParameter().ToSql(); + g.mysql.Aop.ParseExpression = (s, e) => { if (e.Expression.NodeType == ExpressionType.Call) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 271c3ac9..cecb8816 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -114,7 +114,7 @@ namespace FreeSql.Internal else colattr.DbType = colattr.DbType.ToUpper(); - if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; + if (colattr._IsNullable == null && tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower(); From ec6e1f709ecbbf73b2571ecdf4dff68120955a81 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 20 Nov 2019 18:24:30 +0800 Subject: [PATCH 0262/1029] ## v0.11.23 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index ad09dcce..2a0a8f9a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.22 + 0.11.23 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 15fda555..b26b441e 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 23094f25..3ebc4ddc 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e6d05efb..89756451 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e4477bcb..bbffb9cb 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.22 + 0.11.23 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3a0ce8a3..53fb799e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 2760f044..53e29024 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 185252b7..bb36141c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d5932514..93ea8bbc 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6dbcee1f..2932a1a4 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index fd33300f..81220bb9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 09c91574..09851528 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 1114ce0b..c6008b8e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.22 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From cf080254c947fc1738192c5ba135cf837ef81f3a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 Nov 2019 13:14:44 +0800 Subject: [PATCH 0263/1029] update --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 67cdcb46..636496aa 100644 --- a/readme.md +++ b/readme.md @@ -23,7 +23,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | | | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | | | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [黑科技](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | # Packages From b5629b13a6558e692c9f3d92b1a8e6bb19beb1f6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 Nov 2019 13:15:52 +0800 Subject: [PATCH 0264/1029] update --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 636496aa..c78af1b0 100644 --- a/readme.md +++ b/readme.md @@ -23,7 +23,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | | | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | | | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [黑科技](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | # Packages From 04107d3d24355d3592fce4f61689408bae7181eb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 Nov 2019 16:42:20 +0800 Subject: [PATCH 0265/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Repository/D?= =?UTF-8?q?bContext=20SaveMany=20=E6=96=B9=E6=B3=95=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=B8=80=E5=AF=B9=E5=A4=9A=EF=BC=8C=E5=AD=90=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9A=84=E5=AE=8C=E6=95=B4=E4=BF=9D=E5=AD=98=EF=BC=9B=20-=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=20SaveManyToMany=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=8D=E4=B8=BA=20SaveMany=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 14 ++- .../DbContext/DbContextOptions.cs | 4 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 57 ++++++------ FreeSql.DbContext/DbSet/DbSetSync.cs | 91 ++++++++++++------- FreeSql.DbContext/FreeSql.DbContext.xml | 43 ++++----- .../Repository/Repository/BaseRepository.cs | 4 +- .../Repository/BaseRepositoryAsync.cs | 4 +- .../Repository/Repository/IBasicRepository.cs | 10 +- FreeSql.DbContext/readme.md | 4 +- .../RepositoryTests.cs | 6 +- .../FreeSql.Tests.DbContext/UnitTest1.cs | 4 +- FreeSql/FreeSql.xml | 3 +- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 3 +- .../SelectProvider/Select0Provider.cs | 8 +- .../SelectProvider/Select1Provider.cs | 4 +- 15 files changed, 150 insertions(+), 109 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 7db324cf..9524f9b4 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -158,14 +158,18 @@ namespace FreeSql this.Set().AddOrUpdate(data); } /// - /// 保存实体的指定 ManyToMany 导航属性 + /// 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) + /// 场景:在关闭级联保存功能之后,手工使用本方法 + /// 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus") + /// 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据 + /// 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录 /// /// 实体对象 /// 属性名 - public void SaveManyToMany(TEntity data, string propertyName) where TEntity : class + public void SaveMany(TEntity data, string propertyName) where TEntity : class { CheckEntityTypeOrThrow(typeof(TEntity)); - this.Set().SaveManyToMany(data, propertyName); + this.Set().SaveMany(data, propertyName); } /// @@ -212,10 +216,10 @@ namespace FreeSql CheckEntityTypeOrThrow(typeof(TEntity)); return this.Set().AddOrUpdateAsync(data); } - public Task SaveManyToManyAsync(TEntity data, string propertyName) where TEntity : class + public Task SaveManyAsync(TEntity data, string propertyName) where TEntity : class { CheckEntityTypeOrThrow(typeof(TEntity)); - return this.Set().SaveManyToManyAsync(data, propertyName); + return this.Set().SaveManyAsync(data, propertyName); } #endif #endregion diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index 95cd5630..d8492bbe 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -9,9 +9,9 @@ namespace FreeSql { /// - /// 是否开启一对多,多对多联级保存功能 + /// 是否开启一对多,多对多级联保存功能 /// - /// 【一对多】模型下, 保存时可联级保存实体的属性集合。出于使用安全考虑我们没做完整对比,只实现实体属性集合的添加或更新操作,所以不会删除实体属性集合的数据。 + /// 【一对多】模型下, 保存时可级联保存实体的属性集合。出于使用安全考虑我们没做完整对比,只实现实体属性集合的添加或更新操作,所以不会删除实体属性集合的数据。 /// 完整对比的功能使用起来太危险,试想下面的场景: /// - 保存的时候,实体的属性集合是空的,如何操作?记录全部删除? /// - 保存的时候,由于数据库中记录非常之多,那么只想保存子表的部分数据,或者只需要添加,如何操作? diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 0adf77f3..07123ef8 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -133,22 +133,44 @@ namespace FreeSql } } - async public Task SaveManyToManyAsync(TEntity item, string propertyName) + async public Task SaveManyAsync(TEntity item, string propertyName) { if (item == null) return; - if (_table.Properties.ContainsKey(propertyName) == false) throw new KeyNotFoundException($"{_table.Type.FullName} 不存在属性 {propertyName}"); + if (string.IsNullOrEmpty(propertyName)) return; + if (_table.Properties.TryGetValue(propertyName, out var prop) == false) throw new KeyNotFoundException($"{_table.Type.FullName} 不存在属性 {propertyName}"); if (_table.ColumnsByCsIgnore.ContainsKey(propertyName)) throw new ArgumentException($"{_table.Type.FullName} 类型已设置属性 {propertyName} 忽略特性"); + var tref = _table.GetTableRef(propertyName, true); - if (tref.RefType != Internal.Model.TableRefType.ManyToMany) throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 ManyToMany 特性"); - DbContextExecCommand(); + if (tref == null) return; + switch (tref.RefType) + { + case Internal.Model.TableRefType.OneToOne: + case Internal.Model.TableRefType.ManyToOne: + throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 OneToMany 或 ManyToMany 特性"); + } + + await DbContextExecCommandAsync(); var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; _db.Options.EnableAddOrUpdateNavigateList = false; - await AddOrUpdateNavigateListAsync(item, false, propertyName); - _db.Options.EnableAddOrUpdateNavigateList = oldEnable; + try + { + await AddOrUpdateNavigateListAsync(item, false, propertyName); + if (tref.RefType == Internal.Model.TableRefType.OneToMany) + { + await DbContextExecCommandAsync(); + //删除没有保存的数据 + var propValEach = GetItemValue(item, prop) as IEnumerable; + await _db.Orm.Select().AsType(tref.RefEntityType).WhereDynamic(propValEach, true) + .ToDelete().ExecuteAffrowsAsync(); + } + } + finally + { + _db.Options.EnableAddOrUpdateNavigateList = oldEnable; + } } async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd, string propertyName = null) { - Type itemType = null; Func action = async prop => { if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) return; @@ -163,26 +185,7 @@ namespace FreeSql return; } - object propVal = null; - if (itemType == null) itemType = item.GetType(); - if (_table.TypeLazy != null && itemType == _table.TypeLazy) - { - var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Name, propName => - _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); - if (lazyField != null) - { - var lazyFieldValue = (bool)lazyField.GetValue(item); - if (lazyFieldValue == false) return; - } - propVal = prop.GetValue(item); - } - else - { - propVal = prop.GetValue(item); - if (propVal == null) return; - } - - var propValEach = propVal as IEnumerable; + var propValEach = GetItemValue(item, prop) as IEnumerable; if (propValEach == null) return; DbSet refSet = GetDbSetObject(tref.RefEntityType); switch (tref.RefType) diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 5be76522..912c29ce 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -136,34 +136,53 @@ namespace FreeSql } } - static ConcurrentDictionary> _dicLazyIsSetField = new ConcurrentDictionary>(); /// - /// 保存实体的指定 ManyToMany 导航属性 + /// 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) + /// 场景:在关闭级联保存功能之后,手工使用本方法 + /// 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus") + /// 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据 + /// 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录 /// /// 实体对象 /// 属性名 - public void SaveManyToMany(TEntity item, string propertyName) + public void SaveMany(TEntity item, string propertyName) { if (item == null) return; - if (_table.Properties.ContainsKey(propertyName) == false) throw new KeyNotFoundException($"{_table.Type.FullName} 不存在属性 {propertyName}"); + if (string.IsNullOrEmpty(propertyName)) return; + if (_table.Properties.TryGetValue(propertyName, out var prop) == false) throw new KeyNotFoundException($"{_table.Type.FullName} 不存在属性 {propertyName}"); if (_table.ColumnsByCsIgnore.ContainsKey(propertyName)) throw new ArgumentException($"{_table.Type.FullName} 类型已设置属性 {propertyName} 忽略特性"); + var tref = _table.GetTableRef(propertyName, true); - if (tref.RefType != Internal.Model.TableRefType.ManyToMany) throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 ManyToMany 特性"); + if (tref == null) return; + switch (tref.RefType) + { + case Internal.Model.TableRefType.OneToOne: + case Internal.Model.TableRefType.ManyToOne: + throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 OneToMany 或 ManyToMany 特性"); + } + DbContextExecCommand(); var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; _db.Options.EnableAddOrUpdateNavigateList = false; - AddOrUpdateNavigateList(item, false, propertyName); - _db.Options.EnableAddOrUpdateNavigateList = oldEnable; + try + { + AddOrUpdateNavigateList(item, false, propertyName); + if (tref.RefType == Internal.Model.TableRefType.OneToMany) + { + DbContextExecCommand(); + //删除没有保存的数据 + var propValEach = GetItemValue(item, prop) as IEnumerable; + _db.Orm.Select().AsType(tref.RefEntityType).WhereDynamic(propValEach, true) + .ToDelete().ExecuteAffrows(); + } + } + finally + { + _db.Options.EnableAddOrUpdateNavigateList = oldEnable; + } } - /// - /// 联级保存导航集合 - /// - /// 实体对象 - /// 是否为新增的实体对象 - /// 指定保存的属性 void AddOrUpdateNavigateList(TEntity item, bool isAdd, string propertyName = null) { - Type itemType = null; Action action = prop => { if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) return; @@ -178,26 +197,7 @@ namespace FreeSql return; } - object propVal = null; - if (itemType == null) itemType = item.GetType(); - if (_table.TypeLazy != null && itemType == _table.TypeLazy) - { - var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Name, propName => - _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); - if (lazyField != null) - { - var lazyFieldValue = (bool)lazyField.GetValue(item); - if (lazyFieldValue == false) return; - } - propVal = prop.GetValue(item, null); - } - else - { - propVal = prop.GetValue(item, null); - if (propVal == null) return; - } - - var propValEach = propVal as IEnumerable; + var propValEach = GetItemValue(item, prop) as IEnumerable; if (propValEach == null) return; DbSet refSet = GetDbSetObject(tref.RefEntityType); switch (tref.RefType) @@ -313,6 +313,29 @@ namespace FreeSql else if (_table.Properties.TryGetValue(propertyName, out var prop)) action(prop); } + static ConcurrentDictionary> _dicLazyIsSetField = new ConcurrentDictionary>(); + object GetItemValue(TEntity item, PropertyInfo prop) + { + object propVal = null; + var itemType = item.GetType(); + if (_table.TypeLazy != null && itemType == _table.TypeLazy) + { + var lazyField = _dicLazyIsSetField.GetOrAdd(_table.TypeLazy, tl => new ConcurrentDictionary()).GetOrAdd(prop.Name, propName => + _table.TypeLazy.GetField($"__lazy__{propName}", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance)); + if (lazyField != null) + { + var lazyFieldValue = (bool)lazyField.GetValue(item); + if (lazyFieldValue == false) return null; + } + propVal = prop.GetValue(item, null); + } + else + { + propVal = prop.GetValue(item, null); + if (propVal == null) return null; + } + return propVal; + } #endregion #region Update diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 1a43f59e..b718b2e5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -32,9 +32,13 @@ - + - 保存实体的指定 ManyToMany 导航属性 + 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) + 场景:在关闭级联保存功能之后,手工使用本方法 + 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus") + 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据 + 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录 实体对象 属性名 @@ -65,9 +69,9 @@ - 是否开启一对多,多对多联级保存功能 + 是否开启一对多,多对多级联保存功能 - 【一对多】模型下, 保存时可联级保存实体的属性集合。出于使用安全考虑我们没做完整对比,只实现实体属性集合的添加或更新操作,所以不会删除实体属性集合的数据。 + 【一对多】模型下, 保存时可级联保存实体的属性集合。出于使用安全考虑我们没做完整对比,只实现实体属性集合的添加或更新操作,所以不会删除实体属性集合的数据。 完整对比的功能使用起来太危险,试想下面的场景: - 保存的时候,实体的属性集合是空的,如何操作?记录全部删除? - 保存的时候,由于数据库中记录非常之多,那么只想保存子表的部分数据,或者只需要添加,如何操作? @@ -106,34 +110,23 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 - + - 保存实体的指定 ManyToMany 导航属性 + 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) + 场景:在关闭级联保存功能之后,手工使用本方法 + 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus") + 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据 + 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录 实体对象 属性名 - - - 联级保存导航集合 - - 实体对象 - 是否为新增的实体对象 - 指定保存的属性 - 更新 @@ -240,9 +233,13 @@ - + - 保存实体的指定 ManyToMany 导航属性 + 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) + 场景:在关闭级联保存功能之后,手工使用本方法 + 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus") + 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据 + 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录 实体对象 属性名 diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 38dd740b..b18a60a6 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -130,9 +130,9 @@ namespace FreeSql return entity; } - public void SaveManyToMany(TEntity entity, string propertyName) + public void SaveMany(TEntity entity, string propertyName) { - _dbset.SaveManyToMany(entity, propertyName); + _dbset.SaveMany(entity, propertyName); _db.SaveChanges(); } } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs index f848f89d..d29433eb 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs @@ -64,9 +64,9 @@ namespace FreeSql return entity; } - async public Task SaveManyToManyAsync(TEntity entity, string propertyName) + async public Task SaveManyAsync(TEntity entity, string propertyName) { - await _dbset.SaveManyToManyAsync(entity, propertyName); + await _dbset.SaveManyAsync(entity, propertyName); await _db.SaveChangesAsync(); } } diff --git a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs index 24f7291c..b0b4f804 100644 --- a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs @@ -30,11 +30,15 @@ namespace FreeSql TEntity InsertOrUpdate(TEntity entity); /// - /// 保存实体的指定 ManyToMany 导航属性 + /// 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) + /// 场景:在关闭级联保存功能之后,手工使用本方法 + /// 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus") + /// 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据 + /// 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录 /// /// 实体对象 /// 属性名 - void SaveManyToMany(TEntity entity, string propertyName); + void SaveMany(TEntity entity, string propertyName); IUpdate UpdateDiy { get; } @@ -49,7 +53,7 @@ namespace FreeSql Task UpdateAsync(TEntity entity); Task UpdateAsync(IEnumerable entitys); Task InsertOrUpdateAsync(TEntity entity); - Task SaveManyToManyAsync(TEntity entity, string propertyName); + Task SaveManyAsync(TEntity entity, string propertyName); Task DeleteAsync(TEntity entity); Task DeleteAsync(IEnumerable entitys); diff --git a/FreeSql.DbContext/readme.md b/FreeSql.DbContext/readme.md index 155847e5..beee15e9 100644 --- a/FreeSql.DbContext/readme.md +++ b/FreeSql.DbContext/readme.md @@ -6,7 +6,7 @@ ### v0.6.5 -- 修复 Repository 联级保存的 bug; +- 修复 Repository 级联保存的 bug; - 添加工作单元开启方法; - 适配 .net framework 4.5、netstandard 2.0; @@ -192,7 +192,7 @@ fsql.GetGuidRepository().Select.FromRepository(logRepository) - 修复 AddOrUpdate/InsertOrUpdate 当主键无值时,仍然查询了一次数据库; - 增加 查询数据时 TrackToList 对导航集合的状态跟踪; -- 完善 AddOrUpdateNavigateList 联级保存,忽略标记 IsIgnore 的集合属性; +- 完善 AddOrUpdateNavigateList 级联保存,忽略标记 IsIgnore 的集合属性; - 完成 IFreeSql.Include、IncludeMany 功能; ### v0.5.12 diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 4fa4fbe5..3097044b 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -361,7 +361,9 @@ namespace FreeSql.Tests }) } }; + repo.DbContextOptions.EnableAddOrUpdateNavigateList = false; //رռ湦 repo.Insert(cts); + repo.SaveMany(cts[0], "Childs"); //ָ Childs һԶ cts[0].Name = "11"; cts[0].Childs.Clear(); cts[1].Name = "22"; @@ -415,9 +417,9 @@ namespace FreeSql.Tests } }; var repo = g.sqlite.GetRepository(); - //repo.DbContextOptions.EnableAddOrUpdateNavigateList = false; //ر湦 + //repo.DbContextOptions.EnableAddOrUpdateNavigateList = false; //رռ湦 repo.Insert(ss); - repo.SaveManyToMany(ss[0], "Tags"); //ָ Tags Զ + //repo.SaveMany(ss[0], "Tags"); //ָ Tags Զ ss[0].Name = "һ.mp5"; ss[0].Tags.Clear(); diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index ea2a7435..bc192e74 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -98,7 +98,7 @@ namespace FreeSql.Tests var sql = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); - //֧ 1Զ + //֧ 1Զ using (var ctx = new FreeContext(g.sqlite)) { @@ -127,7 +127,7 @@ namespace FreeSql.Tests [Fact] public void Update() { - //ѯ 1Զ࣬ + //ѯ 1Զ࣬ټ using (var ctx = new FreeContext(g.sqlite)) { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a773044d..6bc4b8d9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1431,11 +1431,12 @@ lambda表达式 - + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index ea1db65c..43118b65 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -293,8 +293,9 @@ namespace FreeSql /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// 是否标识为NOT /// - ISelect WhereDynamic(object dywhere); + ISelect WhereDynamic(object dywhere, bool not = false); /// /// 多表查询时,该方法标记后,表达式条件将对所有表进行附加 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 8255b6d8..69fce858 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -888,12 +888,16 @@ namespace FreeSql.Internal.CommonProvider public IDelete ToDelete() { if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToDelete 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); - return _orm.Delete().Where(GetToDeleteWhere("ftb_del")); + var del = _orm.Delete(); + if (_tables[0].Table.Type != typeof(T1)) del.AsType(_tables[0].Table.Type); + return del.Where(GetToDeleteWhere("ftb_del")); } public IUpdate ToUpdate() { if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToUpdate 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); - return _orm.Update().Where(GetToDeleteWhere("ftb_upd")); + var upd = _orm.Update(); + if (_tables[0].Table.Type != typeof(T1)) upd.AsType(_tables[0].Table.Type); + return upd.Where(GetToDeleteWhere("ftb_upd")); } protected List> GetTableRuleUnions() diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index db153519..db3be215 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -319,7 +319,9 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = exp.Parameters[0]; return this.InternalWhere(exp?.Body); } - public ISelect WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere)); + public ISelect WhereDynamic(object dywhere, bool not = false) => not == false ? + this.Where(_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere)) : + this.Where($"not({_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere)})"); public ISelect WhereCascade(Expression> exp) { From 8c5d5ddedcecce731995930233b24bb03182a942 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 Nov 2019 21:55:04 +0800 Subject: [PATCH 0266/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20UnitOfWork?= =?UTF-8?q?=20=E9=9D=99=E6=80=81=E5=B1=9E=E6=80=A7=20DebugBeingUsed?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E4=BA=8E=E7=94=9F=E4=BA=A7=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E7=9B=91=E8=A7=86=E6=AD=A3=E5=9C=A8=E4=BD=BF=E7=94=A8=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E4=BA=8B=E5=8A=A1=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetAsync.cs | 3 +-- FreeSql.DbContext/DbSet/DbSetSync.cs | 3 +-- FreeSql.DbContext/FreeSql.DbContext.xml | 19 ++++++++++++++++++ FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 20 +++++++++++++++++++ FreeSql/FreeSql.xml | 6 ++++-- FreeSql/Interface/Curd/IDelete.cs | 3 ++- FreeSql/Interface/Curd/IUpdate.cs | 3 ++- .../Internal/CommonProvider/DeleteProvider.cs | 4 +++- .../Internal/CommonProvider/UpdateProvider.cs | 4 +++- 9 files changed, 55 insertions(+), 10 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 07123ef8..3d7df0bc 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -160,8 +160,7 @@ namespace FreeSql await DbContextExecCommandAsync(); //删除没有保存的数据 var propValEach = GetItemValue(item, prop) as IEnumerable; - await _db.Orm.Select().AsType(tref.RefEntityType).WhereDynamic(propValEach, true) - .ToDelete().ExecuteAffrowsAsync(); + await _db.Orm.Delete().AsType(tref.RefEntityType).WhereDynamic(propValEach, true).ExecuteAffrowsAsync(); } } finally diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 912c29ce..4e92feb7 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -172,8 +172,7 @@ namespace FreeSql DbContextExecCommand(); //删除没有保存的数据 var propValEach = GetItemValue(item, prop) as IEnumerable; - _db.Orm.Select().AsType(tref.RefEntityType).WhereDynamic(propValEach, true) - .ToDelete().ExecuteAffrows(); + _db.Orm.Delete().AsType(tref.RefEntityType).WhereDynamic(propValEach, true).ExecuteAffrows(); } } finally diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b718b2e5..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -267,6 +274,18 @@ 此工作单元内的实体变化跟踪 + + + 正在使用中的工作单元(调试) + + + + + 开启事务后有值,是 UnitOfWork 的唯一标识 + 格式:yyyyMMdd_HHmmss_种子id + 例如:20191121_214504_1 + + 创建普通数据上下文档对象 diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 892d5e74..4f619c71 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -1,6 +1,7 @@ using SafeObjectPool; using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Data; using System.Data.Common; using System.Linq; @@ -14,10 +15,23 @@ namespace FreeSql public static readonly AsyncLocal Current = new AsyncLocal(); #endif + static int _seed; + /// + /// 正在使用中的工作单元(调试) + /// + public static ConcurrentDictionary DebugBeingUsed { get; } = new ConcurrentDictionary(); + protected IFreeSql _fsql; protected Object _conn; protected DbTransaction _tran; + /// + /// 开启事务后有值,是 UnitOfWork 的唯一标识 + /// 格式:yyyyMMdd_HHmmss_种子id + /// 例如:20191121_214504_1 + /// + public string Id { get; private set; } + public UnitOfWork(IFreeSql fsql) { _fsql = fsql; @@ -28,6 +42,9 @@ namespace FreeSql void ReturnObject() { + if (string.IsNullOrEmpty(this.Id) == false && DebugBeingUsed.TryRemove(this.Id, out var old)) + this.Id = null; + _fsql.Ado.MasterPool.Return(_conn); _tran = null; _conn = null; @@ -66,6 +83,9 @@ namespace FreeSql _tran = IsolationLevel == null ? _conn.Value.BeginTransaction() : _conn.Value.BeginTransaction(IsolationLevel.Value); + + this.Id = $"{DateTime.Now.ToString("yyyyMMdd_HHmmss")}_{Interlocked.Increment(ref _seed)}"; + DebugBeingUsed.TryAdd(this.Id, this); } catch { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6bc4b8d9..56b67dc0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -655,11 +655,12 @@ 实体集合 - + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT @@ -1797,11 +1798,12 @@ 实体集合 - + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 127abd7a..3619cd67 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -52,8 +52,9 @@ namespace FreeSql /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// 是否标识为NOT /// - IDelete WhereDynamic(object dywhere); + IDelete WhereDynamic(object dywhere, bool not = false); /// /// 禁用全局过滤功能,不传参数时将禁用所有 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 2c47437d..9276c68d 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -121,8 +121,9 @@ namespace FreeSql /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// 是否标识为NOT /// - IUpdate WhereDynamic(object dywhere); + IUpdate WhereDynamic(object dywhere, bool not = false); /// /// 禁用全局过滤功能,不传参数时将禁用所有 diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index b1b740af..ed1bac84 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -96,7 +96,9 @@ namespace FreeSql.Internal.CommonProvider } public IDelete Where(T1 item) => this.Where(new[] { item }); public IDelete Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); - public IDelete WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + public IDelete WhereDynamic(object dywhere, bool not = false) => not == false ? + this.Where(_commonUtils.WhereObject(_table, "", dywhere)) : + this.Where($"not({_commonUtils.WhereObject(_table, "", dywhere)})"); public IDelete DisableGlobalFilter(params string[] name) { diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 8823c5bc..51c04727 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -434,7 +434,9 @@ namespace FreeSql.Internal.CommonProvider } public IUpdate Where(T1 item) => this.Where(new[] { item }); public IUpdate Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); - public IUpdate WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + public IUpdate WhereDynamic(object dywhere, bool not = false) => not == false ? + this.Where(_commonUtils.WhereObject(_table, "", dywhere)) : + this.Where($"not({_commonUtils.WhereObject(_table, "", dywhere)})"); public IUpdate DisableGlobalFilter(params string[] name) { From af9084e9a02825239dab3dd28534789e0d1df99b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 Nov 2019 22:04:15 +0800 Subject: [PATCH 0267/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20UnitOfWork?= =?UTF-8?q?=20=E9=9D=99=E6=80=81=E5=B1=9E=E6=80=A7=20DebugBeingUsed?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E4=BA=8E=E7=94=9F=E4=BA=A7=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E7=9B=91=E8=A7=86=E6=AD=A3=E5=9C=A8=E4=BD=BF=E7=94=A8=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E4=BA=8B=E5=8A=A1=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 4 +++- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 4 +++- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 15 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2a0a8f9a..ad55d9e7 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.23 + 0.11.24 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index b26b441e..355c0aa6 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 3ebc4ddc..2afb29f2 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 89756451..3bb3e9ec 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..049ce879 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -276,7 +276,9 @@ - 正在使用中的工作单元(调试) + 正在使用中的工作单元(调试) + Key 格式:yyyyMMdd_HHmmss_种子id + 例如:20191121_214504_1 diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 4f619c71..0628ee30 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -17,7 +17,9 @@ namespace FreeSql static int _seed; /// - /// 正在使用中的工作单元(调试) + /// 正在使用中的工作单元(调试) + /// Key 格式:yyyyMMdd_HHmmss_种子id + /// 例如:20191121_214504_1 /// public static ConcurrentDictionary DebugBeingUsed { get; } = new ConcurrentDictionary(); diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index bbffb9cb..7d836478 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 53fb799e..2ff4b149 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 53e29024..d9ff1c1e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index bb36141c..fef53647 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 93ea8bbc..deb1607a 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2932a1a4..6168600d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 81220bb9..0f051ab0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 09851528..2f1cbed1 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c6008b8e..9ae109f4 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 4859dc9741a97a76dc0b074db11aab8b46238880 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 Nov 2019 22:04:43 +0800 Subject: [PATCH 0268/1029] =?UTF-8?q?Revert=20"-=20=E5=A2=9E=E5=8A=A0=20Un?= =?UTF-8?q?itOfWork=20=E9=9D=99=E6=80=81=E5=B1=9E=E6=80=A7=20DebugBeingUse?= =?UTF-8?q?d=EF=BC=8C=E7=94=A8=E4=BA=8E=E7=94=9F=E4=BA=A7=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E7=9B=91=E8=A7=86=E6=AD=A3=E5=9C=A8=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E4=BA=8B=E5=8A=A1=EF=BC=9B"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit af9084e9a02825239dab3dd28534789e0d1df99b. --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 4 +--- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 4 +--- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 15 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index ad55d9e7..2a0a8f9a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.24 + 0.11.23 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 355c0aa6..b26b441e 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 2afb29f2..3ebc4ddc 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 3bb3e9ec..89756451 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 049ce879..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -276,9 +276,7 @@ - 正在使用中的工作单元(调试) - Key 格式:yyyyMMdd_HHmmss_种子id - 例如:20191121_214504_1 + 正在使用中的工作单元(调试) diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 0628ee30..4f619c71 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -17,9 +17,7 @@ namespace FreeSql static int _seed; /// - /// 正在使用中的工作单元(调试) - /// Key 格式:yyyyMMdd_HHmmss_种子id - /// 例如:20191121_214504_1 + /// 正在使用中的工作单元(调试) /// public static ConcurrentDictionary DebugBeingUsed { get; } = new ConcurrentDictionary(); diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7d836478..bbffb9cb 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.11.23 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2ff4b149..53fb799e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d9ff1c1e..53e29024 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fef53647..bb36141c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index deb1607a..93ea8bbc 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6168600d..2932a1a4 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0f051ab0..81220bb9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2f1cbed1..09851528 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9ae109f4..c6008b8e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.11.23 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 71dbd75a7281ed5b9310082019bd7b624d7fe585 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 Nov 2019 22:06:09 +0800 Subject: [PATCH 0269/1029] ## v0.11.24 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2a0a8f9a..ad55d9e7 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.23 + 0.11.24 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index b26b441e..355c0aa6 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 3ebc4ddc..2afb29f2 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 89756451..3bb3e9ec 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index bbffb9cb..7d836478 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 53fb799e..2ff4b149 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 53e29024..d9ff1c1e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index bb36141c..fef53647 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 93ea8bbc..deb1607a 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2932a1a4..6168600d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 81220bb9..0f051ab0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 09851528..2f1cbed1 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c6008b8e..9ae109f4 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.23 + 0.11.24 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 12be7f00514f79f64b00adca0d843d223c1de79e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 Nov 2019 05:58:17 +0800 Subject: [PATCH 0270/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=E5=86=85?= =?UTF-8?q?=E9=83=A8=E5=8F=82=E6=95=B0=E5=8C=96=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E4=B8=BA=E4=BB=A5=E5=90=8E=20Where=20?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=8F=82=E6=95=B0=E5=8C=96=E5=81=9A=E5=87=86?= =?UTF-8?q?=E5=A4=87=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 13 +++- FreeSql.Tests/FreeSql.Tests/g.cs | 1 + FreeSql/Internal/CommonExpression.cs | 62 ++++++++++++------- .../Internal/CommonProvider/DeleteProvider.cs | 4 +- .../Internal/CommonProvider/InsertProvider.cs | 2 +- .../SelectProvider/Select0Provider.cs | 5 +- .../SelectProvider/Select10Provider.cs | 8 +-- .../SelectProvider/Select1Provider.cs | 4 +- .../SelectProvider/Select2Provider.cs | 8 +-- .../SelectProvider/Select3Provider.cs | 8 +-- .../SelectProvider/Select4Provider.cs | 8 +-- .../SelectProvider/Select5Provider.cs | 8 +-- .../SelectProvider/Select6Provider.cs | 8 +-- .../SelectProvider/Select7Provider.cs | 8 +-- .../SelectProvider/Select8Provider.cs | 8 +-- .../SelectProvider/Select9Provider.cs | 8 +-- .../SelectProvider/SelectGroupingProvider.cs | 6 +- .../Internal/CommonProvider/UpdateProvider.cs | 12 ++-- FreeSql/Internal/CommonUtils.cs | 22 ++++++- .../FreeSql.Provider.MySql/MySqlUtils.cs | 12 +++- .../MySqlConnectorUtils.cs | 12 +++- .../Default/OdbcUtils.cs | 4 +- .../MySql/OdbcMySqlUtils.cs | 3 +- .../Oracle/Curd/OdbcOracleInsert.cs | 6 +- .../Oracle/OdbcOracleUtils.cs | 3 +- .../PostgreSQL/OdbcPostgreSQLUtils.cs | 4 +- .../SqlServer/OdbcSqlServerUtils.cs | 4 +- .../Curd/OracleInsert.cs | 6 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 11 +++- .../PostgreSQLUtils.cs | 19 +++++- .../SqlServerUtils.cs | 20 +++++- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 3 +- 32 files changed, 213 insertions(+), 97 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 7cc880b5..97b4b8d1 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -168,17 +168,24 @@ namespace FreeSql.Tests public class TestMySqlStringIsNullable { public Guid id { get; set; } - public string varchar { get; set; } + public string nvarchar { get; set; } [Column(IsNullable = true)] - public string varchar_null { get; set; } + public string nvarchar_null { get; set; } [Column(IsNullable = false)] + public string nvarchar_notnull { get; set; } + + [Column(DbType = "varchar(100)")] + public string varchar { get; set; } + [Column(IsNullable = true, DbType = "varchar(100)")] + public string varchar_null { get; set; } + [Column(IsNullable = false, DbType = "varchar(100)")] public string varchar_notnull { get; set; } } [Fact] public void Test02() { - g.mysql.Select(); + var testparmSelect = g.sqlserver.Select().Where(a => a.nvarchar == "11" && a.nvarchar_notnull == "22" && a.nvarchar_null == "33" && a.varchar == "11" && a.varchar_notnull == "22" && a.varchar_null == "33"); var slsksd = g.mysql.Update().SetSource(new UserLike { Id = Guid.NewGuid(), CreateUserId = 1000, SubjectId = Guid.NewGuid() }) .UpdateColumns(a => new diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 2fe6231a..f3de6a4e 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -37,6 +37,7 @@ public class g .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;Max Pool Size=3") .UseAutoSyncStructure(true) + //.UseNoneCommandParameter(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 (cmd, traceLog) => Console.WriteLine(traceLog)) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 593693be..3bb464b3 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -329,23 +329,23 @@ namespace FreeSql.Internal { ExpressionType.Modulo, "%" }, { ExpressionType.Equal, "=" }, }; - public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString) + public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString, List dbParams) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = dbParams }); var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - return $"{sql} = {formatSql(true, null, null)}"; + return $"{sql} = {formatSql(true, null, null, null)}"; if (isBool) return GetBoolString(sql); return sql; } - public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression) + public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression, List dbParams) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = dbParams }); var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - return $"{sql} = {formatSql(true, null, null)}"; + return $"{sql} = {formatSql(true, null, null, null)}"; if (isBool) return GetBoolString(sql); return sql; @@ -357,7 +357,7 @@ namespace FreeSql.Internal var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - sql = $"{sql} = {formatSql(true, null, null)}"; + sql = $"{sql} = {formatSql(true, null, null, null)}"; if (isBool) sql = GetBoolString(sql); @@ -435,7 +435,7 @@ namespace FreeSql.Internal { var enumType = leftMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) - right = formatSql(Enum.Parse(enumType, right.StartsWith("N'") ? right.Substring(1).Trim('\'') : right.Trim('\'')), leftMapColumn.Attribute.MapType, leftMapColumn); + right = formatSql(Enum.Parse(enumType, right.StartsWith("N'") ? right.Substring(1).Trim('\'') : right.Trim('\'')), leftMapColumn.Attribute.MapType, leftMapColumn, tsc.dbParams); } if (leftMapColumn == null) { @@ -449,7 +449,7 @@ namespace FreeSql.Internal { var enumType = rightMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) - left = formatSql(Enum.Parse(enumType, left.StartsWith("N'") ? left.Substring(1).Trim('\'') : left.Trim('\'')), rightMapColumn.Attribute.MapType, rightMapColumn); + left = formatSql(Enum.Parse(enumType, left.StartsWith("N'") ? left.Substring(1).Trim('\'') : left.Trim('\'')), rightMapColumn.Attribute.MapType, rightMapColumn, tsc.dbParams); } } } @@ -457,8 +457,8 @@ namespace FreeSql.Internal { if (oper == "=") { - var trueVal = formatSql(true, null, null); - var falseVal = formatSql(false, null, null); + var trueVal = formatSql(true, null, null, null); + var falseVal = formatSql(false, null, null, null); if (left == trueVal) return right; else if (left == falseVal) return $"not({right})"; else if (right == trueVal) return left; @@ -466,8 +466,8 @@ namespace FreeSql.Internal } else if (oper == "<>") { - var trueVal = formatSql(true, null, null); - var falseVal = formatSql(false, null, null); + var trueVal = formatSql(true, null, null, null); + var falseVal = formatSql(false, null, null, null); if (left == trueVal) return $"not({right})"; else if (left == falseVal) return right; else if (right == trueVal) return $"not({left})"; @@ -489,9 +489,9 @@ namespace FreeSql.Internal break; case "AND": case "OR": - if (leftMapColumn != null) left = $"{left} = {formatSql(true, null, null)}"; + if (leftMapColumn != null) left = $"{left} = {formatSql(true, null, null, null)}"; else left = GetBoolString(left); - if (rightMapColumn != null) right = $"{right} = {formatSql(true, null, null)}"; + if (rightMapColumn != null) right = $"{right} = {formatSql(true, null, null, null)}"; else right = GetBoolString(right); break; } @@ -520,7 +520,7 @@ namespace FreeSql.Internal if (notBody.Contains(" IS NOT NULL")) return notBody.Replace(" IS NOT NULL", " IS NULL"); if (notBody.Contains("=")) return notBody.Replace("=", "!="); if (notBody.Contains("!=")) return notBody.Replace("!=", "="); - return $"{notBody} = {formatSql(false, null, null)}"; + return $"{notBody} = {formatSql(false, null, null, null)}"; } return $"not({ExpressionLambdaToSql(notExp, tsc)})"; case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); @@ -532,7 +532,7 @@ namespace FreeSql.Internal return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Negate: case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); - case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp); + case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); case ExpressionType.Conditional: var condExp = exp as ConditionalExpression; return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end"; @@ -890,7 +890,7 @@ namespace FreeSql.Internal //} other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; - if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp); + if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); throw new Exception($"未实现函数表达式 {exp3} 解析"); case ExpressionType.Parameter: case ExpressionType.MemberAccess: @@ -950,7 +950,7 @@ namespace FreeSql.Internal } break; } - if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp); + if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { @@ -1161,7 +1161,7 @@ namespace FreeSql.Internal } if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false) { - if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp); + if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); return ""; } return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc); @@ -1195,6 +1195,7 @@ namespace FreeSql.Internal public ColumnInfo mapColumnTmp { get; set; } public TableInfo currentTable { get; set; } public List whereCascadeExpression { get; set; } + public List dbParams { get; set; } public string alias001 { get; set; } //单表字段的表别名 public ExpTSC SetMapColumnTmp(ColumnInfo col) @@ -1229,8 +1230,12 @@ namespace FreeSql.Internal isQuoteName = this.isQuoteName, isDisableDiyParse = this.isDisableDiyParse, style = this.style, + //mapType = this.mapType, + //mapTypeTmp = this.mapTypeTmp, + //mapColumnTmp = this.mapColumnTmp, currentTable = this.currentTable, whereCascadeExpression = this.whereCascadeExpression, + dbParams = this.dbParams, alias001 = this.alias001 }; } @@ -1245,8 +1250,12 @@ namespace FreeSql.Internal isQuoteName = this.isQuoteName, isDisableDiyParse = true, style = this.style, + mapType = this.mapType, + mapTypeTmp = this.mapTypeTmp, + mapColumnTmp = this.mapColumnTmp, currentTable = this.currentTable, whereCascadeExpression = this.whereCascadeExpression, + dbParams = this.dbParams, alias001 = this.alias001 }; } @@ -1309,6 +1318,17 @@ namespace FreeSql.Internal } } - public string formatSql(object obj, Type mapType, ColumnInfo mapColumn) => string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn)); + public string formatSql(object obj, Type mapType, ColumnInfo mapColumn, List dbParams) + { + //参数化设置,日后优化 + //if (dbParams != null && mapColumn != null) + //{ + // var paramName = $"exp_{dbParams.Count}"; + // var parm = _common.AppendParamter(dbParams, paramName, mapColumn, mapType ?? mapColumn.Attribute.MapType, mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj)); + // _common.SetParameterSize(parm, mapColumn.Attribute.DbType, mapColumn); + // return _common.QuoteParamterName(paramName); + //} + return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn)); + } } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index ed1bac84..7bd56748 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -22,6 +22,7 @@ namespace FreeSql.Internal.CommonProvider protected int _whereTimes = 0; protected List _whereGlobalFilter; protected List _params = new List(); + protected bool _noneParameter; protected DbTransaction _transaction; protected DbConnection _connection; @@ -31,6 +32,7 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _table = _commonUtils.GetTableByEntity(typeof(T1)); + _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; this.Where(_commonUtils.WhereObject(_table, "", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); @@ -85,7 +87,7 @@ namespace FreeSql.Internal.CommonProvider } public abstract List ExecuteDeleted(); - public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null)); + public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _noneParameter ? _params : null)); public IDelete Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index fd4074c4..0bd497c1 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -451,7 +451,7 @@ namespace FreeSql.Internal.CommonProvider else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); } ++colidx2; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 69fce858..3e292a00 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -35,6 +35,7 @@ namespace FreeSql.Internal.CommonProvider protected Action _trackToList; protected List> _includeToList = new List>(); protected bool _distinct; + protected bool _noneParameter; protected Expression _selectExpression; protected List _whereCascadeExpression = new List(); protected List _whereGlobalFilter; @@ -105,6 +106,7 @@ namespace FreeSql.Internal.CommonProvider toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList); toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); + toType.GetField("_noneParameter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._noneParameter); toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); toType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression); toType.GetField("_whereGlobalFilter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereGlobalFilter); @@ -116,6 +118,7 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T1)), Alias = "a", On = null, Type = SelectTableInfoType.From }); + _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; this.Where(_commonUtils.WhereObject(_tables.First().Table, "a.", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); } @@ -1051,7 +1054,7 @@ namespace FreeSql.Internal.CommonProvider return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } - protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression)); + protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _noneParameter ? _params : null)); #endregion #if net40 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 372b46dc..39affc4c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -153,21 +153,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)) : this; } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -226,7 +226,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index db3be215..916e22ba 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -348,7 +348,7 @@ namespace FreeSql.Internal.CommonProvider if (tb == null) throw new Exception("Include 参数类型错误"); _isIncluded = true; - _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null); + _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null, null); return this; } @@ -422,7 +422,7 @@ namespace FreeSql.Internal.CommonProvider if (tbNav == null) throw new Exception($"类型 {typeof(TNavigate).FullName} 错误,不能使用 IncludeMany"); if (collMem.Expression.NodeType != ExpressionType.Parameter) - _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null); + _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null, null); TableRef tbref = null; var tbrefOneToManyColumns = new List>(); //临时 OneToMany 三个表关联,第三个表需要前两个表确定 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 1970e43c..8891dc13 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -130,21 +130,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -203,7 +203,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 641df438..dd18f595 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -133,21 +133,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -206,7 +206,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 95b8195b..64597f32 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -136,21 +136,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -209,7 +209,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index c78ce9be..af16c69b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -139,21 +139,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -212,7 +212,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 7a7a06be..ed6058ba 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -142,21 +142,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -215,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 39fb0d10..674f4503 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -145,21 +145,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -218,7 +218,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 92c54153..324fe9a0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -149,21 +149,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -222,7 +222,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 8db15de2..fcf28472 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -147,20 +147,20 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); } #if net40 @@ -169,7 +169,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); } Task ISelect.ToDataTableAsync(Expression> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 4021b1d9..0e402bd1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -84,7 +84,7 @@ namespace FreeSql.Internal.CommonProvider public ISelectGrouping Having(Expression, bool>> exp) { - var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null); + var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null, null); var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { sql, null }); return this; @@ -92,7 +92,7 @@ namespace FreeSql.Internal.CommonProvider public ISelectGrouping OrderBy(Expression, TMember>> column) { - var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null); + var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null, null); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { sql, null }); return this; @@ -100,7 +100,7 @@ namespace FreeSql.Internal.CommonProvider public ISelectGrouping OrderByDescending(Expression, TMember>> column) { - var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null); + var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null, null); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { $"{sql} DESC", null }); return this; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 51c04727..5eac94a6 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -353,7 +353,7 @@ namespace FreeSql.Internal.CommonProvider else { _set.Append(_commonUtils.QuoteWriteParamter(col.Column.Attribute.MapType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}")); - _commonUtils.AppendParamter(_params, null, col.Column.Attribute.MapType, paramVal); + _commonUtils.AppendParamter(_params, null, col.Column, col.Column.Attribute.MapType, paramVal); } //foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value); return this; @@ -365,7 +365,7 @@ namespace FreeSql.Internal.CommonProvider switch (nodeType) { case ExpressionType.Equal: - _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp, null)); + _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp, null, null)); return this; case ExpressionType.MemberInit: var initExp = body as MemberInitExpression; @@ -401,7 +401,7 @@ namespace FreeSql.Internal.CommonProvider if (body is BinaryExpression == false && nodeType != ExpressionType.Call) return this; var cols = new List(); - var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, exp, null); + var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, exp, null, null); if (cols.Any() == false) return this; foreach (var col in cols) { @@ -424,7 +424,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null)); + public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _noneParameter ? _params : null)); public IUpdate Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; @@ -564,7 +564,7 @@ namespace FreeSql.Internal.CommonProvider else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); - _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, val); + _commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val); } ++colidx; } @@ -603,7 +603,7 @@ namespace FreeSql.Internal.CommonProvider else { cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); - _commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, val); + _commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val); } if (val == null || val == DBNull.Value) nulls++; } diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 226d9c05..4b7d9d01 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -13,6 +13,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml; using System.Xml.XPath; @@ -23,7 +24,7 @@ namespace FreeSql.Internal { public abstract string GetNoneParamaterSqlValue(List specialParams, Type type, object value); - public abstract DbParameter AppendParamter(List _params, string parameterName, Type type, object value); + public abstract DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value); public abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); public abstract string FormatSql(string sql, params object[] args); public abstract string QuoteSqlName(string name); @@ -47,6 +48,25 @@ namespace FreeSql.Internal _orm = orm; } + static Regex _regexSize = new Regex(@"\(([^\)]+)\)", RegexOptions.Compiled); + internal void SetParameterSize(DbParameter parm, string dbtypeFull, ColumnInfo col) + { + if (col == null) return; + if (string.IsNullOrEmpty(dbtypeFull)) return; + var m = _regexSize.Match(dbtypeFull); + if (m.Success == false) return; + var sizeStr = m.Groups[1].Value.Trim(); + if (string.Compare(sizeStr, "max", true) == 0) + { + parm.Size = -1; + return; + } + var sizeArr = sizeStr.Split(','); + if (int.TryParse(sizeArr[0], out var size) == false) return; + if (sizeArr.Length > 1 && int.TryParse(sizeArr[1], out var size2)) size += size2; + parm.Size = size; + } + ConcurrentDictionary dicConfigEntity = new ConcurrentDictionary(); public ICodeFirst ConfigEntity(Action> entity) { diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 52804544..c9a70ec7 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -18,14 +18,22 @@ namespace FreeSql.MySql { } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) { - if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) + if (col != null && type == typeof(string)) + { + if (col.Attribute.DbType.Contains("VARCHAR")) ret.MySqlDbType = MySqlDbType.VarChar; + else if (col.Attribute.DbType.Contains("CHAR")) ret.MySqlDbType = MySqlDbType.VarChar; + else if (col.Attribute.DbType.Contains("TEXT")) ret.MySqlDbType = MySqlDbType.Text; + else ret.MySqlDbType = MySqlDbType.VarChar; + } + else if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { ret.MySqlDbType = MySqlDbType.Text; if (value != null) ret.Value = (value as MygisGeometry).AsText(); diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index f5646853..a1cfc9d6 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -18,14 +18,22 @@ namespace FreeSql.MySql { } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) { - if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) + if (col != null && type == typeof(string)) + { + if (col.Attribute.DbType.Contains("VARCHAR")) ret.MySqlDbType = MySqlDbType.VarChar; + else if (col.Attribute.DbType.Contains("CHAR")) ret.MySqlDbType = MySqlDbType.VarChar; + else if (col.Attribute.DbType.Contains("TEXT")) ret.MySqlDbType = MySqlDbType.Text; + else ret.MySqlDbType = MySqlDbType.VarChar; + } + else if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { ret.MySqlDbType = MySqlDbType.Text; if (value != null) ret.Value = (value as MygisGeometry).AsText(); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index 299ed4b9..c4db2879 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -16,9 +17,10 @@ namespace FreeSql.Odbc.Default public OdbcUtils(IFreeSql orm) : base(orm) { } public OdbcAdapter Adapter => _orm.GetOdbcAdapter(); - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index fa6f7949..4370826b 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -18,9 +18,10 @@ namespace FreeSql.Odbc.MySql { } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index 9b542be3..a5b9be8e 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -68,7 +68,7 @@ namespace FreeSql.Odbc.Oracle else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); } ++colidx2; } @@ -110,7 +110,7 @@ namespace FreeSql.Odbc.Oracle return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); - var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); @@ -179,7 +179,7 @@ namespace FreeSql.Odbc.Oracle return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); - var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index 3538f561..c2040d23 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -16,9 +16,10 @@ namespace FreeSql.Odbc.Oracle { } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (OdbcType)_orm.CodeFirst.GetDbInfo(type)?.type; switch (dbtype) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index fc3143cb..bed333aa 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -10,6 +10,7 @@ using System.Text; using System.Linq.Expressions; using System.Reflection; using System.Data.Odbc; +using FreeSql.Internal.Model; namespace FreeSql.Odbc.PostgreSQL { @@ -63,9 +64,10 @@ namespace FreeSql.Odbc.PostgreSQL return value; } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value != null) value = getParamterValue(type, value); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index 844b735f..c4497b17 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -21,9 +22,10 @@ namespace FreeSql.Odbc.SqlServer public bool IsSqlServer2005 => ServerVersion == 9; public int ServerVersion = 0; - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index e1d632ca..259c103b 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -70,7 +70,7 @@ namespace FreeSql.Oracle.Curd else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); } ++colidx2; } @@ -112,7 +112,7 @@ namespace FreeSql.Oracle.Curd return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); - var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0) as OracleParameter; + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0) as OracleParameter; identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); @@ -180,7 +180,7 @@ namespace FreeSql.Oracle.Curd return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); - var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0) as OracleParameter; + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0) as OracleParameter; identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 4e4e7c8a..cd0d8f79 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -16,9 +16,10 @@ namespace FreeSql.Oracle { } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; if (dbtype == OracleDbType.Boolean) { @@ -26,6 +27,14 @@ namespace FreeSql.Oracle else value = (bool)value == true ? 1 : 0; dbtype = OracleDbType.Int16; } + else if (col != null && type == typeof(string)) + { + if (col.Attribute.DbType.Contains("NVARCHAR2")) dbtype = OracleDbType.NVarchar2; + else if (col.Attribute.DbType.Contains("VARCHAR2")) dbtype = OracleDbType.Varchar2; + else if (col.Attribute.DbType.Contains("NCHAR")) dbtype = OracleDbType.NChar; + else if (col.Attribute.DbType.Contains("CHAR")) dbtype = OracleDbType.Char; + else dbtype = OracleDbType.NVarchar2; + } var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype, Value = value }; _params?.Add(ret); return ret; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 7f0ed104..b4556b31 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -13,6 +13,7 @@ using System.Net; using System.Text; using System.Linq.Expressions; using System.Reflection; +using FreeSql.Internal.Model; namespace FreeSql.PostgreSQL { @@ -78,16 +79,28 @@ namespace FreeSql.PostgreSQL return value; } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value != null) value = getParamterValue(type, value); var ret = new NpgsqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { // ret.DataTypeName = ""; //} else { var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; + if (tp != null) + { + if (col != null && type == typeof(string)) + { + if (col.Attribute.DbType.Contains("VARCHAR")) ret.NpgsqlDbType = NpgsqlDbType.Varchar; + else if (col.Attribute.DbType.Contains("CHAR")) ret.NpgsqlDbType = NpgsqlDbType.Char; + else if (col.Attribute.DbType.Contains("TEXT")) ret.NpgsqlDbType = NpgsqlDbType.Text; + else ret.NpgsqlDbType = NpgsqlDbType.Varchar; + } + else + ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; + } //} _params?.Add(ret); return ret; @@ -137,7 +150,7 @@ namespace FreeSql.PostgreSQL if (value == null) return "NULL"; if (_dicIsAssignableFromPostgisGeometry.GetOrAdd(type, t2 => typeof(PostgisGeometry).IsAssignableFrom(type.IsArray ? type.GetElementType() : type))) { - var pam = AppendParamter(specialParams, null, type, value); + var pam = AppendParamter(specialParams, null, null, type, value); return pam.ParameterName; } value = getParamterValue(type, value); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index e8b51ee5..beb264dd 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -21,13 +22,28 @@ namespace FreeSql.SqlServer public bool IsSqlServer2005 => ServerVersion == 9; public int ServerVersion = 0; - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new SqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; + if (tp != null) + { + if (col != null && type == typeof(string)) + { + if (col.Attribute.DbType.Contains("NVARCHAR")) ret.SqlDbType = SqlDbType.NVarChar; + else if (col.Attribute.DbType.Contains("VARCHAR")) ret.SqlDbType = SqlDbType.VarChar; + else if (col.Attribute.DbType.Contains("NCHAR")) ret.SqlDbType = SqlDbType.NChar; + else if (col.Attribute.DbType.Contains("CHAR")) ret.SqlDbType = SqlDbType.Char; + else if (col.Attribute.DbType.Contains("NTEXT")) ret.SqlDbType = SqlDbType.NText; + else if (col.Attribute.DbType.Contains("TEXT")) ret.SqlDbType = SqlDbType.Text; + else ret.SqlDbType = SqlDbType.VarChar; + } + else + ret.SqlDbType = (SqlDbType)tp.Value; + } _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 9f862c74..aecfde24 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -16,9 +16,10 @@ namespace FreeSql.Sqlite { } - public override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; switch (dbtype) { From e9a8ad70a1de2ba0fbc9a99628ae904265ea953c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 Nov 2019 21:55:36 +0800 Subject: [PATCH 0271/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ICodeFirst.I?= =?UTF-8?q?sGenerateCommandParameterWithLambda=20=E9=80=89=E9=A1=B9?= =?UTF-8?q?=EF=BC=8C=E5=BC=80=E5=90=AF=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=9A=84=E5=91=BD=E4=BB=A4=E5=8F=82=E6=95=B0=E5=8C=96?= =?UTF-8?q?=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20ExpressionCallContext=20?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=87=BD=E6=95=B0=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E6=A1=A3=20DbParameter=20=E5=B1=9E=E6=80=A7=EF=BC=9B?= =?UTF-8?q?=20-=20=E4=BF=AE=E5=A4=8D=20IncludeMany(a=20=3D>=20a.x1.x2.Chil?= =?UTF-8?q?ds)=20=E5=BD=93=20x1,=20x2=20=E4=B8=BA=20null=20=E7=9A=84?= =?UTF-8?q?=E6=8A=A5=20null=20=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Default/Curd/OdbcSelectTest.cs | 16 +- .../Default/MapType/BoolNullableTest.cs | 25 -- .../Default/MapType/BoolTest.cs | 25 -- .../Oracle/MapType/BoolNullableTest.cs | 25 -- .../Oracle/MapType/BoolTest.cs | 25 -- .../PostgreSQL/MapType/BoolNullableTest.cs | 25 -- .../PostgreSQL/MapType/BoolTest.cs | 25 -- .../SqlServer/Curd/SqlServerSelectTest.cs | 16 +- .../SqlServer/MapType/BoolNullableTest.cs | 25 -- .../SqlServer/MapType/BoolTest.cs | 25 -- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 8 + .../Oracle/MapType/BoolNullableTest.cs | 25 -- .../FreeSql.Tests/Oracle/MapType/BoolTest.cs | 25 -- .../PostgreSQL/MapType/BoolNullableTest.cs | 25 -- .../PostgreSQL/MapType/BoolTest.cs | 25 -- .../SqlServer/MapType/BoolNullableTest.cs | 25 -- .../SqlServer/MapType/BoolTest.cs | 25 -- .../Sqlite/MapType/BoolNullableTest.cs | 25 -- .../FreeSql.Tests/Sqlite/MapType/BoolTest.cs | 25 -- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 68 +++- .../ExpressionCallAttribute.cs | 8 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 13 +- FreeSql/FreeSql.xml | 322 ++++++++++-------- FreeSql/FreeSqlBuilder.cs | 11 + FreeSql/Interface/ICodeFirst.cs | 4 + FreeSql/Internal/CommonExpression.cs | 35 +- .../CommonProvider/CodeFirstProvider.cs | 1 + .../Internal/CommonProvider/DeleteProvider.cs | 4 +- .../SelectProvider/Select0Provider.cs | 5 +- .../SelectProvider/Select10Provider.cs | 8 +- .../SelectProvider/Select1Provider.cs | 81 +++-- .../SelectProvider/Select2Provider.cs | 8 +- .../SelectProvider/Select3Provider.cs | 8 +- .../SelectProvider/Select4Provider.cs | 8 +- .../SelectProvider/Select5Provider.cs | 8 +- .../SelectProvider/Select6Provider.cs | 8 +- .../SelectProvider/Select7Provider.cs | 8 +- .../SelectProvider/Select8Provider.cs | 8 +- .../SelectProvider/Select9Provider.cs | 8 +- .../Internal/CommonProvider/UpdateProvider.cs | 2 +- FreeSql/Internal/CommonUtils.cs | 19 -- FreeSql/Internal/Model/ColumnInfo.cs | 4 + FreeSql/Internal/UtilsExpressionTree.cs | 28 ++ .../FreeSql.Provider.MySql/MySqlUtils.cs | 35 +- .../MySqlConnectorUtils.cs | 43 +-- .../Default/OdbcUtils.cs | 1 - .../MySql/OdbcMySqlUtils.cs | 1 - .../Oracle/OdbcOracleUtils.cs | 1 - .../PostgreSQL/OdbcPostgreSQLUtils.cs | 1 - .../SqlServer/OdbcSqlServerUtils.cs | 1 - .../FreeSql.Provider.Oracle/OracleUtils.cs | 26 +- .../PostgreSQLUtils.cs | 17 +- .../SqlServerUtils.cs | 20 +- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 1 - 54 files changed, 518 insertions(+), 746 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index a381b2fa..b3ee6661 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -725,15 +725,15 @@ namespace FreeSql.Tests.Odbc.Default [Fact] public void Sum() { - var subquery = select.ToSql(a => new + var subquery = select.Where(a => a.Id < 200).ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); - var subqueryList = select.ToList(a => new + var subqueryList = select.Where(a => a.Id < 200).ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); } [Fact] @@ -767,15 +767,15 @@ namespace FreeSql.Tests.Odbc.Default [Fact] public void Avg() { - var subquery = select.ToSql(a => new + var subquery = select.Where(a => a.Id < 200).ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); - var subqueryList = select.ToList(a => new + var subqueryList = select.Where(a => a.Id < 200).ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs index b13d90e9..ec8f5d6a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.Odbc.DefaultMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs index cf68b373..544aca1d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/MapType/BoolTest.cs @@ -1100,30 +1100,5 @@ namespace FreeSql.Tests.Odbc.DefaultMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs index e2c5c4ee..e6f685a6 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.Odbc.OracleMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs index decd881f..54ee44e8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.Odbc.OracleMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs index 0c8c0d7f..c9e0dcce 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.Odbc.PostgreSQLMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs index a91a204f..b88d79a9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.Odbc.PostgreSQLMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 0174b4aa..d604deeb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -706,15 +706,15 @@ namespace FreeSql.Tests.Odbc.SqlServer [Fact] public void Sum() { - var subquery = select.ToSql(a => new + var subquery = select.Where(a => a.Id < 200).ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); - var subqueryList = select.ToList(a => new + var subqueryList = select.Where(a => a.Id < 200).ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = select.Where(b => b.Id < 200).Sum(b => b.Id) }); } [Fact] @@ -748,15 +748,15 @@ namespace FreeSql.Tests.Odbc.SqlServer [Fact] public void Avg() { - var subquery = select.ToSql(a => new + var subquery = select.Where(a => a.Id < 100).ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.Where(b => b.Id < 100).Avg(b => b.Id) }); - var subqueryList = select.ToList(a => new + var subqueryList = select.Where(a => a.Id < 100).ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.Where(b => b.Id < 100).Avg(b => b.Id) }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs index 328f733b..ee59233e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolNullableTest.cs @@ -1568,30 +1568,5 @@ namespace FreeSql.Tests.Odbc.SqlServerMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs index b7ec3e4e..5d152b19 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.Odbc.SqlServerMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 6e6ec049..d0b42783 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -204,6 +204,14 @@ 回复的文本内容 + + + 设置表达式中的 string 参数化长度,优化执行计划 + + + + + 调价单 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs index d3da1a49..0224c6c5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.OracleMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs index 0aab5f9f..d0dd9c37 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.OracleMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs index 73804ba1..2a5038d9 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.PostgreSQLMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs index 37ce2ca4..574facca 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.PostgreSQLMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs index ad683985..86552fc1 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolNullableTest.cs @@ -1577,30 +1577,5 @@ namespace FreeSql.Tests.SqlServerMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs index 9d3e5d46..7c5ab8ff 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/BoolTest.cs @@ -1110,30 +1110,5 @@ namespace FreeSql.Tests.SqlServerMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs index 1d261272..78d46bd2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolNullableTest.cs @@ -1567,30 +1567,5 @@ namespace FreeSql.Tests.SqliteMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs index 846817f5..367910bd 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/MapType/BoolTest.cs @@ -1101,30 +1101,5 @@ namespace FreeSql.Tests.SqliteMapType public void GuidNullable() { } - - [Fact] - public void MygisPoint() - { - } - [Fact] - public void MygisLineString() - { - } - [Fact] - public void MygisPolygon() - { - } - [Fact] - public void MygisMultiPoint() - { - } - [Fact] - public void MygisMultiLineString() - { - } - [Fact] - public void MygisMultiPolygon() - { - } } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 97b4b8d1..1f809d0f 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -185,8 +185,6 @@ namespace FreeSql.Tests [Fact] public void Test02() { - var testparmSelect = g.sqlserver.Select().Where(a => a.nvarchar == "11" && a.nvarchar_notnull == "22" && a.nvarchar_null == "33" && a.varchar == "11" && a.varchar_notnull == "22" && a.varchar_null == "33"); - var slsksd = g.mysql.Update().SetSource(new UserLike { Id = Guid.NewGuid(), CreateUserId = 1000, SubjectId = Guid.NewGuid() }) .UpdateColumns(a => new { @@ -291,6 +289,57 @@ namespace FreeSql.Tests var sql = g.sqlite.Select() .ToSql(a => a.CreateTime.FormatDateTime("yyyy-MM-dd")); + + + var parm1 = "11"; + var parm2 = "22"; + var parm3 = "33"; + var testparmSelect = g.sqlserver.Select() + .Where(a => + a.nvarchar == "11" && + a.nvarchar_notnull == "22" && + a.nvarchar_null == "33" && + a.varchar == "11" && + a.varchar_notnull == "22" && + a.varchar_null == "33" && + + a.nvarchar == parm1 && + a.nvarchar_notnull == parm2 && + a.nvarchar_null == parm3 && + a.varchar == parm3 && + a.varchar_notnull == parm2 && + a.varchar_null == parm3 && + + a.nvarchar == parm1.SetDbParameter(10) && + a.nvarchar_notnull == parm2.SetDbParameter(11) && + a.nvarchar_null == parm3.SetDbParameter(12) && + a.varchar == parm3.SetDbParameter(13) && + a.varchar_notnull == parm2.SetDbParameter(14) && + a.varchar_null == parm3.SetDbParameter(15) && + + + "11" == a.nvarchar && + "22" == a.nvarchar_notnull && + "33" == a.nvarchar_null && + "11" == a.varchar && + "22" == a.varchar_notnull && + "33" == a.varchar_null && + + parm1 == a.nvarchar && + parm2 == a.nvarchar_notnull && + parm3 == a.nvarchar_null && + parm1 == a.varchar && + parm2 == a.varchar_notnull && + parm3 == a.varchar_null && + + parm1.SetDbParameter(10) == a.nvarchar && + parm2.SetDbParameter(11) == a.nvarchar_notnull && + parm3.SetDbParameter(12) == a.nvarchar_null && + parm1.SetDbParameter(13) == a.varchar && + parm2.SetDbParameter(14) == a.varchar_notnull && + parm3.SetDbParameter(15) == a.varchar_null + + ); } } @@ -301,7 +350,20 @@ namespace FreeSql.Tests public static string FormatDateTime(this DateTime that, string arg1) { - return $"date_format({context.Value.Values["arg1"]})"; + return $"date_format({context.Value.Values["that"]}, {context.Value.Values["arg1"]})"; + } + + /// + /// 设置表达式中的 string 参数化长度,优化执行计划 + /// + /// + /// + /// + public static string SetDbParameter(this string that, int size) + { + if (context.Value.DbParameter != null) + context.Value.DbParameter.Size = size; + return context.Value.Values["that"]; } } } diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs index 4cd22f54..3c27b078 100644 --- a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs +++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Text; namespace FreeSql.DataAnnotations @@ -18,11 +19,16 @@ namespace FreeSql.DataAnnotations /// /// 数据库类型,可用于适配多种数据库环境 /// - public DataType DataType { get; set; } + public DataType DataType { get; internal set; } /// /// 已解析的表达式中参数内容 /// public Dictionary Values { get; } = new Dictionary(); + + /// + /// 主对象的参数化对象,可重塑其属性 + /// + public DbParameter DbParameter { get; internal set; } } } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 1bea2b5d..9a2604b7 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -128,16 +128,9 @@ public static partial class FreeSqlGlobalExtensions /// /// /// - public static ISelect AsSelect(this IEnumerable that) where TEntity : class - { - throw new NotImplementedException(); - } - public static ISelect AsSelect(this IEnumerable that, IFreeSql orm = null) where TEntity : class - { - return orm?.Select(); - } - - public static FreeSql.ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); + public static ISelect AsSelect(this IEnumerable that) where TEntity : class => throw new NotImplementedException(); + public static ISelect AsSelect(this IEnumerable that, IFreeSql orm = null) where TEntity : class => orm?.Select(); + public static ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); #region 多表查询 /// diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 56b67dc0..dbe7beb2 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -168,6 +168,11 @@ 已解析的表达式中参数内容 + + + 主对象的参数化对象,可重塑其属性 + + 索引名 @@ -587,6 +592,13 @@ + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + + + + 延时加载导航属性对象,导航属性需要声明 virtual @@ -2282,156 +2294,7 @@ - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构 - - - - - 转大写同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - - - - - - 将实体类型集合与数据库对比,返回DDL语句 - - 实体类型 - - - - - 将实体类型与数据库对比,返回DDL语句(指定表名) - - 实体类型 - 指定表名对比 - - - - - 同步实体类型到数据库 - - - - - - - 同步实体类型集合到数据库 - - - - - - - 同步实体类型到数据库(指定表名) - - 实体类型 - 指定表名对比 - - - - - 根据 System.Type 获取数据库信息 - - - - - - - 在外部配置实体的特性 - - - - - - - - 在外部配置实体的特性 - - - + 耗时(单位:毫秒 @@ -2626,6 +2489,165 @@ + + + 多表查询 + + + + + + + + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 中间表,多对多 + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + + + 测量两个经纬度的距离,返回单位:米 + + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) + + + + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + + + + + + + + 多表查询 + + + 多表查询 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index f7e979ca..fb754ac8 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -17,6 +17,7 @@ namespace FreeSql bool _isSyncStructureToUpper = false; bool _isConfigEntityFromDbFirst = false; bool _isNoneCommandParameter = false; + bool _isGenerateCommandParameterWithLambda = false; bool _isLazyLoading = false; StringConvertType _entityPropertyConvertType = StringConvertType.None; Action _aopCommandExecuting = null; @@ -100,6 +101,16 @@ namespace FreeSql return this; } /// + /// 是否生成命令参数化执行,针对 lambda 表达式解析 + /// + /// + /// + public FreeSqlBuilder UseGenerateCommandParameterWithLambda(bool value) + { + _isGenerateCommandParameterWithLambda = value; + return this; + } + /// /// 延时加载导航属性对象,导航属性需要声明 virtual /// /// diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index e79fe7cc..2d1cec92 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -31,6 +31,10 @@ namespace FreeSql /// bool IsNoneCommandParameter { get; set; } /// + /// 是否生成命令参数化执行,针对 lambda 表达式解析 + /// + bool IsGenerateCommandParameterWithLambda { get; set; } + /// /// 延时加载导航属性对象,导航属性需要声明 virtual /// bool IsLazyLoading { get; set; } diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 3bb464b3..6cc728e0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -423,13 +423,14 @@ namespace FreeSql.Internal return $"({ExpressionLambdaToSql(leftExp, tsc)} {oper} {ExpressionLambdaToSql(rightExp, tsc)})"; } + Type oldMapType = null; var left = ExpressionLambdaToSql(leftExp, tsc); var leftMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, left); var isLeftMapType = leftMapColumn != null && new[] { "AND", "OR" }.Contains(oper) == false && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type); ColumnInfo rightMapColumn = null; var isRightMapType = false; - if (isLeftMapType) tsc.mapType = leftMapColumn.Attribute.MapType; - + if (isLeftMapType) oldMapType = tsc.SetMapTypeReturnOld(leftMapColumn.Attribute.MapType); + var right = ExpressionLambdaToSql(rightExp, tsc); if (right != "NULL" && isLeftMapType) { @@ -443,7 +444,7 @@ namespace FreeSql.Internal isRightMapType = rightMapColumn != null && new[] { "AND", "OR" }.Contains(oper) == false && (rightMapColumn.Attribute.MapType != leftExp.Type || rightMapColumn.CsType != leftExp.Type); if (isRightMapType) { - tsc.mapType = rightMapColumn.Attribute.MapType; + oldMapType = tsc.SetMapTypeReturnOld(rightMapColumn.Attribute.MapType); left = ExpressionLambdaToSql(leftExp, tsc); if (left != "NULL" && isRightMapType) { @@ -495,7 +496,7 @@ namespace FreeSql.Internal else right = GetBoolString(right); break; } - tsc.mapType = null; + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); return $"{left} {oper} {right}"; } static ConcurrentDictionary _dicTypeExistsExpressionCallAttribute = new ConcurrentDictionary(); @@ -532,7 +533,7 @@ namespace FreeSql.Internal return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Negate: case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); - case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, null); case ExpressionType.Conditional: var condExp = exp as ConditionalExpression; return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end"; @@ -543,15 +544,21 @@ namespace FreeSql.Internal { var ecc = new ExpressionCallContext { DataType = _ado.DataType }; var exp3MethodParams = exp3.Method.GetParameters(); - for (var a = 0; a < exp3.Arguments.Count; a++) + var dbParamsIndex = tsc.dbParams?.Count; + ecc.Values.Add(exp3MethodParams[0].Name, ExpressionLambdaToSql(exp3.Arguments[0], tsc)); + if (tsc.dbParams?.Count > dbParamsIndex) ecc.DbParameter = tsc.dbParams.Last(); + List oldDbParams = tsc.dbParams; + tsc.dbParams = null; + for (var a = 1; a < exp3.Arguments.Count; a++) if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) ecc.Values.Add(exp3MethodParams[a].Name, ExpressionLambdaToSql(exp3.Arguments[a], tsc)); + tsc.dbParams = oldDbParams; var exp3InvokeParams = new object[exp3.Arguments.Count]; for (var a = 0; a < exp3.Arguments.Count; a++) { if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) - exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); + exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, ecc.Values[exp3MethodParams[a].Name]);// exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); else exp3InvokeParams[a] = ecc; } @@ -1321,13 +1328,13 @@ namespace FreeSql.Internal public string formatSql(object obj, Type mapType, ColumnInfo mapColumn, List dbParams) { //参数化设置,日后优化 - //if (dbParams != null && mapColumn != null) - //{ - // var paramName = $"exp_{dbParams.Count}"; - // var parm = _common.AppendParamter(dbParams, paramName, mapColumn, mapType ?? mapColumn.Attribute.MapType, mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj)); - // _common.SetParameterSize(parm, mapColumn.Attribute.DbType, mapColumn); - // return _common.QuoteParamterName(paramName); - //} + if (dbParams != null) + { + var paramName = $"exp_{dbParams.Count}"; + var parm = _common.AppendParamter(dbParams, paramName, mapColumn, + mapType ?? mapColumn?.Attribute.MapType ?? obj?.GetType(), mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj)); + return _common.QuoteParamterName(paramName); + } return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn)); } } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 3ecb796a..cf1cf470 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -32,6 +32,7 @@ namespace FreeSql.Internal.CommonProvider public bool IsSyncStructureToUpper { get; set; } = false; public bool IsConfigEntityFromDbFirst { get; set; } = false; public virtual bool IsNoneCommandParameter { get; set; } = false; + public virtual bool IsGenerateCommandParameterWithLambda { get; set; } = false; public bool IsLazyLoading { get; set; } = false; public abstract (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 7bd56748..e2d816dc 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -22,7 +22,6 @@ namespace FreeSql.Internal.CommonProvider protected int _whereTimes = 0; protected List _whereGlobalFilter; protected List _params = new List(); - protected bool _noneParameter; protected DbTransaction _transaction; protected DbConnection _connection; @@ -32,7 +31,6 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _table = _commonUtils.GetTableByEntity(typeof(T1)); - _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; this.Where(_commonUtils.WhereObject(_table, "", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); @@ -87,7 +85,7 @@ namespace FreeSql.Internal.CommonProvider } public abstract List ExecuteDeleted(); - public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _noneParameter ? _params : null)); + public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); public IDelete Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 3e292a00..1135f7bd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -35,7 +35,6 @@ namespace FreeSql.Internal.CommonProvider protected Action _trackToList; protected List> _includeToList = new List>(); protected bool _distinct; - protected bool _noneParameter; protected Expression _selectExpression; protected List _whereCascadeExpression = new List(); protected List _whereGlobalFilter; @@ -106,7 +105,6 @@ namespace FreeSql.Internal.CommonProvider toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList); toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); - toType.GetField("_noneParameter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._noneParameter); toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); toType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression); toType.GetField("_whereGlobalFilter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereGlobalFilter); @@ -118,7 +116,6 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T1)), Alias = "a", On = null, Type = SelectTableInfoType.From }); - _noneParameter = _orm.CodeFirst.IsNoneCommandParameter; this.Where(_commonUtils.WhereObject(_tables.First().Table, "a.", dywhere)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); } @@ -1054,7 +1051,7 @@ namespace FreeSql.Internal.CommonProvider return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } - protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _noneParameter ? _params : null)); + protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); #endregion #if net40 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 39affc4c..445641dc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -153,21 +153,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)) : this; } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -226,7 +226,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 916e22ba..c84f2328 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -543,23 +543,48 @@ namespace FreeSql.Internal.CommonProvider var t1parm = Expression.Parameter(typeof(T1)); Expression membersExp = t1parm; - foreach (var mem in members) membersExp = Expression.MakeMemberAccess(membersExp, mem.Member); + Expression membersExpNotNull = null; + foreach (var mem in members) + { + membersExp = Expression.MakeMemberAccess(membersExp, mem.Member); + var expNotNull = Expression.NotEqual(membersExp, Expression.Constant(null)); + if (membersExpNotNull == null) membersExpNotNull = expNotNull; + else membersExpNotNull = Expression.AndAlso(membersExpNotNull, expNotNull); + } members.Clear(); var listValueExp = Expression.Parameter(typeof(List), "listValue"); - var setListValue = Expression.Lambda>>( - Expression.Assign( - Expression.MakeMemberAccess(membersExp, collMem.Member), - Expression.TypeAs(listValueExp, collMem.Type) - ), t1parm, listValueExp).Compile(); + var setListValue = membersExpNotNull == null ? + Expression.Lambda>>( + Expression.Assign( + Expression.MakeMemberAccess(membersExp, collMem.Member), + Expression.TypeAs(listValueExp, collMem.Type) + ), t1parm, listValueExp).Compile() : + Expression.Lambda>>( + Expression.IfThen( + membersExpNotNull, + Expression.Assign( + Expression.MakeMemberAccess(membersExp, collMem.Member), + Expression.TypeAs(listValueExp, collMem.Type) + ) + ), t1parm, listValueExp).Compile(); var returnTarget = Expression.Label(typeof(object)); var propertyNameExp = Expression.Parameter(typeof(string), "propertyName"); - var getListValue1 = Expression.Lambda>( - Expression.Block( - Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - ), t1parm, propertyNameExp).Compile(); + var getListValue1 = membersExpNotNull == null ? + Expression.Lambda>( + Expression.Block( + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile(): + Expression.Lambda>( + Expression.Block( + Expression.IfThen( + membersExpNotNull, + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)) + ), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile(); var getListValue2 = new List>(); for (var j = 0; j < tbrefOneToManyColumns.Count; j++) @@ -570,13 +595,29 @@ namespace FreeSql.Internal.CommonProvider continue; } Expression tbrefOneToManyColumnsMembers = t1parm; - foreach (var mem in tbrefOneToManyColumns[j]) tbrefOneToManyColumnsMembers = Expression.MakeMemberAccess(tbrefOneToManyColumnsMembers, mem.Member); + Expression tbrefOneToManyColumnsMembersNotNull = null; + foreach (var mem in tbrefOneToManyColumns[j]) + { + tbrefOneToManyColumnsMembers = Expression.MakeMemberAccess(tbrefOneToManyColumnsMembers, mem.Member); + var expNotNull = Expression.NotEqual(membersExp, Expression.Constant(null)); + if (tbrefOneToManyColumnsMembersNotNull == null) tbrefOneToManyColumnsMembersNotNull = expNotNull; + else tbrefOneToManyColumnsMembersNotNull = Expression.AndAlso(tbrefOneToManyColumnsMembersNotNull, expNotNull); + } tbrefOneToManyColumns[j].Clear(); - getListValue2.Add(Expression.Lambda>( - Expression.Block( - Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)), - Expression.Label(returnTarget, Expression.Default(typeof(object))) - ), t1parm, propertyNameExp).Compile()); + getListValue2.Add(tbrefOneToManyColumnsMembersNotNull == null ? + Expression.Lambda>( + Expression.Block( + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile() : + Expression.Lambda>( + Expression.Block( + Expression.IfThen( + tbrefOneToManyColumnsMembersNotNull, + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)) + ), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + ), t1parm, propertyNameExp).Compile()); } tbrefOneToManyColumns.Clear(); Func getListValue = (item, propName, colIndex) => @@ -706,7 +747,8 @@ namespace FreeSql.Internal.CommonProvider { if (tbref.Columns.Count == 1) { - var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0).ToString(); + var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0)?.ToString(); + if (dicListKey == null) continue; var dicListVal = Tuple.Create(item, new List()); if (dicList.TryGetValue(dicListKey, out var items) == false) dicList.Add(dicListKey, items = new List>>()); @@ -891,7 +933,8 @@ namespace FreeSql.Internal.CommonProvider { if (tbref.Columns.Count == 1) { - var dicListKey = getListValue1(item, tbref.Columns[0].CsName).ToString(); + var dicListKey = getListValue1(item, tbref.Columns[0].CsName)?.ToString(); + if (dicListKey == null) continue; var dicListVal = Tuple.Create(item, new List()); if (dicList.TryGetValue(dicListKey, out var items) == false) dicList.Add(dicListKey, items = new List>>()); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 8891dc13..25dc239e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -130,21 +130,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -203,7 +203,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index dd18f595..f355d1b5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -133,21 +133,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -206,7 +206,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 64597f32..04b4cc8d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -136,21 +136,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -209,7 +209,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index af16c69b..c7438f9b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -139,21 +139,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -212,7 +212,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index ed6058ba..de717933 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -142,21 +142,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -215,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 674f4503..1ec020d8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -145,21 +145,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -218,7 +218,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 324fe9a0..fd6b33fe 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -149,21 +149,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -222,7 +222,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index fcf28472..ff3098ef 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -147,20 +147,20 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); } #if net40 @@ -169,7 +169,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _noneParameter ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); } Task ISelect.ToDataTableAsync(Expression> select) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 5eac94a6..28d60260 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -424,7 +424,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _noneParameter ? _params : null)); + public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); public IUpdate Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 4b7d9d01..1adbebfa 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -48,25 +48,6 @@ namespace FreeSql.Internal _orm = orm; } - static Regex _regexSize = new Regex(@"\(([^\)]+)\)", RegexOptions.Compiled); - internal void SetParameterSize(DbParameter parm, string dbtypeFull, ColumnInfo col) - { - if (col == null) return; - if (string.IsNullOrEmpty(dbtypeFull)) return; - var m = _regexSize.Match(dbtypeFull); - if (m.Success == false) return; - var sizeStr = m.Groups[1].Value.Trim(); - if (string.Compare(sizeStr, "max", true) == 0) - { - parm.Size = -1; - return; - } - var sizeArr = sizeStr.Split(','); - if (int.TryParse(sizeArr[0], out var size) == false) return; - if (sizeArr.Length > 1 && int.TryParse(sizeArr[1], out var size2)) size += size2; - parm.Size = size; - } - ConcurrentDictionary dicConfigEntity = new ConcurrentDictionary(); public ICodeFirst ConfigEntity(Action> entity) { diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index fbc26e05..84780850 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -13,6 +13,10 @@ namespace FreeSql.Internal.Model public Type CsType { get; set; } public ColumnAttribute Attribute { get; set; } public string Comment { get; internal set; } + public string DbTypeText { get; internal set; } + public int DbSize { get; internal set; } + public byte DbPrecision { get; internal set; } + public byte DbScale { get; internal set; } static ConcurrentDictionary> _dicGetMapValue = new ConcurrentDictionary>(); public object GetMapValue(object obj) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index cecb8816..5904d7fa 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -299,6 +299,34 @@ namespace FreeSql.Internal col.Attribute.IsNullable = false; col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", ""); } + foreach (var col in trytb.Columns.Values) + { + var ltp = @"\(([^\)]+)\)"; + col.DbTypeText = Regex.Replace(col.Attribute.DbType.Replace("NOT NULL", "").Trim(), ltp, ""); + var m = Regex.Match(col.Attribute.DbType, ltp); + if (m.Success == false) continue; + var sizeStr = m.Groups[1].Value.Trim(); + if (string.Compare(sizeStr, "max", true) == 0) + { + col.DbSize = -1; + continue; + } + var sizeArr = sizeStr.Split(','); + if (int.TryParse(sizeArr[0].Trim(), out var size) == false) continue; + if (col.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime)) + { + col.DbScale = (byte)size; + continue; + } + if (sizeArr.Length == 1) + { + col.DbSize = size; + continue; + } + if (byte.TryParse(sizeArr[1], out var scale) == false) continue; + col.DbPrecision = (byte)size; + col.DbScale = scale; + } tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index c9a70ec7..e76342d8 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -21,26 +21,31 @@ namespace FreeSql.MySql public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) + var dbtype = (MySqlDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + if (col != null) { - if (col != null && type == typeof(string)) + var dbtype2 = (MySqlDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText, DbTypeTextFull = col.Attribute.DbType, MaxLength = col.DbSize }); + switch (dbtype2) { - if (col.Attribute.DbType.Contains("VARCHAR")) ret.MySqlDbType = MySqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("CHAR")) ret.MySqlDbType = MySqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("TEXT")) ret.MySqlDbType = MySqlDbType.Text; - else ret.MySqlDbType = MySqlDbType.VarChar; + case MySqlDbType.Binary: + case MySqlDbType.VarBinary: + break; + default: + dbtype = dbtype2; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; } - else if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) - { - ret.MySqlDbType = MySqlDbType.Text; - if (value != null) ret.Value = (value as MygisGeometry).AsText(); - } - else - ret.MySqlDbType = (MySqlDbType)tp.Value; } + if (dbtype == MySqlDbType.Geometry) + { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } + else + ret.MySqlDbType = dbtype; _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index a1cfc9d6..1fe7e253 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -21,30 +21,35 @@ namespace FreeSql.MySql public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) + var dbtype = (MySqlDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + if (col != null) { - if (col != null && type == typeof(string)) + var dbtype2 = (MySqlDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText, DbTypeTextFull = col.Attribute.DbType, MaxLength = col.DbSize }); + switch (dbtype2) { - if (col.Attribute.DbType.Contains("VARCHAR")) ret.MySqlDbType = MySqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("CHAR")) ret.MySqlDbType = MySqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("TEXT")) ret.MySqlDbType = MySqlDbType.Text; - else ret.MySqlDbType = MySqlDbType.VarChar; - } - else if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) - { - ret.MySqlDbType = MySqlDbType.Text; - if (value != null) ret.Value = (value as MygisGeometry).AsText(); - } - else - { - ret.MySqlDbType = (MySqlDbType)tp.Value; - if (ret.MySqlDbType == MySqlDbType.Enum && value != null) - ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + //case MySqlDbType.Binary: + //case MySqlDbType.VarBinary: + // break; + default: + dbtype = dbtype2; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; } } + if (dbtype == MySqlDbType.Geometry) + { + ret.MySqlDbType = MySqlDbType.Text; + if (value != null) ret.Value = (value as MygisGeometry).AsText(); + } + else + { + ret.MySqlDbType = dbtype; + if (ret.MySqlDbType == MySqlDbType.Enum && value != null) + ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + } _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index c4db2879..c589bcdb 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -20,7 +20,6 @@ namespace FreeSql.Odbc.Default public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 4370826b..dc53f35a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -21,7 +21,6 @@ namespace FreeSql.Odbc.MySql public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index c2040d23..8827a089 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -19,7 +19,6 @@ namespace FreeSql.Odbc.Oracle public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (OdbcType)_orm.CodeFirst.GetDbInfo(type)?.type; switch (dbtype) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index bed333aa..c9bcbc21 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -67,7 +67,6 @@ namespace FreeSql.Odbc.PostgreSQL public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value != null) value = getParamterValue(type, value); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index c4497b17..02f18715 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -25,7 +25,6 @@ namespace FreeSql.Odbc.SqlServer public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index cd0d8f79..11c46adc 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -19,7 +19,6 @@ namespace FreeSql.Oracle public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; if (dbtype == OracleDbType.Boolean) { @@ -27,15 +26,24 @@ namespace FreeSql.Oracle else value = (bool)value == true ? 1 : 0; dbtype = OracleDbType.Int16; } - else if (col != null && type == typeof(string)) - { - if (col.Attribute.DbType.Contains("NVARCHAR2")) dbtype = OracleDbType.NVarchar2; - else if (col.Attribute.DbType.Contains("VARCHAR2")) dbtype = OracleDbType.Varchar2; - else if (col.Attribute.DbType.Contains("NCHAR")) dbtype = OracleDbType.NChar; - else if (col.Attribute.DbType.Contains("CHAR")) dbtype = OracleDbType.Char; - else dbtype = OracleDbType.NVarchar2; - } var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype, Value = value }; + if (col != null) + { + var dbtype2 = (OracleDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeTextFull = col.Attribute.DbType.Replace("NOT NULL", "").Trim(), DbTypeText = col.DbTypeText }); + switch (dbtype2) + { + case OracleDbType.Char: + case OracleDbType.Varchar2: + case OracleDbType.NChar: + case OracleDbType.NVarchar2: + case OracleDbType.Decimal: + dbtype = dbtype2; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; + } + } _params?.Add(ret); return ret; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index b4556b31..ce2213a7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -82,24 +82,23 @@ namespace FreeSql.PostgreSQL public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value != null) value = getParamterValue(type, value); var ret = new NpgsqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { // ret.DataTypeName = ""; //} else { var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) + if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; + if (col != null) { - if (col != null && type == typeof(string)) + var dbtype = (NpgsqlDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText }); + if (dbtype != NpgsqlDbType.Unknown) { - if (col.Attribute.DbType.Contains("VARCHAR")) ret.NpgsqlDbType = NpgsqlDbType.Varchar; - else if (col.Attribute.DbType.Contains("CHAR")) ret.NpgsqlDbType = NpgsqlDbType.Char; - else if (col.Attribute.DbType.Contains("TEXT")) ret.NpgsqlDbType = NpgsqlDbType.Text; - else ret.NpgsqlDbType = NpgsqlDbType.Varchar; + ret.NpgsqlDbType = dbtype; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; } - else - ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; } //} _params?.Add(ret); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index beb264dd..56659c60 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -25,24 +25,20 @@ namespace FreeSql.SqlServer public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new SqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) + if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; + if (col != null) { - if (col != null && type == typeof(string)) + var dbtype = (SqlDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText }); + if (dbtype != SqlDbType.Variant) { - if (col.Attribute.DbType.Contains("NVARCHAR")) ret.SqlDbType = SqlDbType.NVarChar; - else if (col.Attribute.DbType.Contains("VARCHAR")) ret.SqlDbType = SqlDbType.VarChar; - else if (col.Attribute.DbType.Contains("NCHAR")) ret.SqlDbType = SqlDbType.NChar; - else if (col.Attribute.DbType.Contains("CHAR")) ret.SqlDbType = SqlDbType.Char; - else if (col.Attribute.DbType.Contains("NTEXT")) ret.SqlDbType = SqlDbType.NText; - else if (col.Attribute.DbType.Contains("TEXT")) ret.SqlDbType = SqlDbType.Text; - else ret.SqlDbType = SqlDbType.VarChar; + ret.SqlDbType = dbtype; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; } - else - ret.SqlDbType = (SqlDbType)tp.Value; } _params?.Add(ret); return ret; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index aecfde24..498ef244 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -19,7 +19,6 @@ namespace FreeSql.Sqlite public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) { if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (type == null && col != null) type = col.Attribute.MapType ?? col.CsType; var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; switch (dbtype) { From 6e6135e9e79a168fd4b310f4ffdee16664fc7f82 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 Nov 2019 22:36:18 +0800 Subject: [PATCH 0272/1029] ## v0.12.1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 54 +-- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 315 +++++++++--------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 15 files changed, 199 insertions(+), 196 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index ad55d9e7..3a2baa84 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.11.24 + 0.12.1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 355c0aa6..49ee9064 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 2afb29f2..97277140 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 3bb3e9ec..7c998e32 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7d836478..762ec280 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.12.1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 1f809d0f..a9d10edd 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -225,7 +225,7 @@ namespace FreeSql.Tests var tbs = g.sqlserver.DbFirst.GetTablesByDatabase("ds_shop"); var dicParamslist = g.sqlite.Select().Page(1, 10) - .Where("id > @id and id > @id2 and id > @id3", + .Where("id > @id and id > @id2 and id > @id3", new Dictionary { ["id"] = 1, ["id2"] = 2, ["id3"] = 3 }) .ToList(); @@ -240,7 +240,7 @@ namespace FreeSql.Tests .IncludeMany(m => m.Permissions, then => then.Include(a => a.Button)) .Page(1, 10) .ToList(); - + var comments1 = g.mysql.Select() .LeftJoin((a, b) => a.Id == b.SubjectId) .ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo }); @@ -295,7 +295,7 @@ namespace FreeSql.Tests var parm2 = "22"; var parm3 = "33"; var testparmSelect = g.sqlserver.Select() - .Where(a => + .Where(a => a.nvarchar == "11" && a.nvarchar_notnull == "22" && a.nvarchar_null == "33" && @@ -340,30 +340,38 @@ namespace FreeSql.Tests parm3.SetDbParameter(15) == a.varchar_null ); + + g.sqlserver.CodeFirst.IsGenerateCommandParameterWithLambda = true; + var name = "testname"; + var sdfsdgselect1 = g.sqlserver.Select().Where(a => a.varchar == name); + var sdfsdgselect2 = g.sqlserver.Select().Where(a => a.varchar == name.SetDbParameter(10)); + + g.sqlserver.Select().Where(a => a.varchar == name).ToList(); + g.sqlserver.Select().Where(a => a.varchar == name.SetDbParameter(10)).ToList(); } } - [ExpressionCall] - public static class DbFunc +[ExpressionCall] +public static class DbFunc +{ + static ThreadLocal context = new ThreadLocal(); + + public static string FormatDateTime(this DateTime that, string arg1) { - static ThreadLocal context = new ThreadLocal(); + return $"date_format({context.Value.Values["that"]}, {context.Value.Values["arg1"]})"; + } - public static string FormatDateTime(this DateTime that, string arg1) - { - return $"date_format({context.Value.Values["that"]}, {context.Value.Values["arg1"]})"; - } - - /// - /// 设置表达式中的 string 参数化长度,优化执行计划 - /// - /// - /// - /// - public static string SetDbParameter(this string that, int size) - { - if (context.Value.DbParameter != null) - context.Value.DbParameter.Size = size; - return context.Value.Values["that"]; - } + /// + /// 设置表达式中的 string 参数化长度,优化执行计划 + /// + /// + /// + /// + public static string SetDbParameter(this string that, int size) + { + if (context.Value.DbParameter != null) + context.Value.DbParameter.Size = size; + return context.Value.Values["that"]; } } +} diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2ff4b149..2293b80f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index dbe7beb2..22dbbbd7 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2294,7 +2294,161 @@ - 耗时(单位:毫秒 + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构 + + + + + 转大写同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + 将实体类型与数据库对比,返回DDL语句 + + + + + + + 将实体类型集合与数据库对比,返回DDL语句 + + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 + + + + + 同步实体类型到数据库 + + + + + + + 同步实体类型集合到数据库 + + + + + + + 同步实体类型到数据库(指定表名) + + 实体类型 + 指定表名对比 + + + + + 根据 System.Type 获取数据库信息 + + + + + + + 在外部配置实体的特性 + + + + + + + + 在外部配置实体的特性 + + + @@ -2489,165 +2643,6 @@ - - - 多表查询 - - - - - - - - 获取c#值 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 中间表,多对多 - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - - - 测量两个经纬度的距离,返回单位:米 - - 经纬坐标1 - 经纬坐标2 - 返回距离(单位:米) - - - - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 - - - - - - - - 多表查询 - - - 多表查询 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d9ff1c1e..bd5b5803 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fef53647..deee2b58 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index deb1607a..a4c7f31d 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6168600d..58472eff 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0f051ab0..2ea5dc22 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2f1cbed1..2aa8df29 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9ae109f4..02187fcd 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.11.24 + 0.12.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 26d1d961b8ffc2a98eded73abb75c66b68fd219c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 Nov 2019 23:14:32 +0800 Subject: [PATCH 0273/1029] =?UTF-8?q?-=20=E7=A6=81=E6=AD=A2=20Contains=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=85=83=E7=B4=A0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 5 +++++ FreeSql/Internal/CommonExpression.cs | 6 ++++++ Providers/FreeSql.Provider.MySql/MySqlExpression.cs | 2 ++ Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs | 2 ++ .../FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs | 2 ++ .../FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs | 2 ++ .../PostgreSQL/OdbcPostgreSQLExpression.cs | 2 ++ .../SqlServer/OdbcSqlServerExpression.cs | 2 ++ Providers/FreeSql.Provider.Oracle/OracleExpression.cs | 2 ++ .../FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs | 2 ++ .../FreeSql.Provider.SqlServer/SqlServerExpression.cs | 2 ++ Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs | 2 ++ 13 files changed, 31 insertions(+), 7 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index a9d10edd..c46f3851 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -348,6 +348,11 @@ namespace FreeSql.Tests g.sqlserver.Select().Where(a => a.varchar == name).ToList(); g.sqlserver.Select().Where(a => a.varchar == name.SetDbParameter(10)).ToList(); + + var testarr = new string[] { "1", "2" }; + var sdfsdgselect3 = g.sqlserver.Select().Where(a => testarr.Contains(a.varchar)); + g.sqlserver.Select().Where(a => testarr.Contains(a.varchar)).ToList(); + } } diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6cc728e0..755c0d71 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1225,6 +1225,12 @@ namespace FreeSql.Internal this.mapType = newValue; return old; } + public List SetDbParamsReturnOld(List newValue) + { + var old = this.dbParams; + this.dbParams = newValue; + return old; + } public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List v1, Func v2, SelectTableInfoType v3) { diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index f8a2e19e..9f1bf803 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -104,8 +104,10 @@ namespace FreeSql.MySql tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); var left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs index f3aa470d..e734dfd0 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -111,8 +111,10 @@ namespace FreeSql.Odbc.Default tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); var left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 36c2261a..9c1df930 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -104,8 +104,10 @@ namespace FreeSql.Odbc.MySql tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); var left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 71190478..9bc4e84e 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -104,8 +104,10 @@ namespace FreeSql.Odbc.Oracle tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); var left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index bee2bacc..86463249 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -133,8 +133,10 @@ namespace FreeSql.Odbc.PostgreSQL tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); //判断 in 或 array @> array if (left.StartsWith("array[") || left.EndsWith("]")) return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 47df3413..5a73fde2 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -108,8 +108,10 @@ namespace FreeSql.Odbc.SqlServer tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); var left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 9ea04aaf..20a1011f 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -104,8 +104,10 @@ namespace FreeSql.Oracle tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); var left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 78184791..3ea73ae2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -163,8 +163,10 @@ namespace FreeSql.PostgreSQL tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); //判断 in 或 array @> array if (left.StartsWith("array[") || left.EndsWith("]")) return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 3e068d4a..5768d9c1 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -108,8 +108,10 @@ namespace FreeSql.SqlServer tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); var left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); switch (callExp.Method.Name) { case "Contains": diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 922a7bef..9bc01183 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -104,8 +104,10 @@ namespace FreeSql.Sqlite tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); var left = objExp == null ? null : getExp(objExp); tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); switch (callExp.Method.Name) { case "Contains": From 5f0e66a749104e2d7178be0ada85a1599c04a3f7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 Nov 2019 23:17:05 +0800 Subject: [PATCH 0274/1029] ## v0.12.2 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 3a2baa84..b1d29ca2 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.1 + 0.12.2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 49ee9064..1195b61a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 97277140..70724122 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 7c998e32..2b7e0557 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 762ec280..8c2f8acc 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.1 + 0.12.2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2293b80f..66dada08 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index bd5b5803..b59e80ed 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index deee2b58..063dc89f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a4c7f31d..2b1f0d12 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 58472eff..eecdfc52 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2ea5dc22..0a50d8cd 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2aa8df29..135c3a52 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 02187fcd..f1018d0b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.1 + 0.12.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 58ba86b5f2f9d92542513a03bf8bfe7d5d23bfba Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 Nov 2019 23:58:01 +0800 Subject: [PATCH 0275/1029] =?UTF-8?q?-=20Lambda=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=8C=96=E5=8A=9F=E8=83=BD=E7=9A=84=20bug=20=E8=A7=A3=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 2 +- FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 131 ------------------ FreeSql/FreeSqlBuilder.cs | 1 + FreeSql/Internal/CommonExpression.cs | 1 + .../SelectProvider/Select0Provider.cs | 2 + .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 19 insertions(+), 146 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b1d29ca2..7d4b1e94 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.2 + 0.12.3 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 1195b61a..3ec6c6e6 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 70724122..41fc59a4 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2b7e0557..2ce356cd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8c2f8acc..2f60b2b5 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.2 + 0.12.3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index c46f3851..852dcfc6 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -341,7 +341,7 @@ namespace FreeSql.Tests ); - g.sqlserver.CodeFirst.IsGenerateCommandParameterWithLambda = true; + //g.sqlserver.CodeFirst.IsGenerateCommandParameterWithLambda = true; var name = "testname"; var sdfsdgselect1 = g.sqlserver.Select().Where(a => a.varchar == name); var sdfsdgselect2 = g.sqlserver.Select().Where(a => a.varchar == name.SetDbParameter(10)); diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index f3de6a4e..ae796f92 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -37,7 +37,7 @@ public class g .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;Max Pool Size=3") .UseAutoSyncStructure(true) - //.UseNoneCommandParameter(true) + //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 (cmd, traceLog) => Console.WriteLine(traceLog)) diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 66dada08..ddad21c3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 22dbbbd7..fd39d1c5 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2031,137 +2031,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index fb754ac8..fef4b9b6 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -212,6 +212,7 @@ namespace FreeSql ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper; ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst; ret.CodeFirst.IsNoneCommandParameter = _isNoneCommandParameter; + ret.CodeFirst.IsGenerateCommandParameterWithLambda = _isGenerateCommandParameterWithLambda; ret.CodeFirst.IsLazyLoading = _isLazyLoading; var ado = ret.Ado as Internal.CommonProvider.AdoProvider; ado.AopCommandExecuting += _aopCommandExecuting; diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 755c0d71..185ce4d4 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -504,6 +504,7 @@ namespace FreeSql.Internal public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) { if (exp == null) return ""; + if (tsc.dbParams != null && tsc.mapColumnTmp != null && tsc.mapColumnTmp.CsType.NullableTypeOrThis() != exp.Type) tsc.SetMapColumnTmp(null); if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpression != null) { var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, tsc.CloneDisableDiyParse())); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 1135f7bd..50eeea1a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -890,6 +890,7 @@ namespace FreeSql.Internal.CommonProvider if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToDelete 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); var del = _orm.Delete(); if (_tables[0].Table.Type != typeof(T1)) del.AsType(_tables[0].Table.Type); + if (_params.Any()) del.GetType().GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(del, new List(_params.ToArray())); return del.Where(GetToDeleteWhere("ftb_del")); } public IUpdate ToUpdate() @@ -897,6 +898,7 @@ namespace FreeSql.Internal.CommonProvider if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToUpdate 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); var upd = _orm.Update(); if (_tables[0].Table.Type != typeof(T1)) upd.AsType(_tables[0].Table.Type); + if (_params.Any()) upd.GetType().GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(upd, new List(_params.ToArray())); return upd.Where(GetToDeleteWhere("ftb_upd")); } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b59e80ed..e4e1f2ae 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 063dc89f..d7f6e4d0 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 2b1f0d12..3211f9f4 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index eecdfc52..1c3ccf18 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0a50d8cd..dc65d203 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 135c3a52..aadf9b99 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f1018d0b..59120f94 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.2 + 0.12.3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 5961479f2a31890a58504fd1dfd7395e92b89a51 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 Nov 2019 01:55:30 +0800 Subject: [PATCH 0276/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ExpressionCa?= =?UTF-8?q?llContext=20=E5=8F=AF=E8=AE=BE=E7=BD=AE=E3=80=81=E9=99=84?= =?UTF-8?q?=E5=8A=A0=E5=8F=82=E6=95=B0=E5=8C=96=E5=AF=B9=E8=B1=A1=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 55 ++++--- .../ExpressionCallAttribute.cs | 12 +- FreeSql/FreeSql.xml | 143 +++++++++++++++++- FreeSql/Internal/CommonExpression.cs | 26 +++- .../Internal/CommonProvider/DeleteProvider.cs | 2 +- .../SelectProvider/Select0Provider.cs | 2 +- .../SelectProvider/Select10Provider.cs | 8 +- .../SelectProvider/Select2Provider.cs | 8 +- .../SelectProvider/Select3Provider.cs | 8 +- .../SelectProvider/Select4Provider.cs | 8 +- .../SelectProvider/Select5Provider.cs | 8 +- .../SelectProvider/Select6Provider.cs | 8 +- .../SelectProvider/Select7Provider.cs | 8 +- .../SelectProvider/Select8Provider.cs | 8 +- .../SelectProvider/Select9Provider.cs | 8 +- .../Internal/CommonProvider/UpdateProvider.cs | 2 +- 16 files changed, 244 insertions(+), 70 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 852dcfc6..64a43bb4 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -11,6 +11,7 @@ using System.Linq.Expressions; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; using System.Threading; +using System.Data.SqlClient; namespace FreeSql.Tests { @@ -22,7 +23,7 @@ namespace FreeSql.Tests /// /// 菜单权限ID /// - [Column(IsPrimary = true, OldName = "SysModulePermissionId")] + [Column(IsPrimary = true, OldName = "SysModulePermissionId")] public String Id { get; set; } /// @@ -356,27 +357,39 @@ namespace FreeSql.Tests } } -[ExpressionCall] -public static class DbFunc -{ - static ThreadLocal context = new ThreadLocal(); - - public static string FormatDateTime(this DateTime that, string arg1) + [ExpressionCall] + public static class DbFunc { - return $"date_format({context.Value.Values["that"]}, {context.Value.Values["arg1"]})"; - } + static ThreadLocal context = new ThreadLocal(); - /// - /// 设置表达式中的 string 参数化长度,优化执行计划 - /// - /// - /// - /// - public static string SetDbParameter(this string that, int size) - { - if (context.Value.DbParameter != null) - context.Value.DbParameter.Size = size; - return context.Value.Values["that"]; + public static string FormatDateTime(this DateTime that, string arg1) + { + return $"date_format({context.Value.ParsedContent["that"]}, {context.Value.ParsedContent["arg1"]})"; + } + + /// + /// 设置表达式中的 string 参数化长度,优化执行计划 + /// + /// + /// + /// + public static string SetDbParameter(this string that, int size) + { + if (context.Value.DbParameter != null) + { + //已经参数化了,开启了全局表达式参数化功能:UseGenerateCommandParameterWithLambda(true) + context.Value.DbParameter.Size = size; + return context.Value.ParsedContent["that"]; + } + var guid = Guid.NewGuid().ToString("N").ToLower(); + context.Value.UserParameters.Add(new SqlParameter + { + ParameterName = guid, + SqlDbType = System.Data.SqlDbType.VarChar, + Size = size, + Value = that + }); + return $"@{guid}"; + } } } -} diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs index 3c27b078..2f91e4d8 100644 --- a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs +++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs @@ -24,11 +24,21 @@ namespace FreeSql.DataAnnotations /// /// 已解析的表达式中参数内容 /// - public Dictionary Values { get; } = new Dictionary(); + public Dictionary ParsedContent { get; } = new Dictionary(); /// /// 主对象的参数化对象,可重塑其属性 /// public DbParameter DbParameter { get; internal set; } + + /// + /// 可附加参数化对象 + /// + public List UserParameters { get; } = new List(); + + /// + /// 返回表达式函数表示的 SQL 字符串 + /// + public string Result { get; set; } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index fd39d1c5..905d6cd1 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -163,7 +163,7 @@ 数据库类型,可用于适配多种数据库环境 - + 已解析的表达式中参数内容 @@ -173,6 +173,16 @@ 主对象的参数化对象,可重塑其属性 + + + 可附加参数化对象 + + + + + 返回表达式函数表示的 SQL 字符串 + + 索引名 @@ -2031,6 +2041,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 }) + + + + + + 可自定义解析表达式 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 185ce4d4..21232567 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -546,20 +546,25 @@ namespace FreeSql.Internal var ecc = new ExpressionCallContext { DataType = _ado.DataType }; var exp3MethodParams = exp3.Method.GetParameters(); var dbParamsIndex = tsc.dbParams?.Count; - ecc.Values.Add(exp3MethodParams[0].Name, ExpressionLambdaToSql(exp3.Arguments[0], tsc)); + ecc.ParsedContent.Add(exp3MethodParams[0].Name, ExpressionLambdaToSql(exp3.Arguments[0], tsc)); if (tsc.dbParams?.Count > dbParamsIndex) ecc.DbParameter = tsc.dbParams.Last(); - List oldDbParams = tsc.dbParams; - tsc.dbParams = null; + List oldDbParams = tsc.SetDbParamsReturnOld(null); for (var a = 1; a < exp3.Arguments.Count; a++) if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) - ecc.Values.Add(exp3MethodParams[a].Name, ExpressionLambdaToSql(exp3.Arguments[a], tsc)); - tsc.dbParams = oldDbParams; + ecc.ParsedContent.Add(exp3MethodParams[a].Name, ExpressionLambdaToSql(exp3.Arguments[a], tsc)); + tsc.SetDbParamsReturnOld(oldDbParams); var exp3InvokeParams = new object[exp3.Arguments.Count]; for (var a = 0; a < exp3.Arguments.Count; a++) { if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) - exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, ecc.Values[exp3MethodParams[a].Name]);// exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); + { + var eccContent = ecc.ParsedContent[exp3MethodParams[a].Name]; + exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, + eccContent.StartsWith("N'") ? + eccContent.Substring(1).Trim('\'').Replace("''", "'") : + eccContent.Trim('\'').Replace("''", "'"));// exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); + } else exp3InvokeParams[a] = ecc; } @@ -571,7 +576,11 @@ namespace FreeSql.Internal typeof(ThreadLocal).GetProperty("Value").SetValue(eccField.GetValue(null), ecc, null); try { - return string.Concat(exp3.Method.Invoke(null, exp3InvokeParams)); + var sqlRet = exp3.Method.Invoke(null, exp3InvokeParams); + if (string.IsNullOrEmpty(ecc.Result) && sqlRet is string) ecc.Result = string.Concat(sqlRet); + if (string.IsNullOrEmpty(ecc.Result)) ecc.Result = ecc.ParsedContent[exp3MethodParams[0].Name]; + if (ecc.UserParameters.Any()) tsc.dbParams?.AddRange(ecc.UserParameters); + return ecc.Result; } finally { @@ -1335,8 +1344,9 @@ namespace FreeSql.Internal public string formatSql(object obj, Type mapType, ColumnInfo mapColumn, List dbParams) { //参数化设置,日后优化 - if (dbParams != null) + if (_common.CodeFirst.IsGenerateCommandParameterWithLambda && dbParams != null) { + if (obj == null) return "NULL"; var paramName = $"exp_{dbParams.Count}"; var parm = _common.AppendParamter(dbParams, paramName, mapColumn, mapType ?? mapColumn?.Attribute.MapType ?? obj?.GetType(), mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj)); diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index e2d816dc..81bac23e 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -85,7 +85,7 @@ namespace FreeSql.Internal.CommonProvider } public abstract List ExecuteDeleted(); - public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _params)); public IDelete Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 50eeea1a..41ae2e15 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1053,7 +1053,7 @@ namespace FreeSql.Internal.CommonProvider return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } - protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params)); #endregion #if net40 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 445641dc..73898c13 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -153,21 +153,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -226,7 +226,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 25dc239e..71eb62a9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -130,21 +130,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -203,7 +203,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index f355d1b5..4430c762 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -133,21 +133,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -206,7 +206,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 04b4cc8d..0af86e6d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -136,21 +136,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -209,7 +209,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index c7438f9b..56214a55 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -139,21 +139,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -212,7 +212,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index de717933..2538c8e0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -142,21 +142,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -215,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 1ec020d8..33b1e13e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -145,21 +145,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -218,7 +218,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index fd6b33fe..5f2dda4f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -149,21 +149,21 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -222,7 +222,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index ff3098ef..ba049ff9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -147,20 +147,20 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).Any(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } #if net40 @@ -169,7 +169,7 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)).AnyAsync(); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } Task ISelect.ToDataTableAsync(Expression> select) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 28d60260..255f7c1d 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -424,7 +424,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _orm.CodeFirst.IsGenerateCommandParameterWithLambda ? _params : null)); + public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _params)); public IUpdate Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; From defab45624296a4a268950c7018feb73061b4c11 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 Nov 2019 19:02:38 +0800 Subject: [PATCH 0277/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20ExpressionCa?= =?UTF-8?q?ll=20=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs | 1 + FreeSql.Tests/FreeSql.Tests/g.cs | 4 ++++ FreeSql/DataAnnotations/ExpressionCallAttribute.cs | 9 +++++---- FreeSql/FreeSql.xml | 5 +++-- FreeSql/Internal/CommonExpression.cs | 8 ++++++-- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs index ee572d0d..a5942054 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs @@ -10,6 +10,7 @@ public class g static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( cmd => { diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index ae796f92..4c336e30 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -11,6 +11,7 @@ public class g static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .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=2") .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 (cmd, traceLog) => Console.WriteLine(traceLog)) @@ -24,6 +25,7 @@ public class g return new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) .UseSyncStructureToLower(true) .UseLazyLoading(true) .UseMonitorCommand( @@ -48,6 +50,7 @@ public class g static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) .UseSyncStructureToUpper(true) //.UseNoneCommandParameter(true) @@ -61,6 +64,7 @@ public class g static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=2") .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs index 2f91e4d8..c9c964e9 100644 --- a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs +++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs @@ -7,9 +7,9 @@ namespace FreeSql.DataAnnotations { /// /// 自定义表达式函数解析 - /// 注意:请使用静态扩展类 + /// 注意:请使用静态方法、或者在类上标记 /// - [AttributeUsage(AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class ExpressionCallAttribute : Attribute { } @@ -32,9 +32,10 @@ namespace FreeSql.DataAnnotations public DbParameter DbParameter { get; internal set; } /// - /// 可附加参数化对象 + /// 可附加参数化对象 + /// 注意:本属性只有 Where 的表达式解析才可用 /// - public List UserParameters { get; } = new List(); + public List UserParameters { get; internal set; } /// /// 返回表达式函数表示的 SQL 字符串 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 905d6cd1..996523e3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -155,7 +155,7 @@ 自定义表达式函数解析 - 注意:请使用静态扩展类 + 注意:请使用静态方法、或者在类上标记 @@ -175,7 +175,8 @@ - 可附加参数化对象 + 可附加参数化对象 + 注意:本属性只有 Where 的表达式解析才可用 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 21232567..ee433e88 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -500,6 +500,7 @@ namespace FreeSql.Internal return $"{left} {oper} {right}"; } static ConcurrentDictionary _dicTypeExistsExpressionCallAttribute = new ConcurrentDictionary(); + static ConcurrentDictionary> _dicMethodExistsExpressionCallAttribute = new ConcurrentDictionary>(); static ConcurrentDictionary _dicTypeExpressionCallClassContextFields = new ConcurrentDictionary(); public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) { @@ -541,9 +542,12 @@ namespace FreeSql.Internal case ExpressionType.Call: tsc.mapType = null; var exp3 = exp as MethodCallExpression; - if (exp3.Object == null && _dicTypeExistsExpressionCallAttribute.GetOrAdd(exp3.Method.DeclaringType, dttp => dttp.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any())) + if (exp3.Object == null && ( + _dicTypeExistsExpressionCallAttribute.GetOrAdd(exp3.Method.DeclaringType, dttp => dttp.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any()) || + exp3.Method.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any() + )) { - var ecc = new ExpressionCallContext { DataType = _ado.DataType }; + var ecc = new ExpressionCallContext { DataType = _ado.DataType, UserParameters = tsc.dbParams == null ? null : new List() }; var exp3MethodParams = exp3.Method.GetParameters(); var dbParamsIndex = tsc.dbParams?.Count; ecc.ParsedContent.Add(exp3MethodParams[0].Name, ExpressionLambdaToSql(exp3.Arguments[0], tsc)); From 70b02c034e6446f5258931a0c4e05c794d493e77 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 Nov 2019 19:06:40 +0800 Subject: [PATCH 0278/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20ExpressionCa?= =?UTF-8?q?ll=20=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonExpression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index ee433e88..af45725a 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -583,7 +583,7 @@ namespace FreeSql.Internal var sqlRet = exp3.Method.Invoke(null, exp3InvokeParams); if (string.IsNullOrEmpty(ecc.Result) && sqlRet is string) ecc.Result = string.Concat(sqlRet); if (string.IsNullOrEmpty(ecc.Result)) ecc.Result = ecc.ParsedContent[exp3MethodParams[0].Name]; - if (ecc.UserParameters.Any()) tsc.dbParams?.AddRange(ecc.UserParameters); + if (ecc?.UserParameters.Any() == true) tsc.dbParams?.AddRange(ecc.UserParameters); return ecc.Result; } finally From 27acd4da088197f587c946bbd3d715961593b0c9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 Nov 2019 19:07:49 +0800 Subject: [PATCH 0279/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20ExpressionCa?= =?UTF-8?q?ll=20=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonExpression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index af45725a..e2f715d3 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -583,7 +583,7 @@ namespace FreeSql.Internal var sqlRet = exp3.Method.Invoke(null, exp3InvokeParams); if (string.IsNullOrEmpty(ecc.Result) && sqlRet is string) ecc.Result = string.Concat(sqlRet); if (string.IsNullOrEmpty(ecc.Result)) ecc.Result = ecc.ParsedContent[exp3MethodParams[0].Name]; - if (ecc?.UserParameters.Any() == true) tsc.dbParams?.AddRange(ecc.UserParameters); + if (ecc.UserParameters?.Any() == true) tsc.dbParams?.AddRange(ecc.UserParameters); return ecc.Result; } finally From 01b31c095b816aa71c6a93479abc81a2ee4af56f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 25 Nov 2019 17:30:36 +0800 Subject: [PATCH 0280/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=89=B9=E6=80=A7=20[Column(ServerTime=20=3D=20DateTi?= =?UTF-8?q?meKind.Utc)]=20=E4=BD=BF=E7=94=A8=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=89=A7=E8=A1=8C=E6=8F=92=E5=85=A5=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20ToList(a=20=3D>?= =?UTF-8?q?=20new=20Dto=20{=20..=20})=20=E5=9C=A8=E4=BD=BF=E7=94=A8=20Grou?= =?UTF-8?q?pBy=20=E4=B9=8B=E5=90=8E=E6=8A=A5=E9=94=99=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=88=B0=E6=95=B0=E6=8D=AE=E5=BA=93=EF=BC=8C?= =?UTF-8?q?=E5=9C=A8=20asp.net=204.7=20=E6=97=A0=E6=95=88=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 1 + .../MySqlConnector/MySqlCodeFirstTest.cs | 7 ++++ .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 7 ++++ .../Oracle/OracleCodeFirstTest.cs | 9 ++++ .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 7 ++++ .../SqlServer/SqlServerCodeFirstTest.cs | 11 ++++- .../Sqlite/SqliteCodeFirstTest.cs | 9 ++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 6 +-- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 35 ++++++++++++++++ FreeSql/DataAnnotations/ColumnAttribute.cs | 18 +++++--- FreeSql/DataAnnotations/ColumnFluent.cs | 11 +++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- FreeSql/FreeSql.xml | 17 +++++--- FreeSql/Internal/CommonExpression.cs | 2 +- .../Internal/CommonProvider/InsertProvider.cs | 15 ++++--- FreeSql/Internal/CommonUtils.cs | 20 ++++++--- FreeSql/Internal/Model/ColumnInfo.cs | 2 + FreeSql/Internal/UtilsExpressionTree.cs | 42 +++++++++++++++---- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 28 +++++++------ .../FreeSql.Provider.MySql/MySqlExpression.cs | 4 +- .../FreeSql.Provider.MySql/MySqlUtils.cs | 2 + .../MySqlConnectorUtils.cs | 2 + .../Default/OdbcUtils.cs | 2 + .../MySql/OdbcMySqlCodeFirst.cs | 28 +++++++------ .../MySql/OdbcMySqlExpression.cs | 4 +- .../MySql/OdbcMySqlUtils.cs | 2 + .../Oracle/Curd/OdbcOracleInsert.cs | 15 ++++--- .../Oracle/OdbcOracleCodeFirst.cs | 11 +++-- .../Oracle/OdbcOracleExpression.cs | 4 +- .../Oracle/OdbcOracleUtils.cs | 2 + .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 10 +++-- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 4 +- .../PostgreSQL/OdbcPostgreSQLUtils.cs | 2 + .../SqlServer/OdbcSqlServerCodeFirst.cs | 32 ++++++-------- .../SqlServer/OdbcSqlServerExpression.cs | 4 +- .../SqlServer/OdbcSqlServerUtils.cs | 2 + .../Curd/OracleInsert.cs | 15 ++++--- .../OracleCodeFirst.cs | 8 ++-- .../OracleExpression.cs | 4 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 2 + .../PostgreSQLCodeFirst.cs | 10 +++-- .../PostgreSQLExpression.cs | 4 +- .../PostgreSQLUtils.cs | 2 + .../SqlServerCodeFirst.cs | 32 ++++++-------- .../SqlServerExpression.cs | 4 +- .../SqlServerUtils.cs | 2 + .../SqliteCodeFirst.cs | 10 ++--- .../SqliteExpression.cs | 4 +- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 2 + 49 files changed, 332 insertions(+), 146 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 95dfcc5a..949cbac3 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -39,6 +39,7 @@ namespace base_entity .UseNoneCommandParameter(true) .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=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=2") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") .Build(); BaseEntity.Initialization(fsql); #endregion diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 7a8e141d..a4a29bea 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -36,6 +36,7 @@ namespace FreeSql.Tests.MySqlConnector public string { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime ʱ { get; set; } } @@ -458,7 +459,10 @@ namespace FreeSql.Tests.MySqlConnector public float testFieldFloat { get; set; } public decimal testFieldDecimal { get; set; } public TimeSpan testFieldTimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } public Guid testFieldGuid { get; set; } @@ -476,7 +480,10 @@ namespace FreeSql.Tests.MySqlConnector public float? testFieldFloatNullable { get; set; } public decimal? testFieldDecimalNullable { get; set; } public TimeSpan? testFieldTimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } public MygisPoint testFieldPoint { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 3fe86a01..6ad6d8e6 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -36,6 +36,7 @@ namespace FreeSql.Tests.MySql public string { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime ʱ { get; set; } } @@ -464,7 +465,10 @@ namespace FreeSql.Tests.MySql public float testFieldFloat { get; set; } public decimal testFieldDecimal { get; set; } public TimeSpan testFieldTimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } public Guid testFieldGuid { get; set; } @@ -482,7 +486,10 @@ namespace FreeSql.Tests.MySql public float? testFieldFloatNullable { get; set; } public decimal? testFieldDecimalNullable { get; set; } public TimeSpan? testFieldTimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } public MygisPoint testFieldPoint { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 4cfd7adc..ca92ea08 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -36,6 +36,7 @@ namespace FreeSql.Tests.Oracle public string { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime ʱ { get; set; } } @@ -222,8 +223,12 @@ namespace FreeSql.Tests.Oracle public float Float { get; set; } public decimal Decimal { get; set; } public TimeSpan TimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime DateTime { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } public string String { get; set; } public Guid Guid { get; set; } @@ -241,8 +246,12 @@ namespace FreeSql.Tests.Oracle public float? FloatNullable { get; set; } public decimal? DecimalNullable { get; set; } public TimeSpan? TimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime? DateTimeNullable { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } public TableAllTypeEnumType1 Enum1 { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index d91dc319..f16ed691 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -43,6 +43,7 @@ namespace FreeSql.Tests.PostgreSQL public string { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime ʱ { get; set; } } @@ -367,7 +368,10 @@ namespace FreeSql.Tests.PostgreSQL public float testFieldFloat { get; set; } public decimal testFieldDecimal { get; set; } public TimeSpan testFieldTimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } public Guid testFieldGuid { get; set; } @@ -397,7 +401,10 @@ namespace FreeSql.Tests.PostgreSQL public float? testFieldFloatNullable { get; set; } public decimal? testFieldDecimalNullable { get; set; } public TimeSpan? testFieldTimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } public NpgsqlPoint? testFieldNpgsqlPointNullable { get; set; } public NpgsqlLine? testFieldNpgsqlLineNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 179d32e3..722b421c 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -37,6 +37,7 @@ namespace FreeSql.Tests.SqlServer public string { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime ʱ { get; set; } } @@ -159,7 +160,7 @@ namespace FreeSql.Tests.SqlServer var sqlTestUpdate = g.sqlserver.Update().SetSource(item3NP).NoneParameter().ToSql(); var item3 = insert.AppendData(item2).ExecuteInserted(); - var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + var newitem2 = select.Where(a => a.Id == item3NP[0].Id).ToOne(); var items = select.ToList(); } @@ -344,8 +345,12 @@ namespace FreeSql.Tests.SqlServer public float testFieldFloat { get; set; } public decimal testFieldDecimal { get; set; } public TimeSpan testFieldTimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime testFieldDateTime { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTimeOffset testFieldDateTimeOffset { get; set; } + public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } public Guid testFieldGuid { get; set; } @@ -363,8 +368,12 @@ namespace FreeSql.Tests.SqlServer public float? testFieldFloatNullable { get; set; } public decimal? testFieldDecimalNullable { get; set; } public TimeSpan? testFieldTimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime? testFieldDateTimeNullable { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } + public Guid? testFieldGuidNullable { get; set; } public TableAllTypeEnumType1 testFieldEnum1 { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index 48281579..f3195f9b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -36,6 +36,7 @@ namespace FreeSql.Tests.Sqlite public string { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime ʱ { get; set; } } @@ -262,8 +263,12 @@ namespace FreeSql.Tests.Sqlite public float Float { get; set; } public decimal Decimal { get; set; } public TimeSpan TimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime DateTime { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } public string String { get; set; } public Guid Guid { get; set; } @@ -281,8 +286,12 @@ namespace FreeSql.Tests.Sqlite public float? FloatNullable { get; set; } public decimal? DecimalNullable { get; set; } public TimeSpan? TimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] public DateTime? DateTimeNullable { get; set; } + [Column(ServerTime = DateTimeKind.Local)] public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } public TableAllTypeEnumType1 Enum1 { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 894723ad..b6080caf 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -670,10 +670,10 @@ namespace FreeSql.Tests .From((a, b) => a.InnerJoin(aa => aa.TemplatesId == b.Id2)) .GroupBy((a, b) => b.Code) - .ToSql(a => new + .ToSql(a => new NewsArticleDto { - a.Key, - sss = a.Sum(a.Value.Item1.OptionsEntity04) + ArticleTitle = a.Key, + ChannelId = a.Sum(a.Value.Item1.OptionsEntity04) }); var testgrpsql2 = g.sqlite.Select() diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 64a43bb4..cf9195e2 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -183,9 +183,44 @@ namespace FreeSql.Tests public string varchar_notnull { get; set; } } + public class TestIgnoreDefaultValue { + public Guid Id { get; set; } + + [Column(IsIgnore = true)] + public double? quantity { get; set; } = 100f; + + public DateTime ct1 { get; set; } + public DateTime? ct2 { get; set; } + } + [Fact] public void Test02() { + var serverTime = g.pgsql.Select().Limit(1).First(a => DateTime.UtcNow); + var timeOffset = DateTime.UtcNow.Subtract(serverTime); //减去数据库时间 + + g.pgsql.Aop.AuditValue += new EventHandler((_, e) => + { + if (e.Column.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime)) + { + if (e.Value == null || (DateTime)e.Value == default(DateTime)) + { + e.Value = DateTime.Now.Subtract(timeOffset); + return; + } + } + }); + + + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + g.pgsql.GetRepository().Insert(new TestIgnoreDefaultValue[] + { + new TestIgnoreDefaultValue(), + new TestIgnoreDefaultValue(), + new TestIgnoreDefaultValue() + }); + var testttt = g.pgsql.Select().Limit(10).ToList(); + var slsksd = g.mysql.Update().SetSource(new UserLike { Id = Guid.NewGuid(), CreateUserId = 1000, SubjectId = Guid.NewGuid() }) .UpdateColumns(a => new { diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 0c9944e1..71216b91 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -43,11 +43,6 @@ namespace FreeSql.DataAnnotations /// public bool IsVersion { get => _IsVersion ?? false; set => _IsVersion = value; } - /// - /// 数据库默认值 - /// - public object DbDefautValue { get; internal set; } - /// /// 类型映射,除了可做基本的类型映射外,特别介绍的功能: /// 1、将 enum 属性映射成 typeof(string) @@ -76,5 +71,18 @@ namespace FreeSql.DataAnnotations /// 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 /// public bool CanUpdate { get => _CanUpdate ?? true; set => _CanUpdate = value; } + + internal DateTimeKind? _ServerTime; + /// + /// 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + /// + public DateTimeKind ServerTime + { + get => _ServerTime ?? DateTimeKind.Local; + set + { + _ServerTime = value == DateTimeKind.Unspecified ? DateTimeKind.Local : value; + } + } } } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index 3cebe19c..f98d6ffc 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -124,5 +124,16 @@ namespace FreeSql.DataAnnotations _column.CanUpdate = value; return this; } + + /// + /// 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + /// + /// + /// + public ColumnFluent ServerTime(DateTimeKind value) + { + _column.ServerTime = value; + return this; + } } } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 9a2604b7..e94e9eb8 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -39,7 +39,7 @@ public static partial class FreeSqlGlobalExtensions }); public static bool IsIntegerType(this Type that) => that == null ? false : (dicIsNumberType.Value.TryGetValue(that, out var tryval) ? tryval : false); public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that); - public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true; + public static bool IsNullableType(this Type that) => that.IsArray == false && that?.FullName.StartsWith("System.Nullable`1[") == true; public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that)); public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that; diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 996523e3..768d92dd 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -45,11 +45,6 @@ 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) - - - 数据库默认值 - - 类型映射,除了可做基本的类型映射外,特别介绍的功能: @@ -78,6 +73,11 @@ 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + 数据库列名 @@ -152,6 +152,13 @@ + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + 自定义表达式函数解析 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index e2f715d3..b31fc599 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -110,7 +110,7 @@ namespace FreeSql.Internal parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0]; parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - if (initExp.NewExpression.Type != _tables.FirstOrDefault()?.Table.Type) + if (_tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) { //dto 映射 var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 0bd497c1..83b63483 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -445,13 +445,18 @@ namespace FreeSql.Internal.CommonProvider if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); - object val = col.GetMapValue(d); - if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + if (string.IsNullOrEmpty(col.DbInsertValue) == false) + sb.Append(col.DbInsertValue); else { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + object val = col.GetMapValue(d); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + } } ++colidx2; } diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 1adbebfa..9b0e17bc 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -34,6 +34,8 @@ namespace FreeSql.Internal public abstract string StringConcat(string[] objs, Type[] types); public abstract string Mod(string left, string right, Type leftType, Type rightType); public abstract string Div(string left, string right, Type leftType, Type rightType); + public abstract string Now { get; } + public abstract string NowUtc { get; } public abstract string QuoteWriteParamter(Type type, string paramterName); public abstract string QuoteReadColumn(Type type, string columnName); @@ -126,7 +128,7 @@ namespace FreeSql.Internal if (trycol._Position != null) attr._Position = trycol.Position; if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert; if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate; - if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue; + if (trycol._ServerTime != null) attr._ServerTime = trycol._ServerTime; } var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); foreach (var tryattrobj in attrs) @@ -145,7 +147,7 @@ namespace FreeSql.Internal if (tryattr._Position != null) attr._Position = tryattr.Position; if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert; if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate; - if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue; + if (tryattr._ServerTime != null) attr._ServerTime = tryattr.ServerTime; } ColumnAttribute ret = null; if (!string.IsNullOrEmpty(attr.Name)) ret = attr; @@ -160,7 +162,7 @@ namespace FreeSql.Internal if (attr._Position != null) ret = attr; if (attr._CanInsert != null) ret = attr; if (attr._CanUpdate != null) ret = attr; - if (attr.DbDefautValue != null) ret = attr; + if (attr._ServerTime != null) ret = attr; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; } @@ -343,8 +345,16 @@ namespace FreeSql.Internal /// Dict:key=属性名,value=注释 public static Dictionary GetProperyCommentBySummary(Type type) { - var xmlPath = type.Assembly.Location.Replace(".dll", ".xml").Replace(".exe", ".xml"); - if (File.Exists(xmlPath) == false) return null; + var regex = new Regex(@"\.(dll|exe)", RegexOptions.IgnoreCase); + var xmlPath = regex.Replace(type.Assembly.Location, ".xml"); + if (File.Exists(xmlPath) == false) + { + if (string.IsNullOrEmpty(type.Assembly.CodeBase)) return null; + xmlPath = regex.Replace(type.Assembly.CodeBase, ".xml"); + if (xmlPath.StartsWith("file:///") && Uri.TryCreate(xmlPath, UriKind.Absolute, out var tryuri)) + xmlPath = tryuri.LocalPath; + if (File.Exists(xmlPath) == false) return null; + } var dic = new Dictionary(); var sReader = new StringReader(File.ReadAllText(xmlPath)); diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index 84780850..05dc24a2 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -14,6 +14,8 @@ namespace FreeSql.Internal.Model public ColumnAttribute Attribute { get; set; } public string Comment { get; internal set; } public string DbTypeText { get; internal set; } + public string DbDefaultValue { get; internal set; } + public string DbInsertValue { get; internal set; } public int DbSize { get; internal set; } public byte DbPrecision { get; internal set; } public byte DbScale { get; internal set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 5904d7fa..69cb6087 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -151,26 +151,48 @@ namespace FreeSql.Internal trytb.ColumnsByCsIgnore.Add(p.Name, col); continue; } - if (entityDefault != null) colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(entityDefault, null); + object defaultValue = null; + if (entityDefault != null) defaultValue = trytb.Properties[p.Name].GetValue(entityDefault, null); if (p.PropertyType.IsEnum) { var isEqualsEnumValue = false; var enumValues = Enum.GetValues(p.PropertyType); for (var a = 0; a < enumValues.Length; a++) - if (object.Equals(colattr.DbDefautValue, enumValues.GetValue(a))) + if (object.Equals(defaultValue, enumValues.GetValue(a))) { isEqualsEnumValue = true; break; } if (isEqualsEnumValue == false && enumValues.Length > 0) - colattr.DbDefautValue = enumValues.GetValue(0); + defaultValue = enumValues.GetValue(0); } - if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue); - if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue; - if (colattr.IsNullable == false && colattr.DbDefautValue == null) + if (defaultValue != null && p.PropertyType != colattr.MapType) defaultValue = Utils.GetDataReaderValue(colattr.MapType, defaultValue); + if (defaultValue == null) defaultValue = tp?.defaultValue; + if (colattr.IsNullable == false && defaultValue == null) { var citype = colattr.MapType.IsNullableType() ? colattr.MapType.GetGenericArguments().FirstOrDefault() : colattr.MapType; - colattr.DbDefautValue = citype.CreateInstanceGetDefaultValue(); + defaultValue = citype.CreateInstanceGetDefaultValue(); + } + try + { + col.DbDefaultValue = common.GetNoneParamaterSqlValue(new List(), colattr.MapType, defaultValue); + } + catch + { + col.DbDefaultValue = "NULL"; + } + //if (defaultValue != null && colattr.MapType.NullableTypeOrThis() == typeof(DateTime)) + //{ + // var dt = (DateTime)defaultValue; + // if (Math.Abs(dt.Subtract(DateTime.Now).TotalSeconds) < 60) + // col.DbDefaultValue = common.Now; + // else if (Math.Abs(dt.Subtract(DateTime.UtcNow).TotalSeconds) < 60) + // col.DbDefaultValue = common.NowUtc; + //} + if (colattr._ServerTime != null && new[] { typeof(DateTime), typeof(DateTimeOffset) }.Contains(colattr.MapType.NullableTypeOrThis())) + { + col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; + col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; } trytb.Columns.Add(colattr.Name, col); @@ -1584,7 +1606,11 @@ namespace FreeSql.Internal Expression.Block( new[] { arrNewExp, arrExp, arrLenExp, arrXExp, arrReadValExp }, Expression.Assign(arrExp, Expression.TypeAs(valueExp, typeof(Array))), - Expression.Assign(arrLenExp, Expression.Call(arrExp, MethodArrayGetLength, Expression.Constant(0))), + Expression.IfThenElse( + Expression.Equal(arrExp, Expression.Constant(null)), + Expression.Assign(arrLenExp, Expression.Constant(0)), + Expression.Assign(arrLenExp, Expression.Call(arrExp, MethodArrayGetLength, Expression.Constant(0))) + ), Expression.Assign(arrXExp, Expression.Constant(0)), Expression.Assign(arrNewExp, Expression.NewArrayBounds(elementType, arrLenExp)), Expression.Loop( diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 34dae9ea..03426dee 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -149,8 +149,7 @@ namespace FreeSql.MySql sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); sb.Append(","); @@ -237,26 +236,31 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); tbcol.Attribute.IsIdentity != tbstructcol.is_identity || isCommentChanged) { + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable && tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); - if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(")"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) { //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } continue; } //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsNullable == false && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); + if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(tbcol.DbDefaultValue); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql(@" @@ -301,8 +305,7 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); sb.Append(","); @@ -331,10 +334,11 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI //insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; } if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + insertvalue = $"ifnull({insertvalue},{tbcol.DbDefaultValue})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + if (tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + insertvalue = tbcol.DbDefaultValue; sb.Append(insertvalue).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 9f1bf803..36477266 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -175,8 +175,8 @@ namespace FreeSql.MySql { switch (exp.Member.Name) { - case "Now": return "now()"; - case "UtcNow": return "utc_timestamp()"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "curdate()"; case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)"; case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)"; diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index e76342d8..15d4dec4 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -88,6 +88,8 @@ namespace FreeSql.MySql public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} div {right}"; + public override string Now => "now()"; + public override string NowUtc => "utc_timestamp()"; public override string QuoteWriteParamter(Type type, string paramterName) { diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 1fe7e253..d4e9f674 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -96,6 +96,8 @@ namespace FreeSql.MySql public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} div {right}"; + public override string Now => "now()"; + public override string NowUtc => "utc_timestamp()"; public override string QuoteWriteParamter(Type type, string paramterName) { diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index c589bcdb..001c8bed 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -60,6 +60,8 @@ namespace FreeSql.Odbc.Default public override string StringConcat(string[] objs, Type[] types) => Adapter.ConcatSql(objs, types); public override string Mod(string left, string right, Type leftType, Type rightType) => Adapter.Mod(left, right, leftType, rightType); public override string Div(string left, string right, Type leftType, Type rightType) => Adapter.Div(left, right, leftType, rightType); + public override string Now => Adapter.LambdaDateTime_Now; + public override string NowUtc => Adapter.LambdaDateTime_UtcNow; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => Adapter.FieldSql(type, columnName); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 557692e9..b4a17d8d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -138,8 +138,7 @@ namespace FreeSql.Odbc.MySql sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); sb.Append(","); @@ -226,26 +225,31 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); tbcol.Attribute.IsIdentity != tbstructcol.is_identity || isCommentChanged) { + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable && tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); - if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(")"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) { //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } continue; } //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsNullable == false && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)); + if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(tbcol.DbDefaultValue); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); - if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); sbalter.Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql(@" @@ -290,8 +294,7 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); sb.Append(","); @@ -320,10 +323,11 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI //insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; } if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + insertvalue = $"ifnull({insertvalue},{tbcol.DbDefaultValue})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + if (tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + insertvalue = tbcol.DbDefaultValue; sb.Append(insertvalue).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 9c1df930..7388e72a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -175,8 +175,8 @@ namespace FreeSql.Odbc.MySql { switch (exp.Member.Name) { - case "Now": return "now()"; - case "UtcNow": return "utc_timestamp()"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "curdate()"; case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)"; case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index dc53f35a..7222f2e2 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -59,6 +59,8 @@ namespace FreeSql.Odbc.MySql public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} div {right}"; + public override string Now => "now()"; + public override string NowUtc => "utc_timestamp()"; public override string QuoteWriteParamter(Type type, string paramterName) { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index a5b9be8e..7e584c90 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -62,13 +62,18 @@ namespace FreeSql.Odbc.Oracle if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); - object val = col.GetMapValue(d); - if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + if (string.IsNullOrEmpty(col.DbInsertValue) == false) + sb.Append(col.DbInsertValue); else { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + object val = col.GetMapValue(d); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + } } ++colidx2; } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index a7fc5be4..844364ad 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -218,7 +218,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { if (tbcol.Attribute.IsNullable == false) - sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); } if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) @@ -240,7 +240,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable == false) { - sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append("';\r\n"); + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); @@ -253,8 +253,7 @@ select nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), a.index_name, case when c.descend = 'DESC' then 1 else 0 end, -case when a.uniqueness = 'UNIQUE' then 1 else 0 end, -c.column_position +case when a.uniqueness = 'UNIQUE' then 1 else 0 end from all_indexes a, all_ind_columns c where a.index_name = c.index_name @@ -334,10 +333,10 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; } if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"nvl({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + insertvalue = $"nvl({insertvalue},{tbcol.DbDefaultValue})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + insertvalue = tbcol.DbDefaultValue; sb.Append(insertvalue.Replace("'", "''")).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 9bc4e84e..da39f52d 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -175,8 +175,8 @@ namespace FreeSql.Odbc.Oracle { switch (exp.Member.Name) { - case "Now": return "systimestamp"; - case "UtcNow": return "sys_extract_utc(systimestamp)"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "trunc(systimestamp)"; case "MinValue": return "to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')"; case "MaxValue": return "to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')"; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index 8827a089..e851589e 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -87,6 +87,8 @@ namespace FreeSql.Odbc.Oracle public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left} / {right})"; + public override string Now => "systimestamp"; + public override string NowUtc => "sys_extract_utc(systimestamp)"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 2b5c557e..5686919c 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -236,7 +236,11 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); @@ -249,7 +253,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); } //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0};\r\n", tbcol.Attribute.DbDefautValue)); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); @@ -338,10 +342,10 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"coalesce({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + insertvalue = $"coalesce({insertvalue},{tbcol.DbDefaultValue})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + insertvalue = tbcol.DbDefaultValue; sb.Append(insertvalue).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 86463249..b9a0b56e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -265,8 +265,8 @@ namespace FreeSql.Odbc.PostgreSQL { switch (exp.Member.Name) { - case "Now": return "current_timestamp"; - case "UtcNow": return "(current_timestamp at time zone 'UTC')"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "current_date"; case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index c9bcbc21..365f9eab 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -113,6 +113,8 @@ namespace FreeSql.Odbc.PostgreSQL public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "current_timestamp"; + public override string NowUtc => "(current_timestamp at time zone 'UTC')"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 6403f544..87d5f2bb 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -179,8 +179,7 @@ ELSE var pkidx = 0; foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); if (tbcol.Attribute.IsPrimary == true) { @@ -288,11 +287,7 @@ use " + database, tboldname ?? tbname); //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); - if (tbcol.Attribute.IsNullable == false && tbcol.Attribute.IsIdentity == false) - { - var addcoldbdefault = tbcol.Attribute.DbDefautValue; - if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); - } + if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" default(").Append(GetTransferDbDefaultValue(tbcol)).Append(")"); sbalter.Append(";\r\n"); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } @@ -354,8 +349,7 @@ use " + database, tboldname ?? tbname); var pkidx2 = 0; foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); if (tbcol.Attribute.IsPrimary == true) { @@ -396,10 +390,11 @@ use " + database, tboldname ?? tbname); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol))})"; + insertvalue = $"isnull({insertvalue},{GetTransferDbDefaultValue(tbcol)})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol)); + if (tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + insertvalue = GetTransferDbDefaultValue(tbcol); sb.Append(insertvalue.Replace("'", "''")).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n"); @@ -438,16 +433,15 @@ use " + database, tboldname ?? tbname); } } } - object GetTransferDbDefaultValue(ColumnInfo col) + string GetTransferDbDefaultValue(ColumnInfo col) { - var ddv = col.Attribute.DbDefautValue; - if (ddv == null) return ddv; - if (ddv is DateTime || ddv is DateTime?) + var ddv = col.DbDefaultValue; + if (string.IsNullOrEmpty(ddv) || ddv == "NULL") return ddv; + if (col.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime) && DateTime.TryParse(ddv, out var trydt)) { - var dt = (DateTime)ddv; - if (col.Attribute.DbType.Contains("SMALLDATETIME") && dt < new DateTime(1900, 1, 1)) ddv = new DateTime(1900, 1, 1); - else if (col.Attribute.DbType.Contains("DATETIME") && dt < new DateTime(1753, 1, 1)) ddv = new DateTime(1753, 1, 1); - else if (col.Attribute.DbType.Contains("DATE") && dt < new DateTime(0001, 1, 1)) ddv = new DateTime(0001, 1, 1); + if (col.Attribute.DbType.Contains("SMALLDATETIME") && trydt < new DateTime(1900, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(1900, 1, 1)); + else if (col.Attribute.DbType.Contains("DATETIME") && trydt < new DateTime(1753, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(1753, 1, 1)); + else if (col.Attribute.DbType.Contains("DATE") && trydt < new DateTime(0001, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(0001, 1, 1)); } return ddv; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 5a73fde2..41e40119 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -179,8 +179,8 @@ namespace FreeSql.Odbc.SqlServer { switch (exp.Member.Name) { - case "Now": return "getdate()"; - case "UtcNow": return "getutcdate()"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "convert(char(10),getdate(),120)"; case "MinValue": return "'1753/1/1 0:00:00'"; case "MaxValue": return "'9999/12/31 23:59:59'"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index 02f18715..bdd06913 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -74,6 +74,8 @@ namespace FreeSql.Odbc.SqlServer } public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "getdate()"; + public override string NowUtc => "getutcdate()"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 259c103b..afda477c 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -64,13 +64,18 @@ namespace FreeSql.Oracle.Curd if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); - object val = col.GetMapValue(d); - if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + if (string.IsNullOrEmpty(col.DbInsertValue) == false) + sb.Append(col.DbInsertValue); else { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); - _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + object val = col.GetMapValue(d); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + } } ++colidx2; } diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index ee4f2097..52bb15f6 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -219,7 +219,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { if (tbcol.Attribute.IsNullable == false) - sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); } if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) @@ -241,7 +241,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable == false) { - sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append("';\r\n"); + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); @@ -334,10 +334,10 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; } if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"nvl({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + insertvalue = $"nvl({insertvalue},{tbcol.DbDefaultValue})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + insertvalue = tbcol.DbDefaultValue; sb.Append(insertvalue.Replace("'", "''")).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 20a1011f..7dbc44e7 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -175,8 +175,8 @@ namespace FreeSql.Oracle { switch (exp.Member.Name) { - case "Now": return "systimestamp"; - case "UtcNow": return "sys_extract_utc(systimestamp)"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "trunc(systimestamp)"; case "MinValue": return "to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')"; case "MaxValue": return "to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')"; diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 11c46adc..570c4c0f 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -82,6 +82,8 @@ namespace FreeSql.Oracle public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left} / {right})"; + public override string Now => "systimestamp"; + public override string NowUtc => "sys_extract_utc(systimestamp)"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index fa57fdf1..f8bfab2f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -274,7 +274,11 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); @@ -287,7 +291,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); } //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(_commonUtils.FormatSql("{0};\r\n", tbcol.Attribute.DbDefautValue)); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); @@ -376,10 +380,10 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"coalesce({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + insertvalue = $"coalesce({insertvalue},{tbcol.DbDefaultValue})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + insertvalue = tbcol.DbDefaultValue; sb.Append(insertvalue).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 3ea73ae2..7996dca4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -295,8 +295,8 @@ namespace FreeSql.PostgreSQL { switch (exp.Member.Name) { - case "Now": return "current_timestamp"; - case "UtcNow": return "(current_timestamp at time zone 'UTC')"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "current_date"; case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index ce2213a7..a0c015f1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -139,6 +139,8 @@ namespace FreeSql.PostgreSQL public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "current_timestamp"; + public override string NowUtc => "(current_timestamp at time zone 'UTC')"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 44747d23..127acd83 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -182,8 +182,7 @@ ELSE var pkidx = 0; foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); if (tbcol.Attribute.IsPrimary == true) { @@ -291,11 +290,7 @@ use " + database, tboldname ?? tbname); //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); - if (tbcol.Attribute.IsNullable == false && tbcol.Attribute.IsIdentity == false) - { - var addcoldbdefault = tbcol.Attribute.DbDefautValue; - if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); - } + if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" default(").Append(GetTransferDbDefaultValue(tbcol)).Append(")"); sbalter.Append(";\r\n"); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } @@ -357,8 +352,7 @@ use " + database, tboldname ?? tbname); var pkidx2 = 0; foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); if (tbcol.Attribute.IsPrimary == true) { @@ -399,10 +393,11 @@ use " + database, tboldname ?? tbname); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol))})"; + insertvalue = $"isnull({insertvalue},{GetTransferDbDefaultValue(tbcol)})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", GetTransferDbDefaultValue(tbcol)); + if (tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + insertvalue = GetTransferDbDefaultValue(tbcol); sb.Append(insertvalue.Replace("'", "''")).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n"); @@ -441,16 +436,15 @@ use " + database, tboldname ?? tbname); } } } - object GetTransferDbDefaultValue(ColumnInfo col) + string GetTransferDbDefaultValue(ColumnInfo col) { - var ddv = col.Attribute.DbDefautValue; - if (ddv == null) return ddv; - if (ddv is DateTime || ddv is DateTime?) + var ddv = col.DbDefaultValue; + if (string.IsNullOrEmpty(ddv) || ddv == "NULL") return ddv; + if (col.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime) && DateTime.TryParse(ddv, out var trydt)) { - var dt = (DateTime)ddv; - if (col.Attribute.DbType.Contains("SMALLDATETIME") && dt < new DateTime(1900, 1, 1)) ddv = new DateTime(1900, 1, 1); - else if (col.Attribute.DbType.Contains("DATETIME") && dt < new DateTime(1753, 1, 1)) ddv = new DateTime(1753, 1, 1); - else if (col.Attribute.DbType.Contains("DATE") && dt < new DateTime(0001, 1, 1)) ddv = new DateTime(0001, 1, 1); + if (col.Attribute.DbType.Contains("SMALLDATETIME") && trydt < new DateTime(1900, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(1900, 1, 1)); + else if (col.Attribute.DbType.Contains("DATETIME") && trydt < new DateTime(1753, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(1753, 1, 1)); + else if (col.Attribute.DbType.Contains("DATE") && trydt < new DateTime(0001, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(0001, 1, 1)); } return ddv; } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 5768d9c1..d8f61bc3 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -179,8 +179,8 @@ namespace FreeSql.SqlServer { switch (exp.Member.Name) { - case "Now": return "getdate()"; - case "UtcNow": return "getutcdate()"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "convert(char(10),getdate(),120)"; case "MinValue": return "'1753/1/1 0:00:00'"; case "MaxValue": return "'9999/12/31 23:59:59'"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 56659c60..bf66c1b1 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -85,6 +85,8 @@ namespace FreeSql.SqlServer } public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "getdate()"; + public override string NowUtc => "getutcdate()"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 1c665dc7..d2e14193 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -117,8 +117,7 @@ namespace FreeSql.Sqlite sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) { isIndent = true; @@ -244,8 +243,7 @@ namespace FreeSql.Sqlite sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) { isIndent = true; @@ -278,10 +276,10 @@ namespace FreeSql.Sqlite insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; } if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})"; + insertvalue = $"ifnull({insertvalue},{tbcol.DbDefaultValue})"; } else if (tbcol.Attribute.IsNullable == false) - insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue); + insertvalue = tbcol.DbDefaultValue; sb.Append(insertvalue).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 9bc01183..68f8cea6 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -175,8 +175,8 @@ namespace FreeSql.Sqlite { switch (exp.Member.Name) { - case "Now": return "datetime(current_timestamp,'localtime')"; - case "UtcNow": return "current_timestamp"; + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; case "Today": return "date(current_timestamp,'localtime')"; case "MinValue": return "datetime('0001-01-01 00:00:00.000')"; case "MaxValue": return "datetime('9999-12-31 23:59:59.999')"; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 498ef244..fd7a88f8 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -85,6 +85,8 @@ namespace FreeSql.Sqlite public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "datetime(current_timestamp,'localtime')"; + public override string NowUtc => "current_timestamp"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, string columnName) => columnName; From e29ac93a671b5eadda45a7e1740aa9ac50490fbf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 25 Nov 2019 18:06:21 +0800 Subject: [PATCH 0281/1029] ## v0.12.4 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7d4b1e94..20c28dec 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.3 + 0.12.4 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 3ec6c6e6..672474d7 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 41fc59a4..ef477336 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2ce356cd..e366af7b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 2f60b2b5..ed5ac3f0 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.3 + 0.12.4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index ddad21c3..cc2259b3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e4e1f2ae..ca4f2490 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d7f6e4d0..6bb85ebc 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3211f9f4..db188611 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 1c3ccf18..e8bf1439 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index dc65d203..b9dddf8f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index aadf9b99..73bb0f69 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 59120f94..eab75b55 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.3 + 0.12.4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 20e06ef3a23fed4dceceee3daf45d118433b82a4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 25 Nov 2019 22:14:09 +0800 Subject: [PATCH 0282/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=8F=92=E5=85=A5=20Values=20=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E9=99=90=E5=88=B6=E8=B6=85=E5=87=BA=E7=9A=84=E5=88=A4=E6=96=AD?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 111 ++++++++++++++++-- .../Internal/CommonProvider/InsertProvider.cs | 38 ++---- .../Internal/CommonProvider/UpdateProvider.cs | 38 ++---- 3 files changed, 120 insertions(+), 67 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index cf9195e2..fb7f5ac3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -193,23 +193,108 @@ namespace FreeSql.Tests public DateTime? ct2 { get; set; } } + public class TBatInst + { + public Guid Id { get; set; } + public string Name { get; set; } + } + [Fact] public void Test02() { - var serverTime = g.pgsql.Select().Limit(1).First(a => DateTime.UtcNow); - var timeOffset = DateTime.UtcNow.Subtract(serverTime); //减去数据库时间 + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); - g.pgsql.Aop.AuditValue += new EventHandler((_, e) => - { - if (e.Column.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime)) - { - if (e.Value == null || (DateTime)e.Value == default(DateTime)) - { - e.Value = DateTime.Now.Subtract(timeOffset); - return; - } - } - }); + g.sqlserver.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + g.mysql.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + g.pgsql.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + g.oracle.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + g.sqlite.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + + Assert.Equal(1048, g.sqlserver.Select().Count()); + Assert.Equal(1048, g.mysql.Select().Count()); + Assert.Equal(1048, g.pgsql.Select().Count()); + Assert.Equal(1048, g.oracle.Select().Count()); + Assert.Equal(1048, g.sqlite.Select().Count()); + + //---- + + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + + g.sqlserver.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + g.mysql.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + g.pgsql.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + g.oracle.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + g.sqlite.Insert(Enumerable.Range(0, 1048).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + + Assert.Equal(1048, g.sqlserver.Select().Count()); + Assert.Equal(1048, g.mysql.Select().Count()); + Assert.Equal(1048, g.pgsql.Select().Count()); + Assert.Equal(1048, g.oracle.Select().Count()); + Assert.Equal(1048, g.sqlite.Select().Count()); + + //---- + + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + + g.sqlserver.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + g.mysql.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + g.pgsql.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + g.oracle.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + g.sqlite.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).ExecuteAffrows(); + + Assert.Equal(3348, g.sqlserver.Select().Count()); + Assert.Equal(3348, g.mysql.Select().Count()); + Assert.Equal(3348, g.pgsql.Select().Count()); + Assert.Equal(3348, g.oracle.Select().Count()); + Assert.Equal(3348, g.sqlite.Select().Count()); + + //---- + + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + + g.sqlserver.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + g.mysql.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + g.pgsql.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + g.oracle.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + g.sqlite.Insert(Enumerable.Range(0, 3348).Select(a => new TBatInst { Name = "test" + a }).ToList()).NoneParameter().ExecuteAffrows(); + + Assert.Equal(3348, g.sqlserver.Select().Count()); + Assert.Equal(3348, g.mysql.Select().Count()); + Assert.Equal(3348, g.pgsql.Select().Count()); + Assert.Equal(3348, g.oracle.Select().Count()); + Assert.Equal(3348, g.sqlite.Select().Count()); + + + //var serverTime = g.pgsql.Select().Limit(1).First(a => DateTime.UtcNow); + //var timeOffset = DateTime.UtcNow.Subtract(serverTime); //减去数据库时间 + + //g.pgsql.Aop.AuditValue += new EventHandler((_, e) => + //{ + // if (e.Column.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime)) + // { + // if (e.Value == null || (DateTime)e.Value == default(DateTime)) + // { + // e.Value = DateTime.Now.Subtract(timeOffset); + // return; + // } + // } + //}); g.pgsql.Delete().Where("1=1").ExecuteAffrows(); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 83b63483..ed89acca 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -147,37 +147,21 @@ namespace FreeSql.Internal.CommonProvider parameterLimit = parameterLimit - 1; if (_source == null || _source.Any() == false) return new List[0]; if (_source.Count == 1) return new[] { _source }; - if (_noneParameter) - { - if (_source.Count < valuesLimit) return new[] { _source }; - var execCount = (int)Math.Ceiling(1.0 * _source.Count / valuesLimit); - var ret = new List[execCount]; - for (var a = 0; a < execCount; a++) - { - var subSource = new List(); - subSource = _source.GetRange(a * valuesLimit, Math.Min(valuesLimit, _source.Count - a * valuesLimit)); - ret[a] = subSource; - } - return ret; - } - else + var takeMax = valuesLimit; + if (_noneParameter == false) { var colSum = _table.Columns.Count - _ignore.Count; - var takeMax = parameterLimit / colSum; - var pamTotal = colSum * _source.Count; - if (pamTotal < parameterLimit) return new[] { _source }; - - var execCount = (int)Math.Ceiling(1.0 * pamTotal / takeMax / colSum); - var ret = new List[execCount]; - for (var a = 0; a < execCount; a++) - { - var subSource = new List(); - subSource = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); - ret[a] = subSource; - } - return ret; + takeMax = parameterLimit / colSum; + if (takeMax > valuesLimit) takeMax = valuesLimit; } + if (_source.Count <= takeMax) return new[] { _source }; + + var execCount = (int)Math.Ceiling(1.0 * _source.Count / takeMax); + var ret = new List[execCount]; + for (var a = 0; a < execCount; a++) + ret[a] = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); + return ret; } protected int SplitExecuteAffrows(int valuesLimit, int parameterLimit) { diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 255f7c1d..f8abaa1a 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -107,37 +107,21 @@ namespace FreeSql.Internal.CommonProvider parameterLimit = parameterLimit - 1; if (_source == null || _source.Any() == false) return new List[0]; if (_source.Count == 1) return new[] { _source }; - if (_noneParameter) - { - if (_source.Count < valuesLimit) return new[] { _source }; - var execCount = (int)Math.Ceiling(1.0 * _source.Count / valuesLimit); - var ret = new List[execCount]; - for (var a = 0; a < execCount; a++) - { - var subSource = new List(); - subSource = _source.GetRange(a * valuesLimit, Math.Min(valuesLimit, _source.Count - a * valuesLimit)); - ret[a] = subSource; - } - return ret; - } - else + var takeMax = valuesLimit; + if (_noneParameter == false) { var colSum = _table.Columns.Count - _ignore.Count; - var takeMax = parameterLimit / colSum; - var pamTotal = colSum * _source.Count; - if (pamTotal < parameterLimit) return new[] { _source }; - - var execCount = (int)Math.Ceiling(1.0 * pamTotal / takeMax / colSum); - var ret = new List[execCount]; - for (var a = 0; a < execCount; a++) - { - var subSource = new List(); - subSource = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); - ret[a] = subSource; - } - return ret; + takeMax = parameterLimit / colSum; + if (takeMax > valuesLimit) takeMax = valuesLimit; } + if (_source.Count <= takeMax) return new[] { _source }; + + var execCount = (int)Math.Ceiling(1.0 * _source.Count / takeMax); + var ret = new List[execCount]; + for (var a = 0; a < execCount; a++) + ret[a] = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); + return ret; } protected int SplitExecuteAffrows(int valuesLimit, int parameterLimit) { From bfed0cd1245e60f88d0bf181ae496980c8f1ea6b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 25 Nov 2019 22:33:44 +0800 Subject: [PATCH 0283/1029] ## v0.12.5 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/DbSet/DbSet.cs | 4 +++- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/DataAnnotations/ColumnAttribute.cs | 10 +--------- FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonUtils.cs | 6 +++--- FreeSql/Internal/UtilsExpressionTree.cs | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 21 insertions(+), 27 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 20c28dec..6f223beb 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.4 + 0.12.5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 672474d7..ec8b41fa 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ef477336..8b3273c6 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index e0728bef..b5331f1a 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -107,8 +107,9 @@ namespace FreeSql internal ConcurrentDictionary _statesInternal => _states; TableInfo _tablePriv; protected TableInfo _table => _tablePriv ?? (_tablePriv = _db.Orm.CodeFirst.GetTableByEntity(_entityType)); - ColumnInfo[] _tableIdentitysPriv; + ColumnInfo[] _tableIdentitysPriv, _tableServerTimesPriv; protected ColumnInfo[] _tableIdentitys => _tableIdentitysPriv ?? (_tableIdentitysPriv = _table.Primarys.Where(a => a.Attribute.IsIdentity).ToArray()); + protected ColumnInfo[] _tableServerTimes => _tableServerTimesPriv ?? (_tableServerTimesPriv = _table.Primarys.Where(a => a.Attribute.ServerTime != DateTimeKind.Unspecified).ToArray()); protected Type _entityType = typeof(TEntity); public Type EntityType => _entityType; @@ -125,6 +126,7 @@ namespace FreeSql _entityType = entityType; _tablePriv = newtb ?? throw new Exception("DbSet.AsType 参数错误,请传入正确的实体类型"); _tableIdentitysPriv = null; + _tableServerTimesPriv = null; return this; } diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e366af7b..223efed1 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index ed5ac3f0..6114645c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.4 + 0.12.5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 71216b91..b7cc6faf 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -72,17 +72,9 @@ namespace FreeSql.DataAnnotations /// public bool CanUpdate { get => _CanUpdate ?? true; set => _CanUpdate = value; } - internal DateTimeKind? _ServerTime; /// /// 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 /// - public DateTimeKind ServerTime - { - get => _ServerTime ?? DateTimeKind.Local; - set - { - _ServerTime = value == DateTimeKind.Unspecified ? DateTimeKind.Local : value; - } - } + public DateTimeKind ServerTime { get; set; } } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cc2259b3..1d6a222e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 9b0e17bc..c533af4e 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -128,7 +128,7 @@ namespace FreeSql.Internal if (trycol._Position != null) attr._Position = trycol.Position; if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert; if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate; - if (trycol._ServerTime != null) attr._ServerTime = trycol._ServerTime; + if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime; } var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); foreach (var tryattrobj in attrs) @@ -147,7 +147,7 @@ namespace FreeSql.Internal if (tryattr._Position != null) attr._Position = tryattr.Position; if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert; if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate; - if (tryattr._ServerTime != null) attr._ServerTime = tryattr.ServerTime; + if (tryattr.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = tryattr.ServerTime; } ColumnAttribute ret = null; if (!string.IsNullOrEmpty(attr.Name)) ret = attr; @@ -162,7 +162,7 @@ namespace FreeSql.Internal if (attr._Position != null) ret = attr; if (attr._CanInsert != null) ret = attr; if (attr._CanUpdate != null) ret = attr; - if (attr._ServerTime != null) ret = attr; + if (attr.ServerTime != DateTimeKind.Unspecified) ret = attr; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 69cb6087..84faec3d 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -189,7 +189,7 @@ namespace FreeSql.Internal // else if (Math.Abs(dt.Subtract(DateTime.UtcNow).TotalSeconds) < 60) // col.DbDefaultValue = common.NowUtc; //} - if (colattr._ServerTime != null && new[] { typeof(DateTime), typeof(DateTimeOffset) }.Contains(colattr.MapType.NullableTypeOrThis())) + if (colattr.ServerTime != DateTimeKind.Unspecified && new[] { typeof(DateTime), typeof(DateTimeOffset) }.Contains(colattr.MapType.NullableTypeOrThis())) { col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index ca4f2490..eeb4adfe 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6bb85ebc..278c1ffe 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index db188611..9854d52b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index e8bf1439..105d3fc6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b9dddf8f..29198669 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 73bb0f69..8955d9c0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index eab75b55..dde7bdbd 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.4 + 0.12.5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 27f053f00be75d9dc4eaeb9eced659f3fe181658 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 29 Nov 2019 17:56:06 +0800 Subject: [PATCH 0284/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ReadAnonymou?= =?UTF-8?q?s=20=E6=98=A0=E5=B0=84=E7=B1=BB=E5=9E=8B=E4=B8=8D=E4=B8=80?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E5=AE=B9=E9=94=99=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 75 ++++++++ .../FreeSql.Tests/Other/kwlib/department.cs | 79 ++++++++ .../Other/kwlib/department_employee.cs | 20 ++ .../FreeSql.Tests/Other/kwlib/employee.cs | 171 ++++++++++++++++++ .../Sqlite/Curd/SqliteSelectTest.cs | 6 + FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 31 +++- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 3 + FreeSql/Internal/CommonExpression.cs | 16 +- 8 files changed, 395 insertions(+), 6 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/kwlib/department.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_employee.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/kwlib/employee.cs diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index d0b42783..5b80bfb0 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -389,5 +389,80 @@ 验证标志 + + + 部门表 + + + + + 部门ID + + + + + 员工列表 对应employee.deptid + + + + + 上级部门ID + + + + + 上级部门对象 + + + + + 部门主管ID + + + + + 部门主管对象 + + + + + 下级部门列表 + + + + + 部门代码 + + + + + 部门名称 + + + + + 员工表 + + + + + 员工ID + + + + + 上级主管对象 + + + + + 下级员工列表 + + + + + 部门对象 + + diff --git a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department.cs b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department.cs new file mode 100644 index 00000000..1f3a5ccf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department.cs @@ -0,0 +1,79 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace kwlib +{ + /// + /// 部门表 + /// + [Serializable] + [Index("部门代码deptcode唯一", "deptcode", true)] + public class department + { + /// + /// 部门ID + /// + [Column(IsPrimary = true, IsIdentity = true)] + public int id { get; set; } + + /// + /// 员工列表 对应employee.deptid + /// + [Navigate("deptid")] + public List Employees { get; set; } + + /// + /// 上级部门ID + /// + public int? supdeptid { get; set; } + /// + /// 上级部门对象 + /// + [Navigate("supdeptid")] + public department parentdepartments { get; set; } + + /// + /// 部门主管ID + /// + public int? managerid { get; set; } + /// + /// 部门主管对象 + /// + [Navigate("managerid")] + public employee manager { get; set; } + + + /// + /// 下级部门列表 + /// + [Navigate("supdeptid")] + public List childDepartments { get; set; } + + + [Navigate(ManyToMany = typeof(department_employee))] + public List employees22 { get; set; } + + + #region MyRegion + /// + /// 部门代码 + /// + public string deptcode { get; set; } + + /// + /// 部门名称 + /// + public string deptname { get; set; } + #endregion + + + + + } + +} \ No newline at end of file diff --git a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_employee.cs b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_employee.cs new file mode 100644 index 00000000..8c20b8e1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_employee.cs @@ -0,0 +1,20 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace kwlib +{ + public class department_employee + { + public int departmentId { get; set; } + public int employeeId { get; set; } + + [Navigate("departmentId")] + public department dept { get; set; } + [Navigate("employeeId")] + public employee empe { get; set; } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/employee.cs b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/employee.cs new file mode 100644 index 00000000..9b292e89 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/employee.cs @@ -0,0 +1,171 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace kwlib +{ + /// + /// 员工表 + /// + [Serializable] + [Index("员工代码empcode唯一", "empcode", true)] + public class employee + { + + + /// + /// 员工ID + /// + [Column(IsPrimary = true, IsIdentity = true)] + [System.ComponentModel.DisplayName("员工ID ")] + public int id { get; set; } + + [System.ComponentModel.DisplayName("上级主管ID")] + /// + /// 上级主管ID + /// + public int? managerid { get; set; } + /// + /// 上级主管对象 + /// + [Navigate("managerid")] + public employee parentManager { get; set; } + + /// + /// 下级员工列表 + /// + [Navigate("managerid")] + public List Employees { get; set; } + + + [Navigate(ManyToMany = typeof(department_employee))] + public List departments { get; set; } + + [System.ComponentModel.DisplayName("部门ID ")] + /// + /// 部门ID + /// + public int? deptid { get; set; } + /// + /// 部门对象 + /// + [Navigate("deptid")] + public department Department { get; set; } + + + + [System.ComponentModel.DisplayName("员工工号")] + /// + /// 员工工号 + /// + public String empcode { get; set; } + + + + [System.ComponentModel.DisplayName("员工姓名")] + /// + /// 员工姓名 + /// + public String empname { get; set; } + + + [System.ComponentModel.DisplayName("地址")] + /// + /// 地址 + /// + public String address { get; set; } + + + [System.ComponentModel.DisplayName("工卡ID ")] + /// + /// 工卡ID + /// + + public String cardid { get; set; } + + + [System.ComponentModel.DisplayName("邮件地址 ")] + /// + /// 邮件地址 + /// + + public String email { get; set; } + + + [System.ComponentModel.DisplayName("合同日期")] + /// + /// 合同日期 + /// + + public DateTime? hetongdate { get; set; } + + + [System.ComponentModel.DisplayName("籍贯")] + /// + /// 籍贯 + /// + + public String homeaddress { get; set; } + + + [System.ComponentModel.DisplayName("入职时间")] + /// + /// 入职时间 + /// + + public DateTime jointime { get; set; } + + + [System.ComponentModel.DisplayName("离职日期")] + /// + /// 离职日期 + /// + public DateTime? leavedate { get; set; } + + + [System.ComponentModel.DisplayName("登录密码")] + /// + /// 登录密码 + /// + public String loginpass { get; set; } + + + + [System.ComponentModel.DisplayName("电话")] + /// + /// 电话 + /// + public String phone { get; set; } + + + [System.ComponentModel.DisplayName("相片地址")] + /// + /// 相片地址 + /// + + public String picurl { get; set; } + + + + [System.ComponentModel.DisplayName("身份证")] + /// + /// 身份证 + /// + + public String sfz { get; set; } + + + } + + + + + + + + + +} diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 1d32c36c..d2e262ca 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -798,9 +798,15 @@ namespace FreeSql.Tests.Sqlite }; var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule).AsTable(tableRule2); var sql = query.ToSql(); + var sql2 = query.ToSql("count(1)"); + var count2 = query.ToList("count(1)"); + + query = select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3"); sql = query.ToSql(a => a.Id); + sql2 = query.ToSql("count(1)"); + count2 = query.ToList("count(1)"); //����е�������a.Type��a.Type.Parent ���ǵ������� diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index b6080caf..1ccd662d 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -424,9 +424,31 @@ namespace FreeSql.Tests public new int Id { get; set; } } + public class TestUpdateModel + { + public string F_EmpId { get; set; } + public TestUpdateModelEnum F_RoleType { get; set; } + public TestUpdateModelEnum F_UseType { get; set; } + } + public enum TestUpdateModelEnum { x1, x2, x3 } + [Fact] public void Test1() { + var _model = new TestUpdateModel { + F_EmpId = "xx11", + F_RoleType = TestUpdateModelEnum.x2, + F_UseType = TestUpdateModelEnum.x3 + }; + var testsql2008 = g.sqlserver.Update() + .Where(a => a.F_EmpId == _model.F_EmpId) + .Set(a => new TestUpdateModel + { + F_RoleType = _model.F_RoleType, + F_UseType = _model.F_UseType + }).ToSql(); + + g.sqlserver.Select(); g.sqlite.Update(1).NoneParameter().Set(a => a.title, null).ExecuteAffrows(); @@ -706,7 +728,14 @@ namespace FreeSql.Tests OptionsEntity02 = false, OptionsEntity04 = testarray[0] }).ToSql(); - + var tbidsql3 = g.sqlite.Update().Where(a => a.TemplatesId == tbid) + .Set(a => new TaskBuild + { + FileName = "111", + TaskName = a.TaskName + "333", + OptionsEntity02 = false, + OptionsEntity04 = testarray[0] + }).ToSql(); var dkdkdkd = g.oracle.Select().ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index fb7f5ac3..3426816e 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; using System.Threading; using System.Data.SqlClient; +using kwlib; namespace FreeSql.Tests { @@ -202,6 +203,8 @@ namespace FreeSql.Tests [Fact] public void Test02() { + var tekset = g.sqlite.Select().IncludeMany(a => a.departments).ToList(); + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); g.mysql.Delete().Where("1=1").ExecuteAffrows(); g.pgsql.Delete().Where("1=1").ExecuteAffrows(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b31fc599..d767c504 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -124,7 +124,7 @@ namespace FreeSql.Internal { Property = dtoProp, CsName = dtoProp.Name, - CsType = dtoProp.PropertyType, + CsType = trydtocol.CsType, // dtoProp.PropertyType, MapType = trydtocol.Attribute.MapType }; parent.Childs.Add(child); @@ -195,7 +195,7 @@ namespace FreeSql.Internal { Property = dtoProp, CsName = dtoProp.Name, - CsType = dtoProp.PropertyType, + CsType = trydtocol.CsType, //dtoProp.PropertyType, MapType = trydtocol.Attribute.MapType }; parent.Childs.Add(child); @@ -227,11 +227,17 @@ namespace FreeSql.Internal if (notRead) { ++index; + if (parent.Property != null) + return Utils.GetDataReaderValue(parent.Property.PropertyType, null); return Utils.GetDataReaderValue(parent.CsType, null); } - if (parent.CsType == parent.MapType) - return Utils.GetDataReaderValue(parent.CsType, dr.GetValue(++index)); - return Utils.GetDataReaderValue(parent.CsType, Utils.GetDataReaderValue(parent.MapType, dr.GetValue(++index))); + object objval = dr.GetValue(++index); + if (parent.CsType != parent.MapType) + objval = Utils.GetDataReaderValue(parent.MapType, objval); + objval = Utils.GetDataReaderValue(parent.CsType, objval); + if (parent.Property != null && parent.CsType != parent.Property.PropertyType) + objval = Utils.GetDataReaderValue(parent.Property.PropertyType, objval); + return objval; } switch (parent.ConsturctorType) { From dcd0ef5750bd26b338ab076db8b0af8813366743 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 29 Nov 2019 21:46:53 +0800 Subject: [PATCH 0285/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Oracle/Sqlit?= =?UTF-8?q?e=20IInsert.ExecuteInserted=20=E6=96=B9=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E4=BA=86=E8=A2=AB=20clear=20=E8=BF=87?= =?UTF-8?q?=E5=90=8E=E7=9A=84=20=5Fsource=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs | 6 ++++-- Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs | 6 ++++-- Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index 7e584c90..f728c68c 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -144,8 +144,9 @@ namespace FreeSql.Odbc.Oracle var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); + var ret = _source.ToList(); this.RawExecuteAffrows(); - return _source; + return ret; } #if net40 @@ -212,8 +213,9 @@ namespace FreeSql.Odbc.Oracle var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); + var ret = _source.ToList(); await this.RawExecuteAffrowsAsync(); - return _source; + return ret; } #endif } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index afda477c..b48404a5 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -145,8 +145,9 @@ namespace FreeSql.Oracle.Curd var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); + var ret = _source.ToList(); this.RawExecuteAffrows(); - return _source; + return ret; } #if net40 @@ -213,8 +214,9 @@ namespace FreeSql.Oracle.Curd var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); + var ret = _source.ToList(); await this.RawExecuteAffrowsAsync(); - return _source; + return ret; } #endif } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index 034aeabb..dd03e1e7 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -52,8 +52,9 @@ namespace FreeSql.Sqlite.Curd var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); + var ret = _source.ToList(); this.RawExecuteAffrows(); - return _source; + return ret; } #if net40 @@ -93,8 +94,9 @@ namespace FreeSql.Sqlite.Curd var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); + var ret = _source.ToList(); await this.RawExecuteAffrowsAsync(); - return _source; + return ret; } #endif } From 6b7eefb5e7359c679333396ce0bacf87e5f53124 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 1 Dec 2019 12:51:11 +0800 Subject: [PATCH 0286/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbContext=20?= =?UTF-8?q?SaveMany=20=E5=AF=B9=E6=AF=94=E5=88=A0=E9=99=A4=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetAsync.cs | 4 ++-- FreeSql.DbContext/DbSet/DbSetSync.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 3d7df0bc..5863b766 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -255,8 +255,8 @@ namespace FreeSql curContains.Add(curIdx); } if (curContains.Any()) - foreach (var curIdx in curContains) - curList.RemoveAt(curIdx); + for (var delIdx = curContains.Count - 1; delIdx >= 0; delIdx--) + curList.RemoveAt(curContains[delIdx]); else midListDel.Add(midItem); } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 4e92feb7..4f7f2701 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -267,8 +267,8 @@ namespace FreeSql curContains.Add(curIdx); } if (curContains.Any()) - foreach (var curIdx in curContains) - curList.RemoveAt(curIdx); + for (var delIdx = curContains.Count - 1; delIdx >= 0; delIdx--) + curList.RemoveAt(curContains[delIdx]); else midListDel.Add(midItem); } From 79a7e8dc682d8145a21892d128a698ea0c145287 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 1 Dec 2019 12:53:53 +0800 Subject: [PATCH 0287/1029] ## v0.12.6 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6f223beb..efb86c70 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.5 + 0.12.6 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ec8b41fa..fa127cf3 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 8b3273c6..aec6f032 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 223efed1..1acea77c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 6114645c..1eecc21a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.5 + 0.12.6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1d6a222e..9b0afe15 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index eeb4adfe..3e644c04 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 278c1ffe..cbc8cd39 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 9854d52b..6a603312 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 105d3fc6..087585cb 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 29198669..ac8e9b95 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 8955d9c0..09666c92 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index dde7bdbd..9447ae38 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.5 + 0.12.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From ecfac8843e49a2661baeb169b6a792282fc72205 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 1 Dec 2019 12:56:05 +0800 Subject: [PATCH 0288/1029] update --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql/FreeSql.xml | 416 ++++++++++++------------ 2 files changed, 207 insertions(+), 216 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 768d92dd..8c5c2836 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2049,47 +2049,67 @@ - + - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + 可自定义解析表达式 - - - - - + - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) + 自定义实体的配置,方便和多个 ORM 共同使用 - - - + - 查询 + 自定义实体的属性配置,方便和多个 ORM 共同使用 - - - + - 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) + 增删查改,执行命令之前触发 - - - - + - 查询 + 增删查改,执行命令完成后触发 - - - + - 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) + CodeFirst迁移,执行之前触发 + + + + + CodeFirst迁移,执行完成触发 + + + + + Insert/Update自动值处理 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + @age; select 2", new { age = 25 }) @@ -2172,190 +2192,7 @@ - - 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) - - - - - - - - - 可自定义解析表达式 - - - - - 自定义实体的配置,方便和多个 ORM 共同使用 - - - - - 自定义实体的属性配置,方便和多个 ORM 共同使用 - - - - - 增删查改,执行命令之前触发 - - - - - 增删查改,执行命令完成后触发 - - - - - CodeFirst迁移,执行之前触发 - - - - - CodeFirst迁移,执行完成触发 - - - - - Insert/Update自动值处理 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - + ntArgs.Property"> 反射的属性信息 @@ -2639,6 +2476,167 @@ + + + 测量两个经纬度的距离,返回单位:米 + + 经纬坐标1 + + + 获取所有数据库 + + + + + + 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 + + + + + + + 获取数据库枚举类型int值 + + + + + + + 获取c#转换,(int)、(long) + + + + + + + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 中间表,多对多 + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + 测量两个经纬度的距离,返回单位:米 From e107b6bbd905e216adbd066cadef1d1aeda89340 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 3 Dec 2019 13:36:12 +0800 Subject: [PATCH 0289/1029] =?UTF-8?q?-=20=E7=A7=BB=E9=99=A4=20Lazy=20?= =?UTF-8?q?=E5=BB=B6=E6=97=B6=E5=8A=A0=E8=BD=BD=E5=8A=A8=E6=80=81=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=B8=AD=E7=9A=84=20Newtonsoft.Json=20=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 3 + FreeSql/FreeSql.xml | 463 ++++++++++++----------- FreeSql/Internal/UtilsExpressionTree.cs | 3 +- 3 files changed, 249 insertions(+), 220 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 1ccd662d..750f4948 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -16,6 +16,7 @@ using Zeus.Domain.Enum; using System.ComponentModel.DataAnnotations; using System.Reflection; using System.Threading; +using Newtonsoft.Json; namespace FreeSql.Tests { @@ -42,6 +43,8 @@ namespace FreeSql.Tests public string OrderTitle { get; set; } public string CustomerName { get; set; } public DateTime TransactionDate { get; set; } + + [JsonIgnore] public virtual List OrderDetails { get; set; } } public class OrderDetail diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8c5c2836..5151df8a 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2109,90 +2109,122 @@ 实体类型 - @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 }) + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - + - 执行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 }) + 实体类型的元数据 - - - - - - - ntArgs.Property"> + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + 反射的属性信息 @@ -2476,167 +2508,6 @@ - - - 测量两个经纬度的距离,返回单位:米 - - 经纬坐标1 - - - 获取所有数据库 - - - - - - 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 - - - - - - - 获取数据库枚举类型int值 - - - - - - - 获取c#转换,(int)、(long) - - - - - - - 获取c#值 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 中间表,多对多 - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - 测量两个经纬度的距离,返回单位:米 @@ -2893,3 +2764,159 @@ + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完将自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 事务体 () => {} + 超时,未执行完将自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 84faec3d..c3aa32ac 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -366,10 +366,9 @@ namespace FreeSql.Internal .AppendLine("using FreeSql.DataAnnotations;") .AppendLine("using System.Collections.Generic;") .AppendLine("using System.Linq;") - .AppendLine("using Newtonsoft.Json;") .AppendLine() .Append("public class ").Append(trytbTypeLazyName).Append(" : ").Append(trytbTypeName).AppendLine(" {") - .AppendLine(" [JsonIgnore] private IFreeSql __fsql_orm__ { get; set; }\r\n"); + .AppendLine(" private IFreeSql __fsql_orm__ { get; set; }\r\n"); } var cscodeLength = cscode?.Length ?? 0; From 46dcd226ff16650d6da57d398b7c3dde45f64fea Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 3 Dec 2019 13:37:26 +0800 Subject: [PATCH 0290/1029] ## v0.12.7 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index efb86c70..efae155f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.6 + 0.12.7 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index fa127cf3..6d49e43d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index aec6f032..938a8f97 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 1acea77c..548b5c4d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 1eecc21a..9d354ac0 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.6 + 0.12.7 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9b0afe15..7a7272ec 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3e644c04..4764fa60 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index cbc8cd39..23e18466 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 6a603312..793e5c48 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 087585cb..d405a960 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ac8e9b95..97083088 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 09666c92..01ed040b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9447ae38..40ca49c2 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.6 + 0.12.7 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 8c770a3ffb74d31fd9225dc08f1854947ef06b5a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 3 Dec 2019 21:16:40 +0800 Subject: [PATCH 0291/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IncludeMany?= =?UTF-8?q?=20=E7=BA=A7=E8=81=94=E6=9F=A5=E8=AF=A2=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E9=80=82=E9=85=8D=EF=BC=88=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E6=98=AF=E5=90=8C=E6=AD=A5=E6=96=B9=E5=BC=8F=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 6 +- .../BaseEntityReadOnly.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + .../Sqlite/Curd/SqliteSelectTest.cs | 165 ++++++++++ FreeSql.Tests/FreeSql.Tests/g.cs | 27 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 11 + FreeSql/FreeSql.xml | 287 ++++++++---------- .../SelectProvider/Select0Provider.cs | 16 +- .../SelectProvider/Select1Provider.cs | 79 ++++- 9 files changed, 416 insertions(+), 184 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 949cbac3..798ea5c3 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -4,7 +4,9 @@ using FreeSql.Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; +using System.Diagnostics; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace base_entity @@ -124,8 +126,8 @@ namespace base_entity ru1.RoleId = r2.Id; await ru1.SaveAsync(); - var u1roles = User1.Select.IncludeMany(a => a.Roles).ToList(); - var u1roles2 = User1.Select.Where(a => a.Roles.AsSelect().Any(b => b.Id == "xx")).ToList(); + var u1roles = await User1.Select.IncludeMany(a => a.Roles).ToListAsync(); + var u1roles2 = await User1.Select.Where(a => a.Roles.AsSelect().Any(b => b.Id == "xx")).ToListAsync(); }).Wait(); diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index e7e82ce5..60ce244a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -36,7 +36,7 @@ namespace FreeSql public static void Initialization(IFreeSql fsql) { _ormPriv = fsql; - _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); + _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine($"\r\n线程{Thread.CurrentThread.ManagedThreadId}: {e.Sql}\r\n"); } /// diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index d2e262ca..75739c13 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -2,6 +2,8 @@ using FreeSql.DataAnnotations; using System; using System.Collections.Generic; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace FreeSql.Tests.Sqlite @@ -1375,6 +1377,169 @@ namespace FreeSql.Tests.Sqlite .ToList(true); } + [Fact] + async public Task Include_ManyToManyAsync() + { + ThreadPool.SetMinThreads(100, 100); + await Task.Yield(); + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)await g.sqlite.Insert(tag1).ExecuteIdentityAsync(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)await g.sqlite.Insert(tag2).ExecuteIdentityAsync(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)await g.sqlite.Insert(tag3).ExecuteIdentityAsync(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)await g.sqlite.Insert(song1).ExecuteIdentityAsync(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)await g.sqlite.Insert(song2).ExecuteIdentityAsync(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)await g.sqlite.Insert(song3).ExecuteIdentityAsync(); + + await g.sqlite.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrowsAsync(); + await g.sqlite.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrowsAsync(); + await g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrowsAsync(); + await g.sqlite.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrowsAsync(); + await g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrowsAsync(); + await g.sqlite.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrowsAsync(); + + await new List(new[] { song1, song2, song3 }).IncludeManyAsync(g.sqlite, a => a.Tags); + + var songs1 = await g.sqlite.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToListAsync(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = await g.sqlite.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToListAsync(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = await g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToListAsync(true); + + + var songs11 = await g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToListAsync(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = await g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToListAsync(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = await g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToListAsync(true); + + // --- Select --- + + await new List(new[] { song1, song2, song3 }).IncludeManyAsync(g.sqlite, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = await g.sqlite.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToListAsync(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = await g.sqlite.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToListAsync(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = await g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToListAsync(true); + + + var asongs11 = await g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToListAsync(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = await g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToListAsync(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = await g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToListAsync(true); + } + public class ToDel1Pk { [Column(IsIdentity = true)] diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 4c336e30..0c8aac09 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; - +using System.Threading; public class g { @@ -13,8 +13,9 @@ public class g .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( - cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 - (cmd, traceLog) => Console.WriteLine(traceLog)) + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) .UseLazyLoading(true) .Build()); public static IFreeSql mysql => mysqlLazy.Value; @@ -29,8 +30,9 @@ public class g .UseSyncStructureToLower(true) .UseLazyLoading(true) .UseMonitorCommand( - cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 - (cmd, traceLog) => Console.WriteLine(traceLog)) + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) .Build(); }); public static IFreeSql pgsql => pgsqlLazy.Value; @@ -41,8 +43,9 @@ public class g .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( - cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 - (cmd, traceLog) => Console.WriteLine(traceLog)) + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) .UseLazyLoading(true) .Build()); public static IFreeSql sqlserver => sqlserverLazy.Value; @@ -56,8 +59,9 @@ public class g //.UseNoneCommandParameter(true) .UseMonitorCommand( - cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 - (cmd, traceLog) => Console.WriteLine(traceLog)) + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) .Build()); public static IFreeSql oracle => oracleLazy.Value; @@ -67,8 +71,9 @@ public class g //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) .UseMonitorCommand( - cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 - (cmd, traceLog) => Console.WriteLine(traceLog)) + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) .Build()); public static IFreeSql sqlite => sqliteLazy.Value; } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index e94e9eb8..29b0c08f 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -210,5 +210,16 @@ public static partial class FreeSqlGlobalExtensions select.SetList(list); return list; } + +#if net40 +#else + async public static System.Threading.Tasks.Task> IncludeManyAsync(this List list, IFreeSql orm, Expression>> navigateSelector, Action> then = null) where T1 : class where TNavigate : class + { + if (list == null || list.Any() == false) return list; + var select = orm.Select().IncludeMany(navigateSelector, then) as FreeSql.Internal.CommonProvider.Select1Provider; + await select.SetListAsync(list); + return list; + } +#endif #endregion } \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5151df8a..768d92dd 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2049,6 +2049,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 }) + + + + + + 可自定义解析表达式 @@ -2764,159 +2895,3 @@ - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完将自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 事务体 () => {} - 超时,未执行完将自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 41ae2e15..0c7aa3c2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -34,6 +34,10 @@ namespace FreeSql.Internal.CommonProvider protected DbConnection _connection; protected Action _trackToList; protected List> _includeToList = new List>(); +#if net40 +#else + protected List> _includeToListAsync = new List>(); +#endif protected bool _distinct; protected Expression _selectExpression; protected List _whereCascadeExpression = new List(); @@ -50,6 +54,10 @@ namespace FreeSql.Internal.CommonProvider _join.Clear(); _trackToList = null; _includeToList.Clear(); +#if net40 +#else + _includeToListAsync.Clear(); +#endif _selectExpression = null; _whereCascadeExpression.Clear(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); @@ -104,6 +112,10 @@ namespace FreeSql.Internal.CommonProvider toType.GetField("_connection", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._connection); toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList); toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); +#if net40 +#else + toType.GetField("_includeToListAsync", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToListAsync); +#endif toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); toType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression); @@ -1154,7 +1166,7 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - foreach (var include in _includeToList) include?.Invoke(ret); + foreach (var include in _includeToListAsync) await include?.Invoke(ret); _trackToList?.Invoke(ret); return ret; } @@ -1220,7 +1232,7 @@ namespace FreeSql.Internal.CommonProvider _orm.Aop.CurdAfter?.Invoke(this, after); } if (typeof(TReturn) == typeof(T1)) - foreach (var include in _includeToList) include?.Invoke(ret); + foreach (var include in _includeToListAsync) await include?.Invoke(ret); _trackToList?.Invoke(ret); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index c84f2328..1f65260f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -533,9 +533,16 @@ namespace FreeSql.Internal.CommonProvider } if (tbref.Columns.Any() == false) throw throwNavigateSelector; } - - _includeToList.Add(listObj => + +#if net40 + Action includeToListSyncOrAsync = (listObj, isAsync) => { + isAsync = false; +#else + Func includeToListSyncOrAsync = async (listObj, isAsync) => + { +#endif + var list = listObj as List; if (list == null) return; if (list.Any() == false) return; @@ -576,7 +583,7 @@ namespace FreeSql.Internal.CommonProvider Expression.Block( Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)), Expression.Label(returnTarget, Expression.Default(typeof(object))) - ), t1parm, propertyNameExp).Compile(): + ), t1parm, propertyNameExp).Compile() : Expression.Lambda>( Expression.Block( Expression.IfThen( @@ -700,8 +707,20 @@ namespace FreeSql.Internal.CommonProvider sbSql.Remove(0, 13); if (sbDic.Count == 1) sbSql.Remove(0, 15).Remove(sbSql.Length - 5, 5); sbDic.Clear(); - if (selectExp == null) subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, null); - else subList = subSelect.ToListMrPrivate(sbSql.ToString(), mf, null); + + if (isAsync) + { +#if net40 +#else + if (selectExp == null) subList = await subSelect.ToListAfPrivateAsync(sbSql.ToString(), af, null); + else subList = await subSelect.ToListMrPrivateAsync(sbSql.ToString(), mf, null); +#endif + } + else + { + if (selectExp == null) subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, null); + else subList = subSelect.ToListMrPrivate(sbSql.ToString(), mf, null); + } sbSql.Clear(); } else @@ -731,8 +750,20 @@ namespace FreeSql.Internal.CommonProvider sbDic.Clear(); } subSelect.Where(oldWhere); - if (selectExp == null) subList = subSelect.ToList(true); - else subList = subSelect.ToList(selectExp); + + if (isAsync) + { +#if net40 +#else + if (selectExp == null) subList = await subSelect.ToListAsync(true); + else subList = await subSelect.ToListAsync(selectExp); +#endif + } + else + { + if (selectExp == null) subList = subSelect.ToList(true); + else subList = subSelect.ToList(selectExp); + } } if (subList.Any() == false) @@ -826,7 +857,8 @@ namespace FreeSql.Internal.CommonProvider { if (z > 0) sbJoin.Append(" AND "); sbJoin.Append($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}"); - if (_whereCascadeExpression.Any()) { + if (_whereCascadeExpression.Any()) + { var cascade = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Alias = "midtb", AliasInit = "midtb", Table = tbrefMid, Type = SelectTableInfoType.InnerJoin }, _whereCascadeExpression); if (string.IsNullOrEmpty(cascade) == false) sbJoin.Append(" AND (").Append(cascade).Append(")"); @@ -843,7 +875,7 @@ namespace FreeSql.Internal.CommonProvider var sbSql = new StringBuilder(); if (_selectExpression == null) - {// return this.InternalToList(_selectExpression).Select(a => (a, ()).ToList(); + { var field = new StringBuilder(); var read = new ReadAnonymousTypeInfo(); read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; @@ -919,8 +951,19 @@ namespace FreeSql.Internal.CommonProvider sbSql.Append(subSelect.ToSql($"{(selectExp == null ? af.Field : mf.field)}{otherData?.field}")); } - if (selectExp == null) subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); - else subList = subSelect.ToListMrPrivate(sbSql.ToString(), mf, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + if (isAsync) + { +#if net40 +#else + if (selectExp == null) subList = await subSelect.ToListAfPrivateAsync(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + else subList = await subSelect.ToListMrPrivateAsync(sbSql.ToString(), mf, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); +#endif + } + else + { + if (selectExp == null) subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + else subList = subSelect.ToListMrPrivate(sbSql.ToString(), mf, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + } if (subList.Any() == false) { foreach (var item in list) @@ -983,7 +1026,13 @@ namespace FreeSql.Internal.CommonProvider } break; } - }); + }; + + _includeToList.Add(listObj => includeToListSyncOrAsync(listObj, false)); +#if net40 +#else + _includeToListAsync.Add(listObj => includeToListSyncOrAsync(listObj, true)); +#endif return this; } @@ -995,6 +1044,12 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else + async internal Task SetListAsync(IEnumerable list) + { + foreach (var include in _includeToListAsync) await include?.Invoke(list); + _trackToList?.Invoke(list); + } + public Task AvgAsync(Expression> column) { if (column == null) return Task.FromResult(default(TMember)); From 539e76c28ee0f183a45345bb74c38d33e2b91581 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 4 Dec 2019 15:37:56 +0800 Subject: [PATCH 0292/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20GetTableByEn?= =?UTF-8?q?tity=20=E5=BD=93=E5=B1=9E=E6=80=A7=E5=90=8D=E6=88=96=E7=89=B9?= =?UTF-8?q?=E6=80=A7=E5=90=8D=E9=87=8D=E5=A4=8D=E6=97=B6=E7=9A=84=E5=8F=8B?= =?UTF-8?q?=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 49 +++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 3 ++ 2 files changed, 52 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 5b80bfb0..7fce6993 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -464,5 +464,54 @@ 部门对象 + + + 入学年份 + + + + + 学段 + + + + + 人数 + + + + + + + + + + + + + + + + + + + + + 待标注 + + + + + 合格 + + + + + 不合格 + + + + + diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c3aa32ac..f175d6ae 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -195,6 +195,9 @@ namespace FreeSql.Internal col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; } + if (trytb.Columns.ContainsKey(colattr.Name)) throw new Exception($"ColumnAttribute.Name {colattr.Name} 重复存在,请检查(注意:不区分大小写)"); + if (trytb.ColumnsByCs.ContainsKey(p.Name)) throw new Exception($"属性名 {p.Name} 重复存在,请检查(注意:不区分大小写)"); + trytb.Columns.Add(colattr.Name, col); trytb.ColumnsByCs.Add(p.Name, col); columnsList.Add(col); From 13631535885827068117c719f476627652b76758 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Dec 2019 10:37:49 +0800 Subject: [PATCH 0293/1029] update ConnectionStrings --- readme.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/readme.md b/readme.md index c78af1b0..5264ad5b 100644 --- a/readme.md +++ b/readme.md @@ -71,6 +71,21 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | FreeSql.Extensions.JsonMap | NETStandard2.0、net45、net40 | | FreeSql.Extensions.BaseEntity | NETStandard2.0 | +# ConnectionStrings + +| Provider | ConnectionString | +| --- | --- | +| FreeSql.DataType.MySql | Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min pool size=1 | +| FreeSql.DataType.PostgreSQL | Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Minimum Pool Size=1 | +| FreeSql.DataType.SqlServer | Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=1 | +| FreeSql.DataType.Oracle | user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1 | +| FreeSql.DataType.Sqlite | Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Min Pool Size=1 | +| FreeSql.DataType.OdbcMySql | Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Min Pool Size=1 | +| FreeSql.DataType.OdbcSqlServer | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min Pool Size=1 | +| FreeSql.DataType.OdbcOracle | Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456;Min Pool Size=1 | +| FreeSql.DataType.OdbcPostgreSQL | Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Min Pool Size=1 | +| FreeSql.DataType.Odbc | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min pool size=1 | +

From 54589f6d73a4ed17e1b206c81e9615cab60e0582 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Dec 2019 10:39:58 +0800 Subject: [PATCH 0294/1029] update connstr --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 5264ad5b..cbb5c9ea 100644 --- a/readme.md +++ b/readme.md @@ -79,7 +79,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | FreeSql.DataType.PostgreSQL | Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Minimum Pool Size=1 | | FreeSql.DataType.SqlServer | Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=1 | | FreeSql.DataType.Oracle | user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1 | -| FreeSql.DataType.Sqlite | Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Min Pool Size=1 | +| FreeSql.DataType.Sqlite | Data Source=\|DataDirectory\|\document.db;Attachs=xxxtb.db;Pooling=true;Min Pool Size=1 | | FreeSql.DataType.OdbcMySql | Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Min Pool Size=1 | | FreeSql.DataType.OdbcSqlServer | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min Pool Size=1 | | FreeSql.DataType.OdbcOracle | Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456;Min Pool Size=1 | From 21ea54af7bf00fba46dc5edf8504790eb7a8b12a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Dec 2019 10:41:48 +0800 Subject: [PATCH 0295/1029] update ConnectionStrings --- readme.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/readme.md b/readme.md index cbb5c9ea..7de8853a 100644 --- a/readme.md +++ b/readme.md @@ -73,18 +73,18 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ # ConnectionStrings -| Provider | ConnectionString | +| DataType | ConnectionString | | --- | --- | -| FreeSql.DataType.MySql | Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min pool size=1 | -| FreeSql.DataType.PostgreSQL | Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Minimum Pool Size=1 | -| FreeSql.DataType.SqlServer | Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=1 | -| FreeSql.DataType.Oracle | user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1 | -| FreeSql.DataType.Sqlite | Data Source=\|DataDirectory\|\document.db;Attachs=xxxtb.db;Pooling=true;Min Pool Size=1 | -| FreeSql.DataType.OdbcMySql | Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Min Pool Size=1 | -| FreeSql.DataType.OdbcSqlServer | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min Pool Size=1 | -| FreeSql.DataType.OdbcOracle | Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456;Min Pool Size=1 | -| FreeSql.DataType.OdbcPostgreSQL | Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Min Pool Size=1 | -| FreeSql.DataType.Odbc | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min pool size=1 | +| DataType.MySql | Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min pool size=1 | +| DataType.PostgreSQL | Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Minimum Pool Size=1 | +| DataType.SqlServer | Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=1 | +| DataType.Oracle | user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1 | +| DataType.Sqlite | Data Source=\|DataDirectory\|\document.db;Attachs=xxxtb.db;Pooling=true;Min Pool Size=1 | +| DataType.OdbcMySql | Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Min Pool Size=1 | +| DataType.OdbcSqlServer | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min Pool Size=1 | +| DataType.OdbcOracle | Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456;Min Pool Size=1 | +| DataType.OdbcPostgreSQL | Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Min Pool Size=1 | +| DataType.Odbc | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min pool size=1 |

From e01f7a2061b89a9c5e2a5778ab5fbf4fc192da64 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Dec 2019 10:44:12 +0800 Subject: [PATCH 0296/1029] update ConnectionStrings --- readme.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index 7de8853a..26009b43 100644 --- a/readme.md +++ b/readme.md @@ -75,16 +75,16 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | DataType | ConnectionString | | --- | --- | -| DataType.MySql | Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min pool size=1 | -| DataType.PostgreSQL | Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Minimum Pool Size=1 | +| DataType.MySql | Data Source=127.0.0.1;Port=3306;User ID=root;Password=root; Initial Catalog=cccddd;Charset=utf8; SslMode=none;Min pool size=1 | +| DataType.PostgreSQL | Host=192.168.164.10;Port=5432;Username=postgres;Password=123456; Database=tedb;Pooling=true;Minimum Pool Size=1 | | DataType.SqlServer | Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=1 | -| DataType.Oracle | user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1 | -| DataType.Sqlite | Data Source=\|DataDirectory\|\document.db;Attachs=xxxtb.db;Pooling=true;Min Pool Size=1 | -| DataType.OdbcMySql | Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Min Pool Size=1 | -| DataType.OdbcSqlServer | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min Pool Size=1 | -| DataType.OdbcOracle | Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456;Min Pool Size=1 | -| DataType.OdbcPostgreSQL | Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Min Pool Size=1 | -| DataType.Odbc | Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Min pool size=1 | +| DataType.Oracle | user id=user1;password=123456; data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1 | +| DataType.Sqlite | Data Source=\|DataDirectory\|\document.db; Attachs=xxxtb.db; Pooling=true;Min Pool Size=1 | +| DataType.OdbcMySql | Driver={MySQL ODBC 8.0 Unicode Driver}; Server=127.0.0.1;Persist Security Info=False; Trusted_Connection=Yes;UID=root;PWD=root; DATABASE=cccddd_odbc;Charset=utf8; SslMode=none;Min Pool Size=1 | +| DataType.OdbcSqlServer | Driver={SQL Server};Server=.;Persist Security Info=False; Trusted_Connection=Yes;Integrated Security=True; DATABASE=freesqlTest_odbc; Pooling=true;Min Pool Size=1 | +| DataType.OdbcOracle | Driver={Oracle in XE};Server=//127.0.0.1:1521/XE; Persist Security Info=False; Trusted_Connection=Yes;UID=odbc1;PWD=123456; Min Pool Size=1 | +| DataType.OdbcPostgreSQL | Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10; Port=5432;UID=postgres;PWD=123456; Database=tedb_odbc;Pooling=true;Min Pool Size=1 | +| DataType.Odbc | Driver={SQL Server};Server=.;Persist Security Info=False; Trusted_Connection=Yes;Integrated Security=True; DATABASE=freesqlTest_odbc; Pooling=true;Min pool size=1 |

From 05cf13f560982ee44bf91bb4db41b78715e84929 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Dec 2019 20:10:39 +0800 Subject: [PATCH 0297/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20GlobalFilter?= =?UTF-8?q?=20Apply=20=E8=87=AA=E5=8A=A8=E9=87=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=8F=82=E6=95=B0=E5=90=8D=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=86=85=E5=AE=B9=E9=87=8D=E5=A4=8D=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20Guid.NewGuid()=20?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 49 ------------------- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 24 +++++++++ FreeSql/Internal/CommonExpression.cs | 2 +- FreeSql/Internal/GlobalFilter.cs | 8 ++- .../FreeSql.Provider.MySql/MySqlExpression.cs | 12 ++--- .../Default/OdbcExpression.cs | 12 ++--- .../MySql/OdbcMySqlExpression.cs | 12 ++--- .../Oracle/OdbcOracleExpression.cs | 12 ++--- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 10 ++-- .../SqlServer/OdbcSqlServerExpression.cs | 12 ++--- .../OracleExpression.cs | 12 ++--- .../PostgreSQLExpression.cs | 10 ++-- .../SqlServerExpression.cs | 12 ++--- .../SqliteExpression.cs | 12 ++--- 14 files changed, 90 insertions(+), 109 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 7fce6993..5b80bfb0 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -464,54 +464,5 @@ 部门对象 - -

- 入学年份 - - - - - 学段 - - - - - 人数 - - - - - - - - - - - - - - - - - - - - - 待标注 - - - - - 合格 - - - - - 不合格 - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 3426816e..22d54a76 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -200,9 +200,33 @@ namespace FreeSql.Tests public string Name { get; set; } } + public class gf_t1 + { + public Guid id { get; set; } + public int rowstate { get; set; } + } + public class gf_t2 + { + public Guid id { get; set; } + public decimal rowstate { get; set; } + } + public class gf_t3 + { + public Guid id { get; set; } + public decimal rowstate { get; set; } + } + [Fact] public void Test02() { + g.mysql.GlobalFilter.Apply("gft1", a => a.rowstate > -1) + .Apply("gft2", a => a.rowstate > -2) + .Apply("gft3", a => a.rowstate > -3); + + var gft1 = g.mysql.Select().Where(a => a.id == Guid.NewGuid()).ToList(); + var gft2 = g.mysql.Select().Where(a => a.id == Guid.NewGuid()).ToList(); + var gft3 = g.mysql.Select().Where(a => a.id == Guid.NewGuid()).ToList(); + var tekset = g.sqlite.Select().IncludeMany(a => a.departments).ToList(); g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index d767c504..b4324998 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1335,7 +1335,7 @@ namespace FreeSql.Internal } return null; } - class ReplaceVisitor : ExpressionVisitor + internal class ReplaceVisitor : ExpressionVisitor { private ParameterExpression parameter; public Expression Modify(Expression expression, ParameterExpression parameter) diff --git a/FreeSql/Internal/GlobalFilter.cs b/FreeSql/Internal/GlobalFilter.cs index 40bab709..01992c9f 100644 --- a/FreeSql/Internal/GlobalFilter.cs +++ b/FreeSql/Internal/GlobalFilter.cs @@ -32,7 +32,13 @@ namespace FreeSql.Internal _filters.TryGetValue(name, out var item); if (item == null) item = new Item { Id = ++_id, Name = name }; - item.Where = where; + + var newParameter = Expression.Parameter(typeof(TEntity), $"gf{_id}"); + var newlambda = Expression.Lambda>( + new CommonExpression.ReplaceVisitor().Modify(where.Body, newParameter), + newParameter + ); + item.Where = newlambda; _filters.AddOrUpdate(name, item, (_, __) => item); return this; } diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 36477266..8df2fa3b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -70,21 +70,21 @@ namespace FreeSql.MySql case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)"; } - break; + return null; case "NewGuid": - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "rand()"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs index e734dfd0..fba05ba0 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -73,25 +73,25 @@ namespace FreeSql.Odbc.Default case "System.UInt64": return _utils.Adapter.LambdaConvert_ToUInt64(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); case "System.Guid": return _utils.Adapter.LambdaConvert_ToGuid(callExp.Method.DeclaringType, getExp(callExp.Arguments[0])); } - break; + return null; case "NewGuid": switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { case "System.Guid": return _utils.Adapter.LambdaGuid_NewGuid; } - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return _utils.Adapter.LambdaRandom_Next; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return _utils.Adapter.LambdaRandom_NextDouble; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return _utils.Adapter.LambdaRandom_NextDouble; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? _utils.Adapter.LambdaConvert_ToString(callExp.Object.Type, getExp(callExp.Object)) : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 7388e72a..5201379c 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -70,21 +70,21 @@ namespace FreeSql.Odbc.MySql case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)"; } - break; + return null; case "NewGuid": - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "rand()"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index da39f52d..dbb94fdd 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -70,21 +70,21 @@ namespace FreeSql.Odbc.Oracle case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; } - break; + return null; case "NewGuid": - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"to_char({getExp(callExp.Object)})" : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index b9a0b56e..3d593394 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -76,19 +76,19 @@ namespace FreeSql.Odbc.PostgreSQL } break; case "NewGuid": - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "random()"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 41e40119..e44aa42d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -70,25 +70,25 @@ namespace FreeSql.Odbc.SqlServer case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; case "System.Guid": return $"cast({getExp(callExp.Arguments[0])} as uniqueidentifier)"; } - break; + return null; case "NewGuid": switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { case "System.Guid": return $"newid()"; } - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as int)"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "rand()"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 7dbc44e7..4642c1c1 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -70,21 +70,21 @@ namespace FreeSql.Oracle case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; } - break; + return null; case "NewGuid": - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"to_char({getExp(callExp.Object)})" : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 7996dca4..c4845638 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -77,19 +77,19 @@ namespace FreeSql.PostgreSQL } break; case "NewGuid": - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "random()"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index d8f61bc3..58e9c669 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -70,25 +70,25 @@ namespace FreeSql.SqlServer case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; case "System.Guid": return $"cast({getExp(callExp.Arguments[0])} as uniqueidentifier)"; } - break; + return null; case "NewGuid": switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { case "System.Guid": return $"newid()"; } - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as int)"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "rand()"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null; - break; + return null; } var objExp = callExp.Object; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 68f8cea6..81108e95 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -70,21 +70,21 @@ namespace FreeSql.Sqlite case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as decimal(21,0))"; case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as character), 1, 36)"; } - break; + return null; case "NewGuid": - break; + return null; case "Next": if (callExp.Object?.Type == typeof(Random)) return "cast(random()*1000000000 as int)"; - break; + return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "random()"; - break; + return null; case "Random": if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; - break; + return null; case "ToString": if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as character)" : null; - break; + return null; } var objExp = callExp.Object; From 5984292043180eb85c863b85f0809c46adb97ee4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Dec 2019 21:23:29 +0800 Subject: [PATCH 0298/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20MaxLength=20?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=B9=B6=E4=B8=94=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20[Column(StringLength=20=3D=20100)]=20=E5=90=8C=E7=AD=89?= =?UTF-8?q?=E7=9A=84=E7=89=B9=E6=80=A7=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ---- FreeSql/DataAnnotations/ColumnAttribute.cs | 23 +++++++++++- FreeSql/DataAnnotations/ColumnFluent.cs | 23 ++++++++++++ FreeSql/FreeSql.xml | 41 +++++++++++++++++++++- FreeSql/FreeSqlBuilder.cs | 29 ++------------- FreeSql/Internal/CommonUtils.cs | 3 ++ FreeSql/Internal/UtilsExpressionTree.cs | 32 +++++++++++++++++ 7 files changed, 122 insertions(+), 36 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index b7cc6faf..8eb5eb1e 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -17,7 +17,7 @@ namespace FreeSql.DataAnnotations public string OldName { get; set; } /// /// 数据库类型,如: varchar(255) - /// 字符串长度,可使用特性 MaxLength(255) + /// 字符串长度,可使用特性 [MaxLength(255)] /// public string DbType { get; set; } @@ -76,5 +76,26 @@ namespace FreeSql.DataAnnotations /// 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 /// public DateTimeKind ServerTime { get; set; } + + internal int? _StringLength; + /// + /// 设置长度,针对 string 类型避免 DbType 的繁琐设置 + /// 提示:也可以使用 [MaxLength(100)] + /// --- + /// StringLength = 100 时,对应 DbType: + /// MySql -> varchar(100) + /// SqlServer -> nvarchar(100) + /// PostgreSQL -> varchar(100) + /// Oracle -> nvarchar2(100) + /// Sqlite -> nvarchar(100) + /// --- + /// StringLength = -1 时,对应 DbType: + /// MySql -> text + /// SqlServer -> nvarchar(max) + /// PostgreSQL -> text + /// Oracle -> nvarchar2(4000) + /// Sqlite -> text + /// + public int StringLength { get => _StringLength ?? 0; set => _StringLength = value; } } } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index f98d6ffc..e5d6e13c 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -135,5 +135,28 @@ namespace FreeSql.DataAnnotations _column.ServerTime = value; return this; } + + /// + /// 设置长度,针对 string 类型避免 DbType 的繁琐设置 + /// --- + /// StringLength = 100 时,对应 DbType: + /// MySql -> varchar(100) + /// SqlServer -> nvarchar(100) + /// PostgreSQL -> varchar(100) + /// Oracle -> nvarchar2(100) + /// Sqlite -> nvarchar(100) + /// --- + /// StringLength = -1 时,对应 DbType: + /// MySql -> text + /// SqlServer -> nvarchar(max) + /// PostgreSQL -> text + /// Oracle -> nvarchar2(4000) + /// Sqlite -> text + /// + public ColumnFluent StringLength(int value) + { + _column.StringLength = value; + return this; + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 768d92dd..3408d4bb 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -17,7 +17,7 @@ 数据库类型,如: varchar(255) - 字符串长度,可使用特性 MaxLength(255) + 字符串长度,可使用特性 [MaxLength(255)] @@ -78,6 +78,26 @@ 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + 提示:也可以使用 [MaxLength(100)] + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + 数据库列名 @@ -159,6 +179,25 @@ + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + 自定义表达式函数解析 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index fef4b9b6..b0fb53be 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -263,34 +263,9 @@ namespace FreeSql if (maxlenAttr != null) { var lenProp = maxlenAttr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).FirstOrDefault(); - if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval)) + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval) && tryval != 0) { - if (tryval != 0) - { - switch (ret.Ado.DataType) - { - case DataType.MySql: - case DataType.OdbcMySql: - e.ModifyResult.DbType = tryval > 0 ? $"varchar({tryval})" : "text"; - break; - case DataType.SqlServer: - case DataType.OdbcSqlServer: - e.ModifyResult.DbType = tryval > 0 ? $"nvarchar({tryval})" : "nvarchar(max)"; - break; - case DataType.PostgreSQL: - case DataType.OdbcPostgreSQL: - e.ModifyResult.DbType = tryval > 0 ? $"varchar({tryval})" : "text"; - break; - case DataType.Oracle: - case DataType.OdbcOracle: - e.ModifyResult.DbType = tryval > 0 ? $"nvarchar2({tryval})" : "nvarchar2(4000)"; - break; - case DataType.Sqlite: - e.ModifyResult.DbType = tryval > 0 ? $"nvarchar({tryval})" : "text"; - break; - - } - } + e.ModifyResult.StringLength = tryval; } } }); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index c533af4e..a2f8d3f0 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -129,6 +129,7 @@ namespace FreeSql.Internal if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert; if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate; if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime; + if (trycol._StringLength != null) attr.StringLength = trycol.StringLength; } var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); foreach (var tryattrobj in attrs) @@ -148,6 +149,7 @@ namespace FreeSql.Internal if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert; if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate; if (tryattr.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = tryattr.ServerTime; + if (tryattr._StringLength != null) attr.StringLength = tryattr.StringLength; } ColumnAttribute ret = null; if (!string.IsNullOrEmpty(attr.Name)) ret = attr; @@ -163,6 +165,7 @@ namespace FreeSql.Internal if (attr._CanInsert != null) ret = attr; if (attr._CanUpdate != null) ret = attr; if (attr.ServerTime != DateTimeKind.Unspecified) ret = attr; + if (attr._StringLength != null) ret = attr; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index f175d6ae..ee954eaa 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -194,6 +194,38 @@ namespace FreeSql.Internal col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; } + if (colattr.MapType == typeof(string) && colattr.StringLength != 0) + { + int strlen = colattr.StringLength; + var charPatten = @"(CHAR|CHAR2|CHARACTER)\s*(\([^\)]*\))?"; + switch (common._orm.Ado.DataType) + { + case DataType.MySql: + case DataType.OdbcMySql: + if (strlen < 0) colattr.DbType = "text"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.SqlServer: + case DataType.OdbcSqlServer: + if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(MAX)"); + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: + if (strlen < 0) colattr.DbType = "text"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.Oracle: + case DataType.OdbcOracle: + if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(4000)"); + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.Sqlite: + if (strlen < 0) colattr.DbType = "text"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + } + } if (trytb.Columns.ContainsKey(colattr.Name)) throw new Exception($"ColumnAttribute.Name {colattr.Name} 重复存在,请检查(注意:不区分大小写)"); if (trytb.ColumnsByCs.ContainsKey(p.Name)) throw new Exception($"属性名 {p.Name} 重复存在,请检查(注意:不区分大小写)"); From dbdcec3a6f4623f640cbd2fb62b5be836eb7c6e9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Dec 2019 21:27:01 +0800 Subject: [PATCH 0299/1029] ## v0.12.8 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index efae155f..2f22aacc 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.7 + 0.12.8 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 6d49e43d..8a9489a6 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 938a8f97..0832b441 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 548b5c4d..29d68e01 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 9d354ac0..e8e41e2a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.7 + 0.12.8 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7a7272ec..e41d4ff7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 4764fa60..6a88a874 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 23e18466..4a8f8c6e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 793e5c48..0bb25692 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d405a960..924ca3c7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 97083088..9ac363d4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 01ed040b..4dfa0b97 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 40ca49c2..3c8469c8 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.7 + 0.12.8 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From e59608a6c82dc134d2ebe5e2ee5951ee0e8fc6e3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Dec 2019 18:18:38 +0800 Subject: [PATCH 0300/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20DateTime=20?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=20Between=20=E5=92=8C=20Be?= =?UTF-8?q?tweenEnd=20=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20Dto=20=E6=98=A0?= =?UTF-8?q?=E5=B0=84=EF=BC=8C=E5=9C=A8=E4=BA=8C=E7=BA=A7=E5=8D=B3=20Dto=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E4=B8=8A=E5=8F=88=20new=20Dto=20=E7=9A=84?= =?UTF-8?q?=E6=97=B6=E5=80=99=EF=BC=8C=E9=94=99=E8=AF=AF=E7=9A=84=E5=8F=88?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=98=A0=E5=B0=84=E4=BA=86=E5=85=A8=E9=83=A8?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 6 +++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 48 +++++++++++++++++-- FreeSql/Internal/CommonExpression.cs | 18 +++---- .../SelectProvider/Select0Provider.cs | 8 ++-- .../SelectProvider/SelectGroupingProvider.cs | 6 +-- 6 files changed, 66 insertions(+), 27 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 22d54a76..758c9ecb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -219,6 +219,12 @@ namespace FreeSql.Tests [Fact] public void Test02() { + var start = DateTime.Now.Date; + var end = DateTime.Now.AddDays(1).Date.AddMilliseconds(-1); + var textbetween = g.sqlite.Select() + .Where(a => a.ct1.Between(start, end)) + .ToList(); + g.mysql.GlobalFilter.Apply("gft1", a => a.rowstate > -1) .Apply("gft2", a => a.rowstate > -2) .Apply("gft3", a => a.rowstate > -3); diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 29b0c08f..97ed7c97 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -1,4 +1,5 @@ using FreeSql; +using FreeSql.DataAnnotations; using System; using System.Collections; using System.Collections.Concurrent; @@ -9,6 +10,7 @@ using System.Drawing; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Threading; public static partial class FreeSqlGlobalExtensions { @@ -102,10 +104,7 @@ public static partial class FreeSqlGlobalExtensions var desc = item.GetType().GetField(name)?.GetCustomAttributes(typeof(DescriptionAttribute), false)?.FirstOrDefault() as DescriptionAttribute; return desc?.Description ?? name; } - public static long ToInt64(this Enum item) - { - return Convert.ToInt64(item); - } + public static long ToInt64(this Enum item) => Convert.ToInt64(item); public static IEnumerable ToSet(this long value) { var ret = new List(); @@ -222,4 +221,45 @@ public static partial class FreeSqlGlobalExtensions } #endif #endregion + + #region LambdaExpression + + public static ThreadLocal expContext = new ThreadLocal(); + + /// + /// C#: that >= between && that <= and + /// SQL: that BETWEEN between AND and + /// + /// + /// + /// + /// + [ExpressionCall] + public static bool Between(this DateTime that, DateTime between, DateTime and) + { + if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) + return that >= between && that <= and; + expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} between {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["end"]}"; + return false; + } + + /// + /// 注意:这个方法和 Between 有细微区别 + /// C#: that >= start && that < end + /// SQL: that >= start and that < end + /// + /// + /// + /// + /// + [ExpressionCall] + public static bool BetweenEnd(this DateTime that, DateTime start, DateTime end) + { + if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) + return that >= start && that < end; + expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} >= {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["that"]} < {expContext.Value.ParsedContent["end"]}"; + return false; + } + + #endregion } \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b4324998..23156372 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -25,20 +25,20 @@ namespace FreeSql.Internal _common = common; } - public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression) + public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression, bool isAllDtoMap) { Func getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; switch (exp.NodeType) { - case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression); - case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString, whereCascadeExpression); + case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); + case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Negate: case ExpressionType.NegateChecked: parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); return false; - case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression); + case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Constant: var constExp = exp as ConstantExpression; //处理自定义SQL语句,如: ToList(new { @@ -110,7 +110,7 @@ namespace FreeSql.Internal parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0]; parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - if (_tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) + if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) { //dto 映射 var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values; @@ -129,7 +129,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -156,7 +156,7 @@ namespace FreeSql.Internal MapType = initAssignExp.Expression.Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString, whereCascadeExpression); + ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString, whereCascadeExpression, false); } } if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); @@ -177,7 +177,7 @@ namespace FreeSql.Internal MapType = newExp.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString, whereCascadeExpression); + ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString, whereCascadeExpression, false); } } else @@ -200,7 +200,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 0c7aa3c2..31cc450d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -530,7 +530,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true); return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); } static ConcurrentDictionary _dicConstructor = new ConcurrentDictionary(); @@ -1003,7 +1003,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression, true); this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null); return new SelectGroupingProvider(this, map, _commonExpression, _tables); } @@ -1061,7 +1061,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, true); return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } @@ -1291,7 +1291,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, true); return (await this.ToListMapReaderAsync((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); } #endif diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 0e402bd1..78ac4bcc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -112,7 +112,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; @@ -126,7 +126,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; } @@ -170,7 +170,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; From e7bb95ef6d0d7940ab7289a99149b55e1bb8cb62 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Dec 2019 18:57:07 +0800 Subject: [PATCH 0301/1029] ## v0.12.9 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 24 +++++++++++++++++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 21 ++++++++++++++++ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 59 insertions(+), 14 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2f22aacc..40fb1d95 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.8 + 0.12.9 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 8a9489a6..17052c8d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0832b441..80eafc2d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 29d68e01..d25919a0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e8e41e2a..d5dfe010 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.8 + 0.12.9 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 758c9ecb..f8051a84 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -216,15 +216,39 @@ namespace FreeSql.Tests public decimal rowstate { get; set; } } + public class gfDto + { + public int rowstate { get; set; } + public dfDto2 dto2 { get; set; } + } + public class dfDto2 + { + public int id { get; set; } + public decimal rowstate { get; set; } + } + [Fact] public void Test02() { + var dtot2 = g.sqlite.Select().ToList(a => new gfDto + { + dto2 = new dfDto2 + { + rowstate = a.rowstate + } + }); + + var start = DateTime.Now.Date; var end = DateTime.Now.AddDays(1).Date.AddMilliseconds(-1); var textbetween = g.sqlite.Select() .Where(a => a.ct1.Between(start, end)) .ToList(); + var textbetweenend = g.sqlite.Select() + .Where(a => a.ct1.BetweenEnd(start, end)) + .ToList(); + g.mysql.GlobalFilter.Apply("gft1", a => a.rowstate > -1) .Apply("gft2", a => a.rowstate > -2) .Apply("gft3", a => a.rowstate > -3); diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 97ed7c97..4012ad7f 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -239,7 +239,7 @@ public static partial class FreeSqlGlobalExtensions { if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) return that >= between && that <= and; - expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} between {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["end"]}"; + expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} between {expContext.Value.ParsedContent["between"]} and {expContext.Value.ParsedContent["and"]}"; return false; } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e41d4ff7..fae92288 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3408d4bb..1a6f3cd5 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2763,6 +2763,27 @@ 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + + + + 使用 and 拼接两个 lambda 表达式 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6a88a874..fc6a2141 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4a8f8c6e..f68ebbe6 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0bb25692..c75a3cea 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 924ca3c7..7dcec730 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 9ac363d4..38be7f21 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4dfa0b97..0e529fb8 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 3c8469c8..9a5dda02 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.8 + 0.12.9 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 04d8b40f0b0cf5e004cf29668cd58e63bcdd0a17 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Dec 2019 20:20:38 +0800 Subject: [PATCH 0302/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=A4=9A?= =?UTF-8?q?=E8=A1=A8=E6=9F=A5=E8=AF=A2=20WhereCascade=EF=BC=8C=E5=A6=82?= =?UTF-8?q?=E6=9E=9C=20Join=20=E6=B2=A1=E6=9C=89=20On=20=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E5=8F=AF=E8=83=BD=E5=AF=BC=E8=87=B4=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=9A=84=20SQL=20=E5=A4=9A=E4=BA=86=E4=B8=80=E4=B8=AA=20AND=20?= =?UTF-8?q?=E5=87=BA=E9=94=99=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ .../FreeSql.Provider.MySql/Curd/MySqlSelect.cs | 9 +++++++-- .../Default/Curd/OdbcSelect.cs | 9 +++++++-- .../MySql/Curd/OdbcMySqlSelect.cs | 9 +++++++-- .../Oracle/Curd/OdbcOracleSelect.cs | 9 +++++++-- .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 9 +++++++-- .../SqlServer/Curd/OdbcSqlServerSelect.cs | 18 ++++++++++++++---- .../Curd/OracleSelect.cs | 9 +++++++-- .../Curd/PostgreSQLSelect.cs | 9 +++++++-- .../Curd/SqlServerSelect.cs | 18 ++++++++++++++---- .../Curd/SqliteSelect.cs | 9 +++++++-- 11 files changed, 91 insertions(+), 24 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index d745db6d..a40c0d56 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -48,8 +48,13 @@ namespace FreeSql.MySql.Curd if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index bc1895ed..b3f0fb59 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -62,8 +62,13 @@ namespace FreeSql.Odbc.Default if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index 430e812f..f013109b 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -48,8 +48,13 @@ namespace FreeSql.Odbc.MySql if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index 1e93f77c..83b9f7ca 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -50,8 +50,13 @@ namespace FreeSql.Odbc.Oracle if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 043feeda..9849d492 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -48,8 +48,13 @@ namespace FreeSql.Odbc.PostgreSQL if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index fa840a15..56b61970 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -66,8 +66,13 @@ namespace FreeSql.Odbc.SqlServer if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; @@ -166,8 +171,13 @@ namespace FreeSql.Odbc.SqlServer if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 290dc859..b2349ef0 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -50,8 +50,13 @@ namespace FreeSql.Oracle.Curd if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 1e8faf08..928d91c6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -48,8 +48,13 @@ namespace FreeSql.PostgreSQL.Curd if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 3eacc1e5..c3518557 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -66,8 +66,13 @@ namespace FreeSql.SqlServer.Curd if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; @@ -166,8 +171,13 @@ namespace FreeSql.SqlServer.Curd if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index dc65ab68..ba3af794 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -48,8 +48,13 @@ namespace FreeSql.Sqlite.Curd if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); else { - sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } } } break; From c942811548e1e1156a7da7bbf69d96b3524c9789 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Dec 2019 20:27:11 +0800 Subject: [PATCH 0303/1029] =?UTF-8?q?-=20=E5=A4=9A=E8=A1=A8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=20WhereCascade=20bug=20=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index f8051a84..50e45747 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -230,6 +230,20 @@ namespace FreeSql.Tests [Fact] public void Test02() { + g.sqlite.GlobalFilter.Apply("gft1", a => a.rowstate > -1) + .Apply("gft2", a => a.rowstate > -2) + .Apply("gft3", a => a.rowstate > -3); + + var tksk1 = g.sqlite.Select() + .InnerJoin((a, b, c) => a.id == b.id) + .Where((a, b, c) => c.rowstate > 10) + .ToList(); + + var tksk2 = g.sqlite.Select() + .InnerJoin((a, b, c) => a.id == b.id) + .Where((a, b, c) => c.rowstate > 10) + .ToList(); + var dtot2 = g.sqlite.Select().ToList(a => new gfDto { dto2 = new dfDto2 From 011cc8d0d8475606fda8c856a20cc4715e6cae8a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 8 Dec 2019 00:03:35 +0800 Subject: [PATCH 0304/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20RawValueAttr?= =?UTF-8?q?ibute=20=E5=AE=9E=E7=8E=B0=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E6=97=B6=EF=BC=8C=E4=BD=BF=E7=94=A8=E5=8E=9F?= =?UTF-8?q?=E5=A7=8B=E5=80=BC=E4=BC=A0=E5=85=A5=E5=8F=82=E6=95=B0=EF=BC=9B?= =?UTF-8?q?=20-=20=E5=A2=9E=E5=8A=A0=20IEnumerable<(T1,=20T2)>.ContainsMan?= =?UTF-8?q?y=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=EF=BC=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=A4=9A=E5=88=97=E6=97=A0=E6=B3=95=20IN=20?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 -- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 8 ++ .../ExpressionCallAttribute.cs | 12 +++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 80 +++++++++++++++++++ FreeSql/FreeSql.xml | 44 ++++++++++ FreeSql/Internal/CommonExpression.cs | 17 ++-- 6 files changed, 154 insertions(+), 14 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 50e45747..feb4a6c3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -252,6 +252,14 @@ namespace FreeSql.Tests } }); + List<(Guid, DateTime)> contains2linqarr = new List<(Guid, DateTime)>(); + Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains2linqarr.ContainsMany(a.Id, a.ct1)).ToSql(a => 1).Replace("\r\n", "")); + g.sqlite.Select().Where(a => contains2linqarr.ContainsMany(a.Id, a.ct1)).ToList(); + + contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); + contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); + contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); + g.sqlite.Select().Where(a => contains2linqarr.ContainsMany(a.Id, a.ct1)).ToList(); var start = DateTime.Now.Date; var end = DateTime.Now.AddDays(1).Date.AddMilliseconds(-1); diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs index c9c964e9..4342ff13 100644 --- a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs +++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs @@ -13,6 +13,13 @@ namespace FreeSql.DataAnnotations public class ExpressionCallAttribute : Attribute { } + /// + /// 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 + /// + [AttributeUsage(AttributeTargets.Parameter)] + public class RawValueAttribute : Attribute + { + } public class ExpressionCallContext { @@ -37,6 +44,11 @@ namespace FreeSql.DataAnnotations /// public List UserParameters { get; internal set; } + /// + /// 将 c# 对象转换为 SQL + /// + public Func FormatSql { get; internal set; } + /// /// 返回表达式函数表示的 SQL 字符串 /// diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 4012ad7f..80e588fd 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -10,6 +10,7 @@ using System.Drawing; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Text; using System.Threading; public static partial class FreeSqlGlobalExtensions @@ -261,5 +262,84 @@ public static partial class FreeSqlGlobalExtensions return false; } + /// + /// C#:从元组集合中查找 exp1, exp2 是否存在 + /// SQL: + /// exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + /// exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + /// ... + /// 注意:当 that 为 null 或 empty 时,返回 1=0 + /// + /// + /// + /// + /// + /// + /// + [ExpressionCall] + public static bool ContainsMany([RawValue] this IEnumerable<(T1, T2)> that, T1 exp1, T2 exp2) + { + if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) + return that?.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2)) == true; + if (that?.Any() != true) + { + expContext.Value.Result = "1=0"; + return false; + } + var sb = new StringBuilder(); + var idx = 0; + foreach (var item in that) + { + if (idx++ > 0) sb.Append(" OR \r\n"); + sb + .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) + .Append(" AND ") + .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))); + } + expContext.Value.Result = sb.ToString(); + return true; + } + /// + /// C#:从元组集合中查找 exp1, exp2 是否存在 + /// SQL: + /// exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR + /// exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + /// ... + /// 注意:当 that 为 null 或 empty 时,返回 1=0 + /// + /// + /// + /// + /// + /// + /// + /// + /// + [ExpressionCall] + public static bool ContainsMany([RawValue] this IEnumerable<(T1, T2, T3)> that, T1 exp1, T2 exp2, T3 exp3) + { + if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) + return that.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2) && a.Item3.Equals(exp3)); + if (that.Any() == false) + { + expContext.Value.Result = "1=0"; + return false; + } + var sb = new StringBuilder(); + var idx = 0; + foreach (var item in that) + { + if (idx++ > 0) sb.Append(" OR \r\n"); + sb + .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) + .Append(" AND ") + .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))) + .Append(" AND ") + .Append(expContext.Value.ParsedContent["exp3"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T3), item.Item3))); + } + expContext.Value.Result = sb.ToString(); + return true; + } + #endregion } \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1a6f3cd5..cda36dcd 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -204,6 +204,11 @@ 注意:请使用静态方法、或者在类上标记 + + + 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 + + 数据库类型,可用于适配多种数据库环境 @@ -225,6 +230,11 @@ 注意:本属性只有 Where 的表达式解析才可用 + + + 将 c# 对象转换为 SQL + + 返回表达式函数表示的 SQL 字符串 @@ -2784,6 +2794,40 @@ + + + C#:从元组集合中查找 exp1, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + + C#:从元组集合中查找 exp1, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + 使用 and 拼接两个 lambda 表达式 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 23156372..b8fdfa9c 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -553,15 +553,15 @@ namespace FreeSql.Internal exp3.Method.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any() )) { - var ecc = new ExpressionCallContext { DataType = _ado.DataType, UserParameters = tsc.dbParams == null ? null : new List() }; + var ecc = new ExpressionCallContext { DataType = _ado.DataType, UserParameters = tsc.dbParams == null ? null : new List(), FormatSql = obj => formatSql(obj, null, null, null) }; var exp3MethodParams = exp3.Method.GetParameters(); var dbParamsIndex = tsc.dbParams?.Count; - ecc.ParsedContent.Add(exp3MethodParams[0].Name, ExpressionLambdaToSql(exp3.Arguments[0], tsc)); + ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null: ExpressionLambdaToSql(exp3.Arguments[0], tsc)); if (tsc.dbParams?.Count > dbParamsIndex) ecc.DbParameter = tsc.dbParams.Last(); List oldDbParams = tsc.SetDbParamsReturnOld(null); for (var a = 1; a < exp3.Arguments.Count; a++) if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) - ecc.ParsedContent.Add(exp3MethodParams[a].Name, ExpressionLambdaToSql(exp3.Arguments[a], tsc)); + ecc.ParsedContent.Add(exp3MethodParams[a].Name, exp3MethodParams[a].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[a], tsc)); tsc.SetDbParamsReturnOld(oldDbParams); var exp3InvokeParams = new object[exp3.Arguments.Count]; @@ -570,10 +570,13 @@ namespace FreeSql.Internal if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) { var eccContent = ecc.ParsedContent[exp3MethodParams[a].Name]; - exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, - eccContent.StartsWith("N'") ? - eccContent.Substring(1).Trim('\'').Replace("''", "'") : - eccContent.Trim('\'').Replace("''", "'"));// exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); + if (eccContent == null) + exp3InvokeParams[a] = Expression.Lambda(exp3.Arguments[a]).Compile().DynamicInvoke(); + else + exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, + eccContent.StartsWith("N'") ? + eccContent.Substring(1).Trim('\'').Replace("''", "'") : + eccContent.Trim('\'').Replace("''", "'"));// exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); } else exp3InvokeParams[a] = ecc; From 5d4e7bb407498c8b084b5d854f8e36f85030ad9a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 8 Dec 2019 00:44:36 +0800 Subject: [PATCH 0305/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20SaveMany=20?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E4=BF=9D=E5=AD=98=E5=88=97=E5=90=8D=E6=89=BE?= =?UTF-8?q?=E4=B8=8D=E5=88=B0=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetAsync.cs | 2 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 152 ++++++++-- .../Other/kwlib/department_employee.cs | 20 -- .../Other/kwlib/department_userinfo.cs | 22 ++ .../kwlib/{department.cs => departments.cs} | 32 +- .../Other/kwlib/{employee.cs => userinfo1.cs} | 273 ++++++++++-------- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 13 +- 9 files changed, 335 insertions(+), 188 deletions(-) delete mode 100644 FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_employee.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_userinfo.cs rename FreeSql.Tests/FreeSql.Tests/Other/kwlib/{department.cs => departments.cs} (64%) rename FreeSql.Tests/FreeSql.Tests/Other/kwlib/{employee.cs => userinfo1.cs} (50%) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 5863b766..e4fbc75d 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -271,7 +271,7 @@ namespace FreeSql } for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) { - var refcol = tref.Columns[midcolidx - tref.Columns.Count]; + var refcol = tref.RefColumns[midcolidx - tref.Columns.Count]; var refval = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[midcolidx].CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curItem, refcol.CsName)); _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[midcolidx].CsName, refval); } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 4f7f2701..c2bbbbbd 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -283,7 +283,7 @@ namespace FreeSql } for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) { - var refcol = tref.Columns[midcolidx - tref.Columns.Count]; + var refcol = tref.RefColumns[midcolidx - tref.Columns.Count]; var refval = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[midcolidx].CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curItem, refcol.CsName)); _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[midcolidx].CsName, refval); } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 5b80bfb0..d6732b50 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -389,80 +389,170 @@ 验证标志 - + 部门表 - + 部门ID - - - 员工列表 对应employee.deptid - - - + 上级部门ID - + 上级部门对象 - + 部门主管ID - + 部门主管对象 - - - 下级部门列表 - - - + 部门代码 - + 部门名称 - + 员工表 - + 员工ID - + + + 考勤号码 + + + + + 编号 + + + + + 身份证 + + + + + 姓名 + + + + + 职务 + + + + + 生日 + + + + + 入职时间 + + + + + 合同日期 + + + + + 家庭地址 + + + + + 邮编 + + + + + 办公电话 + + + + + 行动电话 + + + + + 家庭电话 + + + + + 卡号 + + + + + 邮件地址 + + + + + 身份证有效期 + + + + + 籍贯 + + + + + 民族 + + + + + 离职日期 + + + + + 登录密码 + + + + + 相片地址 + + + + + 上级主管ID + + + 上级主管对象 - - - 下级员工列表 - - - - - 部门对象 - - diff --git a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_employee.cs b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_employee.cs deleted file mode 100644 index 8c20b8e1..00000000 --- a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_employee.cs +++ /dev/null @@ -1,20 +0,0 @@ -using FreeSql.DataAnnotations; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace kwlib -{ - public class department_employee - { - public int departmentId { get; set; } - public int employeeId { get; set; } - - [Navigate("departmentId")] - public department dept { get; set; } - [Navigate("employeeId")] - public employee empe { get; set; } - } -} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_userinfo.cs b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_userinfo.cs new file mode 100644 index 00000000..8baea7f0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department_userinfo.cs @@ -0,0 +1,22 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace kwlib +{ + public class department_userinfo + { + public int departmentsId { get; set; } + public int userinfoId { get; set; } + + [Navigate("departmentsId")] + public departments dept { get; set; } + + + [Navigate("userinfoId")] + public userinfo emp { get; set; } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department.cs b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/departments.cs similarity index 64% rename from FreeSql.Tests/FreeSql.Tests/Other/kwlib/department.cs rename to FreeSql.Tests/FreeSql.Tests/Other/kwlib/departments.cs index 1f3a5ccf..10475cc2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/department.cs +++ b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/departments.cs @@ -13,19 +13,19 @@ namespace kwlib /// [Serializable] [Index("部门代码deptcode唯一", "deptcode", true)] - public class department + public class departments { /// /// 部门ID /// [Column(IsPrimary = true, IsIdentity = true)] - public int id { get; set; } + public int deptid { get; set; } - /// - /// 员工列表 对应employee.deptid - /// - [Navigate("deptid")] - public List Employees { get; set; } + ///// + ///// 员工列表 对应employee.deptid + ///// + //[Navigate("deptid")] + //public List Employees { get; set; } /// /// 上级部门ID @@ -35,7 +35,7 @@ namespace kwlib /// 上级部门对象 /// [Navigate("supdeptid")] - public department parentdepartments { get; set; } + public departments pDepartments { get; set; } /// /// 部门主管ID @@ -45,18 +45,18 @@ namespace kwlib /// 部门主管对象 /// [Navigate("managerid")] - public employee manager { get; set; } + public userinfo manager { get; set; } - /// - /// 下级部门列表 - /// - [Navigate("supdeptid")] - public List childDepartments { get; set; } + ///// + ///// 下级部门列表 + ///// + //[Navigate("supdeptid")] + //public List childDepartments { get; set; } - [Navigate(ManyToMany = typeof(department_employee))] - public List employees22 { get; set; } + [Navigate(ManyToMany = typeof(department_userinfo))] + public List employeesMany { get; set; } #region MyRegion diff --git a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/employee.cs b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/userinfo1.cs similarity index 50% rename from FreeSql.Tests/FreeSql.Tests/Other/kwlib/employee.cs rename to FreeSql.Tests/FreeSql.Tests/Other/kwlib/userinfo1.cs index 9b292e89..7f7dcbe1 100644 --- a/FreeSql.Tests/FreeSql.Tests/Other/kwlib/employee.cs +++ b/FreeSql.Tests/FreeSql.Tests/Other/kwlib/userinfo1.cs @@ -11,151 +11,190 @@ namespace kwlib /// 员工表 /// [Serializable] - [Index("员工代码empcode唯一", "empcode", true)] - public class employee + [Index("员工代码badgenumber唯一", "badgenumber", true)] + public class userinfo { - - /// /// 员工ID /// [Column(IsPrimary = true, IsIdentity = true)] [System.ComponentModel.DisplayName("员工ID ")] - public int id { get; set; } + public int userid { get; set; } + + /// + /// 考勤号码 + /// + [System.ComponentModel.DisplayName("考勤号码")] + public String badgenumber { get; set; } + + + /// + /// 编号 + /// + [System.ComponentModel.DisplayName("编号")] + + public string ssn { get; set; } + + /// + /// 身份证 + /// + [System.ComponentModel.DisplayName("身份证/证件号")] + public String IDCardNo { get; set; } + + /// + /// 姓名 + /// + [System.ComponentModel.DisplayName("姓名")] + public String name { get; set; } + + + + /// + /// 职务 + /// + [System.ComponentModel.DisplayName("职务")] + public string title { get; set; } + + + /// + /// 生日 + /// + [System.ComponentModel.DisplayName("生日 ")] + public DateTime? birthday { get; set; } + /// + /// 入职时间 + /// + [System.ComponentModel.DisplayName("入职时间")] + public DateTime? hiredday { get; set; } + /// + /// 合同日期 + /// + [System.ComponentModel.DisplayName("合同日期")] + public DateTime? hetongdate { get; set; } + + /// + /// 家庭地址 + /// + [System.ComponentModel.DisplayName("家庭地址")] + public String street { get; set; } + + /// + /// 邮编 + /// + [System.ComponentModel.DisplayName("邮编")] + public String zip { get; set; } + + /// + /// 办公电话 + /// + [System.ComponentModel.DisplayName("办公电话")] + public String ophone { get; set; } + + + /// + /// 行动电话 + /// + [System.ComponentModel.DisplayName("行动电话")] + public string pager { get; set; } + + /// + /// 家庭电话 + /// + [System.ComponentModel.DisplayName("家庭电话")] + public String fphone { get; set; } + + /// + /// 卡号 + /// + [System.ComponentModel.DisplayName("卡号 ")] + public String CardNo { get; set; } + + /// + /// 邮件地址 + /// + [System.ComponentModel.DisplayName("邮件地址 ")] + public String email { get; set; } + + + /// + /// 身份证有效期 + /// + [System.ComponentModel.DisplayName("身份证有效期 ")] + public DateTime idcardvalidtime { get; set; } = new DateTime(2099, 12, 31); + + + + /// + /// 籍贯 + /// + [System.ComponentModel.DisplayName("籍贯")] + public String homeaddress { get; set; } + + /// + /// 民族 + /// + [System.ComponentModel.DisplayName("民族")] + public string minzu { get; set; } + + /// + /// 离职日期 + /// + [System.ComponentModel.DisplayName("离职日期")] + public DateTime? leavedate { get; set; } + + /// + /// 登录密码 + /// + [System.ComponentModel.DisplayName("登录密码")] + public String loginpass { get; set; } + + + /// + /// 相片地址 + /// + [System.ComponentModel.DisplayName("相片地址")] + public String picurl { get; set; } - [System.ComponentModel.DisplayName("上级主管ID")] /// /// 上级主管ID /// + [System.ComponentModel.DisplayName("上级主管ID")] public int? managerid { get; set; } /// /// 上级主管对象 /// [Navigate("managerid")] - public employee parentManager { get; set; } - - /// - /// 下级员工列表 - /// - [Navigate("managerid")] - public List Employees { get; set; } - - - [Navigate(ManyToMany = typeof(department_employee))] - public List departments { get; set; } - - [System.ComponentModel.DisplayName("部门ID ")] - /// - /// 部门ID - /// - public int? deptid { get; set; } - /// - /// 部门对象 - /// - [Navigate("deptid")] - public department Department { get; set; } + public userinfo pManager { get; set; } + + + + [Navigate(ManyToMany = typeof(department_userinfo))] + public List departments { get; set; } + + + + + + + + + + + + - [System.ComponentModel.DisplayName("员工工号")] - /// - /// 员工工号 - /// - public String empcode { get; set; } - [System.ComponentModel.DisplayName("员工姓名")] - /// - /// 员工姓名 - /// - public String empname { get; set; } - - - [System.ComponentModel.DisplayName("地址")] - /// - /// 地址 - /// - public String address { get; set; } - - - [System.ComponentModel.DisplayName("工卡ID ")] - /// - /// 工卡ID - /// - - public String cardid { get; set; } - - - [System.ComponentModel.DisplayName("邮件地址 ")] - /// - /// 邮件地址 - /// - - public String email { get; set; } - - - [System.ComponentModel.DisplayName("合同日期")] - /// - /// 合同日期 - /// - - public DateTime? hetongdate { get; set; } - - - [System.ComponentModel.DisplayName("籍贯")] - /// - /// 籍贯 - /// - - public String homeaddress { get; set; } - - - [System.ComponentModel.DisplayName("入职时间")] - /// - /// 入职时间 - /// - - public DateTime jointime { get; set; } - - - [System.ComponentModel.DisplayName("离职日期")] - /// - /// 离职日期 - /// - public DateTime? leavedate { get; set; } - - - [System.ComponentModel.DisplayName("登录密码")] - /// - /// 登录密码 - /// - public String loginpass { get; set; } - [System.ComponentModel.DisplayName("电话")] - /// - /// 电话 - /// - public String phone { get; set; } - - - [System.ComponentModel.DisplayName("相片地址")] - /// - /// 相片地址 - /// - - public String picurl { get; set; } - [System.ComponentModel.DisplayName("身份证")] - /// - /// 身份证 - /// - public String sfz { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index feb4a6c3..b8def659 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -230,6 +230,17 @@ namespace FreeSql.Tests [Fact] public void Test02() { + var u1 = new userinfo { + name = "111", + departments = new List(new[]{ + new departments { deptname = "dep1" }, + new departments { deptname = "dep1" } + }) + }; + var kwrepo = g.sqlite.GetRepository(); + kwrepo.Insert(u1); + + g.sqlite.GlobalFilter.Apply("gft1", a => a.rowstate > -1) .Apply("gft2", a => a.rowstate > -2) .Apply("gft3", a => a.rowstate > -3); @@ -279,8 +290,6 @@ namespace FreeSql.Tests var gft2 = g.mysql.Select().Where(a => a.id == Guid.NewGuid()).ToList(); var gft3 = g.mysql.Select().Where(a => a.id == Guid.NewGuid()).ToList(); - var tekset = g.sqlite.Select().IncludeMany(a => a.departments).ToList(); - g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); g.mysql.Delete().Where("1=1").ExecuteAffrows(); g.pgsql.Delete().Where("1=1").ExecuteAffrows(); From d186affe731deb2421df8d03d4cda74b606d3723 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 8 Dec 2019 00:46:05 +0800 Subject: [PATCH 0306/1029] ## v0.12.10 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 40fb1d95..6164c448 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.9 + 0.12.10 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 17052c8d..97d35e10 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 80eafc2d..e0d0a18a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d25919a0..65e471f8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d5dfe010..67626392 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.9 + 0.12.10 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fae92288..1e75df79 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index fc6a2141..974ee953 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f68ebbe6..a04311ff 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c75a3cea..628de893 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7dcec730..2d98a41f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 38be7f21..bbf55050 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0e529fb8..bd99abff 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9a5dda02..0f912a42 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.9 + 0.12.10 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From dee1d9af8b5784485fb0c9066a0f480e857b8f3b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 8 Dec 2019 13:04:29 +0800 Subject: [PATCH 0307/1029] =?UTF-8?q?##=20v0.12.11=20=E8=B0=83=E6=95=B4=20?= =?UTF-8?q?ContainsMany=20=E6=96=B9=E6=B3=95=E5=90=8D=E4=B8=BA=20Contains?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 27 +++- .../Extensions/FreeSqlGlobalExpressionCall.cs | 130 ++++++++++++++++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 120 ---------------- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 110 +++++++-------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 222 insertions(+), 198 deletions(-) create mode 100644 FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6164c448..75cfd098 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.10 + 0.12.11 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 97d35e10..93c33975 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e0d0a18a..0a287d13 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 65e471f8..6557cd4e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 67626392..0e8c0d0e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.10 + 0.12.11 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index b8def659..f65fd232 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -264,13 +264,34 @@ namespace FreeSql.Tests }); List<(Guid, DateTime)> contains2linqarr = new List<(Guid, DateTime)>(); - Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains2linqarr.ContainsMany(a.Id, a.ct1)).ToSql(a => 1).Replace("\r\n", "")); - g.sqlite.Select().Where(a => contains2linqarr.ContainsMany(a.Id, a.ct1)).ToList(); + Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToSql(a => 1).Replace("\r\n", "")); + g.sqlite.Select().Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToList(); contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); - g.sqlite.Select().Where(a => contains2linqarr.ContainsMany(a.Id, a.ct1)).ToList(); + g.sqlite.Select() + .Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToList(); + + + + + + + + + + + + + List<(Guid, DateTime, DateTime?)> contains3linqarr = new List<(Guid, DateTime, DateTime?)>(); + Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToSql(a => 1).Replace("\r\n", "")); + g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToList(); + + contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); + contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); + contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); + g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToList(); var start = DateTime.Now.Date; var end = DateTime.Now.AddDays(1).Date.AddMilliseconds(-1); diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs new file mode 100644 index 00000000..83b7e83e --- /dev/null +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs @@ -0,0 +1,130 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Threading; + +[ExpressionCall] +public static class FreeSqlGlobalExpressionCall +{ + public static ThreadLocal expContext = new ThreadLocal(); + + /// + /// C#: that >= between && that <= and + /// SQL: that BETWEEN between AND and + /// + /// + /// + /// + /// + public static bool Between(this DateTime that, DateTime between, DateTime and) + { + if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) + return that >= between && that <= and; + expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} between {expContext.Value.ParsedContent["between"]} and {expContext.Value.ParsedContent["and"]}"; + return false; + } + + /// + /// 注意:这个方法和 Between 有细微区别 + /// C#: that >= start && that < end + /// SQL: that >= start and that < end + /// + /// + /// + /// + /// + public static bool BetweenEnd(this DateTime that, DateTime start, DateTime end) + { + if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) + return that >= start && that < end; + expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} >= {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["that"]} < {expContext.Value.ParsedContent["end"]}"; + return false; + } + + /// + /// C#:从元组集合中查找 exp1, exp2 是否存在 + /// SQL: + /// exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + /// exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + /// ... + /// 注意:当 that 为 null 或 empty 时,返回 1=0 + /// + /// + /// + /// + /// + /// + /// + public static bool Contains([RawValue] this IEnumerable<(T1, T2)> that, T1 exp1, T2 exp2) + { + if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) + return that?.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2)) == true; + if (that?.Any() != true) + { + expContext.Value.Result = "1=0"; + return false; + } + var sb = new StringBuilder(); + var idx = 0; + foreach (var item in that) + { + if (idx++ > 0) sb.Append(" OR \r\n"); + sb + .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) + .Append(" AND ") + .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))); + } + expContext.Value.Result = sb.ToString(); + return true; + } + /// + /// C#:从元组集合中查找 exp1, exp2, exp2 是否存在 + /// SQL: + /// exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR + /// exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + /// ... + /// 注意:当 that 为 null 或 empty 时,返回 1=0 + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static bool Contains([RawValue] this IEnumerable<(T1, T2, T3)> that, T1 exp1, T2 exp2, T3 exp3) + { + if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) + return that.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2) && a.Item3.Equals(exp3)); + if (that.Any() == false) + { + expContext.Value.Result = "1=0"; + return false; + } + var sb = new StringBuilder(); + var idx = 0; + foreach (var item in that) + { + if (idx++ > 0) sb.Append(" OR \r\n"); + sb + .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) + .Append(" AND ") + .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))) + .Append(" AND ") + .Append(expContext.Value.ParsedContent["exp3"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T3), item.Item3))); + } + expContext.Value.Result = sb.ToString(); + return true; + } +} \ No newline at end of file diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 80e588fd..86449244 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -222,124 +222,4 @@ public static partial class FreeSqlGlobalExtensions } #endif #endregion - - #region LambdaExpression - - public static ThreadLocal expContext = new ThreadLocal(); - - /// - /// C#: that >= between && that <= and - /// SQL: that BETWEEN between AND and - /// - /// - /// - /// - /// - [ExpressionCall] - public static bool Between(this DateTime that, DateTime between, DateTime and) - { - if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) - return that >= between && that <= and; - expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} between {expContext.Value.ParsedContent["between"]} and {expContext.Value.ParsedContent["and"]}"; - return false; - } - - /// - /// 注意:这个方法和 Between 有细微区别 - /// C#: that >= start && that < end - /// SQL: that >= start and that < end - /// - /// - /// - /// - /// - [ExpressionCall] - public static bool BetweenEnd(this DateTime that, DateTime start, DateTime end) - { - if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) - return that >= start && that < end; - expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} >= {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["that"]} < {expContext.Value.ParsedContent["end"]}"; - return false; - } - - /// - /// C#:从元组集合中查找 exp1, exp2 是否存在 - /// SQL: - /// exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - /// exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - /// ... - /// 注意:当 that 为 null 或 empty 时,返回 1=0 - /// - /// - /// - /// - /// - /// - /// - [ExpressionCall] - public static bool ContainsMany([RawValue] this IEnumerable<(T1, T2)> that, T1 exp1, T2 exp2) - { - if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) - return that?.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2)) == true; - if (that?.Any() != true) - { - expContext.Value.Result = "1=0"; - return false; - } - var sb = new StringBuilder(); - var idx = 0; - foreach (var item in that) - { - if (idx++ > 0) sb.Append(" OR \r\n"); - sb - .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))); - } - expContext.Value.Result = sb.ToString(); - return true; - } - /// - /// C#:从元组集合中查找 exp1, exp2 是否存在 - /// SQL: - /// exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - /// exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - /// ... - /// 注意:当 that 为 null 或 empty 时,返回 1=0 - /// - /// - /// - /// - /// - /// - /// - /// - /// - [ExpressionCall] - public static bool ContainsMany([RawValue] this IEnumerable<(T1, T2, T3)> that, T1 exp1, T2 exp2, T3 exp3) - { - if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) - return that.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2) && a.Item3.Equals(exp3)); - if (that.Any() == false) - { - expContext.Value.Result = "1=0"; - return false; - } - var sb = new StringBuilder(); - var idx = 0; - foreach (var item in that) - { - if (idx++ > 0) sb.Append(" OR \r\n"); - sb - .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp3"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T3), item.Item3))); - } - expContext.Value.Result = sb.ToString(); - return true; - } - - #endregion } \ No newline at end of file diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1e75df79..9e93c88b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index cda36dcd..8a2c7fc9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2688,6 +2688,61 @@ + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + + + + + + + C#:从元组集合中查找 exp1, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + + C#:从元组集合中查找 exp1, exp2, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + 测量两个经纬度的距离,返回单位:米 @@ -2773,61 +2828,6 @@ 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - C#: that >= between && that <= and - SQL: that BETWEEN between AND and - - - - - - - - - 注意:这个方法和 Between 有细微区别 - C#: that >= start && that < end - SQL: that >= start and that < end - - - - - - - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - 使用 and 拼接两个 lambda 表达式 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 974ee953..56319a44 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a04311ff..f84adda1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 628de893..00772c40 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2d98a41f..d15e9462 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index bbf55050..f851f2c6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index bd99abff..8271e6d4 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 0f912a42..c3e4878c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.10 + 0.12.11 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 65e3ed00917b49b1c86f9f011bde8e193c777990 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 8 Dec 2019 22:59:34 +0800 Subject: [PATCH 0308/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbContext=20?= =?UTF-8?q?TrackList=20=E5=AF=B9=E5=8C=BF=E5=90=8D=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E5=A4=84=E7=90=86=E7=9A=84=20bug=EF=BC=9B#150?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSet.cs | 1 + FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index b5331f1a..dc4c3b47 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -79,6 +79,7 @@ namespace FreeSql var itemType = item.GetType(); if (itemType == typeof(object)) return; if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + if (_db.Orm.CodeFirst.GetTableByEntity(itemType) == null) return; var dbset = _db.Set(itemType); dbset?.GetType().GetMethod("TrackToList", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dbset, new object[] { list }); return; diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index bc192e74..d9b02940 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -29,6 +29,14 @@ namespace FreeSql.Tests using (var ctx = g.sqlite.CreateDbContext()) { + var test150 = ctx.Set() + .Select.From((s, b) => s.InnerJoin(a => a.Id == b.Id)) + .ToList((a, b) => new + { + a.Id,a.Name, + id2 = b.Id, name2 = b.Name + }); + var songs = ctx.Set().Select .IncludeMany(a => a.Tags) .ToList(); From a33cad02cc3b95eab2a945d010f6298b2305008d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Dec 2019 09:10:41 +0800 Subject: [PATCH 0309/1029] ## v0.12.12 #150 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/DbSet/DbSet.cs | 4 ++-- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs | 13 ++++++++++++- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 27 insertions(+), 23 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 75cfd098..9b4e314c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.11 + 0.12.12 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 93c33975..7e5ef6e5 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0a287d13..6edf7cd3 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index dc4c3b47..4c43e6ce 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -79,14 +79,14 @@ namespace FreeSql var itemType = item.GetType(); if (itemType == typeof(object)) return; if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; - if (_db.Orm.CodeFirst.GetTableByEntity(itemType) == null) return; + if (_db.Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; var dbset = _db.Set(itemType); dbset?.GetType().GetMethod("TrackToList", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dbset, new object[] { list }); return; } return; } - + if (_table?.Primarys.Any() != true) return; foreach (var item in ls) { var key = _db.Orm.GetEntityKeyString(_entityType, item, false); diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6557cd4e..7f29c7eb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0e8c0d0e..aacc83e9 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.11 + 0.12.12 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index d9b02940..d8f4c6a6 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -26,10 +26,21 @@ namespace FreeSql.Tests g.sqlite.CodeFirst.SyncStructure(); g.sqlite.CodeFirst.SyncStructure(); + var test150_01 = g.sqlite.GetRepository() + .Select.From((s, b) => s.InnerJoin(a => a.Id == b.Id)) + .ToList((a, b) => new + { + a.Id, + a.Name, + id2 = b.Id, + name2 = b.Name + }); + + using (var ctx = g.sqlite.CreateDbContext()) { - var test150 = ctx.Set() + var test150_02 = ctx.Set() .Select.From((s, b) => s.InnerJoin(a => a.Id == b.Id)) .ToList((a, b) => new { diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9e93c88b..d49f6cdd 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 56319a44..ee86e497 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f84adda1..562a44aa 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 00772c40..27765e16 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d15e9462..abf36ae6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f851f2c6..bd39ad01 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 8271e6d4..b4e7a98f 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c3e4878c..25ee1105 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.11 + 0.12.12 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 9bae834386c3549163e78ae9a503ca01939740eb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Dec 2019 15:29:50 +0800 Subject: [PATCH 0310/1029] =?UTF-8?q?-=20=E8=AF=BB=E5=86=99=E5=88=86?= =?UTF-8?q?=E7=A6=BB=E9=83=A8=E9=97=A8=E4=BB=A3=E7=A0=81=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs | 2 +- Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs | 2 +- .../FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs | 4 ++-- .../FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs | 2 +- .../MySql/Curd/OdbcMySqlInsert.cs | 4 ++-- .../MySql/Curd/OdbcMySqlSelect.cs | 2 +- .../FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs | 2 +- .../Oracle/Curd/OdbcOracleSelect.cs | 10 +++++----- .../Oracle/OdbcOracleCodeFirst.cs | 2 +- .../FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs | 2 +- .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 2 +- .../SqlServer/Curd/OdbcSqlServerSelect.cs | 4 ++-- .../SqlServer/OdbcSqlServerDbFirst.cs | 4 ++-- Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs | 10 +++++----- Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs | 2 +- Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs | 2 +- .../Curd/PostgreSQLSelect.cs | 2 +- .../FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs | 2 +- .../FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs | 4 ++-- .../FreeSql.Provider.SqlServer/SqlServerDbFirst.cs | 4 ++-- Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs | 2 +- Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs | 2 +- 24 files changed, 44 insertions(+), 37 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index a40c0d56..e3afe83b 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.MySql.Curd for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 03426dee..b942a2b4 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -218,7 +218,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); if (istmpatler == false) { - var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql("select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); + var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); foreach (var tbcol in tb.ColumnsByPosition) { var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index be1e79d3..44cc9c5e 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -43,7 +43,7 @@ namespace FreeSql.Odbc.Default conn = poolConn.Value; } _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, _utils.Adapter.InsertAfterGetIdentitySql)), out var trylng) ? trylng : 0; + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, $" {_utils.Adapter.InsertAfterGetIdentitySql}")), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -89,7 +89,7 @@ namespace FreeSql.Odbc.Default conn = poolConn.Value; } await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, _utils.Adapter.InsertAfterGetIdentitySql)), out var trylng) ? trylng : 0; + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, $" {_utils.Adapter.InsertAfterGetIdentitySql}")), out var trylng) ? trylng : 0; } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index b3f0fb59..48c08927 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.Odbc.Default for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index 72092283..9d973dd4 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -42,7 +42,7 @@ namespace FreeSql.Odbc.MySql conn = poolConn.Value; } _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, "SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -122,7 +122,7 @@ namespace FreeSql.Odbc.MySql conn = poolConn.Value; } await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, "SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index f013109b..3fef9f09 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.Odbc.MySql for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index b4a17d8d..01361851 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -207,7 +207,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); if (istmpatler == false) { - var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql("select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); + var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); foreach (var tbcol in tb.ColumnsByPosition) { var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index 83b9f7ca..fedef69e 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.Odbc.Oracle for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); @@ -109,13 +109,13 @@ namespace FreeSql.Odbc.Oracle if (string.IsNullOrEmpty(_orderby)) { if (_skip > 0) - sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); } else { - if (_skip > 0 && _limit > 0) sb.Insert(0, "SELECT t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); - else if (_skip > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); - else if (_limit > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); + if (_skip > 0 && _limit > 0) sb.Insert(0, $"{_select} t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + else if (_skip > 0) sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); + else if (_limit > 0) sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); } sbnav.Clear(); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 844364ad..d39e4c48 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -287,7 +287,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam sb.Append(sbalter); continue; } - var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); if (string.IsNullOrEmpty(oldpk) == false) sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index 7d25d4ee..fe87f450 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -174,7 +174,7 @@ namespace FreeSql.Odbc.Oracle if (database == null || database.Any() == false) { - var userUsers = _orm.Ado.ExecuteScalar("select username from user_users")?.ToString(); + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); if (string.IsNullOrEmpty(userUsers)) return loc1; database = new[] { userUsers }; } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 9849d492..2125f405 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.Odbc.PostgreSQL for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 5686919c..6872fc2f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -296,7 +296,7 @@ where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tbol sb.Append(sbalter); continue; } - var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select pg_constraint.conname as pk_name from pg_constraint + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select pg_constraint.conname as pk_name from pg_constraint inner join pg_class on pg_constraint.conrelid = pg_class.oid inner join pg_namespace on pg_namespace.oid = pg_class.relnamespace where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contype='p' diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index 56b61970..12c218dc 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.SqlServer for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); @@ -147,7 +147,7 @@ namespace FreeSql.Odbc.SqlServer for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index bf94f966..4e3652b1 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -253,8 +253,8 @@ from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); { sql += "union all" + string.Format(tsql_place.Replace( - "select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id", - "select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" + " select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id", + " select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index b2349ef0..9df0a9d5 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.Oracle.Curd for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); @@ -109,13 +109,13 @@ namespace FreeSql.Oracle.Curd if (string.IsNullOrEmpty(_orderby)) { if (_skip > 0) - sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); } else { - if (_skip > 0 && _limit > 0) sb.Insert(0, "SELECT t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); - else if (_skip > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); - else if (_limit > 0) sb.Insert(0, "SELECT t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); + if (_skip > 0 && _limit > 0) sb.Insert(0, $"{_select} t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + else if (_skip > 0) sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); + else if (_limit > 0) sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); } sbnav.Clear(); diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 52bb15f6..ff6da1be 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -288,7 +288,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam sb.Append(sbalter); continue; } - var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); if (string.IsNullOrEmpty(oldpk) == false) sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index d76f4be5..089e2791 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -174,7 +174,7 @@ namespace FreeSql.Oracle if (database == null || database.Any() == false) { - var userUsers = _orm.Ado.ExecuteScalar("select username from user_users")?.ToString(); + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); if (string.IsNullOrEmpty(userUsers)) return loc1; database = new[] { userUsers }; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 928d91c6..136f1d3a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.PostgreSQL.Curd for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index f8bfab2f..ebc6d40f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -334,7 +334,7 @@ where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tbol sb.Append(sbalter); continue; } - var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@"select pg_constraint.conname as pk_name from pg_constraint + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select pg_constraint.conname as pk_name from pg_constraint inner join pg_class on pg_constraint.conrelid = pg_class.oid inner join pg_namespace on pg_namespace.oid = pg_class.relnamespace where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contype='p' diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index c3518557..5678baaa 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -32,7 +32,7 @@ namespace FreeSql.SqlServer.Curd for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); @@ -147,7 +147,7 @@ namespace FreeSql.SqlServer.Curd for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 2be0a2e9..6cdb4ca2 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -256,8 +256,8 @@ from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); { sql += "union all" + string.Format(tsql_place.Replace( - "select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id", - "select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" + " select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id", + " select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index ba3af794..33b16a1b 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.Sqlite.Curd for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append("select * from ("); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; var sbnav = new StringBuilder(); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index d2e14193..9ce4376f 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -211,7 +211,7 @@ namespace FreeSql.Sqlite { if (string.Concat(dbIndex[3]) == "pk") continue; var dbIndexesColumns = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.INDEX_INFO({dbIndex[1]})"); - var dbIndexesSql = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $"SELECT sql FROM sqlite_master WHERE name = '{dbIndex[1]}'")); + var dbIndexesSql = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT sql FROM sqlite_master WHERE name = '{dbIndex[1]}'")); foreach (var dbcolumn in dbIndexesColumns) { var dbcolumnName = string.Concat(dbcolumn[2]); From cc585b4cd5d331fce17e8b277a539a645b65f7ba Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Dec 2019 16:48:42 +0800 Subject: [PATCH 0311/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20BaseEntity?= =?UTF-8?q?=20=E7=89=A9=E7=90=86=E5=88=A0=E9=99=A4=E6=96=B9=E6=B3=95=20Del?= =?UTF-8?q?ete(true)=EF=BC=9B#152=20-=20=E4=BF=AE=E5=A4=8D=20Sqlite=20atta?= =?UTF-8?q?chs=20=E9=99=84=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93=E5=88=AB?= =?UTF-8?q?=E5=90=8D=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity/BaseEntity.cs | 11 ++++++++++- .../FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs | 11 ++++++++++- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 3 +++ .../SqliteAdo/SqliteConnectionPool.cs | 4 ++-- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index fa8f9669..7ef0b544 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -80,8 +80,17 @@ namespace FreeSql /// /// 删除数据 /// + /// 是否物理删除 /// - public virtual bool Delete() => this.UpdateIsDeleted(true); + public virtual bool Delete(bool physicalDelete = false) + { + if (physicalDelete == false) return this.UpdateIsDeleted(true); + if (this.Repository == null) + return Orm.Delete(this as TEntity).ExecuteAffrows() == 1; + //this.SetTenantId(); + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.Delete(this as TEntity) == 1; + } /// /// 恢复删除的数据 /// diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index 4b98dca2..13a3c29e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -62,8 +62,17 @@ namespace FreeSql /// /// 删除数据 /// + /// 是否物理删除 /// - public virtual Task DeleteAsync() => this.UpdateIsDeletedAsync(true); + async public virtual Task DeleteAsync(bool physicalDelete = false) + { + if (physicalDelete == false) return await this.UpdateIsDeletedAsync(true); + if (this.Repository == null) + return await Orm.Delete(this as TEntity).ExecuteAffrowsAsync() == 1; + //this.SetTenantId(); + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return await this.Repository.DeleteAsync(this as TEntity) == 1; + } /// /// 恢复删除的数据 /// diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index f65fd232..7b687258 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -230,6 +230,9 @@ namespace FreeSql.Tests [Fact] public void Test02() { + var testcf = g.sqlite.CodeFirst.GetComparisonDDLStatements(typeof(dfDto2), "main.test2"); + + var u1 = new userinfo { name = "111", departments = new List(new[]{ diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index a6805118..bc915c72 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -242,7 +242,7 @@ namespace FreeSql.Sqlite { var sb = new StringBuilder(); foreach (var att in attach) - sb.Append($"attach database [{att}] as [{att.Split('.').First()}];\r\n"); + sb.Append($"attach database [{att}] as [{att.Split('/', '\\').Last().Split('.').First()}];\r\n"); var cmd = that.CreateCommand(); cmd.CommandText = sb.ToString(); @@ -274,7 +274,7 @@ namespace FreeSql.Sqlite { var sb = new StringBuilder(); foreach (var att in attach) - sb.Append($"attach database [{att}] as [{att.Split('.').First()}];\r\n"); + sb.Append($"attach database [{att}] as [{att.Split('/', '\\').Last().Split('.').First()}];\r\n"); var cmd = that.CreateCommand(); cmd.CommandText = sb.ToString(); From 206d7bdbe04b31698f4bdc6676941399442fc31d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Dec 2019 21:25:01 +0800 Subject: [PATCH 0312/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=E6=95=B0=E6=8D=AE=E5=BA=93=20ODBC=20=E9=80=82?= =?UTF-8?q?=E9=85=8D=EF=BC=8C=E5=92=8C=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=20CodeFirst=20=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E5=BC=80=E5=8F=91=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseEntityTree.cs | 4 +- .../FreeSql.Extensions.BaseEntity.xml | 6 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - .../Dameng/Curd/DamengDeleteTest.cs | 93 + .../Dameng/Curd/DamengInsertTest.cs | 278 +++ .../Dameng/Curd/DamengSelectTest.cs | 1529 ++++++++++++++++ .../Dameng/Curd/DamengUpdateTest.cs | 137 ++ .../Dameng/DamengAdo/DamengAdoTest.cs | 66 + .../Dameng/DamengAopTest.cs | 40 + .../Dameng/DamengCodeFirstTest.cs | 257 +++ .../Dameng/DamengDbFirstTest.cs | 25 + .../Dameng/DamengExpression/ConvertTest.cs | 169 ++ .../Dameng/DamengExpression/DateTimeTest.cs | 706 ++++++++ .../Dameng/DamengExpression/MathTest.cs | 156 ++ .../Dameng/DamengExpression/OtherTest.cs | 164 ++ .../Dameng/DamengExpression/StringTest.cs | 726 ++++++++ .../Dameng/DamengExpression/TimeSpanTest.cs | 293 +++ .../Dameng/MapType/BoolNullableTest.cs | 1571 +++++++++++++++++ .../Dameng/MapType/BoolTest.cs | 1105 ++++++++++++ .../Dameng/MapType/DateTimeOffSetTest.cs | 54 + .../Dameng/MapType/EnumTest.cs | 261 +++ .../Dameng/MapType/ToStringTest.cs | 570 ++++++ .../FreeSql.Tests.Provider.Odbc/g.cs | 13 + FreeSql/DataType.cs | 9 +- FreeSql/FreeSql.xml | 5 + FreeSql/FreeSqlBuilder.cs | 5 + .../Internal/CommonProvider/DeleteProvider.cs | 1 + .../Internal/CommonProvider/InsertProvider.cs | 1 + .../SelectProvider/Select0Provider.cs | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 1 + .../Dameng/Curd/OdbcDamengDelete.cs | 31 + .../Dameng/Curd/OdbcDamengInsert.cs | 222 +++ .../Dameng/Curd/OdbcDamengSelect.cs | 184 ++ .../Dameng/Curd/OdbcDamengUpdate.cs | 77 + .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 67 + .../OdbcDamengAdo/OdbcDamengConnectionPool.cs | 253 +++ .../Dameng/OdbcDamengCodeFirst.cs | 446 +++++ .../Dameng/OdbcDamengDbFirst.cs | 508 ++++++ .../Dameng/OdbcDamengExpression.cs | 464 +++++ .../Dameng/OdbcDamengProvider.cs | 64 + .../Dameng/OdbcDamengUtils.cs | 113 ++ .../FreeSqlOdbcGlobalExtensions.cs | 9 + .../OracleCodeFirst.cs | 2 +- .../SqlServerDbFirst.cs | 2 +- readme.md | 2 +- 46 files changed, 10682 insertions(+), 17 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/ToStringTest.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs index fa7bd5b1..e805aa6b 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs @@ -114,8 +114,8 @@ namespace FreeSql (item as BaseEntity).IsDeleted = false; return func(repo, childs); } - public override bool Delete() => UpdateIsDelete(true, (repo, chis) => repo.Update(chis)) > 0; - async public override Task DeleteAsync() => await UpdateIsDelete(true, (repo, chis) => repo.UpdateAsync(chis)) > 0; + public override bool Delete(bool physicalDelete = false) => UpdateIsDelete(true, (repo, chis) => repo.Update(chis)) > 0; + async public override Task DeleteAsync(bool physicalDelete = false) => await UpdateIsDelete(true, (repo, chis) => repo.UpdateAsync(chis)) > 0; public override bool Restore() => UpdateIsDelete(false, (repo, chis) => repo.Update(chis)) > 0; async public override Task RestoreAsync() => await UpdateIsDelete(false, (repo, chis) => repo.UpdateAsync(chis)) > 0; diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml index a03b9ba3..a2b0bbc5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml @@ -38,10 +38,11 @@ - + 删除数据 + 是否物理删除 @@ -94,10 +95,11 @@ - + 删除数据 + 是否物理删除 diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs new file mode 100644 index 00000000..b99edf53 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs @@ -0,0 +1,93 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengDeleteTest + { + + IDelete delete => g.dameng.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.dameng.Delete().ToSql()); + var sql = g.dameng.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.dameng.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.dameng.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.dameng.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.dameng.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //var item = g.dameng.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.dameng.Delete().ToSql()); + var sql = g.dameng.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.dameng.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + + sql = g.dameng.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.dameng.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertTest.cs new file mode 100644 index 00000000..0c2fedef --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertTest.cs @@ -0,0 +1,278 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengInsertTest + { + + IInsert insert => g.dameng.Insert(); //�������� + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 22:25:38.697071") }); + + var data = new List(); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newtitle0', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6'))", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(0, 'newtitle0', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(100, 'newtitle1', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(200, 'newtitle2', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(300, 'newtitle3', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(400, 'newtitle4', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(500, 'newtitle5', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(600, 'newtitle6', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(700, 'newtitle7', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(800, 'newtitle8', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(900, 'newtitle9', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle0') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle1') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle2') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle3') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle4') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle5') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle6') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle7') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle8') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var data = new List(); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle0') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle1') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle2') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle3') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle4') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle5') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle6') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle7') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle8') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var data = new List(); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(100) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(200) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(300) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(400) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(500) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(600) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(700) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(800) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(900) + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.dameng.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.dameng.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicICs")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + //var items = new List(); + //for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //var items2 = insert.AppendData(items).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newTitle0', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6'))", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(0, 'newTitle0', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(100, 'newTitle1', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(200, 'newTitle2', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(300, 'newTitle3', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(400, 'newTitle4', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(500, 'newTitle5', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(600, 'newTitle6', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(700, 'newTitle7', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(800, 'newTitle8', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(900, 'newTitle9', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(0, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(100, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(200, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(300, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(400, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(500, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(600, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(700, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(800, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(900, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle9') + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle9') + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(0, 'newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(100, 'newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(200, 'newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(300, 'newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(400, 'newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(500, 'newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(600, 'newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(700, 'newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(800, 'newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(900, 'newTitle9') + SELECT 1 FROM DUAL", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs new file mode 100644 index 00000000..baa301f6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -0,0 +1,1529 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengSelectTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.dameng.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.dameng.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.dameng.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.dameng.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.dameng.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.dameng.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.dameng.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.dameng.Insert(items).ExecuteAffrows()); + + //var dt1 = select.ToDataTable(); + //var dt2 = select.ToDataTable("id, 111222"); + //var dt3 = select.ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + g.dameng.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.dameng.Select().ToList(); + var testGuidId6 = g.dameng.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.dameng.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.dameng.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Avg(b => b.Id) + }); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.dameng.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.dameng.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.dameng.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.dameng.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.dameng.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.dameng.Insert(model4s).ExecuteAffrows()); + + var t0 = g.dameng.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.dameng.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.dameng.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.dameng.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.dameng.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.dameng.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.dameng.Insert(model1).ExecuteIdentity(); + + var t1 = g.dameng.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.dameng.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.dameng.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.dameng.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.dameng.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.dameng.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.dameng.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.dameng.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.dameng.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.dameng.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.dameng.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.dameng.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.dameng.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.dameng.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.dameng.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.dameng.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.dameng.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.dameng.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.dameng.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.dameng.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.dameng.Insert(song3).ExecuteIdentity(); + + g.dameng.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.dameng.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.dameng.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.dameng.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.dameng.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.oracle, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.dameng.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.dameng.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.dameng.Select().Count()); + Assert.Equal(3, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.dameng.Select().Count()); + Assert.Equal(3, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.dameng.Select().Count()); + Assert.Equal(3, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.dameng.Select().Count()); + Assert.Equal(5, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.dameng.Select().Count()); + Assert.Equal(5, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.dameng.Select().Count()); + Assert.Equal(5, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs new file mode 100644 index 00000000..ce50236a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs @@ -0,0 +1,137 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengUpdateTest + { + IUpdate update => g.dameng.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.dameng.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL, \"TITLE\" = 'newtitle', \"CREATETIME\" = to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 2 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 3 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 4 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 5 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 6 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 7 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 8 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 9 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 10 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle', \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + ? WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.dameng.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs new file mode 100644 index 00000000..a685b04d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs @@ -0,0 +1,66 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.oracle.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.oracle.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + + var t4 = g.oracle.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + + var t5 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAopTest.cs new file mode 100644 index 00000000..a297e27c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.dameng.Aop.AuditValue += audit; + + g.dameng.Insert(item).ExecuteAffrows(); + + g.dameng.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs new file mode 100644 index 00000000..9d19d28b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -0,0 +1,257 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengCodeFirstTest + { + + [Fact] + public void ı_ֶ() + { + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements<ı>(); + g.dameng.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.dameng.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); + g.dameng.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); + + var id = g.dameng.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.dameng.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar2(200) not null", OldName = "title")] + public string title2 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( + `Id` INT(11) NOT NULL AUTO_INCREMENT, + `Bool` BIT(1) NOT NULL, + `SByte` TINYINT(3) NOT NULL, + `Short` SMALLINT(6) NOT NULL, + `Int` INT(11) NOT NULL, + `Long` BIGINT(20) NOT NULL, + `Byte` TINYINT(3) UNSIGNED NOT NULL, + `UShort` SMALLINT(5) UNSIGNED NOT NULL, + `UInt` INT(10) UNSIGNED NOT NULL, + `ULong` BIGINT(20) UNSIGNED NOT NULL, + `Double` DOUBLE NOT NULL, + `Float` FLOAT NOT NULL, + `Decimal` DECIMAL(10,2) NOT NULL, + `TimeSpan` TIME NOT NULL, + `DateTime` DATETIME NOT NULL, + `Bytes` VARBINARY(255), + `String` VARCHAR(255), + `Guid` VARCHAR(36), + `BoolNullable` BIT(1), + `SByteNullable` TINYINT(3), + `ShortNullable` SMALLINT(6), + `IntNullable` INT(11), + `testFielLongNullable` BIGINT(20), + `ByteNullable` TINYINT(3) UNSIGNED, + `UShortNullable` SMALLINT(5) UNSIGNED, + `UIntNullable` INT(10) UNSIGNED, + `ULongNullable` BIGINT(20) UNSIGNED, + `DoubleNullable` DOUBLE, + `FloatNullable` FLOAT, + `DecimalNullable` DECIMAL(10,2), + `TimeSpanNullable` TIME, + `DateTimeNullable` DATETIME, + `GuidNullable` VARCHAR(36), + `Point` POINT, + `LineString` LINESTRING, + `Polygon` POLYGON, + `MultiPoint` MULTIPOINT, + `MultiLineString` MULTILINESTRING, + `MultiPolygon` MULTIPOLYGON, + `Enum1` ENUM('E1','E2','E3') NOT NULL, + `Enum1Nullable` ENUM('E1','E2','E3'), + `Enum2` SET('F1','F2','F3') NOT NULL, + `Enum2Nullable` SET('F1','F2','F3'), + PRIMARY KEY (`Id`) +) Engine=InnoDB; +", sql); + } + + //sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.dameng.Insert(); + ISelect select => g.dameng.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs new file mode 100644 index 00000000..7c40e69d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.dameng.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.dameng.DbFirst.GetTablesByDatabase(); + //var tb = g.dameng.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs new file mode 100644 index 00000000..f3a89e5b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengExpression +{ + public class ConvertTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/DateTimeTest.cs new file mode 100644 index 00000000..08576662 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/DateTimeTest.cs @@ -0,0 +1,706 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengExpression +{ + public class DateTimeTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/MathTest.cs new file mode 100644 index 00000000..b5adc983 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengExpression +{ + public class MathTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/OtherTest.cs new file mode 100644 index 00000000..5129514b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/OtherTest.cs @@ -0,0 +1,164 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengExpression +{ + public class OtherTest + { + + ISelect select => g.dameng.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs new file mode 100644 index 00000000..f945fc5e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs @@ -0,0 +1,726 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengExpression +{ + public class StringTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/TimeSpanTest.cs new file mode 100644 index 00000000..0c0b5c17 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengExpression +{ + public class TimeSpanTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..4e32a232 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolTest.cs new file mode 100644 index 00000000..60f57d11 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..27e703ae --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.oracle; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/EnumTest.cs new file mode 100644 index 00000000..ba996ccf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/ToStringTest.cs new file mode 100644 index 00000000..55f3b877 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.DamengMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index 3f1e5f78..b00b6d96 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -62,4 +62,17 @@ public class g .UseLazyLoading(true) .Build()); public static IFreeSql odbc => odbcLazy.Value; + + static Lazy damemgLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseSyncStructureToUpper(true) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql dameng => damemgLazy.Value; } diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 6ea9bca0..7ab8d66e 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -8,7 +8,7 @@ namespace FreeSql MySql, SqlServer, PostgreSQL, Oracle, Sqlite, - OdbcOracle, OdbcSqlServer, OdbcMySql, OdbcPostgreSQL, + OdbcOracle, OdbcSqlServer, OdbcMySql, OdbcPostgreSQL, /// /// 通用的 Odbc 实现,只能做基本的 Crud 操作 @@ -19,6 +19,11 @@ namespace FreeSql /// /// 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 /// - Odbc + Odbc, + + /// + /// 国产数据库达梦 + /// + OdbcDameng, } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8a2c7fc9..ac93e9cc 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -484,6 +484,11 @@ 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 + + + 国产数据库达梦 + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index b0fb53be..fd1db807 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -200,6 +200,11 @@ namespace FreeSql if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); break; + case DataType.OdbcDameng: + type = Type.GetType("FreeSql.Odbc.Dameng.OdbcDamengProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + break; + default: throw new Exception("未指定 UseConnectionString"); } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 81bac23e..bacd113f 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -122,6 +122,7 @@ namespace FreeSql.Internal.CommonProvider { if (_tableRule == null) return _table.DbName; var newname = _tableRule(_table.DbName); + if (newname == _table.DbName) return _table.DbName; if (string.IsNullOrEmpty(newname)) return _table.DbName; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index ed89acca..ebfb45c1 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -374,6 +374,7 @@ namespace FreeSql.Internal.CommonProvider { if (_tableRule == null) return _table.DbName; var newname = _tableRule(_table.DbName); + if (newname == _table.DbName) return _table.DbName; if (string.IsNullOrEmpty(newname)) return _table.DbName; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 31cc450d..4db3b260 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -917,7 +917,7 @@ namespace FreeSql.Internal.CommonProvider protected List> GetTableRuleUnions() { var unions = new List>(); - var trs = _tableRules.Any() ? _tableRules : new List>(new[] { new Func((type, oldname) => oldname) }); + var trs = _tableRules.Any() ? _tableRules : new List>(new[] { new Func((type, oldname) => null) }); foreach (var tr in trs) { var dict = new Dictionary(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index f8abaa1a..b105a7dc 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -498,6 +498,7 @@ namespace FreeSql.Internal.CommonProvider { if (_tableRule == null) return _table.DbName; var newname = _tableRule(_table.DbName); + if (newname == _table.DbName) return _table.DbName; if (string.IsNullOrEmpty(newname)) return _table.DbName; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index ee954eaa..f122b094 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -217,6 +217,7 @@ namespace FreeSql.Internal break; case DataType.Oracle: case DataType.OdbcOracle: + case DataType.OdbcDameng: if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(4000)"); else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs new file mode 100644 index 00000000..c7904f30 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs @@ -0,0 +1,31 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Dameng +{ + + class OdbcDamengDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OdbcDamengDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + throw new NotImplementedException(); + } + +#if net40 +#else + public override Task> ExecuteDeletedAsync() + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs new file mode 100644 index 00000000..3d065911 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -0,0 +1,222 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Dameng +{ + + class OdbcDamengInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public OdbcDamengInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); + + public override string ToSql() + { + if (_source == null || _source.Any() == false) return null; + var sb = new StringBuilder(); + sb.Append("INSERT "); + if (_source.Count > 1) sb.Append("ALL"); + + _identCol = null; + var sbtb = new StringBuilder(); + sbtb.Append("INTO "); + sbtb.Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("("); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity) _identCol = col; + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sbtb.Append(", "); + sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); + ++colidx; + } + sbtb.Append(") "); + + _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; + var specialParams = new List(); + var didx = 0; + foreach (var d in _source) + { + if (_source.Count > 1) sb.Append("\r\n"); + sb.Append(sbtb); + sb.Append("VALUES"); + sb.Append("("); + var colidx2 = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx2 > 0) sb.Append(", "); + if (string.IsNullOrEmpty(col.DbInsertValue) == false) + sb.Append(col.DbInsertValue); + else + { + object val = col.GetMapValue(d); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + } + } + ++colidx2; + } + sb.Append(")"); + ++didx; + } + if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); + return sb.ToString(); + } + + ColumnInfo _identCol; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + this.RawExecuteAffrows(); + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + await this.RawExecuteAffrowsAsync(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs new file mode 100644 index 00000000..b421d3b1 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs @@ -0,0 +1,184 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Dameng +{ + + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field); + if (string.IsNullOrEmpty(_orderby) && _skip > 0) sb.Append(", ROWNUM AS \"__rownum__\""); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) + sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); + if (sbnav.Length > 0) + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + + if (string.IsNullOrEmpty(_orderby)) + { + if (_skip > 0) + sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + } + else + { + if (_skip > 0 && _limit > 0) sb.Insert(0, $"{_select} t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + else if (_skip > 0) sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); + else if (_limit > 0) sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); + } + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.ToString(); + } + + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs new file mode 100644 index 00000000..944fa5c2 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -0,0 +1,77 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Dameng +{ + + class OdbcDamengUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public OdbcDamengUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); + + + protected override List RawExecuteUpdated() + { + throw new NotImplementedException(); + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + ++pkidx; + } + sb.Append(")"); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs new file mode 100644 index 00000000..ec2338a2 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -0,0 +1,67 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using SafeObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.Odbc.Dameng +{ + class OdbcDamengAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public OdbcDamengAdo() : base(DataType.Oracle) { } + public OdbcDamengAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Oracle) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OdbcDamengConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OdbcDamengConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("to_timestamp('", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "','YYYY-MM-DD HH24:MI:SS.FF6')"); + else if (param is TimeSpan || param is TimeSpan?) + return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + //if (param is string) return string.Concat('N', nparms[a]); + } + + protected override DbCommand CreateCommand() + { + return new OdbcCommand(); + } + + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as OdbcDamengConnectionPool).Return(conn, ex); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs new file mode 100644 index 00000000..61bdc72c --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -0,0 +1,253 @@ +using SafeObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.Dameng +{ + + class OdbcDamengConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + internal string UserId { get; set; } + + public OdbcDamengConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + this.UserId = userIdMatch.Groups[2].Value.Trim().ToUpper(); + + var policy = new OdbcOracleConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + + if (exception is System.IO.IOException) + { + + base.SetUnavailable(exception); + + } + else if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class OdbcOracleConnectionPoolPolicy : IPolicy + { + + internal OdbcDamengConnectionPool _pool; + public string Name { get; set; } = "Oracle OdbcConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1 from dual"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs new file mode 100644 index 00000000..2891a2b2 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -0,0 +1,446 @@ +using FreeSql.DataAnnotations; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.Dameng +{ + + class OdbcDamengCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public OdbcDamengCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (OdbcType.Bit, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "number","number(1) NULL", null, true, null) }, + + { typeof(sbyte).FullName, (OdbcType.SmallInt, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "number", "number(4) NULL", false, true, null) }, + { typeof(short).FullName, (OdbcType.SmallInt, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "number", "number(6) NULL", false, true, null) }, + { typeof(int).FullName, (OdbcType.Int, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "number", "number(11) NULL", false, true, null) }, + { typeof(long).FullName, (OdbcType.BigInt, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "number","number(21) NULL", false, true, null) }, + + { typeof(byte).FullName, (OdbcType.TinyInt, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, "number","number(3) NULL", true, true, null) }, + { typeof(ushort).FullName, (OdbcType.Int, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "number", "number(5) NULL", true, true, null) }, + { typeof(uint).FullName, (OdbcType.BigInt, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong).FullName, (OdbcType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "number", "number(20) NULL", true, true, null) }, + + { typeof(double).FullName, (OdbcType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "double", "double NULL", false, true, null) }, + { typeof(float).FullName, (OdbcType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "real","real NULL", false, true, null) }, + { typeof(decimal).FullName, (OdbcType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + + //达梦8 ODBC 不支持 TimeSpan + //{ typeof(TimeSpan).FullName, (OdbcType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + + { typeof(byte[]).FullName, (OdbcType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string).FullName, (OdbcType.NVarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + + { typeof(Guid).FullName, (OdbcType.Char, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.Char, "char", "char(36) NULL", false, true, null) }, + }; + + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + { + var userId = (_orm.Ado.MasterPool as OdbcDamengConnectionPool).UserId; + var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 + var seqnameDel = new List(); //要删除的序列+触发器 + + var sb = new StringBuilder(); + var sbDeclare = new StringBuilder(); + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; + + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; + var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + primaryKeyName = null; + } + } + + if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 + throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tboldname)) == null) + //模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("execute immediate 'CREATE TABLE ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; + sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) LOGGING ';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + continue; + } + //如果新表,旧表在一个模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql($@" +select +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'Y' then 1 else 0 end, +nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), +nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +b.comments +from all_tab_columns a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var sqlType = GetOracleSqlTypeFullName(a); + return new + { + column = string.Concat(a[0]), + sqlType, + is_nullable = string.Concat(a[6]) == "1", + is_identity = string.Concat(a[7]) == "1" && string.Concat(a[8]) == "1", + comment = string.Concat(a[9]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + istmpatler = true; + //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + if (tbstructcol.is_identity) + seqnameDel.Add(Utils.GetCsName($"{tbname[1]}_seq_{tbstructcol.column}")); + //修改列名 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); + if (tbcol.Attribute.IsIdentity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } + else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (isCommentChanged) + sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + continue; + } + //添加列 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable == false) + { + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); + } + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + } + + var dsuksql = _commonUtils.FormatSql(@" +select +c.column_name, +a.index_name, +case when c.descend = 'DESC' then 1 else 0 end, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner +and a.table_name = c.table_name +and a.owner in ({0}) and a.table_name in ({1}) +and not exists(select 1 from all_constraints where index_name = a.index_name and constraint_type = 'P')", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]).Trim('"'), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }).ToArray(); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append("';\r\n"); + sbalter.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); + //创建临时表 + sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; + sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) LOGGING ';\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); + insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"nvl({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + sb.Append(insertvalue.Replace("'", "''")).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } + } + Dictionary dicDeclare = new Dictionary(); + Action dropSequence = seqname => + { + if (dicDeclare.ContainsKey(seqname) == false) + { + sbDeclare.Append("\r\n").Append(seqname).Append("IS NUMBER; \r\n"); + dicDeclare.Add(seqname, true); + } + sb.Append(seqname).Append("IS := 0; \r\n") + .Append(" select count(1) into ").Append(seqname).Append(_commonUtils.FormatSql("IS from user_sequences where sequence_name={0}; \r\n", seqname)) + .Append("if ").Append(seqname).Append("IS > 0 then \r\n") + .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") + .Append("end if; \r\n"); + }; + Action dropTrigger = tiggerName => + { + if (dicDeclare.ContainsKey(tiggerName) == false) + { + sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); + dicDeclare.Add(tiggerName, true); + } + sb.Append(tiggerName).Append("IS := 0; \r\n") + .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") + .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") + .Append("end if; \r\n"); + }; + foreach (var seqname in seqnameDel) + { + dropSequence(seqname); + dropTrigger(seqname + "TI"); + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var tiggerName = seqname + "TI"; + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + dropSequence(seqname); + if (seqcol.Item3) + { + var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_columns where owner={0} and table_name={1} and column_name={2}", tbname[0], tbname[1], seqcol.Item1.Attribute.Name)) == null ? 1 : + _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}"); + sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n"); + sb.Append("execute immediate 'CREATE OR REPLACE TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)) + .Append(" \r\nbefore insert on ").Append(tbname2) + .Append(" \r\nfor each row \r\nbegin\r\nselect ").Append(_commonUtils.QuoteSqlName(seqname)) + .Append(".nextval into :new.").Append(colname2).Append(" from dual;\r\nend;';\r\n"); + } + else + dropTrigger(tiggerName); + } + if (sbDeclare.Length > 0) sbDeclare.Insert(0, "declare "); + return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString(); + } + + internal static string GetOracleSqlTypeFullName(object[] row) + { + var a = row; + var sqlType = string.Concat(a[1]).ToUpper(); + var data_length = long.Parse(string.Concat(a[2])); + long.TryParse(string.Concat(a[3]), out var data_precision); + long.TryParse(string.Concat(a[4]), out var data_scale); + var char_used = string.Concat(a[5]); + if (sqlType.StartsWith("INTERVAL DAY TO SECOND")) + sqlType = $"INTERVAL DAY({(data_scale - 1536) / 16}) TO SECOND({(data_scale - 1536) % 16})"; + else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) + { + } + else if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) + sqlType += data_scale <= 0 ? "" : $"({data_scale})"; + else if (sqlType.StartsWith("BLOB")) + { + } + else if (sqlType == "REAL" || sqlType == "DOUBLE" || sqlType == "FLOAT") + { + } + else if (data_precision > 0 && data_scale > 0) + sqlType += $"({data_precision},{data_scale})"; + else if (data_precision > 0) + sqlType += $"({data_precision})"; + else + sqlType += $"({data_length})"; + return sqlType; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs new file mode 100644 index 00000000..861dbbdc --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -0,0 +1,508 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.Dameng +{ + class OdbcDamengDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public OdbcDamengDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + OdbcType GetSqlDbType(DbColumnInfo column) + { + var dbfull = column.DbTypeTextFull.ToLower(); + switch (dbfull) + { + case "number(1)": return OdbcType.Bit; + + case "number(4)": return OdbcType.SmallInt; + case "number(6)": return OdbcType.SmallInt; + case "number(11)": return OdbcType.Int; + case "number(21)": return OdbcType.BigInt; + + case "number(3)": return OdbcType.TinyInt; + case "number(5)": return OdbcType.SmallInt; + case "number(10)": return OdbcType.BigInt; + case "number(20)": return OdbcType.Decimal; + + case "float(126)": return OdbcType.Double; + case "float(63)": return OdbcType.Real; + case "number(10,2)": return OdbcType.Decimal; + + case "interval day(2) to second(6)": return OdbcType.Time; + case "timestamp(6)": return OdbcType.DateTime; + case "timestamp(6) with local time zone": return OdbcType.DateTime; + + case "blob": return OdbcType.VarBinary; + case "nvarchar2(255)": return OdbcType.NVarChar; + + case "char(36 char)": return OdbcType.Char; + } + switch (column.DbTypeText.ToLower()) + { + case "number": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(10,2)"]); + return OdbcType.Decimal; + case "float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return OdbcType.Double; + case "interval day to second": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); + return OdbcType.Time; + case "date": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["date(7)"]); + return OdbcType.DateTime; + case "timestamp": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); + return OdbcType.DateTime; + case "timestamp with local time zone": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6) with local time zone"]); + return OdbcType.DateTime; + case "blob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OdbcType.VarBinary; + case "nvarchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + case "varchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + case "char": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.Char; + case "nchar": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NChar; + case "clob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + case "nclob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + case "raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OdbcType.VarBinary; + case "long raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OdbcType.VarBinary; + case "binary_float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]); + return OdbcType.Real; + case "binary_double": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return OdbcType.Double; + case "rowid": + default: + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OdbcType.NVarChar; + } + throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); + } + + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static OdbcDamengDbFirst() + { + var defaultDbToCs = new Dictionary() { + { "number(1)", ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { "number(4)", ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { "number(6)", ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "number(11)", ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "number(21)", ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { "number(3)", ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "number(5)", ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "number(10)", ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "number(20)", ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + + { "float(126)", ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float(63)", ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "number(10,2)", ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { "interval day(2) to second(6)", ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date(7)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6) with local time zone", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + + { "blob", ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { "nvarchar2(255)", ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "char(36 char)", ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } + + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select username from all_users"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public List GetTablesByDatabase(params string[] database2) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + var database = database2?.ToArray(); + + if (database == null || database.Any() == false) + { + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + database = new[] { userUsers }; + } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); + var sql = string.Format(@" +select +a.owner || '.' || a.table_name, +a.owner, +a.table_name, +b.comments, +'TABLE' +from all_tables a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' +where a.owner in ({0})", databaseIn); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 999) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 999) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = string.Format(@" +select +a.owner || '.' || a.table_name, +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'Y' then 1 else 0 end, +nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), +b.comments +from all_tab_cols a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner in ({1}) and {0} +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var ds2 = new List(); + foreach (var row in ds) + { + var ds2item = new object[8]; + ds2item[0] = row[0]; + ds2item[1] = row[1]; + ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); + ds2item[4] = OdbcDamengCodeFirst.GetOracleSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); + ds2item[5] = string.Concat(row[7]) == "1"; + ds2item[6] = string.Concat(row[8]) == "1"; + ds2item[7] = string.Concat(row[9]); + ds2.Add(ds2item); + } + foreach (var row in ds2) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + if (max_length == 0) max_length = -1; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } + + sql = string.Format(@" +select +a.table_owner || '.' || a.table_name, +c.column_name, +c.index_name, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end, +0, +0, +case when c.descend = 'DESC' then 1 else 0 end, +c.column_position +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner +and a.table_name = c.table_name +and a.table_owner in ({1}) and {0} +and not exists(select 1 from all_constraints where index_name = a.index_name and constraint_type = 'P') +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]).Trim('"'); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + bool is_desc = string.Concat(row[6]) == "1"; + if (database.Length == 1) + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = string.Format(@" +select +a.owner || '.' || a.table_name, +c.column_name, +c.constraint_name, +b.owner || '.' || b.table_name, +1, +d.column_name + +-- a.owner 外键拥有者, +-- a.table_name 外键表, +-- c.column_name 外键列, +-- b.owner 主键拥有者, +-- b.table_name 主键表, +-- d.column_name 主键列, +-- c.constraint_name 外键名, +-- d.constraint_name 主键名 + +from +all_constraints a, +all_constraints b, +all_cons_columns c, --外键表 +all_cons_columns d --主键表 +where +a.r_constraint_name = b.constraint_name    +and a.constraint_type = 'R'    +and b.constraint_type = 'P'    +and a.r_owner = b.owner    +and a.constraint_name = c.constraint_name    +and b.constraint_name = d.constraint_name    +and a.owner = c.owner    +and a.table_name = c.table_name    +and b.owner = d.owner    +and b.table_name = d.table_name +and a.owner in ({1}) and {0} +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs new file mode 100644 index 00000000..f7bcad45 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -0,0 +1,464 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Dameng +{ + class OdbcDamengExpression : CommonExpression + { + + public OdbcDamengExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as number)"; + case "System.Char": return $"substr(to_char({getExp(operandExp)}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(operandExp)},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(operandExp)} as number)"; + case "System.Double": return $"cast({getExp(operandExp)} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as number)"; + case "System.Single": return $"cast({getExp(operandExp)} as number)"; + case "System.String": return $"to_char({getExp(operandExp)})"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; + case "System.Guid": return $"substr(to_char({getExp(operandExp)}), 1, 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Char": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(callExp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; + } + return null; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"to_char({getExp(callExp.Object)})" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + var left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "trunc(systimestamp)"; + case "MinValue": return "to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')"; + case "MaxValue": return "to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"trunc({left})"; + case "TimeOfDay": return $"(cast({left} as timestamp with time zone)-trunc({left}))"; + case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; + case "Day": return $"cast(to_char({left},'DD') as number)"; + case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; + case "Month": return $"cast(to_char({left},'MM') as number)"; + case "Year": return $"cast(to_char({left},'YYYY') as number)"; + case "Hour": return $"cast(to_char({left},'HH24') as number)"; + case "Minute": return $"cast(to_char({left},'MI') as number)"; + case "Second": return $"cast(to_char({left},'SS') as number)"; + case "Millisecond": return $"cast(to_char({left},'FF3') as number)"; + case "Ticks": return $"cast(to_char({left},'FF7') as number)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "numtodsinterval(0,'second')"; + case "MinValue": return "numtodsinterval(-233720368.5477580,'second')"; + case "MaxValue": return "numtodsinterval(233720368.5477580,'second')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"extract(day from {left})"; + case "Hours": return $"extract(hour from {left})"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Minutes": return $"extract(minute from {left})"; + case "Seconds": return $"floor(extract(second from {left}))"; + case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; + case "TotalDays": return $"extract(day from {left})"; + case "TotalHours": return $"(extract(day from {left})*24+extract(hour from {left}))"; + case "TotalMilliseconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*1000"; + case "TotalMinutes": return $"(extract(day from {left})*1440+extract(hour from {left})*60+extract(minute from {left}))"; + case "TotalSeconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(to_char({args0Value})||'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'||to_char({args0Value}))")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'||to_char({args0Value})||'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(instr({left}, {indexOfFindStr}, {locateArgs1}, 1)-1)"; + } + return $"(instr({left}, {indexOfFindStr}, 1, 1))-1"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceil({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": + if (exp.Arguments.Count > 1) return $"log({getExp(exp.Arguments[1])},{getExp(exp.Arguments[0])})"; + return $"log(2.7182818284590451,{getExp(exp.Arguments[0])})"; + case "Log10": return $"log(10,{getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + //case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0)"; + + case "Parse": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "AddDays": return $"({left}+{args1})"; + case "AddHours": return $"({left}+({args1})/24)"; + case "AddMilliseconds": return $"({left}+({args1})/86400000)"; + case "AddMinutes": return $"({left}+({args1})/1440)"; + case "AddMonths": return $"add_months({left},{args1})"; + case "AddSeconds": return $"({left}+({args1})/86400)"; + case "AddTicks": return $"({left}+({args1})/864000000000)"; + case "AddYears": return $"add_months({left},({args1})*12)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(cast({left} as timestamp with time zone)-{args1})"; + case "System.TimeSpan": return $"({left}-{args1})"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; + case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60 * 24},'second')"; + case "FromHours": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60},'second')"; + case "FromMilliseconds": return $"numtodsinterval(({getExp(exp.Arguments[0])})/1000,'second')"; + case "FromMinutes": return $"numtodsinterval(({getExp(exp.Arguments[0])})*60,'second')"; + case "FromSeconds": return $"numtodsinterval(({getExp(exp.Arguments[0])}),'second')"; + case "FromTicks": return $"numtodsinterval(({getExp(exp.Arguments[0])})/10000000,'second')"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(6))"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(6))"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; + case "ToString": return $"to_char({left})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + //case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToChar": return $"substr(to_char({getExp(exp.Arguments[0])}), 1, 1)"; + case "ToDateTime": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToString": return $"to_char({getExp(exp.Arguments[0])})"; + case "ToUInt16": + case "ToUInt32": + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as number)"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs new file mode 100644 index 00000000..40868691 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.Odbc.Dameng +{ + + public class OdbcDamengProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new OdbcDamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OdbcDamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OdbcDamengInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OdbcDamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OdbcDamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OdbcDamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OdbcDamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public OdbcDamengProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new OdbcDamengUtils(this); + this.InternalCommonExpression = new OdbcDamengExpression(this.InternalCommonUtils); + + this.Ado = new OdbcDamengAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); + + this.DbFirst = new OdbcDamengDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new OdbcDamengCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + + //this.Aop.AuditValue += new EventHandler((_, e) => + //{ + // if (e.Value == null && e.Column.Attribute.IsPrimary == false && e.Column.Attribute.IsIdentity == false) + // e.Value = Utils.GetDataReaderValue(e.Property.PropertyType.NullableTypeOrThis(), e.Column.Attribute.DbDefautValue); + //}); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + + ~OdbcDamengProvider() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs new file mode 100644 index 00000000..5d86bb05 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -0,0 +1,113 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.Dameng +{ + + class OdbcDamengUtils : CommonUtils + { + public OdbcDamengUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var dbtype = (OdbcType)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case OdbcType.Bit: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = OdbcType.Int; + break; + + case OdbcType.Char: + case OdbcType.NChar: + case OdbcType.VarChar: + case OdbcType.NVarChar: + case OdbcType.Text: + case OdbcType.NText: + value = string.Concat(value); + break; + } + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), OdbcType = dbtype, Value = value }; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + var dbtype = (OdbcType)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case OdbcType.Bit: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = OdbcType.Int; + break; + + case OdbcType.Char: + case OdbcType.NChar: + case OdbcType.VarChar: + case OdbcType.NVarChar: + case OdbcType.Text: + case OdbcType.NText: + value = string.Concat(value); + break; + } + var ret = new OdbcParameter { ParameterName = $":{name}", OdbcType = dbtype, Value = value }; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcOracle(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left} / {right})"; + public override string Now => "systimestamp"; + public override string NowUtc => "getutcdate"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("rawtohex('0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.Append("')").ToString(); + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs index ec0fd1b2..46764a4c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs @@ -45,4 +45,13 @@ /// public static string FormatOdbc(this string that, params object[] args) => _odbcAdo.Addslashes(that, args); static FreeSql.Odbc.Default.OdbcAdo _odbcAdo = new FreeSql.Odbc.Default.OdbcAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatOdbcDameng(this string that, params object[] args) => _odbcDamengAdo.Addslashes(that, args); + static FreeSql.Odbc.Dameng.OdbcDamengAdo _odbcDamengAdo = new FreeSql.Odbc.Dameng.OdbcDamengAdo(); } diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index ff6da1be..7fdff83f 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -400,7 +400,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam dropSequence(seqname); if (seqcol.Item3) { - var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_columns where owner={0} and table_name={1} and column_name={2}", tbname[0], tbname[1], colname2)) == null ? 1 : + var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_columns where owner={0} and table_name={1} and column_name={2}", tbname[0], tbname[1], seqcol.Item1.Attribute.Name)) == null ? 1 : _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}"); sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n"); sb.Append("execute immediate 'CREATE OR REPLACE TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 6cdb4ca2..1f709c10 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -241,7 +241,7 @@ isnull(e.name,'') + '.' + isnull(d.name,'') else cast(a.max_length as varchar) end + ')' when b.name in ('Numeric', 'Decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')' else '' end as 'SqlType' -,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'Comment' +,( select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'Comment' {0} a inner join sys.types b on b.user_type_id = a.user_type_id left join sys.tables d on d.object_id = a.object_id diff --git a/readme.md b/readme.md index 26009b43..159a2d40 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; - [x] 支持 同步/异步数据库操作方法; - [x] 支持 读写分离、分表分库,租户设计,过滤器,乐观锁; -- [x] 支持 多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite; +- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库; | | | | - | - | From 29fd0a2314f84c7a3f2fa16abe4279cff6093ccf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Dec 2019 21:34:25 +0800 Subject: [PATCH 0313/1029] ## v0.12.13 #152 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 9b4e314c..2e241e63 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.12 + 0.12.13 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 7f29c7eb..8043e0df 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index aacc83e9..5911ec6b 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.12 + 0.12.13 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index d49f6cdd..c16ec4de 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index ee86e497..d18c8aba 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 562a44aa..116366b3 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 27765e16..c01e0a42 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index abf36ae6..2f7698e5 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index bd39ad01..3cf12f59 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b4e7a98f..9f37d9b1 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 25ee1105..5953db93 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 37fb148848720390fdb749a35c34e9fb850eeb60 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Dec 2019 08:29:26 +0800 Subject: [PATCH 0314/1029] ## v0.12.13 --- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 7e5ef6e5..cd28e7e2 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6edf7cd3..d26a9212 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.12 + 0.12.13 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. From 68c3dbc9b8be0ffefec50a597506b82f87ccc9d1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Dec 2019 08:34:08 +0800 Subject: [PATCH 0315/1029] update --- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- readme.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c01e0a42..fbc5d5b4 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -5,7 +5,7 @@ 0.12.13 true YeXiangQin - FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)} 专用访问实现,以及通用 Odbc 访问所有数据库 + FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git diff --git a/readme.md b/readme.md index 159a2d40..5bc30cc7 100644 --- a/readme.md +++ b/readme.md @@ -84,6 +84,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | DataType.OdbcSqlServer | Driver={SQL Server};Server=.;Persist Security Info=False; Trusted_Connection=Yes;Integrated Security=True; DATABASE=freesqlTest_odbc; Pooling=true;Min Pool Size=1 | | DataType.OdbcOracle | Driver={Oracle in XE};Server=//127.0.0.1:1521/XE; Persist Security Info=False; Trusted_Connection=Yes;UID=odbc1;PWD=123456; Min Pool Size=1 | | DataType.OdbcPostgreSQL | Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10; Port=5432;UID=postgres;PWD=123456; Database=tedb_odbc;Pooling=true;Min Pool Size=1 | +| DataType.OdbcDameng (达梦) | Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236; Persist Security Info=False; Trusted_Connection=Yes; UID=USER1;PWD=123456789 | | DataType.Odbc | Driver={SQL Server};Server=.;Persist Security Info=False; Trusted_Connection=Yes;Integrated Security=True; DATABASE=freesqlTest_odbc; Pooling=true;Min pool size=1 |

From 39b18217095e3385a223831c63649d84527c8437 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Dec 2019 11:11:58 +0800 Subject: [PATCH 0316/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Select=20AsTable=20=E6=9E=90=E6=9E=84=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=8F=AF=E8=83=BD=E4=BA=A7=E7=94=9F=20bug?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommonProvider/SelectProvider/Select0Provider.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 4db3b260..2a3e034c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -102,7 +102,7 @@ namespace FreeSql.Internal.CommonProvider _multiTables.Add(from._tables[a]); } } - toType.GetField("_tableRules", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._tableRules); + toType.GetField("_tableRules", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List>(from._tableRules.ToArray())); toType.GetField("_aliasRule", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._aliasRule); toType.GetField("_join", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._join.ToString())); //toType.GetField("_orm", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orm); @@ -111,15 +111,15 @@ namespace FreeSql.Internal.CommonProvider toType.GetField("_transaction", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._transaction); toType.GetField("_connection", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._connection); toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList); - toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToList); + toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List>(from._includeToList.ToArray())); #if net40 #else - toType.GetField("_includeToListAsync", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._includeToListAsync); + toType.GetField("_includeToListAsync", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List>(from._includeToListAsync.ToArray())); #endif toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); - toType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereCascadeExpression); - toType.GetField("_whereGlobalFilter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._whereGlobalFilter); + toType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._whereCascadeExpression.ToArray())); + toType.GetField("_whereGlobalFilter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._whereGlobalFilter.ToArray())); } public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) From 933c3a1035149b20eafe95d3e1b4bac993146038 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Dec 2019 11:16:43 +0800 Subject: [PATCH 0317/1029] ## v0.12.15 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2e241e63..3300a9dd 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.13 + 0.12.15 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index cd28e7e2..77f3aa34 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index d26a9212..1572f025 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8043e0df..45058a8b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据

+ + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5911ec6b..94f72d48 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.13 + 0.12.15 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c16ec4de..366637a8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d18c8aba..d4481756 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 116366b3..395c8919 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index fbc5d5b4..1e0a70f6 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2f7698e5..d0074e59 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 3cf12f59..ae6e3952 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9f37d9b1..139b611a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5953db93..9cd4c1bc 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.13 + 0.12.15 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From d8fd20b8f94e1494b3ef285d8b27e0b18608ee86 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Dec 2019 13:27:37 +0800 Subject: [PATCH 0318/1029] ## v0.12.15 --- .../Dameng/Curd/DamengSelectTest.cs | 2 +- .../Dameng/DamengAdo/DamengAdoTest.cs | 12 +++---- .../Dameng/MapType/BoolNullableTest.cs | 36 +++++++++---------- .../Dameng/MapType/BoolTest.cs | 36 +++++++++---------- .../Dameng/MapType/DateTimeOffSetTest.cs | 2 +- .../Dameng/MapType/EnumTest.cs | 8 ++--- .../Dameng/MapType/ToStringTest.cs | 20 +++++------ 7 files changed, 58 insertions(+), 58 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index baa301f6..e3c76774 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -1338,7 +1338,7 @@ namespace FreeSql.Tests.Odbc.Dameng // --- Select --- - new List(new[] { song1, song2, song3 }).IncludeMany(g.oracle, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + new List(new[] { song1, song2, song3 }).IncludeMany(g.dameng, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); var asongs1 = g.dameng.Select() .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs index a685b04d..408d4ee4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs @@ -9,13 +9,13 @@ namespace FreeSql.Tests.Odbc.Dameng [Fact] public void Pool() { - var t1 = g.oracle.Ado.MasterPool.StatisticsFullily; + var t1 = g.dameng.Ado.MasterPool.StatisticsFullily; } [Fact] public void SlavePools() { - var t2 = g.oracle.Ado.SlavePools.Count; + var t2 = g.dameng.Ado.SlavePools.Count; } [Fact] @@ -43,17 +43,17 @@ namespace FreeSql.Tests.Odbc.Dameng public void Query() { - var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + var t3 = g.dameng.Ado.Query("select * from \"TB_TOPIC\""); - var t4 = g.oracle.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + var t4 = g.dameng.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); - var t5 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + var t5 = g.dameng.Ado.Query("select * from \"TB_TOPIC\""); } [Fact] public void QueryMultipline() { - //var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + //var t3 = g.dameng.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); } class xxx diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolNullableTest.cs index 4e32a232..d830e061 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolNullableTest.cs @@ -63,7 +63,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Bool() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); @@ -145,7 +145,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void SByte() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); @@ -227,7 +227,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void SByteNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); @@ -309,7 +309,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Short() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); @@ -391,7 +391,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void ShortNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); @@ -473,7 +473,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Int() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); @@ -555,7 +555,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void IntNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); @@ -637,7 +637,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Long() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); @@ -719,7 +719,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void LongNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); @@ -802,7 +802,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Byte() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); @@ -884,7 +884,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void ByteNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); @@ -966,7 +966,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void UShort() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); @@ -1048,7 +1048,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void UShortNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); @@ -1130,7 +1130,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void UInt() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); @@ -1212,7 +1212,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void UIntNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); @@ -1294,7 +1294,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void ULong() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); @@ -1376,7 +1376,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void ULongNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); @@ -1480,7 +1480,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void String() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolNullableMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolTest.cs index 60f57d11..474935ae 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/BoolTest.cs @@ -65,7 +65,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void BoolNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); @@ -121,7 +121,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void SByte() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); @@ -177,7 +177,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void SByteNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); @@ -233,7 +233,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Short() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); @@ -289,7 +289,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void ShortNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); @@ -345,7 +345,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Int() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); @@ -401,7 +401,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void IntNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); @@ -457,7 +457,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Long() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); @@ -513,7 +513,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void LongNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); @@ -570,7 +570,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Byte() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); @@ -626,7 +626,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void ByteNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); @@ -682,7 +682,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void UShort() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); @@ -738,7 +738,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void UShortNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); @@ -794,7 +794,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void UInt() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); @@ -850,7 +850,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void UIntNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); @@ -906,7 +906,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void ULong() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); @@ -962,7 +962,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void ULongNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); @@ -1040,7 +1040,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void String() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new BoolMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/DateTimeOffSetTest.cs index 27e703ae..0a31d192 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/DateTimeOffSetTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/DateTimeOffSetTest.cs @@ -20,7 +20,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void DateTimeToDateTimeOffSet() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/EnumTest.cs index ba996ccf..a5f708b5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/EnumTest.cs @@ -26,7 +26,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void EnumToString() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new EnumTestMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); @@ -83,7 +83,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void EnumNullableToString() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new EnumTestMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); @@ -144,7 +144,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void EnumToInt() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new EnumTestMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); @@ -201,7 +201,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void EnumNullableToInt() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new EnumTestMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/ToStringTest.cs index 55f3b877..9642e47a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/MapType/ToStringTest.cs @@ -41,7 +41,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Enum1() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); @@ -98,7 +98,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void EnumNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); @@ -158,7 +158,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void BigInteger1() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); @@ -215,7 +215,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void BigIntegerNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); @@ -275,7 +275,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void TimeSpan1() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); @@ -316,7 +316,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void TimeSpanNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); @@ -371,7 +371,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void DateTime1() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); @@ -412,7 +412,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void DateTimeNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id).First(); @@ -468,7 +468,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void Guid1() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); @@ -512,7 +512,7 @@ namespace FreeSql.Tests.Odbc.DamengMapType public void GuidNullable() { //insert - var orm = g.oracle; + var orm = g.dameng; var item = new ToStringMap { }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); From 82376eecb4944b458220970da023ab9179af661e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Dec 2019 16:35:11 +0800 Subject: [PATCH 0319/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ToList((a,b)?= =?UTF-8?q?=20=3D>=20new=20{=20a,=20b=20})=20=E5=BD=93=20b=20=E4=B8=BA=20n?= =?UTF-8?q?ull=20=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C=E5=BA=94=E8=AF=A5?= =?UTF-8?q?=E6=95=B4=E4=B8=AA=20b=20=E4=B8=BA=20null=EF=BC=9B(=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E5=B1=9E=E6=80=A7=E6=B2=A1=E8=BF=99=E4=B8=AA=E9=97=AE?= =?UTF-8?q?=E9=A2=98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 32 +++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 15 ++++++--- .../SelectProvider/Select0Provider.cs | 14 ++++---- .../Internal/Model/ReadAnonymousTypeInfo.cs | 1 + 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 7b687258..3cb9aa53 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -227,9 +227,41 @@ namespace FreeSql.Tests public decimal rowstate { get; set; } } + public class otot1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + + public otot2 t2 { get; set; } + } + public class otot2 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + } + [Fact] public void Test02() { + g.sqlite.Insert(new otot1 { name = "otot1_name1" }).ExecuteAffrows(); + + var otolst1 = g.sqlite.Select() + .LeftJoin(a => a.id == a.t2.id) + .ToList(); + + var otolst2 = g.sqlite.Select() + .LeftJoin((a, b) => a.id == b.id) + .ToList((a, b) => new + { + a, + b + }); + + + + var testcf = g.sqlite.CodeFirst.GetComparisonDDLStatements(typeof(dfDto2), "main.test2"); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b8fdfa9c..e7d7bd56 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -80,6 +80,7 @@ namespace FreeSql.Internal var tb = parent.Table = map.First().Table.Table; parent.Consturctor = tb.Type.GetConstructor(new Type[0]); parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + parent.IsEntity = true; for (var idx = 0; idx < map.Count; idx++) { var child = new ReadAnonymousTypeInfo @@ -220,7 +221,7 @@ namespace FreeSql.Internal if (index >= 0) field.Append(" as").Append(++index); return false; } - public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead) + public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue) { if (parent.Childs.Any() == false) { @@ -232,6 +233,7 @@ namespace FreeSql.Internal return Utils.GetDataReaderValue(parent.CsType, null); } object objval = dr.GetValue(++index); + if (dbValue != null) dbValue.DbValue = objval == DBNull.Value ? null : objval; if (parent.CsType != parent.MapType) objval = Utils.GetDataReaderValue(parent.MapType, objval); objval = Utils.GetDataReaderValue(parent.CsType, objval); @@ -245,7 +247,7 @@ namespace FreeSql.Internal var args = new object[parent.Childs.Count]; for (var a = 0; a < parent.Childs.Count; a++) { - var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead); + var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead, null); if (notRead == false) args[a] = objval; } @@ -256,8 +258,9 @@ namespace FreeSql.Internal for (var b = 0; b < parent.Childs.Count; b++) { var prop = parent.Childs[b].Property; - var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead); - if (isnull == false && objval == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) + var dbval = parent.IsEntity ? new ReadAnonymousDbValueRef() : null; + var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval); + if (isnull == false && parent.IsEntity && dbval.DbValue == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) isnull = true; if (isnull == false && prop.CanWrite) prop.SetValue(ret, objval, null); @@ -266,6 +269,10 @@ namespace FreeSql.Internal } return null; } + public class ReadAnonymousDbValueRef + { + public object DbValue { get; set; } + } public ColumnInfo SearchColumnByField(List _tables, TableInfo currentTable, string field) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 2a3e034c..ad4c1ee6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -352,7 +352,7 @@ namespace FreeSql.Internal.CommonProvider { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); } }, CommandType.Text, sql, dbParms); } @@ -405,7 +405,7 @@ namespace FreeSql.Internal.CommonProvider { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); } if (chunkSize > 0 && chunkSize == ret.Count) { @@ -487,10 +487,10 @@ namespace FreeSql.Internal.CommonProvider _orm.Ado.ExecuteReader(_connection, _transaction, dr => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false, null)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false, null)); }, CommandType.Text, sql, dbParms); } catch (Exception ex) @@ -1151,7 +1151,7 @@ namespace FreeSql.Internal.CommonProvider { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); } return Task.FromResult(false); }, CommandType.Text, sql, dbParms); @@ -1214,10 +1214,10 @@ namespace FreeSql.Internal.CommonProvider await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false, null)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false, null)); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index d3c1fb3a..3ca01e00 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -16,6 +16,7 @@ namespace FreeSql.Internal.Model public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; } public List Childs = new List(); public TableInfo Table { get; set; } + public bool IsEntity { get; set; } } public enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties } } From 9bd815fe3504ef97a48b60fbfd34e98a0fe7cf98 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 10 Dec 2019 16:36:08 +0800 Subject: [PATCH 0320/1029] ## v0.12.16 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 3300a9dd..7a3c55b9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.15 + 0.12.16 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 77f3aa34..eac9e815 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 1572f025..b71c5b45 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 45058a8b..7ca5a286 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 94f72d48..c901737c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.15 + 0.12.16 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 366637a8..2547561e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d4481756..51c7276d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 395c8919..59371ace 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 1e0a70f6..5764bb65 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d0074e59..abfcffb3 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ae6e3952..89cf5943 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 139b611a..4aabd09b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9cd4c1bc..d4ff2915 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.15 + 0.12.16 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 3a889504fb66cb7cfc0ab19f2f0ccb5f9c1a2685 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Dec 2019 22:11:27 +0800 Subject: [PATCH 0321/1029] =?UTF-8?q?=E5=B0=86=E7=A4=BA=E4=BE=8B=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=B1=BB=E5=9E=8B=E5=8D=87=E7=BA=A7=E4=B8=BA=20.net?= =?UTF-8?q?=20core=203.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 2 + Examples/base_entity/base_entity.csproj | 2 +- Examples/benchmarker/Program.cs | 3 - Examples/benchmarker/benchmarker.csproj | 8 +-- Examples/dbcontext_01/Startup.cs | 30 ++------- Examples/dbcontext_01/dbcontext_01.csproj | 7 +- .../FreeSqlExtensions/CodeFirstExtensions.cs | 2 +- Examples/efcore_to_freesql/Startup.cs | 7 +- .../efcore_to_freesql.csproj | 5 +- Examples/orm_vs/orm_vs.csproj | 2 +- Examples/orm_vs_net40/orm_vs_net40.csproj | 2 +- Examples/repository_01/Startup.cs | 31 ++------- Examples/repository_01/repository_01.csproj | 10 ++- Examples/restful/Startup.cs | 28 ++------ Examples/restful/restful.csproj | 8 +-- .../FreeSql.Tests.DbContext.csproj | 2 +- .../FreeSql.Tests.PerformanceTests.csproj | 2 +- ...eeSql.Tests.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Tests.Provider.Odbc.csproj | 2 +- .../FreeSql.Tests/FreeSql.Tests.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 64 +++++++++++++++++++ 21 files changed, 104 insertions(+), 117 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/UnitTest3.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 798ea5c3..6f43a2e8 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -4,6 +4,7 @@ using FreeSql.Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; +using System.Data.SqlClient; using System.Diagnostics; using System.Linq.Expressions; using System.Threading; @@ -35,6 +36,7 @@ namespace base_entity static void Main(string[] args) { + #region 初始化 IFreeSql var fsql = new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index 2df960d9..7289cf02 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -11,7 +11,7 @@ - + diff --git a/Examples/benchmarker/Program.cs b/Examples/benchmarker/Program.cs index c7f00f27..d4fa9473 100644 --- a/Examples/benchmarker/Program.cs +++ b/Examples/benchmarker/Program.cs @@ -53,7 +53,6 @@ namespace FreeSql.Bechmarker } } - [CoreJob] [RPlotExporter, RankColumn] public class OrmVsInsert { @@ -111,7 +110,6 @@ namespace FreeSql.Bechmarker } } - [CoreJob] [RPlotExporter, RankColumn] public class OrmVsUpdate { @@ -144,7 +142,6 @@ namespace FreeSql.Bechmarker } } - [CoreJob] [RPlotExporter, RankColumn] public class OrmVsSelect { diff --git a/Examples/benchmarker/benchmarker.csproj b/Examples/benchmarker/benchmarker.csproj index 958667bd..bcc5dc7d 100644 --- a/Examples/benchmarker/benchmarker.csproj +++ b/Examples/benchmarker/benchmarker.csproj @@ -2,13 +2,13 @@ Exe - netcoreapp2.1 + netcoreapp3.1 - - - + + + diff --git a/Examples/dbcontext_01/Startup.cs b/Examples/dbcontext_01/Startup.cs index 181e9068..777f8be3 100644 --- a/Examples/dbcontext_01/Startup.cs +++ b/Examples/dbcontext_01/Startup.cs @@ -1,11 +1,8 @@ using FreeSql; -using FreeSql.DataAnnotations; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Swashbuckle.AspNetCore.Swagger; using System; using System.Diagnostics; using System.Linq; @@ -73,18 +70,7 @@ namespace dbcontext_01 public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - services.AddSwaggerGen(options => - { - options.SwaggerDoc("v1", new Info - { - Version = "v1", - Title = "FreeSql.DbContext API" - }); - //options.IncludeXmlComments(xmlPath); - }); - - + services.AddControllersWithViews(); services.AddSingleton(Fsql); services.AddSingleton>(Fsql2); @@ -96,24 +82,16 @@ namespace dbcontext_01 var sql3 = Fsql.Update(1).Set(a => a.Create_time.Value.AddHours(1)).ToSql(); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Console.OutputEncoding = Encoding.GetEncoding("GB2312"); Console.InputEncoding = Encoding.GetEncoding("GB2312"); - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); app.UseDeveloperExceptionPage(); - app.UseMvc(); - - app.UseSwagger(); - app.UseSwaggerUI(c => - { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); - }); + app.UseRouting(); + app.UseEndpoints(a => a.MapControllers()); } } } diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj index a90702b5..516f4a05 100644 --- a/Examples/dbcontext_01/dbcontext_01.csproj +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -1,15 +1,12 @@  - netcoreapp2.1 + netcoreapp3.1 InProcess - - - - + diff --git a/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs b/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs index 1c6d5e68..096f5b9f 100644 --- a/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs +++ b/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs @@ -47,7 +47,7 @@ public static class CodeFirstExtensions ); //可空 - freeProp.IsNullable(prop.AfterSaveBehavior != PropertySaveBehavior.Throw); + freeProp.IsNullable(prop.GetAfterSaveBehavior() != PropertySaveBehavior.Throw); //类型 var relationalColumnType = prop.FindAnnotation("Relational:ColumnType"); diff --git a/Examples/efcore_to_freesql/Startup.cs b/Examples/efcore_to_freesql/Startup.cs index 0e9eea21..0fabf866 100644 --- a/Examples/efcore_to_freesql/Startup.cs +++ b/Examples/efcore_to_freesql/Startup.cs @@ -68,13 +68,10 @@ namespace efcore_to_freesql services.AddMvc(); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app) { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - app.UseDeveloperExceptionPage(); - app.UseMvc(); + app.UseEndpoints(a => a.MapControllers()); } } } diff --git a/Examples/efcore_to_freesql/efcore_to_freesql.csproj b/Examples/efcore_to_freesql/efcore_to_freesql.csproj index 4516a3f9..3769825e 100644 --- a/Examples/efcore_to_freesql/efcore_to_freesql.csproj +++ b/Examples/efcore_to_freesql/efcore_to_freesql.csproj @@ -1,13 +1,12 @@  - netcoreapp2.1 + netcoreapp3.1 InProcess - - + diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index a36447e3..4e6eb813 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1 + netcoreapp3.1 diff --git a/Examples/orm_vs_net40/orm_vs_net40.csproj b/Examples/orm_vs_net40/orm_vs_net40.csproj index 581a3ccb..15ca534f 100644 --- a/Examples/orm_vs_net40/orm_vs_net40.csproj +++ b/Examples/orm_vs_net40/orm_vs_net40.csproj @@ -60,7 +60,7 @@ - 12.0.2 + 12.0.3 diff --git a/Examples/repository_01/Startup.cs b/Examples/repository_01/Startup.cs index 24b5b025..65bb13c2 100644 --- a/Examples/repository_01/Startup.cs +++ b/Examples/repository_01/Startup.cs @@ -1,16 +1,11 @@ using FreeSql; using FreeSql.DataAnnotations; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using restful.Entitys; -using Swashbuckle.AspNetCore.Swagger; using System; using System.Diagnostics; -using System.Linq; using System.Text; namespace repository_01 @@ -61,17 +56,7 @@ namespace repository_01 //services.AddTransient(s => s.) - services.AddMvc(); - services.AddSwaggerGen(options => - { - options.SwaggerDoc("v1", new Info - { - Version = "v1", - Title = "FreeSql.RESTful API" - }); - //options.IncludeXmlComments(xmlPath); - }); - + services.AddControllersWithViews(); services.AddSingleton(Fsql); services.AddFreeRepository(filter => @@ -82,24 +67,16 @@ namespace repository_01 }, this.GetType().Assembly); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Console.OutputEncoding = Encoding.GetEncoding("GB2312"); Console.InputEncoding = Encoding.GetEncoding("GB2312"); - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); app.UseDeveloperExceptionPage(); - app.UseMvc(); - - app.UseSwagger(); - app.UseSwaggerUI(c => - { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); - }); + app.UseRouting(); + app.UseEndpoints(a => a.MapControllers()); } } diff --git a/Examples/repository_01/repository_01.csproj b/Examples/repository_01/repository_01.csproj index 4c63f521..fce8cda4 100644 --- a/Examples/repository_01/repository_01.csproj +++ b/Examples/repository_01/repository_01.csproj @@ -1,20 +1,18 @@  - netcoreapp2.1 + netcoreapp3.1 InProcess - - - - - + + + diff --git a/Examples/restful/Startup.cs b/Examples/restful/Startup.cs index 89e8977e..6079ae39 100644 --- a/Examples/restful/Startup.cs +++ b/Examples/restful/Startup.cs @@ -1,9 +1,7 @@ using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Swashbuckle.AspNetCore.Swagger; using System; using System.Text; @@ -41,37 +39,19 @@ namespace restful public void ConfigureServices(IServiceCollection services) { services.AddSingleton(Fsql); - - services.AddMvc(); - services.AddSwaggerGen(options => - { - options.SwaggerDoc("v1", new Info - { - Version = "v1", - Title = "FreeSql.RESTful API" - }); - //options.IncludeXmlComments(xmlPath); - }); + services.AddControllersWithViews(); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Console.OutputEncoding = Encoding.GetEncoding("GB2312"); Console.InputEncoding = Encoding.GetEncoding("GB2312"); - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); app.UseDeveloperExceptionPage(); - app.UseMvc(); - - app.UseSwagger(); - app.UseSwaggerUI(c => - { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); - }); + app.UseRouting(); + app.UseEndpoints(a => a.MapControllers()); } } } diff --git a/Examples/restful/restful.csproj b/Examples/restful/restful.csproj index 0963a30d..67461b06 100644 --- a/Examples/restful/restful.csproj +++ b/Examples/restful/restful.csproj @@ -1,19 +1,17 @@  - netcoreapp2.1 + netcoreapp3.1 InProcess - - - - + + diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj index 761bebcf..bda7efbb 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 false diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj index afdd5535..a3e53b3c 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 false diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj index 314fab71..bb1fc44e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 false diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj index 3e1c4df1..3ece19a4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 false diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 364e968d..c895f7f6 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 false diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs new file mode 100644 index 00000000..4a6d3519 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -0,0 +1,64 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using System.Data.SqlClient; +using kwlib; +using System.Diagnostics; + +namespace FreeSql.Tests +{ + public class UnitTest3 + { + + [Fact] + public void Test03() + { + //using (var conn = new SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=webchat-abc;Pooling=true;Max Pool Size=13")) + //{ + // conn.Open(); + // conn.Close(); + //} + + //using (var fsql = new FreeSql.FreeSqlBuilder() + // .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=webchat-abc;Pooling=true;Max Pool Size=13") + // .UseAutoSyncStructure(true) + // //.UseGenerateCommandParameterWithLambda(true) + // .UseMonitorCommand( + // cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + // //, (cmd, traceLog) => Console.WriteLine(traceLog) + // ) + // .UseLazyLoading(true) + // .Build()) + //{ + // fsql.Select().ToList(); + //} + + + } + + class ut3_t1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + class ut3_t2 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + } + +} From 7797edebf175c40d0c70fc2efb215a4ac181beb1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Dec 2019 22:38:41 +0800 Subject: [PATCH 0322/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Gene?= =?UTF-8?q?rator=20=E5=AE=9E=E4=BD=93=E7=B1=BB=E7=94=9F=E6=88=90=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 234 +++++++++++++++++ .../FreeSql.Generator.csproj | 33 +++ Extensions/FreeSql.Generator/Program.cs | 22 ++ .../FreeSql.Generator/RazorContentManager.cs | 246 ++++++++++++++++++ Extensions/FreeSql.Generator/RazorModel.cs | 145 +++++++++++ FreeSql.sln | 15 ++ readme.md | 8 +- 7 files changed, 696 insertions(+), 7 deletions(-) create mode 100644 Extensions/FreeSql.Generator/ConsoleApp.cs create mode 100644 Extensions/FreeSql.Generator/FreeSql.Generator.csproj create mode 100644 Extensions/FreeSql.Generator/Program.cs create mode 100644 Extensions/FreeSql.Generator/RazorContentManager.cs create mode 100644 Extensions/FreeSql.Generator/RazorModel.cs diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs new file mode 100644 index 00000000..4e456fc5 --- /dev/null +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -0,0 +1,234 @@ +using RazorEngine.Templating; +using System; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using Console = Colorful.Console; + +namespace FreeSql.Generator +{ + class ConsoleApp + { + string ArgsRazorRaw { get; } + string ArgsRazor { get; } + bool[] ArgsNameOptions { get; } + string ArgsNameSpace { get; } + DataType ArgsDbType { get; } + string ArgsConnectionString { get; } + string ArgsFileName { get; } + string ArgsOutput { get; } + + public ConsoleApp(string[] args, ManualResetEvent wait) + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + var gb2312 = Encoding.GetEncoding("GB2312"); + if (gb2312 != null) + { + try + { + Console.OutputEncoding = gb2312; + Console.InputEncoding = gb2312; + } + catch { } + } + + //var ntjson = Assembly.LoadFile(@"C:\Users\28810\Desktop\testfreesql\bin\Debug\netcoreapp2.2\publish\testfreesql.dll"); + + //using (var gen = new Generator(new GeneratorOptions())) + //{ + // gen.TraceLog = log => Console.WriteFormatted(log + "\r\n", Color.DarkGray); + // gen.Build(ArgsOutput, new[] { typeof(ojbk.Entities.AuthRole) }, false); + //} + + var version = "v" + string.Join(".", typeof(ConsoleApp).Assembly.GetName().Version.ToString().Split('.').Where((a, b) => b <= 2)); + Console.WriteAscii(" FreeSql", Color.Violet); + Console.WriteFormatted(@" + # Github # {0} {1} +", Color.SlateGray, +new Colorful.Formatter("https://github.com/2881099/FreeSql", Color.DeepSkyBlue), +new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetName().Version.ToString().Split('.').Where((a, b) => b <= 2)), Color.SlateGray)); + + ArgsOutput = Directory.GetCurrentDirectory(); + ArgsFileName = "{name}.cs"; + string args0 = args[0].Trim().ToLower(); + if (args[0] == "?" || args0 == "--help" || args0 == "-help") + { + + Console.WriteFormatted(@" + {0} + + 更新工具:dotnet tool update -g FreeSql.Generator + + + # 快速开始 # + + > {1} {2} 1 {3} 0,0,0,0 {4} MyProject {5} ""MySql,Data Source=127.0.0.1;..."" + + -Razor 1 * 选择模板:实体类+特性 + + -Razor 2 * 选择模板:实体类+特性+导航属性 + + -Razor ""d:\diy.cshtml"" * 自定义模板文件 + + -NameOptions * 总共4个布尔值,分别对应: + # 首字母大写 + # 首字母大写,其他小写 + # 全部小写 + # 下划线转驼峰 + + -NameSpace * 命名空间 + + -DB ""{6},Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=数据库;Charset=utf8;SslMode=none;Max pool size=2"" + + -DB ""{7},Data Source=.;Integrated Security=True;Initial Catalog=数据库;Pooling=true;Max Pool Size=2"" + + -DB ""{8},Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=数据库;Pooling=true;Maximum Pool Size=2"" + + -DB ""{9},user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2"" + + -DB ""{10},Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789;Max pool size=2"" + {10} 是国产达梦数据库,需要使用 ODBC 连接 + + -FileName 文件名,默认:{name}.cs + + -Output 保存路径,默认为当前 shell 所在目录 + {11} + +", Color.SlateGray, +new Colorful.Formatter("使用 FreeSql 快速生成数据库的实体类", Color.SlateGray), +new Colorful.Formatter("FreeSql.Generator", Color.White), +new Colorful.Formatter("-Razor", Color.ForestGreen), +new Colorful.Formatter("-NameOptions", Color.ForestGreen), +new Colorful.Formatter("-NameSpace", Color.ForestGreen), +new Colorful.Formatter("-DB", Color.ForestGreen), +new Colorful.Formatter("MySql", Color.Yellow), +new Colorful.Formatter("SqlServer", Color.Yellow), +new Colorful.Formatter("PostgreSQL", Color.Yellow), +new Colorful.Formatter("Oracle", Color.Yellow), +new Colorful.Formatter("OdbcDameng", Color.Yellow), +new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新所有实体类", Color.ForestGreen) +); + wait.Set(); + return; + } + for (int a = 0; a < args.Length; a++) + { + switch (args[a]) + { + case "-Razor": + ArgsRazorRaw = args[a + 1].Trim(); + switch (ArgsRazorRaw) + { + case "1": ArgsRazor = RazorContentManager.实体类_特性_cshtml; break; + case "2": ArgsRazor = RazorContentManager.实体类_特性_导航属性_cshtml; break; + default: ArgsRazor = File.ReadAllText(args[a + 1]); break; + } + a++; + break; + + case "-NameOptions": + ArgsNameOptions = args[a + 1].Split(',').Select(opt => opt == "1").ToArray(); + if (ArgsNameOptions.Length != 4) throw new ArgumentException("-NameOptions 参数错误,格式为:0,0,0,0"); + a++; + break; + case "-NameSpace": + ArgsNameSpace = args[a + 1]; + a++; + break; + case "-DB": + var dbargs = args[a + 1].Split(',', 2); + if (dbargs.Length != 2) throw new ArgumentException("-DB 参数错误,格式为:MySql,ConnectionString"); + switch (dbargs[0].Trim().ToLower()) + { + case "mysql": ArgsDbType = DataType.MySql; break; + case "sqlserver": ArgsDbType = DataType.SqlServer; break; + case "postgresql": ArgsDbType = DataType.PostgreSQL; break; + case "oracle": ArgsDbType = DataType.Oracle; break; + case "odbcdameng": ArgsDbType = DataType.OdbcDameng; break; + default: throw new ArgumentException($"-DB 参数错误,不支持的类型:{dbargs[0]}"); + } + ArgsConnectionString = dbargs[1].Trim(); + if (string.IsNullOrEmpty(ArgsConnectionString)) throw new ArgumentException($"-DB 参数错误,未提供 ConnectionString"); + a++; + break; + case "-FileName": + ArgsFileName = args[a + 1]; + a++; + break; + case "-Output": + ArgsOutput = args[a + 1]; + a++; + break; + } + } + + ArgsOutput = ArgsOutput.Trim().TrimEnd('/', '\\'); + ArgsOutput += ArgsOutput.Contains("\\") ? "\\" : "/"; + if (!Directory.Exists(ArgsOutput)) + Directory.CreateDirectory(ArgsOutput); + + RazorEngine.Engine.Razor = RazorEngineService.Create(new RazorEngine.Configuration.TemplateServiceConfiguration + { + EncodedStringFactory = new RazorEngine.Text.RawStringFactory() // Raw string encoding. + }); + var razorId = Guid.NewGuid().ToString("N"); + RazorEngine.Engine.Razor.Compile(ArgsRazor, razorId); + + var outputCounter = 0; + using (IFreeSql fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(ArgsDbType, ArgsConnectionString) + .UseAutoSyncStructure(false) + .UseMonitorCommand(cmd => Console.WriteFormatted(cmd.CommandText + "\r\n", Color.SlateGray)) + .Build()) + { + var tables = fsql.DbFirst.GetTablesByDatabase(); + var outputTables = tables; + + + //开始生成操作 + foreach (var table in outputTables) + { + var sw = new StringWriter(); + var model = new RazorModel(fsql, ArgsNameSpace, ArgsNameOptions, tables, table); + RazorEngine.Engine.Razor.Run(razorId, sw, null, model); + + StringBuilder plus = new StringBuilder(); + plus.AppendLine("//------------------------------------------------------------------------------"); + plus.AppendLine("// "); + plus.AppendLine("// 此代码由工具 FreeSql.Generator 生成。"); + plus.AppendLine("// 运行时版本:" + Environment.Version.ToString()); + plus.AppendLine("// Website: https://github.com/2881099/FreeSql"); + plus.AppendLine("// 对此文件的更改可能会导致不正确的行为,并且如果"); + plus.AppendLine("// 重新生成代码,这些更改将会丢失。"); + plus.AppendLine("// "); + plus.AppendLine("//------------------------------------------------------------------------------"); + plus.Append(sw.ToString()); + plus.AppendLine(); + + var outputFile = $"{ArgsOutput}{ArgsFileName.Replace("{name}", model.GetCsName(table.Name))}"; + File.WriteAllText(outputFile, plus.ToString()); + Console.WriteFormatted(" OUT -> " + outputFile + "\r\n", Color.DeepSkyBlue); + ++outputCounter; + } + } + + var rebuildBat = ArgsOutput + "__重新生成.bat"; + if (File.Exists(rebuildBat) == false) + { + File.WriteAllText(rebuildBat, @$" +FreeSql.Generator -Razor {ArgsRazorRaw} - NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}"" +"); + Console.WriteFormatted(" OUT -> " + rebuildBat + " (以后) 双击它重新生成实体\r\n", Color.Magenta); + ++outputCounter; + } + + Console.WriteFormatted($"\r\n[{DateTime.Now.ToString("MM-dd HH:mm:ss")}] 生成完毕,总共生成了 {outputCounter} 个文件,目录:\"{ArgsOutput}\"\r\n", Color.DarkGreen); + + Console.ReadKey(); + wait.Set(); + } + } +} + diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj new file mode 100644 index 00000000..a1802290 --- /dev/null +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -0,0 +1,33 @@ + + + + Exe + netcoreapp3.1 + true + true + true + 2881099 + 2881099 + FreeSql123 + 使用 FreeSql 快速生成数据库的实体类; dotnet tool install -g FreeSql.Generator + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + 0.12.16 + FreeSql DbFirst 实体生成器 + + + + + + + + + + + + + + + + + diff --git a/Extensions/FreeSql.Generator/Program.cs b/Extensions/FreeSql.Generator/Program.cs new file mode 100644 index 00000000..1b4475fe --- /dev/null +++ b/Extensions/FreeSql.Generator/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace FreeSql.Generator +{ + public class Program + { + static void Main(string[] args) + { + if (args != null && args.Length == 0) args = new[] { "?" }; + ManualResetEvent wait = new ManualResetEvent(false); + new Thread(() => { + Thread.CurrentThread.Join(TimeSpan.FromSeconds(1)); + ConsoleApp app = new ConsoleApp(args, wait); + }).Start(); + wait.WaitOne(); + return; + } + } +} diff --git a/Extensions/FreeSql.Generator/RazorContentManager.cs b/Extensions/FreeSql.Generator/RazorContentManager.cs new file mode 100644 index 00000000..e46a6370 --- /dev/null +++ b/Extensions/FreeSql.Generator/RazorContentManager.cs @@ -0,0 +1,246 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.Generator +{ + class RazorContentManager + { + public static string 实体类_特性_cshtml = + #region 长内容 + @"@using FreeSql.DatabaseModel;@{ +var gen = Model as RazorModel; + +Func GetAttributeString = attr => { + if (string.IsNullOrEmpty(attr)) return null; + return string.Concat("", "", attr.Trim('[', ']')); +}; +Func GetDefaultValue = col => { + if (col.CsType == typeof(string)) return "" = string.Empty;""; + return """"; +}; +}@{ +switch (gen.fsql.Ado.DataType) { + case FreeSql.DataType.PostgreSQL: +@:using System; +@:using System.Collections; +@:using System.Collections.Generic; +@:using System.Linq; +@:using System.Reflection; +@:using System.Threading.Tasks; +@:using Newtonsoft.Json; +@:using FreeSql.DataAnnotations; +@:using System.Net; +@:using Newtonsoft.Json.Linq; +@:using System.Net.NetworkInformation; +@:using NpgsqlTypes; +@:using Npgsql.LegacyPostgis; + break; + case FreeSql.DataType.SqlServer: + case FreeSql.DataType.MySql: + default: +@:using System; +@:using System.Collections; +@:using System.Collections.Generic; +@:using System.Linq; +@:using System.Reflection; +@:using System.Threading.Tasks; +@:using Newtonsoft.Json; +@:using FreeSql.DataAnnotations; + break; +} +} +namespace @gen.NameSpace { + +@if (string.IsNullOrEmpty(gen.table.Comment) == false) { + @:/// + @:/// @gen.table.Comment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") + @:/// +} + [JsonObject(MemberSerialization.OptIn)@GetAttributeString(gen.GetTableAttribute())] + public partial class @gen.GetCsName(gen.FullTableName) { + + @foreach (var col in gen.columns) { + + if (string.IsNullOrEmpty(col.Coment) == false) { + @:/// + @:/// @col.Coment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") + @:/// + } + @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col)) + ""]"") + @:public @gen.GetCsType(col) @gen.GetCsName(col.Name) { get; set; }@GetDefaultValue(col) +@: + } + } +@gen.GetMySqlEnumSetDefine() +}"; + #endregion + + public static string 实体类_特性_导航属性_cshtml = + #region 长内容 + @"@using FreeSql.DatabaseModel;@{ + +var isLazying = true; //延时加载 +var isOneToMany = true; //一对多,集合属性 +var isManyToMany = true; //多对多,集合属性 + +var gen = Model as RazorModel; +var fks = gen.table.Foreigns; + +Func GetAttributeString = attr => { + if (string.IsNullOrEmpty(attr)) return null; + return string.Concat("", "", attr.Trim('[', ']')); +}; + +Func GetFkObjectName = fkx => { + var eqfks = fks.Where(fk22a => fk22a.ReferencedTable.Name == fkx.ReferencedTable.Name); + if (eqfks.Count() == 1) return fkx.ReferencedTable.Name; + var fkretname = fkx.Columns[0].Name; + if (fkretname.EndsWith(fkx.ReferencedColumns[0].Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedColumns[0].Name.Length).TrimEnd('_'); + if (fkretname.EndsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedTable.Name.Length).TrimEnd('_'); + if (fkretname.StartsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(fkx.ReferencedTable.Name.Length).TrimStart('_'); + return fkx.ReferencedTable.Name + (string.IsNullOrEmpty(fkretname) ? """" : (""_"" + fkretname)); +}; +Func GetFkObjectNameOutside = fkx => { + var eqfks = fkx.Table.Foreigns.Where(fk22a => fk22a.ReferencedTable.Name == fkx.ReferencedTable.Name); + if (eqfks.Count() == 1) return fkx.Table.Name; + var fkretname = fkx.Columns[0].Name; + if (fkretname.EndsWith(fkx.ReferencedColumns[0].Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedColumns[0].Name.Length).TrimEnd('_'); + if (fkretname.EndsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedTable.Name.Length).TrimEnd('_'); + if (fkretname.StartsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(fkx.ReferencedTable.Name.Length).TrimStart('_'); + return fkx.Table.Name + ""s""; +}; +}@{ +switch (gen.fsql.Ado.DataType) { + case FreeSql.DataType.PostgreSQL: +@:using System; +@:using System.Collections.Generic; +@:using Newtonsoft.Json; +@:using FreeSql.DataAnnotations; +@:using System.Net; +@:using Newtonsoft.Json.Linq; +@:using System.Net.NetworkInformation; +@:using NpgsqlTypes; +@:using Npgsql.LegacyPostgis; + break; + case FreeSql.DataType.SqlServer: + case FreeSql.DataType.MySql: + default: +@:using System; +@:using System.Collections.Generic; +@:using Newtonsoft.Json; +@:using FreeSql.DataAnnotations; + break; +} +} +namespace @gen.NameSpace { + +@if (string.IsNullOrEmpty(gen.table.Comment) == false) { + @:/// + @:/// @gen.table.Comment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") + @:/// +} + [JsonObject(MemberSerialization.OptIn)@GetAttributeString(gen.GetTableAttribute())] + public partial class @gen.GetCsName(gen.FullTableName) { + + @foreach (var col in gen.columns) { + + var findfks = fks.Where(fkaa => fkaa.Columns.Where(fkaac1 => fkaac1.Name == col.Name).Any()); + var csname = gen.GetCsName(col.Name); + + if (string.IsNullOrEmpty(col.Coment) == false) { + @:/// + @:/// @col.Coment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") + @:/// + } + @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col)) + ""]"") + if (findfks.Any() == false) { + @:public @gen.GetCsType(col) @csname { get; set; } + } else { + @:public @gen.GetCsType(col) @csname { get => _@csname; set { + @:if (_@csname == value) return; + @:_@csname = value; + foreach (var fkcok2 in findfks) { + @:@GetFkObjectName(fkcok2) = null; + } + @:} } + @:private @gen.GetCsType(col) _@csname; + } +@: + } +@if (fks.Any()) { +@: + @:#region 外键 => 导航属性,ManyToOne/OneToOne + foreach (var fk in fks) { + var fkTableName = (fk.ReferencedTable.Schema + ""."" + fk.ReferencedTable.Name).Trim('.'); + if (fk.ReferencedTable.Schema == ""public"" || fk.ReferencedTable.Schema == ""dbo"") + { + fkTableName = fkTableName.Replace(fk.ReferencedTable.Schema + ""."", """"); + } +@: + @:[Navigate(""@string.Join("", "", fk.Columns.Select(a => gen.GetCsName(a.Name)))"")] + @:public@(isLazying ? "" virtual"" : """") @gen.GetCsName(fkTableName) @GetFkObjectName(fk) { get; set; } + } +@: + @:#endregion +} +@if (isOneToMany && gen.tables.Where(tmpft => tmpft.Foreigns.Where(tmpftfk => tmpftfk.ReferencedTable.Schema == gen.table.Schema && tmpftfk.ReferencedTable.Name == gen.table.Name && tmpftfk.Columns.Where(tmpcol => tmpcol.IsPrimary).Count() != tmpftfk.Columns.Count).Any()).Any()) { +@: + @:#region 外键 => 导航属性,OneToMany + foreach (var ft in gen.tables) { + var ftfks = ft.Foreigns.Where(ftfk => ftfk.ReferencedTable.Schema == gen.table.Schema && ftfk.ReferencedTable.Name == gen.table.Name && ftfk.Columns.Where(tmpcol => tmpcol.IsPrimary).Count() != ftfk.Columns.Count).ToArray(); + foreach (var fk in ftfks) { + var fkTableName = (ft.Schema + ""."" + ft.Name).Trim('.'); + if (ft.Schema == ""public"" || ft.Schema == ""dbo"") + { + fkTableName = fkTableName.Replace(ft.Schema + ""."", """"); + } +@: + @:[Navigate(""@string.Join("", "", fk.Columns.Select(a => gen.GetCsName(a.Name)))"")] + @:public@(isLazying ? "" virtual"" : """") List<@gen.GetCsName(fkTableName)> @GetFkObjectNameOutside(fk)s { get; set; } + } + } +@: + @:#endregion +} +@if (isManyToMany) { +@: + @:#region 外键 => 导航属性,ManyToMany + foreach (var ft in gen.tables) { + if (ft != gen.table) { + var ftfks = ft.Foreigns.Where(ftfk => ftfk.Columns.Where(ftfkcol => ftfkcol.IsPrimary == false).Any() == false).ToArray(); + if (ftfks.Length == 2) { + var fk1 = ftfks.Where(ftfk => (ftfk.ReferencedTable.Schema + ""."" + ftfk.ReferencedTable.Name).Trim('.') == gen.FullTableName).ToArray(); + if (fk1.Length == 1) { + var fk2 = ftfks.Where(ftfk => fk1.Contains(ftfk) == false).ToArray(); + + var midft = ft; + var leftft = gen.table; + DbTableInfo rightft = null; + if (fk2.Any()) { + rightft = fk2[0].ReferencedTable; + } else { + rightft = fk1[1].ReferencedTable; + } + + var fkTableName = (rightft.Schema + ""."" + rightft.Name).Trim('.'); + if (rightft.Schema == ""public"" || rightft.Schema == ""dbo"") + { + fkTableName = fkTableName.Replace(rightft.Schema + ""."", """"); + } + var csname = rightft.Name; +@: + @:public@(isLazying ? "" virtual"" : """") List<@gen.GetCsName(fkTableName)> @gen.GetCsName(csname)s { get; set; } + } + } + } + } +@: + @:#endregion +} + } +@gen.GetMySqlEnumSetDefine() +}"; + #endregion + } +} diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs new file mode 100644 index 00000000..80f7a855 --- /dev/null +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -0,0 +1,145 @@ +using FreeSql.DatabaseModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +public class RazorModel { + public RazorModel(IFreeSql fsql, string nameSpace, bool[] NameOptions, List tables, DbTableInfo table) { + this.fsql = fsql; + this.NameSpace = nameSpace; + this.NameOptions = NameOptions; + this.tables = tables; + this.table = table; + } + + public IFreeSql fsql { get; set; } + public bool[] NameOptions { get; set; } + public List tables { get; set; } + public DbTableInfo table { get; set; } + public List columns => this.table.Columns; + public string NameSpace { get; set; } + public string FullTableName => $"{(new[] { "public", "dbo" }.Contains(table.Schema) ? "" : table.Schema)}.{table.Name}".TrimStart('.'); + + public string GetCsName(string name) { + name = Regex.Replace(name.TrimStart('@', '.'), @"[^\w]", "_"); + name = char.IsLetter(name, 0) ? name : string.Concat("_", name); + if (NameOptions[0]) name = UFString(name); + if (NameOptions[1]) name = UFString(name.ToLower()); + if (NameOptions[2]) name = name.ToLower(); + if (NameOptions[3]) name = string.Join("", name.Split('_').Select(a => UFString(a))); + return name; + } + public string UFString(string text) { + text = Regex.Replace(text, @"[^\w]", "_"); + if (text.Length <= 1) return text.ToUpper(); + else return text.Substring(0, 1).ToUpper() + text.Substring(1, text.Length - 1); + } + public string LFString(string text) { + text = Regex.Replace(text, @"[^\w]", "_"); + if (text.Length <= 1) return text.ToLower(); + else return text.Substring(0, 1).ToLower() + text.Substring(1, text.Length - 1); + } + + public string GetCsType(DbColumnInfo col) { + if (fsql.Ado.DataType == FreeSql.DataType.MySql) + if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) + return $"{this.GetCsName(this.FullTableName)}{this.GetCsName(col.Name).ToUpper()}{(col.IsNullable ? "?" : "")}"; + return fsql.DbFirst.GetCsType(col); + } + + #region 特性 + public string GetTableAttribute() { + var sb = new List(); + + if (GetCsName(this.FullTableName) != this.FullTableName) + sb.Add("Name = \"" + this.FullTableName + "\""); + + if (sb.Any() == false) return null; + return "[Table(" + string.Join(", ", sb) + ")]"; + } + public string GetColumnAttribute(DbColumnInfo col) { + var sb = new List(); + + if (GetCsName(col.Name) != col.Name) + sb.Add("Name = \"" + col.Name + "\""); + + var dbinfo = fsql.CodeFirst.GetDbInfo(col.CsType); + if (dbinfo != null && dbinfo.Value.dbtypeFull.Replace("NOT NULL", "").Trim() != col.DbTypeTextFull) + sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + if (col.IsPrimary) + sb.Add("IsPrimary = true"); + if (col.IsIdentity) + sb.Add("IsIdentity = true"); + + if (dbinfo != null && dbinfo.Value.isnullable != col.IsNullable) { + if (col.IsNullable && fsql.DbFirst.GetCsType(col).Contains("?") == false && col.CsType.IsValueType) + sb.Add("IsNullable = true"); + if (col.IsNullable == false && fsql.DbFirst.GetCsType(col).Contains("?") == true) + sb.Add("IsNullable = false"); + } + if (sb.Any() == false) return null; + return "[Column(" + string.Join(", ", sb) + ")]"; + } + #endregion + + #region mysql enum/set + public string GetMySqlEnumSetDefine() { + if (fsql.Ado.DataType != FreeSql.DataType.MySql) return null; + var sb = new StringBuilder(); + foreach (var col in table.Columns) { + if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) { + if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) sb.Append("\r\n\t[Flags]"); + sb.Append($"\r\n\tpublic enum {this.GetCsName(this.FullTableName)}{this.GetCsName(col.Name).ToUpper()}"); + if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) sb.Append(" : long"); + sb.Append(" {\r\n\t\t"); + + string slkdgjlksdjg = ""; + int field_idx = 0; + int unknow_idx = 0; + string exp2 = string.Concat(col.DbTypeTextFull); + int quote_pos = -1; + while (true) { + int first_pos = quote_pos = exp2.IndexOf('\'', quote_pos + 1); + if (quote_pos == -1) break; + while (true) { + quote_pos = exp2.IndexOf('\'', quote_pos + 1); + if (quote_pos == -1) break; + int r_cout = 0; + //for (int p = 1; true; p++) { + // if (exp2[quote_pos - p] == '\\') r_cout++; + // else break; + //} + while (exp2[++quote_pos] == '\'') r_cout++; + if (r_cout % 2 == 0/* && quote_pos - first_pos > 2*/) { + string str2 = exp2.Substring(first_pos + 1, quote_pos - first_pos - 2).Replace("''", "'"); + if (Regex.IsMatch(str2, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$")) + slkdgjlksdjg += ", " + str2; + else + slkdgjlksdjg += string.Format(@", +/// +/// {0} +/// +[Description(""{0}"")] +Unknow{1}", str2.Replace("\"", "\\\""), ++unknow_idx); + if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) + slkdgjlksdjg += " = " + Math.Pow(2, field_idx++); + if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum && field_idx++ == 0) + slkdgjlksdjg += " = 1"; + break; + } + } + if (quote_pos == -1) break; + } + sb.Append(slkdgjlksdjg.Substring(2).TrimStart('\r', '\n', '\t')); + sb.Append("\r\n\t}"); + } + } + return sb.ToString(); + } + #endregion +} + + diff --git a/FreeSql.sln b/FreeSql.sln index 3464c254..b5273404 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -66,6 +66,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Odbc EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "orm_vs_net40", "Examples\orm_vs_net40\orm_vs_net40.csproj", "{1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Generator", "Extensions\FreeSql.Generator\FreeSql.Generator.csproj", "{6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -388,6 +390,18 @@ Global {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|x64.Build.0 = Release|Any CPU {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|x86.ActiveCfg = Release|Any CPU {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23}.Release|x86.Build.0 = Release|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Debug|x64.ActiveCfg = Debug|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Debug|x64.Build.0 = Debug|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Debug|x86.ActiveCfg = Debug|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Debug|x86.Build.0 = Debug|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|Any CPU.Build.0 = Release|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x64.ActiveCfg = Release|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x64.Build.0 = Release|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x86.ActiveCfg = Release|Any CPU + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -411,6 +425,7 @@ Global {3043DEF1-85DF-47AD-8D5D-327270794356} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {C57444BA-8BF7-4790-A864-7F237123219B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/readme.md b/readme.md index 5bc30cc7..473aecee 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ # Features - [x] 支持 CodeFirst 迁移; -- [x] 支持 DbFirst 从数据库导入实体类; +- [x] 支持 DbFirst 从数据库导入实体类,[安装实体类生成工具](https://github.com/2881099/FreeSql/wiki/DbFirst); - [x] 大量采用 ExpressionTree 提升性能; - [x] 支持 深入的类型映射,比如pgsql的数组类型; - [x] 支持 丰富的表达式函数; @@ -43,12 +43,6 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - 要么[FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; - 要么[BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),我求简单现在使用的这个; -> 其他下载 - -- [FreeSql.Tools 生成器](https://github.com/2881099/FreeSql.Tools),基于 razor 模板的生成器; -- [Abp 中使用 FreeSql](https://github.com/gnsilence/JPGZService),测试中...; -- [FreeSql 优势.pptx](https://github.com/2881099/FreeSql/files/3305852/FreeSql.pptx); - > 学习项目 - [😃 A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) From 3c1e616f0b8de964345b52e6022129247180c16f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Dec 2019 22:49:54 +0800 Subject: [PATCH 0323/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Gene?= =?UTF-8?q?rator=20=E5=AE=9E=E4=BD=93=E7=B1=BB=E7=94=9F=E6=88=90=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 2 +- FreeSql/FreeSql.xml | 464 ++++++++++----------- 2 files changed, 226 insertions(+), 240 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 4e456fc5..16614070 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -218,7 +218,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 if (File.Exists(rebuildBat) == false) { File.WriteAllText(rebuildBat, @$" -FreeSql.Generator -Razor {ArgsRazorRaw} - NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}"" +FreeSql.Generator -Razor {ArgsRazorRaw} -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}"" "); Console.WriteFormatted(" OUT -> " + rebuildBat + " (以后) 双击它重新生成实体\r\n", Color.Magenta); ++outputCounter; diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ac93e9cc..27ff99c1 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2267,181 +2267,7 @@ CodeFirst迁移,执行完成触发 - - - - - Insert/Update自动值处理 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构 - - - - - 转大写同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - + 不使用命令参数化执行,针对 Insert/Update @@ -2730,99 +2556,105 @@ - + - C#:从元组集合中查找 exp1, exp2, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 + 获取c#类型对象 - - - - - - - + - + - 测量两个经纬度的距离,返回单位:米 + 获取ado.net读取方法, GetBoolean、GetInt64 - 经纬坐标1 - 经纬坐标2 - 返回距离(单位:米) + + - + - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 - + 名字 + 表达式 - + - 多表查询 + 中间表,多对多 - - + - 多表查询 + 不进行任何处理 - - + - 多表查询 + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple - - + - 多表查询 + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE - - + - 多表查询 + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple - - + - 多表查询 + 将字符串转换为大写 + + BigApple -> BIGAPPLE - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 - 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) @@ -2992,6 +2824,160 @@ CodeFirst 模式开发相关方法 + + + DbFirst 模式开发相关方法 + + < + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完将自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 事务体 () => {} + 超时,未执行完将自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + DbFirst 模式开发相关方法 From cb074e7f0dedadea5b63bf93b326020988f1dba6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Dec 2019 23:48:52 +0800 Subject: [PATCH 0324/1029] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20nuget=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - .../FreeSql.Tests.DbContext.csproj | 9 +- .../FreeSql.Tests.PerformanceTests.csproj | 11 +- ...eeSql.Tests.Provider.MySqlConnector.csproj | 9 +- .../FreeSql.Tests/FreeSql.Tests.csproj | 11 +- FreeSql/FreeSql.xml | 435 +++++++++--------- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 4 +- .../FreeSql.Provider.PostgreSQL.csproj | 4 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 13 files changed, 259 insertions(+), 241 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 7ca5a286..f9b23b76 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -34,7 +34,7 @@ - + diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj index bda7efbb..7247f3a8 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj @@ -7,9 +7,12 @@ - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj index a3e53b3c..896199f9 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj @@ -7,10 +7,13 @@ - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj index bb1fc44e..9ed1b21a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj @@ -7,9 +7,12 @@ - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index c895f7f6..16afde1b 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -12,10 +12,13 @@ - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 27ff99c1..9c96313b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2267,103 +2267,124 @@ CodeFirst迁移,执行完成触发 - - - 不使用命令参数化执行,针对 Insert/Update - + - 是否生成命令参数化执行,针对 lambda 表达式解析 + Insert/Update自动值处理 - + - 延时加载导航属性对象,导航属性需要声明 virtual + 内置解析功能,可辅助您进行解析 - + - 将实体类型与数据库对比,返回DDL语句 + 需要您解析的表达式 - - - + - 将实体类型集合与数据库对比,返回DDL语句 + 解析后的内容 - 实体类型 - - + - 将实体类型与数据库对比,返回DDL语句(指定表名) + 实体类型 - 实体类型 - 指定表名对比 - - + - 同步实体类型到数据库 + 实体配置 - - - + - 同步实体类型集合到数据库 + 索引配置 - - - + - 同步实体类型到数据库(指定表名) + 实体类型 - 实体类型 - 指定表名对比 - - + - 根据 System.Type 获取数据库信息 + 实体的属性 - - - + - 在外部配置实体的特性 + 实体的属性配置 - - - - + - 在外部配置实体的特性 + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - + - 获取在外部配置实体的特性 + 操作类型 - - 未使用ConfigEntity配置时,返回null - + - 获取实体类核心配置 + 实体类型 - - - + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + 获取所有数据库 @@ -2654,7 +2675,153 @@ BigApple -> BIGAPPLE - + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + + + + + + + C#:从元组集合中查找 exp1, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + + C#:从元组集合中查找 exp1, exp2, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + + + + 测量两个经纬度的距离,返回单位:米 + + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) + + + + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + + + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 + 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) @@ -2824,160 +2991,6 @@ CodeFirst 模式开发相关方法 - - - DbFirst 模式开发相关方法 - - < - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完将自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 事务体 () => {} - 超时,未执行完将自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - DbFirst 模式开发相关方法 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 59371ace..0308f7ca 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -23,7 +23,7 @@ - + diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 5764bb65..cd48c3d7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -23,7 +23,7 @@ - + diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index abfcffb3..dbdd428e 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -23,11 +23,11 @@ - + - + diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 89cf5943..e6a063f3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -23,11 +23,11 @@ - + - + diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4aabd09b..a299af87 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -23,7 +23,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index d4ff2915..5df88004 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -26,7 +26,7 @@ - + From 76b613709e73718985b51a3b89dac88d689a5234 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 12 Dec 2019 17:19:32 +0800 Subject: [PATCH 0325/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Oracle=20Dbf?= =?UTF-8?q?irst=20=E5=AD=97=E6=AE=B5=E5=8F=AF=E7=A9=BA=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E6=96=AD=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 2 + FreeSql/FreeSql.xml | 437 +++++++------- .../OdbcDamengAdo/OdbcDamengConnectionPool.cs | 2 +- .../GBase/Curd/OdbcGBaseDelete.cs | 31 + .../GBase/Curd/OdbcGBaseSelect.cs | 176 ++++++ .../GBase/Curd/__OdbcGBaseInsert.cs | 149 +++++ .../GBase/Curd/__OdbcGBaseUpdate.cs | 85 +++ .../OdbcGBaseAdo/OdbcGBaseConnectionPool.cs | 248 ++++++++ .../GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs | 68 +++ .../GBase/OdbcGBaseProvider.cs | 61 ++ .../GBase/__OdbcGBaseCodeFirst.cs | 387 ++++++++++++ .../GBase/__OdbcGBaseDbFirst.cs | 480 +++++++++++++++ .../GBase/__OdbcGBaseExpression.cs | 554 ++++++++++++++++++ .../GBase/__OdbcGBaseUtils.cs | 167 ++++++ .../Oracle/OdbcOracleCodeFirst.cs | 2 +- .../Oracle/OdbcOracleDbFirst.cs | 2 +- .../OdbcPostgreSQLConnectionPool.cs | 2 +- .../OracleCodeFirst.cs | 2 +- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 2 +- 20 files changed, 2630 insertions(+), 234 deletions(-) create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseDelete.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs create mode 100644 Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 3cb9aa53..82594730 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -245,6 +245,8 @@ namespace FreeSql.Tests [Fact] public void Test02() { + g.sqlite.Update(Guid.Empty).Set(a => a.ct1 == a.ct2).ExecuteAffrows(); + g.sqlite.Insert(new otot1 { name = "otot1_name1" }).ExecuteAffrows(); var otolst1 = g.sqlite.Select() diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9c96313b..a89a4d64 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2267,124 +2267,103 @@ CodeFirst迁移,执行完成触发 - - - + - Insert/Update自动值处理 + 不使用命令参数化执行,针对 Insert/Update - + - 内置解析功能,可辅助您进行解析 + 是否生成命令参数化执行,针对 lambda 表达式解析 - + - 需要您解析的表达式 + 延时加载导航属性对象,导航属性需要声明 virtual - + - 解析后的内容 + 将实体类型与数据库对比,返回DDL语句 + + - + - 实体类型 + 将实体类型集合与数据库对比,返回DDL语句 + 实体类型 + - + - 实体配置 + 将实体类型与数据库对比,返回DDL语句(指定表名) + 实体类型 + 指定表名对比 + - + - 索引配置 + 同步实体类型到数据库 + + - + - 实体类型 + 同步实体类型集合到数据库 + + - + - 实体的属性 + 同步实体类型到数据库(指定表名) + 实体类型 + 指定表名对比 + - + - 实体的属性配置 + 根据 System.Type 获取数据库信息 + + - + - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + 在外部配置实体的特性 + + + - + - 操作类型 + 在外部配置实体的特性 + + + - + - 实体类型 + 获取在外部配置实体的特性 + + 未使用ConfigEntity配置时,返回null - + - 实体类型的元数据 + 获取实体类核心配置 + + - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - + 获取所有数据库 @@ -2577,158 +2556,6 @@ - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 中间表,多对多 - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - - - C#: that >= between && that <= and - SQL: that BETWEEN between AND and - - - - - - - - - 注意:这个方法和 Between 有细微区别 - C#: that >= start && that < end - SQL: that >= start and that < end - - - - - - - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - C#:从元组集合中查找 exp1, exp2, exp2 是否存在 @@ -2991,6 +2818,160 @@ CodeFirst 模式开发相关方法 + + + DbFirst 模式开发相关方法 + + < + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完将自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 事务体 () => {} + 超时,未执行完将自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + DbFirst 模式开发相关方法 diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index 61bdc72c..81a601bb 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -62,7 +62,7 @@ namespace FreeSql.Odbc.Dameng { internal OdbcDamengConnectionPool _pool; - public string Name { get; set; } = "Oracle OdbcConnection 对象池"; + public string Name { get; set; } = "Dameng OdbcConnection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseDelete.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseDelete.cs new file mode 100644 index 00000000..f2403466 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseDelete.cs @@ -0,0 +1,31 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.GBase +{ + + class OdbcGBaseDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OdbcGBaseDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + throw new NotImplementedException(); + } + +#if net40 +#else + public override Task> ExecuteDeletedAsync() + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs new file mode 100644 index 00000000..b34ea8c5 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs @@ -0,0 +1,176 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.GBase +{ + + class OdbcGBaseSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + + if (_skip > 0) + sb.Append("SKIP ").Append(_skip).Append(" "); + if (_limit > 0) + sb.Append("FIRST ").Append(_limit).Append(" "); + + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.ToString(); + } + + public OdbcGBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs new file mode 100644 index 00000000..496108fa --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs @@ -0,0 +1,149 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.GBase +{ + + class OdbcGBaseInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public OdbcGBaseInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + this.RawExecuteAffrows(); + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + await this.RawExecuteAffrowsAsync(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseUpdate.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseUpdate.cs new file mode 100644 index 00000000..dc9d3cc7 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseUpdate.cs @@ -0,0 +1,85 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.GBase +{ + + class OdbcGBaseUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public OdbcGBaseUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + + protected override List RawExecuteUpdated() + { + throw new NotImplementedException(); + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + ++pkidx; + } + sb.Append(")"); + } + + protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) + { + if (_noneParameter == false) return; + var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; + if (dbtype == null) return; + + sb.Append("::").Append(dbtype); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs new file mode 100644 index 00000000..e9c6fae6 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs @@ -0,0 +1,248 @@ +using SafeObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.GBase +{ + + class OdbcGBaseConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public OdbcGBaseConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new OdbcPostgreSQLConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + + if (exception is System.IO.IOException) + { + + base.SetUnavailable(exception); + + } + else if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class OdbcPostgreSQLConnectionPoolPolicy : IPolicy + { + + internal OdbcGBaseConnectionPool _pool; + public string Name { get; set; } = "GBase OdbcConnection 对象池"; + public int PoolSize { get; set; } = 50; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs new file mode 100644 index 00000000..c4c215f2 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs @@ -0,0 +1,68 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using SafeObjectPool; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.Odbc.GBase +{ + class OdbcGBaseAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public OdbcGBaseAdo() : base(DataType.PostgreSQL) { } + public OdbcGBaseAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.PostgreSQL) + { + base._util = util; + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OdbcGBaseConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OdbcGBaseConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + + static DateTime dt1970 = new DateTime(1970, 1, 1); + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? "'t'" : "'f'"; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new OdbcCommand(); + } + + protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + { + (pool as OdbcGBaseConnectionPool).Return(conn, ex); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs new file mode 100644 index 00000000..eee74c06 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs @@ -0,0 +1,61 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace FreeSql.Odbc.GBase +{ + + public class OdbcGBaseProvider : IFreeSql + { + + static OdbcGBaseProvider() + { + } + + public ISelect Select() where T1 : class => new OdbcGBaseSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OdbcGBaseSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OdbcGBaseInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OdbcGBaseUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OdbcGBaseUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OdbcGBaseDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OdbcGBaseDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public OdbcGBaseProvider(string masterConnectionString, string[] slaveConnectionString) + { + this.InternalCommonUtils = new OdbcGBaseUtils(this); + this.InternalCommonExpression = new OdbcGBaseExpression(this.InternalCommonUtils); + + this.Ado = new OdbcGBaseAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Aop = new AopProvider(); + + this.DbFirst = new OdbcGBaseDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new OdbcGBaseCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + + ~OdbcGBaseProvider() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs new file mode 100644 index 00000000..15478af5 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs @@ -0,0 +1,387 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text; + +namespace FreeSql.Odbc.GBase +{ + + class OdbcGBaseCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public OdbcGBaseCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + + { typeof(sbyte).FullName, (OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, (OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, (OdbcType.Int, "integer","integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "integer", "integer", false, true, null) }, + { typeof(long).FullName, (OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "bigint", "bigint", false, true, null) }, + + { typeof(byte).FullName, (OdbcType.SmallInt, "byte","byte NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (OdbcType.SmallInt, "byte", "byte", false, true, null) }, + { typeof(ushort).FullName, (OdbcType.Int, "integer","integer NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "integer", "integer", false, true, null) }, + { typeof(uint).FullName, (OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, (OdbcType.Decimal, "decimal","decimal(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "decimal", "decimal(20,0)", false, true, null) }, + + { typeof(float).FullName, (OdbcType.Real, "smallfloat","smallfloat NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "smallfloat", "smallfloat", false, true, null) }, + { typeof(double).FullName, (OdbcType.Double, "float","float NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "float", "float", false, true, null) }, + { typeof(decimal).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + + { typeof(string).FullName, (OdbcType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, + + { typeof(TimeSpan).FullName, (OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp", false, true, null) }, + + { typeof(bool).FullName, (OdbcType.Bit, "char","char(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "char","char(1)", null, true, null) }, + { typeof(Byte[]).FullName, (OdbcType.VarBinary, "blob", "blob", false, null, new byte[0]) }, + + { typeof(Guid).FullName, (OdbcType.Char, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.Char, "char", "char(36)", false, true, null) }, + }; + + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + var isarray = type.FullName != "System.Byte[]" && type.IsArray; + var elementType = isarray ? type.GetElementType() : type; + var info = GetDbInfoNoneArray(elementType); + if (info == null) return null; + return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable, info.Value.defaultValue); + } + (OdbcType type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfoNoneArray(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (OdbcType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OdbcType.Int, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OdbcType.BigInt, "integer", $"integer{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + { + var sb = new StringBuilder(); + var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName.Split(new[] { '.' }, 2); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + + var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } + + if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 + sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tboldname)) == null) + //旧表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql(@" +select +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, +case when a.attnotnull then '0' else '1' end as is_nullable, +coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +--e.adsrc, +a.attndims, +d.description as comment +from pg_class c +inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join pg_type t on t.oid = a.atttypid +left join pg_type t2 on t2.oid = t.typelem +left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join pg_namespace ns on ns.oid = c.relnamespace +inner join pg_namespace ns2 on ns2.oid = t.typnamespace +where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var attndims = int.Parse(string.Concat(a[6])); + var type = string.Concat(a[1]); + var sqlType = string.Concat(a[3]); + var max_length = long.Parse(string.Concat(a[2])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + return new + { + column = string.Concat(a[0]), + sqlType = string.Concat(sqlType), + max_length = long.Parse(string.Concat(a[2])), + is_nullable = string.Concat(a[4]) == "1", + is_identity = string.Concat(a[5]) == "1", //string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + attndims, + comment = string.Concat(a[7]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } + } + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (isCommentChanged) + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); + if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" +select +c.attname, +b.relname, +case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +case when indisunique = 't' then 1 else 0 end IsUnique +from pg_index a +inner join pg_class b on b.oid = a.indexrelid +inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_class d on d.oid = a.indrelid +where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select pg_constraint.conname as pk_name from pg_constraint +inner join pg_class on pg_constraint.conrelid = pg_class.oid +inner join pg_namespace on pg_namespace.oid = pg_class.relnamespace +where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contype='p' +", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"coalesce({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); + sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); + if (seqcol.Item3) + { + sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);\r\n"); + sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); + } + } + return sb.Length == 0 ? null : sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs new file mode 100644 index 00000000..e2f10f07 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs @@ -0,0 +1,480 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.GBase +{ + class OdbcGBaseDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public OdbcGBaseDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetOdbcType(column); + OdbcType GetOdbcType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + var isarray = dbtype.EndsWith("[]"); + if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); + OdbcType ret = OdbcType.VarChar; + switch (dbtype.ToLower().TrimStart('_')) + { + case "int2": ret = OdbcType.SmallInt; break; + case "int4": ret = OdbcType.Int; break; + case "int8": ret = OdbcType.BigInt; break; + case "numeric": ret = OdbcType.Numeric; break; + case "float4": ret = OdbcType.Real; break; + case "float8": ret = OdbcType.Double; break; + case "money": ret = OdbcType.Numeric; break; + + case "bpchar": ret = OdbcType.Char; break; + case "varchar": ret = OdbcType.VarChar; break; + case "text": ret = OdbcType.Text; break; + + case "timestamp": ret = OdbcType.DateTime; break; + case "timestamptz": ret = OdbcType.DateTime; break; + case "date": ret = OdbcType.Date; break; + case "time": ret = OdbcType.Time; break; + case "timetz": ret = OdbcType.Time; break; + case "interval": ret = OdbcType.Time; break; + + case "bool": ret = OdbcType.Bit; break; + case "bytea": ret = OdbcType.VarBinary; break; + case "bit": ret = OdbcType.Bit; break; + case "varbit": ret = OdbcType.VarBinary; break; + + case "json": ret = OdbcType.VarChar; break; + case "jsonb": ret = OdbcType.VarChar; break; + case "uuid": ret = OdbcType.UniqueIdentifier; break; + } + return ret; + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OdbcType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)OdbcType.Numeric, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)OdbcType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OdbcType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + + { (int)OdbcType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)OdbcType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + + { (int)OdbcType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)OdbcType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)OdbcType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select datname from pg_database where datname not in ('template1', 'template0')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public List GetTablesByDatabase(params string[] database) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + var tables = new List(); + + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = $@" +select +b.nspname || '.' || a.tablename, +a.schemaname, +a.tablename , +d.description, +'TABLE' +from pg_tables a +inner join pg_namespace b on b.nspname = a.schemaname +inner join pg_class c on c.relnamespace = b.oid and c.relname = a.tablename +left join pg_description d on d.objoid = c.oid and objsubid = 0 +where a.schemaname not in ('pg_catalog', 'information_schema', 'topology') +and b.nspname || '.' || a.tablename not in ('public.spatial_ref_sys') + +union all + +select +b.nspname || '.' || a.relname, +b.nspname, +a.relname, +d.description, +'VIEW' +from pg_class a +inner join pg_namespace b on b.oid = a.relnamespace +left join pg_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('m','v') +and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews') +"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = $@" +select +ns.nspname || '.' || c.relname as id, +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem = 0 then t.typname else t2.typname end, +case when a.attnotnull then 0 else 1 end as is_nullable, +coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +--e.adsrc as is_identity, +d.description as comment, +a.attndims, +case when t.typelem = 0 then t.typtype else t2.typtype end, +ns2.nspname, +a.attnum +from pg_class c +inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join pg_type t on t.oid = a.atttypid +left join pg_type t2 on t2.oid = t.typelem +left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join pg_namespace ns on ns.oid = c.relnamespace +inner join pg_namespace ns2 on ns2.oid = t.typnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")}"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var type = string.Concat(row[2]); + var max_length = int.Parse(string.Concat(row[3])); + var sqlType = string.Concat(row[4]); + var is_nullable = string.Concat(row[5]) == "1"; + var is_identity = string.Concat(row[6]) == "1"; //string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var comment = string.Concat(row[7]); + int attndims = int.Parse(string.Concat(row[8])); + string typtype = string.Concat(row[9]); + string owner = string.Concat(row[10]); + int attnum = int.Parse(string.Concat(row[11])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (max_length <= 0) max_length = -1; + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + if (max_length > 0) + { + switch (sqlType.ToLower()) + { + //case "numeric": sqlType += $"({max_length})"; break; + case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; + } + } + + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Coment = comment + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } + + sql = $@" +select +ns.nspname || '.' || d.relname as table_id, +c.attname, +b.relname as index_id, +case when a.indisunique then 1 else 0 end IsUnique, +case when a.indisprimary then 1 else 0 end IsPrimary, +case when a.indisclustered then 0 else 1 end IsClustered, +case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +a.indkey::text, +c.attnum +from pg_index a +inner join pg_class b on b.oid = a.indexrelid +inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_class d on d.oid = a.indrelid +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} and a.indisprimary = 'f' +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var index_id = string.Concat(row[2]); + var is_unique = string.Concat(row[3]) == "1"; + var is_primary_key = string.Concat(row[4]) == "1"; + var is_clustered = string.Concat(row[5]) == "1"; + var is_desc = string.Concat(row[6]) == "1"; + var inkey = string.Concat(row[7]).Split(' '); + var attnum = int.Parse(string.Concat(row[8])); + attnum = int.Parse(inkey[attnum - 1]); + foreach (string tc in loc3[object_id].Keys) + { + if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) + { + column = tc; + break; + } + } + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + var loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = $@" +select +ns.nspname || '.' || b.relname as table_id, +array(select attname from pg_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, +a.conname as FKId, +ns2.nspname || '.' || c.relname as ref_table_id, +1 as IsForeignKey, +array(select attname from pg_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, +null ref_sln, +null ref_table +from pg_constraint a +inner join pg_class b on b.oid = a.conrelid +inner join pg_class c on c.oid = a.confrelid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_namespace ns2 on ns2.oid = c.relnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } + + public List GetEnumsByDatabase(params string[] database) + { + if (database == null || database.Length == 0) return new List(); + var drs = _orm.Ado.Query<(string name, string label)>(CommandType.Text, _commonUtils.FormatSql(@" +select +ns.nspname || '.' || a.typname, +b.enumlabel +from pg_type a +inner join pg_enum b on b.enumtypid = a.oid +inner join pg_namespace ns on ns.oid = a.typnamespace +where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information_schema.schemata where catalog_name in {0})", database)); + var ret = new Dictionary>(); + foreach (var dr in drs) + { + if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); + var key = dr.label; + if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) + key = $"Unkown{ret[dr.name].Count + 1}"; + if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); + } + return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs new file mode 100644 index 00000000..c250c87f --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs @@ -0,0 +1,554 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.GBase +{ + class OdbcGBaseExpression : CommonExpression + { + + public OdbcGBaseExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(operandExp)})::int2"; + case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.Decimal": return $"({getExp(operandExp)})::numeric"; + case "System.Double": return $"({getExp(operandExp)})::float8"; + case "System.Int16": return $"({getExp(operandExp)})::int2"; + case "System.Int32": return $"({getExp(operandExp)})::int4"; + case "System.Int64": return $"({getExp(operandExp)})::int8"; + case "System.SByte": return $"({getExp(operandExp)})::int2"; + case "System.Single": return $"({getExp(operandExp)})::float4"; + case "System.String": return $"({getExp(operandExp)})::varchar"; + case "System.UInt16": return $"({getExp(operandExp)})::int2"; + case "System.UInt32": return $"({getExp(operandExp)})::int4"; + case "System.UInt64": return $"({getExp(operandExp)})::int8"; + case "System.Guid": return $"({getExp(operandExp)})::uuid"; + } + } + break; + case ExpressionType.ArrayLength: + var arrOperExp = getExp((exp as UnaryExpression).Operand); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; + case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; + case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; + case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid"; + } + break; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + string left = null; + if (objType.FullName == typeof(Dictionary).FullName) + { + left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + var right = getExp(callExp.Arguments[argIndex]); + return $"({left} @> ({right}))"; + case "ContainsKey": return $"({left} ? {getExp(callExp.Arguments[argIndex])})"; + case "Concat": return $"({left} || {getExp(callExp.Arguments[argIndex])})"; + case "GetLength": + case "GetLongLength": + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + switch (callExp.Method.Name) + { + case "Any": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; + case "Contains": + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + //判断 in 或 array @> array + if (left.StartsWith("array[") || left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + args1 = $"array[{args1}]"; + if (objExp != null) + { + var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); + if (dbinfo.HasValue) args1 = $"{args1}::{dbinfo.Value.dbtype}"; + } + return $"({left} @> {args1})"; + case "Concat": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + var right2 = getExp(callExp.Arguments[argIndex]); + if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; + return $"({left} || {right2})"; + case "GetLength": + case "GetLongLength": + case "Length": + case "Count": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + break; + case ExpressionType.MemberAccess: + var memExp = exp as MemberExpression; + var memParentExp = memExp.Expression?.Type; + if (memParentExp?.FullName == "System.Byte[]") return null; + if (memParentExp != null) + { + if (memParentExp.IsArray == true) + { + var left = getExp(memExp.Expression); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + switch (memExp.Member.Name) + { + case "Length": + case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + switch (memParentExp.FullName) + { + case "Newtonsoft.Json.Linq.JToken": + case "Newtonsoft.Json.Linq.JObject": + case "Newtonsoft.Json.Linq.JArray": + var left = getExp(memExp.Expression); + switch (memExp.Member.Name) + { + case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; + } + break; + } + if (memParentExp.FullName == typeof(Dictionary).FullName) + { + var left = getExp(memExp.Expression); + switch (memExp.Member.Name) + { + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("array["); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append("]").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "current_date"; + case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; + case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"({left})::date"; + case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)"; + case "DayOfWeek": return $"extract(dow from ({left})::timestamp)"; + case "Day": return $"extract(day from ({left})::timestamp)"; + case "DayOfYear": return $"extract(doy from ({left})::timestamp)"; + case "Month": return $"extract(month from ({left})::timestamp)"; + case "Year": return $"extract(year from ({left})::timestamp)"; + case "Hour": return $"extract(hour from ({left})::timestamp)"; + case "Minute": return $"extract(minute from ({left})::timestamp)"; + case "Second": return $"extract(second from ({left})::timestamp)"; + case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)"; + case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)"; + case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)"; + case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)"; + case "Seconds": return $"(floor(({left})/1000000)::int8%60)"; + case "Ticks": return $"(({left})*10)"; + case "TotalDays": return $"(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left})/1000)"; + case "TotalMinutes": return $"(({left})/{(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left})/1000000)"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + var likeOpt = "LIKE"; + if (exp.Arguments.Count > 1) + { + if (exp.Arguments[1].Type == typeof(bool) || + exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + var trimArg1 = ""; + var trimArg2 = ""; + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + var trimChr = getExp(argsTrim01).Trim('\''); + if (trimChr.Length == 1) trimArg1 += trimChr; + else trimArg2 += $" || ({trimChr})"; + } + } + if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)"; + case "DaysInMonth": return $"extract(day from ({getExp(exp.Arguments[0])} || '-' || {getExp(exp.Arguments[1])} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)"; + case "Equals": return $"(({getExp(exp.Arguments[0])})::timestamp = ({getExp(exp.Arguments[1])})::timestamp)"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; + + case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"(({left})::timestamp+(({args1})||' microseconds')::interval)"; + case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; + case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; + case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; + case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)"; + case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)"; + case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)"; + case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; + case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; + case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; + } + break; + case "Equals": return $"({left} = ({args1})::timestamp)"; + case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; + case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"({left})::varchar"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; + case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; + case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; + case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; + case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; + case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; + case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs new file mode 100644 index 00000000..ee39daff --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs @@ -0,0 +1,167 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Data.Common; +using System.Linq; +using System.Net; +using System.Text; +using System.Linq.Expressions; +using System.Reflection; +using System.Data.Odbc; +using FreeSql.Internal.Model; + +namespace FreeSql.Odbc.GBase +{ + + class OdbcGBaseUtils : CommonUtils + { + public OdbcGBaseUtils(IFreeSql orm) : base(orm) + { + } + + static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) + { + var valueArr = value as Array; + var len = valueArr.GetLength(0); + var ret = Array.CreateInstance(arrayType, len); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); + } + return ret; + } + static Dictionary> dicGetParamterValue = new Dictionary> { + { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, + { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, + { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, + { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + }; + static object getParamterValue(Type type, object value, int level = 0) + { + if (type.FullName == "System.Byte[]") return value; + if (type.IsArray && level == 0) + { + var elementType = type.GetElementType(); + Type enumType = null; + if (elementType.IsEnum) enumType = elementType; + else if (elementType.IsNullableType()) + { + var genericTypesFirst = elementType.GetGenericArguments().First(); + if (genericTypesFirst.IsEnum) enumType = genericTypesFirst; + } + if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)); + return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; + } + if (type.IsNullableType()) type = type.GetGenericArguments().First(); + if (type.IsEnum) return (int)value; + if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); + return value; + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value != null) value = getParamterValue(type, value); + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + //} + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value != null) value = getParamterValue(type, value); + var ret = new OdbcParameter { ParameterName = $"@{name}", Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + //} + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcPostgreSQL(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "current_timestamp"; + public override string NowUtc => "(current_timestamp at time zone 'UTC')"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + value = getParamterValue(type, value); + var type2 = value.GetType(); + if (type2 == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("'\\x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); + } + else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; + } + else if (value is Array) + { + var valueArr = value as Array; + var eleType = type2.GetElementType(); + var len = valueArr.GetLength(0); + var sb = new StringBuilder().Append("ARRAY["); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + if (a > 0) sb.Append(","); + sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + } + sb.Append("]"); + var dbinfo = _orm.CodeFirst.GetDbInfo(type); + if (dbinfo.HasValue) sb.Append("::").Append(dbinfo.Value.dbtype); + return sb.ToString(); + } + else if (dicGetParamterValue.ContainsKey(type2.FullName)) + { + value = string.Concat(value); + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index d39e4c48..ad61cdb9 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -182,7 +182,7 @@ a.data_length, a.data_precision, a.data_scale, a.char_used, -case when a.nullable = 'Y' then 1 else 0 end, +case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), b.comments diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index fe87f450..dfcbfa6b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -258,7 +258,7 @@ a.data_length, a.data_precision, a.data_scale, a.char_used, -case when a.nullable = 'Y' then 1 else 0 end, +case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), b.comments from all_tab_cols a diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index dfc21556..69688f14 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -57,7 +57,7 @@ namespace FreeSql.Odbc.PostgreSQL { internal OdbcPostgreSQLConnectionPool _pool; - public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池"; + public string Name { get; set; } = "PostgreSQL OdbcConnection 对象池"; public int PoolSize { get; set; } = 50; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 7fdff83f..e408452f 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -183,7 +183,7 @@ a.data_length, a.data_precision, a.data_scale, a.char_used, -case when a.nullable = 'Y' then 1 else 0 end, +case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), b.comments diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 089e2791..8f24499e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -258,7 +258,7 @@ a.data_length, a.data_precision, a.data_scale, a.char_used, -case when a.nullable = 'Y' then 1 else 0 end, +case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), b.comments from all_tab_cols a From a9512745d8e3b31889f9975f176e1751f011d98f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 12 Dec 2019 17:20:22 +0800 Subject: [PATCH 0326/1029] ## v0.12.17 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7a3c55b9..ed78c3c2 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.16 + 0.12.17 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index eac9e815..55c56be1 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b71c5b45..a615211d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index a1802290..2ed05a3b 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类; dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 0.12.16 + 0.12.17 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index f9b23b76..dd3472ea 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c901737c..dd4ea747 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.16 + 0.12.17 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2547561e..02d5e48e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 51c7276d..48b0f852 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0308f7ca..79127d8f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index cd48c3d7..bf2be899 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index dbdd428e..3d36549b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e6a063f3..76d6b763 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a299af87..c0c5566a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5df88004..2e3ced2e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.16 + 0.12.17 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 801b9ba082681174c40ae818323bb296f258f6d6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 12 Dec 2019 18:03:32 +0800 Subject: [PATCH 0327/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Oracle=20Dbf?= =?UTF-8?q?irst=20=E5=AD=97=E6=AE=B5=E5=8F=AF=E7=A9=BA=E3=80=81=E5=92=8C?= =?UTF-8?q?=E4=B8=BB=E9=94=AE=E5=88=A4=E6=96=AD=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 330 ++++++++++-------- .../Oracle/OdbcOracleDbFirst.cs | 8 +- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 8 +- 3 files changed, 183 insertions(+), 163 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a89a4d64..ac93e9cc 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2267,7 +2267,181 @@ CodeFirst迁移,执行完成触发 - + + + + + Insert/Update自动值处理 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构 + + + + + 转大写同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + 不使用命令参数化执行,针对 Insert/Update @@ -2818,160 +2992,6 @@ CodeFirst 模式开发相关方法 - - - DbFirst 模式开发相关方法 - - < - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完将自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 事务体 () => {} - 超时,未执行完将自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - DbFirst 模式开发相关方法 diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index dfcbfa6b..618b5b16 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -276,8 +276,8 @@ where a.owner in ({1}) and {0} ds2item[1] = row[1]; ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); ds2item[4] = OdbcOracleCodeFirst.GetOracleSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); - ds2item[5] = string.Concat(row[7]) == "1"; - ds2item[6] = string.Concat(row[8]) == "1"; + ds2item[5] = string.Concat(row[7]); + ds2item[6] = string.Concat(row[8]); ds2item[7] = string.Concat(row[9]); ds2.Add(ds2item); } @@ -321,7 +321,7 @@ a.table_owner || '.' || a.table_name, nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), c.index_name, case when a.uniqueness = 'UNIQUE' then 1 else 0 end, -0, +case when exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') then 1 else 0 end, 0, case when c.descend = 'DESC' then 1 else 0 end, c.column_position @@ -331,7 +331,6 @@ where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name and a.table_owner in ({1}) and {0} -and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -352,6 +351,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; var loc9 = loc3[table_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + if (is_primary_key) continue; Dictionary loc10 = null; DbIndexInfo loc11 = null; diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 8f24499e..dfd9fef0 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -276,8 +276,8 @@ where a.owner in ({1}) and {0} ds2item[1] = row[1]; ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); ds2item[4] = OracleCodeFirst.GetOracleSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); - ds2item[5] = string.Concat(row[7]) == "1"; - ds2item[6] = string.Concat(row[8]) == "1"; + ds2item[5] = string.Concat(row[7]); + ds2item[6] = string.Concat(row[8]); ds2item[7] = string.Concat(row[9]); ds2.Add(ds2item); } @@ -321,7 +321,7 @@ a.table_owner || '.' || a.table_name, nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), c.index_name, case when a.uniqueness = 'UNIQUE' then 1 else 0 end, -0, +case when exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') then 1 else 0 end, 0, case when c.descend = 'DESC' then 1 else 0 end, c.column_position @@ -331,7 +331,6 @@ where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name and a.table_owner in ({1}) and {0} -and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -352,6 +351,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; var loc9 = loc3[table_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + if (is_primary_key) continue; Dictionary loc10 = null; DbIndexInfo loc11 = null; From 18176f3789f66cddc11ec067aa4ffbe2168b63a7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 12 Dec 2019 18:15:36 +0800 Subject: [PATCH 0328/1029] ## v0.12.18 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 15 files changed, 14 insertions(+), 21 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index ed78c3c2..c2b41bb1 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.17 + 0.12.18 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 55c56be1..aec1dd7c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a615211d..b74a4f98 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 2ed05a3b..d98d5484 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类; dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 0.12.17 + 0.12.18 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index dd3472ea..508cf294 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index dd4ea747..f18badda 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.17 + 0.12.18 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 02d5e48e..69a99d2c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 48b0f852..9fe06afe 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 79127d8f..9fdeff38 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index bf2be899..e766aa37 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 3d36549b..5503ebb4 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 76d6b763..2fa981be 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c0c5566a..0c2f0303 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 2e3ced2e..96a1049b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.17 + 0.12.18 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 2b85e2e22d5ae67cce98550f90319c1d5f23aed6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 13 Dec 2019 12:38:57 +0800 Subject: [PATCH 0329/1029] =?UTF-8?q?-=20=E6=9B=B4=E6=96=B0=20=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=20nullable=20=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ .../FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs | 2 +- .../FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 2891a2b2..99d486fd 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -182,7 +182,7 @@ a.data_length, a.data_precision, a.data_scale, a.char_used, -case when a.nullable = 'Y' then 1 else 0 end, +case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), b.comments diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 861dbbdc..3fb77c3f 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -258,7 +258,7 @@ a.data_length, a.data_precision, a.data_scale, a.char_used, -case when a.nullable = 'Y' then 1 else 0 end, +case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), b.comments from all_tab_cols a @@ -320,7 +320,7 @@ a.table_owner || '.' || a.table_name, c.column_name, c.index_name, case when a.uniqueness = 'UNIQUE' then 1 else 0 end, -0, +case when exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') then 1 else 0 end, 0, case when c.descend = 'DESC' then 1 else 0 end, c.column_position @@ -330,7 +330,6 @@ where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name and a.table_owner in ({1}) and {0} -and not exists(select 1 from all_constraints where index_name = a.index_name and constraint_type = 'P') ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -351,6 +350,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; var loc9 = loc3[table_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + if (is_primary_key) continue; Dictionary loc10 = null; DbIndexInfo loc11 = null; From dfb4662d869c1033e6626808b29223d17c39f69c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Dec 2019 01:34:38 +0800 Subject: [PATCH 0330/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20=E5=90=8C?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E6=97=B6=E9=97=B4=20fsql.Transaction=20?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E7=AD=89=E7=BA=A7=E5=8F=82=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E4=BC=A0=E5=85=A5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql/FreeSql.xml | 347 +++++++++--------- FreeSql/Interface/IAdo.cs | 9 +- FreeSql/Interface/IFreeSql.cs | 10 +- .../AdoProvider/AdoProviderTransaction.cs | 19 +- .../FreeSql.Provider.MySql/MySqlProvider.cs | 4 +- .../Dameng/OdbcDamengProvider.cs | 4 +- .../Default/OdbcProvider.cs | 4 +- ..._OdbcGBaseUpdate.cs => OdbcGBaseUpdate.cs} | 0 .../GBase/OdbcGBaseProvider.cs | 4 +- .../GBase/__OdbcGBaseCodeFirst.cs | 2 +- .../GBase/__OdbcGBaseExpression.cs | 52 +-- .../MySql/OdbcMySqlProvider.cs | 4 +- .../Oracle/OdbcOracleProvider.cs | 4 +- .../PostgreSQL/OdbcPostgreSQLProvider.cs | 4 +- .../SqlServer/OdbcSqlServerProvider.cs | 4 +- .../FreeSql.Provider.Oracle/OracleProvider.cs | 4 +- .../PostgreSQLProvider.cs | 4 +- .../SqlServerProvider.cs | 4 +- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 4 +- 20 files changed, 254 insertions(+), 240 deletions(-) rename Providers/FreeSql.Provider.Odbc/GBase/Curd/{__OdbcGBaseUpdate.cs => OdbcGBaseUpdate.cs} (100%) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ac93e9cc..124441f8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1960,10 +1960,18 @@ 事务体 () => {} - + 开启事务(不支持异步) + 超时,未执行完将自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + 事务体 () => {} 超时,未执行完将自动提交 @@ -2256,187 +2264,7 @@ - 增删查改,执行命令完成后触发 - - - - - CodeFirst迁移,执行之前触发 - - - - - CodeFirst迁移,执行完成触发 - - - - - Insert/Update自动值处理 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构 - - - - - 转大写同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 本功能会影响 IFreeSql 首次访问的速度。 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 @@ -2970,10 +2798,163 @@ 事务体 () => {} - + 开启事务(不支持异步) + 超时,未执行完将自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + + + + + 使用 and 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完将自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完将自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + 事务体 () => {} 超时,未执行完将自动提交 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index fd86d18c..fb830e6e 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -41,9 +41,16 @@ namespace FreeSql /// /// 开启事务(不支持异步) /// + /// 超时,未执行完将自动提交 + /// 事务体 () => {} + void Transaction(TimeSpan timeout, Action handler); + /// + /// 开启事务(不支持异步) + /// + /// /// 事务体 () => {} /// 超时,未执行完将自动提交 - void Transaction(Action handler, TimeSpan timeout); + void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler); /// /// 当前线程的事务 /// diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index e72033f9..4e1708c9 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -2,6 +2,7 @@ using FreeSql.Internal; using System; using System.Collections.Generic; +using System.Data; using System.Linq.Expressions; public interface IFreeSql : IFreeSql { } @@ -93,9 +94,16 @@ public interface IFreeSql : IDisposable /// /// 开启事务(不支持异步) /// + /// 超时,未执行完将自动提交 + /// 事务体 () => {} + void Transaction(TimeSpan timeout, Action handler); + /// + /// 开启事务(不支持异步) + /// + /// /// 事务体 () => {} /// 超时,未执行完将自动提交 - void Transaction(Action handler, TimeSpan timeout); + void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler); /// /// 数据库访问对象 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 8ed0c1e2..7da093e8 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -1,7 +1,8 @@ using SafeObjectPool; using System; -using System.Collections.Generic; using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Diagnostics; using System.Linq; @@ -33,7 +34,7 @@ namespace FreeSql.Internal.CommonProvider public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null; - public void BeginTransaction(TimeSpan timeout) + public void BeginTransaction(TimeSpan timeout, IsolationLevel? isolationLevel) { if (TransactionCurrentThread != null) return; @@ -44,7 +45,7 @@ namespace FreeSql.Internal.CommonProvider try { conn = MasterPool.Get(); - tran = new Transaction2(conn, conn.Value.BeginTransaction(), timeout); + tran = new Transaction2(conn, isolationLevel == null ? conn.Value.BeginTransaction() : conn.Value.BeginTransaction(isolationLevel.Value), timeout); } catch (Exception ex) { @@ -102,15 +103,15 @@ namespace FreeSql.Internal.CommonProvider public void CommitTransaction() => CommitTransaction(true); public void RollbackTransaction() => CommitTransaction(false); - public void Transaction(Action handler) - { - Transaction(handler, TimeSpan.FromSeconds(60)); - } - public void Transaction(Action handler, TimeSpan timeout) + public void Transaction(Action handler) => TransactionInternal(null, TimeSpan.FromSeconds(60), handler); + public void Transaction(TimeSpan timeout, Action handler) => TransactionInternal(null, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => TransactionInternal(isolationLevel, timeout, handler); + + void TransactionInternal(IsolationLevel? isolationLevel, TimeSpan timeout, Action handler) { try { - BeginTransaction(timeout); + BeginTransaction(timeout, isolationLevel); handler(); CommitTransaction(); } diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index b5f2dd8d..edfe0054 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using FreeSql.MySql.Curd; using System; using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; @@ -70,7 +71,8 @@ namespace FreeSql.MySql internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs index 40868691..97c84c96 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs @@ -2,6 +2,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Threading; @@ -49,7 +50,8 @@ namespace FreeSql.Odbc.Dameng internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index cac216c5..d4104e30 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -4,6 +4,7 @@ using FreeSql.Odbc.Default; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Data; using System.Linq; using System.Threading; @@ -83,7 +84,8 @@ namespace FreeSql.Odbc.Default internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseUpdate.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs similarity index 100% rename from Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseUpdate.cs rename to Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs index eee74c06..66e28e82 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs @@ -2,6 +2,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; +using System.Data; using System.Threading; namespace FreeSql.Odbc.GBase @@ -46,7 +47,8 @@ namespace FreeSql.Odbc.GBase internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs index 15478af5..2895d9de 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.GBase { typeof(byte).FullName, (OdbcType.SmallInt, "byte","byte NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (OdbcType.SmallInt, "byte", "byte", false, true, null) }, { typeof(ushort).FullName, (OdbcType.Int, "integer","integer NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "integer", "integer", false, true, null) }, - { typeof(uint).FullName, (OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "int8", "int8", false, true, null) }, + { typeof(uint).FullName, (OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "bigint", "bigint", false, true, null) }, { typeof(ulong).FullName, (OdbcType.Decimal, "decimal","decimal(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "decimal", "decimal(20,0)", false, true, null) }, { typeof(float).FullName, (OdbcType.Real, "smallfloat","smallfloat NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "smallfloat", "smallfloat", false, true, null) }, diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs index c250c87f..4d0a43f1 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs @@ -27,21 +27,21 @@ namespace FreeSql.Odbc.GBase switch (exp.Type.NullableTypeOrThis().ToString()) { case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; - case "System.Byte": return $"({getExp(operandExp)})::int2"; + case "System.Byte": return $"({getExp(operandExp)})::byte"; case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; - case "System.Decimal": return $"({getExp(operandExp)})::numeric"; - case "System.Double": return $"({getExp(operandExp)})::float8"; - case "System.Int16": return $"({getExp(operandExp)})::int2"; - case "System.Int32": return $"({getExp(operandExp)})::int4"; - case "System.Int64": return $"({getExp(operandExp)})::int8"; - case "System.SByte": return $"({getExp(operandExp)})::int2"; - case "System.Single": return $"({getExp(operandExp)})::float4"; - case "System.String": return $"({getExp(operandExp)})::varchar"; - case "System.UInt16": return $"({getExp(operandExp)})::int2"; - case "System.UInt32": return $"({getExp(operandExp)})::int4"; - case "System.UInt64": return $"({getExp(operandExp)})::int8"; - case "System.Guid": return $"({getExp(operandExp)})::uuid"; + case "System.Decimal": return $"({getExp(operandExp)})::decimal"; + case "System.Double": return $"({getExp(operandExp)})::float"; + case "System.Int16": return $"({getExp(operandExp)})::smallint"; + case "System.Int32": return $"({getExp(operandExp)})::integer"; + case "System.Int64": return $"({getExp(operandExp)})::bigint"; + case "System.SByte": return $"({getExp(operandExp)})::smallint"; + case "System.Single": return $"({getExp(operandExp)})::smallfloat"; + case "System.String": return $"({getExp(operandExp)})::nvarchar"; + case "System.UInt16": return $"({getExp(operandExp)})::integer"; + case "System.UInt32": return $"({getExp(operandExp)})::bigint"; + case "System.UInt64": return $"({getExp(operandExp)})::decimal"; + case "System.Guid": return $"({getExp(operandExp)})::char"; } } break; @@ -59,26 +59,26 @@ namespace FreeSql.Odbc.GBase switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) { case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; - case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Byte": return $"({getExp(callExp.Arguments[0])})::byte"; case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; - case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; - case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; - case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; - case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; - case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; - case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; - case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; - case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; - case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; - case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; - case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid"; + case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::decimal"; + case "System.Double": return $"({getExp(callExp.Arguments[0])})::float"; + case "System.Int16": return $"({getExp(callExp.Arguments[0])})::smallint"; + case "System.Int32": return $"({getExp(callExp.Arguments[0])})::integer"; + case "System.Int64": return $"({getExp(callExp.Arguments[0])})::bigint"; + case "System.SByte": return $"({getExp(callExp.Arguments[0])})::smallint"; + case "System.Single": return $"({getExp(callExp.Arguments[0])})::smallfloat"; + case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::integer"; + case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::bigint"; + case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::decimal"; + case "System.Guid": return $"({getExp(callExp.Arguments[0])})::char"; } break; case "NewGuid": return null; case "Next": - if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; + if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::integer"; return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "random()"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index f779a505..95b21a6b 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -2,6 +2,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; @@ -48,7 +49,8 @@ namespace FreeSql.Odbc.MySql internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index 9191ce78..e82bc16d 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -2,6 +2,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Threading; @@ -49,7 +50,8 @@ namespace FreeSql.Odbc.Oracle internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index 8358e646..d858489a 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -2,6 +2,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; +using System.Data; using System.Threading; namespace FreeSql.Odbc.PostgreSQL @@ -46,7 +47,8 @@ namespace FreeSql.Odbc.PostgreSQL internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index 58c63d56..faf7847a 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -2,6 +2,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; +using System.Data; using System.Threading; namespace FreeSql.Odbc.SqlServer @@ -54,7 +55,8 @@ namespace FreeSql.Odbc.SqlServer internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index dfed6ce9..6be0984e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using FreeSql.Oracle.Curd; using System; using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Threading; @@ -44,7 +45,8 @@ namespace FreeSql.Oracle internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index 550e9284..a900c60a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -7,6 +7,7 @@ using NpgsqlTypes; using System; using System.Collections; using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Net; @@ -97,7 +98,8 @@ namespace FreeSql.PostgreSQL internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index 3efeae05..0de7d235 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using FreeSql.SqlServer.Curd; using System; using System.Collections.Generic; +using System.Data; using System.Threading; namespace FreeSql.SqlServer @@ -55,7 +56,8 @@ namespace FreeSql.SqlServer internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 5c17d9f9..ba92b82f 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using FreeSql.Sqlite.Curd; using System; using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Threading; @@ -43,7 +44,8 @@ namespace FreeSql.Sqlite internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); From 655d19153b684951ca89db785e34ab2bb7600f8d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Dec 2019 01:37:50 +0800 Subject: [PATCH 0331/1029] ## v0.12.19 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/ConsoleApp.cs | 1 + .../FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 327 ++++++++++-------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 196 insertions(+), 160 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index c2b41bb1..c7e4160a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.18 + 0.12.19 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index aec1dd7c..d7d86b4e 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b74a4f98..dedb95f8 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 16614070..10cfbe88 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -50,6 +50,7 @@ namespace FreeSql.Generator new Colorful.Formatter("https://github.com/2881099/FreeSql", Color.DeepSkyBlue), new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetName().Version.ToString().Split('.').Where((a, b) => b <= 2)), Color.SlateGray)); + ArgsNameOptions = new[] { false, false, false, false }; ArgsOutput = Directory.GetCurrentDirectory(); ArgsFileName = "{name}.cs"; string args0 = args[0].Trim().ToLower(); diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d98d5484..10f86913 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类; dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 0.12.18 + 0.12.19 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 508cf294..b1e3ae5b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index f18badda..d46dad3d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.18 + 0.12.19 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 69a99d2c..2c6d4526 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 124441f8..503ef504 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2264,7 +2264,187 @@ - 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 增删查改,执行命令完成后触发 + + + + + CodeFirst迁移,执行之前触发 + + + + + CodeFirst迁移,执行完成触发 + + + + + Insert/Update自动值处理 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构 + + + + + 转大写同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 本功能会影响 IFreeSql 首次访问的速度。 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 @@ -2805,151 +2985,6 @@ 超时,未执行完将自动提交 事务体 () => {} - - - 开启事务(不支持异步) - - - - - - - 使用 and 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完将自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完将自动提交 - 事务体 () => {} - 开启事务(不支持异步) diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 9fe06afe..32b48104 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 9fdeff38..048c7a19 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e766aa37..88d02e41 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 5503ebb4..794002e7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2fa981be..1e745fbf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0c2f0303..9195657d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 96a1049b..4018b497 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.18 + 0.12.19 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 15c3ab72979f6ba7142efc087f9d29d27357023a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Dec 2019 11:43:17 +0800 Subject: [PATCH 0332/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.ForU?= =?UTF-8?q?pdate=20=E6=8E=92=E4=BB=96=E6=9B=B4=E6=96=B0=E9=94=81=EF=BC=88?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=95=B0=E6=8D=AE=E5=BA=93=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E7=9A=84=E8=A7=84=E5=88=99=EF=BC=8C=E8=A7=81=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=EF=BC=89=EF=BC=9B=20-=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=20SqlServer=20WithLock=20=E5=8A=9F=E8=83=BD=EF=BC=8C=E7=BB=84?= =?UTF-8?q?=E5=90=88=E5=A4=9A=E7=A7=8D=E4=BD=BF=E7=94=A8=20|=20=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E7=9B=B8=E8=81=94=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ++++ .../MySqlConnector/Curd/MySqlSelectTest.cs | 16 ++++++++ .../Dameng/Curd/DamengSelectTest.cs | 16 ++++++++ .../Default/Curd/OdbcSelectTest.cs | 16 ++++++++ .../MySql/Curd/MySqlSelectTest.cs | 16 ++++++++ .../Oracle/Curd/OracleSelectTest.cs | 16 ++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 16 ++++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 16 ++++++++ .../MySql/Curd/MySqlSelectTest.cs | 16 ++++++++ .../Oracle/Curd/OracleSelectTest.cs | 16 ++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 16 ++++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 39 +++++++++++++++++++ .../Sqlite/Curd/SqliteSelectTest.cs | 16 ++++++++ FreeSql/FreeSql.xml | 26 ++++++++++--- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 14 +++++++ FreeSql/Interface/IAdo.cs | 6 +-- FreeSql/Interface/IFreeSql.cs | 6 +-- .../SelectProvider/Select0Provider.cs | 31 +++++++++++++++ .../SelectProvider/Select1Provider.cs | 7 +++- .../Curd/MySqlSelect.cs | 24 ++++++------ .../Dameng/Curd/OdbcDamengSelect.cs | 24 ++++++------ .../Default/Curd/OdbcSelect.cs | 24 ++++++------ .../GBase/Curd/OdbcGBaseSelect.cs | 24 ++++++------ .../MySql/Curd/OdbcMySqlSelect.cs | 24 ++++++------ .../Oracle/Curd/OdbcOracleSelect.cs | 24 ++++++------ .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 24 ++++++------ .../SqlServer/Curd/OdbcSqlServerSelect.cs | 34 ++++++++-------- .../Curd/OracleSelect.cs | 24 ++++++------ .../Curd/PostgreSQLSelect.cs | 24 ++++++------ .../Curd/SqlServerSelect.cs | 34 ++++++++-------- .../SqlServerExtensions.cs | 20 ++++++++-- .../Curd/SqliteSelect.cs | 24 ++++++------ 32 files changed, 470 insertions(+), 170 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 4c3e0afa..c4759737 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1598,5 +1598,21 @@ namespace FreeSql.Tests.MySqlConnector Assert.Equal(5, g.mysql.Select().Count()); Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.mysql; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`id`, a.`name` FROM `ToUpd1Pk` a limit 0,1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`id`, a.`name` FROM `ToUpd1Pk` a limit 0,1 for update", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index e3c76774..ceb18b68 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -1525,5 +1525,21 @@ namespace FreeSql.Tests.Odbc.Dameng Assert.Equal(5, g.dameng.Select().Count()); Assert.Equal(5, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.dameng; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index b3ee6661..07ab8234 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -1336,5 +1336,21 @@ namespace FreeSql.Tests.Odbc.Default Assert.Equal(5, g.odbc.Select().Count()); Assert.Equal(5, g.odbc.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.odbc; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index b8fca5e8..51482200 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1609,5 +1609,21 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal(5, g.mysql.Select().Count()); Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.mysql; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`id`, a.`name` FROM `ToUpd1Pk` a limit 0,1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`id`, a.`name` FROM `ToUpd1Pk` a limit 0,1 for update", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 0de86c1f..0568f121 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -1525,5 +1525,21 @@ namespace FreeSql.Tests.Odbc.Oracle Assert.Equal(5, g.oracle.Select().Count()); Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.oracle; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 639a59c5..faf70373 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1581,5 +1581,21 @@ namespace FreeSql.Tests.Odbc.PostgreSQL Assert.Equal(5, g.pgsql.Select().Count()); Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.pgsql; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"name\" FROM \"toupd1pk\" a limit 1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"name\" FROM \"toupd1pk\" a limit 1 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index d604deeb..0d92fd45 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -1475,5 +1475,21 @@ namespace FreeSql.Tests.Odbc.SqlServer Assert.Equal(5, g.sqlserver.Select().Count()); Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.sqlserver; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock)", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock, NoWait)", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 618d02b2..7783236f 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1640,5 +1640,21 @@ namespace FreeSql.Tests.MySql Assert.Equal(5, g.mysql.Select().Count()); Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.mysql; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`id`, a.`name` FROM `ToUpd1Pk` a limit 0,1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`id`, a.`name` FROM `ToUpd1Pk` a limit 0,1 for update", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index b690941a..bf8cd0a0 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -1525,5 +1525,21 @@ namespace FreeSql.Tests.Oracle Assert.Equal(5, g.oracle.Select().Count()); Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.oracle; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 613cfde5..9308436d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1598,5 +1598,21 @@ namespace FreeSql.Tests.PostgreSQL Assert.Equal(5, g.pgsql.Select().Count()); Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.pgsql; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"name\" FROM \"toupd1pk\" a limit 1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"name\" FROM \"toupd1pk\" a limit 1 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index a34a5924..92be87cb 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1520,5 +1520,44 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(5, g.sqlserver.Select().Count()); Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void WithLock() + { + var orm = g.sqlserver; + orm.Transaction(() => + { + var sql = orm.Select().WithLock().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(NoLock)", sql); + orm.Select().WithLock().Limit(1).ToList(); + + sql = orm.Select().WithLock(SqlServerLock.NoLock).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(NoLock)", sql); + orm.Select().WithLock(SqlServerLock.NoLock).Limit(1).ToList(); + + sql = orm.Select().WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(NoLock, NoWait)", sql); + orm.Select().WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait).Limit(1).ToList(); + + sql = orm.Select().WithLock(SqlServerLock.UpdLock | SqlServerLock.RowLock | SqlServerLock.NoWait).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock, NoWait)", sql); + orm.Select().WithLock(SqlServerLock.UpdLock | SqlServerLock.RowLock | SqlServerLock.NoWait).Limit(1).ToList(); + }); + } + [Fact] + public void ForUpdate() + { + var orm = g.sqlserver; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock)", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock, NoWait)", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 75739c13..d0008de7 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1673,5 +1673,21 @@ namespace FreeSql.Tests.Sqlite Assert.Equal(5, g.sqlite.Select().Count()); Assert.Equal(5, g.sqlite.Select().Where(a => a.name.StartsWith("nick")).Count()); } + + [Fact] + public void ForUpdate() + { + var orm = g.sqlite; + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"name\" FROM \"ToUpd1Pk\" a limit 0,1", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"name\" FROM \"ToUpd1Pk\" a limit 0,1", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 503ef504..f9ceda03 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1154,6 +1154,20 @@ 零个或多个过滤器名字 + + + 排他更新锁 + 注意:务必在开启事务后使用该功能 + MySql: for update + SqlServer: With(UpdLock, RowLock, NoWait) + PostgreSQL: for update nowait + Oracle: for update nowait + Sqlite: 无效果 + 达梦: for update nowait + + noawait + + 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) @@ -1956,7 +1970,7 @@ - 开启事务(不支持异步),60秒未执行完将自动提交 + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 事务体 () => {} @@ -1964,7 +1978,7 @@ 开启事务(不支持异步) - 超时,未执行完将自动提交 + 超时,未执行完成(可能)被其他线程事务自动提交 事务体 () => {} @@ -1973,7 +1987,7 @@ 事务体 () => {} - 超时,未执行完将自动提交 + 超时,未执行完成(可能)被其他线程事务自动提交 @@ -2974,7 +2988,7 @@ - 开启事务(不支持异步),60秒未执行完将自动提交 + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 事务体 () => {} @@ -2982,7 +2996,7 @@ 开启事务(不支持异步) - 超时,未执行完将自动提交 + 超时,未执行完成(可能)被其他线程事务自动提交 事务体 () => {} @@ -2991,7 +3005,7 @@ 事务体 () => {} - 超时,未执行完将自动提交 + 超时,未执行完成(可能)被其他线程事务自动提交 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 163743bf..a9366d41 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -250,6 +250,20 @@ namespace FreeSql /// TSelect DisableGlobalFilter(params string[] name); + /// + /// 排他更新锁 + /// 注意:务必在开启事务后使用该功能 + /// MySql: for update + /// SqlServer: With(UpdLock, RowLock, NoWait) + /// PostgreSQL: for update nowait + /// Oracle: for update nowait + /// Sqlite: 无效果 + /// 达梦: for update nowait + /// + /// noawait + /// + TSelect ForUpdate(bool nowait = false); + /// /// 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) /// diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index fb830e6e..b42cb61e 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -34,14 +34,14 @@ namespace FreeSql #region 事务 /// - /// 开启事务(不支持异步),60秒未执行完将自动提交 + /// 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 /// /// 事务体 () => {} void Transaction(Action handler); /// /// 开启事务(不支持异步) /// - /// 超时,未执行完将自动提交 + /// 超时,未执行完成(可能)被其他线程事务自动提交 /// 事务体 () => {} void Transaction(TimeSpan timeout, Action handler); /// @@ -49,7 +49,7 @@ namespace FreeSql /// /// /// 事务体 () => {} - /// 超时,未执行完将自动提交 + /// 超时,未执行完成(可能)被其他线程事务自动提交 void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler); /// /// 当前线程的事务 diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index 4e1708c9..19064fd0 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -87,14 +87,14 @@ public interface IFreeSql : IDisposable IDelete Delete(object dywhere) where T1 : class; /// - /// 开启事务(不支持异步),60秒未执行完将自动提交 + /// 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 /// /// 事务体 () => {} void Transaction(Action handler); /// /// 开启事务(不支持异步) /// - /// 超时,未执行完将自动提交 + /// 超时,未执行完成(可能)被其他线程事务自动提交 /// 事务体 () => {} void Transaction(TimeSpan timeout, Action handler); /// @@ -102,7 +102,7 @@ public interface IFreeSql : IDisposable /// /// /// 事务体 () => {} - /// 超时,未执行完将自动提交 + /// 超时,未执行完成(可能)被其他线程事务自动提交 void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler); /// diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index ad4c1ee6..e56102fd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -26,6 +26,7 @@ namespace FreeSql.Internal.CommonProvider protected List _tables = new List(); protected List> _tableRules = new List>(); protected Func _aliasRule; + protected string _tosqlAppendContent; protected StringBuilder _join = new StringBuilder(); protected IFreeSql _orm; protected CommonUtils _commonUtils; @@ -990,6 +991,36 @@ namespace FreeSql.Internal.CommonProvider } return this as TSelect; } + public TSelect ForUpdate(bool noawait = false) + { + if (_transaction == null && _orm.Ado.TransactionCurrentThread == null) + throw new Exception("安全起见,请务必在事务开启之后,再使用 ForUpdate"); + switch (_orm.Ado.DataType) + { + case DataType.MySql: + case DataType.OdbcMySql: + _tosqlAppendContent = " for update"; + break; + case DataType.SqlServer: + case DataType.OdbcSqlServer: + _aliasRule = (_, old) => $"{old} With(UpdLock, RowLock{(noawait ? ", NoWait" : "")})"; + break; + case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: + _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; + break; + case DataType.Oracle: + case DataType.OdbcOracle: + _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; + break; + case DataType.Sqlite: + break; + case DataType.OdbcDameng: + _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; + break; + } + return this as TSelect; + } #region common protected TMember InternalAvg(Expression exp) => this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 1f65260f..a2c3a341 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -636,13 +636,18 @@ namespace FreeSql.Internal.CommonProvider foreach (var item in list) setListValue(item, null); - var subSelect = _orm.Select().DisableGlobalFilter().WithConnection(_connection).WithTransaction(_transaction).TrackToList(_trackToList) as Select1Provider; + var subSelect = _orm.Select() + .DisableGlobalFilter() + .WithConnection(_connection) + .WithTransaction(_transaction) + .TrackToList(_trackToList) as Select1Provider; if (_tableRules?.Any() == true) foreach (var tr in _tableRules) subSelect.AsTable(tr); if (_whereCascadeExpression.Any()) subSelect._whereCascadeExpression.AddRange(_whereCascadeExpression.ToArray()); + //subSelect._aliasRule = _aliasRule; //把 SqlServer 查询锁传递下去 then?.Invoke(subSelect); var subSelectT1Alias = subSelect._tables[0].Alias; var oldWhere = subSelect._where.ToString(); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index e3afe83b..c29cc5e7 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.MySql.Curd class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -109,7 +109,7 @@ namespace FreeSql.MySql.Curd sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -122,51 +122,51 @@ namespace FreeSql.MySql.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs index b421d3b1..0f0c131c 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Odbc.Dameng class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -121,7 +121,7 @@ namespace FreeSql.Odbc.Dameng sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -134,51 +134,51 @@ namespace FreeSql.Odbc.Dameng public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index 48c08927..1611f4f7 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -11,7 +11,7 @@ namespace FreeSql.Odbc.Default class OdbcSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { var _utils = _commonUtils as OdbcUtils; if (_orm.CodeFirst.IsAutoSyncStructure) @@ -125,7 +125,7 @@ namespace FreeSql.Odbc.Default if (_limit > 0 && _utils.Adapter.SelectTopStyle == OdbcAdapter.SelecTopStyle.Limit) sb.Append(" \r\nLIMIT ").Append(_skip + _limit); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -138,51 +138,51 @@ namespace FreeSql.Odbc.Default public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs index b34ea8c5..ef74c2f1 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Odbc.GBase class OdbcGBaseSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -113,7 +113,7 @@ namespace FreeSql.Odbc.GBase sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public OdbcGBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -126,51 +126,51 @@ namespace FreeSql.Odbc.GBase public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index 3fef9f09..13790134 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Odbc.MySql class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -109,7 +109,7 @@ namespace FreeSql.Odbc.MySql sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -122,51 +122,51 @@ namespace FreeSql.Odbc.MySql public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index fedef69e..bf1d8471 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Odbc.Oracle class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -121,7 +121,7 @@ namespace FreeSql.Odbc.Oracle sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -134,51 +134,51 @@ namespace FreeSql.Odbc.Oracle public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 2125f405..0ef6c116 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Odbc.PostgreSQL class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -111,7 +111,7 @@ namespace FreeSql.Odbc.PostgreSQL sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -124,51 +124,51 @@ namespace FreeSql.Odbc.PostgreSQL public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index 12c218dc..09b2cd46 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -12,13 +12,13 @@ namespace FreeSql.Odbc.SqlServer class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) => (_commonUtils as OdbcSqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _whereCascadeExpression, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _whereCascadeExpression, _orm); + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -128,12 +128,12 @@ namespace FreeSql.Odbc.SqlServer sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -244,7 +244,7 @@ namespace FreeSql.Odbc.SqlServer sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } #endregion @@ -258,51 +258,51 @@ namespace FreeSql.Odbc.SqlServer public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 9df0a9d5..fb94feaa 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Oracle.Curd class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -121,7 +121,7 @@ namespace FreeSql.Oracle.Curd sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -134,51 +134,51 @@ namespace FreeSql.Oracle.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 136f1d3a..4485b2be 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.PostgreSQL.Curd class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -111,7 +111,7 @@ namespace FreeSql.PostgreSQL.Curd sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -124,51 +124,51 @@ namespace FreeSql.PostgreSQL.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 5678baaa..ccb2d920 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -12,13 +12,13 @@ namespace FreeSql.SqlServer.Curd class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _whereCascadeExpression, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _whereCascadeExpression, _orm); + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -128,12 +128,12 @@ namespace FreeSql.SqlServer.Curd sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -244,7 +244,7 @@ namespace FreeSql.SqlServer.Curd sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } #endregion @@ -261,51 +261,51 @@ namespace FreeSql.SqlServer.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 2fef171e..ab503d90 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -25,8 +25,8 @@ public static partial class FreeSqlSqlServerGlobalExtensions /// public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T : class => rule == null ? - that.AsAlias((type, old) => $"{old} with({lockType.ToString()})") : - that.AsAlias((type, old) => rule.TryGetValue(type, out var trybool) && trybool ? $"{old} with({lockType.ToString()})" : old); + that.AsAlias((type, old) => $"{old} With({lockType.ToString()})") : + that.AsAlias((type, old) => rule.TryGetValue(type, out var trybool) && trybool ? $"{old} With({lockType.ToString()})" : old); /// /// 设置全局 SqlServer with(nolock) 查询 @@ -42,7 +42,21 @@ public static partial class FreeSqlSqlServerGlobalExtensions internal static ConcurrentDictionary)> _dicSetGlobalSelectWithLock = new ConcurrentDictionary)>(); } +[Flags] public enum SqlServerLock { - HoldLock, NoLock, PagLock, ReadCommitted, ReadPast, ReadUnCommitted, RepeaTableRead, RowLock, Serializable, TabLock, TabLockX, UpdLock, XLock + NoLock = 1, + HoldLock = 2, + UpdLock = 4, + RowLock = 8, + ReadCommitted = 16, + ReadPast = 32, + ReadUnCommitted = 64, + RepeaTableRead = 256, + PagLock = 512, + Serializable = 1024, + TabLock = 2048, + TabLockX = 4096, + XLock = 8192, + NoWait = 16384 } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index 33b16a1b..f2cf82db 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -12,7 +12,7 @@ namespace FreeSql.Sqlite.Curd class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); @@ -109,7 +109,7 @@ namespace FreeSql.Sqlite.Curd sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.ToString(); + return sb.Append(_tosqlAppendContent).ToString(); } public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } @@ -122,51 +122,51 @@ namespace FreeSql.Sqlite.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } From 97c1a31a679e343403ee809dcfcf7da4b354ffc1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Dec 2019 11:45:07 +0800 Subject: [PATCH 0333/1029] ## v0.12.20 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 131 ------------------ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 14 insertions(+), 152 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index c7e4160a..a721ceff 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.19 + 0.12.20 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index d7d86b4e..64685077 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index dedb95f8..0047ce19 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 10f86913..35c6ad32 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类; dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 0.12.19 + 0.12.20 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b1e3ae5b..6c19ca24 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d46dad3d..fa40fd15 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.19 + 0.12.20 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2c6d4526..100b5b3a 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index f9ceda03..0bac7629 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2125,137 +2125,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 32b48104..f3ac3f22 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 048c7a19..76068797 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 88d02e41..308f4983 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 794002e7..8ff89d47 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1e745fbf..b84a95f9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9195657d..d4968054 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4018b497..f23d830c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.19 + 0.12.20 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From f1625202020f2878dc466bff6bc0483b09b5ef8d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 14 Dec 2019 12:21:55 +0800 Subject: [PATCH 0334/1029] update ForUpdate tests --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + .../MySqlConnector/Curd/MySqlSelectTest.cs | 4 + .../Dameng/Curd/DamengSelectTest.cs | 4 + .../Default/Curd/OdbcSelectTest.cs | 4 + .../MySql/Curd/MySqlSelectTest.cs | 4 + .../Oracle/Curd/OracleSelectTest.cs | 4 + .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 4 + .../SqlServer/Curd/SqlServerSelectTest.cs | 4 + .../MySql/Curd/MySqlSelectTest.cs | 4 + .../Oracle/Curd/OracleSelectTest.cs | 4 + .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 4 + .../SqlServer/Curd/SqlServerSelectTest.cs | 4 + .../Sqlite/Curd/SqliteSelectTest.cs | 4 + FreeSql/FreeSql.xml | 131 ++++++++++++++++++ 14 files changed, 186 insertions(+) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index c4759737..bd98bc2a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1603,6 +1603,10 @@ namespace FreeSql.Tests.MySqlConnector public void ForUpdate() { var orm = g.mysql; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index ceb18b68..57002e1d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -1530,6 +1530,10 @@ namespace FreeSql.Tests.Odbc.Dameng public void ForUpdate() { var orm = g.dameng; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 07ab8234..1106202b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -1341,6 +1341,10 @@ namespace FreeSql.Tests.Odbc.Default public void ForUpdate() { var orm = g.odbc; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 51482200..88da23e6 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1614,6 +1614,10 @@ namespace FreeSql.Tests.Odbc.MySql public void ForUpdate() { var orm = g.mysql; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 0568f121..71a9e93d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -1530,6 +1530,10 @@ namespace FreeSql.Tests.Odbc.Oracle public void ForUpdate() { var orm = g.oracle; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index faf70373..d414956c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1586,6 +1586,10 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public void ForUpdate() { var orm = g.pgsql; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 0d92fd45..2fe461ca 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -1480,6 +1480,10 @@ namespace FreeSql.Tests.Odbc.SqlServer public void ForUpdate() { var orm = g.sqlserver; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 7783236f..ba3ab4af 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1645,6 +1645,10 @@ namespace FreeSql.Tests.MySql public void ForUpdate() { var orm = g.mysql; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index bf8cd0a0..2e36d4e8 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -1530,6 +1530,10 @@ namespace FreeSql.Tests.Oracle public void ForUpdate() { var orm = g.oracle; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 9308436d..662c084d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1603,6 +1603,10 @@ namespace FreeSql.Tests.PostgreSQL public void ForUpdate() { var orm = g.pgsql; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 92be87cb..9adc89d4 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1548,6 +1548,10 @@ namespace FreeSql.Tests.SqlServer public void ForUpdate() { var orm = g.sqlserver; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index d0008de7..dfaf65fc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1678,6 +1678,10 @@ namespace FreeSql.Tests.Sqlite public void ForUpdate() { var orm = g.sqlite; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + orm.Transaction(() => { var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 0bac7629..f9ceda03 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2125,6 +2125,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 }) + + + + + + 可自定义解析表达式 From c7b63ef4741bd7f05b32424157288ee677a5914f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 15 Dec 2019 13:04:08 +0800 Subject: [PATCH 0335/1029] =?UTF-8?q?-=20=E8=A7=A3=E5=86=B3=20vb.net=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=97=A0=E6=B3=95=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=AF=94=E8=BE=83=EF=BC=9B#140?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/test_vb/Program.vb | 26 +++++++++++++++++++ Examples/test_vb/test_vb.vbproj | 13 ++++++++++ FreeSql.sln | 15 +++++++++++ FreeSql/Internal/CommonExpression.cs | 14 ++++++++++ .../OdbcGBaseAdo/OdbcGBaseConnectionPool.cs | 2 ++ 5 files changed, 70 insertions(+) create mode 100644 Examples/test_vb/Program.vb create mode 100644 Examples/test_vb/test_vb.vbproj diff --git a/Examples/test_vb/Program.vb b/Examples/test_vb/Program.vb new file mode 100644 index 00000000..d0eb32f3 --- /dev/null +++ b/Examples/test_vb/Program.vb @@ -0,0 +1,26 @@ +Imports System + +Module Program + Sub Main(args As String()) + Console.WriteLine("Hello World!") + + Dim fsql = New FreeSql.FreeSqlBuilder() _ + .UseConnectionString(FreeSql.DataType.Sqlite, "data source=testvb.db") _ + .UseAutoSyncStructure(True) _ + .UseMonitorCommand(Sub(cmd) Trace.WriteLine(cmd.CommandText)) _ + .Build() + + REM Microsoft.VisualBasic.CompilerServices.Operators.CompareString() + Dim List1 = fsql.Select(Of Testvb).Where(Function(a) a.Id = 100).ToList() + Dim List2 = fsql.Select(Of Testvb).Where(Function(a) a.Title = "xxx").ToList() + Dim List3 = fsql.Select(Of Testvb).Where(Function(a) a.Title <> "xxx").ToList() + + fsql.Dispose() + End Sub +End Module + +Class Testvb + Property Id As Integer + Property Title As String +End Class + diff --git a/Examples/test_vb/test_vb.vbproj b/Examples/test_vb/test_vb.vbproj new file mode 100644 index 00000000..6c715f78 --- /dev/null +++ b/Examples/test_vb/test_vb.vbproj @@ -0,0 +1,13 @@ + + + + Exe + test_vb + netcoreapp3.1 + + + + + + + diff --git a/FreeSql.sln b/FreeSql.sln index b5273404..211de198 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -68,6 +68,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "orm_vs_net40", "Examples\or EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Generator", "Extensions\FreeSql.Generator\FreeSql.Generator.csproj", "{6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}" EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "test_vb", "Examples\test_vb\test_vb.vbproj", "{0A2206B1-1D34-45F4-B028-E3C5D6F02295}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -402,6 +404,18 @@ Global {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x64.Build.0 = Release|Any CPU {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x86.ActiveCfg = Release|Any CPU {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x86.Build.0 = Release|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|x64.ActiveCfg = Debug|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|x64.Build.0 = Debug|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|x86.ActiveCfg = Debug|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|x86.Build.0 = Debug|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|Any CPU.Build.0 = Release|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|x64.ActiveCfg = Release|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|x64.Build.0 = Release|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|x86.ActiveCfg = Release|Any CPU + {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -426,6 +440,7 @@ Global {C57444BA-8BF7-4790-A864-7F237123219B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} + {0A2206B1-1D34-45F4-B028-E3C5D6F02295} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index e7d7bd56..10af2539 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -417,6 +417,20 @@ namespace FreeSql.Internal } public string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) { + if (leftExp.NodeType == ExpressionType.Call && + rightExp.NodeType == ExpressionType.Constant && + new[] { "=", "<>" }.Contains(oper)) + { + var leftExpCall = leftExp as MethodCallExpression; + //vb 语法,将字符串比较转换为了 CompareString + if (leftExpCall.Method.Name == "CompareString" && + leftExpCall.Method.DeclaringType?.FullName == "Microsoft.VisualBasic.CompilerServices.Operators" && + leftExpCall.Arguments.Count == 3 && + leftExpCall.Arguments[2].Type == typeof(bool) && + rightExp.Type == typeof(int) && + (int)(rightExp as ConstantExpression).Value == 0) + return ExpressionBinary(oper, leftExpCall.Arguments[0], leftExpCall.Arguments[1], tsc); + } switch (oper) { case "OR": diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs index e9c6fae6..b22e01e5 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs @@ -9,6 +9,8 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +//jdbc:gbasedbt-sqli://192.168.164.10:9088/gbasedb:GBASEDBTSERVER=gbaseserver;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;NEWCODESET=GB18030,GB18030-2000,5488; + namespace FreeSql.Odbc.GBase { From 38d5580c54f3c55c0a233b5dba89d6580b867bb8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 16 Dec 2019 10:49:35 +0800 Subject: [PATCH 0336/1029] add vb.net tests --- Examples/test_vb/Program.vb | 26 ----------------- Examples/test_vb/test_vb.vbproj | 13 --------- .../BaseEntity 纯净版源码(.Net 4.0).zip | Bin 0 -> 2340 bytes .../FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ----- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj | 23 +++++++++++++++ FreeSql.Tests.VB/UnitTest1.vb | 23 +++++++++++++++ FreeSql.Tests.VB/g.vb | 18 ++++++++++++ FreeSql.sln | 27 +++++++++--------- FreeSql/FreeSql.csproj | 2 +- 12 files changed, 81 insertions(+), 64 deletions(-) delete mode 100644 Examples/test_vb/Program.vb delete mode 100644 Examples/test_vb/test_vb.vbproj create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip create mode 100644 FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj create mode 100644 FreeSql.Tests.VB/UnitTest1.vb create mode 100644 FreeSql.Tests.VB/g.vb diff --git a/Examples/test_vb/Program.vb b/Examples/test_vb/Program.vb deleted file mode 100644 index d0eb32f3..00000000 --- a/Examples/test_vb/Program.vb +++ /dev/null @@ -1,26 +0,0 @@ -Imports System - -Module Program - Sub Main(args As String()) - Console.WriteLine("Hello World!") - - Dim fsql = New FreeSql.FreeSqlBuilder() _ - .UseConnectionString(FreeSql.DataType.Sqlite, "data source=testvb.db") _ - .UseAutoSyncStructure(True) _ - .UseMonitorCommand(Sub(cmd) Trace.WriteLine(cmd.CommandText)) _ - .Build() - - REM Microsoft.VisualBasic.CompilerServices.Operators.CompareString() - Dim List1 = fsql.Select(Of Testvb).Where(Function(a) a.Id = 100).ToList() - Dim List2 = fsql.Select(Of Testvb).Where(Function(a) a.Title = "xxx").ToList() - Dim List3 = fsql.Select(Of Testvb).Where(Function(a) a.Title <> "xxx").ToList() - - fsql.Dispose() - End Sub -End Module - -Class Testvb - Property Id As Integer - Property Title As String -End Class - diff --git a/Examples/test_vb/test_vb.vbproj b/Examples/test_vb/test_vb.vbproj deleted file mode 100644 index 6c715f78..00000000 --- a/Examples/test_vb/test_vb.vbproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - Exe - test_vb - netcoreapp3.1 - - - - - - - diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip new file mode 100644 index 0000000000000000000000000000000000000000..15569d335e8997e97db1eaafcf78e9924c4056ce GIT binary patch literal 2340 zcmZ`*XEYqz8Xdhen2d2nO|+Y_x8-n$@( z9?^whkSlk+`(ECA>z(hcZ?AKHeEa*e_u4QmB4Q8#03Zk0mZJ2uZa>i(A_4%QGyuT$ z1t?j0AXHpD?LD6h+j!JG>@6P`1${E!k~hKWQ{-Fs!-zpJ5<=x@6AmzsTN{_xiyaV` z0wJ+A+Xp@c!m!63un+}p)MpzX3e=63)|%G^_G4ruQB08mJAQiy#|Hmza$o)^cb>s+uM+RT{PE0z*PQq758RIe4!1~S);HL?Q--sR7zbOh_`m=l-R?k( zeDwQIlFW3wgFy}8#UJ}SYv#fp!ICaGT&blTzR@w=(qh*css^Q)7%kA@bCG%nFdEdh{i<4ql1#vBOhgjWFb4)s>q8t$ zcZ9Mxierm=%bKcCl%=)S^O;Dr*x@i?>)GT8`j%aLlGKzLsog~F;hW|m?_Scr@G!Qo zW6k^*oOkZwgdPs9@r;&`CY*@xl7)p%CnPuK+14rdbMwT=p)N?{j08Sr`SYu;%XEWR z(h54H7ODIOX4k1oCI~1SoYaGFQk*CC1N~m^DC~6DiJ%4IgNG;L6Ug=wqlt*9UE137 z>kihiy|GNao&2s2es2~h9&S%1FW=P-9@K9A_J{GjUSC~IG7F!FP_x9=Rk{x-kIG?! z)XFWd*#O@(I}sF_NL?5uL_WxVv-{VR#}qKkVry6$HV{#ystyikkHZLYf1;As!r8sV}D z#G?9YPjcy1HR2veGy;z;ltt{NVGDd(MCLLXd`zarcZcKJepHpf&$#k3PF>h8DPaE+ zzUsB`!P9!ko5TRXGim_f#(xN3A7S-G&&BDd0Sp?MmX0fc0$WCYxb_%CaX(aqIj)q0 zh&zq^VQBlivms8e(~2Gvdzbrml6?;#sCZ>U^59#;MH+VgeAUvGM*}NfH_1mibRRol zx}LF@aisHpIOv$!jkZHP%B|Vi9u8DvVeMXf#W-z+Y1bBf>ka8fu8WOXRH}_wbt5t$ zf&#OO8MU>?scKLg#wN#DaAyyQMG2Pb79X1yK`ldGF6xmZN@R`cN0@Z`}D7Q)-+ z&-M?sW&|@_=Q+fM_YMZyY+{|;!0R(%osAnWjOm!D1lFIUR!dRP*P3E^Bg zwXde7;~s2GNYv{=4HadUmqSd(kFa1UK#aMtXX&xYE9guZWMRv-UAiJUM$S}wNr2ix z!`5{q|3p|b&d?geuR+TwyGXN;p;;CVC2pp>l+d$owx`I?7N&Sy==xwX!maiExD`Gj zOGzt72}d!{Bwl8@z`$}rkD3-}ge|^&Um&ZZd$Exc`VM=m*g-79^@X7OO%?E%oaB>4 zJwZl;8k5w~6Vay8ja^7lN!ai7E=X1~ma$M^bQ}y(DkjA?6?UuLjRMpOg14Gy{#M@y zT}l6lo7sf;lsgjK>UQ(Ot=q9V^iD1KzztD$<8T(HF}2K7?=GA=kq*5?Tghno6o$5NK)9kEkkqQFYurC7v}cYzotS|Zmg|OG9B2u z9@n0-0WDFBL&(sNRFcam&AWMDVl!^#=IgegdpKdwqeX=VHN}fo;9ta&%VTVnqUWHQ z!HK^a^Jx_=FECgJpm`OXfJLy&UP-frm(>^x-u*I=P7_}D3INk0Ae0CEza(+{+ERWV zj=%bUl)R`f4=?%^=&!$ literal 0 HcmV?d00001 diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 35c6ad32..e057bf5e 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -9,7 +9,7 @@ 2881099 2881099 FreeSql123 - 使用 FreeSql 快速生成数据库的实体类; dotnet tool install -g FreeSql.Generator + 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql 0.12.20 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6c19ca24..4ebadbdd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -5,7 +5,7 @@ 0.12.20 true YeXiangQin - FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. 达梦 https://github.com/2881099/FreeSql.DbContext FreeSql ORM DbContext git diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index fa40fd15..f3ed3c0a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 0.12.20 YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository true diff --git a/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj b/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj new file mode 100644 index 00000000..a8e7b84e --- /dev/null +++ b/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj @@ -0,0 +1,23 @@ + + + + FreeSql.Tests.VB + netcoreapp3.1 + + false + + + + + + + + + + + + + + + + diff --git a/FreeSql.Tests.VB/UnitTest1.vb b/FreeSql.Tests.VB/UnitTest1.vb new file mode 100644 index 00000000..7c8a5f14 --- /dev/null +++ b/FreeSql.Tests.VB/UnitTest1.vb @@ -0,0 +1,23 @@ +Imports System +Imports Xunit + +Namespace FreeSql.Tests.VB + Public Class UnitTest1 + + Sub TestSub() + + REM VB.net ʽԲ + Dim List1 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = 100).ToList() + Dim List2 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = "xxx").ToList() + Dim List3 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> "xxx").ToList() + + Dim List4 = g.sqlserver.Select(Of Testvb).ToList(Function(a) New With {a, a.Id, a.Title}) + + End Sub + End Class +End Namespace + +Class Testvb + Property Id As Integer + Property Title As String +End Class diff --git a/FreeSql.Tests.VB/g.vb b/FreeSql.Tests.VB/g.vb new file mode 100644 index 00000000..7a83db79 --- /dev/null +++ b/FreeSql.Tests.VB/g.vb @@ -0,0 +1,18 @@ +Imports System.Threading + +Public Class g + + Shared sqlserverLazy As Lazy(Of IFreeSql) = New Lazy(Of IFreeSql)(New Func(Of IFreeSql)(Function() New FreeSqlBuilder() _ + .UseConnectionString(DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") _ + .UseAutoSyncStructure(True) _ + .UseMonitorCommand(Sub(cmd) Trace.WriteLine("\r\n线程" & Thread.CurrentThread.ManagedThreadId & ": " & cmd.CommandText)) _ + .UseLazyLoading(True) _ + .Build())) + + Public Shared ReadOnly Property sqlserver As IFreeSql + Get + Return sqlserverLazy.Value + End Get + End Property + +End Class diff --git a/FreeSql.sln b/FreeSql.sln index 211de198..32083dc2 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -68,7 +68,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "orm_vs_net40", "Examples\or EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Generator", "Extensions\FreeSql.Generator\FreeSql.Generator.csproj", "{6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}" EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "test_vb", "Examples\test_vb\test_vb.vbproj", "{0A2206B1-1D34-45F4-B028-E3C5D6F02295}" +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "FreeSql.Tests.VB", "FreeSql.Tests.VB\FreeSql.Tests.VB.vbproj", "{A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -404,18 +404,18 @@ Global {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x64.Build.0 = Release|Any CPU {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x86.ActiveCfg = Release|Any CPU {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}.Release|x86.Build.0 = Release|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|x64.ActiveCfg = Debug|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|x64.Build.0 = Debug|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|x86.ActiveCfg = Debug|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Debug|x86.Build.0 = Debug|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|Any CPU.Build.0 = Release|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|x64.ActiveCfg = Release|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|x64.Build.0 = Release|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|x86.ActiveCfg = Release|Any CPU - {0A2206B1-1D34-45F4-B028-E3C5D6F02295}.Release|x86.Build.0 = Release|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Debug|x64.ActiveCfg = Debug|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Debug|x64.Build.0 = Debug|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Debug|x86.ActiveCfg = Debug|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Debug|x86.Build.0 = Debug|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|Any CPU.Build.0 = Release|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|x64.ActiveCfg = Release|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|x64.Build.0 = Release|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|x86.ActiveCfg = Release|Any CPU + {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -440,7 +440,6 @@ Global {C57444BA-8BF7-4790-A864-7F237123219B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} - {0A2206B1-1D34-45F4-B028-E3C5D6F02295} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 100b5b3a..e0441819 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -5,7 +5,7 @@ 0.12.20 true YeXiangQin - FreeSql is the most convenient ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. 达梦 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git From fe7b7e50127e0f0bbdfcb06cc06860718939c724 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 16 Dec 2019 12:12:55 +0800 Subject: [PATCH 0337/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20GlobalFilter?= =?UTF-8?q?=20=E8=BF=87=E6=BB=A4=E5=99=A8=E8=A1=A8=E8=BE=BE=E5=BC=8F=20boo?= =?UTF-8?q?l=20=E8=A7=A3=E6=9E=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests.VB/UnitTest1.vb | 3 ++ .../MySqlConnectorExpression/OtherTest.cs | 1 + .../Dameng/DamengExpression/OtherTest.cs | 1 + .../Default/OdbcExpression/OtherTest.cs | 1 + .../MySql/MySqlExpression/OtherTest.cs | 1 + .../Oracle/OracleExpression/OtherTest.cs | 1 + .../PostgreSQLExpression/OtherTest.cs | 1 + .../SqlServerExpression/OtherTest.cs | 1 + .../MySql/MySqlExpression/OtherTest.cs | 1 + .../Oracle/OracleExpression/OtherTest.cs | 1 + .../PostgreSQLExpression/OtherTest.cs | 1 + .../SqlServerExpression/OtherTest.cs | 1 + .../Sqlite/SqliteExpression/OtherTest.cs | 1 + FreeSql/Internal/CommonExpression.cs | 33 +++++++++---------- 14 files changed, 30 insertions(+), 18 deletions(-) diff --git a/FreeSql.Tests.VB/UnitTest1.vb b/FreeSql.Tests.VB/UnitTest1.vb index 7c8a5f14..2a233711 100644 --- a/FreeSql.Tests.VB/UnitTest1.vb +++ b/FreeSql.Tests.VB/UnitTest1.vb @@ -13,6 +13,8 @@ Namespace FreeSql.Tests.VB Dim List4 = g.sqlserver.Select(Of Testvb).ToList(Function(a) New With {a, a.Id, a.Title}) + Dim List5 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IsDeleted).ToList() + End Sub End Class End Namespace @@ -20,4 +22,5 @@ End Namespace Class Testvb Property Id As Integer Property Title As String + Property IsDeleted As Boolean End Class diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs index 19ab9e10..f882ed1a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs @@ -41,6 +41,7 @@ namespace FreeSql.Tests.MySqlConnectorExpression var t3 = select.Where(a => a.testFieldBool == false).ToList(); var t4 = select.Where(a => !a.testFieldBool).ToList(); var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/OtherTest.cs index 5129514b..c5cdb567 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/OtherTest.cs @@ -39,6 +39,7 @@ namespace FreeSql.Tests.Odbc.DamengExpression var t3 = select.Where(a => a.Bool == false).ToList(); var t4 = select.Where(a => !a.Bool).ToList(); var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).Limit(10).ToList(); var t11 = select.Where(a => a.BoolNullable == true).ToList(); var t22 = select.Where(a => a.BoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs index cf22c6f2..b7cd5c7b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/OtherTest.cs @@ -35,6 +35,7 @@ namespace FreeSql.Tests.Odbc.DefaultExpression var t3 = select.Where(a => a.testFieldBool == false).ToList(); var t4 = select.Where(a => !a.testFieldBool).ToList(); var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs index 3c31f047..c3c442d1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs @@ -41,6 +41,7 @@ namespace FreeSql.Tests.Odbc.MySqlExpression var t3 = select.Where(a => a.testFieldBool == false).ToList(); var t4 = select.Where(a => !a.testFieldBool).ToList(); var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs index dcc2eccf..7be7f8f5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/OtherTest.cs @@ -39,6 +39,7 @@ namespace FreeSql.Tests.Odbc.OracleExpression var t3 = select.Where(a => a.Bool == false).ToList(); var t4 = select.Where(a => !a.Bool).ToList(); var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).Limit(10).ToList(); var t11 = select.Where(a => a.BoolNullable == true).ToList(); var t22 = select.Where(a => a.BoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs index f0062476..a418e8ac 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -44,6 +44,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression var t3 = select.Where(a => a.testFieldBool == false).ToList(); var t4 = select.Where(a => !a.testFieldBool).ToList(); var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs index 7d0167f1..bb965b84 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/OtherTest.cs @@ -36,6 +36,7 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression var t3 = select.Where(a => a.testFieldBool == false).ToList(); var t4 = select.Where(a => !a.testFieldBool).ToList(); var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs index d926eed7..2ab152e1 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs @@ -41,6 +41,7 @@ namespace FreeSql.Tests.MySqlExpression var t3 = select.Where(a => a.testFieldBool == false).ToList(); var t4 = select.Where(a => !a.testFieldBool).ToList(); var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).ToList(); var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs index d8317ef1..e1b0a61c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs @@ -39,6 +39,7 @@ namespace FreeSql.Tests.OracleExpression var t3 = select.Where(a => a.Bool == false).ToList(); var t4 = select.Where(a => !a.Bool).ToList(); var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).ToList(); var t11 = select.Where(a => a.BoolNullable == true).ToList(); var t22 = select.Where(a => a.BoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index 4ba7feea..034c1ae3 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -48,6 +48,7 @@ namespace FreeSql.Tests.PostgreSQLExpression var t3 = select.Where(a => a.testFieldBool == false).Limit(10).ToList(); var t4 = select.Where(a => !a.testFieldBool).Limit(10).ToList(); var t5 = select.Where(a => a.testFieldBool).Limit(10).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); var t11 = select.Where(a => a.testFieldBoolNullable == true).Limit(10).ToList(); var t22 = select.Where(a => a.testFieldBoolNullable != true).Limit(10).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs index ce27dceb..70cfb014 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs @@ -44,6 +44,7 @@ namespace FreeSql.Tests.SqlServerExpression var t3 = select.Where(a => a.testFieldBool == false).ToList(); var t4 = select.Where(a => !a.testFieldBool).ToList(); var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs index 51aa61f6..c40c4e42 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs @@ -39,6 +39,7 @@ namespace FreeSql.Tests.SqliteExpression var t3 = select.Where(a => a.Bool == false).ToList(); var t4 = select.Where(a => !a.Bool).ToList(); var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).Limit(10).ToList(); var t11 = select.Where(a => a.BoolNullable == true).ToList(); var t22 = select.Where(a => a.BoolNullable != true).ToList(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 10af2539..f3cc5c5b 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -342,37 +342,24 @@ namespace FreeSql.Internal { ExpressionType.Modulo, "%" }, { ExpressionType.Equal, "=" }, }; + public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString, List dbParams) { var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = dbParams }); - var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); - if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - return $"{sql} = {formatSql(true, null, null, null)}"; - if (isBool) - return GetBoolString(sql); - return sql; + return GetBoolString(exp, sql); } public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression, List dbParams) { var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = dbParams }); - var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); - if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - return $"{sql} = {formatSql(true, null, null, null)}"; - if (isBool) - return GetBoolString(sql); - return sql; + return GetBoolString(exp, sql); } static ConcurrentDictionary dicRegexAlias = new ConcurrentDictionary(); public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression) { var tbidx = _tables.Count; var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); - var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); - if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) - sql = $"{sql} = {formatSql(true, null, null, null)}"; - if (isBool) - sql = GetBoolString(sql); + sql = GetBoolString(exp, sql); if (_tables.Count > tbidx) { @@ -404,6 +391,15 @@ namespace FreeSql.Internal static MethodInfo MethodDateTimeSubtractTimeSpan = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(TimeSpan) }); static MethodInfo MethodMathFloor = typeof(Math).GetMethod("Floor", new Type[] { typeof(double) }); + public string GetBoolString(Expression exp, string sql) + { + var isBool = exp.Type.NullableTypeOrThis() == typeof(bool); + if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) + return $"{sql} = {formatSql(true, null, null, null)}"; + if (isBool) + return GetBoolString(sql); + return sql; + } static string GetBoolString(string sql) { switch (sql) @@ -1340,7 +1336,8 @@ namespace FreeSql.Internal new ReplaceVisitor().Modify(fl.Body, newParameter), newParameter ); - var whereSql = ExpressionLambdaToSql(expExp, new ExpTSC { _tables = null, _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = null, _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + whereSql = GetBoolString(expExp.Body, whereSql); if (isEmpty == false) sb.Append(" AND "); else From 51494c31a2c88fc2e14135f1e922c4a55ebacc9b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 16 Dec 2019 18:02:20 +0800 Subject: [PATCH 0338/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect.AsTa?= =?UTF-8?q?ble=20union=20all=20=E6=9F=A5=E8=AF=A2=E5=AF=B9=20count/max/min?= =?UTF-8?q?/avg/sum=20=E7=9A=84=E5=88=AB=E5=90=8D=20bug=EF=BC=9B#157?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + .../MySqlConnector/Curd/MySqlSelectTest.cs | 15 + .../Dameng/Curd/DamengSelectTest.cs | 15 + .../Default/Curd/OdbcSelectTest.cs | 15 + .../MySql/Curd/MySqlSelectTest.cs | 15 + .../Oracle/Curd/OracleSelectTest.cs | 15 + .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 15 + .../SqlServer/Curd/SqlServerSelectTest.cs | 15 + .../MySql/Curd/MySqlSelectTest.cs | 15 + .../Oracle/Curd/OracleSelectTest.cs | 15 + .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 15 + .../SqlServer/Curd/SqlServerSelectTest.cs | 15 + .../Sqlite/Curd/SqliteSelectTest.cs | 15 + FreeSql/FreeSql.xml | 345 ++++++++---------- .../SelectProvider/Select0Provider.cs | 24 +- 15 files changed, 357 insertions(+), 199 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index bd98bc2a..cf5f41f3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -954,6 +954,21 @@ namespace FreeSql.Tests.MySqlConnector query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 57002e1d..5e8e8135 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -881,6 +881,21 @@ namespace FreeSql.Tests.Odbc.Dameng query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TiOtmModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 1106202b..63a22cb8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -850,6 +850,21 @@ namespace FreeSql.Tests.Odbc.Default query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 88da23e6..75597ce2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -965,6 +965,21 @@ namespace FreeSql.Tests.Odbc.MySql query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 71a9e93d..363a1548 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -881,6 +881,21 @@ namespace FreeSql.Tests.Odbc.Oracle query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TiOtmModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index d414956c..4599275e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -937,6 +937,21 @@ namespace FreeSql.Tests.Odbc.PostgreSQL query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb UNION ALLSELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 2fe461ca..e750c5c4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -831,6 +831,21 @@ namespace FreeSql.Tests.Odbc.SqlServer query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index ba3ab4af..61555675 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -996,6 +996,21 @@ namespace FreeSql.Tests.MySql query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 2e36d4e8..8a194d9d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -881,6 +881,21 @@ namespace FreeSql.Tests.Oracle query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TiOtmModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 662c084d..20c1f3b8 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -954,6 +954,21 @@ namespace FreeSql.Tests.PostgreSQL query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb UNION ALLSELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 9adc89d4..8e31fc48 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -876,6 +876,21 @@ namespace FreeSql.Tests.SqlServer query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index dfaf65fc..ac2c24a6 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -865,6 +865,21 @@ namespace FreeSql.Tests.Sqlite query = select.LeftJoin("\"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a) ftb UNION ALLSELECT * from (SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"tb_topic22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index f9ceda03..4346a314 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2257,193 +2257,7 @@ - - 可自定义解析表达式 - - - - - 自定义实体的配置,方便和多个 ORM 共同使用 - - - - - 自定义实体的属性配置,方便和多个 ORM 共同使用 - - - - - 增删查改,执行命令之前触发 - - - - - 增删查改,执行命令完成后触发 - - - - - CodeFirst迁移,执行之前触发 - - - - - CodeFirst迁移,执行完成触发 - - - - - Insert/Update自动值处理 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + @@ -3034,3 +2848,160 @@ +unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index e56102fd..6e2b76ab 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -155,10 +155,10 @@ namespace FreeSql.Internal.CommonProvider public bool Any() { this.Limit(1); - return this.ToList("1").FirstOrDefault() == 1; + return this.ToList("1 as1").FirstOrDefault() == 1; } - public long Count() => this.ToList("count(1)").FirstOrDefault(); + public long Count() => this.ToList("count(1) as1").FirstOrDefault(); public TSelect Count(out long count) { @@ -1023,10 +1023,10 @@ namespace FreeSql.Internal.CommonProvider } #region common - protected TMember InternalAvg(Expression exp) => this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); - protected TMember InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); + protected TMember InternalAvg(Expression exp) => this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").FirstOrDefault(); + protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").FirstOrDefault(); + protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").FirstOrDefault(); + protected TMember InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").FirstOrDefault(); protected ISelectGrouping InternalGroupBy(Expression columns) { @@ -1104,10 +1104,10 @@ namespace FreeSql.Internal.CommonProvider async public Task AnyAsync() { this.Limit(1); - return (await this.ToListAsync("1")).FirstOrDefault() == 1; + return (await this.ToListAsync("1 as1")).FirstOrDefault() == 1; } - async public Task CountAsync() => (await this.ToListAsync("count(1)")).FirstOrDefault(); + async public Task CountAsync() => (await this.ToListAsync("count(1) as1")).FirstOrDefault(); async public Task ToDataTableAsync(string field = null) { @@ -1284,10 +1284,10 @@ namespace FreeSql.Internal.CommonProvider } protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) => ToListMapReaderPrivateAsync(af, null); - async protected Task InternalAvgAsync(Expression exp) => (await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); - async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); - async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); - async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); + async protected Task InternalAvgAsync(Expression exp) => (await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).FirstOrDefault(); + async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).FirstOrDefault(); + async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).FirstOrDefault(); + async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).FirstOrDefault(); protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); From e1e3e4a3b27f021e4d368573ef9bcdd6cc469f2a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 17 Dec 2019 01:39:53 +0800 Subject: [PATCH 0339/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Where=20In?= =?UTF-8?q?=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=EF=BC=9B=20-?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=20FreeSqlBuilder.UseConnectionFactory=20?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=AF=B9=E8=B1=A1=E7=9A=84=E5=88=9B=E5=BB=BA=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests.PerformanceTests.csproj | 2 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 42 +- .../g.cs | 2 + .../Dameng/Curd/DamengSelectTest.cs | 42 +- .../Default/Curd/OdbcSelectTest.cs | 46 +- .../MySql/Curd/MySqlSelectTest.cs | 42 +- .../Oracle/Curd/OracleSelectTest.cs | 42 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 42 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 46 +- .../FreeSql.Tests.Provider.Odbc/g.cs | 7 + .../MySql/Curd/MySqlSelectTest.cs | 44 +- .../Oracle/Curd/OracleSelectTest.cs | 42 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 42 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 38 +- .../Sqlite/Curd/SqliteSelectTest.cs | 42 +- FreeSql.Tests/FreeSql.Tests/g.cs | 15 + FreeSql.sln | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 487 +++++++----------- FreeSql/FreeSqlBuilder.cs | 25 +- FreeSql/Interface/IAdo.cs | 4 +- FreeSql/Internal/CommonExpression.cs | 5 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 20 +- .../AdoProvider/AdoProviderAsync.cs | 6 +- .../AdoProvider/AdoProviderTransaction.cs | 2 +- .../AdoProvider/DbConnectionPool.cs | 134 +++++ .../MySqlAdo/MySqlAdo.cs | 13 +- .../FreeSql.Provider.MySql/MySqlProvider.cs | 4 +- .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 15 +- .../OdbcDamengAdo/OdbcDamengConnectionPool.cs | 11 +- .../Dameng/OdbcDamengCodeFirst.cs | 7 +- .../Dameng/OdbcDamengProvider.cs | 4 +- .../Default/OdbcAdo/OdbcAdo.cs | 13 +- .../Default/OdbcProvider.cs | 5 +- .../GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs | 13 +- .../GBase/OdbcGBaseProvider.cs | 5 +- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 15 +- .../MySql/OdbcMySqlProvider.cs | 4 +- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 15 +- .../OdbcOracleAdo/OdbcOracleConnectionPool.cs | 11 +- .../Oracle/OdbcOracleCodeFirst.cs | 7 +- .../Oracle/OdbcOracleProvider.cs | 4 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 15 +- .../PostgreSQL/OdbcPostgreSQLProvider.cs | 5 +- .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 15 +- .../SqlServer/OdbcSqlServerProvider.cs | 5 +- .../OracleAdo/OracleAdo.cs | 13 +- .../OracleAdo/OracleConnectionPool.cs | 11 +- .../OracleCodeFirst.cs | 7 +- .../FreeSql.Provider.Oracle/OracleProvider.cs | 4 +- .../PostgreSQLAdo/PostgreSQLAdo.cs | 15 +- .../PostgreSQLProvider.cs | 4 +- .../SqlServerAdo/SqlServerAdo.cs | 13 +- .../SqlServerProvider.cs | 5 +- .../SqliteAdo/SqliteAdo.cs | 13 +- .../SqliteAdo/SqliteConnectionPool.cs | 12 +- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 4 +- 57 files changed, 1018 insertions(+), 492 deletions(-) create mode 100644 FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj index 896199f9..c86a28d6 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj @@ -19,7 +19,7 @@ - + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index cf5f41f3..571ff538 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -832,12 +832,16 @@ namespace FreeSql.Tests.MySqlConnector var subquery = select.ToSql(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -846,12 +850,16 @@ namespace FreeSql.Tests.MySqlConnector var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -860,12 +868,16 @@ namespace FreeSql.Tests.MySqlConnector var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -874,15 +886,29 @@ namespace FreeSql.Tests.MySqlConnector var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` +FROM `tb_topic` a +WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` + FROM `tb_topic` b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs index a5942054..bd67be80 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs @@ -9,11 +9,13 @@ public class g static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") + //.UseConnectionFactory(FreeSql.DataType.MySql, () => new MySql.Data.MySqlClient.MySqlConnection("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( cmd => { + cmd.CommandTimeout = 200000; Trace.WriteLine(cmd.CommandText); }, //监听SQL命令对象,在执行前 (cmd, traceLog) => diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 5e8e8135..0f2ff099 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -758,12 +758,16 @@ namespace FreeSql.Tests.Odbc.Dameng var subquery = select.ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -772,12 +776,16 @@ namespace FreeSql.Tests.Odbc.Dameng var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -786,12 +794,16 @@ namespace FreeSql.Tests.Odbc.Dameng var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -800,15 +812,29 @@ namespace FreeSql.Tests.Odbc.Dameng var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 63a22cb8..4bbf76e3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -725,15 +725,18 @@ namespace FreeSql.Tests.Odbc.Default [Fact] public void Sum() { - var subquery = select.Where(a => a.Id < 200).ToSql(a => new + var subquery = select.ToSql(a => new { all = a, - count = select.Where(b => b.Id < 200).Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); - var subqueryList = select.Where(a => a.Id < 200).ToList(a => new + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new { all = a, - count = select.Where(b => b.Id < 200).Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -742,12 +745,15 @@ namespace FreeSql.Tests.Odbc.Default var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -756,29 +762,45 @@ namespace FreeSql.Tests.Odbc.Default var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] public void Avg() { - var subquery = select.Where(a => a.Id < 200).ToSql(a => new + var subquery = select.ToSql(a => new { all = a, - count = select.Where(b => b.Id < 200).Sum(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); - var subqueryList = select.Where(a => a.Id < 200).ToList(a => new + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new { all = a, - count = select.Where(b => b.Id < 200).Sum(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] +FROM [tb_topic22] a +WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] + FROM [tb_topic22] b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 75597ce2..c6b9f900 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -843,12 +843,16 @@ namespace FreeSql.Tests.Odbc.MySql var subquery = select.ToSql(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -857,12 +861,16 @@ namespace FreeSql.Tests.Odbc.MySql var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -871,12 +879,16 @@ namespace FreeSql.Tests.Odbc.MySql var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -885,15 +897,29 @@ namespace FreeSql.Tests.Odbc.MySql var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` +FROM `tb_topic` a +WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` + FROM `tb_topic` b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 363a1548..6f0bfc79 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -758,12 +758,16 @@ namespace FreeSql.Tests.Odbc.Oracle var subquery = select.ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -772,12 +776,16 @@ namespace FreeSql.Tests.Odbc.Oracle var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -786,12 +794,16 @@ namespace FreeSql.Tests.Odbc.Oracle var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -800,15 +812,29 @@ namespace FreeSql.Tests.Odbc.Oracle var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 4599275e..eae61153 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -815,12 +815,16 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT sum(b.""id"") + FROM ""tb_topic"" b + limit 1) as6 +FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -829,12 +833,16 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT min(b.""id"") + FROM ""tb_topic"" b + limit 1) as6 +FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -843,12 +851,16 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT max(b.""id"") + FROM ""tb_topic"" b + limit 1) as6 +FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -857,15 +869,29 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT avg(b.""id"") + FROM ""tb_topic"" b + limit 1) as6 +FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime"" +FROM ""tb_topic"" a +WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" + FROM ""tb_topic"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index e750c5c4..9e7c6e74 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -706,15 +706,18 @@ namespace FreeSql.Tests.Odbc.SqlServer [Fact] public void Sum() { - var subquery = select.Where(a => a.Id < 200).ToSql(a => new + var subquery = select.ToSql(a => new { all = a, - count = select.Where(b => b.Id < 200).Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); - var subqueryList = select.Where(a => a.Id < 200).ToList(a => new + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new { all = a, - count = select.Where(b => b.Id < 200).Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -723,12 +726,15 @@ namespace FreeSql.Tests.Odbc.SqlServer var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -737,29 +743,45 @@ namespace FreeSql.Tests.Odbc.SqlServer var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] public void Avg() { - var subquery = select.Where(a => a.Id < 100).ToSql(a => new + var subquery = select.ToSql(a => new { all = a, - count = select.Where(b => b.Id < 100).Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); - var subqueryList = select.Where(a => a.Id < 100).ToList(a => new + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new { all = a, - count = select.Where(b => b.Id < 100).Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] +FROM [tb_topic22] a +WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] + FROM [tb_topic22] b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index b00b6d96..1de7386f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -8,6 +8,7 @@ public class g { static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.OdbcMySql, "Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Max pool size=2") + //.UseConnectionFactory(FreeSql.DataType.OdbcMySql, () => new System.Data.Odbc.OdbcConnection("Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;")) .UseAutoSyncStructure(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 @@ -18,7 +19,9 @@ public class g static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.OdbcSqlServer, "Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Max pool size=3") + //.UseConnectionFactory(FreeSql.DataType.OdbcSqlServer, () => new System.Data.Odbc.OdbcConnection("Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;")) //.UseConnectionString(FreeSql.DataType.OdbcSqlServer, "Driver={SQL Server};Server=192.168.164.129;Persist Security Info=False;Trusted_Connection=Yes;UID=sa;PWD=123456;DATABASE=ds_shop;") + //.UseConnectionFactory(FreeSql.DataType.OdbcSqlServer, () => new System.Data.Odbc.OdbcConnection("Driver={SQL Server};Server=192.168.164.129;Persist Security Info=False;Trusted_Connection=Yes;UID=sa;PWD=123456;DATABASE=ds_shop;")) .UseAutoSyncStructure(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 @@ -29,6 +32,7 @@ public class g static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.OdbcOracle, "Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456") + //.UseConnectionFactory(FreeSql.DataType.OdbcOracle, () => new System.Data.Odbc.OdbcConnection("Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseSyncStructureToUpper(true) @@ -44,6 +48,7 @@ public class g { return new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.OdbcPostgreSQL, "Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Maximum Pool Size=2") + //.UseConnectionFactory(FreeSql.DataType.OdbcPostgreSQL, () => new System.Data.Odbc.OdbcConnection("Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;")) .UseAutoSyncStructure(true) .UseSyncStructureToLower(true) .UseLazyLoading(true) @@ -56,6 +61,7 @@ public class g static Lazy odbcLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Odbc, "Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Max pool size=5") + //.UseConnectionFactory(FreeSql.DataType.Odbc, () => new System.Data.Odbc.OdbcConnection("Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;")) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 (cmd, traceLog) => Console.WriteLine(traceLog)) @@ -65,6 +71,7 @@ public class g static Lazy damemgLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") + //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseSyncStructureToUpper(true) diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 61555675..d2a251fc 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -874,12 +874,16 @@ namespace FreeSql.Tests.MySql var subquery = select.ToSql(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -888,12 +892,16 @@ namespace FreeSql.Tests.MySql var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -902,12 +910,16 @@ namespace FreeSql.Tests.MySql var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) - }); + count = select.As("b").Max(b => b.Id) + }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -916,15 +928,29 @@ namespace FreeSql.Tests.MySql var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) + FROM `tb_topic` b + limit 0,1) as6 +FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` +FROM `tb_topic` a +WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` + FROM `tb_topic` b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 8a194d9d..0e4e657c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -758,12 +758,16 @@ namespace FreeSql.Tests.Oracle var subquery = select.ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -772,12 +776,16 @@ namespace FreeSql.Tests.Oracle var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -786,12 +794,16 @@ namespace FreeSql.Tests.Oracle var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -800,15 +812,29 @@ namespace FreeSql.Tests.Oracle var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 20c1f3b8..9418b8d0 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -832,12 +832,16 @@ namespace FreeSql.Tests.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT sum(b.""id"") + FROM ""tb_topic"" b + limit 1) as6 +FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = (long)select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -846,12 +850,16 @@ namespace FreeSql.Tests.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT min(b.""id"") + FROM ""tb_topic"" b + limit 1) as6 +FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -860,12 +868,16 @@ namespace FreeSql.Tests.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT max(b.""id"") + FROM ""tb_topic"" b + limit 1) as6 +FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -874,15 +886,29 @@ namespace FreeSql.Tests.PostgreSQL var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT avg(b.""id"") + FROM ""tb_topic"" b + limit 1) as6 +FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime"" +FROM ""tb_topic"" a +WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" + FROM ""tb_topic"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 8e31fc48..fef4aa42 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -754,12 +754,15 @@ namespace FreeSql.Tests.SqlServer var subquery = select.ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -768,12 +771,15 @@ namespace FreeSql.Tests.SqlServer var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -782,12 +788,15 @@ namespace FreeSql.Tests.SqlServer var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -796,15 +805,28 @@ namespace FreeSql.Tests.SqlServer var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) + FROM [tb_topic22] b) as6 +FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] +FROM [tb_topic22] a +WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] + FROM [tb_topic22] b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index ac2c24a6..743bb309 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -711,12 +711,16 @@ namespace FreeSql.Tests.Sqlite var subquery = select.ToSql(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); + Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT sum(b.""Id"") + FROM ""tb_topic22"" b + limit 0,1) as6 +FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Sum(b => b.Id) + count = (long)select.As("b").Sum(b => b.Id) }); } [Fact] @@ -725,12 +729,16 @@ namespace FreeSql.Tests.Sqlite var subquery = select.ToSql(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); + Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT min(b.""Id"") + FROM ""tb_topic22"" b + limit 0,1) as6 +FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Min(b => b.Id) + count = select.As("b").Min(b => b.Id) }); } [Fact] @@ -739,12 +747,16 @@ namespace FreeSql.Tests.Sqlite var subquery = select.ToSql(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); + Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT max(b.""Id"") + FROM ""tb_topic22"" b + limit 0,1) as6 +FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Max(b => b.Id) + count = select.As("b").Max(b => b.Id) }); } [Fact] @@ -753,15 +765,29 @@ namespace FreeSql.Tests.Sqlite var subquery = select.ToSql(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); + Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT avg(b.""Id"") + FROM ""tb_topic22"" b + limit 0,1) as6 +FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { all = a, - count = select.Avg(b => b.Id) + count = select.As("b").Avg(b => b.Id) }); } [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""Clicks"", a.""TypeGuid"", a.""Title"", a.""CreateTime"" +FROM ""tb_topic22"" a +WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" + FROM ""tb_topic22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] public void As() { } diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 0c8aac09..a4f06b7d 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -10,6 +10,7 @@ public class g static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .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=2") + //.UseConnectionFactory(FreeSql.DataType.MySql, () => new MySql.Data.MySqlClient.MySqlConnection("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( @@ -25,6 +26,7 @@ public class g NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); return new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") + //.UseConnectionFactory(FreeSql.DataType.PostgreSQL, () => new Npgsql.NpgsqlConnection("Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseSyncStructureToLower(true) @@ -39,7 +41,9 @@ public class g static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + //.UseConnectionFactory(FreeSql.DataType.SqlServer, () => new System.Data.SqlClient.SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;")) //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;Max Pool Size=3") + //.UseConnectionFactory(FreeSql.DataType.SqlServer, () => new System.Data.SqlClient.SqlConnection("Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( @@ -52,6 +56,7 @@ public class g static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") + //.UseConnectionFactory(FreeSql.DataType.Oracle, () => new Oracle.ManagedDataAccess.Client.OracleConnection("user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) @@ -67,6 +72,16 @@ public class g static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=2") + //.UseConnectionFactory(FreeSql.DataType.Sqlite, () => + //{ + // var conn = new System.Data.SQLite.SQLiteConnection(@"Data Source=|DataDirectory|\document.db;Pooling=true;"); + // //conn.Open(); + // //var cmd = conn.CreateCommand(); + // //cmd.CommandText = $"attach database [xxxtb.db] as [xxxtb];\r\n"; + // //cmd.ExecuteNonQuery(); + // //cmd.Dispose(); + // return conn; + //}) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) diff --git a/FreeSql.sln b/FreeSql.sln index 32083dc2..f5f3b0f2 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -68,7 +68,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "orm_vs_net40", "Examples\or EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Generator", "Extensions\FreeSql.Generator\FreeSql.Generator.csproj", "{6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4}" EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "FreeSql.Tests.VB", "FreeSql.Tests.VB\FreeSql.Tests.VB.vbproj", "{A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "FreeSql.Tests.VB", "FreeSql.Tests.VB\FreeSql.Tests.VB.vbproj", "{A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e0441819..51dcc983 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -28,7 +28,7 @@ - + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4346a314..1a33cd4d 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -613,7 +613,7 @@ - 使用连接串 + 使用连接串(推荐) 数据库类型 数据库连接串 @@ -627,6 +627,15 @@ 从数据库连接串 + + + 使用自定义数据库连接对象(放弃内置对象连接池技术) + + 数据库类型 + 数据库连接对象创建器 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 @@ -2125,139 +2134,194 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - - + 可自定义解析表达式 + + + + + 自定义实体的配置,方便和多个 ORM 共同使用 + + + + + 自定义实体的属性配置,方便和多个 ORM 共同使用 + + + + + 增删查改,执行命令之前触发 + + + + + 增删查改,执行命令完成后触发 + + + + + CodeFirst迁移,执行之前触发 + + + + + CodeFirst迁移,执行完成触发 + + + + + Insert/Update自动值处理 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 @@ -2848,160 +2912,3 @@ -unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index fd1db807..8e843a9b 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -12,6 +12,7 @@ namespace FreeSql DataType _dataType; string _masterConnectionString; string[] _slaveConnectionString; + Func _connectionFactory; bool _isAutoSyncStructure = false; bool _isSyncStructureToLower = false; bool _isSyncStructureToUpper = false; @@ -25,7 +26,7 @@ namespace FreeSql Type _providerType = null; /// - /// 使用连接串 + /// 使用连接串(推荐) /// /// 数据库类型 /// 数据库连接串 @@ -33,6 +34,7 @@ namespace FreeSql /// public FreeSqlBuilder UseConnectionString(DataType dataType, string connectionString, Type providerType = null) { + if (_connectionFactory != null) throw new Exception("已经指定了 UseConnectionFactory,不能再指定 UseConnectionString"); _dataType = dataType; _masterConnectionString = connectionString; _providerType = providerType; @@ -45,10 +47,27 @@ namespace FreeSql /// public FreeSqlBuilder UseSlave(params string[] slaveConnectionString) { + if (_connectionFactory != null) throw new Exception("已经指定了 UseConnectionFactory,不能再指定 UseSlave"); _slaveConnectionString = slaveConnectionString; return this; } /// + /// 使用自定义数据库连接对象(放弃内置对象连接池技术) + /// + /// 数据库类型 + /// 数据库连接对象创建器 + /// 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + /// + public FreeSqlBuilder UseConnectionFactory(DataType dataType, Func connectionFactory, Type providerType = null) + { + if (string.IsNullOrEmpty(_masterConnectionString) == false) throw new Exception("已经指定了 UseConnectionString,不能再指定 UseConnectionFactory"); + if (_slaveConnectionString?.Any() == true) throw new Exception("已经指定了 UseSlave,不能再指定 UseConnectionFactory"); + _dataType = dataType; + _connectionFactory = connectionFactory; + _providerType = providerType; + return this; + } + /// /// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 /// /// true:运行时检查自动同步结构, false:不同步结构 @@ -149,7 +168,7 @@ namespace FreeSql public IFreeSql Build() => Build(); public IFreeSql Build() { - if (string.IsNullOrEmpty(_masterConnectionString)) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString"); + if (string.IsNullOrEmpty(_masterConnectionString) && _connectionFactory == null) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString"); IFreeSql ret = null; var type = _providerType; if (type?.IsGenericType == true) type = type.MakeGenericType(typeof(TMark)); @@ -208,7 +227,7 @@ namespace FreeSql default: throw new Exception("未指定 UseConnectionString"); } } - ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql; + ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString, _connectionFactory }) as IFreeSql; if (ret != null) { ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure; diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index b42cb61e..57670ee0 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -14,11 +14,11 @@ namespace FreeSql /// /// 主库连接池 /// - ObjectPool MasterPool { get; } + IObjectPool MasterPool { get; } /// /// 从库连接池 /// - List> SlavePools { get; } + List> SlavePools { get; } /// /// 监视数据库命令对象(执行前,调试) /// diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index f3cc5c5b..e43904f5 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -660,6 +660,7 @@ namespace FreeSql.Internal case "Min": case "Max": case "Avg": + case "ToList": //where in case "First": var anyArgs = exp3.Arguments; var exp3Stack = new Stack(); @@ -732,7 +733,8 @@ namespace FreeSql.Internal if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke(); fsqlType = fsql?.GetType(); if (fsqlType == null) break; - fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); + if (exp3.Method.Name != "ToList") + fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; if (fsqltables != tsc._tables) @@ -915,6 +917,7 @@ namespace FreeSql.Internal if (string.IsNullOrEmpty(sqlSum) == false) return $"({sqlSum.Replace("\r\n", "\r\n\t")})"; break; + case "ToList": case "First": var tscClone2 = tsc.CloneDisableDiyParse(); tscClone2.isDisableDiyParse = false; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index a8048150..840f6ca1 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -14,7 +14,7 @@ namespace FreeSql.Internal.CommonProvider public abstract partial class AdoProvider : IAdo, IDisposable { - protected abstract void ReturnConnection(ObjectPool pool, Object conn, Exception ex); + protected abstract void ReturnConnection(IObjectPool pool, Object conn, Exception ex); protected abstract DbCommand CreateCommand(); protected abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); public Action AopCommandExecuting { get; set; } @@ -22,8 +22,8 @@ namespace FreeSql.Internal.CommonProvider protected bool IsTracePerformance => AopCommandExecuted != null; - public ObjectPool MasterPool { get; protected set; } - public List> SlavePools { get; } = new List>(); + public IObjectPool MasterPool { get; protected set; } + public List> SlavePools { get; } = new List>(); public DataType DataType { get; } protected CommonUtils _util { get; set; } protected int slaveUnavailables = 0; @@ -35,7 +35,7 @@ namespace FreeSql.Internal.CommonProvider this.DataType = dataType; } - void LoggerException(ObjectPool pool, (DbCommand cmd, bool isclose) pc, Exception e, DateTime dt, StringBuilder logtxt, bool isThrowException = true) + void LoggerException(IObjectPool pool, (DbCommand cmd, bool isclose) pc, Exception e, DateTime dt, StringBuilder logtxt, bool isThrowException = true) { var cmd = pc.cmd; if (pc.isclose) pc.cmd.Connection.Close(); @@ -76,7 +76,11 @@ namespace FreeSql.Internal.CommonProvider AopCommandExecuted?.Invoke(cmd, log.ToString()); cmd.Parameters.Clear(); - if (isThrowException) throw e; + if (isThrowException) + { + cmd.Dispose(); + throw e; + } } internal Dictionary GetQueryTypeProperties(Type type) @@ -515,7 +519,7 @@ namespace FreeSql.Internal.CommonProvider //查从库 this.SlavePools : ( //查主库 - slaveUnavailables == this.SlavePools.Count ? new List>() : + slaveUnavailables == this.SlavePools.Count ? new List>() : //查从库可用 this.SlavePools.Where(sp => sp.IsAvailable).ToList()); if (availables.Any()) @@ -556,6 +560,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); + pc.cmd.Dispose(); ExecuteReaderMultiple(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); return; } @@ -618,6 +623,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(pool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); + pc.cmd.Dispose(); } public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); @@ -708,6 +714,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); + pc.cmd.Dispose(); return val; } public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); @@ -743,6 +750,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); + pc.cmd.Dispose(); return val; } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index a9b154ae..63e50246 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -448,7 +448,7 @@ namespace FreeSql.Internal.CommonProvider //查从库 this.SlavePools : ( //查主库 - slaveUnavailables == this.SlavePools.Count ? new List>() : + slaveUnavailables == this.SlavePools.Count ? new List>() : //查从库可用 this.SlavePools.Where(sp => sp.IsAvailable).ToList()); if (availables.Any()) @@ -489,6 +489,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); + pc.cmd.Dispose(); await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); return; } @@ -551,6 +552,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(pool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); + pc.cmd.Dispose(); } public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); @@ -642,6 +644,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); + pc.cmd.Dispose(); return val; } public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); @@ -677,6 +680,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); + pc.cmd.Dispose(); return val; } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 7da093e8..df0b0741 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -136,7 +136,7 @@ namespace FreeSql.Internal.CommonProvider } catch { } - ObjectPool[] pools = null; + IObjectPool[] pools = null; for (var a = 0; a < 10; a++) { try diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs new file mode 100644 index 00000000..5d2d931b --- /dev/null +++ b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs @@ -0,0 +1,134 @@ +using SafeObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + public class DbConnectionPool : IObjectPool + { + internal DataType _dataType; + internal Func _connectionFactory; + int _id; + public DbConnectionPool(DataType dataType, Func connectionFactory) + { + _dataType = dataType; + _connectionFactory = connectionFactory; + Policy = new DbConnectionPoolPolicy(this); + } + + public IPolicy Policy { get; } + + public bool IsAvailable => true; + public Exception UnavailableException => null; + public DateTime? UnavailableTime => null; + public string Statistics => "throw new NotImplementedException()"; + public string StatisticsFullily => "throw new NotImplementedException()"; + + public void Dispose() + { + } + + public Object Get(TimeSpan? timeout = null) + { + var conn = _connectionFactory(); + if (conn.State != ConnectionState.Open) + conn.Open(); + return Object.InitWith(this, Interlocked.Increment(ref _id), conn); + } + +#if net40 +#else + async public Task> GetAsync() + { + var conn = _connectionFactory(); + if (conn.State != ConnectionState.Open) + await conn.OpenAsync(); + return Object.InitWith(this, Interlocked.Increment(ref _id), conn); + } +#endif + + public void Return(Object obj, bool isReset = false) + { + if (obj == null) return; + Policy.OnDestroy(obj.Value); + } + + public bool SetUnavailable(Exception exception) + { + throw new NotImplementedException(); + } + } + + internal class DbConnectionPoolPolicy : IPolicy + { + DbConnectionPool Pool; + public DbConnectionPoolPolicy(DbConnectionPool pool) + { + this.Pool = pool; + } + + public string Name { get; set; } = typeof(DbConnectionPoolPolicy).GetType().FullName; + public int PoolSize { get; set; } = 1000; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(50); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + public DbConnection OnCreate() + { + var conn = Pool._connectionFactory(); + if (conn.State != ConnectionState.Open) + conn.Open(); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj != null) + { + if (obj.State != ConnectionState.Closed) + obj.Close(); + //obj.Dispose(); + } + } + + public void OnGet(Object obj) + { + } + +#if net40 +#else + public Task OnGetAsync(Object obj) + { + return Task.FromResult(true); + } +#endif + + public void OnGetTimeout() + { + } + + public void OnReturn(Object obj) + { + } + + public bool OnCheckAvailable(Object obj) + { + return true; + } + + public void OnAvailable() + { + } + + public void OnUnavailable() + { + } + } +} diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index c101e092..62ec1bd3 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -14,9 +14,14 @@ namespace FreeSql.MySql { public MySqlAdo() : base(DataType.MySql) { } - public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.MySql) + public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.MySql) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.MySql, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -59,9 +64,11 @@ namespace FreeSql.MySql return new MySqlCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as MySqlConnectionPool).Return(conn, ex); + var rawPool = pool as MySqlConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index edfe0054..f1b146d0 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -55,12 +55,12 @@ namespace FreeSql.MySql public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public MySqlProvider(string masterConnectionString, string[] slaveConnectionString) + public MySqlProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new MySqlUtils(this); this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils); - this.Ado = new MySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new MySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index ec2338a2..ed749b48 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -12,10 +12,15 @@ namespace FreeSql.Odbc.Dameng { class OdbcDamengAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcDamengAdo() : base(DataType.Oracle) { } - public OdbcDamengAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Oracle) + public OdbcDamengAdo() : base(DataType.OdbcDameng) { } + public OdbcDamengAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcDameng) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.OdbcDameng, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new OdbcDamengConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -57,9 +62,11 @@ namespace FreeSql.Odbc.Dameng return new OdbcCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as OdbcDamengConnectionPool).Return(conn, ex); + var rawPool = pool as OdbcDamengConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index 81a601bb..f6d7eede 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -21,9 +21,7 @@ namespace FreeSql.Odbc.Dameng public OdbcDamengConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); - if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); - this.UserId = userIdMatch.Groups[2].Value.Trim().ToUpper(); + this.UserId = OdbcDamengConnectionPool.GetUserId(connectionString); var policy = new OdbcOracleConnectionPoolPolicy { @@ -37,6 +35,13 @@ namespace FreeSql.Odbc.Dameng this.unavailableHandler = unavailableHandler; } + public static string GetUserId(string connectionString) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + return userIdMatch.Groups[2].Value.Trim().ToUpper(); + } + public void Return(Object obj, Exception exception, bool isRecreate = false) { if (exception != null && exception is OdbcException) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 99d486fd..09a14594 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -77,7 +77,12 @@ namespace FreeSql.Odbc.Dameng protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { - var userId = (_orm.Ado.MasterPool as OdbcDamengConnectionPool).UserId; + var userId = (_orm.Ado.MasterPool as OdbcDamengConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = OdbcDamengConnectionPool.GetUserId(conn.Value.ConnectionString); + } var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs index 97c84c96..c1da688a 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs @@ -28,12 +28,12 @@ namespace FreeSql.Odbc.Dameng public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public OdbcDamengProvider(string masterConnectionString, string[] slaveConnectionString) + public OdbcDamengProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcDamengUtils(this); this.InternalCommonExpression = new OdbcDamengExpression(this.InternalCommonUtils); - this.Ado = new OdbcDamengAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new OdbcDamengAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new OdbcDamengDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index 27352355..69fdce7d 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -13,9 +13,14 @@ namespace FreeSql.Odbc.Default class OdbcAdo : FreeSql.Internal.CommonProvider.AdoProvider { public OdbcAdo() : base(DataType.Odbc) { } - public OdbcAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Odbc) + public OdbcAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Odbc) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Odbc, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new OdbcConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -60,9 +65,11 @@ namespace FreeSql.Odbc.Default return new OdbcCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as OdbcConnectionPool).Return(conn, ex); + var rawPool = pool as OdbcConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index d4104e30..9406b549 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Threading; @@ -37,12 +38,12 @@ namespace FreeSql.Odbc.Default /// /// /// 适配器 - public OdbcProvider(string masterConnectionString, string[] slaveConnectionString) + public OdbcProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcUtils(this); this.InternalCommonExpression = new OdbcExpression(this.InternalCommonUtils); - this.Ado = new OdbcAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new OdbcAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.CodeFirst = new OdbcCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs index c4c215f2..8129aafe 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs @@ -14,9 +14,14 @@ namespace FreeSql.Odbc.GBase class OdbcGBaseAdo : FreeSql.Internal.CommonProvider.AdoProvider { public OdbcGBaseAdo() : base(DataType.PostgreSQL) { } - public OdbcGBaseAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.PostgreSQL) + public OdbcGBaseAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.PostgreSQL) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.PostgreSQL, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new OdbcGBaseConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -58,9 +63,11 @@ namespace FreeSql.Odbc.GBase return new OdbcCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as OdbcGBaseConnectionPool).Return(conn, ex); + var rawPool = pool as OdbcGBaseConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs index 66e28e82..0d797f6f 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Threading; namespace FreeSql.Odbc.GBase @@ -31,12 +32,12 @@ namespace FreeSql.Odbc.GBase public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public OdbcGBaseProvider(string masterConnectionString, string[] slaveConnectionString) + public OdbcGBaseProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcGBaseUtils(this); this.InternalCommonExpression = new OdbcGBaseExpression(this.InternalCommonUtils); - this.Ado = new OdbcGBaseAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new OdbcGBaseAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new OdbcGBaseDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 8c6f5c24..7f454fb0 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -13,10 +13,15 @@ namespace FreeSql.Odbc.MySql class OdbcMySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcMySqlAdo() : base(DataType.MySql) { } - public OdbcMySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.MySql) + public OdbcMySqlAdo() : base(DataType.OdbcMySql) { } + public OdbcMySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcMySql) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.OdbcMySql, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new OdbcMySqlConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -57,9 +62,11 @@ namespace FreeSql.Odbc.MySql return new OdbcCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as OdbcMySqlConnectionPool).Return(conn, ex); + var rawPool = pool as OdbcMySqlConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index 95b21a6b..a0bb6347 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -33,12 +33,12 @@ namespace FreeSql.Odbc.MySql public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public OdbcMySqlProvider(string masterConnectionString, string[] slaveConnectionString) + public OdbcMySqlProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcMySqlUtils(this); this.InternalCommonExpression = new OdbcMySqlExpression(this.InternalCommonUtils); - this.Ado = new OdbcMySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new OdbcMySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new OdbcMySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index 98e7921a..b3d53183 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -12,10 +12,15 @@ namespace FreeSql.Odbc.Oracle { class OdbcOracleAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcOracleAdo() : base(DataType.Oracle) { } - public OdbcOracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Oracle) + public OdbcOracleAdo() : base(DataType.OdbcOracle) { } + public OdbcOracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcOracle) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.OdbcOracle, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new OdbcOracleConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -57,9 +62,11 @@ namespace FreeSql.Odbc.Oracle return new OdbcCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as OdbcOracleConnectionPool).Return(conn, ex); + var rawPool = pool as OdbcOracleConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index 7ccfa7bd..31d23008 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -21,9 +21,7 @@ namespace FreeSql.Odbc.Oracle public OdbcOracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); - if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); - this.UserId = userIdMatch.Groups[2].Value.Trim().ToUpper(); + this.UserId = OdbcOracleConnectionPool.GetUserId(connectionString); var policy = new OdbcOracleConnectionPoolPolicy { @@ -37,6 +35,13 @@ namespace FreeSql.Odbc.Oracle this.unavailableHandler = unavailableHandler; } + public static string GetUserId(string connectionString) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + return userIdMatch.Groups[2].Value.Trim().ToUpper(); + } + public void Return(Object obj, Exception exception, bool isRecreate = false) { if (exception != null && exception is OdbcException) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index ad61cdb9..eece275f 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -77,7 +77,12 @@ namespace FreeSql.Odbc.Oracle protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { - var userId = (_orm.Ado.MasterPool as OdbcOracleConnectionPool).UserId; + var userId = (_orm.Ado.MasterPool as OdbcOracleConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = OdbcOracleConnectionPool.GetUserId(conn.Value.ConnectionString); + } var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index e82bc16d..47b16b74 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -28,12 +28,12 @@ namespace FreeSql.Odbc.Oracle public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public OdbcOracleProvider(string masterConnectionString, string[] slaveConnectionString) + public OdbcOracleProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcOracleUtils(this); this.InternalCommonExpression = new OdbcOracleExpression(this.InternalCommonUtils); - this.Ado = new OdbcOracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new OdbcOracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new OdbcOracleDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index 0777ffb8..cdd1269e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -13,10 +13,15 @@ namespace FreeSql.Odbc.PostgreSQL { class OdbcPostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcPostgreSQLAdo() : base(DataType.PostgreSQL) { } - public OdbcPostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.PostgreSQL) + public OdbcPostgreSQLAdo() : base(DataType.OdbcPostgreSQL) { } + public OdbcPostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcPostgreSQL) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.OdbcPostgreSQL, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new OdbcPostgreSQLConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -58,9 +63,11 @@ namespace FreeSql.Odbc.PostgreSQL return new OdbcCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as OdbcPostgreSQLConnectionPool).Return(conn, ex); + var rawPool = pool as OdbcPostgreSQLConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index d858489a..dee8daae 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Threading; namespace FreeSql.Odbc.PostgreSQL @@ -31,12 +32,12 @@ namespace FreeSql.Odbc.PostgreSQL public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public OdbcPostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString) + public OdbcPostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcPostgreSQLUtils(this); this.InternalCommonExpression = new OdbcPostgreSQLExpression(this.InternalCommonUtils); - this.Ado = new OdbcPostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new OdbcPostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new OdbcPostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index 20e197c6..a9661dc8 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -13,10 +13,15 @@ namespace FreeSql.Odbc.SqlServer { class OdbcSqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcSqlServerAdo() : base(DataType.SqlServer) { } - public OdbcSqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.SqlServer) + public OdbcSqlServerAdo() : base(DataType.OdbcSqlServer) { } + public OdbcSqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcSqlServer) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.OdbcSqlServer, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new OdbcSqlServerConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -73,9 +78,11 @@ namespace FreeSql.Odbc.SqlServer return new OdbcCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as OdbcSqlServerConnectionPool).Return(conn, ex); + var rawPool = pool as OdbcSqlServerConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index faf7847a..5d3fd7bf 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Threading; namespace FreeSql.Odbc.SqlServer @@ -27,12 +28,12 @@ namespace FreeSql.Odbc.SqlServer public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public OdbcSqlServerProvider(string masterConnectionString, string[] slaveConnectionString) + public OdbcSqlServerProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcSqlServerUtils(this); this.InternalCommonExpression = new OdbcSqlServerExpression(this.InternalCommonUtils); - this.Ado = new OdbcSqlServerAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new OdbcSqlServerAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new OdbcSqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 3c637833..289b95f4 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -13,9 +13,14 @@ namespace FreeSql.Oracle class OracleAdo : FreeSql.Internal.CommonProvider.AdoProvider { public OracleAdo() : base(DataType.Oracle) { } - public OracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Oracle) + public OracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Oracle) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Oracle, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new OracleConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -59,9 +64,11 @@ namespace FreeSql.Oracle return cmd; } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as OracleConnectionPool).Return(conn, ex); + var rawPool = pool as OracleConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index cf65eb94..f28debbc 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -21,9 +21,7 @@ namespace FreeSql.Oracle public OracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { - var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); - if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); - this.UserId = userIdMatch.Groups[2].Value.Trim().ToUpper(); + this.UserId = OracleConnectionPool.GetUserId(connectionString); var policy = new OracleConnectionPoolPolicy { @@ -37,6 +35,13 @@ namespace FreeSql.Oracle this.unavailableHandler = unavailableHandler; } + public static string GetUserId(string connectionString) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + return userIdMatch.Groups[2].Value.Trim().ToUpper(); + } + public void Return(Object obj, Exception exception, bool isRecreate = false) { if (exception != null && exception is OracleException) diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index e408452f..85a273e7 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -78,7 +78,12 @@ namespace FreeSql.Oracle protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) { - var userId = (_orm.Ado.MasterPool as OracleConnectionPool).UserId; + var userId = (_orm.Ado.MasterPool as OracleConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = OracleConnectionPool.GetUserId(conn.Value.ConnectionString); + } var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index 6be0984e..9a7bebdc 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -29,12 +29,12 @@ namespace FreeSql.Oracle public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public OracleProvider(string masterConnectionString, string[] slaveConnectionString) + public OracleProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OracleUtils(this); this.InternalCommonExpression = new OracleExpression(this.InternalCommonUtils); - this.Ado = new OracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new OracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new OracleDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index f1600c24..1dca64d1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -15,9 +15,14 @@ namespace FreeSql.PostgreSQL class PostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider { public PostgreSQLAdo() : base(DataType.PostgreSQL) { } - public PostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.PostgreSQL) + public PostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.PostgreSQL) { - base._util = util; + base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.PostgreSQL, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new PostgreSQLConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -75,9 +80,11 @@ namespace FreeSql.PostgreSQL return new NpgsqlCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as PostgreSQLConnectionPool).Return(conn, ex); + var rawPool = pool as PostgreSQLConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index a900c60a..8471653f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -82,12 +82,12 @@ namespace FreeSql.PostgreSQL public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public PostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString) + public PostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new PostgreSQLUtils(this); this.InternalCommonExpression = new PostgreSQLExpression(this.InternalCommonUtils); - this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new PostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 2d898e7a..b12cdf10 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -14,9 +14,14 @@ namespace FreeSql.SqlServer class SqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider { public SqlServerAdo() : base(DataType.SqlServer) { } - public SqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.SqlServer) + public SqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.SqlServer) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.SqlServer, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new SqlServerConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -73,9 +78,11 @@ namespace FreeSql.SqlServer return new SqlCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as SqlServerConnectionPool).Return(conn, ex); + var rawPool = pool as SqlServerConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index 0de7d235..afaf697b 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -4,6 +4,7 @@ using FreeSql.SqlServer.Curd; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Threading; namespace FreeSql.SqlServer @@ -28,12 +29,12 @@ namespace FreeSql.SqlServer public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst { get; } - public SqlServerProvider(string masterConnectionString, string[] slaveConnectionString) + public SqlServerProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new SqlServerUtils(this); this.InternalCommonExpression = new SqlServerExpression(this.InternalCommonUtils); - this.Ado = new SqlServerAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new SqlServerAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.DbFirst = new SqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index d57c74ec..d589b9b4 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -12,9 +12,14 @@ namespace FreeSql.Sqlite class SqliteAdo : FreeSql.Internal.CommonProvider.AdoProvider { public SqliteAdo() : base(DataType.Sqlite) { } - public SqliteAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Sqlite) + public SqliteAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Sqlite) { base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Sqlite, connectionFactory); + return; + } if (!string.IsNullOrEmpty(masterConnectionString)) MasterPool = new SqliteConnectionPool("主库", masterConnectionString, null, null); if (slaveConnectionStrings != null) @@ -55,9 +60,11 @@ namespace FreeSql.Sqlite return AdonetPortable.GetSqliteCommand(); } - protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) { - (pool as SqliteConnectionPool).Return(conn, ex); + var rawPool = pool as SqliteConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); } protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index bc915c72..791fdb02 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -224,7 +224,10 @@ namespace FreeSql.Sqlite { try { - PingCommand(that).ExecuteNonQuery(); + using (var cmd = PingCommand(that)) + { + cmd.ExecuteNonQuery(); + } return true; } catch @@ -247,6 +250,7 @@ namespace FreeSql.Sqlite var cmd = that.CreateCommand(); cmd.CommandText = sb.ToString(); cmd.ExecuteNonQuery(); + cmd.Dispose(); } } @@ -256,7 +260,10 @@ namespace FreeSql.Sqlite { try { - await PingCommand(that).ExecuteNonQueryAsync(); + using (var cmd = PingCommand(that)) + { + await cmd.ExecuteNonQueryAsync(); + } return true; } catch @@ -279,6 +286,7 @@ namespace FreeSql.Sqlite var cmd = that.CreateCommand(); cmd.CommandText = sb.ToString(); await cmd.ExecuteNonQueryAsync(); + cmd.Dispose(); } } #endif diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index ba92b82f..5e4a8abb 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -29,12 +29,12 @@ namespace FreeSql.Sqlite public IAop Aop { get; } public ICodeFirst CodeFirst { get; } public IDbFirst DbFirst => null; - public SqliteProvider(string masterConnectionString, string[] slaveConnectionString) + public SqliteProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new SqliteUtils(this); this.InternalCommonExpression = new SqliteExpression(this.InternalCommonUtils); - this.Ado = new SqliteAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString); + this.Ado = new SqliteAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); From 301578936aeef6f1a3d1f41ecdc886cd6083f9dd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 17 Dec 2019 01:52:56 +0800 Subject: [PATCH 0340/1029] ## v0.12.21 #140 #157 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 131 ++++++++++++++++++ .../AdoProvider/DbConnectionPool.cs | 7 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 151 insertions(+), 24 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a721ceff..b5580902 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.20 + 0.12.21 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 64685077..670584e8 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0047ce19..14bcca23 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index e057bf5e..33f66e0f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 0.12.20 + 0.12.21 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4ebadbdd..07f35455 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. 达梦 diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index f3ed3c0a..06e825f9 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.20 + 0.12.21 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index a4f06b7d..99c4b02b 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -9,7 +9,7 @@ public class g { static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .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=2") + .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=5") //.UseConnectionFactory(FreeSql.DataType.MySql, () => new MySql.Data.MySqlClient.MySqlConnection("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 51dcc983..499169fa 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. 达梦 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1a33cd4d..4b4e7645 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2134,6 +2134,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 }) + + + + + + 可自定义解析表达式 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs index 5d2d931b..9cbd4b7e 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs @@ -54,8 +54,11 @@ namespace FreeSql.Internal.CommonProvider public void Return(Object obj, bool isReset = false) { - if (obj == null) return; - Policy.OnDestroy(obj.Value); + if (obj == null || obj.Value == null) return; + if (obj.Value.State != ConnectionState.Closed) + obj.Value.Close(); + if (_dataType == DataType.Sqlite) + obj.Dispose(); } public bool SetUnavailable(Exception exception) diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index f3ac3f22..1dc21b5c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 76068797..714dca1c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 308f4983..e38abfb8 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8ff89d47..8c14ece6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b84a95f9..3938cc17 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d4968054..d5c762a7 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f23d830c..812042ff 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.20 + 0.12.21 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 204b6ecd98337c1d9fa6b8ed9e3b64efd89586ff Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 17 Dec 2019 13:35:13 +0800 Subject: [PATCH 0341/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20AsTable=20?= =?UTF-8?q?=E5=88=86=E8=A1=A8=E6=9F=A5=E8=AF=A2=20Any/Min/Max/Avg/Sum/Coun?= =?UTF-8?q?t=20=E7=9A=84=E5=A4=84=E7=90=86=EF=BC=9B#158=20-=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=20Avg=20=E6=96=B9=E6=B3=95=E8=BF=94=E5=9B=9E=E5=80=BC?= =?UTF-8?q?=E4=B8=BA=20double=EF=BC=8CSum=20=E6=96=B9=E6=B3=95=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E5=80=BC=E4=B8=BA=20decimal=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect4.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect5.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect6.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect7.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect8.cs | 8 ++--- FreeSql/Interface/Curd/ISelect/ISelect9.cs | 8 ++--- .../SelectProvider/Select0Provider.cs | 32 ++++++++++++------- .../SelectProvider/Select10Provider.cs | 20 ++++++------ .../SelectProvider/Select1Provider.cs | 24 +++++++------- .../SelectProvider/Select2Provider.cs | 20 ++++++------ .../SelectProvider/Select3Provider.cs | 20 ++++++------ .../SelectProvider/Select4Provider.cs | 20 ++++++------ .../SelectProvider/Select5Provider.cs | 20 ++++++------ .../SelectProvider/Select6Provider.cs | 20 ++++++------ .../SelectProvider/Select7Provider.cs | 20 ++++++------ .../SelectProvider/Select8Provider.cs | 20 ++++++------ .../SelectProvider/Select9Provider.cs | 20 ++++++------ 21 files changed, 162 insertions(+), 154 deletions(-) diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 43118b65..01542938 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -23,10 +23,10 @@ namespace FreeSql Task FirstAsync(); Task ToAggregateAsync(Expression, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif /// @@ -106,7 +106,7 @@ namespace FreeSql /// 返回类型 /// 列 /// - TMember Sum(Expression> column); + decimal Sum(Expression> column); /// /// 最小值 /// @@ -127,7 +127,7 @@ namespace FreeSql /// 返回类型 /// 列 /// - TMember Avg(Expression> column); + double Avg(Expression> column); /// /// 指定别名 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 83cc7949..a148e3d2 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 98d24ad7..4ce85e8b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index ee60a5b0..cb384c44 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 57640478..7bedf4d0 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index 3b94ff28..59b90b9d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 97c6c05c..92b0275b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index 80d7bc72..a13a8b6f 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 976ca71b..0e9d1633 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 0960ea22..8c3f9d16 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -18,10 +18,10 @@ namespace FreeSql Task> ToListAsync(); Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); + Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task AvgAsync(Expression> column); #endif bool Any(Expression> exp); @@ -30,10 +30,10 @@ namespace FreeSql List ToList(); string ToSql(Expression> select); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - TMember Sum(Expression> column); + decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); - TMember Avg(Expression> column); + double Avg(Expression> column); ISelect LeftJoin(Expression> exp); ISelect InnerJoin(Expression> exp); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 6e2b76ab..bb3db92c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -155,10 +155,10 @@ namespace FreeSql.Internal.CommonProvider public bool Any() { this.Limit(1); - return this.ToList("1 as1").FirstOrDefault() == 1; + return this.ToList("1 as1").Sum() > 0; //这里的 Sum 为了分表查询 } - public long Count() => this.ToList("count(1) as1").FirstOrDefault(); + public long Count() => this.ToList("count(1) as1").Sum(); //这里的 Sum 为了分表查询 public TSelect Count(out long count) { @@ -1023,10 +1023,14 @@ namespace FreeSql.Internal.CommonProvider } #region common - protected TMember InternalAvg(Expression exp) => this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").FirstOrDefault(); - protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").FirstOrDefault(); - protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").FirstOrDefault(); - protected TMember InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").FirstOrDefault(); + protected double InternalAvg(Expression exp) + { + var list = this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1"); + return list.Sum() / list.Count; + } + protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").Max(); + protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").Min(); + protected decimal InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").Sum(); protected ISelectGrouping InternalGroupBy(Expression columns) { @@ -1104,10 +1108,10 @@ namespace FreeSql.Internal.CommonProvider async public Task AnyAsync() { this.Limit(1); - return (await this.ToListAsync("1 as1")).FirstOrDefault() == 1; + return (await this.ToListAsync("1 as1")).Sum() > 0; //这里的 Sum 为了分表查询 } - async public Task CountAsync() => (await this.ToListAsync("count(1) as1")).FirstOrDefault(); + async public Task CountAsync() => (await this.ToListAsync("count(1) as1")).Sum(); //这里的 Sum 为了分表查询 async public Task ToDataTableAsync(string field = null) { @@ -1284,10 +1288,14 @@ namespace FreeSql.Internal.CommonProvider } protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) => ToListMapReaderPrivateAsync(af, null); - async protected Task InternalAvgAsync(Expression exp) => (await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).FirstOrDefault(); - async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).FirstOrDefault(); - async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).FirstOrDefault(); - async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).FirstOrDefault(); + async protected Task InternalAvgAsync(Expression exp) + { + var list = await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1"); + return list.Sum() / list.Count; + } + async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).Max(); + async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).Min(); + async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).Sum(); protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 73898c13..008dbdb4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -35,11 +35,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return 0; for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -77,11 +77,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) @@ -172,11 +172,11 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -193,11 +193,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index a2c3a341..92542383 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -104,11 +104,11 @@ namespace FreeSql.Internal.CommonProvider return this; } - public TMember Avg(Expression> column) + public double Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); _tables[0].Parameter = column.Parameters[0]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class;// { this.InternalFrom(exp); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } @@ -155,11 +155,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - public TMember Sum(Expression> column) + public decimal Sum(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(decimal); _tables[0].Parameter = column.Parameters[0]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } public List ToList(Expression> select) @@ -1055,11 +1055,11 @@ namespace FreeSql.Internal.CommonProvider _trackToList?.Invoke(list); } - public Task AvgAsync(Expression> column) + public Task AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); _tables[0].Parameter = column.Parameters[0]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } public Task MaxAsync(Expression> column) { @@ -1073,11 +1073,11 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = column.Parameters[0]; return this.InternalMinAsync(column?.Body); } - public Task SumAsync(Expression> column) + public Task SumAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(decimal)); _tables[0].Parameter = column.Parameters[0]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } public Task> ToListAsync(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 71eb62a9..f1d3fc81 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -19,11 +19,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -61,11 +61,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select) @@ -149,11 +149,11 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -170,11 +170,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 4430c762..bf9b37f3 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -21,11 +21,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -63,11 +63,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) @@ -152,11 +152,11 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -173,11 +173,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 0af86e6d..4d390f0f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -23,11 +23,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -65,11 +65,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) @@ -155,11 +155,11 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -176,11 +176,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 56214a55..e0a13adc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -25,11 +25,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -67,11 +67,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) @@ -158,11 +158,11 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -179,11 +179,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 2538c8e0..8c9c18d8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -27,11 +27,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -69,11 +69,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) @@ -161,11 +161,11 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -182,11 +182,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 33b1e13e..b7065918 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -29,11 +29,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -71,11 +71,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) @@ -164,11 +164,11 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -185,11 +185,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 5f2dda4f..af888f39 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -31,11 +31,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -73,11 +73,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) @@ -168,11 +168,11 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -189,11 +189,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index ba049ff9..c8186b68 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -33,11 +33,11 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); } - TMember ISelect.Avg(Expression> column) + double ISelect.Avg(Expression> column) { - if (column == null) return default(TMember); + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); + return this.InternalAvg(column?.Body); } ISelectGrouping ISelect.GroupBy(Expression> exp) @@ -75,11 +75,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } - TMember ISelect.Sum(Expression> column) + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); + return this.InternalSum(column?.Body); } TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) @@ -181,11 +181,11 @@ namespace FreeSql.Internal.CommonProvider Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Task ISelect.AvgAsync(Expression> column) + Task ISelect.AvgAsync(Expression> column) { - if (column == null) return Task.FromResult(default(TMember)); + if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body); } Task ISelect.MaxAsync(Expression> column) @@ -202,11 +202,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalMinAsync(column?.Body); } - Task ISelect.SumAsync(Expression> column) + Task ISelect.SumAsync(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body); } Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) From fe5b98509b152607cb603ccfa22425eab60a7ca5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 17 Dec 2019 22:08:12 +0800 Subject: [PATCH 0342/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.ToSq?= =?UTF-8?q?l=20=E5=AD=97=E6=AE=B5=E5=88=AB=E5=90=8D=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=EF=BC=8C=E9=BB=98=E8=AE=A4=E4=B8=BA=20AsIndex=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E6=94=B9=E4=B8=BA=20AsProperty=EF=BC=9B#158?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ++++++ .../MySqlConnector/Curd/MySqlSelectTest.cs | 18 +++++++++++++++ .../Dameng/Curd/DamengSelectTest.cs | 18 +++++++++++++++ .../Default/Curd/OdbcSelectTest.cs | 18 +++++++++++++++ .../MySql/Curd/MySqlSelectTest.cs | 18 +++++++++++++++ .../Oracle/Curd/OracleSelectTest.cs | 18 +++++++++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 18 +++++++++++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 18 +++++++++++++++ .../MySql/Curd/MySqlSelectTest.cs | 18 +++++++++++++++ .../Oracle/Curd/OracleSelectTest.cs | 18 +++++++++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 18 +++++++++++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 18 +++++++++++++++ .../Sqlite/Curd/SqliteSelectTest.cs | 18 +++++++++++++++ FreeSql/FreeSql.xml | 14 +++++++++++- .../Curd/ISelect/FieldAliasOptions.cs | 22 +++++++++++++++++++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 3 ++- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect4.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect5.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect6.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect7.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect8.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect9.cs | 2 +- FreeSql/Internal/CommonExpression.cs | 6 +++++ .../SelectProvider/Select0Provider.cs | 8 +++---- .../SelectProvider/Select10Provider.cs | 6 ++--- .../SelectProvider/Select1Provider.cs | 6 ++--- .../SelectProvider/Select2Provider.cs | 6 ++--- .../SelectProvider/Select3Provider.cs | 6 ++--- .../SelectProvider/Select4Provider.cs | 6 ++--- .../SelectProvider/Select5Provider.cs | 6 ++--- .../SelectProvider/Select6Provider.cs | 6 ++--- .../SelectProvider/Select7Provider.cs | 6 ++--- .../SelectProvider/Select8Provider.cs | 6 ++--- .../SelectProvider/Select9Provider.cs | 6 ++--- 37 files changed, 309 insertions(+), 45 deletions(-) create mode 100644 FreeSql/Interface/Curd/ISelect/FieldAliasOptions.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 571ff538..c0936140 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -995,6 +995,24 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 0f2ff099..bd34ae44 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -922,6 +922,24 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TiOtmModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 4bbf76e3..f5ddd317 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -887,6 +887,24 @@ WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index c6b9f900..55b667ea 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1006,6 +1006,24 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 6f0bfc79..98e1c28d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -922,6 +922,24 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TiOtmModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index eae61153..d1c0da01 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -978,6 +978,24 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 9e7c6e74..4b7f5448 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -868,6 +868,24 @@ WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index d2a251fc..43db97cc 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1037,6 +1037,24 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 0e4e657c..9eb3b48b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -922,6 +922,24 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TiOtmModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 9418b8d0..7ee59d6b 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -995,6 +995,24 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index fef4aa42..2f141e8d 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -913,6 +913,24 @@ WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 743bb309..4b243edc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -906,6 +906,24 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4b4e7645..14d2a6a5 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -894,6 +894,17 @@ + + + 自动产生 as1, as2, as3 .... 字段别名 + 这种方法可以最大程度防止多表,存在相同字段的问题 + + + + + 使用属性名作为字段别名 + + 【linq to sql】专用方法,不建议直接使用 @@ -1316,12 +1327,13 @@ - + 返回即将执行的SQL语句 返回类型 选择列 + 字段别名 diff --git a/FreeSql/Interface/Curd/ISelect/FieldAliasOptions.cs b/FreeSql/Interface/Curd/ISelect/FieldAliasOptions.cs new file mode 100644 index 00000000..6c17997a --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/FieldAliasOptions.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql +{ + public enum FieldAliasOptions + { + /// + /// 自动产生 as1, as2, as3 .... 字段别名 + /// 这种方法可以最大程度防止多表,存在相同字段的问题 + /// + AsIndex, + + + /// + /// 使用属性名作为字段别名 + /// + AsProperty + } +} diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 01542938..32e296d2 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -89,8 +89,9 @@ namespace FreeSql /// /// 返回类型 /// 选择列 + /// 字段别名 /// - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); /// /// 执行SQL查询,返回指定字段的聚合结果 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index a148e3d2..c370667b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 4ce85e8b..c419870b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index cb384c44..d53693c1 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 7bedf4d0..b60dfc14 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index 59b90b9d..f4c340be 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 92b0275b..8a6db616 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index a13a8b6f..62a0d528 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 0e9d1633..18d4c318 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 8c3f9d16..f8974d0b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -28,7 +28,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); - string ToSql(Expression> select); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); TMember Min(Expression> column); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index e43904f5..b1d2a2d8 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -25,6 +25,7 @@ namespace FreeSql.Internal _common = common; } + internal const int ReadAnonymousFieldAsCsName = -53129; public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression, bool isAllDtoMap) { Func getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; @@ -37,6 +38,7 @@ namespace FreeSql.Internal parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); return false; case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Constant: @@ -54,6 +56,7 @@ namespace FreeSql.Internal parent.DbField = _common.FormatSql("{0}", constExp?.Value); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); return false; case ExpressionType.Call: var callExp = exp as MethodCallExpression; @@ -70,6 +73,7 @@ namespace FreeSql.Internal parent.DbField = ExpressionLambdaToSql(exp, getTSC()); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); return false; case ExpressionType.Parameter: case ExpressionType.MemberAccess: @@ -102,6 +106,7 @@ namespace FreeSql.Internal parent.DbField = ExpressionLambdaToSql(exp, getTSC()); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); parent.MapType = SearchColumnByField(_tables, null, parent.DbField)?.Attribute.MapType ?? exp.Type; return false; } @@ -219,6 +224,7 @@ namespace FreeSql.Internal parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})"; field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); return false; } public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index bb3db92c..b9d079e5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -525,11 +525,11 @@ namespace FreeSql.Internal.CommonProvider return ToListMrPrivate(sql, af, otherData); } protected List ToListMapReader((ReadAnonymousTypeInfo map, string field) af) => ToListMapReaderPrivate(af, null); - protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) + protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); - var index = 0; + var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true); return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); @@ -1059,9 +1059,9 @@ namespace FreeSql.Internal.CommonProvider protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); protected List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); - protected string InternalToSql(Expression select) + protected string InternalToSql(Expression select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - var af = this.GetExpressionField(select); + var af = this.GetExpressionField(select, fieldAlias); return this.ToSql(af.field); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 008dbdb4..892b45d6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -121,11 +121,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 92542383..0187fd1b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -263,11 +263,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - public string ToSql(Expression> select) + public string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); _tables[0].Parameter = select.Parameters[0]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } public TReturn ToAggregate(Expression, TReturn>> select) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index f1d3fc81..40ed5cb9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -98,11 +98,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index bf9b37f3..31f842a7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -101,11 +101,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 4d390f0f..e3ab43e0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -104,11 +104,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index e0a13adc..97633b78 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -107,11 +107,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 8c9c18d8..1f3dfd02 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -110,11 +110,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index b7065918..b6e443f8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -113,11 +113,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index af888f39..3c47a61e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -117,11 +117,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index c8186b68..5011cfa1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -117,11 +117,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { - if (select == null) return this.InternalToSql(select?.Body); + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body); + return this.InternalToSql(select?.Body, fieldAlias); } ISelect ISelect.LeftJoin(Expression> exp) From e2624ed8ee7975252c1db3f6cb682386537489e7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 18 Dec 2019 12:16:58 +0800 Subject: [PATCH 0343/1029] =?UTF-8?q?-=20FreeSql.Generator=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20core=202.1=202.2=203.0=203.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 2 +- .../FreeSql.Generator.csproj | 4 +- FreeSql/FreeSql.xml | 288 ++++++++++-------- .../SelectProvider/Select0Provider.cs | 2 +- 4 files changed, 161 insertions(+), 135 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 10cfbe88..104585db 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -218,7 +218,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 var rebuildBat = ArgsOutput + "__重新生成.bat"; if (File.Exists(rebuildBat) == false) { - File.WriteAllText(rebuildBat, @$" + File.WriteAllText(rebuildBat, $@" FreeSql.Generator -Razor {ArgsRazorRaw} -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}"" "); Console.WriteFormatted(" OUT -> " + rebuildBat + " (以后) 双击它重新生成实体\r\n", Color.Magenta); diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 33f66e0f..2304f4fd 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -2,13 +2,13 @@ Exe - netcoreapp3.1 + netcoreapp3.1;netcoreapp3.0;netcoreapp2.2;netcoreapp2.1 true true true 2881099 2881099 - FreeSql123 + FreeSql 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 14d2a6a5..64a4e184 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2146,137 +2146,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3055,3 +2924,160 @@ +unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index b9d079e5..cd308800 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -240,7 +240,7 @@ namespace FreeSql.Internal.CommonProvider } public TSelect Master() { - _select = " SELECT "; + _select = $" {_select.Trim()} "; return this as TSelect; } public TSelect Offset(int offset) => this.Skip(offset) as TSelect; From a357ee4975c0028e622cc8372b27857f566949ff Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 18 Dec 2019 21:18:24 +0800 Subject: [PATCH 0344/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20BaseEntity?= =?UTF-8?q?=20=E6=9F=A5=E8=AF=A2=E6=95=B0=E6=8D=AE=E6=97=B6=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=20Attach=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseEntity 纯净版源码(.Net 4.0).zip | Bin 2340 -> 2698 bytes .../BaseEntity 纯净版源码.zip | Bin 4088 -> 4439 bytes .../BaseEntityReadOnly.cs | 40 ++- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql/FreeSql.xml | 290 ++++++++---------- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 2 +- 6 files changed, 172 insertions(+), 167 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip index 15569d335e8997e97db1eaafcf78e9924c4056ce..11ac08713d39e5fa8d6f14da479b098d1c22ad90 100644 GIT binary patch delta 1517 zcmVcG2#1pokR5|a@G9Di3ykJB&|z9aD;Ot>UslmR3p zptLXy0~!edVv0BbLT>6(Lza&100oW2z9SCo`ywGKgcy(z`|@WdopRzY@EoT}mvqRm zNchk?_Iux3{rvpn(>I?}cOTlw2$`6)%?()K5!dwu7SwZjZs7v8KT+p`I6a@{sAt>6 z3MuEmZSKMaM;9(YFouVR(HibM4rcX2vJ_l8-Msh$jRJ@uMe2~@9kp_MI?gu`n+Q@y zvv*DfFCWZ&xf(qDIQ#lj2jp-!=B^?x*+kz!xqtkhsJqsLV7?`MMo=EXlo)#yWz8?y z)Izw#1;ds=mW??_>oF%|uAri>sHFDM;1Drj7>_JNdp+iCWAtE7kqj_0HuQ8OczrD4 z24)mYe`vjatmp}Ew4tHLk`Iw30dz`yG)pFEL>pj;AF%XUYApK>C$L( z)N@^xkgyFIq096u)@#HBAS%cZ(zG%xA@2FiB6&f$Fw3Q!gAb#c=h=wUBP72<(zib6#JJi9gu3cYKRDa(E zw7O##9jX%0CEA0nkUc6gnbN!Y@M&xMN%Q)v=H-_eSW5ZJ2b`h_V2BY8dhQ-57SjX$~)vQrbUv|lQ1!+dZq(hAan0&L48*SBpW zQX!U|IKk%NfRGk*G!7yXALLR%c?_A!#gufSkGZ}>n7sTV=w5grpHt%mmv5vDP}Q}W zLL?6t1Ow?IH8cZ=x}Z&>b-(8Q>PWr}3bn~2r6L&_<;am(Q^7V*%;_I(Yky?r1#&rs z{z}MCy@qY^KYXdkB@F)hiSb=o0obirZ97axvR;B-Pt8 zLxxbQ&-)$T!}Sl{Zh3B*$~I9eNLi?P^X=@lht2EfBH#ZfAsesgGBzkycL@DX5CJAZ zkQABUKQo`M1}7SsAAgn16Cjj8FD}pWc2e^=6&~xTOUW8KDm%U$;_#FCM1Q}1D!A}S zz1tyMf_shT-8an}uT%>QQIv~Uo~y;+$}M=g!8`x^$wqMQOa}eKki-pjRC(s^*F=?a zGqI|#&q_uQrD|Yh-A(aRSnm3}KGoTTNU~r?)Id6ioOS_~ybKbx|B?z}Q(q}lKLL|S z2x|@zs*+D=>cG2#1pokR5|hCQH7@IE8eXNf)dA~i8eXNf)d2t(PO=@I)d5gT1qJ{B T000620szJU006ED00000kGI-= delta 1135 zcmV-#1d#iR6{Hfd0|X96tB+3>*H3mF1ONbU43iNA9Di0>tJ6Rfe!tNFaL7}NB~?LC zYvZmI1jSZ-P?2de+JS7HnW$9+cdmNH2lssev4~g&QS`d}nVa1D^_WL7V-vhH7Jo4SH5sSK;9yvYG1!C{-s*6|JF%9G zK3PoQD-3E$W^mA@_AW|}RAQAWNe&Y|-wocJO09)41icUaH&0@{X$hsFE(u_#a8cEV zalrcZz+2Qk3JyLBTaOvoll`D>P!>LaUA*26E?(*P-UqV}g6Efmxtk-YYBh&&f-G_z zMSm93J~?EQPb?EtwOE+Z_AtEB=k6G&s)RHVZgw398`6Uii;hrbt2H_v)`TO%aS0T~ z6kEVtpBlKzG2@!qtk~!nc&=*!Bgb)dm7++0(ZOo5SW$`s;Cv7dQcE)%Q~2$S$IkQ+ zMf$pO^fxY=4$SZQ$bnxT_r2!`cxk9Bp9{OCl4Z$UGsLTTX4zIk*Sucu3D>_V6KY5x?Ds^m$-b-VT-=|jMFdoWMd1f6!6j&?EH>n4yk$?MEU6{WX zoayHNRG}^xhho9-lKXaJ&t-(Wbc7YtJvbqGqykL*-sUqFaLd-SFPq z@aF577)2H3=G7PRW^nbk_#O~nkKfLAgV_r?;*Ux)r0I>EBcr8GzmdoxPYYs-Mk53lYPj(yx003_clP3x_4hVM2H%qhC0SI==H%qgVY6=<#NC*G`004Uf BBj5l4 diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip index ab1fb53d6f3f718fcb89c9e829b10dcad851ac12..47a9b4d13018fbf8f0544cd4d91eb495eb312a33 100644 GIT binary patch delta 1914 zcmV-=2Zi|fAJ-zV;Rp`&sgh4~cSkl22LJ$D8I$h_9e+u0(?AryBlSNF;bM!*1tcUO zO-fq|s)Q(_0SEUD-gunYaqPxr zk?KN1T0mGzBQ#&|r)r`rgF=gaP*&>uiX_1?-2rj??O!O=> zaEZ_|R!P&`o@K{+mLYih`ub2mwM!*zRkHq&bLmX&;!89POc=>&CDOOETxfod(oIAs zj1*A)?rG=s!|K8{=h5f-+b;o@eeFE=saBIx1_@>T6nU<_DfvMoK(zyM+smU$Q%Wh3HQh$_X#@06((Pze7P8_v};pqYODX7JX>;*>_pjZ0iICWh~$EcR-)8iYp;Eyh19XwfH=~ zrKgilO6beRl@HGB&DzY(#_MnOh1br)H7N7-=Z|VLAGAVuhqfaxWFtr&ix{k_V=T@G z2t%2$ManL$+a!b>ji&?zrue%ZQt!3s)ay{YIwV6h>&{2v)&5Y<+^SI~1-@l4s&Vdx zb78Lf@pEl{w)*h}RKfbY$A4&$F|1C+aNDi13E*N-th!yxFDi5EvWM0DHGqZN@PA_z*+HYnv|)<~($DpDvHq2Onb%O=`l4<%(c50PO^Ra_tv=D7#I zm^M>DR{R2#3Fmv1e!}S<_t5-wY%%oPeb5hP{vdax4&UuHJPZh@;D7qLt<6&*-C62& ziZU)Y*FX^A$3;4VDQ&S#6m}X3avw4560!KvBF2e8zNp4NU%FYdfU7u^L=f?<3xpz) zTxvLKK_vrie62e*?^K7cOQ2Ab+*8Vvkx&jiEo;2sOvh6;t>ODxAm^VvTln8r&x=#f zUk9kc+bnv)BsXnK$bUfD40vqACD{BiY%$6cTS|@F`I6?Ia#y5)V?fK+I$nkOM;AHn zzQZgK7Zle#9x_7}5tc1AHe#|ET$4OV(@A?q0vAmiz&mLcDY~XJ0H%? zZ-N~?Fky@9zQ=m-r26Ik&##wwL-sl`RzPAFtzIR=cmdir5Tkq@FAJuNmc-a3ZE*mXM+&8GDZhtTO9VY@Cp97~ze4SVQa?Lq8 zm-vpfRjNjL@!UbmCe@f}1sZ`r7CfCL&gdU^PCFMKi)(0z7U%w4?cTfE%{Ss41zzNX zvoFM;GkY5@BH`Nl$Ei7I=4=A}g-bkTy>m#HD$8r360j;0Tk%4a;uOUjT?9^2(?gw` zwm|*$s2PE@Lrz=KTN#s; z4>c|(S6DrzwbcP8S6DrzwbcQKA7xsCQPlxZO9ci10000300RIj0RR9O5C8xG0BG-* Ar2qf` delta 1560 zcmV+z2Iu+LBKRM$;Rp_`v~o|AW+23_1pojs6O-=<9e-JG(?Ae@uhjpr_{kQP3rI*n znm~bqA|Z-MfCoTmYj22!kJP&^1cbz`awBoyhlHpQP>>J^XyMP)NqFKfFza<<$BC)S zA>oJE-kF`*`Q~(feEH^4!#;?%xP+7@O?5M7c+|EXhMD2mG&eXP=%qSk#7evd+&yas zK4?3X8Gjm0lC~N4q&jw_<`PQ#NLR~MmtY+hfG{{q#&m}02;E^c%1%GGFn=lOx;R(uItTCjSm{PP6Q!-{V zgVhBWKYe&nz!x?YL(9+s$F+92##BzQq!`&T^z4lP?nJa3HY0!bQ|sMR!Ix%Gbkv>$ zjDv`Lp>qzjem!DU*Ex)Aau|&r(MXNQgSLmCn{IkrtSE&<385i$?8a=k`W z5M(eigd|CaB}5(1)kvNZ%2a(KXW=8L<~Syz#!-@AElFHnpjcLvoTLE2*&uG47FpKC zuw;w7bk?wo3nRn9t(%k%%+h3Jz%L7YOMg(>0eSHl?1-`uPx8D}p_8Um=o8OEm6aO5 zQ;wmd1pXZ{Txw`QJN=?73iW)znCnkfN1d9w$#eCMq~bu{FV7>H4k4oOY$-#s6LpUZ zctU9-asVz`j--9=K3j?-aXf3-&7JVC&H5joFU&viFW>afo?iHT(Z7%(uY+}$K!3Q{ z6g(6@r6>L_0ByXo$8is#jpU$V%iN;y(e_MJ$ykd1?7;CLFv%2wC=mObug^C>zX;v` zH_a?k#|+|R8&|g;ajn0Ik}2#W56WPkS4dT~mPn?obcYRRRl7C7&Ok+iQ5>A}r$kBH z0^SiF+pMEe3MFBiqhWJ|1}P2II)7Lz6C2yCsDmb6dV2ZfjJ|AL`RHH0)tJ83dh@k8 z|Hhxc4rRXi;&Eg8qoFVE&~D^~ZUm|05}UQpn2Pg3!cabGk-8h39!Vfa(>VcwDSq#U zG`#(CbP!gii~^BuhRuju;Uh^=Xbu~DCU~@f~cj$59K8I*1G*nbJ}GY;`H zQWoz8v@S+PhpPmtT1W#@uze|3H6A~2%|2_~eA~GEW^v1wn!Y7sLKln9F5Z6;MG>u+ z9%VEQ#Dqzm&><`89)ne(w%ZhIK}U%aUJc_}#M^pxD`DeqP*~#p6>L%>I$`26Do7UI zg)*@n%Ivs1X4P0-PUHy`<9|F7Vn9gm6;iNu<`eNP- zcw*N-gk5uN-QcxJDt~ZYsB!y4^Ty-G&FK*P|HNg*ip+h3I>#MCzvDy@6G`A4nLqm$ zzFhZD&1C+T?v$z`Z>c*;&7lT!+*q@X*5X|}b4Gu^d&a-;MEqR=(c(XtY21I`xb;@_ zTks-Zy!uis`d9D32P^!&@%{9SKYcF4`2&}9y8kF+SgS5lWjA>(RAW}M2 zF?(?mBWmyD4Ifrktp0}Fz}lmyt4;J{h?J_Kom{xme=O&uzC+~kpOY65&kn7$a!-?H zAjGZ(001!)lk^ZZF5|Xku^pb(0pqr1u^pb(0f!%DT7ps40Z>Z?1^@s600RI604f0h K0JshS0001s^X@GG diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 60ce244a..4b491433 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -1,7 +1,10 @@ using FreeSql.DataAnnotations; using System; +using System.Collections; +using System.Collections.Generic; using System.Data; using System.Diagnostics; +using System.Linq; using System.Linq.Expressions; using System.Threading; @@ -109,12 +112,47 @@ namespace FreeSql { get { - var select = Orm.Select().WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)); + var select = Orm.Select() + .TrackToList(TrackToList) //自动为每个元素 Attach + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)); if (string.IsNullOrEmpty(CurrentTenantId) == false) select.WhereCascade(a => (a as ITenant).TenantId == CurrentTenantId); return select.WhereCascade(a => (a as BaseEntity).IsDeleted == false); } } + + static void TrackToList(object list) + { + if (list == null) return; + var ls = list as IList; + if (ls == null) + { + var ie = list as IEnumerable; + if (ie == null) return; + var isFirst = true; + foreach (var item in ie) + { + if (item == null) return; + if (isFirst) + { + isFirst = false; + var itemType = item.GetType(); + if (itemType == typeof(object)) return; + if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; + if (item is BaseEntity == false) return; + } + (item as BaseEntity)?.Attach(); + } + return; + } + if (ls.Any() == false) return; + if (ls.FirstOrDefault() is BaseEntity == false) return; + if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) return; + foreach (var item in ls) + (item as BaseEntity)?.Attach(); + } + /// /// 设置当前租户id /// diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 64a4e184..97eb81b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1037,7 +1037,7 @@ 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 - 如:select.AsAlias((_, oldAlias) => oldAlias + " with(lock)") + 如:select.AsAlias((_, old) => $"{old} with(lock)") @@ -2146,6 +2146,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 }) + + + + + + 可自定义解析表达式 @@ -2924,160 +3055,3 @@ -unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index a9366d41..363d8249 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -124,7 +124,7 @@ namespace FreeSql TSelect AsTable(Func tableRule); /// /// 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 - /// 如:select.AsAlias((_, oldAlias) => oldAlias + " with(lock)") + /// 如:select.AsAlias((_, old) => $"{old} with(lock)") /// /// /// From 954a948837047933a22271e297351546b6885608 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 18 Dec 2019 21:29:21 +0800 Subject: [PATCH 0345/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20Sqlite=20=E7=9A=84=E9=A1=B9=E7=9B=AE=E5=BD=93?= =?UTF-8?q?=E6=9C=AA=E9=80=89=E6=8B=A9=20x86/x64=20=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E5=8F=8B=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 791fdb02..526dbabd 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -138,8 +138,8 @@ namespace FreeSql.Sqlite { if (obj.Value == null) { - if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) - throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + if (_pool.SetUnavailable(new Exception("连接字符串错误,或者检查项目属性 > 生成 > 目标平台:x86 | x64")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。或者检查项目属性 > 生成 > 目标平台:x86 | x64"); return; } From e03aaed55b8d1645169902f5e399758dfc2ccab8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Dec 2019 10:51:21 +0800 Subject: [PATCH 0346/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20LazyLoading?= =?UTF-8?q?=20=E5=9C=A8=20Net4=20=E7=8E=AF=E5=A2=83=E4=B8=8B=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Entities/Class1.cs | 1 + Examples/base_entity/Entities/User.cs | 2 +- Examples/base_entity/Program.cs | 3 ++ Examples/base_entity/base_entity.csproj | 1 + Examples/orm_vs_net40/Program.cs | 7 --- .../BaseEntity 纯净版源码(.Net 4.0).zip | Bin 2698 -> 2698 bytes .../LazyLoadingComplier.cs | 41 ++++++++++++++---- FreeSql/Internal/UtilsExpressionTree.cs | 12 +++-- 8 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 Examples/base_entity/Entities/Class1.cs diff --git a/Examples/base_entity/Entities/Class1.cs b/Examples/base_entity/Entities/Class1.cs new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/Examples/base_entity/Entities/Class1.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Examples/base_entity/Entities/User.cs b/Examples/base_entity/Entities/User.cs index 7e7d741f..3b8270ec 100644 --- a/Examples/base_entity/Entities/User.cs +++ b/Examples/base_entity/Entities/User.cs @@ -31,7 +31,7 @@ public class User1 : BaseEntity public int GroupId { get; set; } public UserGroup Group { get; set; } - public List Roles { get; set; } + public virtual List Roles { get; set; } /// /// 登陆名 diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 6f43a2e8..146f9603 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -44,10 +44,13 @@ namespace base_entity .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=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=2") .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + .UseLazyLoading(true) .Build(); BaseEntity.Initialization(fsql); #endregion + var us = User1.Select.Limit(10).ToList(); + new Products { title = "product-1" }.Save(); new Products { title = "product-2" }.Save(); new Products { title = "product-3" }.Save(); diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index 7289cf02..c912bae3 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -17,6 +17,7 @@ + diff --git a/Examples/orm_vs_net40/Program.cs b/Examples/orm_vs_net40/Program.cs index e3f572cb..66cd43ef 100644 --- a/Examples/orm_vs_net40/Program.cs +++ b/Examples/orm_vs_net40/Program.cs @@ -35,13 +35,6 @@ namespace orm_vs static void Main(string[] args) { - var testlist1 = fsql.Select().OrderBy(a => a.Id).ToList(); - var testlist2 = new List(); - fsql.Select().OrderBy(a => a.Id).ToChunk(0, list => - { - testlist2.AddRange(list); - }); - fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip index 11ac08713d39e5fa8d6f14da479b098d1c22ad90..6a90cb183bbb7a74c0e98cbb524ad08de5b0618b 100644 GIT binary patch delta 759 zcmV)W;w zsSwLfykK+iKuC)@8V3=H6LKk_Jci8VV@f*F$6VhbOx}JGbT2%R^O%QsR6sOsKK zA(E#Hf`5VZkQ%xHL|xD((Yjyresv^Y28G(>ky4S2jB?~itf^p|C+75zwl%W!0=b+* zgC*pr-YyV>)JyolYw+(?qGU4Kwq*n`H-bO5UN3pLVrn>wS}7_Ze2IfB9#vFFbC1jGMSW^ zyb8sypr%rnBWRoo4O*)@5ymS6V5$OBDMvH%!koG%w4rmivJIqyeOu_pZ+ap_yrNu- z5RLhUE%hYZ98TGvyL~ES`xf1A_aD!Edi&$^rJeG=)Umv?u{mBw1+;9b0qf0c)6GlA zgMaDIt#i*+!=V^^S)e1UddwViFtw$FwdE^UE?c^4)w;<^)AAh6$asf#_B`ZpO)J>g zDV1^SaijJ1Yw-C>)b9Mnt5=zkyt&qF^j)jHJ%mco>lF$JbO{?8#ce7kxtQ%elIm@l zAwwwD=lu@v;rfSew>-B@WuK@Oq%73D`G0oy+Qa7cbCK`=laP&9bQv2It2=~#Cx`%( zAV`YL51^S(SA!Fc%&$u32@p!48JA~yJE?h`3XgTvrDP2ql`UTmarnu6qQBoh6Lr%MZN?wWDe@TU~sn3+DpOdZ$ pYYjkFlTXfj`iz1F003;0CJHtV2*4)*7q-;_2*4)*7q*jX3LuT3da3{b delta 759 zcmVcG2#1pokRvk(OE0)Gam-#Ys|xX_q+|FJoJW#;|! z;PlDaH;>SW5ZJ2b`h_V2BY8dhQ(ZxgKe`gKQxmVWUn*_Gd~hz(3etfBY|A6pw{0U* zA(ovu!RFwAkQQ?^4k8jCb-(8Q>PWr}3bn~2r6L&_<;am(Q^7V*%;_I(Yh>jGayfnczFAsOs8;Uvg;Jhb`6su|vz4 zPgWc``Gp*L97nw}37ry}CsSs9U8QBLhOyR!ihn9g3pYpHx^AFFDjnuw4x*h^GN~|m z6^dU$O{FeJ&^Q$uv{rQ@j8_K0R0XC|j%MVAIdxBHL+5T~8%PEFw$P2=^hAbuMY$Fs z8uJZX>PfaaoU%W6`&7p6ExO+BKc4yY_Q&T-JLPq$V|is`bG(cSXxUN&)|=O+o0pCU z(|?~^=bo#6LoxQUKtopbm^tQPYD))e%U7;kwsh61b(52(@e1v1dC1|KR;PaKJ+xd$(uQDTfa;@3uyHql22&rz`KG4003)~CJHtV>uDNZrM1-o>uDNZrL~i43LvuxaLWJy diff --git a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs index dc388bf4..903d31ce 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs +++ b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs @@ -1,9 +1,7 @@ -using Microsoft.CSharp; -using System; +using System; using System.CodeDom.Compiler; -using System.Collections.Generic; +using System.IO; using System.Reflection; -using System.Text; namespace FreeSql.Extensions.LazyLoading { @@ -14,7 +12,7 @@ namespace FreeSql.Extensions.LazyLoading #if ns20 internal static Lazy _compiler = new Lazy(() => { - //var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll"); + //var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll;*.exe"); var compiler = new CSScriptLib.RoslynEvaluator(); compiler.DisableReferencingFromCode = false; //compiler.DebugBuild = true; @@ -36,14 +34,41 @@ namespace FreeSql.Extensions.LazyLoading #else - public static Assembly CompileCode(string cscode) { + public static Assembly CompileCode(string cscode) { - using (var compiler = CodeDomProvider.CreateProvider("cs")) { + var files = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName); + using (var compiler = CodeDomProvider.CreateProvider("cs")) { var objCompilerParameters = new CompilerParameters(); objCompilerParameters.ReferencedAssemblies.Add("System.dll"); + objCompilerParameters.ReferencedAssemblies.Add("System.Core.dll"); objCompilerParameters.ReferencedAssemblies.Add("FreeSql.dll"); - objCompilerParameters.GenerateExecutable = false; + foreach (var dll in files) + { + if (!dll.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && + !dll.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) continue; + + Console.WriteLine(dll); + var dllName = string.Empty; + var idx = dll.LastIndexOf('/'); + if (idx != -1) dllName = dll.Substring(idx + 1); + else + { + idx = dll.LastIndexOf('\\'); + if (idx != -1) dllName = dll.Substring(idx + 1); + } + if (string.IsNullOrEmpty(dllName)) continue; + try + { + var ass = Assembly.LoadFile(dll); + objCompilerParameters.ReferencedAssemblies.Add(dllName); + } + catch + { + + } + } + objCompilerParameters.GenerateExecutable = false; objCompilerParameters.GenerateInMemory = true; CompilerResults cr = compiler.CompileAssemblyFromSource(objCompilerParameters, cscode); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index f122b094..c7846319 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -788,8 +788,8 @@ namespace FreeSql.Internal .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); if (nvref.Exception == null) - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace}.{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace}.{propElementType.Name}") - .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace}.{tbmid.Type.Name}") + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace?.NotNullAndConcat(".")}{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace?.NotNullAndConcat(".")}{propElementType.Name}") + .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace?.NotNullAndConcat(".")}{tbmid.Type.Name}") .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();") .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); else @@ -801,7 +801,9 @@ namespace FreeSql.Internal } if (vp?.Item3 == true) { //set 重写 - cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); + cscode.Append(" set {\r\n") + .Append(" base.").Append(pnv.Name).AppendLine(" = value;") + .Append(" }\r\n"); } cscode.AppendLine(" }"); } @@ -940,7 +942,9 @@ namespace FreeSql.Internal } if (vp?.Item3 == true) { //set 重写 - cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); + cscode.Append(" set {\r\n") + .Append(" base.").Append(pnv.Name).AppendLine(" = value;") + .Append(" }\r\n"); } cscode.AppendLine(" }"); } From a23a49163e4b32b6d07d0e58c8a0432947638bf6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Dec 2019 10:55:26 +0800 Subject: [PATCH 0347/1029] update --- .../LazyLoadingComplier.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs index 903d31ce..0c8017fc 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs +++ b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs @@ -33,16 +33,16 @@ namespace FreeSql.Extensions.LazyLoading } #else - - public static Assembly CompileCode(string cscode) { + public static Assembly CompileCode(string cscode) + { var files = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName); - using (var compiler = CodeDomProvider.CreateProvider("cs")) { - - var objCompilerParameters = new CompilerParameters(); - objCompilerParameters.ReferencedAssemblies.Add("System.dll"); + using (var compiler = CodeDomProvider.CreateProvider("cs")) + { + var objCompilerParameters = new CompilerParameters(); + objCompilerParameters.ReferencedAssemblies.Add("System.dll"); objCompilerParameters.ReferencedAssemblies.Add("System.Core.dll"); - objCompilerParameters.ReferencedAssemblies.Add("FreeSql.dll"); + objCompilerParameters.ReferencedAssemblies.Add("FreeSql.dll"); foreach (var dll in files) { if (!dll.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && @@ -69,16 +69,16 @@ namespace FreeSql.Extensions.LazyLoading } } objCompilerParameters.GenerateExecutable = false; - objCompilerParameters.GenerateInMemory = true; + objCompilerParameters.GenerateInMemory = true; - CompilerResults cr = compiler.CompileAssemblyFromSource(objCompilerParameters, cscode); + CompilerResults cr = compiler.CompileAssemblyFromSource(objCompilerParameters, cscode); - if (cr.Errors.Count > 0) - throw new Exception(cr.Errors[0].ErrorText); + if (cr.Errors.Count > 0) + throw new Exception(cr.Errors[0].ErrorText); - return cr.CompiledAssembly; - } - } + return cr.CompiledAssembly; + } + } #endif } From eb4bbd9448b6f1f920a8e9d2a97e556090f49d2c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Dec 2019 11:22:19 +0800 Subject: [PATCH 0348/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E4=B8=BB=E9=94=AE=E7=9A=84=E5=AE=9E=E4=BD=93=EF=BC=8C?= =?UTF-8?q?=E7=BA=A6=E5=AE=9A=20id=20=E5=91=BD=E5=90=8D=E7=9A=84=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E4=B8=8A=E8=8B=A5=E8=AE=BE=E7=BD=AE=E4=BA=86=20IsPrim?= =?UTF-8?q?ary=20=3D=20false=EF=BC=8C=E5=88=99=E5=85=B6=E4=B8=8D=E5=B1=9E?= =?UTF-8?q?=E4=BA=8E=E7=BA=A6=E5=AE=9A=E4=B8=BB=E9=94=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 14 ++ FreeSql/FreeSql.xml | 288 ++++++++++++----------- FreeSql/Internal/UtilsExpressionTree.cs | 6 +- 3 files changed, 174 insertions(+), 134 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 4a6d3519..6c86a36d 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -43,7 +43,21 @@ namespace FreeSql.Tests // fsql.Select().ToList(); //} + var tb1 = g.sqlite.CodeFirst.GetTableByEntity(typeof(pkfalse_t1)); + var tb2 = g.sqlite.CodeFirst.GetTableByEntity(typeof(pkfalse_t2)); + } + + class pkfalse_t1 + { + [Column(IsPrimary = false)] + public int id { get; set; } + } + + class pkfalse_t2 + { + [Column(IsPrimary = true)] + public int id { get; set; } } class ut3_t1 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 97eb81b3..ca0c17f1 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2146,137 +2146,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3055,3 +2924,160 @@ +unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c7846319..8f8ce4e3 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -335,17 +335,17 @@ namespace FreeSql.Internal trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); if (trytb.Primarys.Any() == false) { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, "id", true) == 0).ToArray(); + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute._IsPrimary == null && string.Compare(a.Attribute.Name, "id", true) == 0).ToArray(); if (trytb.Primarys.Any() == false) { var identcol = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).FirstOrDefault(); if (identcol != null) trytb.Primarys = new[] { identcol }; if (trytb.Primarys.Any() == false) { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}id", true) == 0).ToArray(); + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute._IsPrimary == null && string.Compare(a.Attribute.Name, $"{trytb.DbName}id", true) == 0).ToArray(); if (trytb.Primarys.Any() == false) { - trytb.Primarys = trytb.Columns.Values.Where(a => string.Compare(a.Attribute.Name, $"{trytb.DbName}_id", true) == 0).ToArray(); + trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute._IsPrimary == null && string.Compare(a.Attribute.Name, $"{trytb.DbName}_id", true) == 0).ToArray(); } } } From ec25ccea86987ceec2d23aa81e5ddf150d376e38 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Dec 2019 13:46:11 +0800 Subject: [PATCH 0349/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20Select`2-10?= =?UTF-8?q?=20=E5=A4=9A=E8=A1=A8=E6=9F=A5=E8=AF=A2=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=20First(select)/ToOne(select)/First?= =?UTF-8?q?\=20=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LazyLoadingComplier.cs | 7 - .../DataAnnotations/MySqlFluentTest.cs | 27 ++ .../DataAnnotations/SqlServerFluentTest.cs | 27 ++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 16 - FreeSql/FreeSql.xml | 288 ++++++++---------- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 12 +- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 14 +- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 12 +- FreeSql/Interface/Curd/ISelect/ISelect4.cs | 12 +- FreeSql/Interface/Curd/ISelect/ISelect5.cs | 12 +- FreeSql/Interface/Curd/ISelect/ISelect6.cs | 12 +- FreeSql/Interface/Curd/ISelect/ISelect7.cs | 12 +- FreeSql/Interface/Curd/ISelect/ISelect8.cs | 12 +- FreeSql/Interface/Curd/ISelect/ISelect9.cs | 12 +- .../SelectProvider/Select10Provider.cs | 12 +- .../SelectProvider/Select2Provider.cs | 12 +- .../SelectProvider/Select3Provider.cs | 12 +- .../SelectProvider/Select4Provider.cs | 12 +- .../SelectProvider/Select5Provider.cs | 12 +- .../SelectProvider/Select6Provider.cs | 12 +- .../SelectProvider/Select7Provider.cs | 12 +- .../SelectProvider/Select8Provider.cs | 12 +- .../SelectProvider/Select9Provider.cs | 12 +- FreeSql/Internal/UtilsExpressionTree.cs | 3 - .../Dameng/OdbcDamengCodeFirst.cs | 2 +- 25 files changed, 376 insertions(+), 212 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs index 0c8017fc..75dfb248 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs +++ b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs @@ -12,15 +12,8 @@ namespace FreeSql.Extensions.LazyLoading #if ns20 internal static Lazy _compiler = new Lazy(() => { - //var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll;*.exe"); var compiler = new CSScriptLib.RoslynEvaluator(); compiler.DisableReferencingFromCode = false; - //compiler.DebugBuild = true; - //foreach (var dll in dlls) { - // Console.WriteLine(dll); - // var ass = Assembly.LoadFile(dll); - // compiler.ReferenceAssembly(ass); - //} compiler .ReferenceAssemblyOf() .ReferenceDomainAssemblies(); diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index efeca38c..c4110f04 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -133,6 +133,33 @@ namespace FreeSql.Tests.DataAnnotations public bool isignore { get; set; } } + [Fact] + public void AutoPrimary() + { + var tb1 = g.mysql.CodeFirst.GetTableByEntity(typeof(pkfalse_t1)); + var tb2 = g.mysql.CodeFirst.GetTableByEntity(typeof(pkfalse_t2)); + var tb3 = g.mysql.CodeFirst.GetTableByEntity(typeof(pkfalse_t3)); + + Assert.True(tb1.ColumnsByCs["id"].Attribute.IsPrimary); + Assert.False(tb2.ColumnsByCs["id"].Attribute.IsPrimary); + Assert.True(tb3.ColumnsByCs["id"].Attribute.IsPrimary); + } + + class pkfalse_t1 + { + public int id { get; set; } + } + class pkfalse_t2 + { + [Column(IsPrimary = false)] + public int id { get; set; } + } + class pkfalse_t3 + { + [Column(IsPrimary = true)] + public int id { get; set; } + } + [Fact] public void CanInsert_CanUpdate() { diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs index 77e54ddb..e3eaf1f7 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs @@ -128,6 +128,33 @@ namespace FreeSql.Tests.DataAnnotations [Column(IsIgnore = true)] public bool isignore { get; set; } } + + [Fact] + public void AutoPrimary() + { + var tb1 = g.sqlserver.CodeFirst.GetTableByEntity(typeof(pkfalse_t1)); + var tb2 = g.sqlserver.CodeFirst.GetTableByEntity(typeof(pkfalse_t2)); + var tb3 = g.sqlserver.CodeFirst.GetTableByEntity(typeof(pkfalse_t3)); + + Assert.True(tb1.ColumnsByCs["id"].Attribute.IsPrimary); + Assert.False(tb2.ColumnsByCs["id"].Attribute.IsPrimary); + Assert.True(tb3.ColumnsByCs["id"].Attribute.IsPrimary); + } + + class pkfalse_t1 + { + public int id { get; set; } + } + class pkfalse_t2 + { + [Column(IsPrimary = false)] + public int id { get; set; } + } + class pkfalse_t3 + { + [Column(IsPrimary = true)] + public int id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 6c86a36d..0fba1c0e 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -43,21 +43,6 @@ namespace FreeSql.Tests // fsql.Select().ToList(); //} - var tb1 = g.sqlite.CodeFirst.GetTableByEntity(typeof(pkfalse_t1)); - - var tb2 = g.sqlite.CodeFirst.GetTableByEntity(typeof(pkfalse_t2)); - } - - class pkfalse_t1 - { - [Column(IsPrimary = false)] - public int id { get; set; } - } - - class pkfalse_t2 - { - [Column(IsPrimary = true)] - public int id { get; set; } } class ut3_t1 @@ -66,7 +51,6 @@ namespace FreeSql.Tests public int id { get; set; } public string name { get; set; } } - class ut3_t2 { [Column(IsIdentity = true)] diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ca0c17f1..97eb81b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2146,6 +2146,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 }) + + + + + + 可自定义解析表达式 @@ -2924,160 +3055,3 @@ -unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index c370667b..57faf043 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); + + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -28,6 +31,11 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index c419870b..ccb2d1c6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select); + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select); Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -26,8 +29,13 @@ namespace FreeSql bool Any(Expression> exp); DataTable ToDataTable(Expression> select); - List ToList(Expression> select); + List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index d53693c1..eac99d36 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -28,6 +31,11 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index b60dfc14..ca180e47 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -28,6 +31,11 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index f4c340be..a870eeed 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -28,6 +31,11 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 8a6db616..08cdd495 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -28,6 +31,11 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index 62a0d528..88f81f92 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -28,6 +31,11 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 18d4c318..92492ef6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -28,6 +31,11 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index f8974d0b..21d92c7a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -12,12 +12,15 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); - Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); Task SumAsync(Expression> column); Task MinAsync(Expression> column); Task MaxAsync(Expression> column); @@ -28,6 +31,11 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); decimal Sum(Expression> column); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 892b45d6..fd73c7c0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -121,7 +122,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -170,6 +171,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -228,6 +233,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 40ed5cb9..beaa1d50 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -98,7 +99,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -147,6 +148,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -205,6 +210,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 31f842a7..5f49d8cf 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -101,7 +102,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -150,6 +151,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -208,6 +213,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index e3ab43e0..075397f7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -104,7 +105,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -153,6 +154,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -211,6 +216,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 97633b78..d21e16a2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -107,7 +108,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -156,6 +157,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -214,6 +219,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 1f3dfd02..5669598d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -110,7 +111,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -159,6 +160,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -217,6 +222,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index b6e443f8..a8f94ac3 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -113,7 +114,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -162,6 +163,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -220,6 +225,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 3c47a61e..f85d2df9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -117,7 +118,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -166,6 +167,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -224,6 +229,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 5011cfa1..d03d4ba0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -117,7 +118,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToDataTable(select?.Body); } - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; @@ -163,6 +164,10 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + #if net40 #else Task ISelect.AnyAsync(Expression> exp) @@ -222,6 +227,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToListAsync(select?.Body); } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 8f8ce4e3..c8b1b92f 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -98,10 +98,7 @@ namespace FreeSql.Internal { Name = p.Name, DbType = tp.Value.dbtypeFull, - IsIdentity = false, IsNullable = tp.Value.isnullable ?? true, - IsPrimary = false, - IsIgnore = false, MapType = p.PropertyType }; if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 09a14594..f9e6d7d0 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -425,7 +425,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and var data_length = long.Parse(string.Concat(a[2])); long.TryParse(string.Concat(a[3]), out var data_precision); long.TryParse(string.Concat(a[4]), out var data_scale); - var char_used = string.Concat(a[5]); + //var char_used = string.Concat(a[5]); if (sqlType.StartsWith("INTERVAL DAY TO SECOND")) sqlType = $"INTERVAL DAY({(data_scale - 1536) / 16}) TO SECOND({(data_scale - 1536) % 16})"; else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) From 969e690682f93b62feb818b4568b6b67ece91bd8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Dec 2019 15:50:42 +0800 Subject: [PATCH 0350/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ISelect.Coun?= =?UTF-8?q?t()=20=E4=B9=8B=E5=89=8D=E4=BD=BF=E7=94=A8=E4=BA=86=20OrderBy?= =?UTF-8?q?=20=E4=BC=9A=E4=BA=A7=E7=94=9F=E7=9A=84=20SQL=20=E8=AF=AD?= =?UTF-8?q?=E6=B3=95=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SqlServer/Curd/SqlServerSelectTest.cs | 3 ++ FreeSql/Internal/CommonExpression.cs | 5 ++-- .../SelectProvider/Select0Provider.cs | 28 +++++++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 2f141e8d..8e318e6b 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -209,8 +209,11 @@ namespace FreeSql.Tests.SqlServer public void Count() { var count = select.Where(a => 1 == 1).Count(); + var count11 = select.Where(a => 1 == 1).OrderBy(a => a.Id).Count(); select.Where(a => 1 == 1).Count(out var count2); + select.Where(a => 1 == 1).OrderBy(a => a.Id).Count(out var count22); Assert.Equal(count, count2); + Assert.Equal(count11, count22); Assert.Equal(0, select.Where(a => 1 == 2).Count()); var subquery = select.ToSql(a => new diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b1d2a2d8..e715f4e4 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -762,8 +762,9 @@ namespace FreeSql.Internal else if (fsqlType != null) { var call3Exp = exp3tmp as MethodCallExpression; - var method = fsqlType.GetMethod(call3Exp.Method.Name, call3Exp.Arguments.Select(a => a.Type).ToArray()); - if (call3Exp.Method.ContainsGenericParameters) method.MakeGenericMethod(call3Exp.Method.GetGenericArguments()); + var method = call3Exp.Method; + //var method = fsqlType.GetMethod(call3Exp.Method.Name, call3Exp.Arguments.Select(a => a.Type).ToArray()); + //if (call3Exp.Method.ContainsGenericParameters) method.MakeGenericMethod(call3Exp.Method.GetGenericArguments()); var parms = method.GetParameters(); var args = new object[call3Exp.Arguments.Count]; for (var a = 0; a < args.Length; a++) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index cd308800..238a0285 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -158,7 +158,19 @@ namespace FreeSql.Internal.CommonProvider return this.ToList("1 as1").Sum() > 0; //这里的 Sum 为了分表查询 } - public long Count() => this.ToList("count(1) as1").Sum(); //这里的 Sum 为了分表查询 + public long Count() + { + var tmpOrderBy = _orderby; + _orderby = null; //解决 select count(1) from t order by id 这样的 SQL 错误 + try + { + return this.ToList("count(1) as1").Sum(); //这里的 Sum 为了分表查询 + } + finally + { + _orderby = tmpOrderBy; + } + } public TSelect Count(out long count) { @@ -1111,7 +1123,19 @@ namespace FreeSql.Internal.CommonProvider return (await this.ToListAsync("1 as1")).Sum() > 0; //这里的 Sum 为了分表查询 } - async public Task CountAsync() => (await this.ToListAsync("count(1) as1")).Sum(); //这里的 Sum 为了分表查询 + async public Task CountAsync() + { + var tmpOrderBy = _orderby; + _orderby = null; + try + { + return (await this.ToListAsync("count(1) as1")).Sum(); //这里的 Sum 为了分表查询 + } + finally + { + _orderby = tmpOrderBy; + } + } async public Task ToDataTableAsync(string field = null) { From ad623e0b629d9c51617d77c41296325e566aa004 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Dec 2019 13:30:09 +0800 Subject: [PATCH 0351/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Gene?= =?UTF-8?q?rator=20-Filter=20=E8=AE=BE=E7=BD=AE=E9=80=89=E9=A1=B9=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E9=98=BB=E6=AD=A2=E5=AD=98=E5=82=A8=E8=BF=87=E7=A8=8B?= =?UTF-8?q?+=E8=A7=86=E5=9B=BE=E7=9A=84=E7=94=9F=E6=88=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 59 +++++++++++++++++-- .../FreeSql.Generator/RazorContentManager.cs | 10 ++-- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 104585db..4aa763b1 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -17,6 +17,7 @@ namespace FreeSql.Generator string ArgsNameSpace { get; } DataType ArgsDbType { get; } string ArgsConnectionString { get; } + string ArgsFilter { get; } string ArgsFileName { get; } string ArgsOutput { get; } @@ -50,9 +51,13 @@ namespace FreeSql.Generator new Colorful.Formatter("https://github.com/2881099/FreeSql", Color.DeepSkyBlue), new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetName().Version.ToString().Split('.').Where((a, b) => b <= 2)), Color.SlateGray)); + ArgsRazorRaw = "1"; + ArgsRazor = RazorContentManager.实体类_特性_cshtml; ArgsNameOptions = new[] { false, false, false, false }; - ArgsOutput = Directory.GetCurrentDirectory(); + ArgsNameSpace = "MyProject"; + ArgsFilter = ""; ArgsFileName = "{name}.cs"; + ArgsOutput = Directory.GetCurrentDirectory(); string args0 = args[0].Trim().ToLower(); if (args[0] == "?" || args0 == "--help" || args0 == "-help") { @@ -92,6 +97,10 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -DB ""{10},Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789;Max pool size=2"" {10} 是国产达梦数据库,需要使用 ODBC 连接 + -Filter Table+View+StoreProcedure + 默认生成:表+视图+存储过程 + 如果不想生成视图和存储过程 -Fitler View+StoreProcedure + -FileName 文件名,默认:{name}.cs -Output 保存路径,默认为当前 shell 所在目录 @@ -151,7 +160,10 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 default: throw new ArgumentException($"-DB 参数错误,不支持的类型:{dbargs[0]}"); } ArgsConnectionString = dbargs[1].Trim(); - if (string.IsNullOrEmpty(ArgsConnectionString)) throw new ArgumentException($"-DB 参数错误,未提供 ConnectionString"); + a++; + break; + case "-Filter": + ArgsFilter = args[a + 1]; a++; break; case "-FileName": @@ -165,6 +177,8 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 } } + if (string.IsNullOrEmpty(ArgsConnectionString)) throw new ArgumentException($"-DB 参数错误,未提供 ConnectionString"); + ArgsOutput = ArgsOutput.Trim().TrimEnd('/', '\\'); ArgsOutput += ArgsOutput.Contains("\\") ? "\\" : "/"; if (!Directory.Exists(ArgsOutput)) @@ -187,10 +201,34 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 var tables = fsql.DbFirst.GetTablesByDatabase(); var outputTables = tables; - + //开始生成操作 foreach (var table in outputTables) { + switch (table.Type) + { + case DatabaseModel.DbTableType.TABLE: + if (ArgsFilter.Contains("Table", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteFormatted(" Ignore Table -> " + table.Name + "\r\n", Color.DarkSlateGray); + continue; + } + break; + case DatabaseModel.DbTableType.VIEW: + if (ArgsFilter.Contains("View", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteFormatted(" Ignore View -> " + table.Name + "\r\n", Color.DarkSlateGray); + continue; + } + break; + case DatabaseModel.DbTableType.StoreProcedure: + if (ArgsFilter.Contains("StoreProcedure", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteFormatted(" Ignore StoreProcedure -> " + table.Name + "\r\n", Color.DarkSlateGray); + continue; + } + break; + } var sw = new StringWriter(); var model = new RazorModel(fsql, ArgsNameSpace, ArgsNameOptions, tables, table); RazorEngine.Engine.Razor.Run(razorId, sw, null, model); @@ -210,7 +248,18 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 var outputFile = $"{ArgsOutput}{ArgsFileName.Replace("{name}", model.GetCsName(table.Name))}"; File.WriteAllText(outputFile, plus.ToString()); - Console.WriteFormatted(" OUT -> " + outputFile + "\r\n", Color.DeepSkyBlue); + switch (table.Type) + { + case DatabaseModel.DbTableType.TABLE: + Console.WriteFormatted(" OUT Table -> " + outputFile + "\r\n", Color.DeepSkyBlue); + break; + case DatabaseModel.DbTableType.VIEW: + Console.WriteFormatted(" OUT View -> " + outputFile + "\r\n", Color.DeepSkyBlue); + break; + case DatabaseModel.DbTableType.StoreProcedure: + Console.WriteFormatted(" OUT StoreProcedure -> " + outputFile + "\r\n", Color.DeepSkyBlue); + break; + } ++outputCounter; } } @@ -220,7 +269,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 { File.WriteAllText(rebuildBat, $@" FreeSql.Generator -Razor {ArgsRazorRaw} -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}"" -"); +"); Console.WriteFormatted(" OUT -> " + rebuildBat + " (以后) 双击它重新生成实体\r\n", Color.Magenta); ++outputCounter; } diff --git a/Extensions/FreeSql.Generator/RazorContentManager.cs b/Extensions/FreeSql.Generator/RazorContentManager.cs index e46a6370..9773795b 100644 --- a/Extensions/FreeSql.Generator/RazorContentManager.cs +++ b/Extensions/FreeSql.Generator/RazorContentManager.cs @@ -77,8 +77,8 @@ namespace @gen.NameSpace { #endregion public static string 实体类_特性_导航属性_cshtml = - #region 长内容 - @"@using FreeSql.DatabaseModel;@{ + #region 长内容 + @"@using FreeSql.DatabaseModel;@{ var isLazying = true; //延时加载 var isOneToMany = true; //一对多,集合属性 @@ -108,7 +108,7 @@ Func GetFkObjectNameOutside = fkx => { if (fkretname.EndsWith(fkx.ReferencedColumns[0].Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedColumns[0].Name.Length).TrimEnd('_'); if (fkretname.EndsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedTable.Name.Length).TrimEnd('_'); if (fkretname.StartsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(fkx.ReferencedTable.Name.Length).TrimStart('_'); - return fkx.Table.Name + ""s""; + return fkx.Table.Name + (string.IsNullOrEmpty(fkretname) ? """" : (""_"" + fkretname)); }; }@{ switch (gen.fsql.Ado.DataType) { @@ -179,7 +179,7 @@ namespace @gen.NameSpace { } @: @:[Navigate(""@string.Join("", "", fk.Columns.Select(a => gen.GetCsName(a.Name)))"")] - @:public@(isLazying ? "" virtual"" : """") @gen.GetCsName(fkTableName) @GetFkObjectName(fk) { get; set; } + @:public@(isLazying ? "" virtual"" : """") @gen.GetCsName(fkTableName) @gen.GetCsName(GetFkObjectName(fk)) { get; set; } } @: @:#endregion @@ -197,7 +197,7 @@ namespace @gen.NameSpace { } @: @:[Navigate(""@string.Join("", "", fk.Columns.Select(a => gen.GetCsName(a.Name)))"")] - @:public@(isLazying ? "" virtual"" : """") List<@gen.GetCsName(fkTableName)> @GetFkObjectNameOutside(fk)s { get; set; } + @:public@(isLazying ? "" virtual"" : """") List<@gen.GetCsName(fkTableName)> @gen.GetCsName(GetFkObjectNameOutside(fk))s { get; set; } } } @: From 5e7ba890d4623b3e2f129da0883078c1dfb951a6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Dec 2019 14:17:55 +0800 Subject: [PATCH 0352/1029] - FreeSql.Generator --- Extensions/FreeSql.Generator/ConsoleApp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 4aa763b1..c3e9b51b 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -268,7 +268,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 if (File.Exists(rebuildBat) == false) { File.WriteAllText(rebuildBat, $@" -FreeSql.Generator -Razor {ArgsRazorRaw} -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}"" +FreeSql.Generator -Razor {ArgsRazorRaw} -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}""{(string.IsNullOrEmpty(ArgsFilter) ? "" : $" -Filter \"{ArgsFilter}\"")} -FileName ""{ArgsFileName}"" "); Console.WriteFormatted(" OUT -> " + rebuildBat + " (以后) 双击它重新生成实体\r\n", Color.Magenta); ++outputCounter; From 80133d0af76e89e8dd689983d61fd51b27b74e2f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Dec 2019 17:21:18 +0800 Subject: [PATCH 0353/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Gene?= =?UTF-8?q?rator=20=E5=9C=A8=E7=9B=AE=E6=A0=87=E7=9B=AE=E5=BD=95=E4=BA=A7?= =?UTF-8?q?=E7=94=9F=20=5F=5Frazor.cshtml.txt=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E4=BE=BF=E8=87=AA=E5=AE=9A=E4=B9=89=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=A8=A1=E6=9D=BF=E7=94=9F=E6=88=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 47 +++++++++++++--------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index c3e9b51b..6488856a 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -19,7 +19,7 @@ namespace FreeSql.Generator string ArgsConnectionString { get; } string ArgsFilter { get; } string ArgsFileName { get; } - string ArgsOutput { get; } + internal string ArgsOutput { get; private set; } public ConsoleApp(string[] args, ManualResetEvent wait) { @@ -57,7 +57,16 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam ArgsNameSpace = "MyProject"; ArgsFilter = ""; ArgsFileName = "{name}.cs"; - ArgsOutput = Directory.GetCurrentDirectory(); + Action setArgsOutput = value => + { + ArgsOutput = value; + ArgsOutput = ArgsOutput.Trim().TrimEnd('/', '\\'); + ArgsOutput += ArgsOutput.Contains("\\") ? "\\" : "/"; + if (!Directory.Exists(ArgsOutput)) + Directory.CreateDirectory(ArgsOutput); + }; + setArgsOutput(Directory.GetCurrentDirectory()); + string args0 = args[0].Trim().ToLower(); if (args[0] == "?" || args0 == "--help" || args0 == "-help") { @@ -125,9 +134,9 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 } for (int a = 0; a < args.Length; a++) { - switch (args[a]) + switch (args[a].Trim().ToLower()) { - case "-Razor": + case "-razor": ArgsRazorRaw = args[a + 1].Trim(); switch (ArgsRazorRaw) { @@ -138,16 +147,16 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 a++; break; - case "-NameOptions": + case "-nameoptions": ArgsNameOptions = args[a + 1].Split(',').Select(opt => opt == "1").ToArray(); if (ArgsNameOptions.Length != 4) throw new ArgumentException("-NameOptions 参数错误,格式为:0,0,0,0"); a++; break; - case "-NameSpace": + case "-namespace": ArgsNameSpace = args[a + 1]; a++; break; - case "-DB": + case "-db": var dbargs = args[a + 1].Split(',', 2); if (dbargs.Length != 2) throw new ArgumentException("-DB 参数错误,格式为:MySql,ConnectionString"); switch (dbargs[0].Trim().ToLower()) @@ -162,16 +171,16 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 ArgsConnectionString = dbargs[1].Trim(); a++; break; - case "-Filter": + case "-filter": ArgsFilter = args[a + 1]; a++; break; - case "-FileName": + case "-filename": ArgsFileName = args[a + 1]; a++; break; - case "-Output": - ArgsOutput = args[a + 1]; + case "-output": + setArgsOutput(args[a + 1]); a++; break; } @@ -179,11 +188,6 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 if (string.IsNullOrEmpty(ArgsConnectionString)) throw new ArgumentException($"-DB 参数错误,未提供 ConnectionString"); - ArgsOutput = ArgsOutput.Trim().TrimEnd('/', '\\'); - ArgsOutput += ArgsOutput.Contains("\\") ? "\\" : "/"; - if (!Directory.Exists(ArgsOutput)) - Directory.CreateDirectory(ArgsOutput); - RazorEngine.Engine.Razor = RazorEngineService.Create(new RazorEngine.Configuration.TemplateServiceConfiguration { EncodedStringFactory = new RazorEngine.Text.RawStringFactory() // Raw string encoding. @@ -201,7 +205,6 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 var tables = fsql.DbFirst.GetTablesByDatabase(); var outputTables = tables; - //开始生成操作 foreach (var table in outputTables) { @@ -267,8 +270,16 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 var rebuildBat = ArgsOutput + "__重新生成.bat"; if (File.Exists(rebuildBat) == false) { + var razorCshtml = ArgsOutput + "__razor.cshtml.txt"; + if (File.Exists(razorCshtml) == false) + { + File.WriteAllText(razorCshtml, ArgsRazor); + Console.WriteFormatted(" OUT -> " + razorCshtml + " (以后) 编辑它自定义模板生成\r\n", Color.Magenta); + ++outputCounter; + } + File.WriteAllText(rebuildBat, $@" -FreeSql.Generator -Razor {ArgsRazorRaw} -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}""{(string.IsNullOrEmpty(ArgsFilter) ? "" : $" -Filter \"{ArgsFilter}\"")} -FileName ""{ArgsFileName}"" +FreeSql.Generator -Razor ""__razor.cshtml.txt"" -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}""{(string.IsNullOrEmpty(ArgsFilter) ? "" : $" -Filter \"{ArgsFilter}\"")} -FileName ""{ArgsFileName}"" "); Console.WriteFormatted(" OUT -> " + rebuildBat + " (以后) 双击它重新生成实体\r\n", Color.Magenta); ++outputCounter; From ab1d0a2cb582d551ff0817542faeb88bc98a1275 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Dec 2019 19:47:43 +0800 Subject: [PATCH 0354/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IInsert/IUpd?= =?UTF-8?q?ate=20BatchOptions=20=E6=96=B9=E6=B3=95=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=8F=92=E5=85=A5=E7=9A=84=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 163 ++++-------------- FreeSql/Interface/Curd/IInsert.cs | 16 ++ FreeSql/Interface/Curd/IUpdate.cs | 16 ++ .../Internal/CommonProvider/InsertProvider.cs | 18 +- .../Internal/CommonProvider/UpdateProvider.cs | 16 +- .../Curd/MySqlInsert.cs | 6 +- .../Curd/MySqlUpdate.cs | 4 +- .../Dameng/Curd/OdbcDamengInsert.cs | 6 +- .../Dameng/Curd/OdbcDamengUpdate.cs | 4 +- .../GBase/Curd/OdbcGBaseUpdate.cs | 4 +- .../GBase/Curd/__OdbcGBaseInsert.cs | 6 +- .../MySql/Curd/OdbcMySqlInsert.cs | 6 +- .../MySql/Curd/OdbcMySqlUpdate.cs | 4 +- .../Oracle/Curd/OdbcOracleInsert.cs | 6 +- .../Oracle/Curd/OdbcOracleUpdate.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 6 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 6 +- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 4 +- .../Curd/OracleInsert.cs | 6 +- .../Curd/OracleUpdate.cs | 4 +- .../Curd/PostgreSQLInsert.cs | 6 +- .../Curd/PostgreSQLUpdate.cs | 4 +- .../Curd/SqlServerInsert.cs | 6 +- .../Curd/SqlServerUpdate.cs | 4 +- .../Curd/SqliteInsert.cs | 6 +- .../Curd/SqliteUpdate.cs | 4 +- 27 files changed, 148 insertions(+), 191 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 97eb81b3..76a0f62e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -856,6 +856,22 @@ + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 values, parameters 限制不一样,默认设置: + MySql 5000 3000 + PostgreSQL 5000 3000 + SqlServer 1000 2100 + Oracle 500 999 + Sqlite 5000 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 values 数量拆分执行 + 指定根据 parameters 数量拆分执行 + 是否自动开启事务 + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; @@ -1818,6 +1834,22 @@ + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 rows, parameters 限制不一样,默认设置: + MySql 500 3000 + PostgreSQL 500 3000 + SqlServer 500 2100 + Oracle 200 999 + Sqlite 200 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 rows 数量拆分执行 + 指定根据 parameters 数量拆分执行 + 是否自动开启事务 + + 更新数据,设置更新的实体 @@ -2146,137 +2178,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 9a246642..74a77ca5 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -66,6 +66,22 @@ namespace FreeSql /// IInsert NoneParameter(); + /// + /// 批量执行选项设置,一般不需要使用该方法 + /// 各数据库 values, parameters 限制不一样,默认设置: + /// MySql 5000 3000 + /// PostgreSQL 5000 3000 + /// SqlServer 1000 2100 + /// Oracle 500 999 + /// Sqlite 5000 999 + /// 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + /// + /// 指定根据 values 数量拆分执行 + /// 指定根据 parameters 数量拆分执行 + /// 是否自动开启事务 + /// + IInsert BatchOptions(int valuesLimit, int parameterLimit, bool autoTransaction = true); + /// /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; /// diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 9276c68d..8595b648 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -28,6 +28,22 @@ namespace FreeSql /// IUpdate NoneParameter(); + /// + /// 批量执行选项设置,一般不需要使用该方法 + /// 各数据库 rows, parameters 限制不一样,默认设置: + /// MySql 500 3000 + /// PostgreSQL 500 3000 + /// SqlServer 500 2100 + /// Oracle 200 999 + /// Sqlite 200 999 + /// 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + /// + /// 指定根据 rows 数量拆分执行 + /// 指定根据 parameters 数量拆分执行 + /// 是否自动开启事务 + /// + IUpdate BatchOptions(int rowsLimit, int parameterLimit, bool autoTransaction = true); + /// /// 更新数据,设置更新的实体 /// diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index ebfb45c1..a606b4d3 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -23,6 +23,8 @@ namespace FreeSql.Internal.CommonProvider protected TableInfo _table; protected Func _tableRule; protected bool _noneParameter, _insertIdentity; + protected int _batchValuesLimit, _batchParameterLimit; + protected bool _batchAutoTransaction = true; protected DbParameter[] _params; protected DbTransaction _transaction; protected DbConnection _connection; @@ -50,6 +52,8 @@ namespace FreeSql.Internal.CommonProvider } protected void ClearData() { + _batchValuesLimit = _batchParameterLimit = 0; + _batchAutoTransaction = true; _insertIdentity = false; _source.Clear(); _ignore.Clear(); @@ -83,6 +87,14 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IInsert BatchOptions(int valuesLimit, int parameterLimit, bool autoTransaction = true) + { + _batchValuesLimit = valuesLimit; + _batchParameterLimit = parameterLimit; + _batchAutoTransaction = autoTransaction; + return this; + } + public IInsert AppendData(T1 source) { if (source != null) @@ -181,7 +193,7 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + if (_transaction != null || _batchAutoTransaction == false) { for (var a = 0; a < ss.Length; a++) { @@ -233,7 +245,7 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + if (_transaction != null || _batchAutoTransaction == false) { for (var a = 0; a < ss.Length; a++) { @@ -287,7 +299,7 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + if (_transaction != null || _batchAutoTransaction == false) { for (var a = 0; a < ss.Length; a++) { diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index b105a7dc..b84951eb 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -30,6 +30,8 @@ namespace FreeSql.Internal.CommonProvider protected List _params = new List(); protected List _paramsSource = new List(); protected bool _noneParameter; + protected int _batchRowsLimit, _batchParameterLimit; + protected bool _batchAutoTransaction = true; protected DbTransaction _transaction; protected DbConnection _connection; @@ -58,6 +60,8 @@ namespace FreeSql.Internal.CommonProvider } protected void ClearData() { + _batchRowsLimit = _batchParameterLimit = 0; + _batchAutoTransaction = true; _source.Clear(); _ignore.Clear(); _auditValueChangedDict.Clear(); @@ -89,6 +93,14 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IUpdate BatchOptions(int rowsLimit, int parameterLimit, bool autoTransaction = true) + { + _batchRowsLimit = rowsLimit; + _batchParameterLimit = parameterLimit; + _batchAutoTransaction = autoTransaction; + return this; + } + protected void ValidateVersionAndThrow(int affrows) { if (_table.VersionColumn != null && _source.Count > 0) @@ -136,7 +148,7 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + if (_transaction != null || _batchAutoTransaction == false) { for (var a = 0; a < ss.Length; a++) { @@ -183,7 +195,7 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + if (_transaction != null || _batchAutoTransaction == false) { for (var a = 0; a < ss.Length; a++) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 20af4f0b..ee25ff2b 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -29,9 +29,9 @@ namespace FreeSql.MySql.Curd internal Dictionary InternalIgnore => _ignore; internal void InternalClearData() => ClearData(); - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); public override string ToSql() diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 45ac940f..dcde6b41 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -25,8 +25,8 @@ namespace FreeSql.MySql.Curd internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override List RawExecuteUpdated() { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index 3d065911..177f36e8 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -18,9 +18,9 @@ namespace FreeSql.Odbc.Dameng { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); - public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override string ToSql() { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs index 944fa5c2..6b15906c 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.Odbc.Dameng { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override List RawExecuteUpdated() diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs index dc9d3cc7..4a02c36b 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.Odbc.GBase { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override List RawExecuteUpdated() { diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs index 496108fa..b017e33d 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs @@ -16,9 +16,9 @@ namespace FreeSql.Odbc.GBase { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override long RawExecuteIdentity() { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index 9d973dd4..cfb9bcdb 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -17,9 +17,9 @@ namespace FreeSql.Odbc.MySql { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override long RawExecuteIdentity() diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index 4194f4f0..d98073d5 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.Odbc.MySql { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override List RawExecuteUpdated() diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index f728c68c..0e97103b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -18,9 +18,9 @@ namespace FreeSql.Odbc.Oracle { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); - public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override string ToSql() { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index 51e66622..58c7b20b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.Odbc.Oracle { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override List RawExecuteUpdated() diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index 9ded50ef..f159b95c 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -16,9 +16,9 @@ namespace FreeSql.Odbc.PostgreSQL { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override long RawExecuteIdentity() { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 8c13d6cf..704da574 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.Odbc.PostgreSQL { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override List RawExecuteUpdated() { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index da09a6ab..464c2d37 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -17,9 +17,9 @@ namespace FreeSql.Odbc.SqlServer { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(1000, 2100); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); - public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); protected override int RawExecuteAffrows() { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index 52155aad..57930d57 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.Odbc.SqlServer { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 2100); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 2100); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); protected override List RawExecuteUpdated() { diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index b48404a5..da9c4f0e 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -19,9 +19,9 @@ namespace FreeSql.Oracle.Curd { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 999); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(500, 999); - public override List ExecuteInserted() => base.SplitExecuteInserted(500, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override string ToSql() diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index 57f85150..3cb65446 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.Oracle.Curd { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override List RawExecuteUpdated() diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index af39699c..1fbb4892 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -29,9 +29,9 @@ namespace FreeSql.PostgreSQL.Curd internal Dictionary InternalIgnore => _ignore; internal void InternalClearData() => ClearData(); - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override long RawExecuteIdentity() { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index e2d85ce9..23c53f3e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -26,8 +26,8 @@ namespace FreeSql.PostgreSQL.Curd internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); protected override List RawExecuteUpdated() { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index a8432057..df48b84a 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -18,9 +18,9 @@ namespace FreeSql.SqlServer.Curd { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(1000, 2100); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(1000, 2100); - public override List ExecuteInserted() => base.SplitExecuteInserted(1000, 2100); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override string ToSql() { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index e16c5dec..a8ac9031 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.SqlServer.Curd { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 2100); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(500, 2100); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); protected override List RawExecuteUpdated() diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index dd03e1e7..b0209b36 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -16,9 +16,9 @@ namespace FreeSql.Sqlite.Curd { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 999); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 999); - public override List ExecuteInserted() => base.SplitExecuteInserted(5000, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override long RawExecuteIdentity() { diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index 92e9bdc2..c5379695 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -18,8 +18,8 @@ namespace FreeSql.Sqlite.Curd { } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(200, 999); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(200, 999); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override List RawExecuteUpdated() From c268970c7185596253c4a8049607cfde30789ee9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Dec 2019 21:53:44 +0800 Subject: [PATCH 0355/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IInsert.ToDa?= =?UTF-8?q?taTable=20=E6=96=B9=E6=B3=95=EF=BC=8C=E4=B8=BA=20BulkCopy=20?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=8F=90=E4=BE=9B=E6=95=B0=E6=8D=AE=EF=BC=8C?= =?UTF-8?q?=E8=AF=A5=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86=E4=BA=86(?= =?UTF-8?q?=E8=A1=A8=E5=90=8D=E3=80=81=E5=AD=97=E6=AE=B5=E5=90=8D=E3=80=81?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=EF=BC=89=E6=98=A0=E5=B0=84=E5=92=8C=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E5=88=97=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql/FreeSql.xml | 131 ++++++++++++++++++ FreeSql/Interface/Curd/IInsert.cs | 10 ++ .../Internal/CommonProvider/InsertProvider.cs | 25 ++++ 4 files changed, 173 insertions(+) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 76a0f62e..9033ba51 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2178,6 +2178,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 }) + + + + + + 可自定义解析表达式 diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 74a77ca5..77ddd620 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading.Tasks; @@ -115,6 +116,15 @@ namespace FreeSql /// List ExecuteInserted(); + /// + /// 返回 DataTable 以便做 BulkCopy 数据做准备 + /// 此方法会处理: + /// 类型、表名、字段名映射 + /// IgnoreColumns、InsertColumns + /// + /// + DataTable ToDataTable(); + #if net40 #else Task ExecuteAffrowsAsync(); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index a606b4d3..d634ad30 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -464,6 +464,31 @@ namespace FreeSql.Internal.CommonProvider _params = specialParams.ToArray(); return sb.ToString(); } + + public DataTable ToDataTable() + { + var dt = new DataTable(); + dt.TableName = TableRuleInvoke(); + foreach (var col in _table.ColumnsByPosition) + { + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + dt.Columns.Add(col.Attribute.Name, col.Attribute.MapType); + } + foreach (var d in _source) + { + var row = new object[dt.Columns.Count]; + var rowIndex = 0; + foreach (var col in _table.ColumnsByPosition) + { + if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + row[rowIndex++] = col.GetMapValue(d); + } + dt.Rows.Add(row); + } + return dt; + } } } From c335eab82c38b70820f33ea68471d292e62c323c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Dec 2019 14:43:24 +0800 Subject: [PATCH 0356/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IInsert.Exec?= =?UTF-8?q?uteSqlBulkCopy=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=20SqlBulkCopy=20=E6=89=B9=E9=87=8F=E6=8F=92=E5=85=A5?= =?UTF-8?q?=EF=BC=8C=E5=9C=A8=20FreeSql.Provider.SqlServer=20=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 9 ++ .../Internal/CommonProvider/InsertProvider.cs | 17 +++- .../Curd/SqlServerInsert.cs | 5 ++ .../SqlServerExtensions.cs | 84 +++++++++++++++++++ 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9033ba51..5a5f4b82 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -910,6 +910,15 @@ + + + 返回 DataTable 以便做 BulkCopy 数据做准备 + 此方法会处理: + 类型、表名、字段名映射 + IgnoreColumns、InsertColumns + + + 自动产生 as1, as2, as3 .... 字段别名 diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index d634ad30..296dac53 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -1,4 +1,5 @@ using FreeSql.Internal.Model; +using FreeSql.Extensions.EntityUtil; using SafeObjectPool; using System; using System.Collections.Generic; @@ -136,8 +137,20 @@ namespace FreeSql.Internal.CommonProvider foreach (var col in table.Columns.Values) { object val = col.GetMapValue(data); - if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) - col.SetMapValue(data, val = FreeUtil.NewMongodbId()); + if (col.Attribute.IsPrimary) + { + if (col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) + col.SetMapValue(data, val = FreeUtil.NewMongodbId()); + else if (col.CsType.NullableTypeOrThis() == typeof(Guid)) + { + var guidVal = orm.GetEntityValueWithPropertyName(table.Type, data, col.CsName); + if (guidVal == null || (Guid)guidVal == Guid.Empty) + { + orm.SetEntityValueWithPropertyName(table.Type, data, col.CsName, FreeUtil.NewMongodbId()); + val = col.GetMapValue(data); + } + } + } if (orm.Aop.AuditValue != null) { var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index df48b84a..f70d791e 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -18,6 +19,10 @@ namespace FreeSql.SqlServer.Curd { } + internal IFreeSql InternalOrm => _orm as IFreeSql; + internal SqlConnection InternalConnection => _connection as SqlConnection; + internal SqlTransaction InternalTransaction => _transaction as SqlTransaction; + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index ab503d90..38cb29d5 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Data.SqlClient; public static partial class FreeSqlSqlServerGlobalExtensions { @@ -40,6 +41,89 @@ public static partial class FreeSqlSqlServerGlobalExtensions return that; } internal static ConcurrentDictionary)> _dicSetGlobalSelectWithLock = new ConcurrentDictionary)>(); + + /// + /// SqlServer SqlCopyBulk 批量插入功能 + /// 使用 IgnoreColumns/InsertColumns 设置忽略/指定导入的列 + /// 使用 WithConnection/WithTransaction 传入连接/事务对象 + /// 提示:若本方法不能满足,请使用 IInsert<T>.ToDataTable 方法得到 DataTable 对象后,自行处理。 + /// SqlCopyBulk 与 insert into t values(..),(..),(..) 性能测试参考: + /// 插入180000行,52列:21,065ms 与 402,355ms,10列:4,248ms 与 47,204ms + /// 插入10000行,52列:578ms 与 24,847ms,10列:127ms 与 2,275ms + /// 插入5000行,52列:326ms 与 11,465ms,10列:71ms 与 1,108ms + /// 插入2000行,52列:139ms 与 4,971ms,10列:30ms 与 488ms + /// 插入1000行,52列:105ms 与 2,437ms,10列:48ms 与 279ms + /// 插入500行,52列:79ms 与 915ms,10列:14ms 与 123ms + /// 插入100行,52列:60ms 与 138ms,10列:11ms 与 35ms + /// 插入50行,52列:48ms 与 88ms,10列:10ms 与 16ms + /// + /// + /// + /// + /// + /// + public static void ExecuteSqlBulkCopy(this IInsert that, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? batchSize = null, int? bulkCopyTimeout = null) where T : class + { + var insert = that as FreeSql.SqlServer.Curd.SqlServerInsert; + if (insert == null) throw new Exception("ExecuteSqlBulkCopy 是 FreeSql.Provider.SqlServer 特有的功能"); + + var dt = that.ToDataTable(); + if (dt.Rows.Count == 0) return; + + Action writeToServer = bulkCopy => + { + if (batchSize.HasValue) bulkCopy.BatchSize = batchSize.Value; + if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; + bulkCopy.DestinationTableName = dt.TableName; + bulkCopy.WriteToServer(dt); + }; + + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(conn.Value as SqlConnection) : + new SqlBulkCopy(conn.Value as SqlConnection, copyOptions, null)) + { + writeToServer(bulkCopy); + } + } + } + else if (insert.InternalTransaction != null) + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(insert.InternalTransaction.Connection) : + new SqlBulkCopy(insert.InternalTransaction.Connection, copyOptions, insert.InternalTransaction)) + { + writeToServer(bulkCopy); + } + } + else if (insert.InternalConnection != null) + { + var conn = insert.InternalConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + conn.Open(); + } + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(insert.InternalConnection) : + new SqlBulkCopy(insert.InternalConnection, copyOptions, null)) + { + writeToServer(bulkCopy); + } + if (isNotOpen) + { + conn.Close(); + } + } + else + { + throw new NotImplementedException("未实现错误,请反馈给作者"); + } + } } [Flags] From 834bdea11f7670e1bea6a602b8ed17ab549dd6c0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Dec 2019 16:44:31 +0800 Subject: [PATCH 0357/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IInsert.Exec?= =?UTF-8?q?utePgCopy=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=20PostgreSQL=20Copy=20=E6=89=B9=E9=87=8F=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=EF=BC=8C=E5=9C=A8=20FreeSql.Provider.PostgreSQL=20?= =?UTF-8?q?=E5=8F=AF=E7=94=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/CommonProvider/InsertProvider.cs | 1 + .../PostgreSQLExtensions.cs | 90 +++++++++++++++++++ .../Curd/SqlServerInsert.cs | 5 +- .../SqlServerExtensions.cs | 77 +++++++++------- 4 files changed, 137 insertions(+), 36 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 296dac53..a501c9c1 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -488,6 +488,7 @@ namespace FreeSql.Internal.CommonProvider if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; dt.Columns.Add(col.Attribute.Name, col.Attribute.MapType); } + if (dt.Columns.Count == 0) return dt; foreach (var d in _source) { var row = new object[dt.Columns.Count]; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs index 5528b09c..dd5aa832 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs @@ -1,7 +1,10 @@ using FreeSql; using FreeSql.PostgreSQL.Curd; +using Npgsql; using System; +using System.Data; using System.Linq.Expressions; +using System.Text; public static partial class FreeSqlPostgreSQLGlobalExtensions { @@ -24,4 +27,91 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions /// 默认是以主键作为重复判断,也可以指定其他列:a => a.Name | a => new{a.Name,a.Time} | a => new[]{"name","time"} /// public static OnConflictDoUpdate OnConflictDoUpdate(this IInsert that, Expression> columns = null) where T1 : class => new FreeSql.PostgreSQL.Curd.OnConflictDoUpdate(that.InsertIdentity(), columns); + + /// + /// PostgreSQL COPY 批量导入功能,封装了 NpgsqlConnection.BeginBinaryImport 方法 + /// 使用 IgnoreColumns/InsertColumns 设置忽略/指定导入的列 + /// 使用 WithConnection/WithTransaction 传入连接/事务对象 + /// 提示:若本方法不能满足,请使用 IInsert<T>.ToDataTable 方法得到 DataTable 对象后,自行处理。 + /// COPY 与 insert into t values(..),(..),(..) 性能测试参考: + /// 插入180000行,52列:10,090ms 与 46,756ms,10列:4,081ms 与 9,786ms + /// 插入10000行,52列:583ms 与 3,294ms,10列:167ms 与 568ms + /// 插入5000行,52列:337ms 与 2,269ms,10列:93ms 与 366ms + /// 插入2000行,52列:136ms 与 1,019ms,10列:39ms 与 157ms + /// 插入1000行,52列:88ms 与 374ms,10列:21ms 与 102ms + /// 插入500行,52列:61ms 与 209ms,10列:12ms 与 34ms + /// 插入100行,52列:30ms 与 51ms,10列:4ms 与 9ms + /// 插入50行,52列:25ms 与 37ms,10列:2ms 与 6ms + /// + /// + /// + public static void ExecutePgCopy(this IInsert that) where T : class + { + var insert = that as FreeSql.PostgreSQL.Curd.PostgreSQLInsert; + if (insert == null) throw new Exception("ExecuteSqlBulkCopy 是 FreeSql.Provider.PostgreSQL 特有的功能"); + + var dt = that.ToDataTable(); + if (dt.Rows.Count == 0) return; + + Action binaryImport = conn => + { + var copyFromCommand = new StringBuilder().Append("COPY ").Append(insert.InternalCommonUtils.QuoteSqlName(dt.TableName)).Append("("); + var colIndex = 0; + foreach (DataColumn col in dt.Columns) + { + if (colIndex++ > 0) copyFromCommand.Append(", "); + copyFromCommand.Append(insert.InternalCommonUtils.QuoteSqlName(col.ColumnName)); + } + copyFromCommand.Append(") FROM STDIN BINARY"); + using (var writer = conn.BeginBinaryImport(copyFromCommand.ToString())) + { + foreach (DataRow item in dt.Rows) + writer.WriteRow(item.ItemArray); + writer.Complete(); + } + copyFromCommand.Clear(); + }; + + try + { + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + binaryImport(conn.Value as NpgsqlConnection); + } + } + else if (insert.InternalTransaction != null) + { + binaryImport(insert.InternalTransaction.Connection as NpgsqlConnection); + } + else if (insert.InternalConnection != null) + { + var conn = insert.InternalConnection as NpgsqlConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + conn.Open(); + } + try + { + binaryImport(conn); + } + finally + { + if (isNotOpen) + conn.Close(); + } + } + else + { + throw new NotImplementedException("ExecuteCopy 未实现错误,请反馈给作者"); + } + } + finally + { + dt.Clear(); + } + } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index f70d791e..58c74bc1 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -20,8 +19,8 @@ namespace FreeSql.SqlServer.Curd } internal IFreeSql InternalOrm => _orm as IFreeSql; - internal SqlConnection InternalConnection => _connection as SqlConnection; - internal SqlTransaction InternalTransaction => _transaction as SqlTransaction; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 38cb29d5..cea0b092 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -78,50 +78,61 @@ public static partial class FreeSqlSqlServerGlobalExtensions bulkCopy.WriteToServer(dt); }; - if (insert.InternalConnection == null && insert.InternalTransaction == null) + try { - using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(conn.Value as SqlConnection) : + new SqlBulkCopy(conn.Value as SqlConnection, copyOptions, null)) + { + writeToServer(bulkCopy); + } + } + } + else if (insert.InternalTransaction != null) { using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? - new SqlBulkCopy(conn.Value as SqlConnection) : - new SqlBulkCopy(conn.Value as SqlConnection, copyOptions, null)) + new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection) : + new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection, copyOptions, insert.InternalTransaction as SqlTransaction)) { writeToServer(bulkCopy); } } - } - else if (insert.InternalTransaction != null) - { - using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? - new SqlBulkCopy(insert.InternalTransaction.Connection) : - new SqlBulkCopy(insert.InternalTransaction.Connection, copyOptions, insert.InternalTransaction)) + else if (insert.InternalConnection != null) { - writeToServer(bulkCopy); + var conn = insert.InternalConnection as SqlConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + conn.Open(); + } + try + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(conn) : + new SqlBulkCopy(conn, copyOptions, null)) + { + writeToServer(bulkCopy); + } + } + finally + { + if (isNotOpen) + conn.Close(); + } + } + else + { + throw new NotImplementedException("ExecuteSqlBulkCopy 未实现错误,请反馈给作者"); } } - else if (insert.InternalConnection != null) + finally { - var conn = insert.InternalConnection; - var isNotOpen = false; - if (conn.State != System.Data.ConnectionState.Open) - { - isNotOpen = true; - conn.Open(); - } - using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? - new SqlBulkCopy(insert.InternalConnection) : - new SqlBulkCopy(insert.InternalConnection, copyOptions, null)) - { - writeToServer(bulkCopy); - } - if (isNotOpen) - { - conn.Close(); - } - } - else - { - throw new NotImplementedException("未实现错误,请反馈给作者"); + dt.Clear(); } } } From 01c0fbf4f2638b15aafea8b5e392d41dab5252d2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Dec 2019 19:28:56 +0800 Subject: [PATCH 0358/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ExecutePgCop?= =?UTF-8?q?yAsync/ExecuteSqlBulkCopyAsync=20=E5=BC=82=E6=AD=A5=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 -- .../FreeSql.Provider.PostgreSQL.csproj | 4 + .../PostgreSQLExtensions.cs | 79 ++++++++++++++++++- .../SqlServerExtensions.cs | 79 +++++++++++++++++++ 4 files changed, 160 insertions(+), 9 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 3938cc17..9c8fd3ae 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -33,6 +33,10 @@ + + + net45 + diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs index dd5aa832..b2c75baf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs @@ -5,6 +5,7 @@ using System; using System.Data; using System.Linq.Expressions; using System.Text; +using System.Threading.Tasks; public static partial class FreeSqlPostgreSQLGlobalExtensions { @@ -28,6 +29,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions /// public static OnConflictDoUpdate OnConflictDoUpdate(this IInsert that, Expression> columns = null) where T1 : class => new FreeSql.PostgreSQL.Curd.OnConflictDoUpdate(that.InsertIdentity(), columns); + #region ExecutePgCopy /// /// PostgreSQL COPY 批量导入功能,封装了 NpgsqlConnection.BeginBinaryImport 方法 /// 使用 IgnoreColumns/InsertColumns 设置忽略/指定导入的列 @@ -48,7 +50,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions public static void ExecutePgCopy(this IInsert that) where T : class { var insert = that as FreeSql.PostgreSQL.Curd.PostgreSQLInsert; - if (insert == null) throw new Exception("ExecuteSqlBulkCopy 是 FreeSql.Provider.PostgreSQL 特有的功能"); + if (insert == null) throw new Exception("ExecutePgCopy 是 FreeSql.Provider.PostgreSQL 特有的功能"); var dt = that.ToDataTable(); if (dt.Rows.Count == 0) return; @@ -106,7 +108,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions } else { - throw new NotImplementedException("ExecuteCopy 未实现错误,请反馈给作者"); + throw new NotImplementedException("ExecutePgCopy 未实现错误,请反馈给作者"); } } finally @@ -114,4 +116,77 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions dt.Clear(); } } + +#if net45 +#else + async public static Task ExecutePgCopyAsync(this IInsert that) where T : class + { + var insert = that as FreeSql.PostgreSQL.Curd.PostgreSQLInsert; + if (insert == null) throw new Exception("ExecutePgCopyAsync 是 FreeSql.Provider.PostgreSQL 特有的功能"); + + var dt = that.ToDataTable(); + if (dt.Rows.Count == 0) return; + Func binaryImportAsync = async conn => + { + var copyFromCommand = new StringBuilder().Append("COPY ").Append(insert.InternalCommonUtils.QuoteSqlName(dt.TableName)).Append("("); + var colIndex = 0; + foreach (DataColumn col in dt.Columns) + { + if (colIndex++ > 0) copyFromCommand.Append(", "); + copyFromCommand.Append(insert.InternalCommonUtils.QuoteSqlName(col.ColumnName)); + } + copyFromCommand.Append(") FROM STDIN BINARY"); + using (var writer = conn.BeginBinaryImport(copyFromCommand.ToString())) + { + foreach (DataRow item in dt.Rows) + await writer.WriteRowAsync(System.Threading.CancellationToken.None, item.ItemArray); + writer.Complete(); + } + copyFromCommand.Clear(); + }; + + try + { + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = await insert.InternalOrm.Ado.MasterPool.GetAsync()) + { + await binaryImportAsync(conn.Value as NpgsqlConnection); + } + } + else if (insert.InternalTransaction != null) + { + await binaryImportAsync(insert.InternalTransaction.Connection as NpgsqlConnection); + } + else if (insert.InternalConnection != null) + { + var conn = insert.InternalConnection as NpgsqlConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + await conn.OpenAsync(); + } + try + { + await binaryImportAsync(conn); + } + finally + { + if (isNotOpen) + await conn.CloseAsync(); + } + } + else + { + throw new NotImplementedException("ExecutePgCopyAsync 未实现错误,请反馈给作者"); + } + } + finally + { + dt.Clear(); + } + } +#endif + #endregion } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index cea0b092..22ac8e2e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.SqlClient; +using System.Threading.Tasks; public static partial class FreeSqlSqlServerGlobalExtensions { @@ -42,6 +43,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions } internal static ConcurrentDictionary)> _dicSetGlobalSelectWithLock = new ConcurrentDictionary)>(); + #region ExecuteSqlBulkCopy /// /// SqlServer SqlCopyBulk 批量插入功能 /// 使用 IgnoreColumns/InsertColumns 设置忽略/指定导入的列 @@ -135,6 +137,83 @@ public static partial class FreeSqlSqlServerGlobalExtensions dt.Clear(); } } +#if net40 +#else + async public static Task ExecuteSqlBulkCopyAsync(this IInsert that, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? batchSize = null, int? bulkCopyTimeout = null) where T : class + { + var insert = that as FreeSql.SqlServer.Curd.SqlServerInsert; + if (insert == null) throw new Exception("ExecuteSqlBulkCopyAsync 是 FreeSql.Provider.SqlServer 特有的功能"); + + var dt = that.ToDataTable(); + if (dt.Rows.Count == 0) return; + + Func writeToServerAsync = bulkCopy => + { + if (batchSize.HasValue) bulkCopy.BatchSize = batchSize.Value; + if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; + bulkCopy.DestinationTableName = dt.TableName; + return bulkCopy.WriteToServerAsync(dt); + }; + + try + { + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = await insert.InternalOrm.Ado.MasterPool.GetAsync()) + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(conn.Value as SqlConnection) : + new SqlBulkCopy(conn.Value as SqlConnection, copyOptions, null)) + { + await writeToServerAsync(bulkCopy); + } + } + } + else if (insert.InternalTransaction != null) + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection) : + new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection, copyOptions, insert.InternalTransaction as SqlTransaction)) + { + await writeToServerAsync(bulkCopy); + } + } + else if (insert.InternalConnection != null) + { + var conn = insert.InternalConnection as SqlConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + await conn.OpenAsync(); + } + try + { + using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? + new SqlBulkCopy(conn) : + new SqlBulkCopy(conn, copyOptions, null)) + { + await writeToServerAsync(bulkCopy); + } + } + finally + { + if (isNotOpen) + conn.Close(); + } + } + else + { + throw new NotImplementedException("ExecuteSqlBulkCopyAsync 未实现错误,请反馈给作者"); + } + } + finally + { + dt.Clear(); + } + } +#endif + #endregion } [Flags] From f5128f330883ad4dec6e5f98968fc9c0ce699d60 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Dec 2019 20:00:39 +0800 Subject: [PATCH 0359/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelectGroup?= =?UTF-8?q?ing=20=E5=88=86=E7=BB=84=E6=9F=A5=E8=AF=A2=E6=80=BB=E9=87=8F?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E6=B3=95=20.Count()=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 1 + .../Dameng/Curd/DamengSelectTest.cs | 1 + .../Default/Curd/OdbcSelectTest.cs | 1 + .../MySql/Curd/MySqlSelectTest.cs | 1 + .../Oracle/Curd/OracleSelectTest.cs | 1 + .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 1 + .../SqlServer/Curd/SqlServerSelectTest.cs | 1 + .../FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 1 + .../FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs | 1 + .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 1 + .../SqlServer/Curd/SqlServerSelectTest.cs | 1 + .../FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 1 + FreeSql/FreeSql.xml | 13 +++++++++++++ FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs | 13 +++++++++++++ .../SelectProvider/Select0Provider.cs | 2 +- .../SelectProvider/SelectGroupingProvider.cs | 14 ++++++++++++-- 16 files changed, 51 insertions(+), 3 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index c0936140..d2f84e9a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -722,6 +722,7 @@ namespace FreeSql.Tests.MySqlConnector .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index bd34ae44..c318cb2c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -648,6 +648,7 @@ namespace FreeSql.Tests.Odbc.Dameng .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index f5ddd317..3eb5ced3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -639,6 +639,7 @@ namespace FreeSql.Tests.Odbc.Default .OrderBy(a => a.Key.tt2) .OrderByDescending(a => a.Count()) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 55b667ea..d8a227b4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -732,6 +732,7 @@ namespace FreeSql.Tests.Odbc.MySql .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 98e1c28d..40a4862c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -648,6 +648,7 @@ namespace FreeSql.Tests.Odbc.Oracle .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index d1c0da01..e04ee009 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -710,6 +710,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 4b7f5448..dafc6f17 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -604,6 +604,7 @@ namespace FreeSql.Tests.Odbc.SqlServer .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 43db97cc..c76fea46 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -763,6 +763,7 @@ namespace FreeSql.Tests.MySql .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 9eb3b48b..39c678ba 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -648,6 +648,7 @@ namespace FreeSql.Tests.Oracle .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 7ee59d6b..117aa2f8 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -727,6 +727,7 @@ namespace FreeSql.Tests.PostgreSQL .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 8e318e6b..ddcfa963 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -652,6 +652,7 @@ namespace FreeSql.Tests.SqlServer .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 4b243edc..657caa7d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -601,6 +601,7 @@ namespace FreeSql.Tests.Sqlite .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) + .Count(out var trycount) .ToList(a => new { a.Key.tt2, diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5a5f4b82..f20e9ab4 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1776,6 +1776,19 @@ 每页多少 + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + 分组的数据 diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 7cfb0f7e..3ba8b71b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -11,6 +11,7 @@ namespace FreeSql #if net40 #else + Task CountAsync(); Task> ToListAsync(Expression, TReturn>> select); #endif @@ -95,6 +96,18 @@ namespace FreeSql /// 每页多少 /// ISelectGrouping Page(int pageNumber, int pageSize); + + /// + /// 查询的记录数量 + /// + /// + long Count(); + /// + /// 查询的记录数量,以参数out形式返回 + /// + /// 返回的变量 + /// + ISelectGrouping Count(out long count); } public interface ISelectGroupingAggregate diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 238a0285..0a36fad7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1052,7 +1052,7 @@ namespace FreeSql.Internal.CommonProvider _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression, true); this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null); - return new SelectGroupingProvider(this, map, _commonExpression, _tables); + return new SelectGroupingProvider(_orm, this, map, _commonExpression, _tables); } protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 78ac4bcc..e9bd0947 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -11,13 +11,14 @@ namespace FreeSql.Internal.CommonProvider { public class SelectGroupingProvider : ISelectGrouping { - + internal IFreeSql _orm; internal object _select; internal ReadAnonymousTypeInfo _map; internal CommonExpression _comonExp; internal List _tables; - public SelectGroupingProvider(object select, ReadAnonymousTypeInfo map, CommonExpression comonExp, List tables) + public SelectGroupingProvider(IFreeSql orm, object select, ReadAnonymousTypeInfo map, CommonExpression comonExp, List tables) { + _orm = orm; _select = select; _map = map; _comonExp = comonExp; @@ -162,8 +163,17 @@ namespace FreeSql.Internal.CommonProvider return this; } + public long Count() => long.TryParse(string.Concat(_orm.Ado.ExecuteScalar($"select count(1) from ({this.ToSql("1 as1")}) fta")), out var trylng) ? trylng : default(long); + public ISelectGrouping Count(out long count) + { + count = this.Count(); + return this; + } + #if net40 #else + async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync($"select count(1) from ({this.ToSql("1 as1")}) fta")), out var trylng) ? trylng : default(long); + public Task> ToListAsync(Expression, TReturn>> select) { var map = new ReadAnonymousTypeInfo(); From 5b33e2d0629a9068f2da1f04b744a5e0b25bec70 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Dec 2019 20:31:08 +0800 Subject: [PATCH 0360/1029] =?UTF-8?q?-=20=E5=85=BC=E5=AE=B9=20Vb.Net=20?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8=20IncludeMany=20=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B#140?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests.VB/UnitTest1.vb | 37 +++++++++++++++++-- FreeSql.Tests.VB/g.vb | 2 +- .../SelectProvider/Select1Provider.cs | 1 + 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/FreeSql.Tests.VB/UnitTest1.vb b/FreeSql.Tests.VB/UnitTest1.vb index 2a233711..07d82b23 100644 --- a/FreeSql.Tests.VB/UnitTest1.vb +++ b/FreeSql.Tests.VB/UnitTest1.vb @@ -7,13 +7,33 @@ Namespace FreeSql.Tests.VB Sub TestSub() REM VB.net ʽԲ + Dim id As Integer = 100 Dim List1 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = 100).ToList() - Dim List2 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = "xxx").ToList() - Dim List3 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> "xxx").ToList() + Dim List2 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = id).ToList() + Dim List3 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = "xxx").ToList() + Dim title As String = "xxx" + Dim List4 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = title).ToList() + Dim List5 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> "xxx").ToList() + Dim List6 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> title).ToList() - Dim List4 = g.sqlserver.Select(Of Testvb).ToList(Function(a) New With {a, a.Id, a.Title}) + Dim List7 = g.sqlserver.Select(Of Testvb).ToList(Function(a) New With {a, a.Id, a.Title}) + Dim List8 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IsDeleted).ToList() + + + g.sqlserver.Delete(Of Testvb2).Where("1=1").ExecuteAffrows() + g.sqlserver.Delete(Of Testvb).Where("1=1").ExecuteAffrows() + g.sqlserver.Insert(New Testvb With {.Id = 1, .Title = "title1"}).ExecuteAffrows() + g.sqlserver.Insert(New Testvb With {.Id = 2, .Title = "title2"}).ExecuteAffrows() + g.sqlserver.Insert(New Testvb With {.Id = 3, .Title = "title3"}).ExecuteAffrows() + g.sqlserver.Insert(New Testvb2 With {.Id = 1, .TestvbId = 1, .Context = "Context11"}).ExecuteAffrows() + g.sqlserver.Insert(New Testvb2 With {.Id = 2, .TestvbId = 1, .Context = "Context12"}).ExecuteAffrows() + g.sqlserver.Insert(New Testvb2 With {.Id = 3, .TestvbId = 1, .Context = "Context13"}).ExecuteAffrows() + g.sqlserver.Insert(New Testvb2 With {.Id = 4, .TestvbId = 2, .Context = "Context21"}).ExecuteAffrows() + g.sqlserver.Insert(New Testvb2 With {.Id = 5, .TestvbId = 2, .Context = "Context22"}).ExecuteAffrows() + g.sqlserver.Insert(New Testvb2 With {.Id = 6, .TestvbId = 3, .Context = "Context31"}).ExecuteAffrows() + + Dim List9 = g.sqlserver.Select(Of Testvb).IncludeMany(Function(a) a.Testvb2s).ToList() - Dim List5 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IsDeleted).ToList() End Sub End Class @@ -23,4 +43,13 @@ Class Testvb Property Id As Integer Property Title As String Property IsDeleted As Boolean + + Property Testvb2s As List(Of Testvb2) End Class + +Class Testvb2 + Property Id As Integer + Property TestvbId As Integer + Property Testvb As Testvb + Property Context As String +End Class \ No newline at end of file diff --git a/FreeSql.Tests.VB/g.vb b/FreeSql.Tests.VB/g.vb index 7a83db79..da9cc3a1 100644 --- a/FreeSql.Tests.VB/g.vb +++ b/FreeSql.Tests.VB/g.vb @@ -5,7 +5,7 @@ Public Class g Shared sqlserverLazy As Lazy(Of IFreeSql) = New Lazy(Of IFreeSql)(New Func(Of IFreeSql)(Function() New FreeSqlBuilder() _ .UseConnectionString(DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") _ .UseAutoSyncStructure(True) _ - .UseMonitorCommand(Sub(cmd) Trace.WriteLine("\r\n线程" & Thread.CurrentThread.ManagedThreadId & ": " & cmd.CommandText)) _ + .UseMonitorCommand(Sub(cmd) Trace.WriteLine(vbCrLf & "线程" & Thread.CurrentThread.ManagedThreadId & ": " & cmd.CommandText)) _ .UseLazyLoading(True) _ .Build())) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 0187fd1b..cfcffed9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -386,6 +386,7 @@ namespace FreeSql.Internal.CommonProvider var expBody = navigateSelector?.Body; if (expBody == null) return this; + if (expBody.NodeType == ExpressionType.Convert) expBody = (expBody as UnaryExpression)?.Operand; MethodCallExpression whereExp = null; int takeNumber = 0; Expression> selectExp = null; From 1b1f5c12aede26bbac00d5dcf8a1a488879951fd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Dec 2019 20:33:12 +0800 Subject: [PATCH 0361/1029] =?UTF-8?q?-=20=E5=85=BC=E5=AE=B9=20Vb.Net=20?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8=20IncludeMany=20=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/CommonProvider/SelectProvider/Select1Provider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index cfcffed9..46667c86 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -386,7 +386,7 @@ namespace FreeSql.Internal.CommonProvider var expBody = navigateSelector?.Body; if (expBody == null) return this; - if (expBody.NodeType == ExpressionType.Convert) expBody = (expBody as UnaryExpression)?.Operand; + if (expBody.NodeType == ExpressionType.Convert) expBody = (expBody as UnaryExpression)?.Operand; //- 兼容 Vb.Net 无法使用 IncludeMany 的问题; MethodCallExpression whereExp = null; int takeNumber = 0; Expression> selectExp = null; From 43301481938dc775f782a0fc089b9651c1ea9f03 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Dec 2019 21:32:45 +0800 Subject: [PATCH 0362/1029] =?UTF-8?q?-=20=E5=85=BC=E5=AE=B9=20Vb.Net=20?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8=20int=3F=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=20=3D=20=E7=AD=89=E5=8F=B7=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=EF=BC=9B#140?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests.VB/UnitTest1.vb | 5 +++++ FreeSql/Internal/CommonExpression.cs | 1 + 2 files changed, 6 insertions(+) diff --git a/FreeSql.Tests.VB/UnitTest1.vb b/FreeSql.Tests.VB/UnitTest1.vb index 07d82b23..84ab482a 100644 --- a/FreeSql.Tests.VB/UnitTest1.vb +++ b/FreeSql.Tests.VB/UnitTest1.vb @@ -10,6 +10,10 @@ Namespace FreeSql.Tests.VB Dim id As Integer = 100 Dim List1 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = 100).ToList() Dim List2 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = id).ToList() + Dim List11 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = 100).ToList() + Dim List22 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = id).ToList() + Dim idNullable As Integer? = 100 + Dim List222 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = idNullable).ToList() Dim List3 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = "xxx").ToList() Dim title As String = "xxx" Dim List4 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = title).ToList() @@ -43,6 +47,7 @@ Class Testvb Property Id As Integer Property Title As String Property IsDeleted As Boolean + Property IdNullable As Integer? Property Testvb2s As List(Of Testvb2) End Class diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index e715f4e4..ab2373ff 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -559,6 +559,7 @@ namespace FreeSql.Internal case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc); case ExpressionType.TypeAs: case ExpressionType.Convert: + case ExpressionType.ConvertChecked: //var othercExp = ExpressionLambdaToSqlOther(exp, tsc); //if (string.IsNullOrEmpty(othercExp) == false) return othercExp; return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); From a17917e172d86dfb641fc69b42abe335d08be76e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Dec 2019 22:23:19 +0800 Subject: [PATCH 0363/1029] =?UTF-8?q?-=20FreeSql.Generator=20=E4=B8=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9A=84=E9=80=89=E9=A1=B9=EF=BC=8C=E5=8F=8B?= =?UTF-8?q?=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 4 +++- FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 6488856a..c8d9e46d 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -108,7 +108,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -Filter Table+View+StoreProcedure 默认生成:表+视图+存储过程 - 如果不想生成视图和存储过程 -Fitler View+StoreProcedure + 如果不想生成视图和存储过程 -Filter View+StoreProcedure -FileName 文件名,默认:{name}.cs @@ -183,6 +183,8 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 setArgsOutput(args[a + 1]); a++; break; + default: + throw new ArgumentException($"错误的参数设置:{args[a]}"); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index 1de7386f..bd719336 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -82,4 +82,9 @@ public class g (cmd, traceLog) => Console.WriteLine(traceLog)) .Build()); public static IFreeSql dameng => damemgLazy.Value; + + //启动神州通用数据库 /etc/init.d/oscardb_OSRDBd start + //SYSDBA 密码 szoscar55 + + } From 35829f9010be761067f339e358dc6e954837f8a6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 22 Dec 2019 01:15:38 +0800 Subject: [PATCH 0364/1029] =?UTF-8?q?-=20FreeSql.Generator=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=98=A0=E5=B0=84=E5=AE=B9=E9=94=99=E5=88=A4=E6=96=AD?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/RazorModel.cs | 28 +++++++++++-------- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++ .../FreeSql.Tests.Provider.Odbc/g.cs | 15 ++++++++++ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 80f7a855..d754ee2f 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -66,19 +66,23 @@ public class RazorModel { if (GetCsName(col.Name) != col.Name) sb.Add("Name = \"" + col.Name + "\""); - var dbinfo = fsql.CodeFirst.GetDbInfo(col.CsType); - if (dbinfo != null && dbinfo.Value.dbtypeFull.Replace("NOT NULL", "").Trim() != col.DbTypeTextFull) - sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); - if (col.IsPrimary) - sb.Add("IsPrimary = true"); - if (col.IsIdentity) - sb.Add("IsIdentity = true"); + if (col.CsType != null) + { + var dbinfo = fsql.CodeFirst.GetDbInfo(col.CsType); + if (dbinfo != null && dbinfo.Value.dbtypeFull.Replace("NOT NULL", "").Trim() != col.DbTypeTextFull) + sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + if (col.IsPrimary) + sb.Add("IsPrimary = true"); + if (col.IsIdentity) + sb.Add("IsIdentity = true"); - if (dbinfo != null && dbinfo.Value.isnullable != col.IsNullable) { - if (col.IsNullable && fsql.DbFirst.GetCsType(col).Contains("?") == false && col.CsType.IsValueType) - sb.Add("IsNullable = true"); - if (col.IsNullable == false && fsql.DbFirst.GetCsType(col).Contains("?") == true) - sb.Add("IsNullable = false"); + if (dbinfo != null && dbinfo.Value.isnullable != col.IsNullable) + { + if (col.IsNullable && fsql.DbFirst.GetCsType(col).Contains("?") == false && col.CsType.IsValueType) + sb.Add("IsNullable = true"); + if (col.IsNullable == false && fsql.DbFirst.GetCsType(col).Contains("?") == true) + sb.Add("IsNullable = false"); + } } if (sb.Any() == false) return null; return "[Column(" + string.Join(", ", sb) + ")]"; diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index bd719336..7ae66c0d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -83,6 +83,21 @@ public class g .Build()); public static IFreeSql dameng => damemgLazy.Value; + + static Lazy gbaseLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") + //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseSyncStructureToUpper(true) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql gbase => gbaseLazy.Value; + //启动神州通用数据库 /etc/init.d/oscardb_OSRDBd start //SYSDBA 密码 szoscar55 From 738eeb81a8f3556cd367184278f285b075aea14c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 22 Dec 2019 03:20:54 +0800 Subject: [PATCH 0365/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=20DbFirst=20=E7=B1=BB=E5=9E=8B=E5=A4=84=E7=90=86?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests.Provider.Odbc/g.cs | 5 +- .../Dameng/OdbcDamengDbFirst.cs | 54 +++++++++++++++++-- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index 7ae66c0d..4bb24a55 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -83,9 +83,9 @@ public class g .Build()); public static IFreeSql dameng => damemgLazy.Value; - + //启动南大通用数据库 oninit -vy static Lazy gbaseLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={GBase ODBC DRIVER (64-bit)};Server=192.168.164.10:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")) .UseAutoSyncStructure(true) .UseLazyLoading(true) @@ -98,6 +98,7 @@ public class g .Build()); public static IFreeSql gbase => gbaseLazy.Value; + //启动神州通用数据库 /etc/init.d/oscardb_OSRDBd start //SYSDBA 密码 szoscar55 diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 3fb77c3f..40b2d1eb 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -52,17 +52,49 @@ namespace FreeSql.Odbc.Dameng case "blob": return OdbcType.VarBinary; case "nvarchar2(255)": return OdbcType.NVarChar; - case "char(36 char)": return OdbcType.Char; + case "char(36)": return OdbcType.Char; } switch (column.DbTypeText.ToLower()) { + case "bit": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(1)"]); + return OdbcType.Bit; + case "smallint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(5)"]); + return OdbcType.SmallInt; + case "byte": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(3)"]); + return OdbcType.TinyInt; + case "tinyint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(3)"]); + return OdbcType.TinyInt; + case "integer": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(11)"]); + return OdbcType.Int; + case "bigint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(21)"]); + return OdbcType.Int; + case "dec": + case "decimal": + case "numeric": case "number": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(10,2)"]); return OdbcType.Decimal; - case "float": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); - return OdbcType.Double; + case "time": case "interval day to second": + case "interval year to month": + case "interval year": + case "interval month": + case "interval day": + case "interval day to hour": + case "interval day to minute": + case "interval hour": + case "interval hour to minute": + case "interval hour to second": + case "interval minute": + case "interval minute to second": + case "interval second": + case "time with time zone": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); return OdbcType.Time; case "date": @@ -72,17 +104,27 @@ namespace FreeSql.Odbc.Dameng _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); return OdbcType.DateTime; case "timestamp with local time zone": + case "timestamp with time zone": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6) with local time zone"]); return OdbcType.DateTime; + case "binary": + case "varbinary": case "blob": + case "image": + case "longvarbinary": + case "bfile": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); return OdbcType.VarBinary; case "nvarchar2": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); return OdbcType.NVarChar; + case "varchar": case "varchar2": + case "text": + case "longvarchar": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); return OdbcType.NVarChar; + case "character": case "char": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); return OdbcType.Char; @@ -101,9 +143,13 @@ namespace FreeSql.Odbc.Dameng case "long raw": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); return OdbcType.VarBinary; + case "real": case "binary_float": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]); return OdbcType.Real; + case "double": + case "float": + case "double precision": case "binary_double": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); return OdbcType.Double; From d5ed1c8a30c5ba6f6304ab1028fb6c93f25d3285 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 22 Dec 2019 20:10:21 +0800 Subject: [PATCH 0366/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E5=9F=BA=E7=B1=BB=E7=9A=84=E5=B1=9E=E6=80=A7=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=8C=E4=BC=98=E5=85=88=E6=8E=92=E5=9C=A8=E6=9C=80?= =?UTF-8?q?=E5=89=8D=E9=9D=A2=EF=BC=9B=20#164=20-=20=E6=95=B4=E7=90=86=20?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E7=B1=BB=20Ctor=20=E6=9C=89=E6=9E=84?= =?UTF-8?q?=E9=80=A0=E5=87=BD=E6=95=B0=E7=9A=84=E6=98=A0=E5=B0=84=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=9B#164=20[wiki](https://github.com/2881099/Free?= =?UTF-8?q?Sql/wiki/%e8%bf%94%e5%9b%9e%e6%95%b0%e6%8d%ae#dto-%E6%98%A0%E5%?= =?UTF-8?q?B0%84%E6%9F%A5%E8%AF%A2)=20-=20=E4=BC=98=E5=8C=96=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E5=B1=9E=E6=80=A7=EF=BC=8C=E6=94=AF=E6=8C=81=20protec?= =?UTF-8?q?ted=20set=20=E5=B1=9E=E6=80=A7=EF=BC=9B#164?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/DependencyInjection.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - .../MySql/Curd/MySqlSelectTest.cs | 17 ++ .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 17 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 20 +- FreeSql/Internal/CommonExpression.cs | 175 ++++++++++-------- .../SelectProvider/Select0Provider.cs | 20 +- .../SelectProvider/Select10Provider.cs | 4 +- .../SelectProvider/Select1Provider.cs | 9 +- .../SelectProvider/Select2Provider.cs | 4 +- .../SelectProvider/Select3Provider.cs | 4 +- .../SelectProvider/Select4Provider.cs | 4 +- .../SelectProvider/Select5Provider.cs | 4 +- .../SelectProvider/Select6Provider.cs | 4 +- .../SelectProvider/Select7Provider.cs | 4 +- .../SelectProvider/Select8Provider.cs | 4 +- .../SelectProvider/Select9Provider.cs | 4 +- .../Internal/Model/ReadAnonymousTypeInfo.cs | 3 +- FreeSql/Internal/UtilsExpressionTree.cs | 95 +++++----- 19 files changed, 226 insertions(+), 175 deletions(-) diff --git a/FreeSql.DbContext/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Extensions/DependencyInjection.cs index ebd575e1..cad5047f 100644 --- a/FreeSql.DbContext/Extensions/DependencyInjection.cs +++ b/FreeSql.DbContext/Extensions/DependencyInjection.cs @@ -15,7 +15,7 @@ namespace FreeSql DbContext ctx = null; try { - var ctor = dbContextType.GetConstructors().FirstOrDefault(); + var ctor = dbContextType. GetConstructors().FirstOrDefault(); var ctorParams = ctor.GetParameters().Select(a => sp.GetService(a.ParameterType)).ToArray(); ctx = Activator.CreateInstance(dbContextType, ctorParams) as DbContext; } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index c76fea46..0cf69bea 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1056,6 +1056,23 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` a.Id, a.Clicks }); + + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2 +FROM (SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks +FROM `tb_topic_1` a) ftb + +UNION ALL + +SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks +FROM `tb_topic_2` a) ftb) a +limit 0,20", select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToSql(a => new + { + a.Id, + a.Clicks + })); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 6ad6d8e6..6a0da303 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -17,11 +17,7 @@ namespace FreeSql.Tests.MySql var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<ı2>(); g.mysql.CodeFirst.SyncStructure<ı2>(); - var item = new ı2 - { - = "Ա", - ʱ = DateTime.Now - }; + var item = ı2.Create("Ա", DateTime.Now); Assert.Equal(1, g.mysql.Insert<ı2>().AppendData(item).ExecuteAffrows()); Assert.NotEqual(Guid.Empty, item.); var item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); @@ -32,12 +28,17 @@ namespace FreeSql.Tests.MySql class ı2 { [Column(IsPrimary = true)] - public Guid { get; set; } + public Guid { get; protected set; } - public string { get; set; } + public string { get; protected set; } [Column(ServerTime = DateTimeKind.Local)] - public DateTime ʱ { get; set; } + public DateTime ʱ { get; protected set; } + + public static ı2 Create(string title, DateTime ctm) + { + return new ı2 { = title, ʱ = ctm }; + } } [Fact] diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 86449244..f04dc599 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -47,21 +47,35 @@ public static partial class FreeSqlGlobalExtensions public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that)); public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that; internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args)); - static ConcurrentDictionary _dicGetDefaultValueFirstConstructorsParameters = new ConcurrentDictionary(); public static object CreateInstanceGetDefaultValue(this Type that) { if (that == null) return null; if (that == typeof(string)) return default(string); if (that.IsArray) return Array.CreateInstance(that, 0); - var ctorParms = _dicGetDefaultValueFirstConstructorsParameters.GetOrAdd(that, tp => tp.GetConstructors().FirstOrDefault()?.GetParameters()); + var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters(); if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, null); return Activator.CreateInstance(that, ctorParms.Select(a => Activator.CreateInstance(a.ParameterType, null)).ToArray()); } + internal static NewExpression InternalNewExpression(this Type that) + { + var ctor = that.InternalGetTypeConstructor0OrFirst(); + return Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Constant(a.ParameterType.CreateInstanceGetDefaultValue(), a.ParameterType))); + } + + static ConcurrentDictionary _dicInternalGetTypeConstructor0OrFirst = new ConcurrentDictionary(); + internal static ConstructorInfo InternalGetTypeConstructor0OrFirst(this Type that, bool isThrow = true) + { + var ret = _dicInternalGetTypeConstructor0OrFirst.GetOrAdd(that, tp => + tp.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null) ?? + tp.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault()); + if (ret == null && isThrow) throw new ArgumentException($"{that.FullName} 类型无方法访问构造函数"); + return ret; + } static ConcurrentDictionary> _dicGetPropertiesDictIgnoreCase = new ConcurrentDictionary>(); public static Dictionary GetPropertiesDictIgnoreCase(this Type that) => that == null ? null : _dicGetPropertiesDictIgnoreCase.GetOrAdd(that, tp => { - var props = that.GetProperties(); + var props = that.GetProperties().GroupBy(p => p.DeclaringType).Reverse().SelectMany(p => p); //将基类的属性位置放在前面 #164 var dict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); foreach (var prop in props) { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index ab2373ff..ec8770fc 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -52,7 +52,8 @@ namespace FreeSql.Internal var constExpValue = constExp.Value?.ToString() ?? "NULL"; if (constExpValue == string.Empty) constExpValue = _common.FormatSql("{0}", ""); parent.DbField = constExpValue; - } else + } + else parent.DbField = _common.FormatSql("{0}", constExp?.Value); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); @@ -82,8 +83,8 @@ namespace FreeSql.Internal var map = new List(); ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString); var tb = parent.Table = map.First().Table.Table; - parent.Consturctor = tb.Type.GetConstructor(new Type[0]); - parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + parent.CsType = tb.Type; + parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst(); parent.IsEntity = true; for (var idx = 0; idx < map.Count; idx++) { @@ -113,10 +114,25 @@ namespace FreeSql.Internal return false; case ExpressionType.MemberInit: var initExp = exp as MemberInitExpression; - parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0]; - parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - - if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) + parent.CsType = initExp.Type; + parent.Consturctor = initExp.NewExpression.Constructor; + if (initExp.NewExpression?.Arguments.Count > 0) + { + //处理构造参数 + for (var a = 0; a < initExp.NewExpression.Arguments.Count; a++) + { + var child = new ReadAnonymousTypeInfo + { + Property = null, + CsName = initExp.NewExpression.Members[a].Name, + CsType = initExp.NewExpression.Arguments[a].Type, + MapType = initExp.NewExpression.Arguments[a].Type + }; + parent.Childs.Add(child); + ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], getSelectGroupingMapString, whereCascadeExpression, false); + } + } + else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) { //dto 映射 var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values; @@ -124,26 +140,26 @@ namespace FreeSql.Internal { foreach (var dtTb in _tables) { - if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) + if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue; + if (trydtocol.Attribute.IsIgnore == true) continue; + + var child = new ReadAnonymousTypeInfo { - var child = new ReadAnonymousTypeInfo - { - Property = dtoProp, - CsName = dtoProp.Name, - CsType = trydtocol.CsType, // dtoProp.PropertyType, - MapType = trydtocol.Attribute.MapType - }; - parent.Childs.Add(child); - if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); - else - { - child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; - field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(" as").Append(++index); - } - break; + Property = dtoProp, + CsName = dtoProp.Name, + CsType = trydtocol.CsType, // dtoProp.PropertyType, + MapType = trydtocol.Attribute.MapType + }; + parent.Childs.Add(child); + if (dtTb.Parameter != null) + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); + else + { + child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; + field.Append(", ").Append(child.DbField); + if (index >= 0) field.Append(" as").Append(++index); } + break; } } } @@ -169,15 +185,27 @@ namespace FreeSql.Internal return true; case ExpressionType.New: var newExp = exp as NewExpression; - parent.Consturctor = newExp.Type.GetConstructors()[0]; - parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments; - if (newExp.Members?.Count > 0) + parent.CsType = newExp.Type; + parent.Consturctor = newExp.Constructor; + if (newExp.Arguments?.Count > 0 && + ( + newExp.Type.IsAnonymousType() || + newExp.Arguments.Any(a => + { + if (a.NodeType != ExpressionType.Constant) return true; + var constVal = (a as ConstantExpression)?.Value; + if (constVal == null) return true; + if (object.Equals(constVal, a.Type.CreateInstanceGetDefaultValue()) == false) return true; + return false; + }) + )) { - for (var a = 0; a < newExp.Members.Count; a++) + //处理构造参数 + for (var a = 0; a < newExp.Arguments.Count; a++) { var child = new ReadAnonymousTypeInfo { - Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), + Property = null, CsName = newExp.Members[a].Name, CsType = newExp.Arguments[a].Type, MapType = newExp.Arguments[a].Type @@ -188,37 +216,37 @@ namespace FreeSql.Internal } else { + parent.IsDefaultCtor = true; //dto 映射 - parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; var dtoProps2 = newExp.Type.GetPropertiesDictIgnoreCase().Values; foreach (var dtoProp in dtoProps2) { foreach (var dtTb in _tables) { - if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol)) + if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue; + if (trydtocol.Attribute.IsIgnore == true) continue; + + var child = new ReadAnonymousTypeInfo { - var child = new ReadAnonymousTypeInfo - { - Property = dtoProp, - CsName = dtoProp.Name, - CsType = trydtocol.CsType, //dtoProp.PropertyType, - MapType = trydtocol.Attribute.MapType - }; - parent.Childs.Add(child); - if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); - else - { - child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; - field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(" as").Append(++index); - } - break; + Property = dtoProp, + CsName = dtoProp.Name, + CsType = trydtocol.CsType, //dtoProp.PropertyType, + MapType = trydtocol.Attribute.MapType + }; + parent.Childs.Add(child); + if (dtTb.Parameter != null) + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); + else + { + child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; + field.Append(", ").Append(child.DbField); + if (index >= 0) field.Append(" as").Append(++index); } + break; } } - if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名相同"); } + if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名相同"); return true; } parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})"; @@ -247,33 +275,30 @@ namespace FreeSql.Internal objval = Utils.GetDataReaderValue(parent.Property.PropertyType, objval); return objval; } - switch (parent.ConsturctorType) + var ctorParmsLength = 0; + object ret; + if (parent.IsDefaultCtor || parent.IsEntity || (ctorParmsLength = parent.Consturctor.GetParameters()?.Length ?? 0) == 0) + ret = parent.CsType?.CreateInstanceGetDefaultValue() ?? parent.Consturctor.Invoke(null); + else { - case ReadAnonymousTypeInfoConsturctorType.Arguments: - var args = new object[parent.Childs.Count]; - for (var a = 0; a < parent.Childs.Count; a++) - { - var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead, null); - if (notRead == false) - args[a] = objval; - } - return parent.Consturctor.Invoke(args); - case ReadAnonymousTypeInfoConsturctorType.Properties: - var ret = parent.Consturctor.Invoke(null); - var isnull = notRead; - for (var b = 0; b < parent.Childs.Count; b++) - { - var prop = parent.Childs[b].Property; - var dbval = parent.IsEntity ? new ReadAnonymousDbValueRef() : null; - var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval); - if (isnull == false && parent.IsEntity && dbval.DbValue == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) - isnull = true; - if (isnull == false && prop.CanWrite) - prop.SetValue(ret, objval, null); - } - return isnull ? null : ret; + var ctorParms = new object[ctorParmsLength]; + for (var c = 0; c < ctorParmsLength; c++) + ctorParms[c] = ReadAnonymous(parent.Childs[c], dr, ref index, notRead, null); + ret = parent.Consturctor.Invoke(ctorParms); } - return null; + + var isnull = notRead; + for (var b = ctorParmsLength; b < parent.Childs.Count; b++) + { + var prop = parent.Childs[b].Property; + var dbval = parent.IsEntity ? new ReadAnonymousDbValueRef() : null; + var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval); + if (isnull == false && parent.IsEntity && dbval.DbValue == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) + isnull = true; + if (isnull == false && prop.CanWrite) + prop.SetValue(ret, objval, null); + } + return isnull ? null : ret; } public class ReadAnonymousDbValueRef { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 0a36fad7..2881b8fb 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -546,7 +546,6 @@ namespace FreeSql.Internal.CommonProvider _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true); return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); } - static ConcurrentDictionary _dicConstructor = new ConcurrentDictionary(); static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); public class GetAllFieldExpressionTreeInfo { @@ -568,9 +567,8 @@ namespace FreeSql.Internal.CommonProvider var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); var blockExp = new List(); - var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))), + Expression.Assign(retExp, type.InternalNewExpression()), Expression.Assign(dataIndexExp, Expression.Constant(0)) }); //typeof(Topic).GetMethod("get_Type").IsVirtual @@ -711,9 +709,8 @@ namespace FreeSql.Internal.CommonProvider var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); var blockExp = new List(); - var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))), + Expression.Assign(retExp, type.InternalNewExpression()), Expression.Assign(dataIndexExp, Expression.Constant(0)) }); //typeof(Topic).GetMethod("get_Type").IsVirtual @@ -762,7 +759,7 @@ namespace FreeSql.Internal.CommonProvider } } //只读到二级属性 - var propGetSetMethod = prop.GetSetMethod(); + var propGetSetMethod = prop.GetSetMethod(true); Expression readExpAssign = null; //加速缓存 if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor, Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)), @@ -836,9 +833,9 @@ namespace FreeSql.Internal.CommonProvider protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() { var tb1 = _tables.First().Table; - var type = tb1.Type; - var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0])); - var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties }; + var type = tb1.TypeLazy ?? tb1.Type; + var constructor = type.InternalGetTypeConstructor0OrFirst(); + var map = new ReadAnonymousTypeInfo { CsType = type, Consturctor = constructor, IsEntity = true }; var field = new StringBuilder(); var dicfield = new Dictionary(); @@ -862,8 +859,9 @@ namespace FreeSql.Internal.CommonProvider var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault(); if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault(); if (tb2 == null) continue; - child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]); - child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + child.CsType = (tb2.Table.TypeLazy ?? tb2.Table.Type); + child.Consturctor = child.CsType.InternalGetTypeConstructor0OrFirst(); + child.IsEntity = true; foreach (var col2 in tb2.Table.Columns.Values) { if (index > 0) field.Append(", "); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index fd73c7c0..4ab36722 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -101,8 +101,8 @@ namespace FreeSql.Internal.CommonProvider List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 46667c86..ea6e9ff6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -172,8 +172,8 @@ namespace FreeSql.Internal.CommonProvider public List ToList() => ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a")); } @@ -884,8 +884,9 @@ namespace FreeSql.Internal.CommonProvider { var field = new StringBuilder(); var read = new ReadAnonymousTypeInfo(); - read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; - read.Consturctor = (tbrefMid.TypeLazy ?? tbrefMid.Type).GetConstructor(new Type[0]); + read.CsType = (tbrefMid.TypeLazy ?? tbrefMid.Type); + read.Consturctor = read.CsType.InternalGetTypeConstructor0OrFirst(); + read.IsEntity = true; read.Table = tbrefMid; foreach (var col in tbrefMid.Columns.Values) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index beaa1d50..d8ed2fe8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -86,8 +86,8 @@ namespace FreeSql.Internal.CommonProvider List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b")); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 5f49d8cf..03cf62e3 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -88,8 +88,8 @@ namespace FreeSql.Internal.CommonProvider List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c")); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 075397f7..e006c78b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -90,8 +90,8 @@ namespace FreeSql.Internal.CommonProvider List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index d21e16a2..76e9ddbc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -92,8 +92,8 @@ namespace FreeSql.Internal.CommonProvider List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 5669598d..81fe63cf 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -94,8 +94,8 @@ namespace FreeSql.Internal.CommonProvider List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index a8f94ac3..f3a953e6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -96,8 +96,8 @@ namespace FreeSql.Internal.CommonProvider List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index f85d2df9..79e5f4af 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -99,8 +99,8 @@ namespace FreeSql.Internal.CommonProvider Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index d03d4ba0..ebc99041 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -99,8 +99,8 @@ namespace FreeSql.Internal.CommonProvider List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { - var ctor = typeof(TDto).GetConstructor(new Type[0]); - return Expression.Lambda>(Expression.New(ctor), + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index 3ca01e00..d252db75 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -13,10 +13,9 @@ namespace FreeSql.Internal.Model public Type MapType { get; set; } public string DbField { get; set; } public ConstructorInfo Consturctor { get; set; } - public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; } public List Childs = new List(); public TableInfo Table { get; set; } public bool IsEntity { get; set; } + public bool IsDefaultCtor { get; set; } } - public enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties } } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c8b1b92f..83002513 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -72,7 +72,7 @@ namespace FreeSql.Internal var columnsList = new List(); foreach (var p in trytb.Properties.Values) { - var setMethod = p.GetSetMethod(); //trytb.Type.GetMethod($"set_{p.Name}"); + var setMethod = p.GetSetMethod(true); //trytb.Type.GetMethod($"set_{p.Name}"); var colattr = common.GetEntityColumnAttribute(entity, p); var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType); if (setMethod == null || (tp == null && p.PropertyType.IsValueType)) // 属性没有 set自动忽略 @@ -1200,7 +1200,7 @@ namespace FreeSql.Internal this.Value = value; this.DataIndex = dataIndex; } - public static ConstructorInfo Constructor = typeof(RowInfo).GetConstructor(new[] { typeof(object), typeof(int) }); + public static ConstructorInfo Constructor = typeof(RowInfo). GetConstructor(new[] { typeof(object), typeof(int) }); public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value"); public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex"); } @@ -1342,14 +1342,15 @@ namespace FreeSql.Internal var readpkvalExp = Expression.Variable(typeof(object), "isnull3val"); var indexesLengthExp = Expression.Variable(typeof(int), "indexesLength"); var blockExp = new List(); - var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); - var ctorParms = ctor.GetParameters(); - if (ctorParms.Length > 0) + var newExp = type.InternalNewExpression(); + if (false && newExp.Arguments.Count > 0) { + #region 按构造参数读取数据,此功能暂时关闭 + /* blockExp.AddRange(new Expression[] { - Expression.Assign(readpknullExp, Expression.Constant(false)) - }); - foreach (var ctorParm in ctorParms) + Expression.Assign(readpknullExp, Expression.Constant(false)) + }); + foreach (var ctorParm in newExp.Constructor.GetParameters()) { if (typetb.ColumnsByCsIgnore.ContainsKey(ctorParm.Name)) continue; var readType = typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) ? trycol.Attribute.MapType : ctorParm.ParameterType; @@ -1419,33 +1420,35 @@ namespace FreeSql.Internal ); blockExp.AddRange(new Expression[] { - Expression.Assign(tryidxExp, dataIndexExp), - readVal, - Expression.Assign(readExp, readExpAssign), - Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex) - ), - Expression.Block(ispkExp) - }); + Expression.Assign(tryidxExp, dataIndexExp), + readVal, + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex) + ), + Expression.Block(ispkExp) + }); } blockExp.Add( Expression.IfThen( Expression.IsFalse(readpknullExp), - Expression.Assign(retExp, Expression.New(ctor, readExpValueParms)) + Expression.Assign(retExp, Expression.New(newExp.Constructor, readExpValueParms)) ) ); + */ + #endregion } else { blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, Expression.New(ctor)), - Expression.Assign(indexesLengthExp, Expression.Constant(0)), - Expression.IfThen( - Expression.NotEqual(indexesExp, Expression.Constant(null)), - Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp)) - ), - Expression.Assign(readpknullExp, Expression.Constant(false)) - }); + Expression.Assign(retExp, newExp), + Expression.Assign(indexesLengthExp, Expression.Constant(0)), + Expression.IfThen( + Expression.NotEqual(indexesExp, Expression.Constant(null)), + Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp)) + ), + Expression.Assign(readpknullExp, Expression.Constant(false)) + }); var props = type.GetPropertiesDictIgnoreCase().Values; var propIndex = 0; @@ -1459,7 +1462,7 @@ namespace FreeSql.Internal var readType = typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) ? trycol.Attribute.MapType : prop.PropertyType; var ispkExp = new List(); - var propGetSetMethod = prop.GetSetMethod(); + var propGetSetMethod = prop.GetSetMethod(true); Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp)); Expression readExpAssign = null; //加速缓存 if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, @@ -1524,30 +1527,30 @@ namespace FreeSql.Internal ) ); blockExp.AddRange(new Expression[] { - //以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值 - Expression.IfThenElse( - Expression.LessThan(Expression.Constant(propIndex), indexesLengthExp), - Expression.Assign(tryidxExp, Expression.ArrayAccess(indexesExp, Expression.Constant(propIndex))), - Expression.Assign(tryidxExp, dataIndexExp) - ), - Expression.IfThen( - Expression.GreaterThanOrEqual(tryidxExp, Expression.Constant(0)), - Expression.Block( - readVal, - Expression.Assign(readExp, readExpAssign), - Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex)), - Expression.Block(ispkExp) + //以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值 + Expression.IfThenElse( + Expression.LessThan(Expression.Constant(propIndex), indexesLengthExp), + Expression.Assign(tryidxExp, Expression.ArrayAccess(indexesExp, Expression.Constant(propIndex))), + Expression.Assign(tryidxExp, dataIndexExp) + ), + Expression.IfThen( + Expression.GreaterThanOrEqual(tryidxExp, Expression.Constant(0)), + Expression.Block( + readVal, + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex)), + Expression.Block(ispkExp) + ) ) - ) - }); + }); ++propIndex; } } blockExp.AddRange(new Expression[] { - Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)), - Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) - }); + Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)), + Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) + }); return Expression.Lambda>( Expression.Block(new[] { retExp, readExp, tryidxExp, readpknullExp, readpkvalExp, readExpsIndex, indexesLengthExp }.Concat(readExpValueParms), blockExp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); }); @@ -1616,7 +1619,7 @@ namespace FreeSql.Internal static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); static PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", BindingFlags.Instance | BindingFlags.Public); static PropertyInfo PropertyDateTimeTicks = typeof(DateTime).GetProperty("Ticks", BindingFlags.Instance | BindingFlags.Public); - static ConstructorInfo CtorDateTimeOffsetArgsTicks = typeof(DateTimeOffset).GetConstructor(new[] { typeof(long), typeof(TimeSpan) }); + static ConstructorInfo CtorDateTimeOffsetArgsTicks = typeof(DateTimeOffset). GetConstructor(new[] { typeof(long), typeof(TimeSpan) }); public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); public static ConcurrentBag> GetDataReaderValueBlockExpressionObjectToStringIfThenElse = new ConcurrentBag>(); From a92c279c724e5b7a6bb5eef201a8e9bbbd78d876 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 24 Dec 2019 06:16:52 +0800 Subject: [PATCH 0367/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Ado.Query=20?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=AD=97=E6=AE=B5=E9=87=8D=E5=A4=8D=E6=97=B6?= =?UTF-8?q?=E6=8A=A5=E9=94=99=EF=BC=9B#162=20#165=20#161=20-=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20FreeSql.Provider.MsAccess=20=E6=94=AF=E6=8C=81=20Ac?= =?UTF-8?q?cess=20=E6=95=B0=E6=8D=AE=E5=BA=93=E6=93=8D=E4=BD=9C=EF=BC=8C?= =?UTF-8?q?=E5=B7=B2=E9=80=9A=E8=BF=87=202003/2007=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.JsonMap.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 77 + .../MySql/Curd/MySqlSelectTest.cs | 77 + .../FreeSql.Tests/FreeSql.Tests.csproj | 1 + .../MsAccess/Curd/MsAccessDeleteTest.cs | 93 + .../MsAccess/Curd/MsAccessInsertTest.cs | 141 ++ .../MsAccess/Curd/MsAccessSelectTest.cs | 1414 +++++++++++++++ .../MsAccess/Curd/MsAccessUpdateTest.cs | 141 ++ .../MsAccess/MapType/BoolNullableTest.cs | 1571 +++++++++++++++++ .../MsAccess/MapType/BoolTest.cs | 1105 ++++++++++++ .../MsAccess/MapType/DateTimeOffSetTest.cs | 54 + .../MsAccess/MapType/EnumTest.cs | 261 +++ .../MsAccess/MapType/ToStringTest.cs | 570 ++++++ .../MsAccess/MsAccessAdo/MsAccessAdoTest.cs | 81 + .../FreeSql.Tests/MsAccess/MsAccessAopTest.cs | 40 + .../MsAccess/MsAccessCodeFirstTest.cs | 307 ++++ .../MsAccessExpression/ConvertTest.cs | 169 ++ .../MsAccessExpression/DateTimeTest.cs | 706 ++++++++ .../MsAccess/MsAccessExpression/MathTest.cs | 156 ++ .../MsAccess/MsAccessExpression/OtherTest.cs | 164 ++ .../MsAccess/MsAccessExpression/StringTest.cs | 728 ++++++++ .../MsAccessExpression/TimeSpanTest.cs | 293 +++ .../MySql/Curd/MySqlSelectTest.cs | 89 +- FreeSql.Tests/FreeSql.Tests/g.cs | 14 + FreeSql.sln | 15 + FreeSql/DataType.cs | 7 +- FreeSql/FreeSql.csproj | 4 +- FreeSql/FreeSql.xml | 140 +- FreeSql/FreeSqlBuilder.cs | 5 + .../Interface/Curd/ISelect/ISelectGrouping.cs | 2 +- FreeSql/Internal/CommonExpression.cs | 28 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 29 +- .../AdoProvider/AdoProviderAsync.cs | 29 +- .../Internal/CommonProvider/InsertProvider.cs | 4 +- .../SelectProvider/Select0Provider.cs | 36 +- .../SelectProvider/Select1Provider.cs | 4 +- .../SelectProvider/SelectGroupingProvider.cs | 8 +- .../Internal/CommonProvider/UpdateProvider.cs | 4 +- FreeSql/Internal/CommonUtils.cs | 2 + FreeSql/Internal/UtilsExpressionTree.cs | 11 +- .../Curd/MsAccessDelete.cs | 109 ++ .../Curd/MsAccessInsert.cs | 183 ++ .../Curd/MsAccessSelect.cs | 194 ++ .../Curd/MsAccessUpdate.cs | 79 + .../FreeSql.Provider.MsAccess.csproj | 38 + .../FreeSqlMsAccessGlobalExtensions.cs | 12 + .../MsAccessAdo/MsAccessAdo.cs | 77 + .../MsAccessAdo/MsAccessConnectionPool.cs | 242 +++ .../MsAccessCodeFirst.cs | 458 +++++ .../MsAccessExpression.cs | 398 +++++ .../MsAccessProvider.cs | 60 + .../MsAccessUtils.cs | 126 ++ .../MySqlAdo/MySqlAdo.cs | 1 - .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 1 - .../Default/OdbcAdo/OdbcAdo.cs | 1 - .../GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs | 1 - .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 1 - .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 1 - .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 1 - .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 1 - .../OracleAdo/OracleAdo.cs | 1 - .../PostgreSQLAdo/PostgreSQLAdo.cs | 1 - .../SqliteAdo/SqliteAdo.cs | 1 - .../SqliteCodeFirst.cs | 3 +- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 2 +- readme.md | 2 +- 69 files changed, 10380 insertions(+), 207 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/TimeSpanTest.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj create mode 100644 Providers/FreeSql.Provider.MsAccess/FreeSqlMsAccessGlobalExtensions.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs create mode 100644 Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 670584e8..64880c4e 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -28,7 +28,7 @@ - + diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 07f35455..2a978474 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -5,7 +5,7 @@ 0.12.21 true YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. 达梦 + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access https://github.com/2881099/FreeSql.DbContext FreeSql ORM DbContext git diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 06e825f9..23dd38fa 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 0.12.21 YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦, and read/write separation、and split table. + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository true diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index d2f84e9a..953f6479 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1014,6 +1014,83 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` a.Id, a.Clicks }); + + var sqltmp12 = g.mysql.Select() + .Where(t => t.IsFinished && (t.AuditorId == "1" || t.AuditorId == "1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3")) + .GroupBy(t => new { t.ProcessId, t.NodeId, t.NodeName }) + .ToSql(t => new WF_TaskGroupBy + { + TaskId = t.Max(t.Value.Id), + TaskType = t.Max(t.Value.Type), + ProcessId = t.Key.ProcessId, + NodeId = t.Key.NodeId, + NodeName = t.Key.NodeName + }, FieldAliasOptions.AsProperty); + + var groupsql12 = g.mysql.Select() + .AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null) + .LeftJoin((a, p) => p.Id == a.ProcessId) + .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) + .ToSql((a, p) => new + { + WF_Task = a, + WF_ProcessInstance = p + }); + + Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName +FROM `WF_Task` a +WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) +GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName`", sqltmp12); + Assert.Equal(@"SELECT a.`TaskId` as1, a.`TaskType` as2, a.`ProcessId` as3, a.`NodeId` as4, a.`NodeName` as5, b.`Id` as6, b.`TaskType` as7, b.`ProcessId` as8, b.`NodeId` as9, b.`CreateTime` as10, b.`IsFinished` as11, b.`EnabledMark` as12 +FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName + FROM `WF_Task` a + WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) + GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a +LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId` +WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12); + + var grouplist12 = g.mysql.Select() + .AsTable((type, old) => $"( {sqltmp12} )") + .LeftJoin((a, p) => p.Id == a.ProcessId) + .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) + .ToList((a, p) => new + { + WF_Task = a, + WF_ProcessInstance = p + }); + } + + [Table(DisableSyncStructure = true)] + class WF_TaskGroupBy + { + public int TaskId { get; set; } + public int TaskType { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public string NodeName { get; set; } + } + class WF_Task + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int Type { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public string NodeName { get; set; } + public string AuditorId { get; set; } + public DateTime CreateTime { get; set; } + public bool IsFinished { get; set; } + } + class WF_ProcessInstance + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int TaskType { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public DateTime CreateTime { get; set; } + public bool IsFinished { get; set; } + public bool EnabledMark { get; set; } } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index d8a227b4..78f2f6e3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1025,6 +1025,83 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` a.Id, a.Clicks }); + + var sqltmp12 = g.mysql.Select() + .Where(t => t.IsFinished && (t.AuditorId == "1" || t.AuditorId == "1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3")) + .GroupBy(t => new { t.ProcessId, t.NodeId, t.NodeName }) + .ToSql(t => new WF_TaskGroupBy + { + TaskId = t.Max(t.Value.Id), + TaskType = t.Max(t.Value.Type), + ProcessId = t.Key.ProcessId, + NodeId = t.Key.NodeId, + NodeName = t.Key.NodeName + }, FieldAliasOptions.AsProperty); + + var groupsql12 = g.mysql.Select() + .AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null) + .LeftJoin((a, p) => p.Id == a.ProcessId) + .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) + .ToSql((a, p) => new + { + WF_Task = a, + WF_ProcessInstance = p + }); + + Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName +FROM `WF_Task` a +WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) +GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName`", sqltmp12); + Assert.Equal(@"SELECT a.`TaskId` as1, a.`TaskType` as2, a.`ProcessId` as3, a.`NodeId` as4, a.`NodeName` as5, b.`Id` as6, b.`TaskType` as7, b.`ProcessId` as8, b.`NodeId` as9, b.`CreateTime` as10, b.`IsFinished` as11, b.`EnabledMark` as12 +FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName + FROM `WF_Task` a + WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) + GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a +LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId` +WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12); + + var grouplist12 = g.mysql.Select() + .AsTable((type, old) => $"( {sqltmp12} )") + .LeftJoin((a, p) => p.Id == a.ProcessId) + .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) + .ToList((a, p) => new + { + WF_Task = a, + WF_ProcessInstance = p + }); + } + + [Table(DisableSyncStructure = true)] + class WF_TaskGroupBy + { + public int TaskId { get; set; } + public int TaskType { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public string NodeName { get; set; } + } + class WF_Task + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int Type { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public string NodeName { get; set; } + public string AuditorId { get; set; } + public DateTime CreateTime { get; set; } + public bool IsFinished { get; set; } + } + class WF_ProcessInstance + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int TaskType { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public DateTime CreateTime { get; set; } + public bool IsFinished { get; set; } + public bool EnabledMark { get; set; } } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 16afde1b..5d7edd8a 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -31,6 +31,7 @@ + diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs new file mode 100644 index 00000000..8155d317 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs @@ -0,0 +1,93 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccess +{ + public class MsAccessDeleteTest + { + + IDelete delete => g.msaccess.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.msaccess.Delete().ToSql()); + var sql = g.msaccess.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.msaccess.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.msaccess.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.msaccess.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.msaccess.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //var item = g.msaccess.Delete(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.msaccess.Delete().AsTable(a => "TopicAsTable").ToSql()); + var sql = g.msaccess.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.msaccess.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] = 1)", sql); + + sql = g.msaccess.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + + sql = g.msaccess.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs new file mode 100644 index 00000000..c2e44197 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccess +{ + public class MsAccessInsertTest + { + IInsert insert => g.msaccess.Insert(); //�������� + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 20:09:37") }); + + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(0, 'newtitle0', '2019-09-19 20:09:37')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(0, 'newtitle0', '2019-09-19 20:09:37'), (100, 'newtitle1', '2019-09-19 20:09:37'), (200, 'newtitle2', '2019-09-19 20:09:37'), (300, 'newtitle3', '2019-09-19 20:09:37'), (400, 'newtitle4', '2019-09-19 20:09:37'), (500, 'newtitle5', '2019-09-19 20:09:37'), (600, 'newtitle6', '2019-09-19 20:09:37'), (700, 'newtitle7', '2019-09-19 20:09:37'), (800, 'newtitle8', '2019-09-19 20:09:37'), (900, 'newtitle9', '2019-09-19 20:09:37')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var sql = insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.msaccess.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 32; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.msaccess.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(32, itemsIgnore.Count); + Assert.Equal(32, g.msaccess.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.msaccess.Insert(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + + + //items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //var lastId = g.sqlite.Select().Max(a => a.Id); + //Assert.NotEqual(lastId, g.msaccess.Insert(items).ExecuteIdentity()); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 20:01:51") }); + + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(0, 'newtitle0', '2019-09-19 20:01:51')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(0, 'newtitle0', '2019-09-19 20:01:51'), (100, 'newtitle1', '2019-09-19 20:01:51'), (200, 'newtitle2', '2019-09-19 20:01:51'), (300, 'newtitle3', '2019-09-19 20:01:51'), (400, 'newtitle4', '2019-09-19 20:01:51'), (500, 'newtitle5', '2019-09-19 20:01:51'), (600, 'newtitle6', '2019-09-19 20:01:51'), (700, 'newtitle7', '2019-09-19 20:01:51'), (800, 'newtitle8', '2019-09-19 20:01:51'), (900, 'newtitle9', '2019-09-19 20:01:51')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.Title, a.TypeGuid }).InsertColumns(a => a.Title).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.Title, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs new file mode 100644 index 00000000..d968da49 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -0,0 +1,1414 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccess +{ + public class MsAccessSelectTest + { + ISelect select => g.msaccess.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.msaccess.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 + //FROM [Tag] a + //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] + //LEFT JOIN [Tag] a__Parent__Parent ON a__Parent__Parent.[Id] = a__Parent.[Parent_id] + //WHERE (a__Parent__Parent.[Name] = '粤语') + + //OneToMany + var t1 = g.msaccess.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] + //FROM [Tag] a + //WHERE (exists(SELECT 1 + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) + + //ManyToMany + var t2 = g.msaccess.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] + //FROM [Song] a + //WHERE(exists(SELECT 1 + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.msaccess.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.msaccess.Select().Limit(10).ToList(); + + + } + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, g.msaccess.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, g.msaccess.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //; + //Assert.Equal(9989, g.msaccess.Insert(items).NoneParameter().ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, now()"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + g.msaccess.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.msaccess.Select().ToList(); + var testGuidId6 = g.msaccess.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON (a.[TypeGuid] = b.[Guid])", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a LEFT JOIN [TestTypeInfo] b ON (a.[TypeGuid] = b.[Guid])) LEFT JOIN [TestTypeParentInfo] c ON (b.[ParentId] = c.[Id])", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx')", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx')) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx')", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM (([tb_topic22] a LEFT JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx')) LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId])", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfo] c ON (c.[Id] = a__Type.[ParentId])", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a LEFT JOIN [TestTypeInfo] b ON (a.[TypeGuid] = b.[Guid])) LEFT JOIN [TestTypeParentInfo] c ON (b.[ParentId] = c.[Id])", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.LeftJoin("TestTypeInfo b on (b.Guid = a.TypeGuid and b.Name = ?)", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on (b.Guid = a.TypeGuid and b.Name = ?)", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx')", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx')) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx')", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM (([tb_topic22] a INNER JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx')) LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) INNER JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId])", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) INNER JOIN [TestTypeParentInfo] c ON (c.[Id] = a__Type.[ParentId])", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a INNER JOIN [TestTypeInfo] b ON (a.[TypeGuid] = b.[Guid])) INNER JOIN [TestTypeParentInfo] c ON (b.[ParentId] = c.[Id])", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.InnerJoin("TestTypeInfo b on (b.Guid = a.TypeGuid and b.Name = ?)", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on (b.Guid = a.TypeGuid and b.Name = ?)", sql); + query.ToList(); + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx')", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx')) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx')", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM (([tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx')) LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId])", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) RIGHT JOIN [TestTypeParentInfo] c ON (c.[Id] = a__Type.[ParentId])", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON (a.[TypeGuid] = b.[Guid])) RIGHT JOIN [TestTypeParentInfo] c ON (b.[ParentId] = c.[Id])", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + query = select.RightJoin("TestTypeInfo b on (b.Guid = a.TypeGuid and b.Name = ?)", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on (b.Guid = a.TypeGuid and b.Name = ?)", sql); + query.ToList(); + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid]) WHERE (a__Type.[Name] = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid]) WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Name] = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = 'typeTitle' AND b.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = ?)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE ((a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid]) WHERE (a__Type.[Name] = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid]) WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Name] = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = ?)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.clicks > 100 and a.id = ?", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.msaccess.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.msaccess.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(Convert.ToInt64(a.Key.Id)), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 sum(b.[Id]) + FROM [tb_topic22] b) as as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 min(b.[Id]) + FROM [tb_topic22] b) as as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 max(b.[Id]) + FROM [tb_topic22] b) as as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 avg(b.[Id]) + FROM [tb_topic22] b) as as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] +FROM [tb_topic22] a +WHERE (((cstr(a.[Id])) in (SELECT b.[Title] + FROM [tb_topic22] b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic22 where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON (a__Type.[Guid] = a.[TypeGuid])", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON (a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx')", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON (a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = 'xxx')) LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Id] = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON (b.[Guid] = a.[TypeGuid])", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx')", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM (([tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON (b.[Guid] = a.[TypeGuid] AND b.[Name] = 'xxx')) LEFT JOIN [TestTypeInfoAsTable2] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId]) WHERE (a__Type__Parent.[Id] = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON (a__Type__Parent.[Id] = a__Type.[ParentId])", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM (([tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON (a__Type.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeInfoAsTable2] b ON (b.[Guid] = a.[TypeGuid])) LEFT JOIN [TestTypeParentInfoAsTable] c ON (c.[Id] = a__Type.[ParentId])", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM ([tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON (a.[TypeGuid] = b.[Guid])) LEFT JOIN [TestTypeParentInfoAsTable] c ON (b.[ParentId] = c.[Id])", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on (b.Guid = a.TypeGuid and b.Name = @bname)", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on (b.Guid = a.TypeGuid and b.Name = @bname)", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.msaccess.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.msaccess.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.msaccess.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.msaccess.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.msaccess.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.msaccess.Insert(model4s).ExecuteAffrows()); + + var t0 = g.msaccess.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.msaccess.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.msaccess.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.msaccess.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.msaccess.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.msaccess.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() }; + model2.id = (int)g.msaccess.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.msaccess.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.msaccess.Insert(model1).ExecuteIdentity(); + + var t1 = g.msaccess.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.msaccess.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.msaccess.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.msaccess.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.msaccess.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.msaccess.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.msaccess.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.msaccess.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.msaccess.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.msaccess.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.msaccess.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.msaccess.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.msaccess.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.msaccess.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.msaccess.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.msaccess.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.msaccess.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.msaccess.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.msaccess.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.msaccess.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.msaccess.Insert(song3).ExecuteIdentity(); + + g.msaccess.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.msaccess.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.msaccess.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.msaccess.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.msaccess.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.msaccess.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.msaccess.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.msaccess.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.msaccess.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.msaccess.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.msaccess.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.msaccess.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.msaccess.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.msaccess.Select().Count()); + g.msaccess.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.msaccess.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.msaccess.Select().Count()); + Assert.Equal(3, g.msaccess.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.msaccess.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.msaccess.Select().Count()); + g.msaccess.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.msaccess.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.msaccess.Select().Count()); + Assert.Equal(3, g.msaccess.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.msaccess.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.msaccess.Select().Count()); + g.msaccess.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.msaccess.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.msaccess.Select().Count()); + Assert.Equal(3, g.msaccess.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.msaccess.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.msaccess.Select().Count()); + g.msaccess.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.msaccess.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.msaccess.Select().Count()); + Assert.Equal(5, g.msaccess.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.msaccess.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.msaccess.Select().Count()); + g.msaccess.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.msaccess.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.msaccess.Select().Count()); + Assert.Equal(5, g.msaccess.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.msaccess.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.msaccess.Select().Count()); + g.msaccess.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.msaccess.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.msaccess.Select().Count()); + Assert.Equal(5, g.msaccess.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.msaccess; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs new file mode 100644 index 00000000..804f570e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccess +{ + public class MsAccessUpdateTest + { + IUpdate update => g.msaccess.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.msaccess.Update().ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.msaccess.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.msaccess.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.msaccess.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.msaccess.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL, [Title] = 'newtitle', [CreateTime] = '1970-01-01 00:00:00' WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, [Title] = CASE [Id] WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, [CreateTime] = CASE [Id] WHEN 1 THEN '1970-01-01 00:00:00' WHEN 2 THEN '1970-01-01 00:00:00' WHEN 3 THEN '1970-01-01 00:00:00' WHEN 4 THEN '1970-01-01 00:00:00' WHEN 5 THEN '1970-01-01 00:00:00' WHEN 6 THEN '1970-01-01 00:00:00' WHEN 7 THEN '1970-01-01 00:00:00' WHEN 8 THEN '1970-01-01 00:00:00' WHEN 9 THEN '1970-01-01 00:00:00' WHEN 10 THEN '1970-01-01 00:00:00' END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = '2020-01-01 00:00:00' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = 'newtitle' WHERE ([Id] = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = 'newtitle' WHERE ([Id] = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = 'newtitle' WHERE ([Id] = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = 'newtitle', [CreateTime] = '2020-01-01 00:00:00' WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = iif(isnull([Clicks]), 0, [Clicks]) * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = iif(isnull([Clicks]), 0, [Clicks]) * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + ? WHERE ([Id] = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var time = DateTime.Now; + var items222 = g.msaccess.Select().Where(a => a.CreateTime > Convert.ToDateTime(time)).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.msaccess.Update().ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.msaccess.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.msaccess.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.msaccess.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.msaccess.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..4ba03b05 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MsAccessMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.msaccess; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/BoolTest.cs new file mode 100644 index 00000000..9de51dc3 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MsAccessMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.msaccess; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..30aec046 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MsAccessMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.msaccess; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/EnumTest.cs new file mode 100644 index 00000000..12797bdc --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MsAccessMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.msaccess; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.msaccess; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.msaccess; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.msaccess; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/ToStringTest.cs new file mode 100644 index 00000000..2b7326b0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MsAccessMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.msaccess; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs new file mode 100644 index 00000000..fca67875 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs @@ -0,0 +1,81 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MsAccess +{ + public class MsAccessAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.msaccess.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.msaccess.Ado.SlavePools.Count; + } + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t0 = g.msaccess.Ado.Query("select * from [song]"); + + var t1 = g.msaccess.Ado.Query("select id, url, create_time from [song]"); + + var t2 = g.msaccess.Ado.Query("select id, url, create_time from [song]"); + + var t3 = g.msaccess.Ado.Query("select * from [song]"); + + var t4 = g.msaccess.Ado.Query<(int, string, string)>("select * from [song]"); + + var t5 = g.msaccess.Ado.Query("select * from [song]"); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.msaccess.Ado.Query("select * from song; select * from song; select * from song"); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + + class testallDto + { + public int Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime Test_time { get; set; } + public DateTime Create_time { get; set; } + public bool Is_deleted { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAopTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAopTest.cs new file mode 100644 index 00000000..c18b3656 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.MsAccess +{ + public class MsAccessAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.msaccess.Aop.AuditValue += audit; + + g.msaccess.Insert(item).ExecuteAffrows(); + + g.msaccess.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs new file mode 100644 index 00000000..1ce9d88a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -0,0 +1,307 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.MsAccess +{ + public class MsAccessCodeFirstTest + { + + [Fact] + public void ı_ֶ() + { + var sql = g.msaccess.CodeFirst.GetComparisonDDLStatements<ı>(); + g.msaccess.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.msaccess.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.msaccess.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.msaccess.CodeFirst.GetComparisonDDLStatements(); + g.msaccess.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo2", OldName = "AddUniquesInfo")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group desc, index22", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + + public class Topic + { + public Guid Id { get; set; } + public string Title { get; set; } + public string Content { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "Comment")] + public class Comment + { + public Guid Id { get; set; } + public Guid TopicId { get; set; } + public virtual Topic Topic { get; set; } + public string Nickname { get; set; } + public string Content { get; set; } + public DateTime CreateTime { get; set; } + } + + + [Fact] + public void AddField() + { + + //һ FreeSql.Repository չdotnet add package FreeSql.Repository + var topicRepository = g.msaccess.GetGuidRepository(); + var commentRepository = g.msaccess.GetGuidRepository(); + + //Ӳ + var topic = topicRepository.Insert(new Topic + { + Title = "±1", + Content = "1", + CreateTime = DateTime.Now + }); + + //10 + var comments = Enumerable.Range(0, 10).Select(a => new Comment + { + TopicId = topic.Id, + Nickname = $"dz{a}", + Content = $"{a}", + CreateTime = DateTime.Now + }).ToArray(); + var affrows = commentRepository.Insert(comments); + + var find = commentRepository.Select.Where(a => a.Topic.Title == "±1").ToList(); + + + + + var sql = g.msaccess.CodeFirst.GetComparisonDDLStatements(); + + var id = g.msaccess.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.msaccess.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar(200) not null", OldName = "title2")] + public string title3223 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.msaccess.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE [tb_alltype] ( + [Id] AUTOINCREMENT, + [Bool] BIT NOT NULL, + [SByte] DECIMAL(3,0) NOT NULL, + [Short] DECIMAL(6,0) NOT NULL, + [Int] DECIMAL(11,0) NOT NULL, + [Long] DECIMAL(20,0) NOT NULL, + [Byte] DECIMAL(3,0) NOT NULL, + [UShort] DECIMAL(5,0) NOT NULL, + [UInt] DECIMAL(10,0) NOT NULL, + [ULong] DECIMAL(20,0) NOT NULL, + [Double] DOUBLE NOT NULL, + [Float] SINGLE NOT NULL, + [Decimal] DECIMAL(10,2) NOT NULL, + [TimeSpan] TIME NOT NULL, + [DateTime] DATETIME NOT NULL, + [DateTimeOffSet] DATETIME NOT NULL, + [Bytes] BINARY(255), + [String] VARCHAR(255), + [Guid] VARCHAR(36) NOT NULL, + [BoolNullable] BIT, + [SByteNullable] DECIMAL(3,0), + [ShortNullable] DECIMAL(6,0), + [IntNullable] DECIMAL(11,0), + [testFielLongNullable] DECIMAL(20,0), + [ByteNullable] DECIMAL(3,0), + [UShortNullable] DECIMAL(5,0), + [UIntNullable] DECIMAL(10,0), + [ULongNullable] DECIMAL(20,0), + [DoubleNullable] DOUBLE, + [FloatNullable] SINGLE, + [DecimalNullable] DECIMAL(10,2), + [TimeSpanNullable] TIME, + [DateTimeNullable] DATETIME, + [DateTimeOffSetNullable] DATETIME, + [GuidNullable] VARCHAR(36), + [Enum1] DECIMAL(11,0) NOT NULL, + [Enum1Nullable] DECIMAL(11,0), + [Enum2] DECIMAL(20,0) NOT NULL, + [Enum2Nullable] DECIMAL(20,0), + PRIMARY KEY ([Id]) +) +; +", sql); + } + + //sql = g.msaccess.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.msaccess.Insert(); + ISelect select => g.msaccess.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue - 10000000, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + //public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime DateTime { get; set; } + [Column(ServerTime = DateTimeKind.Local)] + public DateTime DateTimeOffSet { get; set; } + + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? DateTimeNullable { get; set; } + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? DateTimeOffSetNullable { get; set; } + + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/ConvertTest.cs new file mode 100644 index 00000000..090e4192 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccessExpression +{ + public class ConvertTest + { + + ISelect select => g.msaccess.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/DateTimeTest.cs new file mode 100644 index 00000000..c6b32990 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/DateTimeTest.cs @@ -0,0 +1,706 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccessExpression +{ + public class DateTimeTest + { + + ISelect select => g.msaccess.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") + + //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" + //FROM "tb_topic111333" a + //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" + //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" + //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/MathTest.cs new file mode 100644 index 00000000..2fada455 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccessExpression +{ + public class MathTest + { + + ISelect select => g.msaccess.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + // var data = new List(); + // data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + //data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/OtherTest.cs new file mode 100644 index 00000000..b5761410 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/OtherTest.cs @@ -0,0 +1,164 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccessExpression +{ + public class OtherTest + { + + ISelect select => g.msaccess.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).Limit(10).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs new file mode 100644 index 00000000..b89066fa --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs @@ -0,0 +1,728 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccessExpression +{ + public class StringTest + { + + ISelect select => g.msaccess.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.msaccess.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + //System.Data.OleDb.OleDbException : ʽ 'replace' δ塣 + //var data = new List(); + //data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + //data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + ////FROM `tb_topic` a + ////WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + ////SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + ////FROM `tb_topic` a, `TestTypeInfo` a__Type + ////WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/TimeSpanTest.cs new file mode 100644 index 00000000..c644da93 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MsAccessExpression +{ + public class TimeSpanTest + { + + ISelect select => g.msaccess.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 0cf69bea..74b7b809 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1059,12 +1059,12 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2 FROM (SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks -FROM `tb_topic_1` a) ftb - -UNION ALL - -SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks -FROM `tb_topic_2` a) ftb) a + FROM `tb_topic_1` a) ftb + + UNION ALL + + SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks + FROM `tb_topic_2` a) ftb) a limit 0,20", select .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) .Page(1, 20) @@ -1073,6 +1073,83 @@ limit 0,20", select a.Id, a.Clicks })); + + var sqltmp12 = g.mysql.Select() + .Where(t => t.IsFinished && (t.AuditorId == "1" || t.AuditorId == "1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3")) + .GroupBy(t => new { t.ProcessId, t.NodeId, t.NodeName }) + .ToSql(t => new WF_TaskGroupBy + { + TaskId = t.Max(t.Value.Id), + TaskType = t.Max(t.Value.Type), + ProcessId = t.Key.ProcessId, + NodeId = t.Key.NodeId, + NodeName = t.Key.NodeName + }, FieldAliasOptions.AsProperty); + + var groupsql12 = g.mysql.Select() + .AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null) + .LeftJoin((a, p) => p.Id == a.ProcessId) + .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) + .ToSql((a, p) => new + { + WF_Task = a, + WF_ProcessInstance = p + }); + + Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName +FROM `WF_Task` a +WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) +GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName`", sqltmp12); + Assert.Equal(@"SELECT a.`TaskId` as1, a.`TaskType` as2, a.`ProcessId` as3, a.`NodeId` as4, a.`NodeName` as5, b.`Id` as6, b.`TaskType` as7, b.`ProcessId` as8, b.`NodeId` as9, b.`CreateTime` as10, b.`IsFinished` as11, b.`EnabledMark` as12 +FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName + FROM `WF_Task` a + WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) + GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a +LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId` +WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12); + + var grouplist12 = g.mysql.Select() + .AsTable((type, old) => $"( {sqltmp12} )") + .LeftJoin((a, p) => p.Id == a.ProcessId) + .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) + .ToList((a, p) => new + { + WF_Task = a, + WF_ProcessInstance = p + }); + } + + [Table(DisableSyncStructure = true)] + class WF_TaskGroupBy + { + public int TaskId { get; set; } + public int TaskType { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public string NodeName { get; set; } + } + class WF_Task + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int Type { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public string NodeName { get; set; } + public string AuditorId { get; set; } + public DateTime CreateTime { get; set; } + public bool IsFinished { get; set; } + } + class WF_ProcessInstance + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int TaskType { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public DateTime CreateTime { get; set; } + public bool IsFinished { get; set; } + public bool EnabledMark { get; set; } } public class TestInclude_OneToManyModel1 diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 99c4b02b..1f5f3c64 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -91,4 +91,18 @@ public class g ) .Build()); public static IFreeSql sqlite => sqliteLazy.Value; + + + static Lazy msaccessLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.MsAccess, @"Provider=Microsoft.Jet.OleDb.4.0;Data Source=d:/accdb/2003.mdb;max pool size=5") + .UseConnectionString(FreeSql.DataType.MsAccess, @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=d:/accdb/2007.accdb;max pool size=5") + .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) + .Build()); + public static IFreeSql msaccess => msaccessLazy.Value; } diff --git a/FreeSql.sln b/FreeSql.sln index f5f3b0f2..9ac013cd 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -70,6 +70,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Generator", "Extens EndProject Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "FreeSql.Tests.VB", "FreeSql.Tests.VB\FreeSql.Tests.VB.vbproj", "{A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MsAccess", "Providers\FreeSql.Provider.MsAccess\FreeSql.Provider.MsAccess.csproj", "{B397A761-F646-41CF-A160-AB6C05DAF2FB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -416,6 +418,18 @@ Global {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|x64.Build.0 = Release|Any CPU {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|x86.ActiveCfg = Release|Any CPU {A4FB811A-15EF-4E4C-AC15-826F9BB44E2D}.Release|x86.Build.0 = Release|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Debug|x64.ActiveCfg = Debug|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Debug|x64.Build.0 = Debug|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Debug|x86.ActiveCfg = Debug|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Debug|x86.Build.0 = Debug|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|Any CPU.Build.0 = Release|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x64.ActiveCfg = Release|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x64.Build.0 = Release|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x86.ActiveCfg = Release|Any CPU + {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -440,6 +454,7 @@ Global {C57444BA-8BF7-4790-A864-7F237123219B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} + {B397A761-F646-41CF-A160-AB6C05DAF2FB} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 7ab8d66e..236f6325 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -22,8 +22,13 @@ namespace FreeSql Odbc, /// - /// 国产数据库达梦 + /// 武汉达梦数据库有限公司 /// OdbcDameng, + + /// + /// Microsoft Office Access 是由微软发布的关联式数据库管理系统 + /// + MsAccess, } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 499169fa..1ad59ab7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -5,7 +5,7 @@ 0.12.21 true YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, And Odbc. 达梦 + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git @@ -28,7 +28,7 @@ - + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index f20e9ab4..b6056f16 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -486,7 +486,12 @@ - 国产数据库达梦 + 武汉达梦数据库有限公司 + + + + + Microsoft Office Access 是由微软发布的关联式数据库管理系统 @@ -1725,7 +1730,7 @@ 【linq to sql】专用方法,不建议直接使用 - + 返回即将执行的SQL语句 @@ -2200,137 +2205,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 8e843a9b..dc8f1a20 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -224,6 +224,11 @@ namespace FreeSql if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); break; + case DataType.MsAccess: + type = Type.GetType("FreeSql.MsAccess.MsAccessProvider`1,FreeSql.Provider.MsAccess")?.MakeGenericType(typeof(TMark)); + if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MsAccess.dll,可前往 nuget 下载"); + break; + default: throw new Exception("未指定 UseConnectionString"); } } diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 3ba8b71b..46c5a92c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -55,7 +55,7 @@ namespace FreeSql /// 返回类型 /// 选择列 /// - string ToSql(Expression, TReturn>> select); + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); /// /// 返回即将执行的SQL语句 /// diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index ec8770fc..1d68f397 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -37,8 +37,8 @@ namespace FreeSql.Internal case ExpressionType.NegateChecked: parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); + if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); return false; case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Constant: @@ -56,8 +56,8 @@ namespace FreeSql.Internal else parent.DbField = _common.FormatSql("{0}", constExp?.Value); field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); + if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); return false; case ExpressionType.Call: var callExp = exp as MethodCallExpression; @@ -73,8 +73,8 @@ namespace FreeSql.Internal else parent.DbField = ExpressionLambdaToSql(exp, getTSC()); field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); + if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); return false; case ExpressionType.Parameter: case ExpressionType.MemberAccess: @@ -97,7 +97,7 @@ namespace FreeSql.Internal MapType = map[idx].Column.Attribute.MapType }; field.Append(", ").Append(_common.QuoteReadColumn(child.MapType, child.DbField)); - if (index >= 0) field.Append(" as").Append(++index); + if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); parent.Childs.Add(child); } } @@ -106,8 +106,8 @@ namespace FreeSql.Internal parent.CsType = exp.Type; parent.DbField = ExpressionLambdaToSql(exp, getTSC()); field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); + if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); parent.MapType = SearchColumnByField(_tables, null, parent.DbField)?.Attribute.MapType ?? exp.Type; return false; } @@ -157,7 +157,7 @@ namespace FreeSql.Internal { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(" as").Append(++index); + if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); } break; } @@ -240,7 +240,7 @@ namespace FreeSql.Internal { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(" as").Append(++index); + if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); } break; } @@ -251,8 +251,8 @@ namespace FreeSql.Internal } parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})"; field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(" as").Append(++index); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(" ").Append(parent.CsName); + if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); return false; } public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue) @@ -593,7 +593,7 @@ namespace FreeSql.Internal case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, null); case ExpressionType.Conditional: var condExp = exp as ConditionalExpression; - return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end"; + return _common.IIF(ExpressionLambdaToSql(condExp.Test, tsc), ExpressionLambdaToSql(condExp.IfTrue, tsc), ExpressionLambdaToSql(condExp.IfFalse, tsc)); case ExpressionType.Call: tsc.mapType = null; var exp3 = exp as MethodCallExpression; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 840f6ca1..3c0e3054 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -111,6 +111,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -153,6 +154,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -169,6 +171,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -219,6 +222,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -235,6 +239,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -251,6 +256,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -307,6 +313,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -323,6 +330,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -339,6 +347,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -355,6 +364,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -417,6 +427,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -433,6 +444,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -449,6 +461,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -465,6 +478,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -481,6 +495,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -655,7 +670,12 @@ namespace FreeSql.Internal.CommonProvider if (ret.Tables.Count <= result) { dt = ret.Tables.Add(); - for (var a = 0; a < dr.FieldCount; a++) dt.Columns.Add(dr.GetName(a)); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; + dt.Columns.Add(name); + } } object[] values = new object[dt.Columns.Count]; dr.GetValues(values); @@ -674,7 +694,12 @@ namespace FreeSql.Internal.CommonProvider ExecuteReader(connection, transaction, dr => { if (ret.Columns.Count == 0) - for (var a = 0; a < dr.FieldCount; a++) ret.Columns.Add(dr.GetName(a)); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; + ret.Columns.Add(name); + } object[] values = new object[ret.Columns.Count]; dr.GetValues(values); ret.Rows.Add(values); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 63e50246..efe6cd71 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -35,6 +35,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -78,6 +79,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -94,6 +96,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -145,6 +148,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -161,6 +165,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -177,6 +182,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -234,6 +240,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -250,6 +257,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -266,6 +274,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -282,6 +291,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -345,6 +355,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -361,6 +372,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -377,6 +389,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -393,6 +406,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -409,6 +423,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < dr.FieldCount; a++) { var name = dr.GetName(a); + if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); } @@ -585,7 +600,12 @@ namespace FreeSql.Internal.CommonProvider if (ret.Tables.Count <= result) { dt = ret.Tables.Add(); - for (var a = 0; a < dr.FieldCount; a++) dt.Columns.Add(dr.GetName(a)); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; + dt.Columns.Add(name); + } } object[] values = new object[dt.Columns.Count]; for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); @@ -604,7 +624,12 @@ namespace FreeSql.Internal.CommonProvider await ExecuteReaderAsync(connection, transaction, async dr => { if (ret.Columns.Count == 0) - for (var a = 0; a < dr.FieldCount; a++) ret.Columns.Add(dr.GetName(a)); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; + ret.Columns.Add(name); + } object[] values = new object[ret.Columns.Count]; for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); ret.Rows.Add(values); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index a501c9c1..34bbeb15 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -88,7 +88,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IInsert BatchOptions(int valuesLimit, int parameterLimit, bool autoTransaction = true) + public virtual IInsert BatchOptions(int valuesLimit, int parameterLimit, bool autoTransaction = true) { _batchValuesLimit = valuesLimit; _batchParameterLimit = parameterLimit; @@ -170,6 +170,8 @@ namespace FreeSql.Internal.CommonProvider { valuesLimit = valuesLimit - 1; parameterLimit = parameterLimit - 1; + if (valuesLimit <= 0) valuesLimit = 1; + if (parameterLimit <= 0) parameterLimit = 999; if (_source == null || _source.Any() == false) return new List[0]; if (_source.Count == 1) return new[] { _source }; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 2881b8fb..5d45b4fc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -155,7 +155,7 @@ namespace FreeSql.Internal.CommonProvider public bool Any() { this.Limit(1); - return this.ToList("1 as1").Sum() > 0; //这里的 Sum 为了分表查询 + return this.ToList($"{1}{_commonUtils.FieldAsAlias("as1")}").Sum() > 0; //这里的 Sum 为了分表查询 } public long Count() @@ -164,7 +164,7 @@ namespace FreeSql.Internal.CommonProvider _orderby = null; //解决 select count(1) from t order by id 这样的 SQL 错误 try { - return this.ToList("count(1) as1").Sum(); //这里的 Sum 为了分表查询 + return this.ToList($"count(1){_commonUtils.FieldAsAlias("as1")}").Sum(); //这里的 Sum 为了分表查询 } finally { @@ -599,7 +599,7 @@ namespace FreeSql.Internal.CommonProvider var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); ++colidx; } @@ -730,7 +730,7 @@ namespace FreeSql.Internal.CommonProvider var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); } else @@ -754,7 +754,7 @@ namespace FreeSql.Internal.CommonProvider field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); ++index; ++otherindex; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); } } @@ -851,7 +851,7 @@ namespace FreeSql.Internal.CommonProvider var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); } else @@ -868,7 +868,7 @@ namespace FreeSql.Internal.CommonProvider var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); child.Childs.Add(new ReadAnonymousTypeInfo { @@ -946,6 +946,8 @@ namespace FreeSql.Internal.CommonProvider if (_orm.CodeFirst.IsSyncStructureToUpper) name = name.ToUpper(); if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, name); } + else + name = name.Replace("\r\n", "\r\n "); } dict.Add(tb.Table.Type, name); } @@ -1035,12 +1037,12 @@ namespace FreeSql.Internal.CommonProvider protected double InternalAvg(Expression exp) { - var list = this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1"); + var list = this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"); return list.Sum() / list.Count; } - protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").Max(); - protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").Min(); - protected decimal InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1").Sum(); + protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Max(); + protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Min(); + protected decimal InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Sum(); protected ISelectGrouping InternalGroupBy(Expression columns) { @@ -1118,7 +1120,7 @@ namespace FreeSql.Internal.CommonProvider async public Task AnyAsync() { this.Limit(1); - return (await this.ToListAsync("1 as1")).Sum() > 0; //这里的 Sum 为了分表查询 + return (await this.ToListAsync($"1{_commonUtils.FieldAsAlias("as1")}")).Sum() > 0; //这里的 Sum 为了分表查询 } async public Task CountAsync() @@ -1127,7 +1129,7 @@ namespace FreeSql.Internal.CommonProvider _orderby = null; try { - return (await this.ToListAsync("count(1) as1")).Sum(); //这里的 Sum 为了分表查询 + return (await this.ToListAsync($"count(1){_commonUtils.FieldAsAlias("as1")}")).Sum(); //这里的 Sum 为了分表查询 } finally { @@ -1312,12 +1314,12 @@ namespace FreeSql.Internal.CommonProvider async protected Task InternalAvgAsync(Expression exp) { - var list = await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1"); + var list = await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"); return list.Sum() / list.Count; } - async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).Max(); - async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).Min(); - async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}) as1")).Sum(); + async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Max(); + async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Min(); + async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Sum(); protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index ea6e9ff6..30d3615f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -56,7 +56,7 @@ namespace FreeSql.Internal.CommonProvider case "Where": this.InternalWhere(expCall.Arguments[0]); break; case "WhereIf": var whereIfCond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); - if (whereIfCond == "1" || whereIfCond == "'t'") + if (whereIfCond == "1" || whereIfCond == "'t'" || whereIfCond == "-1") //MsAccess -1 this.InternalWhere(expCall.Arguments[1]); break; case "OrderBy": @@ -73,7 +73,7 @@ namespace FreeSql.Internal.CommonProvider if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) { var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); - if (ifcond == "1" || ifcond == "'t'") + if (ifcond == "1" || ifcond == "'t'" || ifcond == "-1")//MsAccess -1 this.InternalOrderByDescending(expCall.Arguments.LastOrDefault()); break; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index e9bd0947..3bd15b46 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -121,11 +121,11 @@ namespace FreeSql.Internal.CommonProvider public List Select(Expression, TReturn>> select) => ToList(select); - public string ToSql(Expression, TReturn>> select) + public string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); - var index = 0; + var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); @@ -163,7 +163,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public long Count() => long.TryParse(string.Concat(_orm.Ado.ExecuteScalar($"select count(1) from ({this.ToSql("1 as1")}) fta")), out var trylng) ? trylng : default(long); + public long Count() => long.TryParse(string.Concat(_orm.Ado.ExecuteScalar($"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta")), out var trylng) ? trylng : default(long); public ISelectGrouping Count(out long count) { count = this.Count(); @@ -172,7 +172,7 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync($"select count(1) from ({this.ToSql("1 as1")}) fta")), out var trylng) ? trylng : default(long); + async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync($"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta")), out var trylng) ? trylng : default(long); public Task> ToListAsync(Expression, TReturn>> select) { diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index b84951eb..9cd654f3 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -93,7 +93,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IUpdate BatchOptions(int rowsLimit, int parameterLimit, bool autoTransaction = true) + public virtual IUpdate BatchOptions(int rowsLimit, int parameterLimit, bool autoTransaction = true) { _batchRowsLimit = rowsLimit; _batchParameterLimit = parameterLimit; @@ -117,6 +117,8 @@ namespace FreeSql.Internal.CommonProvider { valuesLimit = valuesLimit - 1; parameterLimit = parameterLimit - 1; + if (valuesLimit <= 0) valuesLimit = 1; + if (parameterLimit <= 0) parameterLimit = 999; if (_source == null || _source.Any() == false) return new List[0]; if (_source.Count == 1) return new[] { _source }; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index a2f8d3f0..0b985d08 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -38,6 +38,8 @@ namespace FreeSql.Internal public abstract string NowUtc { get; } public abstract string QuoteWriteParamter(Type type, string paramterName); public abstract string QuoteReadColumn(Type type, string columnName); + public virtual string FieldAsAlias(string alias) => $" {alias}"; + public virtual string IIF(string test, string ifTrue, string ifElse) => $"case when {test} then {ifTrue} else {ifElse} end"; public IFreeSql _orm { get; set; } public ICodeFirst CodeFirst => _orm.CodeFirst; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 83002513..85ac0949 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -199,7 +199,7 @@ namespace FreeSql.Internal { case DataType.MySql: case DataType.OdbcMySql: - if (strlen < 0) colattr.DbType = "text"; + if (strlen < 0) colattr.DbType = "TEXT"; else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; case DataType.SqlServer: @@ -209,7 +209,7 @@ namespace FreeSql.Internal break; case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: - if (strlen < 0) colattr.DbType = "text"; + if (strlen < 0) colattr.DbType = "TEXT"; else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; case DataType.Oracle: @@ -219,7 +219,12 @@ namespace FreeSql.Internal else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; case DataType.Sqlite: - if (strlen < 0) colattr.DbType = "text"; + if (strlen < 0) colattr.DbType = "TEXT"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.MsAccess: + charPatten = @"(CHAR|CHAR2|CHARACTER|TEXT)\s*(\([^\)]*\))?"; + if (strlen < 0) colattr.DbType = "LONGTEXT"; else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; } diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs new file mode 100644 index 00000000..46c81d2e --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs @@ -0,0 +1,109 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.MsAccess.Curd +{ + + class MsAccessDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public MsAccessDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); + + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + +#if net40 +#else + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException("找不到 WHERE "); + sb.Insert(0, sql.Substring(0, validx)); + sb.Append(sql.Substring(validx)); + + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBefore?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + this.ClearData(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs new file mode 100644 index 00000000..1ab68770 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs @@ -0,0 +1,183 @@ +using FreeSql.Internal; +using SafeObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.MsAccess.Curd +{ + + class MsAccessInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public MsAccessInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + _batchAutoTransaction = false; + } + + //蛋疼的 access 插入只能一条一条执行,不支持 values(..),(..) 也不支持 select .. UNION ALL select .. + public override int ExecuteAffrows() => base.SplitExecuteAffrows(1, 1000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(1, 1000); + public override List ExecuteInserted() => base.SplitExecuteInserted(1, 1000); + + public override IInsert BatchOptions(int valuesLimit, int parameterLimit, bool autoTransaction = true) => + throw new NotImplementedException("蛋疼的 access 插入只能一条一条执行,不支持 values(..),(..) 也不支持 select .. UNION ALL select .."); + + protected override int RawExecuteAffrows() + { + var sql = this.ToSql(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return affrows; + } + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT @@identity;"), _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + var isUseConnection = _connection != null; + try + { + if (isUseConnection == false) + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _connection = conn.Value; + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, "SELECT @@identity", _params)), out ret); + } + } + else + { + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, "SELECT @@identity", _params)), out ret); + } + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (isUseConnection == false) _connection = null; + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + this.RawExecuteAffrows(); + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + + async protected override Task RawExecuteAffrowsAsync() + { + var sql = this.ToSql(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return affrows; + } + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT @@identity;"), _params); + _orm.Aop.CurdBefore?.Invoke(this, before); + long ret = 0; + Exception exception = null; + var isUseConnection = _connection != null; + try + { + if (isUseConnection == false) + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _connection = conn.Value; + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _params)), out ret); + } + } + else + { + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _params)), out ret); + } + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (isUseConnection == false) _connection = null; + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfter?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + await this.RawExecuteAffrowsAsync(); + return ret; + } +#endif + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs new file mode 100644 index 00000000..dde8525e --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs @@ -0,0 +1,194 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.MsAccess.Curd +{ + + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); + sb.Append(field); + if (_skip > 0) + throw new NotImplementedException("FreeSql.Provider.MsAccess 未实现 Skip/Offset 功能,如果需要分页请使用判断上一次 id"); + sb.Append(" \r\nFROM "); + var fromIndex = sb.Length; + var ioinCounter = 0; + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + if (ioinCounter++ > 0) sb.Insert(fromIndex, "(").Append(") "); + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON (").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + sb.Append(")"); + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + if (ioinCounter++ > 0) sb.Insert(fromIndex, "(").Append(") "); + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + if (ioinCounter++ > 0) sb.Insert(fromIndex, "(").Append(") "); + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + if (ioinCounter++ > 0) sb.Insert(fromIndex, "(").Append(") "); + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON (").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + sb.Append(")"); + } + if (_join.Length > 0) + { + sb.Append(Regex.Replace(_join.ToString(), @" \r\n(LEFT|INNER|RIGHT) JOIN ", m => + { + if (ioinCounter++ > 0) + { + sb.Insert(fromIndex, "(").Append(") "); + return $") {m.Groups[0].Value}"; + } + return m.Groups[0].Value; + }, RegexOptions.IgnoreCase)); + } + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class AccessSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs new file mode 100644 index 00000000..bf39d6b1 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs @@ -0,0 +1,79 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.MsAccess.Curd +{ + + class MsAccessUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public MsAccessUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + _batchAutoTransaction = false; + } + + //蛋疼的 access 更新只能一条一条执行,不支持 case .. when .. then .. end,也不支持事务 + public override int ExecuteAffrows() => base.SplitExecuteAffrows(1, 1000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(1, 1000); + + public override IUpdate BatchOptions(int rowsLimit, int parameterLimit, bool autoTransaction = true) => + throw new NotImplementedException("蛋疼的 access 插入只能一条一条执行,不支持 values(..),(..) 也不支持 select .. UNION ALL select .."); + + protected override List RawExecuteUpdated() + { + throw new NotImplementedException(); + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(", "); + caseWhen.Append(MsAccessUtils.GetCastSql(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)), typeof(string))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(", "); + sb.Append(MsAccessUtils.GetCastSql(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)), typeof(string))); + ++pkidx; + } + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); + + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj new file mode 100644 index 00000000..1f157363 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -0,0 +1,38 @@ + + + + netstandard2.0;net45;net40 + 0.12.21 + true + YeXiangQin + FreeSql 数据库 Ms Access 实现 + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM;Access + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + + + + + + + + + + + + + + + + net40 + + + + diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSqlMsAccessGlobalExtensions.cs b/Providers/FreeSql.Provider.MsAccess/FreeSqlMsAccessGlobalExtensions.cs new file mode 100644 index 00000000..b56b05b9 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/FreeSqlMsAccessGlobalExtensions.cs @@ -0,0 +1,12 @@ +public static partial class FreeSqlMsAccessGlobalExtensions +{ + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatAccess(this string that, params object[] args) => _accessAdo.Addslashes(that, args); + static FreeSql.MsAccess.MsAccessAdo _accessAdo = new FreeSql.MsAccess.MsAccessAdo(); +} diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs new file mode 100644 index 00000000..030b57a1 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs @@ -0,0 +1,77 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using SafeObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Data.OleDb; +using System.Linq; +using System.Text; +using System.Threading; + +namespace FreeSql.MsAccess +{ + class MsAccessAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public MsAccessAdo() : base(DataType.MsAccess) { } + public MsAccessAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.MsAccess) + { + base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.MsAccess, connectionFactory); + return; + } + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new MsAccessConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new MsAccessConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) + return (bool)param ? -1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + { + if (param.Equals(DateTime.MinValue) == true) param = new DateTime(1970, 1, 1); + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss"), "'"); + } + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).TotalSeconds; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new OleDbCommand(); + } + + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + var rawPool = pool as MsAccessConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs new file mode 100644 index 00000000..34e49c8d --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs @@ -0,0 +1,242 @@ +using SafeObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.OleDb; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.MsAccess +{ + + class MsAccessConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public MsAccessConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + var policy = new AccessConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OleDbException) + { + + if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class AccessConnectionPoolPolicy : IPolicy + { + + internal MsAccessConnectionPool _pool; + public string Name { get; set; } = "Microsoft Access OleDbConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(30); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + if (int.TryParse(m.Groups[1].Value, out var poolsize) && poolsize > 0) + PoolSize = poolsize; + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OleDbConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs new file mode 100644 index 00000000..a57f6098 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs @@ -0,0 +1,458 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.OleDb; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.MsAccess +{ + + class MsAccessCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public MsAccessCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary _dicCsToDb = new Dictionary() { + { typeof(bool).FullName, (OleDbType.Boolean, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OleDbType.Boolean, "bit","bit", null, true, null) }, + + { typeof(sbyte).FullName, (OleDbType.TinyInt, "decimal", "decimal(3,0) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OleDbType.TinyInt, "decimal", "decimal(3,0)", false, true, null) }, + { typeof(short).FullName, (OleDbType.SmallInt, "decimal","decimal(6,0) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OleDbType.SmallInt, "decimal", "decimal(6,0)", false, true, null) }, + { typeof(int).FullName, (OleDbType.Integer, "decimal", "decimal(11,0) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OleDbType.Integer, "decimal", "decimal(11,0)", false, true, null) }, + { typeof(long).FullName, (OleDbType.BigInt, "decimal","decimal(20,0) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OleDbType.BigInt, "decimal","decimal(20,0)", false, true, null) }, + // access int long 类型是留给自动增长用的,所以这里全映射为 decimal + { typeof(byte).FullName, (OleDbType.UnsignedTinyInt, "decimal","decimal(3,0) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OleDbType.UnsignedTinyInt, "decimal","decimal(3,0)", true, true, null) }, + { typeof(ushort).FullName, (OleDbType.UnsignedSmallInt, "decimal","decimal(5,0) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OleDbType.UnsignedSmallInt, "decimal", "decimal(5,0)", true, true, null) }, + { typeof(uint).FullName, (OleDbType.UnsignedInt, "decimal", "decimal(10,0) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OleDbType.UnsignedInt, "decimal", "decimal(10,0)", true, true, null) }, + { typeof(ulong).FullName, (OleDbType.UnsignedBigInt, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OleDbType.UnsignedBigInt, "decimal", "decimal(20,0)", true, true, null) }, + + { typeof(double).FullName, (OleDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OleDbType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, (OleDbType.Currency, "single","single NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OleDbType.Currency, "single","single", false, true, null) }, + { typeof(decimal).FullName, (OleDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OleDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + + { typeof(TimeSpan).FullName, (OleDbType.DBTime, "datetime","datetime NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OleDbType.DBTime, "datetime", "datetime",false, true, null) }, + { typeof(DateTime).FullName, (OleDbType.DBTimeStamp, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OleDbType.DBTimeStamp, "datetime", "datetime", false, true, null) }, + + { typeof(byte[]).FullName, (OleDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, (OleDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + + { typeof(Guid).FullName, (OleDbType.Guid, "varchar", "varchar(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OleDbType.Guid, "varchar", "varchar(36)", false, true, null) }, + }; + + public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + (OleDbType.BigInt, "decimal", $"decimal(20,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + (OleDbType.Integer, "decimal", $"decimal(11,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + } + return null; + } + + protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + { + var sb = new StringBuilder(); + var sbDeclare = new StringBuilder(); + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName; + var tboldname = tb.DbOldName; //旧表名 + if (string.Compare(tbname, tboldname, true) == 0) tboldname = null; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + tbname = obj.tableName; + tboldname = null; + } + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + var isexistsTb = false; + + DataTable schemaTables = null; + using (var conn = _orm.Ado.MasterPool.Get()) + { + schemaTables = conn.Value.GetSchema("Tables"); + } + var schemaTablesTableNameIndex = 2; + for (var idx = 0; idx < schemaTables.Columns.Count; idx++) + if (string.Compare(schemaTables.Columns[idx].ColumnName, "TABLE_NAME", true) == 0) + { + schemaTablesTableNameIndex = idx; + break; + } + Func existsTable = tn => + { + foreach (DataRow row in schemaTables.Rows) + if (string.Compare(row[schemaTablesTableNameIndex]?.ToString(), tn, true) == 0) + return true; + return false; + //_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT 1 FROM MsysObjects WHERE Name='{tn}' AND Left([Name],1)<>'~' AND Left([Name],4)<>'Msys' AND Type=1 and Flags=0") != null; + }; + Action createTable = tn => + { + tn = _commonUtils.QuoteSqlName(tn); + //创建表 + sb.Append("CREATE TABLE ").Append(tn).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTOINCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) + sb.Append(" AUTOINCREMENT"); + else + sb.Append(" ").Append(tbcol.Attribute.DbType); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) \r\n;\r\n"); + }; + Action createTableIndex = tn => + { + tn = _commonUtils.QuoteSqlName(tn); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tn).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + }; + + if (tboldname != null) + { + if (existsTable(tboldname) == false) + //旧表不存在 + tboldname = null; + } + isexistsTb = existsTable(tbname); + if (isexistsTb == false) + { //表不存在 + if (tboldname == null) + { + createTable(tbname); + createTableIndex(tbname); + continue; + } + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + if (tboldname != null && isexistsTb == true) + throw new Exception($"旧表(OldName):{tboldname} 存在,数据库已存在 {tbname} 表,无法改名"); + + DataTable schemaColumns = null; + DataTable schemaDataTypes = null; + DataTable schemaIndexes = null; + using (var conn = _orm.Ado.MasterPool.Get()) + { + schemaColumns = conn.Value.GetSchema("COLUMNS"); + schemaDataTypes = conn.Value.GetSchema("DATATYPES"); + schemaIndexes = conn.Value.GetSchema("INDEXES"); + } + Func checkPrimaryKeyByTableNameAndColumn = (tn, cn) => + { + int table_name_index = 0, primary_key_index = 0, column_name_index = 0; + for (var a = 0; a < schemaIndexes.Columns.Count; a++) + { + switch (schemaIndexes.Columns[a].ColumnName.ToLower()) + { + case "table_name": + table_name_index = a; + break; + case "primary_key": + primary_key_index = a; + break; + case "column_name": + column_name_index = a; + break; + } + } + foreach (DataRow row in schemaIndexes.Rows) + { + if (string.Compare(row[table_name_index]?.ToString(), tn, true) != 0) continue; + if (string.Compare(row[column_name_index]?.ToString(), cn, true) != 0) continue; + return new[] { "1", "True", "true", "t", "yes", "ok" }.Contains(row[primary_key_index]?.ToString()); + } + return false; + }; + Func> getIndexesByTableName = tn => + { + int table_name_index = 0, index_name_index = 0, primary_key_index = 0, unique_index = 0, column_name_index = 0, collation_index = 0; + for (var a = 0; a < schemaIndexes.Columns.Count; a++) + { + switch (schemaIndexes.Columns[a].ColumnName.ToLower()) + { + case "table_name": + table_name_index = a; + break; + case "index_name": + index_name_index = a; + break; + case "primary_key": + primary_key_index = a; + break; + case "unique": + unique_index = a; + break; + case "column_name": + column_name_index = a; + break; + case "collation": + collation_index = a; + break; + } + } + var idxs = new List(); + foreach (DataRow row in schemaIndexes.Rows) + { + if (string.Compare(row[table_name_index]?.ToString(), tn, true) != 0) continue; + if (new[] { "1", "True", "true", "t", "yes", "ok" }.Contains(row[primary_key_index]?.ToString())) continue; + var column_name = row[column_name_index]?.ToString(); + var index_name = row[index_name_index]?.ToString(); + var isDesc = int.TryParse(row[collation_index]?.ToString(), out var collation) ? (collation == 2) : false; + var unique = new[] { "1", "True", "true", "t", "yes", "ok" }.Contains(row[unique_index]?.ToString()); + idxs.Add(new[] { column_name, index_name, isDesc ? "1" : "0", unique ? "1" : "0" }); + } + return idxs; + }; + Func> getColumnsByTableName = tn => + { + int table_name_index = 0, column_name_index = 0, is_nullable_index = 0, data_type_index = 0, + character_maximum_length_index = 0, character_octet_length_index = 0, numeric_precision_index = 0, numeric_scale_index = 0, + datetime_precision_index = 0, description_index = 0; + for (var a = 0; a < schemaColumns.Columns.Count; a++) + { + switch (schemaColumns.Columns[a].ColumnName.ToLower()) + { + case "table_name": + table_name_index = a; + break; + case "column_name": + column_name_index = a; + break; + case "is_nullable": + is_nullable_index = a; + break; + case "data_type": + data_type_index = a; + break; + case "character_maximum_length": + character_maximum_length_index = a; + break; + case "character_octet_length": + character_octet_length_index = a; + break; + case "numeric_precision": + numeric_precision_index = a; + break; + case "numeric_scale": + numeric_scale_index = a; + break; + case "datetime_precision": + datetime_precision_index = a; + break; + case "description": + description_index = a; + break; + } + } + int datatype_ProviderDbType_index = 0, datatype_NativeDataType_index = 0, datatype_TypeName_index = 0, datatype_IsAutoIncrementable_index = 0; + for (var a = 0; a < schemaDataTypes.Columns.Count; a++) + { + switch (schemaDataTypes.Columns[a].ColumnName.ToLower()) + { + case "providerdbtype": + datatype_ProviderDbType_index = a; + break; + case "nativedatatype": + datatype_NativeDataType_index = a; + break; + case "typename": + datatype_TypeName_index = a; + break; + case "isautoincrementable": + datatype_IsAutoIncrementable_index = a; + break; + } + } + Func getDataType = dtnum => + { + DataRow dtRow = null; //这里的写法是为了照顾 SchemaTypes 返回的结构 + foreach (DataRow dataType in schemaDataTypes.Rows) + { + if (datatype_ProviderDbType_index >= 0 && dataType[datatype_ProviderDbType_index]?.ToString() == dtnum) dtRow = dataType; + if (datatype_NativeDataType_index >= 0 && dataType[datatype_NativeDataType_index]?.ToString() == dtnum) dtRow = dataType; + } + return dtRow; + }; + var ret = new Dictionary(); + foreach (DataRow row in schemaColumns.Rows) + { + if (string.Compare(row[table_name_index]?.ToString(), tn, true) != 0) continue; + var column_name = row[column_name_index]?.ToString(); + var dataTypeRow = getDataType(row[data_type_index]?.ToString()); + var is_identity = new[] { "1", "True", "true", "t", "yes", "ok" }.Contains(dataTypeRow[datatype_IsAutoIncrementable_index]?.ToString()); + var is_nullable = new[] { "1", "True", "true", "t", "yes", "ok" }.Contains(row[is_nullable_index]?.ToString()); + if (is_nullable && checkPrimaryKeyByTableNameAndColumn(tn, column_name)) is_nullable = false; + var comment = row[description_index]?.ToString(); + if (string.IsNullOrEmpty(comment)) comment = null; + int.TryParse(row[character_maximum_length_index]?.ToString(), out var character_maximum_length); + int.TryParse(row[character_octet_length_index]?.ToString(), out var character_octet_length); + int.TryParse(row[numeric_precision_index]?.ToString(), out var numeric_precision); + int.TryParse(row[numeric_scale_index]?.ToString(), out var numeric_scale); + int.TryParse(row[datetime_precision_index]?.ToString(), out var datetime_precision); + var datatype = dataTypeRow[datatype_TypeName_index]?.ToString().ToUpper(); + if (numeric_precision > 0 && numeric_scale > 0) datatype = $"{datatype}({numeric_precision},{numeric_scale})"; + else if (character_maximum_length > 0 && character_octet_length > 0) datatype = $"{datatype}({character_maximum_length})"; + ret.Add(column_name, (column_name, datatype, is_nullable, is_identity, comment)); + } + return ret; + }; + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var tbtmp = tboldname ?? tbname; + var tbstruct = getColumnsByTableName(tbtmp); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + if (tbstructcol.sqlType != "LONG" && tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + istmpatler = true; + if (tbstructcol.sqlType != "BIT" && tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + istmpatler = true; + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + istmpatler = true; + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + istmpatler = true; + continue; + } + //添加列 + istmpatler = true; + } + var dsuk = getIndexesByTableName(tbtmp); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + istmpatler = true; + } + } + if (istmpatler == false) + { + sb.Append(sbalter); + continue; + } + + Dictionary dicDropTable = new Dictionary(StringComparer.OrdinalIgnoreCase); + Action dropTable = tn => { + if (dicDropTable.ContainsKey(tn)) return; + dicDropTable.Add(tn, true); + sb.Append("DROP TABLE ").Append(_commonUtils.QuoteSqlName(tn)).Append(";\r\n"); + }; + Action createTableImportData = (newtn, oldtn) => + { + if (existsTable(newtn)) dropTable(newtn); + createTable(newtn); + sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(newtn)).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); + insertvalue = MsAccessUtils.GetCastSql(insertvalue, tbcol.Attribute.MapType); + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"iif(isnull({insertvalue}),{tbcol.DbDefaultValue},{insertvalue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(_commonUtils.QuoteSqlName(oldtn)).Append(";\r\n"); + dropTable(oldtn); + }; + + if (tboldname != null && isexistsTb == true) + { + createTableImportData(tbname + "_FreeSqlBackup", tbname); //备份 tbname 表 + createTableImportData(tbname, tboldname); //创建新表,把 oldname 旧表数据导入到新表,删除 oldname + } + if (tboldname != null && isexistsTb == false) + { + createTableImportData(tbname, tboldname); //创建新表,把 oldname 旧表数据导入到新表,删除 oldname + } + if (tboldname == null && isexistsTb == true) + { + createTableImportData(tbname + "_FreeSqlTmp", tbname); //创建 Tmp 表,把 tbname 表数据导入到 Tmp,删除 tbname + createTableImportData(tbname, tbname + "_FreeSqlTmp"); //创建 新表,把 Tmp 表数据导入到新表,删除 Tmp + } + } + return sb.Length == 0 ? null : sb.ToString(); + } + + public override int ExecuteDDLStatements(string ddl) + { + if (string.IsNullOrEmpty(ddl)) return 0; + var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray(); + + if (scripts.Any() == false) return 0; + if (scripts.Length == 1) return base.ExecuteDDLStatements(ddl); + + var affrows = 0; + foreach (var script in scripts) + affrows += base.ExecuteDDLStatements(script); + return affrows; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs new file mode 100644 index 00000000..53fbb008 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -0,0 +1,398 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.MsAccess +{ + class MsAccessExpression : CommonExpression + { + + public MsAccessExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + var retBefore = getExp(operandExp); + var retAfter = MsAccessUtils.GetCastSql(retBefore, gentype); + if (retBefore != retAfter) return retAfter; + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + var retBefore = getExp(callExp.Arguments[0]); + var retAfter = MsAccessUtils.GetCastSql(retBefore, callExp.Method.DeclaringType.NullableTypeOrThis()); + if (retBefore != retAfter) return retAfter; + return null; + case "NewGuid": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Guid": return $"newid()"; + } + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "rnd*1000000000000000"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "rnd"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "rnd"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? MsAccessUtils.GetCastSql(getExp(callExp.Object), typeof(string)) : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + var left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"len({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "date"; + case "MinValue": return "'1753/1/1 0:00:00'"; + case "MaxValue": return "'9999/12/31 23:59:59'"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"format({left},'yyyy-mm-dd')"; + case "TimeOfDay": return $"datediff('s', format({left},'yyyy-mm-dd'), {left})"; + case "DayOfWeek": return $"(format({left},'w')-1)"; + case "Day": return $"day({left})"; + case "DayOfYear": return $"format({left},'y')"; + case "Month": return $"month({left})"; + case "Year": return $"year({left})"; + case "Hour": return $"hour({left})"; + case "Minute": return $"minute({left})"; + case "Second": return $"second({left})"; + case "Millisecond": return $"(second({left})/1000)"; + case "Ticks": return $"({MsAccessUtils.GetCastSql($"datediff('s', '1970-1-1', {left})", typeof(long))}*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"clng(({left})/{60 * 60 * 24}+1)"; + case "Hours": return $"clng(({left})/{60 * 60} mod 24+1)"; + case "Milliseconds": return $"({MsAccessUtils.GetCastSql(left, typeof(long))}*1000)"; + case "Minutes": return $"clng(({left})/60 mod 60+1)"; + case "Seconds": return $"(({left}) mod 60)"; + case "Ticks": return $"({MsAccessUtils.GetCastSql(left, typeof(long))}*10000000)"; + case "TotalDays": return $"(({left})/{60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{60 * 60})"; + case "TotalMilliseconds": return $"({MsAccessUtils.GetCastSql(left, typeof(long))}*1000)"; + case "TotalMinutes": return $"(({left})/60)"; + case "TotalSeconds": return $"({left})"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"({args0Value}+'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+{args0Value})")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'+{args0Value}+'%')"; + case "ToLower": return $"lcase({left})"; + case "ToUpper": return $"ucase({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})"; + return $"mid({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(instr({locateArgs1}, {left}, {indexOfFindStr})-1)"; + } + return $"(instr({left}, {indexOfFindStr})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": return $"ltrim(rtrim({left}))"; + case "TrimStart": return $"ltrim({left})"; + case "TrimEnd": return $"rtrim({left})"; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"strcomp({left}, {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"clng({getExp(exp.Arguments[0])}+1)"; + case "Ceiling": return $"clng({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])}, 0)"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqr({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"floor({getExp(exp.Arguments[0])})"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"format(dateadd('d', -1, dateadd('m', 1, {MsAccessUtils.GetCastSql(getExp(exp.Arguments[0]), typeof(string))} + '-' + {MsAccessUtils.GetCastSql(getExp(exp.Arguments[1]), typeof(string))} + '-1')),'d')"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1}) mod 4=0 AND ({isLeapYearArgs1}) mod 100<>0 OR ({isLeapYearArgs1}) mod 400=0)"; + + case "Parse": return MsAccessUtils.GetCastSql(getExp(exp.Arguments[0]), typeof(DateTime)); + case "ParseExact": + case "TryParse": + case "TryParseExact": return MsAccessUtils.GetCastSql(getExp(exp.Arguments[0]), typeof(DateTime)); + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"dateadd('s', {args1}, {left})"; + case "AddDays": return $"dateadd('d', {args1}, {left})"; + case "AddHours": return $"dateadd('h', {args1}, {left})"; + case "AddMilliseconds": return $"dateadd('s', ({args1})/1000, {left})"; + case "AddMinutes": return $"dateadd('n', {args1}, {left})"; + case "AddMonths": return $"dateadd('m', {args1}, {left})"; + case "AddSeconds": return $"dateadd('s', {args1}, {left})"; + case "AddTicks": return $"dateadd('s', ({args1})/10000000, {left})"; + case "AddYears": return $"dateadd('yyyy', {args1}, {left})"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"datediff('s', {args1}, {left})"; + case "System.TimeSpan": return $"dateadd('s', ({args1})*-1, {left})"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"datediff('s',{args1},{left})"; + case "ToString": return exp.Arguments.Count == 0 ? $"format({left},'yyyy-mm-dd HH:mm:ss')" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; + case "FromSeconds": return $"({getExp(exp.Arguments[0])})"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; + case "Parse": return MsAccessUtils.GetCastSql(getExp(exp.Arguments[0]), typeof(long)); + case "ParseExact": + case "TryParse": + case "TryParseExact": return MsAccessUtils.GetCastSql(getExp(exp.Arguments[0]), typeof(long)); + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return MsAccessUtils.GetCastSql(left, typeof(string)); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null && exp.Method.DeclaringType == typeof(Convert)) + { + var retBefore = getExp(exp.Arguments[0]); + var retAfter = MsAccessUtils.GetCastSql(retBefore, exp.Method.ReturnType.NullableTypeOrThis()); + if (retBefore != retAfter) return retAfter; + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs new file mode 100644 index 00000000..8c75f086 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs @@ -0,0 +1,60 @@ +using FreeSql.MsAccess.Curd; +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.MsAccess +{ + + public class MsAccessProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new MsAccessSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new MsAccessSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new MsAccessInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new MsAccessUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new MsAccessUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new MsAccessDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new MsAccessDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); + public MsAccessProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new MsAccessUtils(this); + this.InternalCommonExpression = new MsAccessExpression(this.InternalCommonUtils); + + this.Ado = new MsAccessAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.CodeFirst = new MsAccessCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + + ~MsAccessProvider() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs new file mode 100644 index 00000000..c52df2e6 --- /dev/null +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -0,0 +1,126 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.OleDb; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.MsAccess +{ + + public class MsAccessUtils : CommonUtils + { + public MsAccessUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = new OleDbParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OleDbType = (OleDbType)tp.Value; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = new OleDbParameter { ParameterName = $"@{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OleDbType = (OleDbType)tp.Value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatAccess(args); + public override string QuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; + } + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"iif(isnull({sql}), {value}, {sql})"; + public override string StringConcat(string[] objs, Type[] types) + { + var sb = new StringBuilder(); + var news = new string[objs.Length]; + for (var a = 0; a < objs.Length; a++) + { + if (types[a] == typeof(string)) news[a] = objs[a]; + else news[a] = MsAccessUtils.GetCastSql(objs[a], typeof(string)); + } + return string.Join(" + ", news); + } + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} mod {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "now()"; + public override string NowUtc => "now()"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string FieldAsAlias(string alias) => $" as {alias}"; + public override string IIF(string test, string ifTrue, string ifElse) => $"iif({test}, {ifTrue}, {ifElse})"; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) + { + var bytes = value as byte[]; + var sb = new StringBuilder().Append("0x"); + foreach (var vc in bytes) + { + if (vc < 10) sb.Append("0"); + sb.Append(vc.ToString("X")); + } + return sb.ToString(); + } + else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}"; + } + return FormatSql("{0}", value, 1); + } + + public static string GetCastSql(string sqlExp, Type toType) + { + switch (toType.ToString()) + { + case "System.Boolean": return $"(cstr({sqlExp}) not in ('0','false'))"; + case "System.Byte": return $"cbyte({sqlExp})"; + case "System.Char": return $"left(cstr({sqlExp}),1)"; + case "System.DateTime": return $"cdate({sqlExp})"; + case "System.Decimal": return $"ccur({sqlExp})"; + case "System.Double": return $"cdbl({sqlExp})"; + case "System.Int16": return $"cint({sqlExp})"; + case "System.Int32": return $"cint({sqlExp})"; + case "System.Int64": return $"clng({sqlExp})"; + case "System.SByte": return $"cint({sqlExp})"; + case "System.Single": return $"csng({sqlExp})"; + case "System.String": return $"cstr({sqlExp})"; + case "System.UInt16": return $"cint({sqlExp})"; + case "System.UInt32": return $"clng({sqlExp})"; + case "System.UInt64": return $"clng({sqlExp})"; + case "System.Guid": return $"cstr({sqlExp})"; + } + return sqlExp; + } + } +} diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index 62ec1bd3..f492d3ca 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -33,7 +33,6 @@ namespace FreeSql.MySql } } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index ed749b48..7fa731c7 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -32,7 +32,6 @@ namespace FreeSql.Odbc.Dameng } } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index 69fdce7d..cd8a016a 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -34,7 +34,6 @@ namespace FreeSql.Odbc.Default } OdbcAdapter Adapter => (_util == null ? FreeSqlOdbcGlobalExtensions.DefaultOdbcAdapter : _util._orm.GetOdbcAdapter()); - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs index 8129aafe..058e742b 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs @@ -34,7 +34,6 @@ namespace FreeSql.Odbc.GBase } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 7f454fb0..810fbf3c 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -33,7 +33,6 @@ namespace FreeSql.Odbc.MySql } } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index b3d53183..d13b2bb9 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -32,7 +32,6 @@ namespace FreeSql.Odbc.Oracle } } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index cdd1269e..fc3c6823 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -34,7 +34,6 @@ namespace FreeSql.Odbc.PostgreSQL } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index a9661dc8..a22adce1 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -34,7 +34,6 @@ namespace FreeSql.Odbc.SqlServer } } - static DateTime dt1970 = new DateTime(1970, 1, 1); string[] ncharDbTypes = new[] { "NVARCHAR", "NCHAR", "NTEXT" }; public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 289b95f4..50beedec 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -32,7 +32,6 @@ namespace FreeSql.Oracle } } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index 1dca64d1..7f6da042 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -35,7 +35,6 @@ namespace FreeSql.PostgreSQL } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index d589b9b4..c6d37238 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -31,7 +31,6 @@ namespace FreeSql.Sqlite } } } - static DateTime dt1970 = new DateTime(1970, 1, 1); public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 9ce4376f..fa1a718d 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -216,7 +216,7 @@ namespace FreeSql.Sqlite { var dbcolumnName = string.Concat(dbcolumn[2]); var isDesc = dbIndexesSql.IndexOf($@"{dbcolumnName}"" DESC", StringComparison.CurrentCultureIgnoreCase) == -1 ? "0" : "1"; - dsuk.Add(new[] { dbcolumnName, string.Concat(dbIndex[1]), isDesc, string.Concat(dbIndex[2]) }); ; + dsuk.Add(new[] { dbcolumnName, string.Concat(dbIndex[1]), isDesc, string.Concat(dbIndex[2]) }); } } foreach (var uk in tb.Indexes) @@ -238,7 +238,6 @@ namespace FreeSql.Sqlite var tablenameOnlyTb = tboldname == null ? _commonUtils.QuoteSqlName(tbname[1]) : _commonUtils.QuoteSqlName(tboldname[1]); var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}._FreeSqlTmp_{tbname[1]}"); //创建临时表 - //创建表 isIndent = false; sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 5e4a8abb..138056e9 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -28,7 +28,7 @@ namespace FreeSql.Sqlite public IAdo Ado { get; } public IAop Aop { get; } public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst => null; + public IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); public SqliteProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new SqliteUtils(this); diff --git a/readme.md b/readme.md index 473aecee..cd3468ca 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; - [x] 支持 同步/异步数据库操作方法; - [x] 支持 读写分离、分表分库,租户设计,过滤器,乐观锁; -- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库; +- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库/Access; | | | | - | - | From ea7a8609c87d13b263a3c0f0ac465931a093e5f7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 24 Dec 2019 06:32:41 +0800 Subject: [PATCH 0368/1029] debug mysql tests --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 2 +- .../FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs | 2 +- FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 953f6479..607fcc57 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1050,7 +1050,7 @@ LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId` WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12); var grouplist12 = g.mysql.Select() - .AsTable((type, old) => $"( {sqltmp12} )") + .AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null) .LeftJoin((a, p) => p.Id == a.ProcessId) .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) .ToList((a, p) => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 78f2f6e3..4be159dc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1061,7 +1061,7 @@ LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId` WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12); var grouplist12 = g.mysql.Select() - .AsTable((type, old) => $"( {sqltmp12} )") + .AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null) .LeftJoin((a, p) => p.Id == a.ProcessId) .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) .ToList((a, p) => new diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 74b7b809..7a71bc05 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1109,7 +1109,7 @@ LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId` WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12); var grouplist12 = g.mysql.Select() - .AsTable((type, old) => $"( {sqltmp12} )") + .AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null) .LeftJoin((a, p) => p.Id == a.ProcessId) .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) .ToList((a, p) => new From a664bc41bc0bef1634b6153612fa21d9091b5c04 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 25 Dec 2019 18:27:45 +0800 Subject: [PATCH 0369/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20ExpressionCa?= =?UTF-8?q?ll=20=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 1 + .../ExpressionCallAttribute.cs | 44 ++++- FreeSql/FreeSql.xml | 150 ++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 14 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 10 +- .../AdoProvider/AdoProviderAsync.cs | 8 +- 7 files changed, 215 insertions(+), 19 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 82594730..d97e28fc 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -13,6 +13,7 @@ using System.ComponentModel.DataAnnotations; using System.Threading; using System.Data.SqlClient; using kwlib; +using System.Text; namespace FreeSql.Tests { diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs index 4342ff13..6970eca9 100644 --- a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs +++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs @@ -1,6 +1,9 @@ -using System; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data.Common; +using System.Linq.Expressions; using System.Text; namespace FreeSql.DataAnnotations @@ -23,6 +26,15 @@ namespace FreeSql.DataAnnotations public class ExpressionCallContext { + internal ExpressionCallContext() + { + Utility = new DefaultUtility { _context = this }; + } + + public IUtility Utility { get; } + + internal CommonExpression _commonExp; + internal CommonExpression.ExpTSC _tsc; /// /// 数据库类型,可用于适配多种数据库环境 /// @@ -32,6 +44,10 @@ namespace FreeSql.DataAnnotations /// 已解析的表达式中参数内容 /// public Dictionary ParsedContent { get; } = new Dictionary(); + /// + /// 表达式原始值 + /// + public Dictionary RawExpression { get; } = new Dictionary(); /// /// 主对象的参数化对象,可重塑其属性 @@ -53,5 +69,31 @@ namespace FreeSql.DataAnnotations /// 返回表达式函数表示的 SQL 字符串 /// public string Result { get; set; } + + public interface IUtility + { + /// + /// 获取实体元数据 + /// + /// + /// + TableInfo GetTableByEntity(Type entityType); + + /// + /// 解析表达式 + /// + /// + /// + string ParseExpression(Expression exp); + } + + class DefaultUtility : IUtility + { + internal ExpressionCallContext _context; + + public TableInfo GetTableByEntity(Type entityType) => _context?._commonExp._common.GetTableByEntity(entityType); + + public string ParseExpression(Expression exp) => _context?._commonExp.ExpressionLambdaToSql(exp, _context._tsc.CloneDisableDiyParse()); + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b6056f16..13ec6385 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -219,6 +219,11 @@ 已解析的表达式中参数内容 + + + 表达式原始值 + + 主对象的参数化对象,可重塑其属性 @@ -240,6 +245,20 @@ 返回表达式函数表示的 SQL 字符串 + + + 获取实体元数据 + + + + + + + 解析表达式 + + + + 索引名 @@ -2205,6 +2224,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 }) + + + + + + 可自定义解析表达式 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 1d68f397..a6beb913 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -602,15 +602,25 @@ namespace FreeSql.Internal exp3.Method.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any() )) { - var ecc = new ExpressionCallContext { DataType = _ado.DataType, UserParameters = tsc.dbParams == null ? null : new List(), FormatSql = obj => formatSql(obj, null, null, null) }; + var ecc = new ExpressionCallContext { + _commonExp = this, + _tsc = tsc, + DataType = _ado.DataType, + UserParameters = tsc.dbParams == null ? null : new List(), + FormatSql = obj => formatSql(obj, null, null, null) + }; var exp3MethodParams = exp3.Method.GetParameters(); var dbParamsIndex = tsc.dbParams?.Count; - ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null: ExpressionLambdaToSql(exp3.Arguments[0], tsc)); + ecc.RawExpression.Add(exp3MethodParams[0].Name, exp3.Arguments[0]); + ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[0], tsc)); if (tsc.dbParams?.Count > dbParamsIndex) ecc.DbParameter = tsc.dbParams.Last(); List oldDbParams = tsc.SetDbParamsReturnOld(null); for (var a = 1; a < exp3.Arguments.Count; a++) if (exp3.Arguments[a].Type != typeof(ExpressionCallContext)) + { + ecc.RawExpression.Add(exp3MethodParams[a].Name, exp3.Arguments[a]); ecc.ParsedContent.Add(exp3MethodParams[a].Name, exp3MethodParams[a].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[a], tsc)); + } tsc.SetDbParamsReturnOld(oldDbParams); var exp3InvokeParams = new object[exp3.Arguments.Count]; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 3c0e3054..11299db6 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -78,7 +78,7 @@ namespace FreeSql.Internal.CommonProvider cmd.Parameters.Clear(); if (isThrowException) { - cmd.Dispose(); + if (DataType == DataType.Sqlite) cmd.Dispose(); throw e; } } @@ -575,7 +575,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); - pc.cmd.Dispose(); + if (DataType == DataType.Sqlite) pc.cmd.Dispose(); ExecuteReaderMultiple(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); return; } @@ -638,7 +638,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(pool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); - pc.cmd.Dispose(); + if (DataType == DataType.Sqlite) pc.cmd.Dispose(); } public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); @@ -739,7 +739,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); - pc.cmd.Dispose(); + if (DataType == DataType.Sqlite) pc.cmd.Dispose(); return val; } public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); @@ -775,7 +775,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); - pc.cmd.Dispose(); + if (DataType == DataType.Sqlite) pc.cmd.Dispose(); return val; } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index efe6cd71..694ac18c 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -504,7 +504,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); - pc.cmd.Dispose(); + if (DataType == DataType.Sqlite) pc.cmd.Dispose(); await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); return; } @@ -567,7 +567,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(pool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); - pc.cmd.Dispose(); + if (DataType == DataType.Sqlite) pc.cmd.Dispose(); } public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); @@ -669,7 +669,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); - pc.cmd.Dispose(); + if (DataType == DataType.Sqlite) pc.cmd.Dispose(); return val; } public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); @@ -705,7 +705,7 @@ namespace FreeSql.Internal.CommonProvider } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); - pc.cmd.Dispose(); + if (DataType == DataType.Sqlite) pc.cmd.Dispose(); return val; } From c03a8c7b798d19b835e9ff3a564c616749e8da85 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 25 Dec 2019 20:50:56 +0800 Subject: [PATCH 0370/1029] ## v1.0.0 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- readme.md | 10 ++++------ 16 files changed, 19 insertions(+), 21 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b5580902..f245cee8 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.12.21 + 1.0.0 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 64880c4e..9d322a96 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 14bcca23..99caf79a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 2304f4fd..4235f29d 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 0.12.21 + 1.0.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2a978474..bbed01ca 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 23dd38fa..41577a7e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1ad59ab7..98df7eab 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 1f157363..222eeaf2 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 1dc21b5c..79a2a23e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 714dca1c..65d492bd 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e38abfb8..dc0a1669 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8c14ece6..86906bfc 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 9c8fd3ae..787a7ac6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d5c762a7..9b41cd59 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 812042ff..456cba14 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 0.12.21 + 1.0.0 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin diff --git a/readme.md b/readme.md index cd3468ca..0d93c231 100644 --- a/readme.md +++ b/readme.md @@ -8,14 +8,12 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ # Features -- [x] 支持 CodeFirst 迁移; +- [x] 支持 CodeFirst 迁移,哪怕使用 Access 数据库也支持; - [x] 支持 DbFirst 从数据库导入实体类,[安装实体类生成工具](https://github.com/2881099/FreeSql/wiki/DbFirst); -- [x] 大量采用 ExpressionTree 提升性能; - [x] 支持 深入的类型映射,比如pgsql的数组类型; -- [x] 支持 丰富的表达式函数; +- [x] 支持 丰富的表达式函数,以及灵活的自定义解析; - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; -- [x] 支持 同步/异步数据库操作方法; -- [x] 支持 读写分离、分表分库,租户设计,过滤器,乐观锁; +- [x] 支持 读写分离、分表分库,租户设计,过滤器,乐观锁,悲观锁; - [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库/Access; | | | @@ -90,7 +88,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ > dotnet add package FreeSql.Provider.Sqlite ```csharp -IFreeSql fsql = new FreeSql.FreeSqlBuilder() +static IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") .UseAutoSyncStructure(true) //自动同步实体结构到数据库 From 5a6d96df9d5582c35a7a14a6838e0f9301574f22 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Thu, 26 Dec 2019 16:48:11 +0800 Subject: [PATCH 0371/1029] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 ++++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/custom.md | 23 +++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/custom.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dd84ea78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 00000000..148222c4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,23 @@ +--- +name: Custom issue template +about: 标题内容 +title: '' +labels: '' +assignees: '' + +--- + +## 环境描述 + +系统: Linux/Windows +数据库:SqlServer/MySql/PostgreSQL/Oracle/Sqlite/MsAccess/达梦 + +## 问题描述 + +** 提高有效沟涌方式,尽量把过程描述清楚 ** + +** 使用 markdown 语法 ** + +```csharp +//这里放置 c# 代码,增加阅读性 +``` From b3ed6989aa52304c7317fc61c68b5dfeed07655b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Dec 2019 16:50:17 +0800 Subject: [PATCH 0372/1029] update issues template --- .github/ISSUE_TEMPLATE/bug_report.md | 38 ------------------------ FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 16 ++++++++++ 3 files changed, 23 insertions(+), 38 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index dd84ea78..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] - -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] - -**Additional context** -Add any other context about the problem here. diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 0fba1c0e..93ce4d45 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -14,6 +14,7 @@ using System.Threading; using System.Data.SqlClient; using kwlib; using System.Diagnostics; +using System.IO; namespace FreeSql.Tests { @@ -43,6 +44,21 @@ namespace FreeSql.Tests // fsql.Select().ToList(); //} + //var testByte = new TestByte { pic = File.ReadAllBytes(@"C:\Users\28810\Desktop\github\FreeSql\functions06.png") }; + //var sql = g.sqlserver.Insert(testByte).NoneParameter().ToSql(); + //g.sqlserver.Insert(testByte).ExecuteAffrows(); + + //var getTestByte = g.sqlserver.Select(testByte).First(); + + //File.WriteAllBytes(@"C:\Users\28810\Desktop\github\FreeSql\functions06_write.png", getTestByte.pic); + } + + class TestByte + { + public Guid id { get; set; } + + [Column(DbType = "varbinary(max)")] + public byte[] pic { get; set; } } class ut3_t1 From 14204d22a463bd2dd37aa6f925878e294c594126 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Dec 2019 17:06:16 +0800 Subject: [PATCH 0373/1029] update ISSUE_TEMPLATE --- .github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md | 61 ++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/custom.md | 23 --------- 2 files changed, 61 insertions(+), 23 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md delete mode 100644 .github/ISSUE_TEMPLATE/custom.md diff --git a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..0af344a2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md @@ -0,0 +1,61 @@ +##### 问题描述 + +```csharp +// c# 代码段 +``` + + +##### 重现问题步骤(如果可以) + +1. ... +2. ... + + +##### 发现问题的模块 + +- [ ] FreeSql 版本: +- [ ] FreeSql.Provider.?? +- [ ] FreeSql.Repository +- [ ] FreeSql.DbContext + + +##### 模块对应的 .net 版本 + +- [ ] .net 4.0 +- [ ] .net 4.5 +- [ ] .net 4.6 +- [ ] .net 4.7 +- [ ] .net standard 2.0 +- [ ] .net core 2.x +- [x] .net core 3.x + + +##### 数据库环境 + +- [x] MySql,版本: +- [ ] SqlServer,版本: +- [ ] PostgreSQL,版本: +- [ ] Oracle,版本: +- [ ] Sqlite +- [ ] Access,版本: +- [ ] 达梦,版本: + + +##### 开发环境 + +- [ ] Visual Studio 2015 +- [ ] Visual Studio 2017 +- [x] Visual Studio 2019 +- [ ] Visual Studio Code +- [ ] 其他: + + +##### 系统环境 + +- [x] Windows,版本: +- [ ] Linux,版本: +- [ ] Mac,版本: +- [ ] 其他: + + +> 发布问题后,请保持对 issue 的关注,有时会有需要进一步沟通的信息,很长时间内没有得到答复的 issue 将被关闭。 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md deleted file mode 100644 index 148222c4..00000000 --- a/.github/ISSUE_TEMPLATE/custom.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: Custom issue template -about: 标题内容 -title: '' -labels: '' -assignees: '' - ---- - -## 环境描述 - -系统: Linux/Windows -数据库:SqlServer/MySql/PostgreSQL/Oracle/Sqlite/MsAccess/达梦 - -## 问题描述 - -** 提高有效沟涌方式,尽量把过程描述清楚 ** - -** 使用 markdown 语法 ** - -```csharp -//这里放置 c# 代码,增加阅读性 -``` From 9aee4ba4d60a06fdf4fa854cfeabde59df7057e3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Dec 2019 13:57:19 +0800 Subject: [PATCH 0374/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20NoneParamete?= =?UTF-8?q?r=20=E6=97=A0=E5=8F=82=E5=AF=B9=20byte[]=20=E4=BA=8C=E8=BF=9B?= =?UTF-8?q?=E5=88=B6=E6=8B=BC=E6=8E=A5=E7=9A=84=20bug=EF=BC=9B#170?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 6 +- FreeSql/FreeSql.xml | 288 ++++++++++-------- .../MsAccessUtils.cs | 5 +- .../FreeSql.Provider.MySql/MySqlUtils.cs | 5 +- .../MySqlConnectorUtils.cs | 5 +- .../Dameng/OdbcDamengUtils.cs | 5 +- .../Default/OdbcAdapter.cs | 5 +- .../GBase/__OdbcGBaseUtils.cs | 5 +- .../MySql/OdbcMySqlUtils.cs | 5 +- .../Oracle/OdbcOracleUtils.cs | 5 +- .../PostgreSQL/OdbcPostgreSQLUtils.cs | 5 +- .../SqlServer/OdbcSqlServerUtils.cs | 5 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 5 +- .../PostgreSQLUtils.cs | 5 +- .../SqlServerUtils.cs | 5 +- 16 files changed, 173 insertions(+), 193 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 93ce4d45..235f8eb4 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -44,13 +44,13 @@ namespace FreeSql.Tests // fsql.Select().ToList(); //} - //var testByte = new TestByte { pic = File.ReadAllBytes(@"C:\Users\28810\Desktop\github\FreeSql\functions06.png") }; + //var testByte = new TestByte { pic = File.ReadAllBytes(@"C:\Users\28810\Desktop\71500003-0ad69400-289e-11ea-85cb-36a54f52ebc0.png") }; //var sql = g.sqlserver.Insert(testByte).NoneParameter().ToSql(); - //g.sqlserver.Insert(testByte).ExecuteAffrows(); + //g.sqlserver.Insert(testByte).NoneParameter().ExecuteAffrows(); //var getTestByte = g.sqlserver.Select(testByte).First(); - //File.WriteAllBytes(@"C:\Users\28810\Desktop\github\FreeSql\functions06_write.png", getTestByte.pic); + //File.WriteAllBytes(@"C:\Users\28810\Desktop\71500003-0ad69400-289e-11ea-85cb-36a54f52ebc0_write.png", getTestByte.pic); } class TestByte diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 13ec6385..d2213da2 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2224,137 +2224,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3133,3 +3002,160 @@ +unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs index c52df2e6..b0798d2a 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -85,10 +85,7 @@ namespace FreeSql.MsAccess var bytes = value as byte[]; var sb = new StringBuilder().Append("0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.ToString(); } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 15d4dec4..4e5ea4b0 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -126,10 +126,7 @@ namespace FreeSql.MySql var bytes = value as byte[]; var sb = new StringBuilder().Append("0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index d4e9f674..202eb9f1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -134,10 +134,7 @@ namespace FreeSql.MySql var bytes = value as byte[]; var sb = new StringBuilder().Append("0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index 5d86bb05..065081d9 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -101,10 +101,7 @@ namespace FreeSql.Odbc.Dameng var bytes = value as byte[]; var sb = new StringBuilder().Append("rawtohex('0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.Append("')").ToString(); } return FormatSql("{0}", value, 1); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs index ddddb518..9ac1d070 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs @@ -58,10 +58,7 @@ namespace FreeSql.Odbc.Default var bytes = value as byte[]; var sb = new StringBuilder().Append("0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs index ee39daff..3382ae3e 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs @@ -129,10 +129,7 @@ namespace FreeSql.Odbc.GBase var bytes = value as byte[]; var sb = new StringBuilder().Append("'\\x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); } else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 7222f2e2..20917791 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -97,10 +97,7 @@ namespace FreeSql.Odbc.MySql var bytes = value as byte[]; var sb = new StringBuilder().Append("0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index e851589e..5880ea5a 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -101,10 +101,7 @@ namespace FreeSql.Odbc.Oracle var bytes = value as byte[]; var sb = new StringBuilder().Append("rawtohex('0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.Append("')").ToString(); } return FormatSql("{0}", value, 1); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 365f9eab..5d2559ce 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -129,10 +129,7 @@ namespace FreeSql.Odbc.PostgreSQL var bytes = value as byte[]; var sb = new StringBuilder().Append("'\\x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); } else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index bdd06913..612facff 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -88,10 +88,7 @@ namespace FreeSql.Odbc.SqlServer var bytes = value as byte[]; var sb = new StringBuilder().Append("0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.ToString(); } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 570c4c0f..64388b4a 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -96,10 +96,7 @@ namespace FreeSql.Oracle var bytes = value as byte[]; var sb = new StringBuilder().Append("rawtohex('0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.Append("')").ToString(); } return FormatSql("{0}", value, 1); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index a0c015f1..0910d9cc 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -161,10 +161,7 @@ namespace FreeSql.PostgreSQL var bytes = value as byte[]; var sb = new StringBuilder().Append("'\\x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); } else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index bf66c1b1..9d76798e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -99,10 +99,7 @@ namespace FreeSql.SqlServer var bytes = value as byte[]; var sb = new StringBuilder().Append("0x"); foreach (var vc in bytes) - { - if (vc < 10) sb.Append("0"); - sb.Append(vc.ToString("X")); - } + sb.Append(vc.ToString("X").PadLeft(2, '0')); return sb.ToString(); } else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) From 20ffad0ba37a8973de0ac5558c60ae89299f9b42 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 28 Dec 2019 00:35:11 +0800 Subject: [PATCH 0375/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=E8=BF=9E=E6=8E=A5=E6=B1=A0=E4=B8=BA=20+5=EF=BC=88?= =?UTF-8?q?=E5=B1=9E=E4=BA=8E=E5=86=85=E9=83=A8=E8=AE=BE=E7=BD=AE=EF=BC=89?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs | 2 +- .../Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs | 2 +- .../Default/OdbcAdo/OdbcConnectionPool.cs | 2 +- .../GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs | 2 +- .../MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs | 2 +- .../Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs | 2 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs | 2 +- .../SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs | 2 +- .../FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs | 2 +- .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 2 +- .../SqlServerAdo/SqlServerConnectionPool.cs | 4 ++-- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index e8bbc3fc..9e0da560 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -65,7 +65,7 @@ namespace FreeSql.MySql var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index f6d7eede..f7dd707d 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -87,7 +87,7 @@ namespace FreeSql.Odbc.Dameng var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs index 42d702a7..c8eb1bcb 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -70,7 +70,7 @@ namespace FreeSql.Odbc.Default var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs index b22e01e5..06db5358 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.GBase var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs index 9ad71a17..1caf9501 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -65,7 +65,7 @@ namespace FreeSql.Odbc.MySql var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index 31d23008..fecf7793 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -87,7 +87,7 @@ namespace FreeSql.Odbc.Oracle var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index 69688f14..c387559d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -77,7 +77,7 @@ namespace FreeSql.Odbc.PostgreSQL var pattern = @"Max(imum)?\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[2].Value, out var poolsize) == false || poolsize <= 0) poolsize = 50; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs index 6a2516a6..ef9843bd 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -70,7 +70,7 @@ namespace FreeSql.Odbc.SqlServer var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index f28debbc..eb8c0e0e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -87,7 +87,7 @@ namespace FreeSql.Oracle var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index d9694fbe..4297e35e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -77,7 +77,7 @@ namespace FreeSql.PostgreSQL var pattern = @"Max(imum)?\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[2].Value, out var poolsize) == false || poolsize <= 0) poolsize = 50; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) : diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 6911e681..42663a0a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -70,8 +70,8 @@ namespace FreeSql.SqlServer var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1); - PoolSize = poolsize + connStrIncr; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); + PoolSize = poolsize +connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : $"{_connectionString};Max pool size={PoolSize}"; From 8cb7ef2130dda9ce8982d596a6902345ad8dc46f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Dec 2019 15:30:43 +0800 Subject: [PATCH 0376/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20EfCoreFluent?= =?UTF-8?q?Api=20=E6=89=A9=E5=B1=95=E5=8C=85=EF=BC=8C=E6=8E=A5=E8=BF=91=20?= =?UTF-8?q?efcore=20fluentApi=20=E7=9A=84=E4=BD=BF=E7=94=A8=E4=B9=A0?= =?UTF-8?q?=E6=83=AF=EF=BC=9B#4=20-=20=E5=A2=9E=E5=8A=A0=20ColumnAttribute?= =?UTF-8?q?=20=E5=B1=9E=E6=80=A7=20InsertValueSql=EF=BC=8C=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E6=95=B0=E6=8D=AE=E7=9A=84=E6=97=B6=E5=80=99=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E7=94=A8=20sql=20=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EfCoreColumnFluent.cs | 54 +++ .../EfCoreTableFluent.cs | 312 ++++++++++++++++++ .../FreeSql.Extensions.EfCoreFluentApi.csproj | 34 ++ .../ICodeFirstExtensions.cs | 37 +++ FreeSql.DbContext/FreeSql.DbContext.xml | 7 + .../FreeSql.Tests/FreeSql.Tests.csproj | 1 + FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 33 ++ FreeSql.sln | 15 + FreeSql/DataAnnotations/ColumnAttribute.cs | 6 + FreeSql/DataAnnotations/ColumnFluent.cs | 12 + FreeSql/DataAnnotations/TableFluent.cs | 50 ++- FreeSql/FreeSql.xml | 311 +++++++++-------- FreeSql/Internal/CommonUtils.cs | 7 +- FreeSql/Internal/UtilsExpressionTree.cs | 5 + 14 files changed, 721 insertions(+), 163 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs create mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs create mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj create mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs new file mode 100644 index 00000000..2a9cb547 --- /dev/null +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using FreeSql.DataAnnotations; + +namespace FreeSql.Extensions.EfCoreFluentApi +{ + public class EfCoreColumnFluent + { + ColumnFluent _cf; + + internal EfCoreColumnFluent(ColumnFluent tf) + { + _cf = tf; + } + + public ColumnFluent Help() => _cf; + + public EfCoreColumnFluent HasColumnName(string name) + { + _cf.Name(name); + return this; + } + public EfCoreColumnFluent HashColumnType(string dbtype) + { + _cf.DbType(dbtype); + return this; + } + public EfCoreColumnFluent IsRequired() + { + _cf.IsNullable(false); + return this; + } + public EfCoreColumnFluent HasMaxLength(int length) + { + _cf.StringLength(length); + return this; + } + public EfCoreColumnFluent HasDefaultValueSql(string sqlValue) + { + _cf.InsertValueSql(sqlValue); + return this; + } + public EfCoreColumnFluent IsRowVersion() + { + _cf.IsVersion(true); + return this; + } + //public EfCoreColumnFluent HasConversion(Func stringify, Func parse) + //{ + // return this; + //} + } +} diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs new file mode 100644 index 00000000..b914fbab --- /dev/null +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs @@ -0,0 +1,312 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using FreeSql.DataAnnotations; + +namespace FreeSql.Extensions.EfCoreFluentApi +{ + public class EfCoreTableFluent + { + TableFluent _tf; + internal EfCoreTableFluent(TableFluent tf) + { + _tf = tf; + } + + public EfCoreTableFluent ToTable(string name) + { + _tf.Name(name); + return this; + } + public EfCoreTableFluent ToView(string name) + { + _tf.DisableSyncStructure(true); + _tf.Name(name); + return this; + } + + public EfCoreColumnFluent Property(Expression> property) => new EfCoreColumnFluent(_tf.Property(property)); + public EfCoreColumnFluent Property(string property) => new EfCoreColumnFluent(_tf.Property(property)); + + public TableFluent Help() => _tf; + + #region HasKey + public EfCoreTableFluent HasKey(Expression> key) + { + if (key?.Body == null) return this; + var exp = key.Body; + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _tf.Property((exp as MemberExpression).Member.Name).IsPrimary(true); + break; + case ExpressionType.New: + foreach (var member in (exp as NewExpression).Members) + _tf.Property(member.Name).IsPrimary(true); + break; + } + return this; + } + #endregion + + #region HasIndex + public HasIndexFluent HasIndex(Expression> index) + { + if (index?.Body == null) throw new ArgumentException("参数错误 index 不能为 null"); + var exp = index.Body; + + var indexName = $"idx_{Guid.NewGuid().ToString("N").Substring(0, 8)}"; + var columns = new List(); + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + columns.Add((exp as MemberExpression).Member.Name); + break; + case ExpressionType.New: + foreach (var member in (exp as NewExpression).Members) + columns.Add(member.Name); + break; + } + _tf.Index(indexName, string.Join(", ", columns), false); + return new HasIndexFluent(_tf, indexName, columns); + } + public class HasIndexFluent + { + TableFluent _modelBuilder; + string _indexName; + List _columns; + bool _isUnique; + + internal HasIndexFluent(TableFluent modelBuilder, string indexName, List columns) + { + _modelBuilder = modelBuilder; + _indexName = indexName; + _columns = columns; + } + public HasIndexFluent IsUnique() + { + _isUnique = true; + _modelBuilder.Index(_indexName, string.Join(", ", _columns), _isUnique); + return this; + } + public HasIndexFluent HasName(string name) + { + _modelBuilder.IndexRemove(_indexName); + _indexName = name; + _modelBuilder.Index(_indexName, string.Join(", ", _columns), _isUnique); + return this; + } + } + #endregion + + #region HasOne + public HasOneFluent HasOne(Expression> one) + { + if (one?.Body == null) throw new ArgumentException("参数错误 one 不能为 null"); + var exp = one.Body; + + var oneProperty = ""; + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + oneProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(oneProperty)) throw new ArgumentException("参数错误 one"); + return new HasOneFluent(_tf, oneProperty); + } + public class HasOneFluent + { + TableFluent _tf; + string _selfProperty; + string _selfBind; + string _withManyProperty; + string _withOneProperty; + string _withOneBind; + + internal HasOneFluent(TableFluent modelBuilder, string oneProperty) + { + _tf = modelBuilder; + _selfProperty = oneProperty; + } + public HasOneFluent WithMany(Expression> many) + { + if (many?.Body == null) throw new ArgumentException("参数错误 many 不能为 null"); + var exp = many.Body; + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withManyProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(_withManyProperty)) throw new ArgumentException("参数错误 many"); + if (string.IsNullOrEmpty(_selfBind) == false) + _tf.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); + return this; + } + public HasOneFluent WithOne(Expression> one, Expression> foreignKey) + { + if (one?.Body == null) throw new ArgumentException("参数错误 one 不能为 null"); + var exp = one.Body; + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withOneProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(_withOneProperty)) throw new ArgumentException("参数错误 one"); + + if (foreignKey?.Body == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + exp = foreignKey.Body; + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withOneBind = (exp as MemberExpression).Member.Name; + _withOneBind = _withOneBind.TrimStart(',', ' '); + break; + case ExpressionType.New: + _withOneBind = ""; + foreach (var member in (exp as NewExpression).Members) + _withOneBind += ", " + member.Name; + _withOneBind = _withOneBind.TrimStart(',', ' '); + break; + } + if (string.IsNullOrEmpty(_withOneBind)) throw new ArgumentException("参数错误 foreignKey"); + if (string.IsNullOrEmpty(_selfBind) == false) + _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); + return this; + } + public HasOneFluent HasForeignKey(Expression> foreignKey) + { + if (foreignKey?.Body == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + var exp = foreignKey.Body; + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _selfBind = (exp as MemberExpression).Member.Name; + _selfBind = _selfBind.TrimStart(',', ' '); + break; + case ExpressionType.New: + _selfBind = ""; + foreach (var member in (exp as NewExpression).Members) + _selfBind += ", " + member.Name; + _selfBind = _selfBind.TrimStart(',', ' '); + break; + } + if (string.IsNullOrEmpty(_selfBind)) throw new ArgumentException("参数错误 foreignKey"); + _tf.Navigate(_selfProperty, _selfBind); + if (string.IsNullOrEmpty(_withManyProperty) == false) + _tf.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); + if (string.IsNullOrEmpty(_withOneProperty) == false && string.IsNullOrEmpty(_withOneBind) == false) + _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); + return this; + } + } + #endregion + + #region HasMany + public HasManyFluent HasMany(Expression>> many) + { + if (many?.Body == null) throw new ArgumentException("参数错误 many 不能为 null"); + var exp = many.Body; + + var manyProperty = ""; + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + manyProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(manyProperty)) throw new ArgumentException("参数错误 many"); + return new HasManyFluent(_tf, manyProperty); + } + public class HasManyFluent + { + TableFluent _tf; + string _selfProperty; + string _selfBind; + string _withOneProperty; + string _withManyProperty; + + internal HasManyFluent(TableFluent modelBuilder, string manyProperty) + { + _tf = modelBuilder; + _selfProperty = manyProperty; + } + + public void WithMany(Expression>> many, Type middleType) + { + if (many?.Body == null) throw new ArgumentException("参数错误 many 不能为 null"); + var exp = many.Body; + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withManyProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(_withManyProperty)) throw new ArgumentException("参数错误 many"); + + _tf.Navigate(_selfProperty, null, middleType); + _tf.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, null, middleType)); + } + public HasManyFluent WithOne(Expression> one) + { + if (one?.Body == null) throw new ArgumentException("参数错误 one 不能为 null"); + var exp = one.Body; + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withOneProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(_withOneProperty)) throw new ArgumentException("参数错误 one"); + + if (string.IsNullOrEmpty(_selfBind) == false) + _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); + return this; + } + public HasManyFluent HasForeignKey(Expression> foreignKey) + { + if (foreignKey?.Body == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + var exp = foreignKey.Body; + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _selfBind = (exp as MemberExpression).Member.Name; + _selfBind = _selfBind.TrimStart(',', ' '); + break; + case ExpressionType.New: + _selfBind = ""; + foreach (var member in (exp as NewExpression).Members) + _selfBind += ", " + member.Name; + _selfBind = _selfBind.TrimStart(',', ' '); + break; + } + if (string.IsNullOrEmpty(_selfBind)) throw new ArgumentException("参数错误 foreignKey"); + _tf.Navigate(_selfProperty, _selfBind); + if (string.IsNullOrEmpty(_withOneProperty) == false) + _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); + return this; + } + } + #endregion + + public EfCoreTableFluent Ignore(Expression> property) + { + _tf.Property(property).IsIgnore(true); + return this; + } + //public EfCoreTableFluent HasData(T data) => HasData(new[] { data }); + //public EfCoreTableFluent HasData(IEnumerable data) + //{ + // return this; + //} + } +} diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj new file mode 100644 index 00000000..671086f8 --- /dev/null +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -0,0 +1,34 @@ + + + + netstandard2.0 + 1.0.0 + true + YeXiangQin + FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM;FluentApi + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + + + + + + + + FreeSql.Extensions.EfCoreFluentApi.xml + 3 + + + + + + + diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs new file mode 100644 index 00000000..e6799c46 --- /dev/null +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using FreeSql.DataAnnotations; + +namespace FreeSql.Extensions.EfCoreFluentApi +{ + public static class ICodeFirstExtensions + { + + static void Test() + { + ICodeFirst cf = null; + cf.Entity(eb => + { + eb.Property(b => b.Name).HashColumnType("varchar(50)"); + eb.Property(b => b.FullName).HashColumnType("varchar(60)"); + + eb.HasKey(a => a.Id).HasKey(a => new { a.Id, a.Name }); + eb.HasIndex(a => a.Name).IsUnique().HasName("idx_xxx11"); + }); + } + class TestInfo + { + public int Id { get; set; } + public string Name { get; set; } + public string FullName { get; set; } + public int DefaultValue { get; set; } + } + + public static ICodeFirst Entity(this ICodeFirst codeFirst, Action> modelBuilder) + { + codeFirst.ConfigEntity(tf => modelBuilder(new EfCoreTableFluent(tf))); + return codeFirst; + } + } +} diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 5d7edd8a..e2398841 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -12,6 +12,7 @@ + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 235f8eb4..ee8ef69d 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -51,6 +51,39 @@ namespace FreeSql.Tests //var getTestByte = g.sqlserver.Select(testByte).First(); //File.WriteAllBytes(@"C:\Users\28810\Desktop\71500003-0ad69400-289e-11ea-85cb-36a54f52ebc0_write.png", getTestByte.pic); + + var ib = new IdleBus(TimeSpan.FromMinutes(10), 2); + ib.Notice += (_, e2) => Trace.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] 线程{Thread.CurrentThread.ManagedThreadId}:{e2.Log}"); + + ib.Register("db1", () => new FreeSql.FreeSqlBuilder() + .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=3") + .UseAutoSyncStructure(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .UseLazyLoading(true) + .Build()); + ib.Register("db2", () => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=3") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseSyncStructureToUpper(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build()); + ib.Register("db3", () => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=3") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build()); + //...注入很多个 + + var fsql = ib.Get("db1"); //使用的时候用 Get 方法,不要存其引用关系 + fsql.Select().Limit(10).ToList(); + + fsql = ib.Get("db2"); + fsql.Select().Limit(10).ToList(); + + fsql = ib.Get("db3"); + fsql.Select().Limit(10).ToList(); } class TestByte diff --git a/FreeSql.sln b/FreeSql.sln index 9ac013cd..b4e15e7c 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -72,6 +72,8 @@ Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "FreeSql.Tests.VB", "FreeSql EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MsAccess", "Providers\FreeSql.Provider.MsAccess\FreeSql.Provider.MsAccess.csproj", "{B397A761-F646-41CF-A160-AB6C05DAF2FB}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.EfCoreFluentApi", "Extensions\FreeSql.Extensions.EfCoreFluentApi\FreeSql.Extensions.EfCoreFluentApi.csproj", "{773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -430,6 +432,18 @@ Global {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x64.Build.0 = Release|Any CPU {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x86.ActiveCfg = Release|Any CPU {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x86.Build.0 = Release|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|x64.ActiveCfg = Debug|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|x64.Build.0 = Debug|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|x86.ActiveCfg = Debug|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|x86.Build.0 = Debug|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|Any CPU.Build.0 = Release|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x64.ActiveCfg = Release|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x64.Build.0 = Release|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x86.ActiveCfg = Release|Any CPU + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -455,6 +469,7 @@ Global {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {B397A761-F646-41CF-A160-AB6C05DAF2FB} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 8eb5eb1e..96cc37b5 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -97,5 +97,11 @@ namespace FreeSql.DataAnnotations /// Sqlite -> text /// public int StringLength { get => _StringLength ?? 0; set => _StringLength = value; } + + /// + /// 执行 Insert 方法时使用此值 + /// 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + /// + public string InsertValueSql { get; set; } } } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index e5d6e13c..2a897e6f 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -158,5 +158,17 @@ namespace FreeSql.DataAnnotations _column.StringLength = value; return this; } + + /// + /// 执行 Insert 方法时使用此值 + /// 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + /// + /// + /// + public ColumnFluent InsertValueSql(string value) + { + _column.InsertValueSql = value; + return this; + } } } diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index e2b199d5..d36e0e2e 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -9,16 +9,21 @@ namespace FreeSql.DataAnnotations public class TableFluent { - public TableFluent(Type entityType, TableAttribute table) + public TableFluent(ICodeFirst codeFirst, Type entityType, TableAttribute table) { + _codeFirst = codeFirst; _entityType = entityType; _properties = _entityType.GetPropertiesDictIgnoreCase(); _table = table; } + ICodeFirst _codeFirst; Type _entityType; Dictionary _properties; TableAttribute _table; + + public void ConfigEntity(Action> fluent2) => _codeFirst.ConfigEntity(fluent2); + /// /// 数据库表名 /// @@ -52,6 +57,21 @@ namespace FreeSql.DataAnnotations return new ColumnFluent(col); } + /// + /// 导航关系Fluent,与 NavigateAttribute 对应 + /// + /// + /// + /// 多对多关系的中间实体类型 + /// + public TableFluent Navigate(string proto, string bind, Type manyToMany = null) + { + if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); + var nav = new NavigateAttribute { Bind = bind, ManyToMany = manyToMany }; + _table._navigates.AddOrUpdate(tryProto.Name, nav, (name, old) => nav); + return this; + } + /// /// 设置实体的索引 /// @@ -70,12 +90,19 @@ namespace FreeSql.DataAnnotations public class TableFluent { - public TableFluent(TableAttribute table) + public TableFluent(ICodeFirst codeFirst, TableAttribute table) { + _codeFirst = codeFirst; + _properties = typeof(T).GetPropertiesDictIgnoreCase(); _table = table; } + ICodeFirst _codeFirst; + Dictionary _properties; TableAttribute _table; + + public void ConfigEntity(Action> fluent2) => _codeFirst.ConfigEntity(fluent2); + /// /// 数据库表名 /// @@ -106,7 +133,12 @@ namespace FreeSql.DataAnnotations { var proto = (column.Body as MemberExpression)?.Member; if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); - var col = _table._columns.GetOrAdd(proto.Name, name => new ColumnAttribute { Name = proto.Name }); + return Property(proto.Name); + } + public ColumnFluent Property(string proto) + { + if (_properties.TryGetValue(proto, out var tryProto)) throw new KeyNotFoundException($"找不到属性名 {proto}"); + var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { Name = proto }); return new ColumnFluent(col); } @@ -122,8 +154,13 @@ namespace FreeSql.DataAnnotations { var member = (proto.Body as MemberExpression)?.Member; if (member == null) throw new FormatException($"错误的表达式格式 {proto}"); + return Navigate(member.Name, bind, manyToMany); + } + public TableFluent Navigate(string proto, string bind, Type manyToMany = null) + { + if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); var nav = new NavigateAttribute { Bind = bind, ManyToMany = manyToMany }; - _table._navigates.AddOrUpdate(member.Name, nav, (name, old) => nav); + _table._navigates.AddOrUpdate(tryProto.Name, nav, (name, old) => nav); return this; } @@ -140,5 +177,10 @@ namespace FreeSql.DataAnnotations _table._indexs.AddOrUpdate(name, idx, (_, __) => idx); return this; } + public TableFluent IndexRemove(string name) + { + _table._indexs.TryRemove(name, out var oldidx); + return this; + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d2213da2..a3e67577 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -98,6 +98,12 @@ Sqlite -> text + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + 数据库列名 @@ -198,6 +204,14 @@ Sqlite -> text + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + 自定义表达式函数解析 @@ -319,6 +333,15 @@ 禁用 CodeFirst 同步结构迁移 + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + 多对多关系的中间实体类型 + + 设置实体的索引 @@ -2224,6 +2247,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 }) + + + + + + 可自定义解析表达式 @@ -3002,160 +3156,3 @@ -unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 0b985d08..b70e0dea 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -58,7 +58,7 @@ namespace FreeSql.Internal if (entity == null) return _orm.CodeFirst; var type = typeof(T); var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); - var fluent = new TableFluent(table); + var fluent = new TableFluent(CodeFirst, table); entity.Invoke(fluent); Utils.RemoveTableByEntity(type, this); //remove cache return _orm.CodeFirst; @@ -67,7 +67,7 @@ namespace FreeSql.Internal { if (entity == null) return _orm.CodeFirst; var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); - var fluent = new TableFluent(type, table); + var fluent = new TableFluent(CodeFirst, type, table); entity.Invoke(fluent); Utils.RemoveTableByEntity(type, this); //remove cache return _orm.CodeFirst; @@ -132,6 +132,7 @@ namespace FreeSql.Internal if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate; if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime; if (trycol._StringLength != null) attr.StringLength = trycol.StringLength; + if (!string.IsNullOrEmpty(trycol.InsertValueSql)) attr.InsertValueSql = trycol.InsertValueSql; } var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); foreach (var tryattrobj in attrs) @@ -152,6 +153,7 @@ namespace FreeSql.Internal if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate; if (tryattr.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = tryattr.ServerTime; if (tryattr._StringLength != null) attr.StringLength = tryattr.StringLength; + if (!string.IsNullOrEmpty(tryattr.InsertValueSql)) attr.InsertValueSql = tryattr.InsertValueSql; } ColumnAttribute ret = null; if (!string.IsNullOrEmpty(attr.Name)) ret = attr; @@ -168,6 +170,7 @@ namespace FreeSql.Internal if (attr._CanUpdate != null) ret = attr; if (attr.ServerTime != DateTimeKind.Unspecified) ret = attr; if (attr._StringLength != null) ret = attr; + if (!string.IsNullOrEmpty(attr.InsertValueSql)) ret = attr; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 85ac0949..8c8631c1 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -191,6 +191,11 @@ namespace FreeSql.Internal col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; } + if (string.IsNullOrEmpty(colattr.InsertValueSql) == false) + { + col.DbDefaultValue = colattr.InsertValueSql; + col.DbInsertValue = colattr.InsertValueSql; + } if (colattr.MapType == typeof(string) && colattr.StringLength != 0) { int strlen = colattr.StringLength; From 96f705efd70c6ff8b0ca2284022fb9f8ccd2d683 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Dec 2019 16:56:19 +0800 Subject: [PATCH 0377/1029] update readme --- readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 0d93c231..f4b4bdd8 100644 --- a/readme.md +++ b/readme.md @@ -20,7 +20,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | - | - | | | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | | | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | -| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9#%E4%B9%90%E8%A7%82%E9%94%81) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | | | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | # Packages @@ -39,7 +39,9 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - 要么[FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository),仓储+工作单元习惯; - 要么[FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; - 要么[FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; -- 要么[BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),我求简单现在使用的这个; +- 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),我求简单现在使用的这个; + +> 即将推出 FluentApi 实体模型与 EfCore 90% 相似的扩展包; > 学习项目 From a791febadec580e3cefb99fd0344ad005908a5e9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Dec 2019 16:58:09 +0800 Subject: [PATCH 0378/1029] update readme --- readme.md | 1 - 1 file changed, 1 deletion(-) diff --git a/readme.md b/readme.md index f4b4bdd8..b8959c46 100644 --- a/readme.md +++ b/readme.md @@ -31,7 +31,6 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | FreeSql.Repository | [![nuget](https://img.shields.io/nuget/v/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Repository) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Repository?groupby=Version) | | FreeSql.DbContext | [![nuget](https://img.shields.io/nuget/v/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.DbContext) | [![stats](https://img.shields.io/nuget/dt/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.DbContext?groupby=Version) | | [FreeSql.AdminLTE](https://github.com/2881099/FreeSql.AdminLTE) | [![nuget](https://img.shields.io/nuget/v/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.AdminLTE) | [![stats](https://img.shields.io/nuget/dt/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.AdminLTE?groupby=Version) | -| [FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Connection.Extensions) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Connection.Extensions.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Connection.Extensions?groupby=Version) | > FreeSql 提供了五种使用习惯,请根据实际情况选择团队合适的一种: From 647c93f6dd1f2b01da6be69241915f5549e93ff2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Dec 2019 17:21:32 +0800 Subject: [PATCH 0379/1029] update debug --- .../FreeSql.Extensions.EfCoreFluentApi.xml | 8 ++ FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql/DataAnnotations/TableFluent.cs | 2 +- FreeSql/FreeSql.xml | 131 ------------------ 4 files changed, 9 insertions(+), 139 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml new file mode 100644 index 00000000..35afb8c0 --- /dev/null +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml @@ -0,0 +1,8 @@ + + + + FreeSql.Extensions.EfCoreFluentApi + + + + diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index d36e0e2e..7c8b66c9 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -137,7 +137,7 @@ namespace FreeSql.DataAnnotations } public ColumnFluent Property(string proto) { - if (_properties.TryGetValue(proto, out var tryProto)) throw new KeyNotFoundException($"找不到属性名 {proto}"); + if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { Name = proto }); return new ColumnFluent(col); } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a3e67577..3c47d4cb 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2247,137 +2247,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 From f4c9bd5af6a6a8676ce31e4658d2dd17fa50e9a0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 30 Dec 2019 12:18:43 +0800 Subject: [PATCH 0380/1029] update readme --- .../ICodeFirstExtensions.cs | 85 ++++++++++++++----- .../readme.md | 70 +++++++++++++++ 2 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs index e6799c46..5a75ea8c 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs @@ -8,30 +8,75 @@ namespace FreeSql.Extensions.EfCoreFluentApi public static class ICodeFirstExtensions { - static void Test() - { - ICodeFirst cf = null; - cf.Entity(eb => - { - eb.Property(b => b.Name).HashColumnType("varchar(50)"); - eb.Property(b => b.FullName).HashColumnType("varchar(60)"); - - eb.HasKey(a => a.Id).HasKey(a => new { a.Id, a.Name }); - eb.HasIndex(a => a.Name).IsUnique().HasName("idx_xxx11"); - }); - } - class TestInfo - { - public int Id { get; set; } - public string Name { get; set; } - public string FullName { get; set; } - public int DefaultValue { get; set; } - } - public static ICodeFirst Entity(this ICodeFirst codeFirst, Action> modelBuilder) { codeFirst.ConfigEntity(tf => modelBuilder(new EfCoreTableFluent(tf))); return codeFirst; } + + static void Test() + { + ICodeFirst cf = null; + cf.Entity(eb => + { + eb.ToTable("tb_song"); + eb.Ignore(a => a.Field1); + eb.Property(a => a.Title).HashColumnType("varchar(50)").IsRequired(); + eb.Property(a => a.Url).HasMaxLength(100); + + eb.Property(a => a.RowVersion).IsRowVersion(); + eb.Property(a => a.CreateTime).HasDefaultValueSql("getdate()"); + + eb.HasKey(a => a.Id); + eb.HasIndex(a => a.Title).IsUnique().HasName("idx_xxx11"); + + //一对多、多对一 + eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); + + //多对多 + eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); + }); + } + + public class SongType + { + public int Id { get; set; } + public string Name { get; set; } + + public List Songs { get; set; } + } + + public class Song + { + public int Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime CreateTime { get; set; } + + public int TypeId { get; set; } + public SongType Type { get; set; } + public List Tags { get; set; } + + public int Field1 { get; set; } + public long RowVersion { get; set; } + } + public class Song_tag + { + public int Song_id { get; set; } + public Song Song { get; set; } + + public int Tag_id { get; set; } + public Tag Tag { get; set; } + } + + public class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string Name { get; set; } + + public List Songs { get; set; } + } } } diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md new file mode 100644 index 00000000..6c637fc3 --- /dev/null +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md @@ -0,0 +1,70 @@ +这个 FreeSql 扩展包,实现与 EfCore FluentApi 95% 相似的使用习惯; + +## 以假乱真 + +```csharp +static void Test() +{ + ICodeFirst cf = null; + cf.Entity(eb => + { + eb.ToTable("tb_song"); + eb.Ignore(a => a.Field1); + eb.Property(a => a.Title).HashColumnType("varchar(50)").IsRequired(); + eb.Property(a => a.Url).HasMaxLength(100); + + eb.Property(a => a.RowVersion).IsRowVersion(); + eb.Property(a => a.CreateTime).HasDefaultValueSql("getdate()"); + + eb.HasKey(a => a.Id); + eb.HasIndex(a => a.Title).IsUnique().HasName("idx_xxx11"); + + //一对多、多对一 + eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); + + //多对多 + eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); + }); +} + +public class SongType +{ + public int Id { get; set; } + public string Name { get; set; } + + public List Songs { get; set; } +} + +public class Song +{ + public int Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime CreateTime { get; set; } + + public int TypeId { get; set; } + public SongType Type { get; set; } + public List Tags { get; set; } + + public int Field1 { get; set; } + public long RowVersion { get; set; } +} +public class Song_tag +{ + public int Song_id { get; set; } + public Song Song { get; set; } + + public int Tag_id { get; set; } + public Tag Tag { get; set; } +} + +public class Tag +{ + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string Name { get; set; } + + public List Songs { get; set; } +} +``` \ No newline at end of file From 113a8276b3264d60b95d14f0f44ee6c1a1b0e09b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 30 Dec 2019 19:01:46 +0800 Subject: [PATCH 0381/1029] update readme --- Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md | 4 +++- readme.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md index 6c637fc3..54c4c46f 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md @@ -1,4 +1,6 @@ -这个 FreeSql 扩展包,实现与 EfCore FluentApi 95% 相似的使用习惯; +FreeSql 原本的 FluentApi 方法名与特性名保持一致,所以使用理解成本较低(只需要了解一份); + +这个扩展包目的,为了照顾熟悉 EfCore FluentApi 的开发者,使用习惯 95% 相似; ## 以假乱真 diff --git a/readme.md b/readme.md index b8959c46..c431f5dd 100644 --- a/readme.md +++ b/readme.md @@ -40,7 +40,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - 要么[FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; - 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),我求简单现在使用的这个; -> 即将推出 FluentApi 实体模型与 EfCore 90% 相似的扩展包; +> 即将推出 [FluentApi 实体模型与 EfCore 90% 相似的扩展包](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi); > 学习项目 From 255593a59485a0f0b6ffaa2b6646335624691bfb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Dec 2019 16:26:04 +0800 Subject: [PATCH 0382/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect`1.Wi?= =?UTF-8?q?thSql("select=20*=20from=20user=20...")=20=E5=8A=9F=E8=83=BD?= =?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 | 7 +++++++ FreeSql/FreeSql.xml | 8 ++++++++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 8 ++++++++ .../CommonProvider/SelectProvider/Select1Provider.cs | 10 ++++++++++ 4 files changed, 33 insertions(+) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3c47d4cb..947162a6 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1707,6 +1707,14 @@ 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + 实现 select .. from ( select ... from t ) a 这样的功能 + 使用 AsTable 方法也可以达到效果 + + SQL语句 + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 32e296d2..34c9ce6d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -369,5 +369,13 @@ namespace FreeSql /// 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) /// ISelect IncludeMany(Expression>> navigateSelector, Action> then = null) where TNavigate : class; + + /// + /// 实现 select .. from ( select ... from t ) a 这样的功能 + /// 使用 AsTable 方法也可以达到效果 + /// + /// SQL语句 + /// + ISelect WithSql(string sql); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 30d3615f..ca3d3f8b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -329,6 +329,16 @@ namespace FreeSql.Internal.CommonProvider return this; } + public ISelect WithSql(string sql) + { + this.AsTable((type, old) => + { + if (type == _tables.First().Table?.Type) return $"( {sql} )"; + return old; + }); + return this; + } + public bool Any(Expression> exp) => this.Where(exp).Any(); public TReturn ToOne(Expression> select) => this.Limit(1).ToList(select).FirstOrDefault(); From 63612d20fdbcc9bef02c5b55a526eb8ade4ed925 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Dec 2019 22:49:49 +0800 Subject: [PATCH 0383/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20PgSql=20OnCo?= =?UTF-8?q?nflictDoUpdate=20=E5=8A=9F=E8=83=BD=E5=A2=9E=E5=8A=A0=20DO=20NO?= =?UTF-8?q?THING=20=E6=93=8D=E4=BD=9C=EF=BC=9B#174?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 131 ++++++++++++++++++ .../Curd/OnConflictDoUpdate.cs | 68 +++++---- 2 files changed, 172 insertions(+), 27 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 947162a6..59e0a2ec 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2255,6 +2255,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 }) + + + + + + 可自定义解析表达式 diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index 2e1dd474..bedded9d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -21,6 +21,7 @@ namespace FreeSql.PostgreSQL.Curd (_pgsqlUpdatePriv = new PostgreSQLUpdate(_pgsqlInsert.InternalOrm, _pgsqlInsert.InternalCommonUtils, _pgsqlInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } .NoneParameter().SetSource(_pgsqlInsert.InternalSource) as PostgreSQLUpdate); ColumnInfo[] _columns; + bool _doNothing; public OnConflictDoUpdate(IInsert insert, Expression> columns = null) { @@ -86,6 +87,12 @@ namespace FreeSql.PostgreSQL.Curd return this; } + public OnConflictDoUpdate DoNothing() + { + _doNothing = true; + return this; + } + public string ToSql() { var sb = new StringBuilder(); @@ -95,41 +102,48 @@ namespace FreeSql.PostgreSQL.Curd if (a > 0) sb.Append(", "); sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); } - sb.Append(") DO UPDATE SET\r\n"); - - var sbSetEmpty = _pgsqlUpdate.InternalSbSet.Length == 0; - var sbSetIncrEmpty = _pgsqlUpdate.InternalSbSetIncr.Length == 0; - if (sbSetEmpty == false || sbSetIncrEmpty == false) + if (_doNothing) { - if (sbSetEmpty == false) sb.Append(_pgsqlUpdate.InternalSbSet.ToString().Substring(2)); - if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _pgsqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _pgsqlUpdate.InternalSbSetIncr.ToString()); + sb.Append(") DO NOTHING"); } else { - var colidx = 0; - foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + sb.Append(") DO UPDATE SET\r\n"); + + var sbSetEmpty = _pgsqlUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _pgsqlUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) { - if (col.Attribute.IsPrimary || _pgsqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + if (sbSetEmpty == false) sb.Append(_pgsqlUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _pgsqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _pgsqlUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _pgsqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; - if (colidx > 0) sb.Append(", \r\n"); + if (colidx > 0) sb.Append(", \r\n"); - if (col.Attribute.IsVersion == true) - { - var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); - sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); + if (col.Attribute.IsVersion == true) + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); + } + else if (_pgsqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _pgsqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _pgsqlUpdate.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = EXCLUDED.").Append(field); + } + ++colidx; } - else if (_pgsqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) - { - var caseWhen = _pgsqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); - sb.Append(caseWhen); - if (caseWhen.EndsWith(" END")) _pgsqlUpdate.InternalToSqlCaseWhenEnd(sb, col); - } - else - { - var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); - sb.Append(field).Append(" = EXCLUDED.").Append(field); - } - ++colidx; } } From c27b3fea1f15e83b41920e0844565376d83159cd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 2 Jan 2020 11:27:24 +0800 Subject: [PATCH 0384/1029] =?UTF-8?q?-=20=E6=94=B9=E6=AD=A3=20HashColumnTy?= =?UTF-8?q?pe=20=E4=B8=BA=20HasColumnType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs | 2 +- .../FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs | 2 +- Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs index 2a9cb547..f91e6019 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs @@ -21,7 +21,7 @@ namespace FreeSql.Extensions.EfCoreFluentApi _cf.Name(name); return this; } - public EfCoreColumnFluent HashColumnType(string dbtype) + public EfCoreColumnFluent HasColumnType(string dbtype) { _cf.DbType(dbtype); return this; diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs index 5a75ea8c..bf2ff003 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs @@ -21,7 +21,7 @@ namespace FreeSql.Extensions.EfCoreFluentApi { eb.ToTable("tb_song"); eb.Ignore(a => a.Field1); - eb.Property(a => a.Title).HashColumnType("varchar(50)").IsRequired(); + eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); eb.Property(a => a.Url).HasMaxLength(100); eb.Property(a => a.RowVersion).IsRowVersion(); diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md index 54c4c46f..6eb6f7c8 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md @@ -12,7 +12,7 @@ static void Test() { eb.ToTable("tb_song"); eb.Ignore(a => a.Field1); - eb.Property(a => a.Title).HashColumnType("varchar(50)").IsRequired(); + eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); eb.Property(a => a.Url).HasMaxLength(100); eb.Property(a => a.RowVersion).IsRowVersion(); From f8e4e271132acb306b458c19dc76e918cdbb2a09 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 3 Jan 2020 12:33:19 +0800 Subject: [PATCH 0385/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IAdo.Query\=20=E5=AD=97=E6=AE=B5=E5=90=8D=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B#162?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 24 ++++++++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 8 ++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index ee8ef69d..36f6ae2a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -84,6 +84,17 @@ namespace FreeSql.Tests fsql = ib.Get("db3"); fsql.Select().Limit(10).ToList(); + + fsql = g.sqlserver; + fsql.Insert(new OrderMain { OrderNo = "1001", OrderTime = new DateTime(2019, 12, 01) }).ExecuteAffrows(); + fsql.Insert(new OrderDetail { OrderNo = "1001", ItemNo = "I001", Qty = 1 }).ExecuteAffrows(); + fsql.Insert(new OrderDetail { OrderNo = "1001", ItemNo = "I002", Qty = 1 }).ExecuteAffrows(); + fsql.Insert(new OrderDetail { OrderNo = "1001", ItemNo = "I003", Qty = 1 }).ExecuteAffrows(); + fsql.Insert(new OrderMain { OrderNo = "1002", OrderTime = new DateTime(2019, 12, 02) }).ExecuteAffrows(); + fsql.Insert(new OrderDetail { OrderNo = "1002", ItemNo = "I011", Qty = 1 }).ExecuteAffrows(); + fsql.Insert(new OrderDetail { OrderNo = "1002", ItemNo = "I012", Qty = 1 }).ExecuteAffrows(); + fsql.Insert(new OrderDetail { OrderNo = "1002", ItemNo = "I013", Qty = 1 }).ExecuteAffrows(); + fsql.Ado.Query("select * from orderdetail left join ordermain on orderdetail.orderno=ordermain.orderno where ordermain.orderno='1001'"); } class TestByte @@ -106,6 +117,19 @@ namespace FreeSql.Tests public int id { get; set; } public string name { get; set; } } + + public class OrderMain + { + public string OrderNo { get; set; } + public DateTime OrderTime { get; set; } + public decimal Amount { get; set; } + } + public class OrderDetail + { + public string OrderNo { get; set; } + public string ItemNo { get; set; } + public decimal Qty { get; set; } + } } } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 8c8631c1..b35b342f 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1331,8 +1331,12 @@ namespace FreeSql.Internal var expandodic = new Dictionary();// (IDictionary)expando; var fc = row2.FieldCount; for (var a = 0; a < fc; a++) - //expando[row2.GetName(a)] = row2.GetValue(a); - expandodic.Add(row2.GetName(a), row2.GetValue(a)); + { + var name = row2.GetName(a); + //expando[name] = row2.GetValue(a); + if (expandodic.ContainsKey(name)) continue; + expandodic.Add(name, row2.GetValue(a)); + } //expando = expandodic; return new RowInfo(expandodic, fc); }; From bdf32ea73600081fe3808a9424051a62dec19c06 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 3 Jan 2020 13:03:11 +0800 Subject: [PATCH 0386/1029] ## v1.0.1 # 174 #170 #162 --- .../BaseEntity.cs | 8 +- .../BaseEntityAsync.cs | 8 +- .../BaseEntityReadOnly.cs | 8 +- .../BaseEntityTree.cs | 8 +- .../FreeSql.Extensions.BaseEntity.csproj | 12 +- .../Net40/BaseEntity.cs | 110 +++++++++++++++ .../Net40/BaseEntityReadOnly.cs | 130 ++++++++++++++++++ .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- readme.md | 2 +- 24 files changed, 290 insertions(+), 33 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index 7ef0b544..a3fa6cbf 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -1,4 +1,6 @@ -using FreeSql; +#if netcore + +using FreeSql; using FreeSql.DataAnnotations; using System; using System.Data; @@ -142,4 +144,6 @@ namespace FreeSql return this.Repository.InsertOrUpdate(this as TEntity); } } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index 13a3c29e..e9b33458 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -1,4 +1,6 @@ -using FreeSql; +#if netcore + +using FreeSql; using FreeSql.DataAnnotations; using System; using System.Threading.Tasks; @@ -124,4 +126,6 @@ namespace FreeSql return this.Repository.InsertOrUpdateAsync(this as TEntity); } } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 4b491433..4d0e2ee0 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -1,4 +1,6 @@ -using FreeSql.DataAnnotations; +#if netcore + +using FreeSql.DataAnnotations; using System; using System.Collections; using System.Collections.Generic; @@ -199,4 +201,6 @@ namespace FreeSql return item; } } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs index e805aa6b..abb28109 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs @@ -1,4 +1,6 @@ -using FreeSql; +#if netcore + +using FreeSql; using FreeSql.DataAnnotations; using System; using System.Collections.Generic; @@ -161,4 +163,6 @@ namespace FreeSql return ret; } } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f245cee8..2f9cbbe7 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - 1.0.0 + netcoreapp31;netcoreapp21;net4.0; + 1.0.1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. @@ -31,4 +31,12 @@ + + + + + + netcore + + diff --git a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs new file mode 100644 index 00000000..03bfa3a9 --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs @@ -0,0 +1,110 @@ +#if netcore +#else + +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Data; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql +{ + /// + /// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 + /// + /// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 + /// + /// + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntity : BaseEntity where TEntity : class + { + static BaseEntity() + { + var tkeyType = typeof(TKey)?.NullableTypeOrThis(); + if (tkeyType == typeof(int) || tkeyType == typeof(long)) + Orm.CodeFirst.ConfigEntity(typeof(TEntity), + t => t.Property("Id").IsIdentity(true)); + } + + /// + /// 主键 + /// + [Column(Position = 1)] + public virtual TKey Id { get; set; } + + /// + /// 根据主键值获取数据 + /// + /// + /// + public static TEntity Find(TKey id) + { + var item = Select.WhereDynamic(id).First(); + (item as BaseEntity)?.Attach(); + return item; + } + } + + /// + /// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 + /// + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntity : BaseEntityReadOnly where TEntity : class + { + bool DeletedPrivate(bool value) + { + if (this.Repository == null) + return Orm.Delete(this as TEntity) + .ExecuteAffrows() == 1; + + return this.Repository.Delete(this as TEntity) == 1; + } + /// + /// 删除数据 + /// + /// + public virtual bool Delete() => this.DeletedPrivate(true); + + /// + /// 更新数据 + /// + /// + public virtual bool Update() + { + if (this.Repository == null) + return Orm.Update() + .SetSource(this as TEntity).ExecuteAffrows() == 1; + + return this.Repository.Update(this as TEntity) == 1; + } + /// + /// 插入数据 + /// + public virtual TEntity Insert() + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + return this.Repository.Insert(this as TEntity); + } + + /// + /// 更新或插入 + /// + /// + public virtual TEntity Save() + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + return this.Repository.InsertOrUpdate(this as TEntity); + } + } +} + +#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs new file mode 100644 index 00000000..33ff1a2f --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs @@ -0,0 +1,130 @@ +#if netcore +#else + +using FreeSql.DataAnnotations; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; + +namespace FreeSql +{ + /// + /// 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 + /// + [Table(DisableSyncStructure = true)] + public abstract class BaseEntity + { + static IFreeSql _ormPriv; + /// + /// 全局 IFreeSql orm 对象 + /// + public static IFreeSql Orm => _ormPriv ?? throw new Exception(@"使用前请初始化 BaseEntity.Initialization(new FreeSqlBuilder() +.UseAutoSyncStructure(true) +.UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") +.Build());"); + + /// + /// 初始化BaseEntity + /// BaseEntity.Initialization(new FreeSqlBuilder() + /// + /// .UseAutoSyncStructure(true) + /// + /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") + /// + /// .Build()); + /// + /// IFreeSql orm 对象 + public static void Initialization(IFreeSql fsql) + { + _ormPriv = fsql; + _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); + } + } + + public abstract class BaseEntityReadOnly : BaseEntity where TEntity : class + { + /// + /// 查询数据 + /// + /// + public static ISelect Select + { + get + { + var select = Orm.Select().TrackToList(TrackToList); //自动为每个元素 Attach; + return select; + } + } + + static void TrackToList(object list) + { + if (list == null) return; + var ls = list as IList; + if (ls == null) + { + var ie = list as IEnumerable; + if (ie == null) return; + var isFirst = true; + foreach (var item in ie) + { + if (item == null) return; + if (isFirst) + { + isFirst = false; + var itemType = item.GetType(); + if (itemType == typeof(object)) return; + if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; + if (item is BaseEntity == false) return; + } + (item as BaseEntity)?.Attach(); + } + return; + } + if (ls.Any() == false) return; + if (ls.FirstOrDefault() is BaseEntity == false) return; + if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) return; + foreach (var item in ls) + (item as BaseEntity)?.Attach(); + } + + /// + /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + /// + /// lambda表达式 + /// + public static ISelect Where(Expression> exp) => Select.Where(exp); + /// + /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + /// + /// true 时生效 + /// lambda表达式 + /// + public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); + + /// + /// 仓储对象 + /// + protected IBaseRepository Repository { get; set; } + + /// + /// 附加实体,在更新数据时,只更新变化的部分 + /// + public TEntity Attach() + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + var item = this as TEntity; + this.Repository.Attach(item); + return item; + } + } +} + +#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 671086f8..8da4680f 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 9d322a96..68cb7529 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 99caf79a..79b3dc13 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 4235f29d..a1747bac 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.0.0 + 1.0.1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index bbed01ca..c5c5dcf2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 41577a7e..6a050d43 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 98df7eab..5aa54a7b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 222eeaf2..98f412f3 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 79a2a23e..e4cf46b6 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 65d492bd..c66383be 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index dc0a1669..e459357b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 86906bfc..6b0096a1 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 787a7ac6..351d72b1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9b41cd59..c7d6e4fc 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 456cba14..31568f3d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.0 + 1.0.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin diff --git a/readme.md b/readme.md index c431f5dd..564b2192 100644 --- a/readme.md +++ b/readme.md @@ -40,7 +40,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - 要么[FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; - 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),我求简单现在使用的这个; -> 即将推出 [FluentApi 实体模型与 EfCore 90% 相似的扩展包](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi); +> [FluentApi 与 EfCore 90% 相似的扩展包](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi); > 学习项目 From d12bfc2f8c50ad20361090e6a89e369323ed6394 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 3 Jan 2020 13:09:03 +0800 Subject: [PATCH 0387/1029] #174 --- Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md index 6eb6f7c8..5074724e 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md @@ -2,6 +2,8 @@ FreeSql 原本的 FluentApi 方法名与特性名保持一致,所以使用理 这个扩展包目的,为了照顾熟悉 EfCore FluentApi 的开发者,使用习惯 95% 相似; +> dotnet add package FreeSql.Extensions.EfCoreFluentApi + ## 以假乱真 ```csharp From 77463154e1cb9c897a8fd098519acfb54b29db98 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 3 Jan 2020 22:06:23 +0800 Subject: [PATCH 0388/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20BaseReposito?= =?UTF-8?q?ry.UnitOfWork=20=E5=BB=B6=E8=BF=9F=E8=AE=BE=E7=BD=AE=E6=97=A0?= =?UTF-8?q?=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/Repository/BaseRepository.cs | 11 +- FreeSql/FreeSql.xml | 361 ++++++++---------- 2 files changed, 179 insertions(+), 193 deletions(-) diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index b18a60a6..df25b35d 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -63,7 +63,16 @@ namespace FreeSql public DbContextOptions DbContextOptions { get => _db.Options; set => _db.Options = value; } public IFreeSql Orm { get; private set; } - public IUnitOfWork UnitOfWork { get; set; } + IUnitOfWork _unitOfWork; + public IUnitOfWork UnitOfWork + { + set + { + _unitOfWork = value; + if (_dbsetPriv != null) _dbsetPriv._uow = _unitOfWork; //防止 dbset 对象已经存在,再次设置 UnitOfWork 无法生效,所以作此判断重新设置 + } + get => _unitOfWork; + } public IUpdate UpdateDiy => _dbset.OrmUpdateInternal(null); public ISelect Select => _dbset.OrmSelectInternal(null); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 59e0a2ec..e4bdedbe 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2430,178 +2430,7 @@ 内置解析功能,可辅助您进行解析 - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构 - - - - - 转大写同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - + mmary> @@ -2887,41 +2716,189 @@ C#:从元组集合中查找 exp1, exp2, exp2 是否存在 SQL: exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 + exp1 = that[1].Item1 and exp2 = that[1].Item2 aummary> + 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - + - + - 测量两个经纬度的距离,返回单位:米 + 序列化 - 经纬坐标1 - 经纬坐标2 - 返回距离(单位:米) + + - + - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 - + 名字 + 表达式 - + - 多表查询 + 中间表,多对多 + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 将帕斯系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 使用 and 拼接两个 lambda 表达式 + + + 使用 and 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + er> 多表查询 From d67e9644ebe1a7f7aa60001d29abdc51c6682475 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 4 Jan 2020 22:53:39 +0800 Subject: [PATCH 0389/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=8F=82?= =?UTF-8?q?=E8=80=83=20Chloe=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E9=92=88?= =?UTF-8?q?=E5=AF=B9=E5=8F=98=E9=87=8F=E7=9A=84=E8=A7=A3=E6=9E=90=EF=BC=8C?= =?UTF-8?q?=E6=8F=90=E5=8D=87=E4=BA=86=E4=B8=80=E5=80=8D=E6=80=A7=E8=83=BD?= =?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 | 7 + FreeSql/FreeSql.xml | 361 +++++++++++++----------- FreeSql/Internal/CommonExpression.cs | 32 ++- 3 files changed, 230 insertions(+), 170 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e4bdedbe..59e0a2ec 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2430,7 +2430,178 @@ 内置解析功能,可辅助您进行解析 - mmary> + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构 + + + + + 转大写同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + @@ -2716,189 +2887,41 @@ C#:从元组集合中查找 exp1, exp2, exp2 是否存在 SQL: exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 aummary> - 获取ado.net读取方法, GetBoolean、GetInt64 + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 - + + + + + + + - + - 序列化 + 测量两个经纬度的距离,返回单位:米 - - + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) - + - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 - 名字 - 表达式 + - + - 中间表,多对多 - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 将帕斯系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 使用 and 拼接两个 lambda 表达式 + 多表查询 - - - 使用 and 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - er> 多表查询 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index a6beb913..0765d7d4 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1005,6 +1005,7 @@ namespace FreeSql.Internal if (string.IsNullOrEmpty(other4Exp) == false) return other4Exp; } var expStack = new Stack(); + var expStackConstOrMemberCount = 1; expStack.Push(exp); MethodCallExpression callExp = null; var exp2 = exp4?.Expression; @@ -1014,6 +1015,7 @@ namespace FreeSql.Internal { case ExpressionType.Constant: expStack.Push(exp2); + expStackConstOrMemberCount++; break; case ExpressionType.Parameter: expStack.Push(exp2); @@ -1021,6 +1023,7 @@ namespace FreeSql.Internal case ExpressionType.MemberAccess: expStack.Push(exp2); exp2 = (exp2 as MemberExpression).Expression; + expStackConstOrMemberCount++; if (exp2 == null) break; continue; case ExpressionType.Call: @@ -1043,7 +1046,34 @@ namespace FreeSql.Internal } break; } - if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + if (expStack.First().NodeType != ExpressionType.Parameter) + { + if (expStackConstOrMemberCount == expStack.Count) + { + object firstValue = null; + switch (expStack.First().NodeType) + { + case ExpressionType.Constant: + var expStackFirst = expStack.Pop() as ConstantExpression; + firstValue = expStackFirst?.Value; + break; + case ExpressionType.MemberAccess: + var expStackFirstMem = expStack.First() as MemberExpression; + if (expStackFirstMem.Expression?.NodeType == ExpressionType.Constant) firstValue = (expStackFirstMem.Expression as ConstantExpression)?.Value; + break; + } + while (expStack.Any()) + { + var expStackItem = expStack.Pop() as MemberExpression; + if (expStackItem.Member.MemberType == MemberTypes.Property) + firstValue = ((PropertyInfo)expStackItem.Member).GetValue(firstValue, null); + else if (expStackItem.Member.MemberType == MemberTypes.Field) + firstValue = ((FieldInfo)expStackItem.Member).GetValue(firstValue); + } + return formatSql(firstValue, tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + } + return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + } if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { From 54ceb537d9dd80d10fa8c4b4b94c594da7d229ec Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 5 Jan 2020 10:37:02 +0800 Subject: [PATCH 0390/1029] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=8B=BC=E5=86=99?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=9A=84=E5=86=85=E9=83=A8=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs/orm_vs.csproj | 6 +++--- FreeSql.DbContext/DbContext/DbContextAsync.cs | 14 +++++++------- FreeSql.DbContext/DbContext/DbContextSync.cs | 14 +++++++------- FreeSql.DbContext/DbSet/DbSetAsync.cs | 10 +++++----- FreeSql.DbContext/DbSet/DbSetSync.cs | 10 +++++----- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- .../SqlServer/Curd/SqlServerInsertTest.cs | 16 ++++++++-------- 7 files changed, 35 insertions(+), 42 deletions(-) diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index 4e6eb813..4ee359da 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -6,9 +6,9 @@ - - - + + + diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 4cac04a2..88969bd7 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -17,7 +17,7 @@ namespace FreeSql return SaveChangesSuccess(); } - static Dictionary>>> _dicExecCommandDbContextBetchAsync = new Dictionary>>>(); + static Dictionary>>> _dicExecCommandDbContextBatchAsync = new Dictionary>>>(); async internal Task ExecCommandAsync() { if (isExecCommanding) return; @@ -27,9 +27,9 @@ namespace FreeSql ExecCommandInfo oldinfo = null; var states = new List(); - Func> dbContextBetch = methodName => + Func> dbContextBatch = methodName => { - if (_dicExecCommandDbContextBetchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false) + if (_dicExecCommandDbContextBatchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false) trydic = new Dictionary>>(); if (trydic.TryGetValue(methodName, out var tryfunc) == false) { @@ -53,19 +53,19 @@ namespace FreeSql }; Func funcDelete = async () => { - _affrows += await dbContextBetch("DbContextBetchRemoveAsync"); + _affrows += await dbContextBatch("DbContextBatchRemoveAsync"); states.Clear(); }; Func funcInsert = async () => { - _affrows += await dbContextBetch("DbContextBetchAddAsync"); + _affrows += await dbContextBatch("DbContextBatchAddAsync"); states.Clear(); }; Func funcUpdate = async (isLiveUpdate) => { var affrows = 0; - if (isLiveUpdate) affrows = await dbContextBetch("DbContextBetchUpdateNowAsync"); - else affrows = await dbContextBetch("DbContextBetchUpdateAsync"); + if (isLiveUpdate) affrows = await dbContextBatch("DbContextBatchUpdateNowAsync"); + else affrows = await dbContextBatch("DbContextBatchUpdateAsync"); if (affrows == -999) { //最后一个元素已被删除 states.RemoveAt(states.Count - 1); diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs index cbec1023..88fc4ca5 100644 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -30,7 +30,7 @@ namespace FreeSql return SaveChangesSuccess(); } - static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); + static Dictionary>> _dicExecCommandDbContextBatch = new Dictionary>>(); bool isExecCommanding = false; internal void ExecCommand() { @@ -41,9 +41,9 @@ namespace FreeSql ExecCommandInfo oldinfo = null; var states = new List(); - Func dbContextBetch = methodName => + Func dbContextBatch = methodName => { - if (_dicExecCommandDbContextBetch.TryGetValue(oldinfo.stateType, out var trydic) == false) + if (_dicExecCommandDbContextBatch.TryGetValue(oldinfo.stateType, out var trydic) == false) trydic = new Dictionary>(); if (trydic.TryGetValue(methodName, out var tryfunc) == false) { @@ -67,19 +67,19 @@ namespace FreeSql }; Action funcDelete = () => { - _affrows += dbContextBetch("DbContextBetchRemove"); + _affrows += dbContextBatch("DbContextBatchRemove"); states.Clear(); }; Action funcInsert = () => { - _affrows += dbContextBetch("DbContextBetchAdd"); + _affrows += dbContextBatch("DbContextBatchAdd"); states.Clear(); }; Action funcUpdate = isLiveUpdate => { var affrows = 0; - if (isLiveUpdate) affrows = dbContextBetch("DbContextBetchUpdateNow"); - else affrows = dbContextBetch("DbContextBetchUpdate"); + if (isLiveUpdate) affrows = dbContextBatch("DbContextBatchUpdateNow"); + else affrows = dbContextBatch("DbContextBatchUpdate"); if (affrows == -999) { //最后一个元素已被删除 states.RemoveAt(states.Count - 1); diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index e4fbc75d..df1a2c00 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -20,7 +20,7 @@ namespace FreeSql return _db.ExecCommandAsync(); } - async Task DbContextBetchAddAsync(EntityState[] adds) + async Task DbContextBatchAddAsync(EntityState[] adds) { if (adds.Any() == false) return 0; var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(); @@ -303,9 +303,9 @@ namespace FreeSql #endregion #region UpdateAsync - Task DbContextBetchUpdateAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, false); - Task DbContextBetchUpdateNowAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, true); - async Task DbContextBetchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate) + Task DbContextBatchUpdateAsync(EntityState[] ups) => DbContextBatchUpdatePrivAsync(ups, false); + Task DbContextBatchUpdateNowAsync(EntityState[] ups) => DbContextBatchUpdatePrivAsync(ups, true); + async Task DbContextBatchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate) { if (ups.Any() == false) return 0; var uplst1 = ups[ups.Length - 1]; @@ -392,7 +392,7 @@ namespace FreeSql #endregion #region RemoveAsync - async Task DbContextBetchRemoveAsync(EntityState[] dels) + async Task DbContextBatchRemoveAsync(EntityState[] dels) { if (dels.Any() == false) return 0; var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index c2bbbbbd..172d13cb 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -19,7 +19,7 @@ namespace FreeSql _db.ExecCommand(); } - int DbContextBetchAdd(EntityState[] adds) + int DbContextBatchAdd(EntityState[] adds) { if (adds.Any() == false) return 0; var affrows = this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrows(); @@ -338,9 +338,9 @@ namespace FreeSql #endregion #region Update - int DbContextBetchUpdate(EntityState[] ups) => DbContextBetchUpdatePriv(ups, false); - int DbContextBetchUpdateNow(EntityState[] ups) => DbContextBetchUpdatePriv(ups, true); - int DbContextBetchUpdatePriv(EntityState[] ups, bool isLiveUpdate) + int DbContextBatchUpdate(EntityState[] ups) => DbContextBatchUpdatePriv(ups, false); + int DbContextBatchUpdateNow(EntityState[] ups) => DbContextBatchUpdatePriv(ups, true); + int DbContextBatchUpdatePriv(EntityState[] ups, bool isLiveUpdate) { if (ups.Any() == false) return 0; var uplst1 = ups[ups.Length - 1]; @@ -433,7 +433,7 @@ namespace FreeSql #endregion #region Remove - int DbContextBetchRemove(EntityState[] dels) + int DbContextBatchRemove(EntityState[] dels) { if (dels.Any() == false) return 0; var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index c17a1113..c25d5c68 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -103,19 +103,19 @@ namespace FreeSql.Tests.SqlServer //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); //Assert.Equal(9989, g.sqlserver.Insert(items).ExecuteAffrows()); - //var bttype = new TestBetchInsertType { title = "testbttitle1" }; + //var bttype = new TestBatchInsertType { title = "testbttitle1" }; //bttype.id = (int)g.sqlserver.Insert(bttype).ExecuteIdentity(); //Assert.True(bttype.id > 0); - //var bttopic = Enumerable.Range(0, 10000).Select(a => new TestBetchInsertTopic { TypeId = bttype.id, Text = $"testtopic{a}" }).ToArray(); - //Assert.Equal(bttopic.Length, g.sqlserver.Insert(bttopic).ExecuteAffrows()); + //var bttopic = Enumerable.Range(0, 10000).Select(a => new TestBatchInsertTopic { TypeId = bttype.id, Text = $"testtopic{a}" }).ToArray(); + //Assert.Equal(bttopic.Length, g.sqlserver.Insert(bttopic).ExecuteAffrows()); //g.sqlserver.Transaction(() => //{ - // bttype = new TestBetchInsertType { title = "transaction_testbttitle2" }; + // bttype = new TestBatchInsertType { title = "transaction_testbttitle2" }; // bttype.id = (int)g.sqlserver.Insert(bttype).ExecuteIdentity(); // Assert.True(bttype.id > 0); - // bttopic = Enumerable.Range(0, 10000).Select(a => new TestBetchInsertTopic { TypeId = bttype.id, Text = $"transaction_testtopic{a}" }).ToArray(); - // Assert.Equal(bttopic.Length, g.sqlserver.Insert(bttopic).ExecuteAffrows()); + // bttopic = Enumerable.Range(0, 10000).Select(a => new TestBatchInsertTopic { TypeId = bttype.id, Text = $"transaction_testtopic{a}" }).ToArray(); + // Assert.Equal(bttopic.Length, g.sqlserver.Insert(bttopic).ExecuteAffrows()); //}); g.sqlserver.Transaction(() => @@ -127,12 +127,12 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(detail.Length, g.sqlserver.Insert(detail).NoneParameter().ExecuteAffrows()); }); } - class TestBetchInsertType { + class TestBatchInsertType { [Column(IsIdentity = true)] public int id { get; set; } public string title { get; set; } } - class TestBetchInsertTopic + class TestBatchInsertTopic { public Guid id { get; set; } public int TypeId { get; set; } From 65fa7ceb95712e47ced761c6dfbfb2f214d19a8b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 5 Jan 2020 17:21:28 +0800 Subject: [PATCH 0391/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=20FreeSql.G?= =?UTF-8?q?enerator=20=E5=A4=96=E9=94=AE=E5=AF=BC=E8=88=AA=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=A4=A7=E5=86=99=E5=B0=8F=20bug=EF=BC=9B#177?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- Extensions/FreeSql.Generator/RazorContentManager.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index a1747bac..222b8e28 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;netcoreapp3.0;netcoreapp2.2;netcoreapp2.1 + netcoreapp3.1;netcoreapp2.1 true true true diff --git a/Extensions/FreeSql.Generator/RazorContentManager.cs b/Extensions/FreeSql.Generator/RazorContentManager.cs index 9773795b..e881aa80 100644 --- a/Extensions/FreeSql.Generator/RazorContentManager.cs +++ b/Extensions/FreeSql.Generator/RazorContentManager.cs @@ -161,7 +161,7 @@ namespace @gen.NameSpace { @:if (_@csname == value) return; @:_@csname = value; foreach (var fkcok2 in findfks) { - @:@GetFkObjectName(fkcok2) = null; + @:@gen.GetCsName(GetFkObjectName(fkcok2)) = null; } @:} } @:private @gen.GetCsType(col) _@csname; From f7205b041480456cf40a09f48adf6e89c4bb87e8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 6 Jan 2020 12:00:50 +0800 Subject: [PATCH 0392/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IsVersion=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=9B=B4=E6=96=B0=20version=3Difnull(version?= =?UTF-8?q?,0)+1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/UpdateProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 9cd654f3..a38e6d0f 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -629,7 +629,7 @@ namespace FreeSql.Internal.CommonProvider if (_table.VersionColumn != null) { var vcname = _commonUtils.QuoteSqlName(_table.VersionColumn.Attribute.Name); - sb.Append(", ").Append(vcname).Append(" = ").Append(vcname).Append(" + 1"); + sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.IsNull(vcname, 0)).Append(" + 1"); } sb.Append(" \r\nWHERE "); From bbba06a3437cd7bf74b539f1d0f6f1f76875082e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 6 Jan 2020 18:50:38 +0800 Subject: [PATCH 0393/1029] =?UTF-8?q?-=20=E6=89=A9=E5=B1=95=20=E5=86=85?= =?UTF-8?q?=E9=83=A8=E6=96=B9=E6=B3=95=20QuoteReadColumn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 31 +++++++ FreeSql/Internal/CommonExpression.cs | 2 +- .../SelectProvider/Select0Provider.cs | 10 +-- .../SelectProvider/Select1Provider.cs | 2 +- FreeSql/Internal/CommonUtils.cs | 2 +- .../Curd/MsAccessDelete.cs | 82 +------------------ .../Curd/MsAccessUpdate.cs | 5 +- .../MsAccessUtils.cs | 2 +- .../Curd/MySqlDelete.cs | 4 +- .../Curd/MySqlInsert.cs | 4 +- .../Curd/MySqlUpdate.cs | 9 +- .../FreeSql.Provider.MySql/MySqlUtils.cs | 4 +- .../MySqlConnectorUtils.cs | 4 +- .../Dameng/Curd/OdbcDamengUpdate.cs | 5 +- .../Dameng/OdbcDamengUtils.cs | 2 +- .../Default/Curd/OdbcUpdate.cs | 5 +- .../Default/OdbcUtils.cs | 2 +- .../GBase/Curd/OdbcGBaseUpdate.cs | 5 +- .../GBase/__OdbcGBaseUtils.cs | 2 +- .../MySql/Curd/OdbcMySqlDelete.cs | 4 +- .../MySql/Curd/OdbcMySqlInsert.cs | 4 +- .../MySql/Curd/OdbcMySqlUpdate.cs | 9 +- .../MySql/OdbcMySqlUtils.cs | 4 +- .../Oracle/Curd/OdbcOracleUpdate.cs | 5 +- .../Oracle/OdbcOracleUtils.cs | 2 +- .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 9 +- .../PostgreSQL/OdbcPostgreSQLUtils.cs | 2 +- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 9 +- .../SqlServer/OdbcSqlServerUtils.cs | 2 +- .../Curd/OracleUpdate.cs | 5 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 2 +- .../Curd/PostgreSQLDelete.cs | 4 +- .../Curd/PostgreSQLInsert.cs | 4 +- .../Curd/PostgreSQLUpdate.cs | 9 +- .../PostgreSQLUtils.cs | 2 +- .../Curd/SqlServerDelete.cs | 4 +- .../Curd/SqlServerInsert.cs | 4 +- .../Curd/SqlServerUpdate.cs | 9 +- .../SqlServerUtils.cs | 2 +- .../Curd/SqliteUpdate.cs | 5 +- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 2 +- 46 files changed, 140 insertions(+), 167 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 36f6ae2a..8953057a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -15,6 +15,7 @@ using System.Data.SqlClient; using kwlib; using System.Diagnostics; using System.IO; +using System.Text; namespace FreeSql.Tests { @@ -95,6 +96,36 @@ namespace FreeSql.Tests fsql.Insert(new OrderDetail { OrderNo = "1002", ItemNo = "I012", Qty = 1 }).ExecuteAffrows(); fsql.Insert(new OrderDetail { OrderNo = "1002", ItemNo = "I013", Qty = 1 }).ExecuteAffrows(); fsql.Ado.Query("select * from orderdetail left join ordermain on orderdetail.orderno=ordermain.orderno where ordermain.orderno='1001'"); + + + g.oracle.Insert(new[] + { + new SendInfo{ Code = "001", Binary = Encoding.UTF8.GetBytes("我是中国人") }, + new SendInfo{ Code = "002", Binary = Encoding.UTF8.GetBytes("我是地球人") }, + new SendInfo{ Code = "003", Binary = Encoding.UTF8.GetBytes("我是.net")}, + new SendInfo{ Code = "004", Binary = Encoding.UTF8.GetBytes("我是freesql") }, + }) + .NoneParameter().ExecuteAffrows(); + + var slslsl = g.oracle.Select().ToList(); + } + + [Table(Name = "t_text")] + public class SendInfo + { + [Column(IsPrimary = true)] + public Guid ID { get; set; } + + [Column(Name = "YPID5")] + public string Code { get; set; } + + public byte[] Binary { get; set; } + + [Column(ServerTime = DateTimeKind.Utc)] + public DateTime CreateTime { get; set; } + + [Column(InsertValueSql = "'123'")] + public string InsertValue2 { get; set; } } class TestByte diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 0765d7d4..aa7b25ad 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -96,7 +96,7 @@ namespace FreeSql.Internal CsType = map[idx].Column.CsType, MapType = map[idx].Column.Attribute.MapType }; - field.Append(", ").Append(_common.QuoteReadColumn(child.MapType, child.DbField)); + field.Append(", ").Append(_common.QuoteReadColumn(child.CsType, child.MapType, child.DbField)); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); parent.Childs.Add(child); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 5d45b4fc..53e1acae 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -597,7 +597,7 @@ namespace FreeSql.Internal.CommonProvider if (tbiindex > 0 && colidx == 0) field.Append("\r\n"); } var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); + field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); ++index; if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); @@ -728,7 +728,7 @@ namespace FreeSql.Internal.CommonProvider { //普通字段 if (index > 0) field.Append(", "); var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); + field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); ++index; if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); @@ -751,7 +751,7 @@ namespace FreeSql.Internal.CommonProvider { if (index > 0) field.Append(", "); var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); + field.Append(_commonUtils.QuoteReadColumn(col2.CsType, col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); ++index; ++otherindex; if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); @@ -849,7 +849,7 @@ namespace FreeSql.Internal.CommonProvider { //普通字段 if (index > 0) field.Append(", "); var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); + field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); ++index; if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); @@ -866,7 +866,7 @@ namespace FreeSql.Internal.CommonProvider { if (index > 0) field.Append(", "); var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); + field.Append(_commonUtils.QuoteReadColumn(col2.CsType, col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); ++index; if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); else dicfield.Add(quoteName, true); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index ca3d3f8b..255ad8ee 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -910,7 +910,7 @@ namespace FreeSql.Internal.CommonProvider Property = tbrefMid.Properties[col.CsName] }; read.Childs.Add(child); - field.Append(", ").Append(_commonUtils.QuoteReadColumn(child.MapType, child.DbField)); + field.Append(", ").Append(_commonUtils.QuoteReadColumn(child.CsType, child.MapType, child.DbField)); } otherData = (field.ToString(), read); } diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index b70e0dea..46ab536c 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -37,7 +37,7 @@ namespace FreeSql.Internal public abstract string Now { get; } public abstract string NowUtc { get; } public abstract string QuoteWriteParamter(Type type, string paramterName); - public abstract string QuoteReadColumn(Type type, string columnName); + public abstract string QuoteReadColumn(Type type, Type mapType, string columnName); public virtual string FieldAsAlias(string alias) => $" {alias}"; public virtual string IIF(string test, string ifTrue, string ifElse) => $"case when {test} then {ifTrue} else {ifElse} end"; diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs index 46c81d2e..31e2c19e 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs @@ -17,92 +17,14 @@ namespace FreeSql.MsAccess.Curd public override List ExecuteDeleted() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; + throw new NotImplementedException(); } #if net40 #else async public override Task> ExecuteDeletedAsync() { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var sb = new StringBuilder(); - sb.Append(" OUTPUT "); - var colidx = 0; - foreach (var col in _table.Columns.Values) - { - if (colidx > 0) sb.Append(", "); - sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; - } - - var validx = sql.IndexOf(" WHERE "); - if (validx == -1) throw new ArgumentException("找不到 WHERE "); - sb.Insert(0, sql.Substring(0, validx)); - sb.Append(sql.Substring(validx)); - - sql = sb.ToString(); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); - } - this.ClearData(); - return ret; + throw new NotImplementedException(); } #endif } diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs index bf39d6b1..f54c9077 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs @@ -35,7 +35,8 @@ namespace FreeSql.MsAccess.Curd { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -43,7 +44,7 @@ namespace FreeSql.MsAccess.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append(MsAccessUtils.GetCastSql(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)), typeof(string))); + caseWhen.Append(MsAccessUtils.GetCastSql(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)), typeof(string))); ++pkidx; } caseWhen.Append(")"); diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs index b0798d2a..125d7a60 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -73,7 +73,7 @@ namespace FreeSql.MsAccess public override string NowUtc => "now()"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string FieldAsAlias(string alias) => $" as {alias}"; public override string IIF(string test, string ifTrue, string ifElse) => $"iif({test}, {ifTrue}, {ifElse})"; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index 05dfc35d..60949a68 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -27,7 +27,7 @@ namespace FreeSql.MySql.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -68,7 +68,7 @@ namespace FreeSql.MySql.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index ee25ff2b..f84783fe 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -79,7 +79,7 @@ namespace FreeSql.MySql.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -148,7 +148,7 @@ namespace FreeSql.MySql.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index dcde6b41..f2e29d2d 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -40,7 +40,7 @@ namespace FreeSql.MySql.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -71,7 +71,8 @@ namespace FreeSql.MySql.Curd { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("CONCAT("); @@ -79,7 +80,7 @@ namespace FreeSql.MySql.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } caseWhen.Append(")"); @@ -120,7 +121,7 @@ namespace FreeSql.MySql.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 4e5ea4b0..f00192a3 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -104,9 +104,9 @@ namespace FreeSql.MySql } return paramterName; } - public override string QuoteReadColumn(Type type, string columnName) + public override string QuoteReadColumn(Type type, Type mapType, string columnName) { - switch (type.FullName) + switch (mapType.FullName) { case "MygisPoint": case "MygisLineString": diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 202eb9f1..5734c337 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -112,9 +112,9 @@ namespace FreeSql.MySql } return paramterName; } - public override string QuoteReadColumn(Type type, string columnName) + public override string QuoteReadColumn(Type type, Type mapType, string columnName) { - switch (type.FullName) + switch (mapType.FullName) { case "MygisPoint": case "MygisLineString": diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs index 6b15906c..2b274bf4 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -31,7 +31,8 @@ namespace FreeSql.Odbc.Dameng { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -39,7 +40,7 @@ namespace FreeSql.Odbc.Dameng foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(" || "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } caseWhen.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index 065081d9..0e55dfc1 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -91,7 +91,7 @@ namespace FreeSql.Odbc.Dameng public override string NowUtc => "getutcdate"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs index 95cfc2fe..c13928d9 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs @@ -28,7 +28,8 @@ namespace FreeSql.Odbc.Default { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -36,7 +37,7 @@ namespace FreeSql.Odbc.Default foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append(_utils.Adapter.CastSql(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)), _utils.Adapter.MappingOdbcTypeVarChar)); + caseWhen.Append(_utils.Adapter.CastSql(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)), _utils.Adapter.MappingOdbcTypeVarChar)); ++pkidx; } caseWhen.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index 001c8bed..ba0937b5 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -64,7 +64,7 @@ namespace FreeSql.Odbc.Default public override string NowUtc => Adapter.LambdaDateTime_UtcNow; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => Adapter.FieldSql(type, columnName); + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => Adapter.FieldSql(type, columnName); public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs index 4a02c36b..e2495d19 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs @@ -30,7 +30,8 @@ namespace FreeSql.Odbc.GBase { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -38,7 +39,7 @@ namespace FreeSql.Odbc.GBase foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(" || "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); ++pkidx; } caseWhen.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs index 3382ae3e..c4b722e2 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs @@ -117,7 +117,7 @@ namespace FreeSql.Odbc.GBase public override string NowUtc => "(current_timestamp at time zone 'UTC')"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index e4daabfb..c10fcb88 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -27,7 +27,7 @@ namespace FreeSql.Odbc.MySql foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -68,7 +68,7 @@ namespace FreeSql.Odbc.MySql foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index cfb9bcdb..d90e0ec4 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -71,7 +71,7 @@ namespace FreeSql.Odbc.MySql foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -151,7 +151,7 @@ namespace FreeSql.Odbc.MySql foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index d98073d5..c2234536 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -34,7 +34,7 @@ namespace FreeSql.Odbc.MySql foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -65,7 +65,8 @@ namespace FreeSql.Odbc.MySql { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("CONCAT("); @@ -73,7 +74,7 @@ namespace FreeSql.Odbc.MySql foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } caseWhen.Append(")"); @@ -114,7 +115,7 @@ namespace FreeSql.Odbc.MySql foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 20917791..cfc79dbd 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -75,9 +75,9 @@ namespace FreeSql.Odbc.MySql } return paramterName; } - public override string QuoteReadColumn(Type type, string columnName) + public override string QuoteReadColumn(Type type, Type mapType, string columnName) { - switch (type.FullName) + switch (mapType.FullName) { case "MygisPoint": case "MygisLineString": diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index 58c7b20b..629d3d89 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -31,7 +31,8 @@ namespace FreeSql.Odbc.Oracle { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -39,7 +40,7 @@ namespace FreeSql.Odbc.Oracle foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(" || "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } caseWhen.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index 5880ea5a..b33fc74d 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -91,7 +91,7 @@ namespace FreeSql.Odbc.Oracle public override string NowUtc => "sys_extract_utc(systimestamp)"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index 11250d19..1fe6c5ee 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -27,7 +27,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -68,7 +68,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index f159b95c..3431e614 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -82,7 +82,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -174,7 +174,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 704da574..f62def8f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -33,7 +33,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -64,7 +64,8 @@ namespace FreeSql.Odbc.PostgreSQL { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -72,7 +73,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(" || "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); ++pkidx; } caseWhen.Append(")"); @@ -122,7 +123,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 5d2559ce..5275357f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -117,7 +117,7 @@ namespace FreeSql.Odbc.PostgreSQL public override string NowUtc => "(current_timestamp at time zone 'UTC')"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index 609591fa..6cee6f44 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -26,7 +26,7 @@ namespace FreeSql.Odbc.SqlServer foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } @@ -72,7 +72,7 @@ namespace FreeSql.Odbc.SqlServer foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 464c2d37..5bd211c0 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -84,7 +84,7 @@ namespace FreeSql.Odbc.SqlServer foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } @@ -194,7 +194,7 @@ namespace FreeSql.Odbc.SqlServer foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index 57930d57..aa57a9de 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -32,7 +32,7 @@ namespace FreeSql.Odbc.SqlServer foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } @@ -69,7 +69,8 @@ namespace FreeSql.Odbc.SqlServer { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -77,7 +78,7 @@ namespace FreeSql.Odbc.SqlServer foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); + caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); ++pkidx; } caseWhen.Append(")"); @@ -115,7 +116,7 @@ namespace FreeSql.Odbc.SqlServer foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index 612facff..8b00e08d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -78,7 +78,7 @@ namespace FreeSql.Odbc.SqlServer public override string NowUtc => "getutcdate()"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index 3cb65446..17cc8a5a 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -31,7 +31,8 @@ namespace FreeSql.Oracle.Curd { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -39,7 +40,7 @@ namespace FreeSql.Oracle.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(" || "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } caseWhen.Append(")"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 64388b4a..68d5a100 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -86,7 +86,7 @@ namespace FreeSql.Oracle public override string NowUtc => "sys_extract_utc(systimestamp)"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index f5478a2e..b4586c2d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -27,7 +27,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -68,7 +68,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index 1fbb4892..da3f8675 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -95,7 +95,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -187,7 +187,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 23c53f3e..18773870 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); @@ -72,8 +72,9 @@ namespace FreeSql.PostgreSQL.Curd { if (_table.Primarys.Length == 1) { + var pk = _table.Primarys.First(); if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -82,7 +83,7 @@ namespace FreeSql.PostgreSQL.Curd { if (pkidx > 0) caseWhen.Append(" || "); if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); ++pkidx; } caseWhen.Append(")"); @@ -132,7 +133,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } sql = sb.ToString(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 0910d9cc..72a680f9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -143,7 +143,7 @@ namespace FreeSql.PostgreSQL public override string NowUtc => "(current_timestamp at time zone 'UTC')"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; static ConcurrentDictionary _dicIsAssignableFromPostgisGeometry = new ConcurrentDictionary(); public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index 8656d908..6548ba9e 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -26,7 +26,7 @@ namespace FreeSql.SqlServer.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } @@ -72,7 +72,7 @@ namespace FreeSql.SqlServer.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 58c74bc1..ba66255e 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -68,7 +68,7 @@ namespace FreeSql.SqlServer.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } @@ -152,7 +152,7 @@ namespace FreeSql.SqlServer.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index a8ac9031..4b69d8c5 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -33,7 +33,7 @@ namespace FreeSql.SqlServer.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } @@ -70,7 +70,8 @@ namespace FreeSql.SqlServer.Curd { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("("); @@ -78,7 +79,7 @@ namespace FreeSql.SqlServer.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); + caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); ++pkidx; } caseWhen.Append(")"); @@ -116,7 +117,7 @@ namespace FreeSql.SqlServer.Curd foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 9d76798e..9737ffe4 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -89,7 +89,7 @@ namespace FreeSql.SqlServer public override string NowUtc => "getutcdate()"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index c5379695..8988d244 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -31,7 +31,8 @@ namespace FreeSql.Sqlite.Curd { if (_table.Primarys.Length == 1) { - caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } caseWhen.Append("CONCAT("); @@ -39,7 +40,7 @@ namespace FreeSql.Sqlite.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(", "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } caseWhen.Append(")"); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index fd7a88f8..99c23e82 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -89,7 +89,7 @@ namespace FreeSql.Sqlite public override string NowUtc => "current_timestamp"; public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, string columnName) => columnName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { From fbbd74f54c6172e5c6337fa96ce2212d53163d95 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 6 Jan 2020 19:36:30 +0800 Subject: [PATCH 0394/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20[Column(Serv?= =?UTF-8?q?erTime=20=3D=20Utc)]=20=E7=89=B9=E6=80=A7=EF=BC=8C=E5=AF=B9=20U?= =?UTF-8?q?pdate=20=E6=97=B6=E4=B9=9F=E8=83=BD=E7=94=9F=E6=95=88=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlCodeFirstTest.cs | 7 +- .../MsAccess/MsAccessCodeFirstTest.cs | 5 +- .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 5 +- .../Oracle/OracleCodeFirstTest.cs | 5 +- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 5 +- .../SqlServer/SqlServerCodeFirstTest.cs | 5 +- .../Sqlite/SqliteCodeFirstTest.cs | 5 +- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 5 +- .../Internal/CommonProvider/UpdateProvider.cs | 73 ++++++++++++------- FreeSql/Internal/Model/ColumnInfo.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 3 +- 11 files changed, 82 insertions(+), 37 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index a4a29bea..2895bf7f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -28,6 +28,8 @@ namespace FreeSql.Tests.MySqlConnector Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + g.mysql.Update<ı2>().SetSource(item2).ExecuteAffrows(); } class ı2 { @@ -36,8 +38,11 @@ namespace FreeSql.Tests.MySqlConnector public string { get; set; } - [Column(ServerTime = DateTimeKind.Local)] + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs index 1ce9d88a..4f3506f1 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -36,8 +36,11 @@ namespace FreeSql.Tests.MsAccess public string { get; set; } - [Column(ServerTime = DateTimeKind.Local)] + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 6a0da303..193d27ee 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -32,9 +32,12 @@ namespace FreeSql.Tests.MySql public string { get; protected set; } - [Column(ServerTime = DateTimeKind.Local)] + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] public DateTime ʱ { get; protected set; } + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } + public static ı2 Create(string title, DateTime ctm) { return new ı2 { = title, ʱ = ctm }; diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index ca92ea08..d1ae51d2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -36,8 +36,11 @@ namespace FreeSql.Tests.Oracle public string { get; set; } - [Column(ServerTime = DateTimeKind.Local)] + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index f16ed691..c2a92151 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -43,8 +43,11 @@ namespace FreeSql.Tests.PostgreSQL public string { get; set; } - [Column(ServerTime = DateTimeKind.Local)] + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 722b421c..2566b4ec 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -37,8 +37,11 @@ namespace FreeSql.Tests.SqlServer public string { get; set; } - [Column(ServerTime = DateTimeKind.Local)] + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index f3195f9b..fb9e02ec 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -36,8 +36,11 @@ namespace FreeSql.Tests.Sqlite public string { get; set; } - [Column(ServerTime = DateTimeKind.Local)] + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 8953057a..4f3cd9f9 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -121,8 +121,11 @@ namespace FreeSql.Tests public byte[] Binary { get; set; } + [Column(ServerTime = DateTimeKind.Utc, CanUpdate = false)] + public DateTime 创建时间 { get; set; } + [Column(ServerTime = DateTimeKind.Utc)] - public DateTime CreateTime { get; set; } + public DateTime 更新时间 { get; set; } [Column(InsertValueSql = "'123'")] public string InsertValue2 { get; set; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index a38e6d0f..ceb83026 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -557,13 +557,19 @@ namespace FreeSql.Internal.CommonProvider { if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - var val = col.GetMapValue(_source.First()); - if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); + + if (col.Attribute.CanUpdate && string.IsNullOrEmpty(col.DbUpdateValue) == false) + sb.Append(col.DbUpdateValue); else { - sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); - _commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val); + var val = col.GetMapValue(_source.First()); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); + _commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val); + } } ++colidx; } @@ -589,32 +595,36 @@ namespace FreeSql.Internal.CommonProvider if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - var nulls = 0; - var cwsb = new StringBuilder().Append(cw); - foreach (var d in _source) - { - cwsb.Append(" \r\nWHEN "); - ToSqlWhen(cwsb, _table.Primarys, d); - cwsb.Append(" THEN "); - var val = col.GetMapValue(d); - if (_noneParameter) - cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); - else - { - cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); - _commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val); - } - if (val == null || val == DBNull.Value) nulls++; - } - cwsb.Append(" END"); - if (nulls == _source.Count) sb.Append("NULL"); + if (col.Attribute.CanUpdate && string.IsNullOrEmpty(col.DbUpdateValue) == false) + sb.Append(col.DbUpdateValue); else { - ToSqlCaseWhenEnd(cwsb, col); - sb.Append(cwsb.ToString()); + var nulls = 0; + var cwsb = new StringBuilder().Append(cw); + foreach (var d in _source) + { + cwsb.Append(" \r\nWHEN "); + ToSqlWhen(cwsb, _table.Primarys, d); + cwsb.Append(" THEN "); + var val = col.GetMapValue(d); + if (_noneParameter) + cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); + else + { + cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); + _commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val); + } + if (val == null || val == DBNull.Value) nulls++; + } + cwsb.Append(" END"); + if (nulls == _source.Count) sb.Append("NULL"); + else + { + ToSqlCaseWhenEnd(cwsb, col); + sb.Append(cwsb.ToString()); + } + cwsb.Clear(); } - cwsb.Clear(); - ++colidx; } } @@ -626,6 +636,13 @@ namespace FreeSql.Internal.CommonProvider if (_setIncr.Length > 0) sb.Append(_set.Length > 0 ? _setIncr.ToString() : _setIncr.ToString().Substring(2)); + if (_source.Any() == false) + { + foreach (var col in _table.Columns.Values) + if (col.Attribute.CanUpdate && string.IsNullOrEmpty(col.DbUpdateValue) == false) + sb.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(col.DbUpdateValue); + } + if (_table.VersionColumn != null) { var vcname = _commonUtils.QuoteSqlName(_table.VersionColumn.Attribute.Name); diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index 05dc24a2..ef164b67 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -16,6 +16,7 @@ namespace FreeSql.Internal.Model public string DbTypeText { get; internal set; } public string DbDefaultValue { get; internal set; } public string DbInsertValue { get; internal set; } + public string DbUpdateValue { get; internal set; } public int DbSize { get; internal set; } public byte DbPrecision { get; internal set; } public byte DbScale { get; internal set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index b35b342f..46aafb3e 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -188,8 +188,9 @@ namespace FreeSql.Internal //} if (colattr.ServerTime != DateTimeKind.Unspecified && new[] { typeof(DateTime), typeof(DateTimeOffset) }.Contains(colattr.MapType.NullableTypeOrThis())) { - col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; + col.DbDefaultValue = "'1970-1-1'"; col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; + col.DbUpdateValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; } if (string.IsNullOrEmpty(colattr.InsertValueSql) == false) { From 5afeea7711a921ae6263173cb1db1f71665d8506 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 7 Jan 2020 00:41:22 +0800 Subject: [PATCH 0395/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20[Column(MapT?= =?UTF-8?q?ype=20=3D=20typeof(byte[]))]=20=E5=AF=B9=20Guid/string=20?= =?UTF-8?q?=E7=9A=84=E6=98=A0=E5=B0=84=E6=94=AF=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 4 +- FreeSql/Internal/CommonUtils.cs | 6 ++ FreeSql/Internal/UtilsExpressionTree.cs | 65 ++++++++++++++----- .../MsAccessAdo/MsAccessAdo.cs | 5 +- .../MsAccessUtils.cs | 11 +--- .../MySqlAdo/MySqlAdo.cs | 3 + .../FreeSql.Provider.MySql/MySqlUtils.cs | 11 +--- .../MySqlConnectorUtils.cs | 11 +--- .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 5 +- .../Dameng/OdbcDamengExpression.cs | 2 +- .../Dameng/OdbcDamengUtils.cs | 9 +-- .../Default/OdbcAdapter.cs | 9 +-- .../Default/OdbcAdo/OdbcAdo.cs | 3 + .../GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs | 2 + .../GBase/__OdbcGBaseUtils.cs | 11 +--- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 3 + .../MySql/OdbcMySqlUtils.cs | 11 +--- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 5 +- .../Oracle/OdbcOracleExpression.cs | 2 +- .../Oracle/OdbcOracleUtils.cs | 9 +-- .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 3 + .../PostgreSQL/OdbcPostgreSQLUtils.cs | 11 +--- .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 3 + .../SqlServer/OdbcSqlServerUtils.cs | 11 +--- .../OracleAdo/OracleAdo.cs | 5 +- .../OracleExpression.cs | 2 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 9 +-- .../PostgreSQLAdo/PostgreSQLAdo.cs | 3 + .../PostgreSQLUtils.cs | 11 +--- .../SqlServerAdo/SqlServerAdo.cs | 3 + .../SqlServerUtils.cs | 11 +--- .../SqliteAdo/SqliteAdo.cs | 3 + .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 1 - 33 files changed, 128 insertions(+), 135 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 4f3cd9f9..df158e9a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -108,12 +108,14 @@ namespace FreeSql.Tests .NoneParameter().ExecuteAffrows(); var slslsl = g.oracle.Select().ToList(); + var slsld1 = g.oracle.Select().Where(a => a.ID == Guid.Parse("8D9C135E7FEBC41C00BE241C1771FF97")).ToList(); + var slsld2 = g.oracle.Select().Where(a => a.ID == slsld1[0].ID).ToList(); } [Table(Name = "t_text")] public class SendInfo { - [Column(IsPrimary = true)] + [Column(IsPrimary = true, DbType = "raw(16)", MapType = typeof(byte[]))] public Guid ID { get; set; } [Column(Name = "YPID5")] diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 46ab536c..4096acda 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -40,6 +40,12 @@ namespace FreeSql.Internal public abstract string QuoteReadColumn(Type type, Type mapType, string columnName); public virtual string FieldAsAlias(string alias) => $" {alias}"; public virtual string IIF(string test, string ifTrue, string ifElse) => $"case when {test} then {ifTrue} else {ifElse} end"; + public static string BytesSqlRaw(byte[] bytes) + { + var sb = new StringBuilder(); + foreach (var vc in bytes) sb.Append(vc.ToString("X2")); + return sb.ToString(); + } public IFreeSql _orm { get; set; } public ICodeFirst CodeFirst => _orm.CodeFirst; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 46aafb3e..8a52b7f6 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -188,7 +188,7 @@ namespace FreeSql.Internal //} if (colattr.ServerTime != DateTimeKind.Unspecified && new[] { typeof(DateTime), typeof(DateTimeOffset) }.Contains(colattr.MapType.NullableTypeOrThis())) { - col.DbDefaultValue = "'1970-1-1'"; + col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; col.DbUpdateValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; } @@ -1608,6 +1608,19 @@ namespace FreeSql.Internal if (obj == null) return null; return string.Concat(obj); } + static byte[] GuidToBytes(Guid guid) + { + var bytes = new byte[16]; + var guidN = guid.ToString("N"); + for (var a = 0; a < guidN.Length; a += 2) + bytes[a / 2] = byte.Parse($"{guidN[a]}{guidN[a + 1]}", System.Globalization.NumberStyles.HexNumber); + return bytes; + } + static Guid BytesToGuid(byte[] bytes) + { + if (bytes == null) return Guid.Empty; + return Guid.TryParse(BitConverter.ToString(bytes, 0, Math.Min(bytes.Length, 36)).Replace("-", ""), out var tryguid) ? tryguid : Guid.Empty; + } static ConcurrentDictionary>> _dicGetDataReaderValue = new ConcurrentDictionary>>(); static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) }); @@ -1635,6 +1648,11 @@ namespace FreeSql.Internal static PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", BindingFlags.Instance | BindingFlags.Public); static PropertyInfo PropertyDateTimeTicks = typeof(DateTime).GetProperty("Ticks", BindingFlags.Instance | BindingFlags.Public); static ConstructorInfo CtorDateTimeOffsetArgsTicks = typeof(DateTimeOffset). GetConstructor(new[] { typeof(long), typeof(TimeSpan) }); + static Encoding DefaultEncoding = Encoding.UTF8; + static MethodInfo MethodEncodingGetBytes = typeof(Encoding).GetMethod("GetBytes", new[] { typeof(string) }); + static MethodInfo MethodEncodingGetString = typeof(Encoding).GetMethod("GetString", new[] { typeof(byte[]) }); + static MethodInfo MethodGuidToBytes = typeof(Utils).GetMethod("GuidToBytes", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(Guid) }, null); + static MethodInfo MethodBytesToGuid = typeof(Utils).GetMethod("BytesToGuid", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(byte[]) }, null); public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); public static ConcurrentBag> GetDataReaderValueBlockExpressionObjectToStringIfThenElse = new ConcurrentBag>(); @@ -1644,7 +1662,19 @@ namespace FreeSql.Internal var valueExp = Expression.Variable(typeof(object), "locvalue"); Func funcGetExpression = () => { - if (type.FullName == "System.Byte[]") return Expression.Return(returnTarget, valueExp); + if (type.FullName == "System.Byte[]") return Expression.IfThenElse( + Expression.TypeEqual(valueExp, type), + Expression.Return(returnTarget, valueExp), + Expression.IfThenElse( + Expression.TypeEqual(valueExp, typeof(string)), + Expression.Return(returnTarget, Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetBytes, Expression.Convert(valueExp, typeof(string)))), + Expression.IfThenElse( + Expression.Or(Expression.TypeEqual(valueExp, typeof(Guid)), Expression.TypeEqual(valueExp, typeof(Guid?))), + Expression.Return(returnTarget, Expression.Call(MethodGuidToBytes, Expression.Convert(valueExp, typeof(Guid)))), + Expression.Return(returnTarget, Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetBytes, Expression.Call(MethodToString, valueExp))) + ) + ) + ); if (type.IsArray) { var elementType = type.GetElementType(); @@ -1911,7 +1941,8 @@ namespace FreeSql.Internal Expression callToStringExp = Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))); foreach (var toStringFunc in GetDataReaderValueBlockExpressionObjectToStringIfThenElse) callToStringExp = toStringFunc(returnTarget, valueExp, callToStringExp, type); - Expression switchExp = null; + Expression switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); + Expression defaultRetExp = switchExp; if (tryparseExp != null) switchExp = Expression.Switch( Expression.Constant(type), @@ -1921,24 +1952,16 @@ namespace FreeSql.Internal Expression.Constant(typeof(byte)), Expression.Constant(typeof(ushort)), Expression.Constant(typeof(uint)), Expression.Constant(typeof(ulong)), Expression.Constant(typeof(double)), Expression.Constant(typeof(float)), Expression.Constant(typeof(decimal)), Expression.Constant(typeof(DateTime)), Expression.Constant(typeof(DateTimeOffset)) - ), - Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type)) + ) ); else if (tryparseBooleanExp != null) switchExp = Expression.Switch( Expression.Constant(type), - Expression.SwitchCase(tryparseBooleanExp, Expression.Constant(typeof(bool))), - Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type)) + Expression.SwitchCase(tryparseBooleanExp, Expression.Constant(typeof(bool))) ); else if (type == typeof(string)) - switchExp = callToStringExp; - else - switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); + defaultRetExp = switchExp = callToStringExp; - var defaultRetExp = type == typeof(string) ? - callToStringExp : - Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); - return Expression.IfThenElse( Expression.TypeEqual(valueExp, type), Expression.Return(returnTarget, valueExp), @@ -1952,7 +1975,19 @@ namespace FreeSql.Internal Expression.AndAlso(Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(DateTimeOffset))), Expression.TypeEqual(valueExp, typeof(DateTime))), Expression.Return(returnTarget, Expression.Convert( Expression.New(CtorDateTimeOffsetArgsTicks, Expression.MakeMemberAccess(Expression.Convert(valueExp, typeof(DateTime)), PropertyDateTimeTicks), Expression.Constant(TimeSpan.Zero)), typeof(object))), - defaultRetExp + Expression.IfThenElse( + Expression.TypeEqual(valueExp, typeof(byte[])), + Expression.IfThenElse( + Expression.Or(Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(Guid))), Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(Guid?)))), + Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodBytesToGuid, Expression.Convert(valueExp, typeof(byte[]))), typeof(object))), + Expression.IfThenElse( + Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(string))), + Expression.Return(returnTarget, Expression.Convert(Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetString, Expression.Convert(valueExp, typeof(byte[]))), typeof(object))), + defaultRetExp + ) + ), + defaultRetExp + ) ) ) ) diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs index 030b57a1..68d6022c 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs @@ -39,6 +39,7 @@ namespace FreeSql.MsAccess if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) return (bool)param ? -1 : 0; else if (param is string || param is char) @@ -54,7 +55,9 @@ namespace FreeSql.MsAccess } else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).TotalSeconds; - else if (param is IEnumerable) + else if (param is byte[]) + return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; + else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs index 125d7a60..cc5d50ee 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -80,15 +80,8 @@ namespace FreeSql.MsAccess public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.ToString(); - } - else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { var ts = (TimeSpan)value; value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}"; diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index f492d3ca..57751c7e 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -38,6 +38,7 @@ namespace FreeSql.MySql if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string || param is char) @@ -50,6 +51,8 @@ namespace FreeSql.MySql return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; else if (param is MygisGeometry) return string.Concat("ST_GeomFromText('", (param as MygisGeometry).AsText().Replace("'", "''"), "')"); else if (param is IEnumerable) diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index f00192a3..3e97a404 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -121,15 +121,8 @@ namespace FreeSql.MySql public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } - else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { var ts = (TimeSpan)value; value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 5734c337..0f1f122a 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -129,15 +129,8 @@ namespace FreeSql.MySql public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } - else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { var ts = (TimeSpan)value; value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index 7fa731c7..1bb529b0 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -37,7 +37,10 @@ namespace FreeSql.Odbc.Dameng if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); - if (param is bool || param is bool?) + + if (param is byte[]) + return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; + else if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string || param is char) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index f7bcad45..8a26b08c 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -41,7 +41,7 @@ namespace FreeSql.Odbc.Dameng case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; - case "System.Guid": return $"substr(to_char({getExp(operandExp)}), 1, 36)"; + case "System.Guid": return $"to_char({getExp(operandExp)})"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index 0e55dfc1..0a407b2a 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -96,14 +96,7 @@ namespace FreeSql.Odbc.Dameng public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("rawtohex('0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.Append("')").ToString(); - } + if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; return FormatSql("{0}", value, 1); } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs index 9ac1d070..a1dd0314 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs @@ -1,4 +1,5 @@ -using FreeSql.Internal.Model; +using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Text; @@ -55,11 +56,7 @@ namespace FreeSql.Odbc.Default public virtual string ByteRawSql(object value) { if (value == null) return "NULL"; - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.ToString(); + return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; } public virtual string CastSql(string sql, string to) => $"cast({sql} as {to})"; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index cd8a016a..c5df3ef0 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -39,6 +39,7 @@ namespace FreeSql.Odbc.Default if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string) @@ -53,6 +54,8 @@ namespace FreeSql.Odbc.Default return Adapter.DateTimeRawSql(param); else if (param is TimeSpan || param is TimeSpan?) return Adapter.TimeSpanRawSql(param); + else if (param is byte[]) + return Adapter.ByteRawSql(param as byte[]); else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs index 058e742b..7e627c7b 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs @@ -51,6 +51,8 @@ namespace FreeSql.Odbc.GBase return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'"; else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs index c4b722e2..535d561e 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs @@ -124,15 +124,8 @@ namespace FreeSql.Odbc.GBase if (value == null) return "NULL"; value = getParamterValue(type, value); var type2 = value.GetType(); - if (type2 == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("'\\x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } - else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; + if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) { var ts = (TimeSpan)value; return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 810fbf3c..49fb8d61 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -38,6 +38,7 @@ namespace FreeSql.Odbc.MySql if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string || param is char) @@ -50,6 +51,8 @@ namespace FreeSql.Odbc.MySql return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index cfc79dbd..1e048430 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -92,15 +92,8 @@ namespace FreeSql.Odbc.MySql public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } - else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { var ts = (TimeSpan)value; value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index d13b2bb9..b7d9c10b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -37,7 +37,10 @@ namespace FreeSql.Odbc.Oracle if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); - if (param is bool || param is bool?) + + if (param is byte[]) + return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; + else if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string || param is char) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index dbb94fdd..a31f14d9 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -41,7 +41,7 @@ namespace FreeSql.Odbc.Oracle case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; - case "System.Guid": return $"substr(to_char({getExp(operandExp)}), 1, 36)"; + case "System.Guid": return $"to_char({getExp(operandExp)})"; } } break; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index b33fc74d..bf7dc392 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -96,14 +96,7 @@ namespace FreeSql.Odbc.Oracle public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("rawtohex('0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.Append("')").ToString(); - } + if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; return FormatSql("{0}", value, 1); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index fc3c6823..0d3b0526 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -39,6 +39,7 @@ namespace FreeSql.Odbc.PostgreSQL if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; else if (param is string || param is char) @@ -51,6 +52,8 @@ namespace FreeSql.Odbc.PostgreSQL return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'"; else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 5275357f..e139a342 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -124,15 +124,8 @@ namespace FreeSql.Odbc.PostgreSQL if (value == null) return "NULL"; value = getParamterValue(type, value); var type2 = value.GetType(); - if (type2 == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("'\\x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } - else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; + if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) { var ts = (TimeSpan)value; return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index a22adce1..20c58366 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -40,6 +40,7 @@ namespace FreeSql.Odbc.SqlServer if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string) @@ -66,6 +67,8 @@ namespace FreeSql.Odbc.SqlServer } else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).TotalSeconds; + else if (param is byte[]) + return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index 8b00e08d..dd0d11d9 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -83,15 +83,8 @@ namespace FreeSql.Odbc.SqlServer public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.ToString(); - } - else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { var ts = (TimeSpan)value; value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 50beedec..67ac84db 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -37,7 +37,10 @@ namespace FreeSql.Oracle if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); - if (param is bool || param is bool?) + + if (param is byte[]) + return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; + else if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string || param is char) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 4642c1c1..79682275 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -68,7 +68,7 @@ namespace FreeSql.Oracle case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; + case "System.Guid": return $"to_char({getExp(callExp.Arguments[0])})"; } return null; case "NewGuid": diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 68d5a100..f3a7621e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -91,14 +91,7 @@ namespace FreeSql.Oracle public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("rawtohex('0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.Append("')").ToString(); - } + if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; return FormatSql("{0}", value, 1); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index 7f6da042..8f7e2a36 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -40,6 +40,7 @@ namespace FreeSql.PostgreSQL if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList() || param is JToken || param is JObject || param is JArray)) param = Utils.GetDataReaderValue(mapType, param); + bool isdic; if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; @@ -53,6 +54,8 @@ namespace FreeSql.PostgreSQL return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'"; else if (param is JToken || param is JObject || param is JArray) return string.Concat("'", param.ToString().Replace("'", "''"), "'::jsonb"); else if ((isdic = param is Dictionary) || diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 72a680f9..729e3b18 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -156,15 +156,8 @@ namespace FreeSql.PostgreSQL } value = getParamterValue(type, value); var type2 = value.GetType(); - if (type2 == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("'\\x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.Append("'").ToString(); //val = Encoding.UTF8.GetString(val as byte[]); - } - else if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; + if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) { var ts = (TimeSpan)value; return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index b12cdf10..5b247b31 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -41,6 +41,7 @@ namespace FreeSql.SqlServer if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string) @@ -67,6 +68,8 @@ namespace FreeSql.SqlServer } else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).TotalSeconds; + else if (param is byte[]) + return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 9737ffe4..ef5e5b8b 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -94,15 +94,8 @@ namespace FreeSql.SqlServer public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) - { - var bytes = value as byte[]; - var sb = new StringBuilder().Append("0x"); - foreach (var vc in bytes) - sb.Append(vc.ToString("X").PadLeft(2, '0')); - return sb.ToString(); - } - else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { var ts = (TimeSpan)value; value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index c6d37238..213c1db5 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -36,6 +36,7 @@ namespace FreeSql.Sqlite if (param == null) return "NULL"; if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) param = Utils.GetDataReaderValue(mapType, param); + if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string || param is char) @@ -48,6 +49,8 @@ namespace FreeSql.Sqlite return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss"), "'"); else if (param is TimeSpan || param is TimeSpan?) return ((TimeSpan)param).Ticks / 10000; + else if (param is byte[]) + return string.Concat("'", Encoding.UTF8.GetString(param as byte[]), "'"); else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 99c23e82..12b81771 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -94,7 +94,6 @@ namespace FreeSql.Sqlite public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; - if (type == typeof(byte[])) value = Encoding.UTF8.GetString(value as byte[]); return FormatSql("{0}", value, 1); } } From b9afe8552d3fa07850fe8d0b3ce7d4eb6e4be9a3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 7 Jan 2020 00:43:37 +0800 Subject: [PATCH 0396/1029] 1.1.0-preview1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2f9cbbe7..80bf2bfa 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.0.1 + 1.1.0-preview1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 8da4680f..591d13d2 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 68cb7529..0856a3cf 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 79b3dc13..013f2495 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 222b8e28..f2a73214 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.0.1 + 1.1.0-preview1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index c5c5dcf2..a476d728 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 6a050d43..e3a2d46a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 5aa54a7b..59d530b1 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 98f412f3..37a65083 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e4cf46b6..3e0f23ee 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index c66383be..0543e1d7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e459357b..9093e7d7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6b0096a1..6a01d3f5 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 351d72b1..75d1b408 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c7d6e4fc..0aca82db 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 31568f3d..32efa49e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.0.1 + 1.1.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 0addfc638afa28b8e3c57c6b5aabe295175e1fcd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 7 Jan 2020 10:55:36 +0800 Subject: [PATCH 0397/1029] Add raw(18) -> Guid UnitTest --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index df158e9a..c109e1e2 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -98,6 +98,7 @@ namespace FreeSql.Tests fsql.Ado.Query("select * from orderdetail left join ordermain on orderdetail.orderno=ordermain.orderno where ordermain.orderno='1001'"); + g.oracle.Delete().Where("1=1").ExecuteAffrows(); g.oracle.Insert(new[] { new SendInfo{ Code = "001", Binary = Encoding.UTF8.GetBytes("我是中国人") }, @@ -108,8 +109,33 @@ namespace FreeSql.Tests .NoneParameter().ExecuteAffrows(); var slslsl = g.oracle.Select().ToList(); - var slsld1 = g.oracle.Select().Where(a => a.ID == Guid.Parse("8D9C135E7FEBC41C00BE241C1771FF97")).ToList(); - var slsld2 = g.oracle.Select().Where(a => a.ID == slsld1[0].ID).ToList(); + + var mt_codeId = Guid.Parse("2f48c5ca-7257-43c8-9ee2-0e16fa990253"); + Assert.Equal(1, g.oracle.Insert(new SendInfo { ID = mt_codeId, Code = "mt_code", Binary = Encoding.UTF8.GetBytes("我是mt_code") }) + .ExecuteAffrows()); + var mt_code = g.oracle.Select().Where(a => a.ID == mt_codeId).First(); + Assert.NotNull(mt_code); + Assert.Equal(mt_codeId, mt_code.ID); + Assert.Equal("mt_code", mt_code.Code); + + mt_code = g.oracle.Select().Where(a => a.ID == Guid.Parse("2f48c5ca725743c89ee20e16fa990253".ToUpper())).First(); + Assert.NotNull(mt_code); + Assert.Equal(mt_codeId, mt_code.ID); + Assert.Equal("mt_code", mt_code.Code); + + mt_codeId = Guid.Parse("2f48c5ca-7257-43c8-9ee2-0e16fa990251"); + Assert.Equal(1, g.oracle.Insert(new SendInfo { ID = mt_codeId, Code = "mt_code2", Binary = Encoding.UTF8.GetBytes("我是mt_code2") }) + .NoneParameter() + .ExecuteAffrows()); + mt_code = g.oracle.Select().Where(a => a.ID == mt_codeId).First(); + Assert.NotNull(mt_code); + Assert.Equal(mt_codeId, mt_code.ID); + Assert.Equal("mt_code2", mt_code.Code); + + mt_code = g.oracle.Select().Where(a => a.ID == Guid.Parse("2f48c5ca725743c89ee20e16fa990251".ToUpper())).First(); + Assert.NotNull(mt_code); + Assert.Equal(mt_codeId, mt_code.ID); + Assert.Equal("mt_code2", mt_code.Code); } [Table(Name = "t_text")] From 0dec7ff587a8a663be64bea54e8f19be6f8b3a02 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 7 Jan 2020 18:16:37 +0800 Subject: [PATCH 0398/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20MapType=20by?= =?UTF-8?q?te[]=20=E5=AF=B9=20Contains/Parse=20=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E7=9A=84=E5=A4=84=E7=90=86=EF=BC=9B#178?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 3 +++ .../FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs | 2 +- Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs | 2 +- .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 2 +- .../FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs | 8 ++++++-- .../FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs | 2 +- .../GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs | 2 +- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 2 +- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 2 +- .../FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs | 8 ++++++-- .../PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 2 +- .../SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 2 +- Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs | 2 +- Providers/FreeSql.Provider.Oracle/OracleExpression.cs | 8 ++++++-- .../PostgreSQLAdo/PostgreSQLAdo.cs | 2 +- .../SqlServerAdo/SqlServerAdo.cs | 2 +- Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs | 2 +- 17 files changed, 34 insertions(+), 19 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index c109e1e2..bb0e122e 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -110,6 +110,9 @@ namespace FreeSql.Tests var slslsl = g.oracle.Select().ToList(); + var slsls1Ids = slslsl.Select(a => a.ID).ToArray(); + var slslss2 = g.oracle.Select().Where(a => slsls1Ids.Contains(a.ID)).ToList(); + var mt_codeId = Guid.Parse("2f48c5ca-7257-43c8-9ee2-0e16fa990253"); Assert.Equal(1, g.oracle.Insert(new SendInfo { ID = mt_codeId, Code = "mt_code", Binary = Encoding.UTF8.GetBytes("我是mt_code") }) .ExecuteAffrows()); diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs index 68d6022c..f6f8844b 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs @@ -37,7 +37,7 @@ namespace FreeSql.MsAccess public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index 57751c7e..e95438d1 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -36,7 +36,7 @@ namespace FreeSql.MySql public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index 1bb529b0..34c3529c 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -35,7 +35,7 @@ namespace FreeSql.Odbc.Dameng public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is byte[]) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index 8a26b08c..03468326 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -41,7 +41,9 @@ namespace FreeSql.Odbc.Dameng case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; - case "System.Guid": return $"to_char({getExp(operandExp)})"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(operandExp)})"; + return $"to_char({getExp(operandExp)})"; } } break; @@ -68,7 +70,9 @@ namespace FreeSql.Odbc.Dameng case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(callExp.Arguments[0])})"; + return $"to_char({getExp(callExp.Arguments[0])})"; } return null; case "NewGuid": diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index c5df3ef0..32b028f7 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.Default public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs index 7e627c7b..96a01d0e 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.GBase public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 49fb8d61..d9738cc6 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -36,7 +36,7 @@ namespace FreeSql.Odbc.MySql public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index b7d9c10b..fabfcddd 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -35,7 +35,7 @@ namespace FreeSql.Odbc.Oracle public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is byte[]) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index a31f14d9..d55cd439 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -41,7 +41,9 @@ namespace FreeSql.Odbc.Oracle case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; - case "System.Guid": return $"to_char({getExp(operandExp)})"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(operandExp)})"; + return $"to_char({getExp(operandExp)})"; } } break; @@ -68,7 +70,9 @@ namespace FreeSql.Odbc.Oracle case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Guid": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 36)"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(callExp.Arguments[0])})"; + return $"to_char({getExp(callExp.Arguments[0])})"; } return null; case "NewGuid": diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index 0d3b0526..c0ac2ae6 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.PostgreSQL public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index 20c58366..d97d5fc1 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.SqlServer public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 67ac84db..ba81e59c 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -35,7 +35,7 @@ namespace FreeSql.Oracle public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is byte[]) diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 79682275..fc0d0885 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -41,7 +41,9 @@ namespace FreeSql.Oracle case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; - case "System.Guid": return $"substr(to_char({getExp(operandExp)}), 1, 36)"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(operandExp)})"; + return $"to_char({getExp(operandExp)})"; } } break; @@ -68,7 +70,9 @@ namespace FreeSql.Oracle case "System.UInt16": case "System.UInt32": case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; - case "System.Guid": return $"to_char({getExp(callExp.Arguments[0])})"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(callExp.Arguments[0])})"; + return $"to_char({getExp(callExp.Arguments[0])})"; } return null; case "NewGuid": diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index 8f7e2a36..d843b497 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -38,7 +38,7 @@ namespace FreeSql.PostgreSQL public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList() || param is JToken || param is JObject || param is JArray)) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || param is JToken || param is JObject || param is JArray)) param = Utils.GetDataReaderValue(mapType, param); bool isdic; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 5b247b31..5ca513c1 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -39,7 +39,7 @@ namespace FreeSql.SqlServer public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 213c1db5..4e473739 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -34,7 +34,7 @@ namespace FreeSql.Sqlite public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false || mapType.IsArrayOrList())) + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); if (param is bool || param is bool?) From 3af89abbb1401c7112f5a4790b597f1d9becb6d6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 8 Jan 2020 12:28:23 +0800 Subject: [PATCH 0399/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=20DbConnect?= =?UTF-8?q?ionPool.Return=20=E5=9C=A8=20Sqlite=20=E4=B8=8B=E7=9A=84=20bug?= =?UTF-8?q?=EF=BC=9B#179?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- .../CommonProvider/AdoProvider/DbConnectionPool.cs | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs index 9cbd4b7e..a336446b 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs @@ -58,7 +58,7 @@ namespace FreeSql.Internal.CommonProvider if (obj.Value.State != ConnectionState.Closed) obj.Value.Close(); if (_dataType == DataType.Sqlite) - obj.Dispose(); + obj.Value.Dispose(); } public bool SetUnavailable(Exception exception) From fa349a2567acf80a43a663ad12e3ec4ff2e890a6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 8 Jan 2020 12:39:12 +0800 Subject: [PATCH 0400/1029] v1.1.0-preview2 #179 #178 #177 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 80bf2bfa..b84986ff 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 591d13d2..1503730a 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0856a3cf..efd49670 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 013f2495..b1e22877 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index f2a73214..85a7bf6d 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.1.0-preview1 + 1.1.0-preview2 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a476d728..21b86586 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e3a2d46a..2baa13f4 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 59d530b1..61bfd7f6 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 37a65083..865096bf 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3e0f23ee..933c287f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0543e1d7..93d50569 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 9093e7d7..d6397d62 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6a01d3f5..0e102172 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 75d1b408..92931d49 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0aca82db..5d7353e5 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 32efa49e..fe86af90 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview1 + 1.1.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From f5f5ccd9a8ae90fdc3d85cf4708617559c76430e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 9 Jan 2020 10:19:24 +0800 Subject: [PATCH 0401/1029] Add Contributors --- readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 564b2192..31344638 100644 --- a/readme.md +++ b/readme.md @@ -276,6 +276,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [movingsam](https://github.com/movingsam)、 [ALer-R](https://github.com/ALer-R)、 [zouql](https://github.com/zouql)、 -深圳|凉茶 +深圳|凉茶、 +[densen2014](https://github.com/densen2014) (QQ群:4336577) \ No newline at end of file From ee1eb959a5346bd575d8782ba09e8e9f40a4a9ce Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 9 Jan 2020 10:27:53 +0800 Subject: [PATCH 0402/1029] add Contributors --- readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 31344638..89a25fba 100644 --- a/readme.md +++ b/readme.md @@ -277,6 +277,8 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [ALer-R](https://github.com/ALer-R)、 [zouql](https://github.com/zouql)、 深圳|凉茶、 -[densen2014](https://github.com/densen2014) +[densen2014](https://github.com/densen2014)、 +[LiaoLiaoWuJu](https://github.com/LiaoLiaoWuJu)、 +[hd2y](https://github.com/hd2y) (QQ群:4336577) \ No newline at end of file From 6eb720d2aeb29a64dcccee1b36856b36698013a2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 9 Jan 2020 15:27:46 +0800 Subject: [PATCH 0403/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Prov?= =?UTF-8?q?ider.MySqlConnector=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=20Ex?= =?UTF-8?q?ecuteMySqlBulkCopy=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSqlMySqlConnectorGlobalExtensions.cs | 147 ++++++++++++++++++ 2 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 93d50569..b40a0440 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -23,7 +23,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs new file mode 100644 index 00000000..6b22af02 --- /dev/null +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs @@ -0,0 +1,147 @@ +using FreeSql; +using MySql.Data.MySqlClient; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +public static class FreeSqlMySqlConnectorGlobalExtensions +{ + #region ExecuteMySqlBulkCopy + /// + /// MySql MySqlCopyBulk 批量插入功能 + /// 使用 IgnoreColumns/InsertColumns 设置忽略/指定导入的列 + /// 使用 WithConnection/WithTransaction 传入连接/事务对象 + /// 提示:若本方法不能满足,请使用 IInsert<T>.ToDataTable 方法得到 DataTable 对象后,自行处理。 + /// MySqlCopyBulk 与 insert into t values(..),(..),(..) 性能测试参考: + /// 插入180000行,52列:28,405ms 与 38,481ms,10列:6,504ms 与 11,171ms + /// 插入10000行,52列:1,142ms 与 2,234ms,10列:339ms 与 866ms + /// 插入5000行,52列:657ms 与 1,136ms,10列:257ms 与 366ms + /// 插入2000行,52列:451ms 与 284ms,10列:116ms 与 80ms + /// 插入1000行,52列:435ms 与 239ms,10列:87ms 与 83ms + /// 插入500行,52列:592ms 与 167ms,10列:100ms 与 50ms + /// 插入100行,52列:47ms 与 66ms,10列:16ms 与 24ms + /// 插入50行,52列:22ms 与 30ms,10列:16ms 与 34ms + /// + /// + /// + /// + public static void ExecuteMySqlBulkCopy(this IInsert that, int? bulkCopyTimeout = null) where T : class + { + var insert = that as FreeSql.MySql.Curd.MySqlInsert; + if (insert == null) throw new Exception("ExecuteMySqlBulkCopy 是 FreeSql.Provider.MySqlConnector 特有的功能"); + + var dt = that.ToDataTable(); + if (dt.Rows.Count == 0) return; + + Action writeToServer = bulkCopy => + { + if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; + bulkCopy.DestinationTableName = dt.TableName; + bulkCopy.WriteToServer(dt); + }; + + try + { + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + writeToServer(new MySqlBulkCopy(conn.Value as MySqlConnection)); + } + } + else if (insert.InternalTransaction != null) + { + writeToServer(new MySqlBulkCopy(insert.InternalTransaction.Connection as MySqlConnection)); + } + else if (insert.InternalConnection != null) + { + var conn = insert.InternalConnection as MySqlConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + conn.Open(); + } + try + { + writeToServer(new MySqlBulkCopy(conn)); + } + finally + { + if (isNotOpen) + conn.Close(); + } + } + else + { + throw new NotImplementedException("ExecuteMySqlBulkCopy 未实现错误,请反馈给作者"); + } + } + finally + { + dt.Clear(); + } + } +#if net40 +#else + async public static Task ExecuteMySqlBulkCopyAsync(this IInsert that, int? bulkCopyTimeout = null) where T : class + { + var insert = that as FreeSql.MySql.Curd.MySqlInsert; + if (insert == null) throw new Exception("ExecuteMySqlBulkCopyAsync 是 FreeSql.Provider.MySqlConnector 特有的功能"); + + var dt = that.ToDataTable(); + if (dt.Rows.Count == 0) return; + + Func writeToServer = bulkCopy => + { + if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; + bulkCopy.DestinationTableName = dt.TableName; + return bulkCopy.WriteToServerAsync(dt); + }; + + try + { + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + await writeToServer(new MySqlBulkCopy(conn.Value as MySqlConnection)); + } + } + else if (insert.InternalTransaction != null) + { + await writeToServer(new MySqlBulkCopy(insert.InternalTransaction.Connection as MySqlConnection)); + } + else if (insert.InternalConnection != null) + { + var conn = insert.InternalConnection as MySqlConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + conn.Open(); + } + try + { + await writeToServer(new MySqlBulkCopy(conn)); + } + finally + { + if (isNotOpen) + conn.Close(); + } + } + else + { + throw new NotImplementedException("ExecuteMySqlBulkCopyAsync 未实现错误,请反馈给作者"); + } + } + finally + { + dt.Clear(); + } + } +#endif + #endregion +} From 90101e2d2293d0ee95e2db550fd2e564041149a7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 9 Jan 2020 18:21:29 +0800 Subject: [PATCH 0404/1029] v1.1.0-preview3 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- .../Extensions/DependencyInjection.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 18 ++++++++++++------ FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ .../Extensions/DependencyInjection.cs | 2 +- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 6 +++--- FreeSql.Repository/FreeSql.Repository.csproj | 4 ++-- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 40 insertions(+), 27 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b84986ff..fbae725e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 1503730a..ac56c127 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index efd49670..bc03eef8 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b1e22877..6cf592b5 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 85a7bf6d..12b2b207 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.1.0-preview2 + 1.1.0-preview3 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Extensions/DependencyInjection.cs index cad5047f..c22b4ee8 100644 --- a/FreeSql.DbContext/Extensions/DependencyInjection.cs +++ b/FreeSql.DbContext/Extensions/DependencyInjection.cs @@ -1,4 +1,4 @@ -#if ns20 +#if netcoreapp using Microsoft.Extensions.DependencyInjection; using System; using System.Linq; diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 21b86586..2155259a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -1,8 +1,8 @@  - netstandard2.0;net45;net40 - 1.1.0-preview2 + netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 + 1.1.0-preview3 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access @@ -26,16 +26,22 @@ 3 - - ns20;netstandard20 - net40 + + netcoreapp + - + + + + + + + diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs index 9781bee9..019684f1 100644 --- a/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs +++ b/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs @@ -1,4 +1,4 @@ -#if ns20 +#if netcoreapp using System; using System.Reflection; diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 4f619c71..a21bb5af 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -11,7 +11,7 @@ namespace FreeSql { public class UnitOfWork : IUnitOfWork { -#if ns20 +#if netcoreapp public static readonly AsyncLocal Current = new AsyncLocal(); #endif @@ -35,7 +35,7 @@ namespace FreeSql public UnitOfWork(IFreeSql fsql) { _fsql = fsql; -#if ns20 +#if netcoreapp Current.Value = this; #endif } @@ -48,7 +48,7 @@ namespace FreeSql _fsql.Ado.MasterPool.Return(_conn); _tran = null; _conn = null; -#if ns20 +#if netcoreapp Current.Value = null; #endif EntityChangeReport?.Report.Clear(); diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 2baa13f4..67fcc25b 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -1,8 +1,8 @@  - netstandard2.0;net45;net40 - 1.1.0-preview2 + netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 + 1.1.0-preview3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 61bfd7f6..adcfc21e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 865096bf..5a92b5d9 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 933c287f..50389eb2 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index b40a0440..29854788 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d6397d62..733a8901 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 0e102172..0dd4dfb7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 92931d49..b850adb8 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5d7353e5..f3e0b751 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fe86af90..4d2d0a3f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview2 + 1.1.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 3fe4c54ee4beb4bda9f504f07f48f7dd8926da47 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Jan 2020 22:03:47 +0800 Subject: [PATCH 0405/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbFirst=20my?= =?UTF-8?q?sql/pgsql/sqlserver=20=E8=8E=B7=E5=8F=96=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E7=9A=84=20bug=EF=BC=9B=200.10.7=20=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E5=90=8E=E7=9A=84=20bug=20#182?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs | 2 +- Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs | 2 +- Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs | 2 +- .../FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs | 2 +- .../FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs | 2 +- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs | 2 +- Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 04feb558..e170694e 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -287,7 +287,7 @@ case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' from information_schema.statistics a -where a.table_schema in ({1}) and {0} and a.index_name <> 'PRIMARY' +where a.table_schema in ({1}) and {0} ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs index e2f10f07..245ab0cf 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs @@ -294,7 +294,7 @@ inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} and a.indisprimary = 'f' +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index afd2549b..f9506697 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -257,7 +257,7 @@ case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' from information_schema.statistics a -where a.table_schema in ({1}) and {0} and a.index_name <> 'PRIMARY' +where a.table_schema in ({1}) and {0} ", loc8, databaseIn); ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index d4229572..d248291e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -294,7 +294,7 @@ inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} and a.indisprimary = 'f' +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index 4e3652b1..5f21d5dd 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -305,7 +305,7 @@ select from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id -where {loc8.ToString().Replace("a.table_name", "a.object_id")} and b.is_primary_key = 0 +where {loc8.ToString().Replace("a.table_name", "a.object_id")} ; use [{olddatabase}]; "; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 5910c1d3..f10093c2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -405,7 +405,7 @@ inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} and a.indisprimary = 'f' +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 1f709c10..31089821 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -308,7 +308,7 @@ select from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id -where {loc8.ToString().Replace("a.table_name", "a.object_id")} and b.is_primary_key = 0 +where {loc8.ToString().Replace("a.table_name", "a.object_id")} ; use [{olddatabase}]; "; From 994cc475c214d0e376c5e78416f751d7ce9e33db Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 11 Jan 2020 02:22:16 +0800 Subject: [PATCH 0406/1029] =?UTF-8?q?-=20=E8=A7=A3=E5=86=B3=20=E8=A1=A8?= =?UTF-8?q?=E5=90=8D=E5=90=8D=E7=A7=B0=E5=8C=85=E5=90=AB=E7=82=B9=EF=BC=8C?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=BF=9B=E8=A1=8C=20CRUD=20=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E7=94=B1=E4=BA=8E=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=9A=84=E5=A4=8D=E6=9D=82=E6=80=A7=EF=BC=8C=E6=AD=A4=E7=B1=BB?= =?UTF-8?q?=E6=83=85=E5=86=B5=E4=BB=85=E6=94=AF=E6=8C=81=20MySql/Sqlite=20?= =?UTF-8?q?CodeFirst=20=E8=87=AA=E5=8A=A8=E8=BF=81=E7=A7=BB=EF=BC=9B=20>?= =?UTF-8?q?=20=E6=B3=A8=E6=84=8F=EF=BC=9A=E5=B0=BD=E9=87=8F=E4=B8=8D?= =?UTF-8?q?=E8=A6=81=E4=BD=BF=E7=94=A8=E5=B8=A6=E7=82=B9=E7=9A=84=E8=A1=A8?= =?UTF-8?q?=E5=90=8D=EF=BC=8C=E5=8F=AA=E6=9C=89=20MySql/Sqlite=20=E5=AF=B9?= =?UTF-8?q?=E6=AD=A4=E7=B1=BB=E8=A1=A8=E5=90=8D=E6=94=AF=E6=8C=81=20CodeFi?= =?UTF-8?q?rst=E3=80=82=E4=BD=86=E6=98=AF=E5=AE=83=E4=B8=8D=E5=BD=B1?= =?UTF-8?q?=E5=93=8D=20CRUD=20=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20[Table(Name=20=3D=20"`sys.config`")]=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/RazorModel.cs | 8 +- .../MySqlConnector/MySqlCodeFirstTest.cs | 27 +++++++ .../MySql/MySqlCodeFirstTest.cs | 27 +++++++ .../FreeSql.Tests/Internal/CommonUtilsTest.cs | 78 +++++++++++++++++++ .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 28 +++++++ .../Sqlite/SqliteCodeFirstTest.cs | 28 +++++++ FreeSql/Internal/CommonUtils.cs | 17 +++- .../Curd/MsAccessDelete.cs | 2 +- .../MsAccessUtils.cs | 20 +++-- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 34 ++++---- .../FreeSql.Provider.MySql/MySqlUtils.cs | 21 ++--- .../MySqlConnectorUtils.cs | 21 ++--- .../Dameng/OdbcDamengCodeFirst.cs | 7 +- .../Dameng/OdbcDamengUtils.cs | 19 +++-- .../Default/OdbcUtils.cs | 22 +++--- .../GBase/__OdbcGBaseCodeFirst.cs | 7 +- .../GBase/__OdbcGBaseUtils.cs | 34 ++++---- .../MySql/OdbcMySqlCodeFirst.cs | 28 +++---- .../MySql/OdbcMySqlUtils.cs | 21 ++--- .../Oracle/OdbcOracleCodeFirst.cs | 7 +- .../Oracle/OdbcOracleUtils.cs | 19 +++-- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 7 +- .../PostgreSQL/OdbcPostgreSQLUtils.cs | 34 ++++---- .../SqlServer/OdbcSqlServerCodeFirst.cs | 7 +- .../SqlServer/OdbcSqlServerUtils.cs | 20 +++-- .../OracleCodeFirst.cs | 7 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 19 +++-- .../PostgreSQLCodeFirst.cs | 12 ++- .../PostgreSQLUtils.cs | 23 +++--- .../SqlServerCodeFirst.cs | 13 ++-- .../SqlServerUtils.cs | 19 +++-- .../SqliteCodeFirst.cs | 26 +++---- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 19 +++-- 33 files changed, 467 insertions(+), 214 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Internal/CommonUtilsTest.cs diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index d754ee2f..7a8dbdb9 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; -using System.Threading.Tasks; public class RazorModel { public RazorModel(IFreeSql fsql, string nameSpace, bool[] NameOptions, List tables, DbTableInfo table) { @@ -55,7 +54,12 @@ public class RazorModel { var sb = new List(); if (GetCsName(this.FullTableName) != this.FullTableName) - sb.Add("Name = \"" + this.FullTableName + "\""); + { + if (this.FullTableName.IndexOf('.') == -1) + sb.Add("Name = \"" + this.FullTableName + "\""); + else + sb.Add("Name = \"" + this.FullTableName + "\""); //Todo: QuoteSqlName + } if (sb.Any() == false) return null; return "[Table(" + string.Join(", ", sb) + ")]"; diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 2895bf7f..7f174fd9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -10,6 +10,33 @@ namespace FreeSql.Tests.MySqlConnector { public class MySqlCodeFirstTest { + [Fact] + public void е() + { + var item = new tbdot01 { name = "insert" }; + g.mysql.Insert(item).ExecuteAffrows(); + + var find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("insert", find.name); + + Assert.Equal(1, g.mysql.Update().Set(a => a.name == "update").Where(a => a.id == item.id).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("update", find.name); + + Assert.Equal(1, g.mysql.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.Null(find); + } + [Table(Name = "`sys.tbdot01`")] + class tbdot01 + { + public Guid id { get; set; } + public string name { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index e28cb85f..d06c3a27 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -10,6 +10,33 @@ namespace FreeSql.Tests.Odbc.MySql { public class MySqlCodeFirstTest { + [Fact] + public void е() + { + var item = new tbdot01 { name = "insert" }; + g.mysql.Insert(item).ExecuteAffrows(); + + var find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("insert", find.name); + + Assert.Equal(1, g.mysql.Update().Set(a => a.name == "update").Where(a => a.id == item.id).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("update", find.name); + + Assert.Equal(1, g.mysql.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.Null(find); + } + [Table(Name = "`sys.tbdot01`")] + class tbdot01 + { + public Guid id { get; set; } + public string name { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests/Internal/CommonUtilsTest.cs b/FreeSql.Tests/FreeSql.Tests/Internal/CommonUtilsTest.cs new file mode 100644 index 00000000..ffa21679 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Internal/CommonUtilsTest.cs @@ -0,0 +1,78 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using System.Data.SqlClient; +using kwlib; +using System.Diagnostics; +using System.IO; +using System.Text; +using FreeSql.Internal; + +namespace FreeSql.InternalTests +{ + public class CommonUtilsTest + { + + [Fact] + public void GetSplitTableNames() + { + var tbname = CommonUtils.GetSplitTableNames("table1", '`', '`', 2); + Assert.Equal("table1", tbname[0]); + + tbname = CommonUtils.GetSplitTableNames("table1", '"', '"', 2); + Assert.Equal("table1", tbname[0]); + + tbname = CommonUtils.GetSplitTableNames("table1", '[', ']', 2); + Assert.Equal("table1", tbname[0]); + + //--- + + tbname = CommonUtils.GetSplitTableNames("schema1.table1", '`', '`', 2); + Assert.Equal("schema1", tbname[0]); + Assert.Equal("table1", tbname[1]); + + tbname = CommonUtils.GetSplitTableNames("schema1.table1", '"', '"', 2); + Assert.Equal("schema1", tbname[0]); + Assert.Equal("table1", tbname[1]); + + tbname = CommonUtils.GetSplitTableNames("schema1.table1", '[', ']', 2); + Assert.Equal("schema1", tbname[0]); + Assert.Equal("table1", tbname[1]); + + //--- + + tbname = CommonUtils.GetSplitTableNames("`sys.table1`", '`', '`', 2); + Assert.Equal("sys.table1", tbname[0]); + + tbname = CommonUtils.GetSplitTableNames("\"sys.table1\"", '"', '"', 2); + Assert.Equal("sys.table1", tbname[0]); + + tbname = CommonUtils.GetSplitTableNames("[sys.table1]", '[', ']', 2); + Assert.Equal("sys.table1", tbname[0]); + + //--- + + tbname = CommonUtils.GetSplitTableNames("`schema1`.`sys.table1`", '`', '`', 2); + Assert.Equal("schema1", tbname[0]); + Assert.Equal("sys.table1", tbname[1]); + + tbname = CommonUtils.GetSplitTableNames("\"schema1\".\"sys.table1\"", '"', '"', 2); + Assert.Equal("schema1", tbname[0]); + Assert.Equal("sys.table1", tbname[1]); + + tbname = CommonUtils.GetSplitTableNames("[schema1].[sys.table1]", '[', ']', 2); + Assert.Equal("schema1", tbname[0]); + Assert.Equal("sys.table1", tbname[1]); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 193d27ee..f98d084c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -11,6 +11,34 @@ namespace FreeSql.Tests.MySql public class MySqlCodeFirstTest { + [Fact] + public void е() + { + var item = new tbdot01 { name = "insert" }; + g.mysql.Insert(item).ExecuteAffrows(); + + var find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("insert", find.name); + + Assert.Equal(1, g.mysql.Update().Set(a => a.name == "update").Where(a => a.id == item.id).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("update", find.name); + + Assert.Equal(1, g.mysql.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.Null(find); + } + [Table(Name = "`sys.tbdot01`")] + class tbdot01 + { + public Guid id { get; set; } + public string name { get; set; } + } + [Fact] public void ı_ֶ() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index fb9e02ec..9eb09d80 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -11,6 +11,34 @@ namespace FreeSql.Tests.Sqlite public class SqliteCodeFirstTest { + [Fact] + public void е() + { + var item = new tbdot01 { name = "insert" }; + g.sqlite.Insert(item).ExecuteAffrows(); + + var find = g.sqlite.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("insert", find.name); + + Assert.Equal(1, g.sqlite.Update().Set(a => a.name == "update").Where(a => a.id == item.id).ExecuteAffrows()); + find = g.sqlite.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("update", find.name); + + Assert.Equal(1, g.sqlite.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + find = g.sqlite.Select().Where(a => a.id == item.id).First(); + Assert.Null(find); + } + [Table(Name = "\"sys.tbdot01\"")] + class tbdot01 + { + public Guid id { get; set; } + public string name { get; set; } + } + [Fact] public void ı_ֶ() { diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 4096acda..f695b8aa 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -27,8 +27,23 @@ namespace FreeSql.Internal public abstract DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value); public abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); public abstract string FormatSql(string sql, params object[] args); - public abstract string QuoteSqlName(string name); + public abstract string QuoteSqlName(params string[] name); public abstract string TrimQuoteSqlName(string name); + public abstract string[] SplitTableName(string name); + public static string[] GetSplitTableNames(string name, char leftQuote, char rightQuote, int size) + { + if (string.IsNullOrEmpty(name)) return null; + if (name.IndexOf(leftQuote) == -1) return name.Split(new[] { '.' }, size); + name = Regex.Replace(name, + (leftQuote == '[' ? "\\" : "") + + leftQuote + @"([^" + (rightQuote == ']' ? "\\" : "") + rightQuote + @"]+)" + + (rightQuote == ']' ? "\\" : "") + + rightQuote, m => m.Groups[1].Value.Replace('.', '?')); + var ret = name.Split(new[] { '.' }, size); + for (var a = 0; a < ret.Length; a++) + ret[a] = ret[a].Replace('?', '.'); + return ret; + } public abstract string QuoteParamterName(string name); public abstract string IsNull(string sql, object value); public abstract string StringConcat(string[] objs, Type[] types); diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs index 31e2c19e..7990aae6 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs @@ -22,7 +22,7 @@ namespace FreeSql.MsAccess.Curd #if net40 #else - async public override Task> ExecuteDeletedAsync() + public override Task> ExecuteDeletedAsync() { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs index cc5d50ee..31c9b7a1 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -2,11 +2,8 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Data.OleDb; -using System.Linq; -using System.Linq.Expressions; using System.Text; namespace FreeSql.MsAccess @@ -40,12 +37,18 @@ namespace FreeSql.MsAccess }); public override string FormatSql(string sql, params object[] args) => sql?.FormatAccess(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("[") && nametrim.EndsWith("]")) + return nametrim; + return $"[{nametrim.Replace(".", "].[")}]"; + } + return $"[{string.Join("].[", name)}]"; } public override string TrimQuoteSqlName(string name) { @@ -54,6 +57,7 @@ namespace FreeSql.MsAccess return nametrim; //原生SQL return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '[', ']', 2); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"iif(isnull({sql}), {value}, {sql})"; public override string StringConcat(string[] objs, Type[] types) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index b942a2b4..6cf5089d 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -1,10 +1,6 @@ -using FreeSql.DataAnnotations; -using FreeSql.DatabaseModel; -using FreeSql.Internal; -using FreeSql.Internal.Model; +using FreeSql.Internal; using MySql.Data.MySqlClient; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Linq; @@ -112,14 +108,14 @@ namespace FreeSql.MySql var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { database, tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -145,7 +141,7 @@ namespace FreeSql.MySql if (tboldname == null) { //创建表 - var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var createTableName = _commonUtils.QuoteSqlName(tbname[0], tbname[1]); sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { @@ -180,7 +176,7 @@ namespace FreeSql.MySql } //如果新表,旧表在一个数据库下,直接修改表名 if (string.Compare(tbname[0], tboldname[0], true) == 0) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tboldname[0], tboldname[1])).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); else { //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 @@ -237,8 +233,8 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); isCommentChanged) { if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable && tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); @@ -247,7 +243,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) { //修改列名 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); @@ -256,7 +252,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); continue; } //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(tbcol.DbDefaultValue); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); @@ -278,10 +274,10 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -299,8 +295,8 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI } //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + var tablename = tboldname == null ? _commonUtils.QuoteSqlName(tbname[0], tbname[1]) : _commonUtils.QuoteSqlName(tboldname[0], tboldname[1]); + var tmptablename = _commonUtils.QuoteSqlName(tbname[0], $"FreeSqlTmp_{tbname[1]}"); //创建临时表 sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) @@ -343,7 +339,7 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 3e97a404..3da98012 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -4,10 +4,6 @@ using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data.Common; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Text; namespace FreeSql.MySql { @@ -69,12 +65,18 @@ namespace FreeSql.MySql }); public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("`") && nametrim.EndsWith("`")) + return nametrim; + return $"`{nametrim.Replace(".", "`.`")}`"; + } + return $"`{string.Join("`.`", name)}`"; } public override string TrimQuoteSqlName(string name) { @@ -83,6 +85,7 @@ namespace FreeSql.MySql return nametrim; //原生SQL return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '`', '`', 2); public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 0f1f122a..8541261f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -4,10 +4,6 @@ using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data.Common; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Text; namespace FreeSql.MySql { @@ -77,12 +73,18 @@ namespace FreeSql.MySql }); public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("`") && nametrim.EndsWith("`")) + return nametrim; + return $"`{nametrim.Replace(".", "`.`")}`"; + } + return $"`{string.Join("`.`", name)}`"; } public override string TrimQuoteSqlName(string name) { @@ -91,6 +93,7 @@ namespace FreeSql.MySql return nametrim; //原生SQL return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '`', '`', 2); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index f9e6d7d0..0522f9c2 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -94,15 +94,15 @@ namespace FreeSql.Odbc.Dameng var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -111,6 +111,7 @@ namespace FreeSql.Odbc.Dameng primaryKeyName = null; } } + //codefirst 不支持表名中带 . if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index 0a407b2a..1bfc029b 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -4,8 +4,6 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; -using System.Linq.Expressions; -using System.Text; namespace FreeSql.Odbc.Dameng { @@ -68,12 +66,18 @@ namespace FreeSql.Odbc.Dameng }); public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcOracle(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; } public override string TrimQuoteSqlName(string name) { @@ -82,6 +86,7 @@ namespace FreeSql.Odbc.Dameng return nametrim; //原生SQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index ba0937b5..c3a64399 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -2,12 +2,8 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Data.Odbc; -using System.Linq; -using System.Linq.Expressions; -using System.Text; namespace FreeSql.Odbc.Default { @@ -39,13 +35,18 @@ namespace FreeSql.Odbc.Default }); public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbc(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - //return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; - return $"{Adapter.QuoteSqlNameLeft}{nametrim.TrimStart(Adapter.QuoteSqlNameLeft).TrimEnd(Adapter.QuoteSqlNameRight).Replace(".", $"{Adapter.QuoteSqlNameRight}.{Adapter.QuoteSqlNameLeft}")}{Adapter.QuoteSqlNameRight}"; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith(Adapter.QuoteSqlNameLeft.ToString()) && nametrim.EndsWith(Adapter.QuoteSqlNameRight.ToString())) + return nametrim; + return $"{Adapter.QuoteSqlNameLeft}{nametrim.TrimStart(Adapter.QuoteSqlNameLeft).TrimEnd(Adapter.QuoteSqlNameRight).Replace(".", $"{Adapter.QuoteSqlNameRight}.{Adapter.QuoteSqlNameLeft}")}{Adapter.QuoteSqlNameRight}"; + } + return $"{Adapter.QuoteSqlNameLeft}{string.Join($"{Adapter.QuoteSqlNameRight}.{Adapter.QuoteSqlNameLeft}", name)}{Adapter.QuoteSqlNameRight}"; } public override string TrimQuoteSqlName(string name) { @@ -55,6 +56,7 @@ namespace FreeSql.Odbc.Default //return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; return $"{nametrim.TrimStart(Adapter.QuoteSqlNameLeft).TrimEnd(Adapter.QuoteSqlNameRight).Replace($"{Adapter.QuoteSqlNameRight}.{Adapter.QuoteSqlNameLeft}", ".").Replace($".{Adapter.QuoteSqlNameLeft}", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, Adapter.QuoteSqlNameLeft, Adapter.QuoteSqlNameRight, 2); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => Adapter.IsNullSql(sql, value); public override string StringConcat(string[] objs, Type[] types) => Adapter.ConcatSql(objs, types); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs index 2895d9de..9f3b6b11 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs @@ -90,14 +90,14 @@ namespace FreeSql.Odbc.GBase var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -105,6 +105,7 @@ namespace FreeSql.Odbc.GBase tboldname = null; } } + //codefirst 不支持表名、模式名、数据库名中带 . if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs index 535d561e..7c6a56e3 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs @@ -1,16 +1,11 @@ using FreeSql.Internal; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Data.Common; -using System.Linq; -using System.Net; -using System.Text; -using System.Linq.Expressions; -using System.Reflection; -using System.Data.Odbc; using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq; +using System.Text; namespace FreeSql.Odbc.GBase { @@ -94,12 +89,18 @@ namespace FreeSql.Odbc.GBase }); public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcPostgreSQL(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; } public override string TrimQuoteSqlName(string name) { @@ -108,6 +109,7 @@ namespace FreeSql.Odbc.GBase return nametrim; //原生SQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 01361851..ea03dc69 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -101,14 +101,14 @@ namespace FreeSql.Odbc.MySql var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { database, tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -134,7 +134,7 @@ namespace FreeSql.Odbc.MySql if (tboldname == null) { //创建表 - var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var createTableName = _commonUtils.QuoteSqlName(tbname[0], tbname[1]); sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { @@ -169,7 +169,7 @@ namespace FreeSql.Odbc.MySql } //如果新表,旧表在一个数据库下,直接修改表名 if (string.Compare(tbname[0], tboldname[0], true) == 0) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tboldname[0], tboldname[1])).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); else { //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 @@ -226,8 +226,8 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); isCommentChanged) { if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable && tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); @@ -236,7 +236,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) { //修改列名 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); @@ -245,7 +245,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); continue; } //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(tbcol.DbDefaultValue); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); @@ -267,10 +267,10 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -288,8 +288,8 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI } //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + var tablename = tboldname == null ? _commonUtils.QuoteSqlName(tbname[0], tbname[1]) : _commonUtils.QuoteSqlName(tboldname[0], tboldname[1]); + var tmptablename = _commonUtils.QuoteSqlName(tbname[0], $"FreeSqlTmp_{tbname[1]}"); //创建临时表 sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) @@ -332,7 +332,7 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 1e048430..50f45dbf 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -4,10 +4,6 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Text; namespace FreeSql.Odbc.MySql { @@ -40,12 +36,18 @@ namespace FreeSql.Odbc.MySql }); public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcMySql(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"`{nametrim.Trim('`').Replace(".", "`.`")}`"; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("`") && nametrim.EndsWith("`")) + return nametrim; + return $"`{nametrim.Replace(".", "`.`")}`"; + } + return $"`{string.Join("`.`", name)}`"; } public override string TrimQuoteSqlName(string name) { @@ -54,6 +56,7 @@ namespace FreeSql.Odbc.MySql return nametrim; //原生SQL return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '`', '`', 2); public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index eece275f..302342ab 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -94,15 +94,15 @@ namespace FreeSql.Odbc.Oracle var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -111,6 +111,7 @@ namespace FreeSql.Odbc.Oracle primaryKeyName = null; } } + //codefirst 不支持表名中带 . if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index bf7dc392..9054c31b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -4,8 +4,6 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; -using System.Linq.Expressions; -using System.Text; namespace FreeSql.Odbc.Oracle { @@ -68,12 +66,18 @@ namespace FreeSql.Odbc.Oracle }); public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcOracle(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; } public override string TrimQuoteSqlName(string name) { @@ -82,6 +86,7 @@ namespace FreeSql.Odbc.Oracle return nametrim; //原生SQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 6872fc2f..a09e2223 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -90,14 +90,14 @@ namespace FreeSql.Odbc.PostgreSQL var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -105,6 +105,7 @@ namespace FreeSql.Odbc.PostgreSQL tboldname = null; } } + //codefirst 不支持表名、模式名、数据库名中带 . if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index e139a342..62d259e3 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -1,16 +1,11 @@ using FreeSql.Internal; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Data.Common; -using System.Linq; -using System.Net; -using System.Text; -using System.Linq.Expressions; -using System.Reflection; -using System.Data.Odbc; using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq; +using System.Text; namespace FreeSql.Odbc.PostgreSQL { @@ -94,12 +89,18 @@ namespace FreeSql.Odbc.PostgreSQL }); public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcPostgreSQL(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; } public override string TrimQuoteSqlName(string name) { @@ -108,6 +109,7 @@ namespace FreeSql.Odbc.PostgreSQL return nametrim; //原生SQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 87d5f2bb..95f4b76d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -135,16 +135,16 @@ ELSE var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 3); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] }; if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] }; if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] }; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 3); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { database, "dbo", tbtmpname[0] }; if (tbtmpname?.Length == 2) tbtmpname = new[] { database, tbtmpname[0], tbtmpname[1] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1] || tbname[2] != tbtmpname[2]) @@ -153,6 +153,7 @@ ELSE tboldname = null; } } + //codefirst 不支持表名、模式名、数据库名中带 . if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index dd0d11d9..adfa99ab 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -2,11 +2,8 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Data.Odbc; -using System.Linq; -using System.Linq.Expressions; using System.Text; namespace FreeSql.Odbc.SqlServer @@ -44,12 +41,18 @@ namespace FreeSql.Odbc.SqlServer }); public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcSqlServer(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("[") && nametrim.EndsWith("]")) + return nametrim; + return $"[{nametrim.Replace(".", "].[")}]"; + } + return $"[{string.Join("].[", name)}]"; } public override string TrimQuoteSqlName(string name) { @@ -58,6 +61,7 @@ namespace FreeSql.Odbc.SqlServer return nametrim; //原生SQL return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '[', ']', 3); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 85a273e7..40942739 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -95,15 +95,15 @@ namespace FreeSql.Oracle var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -112,6 +112,7 @@ namespace FreeSql.Oracle primaryKeyName = null; } } + //codefirst 不支持表名中带 . if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index f3a7621e..d28c66c5 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -4,8 +4,6 @@ using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Generic; using System.Data.Common; -using System.Linq.Expressions; -using System.Text; namespace FreeSql.Oracle { @@ -63,12 +61,18 @@ namespace FreeSql.Oracle }); public override string FormatSql(string sql, params object[] args) => sql?.FormatOracle(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; } public override string TrimQuoteSqlName(string name) { @@ -77,6 +81,7 @@ namespace FreeSql.Oracle return nametrim; //原生SQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index ebc6d40f..15c92508 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -1,13 +1,10 @@ -using FreeSql.DataAnnotations; -using FreeSql.DatabaseModel; -using FreeSql.Internal; +using FreeSql.Internal; using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; using Npgsql.LegacyPostgis; using NpgsqlTypes; using System; using System.Collections; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Linq; @@ -128,14 +125,14 @@ namespace FreeSql.PostgreSQL var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -143,6 +140,7 @@ namespace FreeSql.PostgreSQL tboldname = null; } } + //codefirst 不支持表名、模式名、数据库名中带 . if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 729e3b18..08d541e3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -1,19 +1,17 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; using Npgsql; using Npgsql.LegacyPostgis; using NpgsqlTypes; using System; using System.Collections; -using System.Collections.Generic; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Net; using System.Text; -using System.Linq.Expressions; -using System.Reflection; -using FreeSql.Internal.Model; namespace FreeSql.PostgreSQL { @@ -120,12 +118,18 @@ namespace FreeSql.PostgreSQL }); public override string FormatSql(string sql, params object[] args) => sql?.FormatPostgreSQL(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; } public override string TrimQuoteSqlName(string name) { @@ -134,6 +138,7 @@ namespace FreeSql.PostgreSQL return nametrim; //原生SQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 127acd83..86927f95 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -1,14 +1,10 @@ -using FreeSql.DataAnnotations; -using FreeSql.DatabaseModel; -using FreeSql.Internal; +using FreeSql.Internal; using FreeSql.Internal.Model; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; -using System.Text.RegularExpressions; namespace FreeSql.SqlServer { @@ -138,16 +134,16 @@ ELSE var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 3); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] }; if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] }; if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] }; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 3); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { database, "dbo", tbtmpname[0] }; if (tbtmpname?.Length == 2) tbtmpname = new[] { database, tbtmpname[0], tbtmpname[1] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1] || tbname[2] != tbtmpname[2]) @@ -156,6 +152,7 @@ ELSE tboldname = null; } } + //codefirst 不支持表名、模式名、数据库名中带 . if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index ef5e5b8b..748ebf00 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -5,8 +5,6 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.SqlClient; -using System.Linq; -using System.Linq.Expressions; using System.Text; namespace FreeSql.SqlServer @@ -55,12 +53,18 @@ namespace FreeSql.SqlServer }); public override string FormatSql(string sql, params object[] args) => sql?.FormatSqlServer(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("[") && nametrim.EndsWith("]")) + return nametrim; + return $"[{nametrim.Replace(".", "].[")}]"; + } + return $"[{string.Join("].[", name)}]"; } public override string TrimQuoteSqlName(string name) { @@ -69,6 +73,7 @@ namespace FreeSql.SqlServer return nametrim; //原生SQL return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '[', ']', 3); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index fa1a718d..4806504c 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -1,9 +1,5 @@ -using FreeSql.DataAnnotations; -using FreeSql.DatabaseModel; -using FreeSql.Internal; -using FreeSql.Internal.Model; +using FreeSql.Internal; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Linq; @@ -83,14 +79,14 @@ namespace FreeSql.Sqlite var tb = _commonUtils.GetTableByEntity(obj.entityType); if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = tb.DbName.Split(new[] { '.' }, 2); + var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] }; - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 if (tboldname?.Length == 1) tboldname = new[] { "main", tboldname[0] }; if (string.IsNullOrEmpty(obj.tableName) == false) { - var tbtmpname = obj.tableName.Split(new[] { '.' }, 2); + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); if (tbtmpname?.Length == 1) tbtmpname = new[] { "main", tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { @@ -113,7 +109,7 @@ namespace FreeSql.Sqlite if (tboldname == null) { //创建表 - var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var createTableName = _commonUtils.QuoteSqlName(tbname[0], tbname[1]); sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { @@ -151,7 +147,7 @@ namespace FreeSql.Sqlite } //如果新表,旧表在一个模式下,直接修改表名 if (string.Compare(tbname[0], tboldname[0], true) == 0) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tboldname[0], tboldname[1])).Append(" RENAME TO \"").Append(tbname[1]).Append("\";\r\n"); else { //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 @@ -234,9 +230,9 @@ namespace FreeSql.Sqlite } //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); - var tablenameOnlyTb = tboldname == null ? _commonUtils.QuoteSqlName(tbname[1]) : _commonUtils.QuoteSqlName(tboldname[1]); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}._FreeSqlTmp_{tbname[1]}"); + var tablename = tboldname == null ? _commonUtils.QuoteSqlName(tbname[0], tbname[1]) : _commonUtils.QuoteSqlName(tboldname[0], tboldname[1]); + var tablenameOnlyTb = tboldname == null ? tbname[1] : tboldname[1]; + var tmptablename = _commonUtils.QuoteSqlName(tbname[0], $"_FreeSqlTmp_{tbname[1]}"); //创建临时表 isIndent = false; sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); @@ -283,13 +279,13 @@ namespace FreeSql.Sqlite } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO \"").Append(tbname[1]).Append("\";\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablenameOnlyTb).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON \"").Append(tablenameOnlyTb).Append("\"("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 12b81771..ef9b986d 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -4,8 +4,6 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Linq.Expressions; -using System.Text; namespace FreeSql.Sqlite { @@ -66,12 +64,18 @@ namespace FreeSql.Sqlite }); public override string FormatSql(string sql, params object[] args) => sql?.FormatSqlite(args); - public override string QuoteSqlName(string name) + public override string QuoteSqlName(params string[] name) { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\""; + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; } public override string TrimQuoteSqlName(string name) { @@ -80,6 +84,7 @@ namespace FreeSql.Sqlite return nametrim; //原生SQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; From 973ca748d51397b5d1515e5c447a8dea2f39bf86 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 11 Jan 2020 02:30:36 +0800 Subject: [PATCH 0407/1029] v1.1.0-preview4 #182 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index fbae725e..9e2a9dfb 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index ac56c127..77af11e0 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index bc03eef8..42fdf94f 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6cf592b5..1ec75893 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 12b2b207..a3184393 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.1.0-preview3 + 1.0.1-preview4 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2155259a..fa256b25 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 67fcc25b..6085152f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index adcfc21e..4905ae1a 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 5a92b5d9..d54d3a4a 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 50389eb2..af0f1ed0 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 29854788..2363901b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 733a8901..a3fc3ea7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 0dd4dfb7..00ea9383 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b850adb8..61be0272 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index f3e0b751..5763c94d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4d2d0a3f..fb26a112 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview3 + 1.1.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 8d5fb26bd254e407706f935f6b5d0ea1b5953bab Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 11 Jan 2020 03:15:25 +0800 Subject: [PATCH 0408/1029] update --- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index a3184393..e5ad3b63 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.0.1-preview4 + 1.1.0-preview4 FreeSql DbFirst 实体生成器 From e8d177eb845440559176c3821a587b3e9a391a13 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 11 Jan 2020 21:25:21 +0800 Subject: [PATCH 0409/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.All?= =?UTF-8?q?=20=E5=85=A8=E5=AE=B6=E6=A1=B6=E5=8C=85=EF=BC=8C=E6=87=92?= =?UTF-8?q?=E4=BA=BA=E4=B8=93=E7=94=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.All/FreeSql.All.csproj | 35 ++++++++++++++++++++++++++++++++++ FreeSql.sln | 14 ++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 FreeSql.All/FreeSql.All.csproj diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj new file mode 100644 index 00000000..7b6bffd9 --- /dev/null +++ b/FreeSql.All/FreeSql.All.csproj @@ -0,0 +1,35 @@ + + + + netstandard2.0;net45;net40 + 1.1.0-preview4 + true + YeXiangQin + FreeSql 全家桶,懒人专用 + https://github.com/2881099/FreeSql.DbContext + FreeSql ORM DbContext + git + MIT + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + + + + + + + + + + + + + + + + + + diff --git a/FreeSql.sln b/FreeSql.sln index b4e15e7c..37d728c5 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -74,6 +74,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MsAccess", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.EfCoreFluentApi", "Extensions\FreeSql.Extensions.EfCoreFluentApi\FreeSql.Extensions.EfCoreFluentApi.csproj", "{773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.All", "FreeSql.All\FreeSql.All.csproj", "{933115AD-769C-4FBE-B000-2E8CF2292377}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -444,6 +446,18 @@ Global {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x64.Build.0 = Release|Any CPU {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x86.ActiveCfg = Release|Any CPU {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x86.Build.0 = Release|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|Any CPU.Build.0 = Debug|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|x64.ActiveCfg = Debug|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|x64.Build.0 = Debug|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|x86.ActiveCfg = Debug|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|x86.Build.0 = Debug|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|Any CPU.ActiveCfg = Release|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|Any CPU.Build.0 = Release|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|x64.ActiveCfg = Release|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|x64.Build.0 = Release|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|x86.ActiveCfg = Release|Any CPU + {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 14e0f35e2fa9c63387836edcaf92fc0277913d86 Mon Sep 17 00:00:00 2001 From: tky Date: Fri, 17 Jan 2020 15:19:19 +0800 Subject: [PATCH 0410/1029] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20.ToList(a=20=3D>?= =?UTF-8?q?=20new=20DTO(a.id))=20=E6=8A=A5=20=E6=9C=AA=E5=B0=86=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E5=BC=95=E7=94=A8=E8=AE=BE=E7=BD=AE=E5=88=B0=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E7=9A=84=E5=AE=9E=E4=BE=8B=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonExpression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index aa7b25ad..4a3ff851 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -206,7 +206,7 @@ namespace FreeSql.Internal var child = new ReadAnonymousTypeInfo { Property = null, - CsName = newExp.Members[a].Name, + CsName = (newExp.Arguments[a] as MemberExpression)?.Member.Name, CsType = newExp.Arguments[a].Type, MapType = newExp.Arguments[a].Type }; From 9e63f1187bb706147fd92fe56cd740ae4882196a Mon Sep 17 00:00:00 2001 From: tky Date: Fri, 17 Jan 2020 15:37:37 +0800 Subject: [PATCH 0411/1029] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20.ToList(a=20=3D>?= =?UTF-8?q?=20new=20DTO(a.id)=20{=20xxx=20=3D=20a.ext=20})=20=E6=8A=A5=20?= =?UTF-8?q?=E6=9C=AA=E5=B0=86=E5=AF=B9=E8=B1=A1=E5=BC=95=E7=94=A8=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=88=B0=E5=AF=B9=E8=B1=A1=E7=9A=84=E5=AE=9E=E4=BE=8B?= =?UTF-8?q?=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonExpression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 4a3ff851..9cbfdf81 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -124,7 +124,7 @@ namespace FreeSql.Internal var child = new ReadAnonymousTypeInfo { Property = null, - CsName = initExp.NewExpression.Members[a].Name, + CsName = (initExp.NewExpression.Arguments[a] as MemberExpression)?.Member.Name, CsType = initExp.NewExpression.Arguments[a].Type, MapType = initExp.NewExpression.Arguments[a].Type }; From c64deb3d20d4ff649c9531729daca286e09179d4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Jan 2020 23:53:06 +0800 Subject: [PATCH 0412/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20GroupBy=20?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2=E9=94=99=E8=AF=AF=EF=BC=9B?= =?UTF-8?q?#186=20-=20=E4=BF=AE=E5=A4=8D=20.ToList(a=20=3D>=20new=20DTO(a.?= =?UTF-8?q?id))=20=E6=8A=A5=20=E6=9C=AA=E5=B0=86=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E8=AE=BE=E7=BD=AE=E5=88=B0=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E7=9A=84=E5=AE=9E=E4=BE=8B=20=E9=97=AE=E9=A2=98=EF=BC=9B=20#18?= =?UTF-8?q?7=20-=20=E4=BF=AE=E5=A4=8D=20update=E8=AF=AD=E5=8F=A5=EF=BC=8C?= =?UTF-8?q?=E4=BA=8C=E5=85=83=E8=BF=90=E7=AE=97=E8=A7=A3=E6=9E=90=E5=87=BA?= =?UTF-8?q?=E9=94=99=EF=BC=9B=20#184?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 28 +++++++++++++++++++ .../MySqlConnector/Curd/MySqlUpdateTest.cs | 4 +++ .../Dameng/Curd/DamengSelectTest.cs | 28 +++++++++++++++++++ .../Dameng/Curd/DamengUpdateTest.cs | 4 +++ .../Default/Curd/OdbcSelectTest.cs | 28 +++++++++++++++++++ .../Default/Curd/OdbcUpdateTest.cs | 4 +++ .../MySql/Curd/MySqlSelectTest.cs | 28 +++++++++++++++++++ .../MySql/Curd/MySqlUpdateTest.cs | 4 +++ .../Oracle/Curd/OracleSelectTest.cs | 28 +++++++++++++++++++ .../Oracle/Curd/OracleUpdateTest.cs | 4 +++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 27 ++++++++++++++++++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 4 +++ .../SqlServer/Curd/SqlServerSelectTest.cs | 28 +++++++++++++++++++ .../SqlServer/Curd/SqlServerUpdateTest.cs | 4 +++ .../MsAccess/Curd/MsAccessSelectTest.cs | 28 +++++++++++++++++++ .../MsAccess/Curd/MsAccessUpdateTest.cs | 4 +++ .../MySql/Curd/MySqlSelectTest.cs | 28 +++++++++++++++++++ .../MySql/Curd/MySqlUpdateTest.cs | 4 +++ .../Oracle/Curd/OracleSelectTest.cs | 28 +++++++++++++++++++ .../Oracle/Curd/OracleUpdateTest.cs | 4 +++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 27 ++++++++++++++++++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 4 +++ .../SqlServer/Curd/SqlServerSelectTest.cs | 28 +++++++++++++++++++ .../SqlServer/Curd/SqlServerUpdateTest.cs | 4 +++ .../Sqlite/Curd/SqliteSelectTest.cs | 28 +++++++++++++++++++ .../Sqlite/Curd/SqliteUpdateTest.cs | 4 +++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 2 +- .../Interface/Curd/ISelect/ISelectGrouping.cs | 4 +-- FreeSql/Internal/CommonExpression.cs | 4 +-- .../SelectProvider/SelectGroupingProvider.cs | 2 ++ .../Internal/CommonProvider/UpdateProvider.cs | 4 ++- .../SqliteCodeFirst.cs | 4 +-- readme.md | 3 +- 33 files changed, 428 insertions(+), 9 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 607fcc57..fc638846 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -155,6 +155,19 @@ namespace FreeSql.Tests.MySqlConnector public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -171,6 +184,18 @@ namespace FreeSql.Tests.MySqlConnector var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + var t0 = select.Limit(50).ToList(); var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); @@ -735,6 +760,9 @@ namespace FreeSql.Tests.MySqlConnector var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 992bc4cf..1a6ad37b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -127,6 +127,10 @@ namespace FreeSql.Tests.MySqlConnector sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 div 1 WHERE (`Id` = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = case when `CreateTime` > '2000-01-01 00:00:00.000' then 1 else 2 end WHERE (`Id` = 1)", sql); sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index c318cb2c..79cd586c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -146,6 +146,19 @@ namespace FreeSql.Tests.Odbc.Dameng public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -160,6 +173,18 @@ namespace FreeSql.Tests.Odbc.Dameng var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + g.dameng.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.dameng.Select().ToList(); var testGuidId6 = g.dameng.Select().ToList(a => a.id); @@ -662,6 +687,9 @@ namespace FreeSql.Tests.Odbc.Dameng var testpid1 = g.dameng.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.dameng.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs index ce50236a..51a139c0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs @@ -86,6 +86,10 @@ namespace FreeSql.Tests.Odbc.Dameng sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10 / 1) WHERE (\"ID\" = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > to_timestamp('2000-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') then 1 else 2 end WHERE (\"ID\" = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 3eb5ced3..8db28289 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -137,6 +137,19 @@ namespace FreeSql.Tests.Odbc.Default public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -151,6 +164,18 @@ namespace FreeSql.Tests.Odbc.Default var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + g.odbc.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.odbc.Select().ToList(); var testGuidId6 = g.odbc.Select().ToList(a => a.id); @@ -653,6 +678,9 @@ namespace FreeSql.Tests.Odbc.Default var testpid1 = g.odbc.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.odbc.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs index 6ebcd701..3b2fe87d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs @@ -88,6 +88,10 @@ namespace FreeSql.Tests.Odbc.Default sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = case when [CreateTime] > '2000-01-01 00:00:00' then 1 else 2 end WHERE ([Id] = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 4be159dc..79e3e6ad 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -155,6 +155,19 @@ namespace FreeSql.Tests.Odbc.MySql public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -171,6 +184,18 @@ namespace FreeSql.Tests.Odbc.MySql var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + var t0 = select.Limit(50).ToList(); @@ -746,6 +771,9 @@ namespace FreeSql.Tests.Odbc.MySql var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs index c6cf8693..d0497e2d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -128,6 +128,10 @@ namespace FreeSql.Tests.Odbc.MySql sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 div 1 WHERE (`Id` = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = case when `CreateTime` > '2000-01-01 00:00:00.000' then 1 else 2 end WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 40a4862c..ec0fb836 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -146,6 +146,19 @@ namespace FreeSql.Tests.Odbc.Oracle public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -160,6 +173,18 @@ namespace FreeSql.Tests.Odbc.Oracle var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + g.oracle.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.oracle.Select().ToList(); var testGuidId6 = g.oracle.Select().ToList(a => a.id); @@ -662,6 +687,9 @@ namespace FreeSql.Tests.Odbc.Oracle var testpid1 = g.oracle.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.oracle.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs index ef16ca98..aef3d5bc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -86,6 +86,10 @@ namespace FreeSql.Tests.Odbc.Oracle sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10 / 1) WHERE (\"ID\" = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > to_timestamp('2000-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') then 1 else 2 end WHERE (\"ID\" = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index e04ee009..545c0fa6 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -136,6 +136,19 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -150,6 +163,17 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); var t1 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); var t2 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); @@ -724,6 +748,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var testpid1 = g.pgsql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.pgsql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 7808a318..9324d935 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -87,6 +87,10 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = \"clicks\" * 10 / 1 WHERE (\"id\" = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = case when \"createtime\" > '2000-01-01 00:00:00.000000' then 1 else 2 end WHERE (\"id\" = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = 10 WHERE (\"id\" = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index dafc6f17..7b9f97af 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -137,6 +137,19 @@ namespace FreeSql.Tests.Odbc.SqlServer public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -150,6 +163,18 @@ namespace FreeSql.Tests.Odbc.SqlServer var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + g.sqlserver.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.sqlserver.Select().ToList(); var testGuidId6 = g.sqlserver.Select().ToList(a => a.id); @@ -618,6 +643,9 @@ namespace FreeSql.Tests.Odbc.SqlServer var testpid1 = g.sqlserver.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.sqlserver.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs index edf2bd99..5e2e504e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs @@ -89,6 +89,10 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = case when [CreateTime] > '2000-01-01 00:00:00.000' then 1 else 2 end WHERE ([Id] = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index d968da49..243d9eb0 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -137,6 +137,19 @@ namespace FreeSql.Tests.MsAccess public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -151,6 +164,18 @@ namespace FreeSql.Tests.MsAccess var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + g.msaccess.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.msaccess.Select().ToList(); var testGuidId6 = g.msaccess.Select().ToList(a => a.id); @@ -651,6 +676,9 @@ namespace FreeSql.Tests.MsAccess var testpid1 = g.msaccess.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.msaccess.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs index 804f570e..2e148df4 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs @@ -88,6 +88,10 @@ namespace FreeSql.Tests.MsAccess sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = iif([CreateTime] > '2000-01-01 00:00:00', 1, 2) WHERE ([Id] = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 7a71bc05..818e4196 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -155,6 +155,19 @@ namespace FreeSql.Tests.MySql public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -171,6 +184,18 @@ namespace FreeSql.Tests.MySql var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + var t0 = select.Limit(50).ToList(); @@ -777,6 +802,9 @@ namespace FreeSql.Tests.MySql var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index ebcf418c..95aae673 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -129,6 +129,10 @@ namespace FreeSql.Tests.MySql sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 div 1 WHERE (`Id` = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = case when `CreateTime` > '2000-01-01 00:00:00.000' then 1 else 2 end WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 39c678ba..942fb81f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -146,6 +146,19 @@ namespace FreeSql.Tests.Oracle public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -160,6 +173,18 @@ namespace FreeSql.Tests.Oracle var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + g.oracle.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.oracle.Select().ToList(); var testGuidId6 = g.oracle.Select().ToList(a => a.id); @@ -662,6 +687,9 @@ namespace FreeSql.Tests.Oracle var testpid1 = g.oracle.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.oracle.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 4d83817d..0df27fb9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -86,6 +86,10 @@ namespace FreeSql.Tests.Oracle sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10 / 1) WHERE (\"ID\" = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > to_timestamp('2000-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') then 1 else 2 end WHERE (\"ID\" = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 117aa2f8..75ffdfa5 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -136,6 +136,19 @@ namespace FreeSql.Tests.PostgreSQL public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -150,6 +163,17 @@ namespace FreeSql.Tests.PostgreSQL var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); var t1 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); var t2 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); @@ -741,6 +765,9 @@ namespace FreeSql.Tests.PostgreSQL var testpid1 = g.pgsql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.pgsql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 6d10bf81..d13cd12c 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -87,6 +87,10 @@ namespace FreeSql.Tests.PostgreSQL sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = \"clicks\" * 10 / 1 WHERE (\"id\" = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = case when \"createtime\" > '2000-01-01 00:00:00.000000' then 1 else 2 end WHERE (\"id\" = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = 10 WHERE (\"id\" = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index ddcfa963..8ebffb14 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -147,6 +147,19 @@ namespace FreeSql.Tests.SqlServer public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } [Fact] public void ToList() { @@ -160,6 +173,18 @@ namespace FreeSql.Tests.SqlServer var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + g.sqlserver.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.sqlserver.Select().ToList(); var testGuidId6 = g.sqlserver.Select().ToList(a => a.id); @@ -666,6 +691,9 @@ namespace FreeSql.Tests.SqlServer var testpid1 = g.sqlserver.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.sqlserver.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index ad22de5e..4528a7ee 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -98,6 +98,10 @@ namespace FreeSql.Tests.SqlServer sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = case when [CreateTime] > '2000-01-01 00:00:00.000' then 1 else 2 end WHERE ([Id] = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 657caa7d..5d138880 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -146,6 +146,19 @@ namespace FreeSql.Tests.Sqlite public TestDtoLeftJoin Obj { get; set; } } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } class TestDtoLeftJoin { [Column(IsPrimary = true)] @@ -177,6 +190,18 @@ namespace FreeSql.Tests.Sqlite var testDto33 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); var testDto44 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + g.sqlite.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.sqlite.Select().ToList(); var testGuidId6 = g.sqlite.Select().ToList(a => a.id); @@ -615,6 +640,9 @@ namespace FreeSql.Tests.Sqlite var testpid1 = g.sqlite.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.sqlite.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + var aggsql1 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index b752651c..d77cac96 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -91,6 +91,10 @@ namespace FreeSql.Tests.Sqlite sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = \"Clicks\" * 10 / 1 WHERE (\"Id\" = 1)", sql); + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = case when \"CreateTime\" > '2000-01-01 00:00:00' then 1 else 2 end WHERE (\"Id\" = 1)", sql); + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"Id\" = 10 WHERE (\"Id\" = 1)", sql); } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 750f4948..c952897c 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -698,7 +698,7 @@ namespace FreeSql.Tests .ToSql(a => new NewsArticleDto { ArticleTitle = a.Key, - ChannelId = a.Sum(a.Value.Item1.OptionsEntity04) + ChannelId = (int)a.Sum(a.Value.Item1.OptionsEntity04) }); var testgrpsql2 = g.sqlite.Select() diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 46c5a92c..bcd93fe9 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -127,14 +127,14 @@ namespace FreeSql /// /// /// - T3 Sum(T3 column); + decimal Sum(T3 column); /// /// 平均值 /// /// /// /// - T3 Avg(T3 column); + decimal Avg(T3 column); /// /// 最大值 /// diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 9cbfdf81..7abfdcab 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -124,7 +124,7 @@ namespace FreeSql.Internal var child = new ReadAnonymousTypeInfo { Property = null, - CsName = (initExp.NewExpression.Arguments[a] as MemberExpression)?.Member.Name, + CsName = initExp.NewExpression.Members != null ? initExp.NewExpression.Members[a].Name : (initExp.NewExpression.Arguments[a] as MemberExpression)?.Member.Name, CsType = initExp.NewExpression.Arguments[a].Type, MapType = initExp.NewExpression.Arguments[a].Type }; @@ -206,7 +206,7 @@ namespace FreeSql.Internal var child = new ReadAnonymousTypeInfo { Property = null, - CsName = (newExp.Arguments[a] as MemberExpression)?.Member.Name, + CsName = newExp.Members != null ? newExp.Members[a].Name : (newExp.Arguments[a] as MemberExpression)?.Member.Name, CsType = newExp.Arguments[a].Type, MapType = newExp.Arguments[a].Type }; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 3bd15b46..3e589e0a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -114,6 +114,7 @@ namespace FreeSql.Internal.CommonProvider var index = 0; _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); + if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; @@ -181,6 +182,7 @@ namespace FreeSql.Internal.CommonProvider var index = 0; _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); + if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index ceb83026..141abdd9 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -363,7 +363,9 @@ namespace FreeSql.Internal.CommonProvider switch (nodeType) { case ExpressionType.Equal: - _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp, null, null)); + var equalBinaryExp = body as BinaryExpression; + _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, equalBinaryExp.Left, null, null)) + .Append(" = ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, equalBinaryExp.Right, null, null)); return this; case ExpressionType.MemberInit: var initExp = body as MemberInitExpression; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 4806504c..91a72326 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -160,7 +160,7 @@ namespace FreeSql.Sqlite //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 var tbtmp = tboldname ?? tbname; var dsql = _orm.Ado.ExecuteScalar(CommandType.Text, $" select sql from {tbtmp[0]}.sqlite_master where type='table' and name='{tbtmp[1]}'")?.ToString(); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.table_info({_commonUtils.QuoteSqlName(tbtmp[1])})"); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.table_info(\"{tbtmp[1]}\")"); var tbstruct = ds.ToDictionary(a => string.Concat(a[1]), a => { var is_identity = false; @@ -202,7 +202,7 @@ namespace FreeSql.Sqlite istmpatler = true; } var dsuk = new List(); - var dbIndexes = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.INDEX_LIST({_commonUtils.QuoteSqlName(tbtmp[1])})"); + var dbIndexes = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.INDEX_LIST(\"{tbtmp[1]}\")"); foreach (var dbIndex in dbIndexes) { if (string.Concat(dbIndex[3]) == "pk") continue; diff --git a/readme.md b/readme.md index 89a25fba..23027015 100644 --- a/readme.md +++ b/readme.md @@ -279,6 +279,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper 深圳|凉茶、 [densen2014](https://github.com/densen2014)、 [LiaoLiaoWuJu](https://github.com/LiaoLiaoWuJu)、 -[hd2y](https://github.com/hd2y) +[hd2y](https://github.com/hd2y)、 +[tky753](https://github.com/tky753) (QQ群:4336577) \ No newline at end of file From c89e4f9b20c681ba46c5c057c2909d6a6612d24a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 20 Jan 2020 01:48:41 +0800 Subject: [PATCH 0413/1029] debug #183 --- FreeSql/FreeSql.xml | 432 +++++++++--------- .../FreeSql.Provider.Sqlite/AdonetPortable.cs | 61 --- .../FreeSql.Provider.Sqlite.csproj | 7 +- .../SqliteAdo/SqliteAdo.cs | 9 +- .../SqliteAdo/SqliteConnectionPool.cs | 5 +- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 1 + .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 5 +- 7 files changed, 237 insertions(+), 283 deletions(-) delete mode 100644 Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 59e0a2ec..df8d2443 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2546,159 +2546,7 @@ 耗时(单位:Ticks) - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构 - - - - - 转大写同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - - - - - - 将实体类型集合与数据库对比,返回DDL语句 - - 实体类型 - - - - - 将实体类型与数据库对比,返回DDL语句(指定表名) - - 实体类型 - 指定表名对比 - - - - - 同步实体类型到数据库 - - - - - - - 同步实体类型集合到数据库 - - - - - - - 同步实体类型到数据库(指定表名) - - 实体类型 - 指定表名对比 - - - - - 根据 System.Type 获取数据库信息 - - - - - - - 在外部配置实体的特性 - - - - - - - - 在外部配置实体的特性 - - - - - - - - 获取在外部配置实体的特性 - - - 未使用ConfigEntity配置时,返回null - - - - 获取实体类核心配置 - - - - - - - 获取所有数据库 - - - - - - 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 - + @@ -2887,98 +2735,107 @@ C#:从元组集合中查找 exp1, exp2, exp2 是否存在 SQL: exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 + exp1 = that[1].Item1 and exp2 = that[1].Item2 aummary> + 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - + - + - 测量两个经纬度的距离,返回单位:米 + 序列化 - 经纬坐标1 - 经纬坐标2 - 返回距离(单位:米) + + - + - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 - + 名字 + 表达式 - + - 多表查询 + 中间表,多对多 - - + - 多表查询 + 不进行任何处理 - - + - 多表查询 + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple - - + - 多表查询 + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE - - + - 多表查询 + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple - - + - 多表查询 + 将字符串转换为大写 + + BigApple -> BIGAPPLE - - + - 多表查询 + 将字符串转换为小写 + + BigApple -> bigapple - - + - 多表查询 - - - - - - 多表查询 - - - - - - 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 - 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 将帕斯系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) @@ -3152,6 +3009,157 @@ CodeFirst 模式开发相关方法 + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + DbFirst 模式开发相关方法 diff --git a/Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs b/Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs deleted file mode 100644 index 6d8dcbf4..00000000 --- a/Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data.Common; -using System.Reflection; -using System.Text; - -namespace FreeSql.Sqlite -{ - internal class AdonetPortable - { - -#if ns20 - static bool _IsMicrosoft_Data_Sqlite; - static object _IsMicrosoft_Data_SqliteLock = new object(); - - static T PortableAction(Func systemCreate, Func microsoftCreate) - { - if (_IsMicrosoft_Data_Sqlite == false) - { - try - { - return systemCreate(); - } - catch - { - lock (_IsMicrosoft_Data_SqliteLock) - { - _IsMicrosoft_Data_Sqlite = true; - } - } - } - return microsoftCreate(); - } - - public static DbConnection GetSqliteConnection(string connectionString) => PortableAction( - () => new System.Data.SQLite.SQLiteConnection(connectionString), - () => new Microsoft.Data.Sqlite.SqliteConnection(connectionString)); - - public static DbCommand GetSqliteCommand() => PortableAction( - () => new System.Data.SQLite.SQLiteCommand(), - () => new Microsoft.Data.Sqlite.SqliteCommand()); - - public static DbParameter GetSqliteParameter() => PortableAction( - () => new System.Data.SQLite.SQLiteParameter(), - () => new Microsoft.Data.Sqlite.SqliteParameter()); - - public static bool IsSqliteException(Exception exception) => PortableAction( - () => exception is System.Data.SQLite.SQLiteException, - () => exception is Microsoft.Data.Sqlite.SqliteException); -#else - - public static DbConnection GetSqliteConnection(string connectionString) => new System.Data.SQLite.SQLiteConnection(connectionString); - - public static DbCommand GetSqliteCommand() => new System.Data.SQLite.SQLiteCommand(); - - public static DbParameter GetSqliteParameter() => new System.Data.SQLite.SQLiteParameter(); - - public static bool IsSqliteException(Exception exception) => exception is System.Data.SQLite.SQLiteException; -#endif - } -} diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fb26a112..48bf9f84 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -21,13 +21,10 @@ - - + + - - - diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 4e473739..5745a3e8 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -4,6 +4,7 @@ using SafeObjectPool; using System; using System.Collections; using System.Data.Common; +using System.Data.SQLite; using System.Text; using System.Threading; @@ -18,6 +19,10 @@ namespace FreeSql.Sqlite if (connectionFactory != null) { MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Sqlite, connectionFactory); + using (var conn = MasterPool.Get()) + { + _CreateCommandConnection = conn.Value; + } return; } if (!string.IsNullOrEmpty(masterConnectionString)) @@ -57,9 +62,11 @@ namespace FreeSql.Sqlite return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } + DbConnection _CreateCommandConnection; protected override DbCommand CreateCommand() { - return AdonetPortable.GetSqliteCommand(); + if (_CreateCommandConnection != null) return _CreateCommandConnection.CreateCommand(); + return new SQLiteCommand(); } protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 526dbabd..5257b7e0 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Data.SQLite; using System.Linq; using System.Text; using System.Text.RegularExpressions; @@ -34,7 +35,7 @@ namespace FreeSql.Sqlite public void Return(Object obj, Exception exception, bool isRecreate = false) { - if (exception != null && AdonetPortable.IsSqliteException(exception)) + if (exception != null && exception is SQLiteException) { try { if (obj.Value.Ping() == false) obj.Value.OpenAndAttach(policy.Attaches); } catch { base.SetUnavailable(exception); } } @@ -121,7 +122,7 @@ namespace FreeSql.Sqlite public DbConnection OnCreate() { - var conn = AdonetPortable.GetSqliteConnection(_connectionString); + var conn = new SQLiteConnection(_connectionString); return conn; } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 138056e9..972137b6 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -38,6 +38,7 @@ namespace FreeSql.Sqlite this.Aop = new AopProvider(); this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + if (connectionFactory != null) this.CodeFirst.IsNoneCommandParameter = true; } internal CommonUtils InternalCommonUtils { get; } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index ef9b986d..41ba2433 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Data.SQLite; namespace FreeSql.Sqlite { @@ -31,7 +32,7 @@ namespace FreeSql.Sqlite dbtype = DbType.Int64; break; } - var ret = AdonetPortable.GetSqliteParameter(); + var ret = new SQLiteParameter(); ret.ParameterName = QuoteParamterName(parameterName); ret.DbType = dbtype; ret.Value = value; @@ -56,7 +57,7 @@ namespace FreeSql.Sqlite dbtype = DbType.Int64; break; } - var ret = AdonetPortable.GetSqliteParameter(); + var ret = new SQLiteParameter(); ret.ParameterName = $"@{name}"; ret.DbType = dbtype; ret.Value = value; From 668b5e580dcbbf2d83ed310c46de5af99fe14145 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 20 Jan 2020 02:08:51 +0800 Subject: [PATCH 0414/1029] debug #183 --- .../FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 5745a3e8..5e44f876 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -19,10 +19,8 @@ namespace FreeSql.Sqlite if (connectionFactory != null) { MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Sqlite, connectionFactory); - using (var conn = MasterPool.Get()) - { - _CreateCommandConnection = conn.Value; - } + _CreateCommandConnection = MasterPool.Get().Value; + _CreateCommandConnection.Close(); return; } if (!string.IsNullOrEmpty(masterConnectionString)) @@ -65,7 +63,12 @@ namespace FreeSql.Sqlite DbConnection _CreateCommandConnection; protected override DbCommand CreateCommand() { - if (_CreateCommandConnection != null) return _CreateCommandConnection.CreateCommand(); + if (_CreateCommandConnection != null) + { + var cmd = _CreateCommandConnection.CreateCommand(); + cmd.Connection = null; + return cmd; + } return new SQLiteCommand(); } From 406fd1d7cbbaa80005d32251a728766c48bd980e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 20 Jan 2020 02:14:22 +0800 Subject: [PATCH 0415/1029] 1.1.0-preview5 #183 #184 #186 #187 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 432 +++++++++--------- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 229 insertions(+), 237 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 9e2a9dfb..7ae6ab01 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 77af11e0..66c4f9ea 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 42fdf94f..ffb0139c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 1ec75893..76816a84 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index e5ad3b63..fffe5394 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.1.0-preview4 + 1.1.0-preview5 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 7b6bffd9..3767f86c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index fa256b25..af30b255 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 6085152f..f0053407 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4905ae1a..22f605c7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index df8d2443..59e0a2ec 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2546,7 +2546,159 @@ 耗时(单位:Ticks) - + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构 + + + + + 转大写同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + 将实体类型与数据库对比,返回DDL语句 + + + + + + + 将实体类型集合与数据库对比,返回DDL语句 + + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 + + + + + 同步实体类型到数据库 + + + + + + + 同步实体类型集合到数据库 + + + + + + + 同步实体类型到数据库(指定表名) + + 实体类型 + 指定表名对比 + + + + + 根据 System.Type 获取数据库信息 + + + + + + + 在外部配置实体的特性 + + + + + + + + 在外部配置实体的特性 + + + + + + + + 获取在外部配置实体的特性 + + + 未使用ConfigEntity配置时,返回null + + + + 获取实体类核心配置 + + + + + + + 获取所有数据库 + + + + + + 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 + @@ -2735,107 +2887,98 @@ C#:从元组集合中查找 exp1, exp2, exp2 是否存在 SQL: exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 aummary> - 获取ado.net读取方法, GetBoolean、GetInt64 + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 - + + + + + + + - + - 序列化 + 测量两个经纬度的距离,返回单位:米 - - + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) - + - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 - 名字 - 表达式 + - + - 中间表,多对多 + 多表查询 + - + - 不进行任何处理 + 多表查询 + - + - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple + 多表查询 + - + - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE + 多表查询 + - + - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple + 多表查询 + - + - 将字符串转换为大写 - - BigApple -> BIGAPPLE + 多表查询 + - + - 将字符串转换为小写 - - BigApple -> bigapple + 多表查询 + - + - 将帕斯系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 多表查询 + + + + + + 多表查询 + + + + + + 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 + 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) @@ -3009,157 +3152,6 @@ CodeFirst 模式开发相关方法 - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - DbFirst 模式开发相关方法 diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index d54d3a4a..c27fdee7 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index af0f1ed0..14f8f8f7 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 2363901b..c15002a1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a3fc3ea7..3e701a27 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 00ea9383..ab6faa18 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 61be0272..16f577ed 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5763c94d..1317f9cb 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 48bf9f84..fea8408a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview4 + 1.1.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 15d5a592210aed81adc6087658a3fbea64b86f8d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 20 Jan 2020 13:43:24 +0800 Subject: [PATCH 0416/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSqlBuild?= =?UTF-8?q?er=20=E5=8F=8B=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Generator.csproj | 2 +- FreeSql/FreeSqlBuilder.cs | 27 ++++++++++--------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index fffe5394..bbc18399 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -18,7 +18,7 @@ - + diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index dc8f1a20..060ba8f1 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -174,62 +174,63 @@ namespace FreeSql if (type?.IsGenericType == true) type = type.MakeGenericType(typeof(TMark)); if (type == null) { + Action throwNotFind = (dll, providerType) => throw new Exception($"缺少 FreeSql 数据库实现包:{dll},可前往 nuget 下载;如果存在 {dll} 依然报错(原因是环境问题导致反射不到类型),请在 UseConnectionString/UseConnectionFactory 第三个参数手工传入 typeof({providerType})"); switch (_dataType) { case DataType.MySql: type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.MySql.dll", "FreeSql.MySql.MySqlProvider<>"); break; case DataType.SqlServer: type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.SqlServer.dll", "FreeSql.SqlServer.SqlServerProvider<>"); break; case DataType.PostgreSQL: type = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.PostgreSQL.dll", "FreeSql.PostgreSQL.PostgreSQLProvider<>"); break; case DataType.Oracle: type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.Oracle.dll", "FreeSql.Oracle.OracleProvider<>"); break; case DataType.Sqlite: type = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.Sqlite.dll", "FreeSql.Sqlite.SqliteProvider<>"); break; case DataType.OdbcOracle: type = Type.GetType("FreeSql.Odbc.Oracle.OdbcOracleProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.Odbc.dll", "FreeSql.Odbc.Oracle.OdbcOracleProvider<>"); break; case DataType.OdbcSqlServer: type = Type.GetType("FreeSql.Odbc.SqlServer.OdbcSqlServerProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.Odbc.dll", "FreeSql.Odbc.SqlServer.OdbcSqlServerProvider<>"); break; case DataType.OdbcMySql: type = Type.GetType("FreeSql.Odbc.MySql.OdbcMySqlProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.Odbc.dll", "FreeSql.Odbc.MySql.OdbcMySqlProvider<>"); break; case DataType.OdbcPostgreSQL: type = Type.GetType("FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.Odbc.dll", "FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLProvider<>"); break; case DataType.Odbc: type = Type.GetType("FreeSql.Odbc.Default.OdbcProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.Odbc.dll", "FreeSql.Odbc.Default.OdbcProvider<>"); break; case DataType.OdbcDameng: type = Type.GetType("FreeSql.Odbc.Dameng.OdbcDamengProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Odbc.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.Odbc.dll", "FreeSql.Odbc.Dameng.OdbcDamengProvider<>"); break; case DataType.MsAccess: type = Type.GetType("FreeSql.MsAccess.MsAccessProvider`1,FreeSql.Provider.MsAccess")?.MakeGenericType(typeof(TMark)); - if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MsAccess.dll,可前往 nuget 下载"); + if (type == null) throwNotFind("FreeSql.Provider.MsAccess.dll", "FreeSql.MsAccess.MsAccessProvider<>"); break; - default: throw new Exception("未指定 UseConnectionString"); + default: throw new Exception("未指定 UseConnectionString 或者 UseConnectionFactory"); } } ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString, _connectionFactory }) as IFreeSql; From fc4071b73060f240584e9af1ba219324a53d1918 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Jan 2020 11:36:01 +0800 Subject: [PATCH 0417/1029] =?UTF-8?q?-=20=E6=94=AF=E6=8C=81=20Sqlite=20:me?= =?UTF-8?q?mory:=20=E6=A8=A1=E5=BC=8F=EF=BC=9B=20#191?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SqlServer/Curd/SqlServerInsertTest.cs | 11 +++++++- FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- .../AdoProvider/DbConnectionPool.cs | 27 +++++++++++++++++++ .../SqliteAdo/SqliteAdo.cs | 7 ++--- .../SqliteAdo/SqliteConnectionPool.cs | 6 +++++ 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index c25d5c68..356f5fcf 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -25,7 +25,7 @@ namespace FreeSql.Tests.SqlServer { [Column(IsIdentity = true, IsPrimary = true)] public int Id { get; set; } - public int? Clicks { get; set; } + public int Clicks { get; set; } public int TypeGuid { get; set; } public TestTypeInfo Type { get; set; } public string Title { get; set; } @@ -164,6 +164,15 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(items.First().Title, itemsInserted.First().Title); Assert.Equal(items.Last().Title, itemsInserted.Last().Title); } + [Fact] + public void ExecuteSqlBulkCopy() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + insert.AppendData(items).InsertIdentity().ExecuteSqlBulkCopy(); + // System.NotSupportedException:“DataSet does not support System.Nullable<>.” + } [Fact] public void AsTable() diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 1f5f3c64..985eae8b 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -71,7 +71,7 @@ public class g public static IFreeSql oracle => oracleLazy.Value; static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=2") + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;") //.UseConnectionFactory(FreeSql.DataType.Sqlite, () => //{ // var conn = new System.Data.SQLite.SQLiteConnection(@"Data Source=|DataDirectory|\document.db;Pooling=true;"); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs index a336446b..d3be116e 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs @@ -13,9 +13,35 @@ namespace FreeSql.Internal.CommonProvider { internal DataType _dataType; internal Func _connectionFactory; + public DbConnection TestConnection { get; } + public bool IsSingletonConnection { get; } int _id; public DbConnectionPool(DataType dataType, Func connectionFactory) { + #region Test connectionFactory + //情况1:() => new SqlConnection(...) + //情况2:() => conn + DbConnection conn1 = null; + DbConnection conn2 = null; + try + { + conn1 = connectionFactory(); //测试 conn + conn2 = connectionFactory(); + + TestConnection = conn1; //赋值创建 Command,兼容 Mono.Data.Sqlite + IsSingletonConnection = conn1 == conn2; + } + catch { } + finally + { + if (conn1 != conn2) + { + if (conn1?.State == ConnectionState.Open) try { conn1?.Close(); } catch { } + if (conn2?.State == ConnectionState.Open) try { conn2?.Close(); } catch { } + } + } + #endregion + _dataType = dataType; _connectionFactory = connectionFactory; Policy = new DbConnectionPoolPolicy(this); @@ -55,6 +81,7 @@ namespace FreeSql.Internal.CommonProvider public void Return(Object obj, bool isReset = false) { if (obj == null || obj.Value == null) return; + if (IsSingletonConnection) return; if (obj.Value.State != ConnectionState.Closed) obj.Value.Close(); if (_dataType == DataType.Sqlite) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 5e44f876..09ba12df 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections; +using System.Data; using System.Data.Common; using System.Data.SQLite; using System.Text; @@ -18,9 +19,9 @@ namespace FreeSql.Sqlite base._util = util; if (connectionFactory != null) { - MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Sqlite, connectionFactory); - _CreateCommandConnection = MasterPool.Get().Value; - _CreateCommandConnection.Close(); + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Sqlite, connectionFactory); + MasterPool = pool; + _CreateCommandConnection = pool.TestConnection; return; } if (!string.IsNullOrEmpty(masterConnectionString)) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 5257b7e0..fb3ac566 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -106,6 +106,12 @@ namespace FreeSql.Sqlite _connectionString = string.Concat(att[0], idx == -1 ? "" : att[1].Substring(idx)); } + if (_connectionString.ToLower().Contains(":memory:")) + { + //内存模式 + PoolSize = 1; + } + #if ns20 minPoolSize = 1; #endif From 6a7b7bed874d454e2b21797639ebd2ff37be4379 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Jan 2020 11:53:43 +0800 Subject: [PATCH 0418/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IdleTimeout?= =?UTF-8?q?=20=E9=BB=98=E8=AE=A4=E5=80=BC=E4=B8=BA=2020=20=E7=A7=92?= =?UTF-8?q?=EF=BC=9B=20#194?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs | 2 +- .../Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs | 2 +- .../FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs | 2 +- .../GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs | 2 +- .../MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs | 2 +- .../Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs | 2 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs | 2 +- .../SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs | 2 +- .../FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs | 2 +- .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 2 +- .../SqlServerAdo/SqlServerConnectionPool.cs | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 9e0da560..d1a7311f 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -48,7 +48,7 @@ namespace FreeSql.MySql public string Name { get; set; } = "MySql MySqlConnection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index f7dd707d..d1db9ed3 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -70,7 +70,7 @@ namespace FreeSql.Odbc.Dameng public string Name { get; set; } = "Dameng OdbcConnection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs index c8eb1bcb..99e4023e 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.Default public string Name { get; set; } = "Default OdbcConnection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs index 06db5358..448f3978 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs @@ -62,7 +62,7 @@ namespace FreeSql.Odbc.GBase public string Name { get; set; } = "GBase OdbcConnection 对象池"; public int PoolSize { get; set; } = 50; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs index 1caf9501..a68020e9 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -48,7 +48,7 @@ namespace FreeSql.Odbc.MySql public string Name { get; set; } = "MySql OdbcConnection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index fecf7793..ab255dbd 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -70,7 +70,7 @@ namespace FreeSql.Odbc.Oracle public string Name { get; set; } = "Oracle OdbcConnection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index c387559d..574ae33b 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -60,7 +60,7 @@ namespace FreeSql.Odbc.PostgreSQL public string Name { get; set; } = "PostgreSQL OdbcConnection 对象池"; public int PoolSize { get; set; } = 50; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs index ef9843bd..ebef1228 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.SqlServer public string Name { get; set; } = "SqlServer OdbcConnection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index eb8c0e0e..2c2178b5 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -70,7 +70,7 @@ namespace FreeSql.Oracle public string Name { get; set; } = "Oracle Connection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index 4297e35e..ba1ce9a5 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -60,7 +60,7 @@ namespace FreeSql.PostgreSQL public string Name { get; set; } = "PostgreSQL NpgsqlConnection 对象池"; public int PoolSize { get; set; } = 50; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 42663a0a..2e8272fb 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -53,7 +53,7 @@ namespace FreeSql.SqlServer public string Name { get; set; } = "SqlServer SqlConnection 对象池"; public int PoolSize { get; set; } = 100; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; From 023956d70418d3b9f66603007f588225591aa652 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Jan 2020 12:53:34 +0800 Subject: [PATCH 0419/1029] 1.1.0-preview6 #191 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 6 +++--- .../FreeSql.Provider.MySqlConnector.csproj | 4 ++-- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7ae6ab01..a69357f3 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 66c4f9ea..48230bfd 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ffb0139c..20eb0723 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 76816a84..68c23b02 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index bbc18399..8755c784 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.1.0-preview5 + 1.1.0-preview6 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3767f86c..840c2e2f 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index af30b255..fbc97d50 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index f0053407..dddcffa0 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 22f605c7..65647aa6 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index c27fdee7..42121022 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 14f8f8f7..7bf8372f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,10 +2,10 @@ netstandard2.0;net452;net451;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin - FreeSql 数据库实现,基于 MySql 5.6 + FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git @@ -23,7 +23,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index c15002a1..666a48de 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,10 +2,10 @@ netstandard2.0;net45 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin - FreeSql 数据库实现,基于 MySql 5.6 + FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3e701a27..e90bb786 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ab6faa18..456dc46f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 16f577ed..7eb59e6d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 1317f9cb..4d438a7e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fea8408a..52ec5274 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview5 + 1.1.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 4b2887f6075b267fcd3ed8457552280e92aaf04d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Jan 2020 15:53:11 +0800 Subject: [PATCH 0420/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E7=88=B6?= =?UTF-8?q?=E5=AD=90=E5=85=B3=E7=B3=BB=E5=AF=BC=E8=88=AA=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=20Dto=20=E4=B8=AD=E7=9B=B4=E6=8E=A5=E4=BD=BF=E7=94=A8=20a.Pare?= =?UTF-8?q?nt=20=E6=98=A0=E5=B0=84=E9=94=99=E8=AF=AF=E7=9A=84=20bug?= =?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 | 7 ----- FreeSql/Internal/CommonExpression.cs | 3 ++- readme.md | 34 ++++++------------------- 3 files changed, 10 insertions(+), 34 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 7abfdcab..d5896cd6 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1109,7 +1109,8 @@ namespace FreeSql.Internal var finds = new SelectTableInfo[0]; if (tsc.style == ExpressionStyle.SelectColumns) { - finds = tsc._tables.Where(a => a.Table.Type == tbtmp.Type).ToArray(); + finds = tsc._tables.Where(a => a.Table.Type == tbtmp.Type && a.Alias == alias).ToArray(); + if (finds.Length != 1) finds = tsc._tables.Where(a => a.Table.Type == tbtmp.Type).ToArray(); if (finds.Any()) finds = new[] { finds.First() }; } if (finds.Length != 1 && isa && parmExp != null) diff --git a/readme.md b/readme.md index 23027015..43603321 100644 --- a/readme.md +++ b/readme.md @@ -215,30 +215,6 @@ using (var ctx = new fsql.CreateDbContext()) { } ``` -# DataFilter & Tenant - -```csharp -public void ConfigureServices(IServiceCollection services) { - services.AddSingleton(Fsql); - services.AddFreeRepository(filter => filter - .Apply("SoftDelete", a => a.IsDeleted == false) - .Apply("Tenant", a => a.TenantId == 1) - , - this.GetType().Assembly - ); -} -``` - -Temporary disable: -```csharp -var repoq = fsql.GetRepository(); - -using (repo1.DataFilter.Disable("Tenant")) { - //Tenant Invalid -} -//Tenant restore -``` - # Performance FreeSql Query & Dapper Query @@ -265,7 +241,7 @@ Elapsed: 00:00:00.6707125; ToList Entity Counts: 131072; ORM: FreeSql* Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ``` -[Test code](FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs) +[Test code](FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs)、[More](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd) # Contributors @@ -282,4 +258,10 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [hd2y](https://github.com/hd2y)、 [tky753](https://github.com/tky753) -(QQ群:4336577) \ No newline at end of file +(QQ群:4336577) + +# Donation + +L*y 58元、花花 88 元、麦兜很乖 50元、网络来者 2000元 + + From 38737752e1339effeb0c1aab4886ba8b07349168 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Jan 2020 16:00:37 +0800 Subject: [PATCH 0421/1029] update Donation --- readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 43603321..43422969 100644 --- a/readme.md +++ b/readme.md @@ -264,4 +264,6 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper L*y 58元、花花 88 元、麦兜很乖 50元、网络来者 2000元 - +| | | +| - | - | +| | | \ No newline at end of file From 12caace111d7be98f3cf5e398d929a6eb13af580 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Jan 2020 16:08:09 +0800 Subject: [PATCH 0422/1029] update Donation --- readme.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 43422969..be01dff4 100644 --- a/readme.md +++ b/readme.md @@ -262,8 +262,11 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper # Donation -L*y 58元、花花 88 元、麦兜很乖 50元、网络来者 2000元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元 + +> Thank you for your donation | | | | - | - | -| | | \ No newline at end of file +| | | + From cb2e229792a549ceb3efcb3f4d5306852498da84 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Jan 2020 16:10:00 +0800 Subject: [PATCH 0423/1029] update Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index be01dff4..b39c20fb 100644 --- a/readme.md +++ b/readme.md @@ -262,7 +262,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper # Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元 > Thank you for your donation From 752e0fc30e7a4568973231b386d51c5716b4a6a2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Jan 2020 16:33:08 +0800 Subject: [PATCH 0424/1029] update Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index b39c20fb..567d27b8 100644 --- a/readme.md +++ b/readme.md @@ -262,7 +262,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper # Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元 > Thank you for your donation From aaf05c5e9b8933b3d9cdc6bac797223298a6a3e9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 31 Jan 2020 12:12:28 +0800 Subject: [PATCH 0425/1029] ## v1.1.0 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 4 ++-- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a69357f3..7fd1dcf8 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.1.0-preview6 + 1.1.0 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 48230bfd..cb3b28be 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 20eb0723..2a4751d2 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 68c23b02..b1920708 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 8755c784..41411894 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.1.0-preview6 + 1.1.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 840c2e2f..e5ddca5b 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index fbc97d50..c741cee0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access @@ -34,7 +34,7 @@ - + diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index dddcffa0..4e4d5b46 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0-preview6 + 1.1.0 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 65647aa6..62996da6 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 42121022..9b6ec8dc 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 7bf8372f..5578a794 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 666a48de..de80c350 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e90bb786..36c8ad1a 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 456dc46f..df4b6698 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7eb59e6d..9e24ae01 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4d438a7e..7728c569 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 52ec5274..e4746baa 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0-preview6 + 1.1.0 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 78ba778446dff3998ea6ba942817dc64022fc1fb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 12 Feb 2020 16:28:46 +0800 Subject: [PATCH 0426/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ToList(a=20?= =?UTF-8?q?=3D>=20new=20Dto=20{})=20=E8=BF=99=E7=A7=8D=E6=83=85=E5=86=B5?= =?UTF-8?q?=E6=8C=89=E5=AD=97=E6=AE=B5=E5=90=8D=E5=8C=B9=E9=85=8Dr?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E5=BA=94=E8=AF=A5=E6=8C=89=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=90=8D=EF=BC=9B#208?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonExpression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index d5896cd6..9a9b7a86 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -140,7 +140,7 @@ namespace FreeSql.Internal { foreach (var dtTb in _tables) { - if (dtTb.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue; + if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue; if (trydtocol.Attribute.IsIgnore == true) continue; var child = new ReadAnonymousTypeInfo From cbdeece6492bcad7f2e53951760ee48ddac81980 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 12 Feb 2020 16:46:39 +0800 Subject: [PATCH 0427/1029] 1.2.0-preview1 #208 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7fd1dcf8..f89b7f1c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.1.0 + 1.2.0-preview1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index cb3b28be..9f4d810b 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 2a4751d2..956b41e4 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b1920708..5b83a4fe 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 41411894..04c4d315 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.1.0 + 1.2.0-preview1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index e5ddca5b..36a40c21 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index c741cee0..e2bf07d1 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4e4d5b46..5f0e98bb 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.1.0 + 1.2.0-preview1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 62996da6..1c601af4 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 9b6ec8dc..ada707a5 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5578a794..aba67387 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index de80c350..8e4b599d 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 36c8ad1a..fa32ede1 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index df4b6698..39c42722 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 9e24ae01..204cf11e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 7728c569..dc4476a2 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e4746baa..66d45361 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.1.0 + 1.2.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From cfbb143ec657151b7f91b5fc3b21b45ed7e42d46 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 15 Feb 2020 17:37:21 +0800 Subject: [PATCH 0428/1029] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=20GenerateCommandParameterWithLambda?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 10 +++++++--- FreeSql/FreeSqlBuilder.cs | 6 +++++- FreeSql/Interface/ICodeFirst.cs | 6 +++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index bb0e122e..1d90c559 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -59,12 +59,14 @@ namespace FreeSql.Tests ib.Register("db1", () => new FreeSql.FreeSqlBuilder() .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=3") .UseAutoSyncStructure(true) + .UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) .UseLazyLoading(true) .Build()); ib.Register("db2", () => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=3") .UseAutoSyncStructure(true) + .UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) .UseSyncStructureToUpper(true) .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) @@ -72,19 +74,21 @@ namespace FreeSql.Tests ib.Register("db3", () => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=3") .UseAutoSyncStructure(true) + .UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) .Build()); //...注入很多个 var fsql = ib.Get("db1"); //使用的时候用 Get 方法,不要存其引用关系 - fsql.Select().Limit(10).ToList(); + var sqlparamId = 100; + fsql.Select().Limit(10).Where(a => a.id == sqlparamId).ToList(); fsql = ib.Get("db2"); - fsql.Select().Limit(10).ToList(); + fsql.Select().Limit(10).Where(a => a.id == sqlparamId).ToList(); fsql = ib.Get("db3"); - fsql.Select().Limit(10).ToList(); + fsql.Select().Limit(10).Where(a => a.id == sqlparamId).ToList(); fsql = g.sqlserver; fsql.Insert(new OrderMain { OrderNo = "1001", OrderTime = new DateTime(2019, 12, 01) }).ExecuteAffrows(); diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 060ba8f1..3f62e85a 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -120,7 +120,11 @@ namespace FreeSql return this; } /// - /// 是否生成命令参数化执行,针对 lambda 表达式解析 + /// 是否生成命令参数化执行,针对 lambda 表达式解析 + /// 注意:常量不会参数化,变量才会做参数化 + /// var id = 100; + /// fsql.Select<T>().Where(a => a.id == id) 会参数化 + /// fsql.Select<T>().Where(a => a.id == 100) 不会参数化 /// /// /// diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 2d1cec92..482a4358 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -31,7 +31,11 @@ namespace FreeSql /// bool IsNoneCommandParameter { get; set; } /// - /// 是否生成命令参数化执行,针对 lambda 表达式解析 + /// 是否生成命令参数化执行,针对 lambda 表达式解析 + /// 注意:常量不会参数化,变量才会做参数化 + /// var id = 100; + /// fsql.Select<T>().Where(a => a.id == id) 会参数化 + /// fsql.Select<T>().Where(a => a.id == 100) 不会参数化 /// bool IsGenerateCommandParameterWithLambda { get; set; } /// From f8e18f0548a7c98f7d503a664b73e52faab33816 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 18 Feb 2020 12:21:27 +0800 Subject: [PATCH 0429/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20nuget=20?= =?UTF-8?q?=E5=8C=85=E5=BC=BA=E7=AD=BE=E5=90=8D=E5=8F=91=E5=B8=83=20v1.2.0?= =?UTF-8?q?-preview2=EF=BC=9B#201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/dbcontext_01/Program.cs | 2 + .../FreeSql.Extensions.BaseEntity.csproj | 5 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 5 +- .../FreeSql.Extensions.JsonMap.csproj | 5 +- .../FreeSql.Extensions.LazyLoading.csproj | 5 +- .../FreeSql.Generator.csproj | 5 +- FreeSql.All/FreeSql.All.csproj | 5 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 5 +- FreeSql.Repository/FreeSql.Repository.csproj | 5 +- FreeSql/FreeSql.csproj | 7 ++- FreeSql/FreeSql.xml | 52 +++++++++++-------- FreeSql/Interface/IAdo.cs | 40 +++++++------- .../FreeSql.Provider.MsAccess.csproj | 5 +- .../FreeSql.Provider.MySql.csproj | 5 +- .../FreeSql.Provider.MySqlConnector.csproj | 5 +- .../FreeSql.Provider.Odbc.csproj | 5 +- .../FreeSql.Provider.Oracle.csproj | 5 +- .../FreeSql.Provider.PostgreSQL.csproj | 5 +- .../FreeSql.Provider.SqlServer.csproj | 5 +- .../FreeSql.Provider.Sqlite.csproj | 7 ++- 20 files changed, 122 insertions(+), 61 deletions(-) diff --git a/Examples/dbcontext_01/Program.cs b/Examples/dbcontext_01/Program.cs index ef6e0446..0aa6a2a1 100644 --- a/Examples/dbcontext_01/Program.cs +++ b/Examples/dbcontext_01/Program.cs @@ -40,6 +40,8 @@ namespace dbcontext_01 static IFreeSql fsql; public static void Main(string[] args) { + var asse = typeof(SafeObjectPool.ObjectPool<>).Assembly; + fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") .UseAutoSyncStructure(true) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f89b7f1c..a6ad8d13 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 9f4d810b..fbb56c69 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 956b41e4..f7efbbd0 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5b83a4fe..0d85dae8 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 04c4d315..5986aba2 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,8 +12,11 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.2.0-preview1 + 1.2.0-preview2 FreeSql DbFirst 实体生成器 + true + YeXiangQin.pfx + false diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 36a40c21..edee1d5c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 全家桶,懒人专用 @@ -15,6 +15,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e2bf07d1..a56745a3 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access @@ -15,6 +15,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5f0e98bb..e6a41407 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository @@ -15,6 +15,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1c601af4..1a718b3b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false @@ -28,7 +31,7 @@ - + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 59e0a2ec..21df8587 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -722,7 +722,11 @@ - 是否生成命令参数化执行,针对 lambda 表达式解析 + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 @@ -2135,7 +2139,7 @@ - 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 }) + 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) @@ -2149,7 +2153,7 @@ - 查询,ExecuteArray("select * from user where age > @age", new { age = 25 }) + 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) @@ -2164,7 +2168,7 @@ - 查询,ExecuteDataSet("select * from user where age > @age; select 2", new { age = 25 }) + 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) @@ -2179,7 +2183,7 @@ - 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 }) + 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) @@ -2195,7 +2199,7 @@ - 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 }) + 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) @@ -2211,7 +2215,7 @@ - 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 }) + 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) @@ -2219,7 +2223,7 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -2229,7 +2233,7 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new { age = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) @@ -2238,7 +2242,7 @@ - 执行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 SqlParameter { ParameterName = "age", Value = 25 }) @@ -2248,7 +2252,7 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) @@ -2266,7 +2270,7 @@ - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) @@ -2280,7 +2284,7 @@ - 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) @@ -2295,7 +2299,7 @@ - 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) @@ -2310,7 +2314,7 @@ - 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) @@ -2326,7 +2330,7 @@ - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) @@ -2342,7 +2346,7 @@ - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) @@ -2350,7 +2354,7 @@ - 执行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 SqlParameter { ParameterName = "age", Value = 25 }) @@ -2360,7 +2364,7 @@ - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) @@ -2369,7 +2373,7 @@ - 执行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 SqlParameter { ParameterName = "age", Value = 25 }) @@ -2379,7 +2383,7 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) @@ -2600,7 +2604,11 @@ - 是否生成命令参数化执行,针对 lambda 表达式解析 + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 57670ee0..7fccbfa2 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -68,7 +68,7 @@ namespace FreeSql void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 }) + /// 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// /// /// @@ -84,7 +84,7 @@ namespace FreeSql object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteArray("select * from user where age > @age", new { age = 25 }) + /// 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) /// /// /// @@ -101,7 +101,7 @@ namespace FreeSql DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataSet("select * from user where age > @age; select 2", new { age = 25 }) + /// 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) /// /// /// @@ -118,7 +118,7 @@ namespace FreeSql DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 }) + /// 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) /// /// /// @@ -136,7 +136,7 @@ namespace FreeSql int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 }) + /// 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) /// /// /// @@ -154,7 +154,7 @@ namespace FreeSql object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 }) + /// 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) /// /// /// @@ -164,7 +164,7 @@ namespace FreeSql object ExecuteScalar(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) /// /// /// @@ -175,7 +175,7 @@ namespace FreeSql List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) /// /// /// @@ -186,7 +186,7 @@ namespace FreeSql List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); /// - /// 执行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 SqlParameter { ParameterName = "age", Value = 25 }) /// /// /// @@ -197,7 +197,7 @@ namespace FreeSql (List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); (List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) /// /// /// @@ -240,7 +240,7 @@ namespace FreeSql Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) + /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// /// /// @@ -256,7 +256,7 @@ namespace FreeSql Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) + /// 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) /// /// /// @@ -273,7 +273,7 @@ namespace FreeSql Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) + /// 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) /// /// /// @@ -290,7 +290,7 @@ namespace FreeSql Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) + /// 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) /// /// /// @@ -308,7 +308,7 @@ namespace FreeSql Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) + /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) /// /// /// @@ -326,7 +326,7 @@ namespace FreeSql Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) + /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) /// /// /// @@ -336,7 +336,7 @@ namespace FreeSql Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); /// - /// 执行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 SqlParameter { ParameterName = "age", Value = 25 }) /// /// /// @@ -347,7 +347,7 @@ namespace FreeSql Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) + /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) /// /// /// @@ -358,7 +358,7 @@ namespace FreeSql Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); /// - /// 执行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 SqlParameter { ParameterName = "age", Value = 25 }) /// /// /// @@ -369,7 +369,7 @@ namespace FreeSql Task<(List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) /// /// /// diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index ada707a5..d3d82213 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 数据库 Ms Access 实现 @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index aba67387..04e5bfbc 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8e4b599d..e3ca235e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index fa32ede1..b1cf4f35 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 39c42722..876733f1 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 204cf11e..929e9ba6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index dc4476a2..84d6d06b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -16,6 +16,9 @@ $(AssemblyName) true true + true + false + YeXiangQin.pfx diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 66d45361..540e79d1 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview1 + 1.2.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin @@ -16,13 +16,16 @@ $(AssemblyName) true true + true + YeXiangQin.pfx + false - + From b9d3ad8fec6c49c18101c8fad2531d0659f6a6a3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 21 Feb 2020 12:11:18 +0800 Subject: [PATCH 0430/1029] update *.pfx --- .gitignore | 1 - .../FreeSql.Extensions.BaseEntity/YeXiangQin.pfx | Bin 0 -> 1764 bytes .../YeXiangQin.pfx | Bin 0 -> 1764 bytes .../FreeSql.Extensions.JsonMap/YeXiangQin.pfx | Bin 0 -> 1764 bytes .../YeXiangQin.pfx | Bin 0 -> 1764 bytes Extensions/FreeSql.Generator/YeXiangQin.pfx | Bin 0 -> 1764 bytes FreeSql.All/YeXiangQin.pfx | Bin 0 -> 1764 bytes FreeSql.DbContext/YeXiangQin.pfx | Bin 0 -> 1764 bytes FreeSql.Repository/YeXiangQin.pfx | Bin 0 -> 1764 bytes FreeSql/YeXiangQin.pfx | Bin 0 -> 1764 bytes .../FreeSql.Provider.MsAccess/YeXiangQin.pfx | Bin 0 -> 1764 bytes Providers/FreeSql.Provider.MySql/YeXiangQin.pfx | Bin 0 -> 1764 bytes .../YeXiangQin.pfx | Bin 0 -> 1764 bytes Providers/FreeSql.Provider.Odbc/YeXiangQin.pfx | Bin 0 -> 1764 bytes Providers/FreeSql.Provider.Oracle/YeXiangQin.pfx | Bin 0 -> 1764 bytes .../FreeSql.Provider.PostgreSQL/YeXiangQin.pfx | Bin 0 -> 1764 bytes .../FreeSql.Provider.SqlServer/YeXiangQin.pfx | Bin 0 -> 1764 bytes Providers/FreeSql.Provider.Sqlite/YeXiangQin.pfx | Bin 0 -> 1764 bytes 18 files changed, 1 deletion(-) create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Extensions.JsonMap/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Extensions.LazyLoading/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Generator/YeXiangQin.pfx create mode 100644 FreeSql.All/YeXiangQin.pfx create mode 100644 FreeSql.DbContext/YeXiangQin.pfx create mode 100644 FreeSql.Repository/YeXiangQin.pfx create mode 100644 FreeSql/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.MsAccess/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.MySql/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.MySqlConnector/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.Odbc/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.Oracle/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.PostgreSQL/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.SqlServer/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.Sqlite/YeXiangQin.pfx diff --git a/.gitignore b/.gitignore index 63842b23..de79a863 100644 --- a/.gitignore +++ b/.gitignore @@ -186,7 +186,6 @@ ClientBin/ *~ *.dbmdl *.dbproj.schemaview -*.pfx *.publishsettings node_modules/ orleans.codegen.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/YeXiangQin.pfx b/Extensions/FreeSql.Extensions.BaseEntity/YeXiangQin.pfx new file mode 100644 index 0000000000000000000000000000000000000000..33f631e7b45091ea98b5c7ac4908e8b5e7044b00 GIT binary patch literal 1764 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 Date: Sun, 23 Feb 2020 12:22:36 +0800 Subject: [PATCH 0431/1029] =?UTF-8?q?=E6=9B=B4=E6=94=B9=20pfx=20=E5=BC=BA?= =?UTF-8?q?=E7=AD=BE=E5=90=8D=E4=B8=BA=20snk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 4 ++-- .../FreeSql.Extensions.BaseEntity/YeXiangQin.pfx | Bin 1764 -> 0 bytes Extensions/FreeSql.Extensions.BaseEntity/key.snk | Bin 0 -> 596 bytes .../FreeSql.Extensions.EfCoreFluentApi.csproj | 4 ++-- .../YeXiangQin.pfx | Bin 1764 -> 0 bytes .../FreeSql.Extensions.EfCoreFluentApi/key.snk | Bin 0 -> 596 bytes .../FreeSql.Extensions.JsonMap.csproj | 4 ++-- .../FreeSql.Extensions.JsonMap/YeXiangQin.pfx | Bin 1764 -> 0 bytes Extensions/FreeSql.Extensions.JsonMap/key.snk | Bin 0 -> 596 bytes .../FreeSql.Extensions.LazyLoading.csproj | 4 ++-- .../YeXiangQin.pfx | Bin 1764 -> 0 bytes .../FreeSql.Extensions.LazyLoading/key.snk | Bin 0 -> 596 bytes .../FreeSql.Generator/FreeSql.Generator.csproj | 4 ++-- Extensions/FreeSql.Generator/YeXiangQin.pfx | Bin 1764 -> 0 bytes Extensions/FreeSql.Generator/key.snk | Bin 0 -> 596 bytes FreeSql.All/FreeSql.All.csproj | 4 ++-- FreeSql.All/YeXiangQin.pfx | Bin 1764 -> 0 bytes FreeSql.All/key.snk | Bin 0 -> 596 bytes FreeSql.DbContext/FreeSql.DbContext.csproj | 4 ++-- FreeSql.DbContext/YeXiangQin.pfx | Bin 1764 -> 0 bytes FreeSql.DbContext/key.snk | Bin 0 -> 596 bytes FreeSql.Repository/FreeSql.Repository.csproj | 4 ++-- FreeSql.Repository/YeXiangQin.pfx | Bin 1764 -> 0 bytes FreeSql.Repository/key.snk | Bin 0 -> 596 bytes FreeSql/FreeSql.csproj | 6 +++--- FreeSql/YeXiangQin.pfx | Bin 1764 -> 0 bytes FreeSql/key.snk | Bin 0 -> 596 bytes .../FreeSql.Provider.MsAccess.csproj | 4 ++-- .../FreeSql.Provider.MsAccess/YeXiangQin.pfx | Bin 1764 -> 0 bytes Providers/FreeSql.Provider.MsAccess/key.snk | Bin 0 -> 596 bytes .../FreeSql.Provider.MySql.csproj | 4 ++-- Providers/FreeSql.Provider.MySql/YeXiangQin.pfx | Bin 1764 -> 0 bytes Providers/FreeSql.Provider.MySql/key.snk | Bin 0 -> 596 bytes .../FreeSql.Provider.MySqlConnector.csproj | 6 +++--- .../YeXiangQin.pfx | Bin 1764 -> 0 bytes .../FreeSql.Provider.MySqlConnector/key.snk | Bin 0 -> 596 bytes .../FreeSql.Provider.Odbc.csproj | 4 ++-- Providers/FreeSql.Provider.Odbc/YeXiangQin.pfx | Bin 1764 -> 0 bytes Providers/FreeSql.Provider.Odbc/key.snk | Bin 0 -> 596 bytes .../FreeSql.Provider.Oracle.csproj | 4 ++-- Providers/FreeSql.Provider.Oracle/YeXiangQin.pfx | Bin 1764 -> 0 bytes Providers/FreeSql.Provider.Oracle/key.snk | Bin 0 -> 596 bytes .../FreeSql.Provider.PostgreSQL.csproj | 6 +++--- .../FreeSql.Provider.PostgreSQL/YeXiangQin.pfx | Bin 1764 -> 0 bytes Providers/FreeSql.Provider.PostgreSQL/key.snk | Bin 0 -> 596 bytes .../FreeSql.Provider.SqlServer.csproj | 4 ++-- .../FreeSql.Provider.SqlServer/YeXiangQin.pfx | Bin 1764 -> 0 bytes Providers/FreeSql.Provider.SqlServer/key.snk | Bin 0 -> 596 bytes .../FreeSql.Provider.Sqlite.csproj | 4 ++-- Providers/FreeSql.Provider.Sqlite/YeXiangQin.pfx | Bin 1764 -> 0 bytes Providers/FreeSql.Provider.Sqlite/key.snk | Bin 0 -> 596 bytes 51 files changed, 37 insertions(+), 37 deletions(-) delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/key.snk delete mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/key.snk delete mode 100644 Extensions/FreeSql.Extensions.JsonMap/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Extensions.JsonMap/key.snk delete mode 100644 Extensions/FreeSql.Extensions.LazyLoading/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Extensions.LazyLoading/key.snk delete mode 100644 Extensions/FreeSql.Generator/YeXiangQin.pfx create mode 100644 Extensions/FreeSql.Generator/key.snk delete mode 100644 FreeSql.All/YeXiangQin.pfx create mode 100644 FreeSql.All/key.snk delete mode 100644 FreeSql.DbContext/YeXiangQin.pfx create mode 100644 FreeSql.DbContext/key.snk delete mode 100644 FreeSql.Repository/YeXiangQin.pfx create mode 100644 FreeSql.Repository/key.snk delete mode 100644 FreeSql/YeXiangQin.pfx create mode 100644 FreeSql/key.snk delete mode 100644 Providers/FreeSql.Provider.MsAccess/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.MsAccess/key.snk delete mode 100644 Providers/FreeSql.Provider.MySql/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.MySql/key.snk delete mode 100644 Providers/FreeSql.Provider.MySqlConnector/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.MySqlConnector/key.snk delete mode 100644 Providers/FreeSql.Provider.Odbc/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.Odbc/key.snk delete mode 100644 Providers/FreeSql.Provider.Oracle/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.Oracle/key.snk delete mode 100644 Providers/FreeSql.Provider.PostgreSQL/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.PostgreSQL/key.snk delete mode 100644 Providers/FreeSql.Provider.SqlServer/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.SqlServer/key.snk delete mode 100644 Providers/FreeSql.Provider.Sqlite/YeXiangQin.pfx create mode 100644 Providers/FreeSql.Provider.Sqlite/key.snk diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a6ad8d13..1431789c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Extensions/FreeSql.Extensions.BaseEntity/YeXiangQin.pfx b/Extensions/FreeSql.Extensions.BaseEntity/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+txzNELIK1Zl^G25_BRDIVgo1N! zXF}xT3HRaNDcPRxB*n$%z&ZF!n@POGRXtr&4sG}r#?JM!U}HZ^2<-5N9)4M+H?5|_ zLy~*EP}KH5n#|gI&*-hTUCZ7}8S_t$=_1|{semC0aJo%L3;I zfZ%#&r#sq{*D%6|T;+wL{9&_WTeRIT#=?_I|0OH0WO z1^!5jYd^+*-epd^Xh3ptG1GFYbGqAu-z1Hw)r=w~8 zroRQf+b@8^k}2EAwQ&)}cyTuzvJ?LnX_9CV)$%@N>kWR*Q~1|AT)};m%$dx)vbz|< zfq26AUR|B9qsKouhps$fBJEm?h4Pfn6l)jA4n^9G)|4S5VPNiA2S(b netstandard2.0 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/YeXiangQin.pfx b/Extensions/FreeSql.Extensions.EfCoreFluentApi/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+txwVBs&v2*nzWIybp^a_TG#wMBR z9;`#2JIny2^KS;JL10G8RJp@bXIl86_Ep6}VeXsPu}NlBdUknchkmNk+KM18EUQoh zvMc_{lvG;WGhv`|lr1v+ZSwImfg98Vr;@T>Y)tPNgFS-uZ_$f)D8x)L54|Au?s?EN zNa~@z?gEkaTR6%IyQh5$5Vi*TL*!8@LezE|G6ar#^3+yRfa8Anv}0*u_A2;L>OBNk zIQT9I&vFm0?El=~_O)+E)qmKmLsuCZf3rB`t>5lmlZUoEeXQuaIx0Xc?Qr(x0Md~0 zfW2jtGin`LH6r@A4kaoo`!ha{M1JwZiFqe6J?Y!QUpc%U*T$2V{LVl7BMZG~mJOHS zD@D=?v~pQ;DUD1o5K^QX1!%Nzh`gOrU1v$+{U(j~#0LORdaY5}&ZCI<(D!L(=|Pa; z{M)JI|HfK(V-z$}A&Rt^w$Ma<^(zX5y_UTA0Pw{%>9hl`T_3ky<3-aO%r?<+d>k_J z^?^>17_0!=LwI7Hc!Jh@4KC netstandard2.0;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Extensions/FreeSql.Extensions.JsonMap/YeXiangQin.pfx b/Extensions/FreeSql.Extensions.JsonMap/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+tx}1=JPk=q?Zlr?i$1O?SgX-{{&z z|LRF?-aWODhAO}h_7M!wz}uPXx}n-g{((r9{{%_ z4)%gVXcj;Ru@GYAIZI@e#GBtO#O5m-Qr4X_lbAV}=qNRkd0^`@I6i9k`wSe@ZPxVo zk;MXig(S-cYHE!0GWWlp7EH@E!WkF6jS+3z4rvW0%Sq;U1bq`B9*HNJjxo*23*7Vw zHyt>{2CR~8==`lYLgAmwsXPXYZ_AEAKy|PuUz0(G)L1xO{{*n6Bn?mV~QKg!055THihpc>GOh(U-NgO?4_DzY4uq!p9=Q;`G i9;v3GkC674Mbx4_b$)?7a0%Z%&zUjzbGs@!l^s|B literal 0 HcmV?d00001 diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0d85dae8..6799a0d3 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Extensions/FreeSql.Extensions.LazyLoading/YeXiangQin.pfx b/Extensions/FreeSql.Extensions.LazyLoading/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+txWU7AHgQ^i+%lp3B$bCiw zGI}Qt9{#39rbg&Q%Pnk+$L^GcA-wUFLnBl)_nH*=qhl77F^JlebwApzIjG$-RyL$r!qijvEGeMc?U8Yix% zZ|91n#{g=DMUN?a@>qg;SC(6u5am0Mgi_Hc04l7HO7OM!qjBw0*KJ|3^ulNeOPEC0 zaNidQ%sYy!jak91(o%~K?2=-Q$B&{oZC0}Y`|OtO6OcEfsWEke{uhb~0W#5f##6m~ z|53o7q)!9$Dg=y{;9Xu9<&`pdVH`Oy im@`g=c^6yUcR=cMf@8H&$q5hyq*$(}s97as>uW`g使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.2.0-preview2 + 1.2.0-preview3 FreeSql DbFirst 实体生成器 true - YeXiangQin.pfx + key.snk false diff --git a/Extensions/FreeSql.Generator/YeXiangQin.pfx b/Extensions/FreeSql.Generator/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+txW+DT*_*#IA|q^@DkSOtO_JsEU)xDsMZXaeKEP zQ-{;y`e%VnpZ@gu?Q_G1L+Hx4Uz)qxI0?7}$+A71?MFyXxMi>{wm>Pcq-+h+Ms6Vq+=! z?YsQ`^Ed)Dt0G=aD~luUE@Mc%Mt#9yW#VR8Rd|MZJk~xiEQsS3j!@?^LpG#zbjP>b ztc9pOyJs&}W3Pk^9z36pp{X1WpgU&_U9H+&YBa4<%P`)9X|z&`S}a0v{&t2fHnOM>`4>P=XZ5Sk^Pze7%+SfW;2gM{v6v8Sk%_Ui)ss* zN75Ihrn5-Jt+mBR%_vEhi!$Q4ty;bb8_RqnVeK1F4ebtuO~yA0L4RxmL}S%&hYtx4b~1K16&s7MG;qOeCYm`pN>ppOMdSusU3GT&!C7>3cyq iT+~J!Ht>Yp+@HXllzB6JFmx8GLI6nDeRy+uAmpJh@+3e2 literal 0 HcmV?d00001 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index edee1d5c..b25deadc 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 全家桶,懒人专用 @@ -16,7 +16,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/FreeSql.All/YeXiangQin.pfx b/FreeSql.All/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+tx5B);pqIC72FQskT9a6${=V; zS|9)RwYAsJ4rsM9t$s?bx|XX)nkC2K4gEfHLIOcOhb#c#K(F*zB2AucZ22V-?;riX z@pJq=?;NuGyLbv=eY^>U0bVr(+cXrS0==gph#!1>7!Yk}ED z_AjBuy9}1;C|>Ln=8pU%diQHFU^TuSfVWsm^1!Sch5>etRT$c3XeHydJ$`MeU1VG8 zhV13|GXBXkz|x?<(->o&J|+bP?F!>t#-$swQR^xCD|zDJcF<2E(b$B_KtbVmzS3(N zti8X%dwSvYN7QMpi-Re%!k(+V4H5g{yvgq2Q9SsgVg@mjqdwzw=^Bni^a;zv1fB8j zM$t)bRM99VP@8!sKJeT`FCM}`7@SUh_cX3~POw|bSSnbSD(e%?I*!c$owiQ!1fM>S z6}~z$)+&Sj^#HEudXKGX<8ZP1vLnv0yXUrKgR^)%fJ}1Raw=cnGo=EVo*mU26j|%t z_9;Puk%`tp+12B$QLNgZaPlZ(`627AN(0fTKq>D0g_Ot=i6} netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access @@ -16,7 +16,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/FreeSql.DbContext/YeXiangQin.pfx b/FreeSql.DbContext/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+txWaj$X?4i{qp)*g3rM^|#z)bMhWyEHzM*<$ZTN{J}SXzvl@N0c~u13E7!*StHJrSmPT&J z&iN;mxfdGtu-&~+S{P24`_V9kyN<5Z9V!0AN`gxA8vFC-IM8tVMMonhtI01>3!|g2 zB_K7m8UXWe!D`Zuad*+x;n~vKV77tC2wz8(jkBCr)A&+>2+zc-Uq+*d)cM?B-(Zv> zx%SL%+aO-i6UD}Z1O)SkW9vma_IQr-N>^L`m#Q1!s%O!ww13#w{>8?Bie{Tgm;1C8 zv12*~GL@4Rf&v3ZhU$hZDFUy4W5Ch_X$=L(tw$l_t(pVGJK)u`HKtT{vOMAw*K>pT z4P8^FkGCOi$qos0e!P}rJC;sx6D*!0b+69hLyacys6-0i7c`7nnza~DC zzH{y7@&>56nNQ}V}&m|6#LocTHvj9HATw$jHWo<`$btT%s?AEi-zvg)_E5dz{q zH(=H-MIJd}g%w{C^=Fw%n}bvs4IhsP9rNsYk;PR$UP_NJM$=e2acyd`{5l#n4t$i| i netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository @@ -16,7 +16,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/FreeSql.Repository/YeXiangQin.pfx b/FreeSql.Repository/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+tx-;TsjRj4Le#mj z#@K#c8r~~x9H3>@I9zy1P);2uENK&#r-m{cnFFz&A|S;k1&ki zQjNcH)XzrXp003By?77ucN)LH z2CgMtE@VUNkgtG;8C?gCTXZ1QQ#pC=P?vAo%86`GgLtDu|IpuGj11!I4_tU-uoxTF zyLlBg%aN#y;riAOX~$2-WXx|<%v#b`)2h|jGY5%r8C*EJ0AbG2oqNe@#5|0o@rIW- zxE8Lw)$GuLYT*eqq2ub03CMh|Ns;3N>+X{KhQ%mqdk^Y8{IFfTM(uZHeXbkMp#8;( zIH3zrcCLtEH-hD!CxL9-^KE>({fl?erN`R(J6z>hoQr$)czeOOKRdC%^0-xf%LcTQ z`nfZelk@({xfy4%brx_DW?w^^XjZLTFwg~B7lWDW@!k6Q>%hkmu+3)|y-kPEB>G4= zQksS1h1HkeTjTKUPGm;dj@Ei~{tZ|Rd**{bNT?F>Qf#xumw)-uc?WAE{{LXl7qGg? z2ZItSoV-lIb% netstandard2.0;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false @@ -31,7 +31,7 @@ - + diff --git a/FreeSql/YeXiangQin.pfx b/FreeSql/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+tx#y(r-pR)K?5&i__?`P1P zWT4Vt8|54bOhux8vf(uPf$&Kk#ZxvS5&Up{c>~-r;wb)iH|i!68y)$6+A&c_oE(OzJt8&n7LzoUX7`_=T- z&dAnHb1spv9sPXkqrLr-sWO^1&-})f|Fgg)(-cX74gQ<}O_L7I$Bsqga0MN(Q-S%_ zDB~-~irE^U_Awu8nX3OiP@E&oCn?`PWF;T{nAWNj^-UkQ__`8{*CMp=q{vL3l%C+G zvCwU85}u{Q!U3C#jC#v`XKc8OVuD!Ivh^R|12>UwKO#MvUK(*Nm<<1$=CHJ%2Y?`C zJLsRYM|8Y-gjov0fc14re4n1Rq;Ab7Wn}G`{H(7}uMcK2#p@SLbS9^TzoI*c`DW#eorqs!KZ(N~DNtV-SEt ipvnItz-H_u5u$M netstandard2.0;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 数据库 Ms Access 实现 @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Providers/FreeSql.Provider.MsAccess/YeXiangQin.pfx b/Providers/FreeSql.Provider.MsAccess/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+tx3ha%dxWiEm*=8^&RARE9b({mUc=dJ4}$ z{Y>KqEV0XT)JpE}h#ZlQ5jH^kzTfD9Uvv|qz*08EDGEP(4XdpCp{?zmk(_&$;4PI? zPPabpviZc@1^r8i0GZ>bgezSYl+eQYtfKUYh~t%9l!R(kKtyL4USC|wZR7aSuCH&> zHGFFo&OB&WU-FVws*S*cP-7E;*OiZqmJPMdvP#npX0$eIg++&}OZSCN6<8>1j;_6bBsVM*{ao|p2Et}H=7z=|3~G-`rI isnJ(UlkcDm;?u!ll88yO*Eh6RDv(k9*|oNbu4qj>k0>Aj literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 04e5bfbc..b5a69ee5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Providers/FreeSql.Provider.MySql/YeXiangQin.pfx b/Providers/FreeSql.Provider.MySql/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+tx zXRa&N$R%$We)Bh^n-y1%^RrxSr2|R>x4b#7XhRE|2Z>?}<-^l%xw#RC?xkzW8V0Zx zgt2{y|LjeTh{4}4Qwmj$#lwVdjlipD-1($Zr1|dD`wHGrX2=?^RlS(e-x5Bb(K73y z#I9J^%|#5cEco5&dD|8EN-r?@FHP=45}?Zv1Zc8V55EkD)gs*!c|ntt&1zl%hbe;Y zlPF9*q9b|E^aNEX0Z|yR#CjXo&&4@>mLlJuc95;yA!JBpLN!kjqpo}|yT(tA@aEz+ zJyi>KQ$KNltr?CWRA<&5{2Ic`AV;ZJ(ud-gSS5UoQ(h8aZk+vBs4%@lP<4n0G5R^w_d9cG%~ z({>#4-O9XuAGb~VYL@;6Hw@#MLzz?X9`awlgW5{_hvKA}Z6KwKB&bm5r}COiGm(%T zOkfLfZ?`-OGxy3NR<$o9zDX7oQmOn(nwcMCNccm!Xze09D&E?TROk1?OZ@^bd`gJy i8(9;r){w?;g!M2Hq2gMgJtdf3ag_7{BPMm netstandard2.0;net45 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/YeXiangQin.pfx b/Providers/FreeSql.Provider.MySqlConnector/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 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 literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index b1cf4f35..ef53633b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Providers/FreeSql.Provider.Odbc/YeXiangQin.pfx b/Providers/FreeSql.Provider.Odbc/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+txOC%~+JZu+c~r1FPMn^M z%WA{i9bNConJTj@g0UCU4st*8bc<&F`3^irHOgdTZY9UjUpF?4ZQim!7SJr_z$1_N z?FA7YnMFtCno8>J(`{Wprq3;uRIDXJF%W74uOd1LyEUE+YuaC@7dhkjx|faHW0irmO%!`S*`KSN&pHVvu^ netstandard2.0;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Providers/FreeSql.Provider.Oracle/YeXiangQin.pfx b/Providers/FreeSql.Provider.Oracle/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+txLbvqwM=NOyf{!4Y`x&G`@<%EQq?fzn>oTUBt&b z`rAA%xyG`lB@EGR$oRO{_2OU6ryJDlkzsCeieYx?J$^vXkoF9$5RGr;`2QdhOdMPV zjvfa}kwHUjsd(0tdrGv>+e+7~!rb)Is}*Mv(6+*MYPJyCL&@Cyjyy#YOKy-kfbp7gyvi(Y_Z{jD0NJFlwQnSNfM@ z>Q1Q>s*rV&e=H@l@eoCA%iU$vODP1JQA<*7ii`oc z!JJW!T`*8l)=WA)y8mW>IKdfbbd(Cq+XBzIEt}ICH8mIPY~m>VbN_jy$1B5}EDv}r zy`cXG^_BzXdjqIOO~G?)sgm7Vs0{J*EPMEU7Xw#W5I?8@qXa~4c}&P-F5ozj)(GPb ib^f`^BK#E4G=3(%>tV*?N~BqifC|L@^gXrl%SdESL@H4L literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 929e9ba6..5161be40 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false @@ -30,7 +30,7 @@ - + diff --git a/Providers/FreeSql.Provider.PostgreSQL/YeXiangQin.pfx b/Providers/FreeSql.Provider.PostgreSQL/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 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 literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 84d6d06b..e94acaa6 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -18,7 +18,7 @@ true true false - YeXiangQin.pfx + key.snk diff --git a/Providers/FreeSql.Provider.SqlServer/YeXiangQin.pfx b/Providers/FreeSql.Provider.SqlServer/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 zcmZXTc{tSj7stP|7~7C7H(ROn{KhhT2aR2}aFZqChtkDF#xi3WOAX2xDiazKL!oP{ ziRfBW#@0lZZf;2t;}K&k+3sjc+^?SB@80M4{GRii^EvO=Ip_0y{`ee_hMI)K5Fib8 z3ni|V?wGzI1rvpp(omU58tN*9(?A-c>3>RyDkKe22H_IOi%^pPnL9(5^4L{N!JG44R!JG`JF(f%IWC7-q#J<~`t-y;l{D517pj=L%#^SOMAKu>9 zxJ{N4CF4soyIYkP+eT~0)4ID0Sj&_kzcB1+yRUaMcfDBG6mjPXrBpN zm<-E#UA!=DQ+);v)wQQl@;BwWmPV?@MA|=_V$Op_`$uCJ=IaTu3`&|NLy6u38c<}x z8a6lylv6Y16iuASbv=6P$1ohMZ{5A-f}CMX-Q6-`jMCX(F^$`v={7XZLp;p6S{`9V zf7|;culA6+C-uRCt<mR@BKr){drdxf_-{Y4$ZR)*GhQ1nM*{PSaML>%T zZolQkd6mq>-a>4ymWC}J;fbzTJ2U3?;+FK7MShY(v5vN|;+e_Ssf)(V>3Z$S9?HvZ zbAi8{BG+EASKVkkWLX)}-`Sxqk!w-j|3^i&;4EJvKA-W*TE);}E!gh)=A3^s`y}`- z)g-(4j-|}e>?k{L^KQJ-1pR|_T9}5es(i)o2uJO@DEK`eh2>G9)09IN=Z$UOfcxBP z9|zT))IS&myAhy^$%B{Oy&24sz{=ZxkH*I3A25_{*Ucr89!6eWvW@t6elatMd?3So z_4)!XWeAl2`r+I;B+>1a=!&M?`;UV3tx0HU<{!@St%LbNoAu#d2Yb~*-z54sJee~^>zzQf z*L_aUaP;Ry6kYXv{_7sw zknN|Vu2ysp@N~$!_r}V{Pt||Y+&>w?^3=C(yc=XO8m1S^8oBXrNWU1kur@EqB;y=4 z@2E}WEn3O(w}Y!CCCy&={p4g9Z>B(XbyBFLmfbAV>RmlLvQ;cnPuA$bbSB*hsn@jp zCO9@WgchfMi_y0bF(Fj;z7DvQTX#hFU;O;83hZU8Aw@rY`N@W+QuHF35yd>;9QBbM z;S+COGrs8hkyW4rQ)j1b;5!<-yUy=|-BL02S5xZoH1^fOrgmykWf;g3X1)56tZ_xo zE4HV}pKHwWmpQDMAdilL%MYqNVmo5XL**51UT6F)8(!w%(=(iBnmpW6{^(1rl!3Sx z!DTH<<>w_0vcBr%K`V!r3j`-u9f2VN)tgfBp6fFFjdP=7I!e26z>!ly`NpfLtx{jP z(9U^yCG?R({xtLXU6FCJ<@=%KzO~Tf&R5g|a$dTnr)Hd4$7++BB+*+Ir%!ebm3XG5 zHpfM>pEiCVY8-VX&Cd;gC=!mGt95YKJX>hQ?X=!-E4B-)T_T@);K)iTag9b6nc-&? zr1zijSe8(_)5Z&*-8ivN@~xN-e=={R&9bj?rqt&J&8m3dnBe+txNYPdib`XmdyeJjJO*(GoFpk5-m#C%tU*YYSF1oc&! z&kYPxg~7*FLbDPbDh_`p$8<618)8lKWI0u5zLBBpb$KxZ|G~Ba-dRfWj-t)oqimF zE#!P$OAB(Bn~yo=G+~%~I}KFe>a{8jz$a1cC4cL584Ye>4-#0>&dO!-T~X z0cTsO43DlXjY1(msb!@lpjn)LdvDjwWCK&t&5XkwKp(rNyKE7jz`zkZ@0Msf_Xt+a zH^XQRZTV`+T1Vso`=ZI*?Md)@UH*a{vJH7MzE*XWETB8BFercl2{#E1HbiYB%rh5- z_l={31SY>MhHU}tv~HK0A#^PxFhFf^Y@m2_7e&zfusJWkFJCA3dPOYPnyX8prc}5l i2+nOq*_D6u$te$&OM6CpcH00W3pFikHt^8lZZ?lbG6jJE literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 540e79d1..44632342 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview2 + 1.2.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin @@ -17,7 +17,7 @@ true true true - YeXiangQin.pfx + key.snk false diff --git a/Providers/FreeSql.Provider.Sqlite/YeXiangQin.pfx b/Providers/FreeSql.Provider.Sqlite/YeXiangQin.pfx deleted file mode 100644 index 33f631e7b45091ea98b5c7ac4908e8b5e7044b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1764 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 literal 0 HcmV?d00001 From 02cd7ad5576386ce142cb49e829e0e4871d0a027 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 24 Feb 2020 18:03:37 +0800 Subject: [PATCH 0432/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20IUpdate.SetS?= =?UTF-8?q?ource=20=E7=BB=84=E5=90=88=E4=B8=BB=E9=94=AE=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9B=B4=E6=96=B0=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= =?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 | 7 - .../MySqlConnector/Curd/MySqlUpdateTest.cs | 13 + .../Dameng/Curd/DamengUpdateTest.cs | 23 ++ .../Default/Curd/OdbcUpdateTest.cs | 13 + .../MySql/Curd/MySqlUpdateTest.cs | 13 + .../Oracle/Curd/OracleUpdateTest.cs | 13 + .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 13 + .../SqlServer/Curd/SqlServerUpdateTest.cs | 13 + .../MsAccess/Curd/MsAccessUpdateTest.cs | 23 ++ .../MySql/Curd/MySqlUpdateTest.cs | 13 + .../Oracle/Curd/OracleUpdateTest.cs | 13 + .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 14 + .../SqlServer/Curd/SqlServerUpdateTest.cs | 14 + .../Sqlite/Curd/SqliteUpdateTest.cs | 13 + FreeSql/FreeSql.xml | 330 +++++++++--------- .../Curd/MsAccessUpdate.cs | 4 +- .../Curd/MySqlUpdate.cs | 4 +- .../Dameng/Curd/OdbcDamengUpdate.cs | 4 +- .../Default/Curd/OdbcUpdate.cs | 4 +- .../GBase/Curd/OdbcGBaseUpdate.cs | 4 +- .../MySql/Curd/OdbcMySqlUpdate.cs | 4 +- .../Oracle/Curd/OdbcOracleUpdate.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 4 +- .../Curd/OracleUpdate.cs | 4 +- .../Curd/PostgreSQLUpdate.cs | 4 +- .../Curd/SqlServerUpdate.cs | 4 +- .../Curd/SqliteUpdate.cs | 8 +- 28 files changed, 375 insertions(+), 209 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 1a6ad37b..8c22ca85 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -78,6 +78,19 @@ namespace FreeSql.Tests.MySqlConnector Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs index 51a139c0..1c5c437d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs @@ -48,6 +48,29 @@ namespace FreeSql.Tests.Odbc.Dameng sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + if (g.dameng.Select().Where(a => a.id1 == 1 && a.id2 == 7).Any() == false) + g.dameng.Insert(new ts_source_mpk { id1 = 1, id2 = 7 }).ExecuteAffrows(); + if (g.dameng.Select().Where(a => a.id1 == 1 && a.id2 == 8).Any() == false) + g.dameng.Insert(new ts_source_mpk { id1 = 1, id2 = 8 }).ExecuteAffrows(); + + sql = g.dameng.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + g.dameng.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ExecuteAffrows(); + var testlist = g.dameng.Select().ToList(); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs index 3b2fe87d..7adec224 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.Odbc.Default sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = '2020-01-01 00:00:00' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.odbc.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs index d0497e2d..a187cf59 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -78,6 +78,19 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs index aef3d5bc..5882a1e5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -48,6 +48,19 @@ namespace FreeSql.Tests.Odbc.Oracle sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.oracle.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 9324d935..ecc43d80 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -49,6 +49,19 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"createtime\" = '2020-01-01 00:00:00.000000' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.pgsql.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs index 5e2e504e..99b73c02 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs @@ -51,6 +51,19 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = '2020-01-01 00:00:00.000' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.sqlserver.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs index 2e148df4..76c44fbc 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs @@ -50,6 +50,29 @@ namespace FreeSql.Tests.MsAccess sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = '2020-01-01 00:00:00' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + if (g.msaccess.Select().Where(a => a.id1 == 1 && a.id2 == 7).Any() == false) + g.msaccess.Insert(new ts_source_mpk { id1 = 1, id2 = 7 }).ExecuteAffrows(); + if (g.msaccess.Select().Where(a => a.id1 == 1 && a.id2 == 8).Any() == false) + g.msaccess.Insert(new ts_source_mpk { id1 = 1, id2 = 8 }).ExecuteAffrows(); + + sql = g.msaccess.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + g.msaccess.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ExecuteAffrows(); + var testlist = g.msaccess.Select().ToList(); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 95aae673..4f8cbe00 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -79,6 +79,19 @@ namespace FreeSql.Tests.MySql Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 0df27fb9..b3413337 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -48,6 +48,19 @@ namespace FreeSql.Tests.Oracle sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = :p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.oracle.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index d13cd12c..1eabd7f3 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -49,7 +49,21 @@ namespace FreeSql.Tests.PostgreSQL sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"createtime\" = @p_0 WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.pgsql.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] public void IgnoreColumns() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 4528a7ee..9dd1dea6 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -60,7 +60,21 @@ namespace FreeSql.Tests.SqlServer sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = @p_0 WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.sqlserver.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] public void IgnoreColumns() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index d77cac96..fe4532a7 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.Sqlite sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"CreateTime\" = @p_0 WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.sqlite.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } } [Fact] public void IgnoreColumns() diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 21df8587..66b08dae 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2426,180 +2426,7 @@ - - Insert/Update自动值处理 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构 - - - - - 转大写同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update + @@ -2874,6 +2701,161 @@ + + + C#:从元组集合中查找 exp1, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 中间表,多对多 + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + + + + C#:从元组集合中查找 exp1, exp2 是否存在 diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs index f54c9077..6a70a096 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs @@ -43,7 +43,7 @@ namespace FreeSql.MsAccess.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); + if (pkidx > 0) caseWhen.Append(" + '+' + "); caseWhen.Append(MsAccessUtils.GetCastSql(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)), typeof(string))); ++pkidx; } @@ -60,7 +60,7 @@ namespace FreeSql.MsAccess.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); + if (pkidx > 0) sb.Append(" + '+' + "); sb.Append(MsAccessUtils.GetCastSql(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)), typeof(string))); ++pkidx; } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index f2e29d2d..b208affd 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -79,7 +79,7 @@ namespace FreeSql.MySql.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); + if (pkidx > 0) caseWhen.Append(", '+', "); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } @@ -97,7 +97,7 @@ namespace FreeSql.MySql.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); + if (pkidx > 0) sb.Append(", '+', "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs index 2b274bf4..22aa2504 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -39,7 +39,7 @@ namespace FreeSql.Odbc.Dameng var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(" || "); + if (pkidx > 0) caseWhen.Append(" || '+' || "); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } @@ -57,7 +57,7 @@ namespace FreeSql.Odbc.Dameng var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(" || "); + if (pkidx > 0) sb.Append(" || '+' || "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs index c13928d9..b24bb642 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs @@ -36,7 +36,7 @@ namespace FreeSql.Odbc.Default var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); + if (pkidx > 0) caseWhen.Append(" + '+' + "); caseWhen.Append(_utils.Adapter.CastSql(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)), _utils.Adapter.MappingOdbcTypeVarChar)); ++pkidx; } @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.Default var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); + if (pkidx > 0) sb.Append(" + '+' + "); sb.Append(_utils.Adapter.CastSql(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)), _utils.Adapter.MappingOdbcTypeVarChar)); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs index e2495d19..2701cfcb 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.GBase var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(" || "); + if (pkidx > 0) caseWhen.Append(" || '+' || "); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); ++pkidx; } @@ -56,7 +56,7 @@ namespace FreeSql.Odbc.GBase var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(" || "); + if (pkidx > 0) sb.Append(" || '+' || "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index c2234536..b0892779 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -73,7 +73,7 @@ namespace FreeSql.Odbc.MySql var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); + if (pkidx > 0) caseWhen.Append(", '+', "); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } @@ -91,7 +91,7 @@ namespace FreeSql.Odbc.MySql var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); + if (pkidx > 0) sb.Append(", '+', "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index 629d3d89..97f4f680 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -39,7 +39,7 @@ namespace FreeSql.Odbc.Oracle var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(" || "); + if (pkidx > 0) caseWhen.Append(" || '+' || "); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } @@ -57,7 +57,7 @@ namespace FreeSql.Odbc.Oracle var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(" || "); + if (pkidx > 0) sb.Append(" || '+' || "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index f62def8f..fb8ce06a 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -72,7 +72,7 @@ namespace FreeSql.Odbc.PostgreSQL var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(" || "); + if (pkidx > 0) caseWhen.Append(" || '+' || "); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); ++pkidx; } @@ -90,7 +90,7 @@ namespace FreeSql.Odbc.PostgreSQL var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(" || "); + if (pkidx > 0) sb.Append(" || '+' || "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index aa57a9de..c6b1f146 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -77,7 +77,7 @@ namespace FreeSql.Odbc.SqlServer var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); + if (pkidx > 0) caseWhen.Append(" + '+' + "); caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); ++pkidx; } @@ -94,7 +94,7 @@ namespace FreeSql.Odbc.SqlServer var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); + if (pkidx > 0) sb.Append(" + '+' + "); sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append(" as varchar)"); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index 17cc8a5a..d24b384d 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -39,7 +39,7 @@ namespace FreeSql.Oracle.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(" || "); + if (pkidx > 0) caseWhen.Append(" || '+' || "); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } @@ -57,7 +57,7 @@ namespace FreeSql.Oracle.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(" || "); + if (pkidx > 0) sb.Append(" || '+' || "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); ++pkidx; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 18773870..ea1320c7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -81,7 +81,7 @@ namespace FreeSql.PostgreSQL.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(" || "); + if (pkidx > 0) caseWhen.Append(" || '+' || "); if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); ++pkidx; @@ -100,7 +100,7 @@ namespace FreeSql.PostgreSQL.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(" || "); + if (pkidx > 0) sb.Append(" || '+' || "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); ++pkidx; } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index 4b69d8c5..bfb9e139 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -78,7 +78,7 @@ namespace FreeSql.SqlServer.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); + if (pkidx > 0) caseWhen.Append(" + '+' + "); caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); ++pkidx; } @@ -95,7 +95,7 @@ namespace FreeSql.SqlServer.Curd var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); + if (pkidx > 0) sb.Append(" + '+' + "); sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append(" as varchar)"); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index 8988d244..507d4e6f 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -35,11 +35,11 @@ namespace FreeSql.Sqlite.Curd caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } - caseWhen.Append("CONCAT("); + caseWhen.Append("("); var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) caseWhen.Append(", "); + if (pkidx > 0) caseWhen.Append(" || '+' || "); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); ++pkidx; } @@ -53,11 +53,11 @@ namespace FreeSql.Sqlite.Curd sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); return; } - sb.Append("CONCAT("); + sb.Append("("); var pkidx = 0; foreach (var pk in _table.Primarys) { - if (pkidx > 0) sb.Append(", "); + if (pkidx > 0) sb.Append(" || '+' || "); sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); ++pkidx; } From 646d9532af3c6205365de92270d5077266002cb2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 24 Feb 2020 18:08:04 +0800 Subject: [PATCH 0433/1029] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E9=A5=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 330 +++++++++--------- .../SqlServer/OdbcSqlServerCodeFirst.cs | 4 +- .../SqlServerCodeFirst.cs | 4 +- 3 files changed, 178 insertions(+), 160 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 66b08dae..21df8587 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2426,7 +2426,180 @@ - + Insert/Update自动值处理 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构 + + + + + 转大写同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update @@ -2701,161 +2874,6 @@ - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 中间表,多对多 - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - - - C#: that >= between && that <= and - SQL: that BETWEEN between AND and - - - - - - - - - 注意:这个方法和 Between 有细微区别 - C#: that >= start && that < end - SQL: that >= start and that < end - - - - - - C#:从元组集合中查找 exp1, exp2 是否存在 diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 95f4b76d..b6eeddae 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -251,7 +251,7 @@ inner join sys.types b on b.user_type_id = a.user_type_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id where a.object_id in (object_id(N'[{1}].[{2}]')); -use " + database, tboldname ?? tbname); +use [" + database + "];", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new { @@ -303,7 +303,7 @@ from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_primary_key = 0; -use " + database, tboldname ?? tbname); +use [" + database + "];", tboldname ?? tbname); var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); foreach (var uk in tb.Indexes) { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 86927f95..6276be91 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -250,7 +250,7 @@ inner join sys.types b on b.user_type_id = a.user_type_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id where a.object_id in (object_id(N'[{1}].[{2}]')); -use " + database, tboldname ?? tbname); +use [" + database + "];", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new { @@ -302,7 +302,7 @@ from sys.index_columns a inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_primary_key = 0; -use " + database, tboldname ?? tbname); +use [" + database + "];", tboldname ?? tbname); var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); foreach (var uk in tb.Indexes) { From 7796cd1c419d2a653596447a9366babdfa0d900d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 24 Feb 2020 18:19:52 +0800 Subject: [PATCH 0434/1029] v1.2.0-preview5 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1431789c..2c864301 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 3d9576f8..b044b378 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index c952abab..ae7ad86f 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6799a0d3..ba38dbdf 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 7ff1dc1b..56938b21 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.2.0-preview3 + 1.2.0-preview5 FreeSql DbFirst 实体生成器 true key.snk diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index b25deadc..dd1834fb 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 99e6cdb7..570ca81c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 84c55ec2..945a8ad1 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 784def0a..f999e715 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index bc1fe6aa..189209d2 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b5a69ee5..c7e8239c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8a2e77a7..e6f21429 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index ef53633b..01b7ff6e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 0bb8c4b0..da828171 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 5161be40..6b9a545d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e94acaa6..5f4d2514 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 44632342..a5ab08ed 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview3 + 1.2.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 96f3957b984a537fa5c9ababb2c07f487857bdd5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 25 Feb 2020 17:18:31 +0800 Subject: [PATCH 0435/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Oracle=20?= =?UTF-8?q?=E5=AF=BC=E8=88=AA=E5=B1=9E=E6=80=A7=20=E8=A1=A8=E5=88=AB?= =?UTF-8?q?=E5=90=8D=E8=BF=87=E9=95=BF=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs | 8 +++++++- Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index bf1d8471..6dafdef1 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -121,7 +121,13 @@ namespace FreeSql.Odbc.Oracle sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.Append(_tosqlAppendContent).ToString(); + var sql = sb.Append(_tosqlAppendContent).ToString(); + + var aliasGreater30 = 0; + foreach (var tb in _tables) + if (tb.Alias.Length > 30) sql = sql.Replace(tb.Alias, $"than30_{aliasGreater30++}"); + + return sql; } public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index fb94feaa..f73aaaa5 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -121,7 +121,13 @@ namespace FreeSql.Oracle.Curd sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); } - return sb.Append(_tosqlAppendContent).ToString(); + var sql = sb.Append(_tosqlAppendContent).ToString(); + + var aliasGreater30 = 0; + foreach (var tb in _tables) + if (tb.Alias.Length > 30) sql = sql.Replace(tb.Alias, $"than30_{aliasGreater30++}"); + + return sql; } public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } From 761b6e0068f91aeffb078f26b3f7400b08374faa Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 27 Feb 2020 12:54:43 +0800 Subject: [PATCH 0436/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbSet.Where?= =?UTF-8?q?=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B#216?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 32 ++++++++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 26 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 1d90c559..8d1d11fe 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -22,9 +22,41 @@ namespace FreeSql.Tests public class UnitTest3 { + public class Song23 + { + public long Id { get; set; } + public string Name { get; set; } + } + + public class Author23 + { + public long Id { get; set; } + public long SongId { get; set; } + public string Name { get; set; } + } + + public class TestDbContext : DbContext + { + public TestDbContext(IFreeSql orm) : base(orm, null) + { + } + public DbSet Songs { get; set; } + public DbSet Authors { get; set; } + } + [Fact] public void Test03() { + var context = new TestDbContext(g.sqlite); + + var sql = context.Songs + .Where(a => + context.Authors + //.Select //加上这句就不报错,不加上报 variable 'a' of type 'Song' referenced from scope '', but it is not defined + .Where(b => b.SongId == a.Id) + .Any()) + .ToSql(a => a.Name); + //using (var conn = new SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=webchat-abc;Pooling=true;Max Pool Size=13")) //{ // conn.Open(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 9a9b7a86..3dc16e12 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -771,6 +771,32 @@ namespace FreeSql.Internal } } } + if (new[] { "Where", "WhereIf" }.Contains(exp3tmpCall.Method.Name) && exp3tmpCall.Object != null) + { + //这段特别兼容 DbSet.Where 表达式解析 #216 + var exp3tmpTestCall = Expression.Call(exp3tmpCall.Object, exp3tmpCall.Method, exp3tmpCall.Arguments.Select(a => + { + var a2 = a; + if (a2.NodeType == ExpressionType.Quote) a2 = (a as UnaryExpression)?.Operand; + if (a2?.NodeType == ExpressionType.Lambda) + { + var alambda = a2 as LambdaExpression; + if (alambda.ReturnType == typeof(bool)) + return Expression.Constant(null, a.Type);// Expression.Lambda(Expression.Constant(true), alambda.Parameters); + } + return a; + //if (a.Type == typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(exp3tmp.Type.GetGenericArguments()[0], typeof(bool)))) + // return Expression.Lambda(Expression.Constant(true), + }).ToArray()); + fsql = Expression.Lambda(exp3tmpTestCall).Compile().DynamicInvoke(); + var fsqlFindMethod = fsql.GetType().GetMethod(exp3tmpCall.Method.Name, exp3tmpCall.Arguments.Select(a => a.Type).ToArray()); + if (fsqlFindMethod == null) + throw new Exception($"无法解析表达式方法 {exp3tmpCall.Method.Name}"); + var exp3StackOld = exp3Stack; + exp3Stack = new Stack(); + exp3Stack.Push(Expression.Call(Expression.Constant(fsql), fsqlFindMethod, exp3tmpCall.Arguments)); + while (exp3StackOld.Any()) exp3Stack.Push(exp3StackOld.Pop()); + } } if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke(); fsqlType = fsql?.GetType(); From f22f65fee9de6fae2c23620de9f0b94d01121045 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 28 Feb 2020 10:41:03 +0800 Subject: [PATCH 0437/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbContext/Re?= =?UTF-8?q?pository=20Update=20=E4=B8=8D=E6=9B=B4=E6=96=B0=20DbUpdateValue?= =?UTF-8?q?=20=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B#219?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ----- ...eeSql.Tests.Provider.MySqlConnector.csproj | 1 + .../MySqlConnector/MySqlCodeFirstTest.cs | 24 ++++++++++++++ .../Dameng/DamengCodeFirstTest.cs | 22 +++++++++++++ .../Default/OdbcCodeFirstTest.cs | 22 +++++++++++++ .../MySql/MySqlCodeFirstTest.cs | 22 +++++++++++++ .../Oracle/OracleCodeFirstTest.cs | 22 +++++++++++++ .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 22 +++++++++++++ .../SqlServer/SqlServerCodeFirstTest.cs | 22 +++++++++++++ .../MsAccess/MsAccessCodeFirstTest.cs | 22 +++++++++++++ .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 26 +++++++++++++++- .../Oracle/OracleCodeFirstTest.cs | 22 +++++++++++++ .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 22 +++++++++++++ .../SqlServer/SqlServerCodeFirstTest.cs | 22 +++++++++++++ .../Sqlite/SqliteCodeFirstTest.cs | 22 +++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 8 +++++ FreeSql/Extensions/EntityUtilExtensions.cs | 31 +++++++++++++------ 17 files changed, 321 insertions(+), 18 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj index 9ed1b21a..07efc1f8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj @@ -17,6 +17,7 @@ + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 7f174fd9..86460dce 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -57,6 +57,30 @@ namespace FreeSql.Tests.MySqlConnector Assert.Equal(item., item2.); g.mysql.Update<ı2>().SetSource(item2).ExecuteAffrows(); + + + + item. = "Ա"; + Assert.Equal(1, g.mysql.Update<ı2>().SetSource(item).ExecuteAffrows()); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.mysql.GetRepository<ı2>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı2 { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index 9d19d28b..b5ba4461 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -28,6 +28,28 @@ namespace FreeSql.Tests.Odbc.Dameng Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.dameng.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.dameng.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs index c26d27ff..e04d5d40 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs @@ -25,6 +25,28 @@ namespace FreeSql.Tests.Odbc.Default Assert.NotNull(item2); Assert.Equal(item.编号, item2.编号); Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新"; + Assert.Equal(1, g.odbc.Update<测试中文表>().SetSource(item).ExecuteAffrows()); + item2 = g.odbc.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo"; + var repo = g.odbc.GetRepository<测试中文表>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.odbc.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.odbc.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); } class 测试中文表 { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index d06c3a27..6c52d3ae 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -55,6 +55,28 @@ namespace FreeSql.Tests.Odbc.MySql Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.mysql.Update<ı2>().SetSource(item).ExecuteAffrows()); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.mysql.GetRepository<ı2>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı2 { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs index a5686eeb..2ae10e27 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -28,6 +28,28 @@ namespace FreeSql.Tests.Odbc.Oracle Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.oracle.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.oracle.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs index 81773eba..96a926fd 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -32,6 +32,28 @@ namespace FreeSql.Tests.Odbc.PostgreSQL Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.pgsql.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.pgsql.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index 68ca3891..355854b2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -29,6 +29,28 @@ namespace FreeSql.Tests.Odbc.SqlServer Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.sqlserver.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.sqlserver.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.sqlserver.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.sqlserver.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.sqlserver.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs index 4f3506f1..bd27dc0c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -28,6 +28,28 @@ namespace FreeSql.Tests.MsAccess Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.msaccess.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.msaccess.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.msaccess.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.msaccess.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.msaccess.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index f98d084c..ad7efc27 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -52,6 +52,28 @@ namespace FreeSql.Tests.MySql Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item.22 = "Ա"; + Assert.Equal(1, g.mysql.Update<ı2>().SetSource(item).ExecuteAffrows()); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item.22, item2.22); + + item.22 = "Ա_repo"; + var repo = g.mysql.GetRepository<ı2>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item.22, item2.22); + + item.22 = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.mysql.Select<ı2>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item.22, item2.22); } class ı2 { @@ -60,6 +82,8 @@ namespace FreeSql.Tests.MySql public string { get; protected set; } + public string 22 { get; set; } + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] public DateTime ʱ { get; protected set; } @@ -68,7 +92,7 @@ namespace FreeSql.Tests.MySql public static ı2 Create(string title, DateTime ctm) { - return new ı2 { = title, ʱ = ctm }; + return new ı2 { = title, 22 = title, ʱ = ctm }; } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index d1ae51d2..f1eeab72 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -28,6 +28,28 @@ namespace FreeSql.Tests.Oracle Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.oracle.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.oracle.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index c2a92151..5db7074a 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -35,6 +35,28 @@ namespace FreeSql.Tests.PostgreSQL Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.pgsql.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.pgsql.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.pgsql.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 2566b4ec..b86c0e2f 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -29,6 +29,28 @@ namespace FreeSql.Tests.SqlServer Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.sqlserver.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.sqlserver.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.sqlserver.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.sqlserver.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.sqlserver.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index 9eb09d80..1d48cb21 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -56,6 +56,28 @@ namespace FreeSql.Tests.Sqlite Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.sqlite.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.sqlite.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.sqlite.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.sqlite.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.sqlite.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); } class ı { diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 8d1d11fe..c468a7a7 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -57,6 +57,14 @@ namespace FreeSql.Tests .Any()) .ToSql(a => a.Name); + sql = context.Songs + .Where(a => + context.Authors + .Select //加上这句就不报错,不加上报 variable 'a' of type 'Song' referenced from scope '', but it is not defined + .Where(b => b.SongId == a.Id) + .Any()) + .ToSql(a => a.Name); + //using (var conn = new SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=webchat-abc;Pooling=true;Max Pool Size=13")) //{ // conn.Open(); diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 7ec6cc31..044fd446 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -553,20 +553,31 @@ namespace FreeSql.Extensions.EntityUtil { if (_table.ColumnsByCs.TryGetValue(prop.Name, out var trycol) == false) continue; exps.Add( - Expression.IfThenElse( - Expression.Equal( - Expression.MakeMemberAccess(var1Parm, prop), - Expression.MakeMemberAccess(var2Parm, prop) - ), + trycol.Attribute.CanUpdate == false ? Expression.IfThen( Expression.IsTrue(parm3), Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) - ), - Expression.IfThen( - Expression.IsFalse(parm3), - Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) + ) : ( + trycol.Attribute.CanUpdate && string.IsNullOrEmpty(trycol.DbUpdateValue) == false ? + Expression.IfThen( + Expression.IsFalse(parm3), + Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) + ) : + Expression.IfThenElse( + Expression.Equal( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.MakeMemberAccess(var2Parm, prop) + ), + Expression.IfThen( + Expression.IsTrue(parm3), + Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) + ), + Expression.IfThen( + Expression.IsFalse(parm3), + Expression.Call(var1Ret, typeof(List).GetMethod("Add", new Type[] { typeof(string) }), Expression.Constant(trycol.Attribute.Name)) + ) + ) ) - ) ); a++; } From 5cff594161aa73e5f239f3fc92d0c440e23e0adf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 28 Feb 2020 11:54:13 +0800 Subject: [PATCH 0438/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IUpdate.SetD?= =?UTF-8?q?to=20=E6=A0=B9=E6=8D=AE=20dto=20=E6=9B=B4=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=9B#218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++ FreeSql/FreeSql.xml | 11 ++++ FreeSql/Interface/Curd/IUpdate.cs | 12 ++++ .../Internal/CommonProvider/UpdateProvider.cs | 56 ++++++++++++++----- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 21df8587..5c768294 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2000,6 +2000,17 @@ 参数 + + + 设置更新的列 + + SetDto(new { title = "xxx", clicks = 2 }) + + SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + + dto 或 Dictionary<string, object> + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 8595b648..5e79eb95 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -56,6 +56,7 @@ namespace FreeSql /// 实体集合 /// IUpdate SetSource(IEnumerable source); + /// /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) /// @@ -107,6 +108,17 @@ namespace FreeSql /// IUpdate SetRaw(string sql, object parms = null); + /// + /// 设置更新的列 + /// + /// SetDto(new { title = "xxx", clicks = 2 }) + /// + /// SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + /// + /// dto 或 Dictionary<string, object> + /// + IUpdate SetDto(object dto); + /// /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) /// 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 141abdd9..0b358e40 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -334,26 +334,31 @@ namespace FreeSql.Internal.CommonProvider return this; } + protected void SetPriv(ColumnInfo col, object value) + { + object paramVal = null; + if (value != null) + { + if (col.Attribute.MapType == value.GetType()) paramVal = value; + else paramVal = Utils.GetDataReaderValue(col.Attribute.MapType, value); + } + _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); + if (_noneParameter) + { + _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, col.Attribute.MapType, paramVal)); + } + else + { + _set.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}")); + _commonUtils.AppendParamter(_params, null, col, col.Attribute.MapType, paramVal); + } + } public IUpdate Set(Expression> column, TMember value) { var cols = new List(); _commonExpression.ExpressionSelectColumn_MemberAccess(null, cols, SelectTableInfoType.From, column?.Body, true, null); if (cols.Count != 1) return this; - var col = cols.First(); - object paramVal = null; - if (col.Column.Attribute.MapType == typeof(TMember)) paramVal = value; - else paramVal = Utils.GetDataReaderValue(col.Column.Attribute.MapType, value); - _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Column.Attribute.Name)).Append(" = "); - if (_noneParameter) - { - _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, col.Column.Attribute.MapType, paramVal)); - } - else - { - _set.Append(_commonUtils.QuoteWriteParamter(col.Column.Attribute.MapType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}")); - _commonUtils.AppendParamter(_params, null, col.Column, col.Column.Attribute.MapType, paramVal); - } - //foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value); + SetPriv(cols.First().Column, value); return this; } public IUpdate Set(Expression> exp) @@ -424,6 +429,27 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IUpdate SetDto(object dto) + { + if (dto == null) return this; + if (dto is Dictionary) + { + var dic = dto as Dictionary; + foreach (var kv in dic) + { + if (_table.ColumnsByCs.TryGetValue(kv.Key, out var trycol) == false) continue; + SetPriv(trycol, kv.Value); + } + } + var dtoProps = dto.GetType().GetProperties(); + foreach (var dtoProp in dtoProps) + { + if (_table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trycol) == false) continue; + SetPriv(trycol, dtoProp.GetValue(dto, null)); + } + return this; + } + public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _params)); public IUpdate Where(string sql, object parms = null) { From 1e88e8add2f0fec73b35324afec4668148e63f37 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 28 Feb 2020 13:18:33 +0800 Subject: [PATCH 0439/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IUpdate.SetD?= =?UTF-8?q?to=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=EF=BC=9B#218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - .../MySqlConnector/Curd/MySqlUpdateTest.cs | 13 ++ .../Dameng/Curd/DamengUpdateTest.cs | 9 ++ .../Default/Curd/OdbcUpdateTest.cs | 9 ++ .../MySql/Curd/MySqlUpdateTest.cs | 9 ++ .../Oracle/Curd/OracleUpdateTest.cs | 9 ++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 9 ++ .../SqlServer/Curd/SqlServerUpdateTest.cs | 9 ++ .../MsAccess/Curd/MsAccessUpdateTest.cs | 9 ++ .../MySql/Curd/MySqlUpdateTest.cs | 13 ++ .../Oracle/Curd/OracleUpdateTest.cs | 13 ++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 13 ++ .../SqlServer/Curd/SqlServerUpdateTest.cs | 13 ++ .../Sqlite/Curd/SqliteUpdateTest.cs | 13 ++ FreeSql/FreeSql.xml | 131 ------------------ .../Internal/CommonProvider/UpdateProvider.cs | 7 +- 16 files changed, 143 insertions(+), 143 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 8c22ca85..34f0a3c8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -170,6 +170,19 @@ namespace FreeSql.Tests.MySqlConnector Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = @p_0, `Title` = @p_1 WHERE (`Id` = 1)", sql); + sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = 1, `Title` = 'xxx' WHERE (`Id` = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = @p_0, `Title` = @p_1 WHERE (`Id` = 1)", sql); + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = 1, `Title` = 'xxx' WHERE (`Id` = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs index 1c5c437d..eb9c649d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs @@ -123,6 +123,15 @@ namespace FreeSql.Tests.Odbc.Dameng Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + ? WHERE (\"ID\" = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs index 7adec224..e70ff06e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs @@ -115,6 +115,15 @@ namespace FreeSql.Tests.Odbc.Default Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + ? WHERE ([Id] = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = N'xxx' WHERE ([Id] = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = N'xxx' WHERE ([Id] = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs index a187cf59..c823a1fc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -170,6 +170,15 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = 1, `Title` = 'xxx' WHERE (`Id` = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = 1, `Title` = 'xxx' WHERE (`Id` = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs index 5882a1e5..a4ae7706 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -113,6 +113,15 @@ namespace FreeSql.Tests.Odbc.Oracle Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + ? WHERE (\"ID\" = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index ecc43d80..854481d5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -114,6 +114,15 @@ namespace FreeSql.Tests.Odbc.PostgreSQL Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + ? WHERE (\"id\" = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = 1, \"title\" = 'xxx' WHERE (\"id\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = 1, \"title\" = 'xxx' WHERE (\"id\" = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs index 99b73c02..1ea9b81a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs @@ -116,6 +116,15 @@ namespace FreeSql.Tests.Odbc.SqlServer Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + ? WHERE ([Id] = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = N'xxx' WHERE ([Id] = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = N'xxx' WHERE ([Id] = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs index 76c44fbc..4b6c188d 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs @@ -125,6 +125,15 @@ namespace FreeSql.Tests.MsAccess Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + ? WHERE ([Id] = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = 'xxx' WHERE ([Id] = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = 'xxx' WHERE ([Id] = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 4f8cbe00..98ce79c2 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -171,6 +171,19 @@ namespace FreeSql.Tests.MySql Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ?p_0, `Title` = ?p_1 WHERE (`Id` = 1)", sql); + sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = 1, `Title` = 'xxx' WHERE (`Id` = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ?p_0, `Title` = ?p_1 WHERE (`Id` = 1)", sql); + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = 1, `Title` = 'xxx' WHERE (`Id` = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index b3413337..67c163f2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -113,6 +113,19 @@ namespace FreeSql.Tests.Oracle Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + :incrClick WHERE (\"ID\" = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = :p_0, \"TITLE\" = :p_1 WHERE (\"ID\" = 1)", sql); + sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = :p_0, \"TITLE\" = :p_1 WHERE (\"ID\" = 1)", sql); + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 1eabd7f3..5b574ff6 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -115,6 +115,19 @@ namespace FreeSql.Tests.PostgreSQL Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + @incrClick WHERE (\"id\" = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = @p_0, \"title\" = @p_1 WHERE (\"id\" = 1)", sql); + sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = 1, \"title\" = 'xxx' WHERE (\"id\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = @p_0, \"title\" = @p_1 WHERE (\"id\" = 1)", sql); + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = 1, \"title\" = 'xxx' WHERE (\"id\" = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 9dd1dea6..38e8a77a 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -126,6 +126,19 @@ namespace FreeSql.Tests.SqlServer Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + @incrClick WHERE ([Id] = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = @p_0, [Title] = @p_1 WHERE ([Id] = 1)", sql); + sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = N'xxx' WHERE ([Id] = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = @p_0, [Title] = @p_1 WHERE ([Id] = 1)", sql); + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = N'xxx' WHERE ([Id] = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index fe4532a7..e13e0c0b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -118,6 +118,19 @@ namespace FreeSql.Tests.Sqlite Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + :incrClick WHERE (\"Id\" = 1)", sql); } [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = @p_0, \"Title\" = @p_1 WHERE (\"Id\" = 1)", sql); + sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = 1, \"Title\" = 'xxx' WHERE (\"Id\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = @p_0, \"Title\" = @p_1 WHERE (\"Id\" = 1)", sql); + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = 1, \"Title\" = 'xxx' WHERE (\"Id\" = 1)", sql); + } + [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5c768294..c4c9f9c1 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2270,137 +2270,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 0b358e40..ce44bcba 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -337,11 +337,8 @@ namespace FreeSql.Internal.CommonProvider protected void SetPriv(ColumnInfo col, object value) { object paramVal = null; - if (value != null) - { - if (col.Attribute.MapType == value.GetType()) paramVal = value; - else paramVal = Utils.GetDataReaderValue(col.Attribute.MapType, value); - } + if (col.Attribute.MapType == col.CsType) paramVal = value; + else paramVal = Utils.GetDataReaderValue(col.Attribute.MapType, value); _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); if (_noneParameter) { From ce7140783ee5706878b078f34150431416a5c468 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 28 Feb 2020 18:09:32 +0800 Subject: [PATCH 0440/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20EfFluentApi?= =?UTF-8?q?=20=E4=B8=80=E4=B8=AA=E5=8F=82=E6=95=B0=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs | 2 +- .../ICodeFirstExtensions.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs index b914fbab..b9ab2cb2 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs @@ -271,7 +271,7 @@ namespace FreeSql.Extensions.EfCoreFluentApi _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); return this; } - public HasManyFluent HasForeignKey(Expression> foreignKey) + public HasManyFluent HasForeignKey(Expression> foreignKey) { if (foreignKey?.Body == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); var exp = foreignKey.Body; diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs index bf2ff003..725da63a 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs @@ -36,6 +36,10 @@ namespace FreeSql.Extensions.EfCoreFluentApi //多对多 eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); }); + cf.Entity(eb => + { + eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey( a => a.TypeId) + }); } public class SongType From 86b6608bccb0810230abb70806540b984c449de4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 28 Feb 2020 18:45:34 +0800 Subject: [PATCH 0441/1029] ## v1.2.0 #208 #201 #216 #219 #218 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../ICodeFirstExtensions.cs | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 13 +- .../FreeSql.Generator.csproj | 5 +- Extensions/FreeSql.Generator/key.snk | Bin 596 -> 0 bytes FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 131 ++++++++++++++++++ .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 163 insertions(+), 25 deletions(-) delete mode 100644 Extensions/FreeSql.Generator/key.snk diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2c864301..231c8d99 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.2.0-preview5 + 1.2.0 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index b044b378..1d4bd0d2 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs index 725da63a..198f6a3c 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs @@ -38,7 +38,7 @@ namespace FreeSql.Extensions.EfCoreFluentApi }); cf.Entity(eb => { - eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey( a => a.TypeId) + eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); }); } diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ae7ad86f..f16b55e2 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ba38dbdf..e78eae61 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -1,8 +1,8 @@  - netstandard2.0;net45;net40 - 1.2.0-preview5 + netstandard2.0;netstandard2.1;net45;net40 + 1.2.0 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. @@ -24,12 +24,15 @@ - + - + + + + - + ns20;netstandard20 diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 56938b21..21d5a195 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,11 +12,8 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.2.0-preview5 + 1.2.0 FreeSql DbFirst 实体生成器 - true - key.snk - false diff --git a/Extensions/FreeSql.Generator/key.snk b/Extensions/FreeSql.Generator/key.snk deleted file mode 100644 index 63fe97bf48315cf06d5051753aaa24f9fa597eb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096Y^NXEz#4OoYIJvsI9xP*9_D;W?{2~_O zub%kw9h^4Z+T%7;w~pC?6@17a`SFfWN#L4GkxVx0it7@cn|NzBd=68SHK{J`3xJhE zo~}zoV1Y;}bMJW+DT*_*#IA|q^@DkSOtO_JsEU)xDsMZXaeKEP zQ-{;y`e%VnpZ@gu?Q_G1L+Hx4Uz)qxI0?7}$+A71?MFyXxMi>{wm>Pcq-+h+Ms6Vq+=! z?YsQ`^Ed)Dt0G=aD~luUE@Mc%Mt#9yW#VR8Rd|MZJk~xiEQsS3j!@?^LpG#zbjP>b ztc9pOyJs&}W3Pk^9z36pp{X1WpgU&_U9H+&YBa4<%P`)9X|z&`S}a0v{&t2fHnOM>`4>P=XZ5Sk^Pze7%+SfW;2gM{v6v8Sk%_Ui)ss* zN75Ihrn5-Jt+mBR%_vEhi!$Q4ty;bb8_RqnVeK1F4ebtuO~yA0L4RxmL}S%&hYtx4b~1K16&s7MG;qOeCYm`pN>ppOMdSusU3GT&!C7>3cyq iT+~J!Ht>Yp+@HXllzB6JFmx8GLI6nDeRy+uAmpJh@+3e2 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index dd1834fb..3bc5814d 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 570ca81c..d832af64 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dc0203b8..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 945a8ad1..c980a8da 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0-preview5 + 1.2.0 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f999e715..86365c2e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c4c9f9c1..5c768294 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2270,6 +2270,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 }) + + + + + + 可自定义解析表达式 diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 189209d2..867c4443 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c7e8239c..c05e4c0e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index e6f21429..049b91e4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 01b7ff6e..d914e2e4 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index da828171..7fdf2c37 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 6b9a545d..722ee55d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5f4d2514..46879916 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a5ab08ed..75c8797a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0-preview5 + 1.2.0 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 157dbc283e22475994024d00dc0b1e396c7a484f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 29 Feb 2020 13:05:48 +0800 Subject: [PATCH 0442/1029] update readme --- Docs/1. quickstart.md | 97 --------- Docs/2 入门.md | 28 --- Docs/2.1 安装FreeSql | 0 Docs/codefirst.md | 193 ----------------- Docs/dbfirst.md | 109 ---------- Docs/delete.md | 82 -------- Docs/expression.md | 177 ---------------- Docs/generator.md | 103 --------- Docs/insert.md | 79 ------- Docs/select.md | 259 ----------------------- Docs/update.md | 129 ------------ FreeSql.DbContext/readme.md | 396 +++++++++++++++-------------------- FreeSql.Repository/readme.md | 288 +++++++++++++++++-------- readme.md | 227 +++++++++----------- 14 files changed, 455 insertions(+), 1712 deletions(-) delete mode 100644 Docs/1. quickstart.md delete mode 100644 Docs/2 入门.md delete mode 100644 Docs/2.1 安装FreeSql delete mode 100644 Docs/codefirst.md delete mode 100644 Docs/dbfirst.md delete mode 100644 Docs/delete.md delete mode 100644 Docs/expression.md delete mode 100644 Docs/generator.md delete mode 100644 Docs/insert.md delete mode 100644 Docs/select.md delete mode 100644 Docs/update.md diff --git a/Docs/1. quickstart.md b/Docs/1. quickstart.md deleted file mode 100644 index c9c021af..00000000 --- a/Docs/1. quickstart.md +++ /dev/null @@ -1,97 +0,0 @@ -# FreeSql 简介 - -FreeSql 是轻量化、可扩展和跨平台版的 .NETStandard 数据访问技术实现。 - -FreeSql 可用作对象关系映射程序 (O/RM),以便于开发人员能够使用 .NETStandard 对象来处理数据库,不必经常编写大部分数据访问代码。 - -FreeSql 支持 MySql/SqlServer/PostgreSQL 数据库技术实现。 - -## 模型 - -FreeSql 使用模型执行数据访问,模型由实体类表示数据库表或视图,用于查询和保存数据。 有关详细信息,请参阅创建模型。 - -可从现有数据库生成实体模型,提供 IDbFirst 生成实体模型。 - -或者手动创建模型,基于模型创建或修改数据库,提供 ICodeFirst 同步结构的 API(甚至可以做到开发阶段自动同步)。 - -```csharp -using FreeSql.DataAnnotations; -using System; - -public class Blog -{ - [Column(IsIdentity = true, IsPrimary = true)] - public int BlogId { get; set; } - public string Url { get; set; } - public int Rating { get; set; } -} - -public class Post -{ - public int PostId { get; set; } - public string Title { get; set; } - public string Content { get; set; } - - public int BlogId { get; set; } - public Blog Blog { get; set; } -} -``` - -## 声明 - -```csharp -var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" + - "Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10"; - -IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.MySql, connstr) - .UseSlave("connectionString1", "connectionString2") //使用从数据库,支持多个 - - .UseLogger(null) //使用日志,不指定默认输出控制台 ILogger - .UseCache(null) //使用缓存,不指定默认使用内存 IDistributedCache - - .UseAutoSyncStructure(true) //自动同步实体结构到数据库 - .UseSyncStructureToLower(true) //转小写同步结构 - .Build(); -``` - -注意: IFreeSql 在项目中应以单例声明,而不是在每次使用的时候创建。 - -## 查询 - -```csharp -var blogs = fsql.Select - .Where(b => b.Rating > 3) - .OrderBy(b => b.Url) - .ToList(); -``` - -## 插入 - -```csharp -var blog = new Blog { Url = "http://sample.com" }; -blog.BlogId = (int)fsql.Insert() - .AppendData(blog) - .ExecuteIdentity(); -``` - -## 更新 - -```csharp -fsql.Update() - .Set(b => b.Url, "http://sample2222.com") - .Where(b => b.Url == "http://sample.com") - .ExecuteAffrows(); -``` - -## 删除 - -```csharp -fsql.Delete() - .Where(b => b.Url == "http://sample.com") - .ExecuteAffrows(); -``` - -## 后续步骤 - -有关介绍性教程,请参阅 [FreeSql 入门]()。 diff --git a/Docs/2 入门.md b/Docs/2 入门.md deleted file mode 100644 index 00857ee9..00000000 --- a/Docs/2 入门.md +++ /dev/null @@ -1,28 +0,0 @@ -# FreeSql 入门 - -## 安装 - -FreeSql 是一个 .NET Standard 2.0 库,支持 .NET Framework 4.6.1 或 .NET Core 或更高版本的应用程序。 - -```shell -dotnet add package FreeSql -``` - -或者 - -```shell -Install-Package FreeSql -``` - -## 入门教程 - -FreeSql 可基于现有数据库创建模型,也可基于模型创建数据库。 提供的教程演示了这两种方法。 - -* .NET Core 控制台应用 - -- * 新建数据库 - -* ASP.NET Core 应用 - -- * 新建数据库 -- * 现有数据库 \ No newline at end of file diff --git a/Docs/2.1 安装FreeSql b/Docs/2.1 安装FreeSql deleted file mode 100644 index e69de29b..00000000 diff --git a/Docs/codefirst.md b/Docs/codefirst.md deleted file mode 100644 index 34d25cee..00000000 --- a/Docs/codefirst.md +++ /dev/null @@ -1,193 +0,0 @@ -# CodeFirst - -## 类型映射 - -| csharp | MySql | SqlServer | PostgreSQL | oracle | -| - | - | - | - | - | -| bool \| bool? | bit(1) | bit | bool | number(1) | -| sbyte \| sbyte? | tinyint(3) | smallint | int2 | number(4) | -| short \| short? | smallint(6) | smallint | int2 | number(6) | -| int \| int? | int(11) | int | int4 | number(11) | -| long \| long? | bigint(20) | bigint | int8 | number(21) | -| byte \| byte? | tinyint(3) unsigned | tinyint | int2 | number(3) | -| ushort \| ushort? | smallint(5) unsigned | int | int4 | number(5) | -| uint \| uint? | int(10) unsigned | bigint | int8 | number(10) | -| ulong \| ulong? | bigint(20) unsigned | decimal(20,0) | numeric(20,0) | number(20) | -| double \| double? | double | float | float8 | float(126) | -| float \| float? | float | real | float4 | float(63) | -| decimal \| decimal? | decimal(10,2) | decimal(10,2) | numeric(10,2) | number(10,2) | -| Guid \| Guid? | char(36) | uniqueidentifier | uuid | char(36 CHAR) | -| TimeSpan \| TimeSpan? | time | time | time | interval day(2) to second(6) | -| DateTime \| DateTime? | datetime | datetime | timestamp | timestamp(6) | -| DateTimeOffset \| DateTimeOffset? | - | - | datetimeoffset | timestamp(6) with local time zone | -| Enum \| Enum? | enum | int | int4 | number(16) | -| FlagsEnum \| FlagsEnum? | set | bigint | int8 | number(32) | -| byte[] | varbinary(255) | varbinary(255) | bytea | blob | -| string | varchar(255) | nvarchar(255) | varchar(255) | nvarchar2(255) | -| MygisPoint | point | - | - | - | -| MygisLineString | linestring | - | - | - | -| MygisPolygon | polygon | - | - | - | -| MygisMultiPoint | multipoint | - | - | - | -| MygisMultiLineString | multilinestring | - | - | - | -| MygisMultiPolygon | multipolygon | - | - | - | -| BitArray | - | - | varbit(64) | - | -| NpgsqlPoint \| NpgsqlPoint? | - | - | point | - | -| NpgsqlLine \| NpgsqlLine? | - | - | line | - | -| NpgsqlLSeg \| NpgsqlLSeg? | - | - | lseg | - | -| NpgsqlBox \| NpgsqlBox? | - | - | box | - | -| NpgsqlPath \| NpgsqlPath? | - | - | path | - | -| NpgsqlPolygon \| NpgsqlPolygon? | - | - | polygon | - | -| NpgsqlCircle \| NpgsqlCircle? | - | - | circle | - | -| (IPAddress Address, int Subnet) \| (IPAddress Address, int Subnet)? | - | - | cidr | - | -| IPAddress | - | - | inet | - | -| PhysicalAddress | - | - | macaddr | - | -| NpgsqlRange\ \| NpgsqlRange\? | - | - | int4range | - | -| NpgsqlRange\ \| NpgsqlRange\? | - | - | int8range | - | -| NpgsqlRange\ \| NpgsqlRange\? | - | - | numrange | - | -| NpgsqlRange\ \| NpgsqlRange\? | - | - | tsrange | - | -| PostgisPoint | - | - | geometry | - | -| PostgisLineString | - | - | geometry | - | -| PostgisPolygon | - | - | geometry | - | -| PostgisMultiPoint | - | - | geometry | - | -| PostgisMultiLineString | - | - | geometry | - | -| PostgisMultiPolygon | - | - | geometry | - | -| PostgisGeometry | - | - | geometry | - | -| PostgisGeometryCollection | - | - | geometry | - | -| Dictionary | - | - | hstore | - | -| JToken | - | - | jsonb | - | -| JObject | - | - | jsonb | - | -| JArray | - | - | jsonb | - | -| 数组 | - | - | 以上所有类型都支持 | - | - -> 以上类型和长度是默认值,可手工设置,如 string 属性可指定 [Column(DbType = "varchar(max)")] - -```csharp -IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .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") - .UseAutoSyncStructure(true) - - .UseMonitorCommand( - cmd => { - Console.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build(); -``` - -### 自动同步实体结构【开发环境必备】 - -自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - -```csharp -fsql.CodeFirst.IsAutoSyncDataStructure = true; -``` - -> 此功能默认为开启状态,发布正式环境后,请修改此设置 - -> 虽然【自动同步实体结构】功能开发非常好用,但是有个坏处,就是数据库后面会很乱,没用的字段一大堆 - -### 手工同步实体结构 - -| 实体&表对比 | 添加 | 改名 | 删除 | -| - | - | - | - | -| | √ | √ | X | - -| 实体属性&字段对比 | 添加 | 修改可空 | 修改自增 | 修改类型 | 改名 | 删除 | -| - | - | - | - | - | - | - | -| | √ | √ | √ | √ | √ | X | - -> 为了保证安全,不提供删除字段 - - -1、提供方法对比实体,与数据库中的变化部分 - -```csharp -var t1 = mysql.CodeFirst.GetComparisonDDLStatements(); - -class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } - public ushort fusho { get; set; } -} -``` -```sql -CREATE TABLE IF NOT EXISTS `cccddd`.`Topic` ( - `Id` INT(11) NOT NULL AUTO_INCREMENT, - `Clicks` INT(11) NOT NULL, - `Title` VARCHAR(255), - `CreateTime` DATETIME NOT NULL, - `fusho` SMALLINT(5) UNSIGNED NOT NULL, - PRIMARY KEY (`Id`) -) Engine=InnoDB CHARACTER SET utf8; -``` - -2、指定实体的表名 - -指定 Name 后,实体类名变化不影响数据库对应的表 -```csharp -[Table(Name = "tb_topic111")] -class Topic { - //... -} -``` - -3、无指定实体的表名,修改实体类名 - -指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - -```csharp -[Table(OldName = "Topic")] -class Topic2 { - //... -} -``` -```sql -ALTER TABLE `cccddd`.`Topic` RENAME TO `cccddd`.`Topic2`; -``` - -4、修改属性的类型 - -把 Id 类型改为 uint 后 -```sql -ALTER TABLE `cccddd`.`Topic2` MODIFY `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT; -``` -```csharp -[Column(DbType = "varchar(128)")] -public string Title { get; set; } -``` -```sql -ALTER TABLE `cccddd`.`Topic2` MODIFY `Title2` VARCHAR(128); -``` - -5、指定属性的字段名 - -这样指定后,修改实体的属性名不影响数据库对应的列 -```csharp -[Column(Name = "titl2")] -public string Title { get; set; } -``` - -6、无指定属性的字段名,修改属性名 - -指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - -```csharp -[Column(OldName = "Title2")] -public string Title { get; set; } -``` -```sql -ALTER TABLE `cccddd`.`Topic2` CHANGE COLUMN `Title2` `Title` VARCHAR(255); -``` - -7、提供方法同步结构 - -```csharp -var t2 = fsql.CodeFirst.SyncStructure(); -//同步实体类型到数据库 -``` diff --git a/Docs/dbfirst.md b/Docs/dbfirst.md deleted file mode 100644 index 0c9f119a..00000000 --- a/Docs/dbfirst.md +++ /dev/null @@ -1,109 +0,0 @@ -# DbFirst - -```csharp -IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .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") - .Build(); -``` - -### 获取所有数据库 - -```csharp -var t1 = fsql.DbFirst.GetDatabases(); -//返回字符串数组, ["cccddd", "test"] -``` - -### 获取指定数据库的表信息 - -```csharp -var t2 = fsql.DbFirst.GetTablesByDatabase(fsql.DbFirst.GetDatabases()[0]); -//返回包括表、列详情、主键、唯一键、索引、外键 -``` - -# 生成器 - -生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: - -| 模板名称 | 路径 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | -| ------------- | - | - |- | - |- | - |- | -| simple-entity | ../Templates/MySql/simple-entity | √ | X | X | √ | X | X | -| simple-entity-navigation-object | ../Templates/MySql/simple-entity-navigation-object | √ | √ | X | √ | X | X | -| rich-entity-navigation-object | ../Templates/MySql/rich-entity-navigation-object | √ | √ | √ | X | √ | X | - -> 更多模板逐步开发中。。。 - -```csharp -//创建模板生成类实现 -var gen = new FreeSql.Generator.TemplateGenerator(); -gen.Build(fsql.DbFirst, - @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) - @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 - "cccddd" //数据库 -); -``` - -## 模板语法 - -```html - - -{#title} - - - - -{#表达式} -{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 - - -{include ../header.html} -
-

aaa

-

bbb {#i}

-

ccc {#i}

-
- - -{module module_name1 parms1, 2, 3...} -{/module} -{module module_name2 parms1, 2, 3...} -{/module} - - -{import ../module.html as myname} -{#myname.module_name(parms1, 2, 3...)} - - -{extends ../inc/layout.html} -{block body}{/block} - - -{% -for (var a = 0; a < 100; a++) - print(a); -%} - - -{if i === 50} -{elseif i > 60} -{else} -{/if} - - -{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} - -{for item,index in items} 可选参数称 index - 可自定义名 {for item2, index99 in 数组表达式} - -{for key,item,index on json} 可选参数 item, index, - 可自定义名 {for key2, item2, index99 in 对象表达式} -{/for} - - -{miss} -此块内容不被bmw.js解析 -{/miss} - - - -``` \ No newline at end of file diff --git a/Docs/delete.md b/Docs/delete.md deleted file mode 100644 index 31c40d99..00000000 --- a/Docs/delete.md +++ /dev/null @@ -1,82 +0,0 @@ -# 删除数据 - -| 方法 | 返回值 | 参数 | 描述 | -| - | - | - | - | -| Where | \ | Lambda | 表达式条件,仅支持实体基础成员(不包含导航对象) | -| Where | \ | string, parms | 原生sql语法条件,Where("id = ?id", new { id = 1 }) | -| Where | \ | T1 \| IEnumerable | 传入实体或集合,将其主键作为条件 | -| WhereExists | \ | ISelect | 子查询是否存在 | -| ToSql | string | | 返回即将执行的SQL语句 | -| ExecuteAffrows | long | | 执行SQL语句,返回影响的行数 | -| ExecuteDeleted | List\ | | 执行SQL语句,返回被删除的记录 | - -### 测试代码 - -```csharp -IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .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") - .Build(); -IDelete delete => fsql.Delete(); - -[Table(Name = "tb_topic")] -class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } -} -``` - -### 动态条件 -```csharp -Delete(object dywhere) -``` -dywhere 支持 - -* 主键值 -* new[] { 主键值1, 主键值2 } -* Topic对象 -* new[] { Topic对象1, Topic对象2 } -* new { id = 1 } - -```csharp -var t1 = fsql.Delete(new[] { 1, 2 }).ToSql(); -//DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2) - -var t2 = fsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); -//DELETE FROM `tb_topic` WHERE (`Id` = 1) - -var t3 = fsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); -//DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2) - -var t4 = fsql.Delete(new { id = 1 }).ToSql(); -//DELETE FROM `tb_topic` WHERE (`Id` = 1) -``` - -### 删除条件 - -```csharp -var t5 = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); -//DELETE FROM `tb_topic` WHERE (`Id` = 1) - -var t6 = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); -//DELETE FROM `tb_topic` WHERE (id = ?id) - -var item = new Topic { Id = 1, Title = "newtitle" }; -var t7 = delete.Where(item).ToSql().Replace("\r\n", ""); -//DELETE FROM `tb_topic` WHERE (`Id` = 1) - -var items = new List(); -for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); -var t8 = delete.Where(items).ToSql().Replace("\r\n", ""); -//DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10)) -``` - -### 执行命令 - -| 方法 | 返回值 | 参数 | 描述 | -| - | - | - | - | -| ExecuteAffrows | long | | 执行SQL语句,返回影响的行数 | -| ExecuteDeleted | List\ | | 执行SQL语句,返回被删除的记录 | \ No newline at end of file diff --git a/Docs/expression.md b/Docs/expression.md deleted file mode 100644 index 9566aa3f..00000000 --- a/Docs/expression.md +++ /dev/null @@ -1,177 +0,0 @@ -# 表达式函数 -| 表达式 | MySql | SqlServer | PostgreSQL | Oracle | 功能说明 | -| - | - | - | - | - | - | -| a ? b : c | case when a then b else c end | case when a then b else c end | case when a then b else c end | case when a then b else c end | a成立时取b值,否则取c值 | -| a ?? b | ifnull(a, b) | isnull(a, b) | coalesce(a, b) | nvl(a, b) | 当a为null时,取b值 | -| 数字 + 数字 | a + b | a + b | a + b | a + b | 数字相加 | -| 数字 + 字符串 | concat(a, b) | cast(a as varchar) + cast(b as varchar) | case(a as varchar)\|\| b | a\|\| b | 字符串相加,a或b任意一个为字符串时 | -| a - b | a - b | a - b | a - b | a - b | 减 -| a * b | a * b | a * b | a * b | a * b | 乘 -| a / b | a / b | a / b | a / b | a / b | 除 -| a % b | a % b | a % b | a % b | mod(a,b) | 模 - -> 等等... - -### 数组 -| 表达式 | MySql | SqlServer | PostgreSQL | Oracle | 功能说明 | -| - | - | - | - | - | - | -| a.Length | - | - | case when a is null then 0 else array_length(a,1) end | - | 数组长度 | -| 常量数组.Length | - | - | array_length(array[常量数组元素逗号分割],1) | - | 数组长度 | -| a.Any() | - | - | case when a is null then 0 else array_length(a,1) end > 0 | - | 数组是否为空 | -| 常量数组.Contains(b) | b in (常量数组元素逗号分割) | b in (常量数组元素逗号分割) | b in (常量数组元素逗号分割) | b in (常量数组元素逗号分割) | IN查询 | -| a.Contains(b) | - | - | a @> array[b] | - | a数组是否包含b元素 | -| a.Concat(b) | - | - | a \|\| b | - | 数组相连 | -| a.Count() | - | - | 同 Length | - | 数组长度 | - -### 字典 Dictionary -| 表达式 | MySql | SqlServer | PostgreSQL | Oracle | 功能说明 | -| - | - | - | - | - | - | -| a.Count | - | - | case when a is null then 0 else array_length(akeys(a),1) end | - | 字典长度 | -| a.Keys | - | - | akeys(a) | - | 返回字典所有key数组 | -| a.Values | - | - | avals(a) | - | 返回字典所有value数组 | -| a.Contains(b) | - | - | a @> b | - | 字典是否包含b -| a.ContainsKey(b) | - | - | a? b | - | 字典是否包含key -| a.Concat(b) | - | - | a \|\| b | - | 字典相连 | -| a.Count() | - | - | 同 Count | - | 字典长度 | - -### JSON JToken/JObject/JArray -| 表达式 | MySql | SqlServer | PostgreSQL | Oracle | 功能说明 | -| - | - | - | - | - | - | -| a.Count | - | - | jsonb_array_length(coalesce(a, '[])) | - | json数组类型的长度 | -| a.Any() | - | - | jsonb_array_length(coalesce(a, '[])) > 0 | - | json数组类型,是否为空 | -| a.Contains(b) | - | - | coalesce(a, '{}') @> b::jsonb | - | json中是否包含b | -| a.ContainsKey(b) | - | - | coalesce(a, '{}') ? b | - | json中是否包含键b | -| a.Concat(b) | - | - | coalesce(a, '{}') || b::jsonb | - | 连接两个json | -| Parse(a) | - | - | a::jsonb | - | 转化字符串为json类型 | - -### 字符串对象 -| 表达式 | MySql | SqlServer | PostgreSQL | Oracle | 功能说明 | -| - | - | - | - | - | - | -| string.Empty | '' | '' | '' | 空字符串表示 | -| string.IsNullOrEmpty(a) | (a is null or a = '') | (a is null or a = '') | (a is null or a = '') | (a is null or a = '') | 空字符串表示 | -| a.CompareTo(b) | strcmp(a, b) | - | case when a = b then 0 when a > b then 1 else -1 end | case when a = b then 0 when a > b then 1 else -1 end | 比较a和b大小 | -| a.Contains('b') | a like '%b%' | a like '%b%' | a ilike'%b%' | a like '%b%' | a是否包含b | -| a.EndsWith('b') | a like '%b' | a like '%b' | a ilike'%b' | a like '%b' | a尾部是否包含b | -| a.IndexOf(b) | locate(a, b) - 1 | locate(a, b) - 1 | strpos(a, b) - 1 | instr(a, b, 1, 1) - 1 | 查找a中出现b的位置 | -| a.Length | char_length(a) | len(a) | char_length(a) | length(a) | 返回a的字符串长度 | -| a.PadLeft(b, c) | lpad(a, b, c) | - | lpad(a, b, c) | lpad(a, b, c) | 在a的左侧充字符c,直到字符串长度大于b | -| a.PadRight(b, c) | rpad(a, b, c) | - | rpad(a, b, c) | rpad(a, b, c) | 在a的右侧充字符c,直到字符串长度大于b | -| a.Replace(b, c) | replace(a, b, c) | replace(a, b, c) | replace(a, b, c) | replace(a, b, c) | 将a中字符串b,替换成c | -| a.StartsWith('b') | a like 'b%' | a like 'b%' | a ilike'b%' | a like 'b%' | a头部是否包含b | -| a.Substring(b, c) | substr(a, b, c + 1) | substring(a, b, c + 1) | substr(a, b, c + 1) | substr(a, b, c + 1) | 截取a中位置b到c的内容 | -| a.ToLower | lower(a) | lower(a) | lower(a) | lower(a) | 转小写 | -| a.ToUpper | upper(a) | upper(a) | upper(a) | upper(a) | 转大写 | -| a.Trim | trim(a) | trim(a) | trim(a) | trim(a) | 移除两边字符 | -| a.TrimEnd | rtrim(a) | rtrim(a) | rtrim(a) | rtrim(a) | 移除左侧指定字符 | -| a.TrimStart | ltrim(a) | ltrim(a) | ltrim(a) | ltrim(a) | 移除右侧指定字符 | - -### 日期对象 -| 表达式 | MySql | SqlServer | PostgreSQL | Oracle | -| - | - | - | - | - | -| DateTime.Now | now() | getdate() | current_timestamp | systimestamp | -| DateTime.UtcNow | utc_timestamp() | getutcdate() | (current_timestamp at time zone 'UTC') | sys_extract_utc(systimestamp) | -| DateTime.Today | curdate | convert(char(10),getdate(),120) | current_date | trunc(systimestamp) | -| DateTime.MaxValue | cast('9999/12/31 23:59:59' as datetime) | '9999/12/31 23:59:59' | '9999/12/31 23:59:59'::timestamp | to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6') | -| DateTime.MinValue | cast('0001/1/1 0:00:00' as datetime) | '1753/1/1 0:00:00' | '0001/1/1 0:00:00'::timestamp | to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6') | -| DateTime.Compare(a, b) | a - b | a - b | extract(epoch from a::timestamp-b::timestamp) | extract(day from (a-b)) | -| DateTime.DaysInMonth(a, b) | dayofmonth(last_day(concat(a, '-', b, '-1'))) | datepart(day, dateadd(day, -1, dateadd(month, 1, cast(a as varchar) + '-' + cast(b as varchar) + '-1'))) | extract(day from (a || '-' || b || '-01')::timestamp+'1 month'::interval-'1 day'::interval) | cast(to_char(last_day(a||'-'||b||'-01'),'DD') as number) | -| DateTime.Equals(a, b) | a = b | a = b | a = b | a = b | -| DateTime.IsLeapYear(a) | a%4=0 and a%100<>0 or a%400=0 | a%4=0 and a%100<>0 or a%400=0 | a%4=0 and a%100<>0 or a%400=0 | mod(a,4)=0 AND mod(a,100)<>0 OR mod(a,400)=0 | -| DateTime.Parse(a) | cast(a as datetime) | cast(a as datetime) | a::timestamp | to_timestamp(a,'YYYY-MM-DD HH24:MI:SS.FF6') | -| a.Add(b) | date_add(a, interval b microsecond) | dateadd(millisecond, b / 1000, a) | a::timestamp+(b||' microseconds')::interval | 增加TimeSpan值 | a + b | -| a.AddDays(b) | date_add(a, interval b day) | dateadd(day, b, a) | a::timestamp+(b||' day')::interval | a + b | -| a.AddHours(b) | date_add(a, interval b hour) | dateadd(hour, b, a) | a::timestamp+(b||' hour')::interval | a + b/24 | -| a.AddMilliseconds(b) | date_add(a, interval b*1000 microsecond) | dateadd(millisecond, b, a) | a::timestamp+(b||' milliseconds')::interval | a + b/86400000 | -| a.AddMinutes(b) | date_add(a, interval b minute) | dateadd(minute, b, a) | a::timestamp+(b||' minute')::interval | a + b/1440 | -| a.AddMonths(b) | date_add(a, interval b month) | dateadd(month, b, a) | a::timestamp+(b||' month')::interval | add_months(a,b) | -| a.AddSeconds(b) | date_add(a, interval b second) | dateadd(second, b, a) | a::timestamp+(b||' second')::interval | a + b/86400 | -| a.AddTicks(b) | date_add(a, interval b/10 microsecond) | dateadd(millisecond, b / 10000, a) | a::timestamp+(b||' microseconds')::interval | a + b/86400000000 | -| a.AddYears(b) | date_add(a, interval b year) | dateadd(year, b, a) | a::timestamp+(b||' year')::interval | add_months(a,b*12) | -| a.Date | cast(date_format(a, '%Y-%m-%d') as datetime) | convert(char(10),a,120) | a::date | trunc(a) | -| a.Day | dayofmonth(a) | datepart(day, a) | extract(day from a::timestamp) | cast(to_char(a,'DD') as number) | -| a.DayOfWeek | dayofweek(a) | datepart(weekday, a) - 1 | extract(dow from a::timestamp) | case when to_char(a)='7' then 0 else cast(to_char(a) as number) end | -| a.DayOfYear | dayofyear(a) | datepart(dayofyear, a) | extract(doy from a::timestamp) | cast(to_char(a,'DDD') as number) | -| a.Hour | hour(a) | datepart(hour, a) | extract(hour from a::timestamp) | cast(to_char(a,'HH24') as number) | -| a.Millisecond | floor(microsecond(a) / 1000) | datepart(millisecond, a) | extract(milliseconds from a::timestamp)-extract(second from a::timestamp)*1000 | cast(to_char(a,'FF3') as number) | -| a.Minute | minute(a) | datepart(minute, a) | extract(minute from a::timestamp) | cast(to_char(a,'MI') as number) | -| a.Month | month(a) | datepart(month, a) | extract(month from a::timestamp) | cast(to_char(a,'FF3') as number) | -| a.Second | second(a) | datepart(second, a) | extract(second from a::timestamp) | cast(to_char(a,'SS') as number) | -| a.Subtract(b) | timestampdiff(microsecond, b, a) | datediff(millisecond, b, a) * 1000 | (extract(epoch from a::timestamp-b::timestamp)*1000000) | a - b | -| a.Ticks | timestampdiff(microsecond, '0001-1-1', a) * 10 | datediff(millisecond, '1970-1-1', a) * 10000 + 621355968000000000 | extract(epoch from a::timestamp)*10000000+621355968000000000 | cast(to_char(a,'FF7') as number) | -| a.TimeOfDay | timestampdiff(microsecond, date_format(a, '%Y-%m-%d'), a) | '1970-1-1 ' + convert(varchar, a, 14) | extract(epoch from a::time)*1000000 | a - trunc(a) | -| a.Year | year(a) | datepart(year, a) | extract(year from a::timestamp) | 年 | cast(to_char(a,'YYYY') as number) | -| a.Equals(b) | a = b | a = b | a = b | a = b | -| a.CompareTo(b) | a - b | a - b | a - b | a - b | -| a.ToString() | date_format(a, '%Y-%m-%d %H:%i:%s.%f') | convert(varchar, a, 121) | to_char(a, 'YYYY-MM-DD HH24:MI:SS.US') | to_char(a,'YYYY-MM-DD HH24:MI:SS.FF6') | - -### 时间对象 -| 表达式 | MySql(微秒) | SqlServer(秒) | PostgreSQL(微秒) | Oracle(Interval day(9) to second(7)) | -| - | - | - | - | - | -| TimeSpan.Zero | 0 | 0 | - | 0微秒 | numtodsinterval(0,'second') | -| TimeSpan.MaxValue | 922337203685477580 | 922337203685477580 | - | numtodsinterval(233720368.5477580,'second') | -| TimeSpan.MinValue | -922337203685477580 | -922337203685477580 | - | numtodsinterval(-233720368.5477580,'second') | -| TimeSpan.Compare(a, b) | a - b | a - b | - | extract(day from (a-b)) | -| TimeSpan.Equals(a, b) | a = b | a = b | - | a = b | -| TimeSpan.FromDays(a) | a * 1000000 * 60 * 60 * 24 | a * 1000000 * 60 * 60 * 24 | - | numtodsinterval(a*86400,'second') | -| TimeSpan.FromHours(a) | a * 1000000 * 60 * 60 | a * 1000000 * 60 * 60 | - | numtodsinterval(a*3600,'second') | -| TimeSpan.FromMilliseconds(a) | a * 1000 | a * 1000 | - | numtodsinterval(a/1000,'second') | -| TimeSpan.FromMinutes(a) | a * 1000000 * 60 | a * 1000000 * 60 | - | numtodsinterval(a*60,'second') | -| TimeSpan.FromSeconds(a) | a * 1000000 | a * 1000000 | - | numtodsinterval(a,'second') | -| TimeSpan.FromTicks(a) | a / 10 | a / 10 | - | numtodsinterval(a/10000000,'second') | -| a.Add(b) | a + b | a + b | - | a + b | -| a.Subtract(b) | a - b | a - b | - | a - b | -| a.CompareTo(b) | a - b | a - b | - | extract(day from (a-b)) | -| a.Days | a div (1000000 * 60 * 60 * 24) | a div (1000000 * 60 * 60 * 24) | - | extract(day from a) | -| a.Hours | a div (1000000 * 60 * 60) mod 24 | a div (1000000 * 60 * 60) mod 24 | - | extract(hour from a) | -| a.Milliseconds | a div 1000 mod 1000 | a div 1000 mod 1000 | - | cast(substr(extract(second from a)-floor(extract(second from a)),2,3) as number) | -| a.Seconds | a div 1000000 mod 60 | a div 1000000 mod 60 | - | extract(second from a) | -| a.Ticks | a * 10 | a * 10 | - | (extract(day from a)*86400+extract(hour from a)*3600+extract(minute from a)*60+extract(second from a))*10000000 | -| a.TotalDays | a / (1000000 * 60 * 60 * 24) | a / (1000000 * 60 * 60 * 24) | - | extract(day from a) | -| a.TotalHours | a / (1000000 * 60 * 60) | a / (1000000 * 60 * 60) | - | (extract(day from a)*24+extract(hour from a)) | -| a.TotalMilliseconds | a / 1000 | a / 1000 | - | (extract(day from a)*86400+extract(hour from a)*3600+extract(minute from a)*60+extract(second from a))*1000 | -| a.TotalMinutes | a / (1000000 * 60) | a / (1000000 * 60) | - | | (extract(day from a)*1440+extract(hour from a)*60+extract(minute from a)) | -| a.TotalSeconds | a / 1000000 | a / 1000000 | - | (extract(day from a)*86400+extract(hour from a)*3600+extract(minute from a)*60+extract(second from a)) | -| a.Equals(b) | a = b | a = b | - | a = b | -| a.ToString() | cast(a as varchar) | cast(a as varchar) | - | to_char(a) | - -### 数学函数 -| 表达式 | MySql | SqlServer | PostgreSQL | Oracle | -| - | - | - | - | - | -| Math.Abs(a) | abs(a) | abs(a) | abs(a) | -| Math.Acos(a) | acos(a) | acos(a) | acos(a) | acos(a) | -| Math.Asin(a) | asin(a) | asin(a) | asin(a) | asin(a) | -| Math.Atan(a) | atan(a) | atan(a) | atan(a) | atan(a) | -| Math.Atan2(a, b) | atan2(a, b) | atan2(a, b) | atan2(a, b) | - | -| Math.Ceiling(a) | ceiling(a) | ceiling(a) | ceiling(a) | ceil(a) | -| Math.Cos(a) | cos(a) | cos(a) | cos(a) | cos(a) | -| Math.Exp(a) | exp(a) | exp(a) | exp(a) | exp(a) | -| Math.Floor(a) | floor(a) | floor(a) | floor(a) | floor(a) | -| Math.Log(a) | log(a) | log(a) | log(a) | log(e,a) | -| Math.Log10(a) | log10(a) | log10(a) | log10(a) | log(10,a) | -| Math.PI(a) | 3.1415926535897931 | 3.1415926535897931 | 3.1415926535897931 | 3.1415926535897931 | -| Math.Pow(a, b) | pow(a, b) | power(a, b) | pow(a, b) | power(a, b) | -| Math.Round(a, b) | round(a, b) | round(a, b) | round(a, b) | round(a, b) | -| Math.Sign(a) | sign(a) | sign(a) | sign(a) | sign(a) | -| Math.Sin(a) | sin(a) | sin(a) | sin(a) | sin(a) | -| Math.Sqrt(a) | sqrt(a) | sqrt(a) | sqrt(a) | sqrt(a) | -| Math.Tan(a) | tan(a) | tan(a) | tan(a) | tan(a) | -| Math.Truncate(a) | truncate(a, 0) | floor(a) | trunc(a, 0) | trunc(a, 0) | - -### 类型转换 -| 表达式 | MySql | SqlServer | PostgreSQL | Oracle | -| - | - | - | - | - | -| Convert.ToBoolean(a) | a not in ('0','false') | a not in ('0','false') | a::varchar not in ('0','false','f','no') | - | -| Convert.ToByte(a) | cast(a as unsigned) | cast(a as tinyint) | a::int2 | cast(a as number) | -| Convert.ToChar(a) | substr(cast(a as char),1,1) | substring(cast(a as nvarchar),1,1) | substr(a::char,1,1) | substr(to_char(a),1,1) | -| Convert.ToDateTime(a) | cast(a as datetime) | cast(a as datetime) | a::timestamp | to_timestamp(a,'YYYY-MM-DD HH24:MI:SS.FF6') | -| Convert.ToDecimal(a) | cast(a as decimal(36,18)) | cast(a as decimal(36,19)) | a::numeric | cast(a as number) | -| Convert.ToDouble(a) | cast(a as decimal(32,16)) | cast(a as decimal(32,16)) | a::float8 | cast(a as number) | -| Convert.ToInt16(a) | cast(a as signed) | cast(a as smallint) | a::int2 | cast(a as number) | -| Convert.ToInt32(a) | cast(a as signed) | cast(a as int) | a::int4 | cast(a as number) | -| Convert.ToInt64(a) | cast(a as signed) | cast(a as bigint) | a::int8 | cast(a as number) | -| Convert.ToSByte(a) | cast(a as signed) | cast(a as tinyint) | a::int2 | cast(a as number) | -| Convert.ToString(a) | cast(a as decimal(14,7)) | cast(a as decimal(14,7)) | a::float4 | to_char(a) | -| Convert.ToSingle(a) | cast(a as char) | cast(a as nvarchar) | a::varchar | cast(a as number) | -| Convert.ToUInt16(a) | cast(a as unsigned) | cast(a as smallint) | a::int2 | cast(a as number) | -| Convert.ToUInt32(a) | cast(a as unsigned) | cast(a as int) | a::int4 | cast(a as number) | -| Convert.ToUInt64(a) | cast(a as unsigned) | cast(a as bigint) | a::int8 | cast(a as number) | diff --git a/Docs/generator.md b/Docs/generator.md deleted file mode 100644 index 66b01ceb..00000000 --- a/Docs/generator.md +++ /dev/null @@ -1,103 +0,0 @@ -# 生成器 - -生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: - -| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | -| ------------- | - | - |- | - |- | - | -| simple-entity | √ | X | X | √ | X | X | -| simple-entity-navigation-object | √ | √ | X | √ | X | X | -| rich-entity-navigation-object | √ | √ | √ | X | √ | X | - -模板在项目目录:/Templates/MySql - -> 更多模板逐步开发中。。。 - -```csharp -//定义 mysql FreeSql -IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .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") - .UseAutoSyncStructure(true) - - .UseMonitorCommand( - cmd => { - Console.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build(); - -//创建模板生成类实现 -var gen = new FreeSql.Generator.TemplateGenerator(); -gen.Build(mysql.DbFirst, - @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) - @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 - "cccddd" //数据库 -); -``` - -## 模板语法 - -```html - - -{#title} - - - - -{#表达式} -{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 - - -{include ../header.html} -
-

aaa

-

bbb {#i}

-

ccc {#i}

-
- - -{module module_name1 parms1, 2, 3...} -{/module} -{module module_name2 parms1, 2, 3...} -{/module} - - -{import ../module.html as myname} -{#myname.module_name(parms1, 2, 3...)} - - -{extends ../inc/layout.html} -{block body}{/block} - - -{% -for (var a = 0; a < 100; a++) - print(a); -%} - - -{if i === 50} -{elseif i > 60} -{else} -{/if} - - -{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} - -{for item,index in items} 可选参数称 index - 可自定义名 {for item2, index99 in 数组表达式} - -{for key,item,index on json} 可选参数 item, index, - 可自定义名 {for key2, item2, index99 in 对象表达式} -{/for} - - -{miss} -此块内容不被bmw.js解析 -{/miss} - - - -``` \ No newline at end of file diff --git a/Docs/insert.md b/Docs/insert.md deleted file mode 100644 index c84c5e02..00000000 --- a/Docs/insert.md +++ /dev/null @@ -1,79 +0,0 @@ -# 插入数据 - -| 方法 | 返回值 | 参数 | 描述 | -| - | - | - | - | -| AppendData | \ | T1 \| IEnumerable | 追加准备插入的实体 | -| InsertColumns | \ | Lambda | 只插入的列 | -| IgnoreColumns | \ | Lambda | 忽略的列 | -| ToSql | string | | 返回即将执行的SQL语句 | -| ExecuteAffrows | long | | 执行SQL语句,返回影响的行数 | -| ExecuteIdentity | long | | 执行SQL语句,返回自增值 | -| ExecuteInserted | List\ | | 执行SQL语句,返回插入后的记录 | - -### 列优先级 - -> 全部列 < 指定列(InsertColumns) < 忽略列(IgnoreColumns) - -### 测试代码 - -```csharp -IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .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") - .Build(); -IInsert insert => fsql.Insert(); - -[Table(Name = "tb_topic")] -class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } -} - -var items = new List(); -for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); -``` - -### 插入 - -```csharp -var t1 = insert.AppendData(items.First()).ToSql(); -//INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks0, ?Title0, ?CreateTime0) -``` - -### 批量插入 - -```csharp -var t2 = insert.AppendData(items).ToSql(); -//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) -``` - -### 只想插入指定的列 - -```csharp -var t3 = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); -//INSERT INTO `tb_topic`(`Title`) VALUES(?Title0), (?Title1), (?Title2), (?Title3), (?Title4), (?Title5), (?Title6), (?Title7), (?Title8), (?Title9) - -var t4 = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); -//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) -``` - -### 忽略列 - -```csharp -var t5 = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); -//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) - -var t6 = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); -///INSERT INTO `tb_topic`(`Clicks`) VALUES(?Clicks0), (?Clicks1), (?Clicks2), (?Clicks3), (?Clicks4), (?Clicks5), (?Clicks6), (?Clicks7), (?Clicks8), (?Clicks9) -``` - -### 执行命令 - -| 方法 | 返回值 | 描述 | -| - | - | - | -| ExecuteAffrows | long | 执行SQL语句,返回影响的行数 | -| ExecuteIdentity | long | 执行SQL语句,返回自增值 | -| ExecuteInserted | List\ | 执行SQL语句,返回插入后的记录 | diff --git a/Docs/select.md b/Docs/select.md deleted file mode 100644 index ccf443c0..00000000 --- a/Docs/select.md +++ /dev/null @@ -1,259 +0,0 @@ -# 查询数据 - -## 测试代码 - -```csharp -IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .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") - .Build(); -ISelect select => fsql.Select(); - -[Table(Name = "tb_topic")] -class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public int TestTypeInfoGuid { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } -} -class TestTypeInfo { - public int Guid { get; set; } - public int ParentId { get; set; } - public TestTypeParentInfo Parent { get; set; } - public string Name { get; set; } -} -class TestTypeParentInfo { - public int Id { get; set; } - public string Name { get; set; } - - public List Types { get; set; } -} -``` - -# Where - -### 单表 -```csharp -var sql = select.Where(a => a.Id == 10).ToSql(); -///SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) - -sql = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100).ToSql(); -///SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100) - -sql = select.Where(a => new []{1,2,3}.Contains(a.Id)).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` in (1,2,3)) -``` -> [《Expression 表达式函数文档》](Docs/expression.md) - -### 多表,使用导航属性 -```csharp -sql = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid).ToSql(); -///SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TestTypeInfoGuid`) - -sql = select.Where(a => a.Type.Parent.Name == "tparent").ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` a__Type, `TestTypeParentInfo` a__Type__Parent WHERE (a__Type__Parent.`Name` = 'tparent') -``` - -### 多表,没有导航属性 -```csharp -sql = select.Where((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "typeTitle").ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'typeTitle') - -sql = select.Where((a, b, c) => c.Name == "tparent").ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent') -``` - -### 多表,任意查 -```csharp -sql = select.From((s, b, c) => s - .Where(a => a.Id == 10 && c.Name == "xxx") - .Where(a => b.ParentId == 20)).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c, `TestTypeInfo` b WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20) -``` - -### 子表 Exists 查询 -```csharp -var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); -// SELECT a.`Id`, a.`TypeGuid`, a.`Title`, a.`CreateTime` -// FROM `xxx` a -// WHERE (exists(SELECT 1 -// FROM `xxx` b -// WHERE (b.`Id` = a.`Id`))) - -//两级相同的子表查询 -sql2222 = select.Where(a => - select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) - .Offset(a.Id) - .Any() - ).Any() -).ToList(); -// SELECT a.`Id`, a.`TypeGuid`, a.`Title`, a.`CreateTime` -// FROM `xxx` a -// WHERE (exists(SELECT 1 -// FROM `xxx` b -// WHERE (b.`Id` = a.`Id` AND exists(SELECT 1 -// FROM `xxx` c -// WHERE (c.`Id` = b.`Id`) AND (c.`Id` = a.`Id`) AND (c.`Id` = b.`Id`) -// limit 0,1)) -// limit 0,1)) -``` - -### 原生SQL -```csharp -sql = select.Where("a.clicks > 100 && a.id = ?id", new { id = 10 }).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 && a.id = ?id) -``` - -> 以上条件查询,支持 WhereIf - -# 联表 - -### 使用导航属性联表 -```csharp -sql = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` - -sql = select - .LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid) - .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` -``` - -### 没有导航属性联表 -```csharp -sql = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` - -sql = select - .LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid) - .LeftJoin((a, c) => c.Id == a.Type.ParentId).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = b.`ParentId` -``` - -### 联表任意查 -```csharp -sql = select.From((s, b, c) => s - .LeftJoin(a => a.TestTypeInfoGuid == b.Guid) - .LeftJoin(a => b.ParentId == c.Id)).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id` -``` - -### 原生SQL联表 -```csharp -sql = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", new { bname = "xxx" }).ToSql(); -//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname -``` - -# 查询数据 - -### 返回 List -```csharp -List t1 = select.Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); -``` - -### 返回 List + 导航属性的数据 -```csharp -List t2 = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid).ToList(); -//此时会返回普通字段 + 导航对象 Type 的数据 -``` - -### 指定字段返回 -```csharp -//返回一个字段 -List t3 = select.Where(a => a.Id > 0).Skip(100).Limit(200).ToList(a => a.Id); - -//返回匿名类 -List<匿名类> t4 = select.Where(a => a.Id > 0).Skip(100).Limit(200).ToList(a => new { a.Id, a.Title }); - -//返回元组 -List<(int, string)> t5 = select.Where(a => a.Id > 0).Skip(100).Limit(200).ToList<(int, string)>("id, title"); - -//返回SQL字段 -List<匿名类> t4 = select.Where(a => a.Id > 0).Skip(100).Limit(200) - .ToList(a => new { - a.Id, - a.Title, - cstitle = "substr(a.title, 0, 2)", //将 substr(a.title, 0, 2) 作为查询字段 - csnow = Convert.ToDateTime("now()"), //将 now() 作为查询字段 - //奇思妙想:怎么查询开窗函数的结果 - }); -``` - -### 执行SQL返回数据 -```csharp -class xxx { - public int Id { get; set; } - public string Path { get; set; } - public string Title2 { get; set; } -} - -List t6 = fsql.Ado.Query("select * from song"); -List<(int, string ,string)> t7 = fsql.Ado.Query<(int, string, string)>("select * from song"); -List t8 = fsql.Ado.Query("select * from song"); -``` - -### 分组聚合 -```csharp -var groupby = fsql.Select() - .GroupBy(a => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) - .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) - .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) - .OrderBy(a => a.Key.tt2) - .OrderByDescending(a => a.Count()) - .ToList(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4) }); -//SELECT substr(a.`Title`, 1, 2) as1, count(1) as2, avg((a.`Id` % 4)) as3 -//FROM `xxx` a -//GROUP BY substr(a.`Title`, 1, 2), (a.`Id` % 4) -//HAVING (count(1) > 0 AND avg((a.`Id` % 4)) > 0 AND max((a.`Id` % 4)) > 0) AND (count(1) < 300 OR avg((a.`Id` % 4)) < 100) -//ORDER BY substr(a.`Title`, 1, 2), count(1) DESC -``` - -# 更多文档整理中。。。 - -| 方法 | 返回值 | 参数 | 描述 | -| ------------- | - | - | - | -| ToSql | string | | 返回即将执行的SQL语句 | -| ToList | List | | 执行SQL查询,返回 T1 实体所有字段的记录,若存在导航属性则一起查询返回,记录不存在时返回 Count 为 0 的列表 | -| ToList\ | List\ | Lambda | 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 | -| ToList\ | List\ | string field | 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 | -| ToOne | T1 | | 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null | -| Any | bool | | 执行SQL查询,是否有记录 | -| Sum | T | Lambda | 指定一个列求和 | -| Min | T | Lambda | 指定一个列求最小值 | -| Max | T | Lambda | 指定一个列求最大值 | -| Avg | T | Lambda | 指定一个列求平均值 | -| 【分页】 | -| Count | long | | 查询的记录数量 | -| Count | \ | out long | 查询的记录数量,以参数out形式返回 | -| Skip | \ | int offset | 查询向后偏移行数 | -| Offset | \ | int offset | 查询向后偏移行数 | -| Limit | \ | int limit | 查询多少条数据 | -| Take | \ | int limit | 查询多少条数据 | -| Page | \ | int pageIndex, int pageSize | 分页 | -| 【条件】 | -| Where | \ | Lambda | 支持多表查询表达式 | -| WhereIf | \ | bool, Lambda | 支持多表查询表达式 | -| Where | \ | string, parms | 原生sql语法条件,Where("id = ?id", new { id = 1 }) | -| WhereIf | \ | bool, string, parms | 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) | -| 【分组】 | -| GroupBy | \ | Lambda | 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) | -| GroupBy | \ | string, parms | 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) | -| Having | \ | string, parms | 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) | -| 【排序】 | -| OrderBy | \ | Lambda | 按列排序,OrderBy(a => a.Time) | -| OrderByDescending | \ | Lambda | 按列倒向排序,OrderByDescending(a => a.Time) | -| OrderBy | \ | string, parms | 按原生sql语法排序,OrderBy("count(name) + ?cc", new { cc = 1 }) | -| 【联表】 | -| LeftJoin | \ | Lambda | 左联查询,可使用导航属性,或指定关联的实体类型 | -| InnerJoin | \ | Lambda | 联接查询,可使用导航属性,或指定关联的实体类型 | -| RightJoin | \ | Lambda | 右联查询,可使用导航属性,或指定关联的实体类型 | -| LeftJoin | \ | string, parms | 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) | -| InnerJoin | \ | string, parms | 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) | -| RightJoin | \ | string, parms | 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) | -| From | \ | Lambda | 多表查询,3个表以上使用非常方便,目前设计最大支持10个表 | -| 【其他】 | -| As | \ | string alias = "a" | 指定别名 | -| Master | \ | | 指定从主库查询(默认查询从库) | -| Caching | \ | int seconds, string key = null | 缓存查询结果 | \ No newline at end of file diff --git a/Docs/update.md b/Docs/update.md deleted file mode 100644 index dfe3bf0a..00000000 --- a/Docs/update.md +++ /dev/null @@ -1,129 +0,0 @@ -# 更新数据 - -| 方法 | 返回值 | 参数 | 描述 | -| - | - | - | - | -| SetSource | \ | T1 \| IEnumerable | 更新数据,设置更新的实体 | -| IgnoreColumns | \ | Lambda | 忽略的列 | -| Set | \ | Lambda, value | 设置列的新值,Set(a => a.Name, "newvalue") | -| Set | \ | Lambda | 设置列的的新值为基础上增加,Set(a => a.Clicks + 1),相当于 clicks=clicks+1; | -| SetRaw | \ | string, parms | 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) | -| Where | \ | Lambda | 表达式条件,仅支持实体基础成员(不包含导航对象) | -| Where | \ | string, parms | 原生sql语法条件,Where("id = ?id", new { id = 1 }) | -| Where | \ | T1 \| IEnumerable | 传入实体或集合,将其主键作为条件 | -| WhereExists | \ | ISelect | 子查询是否存在 | -| ToSql | string | | 返回即将执行的SQL语句 | -| ExecuteAffrows | long | | 执行SQL语句,返回影响的行数 | -| ExecuteUpdated | List\ | | 执行SQL语句,返回更新后的记录 | - -### 列优先级 - -> 全部列 < 指定列(Set/SetRaw) < 忽略列(IgnoreColumns) - -### 测试代码 - -```csharp -[Table(Name = "tb_topic")] -class Topic { - [Column(IsIdentity = true, IsPrimary = true)] - public int Id { get; set; } - public int Clicks { get; set; } - public TestTypeInfo Type { get; set; } - public string Title { get; set; } - public DateTime CreateTime { get; set; } -} - -IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .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") - .Build(); -IUpdate update => fsql.Update(); -``` - -### 动态条件 -```csharp -Update(object dywhere) -``` -dywhere 支持 - -* 主键值 -* new[] { 主键值1, 主键值2 } -* Topic对象 -* new[] { Topic对象1, Topic对象2 } -* new { id = 1 } - -### 更新指定列 -```csharp -var t1 = fsql.Update(1).Set(a => a.CreateTime, DateTime.Now).ToSql(); -//UPDATE `tb_topic` SET `CreateTime` = '2018-12-08 00:04:59' WHERE (`Id` = 1) -``` - -### 更新指定列,累加 -```csharp -var t2 = fsql.Update(1).Set(a => a.Clicks + 1).ToSql(); -//UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`,0) + 1 WHERE (`Id` = 1) -``` - -### 保存实体 -```csharp -var item = new Topic { Id = 1, Title = "newtitle" }; -var t3 = update.SetSource(item).ToSql(); -//UPDATE `tb_topic` SET `Clicks` = ?p_0, `Title` = ?p_1, `CreateTime` = ?p_2 WHERE (`Id` = 1) -``` - -### 保存实体,忽略一些列 -```csharp -var t4 = update.SetSource(item).IgnoreColumns(a => a.Clicks).ToSql(); -//UPDATE `tb_topic` SET `Title` = ?p_0, `CreateTime` = ?p_1 WHERE (`Id` = 1) -var t5 = update.SetSource(item).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql(); -//UPDATE `tb_topic` SET `Title` = ?p_0 WHERE (`Id` = 1) -``` - -### 批量保存 -```csharp -var items = new List(); -for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); - -var t6 = update.SetSource(items).ToSql(); -//UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN ?p_0 WHEN 2 THEN ?p_1 WHEN 3 THEN ?p_2 WHEN 4 THEN ?p_3 WHEN 5 THEN ?p_4 WHEN 6 THEN ?p_5 WHEN 7 THEN ?p_6 WHEN 8 THEN ?p_7 WHEN 9 THEN ?p_8 WHEN 10 THEN ?p_9 END, `Title` = CASE `Id` WHEN 1 THEN ?p_10 WHEN 2 THEN ?p_11 WHEN 3 THEN ?p_12 WHEN 4 THEN ?p_13 WHEN 5 THEN ?p_14 WHEN 6 THEN ?p_15 WHEN 7 THEN ?p_16 WHEN 8 THEN ?p_17 WHEN 9 THEN ?p_18 WHEN 10 THEN ?p_19 END, `CreateTime` = CASE `Id` WHEN 1 THEN ?p_20 WHEN 2 THEN ?p_21 WHEN 3 THEN ?p_22 WHEN 4 THEN ?p_23 WHEN 5 THEN ?p_24 WHEN 6 THEN ?p_25 WHEN 7 THEN ?p_26 WHEN 8 THEN ?p_27 WHEN 9 THEN ?p_28 WHEN 10 THEN ?p_29 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10)) -``` - -> 批量保存的场景,先查询20条记录,根据本地很复杂的规则把集合的值改完后 - -> 传统做法是循环20次保存,用 case when 只要一次就行 - -### 批量保存,忽略一些列 -```csharp -var t7 = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql(); -//UPDATE `tb_topic` SET `Title` = CASE `Id` WHEN 1 THEN ?p_0 WHEN 2 THEN ?p_1 WHEN 3 THEN ?p_2 WHEN 4 THEN ?p_3 WHEN 5 THEN ?p_4 WHEN 6 THEN ?p_5 WHEN 7 THEN ?p_6 WHEN 8 THEN ?p_7 WHEN 9 THEN ?p_8 WHEN 10 THEN ?p_9 END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10)) -``` - -### 批量更新指定列 -```csharp -var t8 = update.SetSource(items).Set(a => a.CreateTime, DateTime.Now).ToSql(); -//UPDATE `tb_topic` SET `CreateTime` = ?p_0 WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10)) -``` - -> 指定列更新后,批量保存将失效 - -### 更新条件 - -> 除了顶上介绍的 dywhere 构造参数外,还支持 Where lambda/sql 方法 - -```csharp -var t9 = update.Set(a => a.Title, "新标题").Where(a => a.Id == 1).ToSql(); -//UPDATE `tb_topic` SET `Title` = '新标题' WHERE (Id = 1) -``` - -### 自定义SQL - -```csharp -var t10 = update.SetRaw("Title = {0}", "新标题").Where("Id = {0}", 1).ToSql(); -//UPDATE `tb_topic` SET Title = '新标题' WHERE (Id = 1) -//sql语法条件,参数使用 {0},与 string.Format 保持一致,无须加单引号,错误的用法:'{0}' -``` - -### 执行命令 - -| 方法 | 返回值 | 参数 | 描述 | -| - | - | - | - | -| ExecuteAffrows | long | | 执行SQL语句,返回影响的行数 | -| ExecuteUpdated | List\ | | 执行SQL语句,返回更新后的记录 | \ No newline at end of file diff --git a/FreeSql.DbContext/readme.md b/FreeSql.DbContext/readme.md index beee15e9..ac006f8d 100644 --- a/FreeSql.DbContext/readme.md +++ b/FreeSql.DbContext/readme.md @@ -1,284 +1,216 @@ -这是 [FreeSql](https://github.com/2881099/FreeSql) 衍生出来的扩展包,包含 DbContext & DbSet、Repository & UnitOfWork 实现面向对象的特性(QQ群:4336577)。 +FreeSql.DbContext 实现类似 EFCore 使用习惯,跟踪对象状态,最终通过 SaveChanges 方法提交事务。 + +## 安装 > dotnet add package FreeSql.DbContext -## 更新日志 +## 如何使用 -### v0.6.5 - -- 修复 Repository 级联保存的 bug; -- 添加工作单元开启方法; -- 适配 .net framework 4.5、netstandard 2.0; - -### v0.6.1 - -- 拆分 FreeSql 小包引用,各数据库单独包、延时加载包; -- FreeSql.Extensions.LazyLoading -- FreeSql.Provider.MySql -- FreeSql.Provider.PostgreSQL -- FreeSql.Provider.SqlServer -- FreeSql.Provider.Sqlite -- FreeSql.Provider.Oracle -- 移除 IFreeSql.Cache,以及 ISelect.Caching 方法; -- 移除 IFreeSql.Log,包括内部原有的日志输出,改为 Trace.WriteLine; -- IAdo.Query\ 读取返回变为 List\\>; -- 定义 IFreeSql 和以前一样,移除了 UseCache、UseLogger 方法; - -## DbContext & DbSet - -```csharp -using (var ctx = new SongContext()) { - var song = new Song { BigNumber = "1000000000000000000" }; - ctx.Songs.Add(song); - - song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); - ctx.Songs.Update(song); - - var tag = new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } - } - }; - ctx.Tags.Add(tag); +0、通用方法,为啥是0??? +``` +using (var ctx = fsql.CreateDbContext()) { + //var db1 = ctx.Set(); + //var db2 = ctx.Set(); + var item = new Song { }; + ctx.Add(item); ctx.SaveChanges(); } ``` -## Repository & UnitOfWork +> 注意:DbContext 对象多线程不安全 -仓储与工作单元一起使用,工作单元具有事务特点。 +1、在 OnConfiguring 方法上配置与 IFreeSql 关联 ```csharp -using (var unitOfWork = fsql.CreateUnitOfWork()) { - var songRepository = unitOfWork.GetRepository(); - var tagRepository = unitOfWork.GetRepository(); +public class SongContext : DbContext { - var song = new Song { BigNumber = "1000000000000000000" }; - songRepository.Insert(song); + public DbSet Songs { get; set; } + public DbSet Tags { get; set; } - songRepository.Update(song); - - song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); - songRepository.Update(song); - - var tag = new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } - } - }; - tagRepository.Insert(tag); - - ctx.Commit(); + protected override void OnConfiguring(DbContextOptionsBuilder builder) { + builder.UseFreeSql(dbcontext_01.Startup.Fsql); + } } -``` -## Repository - -简单使用仓储,有状态跟踪,它不包含事务的特点。 - -```csharp -var songRepository = fsql.GetRepository(); -var song = new Song { BigNumber = "1000000000000000000" }; -songRepository.Insert(song); -``` - -## IFreeSql 核心定义 - -```csharp -var fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseNoneCommandParameter(true) - - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) - .Build(); public class Song { [Column(IsIdentity = true)] public int Id { get; set; } - public string BigNumber { get; set; } - - [Column(IsVersion = true)] //乐观锁 - public long versionRow { get; set; } -} -public class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public string Name { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } public virtual ICollection Tags { get; set; } } +public class Song_tag { + public int Song_id { get; set; } + public virtual Song Song { get; set; } -public class SongContext : DbContext { - public DbSet Songs { get; set; } - public DbSet Tags { get; set; } + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } +} - protected override void OnConfiguring(DbContextOptionsBuilder builder) { - builder.UseFreeSql(fsql); - } +public class Tag { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } } ``` -# 过滤器与验证 - -假设我们有User(用户)、Topic(主题)两个实体,在领域类中定义了两个仓储: +使用的时候与 EFCore 类似: ```csharp -var userRepository = fsql.GetGuidRepository(); -var topicRepository = fsql.GetGuidRepository(); +long id = 0; + +using (var ctx = new SongContext()) { + + var song = new Song { }; + await ctx.Songs.AddAsync(song); + id = song.Id; + + var adds = Enumerable.Range(0, 100) + .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .ToList(); + await ctx.Songs.AddRangeAsync(adds); + + for (var a = 0; a < adds.Count; a++) + adds[a].Title = "dkdkdkdk" + a; + + ctx.Songs.UpdateRange(adds); + + ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList()); + + //ctx.Songs.Update(adds.First()); + + adds.Last().Url = "skldfjlksdjglkjjcccc"; + ctx.Songs.Update(adds.Last()); + + //throw new Exception("回滚"); + + await ctx.SaveChangesAsync(); +} ``` -在开发过程中,总是担心 topicRepository 的数据安全问题,即有可能查询或操作到其他用户的主题。因此我们在v0.0.7版本进行了改进,增加了 filter lambad 表达式参数。 +2、注入方式使用 ```csharp -var userRepository = fsql.GetGuidRepository(a => a.Id == 1); -var topicRepository = fsql.GetGuidRepository(a => a.UserId == 1); +public void ConfigureServices(IServiceCollection services) +{ + services.AddSingleton(Fsql); + services.AddFreeDbContext(options => options.UseFreeSql(Fsql)); +} ``` -* 在查询/修改/删除时附加此条件,从而达到不会修改其他用户的数据; -* 在添加时,使用表达式验证数据的合法性,若不合法则抛出异常; - -# 分表与分库 - -FreeSql 提供 AsTable 分表的基础方法,GuidRepository 作为分存式仓储将实现了分表与分库(不支持跨服务器分库)的封装。 +在 mvc 中获取: ```csharp -var logRepository = fsql.GetGuidRepository(null, oldname => $"{oldname}_{DateTime.Now.ToString("YYYYMM")}"); +IFreeSql _orm; +public ValuesController(SongContext songContext) { +} ``` -上面我们得到一个日志仓储按年月分表,使用它 CURD 最终会操作 Log_201903 表。 +## 优先级 -合并两个仓储,实现分表下的联表查询: +OnConfiguring > AddFreeDbContext + +## 乐观锁 + +更新实体数据,在并发情况下极容易造成旧数据将新的记录更新。FreeSql 核心部分已经支持乐观锁。 + +乐观锁的原理,是利用实体某字段,如:long version,更新前先查询数据,此时 version 为 1,更新时产生的 SQL 会附加 where version = 1,当修改失败时(即 Affrows == 0)抛出异常。 + +每个实体只支持一个乐观锁,在属性前标记特性:[Column(IsVersion = true)] 即可。 + +> 无论是使用 FreeSql/FreeSql.Repository/FreeSql.DbContext,每次更新 version 的值都会增加 1 + +## 说明 + +- DbContext 操作的数据在最后 SaveChanges 时才批量保存; +- DbContext 内所有操作,使用同一个事务; +- 当实体存在自增时,或者 Add/AddRange 的时候主键值为空,会提前开启事务; +- 支持同步/异步方法; + +## 合并机制 + +db.Add(new Xxx()); +db.Add(new Xxx()); +db.Add(new Xxx()); + +这三步,会合并成一个批量插入的语句执行,前提是它们没有自增属性。 + +适用 Guid 主键,Guid 主键的值不用设置,交给 FreeSql 处理即可,空着的 Guid 主键会在插入时获取有序不重值的 Guid 值。 + +又比如: + +db.Add(new Xxx()); +db.Add(new Xxx()); +db.Update(xxx); +db.Add(new Xxx()); + +Guid Id 的情况下,执行三次命令:前两次插入合并执行,update 为一次,后面的 add 为一次。 + +## 联级保存 + +请移步文档[《联级保存》](https://github.com/2881099/FreeSql/wiki/%e8%81%94%e7%ba%a7%e4%bf%9d%e5%ad%98) + +## 实体变化事件 + +全局设置: ```csharp -fsql.GetGuidRepository().Select.FromRepository(logRepository) - .LeftJoin(b => b.UserId == a.Id) - .ToList(); +fsql.SetDbContextOptions(opt => { + opt.OnEntityChange = report => { + Console.WriteLine(report); + }; +}); ``` -注意事项: +单独设置 DbContext 或者 UnitOfWork: -* 不能使用 CodeFirst 迁移分表,开发环境时仍然可以迁移 Log 表; -* 不可在分表分库的实体类型中使用《延时加载》; +```csharp +var ctx = fsql.CreateDbContext(); +ctx.Options.OnEntityChange = report => { + Console.WriteLine(report); +}; -# 历史版本 +var uow = fsql.CreateUnitOfWork(); +uow.OnEntityChange = report => { + Console.WriteLine(report); +}; +``` -### v0.5.23 +参数 report 是一个 List 集合,集合元素的类型定义如下: -- 增加 DbSet/Repository FlushState 手工清除状态管理数据; +```csharp +public class EntityChangeInfo +{ + public object Object { get; set; } + public EntityChangeType Type { get; set; } +} +public enum EntityChangeType { Insert, Update, Delete, SqlRaw } +``` -### v0.5.21 +| 变化类型 | 说明 | +| -- | -- | +| Insert | 实体对象被插入 | +| Update | 实体对象被更新 | +| Delete | 实体对象被删除 | +| SqlRaw | 执行了SQL语句 | -- 修复 AddOrUpdate/InsertOrUpdate 当主键无值时,仍然查询了一次数据库; -- 增加 查询数据时 TrackToList 对导航集合的状态跟踪; -- 完善 AddOrUpdateNavigateList 级联保存,忽略标记 IsIgnore 的集合属性; -- 完成 IFreeSql.Include、IncludeMany 功能; +SqlRaw 目前有两处地方比较特殊: +- 多对多联级更新导航属性的时候,对中间表的全部删除操作; +- 通用仓储类 BaseRepository 有一个 Delete 方法,参数为表达式,而并非实体; +```csharp +int Delete(Expression> predicate); +``` -### v0.5.12 - -- 增加 工作单元开关,可在任意 Insert/Update/Delete 之前调用,以关闭工作单元使其失效;[PR #1](https://github.com/2881099/FreeSql.DbContext/pull/1) - -### v0.5.9 - -- 增加 linq to sql 的查询语法,以及单元测试,[wiki](https://github.com/2881099/FreeSql/wiki/LinqToSql); -- 修复 EnableAddOrUpdateNavigateList 设置对异步方法无效的 bug; - -### v0.5.8 - -- 增加 IFreeSql.SetDbContextOptions 设置 DbContext 的功能:开启或禁用连级一对多导航集合属性保存的功能,EnableAddOrUpdateNavigateList(默认开启); -- 增加 IUnitOfWork.IsolationLevel 设置事务级别; - -### v0.5.7 - -- 修复 UnitOfWork.GetRepository() 事务 bug,原因:仓储的每步操作都提交了事务; - -### v0.5.5 - -- 修复 MapEntityValue 对 IsIgnore 未处理的 bug; - -### v0.5.4 - -- 修复 Repository 追加导航集合的保存 bug; -- 公开 IRepository.Orm 对象; - -### v0.5.3 - -- 修复 实体跟踪的 bug,当查询到的实体自增值为 0 时重现; -- 优化 状态管理字典为 ConcurrentDictionary; - -### v0.5.2 - -- 优化 SqlServer UnitOfWork 使用bug,在 FreeSql 内部解决的; -- 补充 测试与支持联合主键的自增; - -### v0.5.1 - -- 补充 开放 DbContext.UnitOfWork 对象,方便扩展并保持在同一个事务执行; -- 补充 增加 DbSet\、Repository\ 使用方法,配合 AsType(实体类型),实现弱类型操作; -- 修复 DbContext.AddOrUpdate 传入 null 时,任然会查询一次数据库的 bug; -- 优化 DbContext.AddOrUpdate 未添加实体主键的错误提醒; -- 修复 DbContext.Set\ 缓存的 bug,使用多种弱类型时发生; -- 修复 IsIgnore 过滤字段后,查询的错误; -- 修复 全局过滤器功能迁移的遗留 bug; - -### v0.4.14 - -- 优化 Add 时未设置主键的错误提醒; - -### v0.4.13 - -- 补充 Repository 增加 Attach 方法; -- 优化 Update/AddOrUpdate 实体的时候,若状态管理不存在,尝试查询一次数据库,以便跟踪对象; - -### v0.4.12 - -- 修复 非自增情况下,Add 后再 Update 该实体时,错误(需要先 Attach 或查询)的 bug; - -### v0.4.10 - -- 补充 开放 DbContext.Orm 对象; -- 修复 OnConfiguring 未配置时注入获取失败的 bug; - -### v0.4.6 - -- 修复 DbSet AddRange/UpdateRange/RemoveRange 参数为空列表时报错,现在不用判断 data.Any() == true 再执行; -- 增加 DbContext 对 DbSet 的快速代理方法(Add/Update/Remove/Attach); -- 增加 DbContext 通用类,命名为:FreeContext,也可以通过 IFreeSql 扩展方法 CreateDbContext 创建; -- 增加 ISelect NoTracking 扩展方法,查询数据时不追踪(从而提升查询性能); - -### v0.4.5 - -- 增加 DbSet Attach 方法附加实体,可用于不查询就更新或删除; - -### v0.4.2 - -- 增加 DbSet UpdateAsync/UpdateRangeAsync 方法,当一个实体被更新两次时,会先执行前面的队列; -- 增加 GetRepository 获取联合主键的适用仓储类; -- 增加 DbSet 在 Add/Update 时对导航属性(OneToMany) 的处理(AddOrUpdate); - -### v0.4.1 -- 独立 FreeSql.DbContext 项目; -- 实现 Repository + DbSet 统一的状态跟踪与工作单元; -- 增加 DbSet AddOrUpdate 方法; -- 增加 Repository InsertOrUpdate 方法; \ No newline at end of file +DbContext.SaveChanges,或者 Repository 对实体的 Insert/Update/Delete,或者 UnitOfWork.Commit 操作都会最多触发一次该事件。 \ No newline at end of file diff --git a/FreeSql.Repository/readme.md b/FreeSql.Repository/readme.md index 32fee71e..1ba1f896 100644 --- a/FreeSql.Repository/readme.md +++ b/FreeSql.Repository/readme.md @@ -1,95 +1,68 @@ -这是 [FreeSql](https://github.com/2881099/FreeSql) 衍生出来的扩展包,包含 Repository & UnitOfWork 实现面向对象的特性(QQ群:4336577)。 +FreeSql.Repository 作为扩展,实现了通用仓储层功能。与其他规范标准一样,仓储层也有相应的规范定义。FreeSql.Repository 参考 abp vnext 接口,定义和实现基础的仓储层(CURD),应该算比较通用的方法吧。 + +## 安装 > dotnet add package FreeSql.Repository -## Repository & UnitOfWork - -仓储与工作单元一起使用,工作单元具有事务特点。 +## 定义 ```csharp -using (var unitOfWork = fsql.CreateUnitOfWork()) { - var songRepository = unitOfWork.GetRepository(); - var tagRepository = unitOfWork.GetRepository(); - - var song = new Song { BigNumber = "1000000000000000000" }; - songRepository.Insert(song); - - songRepository.Update(song); - - song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); - songRepository.Update(song); - - var tag = new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } - } - }; - tagRepository.Insert(tag); - - ctx.Commit(); -} -``` - -## Repository - -简单使用仓储,有状态跟踪,它不包含事务的特点。 - -```csharp -var songRepository = fsql.GetRepository(); -var song = new Song { BigNumber = "1000000000000000000" }; -songRepository.Insert(song); -``` - -## IFreeSql 核心定义 - -```csharp -var fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseNoneCommandParameter(true) - - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) - .Build(); +static IFreeSql fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) //自动迁移实体的结构到数据库 + .Build(); //请务必定义成 Singleton 单例模式 public class Song { [Column(IsIdentity = true)] public int Id { get; set; } - public string BigNumber { get; set; } - - [Column(IsVersion = true)] //乐观锁 - public long versionRow { get; set; } -} -public class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public string Name { get; set; } - - public virtual ICollection Tags { get; set; } -} - -public class SongContext : DbContext { - public DbSet Songs { get; set; } - public DbSet Tags { get; set; } - - protected override void OnConfiguring(DbContextOptionsBuilder builder) { - builder.UseFreeSql(fsql); - } + public string Title { get; set; } } ``` -# 过滤器与验证 +## 使用方法 + +1、IFreeSql 的扩展方法; + +```csharp +var curd = fsql.GetRepository(); +``` + +> 注意:Repository对象多线程不安全 + +2、继承实现; + +```csharp +public class SongRepository : BaseRepository { + public SongRepository(IFreeSql fsql) : base(fsql, null, null) {} + + //在这里增加 CURD 以外的方法 +} +``` + +3、依赖注入; + +```csharp +public void ConfigureServices(IServiceCollection services) { + + services.AddSingleton(Fsql); + services.AddFreeRepository(filter => filter + .Apply("SoftDelete", a => a.IsDeleted == false) + .Apply("Tenant", a => a.TenantId == 1) + , + this.GetType().Assembly + ); +} + +//在控制器使用 +public SongsController(GuidRepository repos1) { +} +``` + +> 依赖注入的方式可实现全局【过滤与验证】的设定,方便租户功能的设计; + +更多资料:[《过滤器、全局过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) + +## 过滤与验证 假设我们有User(用户)、Topic(主题)两个实体,在领域类中定义了两个仓储: @@ -98,7 +71,7 @@ var userRepository = fsql.GetGuidRepository(); var topicRepository = fsql.GetGuidRepository(); ``` -在开发过程中,总是担心 topicRepository 的数据安全问题,即有可能查询或操作到其他用户的主题。因此我们在v0.0.7版本进行了改进,增加了 filter lambad 表达式参数。 +在开发过程中,总是担心 topicRepository 的数据安全问题,即有可能查询或操作到其他用户的主题。因此我们在v0.0.7版本进行了改进,增加了 filter lambda 表达式参数。 ```csharp var userRepository = fsql.GetGuidRepository(a => a.Id == 1); @@ -108,7 +81,7 @@ var topicRepository = fsql.GetGuidRepository(a => a.UserId == 1); * 在查询/修改/删除时附加此条件,从而达到不会修改其他用户的数据; * 在添加时,使用表达式验证数据的合法性,若不合法则抛出异常; -# 分表与分库 +## 分表与分库 FreeSql 提供 AsTable 分表的基础方法,GuidRepository 作为分存式仓储将实现了分表与分库(不支持跨服务器分库)的封装。 @@ -118,15 +91,148 @@ var logRepository = fsql.GetGuidRepository(null, oldname => $"{oldname}_{Da 上面我们得到一个日志仓储按年月分表,使用它 CURD 最终会操作 Log_201903 表。 -合并两个仓储,实现分表下的联表查询: - -```csharp -fsql.GetGuidRepository().Select.FromRepository(logRepository) - .LeftJoin(b => b.UserId == a.Id) - .ToList(); -``` - 注意事项: -* 不能使用 CodeFirst 迁移分表,开发环境时仍然可以迁移 Log 表; +* v0.11.12以后的版本可以使用 CodeFirst 迁移分表; * 不可在分表分库的实体类型中使用《延时加载》; + +## 兼容问题 + +FreeSql 支持五种数据库,分别为 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦,虽然他们都为关系型数据库,但各自有着独特的技术亮点,有许多亮点值得我们使用; + +比如 SqlServer 提供的 output inserted 特性,在表使用了自增或数据库定义了默认值的时候,使用它可以快速将 insert 的数据返回。PostgreSQL 也有相应的功能,如此方便却不是每个数据库都支持。 + +IRepository 接口定义: + +```csharp +TEntity Insert(TEntity entity); +Task InsertAsync(TEntity entity); +``` + +于是我们做了两种仓库层实现: + +- BaseRepository 采用 ExecuteInserted 执行; +- GuidRepository 采用 ExecuteAffrows 执行(兼容性好); + +当采用了不支持的数据库时(Sqlite/MySql/Oracle),建议: + +* 使用 uuid 作为主键(即 Guid); +* 避免使用数据库的默认值功能; +* 仓储层实现请使用 GuidRepository; + +## UnitOfWork + +UnitOfWork 可将多个仓储放在一个单元管理执行,最终通用 Commit 执行所有操作,内部采用了数据库事务; + +```csharp +using (var uow = fsql.CreateUnitOfWork()) { + var songRepo = uow.GetRepository(); + var userRepo = uow.GetRepository(); + + //上面两个仓储,由同一UnitOfWork uow 创建 + //在此执行仓储操作 + + //这里不受异步方便影响 + + uow.Commit(); +} +``` + +参考:在 asp.net core 中注入工作单元方法 + +```csharp +//第一步: +public class UnitOfWorkRepository : BaseRepository +{ + public UnitOfWorkRepository(IFreeSql fsql, IUnitOfWork uow) : base(fsql, null, null) + { + this.UnitOfWork = uow; + } +} +public class UnitOfWorkRepository : BaseRepository +{ + public UnitOfWorkRepository(IFreeSql fsql, IUnitOfWork uow) : base(fsql, null, null) + { + this.UnitOfWork = uow; + } +} + +//第二步: +public void ConfigureServices(IServiceCollection services) +{ + services.AddSingleton(fsql); + services.AddScoped(sp => fsql.CreateUnitOfWork()); + + services.AddScoped(typeof(IReadOnlyRepository<>), typeof(UnitOfWorkRepository<>)); + services.AddScoped(typeof(IBasicRepository<>), typeof(UnitOfWorkRepository<>)); + services.AddScoped(typeof(BaseRepository<>), typeof(UnitOfWorkRepository<>)); + + services.AddScoped(typeof(IReadOnlyRepository<,>), typeof(UnitOfWorkRepository<,>)); + services.AddScoped(typeof(IBasicRepository<,>), typeof(UnitOfWorkRepository<,>)); + services.AddScoped(typeof(BaseRepository<,>), typeof(UnitOfWorkRepository<,>)); + + //批量注入程序集内的所有自建仓储类,可以根据自己需要来修改 + Assembly[] assemblies = new [] { typeof(XxxRepository).Assembly }; + if (assemblies?.Any() == true) + foreach (var asse in assemblies) + foreach (var repo in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(UnitOfWorkRepository).IsAssignableFrom(a))) + services.AddScoped(repo); +} +``` + +## 联级保存 + +请移步文档[《联级保存》](https://github.com/2881099/FreeSql/wiki/%e8%81%94%e7%ba%a7%e4%bf%9d%e5%ad%98) + +## 实体变化事件 + +全局设置: + +```csharp +fsql.SetDbContextOptions(opt => { + opt.OnEntityChange = report => { + Console.WriteLine(report); + }; +}); +``` + +单独设置 DbContext 或者 UnitOfWork: + +```csharp +var ctx = fsql.CreateDbContext(); +ctx.Options.OnEntityChange = report => { + Console.WriteLine(report); +}; + +var uow = fsql.CreateUnitOfWork(); +uow.OnEntityChange = report => { + Console.WriteLine(report); +}; +``` + +参数 report 是一个 List 集合,集合元素的类型定义如下: + +```csharp +public class EntityChangeInfo +{ + public object Object { get; set; } + public EntityChangeType Type { get; set; } +} +public enum EntityChangeType { Insert, Update, Delete, SqlRaw } +``` + +| 变化类型 | 说明 | +| -- | -- | +| Insert | 实体对象被插入 | +| Update | 实体对象被更新 | +| Delete | 实体对象被删除 | +| SqlRaw | 执行了SQL语句 | + +SqlRaw 目前有两处地方比较特殊: +- 多对多联级更新导航属性的时候,对中间表的全部删除操作; +- 通用仓储类 BaseRepository 有一个 Delete 方法,参数为表达式,而并非实体; +```csharp +int Delete(Expression> predicate); +``` + +DbContext.SaveChanges,或者 Repository 对实体的 Insert/Update/Delete,或者 UnitOfWork.Commit 操作都会最多触发一次该事件。 \ No newline at end of file diff --git a/readme.md b/readme.md index 567d27b8..5f51591d 100644 --- a/readme.md +++ b/readme.md @@ -1,12 +1,14 @@

- +

FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+ 或 Xamarin 扶摇直上,至强ORM只为自由编码;鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) -# Features +[![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/2881099/FreeSql/master/LICENSE.txt) + +## Features - [x] 支持 CodeFirst 迁移,哪怕使用 Access 数据库也支持; - [x] 支持 DbFirst 从数据库导入实体类,[安装实体类生成工具](https://github.com/2881099/FreeSql/wiki/DbFirst); @@ -16,29 +18,22 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 读写分离、分表分库,租户设计,过滤器,乐观锁,悲观锁; - [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库/Access; -| | | -| - | - | -| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | -| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9#%E4%B9%90%E8%A7%82%E9%94%81) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +## Documentation -# Packages +[《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html)、[《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2)、[《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9)、[《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0)、[《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) -| Package Name | NuGet | Downloads | -|--------------| ------- | ---- | -| FreeSql | [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) | [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) | -| FreeSql.Repository | [![nuget](https://img.shields.io/nuget/v/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Repository) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Repository?groupby=Version) | -| FreeSql.DbContext | [![nuget](https://img.shields.io/nuget/v/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.DbContext) | [![stats](https://img.shields.io/nuget/dt/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.DbContext?groupby=Version) | -| [FreeSql.AdminLTE](https://github.com/2881099/FreeSql.AdminLTE) | [![nuget](https://img.shields.io/nuget/v/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.AdminLTE) | [![stats](https://img.shields.io/nuget/dt/FreeSql.AdminLTE.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.AdminLTE?groupby=Version) | +[《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0)、[《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst)、[《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst)、[《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) -> FreeSql 提供了五种使用习惯,请根据实际情况选择团队合适的一种: +[《Repository》](https://github.com/2881099/FreeSql/wiki/Repository)、[《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83)、[《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8)、[《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9#%E4%B9%90%E8%A7%82%E9%94%81)、[《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) + +[《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)、[《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8)、[《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7)、[《AOP》](https://github.com/2881099/FreeSql/wiki/AOP)、[《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C)、[*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) + +> FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: - 要么FreeSql,原始用法; - 要么[FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository),仓储+工作单元习惯; - 要么[FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; -- 要么[FreeSql.Connection.Extensions](https://github.com/2881099/FreeSql.Connection.Extensions),有点像Dapper的使用习惯; -- 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),我求简单现在使用的这个; +- 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),求简单使用这个; > [FluentApi 与 EfCore 90% 相似的扩展包](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi); @@ -49,173 +44,139 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 欢迎更多使用 FreeSql 的开源项目加入目录 -# Providers - -| Package Name | Version | -|--------------| ------- | -| FreeSql.Provider.MySql | NETStandard2.0、net45、net40 | -| FreeSql.Provider.MySqlConnector | NETStandard2.0、net45 | -| FreeSql.Provider.PostgreSQL | NETStandard2.0、net45 | -| FreeSql.Provider.SqlServer | NETStandard2.0、net45、net40 | -| FreeSql.Provider.Sqlite | NETStandard2.0、net45、net40 | -| FreeSql.Provider.Oracle | NETStandard2.0、net45、net40 | -| [FreeSql.Provider.Odbc](https://github.com/2881099/FreeSql/tree/master/Providers/FreeSql.Provider.Odbc) | NETStandard2.0、net45、net40 | -| FreeSql.Extensions.LazyLoading | NETStandard2.0、net45、net40 | -| FreeSql.Extensions.JsonMap | NETStandard2.0、net45、net40 | -| FreeSql.Extensions.BaseEntity | NETStandard2.0 | - -# ConnectionStrings - -| DataType | ConnectionString | -| --- | --- | -| DataType.MySql | Data Source=127.0.0.1;Port=3306;User ID=root;Password=root; Initial Catalog=cccddd;Charset=utf8; SslMode=none;Min pool size=1 | -| DataType.PostgreSQL | Host=192.168.164.10;Port=5432;Username=postgres;Password=123456; Database=tedb;Pooling=true;Minimum Pool Size=1 | -| DataType.SqlServer | Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=1 | -| DataType.Oracle | user id=user1;password=123456; data source=//127.0.0.1:1521/XE;Pooling=true;Min Pool Size=1 | -| DataType.Sqlite | Data Source=\|DataDirectory\|\document.db; Attachs=xxxtb.db; Pooling=true;Min Pool Size=1 | -| DataType.OdbcMySql | Driver={MySQL ODBC 8.0 Unicode Driver}; Server=127.0.0.1;Persist Security Info=False; Trusted_Connection=Yes;UID=root;PWD=root; DATABASE=cccddd_odbc;Charset=utf8; SslMode=none;Min Pool Size=1 | -| DataType.OdbcSqlServer | Driver={SQL Server};Server=.;Persist Security Info=False; Trusted_Connection=Yes;Integrated Security=True; DATABASE=freesqlTest_odbc; Pooling=true;Min Pool Size=1 | -| DataType.OdbcOracle | Driver={Oracle in XE};Server=//127.0.0.1:1521/XE; Persist Security Info=False; Trusted_Connection=Yes;UID=odbc1;PWD=123456; Min Pool Size=1 | -| DataType.OdbcPostgreSQL | Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10; Port=5432;UID=postgres;PWD=123456; Database=tedb_odbc;Pooling=true;Min Pool Size=1 | -| DataType.OdbcDameng (达梦) | Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236; Persist Security Info=False; Trusted_Connection=Yes; UID=USER1;PWD=123456789 | -| DataType.Odbc | Driver={SQL Server};Server=.;Persist Security Info=False; Trusted_Connection=Yes;Integrated Security=True; DATABASE=freesqlTest_odbc; Pooling=true;Min pool size=1 | -

-# Quick start +## Quick start > dotnet add package FreeSql.Provider.Sqlite ```csharp static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, - @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) //自动同步实体结构到数据库 - .Build(); //请务必定义成 Singleton 单例模式 + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=document.db") + .UseAutoSyncStructure(true) //自动同步实体结构到数据库 + .Build(); //请务必定义成 Singleton 单例模式 class Song { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Title { get; set; } - public string Url { get; set; } - public DateTime CreateTime { get; set; } - - public virtual ICollection Tags { get; set; } + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime CreateTime { get; set; } + + public virtual ICollection Tags { get; set; } } class Song_tag { - public int Song_id { get; set; } - public virtual Song Song { get; set; } - - public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } } class Tag { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Name { get; set; } - - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } } ``` -# Query +## Query ```csharp //OneToOne、ManyToOne -var t0 = fsql.Select() - .Where(a => a.Parent.Parent.Name == "粤语") - .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) - .ToList(); +fsql.Select() + .Where(a => a.Parent.Parent.Name == "粤语") + .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) + .ToList(); //OneToMany -var t1 = fsql.Select() - .Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)) - .ToList(); +fsql.Select() + .Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)) + .ToList(); //ManyToMany -var t2 = fsql.Select() +fsql.Select() .Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")) .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) .ToList(); //Other -var t3 = fsql.Select() - .Where(a => a.IsDelete == 0) - .WhereIf(keyword != null, a => a.UserName.Contains(keyword)) - .WhereIf(role_id > 0, a => a.RoleId == role_id) - .Where(a => a.Nodes.AsSelect().Any(t => t.Parent.Id == t.UserId)) - .Count(out var total) - .Page(page, size) - .OrderByDescending(a => a.Id) - .ToList() +fsql.Select() + .Where(a => a.IsDelete == 0) + .WhereIf(keyword != null, a => a.UserName.Contains(keyword)) + .WhereIf(role_id > 0, a => a.RoleId == role_id) + .Where(a => a.Nodes.AsSelect().Any(t => t.Parent.Id == t.UserId)) + .Count(out var total) + .Page(page, size) + .OrderByDescending(a => a.Id) + .ToList() ``` 更多前往Wiki:[《Select 查询数据文档》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) ```csharp -var t3 = fsql.Select() - .Where(a => new[] { 1, 2, 3 }.Contains(a.Id)) - .ToList(); -``` -```csharp -var t4 = fsql.Select() - .Where(a => a.CreateTime.Date == DateTime.Now.Date) - .ToList(); -``` -```csharp -var t5 = fsql.Select() - .OrderBy(a => Guid.NewGuid()) - .Limit(1) - .ToList(); +fsql.Select() + .Where(a => new[] { 1, 2, 3 }.Contains(a.Id)) + .ToList(); + +fsql.Select() + .Where(a => a.CreateTime.Date == DateTime.Today) + .ToList(); + +fsql.Select() + .OrderBy(a => Guid.NewGuid()) + .Limit(1) + .ToList(); ``` 更多前往Wiki:[《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) -# Repository & UnitOfWork +## Repository & UnitOfWork > dotnet add package FreeSql.Repository ```csharp using (var uow = fsql.CreateUnitOfWork()) { - var repo1 = uow.GetRepository(); - var repo2 = uow.GetRepository(); + var repo1 = uow.GetRepository(); + var repo2 = uow.GetRepository(); - await repo1.InsertAsync(new Song()); - await repo2.InsertAsync(new Tag()); - uow.Commit(); + await repo1.InsertAsync(new Song()); + await repo2.InsertAsync(new Tag()); + uow.Commit(); } ``` -# DbContext & DbSet +## DbContext & DbSet > dotnet add package FreeSql.DbContext ```csharp using (var ctx = new fsql.CreateDbContext()) { - var songs = ctx.Set(); - var tags = ctx.Set(); + var songs = ctx.Set(); + var tags = ctx.Set(); - var tag = new Tag { - Name = "testaddsublist", + var tag = new Tag { + Name = "testaddsublist", + Tags = new[] { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { + Name = "sub3", Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } + new Tag { Name = "sub3_01" } } - }; - //tags.Add(tag); - ctx.Add(tag); - await ctx.SaveChangesAsync(); + } + } + }; + //tags.Add(tag); + ctx.Add(tag); + await ctx.SaveChangesAsync(); } ``` -# Performance +## Performance FreeSql Query & Dapper Query ```shell @@ -243,7 +204,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [Test code](FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs)、[More](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd) -# Contributors +## Contributors [systemhejiyong](https://github.com/systemhejiyong)、 [LambertW](https://github.com/LambertW)、 @@ -260,7 +221,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper (QQ群:4336577) -# Donation +## Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元 From a047e210095c08f0b5f88c21ff5a182e3000eb03 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 29 Feb 2020 13:21:28 +0800 Subject: [PATCH 0443/1029] update --- readme.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/readme.md b/readme.md index 5f51591d..c59a423b 100644 --- a/readme.md +++ b/readme.md @@ -20,13 +20,12 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ ## Documentation -[《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html)、[《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2)、[《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9)、[《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0)、[《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) - -[《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0)、[《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst)、[《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst)、[《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) - -[《Repository》](https://github.com/2881099/FreeSql/wiki/Repository)、[《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83)、[《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8)、[《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9#%E4%B9%90%E8%A7%82%E9%94%81)、[《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) - -[《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)、[《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8)、[《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7)、[《AOP》](https://github.com/2881099/FreeSql/wiki/AOP)、[《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C)、[*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) +| | | +| - | - | +| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9#%E4%B9%90%E8%A7%82%E9%94%81) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | > FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: @@ -102,9 +101,9 @@ fsql.Select() //ManyToMany fsql.Select() - .Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")) - .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) - .ToList(); + .Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")) + .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) + .ToList(); //Other fsql.Select() From c4b69ff20fb0c09e8639dcc4f2b3a571f924de54 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 29 Feb 2020 13:24:11 +0800 Subject: [PATCH 0444/1029] update readme --- readme.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/readme.md b/readme.md index c59a423b..9baa1221 100644 --- a/readme.md +++ b/readme.md @@ -34,8 +34,6 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - 要么[FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; - 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),求简单使用这个; -> [FluentApi 与 EfCore 90% 相似的扩展包](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi); - > 学习项目 - [😃 A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) From 32703e016a7fa4a56ba04213f0a72ea3d2338bbf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 29 Feb 2020 13:25:39 +0800 Subject: [PATCH 0445/1029] update readme --- readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 9baa1221..940aa0de 100644 --- a/readme.md +++ b/readme.md @@ -22,10 +22,10 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | | | - | - | -| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | -| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9#%E4%B9%90%E8%A7%82%E9%94%81) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9#%E4%B9%90%E8%A7%82%E9%94%81) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | > FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: From 24cc8bc1daa59987d8df6d370c8e76ac018cab5f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 2 Mar 2020 18:57:53 +0800 Subject: [PATCH 0446/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20Aop=20?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20event=20=E4=BA=8B=E4=BB=B6=EF=BC=9B=20-=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=20Ado.AopCommandExecuting/AopCommandExecuted?= =?UTF-8?q?=20=E5=88=B0=20Aop.CommandBefore/After=EF=BC=9B=20-=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20Aop.TraceBefore/After=20=E4=BA=8B=E4=BB=B6=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/dbcontext_01/Startup.cs | 8 +- Examples/restful/Startup.cs | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 3 - FreeSql.DbContext/DbSet/DbSetAsync.cs | 7 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 7 +- FreeSql.DbContext/FreeSql.DbContext.xml | 14 +- FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 5 + FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 62 ++++- .../FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 2 +- .../DataAnnotations/MySqlFluentTest.cs | 4 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 96 ++++++-- FreeSql/FreeSqlBuilder.cs | 12 +- FreeSql/Interface/IAdo.cs | 8 - FreeSql/Interface/IAop.cs | 167 ++++++++++++- FreeSql/Internal/CommonExpression.cs | 12 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 79 +++---- .../AdoProvider/AdoProviderAsync.cs | 52 ++--- .../AdoProvider/AdoProviderTransaction.cs | 36 ++- .../Internal/CommonProvider/AopProvider.cs | 41 +++- .../CommonProvider/CodeFirstProvider.cs | 4 +- .../Internal/CommonProvider/DeleteProvider.cs | 4 +- .../CommonProvider/DeleteProviderAsync.cs | 4 +- .../Internal/CommonProvider/InsertProvider.cs | 219 +++++++++++------- .../CommonProvider/InsertProviderAsync.cs | 215 ++++++++++------- .../SelectProvider/Select0Provider.cs | 44 ++-- .../Internal/CommonProvider/UpdateProvider.cs | 152 +++++++----- .../CommonProvider/UpdateProviderAsync.cs | 142 ++++++++---- FreeSql/Internal/CommonUtils.cs | 12 +- .../Curd/MsAccessInsert.cs | 16 +- .../Curd/MySqlDelete.cs | 8 +- .../Curd/MySqlInsert.cs | 16 +- .../Curd/MySqlUpdate.cs | 8 +- .../Curd/OnDuplicateKeyUpdate.cs | 8 +- .../Dameng/Curd/OdbcDamengInsert.cs | 16 +- .../Default/Curd/OdbcInsert.cs | 8 +- .../GBase/Curd/__OdbcGBaseInsert.cs | 16 +- .../MySql/Curd/OdbcMySqlDelete.cs | 8 +- .../MySql/Curd/OdbcMySqlInsert.cs | 16 +- .../MySql/Curd/OdbcMySqlUpdate.cs | 8 +- .../Oracle/Curd/OdbcOracleInsert.cs | 16 +- .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 8 +- .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 24 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 8 +- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 8 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 24 +- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 8 +- .../Curd/OracleInsert.cs | 16 +- .../Curd/OnConflictDoUpdate.cs | 8 +- .../Curd/PostgreSQLDelete.cs | 8 +- .../Curd/PostgreSQLInsert.cs | 24 +- .../Curd/PostgreSQLUpdate.cs | 8 +- .../Curd/SqlServerDelete.cs | 8 +- .../Curd/SqlServerInsert.cs | 16 +- .../Curd/SqlServerUpdate.cs | 8 +- .../Curd/SqliteInsert.cs | 8 +- 58 files changed, 1109 insertions(+), 638 deletions(-) diff --git a/Examples/dbcontext_01/Startup.cs b/Examples/dbcontext_01/Startup.cs index 777f8be3..6ac054d2 100644 --- a/Examples/dbcontext_01/Startup.cs +++ b/Examples/dbcontext_01/Startup.cs @@ -31,20 +31,20 @@ namespace dbcontext_01 (cmd, log) => Trace.WriteLine(log) ) .Build(); - Fsql.Aop.SyncStructureBefore = (s, e) => + Fsql.Aop.SyncStructureBefore += (s, e) => { Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName))); }; - Fsql.Aop.SyncStructureAfter = (s, e) => + Fsql.Aop.SyncStructureAfter += (s, e) => { Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName)) + " " + e.ElapsedMilliseconds + "ms\r\n" + e.Exception?.Message + e.Sql); }; - Fsql.Aop.CurdBefore = (s, e) => + Fsql.Aop.CurdBefore += (s, e) => { Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + ", " + e.Sql); }; - Fsql.Aop.CurdAfter = (s, e) => + Fsql.Aop.CurdAfter += (s, e) => { Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + " " + e.ElapsedMilliseconds + "ms, " + e.Sql); }; diff --git a/Examples/restful/Startup.cs b/Examples/restful/Startup.cs index 6079ae39..240e6286 100644 --- a/Examples/restful/Startup.cs +++ b/Examples/restful/Startup.cs @@ -18,7 +18,7 @@ namespace restful .UseAutoSyncStructure(true) .Build(); - Fsql.Aop.CurdAfter = (s, e) => + Fsql.Aop.CurdAfter += (s, e) => { if (e.ElapsedMilliseconds > 200) { diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e78eae61..2a7cc192 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -16,9 +16,6 @@ $(AssemblyName) true true - true - key.snk - false
diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index df1a2c00..68d6b0bb 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -160,7 +160,9 @@ namespace FreeSql await DbContextExecCommandAsync(); //删除没有保存的数据 var propValEach = GetItemValue(item, prop) as IEnumerable; - await _db.Orm.Delete().AsType(tref.RefEntityType).WhereDynamic(propValEach, true).ExecuteAffrowsAsync(); + await _db.Orm.Delete().AsType(tref.RefEntityType) + .WithTransaction(_uow?.GetOrBeginTransaction()) + .WhereDynamic(propValEach, true).ExecuteAffrowsAsync(); } } finally @@ -213,7 +215,8 @@ namespace FreeSql if (curList.Any() == false) //全部删除 { - var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType); + var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType) + .WithTransaction(_uow?.GetOrBeginTransaction()); foreach (var midWhere in midWheres) delall.Where(midWhere); var sql = delall.ToSql(); await delall.ExecuteAffrowsAsync(); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 172d13cb..603e1fda 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -172,7 +172,9 @@ namespace FreeSql DbContextExecCommand(); //删除没有保存的数据 var propValEach = GetItemValue(item, prop) as IEnumerable; - _db.Orm.Delete().AsType(tref.RefEntityType).WhereDynamic(propValEach, true).ExecuteAffrows(); + _db.Orm.Delete().AsType(tref.RefEntityType) + .WithTransaction(_uow?.GetOrBeginTransaction()) + .WhereDynamic(propValEach, true).ExecuteAffrows(); } } finally @@ -225,7 +227,8 @@ namespace FreeSql if (curList.Any() == false) //全部删除 { - var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType); + var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType) + .WithTransaction(_uow?.GetOrBeginTransaction()); foreach (var midWhere in midWheres) delall.Where(midWhere); var sql = delall.ToSql(); delall.ExecuteAffrows(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..2735cefb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -251,6 +244,13 @@ 实体对象 属性名 + + + 开启事务,或者返回已开启的事务 + + 若未开启事务,则开启 + + 是否启用工作单元 diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index 2dc2b691..e6ffb167 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -8,6 +8,11 @@ namespace FreeSql public interface IUnitOfWork : IDisposable { + /// + /// 开启事务,或者返回已开启的事务 + /// + /// 若未开启事务,则开启 + /// DbTransaction GetOrBeginTransaction(bool isCreate = true); IsolationLevel? IsolationLevel { get; set; } diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index a21bb5af..a05b8ba6 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -24,6 +24,8 @@ namespace FreeSql protected IFreeSql _fsql; protected Object _conn; protected DbTransaction _tran; + protected Aop.TraceBeforeEventArgs _tranBefore; + protected Aop.TraceBeforeEventArgs _uowBefore; /// /// 开启事务后有值,是 UnitOfWork 的唯一标识 @@ -35,6 +37,11 @@ namespace FreeSql public UnitOfWork(IFreeSql fsql) { _fsql = fsql; + if (_fsql == null) throw new ArgumentNullException(nameof(fsql)); + + _uowBefore = new Aop.TraceBeforeEventArgs("UnitOfWork", null); + _fsql?.Aop.TraceBeforeHandler?.Invoke(this, _uowBefore); + #if netcoreapp Current.Value = this; #endif @@ -77,49 +84,83 @@ namespace FreeSql if (!Enable) return null; if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); - _conn = _fsql.Ado.MasterPool.Get(); + _tranBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", IsolationLevel); + _fsql?.Aop.TraceBeforeHandler?.Invoke(this, _tranBefore); try { - _tran = IsolationLevel == null ? - _conn.Value.BeginTransaction() : - _conn.Value.BeginTransaction(IsolationLevel.Value); + _conn = _fsql.Ado.MasterPool.Get(); + try + { + _tran = IsolationLevel == null ? + _conn.Value.BeginTransaction() : + _conn.Value.BeginTransaction(IsolationLevel.Value); - this.Id = $"{DateTime.Now.ToString("yyyyMMdd_HHmmss")}_{Interlocked.Increment(ref _seed)}"; - DebugBeingUsed.TryAdd(this.Id, this); + this.Id = $"{DateTime.Now.ToString("yyyyMMdd_HHmmss")}_{Interlocked.Increment(ref _seed)}"; + DebugBeingUsed.TryAdd(this.Id, this); + } + catch + { + ReturnObject(); + throw; + } } - catch + catch (Exception ex) { - ReturnObject(); - throw; + _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "失败", ex)); + throw ex; } return _tran; } public void Commit() { + var isCommited = false; try { if (_tran != null) { _tran.Commit(); + isCommited = true; + _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "提交", null)); + if (EntityChangeReport != null && EntityChangeReport.OnChange != null && EntityChangeReport.Report.Any() == true) EntityChangeReport.OnChange.Invoke(EntityChangeReport.Report); } } + catch (Exception ex) + { + if (isCommited == false) + _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "提交失败", ex)); + throw ex; + } finally { ReturnObject(); + _tranBefore = null; } } public void Rollback() { + var isRollbacked = false; try { - if (_tran != null) _tran.Rollback(); + if (_tran != null) + { + _tran.Rollback(); + isRollbacked = true; + _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "回滚", null)); + } + } + catch (Exception ex) + { + if (isRollbacked == false) + _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "回滚失败", ex)); + throw ex; } finally { ReturnObject(); + _tranBefore = null; } } @@ -137,6 +178,7 @@ namespace FreeSql } finally { + _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_uowBefore, "释放", null)); GC.SuppressFinalize(this); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index 4af3bc73..5f040d3c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -485,7 +485,7 @@ WHERE ROWNUM < 11"; // .ExecuteAffrows(); - g.mysql.Aop.ParseExpression = (s, e) => + g.mysql.Aop.ParseExpression += (s, e) => { if (e.Expression.NodeType == ExpressionType.Call) { diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index c4110f04..5046db22 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -37,7 +37,7 @@ namespace FreeSql.Tests.DataAnnotations { g.mysql.CodeFirst.ConfigEntity(a => a.Property(b => b.pkid).IsPrimary(true)); - g.mysql.Aop.ConfigEntity = (s, e) => + g.mysql.Aop.ConfigEntity += (s, e) => { var attr = e.EntityType.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute), false).FirstOrDefault() as System.ComponentModel.DataAnnotations.Schema.TableAttribute; if (attr != null) @@ -45,7 +45,7 @@ namespace FreeSql.Tests.DataAnnotations e.ModifyResult.Name = attr.Name; } }; - g.mysql.Aop.ConfigEntityProperty = (s, e) => + g.mysql.Aop.ConfigEntityProperty += (s, e) => { if (e.Property.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.KeyAttribute), false).Any()) { diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index c952897c..37e30197 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -756,7 +756,7 @@ namespace FreeSql.Tests // .ExecuteAffrows(); - g.mysql.Aop.ParseExpression = (s, e) => + g.mysql.Aop.ParseExpression += (s, e) => { if (e.Expression.NodeType == ExpressionType.Call) { diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index d97e28fc..1318b25a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -459,7 +459,7 @@ namespace FreeSql.Tests a.SubjectId }).NoneParameter().ToSql(); - g.mysql.Aop.ParseExpression = (s, e) => + g.mysql.Aop.ParseExpression += (s, e) => { if (e.Expression.NodeType == ExpressionType.Call) { diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 86365c2e..f8a2f9b7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -34,7 +34,7 @@ - + net40 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5c768294..08d2c1b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2098,16 +2098,6 @@ 从库连接池 - - - 监视数据库命令对象(执行前,调试) - - - - - 监视数据库命令对象(执行后,用于监视执行性能) - - 数据库类型 @@ -2401,46 +2391,66 @@ - + 可自定义解析表达式 - + 自定义实体的配置,方便和多个 ORM 共同使用 - + 自定义实体的属性配置,方便和多个 ORM 共同使用 - + 增删查改,执行命令之前触发 - + 增删查改,执行命令完成后触发 - + CodeFirst迁移,执行之前触发 - + CodeFirst迁移,执行完成触发 - + Insert/Update自动值处理 + + + 监视数据库命令对象(执行前,调试) + + + + + 监视数据库命令对象(执行后,用于监视执行性能) + + + + + 跟踪开始 + + + + + 跟踪结束 + + 内置解析功能,可辅助您进行解析 @@ -2586,6 +2596,56 @@ 获取实体的属性值,也可以设置实体的属性新值 + + + 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 + + + + + 备注 + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 3f62e85a..9309609d 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -248,9 +248,15 @@ namespace FreeSql ret.CodeFirst.IsNoneCommandParameter = _isNoneCommandParameter; ret.CodeFirst.IsGenerateCommandParameterWithLambda = _isGenerateCommandParameterWithLambda; ret.CodeFirst.IsLazyLoading = _isLazyLoading; - var ado = ret.Ado as Internal.CommonProvider.AdoProvider; - ado.AopCommandExecuting += _aopCommandExecuting; - ado.AopCommandExecuted += _aopCommandExecuted; + + ret.Aop.CommandBefore += new EventHandler((s, e) => + { + _aopCommandExecuting(e.Command); + }); + ret.Aop.CommandAfter += new EventHandler((s, e) => + { + _aopCommandExecuted(e.Command, e.Log); + }); //添加实体属性名全局AOP转换处理 if (_entityPropertyConvertType != StringConvertType.None) diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 7fccbfa2..3d7d60bc 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -20,14 +20,6 @@ namespace FreeSql /// List> SlavePools { get; } /// - /// 监视数据库命令对象(执行前,调试) - /// - Action AopCommandExecuting { get; set; } - /// - /// 监视数据库命令对象(执行后,用于监视执行性能) - /// - Action AopCommandExecuted { get; set; } - /// /// 数据库类型 /// DataType DataType { get; } diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index 9aeefb8d..b9914ff3 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -15,44 +15,75 @@ namespace FreeSql /// /// 可自定义解析表达式 /// - EventHandler ParseExpression { get; set; } + event EventHandler ParseExpression; + EventHandler ParseExpressionHandler { get; } /// /// 自定义实体的配置,方便和多个 ORM 共同使用 /// - EventHandler ConfigEntity { get; set; } + event EventHandler ConfigEntity; + EventHandler ConfigEntityHandler { get; } /// /// 自定义实体的属性配置,方便和多个 ORM 共同使用 /// - EventHandler ConfigEntityProperty { get; set; } + event EventHandler ConfigEntityProperty; + EventHandler ConfigEntityPropertyHandler { get; } /// /// 增删查改,执行命令之前触发 /// - EventHandler CurdBefore { get; set; } + event EventHandler CurdBefore; + EventHandler CurdBeforeHandler { get; } /// /// 增删查改,执行命令完成后触发 /// - EventHandler CurdAfter { get; set; } + event EventHandler CurdAfter; + EventHandler CurdAfterHandler { get; } /// /// CodeFirst迁移,执行之前触发 /// - EventHandler SyncStructureBefore { get; set; } + event EventHandler SyncStructureBefore; + EventHandler SyncStructureBeforeHandler { get; } /// /// CodeFirst迁移,执行完成触发 /// - EventHandler SyncStructureAfter { get; set; } + event EventHandler SyncStructureAfter; + EventHandler SyncStructureAfterHandler { get; } /// /// Insert/Update自动值处理 /// - EventHandler AuditValue { get; set; } + event EventHandler AuditValue; + EventHandler AuditValueHandler { get; } + + /// + /// 监视数据库命令对象(执行前,调试) + /// + event EventHandler CommandBefore; + EventHandler CommandBeforeHandler { get; } + /// + /// 监视数据库命令对象(执行后,用于监视执行性能) + /// + event EventHandler CommandAfter; + EventHandler CommandAfterHandler { get; } + + /// + /// 跟踪开始 + /// + event EventHandler TraceBefore; + EventHandler TraceBeforeHandler { get; } + /// + /// 跟踪结束 + /// + event EventHandler TraceAfter; + EventHandler TraceAfterHandler { get; } } } namespace FreeSql.Aop { + #region ParseExpression public class ParseExpressionEventArgs : EventArgs { public ParseExpressionEventArgs(Expression expression, Func freeParse) @@ -75,6 +106,9 @@ namespace FreeSql.Aop /// public string Result { get; set; } } + #endregion + + #region ConfigEntity/Property public class ConfigEntityEventArgs : EventArgs { public ConfigEntityEventArgs(Type entityType) @@ -119,7 +153,9 @@ namespace FreeSql.Aop /// public ColumnAttribute ModifyResult { get; } } + #endregion + #region CurdBefore/After public class CurdBeforeEventArgs : EventArgs { public CurdBeforeEventArgs(Type entityType, TableInfo table, CurdType curdType, string sql, DbParameter[] dbParms) : @@ -155,7 +191,7 @@ namespace FreeSql.Aop /// /// 实体类型的元数据 /// - public TableInfo Table { get; set; } + public TableInfo Table { get; } /// /// 执行的 SQL /// @@ -183,7 +219,7 @@ namespace FreeSql.Aop /// /// 执行SQL命令,返回的结果 /// - public object ExecuteResult { get; set; } + public object ExecuteResult { get; } /// /// 耗时(单位:Ticks) /// @@ -193,7 +229,9 @@ namespace FreeSql.Aop /// public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; } + #endregion + #region SyncStructureBefore/After public class SyncStructureBeforeEventArgs : EventArgs { public SyncStructureBeforeEventArgs(Type[] entityTypes) : @@ -246,7 +284,9 @@ namespace FreeSql.Aop /// public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; } + #endregion + #region AuditValue public class AuditValueEventArgs : EventArgs { public AuditValueEventArgs(AuditValueType autoValueType, ColumnInfo column, PropertyInfo property, object value) @@ -285,4 +325,111 @@ namespace FreeSql.Aop public bool IsChanged { get; private set; } } public enum AuditValueType { Update, Insert } + #endregion + + #region CommandBefore/After + public class CommandBeforeEventArgs : EventArgs + { + public CommandBeforeEventArgs(DbCommand command) : + this(Guid.NewGuid(), new Stopwatch(), command) + { + this.Stopwatch.Start(); + } + protected CommandBeforeEventArgs(Guid identifier, Stopwatch stopwatch, DbCommand command) + { + this.Identifier = identifier; + this.Stopwatch = stopwatch; + this.Command = command; + } + + /// + /// 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 + /// + public Guid Identifier { get; protected set; } + protected Stopwatch Stopwatch { get; } + internal Stopwatch StopwatchInternal => Stopwatch; + public DbCommand Command { get; } + } + public class CommandAfterEventArgs : CommandBeforeEventArgs + { + public CommandAfterEventArgs(CommandBeforeEventArgs before, Exception exception, string log) : + base(before.Identifier, before.StopwatchInternal, before.Command) + { + this.Exception = exception; + this.Log = log; + this.Stopwatch.Stop(); + } + + /// + /// 发生的错误 + /// + public Exception Exception { get; } + /// + /// 执行SQL命令,返回的结果 + /// + public string Log { get; } + /// + /// 耗时(单位:Ticks) + /// + public long ElapsedTicks => this.Stopwatch.ElapsedTicks; + /// + /// 耗时(单位:毫秒) + /// + public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; + } + #endregion + + #region TraceBefore/After + public class TraceBeforeEventArgs : EventArgs + { + public TraceBeforeEventArgs(string operation, object value) : + this(Guid.NewGuid(), new Stopwatch(), operation, value) + { + this.Stopwatch.Start(); + } + protected TraceBeforeEventArgs(Guid identifier, Stopwatch stopwatch, string operation, object value) + { + this.Identifier = identifier; + this.Stopwatch = stopwatch; + this.Operation = operation; + this.Value = value; + } + + /// + /// 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 + /// + public Guid Identifier { get; protected set; } + protected Stopwatch Stopwatch { get; } + internal Stopwatch StopwatchInternal => Stopwatch; + public string Operation { get; } + public object Value { get; } + } + public class TraceAfterEventArgs : TraceBeforeEventArgs + { + public TraceAfterEventArgs(TraceBeforeEventArgs before, string remark, Exception exception) : + base(before.Identifier, before.StopwatchInternal, before.Operation, before.Value) + { + this.Remark = remark; + this.Exception = exception; + this.Stopwatch.Stop(); + } + + /// + /// 备注 + /// + public string Remark { get; } + /// + /// 发生的错误 + /// + public Exception Exception { get; } + /// + /// 耗时(单位:Ticks) + /// + public long ElapsedTicks => this.Stopwatch.ElapsedTicks; + /// + /// 耗时(单位:毫秒) + /// + public long ElapsedMilliseconds => this.Stopwatch.ElapsedMilliseconds; + } + #endregion } \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 3dc16e12..6a121cdb 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -486,7 +486,9 @@ namespace FreeSql.Internal if (isLeftMapType) oldMapType = tsc.SetMapTypeReturnOld(leftMapColumn.Attribute.MapType); var right = ExpressionLambdaToSql(rightExp, tsc); - if (right != "NULL" && isLeftMapType) + if (right != "NULL" && isLeftMapType && + //判断参数化后的bug + !(right.Contains('@') || right.Contains('?') || right.Contains(':'))) { var enumType = leftMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) @@ -500,7 +502,9 @@ namespace FreeSql.Internal { oldMapType = tsc.SetMapTypeReturnOld(rightMapColumn.Attribute.MapType); left = ExpressionLambdaToSql(leftExp, tsc); - if (left != "NULL" && isRightMapType) + if (left != "NULL" && isRightMapType && + //判断参数化后的bug + !(left.Contains('@') || left.Contains('?') || left.Contains(':'))) { var enumType = rightMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) @@ -560,10 +564,10 @@ namespace FreeSql.Internal { if (exp == null) return ""; if (tsc.dbParams != null && tsc.mapColumnTmp != null && tsc.mapColumnTmp.CsType.NullableTypeOrThis() != exp.Type) tsc.SetMapColumnTmp(null); - if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpression != null) + if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpressionHandler != null) { var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, tsc.CloneDisableDiyParse())); - _common._orm.Aop.ParseExpression?.Invoke(this, args); + _common._orm.Aop.ParseExpressionHandler?.Invoke(this, args); if (string.IsNullOrEmpty(args.Result) == false) return args.Result; } switch (exp.NodeType) diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 11299db6..86f0bb2e 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -17,10 +17,8 @@ namespace FreeSql.Internal.CommonProvider protected abstract void ReturnConnection(IObjectPool pool, Object conn, Exception ex); protected abstract DbCommand CreateCommand(); protected abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); - public Action AopCommandExecuting { get; set; } - public Action AopCommandExecuted { get; set; } - protected bool IsTracePerformance => AopCommandExecuted != null; + protected bool IsTracePerformance => _util?._orm?.Aop.CommandAfterHandler != null; public IObjectPool MasterPool { get; protected set; } public List> SlavePools { get; } = new List>(); @@ -35,22 +33,22 @@ namespace FreeSql.Internal.CommonProvider this.DataType = dataType; } - void LoggerException(IObjectPool pool, (DbCommand cmd, bool isclose) pc, Exception e, DateTime dt, StringBuilder logtxt, bool isThrowException = true) + void LoggerException(IObjectPool pool, (Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose) pc, Exception ex, DateTime dt, StringBuilder logtxt, bool isThrowException = true) { var cmd = pc.cmd; if (pc.isclose) pc.cmd.Connection.Close(); if (IsTracePerformance) { TimeSpan ts = DateTime.Now.Subtract(dt); - if (e == null && ts.TotalMilliseconds > 100) + if (ex == null && ts.TotalMilliseconds > 100) Trace.WriteLine(logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString()); else logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)耗时{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString(); } - if (e == null) + if (ex == null) { - AopCommandExecuted?.Invoke(cmd, logtxt.ToString()); + _util?._orm?.Aop.CommandAfterHandler?.Invoke(_util._orm, new Aop.CommandAfterEventArgs(pc.before, null, logtxt.ToString())); return; } @@ -59,7 +57,7 @@ namespace FreeSql.Internal.CommonProvider foreach (DbParameter parm in cmd.Parameters) log.Append(parm.ParameterName.PadRight(20, ' ')).Append(" = ").Append((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value).Append("\r\n"); - log.Append(e.Message); + log.Append(ex.Message); Trace.WriteLine(log.ToString()); if (cmd.Transaction != null) @@ -70,16 +68,16 @@ namespace FreeSql.Internal.CommonProvider //cmd.Transaction.Rollback(); } else - RollbackTransaction(); + RollbackTransaction(ex); } - AopCommandExecuted?.Invoke(cmd, log.ToString()); + _util?._orm?.Aop.CommandAfterHandler?.Invoke(_util._orm, new Aop.CommandAfterEventArgs(pc.before, null, logtxt.ToString())); cmd.Parameters.Clear(); if (isThrowException) { if (DataType == DataType.Sqlite) cmd.Dispose(); - throw e; + throw ex; } } @@ -547,11 +545,14 @@ namespace FreeSql.Internal.CommonProvider Object conn = null; var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); - if (IsTracePerformance) logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + if (IsTracePerformance) + { + logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt_dt = DateTime.Now; + } Exception ex = null; try { - if (IsTracePerformance) logtxt_dt = DateTime.Now; if (isSlave) { //从库查询切换,恢复 @@ -571,7 +572,7 @@ namespace FreeSql.Internal.CommonProvider { if (IsTracePerformance) logtxt_dt = DateTime.Now; ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); } LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); @@ -587,43 +588,31 @@ namespace FreeSql.Internal.CommonProvider } if (IsTracePerformance) { - logtxt.Append("Open: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt.Append("Pool.Get: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); logtxt_dt = DateTime.Now; } using (var dr = pc.cmd.ExecuteReader()) { - if (IsTracePerformance) logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); int resultIndex = 0; while (true) { while (true) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; bool isread = dr.Read(); - if (IsTracePerformance) logtxt.Append(" dr.Read: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); if (isread == false) break; if (readerHander != null) - { - object[] values = null; - if (IsTracePerformance) - { - logtxt_dt = DateTime.Now; - values = new object[dr.FieldCount]; - dr.GetValues(values); - logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - logtxt_dt = DateTime.Now; - } readerHander(dr, resultIndex); - if (IsTracePerformance) logtxt.Append(" readerHander: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n"); - } } if (++resultIndex >= multipleResult || dr.NextResult() == false) break; } - if (IsTracePerformance) logtxt_dt = DateTime.Now; dr.Close(); } - if (IsTracePerformance) logtxt.Append("ExecuteReader_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + if (IsTracePerformance) + { + logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt_dt = DateTime.Now; + } } catch (Exception ex2) { @@ -632,9 +621,12 @@ namespace FreeSql.Internal.CommonProvider if (conn != null) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + if (IsTracePerformance) + { + logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + logtxt_dt = DateTime.Now; + } } LoggerException(pool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); @@ -735,7 +727,7 @@ namespace FreeSql.Internal.CommonProvider { if (IsTracePerformance) logtxt_dt = DateTime.Now; ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); @@ -771,7 +763,7 @@ namespace FreeSql.Internal.CommonProvider { if (IsTracePerformance) logtxt_dt = DateTime.Now; ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); @@ -779,7 +771,7 @@ namespace FreeSql.Internal.CommonProvider return val; } - (DbCommand cmd, bool isclose) PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) + (Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose) PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { var dt = DateTime.Now; DbCommand cmd = CreateCommand(); @@ -800,14 +792,10 @@ namespace FreeSql.Internal.CommonProvider if (connection == null) { var tran = transaction ?? TransactionCurrentThread; - if (IsTracePerformance) logtxt.Append(" PrepareCommand_part1: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); - if (tran != null && connection == null) { - if (IsTracePerformance) dt = DateTime.Now; cmd.Connection = tran.Connection; cmd.Transaction = tran; - if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); } } else @@ -825,11 +813,12 @@ namespace FreeSql.Internal.CommonProvider } if (IsTracePerformance) dt = DateTime.Now; - AutoCommitTransaction(); - if (IsTracePerformance) logtxt.Append(" AutoCommitTransaction: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + CommitTimeoutTransaction(); + if (IsTracePerformance) logtxt.Append(" CommitTimeoutTransaction: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - AopCommandExecuting?.Invoke(cmd); - return (cmd, isclose); + var before = new Aop.CommandBeforeEventArgs(cmd); + _util?._orm?.Aop.CommandBeforeHandler?.Invoke(_util._orm, before); + return (before, cmd, isclose); } } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 694ac18c..cc93f542 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -476,11 +476,14 @@ namespace FreeSql.Internal.CommonProvider Object conn = null; var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); - if (IsTracePerformance) logtxt.Append("PrepareCommandAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + if (IsTracePerformance) + { + logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt_dt = DateTime.Now; + } Exception ex = null; try { - if (IsTracePerformance) logtxt_dt = DateTime.Now; if (isSlave) { //从库查询切换,恢复 @@ -500,7 +503,7 @@ namespace FreeSql.Internal.CommonProvider { if (IsTracePerformance) logtxt_dt = DateTime.Now; ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); } LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); @@ -516,43 +519,31 @@ namespace FreeSql.Internal.CommonProvider } if (IsTracePerformance) { - logtxt.Append("OpenAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt.Append("Pool.Get: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); logtxt_dt = DateTime.Now; } using (var dr = await pc.cmd.ExecuteReaderAsync()) { - if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); int resultIndex = 0; while (true) { while (true) { - if (IsTracePerformance) logtxt_dt = DateTime.Now; bool isread = await dr.ReadAsync(); - if (IsTracePerformance) logtxt.Append(" dr.ReadAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); if (isread == false) break; if (readerHander != null) - { - object[] values = null; - if (IsTracePerformance) - { - logtxt_dt = DateTime.Now; - values = new object[dr.FieldCount]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); - logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); - logtxt_dt = DateTime.Now; - } await readerHander(dr, resultIndex); - if (IsTracePerformance) logtxt.Append(" readerHanderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n"); - } } if (++resultIndex >= multipleResult || dr.NextResult() == false) break; } - if (IsTracePerformance) logtxt_dt = DateTime.Now; dr.Close(); } - if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + if (IsTracePerformance) + { + logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + logtxt_dt = DateTime.Now; + } } catch (Exception ex2) { @@ -563,7 +554,7 @@ namespace FreeSql.Internal.CommonProvider { if (IsTracePerformance) logtxt_dt = DateTime.Now; ReturnConnection(pool, conn, ex); //pool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); } LoggerException(pool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); @@ -665,7 +656,7 @@ namespace FreeSql.Internal.CommonProvider { if (IsTracePerformance) logtxt_dt = DateTime.Now; ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); @@ -701,7 +692,7 @@ namespace FreeSql.Internal.CommonProvider { if (IsTracePerformance) logtxt_dt = DateTime.Now; ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex); - if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); + if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms"); } LoggerException(this.MasterPool, pc, ex, dt, logtxt); pc.cmd.Parameters.Clear(); @@ -709,7 +700,7 @@ namespace FreeSql.Internal.CommonProvider return val; } - async Task<(DbCommand cmd, bool isclose)> PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) + async Task<(Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose)> PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { DateTime dt = DateTime.Now; DbCommand cmd = CreateCommand(); @@ -733,10 +724,8 @@ namespace FreeSql.Internal.CommonProvider if (tran != null) { - if (IsTracePerformance) dt = DateTime.Now; cmd.Connection = tran.Connection; cmd.Transaction = tran; - if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); } } else @@ -745,7 +734,7 @@ namespace FreeSql.Internal.CommonProvider { if (IsTracePerformance) dt = DateTime.Now; await connection.OpenAsync(); - if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpenAsync: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpen: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); isclose = true; } cmd.Connection = connection; @@ -753,10 +742,9 @@ namespace FreeSql.Internal.CommonProvider cmd.Transaction = transaction; } - if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); - - AopCommandExecuting?.Invoke(cmd); - return (cmd, isclose); + var before = new Aop.CommandBeforeEventArgs(cmd); + _util?._orm?.Aop.CommandBeforeHandler?.Invoke(_util._orm, before); + return (before, cmd, isclose); } } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index df0b0741..60133ed4 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -15,6 +15,7 @@ namespace FreeSql.Internal.CommonProvider class Transaction2 { + internal Aop.TraceBeforeEventArgs AopBefore; internal Object Conn; internal DbTransaction Transaction; internal DateTime RunTime; @@ -33,6 +34,7 @@ namespace FreeSql.Internal.CommonProvider private object _trans_lock = new object(); public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null; + public Aop.TraceBeforeEventArgs TransactionCurrentThreadAopBefore => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.AopBefore : null; public void BeginTransaction(TimeSpan timeout, IsolationLevel? isolationLevel) { @@ -41,16 +43,21 @@ namespace FreeSql.Internal.CommonProvider int tid = Thread.CurrentThread.ManagedThreadId; Transaction2 tran = null; Object conn = null; + var before = new Aop.TraceBeforeEventArgs("ThreadTransaction", isolationLevel); + _util?._orm?.Aop.TraceBeforeHandler?.Invoke(this, before); try { conn = MasterPool.Get(); tran = new Transaction2(conn, isolationLevel == null ? conn.Value.BeginTransaction() : conn.Value.BeginTransaction(isolationLevel.Value), timeout); + tran.AopBefore = before; } catch (Exception ex) { Trace.WriteLine($"数据库出错(开启事务){ex.Message} \r\n{ex.StackTrace}"); MasterPool.Return(conn); + var after = new Aop.TraceAfterEventArgs(before, "", ex); + _util?._orm?.Aop.TraceAfterHandler?.Invoke(this, after); throw ex; } if (_trans.ContainsKey(tid)) CommitTransaction(); @@ -59,17 +66,17 @@ namespace FreeSql.Internal.CommonProvider _trans.TryAdd(tid, tran); } - private void AutoCommitTransaction() + private void CommitTimeoutTransaction() { if (_trans.Count > 0) { Transaction2[] trans = null; lock (_trans_lock) trans = _trans.Values.Where(st2 => DateTime.Now.Subtract(st2.RunTime) > st2.Timeout).ToArray(); - foreach (Transaction2 tran in trans) CommitTransaction(true, tran); + foreach (Transaction2 tran in trans) CommitTransaction(true, tran, null, "Timeout自动提交"); } } - private void CommitTransaction(bool isCommit, Transaction2 tran) + private void CommitTransaction(bool isCommit, Transaction2 tran, Exception rollbackException, string remark = null) { if (tran == null || tran.Transaction == null || tran.Transaction.Connection == null) return; @@ -79,29 +86,34 @@ namespace FreeSql.Internal.CommonProvider _trans.TryRemove(tran.Conn.LastGetThreadId, out var oldtran); Exception ex = null; - var f001 = isCommit ? "提交" : "回滚"; + if (string.IsNullOrEmpty(remark)) remark = isCommit ? "提交" : "回滚"; try { - Trace.WriteLine($"线程{tran.Conn.LastGetThreadId}事务{f001}"); + Trace.WriteLine($"线程{tran.Conn.LastGetThreadId}事务{remark}"); if (isCommit) tran.Transaction.Commit(); else tran.Transaction.Rollback(); } catch (Exception ex2) { ex = ex2; - Trace.WriteLine($"数据库出错({f001}事务):{ex.Message} {ex.StackTrace}"); + Trace.WriteLine($"数据库出错({remark}事务):{ex.Message} {ex.StackTrace}"); } finally { ReturnConnection(MasterPool, tran.Conn, ex); //MasterPool.Return(tran.Conn, ex); + + var after = new Aop.TraceAfterEventArgs(tran.AopBefore, remark, ex ?? rollbackException); + _util?._orm?.Aop.TraceAfterHandler?.Invoke(this, after); } } - private void CommitTransaction(bool isCommit) + public void CommitTransaction() { - if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(isCommit, tran); + if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(true, tran, null); + } + public void RollbackTransaction(Exception ex) + { + if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(false, tran, ex); } - public void CommitTransaction() => CommitTransaction(true); - public void RollbackTransaction() => CommitTransaction(false); public void Transaction(Action handler) => TransactionInternal(null, TimeSpan.FromSeconds(60), handler); public void Transaction(TimeSpan timeout, Action handler) => TransactionInternal(null, timeout, handler); @@ -117,7 +129,7 @@ namespace FreeSql.Internal.CommonProvider } catch (Exception ex) { - RollbackTransaction(); + RollbackTransaction(ex); throw ex; } } @@ -132,7 +144,7 @@ namespace FreeSql.Internal.CommonProvider Transaction2[] trans = null; lock (_trans_lock) trans = _trans.Values.ToArray(); - foreach (Transaction2 tran in trans) CommitTransaction(false, tran); + foreach (Transaction2 tran in trans) CommitTransaction(false, tran, null, "Dispose自动提交"); } catch { } diff --git a/FreeSql/Internal/CommonProvider/AopProvider.cs b/FreeSql/Internal/CommonProvider/AopProvider.cs index 168a0dcf..1f426e04 100644 --- a/FreeSql/Internal/CommonProvider/AopProvider.cs +++ b/FreeSql/Internal/CommonProvider/AopProvider.cs @@ -8,13 +8,38 @@ namespace FreeSql.Internal.CommonProvider { public class AopProvider : IAop { - public EventHandler ParseExpression { get; set; } - public EventHandler ConfigEntity { get; set; } - public EventHandler ConfigEntityProperty { get; set; } - public EventHandler CurdBefore { get; set; } - public EventHandler CurdAfter { get; set; } - public EventHandler SyncStructureBefore { get; set; } - public EventHandler SyncStructureAfter { get; set; } - public EventHandler AuditValue { get; set; } + public event EventHandler ParseExpression; + public event EventHandler ConfigEntity; + public event EventHandler ConfigEntityProperty; + + public event EventHandler CurdBefore; + public event EventHandler CurdAfter; + public event EventHandler SyncStructureBefore; + public event EventHandler SyncStructureAfter; + + public event EventHandler AuditValue; + + public event EventHandler CommandBefore; + public event EventHandler CommandAfter; + public event EventHandler TraceBefore; + public event EventHandler TraceAfter; + + //------------- Handler + + public EventHandler ParseExpressionHandler => ParseExpression; + public EventHandler ConfigEntityHandler => ConfigEntity; + public EventHandler ConfigEntityPropertyHandler => ConfigEntityProperty; + + public EventHandler CurdBeforeHandler => CurdBefore; + public EventHandler CurdAfterHandler => CurdAfter; + public EventHandler SyncStructureBeforeHandler => SyncStructureBefore; + public EventHandler SyncStructureAfterHandler => SyncStructureAfter; + + public EventHandler AuditValueHandler => AuditValue; + + public EventHandler CommandBeforeHandler => CommandBefore; + public EventHandler CommandAfterHandler => CommandAfter; + public EventHandler TraceBeforeHandler => TraceBefore; + public EventHandler TraceAfterHandler => TraceAfter; } } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index cf1cf470..83cdd9e6 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -84,7 +84,7 @@ namespace FreeSql.Internal.CommonProvider .Select(a => (a.entityType, GetTableNameLowerOrUpper(a.tableName))).ToArray(); if (syncObjects.Any() == false) return false; var before = new Aop.SyncStructureBeforeEventArgs(syncObjects.Select(a => a.entityType).ToArray()); - _orm.Aop.SyncStructureBefore?.Invoke(this, before); + _orm.Aop.SyncStructureBeforeHandler?.Invoke(this, before); Exception exception = null; string ddl = null; try @@ -110,7 +110,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.SyncStructureAfterEventArgs(before, ddl, exception); - _orm.Aop.SyncStructureAfter?.Invoke(this, after); + _orm.Aop.SyncStructureAfterHandler?.Invoke(this, after); } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index bacd113f..516b75f0 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -63,7 +63,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(sql)) return 0; var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -78,7 +78,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return affrows; diff --git a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs index 9860c999..45afc9d5 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs @@ -19,7 +19,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(sql)) return 0; var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -34,7 +34,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return affrows; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 34bbeb15..794bd98e 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -121,7 +121,7 @@ namespace FreeSql.Internal.CommonProvider source = source.Where(a => a != null).ToList(); AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); _source.AddRange(source); - + } return this; } @@ -151,10 +151,10 @@ namespace FreeSql.Internal.CommonProvider } } } - if (orm.Aop.AuditValue != null) + if (orm.Aop.AuditValueHandler != null) { var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); - orm.Aop.AuditValue(sender, auditArgs); + orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.IsChanged) { col.SetMapValue(data, val = auditArgs.Value); @@ -208,35 +208,55 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null || _batchAutoTransaction == false) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrows", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - ret += this.RawExecuteAffrows(); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += this.RawExecuteAffrows(); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += this.RawExecuteAffrows(); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = _orm.Ado.MasterPool.Get()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret += this.RawExecuteAffrows(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -260,37 +280,57 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null || _batchAutoTransaction == false) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteIdentity", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - if (a < ss.Length - 1) this.RawExecuteAffrows(); - else ret = this.RawExecuteIdentity(); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) this.RawExecuteAffrows(); + else ret = this.RawExecuteIdentity(); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) this.RawExecuteAffrows(); + else ret = this.RawExecuteIdentity(); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = _orm.Ado.MasterPool.Get()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - if (a < ss.Length - 1) this.RawExecuteAffrows(); - else ret = this.RawExecuteIdentity(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -314,35 +354,55 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null || _batchAutoTransaction == false) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteInserted", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - ret.AddRange(this.RawExecuteInserted()); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(this.RawExecuteInserted()); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(this.RawExecuteInserted()); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = _orm.Ado.MasterPool.Get()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret.AddRange(this.RawExecuteInserted()); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -353,7 +413,7 @@ namespace FreeSql.Internal.CommonProvider { var sql = ToSql(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -368,7 +428,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return affrows; } @@ -507,4 +567,3 @@ namespace FreeSql.Internal.CommonProvider } } } - diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index 14c5cff7..0f6d77d1 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -34,35 +34,55 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrowsAsync", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -86,42 +106,62 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteIdentityAsync", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); - else ret = await this.RawExecuteIdentityAsync(); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); + else ret = await this.RawExecuteIdentityAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); + else ret = await this.RawExecuteIdentityAsync(); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); - else ret = await this.RawExecuteIdentityAsync(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; } - + async protected Task> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) { var ss = SplitSource(valuesLimit, parameterLimit); @@ -140,35 +180,55 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteInsertedAsync", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - ret.AddRange(await this.RawExecuteInsertedAsync()); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteInsertedAsync()); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteInsertedAsync()); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret.AddRange(await this.RawExecuteInsertedAsync()); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -178,7 +238,7 @@ namespace FreeSql.Internal.CommonProvider { var sql = ToSql(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -193,7 +253,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return affrows; } @@ -207,4 +267,3 @@ namespace FreeSql.Internal.CommonProvider #endif } } - diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 53e1acae..3915bb22 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -299,7 +299,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(field); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); DataTable ret = null; Exception exception = null; try @@ -314,7 +314,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -325,7 +325,7 @@ namespace FreeSql.Internal.CommonProvider var type = typeof(TTuple); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); var flagStr = $"ToListField:{field}"; Exception exception = null; @@ -345,7 +345,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -353,7 +353,7 @@ namespace FreeSql.Internal.CommonProvider { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -377,7 +377,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } foreach (var include in _includeToList) include?.Invoke(ret); _trackToList?.Invoke(ret); @@ -403,7 +403,7 @@ namespace FreeSql.Internal.CommonProvider { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); var retCount = 0; Exception exception = null; @@ -444,7 +444,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, retCount); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } if (ret.Any() || checkDoneTimes == 0) { @@ -492,7 +492,7 @@ namespace FreeSql.Internal.CommonProvider var type = typeof(TReturn); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -514,7 +514,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } if (typeof(TReturn) == typeof(T1)) foreach (var include in _includeToList) include?.Invoke(ret); @@ -1082,7 +1082,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.InternalToSql(select); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); DataTable ret = null; Exception exception = null; try @@ -1097,7 +1097,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -1142,7 +1142,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.ToSql(field); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); DataTable ret = null; Exception exception = null; try @@ -1157,7 +1157,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -1168,7 +1168,7 @@ namespace FreeSql.Internal.CommonProvider var type = typeof(TTuple); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); var flagStr = $"ToListField:{field}"; Exception exception = null; @@ -1189,7 +1189,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -1198,7 +1198,7 @@ namespace FreeSql.Internal.CommonProvider { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -1223,7 +1223,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } foreach (var include in _includeToListAsync) await include?.Invoke(ret); _trackToList?.Invoke(ret); @@ -1265,7 +1265,7 @@ namespace FreeSql.Internal.CommonProvider var type = typeof(TReturn); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -1288,7 +1288,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } if (typeof(TReturn) == typeof(T1)) foreach (var include in _includeToListAsync) await include?.Invoke(ret); @@ -1328,7 +1328,7 @@ namespace FreeSql.Internal.CommonProvider var sql = this.InternalToSql(select); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); DataTable ret = null; Exception exception = null; try @@ -1343,7 +1343,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index ce44bcba..629c4c63 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -150,35 +150,55 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null || _batchAutoTransaction == false) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrows", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - ret += this.RawExecuteAffrows(); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += this.RawExecuteAffrows(); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += this.RawExecuteAffrows(); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = _orm.Ado.MasterPool.Get()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret += this.RawExecuteAffrows(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -197,35 +217,55 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null || _batchAutoTransaction == false) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteUpdated", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - ret.AddRange(this.RawExecuteUpdated()); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(this.RawExecuteUpdated()); + } + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(this.RawExecuteUpdated()); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = _orm.Ado.MasterPool.Get()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret.AddRange(this.RawExecuteUpdated()); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -238,7 +278,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(sql)) return 0; var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -254,7 +294,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return affrows; } @@ -289,7 +329,7 @@ namespace FreeSql.Internal.CommonProvider public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data?.Any() != true) return; - if (orm.Aop.AuditValue == null) return; + if (orm.Aop.AuditValueHandler == null) return; foreach (var d in data) { if (d == null) continue; @@ -297,7 +337,7 @@ namespace FreeSql.Internal.CommonProvider { object val = col.GetMapValue(d); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); - orm.Aop.AuditValue(sender, auditArgs); + orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.IsChanged) { col.SetMapValue(d, val = auditArgs.Value); @@ -309,13 +349,13 @@ namespace FreeSql.Internal.CommonProvider } public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) { - if (orm.Aop.AuditValue == null) return; + if (orm.Aop.AuditValueHandler == null) return; if (data == null) return; foreach (var col in table.Columns.Values) { object val = col.GetMapValue(data); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); - orm.Aop.AuditValue(sender, auditArgs); + orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.IsChanged) { col.SetMapValue(data, val = auditArgs.Value); @@ -605,7 +645,7 @@ namespace FreeSql.Internal.CommonProvider else if (_source.Count > 1) { //批量保存 Source if (_table.Primarys.Any() == false) return null; - + var caseWhen = new StringBuilder(); caseWhen.Append("CASE "); ToSqlCase(caseWhen, _table.Primarys); @@ -698,4 +738,4 @@ namespace FreeSql.Internal.CommonProvider return sb.ToString(); } } -} \ No newline at end of file +} diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index 5d2767f0..87ca9d41 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -30,35 +30,55 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrowsAsync", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret += await this.RawExecuteAffrowsAsync(); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret += await this.RawExecuteAffrowsAsync(); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -76,35 +96,55 @@ namespace FreeSql.Internal.CommonProvider if (_transaction == null) this.WithTransaction(_orm.Ado.TransactionCurrentThread); - if (_transaction != null) + var before = new Aop.TraceBeforeEventArgs("SplitExecuteUpdatedAsync", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try { - for (var a = 0; a < ss.Length; a++) + if (_transaction != null || _batchAutoTransaction == false) { - _source = ss[a]; - ret.AddRange(await this.RawExecuteUpdatedAsync()); + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteUpdatedAsync()); + } + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + ret.AddRange(await this.RawExecuteUpdatedAsync()); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } } } - else + catch (Exception ex) { - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - ret.AddRange(await this.RawExecuteUpdatedAsync()); - } - _transaction.Commit(); - } - catch - { - _transaction.Rollback(); - throw; - } - _transaction = null; - } + exception = ex; + throw ex; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); } ClearData(); return ret; @@ -116,7 +156,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(sql)) return 0; var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -132,7 +172,7 @@ namespace FreeSql.Internal.CommonProvider finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return affrows; } @@ -142,4 +182,4 @@ namespace FreeSql.Internal.CommonProvider public abstract Task> ExecuteUpdatedAsync(); #endif } -} \ No newline at end of file +} diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index f695b8aa..cbab8e0a 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -100,10 +100,10 @@ namespace FreeSql.Internal public TableAttribute GetEntityTableAttribute(Type type) { TableAttribute attr = null; - if (_orm.Aop.ConfigEntity != null) + if (_orm.Aop.ConfigEntityHandler != null) { var aope = new Aop.ConfigEntityEventArgs(type); - _orm.Aop.ConfigEntity(_orm, aope); + _orm.Aop.ConfigEntityHandler(_orm, aope); attr = aope.ModifyResult; } if (attr == null) attr = new TableAttribute(); @@ -130,10 +130,10 @@ namespace FreeSql.Internal public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) { ColumnAttribute attr = null; - if (_orm.Aop.ConfigEntityProperty != null) + if (_orm.Aop.ConfigEntityPropertyHandler != null) { var aope = new Aop.ConfigEntityPropertyEventArgs(type, proto); - _orm.Aop.ConfigEntityProperty(_orm, aope); + _orm.Aop.ConfigEntityPropertyHandler(_orm, aope); attr = aope.ModifyResult; } if (attr == null) attr = new ColumnAttribute(); @@ -219,10 +219,10 @@ namespace FreeSql.Internal public IndexAttribute[] GetEntityIndexAttribute(Type type) { var ret = new Dictionary(); - if (_orm.Aop.ConfigEntity != null) + if (_orm.Aop.ConfigEntityHandler != null) { var aope = new Aop.ConfigEntityEventArgs(type); - _orm.Aop.ConfigEntity(_orm, aope); + _orm.Aop.ConfigEntityHandler(_orm, aope); foreach (var idxattr in aope.ModifyIndexResult) if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields)) { diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs index 1ab68770..012931a7 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs @@ -31,7 +31,7 @@ namespace FreeSql.MsAccess.Curd { var sql = this.ToSql(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -46,7 +46,7 @@ namespace FreeSql.MsAccess.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return affrows; } @@ -56,7 +56,7 @@ namespace FreeSql.MsAccess.Curd if (string.IsNullOrEmpty(sql)) return 0; var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT @@identity;"), _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; var isUseConnection = _connection != null; @@ -86,7 +86,7 @@ namespace FreeSql.MsAccess.Curd { if (isUseConnection == false) _connection = null; var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -110,7 +110,7 @@ namespace FreeSql.MsAccess.Curd { var sql = this.ToSql(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -125,7 +125,7 @@ namespace FreeSql.MsAccess.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return affrows; } @@ -135,7 +135,7 @@ namespace FreeSql.MsAccess.Curd if (string.IsNullOrEmpty(sql)) return 0; var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT @@identity;"), _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; var isUseConnection = _connection != null; @@ -165,7 +165,7 @@ namespace FreeSql.MsAccess.Curd { if (isUseConnection == false) _connection = null; var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index 60949a68..296a6fd3 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -33,7 +33,7 @@ namespace FreeSql.MySql.Curd sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -48,7 +48,7 @@ namespace FreeSql.MySql.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; @@ -74,7 +74,7 @@ namespace FreeSql.MySql.Curd sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -89,7 +89,7 @@ namespace FreeSql.MySql.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index f84783fe..190e6b7e 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -48,7 +48,7 @@ namespace FreeSql.MySql.Curd sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -63,7 +63,7 @@ namespace FreeSql.MySql.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -84,7 +84,7 @@ namespace FreeSql.MySql.Curd } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -99,7 +99,7 @@ namespace FreeSql.MySql.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -117,7 +117,7 @@ namespace FreeSql.MySql.Curd sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -132,7 +132,7 @@ namespace FreeSql.MySql.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -153,7 +153,7 @@ namespace FreeSql.MySql.Curd } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -168,7 +168,7 @@ namespace FreeSql.MySql.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index b208affd..084553f0 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -46,7 +46,7 @@ namespace FreeSql.MySql.Curd sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -62,7 +62,7 @@ namespace FreeSql.MySql.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -127,7 +127,7 @@ namespace FreeSql.MySql.Curd sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -143,7 +143,7 @@ namespace FreeSql.MySql.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs index 9804ce92..883630c8 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -117,7 +117,7 @@ namespace FreeSql.MySql.Curd if (string.IsNullOrEmpty(sql)) return 0; var before = new CurdBeforeEventArgs(_mysqlInsert.InternalTable.Type, _mysqlInsert.InternalTable, CurdType.Insert, sql, _mysqlInsert.InternalParams); - _mysqlInsert.InternalOrm.Aop.CurdBefore?.Invoke(_mysqlInsert, before); + _mysqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_mysqlInsert, before); long ret = 0; Exception exception = null; try @@ -132,7 +132,7 @@ namespace FreeSql.MySql.Curd finally { var after = new CurdAfterEventArgs(before, exception, ret); - _mysqlInsert.InternalOrm.Aop.CurdAfter?.Invoke(_mysqlInsert, after); + _mysqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_mysqlInsert, after); ClearData(); } return ret; @@ -146,7 +146,7 @@ namespace FreeSql.MySql.Curd if (string.IsNullOrEmpty(sql)) return 0; var before = new CurdBeforeEventArgs(_mysqlInsert.InternalTable.Type, _mysqlInsert.InternalTable, CurdType.Insert, sql, _mysqlInsert.InternalParams); - _mysqlInsert.InternalOrm.Aop.CurdBefore?.Invoke(_mysqlInsert, before); + _mysqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_mysqlInsert, before); long ret = 0; Exception exception = null; try @@ -161,7 +161,7 @@ namespace FreeSql.MySql.Curd finally { var after = new CurdAfterEventArgs(before, exception, ret); - _mysqlInsert.InternalOrm.Aop.CurdAfter?.Invoke(_mysqlInsert, after); + _mysqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_mysqlInsert, after); ClearData(); } return ret; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index 177f36e8..6b6c5565 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -97,7 +97,7 @@ namespace FreeSql.Odbc.Dameng if (_identCol == null || _source.Count > 1) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); @@ -110,7 +110,7 @@ namespace FreeSql.Odbc.Dameng finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } @@ -120,7 +120,7 @@ namespace FreeSql.Odbc.Dameng sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); @@ -134,7 +134,7 @@ namespace FreeSql.Odbc.Dameng finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -167,7 +167,7 @@ namespace FreeSql.Odbc.Dameng if (_identCol == null || _source.Count > 1) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); @@ -180,7 +180,7 @@ namespace FreeSql.Odbc.Dameng finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } @@ -190,7 +190,7 @@ namespace FreeSql.Odbc.Dameng sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); @@ -204,7 +204,7 @@ namespace FreeSql.Odbc.Dameng finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index 44cc9c5e..dddd0cf0 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -30,7 +30,7 @@ namespace FreeSql.Odbc.Default Object poolConn = null; var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, $"; {_utils.Adapter.InsertAfterGetIdentitySql}"), _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -56,7 +56,7 @@ namespace FreeSql.Odbc.Default _orm.Ado.MasterPool.Return(poolConn); var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -76,7 +76,7 @@ namespace FreeSql.Odbc.Default Object poolConn = null; var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, $"; {_utils.Adapter.InsertAfterGetIdentitySql}"), _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -102,7 +102,7 @@ namespace FreeSql.Odbc.Default _orm.Ado.MasterPool.Return(poolConn); var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs index b017e33d..8036e82a 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs @@ -33,7 +33,7 @@ namespace FreeSql.Odbc.GBase if (identCols.Any() == false) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); @@ -46,13 +46,13 @@ namespace FreeSql.Odbc.GBase finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); @@ -65,7 +65,7 @@ namespace FreeSql.Odbc.GBase finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -99,7 +99,7 @@ namespace FreeSql.Odbc.GBase if (identCols.Any() == false) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); @@ -112,13 +112,13 @@ namespace FreeSql.Odbc.GBase finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); @@ -131,7 +131,7 @@ namespace FreeSql.Odbc.GBase finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index c10fcb88..a81acc88 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -33,7 +33,7 @@ namespace FreeSql.Odbc.MySql sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -48,7 +48,7 @@ namespace FreeSql.Odbc.MySql finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; @@ -74,7 +74,7 @@ namespace FreeSql.Odbc.MySql sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -89,7 +89,7 @@ namespace FreeSql.Odbc.MySql finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index d90e0ec4..41b4b0bf 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -29,7 +29,7 @@ namespace FreeSql.Odbc.MySql Object poolConn = null; var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -55,7 +55,7 @@ namespace FreeSql.Odbc.MySql _orm.Ado.MasterPool.Return(poolConn); var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -76,7 +76,7 @@ namespace FreeSql.Odbc.MySql } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -91,7 +91,7 @@ namespace FreeSql.Odbc.MySql finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -109,7 +109,7 @@ namespace FreeSql.Odbc.MySql Object poolConn = null; var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -135,7 +135,7 @@ namespace FreeSql.Odbc.MySql _orm.Ado.MasterPool.Return(poolConn); var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -156,7 +156,7 @@ namespace FreeSql.Odbc.MySql } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -171,7 +171,7 @@ namespace FreeSql.Odbc.MySql finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index b0892779..4613ed9d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -40,7 +40,7 @@ namespace FreeSql.Odbc.MySql sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -56,7 +56,7 @@ namespace FreeSql.Odbc.MySql finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -121,7 +121,7 @@ namespace FreeSql.Odbc.MySql sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -137,7 +137,7 @@ namespace FreeSql.Odbc.MySql finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index 0e97103b..ac7cb08e 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -97,7 +97,7 @@ namespace FreeSql.Odbc.Oracle if (_identCol == null || _source.Count > 1) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); @@ -110,7 +110,7 @@ namespace FreeSql.Odbc.Oracle finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } @@ -120,7 +120,7 @@ namespace FreeSql.Odbc.Oracle sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); @@ -134,7 +134,7 @@ namespace FreeSql.Odbc.Oracle finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -167,7 +167,7 @@ namespace FreeSql.Odbc.Oracle if (_identCol == null || _source.Count > 1) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); @@ -180,7 +180,7 @@ namespace FreeSql.Odbc.Oracle finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } @@ -190,7 +190,7 @@ namespace FreeSql.Odbc.Oracle sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); @@ -204,7 +204,7 @@ namespace FreeSql.Odbc.Oracle finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index 1fe6c5ee..0d50f9dc 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -33,7 +33,7 @@ namespace FreeSql.Odbc.PostgreSQL sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -48,7 +48,7 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; @@ -74,7 +74,7 @@ namespace FreeSql.Odbc.PostgreSQL sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -89,7 +89,7 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index 3431e614..a2a2a2a2 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -33,7 +33,7 @@ namespace FreeSql.Odbc.PostgreSQL if (identCols.Any() == false) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); @@ -46,13 +46,13 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); @@ -65,7 +65,7 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -87,7 +87,7 @@ namespace FreeSql.Odbc.PostgreSQL } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -102,7 +102,7 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -126,7 +126,7 @@ namespace FreeSql.Odbc.PostgreSQL if (identCols.Any() == false) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); @@ -139,13 +139,13 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); @@ -158,7 +158,7 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -179,7 +179,7 @@ namespace FreeSql.Odbc.PostgreSQL } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -194,7 +194,7 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index fb8ce06a..8bb51100 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -39,7 +39,7 @@ namespace FreeSql.Odbc.PostgreSQL sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -55,7 +55,7 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -129,7 +129,7 @@ namespace FreeSql.Odbc.PostgreSQL sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -145,7 +145,7 @@ namespace FreeSql.Odbc.PostgreSQL finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index 6cee6f44..6370377c 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; @@ -84,7 +84,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -99,7 +99,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 5bd211c0..d134cfe0 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -26,7 +26,7 @@ namespace FreeSql.Odbc.SqlServer var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -41,7 +41,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return affrows; } @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.SqlServer sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -68,7 +68,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -105,7 +105,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -120,7 +120,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -136,7 +136,7 @@ namespace FreeSql.Odbc.SqlServer var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var affrows = 0; Exception exception = null; try @@ -151,7 +151,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return affrows; } @@ -163,7 +163,7 @@ namespace FreeSql.Odbc.SqlServer sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -178,7 +178,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -215,7 +215,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -230,7 +230,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index c6b1f146..3af0446f 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -44,7 +44,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -60,7 +60,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -128,7 +128,7 @@ namespace FreeSql.Odbc.SqlServer sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -144,7 +144,7 @@ namespace FreeSql.Odbc.SqlServer finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index da9c4f0e..71ad77dc 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -99,7 +99,7 @@ namespace FreeSql.Oracle.Curd if (_identCol == null || _source.Count > 1) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); @@ -112,7 +112,7 @@ namespace FreeSql.Oracle.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } @@ -122,7 +122,7 @@ namespace FreeSql.Oracle.Curd sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); @@ -136,7 +136,7 @@ namespace FreeSql.Oracle.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -168,7 +168,7 @@ namespace FreeSql.Oracle.Curd if (_identCol == null || _source.Count > 1) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); @@ -181,7 +181,7 @@ namespace FreeSql.Oracle.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } @@ -191,7 +191,7 @@ namespace FreeSql.Oracle.Curd sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); @@ -205,7 +205,7 @@ namespace FreeSql.Oracle.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index bedded9d..c4d87aed 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -156,7 +156,7 @@ namespace FreeSql.PostgreSQL.Curd if (string.IsNullOrEmpty(sql)) return 0; var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); - _pgsqlInsert.InternalOrm.Aop.CurdBefore?.Invoke(_pgsqlInsert, before); + _pgsqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_pgsqlInsert, before); long ret = 0; Exception exception = null; try @@ -171,7 +171,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new CurdAfterEventArgs(before, exception, ret); - _pgsqlInsert.InternalOrm.Aop.CurdAfter?.Invoke(_pgsqlInsert, after); + _pgsqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_pgsqlInsert, after); ClearData(); } return ret; @@ -185,7 +185,7 @@ namespace FreeSql.PostgreSQL.Curd if (string.IsNullOrEmpty(sql)) return 0; var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); - _pgsqlInsert.InternalOrm.Aop.CurdBefore?.Invoke(_pgsqlInsert, before); + _pgsqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_pgsqlInsert, before); long ret = 0; Exception exception = null; try @@ -200,7 +200,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new CurdAfterEventArgs(before, exception, ret); - _pgsqlInsert.InternalOrm.Aop.CurdAfter?.Invoke(_pgsqlInsert, after); + _pgsqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_pgsqlInsert, after); ClearData(); } return ret; diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index b4586c2d..9a275042 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -33,7 +33,7 @@ namespace FreeSql.PostgreSQL.Curd sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -48,7 +48,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; @@ -74,7 +74,7 @@ namespace FreeSql.PostgreSQL.Curd sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -89,7 +89,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index da3f8675..d010dd01 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -46,7 +46,7 @@ namespace FreeSql.PostgreSQL.Curd if (identCols.Any() == false) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); @@ -59,13 +59,13 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); @@ -78,7 +78,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -100,7 +100,7 @@ namespace FreeSql.PostgreSQL.Curd } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -115,7 +115,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -139,7 +139,7 @@ namespace FreeSql.PostgreSQL.Curd if (identCols.Any() == false) { before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); @@ -152,13 +152,13 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return 0; } sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); @@ -171,7 +171,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -192,7 +192,7 @@ namespace FreeSql.PostgreSQL.Curd } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -207,7 +207,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index ea1320c7..4d7f248f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -47,7 +47,7 @@ namespace FreeSql.PostgreSQL.Curd sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -63,7 +63,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -139,7 +139,7 @@ namespace FreeSql.PostgreSQL.Curd sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -155,7 +155,7 @@ namespace FreeSql.PostgreSQL.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index 6548ba9e..175084a9 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -53,7 +53,7 @@ namespace FreeSql.SqlServer.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; @@ -84,7 +84,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -99,7 +99,7 @@ namespace FreeSql.SqlServer.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } this.ClearData(); return ret; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index ba66255e..36dd6f17 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -38,7 +38,7 @@ namespace FreeSql.SqlServer.Curd sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -53,7 +53,7 @@ namespace FreeSql.SqlServer.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -89,7 +89,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -104,7 +104,7 @@ namespace FreeSql.SqlServer.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -122,7 +122,7 @@ namespace FreeSql.SqlServer.Curd sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -137,7 +137,7 @@ namespace FreeSql.SqlServer.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -173,7 +173,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -188,7 +188,7 @@ namespace FreeSql.SqlServer.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index bfb9e139..d2ea517c 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -45,7 +45,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -61,7 +61,7 @@ namespace FreeSql.SqlServer.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -129,7 +129,7 @@ namespace FreeSql.SqlServer.Curd sql = sb.ToString(); var dbParms = _params.Concat(_paramsSource).ToArray(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try @@ -145,7 +145,7 @@ namespace FreeSql.SqlServer.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index b0209b36..d3ac22ba 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -27,7 +27,7 @@ namespace FreeSql.Sqlite.Curd sql = string.Concat(sql, "; SELECT last_insert_rowid();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -42,7 +42,7 @@ namespace FreeSql.Sqlite.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } @@ -70,7 +70,7 @@ namespace FreeSql.Sqlite.Curd sql = string.Concat(sql, "; SELECT last_insert_rowid();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBefore?.Invoke(this, before); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try @@ -85,7 +85,7 @@ namespace FreeSql.Sqlite.Curd finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfter?.Invoke(this, after); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } From f0bd6cc625fa448c4833ec557846b0d9d38015c0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 2 Mar 2020 20:57:56 +0800 Subject: [PATCH 0447/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20Ado.AopComma?= =?UTF-8?q?ndExecuting/AopCommandExecuted=20=E5=88=B0=20Aop.CommandBefore/?= =?UTF-8?q?After=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ++ FreeSql/FreeSql.xml | 131 ------------------------ FreeSql/FreeSqlBuilder.cs | 18 ++-- 3 files changed, 17 insertions(+), 139 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2735cefb..ca7c357b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 08d2c1b3..784479be 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2260,137 +2260,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 9309609d..26720246 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -249,14 +249,16 @@ namespace FreeSql ret.CodeFirst.IsGenerateCommandParameterWithLambda = _isGenerateCommandParameterWithLambda; ret.CodeFirst.IsLazyLoading = _isLazyLoading; - ret.Aop.CommandBefore += new EventHandler((s, e) => - { - _aopCommandExecuting(e.Command); - }); - ret.Aop.CommandAfter += new EventHandler((s, e) => - { - _aopCommandExecuted(e.Command, e.Log); - }); + if (_aopCommandExecuting != null) + ret.Aop.CommandBefore += new EventHandler((s, e) => + { + _aopCommandExecuting?.Invoke(e.Command); + }); + if (_aopCommandExecuted != null) + ret.Aop.CommandAfter += new EventHandler((s, e) => + { + _aopCommandExecuted?.Invoke(e.Command, e.Log); + }); //添加实体属性名全局AOP转换处理 if (_entityPropertyConvertType != StringConvertType.None) From a45cfff5f696c4c51fa4455c29e5f4a0f8925739 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 3 Mar 2020 12:36:44 +0800 Subject: [PATCH 0448/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ToList=20?= =?UTF-8?q?=E7=88=B6=E5=AD=90=E5=AF=BC=E8=88=AA=E5=8F=AF=E8=83=BD=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 50 +++++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 94 +++++++++++++ FreeSql/FreeSql.xml | 131 ++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 3 +- 4 files changed, 277 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index d6732b50..6750270a 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -212,6 +212,56 @@ + + + 父级 + + + + + 创建人 + + + + + 创建时间 + + + + + 备注 + + + + + 菜单名称 + + + + + 英文名称 + + + + + 链接地址 + + + + + 父级菜单 一级为 0 + + + + + 按钮操作 逗号分隔 + + + + + 导航属性 + + 调价单 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index c468a7a7..49ecb36e 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -44,9 +44,103 @@ namespace FreeSql.Tests public DbSet Authors { get; set; } } + /// + /// 父级 + /// + public class BaseModel + { + [Column(IsPrimary = true)] + public string ID { get; set; } + + /// + /// 创建人 + /// + public string UserID { get; set; } = "Admin"; + + /// + /// 创建时间 + /// + [Column(ServerTime = DateTimeKind.Utc)] + public DateTime CreateTime { get; set; } + + /// + /// 备注 + /// + public string Description { get; set; } + } + public class Menu : BaseModel + { + public string SubNameID { get; set; } + + /// + /// 菜单名称 + /// + public string Name { get; set; } + + /// + /// 英文名称 + /// + public string EnName { get; set; } + + /// + /// 链接地址 + /// + public string Url { get; set; } + + /// + /// 父级菜单 一级为 0 + /// + public string ParentID { get; set; } + + /// + /// 按钮操作 逗号分隔 + /// + public string OperationIds { get; set; } + + /// + /// 导航属性 + /// + public virtual Menu Parent { get; set; } + + + [Column(IsIgnore = true)] + public string OperationNames { get; set; } + + [Column(IsIgnore = true)] + public string SystemName { get; set; } + + } + class SubSystem + { + public string Id { get; set; } + public string Name { get; set; } + } + [Fact] public void Test03() { + var subSyetemId = "xxx"; + var list = g.sqlite.Select() + .LeftJoin((a,b) => a.SubNameID == b.Id) + .WhereIf(!string.IsNullOrEmpty(subSyetemId), (a, s) => a.SubNameID == subSyetemId) + .ToList((a, s) => new Menu + { + ID = a.ID, + SystemName = s.Name, + SubNameID = s.Id, + CreateTime = a.CreateTime, + Description = a.Description, + EnName = a.EnName, + Name = a.Name, + OperationIds = a.OperationIds, + Parent = a.Parent, + ParentID = a.ParentID, + Url = a.Url, + UserID = a.UserID + }); + + + var context = new TestDbContext(g.sqlite); var sql = context.Songs diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 784479be..08d2c1b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2260,6 +2260,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 }) + + + + + + 可自定义解析表达式 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6a121cdb..f9e424d1 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1140,7 +1140,8 @@ namespace FreeSql.Internal if (tsc.style == ExpressionStyle.SelectColumns) { finds = tsc._tables.Where(a => a.Table.Type == tbtmp.Type && a.Alias == alias).ToArray(); - if (finds.Length != 1) finds = tsc._tables.Where(a => a.Table.Type == tbtmp.Type).ToArray(); + if (finds.Any() == false && alias.Contains("__") == false) + finds = tsc._tables.Where(a => a.Table.Type == tbtmp.Type).ToArray(); if (finds.Any()) finds = new[] { finds.First() }; } if (finds.Length != 1 && isa && parmExp != null) From 34ba9fbf4f5d951912db7c13eca0d4651082399d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 3 Mar 2020 16:44:52 +0800 Subject: [PATCH 0449/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20Include=20?= =?UTF-8?q?=E5=8F=8B=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/CommonProvider/SelectProvider/Select1Provider.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 255ad8ee..fa3287cc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -354,6 +354,8 @@ namespace FreeSql.Internal.CommonProvider { var expBody = navigateSelector?.Body; if (expBody == null) return this; + if (expBody.NodeType != ExpressionType.MemberAccess) throw new Exception("Include 参数类型错误,表达式类型应该为 MemberAccess"); + if (typeof(IEnumerable).IsAssignableFrom(expBody.Type)) throw new Exception("Include 参数类型错误,集合属性请使用 IncludeMany"); var tb = _commonUtils.GetTableByEntity(expBody.Type); if (tb == null) throw new Exception("Include 参数类型错误"); From 780b963267cbde2b34acbb2528812610962c483d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 4 Mar 2020 13:10:17 +0800 Subject: [PATCH 0450/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E8=AF=BB?= =?UTF-8?q?=E5=86=99=E5=88=86=E7=A6=BB=E5=88=9B=E5=BB=BA=20IFreeSql=20?= =?UTF-8?q?=E6=97=B6=E5=A6=82=E6=9E=9C=E4=BB=8E=E5=BA=93=E4=B8=8D=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=E5=AF=BC=E8=87=B4=20iis=20=E9=80=80=E5=87=BA=E7=9A=84?= =?UTF-8?q?=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/dbcontext_01/Controllers/ValuesController.cs | 4 ++-- Examples/dbcontext_01/Startup.cs | 3 +++ Examples/dbcontext_01/dbcontext_01.csproj | 1 + .../MsAccessAdo/MsAccessConnectionPool.cs | 5 ++--- .../FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs | 5 ++--- .../Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs | 5 ++--- .../Default/OdbcAdo/OdbcConnectionPool.cs | 5 ++--- .../GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs | 5 ++--- .../MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs | 5 ++--- .../Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs | 5 ++--- .../OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs | 5 ++--- .../OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs | 5 ++--- .../OracleAdo/OracleConnectionPool.cs | 5 ++--- .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 5 ++--- .../SqlServerAdo/SqlServerConnectionPool.cs | 5 ++--- .../SqliteAdo/SqliteConnectionPool.cs | 5 ++--- 16 files changed, 32 insertions(+), 41 deletions(-) diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs index 0df8ab90..e8aa5508 100644 --- a/Examples/dbcontext_01/Controllers/ValuesController.cs +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -235,9 +235,9 @@ namespace dbcontext_01.Controllers // GET api/values/5 [HttpGet("{id}")] - public ActionResult Get(int id) + public ActionResult Get(int id) { - return "value"; + return _orm.Select().Where(a => a.Id == id).First(); } // POST api/values diff --git a/Examples/dbcontext_01/Startup.cs b/Examples/dbcontext_01/Startup.cs index 6ac054d2..638fc0f6 100644 --- a/Examples/dbcontext_01/Startup.cs +++ b/Examples/dbcontext_01/Startup.cs @@ -20,6 +20,9 @@ namespace dbcontext_01 .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document2.db;Pooling=true;Max Pool Size=10") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + //.UseConnectionString(DataType.MySql, "Data Source=192.168.164.10;Port=33061;User ID=root;Password=123456;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5") + //.UseSlave("Data Source=192.168.164.10;Port=33062;User ID=root;Password=123456;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5") + //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") //.UseSyncStructureToUpper(true) diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj index 516f4a05..5a84476d 100644 --- a/Examples/dbcontext_01/dbcontext_01.csproj +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -12,6 +12,7 @@ + diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs index 34e49c8d..4ae88c92 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs @@ -19,6 +19,8 @@ namespace FreeSql.MsAccess public MsAccessConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new AccessConnectionPoolPolicy { _pool = this, @@ -26,9 +28,6 @@ namespace FreeSql.MsAccess }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index d1a7311f..61fb63f4 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -19,6 +19,8 @@ namespace FreeSql.MySql public MySqlConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new MySqlConnectionPoolPolicy { _pool = this, @@ -26,9 +28,6 @@ namespace FreeSql.MySql }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index d1db9ed3..a6a23395 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -23,6 +23,8 @@ namespace FreeSql.Odbc.Dameng { this.UserId = OdbcDamengConnectionPool.GetUserId(connectionString); + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new OdbcOracleConnectionPoolPolicy { _pool = this, @@ -30,9 +32,6 @@ namespace FreeSql.Odbc.Dameng }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public static string GetUserId(string connectionString) diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs index 99e4023e..4ce05dd8 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -19,6 +19,8 @@ namespace FreeSql.Odbc.Default public OdbcConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new OdbcConnectionPoolPolicy { _pool = this, @@ -26,9 +28,6 @@ namespace FreeSql.Odbc.Default }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs index 448f3978..c4830c6d 100644 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs @@ -22,6 +22,8 @@ namespace FreeSql.Odbc.GBase public OdbcGBaseConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new OdbcPostgreSQLConnectionPoolPolicy { _pool = this, @@ -29,9 +31,6 @@ namespace FreeSql.Odbc.GBase }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs index a68020e9..a9a044cc 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -19,6 +19,8 @@ namespace FreeSql.Odbc.MySql public OdbcMySqlConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new OdbcMySqlConnectionPoolPolicy { _pool = this, @@ -26,9 +28,6 @@ namespace FreeSql.Odbc.MySql }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index ab255dbd..06f358fe 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -23,6 +23,8 @@ namespace FreeSql.Odbc.Oracle { this.UserId = OdbcOracleConnectionPool.GetUserId(connectionString); + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new OdbcOracleConnectionPoolPolicy { _pool = this, @@ -30,9 +32,6 @@ namespace FreeSql.Odbc.Oracle }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public static string GetUserId(string connectionString) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index 574ae33b..2230fbc3 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -20,6 +20,8 @@ namespace FreeSql.Odbc.PostgreSQL public OdbcPostgreSQLConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new OdbcPostgreSQLConnectionPoolPolicy { _pool = this, @@ -27,9 +29,6 @@ namespace FreeSql.Odbc.PostgreSQL }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs index ebef1228..d068a424 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -19,6 +19,8 @@ namespace FreeSql.Odbc.SqlServer public OdbcSqlServerConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new OdbcSqlServerConnectionPoolPolicy { _pool = this, @@ -26,9 +28,6 @@ namespace FreeSql.Odbc.SqlServer }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index 2c2178b5..c088d63a 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -21,6 +21,8 @@ namespace FreeSql.Oracle public OracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; this.UserId = OracleConnectionPool.GetUserId(connectionString); var policy = new OracleConnectionPoolPolicy @@ -30,9 +32,6 @@ namespace FreeSql.Oracle }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public static string GetUserId(string connectionString) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index ba1ce9a5..007bc36b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -20,6 +20,8 @@ namespace FreeSql.PostgreSQL public PostgreSQLConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new PostgreSQLConnectionPoolPolicy { _pool = this, @@ -27,9 +29,6 @@ namespace FreeSql.PostgreSQL }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 2e8272fb..7e5496fd 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -19,6 +19,8 @@ namespace FreeSql.SqlServer public SqlServerConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; var policy = new SqlServerConnectionPoolPolicy { _pool = this, @@ -26,9 +28,6 @@ namespace FreeSql.SqlServer }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index fb3ac566..10baf6f0 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -21,6 +21,8 @@ namespace FreeSql.Sqlite public SqliteConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; policy = new SqliteConnectionPoolPolicy { _pool = this, @@ -28,9 +30,6 @@ namespace FreeSql.Sqlite }; this.Policy = policy; policy.ConnectionString = connectionString; - - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; } public void Return(Object obj, Exception exception, bool isRecreate = false) From b9b0be89c1fa6f9b84866d846936a3b167c4128b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Mar 2020 16:51:24 +0800 Subject: [PATCH 0451/1029] 1.3.0-preview1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 231c8d99..a412154d 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.2.0 + 1.3.0-preview1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 1d4bd0d2..648d4f0b 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index f16b55e2..fefa796b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 2a7cc192..b8aa505f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 21d5a195..edc147d4 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.2.0 + 1.3.0-preview1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3bc5814d..dcf78508 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d832af64..e7eceb98 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c980a8da..99448883 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.0 + 1.3.0-preview1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f8a2f9b7..42505e98 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 867c4443..3591fa57 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c05e4c0e..1019d01f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 049b91e4..fcad928b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d914e2e4..6ce89adc 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7fdf2c37..d4f0ef0e 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 722ee55d..741e49a6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 46879916..37d1d8d4 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 75c8797a..950bc6bf 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.0 + 1.3.0-preview1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From fa3aa8ec83d91f273d9d7e8374f74d36cb107dcb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 5 Mar 2020 16:58:26 +0800 Subject: [PATCH 0452/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20DbContext/Re?= =?UTF-8?q?pository=20EnableAddOrUpdateNavigateList=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=85=B3=E9=97=AD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContextOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index d8492bbe..8264011a 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -20,7 +20,7 @@ namespace FreeSql /// - 属性集合为空时,删除他们的所有关联数据(中间表) /// - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录 /// - public bool EnableAddOrUpdateNavigateList { get; set; } = true; + public bool EnableAddOrUpdateNavigateList { get; set; } = false; /// /// 实体变化事件 From b45360bfbe37e8d2d717ae74f78c215cb6ec7bf5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 00:15:35 +0800 Subject: [PATCH 0453/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbContext/Re?= =?UTF-8?q?pository=20SaveMany=20=E4=B8=80=E5=AF=B9=E5=A4=9A=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E6=97=B6=E5=88=A0=E9=99=A4=E6=9D=A1=E4=BB=B6=20bug?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetAsync.cs | 17 ++++++++++++++++- FreeSql.DbContext/DbSet/DbSetSync.cs | 17 ++++++++++++++++- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 4 +++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 68d6b0bb..cec6c1b2 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -158,10 +158,25 @@ namespace FreeSql if (tref.RefType == Internal.Model.TableRefType.OneToMany) { await DbContextExecCommandAsync(); - //删除没有保存的数据 + //删除没有保存的数据,求出主体的条件 + var deleteWhereParentParam = Expression.Parameter(typeof(object), "a"); + Expression whereParentExp = null; + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) + { + var whereExp = Expression.Equal( + Expression.MakeMemberAccess(Expression.Convert(deleteWhereParentParam, tref.RefEntityType), tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName]), + Expression.Constant( + FreeSql.Internal.Utils.GetDataReaderValue( + tref.Columns[colidx].CsType, + _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.RefColumns[colidx].CsType) + ); + if (whereParentExp == null) whereParentExp = whereExp; + else whereParentExp = Expression.AndAlso(whereParentExp, whereExp); + } var propValEach = GetItemValue(item, prop) as IEnumerable; await _db.Orm.Delete().AsType(tref.RefEntityType) .WithTransaction(_uow?.GetOrBeginTransaction()) + .Where(Expression.Lambda>(whereParentExp, deleteWhereParentParam)) .WhereDynamic(propValEach, true).ExecuteAffrowsAsync(); } } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 603e1fda..10a10f57 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -170,10 +170,25 @@ namespace FreeSql if (tref.RefType == Internal.Model.TableRefType.OneToMany) { DbContextExecCommand(); - //删除没有保存的数据 + //删除没有保存的数据,求出主体的条件 + var deleteWhereParentParam = Expression.Parameter(typeof(object), "a"); + Expression whereParentExp = null; + for (var colidx = 0; colidx < tref.Columns.Count; colidx++) + { + var whereExp = Expression.Equal( + Expression.MakeMemberAccess(Expression.Convert(deleteWhereParentParam, tref.RefEntityType), tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName]), + Expression.Constant( + FreeSql.Internal.Utils.GetDataReaderValue( + tref.Columns[colidx].CsType, + _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.RefColumns[colidx].CsType) + ); + if (whereParentExp == null) whereParentExp = whereExp; + else whereParentExp = Expression.AndAlso(whereParentExp, whereExp); + } var propValEach = GetItemValue(item, prop) as IEnumerable; _db.Orm.Delete().AsType(tref.RefEntityType) .WithTransaction(_uow?.GetOrBeginTransaction()) + .Where(Expression.Lambda>(whereParentExp, deleteWhereParentParam)) .WhereDynamic(propValEach, true).ExecuteAffrows(); } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 37e30197..bc70c511 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -1092,7 +1092,9 @@ namespace FreeSql.Tests }) }; - g.mysql.GetRepository().Insert(neworder); + var repo = g.mysql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(neworder); var order = g.mysql.Select().Where(a => a.Id == neworder.Id).ToOne(); //查询订单表 if (order == null) From 6e9f5d3f8e6c44d5e9d759f5b14490546d57d6b9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 00:16:53 +0800 Subject: [PATCH 0454/1029] 1.3.0-preview2 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 17 insertions(+), 24 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a412154d..7e12d621 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 648d4f0b..2f42cbcf 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index fefa796b..2bca7270 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b8aa505f..a3fc2e0f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index edc147d4..b7d7977c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview1 + 1.3.0-preview2 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index dcf78508..c6f28d45 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e7eceb98..162d61ef 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ca7c357b..2735cefb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 99448883..78c6ad80 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 42505e98..c7d2f7ff 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 3591fa57..c0d27eef 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 1019d01f..488c2877 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fcad928b..b5cdb901 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 6ce89adc..a609c553 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d4f0ef0e..199fb7e3 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 741e49a6..a7a57989 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 37d1d8d4..42e0b28a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 950bc6bf..fe8784aa 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview1 + 1.3.0-preview2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From f834b2aef3f88bcb577a23ff89347cdd8b516367 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 00:45:10 +0800 Subject: [PATCH 0455/1029] update functions.png --- functions06.png | Bin 97690 -> 0 bytes functions07.png | Bin 0 -> 103106 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 functions06.png create mode 100644 functions07.png diff --git a/functions06.png b/functions06.png deleted file mode 100644 index 8eb0a810d18c20b8a49a54fb727a47884131dff8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97690 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

U 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 diff --git a/functions07.png b/functions07.png new file mode 100644 index 0000000000000000000000000000000000000000..7e6d9bc339b42b362fe5c895b3020b9e986e3b99 GIT binary patch literal 103106 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 V82e?`v@qb`Bl*X2r84Hh{||OVdg1^8 literal 0 HcmV?d00001 From b71e7c1b23d69aab7fbc0a94b325cce9a2520dd3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 00:47:21 +0800 Subject: [PATCH 0456/1029] update readme functions.png --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 940aa0de..828bcd38 100644 --- a/readme.md +++ b/readme.md @@ -42,7 +42,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 欢迎更多使用 FreeSql 的开源项目加入目录

- +

## Quick start From ab52728f7fde4c30803ec12d9d4b11cbadbd725f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 13:13:47 +0800 Subject: [PATCH 0457/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20BaseEntity?= =?UTF-8?q?=20SaveMany=20=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseEntity.cs | 13 +++++ .../BaseEntityAsync.cs | 13 +++++ .../Net40/BaseEntity.cs | 12 +++++ FreeSql.DbContext/DbSet/DbSetAsync.cs | 11 ++-- FreeSql.DbContext/DbSet/DbSetSync.cs | 11 ++-- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++ .../RepositoryTests.cs | 53 ++++++++++++++++++- 7 files changed, 113 insertions(+), 7 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index a3fa6cbf..516fdbd9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -143,6 +143,19 @@ namespace FreeSql this.Repository.UnitOfWork = UnitOfWork.Current.Value; return this.Repository.InsertOrUpdate(this as TEntity); } + + /// + /// 【完整】保存导航属性,子表 + /// + /// 导航属性名 + public virtual void SaveMany(string navigatePropertyName) + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.SaveMany(this as TEntity, navigatePropertyName); + } } } diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index e9b33458..0d412cdb 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -125,6 +125,19 @@ namespace FreeSql this.Repository.UnitOfWork = UnitOfWork.Current.Value; return this.Repository.InsertOrUpdateAsync(this as TEntity); } + + /// + /// 【完整】保存导航属性,子表 + /// + /// 导航属性名 + public virtual Task SaveManyAsync(string navigatePropertyName) + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.UnitOfWork = UnitOfWork.Current.Value; + return this.Repository.SaveManyAsync(this as TEntity, navigatePropertyName); + } } } diff --git a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs index 03bfa3a9..41742013 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs @@ -104,6 +104,18 @@ namespace FreeSql return this.Repository.InsertOrUpdate(this as TEntity); } + + /// + /// 【完整】保存导航属性,子表 + /// + /// 导航属性名 + public virtual void SaveMany(string navigatePropertyName) + { + if (this.Repository == null) + this.Repository = Orm.GetRepository(); + + this.Repository.SaveMany(this as TEntity, navigatePropertyName); + } } } diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index cec6c1b2..1dfb5296 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -174,10 +174,15 @@ namespace FreeSql else whereParentExp = Expression.AndAlso(whereParentExp, whereExp); } var propValEach = GetItemValue(item, prop) as IEnumerable; - await _db.Orm.Delete().AsType(tref.RefEntityType) + var subDelete = _db.Orm.Delete().AsType(tref.RefEntityType) .WithTransaction(_uow?.GetOrBeginTransaction()) - .Where(Expression.Lambda>(whereParentExp, deleteWhereParentParam)) - .WhereDynamic(propValEach, true).ExecuteAffrowsAsync(); + .Where(Expression.Lambda>(whereParentExp, deleteWhereParentParam)); + foreach (var propValItem in propValEach) + { + subDelete.WhereDynamic(propValEach, true); + break; + } + await subDelete.ExecuteAffrowsAsync(); } } finally diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 10a10f57..7ffb4adc 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -186,10 +186,15 @@ namespace FreeSql else whereParentExp = Expression.AndAlso(whereParentExp, whereExp); } var propValEach = GetItemValue(item, prop) as IEnumerable; - _db.Orm.Delete().AsType(tref.RefEntityType) + var subDelete = _db.Orm.Delete().AsType(tref.RefEntityType) .WithTransaction(_uow?.GetOrBeginTransaction()) - .Where(Expression.Lambda>(whereParentExp, deleteWhereParentParam)) - .WhereDynamic(propValEach, true).ExecuteAffrows(); + .Where(Expression.Lambda>(whereParentExp, deleteWhereParentParam)); + foreach (var propValItem in propValEach) + { + subDelete.WhereDynamic(propValEach, true); + break; + } + subDelete.ExecuteAffrows(); } } finally diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2735cefb..ca7c357b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 3097044b..7d0a479e 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -335,6 +335,57 @@ namespace FreeSql.Tests public Guid CagetoryId { get; set; } public string Name { get; set; } } + [Fact] + public void SaveMany_OneToMany() + { + var repo = g.sqlite.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = false; //رռ湦 + var cts = new[] { + new Cagetory + { + Name = "1", + Goodss = new List(new[] + { + new Goods { Name = "Ʒ1" }, + new Goods { Name = "Ʒ2" }, + new Goods { Name = "Ʒ3" } + }) + }, + new Cagetory + { + Name = "2", + Goodss = new List(new[] + { + new Goods { Name = "Ʒ4" }, + new Goods { Name = "Ʒ5" } + }) + } + }; + repo.Insert(cts); + repo.SaveMany(cts[0], "Goodss"); //ָ Goodss һԶ + repo.SaveMany(cts[1], "Goodss"); //ָ Goodss һԶ + cts[0].Goodss.RemoveAt(1); + cts[1].Goodss.RemoveAt(1); + repo.SaveMany(cts[0], "Goodss"); //ָ Goodss һԶ + repo.SaveMany(cts[1], "Goodss"); //ָ Goodss һԶ + + cts[0].Name = "11"; + cts[0].Goodss.Clear(); + cts[1].Name = "22"; + cts[1].Goodss.Clear(); + repo.Update(cts); + repo.SaveMany(cts[0], "Goodss"); //ָ Goodss һԶ + repo.SaveMany(cts[1], "Goodss"); //ָ Goodss һԶ + cts[0].Name = "111"; + cts[0].Goodss.Clear(); + cts[0].Goodss.Add(new Goods { Name = "Ʒ33" }); + cts[1].Name = "222"; + cts[1].Goodss.Clear(); + cts[1].Goodss.Add(new Goods { Name = "Ʒ55" }); + repo.Update(cts); + repo.SaveMany(cts[0], "Goodss"); //ָ Goodss һԶ + repo.SaveMany(cts[1], "Goodss"); //ָ Goodss һԶ + } [Fact] public void EnableAddOrUpdateNavigateList_OneToMany_Parent() @@ -417,7 +468,7 @@ namespace FreeSql.Tests } }; var repo = g.sqlite.GetRepository(); - //repo.DbContextOptions.EnableAddOrUpdateNavigateList = false; //رռ湦 + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; //򿪼湦 repo.Insert(ss); //repo.SaveMany(ss[0], "Tags"); //ָ Tags Զ From 123ae07cfa513b2b84bbdd4ac4007234fc19308b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 14:29:36 +0800 Subject: [PATCH 0458/1029] 1.3.0-preview3 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7e12d621..690dab7e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 2f42cbcf..785d88c9 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 2bca7270..01da0487 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a3fc2e0f..b263d35a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index b7d7977c..9440eb8a 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview2 + 1.3.0-preview3 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index c6f28d45..632ba5e0 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 162d61ef..5c06dd26 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 78c6ad80..af087c79 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c7d2f7ff..452a52c8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index c0d27eef..e39e8d2f 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 488c2877..b170bcf6 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index b5cdb901..4b1d64c8 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a609c553..1f1e263e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 199fb7e3..e91d98d8 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a7a57989..61c380b8 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 42e0b28a..e881aeb4 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fe8784aa..7de44aa2 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview2 + 1.3.0-preview3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 2089a1f7476394acd6a96cf9f2dc2738966407c0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 17:01:30 +0800 Subject: [PATCH 0459/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20LazyLoading?= =?UTF-8?q?=20=E4=BE=9D=E8=B5=96=E9=A1=B9=E7=9B=AE=20CSScript.Core=20?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=9A=84=20bug=EF=BC=9B=EF=BC=88=E4=BB=A5?= =?UTF-8?q?=E4=B8=8A=E9=83=BD=E4=B8=8D=E5=86=8D=E5=8D=87=E7=BA=A7=E8=AF=A5?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseEntityReadOnly.cs | 2 +- .../Net40/BaseEntityReadOnly.cs | 2 +- FreeSql.DbContext/DbSet/DbSet.cs | 2 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 4 +- .../FreeSql.Tests.DbContext.csproj | 1 + .../FreeSql.Tests.DbContext/USERINFO.cs | 285 ++++++++++++++++++ .../FreeSql.Tests.DbContext/UnitTest1.cs | 29 ++ .../FreeSql.Tests.DbContext/departments(1).cs | 96 ++++++ .../FreeSql.Tests.DbContext/dept_user.cs | 21 ++ 9 files changed, 437 insertions(+), 5 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.DbContext/USERINFO.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.DbContext/departments(1).cs create mode 100644 FreeSql.Tests/FreeSql.Tests.DbContext/dept_user.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 4d0e2ee0..e50030ab 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -140,7 +140,7 @@ namespace FreeSql isFirst = false; var itemType = item.GetType(); if (itemType == typeof(object)) return; - if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + if (itemType.FullName.Contains("FreeSqlLazyEntity__")) itemType = itemType.BaseType; if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; if (item is BaseEntity == false) return; } diff --git a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs index 33ff1a2f..7464f2fb 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs @@ -78,7 +78,7 @@ namespace FreeSql isFirst = false; var itemType = item.GetType(); if (itemType == typeof(object)) return; - if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + if (itemType.FullName.Contains("FreeSqlLazyEntity__")) itemType = itemType.BaseType; if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; if (item is BaseEntity == false) return; } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 4c43e6ce..a25d4317 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -78,7 +78,7 @@ namespace FreeSql if (item == null) return; var itemType = item.GetType(); if (itemType == typeof(object)) return; - if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + if (itemType.FullName.Contains("FreeSqlLazyEntity__")) itemType = itemType.BaseType; if (_db.Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; var dbset = _db.Set(itemType); dbset?.GetType().GetMethod("TrackToList", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dbset, new object[] { list }); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 7ffb4adc..79171465 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -277,9 +277,9 @@ namespace FreeSql var isEquals = true; for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) { - var refcol = tref.Columns[midcolidx - tref.Columns.Count]; + var refcol = tref.RefColumns[midcolidx - tref.Columns.Count]; var midval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefMiddleEntityType, midItem, tref.MiddleColumns[midcolidx].CsName)); - var refval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curList[curIdx], tref.Columns[midcolidx - tref.Columns.Count].CsName)); + var refval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curList[curIdx], refcol.CsName)); if (object.Equals(midval, refval) == false) { isEquals = false; diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj index 7247f3a8..a0c1aeda 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj @@ -16,6 +16,7 @@ + diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/USERINFO.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/USERINFO.cs new file mode 100644 index 00000000..5400bbd7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/USERINFO.cs @@ -0,0 +1,285 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; + +/// +/// 员工信息表 +/// +[Serializable] +[Index("员工代码badgenumber唯一", "badgenumber", true)] +public class userinfo : BaseEntity +{ + /// + /// 员工ID + /// + [Column(IsPrimary = true)] + [System.ComponentModel.DisplayName("员工ID ")] + [System.ComponentModel.DataAnnotations.Required()] + public int userid { get; set; } + + /// + /// 工号 + /// + [System.ComponentModel.DisplayName("工号")] + [System.ComponentModel.DataAnnotations.Required()] + [Column(Name = "BADGENUMBER", DbType = "VARCHAR(24)")] + public String badgenumber { get; set; } + + /// + /// 姓名 + /// + [System.ComponentModel.DisplayName("姓名")] + [System.ComponentModel.DataAnnotations.Required()] + [Column(DbType = "varchar(40) NULL")] + + public String Name { get; set; } + /// + /// 身份证 + /// + [System.ComponentModel.DisplayName("身份证证")] + [System.ComponentModel.DataAnnotations.Required()] + public String IDCardNo { get; set; } + + + + /// + /// 行动电话 + /// + [System.ComponentModel.DisplayName("行动电话")] + [Column(DbType = "varchar(20) NULL")] + public string pager { get; set; } + + /// + /// 邮件地址 + /// + [System.ComponentModel.DisplayName("邮件地址 ")] + public String email { get; set; } + + + + + /// + /// 办公电话 + /// + [System.ComponentModel.DisplayName("办公电话")] + [Column(DbType = "varchar(20) NULL")] + public String ophone { get; set; } + + /// + /// 入职时间 + /// + [System.ComponentModel.DisplayName("入职时间")] + [Column(DbType = "date")] + public DateTime? hiredday { get; set; } + + + + + /// + /// 生日 + /// + [System.ComponentModel.DisplayName("生日 ")] + [Column(DbType = "date")] + public DateTime? birthday { get; set; } + + + /// + /// 民族 + /// + [System.ComponentModel.DisplayName("民族")] + public string minzu { get; set; } + + /// + /// 籍贯 + /// + [System.ComponentModel.DisplayName("籍贯")] + public String homeaddress { get; set; } + + + /// + /// 合同日期 + /// + [System.ComponentModel.DisplayName("合同日期")] + [Column(DbType = "date")] + public DateTime? hetongdate { get; set; } + + /// + /// 家庭地址 + /// + [System.ComponentModel.DisplayName("家庭地址")] + [Column(DbType = "varchar(80) NULL")] + public String street { get; set; } + + + /// + /// 邮编 + /// + [System.ComponentModel.DisplayName("邮编")] + [Column(DbType = "varchar(12) NULL")] + public String zip { get; set; } + + [System.ComponentModel.DisplayName("城市")] + [Column(Name = "CITY", DbType = "varchar(2)")] + public string CITY { get; set; } + + [System.ComponentModel.DisplayName("省份")] + [Column(DbType = "varchar(2) NULL")] + public string STATE { get; set; } + + + /// + /// 编号 + /// + [System.ComponentModel.DisplayName("编号")] + + public string ssn { get; set; } + + [Column(DbType = "varchar(8) NULL")] + public string GENDER { get; set; } = "M"; + /// + /// 职务 + /// + [System.ComponentModel.DisplayName("职务")] + [Column(DbType = "varchar(20) NULL")] + public string title { get; set; } + + + public short? VERIFICATIONMETHOD { get; set; }//验证方式 + public short? DEFAULTDEPTID { get; set; } = 1;//所属部门ID号 + public short? ATT { get; set; } = 1;//考勤有效 + public short? INLATE { get; set; } = 1;//计迟到 + public short? OUTEARLY { get; set; } = 1;//计早退 + + public short? OVERTIME { get; set; } + + public short? SEP { get; set; } = 1; + public short HOLIDAY { get; set; } = 1;//假日休息 + public string PASSWORD { get; set; }//口令 + public short LUNCHDURATION { get; set; } = 1;//有午休 + public string MVerifyPass { get; set; }//考勤验证密码 + + //[Column(DbType = "image NULL")] + //public byte[] PHOTO { get; set; } + //[Column(DbType = "image NULL")] + //public byte[] Notes { get; set; } + + public int? VerifyCode { get; set; } + public int? Expires { get; set; } + public int? ValidCount { get; set; } + public int? UseAccGroupTZ { get; set; } + + public int? AccGroup { get; set; } + public int? FaceGroup { get; set; } + public int? EMPRIVILEGE { get; set; } + public int? InheritDeptRule { get; set; } + public int? RegisterOT { get; set; } + public int? MinAutoSchInterval { get; set; } + public int? AutoSchPlan { get; set; } + public int? InheritDeptSchClass { get; set; } + public int? InheritDeptSch { get; set; } + public int? privilege { get; set; } + public int? TimeZone1 { get; set; } + public int? TimeZone2 { get; set; } + public int? TimeZone3 { get; set; } + + [Column(DbType = "date")] + public DateTime? ValidTimeEnd { get; set; } + [Column(DbType = "date")] + public DateTime? ValidTimeBegin { get; set; } + + /// + /// 家庭电话 + /// + [System.ComponentModel.DisplayName("家庭电话")] + [Column(DbType = "varchar(20) NULL")] + public String fphone { get; set; } + + /// + /// 卡号 + /// + [System.ComponentModel.DisplayName("卡号 ")] + [Column(Name = "CardNo", DbType = "varchar(20)")] + public String CardNo { get; set; } + + + + /// + /// 身份证有效期 + /// + [System.ComponentModel.DisplayName("身份证有效期 ")] + public String idcardvalidtime { get; set; } = new DateTime(2099, 12, 31).ToString(); + + + + + + /// + /// 离职日期 + /// + [System.ComponentModel.DisplayName("离职日期")] + [Column(DbType = "date")] + public DateTime? leavedate { get; set; } + + /// + /// 登录密码 + /// + [System.ComponentModel.DisplayName("登录密码")] + public String loginpass { get; set; } + + + /// + /// 相片地址 + /// + [System.ComponentModel.DisplayName("相片地址")] + public String picurl { get; set; } + + /// + /// 上级主管 + /// + [System.ComponentModel.DisplayName("上级主管")] + public int? managerid { get; set; } + ///// + ///// 上级主管对象 + ///// + //[Navigate("managerid")] + //public userinfo pManager { get; set; } + + + + [Navigate(ManyToMany = typeof(dept_user))] + public List depts { get; set; } + + /// + /// 管理员标志 + /// + + [System.ComponentModel.DisplayName("管理员标志")] + public short? SECURITYFLAGS { get; set; }//管理员标志 + + + + + + + + + + + + + + + + +} + + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index d8f4c6a6..1f2e7e9c 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -21,6 +21,35 @@ namespace FreeSql.Tests [Fact] public void Include_ManyToMany() { + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + BaseEntity.Initialization(g.sqlite); + + userinfo user = new userinfo { userid = 1 }; + user.Insert(); + + user.depts = new List( + new[] { + new DEPARTMENTS { deptid = 1, deptcode = "01" }, + new DEPARTMENTS { deptid = 2, deptcode = "02" }, + new DEPARTMENTS { deptid = 3, deptcode = "03" }, + }); + user.SaveMany("depts"); + + user.depts = new List( + new[] { + new DEPARTMENTS { deptid = 1, deptcode = "01" }, + new DEPARTMENTS { deptid = 2, deptcode = "02" }, + new DEPARTMENTS { deptid = 4, deptcode = "04" }, + }); + user.SaveMany("depts"); + + user.depts = new List( + new[] { + new DEPARTMENTS { deptid = 2, deptcode = "02" }, + }); + user.SaveMany("depts"); g.sqlite.CodeFirst.SyncStructure(); g.sqlite.CodeFirst.SyncStructure(); diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/departments(1).cs b/FreeSql.Tests/FreeSql.Tests.DbContext/departments(1).cs new file mode 100644 index 00000000..6ce4d586 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/departments(1).cs @@ -0,0 +1,96 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; + + + +/// +/// 部门表 +/// +[Serializable] +[Index("部门代码deptcode唯一", "deptcode", true)] +public class DEPARTMENTS : BaseEntity +{ + /// + /// 部门ID + /// + [Column(IsPrimary = true)] + + [System.ComponentModel.DisplayName("部门ID")] + public int deptid { get; set; } + + ///// + ///// 员工列表 对应employee.deptid + ///// + //[Navigate("deptid")] + //public List Employees { get; set; } + + /// + /// 上级部门ID + /// + [System.ComponentModel.DisplayName("上级部门ID")] + public int? supdeptid { get; set; } + /// + /// 上级部门对象 + /// + [Navigate("supdeptid")] + public DEPARTMENTS pDepartments { get; set; } + + /// + /// 部门主管ID + /// + [System.ComponentModel.DisplayName("部门主管ID")] + public int? managerid { get; set; } + /// + /// 部门主管对象 + /// + [Navigate("managerid")] + public userinfo manager { get; set; } + + + ///// + ///// 下级部门列表 + ///// + //[Navigate("supdeptid")] + //public List childDepartments { get; set; } + + + [Navigate(ManyToMany = typeof(dept_user))] + public List employeesMany { get; set; } + + + #region MyRegion + /// + /// 部门代码 + /// + [System.ComponentModel.DisplayName("部门代码")] + [System.ComponentModel.DataAnnotations.Required()] + public string deptcode { get; set; } + + /// + /// 部门名称 + /// + [System.ComponentModel.DisplayName("部门名称")] + [System.ComponentModel.DataAnnotations.Required()] + public string deptname { get; set; } + #endregion + + public short? InheritParentSch { get; set; } + public short? InheritDeptSch { get; set; } + public short? InheritDeptSchClass { get; set; } + public short? AutoSchPlan { get; set; } + public short? InLate { get; set; } + public short? OutEarly { get; set; } + public short? InheritDeptRule { get; set; } + public int? MinAutoSchInterval { get; set; } + public short? RegisterOT { get; set; } + public int? DefaultSchId { get; set; } + public short? ATT { get; set; } + public short? Holiday { get; set; } + public short? OverTime { get; set; } + + + +} + diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/dept_user.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/dept_user.cs new file mode 100644 index 00000000..f6cf1e0f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/dept_user.cs @@ -0,0 +1,21 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FreeSql; + +public class dept_user: BaseEntity + { + public int deptid { get; set; } + public int userid { get; set; } + + [Navigate("deptid")] + public DEPARTMENTS dept { get; set; } + + + [Navigate("userid")] + public userinfo emp { get; set; } + } + From b5e6a39a25ffda3f5f4fd2cec838c5ea51e4f7c1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 17:10:48 +0800 Subject: [PATCH 0460/1029] ## v1.2.1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 690dab7e..9245afc8 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview3 + 1.2.1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 785d88c9..2279c2e7 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 01da0487..e9b80e9c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b263d35a..7f8d57b8 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 9440eb8a..9505d7db 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview3 + 1.2.1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 632ba5e0..35ce66cb 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 5c06dd26..1d45aa40 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index af087c79..3c476df1 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview3 + 1.2.1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 452a52c8..d62682bb 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index e39e8d2f..469ca848 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b170bcf6..4f5591fc 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4b1d64c8..582cc2e2 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 1f1e263e..1eb45d2c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index e91d98d8..29894571 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 61c380b8..8d2e3b64 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e881aeb4..2b8ac756 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7de44aa2..499cc04b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview3 + 1.2.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From ed6ef68d7aef8740ba6b45aeb7a61725103d34a0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 17:15:59 +0800 Subject: [PATCH 0461/1029] 1.3.0-preview4 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 131 ------------------ .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 17 insertions(+), 148 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 9245afc8..79f68429 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.2.1 + 1.3.0-preview4 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 2279c2e7..6d34c895 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e9b80e9c..6493cdb0 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7f8d57b8..82126de9 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 9505d7db..c794f2e5 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.2.1 + 1.3.0-preview4 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 35ce66cb..bba971b5 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 1d45aa40..560f8046 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3c476df1..990962b2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 - 1.2.1 + 1.3.0-preview4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index d62682bb..da74740e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 08d2c1b3..784479be 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2260,137 +2260,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 469ca848..1aedefb6 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 4f5591fc..c251beb4 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 582cc2e2..fe7da754 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 1eb45d2c..e437e24b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 29894571..2bd21387 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8d2e3b64..3f107edb 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2b8ac756..3143cf46 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 499cc04b..1ae621b5 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.2.1 + 1.3.0-preview4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 4e5d15e0442550f45175619c48f16083b45a92aa Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 6 Mar 2020 23:21:09 +0800 Subject: [PATCH 0462/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IncludeMany?= =?UTF-8?q?=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=E5=AF=B9=20T1=20?= =?UTF-8?q?=E4=B8=8D=E8=87=AA=E5=8A=A8=E8=BF=81=E7=A7=BB=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 12 ++ FreeSql/FreeSql.xml | 131 ++++++++++++++++++ .../SelectProvider/Select1Provider.cs | 12 +- 3 files changed, 151 insertions(+), 4 deletions(-) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index f04dc599..99debfaf 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -220,6 +220,12 @@ public static partial class FreeSqlGlobalExtensions public static List IncludeMany(this List list, IFreeSql orm, Expression>> navigateSelector, Action> then = null) where T1 : class where TNavigate : class { if (list == null || list.Any() == false) return list; + if (orm.CodeFirst.IsAutoSyncStructure) + { + var tb = orm.CodeFirst.GetTableByEntity(typeof(T1)); + if (tb == null || tb.Primarys.Any() == false) + (orm.CodeFirst as FreeSql.Internal.CommonProvider.CodeFirstProvider)._dicSycedTryAdd(typeof(T1)); //._dicSyced.TryAdd(typeof(TReturn), true); + } var select = orm.Select().IncludeMany(navigateSelector, then) as FreeSql.Internal.CommonProvider.Select1Provider; select.SetList(list); return list; @@ -230,6 +236,12 @@ public static partial class FreeSqlGlobalExtensions async public static System.Threading.Tasks.Task> IncludeManyAsync(this List list, IFreeSql orm, Expression>> navigateSelector, Action> then = null) where T1 : class where TNavigate : class { if (list == null || list.Any() == false) return list; + if (orm.CodeFirst.IsAutoSyncStructure) + { + var tb = orm.CodeFirst.GetTableByEntity(typeof(T1)); + if (tb == null || tb.Primarys.Any() == false) + (orm.CodeFirst as FreeSql.Internal.CommonProvider.CodeFirstProvider)._dicSycedTryAdd(typeof(T1)); //._dicSyced.TryAdd(typeof(TReturn), true); + } var select = orm.Select().IncludeMany(navigateSelector, then) as FreeSql.Internal.CommonProvider.Select1Provider; await select.SetListAsync(list); return list; diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 784479be..08d2c1b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2260,6 +2260,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 }) + + + + + + 可自定义解析表达式 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index fa3287cc..54adc140 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -183,7 +183,8 @@ namespace FreeSql.Internal.CommonProvider if (typeof(TReturn) == typeof(T1)) return this as ISelect; _tables[0].Parameter = select.Parameters[0]; _selectExpression = select.Body; - (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TReturn)); //._dicSyced.TryAdd(typeof(TReturn), true); + if (_orm.CodeFirst.IsAutoSyncStructure) + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TReturn)); //._dicSyced.TryAdd(typeof(TReturn), true); var ret = _orm.Select(); Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -198,7 +199,8 @@ namespace FreeSql.Internal.CommonProvider ), SelectTableInfoType.InnerJoin); if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); + if (_orm.CodeFirst.IsAutoSyncStructure) + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -213,7 +215,8 @@ namespace FreeSql.Internal.CommonProvider ), SelectTableInfoType.InnerJoin); if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); + if (_orm.CodeFirst.IsAutoSyncStructure) + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -245,7 +248,8 @@ namespace FreeSql.Internal.CommonProvider } if (typeof(TResult) == typeof(T1)) return this as ISelect; _selectExpression = resultSelector.Body; - (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); + if (_orm.CodeFirst.IsAutoSyncStructure) + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); var ret = _orm.Select() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; From 59b9b1272b196242a934d8ec68778726a0de6eb9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 7 Mar 2020 16:08:03 +0800 Subject: [PATCH 0463/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=AF=B9=20System.ValueType=20=E7=9A=84=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=EF=BC=8C=E5=87=8F=E5=B0=91=E7=89=88=E6=9C=AC=E5=86=B2?= =?UTF-8?q?=E7=AA=81=E9=97=AE=E9=A2=98=EF=BC=9B=EF=BC=88=E7=9B=AE=E5=89=8D?= =?UTF-8?q?=20FreeSql.dll=20=E6=97=A0=E4=BB=BB=E4=BD=95=E5=85=AC=E7=94=A8?= =?UTF-8?q?=E5=BA=93=E4=BE=9D=E8=B5=96=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/RazorModel.cs | 4 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 7 +- .../Repository/DataFilter/DataFilter.cs | 17 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/DatabaseModel/DbTypeInfo.cs | 14 +- .../Extensions/FreeSqlGlobalExpressionCall.cs | 2 + FreeSql/FreeSql.csproj | 8 +- FreeSql/FreeSql.xml | 350 +++++------ FreeSql/Interface/Curd/ISelect/ISelect10.cs | 5 +- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 5 +- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 5 +- FreeSql/Interface/Curd/ISelect/ISelect4.cs | 5 +- FreeSql/Interface/Curd/ISelect/ISelect5.cs | 5 +- FreeSql/Interface/Curd/ISelect/ISelect6.cs | 5 +- FreeSql/Interface/Curd/ISelect/ISelect7.cs | 5 +- FreeSql/Interface/Curd/ISelect/ISelect8.cs | 5 +- FreeSql/Interface/Curd/ISelect/ISelect9.cs | 5 +- FreeSql/Interface/IAdo.cs | 97 +-- FreeSql/Interface/ICodeFirst.cs | 2 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 83 +-- .../AdoProvider/AdoProviderAsync.cs | 71 +-- .../CommonProvider/CodeFirstProvider.cs | 32 +- .../SelectProvider/Select0Provider.cs | 36 +- .../SelectProvider/Select10Provider.cs | 6 +- .../SelectProvider/Select1Provider.cs | 32 +- .../SelectProvider/Select2Provider.cs | 6 +- .../SelectProvider/Select3Provider.cs | 6 +- .../SelectProvider/Select4Provider.cs | 6 +- .../SelectProvider/Select5Provider.cs | 6 +- .../SelectProvider/Select6Provider.cs | 6 +- .../SelectProvider/Select7Provider.cs | 6 +- .../SelectProvider/Select8Provider.cs | 6 +- .../SelectProvider/Select9Provider.cs | 6 +- .../SelectProvider/SelectGroupingProvider.cs | 4 +- FreeSql/Internal/Model/DbToCs.cs | 71 +++ FreeSql/Internal/Model/NaviteTuple.cs | 182 ++++++ .../Internal/Model/ReadAnonymousTypeInfo.cs | 21 + FreeSql/Internal/UtilsExpressionTree.cs | 14 +- .../MsAccessCodeFirst.cs | 71 ++- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 61 +- .../FreeSql.Provider.MySql/MySqlDbFirst.cs | 75 +-- .../Dameng/OdbcDamengCodeFirst.cs | 62 +- .../Dameng/OdbcDamengDbFirst.cs | 43 +- .../Default/OdbcCodeFirst.cs | 48 +- .../GBase/Curd/OdbcGBaseDelete.cs | 31 - .../GBase/Curd/OdbcGBaseSelect.cs | 176 ------ .../GBase/Curd/OdbcGBaseUpdate.cs | 86 --- .../GBase/Curd/__OdbcGBaseInsert.cs | 149 ----- .../OdbcGBaseAdo/OdbcGBaseConnectionPool.cs | 249 -------- .../GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs | 76 --- .../GBase/OdbcGBaseProvider.cs | 64 -- .../GBase/__OdbcGBaseCodeFirst.cs | 388 ------------ .../GBase/__OdbcGBaseDbFirst.cs | 480 --------------- .../GBase/__OdbcGBaseExpression.cs | 554 ------------------ .../GBase/__OdbcGBaseUtils.cs | 159 ----- .../MySql/OdbcMySqlCodeFirst.cs | 49 +- .../MySql/OdbcMySqlDbFirst.cs | 39 +- .../Oracle/OdbcOracleCodeFirst.cs | 62 +- .../Oracle/OdbcOracleDbFirst.cs | 43 +- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 62 +- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 44 +- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLUtils.cs | 2 +- .../SqlServer/OdbcSqlServerCodeFirst.cs | 50 +- .../SqlServer/OdbcSqlServerDbFirst.cs | 49 +- .../OracleCodeFirst.cs | 62 +- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 43 +- .../PostgreSQLCodeFirst.cs | 110 ++-- .../PostgreSQLExpression.cs | 2 +- .../PostgreSQLUtils.cs | 2 +- .../SqlServerCodeFirst.cs | 50 +- .../SqlServerDbFirst.cs | 57 +- .../SqlServerExtensions.cs | 5 +- .../SqliteCodeFirst.cs | 49 +- 74 files changed, 1344 insertions(+), 3358 deletions(-) create mode 100644 FreeSql/Internal/Model/DbToCs.cs create mode 100644 FreeSql/Internal/Model/NaviteTuple.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseDelete.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs delete mode 100644 Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 7a8dbdb9..07e5bb6a 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -73,14 +73,14 @@ public class RazorModel { if (col.CsType != null) { var dbinfo = fsql.CodeFirst.GetDbInfo(col.CsType); - if (dbinfo != null && dbinfo.Value.dbtypeFull.Replace("NOT NULL", "").Trim() != col.DbTypeTextFull) + if (dbinfo != null && dbinfo.dbtypeFull.Replace("NOT NULL", "").Trim() != col.DbTypeTextFull) sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); if (col.IsPrimary) sb.Add("IsPrimary = true"); if (col.IsIdentity) sb.Add("IsIdentity = true"); - if (dbinfo != null && dbinfo.Value.isnullable != col.IsNullable) + if (dbinfo != null && dbinfo.isnullable != col.IsNullable) { if (col.IsNullable && fsql.DbFirst.GetCsType(col).Contains("?") == false && col.CsType.IsValueType) sb.Add("IsNullable = true"); diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 560f8046..a7a2081f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -1,7 +1,7 @@  - netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 + netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.3.0-preview4 true YeXiangQin @@ -32,13 +32,16 @@ net40 - + netcoreapp + + + diff --git a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs index c0e578ff..2d472304 100644 --- a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs +++ b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs @@ -153,8 +153,19 @@ namespace FreeSql public class FluentDataFilter : IDisposable { - - internal List<(Type type, string name, LambdaExpression exp)> _filters = new List<(Type type, string name, LambdaExpression exp)>(); + internal class FilterInfo + { + public Type type { get; } + public string name { get; } + public LambdaExpression exp { get; } + public FilterInfo(Type type, string name, LambdaExpression exp) + { + this.type = type; + this.name = name; + this.exp = exp; + } + } + internal List _filters = new List(); public FluentDataFilter Apply(string filterName, Expression> filterAndValidateExp) where TEntity : class { @@ -162,7 +173,7 @@ namespace FreeSql throw new ArgumentNullException(nameof(filterName)); if (filterAndValidateExp == null) return this; - _filters.Add((typeof(TEntity), filterName, filterAndValidateExp)); + _filters.Add(new FilterInfo(typeof(TEntity), filterName, filterAndValidateExp)); return this; } diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 990962b2..d158f453 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -1,7 +1,7 @@  - netstandard2.0;netcoreapp31;netcoreapp22;netcoreapp21;net45;net40 + netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.3.0-preview4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. diff --git a/FreeSql/DatabaseModel/DbTypeInfo.cs b/FreeSql/DatabaseModel/DbTypeInfo.cs index eb319c02..680c14fb 100644 --- a/FreeSql/DatabaseModel/DbTypeInfo.cs +++ b/FreeSql/DatabaseModel/DbTypeInfo.cs @@ -13,6 +13,18 @@ namespace FreeSql.DatabaseModel /// /// 枚举项 /// - public List<(string label, string value)> Labels { get; set; } + public List Labels { get; set; } + + public class LabelInfo + { + public string label { get; } + public string value { get; } + + public LabelInfo(string label, string value) + { + this.label = label; + this.value = value; + } + } } } diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs index 83b7e83e..2ad04f7d 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs @@ -51,6 +51,7 @@ public static class FreeSqlGlobalExpressionCall return false; } +#if netcoreapp /// /// C#:从元组集合中查找 exp1, exp2 是否存在 /// SQL: @@ -127,4 +128,5 @@ public static class FreeSqlGlobalExpressionCall expContext.Value.Result = sb.ToString(); return true; } +#endif } \ No newline at end of file diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index da74740e..b30fa455 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45;net40 + netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.3.0-preview4 true YeXiangQin @@ -32,9 +32,11 @@ - - + + + netcoreapp + net40 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 08d2c1b3..8090152d 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2260,137 +2260,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2945,40 +2814,6 @@ - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - - C#:从元组集合中查找 exp1, exp2, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - 测量两个经纬度的距离,返回单位:米 @@ -3243,3 +3078,188 @@ +.IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 57faf043..52121b8a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index ccb2d1c6..9461c992 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index eac99d36..e3195e00 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index ca180e47..845ad08f 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index a870eeed..02002672 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 08cdd495..756e1c38 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index 88f81f92..5b115d56 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 92492ef6..502eef4c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 21d92c7a..043bc3c8 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -50,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 3d7d60bc..3d93860d 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -1,4 +1,5 @@ using FreeSql.DatabaseModel; +using FreeSql.Internal.Model; using SafeObjectPool; using System; using System.Collections.Generic; @@ -185,9 +186,9 @@ namespace FreeSql /// /// /// - (List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) /// @@ -195,28 +196,28 @@ namespace FreeSql /// /// /// - (List, List) Query(string cmdText, object parms = null); - (List, List) Query(DbTransaction transaction, string cmdText, object parms = null); - (List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + NaviteTuple, List> Query(string cmdText, object parms = null); + NaviteTuple, List> Query(DbTransaction transaction, string cmdText, object parms = null); + NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - (List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List) Query(string cmdText, object parms = null); - (List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); - (List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - (List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List) Query(string cmdText, object parms = null); - (List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); - (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - (List, List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - (List, List, List, List, List) Query(string cmdText, object parms = null); - (List, List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null); - (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + NaviteTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List> Query(string cmdText, object parms = null); + NaviteTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); + NaviteTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + NaviteTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List, List> Query(string cmdText, object parms = null); + NaviteTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); + NaviteTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + NaviteTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NaviteTuple, List, List, List, List> Query(string cmdText, object parms = null); + NaviteTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); + NaviteTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); #if net40 #else @@ -357,9 +358,9 @@ namespace FreeSql /// /// /// - Task<(List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) /// @@ -367,28 +368,28 @@ namespace FreeSql /// /// /// - Task<(List, List)> QueryAsync(string cmdText, object parms = null); - Task<(List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List>> QueryAsync(string cmdText, object parms = null); + Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List)> QueryAsync(string cmdText, object parms = null); - Task<(List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List)> QueryAsync(string cmdText, object parms = null); - Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task<(List, List, List, List, List)> QueryAsync(string cmdText, object parms = null); - Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List>> QueryAsync(string cmdText, object parms = null); + Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List>> QueryAsync(string cmdText, object parms = null); + Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null); + Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); #endregion #endif } diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 482a4358..04f2085e 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -87,7 +87,7 @@ namespace FreeSql /// /// /// - (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); + DbInfoResult GetDbInfo(Type type); /// /// 在外部配置实体的特性 /// diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 86f0bb2e..45db5750 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.Linq; using System.Text; using System.Reflection; +using FreeSql.Internal.Model; namespace FreeSql.Internal.CommonProvider { @@ -33,7 +34,7 @@ namespace FreeSql.Internal.CommonProvider this.DataType = dataType; } - void LoggerException(IObjectPool pool, (Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose) pc, Exception ex, DateTime dt, StringBuilder logtxt, bool isThrowException = true) + void LoggerException(IObjectPool pool, PrepareCommandResult pc, Exception ex, DateTime dt, StringBuilder logtxt, bool isThrowException = true) { var cmd = pc.cmd; if (pc.isclose) pc.cmd.Connection.Close(); @@ -121,14 +122,14 @@ namespace FreeSql.Internal.CommonProvider return ret; } #region query multi - public (List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public (List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public (List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NaviteTuple, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public NaviteTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -180,17 +181,17 @@ namespace FreeSql.Internal.CommonProvider break; } }, cmdType, cmdText, cmdParms); - return (ret1, ret2); + return NaviteTuple.Create(ret1, ret2); } - public (List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public (List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public (List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NaviteTuple, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public NaviteTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public NaviteTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -265,17 +266,17 @@ namespace FreeSql.Internal.CommonProvider break; } }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3); + return NaviteTuple.Create(ret1, ret2, ret3); } - public (List, List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public (List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public (List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NaviteTuple, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public NaviteTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public NaviteTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -373,17 +374,17 @@ namespace FreeSql.Internal.CommonProvider break; } }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3, ret4); + return NaviteTuple.Create(ret1, ret2, ret3, ret4); } - public (List, List, List, List, List) Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List, List) Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public (List, List, List, List, List) Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public (List, List, List, List, List) Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public (List, List, List, List, List) Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NaviteTuple, List, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NaviteTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public NaviteTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public NaviteTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -504,7 +505,7 @@ namespace FreeSql.Internal.CommonProvider break; } }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3, ret4, ret5); + return NaviteTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion @@ -771,7 +772,19 @@ namespace FreeSql.Internal.CommonProvider return val; } - (Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose) PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) + class PrepareCommandResult + { + public Aop.CommandBeforeEventArgs before { get; } + public DbCommand cmd { get; } + public bool isclose { get; } + public PrepareCommandResult(Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose) + { + this.before = before; + this.cmd = cmd; + this.isclose = isclose; + } + } + PrepareCommandResult PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { var dt = DateTime.Now; DbCommand cmd = CreateCommand(); @@ -818,7 +831,7 @@ namespace FreeSql.Internal.CommonProvider var before = new Aop.CommandBeforeEventArgs(cmd); _util?._orm?.Aop.CommandBeforeHandler?.Invoke(_util._orm, before); - return (before, cmd, isclose); + return new PrepareCommandResult(before, cmd, isclose); } } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index cc93f542..7297122d 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -1,4 +1,5 @@ -using SafeObjectPool; +using FreeSql.Internal.Model; +using SafeObjectPool; using System; using System.Collections.Generic; using System.Data; @@ -48,14 +49,14 @@ namespace FreeSql.Internal.CommonProvider return ret; } #region QueryAsync multi - public Task<(List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task<(List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task<(List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -108,17 +109,17 @@ namespace FreeSql.Internal.CommonProvider } return Task.FromResult(false); }, cmdType, cmdText, cmdParms); - return (ret1, ret2); + return NaviteTuple.Create(ret1, ret2); } - public Task<(List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task<(List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task<(List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -194,17 +195,17 @@ namespace FreeSql.Internal.CommonProvider } return Task.FromResult(false); }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3); + return NaviteTuple.Create(ret1, ret2, ret3); } - public Task<(List, List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task<(List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task<(List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -303,17 +304,17 @@ namespace FreeSql.Internal.CommonProvider } return Task.FromResult(false); }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3, ret4); + return NaviteTuple.Create(ret1, ret2, ret3, ret4); } - public Task<(List, List, List, List, List)> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task<(List, List, List, List, List)> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task<(List, List, List, List, List)> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task<(List, List, List, List, List)> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return (new List(), new List(), new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -435,7 +436,7 @@ namespace FreeSql.Internal.CommonProvider } return Task.FromResult(false); }, cmdType, cmdText, cmdParms); - return (ret1, ret2, ret3, ret4, ret5); + return NaviteTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion @@ -700,7 +701,7 @@ namespace FreeSql.Internal.CommonProvider return val; } - async Task<(Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose)> PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) + async Task PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { DateTime dt = DateTime.Now; DbCommand cmd = CreateCommand(); @@ -744,7 +745,7 @@ namespace FreeSql.Internal.CommonProvider var before = new Aop.CommandBeforeEventArgs(cmd); _util?._orm?.Aop.CommandBeforeHandler?.Invoke(_util._orm, before); - return (before, cmd, isclose); + return new PrepareCommandResult(before, cmd, isclose); } } } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 83cdd9e6..2e414072 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -35,7 +35,7 @@ namespace FreeSql.Internal.CommonProvider public virtual bool IsGenerateCommandParameterWithLambda { get; set; } = false; public bool IsLazyLoading { get; set; } = false; - public abstract (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); + public abstract DbInfoResult GetDbInfo(Type type); public ICodeFirst ConfigEntity(Action> entity) => _commonUtils.ConfigEntity(entity); public ICodeFirst ConfigEntity(Type type, Action entity) => _commonUtils.ConfigEntity(type, entity); @@ -50,12 +50,22 @@ namespace FreeSql.Internal.CommonProvider return tableName; } public string GetComparisonDDLStatements() => - this.GetComparisonDDLStatements((typeof(TEntity), "")); + this.GetComparisonDDLStatements(new TypeAndName(typeof(TEntity), "")); public string GetComparisonDDLStatements(params Type[] entityTypes) => entityTypes == null ? null : - this.GetComparisonDDLStatements(entityTypes.Distinct().Select(a => (a, "")).ToArray()); + this.GetComparisonDDLStatements(entityTypes.Distinct().Select(a => new TypeAndName(a, "")).ToArray()); public string GetComparisonDDLStatements(Type entityType, string tableName) => - this.GetComparisonDDLStatements((entityType, GetTableNameLowerOrUpper(tableName))); - protected abstract string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects); + this.GetComparisonDDLStatements(new TypeAndName(entityType, GetTableNameLowerOrUpper(tableName))); + protected abstract string GetComparisonDDLStatements(params TypeAndName[] objects); + public class TypeAndName + { + public Type entityType { get; } + public string tableName { get; } + public TypeAndName(Type entityType, string tableName) + { + this.entityType = entityType; + this.tableName = tableName; + } + } static object syncStructureLock = new object(); object _dicSycedLock = new object(); @@ -72,16 +82,16 @@ namespace FreeSql.Internal.CommonProvider _dicSycedGetOrAdd(entityType).TryAdd(GetTableNameLowerOrUpper(tableName), true); public bool SyncStructure() => - this.SyncStructure((typeof(TEntity), "")); + this.SyncStructure(new TypeAndName(typeof(TEntity), "")); public bool SyncStructure(params Type[] entityTypes) => entityTypes == null ? false : - this.SyncStructure(entityTypes.Distinct().Select(a => (a, "")).ToArray()); + this.SyncStructure(entityTypes.Distinct().Select(a => new TypeAndName(a, "")).ToArray()); public bool SyncStructure(Type entityType, string tableName) => - this.SyncStructure((entityType, GetTableNameLowerOrUpper(tableName))); - protected bool SyncStructure(params (Type entityType, string tableName)[] objects) + this.SyncStructure(new TypeAndName(entityType, GetTableNameLowerOrUpper(tableName))); + protected bool SyncStructure(params TypeAndName[] objects) { if (objects == null) return false; - (Type entityType, string tableName)[] syncObjects = objects.Where(a => _dicSycedGetOrAdd(a.entityType).ContainsKey(GetTableNameLowerOrUpper(a.tableName)) == false && GetTableByEntity(a.entityType)?.DisableSyncStructure == false) - .Select(a => (a.entityType, GetTableNameLowerOrUpper(a.tableName))).ToArray(); + var syncObjects = objects.Where(a => _dicSycedGetOrAdd(a.entityType).ContainsKey(GetTableNameLowerOrUpper(a.tableName)) == false && GetTableByEntity(a.entityType)?.DisableSyncStructure == false) + .Select(a => new TypeAndName(a.entityType, GetTableNameLowerOrUpper(a.tableName))).ToArray(); if (syncObjects.Any() == false) return false; var before = new Aop.SyncStructureBeforeEventArgs(syncObjects.Select(a => a.entityType).ToArray()); _orm.Aop.SyncStructureBeforeHandler?.Invoke(this, before); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 3915bb22..07f7267e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -349,7 +349,7 @@ namespace FreeSql.Internal.CommonProvider } return ret; } - internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); @@ -383,7 +383,7 @@ namespace FreeSql.Internal.CommonProvider _trackToList?.Invoke(ret); return ret; } - internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { string sql = null; if (otherData?.Length > 0) @@ -399,7 +399,7 @@ namespace FreeSql.Internal.CommonProvider return ToListAfPrivate(sql, af, otherData); } #region ToChunk - internal void ToListAfChunkPrivate(int chunkSize, Action> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + internal void ToListAfChunkPrivate(int chunkSize, Action> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); @@ -453,7 +453,7 @@ namespace FreeSql.Internal.CommonProvider chunkDone(ret); } } - internal void ToListChunkPrivate(int chunkSize, Action> chunkDone, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + internal void ToListChunkPrivate(int chunkSize, Action> chunkDone, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { string sql = null; if (otherData?.Length > 0) @@ -487,7 +487,7 @@ namespace FreeSql.Internal.CommonProvider public T1 First() => this.ToOne(); - internal List ToListMrPrivate(string sql, (ReadAnonymousTypeInfo map, string field) af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + internal List ToListMrPrivate(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) { var type = typeof(TReturn); var dbParms = _params.ToArray(); @@ -521,7 +521,7 @@ namespace FreeSql.Internal.CommonProvider _trackToList?.Invoke(ret); return ret; } - internal List ToListMapReaderPrivate((ReadAnonymousTypeInfo map, string field) af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + internal List ToListMapReaderPrivate(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) { string sql = null; if (otherData?.Length > 0) @@ -536,15 +536,15 @@ namespace FreeSql.Internal.CommonProvider return ToListMrPrivate(sql, af, otherData); } - protected List ToListMapReader((ReadAnonymousTypeInfo map, string field) af) => ToListMapReaderPrivate(af, null); - protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + protected List ToListMapReader(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivate(af, null); + protected ReadAnonymousTypeAfInfo GetExpressionField(Expression newexp, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true); - return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); + return new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); } static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); public class GetAllFieldExpressionTreeInfo @@ -830,7 +830,7 @@ namespace FreeSql.Internal.CommonProvider }; }); } - protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() + protected ReadAnonymousTypeAfInfo GetAllFieldReflection() { var tb1 = _tables.First().Table; var type = tb1.TypeLazy ?? tb1.Type; @@ -879,7 +879,7 @@ namespace FreeSql.Internal.CommonProvider } map.Childs.Add(child); } - return (map, field.ToString()); + return new ReadAnonymousTypeAfInfo(map, field.ToString()); } string GetToDeleteWhere(string alias) @@ -1109,7 +1109,7 @@ namespace FreeSql.Internal.CommonProvider var index = 0; _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, true); - return this.ToListMapReader((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); + return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params)); @@ -1194,7 +1194,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); @@ -1230,7 +1230,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { string sql = null; if (otherData?.Length > 0) @@ -1260,7 +1260,7 @@ namespace FreeSql.Internal.CommonProvider public Task FirstAsync() => this.ToOneAsync(); - async internal Task> ToListMrPrivateAsync(string sql, (ReadAnonymousTypeInfo map, string field) af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + async internal Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) { var type = typeof(TReturn); var dbParms = _params.ToArray(); @@ -1295,7 +1295,7 @@ namespace FreeSql.Internal.CommonProvider _trackToList?.Invoke(ret); return ret; } - internal Task> ToListMapReaderPrivateAsync((ReadAnonymousTypeInfo map, string field) af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) + internal Task> ToListMapReaderPrivateAsync(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) { string sql = null; if (otherData?.Length > 0) @@ -1310,7 +1310,7 @@ namespace FreeSql.Internal.CommonProvider return ToListMrPrivateAsync(sql, af, otherData); } - protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) => ToListMapReaderPrivateAsync(af, null); + protected Task> ToListMapReaderAsync(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivateAsync(af, null); async protected Task InternalAvgAsync(Expression exp) { @@ -1355,7 +1355,7 @@ namespace FreeSql.Internal.CommonProvider var index = 0; _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, true); - return (await this.ToListMapReaderAsync((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); + return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); } #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 4ab36722..b960c579 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -43,11 +43,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 54adc140..83cb8b3d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -368,7 +368,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - static (ParameterExpression param, List members) GetExpressionStack(Expression exp) + static NaviteTuple> GetExpressionStack(Expression exp) { Expression tmpExp = exp; ParameterExpression param = null; @@ -392,7 +392,7 @@ namespace FreeSql.Internal.CommonProvider } } if (param == null) throw new Exception($"表达式错误,它的顶级对象不是 ParameterExpression:{exp}"); - return (param, members); + return NaviteTuple.Create(param, members); } static MethodInfo GetEntityValueWithPropertyNameMethod = typeof(EntityUtilExtensions).GetMethod("GetEntityValueWithPropertyName"); static ConcurrentDictionary> _dicTypeMethod = new ConcurrentDictionary>(); @@ -429,7 +429,9 @@ namespace FreeSql.Internal.CommonProvider if (expBody.NodeType != ExpressionType.MemberAccess) throw throwNavigateSelector; var collMem = expBody as MemberExpression; - var (membersParam, members) = GetExpressionStack(collMem.Expression); + var ges = GetExpressionStack(collMem.Expression); + var membersParam = ges.Item1; + var members = ges.Item2; var tb = _commonUtils.GetTableByEntity(collMem.Expression.Type); if (tb == null) throw throwNavigateSelector; var collMemElementType = (collMem.Type.IsGenericType ? collMem.Type.GetGenericArguments().FirstOrDefault() : collMem.Type.GetElementType()); @@ -484,7 +486,9 @@ namespace FreeSql.Internal.CommonProvider if (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) { - var (rightMembersParam, rightMembers) = GetExpressionStack(rightP1MemberExp.Expression); + var rightGes = GetExpressionStack(rightP1MemberExp.Expression); + var rightMembersParam = rightGes.Item1; + var rightMembers = rightGes.Item2; if (rightMembersParam != membersParam) throw throwNavigateSelector; var isCollMemEquals = rightMembers.Count == members.Count; if (isCollMemEquals) @@ -513,7 +517,9 @@ namespace FreeSql.Internal.CommonProvider } if (rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) { - var (leftMembersParam, leftMembers) = GetExpressionStack(leftP1MemberExp.Expression); + var leftGes = GetExpressionStack(leftP1MemberExp.Expression); + var leftMembersParam = leftGes.Item1; + var leftMembers = leftGes.Item2; if (leftMembersParam != membersParam) throw throwNavigateSelector; var isCollMemEquals = leftMembers.Count == members.Count; if (isCollMemEquals) @@ -715,7 +721,7 @@ namespace FreeSql.Internal.CommonProvider if (takeNumber > 0) { Select0Provider, TNavigate>.GetAllFieldExpressionTreeInfo af = null; - (ReadAnonymousTypeInfo map, string field) mf = default; + ReadAnonymousTypeAfInfo mf = default; if (selectExp == null) af = subSelect.GetAllFieldExpressionTreeLevelAll(); else mf = subSelect.GetExpressionField(selectExp); var sbSql = new StringBuilder(); @@ -890,10 +896,10 @@ namespace FreeSql.Internal.CommonProvider sbJoin.Clear(); Select0Provider, TNavigate>.GetAllFieldExpressionTreeInfo af = null; - (ReadAnonymousTypeInfo map, string field) mf = default; + ReadAnonymousTypeAfInfo mf = default; if (selectExp == null) af = subSelect.GetAllFieldExpressionTreeLevelAll(); else mf = subSelect.GetExpressionField(selectExp); - (string field, ReadAnonymousTypeInfo read)? otherData = null; + ReadAnonymousTypeAfInfo otherData = null; var sbSql = new StringBuilder(); if (_selectExpression == null) @@ -918,7 +924,7 @@ namespace FreeSql.Internal.CommonProvider read.Childs.Add(child); field.Append(", ").Append(_commonUtils.QuoteReadColumn(child.CsType, child.MapType, child.DbField)); } - otherData = (field.ToString(), read); + otherData = new ReadAnonymousTypeAfInfo(read, field.ToString()); } Func> getWhereDic = () => { @@ -978,14 +984,14 @@ namespace FreeSql.Internal.CommonProvider { #if net40 #else - if (selectExp == null) subList = await subSelect.ToListAfPrivateAsync(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); - else subList = await subSelect.ToListMrPrivateAsync(sbSql.ToString(), mf, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + if (selectExp == null) subList = await subSelect.ToListAfPrivateAsync(sbSql.ToString(), af, otherData == null ? null : new[] { new ReadAnonymousTypeOtherInfo(otherData.field, otherData.map, midList) }); + else subList = await subSelect.ToListMrPrivateAsync(sbSql.ToString(), mf, otherData == null ? null : new[] { new ReadAnonymousTypeOtherInfo(otherData.field, otherData.map, midList) }); #endif } else { - if (selectExp == null) subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); - else subList = subSelect.ToListMrPrivate(sbSql.ToString(), mf, otherData == null ? null : new[] { (otherData.Value.field, otherData.Value.read, midList) }); + if (selectExp == null) subList = subSelect.ToListAfPrivate(sbSql.ToString(), af, otherData == null ? null : new[] { new ReadAnonymousTypeOtherInfo(otherData.field, otherData.map, midList) }); + else subList = subSelect.ToListMrPrivate(sbSql.ToString(), mf, otherData == null ? null : new[] { new ReadAnonymousTypeOtherInfo(otherData.field, otherData.map, midList) }); } if (subList.Any() == false) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index d8ed2fe8..40e80a2d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -27,11 +27,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 03cf62e3..90177071 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -29,11 +29,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index e006c78b..36fb28ad 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -31,11 +31,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 76e9ddbc..b7b028bc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -33,11 +33,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 81fe63cf..33d85c40 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -35,11 +35,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index f3a953e6..2a7c84a8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -37,11 +37,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 79e5f4af..7942d59d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -39,11 +39,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index ebc99041..de4a8a57 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -41,11 +41,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 3e589e0a..46c642d8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -117,7 +117,7 @@ namespace FreeSql.Internal.CommonProvider if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); - return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; + return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; } public List Select(Expression, TReturn>> select) => ToList(select); @@ -185,7 +185,7 @@ namespace FreeSql.Internal.CommonProvider if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); - return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; + return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; } #endif } diff --git a/FreeSql/Internal/Model/DbToCs.cs b/FreeSql/Internal/Model/DbToCs.cs new file mode 100644 index 00000000..1d1de47d --- /dev/null +++ b/FreeSql/Internal/Model/DbToCs.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.Internal.Model +{ + public class DbToCs + { + public string csConvert { get; } + public string csParse { get; } + public string csStringify { get; } + public string csType { get; } + public Type csTypeInfo { get; } + public Type csNullableTypeInfo { get; } + public string csTypeValue { get; } + public string dataReaderMethod { get; } + public DbToCs(string csConvert, string csParse, string csStringify, string csType, Type csTypeInfo, Type csNullableTypeInfo, string csTypeValue, string dataReaderMethod) + { + this.csConvert = csConvert; + this.csParse = csParse; + this.csStringify = csStringify; + this.csType = csType; + this.csTypeInfo = csTypeInfo; + this.csNullableTypeInfo = csNullableTypeInfo; + this.csTypeValue = csTypeValue; + this.dataReaderMethod = dataReaderMethod; + } + } + + public static class CsToDb + { + public static CsToDb New(T type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue) => + new CsToDb(type, dbtype, dbtypeFull, isUnsigned, isnullable, defaultValue); + } + public class CsToDb + { + public T type { get; } + public string dbtype { get; } + public string dbtypeFull { get; } + public bool? isUnsigned { get; } + public bool? isnullable { get; } + public object defaultValue { get; } + public CsToDb(T type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue) + { + this.type = type; + this.dbtype = dbtype; + this.dbtypeFull = dbtypeFull; + this.isUnsigned = isUnsigned; + this.isnullable = isnullable; + this.defaultValue = defaultValue; + } + } + + + public class DbInfoResult + { + public int type { get; } + public string dbtype { get; } + public string dbtypeFull { get; } + public bool? isnullable { get; } + public object defaultValue { get; } + public DbInfoResult(int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue) + { + this.type = type; + this.dbtype = dbtype; + this.dbtypeFull = dbtypeFull; + this.isnullable = isnullable; + this.defaultValue = defaultValue; + } + } +} diff --git a/FreeSql/Internal/Model/NaviteTuple.cs b/FreeSql/Internal/Model/NaviteTuple.cs new file mode 100644 index 00000000..8e9dfd46 --- /dev/null +++ b/FreeSql/Internal/Model/NaviteTuple.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.Internal.Model +{ + public static class NaviteTuple + { + public static NaviteTuple Create(T1 item1, T2 item2) => new NaviteTuple(item1, item2); + public static NaviteTuple Create(T1 item1, T2 item2, T3 item3) => new NaviteTuple(item1, item2, item3); + public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) => new NaviteTuple(item1, item2, item3, item4); + public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) => new NaviteTuple(item1, item2, item3, item4, item5); + public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) => new NaviteTuple(item1, item2, item3, item4, item5, item6); + public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) => new NaviteTuple(item1, item2, item3, item4, item5, item6, item7); + public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) => new NaviteTuple(item1, item2, item3, item4, item5, item6, item7, item8); + public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9) => new NaviteTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9); + public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10) => new NaviteTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10); + } + + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public NaviteTuple(T1 item1, T2 item2) + { + Item1 = item1; + Item2 = item2; + } + } + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public NaviteTuple(T1 item1, T2 item2, T3 item3) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + } + } + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + } + } + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + } + } + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + } + } + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + } + } + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + } + } + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public T9 Item9 { get; } + public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + Item9 = item9; + } + } + public class NaviteTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public T9 Item9 { get; } + public T10 Item10 { get; } + public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + Item9 = item9; + Item10 = item10; + } + } +} \ No newline at end of file diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index d252db75..f7018bc7 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -18,4 +18,25 @@ namespace FreeSql.Internal.Model public bool IsEntity { get; set; } public bool IsDefaultCtor { get; set; } } + public class ReadAnonymousTypeAfInfo + { + public ReadAnonymousTypeInfo map { get; } + public string field { get; } + public ReadAnonymousTypeAfInfo(ReadAnonymousTypeInfo map, string field) + { + this.map = map; + this.field = field; + } + } + public class ReadAnonymousTypeOtherInfo { + public string field { get; } + public ReadAnonymousTypeInfo read { get; } + public List retlist { get; } + public ReadAnonymousTypeOtherInfo(string field, ReadAnonymousTypeInfo read, List retlist) + { + this.field = field; + this.read = read; + this.retlist = retlist; + } + } } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 8a52b7f6..6738bcf9 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -66,7 +66,7 @@ namespace FreeSql.Internal trytb.DbOldName = trytb.DbOldName?.ToUpper(); } if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; - var propsLazy = new List<(PropertyInfo, bool, bool)>(); + var propsLazy = new List>(); var propsNavObjs = new List(); var propsComment = CommonUtils.GetProperyCommentBySummary(entity); var columnsList = new List(); @@ -87,7 +87,7 @@ namespace FreeSql.Internal var getIsVirtual = p.GetGetMethod()?.IsVirtual;// trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; var setIsVirtual = setMethod?.IsVirtual; if (getIsVirtual == true || setIsVirtual == true) - propsLazy.Add((p, getIsVirtual == true, setIsVirtual == true)); + propsLazy.Add(NaviteTuple.Create(p, getIsVirtual == true, setIsVirtual == true)); } propsNavObjs.Add(p); continue; @@ -97,8 +97,8 @@ namespace FreeSql.Internal colattr = new ColumnAttribute { Name = p.Name, - DbType = tp.Value.dbtypeFull, - IsNullable = tp.Value.isnullable ?? true, + DbType = tp.dbtypeFull, + IsNullable = tp.isnullable ?? true, MapType = p.PropertyType }; if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable; @@ -111,7 +111,7 @@ namespace FreeSql.Internal else colattr.DbType = colattr.DbType.ToUpper(); - if (colattr._IsNullable == null && tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; + if (colattr._IsNullable == null && tp != null && tp.isnullable == null) colattr.IsNullable = tp.dbtypeFull.Contains("NOT NULL") == false; if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower(); @@ -419,7 +419,7 @@ namespace FreeSql.Internal foreach (var pnv in propsNavObjs) { var vp = propsLazy.Where(a => a.Item1 == pnv).FirstOrDefault(); - var isLazy = vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName); + var isLazy = vp != null && vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName); AddTableRef(common, trytb, pnv, isLazy, vp, cscode); } @@ -445,7 +445,7 @@ namespace FreeSql.Internal return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb; } - public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, (PropertyInfo, bool, bool)? vp, StringBuilder cscode) + public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, NaviteTuple vp, StringBuilder cscode) { var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}"; var propTypeName = pnv.PropertyType.IsGenericType ? diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs index a57f6098..2033b34b 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs @@ -17,35 +17,35 @@ namespace FreeSql.MsAccess public MsAccessCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (OleDbType.Boolean, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OleDbType.Boolean, "bit","bit", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(OleDbType.Boolean, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OleDbType.Boolean, "bit","bit", null, true, null) }, - { typeof(sbyte).FullName, (OleDbType.TinyInt, "decimal", "decimal(3,0) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OleDbType.TinyInt, "decimal", "decimal(3,0)", false, true, null) }, - { typeof(short).FullName, (OleDbType.SmallInt, "decimal","decimal(6,0) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OleDbType.SmallInt, "decimal", "decimal(6,0)", false, true, null) }, - { typeof(int).FullName, (OleDbType.Integer, "decimal", "decimal(11,0) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OleDbType.Integer, "decimal", "decimal(11,0)", false, true, null) }, - { typeof(long).FullName, (OleDbType.BigInt, "decimal","decimal(20,0) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OleDbType.BigInt, "decimal","decimal(20,0)", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(OleDbType.TinyInt, "decimal", "decimal(3,0) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OleDbType.TinyInt, "decimal", "decimal(3,0)", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OleDbType.SmallInt, "decimal","decimal(6,0) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OleDbType.SmallInt, "decimal", "decimal(6,0)", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OleDbType.Integer, "decimal", "decimal(11,0) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OleDbType.Integer, "decimal", "decimal(11,0)", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OleDbType.BigInt, "decimal","decimal(20,0) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OleDbType.BigInt, "decimal","decimal(20,0)", false, true, null) }, // access int long 类型是留给自动增长用的,所以这里全映射为 decimal - { typeof(byte).FullName, (OleDbType.UnsignedTinyInt, "decimal","decimal(3,0) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OleDbType.UnsignedTinyInt, "decimal","decimal(3,0)", true, true, null) }, - { typeof(ushort).FullName, (OleDbType.UnsignedSmallInt, "decimal","decimal(5,0) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OleDbType.UnsignedSmallInt, "decimal", "decimal(5,0)", true, true, null) }, - { typeof(uint).FullName, (OleDbType.UnsignedInt, "decimal", "decimal(10,0) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OleDbType.UnsignedInt, "decimal", "decimal(10,0)", true, true, null) }, - { typeof(ulong).FullName, (OleDbType.UnsignedBigInt, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OleDbType.UnsignedBigInt, "decimal", "decimal(20,0)", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(OleDbType.UnsignedTinyInt, "decimal","decimal(3,0) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OleDbType.UnsignedTinyInt, "decimal","decimal(3,0)", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OleDbType.UnsignedSmallInt, "decimal","decimal(5,0) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OleDbType.UnsignedSmallInt, "decimal", "decimal(5,0)", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(OleDbType.UnsignedInt, "decimal", "decimal(10,0) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OleDbType.UnsignedInt, "decimal", "decimal(10,0)", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New (OleDbType.UnsignedBigInt, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OleDbType.UnsignedBigInt, "decimal", "decimal(20,0)", true, true, null) }, - { typeof(double).FullName, (OleDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OleDbType.Double, "double", "double", false, true, null) }, - { typeof(float).FullName, (OleDbType.Currency, "single","single NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OleDbType.Currency, "single","single", false, true, null) }, - { typeof(decimal).FullName, (OleDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OleDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OleDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OleDbType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, CsToDb.New(OleDbType.Currency, "single","single NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OleDbType.Currency, "single","single", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OleDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OleDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(TimeSpan).FullName, (OleDbType.DBTime, "datetime","datetime NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OleDbType.DBTime, "datetime", "datetime",false, true, null) }, - { typeof(DateTime).FullName, (OleDbType.DBTimeStamp, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OleDbType.DBTimeStamp, "datetime", "datetime", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(OleDbType.DBTime, "datetime","datetime NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OleDbType.DBTime, "datetime", "datetime",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OleDbType.DBTimeStamp, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OleDbType.DBTimeStamp, "datetime", "datetime", false, true, null) }, - { typeof(byte[]).FullName, (OleDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, - { typeof(string).FullName, (OleDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(OleDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(OleDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, - { typeof(Guid).FullName, (OleDbType.Guid, "varchar", "varchar(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OleDbType.Guid, "varchar", "varchar(36)", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OleDbType.Guid, "varchar", "varchar(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OleDbType.Guid, "varchar", "varchar(36)", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -56,8 +56,8 @@ namespace FreeSql.MsAccess if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OleDbType.BigInt, "decimal", $"decimal(20,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OleDbType.Integer, "decimal", $"decimal(11,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OleDbType.BigInt, "decimal", $"decimal(20,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(OleDbType.Integer, "decimal", $"decimal(11,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -66,12 +66,12 @@ namespace FreeSql.MsAccess _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var sb = new StringBuilder(); var sbDeclare = new StringBuilder(); @@ -252,7 +252,7 @@ namespace FreeSql.MsAccess } return idxs; }; - Func> getColumnsByTableName = tn => + Func> getColumnsByTableName = tn => { int table_name_index = 0, column_name_index = 0, is_nullable_index = 0, data_type_index = 0, character_maximum_length_index = 0, character_octet_length_index = 0, numeric_precision_index = 0, numeric_scale_index = 0, @@ -322,7 +322,7 @@ namespace FreeSql.MsAccess } return dtRow; }; - var ret = new Dictionary(); + var ret = new Dictionary(); foreach (DataRow row in schemaColumns.Rows) { if (string.Compare(row[table_name_index]?.ToString(), tn, true) != 0) continue; @@ -341,7 +341,7 @@ namespace FreeSql.MsAccess var datatype = dataTypeRow[datatype_TypeName_index]?.ToString().ToUpper(); if (numeric_precision > 0 && numeric_scale > 0) datatype = $"{datatype}({numeric_precision},{numeric_scale})"; else if (character_maximum_length > 0 && character_octet_length > 0) datatype = $"{datatype}({character_maximum_length})"; - ret.Add(column_name, (column_name, datatype, is_nullable, is_identity, comment)); + ret.Add(column_name, new getColumnsByTableNameResult(column_name, datatype, is_nullable, is_identity, comment)); } return ret; }; @@ -441,6 +441,23 @@ namespace FreeSql.MsAccess return sb.Length == 0 ? null : sb.ToString(); } + class getColumnsByTableNameResult + { + public string column { get; } + public string sqlType { get; } + public bool is_nullable { get; } + public bool is_identity { get; } + public string comment { get; } + public getColumnsByTableNameResult(string column, string sqlType, bool is_nullable, bool is_identity, string comment) + { + this.column = column; + this.sqlType = sqlType; + this.is_nullable = is_nullable; + this.is_identity = is_identity; + this.comment = comment; + } + } + public override int ExecuteDDLStatements(string ddl) { if (string.IsNullOrEmpty(ddl)) return 0; diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 6cf5089d..f96474f4 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; @@ -16,42 +17,42 @@ namespace FreeSql.MySql public MySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (MySqlDbType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (MySqlDbType.Bit, "bit","bit(1)", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(MySqlDbType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(MySqlDbType.Bit, "bit","bit(1)", null, true, null) }, - { typeof(sbyte).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3)", false, true, null) }, - { typeof(short).FullName, (MySqlDbType.Int16, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (MySqlDbType.Int16, "smallint", "smallint(6)", false, true, null) }, - { typeof(int).FullName, (MySqlDbType.Int32, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (MySqlDbType.Int32, "int", "int(11)", false, true, null) }, - { typeof(long).FullName, (MySqlDbType.Int64, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (MySqlDbType.Int64, "bigint","bigint(20)", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(MySqlDbType.Byte, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(MySqlDbType.Byte, "tinyint", "tinyint(3)", false, true, null) }, + { typeof(short).FullName, CsToDb.New(MySqlDbType.Int16, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(MySqlDbType.Int16, "smallint", "smallint(6)", false, true, null) }, + { typeof(int).FullName, CsToDb.New(MySqlDbType.Int32, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(MySqlDbType.Int32, "int", "int(11)", false, true, null) }, + { typeof(long).FullName, CsToDb.New(MySqlDbType.Int64, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(MySqlDbType.Int64, "bigint","bigint(20)", false, true, null) }, - { typeof(byte).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned", true, true, null) }, - { typeof(ushort).FullName, (MySqlDbType.UInt16, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (MySqlDbType.UInt16, "smallint", "smallint(5) unsigned", true, true, null) }, - { typeof(uint).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned", true, true, null) }, - { typeof(ulong).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(MySqlDbType.UByte, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(MySqlDbType.UByte, "tinyint","tinyint(3) unsigned", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(MySqlDbType.UInt16, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(MySqlDbType.UInt16, "smallint", "smallint(5) unsigned", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(MySqlDbType.UInt32, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(MySqlDbType.UInt32, "int", "int(10) unsigned", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(MySqlDbType.UInt64, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(MySqlDbType.UInt64, "bigint", "bigint(20) unsigned", true, true, null) }, - { typeof(double).FullName, (MySqlDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (MySqlDbType.Double, "double", "double", false, true, null) }, - { typeof(float).FullName, (MySqlDbType.Float, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (MySqlDbType.Float, "float","float", false, true, null) }, - { typeof(decimal).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(double).FullName, CsToDb.New(MySqlDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(MySqlDbType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, CsToDb.New(MySqlDbType.Float, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(MySqlDbType.Float, "float","float", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(MySqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(MySqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(TimeSpan).FullName, (MySqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (MySqlDbType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3)", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(MySqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(MySqlDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(MySqlDbType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(MySqlDbType.DateTime, "datetime(3)", "datetime(3)", false, true, null) }, - { typeof(byte[]).FullName, (MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, - { typeof(string).FullName, (MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, - { typeof(Guid).FullName, (MySqlDbType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (MySqlDbType.VarChar, "char", "char(36)", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(MySqlDbType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(MySqlDbType.VarChar, "char", "char(36)", false, true, null) }, - { typeof(MygisPoint).FullName, (MySqlDbType.Geometry, "point", "point", false, null, new MygisPoint(0, 0)) }, - { typeof(MygisLineString).FullName, (MySqlDbType.Geometry, "linestring", "linestring", false, null, new MygisLineString(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) }, - { typeof(MygisPolygon).FullName, (MySqlDbType.Geometry, "polygon", "polygon", false, null, new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) }, - { typeof(MygisMultiPoint).FullName, (MySqlDbType.Geometry, "multipoint","multipoint", false, null, new MygisMultiPoint(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) }, - { typeof(MygisMultiLineString).FullName, (MySqlDbType.Geometry, "multilinestring","multilinestring", false, null, new MygisMultiLineString(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) }, - { typeof(MygisMultiPolygon).FullName, (MySqlDbType.Geometry, "multipolygon", "multipolygon", false, null, new MygisMultiPolygon(new[]{new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}}),new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})})) }, + { typeof(MygisPoint).FullName, CsToDb.New(MySqlDbType.Geometry, "point", "point", false, null, new MygisPoint(0, 0)) }, + { typeof(MygisLineString).FullName, CsToDb.New(MySqlDbType.Geometry, "linestring", "linestring", false, null, new MygisLineString(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) }, + { typeof(MygisPolygon).FullName, CsToDb.New(MySqlDbType.Geometry, "polygon", "polygon", false, null, new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) }, + { typeof(MygisMultiPoint).FullName, CsToDb.New(MySqlDbType.Geometry, "multipoint","multipoint", false, null, new MygisMultiPoint(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) }, + { typeof(MygisMultiLineString).FullName, CsToDb.New(MySqlDbType.Geometry, "multilinestring","multilinestring", false, null, new MygisMultiLineString(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) }, + { typeof(MygisMultiPolygon).FullName, CsToDb.New(MySqlDbType.Geometry, "multipolygon", "multipolygon", false, null, new MygisMultiPolygon(new[]{new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}}),new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})})) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -63,8 +64,8 @@ namespace FreeSql.MySql { var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (MySqlDbType.Set, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(MySqlDbType.Set, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -73,12 +74,12 @@ namespace FreeSql.MySql _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index e170694e..25bba990 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -1,5 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; +using FreeSql.Internal.Model; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; @@ -79,53 +80,53 @@ namespace FreeSql.MySql } } - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)MySqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)MySqlDbType.Bit, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)MySqlDbType.Byte, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, - { (int)MySqlDbType.Int16, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)MySqlDbType.Int24, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Int32, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Int64, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)MySqlDbType.Byte, new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, + { (int)MySqlDbType.Int16, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)MySqlDbType.Int24, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.Int32, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.Int64, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)MySqlDbType.UByte, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { (int)MySqlDbType.UInt16, ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") }, - { (int)MySqlDbType.UInt24, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.UInt32, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.UInt64, ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, + { (int)MySqlDbType.UByte, new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)MySqlDbType.UInt16, new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") }, + { (int)MySqlDbType.UInt24, new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.UInt32, new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.UInt64, new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, - { (int)MySqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)MySqlDbType.Float, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)MySqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)MySqlDbType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)MySqlDbType.Float, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)MySqlDbType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)MySqlDbType.Year, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)MySqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)MySqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)MySqlDbType.Year, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)MySqlDbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)MySqlDbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)MySqlDbType.Timestamp, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)MySqlDbType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)MySqlDbType.TinyBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.Blob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.MediumBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.LongBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.TinyBlob, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.Blob, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.MediumBlob, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.LongBlob, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.Binary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)MySqlDbType.VarBinary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)MySqlDbType.TinyText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.MediumText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.LongText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.TinyText, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.MediumText, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.LongText, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.Guid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, - { (int)MySqlDbType.String, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.VarString, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.Guid, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + { (int)MySqlDbType.String, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.VarString, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)MySqlDbType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)MySqlDbType.Set, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Set", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, - { (int)MySqlDbType.Enum, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Enum", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, + { (int)MySqlDbType.Set, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Set", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, + { (int)MySqlDbType.Enum, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Enum", typeof(Enum), typeof(Enum), "{0}", "GetInt64") }, - { (int)MySqlDbType.Geometry, ("(MygisGeometry)", "MygisGeometry.Parse({0}.Replace(StringifySplit, \"|\"))", "{0}.AsText().Replace(\"|\", StringifySplit)", "MygisGeometry", typeof(MygisGeometry), typeof(MygisGeometry), "{0}", "GetString") }, + { (int)MySqlDbType.Geometry, new DbToCs("(MygisGeometry)", "MygisGeometry.Parse({0}.Replace(StringifySplit, \"|\"))", "{0}.AsText().Replace(\"|\", StringifySplit)", "MygisGeometry", typeof(MygisGeometry), typeof(MygisGeometry), "{0}", "GetString") }, }; public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 0522f9c2..2edc8107 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -19,37 +19,37 @@ namespace FreeSql.Odbc.Dameng public OdbcDamengCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (OdbcType.Bit, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "number","number(1) NULL", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, "number","number(1) NULL", null, true, null) }, - { typeof(sbyte).FullName, (OdbcType.SmallInt, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "number", "number(4) NULL", false, true, null) }, - { typeof(short).FullName, (OdbcType.SmallInt, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "number", "number(6) NULL", false, true, null) }, - { typeof(int).FullName, (OdbcType.Int, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "number", "number(11) NULL", false, true, null) }, - { typeof(long).FullName, (OdbcType.BigInt, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "number","number(21) NULL", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(OdbcType.SmallInt, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OdbcType.SmallInt, "number", "number(4) NULL", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OdbcType.SmallInt, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OdbcType.SmallInt, "number", "number(6) NULL", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OdbcType.Int, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OdbcType.Int, "number", "number(11) NULL", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OdbcType.BigInt, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OdbcType.BigInt, "number","number(21) NULL", false, true, null) }, - { typeof(byte).FullName, (OdbcType.TinyInt, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, "number","number(3) NULL", true, true, null) }, - { typeof(ushort).FullName, (OdbcType.Int, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "number", "number(5) NULL", true, true, null) }, - { typeof(uint).FullName, (OdbcType.BigInt, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "number", "number(10) NULL", true, true, null) }, - { typeof(ulong).FullName, (OdbcType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "number", "number(20) NULL", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(OdbcType.TinyInt, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OdbcType.TinyInt, "number","number(3) NULL", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OdbcType.Int, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OdbcType.Int, "number", "number(5) NULL", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(OdbcType.BigInt, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OdbcType.BigInt, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OdbcType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OdbcType.Decimal, "number", "number(20) NULL", true, true, null) }, - { typeof(double).FullName, (OdbcType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "double", "double NULL", false, true, null) }, - { typeof(float).FullName, (OdbcType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "real","real NULL", false, true, null) }, - { typeof(decimal).FullName, (OdbcType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OdbcType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OdbcType.Double, "double", "double NULL", false, true, null) }, + { typeof(float).FullName, CsToDb.New(OdbcType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OdbcType.Real, "real","real NULL", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OdbcType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Decimal, "number", "number(10,2) NULL", false, true, null) }, //达梦8 ODBC 不支持 TimeSpan - //{ typeof(TimeSpan).FullName, (OdbcType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, - { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, - { typeof(DateTimeOffset).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + //{ typeof(TimeSpan).FullName, CsToDb.NewInfo(OdbcType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, - { typeof(byte[]).FullName, (OdbcType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, - { typeof(string).FullName, (OdbcType.NVarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(OdbcType.NVarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, - { typeof(Guid).FullName, (OdbcType.Char, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.Char, "char", "char(36) NULL", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OdbcType.Char, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.Char, "char", "char(36) NULL", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -60,8 +60,8 @@ namespace FreeSql.Odbc.Dameng if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -70,12 +70,12 @@ namespace FreeSql.Odbc.Dameng _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var userId = (_orm.Ado.MasterPool as OdbcDamengConnectionPool)?.UserId; if (string.IsNullOrEmpty(userId)) @@ -83,7 +83,7 @@ namespace FreeSql.Odbc.Dameng { userId = OdbcDamengConnectionPool.GetUserId(conn.Value.ConnectionString); } - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 + var seqcols = new List>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 var sb = new StringBuilder(); @@ -134,7 +134,7 @@ namespace FreeSql.Odbc.Dameng foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -234,10 +234,10 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); if (tbcol.Attribute.IsIdentity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; @@ -249,7 +249,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } @@ -304,7 +304,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 40b2d1eb..9d9ad075 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -1,5 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -161,35 +162,35 @@ namespace FreeSql.Odbc.Dameng throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); } - static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); static OdbcDamengDbFirst() { - var defaultDbToCs = new Dictionary() { - { "number(1)", ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + var defaultDbToCs = new Dictionary() { + { "number(1)", new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { "number(4)", ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, - { "number(6)", ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { "number(11)", ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { "number(21)", ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { "number(4)", new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { "number(6)", new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "number(11)", new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "number(21)", new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { "number(3)", ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { "number(5)", ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, - { "number(10)", ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, - { "number(20)", ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + { "number(3)", new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "number(5)", new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "number(10)", new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "number(20)", new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, - { "float(126)", ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { "float(63)", ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { "number(10,2)", ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { "float(126)", new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float(63)", new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "number(10,2)", new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { "interval day(2) to second(6)", ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { "date(7)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "timestamp(6)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "timestamp(6) with local time zone", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "interval day(2) to second(6)", new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date(7)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6) with local time zone", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "blob", ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { "blob", new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { "nvarchar2(255)", ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { "char(36 char)", ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + { "nvarchar2(255)", new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "char(36 char)", new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, }; foreach (var kv in defaultDbToCs) _dicDbToCs.TryAdd(kv.Key, kv.Value); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs index 47098780..26e218a9 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs @@ -22,9 +22,9 @@ namespace FreeSql.Odbc.Default OdbcUtils _utils; object _dicCsToDbLock = new object(); - Dictionary _dicCsToDb; + Dictionary> _dicCsToDb; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { if (_dicCsToDb == null) { @@ -35,35 +35,35 @@ namespace FreeSql.Odbc.Default var reg = new Regex(@"\([^\)]+\)", RegexOptions.IgnoreCase | RegexOptions.Compiled); Func deleteBrackets = str => reg.Replace(str, ""); - _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (OdbcType.Bit, _utils.Adapter.MappingOdbcTypeBit,$"{_utils.Adapter.MappingOdbcTypeBit} NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, _utils.Adapter.MappingOdbcTypeBit,_utils.Adapter.MappingOdbcTypeBit, null, true, null) }, + _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, _utils.Adapter.MappingOdbcTypeBit,$"{_utils.Adapter.MappingOdbcTypeBit} NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, _utils.Adapter.MappingOdbcTypeBit,_utils.Adapter.MappingOdbcTypeBit, null, true, null) }, - { typeof(sbyte).FullName, (OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, $"{_utils.Adapter.MappingOdbcTypeSmallInt} NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, false, true, null) }, - { typeof(short).FullName, (OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt,$"{_utils.Adapter.MappingOdbcTypeSmallInt} NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, false, true, null) }, - { typeof(int).FullName, (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, $"{_utils.Adapter.MappingOdbcTypeInt} NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, _utils.Adapter.MappingOdbcTypeInt, false, true, null) }, - { typeof(long).FullName, (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt,$"{_utils.Adapter.MappingOdbcTypeBigInt} NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt,_utils.Adapter.MappingOdbcTypeBigInt, false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, $"{_utils.Adapter.MappingOdbcTypeSmallInt} NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, false, true, null) }, + { typeof(short).FullName, CsToDb.New(OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt,$"{_utils.Adapter.MappingOdbcTypeSmallInt} NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OdbcType.SmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, _utils.Adapter.MappingOdbcTypeSmallInt, false, true, null) }, + { typeof(int).FullName, CsToDb.New(OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, $"{_utils.Adapter.MappingOdbcTypeInt} NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, _utils.Adapter.MappingOdbcTypeInt, false, true, null) }, + { typeof(long).FullName, CsToDb.New(OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt,$"{_utils.Adapter.MappingOdbcTypeBigInt} NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt,_utils.Adapter.MappingOdbcTypeBigInt, false, true, null) }, - { typeof(byte).FullName, (OdbcType.TinyInt, _utils.Adapter.MappingOdbcTypeTinyInt,$"{_utils.Adapter.MappingOdbcTypeTinyInt} NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, _utils.Adapter.MappingOdbcTypeTinyInt,_utils.Adapter.MappingOdbcTypeTinyInt, true, true, null) }, - { typeof(ushort).FullName, (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt,$"{_utils.Adapter.MappingOdbcTypeInt} NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, _utils.Adapter.MappingOdbcTypeInt, true, true, null) }, - { typeof(uint).FullName, (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, $"{_utils.Adapter.MappingOdbcTypeBigInt} NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, _utils.Adapter.MappingOdbcTypeBigInt, true, true, null) }, - { typeof(ulong).FullName, (OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(20,0)", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(OdbcType.TinyInt, _utils.Adapter.MappingOdbcTypeTinyInt,$"{_utils.Adapter.MappingOdbcTypeTinyInt} NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OdbcType.TinyInt, _utils.Adapter.MappingOdbcTypeTinyInt,_utils.Adapter.MappingOdbcTypeTinyInt, true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt,$"{_utils.Adapter.MappingOdbcTypeInt} NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, _utils.Adapter.MappingOdbcTypeInt, true, true, null) }, + { typeof(uint).FullName, CsToDb.New(OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, $"{_utils.Adapter.MappingOdbcTypeBigInt} NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, _utils.Adapter.MappingOdbcTypeBigInt, true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(20,0)", true, true, null) }, - { typeof(double).FullName, (OdbcType.Double, _utils.Adapter.MappingOdbcTypeDouble, $"{_utils.Adapter.MappingOdbcTypeDouble} NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, _utils.Adapter.MappingOdbcTypeDouble, _utils.Adapter.MappingOdbcTypeDouble, false, true, null) }, - { typeof(float).FullName, (OdbcType.Real, _utils.Adapter.MappingOdbcTypeReal,$"{_utils.Adapter.MappingOdbcTypeReal} NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, _utils.Adapter.MappingOdbcTypeReal,_utils.Adapter.MappingOdbcTypeReal, false, true, null) }, - { typeof(decimal).FullName, (OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(10,2)", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OdbcType.Double, _utils.Adapter.MappingOdbcTypeDouble, $"{_utils.Adapter.MappingOdbcTypeDouble} NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OdbcType.Double, _utils.Adapter.MappingOdbcTypeDouble, _utils.Adapter.MappingOdbcTypeDouble, false, true, null) }, + { typeof(float).FullName, CsToDb.New(OdbcType.Real, _utils.Adapter.MappingOdbcTypeReal,$"{_utils.Adapter.MappingOdbcTypeReal} NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OdbcType.Real, _utils.Adapter.MappingOdbcTypeReal,_utils.Adapter.MappingOdbcTypeReal, false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Decimal, _utils.Adapter.MappingOdbcTypeDecimal, $"{_utils.Adapter.MappingOdbcTypeDecimal}(10,2)", false, true, null) }, - { typeof(DateTime).FullName, (OdbcType.DateTime, _utils.Adapter.MappingOdbcTypeDateTime, $"{_utils.Adapter.MappingOdbcTypeDateTime} NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, _utils.Adapter.MappingOdbcTypeDateTime, _utils.Adapter.MappingOdbcTypeDateTime, false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, _utils.Adapter.MappingOdbcTypeDateTime, $"{_utils.Adapter.MappingOdbcTypeDateTime} NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, _utils.Adapter.MappingOdbcTypeDateTime, _utils.Adapter.MappingOdbcTypeDateTime, false, true, null) }, - { typeof(byte[]).FullName, (OdbcType.VarBinary, _utils.Adapter.MappingOdbcTypeVarBinary, $"{_utils.Adapter.MappingOdbcTypeVarBinary}(255)", false, null, new byte[0]) }, - { typeof(string).FullName, (OdbcType.VarChar, _utils.Adapter.MappingOdbcTypeVarChar, $"{_utils.Adapter.MappingOdbcTypeVarChar}(255)", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, _utils.Adapter.MappingOdbcTypeVarBinary, $"{_utils.Adapter.MappingOdbcTypeVarBinary}(255)", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, _utils.Adapter.MappingOdbcTypeVarChar, $"{_utils.Adapter.MappingOdbcTypeVarChar}(255)", false, null, "") }, - { typeof(Guid).FullName, (OdbcType.UniqueIdentifier, deleteBrackets(_utils.Adapter.MappingOdbcTypeUniqueIdentifier), $"{_utils.Adapter.MappingOdbcTypeUniqueIdentifier} NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.UniqueIdentifier, deleteBrackets(_utils.Adapter.MappingOdbcTypeUniqueIdentifier), _utils.Adapter.MappingOdbcTypeUniqueIdentifier, false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, deleteBrackets(_utils.Adapter.MappingOdbcTypeUniqueIdentifier), $"{_utils.Adapter.MappingOdbcTypeUniqueIdentifier} NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, deleteBrackets(_utils.Adapter.MappingOdbcTypeUniqueIdentifier), _utils.Adapter.MappingOdbcTypeUniqueIdentifier, false, true, null) }, }; } } } - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -74,8 +74,8 @@ namespace FreeSql.Odbc.Default if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, $"{_utils.Adapter.MappingOdbcTypeBigInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, $"{_utils.Adapter.MappingOdbcTypeInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, $"{_utils.Adapter.MappingOdbcTypeBigInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, $"{_utils.Adapter.MappingOdbcTypeInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -84,11 +84,11 @@ namespace FreeSql.Odbc.Default _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseDelete.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseDelete.cs deleted file mode 100644 index f2403466..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseDelete.cs +++ /dev/null @@ -1,31 +0,0 @@ -using FreeSql.Internal; -using System; -using System.Collections.Generic; -using System.Data; -using System.Text; -using System.Threading.Tasks; - -namespace FreeSql.Odbc.GBase -{ - - class OdbcGBaseDelete : Internal.CommonProvider.DeleteProvider where T1 : class - { - public OdbcGBaseDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) - { - } - - public override List ExecuteDeleted() - { - throw new NotImplementedException(); - } - -#if net40 -#else - public override Task> ExecuteDeletedAsync() - { - throw new NotImplementedException(); - } -#endif - } -} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs deleted file mode 100644 index ef74c2f1..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseSelect.cs +++ /dev/null @@ -1,176 +0,0 @@ -using FreeSql.Internal; -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; - -namespace FreeSql.Odbc.GBase -{ - - class OdbcGBaseSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class - { - - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) - { - if (_orm.CodeFirst.IsAutoSyncStructure) - _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - - if (_whereCascadeExpression.Any()) - foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); - - var sb = new StringBuilder(); - var tbUnionsGt0 = tbUnions.Count > 1; - for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) - { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); - if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); - var tbUnion = tbUnions[tbUnionsIdx]; - - var sbnav = new StringBuilder(); - sb.Append(_select); - - if (_skip > 0) - sb.Append("SKIP ").Append(_skip).Append(" "); - if (_limit > 0) - sb.Append("FIRST ").Append(_limit).Append(" "); - - if (_distinct) sb.Append("DISTINCT "); - sb.Append(field).Append(" \r\nFROM "); - var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); - var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); - for (var a = 0; a < tbsfrom.Length; a++) - { - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); - if (tbsjoin.Length > 0) - { - //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 - for (var b = 1; b < tbsfrom.Length; b++) - { - sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); - - if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); - else - { - var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; - sb.Append(" ON ").Append(onSql); - if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) - { - if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); - } - } - } - break; - } - else - { - if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); - if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); - } - if (a < tbsfrom.Length - 1) sb.Append(", "); - } - foreach (var tb in tbsjoin) - { - if (tb.Type == SelectTableInfoType.Parent) continue; - switch (tb.Type) - { - case SelectTableInfoType.LeftJoin: - sb.Append(" \r\nLEFT JOIN "); - break; - case SelectTableInfoType.InnerJoin: - sb.Append(" \r\nINNER JOIN "); - break; - case SelectTableInfoType.RightJoin: - sb.Append(" \r\nRIGHT JOIN "); - break; - } - sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); - if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); - } - if (_join.Length > 0) sb.Append(_join); - - sbnav.Append(_where); - if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); - - if (sbnav.Length > 0) - { - sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); - } - if (string.IsNullOrEmpty(_groupby) == false) - { - sb.Append(_groupby); - if (string.IsNullOrEmpty(_having) == false) - sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); - } - sb.Append(_orderby); - - sbnav.Clear(); - if (tbUnionsGt0) sb.Append(") ftb"); - } - return sb.Append(_tosqlAppendContent).ToString(); - } - - public OdbcGBaseSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcGBaseSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 - { - public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcGBaseSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); - } -} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs deleted file mode 100644 index 2701cfcb..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/OdbcGBaseUpdate.cs +++ /dev/null @@ -1,86 +0,0 @@ -using FreeSql.Internal; -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FreeSql.Odbc.GBase -{ - - class OdbcGBaseUpdate : Internal.CommonProvider.UpdateProvider where T1 : class - { - - public OdbcGBaseUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) - : base(orm, commonUtils, commonExpression, dywhere) - { - } - - public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - - protected override List RawExecuteUpdated() - { - throw new NotImplementedException(); - } - - protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) - { - if (_table.Primarys.Length == 1) - { - var pk = _table.Primarys.First(); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); - return; - } - caseWhen.Append("("); - var pkidx = 0; - foreach (var pk in _table.Primarys) - { - if (pkidx > 0) caseWhen.Append(" || '+' || "); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); - ++pkidx; - } - caseWhen.Append(")"); - } - - protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) - { - if (_table.Primarys.Length == 1) - { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); - return; - } - sb.Append("("); - var pkidx = 0; - foreach (var pk in _table.Primarys) - { - if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); - ++pkidx; - } - sb.Append(")"); - } - - protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) - { - if (_noneParameter == false) return; - var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; - if (dbtype == null) return; - - sb.Append("::").Append(dbtype); - } - -#if net40 -#else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); - - protected override Task> RawExecuteUpdatedAsync() - { - throw new NotImplementedException(); - } -#endif - } -} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs b/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs deleted file mode 100644 index 8036e82a..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/Curd/__OdbcGBaseInsert.cs +++ /dev/null @@ -1,149 +0,0 @@ -using FreeSql.Internal; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FreeSql.Odbc.GBase -{ - - class OdbcGBaseInsert : Internal.CommonProvider.InsertProvider where T1 : class - { - public OdbcGBaseInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) - : base(orm, commonUtils, commonExpression) - { - } - - public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - - protected override long RawExecuteIdentity() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - - long ret = 0; - Exception exception = null; - Aop.CurdBeforeEventArgs before = null; - - var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); - if (identCols.Any() == false) - { - before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - try - { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return 0; - } - sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); - before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - try - { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return ret; - } - - protected override List RawExecuteInserted() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var ret = _source.ToList(); - this.RawExecuteAffrows(); - return ret; - } - -#if net40 -#else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); - - async protected override Task RawExecuteIdentityAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - - long ret = 0; - Exception exception = null; - Aop.CurdBeforeEventArgs before = null; - - var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); - if (identCols.Any() == false) - { - before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - try - { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return 0; - } - sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); - before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - try - { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return ret; - } - async protected override Task> RawExecuteInsertedAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return new List(); - - var ret = _source.ToList(); - await this.RawExecuteAffrowsAsync(); - return ret; - } -#endif - } -} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs deleted file mode 100644 index c4830c6d..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/OdbcGBaseConnectionPool.cs +++ /dev/null @@ -1,249 +0,0 @@ -using SafeObjectPool; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Data.Odbc; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -//jdbc:gbasedbt-sqli://192.168.164.10:9088/gbasedb:GBASEDBTSERVER=gbaseserver;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;NEWCODESET=GB18030,GB18030-2000,5488; - -namespace FreeSql.Odbc.GBase -{ - - class OdbcGBaseConnectionPool : ObjectPool - { - - internal Action availableHandler; - internal Action unavailableHandler; - - public OdbcGBaseConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) - { - this.availableHandler = availableHandler; - this.unavailableHandler = unavailableHandler; - var policy = new OdbcPostgreSQLConnectionPoolPolicy - { - _pool = this, - Name = name - }; - this.Policy = policy; - policy.ConnectionString = connectionString; - } - - public void Return(Object obj, Exception exception, bool isRecreate = false) - { - if (exception != null && exception is OdbcException) - { - - if (exception is System.IO.IOException) - { - - base.SetUnavailable(exception); - - } - else if (obj.Value.Ping() == false) - { - - base.SetUnavailable(exception); - } - } - base.Return(obj, isRecreate); - } - } - - class OdbcPostgreSQLConnectionPoolPolicy : IPolicy - { - - internal OdbcGBaseConnectionPool _pool; - public string Name { get; set; } = "GBase OdbcConnection 对象池"; - public int PoolSize { get; set; } = 50; - public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); - public int AsyncGetCapacity { get; set; } = 10000; - public bool IsThrowGetTimeoutException { get; set; } = true; - public int CheckAvailableInterval { get; set; } = 5; - - static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - private string _connectionString; - public string ConnectionString - { - get => _connectionString; - set - { - _connectionString = value ?? ""; - - var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; - Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; - var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); - PoolSize = poolsize + connStrIncr; - _connectionString = m.Success ? - Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : - $"{_connectionString};Max pool size={PoolSize}"; - - pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) - { - IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } - - var minPoolSize = 0; - pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; - m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); - if (m.Success) - { - minPoolSize = int.Parse(m.Groups[1].Value); - _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); - } - - FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); - } - } - - public bool OnCheckAvailable(Object obj) - { - if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); - return obj.Value.Ping(true); - } - - public DbConnection OnCreate() - { - var conn = new OdbcConnection(_connectionString); - return conn; - } - - public void OnDestroy(DbConnection obj) - { - if (obj.State != ConnectionState.Closed) obj.Close(); - obj.Dispose(); - } - - public void OnGet(Object obj) - { - - if (_pool.IsAvailable) - { - if (obj.Value == null) - { - if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) - throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); - return; - } - - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) - { - - try - { - obj.Value.Open(); - } - catch (Exception ex) - { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } - -#if net40 -#else - async public Task OnGetAsync(Object obj) - { - - if (_pool.IsAvailable) - { - if (obj.Value == null) - { - if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) - throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); - return; - } - - if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) - { - - try - { - await obj.Value.OpenAsync(); - } - catch (Exception ex) - { - if (_pool.SetUnavailable(ex) == true) - throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); - } - } - } - } -#endif - - public void OnGetTimeout() - { - - } - - public void OnReturn(Object obj) - { - - } - - public void OnAvailable() - { - _pool.availableHandler?.Invoke(); - } - - public void OnUnavailable() - { - _pool.unavailableHandler?.Invoke(); - } - } - - static class DbConnectionExtensions - { - - static DbCommand PingCommand(DbConnection conn) - { - var cmd = conn.CreateCommand(); - cmd.CommandTimeout = 5; - cmd.CommandText = "select 1"; - return cmd; - } - public static bool Ping(this DbConnection that, bool isThrow = false) - { - try - { - PingCommand(that).ExecuteNonQuery(); - return true; - } - catch - { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } - -#if net40 -#else - async public static Task PingAsync(this DbConnection that, bool isThrow = false) - { - try - { - await PingCommand(that).ExecuteNonQueryAsync(); - return true; - } - catch - { - if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } - if (isThrow) throw; - return false; - } - } -#endif - } -} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs deleted file mode 100644 index 96a01d0e..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseAdo/__OdbcGBaseAdo.cs +++ /dev/null @@ -1,76 +0,0 @@ -using FreeSql.Internal; -using FreeSql.Internal.Model; -using SafeObjectPool; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data.Common; -using System.Data.Odbc; -using System.Text; -using System.Threading; - -namespace FreeSql.Odbc.GBase -{ - class OdbcGBaseAdo : FreeSql.Internal.CommonProvider.AdoProvider - { - public OdbcGBaseAdo() : base(DataType.PostgreSQL) { } - public OdbcGBaseAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.PostgreSQL) - { - base._util = util; - if (connectionFactory != null) - { - MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.PostgreSQL, connectionFactory); - return; - } - if (!string.IsNullOrEmpty(masterConnectionString)) - MasterPool = new OdbcGBaseConnectionPool("主库", masterConnectionString, null, null); - if (slaveConnectionStrings != null) - { - foreach (var slaveConnectionString in slaveConnectionStrings) - { - var slavePool = new OdbcGBaseConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); - SlavePools.Add(slavePool); - } - } - } - - public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) - { - if (param == null) return "NULL"; - if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) - param = Utils.GetDataReaderValue(mapType, param); - if (param is bool || param is bool?) - return (bool)param ? "'t'" : "'f'"; - else if (param is string || param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - else if (param is Enum) - return ((Enum)param).ToInt64(); - else if (decimal.TryParse(string.Concat(param), out var trydec)) - return param; - else if (param is DateTime || param is DateTime?) - return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); - else if (param is TimeSpan || param is TimeSpan?) - return ((TimeSpan)param).Ticks / 10; - else if (param is byte[]) - return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'"; - else if (param is IEnumerable) - return AddslashesIEnumerable(param, mapType, mapColumn); - - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); - } - - protected override DbCommand CreateCommand() - { - return new OdbcCommand(); - } - - protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) - { - var rawPool = pool as OdbcGBaseConnectionPool; - if (rawPool != null) rawPool.Return(conn, ex); - else pool.Return(conn); - } - - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); - } -} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs b/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs deleted file mode 100644 index 0d797f6f..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/OdbcGBaseProvider.cs +++ /dev/null @@ -1,64 +0,0 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Threading; - -namespace FreeSql.Odbc.GBase -{ - - public class OdbcGBaseProvider : IFreeSql - { - - static OdbcGBaseProvider() - { - } - - public ISelect Select() where T1 : class => new OdbcGBaseSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OdbcGBaseSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OdbcGBaseInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OdbcGBaseUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OdbcGBaseUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OdbcGBaseDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OdbcGBaseDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } - public OdbcGBaseProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) - { - this.InternalCommonUtils = new OdbcGBaseUtils(this); - this.InternalCommonExpression = new OdbcGBaseExpression(this.InternalCommonUtils); - - this.Ado = new OdbcGBaseAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); - this.Aop = new AopProvider(); - - this.DbFirst = new OdbcGBaseDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - this.CodeFirst = new OdbcGBaseCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - } - - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - - ~OdbcGBaseProvider() => this.Dispose(); - int _disposeCounter; - public void Dispose() - { - if (Interlocked.Increment(ref _disposeCounter) != 1) return; - (this.Ado as AdoProvider)?.Dispose(); - } - } -} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs deleted file mode 100644 index 9f3b6b11..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseCodeFirst.cs +++ /dev/null @@ -1,388 +0,0 @@ -using FreeSql.Internal; -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Odbc; -using System.Linq; -using System.Text; - -namespace FreeSql.Odbc.GBase -{ - - class OdbcGBaseCodeFirst : Internal.CommonProvider.CodeFirstProvider - { - public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } - public OdbcGBaseCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } - - static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - - { typeof(sbyte).FullName, (OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, - { typeof(short).FullName, (OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, - { typeof(int).FullName, (OdbcType.Int, "integer","integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "integer", "integer", false, true, null) }, - { typeof(long).FullName, (OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "bigint", "bigint", false, true, null) }, - - { typeof(byte).FullName, (OdbcType.SmallInt, "byte","byte NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (OdbcType.SmallInt, "byte", "byte", false, true, null) }, - { typeof(ushort).FullName, (OdbcType.Int, "integer","integer NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "integer", "integer", false, true, null) }, - { typeof(uint).FullName, (OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "bigint", "bigint", false, true, null) }, - { typeof(ulong).FullName, (OdbcType.Decimal, "decimal","decimal(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "decimal", "decimal(20,0)", false, true, null) }, - - { typeof(float).FullName, (OdbcType.Real, "smallfloat","smallfloat NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "smallfloat", "smallfloat", false, true, null) }, - { typeof(double).FullName, (OdbcType.Double, "float","float NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "float", "float", false, true, null) }, - { typeof(decimal).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - - { typeof(string).FullName, (OdbcType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, - - { typeof(TimeSpan).FullName, (OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp", false, true, null) }, - - { typeof(bool).FullName, (OdbcType.Bit, "char","char(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "char","char(1)", null, true, null) }, - { typeof(Byte[]).FullName, (OdbcType.VarBinary, "blob", "blob", false, null, new byte[0]) }, - - { typeof(Guid).FullName, (OdbcType.Char, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.Char, "char", "char(36)", false, true, null) }, - }; - - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) - { - var isarray = type.FullName != "System.Byte[]" && type.IsArray; - var elementType = isarray ? type.GetElementType() : type; - var info = GetDbInfoNoneArray(elementType); - if (info == null) return null; - return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable, info.Value.defaultValue); - } - (OdbcType type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfoNoneArray(Type type) - { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (OdbcType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); - if (type.IsArray) return null; - var enumType = type.IsEnum ? type : null; - if (enumType == null && type.IsNullableType()) - { - var genericTypes = type.GetGenericArguments(); - if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); - } - if (enumType != null) - { - var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OdbcType.Int, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OdbcType.BigInt, "integer", $"integer{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); - if (_dicCsToDb.ContainsKey(type.FullName) == false) - { - lock (_dicCsToDbLock) - { - if (_dicCsToDb.ContainsKey(type.FullName) == false) - _dicCsToDb.Add(type.FullName, newItem); - } - } - return (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); - } - return null; - } - - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) - { - var sb = new StringBuilder(); - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 - - foreach (var obj in objects) - { - if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(obj.entityType); - if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); - if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); - var tbname = _commonUtils.SplitTableName(tb.DbName); - if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; - - var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; - if (string.IsNullOrEmpty(obj.tableName) == false) - { - var tbtmpname = _commonUtils.SplitTableName(obj.tableName); - if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] }; - if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) - { - tbname = tbtmpname; - tboldname = null; - } - } - //codefirst 不支持表名、模式名、数据库名中带 . - - if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 - sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); - - var sbalter = new StringBuilder(); - var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tbname)) == null) - { //表不存在 - if (tboldname != null) - { - if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tboldname)) == null) - //旧表不存在 - tboldname = null; - } - if (tboldname == null) - { - //创建表 - var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); - foreach (var tbcol in tb.ColumnsByPosition) - { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); - } - if (tb.Primarys.Any()) - { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); - //创建表的索引 - foreach (var uk in tb.Indexes) - { - sb.Append("CREATE "); - if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); - foreach (var tbcol in uk.Columns) - { - sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); - if (tbcol.IsDesc) sb.Append(" DESC"); - sb.Append(", "); - } - sb.Remove(sb.Length - 2, 2).Append(");\r\n"); - } - //备注 - foreach (var tbcol in tb.ColumnsByPosition) - { - if (string.IsNullOrEmpty(tbcol.Comment) == false) - sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); - } - continue; - } - //如果新表,旧表在一个数据库和模式下,直接修改表名 - if (string.Compare(tbname[0], tboldname[0], true) == 0) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); - else - { - //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 - istmpatler = true; - } - } - else - tboldname = null; //如果新表已经存在,不走改表名逻辑 - - //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = _commonUtils.FormatSql(@" -select -a.attname, -t.typname, -case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, -case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, -case when a.attnotnull then '0' else '1' end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, ---e.adsrc, -a.attndims, -d.description as comment -from pg_class c -inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid -inner join pg_type t on t.oid = a.atttypid -left join pg_type t2 on t2.oid = t.typelem -left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum -left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum -inner join pg_namespace ns on ns.oid = c.relnamespace -inner join pg_namespace ns2 on ns2.oid = t.typnamespace -where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => - { - var attndims = int.Parse(string.Concat(a[6])); - var type = string.Concat(a[1]); - var sqlType = string.Concat(a[3]); - var max_length = long.Parse(string.Concat(a[2])); - switch (sqlType.ToLower()) - { - case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; - default: max_length *= 8; break; - } - if (type.StartsWith("_")) - { - type = type.Substring(1); - if (attndims == 0) attndims++; - } - if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); - return new - { - column = string.Concat(a[0]), - sqlType = string.Concat(sqlType), - max_length = long.Parse(string.Concat(a[2])), - is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]) == "1", //string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), - attndims, - comment = string.Concat(a[7]) - }; - }, StringComparer.CurrentCultureIgnoreCase); - - if (istmpatler == false) - { - foreach (var tbcol in tb.ColumnsByPosition) - { - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) - { - var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || - tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - { - if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) - { - if (tbcol.Attribute.IsNullable == false) - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); - } - } - if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) - //修改列名 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); - if (isCommentChanged) - sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); - continue; - } - //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); - if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); - } - var dsuksql = _commonUtils.FormatSql(@" -select -c.attname, -b.relname, -case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, -case when indisunique = 't' then 1 else 0 end IsUnique -from pg_index a -inner join pg_class b on b.oid = a.indexrelid -inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid -inner join pg_namespace ns on ns.oid = b.relnamespace -inner join pg_class d on d.oid = a.indrelid -where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); - foreach (var uk in tb.Indexes) - { - if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) - { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); - sbalter.Append("CREATE "); - if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); - foreach (var tbcol in uk.Columns) - { - sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); - if (tbcol.IsDesc) sbalter.Append(" DESC"); - sbalter.Append(", "); - } - sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); - } - } - } - if (istmpatler == false) - { - sb.Append(sbalter); - continue; - } - var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select pg_constraint.conname as pk_name from pg_constraint -inner join pg_class on pg_constraint.conrelid = pg_class.oid -inner join pg_namespace on pg_namespace.oid = pg_class.relnamespace -where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contype='p' -", tbname))?.ToString(); - if (string.IsNullOrEmpty(oldpk) == false) - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); - - //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); - //创建临时表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); - foreach (var tbcol in tb.ColumnsByPosition) - { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); - } - if (tb.Primarys.Any()) - { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append("),"); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); - //备注 - foreach (var tbcol in tb.ColumnsByPosition) - { - if (string.IsNullOrEmpty(tbcol.Comment) == false) - sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); - } - sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.ColumnsByPosition) - sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); - foreach (var tbcol in tb.ColumnsByPosition) - { - var insertvalue = "NULL"; - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) - { - insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) - insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"coalesce({insertvalue},{tbcol.DbDefaultValue})"; - } - else if (tbcol.Attribute.IsNullable == false) - insertvalue = tbcol.DbDefaultValue; - sb.Append(insertvalue).Append(", "); - } - sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); - sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); - //创建表的索引 - foreach (var uk in tb.Indexes) - { - sb.Append("CREATE "); - if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); - foreach (var tbcol in uk.Columns) - { - sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); - if (tbcol.IsDesc) sb.Append(" DESC"); - sb.Append(", "); - } - sb.Remove(sb.Length - 2, 2).Append(");\r\n"); - } - } - foreach (var seqcol in seqcols) - { - var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); - var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); - var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); - sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); - sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); - if (seqcol.Item3) - { - sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);\r\n"); - sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); - } - } - return sb.Length == 0 ? null : sb.ToString(); - } - } -} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs deleted file mode 100644 index 245ab0cf..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseDbFirst.cs +++ /dev/null @@ -1,480 +0,0 @@ -using FreeSql.DatabaseModel; -using FreeSql.Internal; -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Odbc; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -namespace FreeSql.Odbc.GBase -{ - class OdbcGBaseDbFirst : IDbFirst - { - IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - public OdbcGBaseDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) - { - _orm = orm; - _commonUtils = commonUtils; - _commonExpression = commonExpression; - } - - public int GetDbType(DbColumnInfo column) => (int)GetOdbcType(column); - OdbcType GetOdbcType(DbColumnInfo column) - { - var dbtype = column.DbTypeText; - var isarray = dbtype.EndsWith("[]"); - if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); - OdbcType ret = OdbcType.VarChar; - switch (dbtype.ToLower().TrimStart('_')) - { - case "int2": ret = OdbcType.SmallInt; break; - case "int4": ret = OdbcType.Int; break; - case "int8": ret = OdbcType.BigInt; break; - case "numeric": ret = OdbcType.Numeric; break; - case "float4": ret = OdbcType.Real; break; - case "float8": ret = OdbcType.Double; break; - case "money": ret = OdbcType.Numeric; break; - - case "bpchar": ret = OdbcType.Char; break; - case "varchar": ret = OdbcType.VarChar; break; - case "text": ret = OdbcType.Text; break; - - case "timestamp": ret = OdbcType.DateTime; break; - case "timestamptz": ret = OdbcType.DateTime; break; - case "date": ret = OdbcType.Date; break; - case "time": ret = OdbcType.Time; break; - case "timetz": ret = OdbcType.Time; break; - case "interval": ret = OdbcType.Time; break; - - case "bool": ret = OdbcType.Bit; break; - case "bytea": ret = OdbcType.VarBinary; break; - case "bit": ret = OdbcType.Bit; break; - case "varbit": ret = OdbcType.VarBinary; break; - - case "json": ret = OdbcType.VarChar; break; - case "jsonb": ret = OdbcType.VarChar; break; - case "uuid": ret = OdbcType.UniqueIdentifier; break; - } - return ret; - } - - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)OdbcType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)OdbcType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)OdbcType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)OdbcType.Numeric, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)OdbcType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)OdbcType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - - { (int)OdbcType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - - { (int)OdbcType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - - { (int)OdbcType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)OdbcType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - - { (int)OdbcType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, - }; - - public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; - public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; - public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; - public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; - public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; - public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; - public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; - - public List GetDatabases() - { - var sql = @" select datname from pg_database where datname not in ('template1', 'template0')"; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); - } - - public List GetTablesByDatabase(params string[] database) - { - var olddatabase = ""; - using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) - { - olddatabase = conn.Value.Database; - } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; - var tables = new List(); - - foreach (var db in dbs) - { - if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; - - var loc1 = new List(); - var loc2 = new Dictionary(); - var loc3 = new Dictionary>(); - - var sql = $@" -select -b.nspname || '.' || a.tablename, -a.schemaname, -a.tablename , -d.description, -'TABLE' -from pg_tables a -inner join pg_namespace b on b.nspname = a.schemaname -inner join pg_class c on c.relnamespace = b.oid and c.relname = a.tablename -left join pg_description d on d.objoid = c.oid and objsubid = 0 -where a.schemaname not in ('pg_catalog', 'information_schema', 'topology') -and b.nspname || '.' || a.tablename not in ('public.spatial_ref_sys') - -union all - -select -b.nspname || '.' || a.relname, -b.nspname, -a.relname, -d.description, -'VIEW' -from pg_class a -inner join pg_namespace b on b.oid = a.relnamespace -left join pg_description d on d.objoid = a.oid and objsubid = 0 -where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('m','v') -and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews') -"; - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var loc6 = new List(); - var loc66 = new List(); - var loc6_1000 = new List(); - var loc66_1000 = new List(); - foreach (object[] row in ds) - { - var object_id = string.Concat(row[0]); - var owner = string.Concat(row[1]); - var table = string.Concat(row[2]); - var comment = string.Concat(row[3]); - Enum.TryParse(string.Concat(row[4]), out var type); - loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); - loc3.Add(object_id, new Dictionary()); - switch (type) - { - case DbTableType.VIEW: - case DbTableType.TABLE: - loc6_1000.Add(object_id); - if (loc6_1000.Count >= 500) - { - loc6.Add(loc6_1000.ToArray()); - loc6_1000.Clear(); - } - break; - case DbTableType.StoreProcedure: - loc66_1000.Add(object_id); - if (loc66_1000.Count >= 500) - { - loc66.Add(loc66_1000.ToArray()); - loc66_1000.Clear(); - } - break; - } - } - if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); - if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); - - if (loc6.Count == 0) return loc1; - var loc8 = new StringBuilder().Append("("); - for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) - { - if (loc8idx > 0) loc8.Append(" OR "); - loc8.Append("a.table_name in ("); - for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) - { - if (loc8idx2 > 0) loc8.Append(","); - loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); - } - loc8.Append(")"); - } - loc8.Append(")"); - - sql = $@" -select -ns.nspname || '.' || c.relname as id, -a.attname, -t.typname, -case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, -case when t.typelem = 0 then t.typname else t2.typname end, -case when a.attnotnull then 0 else 1 end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, ---e.adsrc as is_identity, -d.description as comment, -a.attndims, -case when t.typelem = 0 then t.typtype else t2.typtype end, -ns2.nspname, -a.attnum -from pg_class c -inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid -inner join pg_type t on t.oid = a.atttypid -left join pg_type t2 on t2.oid = t.typelem -left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum -left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum -inner join pg_namespace ns on ns.oid = c.relnamespace -inner join pg_namespace ns2 on ns2.oid = t.typnamespace -where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")}"; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - foreach (object[] row in ds) - { - var object_id = string.Concat(row[0]); - var column = string.Concat(row[1]); - var type = string.Concat(row[2]); - var max_length = int.Parse(string.Concat(row[3])); - var sqlType = string.Concat(row[4]); - var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]) == "1"; //string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); - var comment = string.Concat(row[7]); - int attndims = int.Parse(string.Concat(row[8])); - string typtype = string.Concat(row[9]); - string owner = string.Concat(row[10]); - int attnum = int.Parse(string.Concat(row[11])); - switch (sqlType.ToLower()) - { - case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; - default: max_length *= 8; break; - } - if (max_length <= 0) max_length = -1; - if (type.StartsWith("_")) - { - type = type.Substring(1); - if (attndims == 0) attndims++; - } - if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); - if (max_length > 0) - { - switch (sqlType.ToLower()) - { - //case "numeric": sqlType += $"({max_length})"; break; - case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; - } - } - - loc3[object_id].Add(column, new DbColumnInfo - { - Name = column, - MaxLength = max_length, - IsIdentity = is_identity, - IsNullable = is_nullable, - IsPrimary = false, - DbTypeText = type, - DbTypeTextFull = sqlType, - Table = loc2[object_id], - Coment = comment - }); - loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); - loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); - } - - sql = $@" -select -ns.nspname || '.' || d.relname as table_id, -c.attname, -b.relname as index_id, -case when a.indisunique then 1 else 0 end IsUnique, -case when a.indisprimary then 1 else 0 end IsPrimary, -case when a.indisclustered then 0 else 1 end IsClustered, -case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, -a.indkey::text, -c.attnum -from pg_index a -inner join pg_class b on b.oid = a.indexrelid -inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid -inner join pg_namespace ns on ns.oid = b.relnamespace -inner join pg_class d on d.oid = a.indrelid -where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} -"; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var indexColumns = new Dictionary>(); - var uniqueColumns = new Dictionary>(); - foreach (object[] row in ds) - { - var object_id = string.Concat(row[0]); - var column = string.Concat(row[1]); - var index_id = string.Concat(row[2]); - var is_unique = string.Concat(row[3]) == "1"; - var is_primary_key = string.Concat(row[4]) == "1"; - var is_clustered = string.Concat(row[5]) == "1"; - var is_desc = string.Concat(row[6]) == "1"; - var inkey = string.Concat(row[7]).Split(' '); - var attnum = int.Parse(string.Concat(row[8])); - attnum = int.Parse(inkey[attnum - 1]); - foreach (string tc in loc3[object_id].Keys) - { - if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) - { - column = tc; - break; - } - } - if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; - var loc9 = loc3[object_id][column]; - if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - - Dictionary loc10 = null; - DbIndexInfo loc11 = null; - if (!indexColumns.TryGetValue(object_id, out loc10)) - indexColumns.Add(object_id, loc10 = new Dictionary()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new DbIndexInfo()); - loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); - if (is_unique && !is_primary_key) - { - if (!uniqueColumns.TryGetValue(object_id, out loc10)) - uniqueColumns.Add(object_id, loc10 = new Dictionary()); - if (!loc10.TryGetValue(index_id, out loc11)) - loc10.Add(index_id, loc11 = new DbIndexInfo()); - loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); - } - } - foreach (var object_id in indexColumns.Keys) - { - foreach (var column in indexColumns[object_id]) - loc2[object_id].IndexesDict.Add(column.Key, column.Value); - } - foreach (var object_id in uniqueColumns.Keys) - { - foreach (var column in uniqueColumns[object_id]) - { - column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); - loc2[object_id].UniquesDict.Add(column.Key, column.Value); - } - } - - sql = $@" -select -ns.nspname || '.' || b.relname as table_id, -array(select attname from pg_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, -a.conname as FKId, -ns2.nspname || '.' || c.relname as ref_table_id, -1 as IsForeignKey, -array(select attname from pg_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, -null ref_sln, -null ref_table -from pg_constraint a -inner join pg_class b on b.oid = a.conrelid -inner join pg_class c on c.oid = a.confrelid -inner join pg_namespace ns on ns.oid = b.relnamespace -inner join pg_namespace ns2 on ns2.oid = c.relnamespace -where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} -"; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; - - var fkColumns = new Dictionary>(); - foreach (object[] row in ds) - { - var table_id = string.Concat(row[0]); - var column = row[1] as string[]; - var fk_id = string.Concat(row[2]); - var ref_table_id = string.Concat(row[3]); - var is_foreign_key = string.Concat(row[4]) == "1"; - var referenced_column = row[5] as string[]; - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); - - if (loc2.ContainsKey(ref_table_id) == false) continue; - - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); - - for (int a = 0; a < column.Length; a++) - { - loc13.Columns.Add(loc3[table_id][column[a]]); - loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); - } - } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); - - foreach (var table_id in loc3.Keys) - { - foreach (var loc5 in loc3[table_id].Values) - { - loc2[table_id].Columns.Add(loc5); - if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); - if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); - } - } - foreach (var loc4 in loc2.Values) - { - //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) - //{ - // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) - // { - // loc5.Column.IsPrimary = true; - // loc4.Primarys.Add(loc5.Column); - // } - //} - loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc4.Columns.Sort((c1, c2) => - { - int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); - if (compare == 0) - { - bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); - bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); - compare = b2.CompareTo(b1); - } - if (compare == 0) compare = c1.Name.CompareTo(c2.Name); - return compare; - }); - loc1.Add(loc4); - } - loc1.Sort((t1, t2) => - { - var ret = t1.Schema.CompareTo(t2.Schema); - if (ret == 0) ret = t1.Name.CompareTo(t2.Name); - return ret; - }); - - loc2.Clear(); - loc3.Clear(); - tables.AddRange(loc1); - } - return tables; - } - - public List GetEnumsByDatabase(params string[] database) - { - if (database == null || database.Length == 0) return new List(); - var drs = _orm.Ado.Query<(string name, string label)>(CommandType.Text, _commonUtils.FormatSql(@" -select -ns.nspname || '.' || a.typname, -b.enumlabel -from pg_type a -inner join pg_enum b on b.enumtypid = a.oid -inner join pg_namespace ns on ns.oid = a.typnamespace -where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information_schema.schemata where catalog_name in {0})", database)); - var ret = new Dictionary>(); - foreach (var dr in drs) - { - if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); - var key = dr.label; - if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) - key = $"Unkown{ret[dr.name].Count + 1}"; - if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); - } - return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); - } - } -} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs deleted file mode 100644 index 4d0a43f1..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseExpression.cs +++ /dev/null @@ -1,554 +0,0 @@ -using FreeSql.Internal; -using FreeSql.Internal.Model; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; - -namespace FreeSql.Odbc.GBase -{ - class OdbcGBaseExpression : CommonExpression - { - - public OdbcGBaseExpression(CommonUtils common) : base(common) { } - - public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) - { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.NodeType) - { - case ExpressionType.Convert: - var operandExp = (exp as UnaryExpression)?.Operand; - var gentype = exp.Type.NullableTypeOrThis(); - if (gentype != operandExp.Type.NullableTypeOrThis()) - { - switch (exp.Type.NullableTypeOrThis().ToString()) - { - case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; - case "System.Byte": return $"({getExp(operandExp)})::byte"; - case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; - case "System.Decimal": return $"({getExp(operandExp)})::decimal"; - case "System.Double": return $"({getExp(operandExp)})::float"; - case "System.Int16": return $"({getExp(operandExp)})::smallint"; - case "System.Int32": return $"({getExp(operandExp)})::integer"; - case "System.Int64": return $"({getExp(operandExp)})::bigint"; - case "System.SByte": return $"({getExp(operandExp)})::smallint"; - case "System.Single": return $"({getExp(operandExp)})::smallfloat"; - case "System.String": return $"({getExp(operandExp)})::nvarchar"; - case "System.UInt16": return $"({getExp(operandExp)})::integer"; - case "System.UInt32": return $"({getExp(operandExp)})::bigint"; - case "System.UInt64": return $"({getExp(operandExp)})::decimal"; - case "System.Guid": return $"({getExp(operandExp)})::char"; - } - } - break; - case ExpressionType.ArrayLength: - var arrOperExp = getExp((exp as UnaryExpression).Operand); - if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; - return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; - case ExpressionType.Call: - var callExp = exp as MethodCallExpression; - - switch (callExp.Method.Name) - { - case "Parse": - case "TryParse": - switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) - { - case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; - case "System.Byte": return $"({getExp(callExp.Arguments[0])})::byte"; - case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; - case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; - case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::decimal"; - case "System.Double": return $"({getExp(callExp.Arguments[0])})::float"; - case "System.Int16": return $"({getExp(callExp.Arguments[0])})::smallint"; - case "System.Int32": return $"({getExp(callExp.Arguments[0])})::integer"; - case "System.Int64": return $"({getExp(callExp.Arguments[0])})::bigint"; - case "System.SByte": return $"({getExp(callExp.Arguments[0])})::smallint"; - case "System.Single": return $"({getExp(callExp.Arguments[0])})::smallfloat"; - case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::integer"; - case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::bigint"; - case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::decimal"; - case "System.Guid": return $"({getExp(callExp.Arguments[0])})::char"; - } - break; - case "NewGuid": - return null; - case "Next": - if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::integer"; - return null; - case "NextDouble": - if (callExp.Object?.Type == typeof(Random)) return "random()"; - return null; - case "Random": - if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; - return null; - case "ToString": - if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; - return null; - } - - var objExp = callExp.Object; - var objType = objExp?.Type; - if (objType?.FullName == "System.Byte[]") return null; - - var argIndex = 0; - if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) - { - objExp = callExp.Arguments.FirstOrDefault(); - objType = objExp?.Type; - argIndex++; - } - if (objType == null) objType = callExp.Method.DeclaringType; - if (objType != null || objType.IsArrayOrList()) - { - string left = null; - if (objType.FullName == typeof(Dictionary).FullName) - { - left = objExp == null ? null : getExp(objExp); - switch (callExp.Method.Name) - { - case "Contains": - var right = getExp(callExp.Arguments[argIndex]); - return $"({left} @> ({right}))"; - case "ContainsKey": return $"({left} ? {getExp(callExp.Arguments[argIndex])})"; - case "Concat": return $"({left} || {getExp(callExp.Arguments[argIndex])})"; - case "GetLength": - case "GetLongLength": - case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; - case "Keys": return $"akeys({left})"; - case "Values": return $"avals({left})"; - } - } - switch (callExp.Method.Name) - { - case "Any": - left = objExp == null ? null : getExp(objExp); - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; - case "Contains": - tsc.SetMapColumnTmp(null); - var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); - var oldDbParams = tsc.SetDbParamsReturnOld(null); - left = objExp == null ? null : getExp(objExp); - tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); - tsc.SetDbParamsReturnOld(oldDbParams); - //判断 in 或 array @> array - if (left.StartsWith("array[") || left.EndsWith("]")) - return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 - return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; - if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; - args1 = $"array[{args1}]"; - if (objExp != null) - { - var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); - if (dbinfo.HasValue) args1 = $"{args1}::{dbinfo.Value.dbtype}"; - } - return $"({left} @> {args1})"; - case "Concat": - left = objExp == null ? null : getExp(objExp); - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - var right2 = getExp(callExp.Arguments[argIndex]); - if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; - return $"({left} || {right2})"; - case "GetLength": - case "GetLongLength": - case "Length": - case "Count": - left = objExp == null ? null : getExp(objExp); - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - return $"case when {left} is null then 0 else array_length({left},1) end"; - } - } - break; - case ExpressionType.MemberAccess: - var memExp = exp as MemberExpression; - var memParentExp = memExp.Expression?.Type; - if (memParentExp?.FullName == "System.Byte[]") return null; - if (memParentExp != null) - { - if (memParentExp.IsArray == true) - { - var left = getExp(memExp.Expression); - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - switch (memExp.Member.Name) - { - case "Length": - case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; - } - } - switch (memParentExp.FullName) - { - case "Newtonsoft.Json.Linq.JToken": - case "Newtonsoft.Json.Linq.JObject": - case "Newtonsoft.Json.Linq.JArray": - var left = getExp(memExp.Expression); - switch (memExp.Member.Name) - { - case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; - } - break; - } - if (memParentExp.FullName == typeof(Dictionary).FullName) - { - var left = getExp(memExp.Expression); - switch (memExp.Member.Name) - { - case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; - case "Keys": return $"akeys({left})"; - case "Values": return $"avals({left})"; - } - } - } - break; - case ExpressionType.NewArrayInit: - var arrExp = exp as NewArrayExpression; - var arrSb = new StringBuilder(); - arrSb.Append("array["); - for (var a = 0; a < arrExp.Expressions.Count; a++) - { - if (a > 0) arrSb.Append(","); - arrSb.Append(getExp(arrExp.Expressions[a])); - } - if (arrSb.Length == 1) arrSb.Append("NULL"); - return arrSb.Append("]").ToString(); - case ExpressionType.ListInit: - var listExp = exp as ListInitExpression; - var listSb = new StringBuilder(); - listSb.Append("("); - for (var a = 0; a < listExp.Initializers.Count; a++) - { - if (listExp.Initializers[a].Arguments.Any() == false) continue; - if (a > 0) listSb.Append(","); - listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); - } - if (listSb.Length == 1) listSb.Append("NULL"); - return listSb.Append(")").ToString(); - case ExpressionType.New: - var newExp = exp as NewExpression; - if (typeof(IList).IsAssignableFrom(newExp.Type)) - { - if (newExp.Arguments.Count == 0) return "(NULL)"; - if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; - return getExp(newExp.Arguments[0]); - } - return null; - } - return null; - } - - public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) - { - if (exp.Expression == null) - { - switch (exp.Member.Name) - { - case "Empty": return "''"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) - { - case "Length": return $"char_length({left})"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) - { - if (exp.Expression == null) - { - switch (exp.Member.Name) - { - case "Now": return _common.Now; - case "UtcNow": return _common.NowUtc; - case "Today": return "current_date"; - case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; - case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) - { - case "Date": return $"({left})::date"; - case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)"; - case "DayOfWeek": return $"extract(dow from ({left})::timestamp)"; - case "Day": return $"extract(day from ({left})::timestamp)"; - case "DayOfYear": return $"extract(doy from ({left})::timestamp)"; - case "Month": return $"extract(month from ({left})::timestamp)"; - case "Year": return $"extract(year from ({left})::timestamp)"; - case "Hour": return $"extract(hour from ({left})::timestamp)"; - case "Minute": return $"extract(minute from ({left})::timestamp)"; - case "Second": return $"extract(second from ({left})::timestamp)"; - case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)"; - case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)"; - } - return null; - } - public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) - { - if (exp.Expression == null) - { - switch (exp.Member.Name) - { - case "Zero": return "0"; - case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 - case "MaxValue": return "922337203685477580"; - } - return null; - } - var left = ExpressionLambdaToSql(exp.Expression, tsc); - switch (exp.Member.Name) - { - case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})"; - case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)"; - case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)"; - case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)"; - case "Seconds": return $"(floor(({left})/1000000)::int8%60)"; - case "Ticks": return $"(({left})*10)"; - case "TotalDays": return $"(({left})/{(long)1000000 * 60 * 60 * 24})"; - case "TotalHours": return $"(({left})/{(long)1000000 * 60 * 60})"; - case "TotalMilliseconds": return $"(({left})/1000)"; - case "TotalMinutes": return $"(({left})/{(long)1000000 * 60})"; - case "TotalSeconds": return $"(({left})/1000000)"; - } - return null; - } - - public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) - { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) - { - switch (exp.Method.Name) - { - case "IsNullOrEmpty": - var arg1 = getExp(exp.Arguments[0]); - return $"({arg1} is null or {arg1} = '')"; - case "IsNullOrWhiteSpace": - var arg2 = getExp(exp.Arguments[0]); - return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; - case "Concat": - return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); - } - } - else - { - var left = getExp(exp.Object); - switch (exp.Method.Name) - { - case "StartsWith": - case "EndsWith": - case "Contains": - var args0Value = getExp(exp.Arguments[0]); - if (args0Value == "NULL") return $"({left}) IS NULL"; - var likeOpt = "LIKE"; - if (exp.Arguments.Count > 1) - { - if (exp.Arguments[1].Type == typeof(bool) || - exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; - } - if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; - if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; - case "ToLower": return $"lower({left})"; - case "ToUpper": return $"upper({left})"; - case "Substring": - var substrArgs1 = getExp(exp.Arguments[0]); - if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); - else substrArgs1 += "+1"; - if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; - return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; - case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; - case "PadLeft": - if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; - return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "PadRight": - if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; - return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Trim": - case "TrimStart": - case "TrimEnd": - if (exp.Arguments.Count == 0) - { - if (exp.Method.Name == "Trim") return $"trim({left})"; - if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; - if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; - } - var trimArg1 = ""; - var trimArg2 = ""; - foreach (var argsTrim02 in exp.Arguments) - { - var argsTrim01s = new[] { argsTrim02 }; - if (argsTrim02.NodeType == ExpressionType.NewArrayInit) - { - var arritem = argsTrim02 as NewArrayExpression; - argsTrim01s = arritem.Expressions.ToArray(); - } - foreach (var argsTrim01 in argsTrim01s) - { - var trimChr = getExp(argsTrim01).Trim('\''); - if (trimChr.Length == 1) trimArg1 += trimChr; - else trimArg2 += $" || ({trimChr})"; - } - } - if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; - return left; - case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; - case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; - } - } - return null; - } - public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) - { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - switch (exp.Method.Name) - { - case "Abs": return $"abs({getExp(exp.Arguments[0])})"; - case "Sign": return $"sign({getExp(exp.Arguments[0])})"; - case "Floor": return $"floor({getExp(exp.Arguments[0])})"; - case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; - case "Round": - if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - return $"round({getExp(exp.Arguments[0])})"; - case "Exp": return $"exp({getExp(exp.Arguments[0])})"; - case "Log": return $"log({getExp(exp.Arguments[0])})"; - case "Log10": return $"log10({getExp(exp.Arguments[0])})"; - case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; - case "Cos": return $"cos({getExp(exp.Arguments[0])})"; - case "Sin": return $"sin({getExp(exp.Arguments[0])})"; - case "Tan": return $"tan({getExp(exp.Arguments[0])})"; - case "Acos": return $"acos({getExp(exp.Arguments[0])})"; - case "Asin": return $"asin({getExp(exp.Arguments[0])})"; - case "Atan": return $"atan({getExp(exp.Arguments[0])})"; - case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; - case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; - } - return null; - } - public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) - { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) - { - switch (exp.Method.Name) - { - case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)"; - case "DaysInMonth": return $"extract(day from ({getExp(exp.Arguments[0])} || '-' || {getExp(exp.Arguments[1])} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)"; - case "Equals": return $"(({getExp(exp.Arguments[0])})::timestamp = ({getExp(exp.Arguments[1])})::timestamp)"; - - case "IsLeapYear": - var isLeapYearArgs1 = getExp(exp.Arguments[0]); - return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; - - case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; - } - } - else - { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) - { - case "Add": return $"(({left})::timestamp+(({args1})||' microseconds')::interval)"; - case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; - case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; - case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; - case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)"; - case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)"; - case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)"; - case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; - case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; - case "Subtract": - switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) - { - case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; - case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; - } - break; - case "Equals": return $"({left} = ({args1})::timestamp)"; - case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')" : null; - } - } - return null; - } - public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) - { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) - { - switch (exp.Method.Name) - { - case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; - case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; - case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; - case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; - case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; - case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; - case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; - case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; - case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; - case "ParseExact": - case "TryParse": - case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; - } - } - else - { - var left = getExp(exp.Object); - var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); - switch (exp.Method.Name) - { - case "Add": return $"({left}+{args1})"; - case "Subtract": return $"({left}-({args1}))"; - case "Equals": return $"({left} = {args1})"; - case "CompareTo": return $"({left}-({args1}))"; - case "ToString": return $"({left})::varchar"; - } - } - return null; - } - public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) - { - Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); - if (exp.Object == null) - { - switch (exp.Method.Name) - { - case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; - case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; - case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; - case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; - case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; - case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; - case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; - case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; - case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; - case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; - case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; - case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; - case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; - case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; - case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; - } - } - return null; - } - } -} diff --git a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs b/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs deleted file mode 100644 index 7c6a56e3..00000000 --- a/Providers/FreeSql.Provider.Odbc/GBase/__OdbcGBaseUtils.cs +++ /dev/null @@ -1,159 +0,0 @@ -using FreeSql.Internal; -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data.Common; -using System.Data.Odbc; -using System.Linq; -using System.Text; - -namespace FreeSql.Odbc.GBase -{ - - class OdbcGBaseUtils : CommonUtils - { - public OdbcGBaseUtils(IFreeSql orm) : base(orm) - { - } - - static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) - { - var valueArr = value as Array; - var len = valueArr.GetLength(0); - var ret = Array.CreateInstance(arrayType, len); - for (var a = 0; a < len; a++) - { - var item = valueArr.GetValue(a); - ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); - } - return ret; - } - static Dictionary> dicGetParamterValue = new Dictionary> { - { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, - { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, - { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, - { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, - { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, - }; - static object getParamterValue(Type type, object value, int level = 0) - { - if (type.FullName == "System.Byte[]") return value; - if (type.IsArray && level == 0) - { - var elementType = type.GetElementType(); - Type enumType = null; - if (elementType.IsEnum) enumType = elementType; - else if (elementType.IsNullableType()) - { - var genericTypesFirst = elementType.GetGenericArguments().First(); - if (genericTypesFirst.IsEnum) enumType = genericTypesFirst; - } - if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)) : - getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)); - return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; - } - if (type.IsNullableType()) type = type.GetGenericArguments().First(); - if (type.IsEnum) return (int)value; - if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); - return value; - } - - public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) - { - if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; - if (value != null) value = getParamterValue(type, value); - var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; - //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { - // ret.DataTypeName = ""; - //} else { - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) ret.OdbcType = (OdbcType)tp.Value; - //} - _params?.Add(ret); - return ret; - } - - public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => - { - if (value != null) value = getParamterValue(type, value); - var ret = new OdbcParameter { ParameterName = $"@{name}", Value = value }; - //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { - // ret.DataTypeName = ""; - //} else { - var tp = _orm.CodeFirst.GetDbInfo(type)?.type; - if (tp != null) ret.OdbcType = (OdbcType)tp.Value; - //} - return ret; - }); - - public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcPostgreSQL(args); - public override string QuoteSqlName(params string[] name) - { - if (name.Length == 1) - { - var nametrim = name[0].Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) - return nametrim; - return $"\"{nametrim.Replace(".", "\".\"")}\""; - } - return $"\"{string.Join("\".\"", name)}\""; - } - public override string TrimQuoteSqlName(string name) - { - var nametrim = name.Trim(); - if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) - return nametrim; //原生SQL - return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; - } - public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; - public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; - public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; - public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; - public override string Now => "current_timestamp"; - public override string NowUtc => "(current_timestamp at time zone 'UTC')"; - - public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; - public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) - { - if (value == null) return "NULL"; - value = getParamterValue(type, value); - var type2 = value.GetType(); - if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; - if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) - { - var ts = (TimeSpan)value; - return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; - } - else if (value is Array) - { - var valueArr = value as Array; - var eleType = type2.GetElementType(); - var len = valueArr.GetLength(0); - var sb = new StringBuilder().Append("ARRAY["); - for (var a = 0; a < len; a++) - { - var item = valueArr.GetValue(a); - if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); - } - sb.Append("]"); - var dbinfo = _orm.CodeFirst.GetDbInfo(type); - if (dbinfo.HasValue) sb.Append("::").Append(dbinfo.Value.dbtype); - return sb.ToString(); - } - else if (dicGetParamterValue.ContainsKey(type2.FullName)) - { - value = string.Concat(value); - } - return FormatSql("{0}", value, 1); - } - } -} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index ea03dc69..94b34597 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -16,35 +17,35 @@ namespace FreeSql.Odbc.MySql public OdbcMySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (OdbcType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "bit","bit(1)", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, "bit","bit(1)", null, true, null) }, - { typeof(sbyte).FullName, (OdbcType.SmallInt, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "tinyint", "tinyint(3)", false, true, null) }, - { typeof(short).FullName, (OdbcType.SmallInt, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "smallint", "smallint(6)", false, true, null) }, - { typeof(int).FullName, (OdbcType.Int, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "int", "int(11)", false, true, null) }, - { typeof(long).FullName, (OdbcType.BigInt, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "bigint","bigint(20)", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(OdbcType.SmallInt, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OdbcType.SmallInt, "tinyint", "tinyint(3)", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OdbcType.SmallInt, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OdbcType.SmallInt, "smallint", "smallint(6)", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OdbcType.Int, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OdbcType.Int, "int", "int(11)", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OdbcType.BigInt, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OdbcType.BigInt, "bigint","bigint(20)", false, true, null) }, - { typeof(byte).FullName, (OdbcType.TinyInt, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, "tinyint","tinyint(3) unsigned", true, true, null) }, - { typeof(ushort).FullName, (OdbcType.Int, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "smallint", "smallint(5) unsigned", true, true, null) }, - { typeof(uint).FullName, (OdbcType.BigInt, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "int", "int(10) unsigned", true, true, null) }, - { typeof(ulong).FullName, (OdbcType.Decimal, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "bigint", "bigint(20) unsigned", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(OdbcType.TinyInt, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OdbcType.TinyInt, "tinyint","tinyint(3) unsigned", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OdbcType.Int, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OdbcType.Int, "smallint", "smallint(5) unsigned", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(OdbcType.BigInt, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OdbcType.BigInt, "int", "int(10) unsigned", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OdbcType.Decimal, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OdbcType.Decimal, "bigint", "bigint(20) unsigned", true, true, null) }, - { typeof(double).FullName, (OdbcType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "double", "double", false, true, null) }, - { typeof(float).FullName, (OdbcType.Real, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "float","float", false, true, null) }, - { typeof(decimal).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OdbcType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OdbcType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, CsToDb.New(OdbcType.Real, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OdbcType.Real, "float","float", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(TimeSpan).FullName, (OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (OdbcType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "datetime(3)", "datetime(3)", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OdbcType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "datetime(3)", "datetime(3)", false, true, null) }, - { typeof(byte[]).FullName, (OdbcType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, - { typeof(string).FullName, (OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, - { typeof(Guid).FullName, (OdbcType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.VarChar, "char", "char(36)", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OdbcType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.VarChar, "char", "char(36)", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -56,8 +57,8 @@ namespace FreeSql.Odbc.MySql { var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OdbcType.VarChar, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OdbcType.VarChar, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.VarChar, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(OdbcType.VarChar, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -66,12 +67,12 @@ namespace FreeSql.Odbc.MySql _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); var database = conn.Value.Database; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index f9506697..6424cf2a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -1,5 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -71,31 +72,31 @@ namespace FreeSql.Odbc.MySql } } - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)OdbcType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OdbcType.Bit, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)OdbcType.TinyInt, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, - { (int)OdbcType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)OdbcType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)OdbcType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)OdbcType.TinyInt, new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") }, + { (int)OdbcType.SmallInt, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)OdbcType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)OdbcType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)OdbcType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)OdbcType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)OdbcType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OdbcType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)OdbcType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)OdbcType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)OdbcType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Timestamp, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)OdbcType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.Binary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.VarBinary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)OdbcType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, - { (int)OdbcType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.UniqueIdentifier, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + { (int)OdbcType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, }; public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 302342ab..adec255e 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -19,37 +19,37 @@ namespace FreeSql.Odbc.Oracle public OdbcOracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (OdbcType.Bit, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "number","number(1) NULL", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, "number","number(1) NULL", null, true, null) }, - { typeof(sbyte).FullName, (OdbcType.SmallInt, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "number", "number(4) NULL", false, true, null) }, - { typeof(short).FullName, (OdbcType.SmallInt, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "number", "number(6) NULL", false, true, null) }, - { typeof(int).FullName, (OdbcType.Int, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "number", "number(11) NULL", false, true, null) }, - { typeof(long).FullName, (OdbcType.BigInt, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "number","number(21) NULL", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(OdbcType.SmallInt, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OdbcType.SmallInt, "number", "number(4) NULL", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OdbcType.SmallInt, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OdbcType.SmallInt, "number", "number(6) NULL", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OdbcType.Int, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OdbcType.Int, "number", "number(11) NULL", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OdbcType.BigInt, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OdbcType.BigInt, "number","number(21) NULL", false, true, null) }, - { typeof(byte).FullName, (OdbcType.TinyInt, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, "number","number(3) NULL", true, true, null) }, - { typeof(ushort).FullName, (OdbcType.Int, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "number", "number(5) NULL", true, true, null) }, - { typeof(uint).FullName, (OdbcType.BigInt, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "number", "number(10) NULL", true, true, null) }, - { typeof(ulong).FullName, (OdbcType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "number", "number(20) NULL", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(OdbcType.TinyInt, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OdbcType.TinyInt, "number","number(3) NULL", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OdbcType.Int, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OdbcType.Int, "number", "number(5) NULL", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(OdbcType.BigInt, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OdbcType.BigInt, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OdbcType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OdbcType.Decimal, "number", "number(20) NULL", true, true, null) }, - { typeof(double).FullName, (OdbcType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "float", "float(126) NULL", false, true, null) }, - { typeof(float).FullName, (OdbcType.Real, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "float","float(63) NULL", false, true, null) }, - { typeof(decimal).FullName, (OdbcType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OdbcType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OdbcType.Double, "float", "float(126) NULL", false, true, null) }, + { typeof(float).FullName, CsToDb.New(OdbcType.Real, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OdbcType.Real, "float","float(63) NULL", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OdbcType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Decimal, "number", "number(10,2) NULL", false, true, null) }, //oracle odbc driver 不支持 TimeSpan 类型的读取 - //{ typeof(TimeSpan).FullName, (OdbcType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, - { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, - { typeof(DateTimeOffset).FullName, (OdbcType.DateTime, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, (OdbcType.DateTime, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, + //{ typeof(TimeSpan).FullName, CsToDb.NewInfo(OdbcType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.NewInfo(OdbcType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset).FullName, CsToDb.New(OdbcType.DateTime, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(OdbcType.DateTime, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, - { typeof(byte[]).FullName, (OdbcType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, - { typeof(string).FullName, (OdbcType.NVarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(OdbcType.NVarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, - { typeof(Guid).FullName, (OdbcType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OdbcType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -60,8 +60,8 @@ namespace FreeSql.Odbc.Oracle if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -70,12 +70,12 @@ namespace FreeSql.Odbc.Oracle _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var userId = (_orm.Ado.MasterPool as OdbcOracleConnectionPool)?.UserId; if (string.IsNullOrEmpty(userId)) @@ -83,7 +83,7 @@ namespace FreeSql.Odbc.Oracle { userId = OdbcOracleConnectionPool.GetUserId(conn.Value.ConnectionString); } - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 + var seqcols = new List>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 var sb = new StringBuilder(); @@ -134,7 +134,7 @@ namespace FreeSql.Odbc.Oracle foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -234,10 +234,10 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); if (tbcol.Attribute.IsIdentity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; @@ -249,7 +249,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } @@ -305,7 +305,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index 618b5b16..b88e7c1c 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -1,5 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -115,35 +116,35 @@ namespace FreeSql.Odbc.Oracle throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); } - static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); static OdbcOracleDbFirst() { - var defaultDbToCs = new Dictionary() { - { "number(1)", ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + var defaultDbToCs = new Dictionary() { + { "number(1)", new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { "number(4)", ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, - { "number(6)", ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { "number(11)", ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { "number(21)", ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { "number(4)", new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { "number(6)", new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "number(11)", new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "number(21)", new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { "number(3)", ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { "number(5)", ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, - { "number(10)", ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, - { "number(20)", ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + { "number(3)", new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "number(5)", new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "number(10)", new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "number(20)", new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, - { "float(126)", ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { "float(63)", ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { "number(10,2)", ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { "float(126)", new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float(63)", new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "number(10,2)", new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { "interval day(2) to second(6)", ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { "date(7)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "timestamp(6)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "timestamp(6) with local time zone", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "interval day(2) to second(6)", new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date(7)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6) with local time zone", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "blob", ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { "blob", new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { "nvarchar2(255)", ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { "char(36 char)", ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + { "nvarchar2(255)", new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "char(36 char)", new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, }; foreach (var kv in defaultDbToCs) _dicDbToCs.TryAdd(kv.Key, kv.Value); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index a09e2223..14f4821d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -16,44 +16,44 @@ namespace FreeSql.Odbc.PostgreSQL public OdbcPostgreSQLCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { + static Dictionary> _dicCsToDb = new Dictionary>() { - { typeof(sbyte).FullName, (OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "int2", "int2", false, true, null) }, - { typeof(short).FullName, (OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "int2", "int2", false, true, null) }, - { typeof(int).FullName, (OdbcType.Int, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "int4", "int4", false, true, null) }, - { typeof(long).FullName, (OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "int8", "int8", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OdbcType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OdbcType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OdbcType.Int, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OdbcType.Int, "int4", "int4", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OdbcType.BigInt, "int8", "int8", false, true, null) }, - { typeof(byte).FullName, (OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (OdbcType.SmallInt, "int2", "int2", false, true, null) }, - { typeof(ushort).FullName, (OdbcType.Int, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "int4", "int4", false, true, null) }, - { typeof(uint).FullName, (OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "int8", "int8", false, true, null) }, - { typeof(ulong).FullName, (OdbcType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, + { typeof(byte).FullName, CsToDb.New(OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OdbcType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OdbcType.Int, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OdbcType.Int, "int4", "int4", false, true, null) }, + { typeof(uint).FullName, CsToDb.New(OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OdbcType.BigInt, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OdbcType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, - { typeof(float).FullName, (OdbcType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "float4", "float4", false, true, null) }, - { typeof(double).FullName, (OdbcType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "float8", "float8", false, true, null) }, - { typeof(decimal).FullName, (OdbcType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, + { typeof(float).FullName, CsToDb.New(OdbcType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OdbcType.Real, "float4", "float4", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OdbcType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OdbcType.Double, "float8", "float8", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, - { typeof(string).FullName, (OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, - { typeof(TimeSpan).FullName, (OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (OdbcType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "timestamp", "timestamp", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OdbcType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp", false, true, null) }, - { typeof(bool).FullName, (OdbcType.Bit, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "bool","bool", null, true, null) }, - { typeof(Byte[]).FullName, (OdbcType.VarBinary, "bytea", "bytea", false, null, new byte[0]) }, + { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, "bool","bool", null, true, null) }, + { typeof(Byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "bytea", "bytea", false, null, new byte[0]) }, - { typeof(Guid).FullName, (OdbcType.UniqueIdentifier, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.UniqueIdentifier, "uuid", "uuid", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "uuid", "uuid", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { var isarray = type.FullName != "System.Byte[]" && type.IsArray; var elementType = isarray ? type.GetElementType() : type; var info = GetDbInfoNoneArray(elementType); if (info == null) return null; - return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable, info.Value.defaultValue); + return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue); } - (OdbcType type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfoNoneArray(Type type) + CsToDb GetDbInfoNoneArray(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (OdbcType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc; if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -64,8 +64,8 @@ namespace FreeSql.Odbc.PostgreSQL if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OdbcType.Int, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OdbcType.BigInt, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.Int, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(OdbcType.BigInt, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -74,15 +74,15 @@ namespace FreeSql.Odbc.PostgreSQL _dicCsToDb.Add(type.FullName, newItem); } } - return (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return newItem; } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var sb = new StringBuilder(); - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + var seqcols = new List>(); //序列 foreach (var obj in objects) { @@ -128,7 +128,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -244,7 +244,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); } } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); @@ -256,7 +256,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql(@" @@ -313,7 +313,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index d248291e..097a63ed 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -1,5 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -62,26 +63,26 @@ namespace FreeSql.Odbc.PostgreSQL return ret; } - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)OdbcType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)OdbcType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)OdbcType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)OdbcType.Numeric, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)OdbcType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)OdbcType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OdbcType.SmallInt, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)OdbcType.Numeric, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)OdbcType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OdbcType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)OdbcType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)OdbcType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)OdbcType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)OdbcType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.Bit, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)OdbcType.VarBinary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)OdbcType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + { (int)OdbcType.UniqueIdentifier, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, }; public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; @@ -454,13 +455,18 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname") return tables; } + public class GetEnumsByDatabaseQueryInfo + { + public string name { get; set; } + public string label { get; set; } + } public List GetEnumsByDatabase(params string[] database) { if (database == null || database.Length == 0) return new List(); - var drs = _orm.Ado.Query<(string name, string label)>(CommandType.Text, _commonUtils.FormatSql(@" + var drs = _orm.Ado.Query(CommandType.Text, _commonUtils.FormatSql(@" select -ns.nspname || '.' || a.typname, -b.enumlabel +ns.nspname || '.' || a.typname AS name, +b.enumlabel AS label from pg_type a inner join pg_enum b on b.enumtypid = a.oid inner join pg_namespace ns on ns.oid = a.typnamespace diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 3d593394..2c4ccee2 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -147,7 +147,7 @@ namespace FreeSql.Odbc.PostgreSQL if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); - if (dbinfo.HasValue) args1 = $"{args1}::{dbinfo.Value.dbtype}"; + if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; } return $"({left} @> {args1})"; case "Concat": diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 62d259e3..7fab4eda 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -146,7 +146,7 @@ namespace FreeSql.Odbc.PostgreSQL } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); - if (dbinfo.HasValue) sb.Append("::").Append(dbinfo.Value.dbtype); + if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype); return sb.ToString(); } else if (dicGetParamterValue.ContainsKey(type2.FullName)) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index b6eeddae..9633d8db 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -16,36 +16,36 @@ namespace FreeSql.Odbc.SqlServer public OdbcSqlServerCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (OdbcType.Bit, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OdbcType.Bit, "bit","bit", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, "bit","bit", null, true, null) }, - { typeof(sbyte).FullName, (OdbcType.SmallInt, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, - { typeof(short).FullName, (OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, - { typeof(int).FullName, (OdbcType.Int, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OdbcType.Int, "int", "int", false, true, null) }, - { typeof(long).FullName, (OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OdbcType.BigInt, "bigint","bigint", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(OdbcType.SmallInt, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OdbcType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OdbcType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OdbcType.Int, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OdbcType.Int, "int", "int", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OdbcType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OdbcType.BigInt, "bigint","bigint", false, true, null) }, - { typeof(byte).FullName, (OdbcType.TinyInt, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OdbcType.TinyInt, "tinyint","tinyint", true, true, null) }, - { typeof(ushort).FullName, (OdbcType.Int, "int","int NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OdbcType.Int, "int", "int", true, true, null) }, - { typeof(uint).FullName, (OdbcType.BigInt, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OdbcType.BigInt, "bigint", "bigint", true, true, null) }, - { typeof(ulong).FullName, (OdbcType.Decimal, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OdbcType.Decimal, "decimal", "decimal(20,0)", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(OdbcType.TinyInt, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OdbcType.TinyInt, "tinyint","tinyint", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OdbcType.Int, "int","int NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OdbcType.Int, "int", "int", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(OdbcType.BigInt, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OdbcType.BigInt, "bigint", "bigint", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(20,0)", true, true, null) }, - { typeof(double).FullName, (OdbcType.Double, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OdbcType.Double, "float", "float", false, true, null) }, - { typeof(float).FullName, (OdbcType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OdbcType.Real, "real","real", false, true, null) }, - { typeof(decimal).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OdbcType.Double, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OdbcType.Double, "float", "float", false, true, null) }, + { typeof(float).FullName, CsToDb.New(OdbcType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OdbcType.Real, "real","real", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(TimeSpan).FullName, (OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OdbcType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (OdbcType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OdbcType.DateTime, "datetime", "datetime", false, true, null) }, - { typeof(DateTimeOffset).FullName, (OdbcType.DateTime, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, (OdbcType.DateTime, "datetimeoffset", "datetimeoffset", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OdbcType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "datetime", "datetime", false, true, null) }, + { typeof(DateTimeOffset).FullName, CsToDb.New(OdbcType.DateTime, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(OdbcType.DateTime, "datetimeoffset", "datetimeoffset", false, true, null) }, - { typeof(byte[]).FullName, (OdbcType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, - { typeof(string).FullName, (OdbcType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(OdbcType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, - { typeof(Guid).FullName, (OdbcType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OdbcType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -56,8 +56,8 @@ namespace FreeSql.Odbc.SqlServer if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OdbcType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OdbcType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(OdbcType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -66,7 +66,7 @@ namespace FreeSql.Odbc.SqlServer _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } @@ -103,7 +103,7 @@ ELSE , @level2type = 'COLUMN', @level2name = N'{2}' ", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); string database = null; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index 5f21d5dd..0242448a 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -1,5 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -59,36 +60,36 @@ namespace FreeSql.Odbc.SqlServer } } - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)OdbcType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OdbcType.Bit, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)OdbcType.TinyInt, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { (int)OdbcType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)OdbcType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)OdbcType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)OdbcType.TinyInt, new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)OdbcType.SmallInt, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)OdbcType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)OdbcType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)OdbcType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OdbcType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)OdbcType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)OdbcType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)OdbcType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)OdbcType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.SmallDateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)OdbcType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.SmallDateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)OdbcType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)OdbcType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)OdbcType.Image, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)OdbcType.Timestamp, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.Binary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.VarBinary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.Image, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)OdbcType.Timestamp, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)OdbcType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.NChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.NVarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.NText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.NChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.NVarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.NText, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)OdbcType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + { (int)OdbcType.UniqueIdentifier, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, }; public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 40942739..6bf213c4 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -21,36 +21,36 @@ namespace FreeSql.Oracle public OracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (OracleDbType.Boolean, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (OracleDbType.Boolean, "number","number(1) NULL", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(OracleDbType.Boolean, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OracleDbType.Boolean, "number","number(1) NULL", null, true, null) }, - { typeof(sbyte).FullName, (OracleDbType.Decimal, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (OracleDbType.Decimal, "number", "number(4) NULL", false, true, null) }, - { typeof(short).FullName, (OracleDbType.Int16, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (OracleDbType.Int16, "number", "number(6) NULL", false, true, null) }, - { typeof(int).FullName, (OracleDbType.Int32, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (OracleDbType.Int32, "number", "number(11) NULL", false, true, null) }, - { typeof(long).FullName, (OracleDbType.Int64, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (OracleDbType.Int64, "number","number(21) NULL", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(4) NULL", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OracleDbType.Int16, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OracleDbType.Int16, "number", "number(6) NULL", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OracleDbType.Int32, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OracleDbType.Int32, "number", "number(11) NULL", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OracleDbType.Int64, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OracleDbType.Int64, "number","number(21) NULL", false, true, null) }, - { typeof(byte).FullName, (OracleDbType.Byte, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (OracleDbType.Byte, "number","number(3) NULL", true, true, null) }, - { typeof(ushort).FullName, (OracleDbType.Decimal, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (OracleDbType.Decimal, "number", "number(5) NULL", true, true, null) }, - { typeof(uint).FullName, (OracleDbType.Decimal, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (OracleDbType.Decimal, "number", "number(10) NULL", true, true, null) }, - { typeof(ulong).FullName, (OracleDbType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (OracleDbType.Decimal, "number", "number(20) NULL", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(OracleDbType.Byte, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OracleDbType.Byte, "number","number(3) NULL", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OracleDbType.Decimal, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(5) NULL", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(20) NULL", true, true, null) }, - { typeof(double).FullName, (OracleDbType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, (OracleDbType.Double, "float", "float(126) NULL", false, true, null) }, - { typeof(float).FullName, (OracleDbType.Single, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, (OracleDbType.Single, "float","float(63) NULL", false, true, null) }, - { typeof(decimal).FullName, (OracleDbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (OracleDbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OracleDbType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OracleDbType.Double, "float", "float(126) NULL", false, true, null) }, + { typeof(float).FullName, CsToDb.New(OracleDbType.Single, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OracleDbType.Single, "float","float(63) NULL", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, - { typeof(TimeSpan).FullName, (OracleDbType.IntervalDS, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (OracleDbType.IntervalDS, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, - { typeof(DateTime).FullName, (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NULL", false, true, null) }, - { typeof(DateTimeOffset).FullName, (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(OracleDbType.IntervalDS, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OracleDbType.IntervalDS, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OracleDbType.TimeStamp, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OracleDbType.TimeStamp, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset).FullName, CsToDb.New(OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, - { typeof(byte[]).FullName, (OracleDbType.Blob, "blob", "blob NULL", false, null, new byte[0]) }, - { typeof(string).FullName, (OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(OracleDbType.Blob, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, - { typeof(Guid).FullName, (OracleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (OracleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OracleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OracleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -61,8 +61,8 @@ namespace FreeSql.Oracle if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (OracleDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (OracleDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OracleDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(OracleDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -71,12 +71,12 @@ namespace FreeSql.Oracle _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var userId = (_orm.Ado.MasterPool as OracleConnectionPool)?.UserId; if (string.IsNullOrEmpty(userId)) @@ -84,7 +84,7 @@ namespace FreeSql.Oracle { userId = OracleConnectionPool.GetUserId(conn.Value.ConnectionString); } - var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增 + var seqcols = new List>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 var sb = new StringBuilder(); @@ -135,7 +135,7 @@ namespace FreeSql.Oracle foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -235,10 +235,10 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); if (tbcol.Attribute.IsIdentity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; @@ -250,7 +250,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } @@ -306,7 +306,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index dfd9fef0..2d2e599e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -1,5 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; +using FreeSql.Internal.Model; using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Concurrent; @@ -115,35 +116,35 @@ namespace FreeSql.Oracle throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); } - static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); static OracleDbFirst() { - var defaultDbToCs = new Dictionary() { - { "number(1)", ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + var defaultDbToCs = new Dictionary() { + { "number(1)", new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { "number(4)", ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, - { "number(6)", ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { "number(11)", ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { "number(21)", ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { "number(4)", new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { "number(6)", new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "number(11)", new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "number(21)", new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { "number(3)", ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { "number(5)", ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, - { "number(10)", ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, - { "number(20)", ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + { "number(3)", new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "number(5)", new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "number(10)", new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "number(20)", new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, - { "float(126)", ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { "float(63)", ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { "number(10,2)", ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { "float(126)", new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float(63)", new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "number(10,2)", new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { "interval day(2) to second(6)", ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { "date(7)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "timestamp(6)", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "timestamp(6) with local time zone", ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "interval day(2) to second(6)", new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date(7)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6) with local time zone", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, - { "blob", ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { "blob", new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { "nvarchar2(255)", ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { "char(36 char)", ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + { "nvarchar2(255)", new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "char(36 char)", new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, }; foreach (var kv in defaultDbToCs) _dicDbToCs.TryAdd(kv.Key, kv.Value); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 15c92508..70011c5a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -22,85 +22,85 @@ namespace FreeSql.PostgreSQL public PostgreSQLCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { + static Dictionary> _dicCsToDb = new Dictionary>() { - { typeof(sbyte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, - { typeof(short).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, - { typeof(int).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true, null) }, - { typeof(long).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(short).FullName, CsToDb.New(NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(int).FullName, CsToDb.New(NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(NpgsqlDbType.Integer, "int4", "int4", false, true, null) }, + { typeof(long).FullName, CsToDb.New(NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(NpgsqlDbType.Bigint, "int8", "int8", false, true, null) }, - { typeof(byte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, - { typeof(ushort).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true, null) }, - { typeof(uint).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true, null) }, - { typeof(ulong).FullName, (NpgsqlDbType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, + { typeof(byte).FullName, CsToDb.New(NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, CsToDb.New(NpgsqlDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(ushort).FullName, CsToDb.New(NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(NpgsqlDbType.Integer, "int4", "int4", false, true, null) }, + { typeof(uint).FullName, CsToDb.New(NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, CsToDb.New(NpgsqlDbType.Bigint, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, CsToDb.New(NpgsqlDbType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(NpgsqlDbType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, - { typeof(float).FullName, (NpgsqlDbType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, (NpgsqlDbType.Real, "float4", "float4", false, true, null) }, - { typeof(double).FullName, (NpgsqlDbType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, (NpgsqlDbType.Double, "float8", "float8", false, true, null) }, - { typeof(decimal).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, + { typeof(float).FullName, CsToDb.New(NpgsqlDbType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(NpgsqlDbType.Real, "float4", "float4", false, true, null) }, + { typeof(double).FullName, CsToDb.New(NpgsqlDbType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(NpgsqlDbType.Double, "float8", "float8", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(NpgsqlDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(NpgsqlDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, - { typeof(string).FullName, (NpgsqlDbType.Varchar, "varchar", "varchar(255)", false, null, "") }, + { typeof(string).FullName, CsToDb.New(NpgsqlDbType.Varchar, "varchar", "varchar(255)", false, null, "") }, - { typeof(TimeSpan).FullName, (NpgsqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (NpgsqlDbType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(NpgsqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(NpgsqlDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(NpgsqlDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(NpgsqlDbType.Timestamp, "timestamp", "timestamp", false, true, null) }, - { typeof(bool).FullName, (NpgsqlDbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, (NpgsqlDbType.Boolean, "bool","bool", null, true, null) }, - { typeof(Byte[]).FullName, (NpgsqlDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) }, - { typeof(BitArray).FullName, (NpgsqlDbType.Varbit, "varbit", "varbit(64)", false, null, new BitArray(new byte[64])) }, + { typeof(bool).FullName, CsToDb.New(NpgsqlDbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(NpgsqlDbType.Boolean, "bool","bool", null, true, null) }, + { typeof(Byte[]).FullName, CsToDb.New(NpgsqlDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) }, + { typeof(BitArray).FullName, CsToDb.New(NpgsqlDbType.Varbit, "varbit", "varbit(64)", false, null, new BitArray(new byte[64])) }, - { typeof(NpgsqlPoint).FullName, (NpgsqlDbType.Point, "point", "point NOT NULL", false, false, new NpgsqlPoint(0, 0)) },{ typeof(NpgsqlPoint?).FullName, (NpgsqlDbType.Point, "point", "point", false, true, null) }, - { typeof(NpgsqlLine).FullName, (NpgsqlDbType.Line, "line", "line NOT NULL", false, false, new NpgsqlLine(0, 0, 1)) },{ typeof(NpgsqlLine?).FullName, (NpgsqlDbType.Line, "line", "line", false, true, null) }, - { typeof(NpgsqlLSeg).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg NOT NULL", false, false, new NpgsqlLSeg(0, 0, 0, 0)) },{ typeof(NpgsqlLSeg?).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg", false, true, null) }, - { typeof(NpgsqlBox).FullName, (NpgsqlDbType.Box, "box", "box NOT NULL", false, false, new NpgsqlBox(0, 0, 0, 0)) },{ typeof(NpgsqlBox?).FullName, (NpgsqlDbType.Box, "box", "box", false, true, null) }, - { typeof(NpgsqlPath).FullName, (NpgsqlDbType.Path, "path", "path NOT NULL", false, false, new NpgsqlPath(new NpgsqlPoint(0, 0))) },{ typeof(NpgsqlPath?).FullName, (NpgsqlDbType.Path, "path", "path", false, true, null) }, - { typeof(NpgsqlPolygon).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon NOT NULL", false, false, new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0))) },{ typeof(NpgsqlPolygon?).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon", false, true, null) }, - { typeof(NpgsqlCircle).FullName, (NpgsqlDbType.Circle, "circle", "circle NOT NULL", false, false, new NpgsqlCircle(0, 0, 0)) },{ typeof(NpgsqlCircle?).FullName, (NpgsqlDbType.Circle, "circle", "circle", false, true, null) }, + { typeof(NpgsqlPoint).FullName, CsToDb.New(NpgsqlDbType.Point, "point", "point NOT NULL", false, false, new NpgsqlPoint(0, 0)) },{ typeof(NpgsqlPoint?).FullName, CsToDb.New(NpgsqlDbType.Point, "point", "point", false, true, null) }, + { typeof(NpgsqlLine).FullName, CsToDb.New(NpgsqlDbType.Line, "line", "line NOT NULL", false, false, new NpgsqlLine(0, 0, 1)) },{ typeof(NpgsqlLine?).FullName, CsToDb.New(NpgsqlDbType.Line, "line", "line", false, true, null) }, + { typeof(NpgsqlLSeg).FullName, CsToDb.New(NpgsqlDbType.LSeg, "lseg", "lseg NOT NULL", false, false, new NpgsqlLSeg(0, 0, 0, 0)) },{ typeof(NpgsqlLSeg?).FullName, CsToDb.New(NpgsqlDbType.LSeg, "lseg", "lseg", false, true, null) }, + { typeof(NpgsqlBox).FullName, CsToDb.New(NpgsqlDbType.Box, "box", "box NOT NULL", false, false, new NpgsqlBox(0, 0, 0, 0)) },{ typeof(NpgsqlBox?).FullName, CsToDb.New(NpgsqlDbType.Box, "box", "box", false, true, null) }, + { typeof(NpgsqlPath).FullName, CsToDb.New(NpgsqlDbType.Path, "path", "path NOT NULL", false, false, new NpgsqlPath(new NpgsqlPoint(0, 0))) },{ typeof(NpgsqlPath?).FullName, CsToDb.New(NpgsqlDbType.Path, "path", "path", false, true, null) }, + { typeof(NpgsqlPolygon).FullName, CsToDb.New(NpgsqlDbType.Polygon, "polygon", "polygon NOT NULL", false, false, new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0))) },{ typeof(NpgsqlPolygon?).FullName, CsToDb.New(NpgsqlDbType.Polygon, "polygon", "polygon", false, true, null) }, + { typeof(NpgsqlCircle).FullName, CsToDb.New(NpgsqlDbType.Circle, "circle", "circle NOT NULL", false, false, new NpgsqlCircle(0, 0, 0)) },{ typeof(NpgsqlCircle?).FullName, CsToDb.New(NpgsqlDbType.Circle, "circle", "circle", false, true, null) }, - { typeof((IPAddress Address, int Subnet)).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr NOT NULL", false, false, (IPAddress.Any, 0)) },{ typeof((IPAddress Address, int Subnet)?).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr", false, true, null) }, - { typeof(IPAddress).FullName, (NpgsqlDbType.Inet, "inet", "inet", false, null, IPAddress.Any) }, - { typeof(PhysicalAddress).FullName, (NpgsqlDbType.MacAddr, "macaddr", "macaddr", false, null, PhysicalAddress.None) }, + { typeof((IPAddress Address, int Subnet)).FullName, CsToDb.New(NpgsqlDbType.Cidr, "cidr", "cidr NOT NULL", false, false, (IPAddress.Any, 0)) },{ typeof((IPAddress Address, int Subnet)?).FullName, CsToDb.New(NpgsqlDbType.Cidr, "cidr", "cidr", false, true, null) }, + { typeof(IPAddress).FullName, CsToDb.New(NpgsqlDbType.Inet, "inet", "inet", false, null, IPAddress.Any) }, + { typeof(PhysicalAddress).FullName, CsToDb.New(NpgsqlDbType.MacAddr, "macaddr", "macaddr", false, null, PhysicalAddress.None) }, - { typeof(JToken).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JToken.Parse("{}")) }, - { typeof(JObject).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JObject.Parse("{}")) }, - { typeof(JArray).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JArray.Parse("[]")) }, - { typeof(Guid).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid", false, true, null) }, + { typeof(JToken).FullName, CsToDb.New(NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JToken.Parse("{}")) }, + { typeof(JObject).FullName, CsToDb.New(NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JObject.Parse("{}")) }, + { typeof(JArray).FullName, CsToDb.New(NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JArray.Parse("[]")) }, + { typeof(Guid).FullName, CsToDb.New(NpgsqlDbType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(NpgsqlDbType.Uuid, "uuid", "uuid", false, true, null) }, - { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range", false, true, null) }, - { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range", false, true, null) }, - { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange", false, true, null) }, - { typeof(NpgsqlRange).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange", false, true, null) }, + { typeof(NpgsqlRange).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range", false, true, null) }, + { typeof(NpgsqlRange).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range", false, true, null) }, + { typeof(NpgsqlRange).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange", false, true, null) }, + { typeof(NpgsqlRange).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange", false, true, null) }, - { typeof(Dictionary).FullName, (NpgsqlDbType.Hstore, "hstore", "hstore", false, null, new Dictionary()) }, - { typeof(PostgisPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, - { typeof(PostgisLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, - { typeof(PostgisPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } })) }, - { typeof(PostgisMultiPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPoint(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, - { typeof(PostgisMultiLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiLineString(new[]{new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }),new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }) })) }, - { typeof(PostgisMultiPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPolygon(new[]{new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }),new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }) })) }, - { typeof(PostgisGeometry).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, - { typeof(PostgisGeometryCollection).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisGeometryCollection(new[]{new PostgisPoint(0, 0),new PostgisPoint(0, 0) })) }, + { typeof(Dictionary).FullName, CsToDb.New(NpgsqlDbType.Hstore, "hstore", "hstore", false, null, new Dictionary()) }, + { typeof(PostgisPoint).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, + { typeof(PostgisLineString).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, + { typeof(PostgisPolygon).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } })) }, + { typeof(PostgisMultiPoint).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPoint(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, + { typeof(PostgisMultiLineString).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiLineString(new[]{new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }),new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }) })) }, + { typeof(PostgisMultiPolygon).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPolygon(new[]{new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }),new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }) })) }, + { typeof(PostgisGeometry).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, + { typeof(PostgisGeometryCollection).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisGeometryCollection(new[]{new PostgisPoint(0, 0),new PostgisPoint(0, 0) })) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { var isarray = type.FullName != "System.Byte[]" && type.IsArray; var elementType = isarray ? type.GetElementType() : type; var info = GetDbInfoNoneArray(elementType); if (info == null) return null; - if (isarray == false) return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable, info.Value.defaultValue); - var dbtypefull = Regex.Replace(info.Value.dbtypeFull, $@"{info.Value.dbtype}(\s*\([^\)]+\))?", "$0[]").Replace(" NOT NULL", ""); - return ((int)(info.Value.type | NpgsqlDbType.Array), $"{info.Value.dbtype}[]", dbtypefull, null, Array.CreateInstance(elementType, 0)); + if (isarray == false) return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue); + var dbtypefull = Regex.Replace(info.dbtypeFull, $@"{info.dbtype}(\s*\([^\)]+\))?", "$0[]").Replace(" NOT NULL", ""); + return new DbInfoResult((int)(info.type | NpgsqlDbType.Array), $"{info.dbtype}[]", dbtypefull, null, Array.CreateInstance(elementType, 0)); } - (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfoNoneArray(Type type) + CsToDb GetDbInfoNoneArray(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (NpgsqlDbType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc; if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (NpgsqlDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(NpgsqlDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -109,12 +109,12 @@ namespace FreeSql.PostgreSQL _dicCsToDb.Add(type.FullName, newItem); } } - return (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return newItem; } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var sb = new StringBuilder(); var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index c4845638..797955ca 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -177,7 +177,7 @@ namespace FreeSql.PostgreSQL if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); - if (dbinfo.HasValue) args1 = $"{args1}::{dbinfo.Value.dbtype}"; + if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; } return $"({left} @> {args1})"; case "Concat": diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 08d541e3..2781ae1b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -181,7 +181,7 @@ namespace FreeSql.PostgreSQL } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); - if (dbinfo.HasValue) sb.Append("::").Append(dbinfo.Value.dbtype); + if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype); return sb.ToString(); } else if (type2 == typeof(BitArray)) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 6276be91..00cdc6f0 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -15,36 +15,36 @@ namespace FreeSql.SqlServer public SqlServerCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (SqlDbType.Bit, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, (SqlDbType.Bit, "bit","bit", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(SqlDbType.Bit, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(SqlDbType.Bit, "bit","bit", null, true, null) }, - { typeof(sbyte).FullName, (SqlDbType.SmallInt, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true, null) }, - { typeof(short).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true, null) }, - { typeof(int).FullName, (SqlDbType.Int, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, (SqlDbType.Int, "int", "int", false, true, null) }, - { typeof(long).FullName, (SqlDbType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, (SqlDbType.BigInt, "bigint","bigint", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(SqlDbType.SmallInt, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(SqlDbType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, CsToDb.New(SqlDbType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(SqlDbType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, CsToDb.New(SqlDbType.Int, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(SqlDbType.Int, "int", "int", false, true, null) }, + { typeof(long).FullName, CsToDb.New(SqlDbType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(SqlDbType.BigInt, "bigint","bigint", false, true, null) }, - { typeof(byte).FullName, (SqlDbType.TinyInt, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (SqlDbType.TinyInt, "tinyint","tinyint", true, true, null) }, - { typeof(ushort).FullName, (SqlDbType.Int, "int","int NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (SqlDbType.Int, "int", "int", true, true, null) }, - { typeof(uint).FullName, (SqlDbType.BigInt, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (SqlDbType.BigInt, "bigint", "bigint", true, true, null) }, - { typeof(ulong).FullName, (SqlDbType.Decimal, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (SqlDbType.Decimal, "decimal", "decimal(20,0)", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(SqlDbType.TinyInt, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(SqlDbType.TinyInt, "tinyint","tinyint", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(SqlDbType.Int, "int","int NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(SqlDbType.Int, "int", "int", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(SqlDbType.BigInt, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(SqlDbType.BigInt, "bigint", "bigint", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(SqlDbType.Decimal, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(SqlDbType.Decimal, "decimal", "decimal(20,0)", true, true, null) }, - { typeof(double).FullName, (SqlDbType.Float, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, (SqlDbType.Float, "float", "float", false, true, null) }, - { typeof(float).FullName, (SqlDbType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, (SqlDbType.Real, "real","real", false, true, null) }, - { typeof(decimal).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(double).FullName, CsToDb.New(SqlDbType.Float, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(SqlDbType.Float, "float", "float", false, true, null) }, + { typeof(float).FullName, CsToDb.New(SqlDbType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(SqlDbType.Real, "real","real", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(SqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(SqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(TimeSpan).FullName, (SqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (SqlDbType.Time, "time", "time",false, true, null) }, - { typeof(DateTime).FullName, (SqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (SqlDbType.DateTime, "datetime", "datetime", false, true, null) }, - { typeof(DateTimeOffset).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(SqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(SqlDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(SqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(SqlDbType.DateTime, "datetime", "datetime", false, true, null) }, + { typeof(DateTimeOffset).FullName, CsToDb.New(SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true, null) }, - { typeof(byte[]).FullName, (SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, - { typeof(string).FullName, (SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, - { typeof(Guid).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -55,8 +55,8 @@ namespace FreeSql.SqlServer if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (SqlDbType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(SqlDbType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -65,7 +65,7 @@ namespace FreeSql.SqlServer _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } @@ -102,7 +102,7 @@ ELSE , @level2type = 'COLUMN', @level2name = N'{2}' ", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); string database = null; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 31089821..6b2e21fe 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -1,5 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -58,40 +59,40 @@ namespace FreeSql.SqlServer } } - static readonly Dictionary _dicDbToCs = new Dictionary() { - { (int)SqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)SqlDbType.Bit, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, - { (int)SqlDbType.TinyInt, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, - { (int)SqlDbType.SmallInt, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, - { (int)SqlDbType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, - { (int)SqlDbType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)SqlDbType.TinyInt, new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)SqlDbType.SmallInt, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)SqlDbType.Int, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)SqlDbType.BigInt, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, - { (int)SqlDbType.SmallMoney, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)SqlDbType.Money, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)SqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, - { (int)SqlDbType.Float, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, - { (int)SqlDbType.Real, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)SqlDbType.SmallMoney, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)SqlDbType.Money, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)SqlDbType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)SqlDbType.Float, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)SqlDbType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, - { (int)SqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, - { (int)SqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)SqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)SqlDbType.DateTime2, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)SqlDbType.SmallDateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, - { (int)SqlDbType.DateTimeOffset, ("(DateTimeOffset?)", "new DateTimeOffset(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTimeOffset), typeof(DateTimeOffset?), "{0}.Value", "GetDateTimeOffset") }, + { (int)SqlDbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)SqlDbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)SqlDbType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)SqlDbType.DateTime2, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)SqlDbType.SmallDateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)SqlDbType.DateTimeOffset, new DbToCs("(DateTimeOffset?)", "new DateTimeOffset(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTimeOffset), typeof(DateTimeOffset?), "{0}.Value", "GetDateTimeOffset") }, - { (int)SqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)SqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)SqlDbType.Image, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)SqlDbType.Timestamp, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)SqlDbType.Binary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)SqlDbType.VarBinary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)SqlDbType.Image, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + { (int)SqlDbType.Timestamp, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, - { (int)SqlDbType.Char, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.NChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.NVarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.NText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.NChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.NVarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)SqlDbType.NText, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, - { (int)SqlDbType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + { (int)SqlDbType.UniqueIdentifier, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, }; public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 22ac8e2e..6315b9fe 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -1,4 +1,5 @@ using FreeSql; +using FreeSql.Internal.Model; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -37,11 +38,11 @@ public static partial class FreeSqlSqlServerGlobalExtensions /// public static IFreeSql SetGlobalSelectWithLock(this IFreeSql that, SqlServerLock lockType, Dictionary rule) { - var value = (lockType, rule); + var value = NaviteTuple.Create(lockType, rule); _dicSetGlobalSelectWithLock.AddOrUpdate(that, value, (_, __) => value); return that; } - internal static ConcurrentDictionary)> _dicSetGlobalSelectWithLock = new ConcurrentDictionary)>(); + internal static ConcurrentDictionary>> _dicSetGlobalSelectWithLock = new ConcurrentDictionary>>(); #region ExecuteSqlBulkCopy /// diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 91a72326..b6ed95d0 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -15,35 +16,35 @@ namespace FreeSql.Sqlite public SqliteCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary _dicCsToDb = new Dictionary() { - { typeof(bool).FullName, (DbType.Boolean, "boolean","boolean NOT NULL", null, false, false) },{ typeof(bool?).FullName, (DbType.Boolean, "boolean","boolean", null, true, null) }, + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(DbType.Boolean, "boolean","boolean NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(DbType.Boolean, "boolean","boolean", null, true, null) }, - { typeof(sbyte).FullName, (DbType.SByte, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (DbType.SByte, "smallint", "smallint", false, true, null) }, - { typeof(short).FullName, (DbType.Int16, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (DbType.Int16, "smallint", "smallint", false, true, null) }, - { typeof(int).FullName, (DbType.Int32, "integer", "integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, (DbType.Int32, "integer", "integer", false, true, null) }, - { typeof(long).FullName, (DbType.Int64, "integer","integer NOT NULL", false, false, 0) },{ typeof(long?).FullName, (DbType.Int64, "integer","integer", false, true, null) }, + { typeof(sbyte).FullName, CsToDb.New(DbType.SByte, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(DbType.SByte, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, CsToDb.New(DbType.Int16, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(DbType.Int16, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, CsToDb.New(DbType.Int32, "integer", "integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(DbType.Int32, "integer", "integer", false, true, null) }, + { typeof(long).FullName, CsToDb.New(DbType.Int64, "integer","integer NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(DbType.Int64, "integer","integer", false, true, null) }, - { typeof(byte).FullName, (DbType.Byte, "int2","int2 NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (DbType.Byte, "int2","int2", true, true, null) }, - { typeof(ushort).FullName, (DbType.UInt16, "unsigned","unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (DbType.UInt16, "unsigned", "unsigned", true, true, null) }, - { typeof(uint).FullName, (DbType.Decimal, "decimal(10,0)", "decimal(10,0) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (DbType.Decimal, "decimal(10,0)", "decimal(10,0)", true, true, null) }, - { typeof(ulong).FullName, (DbType.Decimal, "decimal(21,0)", "decimal(21,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (DbType.Decimal, "decimal(21,0)", "decimal(21,0)", true, true, null) }, + { typeof(byte).FullName, CsToDb.New(DbType.Byte, "int2","int2 NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(DbType.Byte, "int2","int2", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(DbType.UInt16, "unsigned","unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(DbType.UInt16, "unsigned", "unsigned", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(DbType.Decimal, "decimal(10,0)", "decimal(10,0) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(DbType.Decimal, "decimal(10,0)", "decimal(10,0)", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(DbType.Decimal, "decimal(21,0)", "decimal(21,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(DbType.Decimal, "decimal(21,0)", "decimal(21,0)", true, true, null) }, - { typeof(double).FullName, (DbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (DbType.Double, "double", "double", false, true, null) }, - { typeof(float).FullName, (DbType.Single, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (DbType.Single, "float","float", false, true, null) }, - { typeof(decimal).FullName, (DbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (DbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + { typeof(double).FullName, CsToDb.New(DbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(DbType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, CsToDb.New(DbType.Single, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(DbType.Single, "float","float", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(DbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(DbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, - { typeof(TimeSpan).FullName, (DbType.Time, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (DbType.Time, "bigint", "bigint",false, true, null) }, - { typeof(DateTime).FullName, (DbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (DbType.DateTime, "datetime", "datetime", false, true, null) }, + { typeof(TimeSpan).FullName, CsToDb.New(DbType.Time, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(DbType.Time, "bigint", "bigint",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(DbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(DbType.DateTime, "datetime", "datetime", false, true, null) }, - { typeof(byte[]).FullName, (DbType.Binary, "blob", "blob", false, null, new byte[0]) }, - { typeof(string).FullName, (DbType.String, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(byte[]).FullName, CsToDb.New(DbType.Binary, "blob", "blob", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(DbType.String, "nvarchar", "nvarchar(255)", false, null, "") }, - { typeof(Guid).FullName, (DbType.Guid, "character", "character(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (DbType.Guid, "character", "character(36)", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(DbType.Guid, "character", "character(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DbType.Guid, "character", "character(36)", false, true, null) }, }; - public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) + public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue)); + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -54,8 +55,8 @@ namespace FreeSql.Sqlite if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (DbType.Int64, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - (DbType.Int32, "mediumint", $"mediumint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(DbType.Int64, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(DbType.Int32, "mediumint", $"mediumint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) @@ -64,12 +65,12 @@ namespace FreeSql.Sqlite _dicCsToDb.Add(type.FullName, newItem); } } - return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6); + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); } return null; } - protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var sb = new StringBuilder(); var sbDeclare = new StringBuilder(); From b647d02308afe0b6f0814dc548c6f946091274be Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 8 Mar 2020 14:19:42 +0800 Subject: [PATCH 0464/1029] 1.3.0-preview5 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 350 +++++++++--------- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 182 insertions(+), 202 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 79f68429..f1fd0ca6 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 6d34c895..52fd64f2 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 6493cdb0..ef148021 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 82126de9..c0d5129d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index c794f2e5..db6e87f4 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview4 + 1.3.0-preview5 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index bba971b5..2f792c52 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a7a2081f..ef6126cc 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d158f453..0c8a0344 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b30fa455..91510fa8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8090152d..08d2c1b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2260,6 +2260,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 }) + + + + + + 可自定义解析表达式 @@ -2814,6 +2945,40 @@ + + + C#:从元组集合中查找 exp1, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + + C#:从元组集合中查找 exp1, exp2, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + 测量两个经纬度的距离,返回单位:米 @@ -3078,188 +3243,3 @@ -.IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 1aedefb6..04fa3b87 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c251beb4..91e6286b 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fe7da754..53ad8588 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e437e24b..d1498d5e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2bd21387..5b2babdf 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 3f107edb..872e6468 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 3143cf46..4f1486d2 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 1ae621b5..753ad445 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview4 + 1.3.0-preview5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 9f0e28bcace406ae83e8348244db1c00f2afd85a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 9 Mar 2020 19:25:45 +0800 Subject: [PATCH 0465/1029] update readme --- .../Controllers/ValuesController.cs | 17 ++++-- Examples/dbcontext_01/Startup.cs | 56 +++++++------------ readme.md | 40 ++++--------- 3 files changed, 44 insertions(+), 69 deletions(-) diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs index e8aa5508..7ad083b1 100644 --- a/Examples/dbcontext_01/Controllers/ValuesController.cs +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -14,13 +14,12 @@ namespace dbcontext_01.Controllers IFreeSql _orm; SongContext _songContext; - public ValuesController(SongContext songContext, - IFreeSql orm1, IFreeSql orm2, - IFreeSql orm3 - ) + CurdAfterLog _curdLog; + public ValuesController(SongContext songContext, IFreeSql orm1, CurdAfterLog curdLog) { _songContext = songContext; _orm = orm1; + _curdLog = curdLog; } @@ -230,7 +229,7 @@ namespace dbcontext_01.Controllers var item22 = await _orm.Select().Where(a => a.Id == id).FirstAsync(); var item33 = await _orm.Select().Where(a => a.Id > id).ToListAsync(); - return item22.Id.ToString(); + return item22.Id.ToString() + "\r\n\r\n" + _curdLog.Sb.ToString(); } // GET api/values/5 @@ -240,6 +239,14 @@ namespace dbcontext_01.Controllers return _orm.Select().Where(a => a.Id == id).First(); } + [HttpGet("get{id}")] + public ActionResult Get2(int id) + { + var item1 = _orm.Select().Where(a => a.Id == id).First(); + var item2 = _orm.Select().Where(a => a.Id == id).First(); + return _curdLog.Sb.ToString(); + } + // POST api/values [HttpPost] public void Post([FromBody] string value) diff --git a/Examples/dbcontext_01/Startup.cs b/Examples/dbcontext_01/Startup.cs index 638fc0f6..b086f8ac 100644 --- a/Examples/dbcontext_01/Startup.cs +++ b/Examples/dbcontext_01/Startup.cs @@ -7,6 +7,7 @@ using System; using System.Diagnostics; using System.Linq; using System.Text; +using System.Threading; namespace dbcontext_01 { @@ -19,49 +20,22 @@ namespace dbcontext_01 Fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document2.db;Pooling=true;Max Pool Size=10") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - //.UseConnectionString(DataType.MySql, "Data Source=192.168.164.10;Port=33061;User ID=root;Password=123456;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5") //.UseSlave("Data Source=192.168.164.10;Port=33062;User ID=root;Password=123456;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5") - //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") //.UseSyncStructureToUpper(true) - .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNoneCommandParameter(true) - - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), - (cmd, log) => Trace.WriteLine(log) - ) + .UseMonitorCommand(cmd => { }, (cmd, log) => Trace.WriteLine(log)) .Build(); - Fsql.Aop.SyncStructureBefore += (s, e) => - { - Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName))); - }; - Fsql.Aop.SyncStructureAfter += (s, e) => - { - Console.WriteLine(e.Identifier + ": " + string.Join(", ", e.EntityTypes.Select(a => a.FullName)) + " " + e.ElapsedMilliseconds + "ms\r\n" + e.Exception?.Message + e.Sql); - }; - Fsql.Aop.CurdBefore += (s, e) => - { - Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + ", " + e.Sql); - }; Fsql.Aop.CurdAfter += (s, e) => { Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + " " + e.ElapsedMilliseconds + "ms, " + e.Sql); + CurdAfterLog.Current.Value?.Sb.AppendLine($"{Thread.CurrentThread.ManagedThreadId}: {e.EntityType.FullName} {e.ElapsedMilliseconds}ms, {e.Sql}"); }; - Fsql2 = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document222.db;Pooling=true;Max Pool Size=10") - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText), - (cmd, log) => Trace.WriteLine(log) - ) - .Build(); } enum MySql { } @@ -69,20 +43,14 @@ namespace dbcontext_01 public IConfiguration Configuration { get; } public static IFreeSql Fsql { get; private set; } - public static IFreeSql Fsql2 { get; private set; } public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSingleton(Fsql); - services.AddSingleton>(Fsql2); services.AddFreeDbContext(options => options.UseFreeSql(Fsql)); - - - var sql1 = Fsql.Update(1).Set(a => a.Id + 10).ToSql(); - var sql2 = Fsql.Update(1).Set(a => a.Title + 10).ToSql(); - var sql3 = Fsql.Update(1).Set(a => a.Create_time.Value.AddHours(1)).ToSql(); + services.AddScoped(); } public void Configure(IApplicationBuilder app) @@ -97,4 +65,20 @@ namespace dbcontext_01 app.UseEndpoints(a => a.MapControllers()); } } + + public class CurdAfterLog : IDisposable + { + public static AsyncLocal Current = new AsyncLocal(); + public StringBuilder Sb { get; } = new StringBuilder(); + + public CurdAfterLog() + { + Current.Value = this; + } + public void Dispose() + { + Sb.Clear(); + Current.Value = null; + } + } } diff --git a/readme.md b/readme.md index 828bcd38..2568f7bb 100644 --- a/readme.md +++ b/readme.md @@ -62,14 +62,14 @@ class Song { public string Url { get; set; } public DateTime CreateTime { get; set; } - public virtual ICollection Tags { get; set; } + public ICollection Tags { get; set; } } class Song_tag { public int Song_id { get; set; } - public virtual Song Song { get; set; } + public Song Song { get; set; } public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } + public Tag Tag { get; set; } } class Tag { [Column(IsIdentity = true)] @@ -77,10 +77,10 @@ class Tag { public string Name { get; set; } public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } + public Tag Parent { get; set; } - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } + public ICollection Songs { get; set; } + public ICollection Tags { get; set; } } ``` @@ -89,12 +89,11 @@ class Tag { //OneToOne、ManyToOne fsql.Select() .Where(a => a.Parent.Parent.Name == "粤语") - .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) .ToList(); //OneToMany fsql.Select() - .Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)) + .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) .ToList(); //ManyToMany @@ -127,7 +126,7 @@ fsql.Select() fsql.Select() .OrderBy(a => Guid.NewGuid()) - .Limit(1) + .Limit(10) .ToList(); ``` 更多前往Wiki:[《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) @@ -140,21 +139,8 @@ using (var uow = fsql.CreateUnitOfWork()) { var repo1 = uow.GetRepository(); var repo2 = uow.GetRepository(); - await repo1.InsertAsync(new Song()); - await repo2.InsertAsync(new Tag()); - uow.Commit(); -} -``` - -## DbContext & DbSet -> dotnet add package FreeSql.DbContext - -```csharp -using (var ctx = new fsql.CreateDbContext()) { - var songs = ctx.Set(); - var tags = ctx.Set(); - - var tag = new Tag { + repo2.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo2.Insert(new Tag { Name = "testaddsublist", Tags = new[] { new Tag { Name = "sub1" }, @@ -166,10 +152,8 @@ using (var ctx = new fsql.CreateDbContext()) { } } } - }; - //tags.Add(tag); - ctx.Add(tag); - await ctx.SaveChangesAsync(); + }); + uow.Commit(); } ``` From 720960af14612c42604919cae80d06b05c95175d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Mar 2020 14:06:28 +0800 Subject: [PATCH 0466/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20BulkCopy=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=8F=92=E5=85=A5=E8=87=AA=E5=A2=9E=E9=94=AE?= =?UTF-8?q?=EF=BC=9B=20-=20=E4=BC=98=E5=8C=96=20BulkCopy=20=E5=AF=B9?= =?UTF-8?q?=E5=8F=AF=E7=A9=BA=E7=B1=BB=E5=9E=8B=E7=9A=84=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=9B#227?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/CommonProvider/InsertProvider.cs | 18 +++++++++++++----- .../FreeSqlMySqlConnectorGlobalExtensions.cs | 4 ++-- .../PostgreSQLExtensions.cs | 4 ++-- .../SqlServerExtensions.cs | 4 ++-- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 794bd98e..7553b8be 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -544,24 +544,32 @@ namespace FreeSql.Internal.CommonProvider { var dt = new DataTable(); dt.TableName = TableRuleInvoke(); + var dtCols = new List>(); foreach (var col in _table.ColumnsByPosition) { if (col.Attribute.IsIdentity && _insertIdentity == false) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; - dt.Columns.Add(col.Attribute.Name, col.Attribute.MapType); + dt.Columns.Add(col.Attribute.Name, col.Attribute.MapType.NullableTypeOrThis()); + dtCols.Add(NaviteTuple.Create(col, col.Attribute.MapType.NullableTypeOrThis(), col.Attribute.MapType.IsNullableType())); } if (dt.Columns.Count == 0) return dt; + var didx = 0; foreach (var d in _source) { var row = new object[dt.Columns.Count]; var rowIndex = 0; - foreach (var col in _table.ColumnsByPosition) + foreach (var col in dtCols) { - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; - if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; - row[rowIndex++] = col.GetMapValue(d); + var val = col.Item1.GetMapValue(d); + if (col.Item3 == true) + { + if (val == null) throw new Exception($"[{didx}].{col.Item1.CsName} 值不可为 null;DataTable 限制不可使用 int?/long? 可空类型,IInsert.ToDataTable 将映射成 int/long,因此不可接受 null 值"); + val = Utils.GetDataReaderValue(col.Item2, val); + } + row[rowIndex++] = val; } dt.Rows.Add(row); + didx++; } return dt; } diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs index 6b22af02..c262fa0e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs @@ -31,7 +31,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions var insert = that as FreeSql.MySql.Curd.MySqlInsert; if (insert == null) throw new Exception("ExecuteMySqlBulkCopy 是 FreeSql.Provider.MySqlConnector 特有的功能"); - var dt = that.ToDataTable(); + var dt = that.InsertIdentity().ToDataTable(); if (dt.Rows.Count == 0) return; Action writeToServer = bulkCopy => @@ -90,7 +90,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions var insert = that as FreeSql.MySql.Curd.MySqlInsert; if (insert == null) throw new Exception("ExecuteMySqlBulkCopyAsync 是 FreeSql.Provider.MySqlConnector 特有的功能"); - var dt = that.ToDataTable(); + var dt = that.InsertIdentity().ToDataTable(); if (dt.Rows.Count == 0) return; Func writeToServer = bulkCopy => diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs index b2c75baf..61eb3101 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs @@ -52,7 +52,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions var insert = that as FreeSql.PostgreSQL.Curd.PostgreSQLInsert; if (insert == null) throw new Exception("ExecutePgCopy 是 FreeSql.Provider.PostgreSQL 特有的功能"); - var dt = that.ToDataTable(); + var dt = that.InsertIdentity().ToDataTable(); if (dt.Rows.Count == 0) return; Action binaryImport = conn => @@ -124,7 +124,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions var insert = that as FreeSql.PostgreSQL.Curd.PostgreSQLInsert; if (insert == null) throw new Exception("ExecutePgCopyAsync 是 FreeSql.Provider.PostgreSQL 特有的功能"); - var dt = that.ToDataTable(); + var dt = that.InsertIdentity().ToDataTable(); if (dt.Rows.Count == 0) return; Func binaryImportAsync = async conn => { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 6315b9fe..47b1752f 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -70,7 +70,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions var insert = that as FreeSql.SqlServer.Curd.SqlServerInsert; if (insert == null) throw new Exception("ExecuteSqlBulkCopy 是 FreeSql.Provider.SqlServer 特有的功能"); - var dt = that.ToDataTable(); + var dt = that.InsertIdentity().ToDataTable(); if (dt.Rows.Count == 0) return; Action writeToServer = bulkCopy => @@ -145,7 +145,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions var insert = that as FreeSql.SqlServer.Curd.SqlServerInsert; if (insert == null) throw new Exception("ExecuteSqlBulkCopyAsync 是 FreeSql.Provider.SqlServer 特有的功能"); - var dt = that.ToDataTable(); + var dt = that.InsertIdentity().ToDataTable(); if (dt.Rows.Count == 0) return; Func writeToServerAsync = bulkCopy => From ef63af7db54f88b2e5f1e180938d4f7215552b4c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Mar 2020 14:16:15 +0800 Subject: [PATCH 0467/1029] ## v1.3.0-preview6 #227 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f1fd0ca6..4bb401e4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 52fd64f2..737ff3d1 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ef148021..c887bc0b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c0d5129d..d24c85c3 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index db6e87f4..150ff828 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview5 + 1.3.0-preview6 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 2f792c52..b7e293da 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ef6126cc..d5bec6d4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0c8a0344..dee60f81 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 91510fa8..8df7cdd8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 04fa3b87..7d203e22 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 91e6286b..18ae145c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 53ad8588..b1b83b0e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d1498d5e..d5d8501c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 5b2babdf..c4fd5b9b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 872e6468..b7f8449b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4f1486d2..2e2a4940 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 753ad445..863275d0 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview5 + 1.3.0-preview6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From a1a265fa280a4365655c715727b68a0af1197a9c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Mar 2020 15:20:01 +0800 Subject: [PATCH 0468/1029] 1.3.0-preview7 #277 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSqlMySqlConnectorGlobalExtensions.cs | 4 ++-- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs | 4 ++-- .../FreeSql.Provider.SqlServer.csproj | 2 +- Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs | 4 ++-- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 4bb401e4..100a233e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 737ff3d1..20af993a 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index c887bc0b..77e2493c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index d24c85c3..dc943f8f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 150ff828..2304e0d3 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview6 + 1.3.0-preview7 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index b7e293da..2b19f299 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d5bec6d4..a1de436d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index dee60f81..b83d2db7 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8df7cdd8..a4f5aeda 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 7d203e22..516d5a82 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 18ae145c..89234a8c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index b1b83b0e..ddc9ffff 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs index c262fa0e..6b22af02 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs @@ -31,7 +31,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions var insert = that as FreeSql.MySql.Curd.MySqlInsert; if (insert == null) throw new Exception("ExecuteMySqlBulkCopy 是 FreeSql.Provider.MySqlConnector 特有的功能"); - var dt = that.InsertIdentity().ToDataTable(); + var dt = that.ToDataTable(); if (dt.Rows.Count == 0) return; Action writeToServer = bulkCopy => @@ -90,7 +90,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions var insert = that as FreeSql.MySql.Curd.MySqlInsert; if (insert == null) throw new Exception("ExecuteMySqlBulkCopyAsync 是 FreeSql.Provider.MySqlConnector 特有的功能"); - var dt = that.InsertIdentity().ToDataTable(); + var dt = that.ToDataTable(); if (dt.Rows.Count == 0) return; Func writeToServer = bulkCopy => diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d5d8501c..4643bb71 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index c4fd5b9b..84d26947 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b7f8449b..8c1aa9d6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs index 61eb3101..b2c75baf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs @@ -52,7 +52,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions var insert = that as FreeSql.PostgreSQL.Curd.PostgreSQLInsert; if (insert == null) throw new Exception("ExecutePgCopy 是 FreeSql.Provider.PostgreSQL 特有的功能"); - var dt = that.InsertIdentity().ToDataTable(); + var dt = that.ToDataTable(); if (dt.Rows.Count == 0) return; Action binaryImport = conn => @@ -124,7 +124,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions var insert = that as FreeSql.PostgreSQL.Curd.PostgreSQLInsert; if (insert == null) throw new Exception("ExecutePgCopyAsync 是 FreeSql.Provider.PostgreSQL 特有的功能"); - var dt = that.InsertIdentity().ToDataTable(); + var dt = that.ToDataTable(); if (dt.Rows.Count == 0) return; Func binaryImportAsync = async conn => { diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2e2a4940..de394f96 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 47b1752f..6315b9fe 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -70,7 +70,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions var insert = that as FreeSql.SqlServer.Curd.SqlServerInsert; if (insert == null) throw new Exception("ExecuteSqlBulkCopy 是 FreeSql.Provider.SqlServer 特有的功能"); - var dt = that.InsertIdentity().ToDataTable(); + var dt = that.ToDataTable(); if (dt.Rows.Count == 0) return; Action writeToServer = bulkCopy => @@ -145,7 +145,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions var insert = that as FreeSql.SqlServer.Curd.SqlServerInsert; if (insert == null) throw new Exception("ExecuteSqlBulkCopyAsync 是 FreeSql.Provider.SqlServer 特有的功能"); - var dt = that.InsertIdentity().ToDataTable(); + var dt = that.ToDataTable(); if (dt.Rows.Count == 0) return; Func writeToServerAsync = bulkCopy => diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 863275d0..6997f0cc 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview6 + 1.3.0-preview7 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From fff7925d22162ad0b9cc8b80af7ce00fdd074f87 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 11 Mar 2020 18:51:56 +0800 Subject: [PATCH 0469/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect`1=20?= =?UTF-8?q?AsQueryable=20=E6=96=B9=E6=B3=95=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=B0=86=20ISelect=20=E8=BD=AC=E6=8D=A2=E4=B8=BA=20IQueryable?= =?UTF-8?q?=20=E7=B1=BB=E5=9E=8B=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 -- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 30 +++++ FreeSql/FreeSql.xml | 8 ++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 9 ++ FreeSql/Internal/CommonExpression.cs | 2 + .../SelectProvider/QueryableProvider.cs | 107 ++++++++++++++++++ .../SelectProvider/Select1Provider.cs | 2 + 7 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/QueryableProvider.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ca7c357b..2735cefb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 49ecb36e..dc3ae2e0 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -116,9 +116,39 @@ namespace FreeSql.Tests public string Name { get; set; } } + [Table(Name = "EDI")] + public class Edi + { + [Column(Name = "EDI_ID")] public long Id { get; set; } + } + [Table(Name = "EDI_ITEM")] + public class EdiItem + { + [Column(Name = "EDII_ID")] public long Id { get; set; } + [Column(Name = "EDII_EDI_ID")] public long EdiId { get; set; } + } + [Fact] public void Test03() { + var lksdjkg1 = g.sqlite.Select() + .AsQueryable().Where(a => a.Id > 0).ToList(); + + var lksdjkg2 = g.sqlite.Select() + .AsQueryable().Where(a => a.Id > 0).First(); + + var lksdjkg3 = g.sqlite.Select() + .AsQueryable().Where(a => a.Id > 0).FirstOrDefault(); + + + var sql222efe = g.sqlite.Select() + .InnerJoin((a, b) => b.Id == g.sqlite.Select().As("c").Where(c => c.EdiId == a.Id).OrderBy(c => c.Id).ToOne(c => c.Id)) + .ToSql((a, b) => new + { + Id = a.Id, + EdiId = b.Id + }); + var subSyetemId = "xxx"; var list = g.sqlite.Select() .LeftJoin((a,b) => a.SubNameID == b.Id) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 08d2c1b3..89c147ea 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1719,6 +1719,14 @@ SQL语句 + + + 将 ISelect<T1> 转换为 IQueryable<T1> + 此方法主要用于扩展,比如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 + 注意:IQueryable 方法污染较为严重,请尽量避免此转换 + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 34c9ce6d..a6bb4622 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -377,5 +378,13 @@ namespace FreeSql /// SQL语句 /// ISelect WithSql(string sql); + + /// + /// 将 ISelect<T1> 转换为 IQueryable<T1> + /// 此方法主要用于扩展,比如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 + /// 注意:IQueryable 方法污染较为严重,请尽量避免此转换 + /// + /// + IQueryable AsQueryable(); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index f9e424d1..2138f213 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -707,6 +707,7 @@ namespace FreeSql.Internal case "Max": case "Avg": case "ToList": //where in + case "ToOne": case "First": var anyArgs = exp3.Arguments; var exp3Stack = new Stack(); @@ -991,6 +992,7 @@ namespace FreeSql.Internal return $"({sqlSum.Replace("\r\n", "\r\n\t")})"; break; case "ToList": + case "ToOne": case "First": var tscClone2 = tsc.CloneDisableDiyParse(); tscClone2.isDisableDiyParse = false; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/QueryableProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/QueryableProvider.cs new file mode 100644 index 00000000..bf52e097 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/QueryableProvider.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace FreeSql.Internal.CommonProvider +{ + class QueryableProvider : IQueryable + { + private Expression _expression; + private IQueryProvider _provider; + private object _select; + private CommonExpression _commonExpression; + + public QueryableProvider(object select) + { + _select = select; + _commonExpression = _select.GetType().GetField("_commonExpression", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_select) as CommonExpression; + _expression = Expression.Constant(this); + _provider = new QueryProvider(_select, _commonExpression); + } + public QueryableProvider(Expression expression, IQueryProvider provider, object select, CommonExpression commonExpression) + { + _select = select; + _commonExpression = commonExpression; + _expression = expression; + _provider = provider; + } + + public IEnumerator GetEnumerator() + { + var result = _provider.Execute>(_expression); + if (result == null) + yield break; + foreach (var item in result) + { + yield return item; + } + } + IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); + + public Type ElementType => typeof(QueryableProvider); + public Expression Expression => _expression; + public IQueryProvider Provider => _provider; + } + + class QueryProvider : IQueryProvider + { + private object _select; + private CommonExpression _commonExpression; + + public QueryProvider(object select, CommonExpression commonExpression) + { + _select = select; + _commonExpression = commonExpression; + } + + public IQueryable CreateQuery(Expression expression) + { + IQueryable query = new QueryableProvider(expression, this, _select, _commonExpression); + return query; + } + public IQueryable CreateQuery(Expression expression) => throw new NotImplementedException(); + + + public TResult Execute(Expression expression) + { + var methodExp = expression as MethodCallExpression; + while (methodExp != null) + { + switch (methodExp.Method.Name) + { + case "First": + case "FirstOrDefault": + _select.GetType().GetMethod("Limit", new[] { typeof(int) }).Invoke(_select, new object[] { 1 }); + break; + default: + var selectMethod = _select.GetType().GetMethod(methodExp.Method.Name, methodExp.Arguments.Where((a, b) => b > 0).Select(a => a.Type).ToArray()); + if (selectMethod == null) throw new Exception($"无法找到 ISelect.{methodExp.Method.Name}({string.Join(", ", methodExp.Arguments.Select(a => a.Type.FullName))}) 方法"); + + var selectArgs = methodExp.Arguments.Where((a, b) => b > 0).Select(a => + { + switch (a.NodeType) + { + case ExpressionType.Lambda: return (object)a; + default: return Expression.Lambda(a).Compile().DynamicInvoke(); + } + }).ToArray(); + selectMethod.Invoke(_select, selectArgs); + break; + } + methodExp = methodExp.Arguments.FirstOrDefault() as MethodCallExpression; + } + var resultType = typeof(TResult); + var resultTypeIsList = typeof(IList).IsAssignableFrom(resultType); + if (resultTypeIsList) resultType = resultType.GetGenericArguments()[0]; + var ret = _select.GetType().GetMethod(resultTypeIsList ? "ToList" : "First", new Type[0]) + .MakeGenericMethod(resultType) + .Invoke(_select, new object[0]); + return (TResult)ret; + } + public object Execute(Expression expression) => throw new NotImplementedException(); + } +} diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 83cb8b3d..2d3b877f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -1071,6 +1071,8 @@ namespace FreeSql.Internal.CommonProvider _trackToList?.Invoke(list); } + public IQueryable AsQueryable() => new QueryableProvider(this); + #if net40 #else async internal Task SetListAsync(IEnumerable list) From e132133e62f184ad7cc8ac0c4b4a7168b6336223 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 12 Mar 2020 00:45:56 +0800 Subject: [PATCH 0470/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IAdo.Query?= =?UTF-8?q?=20=E6=96=B9=E6=B3=95=EF=BC=8C=E5=BD=93=E4=BC=A0=E5=85=A5?= =?UTF-8?q?=E5=B8=A6=E4=B8=BB=E9=94=AE=E7=89=B9=E6=80=A7=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=97=B6=EF=BC=8C=E9=98=B2=E6=AD=A2=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E5=88=97=E4=B8=BA=20null=20=E6=97=B6=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E6=95=B4=E8=A1=8C=E8=AE=B0=E5=BD=95=E4=B9=9F=E4=B8=BA=20null?= =?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 | 7 ++ FreeSql/FreeSql.xml | 80 +++++++++++-------- .../CommonProvider/AdoProvider/AdoProvider.cs | 30 +++---- .../AdoProvider/AdoProviderAsync.cs | 30 +++---- FreeSql/Internal/UtilsExpressionTree.cs | 3 +- 5 files changed, 85 insertions(+), 65 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2735cefb..ca7c357b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 89c147ea..ee325756 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2953,40 +2953,6 @@ - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - - C#:从元组集合中查找 exp1, exp2, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - 测量两个经纬度的距离,返回单位:米 @@ -3251,3 +3217,49 @@ +完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 45db5750..2f2facd5 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -105,7 +105,7 @@ namespace FreeSql.Internal.CommonProvider { if (indexes == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -148,7 +148,7 @@ namespace FreeSql.Internal.CommonProvider case 0: if (indexes1 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -165,7 +165,7 @@ namespace FreeSql.Internal.CommonProvider case 1: if (indexes2 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -216,7 +216,7 @@ namespace FreeSql.Internal.CommonProvider case 0: if (indexes1 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -233,7 +233,7 @@ namespace FreeSql.Internal.CommonProvider case 1: if (indexes2 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -250,7 +250,7 @@ namespace FreeSql.Internal.CommonProvider case 2: if (indexes3 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -307,7 +307,7 @@ namespace FreeSql.Internal.CommonProvider case 0: if (indexes1 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -324,7 +324,7 @@ namespace FreeSql.Internal.CommonProvider case 1: if (indexes2 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -341,7 +341,7 @@ namespace FreeSql.Internal.CommonProvider case 2: if (indexes3 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -358,7 +358,7 @@ namespace FreeSql.Internal.CommonProvider case 3: if (indexes4 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -421,7 +421,7 @@ namespace FreeSql.Internal.CommonProvider case 0: if (indexes1 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -438,7 +438,7 @@ namespace FreeSql.Internal.CommonProvider case 1: if (indexes2 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -455,7 +455,7 @@ namespace FreeSql.Internal.CommonProvider case 2: if (indexes3 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -472,7 +472,7 @@ namespace FreeSql.Internal.CommonProvider case 3: if (indexes4 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -489,7 +489,7 @@ namespace FreeSql.Internal.CommonProvider case 4: if (indexes5 == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 7297122d..bc8b96b6 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -31,7 +31,7 @@ namespace FreeSql.Internal.CommonProvider { if (indexes == null) { - var sbflag = new StringBuilder().Append("query"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -75,7 +75,7 @@ namespace FreeSql.Internal.CommonProvider case 0: if (indexes1 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -92,7 +92,7 @@ namespace FreeSql.Internal.CommonProvider case 1: if (indexes2 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -144,7 +144,7 @@ namespace FreeSql.Internal.CommonProvider case 0: if (indexes1 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -161,7 +161,7 @@ namespace FreeSql.Internal.CommonProvider case 1: if (indexes2 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -178,7 +178,7 @@ namespace FreeSql.Internal.CommonProvider case 2: if (indexes3 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -236,7 +236,7 @@ namespace FreeSql.Internal.CommonProvider case 0: if (indexes1 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -253,7 +253,7 @@ namespace FreeSql.Internal.CommonProvider case 1: if (indexes2 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -270,7 +270,7 @@ namespace FreeSql.Internal.CommonProvider case 2: if (indexes3 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -287,7 +287,7 @@ namespace FreeSql.Internal.CommonProvider case 3: if (indexes4 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -351,7 +351,7 @@ namespace FreeSql.Internal.CommonProvider case 0: if (indexes1 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -368,7 +368,7 @@ namespace FreeSql.Internal.CommonProvider case 1: if (indexes2 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -385,7 +385,7 @@ namespace FreeSql.Internal.CommonProvider case 2: if (indexes3 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -402,7 +402,7 @@ namespace FreeSql.Internal.CommonProvider case 3: if (indexes4 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { @@ -419,7 +419,7 @@ namespace FreeSql.Internal.CommonProvider case 4: if (indexes5 == null) { - var sbflag = new StringBuilder().Append("QueryAsync"); + var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) { diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6738bcf9..2823edcd 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1495,7 +1495,8 @@ namespace FreeSql.Internal //判断主键为空,则整个对象不读取 //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp))); - if (trycol?.Attribute.IsPrimary == true) + if (flagStr.StartsWith("adoQuery") == false && //Ado.Query 的时候不作此判断 + trycol?.Attribute.IsPrimary == true) //若主键值为 null,则整行读取出来的对象为 null { ispkExp.Add( Expression.IfThen( From c468c65ba5db581dbeaef0c8ca98e16c97d96e25 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 12 Mar 2020 15:49:08 +0800 Subject: [PATCH 0471/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20UseGenerateC?= =?UTF-8?q?ommandParameterWithLambda(true)=20=E6=97=B6=E5=AD=90=E8=AF=AD?= =?UTF-8?q?=E5=8F=A5=E7=9A=84=E5=8F=82=E6=95=B0=E6=B2=A1=E6=95=B4=E5=90=88?= =?UTF-8?q?=E5=88=B0=E4=B8=BB=E8=AF=AD=E5=8F=A5=EF=BC=9B#231=20-=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20ISelect.RawJoin=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E4=BB=A5=E4=BE=BF=E5=AE=9E=E7=8E=B0=20Outer=20Apply=20?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=EF=BC=9B#200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 5 ++ FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- FreeSql/FreeSql.xml | 88 +++++++++---------- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 7 ++ FreeSql/Internal/CommonExpression.cs | 2 + .../SelectProvider/Select0Provider.cs | 21 +++-- 6 files changed, 70 insertions(+), 55 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index dc3ae2e0..d7538507 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -131,6 +131,11 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var itemId = 1; + var edi = g.sqlite.Select() + .Where(a => g.sqlite.Select().Where(b => b.Id == itemId).Any()) + .First(a => a); //#231 + var lksdjkg1 = g.sqlite.Select() .AsQueryable().Where(a => a.Id > 0).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 985eae8b..8a149a24 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -83,7 +83,7 @@ public class g // return conn; //}) .UseAutoSyncStructure(true) - //.UseGenerateCommandParameterWithLambda(true) + .UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) .UseMonitorCommand( cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ee325756..1efa0813 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1226,6 +1226,14 @@ 参数 + + + 在 JOIN 位置插入 SQL 内容 + 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) @@ -2953,6 +2961,40 @@ + + + C#:从元组集合中查找 exp1, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + + C#:从元组集合中查找 exp1, exp2, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + 测量两个经纬度的距离,返回单位:米 @@ -3217,49 +3259,3 @@ -完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 363d8249..b42fc3c1 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -226,6 +226,13 @@ namespace FreeSql /// 参数 /// TSelect RightJoin(string sql, object parms = null); + /// + /// 在 JOIN 位置插入 SQL 内容 + /// 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") + /// + /// + /// + TSelect RawJoin(string sql); /// /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 2138f213..64bed1e7 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -808,6 +808,8 @@ namespace FreeSql.Internal if (fsqlType == null) break; if (exp3.Method.Name != "ToList") fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); + if (tsc.dbParams != null) + fsqlType.GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, tsc.dbParams); fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; if (fsqltables != tsc._tables) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 07f7267e..d0c9807a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -244,6 +244,19 @@ namespace FreeSql.Internal.CommonProvider if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); return this as TSelect; } + public TSelect RightJoin(string sql, object parms = null) + { + if (string.IsNullOrEmpty(sql)) return this as TSelect; + _join.Append(" \r\nRIGHT JOIN ").Append(sql); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); + return this as TSelect; + } + public TSelect RawJoin(string sql) + { + if (string.IsNullOrEmpty(sql)) return this as TSelect; + _join.Append(" \r\n").Append(sql); + return this as TSelect; + } public TSelect Limit(int limit) { @@ -273,14 +286,6 @@ namespace FreeSql.Internal.CommonProvider return this.Limit(pageSize) as TSelect; } - public TSelect RightJoin(string sql, object parms = null) - { - if (string.IsNullOrEmpty(sql)) return this as TSelect; - _join.Append(" \r\nRIGHT JOIN ").Append(sql); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); - return this as TSelect; - } - public TSelect Skip(int offset) { _skip = offset; From b8a4d3bb473da7dabc1e5a969baa85d98de2fcbf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 12 Mar 2020 15:57:46 +0800 Subject: [PATCH 0472/1029] #231 --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 3 ++- FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index d7538507..b31fe4d3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -131,9 +131,10 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var itemId2 = 2; var itemId = 1; var edi = g.sqlite.Select() - .Where(a => g.sqlite.Select().Where(b => b.Id == itemId).Any()) + .Where(a => a.Id == itemId2 && g.sqlite.Select().Where(b => b.Id == itemId).Any()) .First(a => a); //#231 var lksdjkg1 = g.sqlite.Select() diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 8a149a24..985eae8b 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -83,7 +83,7 @@ public class g // return conn; //}) .UseAutoSyncStructure(true) - .UseGenerateCommandParameterWithLambda(true) + //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) .UseMonitorCommand( cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 From db15d436d89ba9e539c456ea63b38160ff623159 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 12 Mar 2020 16:13:26 +0800 Subject: [PATCH 0473/1029] ## v1.3.0-preview8 #200 #231 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 4 ++-- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 4 ++-- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 100a233e..90675532 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 20af993a..3c8de4dc 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 77e2493c..33cadcf0 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index dc943f8f..e0722719 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 2304e0d3..86b1305b 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview7 + 1.3.0-preview8 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 2b19f299..9cdb89cf 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a1de436d..4457bbdc 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index b83d2db7..3249ab8a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index a4f5aeda..cb645873 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 516d5a82..13252cc3 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 89234a8c..9171e2c3 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ddc9ffff..57541563 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 4643bb71..424b8cdd 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 84d26947..7c16b739 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8c1aa9d6..02ff0fd7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index de394f96..6028493d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 6997f0cc..d0ab3907 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview7 + 1.3.0-preview8 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 85a6ae49e4927c5befe5e19f28cf5ced4dbf9c9f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 13 Mar 2020 10:28:17 +0800 Subject: [PATCH 0474/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20BulkCopy=20?= =?UTF-8?q?=E5=AF=B9=E5=8F=AF=E7=A9=BA=E7=B1=BB=E5=9E=8B=E7=9A=84=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=A4=84=E7=90=86=EF=BC=9B#227?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/InsertProvider.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 7553b8be..3a15daab 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -563,8 +563,11 @@ namespace FreeSql.Internal.CommonProvider var val = col.Item1.GetMapValue(d); if (col.Item3 == true) { - if (val == null) throw new Exception($"[{didx}].{col.Item1.CsName} 值不可为 null;DataTable 限制不可使用 int?/long? 可空类型,IInsert.ToDataTable 将映射成 int/long,因此不可接受 null 值"); - val = Utils.GetDataReaderValue(col.Item2, val); + //if (val == null) throw new Exception($"[{didx}].{col.Item1.CsName} 值不可为 null;DataTable 限制不可使用 int?/long? 可空类型,IInsert.ToDataTable 将映射成 int/long,因此不可接受 null 值"); + if (val == null) + val = DBNull.Value; + else + val = Utils.GetDataReaderValue(col.Item2, val); } row[rowIndex++] = val; } From d4bf205c7978238e03a6b052c8f62541645ceb6a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 13 Mar 2020 10:34:10 +0800 Subject: [PATCH 0475/1029] add Contributors #227 --- readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 2568f7bb..019cb666 100644 --- a/readme.md +++ b/readme.md @@ -198,7 +198,8 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [densen2014](https://github.com/densen2014)、 [LiaoLiaoWuJu](https://github.com/LiaoLiaoWuJu)、 [hd2y](https://github.com/hd2y)、 -[tky753](https://github.com/tky753) +[tky753](https://github.com/tky753)、 +[feijie999](https://github.com/feijie999) (QQ群:4336577) From 8ddf117fc7481d0e6f371346fd333b8c3d87fcf1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 15 Mar 2020 10:05:34 +0800 Subject: [PATCH 0476/1029] Replace CS-Script.Core To Natasha --- .../FreeSql.Extensions.LazyLoading.csproj | 7 ++----- .../LazyLoadingComplier.cs | 15 ++++----------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e0722719..e04b645a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -22,11 +22,8 @@ - - - - - + + diff --git a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs index 75dfb248..4d286aaa 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs +++ b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs @@ -10,19 +10,12 @@ namespace FreeSql.Extensions.LazyLoading { #if ns20 - internal static Lazy _compiler = new Lazy(() => - { - var compiler = new CSScriptLib.RoslynEvaluator(); - compiler.DisableReferencingFromCode = false; - compiler - .ReferenceAssemblyOf() - .ReferenceDomainAssemblies(); - return compiler; - }); - public static Assembly CompileCode(string cscode) { - return _compiler.Value.CompileCode(cscode); + Natasha.AssemblyComplier complier = new Natasha.AssemblyComplier(); + //complier.Domain = DomainManagment.Random; + complier.Add(cscode); + return complier.GetAssembly(); } #else From 529be7d9d25c1a6926cc5031a85183aeec0a7ed3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 15 Mar 2020 10:53:17 +0800 Subject: [PATCH 0477/1029] Recovery CSScript.Core --- .../FreeSql.Extensions.LazyLoading.csproj | 11 ++++++++- .../LazyLoadingComplier.cs | 23 +++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e04b645a..cefbb7c0 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -21,10 +21,19 @@ - + + + + + + + + + ns20;netstandard20 diff --git a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs index 4d286aaa..e89f72e0 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs +++ b/Extensions/FreeSql.Extensions.LazyLoading/LazyLoadingComplier.cs @@ -10,12 +10,27 @@ namespace FreeSql.Extensions.LazyLoading { #if ns20 + //public static Assembly CompileCode(string cscode) + //{ + // Natasha.AssemblyComplier complier = new Natasha.AssemblyComplier(); + // //complier.Domain = DomainManagment.Random; + // complier.Add(cscode); + // return complier.GetAssembly(); + //} + + internal static Lazy _compiler = new Lazy(() => + { + var compiler = new CSScriptLib.RoslynEvaluator(); + compiler.DisableReferencingFromCode = false; + compiler + .ReferenceAssemblyOf() + .ReferenceDomainAssemblies(); + return compiler; + }); + public static Assembly CompileCode(string cscode) { - Natasha.AssemblyComplier complier = new Natasha.AssemblyComplier(); - //complier.Domain = DomainManagment.Random; - complier.Add(cscode); - return complier.GetAssembly(); + return _compiler.Value.CompileCode(cscode); } #else From 0effad75e448fa605e324e70033e9bdfe0a08d27 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 15 Mar 2020 18:33:15 +0800 Subject: [PATCH 0478/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.ToTr?= =?UTF-8?q?eeList=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=EF=BC=8C=E5=8A=A0=E5=B7=A5=E4=B8=BA=E6=A0=91?= =?UTF-8?q?=E5=9E=8B=20List=EF=BC=9B(=E6=B3=A8=E6=84=8F=EF=BC=9A=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E9=9C=80=E8=A6=81=E9=85=8D=E7=BD=AE=E7=88=B6=E5=AD=90?= =?UTF-8?q?=E5=AF=BC=E8=88=AA=E5=B1=9E=E6=80=A7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj | 3 +- FreeSql.Tests.VB/UnitTest1.vb | 63 ++++++- .../RepositoryTests.cs | 11 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 56 ++++++ FreeSql/FreeSql.xml | 9 + .../SelectProvider/Select0Provider.cs | 8 +- .../SelectProvider/Select1Provider.cs | 168 ++++++++++-------- 7 files changed, 232 insertions(+), 86 deletions(-) diff --git a/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj b/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj index a8e7b84e..ef69f571 100644 --- a/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj +++ b/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj @@ -1,4 +1,4 @@ - + FreeSql.Tests.VB @@ -15,6 +15,7 @@ + diff --git a/FreeSql.Tests.VB/UnitTest1.vb b/FreeSql.Tests.VB/UnitTest1.vb index 84ab482a..da79ebdf 100644 --- a/FreeSql.Tests.VB/UnitTest1.vb +++ b/FreeSql.Tests.VB/UnitTest1.vb @@ -1,4 +1,5 @@ Imports System +Imports FreeSql.DataAnnotations Imports Xunit Namespace FreeSql.Tests.VB @@ -38,6 +39,17 @@ Namespace FreeSql.Tests.VB Dim List9 = g.sqlserver.Select(Of Testvb).IncludeMany(Function(a) a.Testvb2s).ToList() + BaseEntity.Initialization(g.sqlserver) + Dim cowR As CowRecord = New CowRecord + cowR.Id = 1 + cowR.Lact = 1 + cowR.VetCount = 1 + cowR.Save() + + cowR.VetCount += 1 + cowR.Update() + + End Sub End Class @@ -57,4 +69,53 @@ Class Testvb2 Property TestvbId As Integer Property Testvb As Testvb Property Context As String -End Class \ No newline at end of file +End Class + + +Public Class CowRecord + Inherits BaseEntity(Of CowRecord) + Private _Id As Integer + Private _Lact As Integer + Private _Pen As Integer + Private _BDAT As Date? + Private _FDAT As Date? + Private _DDAT As Date? + Private _EDAT As Date? + Private _ARDAT As Date? + Private _MKDAT As Date? + Private _BFDAT As Date? + Private _USDAT As Date? + Private _RC As Integer + Private _DMLK1 As Integer + Private _VetCount As Integer + + + Public Property Id As Integer + Get + Return _Id + End Get + Set(value As Integer) + _Id = value + End Set + End Property + + + + Public Property Lact As Integer + Get + Return _Lact + End Get + Set(value As Integer) + _Lact = value + End Set + End Property + + Public Property VetCount As Integer + Get + Return _VetCount + End Get + Set(value As Integer) + _VetCount = value + End Set + End Property +End Class diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 7d0a479e..d6dca944 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -1,6 +1,7 @@ using FreeSql.DataAnnotations; using System; using System.Collections.Generic; +using System.Linq; using Xunit; namespace FreeSql.Tests @@ -318,6 +319,7 @@ namespace FreeSql.Tests cts[1].Goodss.Clear(); cts[1].Goodss.Add(new Goods { Name = "Ʒ55" }); repo.Update(cts); + } [Table(Name = "EAUNL_OTM_CT")] class Cagetory @@ -390,6 +392,7 @@ namespace FreeSql.Tests [Fact] public void EnableAddOrUpdateNavigateList_OneToMany_Parent() { + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); var repo = g.sqlite.GetRepository(); var cts = new[] { new CagetoryParent @@ -412,9 +415,12 @@ namespace FreeSql.Tests }) } }; - repo.DbContextOptions.EnableAddOrUpdateNavigateList = false; //رռ湦 + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; //򿪼湦 repo.Insert(cts); - repo.SaveMany(cts[0], "Childs"); //ָ Childs һԶ + + var treelist1 = repo.Select.ToTreeList(); + + //repo.SaveMany(cts[0], "Childs"); //ָ Childs һԶ cts[0].Name = "11"; cts[0].Childs.Clear(); cts[1].Name = "22"; @@ -427,6 +433,7 @@ namespace FreeSql.Tests cts[1].Childs.Clear(); cts[1].Childs.Add(new CagetoryParent { Name = "2_22" }); repo.Update(cts); + var treelist2 = repo.Select.ToTreeList(); } [Table(Name = "EAUNL_OTMP_CT")] class CagetoryParent diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 99debfaf..fa3116cd 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -1,5 +1,6 @@ using FreeSql; using FreeSql.DataAnnotations; +using FreeSql.Internal.CommonProvider; using System; using System.Collections; using System.Collections.Concurrent; @@ -246,6 +247,61 @@ public static partial class FreeSqlGlobalExtensions await select.SetListAsync(list); return list; } +#endif + #endregion + + #region ToTreeList() 父子分类 + /// + /// 查询数据,加工为树型 List 返回 + /// 注意:实体需要配置父子导航属性 + /// + /// + /// + /// + public static List ToTreeList(this ISelect that) where T1 : class + { + var select = that as Select1Provider; + var tb = select._tables[0].Table; + var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) + .Where(a => a != null && + a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && + a.RefEntityType == tb.Type).ToArray(); + + if (navs.Length != 1) return select.ToList(); + var list = select.ToList(); + + select._trackToList = null; + select._includeToList.Clear(); + var navigateSelectorParamExp = select._tables[0].Parameter ?? Expression.Parameter(typeof(T1), select._tables[0].Alias); + var navigateSelector = Expression.Lambda>>(Expression.MakeMemberAccess(navigateSelectorParamExp, navs[0].Property), navigateSelectorParamExp); + select.IncludeMany(navigateSelector); + select._includeManySubListOneToManyTempValue1 = list; + select.SetList(list); + return list.Except(list.SelectMany(a => FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityValueWithPropertyName(select._orm, tb.Type, a, navs[0].Property.Name) as IEnumerable)).ToList(); + } +#if net40 +#else + async public static System.Threading.Tasks.Task> ToTreeListAsync(this ISelect that) where T1 : class + { + var select = that as Select1Provider; + var tb = select._tables[0].Table; + var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) + .Where(a => a != null && + a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && + a.RefEntityType == tb.Type).ToArray(); + + if (navs.Length != 1) return await select.ToListAsync(); + var list = await select.ToListAsync(); + + select._trackToList = null; + select._includeToList.Clear(); + var navigateSelectorParamExp = select._tables[0].Parameter ?? Expression.Parameter(typeof(T1), select._tables[0].Alias); + var navigateSelector = Expression.Lambda>>(Expression.MakeMemberAccess(navigateSelectorParamExp, navs[0].Property), navigateSelectorParamExp); + select.IncludeMany(navigateSelector); + select._includeManySubListOneToManyTempValue1 = list; + select.SetList(list); + return list.Except(list.SelectMany(a => FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityValueWithPropertyName(select._orm, tb.Type, a, navs[0].Property.Name) as IEnumerable)).ToList(); + } #endif #endregion } \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1efa0813..4958b871 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3080,6 +3080,15 @@ 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + 查询数据,加工为树型 List 返回 + 注意:实体需要配置父子导航属性 + + + + + 使用 and 拼接两个 lambda 表达式 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index d0c9807a..5f843cf7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -23,18 +23,18 @@ namespace FreeSql.Internal.CommonProvider protected string _select = "SELECT ", _orderby, _groupby, _having; protected StringBuilder _where = new StringBuilder(); protected List _params = new List(); - protected List _tables = new List(); + internal protected List _tables = new List(); protected List> _tableRules = new List>(); protected Func _aliasRule; protected string _tosqlAppendContent; protected StringBuilder _join = new StringBuilder(); - protected IFreeSql _orm; + internal protected IFreeSql _orm; protected CommonUtils _commonUtils; protected CommonExpression _commonExpression; protected DbTransaction _transaction; protected DbConnection _connection; - protected Action _trackToList; - protected List> _includeToList = new List>(); + internal protected Action _trackToList; + internal protected List> _includeToList = new List>(); #if net40 #else protected List> _includeToListAsync = new List>(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 2d3b877f..2629c519 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -659,6 +659,93 @@ namespace FreeSql.Internal.CommonProvider foreach (var item in list) setListValue(item, null); + Action, TableInfo> fillOneToManyData = (subList, tbref2) => + { + if (subList.Any() == false) + { + foreach (var item in list) + setListValue(item, new List()); + return; + } + + Dictionary>>> dicList = new Dictionary>>>(); + foreach (var item in list) + { + if (tbref.Columns.Count == 1) + { + var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0)?.ToString(); + if (dicListKey == null) continue; + var dicListVal = Tuple.Create(item, new List()); + if (dicList.TryGetValue(dicListKey, out var items) == false) + dicList.Add(dicListKey, items = new List>>()); + items.Add(dicListVal); + } + else + { + var sb = new StringBuilder(); + for (var z = 0; z < tbref.Columns.Count; z++) + { + if (z > 0) sb.Append("*$*"); + sb.Append(getListValue(item, tbref.Columns[z].CsName, z)); + } + var dicListKey = sb.ToString(); + var dicListVal = Tuple.Create(item, new List()); + if (dicList.TryGetValue(dicListKey, out var items) == false) + dicList.Add(dicListKey, items = new List>>()); + items.Add(dicListVal); + sb.Clear(); + } + } + var parentNavs = new List(); + foreach (var navProp in tbref2.Properties) + { + if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue; + if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue; + var tr2ref = tbref2.GetTableRef(navProp.Key, false); + if (tr2ref == null) continue; + if (tr2ref.RefType != TableRefType.ManyToOne) continue; + if (tr2ref.RefEntityType != tb.Type) continue; + parentNavs.Add(navProp.Key); + } + foreach (var nav in subList) + { + string key = null; + if (tbref.RefColumns.Count == 1) + { + key = _orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[0].CsName).ToString(); + } + else + { + var sb = new StringBuilder(); + for (var z = 0; z < tbref.RefColumns.Count; z++) + { + if (z > 0) sb.Append("*$*"); + sb.Append(_orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[z].CsName)); + } + key = sb.ToString(); + sb.Clear(); + } + if (dicList.TryGetValue(key, out var t1items) == false) continue; + foreach (var t1item in t1items) + t1item.Item2.Add(nav); + + //将子集合的,多对一,对象设置为当前对象 + foreach (var parentNav in parentNavs) + foreach (var t1item in t1items) + _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1); + } + foreach (var t1items in dicList.Values) + foreach (var t1item in t1items) + setListValue(t1item.Item1, t1item.Item2); + dicList.Clear(); + }; + + if (tbref.RefType == TableRefType.OneToMany && _includeManySubListOneToManyTempValue1 != null && _includeManySubListOneToManyTempValue1 is List) + { + fillOneToManyData(_includeManySubListOneToManyTempValue1 as List, _commonUtils.GetTableByEntity(tbref.RefEntityType)); + return; + } + var subSelect = _orm.Select() .DisableGlobalFilter() .WithConnection(_connection) @@ -794,83 +881,7 @@ namespace FreeSql.Internal.CommonProvider } } - if (subList.Any() == false) - { - foreach (var item in list) - setListValue(item, new List()); - return; - } - - Dictionary>>> dicList = new Dictionary>>>(); - foreach (var item in list) - { - if (tbref.Columns.Count == 1) - { - var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0)?.ToString(); - if (dicListKey == null) continue; - var dicListVal = Tuple.Create(item, new List()); - if (dicList.TryGetValue(dicListKey, out var items) == false) - dicList.Add(dicListKey, items = new List>>()); - items.Add(dicListVal); - } - else - { - var sb = new StringBuilder(); - for (var z = 0; z < tbref.Columns.Count; z++) - { - if (z > 0) sb.Append("*$*"); - sb.Append(getListValue(item, tbref.Columns[z].CsName, z)); - } - var dicListKey = sb.ToString(); - var dicListVal = Tuple.Create(item, new List()); - if (dicList.TryGetValue(dicListKey, out var items) == false) - dicList.Add(dicListKey, items = new List>>()); - items.Add(dicListVal); - sb.Clear(); - } - } - var parentNavs = new List(); - foreach (var navProp in tbref2.Properties) - { - if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue; - if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue; - var tr2ref = tbref2.GetTableRef(navProp.Key, false); - if (tr2ref == null) continue; - if (tr2ref.RefType != TableRefType.ManyToOne) continue; - if (tr2ref.RefEntityType != tb.Type) continue; - parentNavs.Add(navProp.Key); - } - foreach (var nav in subList) - { - string key = null; - if (tbref.RefColumns.Count == 1) - { - key = _orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[0].CsName).ToString(); - } - else - { - var sb = new StringBuilder(); - for (var z = 0; z < tbref.RefColumns.Count; z++) - { - if (z > 0) sb.Append("*$*"); - sb.Append(_orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[z].CsName)); - } - key = sb.ToString(); - sb.Clear(); - } - if (dicList.TryGetValue(key, out var t1items) == false) return; - foreach (var t1item in t1items) - t1item.Item2.Add(nav); - - //将子集合的,多对一,对象设置为当前对象 - foreach (var parentNav in parentNavs) - foreach (var t1item in t1items) - _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1); - } - foreach (var t1items in dicList.Values) - foreach (var t1item in t1items) - setListValue(t1item.Item1, t1item.Item2); - dicList.Clear(); + fillOneToManyData(subList, tbref2); } break; case TableRefType.ManyToMany: @@ -1044,7 +1055,7 @@ namespace FreeSql.Internal.CommonProvider key = sb.ToString(); sb.Clear(); } - if (dicList.TryGetValue(key, out var t1items) == false) return; + if (dicList.TryGetValue(key, out var t1items) == false) continue; foreach (var t1item in t1items) t1item.Item2.Add(subList[a]); } @@ -1065,6 +1076,7 @@ namespace FreeSql.Internal.CommonProvider return this; } + internal object _includeManySubListOneToManyTempValue1 = null; internal void SetList(IEnumerable list) { foreach (var include in _includeToList) include?.Invoke(list); From ec4b934f239dfc79e71e45e3ea919c5462a909c4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 16 Mar 2020 12:17:53 +0800 Subject: [PATCH 0479/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20TableInfo=20?= =?UTF-8?q?=E5=85=83=E6=95=B0=E6=8D=AE=E5=AF=B9=20interface=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=B1=BB=20IsVirtual=20=E9=87=8D=E5=86=99=E7=9A=84?= =?UTF-8?q?=E5=88=A4=E6=96=AD=EF=BC=88=E5=A2=9E=E5=8A=A0=20IsFinal=20=3D?= =?UTF-8?q?=3D=20false=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 11 ++++++++++- FreeSql/Internal/UtilsExpressionTree.cs | 7 ++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index b31fe4d3..a23922cb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -116,10 +116,17 @@ namespace FreeSql.Tests public string Name { get; set; } } + public interface EdiInterface + { + List Children { get; set; } + } + [Table(Name = "EDI")] - public class Edi + public class Edi : EdiInterface { [Column(Name = "EDI_ID")] public long Id { get; set; } + + public List Children { get; set; } } [Table(Name = "EDI_ITEM")] public class EdiItem @@ -131,6 +138,8 @@ namespace FreeSql.Tests [Fact] public void Test03() { + g.sqlite.Select().ToList(); + var itemId2 = 2; var itemId = 1; var edi = g.sqlite.Select() diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 2823edcd..1a65014b 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -84,10 +84,11 @@ namespace FreeSql.Internal { if (common.CodeFirst.IsLazyLoading) { - var getIsVirtual = p.GetGetMethod()?.IsVirtual;// trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; - var setIsVirtual = setMethod?.IsVirtual; + var getMethod = p.GetGetMethod(); + var getIsVirtual = getMethod?.IsVirtual == true && getMethod?.IsFinal == false;// trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; + var setIsVirtual = setMethod?.IsVirtual == true && setMethod?.IsFinal == false; if (getIsVirtual == true || setIsVirtual == true) - propsLazy.Add(NaviteTuple.Create(p, getIsVirtual == true, setIsVirtual == true)); + propsLazy.Add(NaviteTuple.Create(p, getIsVirtual, setIsVirtual)); } propsNavObjs.Add(p); continue; From 2d722cb469dddd41df315f6629f8cb0f7b52f356 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 16 Mar 2020 18:43:42 +0800 Subject: [PATCH 0480/1029] update internal Method --- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index fa3116cd..9ea49e7f 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -55,7 +55,7 @@ public static partial class FreeSqlGlobalExtensions if (that.IsArray) return Array.CreateInstance(that, 0); var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters(); if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, null); - return Activator.CreateInstance(that, ctorParms.Select(a => Activator.CreateInstance(a.ParameterType, null)).ToArray()); + return Activator.CreateInstance(that, ctorParms.Select(a => a.ParameterType.IsInterface || a.ParameterType.IsAbstract ? null : Activator.CreateInstance(a.ParameterType, null)).ToArray()); } internal static NewExpression InternalNewExpression(this Type that) { From 5f166c08aa4cacdfed94bb2130fe0349040fe857 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Mar 2020 11:49:47 +0800 Subject: [PATCH 0481/1029] 1.3.0-preview9 #237 #227 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 80 +++++++++++-------- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 63 insertions(+), 51 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 90675532..cc57f0b2 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 3c8de4dc..ead1bcd9 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 33cadcf0..7af77366 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index cefbb7c0..afd036e1 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 86b1305b..3b290689 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview8 + 1.3.0-preview9 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 9cdb89cf..d2503779 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4457bbdc..aa9fa580 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3249ab8a..fa6fd393 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cb645873..fdd2727d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4958b871..60d38476 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2961,40 +2961,6 @@ - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - - C#:从元组集合中查找 exp1, exp2, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - 测量两个经纬度的距离,返回单位:米 @@ -3268,3 +3234,49 @@ +完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 13252cc3..8f6521e6 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 9171e2c3..bae07b50 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 57541563..3c839d51 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 424b8cdd..cddfecbe 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7c16b739..20215b30 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 02ff0fd7..3a8ec689 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 6028493d..03b731c0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index d0ab3907..a8a062d5 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview8 + 1.3.0-preview9 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From a5e657385185db37752923fc0f9aca901fd2ec18 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 19 Mar 2020 22:46:40 +0800 Subject: [PATCH 0482/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Pgsql=20JTok?= =?UTF-8?q?en/JObject/JArray=20=E7=B4=A2=E5=BC=95=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=E7=9A=84=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=EF=BC=9B?= =?UTF-8?q?=20-=20=E5=A2=9E=E5=8A=A0=20object.Equals=20=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E8=A7=A3=E6=9E=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 9 +++ FreeSql/FreeSql.xml | 80 ++++++++----------- FreeSql/Internal/CommonExpression.cs | 7 +- .../PostgreSQLExpression.cs | 1 + 5 files changed, 50 insertions(+), 49 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index 5db7074a..75cd98d8 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -369,7 +369,7 @@ namespace FreeSql.Tests.PostgreSQL var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); var item3 = insert.AppendData(item2).ExecuteInserted().First(); - var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + var newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 8ebffb14..e55dc1a2 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -963,6 +963,15 @@ WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] a.Id, a.Clicks }); + + var testUnionAll = select + .WithSql("SELECT * FROM [tb_topic22] where id = 10") + .WithSql("SELECT * FROM [tb_topic22] where id = 11") + .ToSql(a => new + { + a.Id, + a.Clicks + }); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 60d38476..4958b871 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2961,6 +2961,40 @@ + + + C#:从元组集合中查找 exp1, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + + C#:从元组集合中查找 exp1, exp2, exp2 是否存在 + SQL: + exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR + exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR + ... + 注意:当 that 为 null 或 empty 时,返回 1=0 + + + + + + + + + + 测量两个经纬度的距离,返回单位:米 @@ -3234,49 +3268,3 @@ -完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 64bed1e7..d7f48fdf 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -675,8 +675,11 @@ namespace FreeSql.Internal case "System.Convert": other3Exp = ExpressionLambdaToSqlCallConvert(exp3, tsc); break; } if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; - if (exp3.Method.Name == "Equals" && exp3.Object != null && exp3.Arguments.Count > 0) - return ExpressionBinary("=", exp3.Object, exp3.Arguments[0], tsc); + if (exp3.Method.Name == "Equals") + { + if (exp3.Arguments.Count > 0 && exp3.Object != null) return ExpressionBinary("=", exp3.Object, exp3.Arguments[0], tsc); + if (exp3.Arguments.Count > 1 && exp3.Method.DeclaringType == typeof(object)) return ExpressionBinary("=", exp3.Arguments[0], exp3.Arguments[1], tsc); + } if (callType.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { //if (exp3.Type == typeof(string) && exp3.Arguments.Any() && exp3.Arguments[0].NodeType == ExpressionType.Constant) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 797955ca..bcea0fdc 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -115,6 +115,7 @@ namespace FreeSql.PostgreSQL left = objExp == null ? null : getExp(objExp); switch (callExp.Method.Name) { + case "get_Item": return $"{left}->{getExp(callExp.Arguments[argIndex])}"; case "Any": return $"(jsonb_array_length(coalesce({left},'[]')) > 0)"; case "Contains": var json = getExp(callExp.Arguments[argIndex]); From 22a2450e051e809af369ec4a7288c4164bf44c61 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Mar 2020 01:52:43 +0800 Subject: [PATCH 0483/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect`1=20?= =?UTF-8?q?ToDictionary=20=E6=96=B9=E6=B3=95=E6=9F=A5=E8=AF=A2=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E5=AD=97=E5=85=B8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSet.cs | 2 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 12 ++++ .../Dameng/Curd/DamengSelectTest.cs | 12 ++++ .../Default/Curd/OdbcSelectTest.cs | 12 ++++ .../MySql/Curd/MySqlSelectTest.cs | 12 ++++ .../Oracle/Curd/OracleSelectTest.cs | 12 ++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 12 ++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 12 ++++ .../MsAccess/Curd/MsAccessSelectTest.cs | 14 ++++ .../MySql/Curd/MySqlSelectTest.cs | 12 ++++ .../Oracle/Curd/OracleSelectTest.cs | 12 ++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 12 ++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 12 ++++ .../Sqlite/Curd/SqliteSelectTest.cs | 12 ++++ FreeSql/FreeSql.xml | 9 +++ FreeSql/Interface/Curd/ISelect/ISelect0.cs | 11 +++ .../SelectProvider/Select0Provider.cs | 67 +++++++++++++++++++ 17 files changed, 246 insertions(+), 1 deletion(-) diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index a25d4317..4dbe2715 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -68,7 +68,7 @@ namespace FreeSql internal void TrackToList(object list) { if (list == null) return; - var ls = list as IList; + var ls = list as IEnumerable; if (ls == null) { var ie = list as IEnumerable; diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index fc638846..4fc799af 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -251,6 +251,18 @@ namespace FreeSql.Tests.MySqlConnector var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.mysql.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 79cd586c..314961b2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -192,6 +192,18 @@ namespace FreeSql.Tests.Odbc.Dameng var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.dameng.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 8db28289..edb5cb2d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -183,6 +183,18 @@ namespace FreeSql.Tests.Odbc.Default var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.odbc.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 79e3e6ad..945f877d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -292,6 +292,18 @@ namespace FreeSql.Tests.Odbc.MySql var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.mysql.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index ec0fb836..3a8b0135 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -192,6 +192,18 @@ namespace FreeSql.Tests.Odbc.Oracle var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.oracle.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 545c0fa6..bb1db718 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -268,6 +268,18 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.pgsql.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 7b9f97af..3ac1ed9b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -182,6 +182,18 @@ namespace FreeSql.Tests.Odbc.SqlServer var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.sqlserver.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index 243d9eb0..bd238e73 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -183,6 +183,20 @@ namespace FreeSql.Tests.MsAccess var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a=> new { a.Id, a.Title }); + var testDto11 = select.Limit(10).ToDictionaryAsync(a => a.Id).Result; + var testDto22 = select.Limit(10).ToDictionaryAsync(a => a.Id, a => new { a.Id, a.Title }).Result; + + var repo = g.msaccess.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 818e4196..4a419368 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -292,6 +292,18 @@ namespace FreeSql.Tests.MySql var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.mysql.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 942fb81f..011b3de7 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -192,6 +192,18 @@ namespace FreeSql.Tests.Oracle var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.oracle.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 75ffdfa5..346ab34a 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -268,6 +268,18 @@ namespace FreeSql.Tests.PostgreSQL var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.pgsql.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index e55dc1a2..943de287 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -192,6 +192,18 @@ namespace FreeSql.Tests.SqlServer var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.sqlserver.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 5d138880..d7bb93e1 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -209,6 +209,18 @@ namespace FreeSql.Tests.Sqlite var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.sqlite.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } class TestGuidIdToList { public Guid id { get; set; } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4958b871..96d40ff9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1033,6 +1033,15 @@ + + + 以字典的形式返回查询结果 + 注意:字典的特点会导致 OrderBy 排序失效 + + + + + 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index b42fc3c1..a9a98620 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -14,6 +14,8 @@ namespace FreeSql #if net40 #else Task ToDataTableAsync(string field = null); + Task> ToDictionaryAsync(Func keySelector); + Task> ToDictionaryAsync(Func keySelector, Func valueSelector); Task> ToListAsync(bool includeNestedMembers = false); Task> ToListAsync(string field); @@ -50,6 +52,15 @@ namespace FreeSql /// DataTable ToDataTable(string field = null); + /// + /// 以字典的形式返回查询结果 + /// 注意:字典的特点会导致 OrderBy 排序失效 + /// + /// + /// + /// + Dictionary ToDictionary(Func keySelector); + Dictionary ToDictionary(Func keySelector, Func valueSelector); /// /// 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 /// 注意: diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 5f843cf7..5f3a6a88 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -479,6 +479,39 @@ namespace FreeSql.Internal.CommonProvider this.ToListChunkPrivate(size, done, includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); } #endregion + public Dictionary ToDictionary(Func keySelector) => ToDictionary(keySelector, a => a); + public Dictionary ToDictionary(Func keySelector, Func valueSelector) + { + if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); + if (valueSelector == null) throw new ArgumentNullException(nameof(valueSelector)); + var af = this.GetAllFieldExpressionTreeLevel2(); + var sql = this.ToSql(af.Field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new Dictionary(); + Exception exception = null; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, dr => + { + var item = af.Read(_orm, dr); + ret.Add(keySelector(item), valueSelector(item)); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + if (typeof(TValue) == typeof(T1)) _trackToList?.Invoke(ret.Values); + return ret; + } public virtual List ToList(bool includeNestedMembers = false) { if (_selectExpression != null) return this.InternalToList(_selectExpression); @@ -1251,6 +1284,40 @@ namespace FreeSql.Internal.CommonProvider return ToListAfPrivateAsync(sql, af, otherData); } + public Task> ToDictionaryAsync(Func keySelector) => ToDictionaryAsync(keySelector, a => a); + async public Task> ToDictionaryAsync(Func keySelector, Func valueSelector) + { + if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); + if (valueSelector == null) throw new ArgumentNullException(nameof(valueSelector)); + var af = this.GetAllFieldExpressionTreeLevel2(); + var sql = this.ToSql(af.Field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new Dictionary(); + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + { + var item = af.Read(_orm, dr); + ret.Add(keySelector(item), valueSelector(item)); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + if (typeof(TValue) == typeof(T1)) _trackToList?.Invoke(ret.Values); + return ret; + } public virtual Task> ToListAsync(bool includeNestedMembers = false) { if (_selectExpression != null) return this.InternalToListAsync(_selectExpression); From a7b09bf0af8ec4cf9b1a2a4bc3f37bd605469431 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Mar 2020 01:54:18 +0800 Subject: [PATCH 0484/1029] v1.3.0-preview10 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index cc57f0b2..2266f5c3 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index ead1bcd9..3215a4aa 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 7af77366..92aaeb4b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index afd036e1..9b7689d9 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 3b290689..c5ff4f27 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview9 + 1.3.0-preview10 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index d2503779..f3ae8779 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index aa9fa580..310a95d2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index fa6fd393..35f13e7e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fdd2727d..51229c77 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 8f6521e6..7f4dcf57 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index bae07b50..a5982827 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 3c839d51..8e67ab5e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index cddfecbe..1c4ad512 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 20215b30..fee6489a 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 3a8ec689..b1f1f6c6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 03b731c0..5ec10980 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a8a062d5..7a76e8f2 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview9 + 1.3.0-preview10 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 25312ceeadbaa794850c18a40b5b2782206b8033 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Mar 2020 02:14:29 +0800 Subject: [PATCH 0485/1029] v1.3.0-preview10 tests --- .../Dameng/Curd/DamengSelectTest.cs | 6 +----- .../Oracle/Curd/OracleSelectTest.cs | 6 +----- .../FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs | 1 + FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs | 1 + .../FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs | 1 + 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 314961b2..0c314b52 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -195,6 +195,7 @@ namespace FreeSql.Tests.Odbc.Dameng [Fact] public void ToDictionary() { + g.dameng.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); var testDto1 = select.Limit(10).ToDictionary(a => a.Id); var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); @@ -717,7 +718,6 @@ namespace FreeSql.Tests.Odbc.Dameng { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -729,7 +729,6 @@ namespace FreeSql.Tests.Odbc.Dameng b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist2 = select @@ -738,9 +737,7 @@ namespace FreeSql.Tests.Odbc.Dameng { b.Key.Title, b.Key.yyyy, - cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -750,7 +747,6 @@ namespace FreeSql.Tests.Odbc.Dameng { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid), sum3 = b.Sum(b.Value.Type.Parent.Id) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 3a8b0135..065806e6 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -195,6 +195,7 @@ namespace FreeSql.Tests.Odbc.Oracle [Fact] public void ToDictionary() { + g.oracle.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); var testDto1 = select.Limit(10).ToDictionary(a => a.Id); var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); @@ -708,7 +709,6 @@ namespace FreeSql.Tests.Odbc.Oracle { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist1 = select @@ -717,7 +717,6 @@ namespace FreeSql.Tests.Odbc.Oracle { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -729,7 +728,6 @@ namespace FreeSql.Tests.Odbc.Oracle b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist2 = select @@ -740,7 +738,6 @@ namespace FreeSql.Tests.Odbc.Oracle b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -750,7 +747,6 @@ namespace FreeSql.Tests.Odbc.Oracle { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid), sum3 = b.Sum(b.Value.Type.Parent.Id) }); diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index bd238e73..71636cca 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -186,6 +186,7 @@ namespace FreeSql.Tests.MsAccess [Fact] public void ToDictionary() { + g.msaccess.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); var testDto1 = select.Limit(10).ToDictionary(a => a.Id); var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a=> new { a.Id, a.Title }); var testDto11 = select.Limit(10).ToDictionaryAsync(a => a.Id).Result; diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 011b3de7..3dc2c5d3 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -195,6 +195,7 @@ namespace FreeSql.Tests.Oracle [Fact] public void ToDictionary() { + g.oracle.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); var testDto1 = select.Limit(10).ToDictionary(a => a.Id); var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 943de287..d8c8a698 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -195,6 +195,7 @@ namespace FreeSql.Tests.SqlServer [Fact] public void ToDictionary() { + g.sqlserver.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); var testDto1 = select.Limit(10).ToDictionary(a => a.Id); var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); From 72781596bdaf16ee5a5fd74f0af1c31c2a0b3117 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Mar 2020 20:32:49 +0800 Subject: [PATCH 0486/1029] =?UTF-8?q?-=20=E7=A7=BB=E9=99=A4=20In=E5=A4=9A?= =?UTF-8?q?=E8=A1=A8=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=87=BD=E6=95=B0=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=20#243=EF=BC=9B=20-=20=E8=B0=83=E6=95=B4=20SafeObject?= =?UTF-8?q?Pool=20=E6=BA=90=E7=A0=81=E7=A7=BB=E5=85=A5=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/dbcontext_01/Program.cs | 2 +- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 2 +- .../Extensions/FreeSqlGlobalExpressionCall.cs | 92 +-- FreeSql/FreeSql.csproj | 9 +- FreeSql/FreeSql.xml | 253 ++++++-- FreeSql/FreeUtil.cs | 2 +- FreeSql/Interface/IAdo.cs | 2 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 2 +- .../AdoProvider/AdoProviderAsync.cs | 2 +- .../AdoProvider/AdoProviderTransaction.cs | 2 +- .../AdoProvider/DbConnectionPool.cs | 2 +- .../Internal/CommonProvider/InsertProvider.cs | 2 +- .../CommonProvider/InsertProviderAsync.cs | 2 +- FreeSql/Internal/CommonUtils.cs | 2 +- FreeSql/Internal/ObjectPool/DefaultPolicy.cs | 74 +++ FreeSql/Internal/ObjectPool/IObjectPool.cs | 63 ++ FreeSql/Internal/ObjectPool/IPolicy.cs | 99 ++++ FreeSql/Internal/ObjectPool/Object.cs | 93 +++ FreeSql/Internal/ObjectPool/ObjectPool.cs | 547 ++++++++++++++++++ .../Curd/MsAccessInsert.cs | 2 +- .../MsAccessAdo/MsAccessAdo.cs | 2 +- .../MsAccessAdo/MsAccessConnectionPool.cs | 2 +- .../MySqlAdo/MySqlAdo.cs | 2 +- .../MySqlAdo/MySqlConnectionPool.cs | 2 +- .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 2 +- .../OdbcDamengAdo/OdbcDamengConnectionPool.cs | 2 +- .../Default/Curd/OdbcInsert.cs | 2 +- .../Default/OdbcAdo/OdbcAdo.cs | 2 +- .../Default/OdbcAdo/OdbcConnectionPool.cs | 2 +- .../MySql/Curd/OdbcMySqlInsert.cs | 2 +- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 2 +- .../OdbcMySqlAdo/OdbcMySqlConnectionPool.cs | 2 +- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 2 +- .../OdbcOracleAdo/OdbcOracleConnectionPool.cs | 2 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 2 +- .../OdbcPostgreSQLConnectionPool.cs | 2 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 2 +- .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 2 +- .../OdbcSqlServerConnectionPool.cs | 2 +- .../OracleAdo/OracleAdo.cs | 2 +- .../OracleAdo/OracleConnectionPool.cs | 2 +- .../PostgreSQLAdo/PostgreSQLAdo.cs | 2 +- .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 2 +- .../PostgreSQLDbFirst.cs | 2 +- .../Curd/SqlServerInsert.cs | 2 +- .../SqlServerAdo/SqlServerAdo.cs | 2 +- .../SqlServerAdo/SqlServerConnectionPool.cs | 2 +- .../SqliteAdo/SqliteAdo.cs | 2 +- .../SqliteAdo/SqliteConnectionPool.cs | 2 +- 49 files changed, 1138 insertions(+), 174 deletions(-) create mode 100644 FreeSql/Internal/ObjectPool/DefaultPolicy.cs create mode 100644 FreeSql/Internal/ObjectPool/IObjectPool.cs create mode 100644 FreeSql/Internal/ObjectPool/IPolicy.cs create mode 100644 FreeSql/Internal/ObjectPool/Object.cs create mode 100644 FreeSql/Internal/ObjectPool/ObjectPool.cs diff --git a/Examples/dbcontext_01/Program.cs b/Examples/dbcontext_01/Program.cs index 0aa6a2a1..6f7b9727 100644 --- a/Examples/dbcontext_01/Program.cs +++ b/Examples/dbcontext_01/Program.cs @@ -40,7 +40,7 @@ namespace dbcontext_01 static IFreeSql fsql; public static void Main(string[] args) { - var asse = typeof(SafeObjectPool.ObjectPool<>).Assembly; + var asse = typeof(FreeSql.Internal.ObjectPool.ObjectPool<>).Assembly; fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index a05b8ba6..4e0aa3de 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Collections.Concurrent; diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs index 2ad04f7d..67faf87a 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs @@ -1,16 +1,5 @@ -using FreeSql; -using FreeSql.DataAnnotations; +using FreeSql.DataAnnotations; using System; -using System.Collections; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Text; using System.Threading; [ExpressionCall] @@ -50,83 +39,4 @@ public static class FreeSqlGlobalExpressionCall expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} >= {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["that"]} < {expContext.Value.ParsedContent["end"]}"; return false; } - -#if netcoreapp - /// - /// C#:从元组集合中查找 exp1, exp2 是否存在 - /// SQL: - /// exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - /// exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - /// ... - /// 注意:当 that 为 null 或 empty 时,返回 1=0 - /// - /// - /// - /// - /// - /// - /// - public static bool Contains([RawValue] this IEnumerable<(T1, T2)> that, T1 exp1, T2 exp2) - { - if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) - return that?.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2)) == true; - if (that?.Any() != true) - { - expContext.Value.Result = "1=0"; - return false; - } - var sb = new StringBuilder(); - var idx = 0; - foreach (var item in that) - { - if (idx++ > 0) sb.Append(" OR \r\n"); - sb - .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))); - } - expContext.Value.Result = sb.ToString(); - return true; - } - /// - /// C#:从元组集合中查找 exp1, exp2, exp2 是否存在 - /// SQL: - /// exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - /// exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - /// ... - /// 注意:当 that 为 null 或 empty 时,返回 1=0 - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static bool Contains([RawValue] this IEnumerable<(T1, T2, T3)> that, T1 exp1, T2 exp2, T3 exp3) - { - if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) - return that.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2) && a.Item3.Equals(exp3)); - if (that.Any() == false) - { - expContext.Value.Result = "1=0"; - return false; - } - var sb = new StringBuilder(); - var idx = 0; - foreach (var item in that) - { - if (idx++ > 0) sb.Append(" OR \r\n"); - sb - .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp3"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T3), item.Item3))); - } - expContext.Value.Result = sb.ToString(); - return true; - } -#endif } \ No newline at end of file diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 51229c77..c8887594 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -1,7 +1,7 @@  - netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 + netstandard2.0;net45;net40 1.3.0-preview10 true YeXiangQin @@ -30,13 +30,6 @@ 3 - - - - - - netcoreapp - net40 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 96d40ff9..cbd67953 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2900,6 +2900,225 @@ 中间表,多对多 + + + 是否可用 + + + + + 不可用错误 + + + + + 不可用时间 + + + + + 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + + + 由【可用】变成【不可用】时返回true,否则返回false + + + + 统计对象池中的对象 + + + + + 统计对象池中的对象(完整) + + + + + 获取资源 + + 超时 + + + + + 获取资源 + + + + + + 使用完毕后,归还资源 + + 对象 + 是否重新创建 + + + + 名称 + + + + + 池容量 + + + + + 默认获取超时设置 + + + + + 空闲时间,获取时若超出,则重新创建 + + + + + 异步获取排队队列大小,小于等于0不生效 + + + + + 获取超时后,是否抛出异常 + + + + + 后台定时检查可用性间隔秒数 + + + + + 对象池的对象被创建时 + + 返回被创建的对象 + + + + 销毁对象 + + 资源对象 + + + + 从对象池获取对象超时的时候触发,通过该方法统计 + + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + + + + 归还对象给对象池的时候触发 + + 资源对象 + + + + 检查可用性 + + 资源对象 + + + + + 事件:可用时触发 + + + + + 事件:不可用时触发 + + + + + 所属对象池 + + + + + 在对象池中的唯一标识 + + + + + 资源对象 + + + + + 被获取的总次数 + + + + 最后获取时的时间 + + + + 最后归还时的时间 + + + + + 创建时间 + + + + + 最后获取时的线程id + + + + + 最后归还时的线程id + + + + + 重置 Value 值 + + + + + 对象池管理类 + + 对象类型 + + + + 后台定时检查可用性 + + + + + + 创建对象池 + + 池大小 + 池内对象的创建委托 + 获取池内对象成功后,进行使用前操作 + + + + 创建对象池 + + 策略 + + + + 获取可用资源,或创建资源 + + + 不进行任何处理 @@ -2970,40 +3189,6 @@ - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - - C#:从元组集合中查找 exp1, exp2, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - 测量两个经纬度的距离,返回单位:米 diff --git a/FreeSql/FreeUtil.cs b/FreeSql/FreeUtil.cs index 145b8243..37e928c9 100644 --- a/FreeSql/FreeUtil.cs +++ b/FreeSql/FreeUtil.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Data.Common; diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 3d93860d..d5ec0a8c 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -1,6 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 2f2facd5..07d785ca 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Collections.Concurrent; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index bc8b96b6..356222af 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -1,5 +1,5 @@ using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 60133ed4..cd7356a5 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs index d3be116e..e667b19f 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 3a15daab..d673a2af 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -1,6 +1,6 @@ using FreeSql.Internal.Model; using FreeSql.Extensions.EntityUtil; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index 0f6d77d1..ddd24bf9 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -1,5 +1,5 @@ using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index cbab8e0a..14a5e3a6 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -2,7 +2,7 @@ using FreeSql.DatabaseModel; using FreeSql.Extensions.EntityUtil; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Concurrent; diff --git a/FreeSql/Internal/ObjectPool/DefaultPolicy.cs b/FreeSql/Internal/ObjectPool/DefaultPolicy.cs new file mode 100644 index 00000000..5541c579 --- /dev/null +++ b/FreeSql/Internal/ObjectPool/DefaultPolicy.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.ObjectPool +{ + + public class DefaultPolicy : IPolicy + { + + public string Name { get; set; } = typeof(DefaultPolicy).GetType().FullName; + public int PoolSize { get; set; } = 1000; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(50); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + public Func CreateObject; + public Action> OnGetObject; + + public T OnCreate() + { + return CreateObject(); + } + + public void OnDestroy(T obj) + { + + } + + public void OnGet(Object obj) + { + //Console.WriteLine("Get: " + obj); + OnGetObject?.Invoke(obj); + } + +#if net40 +#else + public Task OnGetAsync(Object obj) + { + //Console.WriteLine("GetAsync: " + obj); + OnGetObject?.Invoke(obj); + return Task.FromResult(true); + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + //Console.WriteLine("Return: " + obj); + } + + public bool OnCheckAvailable(Object obj) + { + return true; + } + + public void OnAvailable() + { + + } + + public void OnUnavailable() + { + + } + } +} \ No newline at end of file diff --git a/FreeSql/Internal/ObjectPool/IObjectPool.cs b/FreeSql/Internal/ObjectPool/IObjectPool.cs new file mode 100644 index 00000000..45644edb --- /dev/null +++ b/FreeSql/Internal/ObjectPool/IObjectPool.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.ObjectPool +{ + public interface IObjectPool : IDisposable + { + IPolicy Policy { get; } + /// + /// 是否可用 + /// + bool IsAvailable { get; } + /// + /// 不可用错误 + /// + Exception UnavailableException { get; } + /// + /// 不可用时间 + /// + DateTime? UnavailableTime { get; } + + /// + /// 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + /// + /// + /// 由【可用】变成【不可用】时返回true,否则返回false + bool SetUnavailable(Exception exception); + + /// + /// 统计对象池中的对象 + /// + string Statistics { get; } + /// + /// 统计对象池中的对象(完整) + /// + string StatisticsFullily { get; } + + /// + /// 获取资源 + /// + /// 超时 + /// + Object Get(TimeSpan? timeout = null); + +#if net40 +#else + /// + /// 获取资源 + /// + /// + Task> GetAsync(); +#endif + + /// + /// 使用完毕后,归还资源 + /// + /// 对象 + /// 是否重新创建 + void Return(Object obj, bool isReset = false); + } +} diff --git a/FreeSql/Internal/ObjectPool/IPolicy.cs b/FreeSql/Internal/ObjectPool/IPolicy.cs new file mode 100644 index 00000000..63918587 --- /dev/null +++ b/FreeSql/Internal/ObjectPool/IPolicy.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.ObjectPool +{ + public interface IPolicy + { + + /// + /// 名称 + /// + string Name { get; set; } + + /// + /// 池容量 + /// + int PoolSize { get; set; } + + /// + /// 默认获取超时设置 + /// + TimeSpan SyncGetTimeout { get; set; } + + /// + /// 空闲时间,获取时若超出,则重新创建 + /// + TimeSpan IdleTimeout { get; set; } + + /// + /// 异步获取排队队列大小,小于等于0不生效 + /// + int AsyncGetCapacity { get; set; } + + /// + /// 获取超时后,是否抛出异常 + /// + bool IsThrowGetTimeoutException { get; set; } + + /// + /// 后台定时检查可用性间隔秒数 + /// + int CheckAvailableInterval { get; set; } + + /// + /// 对象池的对象被创建时 + /// + /// 返回被创建的对象 + T OnCreate(); + + /// + /// 销毁对象 + /// + /// 资源对象 + void OnDestroy(T obj); + + /// + /// 从对象池获取对象超时的时候触发,通过该方法统计 + /// + void OnGetTimeout(); + + /// + /// 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + /// + /// 资源对象 + void OnGet(Object obj); +#if net40 +#else + /// + /// 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + /// + /// 资源对象 + Task OnGetAsync(Object obj); +#endif + + /// + /// 归还对象给对象池的时候触发 + /// + /// 资源对象 + void OnReturn(Object obj); + + /// + /// 检查可用性 + /// + /// 资源对象 + /// + bool OnCheckAvailable(Object obj); + + /// + /// 事件:可用时触发 + /// + void OnAvailable(); + /// + /// 事件:不可用时触发 + /// + void OnUnavailable(); + } +} \ No newline at end of file diff --git a/FreeSql/Internal/ObjectPool/Object.cs b/FreeSql/Internal/ObjectPool/Object.cs new file mode 100644 index 00000000..cb76a49e --- /dev/null +++ b/FreeSql/Internal/ObjectPool/Object.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace FreeSql.Internal.ObjectPool +{ + + public class Object : IDisposable + { + public static Object InitWith(IObjectPool pool, int id, T value) + { + return new Object + { + Pool = pool, + Id = id, + Value = value, + LastGetThreadId = Thread.CurrentThread.ManagedThreadId, + LastGetTime = DateTime.Now + }; + } + + /// + /// 所属对象池 + /// + public IObjectPool Pool { get; internal set; } + + /// + /// 在对象池中的唯一标识 + /// + public int Id { get; internal set; } + /// + /// 资源对象 + /// + public T Value { get; internal set; } + + internal long _getTimes; + /// + /// 被获取的总次数 + /// + public long GetTimes => _getTimes; + + /// 最后获取时的时间 + public DateTime LastGetTime { get; internal set; } + + /// + /// 最后归还时的时间 + /// + public DateTime LastReturnTime { get; internal set; } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; internal set; } = DateTime.Now; + + /// + /// 最后获取时的线程id + /// + public int LastGetThreadId { get; internal set; } + + /// + /// 最后归还时的线程id + /// + public int LastReturnThreadId { get; internal set; } + + public override string ToString() + { + return $"{this.Value}, Times: {this.GetTimes}, ThreadId(R/G): {this.LastReturnThreadId}/{this.LastGetThreadId}, Time(R/G): {this.LastReturnTime.ToString("yyyy-MM-dd HH:mm:ss:ms")}/{this.LastGetTime.ToString("yyyy-MM-dd HH:mm:ss:ms")}"; + } + + /// + /// 重置 Value 值 + /// + public void ResetValue() + { + if (this.Value != null) + { + try { this.Pool.Policy.OnDestroy(this.Value); } catch { } + try { (this.Value as IDisposable)?.Dispose(); } catch { } + } + T value = default(T); + try { value = this.Pool.Policy.OnCreate(); } catch { } + this.Value = value; + this.LastReturnTime = DateTime.Now; + } + + internal bool _isReturned = false; + public void Dispose() + { + Pool?.Return(this); + } + } +} \ No newline at end of file diff --git a/FreeSql/Internal/ObjectPool/ObjectPool.cs b/FreeSql/Internal/ObjectPool/ObjectPool.cs new file mode 100644 index 00000000..2dc21f44 --- /dev/null +++ b/FreeSql/Internal/ObjectPool/ObjectPool.cs @@ -0,0 +1,547 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Internal.ObjectPool +{ + + /// + /// 对象池管理类 + /// + /// 对象类型 + public partial class ObjectPool : IObjectPool + { + public IPolicy Policy { get; protected set; } + + private List> _allObjects = new List>(); + private object _allObjectsLock = new object(); + private ConcurrentStack> _freeObjects = new ConcurrentStack>(); + + private ConcurrentQueue _getSyncQueue = new ConcurrentQueue(); + private ConcurrentQueue>> _getAsyncQueue = new ConcurrentQueue>>(); + private ConcurrentQueue _getQueue = new ConcurrentQueue(); + + public bool IsAvailable => this.UnavailableException == null; + public Exception UnavailableException { get; private set; } + public DateTime? UnavailableTime { get; private set; } + private object UnavailableLock = new object(); + private bool running = true; + + public bool SetUnavailable(Exception exception) + { + + bool isseted = false; + + if (exception != null && UnavailableException == null) + { + + lock (UnavailableLock) + { + + if (UnavailableException == null) + { + + UnavailableException = exception; + UnavailableTime = DateTime.Now; + isseted = true; + } + } + } + + if (isseted) + { + + Policy.OnUnavailable(); + CheckAvailable(Policy.CheckAvailableInterval); + } + + return isseted; + } + + /// + /// 后台定时检查可用性 + /// + /// + private void CheckAvailable(int interval) + { + + new Thread(() => + { + + if (UnavailableException != null) + { + var bgcolor = Console.BackgroundColor; + var forecolor = Console.ForegroundColor; + Console.BackgroundColor = ConsoleColor.DarkYellow; + Console.ForegroundColor = ConsoleColor.White; + Console.Write($"【{Policy.Name}】恢复检查时间:{DateTime.Now.AddSeconds(interval)}"); + Console.BackgroundColor = bgcolor; + Console.ForegroundColor = forecolor; + Console.WriteLine(); + } + + while (UnavailableException != null) + { + + if (running == false) return; + + Thread.CurrentThread.Join(TimeSpan.FromSeconds(interval)); + + if (running == false) return; + + try + { + + var conn = getFree(false); + if (conn == null) throw new Exception($"CheckAvailable 无法获得资源,{this.Statistics}"); + + try + { + + if (Policy.OnCheckAvailable(conn) == false) throw new Exception("CheckAvailable 应抛出异常,代表仍然不可用。"); + break; + + } + finally + { + + Return(conn); + } + + } + catch (Exception ex) + { + var bgcolor = Console.BackgroundColor; + var forecolor = Console.ForegroundColor; + Console.BackgroundColor = ConsoleColor.DarkYellow; + Console.ForegroundColor = ConsoleColor.White; + Console.Write($"【{Policy.Name}】仍然不可用,下一次恢复检查时间:{DateTime.Now.AddSeconds(interval)},错误:({ex.Message})"); + Console.BackgroundColor = bgcolor; + Console.ForegroundColor = forecolor; + Console.WriteLine(); + } + } + + RestoreToAvailable(); + + }).Start(); + } + + private void RestoreToAvailable() + { + + bool isRestored = false; + if (UnavailableException != null) + { + + lock (UnavailableLock) + { + + if (UnavailableException != null) + { + + UnavailableException = null; + UnavailableTime = null; + isRestored = true; + } + } + } + + if (isRestored) + { + + lock (_allObjectsLock) + _allObjects.ForEach(a => a.LastGetTime = a.LastReturnTime = new DateTime(2000, 1, 1)); + + Policy.OnAvailable(); + + var bgcolor = Console.BackgroundColor; + var forecolor = Console.ForegroundColor; + Console.BackgroundColor = ConsoleColor.DarkGreen; + Console.ForegroundColor = ConsoleColor.White; + Console.Write($"【{Policy.Name}】已恢复工作"); + Console.BackgroundColor = bgcolor; + Console.ForegroundColor = forecolor; + Console.WriteLine(); + } + } + + protected bool LiveCheckAvailable() + { + + try + { + + var conn = getFree(false); + if (conn == null) throw new Exception($"LiveCheckAvailable 无法获得资源,{this.Statistics}"); + + try + { + + if (Policy.OnCheckAvailable(conn) == false) throw new Exception("LiveCheckAvailable 应抛出异常,代表仍然不可用。"); + + } + finally + { + + Return(conn); + } + + } + catch + { + return false; + } + + RestoreToAvailable(); + + return true; + } + + public string Statistics => $"Pool: {_freeObjects.Count}/{_allObjects.Count}, Get wait: {_getSyncQueue.Count}, GetAsync wait: {_getAsyncQueue.Count}"; + public string StatisticsFullily + { + get + { + var sb = new StringBuilder(); + + sb.AppendLine(Statistics); + sb.AppendLine(""); + + foreach (var obj in _allObjects) + { + sb.AppendLine($"{obj.Value}, Times: {obj.GetTimes}, ThreadId(R/G): {obj.LastReturnThreadId}/{obj.LastGetThreadId}, Time(R/G): {obj.LastReturnTime.ToString("yyyy-MM-dd HH:mm:ss:ms")}/{obj.LastGetTime.ToString("yyyy-MM-dd HH:mm:ss:ms")}, "); + } + + return sb.ToString(); + } + } + + /// + /// 创建对象池 + /// + /// 池大小 + /// 池内对象的创建委托 + /// 获取池内对象成功后,进行使用前操作 + public ObjectPool(int poolsize, Func createObject, Action> onGetObject = null) : this(new DefaultPolicy { PoolSize = poolsize, CreateObject = createObject, OnGetObject = onGetObject }) + { + } + /// + /// 创建对象池 + /// + /// 策略 + public ObjectPool(IPolicy policy) + { + Policy = policy; + + AppDomain.CurrentDomain.ProcessExit += (s1, e1) => + { + running = false; + }; + try + { + Console.CancelKeyPress += (s1, e1) => + { + if (e1.Cancel) return; + running = false; + }; + } + catch { } + } + + /// + /// 获取可用资源,或创建资源 + /// + /// + private Object getFree(bool checkAvailable) + { + + if (running == false) + throw new ObjectDisposedException($"【{Policy.Name}】对象池已释放,无法访问。"); + + if (checkAvailable && UnavailableException != null) + throw new Exception($"【{Policy.Name}】状态不可用,等待后台检查程序恢复方可使用。{UnavailableException?.Message}"); + + if ((_freeObjects.TryPop(out var obj) == false || obj == null) && _allObjects.Count < Policy.PoolSize) + { + + lock (_allObjectsLock) + if (_allObjects.Count < Policy.PoolSize) + _allObjects.Add(obj = new Object { Pool = this, Id = _allObjects.Count + 1 }); + } + + if (obj != null) + obj._isReturned = false; + + if (obj != null && obj.Value == null || + obj != null && Policy.IdleTimeout > TimeSpan.Zero && DateTime.Now.Subtract(obj.LastReturnTime) > Policy.IdleTimeout) + { + try + { + obj.ResetValue(); + } + catch + { + Return(obj); + throw; + } + } + + return obj; + } + + public Object Get(TimeSpan? timeout = null) + { + + var obj = getFree(true); + + if (obj == null) + { + + var queueItem = new GetSyncQueueInfo(); + + _getSyncQueue.Enqueue(queueItem); + _getQueue.Enqueue(false); + + if (timeout == null) timeout = Policy.SyncGetTimeout; + + try + { + if (queueItem.Wait.Wait(timeout.Value)) + obj = queueItem.ReturnValue; + } + catch { } + + if (obj == null) obj = queueItem.ReturnValue; + if (obj == null) lock (queueItem.Lock) queueItem.IsTimeout = (obj = queueItem.ReturnValue) == null; + if (obj == null) obj = queueItem.ReturnValue; + + if (obj == null) + { + + Policy.OnGetTimeout(); + + if (Policy.IsThrowGetTimeoutException) + throw new TimeoutException($"SafeObjectPool.Get 获取超时({timeout.Value.TotalSeconds}秒)。"); + + return null; + } + } + + try + { + Policy.OnGet(obj); + } + catch + { + Return(obj); + throw; + } + + obj.LastGetThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastGetTime = DateTime.Now; + Interlocked.Increment(ref obj._getTimes); + + return obj; + } + +#if net40 +#else + async public Task> GetAsync() + { + + var obj = getFree(true); + + if (obj == null) + { + + if (Policy.AsyncGetCapacity > 0 && _getAsyncQueue.Count >= Policy.AsyncGetCapacity - 1) + throw new OutOfMemoryException($"SafeObjectPool.GetAsync 无可用资源且队列过长,Policy.AsyncGetCapacity = {Policy.AsyncGetCapacity}。"); + + var tcs = new TaskCompletionSource>(); + + _getAsyncQueue.Enqueue(tcs); + _getQueue.Enqueue(true); + + obj = await tcs.Task; + + //if (timeout == null) timeout = Policy.SyncGetTimeout; + + //if (tcs.Task.Wait(timeout.Value)) + // obj = tcs.Task.Result; + + //if (obj == null) { + + // tcs.TrySetCanceled(); + // Policy.GetTimeout(); + + // if (Policy.IsThrowGetTimeoutException) + // throw new Exception($"SafeObjectPool.GetAsync 获取超时({timeout.Value.TotalSeconds}秒)。"); + + // return null; + //} + } + + try + { + await Policy.OnGetAsync(obj); + } + catch + { + Return(obj); + throw; + } + + obj.LastGetThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastGetTime = DateTime.Now; + Interlocked.Increment(ref obj._getTimes); + + return obj; + } +#endif + + public void Return(Object obj, bool isReset = false) + { + + if (obj == null) return; + + if (obj._isReturned) return; + + if (running == false) + { + + Policy.OnDestroy(obj.Value); + try { (obj.Value as IDisposable)?.Dispose(); } catch { } + + return; + } + + if (isReset) obj.ResetValue(); + + bool isReturn = false; + + while (isReturn == false && _getQueue.TryDequeue(out var isAsync)) + { + + if (isAsync == false) + { + + if (_getSyncQueue.TryDequeue(out var queueItem) && queueItem != null) + { + + lock (queueItem.Lock) + if (queueItem.IsTimeout == false) + queueItem.ReturnValue = obj; + + if (queueItem.ReturnValue != null) + { + + obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastReturnTime = DateTime.Now; + + try + { + queueItem.Wait.Set(); + isReturn = true; + } + catch + { + } + } + + try { queueItem.Dispose(); } catch { } + } + + } + else + { + + if (_getAsyncQueue.TryDequeue(out var tcs) && tcs != null && tcs.Task.IsCanceled == false) + { + + obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastReturnTime = DateTime.Now; + + try { isReturn = tcs.TrySetResult(obj); } catch { } + } + } + } + + //无排队,直接归还 + if (isReturn == false) + { + try + { + Policy.OnReturn(obj); + } + catch + { + throw; + } + finally + { + obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastReturnTime = DateTime.Now; + obj._isReturned = true; + + _freeObjects.Push(obj); + } + } + } + + public void Dispose() + { + + running = false; + + while (_freeObjects.TryPop(out var fo)) ; + + while (_getSyncQueue.TryDequeue(out var sync)) + { + try { sync.Wait.Set(); } catch { } + } + + while (_getAsyncQueue.TryDequeue(out var async)) + async.TrySetCanceled(); + + while (_getQueue.TryDequeue(out var qs)) ; + + for (var a = 0; a < _allObjects.Count; a++) + { + Policy.OnDestroy(_allObjects[a].Value); + try { (_allObjects[a].Value as IDisposable)?.Dispose(); } catch { } + } + + _allObjects.Clear(); + } + + class GetSyncQueueInfo : IDisposable + { + + internal ManualResetEventSlim Wait { get; set; } = new ManualResetEventSlim(); + + internal Object ReturnValue { get; set; } + + internal object Lock = new object(); + + internal bool IsTimeout { get; set; } = false; + + public void Dispose() + { + try + { + if (Wait != null) + Wait.Dispose(); + } + catch + { + } + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs index 012931a7..987a05ca 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs index f6f8844b..195dbb9d 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs index 4ae88c92..f28cc00a 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index e95438d1..d6df8d17 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -1,7 +1,7 @@ using FreeSql.Internal; using FreeSql.Internal.Model; using MySql.Data.MySqlClient; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 61fb63f4..86cb81ec 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -1,5 +1,5 @@ using MySql.Data.MySqlClient; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index 34c3529c..f485abe1 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index a6a23395..9bb0051d 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index dddd0cf0..3abd6fd4 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index 32b028f7..f11b8b10 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs index 4ce05dd8..8e6fb010 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index 41b4b0bf..88a9c9b5 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index d9738cc6..94921b95 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs index a9a044cc..c3e07c5d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index fabfcddd..bb33aa87 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index 06f358fe..ddf1e6e4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index c0ac2ae6..60361f3e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index 2230fbc3..62e08f02 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index d134cfe0..8c8fd511 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index d97d5fc1..9f2f291e 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs index d068a424..dab55b93 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index ba81e59c..791f4f7b 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -1,7 +1,7 @@ using FreeSql.Internal; using FreeSql.Internal.Model; using Oracle.ManagedDataAccess.Client; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index c088d63a..09b82011 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -1,5 +1,5 @@ using Oracle.ManagedDataAccess.Client; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index d843b497..5f1600b9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -2,7 +2,7 @@ using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; using Npgsql; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index 007bc36b..958420ef 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -1,5 +1,5 @@ using Npgsql; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index f10093c2..f5cbc3a0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -3,7 +3,7 @@ using FreeSql.Internal; using Newtonsoft.Json.Linq; using Npgsql.LegacyPostgis; using NpgsqlTypes; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 36dd6f17..c99cbbb6 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 5ca513c1..08bce9b7 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 7e5496fd..1e9e060a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 09ba12df..357b87b8 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 10baf6f0..828ca70d 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; From 2544db5c4bfabfa01ddd98234e0f497ce292e263 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Mar 2020 20:42:13 +0800 Subject: [PATCH 0487/1029] up --- .../Oracle/Curd/OracleSelectTest.cs | 5 --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 40 +++++++------------ 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 3dc2c5d3..c12ba6ee 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -709,7 +709,6 @@ namespace FreeSql.Tests.Oracle { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist1 = select @@ -718,7 +717,6 @@ namespace FreeSql.Tests.Oracle { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -730,7 +728,6 @@ namespace FreeSql.Tests.Oracle b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist2 = select @@ -741,7 +738,6 @@ namespace FreeSql.Tests.Oracle b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -751,7 +747,6 @@ namespace FreeSql.Tests.Oracle { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid), sum3 = b.Sum(b.Value.Type.Parent.Id) }); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 1318b25a..003cc47c 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -301,35 +301,25 @@ namespace FreeSql.Tests } }); - List<(Guid, DateTime)> contains2linqarr = new List<(Guid, DateTime)>(); - Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToSql(a => 1).Replace("\r\n", "")); - g.sqlite.Select().Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToList(); + //List<(Guid, DateTime)> contains2linqarr = new List<(Guid, DateTime)>(); + //Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToSql(a => 1).Replace("\r\n", "")); + //g.sqlite.Select().Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToList(); - contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); - contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); - contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); - g.sqlite.Select() - .Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToList(); + //contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); + //contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); + //contains2linqarr.Add((Guid.NewGuid(), DateTime.Now)); + //g.sqlite.Select() + // .Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToList(); + //List<(Guid, DateTime, DateTime?)> contains3linqarr = new List<(Guid, DateTime, DateTime?)>(); + //Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToSql(a => 1).Replace("\r\n", "")); + //g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToList(); - - - - - - - - - - List<(Guid, DateTime, DateTime?)> contains3linqarr = new List<(Guid, DateTime, DateTime?)>(); - Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToSql(a => 1).Replace("\r\n", "")); - g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToList(); - - contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); - contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); - contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); - g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToList(); + //contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); + //contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); + //contains3linqarr.Add((Guid.NewGuid(), DateTime.Now, DateTime.Now)); + //g.sqlite.Select().Where(a => contains3linqarr.Contains(a.Id, a.ct1, a.ct2)).ToList(); var start = DateTime.Now.Date; var end = DateTime.Now.AddDays(1).Date.AddMilliseconds(-1); From 2f32e0e71c1f1f095e71b531daabfd70e9231c49 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 20 Mar 2020 21:29:53 +0800 Subject: [PATCH 0488/1029] =?UTF-8?q?=E7=A7=BB=E5=85=A5=20SafeObjectPool?= =?UTF-8?q?=20=E6=BA=90=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 5 +++++ .../Internal/CommonProvider/AdoProvider/DbConnectionPool.cs | 3 ++- FreeSql/Internal/ObjectPool/DefaultPolicy.cs | 1 + FreeSql/Internal/ObjectPool/IPolicy.cs | 5 +++++ FreeSql/Internal/ObjectPool/ObjectPool.cs | 6 ++++-- .../MsAccessAdo/MsAccessConnectionPool.cs | 1 + .../FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs | 1 + .../Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs | 1 + .../Default/OdbcAdo/OdbcConnectionPool.cs | 1 + .../MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs | 1 + .../Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs | 1 + .../OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs | 1 + .../OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs | 1 + .../OracleAdo/OracleConnectionPool.cs | 1 + .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 1 + .../SqlServerAdo/SqlServerConnectionPool.cs | 1 + .../SqliteAdo/SqliteConnectionPool.cs | 1 + 17 files changed, 29 insertions(+), 3 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index cbd67953..f312638c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2982,6 +2982,11 @@ 获取超时后,是否抛出异常 + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 + + 后台定时检查可用性间隔秒数 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs index e667b19f..03cc643d 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs @@ -105,9 +105,10 @@ namespace FreeSql.Internal.CommonProvider public string Name { get; set; } = typeof(DbConnectionPoolPolicy).GetType().FullName; public int PoolSize { get; set; } = 1000; public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); - public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(50); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; public DbConnection OnCreate() diff --git a/FreeSql/Internal/ObjectPool/DefaultPolicy.cs b/FreeSql/Internal/ObjectPool/DefaultPolicy.cs index 5541c579..744b8b8b 100644 --- a/FreeSql/Internal/ObjectPool/DefaultPolicy.cs +++ b/FreeSql/Internal/ObjectPool/DefaultPolicy.cs @@ -15,6 +15,7 @@ namespace FreeSql.Internal.ObjectPool public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(50); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; public Func CreateObject; diff --git a/FreeSql/Internal/ObjectPool/IPolicy.cs b/FreeSql/Internal/ObjectPool/IPolicy.cs index 63918587..9a2b40d6 100644 --- a/FreeSql/Internal/ObjectPool/IPolicy.cs +++ b/FreeSql/Internal/ObjectPool/IPolicy.cs @@ -38,6 +38,11 @@ namespace FreeSql.Internal.ObjectPool /// bool IsThrowGetTimeoutException { get; set; } + /// + /// 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 + /// + bool IsAutoDisposeWithSystem { get; set; } + /// /// 后台定时检查可用性间隔秒数 /// diff --git a/FreeSql/Internal/ObjectPool/ObjectPool.cs b/FreeSql/Internal/ObjectPool/ObjectPool.cs index 2dc21f44..6b9d520f 100644 --- a/FreeSql/Internal/ObjectPool/ObjectPool.cs +++ b/FreeSql/Internal/ObjectPool/ObjectPool.cs @@ -241,14 +241,16 @@ namespace FreeSql.Internal.ObjectPool AppDomain.CurrentDomain.ProcessExit += (s1, e1) => { - running = false; + if (Policy.IsAutoDisposeWithSystem) + running = false; }; try { Console.CancelKeyPress += (s1, e1) => { if (e1.Cancel) return; - running = false; + if (Policy.IsAutoDisposeWithSystem) + running = false; }; } catch { } diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs index f28cc00a..b59384bc 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs @@ -55,6 +55,7 @@ namespace FreeSql.MsAccess public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; private string _connectionString; diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 86cb81ec..88479d75 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -50,6 +50,7 @@ namespace FreeSql.MySql public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index 9bb0051d..01fabe40 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -72,6 +72,7 @@ namespace FreeSql.Odbc.Dameng public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs index 8e6fb010..fb9c6a2f 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -55,6 +55,7 @@ namespace FreeSql.Odbc.Default public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs index c3e07c5d..45188f84 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -50,6 +50,7 @@ namespace FreeSql.Odbc.MySql public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index ddf1e6e4..04215901 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -72,6 +72,7 @@ namespace FreeSql.Odbc.Oracle public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index 62e08f02..2b36f586 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -62,6 +62,7 @@ namespace FreeSql.Odbc.PostgreSQL public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs index dab55b93..fb70774a 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -55,6 +55,7 @@ namespace FreeSql.Odbc.SqlServer public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index 09b82011..9f40af14 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -72,6 +72,7 @@ namespace FreeSql.Oracle public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index 958420ef..6fc4d7fe 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -62,6 +62,7 @@ namespace FreeSql.PostgreSQL public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 1e9e060a..a58f8940 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -55,6 +55,7 @@ namespace FreeSql.SqlServer public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 828ca70d..f2275191 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -54,6 +54,7 @@ namespace FreeSql.Sqlite public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero; public int AsyncGetCapacity { get; set; } = 10000; public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; public int CheckAvailableInterval { get; set; } = 5; public string[] Attaches = new string[0]; From 508743ad1a72dce5c91161e542d941fa63f42abb Mon Sep 17 00:00:00 2001 From: Eternity Date: Sat, 21 Mar 2020 02:56:27 +0800 Subject: [PATCH 0489/1029] =?UTF-8?q?Json=E6=89=A9=E5=B1=95=E6=94=AF?= =?UTF-8?q?=E6=8C=81JsonSerializerSettings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index a8630d74..efac4d3f 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -15,16 +15,21 @@ namespace FreeSql.Extensions static object _isAopedLock = new object(); static ConcurrentDictionary _dicTypes = new ConcurrentDictionary(); static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); - static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object) }); + static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); /// /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 /// /// public static void UseJsonMap(this IFreeSql that) + { + UseJsonMap(that, null); + } + + public static void UseJsonMap(this IFreeSql that, JsonSerializerSettings settings) { if (_isAoped == false) - lock(_isAopedLock) + lock (_isAopedLock) if (_isAoped == false) { _isAoped = true; @@ -46,7 +51,7 @@ namespace FreeSql.Extensions { return Expression.IfThenElse( Expression.TypeEqual(valueExp, e.Property.PropertyType), - Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object))), typeof(object)), + Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(settings)), typeof(object)), elseExp); }); } @@ -54,5 +59,6 @@ namespace FreeSql.Extensions }); } } + } } From d8f49808a831648fac77efb69ebda18cb4ca7bc1 Mon Sep 17 00:00:00 2001 From: Eternity Date: Sat, 21 Mar 2020 02:56:27 +0800 Subject: [PATCH 0490/1029] =?UTF-8?q?Json=E6=89=A9=E5=B1=95=E6=94=AF?= =?UTF-8?q?=E6=8C=81JsonSerializerSettings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 16 +++++--- Examples/base_entity/base_entity.csproj | 6 ++- .../FreeSql.Extensions.JsonMap.csproj | 9 +++-- .../FreeSql.Extensions.JsonMap/JsonMapCore.cs | 40 ++++++++++++++++--- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 146f9603..5633193b 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -18,6 +18,8 @@ namespace base_entity { public int clicks { get; set; } public string title { get; set; } + + public string nullvalue { get; set; } } [Table(Name = "sysconfig")] public class S_SysConfig : BaseEntity> @@ -43,7 +45,7 @@ namespace base_entity .UseNoneCommandParameter(true) .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=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=2") - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") .UseLazyLoading(true) .Build(); BaseEntity.Initialization(fsql); @@ -59,10 +61,12 @@ namespace base_entity var items1 = Products.Select.Limit(10).OrderByDescending(a => a.CreateTime).ToList(); var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); - - BaseEntity.Orm.UseJsonMap(); - - new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); +#if NETCORE30 + BaseEntity.Orm.UseJsonMap(new System.Text.Json.JsonSerializerOptions { IgnoreNullValues = true }); +#else + BaseEntity.Orm.UseJsonMap(new JsonSerializerSettings { NullValueHandling=NullValueHandling.Ignore }); +#endif + new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11", nullvalue = null } }.Save(); new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" } }.Save(); new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" } }.Save(); var testconfigs11 = S_SysConfig.Select.ToList(); @@ -136,7 +140,7 @@ namespace base_entity }).Wait(); - + Console.WriteLine("按任意键结束。。。"); Console.ReadKey(); diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index c912bae3..271b69a9 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1 + netcoreapp2.1;netcoreapp3.0 @@ -13,7 +13,9 @@ - + + NETCORE30 + diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 92aaeb4b..6eb5f92d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45;net40 + netstandard2.0;net45;net40;netcoreapp3.0 1.3.0-preview10 true YeXiangQin @@ -24,13 +24,16 @@ - + FreeSql.Extensions.JsonMap.xml 3 + + NETCORE30 + - + diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index a8630d74..53138def 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -6,7 +6,9 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; - +#if NETCORE30 +using System.Text.Json; +#endif namespace FreeSql.Extensions { public static class JsonMapCore @@ -14,17 +16,38 @@ namespace FreeSql.Extensions static bool _isAoped = false; static object _isAopedLock = new object(); static ConcurrentDictionary _dicTypes = new ConcurrentDictionary(); - static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); - static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object) }); +#if NETCORE30 + static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonSerializer).GetMethod(nameof(JsonSerializer.Deserialize), new[] { typeof(string), typeof(Type) }); + static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonSerializer).GetMethod(nameof(JsonSerializer.Serialize), new[] { typeof(object), typeof(Type), typeof(JsonSerializerOptions) }); +#else + static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod(nameof(JsonConvert.DeserializeObject), new[] { typeof(string), typeof(Type) }); + + static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod(nameof(JsonConvert.SerializeObject), new[] { typeof(object), typeof(JsonSerializerSettings) }); +#endif /// /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 /// /// public static void UseJsonMap(this IFreeSql that) + { + UseJsonMap(that, +#if NETCORE30 + new JsonSerializerOptions() + +#else + new JsonSerializerSettings() +#endif + );} +#if NETCORE30 + public static void UseJsonMap(this IFreeSql that, JsonSerializerOptions settings) +#else + public static void UseJsonMap(this IFreeSql that, JsonSerializerSettings settings) +#endif + { if (_isAoped == false) - lock(_isAopedLock) + lock (_isAopedLock) if (_isAoped == false) { _isAoped = true; @@ -46,7 +69,13 @@ namespace FreeSql.Extensions { return Expression.IfThenElse( Expression.TypeEqual(valueExp, e.Property.PropertyType), - Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object))), typeof(object)), + Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, +#if NETCORE30 + Expression.Convert(valueExp, typeof(object)), Expression.Constant(valueExp.Type), Expression.Constant(settings)) +#else + Expression.Convert(valueExp, typeof(object)), Expression.Constant(settings)) +#endif + , typeof(object)), elseExp); }); } @@ -54,5 +83,6 @@ namespace FreeSql.Extensions }); } } + } } From 519f82b046f1f8caf39b499fe97ba845c90fb3ce Mon Sep 17 00:00:00 2001 From: Eternity Date: Sat, 21 Mar 2020 19:05:30 +0800 Subject: [PATCH 0491/1029] =?UTF-8?q?Revert=20"Json=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E6=94=AF=E6=8C=81JsonSerializerSettings"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit d8f49808a831648fac77efb69ebda18cb4ca7bc1. --- Examples/base_entity/Program.cs | 16 +++----- Examples/base_entity/base_entity.csproj | 6 +-- .../FreeSql.Extensions.JsonMap.csproj | 9 ++--- .../FreeSql.Extensions.JsonMap/JsonMapCore.cs | 40 ++++--------------- 4 files changed, 19 insertions(+), 52 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 5633193b..146f9603 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -18,8 +18,6 @@ namespace base_entity { public int clicks { get; set; } public string title { get; set; } - - public string nullvalue { get; set; } } [Table(Name = "sysconfig")] public class S_SysConfig : BaseEntity> @@ -45,7 +43,7 @@ namespace base_entity .UseNoneCommandParameter(true) .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=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=2") - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") .UseLazyLoading(true) .Build(); BaseEntity.Initialization(fsql); @@ -61,12 +59,10 @@ namespace base_entity var items1 = Products.Select.Limit(10).OrderByDescending(a => a.CreateTime).ToList(); var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); -#if NETCORE30 - BaseEntity.Orm.UseJsonMap(new System.Text.Json.JsonSerializerOptions { IgnoreNullValues = true }); -#else - BaseEntity.Orm.UseJsonMap(new JsonSerializerSettings { NullValueHandling=NullValueHandling.Ignore }); -#endif - new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11", nullvalue = null } }.Save(); + + BaseEntity.Orm.UseJsonMap(); + + new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" } }.Save(); new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" } }.Save(); var testconfigs11 = S_SysConfig.Select.ToList(); @@ -140,7 +136,7 @@ namespace base_entity }).Wait(); - + Console.WriteLine("按任意键结束。。。"); Console.ReadKey(); diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index 271b69a9..c912bae3 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1;netcoreapp3.0 + netcoreapp2.1 @@ -13,9 +13,7 @@ - - NETCORE30 - + diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 6eb5f92d..92aaeb4b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45;net40;netcoreapp3.0 + netstandard2.0;net45;net40 1.3.0-preview10 true YeXiangQin @@ -24,16 +24,13 @@ - + FreeSql.Extensions.JsonMap.xml 3 - - NETCORE30 - - + diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index 53138def..a59f3c0b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -6,9 +6,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; -#if NETCORE30 -using System.Text.Json; -#endif + namespace FreeSql.Extensions { public static class JsonMapCore @@ -16,38 +14,23 @@ namespace FreeSql.Extensions static bool _isAoped = false; static object _isAopedLock = new object(); static ConcurrentDictionary _dicTypes = new ConcurrentDictionary(); -#if NETCORE30 - static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonSerializer).GetMethod(nameof(JsonSerializer.Deserialize), new[] { typeof(string), typeof(Type) }); + static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); + static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object) }); - static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonSerializer).GetMethod(nameof(JsonSerializer.Serialize), new[] { typeof(object), typeof(Type), typeof(JsonSerializerOptions) }); -#else - static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod(nameof(JsonConvert.DeserializeObject), new[] { typeof(string), typeof(Type) }); - - static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod(nameof(JsonConvert.SerializeObject), new[] { typeof(object), typeof(JsonSerializerSettings) }); -#endif /// /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 /// /// + public static void UseJsonMap(this IFreeSql that) { - UseJsonMap(that, -#if NETCORE30 - new JsonSerializerOptions() + UseJsonMap(that,new JsonSerializerSettings()); + } -#else - new JsonSerializerSettings() -#endif - );} -#if NETCORE30 - public static void UseJsonMap(this IFreeSql that, JsonSerializerOptions settings) -#else public static void UseJsonMap(this IFreeSql that, JsonSerializerSettings settings) -#endif - { if (_isAoped == false) - lock (_isAopedLock) + lock(_isAopedLock) if (_isAoped == false) { _isAoped = true; @@ -69,13 +52,7 @@ namespace FreeSql.Extensions { return Expression.IfThenElse( Expression.TypeEqual(valueExp, e.Property.PropertyType), - Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, -#if NETCORE30 - Expression.Convert(valueExp, typeof(object)), Expression.Constant(valueExp.Type), Expression.Constant(settings)) -#else - Expression.Convert(valueExp, typeof(object)), Expression.Constant(settings)) -#endif - , typeof(object)), + Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(settings)), typeof(object)), elseExp); }); } @@ -83,6 +60,5 @@ namespace FreeSql.Extensions }); } } - } } From ec7dec161af9497baf2d79764b47ad3a58830660 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Mar 2020 19:19:53 +0800 Subject: [PATCH 0492/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E5=86=85?= =?UTF-8?q?=E9=83=A8=E6=96=B9=E6=B3=95=20DisplayCsharp=EF=BC=8C=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=20LazyLoading=20=E5=8A=A8=E6=80=81=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=B1=BB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 --- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 53 +++++++++++++++++-- FreeSql/FreeSql.xml | 7 +++ FreeSql/Internal/UtilsExpressionTree.cs | 18 +++---- 4 files changed, 65 insertions(+), 20 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ca7c357b..2735cefb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 9ea49e7f..5aded13e 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -16,7 +16,7 @@ using System.Threading; public static partial class FreeSqlGlobalExtensions { - static Lazy> dicIsNumberType = new Lazy>(() => new Dictionary + static Lazy> _dicIsNumberType = new Lazy>(() => new Dictionary { [typeof(sbyte)] = true, [typeof(sbyte?)] = true, @@ -41,13 +41,60 @@ public static partial class FreeSqlGlobalExtensions [typeof(decimal)] = false, [typeof(decimal?)] = false }); - public static bool IsIntegerType(this Type that) => that == null ? false : (dicIsNumberType.Value.TryGetValue(that, out var tryval) ? tryval : false); - public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that); + public static bool IsIntegerType(this Type that) => that == null ? false : (_dicIsNumberType.Value.TryGetValue(that, out var tryval) ? tryval : false); + public static bool IsNumberType(this Type that) => that == null ? false : _dicIsNumberType.Value.ContainsKey(that); public static bool IsNullableType(this Type that) => that.IsArray == false && that?.FullName.StartsWith("System.Nullable`1[") == true; public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that)); public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that; internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args)); + /// + /// 获取 Type 的原始 c# 文本表示 + /// + /// + /// + public static string DisplayCsharp(this Type that) + { + return DisplayCsharp(that, true); + } + static string DisplayCsharp(this Type that, bool isNameSpace) + { + if (that == typeof(void)) return "void"; + if (that.IsGenericParameter) return that.Name; + var sb = new StringBuilder(); + var nestedType = that; + while (nestedType.IsNested) + { + sb.Insert(0, ".").Insert(0, DisplayCsharp(nestedType.DeclaringType, false)); + nestedType = nestedType.DeclaringType; + } + if (isNameSpace && string.IsNullOrEmpty(nestedType.Namespace) == false) + sb.Insert(0, ".").Insert(0, nestedType.Namespace); + + if (that.IsGenericType == false) + return sb.Append(that.Name).ToString(); + + var genericParameters = that.GetGenericArguments(); + if (that.IsNested && that.DeclaringType.IsGenericType) + { + var dic = genericParameters.ToDictionary(a => a.Name); + foreach (var nestedGenericParameter in that.DeclaringType.GetGenericArguments()) + if (dic.ContainsKey(nestedGenericParameter.Name)) + dic.Remove(nestedGenericParameter.Name); + genericParameters = dic.Values.ToArray(); + } + if (genericParameters.Any() == false) + return sb.Append(that.Name).ToString(); + + sb.Append(that.Name.Remove(that.Name.IndexOf('`'))).Append("<"); + var genericTypeIndex = 0; + foreach (var genericType in genericParameters) + { + if (genericTypeIndex++ > 0) sb.Append(", "); + sb.Append(DisplayCsharp(genericType, true)); + } + return sb.Append(">").ToString(); + } public static object CreateInstanceGetDefaultValue(this Type that) { if (that == null) return null; diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index f312638c..cf900d20 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3194,6 +3194,13 @@ + + + 获取 Type 的原始 c# 文本表示 + + + + 测量两个经纬度的距离,返回单位:米 diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 1a65014b..cf78e9a3 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -397,7 +397,7 @@ namespace FreeSql.Internal tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 - var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}"; + var trytbTypeName = trytb.Type.DisplayCsharp(); var trytbTypeLazyName = default(string); StringBuilder cscode = null; if (common.CodeFirst.IsLazyLoading && propsLazy.Any()) @@ -448,10 +448,8 @@ namespace FreeSql.Internal } public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, NaviteTuple vp, StringBuilder cscode) { - var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}"; - var propTypeName = pnv.PropertyType.IsGenericType ? - $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GetGenericArguments().Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" : - (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name}"); + var trytbTypeName = trytb.Type.DisplayCsharp(); + var propTypeName = pnv.PropertyType.DisplayCsharp(); var pnvAttr = common.GetEntityNavigateAttribute(trytb.Type, pnv); var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); @@ -474,7 +472,7 @@ namespace FreeSql.Internal var tbref = propElementType == trytb.Type ? trytb : GetTableByEntity(propElementType, common); //可能是父子关系 if (tbref == null) return; - var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}"; + var tbrefTypeName = tbref.Type.DisplayCsharp(); Type midType = null; var isManyToMany = false; @@ -797,8 +795,8 @@ namespace FreeSql.Internal .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); if (nvref.Exception == null) - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace?.NotNullAndConcat(".")}{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace?.NotNullAndConcat(".")}{propElementType.Name}") - .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.IsNested ? $"{tbmid.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbmid.Type.DeclaringType.Name}.{tbmid.Type.Name}" : $"{tbmid.Type.Namespace?.NotNullAndConcat(".")}{tbmid.Type.Name}") + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.DisplayCsharp()) + .Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.DisplayCsharp()) .Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();") .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;"); else @@ -933,7 +931,7 @@ namespace FreeSql.Internal if (nvref.Exception == null) { - cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.IsNested ? $"{propElementType.DeclaringType.Namespace?.NotNullAndConcat(".")}{propElementType.DeclaringType.Name}.{propElementType.Name}" : $"{propElementType.Namespace?.NotNullAndConcat(".")}{propElementType.Name}").Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();"); + cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.DisplayCsharp()).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();"); if (refprop != null) { cscode.Append(" foreach (var loc1 in base.").Append(pnv.Name).AppendLine(")") @@ -969,7 +967,7 @@ namespace FreeSql.Internal trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; } - var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}"; + var tbrefTypeName = tbref.Type.DisplayCsharp(); var isOnoToOne = pnv.PropertyType != trytb.Type && tbref.Properties.Where(z => z.Value.PropertyType == trytb.Type).Any() && tbref.Primarys.Length == trytb.Primarys.Length && From 123dbcf3ec31e4c149063f49601bb73f9557dced Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Mar 2020 19:30:04 +0800 Subject: [PATCH 0493/1029] clean --- Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index 7615b886..32647dae 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -21,7 +21,6 @@ namespace FreeSql.Extensions /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 /// /// - public static void UseJsonMap(this IFreeSql that) { UseJsonMap(that, Newtonsoft.Json.JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings()); From 500a4d02f321959055fcff686d4aee76558cb919 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 21 Mar 2020 22:27:58 +0800 Subject: [PATCH 0494/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20Internal=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=20CreateInstance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 5aded13e..81668363 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -102,7 +102,7 @@ public static partial class FreeSqlGlobalExtensions if (that.IsArray) return Array.CreateInstance(that, 0); var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters(); if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, null); - return Activator.CreateInstance(that, ctorParms.Select(a => a.ParameterType.IsInterface || a.ParameterType.IsAbstract ? null : Activator.CreateInstance(a.ParameterType, null)).ToArray()); + return Activator.CreateInstance(that, ctorParms.Select(a => a.ParameterType.IsInterface || a.ParameterType.IsAbstract || a.ParameterType == typeof(string) ? null : Activator.CreateInstance(a.ParameterType, null)).ToArray()); } internal static NewExpression InternalNewExpression(this Type that) { From cb366cc7719a0a8d12f36aaac54f56737ca14f6c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 22 Mar 2020 01:15:40 +0800 Subject: [PATCH 0495/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Navigate=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E6=9C=AA=E8=AE=BE=E7=BD=AE=20set=20=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E5=8F=8B=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20=E5=BB=B6=E6=97=B6?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=87=8D=E5=86=99=E7=B1=BB=E5=AF=B9=20protec?= =?UTF-8?q?ted=20set=20=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 3 + Examples/base_entity/Test01/Role.cs | 52 ++++++++ Examples/base_entity/Test01/User.cs | 154 ++++++++++++++++++++++ Examples/base_entity/Test01/UserRole.cs | 36 ++++++ Examples/base_entity/base_entity.xml | 165 ++++++++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 34 +++-- 6 files changed, 432 insertions(+), 12 deletions(-) create mode 100644 Examples/base_entity/Test01/Role.cs create mode 100644 Examples/base_entity/Test01/User.cs create mode 100644 Examples/base_entity/Test01/UserRole.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 146f9603..5cb92a98 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -49,6 +49,9 @@ namespace base_entity BaseEntity.Initialization(fsql); #endregion + var test01 = EMSServerModel.Model.User.Select.IncludeMany(a => a.Roles).ToList(); + var test01tb = EMSServerModel.Model.User.Orm.CodeFirst.GetTableByEntity(typeof(EMSServerModel.Model.User)); + var us = User1.Select.Limit(10).ToList(); new Products { title = "product-1" }.Save(); diff --git a/Examples/base_entity/Test01/Role.cs b/Examples/base_entity/Test01/Role.cs new file mode 100644 index 00000000..2db80d33 --- /dev/null +++ b/Examples/base_entity/Test01/Role.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; +using FreeSql; + +namespace EMSServerModel.Model +{ + /// + /// ɫ + /// + [JsonObject(MemberSerialization.OptIn)] + public partial class Role : BaseEntity{ + /// + /// ɫ + /// + [JsonProperty, Column(IsPrimary = true, IsIdentity = true)] + public long RoleId { get; set; } + + /// + /// ɫ + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string RoleName { get; set; } = string.Empty; + + /// + /// ɫ + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string RoleDesc { get; set; } = string.Empty; + + ///// + ///// ʱ + ///// + //[JsonProperty, Column(DbType = "date")] + //public DateTime CreateTime { get; set; } = DateTime.Now; + + /// + /// + /// + [JsonProperty] + public bool IsEnable { get; set; } = true; + + /// + /// ɫûԶർ + /// + [Navigate(ManyToMany = typeof(UserRole))] + public virtual ICollection Users { get; protected set; } + + } + +} diff --git a/Examples/base_entity/Test01/User.cs b/Examples/base_entity/Test01/User.cs new file mode 100644 index 00000000..46dc8e95 --- /dev/null +++ b/Examples/base_entity/Test01/User.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; +using System.ComponentModel.DataAnnotations; +using FreeSql; + +namespace EMSServerModel.Model +{ + /// + /// 用户表 + /// + [JsonObject(MemberSerialization.OptIn)] + public partial class User : BaseEntity{ + + //[JsonProperty, Column(IsIdentity = true)] + //public long Id { get; set; } + + /// + /// 编号 + /// + [JsonProperty, Column(DbType = "varchar(50)", IsPrimary = true)] + public string UserId { get; set; } = string.Empty; + + /// + /// 头像 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string Avatar { get; set; } = string.Empty; + + /// + /// 姓名 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string UserName { get; set; } = string.Empty; + + /// + /// 艺名 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string NickName { get; set; } = string.Empty; + + /// + /// 电话 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string Tel { get; set; } = string.Empty; + + /// + /// 性别 + /// + [JsonProperty] + public Sex Sex { get; set; } = Sex.男; + + /// + /// 证件号 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string UID { get; set; } = string.Empty; + + /// + /// 生日 + /// + [JsonProperty, Column(DbType = "date")] + public DateTime? DateOfBirth { get; set; } + + + /// + /// 出生地 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string PlaceOfBirth { get; set; } = string.Empty; + + /// + /// 居住地 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string Addr { get; set; } = string.Empty; + + + /// + /// 密码 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string Pwd { get; set; } = string.Empty; + + + /// + /// 部门编号 + /// + [JsonProperty] + public long? DeptId { get; set; } + + /// + /// 职务编号 + /// + [JsonProperty] + public long? TitleId { get; set; } + + + ///// + ///// 创建时间 + ///// + //[JsonProperty, Column(DbType = "date")] + //public DateTime CreateTime { get; set; } = DateTime.Now; + + /// + /// 国籍 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string Nationality { get; set; } = string.Empty; + + /// + /// 经手人 + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string Handler { get; set; } = string.Empty; + + /// + /// 启用 + /// + [JsonProperty] + public bool IsEnable { get; set; } = true; + + + /// + /// 备注 + /// + [JsonProperty, Column(DbType = "varchar(100)")] + public string Memos { get; set; } + + /// + /// + /// + [Navigate(ManyToMany = typeof(UserRole))] + public virtual ICollection Roles { get; protected set; } + + } + /// + /// 性别枚举 + /// + public enum Sex + { + /// + /// 女=0 + /// + 女=0, + /// + /// 男=1 + /// + 男=1 + } + +} diff --git a/Examples/base_entity/Test01/UserRole.cs b/Examples/base_entity/Test01/UserRole.cs new file mode 100644 index 00000000..3c13335a --- /dev/null +++ b/Examples/base_entity/Test01/UserRole.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json; +using FreeSql.DataAnnotations; +using FreeSql; + +namespace EMSServerModel.Model +{ + /// + /// ûɫϵ + /// + [JsonObject(MemberSerialization.OptIn)] + public partial class UserRole : BaseEntity{ + /// + /// ɫ + /// + [JsonProperty] + public long RoleId { get; set; } + /// + /// ɫ + /// + [Navigate("RoleId")] + public Role Roles { get; set; } + + /// + /// û + /// + [JsonProperty, Column(DbType = "varchar(50)")] + public string UserId { get; set; } + /// + /// û + /// + [Navigate("UserId")] + public User Users { get; set; } + + } + +} diff --git a/Examples/base_entity/base_entity.xml b/Examples/base_entity/base_entity.xml index 682b4b8a..a2fd01f9 100644 --- a/Examples/base_entity/base_entity.xml +++ b/Examples/base_entity/base_entity.xml @@ -29,5 +29,170 @@ 描述 + + + 角色表 + + + + + 角色编号 + + + + + 角色名称 + + + + + 角色描述 + + + + + 启用 + + + + + 角色用户多对多导航 + + + + + 用户表 + + + + + 编号 + + + + + 头像 + + + + + 姓名 + + + + + 艺名 + + + + + 电话 + + + + + 性别 + + + + + 证件号 + + + + + 生日 + + + + + 出生地 + + + + + 居住地 + + + + + 密码 + + + + + 部门编号 + + + + + 职务编号 + + + + + 国籍 + + + + + 经手人 + + + + + 启用 + + + + + 备注 + + + + + + + + + + 性别枚举 + + + + + 女=0 + + + + + 男=1 + + + + + 用户角色关系表 + + + + + 角色编号 + + + + + 角色导航 + + + + + 用户编号 + + + + + 用户导航 + + diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index cf78e9a3..d9dc1840 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -66,7 +66,7 @@ namespace FreeSql.Internal trytb.DbOldName = trytb.DbOldName?.ToUpper(); } if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; - var propsLazy = new List>(); + var propsLazy = new List>(); var propsNavObjs = new List(); var propsComment = CommonUtils.GetProperyCommentBySummary(entity); var columnsList = new List(); @@ -79,6 +79,9 @@ namespace FreeSql.Internal { if (colattr == null) colattr = new ColumnAttribute { IsIgnore = true }; else colattr.IsIgnore = true; + //Navigate 错误提示 + var pnvAttr = common.GetEntityNavigateAttribute(trytb.Type, p); + if (pnvAttr != null) throw new Exception($"【导航属性】{trytb.Type.DisplayCsharp()}.{p.Name} 缺少 set 属性"); } if (tp == null && colattr?.IsIgnore != true) { @@ -88,7 +91,7 @@ namespace FreeSql.Internal var getIsVirtual = getMethod?.IsVirtual == true && getMethod?.IsFinal == false;// trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; var setIsVirtual = setMethod?.IsVirtual == true && setMethod?.IsFinal == false; if (getIsVirtual == true || setIsVirtual == true) - propsLazy.Add(NaviteTuple.Create(p, getIsVirtual, setIsVirtual)); + propsLazy.Add(NaviteTuple.Create(p, getIsVirtual, setIsVirtual, getMethod, setMethod)); } propsNavObjs.Add(p); continue; @@ -446,10 +449,17 @@ namespace FreeSql.Internal return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb; } - public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, NaviteTuple vp, StringBuilder cscode) + public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, NaviteTuple vp, StringBuilder cscode) { + var getMethod = vp?.Item4; + var setMethod = vp?.Item5; var trytbTypeName = trytb.Type.DisplayCsharp(); var propTypeName = pnv.PropertyType.DisplayCsharp(); + var propModification = (getMethod?.IsPublic == true || setMethod?.IsPublic == true ? "public " : (getMethod?.IsAssembly == true || setMethod?.IsAssembly == true ? "internal " : (getMethod?.IsFamily == true || setMethod?.IsFamily == true ? "protected " : (getMethod?.IsPrivate == true || setMethod?.IsPrivate == true ? "private " : "")))); + var propSetModification = (setMethod?.IsPublic == true ? "public " : (setMethod?.IsAssembly == true ? "internal " : (setMethod?.IsFamily == true ? "protected " : (setMethod?.IsPrivate == true ? "private " : "")))); + var propGetModification = (getMethod?.IsPublic == true ? "public " : (getMethod?.IsAssembly == true ? "internal " : (getMethod?.IsFamily == true ? "protected " : (getMethod?.IsPrivate == true ? "private " : "")))); + if (propSetModification == propModification) propSetModification = ""; + if (propGetModification == propModification) propGetModification = ""; var pnvAttr = common.GetEntityNavigateAttribute(trytb.Type, pnv); var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); @@ -788,10 +798,10 @@ namespace FreeSql.Internal if (isLazy) { cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + .Append(" ").Append(propModification).Append(" override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); if (vp?.Item2 == true) { //get 重写 - cscode.Append(" get {\r\n") + cscode.Append(" ").Append(propGetModification).Append(" get {\r\n") .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); if (nvref.Exception == null) @@ -808,7 +818,7 @@ namespace FreeSql.Internal } if (vp?.Item3 == true) { //set 重写 - cscode.Append(" set {\r\n") + cscode.Append(" ").Append(propSetModification).Append(" set {\r\n") .Append(" base.").Append(pnv.Name).AppendLine(" = value;") .Append(" }\r\n"); } @@ -923,10 +933,10 @@ namespace FreeSql.Internal if (isLazy) { cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + .Append(" ").Append(propModification).Append(" override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); if (vp?.Item2 == true) { //get 重写 - cscode.Append(" get {\r\n") + cscode.Append(" ").Append(propGetModification).Append(" get {\r\n") .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); if (nvref.Exception == null) @@ -949,7 +959,7 @@ namespace FreeSql.Internal } if (vp?.Item3 == true) { //set 重写 - cscode.Append(" set {\r\n") + cscode.Append(" ").Append(propSetModification).Append(" set {\r\n") .Append(" base.").Append(pnv.Name).AppendLine(" = value;") .Append(" }\r\n"); } @@ -1079,10 +1089,10 @@ namespace FreeSql.Internal if (isLazy) { cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;") - .Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); + .Append(" ").Append(propModification).Append(" override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {"); if (vp?.Item2 == true) { //get 重写 - cscode.Append(" get {\r\n") + cscode.Append(" ").Append(propGetModification).Append(" get {\r\n") .Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {"); if (nvref.Exception == null) @@ -1098,7 +1108,7 @@ namespace FreeSql.Internal } if (vp?.Item3 == true) { //set 重写 - cscode.Append(" set {\r\n") + cscode.Append(" ").Append(propSetModification).Append(" set {\r\n") .Append(" base.").Append(pnv.Name).AppendLine(" = value;") .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;") .Append(" }\r\n"); From 487cefebc8200b668aa56d87dddbd9735159b725 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 22 Mar 2020 23:00:26 +0800 Subject: [PATCH 0496/1029] update readme --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 019cb666..978ee2da 100644 --- a/readme.md +++ b/readme.md @@ -36,6 +36,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ > 学习项目 +- [zhontai.net Admin后台管理系统](https://github.com/zhontai/Admin.Core) - [😃 A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) - [内容管理系统](https://github.com/hejiyong/fscms) From a8eaca9e588513ce4a0dbf566a447d97bef8cbe6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 23 Mar 2020 23:17:00 +0800 Subject: [PATCH 0497/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ConnectionPo?= =?UTF-8?q?ol=20=E6=8F=90=E5=8D=87=E8=A2=AB=E5=8A=A8=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E6=96=AD=E5=BC=80=E7=9A=84=E4=BD=93=E9=AA=8C=EF=BC=88=E4=BC=9A?= =?UTF-8?q?=E5=8D=A1=E7=9A=84=E5=8F=AF=E4=BB=A5=E5=8D=87=E7=BA=A7=EF=BC=89?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Entities/Class1.cs | 1 - FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql/FreeSql.xml | 2 +- FreeSql/FreeUtil.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 2 +- .../MsAccessAdo/MsAccessConnectionPool.cs | 2 +- .../FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs | 5 +++-- .../Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs | 2 +- .../Default/OdbcAdo/OdbcConnectionPool.cs | 2 +- .../MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs | 2 +- .../Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs | 2 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs | 2 +- .../OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs | 2 +- .../OracleAdo/OracleConnectionPool.cs | 5 +++-- .../PostgreSQLAdo/PostgreSQLConnectionPool.cs | 5 +++-- .../SqlServerAdo/SqlServerConnectionPool.cs | 5 +++-- .../SqliteAdo/SqliteConnectionPool.cs | 2 +- 17 files changed, 30 insertions(+), 20 deletions(-) delete mode 100644 Examples/base_entity/Entities/Class1.cs diff --git a/Examples/base_entity/Entities/Class1.cs b/Examples/base_entity/Entities/Class1.cs deleted file mode 100644 index 5f282702..00000000 --- a/Examples/base_entity/Entities/Class1.cs +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2735cefb..ca7c357b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index cf900d20..68ddd4ef 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1036,7 +1036,7 @@ 以字典的形式返回查询结果 - 注意:字典的特点会导致 OrderBy 排序失效 + 注意:字典的特点会导致返回的数据无序 diff --git a/FreeSql/FreeUtil.cs b/FreeSql/FreeUtil.cs index 37e928c9..79c29827 100644 --- a/FreeSql/FreeUtil.cs +++ b/FreeSql/FreeUtil.cs @@ -32,7 +32,7 @@ public static class FreeUtil var uninxtime = (int)now.Subtract(dt1970).TotalSeconds; int increment = Interlocked.Increment(ref __staticIncrement) & 0x00ffffff; var rand = rnd.Value.Next(0, int.MaxValue); - 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')}"; + var guid = $"{uninxtime.ToString("x8").PadLeft(8, '0')}{rand.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')}"; return Guid.Parse(guid); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index a9a98620..80a3ca55 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -54,7 +54,7 @@ namespace FreeSql /// /// 以字典的形式返回查询结果 - /// 注意:字典的特点会导致 OrderBy 排序失效 + /// 注意:字典的特点会导致返回的数据无序 /// /// /// diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs index b59384bc..c4d429f7 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs @@ -182,7 +182,7 @@ namespace FreeSql.MsAccess public void OnReturn(Object obj) { - if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 88479d75..5c3fa614 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -106,7 +106,8 @@ namespace FreeSql.MySql public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); + try { if (obj.State != ConnectionState.Closed) obj.Close(); } catch { } + try { MySqlConnection.ClearPool(obj as MySqlConnection); } catch { } obj.Dispose(); } @@ -176,7 +177,7 @@ namespace FreeSql.MySql public void OnReturn(Object obj) { - + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index 01fabe40..919c9d6b 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -198,7 +198,7 @@ namespace FreeSql.Odbc.Dameng public void OnReturn(Object obj) { - + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs index fb9c6a2f..3379c7b0 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -183,7 +183,7 @@ namespace FreeSql.Odbc.Default public void OnReturn(Object obj) { - if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs index 45188f84..361de661 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -176,7 +176,7 @@ namespace FreeSql.Odbc.MySql public void OnReturn(Object obj) { - + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index 04215901..cf65c0a4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -198,7 +198,7 @@ namespace FreeSql.Odbc.Oracle public void OnReturn(Object obj) { - + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index 2b36f586..4b4b0634 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -188,7 +188,7 @@ namespace FreeSql.Odbc.PostgreSQL public void OnReturn(Object obj) { - + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs index fb70774a..a66af427 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -183,7 +183,7 @@ namespace FreeSql.Odbc.SqlServer public void OnReturn(Object obj) { - if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index 9f40af14..3dc769fd 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -128,7 +128,8 @@ namespace FreeSql.Oracle public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); + try { if (obj.State != ConnectionState.Closed) obj.Close(); } catch { } + try { OracleConnection.ClearPool(obj as OracleConnection); } catch { } obj.Dispose(); } @@ -198,7 +199,7 @@ namespace FreeSql.Oracle public void OnReturn(Object obj) { - + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index 6fc4d7fe..d6d6f29f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -118,7 +118,8 @@ namespace FreeSql.PostgreSQL public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); + try { if (obj.State != ConnectionState.Closed) obj.Close(); } catch { } + try { NpgsqlConnection.ClearPool(obj as NpgsqlConnection); } catch { } obj.Dispose(); } @@ -188,7 +189,7 @@ namespace FreeSql.PostgreSQL public void OnReturn(Object obj) { - + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index a58f8940..4cba9ac5 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -111,7 +111,8 @@ namespace FreeSql.SqlServer public void OnDestroy(DbConnection obj) { - if (obj.State != ConnectionState.Closed) obj.Close(); + try { if (obj.State != ConnectionState.Closed) obj.Close(); } catch { } + try { SqlConnection.ClearPool(obj as SqlConnection); } catch { } obj.Dispose(); } @@ -181,7 +182,7 @@ namespace FreeSql.SqlServer public void OnReturn(Object obj) { - if (obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index f2275191..2ed75b19 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -204,7 +204,7 @@ namespace FreeSql.Sqlite public void OnReturn(Object obj) { - + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() From 09991bbbf02a64f8459cedfe67fb64175f8200b2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 23 Mar 2020 23:34:14 +0800 Subject: [PATCH 0498/1029] 1.3.0-preview91 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- .../MsAccessAdo/MsAccessConnectionPool.cs | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2266f5c3..98d3aabd 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 3215a4aa..b207220d 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 92aaeb4b..0a0ca4d2 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 9b7689d9..cacb4fcc 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index c5ff4f27..995c201a 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview10 + 1.3.0-preview91 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index f3ae8779..02e0fa77 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 310a95d2..8d76f73d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 35f13e7e..9c339a15 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c8887594..42dd45fe 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 7f4dcf57..96f88804 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs index c4d429f7..e27ac4af 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs @@ -182,7 +182,7 @@ namespace FreeSql.MsAccess public void OnReturn(Object obj) { - //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } } public void OnAvailable() diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index a5982827..75c7e607 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8e67ab5e..bb722d15 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 1c4ad512..500b7b44 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fee6489a..80612c90 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b1f1f6c6..5da106f4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5ec10980..732b2402 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7a76e8f2..0bd9f8f5 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview10 + 1.3.0-preview91 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From fcb33078492781ee0d39e297aee997399054fd02 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 24 Mar 2020 19:39:33 +0800 Subject: [PATCH 0499/1029] recover FreeUtil.cs --- FreeSql/FreeUtil.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/FreeUtil.cs b/FreeSql/FreeUtil.cs index 79c29827..37e928c9 100644 --- a/FreeSql/FreeUtil.cs +++ b/FreeSql/FreeUtil.cs @@ -32,7 +32,7 @@ public static class FreeUtil var uninxtime = (int)now.Subtract(dt1970).TotalSeconds; int increment = Interlocked.Increment(ref __staticIncrement) & 0x00ffffff; var rand = rnd.Value.Next(0, int.MaxValue); - var guid = $"{uninxtime.ToString("x8").PadLeft(8, '0')}{rand.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')}"; + 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')}"; return Guid.Parse(guid); } From 5e9975891ec410d16f6239e752773e583b5d5862 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 24 Mar 2020 19:40:57 +0800 Subject: [PATCH 0500/1029] 1.3.0-preview92 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 98d3aabd..9858845c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index b207220d..b8d28370 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0a0ca4d2..edf189f0 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index cacb4fcc..7557e1a9 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 995c201a..6a28e6de 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview91 + 1.3.0-preview92 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 02e0fa77..1a760a01 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8d76f73d..d4de3022 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 9c339a15..a2665658 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 42dd45fe..8f7482a2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 96f88804..835f0088 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 75c7e607..36751dcc 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index bb722d15..9af7cb62 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 500b7b44..c0f67812 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 80612c90..a0fe9baf 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 5da106f4..d819f804 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 732b2402..982baffa 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 0bd9f8f5..1027aa50 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview91 + 1.3.0-preview92 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 58aa99a6e656c3b1e42216d7c7ce6e450dacac8e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 25 Mar 2020 13:36:13 +0800 Subject: [PATCH 0501/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20Repository?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89=EF=BC=8C=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E4=B8=BA=E4=B8=80=E4=B8=AA=20IBaseRepository=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/SongController.cs | 3 +- .../BaseEntityTree.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 21 +++--- .../ContextSet/RepositoryDbContext.cs | 1 - .../Repository/ContextSet/RepositoryDbSet.cs | 8 +- .../ContextSet/RepositoryUnitOfWork.cs | 12 +-- .../Extensions/DependencyInjection.cs | 29 +++++--- .../Extensions/FreeSqlRepositoryExtensions.cs | 23 +----- .../Repository/Repository/BaseRepository.cs | 31 +++----- .../Repository/BaseRepositoryAsync.cs | 3 - .../Repository/DefaultRepository.cs | 19 ++--- .../Repository/Repository/GuidRepository.cs | 19 ----- .../Repository/Repository/IBaseRepository.cs | 74 ++++++++++++++++++- .../Repository/Repository/IBasicRepository.cs | 74 ------------------- .../Repository/IReadOnlyRepository.cs | 31 -------- 15 files changed, 134 insertions(+), 216 deletions(-) delete mode 100644 FreeSql.DbContext/Repository/Repository/GuidRepository.cs delete mode 100644 FreeSql.DbContext/Repository/Repository/IBasicRepository.cs delete mode 100644 FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs diff --git a/Examples/repository_01/Controllers/SongController.cs b/Examples/repository_01/Controllers/SongController.cs index 51d9b9c8..f64a1a8c 100644 --- a/Examples/repository_01/Controllers/SongController.cs +++ b/Examples/repository_01/Controllers/SongController.cs @@ -39,8 +39,7 @@ namespace restful.Controllers DefaultRepository repos21, BaseRepository repos3, BaseRepository repos4, - IBasicRepository repos31, IBasicRepository repos41, - IReadOnlyRepository repos311, IReadOnlyRepository repos411, + IBaseRepository repos31, IBaseRepository repos41, SongRepository reposSong ) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs index abb28109..28be88c8 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs @@ -105,7 +105,7 @@ namespace FreeSql repo.Update(buf); } - T UpdateIsDelete(bool value, Func, List, T> func) + T UpdateIsDelete(bool value, Func, List, T> func) { var childs = GetAllChilds(); childs.Add(this as TEntity); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ca7c357b..28fdb213 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -218,29 +211,35 @@ + + + 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + + + 设置 DbContext 选项 - + 清空状态数据 - + 附加实体,可用于不查询就更新或删除 - + 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 - + 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) 场景:在关闭级联保存功能之后,手工使用本方法 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 978a952b..98abccd2 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -17,7 +17,6 @@ namespace FreeSql _repo = repo; } - static ConcurrentDictionary _dicGetRepositoryDbField = new ConcurrentDictionary(); static FieldInfo GetRepositoryDbField(Type type) => _dicGetRepositoryDbField.GetOrAdd(type, tp => typeof(BaseRepository<,>).MakeGenericType(tp, typeof(int)).GetField("_dbPriv", BindingFlags.Instance | BindingFlags.NonPublic)); public override IDbSet Set(Type entityType) diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs index 195ae85a..2b33cf57 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs @@ -22,7 +22,7 @@ namespace FreeSql var filters = (_repo.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); foreach (var filter in filters) select.Where(filter.Value.Expression); - return select.AsTable(_repo.AsTableSelectInternal); + return select.AsTable(_repo.AsTableSelectValueInternal); } internal ISelect OrmSelectInternal(object dywhere) => OrmSelect(dywhere); protected override IUpdate OrmUpdate(IEnumerable entitys) @@ -37,7 +37,7 @@ namespace FreeSql throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_db.Orm.GetEntityString(_entityType, entity)}"); update.Where(filter.Value.Expression); } - return update.AsTable(_repo.AsTableInternal); + return update.AsTable(_repo.AsTableValueInternal); } internal IUpdate OrmUpdateInternal(IEnumerable entitys) => OrmUpdate(entitys); protected override IDelete OrmDelete(object dywhere) @@ -45,7 +45,7 @@ namespace FreeSql var delete = base.OrmDelete(dywhere); var filters = (_repo.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); foreach (var filter in filters) delete.Where(filter.Value.Expression); - return delete.AsTable(_repo.AsTableInternal); + return delete.AsTable(_repo.AsTableValueInternal); } internal IDelete OrmDeleteInternal(object dywhere) => OrmDelete(dywhere); protected override IInsert OrmInsert(TEntity entity) => OrmInsert(new[] { entity }); @@ -60,7 +60,7 @@ namespace FreeSql if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_db.Orm.GetEntityString(_entityType, entity)}"); } - return insert.AsTable(_repo.AsTableInternal); + return insert.AsTable(_repo.AsTableValueInternal); } internal IInsert OrmInsertInternal(TEntity entity) => OrmInsert(entity); internal IInsert OrmInsertInternal(IEnumerable entitys) => OrmInsert(entitys); diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs index 5fcebda7..e5479d93 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs @@ -13,7 +13,7 @@ namespace FreeSql /// /// 数据过滤 + 验证 /// - DefaultRepository GetRepository(Expression> filter = null) where TEntity : class; + IBaseRepository GetRepository(Expression> filter = null) where TEntity : class; /// /// 在工作单元内创建联合主键的仓储类,工作单元下的仓储操作具有事务特点 @@ -21,7 +21,7 @@ namespace FreeSql /// /// 数据过滤 + 验证 /// - BaseRepository GetRepository(Expression> filter = null) where TEntity : class; + IBaseRepository GetRepository(Expression> filter = null) where TEntity : class; /// /// 在工作单元内创建仓库类,工作单元下的仓储操作具有事务特点 @@ -30,7 +30,7 @@ namespace FreeSql /// 数据过滤 + 验证 /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository /// - GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class; + IBaseRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class; } class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork @@ -40,21 +40,21 @@ namespace FreeSql { } - public GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class + public IBaseRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class { var repo = new GuidRepository(_fsql, filter, asTable); repo.UnitOfWork = this; return repo; } - public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class + public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class { var repo = new DefaultRepository(_fsql, filter); repo.UnitOfWork = this; return repo; } - public BaseRepository GetRepository(Expression> filter = null) where TEntity : class + public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class { var repo = new DefaultRepository(_fsql, filter); repo.UnitOfWork = this; diff --git a/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs index 019684f1..e0ae86eb 100644 --- a/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs +++ b/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs @@ -1,29 +1,36 @@ #if netcoreapp -using System; -using System.Reflection; -using System.Linq; using Microsoft.Extensions.DependencyInjection; +using System; +using System.Linq; +using System.Reflection; namespace FreeSql { public static class FreeSqlRepositoryDependencyInjection { + /// + /// 批量注入 Repository,可以参考代码自行调整 + /// + /// + /// + /// + /// public static IServiceCollection AddFreeRepository(this IServiceCollection services, Action globalDataFilter = null, params Assembly[] assemblies) { + if (globalDataFilter != null) + { + DataFilterUtil._globalDataFilter = globalDataFilter; + //如果看到了这里的代码,想自己调整,但因为 _globalDataFilter 是内部属性,无法修改? + //请考虑改用 fsql.GlobalFilter.Apply + } - DataFilterUtil._globalDataFilter = globalDataFilter; - - services.AddScoped(typeof(IReadOnlyRepository<>), typeof(GuidRepository<>)); - services.AddScoped(typeof(IBasicRepository<>), typeof(GuidRepository<>)); + services.AddScoped(typeof(IBaseRepository<>), typeof(GuidRepository<>)); services.AddScoped(typeof(BaseRepository<>), typeof(GuidRepository<>)); - services.AddScoped(typeof(GuidRepository<>)); - services.AddScoped(typeof(IReadOnlyRepository<,>), typeof(DefaultRepository<,>)); - services.AddScoped(typeof(IBasicRepository<,>), typeof(DefaultRepository<,>)); + services.AddScoped(typeof(IBaseRepository<,>), typeof(DefaultRepository<,>)); services.AddScoped(typeof(BaseRepository<,>), typeof(DefaultRepository<,>)); - services.AddScoped(typeof(DefaultRepository<,>)); if (assemblies?.Any() == true) foreach (var asse in assemblies) diff --git a/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs b/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs index 9570ebdb..af4aaaaa 100644 --- a/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs +++ b/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs @@ -1,7 +1,7 @@ using FreeSql; using System; -using System.Linq.Expressions; using System.Linq; +using System.Linq.Expressions; public static class FreeSqlRepositoryExtensions { @@ -14,7 +14,7 @@ public static class FreeSqlRepositoryExtensions /// /// 数据过滤 + 验证 /// - public static DefaultRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class + public static IBaseRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { return new DefaultRepository(that, filter); } @@ -26,7 +26,7 @@ public static class FreeSqlRepositoryExtensions /// /// 数据过滤 + 验证 /// - public static BaseRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class + public static IBaseRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { return new DefaultRepository(that, filter); } @@ -39,26 +39,11 @@ public static class FreeSqlRepositoryExtensions /// 数据过滤 + 验证 /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository /// - public static GuidRepository GetGuidRepository(this IFreeSql that, Expression> filter = null, Func asTable = null) where TEntity : class + public static IBaseRepository GetGuidRepository(this IFreeSql that, Expression> filter = null, Func asTable = null) where TEntity : class { return new GuidRepository(that, filter, asTable); } - ///// - ///// 合并两个仓储的设置(过滤+分表),以便查询 - ///// - ///// - ///// - ///// - ///// - ///// - //public static ISelect FromRepository(this ISelect that, BaseRepository repos) where TEntity : class where T2 : class - //{ - // var filters = (repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - // foreach (var filter in filters) that.Where(filter.Value.Expression); - // return that.AsTable(repos.AsTableSelectInternal); - //} - /// /// 创建基于仓储功能的工作单元,务必使用 using 包含使用 /// diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index df25b35d..cc8ec1bf 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -18,19 +18,8 @@ namespace FreeSql internal RepositoryDbSet _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set() as RepositoryDbSet); public IDataFilter DataFilter { get; } = new DataFilter(); - Func _asTableVal; - protected Func AsTable - { - get => _asTableVal; - set - { - _asTableVal = value; - AsTableSelect = value == null ? null : new Func((a, b) => a == EntityType ? value(b) : null); - } - } - internal Func AsTableInternal => AsTable; - protected Func AsTableSelect { get; private set; } - internal Func AsTableSelectInternal => AsTableSelect; + internal Func AsTableValueInternal { get; private set; } + internal Func AsTableSelectValueInternal { get; private set; } protected void ApplyDataFilter(string name, Expression> exp) => DataFilter.Apply(name, exp); @@ -39,7 +28,7 @@ namespace FreeSql Orm = fsql; DataFilterUtil.SetRepositoryDataFilter(this, null); DataFilter.Apply("", filter); - AsTable = asTable; + AsTable(asTable); } ~BaseRepository() => this.Dispose(); @@ -60,6 +49,11 @@ namespace FreeSql } public Type EntityType => _dbsetPriv?.EntityType ?? typeof(TEntity); public void AsType(Type entityType) => _dbset.AsType(entityType); + public void AsTable(Func rule) + { + AsTableValueInternal = rule; + AsTableSelectValueInternal = rule == null ? null : new Func((a, b) => a == EntityType ? rule(b) : null); + } public DbContextOptions DbContextOptions { get => _db.Options; set => _db.Options = value; } public IFreeSql Orm { get; private set; } @@ -125,7 +119,7 @@ namespace FreeSql public void Attach(TEntity data) => _db.Attach(data); public void Attach(IEnumerable data) => _db.AttachRange(data); - public IBasicRepository AttachOnlyPrimary(TEntity data) + public IBaseRepository AttachOnlyPrimary(TEntity data) { _db.AttachOnlyPrimary(data); return this; @@ -149,10 +143,7 @@ namespace FreeSql public abstract partial class BaseRepository : BaseRepository, IBaseRepository where TEntity : class { - - public BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base(fsql, filter, asTable) - { - } + public BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base(fsql, filter, asTable) { } TEntity CheckTKeyAndReturnIdEntity(TKey id) { @@ -167,9 +158,7 @@ namespace FreeSql } public int Delete(TKey id) => Delete(CheckTKeyAndReturnIdEntity(id)); - public TEntity Find(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); - public TEntity Get(TKey id) => Find(id); } } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs index d29433eb..c3e5dd42 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs @@ -73,11 +73,8 @@ namespace FreeSql partial class BaseRepository { - public Task DeleteAsync(TKey id) => DeleteAsync(CheckTKeyAndReturnIdEntity(id)); - public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(); - public Task GetAsync(TKey id) => FindAsync(id); } } diff --git a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs index a1f69e07..6f36a3dc 100644 --- a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs @@ -3,18 +3,15 @@ using System.Linq.Expressions; namespace FreeSql { - public class DefaultRepository : - BaseRepository - where TEntity : class + public class DefaultRepository : BaseRepository where TEntity : class { + public DefaultRepository(IFreeSql fsql) : base(fsql, null, null) { } + public DefaultRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter, null) { } + } - public DefaultRepository(IFreeSql fsql) : base(fsql, null, null) - { - - } - - public DefaultRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter, null) - { - } + public class GuidRepository : BaseRepository where TEntity : class + { + public GuidRepository(IFreeSql fsql) : this(fsql, null, null) { } + public GuidRepository(IFreeSql fsql, Expression> filter, Func asTable) : base(fsql, filter, asTable) { } } } diff --git a/FreeSql.DbContext/Repository/Repository/GuidRepository.cs b/FreeSql.DbContext/Repository/Repository/GuidRepository.cs deleted file mode 100644 index 1025f961..00000000 --- a/FreeSql.DbContext/Repository/Repository/GuidRepository.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Linq.Expressions; - -namespace FreeSql -{ - public class GuidRepository : - BaseRepository - where TEntity : class - { - - public GuidRepository(IFreeSql fsql) : this(fsql, null, null) - { - - } - public GuidRepository(IFreeSql fsql, Expression> filter, Func asTable) : base(fsql, filter, asTable) - { - } - } -} diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index 5ea1f28b..e172073f 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq.Expressions; using System.Threading.Tasks; @@ -17,6 +18,11 @@ namespace FreeSql /// /// void AsType(Type entityType); + /// + /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + /// + /// + void AsTable(Func rule); /// /// 设置 DbContext 选项 @@ -24,19 +30,83 @@ namespace FreeSql DbContextOptions DbContextOptions { get; set; } } - public interface IBaseRepository : IReadOnlyRepository, IBasicRepository + public interface IBaseRepository : IBaseRepository where TEntity : class { + IDataFilter DataFilter { get; } + ISelect Select { get; } + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + TEntity Insert(TEntity entity); + List Insert(IEnumerable entitys); + + /// + /// 清空状态数据 + /// + void FlushState(); + /// + /// 附加实体,可用于不查询就更新或删除 + /// + /// + void Attach(TEntity entity); + void Attach(IEnumerable entity); + /// + /// 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 + /// + /// + IBaseRepository AttachOnlyPrimary(TEntity data); + + int Update(TEntity entity); + int Update(IEnumerable entitys); + + TEntity InsertOrUpdate(TEntity entity); + /// + /// 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) + /// 场景:在关闭级联保存功能之后,手工使用本方法 + /// 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus") + /// 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据 + /// 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录 + /// + /// 实体对象 + /// 属性名 + void SaveMany(TEntity entity, string propertyName); + + IUpdate UpdateDiy { get; } + + int Delete(TEntity entity); + int Delete(IEnumerable entitys); int Delete(Expression> predicate); #if net40 #else + Task InsertAsync(TEntity entity); + Task> InsertAsync(IEnumerable entitys); + + Task UpdateAsync(TEntity entity); + Task UpdateAsync(IEnumerable entitys); + Task InsertOrUpdateAsync(TEntity entity); + Task SaveManyAsync(TEntity entity, string propertyName); + + Task DeleteAsync(TEntity entity); + Task DeleteAsync(IEnumerable entitys); Task DeleteAsync(Expression> predicate); #endif } - public interface IBaseRepository : IBaseRepository, IReadOnlyRepository, IBasicRepository + public interface IBaseRepository : IBaseRepository where TEntity : class { + TEntity Get(TKey id); + TEntity Find(TKey id); + int Delete(TKey id); + +#if net40 +#else + Task GetAsync(TKey id); + Task FindAsync(TKey id); + Task DeleteAsync(TKey id); +#endif } } \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs deleted file mode 100644 index b0b4f804..00000000 --- a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace FreeSql -{ - public interface IBasicRepository : IReadOnlyRepository - where TEntity : class - { - TEntity Insert(TEntity entity); - List Insert(IEnumerable entitys); - - /// - /// 清空状态数据 - /// - void FlushState(); - /// - /// 附加实体,可用于不查询就更新或删除 - /// - /// - void Attach(TEntity entity); - void Attach(IEnumerable entity); - /// - /// 附加实体,并且只附加主键值,可用于不更新属性值为null或默认值的字段 - /// - /// - IBasicRepository AttachOnlyPrimary(TEntity data); - - int Update(TEntity entity); - int Update(IEnumerable entitys); - - TEntity InsertOrUpdate(TEntity entity); - /// - /// 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) - /// 场景:在关闭级联保存功能之后,手工使用本方法 - /// 例子:保存商品的 OneToMany 集合属性,SaveMany(goods, "Skus") - /// 当 goods.Skus 为空(非null)时,会删除表中已存在的所有数据 - /// 当 goods.Skus 不为空(非null)时,添加/更新后,删除表中不存在 Skus 集合属性的所有记录 - /// - /// 实体对象 - /// 属性名 - void SaveMany(TEntity entity, string propertyName); - - IUpdate UpdateDiy { get; } - - int Delete(TEntity entity); - int Delete(IEnumerable entitys); - -#if net40 -#else - Task InsertAsync(TEntity entity); - Task> InsertAsync(IEnumerable entitys); - - Task UpdateAsync(TEntity entity); - Task UpdateAsync(IEnumerable entitys); - Task InsertOrUpdateAsync(TEntity entity); - Task SaveManyAsync(TEntity entity, string propertyName); - - Task DeleteAsync(TEntity entity); - Task DeleteAsync(IEnumerable entitys); -#endif - } - - public interface IBasicRepository : IBasicRepository, IReadOnlyRepository - where TEntity : class - { - int Delete(TKey id); - -#if net40 -#else - Task DeleteAsync(TKey id); -#endif - } -} - diff --git a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs b/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs deleted file mode 100644 index bd96458f..00000000 --- a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - public interface IReadOnlyRepository : IBaseRepository - where TEntity : class - { - - IDataFilter DataFilter { get; } - - ISelect Select { get; } - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - } - - public interface IReadOnlyRepository : IReadOnlyRepository - where TEntity : class - { - TEntity Get(TKey id); - TEntity Find(TKey id); - -#if net40 -#else - Task GetAsync(TKey id); - Task FindAsync(TKey id); -#endif - } -} From ff61607e01f72676bbf21341941c52c013605a4d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Mar 2020 23:43:25 +0800 Subject: [PATCH 0502/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E9=9B=86?= =?UTF-8?q?=E5=90=88=E5=AF=BC=E8=88=AA=E5=B1=9E=E6=80=A7=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E4=B8=AD=E5=BF=98=E8=AE=B0=E4=BD=BF=E7=94=A8=20AsSele?= =?UTF-8?q?ct()=20=E7=9A=84=E5=8F=8B=E5=A5=BD=E9=94=99=E8=AF=AF=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 3 - FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 60 +++++-- FreeSql/FreeSql.xml | 147 +----------------- FreeSql/Internal/CommonExpression.cs | 3 + .../MsAccessExpression.cs | 1 + .../FreeSql.Provider.MySql/MySqlExpression.cs | 1 + .../Dameng/OdbcDamengExpression.cs | 1 + .../Default/OdbcExpression.cs | 1 + .../MySql/OdbcMySqlExpression.cs | 1 + .../Oracle/OdbcOracleExpression.cs | 1 + .../SqlServer/OdbcSqlServerExpression.cs | 1 + .../OracleExpression.cs | 1 + .../SqlServerExpression.cs | 1 + .../SqliteExpression.cs | 1 + readme.md | 2 +- 15 files changed, 60 insertions(+), 165 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index bc70c511..f7df0e51 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -550,7 +550,6 @@ namespace FreeSql.Tests - var gkjdjd = g.sqlite.Select().Where(a => a.Post.AsSelect().Count() > 0).ToList(); var testrunsql1 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); @@ -892,8 +891,6 @@ namespace FreeSql.Tests - - var ttt1 = g.sqlite.Select().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList(); diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 81668363..546f8c22 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -51,18 +51,15 @@ public static partial class FreeSqlGlobalExtensions /// /// 获取 Type 的原始 c# 文本表示 /// - /// + /// /// - public static string DisplayCsharp(this Type that) + internal static string DisplayCsharp(this Type type, bool isNameSpace = true) { - return DisplayCsharp(that, true); - } - static string DisplayCsharp(this Type that, bool isNameSpace) - { - if (that == typeof(void)) return "void"; - if (that.IsGenericParameter) return that.Name; + if (type == null) return null; + if (type == typeof(void)) return "void"; + if (type.IsGenericParameter) return type.Name; var sb = new StringBuilder(); - var nestedType = that; + var nestedType = type; while (nestedType.IsNested) { sb.Insert(0, ".").Insert(0, DisplayCsharp(nestedType.DeclaringType, false)); @@ -71,22 +68,22 @@ public static partial class FreeSqlGlobalExtensions if (isNameSpace && string.IsNullOrEmpty(nestedType.Namespace) == false) sb.Insert(0, ".").Insert(0, nestedType.Namespace); - if (that.IsGenericType == false) - return sb.Append(that.Name).ToString(); + if (type.IsGenericType == false) + return sb.Append(type.Name).ToString(); - var genericParameters = that.GetGenericArguments(); - if (that.IsNested && that.DeclaringType.IsGenericType) + var genericParameters = type.GetGenericArguments(); + if (type.IsNested && type.DeclaringType.IsGenericType) { var dic = genericParameters.ToDictionary(a => a.Name); - foreach (var nestedGenericParameter in that.DeclaringType.GetGenericArguments()) + foreach (var nestedGenericParameter in type.DeclaringType.GetGenericArguments()) if (dic.ContainsKey(nestedGenericParameter.Name)) dic.Remove(nestedGenericParameter.Name); genericParameters = dic.Values.ToArray(); } if (genericParameters.Any() == false) - return sb.Append(that.Name).ToString(); + return sb.Append(type.Name).ToString(); - sb.Append(that.Name.Remove(that.Name.IndexOf('`'))).Append("<"); + sb.Append(type.Name.Remove(type.Name.IndexOf('`'))).Append("<"); var genericTypeIndex = 0; foreach (var genericType in genericParameters) { @@ -95,6 +92,37 @@ public static partial class FreeSqlGlobalExtensions } return sb.Append(">").ToString(); } + internal static string DisplayCsharp(this MethodInfo method, bool isOverride) + { + if (method == null) return null; + var sb = new StringBuilder(); + if (method.IsPublic) sb.Append("public "); + if (method.IsAssembly) sb.Append("internal "); + if (method.IsFamily) sb.Append("protected "); + if (method.IsPrivate) sb.Append("private "); + if (method.IsPrivate) sb.Append("private "); + if (method.IsStatic) sb.Append("static "); + if (method.IsAbstract && method.DeclaringType.IsInterface == false) sb.Append("abstract "); + if (method.IsVirtual && method.DeclaringType.IsInterface == false) sb.Append(isOverride ? "override " : "virtual "); + sb.Append(method.ReturnType.DisplayCsharp()).Append(" ").Append(method.Name); + + var genericParameters = method.GetGenericArguments(); + if (method.DeclaringType.IsNested && method.DeclaringType.DeclaringType.IsGenericType) + { + var dic = genericParameters.ToDictionary(a => a.Name); + foreach (var nestedGenericParameter in method.DeclaringType.DeclaringType.GetGenericArguments()) + if (dic.ContainsKey(nestedGenericParameter.Name)) + dic.Remove(nestedGenericParameter.Name); + genericParameters = dic.Values.ToArray(); + } + if (genericParameters.Any()) + sb.Append("<") + .Append(string.Join(", ", genericParameters.Select(a => a.DisplayCsharp()))) + .Append(">"); + + sb.Append("(").Append(string.Join(", ", method.GetParameters().Select(a => $"{a.ParameterType.DisplayCsharp()} {a.Name}"))).Append(")"); + return sb.ToString(); + } public static object CreateInstanceGetDefaultValue(this Type that) { if (that == null) return null; diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 68ddd4ef..e63a0ae4 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2285,137 +2285,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2939,12 +2808,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3015,12 +2878,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3194,11 +3051,11 @@ - + 获取 Type 的原始 c# 文本表示 - + diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index d7f48fdf..5493f699 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1021,6 +1021,7 @@ namespace FreeSql.Internal other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); + if (exp3.Method.DeclaringType == typeof(Enumerable)) throw new Exception($"未实现函数表达式 {exp3} 解析。如果正在操作导航属性集合,请使用 .AsSelect().{exp3.Method.Name}({(exp3.Arguments.Count > 1 ? "..." : "")})"); throw new Exception($"未实现函数表达式 {exp3} 解析"); case ExpressionType.Parameter: case ExpressionType.MemberAccess: @@ -1292,6 +1293,8 @@ namespace FreeSql.Internal } if (tb2.ColumnsByCsIgnore.ContainsKey(mp2.Member.Name)) throw new ArgumentException($"{tb2.DbName}.{mp2.Member.Name} 被忽略,请检查 IsIgnore 设置,确认 get/set 为 public"); + if (tb2.GetTableRef(mp2.Member.Name, false) != null) + throw new ArgumentException($"{tb2.DbName}.{mp2.Member.Name} 导航属性集合忘了 .AsSelect() 吗?如果在 ToList(a => a.{mp2.Member.Name}) 中使用,请移步参考 IncludeMany 文档。"); throw new ArgumentException($"{tb2.DbName} 找不到列 {mp2.Member.Name}"); } var col2 = tb2.ColumnsByCs[mp2.Member.Name]; diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs index 53fbb008..2692b868 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -74,6 +74,7 @@ namespace FreeSql.MsAccess if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 8df2fa3b..d7339eac 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -101,6 +101,7 @@ namespace FreeSql.MySql if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index 03468326..11604c98 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -105,6 +105,7 @@ namespace FreeSql.Odbc.Dameng if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs index fba05ba0..df861404 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -108,6 +108,7 @@ namespace FreeSql.Odbc.Default if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 5201379c..3fdf6e2a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -101,6 +101,7 @@ namespace FreeSql.Odbc.MySql if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index d55cd439..d09da364 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -105,6 +105,7 @@ namespace FreeSql.Odbc.Oracle if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index e44aa42d..dcbdfec7 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -105,6 +105,7 @@ namespace FreeSql.Odbc.SqlServer if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index fc0d0885..5169f563 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -105,6 +105,7 @@ namespace FreeSql.Oracle if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 58e9c669..8aba97e0 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -105,6 +105,7 @@ namespace FreeSql.SqlServer if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 81108e95..325aa535 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -101,6 +101,7 @@ namespace FreeSql.Sqlite if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) { + if (argIndex >= callExp.Arguments.Count) break; tsc.SetMapColumnTmp(null); var args1 = getExp(callExp.Arguments[argIndex]); var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); diff --git a/readme.md b/readme.md index 978ee2da..2e6b3bec 100644 --- a/readme.md +++ b/readme.md @@ -206,7 +206,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元 > Thank you for your donation From 7229c08d0dc9f0b512c4ef97f68d9a934ebc9504 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Mar 2020 16:26:59 +0800 Subject: [PATCH 0503/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E5=8C=BA=E5=9F=9F=E5=8C=96=E5=90=8E=20ToSql=20?= =?UTF-8?q?=E4=BA=A7=E7=94=9F=E7=9A=84=E9=94=99=E8=AF=AF=EF=BC=8C=E6=AF=94?= =?UTF-8?q?=E5=A6=82=E6=95=B0=E5=AD=97=E5=8F=AF=E8=83=BD=E7=94=9F=E6=88=90?= =?UTF-8?q?=20SQL=20=E4=B8=BA=EF=BC=9A100,000=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql/FreeSql.xml | 143 ++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 4 +- .../AdoProvider/AdoProviderUtils.cs | 3 +- 4 files changed, 155 insertions(+), 2 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 28fdb213..d8bba58b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e63a0ae4..17e209b4 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2285,6 +2285,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 }) + + + + + + 可自定义解析表达式 @@ -2808,6 +2939,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2878,6 +3015,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 5493f699..93e78a51 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -11,6 +11,7 @@ using System.Text; using System.Text.RegularExpressions; using FreeSql.DataAnnotations; using System.Threading; +using System.Globalization; namespace FreeSql.Internal { @@ -1501,7 +1502,8 @@ namespace FreeSql.Internal mapType ?? mapColumn?.Attribute.MapType ?? obj?.GetType(), mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj)); return _common.QuoteParamterName(paramName); } - return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn)); + return string.Format(CultureInfo.InvariantCulture, "{0}", _ado.AddslashesProcessParam(obj, mapType, mapColumn)); + //return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn)); } } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs index 9edce10c..a8b1d542 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using System.Collections.Concurrent; +using System.Globalization; using System.Text; using System.Text.RegularExpressions; @@ -22,7 +23,7 @@ namespace FreeSql.Internal.CommonProvider .Replace(filter, $" IS {{{a}}}"); nparms[a] = AddslashesProcessParam(parms[a], null, null); } - try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; } + try { string ret = string.Format(CultureInfo.InvariantCulture, filter, nparms); return ret; } catch { return filter; } } static ConcurrentDictionary _dicAddslashesReplaceIsNull = new ConcurrentDictionary(); From 6fbdbe3327fbd58e8bfd1bb22d01e7a1eb3d5683 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Mar 2020 16:51:28 +0800 Subject: [PATCH 0504/1029] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=20StringLength?= =?UTF-8?q?/MaxLength=20=E5=AF=B9=20Oracle=20varchar2=20=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=97=A0=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- .../MySqlConnector/MySqlCodeFirstTest.cs | 13 +++++++++++++ .../Dameng/DamengCodeFirstTest.cs | 12 ++++++++++++ .../Default/OdbcCodeFirstTest.cs | 1 + .../MySql/MySqlCodeFirstTest.cs | 13 +++++++++++++ .../Oracle/OracleCodeFirstTest.cs | 12 ++++++++++++ .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 12 ++++++++++++ .../SqlServer/SqlServerCodeFirstTest.cs | 13 +++++++++++++ .../FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs | 12 ++++++++++++ .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 12 ++++++++++++ .../FreeSql.Tests/Oracle/OracleCodeFirstTest.cs | 12 ++++++++++++ .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 12 ++++++++++++ .../SqlServer/SqlServerCodeFirstTest.cs | 12 ++++++++++++ .../FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs | 12 ++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 2 +- 15 files changed, 149 insertions(+), 8 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d8bba58b..28fdb213 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 86460dce..329b4e61 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -10,6 +10,19 @@ namespace FreeSql.Tests.MySqlConnector { public class MySqlCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } + [Fact] public void е() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index b5ba4461..44718c65 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -10,6 +10,18 @@ namespace FreeSql.Tests.Odbc.Dameng { public class DamengCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.dameng.CodeFirst.GetComparisonDDLStatements(); + g.dameng.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs index e04d5d40..1859e308 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs @@ -11,6 +11,7 @@ namespace FreeSql.Tests.Odbc.Default public class OdbcCodeFirstTest { + [Fact] public void 中文表_字段() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index 6c52d3ae..d0657318 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -10,6 +10,19 @@ namespace FreeSql.Tests.Odbc.MySql { public class MySqlCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } + [Fact] public void е() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs index 2ae10e27..37482571 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -10,6 +10,18 @@ namespace FreeSql.Tests.Odbc.Oracle { public class OracleCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.oracle.CodeFirst.GetComparisonDDLStatements(); + g.oracle.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs index 96a926fd..320146c0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -14,6 +14,18 @@ namespace FreeSql.Tests.Odbc.PostgreSQL { public class PostgreSQLCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index 355854b2..ef642d6b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -12,6 +12,19 @@ namespace FreeSql.Tests.Odbc.SqlServer [Collection("SqlServerCollection")] public class SqlServerCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + g.sqlserver.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } + [Fact] public void ı_ֶ() { diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs index bd27dc0c..ceeca39b 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -10,6 +10,18 @@ namespace FreeSql.Tests.MsAccess { public class MsAccessCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.msaccess.CodeFirst.GetComparisonDDLStatements(); + g.msaccess.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index ad7efc27..1c3cd9ed 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -10,6 +10,18 @@ namespace FreeSql.Tests.MySql { public class MySqlCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void е() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index f1eeab72..959a9b96 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -10,6 +10,18 @@ namespace FreeSql.Tests.Oracle { public class OracleCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.oracle.CodeFirst.GetComparisonDDLStatements(); + g.oracle.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index 75cd98d8..f131c212 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -17,6 +17,18 @@ namespace FreeSql.Tests.PostgreSQL { public class PostgreSQLCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index b86c0e2f..f3e55e01 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -11,6 +11,18 @@ namespace FreeSql.Tests.SqlServer { public class SqlServerCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + g.sqlserver.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void ı_ֶ() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index 1d48cb21..12073a43 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -10,6 +10,18 @@ namespace FreeSql.Tests.Sqlite { public class SqliteCodeFirstTest { + [Fact] + public void StringLength() + { + var dll = g.sqlite.CodeFirst.GetComparisonDDLStatements(); + g.sqlite.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + } [Fact] public void е() diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index d9dc1840..ffb1dfb8 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -204,7 +204,7 @@ namespace FreeSql.Internal if (colattr.MapType == typeof(string) && colattr.StringLength != 0) { int strlen = colattr.StringLength; - var charPatten = @"(CHAR|CHAR2|CHARACTER)\s*(\([^\)]*\))?"; + var charPatten = @"(CHARACTER|CHAR2|CHAR)\s*(\([^\)]*\))?"; switch (common._orm.Ado.DataType) { case DataType.MySql: From d4e73641a4c076c966e53b7084fc5118ab1adbae Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Mar 2020 16:53:23 +0800 Subject: [PATCH 0505/1029] 1.3.0-preview93 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 9858845c..38c26c3f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index b8d28370..19c97d87 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index edf189f0..cd56ee09 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7557e1a9..38e76bc8 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 6a28e6de..f4093450 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview92 + 1.3.0-preview93 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 1a760a01..94cf7d0d 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d4de3022..d8d87f6f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 28fdb213..ddd18378 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -204,6 +211,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index a2665658..9233fde0 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8f7482a2..01a065f1 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 835f0088..3606e581 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 36751dcc..1e666af8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 9af7cb62..068d7466 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c0f67812..cb386f9d 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a0fe9baf..57897586 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d819f804..ca1aa60f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 982baffa..676627e7 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 1027aa50..a93fff69 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview92 + 1.3.0-preview93 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From dbc323a22c2240d4dce9515bff6ac30483fafadd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Mar 2020 17:35:59 +0800 Subject: [PATCH 0506/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20CodeFirst=20?= =?UTF-8?q?IsNullable=20=E8=BF=81=E7=A7=BB=E8=84=9A=E6=9C=AC=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=20NOT=20NULL=20=E8=AF=AD=E6=B3=95=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlCodeFirstTest.cs | 3 +++ .../FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs | 3 +++ .../FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs | 3 +++ .../FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs | 3 +++ .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 3 +++ .../SqlServer/SqlServerCodeFirstTest.cs | 3 +++ FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs | 3 +++ FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 3 +++ FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs | 3 +++ .../FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs | 3 +++ .../FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs | 3 +++ FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs | 3 +++ FreeSql/Internal/UtilsExpressionTree.cs | 2 +- 13 files changed, 37 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 329b4e61..a00a399b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -21,6 +21,9 @@ namespace FreeSql.Tests.MySqlConnector public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index 44718c65..98e1eeea 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -21,6 +21,9 @@ namespace FreeSql.Tests.Odbc.Dameng public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index d0657318..ebc6c398 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -21,6 +21,9 @@ namespace FreeSql.Tests.Odbc.MySql public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs index 37482571..ef9c6147 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -21,6 +21,9 @@ namespace FreeSql.Tests.Odbc.Oracle public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs index 320146c0..179a66d8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -25,6 +25,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index ef642d6b..1eb1d44a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -23,6 +23,9 @@ namespace FreeSql.Tests.Odbc.SqlServer public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs index ceeca39b..826cb13b 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -21,6 +21,9 @@ namespace FreeSql.Tests.MsAccess public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 1c3cd9ed..b3ccdd26 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -21,6 +21,9 @@ namespace FreeSql.Tests.MySql public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 959a9b96..8e7d09c8 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -21,6 +21,9 @@ namespace FreeSql.Tests.Oracle public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index f131c212..700f2d6d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -28,6 +28,9 @@ namespace FreeSql.Tests.PostgreSQL public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index f3e55e01..368eddf8 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -22,6 +22,9 @@ namespace FreeSql.Tests.SqlServer public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index 12073a43..03b30986 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -21,6 +21,9 @@ namespace FreeSql.Tests.Sqlite public Guid Id { get; set; } [Column(StringLength = 50)] public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } } [Fact] diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index ffb1dfb8..efdb4a8a 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -124,7 +124,7 @@ namespace FreeSql.Internal if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) { colattr.IsNullable = false; - colattr.DbType += " NOT NULL"; + colattr.DbType = Regex.Replace(colattr.DbType, @"\bNULL\b", "").Trim() + " NOT NULL"; } if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", ""); colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => From f9c1003e813129aabe8aaf1acc99f6e52291cc60 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Mar 2020 17:37:30 +0800 Subject: [PATCH 0507/1029] 1.3.0-preview94 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 38c26c3f..0e8058c5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 19c97d87..10b60dae 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index cd56ee09..1c80fabf 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 38e76bc8..5e8a5abf 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index f4093450..95c4345a 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview93 + 1.3.0-preview94 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 94cf7d0d..3b7c2958 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d8d87f6f..ce859c0c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 9233fde0..c3123b08 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 01a065f1..4f3394e9 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 3606e581..440f5ebc 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 1e666af8..288cfa5e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 068d7466..3ca38b39 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index cb386f9d..8d94a71b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 57897586..2114a38c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ca1aa60f..61246b5f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 676627e7..8381e630 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a93fff69..95288501 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview93 + 1.3.0-preview94 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From dc625218d64e498beebaf193793616b584db3191 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Mar 2020 18:41:11 +0800 Subject: [PATCH 0508/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ToTreeList?= =?UTF-8?q?=20=E7=9A=84=E9=97=AE=E9=A2=98=20#255?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ----- .../MySqlConnector/Curd/MySqlSelectTest.cs | 39 +++++++++++++++++++ .../Dameng/Curd/DamengSelectTest.cs | 39 +++++++++++++++++++ .../Default/Curd/OdbcSelectTest.cs | 39 +++++++++++++++++++ .../MySql/Curd/MySqlSelectTest.cs | 39 +++++++++++++++++++ .../Oracle/Curd/OracleSelectTest.cs | 39 +++++++++++++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 39 +++++++++++++++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 39 +++++++++++++++++++ .../MsAccess/Curd/MsAccessSelectTest.cs | 39 +++++++++++++++++++ .../MySql/Curd/MySqlSelectTest.cs | 39 +++++++++++++++++++ .../Oracle/Curd/OracleSelectTest.cs | 39 +++++++++++++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 39 +++++++++++++++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 39 +++++++++++++++++++ .../Sqlite/Curd/SqliteSelectTest.cs | 39 +++++++++++++++++++ .../SelectProvider/Select1Provider.cs | 4 +- 15 files changed, 509 insertions(+), 11 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..d8bba58b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,15 +211,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 4fc799af..b1881760 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -250,6 +250,45 @@ namespace FreeSql.Tests.MySqlConnector var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.mysql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.mysql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 0c314b52..f4ab9a5b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -191,6 +191,45 @@ namespace FreeSql.Tests.Odbc.Dameng var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.dameng.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.dameng.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index edb5cb2d..9e404f0f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -182,6 +182,45 @@ namespace FreeSql.Tests.Odbc.Default var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.odbc.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.odbc.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.odbc.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 945f877d..04c11f44 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -291,6 +291,45 @@ namespace FreeSql.Tests.Odbc.MySql var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.mysql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.mysql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 065806e6..f003c4cf 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -191,6 +191,45 @@ namespace FreeSql.Tests.Odbc.Oracle var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.oracle.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.oracle.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index bb1db718..38514d5c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -267,6 +267,45 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.pgsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.pgsql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 3ac1ed9b..b868dc81 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -181,6 +181,45 @@ namespace FreeSql.Tests.Odbc.SqlServer var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.sqlserver.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.sqlserver.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index 71636cca..aa03e685 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -182,6 +182,45 @@ namespace FreeSql.Tests.MsAccess var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.msaccess.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.msaccess.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.msaccess.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 4a419368..86e92f50 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -291,6 +291,45 @@ namespace FreeSql.Tests.MySql var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.mysql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.mysql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index c12ba6ee..2c3c2928 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -191,6 +191,45 @@ namespace FreeSql.Tests.Oracle var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.oracle.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.oracle.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 346ab34a..f1a5ff31 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -267,6 +267,45 @@ namespace FreeSql.Tests.PostgreSQL var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.pgsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.pgsql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index d8c8a698..11d570b7 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -191,6 +191,45 @@ namespace FreeSql.Tests.SqlServer var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.sqlserver.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.sqlserver.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index d7bb93e1..9414c910 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -208,6 +208,45 @@ namespace FreeSql.Tests.Sqlite var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.sqlite.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.sqlite.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Equal(1, ddd.Count); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } } [Fact] public void ToDictionary() diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 2629c519..ef0dcfeb 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -712,7 +712,7 @@ namespace FreeSql.Internal.CommonProvider string key = null; if (tbref.RefColumns.Count == 1) { - key = _orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[0].CsName).ToString(); + key = _orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[0].CsName)?.ToString() ?? ""; } else { @@ -1043,7 +1043,7 @@ namespace FreeSql.Internal.CommonProvider { string key = null; if (tbref.Columns.Count == 1) - key = _orm.GetEntityValueWithPropertyName(tbref.RefMiddleEntityType, midList[a], tbref.MiddleColumns[0].CsName).ToString(); + key = _orm.GetEntityValueWithPropertyName(tbref.RefMiddleEntityType, midList[a], tbref.MiddleColumns[0].CsName)?.ToString() ?? ""; else { var sb = new StringBuilder(); From e245543c5aa0c8b47984a104cfc7b2d4da4e69ba Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 27 Mar 2020 18:43:09 +0800 Subject: [PATCH 0509/1029] 1.3.0-preview95 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 26 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 0e8058c5..abe6aea5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 10b60dae..aca7b12e 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 1c80fabf..5552709b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5e8a5abf..531ee0a4 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 95c4345a..fc4dd2f3 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview94 + 1.3.0-preview95 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3b7c2958..18611710 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ce859c0c..23904f42 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d8bba58b..ddd18378 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,6 +211,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c3123b08..9baf0631 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4f3394e9..f170405f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 440f5ebc..11b22469 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 288cfa5e..252071f2 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 3ca38b39..07f754d5 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 8d94a71b..c184bf3b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2114a38c..4b3dd535 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 61246b5f..c95ad4d3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 8381e630..f1b8f104 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 95288501..a4aafb71 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview94 + 1.3.0-preview95 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From a6eae955edfbd5fe834cb19d4720e0e3088ff2bf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 28 Mar 2020 15:29:39 +0800 Subject: [PATCH 0510/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IAdo.Connect?= =?UTF-8?q?ionString=20=E5=B1=9E=E6=80=A7=E8=BF=94=E5=9B=9E=20UseConnectio?= =?UTF-8?q?nString=20=E4=BC=A0=E5=85=A5=E7=9A=84=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 10 ++++++++++ FreeSql/Interface/IAdo.cs | 8 ++++++++ .../Internal/CommonProvider/AdoProvider/AdoProvider.cs | 6 +++++- .../MsAccessAdo/MsAccessAdo.cs | 4 ++-- Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs | 4 ++-- .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 4 ++-- .../FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs | 4 ++-- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 4 ++-- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 4 ++-- .../PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 4 ++-- .../SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 4 ++-- .../FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs | 4 ++-- .../PostgreSQLAdo/PostgreSQLAdo.cs | 4 ++-- .../SqlServerAdo/SqlServerAdo.cs | 4 ++-- .../FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs | 4 ++-- 15 files changed, 47 insertions(+), 25 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 17e209b4..1a5086ea 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2128,6 +2128,16 @@ 数据库类型 + + + UseConnectionString 时候的值 + + + + + UseSalve 时候的值 + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index d5ec0a8c..2cb27f7b 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -24,6 +24,14 @@ namespace FreeSql /// 数据库类型 /// DataType DataType { get; } + /// + /// UseConnectionString 时候的值 + /// + string ConnectionString { get; } + /// + /// UseSalve 时候的值 + /// + string[] SlaveConnectionStrings { get; } #region 事务 /// diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 07d785ca..a5ebb8db 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -24,14 +24,18 @@ namespace FreeSql.Internal.CommonProvider public IObjectPool MasterPool { get; protected set; } public List> SlavePools { get; } = new List>(); public DataType DataType { get; } + public string ConnectionString { get; } + public string[] SlaveConnectionStrings { get; } protected CommonUtils _util { get; set; } protected int slaveUnavailables = 0; private object slaveLock = new object(); private Random slaveRandom = new Random(); - public AdoProvider(DataType dataType) + public AdoProvider(DataType dataType, string connectionString, string[] slaveConnectionStrings) { this.DataType = dataType; + this.ConnectionString = connectionString; + this.SlaveConnectionStrings = slaveConnectionStrings; } void LoggerException(IObjectPool pool, PrepareCommandResult pc, Exception ex, DateTime dt, StringBuilder logtxt, bool isThrowException = true) diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs index 195dbb9d..496e9d1e 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs @@ -13,8 +13,8 @@ namespace FreeSql.MsAccess { class MsAccessAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public MsAccessAdo() : base(DataType.MsAccess) { } - public MsAccessAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.MsAccess) + public MsAccessAdo() : base(DataType.MsAccess, null, null) { } + public MsAccessAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.MsAccess, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index d6df8d17..2eeaa75b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -13,8 +13,8 @@ namespace FreeSql.MySql class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public MySqlAdo() : base(DataType.MySql) { } - public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.MySql) + public MySqlAdo() : base(DataType.MySql, null, null) { } + public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.MySql, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index f485abe1..71547169 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -12,8 +12,8 @@ namespace FreeSql.Odbc.Dameng { class OdbcDamengAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcDamengAdo() : base(DataType.OdbcDameng) { } - public OdbcDamengAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcDameng) + public OdbcDamengAdo() : base(DataType.OdbcDameng, null, null) { } + public OdbcDamengAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcDameng, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index f11b8b10..eb17053b 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -12,8 +12,8 @@ namespace FreeSql.Odbc.Default { class OdbcAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcAdo() : base(DataType.Odbc) { } - public OdbcAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Odbc) + public OdbcAdo() : base(DataType.Odbc, null, null) { } + public OdbcAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Odbc, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 94921b95..41aa2ed3 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -13,8 +13,8 @@ namespace FreeSql.Odbc.MySql class OdbcMySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcMySqlAdo() : base(DataType.OdbcMySql) { } - public OdbcMySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcMySql) + public OdbcMySqlAdo() : base(DataType.OdbcMySql, null, null) { } + public OdbcMySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcMySql, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index bb33aa87..699f2912 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -12,8 +12,8 @@ namespace FreeSql.Odbc.Oracle { class OdbcOracleAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcOracleAdo() : base(DataType.OdbcOracle) { } - public OdbcOracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcOracle) + public OdbcOracleAdo() : base(DataType.OdbcOracle, null, null) { } + public OdbcOracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcOracle, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index 60361f3e..d37dc5ba 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -13,8 +13,8 @@ namespace FreeSql.Odbc.PostgreSQL { class OdbcPostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcPostgreSQLAdo() : base(DataType.OdbcPostgreSQL) { } - public OdbcPostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcPostgreSQL) + public OdbcPostgreSQLAdo() : base(DataType.OdbcPostgreSQL, null, null) { } + public OdbcPostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcPostgreSQL, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index 9f2f291e..0bba96e3 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -13,8 +13,8 @@ namespace FreeSql.Odbc.SqlServer { class OdbcSqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OdbcSqlServerAdo() : base(DataType.OdbcSqlServer) { } - public OdbcSqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcSqlServer) + public OdbcSqlServerAdo() : base(DataType.OdbcSqlServer, null, null) { } + public OdbcSqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcSqlServer, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 791f4f7b..59ac3c98 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -12,8 +12,8 @@ namespace FreeSql.Oracle { class OracleAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public OracleAdo() : base(DataType.Oracle) { } - public OracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Oracle) + public OracleAdo() : base(DataType.Oracle, null, null) { } + public OracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Oracle, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index 5f1600b9..3e9423dc 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -14,8 +14,8 @@ namespace FreeSql.PostgreSQL { class PostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public PostgreSQLAdo() : base(DataType.PostgreSQL) { } - public PostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.PostgreSQL) + public PostgreSQLAdo() : base(DataType.PostgreSQL, null, null) { } + public PostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.PostgreSQL, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 08bce9b7..ea278f04 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -13,8 +13,8 @@ namespace FreeSql.SqlServer { class SqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public SqlServerAdo() : base(DataType.SqlServer) { } - public SqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.SqlServer) + public SqlServerAdo() : base(DataType.SqlServer, null, null) { } + public SqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.SqlServer, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 357b87b8..c1cc9252 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -13,8 +13,8 @@ namespace FreeSql.Sqlite { class SqliteAdo : FreeSql.Internal.CommonProvider.AdoProvider { - public SqliteAdo() : base(DataType.Sqlite) { } - public SqliteAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Sqlite) + public SqliteAdo() : base(DataType.Sqlite, null, null) { } + public SqliteAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Sqlite, masterConnectionString, slaveConnectionStrings) { base._util = util; if (connectionFactory != null) From 9b87829d53bf2b87ff84f4b9ae045b29e11db076 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 28 Mar 2020 15:36:14 +0800 Subject: [PATCH 0511/1029] v1.3.0 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 17 insertions(+), 26 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index abe6aea5..14f3f65d 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0-preview95 + 1.3.0 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index aca7b12e..a961881e 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 5552709b..e30c647c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 531ee0a4..c3f573b1 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index fc4dd2f3..bd945531 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0-preview95 + 1.3.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 18611710..103bc7ce 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 23904f42..035f340a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..d8bba58b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,15 +211,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 9baf0631..4346982c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0-preview95 + 1.3.0 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f170405f..3e7c6334 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 11b22469..8b558478 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 252071f2..615250b1 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 07f754d5..4ec83feb 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c184bf3b..3783e014 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 4b3dd535..26e8c26c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index c95ad4d3..4faa4baa 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index f1b8f104..9aff696d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a4aafb71..e23c3b31 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0-preview95 + 1.3.0 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From a4367ebc5a5dbd03733c2925edecb6fb7fda3b2b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Mar 2020 18:15:39 +0800 Subject: [PATCH 0512/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbFirst=20Or?= =?UTF-8?q?acle=20=E5=BA=8F=E5=88=97=E5=80=BC=E4=BD=BF=E7=94=A8=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E7=BB=93=E5=90=88?= =?UTF-8?q?=20[Column(InsertValueSql=20=3D=20"xxx.nextval")]=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 8 ++++++++ FreeSql/Interface/Curd/IDelete.cs | 3 ++- FreeSql/Interface/Curd/IInsert.cs | 6 ++++-- FreeSql/Interface/Curd/IUpdate.cs | 3 ++- Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs | 4 ++-- 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d8bba58b..ddd18378 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,6 +211,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index a23922cb..67dadc54 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -322,6 +322,14 @@ namespace FreeSql.Tests Assert.NotNull(mt_code); Assert.Equal(mt_codeId, mt_code.ID); Assert.Equal("mt_code2", mt_code.Code); + + var id = g.oracle.Insert(new TestORC12()).ExecuteIdentity(); + } + + class TestORC12 + { + [Column(IsIdentity = true, InsertValueSql = "\"CLASS1_seq_ID\".nextval")] + public int Id { get; set; } } [Table(Name = "t_text")] diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 3619cd67..0cf9f699 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -86,7 +86,8 @@ namespace FreeSql /// int ExecuteAffrows(); /// - /// 执行SQL语句,返回被删除的记录 + /// 执行SQL语句,返回被删除的记录 + /// 注意:此方法只有 Postgresql/SqlServer 有效果 /// /// List ExecuteDeleted(); diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 77ddd620..e7f5f1db 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -106,12 +106,14 @@ namespace FreeSql /// int ExecuteAffrows(); /// - /// 执行SQL语句,返回自增值 + /// 执行SQL语句,返回自增值 + /// 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] /// /// long ExecuteIdentity(); /// - /// 执行SQL语句,返回插入后的记录 + /// 执行SQL语句,返回插入后的记录 + /// 注意:此方法只有 Postgresql/SqlServer 有效果 /// /// List ExecuteInserted(); diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 5e79eb95..4c04c013 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -183,7 +183,8 @@ namespace FreeSql /// int ExecuteAffrows(); /// - /// 执行SQL语句,返回更新后的记录 + /// 执行SQL语句,返回更新后的记录 + /// 注意:此方法只有 Postgresql/SqlServer 有效果 /// /// List ExecuteUpdated(); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 71ad77dc..93db5277 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -39,7 +39,7 @@ namespace FreeSql.Oracle.Curd foreach (var col in _table.Columns.Values) { if (col.Attribute.IsIdentity) _identCol = col; - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx > 0) sbtb.Append(", "); @@ -60,7 +60,7 @@ namespace FreeSql.Oracle.Curd var colidx2 = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); From 09343499c5c4232b90526b7fc266d02357825e32 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Mar 2020 18:27:31 +0800 Subject: [PATCH 0513/1029] v1.3.1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 12 ++++++++---- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../Dameng/Curd/OdbcDamengInsert.cs | 4 ++-- .../FreeSql.Provider.Odbc.csproj | 2 +- .../Oracle/Curd/OdbcOracleInsert.cs | 4 ++-- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 29 insertions(+), 25 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 14f3f65d..3358a806 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.0 + 1.3.1 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index a961881e..5487ac1d 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e30c647c..a0888f93 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c3f573b1..cdd93822 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index bd945531..5d8e0c49 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.0 + 1.3.1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 103bc7ce..56fc150d 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 035f340a..3a001a00 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4346982c..8f1b095e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.0 + 1.3.1 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3e7c6334..5a172234 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1a5086ea..1c0d9a4a 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -842,7 +842,8 @@ - 执行SQL语句,返回被删除的记录 + 执行SQL语句,返回被删除的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 @@ -951,13 +952,15 @@ - 执行SQL语句,返回自增值 + 执行SQL语句,返回自增值 + 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] - 执行SQL语句,返回插入后的记录 + 执行SQL语句,返回插入后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 @@ -2109,7 +2112,8 @@ - 执行SQL语句,返回更新后的记录 + 执行SQL语句,返回更新后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 8b558478..f8a1bef0 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 615250b1..70b7a88f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4ec83feb..ff844ee2 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index 6b6c5565..ab779a18 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.Dameng foreach (var col in _table.Columns.Values) { if (col.Attribute.IsIdentity) _identCol = col; - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx > 0) sbtb.Append(", "); @@ -58,7 +58,7 @@ namespace FreeSql.Odbc.Dameng var colidx2 = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3783e014..509177d3 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index ac7cb08e..da47a7a5 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.Oracle foreach (var col in _table.Columns.Values) { if (col.Attribute.IsIdentity) _identCol = col; - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx > 0) sbtb.Append(", "); @@ -58,7 +58,7 @@ namespace FreeSql.Odbc.Oracle var colidx2 = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 26e8c26c..be258676 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 4faa4baa..5beae9b2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9aff696d..568cf47c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e23c3b31..fc20c061 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.0 + 1.3.1 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 9f2ffdce77ef0717e45d3df01b796e77d1599699 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Mar 2020 22:36:39 +0800 Subject: [PATCH 0514/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Gene?= =?UTF-8?q?rator=20Sqlite=20=E6=95=B0=E6=8D=AE=E5=BA=93=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E7=B1=BB=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20Sqlite=20DbFirst=20=E5=AE=9E=E7=8E=B0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 10 +- .../FreeSql.Generator.csproj | 5 +- Extensions/FreeSql.Generator/RazorModel.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 - .../FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs | 25 ++ FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- .../FreeSql.Provider.Sqlite/SqliteDbFirst.cs | 359 ++++++++++++++++++ .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 3 +- 8 files changed, 398 insertions(+), 17 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs create mode 100644 Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index c8d9e46d..c32b25ca 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -102,9 +102,11 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -DB ""{8},Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=数据库;Pooling=true;Maximum Pool Size=2"" -DB ""{9},user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2"" + + -DB ""{10},Data Source=document.db;Attachs=xxxtb.db;"" - -DB ""{10},Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789;Max pool size=2"" - {10} 是国产达梦数据库,需要使用 ODBC 连接 + -DB ""{11},Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789;Max pool size=2"" + {11} 是国产达梦数据库,需要使用 ODBC 连接 -Filter Table+View+StoreProcedure 默认生成:表+视图+存储过程 @@ -113,7 +115,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -FileName 文件名,默认:{name}.cs -Output 保存路径,默认为当前 shell 所在目录 - {11} + {12} ", Color.SlateGray, new Colorful.Formatter("使用 FreeSql 快速生成数据库的实体类", Color.SlateGray), @@ -126,6 +128,7 @@ new Colorful.Formatter("MySql", Color.Yellow), new Colorful.Formatter("SqlServer", Color.Yellow), new Colorful.Formatter("PostgreSQL", Color.Yellow), new Colorful.Formatter("Oracle", Color.Yellow), +new Colorful.Formatter("Sqlite", Color.Yellow), new Colorful.Formatter("OdbcDameng", Color.Yellow), new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新所有实体类", Color.ForestGreen) ); @@ -165,6 +168,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 case "sqlserver": ArgsDbType = DataType.SqlServer; break; case "postgresql": ArgsDbType = DataType.PostgreSQL; break; case "oracle": ArgsDbType = DataType.Oracle; break; + case "sqlite": ArgsDbType = DataType.Sqlite; break; case "odbcdameng": ArgsDbType = DataType.OdbcDameng; break; default: throw new ArgumentException($"-DB 参数错误,不支持的类型:{dbargs[0]}"); } diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 5d8e0c49..d5aecb79 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;netcoreapp2.1 + netcoreapp3.1 true true true @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.1 + 1.3.1.5 FreeSql DbFirst 实体生成器 @@ -27,6 +27,7 @@ + diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 07e5bb6a..e2be6979 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -73,7 +73,7 @@ public class RazorModel { if (col.CsType != null) { var dbinfo = fsql.CodeFirst.GetDbInfo(col.CsType); - if (dbinfo != null && dbinfo.dbtypeFull.Replace("NOT NULL", "").Trim() != col.DbTypeTextFull) + if (dbinfo != null && string.Compare(dbinfo.dbtypeFull.Replace("NOT NULL", "").Trim(), col.DbTypeTextFull, true) != 0) sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); if (col.IsPrimary) sb.Add("IsPrimary = true"); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..d8bba58b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,15 +211,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs new file mode 100644 index 00000000..8725e453 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Sqlite +{ + public class SqliteDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.sqlite.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.sqlite.DbFirst.GetTablesByDatabase(); + + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 985eae8b..ba3a65d5 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -71,7 +71,7 @@ public class g public static IFreeSql oracle => oracleLazy.Value; static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;") + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db") //.UseConnectionFactory(FreeSql.DataType.Sqlite, () => //{ // var conn = new System.Data.SQLite.SQLiteConnection(@"Data Source=|DataDirectory|\document.db;Pooling=true;"); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs new file mode 100644 index 00000000..74908fdd --- /dev/null +++ b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs @@ -0,0 +1,359 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Sqlite +{ + class SqliteDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public SqliteDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + DbType GetSqlDbType(DbColumnInfo column) + { + var dbfull = column.DbTypeTextFull.ToLower(); + switch (dbfull) + { + case "boolean": return DbType.Boolean; + + case "smallint": return DbType.Int16; + case "integer": return DbType.Int32; + case "bigint": return DbType.Int64; + + case "int2": return DbType.Byte; + case "unsigned": return DbType.Decimal; + case "decimal(10,0)": return DbType.Decimal; + case "decimal(21,0)": return DbType.Decimal; + + case "double": return DbType.Double; + case "float": return DbType.Single; + case "decimal(10,2)": return DbType.Decimal; + case "datetime": return DbType.DateTime; + + case "blob": return DbType.Binary; + case "nvarchar(255)": return DbType.String; + + case "character(36)": return DbType.AnsiString; + } + switch (column.DbTypeText.ToLower()) + { + case "int": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["integer"]); + return DbType.Int32; + case "tinyint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["int2"]); + return DbType.Byte; + case "mediumint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["bigint"]); + return DbType.Int64; + case "unsigned big int": + case "int8": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["bigint"]); + return DbType.Int64; + + case "numeric": + case "decimal": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["decimal(10,2)"]); + return DbType.Decimal; + + case "date": + case "smalldatetime": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["datetime"]); + return DbType.Date; + + case "real": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float"]); + return DbType.Double; + case "double precision": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["double"]); + return DbType.Double; + + case "blob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return DbType.Binary; + + case "character": + case "varchar": + case "varying character": + case "nchar": + case "native character": + case "nvarchar": + case "text": + case "clob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar(255)"]); + return DbType.String; + + default: + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar(255)"]); + return DbType.String; + } + throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); + } + + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static SqliteDbFirst() + { + var defaultDbToCs = new Dictionary() { + { "boolean", new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { "smallint", new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "integer", new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "bigint", new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { "int2", new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "unsigned", new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "decimal(10,0)", new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "decimal(21,0)", new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + + { "double", new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float", new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "decimal(10,2)", new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { "datetime", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + + { "blob", new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { "nvarchar(255)", new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "character(36)", new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } + + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + return _orm.Ado.ExecuteArray("PRAGMA database_list").Select(a => string.Concat(a[1])).ToList(); + } + + public List GetTablesByDatabase(params string[] database2) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + var database = database2?.ToArray(); + + if (database == null || database.Any() == false) database = GetDatabases().ToArray(); + if (database.Any() == false) return loc1; + + Action addColumn = row => + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + bool is_primary = string.Concat(row[7]) == "1"; + string comment = string.Concat(row[8]); + if (max_length == 0) max_length = -1; + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = is_primary, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + }; + + foreach (var db in database) + { + var sql = $@"select +'{db}.' || tbl_name, +'{db}', +tbl_name, +'' Comment, +'TABLE', +sql +from {db}.sqlite_master where type = 'table'"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) continue; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 999) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 999) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + + if (type == DbTableType.TABLE && table != "sqlite_sequence") + { + var dsql = string.Concat(row[5]); + var cols = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA \"{db}\".table_info(\"{table}\")"); + foreach (var col in cols) + { + var col_name = string.Concat(col[1]); + var is_identity = false; + var dsqlIdx = dsql?.IndexOf($"\"{col_name}\" "); + if (dsqlIdx > 0) + { + var dsqlLastIdx = dsql.IndexOf('\n', dsqlIdx.Value); + if (dsqlLastIdx > 0) is_identity = dsql.Substring(dsqlIdx.Value, dsqlLastIdx - dsqlIdx.Value).Contains("AUTOINCREMENT"); + } + + var ds2item = new object[9]; + ds2item[0] = table_id; + ds2item[1] = col_name; + ds2item[2] = Regex.Replace(string.Concat(col[2]), @"\(\d+(\b*,\b*\d+)?\)", "").ToUpper(); + ds2item[4] = string.Concat(col[2]).ToUpper(); + ds2item[5] = string.Concat(col[5]) == "0" && string.Concat(col[3]) == "0" ? 1 : 0; + ds2item[6] = is_identity; + ds2item[7] = string.Concat(col[5]) == "1" ? 1 : 0; + ds2item[8] = ""; + addColumn(ds2item); + } + + var fks = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA \"{db}\".foreign_key_list(\"{table}\")"); + if (fks != null && fks.Length > 0) + { + var fkColumns = new Dictionary>(); + foreach (var fk in fks) + { + string column = string.Concat(fk[3]); + string fk_id = $"{db}.{table}.{fk[0]}"; + string ref_table_id = database.Length == 1 ? string.Concat(fk[2]) : $"{db}.{fk[2]}"; + string referenced_column = string.Concat(fk[4]); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id2 in fkColumns.Keys) + foreach (var fk in fkColumns[table_id2]) + loc2[table_id2].ForeignsDict.Add(fk.Key, fk.Value); + } + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) continue; + } + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + //if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 972137b6..8782b6d6 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -28,7 +28,7 @@ namespace FreeSql.Sqlite public IAdo Ado { get; } public IAop Aop { get; } public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); + public IDbFirst DbFirst { get; }// => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); public SqliteProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new SqliteUtils(this); @@ -38,6 +38,7 @@ namespace FreeSql.Sqlite this.Aop = new AopProvider(); this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.DbFirst = new SqliteDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); if (connectionFactory != null) this.CodeFirst.IsNoneCommandParameter = true; } From 18079a0c42c70e4d1ebbbb9a435c4ac614f24fd4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Mar 2020 22:46:12 +0800 Subject: [PATCH 0515/1029] v1.3.2 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 26 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 3358a806..fbec3035 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.1 + 1.3.2 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 5487ac1d..47c6772c 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a0888f93..1f776fcf 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index cdd93822..5aae06d6 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 56fc150d..0b35c7d2 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 3a001a00..a293ab03 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d8bba58b..ddd18378 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,6 +211,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8f1b095e..d2b7c4de 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.1 + 1.3.2 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index ba3a65d5..985eae8b 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -71,7 +71,7 @@ public class g public static IFreeSql oracle => oracleLazy.Value; static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db") + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;") //.UseConnectionFactory(FreeSql.DataType.Sqlite, () => //{ // var conn = new System.Data.SQLite.SQLiteConnection(@"Data Source=|DataDirectory|\document.db;Pooling=true;"); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 5a172234..e0d7c107 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index f8a1bef0..6db7ff8e 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 70b7a88f..d186d0a8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ff844ee2..353d98d3 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 509177d3..f0e2dc1b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index be258676..96126e6a 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 5beae9b2..d9c02421 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 568cf47c..8ab08abe 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fc20c061..3c214f01 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.1 + 1.3.2 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 4655646b5288311bc62da2122101a5acf2d60258 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 29 Mar 2020 23:14:36 +0800 Subject: [PATCH 0516/1029] v1.3.2 --- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d5aecb79..4241281d 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.1.5 + 1.3.2 FreeSql DbFirst 实体生成器 From 81915373645aefbd7102ffd9ff8530defea6f5c2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 30 Mar 2020 10:53:29 +0800 Subject: [PATCH 0517/1029] =?UTF-8?q?#=20=E5=AE=8C=E5=96=84=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E6=8B=BC=E6=8E=A5=E6=96=B9=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E4=BB=8E=20T1-T5=EF=BC=9B#256?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - .../LambadaExpressionExtensionsTest.cs | 61 +++- .../Extensions/LambadaExpressionExtensions.cs | 278 +++++++++++++----- FreeSql/FreeSql.xml | 155 +++++++++- 4 files changed, 420 insertions(+), 90 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..28fdb213 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -211,15 +204,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs index 4c6d8e38..099d4417 100644 --- a/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Extensions/LambadaExpressionExtensionsTest.cs @@ -12,29 +12,36 @@ namespace FreeSql.Tests.Extensions public void And() { Expression> where = a => a.id == Guid.Empty; - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" > 0)", g.sqlite.Select().Where(where.And(b => b.num > 0)).ToSql().Replace("\r\n", "")); Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.And(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000' AND a.\"num\" = 1 AND a.\"num\" = 2)", g.sqlite.Select().Where(where.And(b => b.num == 1).And(b => b.num == 2)).ToSql().Replace("\r\n", "")); Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.And(false, b => b.num == 1).And(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); - } + where = null; + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"num\" > 0)", g.sqlite.Select().Where(where.And(b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a", g.sqlite.Select().Where(where.And(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"num\" = 1 AND a.\"num\" = 2)", g.sqlite.Select().Where(where.And(b => b.num == 1).And(b => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a", g.sqlite.Select().Where(where.And(false, b => b.num == 1).And(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); + } [Fact] public void Or() { Expression> where = a => a.id == Guid.Empty; - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE ((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" > 0))", g.sqlite.Select().Where(where.Or(b => b.num > 0)).ToSql().Replace("\r\n", "")); Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Or(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (((a.\"id\" = '00000000-0000-0000-0000-000000000000' OR a.\"num\" = 1) OR a.\"num\" = 2))", g.sqlite.Select().Where(where.Or(b => b.num == 1).Or(b => b.num == 2)).ToSql().Replace("\r\n", "")); Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Or(false, b => b.num == 1).Or(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); - } + where = null; + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"num\" > 0)", g.sqlite.Select().Where(where.Or(b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a", g.sqlite.Select().Where(where.Or(false, b => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE ((a.\"num\" = 1 OR a.\"num\" = 2))", g.sqlite.Select().Where(where.Or(b => b.num == 1).Or(b => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a", g.sqlite.Select().Where(where.Or(false, b => b.num == 1).Or(false, c => c.num == 2)).ToSql().Replace("\r\n", "")); + } [Fact] public void Not() { Expression> where = a => a.id == Guid.Empty; - Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (not(a.\"id\" = '00000000-0000-0000-0000-000000000000'))", g.sqlite.Select().Where(where.Not()).ToSql().Replace("\r\n", "")); Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a WHERE (a.\"id\" = '00000000-0000-0000-0000-000000000000')", g.sqlite.Select().Where(where.Not(false)).ToSql().Replace("\r\n", "")); } @@ -45,5 +52,49 @@ namespace FreeSql.Tests.Extensions public int num { get; set; } } + class testExpAddOr2 + { + public Guid id { get; set; } + + public int num { get; set; } + } + + [Fact] + public void And2() + { + Expression> where = (a, b) => a.id == b.id; + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (a.\"id\" = b.\"id\" AND b.\"num\" > 0)", g.sqlite.Select().Where(where.And((a, b) => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (a.\"id\" = b.\"id\")", g.sqlite.Select().Where(where.And(false, (a, b) => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (a.\"id\" = b.\"id\" AND b.\"num\" = 1 AND b.\"num\" = 2)", g.sqlite.Select().Where(where.And((a, b) => b.num == 1).And((a, b) => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (a.\"id\" = b.\"id\")", g.sqlite.Select().Where(where.And(false, (a, b) => b.num == 1).And(false, (a, c) => c.num == 2)).ToSql().Replace("\r\n", "")); + + where = null; + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (b.\"num\" > 0)", g.sqlite.Select().Where(where.And((a, b) => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b", g.sqlite.Select().Where(where.And(false, (a, b) => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (b.\"num\" = 1 AND b.\"num\" = 2)", g.sqlite.Select().Where(where.And((a, b) => b.num == 1).And((a, b) => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b", g.sqlite.Select().Where(where.And(false, (a, b) => b.num == 1).And(false, (a, c) => c.num == 2)).ToSql().Replace("\r\n", "")); + } + [Fact] + public void Or2() + { + Expression> where = (a, b) => a.id == b.id; + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE ((a.\"id\" = b.\"id\" OR b.\"num\" > 0))", g.sqlite.Select().Where(where.Or((a, b) => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (a.\"id\" = b.\"id\")", g.sqlite.Select().Where(where.Or(false, (a, b) => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (((a.\"id\" = b.\"id\" OR b.\"num\" = 1) OR b.\"num\" = 2))", g.sqlite.Select().Where(where.Or((a, b) => b.num == 1).Or((a, b) => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (a.\"id\" = b.\"id\")", g.sqlite.Select().Where(where.Or(false, (a, b) => b.num == 1).Or(false, (a, c) => c.num == 2)).ToSql().Replace("\r\n", "")); + + where = null; + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (b.\"num\" > 0)", g.sqlite.Select().Where(where.Or((a, b) => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b", g.sqlite.Select().Where(where.Or(false, (a, b) => b.num > 0)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE ((b.\"num\" = 1 OR b.\"num\" = 2))", g.sqlite.Select().Where(where.Or((a, b) => b.num == 1).Or((a, b) => b.num == 2)).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b", g.sqlite.Select().Where(where.Or(false, (a, b) => b.num == 1).Or(false, (a, c) => c.num == 2)).ToSql().Replace("\r\n", "")); + } + [Fact] + public void Not2() + { + Expression> where = (a, b) => a.id == b.id; + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (not(a.\"id\" = b.\"id\"))", g.sqlite.Select().Where(where.Not()).ToSql().Replace("\r\n", "")); + Assert.Equal("SELECT a.\"id\", a.\"num\" FROM \"testExpAddOr\" a, \"testExpAddOr2\" b WHERE (a.\"id\" = b.\"id\")", g.sqlite.Select().Where(where.Not(false)).ToSql().Replace("\r\n", "")); + } } } diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 034efdd3..1b05dbf1 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -14,79 +14,219 @@ namespace System.Linq.Expressions public static partial class LambadaExpressionExtensions { - /// - /// 使用 and 拼接两个 lambda 表达式 - /// - /// - public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); - /// - /// 使用 and 拼接两个 lambda 表达式 - /// - /// - /// - /// true 时生效 - /// - /// - public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) + static LambdaExpression InternalAndOrExpression(bool condition, LambdaExpression exp1, LambdaExpression exp2, bool isAndAlso) { if (condition == false) return exp1; if (exp1 == null) return exp2; if (exp2 == null) return exp1; - ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); - NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter, exp2.Parameters.FirstOrDefault()); + var newParameters = exp1.Parameters.Select((a, b) => Expression.Parameter(a.Type, $"new{b}")).ToArray(); - var left = visitor.Replace(exp1.Body); - var right = visitor.Replace(exp2.Body); - var body = Expression.AndAlso(left, right); - return Expression.Lambda>(body, newParameter); + var left = new NewExpressionVisitor(newParameters, exp2.Parameters.ToArray()).Replace(exp1.Body); + var right = new NewExpressionVisitor(newParameters, exp2.Parameters.ToArray()).Replace(exp2.Body); + var body = isAndAlso ? Expression.AndAlso(left, right) : Expression.OrElse(left, right); + return Expression.Lambda(exp1.Type, body, newParameters); } - - /// - /// 使用 or 拼接两个 lambda 表达式 - /// - /// - public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); - /// - /// 使用 or 拼接两个 lambda 表达式 - /// - /// - /// - /// true 时生效 - /// - /// - public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) - { - if (condition == false) return exp1; - if (exp1 == null) return exp2; - if (exp2 == null) return exp1; - - ParameterExpression newParameter = Expression.Parameter(typeof(T), "c"); - NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter, exp2.Parameters.FirstOrDefault()); - - var left = visitor.Replace(exp1.Body); - var right = visitor.Replace(exp2.Body); - var body = Expression.OrElse(left, right); - return Expression.Lambda>(body, newParameter); - } - - /// - /// 将 lambda 表达式取反 - /// - /// - /// - /// true 时生效 - /// - public static Expression> Not(this Expression> exp, bool condition = true) + static LambdaExpression InternalNotExpression(bool condition, LambdaExpression exp) { if (condition == false) return exp; if (exp == null) return null; - var candidateExpr = exp.Parameters[0]; + var newParameters = exp.Parameters.Select((a, b) => Expression.Parameter(a.Type, $"new{b}")).ToArray(); var body = Expression.Not(exp.Body); - return Expression.Lambda>(body, candidateExpr); + return Expression.Lambda(exp.Type, body, newParameters); } + #region T1 + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, true); + + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, false); + + /// + /// 将 lambda 表达式取反 + /// + /// + /// true 时生效 + /// + public static Expression> Not(this Expression> exp, bool condition = true) => (Expression>)InternalNotExpression(condition, exp); + #endregion + + #region T1, T2 + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, true); + + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, false); + + /// + /// 将 lambda 表达式取反 + /// + /// + /// true 时生效 + /// + public static Expression> Not(this Expression> exp, bool condition = true) => (Expression>)InternalNotExpression(condition, exp); + #endregion + + #region T1, T2, T3 + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, true); + + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, false); + + /// + /// 将 lambda 表达式取反 + /// + /// + /// true 时生效 + /// + public static Expression> Not(this Expression> exp, bool condition = true) => (Expression>)InternalNotExpression(condition, exp); + #endregion + + #region T1, T2, T3, T4 + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, true); + + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, false); + + /// + /// 将 lambda 表达式取反 + /// + /// + /// true 时生效 + /// + public static Expression> Not(this Expression> exp, bool condition = true) => (Expression>)InternalNotExpression(condition, exp); + #endregion + + #region T1, T2, T3, T4, T5 + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + public static Expression> And(this Expression> exp1, Expression> exp2) => And(exp1, true, exp2); + /// + /// 使用 and 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> And(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, true); + + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + public static Expression> Or(this Expression> exp1, Expression> exp2) => Or(exp1, true, exp2); + /// + /// 使用 or 拼接两个 lambda 表达式 + /// + /// + /// true 时生效 + /// + /// + public static Expression> Or(this Expression> exp1, bool condition, Expression> exp2) => (Expression>)InternalAndOrExpression(condition, exp1, exp2, false); + + /// + /// 将 lambda 表达式取反 + /// + /// + /// true 时生效 + /// + public static Expression> Not(this Expression> exp, bool condition = true) => (Expression>)InternalNotExpression(condition, exp); + #endregion + internal static bool IsParameter(this Expression exp) { var test = new TestParameterExpressionVisitor(); @@ -97,17 +237,23 @@ namespace System.Linq.Expressions internal class NewExpressionVisitor : ExpressionVisitor { - ParameterExpression _newParameter; - ParameterExpression _oldParameter; - public NewExpressionVisitor(ParameterExpression newParam, ParameterExpression oldParam) + ParameterExpression[] _newParameters; + ParameterExpression[] _oldParameters; + public NewExpressionVisitor(ParameterExpression newParam, ParameterExpression oldParam) : this(new[] { newParam }, new[] { oldParam }) { } + public NewExpressionVisitor(ParameterExpression[] newParams, ParameterExpression[] oldParams) { - this._newParameter = newParam; - this._oldParameter = oldParam; + this._newParameters = newParams; + this._oldParameters = oldParams; } public Expression Replace(Expression exp) => this.Visit(exp); - protected override Expression VisitParameter(ParameterExpression node) => - node == _oldParameter ? this._newParameter : node; + protected override Expression VisitParameter(ParameterExpression node) + { + for (var a = 0; a < _oldParameters.Length; a++) + if (_oldParameters[a] == node) + return _newParameters[a]; + return node; + } } internal class TestParameterExpressionVisitor : ExpressionVisitor diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1c0d9a4a..cd174404 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3319,7 +3319,6 @@ 使用 and 拼接两个 lambda 表达式 - true 时生效 @@ -3335,7 +3334,6 @@ 使用 or 拼接两个 lambda 表达式 - true 时生效 @@ -3345,7 +3343,158 @@ 将 lambda 表达式取反 - + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + true 时生效 From cdfe48ac03735e966bb27bdbbdb8112c08238b5d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 05:17:00 +0800 Subject: [PATCH 0518/1029] update readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 2e6b3bec..b69664d5 100644 --- a/readme.md +++ b/readme.md @@ -206,7 +206,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元 > Thank you for your donation From 7795296328db3ef96bbb37fc1377fed009e0dfca Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 05:56:49 +0800 Subject: [PATCH 0519/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Oracle=20CLO?= =?UTF-8?q?B/NCLOB=20=E5=A4=A7=E6=96=87=E6=9C=AC=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E8=AF=BB=E5=86=99=E6=94=AF=E6=8C=81=EF=BC=9B#259?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++++++ .../Oracle/OracleCodeFirstTest.cs | 48 +++++++++++++++++++ .../OracleCodeFirst.cs | 6 +++ .../FreeSql.Provider.Oracle/OracleUtils.cs | 4 ++ 4 files changed, 74 insertions(+) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 28fdb213..ddd18378 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -204,6 +211,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 8e7d09c8..68b9de63 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using Newtonsoft.Json; +using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Generic; using System.Linq; @@ -10,6 +11,53 @@ namespace FreeSql.Tests.Oracle { public class OracleCodeFirstTest { + [Fact] + public void Clob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_CLB01 { Data = str1 }; + Assert.Equal(1, g.oracle.Insert(item1).ExecuteAffrows()); + + var item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_CLB01 { Data = str1 }; + Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ + } + class TS_CLB01 + { + public Guid Id { get; set; } + [Column(DbType = "clob")] + public string Data { get; set; } + } + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.oracle.Insert(item1).ExecuteAffrows()); + + var item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ + } + class TS_BLB01 + { + public Guid Id { get; set; } + public byte[] Data { get; set; } + } [Fact] public void StringLength() { diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 6bf213c4..149011e7 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -441,6 +441,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam else if (sqlType.StartsWith("BLOB")) { } + else if (sqlType.StartsWith("CLOB")) + { + } + else if (sqlType.StartsWith("NCLOB")) + { + } else if (char_used.ToLower() == "c") sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; else if (char_used.ToLower() == "b") diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index d28c66c5..6f2ce884 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -40,6 +40,10 @@ namespace FreeSql.Oracle if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; if (col.DbScale != 0) ret.Scale = col.DbScale; break; + case OracleDbType.Clob: + case OracleDbType.NClob: + ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype2, Value = value }; + break; } } _params?.Add(ret); From 558fc52cf09a74d6646bd0897479091a03bf7ec8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 06:07:47 +0800 Subject: [PATCH 0520/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20Oracle=20Str?= =?UTF-8?q?ingLength/MaxLength=20-1=20=E6=97=B6=E5=80=99=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E4=B8=BA=20nclob=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ------- .../Oracle/OracleCodeFirstTest.cs | 45 +++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 3 ++ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..28fdb213 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -211,15 +204,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 68b9de63..baf47d01 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -11,6 +11,51 @@ namespace FreeSql.Tests.Oracle { public class OracleCodeFirstTest { + [Fact] + public void NClob_StringLength_1() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_NCLB02 { Data = str1 }; + Assert.Equal(1, g.oracle.Insert(item1).ExecuteAffrows()); + + var item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_NCLB02 { Data = str1 }; + Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ + } + class TS_NCLB02 + { + public Guid Id { get; set; } + [Column(StringLength = - 1)] + public string Data { get; set; } + } + + [Fact] + public void NClob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_NCLB01 { Data = str1 }; + Assert.Equal(1, g.oracle.Insert(item1).ExecuteAffrows()); + + var item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_NCLB01 { Data = str1 }; + Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ + } + class TS_NCLB01 + { + public Guid Id { get; set; } + [Column(DbType = "nclob")] + public string Data { get; set; } + } [Fact] public void Clob() { diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index efdb4a8a..c77baea9 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -223,6 +223,9 @@ namespace FreeSql.Internal else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; case DataType.Oracle: + if (strlen < 0) colattr.DbType = "NCLOB"; //v1.3.2+ https://github.com/dotnetcore/FreeSql/issues/259 + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; case DataType.OdbcOracle: case DataType.OdbcDameng: if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(4000)"); From bbe5450eb9d7e36d9a82a189a0c66fe449a949ff Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 06:13:43 +0800 Subject: [PATCH 0521/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20IInsert/IUpd?= =?UTF-8?q?ate=20NoneParameter=20=E6=96=B9=E6=B3=95=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=8F=82=E6=95=B0=20isNotCommandParameter=20=E5=8F=AF?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=98=AF=E5=90=A6=E4=BD=BF=E7=94=A8=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=8C=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Interface/Curd/IInsert.cs | 3 ++- FreeSql/Interface/Curd/IUpdate.cs | 3 ++- FreeSql/Internal/CommonProvider/InsertProvider.cs | 4 ++-- FreeSql/Internal/CommonProvider/UpdateProvider.cs | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index e7f5f1db..6f09c6bc 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -64,8 +64,9 @@ namespace FreeSql /// /// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 /// + /// 是否不使用参数化 /// - IInsert NoneParameter(); + IInsert NoneParameter(bool isNotCommandParameter = true); /// /// 批量执行选项设置,一般不需要使用该方法 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 4c04c013..6922dadd 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -25,8 +25,9 @@ namespace FreeSql /// /// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 /// + /// 是否不使用参数化 /// - IUpdate NoneParameter(); + IUpdate NoneParameter(bool isNotCommandParameter = true); /// /// 批量执行选项设置,一般不需要使用该方法 diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index d673a2af..161a630b 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -82,9 +82,9 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IInsert NoneParameter() + public IInsert NoneParameter(bool isNotCommandParameter = true) { - _noneParameter = true; + _noneParameter = isNotCommandParameter; return this; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 629c4c63..f5890251 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -87,9 +87,9 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IUpdate NoneParameter() + public IUpdate NoneParameter(bool isNotCommandParameter = true) { - _noneParameter = true; + _noneParameter = isNotCommandParameter; return this; } From f3593a321f826505e18dc6422f76b56849e23c45 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 07:02:42 +0800 Subject: [PATCH 0522/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSqlBuild?= =?UTF-8?q?er=20UseNameConvert=20=E6=96=B9=E6=B3=95=EF=BC=8C=E7=B1=BB?= =?UTF-8?q?=E5=90=8D=E3=80=81=E5=B1=9E=E6=80=A7=E5=90=8D=E9=83=BD=E7=94=9F?= =?UTF-8?q?=E6=95=88=EF=BC=9B=20-=20=E8=B0=83=E6=95=B4=20FreeSqlBuilder?= =?UTF-8?q?=EF=BC=8C=E5=87=86=E5=A4=87=E7=A7=BB=E9=99=A4=20UseEntityProper?= =?UTF-8?q?tyNameConvert/UseSyncStructureToLower/UseSyncStructureToUpper?= =?UTF-8?q?=20=E6=96=B9=E6=B3=95=EF=BC=9B#260?= 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.DbContext/g.cs | 4 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 2 +- .../Curd/OnDuplicateKeyUpdateTest.cs | 64 ++++++++--------- .../Dameng/Curd/DamengSelectTest.cs | 2 +- .../Default/Curd/OdbcSelectTest.cs | 2 +- .../MySql/Curd/MySqlSelectTest.cs | 2 +- .../Oracle/Curd/OracleSelectTest.cs | 2 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 2 +- .../FreeSql.Tests.Provider.Odbc/g.cs | 8 +-- .../MsAccess/Curd/MsAccessSelectTest.cs | 2 +- .../MySql/Curd/MySqlSelectTest.cs | 2 +- .../Oracle/Curd/OracleSelectTest.cs | 2 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 2 +- .../Sqlite/Curd/SqliteSelectTest.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 2 +- FreeSql.Tests/FreeSql.Tests/g.cs | 4 +- FreeSql/FreeSql.xml | 54 +++++++++++++-- FreeSql/FreeSqlBuilder.cs | 69 ++++++++++++++++--- FreeSql/Interface/ICodeFirst.cs | 4 +- FreeSql/Internal/StringConvertType.cs | 54 ++++++++++++++- FreeSql/Internal/StringUtils.cs | 20 ------ 25 files changed, 232 insertions(+), 95 deletions(-) delete mode 100644 FreeSql/Internal/StringUtils.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 28fdb213..ddd18378 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -204,6 +211,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs index 6bb48a5e..5e6cf923 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/g.cs @@ -44,7 +44,7 @@ public class g static Lazy pgsqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") .UseAutoSyncStructure(true) - .UseSyncStructureToLower(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) .UseLazyLoading(true) .UseMonitorCommand( cmd => @@ -63,7 +63,7 @@ public class g .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") .UseAutoSyncStructure(true) .UseLazyLoading(true) - .UseSyncStructureToUpper(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) .UseNoneCommandParameter(true) .UseMonitorCommand( diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index b1881760..77ba34f0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -270,7 +270,7 @@ namespace FreeSql.Tests.MySqlConnector }) }); var ddd = g.mysql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs index ff852737..2145dedb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs @@ -21,10 +21,10 @@ namespace FreeSql.Tests.MySqlConnector { g.mysql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = VALUES(`time`)"); +`time` = VALUES(`time`)", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -32,10 +32,10 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = VALUES(`time`)"); +`time` = VALUES(`time`)", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -44,10 +44,10 @@ ON DUPLICATE KEY UPDATE { g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -55,21 +55,21 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), `time` = CASE `id` WHEN 200 THEN '2000-01-01 00:00:00.000' WHEN 201 THEN '2000-01-01 00:00:00.000' -WHEN 202 THEN '2000-01-01 00:00:00.000' END"); +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') ON DUPLICATE KEY UPDATE -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -77,12 +77,12 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON DUPLICATE KEY UPDATE `time` = CASE `id` WHEN 200 THEN '2000-01-01 00:00:00.000' WHEN 201 THEN '2000-01-01 00:00:00.000' -WHEN 202 THEN '2000-01-01 00:00:00.000' END"); +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -91,10 +91,10 @@ WHEN 202 THEN '2000-01-01 00:00:00.000' END"); { g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -102,21 +102,21 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), `time` = CASE `id` WHEN 300 THEN '2000-01-01 00:00:00.000' WHEN 301 THEN '2000-01-01 00:00:00.000' -WHEN 302 THEN '2000-01-01 00:00:00.000' END"); +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') ON DUPLICATE KEY UPDATE -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -124,12 +124,12 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON DUPLICATE KEY UPDATE `time` = CASE `id` WHEN 300 THEN '2000-01-01 00:00:00.000' WHEN 301 THEN '2000-01-01 00:00:00.000' -WHEN 302 THEN '2000-01-01 00:00:00.000' END"); +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -138,9 +138,9 @@ WHEN 302 THEN '2000-01-01 00:00:00.000' END"); { g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -148,18 +148,18 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); odku2.ExecuteAffrows(); var dt2020 = DateTime.Parse("2020-1-1"); g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -167,17 +167,17 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -185,9 +185,9 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku2.ToSql()); odku2.ExecuteAffrows(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index f4ab9a5b..34f665fc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -211,7 +211,7 @@ namespace FreeSql.Tests.Odbc.Dameng }) }); var ddd = g.dameng.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 9e404f0f..bf9b4bdc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -202,7 +202,7 @@ namespace FreeSql.Tests.Odbc.Default }) }); var ddd = g.odbc.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 04c11f44..39785795 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -311,7 +311,7 @@ namespace FreeSql.Tests.Odbc.MySql }) }); var ddd = g.mysql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index f003c4cf..22d51222 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -211,7 +211,7 @@ namespace FreeSql.Tests.Odbc.Oracle }) }); var ddd = g.oracle.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 38514d5c..b7b9b513 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -287,7 +287,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL }) }); var ddd = g.pgsql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index b868dc81..e636c42b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -201,7 +201,7 @@ namespace FreeSql.Tests.Odbc.SqlServer }) }); var ddd = g.sqlserver.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index 4bb24a55..e0b589bd 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -35,7 +35,7 @@ public class g //.UseConnectionFactory(FreeSql.DataType.OdbcOracle, () => new System.Data.Odbc.OdbcConnection("Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456")) .UseAutoSyncStructure(true) .UseLazyLoading(true) - .UseSyncStructureToUpper(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) //.UseNoneCommandParameter(true) .UseMonitorCommand( @@ -50,7 +50,7 @@ public class g .UseConnectionString(FreeSql.DataType.OdbcPostgreSQL, "Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Maximum Pool Size=2") //.UseConnectionFactory(FreeSql.DataType.OdbcPostgreSQL, () => new System.Data.Odbc.OdbcConnection("Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;")) .UseAutoSyncStructure(true) - .UseSyncStructureToLower(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) .UseLazyLoading(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 @@ -74,7 +74,7 @@ public class g //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")) .UseAutoSyncStructure(true) .UseLazyLoading(true) - .UseSyncStructureToUpper(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) //.UseNoneCommandParameter(true) .UseMonitorCommand( @@ -89,7 +89,7 @@ public class g //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")) .UseAutoSyncStructure(true) .UseLazyLoading(true) - .UseSyncStructureToUpper(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) //.UseNoneCommandParameter(true) .UseMonitorCommand( diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index aa03e685..d4191350 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -202,7 +202,7 @@ namespace FreeSql.Tests.MsAccess }) }); var ddd = g.msaccess.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 86e92f50..223ce220 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -311,7 +311,7 @@ namespace FreeSql.Tests.MySql }) }); var ddd = g.mysql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 2c3c2928..88cab797 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -211,7 +211,7 @@ namespace FreeSql.Tests.Oracle }) }); var ddd = g.oracle.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index f1a5ff31..1cfd5d9f 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -287,7 +287,7 @@ namespace FreeSql.Tests.PostgreSQL }) }); var ddd = g.pgsql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 11d570b7..c739c6a6 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -211,7 +211,7 @@ namespace FreeSql.Tests.SqlServer }) }); var ddd = g.sqlserver.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 9414c910..86f622e9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -228,7 +228,7 @@ namespace FreeSql.Tests.Sqlite }) }); var ddd = g.sqlite.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); - Assert.Equal(1, ddd.Count); + Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); } public class District diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index f7df0e51..ddd934e8 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -574,7 +574,7 @@ namespace FreeSql.Tests IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=7") - .UseEntityPropertyNameConvert(Internal.StringConvertType.PascalCaseToUnderscoreWithLower) + .UseNameConvert(Internal.NameConvertType.PascalCaseToUnderscoreWithLower) .UseNoneCommandParameter(true) .UseAutoSyncStructure(true) //自动同步实体结构到数据库 .UseMonitorCommand(a => Trace.WriteLine(a.CommandText)) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 67dadc54..cbdb223b 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -247,7 +247,7 @@ namespace FreeSql.Tests .UseAutoSyncStructure(true) .UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) - .UseSyncStructureToUpper(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) .Build()); ib.Register("db3", () => new FreeSql.FreeSqlBuilder() diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 985eae8b..992dfb44 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -29,7 +29,7 @@ public class g //.UseConnectionFactory(FreeSql.DataType.PostgreSQL, () => new Npgsql.NpgsqlConnection("Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) - .UseSyncStructureToLower(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) .UseLazyLoading(true) .UseMonitorCommand( cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 @@ -60,7 +60,7 @@ public class g .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) - .UseSyncStructureToUpper(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) //.UseNoneCommandParameter(true) .UseMonitorCommand( diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index cd174404..d9dcf8c7 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -902,10 +902,11 @@ - + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + 是否不使用参数化 @@ -1937,10 +1938,11 @@ - + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + 是否不使用参数化 @@ -2692,12 +2694,12 @@ - 转小写同步结构 + 转小写同步结构,适用 PostgreSQL - 转大写同步结构 + 转大写同步结构,适用 Oracle/达梦 @@ -3178,14 +3180,52 @@ BigApple -> bigapple - + + + 不进行任何处理 + + + 将帕斯卡命名字符串转换为下划线分隔字符串 BigApple -> Big_Apple - - + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将下划线分隔字符串命名字符串转换为帕斯卡 + + big_apple -> BigApple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 26720246..c4b74eec 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -21,6 +21,7 @@ namespace FreeSql bool _isGenerateCommandParameterWithLambda = false; bool _isLazyLoading = false; StringConvertType _entityPropertyConvertType = StringConvertType.None; + NameConvertType _nameConvertType = NameConvertType.None; Action _aopCommandExecuting = null; Action _aopCommandExecuted = null; Type _providerType = null; @@ -82,6 +83,7 @@ namespace FreeSql /// /// true:转小写, false:不转 /// + [Obsolete("请使用 UseNameConvert(NameConvertType.ToLower),或者 fsql.CodeFirst.IsSyncStructureToLower = value")] public FreeSqlBuilder UseSyncStructureToLower(bool value) { _isSyncStructureToLower = value; @@ -92,6 +94,7 @@ namespace FreeSql /// /// true:转大写, false:不转 /// + [Obsolete("请使用 UseNameConvert(NameConvertType.ToUpper),或者 fsql.CodeFirst.IsSyncStructureToUpper = value")] public FreeSqlBuilder UseSyncStructureToUpper(bool value) { _isSyncStructureToUpper = value; @@ -163,12 +166,25 @@ namespace FreeSql /// /// /// + [Obsolete("请使用 UseNameConvert 功能")] public FreeSqlBuilder UseEntityPropertyNameConvert(StringConvertType convertType) { _entityPropertyConvertType = convertType; return this; } + /// + /// 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) + /// 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] + /// + /// + /// + public FreeSqlBuilder UseNameConvert(NameConvertType convertType) + { + _nameConvertType = convertType; + return this; + } + public IFreeSql Build() => Build(); public IFreeSql Build() { @@ -263,27 +279,60 @@ namespace FreeSql //添加实体属性名全局AOP转换处理 if (_entityPropertyConvertType != StringConvertType.None) { + string PascalCaseToUnderScore(string str) => string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); + switch (_entityPropertyConvertType) { case StringConvertType.Lower: - ret.Aop.ConfigEntityProperty += (_, e) => - e.ModifyResult.Name = e.Property.Name.ToLower(); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToLower(); break; case StringConvertType.Upper: - ret.Aop.ConfigEntityProperty += (_, e) => - e.ModifyResult.Name = e.Property.Name.ToUpper(); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToUpper(); break; case StringConvertType.PascalCaseToUnderscore: - ret.Aop.ConfigEntityProperty += (_, e) => - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name); break; case StringConvertType.PascalCaseToUnderscoreWithLower: - ret.Aop.ConfigEntityProperty += (_, e) => - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToLower(); break; case StringConvertType.PascalCaseToUnderscoreWithUpper: - ret.Aop.ConfigEntityProperty += (_, e) => - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToUpper(); + break; + default: + break; + } + } + //添加实体属性名全局AOP转换处理 + if (_nameConvertType != NameConvertType.None) + { + string PascalCaseToUnderScore(string str) => string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); + string UnderScorePascalCase(string str) => string.Join("", str.Split('_').Select(a => a.Length > 0 ? string.Concat(char.ToUpper(a[0]), a.Substring(1)) : "")); + + switch (_nameConvertType) + { + case NameConvertType.ToLower: + ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = e.EntityType.Name.ToLower(); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToLower(); + break; + case NameConvertType.ToUpper: + ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = e.EntityType.Name.ToUpper(); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToUpper(); + break; + case NameConvertType.PascalCaseToUnderscore: + ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.EntityType.Name); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name); + break; + case NameConvertType.PascalCaseToUnderscoreWithLower: + ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.EntityType.Name).ToLower(); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToLower(); + break; + case NameConvertType.PascalCaseToUnderscoreWithUpper: + ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.EntityType.Name).ToUpper(); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToUpper(); + break; + case NameConvertType.UnderscoreToPascalCase: + ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = UnderScorePascalCase(e.EntityType.Name); + ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = UnderScorePascalCase(e.Property.Name); break; default: break; diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 04f2085e..e242a390 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -13,11 +13,11 @@ namespace FreeSql bool IsAutoSyncStructure { get; set; } /// - /// 转小写同步结构 + /// 转小写同步结构,适用 PostgreSQL /// bool IsSyncStructureToLower { get; set; } /// - /// 转大写同步结构 + /// 转大写同步结构,适用 Oracle/达梦 /// bool IsSyncStructureToUpper { get; set; } /// diff --git a/FreeSql/Internal/StringConvertType.cs b/FreeSql/Internal/StringConvertType.cs index 281fe8fa..6571b7a0 100644 --- a/FreeSql/Internal/StringConvertType.cs +++ b/FreeSql/Internal/StringConvertType.cs @@ -1,4 +1,6 @@ -namespace FreeSql.Internal +using System; + +namespace FreeSql.Internal { public enum StringConvertType { @@ -42,4 +44,54 @@ /// Lower } + + public enum NameConvertType + { + /// + /// 不进行任何处理 + /// + None = 0, + + /// + /// 将帕斯卡命名字符串转换为下划线分隔字符串 + /// + /// BigApple -> Big_Apple + /// + PascalCaseToUnderscore, + + /// + /// 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + /// + /// BigApple -> BIG_APPLE + /// + PascalCaseToUnderscoreWithUpper, + + /// + /// 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + /// + /// BigApple -> big_apple + /// + PascalCaseToUnderscoreWithLower, + + /// + /// 将下划线分隔字符串命名字符串转换为帕斯卡 + /// + /// big_apple -> BigApple + /// + UnderscoreToPascalCase, + + /// + /// 将字符串转换为大写 + /// + /// BigApple -> BIGAPPLE + /// + ToUpper, + + /// + /// 将字符串转换为小写 + /// + /// BigApple -> bigapple + /// + ToLower + } } \ No newline at end of file diff --git a/FreeSql/Internal/StringUtils.cs b/FreeSql/Internal/StringUtils.cs deleted file mode 100644 index 6ec4819b..00000000 --- a/FreeSql/Internal/StringUtils.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Linq; - -namespace FreeSql.Internal -{ - public static class StringUtils - { - /// - /// 将帕斯卡命名字符串转换为下划线分隔字符串 - /// - /// BigApple -> Big_Apple - /// - /// - /// - public static string PascalCaseToUnderScore(string str) - { - return string.Concat(str.Select((x, i) => - i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); - } - } -} \ No newline at end of file From efedc894bf1c2e7917fec4214429996e1cd66c1c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 07:46:58 +0800 Subject: [PATCH 0523/1029] v1.4.0-preview20200331 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 15 ++++++++------- FreeSql/FreeSqlBuilder.cs | 14 +++++++------- FreeSql/Internal/StringConvertType.cs | 12 ++++++------ .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../Dameng/OdbcDamengDbFirst.cs | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../Oracle/OdbcOracleDbFirst.cs | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 41 insertions(+), 40 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index fbec3035..b10c6b35 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 47c6772c..b760e30f 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 1f776fcf..2b43c14a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5aae06d6..3df1af65 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 4241281d..a882080e 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.2 + 1.4.0-preview20200331 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 0b35c7d2..abe30376 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a293ab03..cd506171 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d2b7c4de..4889c0b9 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.2 + 1.4.0-preview20200331 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e0d7c107..c36544bf 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d9dcf8c7..d9c8421f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -755,6 +755,14 @@ + + + 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) + 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] + + + + 指定事务对象 @@ -3206,13 +3214,6 @@ BigApple -> big_apple - - - 将下划线分隔字符串命名字符串转换为帕斯卡 - - big_apple -> BigApple - - 将字符串转换为大写 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index c4b74eec..b3f304fd 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -83,7 +83,6 @@ namespace FreeSql /// /// true:转小写, false:不转 /// - [Obsolete("请使用 UseNameConvert(NameConvertType.ToLower),或者 fsql.CodeFirst.IsSyncStructureToLower = value")] public FreeSqlBuilder UseSyncStructureToLower(bool value) { _isSyncStructureToLower = value; @@ -94,7 +93,6 @@ namespace FreeSql /// /// true:转大写, false:不转 /// - [Obsolete("请使用 UseNameConvert(NameConvertType.ToUpper),或者 fsql.CodeFirst.IsSyncStructureToUpper = value")] public FreeSqlBuilder UseSyncStructureToUpper(bool value) { _isSyncStructureToUpper = value; @@ -306,17 +304,19 @@ namespace FreeSql if (_nameConvertType != NameConvertType.None) { string PascalCaseToUnderScore(string str) => string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); - string UnderScorePascalCase(string str) => string.Join("", str.Split('_').Select(a => a.Length > 0 ? string.Concat(char.ToUpper(a[0]), a.Substring(1)) : "")); + //string UnderScorePascalCase(string str) => string.Join("", str.Split('_').Select(a => a.Length > 0 ? string.Concat(char.ToUpper(a[0]), a.Substring(1)) : "")); switch (_nameConvertType) { case NameConvertType.ToLower: ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = e.EntityType.Name.ToLower(); ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToLower(); + ret.CodeFirst.IsSyncStructureToLower = true; break; case NameConvertType.ToUpper: ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = e.EntityType.Name.ToUpper(); ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToUpper(); + ret.CodeFirst.IsSyncStructureToUpper = true; break; case NameConvertType.PascalCaseToUnderscore: ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.EntityType.Name); @@ -330,10 +330,10 @@ namespace FreeSql ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.EntityType.Name).ToUpper(); ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToUpper(); break; - case NameConvertType.UnderscoreToPascalCase: - ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = UnderScorePascalCase(e.EntityType.Name); - ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = UnderScorePascalCase(e.Property.Name); - break; + //case NameConvertType.UnderscoreToPascalCase: + // ret.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = UnderScorePascalCase(e.EntityType.Name); + // ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = UnderScorePascalCase(e.Property.Name); + // break; default: break; } diff --git a/FreeSql/Internal/StringConvertType.cs b/FreeSql/Internal/StringConvertType.cs index 6571b7a0..da7e6104 100644 --- a/FreeSql/Internal/StringConvertType.cs +++ b/FreeSql/Internal/StringConvertType.cs @@ -73,12 +73,12 @@ namespace FreeSql.Internal /// PascalCaseToUnderscoreWithLower, - /// - /// 将下划线分隔字符串命名字符串转换为帕斯卡 - /// - /// big_apple -> BigApple - /// - UnderscoreToPascalCase, + ///// + ///// 将下划线分隔字符串命名字符串转换为帕斯卡 + ///// + ///// big_apple -> BigApple + ///// + //UnderscoreToPascalCase, /// /// 将字符串转换为大写 diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 6db7ff8e..c73a5c4e 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d186d0a8..760c470f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 353d98d3..63d5d7e2 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 9d9ad075..0edc66c7 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -306,7 +306,7 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name) and rownum < 2), 0), b.comments from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index f0e2dc1b..01f22d71 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index b88e7c1c..4be9ab2c 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -260,7 +260,7 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name) and rownum < 2), 0), b.comments from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 96126e6a..69b851b9 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 2d2e599e..b22f8679 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -260,7 +260,7 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name)), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name) and rownum < 2), 0), b.comments from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d9c02421..d385e201 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 8ab08abe..becc6eef 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 3c214f01..a50af04f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.2 + 1.4.0-preview20200331 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 72c3d91ca1efab5c8b0c765784f24333550841ef Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 12:42:13 +0800 Subject: [PATCH 0524/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20CodeFirst=20?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E7=B1=BB=E6=B3=A8=E9=87=8A=20->=20=E8=A1=A8?= =?UTF-8?q?=E5=A4=87=E6=B3=A8=EF=BC=8C=E4=B9=8B=E5=89=8D=E5=8F=AA=E8=83=BD?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E6=B3=A8=E9=87=8A=20->=20=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=A4=87=E6=B3=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 26 +++- Examples/base_entity/Test01/User.cs | 4 +- Examples/base_entity/Test01/UserRole.cs | 4 +- Examples/base_entity/base_entity.csproj | 1 + Examples/base_entity/base_entity.xml | 6 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 -- FreeSql/FreeSql.xml | 143 ------------------ FreeSql/FreeSqlBuilder.cs | 2 + FreeSql/Internal/CommonUtils.cs | 12 +- FreeSql/Internal/Model/TableInfo.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 10 +- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 15 +- .../Dameng/OdbcDamengCodeFirst.cs | 23 ++- .../MySql/OdbcMySqlCodeFirst.cs | 15 +- .../Oracle/OdbcOracleCodeFirst.cs | 26 +++- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 19 ++- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 2 +- .../SqlServer/OdbcSqlServerCodeFirst.cs | 38 +++++ .../OracleCodeFirst.cs | 20 ++- .../PostgreSQLCodeFirst.cs | 19 ++- .../PostgreSQLDbFirst.cs | 2 +- .../SqlServerCodeFirst.cs | 38 +++++ 22 files changed, 253 insertions(+), 182 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 5cb92a98..97aad3ee 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -41,15 +41,39 @@ namespace base_entity var fsql = new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) .UseNoneCommandParameter(true) + .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=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=2") - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + + //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) + + //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + + + //.UseConnectionString(FreeSql.DataType.OdbcMySql, "Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Max pool size=2") + + //.UseConnectionString(FreeSql.DataType.OdbcSqlServer, "Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Max pool size=3") + + //.UseConnectionString(FreeSql.DataType.OdbcPostgreSQL, "Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Maximum Pool Size=2") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) + + //.UseConnectionString(FreeSql.DataType.OdbcOracle, "Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") + .UseLazyLoading(true) .Build(); BaseEntity.Initialization(fsql); #endregion var test01 = EMSServerModel.Model.User.Select.IncludeMany(a => a.Roles).ToList(); + var test02 = EMSServerModel.Model.UserRole.Select.ToList(); var test01tb = EMSServerModel.Model.User.Orm.CodeFirst.GetTableByEntity(typeof(EMSServerModel.Model.User)); var us = User1.Select.Limit(10).ToList(); diff --git a/Examples/base_entity/Test01/User.cs b/Examples/base_entity/Test01/User.cs index 46dc8e95..be4fbeb2 100644 --- a/Examples/base_entity/Test01/User.cs +++ b/Examples/base_entity/Test01/User.cs @@ -8,10 +8,10 @@ using FreeSql; namespace EMSServerModel.Model { /// - /// 用户表 + /// 用户表bb123123 /// [JsonObject(MemberSerialization.OptIn)] - public partial class User : BaseEntity{ + public partial class User : BaseEntity { //[JsonProperty, Column(IsIdentity = true)] //public long Id { get; set; } diff --git a/Examples/base_entity/Test01/UserRole.cs b/Examples/base_entity/Test01/UserRole.cs index 3c13335a..1d031a08 100644 --- a/Examples/base_entity/Test01/UserRole.cs +++ b/Examples/base_entity/Test01/UserRole.cs @@ -5,12 +5,12 @@ using FreeSql; namespace EMSServerModel.Model { /// - /// ûɫϵ + /// ûɫϵaa111 /// [JsonObject(MemberSerialization.OptIn)] public partial class UserRole : BaseEntity{ /// - /// ɫ + /// ɫ1 /// [JsonProperty] public long RoleId { get; set; } diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index c912bae3..201c18db 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -21,6 +21,7 @@ + diff --git a/Examples/base_entity/base_entity.xml b/Examples/base_entity/base_entity.xml index a2fd01f9..1241b5ac 100644 --- a/Examples/base_entity/base_entity.xml +++ b/Examples/base_entity/base_entity.xml @@ -61,7 +61,7 @@ - 用户表 + 用户表bb123123 @@ -171,12 +171,12 @@ - 用户角色关系表 + 用户角色关系表aa111 - 角色编号 + 角色编号1 diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..d8bba58b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,15 +211,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d9c8421f..4ec6a7f0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2309,137 +2309,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2963,12 +2832,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3039,12 +2902,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index b3f304fd..800b3900 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -83,6 +83,7 @@ namespace FreeSql /// /// true:转小写, false:不转 /// + [Obsolete("请使用 UseNameConvert(NameConvertType.ToLower),或者 fsql.CodeFirst.IsSyncStructureToLower = value")] public FreeSqlBuilder UseSyncStructureToLower(bool value) { _isSyncStructureToLower = value; @@ -93,6 +94,7 @@ namespace FreeSql /// /// true:转大写, false:不转 /// + [Obsolete("请使用 UseNameConvert(NameConvertType.ToUpper),或者 fsql.CodeFirst.IsSyncStructureToUpper = value")] public FreeSqlBuilder UseSyncStructureToUpper(bool value) { _isSyncStructureToUpper = value; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 14a5e3a6..8a59fe20 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -400,11 +400,19 @@ namespace FreeSql.Internal } var xmlNav = xpath.CreateNavigator(); + var className = (type.IsNested ? $"{type.Namespace}.{type.DeclaringType.Name}.{type.Name}" : $"{type.Namespace}.{type.Name}").Trim('.'); + var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='T:{className}']/summary"); + if (node != null) + { + var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); + if (string.IsNullOrEmpty(comment) == false) dic.Add("", comment); //class注释 + } + var props = type.GetPropertiesDictIgnoreCase().Values; foreach (var prop in props) { - var className = (prop.DeclaringType.IsNested ? $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.DeclaringType.Name}.{prop.DeclaringType.Name}" : $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.Name}").Trim('.'); - var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); + className = (prop.DeclaringType.IsNested ? $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.DeclaringType.Name}.{prop.DeclaringType.Name}" : $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.Name}").Trim('.'); + node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); if (node == null) continue; var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); if (string.IsNullOrEmpty(comment)) continue; diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index 09223d1d..c882cc72 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -22,6 +22,7 @@ namespace FreeSql.Internal.Model public string DbName { get; set; } public string DbOldName { get; set; } public bool DisableSyncStructure { get; set; } + public string Comment { get; internal set; } public ColumnInfo VersionColumn { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c77baea9..632a89c6 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -69,6 +69,7 @@ namespace FreeSql.Internal var propsLazy = new List>(); var propsNavObjs = new List(); var propsComment = CommonUtils.GetProperyCommentBySummary(entity); + trytb.Comment = propsComment.TryGetValue("", out var tbcomment) ? tbcomment : ""; var columnsList = new List(); foreach (var p in trytb.Properties.Values) { @@ -370,7 +371,7 @@ namespace FreeSql.Internal foreach (var col in trytb.Primarys) { col.Attribute.IsNullable = false; - col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", ""); + col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "").Trim(); } foreach (var col in trytb.Columns.Values) { @@ -795,7 +796,14 @@ namespace FreeSql.Internal trytb.AddOrUpdateTableRef(pnv.Name, nvref); if (tbmid.Primarys.Any() == false) + { tbmid.Primarys = tbmid.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + foreach (var col in tbmid.Primarys) + { + col.Attribute.IsNullable = false; + col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "").Trim(); + } + } } if (isLazy) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index f96474f4..e48d751f 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -158,7 +158,10 @@ namespace FreeSql.MySql sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { @@ -291,6 +294,10 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select table_comment from information_schema.tables where table_schema = {0} and table_name = {1}", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" COMMENT ").Append(" ").Append(_commonUtils.FormatSql("{0}", tb.Comment ?? "")).Append(";\r\n"); + sb.Append(sbalter); continue; } @@ -314,7 +321,11 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 2edc8107..b28aad3f 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -165,6 +165,8 @@ namespace FreeSql.Odbc.Dameng if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); continue; } //如果新表,旧表在一个模式下,直接修改表名 @@ -189,8 +191,8 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), -nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name) and rownum < 2), 0), +nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI') and rownum < 2), 0), b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name @@ -219,7 +221,15 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { istmpatler = true; + if (istmpatler && tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + if (istmpatler && Regex.IsMatch(tbcol.Attribute.DbType, @"\(\d+") == false && Regex.IsMatch(tbstructcol.sqlType, @"\(\d+") + && string.Compare(tbcol.Attribute.DbType, Regex.Replace(tbstructcol.sqlType, @"\([^\)]+\)", ""), StringComparison.CurrentCultureIgnoreCase) == 0) + istmpatler = false; + } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { @@ -289,6 +299,10 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append(sbalter); continue; } @@ -321,6 +335,9 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -397,7 +414,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); var tiggerName = seqname + "TI"; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 94b34597..3e389fb6 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -151,7 +151,10 @@ namespace FreeSql.Odbc.MySql sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { @@ -284,6 +287,10 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select table_comment from information_schema.tables where table_schema = {0} and table_name = {1}", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" COMMENT ").Append(" ").Append(_commonUtils.FormatSql("{0}", tb.Comment ?? "")).Append(";\r\n"); + sb.Append(sbalter); continue; } @@ -307,7 +314,11 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index adec255e..f741ef1b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -165,6 +165,8 @@ namespace FreeSql.Odbc.Oracle if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); continue; } //如果新表,旧表在一个模式下,直接修改表名 @@ -189,8 +191,8 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), -nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name) and rownum < 2), 0), +nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI') and rownum < 2), 0), b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name @@ -219,7 +221,12 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { istmpatler = true; + if (tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { @@ -290,6 +297,10 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append(sbalter); continue; } @@ -322,6 +333,9 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -398,7 +412,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); var tiggerName = seqname + "TI"; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); @@ -440,6 +454,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam else if (sqlType.StartsWith("BLOB")) { } + else if (sqlType.StartsWith("CLOB")) + { + } + else if (sqlType.StartsWith("NCLOB")) + { + } else if (char_used.ToLower() == "c") sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; else if (char_used.ToLower() == "b") diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 14f4821d..bbc2d5e9 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -158,6 +158,8 @@ namespace FreeSql.Odbc.PostgreSQL if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -180,7 +182,7 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc, a.attndims, d.description as comment @@ -294,6 +296,16 @@ where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tbol } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select +d.description +from pg_class a +inner join pg_namespace b on b.oid = a.relnamespace +left join pg_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('r') and b.nspname = {0} and a.relname = {1} +and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews')", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + sb.Append(sbalter); continue; } @@ -329,6 +341,9 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -370,7 +385,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name").ToLower(); ; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 097a63ed..913ae1c3 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -209,7 +209,7 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc as is_identity, d.description as comment, a.attndims, diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 9633d8db..550903f3 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -71,6 +71,35 @@ namespace FreeSql.Odbc.SqlServer return null; } + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string comment) + { + if (string.IsNullOrEmpty(comment)) + { + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_dropextendedproperty @name = N'MS_Description' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''")); + return; + } + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +ELSE + EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); + } void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) { if (string.IsNullOrEmpty(comment)) @@ -216,6 +245,8 @@ ELSE if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -327,6 +358,10 @@ use [" + database + "];", tboldname ?? tbname); } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)")); + if (dbcomment != (tb.Comment ?? "")) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); + if (sbalter.Length > 0) sb.Append(sbalter).Append("\r\nuse " + database); continue; @@ -373,6 +408,9 @@ use [" + database + "];", tboldname ?? tbname); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tb.Comment); + if ((_commonUtils as OdbcSqlServerUtils).ServerVersion > 9) //SqlServer 2008+ sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 149011e7..b28bc7a2 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -166,6 +166,8 @@ namespace FreeSql.Oracle if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); continue; } //如果新表,旧表在一个模式下,直接修改表名 @@ -190,8 +192,8 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), -nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name) and rownum < 2), 0), +nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI') and rownum < 2), 0), b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name @@ -220,7 +222,12 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { istmpatler = true; + if (tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { @@ -291,6 +298,10 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append(sbalter); continue; } @@ -323,6 +334,9 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -399,7 +413,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); var tiggerName = seqname + "TI"; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 70011c5a..e5a65693 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -193,6 +193,8 @@ namespace FreeSql.PostgreSQL if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -215,7 +217,7 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc, a.attndims, d.description as comment @@ -329,6 +331,16 @@ where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tbol } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select +d.description +from pg_class a +inner join pg_namespace b on b.oid = a.relnamespace +left join pg_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('r') and b.nspname = {0} and a.relname = {1} +and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews')", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + sb.Append(sbalter); continue; } @@ -364,6 +376,9 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -405,7 +420,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name").ToLower(); var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index f5cbc3a0..eb586c98 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -319,7 +319,7 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc as is_identity, d.description as comment, a.attndims, diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 00cdc6f0..2d30c5ba 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -70,6 +70,35 @@ namespace FreeSql.SqlServer return null; } + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string comment) + { + if (string.IsNullOrEmpty(comment)) + { + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_dropextendedproperty @name = N'MS_Description' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''")); + return; + } + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +ELSE + EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); + } void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) { if (string.IsNullOrEmpty(comment)) @@ -215,6 +244,8 @@ ELSE if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -326,6 +357,10 @@ use [" + database + "];", tboldname ?? tbname); } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)")); + if (dbcomment != (tb.Comment ?? "")) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); + if (sbalter.Length > 0) sb.Append(sbalter).Append("\r\nuse " + database); continue; @@ -372,6 +407,9 @@ use [" + database + "];", tboldname ?? tbname); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tb.Comment); + if ((_commonUtils as SqlServerUtils).ServerVersion > 9) //SqlServer 2008+ sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); From d2dcefb5a51be7f0d96698e2259f534b58ac13a7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 12:57:12 +0800 Subject: [PATCH 0525/1029] v1.4.0-preview20200401 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 143 ++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 170 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b10c6b35..f37e95ad 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index b760e30f..3ba3ac25 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 2b43c14a..94f6b648 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 3df1af65..c29a0872 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index a882080e..c23ed6bb 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview20200331 + 1.4.0-preview20200401 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index abe30376..3f85750d 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index cd506171..14d4cc2c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d8bba58b..ddd18378 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,6 +211,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4889c0b9..4c5610c9 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c36544bf..19758aa2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4ec6a7f0..d9c8421f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2309,6 +2309,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 }) + + + + + + 可自定义解析表达式 @@ -2832,6 +2963,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2902,6 +3039,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 632a89c6..1d0676ae 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -69,7 +69,7 @@ namespace FreeSql.Internal var propsLazy = new List>(); var propsNavObjs = new List(); var propsComment = CommonUtils.GetProperyCommentBySummary(entity); - trytb.Comment = propsComment.TryGetValue("", out var tbcomment) ? tbcomment : ""; + trytb.Comment = propsComment != null && propsComment.TryGetValue("", out var tbcomment) ? tbcomment : ""; var columnsList = new List(); foreach (var p in trytb.Properties.Values) { diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index c73a5c4e..200e97e0 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 760c470f..45921bd5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 63d5d7e2..77b296c8 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 01f22d71..ad7711b1 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 69b851b9..8198b11f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d385e201..9c737f87 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index becc6eef..bdfcee7a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a50af04f..0bd3fb78 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200331 + 1.4.0-preview20200401 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From c6c874f6126bc38f53d3dea8ded6086225163565 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 17:14:32 +0800 Subject: [PATCH 0526/1029] update readme --- readme.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index b69664d5..dc5955ea 100644 --- a/readme.md +++ b/readme.md @@ -15,7 +15,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 深入的类型映射,比如pgsql的数组类型; - [x] 支持 丰富的表达式函数,以及灵活的自定义解析; - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; -- [x] 支持 读写分离、分表分库,租户设计,过滤器,乐观锁,悲观锁; +- [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; - [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库/Access; ## Documentation @@ -40,8 +40,6 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [😃 A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) - [内容管理系统](https://github.com/hejiyong/fscms) -欢迎更多使用 FreeSql 的开源项目加入目录 -

@@ -114,7 +112,7 @@ fsql.Select() .OrderByDescending(a => a.Id) .ToList() ``` -更多前往Wiki:[《Select 查询数据文档》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) +[More..](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) ```csharp fsql.Select() @@ -130,7 +128,7 @@ fsql.Select() .Limit(10) .ToList(); ``` -更多前往Wiki:[《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) +[More..](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) ## Repository & UnitOfWork > dotnet add package FreeSql.Repository @@ -184,7 +182,7 @@ Elapsed: 00:00:00.6707125; ToList Entity Counts: 131072; ORM: FreeSql* Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ``` -[Test code](FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs)、[More](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd) +[More..](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd) ## Contributors From d4fd81679d54f52ce1ac6a3a567bc492fbc1d16b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 21:43:07 +0800 Subject: [PATCH 0527/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=9B=A0?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=20#184=20=E5=AF=BC=E8=87=B4=20MySql=20Enum?= =?UTF-8?q?=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=E4=B8=BA=20int?= =?UTF-8?q?=20=E7=9A=84=20bug=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20FreeSql.?= =?UTF-8?q?Provider.MySqlConnector=20Enum=20=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=85=83=E7=B4=A0=E5=80=BC=EF=BC=8C=E5=AF=BC=E8=87=B4=E5=80=BC?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E9=94=99=E8=AF=AF=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 127 +++++++++++++++++ .../MySql/Curd/MySqlUpdateTest.cs | 72 ++++++++++ .../MySql/Curd/MySqlUpdateTest.cs | 128 ++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 15 +- .../Internal/CommonProvider/UpdateProvider.cs | 3 +- .../MySqlConnectorUtils.cs | 21 ++- 6 files changed, 358 insertions(+), 8 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 34f0a3c8..441fdfd5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -160,6 +160,133 @@ namespace FreeSql.Tests.MySqlConnector g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); } + public class tenumcls + { + public Guid id { get; set; } + public tenum status { get; set; } + } + public enum tenum + { + WaitPay = 1, + Pay = 3, + Finsh = 8, + Cacel = 16, + Refunding = 32 + } + [Fact] + public void SetEnum() + { + var fsql = g.mysql; + //#184 + fsql.Delete(Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb")).ExecuteAffrows(); + var item = new tenumcls { id = Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb"), status = tenum.Finsh }; + Assert.Equal("INSERT INTO `tenumcls`(`id`, `status`) VALUES('5e83a910-672f-847c-00c1-316b71d153fb', 'Finsh')", + fsql.Insert().NoneParameter().AppendData(item).ToSql()); + Assert.Equal(1, fsql.Insert().NoneParameter().AppendData(item).ExecuteAffrows()); + var item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = case when `id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Pay).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Pay).ExecuteAffrows()); + + Assert.Equal(@"SELECT a.`id`, a.`status` +FROM `tenumcls` a +WHERE (a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' AND a.`status` = case when a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end) +limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).Limit(1).ToSql()); + item2 = fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + //Parameter + fsql.Delete(Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb")).ExecuteAffrows(); + item = new tenumcls { id = Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb"), status = tenum.Finsh }; + Assert.Equal("INSERT INTO `tenumcls`(`id`, `status`) VALUES(@id_0, @status_0)", + fsql.Insert().AppendData(item).ToSql()); + Assert.Equal(1, fsql.Insert().AppendData(item).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = case when `id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status == tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status == tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status == tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status == tenum.Pay).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = @p_0 +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status, tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status, tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = @p_0 +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status, tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status, tenum.Pay).ExecuteAffrows()); + + Assert.Equal(@"SELECT a.`id`, a.`status` +FROM `tenumcls` a +WHERE (a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' AND a.`status` = case when a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end) +limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).Limit(1).ToSql()); + item2 = fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + } [Fact] public void SetRaw() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs index c823a1fc..ac8f603f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -160,6 +160,78 @@ namespace FreeSql.Tests.Odbc.MySql g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); } + public class tenumcls + { + public Guid id { get; set; } + public tenum status { get; set; } + } + public enum tenum + { + WaitPay = 1, + Pay = 3, + Finsh = 8, + Cacel = 16, + Refunding = 32 + } + [Fact] + public void SetEnum() + { + var fsql = g.mysql; + //#184 + fsql.Delete(Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb")).ExecuteAffrows(); + var item = new tenumcls { id = Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb"), status = tenum.Finsh }; + Assert.Equal("INSERT INTO `tenumcls`(`id`, `status`) VALUES('5e83a910-672f-847c-00c1-316b71d153fb', 'Finsh')", + fsql.Insert().NoneParameter().AppendData(item).ToSql()); + Assert.Equal(1, fsql.Insert().NoneParameter().AppendData(item).ExecuteAffrows()); + var item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = case when `id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Pay).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Pay).ExecuteAffrows()); + + Assert.Equal(@"SELECT a.`id`, a.`status` +FROM `tenumcls` a +WHERE (a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' AND a.`status` = case when a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end) +limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).Limit(1).ToSql()); + item2 = fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + } [Fact] public void SetRaw() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 98ce79c2..b216d48b 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -161,6 +161,134 @@ namespace FreeSql.Tests.MySql g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); } + public class tenumcls + { + public Guid id { get; set; } + public tenum status { get; set; } + } + public enum tenum + { + WaitPay = 1, + Pay = 3, + Finsh = 8, + Cacel = 16, + Refunding = 32 + } + [Fact] + public void SetEnum() + { + var fsql = g.mysql; + //#184 + fsql.Delete(Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb")).ExecuteAffrows(); + var item = new tenumcls { id = Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb"), status = tenum.Finsh }; + Assert.Equal("INSERT INTO `tenumcls`(`id`, `status`) VALUES('5e83a910-672f-847c-00c1-316b71d153fb', 'Finsh')", + fsql.Insert().NoneParameter().AppendData(item).ToSql()); + Assert.Equal(1, fsql.Insert().NoneParameter().AppendData(item).ExecuteAffrows()); + var item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = case when `id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Pay).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Pay).ExecuteAffrows()); + + Assert.Equal(@"SELECT a.`id`, a.`status` +FROM `tenumcls` a +WHERE (a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' AND a.`status` = case when a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end) +limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).Limit(1).ToSql()); + item2 = fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + //Parameter + fsql.Delete(Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb")).ExecuteAffrows(); + item = new tenumcls { id = Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb"), status = tenum.Finsh }; + Assert.Equal("INSERT INTO `tenumcls`(`id`, `status`) VALUES(?id_0, ?status_0)", + fsql.Insert().AppendData(item).ToSql()); + Assert.Equal(1, fsql.Insert().AppendData(item).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = case when `id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status == tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status == tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status == tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status == tenum.Pay).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = ?p_0 +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status, tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status, tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = ?p_0 +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).Set(a => a.status, tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).Set(a => a.status, tenum.Pay).ExecuteAffrows()); + + Assert.Equal(@"SELECT a.`id`, a.`status` +FROM `tenumcls` a +WHERE (a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' AND a.`status` = case when a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end) +limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).Limit(1).ToSql()); + item2 = fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + } + [Fact] public void SetRaw() { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 93e78a51..07dfb1d4 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -489,7 +489,9 @@ namespace FreeSql.Internal var right = ExpressionLambdaToSql(rightExp, tsc); if (right != "NULL" && isLeftMapType && //判断参数化后的bug - !(right.Contains('@') || right.Contains('?') || right.Contains(':'))) + !(right.Contains('@') || right.Contains('?') || right.Contains(':')) && + //三元表达式后,取消此条件 #184 + tsc.mapType != null) { var enumType = leftMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) @@ -505,7 +507,9 @@ namespace FreeSql.Internal left = ExpressionLambdaToSql(leftExp, tsc); if (left != "NULL" && isRightMapType && //判断参数化后的bug - !(left.Contains('@') || left.Contains('?') || left.Contains(':'))) + !(left.Contains('@') || left.Contains('?') || left.Contains(':')) && + //三元表达式后,取消此条件 #184 + tsc.mapType != null) { var enumType = rightMapColumn.CsType.NullableTypeOrThis(); if (enumType.IsEnum) @@ -598,7 +602,12 @@ namespace FreeSql.Internal case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, null); case ExpressionType.Conditional: var condExp = exp as ConditionalExpression; - return _common.IIF(ExpressionLambdaToSql(condExp.Test, tsc), ExpressionLambdaToSql(condExp.IfTrue, tsc), ExpressionLambdaToSql(condExp.IfFalse, tsc)); + var conditionalTestOldMapType = tsc.SetMapTypeReturnOld(null); + var conditionalTestSql = ExpressionLambdaToSql(condExp.Test, tsc); + tsc.SetMapTypeReturnOld(conditionalTestOldMapType); + var conditionalSql = _common.IIF(conditionalTestSql, ExpressionLambdaToSql(condExp.IfTrue, tsc), ExpressionLambdaToSql(condExp.IfFalse, tsc)); + tsc.SetMapTypeReturnOld(null); + return conditionalSql; case ExpressionType.Call: tsc.mapType = null; var exp3 = exp as MethodCallExpression; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index f5890251..6f04aafd 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -406,8 +406,7 @@ namespace FreeSql.Internal.CommonProvider { case ExpressionType.Equal: var equalBinaryExp = body as BinaryExpression; - _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, equalBinaryExp.Left, null, null)) - .Append(" = ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, equalBinaryExp.Right, null, null)); + _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, body, null, null)); return this; case ExpressionType.MemberInit: var initExp = body as MemberInitExpression; diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 8541261f..cdb6996e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Data.Common; namespace FreeSql.MySql @@ -44,12 +45,11 @@ namespace FreeSql.MySql { ret.MySqlDbType = dbtype; if (ret.MySqlDbType == MySqlDbType.Enum && value != null) - ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + ret.Value = EnumValueToMySql(col, value); } _params?.Add(ret); return ret; } - public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { @@ -66,12 +66,27 @@ namespace FreeSql.MySql { ret.MySqlDbType = (MySqlDbType)tp.Value; if (ret.MySqlDbType == MySqlDbType.Enum && value != null) - ret.Value = (long)Convert.ChangeType(value, typeof(long)) + 1; + ret.Value = EnumValueToMySql(null, value); } } return ret; }); + static ConcurrentDictionary> _dicEnumNames = new ConcurrentDictionary>(); + static long EnumValueToMySql(ColumnInfo col, object value) //mysqlConnector 不支持 enumString 作为参数化传递,所以要计算出下标值,mysql 下标从 1 开始,并且 c# 设置了枚举元素值会影响下标 + { + if (value == null) return 0; + if (value is Enum == false) return 0; + var names = _dicEnumNames.GetOrAdd(col?.Attribute.MapType ?? value.GetType(), type => + { + var dic = new Dictionary(); + var ns = Enum.GetNames(type); + for (var a = 0; a < ns.Length; a++) dic.Add(ns[a], a + 1); + return dic; + }); + return names.TryGetValue(value.ToString(), out var tryval) ? tryval : 0; + } + public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); public override string QuoteSqlName(params string[] name) { From cf1aefe8dab21407b0fe76e96c54da5d2117a8f9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 21:59:51 +0800 Subject: [PATCH 0528/1029] ## v1.3.3 #184 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../MySqlConnectorUtils.cs | 11 ++++++----- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 23 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f37e95ad..46e68495 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 3ba3ac25..0be188cd 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 94f6b648..f5fa4e5c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c29a0872..f2b4ca90 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index c23ed6bb..846167bf 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview20200401 + 1.3.3 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3f85750d..fb679741 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 14d4cc2c..932eb90c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4c5610c9..f6b2dc90 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200401 + 1.3.3 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 19758aa2..cd686512 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 200e97e0..99e0024f 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 45921bd5..b3898c1e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 77b296c8..1017cf89 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index cdb6996e..83032db7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -45,7 +45,7 @@ namespace FreeSql.MySql { ret.MySqlDbType = dbtype; if (ret.MySqlDbType == MySqlDbType.Enum && value != null) - ret.Value = EnumValueToMySql(col, value); + ret.Value = EnumValueToMySql(value); } _params?.Add(ret); return ret; @@ -66,18 +66,19 @@ namespace FreeSql.MySql { ret.MySqlDbType = (MySqlDbType)tp.Value; if (ret.MySqlDbType == MySqlDbType.Enum && value != null) - ret.Value = EnumValueToMySql(null, value); + ret.Value = EnumValueToMySql(value); } } return ret; }); static ConcurrentDictionary> _dicEnumNames = new ConcurrentDictionary>(); - static long EnumValueToMySql(ColumnInfo col, object value) //mysqlConnector 不支持 enumString 作为参数化传递,所以要计算出下标值,mysql 下标从 1 开始,并且 c# 设置了枚举元素值会影响下标 + static long EnumValueToMySql(object value) //mysqlConnector 不支持 enumString 作为参数化传递,所以要计算出下标值,mysql 下标从 1 开始,并且 c# 设置了枚举元素值会影响下标 { if (value == null) return 0; - if (value is Enum == false) return 0; - var names = _dicEnumNames.GetOrAdd(col?.Attribute.MapType ?? value.GetType(), type => + var valueType = value.GetType().NullableTypeOrThis(); + if (valueType.IsEnum == false) return 0; + var names = _dicEnumNames.GetOrAdd(valueType, type => { var dic = new Dictionary(); var ns = Enum.GetNames(type); diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index ad7711b1..ea0771e9 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8198b11f..f352910d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 9c737f87..3170e6a0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index bdfcee7a..9839a893 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 0bd3fb78..605437c1 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200401 + 1.3.3 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From cc1f5069f8fb140b599a03dbb9dea5740a07b989 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 1 Apr 2020 13:52:52 +0800 Subject: [PATCH 0529/1029] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20SqlServer=20char?= =?UTF-8?q?index=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=87=BD=E6=95=B0=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=BD=8D=E7=BD=AE=E7=9A=84=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs | 2 +- .../SqlServer/OdbcSqlServerExpression.cs | 4 ++-- Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs index a1dd0314..745091fe 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs @@ -105,7 +105,7 @@ namespace FreeSql.Odbc.Default public virtual string LambdaString_ToLower(string operand) => $"lower({operand})"; public virtual string LambdaString_ToUpper(string operand) => $"upper({operand})"; public virtual string LambdaString_Substring(string operand, string startIndex, string length) => string.IsNullOrEmpty(length) ? $"left({operand}, {startIndex})" : $"substring({operand}, {startIndex}, {length})"; - public virtual string LambdaString_IndexOf(string operand, string value, string startIndex) => string.IsNullOrEmpty(startIndex) ? $"(charindex({operand}, {value})-1)" : $"(charindex({operand}, {value}, {startIndex})-1)"; + public virtual string LambdaString_IndexOf(string operand, string value, string startIndex) => string.IsNullOrEmpty(startIndex) ? $"(charindex({value}, {operand})-1)" : $"(charindex({value}, {operand}, {startIndex})-1)"; public virtual string LambdaString_PadLeft(string operand, string length, string paddingChar) => string.IsNullOrEmpty(paddingChar) ? $"lpad({operand}, {length})" : $"lpad({operand}, {length}, {paddingChar})"; public virtual string LambdaString_PadRight(string operand, string length, string paddingChar) => string.IsNullOrEmpty(paddingChar) ? $"rpad({operand}, {length})" : $"rpad({operand}, {length}, {paddingChar})"; public virtual string LambdaString_Trim(string operand) => $"ltrim(rtrim({operand}))"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index dcbdfec7..280a6181 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -282,9 +282,9 @@ namespace FreeSql.Odbc.SqlServer var locateArgs1 = getExp(exp.Arguments[1]); if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); else locateArgs1 += "+1"; - return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)"; + return $"(charindex({indexOfFindStr}, {left}, {locateArgs1})-1)"; } - return $"(charindex({left}, {indexOfFindStr})-1)"; + return $"(charindex({indexOfFindStr}, {left})-1)"; case "PadLeft": if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 8aba97e0..4abd09ac 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -282,9 +282,9 @@ namespace FreeSql.SqlServer var locateArgs1 = getExp(exp.Arguments[1]); if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); else locateArgs1 += "+1"; - return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)"; + return $"(charindex({indexOfFindStr}, {left}, {locateArgs1})-1)"; } - return $"(charindex({left}, {indexOfFindStr})-1)"; + return $"(charindex({indexOfFindStr}, {left})-1)"; case "PadLeft": if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; From 55ae5bdc9b3ef81c8cedea98d70448e6c517430d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 1 Apr 2020 13:55:38 +0800 Subject: [PATCH 0530/1029] v1.4.0-preview20200402 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 46e68495..86c8b87b 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 0be188cd..04a3c195 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index f5fa4e5c..35e21f47 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index f2b4ca90..86e114f8 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 846167bf..2d98270c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.3 + 1.4.0-preview20200402 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index fb679741..5fd5c2e4 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 932eb90c..989d6d37 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index f6b2dc90..38d6c96f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.3 + 1.4.0-preview20200402 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cd686512..8341d4f5 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 99e0024f..a41be7a4 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b3898c1e..a19246ab 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 1017cf89..37b8b693 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index ea0771e9..0139d8de 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index f352910d..8d0fca71 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 3170e6a0..04476fea 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9839a893..a14f4b37 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 605437c1..8ccd1147 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.3 + 1.4.0-preview20200402 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 339a57ffc8dc5db60fcb541a80e905a43782be1b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 1 Apr 2020 14:02:26 +0800 Subject: [PATCH 0531/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20MySql=20loca?= =?UTF-8?q?te=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=87=BD=E6=95=B0=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=BD=8D=E7=BD=AE=E7=9A=84=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.MySql/MySqlExpression.cs | 4 ++-- Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index d7339eac..ee3ec1bb 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -278,9 +278,9 @@ namespace FreeSql.MySql var locateArgs1 = getExp(exp.Arguments[1]); if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); else locateArgs1 += "+1"; - return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)"; + return $"(locate({indexOfFindStr}, {left}, {locateArgs1})-1)"; } - return $"(locate({left}, {indexOfFindStr})-1)"; + return $"(locate({indexOfFindStr}, {left})-1)"; case "PadLeft": if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 3fdf6e2a..cb2c6bf8 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -278,9 +278,9 @@ namespace FreeSql.Odbc.MySql var locateArgs1 = getExp(exp.Arguments[1]); if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); else locateArgs1 += "+1"; - return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)"; + return $"(locate({indexOfFindStr}, {left}, {locateArgs1})-1)"; } - return $"(locate({left}, {indexOfFindStr})-1)"; + return $"(locate({indexOfFindStr}, {left})-1)"; case "PadLeft": if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; From b6377189eaac403d220be5f0208ea4265bfd890f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 1 Apr 2020 14:12:07 +0800 Subject: [PATCH 0532/1029] v1.3.4 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 17 insertions(+), 33 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 86c8b87b..b5ddd118 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 04a3c195..b8b85b3a 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 35e21f47..608ef363 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 86e114f8..5d71e275 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 2d98270c..b50e77b5 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview20200402 + 1.3.4 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 5fd5c2e4..f6ddd006 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 989d6d37..d1a7ec0e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..28fdb213 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据
- - - 根据 lambda 条件删除数据 - - - - 添加 @@ -211,15 +204,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 38d6c96f..0b904133 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200402 + 1.3.4 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8341d4f5..f865e002 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index a41be7a4..f7dcddd4 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index a19246ab..64aed809 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 37b8b693..66079e73 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0139d8de..47a35ca2 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8d0fca71..41ce63a7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 04476fea..7977a5e8 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a14f4b37..26c0f841 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 8ccd1147..911611e2 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200402 + 1.3.4 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 90b2418fb000a252531ea5be2a0250c0df3421f0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 1 Apr 2020 23:20:42 +0800 Subject: [PATCH 0533/1029] add summary --- FreeSql.DbContext/DbContext/DbContext.cs | 5 ++++ FreeSql.DbContext/FreeSql.DbContext.xml | 28 +++++++++++++++++++ .../Repository/Repository/IBaseRepository.cs | 5 ++++ 3 files changed, 38 insertions(+) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 9524f9b4..9f59b794 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -11,6 +11,11 @@ namespace FreeSql public abstract partial class DbContext : IDisposable { internal IFreeSql _ormPriv; + + /// + /// 注意:IFreeSql 属于顶级对象,事务无法自动传递。 + /// 手工传递事务:ISelect/IInsert/IDelete/IUpdate 可以使用 WithTransaction(uow.GetOrBeginTransaction()) + /// public IFreeSql Orm => _ormPriv ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); #region Property UnitOfWork diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 28fdb213..2fa6c448 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -4,6 +4,12 @@ FreeSql.DbContext + + + 注意:IFreeSql 属于顶级对象,事务无法自动传递。 + 手工传递事务:ISelect/IInsert/IDelete/IUpdate 可以使用 WithTransaction(uow.GetOrBeginTransaction()) + + 添加 @@ -110,6 +116,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -204,6 +217,21 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + + + + 注意:IFreeSql 属于顶级对象,事务无法自动传递。 + 手工传递事务:ISelect/IInsert/IDelete/IUpdate 可以使用 WithTransaction(uow.GetOrBeginTransaction()) + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index e172073f..db8c71a0 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -10,6 +10,11 @@ namespace FreeSql { Type EntityType { get; } IUnitOfWork UnitOfWork { get; set; } + + /// + /// 注意:IFreeSql 属于顶级对象,事务无法自动传递。 + /// 手工传递事务:ISelect/IInsert/IDelete/IUpdate 可以使用 WithTransaction(uow.GetOrBeginTransaction()) + /// IFreeSql Orm { get; } /// From 1d09b7fba37d3bfb385c9d01e9ce1a94578d1400 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 2 Apr 2020 13:27:37 +0800 Subject: [PATCH 0534/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20PostgreSQL?= =?UTF-8?q?=20CodeFirst/DbFirst=20=E7=B3=BB=E7=BB=9F=E8=A1=A8=E7=9A=84?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=85=BC=E5=AE=B9=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 4 ++-- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 6 +++--- .../FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index bbc2d5e9..382de62f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -182,8 +182,8 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid) is_identity, a.attndims, d.description as comment from pg_class c @@ -219,7 +219,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]) == "1", //string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), attndims, comment = string.Concat(a[7]) }; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 913ae1c3..db21a33f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -209,8 +209,8 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, -coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, ---e.adsrc as is_identity, +--e.adsrc as is_identity, pg12以下 +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid) is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, @@ -236,7 +236,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]) == "1"; //string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); var comment = string.Concat(row[7]); int attndims = int.Parse(string.Concat(row[8])); string typtype = string.Concat(row[9]); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index e5a65693..ba8f6671 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -217,8 +217,8 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid) is_identity, a.attndims, d.description as comment from pg_class c @@ -254,7 +254,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]) == "1", //string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), attndims, comment = string.Concat(a[7]) }; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index eb586c98..29c93a20 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -319,8 +319,8 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, -coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, ---e.adsrc as is_identity, +--e.adsrc as is_identity, pg12以下 +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid) is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, @@ -346,7 +346,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]) == "1"; //string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); var comment = string.Concat(row[7]); int attndims = int.Parse(string.Concat(row[8])); string typtype = string.Concat(row[9]); From 6ea5c5d1035e2011aec0af91765fb965beffe191 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 2 Apr 2020 14:20:10 +0800 Subject: [PATCH 0535/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20PostgreSQL?= =?UTF-8?q?=20CodeFirst/DbFirst=20=E7=B3=BB=E7=BB=9F=E8=A1=A8=E7=9A=84?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=85=BC=E5=AE=B9=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 2 +- .../FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs | 2 +- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs | 2 +- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 382de62f..854ee076 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -183,7 +183,7 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, --e.adsrc, -(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid) is_identity, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, a.attndims, d.description as comment from pg_class c diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index db21a33f..24a12ed9 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -210,7 +210,7 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, --e.adsrc as is_identity, pg12以下 -(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid) is_identity, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index ba8f6671..392f55bf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -218,7 +218,7 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, --e.adsrc, -(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid) is_identity, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, a.attndims, d.description as comment from pg_class c diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 29c93a20..d43cbd83 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -320,7 +320,7 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, --e.adsrc as is_identity, pg12以下 -(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid) is_identity, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, From e5cbd407cbfc752b691221d5a194d940c829a5fd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 2 Apr 2020 16:21:18 +0800 Subject: [PATCH 0536/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSqlBuild?= =?UTF-8?q?er=20UseSeedData=20=E8=AE=BE=E5=AE=9A=20CodeFirst=20=E7=A7=8D?= =?UTF-8?q?=E5=AD=90=E6=95=B0=E6=8D=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 19 +- .../BaseEntity.cs | 3 +- .../BaseEntityAsync.cs | 3 +- .../BaseEntityReadOnly.cs | 29 ++- FreeSql.DbContext/FreeSql.DbContext.xml | 9 - FreeSql/FreeSql.xml | 195 +++--------------- FreeSql/FreeSqlBuilder.cs | 127 ++++++------ FreeSql/FreeSqlBuilder_Obsolete.cs | 80 +++++++ 8 files changed, 222 insertions(+), 243 deletions(-) create mode 100644 FreeSql/FreeSqlBuilder_Obsolete.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 97aad3ee..9d762f82 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -65,7 +65,24 @@ namespace base_entity //.UseConnectionString(FreeSql.DataType.OdbcOracle, "Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456") //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) - .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") + //.UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") + + .UseMonitorCommand(cmd => Console.Write(cmd.CommandText)) + .UseSeedData(sd => sd + .Apply(new[] + { + new Products { Id = 1, title = "product-1" }, + new Products { Id = 2, title = "product-2" }, + new Products { Id = 3, title = "product-3" }, + new Products { Id = 4, title = "product-4" } + }) + .Apply(new[] + { + new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" } }, + new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" } }, + new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" } } + }) + ) .UseLazyLoading(true) .Build(); diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index 516fdbd9..829e33c5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -25,8 +25,7 @@ namespace FreeSql { var tkeyType = typeof(TKey)?.NullableTypeOrThis(); if (tkeyType == typeof(int) || tkeyType == typeof(long)) - Orm.CodeFirst.ConfigEntity(typeof(TEntity), - t => t.Property("Id").IsIdentity(true)); + BaseEntity.ConfigEntity(typeof(TEntity), t => t.Property("Id").IsIdentity(true)); } /// diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index 0d412cdb..fb43fcb9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -21,8 +21,7 @@ namespace FreeSql { var tkeyType = typeof(TKey)?.NullableTypeOrThis(); if (tkeyType == typeof(int) || tkeyType == typeof(long)) - Orm.CodeFirst.ConfigEntity(typeof(TEntity), - t => t.Property("Id").IsIdentity(true)); + BaseEntity.ConfigEntity(typeof(TEntity), t => t.Property("Id").IsIdentity(true)); } /// diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index e50030ab..68174990 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -4,6 +4,7 @@ using FreeSql.DataAnnotations; using System; using System.Collections; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Data; using System.Diagnostics; using System.Linq; @@ -18,7 +19,7 @@ namespace FreeSql [Table(DisableSyncStructure = true)] public abstract class BaseEntity { - static IFreeSql _ormPriv; + internal static IFreeSql _ormPriv; /// /// 全局 IFreeSql orm 对象 /// @@ -42,6 +43,32 @@ namespace FreeSql { _ormPriv = fsql; _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine($"\r\n线程{Thread.CurrentThread.ManagedThreadId}: {e.Sql}\r\n"); + if (_configEntityQueues.Any()) + { + lock (_configEntityLock) + { + while (_configEntityQueues.TryDequeue(out var cei)) + _ormPriv.CodeFirst.ConfigEntity(cei.EntityType, cei.Fluent); + } + } + } + + class ConfigEntityInfo + { + public Type EntityType; + public Action Fluent; + } + static ConcurrentQueue _configEntityQueues = new ConcurrentQueue(); + static object _configEntityLock = new object(); + internal static void ConfigEntity(Type entityType, Action fluent) + { + lock (_configEntityLock) + { + if (_ormPriv == null) + _configEntityQueues.Enqueue(new ConfigEntityInfo { EntityType = entityType, Fluent = fluent }); + else + _ormPriv.CodeFirst.ConfigEntity(entityType, fluent); + } } /// diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2fa6c448..bd335d0e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -217,15 +217,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d9c8421f..e9379bd3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -690,20 +690,6 @@ true:运行时检查自动同步结构, false:不同步结构 - - - 转小写同步结构 - - true:转小写, false:不转 - - - - - 转大写同步结构 - - true:转大写, false:不转 - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 @@ -746,6 +732,36 @@ 执行后,可监视执行性能 + + + 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) + 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] + + + + + + + CodeFirst 初始化种子数据 + 表数据为空时,创建设定的种子数据 + + + + + + + 转小写同步结构 + + true:转小写, false:不转 + + + + + 转大写同步结构 + + true:转大写, false:不转 + + 自动转换实体属性名称 Entity Property -> Db Filed @@ -755,14 +771,6 @@ - - - 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) - 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] - - - - 指定事务对象 @@ -2309,137 +2317,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2963,12 +2840,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3039,12 +2910,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 800b3900..11e881a7 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Reflection; @@ -7,7 +8,7 @@ using FreeSql.Internal; namespace FreeSql { - public class FreeSqlBuilder + public partial class FreeSqlBuilder { DataType _dataType; string _masterConnectionString; @@ -79,28 +80,6 @@ namespace FreeSql return this; } /// - /// 转小写同步结构 - /// - /// true:转小写, false:不转 - /// - [Obsolete("请使用 UseNameConvert(NameConvertType.ToLower),或者 fsql.CodeFirst.IsSyncStructureToLower = value")] - public FreeSqlBuilder UseSyncStructureToLower(bool value) - { - _isSyncStructureToLower = value; - return this; - } - /// - /// 转大写同步结构 - /// - /// true:转大写, false:不转 - /// - [Obsolete("请使用 UseNameConvert(NameConvertType.ToUpper),或者 fsql.CodeFirst.IsSyncStructureToUpper = value")] - public FreeSqlBuilder UseSyncStructureToUpper(bool value) - { - _isSyncStructureToUpper = value; - return this; - } - /// /// 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 /// 本功能会影响 IFreeSql 首次访问的速度。 /// 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 @@ -159,20 +138,6 @@ namespace FreeSql return this; } - /// - /// 自动转换实体属性名称 Entity Property -> Db Filed - /// - /// *不会覆盖 [Column] 特性设置的Name - /// - /// - /// - [Obsolete("请使用 UseNameConvert 功能")] - public FreeSqlBuilder UseEntityPropertyNameConvert(StringConvertType convertType) - { - _entityPropertyConvertType = convertType; - return this; - } - /// /// 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) /// 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] @@ -276,32 +241,7 @@ namespace FreeSql _aopCommandExecuted?.Invoke(e.Command, e.Log); }); - //添加实体属性名全局AOP转换处理 - if (_entityPropertyConvertType != StringConvertType.None) - { - string PascalCaseToUnderScore(string str) => string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); - - switch (_entityPropertyConvertType) - { - case StringConvertType.Lower: - ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToLower(); - break; - case StringConvertType.Upper: - ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToUpper(); - break; - case StringConvertType.PascalCaseToUnderscore: - ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name); - break; - case StringConvertType.PascalCaseToUnderscoreWithLower: - ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToLower(); - break; - case StringConvertType.PascalCaseToUnderscoreWithUpper: - ret.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToUpper(); - break; - default: - break; - } - } + this.EntityPropertyNameConvert(ret); //添加实体属性名全局AOP转换处理 if (_nameConvertType != NameConvertType.None) { @@ -362,9 +302,70 @@ namespace FreeSql } } }); + + //SeedData + if (_seedData != null && _seedData._data.Any()) + { + ret.Aop.SyncStructureAfter += new EventHandler((s, e) => + { + if (string.IsNullOrEmpty(e.Sql)) return; + foreach (var et in e.EntityTypes) + { + if (_seedData._data.TryGetValue(et, out var sd) == false) continue; + if (sd.Any() == false) continue; + if (ret.Select().AsType(et).Any()) continue; + ret.Insert() + .AsType(et) + .NoneParameter() + .InsertIdentity() + .AppendData(sd.ToArray()) + .ExecuteAffrows(); + } + }); + + foreach (var sd in _seedData._data) + { + ret.CodeFirst.SyncStructure(sd.Key); + } + } } return ret; } + + public class SeedDataBuilder + { + internal Dictionary> _data = new Dictionary>(); + public SeedDataBuilder Apply(T data) where T : class + { + if (_data.TryGetValue(typeof(T), out var ds) == false) + _data.Add(typeof(T), ds = new List()); + ds.Add(data); + return this; + } + public SeedDataBuilder Apply(T[] data) where T : class + { + return this.Apply(data as IEnumerable); + } + public SeedDataBuilder Apply(IEnumerable data) where T : class + { + foreach (var d in data) this.Apply(d); + return this; + } + } + SeedDataBuilder _seedData; + + /// + /// CodeFirst 初始化种子数据 + /// 表数据为空时,创建设定的种子数据 + /// + /// + /// + public FreeSqlBuilder UseSeedData(Action sd) + { + _seedData = new SeedDataBuilder(); + sd?.Invoke(_seedData); + return this; + } } } diff --git a/FreeSql/FreeSqlBuilder_Obsolete.cs b/FreeSql/FreeSqlBuilder_Obsolete.cs new file mode 100644 index 00000000..41563807 --- /dev/null +++ b/FreeSql/FreeSqlBuilder_Obsolete.cs @@ -0,0 +1,80 @@ +using System; +using System.Data.Common; +using System.Linq; +using System.Reflection; +using FreeSql.DataAnnotations; +using FreeSql.Internal; + +namespace FreeSql +{ + partial class FreeSqlBuilder + { + + /// + /// 转小写同步结构 + /// + /// true:转小写, false:不转 + /// + [Obsolete("请使用 UseNameConvert(NameConvertType.ToLower),或者 fsql.CodeFirst.IsSyncStructureToLower = value")] + public FreeSqlBuilder UseSyncStructureToLower(bool value) + { + _isSyncStructureToLower = value; + return this; + } + /// + /// 转大写同步结构 + /// + /// true:转大写, false:不转 + /// + [Obsolete("请使用 UseNameConvert(NameConvertType.ToUpper),或者 fsql.CodeFirst.IsSyncStructureToUpper = value")] + public FreeSqlBuilder UseSyncStructureToUpper(bool value) + { + _isSyncStructureToUpper = value; + return this; + } + + /// + /// 自动转换实体属性名称 Entity Property -> Db Filed + /// + /// *不会覆盖 [Column] 特性设置的Name + /// + /// + /// + [Obsolete("请使用 UseNameConvert 功能")] + public FreeSqlBuilder UseEntityPropertyNameConvert(StringConvertType convertType) + { + _entityPropertyConvertType = convertType; + return this; + } + + void EntityPropertyNameConvert(IFreeSql fsql) + { + //添加实体属性名全局AOP转换处理 + if (_entityPropertyConvertType != StringConvertType.None) + { + string PascalCaseToUnderScore(string str) => string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); + + switch (_entityPropertyConvertType) + { + case StringConvertType.Lower: + fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToLower(); + break; + case StringConvertType.Upper: + fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = e.Property.Name.ToUpper(); + break; + case StringConvertType.PascalCaseToUnderscore: + fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name); + break; + case StringConvertType.PascalCaseToUnderscoreWithLower: + fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToLower(); + break; + case StringConvertType.PascalCaseToUnderscoreWithUpper: + fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = PascalCaseToUnderScore(e.Property.Name).ToUpper(); + break; + default: + break; + } + } + } + } +} From 03fe0921ee1f6f574e9015c47caae34dceaba6cb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 3 Apr 2020 08:55:56 +0800 Subject: [PATCH 0537/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20EfCoreFluent?= =?UTF-8?q?Api=20HasData=20=E8=AE=BE=E5=AE=9A=20CodeFirst=20=E7=A7=8D?= =?UTF-8?q?=E5=AD=90=E6=95=B0=E6=8D=AE=EF=BC=9B=20-=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=20EfCoreFluentApi=20=E5=8A=9F=E8=83=BD=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20DbContextOptions.NoneParam?= =?UTF-8?q?eter=20=E8=AE=BE=E7=BD=AE=E6=98=AF=E5=90=A6=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=8C=96=E6=89=A7=E8=A1=8C=20Insert/Update?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/efcore_to_freesql/Startup.cs | 11 +- .../efcore_to_freesql.csproj | 2 + .../EfCoreTableFluent.cs | 127 +++++++++++----- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 8 +- .../FreeSql.Extensions.EfCoreFluentApi.xml | 7 + .../ICodeFirstExtensions.cs | 37 ++++- .../DbContext/DbContextOptions.cs | 5 + FreeSql.DbContext/DbSet/DbSet.cs | 18 ++- FreeSql.DbContext/FreeSql.DbContext.xml | 5 + .../ContextSet/RepositoryDbContext.cs | 9 +- FreeSql/DataAnnotations/TableFluent.cs | 22 +-- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 1 + FreeSql/FreeSql.xml | 143 ++++++++++++++++++ FreeSql/FreeSqlBuilder.cs | 8 +- .../CommonProvider/CodeFirstProvider.cs | 6 +- .../Internal/CommonProvider/InsertProvider.cs | 2 + .../Internal/CommonProvider/UpdateProvider.cs | 2 + FreeSql/Internal/CommonUtils.cs | 4 +- 18 files changed, 339 insertions(+), 78 deletions(-) diff --git a/Examples/efcore_to_freesql/Startup.cs b/Examples/efcore_to_freesql/Startup.cs index 0fabf866..6d98c5e5 100644 --- a/Examples/efcore_to_freesql/Startup.cs +++ b/Examples/efcore_to_freesql/Startup.cs @@ -27,6 +27,8 @@ namespace efcore_to_freesql .UseAutoSyncStructure(true) .Build(); + FreeSql.Extensions.EfCoreFluentApi.ICodeFirstExtensions.Test(Fsql); + DBContexts.BaseDBContext.Fsql = Fsql; var sql11 = Fsql.Select().ToSql(); @@ -64,13 +66,20 @@ namespace efcore_to_freesql public void ConfigureServices(IServiceCollection services) { + services.AddControllersWithViews(); services.AddSingleton(Fsql); services.AddMvc(); } public void Configure(IApplicationBuilder app) { - app.UseDeveloperExceptionPage(); + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Console.OutputEncoding = Encoding.GetEncoding("GB2312"); + Console.InputEncoding = Encoding.GetEncoding("GB2312"); + + app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); + app.UseDeveloperExceptionPage(); + app.UseRouting(); app.UseEndpoints(a => a.MapControllers()); } } diff --git a/Examples/efcore_to_freesql/efcore_to_freesql.csproj b/Examples/efcore_to_freesql/efcore_to_freesql.csproj index 3769825e..3624b40c 100644 --- a/Examples/efcore_to_freesql/efcore_to_freesql.csproj +++ b/Examples/efcore_to_freesql/efcore_to_freesql.csproj @@ -10,7 +10,9 @@ + + diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs index b9ab2cb2..db7dd65f 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using FreeSql.DataAnnotations; @@ -7,9 +8,11 @@ namespace FreeSql.Extensions.EfCoreFluentApi { public class EfCoreTableFluent { + IFreeSql _fsql; TableFluent _tf; - internal EfCoreTableFluent(TableFluent tf) + internal EfCoreTableFluent(IFreeSql fsql, TableFluent tf) { + _fsql = fsql; _tf = tf; } @@ -33,8 +36,10 @@ namespace FreeSql.Extensions.EfCoreFluentApi #region HasKey public EfCoreTableFluent HasKey(Expression> key) { - if (key?.Body == null) return this; - var exp = key.Body; + var exp = key?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 key 不能为 null"); + switch (exp.NodeType) { case ExpressionType.MemberAccess: @@ -52,8 +57,9 @@ namespace FreeSql.Extensions.EfCoreFluentApi #region HasIndex public HasIndexFluent HasIndex(Expression> index) { - if (index?.Body == null) throw new ArgumentException("参数错误 index 不能为 null"); - var exp = index.Body; + var exp = index?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 index 不能为 null"); var indexName = $"idx_{Guid.NewGuid().ToString("N").Substring(0, 8)}"; var columns = new List(); @@ -102,8 +108,9 @@ namespace FreeSql.Extensions.EfCoreFluentApi #region HasOne public HasOneFluent HasOne(Expression> one) { - if (one?.Body == null) throw new ArgumentException("参数错误 one 不能为 null"); - var exp = one.Body; + var exp = one?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); var oneProperty = ""; switch (exp.NodeType) @@ -113,10 +120,11 @@ namespace FreeSql.Extensions.EfCoreFluentApi break; } if (string.IsNullOrEmpty(oneProperty)) throw new ArgumentException("参数错误 one"); - return new HasOneFluent(_tf, oneProperty); + return new HasOneFluent(_fsql, _tf, oneProperty); } public class HasOneFluent { + IFreeSql _fsql; TableFluent _tf; string _selfProperty; string _selfBind; @@ -124,15 +132,17 @@ namespace FreeSql.Extensions.EfCoreFluentApi string _withOneProperty; string _withOneBind; - internal HasOneFluent(TableFluent modelBuilder, string oneProperty) + internal HasOneFluent(IFreeSql fsql, TableFluent modelBuilder, string oneProperty) { + _fsql = fsql; _tf = modelBuilder; _selfProperty = oneProperty; } public HasOneFluent WithMany(Expression> many) { - if (many?.Body == null) throw new ArgumentException("参数错误 many 不能为 null"); - var exp = many.Body; + var exp = many?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); switch (exp.NodeType) { @@ -142,13 +152,14 @@ namespace FreeSql.Extensions.EfCoreFluentApi } if (string.IsNullOrEmpty(_withManyProperty)) throw new ArgumentException("参数错误 many"); if (string.IsNullOrEmpty(_selfBind) == false) - _tf.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); return this; } public HasOneFluent WithOne(Expression> one, Expression> foreignKey) { - if (one?.Body == null) throw new ArgumentException("参数错误 one 不能为 null"); - var exp = one.Body; + var exp = one?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); switch (exp.NodeType) { @@ -158,8 +169,9 @@ namespace FreeSql.Extensions.EfCoreFluentApi } if (string.IsNullOrEmpty(_withOneProperty)) throw new ArgumentException("参数错误 one"); - if (foreignKey?.Body == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); - exp = foreignKey.Body; + exp = foreignKey?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); switch (exp.NodeType) { @@ -176,13 +188,14 @@ namespace FreeSql.Extensions.EfCoreFluentApi } if (string.IsNullOrEmpty(_withOneBind)) throw new ArgumentException("参数错误 foreignKey"); if (string.IsNullOrEmpty(_selfBind) == false) - _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); return this; } public HasOneFluent HasForeignKey(Expression> foreignKey) { - if (foreignKey?.Body == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); - var exp = foreignKey.Body; + var exp = foreignKey?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); switch (exp.NodeType) { @@ -200,9 +213,9 @@ namespace FreeSql.Extensions.EfCoreFluentApi if (string.IsNullOrEmpty(_selfBind)) throw new ArgumentException("参数错误 foreignKey"); _tf.Navigate(_selfProperty, _selfBind); if (string.IsNullOrEmpty(_withManyProperty) == false) - _tf.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); if (string.IsNullOrEmpty(_withOneProperty) == false && string.IsNullOrEmpty(_withOneBind) == false) - _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); return this; } } @@ -211,8 +224,9 @@ namespace FreeSql.Extensions.EfCoreFluentApi #region HasMany public HasManyFluent HasMany(Expression>> many) { - if (many?.Body == null) throw new ArgumentException("参数错误 many 不能为 null"); - var exp = many.Body; + var exp = many?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); var manyProperty = ""; switch (exp.NodeType) @@ -222,26 +236,29 @@ namespace FreeSql.Extensions.EfCoreFluentApi break; } if (string.IsNullOrEmpty(manyProperty)) throw new ArgumentException("参数错误 many"); - return new HasManyFluent(_tf, manyProperty); + return new HasManyFluent(_fsql, _tf, manyProperty); } public class HasManyFluent { + IFreeSql _fsql; TableFluent _tf; string _selfProperty; string _selfBind; string _withOneProperty; string _withManyProperty; - internal HasManyFluent(TableFluent modelBuilder, string manyProperty) + internal HasManyFluent(IFreeSql fsql, TableFluent modelBuilder, string manyProperty) { + _fsql = fsql; _tf = modelBuilder; _selfProperty = manyProperty; } public void WithMany(Expression>> many, Type middleType) { - if (many?.Body == null) throw new ArgumentException("参数错误 many 不能为 null"); - var exp = many.Body; + var exp = many?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); switch (exp.NodeType) { @@ -252,12 +269,13 @@ namespace FreeSql.Extensions.EfCoreFluentApi if (string.IsNullOrEmpty(_withManyProperty)) throw new ArgumentException("参数错误 many"); _tf.Navigate(_selfProperty, null, middleType); - _tf.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, null, middleType)); + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, null, middleType)); } public HasManyFluent WithOne(Expression> one) { - if (one?.Body == null) throw new ArgumentException("参数错误 one 不能为 null"); - var exp = one.Body; + var exp = one?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); switch (exp.NodeType) { @@ -268,13 +286,14 @@ namespace FreeSql.Extensions.EfCoreFluentApi if (string.IsNullOrEmpty(_withOneProperty)) throw new ArgumentException("参数错误 one"); if (string.IsNullOrEmpty(_selfBind) == false) - _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); return this; } public HasManyFluent HasForeignKey(Expression> foreignKey) { - if (foreignKey?.Body == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); - var exp = foreignKey.Body; + var exp = foreignKey?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); switch (exp.NodeType) { @@ -292,7 +311,7 @@ namespace FreeSql.Extensions.EfCoreFluentApi if (string.IsNullOrEmpty(_selfBind)) throw new ArgumentException("参数错误 foreignKey"); _tf.Navigate(_selfProperty, _selfBind); if (string.IsNullOrEmpty(_withOneProperty) == false) - _tf.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); return this; } } @@ -303,10 +322,40 @@ namespace FreeSql.Extensions.EfCoreFluentApi _tf.Property(property).IsIgnore(true); return this; } - //public EfCoreTableFluent HasData(T data) => HasData(new[] { data }); - //public EfCoreTableFluent HasData(IEnumerable data) - //{ - // return this; - //} + public EfCoreTableFluent HasData(T data) => HasData(new[] { data }); + + /// + /// 使用 Repository + EnableAddOrUpdateNavigateList + NoneParameter 方式插入种子数据 + /// + /// + /// + public EfCoreTableFluent HasData(IEnumerable data) + { + if (data.Any() == false) return this; + var sdCopy = data.Select(a => (object)a).ToList(); + var sdCopyLock = new object(); + _fsql.Aop.SyncStructureAfter += new EventHandler((s, e) => + { + object[] sd = null; + lock (sdCopyLock) + sd = sdCopy?.ToArray(); + if (sd == null || sd.Any() == false) return; + foreach (var et in e.EntityTypes) + { + if (et != typeof(T)) continue; + if (_fsql.Select().AsType(et).Any()) continue; + + var repo = _fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.AsType(et); + repo.Insert(sd); + + lock (sdCopyLock) + sdCopy = null; + } + }); + return this; + } } } diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index b8b85b3a..53b785ab 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -25,13 +25,13 @@ + + + + FreeSql.Extensions.EfCoreFluentApi.xml 3 - - - - diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml index 35afb8c0..55be793f 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml @@ -4,5 +4,12 @@ FreeSql.Extensions.EfCoreFluentApi + + + 使用 Repository + EnableAddOrUpdateNavigateList + NoneParameter 方式插入种子数据 + + + + diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs index 198f6a3c..542af7c2 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq.Expressions; using FreeSql.DataAnnotations; +using FreeSql.Internal.CommonProvider; namespace FreeSql.Extensions.EfCoreFluentApi { @@ -10,13 +11,14 @@ namespace FreeSql.Extensions.EfCoreFluentApi public static ICodeFirst Entity(this ICodeFirst codeFirst, Action> modelBuilder) { - codeFirst.ConfigEntity(tf => modelBuilder(new EfCoreTableFluent(tf))); + var cf = codeFirst as CodeFirstProvider; + codeFirst.ConfigEntity(tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf))); return codeFirst; } - static void Test() + public static void Test(IFreeSql fsql) { - ICodeFirst cf = null; + var cf = fsql.CodeFirst; cf.Entity(eb => { eb.ToTable("tb_song"); @@ -25,7 +27,7 @@ namespace FreeSql.Extensions.EfCoreFluentApi eb.Property(a => a.Url).HasMaxLength(100); eb.Property(a => a.RowVersion).IsRowVersion(); - eb.Property(a => a.CreateTime).HasDefaultValueSql("getdate()"); + eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp"); eb.HasKey(a => a.Id); eb.HasIndex(a => a.Title).IsUnique().HasName("idx_xxx11"); @@ -39,7 +41,33 @@ namespace FreeSql.Extensions.EfCoreFluentApi cf.Entity(eb => { eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); + + eb.HasData(new[] + { + new SongType + { + Id = 1, + Name = "流行", + Songs = new List(new[] + { + new Song{ Title = "真的爱你" }, + new Song{ Title = "爱你一万年" }, + }) + }, + new SongType + { + Id = 2, + Name = "乡村", + Songs = new List(new[] + { + new Song{ Title = "乡里乡亲" }, + }) + }, + }); }); + + cf.SyncStructure(); + cf.SyncStructure(); } public class SongType @@ -52,6 +80,7 @@ namespace FreeSql.Extensions.EfCoreFluentApi public class Song { + [Column(IsIdentity = true)] public int Id { get; set; } public string Title { get; set; } public string Url { get; set; } diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index 8264011a..deb9490e 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -22,6 +22,11 @@ namespace FreeSql /// public bool EnableAddOrUpdateNavigateList { get; set; } = false; + /// + /// 使用无参数化设置(对应 IInsert/IUpdate) + /// + public bool? NoneParameter { get; set; } + /// /// 实体变化事件 /// diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 4dbe2715..9dfe6aa2 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -52,11 +52,21 @@ namespace FreeSql } } - protected virtual IInsert OrmInsert() => _db.Orm.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); - protected virtual IInsert OrmInsert(TEntity data) => _db.Orm.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); - protected virtual IInsert OrmInsert(IEnumerable data) => _db.Orm.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).AppendData(data); + protected virtual IInsert OrmInsert() + { + var insert = _db.Orm.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); + if (_db.Options.NoneParameter != null) insert.NoneParameter(_db.Options.NoneParameter.Value); + return insert; + } + protected virtual IInsert OrmInsert(TEntity data) => OrmInsert().AppendData(data); + protected virtual IInsert OrmInsert(IEnumerable data) => OrmInsert().AppendData(data); - protected virtual IUpdate OrmUpdate(IEnumerable entitys) => _db.Orm.Update().AsType(_entityType).SetSource(entitys).WithTransaction(_uow?.GetOrBeginTransaction()); + protected virtual IUpdate OrmUpdate(IEnumerable entitys) + { + var update = _db.Orm.Update().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); + if (_db.Options.NoneParameter != null) update.NoneParameter(_db.Options.NoneParameter.Value); + return update.SetSource(entitys); + } protected virtual IDelete OrmDelete(object dywhere) => _db.Orm.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); internal void EnqueueToDbContext(DbContext.EntityChangeType changeType, EntityState state) => diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index bd335d0e..3cbd07b4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -87,6 +87,11 @@ - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录 + + + 使用无参数化设置(对应 IInsert/IUpdate) + + 实体变化事件 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 98abccd2..8945b6fa 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -33,8 +33,9 @@ namespace FreeSql (repo as IBaseRepository).UnitOfWork = _repo.UnitOfWork; GetRepositoryDbField(entityType).SetValue(repo, this); - typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repo.EntityType) - .Invoke(null, new object[] { repo, _repo }); + if (typeof(IBaseRepository<>).MakeGenericType(_repo.EntityType).IsAssignableFrom(_repo.GetType())) + typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repo.EntityType) + .Invoke(null, new object[] { repo, _repo }); } var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repo) as IDbSet; @@ -43,10 +44,10 @@ namespace FreeSql return sd; } - public static void SetRepositoryDataFilter(object repos, BaseRepository baseRepo) where TEntity : class + public static void SetRepositoryDataFilter(object repo, IBaseRepository baseRepo) where TEntity : class { var filter = baseRepo.DataFilter as DataFilter; - DataFilterUtil.SetRepositoryDataFilter(repos, fl => + DataFilterUtil.SetRepositoryDataFilter(repo, fl => { foreach (var f in filter._filters) fl.Apply(f.Key, f.Value.Expression); diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 7c8b66c9..f1e93d42 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -8,22 +8,17 @@ namespace FreeSql.DataAnnotations { public class TableFluent { - - public TableFluent(ICodeFirst codeFirst, Type entityType, TableAttribute table) + public TableFluent(Type entityType, TableAttribute table) { - _codeFirst = codeFirst; _entityType = entityType; _properties = _entityType.GetPropertiesDictIgnoreCase(); _table = table; } - ICodeFirst _codeFirst; Type _entityType; Dictionary _properties; TableAttribute _table; - public void ConfigEntity(Action> fluent2) => _codeFirst.ConfigEntity(fluent2); - /// /// 数据库表名 /// @@ -89,20 +84,15 @@ namespace FreeSql.DataAnnotations public class TableFluent { - - public TableFluent(ICodeFirst codeFirst, TableAttribute table) + public TableFluent(TableAttribute table) { - _codeFirst = codeFirst; _properties = typeof(T).GetPropertiesDictIgnoreCase(); _table = table; } - ICodeFirst _codeFirst; Dictionary _properties; TableAttribute _table; - public void ConfigEntity(Action> fluent2) => _codeFirst.ConfigEntity(fluent2); - /// /// 数据库表名 /// @@ -131,7 +121,9 @@ namespace FreeSql.DataAnnotations public ColumnFluent Property(Expression> column) { - var proto = (column.Body as MemberExpression)?.Member; + var exp = column?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + var proto = (exp as MemberExpression)?.Member; if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); return Property(proto.Name); } @@ -152,7 +144,9 @@ namespace FreeSql.DataAnnotations /// public TableFluent Navigate(Expression> proto, string bind, Type manyToMany = null) { - var member = (proto.Body as MemberExpression)?.Member; + var exp = proto?.Body; + if (exp.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + var member = (exp as MemberExpression)?.Member; if (member == null) throw new FormatException($"错误的表达式格式 {proto}"); return Navigate(member.Name, bind, manyToMany); } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 546f8c22..45ce906d 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -58,6 +58,7 @@ public static partial class FreeSqlGlobalExtensions if (type == null) return null; if (type == typeof(void)) return "void"; if (type.IsGenericParameter) return type.Name; + if (type.IsArray) return $"{DisplayCsharp(type.GetElementType())}[]"; var sb = new StringBuilder(); var nestedType = type; while (nestedType.IsNested) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e9379bd3..94b4980f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2317,6 +2317,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 }) + + + + + + 可自定义解析表达式 @@ -2840,6 +2971,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2910,6 +3047,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 11e881a7..319bed75 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Data.Common; using System.Linq; using System.Reflection; @@ -308,7 +309,7 @@ namespace FreeSql { ret.Aop.SyncStructureAfter += new EventHandler((s, e) => { - if (string.IsNullOrEmpty(e.Sql)) return; + if (_seedData._data.Any() == false) return; foreach (var et in e.EntityTypes) { if (_seedData._data.TryGetValue(et, out var sd) == false) continue; @@ -320,6 +321,7 @@ namespace FreeSql .InsertIdentity() .AppendData(sd.ToArray()) .ExecuteAffrows(); + _seedData._data.TryRemove(et, out var old); } }); @@ -335,11 +337,11 @@ namespace FreeSql public class SeedDataBuilder { - internal Dictionary> _data = new Dictionary>(); + internal ConcurrentDictionary> _data = new ConcurrentDictionary>(); public SeedDataBuilder Apply(T data) where T : class { if (_data.TryGetValue(typeof(T), out var ds) == false) - _data.Add(typeof(T), ds = new List()); + _data.TryAdd(typeof(T), ds = new List()); ds.Add(data); return this; } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 2e414072..02c38cff 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -17,9 +17,9 @@ namespace FreeSql.Internal.CommonProvider public abstract partial class CodeFirstProvider : ICodeFirst { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; + public IFreeSql _orm; + public CommonUtils _commonUtils; + public CommonExpression _commonExpression; public CodeFirstProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { _orm = orm; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 161a630b..313434de 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -134,6 +134,8 @@ namespace FreeSql.Internal.CommonProvider public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data == null) return; + if (typeof(T1) == typeof(object) && data.GetType() != table.Type) + throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); foreach (var col in table.Columns.Values) { object val = col.GetMapValue(data); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 6f04aafd..a1a94a38 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -351,6 +351,8 @@ namespace FreeSql.Internal.CommonProvider { if (orm.Aop.AuditValueHandler == null) return; if (data == null) return; + if (typeof(T1) == typeof(object) && data.GetType() != table.Type) + throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); foreach (var col in table.Columns.Values) { object val = col.GetMapValue(data); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 8a59fe20..9ffab8cb 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -79,7 +79,7 @@ namespace FreeSql.Internal if (entity == null) return _orm.CodeFirst; var type = typeof(T); var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); - var fluent = new TableFluent(CodeFirst, table); + var fluent = new TableFluent(table); entity.Invoke(fluent); Utils.RemoveTableByEntity(type, this); //remove cache return _orm.CodeFirst; @@ -88,7 +88,7 @@ namespace FreeSql.Internal { if (entity == null) return _orm.CodeFirst; var table = dicConfigEntity.GetOrAdd(type, new TableAttribute()); - var fluent = new TableFluent(CodeFirst, type, table); + var fluent = new TableFluent(type, table); entity.Invoke(fluent); Utils.RemoveTableByEntity(type, this); //remove cache return _orm.CodeFirst; From 6434be87271b0b6728b509efdd48359385d57bbe Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 3 Apr 2020 09:03:00 +0800 Subject: [PATCH 0538/1029] update EFCoreFluentApi readme --- .../readme.md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md index 5074724e..64b6da62 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md @@ -29,6 +29,34 @@ static void Test() //多对多 eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); }); + + cf.Entity(eb => + { + eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); + + eb.HasData(new[] + { + new SongType + { + Id = 1, + Name = "流行", + Songs = new List(new[] + { + new Song{ Title = "真的爱你" }, + new Song{ Title = "爱你一万年" }, + }) + }, + new SongType + { + Id = 2, + Name = "乡村", + Songs = new List(new[] + { + new Song{ Title = "乡里乡亲" }, + }) + }, + }); + }); } public class SongType @@ -41,6 +69,7 @@ public class SongType public class Song { + [Column(IsIdentity = true)] public int Id { get; set; } public string Title { get; set; } public string Url { get; set; } From 153c7915c3c1583ac2ff5f5c50342126ecbd54bb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 3 Apr 2020 09:17:40 +0800 Subject: [PATCH 0539/1029] =?UTF-8?q?-=20=E7=A7=BB=E9=99=A4=20=E6=9C=AA?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E7=9A=84=E5=8A=9F=E8=83=BD=20FreeSqlBuilder.?= =?UTF-8?q?UseSeedData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 16 ------- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++++ FreeSql/FreeSql.xml | 8 ---- FreeSql/FreeSqlBuilder.cs | 62 ------------------------- 4 files changed, 9 insertions(+), 86 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 9d762f82..0db13185 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -68,22 +68,6 @@ namespace base_entity //.UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") .UseMonitorCommand(cmd => Console.Write(cmd.CommandText)) - .UseSeedData(sd => sd - .Apply(new[] - { - new Products { Id = 1, title = "product-1" }, - new Products { Id = 2, title = "product-2" }, - new Products { Id = 3, title = "product-3" }, - new Products { Id = 4, title = "product-4" } - }) - .Apply(new[] - { - new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" } }, - new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" } }, - new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" } } - }) - ) - .UseLazyLoading(true) .Build(); BaseEntity.Initialization(fsql); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3cbd07b4..eacd506b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -222,6 +222,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 94b4980f..13c418f1 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -740,14 +740,6 @@ - - - CodeFirst 初始化种子数据 - 表数据为空时,创建设定的种子数据 - - - - 转小写同步结构 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 319bed75..b72283eb 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -303,71 +303,9 @@ namespace FreeSql } } }); - - //SeedData - if (_seedData != null && _seedData._data.Any()) - { - ret.Aop.SyncStructureAfter += new EventHandler((s, e) => - { - if (_seedData._data.Any() == false) return; - foreach (var et in e.EntityTypes) - { - if (_seedData._data.TryGetValue(et, out var sd) == false) continue; - if (sd.Any() == false) continue; - if (ret.Select().AsType(et).Any()) continue; - ret.Insert() - .AsType(et) - .NoneParameter() - .InsertIdentity() - .AppendData(sd.ToArray()) - .ExecuteAffrows(); - _seedData._data.TryRemove(et, out var old); - } - }); - - foreach (var sd in _seedData._data) - { - ret.CodeFirst.SyncStructure(sd.Key); - } - } } return ret; } - - public class SeedDataBuilder - { - internal ConcurrentDictionary> _data = new ConcurrentDictionary>(); - public SeedDataBuilder Apply(T data) where T : class - { - if (_data.TryGetValue(typeof(T), out var ds) == false) - _data.TryAdd(typeof(T), ds = new List()); - ds.Add(data); - return this; - } - public SeedDataBuilder Apply(T[] data) where T : class - { - return this.Apply(data as IEnumerable); - } - public SeedDataBuilder Apply(IEnumerable data) where T : class - { - foreach (var d in data) this.Apply(d); - return this; - } - } - SeedDataBuilder _seedData; - - /// - /// CodeFirst 初始化种子数据 - /// 表数据为空时,创建设定的种子数据 - /// - /// - /// - public FreeSqlBuilder UseSeedData(Action sd) - { - _seedData = new SeedDataBuilder(); - sd?.Invoke(_seedData); - return this; - } } } From 19ab4da369bcca67e43f5b3f631dc647f0dfc12c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 4 Apr 2020 05:52:31 +0800 Subject: [PATCH 0540/1029] 1.4.0-preview20200404 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 17 insertions(+), 33 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b5ddd118..dee553eb 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 53b785ab..cb59edf5 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 608ef363..63fe1bfc 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5d71e275..72a2ea72 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index b50e77b5..c6292671 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.4 + 1.4.0-preview20200404 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index f6ddd006..26cbb023 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d1a7ec0e..6e671a87 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index eacd506b..63db6c75 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -121,13 +121,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -222,15 +215,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0b904133..676f3302 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.4 + 1.4.0-preview20200404 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f865e002..0d7cebe4 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index f7dcddd4..f25ae633 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 64aed809..1046dc87 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 66079e73..a20e4d1f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 47a35ca2..c3ec56dd 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 41ce63a7..b6a8cbfa 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7977a5e8..c12f792e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 26c0f841..cf6bfdac 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 911611e2..9676796b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.4 + 1.4.0-preview20200404 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 74f8700c218c39fae99a08d54d55c009ba006bbe Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 7 Apr 2020 11:25:13 +0800 Subject: [PATCH 0541/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20SyncStructur?= =?UTF-8?q?e=20=E8=BF=94=E5=9B=9E=E5=80=BC=E4=B8=BA=20void?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql/FreeSql.xml | 3 --- FreeSql/Interface/ICodeFirst.cs | 9 +++------ .../CommonProvider/CodeFirstProvider.cs | 18 +++++++++--------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 63db6c75..eacd506b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -121,6 +121,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -215,6 +222,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 13c418f1..83ccee42 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2763,14 +2763,12 @@ 同步实体类型到数据库 - 同步实体类型集合到数据库 - @@ -2778,7 +2776,6 @@ 实体类型 指定表名对比 - diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index e242a390..c5cd16e6 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -66,21 +66,18 @@ namespace FreeSql /// 同步实体类型到数据库 /// /// - /// - bool SyncStructure(); + void SyncStructure(); /// /// 同步实体类型集合到数据库 /// /// - /// - bool SyncStructure(params Type[] entityTypes); + void SyncStructure(params Type[] entityTypes); /// /// 同步实体类型到数据库(指定表名) /// /// 实体类型 /// 指定表名对比 - /// - bool SyncStructure(Type entityType, string tableName); + void SyncStructure(Type entityType, string tableName); /// /// 根据 System.Type 获取数据库信息 diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 02c38cff..bd348901 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -81,18 +81,18 @@ namespace FreeSql.Internal.CommonProvider internal void _dicSycedTryAdd(Type entityType, string tableName = null) => _dicSycedGetOrAdd(entityType).TryAdd(GetTableNameLowerOrUpper(tableName), true); - public bool SyncStructure() => + public void SyncStructure() => this.SyncStructure(new TypeAndName(typeof(TEntity), "")); - public bool SyncStructure(params Type[] entityTypes) => entityTypes == null ? false : - this.SyncStructure(entityTypes.Distinct().Select(a => new TypeAndName(a, "")).ToArray()); - public bool SyncStructure(Type entityType, string tableName) => + public void SyncStructure(params Type[] entityTypes) => + this.SyncStructure(entityTypes?.Distinct().Select(a => new TypeAndName(a, "")).ToArray()); + public void SyncStructure(Type entityType, string tableName) => this.SyncStructure(new TypeAndName(entityType, GetTableNameLowerOrUpper(tableName))); - protected bool SyncStructure(params TypeAndName[] objects) + protected void SyncStructure(params TypeAndName[] objects) { - if (objects == null) return false; + if (objects == null) return; var syncObjects = objects.Where(a => _dicSycedGetOrAdd(a.entityType).ContainsKey(GetTableNameLowerOrUpper(a.tableName)) == false && GetTableByEntity(a.entityType)?.DisableSyncStructure == false) .Select(a => new TypeAndName(a.entityType, GetTableNameLowerOrUpper(a.tableName))).ToArray(); - if (syncObjects.Any() == false) return false; + if (syncObjects.Any() == false) return; var before = new Aop.SyncStructureBeforeEventArgs(syncObjects.Select(a => a.entityType).ToArray()); _orm.Aop.SyncStructureBeforeHandler?.Invoke(this, before); Exception exception = null; @@ -105,11 +105,11 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(ddl)) { foreach (var syncObject in syncObjects) _dicSycedTryAdd(syncObject.entityType, syncObject.tableName); - return true; + return; } var affrows = ExecuteDDLStatements(ddl); foreach (var syncObject in syncObjects) _dicSycedTryAdd(syncObject.entityType, syncObject.tableName); - return true; + return; } } catch (Exception ex) From c1882cd7682c88128316610a185197a5d0ec1468 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 7 Apr 2020 16:42:46 +0800 Subject: [PATCH 0542/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IncludeMany?= =?UTF-8?q?=20=E7=AC=AC3=E5=B1=82=E6=97=A0=E6=B3=95=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8CIncludeMany(a=20=3D>=20a.Pa?= =?UTF-8?q?rent.Parent.Childs)=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommonProvider/SelectProvider/Select1Provider.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index ef0dcfeb..f47cf885 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -372,7 +372,7 @@ namespace FreeSql.Internal.CommonProvider { Expression tmpExp = exp; ParameterExpression param = null; - var members = new List(); + var members = new Stack(); var isbreak = false; while (isbreak == false) { @@ -381,7 +381,7 @@ namespace FreeSql.Internal.CommonProvider case ExpressionType.MemberAccess: var memExp = tmpExp as MemberExpression; tmpExp = memExp.Expression; - members.Add(memExp); + members.Push(memExp); continue; case ExpressionType.Parameter: param = tmpExp as ParameterExpression; @@ -392,7 +392,7 @@ namespace FreeSql.Internal.CommonProvider } } if (param == null) throw new Exception($"表达式错误,它的顶级对象不是 ParameterExpression:{exp}"); - return NaviteTuple.Create(param, members); + return NaviteTuple.Create(param, members.ToList()); } static MethodInfo GetEntityValueWithPropertyNameMethod = typeof(EntityUtilExtensions).GetMethod("GetEntityValueWithPropertyName"); static ConcurrentDictionary> _dicTypeMethod = new ConcurrentDictionary>(); From 0f3bad338f3b2200424f1e19cdcccd45dcb2318d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 7 Apr 2020 18:09:29 +0800 Subject: [PATCH 0543/1029] v1.3.5 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../MySqlConnectorExpression/OtherTest.cs | 4 +- .../MySql/MySqlAdo/MySqlAdoTest.cs | 2 +- .../MySql/MySqlExpression/OtherTest.cs | 4 +- .../DataAnnotations/MySqlFluentTest.cs | 2 +- .../DataAnnotations/SqlServerFluentTest.cs | 2 +- .../MySql/MySqlExpression/OtherTest.cs | 4 +- .../Oracle/Curd/OracleSelectTest.cs | 4 +- .../Oracle/OracleCodeFirstTest.cs | 8 ++-- FreeSql/FreeSql.csproj | 2 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 2 +- FreeSql/Internal/UtilsExpressionTree.cs | 38 +++++++++---------- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 27 files changed, 52 insertions(+), 52 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index dee553eb..5432319f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index cb59edf5..12b23cd9 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 63fe1bfc..e311e25d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 72a2ea72..43df994a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index c6292671..261c082a 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview20200404 + 1.3.5 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 26cbb023..008108f5 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6e671a87..13b8725a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 676f3302..6b2fb6bd 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200404 + 1.3.5 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs index f882ed1a..cc32f9b0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs @@ -78,8 +78,8 @@ namespace FreeSql.Tests.MySqlConnectorExpression public void Array() { int[] nullarr = null; - Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); - Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs index c22ff2f9..e38cd06b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs @@ -53,7 +53,7 @@ namespace FreeSql.Tests.Odbc.MySql [Fact] public void QueryMultipline() { - Assert.Throws(() => g.mysql.Ado.Query("select * from song; select * from song; select * from song")); + Assert.Throws(() => g.mysql.Ado.Query("select * from song; select * from song; select * from song")); } class xxx diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs index c3c442d1..e69345f8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/OtherTest.cs @@ -78,8 +78,8 @@ namespace FreeSql.Tests.Odbc.MySqlExpression public void Array() { int[] nullarr = null; - Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); - Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index 5046db22..06fb7aec 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -16,7 +16,7 @@ namespace FreeSql.Tests.DataAnnotations [Fact] public void DisableSyncStructure() { - Assert.Throws(() => g.mysql.Select().ToList()); + Assert.Throws(() => g.mysql.Select().ToList()); g.mysql.Select().ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs index e3eaf1f7..ce6bda66 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs @@ -20,7 +20,7 @@ namespace FreeSql.Tests.DataAnnotations [Fact] public void DisableSyncStructure() { - Assert.Throws(() => g.sqlserver.Select().ToList()); + Assert.Throws(() => g.sqlserver.Select().ToList()); g.sqlserver.Select().ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs index 2ab152e1..997c0718 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs @@ -78,8 +78,8 @@ namespace FreeSql.Tests.MySqlExpression public void Array() { int[] nullarr = null; - Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); - Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 88cab797..455f4b66 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -793,7 +793,7 @@ namespace FreeSql.Tests.Oracle [Fact] public void ToAggregate() { - var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); } [Fact] public void OrderBy() @@ -997,7 +997,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); - select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + //select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); var sqlsss = select .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index baf47d01..196c0707 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -24,7 +24,7 @@ namespace FreeSql.Tests.Oracle //NoneParameter item1 = new TS_NCLB02 { Data = str1 }; - Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ } class TS_NCLB02 @@ -47,7 +47,7 @@ namespace FreeSql.Tests.Oracle //NoneParameter item1 = new TS_NCLB01 { Data = str1 }; - Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ } class TS_NCLB01 @@ -69,7 +69,7 @@ namespace FreeSql.Tests.Oracle //NoneParameter item1 = new TS_CLB01 { Data = str1 }; - Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ } class TS_CLB01 @@ -95,7 +95,7 @@ namespace FreeSql.Tests.Oracle //NoneParameter item1 = new TS_BLB01 { Data = data1 }; - Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ } class TS_BLB01 diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0d7cebe4..9ceabd66 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index a5ebb8db..c9c1c962 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -82,7 +82,7 @@ namespace FreeSql.Internal.CommonProvider if (isThrowException) { if (DataType == DataType.Sqlite) cmd.Dispose(); - throw ex; + throw new Exception(ex.Message, ex); } } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 1d0676ae..17e30fdd 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1651,16 +1651,16 @@ namespace FreeSql.Internal static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) }); static MethodInfo MethodTimeSpanFromSeconds = typeof(TimeSpan).GetMethod("FromSeconds"); static MethodInfo MethodSByteTryParse = typeof(sbyte).GetMethod("TryParse", new[] { typeof(string), typeof(sbyte).MakeByRefType() }); - static MethodInfo MethodShortTryParse = typeof(short).GetMethod("TryParse", new[] { typeof(string), typeof(short).MakeByRefType() }); - static MethodInfo MethodIntTryParse = typeof(int).GetMethod("TryParse", new[] { typeof(string), typeof(int).MakeByRefType() }); - static MethodInfo MethodLongTryParse = typeof(long).GetMethod("TryParse", new[] { typeof(string), typeof(long).MakeByRefType() }); + static MethodInfo MethodShortTryParse = typeof(short).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(short).MakeByRefType() }); + static MethodInfo MethodIntTryParse = typeof(int).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(int).MakeByRefType() }); + static MethodInfo MethodLongTryParse = typeof(long).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(long).MakeByRefType() }); static MethodInfo MethodByteTryParse = typeof(byte).GetMethod("TryParse", new[] { typeof(string), typeof(byte).MakeByRefType() }); - static MethodInfo MethodUShortTryParse = typeof(ushort).GetMethod("TryParse", new[] { typeof(string), typeof(ushort).MakeByRefType() }); - static MethodInfo MethodUIntTryParse = typeof(uint).GetMethod("TryParse", new[] { typeof(string), typeof(uint).MakeByRefType() }); - static MethodInfo MethodULongTryParse = typeof(ulong).GetMethod("TryParse", new[] { typeof(string), typeof(ulong).MakeByRefType() }); - static MethodInfo MethodDoubleTryParse = typeof(double).GetMethod("TryParse", new[] { typeof(string), typeof(double).MakeByRefType() }); - static MethodInfo MethodFloatTryParse = typeof(float).GetMethod("TryParse", new[] { typeof(string), typeof(float).MakeByRefType() }); - static MethodInfo MethodDecimalTryParse = typeof(decimal).GetMethod("TryParse", new[] { typeof(string), typeof(decimal).MakeByRefType() }); + static MethodInfo MethodUShortTryParse = typeof(ushort).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(ushort).MakeByRefType() }); + static MethodInfo MethodUIntTryParse = typeof(uint).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(uint).MakeByRefType() }); + static MethodInfo MethodULongTryParse = typeof(ulong).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(ulong).MakeByRefType() }); + static MethodInfo MethodDoubleTryParse = typeof(double).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(double).MakeByRefType() }); + static MethodInfo MethodFloatTryParse = typeof(float).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(float).MakeByRefType() }); + static MethodInfo MethodDecimalTryParse = typeof(decimal).GetMethod("TryParse", new[] { typeof(string), typeof(System.Globalization.NumberStyles), typeof(IFormatProvider), typeof(decimal).MakeByRefType() }); static MethodInfo MethodTimeSpanTryParse = typeof(TimeSpan).GetMethod("TryParse", new[] { typeof(string), typeof(TimeSpan).MakeByRefType() }); static MethodInfo MethodDateTimeTryParse = typeof(DateTime).GetMethod("TryParse", new[] { typeof(string), typeof(DateTime).MakeByRefType() }); static MethodInfo MethodDateTimeOffsetTryParse = typeof(DateTimeOffset).GetMethod("TryParse", new[] { typeof(string), typeof(DateTimeOffset).MakeByRefType() }); @@ -1773,7 +1773,7 @@ namespace FreeSql.Internal new Expression[] { Expression.Assign(valueStrExp, Expression.Call(MethodToString, valueExp)), Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodDoubleTryParse, valueStrExp, tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodDoubleTryParse, valueStrExp, Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodTimeSpanFromSeconds, tryparseVarExp), typeof(object))), Expression.IfThenElse( Expression.IsTrue(Expression.Call(MethodTimeSpanTryParse, valueStrExp, tryparseVarTsExp)), @@ -1800,7 +1800,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(short)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodShortTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodShortTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) @@ -1812,7 +1812,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(int)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodIntTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodIntTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) @@ -1824,7 +1824,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(long)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodLongTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodLongTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) @@ -1848,7 +1848,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(ushort)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodUShortTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodUShortTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) @@ -1860,7 +1860,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(uint)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodUIntTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodUIntTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) @@ -1872,7 +1872,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(ulong)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodULongTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodULongTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) @@ -1884,7 +1884,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(float)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodFloatTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodFloatTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) @@ -1896,7 +1896,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(double)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodDoubleTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodDoubleTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) @@ -1908,7 +1908,7 @@ namespace FreeSql.Internal new[] { tryparseVarExp = Expression.Variable(typeof(decimal)) }, new Expression[] { Expression.IfThenElse( - Expression.IsTrue(Expression.Call(MethodDecimalTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.IsTrue(Expression.Call(MethodDecimalTryParse, Expression.Convert(valueExp, typeof(string)), Expression.Constant(System.Globalization.NumberStyles.Any), Expression.Constant(null, typeof(IFormatProvider)), tryparseVarExp)), Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) ) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index f25ae633..6252c860 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 1046dc87..916e832c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a20e4d1f..56914255 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c3ec56dd..baa2a76c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b6a8cbfa..717b19f3 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index c12f792e..ed2242c7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cf6bfdac..11110f37 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9676796b..7dd4165e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200404 + 1.3.5 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 27d6c46758761bbbdb39bb6665f34367c6615ed8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 8 Apr 2020 13:31:40 +0800 Subject: [PATCH 0544/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Oracle/Damen?= =?UTF-8?q?g=20=E7=99=BB=E9=99=86=E5=90=8D=E4=B8=BA=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E6=97=B6=E5=80=99=E7=9A=84=20pk=20=E5=91=BD=E5=90=8D=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---- .../Dameng/DamengCodeFirstTest.cs | 79 ++++++++++++++++--- .../FreeSql.Tests.Provider.Odbc/g.cs | 8 +- FreeSql.Tests/FreeSql.Tests/g.cs | 4 +- .../Dameng/OdbcDamengCodeFirst.cs | 20 ++--- .../Oracle/OdbcOracleCodeFirst.cs | 20 ++--- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 6 +- .../OracleCodeFirst.cs | 20 ++--- .../PostgreSQLCodeFirst.cs | 6 +- 9 files changed, 110 insertions(+), 69 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index eacd506b..63db6c75 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -121,13 +121,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -222,15 +215,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index 98e1eeea..015df564 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -27,55 +27,108 @@ namespace FreeSql.Tests.Odbc.Dameng } [Fact] - public void ı_ֶ() + public void ֱ_ֶ() { - var sql = g.dameng.CodeFirst.GetComparisonDDLStatements<ı>(); - g.dameng.CodeFirst.SyncStructure<ı>(); + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements<ֱ>(); + g.dameng.CodeFirst.SyncStructure<ֱ>(); - var item = new ı + var item = new ֱ { = "Ա", ʱ = DateTime.Now }; - Assert.Equal(1, g.dameng.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.Equal(1, g.dameng.Insert<ֱ>().AppendData(item).ExecuteAffrows()); Assert.NotEqual(Guid.Empty, item.); - var item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + var item2 = g.dameng.Select<ֱ>().Where(a => a. == item.).First(); Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); item. = "Ա"; - Assert.Equal(1, g.dameng.Update<ı>().SetSource(item).ExecuteAffrows()); - item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.Equal(1, g.dameng.Update<ֱ>().SetSource(item).ExecuteAffrows()); + item2 = g.dameng.Select<ֱ>().Where(a => a. == item.).First(); Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); item. = "Ա_repo"; - var repo = g.dameng.GetRepository<ı>(); + var repo = g.dameng.GetRepository<ֱ>(); Assert.Equal(1, repo.Update(item)); - item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + item2 = g.dameng.Select<ֱ>().Where(a => a. == item.).First(); Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); item. = "Ա_repo22"; Assert.Equal(1, repo.Update(item)); - item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + item2 = g.dameng.Select<ֱ>().Where(a => a. == item.).First(); Assert.NotNull(item2); Assert.Equal(item., item2.); Assert.Equal(item., item2.); } - class ı + [Table(Name = "123ֱ")] + class ֱ { - [Column(IsPrimary = true)] + [Column(IsPrimary = true, Name = "123")] public Guid { get; set; } + [Column(Name = "123")] public string { get; set; } + [Column(Name = "123ʱ")] public DateTime ʱ { get; set; } } + //[Fact] + //public void ı_ֶ() + //{ + // var sql = g.dameng.CodeFirst.GetComparisonDDLStatements<ı>(); + // g.dameng.CodeFirst.SyncStructure<ı>(); + + // var item = new ı + // { + // = "Ա", + // ʱ = DateTime.Now + // }; + // Assert.Equal(1, g.dameng.Insert<ı>().AppendData(item).ExecuteAffrows()); + // Assert.NotEqual(Guid.Empty, item.); + // var item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + // Assert.NotNull(item2); + // Assert.Equal(item., item2.); + // Assert.Equal(item., item2.); + + // item. = "Ա"; + // Assert.Equal(1, g.dameng.Update<ı>().SetSource(item).ExecuteAffrows()); + // item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + // Assert.NotNull(item2); + // Assert.Equal(item., item2.); + // Assert.Equal(item., item2.); + + // item. = "Ա_repo"; + // var repo = g.dameng.GetRepository<ı>(); + // Assert.Equal(1, repo.Update(item)); + // item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + // Assert.NotNull(item2); + // Assert.Equal(item., item2.); + // Assert.Equal(item., item2.); + + // item. = "Ա_repo22"; + // Assert.Equal(1, repo.Update(item)); + // item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + // Assert.NotNull(item2); + // Assert.Equal(item., item2.); + // Assert.Equal(item., item2.); + //} + //class ı + //{ + // [Column(IsPrimary = true)] + // public Guid { get; set; } + + // public string { get; set; } + + // public DateTime ʱ { get; set; } + //} + [Fact] public void AddUniques() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index e0b589bd..56004005 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -70,8 +70,8 @@ public class g public static IFreeSql odbc => odbcLazy.Value; static Lazy damemgLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") - //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")) + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=123USER1;PWD=123456789") + //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=123USER1;PWD=123456789")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) @@ -85,8 +85,8 @@ public class g //启动南大通用数据库 oninit -vy static Lazy gbaseLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={GBase ODBC DRIVER (64-bit)};Server=192.168.164.10:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") - //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")) + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={GBase ODBC DRIVER (64-bit)};Server=192.168.164.10:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=123USER1;PWD=123456789") + //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=123USER1;PWD=123456789")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 992dfb44..131bb7bd 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -55,8 +55,8 @@ public class g public static IFreeSql sqlserver => sqlserverLazy.Value; static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") - //.UseConnectionFactory(FreeSql.DataType.Oracle, () => new Oracle.ManagedDataAccess.Client.OracleConnection("user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;")) + .UseConnectionString(FreeSql.DataType.Oracle, "user id=123user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") + //.UseConnectionFactory(FreeSql.DataType.Oracle, () => new Oracle.ManagedDataAccess.Client.OracleConnection("user id=123user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index b28aad3f..a2a91981 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -139,7 +139,7 @@ namespace FreeSql.Odbc.Dameng if (tb.Primarys.Any()) { var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; - sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -323,7 +323,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and if (tb.Primarys.Any()) { var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; - sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -384,12 +384,12 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and { if (dicDeclare.ContainsKey(seqname) == false) { - sbDeclare.Append("\r\n").Append(seqname).Append("IS NUMBER; \r\n"); + sbDeclare.Append("\r\nIS").Append(seqname).Append(" NUMBER; \r\n"); dicDeclare.Add(seqname, true); } - sb.Append(seqname).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(seqname).Append(_commonUtils.FormatSql("IS from user_sequences where sequence_name={0}; \r\n", seqname)) - .Append("if ").Append(seqname).Append("IS > 0 then \r\n") + sb.Append("IS").Append(seqname).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(seqname).Append(_commonUtils.FormatSql(" from user_sequences where sequence_name={0}; \r\n", seqname)) + .Append("if IS").Append(seqname).Append(" > 0 then \r\n") .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") .Append("end if; \r\n"); }; @@ -397,12 +397,12 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and { if (dicDeclare.ContainsKey(tiggerName) == false) { - sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); + sbDeclare.Append("\r\nIS").Append(tiggerName).Append(" NUMBER; \r\n"); dicDeclare.Add(tiggerName, true); } - sb.Append(tiggerName).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) - .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") + sb.Append("IS").Append(tiggerName).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(tiggerName).Append(_commonUtils.FormatSql(" from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if IS").Append(tiggerName).Append(" > 0 then \r\n") .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") .Append("end if; \r\n"); }; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index f741ef1b..a898f956 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -139,7 +139,7 @@ namespace FreeSql.Odbc.Oracle if (tb.Primarys.Any()) { var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; - sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -321,7 +321,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam if (tb.Primarys.Any()) { var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; - sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -382,12 +382,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam { if (dicDeclare.ContainsKey(seqname) == false) { - sbDeclare.Append("\r\n").Append(seqname).Append("IS NUMBER; \r\n"); + sbDeclare.Append("\r\nIS").Append(seqname).Append(" NUMBER; \r\n"); dicDeclare.Add(seqname, true); } - sb.Append(seqname).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(seqname).Append(_commonUtils.FormatSql("IS from user_sequences where sequence_name={0}; \r\n", seqname)) - .Append("if ").Append(seqname).Append("IS > 0 then \r\n") + sb.Append("IS").Append(seqname).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(seqname).Append(_commonUtils.FormatSql(" from user_sequences where sequence_name={0}; \r\n", seqname)) + .Append("if IS").Append(seqname).Append(" > 0 then \r\n") .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") .Append("end if; \r\n"); }; @@ -395,12 +395,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam { if (dicDeclare.ContainsKey(tiggerName) == false) { - sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); + sbDeclare.Append("\r\nIS").Append(tiggerName).Append(" NUMBER; \r\n"); dicDeclare.Add(tiggerName, true); } - sb.Append(tiggerName).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) - .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") + sb.Append("IS").Append(tiggerName).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(tiggerName).Append(_commonUtils.FormatSql(" from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if IS").Append(tiggerName).Append(" > 0 then \r\n") .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") .Append("end if; \r\n"); }; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 854ee076..71e3322a 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -132,7 +132,8 @@ namespace FreeSql.Odbc.PostgreSQL } if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -329,7 +330,8 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp } if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index b28bc7a2..132219f0 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -140,7 +140,7 @@ namespace FreeSql.Oracle if (tb.Primarys.Any()) { var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; - sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -322,7 +322,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam if (tb.Primarys.Any()) { var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; - sb.Append(" \r\n CONSTRAINT ").Append(pkname).Append(" PRIMARY KEY ("); + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -383,12 +383,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam { if (dicDeclare.ContainsKey(seqname) == false) { - sbDeclare.Append("\r\n").Append(seqname).Append("IS NUMBER; \r\n"); + sbDeclare.Append("\r\nIS").Append(seqname).Append(" NUMBER; \r\n"); dicDeclare.Add(seqname, true); } - sb.Append(seqname).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(seqname).Append(_commonUtils.FormatSql("IS from user_sequences where sequence_name={0}; \r\n", seqname)) - .Append("if ").Append(seqname).Append("IS > 0 then \r\n") + sb.Append("IS").Append(seqname).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(seqname).Append(_commonUtils.FormatSql(" from user_sequences where sequence_name={0}; \r\n", seqname)) + .Append("if IS").Append(seqname).Append(" > 0 then \r\n") .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") .Append("end if; \r\n"); }; @@ -396,12 +396,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam { if (dicDeclare.ContainsKey(tiggerName) == false) { - sbDeclare.Append("\r\n").Append(tiggerName).Append("IS NUMBER; \r\n"); + sbDeclare.Append("\r\nIS").Append(tiggerName).Append(" NUMBER; \r\n"); dicDeclare.Add(tiggerName, true); } - sb.Append(tiggerName).Append("IS := 0; \r\n") - .Append(" select count(1) into ").Append(tiggerName).Append(_commonUtils.FormatSql("IS from user_triggers where trigger_name={0}; \r\n", tiggerName)) - .Append("if ").Append(tiggerName).Append("IS > 0 then \r\n") + sb.Append("IS").Append(tiggerName).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(tiggerName).Append(_commonUtils.FormatSql(" from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if IS").Append(tiggerName).Append(" > 0 then \r\n") .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") .Append("end if; \r\n"); }; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 392f55bf..7e714a49 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -167,7 +167,8 @@ namespace FreeSql.PostgreSQL } if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } @@ -364,7 +365,8 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp } if (tb.Primarys.Any()) { - sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } From 7c55f09d47f5cd74f9f05cd980df8adc39a0d50f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 8 Apr 2020 14:19:00 +0800 Subject: [PATCH 0545/1029] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20Unit=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++ .../Dameng/DamengCodeFirstTest.cs | 86 +++++++++---------- .../Oracle/OracleCodeFirstTest.cs | 53 ++++++++++++ .../FreeSql.Tests.Provider.Odbc/g.cs | 12 +-- .../Oracle/OracleCodeFirstTest.cs | 54 ++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 2 +- FreeSql.Tests/FreeSql.Tests/g.cs | 4 +- .../Special/OraclePrimaryKeyNameAttribute.cs | 1 + 8 files changed, 176 insertions(+), 52 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 63db6c75..eacd506b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -121,6 +121,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -215,6 +222,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index 015df564..c5120439 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -79,55 +79,55 @@ namespace FreeSql.Tests.Odbc.Dameng public DateTime ʱ { get; set; } } - //[Fact] - //public void ı_ֶ() - //{ - // var sql = g.dameng.CodeFirst.GetComparisonDDLStatements<ı>(); - // g.dameng.CodeFirst.SyncStructure<ı>(); + [Fact] + public void ı_ֶ() + { + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements<ı>(); + g.dameng.CodeFirst.SyncStructure<ı>(); - // var item = new ı - // { - // = "Ա", - // ʱ = DateTime.Now - // }; - // Assert.Equal(1, g.dameng.Insert<ı>().AppendData(item).ExecuteAffrows()); - // Assert.NotEqual(Guid.Empty, item.); - // var item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); - // Assert.NotNull(item2); - // Assert.Equal(item., item2.); - // Assert.Equal(item., item2.); + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.dameng.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); - // item. = "Ա"; - // Assert.Equal(1, g.dameng.Update<ı>().SetSource(item).ExecuteAffrows()); - // item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); - // Assert.NotNull(item2); - // Assert.Equal(item., item2.); - // Assert.Equal(item., item2.); + item. = "Ա"; + Assert.Equal(1, g.dameng.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); - // item. = "Ա_repo"; - // var repo = g.dameng.GetRepository<ı>(); - // Assert.Equal(1, repo.Update(item)); - // item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); - // Assert.NotNull(item2); - // Assert.Equal(item., item2.); - // Assert.Equal(item., item2.); + item. = "Ա_repo"; + var repo = g.dameng.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); - // item. = "Ա_repo22"; - // Assert.Equal(1, repo.Update(item)); - // item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); - // Assert.NotNull(item2); - // Assert.Equal(item., item2.); - // Assert.Equal(item., item2.); - //} - //class ı - //{ - // [Column(IsPrimary = true)] - // public Guid { get; set; } + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } - // public string { get; set; } + public string { get; set; } - // public DateTime ʱ { get; set; } - //} + public DateTime ʱ { get; set; } + } [Fact] public void AddUniques() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs index ef9c6147..7eccb3bb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -26,6 +26,59 @@ namespace FreeSql.Tests.Odbc.Oracle public string TitleSub { get; set; } } + [Fact] + public void ֱ_ֶ() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<ֱ>(); + g.oracle.CodeFirst.SyncStructure<ֱ>(); + + var item = new ֱ + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.oracle.Insert<ֱ>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.oracle.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.oracle.Update<ֱ>().SetSource(item).ExecuteAffrows()); + item2 = g.oracle.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.oracle.GetRepository<ֱ>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + [Table(Name = "123tb")] + class ֱ + { + [Column(IsPrimary = true, Name = "123id")] + public Guid { get; set; } + + [Column(Name = "123title")] + public string { get; set; } + + [Column(Name = "123time")] + public DateTime ʱ { get; set; } + } + [Fact] public void ı_ֶ() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index 56004005..bf0aa5e8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -31,8 +31,8 @@ public class g public static IFreeSql sqlserver => sqlserverLazy.Value; static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.OdbcOracle, "Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456") - //.UseConnectionFactory(FreeSql.DataType.OdbcOracle, () => new System.Data.Odbc.OdbcConnection("Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456")) + .UseConnectionString(FreeSql.DataType.OdbcOracle, "Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=1odbc;PWD=123456") + //.UseConnectionFactory(FreeSql.DataType.OdbcOracle, () => new System.Data.Odbc.OdbcConnection("Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=1odbc;PWD=123456")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) @@ -70,8 +70,8 @@ public class g public static IFreeSql odbc => odbcLazy.Value; static Lazy damemgLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=123USER1;PWD=123456789") - //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=123USER1;PWD=123456789")) + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=1user;PWD=123456789") + //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=1user;PWD=123456789")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) @@ -85,8 +85,8 @@ public class g //启动南大通用数据库 oninit -vy static Lazy gbaseLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={GBase ODBC DRIVER (64-bit)};Server=192.168.164.10:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=123USER1;PWD=123456789") - //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=123USER1;PWD=123456789")) + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={GBase ODBC DRIVER (64-bit)};Server=192.168.164.10:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=1user;PWD=123456789") + //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=1user;PWD=123456789")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 196c0707..57da44cf 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -119,6 +119,60 @@ namespace FreeSql.Tests.Oracle public string TitleSub { get; set; } } + [Fact] + public void ֱ_ֶ() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<ֱ>(); + g.oracle.CodeFirst.SyncStructure<ֱ>(); + + var item = new ֱ + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.oracle.Insert<ֱ>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.oracle.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.oracle.Update<ֱ>().SetSource(item).ExecuteAffrows()); + item2 = g.oracle.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.oracle.GetRepository<ֱ>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + [Table(Name = "123tb")] + [OraclePrimaryKeyName("pk1_123tb")] + class ֱ + { + [Column(IsPrimary = true, Name = "123id")] + public Guid { get; set; } + + [Column(Name = "123title")] + public string { get; set; } + + [Column(Name = "123time")] + public DateTime ʱ { get; set; } + } + [Fact] public void ı_ֶ() { diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index cbdb223b..646f1bc6 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -328,7 +328,7 @@ namespace FreeSql.Tests class TestORC12 { - [Column(IsIdentity = true, InsertValueSql = "\"CLASS1_seq_ID\".nextval")] + [Column(IsIdentity = true, InsertValueSql = "\"TAG_SEQ_ID\".nextval")] public int Id { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 131bb7bd..e64f0553 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -55,8 +55,8 @@ public class g public static IFreeSql sqlserver => sqlserverLazy.Value; static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Oracle, "user id=123user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") - //.UseConnectionFactory(FreeSql.DataType.Oracle, () => new Oracle.ManagedDataAccess.Client.OracleConnection("user id=123user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;")) + .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") + //.UseConnectionFactory(FreeSql.DataType.Oracle, () => new Oracle.ManagedDataAccess.Client.OracleConnection("user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;")) .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseLazyLoading(true) diff --git a/FreeSql/DataAnnotations/Special/OraclePrimaryKeyNameAttribute.cs b/FreeSql/DataAnnotations/Special/OraclePrimaryKeyNameAttribute.cs index fd2aa735..d3666738 100644 --- a/FreeSql/DataAnnotations/Special/OraclePrimaryKeyNameAttribute.cs +++ b/FreeSql/DataAnnotations/Special/OraclePrimaryKeyNameAttribute.cs @@ -2,6 +2,7 @@ namespace FreeSql.DataAnnotations { + [AttributeUsage(AttributeTargets.Class)] public class OraclePrimaryKeyNameAttribute : Attribute { public OraclePrimaryKeyNameAttribute(string name) From fa59a6e3e823da32852c2794b3954957f01a19ae Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 8 Apr 2020 16:19:14 +0800 Subject: [PATCH 0546/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20GroupBy=20co?= =?UTF-8?q?unt(b.id)=20=E6=8C=87=E5=AE=9A=E5=AD=97=E6=AE=B5=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 1 + .../Dameng/Curd/DamengSelectTest.cs | 1 + .../Default/Curd/OdbcSelectTest.cs | 1 + .../MySql/Curd/MySqlSelectTest.cs | 1 + .../Oracle/Curd/OracleSelectTest.cs | 1 + .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 1 + .../SqlServer/Curd/SqlServerSelectTest.cs | 1 + .../MsAccess/Curd/MsAccessSelectTest.cs | 1 + .../MySql/Curd/MySqlSelectTest.cs | 1 + .../Oracle/Curd/OracleSelectTest.cs | 1 + .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 1 + .../SqlServer/Curd/SqlServerSelectTest.cs | 1 + .../Sqlite/Curd/SqliteSelectTest.cs | 1 + FreeSql/FreeSql.xml | 306 ++++++++++-------- .../Interface/Curd/ISelect/ISelectGrouping.cs | 1 + FreeSql/Internal/CommonExpression.cs | 2 +- 16 files changed, 178 insertions(+), 144 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 77ba34f0..6a768543 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -803,6 +803,7 @@ namespace FreeSql.Tests.MySqlConnector { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 34f665fc..2a444d8e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -730,6 +730,7 @@ namespace FreeSql.Tests.Odbc.Dameng { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index bf9b4bdc..bd446fcf 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -720,6 +720,7 @@ namespace FreeSql.Tests.Odbc.Default { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 39785795..67225bac 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -813,6 +813,7 @@ namespace FreeSql.Tests.Odbc.MySql { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 22d51222..86e20010 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -730,6 +730,7 @@ namespace FreeSql.Tests.Odbc.Oracle { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index b7b9b513..99be779b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -790,6 +790,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index e636c42b..f1ebb323 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -685,6 +685,7 @@ namespace FreeSql.Tests.Odbc.SqlServer { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index d4191350..69a32587 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -721,6 +721,7 @@ namespace FreeSql.Tests.MsAccess { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 223ce220..054e726c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -844,6 +844,7 @@ namespace FreeSql.Tests.MySql { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 455f4b66..b15f3539 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -730,6 +730,7 @@ namespace FreeSql.Tests.Oracle { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 1cfd5d9f..28f04780 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -807,6 +807,7 @@ namespace FreeSql.Tests.PostgreSQL { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index c739c6a6..d8d36c82 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -734,6 +734,7 @@ namespace FreeSql.Tests.SqlServer { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 86f622e9..667f7596 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -682,6 +682,7 @@ namespace FreeSql.Tests.Sqlite { a.Key.tt2, cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 83ccee42..e808373b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2309,137 +2309,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2960,12 +2829,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3036,12 +2899,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3674,4 +3531,167 @@ + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index bcd93fe9..9a8cf6fc 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -121,6 +121,7 @@ namespace FreeSql /// /// int Count(); + int Count(T3 column); /// /// 求和 /// diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 07dfb1d4..8df262b1 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -702,7 +702,7 @@ namespace FreeSql.Internal //} switch (exp3.Method.Name) { - case "Count": return "count(1)"; + case "Count": return exp3.Arguments.Count == 0 ? "count(1)" : $"count({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; case "Sum": return $"sum({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; case "Avg": return $"avg({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; case "Max": return $"max({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; From ee1e292165f28140d47d826b45eb30d9a03f41c3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 8 Apr 2020 19:10:04 +0800 Subject: [PATCH 0547/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20GroupBy=20To?= =?UTF-8?q?Dictionary=20=E8=BF=94=E5=9B=9E=E5=AD=97=E6=AE=B5=E7=9A=84?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=96=B9=E6=B3=95=EF=BC=8CTKey=20=E4=B8=BA?= =?UTF-8?q?=20GroupBy=20=E9=80=89=E6=8B=A9=E7=9A=84=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=EF=BC=9B=20-=20=E6=95=B4=E7=90=86=20GroupBy=20=E6=89=80?= =?UTF-8?q?=E6=9C=89=E6=96=B9=E6=B3=95=E4=B8=8D=E4=BD=BF=E7=94=A8=20DTO=20?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E8=A7=84=E5=88=99=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 23 +- .../Dameng/Curd/DamengSelectTest.cs | 19 +- .../Default/Curd/OdbcSelectTest.cs | 18 ++ .../MySql/Curd/MySqlSelectTest.cs | 23 +- .../Oracle/Curd/OracleSelectTest.cs | 18 ++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 18 ++ .../SqlServer/Curd/SqlServerSelectTest.cs | 18 ++ .../MsAccess/Curd/MsAccessSelectTest.cs | 18 ++ .../MySql/Curd/MySqlSelectTest.cs | 23 +- .../Oracle/Curd/OracleSelectTest.cs | 18 ++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 18 ++ .../SqlServer/Curd/SqlServerSelectTest.cs | 18 ++ .../Sqlite/Curd/SqliteSelectTest.cs | 23 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 23 ++ FreeSql/FreeSql.xml | 306 ++++++++---------- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 4 +- .../Interface/Curd/ISelect/ISelectGrouping.cs | 2 + .../SelectProvider/Select0Provider.cs | 31 +- .../SelectProvider/SelectGroupingProvider.cs | 41 ++- 19 files changed, 455 insertions(+), 207 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 6a768543..5b67eff0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -821,7 +821,6 @@ namespace FreeSql.Tests.MySqlConnector { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist1 = select @@ -830,7 +829,14 @@ namespace FreeSql.Tests.MySqlConnector { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -842,7 +848,6 @@ namespace FreeSql.Tests.MySqlConnector b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist2 = select @@ -853,7 +858,16 @@ namespace FreeSql.Tests.MySqlConnector b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -863,7 +877,6 @@ namespace FreeSql.Tests.MySqlConnector { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid), sum3 = b.Sum(b.Value.Type.Parent.Id) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 2a444d8e..ea7b538e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -749,7 +749,6 @@ namespace FreeSql.Tests.Odbc.Dameng { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist1 = select @@ -760,6 +759,14 @@ namespace FreeSql.Tests.Odbc.Dameng cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -780,6 +787,16 @@ namespace FreeSql.Tests.Odbc.Dameng cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql3 = select .GroupBy(a => a.Title) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index bd446fcf..c0a0a23e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -749,6 +749,14 @@ namespace FreeSql.Tests.Odbc.Default cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -767,6 +775,16 @@ namespace FreeSql.Tests.Odbc.Default b.Key.Title, b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 67225bac..d72847b8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -832,7 +832,6 @@ namespace FreeSql.Tests.Odbc.MySql { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist1 = select @@ -841,7 +840,14 @@ namespace FreeSql.Tests.Odbc.MySql { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -853,7 +859,6 @@ namespace FreeSql.Tests.Odbc.MySql b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist2 = select @@ -864,7 +869,16 @@ namespace FreeSql.Tests.Odbc.MySql b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -874,7 +888,6 @@ namespace FreeSql.Tests.Odbc.MySql { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid), sum3 = b.Sum(b.Value.Type.Parent.Id) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 86e20010..e97f991c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -759,6 +759,14 @@ namespace FreeSql.Tests.Odbc.Oracle cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -777,6 +785,16 @@ namespace FreeSql.Tests.Odbc.Oracle b.Key.Title, b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 99be779b..3f9b79cf 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -819,6 +819,14 @@ namespace FreeSql.Tests.Odbc.PostgreSQL cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -837,6 +845,16 @@ namespace FreeSql.Tests.Odbc.PostgreSQL b.Key.Title, b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index f1ebb323..701c91a7 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -714,6 +714,14 @@ namespace FreeSql.Tests.Odbc.SqlServer cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -732,6 +740,16 @@ namespace FreeSql.Tests.Odbc.SqlServer b.Key.Title, b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index 69a32587..7bb03da1 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -750,6 +750,14 @@ namespace FreeSql.Tests.MsAccess cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -768,6 +776,16 @@ namespace FreeSql.Tests.MsAccess b.Key.Title, b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 054e726c..60f05168 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -863,7 +863,6 @@ namespace FreeSql.Tests.MySql { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist1 = select @@ -872,7 +871,14 @@ namespace FreeSql.Tests.MySql { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -884,7 +890,6 @@ namespace FreeSql.Tests.MySql b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist2 = select @@ -895,7 +900,16 @@ namespace FreeSql.Tests.MySql b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -905,7 +919,6 @@ namespace FreeSql.Tests.MySql { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid), sum3 = b.Sum(b.Value.Type.Parent.Id) }); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index b15f3539..26aacc73 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -759,6 +759,14 @@ namespace FreeSql.Tests.Oracle cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -777,6 +785,16 @@ namespace FreeSql.Tests.Oracle b.Key.Title, b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 28f04780..878c0150 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -836,6 +836,14 @@ namespace FreeSql.Tests.PostgreSQL cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -854,6 +862,16 @@ namespace FreeSql.Tests.PostgreSQL b.Key.Title, b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index d8d36c82..6625e85a 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -763,6 +763,14 @@ namespace FreeSql.Tests.SqlServer cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); var aggsql2 = select .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) @@ -781,6 +789,16 @@ namespace FreeSql.Tests.SqlServer b.Key.Title, b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 667f7596..49f7cdb9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -701,7 +701,6 @@ namespace FreeSql.Tests.Sqlite { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist1 = select @@ -710,7 +709,14 @@ namespace FreeSql.Tests.Sqlite { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -722,7 +728,6 @@ namespace FreeSql.Tests.Sqlite b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) }); var aggtolist2 = select @@ -733,7 +738,16 @@ namespace FreeSql.Tests.Sqlite b.Key.yyyy, cou = b.Count(), - sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); @@ -743,7 +757,6 @@ namespace FreeSql.Tests.Sqlite { b.Key, cou = b.Count(), - sum = b.Sum(b.Key), sum2 = b.Sum(b.Value.TypeGuid), sum3 = b.Sum(b.Value.Type.Parent.Id) }); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index ddd934e8..d300dc9c 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -962,6 +962,29 @@ namespace FreeSql.Tests sum2 = b.Sum(b.Value.TypeGuid) }); + var aggtolist21 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionaryAsync(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }).Result; + var aggsql3 = select .GroupBy(a => a.Title) .ToSql(b => new diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e808373b..83ccee42 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2309,6 +2309,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 }) + + + + + + 可自定义解析表达式 @@ -2829,6 +2960,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2899,6 +3036,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3531,167 +3674,4 @@ - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 80a3ca55..ca52d7c2 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -15,7 +15,7 @@ namespace FreeSql #else Task ToDataTableAsync(string field = null); Task> ToDictionaryAsync(Func keySelector); - Task> ToDictionaryAsync(Func keySelector, Func valueSelector); + Task> ToDictionaryAsync(Func keySelector, Func elementSelector); Task> ToListAsync(bool includeNestedMembers = false); Task> ToListAsync(string field); @@ -60,7 +60,7 @@ namespace FreeSql /// /// Dictionary ToDictionary(Func keySelector); - Dictionary ToDictionary(Func keySelector, Func valueSelector); + Dictionary ToDictionary(Func keySelector, Func elementSelector); /// /// 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 /// 注意: diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 9a8cf6fc..7e73a743 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -13,6 +13,7 @@ namespace FreeSql #else Task CountAsync(); Task> ToListAsync(Expression, TReturn>> select); + Task> ToDictionaryAsync(Expression, TElement>> elementSelector); #endif /// @@ -43,6 +44,7 @@ namespace FreeSql /// 选择列 /// List ToList(Expression, TReturn>> select); + Dictionary ToDictionary(Expression, TElement>> elementSelector); /// /// 【linq to sql】专用方法,不建议直接使用 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 5f3a6a88..950b1383 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -480,23 +480,23 @@ namespace FreeSql.Internal.CommonProvider } #endregion public Dictionary ToDictionary(Func keySelector) => ToDictionary(keySelector, a => a); - public Dictionary ToDictionary(Func keySelector, Func valueSelector) + public Dictionary ToDictionary(Func keySelector, Func elementSelector) { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); - if (valueSelector == null) throw new ArgumentNullException(nameof(valueSelector)); + if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); var af = this.GetAllFieldExpressionTreeLevel2(); var sql = this.ToSql(af.Field); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new Dictionary(); + var ret = new Dictionary(); Exception exception = null; try { _orm.Ado.ExecuteReader(_connection, _transaction, dr => { var item = af.Read(_orm, dr); - ret.Add(keySelector(item), valueSelector(item)); + ret.Add(keySelector(item), elementSelector(item)); }, CommandType.Text, sql, dbParms); } catch (Exception ex) @@ -509,7 +509,7 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } - if (typeof(TValue) == typeof(T1)) _trackToList?.Invoke(ret.Values); + if (typeof(TElement) == typeof(T1)) _trackToList?.Invoke(ret.Values); return ret; } public virtual List ToList(bool includeNestedMembers = false) @@ -1088,9 +1088,10 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression, true); - this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null); - return new SelectGroupingProvider(_orm, this, map, _commonExpression, _tables); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression, false); //不走 DTO 映射 + var sql = field.ToString(); + this.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); + return new SelectGroupingProvider(_orm, this, map, sql, _commonExpression, _tables); } protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { @@ -1146,7 +1147,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, true); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射 return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } @@ -1285,23 +1286,23 @@ namespace FreeSql.Internal.CommonProvider } public Task> ToDictionaryAsync(Func keySelector) => ToDictionaryAsync(keySelector, a => a); - async public Task> ToDictionaryAsync(Func keySelector, Func valueSelector) + async public Task> ToDictionaryAsync(Func keySelector, Func elementSelector) { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); - if (valueSelector == null) throw new ArgumentNullException(nameof(valueSelector)); + if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); var af = this.GetAllFieldExpressionTreeLevel2(); var sql = this.ToSql(af.Field); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new Dictionary(); + var ret = new Dictionary(); Exception exception = null; try { await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => { var item = af.Read(_orm, dr); - ret.Add(keySelector(item), valueSelector(item)); + ret.Add(keySelector(item), elementSelector(item)); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } @@ -1315,7 +1316,7 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } - if (typeof(TValue) == typeof(T1)) _trackToList?.Invoke(ret.Values); + if (typeof(TElement) == typeof(T1)) _trackToList?.Invoke(ret.Values); return ret; } public virtual Task> ToListAsync(bool includeNestedMembers = false) @@ -1426,7 +1427,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, true); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射 return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); } #endif diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 46c642d8..8c2474c4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -14,13 +14,15 @@ namespace FreeSql.Internal.CommonProvider internal IFreeSql _orm; internal object _select; internal ReadAnonymousTypeInfo _map; + internal string _field; internal CommonExpression _comonExp; internal List _tables; - public SelectGroupingProvider(IFreeSql orm, object select, ReadAnonymousTypeInfo map, CommonExpression comonExp, List tables) + public SelectGroupingProvider(IFreeSql orm, object select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List tables) { _orm = orm; _select = select; _map = map; + _field = field; _comonExp = comonExp; _tables = tables; } @@ -107,20 +109,33 @@ namespace FreeSql.Internal.CommonProvider return this; } + public List Select(Expression, TReturn>> select) => ToList(select); public List ToList(Expression, TReturn>> select) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; } - - public List Select(Expression, TReturn>> select) => ToList(select); + public Dictionary ToDictionary(Expression, TElement>> elementSelector) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + + _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, getSelectGroupingMapString, null, false); + if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement); + var method = _select.GetType().GetMethod("ToListMapReaderPrivate", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(typeof(TElement)); + var otherAf = new ReadAnonymousTypeOtherInfo(_field, _map, new List()); + var values = method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null), new[] { otherAf } }) as List; + return otherAf.retlist.Select((a, b) => new KeyValuePair((TKey)a, values[b])).ToDictionary(a => a.Key, a => a.Value); + } public string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { @@ -128,7 +143,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; } @@ -181,12 +196,26 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, true); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TReturn)); return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; } + async public Task> ToDictionaryAsync(Expression, TElement>> elementSelector) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + + _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, getSelectGroupingMapString, null, false); + if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement); + var method = _select.GetType().GetMethod("ToListMapReaderPrivateAsync", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(typeof(TElement)); + var otherAf = new ReadAnonymousTypeOtherInfo(_field, _map, new List()); + var values = await (method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null), new[] { otherAf } }) as Task>); + return otherAf.retlist.Select((a, b) => new KeyValuePair((TKey)a, values[b])).ToDictionary(a => a.Key, a => a.Value); + } #endif } } From 1afca09152669ec938fd6f505ec68b3606d14928 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 8 Apr 2020 19:19:15 +0800 Subject: [PATCH 0548/1029] 1.4.0-preview20200408 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 17 insertions(+), 26 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5432319f..aeea9571 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 12b23cd9..52cbd655 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e311e25d..359afd4e 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 43df994a..9084d951 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 261c082a..9efb442f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.5 + 1.4.0-preview20200408 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 008108f5..442bd4ca 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 13b8725a..98525ca0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index eacd506b..3cbd07b4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -222,15 +222,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 6b2fb6bd..7d3fcf24 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.5 + 1.4.0-preview20200408 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9ceabd66..e31422fd 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 6252c860..dafe02f0 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 916e832c..c9f1c5a1 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 56914255..b1a7c64f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index baa2a76c..6d6c9727 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 717b19f3..fb41068b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ed2242c7..b4c8bce4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 11110f37..cfb15958 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7dd4165e..4d1d331f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.5 + 1.4.0-preview20200408 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 0838599b78b025ef1aff7467ad27c273c2a94533 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 9 Apr 2020 12:07:48 +0800 Subject: [PATCH 0549/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20IUpdate.SetD?= =?UTF-8?q?to=20=E4=B9=9F=E6=94=AF=E6=8C=81=20IgnoreClumns=20=E7=9A=84?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql/Internal/CommonProvider/UpdateProvider.cs | 2 ++ 2 files changed, 11 insertions(+) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3cbd07b4..eacd506b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -222,6 +222,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index a1a94a38..15f73452 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -476,6 +476,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var kv in dic) { if (_table.ColumnsByCs.TryGetValue(kv.Key, out var trycol) == false) continue; + if (_ignore.ContainsKey(kv.Key)) continue; SetPriv(trycol, kv.Value); } } @@ -483,6 +484,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var dtoProp in dtoProps) { if (_table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trycol) == false) continue; + if (_ignore.ContainsKey(dtoProp.Name)) continue; SetPriv(trycol, dtoProp.GetValue(dto, null)); } return this; From 50238339fec5c876849871a7bd09be28d6ec3914 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 9 Apr 2020 12:13:45 +0800 Subject: [PATCH 0550/1029] v1.4.0-preview20200409 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 17 insertions(+), 26 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index aeea9571..d1c4f246 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 52cbd655..cf509012 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 359afd4e..a255c8be 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 9084d951..91d07422 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 9efb442f..ed42624d 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview20200408 + 1.4.0-preview20200409 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 442bd4ca..9d38e848 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 98525ca0..a9459c18 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index eacd506b..3cbd07b4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -222,15 +222,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7d3fcf24..c0a8bb66 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e31422fd..b175386f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index dafe02f0..14c618ee 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c9f1c5a1..5b7a37de 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index b1a7c64f..e35ea5d8 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 6d6c9727..448eba31 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fb41068b..68febf09 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b4c8bce4..1e35764e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cfb15958..d849e2fc 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4d1d331f..ff94ed7c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200408 + 1.4.0-preview20200409 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 98fc8baadef6ab4984dde6a43b93380acbff3087 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 9 Apr 2020 16:47:49 +0800 Subject: [PATCH 0551/1029] v1.4.0-preview20200410 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/Queryable/QueryableTest.cs | 71 +++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 5 +- FreeSql/FreeSql.csproj | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 4 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 103 insertions(+), 20 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d1c4f246..d46770b5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index cf509012..c843c61a 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a255c8be..7321d6ec 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 91d07422..bd2dc8a5 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index ed42624d..5effd1f6 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview20200409 + 1.4.0-preview20200410 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 9d38e848..78004db7 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a9459c18..79d8c385 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 3cbd07b4..eacd506b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -222,6 +222,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c0a8bb66..fee9d51a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs b/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs new file mode 100644 index 00000000..8dbedf6d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs @@ -0,0 +1,71 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using System.Data.SqlClient; +using kwlib; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace FreeSql.Tests +{ + public class QueryableTest + { + class qt01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + + [Navigate(nameof(qt01_item.qt01id))] + public List items { get; set; } + } + class qt01_item + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public int qt01id { get; set; } + } + IFreeSql fsql => g.sqlite; + + [Fact] + public void Any() + { + var sd = new[] { + new qt01{ + name = "any01", + items = new List(new []{ + new qt01_item { title = "any01_item01" }, + new qt01_item { title = "any01_item02" } + }) + }, + new qt01{ + name = "any02", + items = new List(new []{ + new qt01_item { title = "any02_item01" }, + new qt01_item { title = "any02_item02" } + }) + } + }; + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(sd); + + Assert.True(fsql.Select().AsQueryable().Any()); + Assert.True(fsql.Select().AsQueryable().Any(a => a.id == sd[0].id)); + Assert.False(fsql.Select().AsQueryable().Any(a => a.id == sd[0].id && sd[0].id == 0)); + } + } + +} diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 646f1bc6..545b25cb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -147,7 +147,10 @@ namespace FreeSql.Tests .First(a => a); //#231 var lksdjkg1 = g.sqlite.Select() - .AsQueryable().Where(a => a.Id > 0).ToList(); + .AsQueryable().Where(a => a.Id > 0).Where(a => a.Id == 1).ToList(); + + var lksdjkg11 = g.sqlite.Select() + .AsQueryable().Where(a => a.Id > 0).Where(a => a.Id == 1).Any(); var lksdjkg2 = g.sqlite.Select() .AsQueryable().Where(a => a.Id > 0).First(); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b175386f..32663832 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 15f73452..f5ad6a9c 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -476,7 +476,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var kv in dic) { if (_table.ColumnsByCs.TryGetValue(kv.Key, out var trycol) == false) continue; - if (_ignore.ContainsKey(kv.Key)) continue; + if (_ignore.ContainsKey(trycol.Attribute.Name)) continue; SetPriv(trycol, kv.Value); } } @@ -484,7 +484,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var dtoProp in dtoProps) { if (_table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trycol) == false) continue; - if (_ignore.ContainsKey(dtoProp.Name)) continue; + if (_ignore.ContainsKey(trycol.Attribute.Name)) continue; SetPriv(trycol, dtoProp.GetValue(dto, null)); } return this; diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 14c618ee..d21c7874 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5b7a37de..6238bd2e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index e35ea5d8..096d7532 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 448eba31..d83dc775 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 68febf09..2373f1fc 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1e35764e..af83d6d4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d849e2fc..aaca5d5b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ff94ed7c..c03fc76d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200409 + 1.4.0-preview20200410 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 5f987496526d178cca89f5a72ff27e8b5cdcc259 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Apr 2020 02:28:33 +0800 Subject: [PATCH 0552/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20ISelect=20li?= =?UTF-8?q?nq=20to=20sql=20=E5=92=8C=20queryable=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E7=A7=BB=E8=87=B3=20FreeSql.Extensions.Linq?= =?UTF-8?q?=EF=BC=9B#260?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.Linq.csproj | 37 +++ .../FreeSql.Extensions.Linq.xml | 41 +++ .../FreeSqlExtensionsLinq.cs | 131 ++++++++ .../QueryableProvider.cs | 279 ++++++++++++++++++ Extensions/FreeSql.Extensions.Linq/key.snk | Bin 0 -> 596 bytes .../Repository/Repository/BaseRepository.cs | 8 +- .../Repository/BaseRepositoryAsync.cs | 8 +- .../FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 11 - .../FreeSql.Tests/FreeSql.Tests.csproj | 1 + .../Queryable/QueryableLinqToSqlTests.cs | 202 +++++++++++++ .../FreeSql.Tests/Queryable/QueryableTest.cs | 122 +++++++- FreeSql.sln | 15 + FreeSql/FreeSql.xml | 33 --- FreeSql/Interface/Curd/ISelect/ILinqToSql.cs | 31 -- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 10 +- FreeSql/Internal/CommonExpression.cs | 43 +-- .../CommonProvider/CodeFirstProvider.cs | 3 +- .../SelectProvider/QueryableProvider.cs | 107 ------- .../SelectProvider/Select0Provider.cs | 113 +++---- .../SelectProvider/Select1Provider.cs | 122 ++------ .../SelectProvider/SelectGroupingProvider.cs | 105 +++---- 21 files changed, 987 insertions(+), 435 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj create mode 100644 Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml create mode 100644 Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs create mode 100644 Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs create mode 100644 Extensions/FreeSql.Extensions.Linq/key.snk create mode 100644 FreeSql.Tests/FreeSql.Tests/Queryable/QueryableLinqToSqlTests.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ILinqToSql.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/QueryableProvider.cs diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj new file mode 100644 index 00000000..202f9ed5 --- /dev/null +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -0,0 +1,37 @@ + + + + netstandard2.0;net45;net40 + 1.4.0-preview20200410 + true + YeXiangQin + FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + true + key.snk + false + + + + + + + + FreeSql.Extensions.Linq.xml + 3 + + + + + + + diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml new file mode 100644 index 00000000..19871dd2 --- /dev/null +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml @@ -0,0 +1,41 @@ + + + + FreeSql.Extensions.Linq + + + + + 将 ISelect<T1> 转换为 IQueryable<T1> + 此方法主要用于扩展,比如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 + 注意:IQueryable 方法污染较为严重,请尽量避免此转换 + + + + + + 【linq to sql】专用扩展方法,不建议直接使用 + + + + + 【linq to sql】专用扩展方法,不建议直接使用 + + + + + 【linq to sql】专用扩展方法,不建议直接使用 + + + + + 【linq to sql】专用扩展方法,不建议直接使用 + + + + + 【linq to sql】专用扩展方法,不建议直接使用 + + + + diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs b/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs new file mode 100644 index 00000000..de256cec --- /dev/null +++ b/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs @@ -0,0 +1,131 @@ +using FreeSql; +using FreeSql.Extensions.Linq; +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +public static class FreeSqlExtensionsLinqSql +{ + + /// + /// 将 ISelect<T1> 转换为 IQueryable<T1> + /// 此方法主要用于扩展,比如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 + /// 注意:IQueryable 方法污染较为严重,请尽量避免此转换 + /// + /// + public static IQueryable AsQueryable(this ISelect that) where T1 : class + { + return new QueryableProvider(that as Select1Provider); + } + + /// + /// 【linq to sql】专用扩展方法,不建议直接使用 + /// + public static ISelect Select(this ISelect that, Expression> select) where T1 : class where TReturn : class + { + var s1p = that as Select1Provider; + if (typeof(TReturn) == typeof(T1)) return that as ISelect; + s1p._tables[0].Parameter = select.Parameters[0]; + s1p._selectExpression = select.Body; + if (s1p._orm.CodeFirst.IsAutoSyncStructure) + (s1p._orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TReturn)); //._dicSyced.TryAdd(typeof(TReturn), true); + var ret = s1p._orm.Select() as Select1Provider; + Select0Provider.CopyData(s1p, ret, null); + return ret; + } + /// + /// 【linq to sql】专用扩展方法,不建议直接使用 + /// + public static ISelect Join(this ISelect that, ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector) where T1 : class where TInner : class where TResult : class + { + var s1p = that as Select1Provider; + InternalJoin2(s1p, outerKeySelector, innerKeySelector, resultSelector); + if (typeof(TResult) == typeof(T1)) return that as ISelect; + s1p._selectExpression = resultSelector.Body; + if (s1p._orm.CodeFirst.IsAutoSyncStructure) + (s1p._orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); + var ret = s1p._orm.Select() as Select1Provider; + Select0Provider.CopyData(s1p, ret, null); + return ret; + } + internal static void InternalJoin2(Select1Provider s1p, LambdaExpression outerKeySelector, LambdaExpression innerKeySelector, LambdaExpression resultSelector) where T1 : class + { + s1p._tables[0].Parameter = resultSelector.Parameters[0]; + s1p._commonExpression.ExpressionLambdaToSql(outerKeySelector, new CommonExpression.ExpTSC { _tables = s1p._tables }); + s1p.InternalJoin(Expression.Lambda(typeof(Func<,,>).MakeGenericType(typeof(T1), innerKeySelector.Parameters[0].Type, typeof(bool)), + Expression.Equal(outerKeySelector.Body, innerKeySelector.Body), + new[] { outerKeySelector.Parameters[0], innerKeySelector.Parameters[0] } + ), SelectTableInfoType.InnerJoin); + } + + /// + /// 【linq to sql】专用扩展方法,不建议直接使用 + /// + public static ISelect GroupJoin(this ISelect that, ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector) where T1 : class where TInner : class where TResult : class + { + var s1p = that as Select1Provider; + InternalJoin2(s1p, outerKeySelector, innerKeySelector, resultSelector); + if (typeof(TResult) == typeof(T1)) return that as ISelect; + s1p._selectExpression = resultSelector.Body; + if (s1p._orm.CodeFirst.IsAutoSyncStructure) + (s1p._orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); + var ret = s1p._orm.Select() as Select1Provider; + Select0Provider.CopyData(s1p, ret, null); + return ret; + } + /// + /// 【linq to sql】专用扩展方法,不建议直接使用 + /// + public static ISelect SelectMany(this ISelect that, Expression>> collectionSelector, Expression> resultSelector) where T1 : class where TCollection : class where TResult : class + { + var s1p = that as Select1Provider; + InternalSelectMany2(s1p, collectionSelector, resultSelector); + if (typeof(TResult) == typeof(T1)) return that as ISelect; + s1p._selectExpression = resultSelector.Body; + if (s1p._orm.CodeFirst.IsAutoSyncStructure) + (s1p._orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); + var ret = s1p._orm.Select() as Select1Provider; + Select0Provider.CopyData(s1p, ret, null); + return ret; + } + internal static void InternalSelectMany2(Select1Provider s1p, LambdaExpression collectionSelector, LambdaExpression resultSelector) where T1 : class + { + SelectTableInfo find = null; + if (collectionSelector.Body.NodeType == ExpressionType.Call) + { + var callExp = collectionSelector.Body as MethodCallExpression; + if (callExp.Method.Name == "DefaultIfEmpty" && callExp.Method.GetGenericArguments().Any()) + { + find = s1p._tables.Where((a, idx) => idx > 0 && a.Type == SelectTableInfoType.InnerJoin && a.Table.Type == callExp.Method.GetGenericArguments()[0]).LastOrDefault(); + if (find != null) + { + if (!string.IsNullOrEmpty(find.On)) find.On = Regex.Replace(find.On, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); + if (!string.IsNullOrEmpty(find.NavigateCondition)) find.NavigateCondition = Regex.Replace(find.NavigateCondition, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); + find.Type = SelectTableInfoType.LeftJoin; + find.Alias = resultSelector.Parameters[1].Name; + find.Parameter = resultSelector.Parameters[1]; + } + } + } + if (find == null) + { + var tb = s1p._commonUtils.GetTableByEntity(resultSelector.Parameters[1].Type); + if (tb == null) throw new Exception($"SelectMany 错误的类型:{resultSelector.Parameters[1].Type.FullName}"); + s1p._tables.Add(new SelectTableInfo { Alias = resultSelector.Parameters[1].Name, AliasInit = resultSelector.Parameters[1].Name, Parameter = resultSelector.Parameters[1], Table = tb, Type = SelectTableInfoType.From }); + } + } + + /// + /// 【linq to sql】专用扩展方法,不建议直接使用 + /// + public static ISelect DefaultIfEmpty(this ISelect that) where T1 : class + { + return that; + } +} diff --git a/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs b/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs new file mode 100644 index 00000000..892e1cf8 --- /dev/null +++ b/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs @@ -0,0 +1,279 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace FreeSql.Extensions.Linq +{ + class QueryableProvider : IQueryable, IOrderedQueryable where TSource : class + { + private Expression _expression; + private IQueryProvider _provider; + private Select1Provider _select; + + public QueryableProvider(Select1Provider select) + { + _select = select; + _expression = Expression.Constant(this); + _provider = new QueryProvider(_select); + } + public QueryableProvider(Expression expression, IQueryProvider provider, Select1Provider select) + { + _select = select; + _expression = expression; + _provider = provider; + } + + public IEnumerator GetEnumerator() + { + var result = _provider.Execute>(_expression); + if (result == null) + yield break; + foreach (var item in result) + { + yield return item; + } + } + IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); + + public Type ElementType => typeof(QueryableProvider); + public Expression Expression => _expression; + public IQueryProvider Provider => _provider; + } + + class QueryProvider : IQueryProvider where TSource : class + { + private Select1Provider _select; + + public QueryProvider(Select1Provider select) + { + _select = select; + } + + public IQueryable CreateQuery(Expression expression) + { + if (typeof(TElement) != typeof(TCurrent)) + return new QueryableProvider(expression, new QueryProvider(_select), _select); + + return new QueryableProvider(expression, this, _select); + } + public IQueryable CreateQuery(Expression expression) => throw new NotImplementedException(); + + public TResult Execute(Expression expression) + { + var stackCallExps = new Stack(); + var callExp = expression as MethodCallExpression; + while(callExp != null) + { + stackCallExps.Push(callExp); + callExp = callExp?.Arguments.FirstOrDefault() as MethodCallExpression; + } + + SelectGroupingProvider groupBy = null; + var isfirst = false; + while (stackCallExps.Any()) + { + callExp = stackCallExps.Pop(); + TResult throwCallExp(string message) => throw new Exception($"FreeSql Queryable 解析出错,执行的方法 {callExp.Method.Name} {message}"); + if (callExp.Method.DeclaringType != typeof(Queryable)) return throwCallExp($"必须属于 System.Linq.Enumerable"); + + TResult tplMaxMinAvgSum(string method) { + if (callExp.Arguments.Count == 2) + { + var avgParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; + return (TResult)Utils.GetDataReaderValue(typeof(TResult), + _select.GetType().GetMethod(method).MakeGenericMethod(avgParam.ReturnType).Invoke(_select, new object[] { avgParam })); + } + return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); + } + TResult tplOrderBy(string method, bool isDescending) + { + if (callExp.Arguments.Count == 2) + { + var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; + _select.OrderByReflection(arg1, isDescending); + return default(TResult); + } + return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); + } + switch (callExp.Method.Name) + { + case "Any": + if (callExp.Arguments.Count == 2) _select.Where((Expression>)(callExp.Arguments[1] as UnaryExpression)?.Operand); + return (TResult)(object)_select.Any(); + case "AsQueryable": + break; + + case "Max": return tplMaxMinAvgSum("Max"); + case "Min": return tplMaxMinAvgSum("Min"); + case "Sum": return tplMaxMinAvgSum("Sum"); + case "Average": return tplMaxMinAvgSum("Avg"); + + case "Concat": + return throwCallExp(" 不支持"); + case "Contains": + if (callExp.Arguments.Count == 2) + { + var dywhere = (callExp.Arguments[1] as ConstantExpression)?.Value as TSource; + if (dywhere == null) return throwCallExp($" 参数值不能为 null"); + _select.WhereDynamic(dywhere); + return (TResult)(object)_select.Any(); + } + return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); + case "Count": + if (callExp.Arguments.Count == 2) _select.Where((Expression>)(callExp.Arguments[1] as UnaryExpression)?.Operand); + return (TResult)Utils.GetDataReaderValue(typeof(TResult), _select.Count()); + + case "Distinct": + if (callExp.Arguments.Count == 1) + { + _select.Distinct(); + break; + } + return throwCallExp(" 不支持"); + + case "ElementAt": + case "ElementAtOrDefault": + _select.Offset((int)(callExp.Arguments[1] as ConstantExpression)?.Value); + _select.Limit(1); + isfirst = true; + break; + case "First": + case "FirstOrDefault": + case "Single": + case "SingleOrDefault": + if (callExp.Arguments.Count == 2) _select.Where((Expression>)(callExp.Arguments[1] as UnaryExpression)?.Operand); + _select.Limit(1); + isfirst = true; + break; + + case "OrderBy": + tplOrderBy("OrderByReflection", false); + break; + case "OrderByDescending": + tplOrderBy("OrderByReflection", true); + break; + case "ThenBy": + tplOrderBy("OrderByReflection", false); + break; + case "ThenByDescending": + tplOrderBy("OrderByReflection", true); + break; + + case "Where": + var whereParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; + if (whereParam.Parameters.Count == 1) + { + if (groupBy != null) groupBy.InternalHaving(whereParam); + else _select.InternalWhere(whereParam); + break; + } + return throwCallExp(" 不支持"); + + case "Skip": + _select.Offset((int)(callExp.Arguments[1] as ConstantExpression)?.Value); + break; + case "Take": + _select.Limit((int)(callExp.Arguments[1] as ConstantExpression)?.Value); + break; + + case "ToList": + if (callExp.Arguments.Count == 1) + return (TResult)(object)_select.ToList(); + return throwCallExp(" 不支持"); + + + case "Select": + var selectParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; + if (selectParam.Parameters.Count == 1) + { + _select._selectExpression = selectParam; + break; + } + return throwCallExp(" 不支持"); + + case "Join": + if (callExp.Arguments.Count == 5) + { + var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression; + var arg3 = (callExp.Arguments[3] as UnaryExpression)?.Operand as LambdaExpression; + var arg4 = (callExp.Arguments[4] as UnaryExpression)?.Operand as LambdaExpression; + FreeSqlExtensionsLinqSql.InternalJoin2(_select, arg2, arg3, arg4); + _select._selectExpression = arg4.Body; + break; + } + return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); + + case "GroupJoin": + if (callExp.Arguments.Count == 5) + { + var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression; + var arg3 = (callExp.Arguments[3] as UnaryExpression)?.Operand as LambdaExpression; + var arg4 = (callExp.Arguments[4] as UnaryExpression)?.Operand as LambdaExpression; + FreeSqlExtensionsLinqSql.InternalJoin2(_select, arg2, arg3, arg4); + _select._selectExpression = arg4.Body; + break; + } + return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); + + case "SelectMany": + if (callExp.Arguments.Count == 3) + { + var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; + var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression; + FreeSqlExtensionsLinqSql.InternalSelectMany2(_select, arg1, arg2); + _select._selectExpression = arg2.Body; + break; + } + return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); + + case "DefaultIfEmpty": + break; + + case "Last": + case "LastOrDefault": + return throwCallExp(" 不支持"); + + case "GroupBy": + return throwCallExp(" 不支持"); + + if (callExp.Arguments.Count == 2) //TODO: 待实现 + { + var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; + + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = -10000; //临时规则,不返回 as1 + + _select._commonExpression.ReadAnonymousField(_select._tables, field, map, ref index, arg1, null, _select._whereCascadeExpression, false); //不走 DTO 映射 + var sql = field.ToString(); + _select.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); + groupBy = new SelectGroupingProvider(_select._orm, _select, map, sql, _select._commonExpression, _select._tables); + break; + } + return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); + + default: + return throwCallExp(" 不支持"); + } + } + if (isfirst) + { + _select.Limit(1); + if (_select._selectExpression != null) + return (TResult)(object)_select.InternalToList(_select._selectExpression).FirstOrDefault(); + return (TResult)(object)_select.ToList().FirstOrDefault(); + } + if (_select._selectExpression != null) + return (TResult)(object)_select.InternalToList(_select._selectExpression); + return (TResult)(object)_select.ToList(); + } + public object Execute(Expression expression) => throw new NotImplementedException(); + } +} diff --git a/Extensions/FreeSql.Extensions.Linq/key.snk b/Extensions/FreeSql.Extensions.Linq/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..e580bc8d5d64e7c5a0c62b971545d38cfbe7d837 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096c(W3|+clf|4d2=6Xc+R`Gd@9@k@Meh} zR8`}1=JPk=q?Zlr?i$1O?SgX-{{&z z|LRF?-aWODhAO}h_7M!wz}uPXx}n-g{((r9{{%_ z4)%gVXcj;Ru@GYAIZI@e#GBtO#O5m-Qr4X_lbAV}=qNRkd0^`@I6i9k`wSe@ZPxVo zk;MXig(S-cYHE!0GWWlp7EH@E!WkF6jS+3z4rvW0%Sq;U1bq`B9*HNJjxo*23*7Vw zHyt>{2CR~8==`lYLgAmwsXPXYZ_AEAKy|PuUz0(G)L1xO{{*n6Bn?mV~QKg!055THihpc>GOh(U-NgO?4_DzY4uq!p9=Q;`G i9;v3GkC674Mbx4_b$)?7a0%Z%&zUjzbGs@!l^s|B literal 0 HcmV?d00001 diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index cc8ec1bf..0670666f 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -73,7 +73,7 @@ namespace FreeSql public ISelect Where(Expression> exp) => _dbset.OrmSelectInternal(null).Where(exp); public ISelect WhereIf(bool condition, Expression> exp) => _dbset.OrmSelectInternal(null).WhereIf(condition, exp); - public int Delete(Expression> predicate) + public virtual int Delete(Expression> predicate) { var delete = _dbset.OrmDeleteInternal(null).Where(predicate); var sql = delete.ToSql(); @@ -82,12 +82,12 @@ namespace FreeSql return affrows; } - public int Delete(TEntity entity) + public virtual int Delete(TEntity entity) { _dbset.Remove(entity); return _db.SaveChanges(); } - public int Delete(IEnumerable entitys) + public virtual int Delete(IEnumerable entitys) { _dbset.RemoveRange(entitys); return _db.SaveChanges(); @@ -157,7 +157,7 @@ namespace FreeSql return ret; } - public int Delete(TKey id) => Delete(CheckTKeyAndReturnIdEntity(id)); + public virtual int Delete(TKey id) => Delete(CheckTKeyAndReturnIdEntity(id)); public TEntity Find(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); public TEntity Get(TKey id) => Find(id); } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs index c3e5dd42..3cded670 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs @@ -13,7 +13,7 @@ namespace FreeSql where TEntity : class { - async public Task DeleteAsync(Expression> predicate) + async virtual public Task DeleteAsync(Expression> predicate) { var delete = _dbset.OrmDeleteInternal(null).Where(predicate); var sql = delete.ToSql(); @@ -22,12 +22,12 @@ namespace FreeSql return affrows; } - public Task DeleteAsync(TEntity entity) + public virtual Task DeleteAsync(TEntity entity) { _dbset.Remove(entity); return _db.SaveChangesAsync(); } - public Task DeleteAsync(IEnumerable entitys) + public virtual Task DeleteAsync(IEnumerable entitys) { _dbset.RemoveRange(entitys); return _db.SaveChangesAsync(); @@ -73,7 +73,7 @@ namespace FreeSql partial class BaseRepository { - public Task DeleteAsync(TKey id) => DeleteAsync(CheckTKeyAndReturnIdEntity(id)); + public virtual Task DeleteAsync(TKey id) => DeleteAsync(CheckTKeyAndReturnIdEntity(id)); public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(); public Task GetAsync(TKey id) => FindAsync(id); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index 5f040d3c..4f26b4ac 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -563,8 +563,6 @@ WHERE ROWNUM < 11"; .UpdateColumns(x => new { x.Status, x.CategoryId, x.ArticleTitle }) .ToSql(); - var sqldddklist = g.mysql.Select().Select(a => new NewsArticleDto { }).ToList(); - var sql1111333 = g.mysql.Update() .SetSource(new Model2 { id = 1, Title = "xxx", Parent_id = 0 }) @@ -608,15 +606,6 @@ WHERE ROWNUM < 11"; .ToList(); var ttt1 = g.mysql.Select().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList(); - - var linqto1 = - from p in g.mysql.Select() - where p.Id >= 0 - // && p.OrderDetails.AsSelect().Where(c => c.Id > 10).Any() - orderby p.Id descending - orderby p.CustomerName ascending - select new { Name = p.CustomerName, Length = p.Id }; - var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index e2398841..7fd0f8e7 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -30,6 +30,7 @@ + diff --git a/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableLinqToSqlTests.cs b/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableLinqToSqlTests.cs new file mode 100644 index 00000000..f028f93a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableLinqToSqlTests.cs @@ -0,0 +1,202 @@ +using FreeSql.DataAnnotations; +using System; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Linq +{ + + + class TestQueryableLinqToSql + { + public Guid id { get; set; } + + public string name { get; set; } + + public int click { get; set; } = 10; + + public DateTime createtime { get; set; } = DateTime.Now; + } + class TestQueryableLinqToSqlComment + { + public Guid id { get; set; } + + public Guid TestLinqToSqlId { get; set; } + public TestQueryableLinqToSql TEstLinqToSql { get; set; } + + public string text { get; set; } + + public DateTime createtime { get; set; } = DateTime.Now; + } + + public class QueryableLinqToSqlTests + { + + [Fact] + public void Where() + { + var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + + var t1 = (from a in g.sqlite.Select().AsQueryable() + where a.id == item.id + select a).ToList(); + Assert.True(t1.Any()); + Assert.Equal(item.id, t1[0].id); + } + + [Fact] + public void Select() + { + var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + + var t1 = (from a in g.sqlite.Select().AsQueryable() + where a.id == item.id + select new { a.id }).ToList(); + Assert.True(t1.Any()); + Assert.Equal(item.id, t1[0].id); + } + + [Fact] + public void GroupBy() + { + //var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() }; + //g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + + //var t1 = (from a in g.sqlite.Select().AsQueryable() + // where a.id == item.id + // group a by new { a.id, a.name } into g + // select new + // { + // g.Key.id, + // g.Key.name, + // cou = g.Count(), + // avg = g.Average(x => x.click), + // sum = g.Sum(x => x.click), + // max = g.Max(x => x.click), + // min = g.Min(x => x.click) + // }).ToList(); + //Assert.True(t1.Any()); + //Assert.Equal(item.id, t1.First().id); + } + + [Fact] + public void CaseWhen() + { + var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + + var t1 = (from a in g.sqlite.Select().AsQueryable() + where a.id == item.id + select new + { + a.id, + a.name, + testsub = new + { + time = a.click > 10 ? "" : "Сڻ" + } + }).ToList(); + Assert.True(t1.Any()); + Assert.Equal(item.id, t1[0].id); + Assert.Equal("Сڻ", t1[0].testsub.time); + } + + [Fact] + public void Join() + { + var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var comment = new TestQueryableLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); + + var t1 = (from a in g.sqlite.Select().AsQueryable() + join b in g.sqlite.Select().AsQueryable() on a.id equals b.TestLinqToSqlId + select a).ToList(); + Assert.True(t1.Any()); + //Assert.Equal(item.id, t1[0].id); + + var t2 = (from a in g.sqlite.Select().AsQueryable() + join b in g.sqlite.Select().AsQueryable() on a.id equals b.TestLinqToSqlId + select new { a.id, bid = b.id }).ToList(); + Assert.True(t2.Any()); + //Assert.Equal(item.id, t2[0].id); + //Assert.Equal(comment.id, t2[0].bid); + + var t3 = (from a in g.sqlite.Select().AsQueryable() + join b in g.sqlite.Select().AsQueryable() on a.id equals b.TestLinqToSqlId + where a.id == item.id + select new { a.id, bid = b.id }).ToList(); + Assert.True(t3.Any()); + Assert.Equal(item.id, t3[0].id); + Assert.Equal(comment.id, t3[0].bid); + } + + [Fact] + public void LeftJoin() + { + var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var comment = new TestQueryableLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); + + var t1 = (from a in g.sqlite.Select().AsQueryable() + join b in g.sqlite.Select().AsQueryable() on a.id equals b.TestLinqToSqlId into temp + from tc in temp.DefaultIfEmpty() + select a).ToList(); + Assert.True(t1.Any()); + //Assert.Equal(item.id, t1[0].id); + + var t2 = (from a in g.sqlite.Select().AsQueryable() + join b in g.sqlite.Select().AsQueryable() on a.id equals b.TestLinqToSqlId into temp + from tc in temp.DefaultIfEmpty() + select new { a.id, bid = tc.id }).ToList(); + Assert.True(t2.Any()); + //Assert.Equal(item.id, t2[0].id); + //Assert.Equal(comment.id, t2[0].bid); + + var t3 = (from a in g.sqlite.Select().AsQueryable() + join b in g.sqlite.Select().AsQueryable() on a.id equals b.TestLinqToSqlId into temp + from tc in temp.DefaultIfEmpty() + where a.id == item.id + select new { a.id, bid = tc.id }).ToList(); + Assert.True(t3.Any()); + Assert.Equal(item.id, t3[0].id); + Assert.Equal(comment.id, t3[0].bid); + } + + [Fact] + public void From() + { + var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + var comment = new TestQueryableLinqToSqlComment { TestLinqToSqlId = item.id, text = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(comment).ExecuteAffrows(); + + var t1 = (from a in g.sqlite.Select().AsQueryable() + from b in g.sqlite.Select().AsQueryable() + where a.id == b.TestLinqToSqlId + select a).ToList(); + Assert.True(t1.Any()); + //Assert.Equal(item.id, t1[0].id); + + var t2 = (from a in g.sqlite.Select().AsQueryable() + from b in g.sqlite.Select().AsQueryable() + where a.id == b.TestLinqToSqlId + select new { a.id, bid = b.id }).ToList(); + Assert.True(t2.Any()); + //Assert.Equal(item.id, t2[0].id); + //Assert.Equal(comment.id, t2[0].bid); + + var t3 = (from a in g.sqlite.Select().AsQueryable() + from b in g.sqlite.Select().AsQueryable() + where a.id == b.TestLinqToSqlId + where a.id == item.id + select new { a.id, bid = b.id }).ToList(); + Assert.True(t3.Any()); + Assert.Equal(item.id, t3[0].id); + Assert.Equal(comment.id, t3[0].bid); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs b/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs index 8dbedf6d..acae29f2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs @@ -17,7 +17,7 @@ using System.Diagnostics; using System.IO; using System.Text; -namespace FreeSql.Tests +namespace FreeSql.Tests.Linq { public class QueryableTest { @@ -66,6 +66,126 @@ namespace FreeSql.Tests Assert.True(fsql.Select().AsQueryable().Any(a => a.id == sd[0].id)); Assert.False(fsql.Select().AsQueryable().Any(a => a.id == sd[0].id && sd[0].id == 0)); } + + [Fact] + public void Max() + { + var avg = fsql.Select().AsQueryable().Max(a => a.id); + Assert.True(avg > 0); + } + [Fact] + public void Min() + { + var avg = fsql.Select().AsQueryable().Min(a => a.id); + Assert.True(avg > 0); + } + [Fact] + public void Sum() + { + var avg = fsql.Select().AsQueryable().Sum(a => a.id); + Assert.True(avg > 0); + } + [Fact] + public void Average() + { + var avg = fsql.Select().AsQueryable().Average(a => a.id); + Assert.True(avg > 0); + } + + [Fact] + public void Contains() + { + Assert.True(fsql.Select().AsQueryable().Contains(new qt01 { id = 1 })); + Assert.False(fsql.Select().AsQueryable().Contains(new qt01 { id = 0 })); + } + + [Fact] + public void Distinct() + { + fsql.Select().AsQueryable().Distinct().Select(a => a.name).ToList(); + } + + [Fact] + public void ElementAt() + { + Assert.Equal(fsql.Select().Skip(1).First().id, fsql.Select().AsQueryable().ElementAt(1).id); + Assert.Equal(fsql.Select().Skip(2).First().id, fsql.Select().AsQueryable().ElementAt(2).id); + Assert.Equal(fsql.Select().Skip(1).First().id, fsql.Select().AsQueryable().ElementAtOrDefault(1).id); + Assert.Equal(fsql.Select().Skip(2).First().id, fsql.Select().AsQueryable().ElementAtOrDefault(2).id); + } + + [Fact] + public void First() + { + Assert.Equal(fsql.Select().First().id, fsql.Select().AsQueryable().First().id); + Assert.Equal(fsql.Select().First().id, fsql.Select().AsQueryable().FirstOrDefault().id); + } + + [Fact] + public void Single() + { + Assert.Equal(fsql.Select().First().id, fsql.Select().AsQueryable().Single().id); + Assert.Equal(fsql.Select().First().id, fsql.Select().AsQueryable().SingleOrDefault().id); + } + + [Fact] + public void OrderBy() + { + Assert.Equal(fsql.Select().OrderBy(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).Single().id); + Assert.Equal(fsql.Select().OrderBy(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).SingleOrDefault().id); + } + [Fact] + public void OrderByDescending() + { + Assert.Equal(fsql.Select().OrderByDescending(a => a.id).First().id, fsql.Select().AsQueryable().OrderByDescending(a => a.id).Single().id); + Assert.Equal(fsql.Select().OrderByDescending(a => a.id).First().id, fsql.Select().AsQueryable().OrderByDescending(a => a.id).SingleOrDefault().id); + } + [Fact] + public void ThenBy() + { + Assert.Equal(fsql.Select().OrderBy(a => a.id).OrderBy(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).OrderBy(a => a.id).Single().id); + Assert.Equal(fsql.Select().OrderBy(a => a.id).OrderBy(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).OrderBy(a => a.id).SingleOrDefault().id); + + Assert.Equal(fsql.Select().OrderBy(a => a.id).OrderBy(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).ThenBy(a => a.id).Single().id); + Assert.Equal(fsql.Select().OrderBy(a => a.id).OrderBy(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).ThenBy(a => a.id).SingleOrDefault().id); + } + [Fact] + public void ThenByDescending() + { + Assert.Equal(fsql.Select().OrderBy(a => a.id).OrderByDescending(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).OrderByDescending(a => a.id).Single().id); + Assert.Equal(fsql.Select().OrderBy(a => a.id).OrderByDescending(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).OrderByDescending(a => a.id).SingleOrDefault().id); + + Assert.Equal(fsql.Select().OrderBy(a => a.id).OrderByDescending(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).ThenByDescending(a => a.id).Single().id); + Assert.Equal(fsql.Select().OrderBy(a => a.id).OrderByDescending(a => a.id).First().id, fsql.Select().AsQueryable().OrderBy(a => a.id).ThenByDescending(a => a.id).SingleOrDefault().id); + } + + [Fact] + public void Select() + { + Assert.Equal(fsql.Select().First(a => a.name), fsql.Select().AsQueryable().Select(a => a.name).Single()); + Assert.Equal(fsql.Select().First(a => new { a.name }).name, fsql.Select().AsQueryable().Select(a => new { a.name }).Single().name); + } + + [Fact] + public void Where() + { + Assert.Equal(fsql.Select().First(a => a.name), fsql.Select().AsQueryable().Select(a => a.name).Single()); + Assert.Equal(fsql.Select().First(a => new { a.name }).name, fsql.Select().AsQueryable().Select(a => new { a.name }).Single().name); + } + + [Fact] + public void Skip() + { + Assert.Equal(fsql.Select().Skip(2).First(a => a.name), fsql.Select().AsQueryable().Skip(2).Select(a => a.name).Single()); + Assert.Equal(fsql.Select().Skip(2).First(a => new { a.name }).name, fsql.Select().AsQueryable().Skip(2).Select(a => new { a.name }).Single().name); + } + + [Fact] + public void Take() + { + Assert.Equal(fsql.Select().Skip(2).First(a => a.name), fsql.Select().AsQueryable().Skip(2).Take(1).Select(a => a.name).ToList().FirstOrDefault()); + Assert.Equal(fsql.Select().Skip(2).First(a => new { a.name }).name, fsql.Select().AsQueryable().Skip(2).Take(1).Select(a => new { a.name }).ToList().FirstOrDefault().name); + } } } diff --git a/FreeSql.sln b/FreeSql.sln index 37d728c5..d7236979 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -76,6 +76,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.EfCoreFl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.All", "FreeSql.All\FreeSql.All.csproj", "{933115AD-769C-4FBE-B000-2E8CF2292377}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.Linq", "Extensions\FreeSql.Extensions.Linq\FreeSql.Extensions.Linq.csproj", "{57B3F5B0-D46A-4442-8EC6-9A9A784404B7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -458,6 +460,18 @@ Global {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|x64.Build.0 = Release|Any CPU {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|x86.ActiveCfg = Release|Any CPU {933115AD-769C-4FBE-B000-2E8CF2292377}.Release|x86.Build.0 = Release|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Debug|x64.ActiveCfg = Debug|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Debug|x64.Build.0 = Debug|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Debug|x86.ActiveCfg = Debug|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Debug|x86.Build.0 = Debug|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|Any CPU.Build.0 = Release|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|x64.ActiveCfg = Release|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|x64.Build.0 = Release|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|x86.ActiveCfg = Release|Any CPU + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -484,6 +498,7 @@ Global {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {B397A761-F646-41CF-A160-AB6C05DAF2FB} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} + {57B3F5B0-D46A-4442-8EC6-9A9A784404B7} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 83ccee42..77e5b1ba 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -993,31 +993,6 @@ 使用属性名作为字段别名 - - - 【linq to sql】专用方法,不建议直接使用 - - - - - 【linq to sql】专用方法,不建议直接使用 - - - - - 【linq to sql】专用方法,不建议直接使用 - - - - - 【linq to sql】专用方法,不建议直接使用 - - - - - 【linq to sql】专用方法,不建议直接使用 - - 指定事务对象 @@ -1748,14 +1723,6 @@ SQL语句 - - - 将 ISelect<T1> 转换为 IQueryable<T1> - 此方法主要用于扩展,比如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 - 注意:IQueryable 方法污染较为严重,请尽量避免此转换 - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") diff --git a/FreeSql/Interface/Curd/ISelect/ILinqToSql.cs b/FreeSql/Interface/Curd/ISelect/ILinqToSql.cs deleted file mode 100644 index bba2d4e0..00000000 --- a/FreeSql/Interface/Curd/ISelect/ILinqToSql.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Text; - -namespace FreeSql -{ - public interface ILinqToSql where T1 : class - { - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect Select(Expression> select) where TReturn : class; - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect Join(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector) where TInner : class where TResult : class; - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect GroupJoin(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector) where TInner : class where TResult : class; - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect DefaultIfEmpty(); - /// - /// 【linq to sql】专用方法,不建议直接使用 - /// - ISelect SelectMany(Expression>> collectionSelector, Expression> resultSelector) where TCollection : class where TResult : class; - } -} diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index a6bb4622..859b48aa 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface ISelect : ISelect0, T1>, ILinqToSql where T1 : class + public interface ISelect : ISelect0, T1> where T1 : class { #if net40 @@ -378,13 +378,5 @@ namespace FreeSql /// SQL语句 /// ISelect WithSql(string sql); - - /// - /// 将 ISelect<T1> 转换为 IQueryable<T1> - /// 此方法主要用于扩展,比如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 - /// 注意:IQueryable 方法污染较为严重,请尽量避免此转换 - /// - /// - IQueryable AsQueryable(); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 8df262b1..c91ecd75 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1,17 +1,18 @@ -using FreeSql.Internal.Model; +using FreeSql.DataAnnotations; +using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Data.Common; +using System.Globalization; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Text.RegularExpressions; -using FreeSql.DataAnnotations; using System.Threading; -using System.Globalization; namespace FreeSql.Internal { @@ -19,8 +20,8 @@ namespace FreeSql.Internal { public CommonUtils _common; - public CommonProvider.AdoProvider _ado => _adoPriv ?? (_adoPriv = _common._orm.Ado as CommonProvider.AdoProvider); - CommonProvider.AdoProvider _adoPriv; + public AdoProvider _ado => _adoPriv ?? (_adoPriv = _common._orm.Ado as AdoProvider); + AdoProvider _adoPriv; public CommonExpression(CommonUtils common) { _common = common; @@ -692,14 +693,6 @@ namespace FreeSql.Internal } if (callType.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { - //if (exp3.Type == typeof(string) && exp3.Arguments.Any() && exp3.Arguments[0].NodeType == ExpressionType.Constant) { - // switch (exp3.Method.Name) { - // case "Sum": return $"sum({(exp3.Arguments[0] as ConstantExpression)?.Value})"; - // case "Avg": return $"avg({(exp3.Arguments[0] as ConstantExpression)?.Value})"; - // case "Max": return $"max({(exp3.Arguments[0] as ConstantExpression)?.Value})"; - // case "Min": return $"min({(exp3.Arguments[0] as ConstantExpression)?.Value})"; - // } - //} switch (exp3.Method.Name) { case "Count": return exp3.Arguments.Count == 0 ? "count(1)" : $"count({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})"; @@ -819,11 +812,10 @@ namespace FreeSql.Internal if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke(); fsqlType = fsql?.GetType(); if (fsqlType == null) break; - if (exp3.Method.Name != "ToList") - fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1); - if (tsc.dbParams != null) - fsqlType.GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, tsc.dbParams); - fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; + var fsqlSelect0 = fsql as Select0Provider; + if (exp3.Method.Name != "ToList") fsqlSelect0._limit = 1; + if (tsc.dbParams != null) fsqlSelect0._params = tsc.dbParams; + fsqltables = fsqlSelect0._tables; //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; if (fsqltables != tsc._tables) fsqltables.AddRange(tsc._tables.Select(a => new SelectTableInfo @@ -836,7 +828,7 @@ namespace FreeSql.Internal })); if (tsc.whereCascadeExpression?.Any() == true) { - var fsqlCascade = fsqlType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List; + var fsqlCascade = fsqlSelect0._whereCascadeExpression; if (fsqlCascade != tsc.whereCascadeExpression) fsqlCascade.AddRange(tsc.whereCascadeExpression); } @@ -1022,12 +1014,6 @@ namespace FreeSql.Internal break; } } - //var eleType = callType.GetElementType() ?? callType.GenericTypeArguments.FirstOrDefault(); - //if (eleType != null && typeof(IEnumerable<>).MakeGenericType(eleType).IsAssignableFrom(callType)) { //集合导航属性子查询 - // if (exp3.Method.Name == "Any") { //exists - - // } - //} other3Exp = ExpressionLambdaToSqlOther(exp3, tsc); if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp; if (exp3.IsParameter() == false) return formatSql(Expression.Lambda(exp3).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); @@ -1107,7 +1093,10 @@ namespace FreeSql.Internal break; case ExpressionType.MemberAccess: var expStackFirstMem = expStack.First() as MemberExpression; - if (expStackFirstMem.Expression?.NodeType == ExpressionType.Constant) firstValue = (expStackFirstMem.Expression as ConstantExpression)?.Value; + if (expStackFirstMem.Expression?.NodeType == ExpressionType.Constant) + firstValue = (expStackFirstMem.Expression as ConstantExpression)?.Value; + else + return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); break; } while (expStack.Any()) diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index bd348901..619f9d23 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -16,7 +16,6 @@ namespace FreeSql.Internal.CommonProvider public abstract partial class CodeFirstProvider : ICodeFirst { - public IFreeSql _orm; public CommonUtils _commonUtils; public CommonExpression _commonExpression; @@ -78,7 +77,7 @@ namespace FreeSql.Internal.CommonProvider _dicSynced.TryAdd(entityType, trydic = new ConcurrentDictionary()); return trydic; } - internal void _dicSycedTryAdd(Type entityType, string tableName = null) => + public void _dicSycedTryAdd(Type entityType, string tableName = null) => _dicSycedGetOrAdd(entityType).TryAdd(GetTableNameLowerOrUpper(tableName), true); public void SyncStructure() => diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/QueryableProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/QueryableProvider.cs deleted file mode 100644 index bf52e097..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/QueryableProvider.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Text; - -namespace FreeSql.Internal.CommonProvider -{ - class QueryableProvider : IQueryable - { - private Expression _expression; - private IQueryProvider _provider; - private object _select; - private CommonExpression _commonExpression; - - public QueryableProvider(object select) - { - _select = select; - _commonExpression = _select.GetType().GetField("_commonExpression", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_select) as CommonExpression; - _expression = Expression.Constant(this); - _provider = new QueryProvider(_select, _commonExpression); - } - public QueryableProvider(Expression expression, IQueryProvider provider, object select, CommonExpression commonExpression) - { - _select = select; - _commonExpression = commonExpression; - _expression = expression; - _provider = provider; - } - - public IEnumerator GetEnumerator() - { - var result = _provider.Execute>(_expression); - if (result == null) - yield break; - foreach (var item in result) - { - yield return item; - } - } - IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); - - public Type ElementType => typeof(QueryableProvider); - public Expression Expression => _expression; - public IQueryProvider Provider => _provider; - } - - class QueryProvider : IQueryProvider - { - private object _select; - private CommonExpression _commonExpression; - - public QueryProvider(object select, CommonExpression commonExpression) - { - _select = select; - _commonExpression = commonExpression; - } - - public IQueryable CreateQuery(Expression expression) - { - IQueryable query = new QueryableProvider(expression, this, _select, _commonExpression); - return query; - } - public IQueryable CreateQuery(Expression expression) => throw new NotImplementedException(); - - - public TResult Execute(Expression expression) - { - var methodExp = expression as MethodCallExpression; - while (methodExp != null) - { - switch (methodExp.Method.Name) - { - case "First": - case "FirstOrDefault": - _select.GetType().GetMethod("Limit", new[] { typeof(int) }).Invoke(_select, new object[] { 1 }); - break; - default: - var selectMethod = _select.GetType().GetMethod(methodExp.Method.Name, methodExp.Arguments.Where((a, b) => b > 0).Select(a => a.Type).ToArray()); - if (selectMethod == null) throw new Exception($"无法找到 ISelect.{methodExp.Method.Name}({string.Join(", ", methodExp.Arguments.Select(a => a.Type.FullName))}) 方法"); - - var selectArgs = methodExp.Arguments.Where((a, b) => b > 0).Select(a => - { - switch (a.NodeType) - { - case ExpressionType.Lambda: return (object)a; - default: return Expression.Lambda(a).Compile().DynamicInvoke(); - } - }).ToArray(); - selectMethod.Invoke(_select, selectArgs); - break; - } - methodExp = methodExp.Arguments.FirstOrDefault() as MethodCallExpression; - } - var resultType = typeof(TResult); - var resultTypeIsList = typeof(IList).IsAssignableFrom(resultType); - if (resultTypeIsList) resultType = resultType.GetGenericArguments()[0]; - var ret = _select.GetType().GetMethod(resultTypeIsList ? "ToList" : "First", new Type[0]) - .MakeGenericMethod(resultType) - .Invoke(_select, new object[0]); - return (TResult)ret; - } - public object Execute(Expression expression) => throw new NotImplementedException(); - } -} diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 950b1383..d25664fd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -16,33 +16,32 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract partial class Select0Provider : ISelect0 where TSelect : class where T1 : class + public abstract partial class Select0Provider { - - protected int _limit, _skip; - protected string _select = "SELECT ", _orderby, _groupby, _having; - protected StringBuilder _where = new StringBuilder(); - protected List _params = new List(); - internal protected List _tables = new List(); - protected List> _tableRules = new List>(); - protected Func _aliasRule; - protected string _tosqlAppendContent; - protected StringBuilder _join = new StringBuilder(); - internal protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected DbTransaction _transaction; - protected DbConnection _connection; - internal protected Action _trackToList; - internal protected List> _includeToList = new List>(); + public int _limit, _skip; + public string _select = "SELECT ", _orderby, _groupby, _having; + public StringBuilder _where = new StringBuilder(); + public List _params = new List(); + public List _tables = new List(); + public List> _tableRules = new List>(); + public Func _aliasRule; + public string _tosqlAppendContent; + public StringBuilder _join = new StringBuilder(); + public IFreeSql _orm; + public CommonUtils _commonUtils; + public CommonExpression _commonExpression; + public DbTransaction _transaction; + public DbConnection _connection; + public Action _trackToList; + public List> _includeToList = new List>(); #if net40 #else - protected List> _includeToListAsync = new List>(); + public List> _includeToListAsync = new List>(); #endif - protected bool _distinct; - protected Expression _selectExpression; - protected List _whereCascadeExpression = new List(); - protected List _whereGlobalFilter; + public bool _distinct; + public Expression _selectExpression; + public List _whereCascadeExpression = new List(); + public List _whereGlobalFilter; int _disposeCounter; ~Select0Provider() @@ -64,24 +63,25 @@ namespace FreeSql.Internal.CommonProvider _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); _whereCascadeExpression.AddRange(_whereGlobalFilter.Select(a => a.Where)); } - public static void CopyData(Select0Provider from, object to, ReadOnlyCollection lambParms) + + public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection lambParms) { - var toType = to?.GetType(); - if (toType == null) return; - toType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._limit); - toType.GetField("_skip", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._skip); - toType.GetField("_select", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._select); - toType.GetField("_orderby", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orderby); - toType.GetField("_groupby", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._groupby); - toType.GetField("_having", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._having); - toType.GetField("_where", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._where.ToString())); - toType.GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._params.ToArray())); + if (to == null) return; + to._limit = from._limit; + to._skip = from._skip; + to._select = from._select; + to._orderby = from._orderby; + to._groupby = from._groupby; + to._having = from._having; + to._where = new StringBuilder().Append(from._where.ToString()); + to._params = new List(from._params.ToArray()); + if (lambParms == null) - toType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._tables.ToArray())); + to._tables = new List(from._tables.ToArray()); else { var findedIndexs = new List(); - var _multiTables = toType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(to) as List; + var _multiTables = to._tables; _multiTables[0] = from._tables[0]; for (var a = 1; a < lambParms.Count; a++) { @@ -103,26 +103,29 @@ namespace FreeSql.Internal.CommonProvider _multiTables.Add(from._tables[a]); } } - toType.GetField("_tableRules", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List>(from._tableRules.ToArray())); - toType.GetField("_aliasRule", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._aliasRule); - toType.GetField("_join", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._join.ToString())); - //toType.GetField("_orm", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orm); - //toType.GetField("_commonUtils", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonUtils); - //toType.GetField("_commonExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonExpression); - toType.GetField("_transaction", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._transaction); - toType.GetField("_connection", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._connection); - toType.GetField("_trackToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._trackToList); - toType.GetField("_includeToList", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List>(from._includeToList.ToArray())); + to._tableRules = new List>(from._tableRules.ToArray()); + to._aliasRule = from._aliasRule; + to._join = new StringBuilder().Append(from._join.ToString()); + //to._orm = from._orm; + //to._commonUtils = from._commonUtils; + //to._commonExpression = from._commonExpression; + to._transaction = from._transaction; + to._connection = from._connection; + to._trackToList = from._trackToList; + to._includeToList = new List>(from._includeToList.ToArray()); #if net40 #else - toType.GetField("_includeToListAsync", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List>(from._includeToListAsync.ToArray())); + to._includeToListAsync = new List>(from._includeToListAsync.ToArray()); #endif - toType.GetField("_distinct", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._distinct); - toType.GetField("_selectExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._selectExpression); - toType.GetField("_whereCascadeExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._whereCascadeExpression.ToArray())); - toType.GetField("_whereGlobalFilter", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new List(from._whereGlobalFilter.ToArray())); + to._distinct = from._distinct; + to._selectExpression = from._selectExpression; + to._whereCascadeExpression = new List(from._whereCascadeExpression.ToArray()); + to._whereGlobalFilter = new List(from._whereGlobalFilter.ToArray()); } + } + public abstract partial class Select0Provider : Select0Provider, ISelect0 where TSelect : class where T1 : class + { public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { _orm = orm; @@ -1082,7 +1085,7 @@ namespace FreeSql.Internal.CommonProvider protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Min(); protected decimal InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Sum(); - protected ISelectGrouping InternalGroupBy(Expression columns) + public ISelectGrouping InternalGroupBy(Expression columns) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); @@ -1093,7 +1096,7 @@ namespace FreeSql.Internal.CommonProvider this.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); return new SelectGroupingProvider(_orm, this, map, sql, _commonExpression, _tables); } - protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) + public TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); return this as TSelect; @@ -1109,7 +1112,7 @@ namespace FreeSql.Internal.CommonProvider protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); - protected List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); + public List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); protected string InternalToSql(Expression select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { var af = this.GetExpressionField(select, fieldAlias); @@ -1151,7 +1154,7 @@ namespace FreeSql.Internal.CommonProvider return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } - protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params)); + public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params)); #endregion #if net40 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index f47cf885..50b62e21 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -111,15 +111,15 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class;// { this.InternalFrom(exp); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class;// { this.InternalFrom(exp); var ret = new Select3Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class;// { this.InternalFrom(exp); var ret = new Select4Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class;// { this.InternalFrom(exp); var ret = new Select5Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class;// { this.InternalFrom(exp); var ret = new Select6Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class;// { this.InternalFrom(exp); var ret = new Select7Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class;// { this.InternalFrom(exp); var ret = new Select8Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class;// { this.InternalFrom(exp); var ret = new Select9Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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;// { this.InternalFrom(exp); var ret = new Select10Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret, exp?.Parameters); return ret; } + public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class; + public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class; + public abstract ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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; public ISelectGrouping GroupBy(Expression> columns) { @@ -132,41 +132,48 @@ namespace FreeSql.Internal.CommonProvider { if (column == null) return default(TMember); _tables[0].Parameter = column.Parameters[0]; - return this.InternalMax(column?.Body); + return this.InternalMax(column.Body); } public TMember Min(Expression> column) { if (column == null) return default(TMember); _tables[0].Parameter = column.Parameters[0]; - return this.InternalMin(column?.Body); + return this.InternalMin(column.Body); + } + public void OrderByReflection(LambdaExpression column, bool isDescending) + { + if (column == null) return; + _tables[0].Parameter = column.Parameters[0]; + if (isDescending) this.InternalOrderByDescending(column.Body); + else this.InternalOrderBy(column.Body); } public ISelect OrderBy(Expression> column) => this.OrderBy(true, column); public ISelect OrderBy(bool condition, Expression> column) { if (condition == false || column == null) return this; _tables[0].Parameter = column.Parameters[0]; - return this.InternalOrderBy(column?.Body); + return this.InternalOrderBy(column.Body); } public ISelect OrderByDescending(Expression> column) => this.OrderByDescending(true, column); public ISelect OrderByDescending(bool condition, Expression> column) { if (condition == false || column == null) return this; _tables[0].Parameter = column.Parameters[0]; - return this.InternalOrderByDescending(column?.Body); + return this.InternalOrderByDescending(column.Body); } public decimal Sum(Expression> column) { if (column == null) return default(decimal); _tables[0].Parameter = column.Parameters[0]; - return this.InternalSum(column?.Body); + return this.InternalSum(column.Body); } public List ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); _tables[0].Parameter = select.Parameters[0]; - return this.InternalToList(select?.Body); + return this.InternalToList(select.Body); } public List ToList() => ToList(GetToListDtoSelector()); @@ -177,89 +184,6 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a")); } - #region linq to sql - public ISelect Select(Expression> select) where TReturn : class - { - if (typeof(TReturn) == typeof(T1)) return this as ISelect; - _tables[0].Parameter = select.Parameters[0]; - _selectExpression = select.Body; - if (_orm.CodeFirst.IsAutoSyncStructure) - (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TReturn)); //._dicSyced.TryAdd(typeof(TReturn), true); - var ret = _orm.Select(); - Select0Provider, T1>.CopyData(this, ret, null); - return ret; - } - public ISelect Join(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector) where TInner : class where TResult : class - { - _tables[0].Parameter = resultSelector.Parameters[0]; - _commonExpression.ExpressionLambdaToSql(outerKeySelector, new CommonExpression.ExpTSC { _tables = _tables }); - this.InternalJoin(Expression.Lambda>( - Expression.Equal(outerKeySelector.Body, innerKeySelector.Body), - new[] { outerKeySelector.Parameters[0], innerKeySelector.Parameters[0] } - ), SelectTableInfoType.InnerJoin); - if (typeof(TResult) == typeof(T1)) return this as ISelect; - _selectExpression = resultSelector.Body; - if (_orm.CodeFirst.IsAutoSyncStructure) - (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); - var ret = _orm.Select() as Select1Provider; - Select0Provider, T1>.CopyData(this, ret, null); - return ret; - } - public ISelect GroupJoin(ISelect inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector) where TInner : class where TResult : class - { - _tables[0].Parameter = resultSelector.Parameters[0]; - _commonExpression.ExpressionLambdaToSql(outerKeySelector, new CommonExpression.ExpTSC { _tables = _tables }); - this.InternalJoin(Expression.Lambda>( - Expression.Equal(outerKeySelector.Body, innerKeySelector.Body), - new[] { outerKeySelector.Parameters[0], innerKeySelector.Parameters[0] } - ), SelectTableInfoType.InnerJoin); - if (typeof(TResult) == typeof(T1)) return this as ISelect; - _selectExpression = resultSelector.Body; - if (_orm.CodeFirst.IsAutoSyncStructure) - (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); - var ret = _orm.Select() as Select1Provider; - Select0Provider, T1>.CopyData(this, ret, null); - return ret; - } - public ISelect SelectMany(Expression>> collectionSelector, Expression> resultSelector) where TCollection : class where TResult : class - { - SelectTableInfo find = null; - if (collectionSelector.Body.NodeType == ExpressionType.Call) - { - var callExp = collectionSelector.Body as MethodCallExpression; - if (callExp.Method.Name == "DefaultIfEmpty" && callExp.Object.Type.GetGenericArguments().Any()) - { - find = _tables.Where((a, idx) => idx > 0 && a.Type == SelectTableInfoType.InnerJoin && a.Table.Type == callExp.Object.Type.GetGenericArguments()[0]).LastOrDefault(); - if (find != null) - { - if (!string.IsNullOrEmpty(find.On)) find.On = Regex.Replace(find.On, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); - if (!string.IsNullOrEmpty(find.NavigateCondition)) find.NavigateCondition = Regex.Replace(find.NavigateCondition, $@"\b{find.Alias}\.", $"{resultSelector.Parameters[1].Name}."); - find.Type = SelectTableInfoType.LeftJoin; - find.Alias = resultSelector.Parameters[1].Name; - find.Parameter = resultSelector.Parameters[1]; - } - } - } - if (find == null) - { - var tb = _commonUtils.GetTableByEntity(typeof(TCollection)); - if (tb == null) throw new Exception($"SelectMany 错误的类型:{typeof(TCollection).FullName}"); - _tables.Add(new SelectTableInfo { Alias = resultSelector.Parameters[1].Name, AliasInit = resultSelector.Parameters[1].Name, Parameter = resultSelector.Parameters[1], Table = tb, Type = SelectTableInfoType.From }); - } - if (typeof(TResult) == typeof(T1)) return this as ISelect; - _selectExpression = resultSelector.Body; - if (_orm.CodeFirst.IsAutoSyncStructure) - (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true); - var ret = _orm.Select() as Select1Provider; - Select0Provider, T1>.CopyData(this, ret, null); - return ret; - } - public ISelect DefaultIfEmpty() - { - return this; - } - #endregion - public DataTable ToDataTable(Expression> select) { if (select == null) return this.InternalToDataTable(select?.Body); @@ -1083,8 +1007,6 @@ namespace FreeSql.Internal.CommonProvider _trackToList?.Invoke(list); } - public IQueryable AsQueryable() => new QueryableProvider(this); - #if net40 #else async internal Task SetListAsync(IEnumerable list) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 8c2474c4..e353c0f5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -1,5 +1,6 @@ using FreeSql.Internal.Model; using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -9,14 +10,15 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public class SelectGroupingProvider : ISelectGrouping + public class SelectGroupingProvider { - internal IFreeSql _orm; - internal object _select; - internal ReadAnonymousTypeInfo _map; - internal string _field; - internal CommonExpression _comonExp; - internal List _tables; + public IFreeSql _orm; + public object _select; + public ReadAnonymousTypeInfo _map; + public string _field; + public CommonExpression _comonExp; + public List _tables; + public SelectGroupingProvider(IFreeSql orm, object select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List tables) { _orm = orm; @@ -27,7 +29,7 @@ namespace FreeSql.Internal.CommonProvider _tables = tables; } - string getSelectGroupingMapString(Expression[] members) + public string getSelectGroupingMapString(Expression[] members) { if (members.Any() == false) return _map.DbField; var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name; @@ -85,59 +87,45 @@ namespace FreeSql.Internal.CommonProvider return null; } - public ISelectGrouping Having(Expression, bool>> exp) + public void InternalHaving(Expression exp) { var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null, null); var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { sql, null }); - return this; } - - public ISelectGrouping OrderBy(Expression, TMember>> column) + public void InternalOrderBy(Expression exp, bool isDescending) { - var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null, null); + var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null, null); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); - method.Invoke(_select, new object[] { sql, null }); - return this; + method.Invoke(_select, new object[] { isDescending ? $"{sql} DESC" : sql, null }); } - - public ISelectGrouping OrderByDescending(Expression, TMember>> column) - { - var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString, null, null); - var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); - method.Invoke(_select, new object[] { $"{sql} DESC", null }); - return this; - } - - public List Select(Expression, TReturn>> select) => ToList(select); - public List ToList(Expression, TReturn>> select) + public object InternalToList(Expression select, Type elementType, bool isAsync) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = 0; _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); - if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); - var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(typeof(TReturn)); - return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List; + if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; + var method = _select.GetType().GetMethod(isAsync ? "ToListMapReaderAsync" : "ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(elementType); + return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }); } - public Dictionary ToDictionary(Expression, TElement>> elementSelector) + public IEnumerable> InternalToKeyValuePairs(Expression elementSelector, Type elementType) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = 0; _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, getSelectGroupingMapString, null, false); - if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement); + if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; var method = _select.GetType().GetMethod("ToListMapReaderPrivate", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(typeof(TElement)); + method = method.MakeGenericMethod(elementType); var otherAf = new ReadAnonymousTypeOtherInfo(_field, _map, new List()); - var values = method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null), new[] { otherAf } }) as List; - return otherAf.retlist.Select((a, b) => new KeyValuePair((TKey)a, values[b])).ToDictionary(a => a.Key, a => a.Value); + var values = method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null), new[] { otherAf } }) as IList; + return otherAf.retlist.Select((a, b) => new KeyValuePair(a, values[b])); } - - public string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + public string InternalToSql(Expression select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); @@ -147,6 +135,14 @@ namespace FreeSql.Internal.CommonProvider var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; } + } + + public class SelectGroupingProvider : SelectGroupingProvider, ISelectGrouping + { + public SelectGroupingProvider(IFreeSql orm, object select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List tables) + :base(orm, select, map, field, comonExp, tables) { } + + public string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) => InternalToSql(select, fieldAlias); public string ToSql(string field) { if (string.IsNullOrEmpty(field)) @@ -163,7 +159,6 @@ namespace FreeSql.Internal.CommonProvider return this; } public ISelectGrouping Offset(int offset) => this.Skip(offset); - public ISelectGrouping Limit(int limit) { var method = _select.GetType().GetMethod("Limit", new[] { typeof(int) }); @@ -171,7 +166,6 @@ namespace FreeSql.Internal.CommonProvider return this; } public ISelectGrouping Take(int limit) => this.Limit(limit); - public ISelectGrouping Page(int pageNumber, int pageSize) { var method = _select.GetType().GetMethod("Page", new[] { typeof(int), typeof(int) }); @@ -186,22 +180,31 @@ namespace FreeSql.Internal.CommonProvider return this; } + public ISelectGrouping Having(Expression, bool>> exp) + { + InternalHaving(exp); + return this; + } + public ISelectGrouping OrderBy(Expression, TMember>> column) + { + InternalOrderBy(column, false); + return this; + } + public ISelectGrouping OrderByDescending(Expression, TMember>> column) + { + InternalOrderBy(column, true); + return this; + } + + public List Select(Expression, TReturn>> select) => ToList(select); + public List ToList(Expression, TReturn>> select) => InternalToList(select, typeof(TReturn), false) as List; + public Dictionary ToDictionary(Expression, TElement>> elementSelector) => InternalToKeyValuePairs(elementSelector, typeof(TElement)).ToDictionary(a => (TKey)a.Key, a => (TElement)a.Value); + #if net40 #else async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync($"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta")), out var trylng) ? trylng : default(long); - public Task> ToListAsync(Expression, TReturn>> select) - { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; - - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); - if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); - var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(typeof(TReturn)); - return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task>; - } + public Task> ToListAsync(Expression, TReturn>> select) => InternalToList(select, typeof(TReturn), true) as Task>; async public Task> ToDictionaryAsync(Expression, TElement>> elementSelector) { var map = new ReadAnonymousTypeInfo(); From a958a64bd028ef2f335b7cfaca2f1fa5d668488d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Apr 2020 02:55:54 +0800 Subject: [PATCH 0553/1029] update ToTreeList tests --- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 111 +++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 FreeSql.Tests/FreeSql.Tests/UnitTest4.cs diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs new file mode 100644 index 00000000..de67fa13 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -0,0 +1,111 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using System.Data.SqlClient; +using kwlib; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace FreeSql.Tests +{ + public class UnitTest4 + { + [Fact] + public void Test04() + { + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.sqlite.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = g.sqlite.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = g.sqlite.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = g.sqlite.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } + +} From f9566af7d100fb9e3964bd890910fca3b7ce2673 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Apr 2020 11:58:47 +0800 Subject: [PATCH 0554/1029] update IQueryable provider --- .../FreeSql.Extensions.Linq/ExprHelper.cs | 95 +++++++++++++++++++ .../QueryableProvider.cs | 17 ++-- .../FreeSql.Tests/Queryable/ExprHelperTest.cs | 63 ++++++++++++ 3 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.Linq/ExprHelper.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Queryable/ExprHelperTest.cs diff --git a/Extensions/FreeSql.Extensions.Linq/ExprHelper.cs b/Extensions/FreeSql.Extensions.Linq/ExprHelper.cs new file mode 100644 index 00000000..75d2e5aa --- /dev/null +++ b/Extensions/FreeSql.Extensions.Linq/ExprHelper.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq.Expressions; +using System.Linq; +using System.Reflection; + +namespace FreeSql.Extensions.Linq +{ + public static class ExprHelper + { + public static object GetConstExprValue(this Expression exp) + { + if (exp.IsParameter()) return null; + + var expStack = new Stack(); + var exp2 = exp; + while (true) + { + switch (exp2?.NodeType) + { + case ExpressionType.Constant: + expStack.Push(exp2); + break; + case ExpressionType.MemberAccess: + expStack.Push(exp2); + exp2 = (exp2 as MemberExpression).Expression; + if (exp2 == null) break; + continue; + case ExpressionType.Call: + return Expression.Lambda(exp).Compile().DynamicInvoke(); + case ExpressionType.TypeAs: + case ExpressionType.Convert: + var oper2 = (exp2 as UnaryExpression).Operand; + if (oper2.NodeType == ExpressionType.Parameter) + { + var oper2Parm = oper2 as ParameterExpression; + expStack.Push(exp2.Type.IsAbstract || exp2.Type.IsInterface ? oper2Parm : Expression.Parameter(exp2.Type, oper2Parm.Name)); + } + else + expStack.Push(oper2); + break; + } + break; + } + object firstValue = null; + switch (expStack.First().NodeType) + { + case ExpressionType.Constant: + var expStackFirst = expStack.Pop() as ConstantExpression; + firstValue = expStackFirst?.Value; + break; + case ExpressionType.MemberAccess: + var expStackFirstMem = expStack.First() as MemberExpression; + if (expStackFirstMem.Expression?.NodeType == ExpressionType.Constant) + firstValue = (expStackFirstMem.Expression as ConstantExpression)?.Value; + else + return Expression.Lambda(exp).Compile().DynamicInvoke(); + break; + } + while (expStack.Any()) + { + var expStackItem = expStack.Pop(); + switch (expStackItem.NodeType) + { + case ExpressionType.MemberAccess: + var memExp = expStackItem as MemberExpression; + if (memExp.Member.MemberType == MemberTypes.Property) + firstValue = ((PropertyInfo)memExp.Member).GetValue(firstValue, null); + else if (memExp.Member.MemberType == MemberTypes.Field) + firstValue = ((FieldInfo)memExp.Member).GetValue(firstValue); + break; + } + } + return firstValue; + } + + public static bool IsParameter(this Expression exp) + { + var test = new TestParameterExpressionVisitor(); + test.Visit(exp); + return test.Result; + } + internal class TestParameterExpressionVisitor : ExpressionVisitor + { + public bool Result { get; private set; } + + protected override Expression VisitParameter(ParameterExpression node) + { + if (!Result) Result = true; + return node; + } + } + } +} diff --git a/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs b/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs index 892e1cf8..b65147b1 100644 --- a/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs +++ b/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs @@ -81,7 +81,7 @@ namespace FreeSql.Extensions.Linq { callExp = stackCallExps.Pop(); TResult throwCallExp(string message) => throw new Exception($"FreeSql Queryable 解析出错,执行的方法 {callExp.Method.Name} {message}"); - if (callExp.Method.DeclaringType != typeof(Queryable)) return throwCallExp($"必须属于 System.Linq.Enumerable"); + if (callExp.Method.DeclaringType != typeof(Queryable)) return throwCallExp($"必须属于 System.Linq.Queryable"); TResult tplMaxMinAvgSum(string method) { if (callExp.Arguments.Count == 2) @@ -105,7 +105,7 @@ namespace FreeSql.Extensions.Linq switch (callExp.Method.Name) { case "Any": - if (callExp.Arguments.Count == 2) _select.Where((Expression>)(callExp.Arguments[1] as UnaryExpression)?.Operand); + if (callExp.Arguments.Count == 2) _select.InternalWhere(callExp.Arguments[1]); return (TResult)(object)_select.Any(); case "AsQueryable": break; @@ -120,14 +120,14 @@ namespace FreeSql.Extensions.Linq case "Contains": if (callExp.Arguments.Count == 2) { - var dywhere = (callExp.Arguments[1] as ConstantExpression)?.Value as TSource; + var dywhere = callExp.Arguments[1].GetConstExprValue(); if (dywhere == null) return throwCallExp($" 参数值不能为 null"); _select.WhereDynamic(dywhere); return (TResult)(object)_select.Any(); } return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); case "Count": - if (callExp.Arguments.Count == 2) _select.Where((Expression>)(callExp.Arguments[1] as UnaryExpression)?.Operand); + if (callExp.Arguments.Count == 2) _select.InternalWhere(callExp.Arguments[1]); return (TResult)Utils.GetDataReaderValue(typeof(TResult), _select.Count()); case "Distinct": @@ -140,7 +140,7 @@ namespace FreeSql.Extensions.Linq case "ElementAt": case "ElementAtOrDefault": - _select.Offset((int)(callExp.Arguments[1] as ConstantExpression)?.Value); + _select.Offset((int)callExp.Arguments[1].GetConstExprValue()); _select.Limit(1); isfirst = true; break; @@ -148,7 +148,7 @@ namespace FreeSql.Extensions.Linq case "FirstOrDefault": case "Single": case "SingleOrDefault": - if (callExp.Arguments.Count == 2) _select.Where((Expression>)(callExp.Arguments[1] as UnaryExpression)?.Operand); + if (callExp.Arguments.Count == 2) _select.InternalWhere(callExp.Arguments[1]); _select.Limit(1); isfirst = true; break; @@ -177,10 +177,10 @@ namespace FreeSql.Extensions.Linq return throwCallExp(" 不支持"); case "Skip": - _select.Offset((int)(callExp.Arguments[1] as ConstantExpression)?.Value); + _select.Offset((int)callExp.Arguments[1].GetConstExprValue()); break; case "Take": - _select.Limit((int)(callExp.Arguments[1] as ConstantExpression)?.Value); + _select.Limit((int)callExp.Arguments[1].GetConstExprValue()); break; case "ToList": @@ -188,7 +188,6 @@ namespace FreeSql.Extensions.Linq return (TResult)(object)_select.ToList(); return throwCallExp(" 不支持"); - case "Select": var selectParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; if (selectParam.Parameters.Count == 1) diff --git a/FreeSql.Tests/FreeSql.Tests/Queryable/ExprHelperTest.cs b/FreeSql.Tests/FreeSql.Tests/Queryable/ExprHelperTest.cs new file mode 100644 index 00000000..a302b81f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Queryable/ExprHelperTest.cs @@ -0,0 +1,63 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using System.Data.SqlClient; +using kwlib; +using System.Diagnostics; +using System.IO; +using System.Text; +using FreeSql.Extensions.Linq; + +namespace FreeSql.Tests.Linq +{ + public class ExprHelperTest + { + + [Fact] + public void GetConstExprValue() + { + Assert.Equal(-1, ExprHelper.GetConstExprValue(Expression.Constant(-1))); + Assert.Equal(-2, ExprHelper.GetConstExprValue(Expression.Constant(-2))); + Assert.Equal(0, ExprHelper.GetConstExprValue(Expression.Constant(0))); + Assert.Equal(1, ExprHelper.GetConstExprValue(Expression.Constant(1))); + Assert.Equal(2, ExprHelper.GetConstExprValue(Expression.Constant(2))); + + var arr = new[] { -1, -2, 0, 1, 2 }; + for (var a = 0; a < arr.Length; a++) + { + Assert.Equal(arr[a], ExprHelper.GetConstExprValue(Expression.Constant(arr[a]))); + } + + var arritems = new[] + { + new ArrItem { Prop = -1, Field = -1 }, + new ArrItem { Prop = -2, Field = -2 }, + new ArrItem { Prop = 0, Field = 0 }, + new ArrItem { Prop = 1, Field = 1 }, + new ArrItem { Prop = 2, Field = 2 }, + }; + for (var a = 0; a < arr.Length; a++) + { + Assert.Equal(arritems[a].Prop, ExprHelper.GetConstExprValue(Expression.Constant(arritems[a].Prop))); + Assert.Equal(arritems[a].Field, ExprHelper.GetConstExprValue(Expression.Constant(arritems[a].Field))); + } + } + + class ArrItem + { + public int Prop { get; set; } + public int Field { get; set; } + } + } + +} From 4e4240ff7aaeed7f05e470f321f80035a203b576 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Apr 2020 13:09:08 +0800 Subject: [PATCH 0555/1029] add ToTreeList tests #268 --- FreeSql.DbContext/DbContext/DbContext.cs | 2 +- .../Extensions/FreeSqlDbContextExtensions.cs | 6 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - .../FreeSql.Tests.DbContext/UnitTest1.cs | 4 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 85 +++++ .../Dameng/Curd/DamengSelectTest.cs | 85 +++++ .../Default/Curd/OdbcSelectTest.cs | 85 +++++ .../MySql/Curd/MySqlSelectTest.cs | 85 +++++ .../Oracle/Curd/OracleSelectTest.cs | 85 +++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 85 +++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 85 +++++ .../MsAccess/Curd/MsAccessSelectTest.cs | 85 +++++ .../MySql/Curd/MySqlSelectTest.cs | 85 +++++ .../Oracle/Curd/OracleSelectTest.cs | 85 +++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 84 +++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 85 +++++ .../Sqlite/Curd/SqliteSelectTest.cs | 85 +++++ FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 111 ------- FreeSql/FreeSql.xml | 311 ++++++++++-------- FreeSql/Interface/IAdo.cs | 4 + .../CommonProvider/AdoProvider/AdoProvider.cs | 2 + .../Default/OdbcProvider.cs | 8 +- .../Curd/SqlServerSelect.cs | 2 +- .../SqlServerExtensions.cs | 4 +- 24 files changed, 1291 insertions(+), 283 deletions(-) delete mode 100644 FreeSql.Tests/FreeSql.Tests/UnitTest4.cs diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 9f59b794..c4ac6da4 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -43,7 +43,7 @@ namespace FreeSql if (_optionsPriv == null) { _optionsPriv = new DbContextOptions(); - if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(Orm, out var opt)) + if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(Orm.Ado.Identifier, out var opt)) { _optionsPriv.EnableAddOrUpdateNavigateList = opt.EnableAddOrUpdateNavigateList; _optionsPriv.OnEntityChange = opt.OnEntityChange; diff --git a/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs index b4658e20..c6084096 100644 --- a/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs +++ b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs @@ -35,10 +35,10 @@ public static class FreeSqlDbContextExtensions public static IFreeSql SetDbContextOptions(this IFreeSql that, Action options) { if (options == null) return that; - var cfg = _dicSetDbContextOptions.GetOrAdd(that, t => new DbContextOptions()); + var cfg = _dicSetDbContextOptions.GetOrAdd(that.Ado.Identifier, t => new DbContextOptions()); options(cfg); - _dicSetDbContextOptions.AddOrUpdate(that, cfg, (t, o) => cfg); + _dicSetDbContextOptions.AddOrUpdate(that.Ado.Identifier, cfg, (t, o) => cfg); return that; } - internal static ConcurrentDictionary _dicSetDbContextOptions = new ConcurrentDictionary(); + internal static ConcurrentDictionary _dicSetDbContextOptions = new ConcurrentDictionary(); } \ No newline at end of file diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index eacd506b..63db6c75 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -121,13 +121,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -222,15 +215,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index 1f2e7e9c..f01f8158 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -148,7 +148,7 @@ namespace FreeSql.Tests //֧ 1Զ - using (var ctx = new FreeContext(g.sqlite)) + using (var ctx = g.sqlite.CreateDbContext()) { var tags = ctx.Set().Select.IncludeMany(a => a.Tags).ToList(); @@ -177,7 +177,7 @@ namespace FreeSql.Tests { //ѯ 1Զ࣬ټ - using (var ctx = new FreeContext(g.sqlite)) + using (var ctx = g.sqlite.CreateDbContext()) { var tag = ctx.Set().Select.First(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 5b67eff0..554be95f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1848,5 +1848,90 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index ea7b538e..20705c2a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -1698,5 +1698,90 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.dameng; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index c0a0a23e..617e15d3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -1510,5 +1510,90 @@ WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.odbc; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index d72847b8..fc1cd64f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1859,5 +1859,90 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index e97f991c..fa4e36d9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -1699,5 +1699,90 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 3f9b79cf..c46c8307 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1758,5 +1758,90 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 701c91a7..ff5031e9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -1649,5 +1649,90 @@ WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index 7bb03da1..09682b77 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -1511,5 +1511,90 @@ WHERE (((cstr(a.[Id])) in (SELECT b.[Title] orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.msaccess; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 60f05168..afbaffc4 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1907,5 +1907,90 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 26aacc73..c61ce957 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -1699,5 +1699,90 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 878c0150..c46c8779 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1775,5 +1775,89 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + [Fact] + public void ToTreeList() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 6625e85a..d21f844e 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1730,5 +1730,90 @@ WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 49f7cdb9..8d1b715c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1846,5 +1846,90 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" orm.Select().ForUpdate(true).Limit(1).ToList(); }); } + + [Fact] + public void ToTreeList() + { + var fsql = g.sqlite; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs deleted file mode 100644 index de67fa13..00000000 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ /dev/null @@ -1,111 +0,0 @@ -using FreeSql.DataAnnotations; -using FreeSql; -using System; -using System.Collections.Generic; -using Xunit; -using System.Linq; -using Newtonsoft.Json.Linq; -using NpgsqlTypes; -using Npgsql.LegacyPostgis; -using System.Linq.Expressions; -using System.Threading.Tasks; -using System.ComponentModel.DataAnnotations; -using System.Threading; -using System.Data.SqlClient; -using kwlib; -using System.Diagnostics; -using System.IO; -using System.Text; - -namespace FreeSql.Tests -{ - public class UnitTest4 - { - [Fact] - public void Test04() - { - g.sqlite.Delete().Where("1=1").ExecuteAffrows(); - var repo = g.sqlite.GetRepository(); - repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; - repo.DbContextOptions.NoneParameter = true; - repo.Insert(new VM_District_Child - { - Code = "100000", - Name = "中国", - Childs = new List(new[] { - new VM_District_Child - { - Code = "110000", - Name = "北京市", - Childs = new List(new[] { - new VM_District_Child{ Code="110100", Name = "北京市" }, - new VM_District_Child{ Code="110101", Name = "东城区" }, - }) - } - }) - }); - - var t1 = g.sqlite.Select() - .InnerJoin(a => a.ParentCode == a.Parent.Code) - .Where(a => a.Code == "110101") - .ToList(true); - Assert.Single(t1); - Assert.Equal("110101", t1[0].Code); - Assert.NotNull(t1[0].Parent); - Assert.Equal("110000", t1[0].Parent.Code); - - var t2 = g.sqlite.Select() - .InnerJoin(a => a.ParentCode == a.Parent.Code) - .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) - .Where(a => a.Code == "110101") - .ToList(true); - Assert.Single(t2); - Assert.Equal("110101", t2[0].Code); - Assert.NotNull(t2[0].Parent); - Assert.Equal("110000", t2[0].Parent.Code); - Assert.NotNull(t2[0].Parent.Parent); - Assert.Equal("100000", t2[0].Parent.Parent.Code); - - var t3 = g.sqlite.Select().ToTreeList(); - Assert.Single(t3); - Assert.Equal("100000", t3[0].Code); - Assert.Single(t3[0].Childs); - Assert.Equal("110000", t3[0].Childs[0].Code); - Assert.Equal(2, t3[0].Childs[0].Childs.Count); - Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); - Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - } - - [Table(Name = "D_District")] - public class BaseDistrict - { - [Column(IsPrimary = true, StringLength = 6)] - public string Code { get; set; } - - [Column(StringLength = 20, IsNullable = false)] - public string Name { get; set; } - - [Column(StringLength = 6)] - public virtual string ParentCode { get; set; } - } - - [Table(Name = "D_District", DisableSyncStructure = true)] - public class VM_District_Child : BaseDistrict - { - public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } - - [Navigate(nameof(ParentCode))] - public List Childs { get; set; } - } - - [Table(Name = "D_District", DisableSyncStructure = true)] - public class VM_District_Parent : BaseDistrict - { - public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } - - [Navigate(nameof(ParentCode))] - public VM_District_Parent Parent { get; set; } - } - } - -} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 77e5b1ba..12b3cc3e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2119,6 +2119,11 @@ UseSalve 时候的值 + + + 唯一标识 + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 @@ -2276,137 +2281,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2927,12 +2801,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3003,12 +2871,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3641,4 +3503,167 @@ + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 2cb27f7b..b520f690 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -32,6 +32,10 @@ namespace FreeSql /// UseSalve 时候的值 /// string[] SlaveConnectionStrings { get; } + /// + /// 唯一标识 + /// + Guid Identifier { get; } #region 事务 /// diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index c9c1c962..1d31f146 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -26,6 +26,7 @@ namespace FreeSql.Internal.CommonProvider public DataType DataType { get; } public string ConnectionString { get; } public string[] SlaveConnectionStrings { get; } + public Guid Identifier { get; } protected CommonUtils _util { get; set; } protected int slaveUnavailables = 0; private object slaveLock = new object(); @@ -36,6 +37,7 @@ namespace FreeSql.Internal.CommonProvider this.DataType = dataType; this.ConnectionString = connectionString; this.SlaveConnectionStrings = slaveConnectionStrings; + this.Identifier = Guid.NewGuid(); } void LoggerException(IObjectPool pool, PrepareCommandResult pc, Exception ex, DateTime dt, StringBuilder logtxt, bool isThrowException = true) diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index 9406b549..f53e1791 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -101,7 +101,7 @@ namespace FreeSql.Odbc.Default } finally { - FreeSqlOdbcGlobalExtensions._dicOdbcAdater.TryRemove(this as IFreeSql, out var tryada); + FreeSqlOdbcGlobalExtensions._dicOdbcAdater.TryRemove(Ado.Identifier, out var tryada); } } } @@ -110,7 +110,7 @@ namespace FreeSql.Odbc.Default partial class FreeSqlOdbcGlobalExtensions { internal static OdbcAdapter DefaultOdbcAdapter = new OdbcAdapter(); - internal static ConcurrentDictionary _dicOdbcAdater = new ConcurrentDictionary(); - public static void SetOdbcAdapter(this IFreeSql that, OdbcAdapter adapter) => _dicOdbcAdater.AddOrUpdate(that, adapter, (fsql, old) => adapter); - internal static OdbcAdapter GetOdbcAdapter(this IFreeSql that) => _dicOdbcAdater.TryGetValue(that, out var tryada) ? tryada : DefaultOdbcAdapter; + internal static ConcurrentDictionary _dicOdbcAdater = new ConcurrentDictionary(); + public static void SetOdbcAdapter(this IFreeSql that, OdbcAdapter adapter) => _dicOdbcAdater.AddOrUpdate(that.Ado.Identifier, adapter, (fsql, old) => adapter); + internal static OdbcAdapter GetOdbcAdapter(this IFreeSql that) => _dicOdbcAdater.TryGetValue(that.Ado.Identifier, out var tryada) ? tryada : DefaultOdbcAdapter; } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index ccb2d920..459f96f5 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -249,7 +249,7 @@ namespace FreeSql.SqlServer.Curd #endregion public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { - if (FreeSqlSqlServerGlobalExtensions._dicSetGlobalSelectWithLock.TryGetValue(orm, out var tryval)) + if (FreeSqlSqlServerGlobalExtensions._dicSetGlobalSelectWithLock.TryGetValue(orm.Ado.Identifier, out var tryval)) this.WithLock(tryval.Item1, tryval.Item2); } public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 6315b9fe..5fc21290 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -39,10 +39,10 @@ public static partial class FreeSqlSqlServerGlobalExtensions public static IFreeSql SetGlobalSelectWithLock(this IFreeSql that, SqlServerLock lockType, Dictionary rule) { var value = NaviteTuple.Create(lockType, rule); - _dicSetGlobalSelectWithLock.AddOrUpdate(that, value, (_, __) => value); + _dicSetGlobalSelectWithLock.AddOrUpdate(that.Ado.Identifier, value, (_, __) => value); return that; } - internal static ConcurrentDictionary>> _dicSetGlobalSelectWithLock = new ConcurrentDictionary>>(); + internal static ConcurrentDictionary>> _dicSetGlobalSelectWithLock = new ConcurrentDictionary>>(); #region ExecuteSqlBulkCopy /// From d97dc3383cde5f645b95db80e6b9be966c47bccf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Apr 2020 13:13:57 +0800 Subject: [PATCH 0556/1029] add ExpressionCall tests #269 --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 + FreeSql.Tests/FreeSql.Tests/Issues/269.cs | 67 + FreeSql/FreeSql.xml | 7377 +++++++++++---------- FreeSql/Internal/CommonExpression.cs | 4 +- 4 files changed, 3794 insertions(+), 3670 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/269.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 63db6c75..eacd506b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -121,6 +121,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -215,6 +222,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 注意:IFreeSql 属于顶级对象,事务无法自动传递。 diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/269.cs b/FreeSql.Tests/FreeSql.Tests/Issues/269.cs new file mode 100644 index 00000000..93e6165c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/269.cs @@ -0,0 +1,67 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using System.Data.SqlClient; +using kwlib; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace FreeSql.Tests.Issues +{ + public class _269 + { + [Fact] + public void ToSql() + { + var fsql = g.sqlite; + + var sql1 = fsql.Select() + .Where(a => + DbFunc222.FuncExpression("ISNULL", a.UseMode, EDIUseMode.Both) == EDIUseMode.Both) + .ToSql(); //这么写报错:ExpressionTree 转换类型错误,值(a.[EDI_USE_MODE]),类型(System.String),目标类型(System.Nullable`1[EDIUseMode]),Requested value 'a.[EDI_USE_MODE]' was not found. + var sql2 = fsql.Select() + .Where(a => + DbFunc222.FuncExpression("ISNULL", (int)a.UseMode, (int)EDIUseMode.Both) == (int)EDIUseMode.Both) + .ToSql(); //这么写就不报错 + + } + + public enum EDIUseMode : byte + { + OutPut = 1, + Import = 2, + Both = 3, + } + [Table(Name = "EDI222")] + public class Edi + { + [Column(Name = "EDI_ID")] public long Id { get; set; } + [Column(Name = "EDI_USE_MODE")] public EDIUseMode? UseMode { get; set; } + } + } + + [ExpressionCall] + public static class DbFunc222 + { + static ThreadLocal context = new ThreadLocal(); + //自定义数据库方法 + public static TOut FuncExpression(string func, T1 p1, T2 p2) + { + var up = context.Value; + var values = up.ParsedContent.Values.ToArray(); + context.Value.Result = $"{func}({values[1]}, {values[2]})"; + return default; + } + } +} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 12b3cc3e..7783e259 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1,3669 +1,3708 @@ - - - - FreeSql - - - - - 数据库列名 - - - - - 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - - - - - 数据库类型,如: varchar(255) - 字符串长度,可使用特性 [MaxLength(255)] - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 忽略此列,不迁移、不插入 - - - - - 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) - - - - - 类型映射,除了可做基本的类型映射外,特别介绍的功能: - 1、将 enum 属性映射成 typeof(string) - 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap - - - - - 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: - - >0时排前面,1,2,3... - - =0时排中间(默认) - - <0时排后面,...-3,-2,-1 - - - - - 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 - - - - - 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 - - - - - 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 - - - - - 设置长度,针对 string 类型避免 DbType 的繁琐设置 - 提示:也可以使用 [MaxLength(100)] - --- - StringLength = 100 时,对应 DbType: - MySql -> varchar(100) - SqlServer -> nvarchar(100) - PostgreSQL -> varchar(100) - Oracle -> nvarchar2(100) - Sqlite -> nvarchar(100) - --- - StringLength = -1 时,对应 DbType: - MySql -> text - SqlServer -> nvarchar(max) - PostgreSQL -> text - Oracle -> nvarchar2(4000) - Sqlite -> text - - - - - 执行 Insert 方法时使用此值 - 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 - - - - - 数据库列名 - - - - - 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - - - - - 数据库类型,如: varchar(255) - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 忽略此列,不迁移、不插入 - - - - - 乐观锁 - - - - - 类型映射,比如:可将 enum 属性映射成 typeof(string) - - - - - - - 创建表时字段位置,规则如下: - - >0时排前面 - - =0时排中间(默认) - - <0时排后面 - - - - - - - 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 - - - - - - - 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 - - - - - - - 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 - - - - - - - 设置长度,针对 string 类型避免 DbType 的繁琐设置 - --- - StringLength = 100 时,对应 DbType: - MySql -> varchar(100) - SqlServer -> nvarchar(100) - PostgreSQL -> varchar(100) - Oracle -> nvarchar2(100) - Sqlite -> nvarchar(100) - --- - StringLength = -1 时,对应 DbType: - MySql -> text - SqlServer -> nvarchar(max) - PostgreSQL -> text - Oracle -> nvarchar2(4000) - Sqlite -> text - - - - - 执行 Insert 方法时使用此值 - 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 - - - - - - - 自定义表达式函数解析 - 注意:请使用静态方法、或者在类上标记 - - - - - 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 - - - - - 数据库类型,可用于适配多种数据库环境 - - - - - 已解析的表达式中参数内容 - - - - - 表达式原始值 - - - - - 主对象的参数化对象,可重塑其属性 - - - - - 可附加参数化对象 - 注意:本属性只有 Where 的表达式解析才可用 - - - - - 将 c# 对象转换为 SQL - - - - - 返回表达式函数表示的 SQL 字符串 - - - - - 获取实体元数据 - - - - - - - 解析表达式 - - - - - - - 索引名 - - - - - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - - - - - 是否唯一 - - - - - 手工绑定 OneToMany、ManyToOne 导航关系 - - - - - 手工绑定 ManyToMany 导航关系 - - - - - 主键名 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 导航关系Fluent,与 NavigateAttribute 对应 - - - - 多对多关系的中间实体类型 - - - - - 设置实体的索引 - - 索引名 - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 导航关系Fluent,与 NavigateAttribute 对应 - - - - - 多对多关系的中间实体类型 - - - - - 设置实体的索引 - - 索引名 - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - - 所属表 - - - - - 列名 - - - - - 映射到 C# 类型 - - - - - 数据库枚举类型int值 - - - - - 数据库类型,字符串,varchar - - - - - 数据库类型,字符串,varchar(255) - - - - - 最大长度 - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 备注 - - - - - 枚举类型标识 - - - - - 枚举项 - - - - - 唯一标识 - - - - - SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 - - - - - 表名 - - - - - 表备注,SqlServer下是扩展属性 MS_Description - - - - - 表/视图 - - - - - 列 - - - - - 自增列 - - - - - 主键/组合 - - - - - 唯一键/组合 - - - - - 索引/组合 - - - - - 外键 - - - - - 类型标识 - - - - - 枚举项 - - - - - 通用的 Odbc 实现,只能做基本的 Crud 操作 - 不支持实体结构迁移、不支持分页(只能 Take 查询) - - 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 - 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 - - 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 - - - - - 武汉达梦数据库有限公司 - - - - - Microsoft Office Access 是由微软发布的关联式数据库管理系统 - - - - - 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null - - - - - 当Guid无值时,会生成有序的新值 - - - - - - 获取实体的主键值,多个主键返回数组 - - - - - - - - - 获取实体的属性值 - - - - - - - - - - 获取实体的所有数据,以 (1, 2, xxx) 的形式 - - - - - - - - - 使用新实体的值,复盖旧实体的值 - - - - - 使用新实体的主键值,复盖旧实体的主键值 - - - - - 设置实体中主键内的自增字段值(若存在) - - - - - - - - - 获取实体中主键内的自增字段值(若存在) - - - - - - - - 清除实体的主键值,将自增、Guid类型的主键值清除 - - - - - - - - 清除实体的主键值,将自增、Guid类型的主键值清除 - - - - - - - - 对比两个实体值,返回相同/或不相同的列名 - - - - - - - - - - - 设置实体中某属性的数值增加指定的值 - - - - - - - - - - 设置实体中某属性的值 - - - - - - - - - - 缓存执行 IUpdate.Set - - - - - - - - - 使用连接串(推荐) - - 数据库类型 - 数据库连接串 - 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 - - - - - 使用从数据库,支持多个 - - 从数据库连接串 - - - - - 使用自定义数据库连接对象(放弃内置对象连接池技术) - - 数据库类型 - 数据库连接对象创建器 - 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - true:运行时检查自动同步结构, false:不同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - - - 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() - - - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - - - 监视数据库命令对象 - - 执行前 - 执行后,可监视执行性能 - - - - - 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) - 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] - - - - - - - 转小写同步结构 - - true:转小写, false:不转 - - - - - 转大写同步结构 - - true:转大写, false:不转 - - - - - 自动转换实体属性名称 Entity Property -> Db Filed - - *不会覆盖 [Column] 特性设置的Name - - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - lambda表达式条件,仅支持实体基础成员(不包含导航对象) - 若想使用导航对象,请使用 ISelect.ToDelete() 方法 - - lambda表达式条件 - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - - sql语法条件 - 参数 - - - - - 传入实体,将主键作为条件 - - 实体 - - - - - 传入实体集合,将主键作为条件 - - 实体集合 - - - - - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回被删除的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 追加准备插入的实体 - - 实体 - - - - - 追加准备插入的实体 - - 实体 - - - - - 追加准备插入的实体集合 - - 实体集合 - - - - - 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 指定可插入自增字段 - - - - - - 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - - 是否不使用参数化 - - - - - 批量执行选项设置,一般不需要使用该方法 - 各数据库 values, parameters 限制不一样,默认设置: - MySql 5000 3000 - PostgreSQL 5000 3000 - SqlServer 1000 2100 - Oracle 500 999 - Sqlite 5000 999 - 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - - 指定根据 values 数量拆分执行 - 指定根据 parameters 数量拆分执行 - 是否自动开启事务 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回自增值 - 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] - - - - - - 执行SQL语句,返回插入后的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 返回 DataTable 以便做 BulkCopy 数据做准备 - 此方法会处理: - 类型、表名、字段名映射 - IgnoreColumns、InsertColumns - - - - - - 自动产生 as1, as2, as3 .... 字段别名 - 这种方法可以最大程度防止多表,存在相同字段的问题 - - - - - 使用属性名作为字段别名 - - - - - 指定事务对象 - - - - - - - 指定连接对象 - - - - - - - 审核或跟踪 ToList 即将返回的数据 - - - - - - - 执行SQL查询,返回 DataTable - - - - - - 以字典的形式返回查询结果 - 注意:字典的特点会导致返回的数据无序 - - - - - - - - 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 - 注意: - 1、ToList(a => a) 可以返回 a 所有实体 - 2、ToList(a => new { a }) 这样也可以 - 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 - 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() - - false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - - - - - 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 - - 数据块的大小 - 处理数据块 - false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - - - - 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 - - - - - - - - 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - - - - - - 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - - - - - - 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: - fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() - 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: - DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) - 复杂删除使用该方案的好处: - 1、删除前可预览测试数据,防止错误删除操作; - 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); - - - - - - 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: - fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() - 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: - UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) - 复杂更新使用该方案的好处: - 1、更新前可预览测试数据,防止错误更新操作; - 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); - - - - - - 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; - 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 - 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); - select * from (SELECT a."Id" as1 FROM "table_1" a) ftb - UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb - UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb - 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() - - - - - - - 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 - 如:select.AsAlias((_, old) => $"{old} with(lock)") - - - - - - - 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - 指定字段 - - - - - 执行SQL查询,是否有记录 - - - - - - 查询的记录数量 - - - - - - 查询的记录数量,以参数out形式返回 - - 返回的变量 - - - - - 指定从主库查询(默认查询从库) - - - - - - 左联查询,使用导航属性自动生成SQL - - 表达式 - - - - - 联接查询,使用导航属性自动生成SQL - - 表达式 - - - - - 右联查询,使用导航属性自动生成SQL - - 表达式 - - - - - 左联查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 联接查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 右联查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - - sql语法条件 - 参数 - - - - - 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - - sql语法条件 - 参数 - - - - - 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - - sql语法条件 - 参数 - - - - - 在 JOIN 位置插入 SQL 内容 - 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") - - - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - - sql语法条件 - 参数 - - - - - 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) - - true 时生效 - sql语法条件 - 参数 - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 排他更新锁 - 注意:务必在开启事务后使用该功能 - MySql: for update - SqlServer: With(UpdLock, RowLock, NoWait) - PostgreSQL: for update nowait - Oracle: for update nowait - Sqlite: 无效果 - 达梦: for update nowait - - noawait - - - - - 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) - - sql语法 - 参数 - - - - - 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) - - sql语法条件 - 参数 - - - - - 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) - - sql语法 - 参数 - - - - - 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) - - true 时生效 - sql语法 - 参数 - - - - - 查询向后偏移行数 - - - - - - - 查询向后偏移行数 - - 行数 - - - - - 查询多少条数据 - - - - - - - 查询多少条数据 - - - - - - - 分页 - - 第几页 - 每页多少 - - - - - 查询数据前,去重 - - .Distinct().ToList(x => x.GroupName) 对指定字段去重 - - - .Distinct().ToList() 对整个查询去重 - - - - - - - 执行SQL查询,是否有记录 - - lambda表达式 - - - - - 执行SQL查询,返回 DataTable - - - - - - 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 - - - - - - - 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 - - - - - - - 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 - - - - - - - 返回即将执行的SQL语句 - - 返回类型 - 选择列 - 字段别名 - - - - - 执行SQL查询,返回指定字段的聚合结果 - - - - - - - - 求和 - - 返回类型 - 列 - - - - - 最小值 - - 返回类型 - 列 - - - - - 最大值 - - 返回类型 - 列 - - - - - 平均值 - - 返回类型 - 列 - - - - - 指定别名 - - 别名 - - - - - 多表查询 - - - - - - - - 多表查询 - - - - - - - - - 多表查询 - - - - - - - - - - 多表查询 - - - - - - - - - - - 多表查询 - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - - lambda表达式 - - - - - 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - - true 时生效 - lambda表达式 - - - - - 多表条件查询 - - - lambda表达式 - - - - - 多表条件查询 - - - lambda表达式 - - - - - 多表条件查询 - - - - lambda表达式 - - - - - 多表条件查询 - - - - - lambda表达式 - - - - - 多表条件查询 - - - - - lambda表达式 - - - - - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 多表查询时,该方法标记后,表达式条件将对所有表进行附加 - - 例如:软删除、租户,每个表都给条件,挺麻烦的 - - fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) - - 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) - - 当其中的实体可附加表达式才会进行,表越多时收益越大 - - - - - - - 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) - - - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列排序,OrderBy(true, a => a.Time) - - - true 时生效 - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 按列倒向排序,OrderByDescending(true, a => a.Time) - - true 时生效 - 列 - - - - - 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 - - - 选择一个导航属性 - - - - - 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 实现 select .. from ( select ... from t ) a 这样的功能 - 使用 AsTable 方法也可以达到效果 - - SQL语句 - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - - lambda表达式 - - - - - 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - - true 时生效 - lambda表达式 - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 按聚合条件过滤,Where(a => a.Count() > 10) - - lambda表达式 - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - - 返回类型 - 选择列 - - - - - 【linq to sql】专用方法,不建议直接使用 - - - - - 返回即将执行的SQL语句 - - 返回类型 - 选择列 - - - - - 返回即将执行的SQL语句 - - 指定字段 - - - - - 查询向后偏移行数 - - - - - - - 查询向后偏移行数 - - 行数 - - - - - 查询多少条数据 - - - - - - - 查询多少条数据 - - - - - - - 分页 - - 第几页 - 每页多少 - - - - - 查询的记录数量 - - - - - - 查询的记录数量,以参数out形式返回 - - 返回的变量 - - - - - 分组的数据 - - - - - 记录总数 - - - - - - 求和 - - - - - - - - 平均值 - - - - - - - - 最大值 - - - - - - - - 最小值 - - - - - - - 所有元素 - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - - 是否不使用参数化 - - - - - 批量执行选项设置,一般不需要使用该方法 - 各数据库 rows, parameters 限制不一样,默认设置: - MySql 500 3000 - PostgreSQL 500 3000 - SqlServer 500 2100 - Oracle 200 999 - Sqlite 200 999 - 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - - 指定根据 rows 数量拆分执行 - 指定根据 parameters 数量拆分执行 - 是否自动开启事务 - - - - - 更新数据,设置更新的实体 - - 实体 - - - - - 更新数据,设置更新的实体集合 - - 实体集合 - - - - - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 忽略的列 - - 属性名,或者字段名 - - - - - 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 指定的列 - - 属性名,或者字段名 - - - - - 设置列的新值,Set(a => a.Name, "newvalue") - - - lambda选择列 - 新值 - - - - - 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 - - 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' - - - - - - - - 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) - - sql语法 - 参数 - - - - - 设置更新的列 - - SetDto(new { title = "xxx", clicks = 2 }) - - SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) - - dto 或 Dictionary<string, object> - - - - - lambda表达式条件,仅支持实体基础成员(不包含导航对象) - 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 - - lambda表达式条件 - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - - sql语法条件 - 参数 - - - - - 传入实体,将主键作为条件 - - 实体 - - - - - 传入实体集合,将主键作为条件 - - 实体集合 - - - - - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回更新后的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 主库连接池 - - - - - 从库连接池 - - - - - 数据库类型 - - - - - UseConnectionString 时候的值 - - - - - UseSalve 时候的值 - - - - - 唯一标识 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 当前线程的事务 - - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) - - - - - - - 查询 - - - - - - - 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<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 }) - - - - - - - - - 可自定义解析表达式 - - - - - 自定义实体的配置,方便和多个 ORM 共同使用 - - - - - 自定义实体的属性配置,方便和多个 ORM 共同使用 - - - - - 增删查改,执行命令之前触发 - - - - - 增删查改,执行命令完成后触发 - - - - - CodeFirst迁移,执行之前触发 - - - - - CodeFirst迁移,执行完成触发 - - - - - Insert/Update自动值处理 - - - - - 监视数据库命令对象(执行前,调试) - - - - - 监视数据库命令对象(执行后,用于监视执行性能) - - - - - 跟踪开始 - - - - - 跟踪结束 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 - - - - - 备注 - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构,适用 PostgreSQL - - - - - 转大写同步结构,适用 Oracle/达梦 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - - - - - - 将实体类型集合与数据库对比,返回DDL语句 - - 实体类型 - - - - - 将实体类型与数据库对比,返回DDL语句(指定表名) - - 实体类型 - 指定表名对比 - - - - - 同步实体类型到数据库 - - - - - - 同步实体类型集合到数据库 - - - - - - 同步实体类型到数据库(指定表名) - - 实体类型 - 指定表名对比 - - - - 根据 System.Type 获取数据库信息 - - - - - - - 在外部配置实体的特性 - - - - - - - - 在外部配置实体的特性 - - - - - - - - 获取在外部配置实体的特性 - - - 未使用ConfigEntity配置时,返回null - - - - 获取实体类核心配置 - - - - - - - 获取所有数据库 - - - - - - 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 - - - - - - - 获取数据库枚举类型int值 - - - - - - - 获取c#转换,(int)、(long) - - - - - - - 获取c#值 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 中间表,多对多 - - - - - 是否可用 - - - - - 不可用错误 - - - - - 不可用时间 - - - - - 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 - - - 由【可用】变成【不可用】时返回true,否则返回false - - - - 统计对象池中的对象 - - - - - 统计对象池中的对象(完整) - - - - - 获取资源 - - 超时 - - - - - 使用完毕后,归还资源 - - 对象 - 是否重新创建 - - - - 名称 - - - - - 池容量 - - - - - 默认获取超时设置 - - - - - 空闲时间,获取时若超出,则重新创建 - - - - - 异步获取排队队列大小,小于等于0不生效 - - - - - 获取超时后,是否抛出异常 - - - - - 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 - - - - - 后台定时检查可用性间隔秒数 - - - - - 对象池的对象被创建时 - - 返回被创建的对象 - - - - 销毁对象 - - 资源对象 - - - - 从对象池获取对象超时的时候触发,通过该方法统计 - - - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - - - - 归还对象给对象池的时候触发 - - 资源对象 - - - - 检查可用性 - - 资源对象 - - - - - 事件:可用时触发 - - - - - 事件:不可用时触发 - - - - - 所属对象池 - - - - - 在对象池中的唯一标识 - - - - - 资源对象 - - - - - 被获取的总次数 - - - - 最后获取时的时间 - - - - 最后归还时的时间 - - - - - 创建时间 - - - - - 最后获取时的线程id - - - - - 最后归还时的线程id - - - - - 重置 Value 值 - - - - - 对象池管理类 - - 对象类型 - - - - 后台定时检查可用性 - - - - - - 创建对象池 - - 池大小 - 池内对象的创建委托 - 获取池内对象成功后,进行使用前操作 - - - - 创建对象池 - - 策略 - - - - 获取可用资源,或创建资源 - - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - C#: that >= between && that <= and - SQL: that BETWEEN between AND and - - - - - - - - - 注意:这个方法和 Between 有细微区别 - C#: that >= start && that < end - SQL: that >= start and that < end - - - - - - - - - 获取 Type 的原始 c# 文本表示 - - - - - - - 测量两个经纬度的距离,返回单位:米 - - 经纬坐标1 - 经纬坐标2 - 返回距离(单位:米) - - - - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 - - - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 - 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 查询数据,加工为树型 List 返回 - 注意:实体需要配置父子导航属性 - - - - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - + + + + FreeSql + + + + + 数据库列名 + + + + + 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + + + + + 数据库类型,如: varchar(255) + 字符串长度,可使用特性 [MaxLength(255)] + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 忽略此列,不迁移、不插入 + + + + + 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) + + + + + 类型映射,除了可做基本的类型映射外,特别介绍的功能: + 1、将 enum 属性映射成 typeof(string) + 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap + + + + + 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: + + >0时排前面,1,2,3... + + =0时排中间(默认) + + <0时排后面,...-3,-2,-1 + + + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + 提示:也可以使用 [MaxLength(100)] + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + + 数据库列名 + + + + + 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + + + + + 数据库类型,如: varchar(255) + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 忽略此列,不迁移、不插入 + + + + + 乐观锁 + + + + + 类型映射,比如:可将 enum 属性映射成 typeof(string) + + + + + + + 创建表时字段位置,规则如下: + + >0时排前面 + + =0时排中间(默认) + + <0时排后面 + + + + + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + + + + 自定义表达式函数解析 + 注意:请使用静态方法、或者在类上标记 + + + + + 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 + + + + + 数据库类型,可用于适配多种数据库环境 + + + + + 已解析的表达式中参数内容 + + + + + 表达式原始值 + + + + + 主对象的参数化对象,可重塑其属性 + + + + + 可附加参数化对象 + 注意:本属性只有 Where 的表达式解析才可用 + + + + + 将 c# 对象转换为 SQL + + + + + 返回表达式函数表示的 SQL 字符串 + + + + + 获取实体元数据 + + + + + + + 解析表达式 + + + + + + + 索引名 + + + + + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + + 是否唯一 + + + + + 手工绑定 OneToMany、ManyToOne 导航关系 + + + + + 手工绑定 ManyToMany 导航关系 + + + + + 主键名 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + 多对多关系的中间实体类型 + + + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + + 多对多关系的中间实体类型 + + + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + + 所属表 + + + + + 列名 + + + + + 映射到 C# 类型 + + + + + 数据库枚举类型int值 + + + + + 数据库类型,字符串,varchar + + + + + 数据库类型,字符串,varchar(255) + + + + + 最大长度 + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 备注 + + + + + 枚举类型标识 + + + + + 枚举项 + + + + + 唯一标识 + + + + + SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 + + + + + 表名 + + + + + 表备注,SqlServer下是扩展属性 MS_Description + + + + + 表/视图 + + + + + 列 + + + + + 自增列 + + + + + 主键/组合 + + + + + 唯一键/组合 + + + + + 索引/组合 + + + + + 外键 + + + + + 类型标识 + + + + + 枚举项 + + + + + 通用的 Odbc 实现,只能做基本的 Crud 操作 + 不支持实体结构迁移、不支持分页(只能 Take 查询) + + 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 + 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 + + 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 + + + + + 武汉达梦数据库有限公司 + + + + + Microsoft Office Access 是由微软发布的关联式数据库管理系统 + + + + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null + + + + + 当Guid无值时,会生成有序的新值 + + + + + + 获取实体的主键值,多个主键返回数组 + + + + + + + + + 获取实体的属性值 + + + + + + + + + + 获取实体的所有数据,以 (1, 2, xxx) 的形式 + + + + + + + + + 使用新实体的值,复盖旧实体的值 + + + + + 使用新实体的主键值,复盖旧实体的主键值 + + + + + 设置实体中主键内的自增字段值(若存在) + + + + + + + + + 获取实体中主键内的自增字段值(若存在) + + + + + + + + 清除实体的主键值,将自增、Guid类型的主键值清除 + + + + + + + + 清除实体的主键值,将自增、Guid类型的主键值清除 + + + + + + + + 对比两个实体值,返回相同/或不相同的列名 + + + + + + + + + + + 设置实体中某属性的数值增加指定的值 + + + + + + + + + + 设置实体中某属性的值 + + + + + + + + + + 缓存执行 IUpdate.Set + + + + + + + + + 使用连接串(推荐) + + 数据库类型 + 数据库连接串 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + + + + 使用从数据库,支持多个 + + 从数据库连接串 + + + + + 使用自定义数据库连接对象(放弃内置对象连接池技术) + + 数据库类型 + 数据库连接对象创建器 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + true:运行时检查自动同步结构, false:不同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + + + 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() + + + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + + + 监视数据库命令对象 + + 执行前 + 执行后,可监视执行性能 + + + + + 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) + 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] + + + + + + + 转小写同步结构 + + true:转小写, false:不转 + + + + + 转大写同步结构 + + true:转大写, false:不转 + + + + + 自动转换实体属性名称 Entity Property -> Db Filed + + *不会覆盖 [Column] 特性设置的Name + + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToDelete() 方法 + + lambda表达式条件 + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + + sql语法条件 + 参数 + + + + + 传入实体,将主键作为条件 + + 实体 + + + + + 传入实体集合,将主键作为条件 + + 实体集合 + + + + + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回被删除的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 追加准备插入的实体 + + 实体 + + + + + 追加准备插入的实体 + + 实体 + + + + + 追加准备插入的实体集合 + + 实体集合 + + + + + 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 指定可插入自增字段 + + + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + + 是否不使用参数化 + + + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 values, parameters 限制不一样,默认设置: + MySql 5000 3000 + PostgreSQL 5000 3000 + SqlServer 1000 2100 + Oracle 500 999 + Sqlite 5000 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 values 数量拆分执行 + 指定根据 parameters 数量拆分执行 + 是否自动开启事务 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回自增值 + 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] + + + + + + 执行SQL语句,返回插入后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 返回 DataTable 以便做 BulkCopy 数据做准备 + 此方法会处理: + 类型、表名、字段名映射 + IgnoreColumns、InsertColumns + + + + + + 自动产生 as1, as2, as3 .... 字段别名 + 这种方法可以最大程度防止多表,存在相同字段的问题 + + + + + 使用属性名作为字段别名 + + + + + 指定事务对象 + + + + + + + 指定连接对象 + + + + + + + 审核或跟踪 ToList 即将返回的数据 + + + + + + + 执行SQL查询,返回 DataTable + + + + + + 以字典的形式返回查询结果 + 注意:字典的特点会导致返回的数据无序 + + + + + + + + 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + 注意: + 1、ToList(a => a) 可以返回 a 所有实体 + 2、ToList(a => new { a }) 这样也可以 + 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 + 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() + + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + + + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + + 数据块的大小 + 处理数据块 + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + + 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 + + + + + + + + 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + + + + + + 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + + + + + + 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: + DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂删除使用该方案的好处: + 1、删除前可预览测试数据,防止错误删除操作; + 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); + + + + + + 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: + UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂更新使用该方案的好处: + 1、更新前可预览测试数据,防止错误更新操作; + 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); + + + + + + 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 + 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); + select * from (SELECT a."Id" as1 FROM "table_1" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb + 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() + + + + + + + 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 + 如:select.AsAlias((_, old) => $"{old} with(lock)") + + + + + + + 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + 指定字段 + + + + + 执行SQL查询,是否有记录 + + + + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + + + + 指定从主库查询(默认查询从库) + + + + + + 左联查询,使用导航属性自动生成SQL + + 表达式 + + + + + 联接查询,使用导航属性自动生成SQL + + 表达式 + + + + + 右联查询,使用导航属性自动生成SQL + + 表达式 + + + + + 左联查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 联接查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 右联查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + + sql语法条件 + 参数 + + + + + 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + + sql语法条件 + 参数 + + + + + 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + + sql语法条件 + 参数 + + + + + 在 JOIN 位置插入 SQL 内容 + 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") + + + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + + sql语法条件 + 参数 + + + + + 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + + true 时生效 + sql语法条件 + 参数 + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 排他更新锁 + 注意:务必在开启事务后使用该功能 + MySql: for update + SqlServer: With(UpdLock, RowLock, NoWait) + PostgreSQL: for update nowait + Oracle: for update nowait + Sqlite: 无效果 + 达梦: for update nowait + + noawait + + + + + 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + + sql语法 + 参数 + + + + + 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + + sql语法条件 + 参数 + + + + + 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + + sql语法 + 参数 + + + + + 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + + true 时生效 + sql语法 + 参数 + + + + + 查询向后偏移行数 + + + + + + + 查询向后偏移行数 + + 行数 + + + + + 查询多少条数据 + + + + + + + 查询多少条数据 + + + + + + + 分页 + + 第几页 + 每页多少 + + + + + 查询数据前,去重 + + .Distinct().ToList(x => x.GroupName) 对指定字段去重 + + + .Distinct().ToList() 对整个查询去重 + + + + + + + 执行SQL查询,是否有记录 + + lambda表达式 + + + + + 执行SQL查询,返回 DataTable + + + + + + 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 + + + + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + + + + 返回即将执行的SQL语句 + + 返回类型 + 选择列 + 字段别名 + + + + + 执行SQL查询,返回指定字段的聚合结果 + + + + + + + + 求和 + + 返回类型 + 列 + + + + + 最小值 + + 返回类型 + 列 + + + + + 最大值 + + 返回类型 + 列 + + + + + 平均值 + + 返回类型 + 列 + + + + + 指定别名 + + 别名 + + + + + 多表查询 + + + + + + + + 多表查询 + + + + + + + + + 多表查询 + + + + + + + + + + 多表查询 + + + + + + + + + + + 多表查询 + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 多表条件查询 + + + lambda表达式 + + + + + 多表条件查询 + + + lambda表达式 + + + + + 多表条件查询 + + + + lambda表达式 + + + + + 多表条件查询 + + + + + lambda表达式 + + + + + 多表条件查询 + + + + + lambda表达式 + + + + + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 多表查询时,该方法标记后,表达式条件将对所有表进行附加 + + 例如:软删除、租户,每个表都给条件,挺麻烦的 + + fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) + + 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) + + 当其中的实体可附加表达式才会进行,表越多时收益越大 + + + + + + + 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) + + + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列排序,OrderBy(true, a => a.Time) + + + true 时生效 + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 按列倒向排序,OrderByDescending(true, a => a.Time) + + true 时生效 + 列 + + + + + 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 + + + 选择一个导航属性 + + + + + 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 实现 select .. from ( select ... from t ) a 这样的功能 + 使用 AsTable 方法也可以达到效果 + + SQL语句 + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 按聚合条件过滤,Where(a => a.Count() > 10) + + lambda表达式 + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + + 返回类型 + 选择列 + + + + + 【linq to sql】专用方法,不建议直接使用 + + + + + 返回即将执行的SQL语句 + + 返回类型 + 选择列 + + + + + 返回即将执行的SQL语句 + + 指定字段 + + + + + 查询向后偏移行数 + + + + + + + 查询向后偏移行数 + + 行数 + + + + + 查询多少条数据 + + + + + + + 查询多少条数据 + + + + + + + 分页 + + 第几页 + 每页多少 + + + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + + + + 分组的数据 + + + + + 记录总数 + + + + + + 求和 + + + + + + + + 平均值 + + + + + + + + 最大值 + + + + + + + + 最小值 + + + + + + + 所有元素 + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + + 是否不使用参数化 + + + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 rows, parameters 限制不一样,默认设置: + MySql 500 3000 + PostgreSQL 500 3000 + SqlServer 500 2100 + Oracle 200 999 + Sqlite 200 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 rows 数量拆分执行 + 指定根据 parameters 数量拆分执行 + 是否自动开启事务 + + + + + 更新数据,设置更新的实体 + + 实体 + + + + + 更新数据,设置更新的实体集合 + + 实体集合 + + + + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 忽略的列 + + 属性名,或者字段名 + + + + + 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 指定的列 + + 属性名,或者字段名 + + + + + 设置列的新值,Set(a => a.Name, "newvalue") + + + lambda选择列 + 新值 + + + + + 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + + 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + + + + + + + + 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + + sql语法 + 参数 + + + + + 设置更新的列 + + SetDto(new { title = "xxx", clicks = 2 }) + + SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + + dto 或 Dictionary<string, object> + + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 + + lambda表达式条件 + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + + sql语法条件 + 参数 + + + + + 传入实体,将主键作为条件 + + 实体 + + + + + 传入实体集合,将主键作为条件 + + 实体集合 + + + + + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回更新后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 主库连接池 + + + + + 从库连接池 + + + + + 数据库类型 + + + + + UseConnectionString 时候的值 + + + + + UseSalve 时候的值 + + + + + 唯一标识 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 当前线程的事务 + + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + + + + + + + 查询 + + + + + + + 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<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 }) + + + + + + + + + 可自定义解析表达式 + + + + + 自定义实体的配置,方便和多个 ORM 共同使用 + + + + + 自定义实体的属性配置,方便和多个 ORM 共同使用 + + + + + 增删查改,执行命令之前触发 + + + + + 增删查改,执行命令完成后触发 + + + + + CodeFirst迁移,执行之前触发 + + + + + CodeFirst迁移,执行完成触发 + + + + + Insert/Update自动值处理 + + + + + 监视数据库命令对象(执行前,调试) + + + + + 监视数据库命令对象(执行后,用于监视执行性能) + + + + + 跟踪开始 + + + + + 跟踪结束 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 + + + + + 备注 + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构,适用 PostgreSQL + + + + + 转大写同步结构,适用 Oracle/达梦 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + 将实体类型与数据库对比,返回DDL语句 + + + + + + + 将实体类型集合与数据库对比,返回DDL语句 + + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 + + + + + 同步实体类型到数据库 + + + + + + 同步实体类型集合到数据库 + + + + + + 同步实体类型到数据库(指定表名) + + 实体类型 + 指定表名对比 + + + + 根据 System.Type 获取数据库信息 + + + + + + + 在外部配置实体的特性 + + + + + + + + 在外部配置实体的特性 + + + + + + + + 获取在外部配置实体的特性 + + + 未使用ConfigEntity配置时,返回null + + + + 获取实体类核心配置 + + + + + + + 获取所有数据库 + + + + + + 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 + + + + + + + 获取数据库枚举类型int值 + + + + + + + 获取c#转换,(int)、(long) + + + + + + + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 中间表,多对多 + + + + + 是否可用 + + + + + 不可用错误 + + + + + 不可用时间 + + + + + 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + + + 由【可用】变成【不可用】时返回true,否则返回false + + + + 统计对象池中的对象 + + + + + 统计对象池中的对象(完整) + + + + + 获取资源 + + 超时 + + + + + 使用完毕后,归还资源 + + 对象 + 是否重新创建 + + + + 名称 + + + + + 池容量 + + + + + 默认获取超时设置 + + + + + 空闲时间,获取时若超出,则重新创建 + + + + + 异步获取排队队列大小,小于等于0不生效 + + + + + 获取超时后,是否抛出异常 + + + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 + + + + + 后台定时检查可用性间隔秒数 + + + + + 对象池的对象被创建时 + + 返回被创建的对象 + + + + 销毁对象 + + 资源对象 + + + + 从对象池获取对象超时的时候触发,通过该方法统计 + + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 中间表,多对多 + + + + + 是否可用 + + + + + 不可用错误 + + + + + 不可用时间 + + + + + 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + + + 由【可用】变成【不可用】时返回true,否则返回false + + + + 统计对象池中的对象 + + + + + 统计对象池中的对象(完整) + + + + + 获取资源 + + 超时 + + + + + 获取资源 + + + + + + 使用完毕后,归还资源 + < + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + Object`1.Pool"> + + 所属对象池 + + + + + 在对象池中的唯一标识 + + + + + 资源对象 + + + + + 被获取的总次数 + + + + 最后获取时的时间 + + + + 最后归还时的时间 + + + + + 创建时间 + + + + + 最后获取时的线程id + + + + + 最后归还时的线程id + + + + + 重置 Value 值 + + + + + 对象池管理类 + + 对象类型 + + + + 后台定时检查可用性 + + + + + + 创建对象池 + + 池大小 + 池内对象的创建委托 + 获取池内对象成功后,进行使用前操作 + + + + 创建对象池 + + 策略 + + + + 获取可用资源,或创建资源 + + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + + + + + + + 获取 Type 的原始 c# 文本表示 + + + + + + + 测量两个经纬度的距离,返回单位:米 + + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) + + + + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + + + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 + 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 查询数据,加工为树型 List 返回 + 注意:实体需要配置父子导航属性 + + + + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index c91ecd75..b3dd4523 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -646,11 +646,13 @@ namespace FreeSql.Internal var eccContent = ecc.ParsedContent[exp3MethodParams[a].Name]; if (eccContent == null) exp3InvokeParams[a] = Expression.Lambda(exp3.Arguments[a]).Compile().DynamicInvoke(); + else if (exp3.Arguments[a].IsParameter()) + exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); else exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, eccContent.StartsWith("N'") ? eccContent.Substring(1).Trim('\'').Replace("''", "'") : - eccContent.Trim('\'').Replace("''", "'"));// exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); + eccContent.Trim('\'').Replace("''", "'")); } else exp3InvokeParams[a] = ecc; From 52fbe5ed86c237ab6574c0497d99b34908e4e0da Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Apr 2020 19:54:43 +0800 Subject: [PATCH 0557/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20DbContext/Re?= =?UTF-8?q?pository=20Orm=20=E5=B1=9E=E6=80=A7=E8=BF=9B=E8=A1=8C=20CURD=20?= =?UTF-8?q?=E4=B8=8E=E8=87=AA=E8=BA=AB=E4=BA=8B=E5=8A=A1=E7=9B=B8=E5=90=8C?= =?UTF-8?q?=E3=80=90=E6=96=B0=E7=AA=81=E7=A0=B4=E3=80=91=EF=BC=9B#270?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 24 +- .../DbContext/DbContextScopedFreeSql.cs | 74 + FreeSql.DbContext/DbContext/FreeContext.cs | 2 +- FreeSql.DbContext/DbSet/DbSet.cs | 70 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 56 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 60 +- .../Extensions/DependencyInjection.cs | 6 +- FreeSql.DbContext/FreeSql.DbContext.xml | 12 - .../ContextSet/RepositoryDbContext.cs | 4 +- .../Repository/ContextSet/RepositoryDbSet.cs | 4 +- .../Repository/Repository/BaseRepository.cs | 13 +- .../Repository/Repository/IBaseRepository.cs | 5 - .../RepositoryTests.cs | 11 + .../FreeSql.Tests.DbContext/UnitTest1.cs | 11 +- FreeSql/FreeSql.xml | 7377 ++++++++--------- .../Internal/CommonProvider/InsertProvider.cs | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 2 +- 17 files changed, 3884 insertions(+), 3849 deletions(-) create mode 100644 FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index c4ac6da4..49f044f1 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -10,13 +10,9 @@ namespace FreeSql { public abstract partial class DbContext : IDisposable { - internal IFreeSql _ormPriv; - - /// - /// 注意:IFreeSql 属于顶级对象,事务无法自动传递。 - /// 手工传递事务:ISelect/IInsert/IDelete/IUpdate 可以使用 WithTransaction(uow.GetOrBeginTransaction()) - /// - public IFreeSql Orm => _ormPriv ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); + internal DbContextScopedFreeSql _ormScoped; + internal IFreeSql OrmOriginal => _ormScoped?._originalFsql ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); + public IFreeSql Orm => _ormScoped ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); #region Property UnitOfWork internal bool _isUseUnitOfWork = true; //是否创建工作单元事务 @@ -28,7 +24,7 @@ namespace FreeSql { if (_uowPriv != null) return _uowPriv; if (_isUseUnitOfWork == false) return null; - return _uowPriv = new UnitOfWork(Orm); + return _uowPriv = new UnitOfWork(OrmOriginal); } } #endregion @@ -43,7 +39,7 @@ namespace FreeSql if (_optionsPriv == null) { _optionsPriv = new DbContextOptions(); - if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(Orm.Ado.Identifier, out var opt)) + if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(OrmOriginal.Ado.Identifier, out var opt)) { _optionsPriv.EnableAddOrUpdateNavigateList = opt.EnableAddOrUpdateNavigateList; _optionsPriv.OnEntityChange = opt.OnEntityChange; @@ -63,17 +59,17 @@ namespace FreeSql protected DbContext() : this(null, null) { } protected DbContext(IFreeSql fsql, DbContextOptions options) { - _ormPriv = fsql; + _ormScoped = DbContextScopedFreeSql.Create(fsql, () => this, () => UnitOfWork); _optionsPriv = options; - if (_ormPriv == null) + if (_ormScoped == null) { var builder = new DbContextOptionsBuilder(); OnConfiguring(builder); - _ormPriv = builder._fsql; + _ormScoped = DbContextScopedFreeSql.Create(builder._fsql, () => this, () => UnitOfWork); _optionsPriv = builder._options; } - if (_ormPriv != null) InitPropSets(); + if (_ormScoped != null) InitPropSets(); } protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { } @@ -113,7 +109,7 @@ namespace FreeSql #region DbSet 快速代理 void CheckEntityTypeOrThrow(Type entityType) { - if (Orm.CodeFirst.GetTableByEntity(entityType) == null) + if (OrmOriginal.CodeFirst.GetTableByEntity(entityType) == null) throw new ArgumentException($"参数 data 类型错误 {entityType.FullName} "); } /// diff --git a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs new file mode 100644 index 00000000..b188b937 --- /dev/null +++ b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs @@ -0,0 +1,74 @@ +using FreeSql; +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; + +namespace FreeSql +{ + class DbContextScopedFreeSql : IFreeSql + { + public IFreeSql _originalFsql; + Func _resolveDbContext; + Func _resolveUnitOfWork; + DbContextScopedFreeSql() { } + + public static DbContextScopedFreeSql Create(IFreeSql fsql, Func resolveDbContext, Func resolveUnitOfWork) + { + if (fsql == null) return null; + var scopedfsql = fsql as DbContextScopedFreeSql; + if (scopedfsql == null) return new DbContextScopedFreeSql { _originalFsql = fsql, _resolveDbContext = resolveDbContext, _resolveUnitOfWork = resolveUnitOfWork }; + return Create(scopedfsql._originalFsql, resolveDbContext, resolveUnitOfWork); + } + + public IAdo Ado => _originalFsql.Ado; + public IAop Aop => _originalFsql.Aop; + public ICodeFirst CodeFirst => _originalFsql.CodeFirst; + public IDbFirst DbFirst => _originalFsql.DbFirst; + public GlobalFilter GlobalFilter => _originalFsql.GlobalFilter; + public void Dispose() { } + + public void Transaction(Action handler) => _originalFsql.Transaction(handler); + public void Transaction(TimeSpan timeout, Action handler) => _originalFsql.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => _originalFsql.Transaction(isolationLevel, timeout, handler); + + public ISelect Select() where T1 : class + { + _resolveDbContext()?.ExecCommand(); + return _originalFsql.Select().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction(false)); + } + public ISelect Select(object dywhere) where T1 : class => Select().WhereDynamic(dywhere); + + public IDelete Delete() where T1 : class + { + _resolveDbContext()?.ExecCommand(); + return _originalFsql.Delete().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + } + public IDelete Delete(object dywhere) where T1 : class => Delete().WhereDynamic(dywhere); + + public IUpdate Update() where T1 : class + { + var db = _resolveDbContext(); + db?.ExecCommand(); + var update = _originalFsql.Update().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + if (db?.Options.NoneParameter != null) update.NoneParameter(db.Options.NoneParameter.Value); + return update; + } + public IUpdate Update(object dywhere) where T1 : class => Update().WhereDynamic(dywhere); + + public IInsert Insert() where T1 : class + { + var db = _resolveDbContext(); + db?.ExecCommand(); + var insert = _originalFsql.Insert().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + if (db?.Options.NoneParameter != null) insert.NoneParameter(db.Options.NoneParameter.Value); + return insert; + } + public IInsert Insert(T1 source) where T1 : class => Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => Insert().AppendData(source); + + } +} diff --git a/FreeSql.DbContext/DbContext/FreeContext.cs b/FreeSql.DbContext/DbContext/FreeContext.cs index 62fbe1c7..ab7a262f 100644 --- a/FreeSql.DbContext/DbContext/FreeContext.cs +++ b/FreeSql.DbContext/DbContext/FreeContext.cs @@ -7,7 +7,7 @@ namespace FreeSql public FreeContext(IFreeSql orm) { - _ormPriv = orm; + _ormScoped = DbContextScopedFreeSql.Create(orm, () => this, () => UnitOfWork); } } } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 9dfe6aa2..32efd9dd 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -33,7 +33,7 @@ namespace FreeSql protected virtual ISelect OrmSelect(object dywhere) { DbContextExecCommand(); //查询前先提交,否则会出脏读 - return _db.Orm.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); + return _db.OrmOriginal.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); } ~DbSet() => this.Dispose(); @@ -54,7 +54,7 @@ namespace FreeSql protected virtual IInsert OrmInsert() { - var insert = _db.Orm.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); + var insert = _db.OrmOriginal.Insert().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); if (_db.Options.NoneParameter != null) insert.NoneParameter(_db.Options.NoneParameter.Value); return insert; } @@ -63,11 +63,11 @@ namespace FreeSql protected virtual IUpdate OrmUpdate(IEnumerable entitys) { - var update = _db.Orm.Update().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); + var update = _db.OrmOriginal.Update().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); if (_db.Options.NoneParameter != null) update.NoneParameter(_db.Options.NoneParameter.Value); return update.SetSource(entitys); } - protected virtual IDelete OrmDelete(object dywhere) => _db.Orm.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); + protected virtual IDelete OrmDelete(object dywhere) => _db.OrmOriginal.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); internal void EnqueueToDbContext(DbContext.EntityChangeType changeType, EntityState state) => _db.EnqueueAction(changeType, this, typeof(EntityState), _entityType, state); @@ -89,7 +89,7 @@ namespace FreeSql var itemType = item.GetType(); if (itemType == typeof(object)) return; if (itemType.FullName.Contains("FreeSqlLazyEntity__")) itemType = itemType.BaseType; - if (_db.Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; + if (_db.OrmOriginal.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; var dbset = _db.Set(itemType); dbset?.GetType().GetMethod("TrackToList", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dbset, new object[] { list }); return; @@ -99,11 +99,11 @@ namespace FreeSql if (_table?.Primarys.Any() != true) return; foreach (var item in ls) { - var key = _db.Orm.GetEntityKeyString(_entityType, item, false); + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); if (key == null) continue; _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { - _db.Orm.MapEntityValue(_entityType, item, ov.Value); + _db.OrmOriginal.MapEntityValue(_entityType, item, ov.Value); ov.Time = DateTime.Now; return ov; }); @@ -117,7 +117,7 @@ namespace FreeSql protected ConcurrentDictionary _states = new ConcurrentDictionary(); internal ConcurrentDictionary _statesInternal => _states; TableInfo _tablePriv; - protected TableInfo _table => _tablePriv ?? (_tablePriv = _db.Orm.CodeFirst.GetTableByEntity(_entityType)); + protected TableInfo _table => _tablePriv ?? (_tablePriv = _db.OrmOriginal.CodeFirst.GetTableByEntity(_entityType)); ColumnInfo[] _tableIdentitysPriv, _tableServerTimesPriv; protected ColumnInfo[] _tableIdentitys => _tableIdentitysPriv ?? (_tableIdentitysPriv = _table.Primarys.Where(a => a.Attribute.IsIdentity).ToArray()); protected ColumnInfo[] _tableServerTimes => _tableServerTimesPriv ?? (_tableServerTimesPriv = _table.Primarys.Where(a => a.Attribute.ServerTime != DateTimeKind.Unspecified).ToArray()); @@ -133,7 +133,7 @@ namespace FreeSql { if (entityType == typeof(object)) throw new Exception("ISelect.AsType 参数不支持指定为 object"); if (entityType == _entityType) return this; - var newtb = _db.Orm.CodeFirst.GetTableByEntity(entityType); + var newtb = _db.OrmOriginal.CodeFirst.GetTableByEntity(entityType); _entityType = entityType; _tablePriv = newtb ?? throw new Exception("DbSet.AsType 参数错误,请传入正确的实体类型"); _tableIdentitysPriv = null; @@ -179,15 +179,15 @@ namespace FreeSql public void AttachRange(IEnumerable data) { if (data == null || data.Any() == false) return; - if (_table.Primarys.Any() == false) throw new Exception($"不可附加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data.First())}"); + if (_table.Primarys.Any() == false) throw new Exception($"不可附加,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data.First())}"); foreach (var item in data) { - var key = _db.Orm.GetEntityKeyString(_entityType, item, false); - if (string.IsNullOrEmpty(key)) throw new Exception($"不可附加,未设置主键的值:{_db.Orm.GetEntityString(_entityType, item)}"); + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); + if (string.IsNullOrEmpty(key)) throw new Exception($"不可附加,未设置主键的值:{_db.OrmOriginal.GetEntityString(_entityType, item)}"); _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { - _db.Orm.MapEntityValue(_entityType, item, ov.Value); + _db.OrmOriginal.MapEntityValue(_entityType, item, ov.Value); ov.Time = DateTime.Now; return ov; }); @@ -201,10 +201,10 @@ namespace FreeSql { if (data == null) return this; var pkitem = (TEntity)Activator.CreateInstance(_entityType); - foreach (var pk in _db.Orm.CodeFirst.GetTableByEntity(_entityType).Primarys) + foreach (var pk in _db.OrmOriginal.CodeFirst.GetTableByEntity(_entityType).Primarys) { - var colVal = _db.Orm.GetEntityValueWithPropertyName(_entityType, data, pk.CsName); - _db.Orm.SetEntityValueWithPropertyName(_entityType, pkitem, pk.CsName, colVal); + var colVal = _db.OrmOriginal.GetEntityValueWithPropertyName(_entityType, data, pk.CsName); + _db.OrmOriginal.SetEntityValueWithPropertyName(_entityType, pkitem, pk.CsName, colVal); } this.Attach(pkitem); return this; @@ -222,15 +222,15 @@ namespace FreeSql EntityState CreateEntityState(TEntity data) { if (data == null) throw new ArgumentNullException(nameof(data)); - var key = _db.Orm.GetEntityKeyString(_entityType, data, false); + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, false); var state = new EntityState((TEntity)Activator.CreateInstance(_entityType), key); - _db.Orm.MapEntityValue(_entityType, data, state.Value); + _db.OrmOriginal.MapEntityValue(_entityType, data, state.Value); return state; } bool? ExistsInStates(TEntity data) { if (data == null) throw new ArgumentNullException(nameof(data)); - var key = _db.Orm.GetEntityKeyString(_entityType, data, false); + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) return null; return _states.ContainsKey(key); } @@ -255,14 +255,14 @@ namespace FreeSql } if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可添加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可添加,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } - FreeSql.Internal.CommonProvider.InsertProvider.AuditDataValue(this, data, _db.Orm, _table, null); - var key = _db.Orm.GetEntityKeyString(_entityType, data, true); + FreeSql.Internal.CommonProvider.InsertProvider.AuditDataValue(this, data, _db.OrmOriginal, _table, null); + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, true); if (string.IsNullOrEmpty(key)) { - switch (_db.Orm.Ado.DataType) + switch (_db.OrmOriginal.Ado.DataType) { case DataType.SqlServer: case DataType.OdbcSqlServer: @@ -272,7 +272,7 @@ namespace FreeSql default: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) return true; - if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } } @@ -280,13 +280,13 @@ namespace FreeSql { if (_states.ContainsKey(key)) { - if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } - var idval = _db.Orm.GetEntityIdentityValueWithPrimary(_entityType, data); + var idval = _db.OrmOriginal.GetEntityIdentityValueWithPrimary(_entityType, data); if (idval > 0) { - if (isThrow) throw new Exception($"不可添加,自增属性有值:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可添加,自增属性有值:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } } @@ -313,19 +313,19 @@ namespace FreeSql } if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可更新,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可更新,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } - FreeSql.Internal.CommonProvider.UpdateProvider.AuditDataValue(this, data, _db.Orm, _table, null); - var key = _db.Orm.GetEntityKeyString(_entityType, data, false); + FreeSql.Internal.CommonProvider.UpdateProvider.AuditDataValue(this, data, _db.OrmOriginal, _table, null); + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) { - if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } if (_states.TryGetValue(key, out var tryval) == false) { - if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询 或者 Attach:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询 或者 Attach:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } return true; @@ -351,13 +351,13 @@ namespace FreeSql } if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可删除,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可删除,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } - var key = _db.Orm.GetEntityKeyString(_entityType, data, false); + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) { - if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); + if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); return false; } //if (_states.TryGetValue(key, out var tryval) == false) { diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 1dfb5296..1e756f53 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -35,7 +35,7 @@ namespace FreeSql if (_tableIdentitys.Length > 0) { //有自增,马上执行 - switch (_db.Orm.Ado.DataType) + switch (_db.OrmOriginal.Ado.DataType) { case DataType.SqlServer: case DataType.OdbcSqlServer: @@ -46,7 +46,7 @@ namespace FreeSql await DbContextExecCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); - _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) @@ -58,7 +58,7 @@ namespace FreeSql var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); - _db.Orm.MapEntityValue(_entityType, newval, data); + _db.OrmOriginal.MapEntityValue(_entityType, newval, data); Attach(newval); if (_db.Options.EnableAddOrUpdateNavigateList) await AddOrUpdateNavigateListAsync(data, true); @@ -70,7 +70,7 @@ namespace FreeSql await DbContextExecCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); - _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) @@ -96,7 +96,7 @@ namespace FreeSql if (_tableIdentitys.Length > 0) { //有自增,马上执行 - switch (_db.Orm.Ado.DataType) + switch (_db.OrmOriginal.Ado.DataType) { case DataType.SqlServer: case DataType.OdbcSqlServer: @@ -104,11 +104,11 @@ namespace FreeSql case DataType.OdbcPostgreSQL: await DbContextExecCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); - if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); var idx = 0; foreach (var s in data) - _db.Orm.MapEntityValue(_entityType, rets[idx++], s); + _db.OrmOriginal.MapEntityValue(_entityType, rets[idx++], s); IncrAffrows(rets.Count); AttachRange(rets); if (_db.Options.EnableAddOrUpdateNavigateList) @@ -168,13 +168,13 @@ namespace FreeSql Expression.Constant( FreeSql.Internal.Utils.GetDataReaderValue( tref.Columns[colidx].CsType, - _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.RefColumns[colidx].CsType) + _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.RefColumns[colidx].CsType) ); if (whereParentExp == null) whereParentExp = whereExp; else whereParentExp = Expression.AndAlso(whereParentExp, whereExp); } var propValEach = GetItemValue(item, prop) as IEnumerable; - var subDelete = _db.Orm.Delete().AsType(tref.RefEntityType) + var subDelete = _db.OrmOriginal.Delete().AsType(tref.RefEntityType) .WithTransaction(_uow?.GetOrBeginTransaction()) .Where(Expression.Lambda>(whereParentExp, deleteWhereParentParam)); foreach (var propValItem in propValEach) @@ -230,12 +230,12 @@ namespace FreeSql Expression.Constant( FreeSql.Internal.Utils.GetDataReaderValue( tref.MiddleColumns[colidx].CsType, - _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.MiddleColumns[colidx].CsType) + _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.MiddleColumns[colidx].CsType) ), midSelectParam)); if (curList.Any() == false) //全部删除 { - var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType) + var delall = _db.OrmOriginal.Delete().AsType(tref.RefMiddleEntityType) .WithTransaction(_uow?.GetOrBeginTransaction()); foreach (var midWhere in midWheres) delall.Where(midWhere); var sql = delall.ToSql(); @@ -266,8 +266,8 @@ namespace FreeSql for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) { var refcol = tref.Columns[midcolidx - tref.Columns.Count]; - var midval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefMiddleEntityType, midItem, tref.MiddleColumns[midcolidx].CsName)); - var refval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curList[curIdx], tref.Columns[midcolidx - tref.Columns.Count].CsName)); + var midval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(tref.RefMiddleEntityType, midItem, tref.MiddleColumns[midcolidx].CsName)); + var refval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(tref.RefEntityType, curList[curIdx], tref.Columns[midcolidx - tref.Columns.Count].CsName)); if (object.Equals(midval, refval) == false) { isEquals = false; @@ -289,14 +289,14 @@ namespace FreeSql var newItem = Activator.CreateInstance(tref.RefMiddleEntityType); for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { - var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[colidx].CsType, _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); - _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[colidx].CsName, val); + var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); + _db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[colidx].CsName, val); } for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) { var refcol = tref.RefColumns[midcolidx - tref.Columns.Count]; - var refval = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[midcolidx].CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curItem, refcol.CsName)); - _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[midcolidx].CsName, refval); + var refval = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[midcolidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(tref.RefEntityType, curItem, refcol.CsName)); + _db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[midcolidx].CsName, refval); } midListAdd.Add(newItem); } @@ -308,8 +308,8 @@ namespace FreeSql { for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { - var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); - _db.Orm.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val); + var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); + _db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val); } await refSet.AddOrUpdateAsync(propValItem); } @@ -336,10 +336,10 @@ namespace FreeSql if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; var lstval2 = default(EntityState); - if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_db.Orm.GetEntityString(_entityType, uplst2.Value)}"); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_db.OrmOriginal.GetEntityString(_entityType, uplst2.Value)}"); - var cuig1 = _db.Orm.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _db.Orm.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; + var cuig1 = _db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; List data = null; string[] cuig = null; @@ -372,9 +372,9 @@ namespace FreeSql foreach (var newval in data) { if (_states.TryGetValue(newval.Key, out var tryold)) - _db.Orm.MapEntityValue(_entityType, newval.Value, tryold.Value); + _db.OrmOriginal.MapEntityValue(_entityType, newval.Value, tryold.Value); if (newval.OldValue != null) - _db.Orm.MapEntityValue(_entityType, newval.Value, newval.OldValue); + _db.OrmOriginal.MapEntityValue(_entityType, newval.Value, newval.OldValue); } return affrows; } @@ -385,11 +385,11 @@ namespace FreeSql async public Task UpdateAsync(TEntity data) { var exists = ExistsInStates(data); - if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); + if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); if (exists == false) { var olddata = await OrmSelect(data).FirstAsync(); - if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_db.Orm.GetEntityString(_entityType, data)}"); + if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); } await UpdateRangePrivAsync(new[] { data }, true); @@ -438,7 +438,7 @@ namespace FreeSql async public Task AddOrUpdateAsync(TEntity data) { if (data == null) throw new ArgumentNullException(nameof(data)); - if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); + if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); var flagExists = ExistsInStates(data); if (flagExists == false) @@ -458,7 +458,7 @@ namespace FreeSql } if (CanAdd(data, false)) { - _db.Orm.ClearEntityPrimaryValueWithIdentity(_entityType, data); + _db.OrmOriginal.ClearEntityPrimaryValueWithIdentity(_entityType, data); await AddPrivAsync(data, false); } } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 79171465..b49f5542 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -34,7 +34,7 @@ namespace FreeSql if (_tableIdentitys.Length > 0) { //有自增,马上执行 - switch (_db.Orm.Ado.DataType) + switch (_db.OrmOriginal.Ado.DataType) { case DataType.SqlServer: case DataType.OdbcSqlServer: @@ -45,7 +45,7 @@ namespace FreeSql DbContextExecCommand(); var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); - _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) @@ -57,7 +57,7 @@ namespace FreeSql var newval = this.OrmInsert(data).ExecuteInserted().First(); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); - _db.Orm.MapEntityValue(_entityType, newval, data); + _db.OrmOriginal.MapEntityValue(_entityType, newval, data); Attach(newval); if (_db.Options.EnableAddOrUpdateNavigateList) AddOrUpdateNavigateList(data, true); @@ -69,7 +69,7 @@ namespace FreeSql DbContextExecCommand(); var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); - _db.Orm.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); + _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) @@ -99,7 +99,7 @@ namespace FreeSql if (_tableIdentitys.Length > 0) { //有自增,马上执行 - switch (_db.Orm.Ado.DataType) + switch (_db.OrmOriginal.Ado.DataType) { case DataType.SqlServer: case DataType.OdbcSqlServer: @@ -107,11 +107,11 @@ namespace FreeSql case DataType.OdbcPostgreSQL: DbContextExecCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); - if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.Orm.Ado.DataType} 的返回数据,与添加的数目不匹配"); + if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); var idx = 0; foreach (var s in data) - _db.Orm.MapEntityValue(_entityType, rets[idx++], s); + _db.OrmOriginal.MapEntityValue(_entityType, rets[idx++], s); IncrAffrows(rets.Count); AttachRange(rets); if (_db.Options.EnableAddOrUpdateNavigateList) @@ -180,13 +180,13 @@ namespace FreeSql Expression.Constant( FreeSql.Internal.Utils.GetDataReaderValue( tref.Columns[colidx].CsType, - _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.RefColumns[colidx].CsType) + _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.RefColumns[colidx].CsType) ); if (whereParentExp == null) whereParentExp = whereExp; else whereParentExp = Expression.AndAlso(whereParentExp, whereExp); } var propValEach = GetItemValue(item, prop) as IEnumerable; - var subDelete = _db.Orm.Delete().AsType(tref.RefEntityType) + var subDelete = _db.OrmOriginal.Delete().AsType(tref.RefEntityType) .WithTransaction(_uow?.GetOrBeginTransaction()) .Where(Expression.Lambda>(whereParentExp, deleteWhereParentParam)); foreach (var propValItem in propValEach) @@ -242,13 +242,13 @@ namespace FreeSql Expression.Constant( FreeSql.Internal.Utils.GetDataReaderValue( tref.MiddleColumns[colidx].CsType, - _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.MiddleColumns[colidx].CsType) + _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.MiddleColumns[colidx].CsType) ), midSelectParam)); if (curList.Any() == false) //全部删除 { - var delall = _db.Orm.Delete().AsType(tref.RefMiddleEntityType) - .WithTransaction(_uow?.GetOrBeginTransaction()); + var delall = _db.OrmOriginal.Delete().AsType(tref.RefMiddleEntityType) + .WithTransaction(_uow?.GetOrBeginTransaction()); foreach (var midWhere in midWheres) delall.Where(midWhere); var sql = delall.ToSql(); delall.ExecuteAffrows(); @@ -278,8 +278,8 @@ namespace FreeSql for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) { var refcol = tref.RefColumns[midcolidx - tref.Columns.Count]; - var midval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefMiddleEntityType, midItem, tref.MiddleColumns[midcolidx].CsName)); - var refval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curList[curIdx], refcol.CsName)); + var midval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(tref.RefMiddleEntityType, midItem, tref.MiddleColumns[midcolidx].CsName)); + var refval = FreeSql.Internal.Utils.GetDataReaderValue(refcol.CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(tref.RefEntityType, curList[curIdx], refcol.CsName)); if (object.Equals(midval, refval) == false) { isEquals = false; @@ -301,14 +301,14 @@ namespace FreeSql var newItem = Activator.CreateInstance(tref.RefMiddleEntityType); for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { - var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[colidx].CsType, _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); - _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[colidx].CsName, val); + var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); + _db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[colidx].CsName, val); } for (var midcolidx = tref.Columns.Count; midcolidx < tref.MiddleColumns.Count; midcolidx++) { var refcol = tref.RefColumns[midcolidx - tref.Columns.Count]; - var refval = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[midcolidx].CsType, _db.Orm.GetEntityValueWithPropertyName(tref.RefEntityType, curItem, refcol.CsName)); - _db.Orm.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[midcolidx].CsName, refval); + var refval = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[midcolidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(tref.RefEntityType, curItem, refcol.CsName)); + _db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefMiddleEntityType, newItem, tref.MiddleColumns[midcolidx].CsName, refval); } midListAdd.Add(newItem); } @@ -320,8 +320,8 @@ namespace FreeSql { for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { - var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.Orm.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); - _db.Orm.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val); + var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); + _db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val); } refSet.AddOrUpdate(propValItem); } @@ -371,10 +371,10 @@ namespace FreeSql if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; var lstval2 = default(EntityState); - if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_db.Orm.GetEntityString(_entityType, uplst2.Value)}"); + if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_db.OrmOriginal.GetEntityString(_entityType, uplst2.Value)}"); - var cuig1 = _db.Orm.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _db.Orm.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; + var cuig1 = _db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); + var cuig2 = uplst2 != null ? _db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; List data = null; string[] cuig = null; @@ -407,9 +407,9 @@ namespace FreeSql foreach (var newval in data) { if (_states.TryGetValue(newval.Key, out var tryold)) - _db.Orm.MapEntityValue(_entityType, newval.Value, tryold.Value); + _db.OrmOriginal.MapEntityValue(_entityType, newval.Value, tryold.Value); if (newval.OldValue != null) - _db.Orm.MapEntityValue(_entityType, newval.Value, newval.OldValue); + _db.OrmOriginal.MapEntityValue(_entityType, newval.Value, newval.OldValue); } return affrows; } @@ -426,11 +426,11 @@ namespace FreeSql public void Update(TEntity data) { var exists = ExistsInStates(data); - if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_db.Orm.GetEntityString(_entityType, data)}"); + if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); if (exists == false) { var olddata = OrmSelect(data).First(); - if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_db.Orm.GetEntityString(_entityType, data)}"); + if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); } UpdateRangePriv(new[] { data }, true); @@ -476,7 +476,7 @@ namespace FreeSql { var state = CreateEntityState(item); _states.TryRemove(state.Key, out var trystate); - _db.Orm.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, item); + _db.OrmOriginal.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, item); EnqueueToDbContext(DbContext.EntityChangeType.Delete, state); } @@ -501,7 +501,7 @@ namespace FreeSql public void AddOrUpdate(TEntity data) { if (data == null) throw new ArgumentNullException(nameof(data)); - if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_db.Orm.GetEntityString(_entityType, data)}"); + if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); var flagExists = ExistsInStates(data); if (flagExists == false) @@ -521,7 +521,7 @@ namespace FreeSql } if (CanAdd(data, false)) { - _db.Orm.ClearEntityPrimaryValueWithIdentity(_entityType, data); + _db.OrmOriginal.ClearEntityPrimaryValueWithIdentity(_entityType, data); AddPriv(data, false); } } diff --git a/FreeSql.DbContext/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Extensions/DependencyInjection.cs index c22b4ee8..6e7fb6cd 100644 --- a/FreeSql.DbContext/Extensions/DependencyInjection.cs +++ b/FreeSql.DbContext/Extensions/DependencyInjection.cs @@ -23,14 +23,14 @@ namespace FreeSql { throw new Exception($"AddFreeDbContext 发生错误,请检查 {dbContextType.Name} 的构造参数都已正确注入", ex); } - if (ctx != null && ctx._ormPriv == null) + if (ctx != null && ctx._ormScoped == null) { var builder = new DbContextOptionsBuilder(); options(builder); - ctx._ormPriv = builder._fsql; + ctx._ormScoped = DbContextScopedFreeSql.Create(builder._fsql, () => ctx, () => ctx.UnitOfWork); ctx._optionsPriv = builder._options; - if (ctx._ormPriv == null) + if (ctx._ormScoped == null) throw new Exception("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); ctx.InitPropSets(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index eacd506b..165be8ac 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -4,12 +4,6 @@ FreeSql.DbContext - - - 注意:IFreeSql 属于顶级对象,事务无法自动传递。 - 手工传递事务:ISelect/IInsert/IDelete/IUpdate 可以使用 WithTransaction(uow.GetOrBeginTransaction()) - - 添加 @@ -231,12 +225,6 @@ - - - 注意:IFreeSql 属于顶级对象,事务无法自动传递。 - 手工传递事务:ISelect/IInsert/IDelete/IUpdate 可以使用 WithTransaction(uow.GetOrBeginTransaction()) - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 8945b6fa..7638d46d 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -11,7 +11,7 @@ namespace FreeSql protected IBaseRepository _repo; public RepositoryDbContext(IFreeSql orm, IBaseRepository repo) : base() { - _ormPriv = orm; + _ormScoped = DbContextScopedFreeSql.Create(orm, () => this, () => repo.UnitOfWork); _isUseUnitOfWork = false; UnitOfWork = repo.UnitOfWork; _repo = repo; @@ -23,7 +23,7 @@ namespace FreeSql { if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; - var tb = _ormPriv.CodeFirst.GetTableByEntity(entityType); + var tb = OrmOriginal.CodeFirst.GetTableByEntity(entityType); if (tb == null) return null; object repo = _repo; diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs index 2b33cf57..55db9b9f 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs @@ -34,7 +34,7 @@ namespace FreeSql if (entitys != null) foreach (var entity in entitys) if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) - throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_db.Orm.GetEntityString(_entityType, entity)}"); + throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_db.OrmOriginal.GetEntityString(_entityType, entity)}"); update.Where(filter.Value.Expression); } return update.AsTable(_repo.AsTableValueInternal); @@ -58,7 +58,7 @@ namespace FreeSql if (entitys != null) foreach (var entity in entitys) if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) - throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_db.Orm.GetEntityString(_entityType, entity)}"); + throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_db.OrmOriginal.GetEntityString(_entityType, entity)}"); } return insert.AsTable(_repo.AsTableValueInternal); } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 0670666f..de6d38f4 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -13,7 +13,7 @@ namespace FreeSql { internal RepositoryDbContext _dbPriv; //这个不能私有化,有地方需要反射获取它 - internal RepositoryDbContext _db => _dbPriv ?? (_dbPriv = new RepositoryDbContext(Orm, this)); + internal RepositoryDbContext _db => _dbPriv ?? (_dbPriv = new RepositoryDbContext(OrmOriginal, this)); internal RepositoryDbSet _dbsetPriv; internal RepositoryDbSet _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set() as RepositoryDbSet); @@ -25,7 +25,7 @@ namespace FreeSql protected BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) { - Orm = fsql; + _ormScoped = DbContextScopedFreeSql.Create(fsql, () => _db, () => UnitOfWork); DataFilterUtil.SetRepositoryDataFilter(this, null); DataFilter.Apply("", filter); AsTable(asTable); @@ -56,7 +56,9 @@ namespace FreeSql } public DbContextOptions DbContextOptions { get => _db.Options; set => _db.Options = value; } - public IFreeSql Orm { get; private set; } + internal DbContextScopedFreeSql _ormScoped; + internal IFreeSql OrmOriginal => _ormScoped?._originalFsql; + public IFreeSql Orm => _ormScoped; IUnitOfWork _unitOfWork; public IUnitOfWork UnitOfWork { @@ -64,6 +66,7 @@ namespace FreeSql { _unitOfWork = value; if (_dbsetPriv != null) _dbsetPriv._uow = _unitOfWork; //防止 dbset 对象已经存在,再次设置 UnitOfWork 无法生效,所以作此判断重新设置 + if (_dbPriv != null) _dbPriv.UnitOfWork = _unitOfWork; } get => _unitOfWork; } @@ -147,11 +150,11 @@ namespace FreeSql TEntity CheckTKeyAndReturnIdEntity(TKey id) { - var tb = _db.Orm.CodeFirst.GetTableByEntity(EntityType); + var tb = _db.OrmOriginal.CodeFirst.GetTableByEntity(EntityType); if (tb.Primarys.Length != 1) throw new Exception($"实体类型 {EntityType.Name} 主键数量不为 1,无法使用该方法"); if (tb.Primarys[0].CsType.NullableTypeOrThis() != typeof(TKey).NullableTypeOrThis()) throw new Exception($"实体类型 {EntityType.Name} 主键类型不为 {typeof(TKey).FullName},无法使用该方法"); var obj = Activator.CreateInstance(tb.Type); - _db.Orm.SetEntityValueWithPropertyName(tb.Type, obj, tb.Primarys[0].CsName, id); + _db.OrmOriginal.SetEntityValueWithPropertyName(tb.Type, obj, tb.Primarys[0].CsName, id); var ret = obj as TEntity; if (ret == null) throw new Exception($"实体类型 {EntityType.Name} 无法转换为 {typeof(TEntity).Name},无法使用该方法"); return ret; diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index db8c71a0..e172073f 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -10,11 +10,6 @@ namespace FreeSql { Type EntityType { get; } IUnitOfWork UnitOfWork { get; set; } - - /// - /// 注意:IFreeSql 属于顶级对象,事务无法自动传递。 - /// 手工传递事务:ISelect/IInsert/IDelete/IUpdate 可以使用 WithTransaction(uow.GetOrBeginTransaction()) - /// IFreeSql Orm { get; } /// diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index d6dca944..0797327d 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -29,6 +29,13 @@ namespace FreeSql.Tests item = repos.Find(item.Id); Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + + repos.Orm.Insert(new AddUpdateInfo()).ExecuteAffrows(); + repos.Orm.Insert(new AddUpdateInfo { Id = Guid.NewGuid() }).ExecuteAffrows(); + repos.Orm.Update().Set(a => a.Title == "xxx").Where(a => a.Id == item.Id).ExecuteAffrows(); + item = repos.Orm.Select(item).First(); + Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); + repos.Orm.Delete(item).ExecuteAffrows(); } [Fact] @@ -122,6 +129,7 @@ namespace FreeSql.Tests { flowRepos = uow.GetRepository(); flowRepos.Insert(flow); + flowRepos.Orm.Select().ToList(); uow.Commit(); } } @@ -158,6 +166,7 @@ namespace FreeSql.Tests uow.Close(); var uowFlowRepos = uow.GetRepository(); uowFlowRepos.Insert(flow); + uowFlowRepos.Orm.Select().ToList(); //ѹرչԪ᲻ύûӰ죬˴עȷԪǷЧرˣCommitҲӦò //uow.Commit(); } @@ -199,6 +208,7 @@ namespace FreeSql.Tests { var uowFlowRepos = uow.GetRepository(); uowFlowRepos.Insert(flow); + uowFlowRepos.Orm.Select().ToList(); // Insert/Update/Delete ùرuowķᷢ쳣 uow.Close(); uow.Commit(); @@ -240,6 +250,7 @@ namespace FreeSql.Tests { var uowFlowRepos = uow.GetRepository(); uowFlowRepos.Insert(flow); + uowFlowRepos.Orm.Select().ToList(); //commitύݿ //uow.Commit(); } diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index f01f8158..17f73605 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -118,6 +118,8 @@ namespace FreeSql.Tests }; ctx.AddRange(new[] { song1, song2, song3 }); + ctx.Orm.Select().Limit(10).ToList(); + ctx.AddRange( new[] { new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }, @@ -150,7 +152,7 @@ namespace FreeSql.Tests using (var ctx = g.sqlite.CreateDbContext()) { - + ctx.Options.EnableAddOrUpdateNavigateList = true; var tags = ctx.Set().Select.IncludeMany(a => a.Tags).ToList(); var tag = new Tag @@ -168,6 +170,9 @@ namespace FreeSql.Tests } }; ctx.Add(tag); + + var tags2 = ctx.Orm.Select().IncludeMany(a => a.Tags).ToList(); + ctx.SaveChanges(); } } @@ -179,10 +184,12 @@ namespace FreeSql.Tests using (var ctx = g.sqlite.CreateDbContext()) { - + ctx.Options.EnableAddOrUpdateNavigateList = true; var tag = ctx.Set().Select.First(); tag.Tags.Add(new Tag { Name = "sub3" }); + tag.Name = Guid.NewGuid().ToString(); ctx.Update(tag); + var xxx = ctx.Orm.Select().First(); ctx.SaveChanges(); } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 7783e259..12b3cc3e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1,3708 +1,3669 @@ - - - - FreeSql - - - - - 数据库列名 - - - - - 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - - - - - 数据库类型,如: varchar(255) - 字符串长度,可使用特性 [MaxLength(255)] - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 忽略此列,不迁移、不插入 - - - - - 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) - - - - - 类型映射,除了可做基本的类型映射外,特别介绍的功能: - 1、将 enum 属性映射成 typeof(string) - 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap - - - - - 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: - - >0时排前面,1,2,3... - - =0时排中间(默认) - - <0时排后面,...-3,-2,-1 - - - - - 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 - - - - - 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 - - - - - 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 - - - - - 设置长度,针对 string 类型避免 DbType 的繁琐设置 - 提示:也可以使用 [MaxLength(100)] - --- - StringLength = 100 时,对应 DbType: - MySql -> varchar(100) - SqlServer -> nvarchar(100) - PostgreSQL -> varchar(100) - Oracle -> nvarchar2(100) - Sqlite -> nvarchar(100) - --- - StringLength = -1 时,对应 DbType: - MySql -> text - SqlServer -> nvarchar(max) - PostgreSQL -> text - Oracle -> nvarchar2(4000) - Sqlite -> text - - - - - 执行 Insert 方法时使用此值 - 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 - - - - - 数据库列名 - - - - - 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - - - - - 数据库类型,如: varchar(255) - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 忽略此列,不迁移、不插入 - - - - - 乐观锁 - - - - - 类型映射,比如:可将 enum 属性映射成 typeof(string) - - - - - - - 创建表时字段位置,规则如下: - - >0时排前面 - - =0时排中间(默认) - - <0时排后面 - - - - - - - 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 - - - - - - - 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 - - - - - - - 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 - - - - - - - 设置长度,针对 string 类型避免 DbType 的繁琐设置 - --- - StringLength = 100 时,对应 DbType: - MySql -> varchar(100) - SqlServer -> nvarchar(100) - PostgreSQL -> varchar(100) - Oracle -> nvarchar2(100) - Sqlite -> nvarchar(100) - --- - StringLength = -1 时,对应 DbType: - MySql -> text - SqlServer -> nvarchar(max) - PostgreSQL -> text - Oracle -> nvarchar2(4000) - Sqlite -> text - - - - - 执行 Insert 方法时使用此值 - 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 - - - - - - - 自定义表达式函数解析 - 注意:请使用静态方法、或者在类上标记 - - - - - 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 - - - - - 数据库类型,可用于适配多种数据库环境 - - - - - 已解析的表达式中参数内容 - - - - - 表达式原始值 - - - - - 主对象的参数化对象,可重塑其属性 - - - - - 可附加参数化对象 - 注意:本属性只有 Where 的表达式解析才可用 - - - - - 将 c# 对象转换为 SQL - - - - - 返回表达式函数表示的 SQL 字符串 - - - - - 获取实体元数据 - - - - - - - 解析表达式 - - - - - - - 索引名 - - - - - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - - - - - 是否唯一 - - - - - 手工绑定 OneToMany、ManyToOne 导航关系 - - - - - 手工绑定 ManyToMany 导航关系 - - - - - 主键名 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 导航关系Fluent,与 NavigateAttribute 对应 - - - - 多对多关系的中间实体类型 - - - - - 设置实体的索引 - - 索引名 - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 导航关系Fluent,与 NavigateAttribute 对应 - - - - - 多对多关系的中间实体类型 - - - - - 设置实体的索引 - - 索引名 - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - - 所属表 - - - - - 列名 - - - - - 映射到 C# 类型 - - - - - 数据库枚举类型int值 - - - - - 数据库类型,字符串,varchar - - - - - 数据库类型,字符串,varchar(255) - - - - - 最大长度 - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 备注 - - - - - 枚举类型标识 - - - - - 枚举项 - - - - - 唯一标识 - - - - - SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 - - - - - 表名 - - - - - 表备注,SqlServer下是扩展属性 MS_Description - - - - - 表/视图 - - - - - 列 - - - - - 自增列 - - - - - 主键/组合 - - - - - 唯一键/组合 - - - - - 索引/组合 - - - - - 外键 - - - - - 类型标识 - - - - - 枚举项 - - - - - 通用的 Odbc 实现,只能做基本的 Crud 操作 - 不支持实体结构迁移、不支持分页(只能 Take 查询) - - 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 - 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 - - 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 - - - - - 武汉达梦数据库有限公司 - - - - - Microsoft Office Access 是由微软发布的关联式数据库管理系统 - - - - - 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null - - - - - 当Guid无值时,会生成有序的新值 - - - - - - 获取实体的主键值,多个主键返回数组 - - - - - - - - - 获取实体的属性值 - - - - - - - - - - 获取实体的所有数据,以 (1, 2, xxx) 的形式 - - - - - - - - - 使用新实体的值,复盖旧实体的值 - - - - - 使用新实体的主键值,复盖旧实体的主键值 - - - - - 设置实体中主键内的自增字段值(若存在) - - - - - - - - - 获取实体中主键内的自增字段值(若存在) - - - - - - - - 清除实体的主键值,将自增、Guid类型的主键值清除 - - - - - - - - 清除实体的主键值,将自增、Guid类型的主键值清除 - - - - - - - - 对比两个实体值,返回相同/或不相同的列名 - - - - - - - - - - - 设置实体中某属性的数值增加指定的值 - - - - - - - - - - 设置实体中某属性的值 - - - - - - - - - - 缓存执行 IUpdate.Set - - - - - - - - - 使用连接串(推荐) - - 数据库类型 - 数据库连接串 - 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 - - - - - 使用从数据库,支持多个 - - 从数据库连接串 - - - - - 使用自定义数据库连接对象(放弃内置对象连接池技术) - - 数据库类型 - 数据库连接对象创建器 - 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - true:运行时检查自动同步结构, false:不同步结构 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - - - 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() - - - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - - - 监视数据库命令对象 - - 执行前 - 执行后,可监视执行性能 - - - - - 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) - 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] - - - - - - - 转小写同步结构 - - true:转小写, false:不转 - - - - - 转大写同步结构 - - true:转大写, false:不转 - - - - - 自动转换实体属性名称 Entity Property -> Db Filed - - *不会覆盖 [Column] 特性设置的Name - - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - lambda表达式条件,仅支持实体基础成员(不包含导航对象) - 若想使用导航对象,请使用 ISelect.ToDelete() 方法 - - lambda表达式条件 - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - - sql语法条件 - 参数 - - - - - 传入实体,将主键作为条件 - - 实体 - - - - - 传入实体集合,将主键作为条件 - - 实体集合 - - - - - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回被删除的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 追加准备插入的实体 - - 实体 - - - - - 追加准备插入的实体 - - 实体 - - - - - 追加准备插入的实体集合 - - 实体集合 - - - - - 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 指定可插入自增字段 - - - - - - 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - - 是否不使用参数化 - - - - - 批量执行选项设置,一般不需要使用该方法 - 各数据库 values, parameters 限制不一样,默认设置: - MySql 5000 3000 - PostgreSQL 5000 3000 - SqlServer 1000 2100 - Oracle 500 999 - Sqlite 5000 999 - 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - - 指定根据 values 数量拆分执行 - 指定根据 parameters 数量拆分执行 - 是否自动开启事务 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回自增值 - 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] - - - - - - 执行SQL语句,返回插入后的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 返回 DataTable 以便做 BulkCopy 数据做准备 - 此方法会处理: - 类型、表名、字段名映射 - IgnoreColumns、InsertColumns - - - - - - 自动产生 as1, as2, as3 .... 字段别名 - 这种方法可以最大程度防止多表,存在相同字段的问题 - - - - - 使用属性名作为字段别名 - - - - - 指定事务对象 - - - - - - - 指定连接对象 - - - - - - - 审核或跟踪 ToList 即将返回的数据 - - - - - - - 执行SQL查询,返回 DataTable - - - - - - 以字典的形式返回查询结果 - 注意:字典的特点会导致返回的数据无序 - - - - - - - - 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 - 注意: - 1、ToList(a => a) 可以返回 a 所有实体 - 2、ToList(a => new { a }) 这样也可以 - 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 - 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() - - false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - - - - - 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 - - 数据块的大小 - 处理数据块 - false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - - - - 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 - - - - - - - - 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - - - - - - 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - - - - - - 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: - fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() - 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: - DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) - 复杂删除使用该方案的好处: - 1、删除前可预览测试数据,防止错误删除操作; - 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); - - - - - - 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: - fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() - 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: - UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) - 复杂更新使用该方案的好处: - 1、更新前可预览测试数据,防止错误更新操作; - 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); - - - - - - 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; - 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 - 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); - select * from (SELECT a."Id" as1 FROM "table_1" a) ftb - UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb - UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb - 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() - - - - - - - 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 - 如:select.AsAlias((_, old) => $"{old} with(lock)") - - - - - - - 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - 指定字段 - - - - - 执行SQL查询,是否有记录 - - - - - - 查询的记录数量 - - - - - - 查询的记录数量,以参数out形式返回 - - 返回的变量 - - - - - 指定从主库查询(默认查询从库) - - - - - - 左联查询,使用导航属性自动生成SQL - - 表达式 - - - - - 联接查询,使用导航属性自动生成SQL - - 表达式 - - - - - 右联查询,使用导航属性自动生成SQL - - 表达式 - - - - - 左联查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 联接查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 右联查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - - sql语法条件 - 参数 - - - - - 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - - sql语法条件 - 参数 - - - - - 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - - sql语法条件 - 参数 - - - - - 在 JOIN 位置插入 SQL 内容 - 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") - - - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - - sql语法条件 - 参数 - - - - - 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) - - true 时生效 - sql语法条件 - 参数 - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 排他更新锁 - 注意:务必在开启事务后使用该功能 - MySql: for update - SqlServer: With(UpdLock, RowLock, NoWait) - PostgreSQL: for update nowait - Oracle: for update nowait - Sqlite: 无效果 - 达梦: for update nowait - - noawait - - - - - 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) - - sql语法 - 参数 - - - - - 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) - - sql语法条件 - 参数 - - - - - 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) - - sql语法 - 参数 - - - - - 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) - - true 时生效 - sql语法 - 参数 - - - - - 查询向后偏移行数 - - - - - - - 查询向后偏移行数 - - 行数 - - - - - 查询多少条数据 - - - - - - - 查询多少条数据 - - - - - - - 分页 - - 第几页 - 每页多少 - - - - - 查询数据前,去重 - - .Distinct().ToList(x => x.GroupName) 对指定字段去重 - - - .Distinct().ToList() 对整个查询去重 - - - - - - - 执行SQL查询,是否有记录 - - lambda表达式 - - - - - 执行SQL查询,返回 DataTable - - - - - - 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 - - - - - - - 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 - - - - - - - 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 - - - - - - - 返回即将执行的SQL语句 - - 返回类型 - 选择列 - 字段别名 - - - - - 执行SQL查询,返回指定字段的聚合结果 - - - - - - - - 求和 - - 返回类型 - 列 - - - - - 最小值 - - 返回类型 - 列 - - - - - 最大值 - - 返回类型 - 列 - - - - - 平均值 - - 返回类型 - 列 - - - - - 指定别名 - - 别名 - - - - - 多表查询 - - - - - - - - 多表查询 - - - - - - - - - 多表查询 - - - - - - - - - - 多表查询 - - - - - - - - - - - 多表查询 - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - - lambda表达式 - - - - - 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - - true 时生效 - lambda表达式 - - - - - 多表条件查询 - - - lambda表达式 - - - - - 多表条件查询 - - - lambda表达式 - - - - - 多表条件查询 - - - - lambda表达式 - - - - - 多表条件查询 - - - - - lambda表达式 - - - - - 多表条件查询 - - - - - lambda表达式 - - - - - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 多表查询时,该方法标记后,表达式条件将对所有表进行附加 - - 例如:软删除、租户,每个表都给条件,挺麻烦的 - - fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) - - 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) - - 当其中的实体可附加表达式才会进行,表越多时收益越大 - - - - - - - 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) - - - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列排序,OrderBy(true, a => a.Time) - - - true 时生效 - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 按列倒向排序,OrderByDescending(true, a => a.Time) - - true 时生效 - 列 - - - - - 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 - - - 选择一个导航属性 - - - - - 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 实现 select .. from ( select ... from t ) a 这样的功能 - 使用 AsTable 方法也可以达到效果 - - SQL语句 - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - - lambda表达式 - - - - - 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - - true 时生效 - lambda表达式 - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 按聚合条件过滤,Where(a => a.Count() > 10) - - lambda表达式 - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - - 返回类型 - 选择列 - - - - - 【linq to sql】专用方法,不建议直接使用 - - - - - 返回即将执行的SQL语句 - - 返回类型 - 选择列 - - - - - 返回即将执行的SQL语句 - - 指定字段 - - - - - 查询向后偏移行数 - - - - - - - 查询向后偏移行数 - - 行数 - - - - - 查询多少条数据 - - - - - - - 查询多少条数据 - - - - - - - 分页 - - 第几页 - 每页多少 - - - - - 查询的记录数量 - - - - - - 查询的记录数量,以参数out形式返回 - - 返回的变量 - - - - - 分组的数据 - - - - - 记录总数 - - - - - - 求和 - - - - - - - - 平均值 - - - - - - - - 最大值 - - - - - - - - 最小值 - - - - - - - 所有元素 - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - - 是否不使用参数化 - - - - - 批量执行选项设置,一般不需要使用该方法 - 各数据库 rows, parameters 限制不一样,默认设置: - MySql 500 3000 - PostgreSQL 500 3000 - SqlServer 500 2100 - Oracle 200 999 - Sqlite 200 999 - 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - - 指定根据 rows 数量拆分执行 - 指定根据 parameters 数量拆分执行 - 是否自动开启事务 - - - - - 更新数据,设置更新的实体 - - 实体 - - - - - 更新数据,设置更新的实体集合 - - 实体集合 - - - - - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 忽略的列 - - 属性名,或者字段名 - - - - - 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 指定的列 - - 属性名,或者字段名 - - - - - 设置列的新值,Set(a => a.Name, "newvalue") - - - lambda选择列 - 新值 - - - - - 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 - - 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' - - - - - - - - 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) - - sql语法 - 参数 - - - - - 设置更新的列 - - SetDto(new { title = "xxx", clicks = 2 }) - - SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) - - dto 或 Dictionary<string, object> - - - - - lambda表达式条件,仅支持实体基础成员(不包含导航对象) - 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 - - lambda表达式条件 - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - - sql语法条件 - 参数 - - - - - 传入实体,将主键作为条件 - - 实体 - - - - - 传入实体集合,将主键作为条件 - - 实体集合 - - - - - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回更新后的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 主库连接池 - - - - - 从库连接池 - - - - - 数据库类型 - - - - - UseConnectionString 时候的值 - - - - - UseSalve 时候的值 - - - - - 唯一标识 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 当前线程的事务 - - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) - - - - - - - 查询 - - - - - - - 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<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 }) - - - - - - - - - 可自定义解析表达式 - - - - - 自定义实体的配置,方便和多个 ORM 共同使用 - - - - - 自定义实体的属性配置,方便和多个 ORM 共同使用 - - - - - 增删查改,执行命令之前触发 - - - - - 增删查改,执行命令完成后触发 - - - - - CodeFirst迁移,执行之前触发 - - - - - CodeFirst迁移,执行完成触发 - - - - - Insert/Update自动值处理 - - - - - 监视数据库命令对象(执行前,调试) - - - - - 监视数据库命令对象(执行后,用于监视执行性能) - - - - - 跟踪开始 - - - - - 跟踪结束 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 - - - - - 备注 - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构,适用 PostgreSQL - - - - - 转大写同步结构,适用 Oracle/达梦 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - - - - - - 将实体类型集合与数据库对比,返回DDL语句 - - 实体类型 - - - - - 将实体类型与数据库对比,返回DDL语句(指定表名) - - 实体类型 - 指定表名对比 - - - - - 同步实体类型到数据库 - - - - - - 同步实体类型集合到数据库 - - - - - - 同步实体类型到数据库(指定表名) - - 实体类型 - 指定表名对比 - - - - 根据 System.Type 获取数据库信息 - - - - - - - 在外部配置实体的特性 - - - - - - - - 在外部配置实体的特性 - - - - - - - - 获取在外部配置实体的特性 - - - 未使用ConfigEntity配置时,返回null - - - - 获取实体类核心配置 - - - - - - - 获取所有数据库 - - - - - - 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 - - - - - - - 获取数据库枚举类型int值 - - - - - - - 获取c#转换,(int)、(long) - - - - - - - 获取c#值 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 中间表,多对多 - - - - - 是否可用 - - - - - 不可用错误 - - - - - 不可用时间 - - - - - 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 - - - 由【可用】变成【不可用】时返回true,否则返回false - - - - 统计对象池中的对象 - - - - - 统计对象池中的对象(完整) - - - - - 获取资源 - - 超时 - - - - - 使用完毕后,归还资源 - - 对象 - 是否重新创建 - - - - 名称 - - - - - 池容量 - - - - - 默认获取超时设置 - - - - - 空闲时间,获取时若超出,则重新创建 - - - - - 异步获取排队队列大小,小于等于0不生效 - - - - - 获取超时后,是否抛出异常 - - - - - 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 - - - - - 后台定时检查可用性间隔秒数 - - - - - 对象池的对象被创建时 - - 返回被创建的对象 - - - - 销毁对象 - - 资源对象 - - - - 从对象池获取对象超时的时候触发,通过该方法统计 - - - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 中间表,多对多 - - - - - 是否可用 - - - - - 不可用错误 - - - - - 不可用时间 - - - - - 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 - - - 由【可用】变成【不可用】时返回true,否则返回false - - - - 统计对象池中的对象 - - - - - 统计对象池中的对象(完整) - - - - - 获取资源 - - 超时 - - - - - 获取资源 - - - - - - 使用完毕后,归还资源 - < - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - C#: that >= between && that <= and - SQL: that BETWEEN between AND and - - - - - - - - - 注意:这个方法和 Between 有细微区别 - C#: that >= start && that < end - SQL: that >= start and that < end - - - Object`1.Pool"> - - 所属对象池 - - - - - 在对象池中的唯一标识 - - - - - 资源对象 - - - - - 被获取的总次数 - - - - 最后获取时的时间 - - - - 最后归还时的时间 - - - - - 创建时间 - - - - - 最后获取时的线程id - - - - - 最后归还时的线程id - - - - - 重置 Value 值 - - - - - 对象池管理类 - - 对象类型 - - - - 后台定时检查可用性 - - - - - - 创建对象池 - - 池大小 - 池内对象的创建委托 - 获取池内对象成功后,进行使用前操作 - - - - 创建对象池 - - 策略 - - - - 获取可用资源,或创建资源 - - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - C#: that >= between && that <= and - SQL: that BETWEEN between AND and - - - - - - - - - 注意:这个方法和 Between 有细微区别 - C#: that >= start && that < end - SQL: that >= start and that < end - - - - - - - - - 获取 Type 的原始 c# 文本表示 - - - - - - - 测量两个经纬度的距离,返回单位:米 - - 经纬坐标1 - 经纬坐标2 - 返回距离(单位:米) - - - - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 - - - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 - 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 查询数据,加工为树型 List 返回 - 注意:实体需要配置父子导航属性 - - - - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - + + + + FreeSql + + + + + 数据库列名 + + + + + 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + + + + + 数据库类型,如: varchar(255) + 字符串长度,可使用特性 [MaxLength(255)] + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 忽略此列,不迁移、不插入 + + + + + 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) + + + + + 类型映射,除了可做基本的类型映射外,特别介绍的功能: + 1、将 enum 属性映射成 typeof(string) + 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap + + + + + 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: + + >0时排前面,1,2,3... + + =0时排中间(默认) + + <0时排后面,...-3,-2,-1 + + + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + 提示:也可以使用 [MaxLength(100)] + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + + 数据库列名 + + + + + 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + + + + + 数据库类型,如: varchar(255) + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 忽略此列,不迁移、不插入 + + + + + 乐观锁 + + + + + 类型映射,比如:可将 enum 属性映射成 typeof(string) + + + + + + + 创建表时字段位置,规则如下: + + >0时排前面 + + =0时排中间(默认) + + <0时排后面 + + + + + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + + + + 自定义表达式函数解析 + 注意:请使用静态方法、或者在类上标记 + + + + + 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 + + + + + 数据库类型,可用于适配多种数据库环境 + + + + + 已解析的表达式中参数内容 + + + + + 表达式原始值 + + + + + 主对象的参数化对象,可重塑其属性 + + + + + 可附加参数化对象 + 注意:本属性只有 Where 的表达式解析才可用 + + + + + 将 c# 对象转换为 SQL + + + + + 返回表达式函数表示的 SQL 字符串 + + + + + 获取实体元数据 + + + + + + + 解析表达式 + + + + + + + 索引名 + + + + + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + + 是否唯一 + + + + + 手工绑定 OneToMany、ManyToOne 导航关系 + + + + + 手工绑定 ManyToMany 导航关系 + + + + + 主键名 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + 多对多关系的中间实体类型 + + + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + + 多对多关系的中间实体类型 + + + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + + 所属表 + + + + + 列名 + + + + + 映射到 C# 类型 + + + + + 数据库枚举类型int值 + + + + + 数据库类型,字符串,varchar + + + + + 数据库类型,字符串,varchar(255) + + + + + 最大长度 + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 备注 + + + + + 枚举类型标识 + + + + + 枚举项 + + + + + 唯一标识 + + + + + SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 + + + + + 表名 + + + + + 表备注,SqlServer下是扩展属性 MS_Description + + + + + 表/视图 + + + + + 列 + + + + + 自增列 + + + + + 主键/组合 + + + + + 唯一键/组合 + + + + + 索引/组合 + + + + + 外键 + + + + + 类型标识 + + + + + 枚举项 + + + + + 通用的 Odbc 实现,只能做基本的 Crud 操作 + 不支持实体结构迁移、不支持分页(只能 Take 查询) + + 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 + 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 + + 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 + + + + + 武汉达梦数据库有限公司 + + + + + Microsoft Office Access 是由微软发布的关联式数据库管理系统 + + + + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null + + + + + 当Guid无值时,会生成有序的新值 + + + + + + 获取实体的主键值,多个主键返回数组 + + + + + + + + + 获取实体的属性值 + + + + + + + + + + 获取实体的所有数据,以 (1, 2, xxx) 的形式 + + + + + + + + + 使用新实体的值,复盖旧实体的值 + + + + + 使用新实体的主键值,复盖旧实体的主键值 + + + + + 设置实体中主键内的自增字段值(若存在) + + + + + + + + + 获取实体中主键内的自增字段值(若存在) + + + + + + + + 清除实体的主键值,将自增、Guid类型的主键值清除 + + + + + + + + 清除实体的主键值,将自增、Guid类型的主键值清除 + + + + + + + + 对比两个实体值,返回相同/或不相同的列名 + + + + + + + + + + + 设置实体中某属性的数值增加指定的值 + + + + + + + + + + 设置实体中某属性的值 + + + + + + + + + + 缓存执行 IUpdate.Set + + + + + + + + + 使用连接串(推荐) + + 数据库类型 + 数据库连接串 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + + + + 使用从数据库,支持多个 + + 从数据库连接串 + + + + + 使用自定义数据库连接对象(放弃内置对象连接池技术) + + 数据库类型 + 数据库连接对象创建器 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + true:运行时检查自动同步结构, false:不同步结构 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + + + 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() + + + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + + + 监视数据库命令对象 + + 执行前 + 执行后,可监视执行性能 + + + + + 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) + 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] + + + + + + + 转小写同步结构 + + true:转小写, false:不转 + + + + + 转大写同步结构 + + true:转大写, false:不转 + + + + + 自动转换实体属性名称 Entity Property -> Db Filed + + *不会覆盖 [Column] 特性设置的Name + + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToDelete() 方法 + + lambda表达式条件 + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + + sql语法条件 + 参数 + + + + + 传入实体,将主键作为条件 + + 实体 + + + + + 传入实体集合,将主键作为条件 + + 实体集合 + + + + + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回被删除的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 追加准备插入的实体 + + 实体 + + + + + 追加准备插入的实体 + + 实体 + + + + + 追加准备插入的实体集合 + + 实体集合 + + + + + 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 指定可插入自增字段 + + + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + + 是否不使用参数化 + + + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 values, parameters 限制不一样,默认设置: + MySql 5000 3000 + PostgreSQL 5000 3000 + SqlServer 1000 2100 + Oracle 500 999 + Sqlite 5000 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 values 数量拆分执行 + 指定根据 parameters 数量拆分执行 + 是否自动开启事务 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回自增值 + 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] + + + + + + 执行SQL语句,返回插入后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 返回 DataTable 以便做 BulkCopy 数据做准备 + 此方法会处理: + 类型、表名、字段名映射 + IgnoreColumns、InsertColumns + + + + + + 自动产生 as1, as2, as3 .... 字段别名 + 这种方法可以最大程度防止多表,存在相同字段的问题 + + + + + 使用属性名作为字段别名 + + + + + 指定事务对象 + + + + + + + 指定连接对象 + + + + + + + 审核或跟踪 ToList 即将返回的数据 + + + + + + + 执行SQL查询,返回 DataTable + + + + + + 以字典的形式返回查询结果 + 注意:字典的特点会导致返回的数据无序 + + + + + + + + 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + 注意: + 1、ToList(a => a) 可以返回 a 所有实体 + 2、ToList(a => new { a }) 这样也可以 + 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 + 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() + + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + + + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + + 数据块的大小 + 处理数据块 + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + + 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 + + + + + + + + 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + + + + + + 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + + + + + + 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: + DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂删除使用该方案的好处: + 1、删除前可预览测试数据,防止错误删除操作; + 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); + + + + + + 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: + UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂更新使用该方案的好处: + 1、更新前可预览测试数据,防止错误更新操作; + 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); + + + + + + 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 + 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); + select * from (SELECT a."Id" as1 FROM "table_1" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb + 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() + + + + + + + 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 + 如:select.AsAlias((_, old) => $"{old} with(lock)") + + + + + + + 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + 指定字段 + + + + + 执行SQL查询,是否有记录 + + + + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + + + + 指定从主库查询(默认查询从库) + + + + + + 左联查询,使用导航属性自动生成SQL + + 表达式 + + + + + 联接查询,使用导航属性自动生成SQL + + 表达式 + + + + + 右联查询,使用导航属性自动生成SQL + + 表达式 + + + + + 左联查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 联接查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 右联查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + + sql语法条件 + 参数 + + + + + 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + + sql语法条件 + 参数 + + + + + 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + + sql语法条件 + 参数 + + + + + 在 JOIN 位置插入 SQL 内容 + 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") + + + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + + sql语法条件 + 参数 + + + + + 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + + true 时生效 + sql语法条件 + 参数 + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 排他更新锁 + 注意:务必在开启事务后使用该功能 + MySql: for update + SqlServer: With(UpdLock, RowLock, NoWait) + PostgreSQL: for update nowait + Oracle: for update nowait + Sqlite: 无效果 + 达梦: for update nowait + + noawait + + + + + 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + + sql语法 + 参数 + + + + + 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + + sql语法条件 + 参数 + + + + + 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + + sql语法 + 参数 + + + + + 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + + true 时生效 + sql语法 + 参数 + + + + + 查询向后偏移行数 + + + + + + + 查询向后偏移行数 + + 行数 + + + + + 查询多少条数据 + + + + + + + 查询多少条数据 + + + + + + + 分页 + + 第几页 + 每页多少 + + + + + 查询数据前,去重 + + .Distinct().ToList(x => x.GroupName) 对指定字段去重 + + + .Distinct().ToList() 对整个查询去重 + + + + + + + 执行SQL查询,是否有记录 + + lambda表达式 + + + + + 执行SQL查询,返回 DataTable + + + + + + 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 + + + + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + + + + 返回即将执行的SQL语句 + + 返回类型 + 选择列 + 字段别名 + + + + + 执行SQL查询,返回指定字段的聚合结果 + + + + + + + + 求和 + + 返回类型 + 列 + + + + + 最小值 + + 返回类型 + 列 + + + + + 最大值 + + 返回类型 + 列 + + + + + 平均值 + + 返回类型 + 列 + + + + + 指定别名 + + 别名 + + + + + 多表查询 + + + + + + + + 多表查询 + + + + + + + + + 多表查询 + + + + + + + + + + 多表查询 + + + + + + + + + + + 多表查询 + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 多表条件查询 + + + lambda表达式 + + + + + 多表条件查询 + + + lambda表达式 + + + + + 多表条件查询 + + + + lambda表达式 + + + + + 多表条件查询 + + + + + lambda表达式 + + + + + 多表条件查询 + + + + + lambda表达式 + + + + + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 多表查询时,该方法标记后,表达式条件将对所有表进行附加 + + 例如:软删除、租户,每个表都给条件,挺麻烦的 + + fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) + + 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) + + 当其中的实体可附加表达式才会进行,表越多时收益越大 + + + + + + + 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) + + + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列排序,OrderBy(true, a => a.Time) + + + true 时生效 + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 按列倒向排序,OrderByDescending(true, a => a.Time) + + true 时生效 + 列 + + + + + 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 + + + 选择一个导航属性 + + + + + 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 实现 select .. from ( select ... from t ) a 这样的功能 + 使用 AsTable 方法也可以达到效果 + + SQL语句 + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 按聚合条件过滤,Where(a => a.Count() > 10) + + lambda表达式 + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + + 返回类型 + 选择列 + + + + + 【linq to sql】专用方法,不建议直接使用 + + + + + 返回即将执行的SQL语句 + + 返回类型 + 选择列 + + + + + 返回即将执行的SQL语句 + + 指定字段 + + + + + 查询向后偏移行数 + + + + + + + 查询向后偏移行数 + + 行数 + + + + + 查询多少条数据 + + + + + + + 查询多少条数据 + + + + + + + 分页 + + 第几页 + 每页多少 + + + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + + + + 分组的数据 + + + + + 记录总数 + + + + + + 求和 + + + + + + + + 平均值 + + + + + + + + 最大值 + + + + + + + + 最小值 + + + + + + + 所有元素 + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + + 是否不使用参数化 + + + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 rows, parameters 限制不一样,默认设置: + MySql 500 3000 + PostgreSQL 500 3000 + SqlServer 500 2100 + Oracle 200 999 + Sqlite 200 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 rows 数量拆分执行 + 指定根据 parameters 数量拆分执行 + 是否自动开启事务 + + + + + 更新数据,设置更新的实体 + + 实体 + + + + + 更新数据,设置更新的实体集合 + + 实体集合 + + + + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 忽略的列 + + 属性名,或者字段名 + + + + + 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 指定的列 + + 属性名,或者字段名 + + + + + 设置列的新值,Set(a => a.Name, "newvalue") + + + lambda选择列 + 新值 + + + + + 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + + 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + + + + + + + + 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + + sql语法 + 参数 + + + + + 设置更新的列 + + SetDto(new { title = "xxx", clicks = 2 }) + + SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + + dto 或 Dictionary<string, object> + + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 + + lambda表达式条件 + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + + sql语法条件 + 参数 + + + + + 传入实体,将主键作为条件 + + 实体 + + + + + 传入实体集合,将主键作为条件 + + 实体集合 + + + + + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回更新后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 主库连接池 + + + + + 从库连接池 + + + + + 数据库类型 + + + + + UseConnectionString 时候的值 + + + + + UseSalve 时候的值 + + + + + 唯一标识 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 当前线程的事务 + + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + + + + + + + 查询 + + + + + + + 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<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 }) + + + + + + + + + 可自定义解析表达式 + + + + + 自定义实体的配置,方便和多个 ORM 共同使用 + + + + + 自定义实体的属性配置,方便和多个 ORM 共同使用 + + + + + 增删查改,执行命令之前触发 + + + + + 增删查改,执行命令完成后触发 + + + + + CodeFirst迁移,执行之前触发 + + + + + CodeFirst迁移,执行完成触发 + + + + + Insert/Update自动值处理 + + + + + 监视数据库命令对象(执行前,调试) + + + + + 监视数据库命令对象(执行后,用于监视执行性能) + + + + + 跟踪开始 + + + + + 跟踪结束 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 + + + + + 备注 + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构,适用 PostgreSQL + + + + + 转大写同步结构,适用 Oracle/达梦 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + 将实体类型与数据库对比,返回DDL语句 + + + + + + + 将实体类型集合与数据库对比,返回DDL语句 + + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 + + + + + 同步实体类型到数据库 + + + + + + 同步实体类型集合到数据库 + + + + + + 同步实体类型到数据库(指定表名) + + 实体类型 + 指定表名对比 + + + + 根据 System.Type 获取数据库信息 + + + + + + + 在外部配置实体的特性 + + + + + + + + 在外部配置实体的特性 + + + + + + + + 获取在外部配置实体的特性 + + + 未使用ConfigEntity配置时,返回null + + + + 获取实体类核心配置 + + + + + + + 获取所有数据库 + + + + + + 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 + + + + + + + 获取数据库枚举类型int值 + + + + + + + 获取c#转换,(int)、(long) + + + + + + + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 中间表,多对多 + + + + + 是否可用 + + + + + 不可用错误 + + + + + 不可用时间 + + + + + 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + + + 由【可用】变成【不可用】时返回true,否则返回false + + + + 统计对象池中的对象 + + + + + 统计对象池中的对象(完整) + + + + + 获取资源 + + 超时 + + + + + 使用完毕后,归还资源 + + 对象 + 是否重新创建 + + + + 名称 + + + + + 池容量 + + + + + 默认获取超时设置 + + + + + 空闲时间,获取时若超出,则重新创建 + + + + + 异步获取排队队列大小,小于等于0不生效 + + + + + 获取超时后,是否抛出异常 + + + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 + + + + + 后台定时检查可用性间隔秒数 + + + + + 对象池的对象被创建时 + + 返回被创建的对象 + + + + 销毁对象 + + 资源对象 + + + + 从对象池获取对象超时的时候触发,通过该方法统计 + + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + + + + 归还对象给对象池的时候触发 + + 资源对象 + + + + 检查可用性 + + 资源对象 + + + + + 事件:可用时触发 + + + + + 事件:不可用时触发 + + + + + 所属对象池 + + + + + 在对象池中的唯一标识 + + + + + 资源对象 + + + + + 被获取的总次数 + + + + 最后获取时的时间 + + + + 最后归还时的时间 + + + + + 创建时间 + + + + + 最后获取时的线程id + + + + + 最后归还时的线程id + + + + + 重置 Value 值 + + + + + 对象池管理类 + + 对象类型 + + + + 后台定时检查可用性 + + + + + + 创建对象池 + + 池大小 + 池内对象的创建委托 + 获取池内对象成功后,进行使用前操作 + + + + 创建对象池 + + 策略 + + + + 获取可用资源,或创建资源 + + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + + + + + + + 获取 Type 的原始 c# 文本表示 + + + + + + + 测量两个经纬度的距离,返回单位:米 + + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) + + + + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + + + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 + 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 查询数据,加工为树型 List 返回 + 注意:实体需要配置父子导航属性 + + + + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 313434de..ca5f7574 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -134,7 +134,7 @@ namespace FreeSql.Internal.CommonProvider public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data == null) return; - if (typeof(T1) == typeof(object) && data.GetType() != table.Type) + if (typeof(T1) == typeof(object) && new[] { table.Type, table.TypeLazy }.Contains(data.GetType()) == false) throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); foreach (var col in table.Columns.Values) { diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index f5ad6a9c..d4100b04 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -351,7 +351,7 @@ namespace FreeSql.Internal.CommonProvider { if (orm.Aop.AuditValueHandler == null) return; if (data == null) return; - if (typeof(T1) == typeof(object) && data.GetType() != table.Type) + if (typeof(T1) == typeof(object) && new[] { table.Type, table.TypeLazy }.Contains(data.GetType()) == false) throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); foreach (var col in table.Columns.Values) { From 5e531b2521c87b26540aca930dc258efe0053496 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Apr 2020 22:37:42 +0800 Subject: [PATCH 0558/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IQueryable?= =?UTF-8?q?=20RestoreToSelect=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=B0=86=20IQueryable=20=E8=BD=AC=E5=9B=9E=E6=88=90?= =?UTF-8?q?=20ISelect=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.Linq.xml | 14 +- .../FreeSqlExtensionsLinq.cs | 17 +- .../QueryableProvider.cs | 99 +++--- .../{Queryable => Linq}/ExprHelperTest.cs | 0 .../ISelectLinqToSqlTests.cs} | 6 +- .../QueryableLinqToSqlTests.cs | 23 -- .../Linq/QueryableRestoreToSelectTest.cs | 50 +++ .../{Queryable => Linq}/QueryableTest.cs | 0 FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- FreeSql/FreeSql.xml | 308 ++++++++---------- 10 files changed, 266 insertions(+), 253 deletions(-) rename FreeSql.Tests/FreeSql.Tests/{Queryable => Linq}/ExprHelperTest.cs (100%) rename FreeSql.Tests/FreeSql.Tests/{LinqToSql/SqliteLinqToSqlTests.cs => Linq/ISelectLinqToSqlTests.cs} (99%) rename FreeSql.Tests/FreeSql.Tests/{Queryable => Linq}/QueryableLinqToSqlTests.cs (88%) create mode 100644 FreeSql.Tests/FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs rename FreeSql.Tests/FreeSql.Tests/{Queryable => Linq}/QueryableTest.cs (100%) diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml index 19871dd2..f5004a0a 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml @@ -7,11 +7,21 @@ 将 ISelect<T1> 转换为 IQueryable<T1> - 此方法主要用于扩展,比如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 - 注意:IQueryable 方法污染较为严重,请尽量避免此转换 + 用于扩展如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 + 提示:IQueryable 方法污染严重,查询功能的实现也不理想,应尽量避免此转换 + IQueryable<T1> 扩展方法 RestoreToSelect() 可以还原为 ISelect<T1> + + + 将 IQueryable<T1> 转换为 ISelect<T1> + 前提:IQueryable 必须由 FreeSql.Extensions.Linq.QueryableProvider 实现 + + + + + 【linq to sql】专用扩展方法,不建议直接使用 diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs b/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs index de256cec..5df25a29 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs +++ b/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs @@ -15,14 +15,27 @@ public static class FreeSqlExtensionsLinqSql /// /// 将 ISelect<T1> 转换为 IQueryable<T1> - /// 此方法主要用于扩展,比如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 - /// 注意:IQueryable 方法污染较为严重,请尽量避免此转换 + /// 用于扩展如:abp IRepository GetAll() 接口方法需要返回 IQueryable 对象 + /// 提示:IQueryable 方法污染严重,查询功能的实现也不理想,应尽量避免此转换 + /// IQueryable<T1> 扩展方法 RestoreToSelect() 可以还原为 ISelect<T1> /// /// public static IQueryable AsQueryable(this ISelect that) where T1 : class { return new QueryableProvider(that as Select1Provider); } + /// + /// 将 IQueryable<T1> 转换为 ISelect<T1> + /// 前提:IQueryable 必须由 FreeSql.Extensions.Linq.QueryableProvider 实现 + /// + /// + /// + /// + public static ISelect RestoreToSelect(this IQueryable that) where T1 : class + { + var queryable = that as QueryableProvider ?? throw new Exception($"无法将 IQueryable<{typeof(T1).Name}> 转换为 ISelect<{typeof(T1).Name}>,因为他的实现不是 FreeSql.Extensions.Linq.QueryableProvider"); + return queryable._select; + } /// /// 【linq to sql】专用扩展方法,不建议直接使用 diff --git a/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs b/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs index b65147b1..35b2516c 100644 --- a/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs +++ b/Extensions/FreeSql.Extensions.Linq/QueryableProvider.cs @@ -13,15 +13,15 @@ namespace FreeSql.Extensions.Linq { class QueryableProvider : IQueryable, IOrderedQueryable where TSource : class { - private Expression _expression; - private IQueryProvider _provider; - private Select1Provider _select; + Expression _expression; + IQueryProvider _provider; + internal Select1Provider _select; public QueryableProvider(Select1Provider select) { _select = select; _expression = Expression.Constant(this); - _provider = new QueryProvider(_select); + _provider = new QueryProvider(_select, _expression); } public QueryableProvider(Expression expression, IQueryProvider provider, Select1Provider select) { @@ -49,56 +49,58 @@ namespace FreeSql.Extensions.Linq class QueryProvider : IQueryProvider where TSource : class { - private Select1Provider _select; + Select1Provider _select; + Expression _oldExpression; - public QueryProvider(Select1Provider select) + public QueryProvider(Select1Provider select, Expression oldExpression) { _select = select; + _oldExpression = oldExpression; } public IQueryable CreateQuery(Expression expression) { + ExecuteExp(expression, null, false); if (typeof(TElement) != typeof(TCurrent)) - return new QueryableProvider(expression, new QueryProvider(_select), _select); + return new QueryableProvider(expression, new QueryProvider(_select, expression), _select); + _oldExpression = expression; return new QueryableProvider(expression, this, _select); } public IQueryable CreateQuery(Expression expression) => throw new NotImplementedException(); public TResult Execute(Expression expression) { - var stackCallExps = new Stack(); - var callExp = expression as MethodCallExpression; - while(callExp != null) - { - stackCallExps.Push(callExp); - callExp = callExp?.Arguments.FirstOrDefault() as MethodCallExpression; - } + return (TResult)ExecuteExp(expression, typeof(TResult), _oldExpression == expression); + } + public object Execute(Expression expression) => throw new NotImplementedException(); - SelectGroupingProvider groupBy = null; + public object ExecuteExp(Expression expression, Type tresult, bool isProcessed) + { + var callExp = expression as MethodCallExpression; var isfirst = false; - while (stackCallExps.Any()) + if (callExp != null && isProcessed == false) { - callExp = stackCallExps.Pop(); - TResult throwCallExp(string message) => throw new Exception($"FreeSql Queryable 解析出错,执行的方法 {callExp.Method.Name} {message}"); + object throwCallExp(string message) => throw new Exception($"解析失败 {callExp.Method.Name} {message},提示:可以使用扩展方法 IQueryable.RestoreToSelect() 还原为 ISelect 再查询"); if (callExp.Method.DeclaringType != typeof(Queryable)) return throwCallExp($"必须属于 System.Linq.Queryable"); - TResult tplMaxMinAvgSum(string method) { + object tplMaxMinAvgSum(string method) + { if (callExp.Arguments.Count == 2) { var avgParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; - return (TResult)Utils.GetDataReaderValue(typeof(TResult), + return Utils.GetDataReaderValue(tresult, _select.GetType().GetMethod(method).MakeGenericMethod(avgParam.ReturnType).Invoke(_select, new object[] { avgParam })); } return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); } - TResult tplOrderBy(string method, bool isDescending) + object tplOrderBy(string method, bool isDescending) { if (callExp.Arguments.Count == 2) { var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; _select.OrderByReflection(arg1, isDescending); - return default(TResult); + return tresult.CreateInstanceGetDefaultValue(); } return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); } @@ -106,7 +108,7 @@ namespace FreeSql.Extensions.Linq { case "Any": if (callExp.Arguments.Count == 2) _select.InternalWhere(callExp.Arguments[1]); - return (TResult)(object)_select.Any(); + return _select.Any(); case "AsQueryable": break; @@ -123,13 +125,13 @@ namespace FreeSql.Extensions.Linq var dywhere = callExp.Arguments[1].GetConstExprValue(); if (dywhere == null) return throwCallExp($" 参数值不能为 null"); _select.WhereDynamic(dywhere); - return (TResult)(object)_select.Any(); + return _select.Any(); } return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); case "Count": if (callExp.Arguments.Count == 2) _select.InternalWhere(callExp.Arguments[1]); - return (TResult)Utils.GetDataReaderValue(typeof(TResult), _select.Count()); - + return Utils.GetDataReaderValue(tresult, _select.Count()); + case "Distinct": if (callExp.Arguments.Count == 1) { @@ -153,25 +155,24 @@ namespace FreeSql.Extensions.Linq isfirst = true; break; - case "OrderBy": + case "OrderBy": tplOrderBy("OrderByReflection", false); break; - case "OrderByDescending": - tplOrderBy("OrderByReflection", true); + case "OrderByDescending": + tplOrderBy("OrderByReflection", true); break; - case "ThenBy": - tplOrderBy("OrderByReflection", false); + case "ThenBy": + tplOrderBy("OrderByReflection", false); break; - case "ThenByDescending": - tplOrderBy("OrderByReflection", true); + case "ThenByDescending": + tplOrderBy("OrderByReflection", true); break; case "Where": var whereParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; if (whereParam.Parameters.Count == 1) { - if (groupBy != null) groupBy.InternalHaving(whereParam); - else _select.InternalWhere(whereParam); + _select.InternalWhere(whereParam); break; } return throwCallExp(" 不支持"); @@ -185,7 +186,7 @@ namespace FreeSql.Extensions.Linq case "ToList": if (callExp.Arguments.Count == 1) - return (TResult)(object)_select.ToList(); + return _select.ToList(); return throwCallExp(" 不支持"); case "Select": @@ -242,37 +243,21 @@ namespace FreeSql.Extensions.Linq case "GroupBy": return throwCallExp(" 不支持"); - if (callExp.Arguments.Count == 2) //TODO: 待实现 - { - var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression; - - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = -10000; //临时规则,不返回 as1 - - _select._commonExpression.ReadAnonymousField(_select._tables, field, map, ref index, arg1, null, _select._whereCascadeExpression, false); //不走 DTO 映射 - var sql = field.ToString(); - _select.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); - groupBy = new SelectGroupingProvider(_select._orm, _select, map, sql, _select._commonExpression, _select._tables); - break; - } - return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"); - default: return throwCallExp(" 不支持"); } } + if (tresult == null) return null; if (isfirst) { _select.Limit(1); if (_select._selectExpression != null) - return (TResult)(object)_select.InternalToList(_select._selectExpression).FirstOrDefault(); - return (TResult)(object)_select.ToList().FirstOrDefault(); + return _select.InternalToList(_select._selectExpression).FirstOrDefault(); + return _select.ToList().FirstOrDefault(); } if (_select._selectExpression != null) - return (TResult)(object)_select.InternalToList(_select._selectExpression); - return (TResult)(object)_select.ToList(); + return _select.InternalToList(_select._selectExpression); + return _select.ToList(); } - public object Execute(Expression expression) => throw new NotImplementedException(); } } diff --git a/FreeSql.Tests/FreeSql.Tests/Queryable/ExprHelperTest.cs b/FreeSql.Tests/FreeSql.Tests/Linq/ExprHelperTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests/Queryable/ExprHelperTest.cs rename to FreeSql.Tests/FreeSql.Tests/Linq/ExprHelperTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs b/FreeSql.Tests/FreeSql.Tests/Linq/ISelectLinqToSqlTests.cs similarity index 99% rename from FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs rename to FreeSql.Tests/FreeSql.Tests/Linq/ISelectLinqToSqlTests.cs index 555d7c83..584b94c3 100644 --- a/FreeSql.Tests/FreeSql.Tests/LinqToSql/SqliteLinqToSqlTests.cs +++ b/FreeSql.Tests/FreeSql.Tests/Linq/ISelectLinqToSqlTests.cs @@ -3,10 +3,8 @@ using System; using System.Linq; using Xunit; -namespace FreeSql.Tests.LinqToSql +namespace FreeSql.Tests.Linq { - - class TestLinqToSql { public Guid id { get; set; } @@ -29,7 +27,7 @@ namespace FreeSql.Tests.LinqToSql public DateTime createtime { get; set; } = DateTime.Now; } - public class SqliteLinqToSqlTests + public class ISelectLinqToSqlTests { [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableLinqToSqlTests.cs b/FreeSql.Tests/FreeSql.Tests/Linq/QueryableLinqToSqlTests.cs similarity index 88% rename from FreeSql.Tests/FreeSql.Tests/Queryable/QueryableLinqToSqlTests.cs rename to FreeSql.Tests/FreeSql.Tests/Linq/QueryableLinqToSqlTests.cs index f028f93a..6d234d0b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableLinqToSqlTests.cs +++ b/FreeSql.Tests/FreeSql.Tests/Linq/QueryableLinqToSqlTests.cs @@ -58,29 +58,6 @@ namespace FreeSql.Tests.Linq Assert.Equal(item.id, t1[0].id); } - [Fact] - public void GroupBy() - { - //var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() }; - //g.sqlite.Insert().AppendData(item).ExecuteAffrows(); - - //var t1 = (from a in g.sqlite.Select().AsQueryable() - // where a.id == item.id - // group a by new { a.id, a.name } into g - // select new - // { - // g.Key.id, - // g.Key.name, - // cou = g.Count(), - // avg = g.Average(x => x.click), - // sum = g.Sum(x => x.click), - // max = g.Max(x => x.click), - // min = g.Min(x => x.click) - // }).ToList(); - //Assert.True(t1.Any()); - //Assert.Equal(item.id, t1.First().id); - } - [Fact] public void CaseWhen() { diff --git a/FreeSql.Tests/FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs new file mode 100644 index 00000000..6bc941f9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs @@ -0,0 +1,50 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using NpgsqlTypes; +using Npgsql.LegacyPostgis; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Threading; +using System.Data.SqlClient; +using kwlib; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace FreeSql.Tests.Linq +{ + public class QueryableRestoreToSelectTest + { + class qt01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + + [Navigate(nameof(qt01_item.qt01id))] + public List items { get; set; } + } + class qt01_item + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public int qt01id { get; set; } + } + IFreeSql fsql => g.sqlite; + + [Fact] + public void RestoreToSelect() + { + Assert.Equal(fsql.Select().Skip(2).First(a => a.name), fsql.Select().AsQueryable().Skip(2).Take(1).RestoreToSelect().First(a => a.name)); + Assert.Equal(fsql.Select().Skip(2).First(a => new { a.name }).name, fsql.Select().AsQueryable().Skip(2).Take(1).RestoreToSelect().First(a => new { a.name }).name); + } + } + +} diff --git a/FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs b/FreeSql.Tests/FreeSql.Tests/Linq/QueryableTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests/Queryable/QueryableTest.cs rename to FreeSql.Tests/FreeSql.Tests/Linq/QueryableTest.cs diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 45ce906d..c787b5eb 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -214,7 +214,7 @@ public static partial class FreeSqlGlobalExtensions } /// - /// 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + /// 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。 /// /// /// diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 12b3cc3e..18542e5f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2281,6 +2281,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 }) + + + + + + 可自定义解析表达式 @@ -2801,6 +2932,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2871,6 +3008,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3092,7 +3235,7 @@ - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。 + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。 @@ -3503,167 +3646,4 @@ - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - From 0154600d0a08f920970ebd363c83d8887d6e8ec4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 10 Apr 2020 22:53:35 +0800 Subject: [PATCH 0559/1029] 1.4.0-preview20200411 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 18 insertions(+), 34 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d46770b5..0733ad8a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index c843c61a..008461aa 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 7321d6ec..1eed7644 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index bd2dc8a5..260e5463 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 202f9ed5..ce12e62e 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 5effd1f6..9acab912 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview20200410 + 1.4.0-preview20200411 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 78004db7..2a75956b 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 79d8c385..c3560d64 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 165be8ac..dbc7cdda 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -115,13 +115,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -216,15 +209,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index fee9d51a..d2776bed 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 32663832..95bd0d70 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index d21c7874..e37aeb44 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6238bd2e..b41d9d1f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 096d7532..6e42c090 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d83dc775..682c66c8 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2373f1fc..9871286a 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index af83d6d4..7e25d911 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index aaca5d5b..fbcc04ef 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c03fc76d..f34a4acf 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200410 + 1.4.0-preview20200411 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From bd79fc803e239aa1fedda8b01415aaa69a670d26 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 11 Apr 2020 12:02:50 +0800 Subject: [PATCH 0560/1029] rename DbContext Internal Method --- FreeSql.DbContext/DbContext/DbContext.cs | 12 +-- FreeSql.DbContext/DbContext/DbContextAsync.cs | 86 +++++++++--------- .../DbContext/DbContextScopedFreeSql.cs | 8 +- FreeSql.DbContext/DbContext/DbContextSync.cs | 91 ++++++++++--------- FreeSql.DbContext/DbSet/DbSet.cs | 4 +- FreeSql.DbContext/DbSet/DbSetAsync.cs | 24 ++--- FreeSql.DbContext/DbSet/DbSetSync.cs | 24 ++--- FreeSql.DbContext/FreeSql.DbContext.xml | 12 +++ .../ContextSet/RepositoryDbContext.cs | 4 +- 9 files changed, 140 insertions(+), 125 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 49f044f1..42188cb3 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -225,7 +225,7 @@ namespace FreeSql #endif #endregion - #region Queue Action + #region Queue PreCommand public class EntityChangeReport { public class ChangeInfo @@ -244,7 +244,7 @@ namespace FreeSql } internal List _entityChangeReport = new List(); public enum EntityChangeType { Insert, Update, Delete, SqlRaw } - internal class ExecCommandInfo + internal class PrevCommandInfo { public EntityChangeType changeType { get; set; } public IDbSet dbSet { get; set; } @@ -252,11 +252,11 @@ namespace FreeSql public Type entityType { get; set; } public object state { get; set; } } - Queue _actions = new Queue(); + Queue _prevCommands = new Queue(); internal int _affrows = 0; - internal void EnqueueAction(EntityChangeType changeType, IDbSet dbSet, Type stateType, Type entityType, object state) => - _actions.Enqueue(new ExecCommandInfo { changeType = changeType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state }); + internal void EnqueuePreCommand(EntityChangeType changeType, IDbSet dbSet, Type stateType, Type entityType, object state) => + _prevCommands.Enqueue(new PrevCommandInfo { changeType = changeType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state }); #endregion ~DbContext() => this.Dispose(); @@ -266,7 +266,7 @@ namespace FreeSql if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { - _actions.Clear(); + _prevCommands.Clear(); foreach (var set in _listSet) try diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 88969bd7..9195cd1b 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -1,8 +1,9 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Linq.Expressions; +using System.Reflection; using System.Threading.Tasks; #if net40 @@ -13,59 +14,58 @@ namespace FreeSql { async public virtual Task SaveChangesAsync() { - await ExecCommandAsync(); + await FlushCommandAsync(); return SaveChangesSuccess(); } - static Dictionary>>> _dicExecCommandDbContextBatchAsync = new Dictionary>>>(); - async internal Task ExecCommandAsync() + static ConcurrentDictionary>>> _dicFlushCommandDbSetBatchAsync = new ConcurrentDictionary>>>(); + async internal Task FlushCommandAsync() { - if (isExecCommanding) return; - if (_actions.Any() == false) return; - isExecCommanding = true; + if (isFlushCommanding) return; + if (_prevCommands.Any() == false) return; + isFlushCommanding = true; - ExecCommandInfo oldinfo = null; + PrevCommandInfo oldinfo = null; var states = new List(); - Func> dbContextBatch = methodName => + Task dbsetBatch(string method) { - if (_dicExecCommandDbContextBatchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) - { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + var tryfunc = _dicFlushCommandDbSetBatchAsync + .GetOrAdd(oldinfo.stateType, stateType => new ConcurrentDictionary>>()) + .GetOrAdd(method, methodName => + { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - var returnTarget = Expression.Label(typeof(Task)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(Task))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } + var returnTarget = Expression.Label(typeof(Task)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + return Expression.Lambda>>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(Task))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + }); return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Func funcDelete = async () => + } + async Task funcDelete() { - _affrows += await dbContextBatch("DbContextBatchRemoveAsync"); + _affrows += await dbsetBatch("DbContextBatchRemoveAsync"); + states.Clear(); + } + async Task funcInsert() + { + _affrows += await dbsetBatch("DbContextBatchAddAsync"); states.Clear(); }; - Func funcInsert = async () => - { - _affrows += await dbContextBatch("DbContextBatchAddAsync"); - states.Clear(); - }; - Func funcUpdate = async (isLiveUpdate) => + async Task funcUpdate(bool isLiveUpdate) { var affrows = 0; - if (isLiveUpdate) affrows = await dbContextBatch("DbContextBatchUpdateNowAsync"); - else affrows = await dbContextBatch("DbContextBatchUpdateAsync"); + if (isLiveUpdate) affrows = await dbsetBatch("DbContextBatchUpdateNowAsync"); + else affrows = await dbsetBatch("DbContextBatchUpdateAsync"); if (affrows == -999) { //最后一个元素已被删除 states.RemoveAt(states.Count - 1); @@ -87,13 +87,13 @@ namespace FreeSql } }; - while (_actions.Any() || states.Any()) + while (_prevCommands.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; + var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null; if (oldinfo == null) oldinfo = info; var isLiveUpdate = false; - if (_actions.Any() == false && states.Any() || + if (_prevCommands.Any() == false && states.Any() || info != null && oldinfo.changeType != info.changeType || info != null && oldinfo.stateType != info.stateType || info != null && oldinfo.entityType != info.entityType) @@ -130,7 +130,7 @@ namespace FreeSql oldinfo = info; } } - isExecCommanding = false; + isFlushCommanding = false; } } } diff --git a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs index b188b937..e1b0b1ef 100644 --- a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs +++ b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs @@ -35,14 +35,14 @@ namespace FreeSql public ISelect Select() where T1 : class { - _resolveDbContext()?.ExecCommand(); + _resolveDbContext()?.FlushCommand(); return _originalFsql.Select().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction(false)); } public ISelect Select(object dywhere) where T1 : class => Select().WhereDynamic(dywhere); public IDelete Delete() where T1 : class { - _resolveDbContext()?.ExecCommand(); + _resolveDbContext()?.FlushCommand(); return _originalFsql.Delete().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); } public IDelete Delete(object dywhere) where T1 : class => Delete().WhereDynamic(dywhere); @@ -50,7 +50,7 @@ namespace FreeSql public IUpdate Update() where T1 : class { var db = _resolveDbContext(); - db?.ExecCommand(); + db?.FlushCommand(); var update = _originalFsql.Update().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) update.NoneParameter(db.Options.NoneParameter.Value); return update; @@ -60,7 +60,7 @@ namespace FreeSql public IInsert Insert() where T1 : class { var db = _resolveDbContext(); - db?.ExecCommand(); + db?.FlushCommand(); var insert = _originalFsql.Insert().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) insert.NoneParameter(db.Options.NoneParameter.Value); return insert; diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs index 88fc4ca5..d6ad896d 100644 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -1,8 +1,9 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Linq.Expressions; +using System.Reflection; namespace FreeSql { @@ -26,60 +27,62 @@ namespace FreeSql } public virtual int SaveChanges() { - ExecCommand(); + FlushCommand(); return SaveChangesSuccess(); } - static Dictionary>> _dicExecCommandDbContextBatch = new Dictionary>>(); - bool isExecCommanding = false; - internal void ExecCommand() + static ConcurrentDictionary>> _dicFlushCommandDbSetBatch = new ConcurrentDictionary>>(); + bool isFlushCommanding = false; + /// + /// 刷新队列中的命令 + /// + internal void FlushCommand() { - if (isExecCommanding) return; - if (_actions.Any() == false) return; - isExecCommanding = true; + if (isFlushCommanding) return; + if (_prevCommands.Any() == false) return; + isFlushCommanding = true; - ExecCommandInfo oldinfo = null; + PrevCommandInfo oldinfo = null; var states = new List(); - Func dbContextBatch = methodName => + int dbsetBatch(string method) { - if (_dicExecCommandDbContextBatch.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) - { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + var tryfunc = _dicFlushCommandDbSetBatch + .GetOrAdd(oldinfo.stateType, stateType => new ConcurrentDictionary>()) + .GetOrAdd(method, methodName => + { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - var returnTarget = Expression.Label(typeof(int)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(int))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } + var returnTarget = Expression.Label(typeof(int)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + return Expression.Lambda>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(int))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + }); return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Action funcDelete = () => + } + void funcDelete() { - _affrows += dbContextBatch("DbContextBatchRemove"); + _affrows += dbsetBatch("DbContextBatchRemove"); + states.Clear(); + } + void funcInsert() + { + _affrows += dbsetBatch("DbContextBatchAdd"); states.Clear(); }; - Action funcInsert = () => - { - _affrows += dbContextBatch("DbContextBatchAdd"); - states.Clear(); - }; - Action funcUpdate = isLiveUpdate => + void funcUpdate(bool isLiveUpdate) { var affrows = 0; - if (isLiveUpdate) affrows = dbContextBatch("DbContextBatchUpdateNow"); - else affrows = dbContextBatch("DbContextBatchUpdate"); + if (isLiveUpdate) affrows = dbsetBatch("DbContextBatchUpdateNow"); + else affrows = dbsetBatch("DbContextBatchUpdate"); if (affrows == -999) { //最后一个元素已被删除 states.RemoveAt(states.Count - 1); @@ -101,13 +104,13 @@ namespace FreeSql } }; - while (_actions.Any() || states.Any()) + while (_prevCommands.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; + var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null; if (oldinfo == null) oldinfo = info; var isLiveUpdate = false; - if (_actions.Any() == false && states.Any() || + if (_prevCommands.Any() == false && states.Any() || info != null && oldinfo.changeType != info.changeType || info != null && oldinfo.stateType != info.stateType || info != null && oldinfo.entityType != info.entityType) @@ -144,7 +147,7 @@ namespace FreeSql oldinfo = info; } } - isExecCommanding = false; + isFlushCommanding = false; } } } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 32efd9dd..1314a0d1 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -32,7 +32,7 @@ namespace FreeSql protected virtual ISelect OrmSelect(object dywhere) { - DbContextExecCommand(); //查询前先提交,否则会出脏读 + DbContextFlushCommand(); //查询前先提交,否则会出脏读 return _db.OrmOriginal.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); } @@ -70,7 +70,7 @@ namespace FreeSql protected virtual IDelete OrmDelete(object dywhere) => _db.OrmOriginal.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); internal void EnqueueToDbContext(DbContext.EntityChangeType changeType, EntityState state) => - _db.EnqueueAction(changeType, this, typeof(EntityState), _entityType, state); + _db.EnqueuePreCommand(changeType, this, typeof(EntityState), _entityType, state); internal void IncrAffrows(int affrows) => _db._affrows += affrows; diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 1e756f53..774269ee 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -14,10 +14,10 @@ namespace FreeSql { partial class DbSet { - Task DbContextExecCommandAsync() + Task DbContextFlushCommandAsync() { _dicUpdateTimes.Clear(); - return _db.ExecCommandAsync(); + return _db.FlushCommandAsync(); } async Task DbContextBatchAddAsync(EntityState[] adds) @@ -43,7 +43,7 @@ namespace FreeSql case DataType.OdbcPostgreSQL: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); @@ -54,7 +54,7 @@ namespace FreeSql } else { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); @@ -67,7 +67,7 @@ namespace FreeSql default: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); @@ -102,7 +102,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); @@ -149,7 +149,7 @@ namespace FreeSql throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 OneToMany 或 ManyToMany 特性"); } - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; _db.Options.EnableAddOrUpdateNavigateList = false; try @@ -157,7 +157,7 @@ namespace FreeSql await AddOrUpdateNavigateListAsync(item, false, propertyName); if (tref.RefType == Internal.Model.TableRefType.OneToMany) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); //删除没有保存的数据,求出主体的条件 var deleteWhereParentParam = Expression.Parameter(typeof(object), "a"); Expression whereParentExp = null; @@ -401,7 +401,7 @@ namespace FreeSql foreach (var item in data) { if (_dicUpdateTimes.ContainsKey(item)) - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); _dicUpdateTimes.Add(item, 1); var state = CreateEntityState(item); @@ -429,7 +429,7 @@ namespace FreeSql /// async public Task RemoveAsync(Expression> predicate) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); return await this.OrmDelete(null).Where(predicate).ExecuteAffrowsAsync(); } #endregion @@ -449,10 +449,10 @@ namespace FreeSql if (flagExists == true && CanUpdate(data, false)) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var affrows = _db._affrows; await UpdateRangePrivAsync(new[] { data }, false); - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); affrows = _db._affrows - affrows; if (affrows > 0) return; } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index b49f5542..039fed10 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -13,10 +13,10 @@ namespace FreeSql partial class DbSet { - void DbContextExecCommand() + void DbContextFlushCommand() { _dicUpdateTimes.Clear(); - _db.ExecCommand(); + _db.FlushCommand(); } int DbContextBatchAdd(EntityState[] adds) @@ -42,7 +42,7 @@ namespace FreeSql case DataType.OdbcPostgreSQL: if (_tableIdentitys.Length == 1) { - DbContextExecCommand(); + DbContextFlushCommand(); var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); @@ -53,7 +53,7 @@ namespace FreeSql } else { - DbContextExecCommand(); + DbContextFlushCommand(); var newval = this.OrmInsert(data).ExecuteInserted().First(); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); @@ -66,7 +66,7 @@ namespace FreeSql default: if (_tableIdentitys.Length == 1) { - DbContextExecCommand(); + DbContextFlushCommand(); var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); @@ -105,7 +105,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: - DbContextExecCommand(); + DbContextFlushCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); @@ -161,7 +161,7 @@ namespace FreeSql throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 OneToMany 或 ManyToMany 特性"); } - DbContextExecCommand(); + DbContextFlushCommand(); var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; _db.Options.EnableAddOrUpdateNavigateList = false; try @@ -169,7 +169,7 @@ namespace FreeSql AddOrUpdateNavigateList(item, false, propertyName); if (tref.RefType == Internal.Model.TableRefType.OneToMany) { - DbContextExecCommand(); + DbContextFlushCommand(); //删除没有保存的数据,求出主体的条件 var deleteWhereParentParam = Expression.Parameter(typeof(object), "a"); Expression whereParentExp = null; @@ -442,7 +442,7 @@ namespace FreeSql foreach (var item in data) { if (_dicUpdateTimes.ContainsKey(item)) - DbContextExecCommand(); + DbContextFlushCommand(); _dicUpdateTimes.Add(item, 1); var state = CreateEntityState(item); @@ -488,7 +488,7 @@ namespace FreeSql /// public int Remove(Expression> predicate) { - DbContextExecCommand(); + DbContextFlushCommand(); return this.OrmDelete(null).Where(predicate).ExecuteAffrows(); } #endregion @@ -512,10 +512,10 @@ namespace FreeSql if (flagExists == true && CanUpdate(data, false)) { - DbContextExecCommand(); + DbContextFlushCommand(); var affrows = _db._affrows; UpdateRangePriv(new[] { data }, false); - DbContextExecCommand(); + DbContextFlushCommand(); affrows = _db._affrows - affrows; if (affrows > 0) return; } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dbc7cdda..03dcd971 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -67,6 +67,11 @@ 实体变化事件 + + + 刷新队列中的命令 + + 是否开启一对多,多对多级联保存功能 @@ -115,6 +120,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 7638d46d..458f4d65 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -76,14 +76,14 @@ namespace FreeSql } public override int SaveChanges() { - ExecCommand(); + FlushCommand(); return SaveChangesSuccess(); } #if net40 #else async public override Task SaveChangesAsync() { - await ExecCommandAsync(); + await FlushCommandAsync(); return SaveChangesSuccess(); } #endif From 613940df2091fbd917587db97648ac6ce4d1aecc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 12 Apr 2020 19:00:29 +0800 Subject: [PATCH 0561/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20MySql=20?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E5=8F=8D=E6=96=9C=E6=9D=A0=E6=97=A0?= =?UTF-8?q?=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlCodeFirstTest.cs | 7 ++++++- .../Dameng/DamengCodeFirstTest.cs | 7 ++++++- .../Default/OdbcCodeFirstTest.cs | 7 ++++++- .../MySql/MySqlCodeFirstTest.cs | 7 ++++++- .../Oracle/OracleCodeFirstTest.cs | 7 ++++++- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 7 ++++++- .../SqlServer/SqlServerCodeFirstTest.cs | 9 +++++++-- .../FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs | 7 ++++++- FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 7 ++++++- .../FreeSql.Tests/Oracle/OracleCodeFirstTest.cs | 7 ++++++- .../FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs | 7 ++++++- .../FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs | 9 +++++++-- .../FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs | 7 ++++++- Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs | 8 ++++---- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 6 +++--- 15 files changed, 87 insertions(+), 22 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index a00a399b..fed6cd4f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -275,7 +275,7 @@ namespace FreeSql.Tests.MySqlConnector testFieldSByteNullable = 99, testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, - testFieldString = "йstring", + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), testFieldUInt = uint.MaxValue, @@ -288,6 +288,11 @@ namespace FreeSql.Tests.MySqlConnector }; item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index c5120439..0fcc7897 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -270,7 +270,7 @@ namespace FreeSql.Tests.Odbc.Dameng SByteNullable = 99, Short = short.MaxValue, ShortNullable = short.MinValue, - String = "йstring", + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -287,6 +287,11 @@ namespace FreeSql.Tests.Odbc.Dameng item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs index 1859e308..ed20c3ba 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs @@ -98,7 +98,7 @@ namespace FreeSql.Tests.Odbc.Default testFieldSByteNullable = sbyte.MinValue, testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, - testFieldString = "我是中国人string", + testFieldString = "我是中国人string'\\?!@#$%^&*()_+{}}{~?><<>", testFieldUInt = uint.MaxValue, testFieldUIntNullable = uint.MinValue, testFieldULong = ulong.MaxValue, @@ -116,6 +116,11 @@ namespace FreeSql.Tests.Odbc.Default var item3 = insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index ebc6c398..967151b0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -244,7 +244,7 @@ namespace FreeSql.Tests.Odbc.MySql testFieldSByteNullable = 99, testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, - testFieldString = "йstring", + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), testFieldUInt = uint.MaxValue, @@ -263,6 +263,11 @@ namespace FreeSql.Tests.Odbc.MySql item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs index 7eccb3bb..a9e24fc5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -270,7 +270,7 @@ namespace FreeSql.Tests.Odbc.Oracle SByteNullable = 99, Short = short.MaxValue, ShortNullable = short.MinValue, - String = "йstring", + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -287,6 +287,11 @@ namespace FreeSql.Tests.Odbc.Oracle item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs index 179a66d8..c6d33cb5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -182,7 +182,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL testFieldSByteNullable = sbyte.MinValue, testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, - testFieldString = "йString", + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", testFieldTimeSpan = TimeSpan.FromDays(1), testFieldTimeSpanNullable = TimeSpan.FromSeconds(90), testFieldUInt = uint.MaxValue, @@ -200,6 +200,11 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var item3 = insert.AppendData(item2).ExecuteInserted().First(); var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); + newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index 1eb1d44a..a0e1bb2d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -178,7 +178,7 @@ namespace FreeSql.Tests.Odbc.SqlServer testFieldSByteNullable = sbyte.MinValue, testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, - testFieldString = "йstring", + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(30), testFieldUInt = uint.MaxValue, @@ -197,7 +197,12 @@ namespace FreeSql.Tests.Odbc.SqlServer var sqlTestUpdate = g.sqlserver.Update().SetSource(item3NP).NoneParameter().ToSql(); var item3 = insert.AppendData(item2).ExecuteInserted(); - var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + var newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted(); + newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs index 826cb13b..e11d0b2b 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -266,7 +266,7 @@ namespace FreeSql.Tests.MsAccess SByteNullable = 99, Short = short.MaxValue, ShortNullable = short.MinValue, - String = "йstring", + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -279,6 +279,11 @@ namespace FreeSql.Tests.MsAccess }; item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index b3ccdd26..27a3ab52 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -274,7 +274,7 @@ namespace FreeSql.Tests.MySql testFieldSByteNullable = 99, testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, - testFieldString = "йstring", + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), testFieldUInt = uint.MaxValue, @@ -293,6 +293,11 @@ namespace FreeSql.Tests.MySql item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 57da44cf..8080c0fa 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -368,7 +368,7 @@ namespace FreeSql.Tests.Oracle SByteNullable = 99, Short = short.MaxValue, ShortNullable = short.MinValue, - String = "йstring", + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -385,6 +385,11 @@ namespace FreeSql.Tests.Oracle item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index 700f2d6d..ca7ab03e 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -353,7 +353,7 @@ namespace FreeSql.Tests.PostgreSQL testFieldShortArray = new short[] { 1, 2, 3, 4, 5 }, testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 }, testFieldShortNullable = short.MinValue, - testFieldString = "йString", + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", testFieldStringArray = new[] { "йString1", "йString2", null, "йString3" }, testFieldTimeSpan = TimeSpan.FromDays(1), testFieldTimeSpanArray = new[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }, @@ -385,6 +385,11 @@ namespace FreeSql.Tests.PostgreSQL var item3 = insert.AppendData(item2).ExecuteInserted().First(); var newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); + newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 368eddf8..a835f5e5 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -181,7 +181,7 @@ namespace FreeSql.Tests.SqlServer testFieldSByteNullable = sbyte.MinValue, testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, - testFieldString = "йstring", + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(30), testFieldUInt = uint.MaxValue, @@ -200,7 +200,12 @@ namespace FreeSql.Tests.SqlServer var sqlTestUpdate = g.sqlserver.Update().SetSource(item3NP).NoneParameter().ToSql(); var item3 = insert.AppendData(item2).ExecuteInserted(); - var newitem2 = select.Where(a => a.Id == item3NP[0].Id).ToOne(); + var newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted(); + newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index 03b30986..d697b47c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -293,7 +293,7 @@ namespace FreeSql.Tests.Sqlite SByteNullable = 99, Short = short.MaxValue, ShortNullable = short.MinValue, - String = "йstring", + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -306,6 +306,11 @@ namespace FreeSql.Tests.Sqlite }; item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); } diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index 2eeaa75b..17ea6496 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -42,9 +42,9 @@ namespace FreeSql.MySql if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string || param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //只有 mysql 需要处理反斜杠 else if (param is Enum) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)val).ToInt64(); + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //((Enum)val).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) return param; else if (param is DateTime || param is DateTime?) @@ -54,11 +54,11 @@ namespace FreeSql.MySql else if (param is byte[]) return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; else if (param is MygisGeometry) - return string.Concat("ST_GeomFromText('", (param as MygisGeometry).AsText().Replace("'", "''"), "')"); + return string.Concat("ST_GeomFromText('", (param as MygisGeometry).AsText().Replace("'", "''").Replace("\\", "\\\\"), "')"); else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); } protected override DbCommand CreateCommand() diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 41aa2ed3..4b9196ca 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -42,9 +42,9 @@ namespace FreeSql.Odbc.MySql if (param is bool || param is bool?) return (bool)param ? 1 : 0; else if (param is string || param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //只有 mysql 需要处理反斜杠 else if (param is Enum) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)val).ToInt64(); + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //((Enum)val).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) return param; else if (param is DateTime || param is DateTime?) @@ -56,7 +56,7 @@ namespace FreeSql.Odbc.MySql else if (param is IEnumerable) return AddslashesIEnumerable(param, mapType, mapColumn); - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); } protected override DbCommand CreateCommand() From 7ac5f1422d58c811cc2594d88d7078186f3eeded Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 12 Apr 2020 19:25:37 +0800 Subject: [PATCH 0562/1029] v1.3.6 #270 #269 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 27 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 0733ad8a..761fdad6 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index 008461aa..cbd58c5b 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 1eed7644..3a588889 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 260e5463..159c346b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index ce12e62e..5e4d6251 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 9acab912..bcb9111a 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview20200411 + 1.3.6 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 2a75956b..48886d63 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index c3560d64..059e74c4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 03dcd971..19225654 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -221,6 +221,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d2776bed..674677a7 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview20200411 + 1.3.6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 95bd0d70..d53f5878 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index e37aeb44..3036de02 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b41d9d1f..d8548e2b 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6e42c090..d3525807 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 682c66c8..c3cef5b3 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 9871286a..c2a4a162 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7e25d911..2886864f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index fbcc04ef..1d48e516 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f34a4acf..5ce9d360 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview20200411 + 1.3.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 44638a1e97dfe067b4708a8e2303d356027f05d8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 13 Apr 2020 16:26:09 +0800 Subject: [PATCH 0563/1029] add WhereDynamic UnitTests --- .../MySqlConnector/Curd/MySqlDeleteTest.cs | 13 +++++++++++++ .../Dameng/Curd/DamengDeleteTest.cs | 13 +++++++++++++ .../Default/Curd/OdbcDeleteTest.cs | 13 +++++++++++++ .../MySql/Curd/MySqlDeleteTest.cs | 13 +++++++++++++ .../Oracle/Curd/OracleDeleteTest.cs | 13 +++++++++++++ .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 13 +++++++++++++ .../SqlServer/Curd/SqlServerDeleteTest.cs | 13 +++++++++++++ .../MsAccess/Curd/MsAccessDeleteTest.cs | 13 +++++++++++++ .../FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs | 13 +++++++++++++ .../FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs | 13 +++++++++++++ .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 13 +++++++++++++ .../SqlServer/Curd/SqlServerDeleteTest.cs | 13 +++++++++++++ .../FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs | 13 +++++++++++++ 13 files changed, 169 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs index 6d098eb6..558613c3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs @@ -36,6 +36,19 @@ namespace FreeSql.Tests.MySqlConnector sql = g.mysql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM `MultiPkTopic` WHERE (`Id1` = 1 AND `Id2` = 10 OR `Id1` = 2 AND `Id2` = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs index b99edf53..d424fe0e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.Odbc.Dameng sql = g.dameng.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.dameng.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs index 702039c4..65ce7624 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs @@ -36,6 +36,19 @@ namespace FreeSql.Tests.Odbc.Default sql = g.odbc.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.odbc.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM [MultiPkTopic] WHERE ([Id1] = 1 AND [Id2] = 10 OR [Id1] = 2 AND [Id2] = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs index 84b5f642..277df59a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs @@ -36,6 +36,19 @@ namespace FreeSql.Tests.Odbc.MySql sql = g.mysql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM `MultiPkTopic` WHERE (`Id1` = 1 AND `Id2` = 10 OR `Id1` = 2 AND `Id2` = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs index 0cc8be3b..be99ef40 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.Odbc.Oracle sql = g.oracle.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.oracle.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index 33cbd7de..1378d0d9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = g.pgsql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + sql = g.pgsql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"multipktopic\" WHERE (\"id1\" = 1 AND \"id2\" = 10 OR \"id1\" = 2 AND \"id2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs index 7de0c816..89802f75 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = g.sqlserver.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.sqlserver.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM [MultiPkTopic] WHERE ([Id1] = 1 AND [Id2] = 10 OR [Id1] = 2 AND [Id2] = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs index 8155d317..e2fca832 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.MsAccess sql = g.msaccess.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.msaccess.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM [MultiPkTopic] WHERE ([Id1] = 1 AND [Id2] = 10 OR [Id1] = 2 AND [Id2] = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs index 16380704..de9c83a8 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.MySql sql = g.mysql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM `MultiPkTopic` WHERE (`Id1` = 1 AND `Id2` = 10 OR `Id1` = 2 AND `Id2` = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs index f3158cce..6b3cee7f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.Oracle sql = g.oracle.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.oracle.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index f9333d1e..3a0e19d5 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.PostgreSQL sql = g.pgsql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + sql = g.pgsql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"multipktopic\" WHERE (\"id1\" = 1 AND \"id2\" = 10 OR \"id1\" = 2 AND \"id2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs index 9350ea81..713f77f1 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs @@ -45,6 +45,19 @@ namespace FreeSql.Tests.SqlServer sql = g.sqlserver.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.sqlserver.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM [MultiPkTopic] WHERE ([Id1] = 1 AND [Id2] = 10 OR [Id1] = 2 AND [Id2] = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs index 5f1fd2f9..4be2cd43 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs @@ -37,6 +37,19 @@ namespace FreeSql.Tests.Sqlite sql = g.sqlite.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); + + sql = g.sqlite.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MultiPkTopic\" WHERE (\"Id1\" = 1 AND \"Id2\" = 10 OR \"Id1\" = 2 AND \"Id2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } } [Fact] From 5e336a017349082505132777ce5fd291031a5afa Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 13 Apr 2020 19:00:22 +0800 Subject: [PATCH 0564/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20DbFirst=20?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=AD=97=E6=AE=B5=E7=9A=84=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E4=BF=A1=E6=81=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQL/PostgreSQLDbFirstTest.cs | 2 +- FreeSql/DatabaseModel/DBColumnInfo.cs | 4 +++ FreeSql/FreeSql.xml | 5 ++++ .../FreeSql.Provider.MySql/MySqlDbFirst.cs | 7 +++-- .../Dameng/OdbcDamengDbFirst.cs | 10 +++++-- .../MySql/OdbcMySqlDbFirst.cs | 7 +++-- .../Oracle/OdbcOracleDbFirst.cs | 29 +++++++++++++++++-- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 4 ++- .../SqlServer/OdbcSqlServerDbFirst.cs | 14 ++++++--- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 29 +++++++++++++++++-- .../PostgreSQLDbFirst.cs | 4 ++- .../SqlServerDbFirst.cs | 14 ++++++--- .../FreeSql.Provider.Sqlite/SqliteDbFirst.cs | 7 +++-- 13 files changed, 110 insertions(+), 26 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs index 497e9c0f..e32c5ffb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public void GetTablesByDatabase() { - var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[1]); + var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[2]); } } diff --git a/FreeSql/DatabaseModel/DBColumnInfo.cs b/FreeSql/DatabaseModel/DBColumnInfo.cs index 4ede12b5..f20ee737 100644 --- a/FreeSql/DatabaseModel/DBColumnInfo.cs +++ b/FreeSql/DatabaseModel/DBColumnInfo.cs @@ -48,5 +48,9 @@ namespace FreeSql.DatabaseModel /// 备注 /// public string Coment { get; set; } + /// + /// 数据库默认值 + /// + public string DefaultValue { get; set; } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 18542e5f..60f4a9ad 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -440,6 +440,11 @@ 备注 + + + 数据库默认值 + + 枚举类型标识 diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 25bba990..3669cf14 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -238,7 +238,8 @@ ifnull(a.character_maximum_length, 0) 'len', a.column_type, case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', -a.column_comment 'comment' +a.column_comment 'comment', +a.column_default 'default_value' from information_schema.columns a where a.table_schema in ({1}) and {0} ", loc8, databaseIn); @@ -257,6 +258,7 @@ where a.table_schema in ({1}) and {0} bool is_nullable = string.Concat(row[5]) == "1"; bool is_identity = string.Concat(row[6]) == "1"; string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); if (max_length == 0) max_length = -1; if (database.Length == 1) { @@ -272,7 +274,8 @@ where a.table_schema in ({1}) and {0} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 0edc66c7..ff398cc7 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -307,7 +307,8 @@ a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name) and rownum < 2), 0), -b.comments +b.comments, +a.data_default from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name where a.owner in ({1}) and {0} @@ -318,7 +319,7 @@ where a.owner in ({1}) and {0} var ds2 = new List(); foreach (var row in ds) { - var ds2item = new object[8]; + var ds2item = new object[9]; ds2item[0] = row[0]; ds2item[1] = row[1]; ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); @@ -326,6 +327,7 @@ where a.owner in ({1}) and {0} ds2item[5] = string.Concat(row[7]) == "1"; ds2item[6] = string.Concat(row[8]) == "1"; ds2item[7] = string.Concat(row[9]); + ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); } foreach (var row in ds2) @@ -340,6 +342,7 @@ where a.owner in ({1}) and {0} bool is_nullable = string.Concat(row[5]) == "1"; bool is_identity = string.Concat(row[6]) == "1"; string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); if (max_length == 0) max_length = -1; if (database.Length == 1) { @@ -355,7 +358,8 @@ where a.owner in ({1}) and {0} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index 6424cf2a..37e29ab5 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -208,7 +208,8 @@ ifnull(a.character_maximum_length, 0) 'len', a.column_type, case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', -a.column_comment 'comment' +a.column_comment 'comment', +a.column_default 'default_value' from information_schema.columns a where a.table_schema in ({1}) and {0} ", loc8, databaseIn); @@ -227,6 +228,7 @@ where a.table_schema in ({1}) and {0} bool is_nullable = string.Concat(row[5]) == "1"; bool is_identity = string.Concat(row[6]) == "1"; string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); if (max_length == 0) max_length = -1; if (database.Length == 1) { @@ -242,7 +244,8 @@ where a.table_schema in ({1}) and {0} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index 4be9ab2c..35d1dd29 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -250,6 +250,25 @@ where a.owner in ({0})", databaseIn); } loc8.Append(")"); + _orm.Ado.ExecuteNonQuery(CommandType.Text, @" +CREATE OR REPLACE FUNCTION FREESQL_LONG_TO_CHAR_DEFAULT +( + TABLE_NAME VARCHAR, + COLUMN VARCHAR2 +) + RETURN VARCHAR AS + TEXT_C1 VARCHAR2(32767); + SQL_CUR VARCHAR2(2000); +BEGIN + DBMS_OUTPUT.ENABLE(BUFFER_SIZE => NULL); + SQL_CUR := 'SELECT T.DATA_DEFAULT FROM USER_TAB_COLUMNS T WHERE T.TABLE_NAME = '''||TABLE_NAME||''' AND T.COLUMN_NAME='''||COLUMN||''''; + DBMS_OUTPUT.PUT_LINE(SQL_CUR); + EXECUTE IMMEDIATE SQL_CUR + INTO TEXT_C1; + TEXT_C1 := SUBSTR(TEXT_C1, 1, 4000); + RETURN TEXT_C1; +END;"); + sql = string.Format(@" select a.owner || '.' || a.table_name, @@ -261,7 +280,8 @@ a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name) and rownum < 2), 0), -b.comments +to_char(b.comments), +nvl(FREESQL_LONG_TO_CHAR_DEFAULT(a.table_name, a.column_name),'') from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name where a.owner in ({1}) and {0} @@ -272,7 +292,7 @@ where a.owner in ({1}) and {0} var ds2 = new List(); foreach (var row in ds) { - var ds2item = new object[8]; + var ds2item = new object[9]; ds2item[0] = row[0]; ds2item[1] = row[1]; ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); @@ -280,6 +300,7 @@ where a.owner in ({1}) and {0} ds2item[5] = string.Concat(row[7]); ds2item[6] = string.Concat(row[8]); ds2item[7] = string.Concat(row[9]); + ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); } foreach (var row in ds2) @@ -294,6 +315,7 @@ where a.owner in ({1}) and {0} bool is_nullable = string.Concat(row[5]) == "1"; bool is_identity = string.Concat(row[6]) == "1"; string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); if (max_length == 0) max_length = -1; if (database.Length == 1) { @@ -309,7 +331,8 @@ where a.owner in ({1}) and {0} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 24a12ed9..e7115a26 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -238,6 +238,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var is_nullable = string.Concat(row[5]) == "1"; var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); var comment = string.Concat(row[7]); + var defaultValue = string.Concat(row[6]); int attndims = int.Parse(string.Concat(row[8])); string typtype = string.Concat(row[9]); string owner = string.Concat(row[10]); @@ -273,7 +274,8 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index 0242448a..58ed15d7 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -243,13 +243,16 @@ isnull(e.name,'') + '.' + isnull(d.name,'') {0} a inner join sys.types b on b.user_type_id = a.user_type_id left join sys.tables d on d.object_id = a.object_id -left join sys.schemas e on e.schema_id = d.schema_id +left join sys.schemas e on e.schema_id = d.schema_id{2} where {1} "; sql = string.Format(tsql_place, @" ,a.is_nullable 'IsNullable' ,a.is_identity 'IsIdentity' -from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); +,f.text as 'DefaultValue' +from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id"), @" +left join syscomments f on f.id = a.default_object_id +"); if (loc88.Length > 0) { sql += "union all" + @@ -258,7 +261,8 @@ from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); " select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' -from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); +,'' as 'DefaultValue' +from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), ""); } sql = $"use [{db}];{sql};use [{olddatabase}]; "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -275,6 +279,7 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); var comment = string.Concat(row[6]); var is_nullable = bool.Parse(string.Concat(row[7])); var is_identity = bool.Parse(string.Concat(row[8])); + var defaultValue = string.Concat(row[9]); if (max_length == 0) max_length = -1; loc3[object_id].Add(column, new DbColumnInfo @@ -287,7 +292,8 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index b22f8679..d84307ed 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -250,6 +250,25 @@ where a.owner in ({0})", databaseIn); } loc8.Append(")"); + _orm.Ado.ExecuteNonQuery(CommandType.Text, @" +CREATE OR REPLACE FUNCTION FREESQL_LONG_TO_CHAR_DEFAULT +( + TABLE_NAME VARCHAR, + COLUMN VARCHAR2 +) + RETURN VARCHAR AS + TEXT_C1 VARCHAR2(32767); + SQL_CUR VARCHAR2(2000); +BEGIN + DBMS_OUTPUT.ENABLE(BUFFER_SIZE => NULL); + SQL_CUR := 'SELECT T.DATA_DEFAULT FROM USER_TAB_COLUMNS T WHERE T.TABLE_NAME = '''||TABLE_NAME||''' AND T.COLUMN_NAME='''||COLUMN||''''; + DBMS_OUTPUT.PUT_LINE(SQL_CUR); + EXECUTE IMMEDIATE SQL_CUR + INTO TEXT_C1; + TEXT_C1 := SUBSTR(TEXT_C1, 1, 4000); + RETURN TEXT_C1; +END;"); + sql = string.Format(@" select a.owner || '.' || a.table_name, @@ -261,7 +280,8 @@ a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name) and rownum < 2), 0), -b.comments +to_char(b.comments), +nvl(FREESQL_LONG_TO_CHAR_DEFAULT(a.table_name, a.column_name),'') from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name where a.owner in ({1}) and {0} @@ -272,7 +292,7 @@ where a.owner in ({1}) and {0} var ds2 = new List(); foreach (var row in ds) { - var ds2item = new object[8]; + var ds2item = new object[9]; ds2item[0] = row[0]; ds2item[1] = row[1]; ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); @@ -280,6 +300,7 @@ where a.owner in ({1}) and {0} ds2item[5] = string.Concat(row[7]); ds2item[6] = string.Concat(row[8]); ds2item[7] = string.Concat(row[9]); + ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); } foreach (var row in ds2) @@ -294,6 +315,7 @@ where a.owner in ({1}) and {0} bool is_nullable = string.Concat(row[5]) == "1"; bool is_identity = string.Concat(row[6]) == "1"; string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); if (max_length == 0) max_length = -1; if (database.Length == 1) { @@ -309,7 +331,8 @@ where a.owner in ({1}) and {0} DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index d43cbd83..65a9d2f0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -348,6 +348,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var is_nullable = string.Concat(row[5]) == "1"; var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); var comment = string.Concat(row[7]); + var defaultValue = string.Concat(row[6]); int attndims = int.Parse(string.Concat(row[8])); string typtype = string.Concat(row[9]); string owner = string.Concat(row[10]); @@ -383,7 +384,8 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 6b2e21fe..96cbe84a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -246,13 +246,16 @@ isnull(e.name,'') + '.' + isnull(d.name,'') {0} a inner join sys.types b on b.user_type_id = a.user_type_id left join sys.tables d on d.object_id = a.object_id -left join sys.schemas e on e.schema_id = d.schema_id +left join sys.schemas e on e.schema_id = d.schema_id{2} where {1} "; sql = string.Format(tsql_place, @" ,a.is_nullable 'IsNullable' ,a.is_identity 'IsIdentity' -from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); +,f.text as 'DefaultValue' +from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id"), @" +left join syscomments f on f.id = a.default_object_id +"); if (loc88.Length > 0) { sql += "union all" + @@ -261,7 +264,8 @@ from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id")); " select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" ,cast(0 as bit) 'IsNullable' ,a.is_output 'IsIdentity' -from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); +,'' as 'DefaultValue' +from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), ""); } sql = $"use [{db}];{sql};use [{olddatabase}]; "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -278,6 +282,7 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); var comment = string.Concat(row[6]); var is_nullable = bool.Parse(string.Concat(row[7])); var is_identity = bool.Parse(string.Concat(row[8])); + var defaultValue = string.Concat(row[9]); if (max_length == 0) max_length = -1; loc3[object_id].Add(column, new DbColumnInfo @@ -290,7 +295,8 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id")); DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[object_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs index 74908fdd..7c2bae80 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs @@ -172,6 +172,7 @@ namespace FreeSql.Sqlite bool is_identity = string.Concat(row[6]) == "1"; bool is_primary = string.Concat(row[7]) == "1"; string comment = string.Concat(row[8]); + string defaultValue = string.Concat(row[9]); if (max_length == 0) max_length = -1; loc3[table_id].Add(column, new DbColumnInfo { @@ -183,7 +184,8 @@ namespace FreeSql.Sqlite DbTypeText = type, DbTypeTextFull = sqlType, Table = loc2[table_id], - Coment = comment + Coment = comment, + DefaultValue = defaultValue }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); @@ -256,7 +258,7 @@ from {db}.sqlite_master where type = 'table'"; if (dsqlLastIdx > 0) is_identity = dsql.Substring(dsqlIdx.Value, dsqlLastIdx - dsqlIdx.Value).Contains("AUTOINCREMENT"); } - var ds2item = new object[9]; + var ds2item = new object[10]; ds2item[0] = table_id; ds2item[1] = col_name; ds2item[2] = Regex.Replace(string.Concat(col[2]), @"\(\d+(\b*,\b*\d+)?\)", "").ToUpper(); @@ -265,6 +267,7 @@ from {db}.sqlite_master where type = 'table'"; ds2item[6] = is_identity; ds2item[7] = string.Concat(col[5]) == "1" ? 1 : 0; ds2item[8] = ""; + ds2item[9] = string.Concat(col[4]); addColumn(ds2item); } From aa2aac4536928c3809f0b18ef76970bef7746155 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 13 Apr 2020 19:10:37 +0800 Subject: [PATCH 0565/1029] v1.4.0-preview0413 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 761fdad6..df2c1c30 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.3.6 + 1.4.0-preview0413 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index cbd58c5b..cf38556b 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 3a588889..67697dcf 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 159c346b..ccc719b5 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 5e4d6251..b0839035 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index bcb9111a..c5b4bef1 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.3.6 + 1.4.0-preview0413 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 48886d63..0325ae98 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 059e74c4..b66c885a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 674677a7..a44ab16f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.3.6 + 1.4.0-preview0413 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index d53f5878..f6b48a55 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 3036de02..32248c5d 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d8548e2b..e9bc53de 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d3525807..839d7486 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c3cef5b3..12d52cb5 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index c2a4a162..7c6bf219 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2886864f..ff04ea27 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 1d48e516..0020b8bd 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5ce9d360..48297b4f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.3.6 + 1.4.0-preview0413 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From bf5090938afd7532572f575045bab0367377bd4e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 14 Apr 2020 10:15:14 +0800 Subject: [PATCH 0566/1029] update nuget packages --- Examples/benchmarker/benchmarker.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj | 5 +++-- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Examples/benchmarker/benchmarker.csproj b/Examples/benchmarker/benchmarker.csproj index bcc5dc7d..0a83a6e9 100644 --- a/Examples/benchmarker/benchmarker.csproj +++ b/Examples/benchmarker/benchmarker.csproj @@ -6,7 +6,7 @@ - + diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 7fd0f8e7..bad5f21c 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -12,8 +12,9 @@ - - + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 545b25cb..0470c0f1 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -235,7 +235,7 @@ namespace FreeSql.Tests //File.WriteAllBytes(@"C:\Users\28810\Desktop\71500003-0ad69400-289e-11ea-85cb-36a54f52ebc0_write.png", getTestByte.pic); - var ib = new IdleBus(TimeSpan.FromMinutes(10), 2); + var ib = new IdleBus(TimeSpan.FromMinutes(10)); ib.Notice += (_, e2) => Trace.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] 线程{Thread.CurrentThread.ManagedThreadId}:{e2.Log}"); ib.Register("db1", () => new FreeSql.FreeSqlBuilder() diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 839d7486..a11f3924 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 48297b4f..ce8c0f7c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -26,7 +26,7 @@ - + From f8fa15054c8952ab7611ac6ac6259220f313bc1d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 14 Apr 2020 16:12:05 +0800 Subject: [PATCH 0567/1029] =?UTF-8?q?-=20FreeSql.Generator=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20-Match=20=E5=8F=82=E6=95=B0=E5=8F=AA=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=8C=B9=E9=85=8D=E7=9A=84=E8=A1=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index c32b25ca..0a86da2a 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -4,6 +4,7 @@ using System.Drawing; using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading; using Console = Colorful.Console; @@ -18,6 +19,7 @@ namespace FreeSql.Generator DataType ArgsDbType { get; } string ArgsConnectionString { get; } string ArgsFilter { get; } + string ArgsMatch { get; } string ArgsFileName { get; } internal string ArgsOutput { get; private set; } @@ -56,6 +58,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam ArgsNameOptions = new[] { false, false, false, false }; ArgsNameSpace = "MyProject"; ArgsFilter = ""; + ArgsMatch = ""; ArgsFileName = "{name}.cs"; Action setArgsOutput = value => { @@ -112,6 +115,8 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam 默认生成:表+视图+存储过程 如果不想生成视图和存储过程 -Filter View+StoreProcedure + -Match 正则表达式,只生成匹配的表,如:dbo\.TB_.+ + -FileName 文件名,默认:{name}.cs -Output 保存路径,默认为当前 shell 所在目录 @@ -179,6 +184,11 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 ArgsFilter = args[a + 1]; a++; break; + case "-match": + ArgsMatch = args[a + 1]; + if (Regex.IsMatch("", ArgsMatch)) { } //throw + a++; + break; case "-filename": ArgsFileName = args[a + 1]; a++; @@ -214,6 +224,10 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 //开始生成操作 foreach (var table in outputTables) { + if (string.IsNullOrEmpty(ArgsMatch) == false) + { + if (Regex.IsMatch($"{table.Schema}.{table.Name}".TrimStart('.'), ArgsMatch) == false) continue; + } switch (table.Type) { case DatabaseModel.DbTableType.TABLE: @@ -285,7 +299,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 } File.WriteAllText(rebuildBat, $@" -FreeSql.Generator -Razor ""__razor.cshtml.txt"" -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}""{(string.IsNullOrEmpty(ArgsFilter) ? "" : $" -Filter \"{ArgsFilter}\"")} -FileName ""{ArgsFileName}"" +FreeSql.Generator -Razor ""__razor.cshtml.txt"" -NameOptions {string.Join(",", ArgsNameOptions.Select(a => a ? 1 : 0))} -NameSpace {ArgsNameSpace} -DB ""{ArgsDbType},{ArgsConnectionString}""{(string.IsNullOrEmpty(ArgsFilter) ? "" : $" -Filter \"{ArgsFilter}\"")}{(string.IsNullOrEmpty(ArgsMatch) ? "" : $" -Match \"{ArgsMatch}\"")} -FileName ""{ArgsFileName}"" "); Console.WriteFormatted(" OUT -> " + rebuildBat + " (以后) 双击它重新生成实体\r\n", Color.Magenta); ++outputCounter; From 9ad454376e38d3bfcb681b4b0679da2533e25091 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 14 Apr 2020 16:37:30 +0800 Subject: [PATCH 0568/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E4=B8=BB?= =?UTF-8?q?=E9=94=AE=20Guid=20=E8=87=AA=E5=8A=A8=E8=B5=8B=E5=80=BC?= =?UTF-8?q?=E7=9A=84=E4=BC=98=E5=85=88=E7=BA=A7=EF=BC=8C=E4=BD=8E=E4=BA=8E?= =?UTF-8?q?=20Aop.AuditValue=20=E4=BA=8B=E4=BB=B6=EF=BC=88=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E8=87=AA=E5=AE=9A=E4=B9=89=20Guid=20=E5=80=BC?= =?UTF-8?q?=EF=BC=89=EF=BC=9B#274?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/CommonProvider/InsertProvider.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index ca5f7574..6834599f 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -139,6 +139,17 @@ namespace FreeSql.Internal.CommonProvider foreach (var col in table.Columns.Values) { object val = col.GetMapValue(data); + if (orm.Aop.AuditValueHandler != null) + { + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); + orm.Aop.AuditValueHandler(sender, auditArgs); + if (auditArgs.IsChanged) + { + col.SetMapValue(data, val = auditArgs.Value); + if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) + changedDict.Add(col.Attribute.Name, true); + } + } if (col.Attribute.IsPrimary) { if (col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) @@ -153,17 +164,6 @@ namespace FreeSql.Internal.CommonProvider } } } - if (orm.Aop.AuditValueHandler != null) - { - var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); - orm.Aop.AuditValueHandler(sender, auditArgs); - if (auditArgs.IsChanged) - { - col.SetMapValue(data, val = auditArgs.Value); - if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) - changedDict.Add(col.Attribute.Name, true); - } - } } } From 82b612bae6ea975fc724ea770632c8a9b8b498bc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 14 Apr 2020 16:46:43 +0800 Subject: [PATCH 0569/1029] v1.4.0-preview0414 #274 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index df2c1c30..37d9751d 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index cf38556b..a96c1091 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 67697dcf..0ac86b98 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ccc719b5..6a6a3e59 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index b0839035..7e978862 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index c5b4bef1..1beb027c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0413 + 1.4.0-preview0414 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 0325ae98..0ebc8745 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b66c885a..0ca9c563 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index a44ab16f..4a812dd6 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f6b48a55..667027c8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 32248c5d..aa3b83d8 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e9bc53de..286b0788 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a11f3924..852ea2a3 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 12d52cb5..f07f3fdf 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7c6bf219..861060ae 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ff04ea27..c063fca7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0020b8bd..c3e93d5e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ce8c0f7c..ba003c31 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0413 + 1.4.0-preview0414 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 0ac564f801417689b1c0ed598e22d886b3d569a8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 14 Apr 2020 23:38:27 +0800 Subject: [PATCH 0570/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Prov?= =?UTF-8?q?ider.Dameng=20=E5=9F=BA=E4=BA=8E=20DmProvider=20Ado.net=20?= =?UTF-8?q?=E8=AE=BF=E9=97=AE=E8=BE=BE=E6=A2=A6=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=EF=BC=9B#155?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs/Program.cs | 15 + Examples/orm_vs/orm_vs.csproj | 1 + Examples/orm_vs_net40/Program.cs | 16 + Examples/orm_vs_net40/orm_vs_net40.csproj | 4 + FreeSql.DbContext/FreeSql.DbContext.xml | 16 - .../Dameng/Curd/DamengDeleteTest.cs | 106 + .../Dameng/Curd/DamengInsertTest.cs | 278 +++ .../Dameng/Curd/DamengSelectTest.cs | 1788 +++++++++++++++++ .../Dameng/Curd/DamengUpdateTest.cs | 173 ++ .../Dameng/DamengAdo/DamengAdoTest.cs | 66 + .../FreeSql.Tests/Dameng/DamengAopTest.cs | 40 + .../Dameng/DamengCodeFirstTest.cs | 352 ++++ .../FreeSql.Tests/Dameng/DamengDbFirstTest.cs | 25 + .../Dameng/DamengExpression/ConvertTest.cs | 169 ++ .../Dameng/DamengExpression/DateTimeTest.cs | 706 +++++++ .../Dameng/DamengExpression/MathTest.cs | 156 ++ .../Dameng/DamengExpression/OtherTest.cs | 165 ++ .../Dameng/DamengExpression/StringTest.cs | 726 +++++++ .../Dameng/DamengExpression/TimeSpanTest.cs | 293 +++ .../Dameng/MapType/BoolNullableTest.cs | 1571 +++++++++++++++ .../FreeSql.Tests/Dameng/MapType/BoolTest.cs | 1105 ++++++++++ .../Dameng/MapType/DateTimeOffSetTest.cs | 54 + .../FreeSql.Tests/Dameng/MapType/EnumTest.cs | 261 +++ .../Dameng/MapType/ToStringTest.cs | 570 ++++++ .../FreeSql.Tests/FreeSql.Tests.csproj | 7 + FreeSql.Tests/FreeSql.Tests/g.cs | 15 + FreeSql.sln | 15 + FreeSql/DataType.cs | 7 +- FreeSql/FreeSql.xml | 7 +- FreeSql/FreeSqlBuilder.cs | 5 + .../SelectProvider/Select0Provider.cs | 5 +- FreeSql/Internal/UtilsExpressionTree.cs | 35 +- .../Curd/DamengDelete.cs | 31 + .../Curd/DamengInsert.cs | 222 ++ .../Curd/DamengSelect.cs | 184 ++ .../Curd/DamengUpdate.cs | 77 + .../DamengAdo/DamengAdo.cs | 75 + .../DamengAdo/DamengConnectionPool.cs | 253 +++ .../DamengCodeFirst.cs | 469 +++++ .../FreeSql.Provider.Dameng/DamengDbFirst.cs | 559 ++++++ .../DamengExpression.cs | 469 +++++ .../DamengExtensions.cs | 12 + .../FreeSql.Provider.Dameng/DamengProvider.cs | 61 + .../FreeSql.Provider.Dameng/DamengUtils.cs | 102 + .../FreeSql.Provider.Dameng.csproj | 50 + .../lib/DmProvider/DmProvider.1.1.0.nuspec | 21 + .../lib/DmProvider/net20/DmProvider.dll | Bin 0 -> 379904 bytes .../net20/en/DmProvider.resources.dll | Bin 0 -> 20480 bytes .../net20/zh-CN/DmProvider.resources.dll | Bin 0 -> 21504 bytes .../DmProvider/netstandard2.0/DmProvider.dll | Bin 0 -> 384512 bytes .../en/DmProvider.resources.dll | Bin 0 -> 20480 bytes .../zh-CN/DmProvider.resources.dll | Bin 0 -> 21504 bytes .../Dameng/Curd/OdbcDamengSelect.cs | 54 +- .../OdbcDamengAdo/OdbcDamengConnectionPool.cs | 4 +- .../Dameng/OdbcDamengCodeFirst.cs | 6 +- .../Dameng/OdbcDamengDbFirst.cs | 4 +- .../Dameng/OdbcDamengProvider.cs | 6 - .../Dameng/OdbcDamengUtils.cs | 2 +- 58 files changed, 11337 insertions(+), 76 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/MapType/ToStringTest.cs create mode 100644 Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs create mode 100644 Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs create mode 100644 Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs create mode 100644 Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs create mode 100644 Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs create mode 100644 Providers/FreeSql.Provider.Dameng/DamengAdo/DamengConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Dameng/DamengExpression.cs create mode 100644 Providers/FreeSql.Provider.Dameng/DamengExtensions.cs create mode 100644 Providers/FreeSql.Provider.Dameng/DamengProvider.cs create mode 100644 Providers/FreeSql.Provider.Dameng/DamengUtils.cs create mode 100644 Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj create mode 100644 Providers/FreeSql.Provider.Dameng/lib/DmProvider/DmProvider.1.1.0.nuspec create mode 100644 Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/DmProvider.dll create mode 100644 Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/en/DmProvider.resources.dll create mode 100644 Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/zh-CN/DmProvider.resources.dll create mode 100644 Providers/FreeSql.Provider.Dameng/lib/DmProvider/netstandard2.0/DmProvider.dll create mode 100644 Providers/FreeSql.Provider.Dameng/lib/DmProvider/netstandard2.0/en/DmProvider.resources.dll create mode 100644 Providers/FreeSql.Provider.Dameng/lib/DmProvider/netstandard2.0/zh-CN/DmProvider.resources.dll diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index ee8470db..3fdc979b 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -46,8 +46,23 @@ namespace orm_vs } } + static Lazy damengLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Dameng, "server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user") + //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;Max Pool Size=2")) + .UseAutoSyncStructure(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql dameng => damengLazy.Value; + static void Main(string[] args) { + dameng.Select().ToList(); + var testlist1 = fsql.Select().OrderBy(a => a.Id).ToList(); var testlist2 = new List(); fsql.Select().OrderBy(a => a.Id).ToChunk(0, list => diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index 4ee359da..8a489e1f 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -13,6 +13,7 @@ + diff --git a/Examples/orm_vs_net40/Program.cs b/Examples/orm_vs_net40/Program.cs index 66cd43ef..9db52e73 100644 --- a/Examples/orm_vs_net40/Program.cs +++ b/Examples/orm_vs_net40/Program.cs @@ -33,8 +33,24 @@ namespace orm_vs // }); //} + static Lazy damengLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Dameng, "server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user") + //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;Max Pool Size=2")) + .UseAutoSyncStructure(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql dameng => damengLazy.Value; + static void Main(string[] args) { + dameng.Select().ToList(); + + fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements diff --git a/Examples/orm_vs_net40/orm_vs_net40.csproj b/Examples/orm_vs_net40/orm_vs_net40.csproj index 15ca534f..223dc56b 100644 --- a/Examples/orm_vs_net40/orm_vs_net40.csproj +++ b/Examples/orm_vs_net40/orm_vs_net40.csproj @@ -49,6 +49,10 @@ {af9c50ec-6eb6-494b-9b3b-7edba6fd0ebb} FreeSql + + {e74d90e8-1cbc-4677-817b-1ca05ab97937} + FreeSql.Provider.Dameng + {28c6a39c-7ae7-4210-b7b0-0970216637a8} FreeSql.Provider.MySql diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 19225654..8cf53748 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,13 +120,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -221,15 +214,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengDeleteTest.cs new file mode 100644 index 00000000..17ba3c06 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengDeleteTest.cs @@ -0,0 +1,106 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengDeleteTest + { + + IDelete delete => g.dameng.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.dameng.Delete().ToSql()); + var sql = g.dameng.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.dameng.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.dameng.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.dameng.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.dameng.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.dameng.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //var item = g.dameng.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.dameng.Delete().ToSql()); + var sql = g.dameng.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.dameng.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + + sql = g.dameng.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.dameng.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs new file mode 100644 index 00000000..4bb00a07 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs @@ -0,0 +1,278 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengInsertTest + { + + IInsert insert => g.dameng.Insert(); //�������� + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 22:25:38.697071") }); + + var data = new List(); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newtitle0', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6'))", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(0, 'newtitle0', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(100, 'newtitle1', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(200, 'newtitle2', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(300, 'newtitle3', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(400, 'newtitle4', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(500, 'newtitle5', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(600, 'newtitle6', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(700, 'newtitle7', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(800, 'newtitle8', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(900, 'newtitle9', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle0') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle1') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle2') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle3') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle4') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle5') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle6') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle7') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle8') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var data = new List(); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle0') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle1') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle2') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle3') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle4') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle5') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle6') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle7') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle8') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var data = new List(); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(100) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(200) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(300) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(400) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(500) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(600) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(700) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(800) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(900) + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.dameng.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.dameng.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicICs")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + //var items = new List(); + //for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //var items2 = insert.AppendData(items).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newTitle0', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6'))", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(0, 'newTitle0', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(100, 'newTitle1', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(200, 'newTitle2', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(300, 'newTitle3', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(400, 'newTitle4', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(500, 'newTitle5', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(600, 'newTitle6', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(700, 'newTitle7', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(800, 'newTitle8', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(900, 'newTitle9', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(0, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(100, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(200, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(300, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(400, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(500, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(600, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(700, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(800, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(900, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle9') + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle9') + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(0, 'newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(100, 'newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(200, 'newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(300, 'newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(400, 'newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(500, 'newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(600, 'newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(700, 'newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(800, 'newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(900, 'newTitle9') + SELECT 1 FROM DUAL", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs new file mode 100644 index 00000000..c19346f9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -0,0 +1,1788 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengSelectTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.dameng.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.dameng.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.dameng.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.dameng.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.dameng.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.dameng.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.dameng.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.dameng.Insert(items).ExecuteAffrows()); + + //var dt1 = select.ToDataTable(); + //var dt2 = select.ToDataTable("id, 111222"); + //var dt3 = select.ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + g.dameng.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.dameng.Select().ToList(); + var testGuidId6 = g.dameng.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.dameng.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.dameng.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + g.dameng.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.dameng.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = :id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.dameng.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.dameng.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + g.dameng.CodeFirst.SyncStructure(typeof(Topic), "TB_TOPIC"); + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.dameng.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.dameng.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.dameng.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.dameng.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.dameng.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.dameng.Insert(model4s).ExecuteAffrows()); + + var t0 = g.dameng.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.dameng.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.dameng.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.dameng.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.dameng.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.dameng.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.dameng.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.dameng.Insert(model1).ExecuteIdentity(); + + var t1 = g.dameng.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.dameng.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.dameng.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.dameng.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.dameng.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.dameng.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.dameng.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.dameng.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.dameng.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.dameng.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.dameng.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.dameng.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.dameng.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.dameng.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.dameng.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.dameng.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.dameng.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.dameng.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.dameng.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.dameng.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.dameng.Insert(song3).ExecuteIdentity(); + + g.dameng.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.dameng.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.dameng.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.dameng.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.dameng.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.dameng.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.dameng, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.dameng.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.dameng.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.dameng.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.dameng.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.dameng.Select().Count()); + Assert.Equal(3, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.dameng.Select().Count()); + Assert.Equal(3, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.dameng.Select().Count()); + Assert.Equal(3, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.dameng.Select().Count()); + Assert.Equal(5, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.dameng.Select().Count()); + Assert.Equal(5, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.dameng.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.dameng.Select().Count()); + g.dameng.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.dameng.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.dameng.Select().Count()); + Assert.Equal(5, g.dameng.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.dameng; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.dameng; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs new file mode 100644 index 00000000..d9160ab9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs @@ -0,0 +1,173 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengUpdateTest + { + IUpdate update => g.dameng.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.dameng.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL, \"TITLE\" = 'newtitle', \"CREATETIME\" = to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 2 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 3 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 4 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 5 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 6 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 7 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 8 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 9 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 10 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + if (g.dameng.Select().Where(a => a.id1 == 1 && a.id2 == 7).Any() == false) + g.dameng.Insert(new ts_source_mpk { id1 = 1, id2 = 7 }).ExecuteAffrows(); + if (g.dameng.Select().Where(a => a.id1 == 1 && a.id2 == 8).Any() == false) + g.dameng.Insert(new ts_source_mpk { id1 = 1, id2 = 8 }).ExecuteAffrows(); + + sql = g.dameng.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + g.dameng.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ExecuteAffrows(); + var testlist = g.dameng.Select().ToList(); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle', \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10 / 1) WHERE (\"ID\" = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > to_timestamp('2000-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') then 1 else 2 end WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + ? WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.dameng.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs new file mode 100644 index 00000000..796e0a6e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs @@ -0,0 +1,66 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.dameng.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.dameng.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t3 = g.dameng.Ado.Query("select * from \"TB_TOPIC\""); + + var t4 = g.dameng.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + + var t5 = g.dameng.Ado.Query("select * from \"TB_TOPIC\""); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.dameng.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAopTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAopTest.cs new file mode 100644 index 00000000..61b2b2bd --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.dameng.Aop.AuditValue += audit; + + g.dameng.Insert(item).ExecuteAffrows(); + + g.dameng.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs new file mode 100644 index 00000000..e8b064db --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs @@ -0,0 +1,352 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengCodeFirstTest + { + [Fact] + public void StringLength() + { + var dll = g.dameng.CodeFirst.GetComparisonDDLStatements(); + g.dameng.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void ֱ_ֶ() + { + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements<ֱ>(); + g.dameng.CodeFirst.SyncStructure<ֱ>(); + + var item = new ֱ + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.dameng.Insert<ֱ>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.dameng.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.dameng.Update<ֱ>().SetSource(item).ExecuteAffrows()); + item2 = g.dameng.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.dameng.GetRepository<ֱ>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.dameng.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.dameng.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + [Table(Name = "123ֱ")] + class ֱ + { + [Column(IsPrimary = true, Name = "123")] + public Guid { get; set; } + + [Column(Name = "123")] + public string { get; set; } + + [Column(Name = "123ʱ")] + public DateTime ʱ { get; set; } + } + + [Fact] + public void ı_ֶ() + { + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements<ı>(); + g.dameng.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.dameng.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.dameng.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.dameng.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.dameng.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); + g.dameng.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); + + var id = g.dameng.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.dameng.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar2(200) not null", OldName = "title")] + public string title2 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); + if (string.IsNullOrEmpty(sql) == false) + { + Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( + `Id` INT(11) NOT NULL AUTO_INCREMENT, + `Bool` BIT(1) NOT NULL, + `SByte` TINYINT(3) NOT NULL, + `Short` SMALLINT(6) NOT NULL, + `Int` INT(11) NOT NULL, + `Long` BIGINT(20) NOT NULL, + `Byte` TINYINT(3) UNSIGNED NOT NULL, + `UShort` SMALLINT(5) UNSIGNED NOT NULL, + `UInt` INT(10) UNSIGNED NOT NULL, + `ULong` BIGINT(20) UNSIGNED NOT NULL, + `Double` DOUBLE NOT NULL, + `Float` FLOAT NOT NULL, + `Decimal` DECIMAL(10,2) NOT NULL, + `TimeSpan` TIME NOT NULL, + `DateTime` DATETIME NOT NULL, + `Bytes` VARBINARY(255), + `String` VARCHAR(255), + `Guid` VARCHAR(36), + `BoolNullable` BIT(1), + `SByteNullable` TINYINT(3), + `ShortNullable` SMALLINT(6), + `IntNullable` INT(11), + `testFielLongNullable` BIGINT(20), + `ByteNullable` TINYINT(3) UNSIGNED, + `UShortNullable` SMALLINT(5) UNSIGNED, + `UIntNullable` INT(10) UNSIGNED, + `ULongNullable` BIGINT(20) UNSIGNED, + `DoubleNullable` DOUBLE, + `FloatNullable` FLOAT, + `DecimalNullable` DECIMAL(10,2), + `TimeSpanNullable` TIME, + `DateTimeNullable` DATETIME, + `GuidNullable` VARCHAR(36), + `Point` POINT, + `LineString` LINESTRING, + `Polygon` POLYGON, + `MultiPoint` MULTIPOINT, + `MultiLineString` MULTILINESTRING, + `MultiPolygon` MULTIPOLYGON, + `Enum1` ENUM('E1','E2','E3') NOT NULL, + `Enum1Nullable` ENUM('E1','E2','E3'), + `Enum2` SET('F1','F2','F3') NOT NULL, + `Enum2Nullable` SET('F1','F2','F3'), + PRIMARY KEY (`Id`) +) Engine=InnoDB; +", sql); + } + + //sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.dameng.Insert(); + ISelect select => g.dameng.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs new file mode 100644 index 00000000..833dff93 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.dameng.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.dameng.DbFirst.GetTablesByDatabase(); + //var tb = g.dameng.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs new file mode 100644 index 00000000..881fc900 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.DamengExpression +{ + public class ConvertTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/DateTimeTest.cs new file mode 100644 index 00000000..6b7b49e5 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/DateTimeTest.cs @@ -0,0 +1,706 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.DamengExpression +{ + public class DateTimeTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/MathTest.cs new file mode 100644 index 00000000..c330662f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.DamengExpression +{ + public class MathTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/OtherTest.cs new file mode 100644 index 00000000..eec18fe5 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/OtherTest.cs @@ -0,0 +1,165 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.DamengExpression +{ + public class OtherTest + { + + ISelect select => g.dameng.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).Limit(10).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs new file mode 100644 index 00000000..7ac61af1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs @@ -0,0 +1,726 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.DamengExpression +{ + public class StringTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/TimeSpanTest.cs new file mode 100644 index 00000000..1e8a081a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.DamengExpression +{ + public class TimeSpanTest + { + + ISelect select => g.dameng.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..d9b748ac --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.DamengMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.dameng; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolTest.cs new file mode 100644 index 00000000..98d9316e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.DamengMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.dameng; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..26a3e929 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.DamengMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.dameng; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/EnumTest.cs new file mode 100644 index 00000000..44e4c52b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.DamengMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.dameng; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.dameng; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.dameng; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.dameng; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/ToStringTest.cs new file mode 100644 index 00000000..fbe05387 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.DamengMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.dameng; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index bad5f21c..1748585d 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -34,6 +34,7 @@ + @@ -42,4 +43,10 @@ + + + ..\..\Providers\FreeSql.Provider.Dameng\lib\DmProvider\netstandard2.0\DmProvider.dll + + + diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index e64f0553..61c209e1 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -105,4 +105,19 @@ public class g ) .Build()); public static IFreeSql msaccess => msaccessLazy.Value; + + + static Lazy damengLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Dameng, "server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user;poolsize=5") + //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;Max Pool Size=2")) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql dameng => damengLazy.Value; } diff --git a/FreeSql.sln b/FreeSql.sln index d7236979..3ffc7d3d 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -78,6 +78,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.All", "FreeSql.All\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.Linq", "Extensions\FreeSql.Extensions.Linq\FreeSql.Extensions.Linq.csproj", "{57B3F5B0-D46A-4442-8EC6-9A9A784404B7}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Dameng", "Providers\FreeSql.Provider.Dameng\FreeSql.Provider.Dameng.csproj", "{E74D90E8-1CBC-4677-817B-1CA05AB97937}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -472,6 +474,18 @@ Global {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|x64.Build.0 = Release|Any CPU {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|x86.ActiveCfg = Release|Any CPU {57B3F5B0-D46A-4442-8EC6-9A9A784404B7}.Release|x86.Build.0 = Release|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Debug|x64.ActiveCfg = Debug|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Debug|x64.Build.0 = Debug|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Debug|x86.ActiveCfg = Debug|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Debug|x86.Build.0 = Debug|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|Any CPU.Build.0 = Release|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|x64.ActiveCfg = Release|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|x64.Build.0 = Release|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|x86.ActiveCfg = Release|Any CPU + {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -499,6 +513,7 @@ Global {B397A761-F646-41CF-A160-AB6C05DAF2FB} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {57B3F5B0-D46A-4442-8EC6-9A9A784404B7} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} + {E74D90E8-1CBC-4677-817B-1CA05AB97937} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 236f6325..4b60ed38 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -22,7 +22,7 @@ namespace FreeSql Odbc, /// - /// 武汉达梦数据库有限公司 + /// 武汉达梦数据库有限公司,基于 Odbc 的实现 /// OdbcDameng, @@ -30,5 +30,10 @@ namespace FreeSql /// Microsoft Office Access 是由微软发布的关联式数据库管理系统 /// MsAccess, + + /// + /// 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 + /// + Dameng } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 60f4a9ad..468cec8e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -533,7 +533,7 @@ - 武汉达梦数据库有限公司 + 武汉达梦数据库有限公司,基于 Odbc 的实现 @@ -541,6 +541,11 @@ Microsoft Office Access 是由微软发布的关联式数据库管理系统 + + + 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index b72283eb..51a13af8 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -216,6 +216,11 @@ namespace FreeSql if (type == null) throwNotFind("FreeSql.Provider.MsAccess.dll", "FreeSql.MsAccess.MsAccessProvider<>"); break; + case DataType.Dameng: + type = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.Dameng.dll", "FreeSql.Dameng.DamengProvider<>"); + break; + default: throw new Exception("未指定 UseConnectionString 或者 UseConnectionFactory"); } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index d25664fd..95ad2cc5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -803,7 +803,7 @@ namespace FreeSql.Internal.CommonProvider var propGetSetMethod = prop.GetSetMethod(true); Expression readExpAssign = null; //加速缓存 if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor, - Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)), + Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })), //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), Expression.Add(dataIndexExp, Expression.Constant(1)) ); @@ -813,7 +813,7 @@ namespace FreeSql.Internal.CommonProvider if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GetGenericArguments().First(); if (proptypeGeneric.IsEnum || Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor, - Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp)), + Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })), //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), Expression.Add(dataIndexExp, Expression.Constant(1)) ); @@ -1069,6 +1069,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.Sqlite: break; case DataType.OdbcDameng: + case DataType.Dameng: _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; break; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 17e30fdd..98f4a128 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1235,7 +1235,12 @@ namespace FreeSql.Internal public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value"); public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex"); } - internal static MethodInfo MethodDataReaderGetValue = typeof(DbDataReader).GetMethod("GetValue"); + internal static MethodInfo MethodDataReaderGetValue = typeof(Utils).GetMethod("InternalDataReaderGetValue", BindingFlags.Static | BindingFlags.NonPublic); + internal static object InternalDataReaderGetValue(CommonUtils commonUtil, DbDataReader dr, int index) + { + if (commonUtil._orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null; + return dr.GetValue(index); + } internal static RowInfo ExecuteArrayRowReadClassOrTuple(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) { if (string.IsNullOrEmpty(flagStr)) flagStr = "all"; @@ -1252,8 +1257,8 @@ namespace FreeSql.Internal if (type.IsArray) return Expression.Lambda>( Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), Expression.Add(dataIndexExp, Expression.Constant(1)) ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); @@ -1263,8 +1268,8 @@ namespace FreeSql.Internal dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric)) return Expression.Lambda>( Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), Expression.Add(dataIndexExp, Expression.Constant(1)) ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); @@ -1284,8 +1289,8 @@ namespace FreeSql.Internal { Expression read2ExpAssign = null; //加速缓存 if (field.FieldType.IsArray) read2ExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), Expression.Add(dataIndexExp, Expression.Constant(1)) ); else @@ -1294,8 +1299,8 @@ namespace FreeSql.Internal if (fieldtypeGeneric.IsNullableType()) fieldtypeGeneric = fieldtypeGeneric.GetGenericArguments().First(); if (fieldtypeGeneric.IsEnum || dicExecuteArrayRowReadClassOrTuple.ContainsKey(fieldtypeGeneric)) read2ExpAssign = Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + GetDataReaderValueBlockExpression(field.FieldType, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), Expression.Add(dataIndexExp, Expression.Constant(1)) ); else @@ -1336,8 +1341,8 @@ namespace FreeSql.Internal Expression.IfThen( Expression.LessThan(dataIndexExp, rowLenExp), Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), Expression.Add(dataIndexExp, Expression.Constant(1)))) ), Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) @@ -1391,7 +1396,7 @@ namespace FreeSql.Internal var readType = typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) ? trycol.Attribute.MapType : ctorParm.ParameterType; var ispkExp = new List(); - Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)); + Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })); Expression readExpAssign = null; //加速缓存 if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, GetDataReaderValueBlockExpression(readType, readpkvalExp), @@ -1407,7 +1412,7 @@ namespace FreeSql.Internal { //判断主键为空,则整个对象不读取 - //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp))); + //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }))); if (trycol?.Attribute.IsPrimary == true) { ispkExp.Add( @@ -1498,7 +1503,7 @@ namespace FreeSql.Internal var ispkExp = new List(); var propGetSetMethod = prop.GetSetMethod(true); - Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp)); + Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, tryidxExp })); Expression readExpAssign = null; //加速缓存 if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, GetDataReaderValueBlockExpression(readType, readpkvalExp), @@ -1514,7 +1519,7 @@ namespace FreeSql.Internal { //判断主键为空,则整个对象不读取 - //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp))); + //blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }))); if (flagStr.StartsWith("adoQuery") == false && //Ado.Query 的时候不作此判断 trycol?.Attribute.IsPrimary == true) //若主键值为 null,则整行读取出来的对象为 null { diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs new file mode 100644 index 00000000..99141060 --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs @@ -0,0 +1,31 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Dameng.Curd +{ + + class DamengDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public DamengDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + throw new NotImplementedException(); + } + +#if net40 +#else + public override Task> ExecuteDeletedAsync() + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs new file mode 100644 index 00000000..74b1bd6b --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -0,0 +1,222 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Dameng.Curd +{ + + class DamengInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public DamengInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + + public override string ToSql() + { + if (_source == null || _source.Any() == false) return null; + var sb = new StringBuilder(); + sb.Append("INSERT "); + if (_source.Count > 1) sb.Append("ALL"); + + _identCol = null; + var sbtb = new StringBuilder(); + sbtb.Append("INTO "); + sbtb.Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("("); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity) _identCol = col; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sbtb.Append(", "); + sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); + ++colidx; + } + sbtb.Append(") "); + + _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; + var specialParams = new List(); + var didx = 0; + foreach (var d in _source) + { + if (_source.Count > 1) sb.Append("\r\n"); + sb.Append(sbtb); + sb.Append("VALUES"); + sb.Append("("); + var colidx2 = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx2 > 0) sb.Append(", "); + if (string.IsNullOrEmpty(col.DbInsertValue) == false) + sb.Append(col.DbInsertValue); + else + { + object val = col.GetMapValue(d); + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + } + } + ++colidx2; + } + sb.Append(")"); + ++didx; + } + if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); + return sb.ToString(); + } + + ColumnInfo _identCol; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + this.RawExecuteAffrows(); + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + await this.RawExecuteAffrowsAsync(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs new file mode 100644 index 00000000..e93a68f6 --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs @@ -0,0 +1,184 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Dameng.Curd +{ + + class DamengSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field); + if (string.IsNullOrEmpty(_orderby) && _skip > 0) sb.Append(", ROWNUM AS \"__rownum__\""); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) + sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); + if (sbnav.Length > 0) + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + + if (string.IsNullOrEmpty(_orderby)) + { + if (_skip > 0) + sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + } + else + { + if (_skip > 0 && _limit > 0) sb.Insert(0, $"{_select} t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + else if (_skip > 0) sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); + else if (_limit > 0) sb.Insert(0, $"{_select} t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); + } + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs new file mode 100644 index 00000000..db636a0f --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs @@ -0,0 +1,77 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Dameng.Curd +{ + + class DamengUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public DamengUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + + + protected override List RawExecuteUpdated() + { + throw new NotImplementedException(); + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || '+' || "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || '+' || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + ++pkidx; + } + sb.Append(")"); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + + protected override Task> RawExecuteUpdatedAsync() + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs b/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs new file mode 100644 index 00000000..af9caf76 --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs @@ -0,0 +1,75 @@ +using Dm; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.Dameng +{ + class DamengAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public DamengAdo() : base(DataType.Dameng, null, null) { } + public DamengAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Dameng, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Dameng, connectionFactory); + return; + } + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new DamengConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new DamengConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is byte[]) + return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; + else if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("to_timestamp('", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "','YYYY-MM-DD HH24:MI:SS.FF6')"); + else if (param is TimeSpan || param is TimeSpan?) + return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + //if (param is string) return string.Concat('N', nparms[a]); + } + + protected override DbCommand CreateCommand() + { + return new DmCommand(); + } + + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + var rawPool = pool as DamengConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengConnectionPool.cs b/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengConnectionPool.cs new file mode 100644 index 00000000..b10d3749 --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengConnectionPool.cs @@ -0,0 +1,253 @@ +using Dm; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections.Concurrent; +using System.Data; +using System.Data.Common; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Dameng +{ + + class DamengConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + internal string UserId { get; set; } + + public DamengConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + this.UserId = DamengConnectionPool.GetUserId(connectionString); + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + var policy = new DamengConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + } + + public static string GetUserId(string connectionString) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + return userIdMatch.Groups[2].Value.Trim().ToUpper(); + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is DmException) + { + if (exception is System.IO.IOException) + { + base.SetUnavailable(exception); + } + else if (obj.Value.Ping() == false) + { + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class DamengConnectionPoolPolicy : IPolicy + { + + internal DamengConnectionPool _pool; + public string Name { get; set; } = "Dameng DmConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"(Max\s*)?pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[2].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"poolsize={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};poolsize={PoolSize}"; //NotSupportedException + //if (m.Success) _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new DmConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1 from dual"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs new file mode 100644 index 00000000..2378e7ab --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs @@ -0,0 +1,469 @@ +using Dm; +using FreeSql.DataAnnotations; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Dameng +{ + + class DamengCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public DamengCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(DmDbType.Bit, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(DmDbType.Bit, "number","number(1) NULL", null, true, null) }, + + { typeof(sbyte).FullName, CsToDb.New(DmDbType.SByte, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(DmDbType.SByte, "number", "number(4) NULL", false, true, null) }, + { typeof(short).FullName, CsToDb.New(DmDbType.Int16, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(DmDbType.Int16, "number", "number(6) NULL", false, true, null) }, + { typeof(int).FullName, CsToDb.New(DmDbType.Int32, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(DmDbType.Int32, "number", "number(11) NULL", false, true, null) }, + { typeof(long).FullName, CsToDb.New(DmDbType.Int64, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(DmDbType.Int64, "number","number(21) NULL", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(DmDbType.Byte, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(DmDbType.Byte, "number","number(3) NULL", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(DmDbType.UInt16, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(DmDbType.UInt16, "number", "number(5) NULL", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(DmDbType.UInt32, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(DmDbType.UInt32, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(DmDbType.UInt64, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(DmDbType.UInt64, "number", "number(20) NULL", true, true, null) }, + + { typeof(double).FullName, CsToDb.New(DmDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(DmDbType.Double, "double", "double NULL", false, true, null) }, + { typeof(float).FullName, CsToDb.New(DmDbType.Float, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(DmDbType.Float, "real","real NULL", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(DmDbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(DmDbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + + //达梦8 ODBC 不支持 TimeSpan + //{ typeof(TimeSpan).FullName, CsToDb.NewInfo(DmDbType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (DmDbType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(DmDbType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(DmDbType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset).FullName, CsToDb.New(DmDbType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(DmDbType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + + { typeof(byte[]).FullName, CsToDb.New(DmDbType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(DmDbType.VarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + + { typeof(Guid).FullName, CsToDb.New(DmDbType.Char, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DmDbType.Char, "char", "char(36) NULL", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(DmDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : + CsToDb.New(DmDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + var userId = (_orm.Ado.MasterPool as DamengConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = DamengConnectionPool.GetUserId(conn.Value.ConnectionString); + } + var seqcols = new List>(); //序列:列,表,自增 + var seqnameDel = new List(); //要删除的序列+触发器 + + var sb = new StringBuilder(); + var sbDeclare = new StringBuilder(); + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; + var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + primaryKeyName = null; + } + } + //codefirst 不支持表名中带 . + + if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 + throw new NotImplementedException($"达梦 CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tboldname)) == null) + //模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("execute immediate 'CREATE TABLE ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) LOGGING ';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + continue; + } + //如果新表,旧表在一个模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql($@" +select +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'N' then 0 else 1 end, +nvl((select 1 from user_sequences where upper(sequence_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name) and rownum < 2), 0), +nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI') and rownum < 2), 0), +b.comments +from all_tab_columns a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var sqlType = GetDamengSqlTypeFullName(a); + return new + { + column = string.Concat(a[0]), + sqlType, + is_nullable = string.Concat(a[6]) == "1", + is_identity = string.Concat(a[7]) == "1" && string.Concat(a[8]) == "1", + comment = string.Concat(a[9]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + istmpatler = true; + if (istmpatler && tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + if (istmpatler && Regex.IsMatch(tbcol.Attribute.DbType, @"\(\d+") == false && Regex.IsMatch(tbstructcol.sqlType, @"\(\d+") + && string.Compare(tbcol.Attribute.DbType, Regex.Replace(tbstructcol.sqlType, @"\([^\)]+\)", ""), StringComparison.CurrentCultureIgnoreCase) == 0) + istmpatler = false; + } + //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + if (tbstructcol.is_identity) + seqnameDel.Add(Utils.GetCsName($"{tbname[1]}_seq_{tbstructcol.column}")); + //修改列名 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); + if (tbcol.Attribute.IsIdentity) + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } + else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (isCommentChanged) + sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + continue; + } + //添加列 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable == false) + { + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); + } + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + } + + var dsuksql = _commonUtils.FormatSql(@" +select +c.column_name, +a.index_name, +case when c.descend = 'DESC' then 1 else 0 end, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner +and a.table_name = c.table_name +and a.owner in ({0}) and a.table_name in ({1}) +and not exists(select 1 from all_constraints where index_name = a.index_name and constraint_type = 'P')", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]).Trim('"'), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }).ToArray(); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append("';\r\n"); + sbalter.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n"); + } + } + } + if (istmpatler == false) + { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); + //创建临时表 + sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) LOGGING ';\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); + insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"nvl({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + sb.Append(insertvalue.Replace("'", "''")).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } + } + Dictionary dicDeclare = new Dictionary(); + Action dropSequence = seqname => + { + if (dicDeclare.ContainsKey(seqname) == false) + { + sbDeclare.Append("\r\nIS").Append(seqname).Append(" NUMBER; \r\n"); + dicDeclare.Add(seqname, true); + } + sb.Append("IS").Append(seqname).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(seqname).Append(_commonUtils.FormatSql(" from user_sequences where sequence_name={0}; \r\n", seqname)) + .Append("if IS").Append(seqname).Append(" > 0 then \r\n") + .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") + .Append("end if; \r\n"); + }; + Action dropTrigger = tiggerName => + { + if (dicDeclare.ContainsKey(tiggerName) == false) + { + sbDeclare.Append("\r\nIS").Append(tiggerName).Append(" NUMBER; \r\n"); + dicDeclare.Add(tiggerName, true); + } + sb.Append("IS").Append(tiggerName).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(tiggerName).Append(_commonUtils.FormatSql(" from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if IS").Append(tiggerName).Append(" > 0 then \r\n") + .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") + .Append("end if; \r\n"); + }; + foreach (var seqname in seqnameDel) + { + dropSequence(seqname); + dropTrigger(seqname + "TI"); + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); + var tiggerName = seqname + "TI"; + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + dropSequence(seqname); + if (seqcol.Item3) + { + var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_columns where owner={0} and table_name={1} and column_name={2}", tbname[0], tbname[1], seqcol.Item1.Attribute.Name)) == null ? 1 : + _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}"); + sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n"); + sb.Append("execute immediate 'CREATE OR REPLACE TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)) + .Append(" \r\nbefore insert on ").Append(tbname2) + .Append(" \r\nfor each row \r\nbegin\r\nselect ").Append(_commonUtils.QuoteSqlName(seqname)) + .Append(".nextval into :new.").Append(colname2).Append(" from dual;\r\nend;';\r\n"); + } + else + dropTrigger(tiggerName); + } + if (sbDeclare.Length > 0) sbDeclare.Insert(0, "declare "); + return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString(); + } + + internal static string GetDamengSqlTypeFullName(object[] row) + { + var a = row; + var sqlType = string.Concat(a[1]).ToUpper(); + var data_length = long.Parse(string.Concat(a[2])); + long.TryParse(string.Concat(a[3]), out var data_precision); + long.TryParse(string.Concat(a[4]), out var data_scale); + //var char_used = string.Concat(a[5]); + if (sqlType.StartsWith("INTERVAL DAY TO SECOND")) + sqlType = $"INTERVAL DAY({(data_scale - 1536) / 16}) TO SECOND({(data_scale - 1536) % 16})"; + else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) + { + } + else if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) + sqlType += data_scale <= 0 ? "" : $"({data_scale})"; + else if (sqlType.StartsWith("BLOB")) + { + } + else if (sqlType == "REAL" || sqlType == "DOUBLE" || sqlType == "FLOAT") + { + } + else if (data_precision > 0 && data_scale > 0) + sqlType += $"({data_precision},{data_scale})"; + else if (data_precision > 0) + sqlType += $"({data_precision})"; + else + sqlType += $"({data_length})"; + return sqlType; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs new file mode 100644 index 00000000..2b11cd9e --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -0,0 +1,559 @@ +using Dm; +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Dameng +{ + class DamengDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public DamengDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + DmDbType GetSqlDbType(DbColumnInfo column) + { + var dbfull = column.DbTypeTextFull.ToLower(); + switch (dbfull) + { + case "number(1)": return DmDbType.Bit; + + case "number(4)": return DmDbType.SByte; + case "number(6)": return DmDbType.Int16; + case "number(11)": return DmDbType.Int32; + case "number(21)": return DmDbType.Int64; + + case "number(3)": return DmDbType.Byte; + case "number(5)": return DmDbType.UInt16; + case "number(10)": return DmDbType.UInt32; + case "number(20)": return DmDbType.UInt64; + + case "float(126)": return DmDbType.Double; + case "float(63)": return DmDbType.Float; + case "number(10,2)": return DmDbType.Decimal; + + case "interval day(2) to second(6)": return DmDbType.Time; + case "timestamp(6)": return DmDbType.DateTime; + case "timestamp(6) with local time zone": return DmDbType.DateTime; + + case "blob": return DmDbType.VarBinary; + case "nvarchar2(255)": return DmDbType.VarChar; + + case "char(36)": return DmDbType.Char; + } + switch (column.DbTypeText.ToLower()) + { + case "bit": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(1)"]); + return DmDbType.Bit; + case "smallint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(4)"]); + return DmDbType.UInt16; + case "byte": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(3)"]); + return DmDbType.Byte; + case "tinyint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(3)"]); + return DmDbType.Byte; + case "integer": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(11)"]); + return DmDbType.Int32; + case "bigint": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(21)"]); + return DmDbType.Int64; + case "dec": + case "decimal": + case "numeric": + case "number": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(10,2)"]); + return DmDbType.Decimal; + case "time": + case "interval day to second": + case "interval year to month": + case "interval year": + case "interval month": + case "interval day": + case "interval day to hour": + case "interval day to minute": + case "interval hour": + case "interval hour to minute": + case "interval hour to second": + case "interval minute": + case "interval minute to second": + case "interval second": + case "time with time zone": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); + return DmDbType.Time; + case "date": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["date(7)"]); + return DmDbType.DateTime; + case "timestamp": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); + return DmDbType.DateTime; + case "timestamp with local time zone": + case "timestamp with time zone": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6) with local time zone"]); + return DmDbType.DateTime; + case "binary": + case "varbinary": + case "blob": + case "image": + case "longvarbinary": + case "bfile": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return DmDbType.VarBinary; + case "nvarchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DmDbType.VarChar; + case "varchar": + case "varchar2": + case "text": + case "longvarchar": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DmDbType.VarChar; + case "character": + case "char": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DmDbType.Char; + case "nchar": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DmDbType.Char; + case "clob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DmDbType.VarChar; + case "nclob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DmDbType.VarChar; + case "raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return DmDbType.VarBinary; + case "long raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return DmDbType.VarBinary; + case "real": + case "binary_float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]); + return DmDbType.Float; + case "double": + case "float": + case "double precision": + case "binary_double": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return DmDbType.Double; + case "rowid": + default: + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DmDbType.VarChar; + } + throw new NotImplementedException($"未实现 {column.DbTypeTextFull} 类型映射"); + } + + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static DamengDbFirst() + { + var defaultDbToCs = new Dictionary() { + { "number(1)", new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { "number(4)", new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { "number(6)", new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "number(11)", new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "number(21)", new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { "number(3)", new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "number(5)", new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "number(10)", new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "number(20)", new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + + { "float(126)", new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float(63)", new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "number(10,2)", new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { "interval day(2) to second(6)", new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date(7)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6) with local time zone", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + + { "blob", new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { "nvarchar2(255)", new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "char(36 char)", new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } + + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select username from all_users"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public List GetTablesByDatabase(params string[] database2) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + var database = database2?.ToArray(); + + if (database == null || database.Any() == false) + { + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + database = new[] { userUsers }; + } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); + var sql = string.Format(@" +select +a.owner || '.' || a.table_name, +a.owner, +a.table_name, +b.comments, +'TABLE' +from all_tables a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' +where a.owner in ({0})", databaseIn); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 999) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 999) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = string.Format(@" +select +a.owner || '.' || a.table_name, +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'N' then 0 else 1 end, +nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name) and rownum < 2), 0), +b.comments, +a.data_default +from all_tab_cols a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner in ({1}) and {0} +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var ds2 = new List(); + foreach (var row in ds) + { + var ds2item = new object[9]; + ds2item[0] = row[0]; + ds2item[1] = row[1]; + ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); + ds2item[4] = DamengCodeFirst.GetDamengSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); + ds2item[5] = string.Concat(row[7]) == "1"; + ds2item[6] = string.Concat(row[8]) == "1"; + ds2item[7] = string.Concat(row[9]); + ds2item[8] = string.Concat(row[10]); + ds2.Add(ds2item); + } + foreach (var row in ds2) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); + if (max_length == 0) max_length = -1; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment, + DefaultValue = defaultValue + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } + + sql = string.Format(@" +select +a.table_owner || '.' || a.table_name, +c.column_name, +c.index_name, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end, +case when exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') then 1 else 0 end, +0, +case when c.descend = 'DESC' then 1 else 0 end, +c.column_position +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner +and a.table_name = c.table_name +and a.table_owner in ({1}) and {0} +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]).Trim('"'); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + bool is_desc = string.Concat(row[6]) == "1"; + if (database.Length == 1) + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + if (is_primary_key) continue; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = string.Format(@" +select +a.owner || '.' || a.table_name, +c.column_name, +c.constraint_name, +b.owner || '.' || b.table_name, +1, +d.column_name + +-- a.owner 外键拥有者, +-- a.table_name 外键表, +-- c.column_name 外键列, +-- b.owner 主键拥有者, +-- b.table_name 主键表, +-- d.column_name 主键列, +-- c.constraint_name 外键名, +-- d.constraint_name 主键名 + +from +all_constraints a, +all_constraints b, +all_cons_columns c, --外键表 +all_cons_columns d --主键表 +where +a.r_constraint_name = b.constraint_name    +and a.constraint_type = 'R'    +and b.constraint_type = 'P'    +and a.r_owner = b.owner    +and a.constraint_name = c.constraint_name    +and b.constraint_name = d.constraint_name    +and a.owner = c.owner    +and a.table_name = c.table_name    +and b.owner = d.owner    +and b.table_name = d.table_name +and a.owner in ({1}) and {0} +", loc8, databaseIn); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs new file mode 100644 index 00000000..3ac2d3fd --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -0,0 +1,469 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Dameng +{ + class DamengExpression : CommonExpression + { + + public DamengExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as number)"; + case "System.Char": return $"substr(to_char({getExp(operandExp)}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(operandExp)},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(operandExp)} as number)"; + case "System.Double": return $"cast({getExp(operandExp)} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as number)"; + case "System.Single": return $"cast({getExp(operandExp)} as number)"; + case "System.String": return $"to_char({getExp(operandExp)})"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(operandExp)})"; + return $"to_char({getExp(operandExp)})"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Char": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(callExp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(callExp.Arguments[0])})"; + return $"to_char({getExp(callExp.Arguments[0])})"; + } + return null; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"to_char({getExp(callExp.Object)})" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + if (argIndex >= callExp.Arguments.Count) break; + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + var left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "trunc(systimestamp)"; + case "MinValue": return "to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')"; + case "MaxValue": return "to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"trunc({left})"; + case "TimeOfDay": return $"(cast({left} as timestamp with time zone)-trunc({left}))"; + case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; + case "Day": return $"cast(to_char({left},'DD') as number)"; + case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; + case "Month": return $"cast(to_char({left},'MM') as number)"; + case "Year": return $"cast(to_char({left},'YYYY') as number)"; + case "Hour": return $"cast(to_char({left},'HH24') as number)"; + case "Minute": return $"cast(to_char({left},'MI') as number)"; + case "Second": return $"cast(to_char({left},'SS') as number)"; + case "Millisecond": return $"cast(to_char({left},'FF3') as number)"; + case "Ticks": return $"cast(to_char({left},'FF7') as number)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "numtodsinterval(0,'second')"; + case "MinValue": return "numtodsinterval(-233720368.5477580,'second')"; + case "MaxValue": return "numtodsinterval(233720368.5477580,'second')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"extract(day from {left})"; + case "Hours": return $"extract(hour from {left})"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Minutes": return $"extract(minute from {left})"; + case "Seconds": return $"floor(extract(second from {left}))"; + case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; + case "TotalDays": return $"extract(day from {left})"; + case "TotalHours": return $"(extract(day from {left})*24+extract(hour from {left}))"; + case "TotalMilliseconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*1000"; + case "TotalMinutes": return $"(extract(day from {left})*1440+extract(hour from {left})*60+extract(minute from {left}))"; + case "TotalSeconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(to_char({args0Value})||'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'||to_char({args0Value}))")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'||to_char({args0Value})||'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(instr({left}, {indexOfFindStr}, {locateArgs1}, 1)-1)"; + } + return $"(instr({left}, {indexOfFindStr}, 1, 1))-1"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceil({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": + if (exp.Arguments.Count > 1) return $"log({getExp(exp.Arguments[1])},{getExp(exp.Arguments[0])})"; + return $"log(2.7182818284590451,{getExp(exp.Arguments[0])})"; + case "Log10": return $"log(10,{getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + //case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0)"; + + case "Parse": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "AddDays": return $"({left}+{args1})"; + case "AddHours": return $"({left}+({args1})/24)"; + case "AddMilliseconds": return $"({left}+({args1})/86400000)"; + case "AddMinutes": return $"({left}+({args1})/1440)"; + case "AddMonths": return $"add_months({left},{args1})"; + case "AddSeconds": return $"({left}+({args1})/86400)"; + case "AddTicks": return $"({left}+({args1})/864000000000)"; + case "AddYears": return $"add_months({left},({args1})*12)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(cast({left} as timestamp with time zone)-{args1})"; + case "System.TimeSpan": return $"({left}-{args1})"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; + case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60 * 24},'second')"; + case "FromHours": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60},'second')"; + case "FromMilliseconds": return $"numtodsinterval(({getExp(exp.Arguments[0])})/1000,'second')"; + case "FromMinutes": return $"numtodsinterval(({getExp(exp.Arguments[0])})*60,'second')"; + case "FromSeconds": return $"numtodsinterval(({getExp(exp.Arguments[0])}),'second')"; + case "FromTicks": return $"numtodsinterval(({getExp(exp.Arguments[0])})/10000000,'second')"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(6))"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(6))"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; + case "ToString": return $"to_char({left})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + //case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToChar": return $"substr(to_char({getExp(exp.Arguments[0])}), 1, 1)"; + case "ToDateTime": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToString": return $"to_char({getExp(exp.Arguments[0])})"; + case "ToUInt16": + case "ToUInt32": + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as number)"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs b/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs new file mode 100644 index 00000000..a44e710b --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs @@ -0,0 +1,12 @@ +public static partial class FreeSqlDamengGlobalExtensions +{ + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatDameng(this string that, params object[] args) => _damengAdo.Addslashes(that, args); + static FreeSql.Dameng.DamengAdo _damengAdo = new FreeSql.Dameng.DamengAdo(); +} diff --git a/Providers/FreeSql.Provider.Dameng/DamengProvider.cs b/Providers/FreeSql.Provider.Dameng/DamengProvider.cs new file mode 100644 index 00000000..e8166066 --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/DamengProvider.cs @@ -0,0 +1,61 @@ +using FreeSql.Dameng.Curd; +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.Dameng +{ + + public class DamengProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new DamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new DamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new DamengInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new DamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new DamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new DamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new DamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public DamengProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new DamengUtils(this); + this.InternalCommonExpression = new DamengExpression(this.InternalCommonUtils); + + this.Ado = new DamengAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new DamengDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new DamengCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); + public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + + ~DamengProvider() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs new file mode 100644 index 00000000..e6c67977 --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs @@ -0,0 +1,102 @@ +using Dm; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; + +namespace FreeSql.Dameng +{ + + class DamengUtils : CommonUtils + { + public DamengUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var dbtype = (DmDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case DmDbType.Bit: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = DmDbType.Int32; + break; + + case DmDbType.Char: + case DmDbType.VarChar: + case DmDbType.Text: + value = string.Concat(value); + break; + } + var ret = new DmParameter { ParameterName = QuoteParamterName(parameterName), DmSqlType = dbtype, Value = value }; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + var dbtype = (DmDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case DmDbType.Bit: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = DmDbType.Int32; + break; + + case DmDbType.Char: + case DmDbType.VarChar: + case DmDbType.Text: + value = string.Concat(value); + break; + } + var ret = new DmParameter { ParameterName = $":{name}", DmSqlType = dbtype, Value = value }; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatDameng(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); + public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left} / {right})"; + public override string Now => "systimestamp"; + public override string NowUtc => "getutcdate"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj new file mode 100644 index 00000000..35e83d0f --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -0,0 +1,50 @@ + + + + netstandard2.0;net45;net40 + 1.4.0-preview0414 + true + YeXiangQin + FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM;DM8;Dameng;达梦 + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + + + + + + + + + Always + + + + + + + + + + lib\DmProvider\netstandard2.0\DmProvider.dll + false + + + + + ns20;netstandard20 + + + net40 + + + + diff --git a/Providers/FreeSql.Provider.Dameng/lib/DmProvider/DmProvider.1.1.0.nuspec b/Providers/FreeSql.Provider.Dameng/lib/DmProvider/DmProvider.1.1.0.nuspec new file mode 100644 index 00000000..52b9ed57 --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/lib/DmProvider/DmProvider.1.1.0.nuspec @@ -0,0 +1,21 @@ + + + + DmProvider + 1.1.0 + DM + DM + false + DM .NET PROVIDER + Copy right(C) DM + + + + + + + + + + + \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/DmProvider.dll b/Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/DmProvider.dll new file mode 100644 index 0000000000000000000000000000000000000000..865630a9d38d70bdafdbcc356fe7bfb579b8b735 GIT binary patch literal 379904 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 -MQLa*z>B8_WY+}>-^f#3`Ryer}5HgY&e z;B2yRUqQ%U8Vwtr#-w*Dk;Ma2-YIiHeR*7z0Wx?hreMj5m^K^k_5^-98tLq8q`Rxp z!EbkCGK}8SnCuCUR`eCqjY*uM2}6r+V=D4w8dJn=PUEw|j<*p%rB|5kQtIlbpi}fo zU`u)I>K8b25PkbAaPw;F+xf9oG*fd=k|qYXR=y53FSbV4a{N(nr!Rkp`iR09Jej_N z_8kLXeOt`akn}L1gpR=(D&)^G+HQQDlI{Wq-+{X=rGf3~y`@CkS{zm~D≫gvYEb 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 bp5v$;{xAI)mpNbRoTbM9|G)p|DDb}lhwwib literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/en/DmProvider.resources.dll b/Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/en/DmProvider.resources.dll new file mode 100644 index 0000000000000000000000000000000000000000..c6ba0ef66b5ebd8d3dd97cc05c45a7a28a220672 GIT binary patch literal 20480 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 literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/zh-CN/DmProvider.resources.dll b/Providers/FreeSql.Provider.Dameng/lib/DmProvider/net20/zh-CN/DmProvider.resources.dll new file mode 100644 index 0000000000000000000000000000000000000000..66bb2bee789aba2fb726a434d994c3881921afb6 GIT binary patch literal 21504 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 z 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

Ff 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

ac`dgWe)!;#hfP-``v%~OJj~w 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 literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.Dameng/lib/DmProvider/netstandard2.0/en/DmProvider.resources.dll b/Providers/FreeSql.Provider.Dameng/lib/DmProvider/netstandard2.0/en/DmProvider.resources.dll new file mode 100644 index 0000000000000000000000000000000000000000..93f83654f5fc872c7627e2318ab0d19400830153 GIT binary patch literal 20480 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 L|Lp!(Sm3__boX?k literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs index 0f0c131c..fdba488e 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs @@ -125,60 +125,60 @@ namespace FreeSql.Odbc.Dameng } public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index 919c9d6b..61ac9b87 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.Dameng this.availableHandler = availableHandler; this.unavailableHandler = unavailableHandler; - var policy = new OdbcOracleConnectionPoolPolicy + var policy = new OdbcDamengConnectionPoolPolicy { _pool = this, Name = name @@ -62,7 +62,7 @@ namespace FreeSql.Odbc.Dameng } } - class OdbcOracleConnectionPoolPolicy : IPolicy + class OdbcDamengConnectionPoolPolicy : IPolicy { internal OdbcDamengConnectionPool _pool; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index a2a91981..55fc2af3 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -114,7 +114,7 @@ namespace FreeSql.Odbc.Dameng //codefirst 不支持表名中带 . if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 - throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); + throw new NotImplementedException($"达梦 CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}"); var sbalter = new StringBuilder(); var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 @@ -200,7 +200,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { - var sqlType = GetOracleSqlTypeFullName(a); + var sqlType = GetDamengSqlTypeFullName(a); return new { column = string.Concat(a[0]), @@ -436,7 +436,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString(); } - internal static string GetOracleSqlTypeFullName(object[] row) + internal static string GetDamengSqlTypeFullName(object[] row) { var a = row; var sqlType = string.Concat(a[1]).ToUpper(); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index ff398cc7..d6eccbdc 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -61,7 +61,7 @@ namespace FreeSql.Odbc.Dameng _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(1)"]); return OdbcType.Bit; case "smallint": - _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(5)"]); + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(4)"]); return OdbcType.SmallInt; case "byte": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(3)"]); @@ -323,7 +323,7 @@ where a.owner in ({1}) and {0} ds2item[0] = row[0]; ds2item[1] = row[1]; ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); - ds2item[4] = OdbcDamengCodeFirst.GetOracleSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); + ds2item[4] = OdbcDamengCodeFirst.GetDamengSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); ds2item[5] = string.Concat(row[7]) == "1"; ds2item[6] = string.Concat(row[8]) == "1"; ds2item[7] = string.Concat(row[9]); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs index c1da688a..77e114ae 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs @@ -38,12 +38,6 @@ namespace FreeSql.Odbc.Dameng this.DbFirst = new OdbcDamengDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); this.CodeFirst = new OdbcDamengCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); - - //this.Aop.AuditValue += new EventHandler((_, e) => - //{ - // if (e.Value == null && e.Column.Attribute.IsPrimary == false && e.Column.Attribute.IsIdentity == false) - // e.Value = Utils.GetDataReaderValue(e.Property.PropertyType.NullableTypeOrThis(), e.Column.Attribute.DbDefautValue); - //}); } internal CommonUtils InternalCommonUtils { get; } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index 1bfc029b..dd066373 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -65,7 +65,7 @@ namespace FreeSql.Odbc.Dameng return ret; }); - public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcOracle(args); + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcDameng(args); public override string QuoteSqlName(params string[] name) { if (name.Length == 1) From e62e425646de2e863cd95802832ca27b5945d5b6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 14 Apr 2020 23:49:25 +0800 Subject: [PATCH 0571/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IInsert=20In?= =?UTF-8?q?sertColumns/IgnoreColumns=20=E6=96=B9=E6=B3=95=E9=87=8D?= =?UTF-8?q?=E8=BD=BD=E8=BE=93=E5=85=A5=20string[]=EF=BC=9B#275?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++ FreeSql/FreeSql.xml | 14 +++++++++++ FreeSql/Interface/Curd/IInsert.cs | 13 ++++++++++ .../Internal/CommonProvider/InsertProvider.cs | 25 +++++++++++-------- .../Internal/CommonProvider/UpdateProvider.cs | 4 +-- 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 8cf53748..19225654 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,6 +120,13 @@ 清空状态数据

+ + + 根据 lambda 条件删除数据 + + + + 添加 @@ -214,6 +221,15 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 468cec8e..0b477835 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -907,6 +907,13 @@ lambda选择列 + + + 只插入的列 + + 属性名,或者字段名 + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) @@ -914,6 +921,13 @@ lambda选择列 + + + 忽略的列 + + 属性名,或者字段名 + + 指定可插入自增字段 diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 6f09c6bc..025f875b 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -48,12 +48,25 @@ namespace FreeSql /// lambda选择列 /// IInsert InsertColumns(Expression> columns); + /// + /// 只插入的列 + /// + /// 属性名,或者字段名 + /// + IInsert InsertColumns(string[] columns); + /// /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) /// /// lambda选择列 /// IInsert IgnoreColumns(Expression> columns); + /// + /// 忽略的列 + /// + /// 属性名,或者字段名 + /// + IInsert IgnoreColumns(string[] columns); /// /// 指定可插入自增字段 diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 6834599f..7780ba66 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -442,19 +442,24 @@ namespace FreeSql.Internal.CommonProvider public abstract long ExecuteIdentity(); public abstract List ExecuteInserted(); - public IInsert IgnoreColumns(Expression> columns) + public IInsert IgnoreColumns(Expression> columns) => IgnoreColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null)); + public IInsert InsertColumns(Expression> columns) => InsertColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null)); + + public IInsert IgnoreColumns(string[] columns) { - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).Distinct(); - _ignore.Clear(); - foreach (var col in cols) _ignore.Add(col, true); - return this; - } - public IInsert InsertColumns(Expression> columns) - { - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); + var cols = columns.Distinct().ToDictionary(a => a); _ignore.Clear(); foreach (var col in _table.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name) == false && _auditValueChangedDict.ContainsKey(col.Attribute.Name) == false) + if (cols.ContainsKey(col.Attribute.Name) == true || cols.ContainsKey(col.CsName) == true) + _ignore.Add(col.Attribute.Name, true); + return this; + } + public IInsert InsertColumns(string[] columns) + { + var cols = columns.Distinct().ToDictionary(a => a); + _ignore.Clear(); + foreach (var col in _table.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name) == false && cols.ContainsKey(col.CsName) == false && _auditValueChangedDict.ContainsKey(col.Attribute.Name) == false) _ignore.Add(col.Attribute.Name, true); return this; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index d4100b04..e3cdd898 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -309,7 +309,7 @@ namespace FreeSql.Internal.CommonProvider public IUpdate IgnoreColumns(string[] columns) { - var cols = columns.ToDictionary(a => a); + var cols = columns.Distinct().ToDictionary(a => a); _ignore.Clear(); foreach (var col in _table.Columns.Values) if (cols.ContainsKey(col.Attribute.Name) == true || cols.ContainsKey(col.CsName) == true) @@ -318,7 +318,7 @@ namespace FreeSql.Internal.CommonProvider } public IUpdate UpdateColumns(string[] columns) { - var cols = columns.ToDictionary(a => a); + var cols = columns.Distinct().ToDictionary(a => a); _ignore.Clear(); foreach (var col in _table.Columns.Values) if (cols.ContainsKey(col.Attribute.Name) == false && cols.ContainsKey(col.CsName) == false && _auditValueChangedDict.ContainsKey(col.Attribute.Name) == false) From 07a584c9abce675c6f2b30f5769826675233979b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 15 Apr 2020 00:08:06 +0800 Subject: [PATCH 0572/1029] v1.4.0-preview0415 #275 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 19 insertions(+), 35 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 37d9751d..3ab0cf88 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj index a96c1091..fb1393e3 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0ac86b98..8a1f8b55 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6a6a3e59..a73f830a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 7e978862..ff4e9380 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 1beb027c..61c0608d 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0414 + 1.4.0-preview0415 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 0ebc8745..cd4d36d8 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 0ca9c563..4cbfea5f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 19225654..8cf53748 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,13 +120,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -221,15 +214,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4a812dd6..9fb8b314 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 667027c8..9c1133ae 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 35e83d0f..a2529af8 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index aa3b83d8..3a80cc55 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 286b0788..5b631066 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 852ea2a3..fb0c1005 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index f07f3fdf..11e7e84e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 861060ae..d96dee52 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index c063fca7..b8038e52 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c3e93d5e..e0afcb4b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ba003c31..f40dd8f5 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0414 + 1.4.0-preview0415 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 1bf941ada01f88ac8cf26a1402d9831d430052d1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 15 Apr 2020 00:14:38 +0800 Subject: [PATCH 0573/1029] update g.cs --- FreeSql.Tests/FreeSql.Tests/g.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 61c209e1..7ba71c68 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -108,16 +108,16 @@ public class g static Lazy damengLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Dameng, "server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user;poolsize=5") - //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;Max Pool Size=2")) - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) - //.UseNoneCommandParameter(true) + .UseConnectionString(FreeSql.DataType.Dameng, "server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user;poolsize=5") + //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;Max Pool Size=2")) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) - .UseMonitorCommand( - cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 - (cmd, traceLog) => Console.WriteLine(traceLog)) - .Build()); + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); public static IFreeSql dameng => damengLazy.Value; } From 43e1529a832f0ded04f9b87fca8b7c5b00a9d3a9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 15 Apr 2020 01:34:26 +0800 Subject: [PATCH 0574/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20FreeSql.Gene?= =?UTF-8?q?rator=20OdbcDameng=20=E6=94=B9=E4=B8=BA=20Dameng=EF=BC=9B=20-?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=20FreeSql.All=20=E5=AF=B9=20FreeSql.Provi?= =?UTF-8?q?der.Dameng=20=E7=9A=84=E5=BC=95=E7=94=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 10 +- .../FreeSql.Generator.csproj | 8 +- FreeSql.All/FreeSql.All.csproj | 1 + FreeSql/FreeSql.xml | 306 ++++++++++-------- 4 files changed, 176 insertions(+), 149 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 0a86da2a..5ffb8fdb 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -106,10 +106,10 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -DB ""{9},user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2"" - -DB ""{10},Data Source=document.db;Attachs=xxxtb.db;"" + -DB ""{10},Data Source=document.db"" - -DB ""{11},Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789;Max pool size=2"" - {11} 是国产达梦数据库,需要使用 ODBC 连接 + -DB ""{11},server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user;poolsize=2"" + {11} 是国产达梦数据库 -Filter Table+View+StoreProcedure 默认生成:表+视图+存储过程 @@ -134,7 +134,7 @@ new Colorful.Formatter("SqlServer", Color.Yellow), new Colorful.Formatter("PostgreSQL", Color.Yellow), new Colorful.Formatter("Oracle", Color.Yellow), new Colorful.Formatter("Sqlite", Color.Yellow), -new Colorful.Formatter("OdbcDameng", Color.Yellow), +new Colorful.Formatter("Dameng", Color.Yellow), new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新所有实体类", Color.ForestGreen) ); wait.Set(); @@ -174,7 +174,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 case "postgresql": ArgsDbType = DataType.PostgreSQL; break; case "oracle": ArgsDbType = DataType.Oracle; break; case "sqlite": ArgsDbType = DataType.Sqlite; break; - case "odbcdameng": ArgsDbType = DataType.OdbcDameng; break; + case "dameng": ArgsDbType = DataType.Dameng; break; default: throw new ArgumentException($"-DB 参数错误,不支持的类型:{dbargs[0]}"); } ArgsConnectionString = dbargs[1].Trim(); diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 61c0608d..f5368dff 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -23,8 +23,14 @@ + + ..\..\Providers\FreeSql.Provider.Dameng\lib\DmProvider\netstandard2.0\DmProvider.dll + + + + + - diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index cd4d36d8..184ce438 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -26,6 +26,7 @@ + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 0b477835..891fa7b5 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2305,137 +2305,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2956,12 +2825,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3032,12 +2895,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3670,4 +3527,167 @@ + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + From 36759402ccb15aee50c3d6588c3fe57dd91e8037 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Apr 2020 02:58:34 +0800 Subject: [PATCH 0575/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.DbCo?= =?UTF-8?q?ntext=20OnModelCreating=20=E8=99=9A=E6=96=B9=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=9C=A8=20DbContext=20=E4=BD=BF=E7=94=A8=20?= =?UTF-8?q?FluentApi=EF=BC=9B#4=20-=20=E7=A7=BB=E9=99=A4=20FreeSql.Extensi?= =?UTF-8?q?ons.EfCoreFluentApi=EF=BC=8C=E5=8A=9F=E8=83=BD=E7=A7=BB?= =?UTF-8?q?=E8=87=B3=20FreeSql.DbContext=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ValuesController.cs | 40 +-- .../dbcontext_01/DbContexts/SongContext.cs | 87 ++++- Examples/dbcontext_01/Program.cs | 49 --- Examples/efcore_to_freesql/Startup.cs | 2 +- .../efcore_to_freesql.csproj | 2 +- .../FreeSql.Extensions.EfCoreFluentApi.csproj | 37 -- .../FreeSql.Extensions.EfCoreFluentApi.xml | 15 - .../ICodeFirstExtensions.cs | 115 ------- .../key.snk | Bin 596 -> 0 bytes .../readme.md | 103 ------ FreeSql.DbContext/DbContext/DbContext.cs | 24 +- .../EfCoreFluentApi}/EfCoreColumnFluent.cs | 4 + .../EfCoreFluentApiExtensions.cs | 120 +++++++ .../EfCoreFluentApi}/EfCoreTableFluent.cs | 4 + .../Extensions/DependencyInjection.cs | 6 +- .../Extensions/FreeSqlDbContextExtensions.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 36 +- .../Extensions/DependencyInjection.cs | 6 +- .../Extensions/FreeSqlRepositoryExtensions.cs | 2 +- FreeSql.sln | 15 - ... FreeSqlGlobalExpressionCallExtensions.cs} | 2 +- FreeSql/FreeSql.xml | 316 ++++++++---------- FreeSql/Interface/ICodeFirst.cs | 6 +- 23 files changed, 418 insertions(+), 575 deletions(-) delete mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj delete mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml delete mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs delete mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/key.snk delete mode 100644 Extensions/FreeSql.Extensions.EfCoreFluentApi/readme.md rename {Extensions/FreeSql.Extensions.EfCoreFluentApi => FreeSql.DbContext/EfCoreFluentApi}/EfCoreColumnFluent.cs (88%) create mode 100644 FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs rename {Extensions/FreeSql.Extensions.EfCoreFluentApi => FreeSql.DbContext/EfCoreFluentApi}/EfCoreTableFluent.cs (98%) rename FreeSql/Extensions/{FreeSqlGlobalExpressionCall.cs => FreeSqlGlobalExpressionCallExtensions.cs} (96%) diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs index 7ad083b1..6bedf450 100644 --- a/Examples/dbcontext_01/Controllers/ValuesController.cs +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -42,12 +42,12 @@ namespace dbcontext_01.Controllers repos2Song.Where(a => a.Id > 10).ToList(); //查询结果,进入 states - var song = new Song { }; + var song = new Song { Title = "empty" }; repos2Song.Insert(song); id = song.Id; var adds = Enumerable.Range(0, 100) - .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .Select(a => new Song { CreateTime = DateTime.Now, Title = "xxxx" + a, Url = "url222" }) .ToList(); //创建一堆无主键值 @@ -72,17 +72,7 @@ namespace dbcontext_01.Controllers var ctx = _songContext; var tag = new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } - } + Name = "testaddsublist" }; ctx.Tags.Add(tag); @@ -91,17 +81,7 @@ namespace dbcontext_01.Controllers var tagAsync = new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } - } + Name = "testaddsublist" }; await ctx.Tags.AddAsync(tagAsync); @@ -109,7 +89,7 @@ namespace dbcontext_01.Controllers ctx.Songs.Select.Where(a => a.Id > 10).ToList(); //查询结果,进入 states - song = new Song { }; + song = new Song { Title = "empty" }; //可插入的 song ctx.Songs.Add(song); @@ -117,7 +97,7 @@ namespace dbcontext_01.Controllers //因有自增类型,立即开启事务执行SQL,返回自增值 adds = Enumerable.Range(0, 100) - .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .Select(a => new Song { CreateTime = DateTime.Now, Title = "xxxx" + a, Url = "url222" }) .ToList(); //创建一堆无主键值 @@ -159,12 +139,12 @@ namespace dbcontext_01.Controllers reposSong.Where(a => a.Id > 10).ToList(); //查询结果,进入 states - song = new Song { }; + song = new Song { Title = "empty" }; reposSong.Insert(song); id = song.Id; adds = Enumerable.Range(0, 100) - .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .Select(a => new Song { CreateTime = DateTime.Now, Title = "xxxx" + a, Url = "url222" }) .ToList(); //创建一堆无主键值 @@ -193,12 +173,12 @@ namespace dbcontext_01.Controllers using (ctx = new SongContext()) { - song = new Song { }; + song = new Song { Title = "empty" }; await ctx.Songs.AddAsync(song); id = song.Id; adds = Enumerable.Range(0, 100) - .Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" }) + .Select(a => new Song { CreateTime = DateTime.Now, Title = "xxxx" + a, Url = "url222" }) .ToList(); await ctx.Songs.AddRangeAsync(adds); diff --git a/Examples/dbcontext_01/DbContexts/SongContext.cs b/Examples/dbcontext_01/DbContexts/SongContext.cs index da7da534..b920f23d 100644 --- a/Examples/dbcontext_01/DbContexts/SongContext.cs +++ b/Examples/dbcontext_01/DbContexts/SongContext.cs @@ -5,56 +5,109 @@ using System.Collections.Generic; namespace dbcontext_01 { - public class SongContext : DbContext { - public SongContext() : base() { } - public SongContext(IFreeSql fsql) : base(fsql, null) { } - public DbSet Songs { get; set; } public DbSet Tags { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder builder) { builder.UseFreeSql(Startup.Fsql); + //这里直接指定一个静态的 IFreeSql 对象即可,切勿重新 Build() + } + + protected override void OnModelCreating(ICodeFirst codefirst) + { + codefirst.Entity(eb => + { + eb.ToTable("tb_song"); + eb.Ignore(a => a.Field1); + eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); + eb.Property(a => a.Url).HasMaxLength(100); + + eb.Property(a => a.RowVersion).IsRowVersion(); + eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp"); + + eb.HasKey(a => a.Id); + eb.HasIndex(a => new { a.Id, a.Title }).IsUnique().HasName("idx_xxx11"); + + //一对多、多对一 + eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); + + //多对多 + eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); + }); + + codefirst.Entity(eb => + { + eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); + + eb.HasData(new[] + { + new SongType + { + Id = 1, + Name = "流行", + Songs = new List(new[] + { + new Song{ Title = "真的爱你" }, + new Song{ Title = "爱你一万年" }, + }) + }, + new SongType + { + Id = 2, + Name = "乡村", + Songs = new List(new[] + { + new Song{ Title = "乡里乡亲" }, + }) + }, + }); + }); + + codefirst.SyncStructure(); + codefirst.SyncStructure(); } } + public class SongType + { + public int Id { get; set; } + public string Name { get; set; } + public List Songs { get; set; } + } public class Song { [Column(IsIdentity = true)] public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } public string Title { get; set; } public string Url { get; set; } + public DateTime CreateTime { get; set; } - public virtual ICollection Tags { get; set; } + public int TypeId { get; set; } + public SongType Type { get; set; } + public List Tags { get; set; } - [Column(IsVersion = true)] - public long versionRow { get; set; } + public int Field1 { get; set; } + public long RowVersion { get; set; } } public class Song_tag { public int Song_id { get; set; } - public virtual Song Song { get; set; } + public Song Song { get; set; } public int Tag_id { get; set; } - public virtual Tag Tag { get; set; } + public Tag Tag { get; set; } } - public class Tag { [Column(IsIdentity = true)] public int Id { get; set; } - public int? Parent_id { get; set; } - public virtual Tag Parent { get; set; } - public decimal? Ddd { get; set; } public string Name { get; set; } - public virtual ICollection Songs { get; set; } - public virtual ICollection Tags { get; set; } + public List Songs { get; set; } } } diff --git a/Examples/dbcontext_01/Program.cs b/Examples/dbcontext_01/Program.cs index 6f7b9727..657e3abd 100644 --- a/Examples/dbcontext_01/Program.cs +++ b/Examples/dbcontext_01/Program.cs @@ -16,57 +16,8 @@ namespace dbcontext_01 { public class Program { - - public class Song - { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string BigNumber { get; set; } - - [Column(IsVersion = true)]//使用简单 - public long versionRow { get; set; } - } - - public class SongContext : DbContext - { - - public DbSet Songs { get; set; } - - protected override void OnConfiguring(DbContextOptionsBuilder builder) - { - builder.UseFreeSql(fsql); - } - } - static IFreeSql fsql; public static void Main(string[] args) { - var asse = typeof(FreeSql.Internal.ObjectPool.ObjectPool<>).Assembly; - - fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseNoneCommandParameter(true) - - .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) - .Build(); - - - using (var ctx = new SongContext()) - { - var song = new Song { BigNumber = "1000000000000000000" }; - ctx.Songs.Add(song); - - ctx.Songs.Update(song); - - song.BigNumber = (BigInteger.Parse(song.BigNumber) + 1).ToString(); - ctx.Songs.Update(song); - - ctx.SaveChanges(); - - var sql = fsql.Update().SetSource(song).ToSql(); - } - CreateWebHostBuilder(args).Build().Run(); } diff --git a/Examples/efcore_to_freesql/Startup.cs b/Examples/efcore_to_freesql/Startup.cs index 6d98c5e5..2271d74f 100644 --- a/Examples/efcore_to_freesql/Startup.cs +++ b/Examples/efcore_to_freesql/Startup.cs @@ -27,7 +27,7 @@ namespace efcore_to_freesql .UseAutoSyncStructure(true) .Build(); - FreeSql.Extensions.EfCoreFluentApi.ICodeFirstExtensions.Test(Fsql); + FreeSqlDbContextExtensions.EfCoreFluentApiTest(Fsql); DBContexts.BaseDBContext.Fsql = Fsql; diff --git a/Examples/efcore_to_freesql/efcore_to_freesql.csproj b/Examples/efcore_to_freesql/efcore_to_freesql.csproj index 3624b40c..e6a6a3fb 100644 --- a/Examples/efcore_to_freesql/efcore_to_freesql.csproj +++ b/Examples/efcore_to_freesql/efcore_to_freesql.csproj @@ -10,7 +10,7 @@ - + diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj deleted file mode 100644 index fb1393e3..00000000 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - netstandard2.0 - 1.4.0-preview0415 - true - YeXiangQin - FreeSql 扩展包实现,使用 FluentApi 方式配置实体模型,使用习惯接近 EFCore,方便过渡. - https://github.com/2881099/FreeSql - https://github.com/2881099/FreeSql - git - MIT - FreeSql;ORM;FluentApi - $(AssemblyName) - logo.png - $(AssemblyName) - true - true - true - key.snk - false - - - - - - - - - - - - FreeSql.Extensions.EfCoreFluentApi.xml - 3 - - - diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml b/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml deleted file mode 100644 index 55be793f..00000000 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/FreeSql.Extensions.EfCoreFluentApi.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - FreeSql.Extensions.EfCoreFluentApi - - - - - 使用 Repository + EnableAddOrUpdateNavigateList + NoneParameter 方式插入种子数据 - - - - - - diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs b/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs deleted file mode 100644 index 542af7c2..00000000 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/ICodeFirstExtensions.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using FreeSql.DataAnnotations; -using FreeSql.Internal.CommonProvider; - -namespace FreeSql.Extensions.EfCoreFluentApi -{ - public static class ICodeFirstExtensions - { - - public static ICodeFirst Entity(this ICodeFirst codeFirst, Action> modelBuilder) - { - var cf = codeFirst as CodeFirstProvider; - codeFirst.ConfigEntity(tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf))); - return codeFirst; - } - - public static void Test(IFreeSql fsql) - { - var cf = fsql.CodeFirst; - cf.Entity(eb => - { - eb.ToTable("tb_song"); - eb.Ignore(a => a.Field1); - eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); - eb.Property(a => a.Url).HasMaxLength(100); - - eb.Property(a => a.RowVersion).IsRowVersion(); - eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp"); - - eb.HasKey(a => a.Id); - eb.HasIndex(a => a.Title).IsUnique().HasName("idx_xxx11"); - - //一对多、多对一 - eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); - - //多对多 - eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); - }); - cf.Entity(eb => - { - eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); - - eb.HasData(new[] - { - new SongType - { - Id = 1, - Name = "流行", - Songs = new List(new[] - { - new Song{ Title = "真的爱你" }, - new Song{ Title = "爱你一万年" }, - }) - }, - new SongType - { - Id = 2, - Name = "乡村", - Songs = new List(new[] - { - new Song{ Title = "乡里乡亲" }, - }) - }, - }); - }); - - cf.SyncStructure(); - cf.SyncStructure(); - } - - public class SongType - { - public int Id { get; set; } - public string Name { get; set; } - - public List Songs { get; set; } - } - - public class Song - { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Title { get; set; } - public string Url { get; set; } - public DateTime CreateTime { get; set; } - - public int TypeId { get; set; } - public SongType Type { get; set; } - public List Tags { get; set; } - - public int Field1 { get; set; } - public long RowVersion { get; set; } - } - public class Song_tag - { - public int Song_id { get; set; } - public Song Song { get; set; } - - public int Tag_id { get; set; } - public Tag Tag { get; set; } - } - - public class Tag - { - [Column(IsIdentity = true)] - public int Id { get; set; } - - public string Name { get; set; } - - public List Songs { get; set; } - } - } -} diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/key.snk b/Extensions/FreeSql.Extensions.EfCoreFluentApi/key.snk deleted file mode 100644 index 9651c6f6dca7fbfe187084d653fca7c139c7d84a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097P=7d$>wVBs&v2*nzWIybp^a_TG#wMBR z9;`#2JIny2^KS;JL10G8RJp@bXIl86_Ep6}VeXsPu}NlBdUknchkmNk+KM18EUQoh zvMc_{lvG;WGhv`|lr1v+ZSwImfg98Vr;@T>Y)tPNgFS-uZ_$f)D8x)L54|Au?s?EN zNa~@z?gEkaTR6%IyQh5$5Vi*TL*!8@LezE|G6ar#^3+yRfa8Anv}0*u_A2;L>OBNk zIQT9I&vFm0?El=~_O)+E)qmKmLsuCZf3rB`t>5lmlZUoEeXQuaIx0Xc?Qr(x0Md~0 zfW2jtGin`LH6r@A4kaoo`!ha{M1JwZiFqe6J?Y!QUpc%U*T$2V{LVl7BMZG~mJOHS zD@D=?v~pQ;DUD1o5K^QX1!%Nzh`gOrU1v$+{U(j~#0LORdaY5}&ZCI<(D!L(=|Pa; z{M)JI|HfK(V-z$}A&Rt^w$Ma<^(zX5y_UTA0Pw{%>9hl`T_3ky<3-aO%r?<+d>k_J z^?^>17_0!=LwI7Hc!Jh@4KC dotnet add package FreeSql.Extensions.EfCoreFluentApi - -## 以假乱真 - -```csharp -static void Test() -{ - ICodeFirst cf = null; - cf.Entity(eb => - { - eb.ToTable("tb_song"); - eb.Ignore(a => a.Field1); - eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); - eb.Property(a => a.Url).HasMaxLength(100); - - eb.Property(a => a.RowVersion).IsRowVersion(); - eb.Property(a => a.CreateTime).HasDefaultValueSql("getdate()"); - - eb.HasKey(a => a.Id); - eb.HasIndex(a => a.Title).IsUnique().HasName("idx_xxx11"); - - //一对多、多对一 - eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); - - //多对多 - eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); - }); - - cf.Entity(eb => - { - eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); - - eb.HasData(new[] - { - new SongType - { - Id = 1, - Name = "流行", - Songs = new List(new[] - { - new Song{ Title = "真的爱你" }, - new Song{ Title = "爱你一万年" }, - }) - }, - new SongType - { - Id = 2, - Name = "乡村", - Songs = new List(new[] - { - new Song{ Title = "乡里乡亲" }, - }) - }, - }); - }); -} - -public class SongType -{ - public int Id { get; set; } - public string Name { get; set; } - - public List Songs { get; set; } -} - -public class Song -{ - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Title { get; set; } - public string Url { get; set; } - public DateTime CreateTime { get; set; } - - public int TypeId { get; set; } - public SongType Type { get; set; } - public List Tags { get; set; } - - public int Field1 { get; set; } - public long RowVersion { get; set; } -} -public class Song_tag -{ - public int Song_id { get; set; } - public Song Song { get; set; } - - public int Tag_id { get; set; } - public Tag Tag { get; set; } -} - -public class Tag -{ - [Column(IsIdentity = true)] - public int Id { get; set; } - - public string Name { get; set; } - - public List Songs { get; set; } -} -``` \ No newline at end of file diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 42188cb3..cac45b44 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Reflection; using System.Threading.Tasks; using System.Threading; +using FreeSql.Internal.Model; namespace FreeSql { @@ -71,18 +72,27 @@ namespace FreeSql } if (_ormScoped != null) InitPropSets(); } - protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { } + protected virtual void OnConfiguring(DbContextOptionsBuilder options) { } + protected virtual void OnModelCreating(ICodeFirst codefirst) { } #region Set - static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); + static ConcurrentDictionary> _dicGetDbSetProps = new ConcurrentDictionary>(); internal void InitPropSets() { - var props = _dicGetDbSetProps.GetOrAdd(this.GetType(), tp => - tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) - .Where(a => a.PropertyType.IsGenericType && - a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GetGenericArguments()[0])).ToArray()); + var thisType = this.GetType(); + var dicval = _dicGetDbSetProps.GetOrAdd(thisType, tp => + NaviteTuple.Create( + tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) + .Where(a => a.PropertyType.IsGenericType && + a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GetGenericArguments()[0])).ToArray(), + false)); + if (dicval.Item2 == false) + { + if (_dicGetDbSetProps.TryUpdate(thisType, NaviteTuple.Create(dicval.Item1, true), dicval)) + OnModelCreating(OrmOriginal.CodeFirst); + } - foreach (var prop in props) + foreach (var prop in dicval.Item1) { var set = this.Set(prop.PropertyType.GetGenericArguments()[0]); diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs b/FreeSql.DbContext/EfCoreFluentApi/EfCoreColumnFluent.cs similarity index 88% rename from Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs rename to FreeSql.DbContext/EfCoreFluentApi/EfCoreColumnFluent.cs index f91e6019..0b87862c 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreColumnFluent.cs +++ b/FreeSql.DbContext/EfCoreFluentApi/EfCoreColumnFluent.cs @@ -14,6 +14,10 @@ namespace FreeSql.Extensions.EfCoreFluentApi _cf = tf; } + /// + /// 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 + /// + /// public ColumnFluent Help() => _cf; public EfCoreColumnFluent HasColumnName(string name) diff --git a/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs b/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs new file mode 100644 index 00000000..30661258 --- /dev/null +++ b/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using FreeSql; +using FreeSql.DataAnnotations; +using FreeSql.Extensions.EfCoreFluentApi; +using FreeSql.Internal.CommonProvider; + +partial class FreeSqlDbContextExtensions +{ + /// + /// EFCore 99% 相似的 FluentApi 扩展方法 + /// + /// + /// + /// + /// + public static ICodeFirst Entity(this ICodeFirst codeFirst, Action> modelBuilder) + { + var cf = codeFirst as CodeFirstProvider; + codeFirst.ConfigEntity(tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf))); + return codeFirst; + } + + public static void EfCoreFluentApiTest(IFreeSql fsql) + { + var cf = fsql.CodeFirst; + cf.Entity(eb => + { + eb.ToTable("tb_song"); + eb.Ignore(a => a.Field1); + eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); + eb.Property(a => a.Url).HasMaxLength(100); + + eb.Property(a => a.RowVersion).IsRowVersion(); + eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp"); + + eb.HasKey(a => a.Id); + eb.HasIndex(a => a.Title).IsUnique().HasName("idx_xxx11"); + + //一对多、多对一 + eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); + + //多对多 + eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); + }); + cf.Entity(eb => + { + eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); + + eb.HasData(new[] + { + new SongType + { + Id = 1, + Name = "流行", + Songs = new List(new[] + { + new Song{ Title = "真的爱你" }, + new Song{ Title = "爱你一万年" }, + }) + }, + new SongType + { + Id = 2, + Name = "乡村", + Songs = new List(new[] + { + new Song{ Title = "乡里乡亲" }, + }) + }, + }); + }); + + cf.SyncStructure(); + cf.SyncStructure(); + } + + public class SongType + { + public int Id { get; set; } + public string Name { get; set; } + + public List Songs { get; set; } + } + + public class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime CreateTime { get; set; } + + public int TypeId { get; set; } + public SongType Type { get; set; } + public List Tags { get; set; } + + public int Field1 { get; set; } + public long RowVersion { get; set; } + } + public class Song_tag + { + public int Song_id { get; set; } + public Song Song { get; set; } + + public int Tag_id { get; set; } + public Tag Tag { get; set; } + } + + public class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string Name { get; set; } + + public List Songs { get; set; } + } +} diff --git a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs b/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent.cs similarity index 98% rename from Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs rename to FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent.cs index db7dd65f..388e7198 100644 --- a/Extensions/FreeSql.Extensions.EfCoreFluentApi/EfCoreTableFluent.cs +++ b/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent.cs @@ -31,6 +31,10 @@ namespace FreeSql.Extensions.EfCoreFluentApi public EfCoreColumnFluent Property(Expression> property) => new EfCoreColumnFluent(_tf.Property(property)); public EfCoreColumnFluent Property(string property) => new EfCoreColumnFluent(_tf.Property(property)); + /// + /// 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 + /// + /// public TableFluent Help() => _tf; #region HasKey diff --git a/FreeSql.DbContext/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Extensions/DependencyInjection.cs index 6e7fb6cd..dd96b306 100644 --- a/FreeSql.DbContext/Extensions/DependencyInjection.cs +++ b/FreeSql.DbContext/Extensions/DependencyInjection.cs @@ -1,12 +1,12 @@ #if netcoreapp -using Microsoft.Extensions.DependencyInjection; +using FreeSql; using System; using System.Linq; using System.Reflection; -namespace FreeSql +namespace Microsoft.Extensions.DependencyInjection { - public static class DbContextDependencyInjection + public static class FreeSqlDbContextDependencyInjection { static IServiceCollection AddFreeDbContext(this IServiceCollection services, Type dbContextType, Action options) { diff --git a/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs index c6084096..f0ad468e 100644 --- a/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs +++ b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -public static class FreeSqlDbContextExtensions +public static partial class FreeSqlDbContextExtensions { /// diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 8cf53748..299c91e5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -162,6 +162,25 @@ + + + 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 + + + + + + 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 + + + + + + 使用 Repository + EnableAddOrUpdateNavigateList + NoneParameter 方式插入种子数据 + + + + 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点 @@ -302,6 +321,15 @@ 例如:20191121_214504_1 + + + EFCore 99% 相似的 FluentApi 扩展方法 + + + + + + 创建普通数据上下文档对象 @@ -324,7 +352,7 @@ - + 返回默认仓库类 @@ -334,7 +362,7 @@ 数据过滤 + 验证 - + 返回默认仓库类,适用联合主键的仓储类 @@ -343,7 +371,7 @@ 数据过滤 + 验证 - + 返回仓库类 @@ -353,7 +381,7 @@ 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - + 创建基于仓储功能的工作单元,务必使用 using 包含使用 diff --git a/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs b/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs index e0ae86eb..087f176d 100644 --- a/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs +++ b/FreeSql.DbContext/Repository/Extensions/DependencyInjection.cs @@ -1,11 +1,10 @@ #if netcoreapp - -using Microsoft.Extensions.DependencyInjection; +using FreeSql; using System; using System.Linq; using System.Reflection; -namespace FreeSql +namespace Microsoft.Extensions.DependencyInjection { public static class FreeSqlRepositoryDependencyInjection { @@ -41,5 +40,4 @@ namespace FreeSql } } } - #endif \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs b/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs index af4aaaaa..9b4ed306 100644 --- a/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs +++ b/FreeSql.DbContext/Repository/Extensions/FreeSqlRepositoryExtensions.cs @@ -3,7 +3,7 @@ using System; using System.Linq; using System.Linq.Expressions; -public static class FreeSqlRepositoryExtensions +partial class FreeSqlDbContextExtensions { /// diff --git a/FreeSql.sln b/FreeSql.sln index 3ffc7d3d..7cf8a130 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -72,8 +72,6 @@ Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "FreeSql.Tests.VB", "FreeSql EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MsAccess", "Providers\FreeSql.Provider.MsAccess\FreeSql.Provider.MsAccess.csproj", "{B397A761-F646-41CF-A160-AB6C05DAF2FB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.EfCoreFluentApi", "Extensions\FreeSql.Extensions.EfCoreFluentApi\FreeSql.Extensions.EfCoreFluentApi.csproj", "{773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.All", "FreeSql.All\FreeSql.All.csproj", "{933115AD-769C-4FBE-B000-2E8CF2292377}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.Linq", "Extensions\FreeSql.Extensions.Linq\FreeSql.Extensions.Linq.csproj", "{57B3F5B0-D46A-4442-8EC6-9A9A784404B7}" @@ -438,18 +436,6 @@ Global {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x64.Build.0 = Release|Any CPU {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x86.ActiveCfg = Release|Any CPU {B397A761-F646-41CF-A160-AB6C05DAF2FB}.Release|x86.Build.0 = Release|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|x64.ActiveCfg = Debug|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|x64.Build.0 = Debug|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|x86.ActiveCfg = Debug|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Debug|x86.Build.0 = Debug|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|Any CPU.Build.0 = Release|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x64.ActiveCfg = Release|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x64.Build.0 = Release|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x86.ActiveCfg = Release|Any CPU - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F}.Release|x86.Build.0 = Release|Any CPU {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|Any CPU.Build.0 = Debug|Any CPU {933115AD-769C-4FBE-B000-2E8CF2292377}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -511,7 +497,6 @@ Global {1674BCE3-EEB4-4003-A2A7-06F51EFAEA23} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {6A3A4470-7DF7-411B-AAD7-755D7A9DB5A4} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {B397A761-F646-41CF-A160-AB6C05DAF2FB} = {2A381C57-2697-427B-9F10-55DA11FD02E4} - {773D5B63-DE6E-46DB-AF16-6FB1C1352B3F} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {57B3F5B0-D46A-4442-8EC6-9A9A784404B7} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {E74D90E8-1CBC-4677-817B-1CA05AB97937} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs similarity index 96% rename from FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs rename to FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index 67faf87a..63c48c4e 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -3,7 +3,7 @@ using System; using System.Threading; [ExpressionCall] -public static class FreeSqlGlobalExpressionCall +public static class FreeSqlGlobalExpressionCallExtensions { public static ThreadLocal expContext = new ThreadLocal(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 891fa7b5..cb7ec67f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2305,6 +2305,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 }) + + + + + + 可自定义解析表达式 @@ -2651,7 +2782,7 @@ - 在外部配置实体的特性 + FreeSql FluentApi 配置实体,方法名与特性相同 @@ -2659,7 +2790,7 @@ - 在外部配置实体的特性 + FreeSql FluentApi 配置实体,方法名与特性相同 @@ -2667,7 +2798,7 @@ - 获取在外部配置实体的特性 + 获取 FreeSql FluentApi 配置实体的元数据 未使用ConfigEntity配置时,返回null @@ -2825,6 +2956,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2895,6 +3032,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3078,7 +3221,7 @@ BigApple -> bigapple - + C#: that >= between && that <= and SQL: that BETWEEN between AND and @@ -3088,7 +3231,7 @@ - + 注意:这个方法和 Between 有细微区别 C#: that >= start && that < end @@ -3527,167 +3670,4 @@ - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index c5cd16e6..e0ee5e45 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -86,21 +86,21 @@ namespace FreeSql /// DbInfoResult GetDbInfo(Type type); /// - /// 在外部配置实体的特性 + /// FreeSql FluentApi 配置实体,方法名与特性相同 /// /// /// /// ICodeFirst ConfigEntity(Action> entity); /// - /// 在外部配置实体的特性 + /// FreeSql FluentApi 配置实体,方法名与特性相同 /// /// /// /// ICodeFirst ConfigEntity(Type type, Action entity); /// - /// 获取在外部配置实体的特性 + /// 获取 FreeSql FluentApi 配置实体的元数据 /// /// /// 未使用ConfigEntity配置时,返回null From 72208775904f442b72342831cb31065d10ebb898 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Apr 2020 12:32:24 +0800 Subject: [PATCH 0576/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSqlBuild?= =?UTF-8?q?er=20=E8=87=AA=E5=8A=A8=E8=AF=86=E5=88=AB=20EFCore=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=89=B9=E6=80=A7=20Key/Required/NotMapped/Table/Colu?= =?UTF-8?q?mn=EF=BC=9B#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++ .../DataAnnotations/EFCoreAttributeTest.cs | 110 ++++++++++++++++++ FreeSql/FreeSqlBuilder.cs | 76 +++++++++++- 3 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 299c91e5..8fd2938a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,6 +120,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -388,5 +395,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs new file mode 100644 index 00000000..f3dd26ae --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs @@ -0,0 +1,110 @@ +using FreeSql.Tests.DataContext.SqlServer; +using System; +using System.Data.SqlClient; +using Xunit; + +namespace FreeSql.Tests.DataAnnotations +{ + public class EFCoreAttributeTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void TableAttribute() + { + fsql.CodeFirst.SyncStructure(); + fsql.CodeFirst.SyncStructure(); + Assert.Equal("eftesttb_01", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb01)).DbName); + Assert.Equal("dbo.eftesttb_02", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb02)).DbName); + } + [System.ComponentModel.DataAnnotations.Schema.Table("eftesttb_01")] + class eftesttb01 + { + public Guid id { get; set; } + } + [System.ComponentModel.DataAnnotations.Schema.Table("eftesttb_02", Schema = "dbo")] + class eftesttb02 + { + public Guid id { get; set; } + } + + [Fact] + public void MaxLengthAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.Equal("NVARCHAR(100)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb03)).ColumnsByCs["title"].Attribute.DbType); + } + class eftesttb03 + { + public Guid id { get; set; } + [System.ComponentModel.DataAnnotations.MaxLength(100)] + public string title { get; set; } + } + + [Fact] + public void RequiredAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.False(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb04)).ColumnsByCs["title"].Attribute.IsNullable); + } + class eftesttb04 + { + public Guid id { get; set; } + [System.ComponentModel.DataAnnotations.Required] + public string title { get; set; } + } + + [Fact] + public void NotMappedAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.False(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb05)).ColumnsByCsIgnore.ContainsKey("id")); + Assert.True(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb05)).ColumnsByCsIgnore.ContainsKey("title")); + } + class eftesttb05 + { + public Guid id { get; set; } + [System.ComponentModel.DataAnnotations.Schema.NotMapped] + public string title { get; set; } + } + + [Fact] + public void ColumnAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.Equal("title_01", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title1"].Attribute.Name); + Assert.Equal("title_02", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title2"].Attribute.Name); + Assert.Equal("title_03", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title3"].Attribute.Name); + + Assert.Equal(99, fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title2"].Attribute.Position); + Assert.Equal(98, fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title3"].Attribute.Position); + + Assert.Equal("NVARCHAR(255)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title1"].Attribute.DbType); + Assert.Equal("NVARCHAR(255)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title2"].Attribute.DbType); + Assert.Equal("VARCHAR(100)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title3"].Attribute.DbType); + } + class eftesttb06 + { + public Guid id { get; set; } + [System.ComponentModel.DataAnnotations.Schema.Column("title_01")] + public string title1 { get; set; } + [System.ComponentModel.DataAnnotations.Schema.Column("title_02", Order = 99)] + public string title2 { get; set; } + [System.ComponentModel.DataAnnotations.Schema.Column("title_03", Order = 98, TypeName = "varchar(100)")] + public string title3 { get; set; } + } + + [Fact] + public void KeyAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.True(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb07)).ColumnsByCs["title"].Attribute.IsPrimary); + } + class eftesttb07 + { + public Guid id { get; set; } + [System.ComponentModel.DataAnnotations.Key] + public string title { get; set; } + } + } +} diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 51a13af8..4a07cecf 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -286,7 +286,7 @@ namespace FreeSql break; } } - //处理 MaxLength + //处理 MaxLength、EFCore 特性 ret.Aop.ConfigEntityProperty += new EventHandler((s, e) => { object[] attrs = null; @@ -296,17 +296,83 @@ namespace FreeSql } catch { } - var maxlenAttr = attrs?.Where(a => { + var dyattr = attrs?.Where(a => { return ((a as Attribute)?.TypeId as Type)?.Name == "MaxLengthAttribute"; }).FirstOrDefault(); - if (maxlenAttr != null) + if (dyattr != null) { - var lenProp = maxlenAttr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).FirstOrDefault(); - if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval) && tryval != 0) + var lenProp = dyattr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).FirstOrDefault(); + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(dyattr, null)), out var tryval) && tryval != 0) { e.ModifyResult.StringLength = tryval; } } + + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.RequiredAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + e.ModifyResult.IsNullable = false; + } + + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + e.ModifyResult.IsIgnore = true; + } + + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.Schema.ColumnAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + var name = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string) && a.Name == "Name").FirstOrDefault()?.GetValue(dyattr, null)?.ToString(); + short.TryParse(string.Concat(dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(int) && a.Name == "Order").FirstOrDefault()?.GetValue(dyattr, null)), out var order); + var typeName = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string) && a.Name == "TypeName").FirstOrDefault()?.GetValue(dyattr, null)?.ToString(); + + if (string.IsNullOrEmpty(name) == false) + e.ModifyResult.Name = name; + if (order != 0) + e.ModifyResult.Position = order; + if (string.IsNullOrEmpty(typeName) == false) + e.ModifyResult.DbType = typeName; + } + + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.KeyAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + e.ModifyResult.IsPrimary = true; + } + }); + //EFCore 特性 + ret.Aop.ConfigEntity += new EventHandler((s, e) => + { + object[] attrs = null; + try + { + attrs = e.EntityType.GetCustomAttributes(false).ToArray(); //.net core 反射存在版本冲突问题,导致该方法异常 + } + catch { } + + var dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.Schema.TableAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + var name = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string) && a.Name == "Name").FirstOrDefault()?.GetValue(dyattr, null)?.ToString(); + var schema = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string) && a.Name == "Schema").FirstOrDefault()?.GetValue(dyattr, null)?.ToString(); + if (string.IsNullOrEmpty(name) == false && string.IsNullOrEmpty(schema) == false) + e.ModifyResult.Name = $"{schema}.{name}"; + else if (string.IsNullOrEmpty(name) == false) + e.ModifyResult.Name = name; + else if (string.IsNullOrEmpty(schema) == false) + e.ModifyResult.Name = $"{schema}.{e.EntityType.Name}"; + } }); } From 3f9cfc1491e65cbf8a2b0264d8ae7d91d6773412 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Apr 2020 13:13:21 +0800 Subject: [PATCH 0577/1029] update tests --- .../FreeSql.Tests.DbContext/UnitTest1.cs | 16 ++++++++-------- .../SqlServerAdo/SqlServerConnectionPool.cs | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index 17f73605..663056ed 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -26,28 +26,28 @@ namespace FreeSql.Tests g.sqlite.Delete().Where("1=1").ExecuteAffrows(); BaseEntity.Initialization(g.sqlite); - userinfo user = new userinfo { userid = 1 }; + userinfo user = new userinfo { userid = 1, badgenumber = "", Name="", IDCardNo="" }; user.Insert(); user.depts = new List( new[] { - new DEPARTMENTS { deptid = 1, deptcode = "01" }, - new DEPARTMENTS { deptid = 2, deptcode = "02" }, - new DEPARTMENTS { deptid = 3, deptcode = "03" }, + new DEPARTMENTS { deptid = 1, deptcode = "01", deptname = "" }, + new DEPARTMENTS { deptid = 2, deptcode = "02", deptname = "" }, + new DEPARTMENTS { deptid = 3, deptcode = "03" , deptname = ""}, }); user.SaveMany("depts"); user.depts = new List( new[] { - new DEPARTMENTS { deptid = 1, deptcode = "01" }, - new DEPARTMENTS { deptid = 2, deptcode = "02" }, - new DEPARTMENTS { deptid = 4, deptcode = "04" }, + new DEPARTMENTS { deptid = 1, deptcode = "01", deptname = "" }, + new DEPARTMENTS { deptid = 2, deptcode = "02", deptname = "" }, + new DEPARTMENTS { deptid = 4, deptcode = "04", deptname = "" }, }); user.SaveMany("depts"); user.depts = new List( new[] { - new DEPARTMENTS { deptid = 2, deptcode = "02" }, + new DEPARTMENTS { deptid = 2, deptcode = "02", deptname = "" }, }); user.SaveMany("depts"); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 4cba9ac5..6e543e31 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -71,7 +71,7 @@ namespace FreeSql.SqlServer Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); - PoolSize = poolsize +connStrIncr; + PoolSize = poolsize + connStrIncr; _connectionString = m.Success ? Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : $"{_connectionString};Max pool size={PoolSize}"; From 83e19131baa157c4a433b718dacc655b13de0763 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 17 Apr 2020 13:28:11 +0800 Subject: [PATCH 0578/1029] update readme --- functions07.png | Bin 103106 -> 0 bytes functions08.png | Bin 0 -> 115875 bytes readme.md | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 functions07.png create mode 100644 functions08.png diff --git a/functions07.png b/functions07.png deleted file mode 100644 index 7e6d9bc339b42b362fe5c895b3020b9e986e3b99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103106 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 V82e?`v@qb`Bl*X2r84Hh{||OVdg1^8 diff --git a/functions08.png b/functions08.png new file mode 100644 index 0000000000000000000000000000000000000000..90620eec6da5a7f91ea4a1ab92fb7dec16f9db5e GIT binary patch literal 115875 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 z

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 literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index dc5955ea..99222c1d 100644 --- a/readme.md +++ b/readme.md @@ -41,7 +41,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [内容管理系统](https://github.com/hejiyong/fscms)

- +

## Quick start @@ -210,5 +210,5 @@ L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.9 | | | | - | - | -| | | +| | | From 5248b9126d095775438a8cd6ac12048042e7b33e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 17 Apr 2020 13:37:04 +0800 Subject: [PATCH 0579/1029] update Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 99222c1d..5cef837c 100644 --- a/readme.md +++ b/readme.md @@ -204,7 +204,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、寒空飞箭(Colder框架作者) 66元、习惯与被习惯 100元 > Thank you for your donation From 1fa3c47ea1bd18fc27d9c72fc4c12b2f391735b4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 17 Apr 2020 13:48:04 +0800 Subject: [PATCH 0580/1029] update Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 5cef837c..cc4e5957 100644 --- a/readme.md +++ b/readme.md @@ -204,7 +204,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、寒空飞箭(Colder框架作者) 66元、习惯与被习惯 100元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元 > Thank you for your donation From c0d29b39065bd4a549dcc27696671415c3e35393 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 18 Apr 2020 14:50:30 +0800 Subject: [PATCH 0581/1029] v1.4.0-preview0418 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- .../Repository/Repository/BaseRepository.cs | 9 ++++----- .../Repository/Repository/BaseRepositoryAsync.cs | 9 ++++----- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 3ab0cf88..961858fb 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 8a1f8b55..e5202787 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a73f830a..555c8d60 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index ff4e9380..19d913ed 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index f5368dff..ee1590b2 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0415 + 1.4.0-preview0418 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 184ce438..850987c9 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4cbfea5f..162157fd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index de6d38f4..a0d55e77 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -84,7 +84,6 @@ namespace FreeSql _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); return affrows; } - public virtual int Delete(TEntity entity) { _dbset.Remove(entity); @@ -109,12 +108,12 @@ namespace FreeSql return entitys.ToList(); } - public int Update(TEntity entity) + public virtual int Update(TEntity entity) { _dbset.Update(entity); return _db.SaveChanges(); } - public int Update(IEnumerable entitys) + public virtual int Update(IEnumerable entitys) { _dbset.UpdateRange(entitys); return _db.SaveChanges(); @@ -129,7 +128,7 @@ namespace FreeSql } public void FlushState() => _dbset.FlushState(); - public TEntity InsertOrUpdate(TEntity entity) + public virtual TEntity InsertOrUpdate(TEntity entity) { _dbset.AddOrUpdate(entity); _db.SaveChanges(); @@ -161,7 +160,7 @@ namespace FreeSql } public virtual int Delete(TKey id) => Delete(CheckTKeyAndReturnIdEntity(id)); - public TEntity Find(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); + public virtual TEntity Find(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); public TEntity Get(TKey id) => Find(id); } } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs index 3cded670..431db113 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs @@ -21,7 +21,6 @@ namespace FreeSql _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); return affrows; } - public virtual Task DeleteAsync(TEntity entity) { _dbset.Remove(entity); @@ -46,18 +45,18 @@ namespace FreeSql return entitys.ToList(); } - public Task UpdateAsync(TEntity entity) + public virtual Task UpdateAsync(TEntity entity) { _dbset.Update(entity); return _db.SaveChangesAsync(); } - public Task UpdateAsync(IEnumerable entitys) + public virtual Task UpdateAsync(IEnumerable entitys) { _dbset.UpdateRange(entitys); return _db.SaveChangesAsync(); } - async public Task InsertOrUpdateAsync(TEntity entity) + async public virtual Task InsertOrUpdateAsync(TEntity entity) { await _dbset.AddOrUpdateAsync(entity); await _db.SaveChangesAsync(); @@ -74,7 +73,7 @@ namespace FreeSql partial class BaseRepository { public virtual Task DeleteAsync(TKey id) => DeleteAsync(CheckTKeyAndReturnIdEntity(id)); - public Task FindAsync(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(); + public virtual Task FindAsync(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(); public Task GetAsync(TKey id) => FindAsync(id); } } diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 9fb8b314..63183744 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9c1133ae..69403db9 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index a2529af8..875d970b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 3a80cc55..d0903942 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5b631066..d62d832d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fb0c1005..ed5f821d 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 11e7e84e..2f84f309 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d96dee52..acc40c68 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b8038e52..b995aa73 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e0afcb4b..46e6615b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f40dd8f5..0a082e83 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0415 + 1.4.0-preview0418 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From a0e18b1a687967c54caded5b798429eb0f518138 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Apr 2020 00:09:24 +0800 Subject: [PATCH 0582/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Exte?= =?UTF-8?q?nsions.JsonMap=20FluentApi=20=E6=89=A9=E5=B1=95=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=9B#279?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 13 ++- .../FreeSql.Extensions.JsonMap.xml | 2 +- .../FreeSql.Extensions.JsonMap/JsonMapCore.cs | 92 ++++++++++--------- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---- FreeSql/DataAnnotations/ColumnFluent.cs | 10 +- FreeSql/DataAnnotations/TableFluent.cs | 8 +- 6 files changed, 70 insertions(+), 71 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 0db13185..e800ef21 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -27,6 +27,8 @@ namespace base_entity [JsonMap] public T Config { get; set; } + + public T Config2 { get; set; } } public class Products : BaseEntity @@ -89,10 +91,15 @@ namespace base_entity var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); BaseEntity.Orm.UseJsonMap(); + BaseEntity.Orm.UseJsonMap(); + BaseEntity.Orm.CodeFirst.ConfigEntity>(a => + { + a.Property(b => b.Config2).JsonMap(); + }); - new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); - new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" } }.Save(); - new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" } }.Save(); + new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); + new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); + new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); var testconfigs11 = S_SysConfig.Select.ToList(); var repo = BaseEntity.Orm.Select().Limit(10).ToList(); diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml index 6c47f3b3..9829e929 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml @@ -9,7 +9,7 @@ 当实体类属性为【对象】时,以JSON形式映射存储
- + 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index 32647dae..a0f6855d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -6,59 +6,61 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Threading; -namespace FreeSql.Extensions +public static class FreeSqlJsonMapCoreExtensions { - public static class JsonMapCore + static int _isAoped = 0; + static ConcurrentDictionary _dicTypes = new ConcurrentDictionary(); + static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); + static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); + static ConcurrentDictionary> _dicJsonMapFluentApi = new ConcurrentDictionary>(); + + public static ColumnFluent JsonMap(this ColumnFluent col) { - static bool _isAoped = false; - static object _isAopedLock = new object(); - static ConcurrentDictionary _dicTypes = new ConcurrentDictionary(); - static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); - static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); + _dicJsonMapFluentApi.GetOrAdd(col._entityType, et => new ConcurrentDictionary()) + .GetOrAdd(col._property.Name, pn => true); + return col; + } - /// - /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 - /// - /// - public static void UseJsonMap(this IFreeSql that) + /// + /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 + /// + /// + public static void UseJsonMap(this IFreeSql that) + { + UseJsonMap(that, JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings()); + } + + public static void UseJsonMap(this IFreeSql that, JsonSerializerSettings settings) + { + if (Interlocked.CompareExchange(ref _isAoped, 1, 0) == 0) { - UseJsonMap(that, Newtonsoft.Json.JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings()); + FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => + { + if (_dicTypes.ContainsKey(type)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); + return null; + }); } - public static void UseJsonMap(this IFreeSql that, JsonSerializerSettings settings) + that.Aop.ConfigEntityProperty += new EventHandler((s, e) => { - if (_isAoped == false) - lock (_isAopedLock) - if (_isAoped == false) + var isJsonMap = e.Property.GetCustomAttributes(typeof(JsonMapAttribute), false).Any() || _dicJsonMapFluentApi.TryGetValue(e.EntityType, out var tryjmfu) && tryjmfu.ContainsKey(e.Property.Name); + if (isJsonMap) + { + e.ModifyResult.MapType = typeof(string); + if (_dicTypes.TryAdd(e.Property.PropertyType, true)) + { + FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => { - _isAoped = true; - - FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => - { - if (_dicTypes.ContainsKey(type)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); - return null; - }); - - that.Aop.ConfigEntityProperty += new EventHandler((s, e) => - { - if (e.Property.GetCustomAttributes(typeof(JsonMapAttribute), false).Any()) - { - e.ModifyResult.MapType = typeof(string); - if (_dicTypes.TryAdd(e.Property.PropertyType, true)) - { - FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => - { - return Expression.IfThenElse( - Expression.TypeEqual(valueExp, e.Property.PropertyType), - Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(settings)), typeof(object)), - elseExp); - }); - } - } - }); - } - } - + return Expression.IfThenElse( + Expression.TypeEqual(valueExp, e.Property.PropertyType), + Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(settings)), typeof(object)), + elseExp); + }); + } + } + }); } } + diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 8fd2938a..299c91e5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,13 +120,6 @@ 清空状态数据
- - - 根据 lambda 条件删除数据 - - - - 添加 @@ -395,14 +388,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index 2a897e6f..4a1adc93 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -1,16 +1,22 @@ using System; +using System.Collections.Generic; +using System.Reflection; namespace FreeSql.DataAnnotations { public class ColumnFluent { - public ColumnFluent(ColumnAttribute column) + public ColumnFluent(ColumnAttribute column, PropertyInfo property, Type entityType) { _column = column; + _property = property; + _entityType = entityType; } - ColumnAttribute _column; + public ColumnAttribute _column; + public PropertyInfo _property; + public Type _entityType; /// /// 数据库列名 /// diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index f1e93d42..46c1f760 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -47,9 +47,9 @@ namespace FreeSql.DataAnnotations public ColumnFluent Property(string proto) { - if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); - var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto }); - return new ColumnFluent(col); + if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); + var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { Name = proto }); + return new ColumnFluent(col, tryProto, _entityType); } /// @@ -131,7 +131,7 @@ namespace FreeSql.DataAnnotations { if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { Name = proto }); - return new ColumnFluent(col); + return new ColumnFluent(col, tryProto, typeof(T)); } /// From 6c8c70426075319bbacaaa39ec2c49ef9565f524 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Apr 2020 00:10:59 +0800 Subject: [PATCH 0583/1029] v1.4.0-preview0419 #279 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 961858fb..3617a2b3 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e5202787..94950ef3 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 555c8d60..fbac48e6 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 19d913ed..bd33c76c 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index ee1590b2..abc82fb8 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0418 + 1.4.0-preview0419 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 850987c9..beeaabd0 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 162157fd..8e9e98bf 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 299c91e5..8fd2938a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,6 +120,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -388,5 +395,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 63183744..48b4277b 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 69403db9..4fe13219 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 875d970b..ededf5bb 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index d0903942..55dbe18c 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d62d832d..bf71b119 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ed5f821d..91761eed 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 2f84f309..39ce700c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index acc40c68..1eccd0bf 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b995aa73..1053cce7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 46e6615b..324a780f 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 0a082e83..6eda75de 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0418 + 1.4.0-preview0419 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 505100c8527a70c658476d0ba9408c59b2e5c3de Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Apr 2020 14:47:37 +0800 Subject: [PATCH 0584/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20InsertProvid?= =?UTF-8?q?er=20=E5=AF=B9=20InsertValueSql=20=E8=87=AA=E5=A2=9E=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E7=9A=84=E5=A4=84=E7=90=86=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../Internal/CommonProvider/InsertProvider.cs | 4 ++-- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 8fd2938a..299c91e5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,13 +120,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -395,14 +388,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 7780ba66..a88dbd19 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -501,7 +501,7 @@ namespace FreeSql.Internal.CommonProvider var colidx = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx > 0) sb.Append(", "); @@ -520,7 +520,7 @@ namespace FreeSql.Internal.CommonProvider var colidx2 = 0; foreach (var col in _table.Columns.Values) { - if (col.Attribute.IsIdentity && _insertIdentity == false) continue; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; if (colidx2 > 0) sb.Append(", "); From 67222ba007cf5adf6cd996dbd2858d705939f873 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 20 Apr 2020 09:35:03 +0800 Subject: [PATCH 0585/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect.From?= =?UTF-8?q?=20=E5=86=85=E9=83=A8=20WhereIf=20=E4=BA=8C=E6=AC=A1=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20bug=EF=BC=9B1.4.0-previe?= =?UTF-8?q?w0420?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../MySql/Curd/MySqlSelectTest.cs | 9 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 143 ------------------ .../SelectProvider/Select1Provider.cs | 3 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 42 insertions(+), 165 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 3617a2b3..1949f368 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 94950ef3..09e4604c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index fbac48e6..21cc649e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index bd33c76c..580d176c 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index abc82fb8..025acc6c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0419 + 1.4.0-preview0420 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index beeaabd0..af5afb66 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8e9e98bf..b3d819f7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 299c91e5..8fd2938a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,6 +120,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -388,5 +395,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 48b4277b..f5244d54 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index afbaffc4..bfe8db80 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -422,19 +422,24 @@ namespace FreeSql.Tests.MySql [Fact] public void From() { + var testid = ""; var query2 = select.From((s, b) => s .LeftJoin(a => a.TypeGuid == b.Guid) + .WhereIf(string.IsNullOrEmpty(testid), a => a.Clicks == 11) + .WhereIf(!string.IsNullOrEmpty(testid), a => a.Clicks == 12) ); var sql2 = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid`", sql2); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` WHERE (a.`Clicks` = 11)", sql2); query2.ToList(); var query3 = select.From((s, b, c) => s .LeftJoin(a => a.TypeGuid == b.Guid) .LeftJoin(a => b.ParentId == c.Id) + .WhereIf(string.IsNullOrEmpty(testid), a => a.Clicks == 11) + .WhereIf(!string.IsNullOrEmpty(testid), a => a.Clicks == 12) ); var sql3 = query3.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql3); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id` WHERE (a.`Clicks` = 11)", sql3); query3.ToList(); } [Fact] diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4fe13219..9ff421f7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index cb7ec67f..9780f9de 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2305,137 +2305,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2956,12 +2825,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3032,12 +2895,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 50b62e21..48714a49 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -55,8 +55,7 @@ namespace FreeSql.Internal.CommonProvider { case "Where": this.InternalWhere(expCall.Arguments[0]); break; case "WhereIf": - var whereIfCond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); - if (whereIfCond == "1" || whereIfCond == "'t'" || whereIfCond == "-1") //MsAccess -1 + if ((bool)Expression.Lambda(expCall.Arguments[0]).Compile().DynamicInvoke()) this.InternalWhere(expCall.Arguments[1]); break; case "OrderBy": diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index ededf5bb..60362d27 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 55dbe18c..4776a3a5 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index bf71b119..b88cacd1 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 91761eed..ef03faa4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 39ce700c..755c34ef 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 1eccd0bf..ac8c9d25 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1053cce7..bdec4ff7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 324a780f..86a51985 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 6eda75de..9942a29d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0419 + 1.4.0-preview0420 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From b1660e87a510f37fe426b9a2189ae631cd0d4a92 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 20 Apr 2020 21:13:44 +0800 Subject: [PATCH 0586/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20DbContext=20?= =?UTF-8?q?=E4=B8=8E=20EFCore=20=E7=9B=B8=E4=BC=BC=E7=9A=84=20FluentApi=20?= =?UTF-8?q?=E5=AF=B9=E5=8A=A8=E6=80=81=E7=B1=BB=E5=9E=8B=E7=9A=84=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=9B#281?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/efcore_to_freesql/Startup.cs | 3 +- .../EfCoreFluentApiExtensions.cs | 77 +++- .../EfCoreFluentApi/EfCoreTableFluent.cs | 267 +++++-------- .../EfCoreFluentApi/EfCoreTableFluent`1.cs | 365 ++++++++++++++++++ FreeSql.DbContext/FreeSql.DbContext.xml | 33 +- FreeSql/DataAnnotations/TableFluent.cs | 5 + FreeSql/FreeSql.xml | 143 +++++++ 7 files changed, 701 insertions(+), 192 deletions(-) create mode 100644 FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent`1.cs diff --git a/Examples/efcore_to_freesql/Startup.cs b/Examples/efcore_to_freesql/Startup.cs index 2271d74f..0245f0c9 100644 --- a/Examples/efcore_to_freesql/Startup.cs +++ b/Examples/efcore_to_freesql/Startup.cs @@ -27,7 +27,8 @@ namespace efcore_to_freesql .UseAutoSyncStructure(true) .Build(); - FreeSqlDbContextExtensions.EfCoreFluentApiTest(Fsql); + //FreeSqlDbContextExtensions.EfCoreFluentApiTestGeneric(Fsql); + FreeSqlDbContextExtensions.EfCoreFluentApiTestDynamic(Fsql); DBContexts.BaseDBContext.Fsql = Fsql; diff --git a/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs b/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs index 30661258..e31ac3fe 100644 --- a/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs +++ b/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs @@ -9,7 +9,7 @@ using FreeSql.Internal.CommonProvider; partial class FreeSqlDbContextExtensions { /// - /// EFCore 99% 相似的 FluentApi 扩展方法 + /// EFCore 95% 相似的 FluentApi 扩展方法 /// /// /// @@ -21,13 +21,26 @@ partial class FreeSqlDbContextExtensions codeFirst.ConfigEntity(tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf))); return codeFirst; } + /// + /// EFCore 95% 相似的 FluentApi 扩展方法 + /// + /// + /// 实体类型 + /// + /// + public static ICodeFirst Entity(this ICodeFirst codeFirst, Type entityType, Action modelBuilder) + { + var cf = codeFirst as CodeFirstProvider; + codeFirst.ConfigEntity(entityType, tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf, entityType))); + return codeFirst; + } - public static void EfCoreFluentApiTest(IFreeSql fsql) + public static void EfCoreFluentApiTestGeneric(IFreeSql fsql) { var cf = fsql.CodeFirst; cf.Entity(eb => { - eb.ToTable("tb_song"); + eb.ToTable("tb_song1"); eb.Ignore(a => a.Field1); eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); eb.Property(a => a.Url).HasMaxLength(100); @@ -36,7 +49,7 @@ partial class FreeSqlDbContextExtensions eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp"); eb.HasKey(a => a.Id); - eb.HasIndex(a => a.Title).IsUnique().HasName("idx_xxx11"); + eb.HasIndex(a => a.Title).IsUnique().HasName("idx_tb_song1111"); //一对多、多对一 eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); @@ -46,6 +59,7 @@ partial class FreeSqlDbContextExtensions }); cf.Entity(eb => { + eb.ToTable("tb_songtype1"); eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); eb.HasData(new[] @@ -76,6 +90,61 @@ partial class FreeSqlDbContextExtensions cf.SyncStructure(); } + public static void EfCoreFluentApiTestDynamic(IFreeSql fsql) + { + var cf = fsql.CodeFirst; + cf.Entity(typeof(Song), eb => + { + eb.ToTable("tb_song2"); + eb.Ignore("Field1"); + eb.Property("Title").HasColumnType("varchar(50)").IsRequired(); + eb.Property("Url").HasMaxLength(100); + + eb.Property("RowVersion").IsRowVersion(); + eb.Property("CreateTime").HasDefaultValueSql("current_timestamp"); + + eb.HasKey("Id"); + eb.HasIndex("Title").IsUnique().HasName("idx_tb_song2222"); + + //一对多、多对一 + eb.HasOne("Type").HasForeignKey("TypeId").WithMany("Songs"); + + //多对多 + eb.HasMany("Tags").WithMany("Songs", typeof(Song_tag)); + }); + cf.Entity(typeof(SongType), eb => + { + eb.ToTable("tb_songtype2"); + eb.HasMany("Songs").WithOne("Type").HasForeignKey("TypeId"); + + eb.HasData(new[] + { + new SongType + { + Id = 1, + Name = "流行", + Songs = new List(new[] + { + new Song{ Title = "真的爱你" }, + new Song{ Title = "爱你一万年" }, + }) + }, + new SongType + { + Id = 2, + Name = "乡村", + Songs = new List(new[] + { + new Song{ Title = "乡里乡亲" }, + }) + }, + }); + }); + + cf.SyncStructure(); + cf.SyncStructure(); + } + public class SongType { public int Id { get; set; } diff --git a/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent.cs b/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent.cs index 388e7198..90200d24 100644 --- a/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent.cs +++ b/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -6,88 +7,73 @@ using FreeSql.DataAnnotations; namespace FreeSql.Extensions.EfCoreFluentApi { - public class EfCoreTableFluent + public class EfCoreTableFluent { IFreeSql _fsql; - TableFluent _tf; - internal EfCoreTableFluent(IFreeSql fsql, TableFluent tf) + TableFluent _tf; + internal Type _entityType; + internal EfCoreTableFluent(IFreeSql fsql, TableFluent tf, Type entityType) { _fsql = fsql; _tf = tf; + _entityType = entityType; } - public EfCoreTableFluent ToTable(string name) + public EfCoreTableFluent ToTable(string name) { _tf.Name(name); return this; } - public EfCoreTableFluent ToView(string name) + public EfCoreTableFluent ToView(string name) { _tf.DisableSyncStructure(true); _tf.Name(name); return this; } - public EfCoreColumnFluent Property(Expression> property) => new EfCoreColumnFluent(_tf.Property(property)); public EfCoreColumnFluent Property(string property) => new EfCoreColumnFluent(_tf.Property(property)); /// /// 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 /// /// - public TableFluent Help() => _tf; + public TableFluent Help() => _tf; #region HasKey - public EfCoreTableFluent HasKey(Expression> key) + public EfCoreTableFluent HasKey(string key) { - var exp = key?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 key 不能为 null"); - - switch (exp.NodeType) + if (key == null) throw new ArgumentException("参数错误 key 不能为 null"); + foreach (string name in key.Split(',')) { - case ExpressionType.MemberAccess: - _tf.Property((exp as MemberExpression).Member.Name).IsPrimary(true); - break; - case ExpressionType.New: - foreach (var member in (exp as NewExpression).Members) - _tf.Property(member.Name).IsPrimary(true); - break; + if (string.IsNullOrEmpty(name.Trim())) continue; + _tf.Property(name.Trim()).IsPrimary(true); } return this; } #endregion #region HasIndex - public HasIndexFluent HasIndex(Expression> index) + public HasIndexFluent HasIndex(string index) { - var exp = index?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 index 不能为 null"); - + if (index == null) throw new ArgumentException("参数错误 index 不能为 null"); var indexName = $"idx_{Guid.NewGuid().ToString("N").Substring(0, 8)}"; var columns = new List(); - switch (exp.NodeType) + foreach (string name in index.Split(',')) { - case ExpressionType.MemberAccess: - columns.Add((exp as MemberExpression).Member.Name); - break; - case ExpressionType.New: - foreach (var member in (exp as NewExpression).Members) - columns.Add(member.Name); - break; + if (string.IsNullOrEmpty(name.Trim())) continue; + columns.Add(name.Trim()); } _tf.Index(indexName, string.Join(", ", columns), false); return new HasIndexFluent(_tf, indexName, columns); } public class HasIndexFluent { - TableFluent _modelBuilder; + TableFluent _modelBuilder; string _indexName; List _columns; bool _isUnique; - internal HasIndexFluent(TableFluent modelBuilder, string indexName, List columns) + internal HasIndexFluent(TableFluent modelBuilder, string indexName, List columns) { _modelBuilder = modelBuilder; _indexName = indexName; @@ -110,230 +96,157 @@ namespace FreeSql.Extensions.EfCoreFluentApi #endregion #region HasOne - public HasOneFluent HasOne(Expression> one) + public HasOneFluent HasOne(string one) { - var exp = one?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); - - var oneProperty = ""; - switch (exp.NodeType) - { - case ExpressionType.MemberAccess: - oneProperty = (exp as MemberExpression).Member.Name; - break; - } - if (string.IsNullOrEmpty(oneProperty)) throw new ArgumentException("参数错误 one"); - return new HasOneFluent(_fsql, _tf, oneProperty); + if (string.IsNullOrEmpty(one)) throw new ArgumentException("参数错误 one 不能为 null"); + if (_entityType.GetPropertiesDictIgnoreCase().TryGetValue(one, out var oneProperty) == false) throw new ArgumentException($"参数错误 {one} 属性不存在"); + return new HasOneFluent(_fsql, _tf, _entityType, oneProperty.PropertyType, one); } - public class HasOneFluent + public class HasOneFluent { IFreeSql _fsql; - TableFluent _tf; + TableFluent _tf; + Type _entityType1; + Type _entityType2; string _selfProperty; string _selfBind; string _withManyProperty; string _withOneProperty; string _withOneBind; - internal HasOneFluent(IFreeSql fsql, TableFluent modelBuilder, string oneProperty) + internal HasOneFluent(IFreeSql fsql, TableFluent modelBuilder, Type entityType1, Type entityType2, string oneProperty) { _fsql = fsql; _tf = modelBuilder; + _entityType1 = entityType1; + _entityType2 = entityType2; _selfProperty = oneProperty; } - public HasOneFluent WithMany(Expression> many) + public HasOneFluent WithMany(string many) { - var exp = many?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); - - switch (exp.NodeType) - { - case ExpressionType.MemberAccess: - _withManyProperty = (exp as MemberExpression).Member.Name; - break; - } - if (string.IsNullOrEmpty(_withManyProperty)) throw new ArgumentException("参数错误 many"); + if (many == null) throw new ArgumentException("参数错误 many 不能为 null"); + if (_entityType2.GetPropertiesDictIgnoreCase().TryGetValue(many, out var manyProperty) == false) throw new ArgumentException($"参数错误 {many} 属性不存在"); + _withManyProperty = manyProperty.Name; if (string.IsNullOrEmpty(_selfBind) == false) - _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); + _fsql.CodeFirst.ConfigEntity(_entityType2, eb2 => eb2.Navigate(many, _selfBind)); return this; } - public HasOneFluent WithOne(Expression> one, Expression> foreignKey) + public HasOneFluent WithOne(string one, string foreignKey) { - var exp = one?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); + if (string.IsNullOrEmpty(one)) throw new ArgumentException("参数错误 one 不能为 null"); + if (_entityType1.GetPropertiesDictIgnoreCase().TryGetValue(one, out var oneProperty) == false) throw new ArgumentException($"参数错误 {one} 属性不存在"); + if (oneProperty != _entityType1) throw new ArgumentException($"参数错误 {one} 属性不存在"); + _withOneProperty = oneProperty.Name; - switch (exp.NodeType) + if (foreignKey == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + foreach (string name in foreignKey.Split(',')) { - case ExpressionType.MemberAccess: - _withOneProperty = (exp as MemberExpression).Member.Name; - break; - } - if (string.IsNullOrEmpty(_withOneProperty)) throw new ArgumentException("参数错误 one"); - - exp = foreignKey?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); - - switch (exp.NodeType) - { - case ExpressionType.MemberAccess: - _withOneBind = (exp as MemberExpression).Member.Name; - _withOneBind = _withOneBind.TrimStart(',', ' '); - break; - case ExpressionType.New: - _withOneBind = ""; - foreach (var member in (exp as NewExpression).Members) - _withOneBind += ", " + member.Name; - _withOneBind = _withOneBind.TrimStart(',', ' '); - break; + if (string.IsNullOrEmpty(name.Trim())) continue; + _withOneBind += ", " + name.Trim(); } if (string.IsNullOrEmpty(_withOneBind)) throw new ArgumentException("参数错误 foreignKey"); + _withOneBind = _withOneBind.TrimStart(',', ' '); if (string.IsNullOrEmpty(_selfBind) == false) - _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); + _fsql.CodeFirst.ConfigEntity(_entityType2, eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); return this; } - public HasOneFluent HasForeignKey(Expression> foreignKey) + public HasOneFluent HasForeignKey(string foreignKey) { - var exp = foreignKey?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); - - switch (exp.NodeType) + if (foreignKey == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + foreach (string name in foreignKey.Split(',')) { - case ExpressionType.MemberAccess: - _selfBind = (exp as MemberExpression).Member.Name; - _selfBind = _selfBind.TrimStart(',', ' '); - break; - case ExpressionType.New: - _selfBind = ""; - foreach (var member in (exp as NewExpression).Members) - _selfBind += ", " + member.Name; - _selfBind = _selfBind.TrimStart(',', ' '); - break; + if (string.IsNullOrEmpty(name.Trim())) continue; + _selfBind += ", " + name.Trim(); } if (string.IsNullOrEmpty(_selfBind)) throw new ArgumentException("参数错误 foreignKey"); + _selfBind = _selfBind.TrimStart(',', ' '); _tf.Navigate(_selfProperty, _selfBind); if (string.IsNullOrEmpty(_withManyProperty) == false) - _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); + _fsql.CodeFirst.ConfigEntity(_entityType2, eb2 => eb2.Navigate(_withManyProperty, _selfBind)); if (string.IsNullOrEmpty(_withOneProperty) == false && string.IsNullOrEmpty(_withOneBind) == false) - _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); + _fsql.CodeFirst.ConfigEntity(_entityType2, eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); return this; } } #endregion #region HasMany - public HasManyFluent HasMany(Expression>> many) + public HasManyFluent HasMany(string many) { - var exp = many?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); - - var manyProperty = ""; - switch (exp.NodeType) - { - case ExpressionType.MemberAccess: - manyProperty = (exp as MemberExpression).Member.Name; - break; - } - if (string.IsNullOrEmpty(manyProperty)) throw new ArgumentException("参数错误 many"); - return new HasManyFluent(_fsql, _tf, manyProperty); + if (string.IsNullOrEmpty(many)) throw new ArgumentException("参数错误 many 不能为 null"); + if (_entityType.GetPropertiesDictIgnoreCase().TryGetValue(many, out var manyProperty) == false) throw new ArgumentException($"参数错误 {many} 集合属性不存在"); + if (typeof(IEnumerable).IsAssignableFrom(manyProperty.PropertyType) == false || manyProperty.PropertyType.IsGenericType == false) throw new ArgumentException("参数错误 {many} 不是集合属性"); + return new HasManyFluent(_fsql, _tf, _entityType, manyProperty.PropertyType.GetGenericArguments()[0], manyProperty.Name); } - public class HasManyFluent + public class HasManyFluent { IFreeSql _fsql; - TableFluent _tf; + TableFluent _tf; + Type _entityType1; + Type _entityType2; string _selfProperty; string _selfBind; string _withOneProperty; string _withManyProperty; - internal HasManyFluent(IFreeSql fsql, TableFluent modelBuilder, string manyProperty) + internal HasManyFluent(IFreeSql fsql, TableFluent modelBuilder, Type entityType1, Type entityType2, string manyProperty) { _fsql = fsql; _tf = modelBuilder; + _entityType1 = entityType1; + _entityType2 = entityType2; _selfProperty = manyProperty; } - public void WithMany(Expression>> many, Type middleType) + public void WithMany(string many, Type middleType) { - var exp = many?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); - - switch (exp.NodeType) - { - case ExpressionType.MemberAccess: - _withManyProperty = (exp as MemberExpression).Member.Name; - break; - } - if (string.IsNullOrEmpty(_withManyProperty)) throw new ArgumentException("参数错误 many"); - + if (string.IsNullOrEmpty(many)) throw new ArgumentException("参数错误 many 不能为 null"); + if (_entityType2.GetPropertiesDictIgnoreCase().TryGetValue(many, out var manyProperty) == false) throw new ArgumentException($"参数错误 {many} 集合属性不存在"); + if (typeof(IEnumerable).IsAssignableFrom(manyProperty.PropertyType) == false || manyProperty.PropertyType.IsGenericType == false) throw new ArgumentException("参数错误 {many} 不是集合属性"); + _withManyProperty = manyProperty.Name; _tf.Navigate(_selfProperty, null, middleType); - _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, null, middleType)); + _fsql.CodeFirst.ConfigEntity(_entityType2, eb2 => eb2.Navigate(_withManyProperty, null, middleType)); } - public HasManyFluent WithOne(Expression> one) + public HasManyFluent WithOne(string one) { - var exp = one?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); - - switch (exp.NodeType) - { - case ExpressionType.MemberAccess: - _withOneProperty = (exp as MemberExpression).Member.Name; - break; - } - if (string.IsNullOrEmpty(_withOneProperty)) throw new ArgumentException("参数错误 one"); - + if (string.IsNullOrEmpty(one)) throw new ArgumentException("参数错误 one 不能为 null"); + if (_entityType2.GetPropertiesDictIgnoreCase().TryGetValue(one, out var oneProperty) == false) throw new ArgumentException($"参数错误 {one} 属性不存在"); + if (oneProperty.PropertyType != _entityType1) throw new ArgumentException($"参数错误 {one} 属性不存在"); + _withOneProperty = oneProperty.Name; if (string.IsNullOrEmpty(_selfBind) == false) - _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); + _fsql.CodeFirst.ConfigEntity(_entityType2, eb2 => eb2.Navigate(oneProperty.Name, _selfBind)); return this; } - public HasManyFluent HasForeignKey(Expression> foreignKey) + public HasManyFluent HasForeignKey(string foreignKey) { - var exp = foreignKey?.Body; - if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; - if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); - - switch (exp.NodeType) + if (foreignKey == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + foreach (string name in foreignKey.Split(',')) { - case ExpressionType.MemberAccess: - _selfBind = (exp as MemberExpression).Member.Name; - _selfBind = _selfBind.TrimStart(',', ' '); - break; - case ExpressionType.New: - _selfBind = ""; - foreach (var member in (exp as NewExpression).Members) - _selfBind += ", " + member.Name; - _selfBind = _selfBind.TrimStart(',', ' '); - break; + if (string.IsNullOrEmpty(name.Trim())) continue; + _selfBind += ", " + name.Trim(); } if (string.IsNullOrEmpty(_selfBind)) throw new ArgumentException("参数错误 foreignKey"); + _selfBind = _selfBind.TrimStart(',', ' '); _tf.Navigate(_selfProperty, _selfBind); if (string.IsNullOrEmpty(_withOneProperty) == false) - _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); + _fsql.CodeFirst.ConfigEntity(_entityType2, eb2 => eb2.Navigate(_withOneProperty, _selfBind)); return this; } } #endregion - public EfCoreTableFluent Ignore(Expression> property) + public EfCoreTableFluent Ignore(string property) { _tf.Property(property).IsIgnore(true); return this; } - public EfCoreTableFluent HasData(T data) => HasData(new[] { data }); /// /// 使用 Repository + EnableAddOrUpdateNavigateList + NoneParameter 方式插入种子数据 /// /// /// - public EfCoreTableFluent HasData(IEnumerable data) + public EfCoreTableFluent HasData(IEnumerable data) { if (data.Any() == false) return this; var sdCopy = data.Select(a => (object)a).ToList(); @@ -346,7 +259,7 @@ namespace FreeSql.Extensions.EfCoreFluentApi if (sd == null || sd.Any() == false) return; foreach (var et in e.EntityTypes) { - if (et != typeof(T)) continue; + if (et != _entityType) continue; if (_fsql.Select().AsType(et).Any()) continue; var repo = _fsql.GetRepository(); diff --git a/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent`1.cs b/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent`1.cs new file mode 100644 index 00000000..388e7198 --- /dev/null +++ b/FreeSql.DbContext/EfCoreFluentApi/EfCoreTableFluent`1.cs @@ -0,0 +1,365 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using FreeSql.DataAnnotations; + +namespace FreeSql.Extensions.EfCoreFluentApi +{ + public class EfCoreTableFluent + { + IFreeSql _fsql; + TableFluent _tf; + internal EfCoreTableFluent(IFreeSql fsql, TableFluent tf) + { + _fsql = fsql; + _tf = tf; + } + + public EfCoreTableFluent ToTable(string name) + { + _tf.Name(name); + return this; + } + public EfCoreTableFluent ToView(string name) + { + _tf.DisableSyncStructure(true); + _tf.Name(name); + return this; + } + + public EfCoreColumnFluent Property(Expression> property) => new EfCoreColumnFluent(_tf.Property(property)); + public EfCoreColumnFluent Property(string property) => new EfCoreColumnFluent(_tf.Property(property)); + + /// + /// 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 + /// + /// + public TableFluent Help() => _tf; + + #region HasKey + public EfCoreTableFluent HasKey(Expression> key) + { + var exp = key?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 key 不能为 null"); + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _tf.Property((exp as MemberExpression).Member.Name).IsPrimary(true); + break; + case ExpressionType.New: + foreach (var member in (exp as NewExpression).Members) + _tf.Property(member.Name).IsPrimary(true); + break; + } + return this; + } + #endregion + + #region HasIndex + public HasIndexFluent HasIndex(Expression> index) + { + var exp = index?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 index 不能为 null"); + + var indexName = $"idx_{Guid.NewGuid().ToString("N").Substring(0, 8)}"; + var columns = new List(); + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + columns.Add((exp as MemberExpression).Member.Name); + break; + case ExpressionType.New: + foreach (var member in (exp as NewExpression).Members) + columns.Add(member.Name); + break; + } + _tf.Index(indexName, string.Join(", ", columns), false); + return new HasIndexFluent(_tf, indexName, columns); + } + public class HasIndexFluent + { + TableFluent _modelBuilder; + string _indexName; + List _columns; + bool _isUnique; + + internal HasIndexFluent(TableFluent modelBuilder, string indexName, List columns) + { + _modelBuilder = modelBuilder; + _indexName = indexName; + _columns = columns; + } + public HasIndexFluent IsUnique() + { + _isUnique = true; + _modelBuilder.Index(_indexName, string.Join(", ", _columns), _isUnique); + return this; + } + public HasIndexFluent HasName(string name) + { + _modelBuilder.IndexRemove(_indexName); + _indexName = name; + _modelBuilder.Index(_indexName, string.Join(", ", _columns), _isUnique); + return this; + } + } + #endregion + + #region HasOne + public HasOneFluent HasOne(Expression> one) + { + var exp = one?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); + + var oneProperty = ""; + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + oneProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(oneProperty)) throw new ArgumentException("参数错误 one"); + return new HasOneFluent(_fsql, _tf, oneProperty); + } + public class HasOneFluent + { + IFreeSql _fsql; + TableFluent _tf; + string _selfProperty; + string _selfBind; + string _withManyProperty; + string _withOneProperty; + string _withOneBind; + + internal HasOneFluent(IFreeSql fsql, TableFluent modelBuilder, string oneProperty) + { + _fsql = fsql; + _tf = modelBuilder; + _selfProperty = oneProperty; + } + public HasOneFluent WithMany(Expression> many) + { + var exp = many?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withManyProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(_withManyProperty)) throw new ArgumentException("参数错误 many"); + if (string.IsNullOrEmpty(_selfBind) == false) + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); + return this; + } + public HasOneFluent WithOne(Expression> one, Expression> foreignKey) + { + var exp = one?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withOneProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(_withOneProperty)) throw new ArgumentException("参数错误 one"); + + exp = foreignKey?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withOneBind = (exp as MemberExpression).Member.Name; + _withOneBind = _withOneBind.TrimStart(',', ' '); + break; + case ExpressionType.New: + _withOneBind = ""; + foreach (var member in (exp as NewExpression).Members) + _withOneBind += ", " + member.Name; + _withOneBind = _withOneBind.TrimStart(',', ' '); + break; + } + if (string.IsNullOrEmpty(_withOneBind)) throw new ArgumentException("参数错误 foreignKey"); + if (string.IsNullOrEmpty(_selfBind) == false) + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); + return this; + } + public HasOneFluent HasForeignKey(Expression> foreignKey) + { + var exp = foreignKey?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _selfBind = (exp as MemberExpression).Member.Name; + _selfBind = _selfBind.TrimStart(',', ' '); + break; + case ExpressionType.New: + _selfBind = ""; + foreach (var member in (exp as NewExpression).Members) + _selfBind += ", " + member.Name; + _selfBind = _selfBind.TrimStart(',', ' '); + break; + } + if (string.IsNullOrEmpty(_selfBind)) throw new ArgumentException("参数错误 foreignKey"); + _tf.Navigate(_selfProperty, _selfBind); + if (string.IsNullOrEmpty(_withManyProperty) == false) + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, _selfBind)); + if (string.IsNullOrEmpty(_withOneProperty) == false && string.IsNullOrEmpty(_withOneBind) == false) + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _withOneBind)); + return this; + } + } + #endregion + + #region HasMany + public HasManyFluent HasMany(Expression>> many) + { + var exp = many?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); + + var manyProperty = ""; + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + manyProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(manyProperty)) throw new ArgumentException("参数错误 many"); + return new HasManyFluent(_fsql, _tf, manyProperty); + } + public class HasManyFluent + { + IFreeSql _fsql; + TableFluent _tf; + string _selfProperty; + string _selfBind; + string _withOneProperty; + string _withManyProperty; + + internal HasManyFluent(IFreeSql fsql, TableFluent modelBuilder, string manyProperty) + { + _fsql = fsql; + _tf = modelBuilder; + _selfProperty = manyProperty; + } + + public void WithMany(Expression>> many, Type middleType) + { + var exp = many?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 many 不能为 null"); + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withManyProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(_withManyProperty)) throw new ArgumentException("参数错误 many"); + + _tf.Navigate(_selfProperty, null, middleType); + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withManyProperty, null, middleType)); + } + public HasManyFluent WithOne(Expression> one) + { + var exp = one?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 one 不能为 null"); + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _withOneProperty = (exp as MemberExpression).Member.Name; + break; + } + if (string.IsNullOrEmpty(_withOneProperty)) throw new ArgumentException("参数错误 one"); + + if (string.IsNullOrEmpty(_selfBind) == false) + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); + return this; + } + public HasManyFluent HasForeignKey(Expression> foreignKey) + { + var exp = foreignKey?.Body; + if (exp?.NodeType == ExpressionType.Convert) exp = (exp as UnaryExpression)?.Operand; + if (exp == null) throw new ArgumentException("参数错误 foreignKey 不能为 null"); + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + _selfBind = (exp as MemberExpression).Member.Name; + _selfBind = _selfBind.TrimStart(',', ' '); + break; + case ExpressionType.New: + _selfBind = ""; + foreach (var member in (exp as NewExpression).Members) + _selfBind += ", " + member.Name; + _selfBind = _selfBind.TrimStart(',', ' '); + break; + } + if (string.IsNullOrEmpty(_selfBind)) throw new ArgumentException("参数错误 foreignKey"); + _tf.Navigate(_selfProperty, _selfBind); + if (string.IsNullOrEmpty(_withOneProperty) == false) + _fsql.CodeFirst.ConfigEntity(eb2 => eb2.Navigate(_withOneProperty, _selfBind)); + return this; + } + } + #endregion + + public EfCoreTableFluent Ignore(Expression> property) + { + _tf.Property(property).IsIgnore(true); + return this; + } + public EfCoreTableFluent HasData(T data) => HasData(new[] { data }); + + /// + /// 使用 Repository + EnableAddOrUpdateNavigateList + NoneParameter 方式插入种子数据 + /// + /// + /// + public EfCoreTableFluent HasData(IEnumerable data) + { + if (data.Any() == false) return this; + var sdCopy = data.Select(a => (object)a).ToList(); + var sdCopyLock = new object(); + _fsql.Aop.SyncStructureAfter += new EventHandler((s, e) => + { + object[] sd = null; + lock (sdCopyLock) + sd = sdCopy?.ToArray(); + if (sd == null || sd.Any() == false) return; + foreach (var et in e.EntityTypes) + { + if (et != typeof(T)) continue; + if (_fsql.Select().AsType(et).Any()) continue; + + var repo = _fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.AsType(et); + repo.Insert(sd); + + lock (sdCopyLock) + sdCopy = null; + } + }); + return this; + } + } +} diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 8fd2938a..38667865 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -175,6 +175,19 @@ + + + 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 + + + + + + 使用 Repository + EnableAddOrUpdateNavigateList + NoneParameter 方式插入种子数据 + + + + 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 @@ -330,13 +343,22 @@ - EFCore 99% 相似的 FluentApi 扩展方法 + EFCore 95% 相似的 FluentApi 扩展方法 + + + EFCore 95% 相似的 FluentApi 扩展方法 + + + 实体类型 + + + 创建普通数据上下文档对象 @@ -395,14 +417,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 46c1f760..5a9c25e7 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -80,6 +80,11 @@ namespace FreeSql.DataAnnotations _table._indexs.AddOrUpdate(name, idx, (_, __) => idx); return this; } + public TableFluent IndexRemove(string name) + { + _table._indexs.TryRemove(name, out var oldidx); + return this; + } } public class TableFluent diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9780f9de..cb7ec67f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2305,6 +2305,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 }) + + + + + + 可自定义解析表达式 @@ -2825,6 +2956,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2895,6 +3032,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 From c45d8d3c0b2d32d6598cf31f784ae556750af219 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 20 Apr 2020 21:16:23 +0800 Subject: [PATCH 0587/1029] v1.4.0-preview0421 #281 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 18 insertions(+), 25 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1949f368..2e15dbda 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 09e4604c..a3bb187d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 21cc649e..d16e8f26 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 580d176c..c2d858c7 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 025acc6c..f09425ed 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0420 + 1.4.0-preview0421 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index af5afb66..791ada35 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b3d819f7..daa0c815 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 38667865..67ccde2b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,13 +120,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index f5244d54..c9367361 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9ff421f7..c136f69c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 60362d27..949070e3 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 4776a3a5..31b78cc5 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b88cacd1..18351c31 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ef03faa4..fde70db8 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 755c34ef..08629899 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ac8c9d25..8fd16846 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index bdec4ff7..e185785d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 86a51985..d85158b6 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9942a29d..986b6ece 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0420 + 1.4.0-preview0421 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From d29a6f596bb7f4e94d700c014e73a73370af8f7b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Apr 2020 14:38:14 +0800 Subject: [PATCH 0588/1029] update Ado Tests --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ .../MySqlConnectorAdo/MySqlAdoTest.cs | 14 +++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 67ccde2b..f619f03f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,6 +120,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -410,5 +417,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs index f1d59702..9fc81f4a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs @@ -31,8 +31,20 @@ namespace FreeSql.Tests.MySqlConnector [Fact] public void ExecuteNonQuery() { - + var item = new TestExecute01 { title = "title01" }; + g.mysql.Insert(item).ExecuteAffrows(); + var affrows = g.mysql.Ado.ExecuteNonQuery("update TestExecute01 set title = '' where id=@id", new { id = item.id }); + Assert.Equal(1, affrows); + var item2 = g.mysql.Select(item).First(); + Assert.NotNull(item2); + Assert.Equal("", item2.title); } + class TestExecute01 + { + public Guid id { get; set; } + public string title { get; set; } + } + [Fact] public void ExecuteScalar() { From c09173e8a38f28c3a5dbd977339e418eb7db0e44 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Apr 2020 16:29:16 +0800 Subject: [PATCH 0589/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20DbFirst=20Db?= =?UTF-8?q?ColumnInfo=20Position=20=E5=B1=9E=E6=80=A7=EF=BC=8C=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E9=BB=98=E8=AE=A4=E4=BD=8D=E7=BD=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/DatabaseModel/DBColumnInfo.cs | 4 + FreeSql/FreeSql.xml | 296 ++++++++++-------- .../FreeSql.Provider.Dameng/DamengDbFirst.cs | 4 +- .../FreeSql.Provider.MySql/MySqlDbFirst.cs | 4 +- .../Dameng/OdbcDamengDbFirst.cs | 4 +- .../MySql/OdbcMySqlDbFirst.cs | 4 +- .../Oracle/OdbcOracleDbFirst.cs | 4 +- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 4 +- .../SqlServer/OdbcSqlServerDbFirst.cs | 4 +- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 4 +- .../PostgreSQLDbFirst.cs | 4 +- .../SqlServerDbFirst.cs | 4 +- .../FreeSql.Provider.Sqlite/SqliteDbFirst.cs | 8 +- readme.md | 2 +- 14 files changed, 205 insertions(+), 145 deletions(-) diff --git a/FreeSql/DatabaseModel/DBColumnInfo.cs b/FreeSql/DatabaseModel/DBColumnInfo.cs index f20ee737..1c5b9949 100644 --- a/FreeSql/DatabaseModel/DBColumnInfo.cs +++ b/FreeSql/DatabaseModel/DBColumnInfo.cs @@ -52,5 +52,9 @@ namespace FreeSql.DatabaseModel /// 数据库默认值 /// public string DefaultValue { get; set; } + /// + /// 字段位置 + /// + public int Position { get; set; } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index cb7ec67f..09a5a1d6 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -445,6 +445,11 @@ 数据库默认值 + + + 字段位置 + + 枚举类型标识 @@ -2305,137 +2310,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2956,6 +2830,166 @@ 超时 + + + 使用完毕后,归还资源 + + 对象 + 是否重新创建 + + + + 名称 + + + + + 池容量 + + + + + 默认获取超时设置 + + + + + 空闲时间,获取时若超出,则重新创建 + + + + + 异步获取排队队列大小,小于等于0不生效 + + + + + 获取超时后,是否抛出异常 + + + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 + + + ry> + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 中间表,多对多 + + + + + 是否可用 + + + + + 不可用错误 + + + + + 不可用时间 + + + + + 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + + + 由【可用】变成【不可用】时返回true,否则返回false + + + + 统计对象池中的对象 + + + + + 统计对象池中的对象(完整) + + + + + 获取资源 + + 超时 + + 获取资源 diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index 2b11cd9e..fc926d72 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -330,6 +330,7 @@ where a.owner in ({1}) and {0} ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); } + var position = 0; foreach (var row in ds2) { string table_id = string.Concat(row[0]); @@ -359,7 +360,8 @@ where a.owner in ({1}) and {0} DbTypeTextFull = sqlType, Table = loc2[table_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 3669cf14..48a7b416 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -246,6 +246,7 @@ where a.table_schema in ({1}) and {0} ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; + var position = 0; foreach (var row in ds) { string table_id = string.Concat(row[0]); @@ -275,7 +276,8 @@ where a.table_schema in ({1}) and {0} DbTypeTextFull = sqlType, Table = loc2[table_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index d6eccbdc..eb2e1ddc 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -330,6 +330,7 @@ where a.owner in ({1}) and {0} ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); } + var position = 0; foreach (var row in ds2) { string table_id = string.Concat(row[0]); @@ -359,7 +360,8 @@ where a.owner in ({1}) and {0} DbTypeTextFull = sqlType, Table = loc2[table_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index 37e29ab5..66734859 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -216,6 +216,7 @@ where a.table_schema in ({1}) and {0} ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; + var position = 0; foreach (var row in ds) { string table_id = string.Concat(row[0]); @@ -245,7 +246,8 @@ where a.table_schema in ({1}) and {0} DbTypeTextFull = sqlType, Table = loc2[table_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index 35d1dd29..23c409a4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -303,6 +303,7 @@ where a.owner in ({1}) and {0} ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); } + var position = 0; foreach (var row in ds2) { string table_id = string.Concat(row[0]); @@ -332,7 +333,8 @@ where a.owner in ({1}) and {0} DbTypeTextFull = sqlType, Table = loc2[table_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index e7115a26..613e8c4b 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -228,6 +228,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; + var position = 0; foreach (object[] row in ds) { var object_id = string.Concat(row[0]); @@ -275,7 +276,8 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeTextFull = sqlType, Table = loc2[object_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index 58ed15d7..7c5eb871 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -268,6 +268,7 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), " ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; + var position = 0; foreach (object[] row in ds) { var table_id = string.Concat(row[0]); @@ -293,7 +294,8 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), " DbTypeTextFull = sqlType, Table = loc2[object_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index d84307ed..fb01732d 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -303,6 +303,7 @@ where a.owner in ({1}) and {0} ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); } + var position = 0; foreach (var row in ds2) { string table_id = string.Concat(row[0]); @@ -332,7 +333,8 @@ where a.owner in ({1}) and {0} DbTypeTextFull = sqlType, Table = loc2[table_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 65a9d2f0..bba4d80a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -338,6 +338,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; + var position = 0; foreach (object[] row in ds) { var object_id = string.Concat(row[0]); @@ -385,7 +386,8 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") DbTypeTextFull = sqlType, Table = loc2[object_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index 96cbe84a..ff0dd7e4 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -271,6 +271,7 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), " ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; + var position = 0; foreach (object[] row in ds) { var table_id = string.Concat(row[0]); @@ -296,7 +297,8 @@ from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), " DbTypeTextFull = sqlType, Table = loc2[object_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = ++position }); loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs index 7c2bae80..38b64903 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs @@ -159,7 +159,7 @@ namespace FreeSql.Sqlite if (database == null || database.Any() == false) database = GetDatabases().ToArray(); if (database.Any() == false) return loc1; - Action addColumn = row => + Action addColumn = (row, position) => { string table_id = string.Concat(row[0]); string column = string.Concat(row[1]); @@ -185,7 +185,8 @@ namespace FreeSql.Sqlite DbTypeTextFull = sqlType, Table = loc2[table_id], Coment = comment, - DefaultValue = defaultValue + DefaultValue = defaultValue, + Position = position }); loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); @@ -247,6 +248,7 @@ from {db}.sqlite_master where type = 'table'"; { var dsql = string.Concat(row[5]); var cols = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA \"{db}\".table_info(\"{table}\")"); + var position = 0; foreach (var col in cols) { var col_name = string.Concat(col[1]); @@ -268,7 +270,7 @@ from {db}.sqlite_master where type = 'table'"; ds2item[7] = string.Concat(col[5]) == "1" ? 1 : 0; ds2item[8] = ""; ds2item[9] = string.Concat(col[4]); - addColumn(ds2item); + addColumn(ds2item, ++position); } var fks = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA \"{db}\".foreign_key_list(\"{table}\")"); diff --git a/readme.md b/readme.md index cc4e5957..5abda4e9 100644 --- a/readme.md +++ b/readme.md @@ -204,7 +204,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元 > Thank you for your donation From 50eba05c15dc9faccd1201eeaa8667d17614fbeb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Apr 2020 16:55:32 +0800 Subject: [PATCH 0590/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20WhereDynamic?= =?UTF-8?q?=20=E4=BC=A0=E5=85=A5=20string=20=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=BD=AC=E4=B8=BA=E4=B8=BB=E9=94=AE=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=80=BC=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/FreeSql.xml | 291 +++++++++++------------- FreeSql/Internal/CommonUtils.cs | 4 + 3 files changed, 135 insertions(+), 176 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index f619f03f..67ccde2b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,13 +120,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -417,14 +410,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 09a5a1d6..d6b6f1a8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2310,6 +2310,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 }) + + + + + + 可自定义解析表达式 @@ -2830,166 +2961,6 @@ 超时 - - - 使用完毕后,归还资源 - - 对象 - 是否重新创建 - - - - 名称 - - - - - 池容量 - - - - - 默认获取超时设置 - - - - - 空闲时间,获取时若超出,则重新创建 - - - - - 异步获取排队队列大小,小于等于0不生效 - - - - - 获取超时后,是否抛出异常 - - - - - 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 - - - ry> - 获取c#值 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 中间表,多对多 - - - - - 是否可用 - - - - - 不可用错误 - - - - - 不可用时间 - - - - - 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 - - - 由【可用】变成【不可用】时返回true,否则返回false - - - - 统计对象池中的对象 - - - - - 统计对象池中的对象(完整) - - - - - 获取资源 - - 超时 - - 获取资源 diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 9ffab8cb..9e8a337c 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -276,6 +276,10 @@ namespace FreeSql.Internal } return sb.ToString(); } + else if (primarys.Length == 1 && type == typeof(string)) + { + return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}"; + } else if (dywhere is IEnumerable) { var sb = new StringBuilder(); From 658540774e4a830b0100af124ca9508f183a99c1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Apr 2020 17:16:02 +0800 Subject: [PATCH 0591/1029] v1.4.0-preview0422 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2e15dbda..64516ba6 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a3bb187d..e84b6cdb 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index d16e8f26..650d4e7c 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index c2d858c7..0a0d03a9 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index f09425ed..af815c73 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0421 + 1.4.0-preview0422 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 791ada35..7808caa9 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index daa0c815..621c20c7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 67ccde2b..f619f03f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,6 +120,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -410,5 +417,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c9367361..bd553e03 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c136f69c..c1f93c51 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 949070e3..e4869034 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 31b78cc5..4d9aaf05 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 18351c31..6f335e1d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fde70db8..a2d71121 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 08629899..3fc66c8e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8fd16846..bda2ea7b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e185785d..dfd83192 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d85158b6..21f39a9e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 986b6ece..a744b650 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0421 + 1.4.0-preview0422 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From fc4e8344529fc9e3ddbe3f96f4525b37c20095cf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 22 Apr 2020 03:54:26 +0800 Subject: [PATCH 0592/1029] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20UnitOfWorkManage?= =?UTF-8?q?r=20=E7=B1=BB=E7=AE=A1=E7=90=86=E5=B7=A5=E4=BD=9C=E5=8D=95?= =?UTF-8?q?=E5=85=83=EF=BC=8C=E7=A7=BB=E9=99=A4=20FreeSql.UnitOfWork.Curre?= =?UTF-8?q?nt=20=E9=9D=99=E6=80=81=E5=B1=9E=E6=80=A7=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseEntity 纯净版源码(.Net 4.0).zip | Bin 2698 -> 0 bytes .../BaseEntity 纯净版源码.zip | Bin 4439 -> 0 bytes .../BaseEntity.cs | 16 +- .../BaseEntityAsync.cs | 16 +- .../BaseEntityReadOnly.cs | 12 +- .../BaseEntityTree.cs | 4 +- FreeSql.DbContext/FreeSql.DbContext.xml | 42 +++- .../ContextSet/RepositoryUnitOfWorkManager.cs | 201 ++++++++++++++++++ FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 5 +- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 14 +- 10 files changed, 276 insertions(+), 34 deletions(-) delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip create mode 100644 FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWorkManager.cs diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip deleted file mode 100644 index 6a90cb183bbb7a74c0e98cbb524ad08de5b0618b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2698 zcmZ`*XIK+x5)LIaDWOPPAe2x-2Uj{$mu_G|30+!{5?CNqDI!HgYLF@*Eg(%+dhcCI zC;=fXf&xJ)p|f;P_qo0E?w*^OXWr-ge$33DdFM4TBqL`5002|~m&#;gLx}U;2{Hgc zh7JJu7645L6yg^zKR3T%Nhegp{gLV!X_h7UrkX{SDRqhCs0lfX36NAf-h!7^$ft+j zKXQkKU!9cPk*8looiy6M&*X`^QSwKpAnN3sUEK|NrEb%dz~^jnVLKta`^WqH$t_Za z1xP7;H?g*5m!TWL&g9xGWvd+itw%VcB+*kFPi z`Gx)U|6<_Jzxp1A9c)r05H@&*GO>l`%;Q}-7vW(b z2I5$kT72h{A_oI;{BbMm^4GncbsI@kgrZkfRpo;_7q30a>f*FP>tsbnbE@Ez%s(C- zuCB&px3PPbe z1eGDy)$GzfrR5tTV|c=i3LFVdD^f3li~2lm6cqAwM}4QyRSGSZ5`o2~q*Cs_h$kbX z_3G&@Y1&`U8A)Ut8Gw4bhrC+G-QS+e_#_L97&q!ZdJF%<_+3*%#!n(Bi4OVA>z6?+ zm>cdm3I`udhZ(w!gM@$6V#VDHqD`Ayf?{OXD;60j# zJA+_j2o^j9m+FU0st*k#G*})ATi3yheCY7>*im!BRSoOTei%au5I^V!u5fX)28Zx* z6zf{T)xEcOASO*C8|Y~e#q%_!bYr;Tvyt>3oCb@vX;grue2`xpvq5d?;`+5liefr4 zJ6uP24GJ(sv6|62CCtmsjwfMNPQx#zz_#m9qHBfX*`Y}eGOL4yUT+35P;cP(r@!yv zz~ccAubgA>yd!_|d@Z{wUc2!sMR{H8TAomLdCLjrd*&XxxnD0VWA}NRzbPx?J<6p) z@(m8LthY9tQF&dDxWyZfxX5{}irCH0DGln9TFhq(vUo2?#3uE8t*fv;)y-cRPlTK&L;?W-BohE|^FJ2f6ye}(?1lVJ0ON4|&&;2WYeArH!-GS#UI zgaM_%W1%gaDwhfu=Vp{^-tvTMe#r&xW%ZWJ{Ia&WX!}mVP#qJVo;3Cl7R0#J0#38J zAJ~_no{^}iyCoy+R9#S1U4}WCS^>$}vnPvdg{TscPDl1IG_AC(+>xI^P?-2f3Ktfm z$F3dWRi7z1(#r6!yUinp*&J0T@eO+SvID7F)hH1q#5?TW&oY|~TT z(s2}y9*NC)^po?74uhuaWySf3XJh=q8qLz9CAm=y#Vq>QY(4D~#8k^ZTDCdb*vCuOQQWuG5@@eSKXnFECFWgjaU~RTK^TJVD);oQ z#V~7iOzX5`%TYWM#XMh!q?vBZ7KB}np4p3o=M)}UCklw#$^B&0R`@xsV1ZtA|Lq@`} z3ePw`@zK5;bwr#DPtuv`tg25f8nsL+6Ljd0e#;Bvv2h)1|2m)BDSLPw?0vqroulij zO@+LVx|&XlL3h8pDz7dZ1lw{fls|{#r5YL??kI4$0l%n|46dWM78@DML8GvCd(@t~ zUc4eFC1V`3FSJ1A>DZc+fzs5F%`%_Shj2zeDU}p#xliP%yeUQ5<_9Cb)Yms6pB$xd zwvuSuP6|!6J~#~bhdiK&!LOlB(FqB@YkF1X_Bq0YqvXchwMV2axtdXeYp*{@f}(JS zr`;ZVyZ4KnW$}#&a%uTUwMKi&%@^H9dwKWn`Fr+CDgKP?XZ47fFGP$98z$vmY9^^9 z7u#h=!>Gq!KyCLWY{_Eh2+vd9Hn z$Zrc1b-G|(`t46JHuTZO>S0OVK_{-Jy{<;lP6t?zEGO9-_m~+s9E$paeS^Z@?<-^v zu`Cd%d^E;|l5Qx8YFHP8OIo+O&$f=}&m3@#4+q5toT#jM-xZsmho<{%`4k@?d+ePV z;E0z4mGEqId&?a1$hNXWHQHcu>n07AAN5b11D>KnEm=FNshghJd|D#28&~wZAJ1dG znpB#M5cy>{G2*!Pvw#zPAK@5<-u?O_B@yn&@e@m>a&)-xGr$X8z2{>L1=+^%DCWem z-wg=VAcF#q%!k3s<-xf$$^N(!XFBe5i3jvPrz4?7UCVcF+5};Eh$#|19Xf}^96}TZDmK9R9I>%-eEoT6w;SAqlA(;Q#40$T#BtZoGfx z|59%>|NJHaumhN>h*pMmvm}2b0ESTJc{NM&WBLER3O|-V`z8|qEe?OU5kIz}>J|pD eHO`X!jQ}=SE%#q-fE3?HB>m=t->{nc`|BSz!Swb3 diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip deleted file mode 100644 index 47a9b4d13018fbf8f0544cd4d91eb495eb312a33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4439 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 diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index 829e33c5..a3064ad9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -70,12 +70,12 @@ namespace FreeSql { if (this.Repository == null) return Orm.Update(this as TEntity) - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction()) .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; this.SetTenantId(); this.IsDeleted = value; - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return this.Repository.Update(this as TEntity) == 1; } /// @@ -89,7 +89,7 @@ namespace FreeSql if (this.Repository == null) return Orm.Delete(this as TEntity).ExecuteAffrows() == 1; //this.SetTenantId(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return this.Repository.Delete(this as TEntity) == 1; } /// @@ -107,11 +107,11 @@ namespace FreeSql this.UpdateTime = DateTime.Now; if (this.Repository == null) return Orm.Update() - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction()) .SetSource(this as TEntity).ExecuteAffrows() == 1; this.SetTenantId(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return this.Repository.Update(this as TEntity) == 1; } /// @@ -124,7 +124,7 @@ namespace FreeSql this.Repository = Orm.GetRepository(); this.SetTenantId(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return this.Repository.Insert(this as TEntity); } @@ -139,7 +139,7 @@ namespace FreeSql this.Repository = Orm.GetRepository(); this.SetTenantId(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return this.Repository.InsertOrUpdate(this as TEntity); } @@ -152,7 +152,7 @@ namespace FreeSql if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; this.Repository.SaveMany(this as TEntity, navigatePropertyName); } } diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index fb43fcb9..8b0e5ed2 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -53,11 +53,11 @@ namespace FreeSql { if (this.Repository == null) return await Orm.Update(this as TEntity) - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction()) .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; this.IsDeleted = value; - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return await this.Repository.UpdateAsync(this as TEntity) == 1; } /// @@ -71,7 +71,7 @@ namespace FreeSql if (this.Repository == null) return await Orm.Delete(this as TEntity).ExecuteAffrowsAsync() == 1; //this.SetTenantId(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return await this.Repository.DeleteAsync(this as TEntity) == 1; } /// @@ -89,11 +89,11 @@ namespace FreeSql this.UpdateTime = DateTime.Now; if (this.Repository == null) return await Orm.Update() - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction()) + .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction()) .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; this.SetTenantId(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return await this.Repository.UpdateAsync(this as TEntity) == 1; } /// @@ -106,7 +106,7 @@ namespace FreeSql this.Repository = Orm.GetRepository(); this.SetTenantId(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return this.Repository.InsertAsync(this as TEntity); } @@ -121,7 +121,7 @@ namespace FreeSql this.Repository = Orm.GetRepository(); this.SetTenantId(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return this.Repository.InsertOrUpdateAsync(this as TEntity); } @@ -134,7 +134,7 @@ namespace FreeSql if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = UnitOfWork.Current.Value; + this.Repository.UnitOfWork = CurrentUnitOfWork; return this.Repository.SaveManyAsync(this as TEntity, navigatePropertyName); } } diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 68174990..d4efcbff 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -106,9 +106,11 @@ namespace FreeSql { var uow = Orm.CreateUnitOfWork(); uow.IsolationLevel = level; + CurrentUnitOfWork = uow; return uow; } + static readonly AsyncLocal _AsyncUnitOfWork = new AsyncLocal(); static readonly AsyncLocal _AsyncTenantId = new AsyncLocal(); /// /// 获取或设置当前租户id @@ -118,6 +120,14 @@ namespace FreeSql get => _AsyncTenantId.Value; set => _AsyncTenantId.Value = value; } + /// + /// 获取或设置当前租户id + /// + public static IUnitOfWork CurrentUnitOfWork + { + get => _AsyncUnitOfWork.Value; + set => _AsyncUnitOfWork.Value = value; + } } /// @@ -143,7 +153,7 @@ namespace FreeSql { var select = Orm.Select() .TrackToList(TrackToList) //自动为每个元素 Attach - .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)); + .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction(false)); if (string.IsNullOrEmpty(CurrentTenantId) == false) select.WhereCascade(a => (a as ITenant).TenantId == CurrentTenantId); return select.WhereCascade(a => (a as BaseEntity).IsDeleted == false); diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs index 28be88c8..a2b5231c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs @@ -79,7 +79,7 @@ namespace FreeSql buf.Add(this as TEntity); buf.AddRange(this.GetAllChilds()); var repo = Orm.GetRepository(); - repo.UnitOfWork = UnitOfWork.Current.Value; + repo.UnitOfWork = CurrentUnitOfWork; buf = repo.Select.WhereDynamic(buf) .Include(a => ((((((((((a as BaseEntityTree).Parent as BaseEntityTree).Parent @@ -110,7 +110,7 @@ namespace FreeSql var childs = GetAllChilds(); childs.Add(this as TEntity); var repo = Orm.GetRepository(); - repo.UnitOfWork = UnitOfWork.Current.Value; + repo.UnitOfWork = CurrentUnitOfWork; repo.Attach(childs); foreach (var item in childs) (item as BaseEntity).IsDeleted = false; diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index f619f03f..9f17feac 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -227,6 +227,41 @@ 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + + + 仓储的工作单元管理器 + + + + + 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。 + + + + + 支持当前事务,如果没有当前事务,就以非事务方法执行。 + + + + + 使用当前事务,如果没有当前事务,就抛出异常。 + + + + + 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 + + + + + 以非事务方式执行操作,如果当前事务存在则抛出异常。 + + + + + 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,就新建一个事务。 + + 开启过滤器,若使用 using 则使用完后,恢复为原有状态 @@ -299,6 +334,11 @@ 实体对象 属性名 + + + 工作单元 + + 开启事务,或者返回已开启的事务 @@ -326,7 +366,7 @@ - 此工作单元内的实体变化跟踪 + 工作单元内的实体变化跟踪 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWorkManager.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWorkManager.cs new file mode 100644 index 00000000..a3524b59 --- /dev/null +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWorkManager.cs @@ -0,0 +1,201 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; + +namespace FreeSql +{ + /// + /// 仓储的工作单元管理器 + /// + public class RepositoryUnitOfWorkManager : IDisposable + { + IFreeSql _fsql; + List _uows = new List(); + bool _isNotSupported = false; + + public RepositoryUnitOfWorkManager(IFreeSql fsql) + { + _fsql = fsql ?? throw new ArgumentNullException($"{nameof(RepositoryUnitOfWorkManager)} 构造参数 {nameof(fsql)} 不能为 null"); + } + + ~RepositoryUnitOfWorkManager() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + try + { + Exception exception = null; + for (var a = _uows.Count - 1; a >= 0; a--) + { + try + { + if (exception == null) _uows[a].Commit(); + else _uows[a].Rollback(); + } + catch (Exception ex) + { + if (exception == null) exception = ex; + } + } + if (exception != null) throw exception; + } + finally + { + _uows.Clear(); + GC.SuppressFinalize(this); + } + } + + public enum Propagation + { + /// + /// 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。 + /// + Requierd, + /// + /// 支持当前事务,如果没有当前事务,就以非事务方法执行。 + /// + Supports, + /// + /// 使用当前事务,如果没有当前事务,就抛出异常。 + /// + Mandatory, + /// + /// 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 + /// + NotSupported, + /// + /// 以非事务方式执行操作,如果当前事务存在则抛出异常。 + /// + Never, + /// + /// 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,就新建一个事务。 + /// + Nested + } + + public IRepositoryUnitOfWork Begin(Propagation propagation, IsolationLevel? isolationLevel = null) + { + if (propagation == Propagation.Requierd) + { + if (_isNotSupported == false) + { + for (var a = _uows.Count - 1; a >= 0; a--) + if (_uows[a].GetOrBeginTransaction(false) != null) + return new UnitOfWorkProxy(_uows[a]); + } + var uow = new RepositoryUnitOfWork(_fsql); + if (isolationLevel != null) uow.IsolationLevel = isolationLevel.Value; + try { uow.GetOrBeginTransaction(); } + catch { uow.Dispose(); throw; } + _uows.Add(uow); + return uow; + } + if (propagation == Propagation.Supports) + { + if (_isNotSupported == false) + { + for (var a = _uows.Count - 1; a >= 0; a--) + if (_uows[a].GetOrBeginTransaction(false) != null) + return new UnitOfWorkProxy(_uows[a]); + } + return new UnitOfWorkNothing(_fsql); + } + if (propagation == Propagation.Mandatory) + { + if (_isNotSupported == false) + { + for (var a = _uows.Count - 1; a >= 0; a--) + if (_uows[a].GetOrBeginTransaction(false) != null) + return new UnitOfWorkProxy(_uows[a]); + throw new Exception("Propagation_Mandatory: 使用当前事务,如果没有当前事务,就抛出异常"); + } + throw new Exception("Propagation_Mandatory: 使用当前事务,如果没有当前事务,就抛出异常(NotSupported 事务挂起中)"); + } + if (propagation == Propagation.NotSupported) + { + if (_isNotSupported == false) + { + _isNotSupported = true; + return new UnitOfWorkNothing(_fsql) { OnDispose = () => _isNotSupported = false }; + } + return new UnitOfWorkNothing(_fsql); + } + if (propagation == Propagation.Never) + { + if (_isNotSupported == false) + { + for (var a = _uows.Count - 1; a >= 0; a--) + if (_uows[a].GetOrBeginTransaction(false) != null) + throw new Exception("Propagation_Never: 以非事务方式执行操作,如果当前事务存在则抛出异常"); + } + return new UnitOfWorkNothing(_fsql); + } + if (propagation == Propagation.Nested) + { + var uow = new RepositoryUnitOfWork(_fsql); + if (isolationLevel != null) uow.IsolationLevel = isolationLevel.Value; + try { uow.GetOrBeginTransaction(); } + catch { uow.Dispose(); throw; } + _uows.Add(uow); + return uow; + } + throw new NotImplementedException(); + } + + class UnitOfWorkProxy : IRepositoryUnitOfWork + { + IRepositoryUnitOfWork _baseUow; + public UnitOfWorkProxy(IRepositoryUnitOfWork baseUow) => _baseUow = baseUow; + public IsolationLevel? IsolationLevel { get => _baseUow.IsolationLevel; set { } } + public DbContext.EntityChangeReport EntityChangeReport => _baseUow.EntityChangeReport; + + public bool Enable => _baseUow.Enable; + public void Close() => _baseUow.Close(); + public void Open() => _baseUow.Open(); + + public DbTransaction GetOrBeginTransaction(bool isCreate = true) => _baseUow.GetOrBeginTransaction(isCreate); + public void Commit() => this.Dispose(); + public void Rollback() => _baseUow.Rollback(); + public void Dispose() { } + + public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class => _baseUow.GetRepository(filter); + public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class => _baseUow.GetRepository(filter); + public IBaseRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class => _baseUow.GetGuidRepository(filter); + } + class UnitOfWorkNothing : IRepositoryUnitOfWork + { + internal IFreeSql _fsql; + internal Action OnDispose; + public UnitOfWorkNothing(IFreeSql fsql) => _fsql = fsql; + public IsolationLevel? IsolationLevel { get; set; } + public DbContext.EntityChangeReport EntityChangeReport { get; } = new DbContext.EntityChangeReport(); + + public bool Enable { get; } + public void Close() { } + public void Open() { } + + public DbTransaction GetOrBeginTransaction(bool isCreate = true) => null; + public void Commit() + { + if (EntityChangeReport != null && EntityChangeReport.OnChange != null && EntityChangeReport.Report.Any() == true) + EntityChangeReport.OnChange.Invoke(EntityChangeReport.Report); + this.Dispose(); + } + public void Rollback() => this.Dispose(); + public void Dispose() { + EntityChangeReport?.Report.Clear(); + OnDispose?.Invoke(); + } + + public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class => new DefaultRepository(_fsql, filter); + public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class => new DefaultRepository(_fsql, filter); + public IBaseRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class => new GuidRepository(_fsql, filter, asTable); + } + } +} diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index e6ffb167..dfc5e034 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -5,6 +5,9 @@ using System.Data.Common; namespace FreeSql { + /// + /// 工作单元 + /// public interface IUnitOfWork : IDisposable { @@ -40,7 +43,7 @@ namespace FreeSql void Open(); /// - /// 此工作单元内的实体变化跟踪 + /// 工作单元内的实体变化跟踪 /// DbContext.EntityChangeReport EntityChangeReport { get; } } diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 4e0aa3de..941cdac8 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -11,10 +11,6 @@ namespace FreeSql { public class UnitOfWork : IUnitOfWork { -#if netcoreapp - public static readonly AsyncLocal Current = new AsyncLocal(); -#endif - static int _seed; /// /// 正在使用中的工作单元(调试) @@ -40,11 +36,7 @@ namespace FreeSql if (_fsql == null) throw new ArgumentNullException(nameof(fsql)); _uowBefore = new Aop.TraceBeforeEventArgs("UnitOfWork", null); - _fsql?.Aop.TraceBeforeHandler?.Invoke(this, _uowBefore); - -#if netcoreapp - Current.Value = this; -#endif + _fsql.Aop.TraceBeforeHandler?.Invoke(this, _uowBefore); } void ReturnObject() @@ -55,9 +47,6 @@ namespace FreeSql _fsql.Ado.MasterPool.Return(_conn); _tran = null; _conn = null; -#if netcoreapp - Current.Value = null; -#endif EntityChangeReport?.Report.Clear(); } @@ -174,7 +163,6 @@ namespace FreeSql try { this.Rollback(); - this.Close(); } finally { From 7311ae600cd960edd04c0150dd5a4fae96ac8041 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 22 Apr 2020 13:08:38 +0800 Subject: [PATCH 0593/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Guid=20->=20?= =?UTF-8?q?MapType(string)=20=E5=9C=A8=20FreeSql.DbContext=20=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../SqlServer/MapType/ToStringTest.cs | 14 ++++++++++++++ FreeSql/Extensions/EntityUtilExtensions.cs | 1 + 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9f17feac..2c69043d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,13 +120,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -457,14 +450,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs index ab17e685..67f00b66 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/MapType/ToStringTest.cs @@ -18,6 +18,7 @@ namespace FreeSql.Tests.SqlServerMapType class ToStringMap { + [Column(MapType = typeof(string))] public Guid id { get; set; } [Column(MapType = typeof(string))] @@ -49,6 +50,19 @@ namespace FreeSql.Tests.SqlServerMapType [Fact] public void Enum1() { + g.sqlserver.Aop.AuditValue += new EventHandler((s, e) => + { + if (e.Column.CsType == typeof(Guid) && + e.Column.Attribute.MapType == typeof(string) && + e.Value?.ToString() == Guid.Empty.ToString()) + e.Value = FreeUtil.NewMongodbId(); + }); + + g.sqlserver.GetRepository().InsertOrUpdate(new ToStringMap + { + + }); + //insert var orm = g.sqlserver; var item = new ToStringMap { }; diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 044fd446..4236a48d 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -55,6 +55,7 @@ namespace FreeSql.Extensions.EntityUtil { Expression newguid = Expression.Call(MethodFreeUtilNewMongodbId); if (pks[a].Attribute.MapType != pks[a].CsType) newguid = FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pks[a].CsType, newguid); + if (pks[a].CsType == typeof(Guid)) newguid = Expression.Convert(newguid, typeof(Guid)); if (pks[a].CsType == typeof(Guid?)) newguid = Expression.Convert(newguid, typeof(Guid?)); expthen = Expression.Block( new Expression[]{ From c78c4ed7ae399808ea8f6117f51901d5498e7dab Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 22 Apr 2020 14:37:30 +0800 Subject: [PATCH 0594/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=B1=BB=E5=9E=8B=E4=B8=BA=20char=20=E6=97=B6=20Expre?= =?UTF-8?q?ssionTree=20=E8=AF=BB=E5=8F=96=E5=A4=B1=E8=B4=A5=20bug=EF=BC=9B?= =?UTF-8?q?#283=20-=20=E4=BF=AE=E5=A4=8D=20=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20Include=20=E7=88=B6=E5=AD=90=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E5=8F=AF=E8=83=BD=E5=A4=B1=E8=B4=A5=E7=9A=84=20bug?= =?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 ++ .../BankOutlets.cs | 75 +++++++ .../Banks.cs | 66 ++++++ .../UnitTest1.cs | 5 + FreeSql.Tests/FreeSql.Tests/Issues/283.cs | 196 ++++++++++++++++++ .../SelectProvider/Select1Provider.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 45 ++-- 7 files changed, 382 insertions(+), 22 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/283.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2c69043d..9f17feac 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,6 +120,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -450,5 +457,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs new file mode 100644 index 00000000..25ab8b30 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs @@ -0,0 +1,75 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具 FreeSql.Generator 生成。 +// 运行时版本:3.1.0 +// Website: https://github.com/2881099/FreeSql +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; +namespace FreeSql.Jhfw.Models { + + public interface IBaseModel + { + TKey Id { get; set; } + } + [JsonObject(MemberSerialization.OptIn), Table(Name = "bank_outlets")] + public partial class BankOutlets : IBaseModel + { + + [JsonProperty] + public int? BankId { get => _BankId; set { + if (_BankId == value) return; + _BankId = value; + OneBanks = null; + }} + private int? _BankId; + + [JsonProperty] + public int? ParentId { get => _ParentId; set { + if (_ParentId == value) return; + _ParentId = value; + OneBankOutlets = null; + }} + private int? _ParentId; + + [JsonProperty] + public string Address { get; set; } = ""; + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Area { get; set; } = ""; + + [JsonProperty, Column(Name = "ID", IsIdentity = true)] + public int Id { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Name { get; set; } = ""; + + + #region 外键 => 导航属性,ManyToOne/OneToOne + + [Navigate("BankId")] + public virtual Banks OneBanks { get; set; } + + [Navigate("ParentId")] + public virtual BankOutlets OneBankOutlets { get; set; } + + #endregion + + #region 外键 => 导航属性,OneToMany + + [Navigate("ParentId")] + public virtual List ManyBankOutlets { get; set; } + + #endregion + + #region 外键 => 导航属性,ManyToMany + + #endregion + } + +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs new file mode 100644 index 00000000..17f26cdb --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs @@ -0,0 +1,66 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具 FreeSql.Generator 生成。 +// 运行时版本:3.1.0 +// Website: https://github.com/2881099/FreeSql +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; +namespace FreeSql.Jhfw.Models { + + [JsonObject(MemberSerialization.OptIn), Table(Name = "banks")] + public partial class Banks : IBaseModel + { + + [JsonProperty, Column(DbType = "datetime")] + public DateTime? Addtime { get; set; } + + [JsonProperty, Column(DbType = "varchar(250)")] + public string Banner { get; set; } = ""; + + [JsonProperty, Column(DbType = "varchar(20)")] + public string City { get; set; } = ""; + + [JsonProperty, Column(Name = "ID", IsIdentity = true)] + public int Id { get; set; } + + [JsonProperty, Column(DbType = "tinyint(1)")] + public bool IsDelete { get; set; } + + [JsonProperty, Column(DbType = "tinyint(1)")] + public bool IsGrab { get; set; } + + [JsonProperty, Column(DbType = "tinyint(1)")] + public bool IsJoinHmd { get; set; } + + [JsonProperty, Column(DbType = "varchar(100)")] + public string LoanType { get; set; } = ""; + + [JsonProperty, Column(DbType = "varchar(250)")] + public string Logo { get; set; } = ""; + + [JsonProperty] + public string Name { get; set; } = ""; + + [JsonProperty, Column(DbType = "varchar(3000)")] + public string Notice { get; set; } = ""; + + + #region 外键 => 导航属性,OneToMany + + [Navigate("BankId")] + public virtual List ManyBankOutlets { get; set; } + + #endregion + + #region 外键 => 导航属性,ManyToMany + + #endregion + } + +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs index d3300f9b..fa20bfdd 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs @@ -32,6 +32,11 @@ namespace FreeSql.Tests.MySqlConnector public void Test1() { g.mysql.Select().ToList(); + + + var soc = g.mysql.GetRepository(); + var item1 = soc.Where(d => d.Id == 1).Include(x => x.OneBankOutlets).Include(d => d.OneBanks).First(); + var item2 = soc.Where(d => d.Id == 1).Include(d => d.OneBanks).Include(x => x.OneBankOutlets).First(); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/283.cs b/FreeSql.Tests/FreeSql.Tests/Issues/283.cs new file mode 100644 index 00000000..1fd3ecf1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/283.cs @@ -0,0 +1,196 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _283 + { + [Fact] + public void SelectTest() + { + IFreeSql db = g.sqlserver; + + db.Transaction(() => + { + db.Delete().Where("1=1").ExecuteAffrows(); + db.Delete().Where("1=1").ExecuteAffrows(); + + var dictionaries = new BuildDictionary[] + { + new BuildDictionary { Type = 1, Code = 'A', Name = "办公建筑" }, + new BuildDictionary { Type = 1, Code = 'B', Name = "商场建筑" }, + new BuildDictionary { Type = 1, Code = 'C', Name = "宾馆饭店建筑" }, + new BuildDictionary { Type = 1, Code = 'D', Name = "文化教育建筑" }, + new BuildDictionary { Type = 1, Code = 'E', Name = "医疗卫生建筑" }, + new BuildDictionary { Type = 1, Code = 'F', Name = "体育建筑" }, + new BuildDictionary { Type = 1, Code = 'G', Name = "综合建筑" }, + new BuildDictionary { Type = 1, Code = 'Z', Name = "其他建筑" }, + + new BuildDictionary { Type = 2, Code = 'A', Name = "结构建筑" }, + new BuildDictionary { Type = 2, Code = 'B', Name = "框剪结构" }, + new BuildDictionary { Type = 2, Code = 'C', Name = "剪力墙结构" }, + new BuildDictionary { Type = 2, Code = 'D', Name = "砖混结构" }, + new BuildDictionary { Type = 2, Code = 'E', Name = "钢结构" }, + new BuildDictionary { Type = 2, Code = 'F', Name = "筒体结构" }, + new BuildDictionary { Type = 2, Code = 'G', Name = "木结构" }, + new BuildDictionary { Type = 2, Code = 'Z', Name = "其他" }, + + new BuildDictionary { Type = 3, Code = 'A', Name = "集中式全空气系统" }, + new BuildDictionary { Type = 3, Code = 'B', Name = "风机盘管+新风系统" }, + new BuildDictionary { Type = 3, Code = 'C', Name = "分体式空调或 VRV 的局部式机组系统" }, + new BuildDictionary { Type = 3, Code = 'Z', Name = "其他" }, + + new BuildDictionary { Type = 4, Code = 'A', Name = "散热器采暖" }, + new BuildDictionary { Type = 4, Code = 'B', Name = "地板辐射采暖" }, + new BuildDictionary { Type = 4, Code = 'C', Name = "电辐射采暖" }, + new BuildDictionary { Type = 4, Code = 'D', Name = "空调系统集中供暖" }, + new BuildDictionary { Type = 4, Code = 'Z', Name = "其他" }, + + new BuildDictionary { Type = 5, Code = 'A', Name = "砖" }, + new BuildDictionary { Type = 5, Code = 'B', Name = "建筑砌块" }, + new BuildDictionary { Type = 5, Code = 'C', Name = "板材墙体" }, + new BuildDictionary { Type = 5, Code = 'D', Name = "复合墙板和墙体" }, + new BuildDictionary { Type = 5, Code = 'E', Name = "玻璃幕墙" }, + new BuildDictionary { Type = 5, Code = 'Z', Name = "其他" }, + + new BuildDictionary { Type = 6, Code = 'A', Name = "内保温" }, + new BuildDictionary { Type = 6, Code = 'B', Name = "外保温" }, + new BuildDictionary { Type = 6, Code = 'C', Name = "夹芯保温" }, + new BuildDictionary { Type = 6, Code = 'Z', Name = "其他" }, + + new BuildDictionary { Type = 7, Code = 'A', Name = "单玻单层窗" }, + new BuildDictionary { Type = 7, Code = 'B', Name = "单玻双层窗" }, + new BuildDictionary { Type = 7, Code = 'C', Name = "单玻单层窗+单玻双层窗" }, + new BuildDictionary { Type = 7, Code = 'D', Name = "中空双层玻璃窗" }, + new BuildDictionary { Type = 7, Code = 'E', Name = "中空三层玻璃窗" }, + new BuildDictionary { Type = 7, Code = 'F', Name = "中空充惰性气体" }, + new BuildDictionary { Type = 7, Code = 'Z', Name = "其他" }, + + new BuildDictionary { Type = 8, Code = 'A', Name = "普通玻璃" }, + new BuildDictionary { Type = 8, Code = 'B', Name = "镀膜玻璃" }, + new BuildDictionary { Type = 8, Code = 'C', Name = "Low-e 玻璃" }, + new BuildDictionary { Type = 8, Code = 'Z', Name = "其他" }, + + new BuildDictionary { Type = 9, Code = 'A', Name = "钢窗" }, + new BuildDictionary { Type = 9, Code = 'B', Name = "铝合金" }, + new BuildDictionary { Type = 9, Code = 'C', Name = "木窗" }, + new BuildDictionary { Type = 9, Code = 'D', Name = "断热窗框" }, + new BuildDictionary { Type = 9, Code = 'E', Name = "塑钢" }, + new BuildDictionary { Type = 9, Code = 'Z', Name = "其他" }, + }; + + db.Insert(dictionaries).ExecuteAffrows(); + + Build2 build = new Build2 + { + ID = 1, + Name = "建筑 1", + BuildFunctionCode = 'A', + BuildStructureCode = 'A', + AirTypeCode = 'A', + HeatTypeCode = 'A', + WallMaterialTypeCode = 'A', + WallWarmTypeCode = 'A', + WallWindowsTypeCode = 'A', + GlassTypeCode = 'A', + WinFrameMaterialCode = 'A' + }; + + db.Insert(build).ExecuteAffrows(); + }); + + Build2 build = db.Select() + .InnerJoin(a => a.BuildFunctionCode == a.BuildFunction.Code && a.BuildFunction.Type == 1) + .InnerJoin(a => a.BuildStructureCode == a.BuildStructure.Code && a.BuildStructure.Type == 2) + .InnerJoin(a => a.AirTypeCode == a.AirType.Code && a.AirType.Type == 3) + .InnerJoin(a => a.HeatTypeCode == a.HeatType.Code && a.HeatType.Type == 4) + .InnerJoin(a => a.WallMaterialTypeCode == a.WallMaterialType.Code && a.WallMaterialType.Type == 5) + .InnerJoin(a => a.WallWarmTypeCode == a.WallWarmType.Code && a.WallWarmType.Type == 6) + .InnerJoin(a => a.WallWindowsTypeCode == a.WallWindowsType.Code && a.WallWindowsType.Type == 7) + .InnerJoin(a => a.GlassTypeCode == a.GlassType.Code && a.GlassType.Type == 8) + .InnerJoin(a => a.WinFrameMaterialCode == a.WinFrameMaterial.Code && a.WinFrameMaterial.Type == 9) + .Where(a => a.ID == 1) + .ToOne(); + + Assert.NotNull(build); + } + + [Table(Name = "F_Build2")] + public class Build2 + { + public int ID { get; set; } + + public string Name { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char BuildFunctionCode { get; set; } + + [Navigate(nameof(BuildFunctionCode))] + public BuildDictionary BuildFunction { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char BuildStructureCode { get; set; } + + [Navigate(nameof(BuildStructureCode))] + public BuildDictionary BuildStructure { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char AirTypeCode { get; set; } + + [Navigate(nameof(AirTypeCode))] + public BuildDictionary AirType { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char HeatTypeCode { get; set; } + + [Navigate(nameof(HeatTypeCode))] + public BuildDictionary HeatType { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char WallMaterialTypeCode { get; set; } + + [Navigate(nameof(WallMaterialTypeCode))] + public BuildDictionary WallMaterialType { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char WallWarmTypeCode { get; set; } + + [Navigate(nameof(WallWarmTypeCode))] + public BuildDictionary WallWarmType { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char WallWindowsTypeCode { get; set; } + + [Navigate(nameof(WallWindowsTypeCode))] + public BuildDictionary WallWindowsType { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char GlassTypeCode { get; set; } + + [Navigate(nameof(GlassTypeCode))] + public BuildDictionary GlassType { get; set; } + + [Column(MapType = typeof(string), DbType = "char")] + public char WinFrameMaterialCode { get; set; } + + [Navigate(nameof(WinFrameMaterialCode))] + public BuildDictionary WinFrameMaterial { get; set; } + } + + [Table(Name = "F_BuildDictionary")] + public class BuildDictionary + { + [Column(IsPrimary = true)] + public int Type { get; set; } + + [Column(IsPrimary = true, MapType = typeof(string), DbType = "char")] + public char Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + } + } +} diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 48714a49..3870966f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -287,6 +287,7 @@ namespace FreeSql.Internal.CommonProvider if (tb == null) throw new Exception("Include 参数类型错误"); _isIncluded = true; + _tables[0].Parameter = navigateSelector.Parameters[0]; _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null, null); return this; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 98f4a128..5ea91584 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1236,6 +1236,7 @@ namespace FreeSql.Internal public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex"); } internal static MethodInfo MethodDataReaderGetValue = typeof(Utils).GetMethod("InternalDataReaderGetValue", BindingFlags.Static | BindingFlags.NonPublic); + internal static PropertyInfo PropertyDataReaderFieldCount = typeof(DbDataReader).GetProperty("FieldCount"); internal static object InternalDataReaderGetValue(CommonUtils commonUtil, DbDataReader dr, int index) { if (commonUtil._orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null; @@ -1309,33 +1310,33 @@ namespace FreeSql.Internal } } block2Exp.AddRange(new Expression[] { - //Expression.TryCatch(Expression.Block( - // typeof(void), - Expression.Assign(read2Exp, read2ExpAssign), - Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, read2ExpDataIndex)), - Expression.IfThenElse(Expression.Equal(read2ExpValue, Expression.Constant(null)), - Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Default(field.FieldType)), - Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType))) - //), - //Expression.Catch(typeof(Exception), Expression.Block( - // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(0)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 0)))), - // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(1)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 1)))), - // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(2)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 2)))), - // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(3)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 3)))), - // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(4)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 4)))) - // ) - //)) - }); + //Expression.TryCatch(Expression.Block( + // typeof(void), + Expression.Assign(read2Exp, read2ExpAssign), + Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, read2ExpDataIndex)), + Expression.IfThenElse(Expression.Equal(read2ExpValue, Expression.Constant(null)), + Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Default(field.FieldType)), + Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType))) + //), + //Expression.Catch(typeof(Exception), Expression.Block( + // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(0)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 0)))), + // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(1)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 1)))), + // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(2)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 2)))), + // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(3)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 3)))), + // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(4)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 4)))) + // ) + //)) + }); } block2Exp.AddRange(new Expression[] { - Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)), - Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) - }); + Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)), + Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) + }); return Expression.Lambda>( Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); } - var rowLenExp = Expression.ArrayLength(rowExp); + var rowLenExp = Expression.MakeMemberAccess(rowExp, PropertyDataReaderFieldCount); return Expression.Lambda>( Expression.Block( Expression.IfThen( From 26b8a98ad4a6ada97f4211ad8c57c437f9f87b1b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 22 Apr 2020 14:55:25 +0800 Subject: [PATCH 0595/1029] v1.4.0-preview0423 #283 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 64516ba6..f90fec7d 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e84b6cdb..5701d3f5 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 650d4e7c..7c0583c4 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 0a0d03a9..02acb461 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index af815c73..fc9ba519 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0422 + 1.4.0-preview0423 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 7808caa9..640c46f0 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 621c20c7..9cf7f4a8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index bd553e03..7a61fe25 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c1f93c51..60a88a59 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index e4869034..20e33d15 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 4d9aaf05..03b53d08 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6f335e1d..0929b11c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a2d71121..9cde1b06 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3fc66c8e..a3b09ffa 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index bda2ea7b..9606aa48 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index dfd83192..a21cdcab 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 21f39a9e..ff93e089 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a744b650..180a9c61 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0422 + 1.4.0-preview0423 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 34c671cdd83a7e15455665e201c178c68fb835d1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Apr 2020 12:52:21 +0800 Subject: [PATCH 0596/1029] rename iDbFirst to IDbFirst --- FreeSql/Interface/{iDbFirst.cs => IDbFirst - 复制.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename FreeSql/Interface/{iDbFirst.cs => IDbFirst - 复制.cs} (100%) diff --git a/FreeSql/Interface/iDbFirst.cs b/FreeSql/Interface/IDbFirst - 复制.cs similarity index 100% rename from FreeSql/Interface/iDbFirst.cs rename to FreeSql/Interface/IDbFirst - 复制.cs From 960185590a9f440ea07ea6bca78203592a0eec8b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Apr 2020 12:52:32 +0800 Subject: [PATCH 0597/1029] rename iDbFirst to IDbFirst --- FreeSql/Interface/{IDbFirst - 复制.cs => IDbFirst.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename FreeSql/Interface/{IDbFirst - 复制.cs => IDbFirst.cs} (100%) diff --git a/FreeSql/Interface/IDbFirst - 复制.cs b/FreeSql/Interface/IDbFirst.cs similarity index 100% rename from FreeSql/Interface/IDbFirst - 复制.cs rename to FreeSql/Interface/IDbFirst.cs From 79d7d6f5b8b63c764e406a7db9edff41defe4a5e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Apr 2020 13:52:17 +0800 Subject: [PATCH 0598/1029] update readme --- FreeSql/Internal/ObjectPool/ObjectPool.cs | 6 +++--- readme.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/FreeSql/Internal/ObjectPool/ObjectPool.cs b/FreeSql/Internal/ObjectPool/ObjectPool.cs index 6b9d520f..6e760519 100644 --- a/FreeSql/Internal/ObjectPool/ObjectPool.cs +++ b/FreeSql/Internal/ObjectPool/ObjectPool.cs @@ -329,7 +329,7 @@ namespace FreeSql.Internal.ObjectPool Policy.OnGetTimeout(); if (Policy.IsThrowGetTimeoutException) - throw new TimeoutException($"SafeObjectPool.Get 获取超时({timeout.Value.TotalSeconds}秒)。"); + throw new TimeoutException($"ObjectPool.Get 获取超时({timeout.Value.TotalSeconds}秒)。"); return null; } @@ -363,7 +363,7 @@ namespace FreeSql.Internal.ObjectPool { if (Policy.AsyncGetCapacity > 0 && _getAsyncQueue.Count >= Policy.AsyncGetCapacity - 1) - throw new OutOfMemoryException($"SafeObjectPool.GetAsync 无可用资源且队列过长,Policy.AsyncGetCapacity = {Policy.AsyncGetCapacity}。"); + throw new OutOfMemoryException($"ObjectPool.GetAsync 无可用资源且队列过长,Policy.AsyncGetCapacity = {Policy.AsyncGetCapacity}。"); var tcs = new TaskCompletionSource>(); @@ -383,7 +383,7 @@ namespace FreeSql.Internal.ObjectPool // Policy.GetTimeout(); // if (Policy.IsThrowGetTimeoutException) - // throw new Exception($"SafeObjectPool.GetAsync 获取超时({timeout.Value.TotalSeconds}秒)。"); + // throw new Exception($"ObjectPool.GetAsync 获取超时({timeout.Value.TotalSeconds}秒)。"); // return null; //} diff --git a/readme.md b/readme.md index 5abda4e9..98011ce8 100644 --- a/readme.md +++ b/readme.md @@ -23,9 +23,9 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | | | - | - | | | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《BaseEntity》](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity) | -| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《乐观锁》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9#%E4%B9%90%E8%A7%82%E9%94%81) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | > FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: From 2e62db563df2311f415809fe7e8c3ae673b74735 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 23 Apr 2020 13:54:39 +0800 Subject: [PATCH 0599/1029] update readme --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 98011ce8..3e0575d3 100644 --- a/readme.md +++ b/readme.md @@ -23,9 +23,9 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | | | - | - | | | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | > FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: From 5e15749aa8ae8578a6b8b3c365d6ab25802aa0e1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 24 Apr 2020 01:47:48 +0800 Subject: [PATCH 0600/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20UnitOfWorkMa?= =?UTF-8?q?nager=20=E5=B7=A5=E4=BD=9C=E5=8D=95=E5=85=83=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=99=A8=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E7=A7=8D=E4=BC=A0?= =?UTF-8?q?=E6=92=AD=E4=BA=8B=E5=8A=A1=EF=BC=9B#289?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/HomeController.cs | 70 +++++ Examples/aspnetcore_transaction/Program.cs | 27 ++ .../Properties/launchSettings.json | 27 ++ Examples/aspnetcore_transaction/Startup.cs | 58 ++++ .../TransactionalAttribute.cs | 51 ++++ .../aspnetcore_transaction.csproj | 17 ++ .../DbContext/DbContextScopedFreeSql.cs | 8 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 94 +++--- .../ContextSet/RepositoryUnitOfWorkManager.cs | 201 ------------- .../Repository/DefaultRepository.cs | 8 + .../UnitOfWork/UnitOfWorkManager.cs | 274 ++++++++++++++++++ FreeSql.sln | 15 + FreeSql/FreeSql.xml | 143 --------- .../AdoProvider/AdoProviderTransaction.cs | 31 +- 15 files changed, 621 insertions(+), 405 deletions(-) create mode 100644 Examples/aspnetcore_transaction/Controllers/HomeController.cs create mode 100644 Examples/aspnetcore_transaction/Program.cs create mode 100644 Examples/aspnetcore_transaction/Properties/launchSettings.json create mode 100644 Examples/aspnetcore_transaction/Startup.cs create mode 100644 Examples/aspnetcore_transaction/TransactionalAttribute.cs create mode 100644 Examples/aspnetcore_transaction/aspnetcore_transaction.csproj delete mode 100644 FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWorkManager.cs create mode 100644 FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs diff --git a/Examples/aspnetcore_transaction/Controllers/HomeController.cs b/Examples/aspnetcore_transaction/Controllers/HomeController.cs new file mode 100644 index 00000000..34707033 --- /dev/null +++ b/Examples/aspnetcore_transaction/Controllers/HomeController.cs @@ -0,0 +1,70 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace aspnetcore_transaction.Controllers +{ + [ApiController] + [Route("")] + public class HomeController : ControllerBase + { + private readonly ILogger _logger; + + public HomeController(ILogger logger) + { + _logger = logger; + } + + [HttpGet] + //[Transactional] + virtual public object Get([FromServices] BaseRepository repoSong, [FromServices] BaseRepository repoDetail, [FromServices] SongRepository repoSong2, + [FromServices] SongService serviceSong) + { + serviceSong.Test(); + return "111"; + } + } + + public class SongService + { + BaseRepository _repoSong; + BaseRepository _repoDetail; + SongRepository _repoSong2; + + public SongService(BaseRepository repoSong, BaseRepository repoDetail, SongRepository repoSong2) + { + _repoSong = repoSong; + _repoDetail = repoDetail; + _repoSong2 = repoSong2; + } + + [Transactional] + public virtual void Test() + { + _repoSong.Insert(new Song()); + _repoDetail.Insert(new Detail()); + _repoSong2.Insert(new Song()); + } + } + + public class SongRepository : DefaultRepository + { + public SongRepository(UnitOfWorkManager uowm) : base(uowm?.Orm, uowm) { } + } + + public class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + } + public class Detail + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int SongId { get; set; } + public string Title { get; set; } + } +} diff --git a/Examples/aspnetcore_transaction/Program.cs b/Examples/aspnetcore_transaction/Program.cs new file mode 100644 index 00000000..24fcc6bf --- /dev/null +++ b/Examples/aspnetcore_transaction/Program.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace aspnetcore_transaction +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) + .UseServiceProviderFactory(new FreeSql.DynamicProxyServiceProviderFactory()); + } +} diff --git a/Examples/aspnetcore_transaction/Properties/launchSettings.json b/Examples/aspnetcore_transaction/Properties/launchSettings.json new file mode 100644 index 00000000..a2e23312 --- /dev/null +++ b/Examples/aspnetcore_transaction/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:35350/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "dbcontext_01": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:35351/" + } + } +} \ No newline at end of file diff --git a/Examples/aspnetcore_transaction/Startup.cs b/Examples/aspnetcore_transaction/Startup.cs new file mode 100644 index 00000000..67727f65 --- /dev/null +++ b/Examples/aspnetcore_transaction/Startup.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using aspnetcore_transaction.Controllers; +using FreeSql; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace aspnetcore_transaction +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + Fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\test_trans.db") + .UseAutoSyncStructure(true) + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .UseNoneCommandParameter(true) + .Build(); + } + + public IConfiguration Configuration { get; } + public static IFreeSql Fsql { get; private set; } + + public void ConfigureServices(IServiceCollection services) + { + services.AddControllersWithViews(); + + services.AddSingleton(Fsql); + services.AddScoped(); + services.AddFreeRepository(null, typeof(Startup).Assembly); + services.AddScoped(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Console.OutputEncoding = Encoding.GetEncoding("GB2312"); + Console.InputEncoding = Encoding.GetEncoding("GB2312"); + + app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); + app.UseDeveloperExceptionPage(); + app.UseRouting(); + app.UseEndpoints(a => a.MapControllers()); + } + } +} diff --git a/Examples/aspnetcore_transaction/TransactionalAttribute.cs b/Examples/aspnetcore_transaction/TransactionalAttribute.cs new file mode 100644 index 00000000..049575c1 --- /dev/null +++ b/Examples/aspnetcore_transaction/TransactionalAttribute.cs @@ -0,0 +1,51 @@ +using FreeSql; +using Microsoft.AspNetCore.Mvc.Filters; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql +{ + /// + /// 使用事务执行,请查看 Program.cs 代码开启动态代理 + /// + [AttributeUsage(AttributeTargets.Method)] + public class TransactionalAttribute : DynamicProxyAttribute, IActionFilter + { + public Propagation Propagation { get; set; } = Propagation.Requierd; + public IsolationLevel? IsolationLevel { get; set; } + + [DynamicProxyFromServices] + UnitOfWorkManager _uowManager; + IUnitOfWork _uow; + + public override Task Before(DynamicProxyBeforeArguments args) => OnBefore(_uowManager); + public override Task After(DynamicProxyAfterArguments args) => OnAfter(args.Exception); + + //这里是为了 controller + public void OnActionExecuting(ActionExecutingContext context) => OnBefore(context.HttpContext.RequestServices.GetService(typeof(UnitOfWorkManager)) as UnitOfWorkManager); + public void OnActionExecuted(ActionExecutedContext context) => OnAfter(context.Exception); + + + Task OnBefore(UnitOfWorkManager uowm) + { + _uow = uowm.Begin(this.Propagation, this.IsolationLevel); + return Task.FromResult(false); + } + Task OnAfter(Exception ex) + { + try + { + if (ex == null) _uow.Commit(); + else _uow.Rollback(); + } + finally + { + _uow.Dispose(); + } + return Task.FromResult(false); + } + } +} diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj new file mode 100644 index 00000000..1ff5ec53 --- /dev/null +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj @@ -0,0 +1,17 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + + diff --git a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs index e1b0b1ef..66310a51 100644 --- a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs +++ b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs @@ -35,21 +35,21 @@ namespace FreeSql public ISelect Select() where T1 : class { - _resolveDbContext()?.FlushCommand(); + _resolveDbContext?.Invoke()?.FlushCommand(); return _originalFsql.Select().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction(false)); } public ISelect Select(object dywhere) where T1 : class => Select().WhereDynamic(dywhere); public IDelete Delete() where T1 : class { - _resolveDbContext()?.FlushCommand(); + _resolveDbContext?.Invoke()?.FlushCommand(); return _originalFsql.Delete().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); } public IDelete Delete(object dywhere) where T1 : class => Delete().WhereDynamic(dywhere); public IUpdate Update() where T1 : class { - var db = _resolveDbContext(); + var db = _resolveDbContext?.Invoke(); db?.FlushCommand(); var update = _originalFsql.Update().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) update.NoneParameter(db.Options.NoneParameter.Value); @@ -59,7 +59,7 @@ namespace FreeSql public IInsert Insert() where T1 : class { - var db = _resolveDbContext(); + var db = _resolveDbContext?.Invoke(); db?.FlushCommand(); var insert = _originalFsql.Insert().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) insert.NoneParameter(db.Options.NoneParameter.Value); diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 9cf7f4a8..75e7ecf8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -6,7 +6,7 @@ true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access - https://github.com/2881099/FreeSql.DbContext + https://github.com/2881099/FreeSql/wiki/DbContext FreeSql ORM DbContext git MIT diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9f17feac..650dae1f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -227,41 +227,6 @@ 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - - - 仓储的工作单元管理器 - - - - - 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。 - - - - - 支持当前事务,如果没有当前事务,就以非事务方法执行。 - - - - - 使用当前事务,如果没有当前事务,就抛出异常。 - - - - - 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 - - - - - 以非事务方式执行操作,如果当前事务存在则抛出异常。 - - - - - 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,就新建一个事务。 - - 开启过滤器,若使用 using 则使用完后,恢复为原有状态 @@ -381,6 +346,65 @@ 例如:20191121_214504_1 + + + 工作单元管理器 + + + + + 当前的工作单元 + + + + + 将仓储的事务交给我管理 + + + + + + 创建工作单元 + + 事务传播方式 + 事务隔离级别 + + + + + 事务传播方式 + + + + + 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。 + + + + + 支持当前事务,如果没有当前事务,就以非事务方法执行。 + + + + + 使用当前事务,如果没有当前事务,就抛出异常。 + + + + + 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 + + + + + 以非事务方式执行操作,如果当前事务存在则抛出异常。 + + + + + 以嵌套事务方式执行。 + + EFCore 95% 相似的 FluentApi 扩展方法 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWorkManager.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWorkManager.cs deleted file mode 100644 index a3524b59..00000000 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWorkManager.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Linq; -using System.Linq.Expressions; -using System.Threading; - -namespace FreeSql -{ - /// - /// 仓储的工作单元管理器 - /// - public class RepositoryUnitOfWorkManager : IDisposable - { - IFreeSql _fsql; - List _uows = new List(); - bool _isNotSupported = false; - - public RepositoryUnitOfWorkManager(IFreeSql fsql) - { - _fsql = fsql ?? throw new ArgumentNullException($"{nameof(RepositoryUnitOfWorkManager)} 构造参数 {nameof(fsql)} 不能为 null"); - } - - ~RepositoryUnitOfWorkManager() => this.Dispose(); - int _disposeCounter; - public void Dispose() - { - if (Interlocked.Increment(ref _disposeCounter) != 1) return; - try - { - Exception exception = null; - for (var a = _uows.Count - 1; a >= 0; a--) - { - try - { - if (exception == null) _uows[a].Commit(); - else _uows[a].Rollback(); - } - catch (Exception ex) - { - if (exception == null) exception = ex; - } - } - if (exception != null) throw exception; - } - finally - { - _uows.Clear(); - GC.SuppressFinalize(this); - } - } - - public enum Propagation - { - /// - /// 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。 - /// - Requierd, - /// - /// 支持当前事务,如果没有当前事务,就以非事务方法执行。 - /// - Supports, - /// - /// 使用当前事务,如果没有当前事务,就抛出异常。 - /// - Mandatory, - /// - /// 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 - /// - NotSupported, - /// - /// 以非事务方式执行操作,如果当前事务存在则抛出异常。 - /// - Never, - /// - /// 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,就新建一个事务。 - /// - Nested - } - - public IRepositoryUnitOfWork Begin(Propagation propagation, IsolationLevel? isolationLevel = null) - { - if (propagation == Propagation.Requierd) - { - if (_isNotSupported == false) - { - for (var a = _uows.Count - 1; a >= 0; a--) - if (_uows[a].GetOrBeginTransaction(false) != null) - return new UnitOfWorkProxy(_uows[a]); - } - var uow = new RepositoryUnitOfWork(_fsql); - if (isolationLevel != null) uow.IsolationLevel = isolationLevel.Value; - try { uow.GetOrBeginTransaction(); } - catch { uow.Dispose(); throw; } - _uows.Add(uow); - return uow; - } - if (propagation == Propagation.Supports) - { - if (_isNotSupported == false) - { - for (var a = _uows.Count - 1; a >= 0; a--) - if (_uows[a].GetOrBeginTransaction(false) != null) - return new UnitOfWorkProxy(_uows[a]); - } - return new UnitOfWorkNothing(_fsql); - } - if (propagation == Propagation.Mandatory) - { - if (_isNotSupported == false) - { - for (var a = _uows.Count - 1; a >= 0; a--) - if (_uows[a].GetOrBeginTransaction(false) != null) - return new UnitOfWorkProxy(_uows[a]); - throw new Exception("Propagation_Mandatory: 使用当前事务,如果没有当前事务,就抛出异常"); - } - throw new Exception("Propagation_Mandatory: 使用当前事务,如果没有当前事务,就抛出异常(NotSupported 事务挂起中)"); - } - if (propagation == Propagation.NotSupported) - { - if (_isNotSupported == false) - { - _isNotSupported = true; - return new UnitOfWorkNothing(_fsql) { OnDispose = () => _isNotSupported = false }; - } - return new UnitOfWorkNothing(_fsql); - } - if (propagation == Propagation.Never) - { - if (_isNotSupported == false) - { - for (var a = _uows.Count - 1; a >= 0; a--) - if (_uows[a].GetOrBeginTransaction(false) != null) - throw new Exception("Propagation_Never: 以非事务方式执行操作,如果当前事务存在则抛出异常"); - } - return new UnitOfWorkNothing(_fsql); - } - if (propagation == Propagation.Nested) - { - var uow = new RepositoryUnitOfWork(_fsql); - if (isolationLevel != null) uow.IsolationLevel = isolationLevel.Value; - try { uow.GetOrBeginTransaction(); } - catch { uow.Dispose(); throw; } - _uows.Add(uow); - return uow; - } - throw new NotImplementedException(); - } - - class UnitOfWorkProxy : IRepositoryUnitOfWork - { - IRepositoryUnitOfWork _baseUow; - public UnitOfWorkProxy(IRepositoryUnitOfWork baseUow) => _baseUow = baseUow; - public IsolationLevel? IsolationLevel { get => _baseUow.IsolationLevel; set { } } - public DbContext.EntityChangeReport EntityChangeReport => _baseUow.EntityChangeReport; - - public bool Enable => _baseUow.Enable; - public void Close() => _baseUow.Close(); - public void Open() => _baseUow.Open(); - - public DbTransaction GetOrBeginTransaction(bool isCreate = true) => _baseUow.GetOrBeginTransaction(isCreate); - public void Commit() => this.Dispose(); - public void Rollback() => _baseUow.Rollback(); - public void Dispose() { } - - public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class => _baseUow.GetRepository(filter); - public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class => _baseUow.GetRepository(filter); - public IBaseRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class => _baseUow.GetGuidRepository(filter); - } - class UnitOfWorkNothing : IRepositoryUnitOfWork - { - internal IFreeSql _fsql; - internal Action OnDispose; - public UnitOfWorkNothing(IFreeSql fsql) => _fsql = fsql; - public IsolationLevel? IsolationLevel { get; set; } - public DbContext.EntityChangeReport EntityChangeReport { get; } = new DbContext.EntityChangeReport(); - - public bool Enable { get; } - public void Close() { } - public void Open() { } - - public DbTransaction GetOrBeginTransaction(bool isCreate = true) => null; - public void Commit() - { - if (EntityChangeReport != null && EntityChangeReport.OnChange != null && EntityChangeReport.Report.Any() == true) - EntityChangeReport.OnChange.Invoke(EntityChangeReport.Report); - this.Dispose(); - } - public void Rollback() => this.Dispose(); - public void Dispose() { - EntityChangeReport?.Report.Clear(); - OnDispose?.Invoke(); - } - - public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class => new DefaultRepository(_fsql, filter); - public IBaseRepository GetRepository(Expression> filter = null) where TEntity : class => new DefaultRepository(_fsql, filter); - public IBaseRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class => new GuidRepository(_fsql, filter, asTable); - } - } -} diff --git a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs index 6f36a3dc..86b43806 100644 --- a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs @@ -7,11 +7,19 @@ namespace FreeSql { public DefaultRepository(IFreeSql fsql) : base(fsql, null, null) { } public DefaultRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter, null) { } + public DefaultRepository(IFreeSql fsql, UnitOfWorkManager uowManger) : base(uowManger?.Orm ?? fsql, null, null) + { + uowManger?.Binding(this); + } } public class GuidRepository : BaseRepository where TEntity : class { public GuidRepository(IFreeSql fsql) : this(fsql, null, null) { } public GuidRepository(IFreeSql fsql, Expression> filter, Func asTable) : base(fsql, filter, asTable) { } + public GuidRepository(IFreeSql fsql, UnitOfWorkManager uowManger) : base(uowManger?.Orm ?? fsql, null, null) + { + uowManger?.Binding(this); + } } } diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs new file mode 100644 index 00000000..428fd7fb --- /dev/null +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs @@ -0,0 +1,274 @@ + +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Threading; + +namespace FreeSql +{ + /// + /// 工作单元管理器 + /// + public class UnitOfWorkManager : IDisposable + { + DbContextScopedFreeSql _ormScoped; + public IFreeSql Orm => _ormScoped; + List _rawUows = new List(); + List _allUows = new List(); + List _repos = new List(); + + public UnitOfWorkManager(IFreeSql fsql) + { + if (fsql == null) throw new ArgumentNullException($"{nameof(UnitOfWorkManager)} 构造参数 {nameof(fsql)} 不能为 null"); + _ormScoped = DbContextScopedFreeSql.Create(fsql, null, () => this.Current); + } + + #region Dispose + ~UnitOfWorkManager() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + try + { + Exception exception = null; + for (var a = _rawUows.Count - 1; a >= 0; a--) + { + try + { + if (exception == null) _rawUows[a].Uow.Commit(); + else _rawUows[a].Uow.Rollback(); + } + catch (Exception ex) + { + if (exception == null) exception = ex; + } + } + if (exception != null) throw exception; + } + finally + { + _rawUows.Clear(); + _allUows.Clear(); + _repos.Clear(); + GC.SuppressFinalize(this); + } + } + #endregion + + /// + /// 当前的工作单元 + /// + public IUnitOfWork Current => _allUows.LastOrDefault()?.Uow; + + /// + /// 将仓储的事务交给我管理 + /// + /// + public void Binding(IBaseRepository repository) + { + var repoInfo = new RepoInfo(repository); + repository.UnitOfWork = Current; + _repos.Add(repoInfo); + } + void SetAllRepositoryUow() + { + foreach (var repo in _repos) + repo.Repository.UnitOfWork = Current ?? repo.OrginalUow; + } + + /// + /// 创建工作单元 + /// + /// 事务传播方式 + /// 事务隔离级别 + /// + public IUnitOfWork Begin(Propagation propagation = Propagation.Requierd, IsolationLevel? isolationLevel = null) + { + switch (propagation) + { + case Propagation.Requierd: return FindedUowCreateVirtual() ?? CreateUow(isolationLevel); + case Propagation.Supports: return FindedUowCreateVirtual() ?? CreateUowNothing(_allUows.LastOrDefault()?.IsNotSupported ?? false); + case Propagation.Mandatory: return FindedUowCreateVirtual() ?? throw new Exception("Propagation_Mandatory: 使用当前事务,如果没有当前事务,就抛出异常"); + case Propagation.NotSupported: return CreateUowNothing(true); + case Propagation.Never: + var isNotSupported = _allUows.LastOrDefault()?.IsNotSupported ?? false; + if (isNotSupported == false) + { + for (var a = _rawUows.Count - 1; a >= 0; a--) + if (_rawUows[a].Uow.GetOrBeginTransaction(false) != null) + throw new Exception("Propagation_Never: 以非事务方式执行操作,如果当前事务存在则抛出异常"); + } + return CreateUowNothing(isNotSupported); + case Propagation.Nested: return CreateUow(isolationLevel); + default: throw new NotImplementedException(); + } + } + + IUnitOfWork FindedUowCreateVirtual() + { + var isNotSupported = _allUows.LastOrDefault()?.IsNotSupported ?? false; + if (isNotSupported == false) + { + for (var a = _rawUows.Count - 1; a >= 0; a--) + if (_rawUows[a].Uow.GetOrBeginTransaction(false) != null) + { + var uow = new UnitOfWorkVirtual(_rawUows[a].Uow); + var uowInfo = new UowInfo(uow, UowInfo.UowType.Virtual, isNotSupported); + uow.OnDispose = () => _allUows.Remove(uowInfo); + _allUows.Add(uowInfo); + SetAllRepositoryUow(); + return uow; + } + } + return null; + } + IUnitOfWork CreateUowNothing(bool isNotSupported) + { + var uow = new UnitOfWorkNothing(Orm); + var uowInfo = new UowInfo(uow, UowInfo.UowType.Nothing, isNotSupported); + uow.OnDispose = () => _allUows.Remove(uowInfo); + _allUows.Add(uowInfo); + SetAllRepositoryUow(); + return uow; + } + IUnitOfWork CreateUow(IsolationLevel? isolationLevel) + { + var uow = new UnitOfWorkOrginal(new UnitOfWork(Orm)); + var uowInfo = new UowInfo(uow, UowInfo.UowType.Orginal, false); + if (isolationLevel != null) uow.IsolationLevel = isolationLevel.Value; + try { uow.GetOrBeginTransaction(); } + catch { uow.Dispose(); throw; } + + uow.OnDispose = () => + { + _rawUows.Remove(uowInfo); + _allUows.Remove(uowInfo); + SetAllRepositoryUow(); + }; + _rawUows.Add(uowInfo); + _allUows.Add(uowInfo); + SetAllRepositoryUow(); + return uow; + } + + class RepoInfo + { + public IBaseRepository Repository; + public IUnitOfWork OrginalUow; + + public RepoInfo(IBaseRepository repository) + { + this.Repository = repository; + this.OrginalUow = repository.UnitOfWork; + } + } + class UowInfo + { + public IUnitOfWork Uow; + public UowType Type; + public bool IsNotSupported; + public enum UowType { Orginal, Virtual, Nothing } + + public UowInfo(IUnitOfWork uow, UowType type, bool isNotSupported) + { + this.Uow = uow; + this.Type = type; + this.IsNotSupported = isNotSupported; + } + } + class UnitOfWorkOrginal : IUnitOfWork + { + IUnitOfWork _baseUow; + internal Action OnDispose; + public UnitOfWorkOrginal(IUnitOfWork baseUow) => _baseUow = baseUow; + public IsolationLevel? IsolationLevel { get => _baseUow.IsolationLevel; set => _baseUow.IsolationLevel = value; } + public DbContext.EntityChangeReport EntityChangeReport => _baseUow.EntityChangeReport; + + public bool Enable => _baseUow.Enable; + public void Close() => _baseUow.Close(); + public void Open() => _baseUow.Open(); + + public DbTransaction GetOrBeginTransaction(bool isCreate = true) => _baseUow.GetOrBeginTransaction(isCreate); + public void Commit() => _baseUow.Commit(); + public void Rollback() => _baseUow.Rollback(); + public void Dispose() + { + _baseUow.Dispose(); + OnDispose?.Invoke(); + } + } + class UnitOfWorkVirtual : IUnitOfWork + { + IUnitOfWork _baseUow; + internal Action OnDispose; + public UnitOfWorkVirtual(IUnitOfWork baseUow) => _baseUow = baseUow; + public IsolationLevel? IsolationLevel { get => _baseUow.IsolationLevel; set { } } + public DbContext.EntityChangeReport EntityChangeReport => _baseUow.EntityChangeReport; + + public bool Enable => _baseUow.Enable; + public void Close() => _baseUow.Close(); + public void Open() => _baseUow.Open(); + + public DbTransaction GetOrBeginTransaction(bool isCreate = true) => _baseUow.GetOrBeginTransaction(isCreate); + public void Commit() { } + public void Rollback() => _baseUow.Rollback(); + public void Dispose() => OnDispose?.Invoke(); + } + class UnitOfWorkNothing : IUnitOfWork + { + internal IFreeSql _fsql; + internal Action OnDispose; + public UnitOfWorkNothing(IFreeSql fsql) => _fsql = fsql; + public IsolationLevel? IsolationLevel { get; set; } + public DbContext.EntityChangeReport EntityChangeReport { get; } = new DbContext.EntityChangeReport(); + + public bool Enable { get; } + public void Close() { } + public void Open() { } + + public DbTransaction GetOrBeginTransaction(bool isCreate = true) => null; + public void Commit() + { + if (EntityChangeReport != null && EntityChangeReport.OnChange != null && EntityChangeReport.Report.Any() == true) + EntityChangeReport.OnChange.Invoke(EntityChangeReport.Report); + EntityChangeReport?.Report.Clear(); + } + public void Rollback() => EntityChangeReport?.Report.Clear(); + public void Dispose() => OnDispose?.Invoke(); + } + } + + /// + /// 事务传播方式 + /// + public enum Propagation + { + /// + /// 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。 + /// + Requierd, + /// + /// 支持当前事务,如果没有当前事务,就以非事务方法执行。 + /// + Supports, + /// + /// 使用当前事务,如果没有当前事务,就抛出异常。 + /// + Mandatory, + /// + /// 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 + /// + NotSupported, + /// + /// 以非事务方式执行操作,如果当前事务存在则抛出异常。 + /// + Never, + /// + /// 以嵌套事务方式执行。 + /// + Nested + } +} diff --git a/FreeSql.sln b/FreeSql.sln index 7cf8a130..0f8259b1 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -78,6 +78,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.Linq", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Dameng", "Providers\FreeSql.Provider.Dameng\FreeSql.Provider.Dameng.csproj", "{E74D90E8-1CBC-4677-817B-1CA05AB97937}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aspnetcore_transaction", "Examples\aspnetcore_transaction\aspnetcore_transaction.csproj", "{07AB0B37-A8B1-4FB1-9259-7B804E369E36}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -472,6 +474,18 @@ Global {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|x64.Build.0 = Release|Any CPU {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|x86.ActiveCfg = Release|Any CPU {E74D90E8-1CBC-4677-817B-1CA05AB97937}.Release|x86.Build.0 = Release|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Debug|x64.ActiveCfg = Debug|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Debug|x64.Build.0 = Debug|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Debug|x86.ActiveCfg = Debug|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Debug|x86.Build.0 = Debug|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|Any CPU.Build.0 = Release|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|x64.ActiveCfg = Release|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|x64.Build.0 = Release|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|x86.ActiveCfg = Release|Any CPU + {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -499,6 +513,7 @@ Global {B397A761-F646-41CF-A160-AB6C05DAF2FB} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {57B3F5B0-D46A-4442-8EC6-9A9A784404B7} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {E74D90E8-1CBC-4677-817B-1CA05AB97937} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {07AB0B37-A8B1-4FB1-9259-7B804E369E36} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d6b6f1a8..48b7b879 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2310,137 +2310,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2961,12 +2830,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3037,12 +2900,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index cd7356a5..bed124cb 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -16,14 +16,14 @@ namespace FreeSql.Internal.CommonProvider class Transaction2 { internal Aop.TraceBeforeEventArgs AopBefore; - internal Object Conn; + internal Object Connection; internal DbTransaction Transaction; internal DateTime RunTime; internal TimeSpan Timeout; public Transaction2(Object conn, DbTransaction tran, TimeSpan timeout) { - Conn = conn; + Connection = conn; Transaction = tran; RunTime = DateTime.Now; Timeout = timeout; @@ -31,7 +31,6 @@ namespace FreeSql.Internal.CommonProvider } private ConcurrentDictionary _trans = new ConcurrentDictionary(); - private object _trans_lock = new object(); public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null; public Aop.TraceBeforeEventArgs TransactionCurrentThreadAopBefore => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.AopBefore : null; @@ -61,35 +60,27 @@ namespace FreeSql.Internal.CommonProvider throw ex; } if (_trans.ContainsKey(tid)) CommitTransaction(); - - lock (_trans_lock) - _trans.TryAdd(tid, tran); + _trans.TryAdd(tid, tran); } private void CommitTimeoutTransaction() { if (_trans.Count > 0) { - Transaction2[] trans = null; - lock (_trans_lock) - trans = _trans.Values.Where(st2 => DateTime.Now.Subtract(st2.RunTime) > st2.Timeout).ToArray(); - foreach (Transaction2 tran in trans) CommitTransaction(true, tran, null, "Timeout自动提交"); + var trans = _trans.Values.Where(st2 => DateTime.Now.Subtract(st2.RunTime) > st2.Timeout).ToArray(); + foreach (var tran in trans) CommitTransaction(true, tran, null, "Timeout自动提交"); } } private void CommitTransaction(bool isCommit, Transaction2 tran, Exception rollbackException, string remark = null) { if (tran == null || tran.Transaction == null || tran.Transaction.Connection == null) return; - - if (_trans.ContainsKey(tran.Conn.LastGetThreadId)) - lock (_trans_lock) - if (_trans.ContainsKey(tran.Conn.LastGetThreadId)) - _trans.TryRemove(tran.Conn.LastGetThreadId, out var oldtran); + _trans.TryRemove(tran.Connection.LastGetThreadId, out var oldtran); Exception ex = null; if (string.IsNullOrEmpty(remark)) remark = isCommit ? "提交" : "回滚"; try { - Trace.WriteLine($"线程{tran.Conn.LastGetThreadId}事务{remark}"); + Trace.WriteLine($"线程{tran.Connection.LastGetThreadId}事务{remark}"); if (isCommit) tran.Transaction.Commit(); else tran.Transaction.Rollback(); } @@ -100,7 +91,7 @@ namespace FreeSql.Internal.CommonProvider } finally { - ReturnConnection(MasterPool, tran.Conn, ex); //MasterPool.Return(tran.Conn, ex); + ReturnConnection(MasterPool, tran.Connection, ex); //MasterPool.Return(tran.Conn, ex); var after = new Aop.TraceAfterEventArgs(tran.AopBefore, remark, ex ?? rollbackException); _util?._orm?.Aop.TraceAfterHandler?.Invoke(this, after); @@ -141,10 +132,8 @@ namespace FreeSql.Internal.CommonProvider if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { - Transaction2[] trans = null; - lock (_trans_lock) - trans = _trans.Values.ToArray(); - foreach (Transaction2 tran in trans) CommitTransaction(false, tran, null, "Dispose自动提交"); + var trans = _trans.Values.ToArray(); + foreach (var tran in trans) CommitTransaction(false, tran, null, "Dispose自动提交"); } catch { } From 2825f8acd2fbbfc0c7e4b9e3ff7ad1b58543aacb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 24 Apr 2020 02:11:42 +0800 Subject: [PATCH 0601/1029] v1.4.0-preview0424 --- .../aspnetcore_transaction/Controllers/HomeController.cs | 2 +- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 19 insertions(+), 28 deletions(-) diff --git a/Examples/aspnetcore_transaction/Controllers/HomeController.cs b/Examples/aspnetcore_transaction/Controllers/HomeController.cs index 34707033..d3fe0d1c 100644 --- a/Examples/aspnetcore_transaction/Controllers/HomeController.cs +++ b/Examples/aspnetcore_transaction/Controllers/HomeController.cs @@ -39,7 +39,7 @@ namespace aspnetcore_transaction.Controllers _repoSong2 = repoSong2; } - [Transactional] + [Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的 public virtual void Test() { _repoSong.Insert(new Song()); diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f90fec7d..b618fc56 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 5701d3f5..66b31e81 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7c0583c4..13eb59f6 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 02acb461..e2c30948 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index fc9ba519..59ef5f84 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0423 + 1.4.0-preview0424 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 640c46f0..a6b2ea20 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 75e7ecf8..d9dc915f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 650dae1f..67d4eb4a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -481,14 +481,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7a61fe25..6b27270b 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 60a88a59..d9669e24 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 20e33d15..b8f79a51 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 03b53d08..7aa0a215 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0929b11c..01ff06d6 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 9cde1b06..eeadf940 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a3b09ffa..71cea5d2 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 9606aa48..1bf0277f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a21cdcab..657243ef 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index ff93e089..3f09569c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 180a9c61..441ab517 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0423 + 1.4.0-preview0424 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 2db061b27cd3e2d656dc734d6aa0f3c65b6697b5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 24 Apr 2020 23:13:50 +0800 Subject: [PATCH 0602/1029] update readme --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++ FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 13 +- FreeSql/FreeSql.xml | 143 ++++++++++++++++++++ readme.md | 47 +++---- 4 files changed, 182 insertions(+), 30 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 67d4eb4a..650dae1f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -481,5 +481,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index dfc5e034..be92522b 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -20,26 +20,29 @@ namespace FreeSql IsolationLevel? IsolationLevel { get; set; } - /// - /// 是否启用工作单元 - /// - bool Enable { get; } - void Commit(); void Rollback(); + /// + /// 是否启用工作单元 + /// + [Obsolete("即将删除(保留到2020-08-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] + bool Enable { get; } + /// /// 禁用工作单元 /// /// /// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 /// + [Obsolete("即将删除(保留到2020-08-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] void Close(); /// /// 开启工作单元 /// + [Obsolete("即将删除(保留到2020-08-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] void Open(); /// diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 48b7b879..d6b6f1a8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2310,6 +2310,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 }) + + + + + + 可自定义解析表达式 @@ -2830,6 +2961,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2900,6 +3037,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/readme.md b/readme.md index 3e0575d3..9b87db43 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@

- +

FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+ 或 Xamarin @@ -8,7 +8,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/2881099/FreeSql/master/LICENSE.txt) -## Features +## ✨ Features - [x] 支持 CodeFirst 迁移,哪怕使用 Access 数据库也支持; - [x] 支持 DbFirst 从数据库导入实体类,[安装实体类生成工具](https://github.com/2881099/FreeSql/wiki/DbFirst); @@ -18,7 +18,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; - [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库/Access; -## Documentation +## 📖 Documentation | | | | - | - | @@ -27,14 +27,14 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | | | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | -> FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: +> 💿 FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: - 要么FreeSql,原始用法; - 要么[FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository),仓储+工作单元习惯; - 要么[FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; - 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),求简单使用这个; -> 学习项目 +> 💿 学习项目 - [zhontai.net Admin后台管理系统](https://github.com/zhontai/Admin.Core) - [😃 A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) @@ -44,7 +44,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+

-## Quick start +## 🚀 Quick start > dotnet add package FreeSql.Provider.Sqlite @@ -83,7 +83,7 @@ class Tag { } ``` -## Query +## 🔍 Query ```csharp //OneToOne、ManyToOne fsql.Select() @@ -130,33 +130,30 @@ fsql.Select() ``` [More..](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) -## Repository & UnitOfWork +## 📦 Repository + > dotnet add package FreeSql.Repository ```csharp -using (var uow = fsql.CreateUnitOfWork()) { - var repo1 = uow.GetRepository(); - var repo2 = uow.GetRepository(); +var repo = uow.GetRepository(); +repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; - repo2.DbContextOptions.EnableAddOrUpdateNavigateList = true; - repo2.Insert(new Tag { - Name = "testaddsublist", - Tags = new[] { +repo.Insert(new Tag { + Name = "testaddsublist", + Tags = new[] { new Tag { Name = "sub1" }, new Tag { Name = "sub2" }, new Tag { - Name = "sub3", - Tags = new[] { + Name = "sub3", + Tags = new[] { new Tag { Name = "sub3_01" } - } } - } - }); - uow.Commit(); -} + } + } +}); ``` -## Performance +## 💪 Performance FreeSql Query & Dapper Query ```shell @@ -184,7 +181,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [More..](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd) -## Contributors +## 👯 Contributors [systemhejiyong](https://github.com/systemhejiyong)、 [LambertW](https://github.com/LambertW)、 @@ -202,7 +199,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper (QQ群:4336577) -## Donation +## 💕 Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元 From 37ad9d35c803dfad912557b9fcb79972b76f48a5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 24 Apr 2020 23:19:36 +0800 Subject: [PATCH 0603/1029] update readme --- readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 9b87db43..a35a6742 100644 --- a/readme.md +++ b/readme.md @@ -22,10 +22,10 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | | | - | - | -| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) | -| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | > 💿 FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: @@ -36,8 +36,8 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ > 💿 学习项目 -- [zhontai.net Admin后台管理系统](https://github.com/zhontai/Admin.Core) -- [😃 A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) +- [zhontai.net Admin 后台管理系统](https://github.com/zhontai/Admin.Core) +- [A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) - [内容管理系统](https://github.com/hejiyong/fscms)

From 5643d818f7655df34894dbabd298148f28659f2e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 24 Apr 2020 23:25:33 +0800 Subject: [PATCH 0604/1029] upread readme --- readme.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index a35a6742..337359d9 100644 --- a/readme.md +++ b/readme.md @@ -141,14 +141,15 @@ repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; repo.Insert(new Tag { Name = "testaddsublist", Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" }, + new Tag { Name = "sub3", - Tags = new[] { + Tags = new[] { new Tag { Name = "sub3_01" } + } } - } + } } }); ``` From 8bc32ac0438e9dd6afca223a85b342a68116a8a8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 24 Apr 2020 23:44:44 +0800 Subject: [PATCH 0605/1029] update readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 337359d9..766729ec 100644 --- a/readme.md +++ b/readme.md @@ -8,7 +8,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/2881099/FreeSql/master/LICENSE.txt) -## ✨ Features +## 🐮 Features - [x] 支持 CodeFirst 迁移,哪怕使用 Access 数据库也支持; - [x] 支持 DbFirst 从数据库导入实体类,[安装实体类生成工具](https://github.com/2881099/FreeSql/wiki/DbFirst); From 5bd3e6e00dc68366b8ee1ed9e2ea91db4395d2b1 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Sat, 25 Apr 2020 17:01:01 +0800 Subject: [PATCH 0606/1029] Update readme.md --- readme.md | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/readme.md b/readme.md index 766729ec..d1926795 100644 --- a/readme.md +++ b/readme.md @@ -18,7 +18,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; - [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库/Access; -## 📖 Documentation +## 📚 Documentation | | | | - | - | @@ -83,22 +83,18 @@ class Tag { } ``` -## 🔍 Query +## 👀 Query ```csharp //OneToOne、ManyToOne -fsql.Select() - .Where(a => a.Parent.Parent.Name == "粤语") - .ToList(); +fsql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToList(); //OneToMany -fsql.Select() - .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) - .ToList(); +fsql.Select().IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")).ToList(); //ManyToMany fsql.Select() - .Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")) .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "xxx")) + .Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")) .ToList(); //Other @@ -115,18 +111,11 @@ fsql.Select() [More..](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) ```csharp -fsql.Select() - .Where(a => new[] { 1, 2, 3 }.Contains(a.Id)) - .ToList(); +fsql.Select().Where(a => new[] { 1, 2, 3 }.Contains(a.Id)).ToList(); -fsql.Select() - .Where(a => a.CreateTime.Date == DateTime.Today) - .ToList(); +fsql.Select().Where(a => a.CreateTime.Date == DateTime.Today).ToList(); -fsql.Select() - .OrderBy(a => Guid.NewGuid()) - .Limit(10) - .ToList(); +fsql.Select().OrderBy(a => Guid.NewGuid()).Limit(10).ToList(); ``` [More..](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) From 4fa1475ab79463a48bc63a3ffca98c1469c73dcd Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Sat, 25 Apr 2020 17:03:38 +0800 Subject: [PATCH 0607/1029] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index d1926795..40f6c221 100644 --- a/readme.md +++ b/readme.md @@ -83,7 +83,7 @@ class Tag { } ``` -## 👀 Query +## 🔎 Query ```csharp //OneToOne、ManyToOne fsql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToList(); @@ -119,7 +119,7 @@ fsql.Select().OrderBy(a => Guid.NewGuid()).Limit(10).ToList(); ``` [More..](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) -## 📦 Repository +## 🚁 Repository > dotnet add package FreeSql.Repository From b41680adfaae4fde1ba034e0c55fcfb1e2b6f2d6 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Sat, 25 Apr 2020 17:08:36 +0800 Subject: [PATCH 0608/1029] Update readme.md --- readme.md | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/readme.md b/readme.md index 40f6c221..97725bb0 100644 --- a/readme.md +++ b/readme.md @@ -124,25 +124,27 @@ fsql.Select().OrderBy(a => Guid.NewGuid()).Limit(10).ToList(); > dotnet add package FreeSql.Repository ```csharp -var repo = uow.GetRepository(); -repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; +[Transactional] +public void Add() +{ + var repo = ioc.GetService>(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; -repo.Insert(new Tag { - Name = "testaddsublist", - Tags = new[] { - new Tag { Name = "sub1" }, - new Tag { Name = "sub2" }, - new Tag { - Name = "sub3", - Tags = new[] { - new Tag { Name = "sub3_01" } - } - } + var item = new Tag + { + Name = "testaddsublist", + Tags = new[] + { + new Tag { Name = "sub1" }, + new Tag { Name = "sub2" } } - } -}); + }; + repo.Insert(item); +} ``` +参考:[在 asp.net core 中使用 TransactionalAttribute + UnitOfWorkManager 实现多种事务传播](https://github.com/dotnetcore/FreeSql/issues/289) + ## 💪 Performance FreeSql Query & Dapper Query From 635244786aa27811ee48bb0f8f6026ec59acdf1b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 26 Apr 2020 00:34:50 +0800 Subject: [PATCH 0609/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=20DbContext?= =?UTF-8?q?Options.EnableGlobalFilter=20=E8=AE=BE=E7=BD=AE=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E5=9C=A8=20DbContext/Repository=20=E4=B8=AD=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E5=85=A8=E5=B1=80=E8=BF=87=E6=BB=A4=E5=99=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 2 ++ .../DbContext/DbContextOptions.cs | 5 +++++ .../DbContext/DbContextScopedFreeSql.cs | 15 +++++++++++---- FreeSql.DbContext/DbSet/DbSet.cs | 12 ++++++++++-- FreeSql.DbContext/FreeSql.DbContext.xml | 14 +++++--------- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 19 +++++++++++++++++++ 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index cac45b44..0666a4c3 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -43,6 +43,8 @@ namespace FreeSql if (FreeSqlDbContextExtensions._dicSetDbContextOptions.TryGetValue(OrmOriginal.Ado.Identifier, out var opt)) { _optionsPriv.EnableAddOrUpdateNavigateList = opt.EnableAddOrUpdateNavigateList; + _optionsPriv.EnableGlobalFilter = opt.EnableGlobalFilter; + _optionsPriv.NoneParameter = opt.NoneParameter; _optionsPriv.OnEntityChange = opt.OnEntityChange; } } diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index deb9490e..e43ff5ae 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -27,6 +27,11 @@ namespace FreeSql ///

public bool? NoneParameter { get; set; } + /// + /// 是否开启 IFreeSql GlobalFilter 功能(默认:true) + /// + public bool EnableGlobalFilter { get; set; } = true; + /// /// 实体变化事件 /// diff --git a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs index 66310a51..2aabe397 100644 --- a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs +++ b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs @@ -35,15 +35,21 @@ namespace FreeSql public ISelect Select() where T1 : class { - _resolveDbContext?.Invoke()?.FlushCommand(); - return _originalFsql.Select().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction(false)); + var db = _resolveDbContext?.Invoke(); + db?.FlushCommand(); + var select = _originalFsql.Select().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction(false)); + if (db?.Options.EnableGlobalFilter == false) select.DisableGlobalFilter(); + return select; } public ISelect Select(object dywhere) where T1 : class => Select().WhereDynamic(dywhere); public IDelete Delete() where T1 : class { - _resolveDbContext?.Invoke()?.FlushCommand(); - return _originalFsql.Delete().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + var db = _resolveDbContext?.Invoke(); + db?.FlushCommand(); + var delete = _originalFsql.Delete().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + if (db?.Options.EnableGlobalFilter == false) delete.DisableGlobalFilter(); + return delete; } public IDelete Delete(object dywhere) where T1 : class => Delete().WhereDynamic(dywhere); @@ -53,6 +59,7 @@ namespace FreeSql db?.FlushCommand(); var update = _originalFsql.Update().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) update.NoneParameter(db.Options.NoneParameter.Value); + if (db?.Options.EnableGlobalFilter == false) update.DisableGlobalFilter(); return update; } public IUpdate Update(object dywhere) where T1 : class => Update().WhereDynamic(dywhere); diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 1314a0d1..6af6b0d2 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -33,7 +33,9 @@ namespace FreeSql protected virtual ISelect OrmSelect(object dywhere) { DbContextFlushCommand(); //查询前先提交,否则会出脏读 - return _db.OrmOriginal.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); + var select = _db.OrmOriginal.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); + if (_db.Options.EnableGlobalFilter == false) select.DisableGlobalFilter(); + return select; } ~DbSet() => this.Dispose(); @@ -65,9 +67,15 @@ namespace FreeSql { var update = _db.OrmOriginal.Update().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()); if (_db.Options.NoneParameter != null) update.NoneParameter(_db.Options.NoneParameter.Value); + if (_db.Options.EnableGlobalFilter == false) update.DisableGlobalFilter(); return update.SetSource(entitys); } - protected virtual IDelete OrmDelete(object dywhere) => _db.OrmOriginal.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); + protected virtual IDelete OrmDelete(object dywhere) + { + var delete = _db.OrmOriginal.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); + if (_db.Options.EnableGlobalFilter == false) delete.DisableGlobalFilter(); + return delete; + } internal void EnqueueToDbContext(DbContext.EntityChangeType changeType, EntityState state) => _db.EnqueuePreCommand(changeType, this, typeof(EntityState), _entityType, state); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 650dae1f..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -91,6 +91,11 @@ 使用无参数化设置(对应 IInsert/IUpdate)
+ + + 是否开启 IFreeSql GlobalFilter 功能(默认:true) + + 实体变化事件 @@ -481,14 +486,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 003cc47c..8acbdf71 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -301,6 +301,25 @@ namespace FreeSql.Tests } }); + var repo_dtot22 = g.sqlite.GetRepository(); + + var dtot221 = repo_dtot22.Select.ToList(a => new gfDto + { + dto2 = new dfDto2 + { + rowstate = a.rowstate + } + }); + + repo_dtot22.DbContextOptions.EnableGlobalFilter = false; + var dtot222 = repo_dtot22.Select.ToList(a => new gfDto + { + dto2 = new dfDto2 + { + rowstate = a.rowstate + } + }); + //List<(Guid, DateTime)> contains2linqarr = new List<(Guid, DateTime)>(); //Assert.Equal("SELECT 1 as1 FROM \"TestIgnoreDefaultValue\" a WHERE (1=0)", g.sqlite.Select().Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToSql(a => 1).Replace("\r\n", "")); //g.sqlite.Select().Where(a => contains2linqarr.Contains(a.Id, a.ct1)).ToList(); From 1f4903e8c307b72c7e25f12dc0eb87eb1d39fa18 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 26 Apr 2020 00:38:54 +0800 Subject: [PATCH 0610/1029] update readme --- readme.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 97725bb0..fd8ec62a 100644 --- a/readme.md +++ b/readme.md @@ -125,16 +125,13 @@ fsql.Select().OrderBy(a => Guid.NewGuid()).Limit(10).ToList(); ```csharp [Transactional] -public void Add() -{ +public void Add() { var repo = ioc.GetService>(); repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; - var item = new Tag - { + var item = new Tag { Name = "testaddsublist", - Tags = new[] - { + Tags = new[] { new Tag { Name = "sub1" }, new Tag { Name = "sub2" } } From d2e8bcc26b4397fe7d6add4776139a69cf9d988a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 26 Apr 2020 13:45:23 +0800 Subject: [PATCH 0611/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IncludeMany?= =?UTF-8?q?=20=E9=9B=86=E5=90=88=E5=B1=9E=E6=80=A7=E4=B8=BA=20a.xx.Childs?= =?UTF-8?q?=20=E6=97=B6=EF=BC=8C=E5=8F=AF=E8=83=BD=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MsAccess/Curd/MsAccessSelectTest.cs | 5 + FreeSql/FreeSql.xml | 306 ++++++++++-------- .../SelectProvider/Select1Provider.cs | 21 +- 3 files changed, 185 insertions(+), 147 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index 09682b77..8a51a097 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -1087,17 +1087,20 @@ WHERE (((cstr(a.[Id])) in (SELECT b.[Title] var t00 = g.msaccess.Select() .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) .Where(a => a.model2id <= model1.id) + .Limit(10) .ToList(); var t11 = g.msaccess.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) .Where(a => a.id <= model1.id) + .Limit(10) .ToList(); var t22 = g.msaccess.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) + .Limit(10) .ToList(); } @@ -1148,12 +1151,14 @@ WHERE (((cstr(a.[Id])) in (SELECT b.[Title] .LeftJoin(a => a.model2id == a.model2.id) .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) + .Limit(10) .ToList(true); var t11 = g.msaccess.Select() .LeftJoin(a => a.model2id == a.model2.id) .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) .Where(a => a.id <= model1.id) + .Limit(10) .ToList(true); } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d6b6f1a8..b9f10e13 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2310,137 +2310,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2961,12 +2830,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3037,12 +2900,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3675,4 +3532,167 @@ + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 3870966f..f75af392 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -528,14 +528,22 @@ namespace FreeSql.Internal.CommonProvider var getListValue1 = membersExpNotNull == null ? Expression.Lambda>( Expression.Block( - Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)), + Expression.IfThenElse( + Expression.Equal(propertyNameExp, Expression.Constant("")), //propertyName == "" 返回自身 + Expression.Return(returnTarget, membersExp), + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)) + ), Expression.Label(returnTarget, Expression.Default(typeof(object))) ), t1parm, propertyNameExp).Compile() : Expression.Lambda>( Expression.Block( Expression.IfThen( membersExpNotNull, - Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)) + Expression.IfThenElse( + Expression.Equal(propertyNameExp, Expression.Constant("")), + Expression.Return(returnTarget, membersExp), + Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)) + ) ), Expression.Label(returnTarget, Expression.Default(typeof(object))) ), t1parm, propertyNameExp).Compile(); @@ -656,7 +664,7 @@ namespace FreeSql.Internal.CommonProvider //将子集合的,多对一,对象设置为当前对象 foreach (var parentNav in parentNavs) foreach (var t1item in t1items) - _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1); + _orm.SetEntityValueWithPropertyName(tbref.RefEntityType, nav, parentNav, getListValue1(t1item.Item1, "")); //propertyName == "" 返回自身 } foreach (var t1items in dicList.Values) foreach (var t1item in t1items) @@ -992,9 +1000,14 @@ namespace FreeSql.Internal.CommonProvider } }; - _includeToList.Add(listObj => includeToListSyncOrAsync(listObj, false)); #if net40 + _includeToList.Add(listObj => includeToListSyncOrAsync(listObj, false)); #else + _includeToList.Add(listObj => + { + var task = includeToListSyncOrAsync(listObj, false); + if (task.Exception != null) throw task.Exception.InnerException ?? task.Exception; + }); _includeToListAsync.Add(listObj => includeToListSyncOrAsync(listObj, true)); #endif return this; From 4fcad4a79775741647647822babcaf7936583d60 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 26 Apr 2020 14:20:48 +0800 Subject: [PATCH 0612/1029] v1.4.0 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 306 ++++++++---------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- readme.md | 6 +- 21 files changed, 173 insertions(+), 184 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index b618fc56..2bfc27d1 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0-preview0424 + 1.4.0 true YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 66b31e81..ef15934c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 13eb59f6..86940a73 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index e2c30948..6bd7c2cb 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 59ef5f84..499dc514 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0-preview0424 + 1.4.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index a6b2ea20..d25e5f07 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d9dc915f..5f7e4168 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 6b27270b..0024a9b2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0-preview0424 + 1.4.0 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index d9669e24..50207287 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b9f10e13..d6b6f1a8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2310,6 +2310,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 }) + + + + + + 可自定义解析表达式 @@ -2830,6 +2961,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2900,6 +3037,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3532,167 +3675,4 @@ - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index b8f79a51..8e3b478b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 7aa0a215..485d7616 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 01ff06d6..fd7c010e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index eeadf940..fc6f8268 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 71cea5d2..1e5611d7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 1bf0277f..76059896 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 657243ef..f4f9c3a6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 3f09569c..7612e19c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 441ab517..1169859d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.4.0-preview0424 + 1.4.0 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin diff --git a/readme.md b/readme.md index fd8ec62a..8b8901fb 100644 --- a/readme.md +++ b/readme.md @@ -27,14 +27,14 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | | | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | -> 💿 FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: +> FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: - 要么FreeSql,原始用法; - 要么[FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository),仓储+工作单元习惯; - 要么[FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; - 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),求简单使用这个; -> 💿 学习项目 +> 学习项目 - [zhontai.net Admin 后台管理系统](https://github.com/zhontai/Admin.Core) - [A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) @@ -190,7 +190,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## 💕 Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88元 > Thank you for your donation From d55d7a5374f2cd904c9937f5de004f60d4e08cd2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 27 Apr 2020 21:53:38 +0800 Subject: [PATCH 0613/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20non=20public?= =?UTF-8?q?=20ctor=20#291?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 26 +++++++++++++++++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- readme.md | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 0470c0f1..e77bb1b4 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -135,9 +135,35 @@ namespace FreeSql.Tests [Column(Name = "EDII_EDI_ID")] public long EdiId { get; set; } } + public class Song123 + { + public long Id { get; set; } + protected Song123() { } + public Song123(long id) => Id = id; + } + public class Author123 + { + public long Id { get; set; } + public long SongId { get; set; } + public Author123(long id, long songId) + { + Id = id; + SongId = songId; + } + } + [Fact] public void Test03() { + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Insert(new Song123(1)).ExecuteAffrows(); + g.sqlite.Insert(new Author123(11, 1)).ExecuteAffrows(); + var song = g.sqlite.Select() + .From((a, b) => a.InnerJoin(a1 => a1.Id == b.SongId)) + .First((a, b) => a); // throw error + Console.WriteLine(song == null); + g.sqlite.Select().ToList(); var itemId2 = 2; diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index c787b5eb..ae4c5929 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -130,7 +130,7 @@ public static partial class FreeSqlGlobalExtensions if (that == typeof(string)) return default(string); if (that.IsArray) return Array.CreateInstance(that, 0); var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters(); - if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, null); + if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, true); return Activator.CreateInstance(that, ctorParms.Select(a => a.ParameterType.IsInterface || a.ParameterType.IsAbstract || a.ParameterType == typeof(string) ? null : Activator.CreateInstance(a.ParameterType, null)).ToArray()); } internal static NewExpression InternalNewExpression(this Type that) diff --git a/readme.md b/readme.md index 8b8901fb..8a7fd57e 100644 --- a/readme.md +++ b/readme.md @@ -190,7 +190,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## 💕 Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元 > Thank you for your donation From f39a4cb77807bfa04f41c5a2fbecd23f47b0e39d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 28 Apr 2020 10:51:38 +0800 Subject: [PATCH 0614/1029] update tests --- FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 0797327d..3804be96 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -429,6 +429,7 @@ namespace FreeSql.Tests repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; //򿪼湦 repo.Insert(cts); + var notreelist1 = repo.Select.ToList(); var treelist1 = repo.Select.ToTreeList(); //repo.SaveMany(cts[0], "Childs"); //ָ Childs һԶ From 0ffea2b871caf181471ebf7cf10459d9d7b2547f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 30 Apr 2020 12:06:19 +0800 Subject: [PATCH 0615/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E6=B5=AE?= =?UTF-8?q?=E7=82=B9=E7=B1=BB=E5=9E=8B=20NoneParameter=20=E4=B8=8D?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=A7=91=E5=AD=A6=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 6 ++++++ Providers/FreeSql.Provider.Dameng/DamengUtils.cs | 2 ++ Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs | 2 ++ Providers/FreeSql.Provider.MySql/MySqlUtils.cs | 2 ++ .../MySqlConnectorUtils.cs | 2 ++ .../FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs | 2 ++ Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs | 2 ++ Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs | 2 ++ .../FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs | 2 ++ .../PostgreSQL/OdbcPostgreSQLUtils.cs | 2 ++ .../SqlServer/OdbcSqlServerUtils.cs | 2 ++ Providers/FreeSql.Provider.Oracle/OracleUtils.cs | 2 ++ Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs | 2 ++ Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs | 2 ++ Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs | 2 ++ 16 files changed, 34 insertions(+), 9 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,14 +486,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index d300dc9c..2c5357c4 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -675,6 +675,12 @@ namespace FreeSql.Tests subquery = g.sqlite.Select().Where(b => b.Id == a.Id).First(b => b.Group) }); + var sklgjlskdg12 = g.sqlite.Select() + .Where(a => g.sqlite.Select().Any(b => b.MemberId == a.MemberId)) + .ToUpdate() + .Set(a => a.Phone, "123123") + .ToSql(); + var sklgjlskdg = g.sqlite.Select() .Where(a => a.CheckupGroups.AsSelect().Any()) .ToSql(); diff --git a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs index e6c67977..2044411d 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs @@ -4,6 +4,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data.Common; +using System.Globalization; namespace FreeSql.Dameng { @@ -95,6 +96,7 @@ namespace FreeSql.Dameng public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; return FormatSql("{0}", value, 1); } diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs index 31c9b7a1..2002a9a9 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.OleDb; +using System.Globalization; using System.Text; namespace FreeSql.MsAccess @@ -84,6 +85,7 @@ namespace FreeSql.MsAccess public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 3da98012..fdce7b48 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -4,6 +4,7 @@ using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data.Common; +using System.Globalization; namespace FreeSql.MySql { @@ -124,6 +125,7 @@ namespace FreeSql.MySql public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 83032db7..3cf35322 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.Data.Common; +using System.Globalization; namespace FreeSql.MySql { @@ -148,6 +149,7 @@ namespace FreeSql.MySql public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index dd066373..7e619a96 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; +using System.Globalization; namespace FreeSql.Odbc.Dameng { @@ -101,6 +102,7 @@ namespace FreeSql.Odbc.Dameng public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; return FormatSql("{0}", value, 1); } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index c3a64399..b9eb9dad 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; +using System.Globalization; namespace FreeSql.Odbc.Default { @@ -71,6 +72,7 @@ namespace FreeSql.Odbc.Default public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return Adapter.ByteRawSql(value); return FormatSql("{0}", value, 1); } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 50f45dbf..3cd1bb86 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; +using System.Globalization; namespace FreeSql.Odbc.MySql { @@ -95,6 +96,7 @@ namespace FreeSql.Odbc.MySql public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index 9054c31b..e692fac8 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; +using System.Globalization; namespace FreeSql.Odbc.Oracle { @@ -101,6 +102,7 @@ namespace FreeSql.Odbc.Oracle public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; return FormatSql("{0}", value, 1); } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 7fab4eda..9b582199 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; +using System.Globalization; using System.Linq; using System.Text; @@ -124,6 +125,7 @@ namespace FreeSql.Odbc.PostgreSQL public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); value = getParamterValue(type, value); var type2 = value.GetType(); if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index adfa99ab..118fcf69 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Odbc; +using System.Globalization; using System.Text; namespace FreeSql.Odbc.SqlServer @@ -87,6 +88,7 @@ namespace FreeSql.Odbc.SqlServer public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 6f2ce884..868db830 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -4,6 +4,7 @@ using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Generic; using System.Data.Common; +using System.Globalization; namespace FreeSql.Oracle { @@ -100,6 +101,7 @@ namespace FreeSql.Oracle public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; return FormatSql("{0}", value, 1); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 2781ae1b..cc345caa 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -9,6 +9,7 @@ using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.Common; +using System.Globalization; using System.Linq; using System.Net; using System.Text; @@ -154,6 +155,7 @@ namespace FreeSql.PostgreSQL public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (_dicIsAssignableFromPostgisGeometry.GetOrAdd(type, t2 => typeof(PostgisGeometry).IsAssignableFrom(type.IsArray ? type.GetElementType() : type))) { var pam = AppendParamter(specialParams, null, null, type, value); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 748ebf00..125b62e5 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.SqlClient; +using System.Globalization; using System.Text; namespace FreeSql.SqlServer @@ -99,6 +100,7 @@ namespace FreeSql.SqlServer public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) { diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 41ba2433..9f092837 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.SQLite; +using System.Globalization; namespace FreeSql.Sqlite { @@ -100,6 +101,7 @@ namespace FreeSql.Sqlite public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) { if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); return FormatSql("{0}", value, 1); } } From bae0f1c63ed0aea630cc121a3ebb702fedc51412 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 1 May 2020 06:41:58 +0800 Subject: [PATCH 0616/1029] update UnitOfWorkManager demo --- .../Controllers/HomeController.cs | 34 +++++++++++++++++-- Examples/aspnetcore_transaction/Startup.cs | 3 ++ .../aspnetcore_transaction.csproj | 2 +- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Examples/aspnetcore_transaction/Controllers/HomeController.cs b/Examples/aspnetcore_transaction/Controllers/HomeController.cs index d3fe0d1c..84d6a317 100644 --- a/Examples/aspnetcore_transaction/Controllers/HomeController.cs +++ b/Examples/aspnetcore_transaction/Controllers/HomeController.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using System.Threading.Tasks; namespace aspnetcore_transaction.Controllers { @@ -16,12 +17,22 @@ namespace aspnetcore_transaction.Controllers _logger = logger; } - [HttpGet] + [HttpGet("1")] //[Transactional] virtual public object Get([FromServices] BaseRepository repoSong, [FromServices] BaseRepository repoDetail, [FromServices] SongRepository repoSong2, [FromServices] SongService serviceSong) { - serviceSong.Test(); + serviceSong.Test1(); + return "111"; + } + + [HttpGet("2")] + //[Transactional] + async virtual public Task GetAsync([FromServices] BaseRepository repoSong, [FromServices] BaseRepository repoDetail, [FromServices] SongRepository repoSong2, + [FromServices] SongService serviceSong) + { + await serviceSong.Test2(); + await serviceSong.Test3(); return "111"; } } @@ -40,12 +51,29 @@ namespace aspnetcore_transaction.Controllers } [Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的 - public virtual void Test() + public virtual void Test1() { _repoSong.Insert(new Song()); _repoDetail.Insert(new Detail()); _repoSong2.Insert(new Song()); } + + [Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的 + async public virtual Task Test2() + { + await _repoSong.InsertAsync(new Song()); + await _repoDetail.InsertAsync(new Detail()); + await _repoSong2.InsertAsync(new Song()); + } + + [Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的 + async public virtual Task Test3() + { + await _repoSong.InsertAsync(new Song()); + await _repoDetail.InsertAsync(new Detail()); + await _repoSong2.InsertAsync(new Song()); + return "123"; + } } public class SongRepository : DefaultRepository diff --git a/Examples/aspnetcore_transaction/Startup.cs b/Examples/aspnetcore_transaction/Startup.cs index 67727f65..33903efa 100644 --- a/Examples/aspnetcore_transaction/Startup.cs +++ b/Examples/aspnetcore_transaction/Startup.cs @@ -28,6 +28,9 @@ namespace aspnetcore_transaction .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) .UseNoneCommandParameter(true) .Build(); + + Fsql.Aop.TraceBefore += (_, e) => Trace.WriteLine($"----TraceBefore---{e.Identifier} {e.Operation}"); + Fsql.Aop.TraceAfter += (_, e) => Trace.WriteLine($"----TraceAfter---{e.Identifier} {e.Operation} {e.Remark} {e.Exception?.Message} {e.ElapsedMilliseconds}ms\r\n"); } public IConfiguration Configuration { get; } diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj index 1ff5ec53..16c8e28f 100644 --- a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj @@ -5,7 +5,7 @@ - + From d24969d9b1585648d031d697118fbb776b86c3ea Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 1 May 2020 08:31:45 +0800 Subject: [PATCH 0617/1029] update BseRepository virtual dim --- FreeSql.DbContext/Repository/Repository/BaseRepository.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index a0d55e77..2f78dd05 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -72,9 +72,9 @@ namespace FreeSql } public IUpdate UpdateDiy => _dbset.OrmUpdateInternal(null); - public ISelect Select => _dbset.OrmSelectInternal(null); - public ISelect Where(Expression> exp) => _dbset.OrmSelectInternal(null).Where(exp); - public ISelect WhereIf(bool condition, Expression> exp) => _dbset.OrmSelectInternal(null).WhereIf(condition, exp); + public virtual ISelect Select => _dbset.OrmSelectInternal(null); + public ISelect Where(Expression> exp) => Select.Where(exp); + public ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); public virtual int Delete(Expression> predicate) { @@ -160,7 +160,7 @@ namespace FreeSql } public virtual int Delete(TKey id) => Delete(CheckTKeyAndReturnIdEntity(id)); - public virtual TEntity Find(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); + public virtual TEntity Find(TKey id) => Select.WhereDynamic(CheckTKeyAndReturnIdEntity(id)).ToOne(); public TEntity Get(TKey id) => Find(id); } } From 1e83a7eeaad281dfc6a74363504ce4b3b91366a0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 2 May 2020 11:17:59 +0800 Subject: [PATCH 0618/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20WhereCascade?= =?UTF-8?q?/GlobalFilter=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=AD=90=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 2 +- FreeSql/Internal/CommonExpression.cs | 15 +++++++++------ FreeSql/Internal/GlobalFilter.cs | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 8acbdf71..7f0d97fc 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -279,7 +279,7 @@ namespace FreeSql.Tests kwrepo.Insert(u1); - g.sqlite.GlobalFilter.Apply("gft1", a => a.rowstate > -1) + g.sqlite.GlobalFilter.Apply("gft1", a => a.rowstate > -1 && g.sqlite.Select().Any(b => b.id == a.id)) .Apply("gft2", a => a.rowstate > -2) .Apply("gft3", a => a.rowstate > -3); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b3dd4523..8bb2196e 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1438,7 +1438,8 @@ namespace FreeSql.Internal { if (_whereCascadeExpression.Any()) { - var newParameter = Expression.Parameter(tb.Table.Type, "c"); + var newParameter = Expression.Parameter(tb.Table.Type, tb.Alias); + tb.Parameter = newParameter; var sb = new StringBuilder(); var isEmpty = true; @@ -1452,10 +1453,10 @@ namespace FreeSql.Internal { var expExp = Expression.Lambda( typeof(Func<,>).MakeGenericType(tb.Table.Type, typeof(bool)), - new ReplaceVisitor().Modify(fl.Body, newParameter), + new ReplaceVisitor().Modify(fl, newParameter), newParameter ); - var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = null, _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = new List(new[] { tb }), _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); whereSql = GetBoolString(expExp.Body, whereSql); if (isEmpty == false) sb.Append(" AND "); @@ -1478,14 +1479,16 @@ namespace FreeSql.Internal internal class ReplaceVisitor : ExpressionVisitor { private ParameterExpression parameter; - public Expression Modify(Expression expression, ParameterExpression parameter) + private ParameterExpression oldParameter; + public Expression Modify(LambdaExpression lambda, ParameterExpression parameter) { this.parameter = parameter; - return Visit(expression); + this.oldParameter = lambda.Parameters.FirstOrDefault(); + return Visit(lambda.Body); } protected override Expression VisitMember(MemberExpression node) { - if (node.Expression?.NodeType == ExpressionType.Parameter) + if (node.Expression?.NodeType == ExpressionType.Parameter && node.Expression == oldParameter) return Expression.Property(parameter, node.Member.Name); return base.VisitMember(node); } diff --git a/FreeSql/Internal/GlobalFilter.cs b/FreeSql/Internal/GlobalFilter.cs index 01992c9f..f0250d8b 100644 --- a/FreeSql/Internal/GlobalFilter.cs +++ b/FreeSql/Internal/GlobalFilter.cs @@ -35,7 +35,7 @@ namespace FreeSql.Internal var newParameter = Expression.Parameter(typeof(TEntity), $"gf{_id}"); var newlambda = Expression.Lambda>( - new CommonExpression.ReplaceVisitor().Modify(where.Body, newParameter), + new CommonExpression.ReplaceVisitor().Modify(where, newParameter), newParameter ); item.Where = newlambda; From 5096bbc36789ecd418a2d6c3e1e2e9c3dc69a892 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 2 May 2020 11:33:55 +0800 Subject: [PATCH 0619/1029] v1.5.0-preview0502 #291 --- .../FreeSql.Extensions.BaseEntity.csproj | 4 ++-- .../FreeSql.Extensions.JsonMap.csproj | 4 ++-- .../FreeSql.Extensions.LazyLoading.csproj | 4 ++-- .../FreeSql.Extensions.Linq.csproj | 4 ++-- .../FreeSql.Generator/FreeSql.Generator.csproj | 4 ++-- FreeSql.All/FreeSql.All.csproj | 4 ++-- FreeSql.DbContext/FreeSql.DbContext.csproj | 4 ++-- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 4 ++-- FreeSql/FreeSql.csproj | 4 ++-- .../FreeSql.Provider.Dameng.csproj | 4 ++-- .../FreeSql.Provider.MsAccess.csproj | 4 ++-- .../FreeSql.Provider.MySql.csproj | 4 ++-- .../FreeSql.Provider.MySqlConnector.csproj | 4 ++-- .../FreeSql.Provider.Odbc.csproj | 4 ++-- .../FreeSql.Provider.Oracle.csproj | 4 ++-- .../FreeSql.Provider.PostgreSQL.csproj | 4 ++-- .../FreeSql.Provider.SqlServer.csproj | 4 ++-- .../FreeSql.Provider.Sqlite.csproj | 4 ++-- 19 files changed, 36 insertions(+), 52 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 2bfc27d1..545e0928 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,9 +2,9 @@ netcoreapp31;netcoreapp21;net4.0; - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ef15934c..e47ac2dd 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 86940a73..323555ec 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,9 +2,9 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 6bd7c2cb..e7d2d17c 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 499dc514..b837d595 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -6,13 +6,13 @@ true true true - 2881099 + ncc;YeXiangQin 2881099 FreeSql 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.4.0 + 1.5.0-preview0502 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index d25e5f07..f483e289 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 全家桶,懒人专用 https://github.com/2881099/FreeSql.DbContext FreeSql ORM DbContext diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 5f7e4168..36dad567 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,9 +2,9 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access https://github.com/2881099/FreeSql/wiki/DbContext FreeSql ORM DbContext 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.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0024a9b2..9882f607 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,8 +2,8 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.4.0 - YeXiangQin + 1.5.0-preview0502 + ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 50207287..7f13820f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 8e3b478b..7856ea69 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 485d7616..e12c1314 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index fd7c010e..c977f01a 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,9 +2,9 @@ netstandard2.0;net452;net451;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fc6f8268..aaa503e1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 1e5611d7..7cf523e6 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 76059896..8f95e8b2 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f4f9c3a6..8decdb05 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,9 +2,9 @@ netstandard2.0;net461;net452;net451;net45 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 7612e19c..5c4383d4 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,9 +2,9 @@ netstandard2.0;net451;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 1169859d..9b851084 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,9 +2,9 @@ netstandard2.0;net45;net40 - 1.4.0 + 1.5.0-preview0502 true - YeXiangQin + ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql From 9b77dfe5485b13ebe69b92531f676a9c7ef260dd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 2 May 2020 21:27:44 +0800 Subject: [PATCH 0620/1029] update Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 8a7fd57e..bc23703d 100644 --- a/readme.md +++ b/readme.md @@ -190,7 +190,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## 💕 Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元 > Thank you for your donation From 9f2843e8e30d9c9ff1375a1be403016ac65199a3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 3 May 2020 11:12:32 +0800 Subject: [PATCH 0621/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Column(Serve?= =?UTF-8?q?rTime=3Dxxx)=20MySql=20=E4=B8=8B=E6=97=A0=E6=B3=95=E4=BF=9D?= =?UTF-8?q?=E7=95=99=E7=B2=BE=E5=BA=A6=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/UtilsExpressionTree.cs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 5ea91584..debd9d0f 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -193,9 +193,25 @@ namespace FreeSql.Internal //} if (colattr.ServerTime != DateTimeKind.Unspecified && new[] { typeof(DateTime), typeof(DateTimeOffset) }.Contains(colattr.MapType.NullableTypeOrThis())) { - col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; - col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; - col.DbUpdateValue = colattr.ServerTime == DateTimeKind.Local ? common.Now : common.NowUtc; + var commonNow = common.Now; + var commonNowUtc = common.NowUtc; + switch (common._orm.Ado.DataType) + { + case DataType.MySql: + case DataType.OdbcMySql: //处理毫秒 + var timeLength = 0; + var mTimeLength = Regex.Match(colattr.DbType, @"(DATETIME|TIMESTAMP)\s*\((\d+)\)"); + if (mTimeLength.Success) timeLength = int.Parse(mTimeLength.Groups[2].Value); + if (timeLength > 0 && timeLength < 7) + { + commonNow = $"{commonNow.TrimEnd('(', ')')}({timeLength})"; + commonNowUtc = $"{commonNowUtc.TrimEnd('(', ')')}({timeLength})"; + } + break; + } + col.DbDefaultValue = colattr.ServerTime == DateTimeKind.Local ? commonNow : commonNowUtc; + col.DbInsertValue = colattr.ServerTime == DateTimeKind.Local ? commonNow : commonNowUtc; + col.DbUpdateValue = colattr.ServerTime == DateTimeKind.Local ? commonNow : commonNowUtc; } if (string.IsNullOrEmpty(colattr.InsertValueSql) == false) { From ae11f552fa5504005d0dc1a64b558fc158029b1c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 5 May 2020 19:28:08 +0800 Subject: [PATCH 0622/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect.ToDa?= =?UTF-8?q?taTable(lambda)=20=E6=9C=AA=E4=BD=BF=E7=94=A8=20AsProperty=20?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=95=B0=E6=8D=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/CommonProvider/SelectProvider/Select0Provider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 95ad2cc5..9563ae68 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1122,7 +1122,7 @@ namespace FreeSql.Internal.CommonProvider protected DataTable InternalToDataTable(Expression select) { - var sql = this.InternalToSql(select); + var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -1402,7 +1402,7 @@ namespace FreeSql.Internal.CommonProvider async protected Task InternalToDataTableAsync(Expression select) { - var sql = this.InternalToSql(select); + var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); From 60bb29b19f6d558fe610a528538d2df37254d809 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 May 2020 11:00:55 +0800 Subject: [PATCH 0623/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20[Description?= =?UTF-8?q?]=20=E5=85=83=E6=95=B0=E6=8D=AE=E6=B3=A8=E9=87=8A=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E4=BD=8E=E4=BA=8E=20c#=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=B3=A8=E9=87=8A=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/HomeController.cs | 7 +++ .../aspnetcore_transaction.csproj | 4 ++ .../aspnetcore_transaction.xml | 18 ++++++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 2 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 2 +- FreeSql/FreeSql.xml | 7 +++ FreeSql/Internal/CommonUtils.cs | 44 +++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 6 +++ 8 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 Examples/aspnetcore_transaction/aspnetcore_transaction.xml diff --git a/Examples/aspnetcore_transaction/Controllers/HomeController.cs b/Examples/aspnetcore_transaction/Controllers/HomeController.cs index 84d6a317..35129473 100644 --- a/Examples/aspnetcore_transaction/Controllers/HomeController.cs +++ b/Examples/aspnetcore_transaction/Controllers/HomeController.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using System.ComponentModel; using System.Threading.Tasks; namespace aspnetcore_transaction.Controllers @@ -45,6 +46,7 @@ namespace aspnetcore_transaction.Controllers public SongService(BaseRepository repoSong, BaseRepository repoDetail, SongRepository repoSong2) { + var tb = repoSong.Orm.CodeFirst.GetTableByEntity(typeof(Song)); _repoSong = repoSong; _repoDetail = repoDetail; _repoSong2 = repoSong2; @@ -81,9 +83,14 @@ namespace aspnetcore_transaction.Controllers public SongRepository(UnitOfWorkManager uowm) : base(uowm?.Orm, uowm) { } } + [Description("123")] public class Song { + /// + /// 自增 + /// [Column(IsIdentity = true)] + [Description("自增id")] public int Id { get; set; } public string Title { get; set; } } diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj index 16c8e28f..cecd9f4b 100644 --- a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj @@ -4,6 +4,10 @@ netcoreapp3.1 + + aspnetcore_transaction.xml + + diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.xml b/Examples/aspnetcore_transaction/aspnetcore_transaction.xml new file mode 100644 index 00000000..8d78a341 --- /dev/null +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.xml @@ -0,0 +1,18 @@ + + + + aspnetcore_transaction + + + + + 自增 + + + + + 使用事务执行,请查看 Program.cs 代码开启动态代理 + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index c46c8307..f0e048a1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -128,7 +128,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var dt1 = select.Limit(10).ToDataTable(); var dt2 = select.Limit(10).ToDataTable("id, 222"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + var dt3 = select.Limit(10).ToDataTable(a => new { id = a.Id, name2 = a.Type.Name, now = DateTime.Now }); } class TestDto { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index c46c8779..db9854e2 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -128,7 +128,7 @@ namespace FreeSql.Tests.PostgreSQL var dt1 = select.Limit(10).ToDataTable(); var dt2 = select.Limit(10).ToDataTable("id, 222"); - var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + var dt3 = select.Limit(10).ToDataTable(a => new { id = a.Id, name2 = a.Type.Name, now = DateTime.Now }); } class TestDto { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d6b6f1a8..74a353d9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2901,6 +2901,13 @@ AsType, Ctor, ClearData 三处地方需要重新加载 + + + 动态读取 DescriptionAttribute 注释文本 + + + + 通过属性的注释文本,通过 xml 读取 diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 9e8a337c..ef10b55a 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -371,6 +371,48 @@ namespace FreeSql.Internal return iidx == 1 ? sb.Remove(0, 5).Remove(sb.Length - 1, 1).ToString() : sb.Remove(0, 4).ToString(); } + /// + /// 动态读取 DescriptionAttribute 注释文本 + /// + /// + /// + public static Dictionary GetPropertyCommentByDescriptionAttribute(Type type) + { + var dic = new Dictionary(); + GetDydesc(null); //class注释 + + var props = type.GetPropertiesDictIgnoreCase().Values; + foreach (var prop in props) + GetDydesc(prop); + + return dic; + + void GetDydesc(PropertyInfo prop) + { + object[] attrs = null; + try + { + attrs = prop == null ? + type.GetCustomAttributes(false).ToArray() : + prop.GetCustomAttributes(false).ToArray(); //.net core 反射存在版本冲突问题,导致该方法异常 + } + catch { } + + var dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.Name == "DescriptionAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + var valueProp = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string)).FirstOrDefault(); + var comment = valueProp?.GetValue(dyattr, null)?.ToString(); + if (string.IsNullOrEmpty(comment) == false) + dic.Add(prop == null ? + "" : + prop.Name, comment); + } + } + } + /// /// 通过属性的注释文本,通过 xml 读取 /// @@ -378,6 +420,8 @@ namespace FreeSql.Internal /// Dict:key=属性名,value=注释 public static Dictionary GetProperyCommentBySummary(Type type) { + if (type.Assembly.IsDynamic) return null; + //动态生成的程序集,访问不了 Assembly.Location/Assembly.CodeBase var regex = new Regex(@"\.(dll|exe)", RegexOptions.IgnoreCase); var xmlPath = regex.Replace(type.Assembly.Location, ".xml"); if (File.Exists(xmlPath) == false) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index debd9d0f..3d7401d3 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -69,7 +69,10 @@ namespace FreeSql.Internal var propsLazy = new List>(); var propsNavObjs = new List(); var propsComment = CommonUtils.GetProperyCommentBySummary(entity); + var propsCommentByDescAttr = CommonUtils.GetPropertyCommentByDescriptionAttribute(entity); trytb.Comment = propsComment != null && propsComment.TryGetValue("", out var tbcomment) ? tbcomment : ""; + if (string.IsNullOrEmpty(trytb.Comment) && propsCommentByDescAttr != null && propsCommentByDescAttr.TryGetValue("", out tbcomment)) trytb.Comment = tbcomment; + var columnsList = new List(); foreach (var p in trytb.Properties.Values) { @@ -148,6 +151,9 @@ namespace FreeSql.Internal }; if (propsComment != null && propsComment.TryGetValue(p.Name, out var trycomment)) col.Comment = trycomment; + if (string.IsNullOrEmpty(col.Comment) && propsCommentByDescAttr != null && propsCommentByDescAttr.TryGetValue(p.Name, out trycomment)) + col.Comment = trycomment; + if (colattr.IsIgnore) { trytb.ColumnsByCsIgnore.Add(p.Name, col); From 5edf8b3dcf93272e322fde8e8abe76285ebe5ab0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 May 2020 11:02:35 +0800 Subject: [PATCH 0624/1029] v1.5.0-preview0507 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 306 ++++++++++-------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 181 insertions(+), 161 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 545e0928..6527b47d 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e47ac2dd..f08d6988 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 323555ec..258e315e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index e7d2d17c..4ed1cb97 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index b837d595..6913bb63 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0-preview0502 + 1.5.0-preview0507 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index f483e289..7e29422f 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 36dad567..a83618bd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 9882f607..d59c4c0c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7f13820f..b508dc7e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 74a353d9..1e5c8e71 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2310,137 +2310,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -2968,12 +2837,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3044,12 +2907,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3682,4 +3539,167 @@ + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态对象如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + + 事务体 () => {} + + + + 开启事务(不支持异步) + + 超时,未执行完成(可能)被其他线程事务自动提交 + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + 超时,未执行完成(可能)被其他线程事务自动提交 + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 7856ea69..497bbada 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index e12c1314..46043706 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c977f01a..b6102ce7 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index aaa503e1..1c548b15 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 7cf523e6..d1039bc9 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8f95e8b2..78f5c3b6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8decdb05..8f3fb9b4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5c4383d4..b789987d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9b851084..b35cc35d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0502 + 1.5.0-preview0507 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From ebe1b7a34ff44d2d6fece743b0d29c7bd6d00ee8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 May 2020 13:45:25 +0800 Subject: [PATCH 0625/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20Guid=20GetDe?= =?UTF-8?q?faultValue=20=E5=8F=AF=E8=83=BD=E5=AF=BC=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF=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/Extensions/FreeSqlGlobalExtensions.cs | 6 +++++- FreeSql/FreeSql.xml | 20 +++++++++---------- FreeSql/Interface/Curd/IDelete.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 2 +- FreeSql/Interface/Curd/IUpdate.cs | 2 +- FreeSql/Interface/IFreeSql.cs | 6 +++--- 7 files changed, 37 insertions(+), 17 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index ae4c5929..9537f680 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -128,10 +128,14 @@ public static partial class FreeSqlGlobalExtensions { if (that == null) return null; if (that == typeof(string)) return default(string); + if (that == typeof(Guid)) return default(Guid); if (that.IsArray) return Array.CreateInstance(that, 0); var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters(); if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, true); - return Activator.CreateInstance(that, ctorParms.Select(a => a.ParameterType.IsInterface || a.ParameterType.IsAbstract || a.ParameterType == typeof(string) ? null : Activator.CreateInstance(a.ParameterType, null)).ToArray()); + return Activator.CreateInstance(that, ctorParms + .Select(a => a.ParameterType.IsInterface || a.ParameterType.IsAbstract || a.ParameterType == typeof(string) || a.ParameterType.IsArray ? + null : + Activator.CreateInstance(a.ParameterType, null)).ToArray()); } internal static NewExpression InternalNewExpression(this Type that) { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1e5c8e71..eb7bd92e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -824,7 +824,7 @@ - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 是否标识为NOT @@ -1662,7 +1662,7 @@ - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 是否标识为NOT @@ -2077,7 +2077,7 @@ - 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 是否标识为NOT @@ -3456,7 +3456,7 @@ - 修改数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -3471,7 +3471,7 @@ - 查询数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -3486,7 +3486,7 @@ - 删除数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -3540,7 +3540,7 @@ - + @@ -3619,7 +3619,7 @@ - 修改数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -3634,7 +3634,7 @@ - 查询数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -3649,7 +3649,7 @@ - 删除数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 0cf9f699..deab6936 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -49,7 +49,7 @@ namespace FreeSql /// IDelete Where(IEnumerable items); /// - /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// 是否标识为NOT diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 859b48aa..acf1bcf3 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -292,7 +292,7 @@ namespace FreeSql /// ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class where T5 : class; /// - /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// 是否标识为NOT diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 6922dadd..41a8758b 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -147,7 +147,7 @@ namespace FreeSql /// IUpdate Where(IEnumerable items); /// - /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// 是否标识为NOT diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index 19064fd0..2709de31 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -51,7 +51,7 @@ public interface IFreeSql : IDisposable /// IUpdate Update() where T1 : class; /// - /// 修改数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -65,7 +65,7 @@ public interface IFreeSql : IDisposable /// ISelect Select() where T1 : class; /// - /// 查询数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -79,7 +79,7 @@ public interface IFreeSql : IDisposable /// IDelete Delete() where T1 : class; /// - /// 删除数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 From e3dba006cf50d0e328e613e102aa1e581eb9882d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 May 2020 22:54:16 +0800 Subject: [PATCH 0626/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.Wher?= =?UTF-8?q?eDynamicFilter=20=E6=96=B9=E6=B3=95=E5=AE=9E=E7=8E=B0=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E8=BF=87=E6=BB=A4=E6=9D=A1=E4=BB=B6=EF=BC=88=E4=B8=8E?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E4=BA=A4=E4=BA=92=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 38 ++ .../Sqlite/Curd/SqliteSelectTest.cs | 102 +++++ FreeSql/FreeSql.xml | 381 ++++++++++-------- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 10 +- .../SelectProvider/Select0Provider.cs | 105 +++++ FreeSql/Internal/Model/DynamicFilterInfo.cs | 84 ++++ 6 files changed, 556 insertions(+), 164 deletions(-) create mode 100644 FreeSql/Internal/Model/DynamicFilterInfo.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index e800ef21..c1440834 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -1,6 +1,7 @@ using FreeSql; using FreeSql.DataAnnotations; using FreeSql.Extensions; +using FreeSql.Internal.Model; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; @@ -87,6 +88,43 @@ namespace base_entity new Products { title = "product-4" }.Save(); new Products { title = "product-5" }.Save(); + Products.Select.WhereDynamicFilter(JsonConvert.DeserializeObject(@" +{ + ""Logic"" : ""Or"", + ""Filters"" : + [ + { + ""Field"" : ""title"", + ""Operator"" : ""eq"", + ""Value"" : ""product-1"", + ""Filters"" : + [ + { + ""Field"" : ""title"", + ""Operator"" : ""contains"", + ""Value"" : ""product-1111"", + } + ] + }, + { + ""Field"" : ""title"", + ""Operator"" : ""eq"", + ""Value"" : ""product-2"" + }, + { + ""Field"" : ""title"", + ""Operator"" : ""eq"", + ""Value"" : ""product-3"" + }, + { + ""Field"" : ""title"", + ""Operator"" : ""eq"", + ""Value"" : ""product-4"" + }, + ] +} +")).ToList(); + var items1 = Products.Select.Limit(10).OrderByDescending(a => a.CreateTime).ToList(); var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 8d1b715c..0f011db3 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1,4 +1,6 @@ using FreeSql.DataAnnotations; +using FreeSql.Internal.Model; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -1931,5 +1933,105 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" [Navigate(nameof(ParentCode))] public VM_District_Parent Parent { get; set; } } + + [Fact] + public void WhereDynamicFilter() + { + var fsql = g.sqlite; + var sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" +{ + ""Logic"" : ""Or"", + ""Filters"" : + [ + { + ""Field"" : ""Code"", + ""Operator"" : ""Contains"", + ""Value"" : ""val1"", + ""Filters"" : + [ + { + ""Field"" : ""Name"", + ""Operator"" : ""StartsWith"", + ""Value"" : ""val2"", + } + ] + }, + { + ""Field"" : ""Name"", + ""Operator"" : ""EndsWith"", + ""Value"" : ""val3"" + }, + { + ""Field"" : ""ParentCode"", + ""Operator"" : ""Equals"", + ""Value"" : ""val4"" + } + ] +} +")).ToSql(); + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""ParentCode"" +FROM ""D_District"" a +WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") LIKE '%val3' OR a.""ParentCode"" = 'val4'))", sql); + + sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" +{ + ""Logic"" : ""Or"", + ""Filters"" : + [ + { + ""Field"" : ""Code"", + ""Operator"" : ""NotContains"", + ""Value"" : ""val1"", + ""Filters"" : + [ + { + ""Field"" : ""Name"", + ""Operator"" : ""NotStartsWith"", + ""Value"" : ""val2"", + } + ] + }, + { + ""Field"" : ""Name"", + ""Operator"" : ""NotEndsWith"", + ""Value"" : ""val3"" + }, + { + ""Field"" : ""ParentCode"", + ""Operator"" : ""NotEqual"", + ""Value"" : ""val4"" + }, + + { + ""Field"" : ""Parent.Code"", + ""Operator"" : ""eq"", + ""Value"" : ""val11"", + ""Filters"" : + [ + { + ""Field"" : ""Parent.Name"", + ""Operator"" : ""contains"", + ""Value"" : ""val22"", + } + ] + }, + { + ""Field"" : ""Parent.Name"", + ""Operator"" : ""eq"", + ""Value"" : ""val33"" + }, + { + ""Field"" : ""Parent.ParentCode"", + ""Operator"" : ""eq"", + ""Value"" : ""val44"" + } + ] +} +")).ToSql(); + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""ParentCode"", a__Parent.""Code"" as4, a__Parent.""Name"" as5, a__Parent.""ParentCode"" as6 +FROM ""D_District"" a +LEFT JOIN ""D_District"" a__Parent ON a__Parent.""Code"" = a.""ParentCode"" +WHERE ((not((a.""Code"") LIKE '%val1%') AND not((a.""Name"") LIKE 'val2%') OR not((a.""Name"") LIKE '%val3') OR a.""ParentCode"" <> 'val4' OR a__Parent.""Code"" = 'val11' AND (a__Parent.""Name"") LIKE '%val22%' OR a__Parent.""Name"" = 'val33' OR a__Parent.""ParentCode"" = 'val44'))", sql); + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index eb7bd92e..295cad26 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1276,6 +1276,13 @@ 参数 + + + 动态过滤条件 + + + + 禁用全局过滤功能,不传参数时将禁用所有 @@ -2310,6 +2317,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 }) + + + + + + 可自定义解析表达式 @@ -2793,6 +2931,74 @@ 表达式 + + + 动态过滤条件 + + + + + 属性名:Name + 导航属性:Parent.Name + 多表:b.Name + + + + + 操作符 + + + + + 值 + + + + + Filters 下的逻辑运算符 + + + + + 子过滤条件,它与当前的逻辑关系是 And + 注意:当前 Field 可以留空 + + + + + like + + + + + = + + + + + <> + + + + + > + + + + + >= + + + + + < + + + + + <= + + 中间表,多对多 @@ -2837,6 +3043,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -2907,6 +3119,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3539,167 +3757,4 @@ - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态条件,如:主键值 | 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index ca52d7c2..7a5d6713 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -261,6 +262,13 @@ namespace FreeSql /// TSelect WhereIf(bool condition, string sql, object parms = null); + /// + /// 动态过滤条件 + /// + /// + /// + TSelect WhereDynamicFilter(DynamicFilterInfo filter); + /// /// 禁用全局过滤功能,不传参数时将禁用所有 /// diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 9563ae68..42af114d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1025,6 +1025,111 @@ namespace FreeSql.Internal.CommonProvider if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); return this as TSelect; } + + static MethodInfo MethodStringContains = typeof(string).GetMethod("Contains", new[] { typeof(string) }); + static MethodInfo MethodStringStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); + static MethodInfo MethodStringEndsWith = typeof(string).GetMethod("EndsWith", new[] { typeof(string) }); + public TSelect WhereDynamicFilter(DynamicFilterInfo filter) + { + if (filter == null) return this as TSelect; + var sb = new StringBuilder(); + ParseFilter(DynamicFilterLogic.And, filter, true); + this.Where(sb.ToString()); + sb.Clear(); + return this as TSelect; + + void ParseFilter(DynamicFilterLogic logic, DynamicFilterInfo fi, bool isend) + { + if (string.IsNullOrEmpty(fi.Field) == false) + { + var field = fi.Field.Split('.').Select(a => a.Trim()).ToArray(); + Expression exp = null; + + if (field.Length == 1) + { + foreach (var tb in _tables) + { + if (tb.Table.ColumnsByCs.TryGetValue(field[0], out var col) && + tb.Table.Properties.TryGetValue(field[0], out var prop)) + { + tb.Parameter = Expression.Parameter(tb.Table.Type, tb.Alias); + exp = Expression.MakeMemberAccess(tb.Parameter, prop); + break; + } + } + if (exp == null) throw new Exception($"无法匹配 {fi.Field}"); + } + else + { + var firstTb = _tables[0]; + var firstTbs = _tables.Where(a => a.AliasInit == field[0]).ToArray(); + if (firstTbs.Length == 1) + { + firstTb = firstTbs[0]; + } + + firstTb.Parameter = Expression.Parameter(firstTb.Table.Type, firstTb.Alias); + var currentType = firstTb.Table.Type; + Expression currentExp = firstTb.Parameter; + + for (var x = 0; x < field.Length; x++) + { + var tmp1 = field[x]; + if (_commonUtils.GetTableByEntity(currentType).Properties.TryGetValue(tmp1, out var prop) == false) + throw new ArgumentException($"{currentType.DisplayCsharp()} 无法找到属性名 {tmp1}"); + currentType = prop.PropertyType; + currentExp = Expression.MakeMemberAccess(currentExp, prop); + } + exp = currentExp; + } + + switch (fi.Operator) + { + case DynamicFilterOperator.Contains: exp = Expression.Call(exp, MethodStringContains, Expression.Constant(fi.Value)); break; + case DynamicFilterOperator.StartsWith: exp = Expression.Call(exp, MethodStringStartsWith, Expression.Constant(fi.Value)); break; + case DynamicFilterOperator.EndsWith: exp = Expression.Call(exp, MethodStringEndsWith, Expression.Constant(fi.Value)); break; + case DynamicFilterOperator.NotContains: exp = Expression.Not(Expression.Call(exp, MethodStringContains, Expression.Constant(fi.Value))); break; + case DynamicFilterOperator.NotStartsWith: exp = Expression.Not(Expression.Call(exp, MethodStringStartsWith, Expression.Constant(fi.Value))); break; + case DynamicFilterOperator.NotEndsWith: exp = Expression.Not(Expression.Call(exp, MethodStringEndsWith, Expression.Constant(fi.Value))); break; + + case DynamicFilterOperator.Equals: + case DynamicFilterOperator.Eq: exp = Expression.Equal(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.NotEqual: exp = Expression.NotEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + + case DynamicFilterOperator.GreaterThan: exp = Expression.GreaterThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.GreaterThanOrEqual: exp = Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.LessThan: exp = Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + } + + var sql = _commonExpression.ExpressionWhereLambda(_tables, exp, null, null, _params); + + sb.Append(sql); + } + if (fi.Filters?.Any() == true) + { + if (string.IsNullOrEmpty(fi.Field) == false) + sb.Append(" AND "); + if (fi.Logic == DynamicFilterLogic.Or) sb.Append("("); + for (var x = 0; x < fi.Filters.Count; x++) + ParseFilter(fi.Logic, fi.Filters[x], x == fi.Filters.Count - 1); + if (fi.Logic == DynamicFilterLogic.Or) sb.Append(")"); + } + + if (isend == false) + { + if (string.IsNullOrEmpty(fi.Field) == false || fi.Filters?.Any() == true) + { + switch (filter.Logic) + { + case DynamicFilterLogic.And: sb.Append(" AND "); break; + case DynamicFilterLogic.Or: sb.Append(" OR "); break; + } + } + } + } + } + public TSelect DisableGlobalFilter(params string[] name) { if (_whereGlobalFilter.Any() == false) return this as TSelect; diff --git a/FreeSql/Internal/Model/DynamicFilterInfo.cs b/FreeSql/Internal/Model/DynamicFilterInfo.cs new file mode 100644 index 00000000..81ffc35e --- /dev/null +++ b/FreeSql/Internal/Model/DynamicFilterInfo.cs @@ -0,0 +1,84 @@ +using FreeSql; +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace FreeSql.Internal.Model +{ + /// + /// 动态过滤条件 + /// + public class DynamicFilterInfo + { + /// + /// 属性名:Name + /// 导航属性:Parent.Name + /// 多表:b.Name + /// + public string Field { get; set; } + /// + /// 操作符 + /// + public DynamicFilterOperator Operator { get; set; } + /// + /// 值 + /// + public string Value { get; set; } + + /// + /// Filters 下的逻辑运算符 + /// + public DynamicFilterLogic Logic { get; set; } + /// + /// 子过滤条件,它与当前的逻辑关系是 And + /// 注意:当前 Field 可以留空 + /// + public List Filters { get; set; } + } + + public enum DynamicFilterLogic { And, Or } + public enum DynamicFilterOperator + { + /// + /// like + /// + Contains, + StartsWith, + EndsWith, + NotContains, + NotStartsWith, + NotEndsWith, + + /// + /// = + /// + Equals, + Eq, + /// + /// <> + /// + NotEqual, + + /// + /// > + /// + GreaterThan, + /// + /// >= + /// + GreaterThanOrEqual, + /// + /// < + /// + LessThan, + /// + /// <= + /// + LessThanOrEqual, + } +} From d69db2a3b1b955ffb5aca878197b5037b1dba9b3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 7 May 2020 23:11:50 +0800 Subject: [PATCH 0627/1029] v1.5.0-preview0508 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 13 ++++++++++--- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 28 insertions(+), 21 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6527b47d..4774e842 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index f08d6988..f6925e68 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 258e315e..7e237009 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 4ed1cb97..745467d9 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 6913bb63..fe36ad28 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0-preview0507 + 1.5.0-preview0508 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 7e29422f..35b7fd50 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a83618bd..e6d40cfd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d59c4c0c..09dfec72 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 0f011db3..577f59bd 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1916,6 +1916,8 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public DateTime CreateTime { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict @@ -1965,13 +1967,18 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" ""Field"" : ""ParentCode"", ""Operator"" : ""Equals"", ""Value"" : ""val4"" + }, + { + ""Field"" : ""CreateTime"", + ""Operator"" : ""GreaterThanOrEqual"", + ""Value"" : ""2010-10-10"" } ] } ")).ToSql(); - Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""ParentCode"" + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""ParentCode"" FROM ""D_District"" a -WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") LIKE '%val3' OR a.""ParentCode"" = 'val4'))", sql); +WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") LIKE '%val3' OR a.""ParentCode"" = 'val4' OR a.""CreateTime"" >= '2010-10-10 00:00:00'))", sql); sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" { @@ -2028,7 +2035,7 @@ WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") ] } ")).ToSql(); - Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""ParentCode"", a__Parent.""Code"" as4, a__Parent.""Name"" as5, a__Parent.""ParentCode"" as6 + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""ParentCode"", a__Parent.""Code"" as5, a__Parent.""Name"" as6, a__Parent.""CreateTime"" as7, a__Parent.""ParentCode"" as8 FROM ""D_District"" a LEFT JOIN ""D_District"" a__Parent ON a__Parent.""Code"" = a.""ParentCode"" WHERE ((not((a.""Code"") LIKE '%val1%') AND not((a.""Name"") LIKE 'val2%') OR not((a.""Name"") LIKE '%val3') OR a.""ParentCode"" <> 'val4' OR a__Parent.""Code"" = 'val11' AND (a__Parent.""Name"") LIKE '%val22%' OR a__Parent.""Name"" = 'val33' OR a__Parent.""ParentCode"" = 'val44'))", sql); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b508dc7e..88b6f7a0 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 497bbada..53cda6e0 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 46043706..6d9560f5 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b6102ce7..a404015f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 1c548b15..db6fe2b5 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d1039bc9..7b394e1b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 78f5c3b6..d56e0c00 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8f3fb9b4..9052e6cf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b789987d..a164041b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index b35cc35d..59c24519 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0507 + 1.5.0-preview0508 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 03a94888a87b8ae4bbb7c7b0a11e230f497599b2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 8 May 2020 10:38:39 +0800 Subject: [PATCH 0628/1029] - fix 1.5.0-preview0502 bug --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 5 ++++- FreeSql/Internal/CommonExpression.cs | 15 +++++++++------ .../Internal/CommonProvider/DeleteProvider.cs | 2 +- .../SelectProvider/Select1Provider.cs | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 2 +- .../FreeSql.Provider.Dameng/Curd/DamengSelect.cs | 2 +- .../Curd/MsAccessSelect.cs | 2 +- .../FreeSql.Provider.MySql/Curd/MySqlSelect.cs | 2 +- .../Dameng/Curd/OdbcDamengSelect.cs | 2 +- .../Default/Curd/OdbcSelect.cs | 2 +- .../MySql/Curd/OdbcMySqlSelect.cs | 2 +- .../Oracle/Curd/OdbcOracleSelect.cs | 2 +- .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 2 +- .../SqlServer/Curd/OdbcSqlServerSelect.cs | 4 ++-- .../FreeSql.Provider.Oracle/Curd/OracleSelect.cs | 2 +- .../Curd/PostgreSQLSelect.cs | 2 +- .../Curd/SqlServerSelect.cs | 4 ++-- .../FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs | 2 +- 19 files changed, 31 insertions(+), 41 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/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 7f0d97fc..3d0d109b 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -281,17 +281,20 @@ namespace FreeSql.Tests g.sqlite.GlobalFilter.Apply("gft1", a => a.rowstate > -1 && g.sqlite.Select().Any(b => b.id == a.id)) .Apply("gft2", a => a.rowstate > -2) - .Apply("gft3", a => a.rowstate > -3); + .Apply("gft3", a => a.rowstate > -3) + .Apply("gft11", a => a.rowstate > -1); var tksk1 = g.sqlite.Select() .InnerJoin((a, b, c) => a.id == b.id) .Where((a, b, c) => c.rowstate > 10) .ToList(); + g.sqlite.Update().NoneParameter().Set(a => a.rowstate + 1).Where(a => a.rowstate >= 0).ExecuteAffrows(); var tksk2 = g.sqlite.Select() .InnerJoin((a, b, c) => a.id == b.id) .Where((a, b, c) => c.rowstate > 10) .ToList(); + g.sqlite.Update().NoneParameter().Set(a => a.rowstate + 1).Where(a => a.rowstate >= 0).ExecuteAffrows(); var dtot2 = g.sqlite.Select().ToList(a => new gfDto { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 8bb2196e..d328c134 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1433,8 +1433,8 @@ namespace FreeSql.Internal } } - static ConcurrentDictionary _dicGetWhereCascadeSqlError = new ConcurrentDictionary(); - public string GetWhereCascadeSql(SelectTableInfo tb, List _whereCascadeExpression) + static ConcurrentDictionary> _dicGetWhereCascadeSqlError = new ConcurrentDictionary>(); + public string GetWhereCascadeSql(SelectTableInfo tb, List _whereCascadeExpression, bool isMultitb) { if (_whereCascadeExpression.Any()) { @@ -1445,8 +1445,9 @@ namespace FreeSql.Internal foreach (var fl in _whereCascadeExpression) { - var errorKey = FreeUtil.Sha1($"{tb.Table.Type.FullName},{fl.ToString()}"); - if (_dicGetWhereCascadeSqlError.ContainsKey(errorKey)) continue; + var dicSqlError = _dicGetWhereCascadeSqlError.GetOrAdd(tb.Table.Type, tp => new ConcurrentDictionary()); + var errorKey = FreeUtil.Sha1($"{(isMultitb ? 1 : 0)},{fl.ToString()}"); + if (dicSqlError.ContainsKey(errorKey)) continue; var visitor = new ReplaceVisitor(); try @@ -1456,7 +1457,9 @@ namespace FreeSql.Internal new ReplaceVisitor().Modify(fl, newParameter), newParameter ); - var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = new List(new[] { tb }), _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = + isMultitb ? new List(new[] { tb }) : null, + _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); whereSql = GetBoolString(expExp.Body, whereSql); if (isEmpty == false) sb.Append(" AND "); @@ -1466,7 +1469,7 @@ namespace FreeSql.Internal } catch { - _dicGetWhereCascadeSqlError.TryAdd(errorKey, true); + dicSqlError.TryAdd(errorKey, true); continue; } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 516b75f0..f4179e1d 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -151,7 +151,7 @@ namespace FreeSql.Internal.CommonProvider if (_whereGlobalFilter.Any()) { - var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList()); + var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList(), false); if (string.IsNullOrEmpty(globalFilterCondi) == false) sb.Append(" AND ").Append(globalFilterCondi); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index f75af392..c9bd0f50 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -830,7 +830,7 @@ namespace FreeSql.Internal.CommonProvider sbJoin.Append($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}"); if (_whereCascadeExpression.Any()) { - var cascade = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Alias = "midtb", AliasInit = "midtb", Table = tbrefMid, Type = SelectTableInfoType.InnerJoin }, _whereCascadeExpression); + var cascade = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Alias = "midtb", AliasInit = "midtb", Table = tbrefMid, Type = SelectTableInfoType.InnerJoin }, _whereCascadeExpression, true); if (string.IsNullOrEmpty(cascade) == false) sbJoin.Append(" AND (").Append(cascade).Append(")"); } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index e3cdd898..4f85e510 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -726,7 +726,7 @@ namespace FreeSql.Internal.CommonProvider if (_whereGlobalFilter.Any()) { - var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList()); + var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList(), false); if (string.IsNullOrEmpty(globalFilterCondi) == false) sb.Append(" AND ").Append(globalFilterCondi); } diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs index e93a68f6..c9087dff 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.Dameng.Curd if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs index dde8525e..b692561a 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs @@ -20,7 +20,7 @@ namespace FreeSql.MsAccess.Curd if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index c29cc5e7..802bc791 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.MySql.Curd if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs index fdba488e..b876790a 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.Odbc.Dameng if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index 1611f4f7..7479b256 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.Odbc.Default if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index 13790134..078ec66f 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.Odbc.MySql if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index 6dafdef1..ccefb0f7 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.Odbc.Oracle if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 0ef6c116..86d3e7de 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.Odbc.PostgreSQL if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index 09b2cd46..9a6d2cde 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.SqlServer if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -140,7 +140,7 @@ namespace FreeSql.Odbc.SqlServer if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index f73aaaa5..7a725285 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.Oracle.Curd if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 4485b2be..80b28769 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.PostgreSQL.Curd if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 459f96f5..024bc957 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.SqlServer.Curd if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -140,7 +140,7 @@ namespace FreeSql.SqlServer.Curd if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index f2cf82db..bf2af50d 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -19,7 +19,7 @@ namespace FreeSql.Sqlite.Curd if (_whereCascadeExpression.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; From fc828d15a6dfa34f3fb0ed3fa9aa1264f2369336 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 8 May 2020 10:41:12 +0800 Subject: [PATCH 0629/1029] v1.5.0-preview0509 #298 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 4774e842..f050c5f2 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netcoreapp31;netcoreapp21;net4.0; - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index f6925e68..791f4273 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7e237009..847125c5 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 745467d9..b61cf360 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index fe36ad28..c21093e5 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0-preview0508 + 1.5.0-preview0509 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 35b7fd50..c115da28 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e6d40cfd..323c534d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 09dfec72..aabb4060 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 88b6f7a0..ebaadb91 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 53cda6e0..cd92f85c 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 6d9560f5..80d212da 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index a404015f..f1522623 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index db6fe2b5..f6af1e14 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 7b394e1b..11d056fe 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d56e0c00..2f123c2d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 9052e6cf..5a426225 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a164041b..807fad36 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 59c24519..5af96c3e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0508 + 1.5.0-preview0509 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 6d5575def19a6ebb7e54652f10b6312e8cafaf01 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 8 May 2020 14:49:24 +0800 Subject: [PATCH 0630/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20BaseEntity?= =?UTF-8?q?=EF=BC=8C=E7=A7=BB=E9=99=A4=20BaseTreeEntity=E3=80=81Tenant=20?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=EF=BC=8C=E6=94=B9=E5=8F=98=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E4=B9=A0=E6=83=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 16 +- .../BaseEntity.cs | 33 ++-- .../BaseEntityAsync.cs | 34 ++-- .../BaseEntityReadOnly.cs | 105 +++-------- .../BaseEntityTree.cs | 168 ------------------ .../FreeSql.Extensions.BaseEntity.csproj | 10 +- .../FreeSql.Extensions.BaseEntity.xml | 75 ++------ .../Net40/BaseEntity.cs | 122 ------------- .../Net40/BaseEntityReadOnly.cs | 130 -------------- .../FreeSql.Extensions.BaseEntity/readme.md | 36 +++- FreeSql.Tests.VB/UnitTest1.vb | 2 +- .../FreeSql.Tests.DbContext/UnitTest1.cs | 2 +- 12 files changed, 128 insertions(+), 605 deletions(-) delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs delete mode 100644 Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index c1440834..256a8653 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -37,6 +37,8 @@ namespace base_entity public string title { get; set; } } + static AsyncLocal _asyncUow = new AsyncLocal(); + static void Main(string[] args) { @@ -73,7 +75,7 @@ namespace base_entity .UseMonitorCommand(cmd => Console.Write(cmd.CommandText)) .UseLazyLoading(true) .Build(); - BaseEntity.Initialization(fsql); + BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion var test01 = EMSServerModel.Model.User.Select.IncludeMany(a => a.Roles).ToList(); @@ -144,9 +146,17 @@ namespace base_entity Task.Run(async () => { - using (var uow = BaseEntity.Begin()) + using (var uow = BaseEntity.Orm.CreateUnitOfWork()) { - var id = (await new User1().SaveAsync()).Id; + _asyncUow.Value = uow; + try + { + var id = (await new User1().SaveAsync()).Id; + } + finally + { + _asyncUow.Value = null; + } uow.Commit(); } diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index a3064ad9..40382f84 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -1,6 +1,4 @@ -#if netcore - -using FreeSql; +using FreeSql; using FreeSql.DataAnnotations; using System; using System.Data; @@ -34,6 +32,8 @@ namespace FreeSql [Column(Position = 1)] public virtual TKey Id { get; set; } +#if net40 +#else /// /// 根据主键值获取数据 /// @@ -45,6 +45,7 @@ namespace FreeSql (item as BaseEntity)?.Attach(); return item; } +#endif /// /// 根据主键值获取数据 @@ -70,12 +71,11 @@ namespace FreeSql { if (this.Repository == null) return Orm.Update(this as TEntity) - .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction()) + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; - this.SetTenantId(); this.IsDeleted = value; - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return this.Repository.Update(this as TEntity) == 1; } /// @@ -88,8 +88,8 @@ namespace FreeSql if (physicalDelete == false) return this.UpdateIsDeleted(true); if (this.Repository == null) return Orm.Delete(this as TEntity).ExecuteAffrows() == 1; - //this.SetTenantId(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return this.Repository.Delete(this as TEntity) == 1; } /// @@ -107,11 +107,10 @@ namespace FreeSql this.UpdateTime = DateTime.Now; if (this.Repository == null) return Orm.Update() - .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction()) + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) .SetSource(this as TEntity).ExecuteAffrows() == 1; - this.SetTenantId(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return this.Repository.Update(this as TEntity) == 1; } /// @@ -123,8 +122,7 @@ namespace FreeSql if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.SetTenantId(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return this.Repository.Insert(this as TEntity); } @@ -138,8 +136,7 @@ namespace FreeSql if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.SetTenantId(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return this.Repository.InsertOrUpdate(this as TEntity); } @@ -152,10 +149,8 @@ namespace FreeSql if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); this.Repository.SaveMany(this as TEntity, navigatePropertyName); } } -} - -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index 8b0e5ed2..ca589470 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -1,5 +1,4 @@ -#if netcore - + using FreeSql; using FreeSql.DataAnnotations; using System; @@ -27,8 +26,11 @@ namespace FreeSql /// /// 主键 /// + [Column(Position = 1)] public virtual TKey Id { get; set; } +#if net40 +#else /// /// 根据主键值获取数据 /// @@ -40,6 +42,8 @@ namespace FreeSql (item as BaseEntity)?.Attach(); return item; } +#endif + } /// @@ -49,15 +53,17 @@ namespace FreeSql [Table(DisableSyncStructure = true)] public abstract class BaseEntityAsync : BaseEntityReadOnly where TEntity : class { +#if net40 +#else async Task UpdateIsDeletedAsync(bool value) { if (this.Repository == null) return await Orm.Update(this as TEntity) - .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction()) + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; this.IsDeleted = value; - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return await this.Repository.UpdateAsync(this as TEntity) == 1; } /// @@ -70,8 +76,8 @@ namespace FreeSql if (physicalDelete == false) return await this.UpdateIsDeletedAsync(true); if (this.Repository == null) return await Orm.Delete(this as TEntity).ExecuteAffrowsAsync() == 1; - //this.SetTenantId(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return await this.Repository.DeleteAsync(this as TEntity) == 1; } /// @@ -89,11 +95,10 @@ namespace FreeSql this.UpdateTime = DateTime.Now; if (this.Repository == null) return await Orm.Update() - .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction()) + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; - this.SetTenantId(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return await this.Repository.UpdateAsync(this as TEntity) == 1; } /// @@ -105,8 +110,7 @@ namespace FreeSql if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.SetTenantId(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return this.Repository.InsertAsync(this as TEntity); } @@ -120,8 +124,7 @@ namespace FreeSql if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.SetTenantId(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return this.Repository.InsertOrUpdateAsync(this as TEntity); } @@ -134,10 +137,9 @@ namespace FreeSql if (this.Repository == null) this.Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = CurrentUnitOfWork; + this.Repository.UnitOfWork = _resolveUow?.Invoke(); return this.Repository.SaveManyAsync(this as TEntity, navigatePropertyName); } +#endif } } - -#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index d4efcbff..b3dd1c8a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -1,11 +1,10 @@ -#if netcore - + using FreeSql.DataAnnotations; using System; using System.Collections; -using System.Collections.Generic; using System.Collections.Concurrent; -using System.Data; +using System.Collections.Generic; +using System.Data.Common; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; @@ -27,6 +26,7 @@ namespace FreeSql .UseAutoSyncStructure(true) .UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") .Build());"); + internal static Func _resolveUow; /// /// 初始化BaseEntity @@ -39,7 +39,8 @@ namespace FreeSql /// .Build()); /// /// IFreeSql orm 对象 - public static void Initialization(IFreeSql fsql) + /// 工作单元(事务)委托,如果不使用事务请传 null解释:由于AsyncLocal平台兼容不好,所以交给外部管理 + public static void Initialization(IFreeSql fsql, Func resolveUow) { _ormPriv = fsql; _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine($"\r\n线程{Thread.CurrentThread.ManagedThreadId}: {e.Sql}\r\n"); @@ -51,6 +52,7 @@ namespace FreeSql _ormPriv.CodeFirst.ConfigEntity(cei.EntityType, cei.Fluent); } } + _resolveUow = resolveUow; } class ConfigEntityInfo @@ -75,72 +77,25 @@ namespace FreeSql /// 创建时间 /// [Column(Position = -4)] - public DateTime CreateTime { get; set; } = DateTime.Now; + public virtual DateTime CreateTime { get; set; } = DateTime.Now; /// /// 更新时间 /// [Column(Position = -3)] - public DateTime UpdateTime { get; set; } + public virtual DateTime UpdateTime { get; set; } /// /// 逻辑删除 /// [Column(Position = -2)] - public bool IsDeleted { get; set; } + public virtual bool IsDeleted { get; set; } /// /// 排序 /// [Column(Position = -1)] - public int Sort { get; set; } - - /// - /// 开启工作单元事务 - /// - /// - public static IUnitOfWork Begin() => Begin(null); - /// - /// 开启工作单元事务 - /// - /// 事务等级 - /// - public static IUnitOfWork Begin(IsolationLevel? level) - { - var uow = Orm.CreateUnitOfWork(); - uow.IsolationLevel = level; - CurrentUnitOfWork = uow; - return uow; - } - - static readonly AsyncLocal _AsyncUnitOfWork = new AsyncLocal(); - static readonly AsyncLocal _AsyncTenantId = new AsyncLocal(); - /// - /// 获取或设置当前租户id - /// - public static string CurrentTenantId - { - get => _AsyncTenantId.Value; - set => _AsyncTenantId.Value = value; - } - /// - /// 获取或设置当前租户id - /// - public static IUnitOfWork CurrentUnitOfWork - { - get => _AsyncUnitOfWork.Value; - set => _AsyncUnitOfWork.Value = value; - } - } - - /// - /// 租户 - /// - public interface ITenant - { - /// - /// 租户id - /// - string TenantId { get; set; } + public virtual int Sort { get; set; } } + [Table(DisableSyncStructure = true)] public abstract class BaseEntityReadOnly : BaseEntity where TEntity : class { /// @@ -153,9 +108,7 @@ namespace FreeSql { var select = Orm.Select() .TrackToList(TrackToList) //自动为每个元素 Attach - .WithTransaction(CurrentUnitOfWork?.GetOrBeginTransaction(false)); - if (string.IsNullOrEmpty(CurrentTenantId) == false) - select.WhereCascade(a => (a as ITenant).TenantId == CurrentTenantId); + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction(false)); return select.WhereCascade(a => (a as BaseEntity).IsDeleted == false); } } @@ -169,6 +122,7 @@ namespace FreeSql var ie = list as IEnumerable; if (ie == null) return; var isFirst = true; + IBaseRepository berepo = null; foreach (var item in ie) { if (item == null) return; @@ -181,27 +135,29 @@ namespace FreeSql if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; if (item is BaseEntity == false) return; } - (item as BaseEntity)?.Attach(); + var beitem = item as BaseEntity; + if (beitem != null) + { + if (berepo == null) berepo = Orm.GetRepository(); + beitem.Repository = berepo; + beitem.Attach(); + } } return; } if (ls.Any() == false) return; if (ls.FirstOrDefault() is BaseEntity == false) return; if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) return; + IBaseRepository repo = null; foreach (var item in ls) - (item as BaseEntity)?.Attach(); - } - - /// - /// 设置当前租户id - /// - protected void SetTenantId() - { - if (string.IsNullOrEmpty(CurrentTenantId) == false) { - var ten = this as ITenant; - if (ten != null) - ten.TenantId = CurrentTenantId; + var beitem = item as BaseEntity; + if (beitem != null) + { + if (repo == null) repo = Orm.GetRepository(); + beitem.Repository = repo; + beitem.Attach(); + } } } @@ -233,11 +189,8 @@ namespace FreeSql this.Repository = Orm.GetRepository(); var item = this as TEntity; - this.SetTenantId(); this.Repository.Attach(item); return item; } } } - -#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs deleted file mode 100644 index a2b5231c..00000000 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityTree.cs +++ /dev/null @@ -1,168 +0,0 @@ -#if netcore - -using FreeSql; -using FreeSql.DataAnnotations; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FreeSql -{ - /// - /// 树状基类 - /// - /// - /// - [Table(DisableSyncStructure = true)] - public abstract class BaseEntityTree : BaseEntity where TEntity : class - { - /// - /// 父级id - /// - public TKey ParentId - { - get => _ParentId; - set - { - if (Equals(value, default(TKey)) == false && Equals(value, Id)) - throw new ArgumentException("ParentId 值不能与 Id 相同"); - _ParentId = value; - } - } - public TEntity Parent { get; set; } - private TKey _ParentId; - - /// - /// 下级列表 - /// - [Navigate("ParentId")] - public List Childs { get; set; } - - /// - /// 名称 - /// - public string Name { get; set; } - /// - /// 名称:技术部-前端 - /// - public string FullName { get; set; } - - public List GetAllChilds() => Select.WhereDynamic(this) - .IncludeMany(a => (a as BaseEntityTree).Childs, - t1 => t1.IncludeMany(a1 => (a1 as BaseEntityTree).Childs, - t2 => t2.IncludeMany(a2 => (a2 as BaseEntityTree).Childs, - t3 => t3.IncludeMany(a3 => (a3 as BaseEntityTree).Childs, - t4 => t4.IncludeMany(a4 => (a4 as BaseEntityTree).Childs, - t5 => t5.IncludeMany(a5 => (a5 as BaseEntityTree).Childs, - t6 => t6.IncludeMany(a6 => (a6 as BaseEntityTree).Childs, - t7 => t7.IncludeMany(a7 => (a7 as BaseEntityTree).Childs, - t8 => t8.IncludeMany(a8 => (a8 as BaseEntityTree).Childs, - t9 => t9.IncludeMany(a9 => (a9 as BaseEntityTree).Childs, - t10 => t10.IncludeMany(a10 => (a10 as BaseEntityTree).Childs))))))))))).ToList() - .SelectMany(a => (a as BaseEntityTree).Childs - .SelectMany(a1 => (a1 as BaseEntityTree)?.Childs - .SelectMany(a2 => (a2 as BaseEntityTree)?.Childs - .SelectMany(a3 => (a3 as BaseEntityTree)?.Childs - .SelectMany(a4 => (a4 as BaseEntityTree)?.Childs - .SelectMany(a5 => (a5 as BaseEntityTree)?.Childs - .SelectMany(a6 => (a6 as BaseEntityTree)?.Childs - .SelectMany(a7 => (a7 as BaseEntityTree)?.Childs - .SelectMany(a8 => (a8 as BaseEntityTree)?.Childs - .SelectMany(a9 => (a9 as BaseEntityTree)?.Childs - .SelectMany(a10 => (a10 as BaseEntityTree)?.Childs))))))))))).Where(a => a != null).ToList(); - - protected void RefershFullName() - { - var buf = new List(); - buf.Add(this as TEntity); - buf.AddRange(this.GetAllChilds()); - var repo = Orm.GetRepository(); - repo.UnitOfWork = CurrentUnitOfWork; - buf = repo.Select.WhereDynamic(buf) - .Include(a => ((((((((((a as BaseEntityTree).Parent - as BaseEntityTree).Parent - as BaseEntityTree).Parent - as BaseEntityTree).Parent - as BaseEntityTree).Parent - as BaseEntityTree).Parent - as BaseEntityTree).Parent - as BaseEntityTree).Parent - as BaseEntityTree).Parent - as BaseEntityTree).Parent).ToList(true); - foreach (var item in buf) - { - var up = item as BaseEntityTree; - up.Name = up.Name; - var cur = up.Parent as BaseEntityTree; - while (cur != null) - { - up.Name = $"{cur.Name}-{up.Name}"; - cur = cur.Parent as BaseEntityTree; - } - } - repo.Update(buf); - } - - T UpdateIsDelete(bool value, Func, List, T> func) - { - var childs = GetAllChilds(); - childs.Add(this as TEntity); - var repo = Orm.GetRepository(); - repo.UnitOfWork = CurrentUnitOfWork; - repo.Attach(childs); - foreach (var item in childs) - (item as BaseEntity).IsDeleted = false; - return func(repo, childs); - } - public override bool Delete(bool physicalDelete = false) => UpdateIsDelete(true, (repo, chis) => repo.Update(chis)) > 0; - async public override Task DeleteAsync(bool physicalDelete = false) => await UpdateIsDelete(true, (repo, chis) => repo.UpdateAsync(chis)) > 0; - - public override bool Restore() => UpdateIsDelete(false, (repo, chis) => repo.Update(chis)) > 0; - async public override Task RestoreAsync() => await UpdateIsDelete(false, (repo, chis) => repo.UpdateAsync(chis)) > 0; - - public override TEntity Insert() - { - var ret = base.Insert(); - RefershFullName(); - return ret; - } - async public override Task InsertAsync() - { - var ret = await base.InsertAsync(); - RefershFullName(); - return ret; - } - public override bool Update() - { - var old = Find(this.Id) as BaseEntityTree; - var ret = base.Update(); - if (old.Name != this.Name || Equals(old.ParentId, old.ParentId) == false) RefershFullName(); - return ret; - } - async public override Task UpdateAsync() - { - var old = Find(this.Id) as BaseEntityTree; - var ret = await base.UpdateAsync(); - if (old.Name != this.Name || Equals(old.ParentId, old.ParentId) == false) RefershFullName(); - return ret; - } - public override TEntity Save() - { - var old = Find(this.Id) as BaseEntityTree; - var ret = base.Save(); - if (old.Name != this.Name || Equals(old.ParentId, old.ParentId) == false) RefershFullName(); - return ret; - } - async public override Task SaveAsync() - { - var old = Find(this.Id) as BaseEntityTree; - var ret = await base.SaveAsync(); - if (old.Name != this.Name || Equals(old.ParentId, old.ParentId) == false) RefershFullName(); - return ret; - } - } -} - -#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f050c5f2..f6898685 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -1,7 +1,7 @@  - netcoreapp31;netcoreapp21;net4.0; + netstandard2.0;net45;net40 1.5.0-preview0509 true ncc;YeXiangQin @@ -34,12 +34,8 @@ - - - - - - netcore + + net40 diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml index a2b0bbc5..8b44d128 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml @@ -68,6 +68,12 @@ + + + 【完整】保存导航属性,子表 + + 导航属性名 + 包括 CreateTime/UpdateTime/IsDeleted、CRUD 异步方法、以及 ID 主键定义 的实体基类 @@ -125,6 +131,12 @@ + + + 【完整】保存导航属性,子表 + + 导航属性名 + 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 @@ -135,7 +147,7 @@ 全局 IFreeSql orm 对象 - + 初始化BaseEntity BaseEntity.Initialization(new FreeSqlBuilder() @@ -147,6 +159,7 @@ .Build()); IFreeSql orm 对象 + 工作单元(事务)委托,如果不使用事务请传 null解释:由于AsyncLocal平台兼容不好,所以交给外部管理 @@ -168,45 +181,12 @@ 排序 - - - 开启工作单元事务 - - - - - - 开启工作单元事务 - - 事务等级 - - - - - 获取或设置当前租户id - - - - - 租户 - - - - - 租户id - - 查询数据 - - - 设置当前租户id - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") @@ -232,32 +212,5 @@ 附加实体,在更新数据时,只更新变化的部分 - - - 树状基类 - - - - - - - 父级id - - - - - 下级列表 - - - - - 名称 - - - - - 名称:技术部-前端 - - diff --git a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs deleted file mode 100644 index 41742013..00000000 --- a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntity.cs +++ /dev/null @@ -1,122 +0,0 @@ -#if netcore -#else - -using FreeSql; -using FreeSql.DataAnnotations; -using System; -using System.Data; -using System.Diagnostics; -using System.Linq.Expressions; -using System.Threading; -using System.Threading.Tasks; - -namespace FreeSql -{ - /// - /// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 - /// - /// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 - /// - /// - /// - [Table(DisableSyncStructure = true)] - public abstract class BaseEntity : BaseEntity where TEntity : class - { - static BaseEntity() - { - var tkeyType = typeof(TKey)?.NullableTypeOrThis(); - if (tkeyType == typeof(int) || tkeyType == typeof(long)) - Orm.CodeFirst.ConfigEntity(typeof(TEntity), - t => t.Property("Id").IsIdentity(true)); - } - - /// - /// 主键 - /// - [Column(Position = 1)] - public virtual TKey Id { get; set; } - - /// - /// 根据主键值获取数据 - /// - /// - /// - public static TEntity Find(TKey id) - { - var item = Select.WhereDynamic(id).First(); - (item as BaseEntity)?.Attach(); - return item; - } - } - - /// - /// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 - /// - /// - [Table(DisableSyncStructure = true)] - public abstract class BaseEntity : BaseEntityReadOnly where TEntity : class - { - bool DeletedPrivate(bool value) - { - if (this.Repository == null) - return Orm.Delete(this as TEntity) - .ExecuteAffrows() == 1; - - return this.Repository.Delete(this as TEntity) == 1; - } - /// - /// 删除数据 - /// - /// - public virtual bool Delete() => this.DeletedPrivate(true); - - /// - /// 更新数据 - /// - /// - public virtual bool Update() - { - if (this.Repository == null) - return Orm.Update() - .SetSource(this as TEntity).ExecuteAffrows() == 1; - - return this.Repository.Update(this as TEntity) == 1; - } - /// - /// 插入数据 - /// - public virtual TEntity Insert() - { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - return this.Repository.Insert(this as TEntity); - } - - /// - /// 更新或插入 - /// - /// - public virtual TEntity Save() - { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - return this.Repository.InsertOrUpdate(this as TEntity); - } - - /// - /// 【完整】保存导航属性,子表 - /// - /// 导航属性名 - public virtual void SaveMany(string navigatePropertyName) - { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - this.Repository.SaveMany(this as TEntity, navigatePropertyName); - } - } -} - -#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs deleted file mode 100644 index 7464f2fb..00000000 --- a/Extensions/FreeSql.Extensions.BaseEntity/Net40/BaseEntityReadOnly.cs +++ /dev/null @@ -1,130 +0,0 @@ -#if netcore -#else - -using FreeSql.DataAnnotations; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using System.Diagnostics; -using System.Linq; -using System.Linq.Expressions; -using System.Threading; - -namespace FreeSql -{ - /// - /// 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 - /// - [Table(DisableSyncStructure = true)] - public abstract class BaseEntity - { - static IFreeSql _ormPriv; - /// - /// 全局 IFreeSql orm 对象 - /// - public static IFreeSql Orm => _ormPriv ?? throw new Exception(@"使用前请初始化 BaseEntity.Initialization(new FreeSqlBuilder() -.UseAutoSyncStructure(true) -.UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") -.Build());"); - - /// - /// 初始化BaseEntity - /// BaseEntity.Initialization(new FreeSqlBuilder() - /// - /// .UseAutoSyncStructure(true) - /// - /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") - /// - /// .Build()); - /// - /// IFreeSql orm 对象 - public static void Initialization(IFreeSql fsql) - { - _ormPriv = fsql; - _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine(e.Sql + "\r\n"); - } - } - - public abstract class BaseEntityReadOnly : BaseEntity where TEntity : class - { - /// - /// 查询数据 - /// - /// - public static ISelect Select - { - get - { - var select = Orm.Select().TrackToList(TrackToList); //自动为每个元素 Attach; - return select; - } - } - - static void TrackToList(object list) - { - if (list == null) return; - var ls = list as IList; - if (ls == null) - { - var ie = list as IEnumerable; - if (ie == null) return; - var isFirst = true; - foreach (var item in ie) - { - if (item == null) return; - if (isFirst) - { - isFirst = false; - var itemType = item.GetType(); - if (itemType == typeof(object)) return; - if (itemType.FullName.Contains("FreeSqlLazyEntity__")) itemType = itemType.BaseType; - if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; - if (item is BaseEntity == false) return; - } - (item as BaseEntity)?.Attach(); - } - return; - } - if (ls.Any() == false) return; - if (ls.FirstOrDefault() is BaseEntity == false) return; - if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) return; - foreach (var item in ls) - (item as BaseEntity)?.Attach(); - } - - /// - /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - /// - /// lambda表达式 - /// - public static ISelect Where(Expression> exp) => Select.Where(exp); - /// - /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - /// - /// true 时生效 - /// lambda表达式 - /// - public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); - - /// - /// 仓储对象 - /// - protected IBaseRepository Repository { get; set; } - - /// - /// 附加实体,在更新数据时,只更新变化的部分 - /// - public TEntity Attach() - { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - - var item = this as TEntity; - this.Repository.Attach(item); - return item; - } - } -} - -#endif \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/readme.md b/Extensions/FreeSql.Extensions.BaseEntity/readme.md index a9ace8ac..1c347ded 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/readme.md +++ b/Extensions/FreeSql.Extensions.BaseEntity/readme.md @@ -42,7 +42,7 @@ public class UserGroup : BaseEntity ```csharp public class UserGroup : BaseEntity { - [Column(IsIdentity = false)] + [Column(IsIdentity = false)] public override int Id { get; set; } public string GroupName { get; set; } } @@ -90,3 +90,37 @@ var items = UserGroup.Where(a => a.Id > 10).ToList(); 支持多表查询时,软删除条件会附加在每个表中; > 有关更多查询方法,请参考资料:https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2 + +# 事务建议 + +由于 AsyncLocal 平台兼容不好,所以交给外部管理。 + +```csharp +static AsyncLocal _asyncUow = new AsyncLocal(); + +BaseEntity.Initialization(fsql, () => _asyncUow.Value); +``` + +在 Scoped 开始时: _asyncUow.Value = fsql.CreateUnitOfWork(); (也可以使用 UnitOfWorkManager 对象获取 uow) + +在 Scoped 结束时:_asyncUow.Value = null; + +如下: + +```csharp +using (var uow = fsql.CreateUnitOfWork()) +{ + _asyncUow.Value = uow; + + try + { + //todo ... + } + finally + { + _asyncUow.Value = null; + } + + uow.Commit(); +} +``` diff --git a/FreeSql.Tests.VB/UnitTest1.vb b/FreeSql.Tests.VB/UnitTest1.vb index da79ebdf..c8966d58 100644 --- a/FreeSql.Tests.VB/UnitTest1.vb +++ b/FreeSql.Tests.VB/UnitTest1.vb @@ -39,7 +39,7 @@ Namespace FreeSql.Tests.VB Dim List9 = g.sqlserver.Select(Of Testvb).IncludeMany(Function(a) a.Testvb2s).ToList() - BaseEntity.Initialization(g.sqlserver) + BaseEntity.Initialization(g.sqlserver, Nothing) Dim cowR As CowRecord = New CowRecord cowR.Id = 1 cowR.Lact = 1 diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index 663056ed..c723b02b 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -24,7 +24,7 @@ namespace FreeSql.Tests g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); - BaseEntity.Initialization(g.sqlite); + BaseEntity.Initialization(g.sqlite, null); userinfo user = new userinfo { userid = 1, badgenumber = "", Name="", IDCardNo="" }; user.Insert(); From 713ef26909d99b5e12a98cf23ac302e5f18873eb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 8 May 2020 14:52:28 +0800 Subject: [PATCH 0631/1029] update BaseEntity readme --- Examples/base_entity/readme.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Examples/base_entity/readme.md b/Examples/base_entity/readme.md index a9ace8ac..6a8bde3b 100644 --- a/Examples/base_entity/readme.md +++ b/Examples/base_entity/readme.md @@ -90,3 +90,37 @@ var items = UserGroup.Where(a => a.Id > 10).ToList(); 支持多表查询时,软删除条件会附加在每个表中; > 有关更多查询方法,请参考资料:https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2 + +# 事务建议 + +由于 AsyncLocal 平台兼容不好,所以交给外部管理。 + +```csharp +static AsyncLocal _asyncUow = new AsyncLocal(); + +BaseEntity.Initialization(fsql, () => _asyncUow.Value); +``` + +在 Scoped 开始时: _asyncUow.Value = fsql.CreateUnitOfWork(); (也可以使用 UnitOfWorkManager 对象获取 uow) + +在 Scoped 结束时:_asyncUow.Value = null; + +如下: + +```csharp +using (var uow = fsql.CreateUnitOfWork()) +{ + _asyncUow.Value = uow; + + try + { + //todo ... + } + finally + { + _asyncUow.Value = null; + } + + uow.Commit(); +} +``` From 7c112861c0fe5933ddf5a9395eb561816434312f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 9 May 2020 15:26:26 +0800 Subject: [PATCH 0632/1029] update TransactionalAttribute --- Examples/aspnetcore_transaction/TransactionalAttribute.cs | 5 +++-- Examples/base_entity/readme.md | 2 +- Extensions/FreeSql.Extensions.BaseEntity/readme.md | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Examples/aspnetcore_transaction/TransactionalAttribute.cs b/Examples/aspnetcore_transaction/TransactionalAttribute.cs index 049575c1..71f8cbc4 100644 --- a/Examples/aspnetcore_transaction/TransactionalAttribute.cs +++ b/Examples/aspnetcore_transaction/TransactionalAttribute.cs @@ -15,7 +15,8 @@ namespace FreeSql public class TransactionalAttribute : DynamicProxyAttribute, IActionFilter { public Propagation Propagation { get; set; } = Propagation.Requierd; - public IsolationLevel? IsolationLevel { get; set; } + public IsolationLevel IsolationLevel { get => _IsolationLevelPriv.Value; set => _IsolationLevelPriv = value; } + IsolationLevel? _IsolationLevelPriv; [DynamicProxyFromServices] UnitOfWorkManager _uowManager; @@ -31,7 +32,7 @@ namespace FreeSql Task OnBefore(UnitOfWorkManager uowm) { - _uow = uowm.Begin(this.Propagation, this.IsolationLevel); + _uow = uowm.Begin(this.Propagation, this._IsolationLevelPriv); return Task.FromResult(false); } Task OnAfter(Exception ex) diff --git a/Examples/base_entity/readme.md b/Examples/base_entity/readme.md index 6a8bde3b..de64368d 100644 --- a/Examples/base_entity/readme.md +++ b/Examples/base_entity/readme.md @@ -93,7 +93,7 @@ var items = UserGroup.Where(a => a.Id > 10).ToList(); # 事务建议 -由于 AsyncLocal 平台兼容不好,所以交给外部管理。 +由于 AsyncLocal 平台兼容不好,所以交给外部管理事务。 ```csharp static AsyncLocal _asyncUow = new AsyncLocal(); diff --git a/Extensions/FreeSql.Extensions.BaseEntity/readme.md b/Extensions/FreeSql.Extensions.BaseEntity/readme.md index 1c347ded..32425019 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/readme.md +++ b/Extensions/FreeSql.Extensions.BaseEntity/readme.md @@ -93,7 +93,7 @@ var items = UserGroup.Where(a => a.Id > 10).ToList(); # 事务建议 -由于 AsyncLocal 平台兼容不好,所以交给外部管理。 +由于 AsyncLocal 平台兼容不好,所以交给外部管理事务。 ```csharp static AsyncLocal _asyncUow = new AsyncLocal(); From a9ee9aa06912c1d857a771f8110157f602eb332a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 9 May 2020 22:26:26 +0800 Subject: [PATCH 0633/1029] add Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index bc23703d..bb475b21 100644 --- a/readme.md +++ b/readme.md @@ -190,7 +190,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## 💕 Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元 > Thank you for your donation From 54ceefefd2da3e576b131ba709d2456317bb6b06 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 10 May 2020 06:23:00 +0800 Subject: [PATCH 0634/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IgnoreColumn?= =?UTF-8?q?s=20=E7=9B=B8=E5=85=B3=E6=96=B9=E6=B3=95=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=20a=20=3D>=20new=20[]=20{=20"Id"=20?= =?UTF-8?q?..=20}=20=E6=97=A0=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs | 14 ++++++++++++++ FreeSql/Internal/CommonExpression.cs | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index e13e0c0b..7089325b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -69,6 +69,20 @@ namespace FreeSql.Tests.Sqlite { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); + + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new object[] { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); + + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new[] { "Clicks", "CreateTime", "TypeGuid" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); + + var cols = new[] { "Clicks", "CreateTime", "TypeGuid" }; + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => cols).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); + + cols = new[] { "Clicks", "CreateTime", "TypeGuid" }; + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(cols).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Title\" = @p_0 WHERE (\"Id\" = 1)", sql); } [Fact] public void UpdateColumns() diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index d328c134..542e7859 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -341,19 +341,19 @@ namespace FreeSql.Internal case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, getSelectGroupingMapString); case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString) }; - case ExpressionType.MemberAccess: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString) }; + case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries); case ExpressionType.New: var newExp = exp as NewExpression; if (newExp == null) break; var newExpMembers = new string[newExp.Members.Count]; for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, getSelectGroupingMapString); - return newExpMembers; + return newExpMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); case ExpressionType.NewArrayInit: var newArr = exp as NewArrayExpression; if (newArr == null) break; var newArrMembers = new List(); foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, getSelectGroupingMapString)); - return newArrMembers.ToArray(); + return newArrMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); } return new string[0]; } From 89a58a2d554a90c49c9da10dde8303e6c59efbaf Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 10 May 2020 23:34:29 +0800 Subject: [PATCH 0635/1029] update aop transaction demo --- Examples/aspnetcore_transaction/aspnetcore_transaction.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj index cecd9f4b..77ed7fb2 100644 --- a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj @@ -6,11 +6,13 @@ aspnetcore_transaction.xml + 3 - + + From 2853c356e66e683d8e57f40f0791ab78c68f8fff Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 12 May 2020 21:52:28 +0800 Subject: [PATCH 0636/1029] add test #306 --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ------ FreeSql.Tests/FreeSql.Tests/Issues/306.cs | 62 +++++++++++++++++++++++ 2 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/306.cs 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/Issues/306.cs b/FreeSql.Tests/FreeSql.Tests/Issues/306.cs new file mode 100644 index 00000000..c5748a23 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/306.cs @@ -0,0 +1,62 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _306 + { + [Fact] + public void SelectTest() + { + IFreeSql db = g.sqlserver; + + db.Select() + .InnerJoin((a, b) => a.MeterSN == b.MeterSN) + .ToAggregate((a, b) => new VM_PeriodEnergy + { + Sharp = a.Sum(a.Key.Sharp), + Peak = a.Sum(a.Key.Peak), + Shoulder = a.Sum(a.Key.Shoulder), + Off = a.Sum(a.Key.Off), + }); + } + + public class ElectricEnergyValue + { + public int ID { get; set; } + + public string MeterSN { get; set; } + + public DateTime CollectTime { get; set; } + + public decimal Sharp { get; set; } + + public decimal Peak { get; set; } + + public decimal Shoulder { get; set; } + + public decimal Off { get; set; } + } + + public class BranchMeter + { + public int BranchID { get; set; } + + public string MeterSN { get; set; } + } + + public class VM_PeriodEnergy + { + public decimal Sharp { get; set; } + + public decimal Peak { get; set; } + + public decimal Shoulder { get; set; } + + public decimal Off { get; set; } + } + } +} From a0acece7e504247e9970721ce48a355a00874cc8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 13 May 2020 16:52:12 +0800 Subject: [PATCH 0637/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IUpdate.SetI?= =?UTF-8?q?f=20=E6=96=B9=E6=B3=95=EF=BC=9B#309?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Interface/Curd/IUpdate.cs | 19 +++++++++++++++++++ .../Internal/CommonProvider/UpdateProvider.cs | 2 ++ 2 files changed, 21 insertions(+) diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 41a8758b..289f3096 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -93,6 +93,15 @@ namespace FreeSql /// IUpdate Set(Expression> column, TMember value); /// + /// 设置列的新值,Set(a => a.Name, "newvalue") + /// + /// + /// true 时生效 + /// lambda选择列 + /// 新值 + /// + IUpdate SetIf(bool condition, Expression> column, TMember value); + /// /// 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 /// /// 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' @@ -102,6 +111,16 @@ namespace FreeSql /// IUpdate Set(Expression> exp); /// + /// 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + /// + /// 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + /// + /// + /// true 时生效 + /// + /// + IUpdate SetIf(bool condition, Expression> exp); + /// /// 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) /// /// sql语法 diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 4f85e510..1a7cf8ab 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -400,6 +400,7 @@ namespace FreeSql.Internal.CommonProvider SetPriv(cols.First().Column, value); return this; } + public IUpdate SetIf(bool condition, Expression> column, TMember value) => condition ? Set(column, value) : this; public IUpdate Set(Expression> exp) { var body = exp?.Body; @@ -459,6 +460,7 @@ namespace FreeSql.Internal.CommonProvider _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(cols.First().Column.Attribute.Name)).Append(" = ").Append(expt); return this; } + public IUpdate SetIf(bool condition, Expression> exp) => condition ? Set(exp) : this; public IUpdate SetRaw(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; From a8bba1e6d2d95ac9a1f70dfb89f153e2921b602f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 15 May 2020 00:12:15 +0800 Subject: [PATCH 0638/1029] update Performance tests #310 --- Examples/orm_vs/Program.cs | 27 +++++++++++++++-------- Examples/orm_vs/orm_vs.csproj | 3 ++- Examples/orm_vs_net40/Program.cs | 13 +++++++++-- Examples/orm_vs_net40/orm_vs_net40.csproj | 3 +++ FreeSql/FreeSql.xml | 21 ++++++++++++++++++ 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 3fdc979b..781eb77a 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -15,8 +15,8 @@ namespace orm_vs class Program { static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") - .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=20") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + //.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=20") .UseAutoSyncStructure(false) .UseNoneCommandParameter(true) //.UseConfigEntityFromDbFirst(true) @@ -27,10 +27,10 @@ namespace orm_vs get => new SqlSugarClient(new ConnectionConfig() { //不欺负,让连接池100个最小 - //ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", - //DbType = DbType.SqlServer, - ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", - DbType = DbType.MySql, + ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + DbType = DbType.SqlServer, + //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + //DbType = DbType.MySql, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute }); @@ -41,8 +41,8 @@ namespace orm_vs public DbSet Songs { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - //optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); - optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); + optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); + //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); } } @@ -175,7 +175,16 @@ namespace orm_vs } } sw.Stop(); - sb.AppendLine($"EFCore Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); + sb.AppendLine($"EFCore Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + + sw.Restart(); + using (var conn = fsql.Ado.MasterPool.Get()) + { + for (var a = 0; a < forTime; a++) + Dapper.SqlMapper.Query(conn.Value, $"select top {size} * from freesql_song").ToList(); + } + sw.Stop(); + sb.AppendLine($"Dapper Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); } static void Insert(StringBuilder sb, int forTime, int size) diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index 8a489e1f..e0ff4ea9 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -6,6 +6,7 @@ + @@ -13,8 +14,8 @@ - + diff --git a/Examples/orm_vs_net40/Program.cs b/Examples/orm_vs_net40/Program.cs index 9db52e73..3fbc062d 100644 --- a/Examples/orm_vs_net40/Program.cs +++ b/Examples/orm_vs_net40/Program.cs @@ -12,8 +12,8 @@ namespace orm_vs class Program { static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") - .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=20") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + //.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=20") .UseAutoSyncStructure(false) .UseNoneCommandParameter(true) //.UseConfigEntityFromDbFirst(true) @@ -146,6 +146,15 @@ namespace orm_vs // sugar.Queryable().Take(size).ToList(); //sw.Stop(); //sb.AppendLine($"SqlSugar Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + + sw.Restart(); + using (var conn = fsql.Ado.MasterPool.Get()) + { + for (var a = 0; a < forTime; a++) + Dapper.SqlMapper.Query(conn.Value, $"select top {size} * from freesql_song").ToList(); + } + sw.Stop(); + sb.AppendLine($"Dapper Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); } static void Insert(StringBuilder sb, int forTime, int size) diff --git a/Examples/orm_vs_net40/orm_vs_net40.csproj b/Examples/orm_vs_net40/orm_vs_net40.csproj index 223dc56b..a146a664 100644 --- a/Examples/orm_vs_net40/orm_vs_net40.csproj +++ b/Examples/orm_vs_net40/orm_vs_net40.csproj @@ -63,6 +63,9 @@ + + 1.50.2 + 12.0.3 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 295cad26..53d45057 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2023,6 +2023,16 @@ 新值 + + + 设置列的新值,Set(a => a.Name, "newvalue") + + + true 时生效 + lambda选择列 + 新值 + + 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 @@ -2033,6 +2043,17 @@ + + + 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + + 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + + + true 时生效 + + + 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) From 2a3febdad5002df7ba9fef904529137d6008ef6b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 15 May 2020 00:20:53 +0800 Subject: [PATCH 0639/1029] remove orm_vs demo dameng --- Examples/orm_vs/Program.cs | 15 --------------- Examples/orm_vs/orm_vs.csproj | 1 - Examples/orm_vs_net40/Program.cs | 16 ---------------- Examples/orm_vs_net40/orm_vs_net40.csproj | 4 ---- 4 files changed, 36 deletions(-) diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 781eb77a..e962615a 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -46,23 +46,8 @@ namespace orm_vs } } - static Lazy damengLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Dameng, "server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user") - //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;Max Pool Size=2")) - .UseAutoSyncStructure(true) - .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) - //.UseNoneCommandParameter(true) - - .UseMonitorCommand( - cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 - (cmd, traceLog) => Console.WriteLine(traceLog)) - .Build()); - public static IFreeSql dameng => damengLazy.Value; - static void Main(string[] args) { - dameng.Select().ToList(); - var testlist1 = fsql.Select().OrderBy(a => a.Id).ToList(); var testlist2 = new List(); fsql.Select().OrderBy(a => a.Id).ToChunk(0, list => diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index e0ff4ea9..c691f109 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -15,7 +15,6 @@ - diff --git a/Examples/orm_vs_net40/Program.cs b/Examples/orm_vs_net40/Program.cs index 3fbc062d..6e080b94 100644 --- a/Examples/orm_vs_net40/Program.cs +++ b/Examples/orm_vs_net40/Program.cs @@ -33,24 +33,8 @@ namespace orm_vs // }); //} - static Lazy damengLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Dameng, "server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user") - //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;Max Pool Size=2")) - .UseAutoSyncStructure(true) - .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) - //.UseNoneCommandParameter(true) - - .UseMonitorCommand( - cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 - (cmd, traceLog) => Console.WriteLine(traceLog)) - .Build()); - public static IFreeSql dameng => damengLazy.Value; - static void Main(string[] args) { - dameng.Select().ToList(); - - fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements diff --git a/Examples/orm_vs_net40/orm_vs_net40.csproj b/Examples/orm_vs_net40/orm_vs_net40.csproj index a146a664..42978d4e 100644 --- a/Examples/orm_vs_net40/orm_vs_net40.csproj +++ b/Examples/orm_vs_net40/orm_vs_net40.csproj @@ -49,10 +49,6 @@ {af9c50ec-6eb6-494b-9b3b-7edba6fd0ebb} FreeSql - - {e74d90e8-1cbc-4677-817b-1ca05ab97937} - FreeSql.Provider.Dameng - {28c6a39c-7ae7-4210-b7b0-0970216637a8} FreeSql.Provider.MySql From 0991464fd054984a0c46c7f7bcd9933ef788bc09 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 15 May 2020 13:27:44 +0800 Subject: [PATCH 0640/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IUpdate.Set(?= =?UTF-8?q?a=20=3D>=20a.xx=20=3D=20null)=20=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20bug=EF=BC=9B#311?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++++ .../MySqlAdoTest.cs | 71 ++++++++++++++----- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 3 + .../Dameng/Curd/DamengUpdateTest.cs | 3 + .../Default/Curd/OdbcUpdateTest.cs | 3 + .../MySql/Curd/MySqlUpdateTest.cs | 3 + .../Oracle/Curd/OracleUpdateTest.cs | 3 + .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 3 + .../SqlServer/Curd/SqlServerUpdateTest.cs | 3 + .../Dameng/Curd/DamengUpdateTest.cs | 3 + .../MsAccess/Curd/MsAccessUpdateTest.cs | 3 + .../MySql/Curd/MySqlUpdateTest.cs | 3 + .../Oracle/Curd/OracleUpdateTest.cs | 3 + .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 3 + .../SqlServer/Curd/SqlServerUpdateTest.cs | 3 + .../Sqlite/Curd/SqliteUpdateTest.cs | 3 + .../SelectProvider/Select0Provider.cs | 5 +- .../Internal/CommonProvider/UpdateProvider.cs | 4 +- FreeSql/Internal/UtilsExpressionTree.cs | 28 ++++---- 19 files changed, 130 insertions(+), 36 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs index 147241ad..315279e9 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Collections.Generic; using System.Threading.Tasks; using System.Threading; +using FreeSql.Internal; namespace FreeSql.Tests.PerformanceTest { @@ -24,7 +25,7 @@ namespace FreeSql.Tests.PerformanceTest List dplist1 = null; using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); + dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song").ToList(); } time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); @@ -33,7 +34,7 @@ namespace FreeSql.Tests.PerformanceTest List<(int, string, string)> dplist2 = null; using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist2 = Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from song").ToList(); + dplist2 = Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from freesql_song").ToList(); } time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {dplist2.Count}; ORM: Dapper"); @@ -42,7 +43,7 @@ namespace FreeSql.Tests.PerformanceTest List dplist3 = null; using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist3 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); + dplist3 = Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song").ToList(); } time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {dplist3.Count}; ORM: Dapper"); @@ -50,15 +51,15 @@ namespace FreeSql.Tests.PerformanceTest - var t31 = g.mysql.Ado.Query("select * from song limit 1"); + var t31 = g.mysql.Ado.Query("select * from freesql_song limit 1"); time.Restart(); - var t3 = g.mysql.Ado.Query("select * from song"); + var t3 = g.mysql.Ado.Query("select * from freesql_song"); time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {t3.Count}; ORM: FreeSql*"); time.Restart(); - var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from freesql_song"); time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*"); @@ -68,7 +69,7 @@ namespace FreeSql.Tests.PerformanceTest sb.AppendLine($"Elapsed: {time.Elapsed}; Query ToList Counts: {t41.Count}; ORM: FreeSql*"); time.Restart(); - var t5 = g.mysql.Ado.Query("select * from song"); + var t5 = g.mysql.Ado.Query("select * from freesql_song"); time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*"); @@ -86,7 +87,7 @@ namespace FreeSql.Tests.PerformanceTest { using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist1.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 10").ToList()); + dplist1.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song limit 10").ToList()); } } time.Stop(); @@ -98,7 +99,7 @@ namespace FreeSql.Tests.PerformanceTest { using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist2.AddRange(Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from song limit 10").ToList()); + dplist2.AddRange(Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from freesql_song limit 10").ToList()); } } time.Stop(); @@ -110,7 +111,7 @@ namespace FreeSql.Tests.PerformanceTest { using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist3.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 10").ToList()); + dplist3.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song limit 10").ToList()); } } time.Stop(); @@ -123,7 +124,7 @@ namespace FreeSql.Tests.PerformanceTest List t3 = new List(); for (var a = 0; a < 10000; a++) { - t3.AddRange(g.mysql.Ado.Query("select * from song limit 10")); + t3.AddRange(g.mysql.Ado.Query("select * from freesql_song limit 10")); } time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {t3.Count}; ORM: FreeSql*"); @@ -132,7 +133,7 @@ namespace FreeSql.Tests.PerformanceTest List<(int, string, string)> t4 = new List<(int, string, string)>(); for (var a = 0; a < 10000; a++) { - t4.AddRange(g.mysql.Ado.Query<(int, string, string)>("select * from song limit 10")); + t4.AddRange(g.mysql.Ado.Query<(int, string, string)>("select * from freesql_song limit 10")); } time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*"); @@ -141,7 +142,7 @@ namespace FreeSql.Tests.PerformanceTest List t5 = new List(); for (var a = 0; a < 10000; a++) { - t5.AddRange(g.mysql.Ado.Query("select * from song limit 10")); + t5.AddRange(g.mysql.Ado.Query("select * from freesql_song limit 10")); } time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*"); @@ -155,17 +156,53 @@ namespace FreeSql.Tests.PerformanceTest var time = new Stopwatch(); //var t31 = g.mysql.Select().ToList(); + g.mysql.Select().First(); time.Restart(); var t3 = g.mysql.Select().ToList(); time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); + time.Restart(); + var adoarr1 = g.mysql.Ado.ExecuteArray("select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteArray Entity Counts: {adoarr1.Length}; ORM: FreeSql ExecuteArray*"); + + time.Restart(); + var adolist1 = new List(); + g.mysql.Ado.ExecuteReader(dr => + { + var xim = new xxx(); + var val1 = dr.GetValue(0); + if (val1 is int) ; + val1 = int.Parse(string.Format("{0}", val1)); + xim.Id = (int)val1; + val1 = dr.GetValue(1); + if (val1 is DateTime) ; + val1 = (DateTime)val1; + xim.Create_time = (DateTime)val1; + val1 = dr.GetValue(2); + if (val1 is int) ; + val1 = int.Parse(string.Format("{0}", val1)) != 0; + xim.Is_deleted = (bool)val1; + val1 = dr.GetValue(3); + if (val1 is string) ; + val1 = (string)val1; + xim.Title = (string)val1; + val1 = dr.GetValue(4); + if (val1 is string) ; + val1 = (string)val1; + xim.Title = (string)val1; + adolist1.Add(xim); + }, "select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader*"); + time.Restart(); List dplist1 = null; using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from song").ToList(); + dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song").ToList(); } time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); @@ -201,7 +238,7 @@ namespace FreeSql.Tests.PerformanceTest { using (var conn = g.mysql.Ado.MasterPool.Get()) { - dplist1.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from song limit 50").ToList()); + dplist1.AddRange(Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song limit 50").ToList()); } } Interlocked.Add(ref dplist1Count, dplist1.Count); @@ -211,12 +248,12 @@ namespace FreeSql.Tests.PerformanceTest sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1Count}; ORM: Dapper"); } - [Table(Name = "song")] + [Table(Name = "freesql_song")] class xxx { public int Id { get; set; } public string Title { get; set; } - //public string Url { get; set; } + public string Url { get; set; } public DateTime Create_time { get; set; } public bool Is_deleted { get; set; } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 441fdfd5..69bbb16c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -148,6 +148,9 @@ namespace FreeSql.Tests.MySqlConnector sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = NULL WHERE (`Id` = 1)", sql); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); Assert.True(id > 0); sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs index eb9c649d..8d77def2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs @@ -115,6 +115,9 @@ namespace FreeSql.Tests.Odbc.Dameng sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs index e70ff06e..0754dca8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs @@ -107,6 +107,9 @@ namespace FreeSql.Tests.Odbc.Default sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL WHERE ([Id] = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs index ac8f603f..5c25af37 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -148,6 +148,9 @@ namespace FreeSql.Tests.Odbc.MySql sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = NULL WHERE (`Id` = 1)", sql); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); Assert.True(id > 0); sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs index a4ae7706..f98c637a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -105,6 +105,9 @@ namespace FreeSql.Tests.Odbc.Oracle sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 854481d5..fab9e9a8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -106,6 +106,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = 10 WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = NULL WHERE (\"id\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs index 1ea9b81a..882a52fa 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs @@ -108,6 +108,9 @@ namespace FreeSql.Tests.Odbc.SqlServer sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL WHERE ([Id] = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs index d9160ab9..d1285cbb 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs @@ -115,6 +115,9 @@ namespace FreeSql.Tests.Dameng sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs index 4b6c188d..87a4ffee 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs @@ -117,6 +117,9 @@ namespace FreeSql.Tests.MsAccess sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL WHERE ([Id] = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index b216d48b..0d3e1218 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -149,6 +149,9 @@ namespace FreeSql.Tests.MySql sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = NULL WHERE (`Id` = 1)", sql); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); Assert.True(id > 0); sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 67c163f2..5b35fe60 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -105,6 +105,9 @@ namespace FreeSql.Tests.Oracle sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 5b574ff6..602195ff 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -107,6 +107,9 @@ namespace FreeSql.Tests.PostgreSQL sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = 10 WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = NULL WHERE (\"id\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 38e8a77a..0bbb6a58 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -118,6 +118,9 @@ namespace FreeSql.Tests.SqlServer sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL WHERE ([Id] = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index 7089325b..577637c5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -124,6 +124,9 @@ namespace FreeSql.Tests.Sqlite sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"Id\" = 10 WHERE (\"Id\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"Clicks\" = NULL WHERE (\"Id\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 42af114d..9bbe5cea 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1063,10 +1063,7 @@ namespace FreeSql.Internal.CommonProvider { var firstTb = _tables[0]; var firstTbs = _tables.Where(a => a.AliasInit == field[0]).ToArray(); - if (firstTbs.Length == 1) - { - firstTb = firstTbs[0]; - } + if (firstTbs.Length == 1) firstTb = firstTbs[0]; firstTb.Parameter = Expression.Parameter(firstTb.Table.Type, firstTb.Alias); var currentType = firstTb.Table.Type; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 1a7cf8ab..e6307337 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -409,7 +409,9 @@ namespace FreeSql.Internal.CommonProvider { case ExpressionType.Equal: var equalBinaryExp = body as BinaryExpression; - _set.Append(", ").Append(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, body, null, null)); + var eqval = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, body, null, null); + if (eqval.EndsWith(" IS NULL")) eqval = $"{eqval.Remove(eqval.Length - 10)} = NULL"; //issues/311 + _set.Append(", ").Append(eqval); return this; case ExpressionType.MemberInit: var initExp = body as MemberInitExpression; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 3d7401d3..7bbd8a63 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1363,10 +1363,10 @@ namespace FreeSql.Internal Expression.Block( Expression.IfThen( Expression.LessThan(dataIndexExp, rowLenExp), - Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, - GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), - //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), - Expression.Add(dataIndexExp, Expression.Constant(1)))) + Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, + GetDataReaderValueBlockExpression(type, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp })), + //Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, dataIndexExp }) }), + Expression.Add(dataIndexExp, Expression.Constant(1)))) ), Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) ), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); @@ -1442,7 +1442,7 @@ namespace FreeSql.Internal Expression.IfThen( Expression.AndAlso( Expression.IsFalse(readpknullExp), - Expression.Or( + Expression.OrElse( Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), Expression.Equal(readpkvalExp, Expression.Constant(null)) ) @@ -1550,7 +1550,7 @@ namespace FreeSql.Internal Expression.IfThen( Expression.AndAlso( Expression.IsFalse(readpknullExp), - Expression.Or( + Expression.OrElse( Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), Expression.Equal(readpkvalExp, Expression.Constant(null)) ) @@ -1718,7 +1718,7 @@ namespace FreeSql.Internal Expression.TypeEqual(valueExp, typeof(string)), Expression.Return(returnTarget, Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetBytes, Expression.Convert(valueExp, typeof(string)))), Expression.IfThenElse( - Expression.Or(Expression.TypeEqual(valueExp, typeof(Guid)), Expression.TypeEqual(valueExp, typeof(Guid?))), + Expression.OrElse(Expression.TypeEqual(valueExp, typeof(Guid)), Expression.TypeEqual(valueExp, typeof(Guid?))), Expression.Return(returnTarget, Expression.Call(MethodGuidToBytes, Expression.Convert(valueExp, typeof(Guid)))), Expression.Return(returnTarget, Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetBytes, Expression.Call(MethodToString, valueExp))) ) @@ -1969,11 +1969,11 @@ namespace FreeSql.Internal break; case "System.Boolean": tryparseBooleanExp = Expression.Return(returnTarget, - Expression.Convert( - Expression.Not( - Expression.Or( - Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("False")), - Expression.Or( + Expression.Convert( + Expression.Not( + Expression.OrElse( + Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("False")), + Expression.OrElse( Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("false")), Expression.Equal(Expression.Convert(valueExp, typeof(string)), Expression.Constant("0"))))), typeof(object)) @@ -2027,7 +2027,7 @@ namespace FreeSql.Internal Expression.IfThenElse( Expression.TypeEqual(valueExp, typeof(byte[])), Expression.IfThenElse( - Expression.Or(Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(Guid))), Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(Guid?)))), + Expression.OrElse(Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(Guid))), Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(Guid?)))), Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodBytesToGuid, Expression.Convert(valueExp, typeof(byte[]))), typeof(object))), Expression.IfThenElse( Expression.Equal(Expression.Constant(type), Expression.Constant(typeof(string))), @@ -2047,7 +2047,7 @@ namespace FreeSql.Internal new[] { valueExp }, Expression.Assign(valueExp, Expression.Convert(value, typeof(object))), Expression.IfThenElse( - Expression.Or( + Expression.OrElse( Expression.Equal(valueExp, Expression.Constant(null)), Expression.Equal(valueExp, Expression.Constant(DBNull.Value)) ), From 8b908bb6fe053530d13ee8d921bba9137d69845d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 15 May 2020 18:01:51 +0800 Subject: [PATCH 0641/1029] update ado.net version --- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 4 ++-- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 80d212da..2ed762f8 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index f1522623..66a5bfd9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f6af1e14..cd281049 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 2f123c2d..15ec7535 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -26,11 +26,11 @@ - + - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5af96c3e..2bd210ab 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -26,7 +26,7 @@ - + From 148724e2296fe7ee4db5983567a747e181069d72 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 17 May 2020 01:34:06 +0800 Subject: [PATCH 0642/1029] update IUpdate.SetDto summary --- Examples/orm_vs/Program.cs | 297 +++++++++++++++++- .../MySqlAdoTest.cs | 56 ++-- FreeSql/Interface/Curd/IUpdate.cs | 9 +- 3 files changed, 335 insertions(+), 27 deletions(-) diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index e962615a..e4fe2bc0 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -1,11 +1,14 @@ -using Microsoft.EntityFrameworkCore; +using FreeSql.Internal; +using Microsoft.EntityFrameworkCore; using SqlSugar; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Data.Common; using System.Diagnostics; using System.Linq; +using System.Linq.Expressions; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -48,6 +51,297 @@ namespace orm_vs static void Main(string[] args) { + var sb = new StringBuilder(); + var time = new Stopwatch(); + + //var t31 = fsql.Select().ToList(); + fsql.Select().First(); + + time.Restart(); + var t3 = fsql.Select().ToList(); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); + + time.Restart(); + var adoarr1 = fsql.Ado.ExecuteArray("select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteArray Entity Counts: {adoarr1.Length}; ORM: FreeSql ExecuteArray*"); + + time.Restart(); + var adolist1 = new List(); + fsql.Ado.ExecuteReader(dr => + { + var xim = new Song(); + dr.GetValue(0)?.GetType(); + dr.GetValue(1)?.GetType(); + dr.GetValue(2)?.GetType(); + dr.GetValue(3)?.GetType(); + dr.GetValue(4)?.GetType(); + adolist1.Add(xim); + }, "select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader*"); + + + time.Restart(); + adolist1 = new List(); + fsql.Ado.ExecuteReader(dr => + { + var xim = new Song(); + var v1 = dr.GetValue(0); + var locvalue = (object)v1; + if (locvalue == null || locvalue == DBNull.Value) xim.Id = default; + else + { + if (locvalue is int iv) xim.Id = iv; + else + { + if (locvalue is string) + { + + } + } + } + v1 = dr.GetValue(1); + locvalue = (object)v1; + if (locvalue == null || locvalue == DBNull.Value) xim.Create_time = default; + else + { + if (locvalue is DateTime dt) xim.Create_time = dt; + else + { + if (locvalue is string) + { + + } + } + } + v1 = dr.GetValue(2); + locvalue = (object)v1; + if (locvalue == null || locvalue == DBNull.Value) xim.Is_deleted = default; + else + { + if (locvalue is bool bl) xim.Is_deleted = bl; + else + { + if (locvalue is string) + { + + } + } + } + v1 = dr.GetValue(3); + locvalue = (object)v1; + if (locvalue == null || locvalue == DBNull.Value) xim.Title = default; + else + { + if (locvalue is string str) xim.Title = str; + else + { + if (locvalue is string) + { + + } + } + } + v1 = dr.GetValue(4); + locvalue = (object)v1; + if (locvalue == null || locvalue == DBNull.Value) xim.Url = default; + else + { + if (locvalue is string str) xim.Url = str; + else + { + if (locvalue is string) + { + + } + } + } + adolist1.Add(xim); + }, "select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderObject Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderObject*"); + + //var type = typeof(Song); + //var myfuncParam1 = Expression.Parameter(typeof(object[]), "values"); + //var retExp = Expression.Variable(type, "ret"); + //var objExp = Expression.Variable(typeof(object), "obj"); + //var returnTarget = Expression.Label(type); + //var myfuncBody = Expression.Block( + // new[] { retExp, objExp }, + // Expression.Assign(retExp, type.InternalNewExpression()), + // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(0))), + // Utils.GetConvertExpression(type.GetProperty("Id").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Id")), Expression.Convert(objExp, type.GetProperty("Id").PropertyType)), + // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(1))), + // Utils.GetConvertExpression(type.GetProperty("Create_time").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Create_time")), Expression.Convert(objExp, type.GetProperty("Create_time").PropertyType)), + // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(2))), + // Utils.GetConvertExpression(type.GetProperty("Is_deleted").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Is_deleted")), Expression.Convert(objExp, type.GetProperty("Is_deleted").PropertyType)), + // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(3))), + // Utils.GetConvertExpression(type.GetProperty("Title").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Title")), Expression.Convert(objExp, type.GetProperty("Title").PropertyType)), + // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(4))), + // Utils.GetConvertExpression(type.GetProperty("Url").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Url")), Expression.Convert(objExp, type.GetProperty("Url").PropertyType)), + // Expression.Return(returnTarget, retExp), + // Expression.Label(returnTarget, Expression.Default(type)) + //); + //var myfunc = Expression.Lambda>(myfuncBody, myfuncParam1).Compile(); + //time.Restart(); + //adolist1 = new List(); + //fsql.Ado.ExecuteReader(dr => + //{ + // var values = new object[dr.FieldCount]; + // dr.GetValues(values); + // var xim = myfunc(values); + // adolist1.Add(xim); + //}, "select * from freesql_song"); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderMyFunc Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderMyFunc*"); + + + //var methodDrgv = typeof(DbDataReader).GetMethod("GetValue"); + //var myfunc2Param1 = Expression.Parameter(typeof(DbDataReader), "dr"); + //var myfunc2Body = Expression.Block( + // new[] { retExp, objExp }, + // Expression.Assign(retExp, type.InternalNewExpression()), + // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(0))), + // Utils.GetConvertExpression(type.GetProperty("Id").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Id")), Expression.Convert(objExp, type.GetProperty("Id").PropertyType)), + // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(1))), + // Utils.GetConvertExpression(type.GetProperty("Create_time").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Create_time")), Expression.Convert(objExp, type.GetProperty("Create_time").PropertyType)), + // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(2))), + // Utils.GetConvertExpression(type.GetProperty("Is_deleted").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Is_deleted")), Expression.Convert(objExp, type.GetProperty("Is_deleted").PropertyType)), + // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(3))), + // Utils.GetConvertExpression(type.GetProperty("Title").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Title")), Expression.Convert(objExp, type.GetProperty("Title").PropertyType)), + // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(4))), + // Utils.GetConvertExpression(type.GetProperty("Url").PropertyType, objExp), + // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Url")), Expression.Convert(objExp, type.GetProperty("Url").PropertyType)), + // Expression.Return(returnTarget, retExp), + // Expression.Label(returnTarget, Expression.Default(type)) + //); + //var myfunc2 = Expression.Lambda>(myfunc2Body, myfunc2Param1).Compile(); + //time.Restart(); + //adolist1 = new List(); + //fsql.Ado.ExecuteReader(dr => + //{ + // var xim = myfunc2(dr); + // adolist1.Add(xim); + //}, "select * from freesql_song"); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderMyFunc22 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderMyFunc22*"); + + + time.Restart(); + adolist1 = new List(); + fsql.Ado.ExecuteReader(dr => + { + var xim = new Song(); + dr.GetFieldValue(0); + dr.GetFieldValue(1); + dr.GetFieldValue(2); + dr.GetFieldValue(3); + dr.GetFieldValue(4); + adolist1.Add(xim); + }, "select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader0000 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader0000*"); + + time.Restart(); + adolist1 = new List(); + fsql.Ado.ExecuteReader(dr => + { + var xim = new Song(); + Utils.GetDataReaderValue(typeof(int), dr.GetValue(0)); + Utils.GetDataReaderValue(typeof(DateTime), dr.GetValue(1)); + Utils.GetDataReaderValue(typeof(bool), dr.GetValue(2)); + Utils.GetDataReaderValue(typeof(string), dr.GetValue(3)); + Utils.GetDataReaderValue(typeof(string), dr.GetValue(4)); + adolist1.Add(xim); + }, "select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader1111 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader1111*"); + + + //time.Restart(); + //adolist1 = new List(); + //fsql.Ado.ExecuteReader(dr => + //{ + // var xim = new Song(); + // Utils.GetConvertValue(typeof(int), dr.GetValue(0)); + // Utils.GetConvertValue(typeof(DateTime), dr.GetValue(1)); + // Utils.GetConvertValue(typeof(bool), dr.GetValue(2)); + // Utils.GetConvertValue(typeof(string), dr.GetValue(3)); + // Utils.GetConvertValue(typeof(string), dr.GetValue(4)); + // adolist1.Add(xim); + //}, "select * from freesql_song"); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader11112222 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader11112222*"); + + + time.Restart(); + adolist1 = new List(); + fsql.Ado.ExecuteReader(dr => + { + var values = new object[dr.FieldCount]; + dr.GetValues(values); + + var xim = new Song(); + xim.Id = (int)Utils.GetDataReaderValue(typeof(int), values[0]); + xim.Create_time = (DateTime)Utils.GetDataReaderValue(typeof(DateTime), values[1]); + xim.Is_deleted = (bool)Utils.GetDataReaderValue(typeof(bool), values[2]); + xim.Title = (string)Utils.GetDataReaderValue(typeof(string), values[3]); + xim.Url = (string)Utils.GetDataReaderValue(typeof(string), values[4]); + adolist1.Add(xim); + }, "select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader1111 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader1111*"); + + + //time.Restart(); + //adolist1 = new List(); + //fsql.Ado.ExecuteReader(dr => + //{ + // var values = new object[dr.FieldCount]; + // dr.GetValues(values); + + // var xim = new Song(); + // xim.Id = (int)Utils.GetConvertValue(typeof(int), values[0]); + // xim.Create_time = (DateTime)Utils.GetConvertValue(typeof(DateTime), values[1]); + // xim.Is_deleted = (bool)Utils.GetConvertValue(typeof(bool), values[2]); + // xim.Title = (string)Utils.GetConvertValue(typeof(string), values[3]); + // xim.Url = (string)Utils.GetConvertValue(typeof(string), values[4]); + // adolist1.Add(xim); + //}, "select * from freesql_song"); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader11112222 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader11112222*"); + + + time.Restart(); + List dplist1 = null; + using (var conn = fsql.Ado.MasterPool.Get()) + { + dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song").ToList(); + } + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); + + time.Restart(); + t3 = fsql.Select().ToList(); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); + + Console.WriteLine(sb.ToString()); + Console.ReadKey(); + + return; + var testlist1 = fsql.Select().OrderBy(a => a.Id).ToList(); var testlist2 = new List(); fsql.Select().OrderBy(a => a.Id).ToChunk(0, list => @@ -68,7 +362,6 @@ namespace orm_vs sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); fsql.Ado.ExecuteNonQuery("delete from efcore_song"); - var sb = new StringBuilder(); Console.WriteLine("插入性能:"); Insert(sb, 1000, 1); Console.Write(sb.ToString()); diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs index 315279e9..3a792b77 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs @@ -173,31 +173,47 @@ namespace FreeSql.Tests.PerformanceTest g.mysql.Ado.ExecuteReader(dr => { var xim = new xxx(); - var val1 = dr.GetValue(0); - if (val1 is int) ; - val1 = int.Parse(string.Format("{0}", val1)); - xim.Id = (int)val1; - val1 = dr.GetValue(1); - if (val1 is DateTime) ; - val1 = (DateTime)val1; - xim.Create_time = (DateTime)val1; - val1 = dr.GetValue(2); - if (val1 is int) ; - val1 = int.Parse(string.Format("{0}", val1)) != 0; - xim.Is_deleted = (bool)val1; - val1 = dr.GetValue(3); - if (val1 is string) ; - val1 = (string)val1; - xim.Title = (string)val1; - val1 = dr.GetValue(4); - if (val1 is string) ; - val1 = (string)val1; - xim.Title = (string)val1; + dr.GetValue(0); + dr.GetValue(1); + dr.GetValue(2); + dr.GetValue(3); + dr.GetValue(4); adolist1.Add(xim); }, "select * from freesql_song"); time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader*"); + time.Restart(); + adolist1 = new List(); + g.mysql.Ado.ExecuteReader(dr => + { + var xim = new xxx(); + dr.GetFieldValue(0); + dr.GetFieldValue(1); + dr.GetFieldValue(2); + dr.GetFieldValue(3); + dr.GetFieldValue(4); + adolist1.Add(xim); + }, "select * from freesql_song"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader0000 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader0000*"); + + //time.Restart(); + //adolist1 = new List(); + //g.mysql.Ado.ExecuteReader(dr => + //{ + // var xim = new xxx(); + // Utils.GetDataReaderValue(typeof(int), dr.GetValue(0)); + // Utils.GetDataReaderValue(typeof(DateTime), dr.GetValue(1)); + // Utils.GetDataReaderValue(typeof(bool), dr.GetValue(2)); + // Utils.GetDataReaderValue(typeof(string), dr.GetValue(3)); + // Utils.GetDataReaderValue(typeof(string), dr.GetValue(4)); + // adolist1.Add(xim); + //}, "select * from freesql_song"); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader1111 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader1111*"); + + time.Restart(); List dplist1 = null; using (var conn = g.mysql.Ado.MasterPool.Get()) diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 289f3096..4d40419e 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -129,11 +129,10 @@ namespace FreeSql IUpdate SetRaw(string sql, object parms = null); /// - /// 设置更新的列 - /// - /// SetDto(new { title = "xxx", clicks = 2 }) - /// - /// SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + /// 设置更新的列 + /// SetDto(new { title = "xxx", clicks = 2 }) + /// SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + /// 注意:标记 [Column(CanUpdate = false)] 的属性不会被更新 /// /// dto 或 Dictionary<string, object> /// From 70fd324cf317535f7d98d753899c9150bcaca58f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 19 May 2020 15:48:39 +0800 Subject: [PATCH 0643/1029] =?UTF-8?q?-=20=E6=95=B4=E7=90=86=20IInsert/IUpd?= =?UTF-8?q?ate=20=E5=88=86=E6=89=B9=E5=8F=82=E6=95=B0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Curd/DamengInsert.cs | 6 +- .../Curd/DamengUpdate.cs | 4 +- .../Curd/MsAccessInsert.cs | 6 +- .../Curd/MsAccessUpdate.cs | 4 +- .../Curd/MySqlInsert.cs | 6 +- .../Curd/MySqlUpdate.cs | 4 +- .../Dameng/Curd/OdbcDamengInsert.cs | 6 +- .../Dameng/Curd/OdbcDamengUpdate.cs | 4 +- .../Default/Curd/OdbcInsert.cs | 14 ++-- .../Default/Curd/OdbcUpdate.cs | 8 +-- .../MySql/Curd/OdbcMySqlInsert.cs | 8 +-- .../MySql/Curd/OdbcMySqlUpdate.cs | 4 +- .../Oracle/Curd/OdbcOracleInsert.cs | 6 +- .../Oracle/Curd/OdbcOracleUpdate.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 8 +-- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 6 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 69 +++---------------- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 4 +- .../Curd/OracleInsert.cs | 6 +- .../Curd/OracleUpdate.cs | 4 +- .../Curd/PostgreSQLInsert.cs | 6 +- .../Curd/PostgreSQLUpdate.cs | 4 +- .../Curd/SqlServerInsert.cs | 6 +- .../Curd/SqlServerUpdate.cs | 6 +- .../Curd/SqliteInsert.cs | 6 +- .../Curd/SqliteUpdate.cs | 4 +- 26 files changed, 83 insertions(+), 130 deletions(-) diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index 74b1bd6b..addd7d09 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -151,9 +151,9 @@ namespace FreeSql.Dameng.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); async protected override Task RawExecuteIdentityAsync() { diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs index db636a0f..97f8d70c 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs @@ -65,8 +65,8 @@ namespace FreeSql.Dameng.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs index 987a05ca..0e2950f1 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs @@ -102,9 +102,9 @@ namespace FreeSql.MsAccess.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1, 1000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1, 1000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1, 1000); async protected override Task RawExecuteAffrowsAsync() { diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs index 6a70a096..03fa7091 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs @@ -68,8 +68,8 @@ namespace FreeSql.MsAccess.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1, 1000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(1, 1000); protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 190e6b7e..6e7d5cae 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -106,9 +106,9 @@ namespace FreeSql.MySql.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); async protected override Task RawExecuteIdentityAsync() { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 084553f0..4f8c1178 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -106,8 +106,8 @@ namespace FreeSql.MySql.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); async protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index ab779a18..01bb6ae5 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -151,9 +151,9 @@ namespace FreeSql.Odbc.Dameng #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); async protected override Task RawExecuteIdentityAsync() { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs index 22aa2504..847863bb 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -66,8 +66,8 @@ namespace FreeSql.Odbc.Dameng #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index 3abd6fd4..823d76ed 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -19,9 +19,9 @@ namespace FreeSql.Odbc.Default _utils = _commonUtils as OdbcUtils; } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(_utils.Adapter.InsertBatchSplitLimit, 255); - public override long ExecuteIdentity() => base.SplitExecuteIdentity(_utils.Adapter.InsertBatchSplitLimit, 255); - public override List ExecuteInserted() => base.SplitExecuteInserted(_utils.Adapter.InsertBatchSplitLimit, 255); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); protected override long RawExecuteIdentity() { @@ -65,10 +65,10 @@ namespace FreeSql.Odbc.Default #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_utils.Adapter.InsertBatchSplitLimit, 255); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_utils.Adapter.InsertBatchSplitLimit, 255); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_utils.Adapter.InsertBatchSplitLimit, 255); - + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs index b24bb642..e33c4a14 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs @@ -19,8 +19,8 @@ namespace FreeSql.Odbc.Default _utils = _commonUtils as OdbcUtils; } - public override int ExecuteAffrows() => base.SplitExecuteAffrows(_utils.Adapter.InsertBatchSplitLimit, 255); - public override List ExecuteUpdated() => base.SplitExecuteUpdated(_utils.Adapter.InsertBatchSplitLimit, 255); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); protected override List RawExecuteUpdated() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); @@ -61,8 +61,8 @@ namespace FreeSql.Odbc.Default #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_utils.Adapter.InsertBatchSplitLimit, 255); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_utils.Adapter.InsertBatchSplitLimit, 255); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); protected override Task> RawExecuteUpdatedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); #endif diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index 88a9c9b5..a99cfaf4 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -98,10 +98,10 @@ namespace FreeSql.Odbc.MySql #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); - + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index 4613ed9d..2b12d47c 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -100,8 +100,8 @@ namespace FreeSql.Odbc.MySql #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); async protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index da47a7a5..0f2af13a 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -151,9 +151,9 @@ namespace FreeSql.Odbc.Oracle #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); async protected override Task RawExecuteIdentityAsync() { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index 97f4f680..9e52f3c7 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -66,8 +66,8 @@ namespace FreeSql.Odbc.Oracle #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index a2a2a2a2..4d457731 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -109,10 +109,10 @@ namespace FreeSql.Odbc.PostgreSQL #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); - + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 8bb51100..f6e79b76 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -108,9 +108,9 @@ namespace FreeSql.Odbc.PostgreSQL #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); - + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + async protected override Task> RawExecuteUpdatedAsync() { var sql = this.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 8c8fd511..391105d1 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -21,34 +21,14 @@ namespace FreeSql.Odbc.SqlServer public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); - protected override int RawExecuteAffrows() + public override string ToSql() { var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try - { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return affrows; + return this.ToSqlValuesOrSelectUnionAll(versionGreaterThan10); } protected override long RawExecuteIdentity() { - var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); @@ -74,8 +54,7 @@ namespace FreeSql.Odbc.SqlServer } protected override List RawExecuteInserted() { - var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); @@ -88,7 +67,7 @@ namespace FreeSql.Odbc.SqlServer ++colidx; } - if (versionGreaterThan10) + if ((_commonUtils as OdbcSqlServerUtils).ServerVersion > 10) { var validx = sql.IndexOf(") VALUES"); if (validx == -1) throw new ArgumentException("找不到 VALUES"); @@ -127,38 +106,13 @@ namespace FreeSql.Odbc.SqlServer #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); - async protected override Task RawExecuteAffrowsAsync() - { - var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var affrows = 0; - Exception exception = null; - try - { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, affrows); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return affrows; - } async protected override Task RawExecuteIdentityAsync() { - var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); @@ -184,8 +138,7 @@ namespace FreeSql.Odbc.SqlServer } async protected override Task> RawExecuteInsertedAsync() { - var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; - var sql = versionGreaterThan10 ? this.ToSql() : this.ToSqlValuesOrSelectUnionAll(false); + var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); @@ -198,7 +151,7 @@ namespace FreeSql.Odbc.SqlServer ++colidx; } - if (versionGreaterThan10) + if ((_commonUtils as SqlServerUtils).ServerVersion > 10) { var validx = sql.IndexOf(") VALUES"); if (validx == -1) throw new ArgumentException("找不到 VALUES"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index 3af0446f..b564ef82 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -102,8 +102,8 @@ namespace FreeSql.Odbc.SqlServer #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); async protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 93db5277..bf9c9902 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -152,9 +152,9 @@ namespace FreeSql.Oracle.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(500, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(500, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); async protected override Task RawExecuteIdentityAsync() { diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index d24b384d..0b65e0fb 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -66,8 +66,8 @@ namespace FreeSql.Oracle.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index d010dd01..8745d19b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -122,9 +122,9 @@ namespace FreeSql.PostgreSQL.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); async protected override Task RawExecuteIdentityAsync() { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 4d7f248f..364a7f00 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -118,8 +118,8 @@ namespace FreeSql.PostgreSQL.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); async protected override Task> RawExecuteUpdatedAsync() { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index c99cbbb6..ee942b3b 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -111,9 +111,9 @@ namespace FreeSql.SqlServer.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1000, 2100); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1000, 2100); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1000, 2100); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); async protected override Task RawExecuteIdentityAsync() { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index d2ea517c..c67b1b25 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -103,9 +103,9 @@ namespace FreeSql.SqlServer.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 2100); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 2100); - + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + async protected override Task> RawExecuteUpdatedAsync() { var sql = this.ToSql(); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index d3ac22ba..49dd1191 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -59,9 +59,9 @@ namespace FreeSql.Sqlite.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); async protected override Task RawExecuteIdentityAsync() { diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index 507d4e6f..fdf9c3c6 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -66,8 +66,8 @@ namespace FreeSql.Sqlite.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(200, 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999); + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); protected override Task> RawExecuteUpdatedAsync() { From 4a5942629a9b93a1d6942ad46766b3a3b190db18 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 19 May 2020 16:03:44 +0800 Subject: [PATCH 0644/1029] update Odbc IInsert --- FreeSql/FreeSql.xml | 9 ++++----- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 53d45057..32fe7308 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2064,11 +2064,10 @@ - 设置更新的列 - - SetDto(new { title = "xxx", clicks = 2 }) - - SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + 设置更新的列 + SetDto(new { title = "xxx", clicks = 2 }) + SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + 注意:标记 [Column(CanUpdate = false)] 的属性不会被更新 dto 或 Dictionary<string, object> diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 391105d1..4491d2ab 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -151,7 +151,7 @@ namespace FreeSql.Odbc.SqlServer ++colidx; } - if ((_commonUtils as SqlServerUtils).ServerVersion > 10) + if ((_commonUtils as OdbcSqlServerUtils).ServerVersion > 10) { var validx = sql.IndexOf(") VALUES"); if (validx == -1) throw new ArgumentException("找不到 VALUES"); From 4b7a49d88a0ab39c15bb31d611191e62dfe3489b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 20 May 2020 12:11:08 +0800 Subject: [PATCH 0645/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Enum=20?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=97=A0=E5=85=83=E7=B4=A0=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs | 5 +++++ FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs | 4 ++-- .../FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs | 4 ++-- .../FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs | 4 ++-- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 4 ++-- .../FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs | 4 ++-- .../SqlServer/OdbcSqlServerCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs | 4 ++-- Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs | 4 ++-- Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs | 4 ++-- 17 files changed, 36 insertions(+), 31 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index d697b47c..e8084e14 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -371,6 +371,11 @@ namespace FreeSql.Tests.Sqlite public TableAllTypeEnumType1? Enum1Nullable { get; set; } public TableAllTypeEnumType2 Enum2 { get; set; } public TableAllTypeEnumType2? Enum2Nullable { get; set; } + + public TableAllTypeEnumType3 testFieldEnum3 { get; set; } + public TableAllTypeEnumType3? testFieldEnum3Nullable { get; set; } + + public enum TableAllTypeEnumType3 { } } public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 7ba71c68..79f636fc 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -109,7 +109,7 @@ public class g static Lazy damengLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Dameng, "server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user;poolsize=5") - //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;Max Pool Size=2")) + //.UseConnectionFactory(FreeSql.DataType.Dameng, () => new Dm.DmConnection("data source=127.0.0.1:5236;user id=2user;password=123456789;Pooling=true;poolsize=2")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) diff --git a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs index 2378e7ab..d039e15d 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs @@ -60,8 +60,8 @@ namespace FreeSql.Dameng if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(DmDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(DmDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(DmDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(DmDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs index 2033b34b..a78a56ea 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs @@ -56,8 +56,8 @@ namespace FreeSql.MsAccess if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OleDbType.BigInt, "decimal", $"decimal(20,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(OleDbType.Integer, "decimal", $"decimal(11,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OleDbType.BigInt, "decimal", $"decimal(20,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OleDbType.Integer, "decimal", $"decimal(11,0){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index e48d751f..76ba3291 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -64,8 +64,8 @@ namespace FreeSql.MySql { var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(MySqlDbType.Set, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(MySqlDbType.Set, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 55fc2af3..da91867c 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -60,8 +60,8 @@ namespace FreeSql.Odbc.Dameng if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs index 26e218a9..5d758171 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs @@ -74,8 +74,8 @@ namespace FreeSql.Odbc.Default if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, $"{_utils.Adapter.MappingOdbcTypeBigInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, $"{_utils.Adapter.MappingOdbcTypeInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.BigInt, _utils.Adapter.MappingOdbcTypeBigInt, $"{_utils.Adapter.MappingOdbcTypeBigInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OdbcType.Int, _utils.Adapter.MappingOdbcTypeInt, $"{_utils.Adapter.MappingOdbcTypeInt}{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 3e389fb6..7b976b31 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -57,8 +57,8 @@ namespace FreeSql.Odbc.MySql { var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OdbcType.VarChar, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(OdbcType.VarChar, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.VarChar, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OdbcType.VarChar, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index a898f956..cf3b5b64 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -60,8 +60,8 @@ namespace FreeSql.Odbc.Oracle if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.Int, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OdbcType.BigInt, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 71e3322a..734a0e25 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -64,8 +64,8 @@ namespace FreeSql.Odbc.PostgreSQL if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OdbcType.Int, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(OdbcType.BigInt, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.Int, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OdbcType.BigInt, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 9b582199..f6aa1295 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -50,8 +50,8 @@ namespace FreeSql.Odbc.PostgreSQL if (genericTypesFirst.IsEnum) enumType = genericTypesFirst; } if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)) : - getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)); + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()); return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; } if (type.IsNullableType()) type = type.GetGenericArguments().First(); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 550903f3..0f552451 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -56,8 +56,8 @@ namespace FreeSql.Odbc.SqlServer if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OdbcType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(OdbcType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OdbcType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OdbcType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 132219f0..8a8abe9d 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -61,8 +61,8 @@ namespace FreeSql.Oracle if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OracleDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(OracleDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(OracleDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OracleDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 7e714a49..fa581e60 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -99,8 +99,8 @@ namespace FreeSql.PostgreSQL if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(NpgsqlDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(NpgsqlDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index cc345caa..c32ee8db 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -68,8 +68,8 @@ namespace FreeSql.PostgreSQL if (elementType.IsEnum) enumType = elementType; else if (elementType.IsNullableType() && elementType.GenericTypeArguments.First().IsEnum) enumType = elementType.GenericTypeArguments.First(); if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)) : - getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : Enum.GetValues(enumType).GetValue(0)); + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()); return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; } if (type.IsNullableType()) type = type.GenericTypeArguments.First(); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 2d30c5ba..4eaa1476 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -55,8 +55,8 @@ namespace FreeSql.SqlServer if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(SqlDbType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(SqlDbType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index b6ed95d0..eb267acb 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -55,8 +55,8 @@ namespace FreeSql.Sqlite if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(DbType.Int64, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) : - CsToDb.New(DbType.Int32, "mediumint", $"mediumint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)); + CsToDb.New(DbType.Int64, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(DbType.Int32, "mediumint", $"mediumint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) From 6a443620e73ff76540843a450693da61ff361086 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 May 2020 01:59:35 +0800 Subject: [PATCH 0646/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IFreeSql.Ins?= =?UTF-8?q?ertOrUpdate=20=E6=96=B9=E6=B3=95=20#316?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DbContext/DbContextScopedFreeSql.cs | 7 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - .../Curd/MySqlInsertOrUpdateTest.cs | 167 +++++++++ .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 323 +++++++++++++++++ .../MySql/Curd/MySqlInsertOrUpdateTest.cs | 167 +++++++++ .../MySql/Curd/OnDuplicateKeyUpdateTest.cs | 195 +++++++++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 323 +++++++++++++++++ .../PostgreSQL/Curd/OnConflictDoUpdateTest.cs | 158 +++++++++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 205 +++++++++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 323 +++++++++++++++++ .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 323 +++++++++++++++++ .../MySql/Curd/MySqlInsertOrUpdateTest.cs | 167 +++++++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 323 +++++++++++++++++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 205 +++++++++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 325 ++++++++++++++++++ .../Sqlite/Curd/SqliteInsertOrUpdateTest.cs | 165 +++++++++ FreeSql/FreeSql.xml | 210 ++++------- FreeSql/Interface/Curd/IInsertOrUpdate.cs | 66 ++++ FreeSql/Interface/IAop.cs | 4 +- FreeSql/Interface/IFreeSql.cs | 13 + .../CommonProvider/InsertOrUpdateProvider.cs | 222 ++++++++++++ .../Internal/CommonProvider/InsertProvider.cs | 30 +- .../Internal/CommonProvider/UpdateProvider.cs | 38 +- .../Curd/DamengInsertOrUpdate.cs | 43 +++ .../FreeSql.Provider.Dameng/DamengProvider.cs | 1 + .../MsAccessProvider.cs | 1 + .../Curd/MySqlInsertOrUpdate.cs | 29 ++ .../Curd/OnDuplicateKeyUpdate.cs | 5 - .../FreeSql.Provider.MySql/MySqlProvider.cs | 1 + .../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 43 +++ .../Dameng/OdbcDamengProvider.cs | 1 + .../Default/OdbcProvider.cs | 1 + .../MySql/Curd/OdbcMySqlInsert.cs | 20 ++ .../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 29 ++ .../Curd/OdbcMySqlOnDuplicateKeyUpdate.cs | 166 +++++++++ .../MySql/Curd/OdbcMySqlUpdate.cs | 8 +- .../MySql/OdbcMySqlProvider.cs | 1 + .../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 43 +++ .../Oracle/OdbcOracleProvider.cs | 1 + .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 13 + .../Curd/OdbcPostgreSQLInsertOrUpdate.cs | 33 ++ .../Curd/OdbcPostgreSQLOnConflictDoUpdate.cs | 207 +++++++++++ .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 10 + .../PostgreSQL/OdbcPostgreSQLProvider.cs | 1 + .../SqlServer/Curd/OdbcSqlServerInsert.cs | 2 - .../Curd/OdbcSqlServerInsertOrUpdate.cs | 43 +++ .../SqlServer/OdbcSqlServerProvider.cs | 1 + .../Curd/OracleInsertOrUpdate.cs | 43 +++ .../FreeSql.Provider.Oracle/OracleProvider.cs | 1 + .../Curd/OnConflictDoUpdate.cs | 3 - .../Curd/PostgreSQLInsertOrUpdate.cs | 33 ++ .../PostgreSQLProvider.cs | 1 + .../Curd/SqlServerInsert.cs | 2 - .../Curd/SqlServerInsertOrUpdate.cs | 43 +++ .../SqlServerProvider.cs | 1 + .../Curd/SqliteInsertOrUpdate.cs | 30 ++ .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 1 + 57 files changed, 4627 insertions(+), 209 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/OnDuplicateKeyUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/OnConflictDoUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs create mode 100644 FreeSql/Interface/Curd/IInsertOrUpdate.cs create mode 100644 FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs create mode 100644 Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs diff --git a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs index 2aabe397..d82d4224 100644 --- a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs +++ b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs @@ -76,6 +76,11 @@ namespace FreeSql public IInsert Insert(T1[] source) where T1 : class => Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => Insert().AppendData(source); public IInsert Insert(IEnumerable source) where T1 : class => Insert().AppendData(source); - + public IInsertOrUpdate InsertOrUpdate() where T1 : class + { + var db = _resolveDbContext?.Invoke(); + db?.FlushCommand(); + return _originalFsql.InsertOrUpdate().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + } } } 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.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs new file mode 100644 index 00000000..6198c553 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs @@ -0,0 +1,167 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlInsertOrUpdateTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(2, '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(5, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(2, '02', '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(5, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '01', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '011', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(2, '02', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '01', 0, now(3)), (2, '02', 0, now(3)), (3, '03', 0, now(3)), (4, '04', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(6, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '001', 0, now(3)), (2, '002', 0, now(3)), (3, '003', 0, now(3)), (4, '004', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs new file mode 100644 index 00000000..e3832aaa --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -0,0 +1,323 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengInsertOrUpdateTest + { + IFreeSql fsql => g.dameng; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs new file mode 100644 index 00000000..3b9fc212 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs @@ -0,0 +1,167 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlInsertOrUpdateTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(2, '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(2, '02', '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '01', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '011', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(2, '02', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '01', 0, now(3)), (2, '02', 0, now(3)), (3, '03', 0, now(3)), (4, '04', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '001', 0, now(3)), (2, '002', 0, now(3)), (3, '003', 0, now(3)), (4, '004', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/OnDuplicateKeyUpdateTest.cs new file mode 100644 index 00000000..1bf715b6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/OnDuplicateKeyUpdateTest.cs @@ -0,0 +1,195 @@ +using FreeSql.DataAnnotations; +using FreeSql.Odbc.MySql; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class OnDuplicateKeyUpdateTest + { + class TestOnDuplicateKeyUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.mysql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = VALUES(`time`)", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = VALUES(`time`)", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = CASE `id` +WHEN 200 THEN '2000-01-01 00:00:00.000' +WHEN 201 THEN '2000-01-01 00:00:00.000' +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') +ON DUPLICATE KEY UPDATE +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON DUPLICATE KEY UPDATE +`time` = CASE `id` +WHEN 200 THEN '2000-01-01 00:00:00.000' +WHEN 201 THEN '2000-01-01 00:00:00.000' +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = CASE `id` +WHEN 300 THEN '2000-01-01 00:00:00.000' +WHEN 301 THEN '2000-01-01 00:00:00.000' +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') +ON DUPLICATE KEY UPDATE +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON DUPLICATE KEY UPDATE +`time` = CASE `id` +WHEN 300 THEN '2000-01-01 00:00:00.000' +WHEN 301 THEN '2000-01-01 00:00:00.000' +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + var dt2020 = DateTime.Parse("2020-1-1"); + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + odku1 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => a.time == dt2020); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => a.time == dt2020); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + odku1 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => new { time = dt2020, title = a.title + "123" }); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new OdbcMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => new { time = dt2020, title = a.title + "123" }); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs new file mode 100644 index 00000000..156bebbf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -0,0 +1,323 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleInsertOrUpdateTest + { + IFreeSql fsql => g.oracle; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/OnConflictDoUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/OnConflictDoUpdateTest.cs new file mode 100644 index 00000000..9ce29662 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/OnConflictDoUpdateTest.cs @@ -0,0 +1,158 @@ +using FreeSql.DataAnnotations; +using FreeSql.Odbc.PostgreSQL; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class OnConflictDoUpdateTest + { + class TestOnConflictDoUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime? time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.pgsql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = EXCLUDED.""time""", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000'), (101, 'title-101', '2000-01-01 00:00:00.000000'), (102, 'title-102', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = EXCLUDED.""time""", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.pgsql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = CASE EXCLUDED.""id"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.pgsql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = CASE EXCLUDED.""id"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.pgsql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = CASE EXCLUDED.""id"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.pgsql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = CASE EXCLUDED.""id"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.pgsql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2020-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2020-01-01 00:00:00.000000'", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs new file mode 100644 index 00000000..90ce4b5b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -0,0 +1,205 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLInsertOrUpdateTest + { + IFreeSql fsql => g.pgsql; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(2) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs new file mode 100644 index 00000000..0c00dbb5 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -0,0 +1,323 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + public class SqlServerInsertOrUpdateTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 2 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as id1, N'02' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 2 as id1, N'02' as id2, N'02' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name +UNION ALL + SELECT 2, N'02', N'02' +UNION ALL + SELECT 3, N'03', N'03' +UNION ALL + SELECT 4, N'04', N'04' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'001' as name +UNION ALL + SELECT 2, N'02', N'002' +UNION ALL + SELECT 3, N'03', N'003' +UNION ALL + SELECT 4, N'04', N'004' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as id, N'011' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 2 as id, N'02' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'02', 0, getdate() +UNION ALL + SELECT 3, N'03', 0, getdate() +UNION ALL + SELECT 4, N'04', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as id, N'001' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'002', 0, getdate() +UNION ALL + SELECT 3, N'003', 0, getdate() +UNION ALL + SELECT 4, N'004', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs new file mode 100644 index 00000000..54e4c38a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -0,0 +1,323 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengInsertOrUpdateTest + { + IFreeSql fsql => g.dameng; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs new file mode 100644 index 00000000..3cfe1a62 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs @@ -0,0 +1,167 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySql +{ + public class MySqlInsertOrUpdateTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(2, '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(5, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(2, '02', '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(5, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '01', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '011', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(2, '02', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '01', 0, now(3)), (2, '02', 0, now(3)), (3, '03', 0, now(3)), (4, '04', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(6, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '001', 0, now(3)), (2, '002', 0, now(3)), (3, '003', 0, now(3)), (4, '004', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs new file mode 100644 index 00000000..e645b7fc --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -0,0 +1,323 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Oracle +{ + public class OracleInsertOrUpdateTest + { + IFreeSql fsql => g.oracle; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs new file mode 100644 index 00000000..1b1e853b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -0,0 +1,205 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLInsertOrUpdateTest + { + IFreeSql fsql => g.pgsql; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(2) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs new file mode 100644 index 00000000..7858a27d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -0,0 +1,325 @@ +using FreeSql.DataAnnotations; +using FreeSql.Tests.DataContext.SqlServer; +using SaleIDO.Entity.Storeage; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.SqlServer +{ + public class SqlServerInsertOrUpdateTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 2 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as id1, N'02' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 2 as id1, N'02' as id2, N'02' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name +UNION ALL + SELECT 2, N'02', N'02' +UNION ALL + SELECT 3, N'03', N'03' +UNION ALL + SELECT 4, N'04', N'04' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'001' as name +UNION ALL + SELECT 2, N'02', N'002' +UNION ALL + SELECT 3, N'03', N'003' +UNION ALL + SELECT 4, N'04', N'004' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as id, N'011' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 2 as id, N'02' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'02', 0, getdate() +UNION ALL + SELECT 3, N'03', 0, getdate() +UNION ALL + SELECT 4, N'04', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as id, N'001' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'002', 0, getdate() +UNION ALL + SELECT 3, N'003', 0, getdate() +UNION ALL + SELECT 4, N'004', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name, [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs new file mode 100644 index 00000000..0412c2fa --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs @@ -0,0 +1,165 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Sqlite +{ + public class SqliteInsertOrUpdateTest + { + IFreeSql fsql => g.sqlite; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou01""(""id"") VALUES(1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou01""(""id"") VALUES(1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou01""(""id"") VALUES(2)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou02""(""id"", ""name"") VALUES(1, '011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou02""(""id"", ""name"") VALUES(2, '02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou04""(""id"", ""name"", ""version"", ""CreateTime"") VALUES(1, '01', 0, datetime(current_timestamp,'localtime'))", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou04""(""id"", ""name"", ""version"", ""CreateTime"") VALUES(1, '011', 0, datetime(current_timestamp,'localtime'))", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou04""(""id"", ""name"", ""version"", ""CreateTime"") VALUES(2, '02', 0, datetime(current_timestamp,'localtime'))", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou04""(""id"", ""name"", ""version"", ""CreateTime"") VALUES(1, '01', 0, datetime(current_timestamp,'localtime')), (2, '02', 0, datetime(current_timestamp,'localtime')), (3, '03', 0, datetime(current_timestamp,'localtime')), (4, '04', 0, datetime(current_timestamp,'localtime'))", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou04""(""id"", ""name"", ""version"", ""CreateTime"") VALUES(1, '001', 0, datetime(current_timestamp,'localtime')), (2, '002', 0, datetime(current_timestamp,'localtime')), (3, '003', 0, datetime(current_timestamp,'localtime')), (4, '004', 0, datetime(current_timestamp,'localtime'))", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 32fe7308..1b705557 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1011,6 +1011,60 @@ + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 添加或更新,设置实体 + + 实体 + + + + + 添加或更新,设置实体集合 + + 实体集合 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + 自动产生 as1, as2, as3 .... 字段别名 @@ -2337,137 +2391,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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,12 +2986,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3139,12 +3056,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3685,6 +3596,19 @@ + + + 插入或更新数据 + MySql: on duplicate key update + PostgreSQL: on conflict do update + SqlServer: merge into + Oracle: merge into + Sqlite: replace into + Dameng: merge into + + + + 修改数据 diff --git a/FreeSql/Interface/Curd/IInsertOrUpdate.cs b/FreeSql/Interface/Curd/IInsertOrUpdate.cs new file mode 100644 index 00000000..c6db9222 --- /dev/null +++ b/FreeSql/Interface/Curd/IInsertOrUpdate.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql +{ + public interface IInsertOrUpdate where T1 : class + { + + /// + /// 指定事务对象 + /// + /// + /// + IInsertOrUpdate WithTransaction(DbTransaction transaction); + /// + /// 指定事务对象 + /// + /// + /// + IInsertOrUpdate WithConnection(DbConnection connection); + + /// + /// 添加或更新,设置实体 + /// + /// 实体 + /// + IInsertOrUpdate SetSource(T1 source); + /// + /// 添加或更新,设置实体集合 + /// + /// 实体集合 + /// + IInsertOrUpdate SetSource(IEnumerable source); + + /// + /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + /// + /// + /// + IInsertOrUpdate AsTable(Func tableRule); + /// + /// 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + /// + /// + /// + IInsertOrUpdate AsType(Type entityType); + /// + /// 返回即将执行的SQL语句 + /// + /// + string ToSql(); + /// + /// 执行SQL语句,返回影响的行数 + /// + /// + int ExecuteAffrows(); + +#if net40 +#else + Task ExecuteAffrowsAsync(); +#endif + } +} \ No newline at end of file diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index b9914ff3..bef5f515 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -201,7 +201,7 @@ namespace FreeSql.Aop /// public DbParameter[] DbParms { get; } } - public enum CurdType { Select, Delete, Update, Insert } + public enum CurdType { Select, Delete, Update, Insert, InsertOrUpdate } public class CurdAfterEventArgs : CurdBeforeEventArgs { public CurdAfterEventArgs(CurdBeforeEventArgs before, Exception exception, object executeResult) : @@ -324,7 +324,7 @@ namespace FreeSql.Aop private object _value; public bool IsChanged { get; private set; } } - public enum AuditValueType { Update, Insert } + public enum AuditValueType { Update, Insert, InsertOrUpdate } #endregion #region CommandBefore/After diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index 2709de31..72230929 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -44,6 +44,19 @@ public interface IFreeSql : IDisposable /// IInsert Insert(IEnumerable source) where T1 : class; + /// + /// 插入或更新数据 + /// MySql: on duplicate key update + /// PostgreSQL: on conflict do update + /// SqlServer: merge into + /// Oracle: merge into + /// Sqlite: replace into + /// Dameng: merge into + /// + /// + /// + IInsertOrUpdate InsertOrUpdate() where T1 : class; + /// /// 修改数据 /// diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs new file mode 100644 index 00000000..42fe4bee --- /dev/null +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -0,0 +1,222 @@ +using FreeSql.Extensions.EntityUtil; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + public abstract partial class InsertOrUpdateProvider : IInsertOrUpdate where T1 : class + { + protected IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + protected List _source = new List(); + protected Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + protected TableInfo _table; + protected Func _tableRule; + protected DbParameter[] _params; + protected DbTransaction _transaction; + protected DbConnection _connection; + + public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + _table = _commonUtils.GetTableByEntity(typeof(T1)); + if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + } + + protected void ClearData() + { + _source.Clear(); + _auditValueChangedDict.Clear(); + } + + public IInsertOrUpdate WithTransaction(DbTransaction transaction) + { + _transaction = transaction; + _connection = _transaction?.Connection; + return this; + } + public IInsertOrUpdate WithConnection(DbConnection connection) + { + if (_transaction?.Connection != connection) _transaction = null; + _connection = connection; + return this; + } + + public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table, Dictionary changedDict) + { + if (data?.Any() != true) return; + if (orm.Aop.AuditValueHandler == null) return; + foreach (var d in data) + { + if (d == null) continue; + foreach (var col in table.Columns.Values) + { + object val = col.GetMapValue(d); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val); + orm.Aop.AuditValueHandler(sender, auditArgs); + if (auditArgs.IsChanged) + { + col.SetMapValue(d, val = auditArgs.Value); + if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) + changedDict.Add(col.Attribute.Name, true); + } + } + } + } + public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) + { + if (orm.Aop.AuditValueHandler == null) return; + if (data == null) return; + if (typeof(T1) == typeof(object) && new[] { table.Type, table.TypeLazy }.Contains(data.GetType()) == false) + throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); + foreach (var col in table.Columns.Values) + { + object val = col.GetMapValue(data); + var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val); + orm.Aop.AuditValueHandler(sender, auditArgs); + if (auditArgs.IsChanged) + { + col.SetMapValue(data, val = auditArgs.Value); + if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) + changedDict.Add(col.Attribute.Name, true); + } + } + } + + public IInsertOrUpdate SetSource(T1 source) => this.SetSource(new[] { source }); + public IInsertOrUpdate SetSource(IEnumerable source) + { + if (source == null || source.Any() == false) return this; + AuditDataValue(this, source, _orm, _table, _auditValueChangedDict); + _source.AddRange(source.Where(a => a != null)); + return this; + } + + protected string TableRuleInvoke() + { + if (_tableRule == null) return _table.DbName; + var newname = _tableRule(_table.DbName); + if (newname == _table.DbName) return _table.DbName; + if (string.IsNullOrEmpty(newname)) return _table.DbName; + if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname); + return newname; + } + public IInsertOrUpdate AsTable(Func tableRule) + { + _tableRule = tableRule; + return this; + } + public IInsertOrUpdate AsType(Type entityType) + { + if (entityType == typeof(object)) throw new Exception("IInsertOrUpdate.AsType 参数不支持指定为 object"); + if (entityType == _table.Type) return this; + var newtb = _commonUtils.GetTableByEntity(entityType); + _table = newtb ?? throw new Exception("IInsertOrUpdate.AsType 参数错误,请传入正确的实体类型"); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); + return this; + } + + public void WriteSourceSelectUnionAll(StringBuilder sb) + { + var specialParams = new List(); + var didx = 0; + foreach (var d in _source) + { + if (didx > 0) sb.Append(" \r\nUNION ALL\r\n "); + sb.Append("SELECT "); + var colidx2 = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx2 > 0) sb.Append(", "); + if (string.IsNullOrEmpty(col.DbInsertValue) == false) + sb.Append(col.DbInsertValue); + else + { + object val = col.GetMapValue(d); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + } + if (didx == 0) sb.Append(" as ").Append(col.Attribute.Name); + ++colidx2; + } + switch (_orm.Ado.DataType) + { + case DataType.OdbcOracle: + case DataType.Oracle: + case DataType.OdbcDameng: + case DataType.Dameng: + sb.Append(" FROM dual"); + break; + } + ++didx; + } + if (specialParams.Any()) _params = specialParams.ToArray(); + } + + public abstract string ToSql(); + public int ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.InsertOrUpdate, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return affrows; + } +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.InsertOrUpdate, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var affrows = 0; + Exception exception = null; + try + { + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, affrows); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return affrows; + } +#endif + } +} diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index a88dbd19..6883a596 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -15,20 +15,20 @@ namespace FreeSql.Internal.CommonProvider public abstract partial class InsertProvider : IInsert where T1 : class { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected List _source = new List(); - protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - protected Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - protected TableInfo _table; - protected Func _tableRule; - protected bool _noneParameter, _insertIdentity; - protected int _batchValuesLimit, _batchParameterLimit; - protected bool _batchAutoTransaction = true; - protected DbParameter[] _params; - protected DbTransaction _transaction; - protected DbConnection _connection; + public IFreeSql _orm; + public CommonUtils _commonUtils; + public CommonExpression _commonExpression; + public List _source = new List(); + public Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public TableInfo _table; + public Func _tableRule; + public bool _noneParameter, _insertIdentity; + public int _batchValuesLimit, _batchParameterLimit; + public bool _batchAutoTransaction = true; + public DbParameter[] _params; + public DbTransaction _transaction; + public DbConnection _connection; public InsertProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { @@ -509,7 +509,7 @@ namespace FreeSql.Internal.CommonProvider ++colidx; } sb.Append(") "); - if (isValues) sb.Append(isValues ? "VALUES" : "SELECT "); + if (isValues) sb.Append("VALUES"); _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; var specialParams = new List(); var didx = 0; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index e6307337..df335d50 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -15,25 +15,25 @@ namespace FreeSql.Internal.CommonProvider public abstract partial class UpdateProvider : IUpdate where T1 : class { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected List _source = new List(); - protected Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - protected Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - protected TableInfo _table; - protected Func _tableRule; - protected StringBuilder _where = new StringBuilder(); - protected List _whereGlobalFilter; - protected StringBuilder _set = new StringBuilder(); - protected StringBuilder _setIncr = new StringBuilder(); - protected List _params = new List(); - protected List _paramsSource = new List(); - protected bool _noneParameter; - protected int _batchRowsLimit, _batchParameterLimit; - protected bool _batchAutoTransaction = true; - protected DbTransaction _transaction; - protected DbConnection _connection; + public IFreeSql _orm; + public CommonUtils _commonUtils; + public CommonExpression _commonExpression; + public List _source = new List(); + public Dictionary _ignore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public TableInfo _table; + public Func _tableRule; + public StringBuilder _where = new StringBuilder(); + public List _whereGlobalFilter; + public StringBuilder _set = new StringBuilder(); + public StringBuilder _setIncr = new StringBuilder(); + public List _params = new List(); + public List _paramsSource = new List(); + public bool _noneParameter; + public int _batchRowsLimit, _batchParameterLimit; + public bool _batchAutoTransaction = true; + public DbTransaction _transaction; + public DbConnection _connection; public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs new file mode 100644 index 00000000..52f2e955 --- /dev/null +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -0,0 +1,43 @@ +using FreeSql.Internal; +using System; +using System.Linq; +using System.Text; + +namespace FreeSql.Dameng.Curd +{ + + class DamengInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public DamengInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") + .Append("USING ("); + WriteSourceSelectUnionAll(sb); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Dameng/DamengProvider.cs b/Providers/FreeSql.Provider.Dameng/DamengProvider.cs index e8166066..c6903675 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengProvider.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengProvider.cs @@ -24,6 +24,7 @@ namespace FreeSql.Dameng public IUpdate Update(object dywhere) where T1 : class => new DamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new DamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new DamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new DamengInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs index 8c75f086..1160eec7 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs @@ -24,6 +24,7 @@ namespace FreeSql.MsAccess public IUpdate Update(object dywhere) where T1 : class => new MsAccessUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new MsAccessDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new MsAccessDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => throw new NotImplementedException(); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs new file mode 100644 index 00000000..6d530b2f --- /dev/null +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -0,0 +1,29 @@ +using FreeSql.Internal; +using System.Linq; + +namespace FreeSql.MySql.Curd +{ + + class MySqlInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public MySqlInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = _source; + var sql = new OnDuplicateKeyUpdate(insert).ToSql(); + _params = insert._params; + return sql; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs index 883630c8..66118ee1 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -1,11 +1,6 @@ using FreeSql.Aop; -using FreeSql.Internal; -using FreeSql.Internal.Model; using System; -using System.Collections.Generic; using System.Data; -using System.Data.Common; -using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index f1b146d0..c1d533fc 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -50,6 +50,7 @@ namespace FreeSql.MySql public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new MySqlInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs new file mode 100644 index 00000000..c5826cdc --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -0,0 +1,43 @@ +using FreeSql.Internal; +using System; +using System.Linq; +using System.Text; + +namespace FreeSql.Odbc.Dameng +{ + + class OdbcDamengInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public OdbcDamengInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") + .Append("USING ("); + WriteSourceSelectUnionAll(sb); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs index 77e114ae..3adf7d01 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs @@ -23,6 +23,7 @@ namespace FreeSql.Odbc.Dameng public IUpdate Update(object dywhere) where T1 : class => new OdbcDamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcDamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new OdbcDamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcDamengInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index f53e1791..6459f13f 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -26,6 +26,7 @@ namespace FreeSql.Odbc.Default public IUpdate Update(object dywhere) where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => throw new NotImplementedException(); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index a99cfaf4..94f6a20b 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; @@ -17,11 +18,30 @@ namespace FreeSql.Odbc.MySql { } + internal bool InternalIsIgnoreInto = false; + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override string ToSql() + { + if (InternalIsIgnoreInto == false) return base.ToSqlValuesOrSelectUnionAll(); + var sql = base.ToSqlValuesOrSelectUnionAll(); + return $"INSERT IGNORE INTO {sql.Substring(12)}"; + } + protected override long RawExecuteIdentity() { var sql = this.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs new file mode 100644 index 00000000..c8908805 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -0,0 +1,29 @@ +using FreeSql.Internal; +using System.Linq; + +namespace FreeSql.Odbc.MySql +{ + + class OdbcMySqlInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public OdbcMySqlInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = _source; + var sql = new OdbcMySqlOnDuplicateKeyUpdate(insert).ToSql(); + _params = insert._params; + return sql; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs new file mode 100644 index 00000000..cc4649fb --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs @@ -0,0 +1,166 @@ +using FreeSql.Aop; +using System; +using System.Data; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.MySql +{ + public class OdbcMySqlOnDuplicateKeyUpdate where T1 : class + { + internal OdbcMySqlInsert _mysqlInsert; + internal OdbcMySqlUpdate _mysqlUpdatePriv; + internal OdbcMySqlUpdate _mysqlUpdate => _mysqlUpdatePriv ?? (_mysqlUpdatePriv = new OdbcMySqlUpdate(_mysqlInsert.InternalOrm, _mysqlInsert.InternalCommonUtils, _mysqlInsert.InternalCommonExpression, null).NoneParameter().SetSource(_mysqlInsert.InternalSource) as OdbcMySqlUpdate); + + public OdbcMySqlOnDuplicateKeyUpdate(IInsert insert) + { + _mysqlInsert = insert as OdbcMySqlInsert; + if (_mysqlInsert == null) throw new Exception("OnDuplicateKeyUpdate 是 FreeSql.Provider.Odbc/MySql 特有的功能"); + } + + protected void ClearData() + { + _mysqlInsert.InternalClearData(); + _mysqlUpdatePriv = null; + } + + public OdbcMySqlOnDuplicateKeyUpdate IgnoreColumns(Expression> columns) + { + _mysqlUpdate.IgnoreColumns(columns); + return this; + } + public OdbcMySqlOnDuplicateKeyUpdate UpdateColumns(Expression> columns) + { + _mysqlUpdate.UpdateColumns(columns); + return this; + } + public OdbcMySqlOnDuplicateKeyUpdate IgnoreColumns(string[] columns) + { + _mysqlUpdate.IgnoreColumns(columns); + return this; + } + public OdbcMySqlOnDuplicateKeyUpdate UpdateColumns(string[] columns) + { + _mysqlUpdate.UpdateColumns(columns); + return this; + } + + public OdbcMySqlOnDuplicateKeyUpdate Set(Expression> column, TMember value) + { + _mysqlUpdate.Set(column, value); + return this; + } + public OdbcMySqlOnDuplicateKeyUpdate Set(Expression> exp) + { + _mysqlUpdate.Set(exp); + return this; + } + public OdbcMySqlOnDuplicateKeyUpdate SetRaw(string sql) + { + _mysqlUpdate.SetRaw(sql); + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + sb.Append(_mysqlInsert.ToSql()).Append("\r\nON DUPLICATE KEY UPDATE\r\n"); + + var sbSetEmpty = _mysqlUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _mysqlUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_mysqlUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _mysqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _mysqlUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _mysqlInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _mysqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true) + { + var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(field).Append(" + 1"); + } + else if (_mysqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _mysqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _mysqlUpdate.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = VALUES(").Append(field).Append(")"); + } + ++colidx; + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_mysqlInsert.InternalTable.Type, _mysqlInsert.InternalTable, CurdType.Insert, sql, _mysqlInsert.InternalParams); + _mysqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_mysqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _mysqlInsert.InternalOrm.Ado.ExecuteNonQuery(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _mysqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_mysqlInsert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_mysqlInsert.InternalTable.Type, _mysqlInsert.InternalTable, CurdType.Insert, sql, _mysqlInsert.InternalParams); + _mysqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_mysqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _mysqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_mysqlInsert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index 2b12d47c..d86a8c93 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -18,10 +18,16 @@ namespace FreeSql.Odbc.MySql { } + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - protected override List RawExecuteUpdated() { var sql = this.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index a0bb6347..e59064d9 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -28,6 +28,7 @@ namespace FreeSql.Odbc.MySql public IUpdate Update(object dywhere) where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcMySqlInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs new file mode 100644 index 00000000..0c151cc3 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -0,0 +1,43 @@ +using FreeSql.Internal; +using System; +using System.Linq; +using System.Text; + +namespace FreeSql.Odbc.Oracle +{ + + class OdbcOracleInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public OdbcOracleInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") + .Append("USING ("); + WriteSourceSelectUnionAll(sb); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index 47b16b74..1a35a2d2 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -23,6 +23,7 @@ namespace FreeSql.Odbc.Oracle public IUpdate Update(object dywhere) where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcOracleInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index 4d457731..e8367ac5 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -1,7 +1,9 @@ using FreeSql.Internal; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -16,6 +18,17 @@ namespace FreeSql.Odbc.PostgreSQL { } + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs new file mode 100644 index 00000000..ec291e6b --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -0,0 +1,33 @@ +using FreeSql.Internal; +using System.Linq; + +namespace FreeSql.Odbc.PostgreSQL +{ + + class OdbcPostgreSQLInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public OdbcPostgreSQLInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = _source; + var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert); + ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); + if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + ocdu.DoNothing(); + var sql = ocdu.ToSql(); + _params = insert._params; + return sql; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs new file mode 100644 index 00000000..4d59b8af --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs @@ -0,0 +1,207 @@ +using FreeSql.Aop; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.PostgreSQL +{ + public class OdbcPostgreSQLOnConflictDoUpdate where T1 : class + { + internal OdbcPostgreSQLInsert _pgsqlInsert; + internal OdbcPostgreSQLUpdate _pgsqlUpdatePriv; + internal OdbcPostgreSQLUpdate _pgsqlUpdate => _pgsqlUpdatePriv ?? + (_pgsqlUpdatePriv = new OdbcPostgreSQLUpdate(_pgsqlInsert.InternalOrm, _pgsqlInsert.InternalCommonUtils, _pgsqlInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } + .NoneParameter().SetSource(_pgsqlInsert.InternalSource) as OdbcPostgreSQLUpdate); + ColumnInfo[] _columns; + bool _doNothing; + + public OdbcPostgreSQLOnConflictDoUpdate(IInsert insert, Expression> columns = null) + { + _pgsqlInsert = insert as OdbcPostgreSQLInsert; + if (_pgsqlInsert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.Odbc/PostgreSQL 特有的功能"); + + if (columns != null) + { + var colsList = new List(); + var cols = _pgsqlInsert.InternalCommonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name)) + colsList.Add(col); + _columns = colsList.ToArray(); + } + if (_columns == null || _columns.Any() == false) + _columns = _pgsqlInsert.InternalTable.Primarys; + if (_columns.Any() == false) throw new Exception("OnConflictDoUpdate 功能要求实体类必须设置 IsPrimary 属性"); + } + + protected void ClearData() + { + _pgsqlInsert.InternalClearData(); + _pgsqlUpdatePriv = null; + } + + public OdbcPostgreSQLOnConflictDoUpdate IgnoreColumns(Expression> columns) + { + _pgsqlUpdate.IgnoreColumns(columns); + return this; + } + public OdbcPostgreSQLOnConflictDoUpdate UpdateColumns(Expression> columns) + { + _pgsqlUpdate.UpdateColumns(columns); + return this; + } + public OdbcPostgreSQLOnConflictDoUpdate IgnoreColumns(string[] columns) + { + _pgsqlUpdate.IgnoreColumns(columns); + return this; + } + public OdbcPostgreSQLOnConflictDoUpdate UpdateColumns(string[] columns) + { + _pgsqlUpdate.UpdateColumns(columns); + return this; + } + + public OdbcPostgreSQLOnConflictDoUpdate Set(Expression> column, TMember value) + { + _pgsqlUpdate.Set(column, value); + return this; + } + //由于表达式解析问题,ON CONFLICT("id") DO UPDATE SET 需要指定表别名,如 Set(a => a.Clicks + 1) 解析会失败 + //暂时不开放这个功能,如有需要使用 SetRaw("click = t.click + 1") 替代该操作 + //public OnConflictDoUpdate Set(Expression> exp) + //{ + // _pgsqlUpdate.Set(exp); + // return this; + //} + public OdbcPostgreSQLOnConflictDoUpdate SetRaw(string sql) + { + _pgsqlUpdate.SetRaw(sql); + return this; + } + + public OdbcPostgreSQLOnConflictDoUpdate DoNothing() + { + _doNothing = true; + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + sb.Append(_pgsqlInsert.ToSql()).Append("\r\nON CONFLICT("); + for (var a = 0; a < _columns.Length; a++) + { + if (a > 0) sb.Append(", "); + sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + } + if (_doNothing) + { + sb.Append(") DO NOTHING"); + } + else + { + sb.Append(") DO UPDATE SET\r\n"); + + var sbSetEmpty = _pgsqlUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _pgsqlUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_pgsqlUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _pgsqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _pgsqlUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _pgsqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true) + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); + } + else if (_pgsqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _pgsqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _pgsqlUpdate.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = EXCLUDED.").Append(field); + } + ++colidx; + } + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); + _pgsqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_pgsqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _pgsqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_pgsqlInsert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); + _pgsqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_pgsqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _pgsqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_pgsqlInsert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index f6e79b76..d83fff64 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -18,6 +18,14 @@ namespace FreeSql.Odbc.PostgreSQL { } + internal string InternalTableAlias; + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); @@ -65,6 +73,7 @@ namespace FreeSql.Odbc.PostgreSQL if (_table.Primarys.Length == 1) { var pk = _table.Primarys.First(); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); return; } @@ -73,6 +82,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var pk in _table.Primarys) { if (pkidx > 0) caseWhen.Append(" || '+' || "); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); ++pkidx; } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index dee8daae..181803a4 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -27,6 +27,7 @@ namespace FreeSql.Odbc.PostgreSQL public IUpdate Update(object dywhere) where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcPostgreSQLInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 4491d2ab..4fc3e5f0 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -1,9 +1,7 @@ using FreeSql.Internal; -using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; -using System.Data.Common; using System.Text; using System.Threading.Tasks; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs new file mode 100644 index 00000000..85f74a23 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -0,0 +1,43 @@ +using FreeSql.Internal; +using System; +using System.Linq; +using System.Text; + +namespace FreeSql.Odbc.SqlServer +{ + + class OdbcSqlServerInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public OdbcSqlServerInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") + .Append("USING ("); + WriteSourceSelectUnionAll(sb); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index 5d3fd7bf..62ec8650 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -23,6 +23,7 @@ namespace FreeSql.Odbc.SqlServer public IUpdate Update(object dywhere) where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcSqlServerInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs new file mode 100644 index 00000000..981e33f9 --- /dev/null +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -0,0 +1,43 @@ +using FreeSql.Internal; +using System; +using System.Linq; +using System.Text; + +namespace FreeSql.Oracle.Curd +{ + + class OracleInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public OracleInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") + .Append("USING ("); + WriteSourceSelectUnionAll(sb); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index 9a7bebdc..9b5716cf 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -24,6 +24,7 @@ namespace FreeSql.Oracle public IUpdate Update(object dywhere) where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OracleInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index c4d87aed..2fbdf279 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -1,14 +1,11 @@ using FreeSql.Aop; -using FreeSql.Internal; using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; -using System.Data.Common; using System.Linq; using System.Linq.Expressions; using System.Text; -using System.Text.RegularExpressions; using System.Threading.Tasks; namespace FreeSql.PostgreSQL.Curd diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs new file mode 100644 index 00000000..87280563 --- /dev/null +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -0,0 +1,33 @@ +using FreeSql.Internal; +using System.Linq; + +namespace FreeSql.PostgreSQL.Curd +{ + + class PostgreSQLInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public PostgreSQLInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = _source; + var ocdu = new OnConflictDoUpdate(insert); + ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); + if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + ocdu.DoNothing(); + var sql = ocdu.ToSql(); + _params = insert._params; + return sql; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index 8471653f..bb1944bb 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -77,6 +77,7 @@ namespace FreeSql.PostgreSQL public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new PostgreSQLInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index ee942b3b..0017f5c5 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -1,10 +1,8 @@ using FreeSql.Internal; -using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Linq; using System.Text; using System.Threading.Tasks; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs new file mode 100644 index 00000000..5e4870d7 --- /dev/null +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -0,0 +1,43 @@ +using FreeSql.Internal; +using System; +using System.Linq; +using System.Text; + +namespace FreeSql.SqlServer.Curd +{ + + class SqlServerInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public SqlServerInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") + .Append("USING ("); + WriteSourceSelectUnionAll(sb); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index afaf697b..2eec51aa 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -24,6 +24,7 @@ namespace FreeSql.SqlServer public IUpdate Update(object dywhere) where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new SqlServerInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs new file mode 100644 index 00000000..4c6838cb --- /dev/null +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -0,0 +1,30 @@ +using FreeSql.Internal; +using System.Linq; + +namespace FreeSql.Sqlite.Curd +{ + + class SqliteInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public SqliteInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = _source; + var sql = insert.ToSql(); + if (sql.StartsWith("INSERT INTO ") == false) return null; + _params = insert._params; + return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}"; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 8782b6d6..2c18f9b5 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -24,6 +24,7 @@ namespace FreeSql.Sqlite public IUpdate Update(object dywhere) where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IDelete Delete() where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); public IDelete Delete(object dywhere) where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new SqliteInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); public IAdo Ado { get; } public IAop Aop { get; } From 2f838e6f595b5ce71a46c92a00ce46bdb6490303 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 May 2020 02:02:59 +0800 Subject: [PATCH 0647/1029] v1.5.0-preview0521 #316 #311 #309 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 143 ++++++++++++++++++ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 177 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f6898685..0ad68af1 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 791f4273..89589ec6 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 847125c5..110891ef 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index b61cf360..9833e3ca 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index c21093e5..0be1bb8f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0-preview0509 + 1.5.0-preview0521 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index c115da28..fd76fdc4 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 323c534d..d74f315a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index aabb4060..94ed46d0 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index ebaadb91..d777d959 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1b705557..5e8502b0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2391,6 +2391,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 }) + + + + + + 可自定义解析表达式 @@ -2986,6 +3117,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3056,6 +3193,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index cd92f85c..4ffa7f40 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 2ed762f8..0f4bd0ac 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 66a5bfd9..aeda193d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index cd281049..1db93c68 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 11d056fe..470d7fc6 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 15ec7535..70b11ee5 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 5a426225..787125ec 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 807fad36..c28d3a6d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 2bd210ab..60ea79f4 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0509 + 1.5.0-preview0521 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 903a6adaa62b5ecf65776c8bbd93a8955c58bd82 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 May 2020 02:12:54 +0800 Subject: [PATCH 0648/1029] update BaseEntity readme --- Examples/base_entity/readme.md | 2 +- Extensions/FreeSql.Extensions.BaseEntity/readme.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/base_entity/readme.md b/Examples/base_entity/readme.md index de64368d..336c5241 100644 --- a/Examples/base_entity/readme.md +++ b/Examples/base_entity/readme.md @@ -114,7 +114,7 @@ using (var uow = fsql.CreateUnitOfWork()) try { - //todo ... + //todo ... BaseEntity 内部 curd 方法保持使用 uow 事务 } finally { diff --git a/Extensions/FreeSql.Extensions.BaseEntity/readme.md b/Extensions/FreeSql.Extensions.BaseEntity/readme.md index 32425019..bd1a0749 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/readme.md +++ b/Extensions/FreeSql.Extensions.BaseEntity/readme.md @@ -114,7 +114,7 @@ using (var uow = fsql.CreateUnitOfWork()) try { - //todo ... + //todo ... BaseEntity 内部 curd 方法保持使用 uow 事务 } finally { From e395add4ca7be8f95e0681ab2cdb261378d335f4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 May 2020 11:35:18 +0800 Subject: [PATCH 0649/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSqlBuild?= =?UTF-8?q?er.UseExitAutoDisposePool=20=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 8 ++++++++ FreeSql/FreeSqlBuilder.cs | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5e8502b0..931f82fe 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -755,6 +755,14 @@ + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池 + 默认值: true + + + + 转小写同步结构 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 4a07cecf..05f3c979 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -22,6 +22,7 @@ namespace FreeSql bool _isNoneCommandParameter = false; bool _isGenerateCommandParameterWithLambda = false; bool _isLazyLoading = false; + bool _isExitAutoDisposePool = true; StringConvertType _entityPropertyConvertType = StringConvertType.None; NameConvertType _nameConvertType = NameConvertType.None; Action _aopCommandExecuting = null; @@ -151,6 +152,18 @@ namespace FreeSql return this; } + /// + /// 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池 + /// 默认值: true + /// + /// + /// + public FreeSqlBuilder UseExitAutoDisposePool(bool value) + { + _isExitAutoDisposePool = value; + return this; + } + public IFreeSql Build() => Build(); public IFreeSql Build() { @@ -374,6 +387,9 @@ namespace FreeSql e.ModifyResult.Name = $"{schema}.{e.EntityType.Name}"; } }); + + ret.Ado.MasterPool.Policy.IsAutoDisposeWithSystem = _isExitAutoDisposePool; + ret.Ado.SlavePools.ForEach(a => a.Policy.IsAutoDisposeWithSystem = _isExitAutoDisposePool); } return ret; From 97d8c39e1a5a22f1d68dea2e725825ec25badfff Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 21 May 2020 11:56:53 +0800 Subject: [PATCH 0650/1029] update Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index bb475b21..d4bf0964 100644 --- a/readme.md +++ b/readme.md @@ -190,7 +190,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ## 💕 Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元 > Thank you for your donation From 99f0dd73915473e5d9bf3f0ba98da6627500392a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 May 2020 18:20:28 +0800 Subject: [PATCH 0651/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IUpdate.SetS?= =?UTF-8?q?ourceIgnore=20=E6=96=B9=E6=B3=95=EF=BC=8C=E5=8F=AF=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=BF=BD=E7=95=A5=20null=20=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E7=9A=84=E6=9B=B4=E6=96=B0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 2 +- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 14 +++++++++++ .../Dameng/Curd/DamengUpdateTest.cs | 14 +++++++++++ .../Default/Curd/OdbcUpdateTest.cs | 14 +++++++++++ .../MySql/Curd/MySqlUpdateTest.cs | 14 +++++++++++ .../Oracle/Curd/OracleUpdateTest.cs | 14 +++++++++++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 14 +++++++++++ .../SqlServer/Curd/SqlServerUpdateTest.cs | 14 +++++++++++ .../Dameng/Curd/DamengUpdateTest.cs | 14 +++++++++++ .../MsAccess/Curd/MsAccessUpdateTest.cs | 14 +++++++++++ .../MySql/Curd/MySqlUpdateTest.cs | 14 +++++++++++ .../Oracle/Curd/OracleUpdateTest.cs | 14 +++++++++++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 15 +++++++++++- .../SqlServer/Curd/SqlServerUpdateTest.cs | 15 +++++++++++- .../Sqlite/Curd/SqliteUpdateTest.cs | 14 +++++++++++ FreeSql/FreeSql.xml | 22 ++++++++++++++---- FreeSql/FreeSqlBuilder.cs | 10 ++------ FreeSql/Interface/Curd/IUpdate.cs | 23 +++++++++++++++---- .../Internal/CommonProvider/UpdateProvider.cs | 12 +++++++++- 19 files changed, 246 insertions(+), 21 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 256a8653..385e38a5 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -72,7 +72,7 @@ namespace base_entity //.UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") - .UseMonitorCommand(cmd => Console.Write(cmd.CommandText)) + .UseMonitorCommand(cmd => Console.WriteLine(cmd.CommandText)) .UseLazyLoading(true) .Build(); BaseEntity.Initialization(fsql, () => _asyncUow.Value); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 69bbb16c..646a508b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -93,6 +93,20 @@ namespace FreeSql.Tests.MySqlConnector public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE `tssi01` SET `tint` = 10 WHERE (`id` = '00000000-0000-0000-0000-000000000000')", + g.mysql.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs index 8d77def2..8375a89b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs @@ -73,6 +73,20 @@ namespace FreeSql.Tests.Odbc.Dameng public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.dameng.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs index 0754dca8..77a5e25e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs @@ -65,6 +65,20 @@ namespace FreeSql.Tests.Odbc.Default public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE [tssi01] SET [tint] = 10 WHERE ([id] = '00000000-0000-0000-0000-000000000000')", + g.odbc.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs index 5c25af37..0ea494df 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -93,6 +93,20 @@ namespace FreeSql.Tests.Odbc.MySql public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE `tssi01` SET `tint` = 10 WHERE (`id` = '00000000-0000-0000-0000-000000000000')", + g.mysql.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs index f98c637a..f71c827d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -63,6 +63,20 @@ namespace FreeSql.Tests.Odbc.Oracle public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.oracle.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index fab9e9a8..a474aea2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -64,6 +64,20 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"tssi01\" SET \"tint\" = 10 WHERE (\"id\" = '00000000-0000-0000-0000-000000000000')", + g.pgsql.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs index 882a52fa..237b8064 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs @@ -66,6 +66,20 @@ namespace FreeSql.Tests.Odbc.SqlServer public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE [tssi01] SET [tint] = 10 WHERE ([id] = '00000000-0000-0000-0000-000000000000')", + g.sqlserver.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs index d1285cbb..06c53408 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs @@ -73,6 +73,20 @@ namespace FreeSql.Tests.Dameng public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.dameng.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs index 87a4ffee..d493de00 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs @@ -75,6 +75,20 @@ namespace FreeSql.Tests.MsAccess public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE [tssi01] SET [tint] = 10 WHERE ([id] = '00000000-0000-0000-0000-000000000000')", + g.msaccess.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 0d3e1218..5ff9a1b3 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -94,6 +94,20 @@ namespace FreeSql.Tests.MySql public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE `tssi01` SET `tint` = 10 WHERE (`id` = '00000000-0000-0000-0000-000000000000')", + g.mysql.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 5b35fe60..13abb3ef 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -63,6 +63,20 @@ namespace FreeSql.Tests.Oracle public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.oracle.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 602195ff..47267c86 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -63,7 +63,20 @@ namespace FreeSql.Tests.PostgreSQL public int id2 { get; set; } public string xx { get; set; } } - + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"tssi01\" SET \"tint\" = 10 WHERE (\"id\" = '00000000-0000-0000-0000-000000000000')", + g.pgsql.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } [Fact] public void IgnoreColumns() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 0bbb6a58..80474061 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -74,7 +74,20 @@ namespace FreeSql.Tests.SqlServer public int id2 { get; set; } public string xx { get; set; } } - + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE [tssi01] SET [tint] = 10 WHERE ([id] = '00000000-0000-0000-0000-000000000000')", + g.sqlserver.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } [Fact] public void IgnoreColumns() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index 577637c5..49c868b5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -65,6 +65,20 @@ namespace FreeSql.Tests.Sqlite public string xx { get; set; } } [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"tssi01\" SET \"tint\" = 10 WHERE (\"id\" = '00000000-0000-0000-0000-000000000000')", + g.sqlite.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 931f82fe..40b864cc 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2048,30 +2048,44 @@ 实体集合 + + + 更新数据,设置更新的实体,同时设置忽略的列 + 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null) + 注意:参数 ignore 与 IUpdate.IgnoreColumns/UpdateColumns 不能同时使用 + + 实体 + 属性值忽略判断, true忽略 + + - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + 注意:不能与 UpdateColumns 不能同时使用 lambda选择列 - 忽略的列 + 忽略的列 + 注意:不能与 UpdateColumns 不能同时使用 属性名,或者字段名 - 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + 注意:不能与 IgnoreColumns 不能同时使用 lambda选择列 - 指定的列 + 指定的列 + 注意:不能与 IgnoreColumns 同时使用 属性名,或者字段名 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 05f3c979..83bb76ff 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -250,15 +250,9 @@ namespace FreeSql ret.CodeFirst.IsLazyLoading = _isLazyLoading; if (_aopCommandExecuting != null) - ret.Aop.CommandBefore += new EventHandler((s, e) => - { - _aopCommandExecuting?.Invoke(e.Command); - }); + ret.Aop.CommandBefore += new EventHandler((s, e) => _aopCommandExecuting?.Invoke(e.Command)); if (_aopCommandExecuted != null) - ret.Aop.CommandAfter += new EventHandler((s, e) => - { - _aopCommandExecuted?.Invoke(e.Command, e.Log); - }); + ret.Aop.CommandAfter += new EventHandler((s, e) => _aopCommandExecuted?.Invoke(e.Command, e.Log)); this.EntityPropertyNameConvert(ret); //添加实体属性名全局AOP转换处理 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 4d40419e..cc28b273 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -57,28 +57,41 @@ namespace FreeSql /// 实体集合 /// IUpdate SetSource(IEnumerable source); - /// - /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + /// 更新数据,设置更新的实体,同时设置忽略的列 + /// 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null) + /// 注意:参数 ignore 与 IUpdate.IgnoreColumns/UpdateColumns 不能同时使用 + /// + /// 实体 + /// 属性值忽略判断, true忽略 + /// + IUpdate SetSourceIgnore(T1 source, Func ignore); + + /// + /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + /// 注意:不能与 UpdateColumns 不能同时使用 /// /// lambda选择列 /// IUpdate IgnoreColumns(Expression> columns); /// - /// 忽略的列 + /// 忽略的列 + /// 注意:不能与 UpdateColumns 不能同时使用 /// /// 属性名,或者字段名 /// IUpdate IgnoreColumns(string[] columns); /// - /// 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + /// 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + /// 注意:不能与 IgnoreColumns 不能同时使用 /// /// lambda选择列 /// IUpdate UpdateColumns(Expression> columns); /// - /// 指定的列 + /// 指定的列 + /// 注意:不能与 IgnoreColumns 同时使用 /// /// 属性名,或者字段名 /// diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index df335d50..1757826b 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -55,7 +55,7 @@ namespace FreeSql.Internal.CommonProvider { if (_table == null || _table.Type == typeof(object)) return; foreach (var col in _table.Columns.Values) - if (col.Attribute.CanUpdate == false) + if (col.Attribute.CanUpdate == false && _ignore.ContainsKey(col.Attribute.Name) == false) _ignore.Add(col.Attribute.Name, true); } protected void ClearData() @@ -375,6 +375,16 @@ namespace FreeSql.Internal.CommonProvider _source.AddRange(source.Where(a => a != null)); return this; } + public IUpdate SetSourceIgnore(T1 source, Func ignore) + { + if (ignore == null) throw new ArgumentNullException(nameof(ignore)); + var columns = _table.Columns.Values + .Where(col => ignore(_orm.GetEntityValueWithPropertyName(_table.Type, source, col.CsName))) + .Select(col => col.Attribute.Name).ToArray(); + IgnoreColumns(columns); + IgnoreCanUpdate(); + return SetSource(source); + } protected void SetPriv(ColumnInfo col, object value) { From fd7d627603704f9346adb84baf6f6deb9375efe3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 22 May 2020 18:22:57 +0800 Subject: [PATCH 0652/1029] v1.5.0-preview0522 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 4 +++- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 0ad68af1..cf68ca8f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 89589ec6..e73cf646 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 110891ef..9e2cf461 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 9833e3ca..603eb9df 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 0be1bb8f..9fb997c5 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0-preview0521 + 1.5.0-preview0522 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index fd76fdc4..28719a32 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index d74f315a..7c7995ee 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..13ddf83b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,7 +486,9 @@ - + + +Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])"> 批量注入 Repository,可以参考代码自行调整 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 94ed46d0..5e6277fa 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index d777d959..ee71bd82 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 4ffa7f40..40b22059 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 0f4bd0ac..c44a8a32 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index aeda193d..6cdaafdf 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 1db93c68..704ec820 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 470d7fc6..4fd5fd68 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 70b11ee5..d9fd24aa 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 787125ec..0431c63f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c28d3a6d..e35eae49 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 60ea79f4..7907eccc 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0521 + 1.5.0-preview0522 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 45f06c3025f160a3549c0b12c8684dbb54bc5222 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 May 2020 00:50:24 +0800 Subject: [PATCH 0653/1029] update internal code --- Extensions/FreeSql.Generator/ConsoleApp.cs | 18 +++++++++--------- .../FreeSql.Generator/RazorContentManager.cs | 2 ++ .../DbContext/DbContextScopedFreeSql.cs | 11 ++++++----- FreeSql/Interface/IFreeSql.cs | 1 + 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 5ffb8fdb..cf65031c 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -257,15 +257,15 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 RazorEngine.Engine.Razor.Run(razorId, sw, null, model); StringBuilder plus = new StringBuilder(); - plus.AppendLine("//------------------------------------------------------------------------------"); - plus.AppendLine("// "); - plus.AppendLine("// 此代码由工具 FreeSql.Generator 生成。"); - plus.AppendLine("// 运行时版本:" + Environment.Version.ToString()); - plus.AppendLine("// Website: https://github.com/2881099/FreeSql"); - plus.AppendLine("// 对此文件的更改可能会导致不正确的行为,并且如果"); - plus.AppendLine("// 重新生成代码,这些更改将会丢失。"); - plus.AppendLine("// "); - plus.AppendLine("//------------------------------------------------------------------------------"); + //plus.AppendLine("//------------------------------------------------------------------------------"); + //plus.AppendLine("// "); + //plus.AppendLine("// 此代码由工具 FreeSql.Generator 生成。"); + //plus.AppendLine("// 运行时版本:" + Environment.Version.ToString()); + //plus.AppendLine("// Website: https://github.com/2881099/FreeSql"); + //plus.AppendLine("// 对此文件的更改可能会导致不正确的行为,并且如果"); + //plus.AppendLine("// 重新生成代码,这些更改将会丢失。"); + //plus.AppendLine("// "); + //plus.AppendLine("//------------------------------------------------------------------------------"); plus.Append(sw.ToString()); plus.AppendLine(); diff --git a/Extensions/FreeSql.Generator/RazorContentManager.cs b/Extensions/FreeSql.Generator/RazorContentManager.cs index e881aa80..a5d9de6b 100644 --- a/Extensions/FreeSql.Generator/RazorContentManager.cs +++ b/Extensions/FreeSql.Generator/RazorContentManager.cs @@ -50,6 +50,7 @@ switch (gen.fsql.Ado.DataType) { break; } } + namespace @gen.NameSpace { @if (string.IsNullOrEmpty(gen.table.Comment) == false) { @@ -133,6 +134,7 @@ switch (gen.fsql.Ado.DataType) { break; } } + namespace @gen.NameSpace { @if (string.IsNullOrEmpty(gen.table.Comment) == false) { diff --git a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs index d82d4224..3aef53e4 100644 --- a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs +++ b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs @@ -37,7 +37,7 @@ namespace FreeSql { var db = _resolveDbContext?.Invoke(); db?.FlushCommand(); - var select = _originalFsql.Select().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction(false)); + var select = _originalFsql.Select().WithTransaction(_resolveUnitOfWork?.Invoke()?.GetOrBeginTransaction(false)); if (db?.Options.EnableGlobalFilter == false) select.DisableGlobalFilter(); return select; } @@ -47,7 +47,7 @@ namespace FreeSql { var db = _resolveDbContext?.Invoke(); db?.FlushCommand(); - var delete = _originalFsql.Delete().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + var delete = _originalFsql.Delete().WithTransaction(_resolveUnitOfWork?.Invoke()?.GetOrBeginTransaction()); if (db?.Options.EnableGlobalFilter == false) delete.DisableGlobalFilter(); return delete; } @@ -57,7 +57,7 @@ namespace FreeSql { var db = _resolveDbContext?.Invoke(); db?.FlushCommand(); - var update = _originalFsql.Update().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + var update = _originalFsql.Update().WithTransaction(_resolveUnitOfWork?.Invoke()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) update.NoneParameter(db.Options.NoneParameter.Value); if (db?.Options.EnableGlobalFilter == false) update.DisableGlobalFilter(); return update; @@ -68,7 +68,7 @@ namespace FreeSql { var db = _resolveDbContext?.Invoke(); db?.FlushCommand(); - var insert = _originalFsql.Insert().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + var insert = _originalFsql.Insert().WithTransaction(_resolveUnitOfWork?.Invoke()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) insert.NoneParameter(db.Options.NoneParameter.Value); return insert; } @@ -76,11 +76,12 @@ namespace FreeSql public IInsert Insert(T1[] source) where T1 : class => Insert().AppendData(source); public IInsert Insert(List source) where T1 : class => Insert().AppendData(source); public IInsert Insert(IEnumerable source) where T1 : class => Insert().AppendData(source); + public IInsertOrUpdate InsertOrUpdate() where T1 : class { var db = _resolveDbContext?.Invoke(); db?.FlushCommand(); - return _originalFsql.InsertOrUpdate().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); + return _originalFsql.InsertOrUpdate().WithTransaction(_resolveUnitOfWork?.Invoke()?.GetOrBeginTransaction()); } } } diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index 72230929..e2e973a9 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -52,6 +52,7 @@ public interface IFreeSql : IDisposable /// Oracle: merge into /// Sqlite: replace into /// Dameng: merge into + /// 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法 /// /// /// From 511d8f909a6e27408b69b1b5e16420f2b2aa551d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 May 2020 18:17:54 +0800 Subject: [PATCH 0654/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=E6=9C=AA?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E7=9A=84=E5=8A=9F=E8=83=BD=20IFreeSql.Insert?= =?UTF-8?q?OrUpdate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 18 --- .../Curd/MySqlInsertOrUpdateTest.cs | 87 +++++++++++ .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 143 +++++++++++++++++ .../MySql/Curd/MySqlInsertOrUpdateTest.cs | 87 +++++++++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 144 ++++++++++++++++++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 87 +++++++++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 141 +++++++++++++++++ .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 144 ++++++++++++++++++ .../MySql/Curd/MySqlInsertOrUpdateTest.cs | 87 +++++++++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 144 ++++++++++++++++++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 87 +++++++++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 141 +++++++++++++++++ .../Sqlite/Curd/SqliteInsertOrUpdateTest.cs | 76 +++++++++ FreeSql/FreeSql.xml | 8 + .../CommonProvider/InsertOrUpdateProvider.cs | 134 +++++++++++++++- .../Curd/DamengInsertOrUpdate.cs | 64 +++++--- .../Curd/MySqlInsertOrUpdate.cs | 39 +++-- .../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 64 +++++--- .../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 37 +++-- .../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 64 +++++--- .../Curd/OdbcPostgreSQLInsertOrUpdate.cs | 48 ++++-- .../Curd/OdbcSqlServerInsertOrUpdate.cs | 67 +++++--- .../Curd/OracleInsertOrUpdate.cs | 64 +++++--- .../Curd/PostgreSQLInsertOrUpdate.cs | 48 ++++-- .../Curd/SqlServerInsertOrUpdate.cs | 67 +++++--- .../Curd/SqliteInsertOrUpdate.cs | 42 +++-- 26 files changed, 1948 insertions(+), 184 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 13ddf83b..132d875e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -488,14 +481,3 @@ -Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])"> - - 批量注入 Repository,可以参考代码自行调整 - - - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs index 6198c553..91b56e34 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateTest.cs @@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(2, '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(5, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`) + +; + +INSERT INTO `tbiou022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(12, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs index e3832aaa..3901c553 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -154,6 +154,149 @@ WHEN NOT MATCHED THEN public int id { get; set; } public string name { get; set; } } + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('01') +INTO ""TBIOU022""(""NAME"") VALUES('02') +INTO ""TBIOU022""(""NAME"") VALUES('03') +INTO ""TBIOU022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('001') +INTO ""TBIOU022""(""NAME"") VALUES('002') +INTO ""TBIOU022""(""NAME"") VALUES('003') +INTO ""TBIOU022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('00001') +INTO ""TBIOU022""(""NAME"") VALUES('00002') +INTO ""TBIOU022""(""NAME"") VALUES('00003') +INTO ""TBIOU022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs index 3b9fc212..283e8e75 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateTest.cs @@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(2, '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`) + +; + +INSERT INTO `tbiou022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(12, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs index 156bebbf..8ed896b3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('01') +INTO ""TBIOU022""(""NAME"") VALUES('02') +INTO ""TBIOU022""(""NAME"") VALUES('03') +INTO ""TBIOU022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('001') +INTO ""TBIOU022""(""NAME"") VALUES('002') +INTO ""TBIOU022""(""NAME"") VALUES('003') +INTO ""TBIOU022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('00001') +INTO ""TBIOU022""(""NAME"") VALUES('00002') +INTO ""TBIOU022""(""NAME"") VALUES('00003') +INTO ""TBIOU022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs index 90ce4b5b..e539b712 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -95,6 +95,93 @@ ON CONFLICT(""id"") DO UPDATE SET public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"" + +; + +INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs index 0c00dbb5..90bc5604 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -154,6 +154,147 @@ WHEN NOT MATCHED THEN public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'100001' as name +UNION ALL + SELECT 2, N'100002' +UNION ALL + SELECT 3, N'100003' +UNION ALL + SELECT 4, N'100004' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF; + +; + +INSERT INTO [tbiou022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs index 54e4c38a..3a4ceb48 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('01') +INTO ""TBIOU022""(""NAME"") VALUES('02') +INTO ""TBIOU022""(""NAME"") VALUES('03') +INTO ""TBIOU022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('001') +INTO ""TBIOU022""(""NAME"") VALUES('002') +INTO ""TBIOU022""(""NAME"") VALUES('003') +INTO ""TBIOU022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('00001') +INTO ""TBIOU022""(""NAME"") VALUES('00002') +INTO ""TBIOU022""(""NAME"") VALUES('00003') +INTO ""TBIOU022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs index 3cfe1a62..471920c9 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateTest.cs @@ -57,6 +57,93 @@ ON DUPLICATE KEY UPDATE public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(2, '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(5, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`) + +; + +INSERT INTO `tbiou022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(12, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs index e645b7fc..d383cea5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -154,6 +154,150 @@ WHEN NOT MATCHED THEN public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('01') +INTO ""TBIOU022""(""NAME"") VALUES('02') +INTO ""TBIOU022""(""NAME"") VALUES('03') +INTO ""TBIOU022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('001') +INTO ""TBIOU022""(""NAME"") VALUES('002') +INTO ""TBIOU022""(""NAME"") VALUES('003') +INTO ""TBIOU022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('00001') +INTO ""TBIOU022""(""NAME"") VALUES('00002') +INTO ""TBIOU022""(""NAME"") VALUES('00003') +INTO ""TBIOU022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs index 1b1e853b..4049b04d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -95,6 +95,93 @@ ON CONFLICT(""id"") DO UPDATE SET public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"" + +; + +INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs index 7858a27d..dcbb2a3b 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -156,6 +156,147 @@ WHEN NOT MATCHED THEN public int id { get; set; } public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as id, N'100001' as name +UNION ALL + SELECT 2, N'100002' +UNION ALL + SELECT 3, N'100003' +UNION ALL + SELECT 4, N'100004' ) t2 ON (t1.[id] = t2.id) +WHEN MATCHED THEN + update set [name] = t2.name +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbiou022] OFF; + +; + +INSERT INTO [tbiou022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } [Fact] public void InsertOrUpdate_TwoPrimary() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs index 0412c2fa..2e793f17 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs @@ -81,6 +81,82 @@ namespace FreeSql.Tests.Sqlite public string name { get; set; } } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(2, '02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"REPLACE INTO ""tbiou022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') + +; + +INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void InsertOrUpdate_TwoPrimary() { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 40b864cc..f4fd5b54 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2994,6 +2994,13 @@ + + + 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert + + + + AsType, Ctor, ClearData 三处地方需要重新加载 @@ -3770,6 +3777,7 @@ Oracle: merge into Sqlite: replace into Dameng: merge into + 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法 diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 42fe4bee..ba76d54d 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -25,6 +25,7 @@ namespace FreeSql.Internal.CommonProvider protected DbParameter[] _params; protected DbTransaction _transaction; protected DbConnection _connection; + public ColumnInfo IdentityColumn { get; } public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { @@ -33,6 +34,7 @@ namespace FreeSql.Internal.CommonProvider _commonExpression = commonExpression; _table = _commonUtils.GetTableByEntity(typeof(T1)); if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault(); } protected void ClearData() @@ -130,11 +132,10 @@ namespace FreeSql.Internal.CommonProvider return this; } - public void WriteSourceSelectUnionAll(StringBuilder sb) + public void WriteSourceSelectUnionAll(List source, StringBuilder sb, List dbParams) { - var specialParams = new List(); var didx = 0; - foreach (var d in _source) + foreach (var d in source) { if (didx > 0) sb.Append(" \r\nUNION ALL\r\n "); sb.Append("SELECT "); @@ -147,7 +148,7 @@ namespace FreeSql.Internal.CommonProvider else { object val = col.GetMapValue(d); - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(dbParams, col.Attribute.MapType, val)); } if (didx == 0) sb.Append(" as ").Append(col.Attribute.Name); ++colidx2; @@ -163,11 +164,82 @@ namespace FreeSql.Internal.CommonProvider } ++didx; } - if (specialParams.Any()) _params = specialParams.ToArray(); + } + + byte _SplitSourceByIdentityValueIsNullFlag = 0; //防止重复计算 SplitSource + /// + /// 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert + /// + /// + /// + public NaviteTuple, List> SplitSourceByIdentityValueIsNull(List source) + { + if (_SplitSourceByIdentityValueIsNullFlag == 1) return NaviteTuple.Create(source, new List()); + if (_SplitSourceByIdentityValueIsNullFlag == 2) return NaviteTuple.Create(new List(), source); + if (IdentityColumn == null) return NaviteTuple.Create(source, new List()); + var ret = NaviteTuple.Create(new List(), new List()); + foreach (var item in source) + { + if (object.Equals(_orm.GetEntityValueWithPropertyName(_table.Type, item, IdentityColumn.CsName), IdentityColumn.CsType.CreateInstanceGetDefaultValue())) + ret.Item2.Add(item); //自增无值的,记录为直接插入 + else + ret.Item1.Add(item); + } + return ret; } public abstract string ToSql(); public int ExecuteAffrows() + { + var affrows = 0; + var ss = SplitSourceByIdentityValueIsNull(_source); + try + { + if (_transaction != null) + { + _source = ss.Item1; + _SplitSourceByIdentityValueIsNullFlag = 1; + affrows += this.RawExecuteAffrows(); + _source = ss.Item2; + _SplitSourceByIdentityValueIsNullFlag = 2; + affrows += this.RawExecuteAffrows(); + } + else + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + _source = ss.Item1; + _SplitSourceByIdentityValueIsNullFlag = 1; + affrows += this.RawExecuteAffrows(); + _source = ss.Item2; + _SplitSourceByIdentityValueIsNullFlag = 2; + affrows += this.RawExecuteAffrows(); + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } + } + } + finally + { + _SplitSourceByIdentityValueIsNullFlag = 0; + ClearData(); + } + return affrows; + } + public int RawExecuteAffrows() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -193,7 +265,7 @@ namespace FreeSql.Internal.CommonProvider } #if net40 #else - async public Task ExecuteAffrowsAsync() + async public Task RawExecuteAffrowsAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -217,6 +289,56 @@ namespace FreeSql.Internal.CommonProvider } return affrows; } + async public Task ExecuteAffrowsAsync() + { + var affrows = 0; + var ss = SplitSourceByIdentityValueIsNull(_source); + try + { + if (_transaction != null) + { + _source = ss.Item1; + _SplitSourceByIdentityValueIsNullFlag = 1; + affrows += await this.RawExecuteAffrowsAsync(); + _source = ss.Item2; + _SplitSourceByIdentityValueIsNullFlag = 2; + affrows += await this.RawExecuteAffrowsAsync(); + } + else + { + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + _source = ss.Item1; + _SplitSourceByIdentityValueIsNullFlag = 1; + affrows += await this.RawExecuteAffrowsAsync(); + _source = ss.Item2; + _SplitSourceByIdentityValueIsNullFlag = 2; + affrows += await this.RawExecuteAffrowsAsync(); + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); + throw ex; + } + _transaction = null; + } + } + } + finally + { + _SplitSourceByIdentityValueIsNullFlag = 0; + ClearData(); + } + return affrows; + } #endif } } diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index 52f2e955..ec7370ad 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -1,5 +1,7 @@ using FreeSql.Internal; using System; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Text; @@ -16,28 +18,54 @@ namespace FreeSql.Dameng.Curd public override string ToSql() { if (_source?.Any() != true) return null; - if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") - .Append("USING ("); - WriteSourceSelectUnionAll(sb); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) - sb.Append("WHEN MATCHED THEN \r\n") - .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" - ))).Append(" \r\n"); + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - return sb.ToString(); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index 6d530b2f..1106945d 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -1,5 +1,9 @@ using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; +using System.Text; namespace FreeSql.MySql.Curd { @@ -15,15 +19,32 @@ namespace FreeSql.MySql.Curd { if (_source?.Any() != true) return null; - var insert = _orm.Insert() - .AsTable(_tableRule).AsType(_table.Type) - .WithConnection(_connection) - .WithTransaction(_transaction) - .NoneParameter(true) as Internal.CommonProvider.InsertProvider; - insert._source = _source; - var sql = new OnDuplicateKeyUpdate(insert).ToSql(); - _params = insert._params; - return sql; + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else sql = new OnDuplicateKeyUpdate(insert.InsertIdentity()).ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index c5826cdc..d36ee50a 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -1,5 +1,7 @@ using FreeSql.Internal; using System; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Text; @@ -16,28 +18,54 @@ namespace FreeSql.Odbc.Dameng public override string ToSql() { if (_source?.Any() != true) return null; - if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") - .Append("USING ("); - WriteSourceSelectUnionAll(sb); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) - sb.Append("WHEN MATCHED THEN \r\n") - .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" - ))).Append(" \r\n"); + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - return sb.ToString(); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index c8908805..86747427 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -1,4 +1,6 @@ using FreeSql.Internal; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; namespace FreeSql.Odbc.MySql @@ -15,15 +17,32 @@ namespace FreeSql.Odbc.MySql { if (_source?.Any() != true) return null; - var insert = _orm.Insert() - .AsTable(_tableRule).AsType(_table.Type) - .WithConnection(_connection) - .WithTransaction(_transaction) - .NoneParameter(true) as Internal.CommonProvider.InsertProvider; - insert._source = _source; - var sql = new OdbcMySqlOnDuplicateKeyUpdate(insert).ToSql(); - _params = insert._params; - return sql; + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else sql = new OdbcMySqlOnDuplicateKeyUpdate(insert.InsertIdentity()).ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index 0c151cc3..1a0766a1 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -1,5 +1,7 @@ using FreeSql.Internal; using System; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Text; @@ -16,28 +18,54 @@ namespace FreeSql.Odbc.Oracle public override string ToSql() { if (_source?.Any() != true) return null; - if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") - .Append("USING ("); - WriteSourceSelectUnionAll(sb); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) - sb.Append("WHEN MATCHED THEN \r\n") - .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" - ))).Append(" \r\n"); + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - return sb.ToString(); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs index ec291e6b..311e46b2 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -1,4 +1,6 @@ using FreeSql.Internal; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; namespace FreeSql.Odbc.PostgreSQL @@ -15,19 +17,39 @@ namespace FreeSql.Odbc.PostgreSQL { if (_source?.Any() != true) return null; - var insert = _orm.Insert() - .AsTable(_tableRule).AsType(_table.Type) - .WithConnection(_connection) - .WithTransaction(_transaction) - .NoneParameter(true) as Internal.CommonProvider.InsertProvider; - insert._source = _source; - var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert); - ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) - ocdu.DoNothing(); - var sql = ocdu.ToSql(); - _params = insert._params; - return sql; + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else + { + var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert.InsertIdentity()); + ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); + if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + ocdu.DoNothing(); + sql = ocdu.ToSql(); + } + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index 85f74a23..69b11d78 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -1,5 +1,7 @@ using FreeSql.Internal; using System; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Text; @@ -16,28 +18,59 @@ namespace FreeSql.Odbc.SqlServer public override string ToSql() { if (_source?.Any() != true) return null; - if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder(); + if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n"); + sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") .Append("USING ("); - WriteSourceSelectUnionAll(sb); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) - sb.Append("WHEN MATCHED THEN \r\n") - .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" - ))).Append(" \r\n"); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); - return sb.ToString(); + if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index 981e33f9..426f1f16 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -1,5 +1,7 @@ using FreeSql.Internal; using System; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Text; @@ -16,28 +18,54 @@ namespace FreeSql.Oracle.Curd public override string ToSql() { if (_source?.Any() != true) return null; - if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") - .Append("USING ("); - WriteSourceSelectUnionAll(sb); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) - sb.Append("WHEN MATCHED THEN \r\n") - .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" - ))).Append(" \r\n"); + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - return sb.ToString(); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index 87280563..a8a48263 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -1,4 +1,6 @@ using FreeSql.Internal; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; namespace FreeSql.PostgreSQL.Curd @@ -15,19 +17,39 @@ namespace FreeSql.PostgreSQL.Curd { if (_source?.Any() != true) return null; - var insert = _orm.Insert() - .AsTable(_tableRule).AsType(_table.Type) - .WithConnection(_connection) - .WithTransaction(_transaction) - .NoneParameter(true) as Internal.CommonProvider.InsertProvider; - insert._source = _source; - var ocdu = new OnConflictDoUpdate(insert); - ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) - ocdu.DoNothing(); - var sql = ocdu.ToSql(); - _params = insert._params; - return sql; + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else + { + var ocdu = new OnConflictDoUpdate(insert.InsertIdentity()); + ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); + if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + ocdu.DoNothing(); + sql = ocdu.ToSql(); + } + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index 5e4870d7..f8162605 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -1,5 +1,7 @@ using FreeSql.Internal; using System; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Text; @@ -16,28 +18,59 @@ namespace FreeSql.SqlServer.Curd public override string ToSql() { if (_source?.Any() != true) return null; - if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder(); + if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n"); + sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") .Append("USING ("); - WriteSourceSelectUnionAll(sb); - sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) - sb.Append("WHEN MATCHED THEN \r\n") - .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : - $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" - ))).Append(" \r\n"); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); + cols = _table.Columns.Values; + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); - return sb.ToString(); + if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index 4c6838cb..ba2d2189 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -1,4 +1,7 @@ using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; using System.Linq; namespace FreeSql.Sqlite.Curd @@ -15,16 +18,35 @@ namespace FreeSql.Sqlite.Curd { if (_source?.Any() != true) return null; - var insert = _orm.Insert() - .AsTable(_tableRule).AsType(_table.Type) - .WithConnection(_connection) - .WithTransaction(_transaction) - .NoneParameter(true) as Internal.CommonProvider.InsertProvider; - insert._source = _source; - var sql = insert.ToSql(); - if (sql.StartsWith("INSERT INTO ") == false) return null; - _params = insert._params; - return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}"; + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + + if (IdentityColumn != null && flagInsert == false) insert.InsertIdentity(); + + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + if (IdentityColumn != null && flagInsert) return sql; + + if (sql.StartsWith("INSERT INTO ") == false) return null; + return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}"; + } } } } \ No newline at end of file From 19edb9bd2c3c536e49584ecf856d030f142f0ef6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 May 2020 18:21:08 +0800 Subject: [PATCH 0655/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=85=B3?= =?UTF-8?q?=E9=97=AD=20fsql.Transaction=20=E7=BA=BF=E7=A8=8B=E4=BA=8B?= =?UTF-8?q?=E5=8A=A1=E8=87=AA=E5=8A=A8=E6=8F=90=E4=BA=A4=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=EF=BC=9B#323?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdoProvider/AdoProviderTransaction.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index bed124cb..251dd2bc 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -65,11 +65,12 @@ namespace FreeSql.Internal.CommonProvider private void CommitTimeoutTransaction() { - if (_trans.Count > 0) - { - var trans = _trans.Values.Where(st2 => DateTime.Now.Subtract(st2.RunTime) > st2.Timeout).ToArray(); - foreach (var tran in trans) CommitTransaction(true, tran, null, "Timeout自动提交"); - } + //关闭 fsql.Transaction 线程事务自动提交机制 https://github.com/dotnetcore/FreeSql/issues/323 + //if (_trans.Count > 0) + //{ + // var trans = _trans.Values.Where(st2 => DateTime.Now.Subtract(st2.RunTime) > st2.Timeout).ToArray(); + // foreach (var tran in trans) CommitTransaction(true, tran, null, "Timeout自动提交"); + //} } private void CommitTransaction(bool isCommit, Transaction2 tran, Exception rollbackException, string remark = null) { From ce3bd7da1d73aa7cdaf3698bf732b73573480cf5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 May 2020 18:23:37 +0800 Subject: [PATCH 0656/1029] v1.5.0-preview0523 #323 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index cf68ca8f..a4d167c9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e73cf646..3bd86015 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 9e2cf461..ccbcded3 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 603eb9df..6662031e 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 9fb997c5..ec0071de 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0-preview0522 + 1.5.0-preview0523 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 28719a32..8a229a22 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 7c7995ee..34c09bfb 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5e6277fa..4e121532 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index ee71bd82..45986b5a 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 40b22059..607288ae 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index c44a8a32..d3c0651e 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6cdaafdf..69aba6cd 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 704ec820..fb5e3615 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 4fd5fd68..d2fd1005 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d9fd24aa..43da526f 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0431c63f..a69fe36e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e35eae49..7b05a19d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7907eccc..5df1fc1c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0522 + 1.5.0-preview0523 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From b3352faef5a8df4697918667fddc77527d9491d7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 May 2020 18:55:33 +0800 Subject: [PATCH 0657/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=20fsql.Transaction=20=E7=BA=BF=E7=A8=8B=E4=BA=8B?= =?UTF-8?q?=E5=8A=A1=E8=B6=85=E6=97=B6=E6=9C=BA=E5=88=B6=EF=BC=9B#323?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DbContext/DbContextScopedFreeSql.cs | 3 +-- FreeSql/FreeSql.xml | 26 +++++-------------- FreeSql/Interface/IAdo.cs | 11 ++------ FreeSql/Interface/IFreeSql.cs | 15 ++++------- .../AdoProvider/AdoProviderTransaction.cs | 13 +++++----- .../FreeSql.Provider.Dameng/DamengProvider.cs | 3 +-- .../MsAccessProvider.cs | 3 +-- .../FreeSql.Provider.MySql/MySqlProvider.cs | 3 +-- .../Dameng/OdbcDamengProvider.cs | 3 +-- .../Default/OdbcProvider.cs | 3 +-- .../MySql/OdbcMySqlProvider.cs | 3 +-- .../Oracle/OdbcOracleProvider.cs | 3 +-- .../PostgreSQL/OdbcPostgreSQLProvider.cs | 3 +-- .../SqlServer/OdbcSqlServerProvider.cs | 3 +-- .../FreeSql.Provider.Oracle/OracleProvider.cs | 3 +-- .../PostgreSQLProvider.cs | 3 +-- .../SqlServerProvider.cs | 3 +-- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 3 +-- 18 files changed, 33 insertions(+), 74 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs index 3aef53e4..adeaab0d 100644 --- a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs +++ b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs @@ -30,8 +30,7 @@ namespace FreeSql public void Dispose() { } public void Transaction(Action handler) => _originalFsql.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => _originalFsql.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => _originalFsql.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => _originalFsql.Transaction(isolationLevel, handler); public ISelect Select() where T1 : class { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index f4fd5b54..5545a967 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2257,25 +2257,17 @@ - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - 开启事务(不支持异步) - 超时,未执行完成(可能)被其他线程事务自动提交 事务体 () => {} - + 开启事务(不支持异步) 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 @@ -3829,24 +3821,18 @@ - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 事务体 () => {} - + - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index b520f690..6db5bbd1 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -39,23 +39,16 @@ namespace FreeSql #region 事务 /// - /// 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + /// 开启事务(不支持异步) /// /// 事务体 () => {} void Transaction(Action handler); /// /// 开启事务(不支持异步) /// - /// 超时,未执行完成(可能)被其他线程事务自动提交 - /// 事务体 () => {} - void Transaction(TimeSpan timeout, Action handler); - /// - /// 开启事务(不支持异步) - /// /// /// 事务体 () => {} - /// 超时,未执行完成(可能)被其他线程事务自动提交 - void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler); + void Transaction(IsolationLevel isolationLevel, Action handler); /// /// 当前线程的事务 /// diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index e2e973a9..bb42ba92 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -101,23 +101,18 @@ public interface IFreeSql : IDisposable IDelete Delete(object dywhere) where T1 : class; /// - /// 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 + /// 开启事务(不支持异步) + /// v1.5.0 关闭了线程事务超时自动提交的机制 /// /// 事务体 () => {} void Transaction(Action handler); /// - /// 开启事务(不支持异步) - /// - /// 超时,未执行完成(可能)被其他线程事务自动提交 - /// 事务体 () => {} - void Transaction(TimeSpan timeout, Action handler); - /// - /// 开启事务(不支持异步) + /// 开启事务(不支持异步) + /// v1.5.0 关闭了线程事务超时自动提交的机制 /// /// /// 事务体 () => {} - /// 超时,未执行完成(可能)被其他线程事务自动提交 - void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler); + void Transaction(IsolationLevel isolationLevel, Action handler); /// /// 数据库访问对象 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 251dd2bc..41c4f539 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -35,7 +35,7 @@ namespace FreeSql.Internal.CommonProvider public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null; public Aop.TraceBeforeEventArgs TransactionCurrentThreadAopBefore => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.AopBefore : null; - public void BeginTransaction(TimeSpan timeout, IsolationLevel? isolationLevel) + public void BeginTransaction(IsolationLevel? isolationLevel) { if (TransactionCurrentThread != null) return; @@ -48,7 +48,7 @@ namespace FreeSql.Internal.CommonProvider try { conn = MasterPool.Get(); - tran = new Transaction2(conn, isolationLevel == null ? conn.Value.BeginTransaction() : conn.Value.BeginTransaction(isolationLevel.Value), timeout); + tran = new Transaction2(conn, isolationLevel == null ? conn.Value.BeginTransaction() : conn.Value.BeginTransaction(isolationLevel.Value), TimeSpan.FromSeconds(60)); tran.AopBefore = before; } catch (Exception ex) @@ -107,15 +107,14 @@ namespace FreeSql.Internal.CommonProvider if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(false, tran, ex); } - public void Transaction(Action handler) => TransactionInternal(null, TimeSpan.FromSeconds(60), handler); - public void Transaction(TimeSpan timeout, Action handler) => TransactionInternal(null, timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => TransactionInternal(isolationLevel, timeout, handler); + public void Transaction(Action handler) => TransactionInternal(null, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => TransactionInternal(isolationLevel, handler); - void TransactionInternal(IsolationLevel? isolationLevel, TimeSpan timeout, Action handler) + void TransactionInternal(IsolationLevel? isolationLevel, Action handler) { try { - BeginTransaction(timeout, isolationLevel); + BeginTransaction(isolationLevel); handler(); CommitTransaction(); } diff --git a/Providers/FreeSql.Provider.Dameng/DamengProvider.cs b/Providers/FreeSql.Provider.Dameng/DamengProvider.cs index c6903675..64b83116 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengProvider.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengProvider.cs @@ -46,8 +46,7 @@ namespace FreeSql.Dameng internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs index 1160eec7..9632ec87 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs @@ -45,8 +45,7 @@ namespace FreeSql.MsAccess internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index c1d533fc..8ebe5666 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -72,8 +72,7 @@ namespace FreeSql.MySql internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs index 3adf7d01..3644623c 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs @@ -45,8 +45,7 @@ namespace FreeSql.Odbc.Dameng internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index 6459f13f..138487cb 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -86,8 +86,7 @@ namespace FreeSql.Odbc.Default internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index e59064d9..2d97a4d2 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -50,8 +50,7 @@ namespace FreeSql.Odbc.MySql internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index 1a35a2d2..fc9449fc 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -51,8 +51,7 @@ namespace FreeSql.Odbc.Oracle internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index 181803a4..041bb2f9 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -49,8 +49,7 @@ namespace FreeSql.Odbc.PostgreSQL internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index 62ec8650..ffe9ad80 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -57,8 +57,7 @@ namespace FreeSql.Odbc.SqlServer internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index 9b5716cf..f65b8200 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -46,8 +46,7 @@ namespace FreeSql.Oracle internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index bb1944bb..839b9421 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -99,8 +99,7 @@ namespace FreeSql.PostgreSQL internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index 2eec51aa..0b130c33 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -58,8 +58,7 @@ namespace FreeSql.SqlServer internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index 2c18f9b5..ddb71c02 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -47,8 +47,7 @@ namespace FreeSql.Sqlite internal CommonExpression InternalCommonExpression { get; } public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(TimeSpan timeout, Action handler) => Ado.Transaction(timeout, handler); - public void Transaction(IsolationLevel isolationLevel, TimeSpan timeout, Action handler) => Ado.Transaction(isolationLevel, timeout, handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); From bc215fd41c4586e55b1463d40a01d3f3cb585dcc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 23 May 2020 19:05:04 +0800 Subject: [PATCH 0658/1029] v1.5.0-preview0525 #323 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a4d167c9..bb7be7e6 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 3bd86015..e6d02eb3 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ccbcded3..94bb2e59 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 6662031e..2fbdfcbd 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index ec0071de..6fd7bb14 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0-preview0523 + 1.5.0-preview0525 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 8a229a22..cf7904fb 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 34c09bfb..3877950f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4e121532..3ede074b 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 45986b5a..3ed63f42 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 607288ae..e9593a3b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index d3c0651e..0a2a6d3b 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 69aba6cd..49985878 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fb5e3615..d94983ac 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d2fd1005..b6de7e77 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 43da526f..ff836522 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a69fe36e..79aceec3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 7b05a19d..050b201e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5df1fc1c..445a5180 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0523 + 1.5.0-preview0525 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 657b3c6f432cc644e0cb9422f33d0394b2b0b1b3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 02:05:05 +0800 Subject: [PATCH 0659/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20SqlServer=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20yyyyMMdd=20?= =?UTF-8?q?=E5=B8=B8=E7=94=A8=20c#=20=E6=97=A5=E6=9C=9F=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SqlServerExpression/DateTimeTest.cs | 33 +++++++++---- .../SqlServerExpression/DateTimeTest.cs | 33 +++++++++---- .../SqlServer/OdbcSqlServerExpression.cs | 47 +++++++++++++++++-- .../SqlServerExpression.cs | 45 ++++++++++++++++-- 4 files changed, 136 insertions(+), 22 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs index ab4708bc..bdeeab9e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -41,6 +41,31 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + + g.sqlserver.Insert(new Topic()).ExecuteAffrows(); + foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -269,14 +294,6 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - } [Fact] public void DateTime_Compare() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs index aafaf6a9..284cdaf3 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -49,6 +49,31 @@ namespace FreeSql.Tests.SqlServerExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + + g.sqlserver.Insert(new Topic()).ExecuteAffrows(); + foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -277,14 +302,6 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - } [Fact] public void DateTime_Compare() diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 280a6181..d8f7dc9b 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Odbc.SqlServer { @@ -374,7 +373,49 @@ namespace FreeSql.Odbc.SqlServer break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second,{args1},{left})"; - case "ToString": return exp.Arguments.Count == 0 ? $"convert(varchar, {left}, 121)" : null; + case "ToString": + if (exp.Arguments.Count == 0) return $"convert(varchar, cast({left} as datetime), 121)"; + left = $"cast({left} as datetime)"; + switch (args1.TrimStart('N')) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"convert(char(19), {left}, 120)"; + case "'yyyy-MM-dd HH:mm'": return $"substring(convert(char(19), {left}, 120), 1, 16)"; + case "'yyyy-MM-dd HH'": return $"substring(convert(char(19), {left}, 120), 1, 13)"; + case "'yyyy-MM-dd'": return $"convert(char(10), {left}, 23)"; + case "'yyyy-MM'": return $"substring(convert(char(10), {left}, 23), 1, 7)"; + case "'yyyyMMdd'": return $"convert(char(8), {left}, 112)"; + case "'yyyyMM'": return $"substring(convert(char(8), {left}, 112), 1, 6)"; + case "'yyyy'": return $"substring(convert(char(8), {left}, 112), 1, 4)"; + case "'HH:mm:ss'": return $"convert(char(8), {left}, 24)"; + } + var nchar = args1.StartsWith("N'") ? "N" : ""; + return Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"' + substring(convert(char(8), {left}, 112), 1, 4) + {nchar}'"; + case "yy": return $"' + substring(convert(char(6), {left}, 12), 1, 2) + {nchar}'"; + case "MM": return $"' + substring(convert(char(6), {left}, 12), 3, 2) + {nchar}'"; + case "M": return $"' + case when substring(convert(char(6), {left}, 12), 3, 1) = '0' then substring(convert(char(6), {left}, 12), 4, 1) else substring(convert(char(6), {left}, 12), 3, 2) end + {nchar}'"; + case "dd": return $"' + substring(convert(char(6), {left}, 12), 5, 2) + {nchar}'"; + case "d": return $"' + case when substring(convert(char(6), {left}, 12), 5, 1) = '0' then substring(convert(char(6), {left}, 12), 6, 1) else substring(convert(char(6), {left}, 12), 5, 2) end + {nchar}'"; + case "HH": return $"' + substring(convert(char(8), {left}, 24), 1, 2) + {nchar}'"; + case "H": return $"' + case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end + {nchar}'"; + case "hh": + return $"' + case cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) % 12" + + $"when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end + {nchar}'"; + case "h": + return $"' + case cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) % 12" + + $"when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end + {nchar}'"; + case "mm": return $"' + substring(convert(char(8), {left}, 24), 4, 2) + {nchar}'"; + case "m": return $"' + case when substring(convert(char(8), {left}, 24), 4, 1) = '0' then substring(convert(char(8), {left}, 24), 5, 1) else substring(convert(char(8), {left}, 24), 4, 2) end + {nchar}'"; + case "ss": return $"' + substring(convert(char(8), {left}, 24), 7, 2) + {nchar}'"; + case "s": return $"' + case when substring(convert(char(8), {left}, 24), 7, 1) = '0' then substring(convert(char(8), {left}, 24), 8, 1) else substring(convert(char(8), {left}, 24), 7, 2) end + {nchar}'"; + case "tt": return $"' + case when cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) >= 12 then 'PM' else 'AM' end + {nchar}'"; + case "t": return $"' + case when cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) >= 12 then 'P' else 'A' end + {nchar}'"; + } + return m.Groups[0].Value; + }); } } return null; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 4abd09ac..b4b7c563 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.SqlServer { @@ -374,7 +373,47 @@ namespace FreeSql.SqlServer break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second,{args1},{left})"; - case "ToString": return exp.Arguments.Count == 0 ? $"convert(varchar, {left}, 121)" : null; + case "ToString": + if (exp.Arguments.Count == 0) return $"convert(varchar, cast({left} as datetime), 121)"; + left = $"cast({left} as datetime)"; + switch (args1.TrimStart('N')) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"convert(char(19), {left}, 120)"; + case "'yyyy-MM-dd HH:mm'": return $"substring(convert(char(19), {left}, 120), 1, 16)"; + case "'yyyy-MM-dd HH'": return $"substring(convert(char(19), {left}, 120), 1, 13)"; + case "'yyyy-MM-dd'": return $"convert(char(10), {left}, 23)"; + case "'yyyy-MM'": return $"substring(convert(char(10), {left}, 23), 1, 7)"; + case "'yyyyMMdd'": return $"convert(char(8), {left}, 112)"; + case "'yyyyMM'": return $"substring(convert(char(8), {left}, 112), 1, 6)"; + case "'yyyy'": return $"substring(convert(char(8), {left}, 112), 1, 4)"; + case "'HH:mm:ss'": return $"convert(char(8), {left}, 24)"; + } + var nchar = args1.StartsWith("N'") ? "N" : ""; + return Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"' + substring(convert(char(8), {left}, 112), 1, 4) + {nchar}'"; + case "yy": return $"' + substring(convert(char(6), {left}, 12), 1, 2) + {nchar}'"; + case "MM": return $"' + substring(convert(char(6), {left}, 12), 3, 2) + {nchar}'"; + case "M": return $"' + case when substring(convert(char(6), {left}, 12), 3, 1) = '0' then substring(convert(char(6), {left}, 12), 4, 1) else substring(convert(char(6), {left}, 12), 3, 2) end + {nchar}'"; + case "dd": return $"' + substring(convert(char(6), {left}, 12), 5, 2) + {nchar}'"; + case "d": return $"' + case when substring(convert(char(6), {left}, 12), 5, 1) = '0' then substring(convert(char(6), {left}, 12), 6, 1) else substring(convert(char(6), {left}, 12), 5, 2) end + {nchar}'"; + case "HH": return $"' + substring(convert(char(8), {left}, 24), 1, 2) + {nchar}'"; + case "H": return $"' + case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end + {nchar}'"; + case "hh": return $"' + case cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) % 12" + + $"when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end + {nchar}'"; + case "h": return $"' + case cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) % 12" + + $"when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end + {nchar}'"; + case "mm": return $"' + substring(convert(char(8), {left}, 24), 4, 2) + {nchar}'"; + case "m": return $"' + case when substring(convert(char(8), {left}, 24), 4, 1) = '0' then substring(convert(char(8), {left}, 24), 5, 1) else substring(convert(char(8), {left}, 24), 4, 2) end + {nchar}'"; + case "ss": return $"' + substring(convert(char(8), {left}, 24), 7, 2) + {nchar}'"; + case "s": return $"' + case when substring(convert(char(8), {left}, 24), 7, 1) = '0' then substring(convert(char(8), {left}, 24), 8, 1) else substring(convert(char(8), {left}, 24), 7, 2) end + {nchar}'"; + case "tt": return $"' + case when cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) >= 12 then 'PM' else 'AM' end + {nchar}'"; + case "t": return $"' + case when cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) >= 12 then 'P' else 'A' end + {nchar}'"; + } + return m.Groups[0].Value; + }); } } return null; From 08713fba713dd8b45e67f108b84dcc02bf2f992e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 02:46:19 +0800 Subject: [PATCH 0660/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20MySq=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20yyyyMMdd=20?= =?UTF-8?q?=E5=B8=B8=E7=94=A8=20c#=20=E6=97=A5=E6=9C=9F=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnectorExpression/DateTimeTest.cs | 57 ++++++++++++------- .../MySql/MySqlExpression/DateTimeTest.cs | 57 ++++++++++++------- .../SqlServerExpression/DateTimeTest.cs | 1 + .../MySql/MySqlExpression/DateTimeTest.cs | 56 +++++++++++------- .../SqlServerExpression/DateTimeTest.cs | 1 + .../FreeSql.Provider.MySql/MySqlExpression.cs | 50 +++++++++++++++- .../MySql/OdbcMySqlExpression.cs | 50 +++++++++++++++- 7 files changed, 211 insertions(+), 61 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs index fbb5e47b..ed40f8af 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs @@ -41,6 +41,43 @@ namespace FreeSql.Tests.MySqlConnectorExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.mysql.Insert(new Topic()).ExecuteAffrows(); + foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -542,26 +579,6 @@ namespace FreeSql.Tests.MySqlConnectorExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs index f2ed19a4..a8b1bdc7 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs @@ -41,6 +41,43 @@ namespace FreeSql.Tests.Odbc.MySqlExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.mysql.Insert(new Topic()).ExecuteAffrows(); + foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -575,26 +612,6 @@ namespace FreeSql.Tests.Odbc.MySqlExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs index bdeeab9e..fe70fe25 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -63,6 +63,7 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs index c1aebfb4..7fca1664 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs @@ -41,6 +41,43 @@ namespace FreeSql.Tests.MySqlExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.mysql.Insert(new Topic()).ExecuteAffrows(); + foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -575,25 +612,6 @@ namespace FreeSql.Tests.MySqlExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } [Fact] public void DateTime_Compare() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs index 284cdaf3..cae39dc7 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -71,6 +71,7 @@ namespace FreeSql.Tests.SqlServerExpression Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index ee3ec1bb..7de21a0a 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.MySql { @@ -392,7 +393,54 @@ namespace FreeSql.MySql break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; - case "ToString": return exp.Arguments.Count == 0 ? $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')" : null; + case "ToString": + if (exp.Arguments.Count == 0) return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"date_format({left}, '%Y-%m-%d %H:%i:%s')"; + case "'yyyy-MM-dd HH:mm'": return $"date_format({left}, '%Y-%m-%d %H:%i')"; + case "'yyyy-MM-dd HH'": return $"date_format({left}, '%Y-%m-%d %H')"; + case "'yyyy-MM-dd'": return $"date_format({left}, '%Y-%m-%d')"; + case "'yyyy-MM'": return $"date_format({left}, '%Y-%m')"; + case "'yyyyMMdd'": return $"date_format({left}, '%Y%m%d')"; + case "'yyyyMM'": return $"date_format({left}, '%Y%m')"; + case "'yyyy'": return $"date_format({left}, '%Y')"; + case "'HH:mm:ss'": return $"date_format({left}, '%H:%i:%s')"; + } + + args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"%Y"; + case "yy": return $"%y"; + case "MM": return $"%_a1"; + case "M": return $"%c"; + case "dd": return $"%d"; + case "d": return $"%e"; + case "HH": return $"%H"; + case "H": return $"%k"; + case "hh": return $"%h"; + case "h": return $"%l"; + case "mm": return $"%i"; + case "ss": return $"%_a2"; + case "tt": return $"%p"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(m|s|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "m": return $"'), trim(leading '0' from date_format({left}, '%i')), date_format({left}, '"; + case "s": return $"'), trim(leading '0' from date_format({left}, '%s')), date_format({left}, '"; + case "t": return $"'), trim(trailing 'M' from date_format({left}, '%p')), date_format({left}, '"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "%m").Replace("%_a2", "%s"); + return isMatched == false ? $"date_format({left}, {args1})" : $"concat(date_format({left}, {args1}))".Replace($"date_format({left}, '')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index cb2c6bf8..3c55b3ea 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Odbc.MySql { @@ -392,7 +393,54 @@ namespace FreeSql.Odbc.MySql break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; - case "ToString": return exp.Arguments.Count == 0 ? $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')" : null; + case "ToString": + if (exp.Arguments.Count == 0) return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"date_format({left}, '%Y-%m-%d %H:%i:%s')"; + case "'yyyy-MM-dd HH:mm'": return $"date_format({left}, '%Y-%m-%d %H:%i')"; + case "'yyyy-MM-dd HH'": return $"date_format({left}, '%Y-%m-%d %H')"; + case "'yyyy-MM-dd'": return $"date_format({left}, '%Y-%m-%d')"; + case "'yyyy-MM'": return $"date_format({left}, '%Y-%m')"; + case "'yyyyMMdd'": return $"date_format({left}, '%Y%m%d')"; + case "'yyyyMM'": return $"date_format({left}, '%Y%m')"; + case "'yyyy'": return $"date_format({left}, '%Y')"; + case "'HH:mm:ss'": return $"date_format({left}, '%H:%i:%s')"; + } + + args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"%Y"; + case "yy": return $"%y"; + case "MM": return $"%_a1"; + case "M": return $"%c"; + case "dd": return $"%d"; + case "d": return $"%e"; + case "HH": return $"%H"; + case "H": return $"%k"; + case "hh": return $"%h"; + case "h": return $"%l"; + case "mm": return $"%i"; + case "ss": return $"%_a2"; + case "tt": return $"%p"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(m|s|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "m": return $"'), trim(leading '0' from date_format({left}, '%i')), date_format({left}, '"; + case "s": return $"'), trim(leading '0' from date_format({left}, '%s')), date_format({left}, '"; + case "t": return $"'), trim(trailing 'M' from date_format({left}, '%p')), date_format({left}, '"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "%m").Replace("%_a2", "%s"); + return isMatched == false ? $"date_format({left}, {args1})" : $"concat(date_format({left}, {args1}))".Replace($"date_format({left}, '')", "''"); } } return null; From 795ba9c833f65a50ba957b07e3ae4a85da3f7080 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 03:05:15 +0800 Subject: [PATCH 0661/1029] update MySqlExpression DateTime ToString --- .../MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs | 3 +++ .../MySql/MySqlExpression/DateTimeTest.cs | 3 +++ .../FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs | 3 +++ Providers/FreeSql.Provider.MySql/MySqlExpression.cs | 3 +++ Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs | 3 +++ 5 files changed, 15 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs index ed40f8af..322c6673 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs @@ -70,6 +70,9 @@ namespace FreeSql.Tests.MySqlConnectorExpression Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs index a8b1bdc7..3962227a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs @@ -70,6 +70,9 @@ namespace FreeSql.Tests.Odbc.MySqlExpression Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs index 7fca1664..201947fa 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs @@ -70,6 +70,9 @@ namespace FreeSql.Tests.MySqlExpression Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 7de21a0a..814d733b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -402,6 +402,9 @@ namespace FreeSql.MySql case "'yyyy-MM-dd HH'": return $"date_format({left}, '%Y-%m-%d %H')"; case "'yyyy-MM-dd'": return $"date_format({left}, '%Y-%m-%d')"; case "'yyyy-MM'": return $"date_format({left}, '%Y-%m')"; + case "'yyyyMMddHHmmss'": return $"date_format({left}, '%Y%m%d%H%i%s')"; + case "'yyyyMMddHHmm'": return $"date_format({left}, '%Y%m%d%H%i')"; + case "'yyyyMMddHH'": return $"date_format({left}, '%Y%m%d%H')"; case "'yyyyMMdd'": return $"date_format({left}, '%Y%m%d')"; case "'yyyyMM'": return $"date_format({left}, '%Y%m')"; case "'yyyy'": return $"date_format({left}, '%Y')"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 3c55b3ea..feaa5ca4 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -402,6 +402,9 @@ namespace FreeSql.Odbc.MySql case "'yyyy-MM-dd HH'": return $"date_format({left}, '%Y-%m-%d %H')"; case "'yyyy-MM-dd'": return $"date_format({left}, '%Y-%m-%d')"; case "'yyyy-MM'": return $"date_format({left}, '%Y-%m')"; + case "'yyyyMMddHHmmss'": return $"date_format({left}, '%Y%m%d%H%i%s')"; + case "'yyyyMMddHHmm'": return $"date_format({left}, '%Y%m%d%H%i')"; + case "'yyyyMMddHH'": return $"date_format({left}, '%Y%m%d%H')"; case "'yyyyMMdd'": return $"date_format({left}, '%Y%m%d')"; case "'yyyyMM'": return $"date_format({left}, '%Y%m')"; case "'yyyy'": return $"date_format({left}, '%Y')"; From 00ce7d93ce384972e1746dd68a6ed0f1367b0969 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 03:56:02 +0800 Subject: [PATCH 0662/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Sqlite=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20yyyyMMdd=20?= =?UTF-8?q?=E5=B8=B8=E7=94=A8=20c#=20=E6=97=A5=E6=9C=9F=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sqlite/SqliteExpression/DateTimeTest.cs | 66 +++++++++++++------ .../SqliteExpression.cs | 52 ++++++++++++++- 2 files changed, 97 insertions(+), 21 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs index 7afc0189..0ca17964 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs @@ -41,6 +41,52 @@ namespace FreeSql.Tests.SqliteExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.sqlite.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -587,26 +633,6 @@ namespace FreeSql.Tests.SqliteExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 325aa535..5c1ab0fa 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Sqlite { @@ -396,7 +397,56 @@ namespace FreeSql.Sqlite break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))"; - case "ToString": return exp.Arguments.Count == 0 ? $"strftime('%Y-%m-%d %H:%M.%f',{left})" : null; + case "ToString": + if (exp.Arguments.Count == 0) return $"strftime('%Y-%m-%d %H:%M:%f',{left})"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"strftime('%Y-%m-%d %H:%M:%S',{left})"; + case "'yyyy-MM-dd HH:mm'": return $"strftime('%Y-%m-%d %H:%M',{left})"; + case "'yyyy-MM-dd HH'": return $"strftime('%Y-%m-%d %H',{left})"; + case "'yyyy-MM-dd'": return $"strftime('%Y-%m-%d',{left})"; + case "'yyyy-MM'": return $"strftime('%Y-%m',{left})"; + case "'yyyyMMddHHmmss'": return $"strftime('%Y%m%d%H%M%S',{left})"; + case "'yyyyMMddHHmm'": return $"strftime('%Y%m%d%H%M',{left})"; + case "'yyyyMMddHH'": return $"strftime('%Y%m%d%H',{left})"; + case "'yyyyMMdd'": return $"strftime('%Y%m%d',{left})"; + case "'yyyyMM'": return $"strftime('%Y%m',{left})"; + case "'yyyy'": return $"strftime('%Y',{left})"; + case "'HH:mm:ss'": return $"strftime('%H:%M:%S',{left})"; + } + args1 = Regex.Replace(args1, "(yyyy|MM|dd|HH|mm|ss)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"%Y"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "mm": return $"%_a4"; + case "ss": return $"%S"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(yy|M|d|H|hh|h|m|s|tt|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "yy": return $"',{left}) || substr(strftime('%Y',{left}),3,2) || strftime('"; + case "M": return $"',{left}) || ltrim(strftime('%m',{left}),'0') || strftime('"; + case "d": return $"',{left}) || ltrim(strftime('%d',{left}),'0') || strftime('"; + case "H": return $"',{left}) || case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end || strftime('"; + case "hh": return $"',{left}) || case cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) % 12 when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end || strftime('"; + case "h": return $"',{left}) || case cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) % 12 when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end || strftime('"; + case "m": return $"',{left}) || case when substr(strftime('%M',{left}),1,1) = '0' then substr(strftime('%M',{left}),2,1) else strftime('%M',{left}) end || strftime('"; + case "s": return $"',{left}) || case when substr(strftime('%S',{left}),1,1) = '0' then substr(strftime('%S',{left}),2,1) else strftime('%S',{left}) end || strftime('"; + case "tt": return $"',{left}) || case when cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) >= 12 then 'PM' else 'AM' end || strftime('"; + case "t": return $"',{left}) || case when cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) >= 12 then 'P' else 'A' end || strftime('"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "%m").Replace("%_a2", "%d").Replace("%_a3", "%H").Replace("%_a4", "%M"); + return isMatched == false ? $"strftime({args1},{left})" : $"(strftime({args1},{left}))".Replace($"strftime('',{left})", "''"); } } return null; From e20f5324a09eb18b0c888561fb64d0a4131e2470 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 04:15:10 +0800 Subject: [PATCH 0663/1029] update Expression DateTime ToString tests --- .../MySqlConnectorExpression/DateTimeTest.cs | 8 ++++- .../MySql/MySqlExpression/DateTimeTest.cs | 8 ++++- .../SqlServerExpression/DateTimeTest.cs | 11 +++++- .../MySql/MySqlExpression/DateTimeTest.cs | 8 ++++- .../SqlServerExpression/DateTimeTest.cs | 11 +++++- .../FreeSql.Provider.MySql/MySqlExpression.cs | 34 +++++++++---------- .../MySql/OdbcMySqlExpression.cs | 34 +++++++++---------- .../SqlServer/OdbcSqlServerExpression.cs | 5 ++- .../SqlServerExpression.cs | 5 ++- 9 files changed, 83 insertions(+), 41 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs index 322c6673..5a31b774 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/DateTimeTest.cs @@ -62,7 +62,13 @@ namespace FreeSql.Tests.MySqlConnectorExpression //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) g.mysql.Insert(new Topic()).ExecuteAffrows(); - foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) { Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs index 3962227a..568ff4f2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/DateTimeTest.cs @@ -62,7 +62,13 @@ namespace FreeSql.Tests.Odbc.MySqlExpression //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) g.mysql.Insert(new Topic()).ExecuteAffrows(); - foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) { Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs index fe70fe25..4eff3162 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -51,7 +51,13 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); g.sqlserver.Insert(new Topic()).ExecuteAffrows(); - foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) { Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"), select.First(a => dt.ToString())); Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); @@ -59,6 +65,9 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs index 201947fa..f41242d5 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/DateTimeTest.cs @@ -62,7 +62,13 @@ namespace FreeSql.Tests.MySqlExpression //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) g.mysql.Insert(new Topic()).ExecuteAffrows(); - foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) { Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs index cae39dc7..48857b4d 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -59,7 +59,13 @@ namespace FreeSql.Tests.SqlServerExpression data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); g.sqlserver.Insert(new Topic()).ExecuteAffrows(); - foreach (var dt in new[] { DateTime.Parse("2020-5-6 0:1:2"), DateTime.Parse("2020-11-16 13:21:22"), }) + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) { Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"), select.First(a => dt.ToString())); Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); @@ -67,6 +73,9 @@ namespace FreeSql.Tests.SqlServerExpression Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 814d733b..134f26ba 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -394,21 +394,21 @@ namespace FreeSql.MySql case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; case "ToString": - if (exp.Arguments.Count == 0) return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; + if (exp.Arguments.Count == 0) return $"date_format({left},'%Y-%m-%d %H:%i:%s.%f')"; switch (args1) { - case "'yyyy-MM-dd HH:mm:ss'": return $"date_format({left}, '%Y-%m-%d %H:%i:%s')"; - case "'yyyy-MM-dd HH:mm'": return $"date_format({left}, '%Y-%m-%d %H:%i')"; - case "'yyyy-MM-dd HH'": return $"date_format({left}, '%Y-%m-%d %H')"; - case "'yyyy-MM-dd'": return $"date_format({left}, '%Y-%m-%d')"; - case "'yyyy-MM'": return $"date_format({left}, '%Y-%m')"; - case "'yyyyMMddHHmmss'": return $"date_format({left}, '%Y%m%d%H%i%s')"; - case "'yyyyMMddHHmm'": return $"date_format({left}, '%Y%m%d%H%i')"; - case "'yyyyMMddHH'": return $"date_format({left}, '%Y%m%d%H')"; - case "'yyyyMMdd'": return $"date_format({left}, '%Y%m%d')"; - case "'yyyyMM'": return $"date_format({left}, '%Y%m')"; - case "'yyyy'": return $"date_format({left}, '%Y')"; - case "'HH:mm:ss'": return $"date_format({left}, '%H:%i:%s')"; + case "'yyyy-MM-dd HH:mm:ss'": return $"date_format({left},'%Y-%m-%d %H:%i:%s')"; + case "'yyyy-MM-dd HH:mm'": return $"date_format({left},'%Y-%m-%d %H:%i')"; + case "'yyyy-MM-dd HH'": return $"date_format({left},'%Y-%m-%d %H')"; + case "'yyyy-MM-dd'": return $"date_format({left},'%Y-%m-%d')"; + case "'yyyy-MM'": return $"date_format({left},'%Y-%m')"; + case "'yyyyMMddHHmmss'": return $"date_format({left},'%Y%m%d%H%i%s')"; + case "'yyyyMMddHHmm'": return $"date_format({left},'%Y%m%d%H%i')"; + case "'yyyyMMddHH'": return $"date_format({left},'%Y%m%d%H')"; + case "'yyyyMMdd'": return $"date_format({left},'%Y%m%d')"; + case "'yyyyMM'": return $"date_format({left},'%Y%m')"; + case "'yyyy'": return $"date_format({left},'%Y')"; + case "'HH:mm:ss'": return $"date_format({left},'%H:%i:%s')"; } args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|ss|tt)", m => @@ -437,13 +437,13 @@ namespace FreeSql.MySql isMatched = true; switch (m.Groups[1].Value) { - case "m": return $"'), trim(leading '0' from date_format({left}, '%i')), date_format({left}, '"; - case "s": return $"'), trim(leading '0' from date_format({left}, '%s')), date_format({left}, '"; - case "t": return $"'), trim(trailing 'M' from date_format({left}, '%p')), date_format({left}, '"; + case "m": return $"'), case when substr(date_format({left},'%i'),1,1) = '0' then substr(date_format({left},'%i'),2,1) else date_format({left},'%i') end, date_format({left},'"; + case "s": return $"'), case when substr(date_format({left},'%s'),1,1) = '0' then substr(date_format({left},'%s'),2,1) else date_format({left},'%s') end, date_format({left},'"; + case "t": return $"'), trim(trailing 'M' from date_format({left},'%p')), date_format({left},'"; } return m.Groups[0].Value; }).Replace("%_a1", "%m").Replace("%_a2", "%s"); - return isMatched == false ? $"date_format({left}, {args1})" : $"concat(date_format({left}, {args1}))".Replace($"date_format({left}, '')", "''"); + return isMatched == false ? $"date_format({left},{args1})" : $"concat(date_format({left},{args1}))".Replace($"date_format({left},'')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index feaa5ca4..febf9323 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -394,21 +394,21 @@ namespace FreeSql.Odbc.MySql case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; case "ToString": - if (exp.Arguments.Count == 0) return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; + if (exp.Arguments.Count == 0) return $"date_format({left},'%Y-%m-%d %H:%i:%s.%f')"; switch (args1) { - case "'yyyy-MM-dd HH:mm:ss'": return $"date_format({left}, '%Y-%m-%d %H:%i:%s')"; - case "'yyyy-MM-dd HH:mm'": return $"date_format({left}, '%Y-%m-%d %H:%i')"; - case "'yyyy-MM-dd HH'": return $"date_format({left}, '%Y-%m-%d %H')"; - case "'yyyy-MM-dd'": return $"date_format({left}, '%Y-%m-%d')"; - case "'yyyy-MM'": return $"date_format({left}, '%Y-%m')"; - case "'yyyyMMddHHmmss'": return $"date_format({left}, '%Y%m%d%H%i%s')"; - case "'yyyyMMddHHmm'": return $"date_format({left}, '%Y%m%d%H%i')"; - case "'yyyyMMddHH'": return $"date_format({left}, '%Y%m%d%H')"; - case "'yyyyMMdd'": return $"date_format({left}, '%Y%m%d')"; - case "'yyyyMM'": return $"date_format({left}, '%Y%m')"; - case "'yyyy'": return $"date_format({left}, '%Y')"; - case "'HH:mm:ss'": return $"date_format({left}, '%H:%i:%s')"; + case "'yyyy-MM-dd HH:mm:ss'": return $"date_format({left},'%Y-%m-%d %H:%i:%s')"; + case "'yyyy-MM-dd HH:mm'": return $"date_format({left},'%Y-%m-%d %H:%i')"; + case "'yyyy-MM-dd HH'": return $"date_format({left},'%Y-%m-%d %H')"; + case "'yyyy-MM-dd'": return $"date_format({left},'%Y-%m-%d')"; + case "'yyyy-MM'": return $"date_format({left},'%Y-%m')"; + case "'yyyyMMddHHmmss'": return $"date_format({left},'%Y%m%d%H%i%s')"; + case "'yyyyMMddHHmm'": return $"date_format({left},'%Y%m%d%H%i')"; + case "'yyyyMMddHH'": return $"date_format({left},'%Y%m%d%H')"; + case "'yyyyMMdd'": return $"date_format({left},'%Y%m%d')"; + case "'yyyyMM'": return $"date_format({left},'%Y%m')"; + case "'yyyy'": return $"date_format({left},'%Y')"; + case "'HH:mm:ss'": return $"date_format({left},'%H:%i:%s')"; } args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|ss|tt)", m => @@ -437,13 +437,13 @@ namespace FreeSql.Odbc.MySql isMatched = true; switch (m.Groups[1].Value) { - case "m": return $"'), trim(leading '0' from date_format({left}, '%i')), date_format({left}, '"; - case "s": return $"'), trim(leading '0' from date_format({left}, '%s')), date_format({left}, '"; - case "t": return $"'), trim(trailing 'M' from date_format({left}, '%p')), date_format({left}, '"; + case "m": return $"'), case when substr(date_format({left},'%i'),1,1) = '0' then substr(date_format({left},'%i'),2,1) else date_format({left},'%i') end, date_format({left},'"; + case "s": return $"'), case when substr(date_format({left},'%s'),1,1) = '0' then substr(date_format({left},'%s'),2,1) else date_format({left},'%s') end, date_format({left},'"; + case "t": return $"'), trim(trailing 'M' from date_format({left},'%p')), date_format({left},'"; } return m.Groups[0].Value; }).Replace("%_a1", "%m").Replace("%_a2", "%s"); - return isMatched == false ? $"date_format({left}, {args1})" : $"concat(date_format({left}, {args1}))".Replace($"date_format({left}, '')", "''"); + return isMatched == false ? $"date_format({left},{args1})" : $"concat(date_format({left},{args1}))".Replace($"date_format({left},'')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index d8f7dc9b..23574cf3 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -388,9 +388,11 @@ namespace FreeSql.Odbc.SqlServer case "'yyyy'": return $"substring(convert(char(8), {left}, 112), 1, 4)"; case "'HH:mm:ss'": return $"convert(char(8), {left}, 24)"; } + var isMatched = false; var nchar = args1.StartsWith("N'") ? "N" : ""; - return Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => + args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => { + isMatched = true; switch (m.Groups[1].Value) { case "yyyy": return $"' + substring(convert(char(8), {left}, 112), 1, 4) + {nchar}'"; @@ -416,6 +418,7 @@ namespace FreeSql.Odbc.SqlServer } return m.Groups[0].Value; }); + return isMatched == false ? args1 : $"({args1})"; } } return null; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index b4b7c563..07ab621d 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -388,9 +388,11 @@ namespace FreeSql.SqlServer case "'yyyy'": return $"substring(convert(char(8), {left}, 112), 1, 4)"; case "'HH:mm:ss'": return $"convert(char(8), {left}, 24)"; } + var isMatched = false; var nchar = args1.StartsWith("N'") ? "N" : ""; - return Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => + args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => { + isMatched = true; switch (m.Groups[1].Value) { case "yyyy": return $"' + substring(convert(char(8), {left}, 112), 1, 4) + {nchar}'"; @@ -414,6 +416,7 @@ namespace FreeSql.SqlServer } return m.Groups[0].Value; }); + return isMatched == false ? args1 : $"({args1})"; } } return null; From 70266c08c890d1b66b89d70e20e2ba39069c66a4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 05:18:45 +0800 Subject: [PATCH 0664/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20PostgreSQL?= =?UTF-8?q?=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20yyyyMMdd=20?= =?UTF-8?q?=E5=B8=B8=E7=94=A8=20c#=20=E6=97=A5=E6=9C=9F=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQLExpression/DateTimeTest.cs | 66 +++++--- .../PostgreSQLExpression/DateTimeTest.cs | 66 +++++--- FreeSql/FreeSql.xml | 143 ------------------ .../FreeSql.Provider.MySql/MySqlExpression.cs | 1 - .../MySql/OdbcMySqlExpression.cs | 1 - .../PostgreSQL/OdbcPostgreSQLExpression.cs | 53 ++++++- .../SqlServer/OdbcSqlServerExpression.cs | 2 +- .../PostgreSQLExpression.cs | 53 ++++++- .../SqlServerExpression.cs | 2 +- 9 files changed, 198 insertions(+), 189 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs index b70c220c..17a37374 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs @@ -41,6 +41,52 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.pgsql.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -587,26 +633,6 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs index d99dd64c..90a4435b 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs @@ -41,6 +41,52 @@ namespace FreeSql.Tests.PostgreSQLExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.pgsql.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } [Fact] public void Now() { @@ -587,26 +633,6 @@ namespace FreeSql.Tests.PostgreSQLExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5545a967..e50637da 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2405,137 +2405,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3138,12 +3007,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3214,12 +3077,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 134f26ba..6069d19c 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -410,7 +410,6 @@ namespace FreeSql.MySql case "'yyyy'": return $"date_format({left},'%Y')"; case "'HH:mm:ss'": return $"date_format({left},'%H:%i:%s')"; } - args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|ss|tt)", m => { switch (m.Groups[1].Value) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index febf9323..9befd68f 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -410,7 +410,6 @@ namespace FreeSql.Odbc.MySql case "'yyyy'": return $"date_format({left},'%Y')"; case "'HH:mm:ss'": return $"date_format({left},'%H:%i:%s')"; } - args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|ss|tt)", m => { switch (m.Groups[1].Value) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 2c4ccee2..a6b53a6b 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Odbc.PostgreSQL { @@ -483,7 +484,57 @@ namespace FreeSql.Odbc.PostgreSQL break; case "Equals": return $"({left} = ({args1})::timestamp)"; case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')" : null; + case "ToString": + left = $"({left})::timestamp"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; + case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; + case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; + case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; + case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; + case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; + case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 23574cf3..95843601 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -374,8 +374,8 @@ namespace FreeSql.Odbc.SqlServer case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second,{args1},{left})"; case "ToString": - if (exp.Arguments.Count == 0) return $"convert(varchar, cast({left} as datetime), 121)"; left = $"cast({left} as datetime)"; + if (exp.Arguments.Count == 0) return $"convert(varchar, {left}, 121)"; switch (args1.TrimStart('N')) { case "'yyyy-MM-dd HH:mm:ss'": return $"convert(char(19), {left}, 120)"; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index bcea0fdc..157606eb 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.PostgreSQL { @@ -514,7 +515,57 @@ namespace FreeSql.PostgreSQL break; case "Equals": return $"({left} = ({args1})::timestamp)"; case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')" : null; + case "ToString": + left = $"({left})::timestamp"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; + case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; + case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; + case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; + case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; + case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; + case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 07ab621d..573b13fd 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -374,8 +374,8 @@ namespace FreeSql.SqlServer case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second,{args1},{left})"; case "ToString": - if (exp.Arguments.Count == 0) return $"convert(varchar, cast({left} as datetime), 121)"; left = $"cast({left} as datetime)"; + if (exp.Arguments.Count == 0) return $"convert(varchar, {left}, 121)"; switch (args1.TrimStart('N')) { case "'yyyy-MM-dd HH:mm:ss'": return $"convert(char(19), {left}, 120)"; From 2a427311340a5166553b7187caaaa0c144745ac2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 05:50:09 +0800 Subject: [PATCH 0665/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Oracle=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20yyyyMMdd=20?= =?UTF-8?q?=E5=B8=B8=E7=94=A8=20c#=20=E6=97=A5=E6=9C=9F=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Oracle/OracleExpression/DateTimeTest.cs | 66 +++++++++++++------ .../Oracle/OracleExpression/DateTimeTest.cs | 66 +++++++++++++------ .../MySql/OdbcMySqlExpression.cs | 2 - .../Oracle/OdbcOracleExpression.cs | 55 +++++++++++++++- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 3 +- .../SqlServer/OdbcSqlServerExpression.cs | 2 +- .../OracleExpression.cs | 55 +++++++++++++++- .../PostgreSQLExpression.cs | 3 +- .../SqlServerExpression.cs | 2 +- .../SqliteExpression.cs | 2 - 10 files changed, 200 insertions(+), 56 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs index 2e566ddd..9d3473f7 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs @@ -41,6 +41,52 @@ namespace FreeSql.Tests.Odbc.OracleExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.oracle.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + } + } [Fact] public void Now() { @@ -587,26 +633,6 @@ namespace FreeSql.Tests.Odbc.OracleExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs index 0fe69d3a..020968f2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs @@ -41,6 +41,52 @@ namespace FreeSql.Tests.OracleExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.oracle.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + } + } [Fact] public void Now() { @@ -587,26 +633,6 @@ namespace FreeSql.Tests.OracleExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 9befd68f..5cb20008 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -1,8 +1,6 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index d09da364..2795c374 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Odbc.Oracle { @@ -398,7 +397,57 @@ namespace FreeSql.Odbc.Oracle break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"extract(day from ({left}-({args1})))"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + case "ToString": + if (left.StartsWith("'") || left.EndsWith("'")) left = $"to_timestamp({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; + case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; + case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; + case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; + case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; + case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; + case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index a6b53a6b..4ab8f9fd 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -1,5 +1,4 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; using System.Collections.Generic; @@ -485,7 +484,7 @@ namespace FreeSql.Odbc.PostgreSQL case "Equals": return $"({left} = ({args1})::timestamp)"; case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; case "ToString": - left = $"({left})::timestamp"; + if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp"; if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; switch (args1) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 95843601..086a6daf 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -374,7 +374,7 @@ namespace FreeSql.Odbc.SqlServer case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second,{args1},{left})"; case "ToString": - left = $"cast({left} as datetime)"; + if (left.EndsWith(" as datetime)") == false) left = $"cast({left} as datetime)"; if (exp.Arguments.Count == 0) return $"convert(varchar, {left}, 121)"; switch (args1.TrimStart('N')) { diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 5169f563..2029c68e 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Oracle { @@ -398,7 +397,57 @@ namespace FreeSql.Oracle break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"extract(day from ({left}-({args1})))"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + case "ToString": + if (left.StartsWith("'") || left.EndsWith("'")) left = $"to_timestamp({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var isMatched = false; + args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; + case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; + case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; + case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; + case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; + case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; + case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + } + return m.Groups[0].Value; + }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); } } return null; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 157606eb..6c56f6a2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -1,5 +1,4 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; using System; using System.Collections; @@ -516,7 +515,7 @@ namespace FreeSql.PostgreSQL case "Equals": return $"({left} = ({args1})::timestamp)"; case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; case "ToString": - left = $"({left})::timestamp"; + if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp"; if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; switch (args1) { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 573b13fd..a657b039 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -374,7 +374,7 @@ namespace FreeSql.SqlServer case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second,{args1},{left})"; case "ToString": - left = $"cast({left} as datetime)"; + if (left.EndsWith(" as datetime)") == false) left = $"cast({left} as datetime)"; if (exp.Arguments.Count == 0) return $"convert(varchar, {left}, 121)"; switch (args1.TrimStart('N')) { diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 5c1ab0fa..2fb321ea 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -1,8 +1,6 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; From 368da0b04e8a088a16eb97c65c2b0cd475b4f44c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 08:23:04 +0800 Subject: [PATCH 0666/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20yyy?= =?UTF-8?q?yMMdd=20=E5=B8=B8=E7=94=A8=20c#=20=E6=97=A5=E6=9C=9F=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dameng/DamengExpression/DateTimeTest.cs | 110 +++++++++++------- .../Oracle/OracleExpression/DateTimeTest.cs | 6 +- .../Dameng/DamengExpression/DateTimeTest.cs | 110 +++++++++++------- .../Oracle/OracleExpression/DateTimeTest.cs | 14 +-- .../DamengExpression.cs | 66 ++++++++++- .../FreeSql.Provider.MySql/MySqlExpression.cs | 26 +++-- .../Dameng/OdbcDamengExpression.cs | 66 ++++++++++- .../MySql/OdbcMySqlExpression.cs | 26 +++-- .../Oracle/OdbcOracleExpression.cs | 38 +++--- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 38 +++--- .../OracleExpression.cs | 38 +++--- .../PostgreSQLExpression.cs | 38 +++--- .../SqliteExpression.cs | 40 ++++--- 13 files changed, 411 insertions(+), 205 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/DateTimeTest.cs index 08576662..18c4ae76 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/DateTimeTest.cs @@ -20,7 +20,7 @@ namespace FreeSql.Tests.Odbc.DamengExpression public int TypeGuid { get; set; } public TestTypeInfo Type { get; set; } public string Title { get; set; } - public DateTime CreateTime { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; } [Table(Name = "TestTypeInfo333")] class TestTypeInfo @@ -30,7 +30,7 @@ namespace FreeSql.Tests.Odbc.DamengExpression public int ParentId { get; set; } public TestTypeParentInfo Parent { get; set; } public string Name { get; set; } - public DateTime Time { get; set; } + public DateTime Time { get; set; } = DateTime.Now; } [Table(Name = "TestTypeParentInf1")] class TestTypeParentInfo @@ -39,7 +39,53 @@ namespace FreeSql.Tests.Odbc.DamengExpression public string Name { get; set; } public List Types { get; set; } - public DateTime Time2 { get; set; } + public DateTime Time2 { get; set; } = DateTime.Now; + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.dameng.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + } } [Fact] public void Now() @@ -82,8 +128,8 @@ namespace FreeSql.Tests.Odbc.DamengExpression { var data = new List(); data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); @@ -95,9 +141,9 @@ namespace FreeSql.Tests.Odbc.DamengExpression //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); @@ -494,9 +540,9 @@ namespace FreeSql.Tests.Odbc.DamengExpression public void Subtract() { var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" //FROM "TB_TOPIC111333" a //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) @@ -511,9 +557,9 @@ namespace FreeSql.Tests.Odbc.DamengExpression //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" //FROM "TB_TOPIC111333" a //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") @@ -533,9 +579,9 @@ namespace FreeSql.Tests.Odbc.DamengExpression public void _ЧͬSubtract() { var data = new List(); - data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" //FROM "TB_TOPIC111333" a //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) @@ -550,9 +596,9 @@ namespace FreeSql.Tests.Odbc.DamengExpression //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" //FROM "TB_TOPIC111333" a //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") @@ -587,26 +633,6 @@ namespace FreeSql.Tests.Odbc.DamengExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { @@ -631,8 +657,8 @@ namespace FreeSql.Tests.Odbc.DamengExpression { var data = new List(); data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs index 9d3473f7..91829936 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs @@ -20,7 +20,7 @@ namespace FreeSql.Tests.Odbc.OracleExpression public int TypeGuid { get; set; } public TestTypeInfo Type { get; set; } public string Title { get; set; } - public DateTime CreateTime { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; } [Table(Name = "TestTypeInfo333")] class TestTypeInfo @@ -657,8 +657,8 @@ namespace FreeSql.Tests.Odbc.OracleExpression { var data = new List(); data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/DateTimeTest.cs index 6b7b49e5..a9f3ad36 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/DateTimeTest.cs @@ -20,7 +20,7 @@ namespace FreeSql.Tests.DamengExpression public int TypeGuid { get; set; } public TestTypeInfo Type { get; set; } public string Title { get; set; } - public DateTime CreateTime { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; } [Table(Name = "TestTypeInfo333")] class TestTypeInfo @@ -30,7 +30,7 @@ namespace FreeSql.Tests.DamengExpression public int ParentId { get; set; } public TestTypeParentInfo Parent { get; set; } public string Name { get; set; } - public DateTime Time { get; set; } + public DateTime Time { get; set; } = DateTime.Now; } [Table(Name = "TestTypeParentInf1")] class TestTypeParentInfo @@ -39,7 +39,53 @@ namespace FreeSql.Tests.DamengExpression public string Name { get; set; } public List Types { get; set; } - public DateTime Time2 { get; set; } + public DateTime Time2 { get; set; } = DateTime.Now; + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.dameng.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + } } [Fact] public void Now() @@ -82,8 +128,8 @@ namespace FreeSql.Tests.DamengExpression { var data = new List(); data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); @@ -95,9 +141,9 @@ namespace FreeSql.Tests.DamengExpression //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); @@ -494,9 +540,9 @@ namespace FreeSql.Tests.DamengExpression public void Subtract() { var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" //FROM "TB_TOPIC111333" a //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) @@ -511,9 +557,9 @@ namespace FreeSql.Tests.DamengExpression //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" //FROM "TB_TOPIC111333" a //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") @@ -533,9 +579,9 @@ namespace FreeSql.Tests.DamengExpression public void _ЧͬSubtract() { var data = new List(); - data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" //FROM "TB_TOPIC111333" a //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) @@ -550,9 +596,9 @@ namespace FreeSql.Tests.DamengExpression //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" //FROM "TB_TOPIC111333" a //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") @@ -587,26 +633,6 @@ namespace FreeSql.Tests.DamengExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } - [Fact] public void DateTime_Compare() { @@ -631,8 +657,8 @@ namespace FreeSql.Tests.DamengExpression { var data = new List(); data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs index 020968f2..da0dd5cb 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/DateTimeTest.cs @@ -20,7 +20,7 @@ namespace FreeSql.Tests.OracleExpression public int TypeGuid { get; set; } public TestTypeInfo Type { get; set; } public string Title { get; set; } - public DateTime CreateTime { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; } [Table(Name = "TestTypeInfo333")] class TestTypeInfo @@ -30,7 +30,7 @@ namespace FreeSql.Tests.OracleExpression public int ParentId { get; set; } public TestTypeParentInfo Parent { get; set; } public string Name { get; set; } - public DateTime Time { get; set; } + public DateTime Time { get; set; } = DateTime.Now; } [Table(Name = "TestTypeParentInf1")] class TestTypeParentInfo @@ -39,7 +39,7 @@ namespace FreeSql.Tests.OracleExpression public string Name { get; set; } public List Types { get; set; } - public DateTime Time2 { get; set; } + public DateTime Time2 { get; set; } = DateTime.Now; } [Fact] @@ -180,8 +180,8 @@ namespace FreeSql.Tests.OracleExpression { var data = new List(); data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); @@ -657,8 +657,8 @@ namespace FreeSql.Tests.OracleExpression { var data = new List(); data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic111333` a //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index 3ac2d3fd..8e36b3de 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Dameng { @@ -193,7 +192,7 @@ namespace FreeSql.Dameng { case "Date": return $"trunc({left})"; case "TimeOfDay": return $"(cast({left} as timestamp with time zone)-trunc({left}))"; - case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; + case "DayOfWeek": return $"case when to_char({left},'D')='7' then 0 else cast(to_char({left},'D') as number) end"; case "Day": return $"cast(to_char({left},'DD') as number)"; case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; case "Month": return $"cast(to_char({left},'MM') as number)"; @@ -361,7 +360,7 @@ namespace FreeSql.Dameng switch (exp.Method.Name) { case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; - case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; + case "DaysInMonth": return $"cast(to_char(last_day(to_date(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01','yyyy-mm-dd')),'DD') as number)"; case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; case "IsLeapYear": @@ -398,7 +397,64 @@ namespace FreeSql.Dameng break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"extract(day from ({left}-({args1})))"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + case "ToString": + if (left.StartsWith("'") || left.EndsWith("'")) left = $"to_timestamp({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return "YYYY"; + case "yy": return "YY"; + case "MM": return "%_a1"; + case "dd": return "%_a2"; + case "HH": return "%_a3"; + case "mm": return "%_a4"; + case "ss": return "SS"; + case "tt": return "%_a5"; + } + return m.Groups[0].Value; + }); + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "SS", "%_a5" }; + var argsSpts = Regex.Split(args1, "(M|d|H|hh|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "hh": argsSpts[a] = $"case mod(cast(case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end as number),12) when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end"; break; + case "h": argsSpts[a] = $"case mod(cast(case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end as number),12) when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + //达梦 to_char(to_timestamp('2020-02-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6'),' ') 无效 + } + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "MI").Replace("%_a5", "AM"); } } return null; diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 6069d19c..8fd09ef4 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -430,19 +430,25 @@ namespace FreeSql.MySql } return m.Groups[0].Value; }); - var isMatched = false; - args1 = Regex.Replace(args1, "(m|s|t)", m => + var argsFinds = new[] { "%Y", "%y", "%_a1", "%c", "%d", "%e", "%H", "%k", "%h", "%l", "%i", "%_a2", "%p" }; + var argsSpts = Regex.Split(args1, "(m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) { - isMatched = true; - switch (m.Groups[1].Value) + switch (argsSpts[a]) { - case "m": return $"'), case when substr(date_format({left},'%i'),1,1) = '0' then substr(date_format({left},'%i'),2,1) else date_format({left},'%i') end, date_format({left},'"; - case "s": return $"'), case when substr(date_format({left},'%s'),1,1) = '0' then substr(date_format({left},'%s'),2,1) else date_format({left},'%s') end, date_format({left},'"; - case "t": return $"'), trim(trailing 'M' from date_format({left},'%p')), date_format({left},'"; + case "m": argsSpts[a] = $"case when substr(date_format({left},'%i'),1,1) = '0' then substr(date_format({left},'%i'),2,1) else date_format({left},'%i') end"; break; + case "s": argsSpts[a] = $"case when substr(date_format({left},'%s'),1,1) = '0' then substr(date_format({left},'%s'),2,1) else date_format({left},'%s') end"; break; + case "t": argsSpts[a] = $"trim(trailing 'M' from date_format({left},'%p'))"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"date_format({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; } - return m.Groups[0].Value; - }).Replace("%_a1", "%m").Replace("%_a2", "%s"); - return isMatched == false ? $"date_format({left},{args1})" : $"concat(date_format({left},{args1}))".Replace($"date_format({left},'')", "''"); + } + if (argsSpts.Length > 0) args1 = $"concat({string.Join(", ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "%m").Replace("%_a2", "%s"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index 11604c98..a04c563d 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Odbc.Dameng { @@ -193,7 +192,7 @@ namespace FreeSql.Odbc.Dameng { case "Date": return $"trunc({left})"; case "TimeOfDay": return $"(cast({left} as timestamp with time zone)-trunc({left}))"; - case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; + case "DayOfWeek": return $"case when to_char({left},'D')='7' then 0 else cast(to_char({left},'D') as number) end"; case "Day": return $"cast(to_char({left},'DD') as number)"; case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; case "Month": return $"cast(to_char({left},'MM') as number)"; @@ -361,7 +360,7 @@ namespace FreeSql.Odbc.Dameng switch (exp.Method.Name) { case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; - case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; + case "DaysInMonth": return $"cast(to_char(last_day(to_date(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01','yyyy-mm-dd')),'DD') as number)"; case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; case "IsLeapYear": @@ -398,7 +397,64 @@ namespace FreeSql.Odbc.Dameng break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"extract(day from ({left}-({args1})))"; - case "ToString": return exp.Arguments.Count == 0 ? $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')" : null; + case "ToString": + if (left.StartsWith("'") || left.EndsWith("'")) left = $"to_timestamp({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return "YYYY"; + case "yy": return "YY"; + case "MM": return "%_a1"; + case "dd": return "%_a2"; + case "HH": return "%_a3"; + case "mm": return "%_a4"; + case "ss": return "SS"; + case "tt": return "%_a5"; + } + return m.Groups[0].Value; + }); + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "SS", "%_a5" }; + var argsSpts = Regex.Split(args1, "(M|d|H|hh|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "hh": argsSpts[a] = $"case mod(cast(case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end as number),12) when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end"; break; + case "h": argsSpts[a] = $"case mod(cast(case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end as number),12) when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + //达梦 to_char(to_timestamp('2020-02-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6'),' ') 无效 + } + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "MI").Replace("%_a5", "AM"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 5cb20008..ed583629 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -428,19 +428,25 @@ namespace FreeSql.Odbc.MySql } return m.Groups[0].Value; }); - var isMatched = false; - args1 = Regex.Replace(args1, "(m|s|t)", m => + var argsFinds = new[] { "%Y", "%y", "%_a1", "%c", "%d", "%e", "%H", "%k", "%h", "%l", "%i", "%_a2", "%p" }; + var argsSpts = Regex.Split(args1, "(m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) { - isMatched = true; - switch (m.Groups[1].Value) + switch (argsSpts[a]) { - case "m": return $"'), case when substr(date_format({left},'%i'),1,1) = '0' then substr(date_format({left},'%i'),2,1) else date_format({left},'%i') end, date_format({left},'"; - case "s": return $"'), case when substr(date_format({left},'%s'),1,1) = '0' then substr(date_format({left},'%s'),2,1) else date_format({left},'%s') end, date_format({left},'"; - case "t": return $"'), trim(trailing 'M' from date_format({left},'%p')), date_format({left},'"; + case "m": argsSpts[a] = $"case when substr(date_format({left},'%i'),1,1) = '0' then substr(date_format({left},'%i'),2,1) else date_format({left},'%i') end"; break; + case "s": argsSpts[a] = $"case when substr(date_format({left},'%s'),1,1) = '0' then substr(date_format({left},'%s'),2,1) else date_format({left},'%s') end"; break; + case "t": argsSpts[a] = $"trim(trailing 'M' from date_format({left},'%p'))"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"date_format({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; } - return m.Groups[0].Value; - }).Replace("%_a1", "%m").Replace("%_a2", "%s"); - return isMatched == false ? $"date_format({left},{args1})" : $"concat(date_format({left},{args1}))".Replace($"date_format({left},'')", "''"); + } + if (argsSpts.Length > 0) args1 = $"concat({string.Join(", ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "%m").Replace("%_a2", "%s"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 2795c374..ac6dbf3c 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -192,7 +192,7 @@ namespace FreeSql.Odbc.Oracle { case "Date": return $"trunc({left})"; case "TimeOfDay": return $"({left}-trunc({left}))"; - case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; + case "DayOfWeek": return $"case when to_char({left},'D')='7' then 0 else cast(to_char({left},'D') as number) end"; case "Day": return $"cast(to_char({left},'DD') as number)"; case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; case "Month": return $"cast(to_char({left},'MM') as number)"; @@ -360,7 +360,7 @@ namespace FreeSql.Odbc.Oracle switch (exp.Method.Name) { case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; - case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; + case "DaysInMonth": return $"cast(to_char(last_day(to_date(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01','yyyy-mm-dd')),'DD') as number)"; case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; case "IsLeapYear": @@ -431,23 +431,29 @@ namespace FreeSql.Odbc.Oracle } return m.Groups[0].Value; }); - var isMatched = false; - args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) { - isMatched = true; - switch (m.Groups[1].Value) + switch (argsSpts[a]) { - case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; - case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; - case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; - case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; - case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; - case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; - case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; } - return m.Groups[0].Value; - }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); - return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); } } return null; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 4ab8f9fd..e31e3aee 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -465,7 +465,7 @@ namespace FreeSql.Odbc.PostgreSQL var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); switch (exp.Method.Name) { - case "Add": return $"(({left})::timestamp+(({args1})||' microseconds')::interval)"; + case "Add": return $"(({left})::timestamp+((({args1})/1000)||' milliseconds')::interval)"; case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; @@ -478,7 +478,7 @@ namespace FreeSql.Odbc.PostgreSQL switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; - case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; + case "System.TimeSpan": return $"(({left})::timestamp-((({args1})/1000)||' milliseconds')::interval)"; } break; case "Equals": return $"({left} = ({args1})::timestamp)"; @@ -517,23 +517,29 @@ namespace FreeSql.Odbc.PostgreSQL } return m.Groups[0].Value; }); - var isMatched = false; - args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) { - isMatched = true; - switch (m.Groups[1].Value) + switch (argsSpts[a]) { - case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; - case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; - case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; - case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; - case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; - case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; - case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; } - return m.Groups[0].Value; - }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); - return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); } } return null; diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 2029c68e..7fe04b96 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -192,7 +192,7 @@ namespace FreeSql.Oracle { case "Date": return $"trunc({left})"; case "TimeOfDay": return $"({left}-trunc({left}))"; - case "DayOfWeek": return $"case when to_char({left})='7' then 0 else cast(to_char({left}) as number) end"; + case "DayOfWeek": return $"case when to_char({left},'D')='7' then 0 else cast(to_char({left},'D') as number) end"; case "Day": return $"cast(to_char({left},'DD') as number)"; case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; case "Month": return $"cast(to_char({left},'MM') as number)"; @@ -360,7 +360,7 @@ namespace FreeSql.Oracle switch (exp.Method.Name) { case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; - case "DaysInMonth": return $"cast(to_char(last_day(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01'),'DD') as number)"; + case "DaysInMonth": return $"cast(to_char(last_day(to_date(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01','yyyy-mm-dd')),'DD') as number)"; case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; case "IsLeapYear": @@ -431,23 +431,29 @@ namespace FreeSql.Oracle } return m.Groups[0].Value; }); - var isMatched = false; - args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) { - isMatched = true; - switch (m.Groups[1].Value) + switch (argsSpts[a]) { - case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; - case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; - case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; - case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; - case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; - case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; - case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; } - return m.Groups[0].Value; - }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); - return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); } } return null; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 6c56f6a2..42d1a495 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -496,7 +496,7 @@ namespace FreeSql.PostgreSQL var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); switch (exp.Method.Name) { - case "Add": return $"(({left})::timestamp+(({args1})||' microseconds')::interval)"; + case "Add": return $"(({left})::timestamp+((({args1})/1000)||' milliseconds')::interval)"; case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; @@ -509,7 +509,7 @@ namespace FreeSql.PostgreSQL switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) { case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; - case "System.TimeSpan": return $"(({left})::timestamp-(({args1})||' microseconds')::interval)"; + case "System.TimeSpan": return $"(({left})::timestamp-((({args1})/1000)||' milliseconds')::interval)"; } break; case "Equals": return $"({left} = ({args1})::timestamp)"; @@ -548,23 +548,29 @@ namespace FreeSql.PostgreSQL } return m.Groups[0].Value; }); - var isMatched = false; - args1 = Regex.Replace(args1, "(M|d|H|h|m|s|t)", m => + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) { - isMatched = true; - switch (m.Groups[1].Value) + switch (argsSpts[a]) { - case "M": return $"') || ltrim(to_char({left},'MM'),'0') || to_char({left},'"; - case "d": return $"') || case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end || to_char({left},'"; - case "H": return $"') || case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end || to_char({left},'"; - case "h": return $"') || case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end || to_char({left},'"; - case "m": return $"') || case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end || to_char({left},'"; - case "s": return $"') || case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end || to_char({left},'"; - case "t": return $"') || rtrim(to_char({left},'AM'),'M') || to_char({left},'"; + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; } - return m.Groups[0].Value; - }).Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); - return isMatched == false ? $"to_char({left},{args1})" : $"(to_char({left},{args1}))".Replace($"to_char({left},'')", "''"); + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); } } return null; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 2fb321ea..5a82b092 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -425,26 +425,32 @@ namespace FreeSql.Sqlite } return m.Groups[0].Value; }); - var isMatched = false; - args1 = Regex.Replace(args1, "(yy|M|d|H|hh|h|m|s|tt|t)", m => + var argsFinds = new[] { "%Y", "%_a1", "%_a2", "%_a3", "%_a4", "%S" }; + var argsSpts = Regex.Split(args1, "(yy|M|d|H|hh|h|m|s|tt|t)"); + for (var a = 0; a < argsSpts.Length; a++) { - isMatched = true; - switch (m.Groups[1].Value) + switch (argsSpts[a]) { - case "yy": return $"',{left}) || substr(strftime('%Y',{left}),3,2) || strftime('"; - case "M": return $"',{left}) || ltrim(strftime('%m',{left}),'0') || strftime('"; - case "d": return $"',{left}) || ltrim(strftime('%d',{left}),'0') || strftime('"; - case "H": return $"',{left}) || case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end || strftime('"; - case "hh": return $"',{left}) || case cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) % 12 when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end || strftime('"; - case "h": return $"',{left}) || case cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) % 12 when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end || strftime('"; - case "m": return $"',{left}) || case when substr(strftime('%M',{left}),1,1) = '0' then substr(strftime('%M',{left}),2,1) else strftime('%M',{left}) end || strftime('"; - case "s": return $"',{left}) || case when substr(strftime('%S',{left}),1,1) = '0' then substr(strftime('%S',{left}),2,1) else strftime('%S',{left}) end || strftime('"; - case "tt": return $"',{left}) || case when cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) >= 12 then 'PM' else 'AM' end || strftime('"; - case "t": return $"',{left}) || case when cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) >= 12 then 'P' else 'A' end || strftime('"; + case "yy": argsSpts[a] = $"substr(strftime('%Y',{left}),3,2)"; break; + case "M": argsSpts[a] = $"ltrim(strftime('%m',{left}),'0')"; break; + case "d": argsSpts[a] = $"ltrim(strftime('%d',{left}),'0')"; break; + case "H": argsSpts[a] = $"case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end"; break; + case "hh": argsSpts[a] = $"case cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) % 12 when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end"; break; + case "h": argsSpts[a] = $"case cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) % 12 when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end"; break; + case "m": argsSpts[a] = $"case when substr(strftime('%M',{left}),1,1) = '0' then substr(strftime('%M',{left}),2,1) else strftime('%M',{left}) end"; break; + case "s": argsSpts[a] = $"case when substr(strftime('%S',{left}),1,1) = '0' then substr(strftime('%S',{left}),2,1) else strftime('%S',{left}) end"; break; + case "tt": argsSpts[a] = $"case when cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) >= 12 then 'PM' else 'AM' end"; break; + case "t": argsSpts[a] = $"case when cast(case when substr(strftime('%H',{left}),1,1) = '0' then substr(strftime('%H',{left}),2,1) else strftime('%H',{left}) end as smallint) >= 12 then 'P' else 'A' end"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"strftime('{argsSptsA}',{left})" : $"'{argsSptsA}'"; + break; } - return m.Groups[0].Value; - }).Replace("%_a1", "%m").Replace("%_a2", "%d").Replace("%_a3", "%H").Replace("%_a4", "%M"); - return isMatched == false ? $"strftime({args1},{left})" : $"(strftime({args1},{left}))".Replace($"strftime('',{left})", "''"); + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "%m").Replace("%_a2", "%d").Replace("%_a3", "%H").Replace("%_a4", "%M"); } } return null; From 5353b9bdb15444dadb1736cc692aba01992ca05e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 24 May 2020 08:49:14 +0800 Subject: [PATCH 0667/1029] =?UTF-8?q?-=20=E6=A3=80=E6=9F=A5=20MsAccess=20D?= =?UTF-8?q?ateTime=20Format=20=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Oracle/OracleExpression/DateTimeTest.cs | 50 +- .../MsAccessExpression/DateTimeTest.cs | 465 ++---------------- .../MsAccessExpression.cs | 2 +- 3 files changed, 80 insertions(+), 437 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs index 91829936..283a5cf2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/DateTimeTest.cs @@ -61,31 +61,31 @@ namespace FreeSql.Tests.Odbc.OracleExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - g.oracle.Insert(new Topic()).ExecuteAffrows(); - var dtn = DateTime.Parse("2020-1-1 0:0:0"); - var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) - .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) - .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) - .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) - .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); - foreach (var dt in dts) - { - Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); - Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); - Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); - Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); - Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); - Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); - Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); - Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); - Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); - Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); - Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); - Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); - Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); - Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); - Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); - } + //g.oracle.Insert(new Topic()).ExecuteAffrows(); + //var dtn = DateTime.Parse("2020-1-1 0:0:0"); + //var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + // .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + // .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + // .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + // .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + //foreach (var dt in dts) + //{ + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + // Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + // Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + // Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + // Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + // Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + // Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + // Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + // Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + // Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + // Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + //} } [Fact] public void Now() diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/DateTimeTest.cs index c6b32990..ce3566cb 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/DateTimeTest.cs @@ -41,74 +41,76 @@ namespace FreeSql.Tests.MsAccessExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + + //g.msaccess.Insert(new Topic()).ExecuteAffrows(); + //var dtn = DateTime.Parse("2020-1-1 0:0:0"); + //var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + // .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + // .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + // .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + // .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + //foreach (var dt in dts) + //{ + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString())); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + // Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + // Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + // Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + // Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + // Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + // Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + // Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + // Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + // //Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + // //Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + //} + } [Fact] public void Now() { var data = new List(); data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) } [Fact] public void UtcNow() { var data = new List(); data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) } [Fact] public void MinValue() { var data = new List(); data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) } [Fact] public void MaxValue() { var data = new List(); data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) } [Fact] public void Date() { var data = new List(); data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + //data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); - data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + //data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); } [Fact] public void TimeOfDay() @@ -117,36 +119,14 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) } [Fact] public void DayOfWeek() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + //var data = new List(); + //data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); } [Fact] public void Day() @@ -155,17 +135,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) } [Fact] public void DayOfYear() @@ -174,17 +143,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) } [Fact] public void Month() @@ -193,17 +151,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (month(a.`CreateTime`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (month(a__Type.`Time`) > month(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (month(a__Type__Parent.`Time2`) > month(now())) } [Fact] public void Year() @@ -212,17 +159,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (year(a.`CreateTime`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (year(a__Type.`Time`) > year(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (year(a__Type__Parent.`Time2`) > year(now())) } [Fact] public void Hour() @@ -231,17 +167,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (hour(a.`CreateTime`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (hour(a__Type.`Time`) > hour(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) } [Fact] public void Minute() @@ -250,17 +175,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (minute(a.`CreateTime`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (minute(a__Type.`Time`) > minute(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) } [Fact] public void Second() @@ -269,17 +183,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (second(a.`CreateTime`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (second(a__Type.`Time`) > second(now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (second(a__Type__Parent.`Time2`) > second(now())) } [Fact] public void Millisecond() @@ -288,36 +191,14 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) } [Fact] public void Ticks() { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + //var data = new List(); + //data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + //data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); } [Fact] public void Add() @@ -326,17 +207,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) } [Fact] public void AddDays() @@ -345,17 +215,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) } [Fact] public void AddHours() @@ -364,17 +223,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) } [Fact] public void AddMilliseconds() @@ -383,17 +231,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) } [Fact] public void AddMinutes() @@ -402,17 +239,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) } [Fact] public void AddMonths() @@ -421,17 +247,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) } [Fact] public void AddSeconds() @@ -440,17 +255,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) } [Fact] public void AddTicks() @@ -459,17 +263,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) } [Fact] public void AddYears() @@ -478,17 +271,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) } [Fact] public void Subtract() @@ -497,37 +279,10 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" - //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" - //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") } [Fact] public void _ЧͬSubtract() @@ -536,37 +291,10 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //WHERE (((strftime('%s',a."CreateTime")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //WHERE (((strftime('%s',a__Type."Time")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" - //WHERE (((strftime('%s',a__Type__Parent."Time2")-strftime('%s',datetime(current_timestamp,'localtime')))) > 0) data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."Id", a."Clicks", a."TypeGuid", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //WHERE (datetime(a."CreateTime",(-((1)*86400))||' seconds') > a."CreateTime") - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //WHERE (datetime(a__Type."Time",(-((1)*86400))||' seconds') > a."CreateTime") - - //SELECT a."Id", a."Clicks", a."TypeGuid", a__Type."Guid", a__Type."ParentId", a__Type."Name", a__Type."Time", a."Title", a."CreateTime" - //FROM "tb_topic111333" a - //LEFT JOIN "TestTypeInfo333" a__Type ON a__Type."Guid" = a."TypeGuid" - //LEFT JOIN "TestTypeParentInfo23123" a__Type__Parent ON a__Type__Parent."Id" = a__Type."ParentId" - //WHERE (datetime(a__Type__Parent."Time2",(-((1)*86400))||' seconds') > a."CreateTime") } [Fact] public void this_Equals() @@ -575,36 +303,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) - } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) } [Fact] @@ -614,36 +312,14 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((a.`CreateTime`) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) } [Fact] public void DateTime_DaysInMonth() { var data = new List(); - data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); - data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + //data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); } [Fact] public void DateTime_Equals() @@ -652,17 +328,6 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } [Fact] public void DateTime_IsLeapYear() @@ -671,36 +336,14 @@ namespace FreeSql.Tests.MsAccessExpression data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) } [Fact] public void DateTime_Parse() { var data = new List(); - data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); - data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + //data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + //data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + //data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); } } } diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs index 2692b868..87b1ec06 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -343,7 +343,7 @@ namespace FreeSql.MsAccess break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff('s',{args1},{left})"; - case "ToString": return exp.Arguments.Count == 0 ? $"format({left},'yyyy-mm-dd HH:mm:ss')" : null; + case "ToString": return exp.Arguments.Count == 0 ? $"format({left},'yyyy-mm-dd HH:mm:ss')" : $"format({left},{args1})"; } } return null; From 1ac13d6327eb1c26edd831a997db1f78c0f57290 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 25 May 2020 04:20:42 +0800 Subject: [PATCH 0668/1029] v1.5.0 #291 #311 #323 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 169 ++++++++++++++++++ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 187 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index bb7be7e6..a0d3fad9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e6d02eb3..98a98e88 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 94bb2e59..8ddd707a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 2fbdfcbd..50004381 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 6fd7bb14..d4318157 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0-preview0525 + 1.5.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index cf7904fb..1245fcd6 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 3877950f..644bf350 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3ede074b..3eb5cbef 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0-preview0525 + 1.5.0 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3ed63f42..47f36213 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e50637da..b63f13b6 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3718,3 +3718,172 @@ +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 条件 + + + + diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index e9593a3b..e5b093a4 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 0a2a6d3b..47d9ffac 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 49985878..11397cde 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d94983ac..6e8a0fe4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index b6de7e77..b0c6295d 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ff836522..d945c3ac 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 79aceec3..0a38c0b2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 050b201e..be525381 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 445a5180..7d7c5bce 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0-preview0525 + 1.5.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 0d6ebc1e265f83b2dccdbbce68c2a0b31189fc39 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 26 May 2020 02:50:21 +0800 Subject: [PATCH 0669/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20CodeFirst=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=8F=98=E5=8C=96=E5=AF=B9=E6=AF=94=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + Examples/base_entity/Program.cs | 11 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 - FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 11 + FreeSql/FreeSql.xml | 312 ++++++++---------- .../DamengCodeFirst.cs | 5 +- .../MsAccessCodeFirst.cs | 6 +- .../Dameng/OdbcDamengCodeFirst.cs | 5 +- .../Oracle/OdbcOracleCodeFirst.cs | 5 +- .../SqlServer/OdbcSqlServerCodeFirst.cs | 3 + .../OracleCodeFirst.cs | 5 +- .../SqlServerCodeFirst.cs | 3 + .../SqliteCodeFirst.cs | 6 +- 13 files changed, 199 insertions(+), 185 deletions(-) diff --git a/.gitignore b/.gitignore index de79a863..0230a2ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +FreeSql.xml +FreeSql.DbContext.xml + # User-specific files *.suo *.user diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 385e38a5..5b0aca9d 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -5,6 +5,7 @@ using FreeSql.Internal.Model; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; +using System.Data.Odbc; using System.Data.SqlClient; using System.Diagnostics; using System.Linq.Expressions; @@ -41,6 +42,14 @@ namespace base_entity static void Main(string[] args) { + var conn = new OdbcConnection("Driver={KingbaseES 8.2 ODBC Driver ANSI};Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=TEST"); + conn.Open(); + var cmd = conn.CreateCommand(); + cmd.CommandText = "insert into cc2.IDETB01(C1) values(1),(2)"; + cmd.ExecuteNonQuery(); + cmd.CommandText = "select C1 from cc2.\"IDETB01\" where rownum < 2"; + var idw = cmd.ExecuteScalar(); + conn.Close(); #region 初始化 IFreeSql var fsql = new FreeSql.FreeSqlBuilder() @@ -72,7 +81,7 @@ namespace base_entity //.UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") - .UseMonitorCommand(cmd => Console.WriteLine(cmd.CommandText)) + .UseMonitorCommand(umcmd => Console.WriteLine(umcmd.CommandText)) .UseLazyLoading(true) .Build(); BaseEntity.Initialization(fsql, () => _asyncUow.Value); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,14 +486,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 2c5357c4..f8499441 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -438,6 +438,17 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var testemoji = new TestGuidId { xxx = "💐🌸💮🌹🌺🌻🌼🌷🌱🌿🍀" }; + Assert.Equal(1, g.sqlserver.Insert(testemoji).ExecuteAffrows()); + var emoji = g.sqlserver.Select().Where(a => a.Id == testemoji.Id).First(); + Assert.Equal("💐🌸💮🌹🌺🌻🌼🌷🌱🌿🍀", emoji.xxx); + + Assert.Equal(1, g.sqlserver.Delete(testemoji).ExecuteAffrows()); + testemoji = new TestGuidId { xxx = "💐🌸💮🌹🌺🌻🌼🌷🌱🌿🍀" }; + Assert.Equal(1, g.sqlserver.Insert().NoneParameter().AppendData(testemoji).ExecuteAffrows()); + emoji = g.sqlserver.Select().Where(a => a.Id == testemoji.Id).First(); + Assert.Equal("💐🌸💮🌹🌺🌻🌼🌷🌱🌿🍀", emoji.xxx); + var _model = new TestUpdateModel { F_EmpId = "xx11", F_RoleType = TestUpdateModelEnum.x2, diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b63f13b6..5545a967 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2405,6 +2405,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 }) + + + + + + 可自定义解析表达式 @@ -3007,6 +3138,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3077,6 +3214,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3718,172 +3861,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 条件 - - - - diff --git a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs index d039e15d..67910e61 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs @@ -229,6 +229,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (istmpatler && Regex.IsMatch(tbcol.Attribute.DbType, @"\(\d+") == false && Regex.IsMatch(tbstructcol.sqlType, @"\(\d+") && string.Compare(tbcol.Attribute.DbType, Regex.Replace(tbstructcol.sqlType, @"\([^\)]+\)", ""), StringComparison.CurrentCultureIgnoreCase) == 0) istmpatler = false; + if (istmpatler) break; } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) @@ -262,7 +263,9 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } - + } + if (istmpatler == false) + { var dsuksql = _commonUtils.FormatSql(@" select c.column_name, diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs index a78a56ea..463c0001 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs @@ -353,9 +353,10 @@ namespace FreeSql.MsAccess { foreach (var tbcol in tb.ColumnsByPosition) { + if (istmpatler) break; var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { if (tbstructcol.sqlType != "LONG" && tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) istmpatler = true; @@ -371,6 +372,9 @@ namespace FreeSql.MsAccess //添加列 istmpatler = true; } + } + if (istmpatler == false) + { var dsuk = getIndexesByTableName(tbtmp); foreach (var uk in tb.Indexes) { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index da91867c..1440f806 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -229,6 +229,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (istmpatler && Regex.IsMatch(tbcol.Attribute.DbType, @"\(\d+") == false && Regex.IsMatch(tbstructcol.sqlType, @"\(\d+") && string.Compare(tbcol.Attribute.DbType, Regex.Replace(tbstructcol.sqlType, @"\([^\)]+\)", ""), StringComparison.CurrentCultureIgnoreCase) == 0) istmpatler = false; + if (istmpatler) break; } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) @@ -262,7 +263,9 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } - + } + if (istmpatler == false) + { var dsuksql = _commonUtils.FormatSql(@" select c.column_name, diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index cf3b5b64..f1d03da1 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -226,6 +226,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) istmpatler = false; + if (istmpatler) break; } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) @@ -259,7 +260,9 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } - + } + if (istmpatler == false) + { CreateOracleFunction(_orm); var dsuksql = _commonUtils.FormatSql(@" select diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 0f552451..d6eae2bc 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -323,6 +323,9 @@ use [" + database + "];", tboldname ?? tbname); sbalter.Append(";\r\n"); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } + } + if (istmpatler == false) + { var dsuksql = string.Format(@" use [{0}]; select diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 8a8abe9d..fbc93fe7 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -227,6 +227,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) istmpatler = false; + if (istmpatler) break; } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) @@ -260,7 +261,9 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } - + } + if (istmpatler == false) + { CreateOracleFunction(_orm); var dsuksql = _commonUtils.FormatSql(@" select diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 4eaa1476..c5f0959e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -322,6 +322,9 @@ use [" + database + "];", tboldname ?? tbname); sbalter.Append(";\r\n"); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } + } + if (istmpatler == false) + { var dsuksql = string.Format(@" use [{0}]; select diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index eb267acb..044e1e4c 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -184,9 +184,10 @@ namespace FreeSql.Sqlite { foreach (var tbcol in tb.ColumnsByPosition) { + if (istmpatler) break; var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) istmpatler = true; @@ -202,6 +203,9 @@ namespace FreeSql.Sqlite //添加列 istmpatler = true; } + } + if (istmpatler == false) + { var dsuk = new List(); var dbIndexes = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.INDEX_LIST(\"{tbtmp[1]}\")"); foreach (var dbIndex in dbIndexes) From 7d8457a988cda592e3a7d2652c6115c2e25a09d9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 27 May 2020 05:59:33 +0800 Subject: [PATCH 0670/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E4=BA=BA?= =?UTF-8?q?=E5=A4=A7=E9=87=91=E4=BB=93=20OdbcKingbaseES=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=EF=BC=9B#325?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 9 - FreeSql.DbContext/FreeSql.DbContext.xml | 9 + .../KingbaseES/Curd/KingbaseESDeleteTest.cs | 106 + .../Curd/KingbaseESInsertOrUpdateTest.cs | 205 ++ .../KingbaseES/Curd/KingbaseESInsertTest.cs | 141 ++ .../KingbaseES/Curd/KingbaseESSelectTest.cs | 1752 +++++++++++++++++ .../KingbaseES/Curd/KingbaseESUpdateTest.cs | 190 ++ .../KingbaseES/Curd/OnConflictDoUpdateTest.cs | 158 ++ .../KingbaseESAdo/KingbaseESAdoTest.cs | 66 + .../KingbaseES/KingbaseESAopTest.cs | 40 + .../KingbaseES/KingbaseESCodeFirstTest.cs | 327 +++ .../KingbaseES/KingbaseESDbFirstTest.cs | 25 + .../KingbaseESExpression/ConvertTest.cs | 169 ++ .../KingbaseESExpression/DateTimeTest.cs | 732 +++++++ .../KingbaseESExpression/MathTest.cs | 156 ++ .../KingbaseESExpression/OtherTest.cs | 165 ++ .../KingbaseESExpression/StringTest.cs | 726 +++++++ .../KingbaseESExpression/TimeSpanTest.cs | 293 +++ .../KingbaseES/MapType/BoolNullableTest.cs | 1571 +++++++++++++++ .../KingbaseES/MapType/BoolTest.cs | 1105 +++++++++++ .../KingbaseES/MapType/DateTimeOffSetTest.cs | 54 + .../KingbaseES/MapType/EnumTest.cs | 261 +++ .../KingbaseES/MapType/ToStringTest.cs | 570 ++++++ .../FreeSql.Tests.Provider.Odbc/g.cs | 9 +- .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 32 +- FreeSql/DataType.cs | 7 +- FreeSql/FreeSql.xml | 317 +-- FreeSql/FreeSqlBuilder.cs | 5 + .../SelectProvider/Select0Provider.cs | 1 + .../FreeSql.Provider.Dameng/DamengUtils.cs | 2 +- .../MsAccessUtils.cs | 2 +- .../FreeSql.Provider.MySql/MySqlUtils.cs | 2 +- .../MySqlConnectorUtils.cs | 2 +- .../Dameng/OdbcDamengUtils.cs | 2 +- .../Default/OdbcUtils.cs | 2 +- .../FreeSqlOdbcGlobalExtensions.cs | 9 + .../KingbaseES/Curd/OdbcKingbaseESDelete.cs | 99 + .../KingbaseES/Curd/OdbcKingbaseESInsert.cs | 216 ++ .../Curd/OdbcKingbaseESInsertOrUpdate.cs | 57 + .../Curd/OdbcKingbaseESOnConflictDoUpdate.cs | 207 ++ .../KingbaseES/Curd/OdbcKingbaseESSelect.cs | 174 ++ .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 164 ++ .../OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs | 77 + .../OdbcKingbaseESConnectionPool.cs | 258 +++ .../KingbaseES/OdbcKingbaseESCodeFirst.cs | 459 +++++ .../KingbaseES/OdbcKingbaseESDbFirst.cs | 120 ++ .../KingbaseES/OdbcKingbaseESExpression.cs | 585 ++++++ .../KingbaseES/OdbcKingbaseESProvider.cs | 60 + .../KingbaseES/OdbcKingbaseESUtils.cs | 161 ++ .../MySql/OdbcMySqlUtils.cs | 2 +- .../Oracle/OdbcOracleUtils.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLUtils.cs | 2 +- .../SqlServer/OdbcSqlServerUtils.cs | 2 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 2 +- .../PostgreSQLUtils.cs | 2 +- .../SqlServerUtils.cs | 2 +- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 2 +- 57 files changed, 11687 insertions(+), 188 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/OnConflictDoUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/ToStringTest.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESProvider.cs create mode 100644 Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 5b0aca9d..d67d7994 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -42,15 +42,6 @@ namespace base_entity static void Main(string[] args) { - var conn = new OdbcConnection("Driver={KingbaseES 8.2 ODBC Driver ANSI};Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=TEST"); - conn.Open(); - var cmd = conn.CreateCommand(); - cmd.CommandText = "insert into cc2.IDETB01(C1) values(1),(2)"; - cmd.ExecuteNonQuery(); - cmd.CommandText = "select C1 from cc2.\"IDETB01\" where rownum < 2"; - var idw = cmd.ExecuteScalar(); - conn.Close(); - #region 初始化 IFreeSql var fsql = new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESDeleteTest.cs new file mode 100644 index 00000000..40ea21d9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESDeleteTest.cs @@ -0,0 +1,106 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESDeleteTest + { + + IDelete delete => g.kingbaseES.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.kingbaseES.Delete().ToSql()); + var sql = g.kingbaseES.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.kingbaseES.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.kingbaseES.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.kingbaseES.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.kingbaseES.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.kingbaseES.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //var item = g.kingbaseES.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.kingbaseES.Delete().ToSql()); + var sql = g.kingbaseES.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.kingbaseES.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + + sql = g.kingbaseES.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.kingbaseES.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs new file mode 100644 index 00000000..4a1cff8f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs @@ -0,0 +1,205 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESInsertOrUpdateTest + { + IFreeSql fsql => g.kingbaseES; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(2) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(1, '01') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(1, '011') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(2, '02') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '02', '011') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(2, '02', '02') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertTest.cs new file mode 100644 index 00000000..d6ace67c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESInsertTest + { + + IInsert insert => g.kingbaseES.Insert(); + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000000'), (100, 'newtitle1', '0001-01-01 00:00:00.000000'), (200, 'newtitle2', '0001-01-01 00:00:00.000000'), (300, 'newtitle3', '0001-01-01 00:00:00.000000'), (400, 'newtitle4', '0001-01-01 00:00:00.000000'), (500, 'newtitle5', '0001-01-01 00:00:00.000000'), (600, 'newtitle6', '0001-01-01 00:00:00.000000'), (700, 'newtitle7', '0001-01-01 00:00:00.000000'), (800, 'newtitle8', '0001-01-01 00:00:00.000000'), (900, 'newtitle9', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"TITLE\") VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"TITLE\") VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\") VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.kingbaseES.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.kingbaseES.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.kingbaseES.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + insert.AppendData(items.First()).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000000'), (100, 'newTitle1', '0001-01-01 00:00:00.000000'), (200, 'newTitle2', '0001-01-01 00:00:00.000000'), (300, 'newTitle3', '0001-01-01 00:00:00.000000'), (400, 'newTitle4', '0001-01-01 00:00:00.000000'), (500, 'newTitle5', '0001-01-01 00:00:00.000000'), (600, 'newTitle6', '0001-01-01 00:00:00.000000'), (700, 'newTitle7', '0001-01-01 00:00:00.000000'), (800, 'newTitle8', '0001-01-01 00:00:00.000000'), (900, 'newTitle9', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"TITLE\") VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"TITLE\") VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\") VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs new file mode 100644 index 00000000..fed8ea69 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs @@ -0,0 +1,1752 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESSelectTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.kingbaseES.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.kingbaseES.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.kingbaseES.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.kingbaseES.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.kingbaseES.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.kingbaseES.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.kingbaseES.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.kingbaseES.Insert(items).ExecuteAffrows()); + + //var dt1 = select.ToDataTable(); + //var dt2 = select.ToDataTable("id, 111222"); + //var dt3 = select.ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + g.kingbaseES.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.kingbaseES.Select().ToList(); + var testGuidId6 = g.kingbaseES.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.kingbaseES.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.kingbaseES.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.kingbaseES.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + g.kingbaseES.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.kingbaseES.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); + query2.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.kingbaseES.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.kingbaseES.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") + FROM ""TB_TOPIC22"" b + limit 1) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") + FROM ""TB_TOPIC22"" b + limit 1) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") + FROM ""TB_TOPIC22"" b + limit 1) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") + FROM ""TB_TOPIC22"" b + limit 1) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE ((((a.""ID"")::varchar) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.kingbaseES.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.kingbaseES.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.kingbaseES.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.kingbaseES.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.kingbaseES.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.kingbaseES.Insert(model4s).ExecuteAffrows()); + + var t0 = g.kingbaseES.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.kingbaseES.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.kingbaseES.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.kingbaseES.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.kingbaseES.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.kingbaseES.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.kingbaseES.Insert(model1).ExecuteIdentity(); + + var t1 = g.kingbaseES.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.kingbaseES.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.kingbaseES.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.kingbaseES.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.kingbaseES.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.kingbaseES.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.kingbaseES.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.kingbaseES.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.kingbaseES.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.kingbaseES.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.kingbaseES.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.kingbaseES.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.kingbaseES.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.kingbaseES.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.kingbaseES.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.kingbaseES.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.kingbaseES.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.kingbaseES.Insert(song3).ExecuteIdentity(); + + g.kingbaseES.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.kingbaseES.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.kingbaseES.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.kingbaseES, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.kingbaseES.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.kingbaseES.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.kingbaseES.Select().Count()); + Assert.Equal(3, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.kingbaseES.Select().Count()); + Assert.Equal(3, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.kingbaseES.Select().Count()); + Assert.Equal(3, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.kingbaseES.Select().Count()); + Assert.Equal(5, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.kingbaseES.Select().Count()); + Assert.Equal(5, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.kingbaseES.Select().Count()); + Assert.Equal(5, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.kingbaseES; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a limit 1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a limit 1 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.kingbaseES; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs new file mode 100644 index 00000000..383406e0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs @@ -0,0 +1,190 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESUpdateTest + { + IUpdate update => g.kingbaseES.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.kingbaseES.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.kingbaseES.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.kingbaseES.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL, \"TITLE\" = 'newtitle', \"CREATETIME\" = '0001-01-01 00:00:00.000000' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END::int4, \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::varchar, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN '0001-01-01 00:00:00.000000' WHEN 2 THEN '0001-01-01 00:00:00.000000' WHEN 3 THEN '0001-01-01 00:00:00.000000' WHEN 4 THEN '0001-01-01 00:00:00.000000' WHEN 5 THEN '0001-01-01 00:00:00.000000' WHEN 6 THEN '0001-01-01 00:00:00.000000' WHEN 7 THEN '0001-01-01 00:00:00.000000' WHEN 8 THEN '0001-01-01 00:00:00.000000' WHEN 9 THEN '0001-01-01 00:00:00.000000' WHEN 10 THEN '0001-01-01 00:00:00.000000' END::timestamp WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::varchar WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = '2020-01-01 00:00:00.000000' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + if (g.kingbaseES.Select().Where(a => a.id1 == 1 && a.id2 == 7).Any() == false) + g.kingbaseES.Insert(new ts_source_mpk { id1 = 1, id2 = 7 }).ExecuteAffrows(); + if (g.kingbaseES.Select().Where(a => a.id1 == 1 && a.id2 == 8).Any() == false) + g.kingbaseES.Insert(new ts_source_mpk { id1 = 1, id2 = 8 }).ExecuteAffrows(); + + sql = g.kingbaseES.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + g.kingbaseES.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ExecuteAffrows(); + var testlist = g.kingbaseES.Select().ToList(); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.kingbaseES.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle', \"CREATETIME\" = '2020-01-01 00:00:00.000000' WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = \"CLICKS\" * 10 / 1 WHERE (\"ID\" = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > '2000-01-01 00:00:00.000000' then 1 else 2 end WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + ? WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.kingbaseES.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.kingbaseES.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.kingbaseES.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/OnConflictDoUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/OnConflictDoUpdateTest.cs new file mode 100644 index 00000000..608f2acc --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/OnConflictDoUpdateTest.cs @@ -0,0 +1,158 @@ +using FreeSql.DataAnnotations; +using FreeSql.Odbc.KingbaseES; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class OnConflictDoUpdateTest + { + class TestOnConflictDoUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime? time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.kingbaseES.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"", ""TIME"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = EXCLUDED.""TIME""", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"", ""TIME"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000'), (101, 'title-101', '2000-01-01 00:00:00.000000'), (102, 'title-102', '2000-01-01 00:00:00.000000') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = EXCLUDED.""TIME""", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.kingbaseES.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(200, 'title-200') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = CASE EXCLUDED.""ID"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.kingbaseES.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(200, 'title-200') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = CASE EXCLUDED.""ID"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.kingbaseES.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(300, 'title-300') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = CASE EXCLUDED.""ID"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.kingbaseES.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(300, 'title-300') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = CASE EXCLUDED.""ID"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.kingbaseES.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"", ""TIME"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = '2020-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new OdbcKingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"", ""TIME"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = '2020-01-01 00:00:00.000000'", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs new file mode 100644 index 00000000..f37a4b02 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs @@ -0,0 +1,66 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.kingbaseES.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.kingbaseES.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t3 = g.kingbaseES.Ado.Query("select * from \"TB_TOPIC\""); + + var t4 = g.kingbaseES.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + + var t5 = g.kingbaseES.Ado.Query("select * from \"TB_TOPIC\""); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.kingbaseES.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAopTest.cs new file mode 100644 index 00000000..43d22c41 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.kingbaseES.Aop.AuditValue += audit; + + g.kingbaseES.Insert(item).ExecuteAffrows(); + + g.kingbaseES.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs new file mode 100644 index 00000000..8d72a1b3 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs @@ -0,0 +1,327 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESCodeFirstTest + { + [Fact] + public void StringLength() + { + var dll = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + g.kingbaseES.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void ֱ_ֶ() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements<ֱ>(); + g.kingbaseES.CodeFirst.SyncStructure<ֱ>(); + + var item = new ֱ + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.kingbaseES.Insert<ֱ>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.kingbaseES.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.kingbaseES.Update<ֱ>().SetSource(item).ExecuteAffrows()); + item2 = g.kingbaseES.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.kingbaseES.GetRepository<ֱ>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.kingbaseES.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.kingbaseES.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + [Table(Name = "123ֱ")] + class ֱ + { + [Column(IsPrimary = true, Name = "123")] + public Guid { get; set; } + + [Column(Name = "123")] + public string { get; set; } + + [Column(Name = "123ʱ")] + public DateTime ʱ { get; set; } + } + + [Fact] + public void ı_ֶ() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements<ı>(); + g.kingbaseES.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.kingbaseES.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.kingbaseES.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.kingbaseES.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.kingbaseES.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.kingbaseES.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.kingbaseES.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.kingbaseES.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + g.kingbaseES.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + + var id = g.kingbaseES.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.kingbaseES.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar2(200) not null", OldName = "title")] + public string title2 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + //sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.kingbaseES.Insert(); + ISelect select => g.kingbaseES.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem21 = select.Where(a => a.Id == item2.Id).First(a => new + { + a.Id, + a.id2, + a.SByte, + a.Short, + a.Int, + a.Long, + a.Byte, + a.UShort, + a.UInt, + a.ULong, + a.Double, + a.Float, + a.Decimal, + a.TimeSpan, + a.DateTimeOffSet, + a.Bytes, + a.String, + a.Guid + }); + var newitem22 = select.Where(a => a.Id == item2.Id).First(a => new + { + a.Id, a.id2, a.SByte, a.Short, a.Int, a.Long, a.Byte, a.UShort, a.UInt, a.ULong, a.Double, a.Float, a.Decimal, a.TimeSpan, a.DateTime, a.DateTimeOffSet, a.Bytes, a.String, a.Guid + }); + + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs new file mode 100644 index 00000000..39adb728 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.kingbaseES.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + //var t2 = g.kingbaseES.DbFirst.GetTablesByDatabase(); + //var tb = g.kingbaseES.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/ConvertTest.cs new file mode 100644 index 00000000..b14da23a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESExpression +{ + public class ConvertTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/DateTimeTest.cs new file mode 100644 index 00000000..8856f946 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/DateTimeTest.cs @@ -0,0 +1,732 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESExpression +{ + public class DateTimeTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } = DateTime.Now; + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } = DateTime.Now; + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.kingbaseES.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + //data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + //data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + //data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + //data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/MathTest.cs new file mode 100644 index 00000000..f803f792 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESExpression +{ + public class MathTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/OtherTest.cs new file mode 100644 index 00000000..f84ff2b4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/OtherTest.cs @@ -0,0 +1,165 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESExpression +{ + public class OtherTest + { + + ISelect select => g.kingbaseES.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).Limit(10).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs new file mode 100644 index 00000000..7e59d641 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs @@ -0,0 +1,726 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESExpression +{ + public class StringTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.kingbaseES.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/TimeSpanTest.cs new file mode 100644 index 00000000..c21162ff --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESExpression +{ + public class TimeSpanTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..0f5935f7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/BoolTest.cs new file mode 100644 index 00000000..76a27442 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..92efffe6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.kingbaseES; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/EnumTest.cs new file mode 100644 index 00000000..97e2fddc --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.kingbaseES; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.kingbaseES; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.kingbaseES; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.kingbaseES; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/ToStringTest.cs new file mode 100644 index 00000000..332eabf7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseESMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index bf0aa5e8..d6a151b4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -83,10 +83,9 @@ public class g .Build()); public static IFreeSql dameng => damemgLazy.Value; - //启动南大通用数据库 oninit -vy - static Lazy gbaseLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={GBase ODBC DRIVER (64-bit)};Server=192.168.164.10:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=1user;PWD=123456789") - //.UseConnectionFactory(FreeSql.DataType.OdbcDameng, () => new System.Data.Odbc.OdbcConnection("Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=1user;PWD=123456789")) + static Lazy kingbaseESLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.OdbcKingbaseES, "Driver={KingbaseES 8.2 ODBC Driver ANSI};Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=TEST") + //.UseConnectionFactory(FreeSql.DataType.OdbcKingbaseES, () => new System.Data.Odbc.OdbcConnection("Driver={KingbaseES 8.2 ODBC Driver ANSI};Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=TEST")) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) @@ -96,7 +95,7 @@ public class g cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 (cmd, traceLog) => Console.WriteLine(traceLog)) .Build()); - public static IFreeSql gbase => gbaseLazy.Value; + public static IFreeSql kingbaseES => kingbaseESLazy.Value; //启动神州通用数据库 /etc/init.d/oscardb_OSRDBd start diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs index cb793719..3617db5c 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -29,16 +29,16 @@ namespace FreeSql.Tests.PostgreSQL for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); } [Fact] @@ -48,10 +48,10 @@ namespace FreeSql.Tests.PostgreSQL for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); } [Fact] public void IgnoreColumns() @@ -60,10 +60,10 @@ namespace FreeSql.Tests.PostgreSQL for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); g.pgsql.Delete().Where("1=1").ExecuteAffrows(); var itemsIgnore = new List(); @@ -114,28 +114,28 @@ namespace FreeSql.Tests.PostgreSQL for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(@clicks_0, @title_0, @createtime_0), (@clicks_1, @title_1, @createtime_1), (@clicks_2, @title_2, @createtime_2), (@clicks_3, @title_3, @createtime_3), (@clicks_4, @title_4, @createtime_4), (@clicks_5, @title_5, @createtime_5), (@clicks_6, @title_6, @createtime_6), (@clicks_7, @title_7, @createtime_7), (@clicks_8, @title_8, @createtime_8), (@clicks_9, @title_9, @createtime_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES(@title_0), (@title_1), (@title_2), (@title_3), (@title_4), (@title_5), (@title_6), (@title_7), (@title_8), (@title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@clicks_0, @title_0), (@clicks_1, @title_1), (@clicks_2, @title_2), (@clicks_3, @title_3), (@clicks_4, @title_4), (@clicks_5, @title_5), (@clicks_6, @title_6), (@clicks_7, @title_7), (@clicks_8, @title_8), (@clicks_9, @title_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); - Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\") VALUES(@clicks_0), (@clicks_1), (@clicks_2), (@clicks_3), (@clicks_4), (@clicks_5), (@clicks_6), (@clicks_7), (@clicks_8), (@clicks_9)", sql); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); } } } diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 4b60ed38..2a194b94 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -34,6 +34,11 @@ namespace FreeSql /// /// 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 /// - Dameng + Dameng, + + /// + /// 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 + /// + OdbcKingbaseES } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5545a967..d1259f1c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -551,6 +551,11 @@ 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 + + + 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null @@ -2405,137 +2410,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3138,12 +3012,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3214,12 +3082,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3861,3 +3723,172 @@ +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 条件 + + + + diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 83bb76ff..5602f681 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -234,6 +234,11 @@ namespace FreeSql if (type == null) throwNotFind("FreeSql.Provider.Dameng.dll", "FreeSql.Dameng.DamengProvider<>"); break; + case DataType.OdbcKingbaseES: + type = Type.GetType("FreeSql.Odbc.KingbaseES.OdbcKingbaseESProvider`1,FreeSql.Provider.Odbc")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.Odbc.dll", "FreeSql.Odbc.KingbaseES.OdbcKingbaseESProvider<>"); + break; + default: throw new Exception("未指定 UseConnectionString 或者 UseConnectionFactory"); } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 9bbe5cea..e4b1a515 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1172,6 +1172,7 @@ namespace FreeSql.Internal.CommonProvider break; case DataType.OdbcDameng: case DataType.Dameng: + case DataType.OdbcKingbaseES: _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; break; } diff --git a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs index 2044411d..8d26e29f 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs @@ -82,7 +82,7 @@ namespace FreeSql.Dameng return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); - public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $":{name}"; public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs index 2002a9a9..c5c7aa2d 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -59,7 +59,7 @@ namespace FreeSql.MsAccess return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '[', ']', 2); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"@{name}"; public override string IsNull(string sql, object value) => $"iif(isnull({sql}), {value}, {sql})"; public override string StringConcat(string[] objs, Type[] types) { diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index fdce7b48..fe49cd80 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -87,7 +87,7 @@ namespace FreeSql.MySql return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '`', '`', 2); - public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"?{name}"; public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 3cf35322..085f2375 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -111,7 +111,7 @@ namespace FreeSql.MySql return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '`', '`', 2); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"@{name}"; public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index 7e619a96..50391fab 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -88,7 +88,7 @@ namespace FreeSql.Odbc.Dameng return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); - public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $":{name}"; public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index b9eb9dad..ebf3b993 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -58,7 +58,7 @@ namespace FreeSql.Odbc.Default return $"{nametrim.TrimStart(Adapter.QuoteSqlNameLeft).TrimEnd(Adapter.QuoteSqlNameRight).Replace($"{Adapter.QuoteSqlNameRight}.{Adapter.QuoteSqlNameLeft}", ".").Replace($".{Adapter.QuoteSqlNameLeft}", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, Adapter.QuoteSqlNameLeft, Adapter.QuoteSqlNameRight, 2); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"@{name}"; public override string IsNull(string sql, object value) => Adapter.IsNullSql(sql, value); public override string StringConcat(string[] objs, Type[] types) => Adapter.ConcatSql(objs, types); public override string Mod(string left, string right, Type leftType, Type rightType) => Adapter.Mod(left, right, leftType, rightType); diff --git a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs index 46764a4c..bc998ccf 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs @@ -54,4 +54,13 @@ /// public static string FormatOdbcDameng(this string that, params object[] args) => _odbcDamengAdo.Addslashes(that, args); static FreeSql.Odbc.Dameng.OdbcDamengAdo _odbcDamengAdo = new FreeSql.Odbc.Dameng.OdbcDamengAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatOdbcKingbaseES(this string that, params object[] args) => _odbcKingbaseESAdo.Addslashes(that, args); + static FreeSql.Odbc.KingbaseES.OdbcKingbaseESAdo _odbcKingbaseESAdo = new FreeSql.Odbc.KingbaseES.OdbcKingbaseESAdo(); } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs new file mode 100644 index 00000000..f75be644 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs @@ -0,0 +1,99 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.KingbaseES +{ + + class OdbcKingbaseESDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public OdbcKingbaseESDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + +#if net40 +#else + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + this.ClearData(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs new file mode 100644 index 00000000..908c8869 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs @@ -0,0 +1,216 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.KingbaseES +{ + + class OdbcKingbaseESInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public OdbcKingbaseESInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs new file mode 100644 index 00000000..9125b467 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs @@ -0,0 +1,57 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.Odbc.KingbaseES +{ + + class OdbcKingbaseESInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public OdbcKingbaseESInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else + { + var ocdu = new OdbcKingbaseESOnConflictDoUpdate(insert.InsertIdentity()); + ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); + if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + ocdu.DoNothing(); + sql = ocdu.ToSql(); + } + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs new file mode 100644 index 00000000..432020c1 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs @@ -0,0 +1,207 @@ +using FreeSql.Aop; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.KingbaseES +{ + public class OdbcKingbaseESOnConflictDoUpdate where T1 : class + { + internal OdbcKingbaseESInsert _pgsqlInsert; + internal OdbcKingbaseESUpdate _pgsqlUpdatePriv; + internal OdbcKingbaseESUpdate _pgsqlUpdate => _pgsqlUpdatePriv ?? + (_pgsqlUpdatePriv = new OdbcKingbaseESUpdate(_pgsqlInsert.InternalOrm, _pgsqlInsert.InternalCommonUtils, _pgsqlInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } + .NoneParameter().SetSource(_pgsqlInsert.InternalSource) as OdbcKingbaseESUpdate); + ColumnInfo[] _columns; + bool _doNothing; + + public OdbcKingbaseESOnConflictDoUpdate(IInsert insert, Expression> columns = null) + { + _pgsqlInsert = insert as OdbcKingbaseESInsert; + if (_pgsqlInsert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.Odbc/KingbaseES 特有的功能"); + + if (columns != null) + { + var colsList = new List(); + var cols = _pgsqlInsert.InternalCommonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name)) + colsList.Add(col); + _columns = colsList.ToArray(); + } + if (_columns == null || _columns.Any() == false) + _columns = _pgsqlInsert.InternalTable.Primarys; + if (_columns.Any() == false) throw new Exception("OnConflictDoUpdate 功能要求实体类必须设置 IsPrimary 属性"); + } + + protected void ClearData() + { + _pgsqlInsert.InternalClearData(); + _pgsqlUpdatePriv = null; + } + + public OdbcKingbaseESOnConflictDoUpdate IgnoreColumns(Expression> columns) + { + _pgsqlUpdate.IgnoreColumns(columns); + return this; + } + public OdbcKingbaseESOnConflictDoUpdate UpdateColumns(Expression> columns) + { + _pgsqlUpdate.UpdateColumns(columns); + return this; + } + public OdbcKingbaseESOnConflictDoUpdate IgnoreColumns(string[] columns) + { + _pgsqlUpdate.IgnoreColumns(columns); + return this; + } + public OdbcKingbaseESOnConflictDoUpdate UpdateColumns(string[] columns) + { + _pgsqlUpdate.UpdateColumns(columns); + return this; + } + + public OdbcKingbaseESOnConflictDoUpdate Set(Expression> column, TMember value) + { + _pgsqlUpdate.Set(column, value); + return this; + } + //由于表达式解析问题,ON CONFLICT("id") DO UPDATE SET 需要指定表别名,如 Set(a => a.Clicks + 1) 解析会失败 + //暂时不开放这个功能,如有需要使用 SetRaw("click = t.click + 1") 替代该操作 + //public OnConflictDoUpdate Set(Expression> exp) + //{ + // _pgsqlUpdate.Set(exp); + // return this; + //} + public OdbcKingbaseESOnConflictDoUpdate SetRaw(string sql) + { + _pgsqlUpdate.SetRaw(sql); + return this; + } + + public OdbcKingbaseESOnConflictDoUpdate DoNothing() + { + _doNothing = true; + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + sb.Append(_pgsqlInsert.ToSql()).Append("\r\nON CONFLICT("); + for (var a = 0; a < _columns.Length; a++) + { + if (a > 0) sb.Append(", "); + sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + } + if (_doNothing) + { + sb.Append(") DO NOTHING"); + } + else + { + sb.Append(") DO UPDATE SET\r\n"); + + var sbSetEmpty = _pgsqlUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _pgsqlUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_pgsqlUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _pgsqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _pgsqlUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _pgsqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true) + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); + } + else if (_pgsqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _pgsqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _pgsqlUpdate.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = EXCLUDED.").Append(field); + } + ++colidx; + } + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); + _pgsqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_pgsqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _pgsqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_pgsqlInsert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); + _pgsqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_pgsqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _pgsqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_pgsqlInsert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs new file mode 100644 index 00000000..33b21595 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs @@ -0,0 +1,174 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Odbc.KingbaseES +{ + + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_limit > 0) + sb.Append(" \r\nlimit ").Append(_limit); + if (_skip > 0) + sb.Append(" \r\noffset ").Append(_skip); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs new file mode 100644 index 00000000..6fe8f076 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -0,0 +1,164 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.KingbaseES +{ + + class OdbcKingbaseESUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public OdbcKingbaseESUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + internal string InternalTableAlias; + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + var pk = _table.Primarys.First(); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || '+' || "); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || '+' || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + ++pkidx; + } + sb.Append(")"); + } + + protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) + { + if (_noneParameter == false) return; + var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; + if (dbtype == null) return; + + sb.Append("::").Append(dbtype); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs new file mode 100644 index 00000000..0a3d947f --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs @@ -0,0 +1,77 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Threading; + +namespace FreeSql.Odbc.KingbaseES +{ + class OdbcKingbaseESAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public OdbcKingbaseESAdo() : base(DataType.OdbcKingbaseES, null, null) { } + public OdbcKingbaseESAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcKingbaseES, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.OdbcKingbaseES, connectionFactory); + return; + } + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new OdbcKingbaseESConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new OdbcKingbaseESConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + bool isdic; + if (param is bool || param is bool?) + return (bool)param ? "'t'" : "'f'"; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new OdbcCommand(); + } + + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + var rawPool = pool as OdbcKingbaseESConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESConnectionPool.cs new file mode 100644 index 00000000..a7d5f273 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESConnectionPool.cs @@ -0,0 +1,258 @@ +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Odbc.KingbaseES +{ + + class OdbcKingbaseESConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + internal string UserId { get; set; } + + public OdbcKingbaseESConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + this.UserId = OdbcKingbaseESConnectionPool.GetUserId(connectionString); + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + var policy = new OdbcKingbaseESConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + } + + public static string GetUserId(string connectionString) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + return userIdMatch.Groups[2].Value.Trim().ToUpper(); + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OdbcException) + { + + if (exception is System.IO.IOException) + { + + base.SetUnavailable(exception); + + } + else if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class OdbcKingbaseESConnectionPoolPolicy : IPolicy + { + + internal OdbcKingbaseESConnectionPool _pool; + public string Name { get; set; } = "KingbaseES OdbcConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OdbcConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1 from dual"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs new file mode 100644 index 00000000..f777d3ae --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs @@ -0,0 +1,459 @@ +using FreeSql.DataAnnotations; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.KingbaseES +{ + + class OdbcKingbaseESCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public OdbcKingbaseESCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(sbyte).FullName, CsToDb.New(OdbcType.TinyInt, "tinyint","tinyint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OdbcType.TinyInt, "tinyint", "tinyint", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OdbcType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OdbcType.Int, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OdbcType.Int, "int4", "int4", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OdbcType.BigInt, "int8", "int8", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(OdbcType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OdbcType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OdbcType.Int, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OdbcType.Int, "int4", "int4", false, true, null) }, + { typeof(uint).FullName, CsToDb.New(OdbcType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OdbcType.BigInt, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OdbcType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, + + { typeof(float).FullName, CsToDb.New(OdbcType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OdbcType.Real, "float4", "float4", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OdbcType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OdbcType.Double, "float8", "float8", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, + + { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + + { typeof(TimeSpan).FullName, CsToDb.New(OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OdbcType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp", false, true, null) }, + + { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, "bool","bool", null, true, null) }, + { typeof(Byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "bytea", "bytea", false, null, new byte[0]) }, + + { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "char", "char(36)", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(OdbcType.BigInt, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OdbcType.Int, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + var userId = (_orm.Ado.MasterPool as OdbcKingbaseESConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = OdbcKingbaseESConnectionPool.GetUserId(conn.Value.ConnectionString); + } + + var defaultSchema = "PUBLIC"; + var seqcols = new List>(); //序列:列,表,自增 + var seqnameDel = new List(); //要删除的序列+触发器 + + var sb = new StringBuilder(); + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { defaultSchema, tbname[0] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { defaultSchema, tboldname[0] }; + var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { defaultSchema, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + primaryKeyName = null; + } + } + //codefirst 不支持表名中带 . + + if (string.Compare(tbname[0], defaultSchema) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" SELECT 1 FROM information_schema.schemata WHERE schema_name={0}", tbname[0])) == null) //创建数据库 + sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from information_schema.tables where table_schema={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from information_schema.tables where table_schema={0} and table_name={1}", tboldname)) == null) + //模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_PK1"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + continue; + } + //如果新表,旧表在一个模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql($@" +select +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'N' then 0 else 1 end, +nvl((select 1 from user_sequences where upper(sequence_owner)={{0}} and upper(sequence_name)=upper({{2}}||'_'||{{1}}||'_seq_'||a.column_name) limit 1), 0), +b.comments +from all_tab_columns a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner={{0}} and a.table_name={{1}}", userId, (tboldname ?? tbname)[1], (tboldname ?? tbname)[0]); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds.Length != ds.Select(a => string.Concat(a[0])).Count()) throw new Exception("检查到多个模式下存在相同的表名,无法完成对比结构"); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var sqlType = GetKingbaseESSqlTypeFullName(a); + return new + { + column = string.Concat(a[0]), + sqlType, + is_nullable = string.Concat(a[6]) == "1", + is_identity = string.Concat(a[7]) == "1", + comment = string.Concat(a[8]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + istmpatler = true; + if (istmpatler && tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + if (istmpatler && Regex.IsMatch(tbcol.Attribute.DbType, @"\(\d+") == false && Regex.IsMatch(tbstructcol.sqlType, @"\(\d+") + && string.Compare(tbcol.Attribute.DbType, Regex.Replace(tbstructcol.sqlType, @"\([^\)]+\)", ""), StringComparison.CurrentCultureIgnoreCase) == 0) + istmpatler = false; + if (istmpatler) + break; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(tbcol.Attribute.IsNullable == true ? " DROP NOT NULL" : " SET NOT NULL").Append(";\r\n"); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + if (tbstructcol.is_identity) + seqnameDel.Add(Utils.GetCsName($"{tbname[1]}_seq_{tbstructcol.column}")); + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (tbcol.Attribute.IsIdentity) + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } + else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (isCommentChanged) + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")).Append(";\r\n"); + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(");\r\n"); + if (tbcol.Attribute.IsNullable == false) + { + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); + } + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")).Append(";\r\n"); + } + } + if (istmpatler == false) + { + var dsuksql = _commonUtils.FormatSql(@" +select +c.column_name, +a.index_name, +case when c.descend = 'DESC' then 1 else 0 end, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner +and a.table_name = c.table_name +and a.owner in ({0}) and a.table_name in ({1}) +and not exists(select 1 from all_constraints where index_name = a.index_name and constraint_type = 'P')", userId, (tboldname ?? tbname)[1]); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]).Trim('"'), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }).ToArray(); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", userId, tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", userId, tbname[1]))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(oldpk)).Append(";\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_PK2"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); + insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"nvl({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + sb.Append(insertvalue.Replace("'", "''")).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); + sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); + if (seqcol.Item3) + { + sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);\r\n"); + sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); + } + } + return sb.Length == 0 ? null : sb.ToString(); + } + + public override int ExecuteDDLStatements(string ddl) + { + if (string.IsNullOrEmpty(ddl)) return 0; + var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray(); + + if (scripts.Any() == false) return 0; + if (scripts.Length == 1) return base.ExecuteDDLStatements(ddl); + + var affrows = 0; + foreach (var script in scripts) + affrows += base.ExecuteDDLStatements(script); + return affrows; + } + + internal static string GetKingbaseESSqlTypeFullName(object[] row) + { + var a = row; + var sqlType = string.Concat(a[1]).ToUpper(); + var data_length = long.Parse(string.Concat(a[2])); + long.TryParse(string.Concat(a[3]), out var data_precision); + long.TryParse(string.Concat(a[4]), out var data_scale); + //var char_used = string.Concat(a[5]); + if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) + { + } + else if (sqlType.StartsWith("BLOB")) + { + } + else if (sqlType == "DOUBLE" || sqlType == "FLOAT") + { + } + else if (sqlType == "INT2" || sqlType == "INT4" || sqlType == "INT8") + { + } + else if (sqlType == "TINYINT") + { + } + else if (sqlType == "BOOL") + { + } + else if (sqlType == "FLOAT4" || sqlType == "FLOAT8") + { + } + else if (sqlType == "TIME" || sqlType == "TIMESTAMP") + { + } + else if (sqlType == "NUMERIC") + sqlType += $"({data_precision},{data_scale})"; + else if (data_precision > 0 && data_scale > 0) + sqlType += $"({data_precision},{data_scale})"; + else if (data_precision > 0) + sqlType += $"({data_precision})"; + else + sqlType += $"({data_length})"; + return sqlType; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs new file mode 100644 index 00000000..4a4c3f47 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs @@ -0,0 +1,120 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.KingbaseES +{ + class OdbcKingbaseESDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public OdbcKingbaseESDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + OdbcType GetSqlDbType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + var isarray = dbtype.EndsWith("[]"); + if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); + var ret = OdbcType.VarChar; + switch (dbtype.ToLower().TrimStart('_')) + { + case "tinyint": ret = OdbcType.TinyInt; break; + case "int2": ret = OdbcType.SmallInt; break; + case "int4": ret = OdbcType.Int; break; + case "int8": ret = OdbcType.BigInt; break; + case "numeric": ret = OdbcType.Numeric; break; + case "float4": ret = OdbcType.Real; break; + case "float8": ret = OdbcType.Double; break; + case "money": ret = OdbcType.Numeric; break; + + case "char": ret = column.MaxLength == 36 ? OdbcType.UniqueIdentifier : OdbcType.Char; break; + case "bpchar": ret = OdbcType.Char; break; + case "varchar": ret = OdbcType.VarChar; break; + case "text": ret = OdbcType.Text; break; + + case "timestamp": ret = OdbcType.Timestamp; break; + case "timestamptz": ret = OdbcType.Timestamp; break; + case "date": ret = OdbcType.Date; break; + case "time": ret = OdbcType.Time; break; + case "timetz": ret = OdbcType.Time; break; + case "interval": ret = OdbcType.Time; break; + + case "bool": ret = OdbcType.Bit; break; + case "blob": ret = OdbcType.VarBinary; break; + case "bytea": ret = OdbcType.VarBinary; break; + case "bit": ret = OdbcType.Bit; break; + case "varbit": ret = OdbcType.VarBinary; break; + + case "uuid": ret = OdbcType.UniqueIdentifier; break; + } + return ret; + } + + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(); + static OdbcKingbaseESDbFirst() + { + var defaultDbToCs = new Dictionary() { + { (int)OdbcType.TinyInt, new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.SmallInt, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(int), typeof(int?), "{0}.Value", "GetInt16") }, + { (int)OdbcType.Int, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(long), typeof(long?), "{0}.Value", "GetInt32") }, + { (int)OdbcType.BigInt, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)OdbcType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OdbcType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)OdbcType.Numeric, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { (int)OdbcType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OdbcType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)OdbcType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OdbcType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + + { (int)OdbcType.Bit, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)OdbcType.VarBinary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)OdbcType.UniqueIdentifier, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select schema_name from information_schema.schemata where schema_owner<>'SYSTEM'"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return new[] { "PUBLIC" }.Concat(ds.Select(a => a.FirstOrDefault()?.ToString())).ToList(); + } + + public List GetTablesByDatabase(params string[] database2) => throw new NotImplementedException(); + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs new file mode 100644 index 00000000..f3a2155d --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -0,0 +1,585 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Odbc.KingbaseES +{ + class OdbcKingbaseESExpression : CommonExpression + { + + public OdbcKingbaseESExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(operandExp)})::int2"; + case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.Decimal": return $"({getExp(operandExp)})::numeric"; + case "System.Double": return $"({getExp(operandExp)})::float8"; + case "System.Int16": return $"({getExp(operandExp)})::int2"; + case "System.Int32": return $"({getExp(operandExp)})::int4"; + case "System.Int64": return $"({getExp(operandExp)})::int8"; + case "System.SByte": return $"({getExp(operandExp)})::int2"; + case "System.Single": return $"({getExp(operandExp)})::float4"; + case "System.String": return $"({getExp(operandExp)})::varchar"; + case "System.UInt16": return $"({getExp(operandExp)})::int2"; + case "System.UInt32": return $"({getExp(operandExp)})::int4"; + case "System.UInt64": return $"({getExp(operandExp)})::int8"; + case "System.Guid": return $"({getExp(operandExp)})::uuid"; + } + } + break; + case ExpressionType.ArrayLength: + var arrOperExp = getExp((exp as UnaryExpression).Operand); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; + case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; + case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; + case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid"; + } + break; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + string left = null; + if (objType.FullName == typeof(Dictionary).FullName) + { + left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + var right = getExp(callExp.Arguments[argIndex]); + return $"({left} @> ({right}))"; + case "ContainsKey": return $"({left} ? {getExp(callExp.Arguments[argIndex])})"; + case "Concat": return $"({left} || {getExp(callExp.Arguments[argIndex])})"; + case "GetLength": + case "GetLongLength": + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + switch (callExp.Method.Name) + { + case "Any": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; + case "Contains": + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + //判断 in 或 array @> array + if (left.StartsWith("array[") || left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + args1 = $"array[{args1}]"; + if (objExp != null) + { + var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); + if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; + } + return $"({left} @> {args1})"; + case "Concat": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + var right2 = getExp(callExp.Arguments[argIndex]); + if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; + return $"({left} || {right2})"; + case "GetLength": + case "GetLongLength": + case "Length": + case "Count": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + break; + case ExpressionType.MemberAccess: + var memExp = exp as MemberExpression; + var memParentExp = memExp.Expression?.Type; + if (memParentExp?.FullName == "System.Byte[]") return null; + if (memParentExp != null) + { + if (memParentExp.IsArray == true) + { + var left = getExp(memExp.Expression); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + switch (memExp.Member.Name) + { + case "Length": + case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("array["); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append("]").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "current_date"; + case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; + case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"({left})::date"; + case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)"; + case "DayOfWeek": return $"extract(dow from ({left})::timestamp)"; + case "Day": return $"extract(day from ({left})::timestamp)"; + case "DayOfYear": return $"extract(doy from ({left})::timestamp)"; + case "Month": return $"extract(month from ({left})::timestamp)"; + case "Year": return $"extract(year from ({left})::timestamp)"; + case "Hour": return $"extract(hour from ({left})::timestamp)"; + case "Minute": return $"extract(minute from ({left})::timestamp)"; + case "Second": return $"extract(second from ({left})::timestamp)"; + case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)"; + case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)"; + case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)"; + case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)"; + case "Seconds": return $"(floor(({left})/1000000)::int8%60)"; + case "Ticks": return $"(({left})*10)"; + case "TotalDays": return $"(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left})/1000)"; + case "TotalMinutes": return $"(({left})/{(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left})/1000000)"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + var likeOpt = "LIKE"; + if (exp.Arguments.Count > 1) + { + if (exp.Arguments[1].Type == typeof(bool) || + exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": + if (exp.Arguments.Count > 1) return $"log({getExp(exp.Arguments[1])},{getExp(exp.Arguments[0])})"; + return $"log(2.7182818284590451,{getExp(exp.Arguments[0])})"; + case "Log10": return $"log({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)"; + case "DaysInMonth": return $"extract(day from ({getExp(exp.Arguments[0])} || '-' || {getExp(exp.Arguments[1])} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)"; + case "Equals": return $"(({getExp(exp.Arguments[0])})::timestamp = ({getExp(exp.Arguments[1])})::timestamp)"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; + + case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"(({left})::timestamp+((({args1})/1000)||' milliseconds')::interval)"; + case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; + case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; + case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; + case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)"; + case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)"; + case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)"; + case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; + case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; + case "System.TimeSpan": return $"(({left})::timestamp-((({args1})/1000)||' milliseconds')::interval)"; + } + break; + case "Equals": return $"({left} = ({args1})::timestamp)"; + case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; + case "ToString": + if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + } + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"({left})::varchar"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; + case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; + case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; + case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; + case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; + case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; + case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESProvider.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESProvider.cs new file mode 100644 index 00000000..883cb633 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESProvider.cs @@ -0,0 +1,60 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.Odbc.KingbaseES +{ + + public class OdbcKingbaseESProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new OdbcKingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new OdbcKingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new OdbcKingbaseESInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new OdbcKingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new OdbcKingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new OdbcKingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new OdbcKingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcKingbaseESInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public OdbcKingbaseESProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new OdbcKingbaseESUtils(this); + this.InternalCommonExpression = new OdbcKingbaseESExpression(this.InternalCommonUtils); + + this.Ado = new OdbcKingbaseESAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new OdbcKingbaseESDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new OdbcKingbaseESCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + + ~OdbcKingbaseESProvider() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs new file mode 100644 index 00000000..3cddc2e4 --- /dev/null +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs @@ -0,0 +1,161 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Odbc; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace FreeSql.Odbc.KingbaseES +{ + + class OdbcKingbaseESUtils : CommonUtils + { + public OdbcKingbaseESUtils(IFreeSql orm) : base(orm) + { + } + + static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) + { + var valueArr = value as Array; + var len = valueArr.GetLength(0); + var ret = Array.CreateInstance(arrayType, len); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); + } + return ret; + } + static Dictionary> dicGetParamterValue = new Dictionary> { + { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, + { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, + { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, + { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + }; + static object getParamterValue(Type type, object value, int level = 0) + { + if (type.FullName == "System.Byte[]") return value; + if (type.IsArray && level == 0) + { + var elementType = type.GetElementType(); + Type enumType = null; + if (elementType.IsEnum) enumType = elementType; + else if (elementType.IsNullableType()) + { + var genericTypesFirst = elementType.GetGenericArguments().First(); + if (genericTypesFirst.IsEnum) enumType = genericTypesFirst; + } + if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()); + return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; + } + if (type.IsNullableType()) type = type.GetGenericArguments().First(); + if (type.IsEnum) return (int)value; + if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); + return value; + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value != null) value = getParamterValue(type, value); + var ret = new OdbcParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + //} + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value != null) value = getParamterValue(type, value); + var ret = new OdbcParameter { ParameterName = $"@{name.ToUpper()}", Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OdbcType = (OdbcType)tp.Value; + //} + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbcKingbaseES(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); + public override string QuoteParamterName(string name) => $"@{name.ToUpper()}"; + public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "current_timestamp"; + public override string NowUtc => "(current_timestamp at time zone 'UTC')"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + value = getParamterValue(type, value); + var type2 = value.GetType(); + if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; + if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; + } + else if (value is Array) + { + var valueArr = value as Array; + var eleType = type2.GetElementType(); + var len = valueArr.GetLength(0); + var sb = new StringBuilder().Append("ARRAY["); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + if (a > 0) sb.Append(","); + sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + } + sb.Append("]"); + var dbinfo = _orm.CodeFirst.GetDbInfo(type); + if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype); + return sb.ToString(); + } + else if (dicGetParamterValue.ContainsKey(type2.FullName)) + { + value = string.Concat(value); + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 3cd1bb86..6ce28f10 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -58,7 +58,7 @@ namespace FreeSql.Odbc.MySql return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '`', '`', 2); - public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"?{name}"; public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index e692fac8..dddeda5f 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -88,7 +88,7 @@ namespace FreeSql.Odbc.Oracle return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); - public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $":{name}"; public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index f6aa1295..7a223e82 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -111,7 +111,7 @@ namespace FreeSql.Odbc.PostgreSQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"@{(name.ToLower())}"; public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index 118fcf69..cfe4abdd 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -63,7 +63,7 @@ namespace FreeSql.Odbc.SqlServer return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '[', ']', 3); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"@{name}"; public override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) { diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 868db830..90121043 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -87,7 +87,7 @@ namespace FreeSql.Oracle return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); - public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $":{name}"; public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index c32ee8db..cf1b6baf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -140,7 +140,7 @@ namespace FreeSql.PostgreSQL return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"@{name}"; public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 125b62e5..8814ae3e 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -75,7 +75,7 @@ namespace FreeSql.SqlServer return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '[', ']', 3); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"@{name}"; public override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) { diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 9f092837..616b01ef 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -87,7 +87,7 @@ namespace FreeSql.Sqlite return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; } public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); - public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string QuoteParamterName(string name) => $"@{name}"; public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; From 8934492b813cfcf9060eaac806285d86e1141a6b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 27 May 2020 06:44:13 +0800 Subject: [PATCH 0671/1029] =?UTF-8?q?update=20=E4=BA=BA=E5=A4=A7=E9=87=91?= =?UTF-8?q?=E4=BB=93=20descrption?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Repository/readme.md | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 317 +++++++++---------- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 3 +- FreeSql/Interface/ICodeFirst.cs | 2 +- readme.md | 2 +- 8 files changed, 154 insertions(+), 178 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 644bf350..0ddefede 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -5,7 +5,7 @@ 1.5.0 true ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access https://github.com/2881099/FreeSql/wiki/DbContext FreeSql ORM DbContext git diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3eb5cbef..7418ac57 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -4,7 +4,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.5.0 ncc;YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/Access, and read/write separation、and split table. + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository true diff --git a/FreeSql.Repository/readme.md b/FreeSql.Repository/readme.md index 1ba1f896..4c58c538 100644 --- a/FreeSql.Repository/readme.md +++ b/FreeSql.Repository/readme.md @@ -98,7 +98,7 @@ var logRepository = fsql.GetGuidRepository(null, oldname => $"{oldname}_{Da ## 兼容问题 -FreeSql 支持五种数据库,分别为 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦,虽然他们都为关系型数据库,但各自有着独特的技术亮点,有许多亮点值得我们使用; +FreeSql 支持多种数据库,分别为 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/MsAccess,虽然他们都为关系型数据库,但各自有着独特的技术亮点,有许多亮点值得我们使用; 比如 SqlServer 提供的 output inserted 特性,在表使用了自增或数据库定义了默认值的时候,使用它可以快速将 insert 的数据返回。PostgreSQL 也有相应的功能,如此方便却不是每个数据库都支持。 diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 47f36213..aeaae6e0 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -5,7 +5,7 @@ 1.5.0 true ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d1259f1c..06756040 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1366,7 +1366,8 @@ PostgreSQL: for update nowait Oracle: for update nowait Sqlite: 无效果 - 达梦: for update nowait + 达梦: for update nowait + 人大金仓: for update nowait noawait @@ -2410,6 +2411,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 }) + + + + + + 可自定义解析表达式 @@ -2677,7 +2809,7 @@ - 转大写同步结构,适用 Oracle/达梦 + 转大写同步结构,适用 Oracle/达梦/人大金仓 @@ -3012,6 +3144,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3082,6 +3220,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3723,172 +3867,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 条件 - - - - diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 7a5d6713..ef2602cb 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -284,7 +284,8 @@ namespace FreeSql /// PostgreSQL: for update nowait /// Oracle: for update nowait /// Sqlite: 无效果 - /// 达梦: for update nowait + /// 达梦: for update nowait + /// 人大金仓: for update nowait /// /// noawait /// diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index e0ee5e45..e316be66 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -17,7 +17,7 @@ namespace FreeSql /// bool IsSyncStructureToLower { get; set; } /// - /// 转大写同步结构,适用 Oracle/达梦 + /// 转大写同步结构,适用 Oracle/达梦/人大金仓 /// bool IsSyncStructureToUpper { get; set; } /// diff --git a/readme.md b/readme.md index d4bf0964..e997a53e 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 丰富的表达式函数,以及灵活的自定义解析; - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; - [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; -- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦数据库/Access; +- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access; ## 📚 Documentation From 815372cb7f380de3706f944cefa7bd27e27a4d41 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 27 May 2020 17:18:45 +0800 Subject: [PATCH 0672/1029] update orm_vs --- Examples/orm_vs/Program.cs | 522 ++++++++++++++++++------------------- 1 file changed, 261 insertions(+), 261 deletions(-) diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index e4fe2bc0..62c95808 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -18,8 +18,8 @@ namespace orm_vs class Program { static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") - //.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=20") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + .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=20") .UseAutoSyncStructure(false) .UseNoneCommandParameter(true) //.UseConfigEntityFromDbFirst(true) @@ -29,11 +29,10 @@ namespace orm_vs { get => new SqlSugarClient(new ConnectionConfig() { - //不欺负,让连接池100个最小 - ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", - DbType = DbType.SqlServer, - //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", - //DbType = DbType.MySql, + //ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + //DbType = DbType.SqlServer, + ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + DbType = DbType.MySql, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute }); @@ -44,8 +43,8 @@ namespace orm_vs public DbSet Songs { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); - //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); + //optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); + optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); } } @@ -54,219 +53,189 @@ namespace orm_vs var sb = new StringBuilder(); var time = new Stopwatch(); - //var t31 = fsql.Select().ToList(); - fsql.Select().First(); + #region ET test + ////var t31 = fsql.Select().ToList(); + //fsql.Select().First(); - time.Restart(); - var t3 = fsql.Select().ToList(); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); + //time.Restart(); + //var t3 = fsql.Select().ToList(); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); - time.Restart(); - var adoarr1 = fsql.Ado.ExecuteArray("select * from freesql_song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteArray Entity Counts: {adoarr1.Length}; ORM: FreeSql ExecuteArray*"); + //time.Restart(); + //var adoarr1 = fsql.Ado.ExecuteArray("select * from freesql_song"); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteArray Entity Counts: {adoarr1.Length}; ORM: FreeSql ExecuteArray*"); - time.Restart(); - var adolist1 = new List(); - fsql.Ado.ExecuteReader(dr => - { - var xim = new Song(); - dr.GetValue(0)?.GetType(); - dr.GetValue(1)?.GetType(); - dr.GetValue(2)?.GetType(); - dr.GetValue(3)?.GetType(); - dr.GetValue(4)?.GetType(); - adolist1.Add(xim); - }, "select * from freesql_song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader*"); + //time.Restart(); + //var adolist1 = new List(); + //fsql.Ado.ExecuteReader(dr => + //{ + // var xim = new Song(); + // dr.GetValue(0)?.GetType(); + // dr.GetValue(1)?.GetType(); + // dr.GetValue(2)?.GetType(); + // dr.GetValue(3)?.GetType(); + // dr.GetValue(4)?.GetType(); + // adolist1.Add(xim); + //}, "select * from freesql_song"); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader*"); - time.Restart(); - adolist1 = new List(); - fsql.Ado.ExecuteReader(dr => - { - var xim = new Song(); - var v1 = dr.GetValue(0); - var locvalue = (object)v1; - if (locvalue == null || locvalue == DBNull.Value) xim.Id = default; - else - { - if (locvalue is int iv) xim.Id = iv; - else - { - if (locvalue is string) - { + //time.Restart(); + //adolist1 = new List(); + //fsql.Ado.ExecuteReader(dr => + //{ + // var xim = new Song(); + // var v1 = dr.GetValue(0); + // var locvalue = (object)v1; + // if (locvalue == null || locvalue == DBNull.Value) xim.Id = default; + // else + // { + // if (locvalue is int iv) xim.Id = iv; + // else + // { + // if (locvalue is string) + // { - } - } - } - v1 = dr.GetValue(1); - locvalue = (object)v1; - if (locvalue == null || locvalue == DBNull.Value) xim.Create_time = default; - else - { - if (locvalue is DateTime dt) xim.Create_time = dt; - else - { - if (locvalue is string) - { + // } + // } + // } + // v1 = dr.GetValue(1); + // locvalue = (object)v1; + // if (locvalue == null || locvalue == DBNull.Value) xim.Create_time = default; + // else + // { + // if (locvalue is DateTime dt) xim.Create_time = dt; + // else + // { + // if (locvalue is string) + // { - } - } - } - v1 = dr.GetValue(2); - locvalue = (object)v1; - if (locvalue == null || locvalue == DBNull.Value) xim.Is_deleted = default; - else - { - if (locvalue is bool bl) xim.Is_deleted = bl; - else - { - if (locvalue is string) - { + // } + // } + // } + // v1 = dr.GetValue(2); + // locvalue = (object)v1; + // if (locvalue == null || locvalue == DBNull.Value) xim.Is_deleted = default; + // else + // { + // if (locvalue is bool bl) xim.Is_deleted = bl; + // else + // { + // if (locvalue is string) + // { - } - } - } - v1 = dr.GetValue(3); - locvalue = (object)v1; - if (locvalue == null || locvalue == DBNull.Value) xim.Title = default; - else - { - if (locvalue is string str) xim.Title = str; - else - { - if (locvalue is string) - { + // } + // } + // } + // v1 = dr.GetValue(3); + // locvalue = (object)v1; + // if (locvalue == null || locvalue == DBNull.Value) xim.Title = default; + // else + // { + // if (locvalue is string str) xim.Title = str; + // else + // { + // if (locvalue is string) + // { - } - } - } - v1 = dr.GetValue(4); - locvalue = (object)v1; - if (locvalue == null || locvalue == DBNull.Value) xim.Url = default; - else - { - if (locvalue is string str) xim.Url = str; - else - { - if (locvalue is string) - { + // } + // } + // } + // v1 = dr.GetValue(4); + // locvalue = (object)v1; + // if (locvalue == null || locvalue == DBNull.Value) xim.Url = default; + // else + // { + // if (locvalue is string str) xim.Url = str; + // else + // { + // if (locvalue is string) + // { - } - } - } - adolist1.Add(xim); - }, "select * from freesql_song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderObject Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderObject*"); - - //var type = typeof(Song); - //var myfuncParam1 = Expression.Parameter(typeof(object[]), "values"); - //var retExp = Expression.Variable(type, "ret"); - //var objExp = Expression.Variable(typeof(object), "obj"); - //var returnTarget = Expression.Label(type); - //var myfuncBody = Expression.Block( - // new[] { retExp, objExp }, - // Expression.Assign(retExp, type.InternalNewExpression()), - // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(0))), - // Utils.GetConvertExpression(type.GetProperty("Id").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Id")), Expression.Convert(objExp, type.GetProperty("Id").PropertyType)), - // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(1))), - // Utils.GetConvertExpression(type.GetProperty("Create_time").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Create_time")), Expression.Convert(objExp, type.GetProperty("Create_time").PropertyType)), - // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(2))), - // Utils.GetConvertExpression(type.GetProperty("Is_deleted").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Is_deleted")), Expression.Convert(objExp, type.GetProperty("Is_deleted").PropertyType)), - // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(3))), - // Utils.GetConvertExpression(type.GetProperty("Title").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Title")), Expression.Convert(objExp, type.GetProperty("Title").PropertyType)), - // Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(4))), - // Utils.GetConvertExpression(type.GetProperty("Url").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Url")), Expression.Convert(objExp, type.GetProperty("Url").PropertyType)), - // Expression.Return(returnTarget, retExp), - // Expression.Label(returnTarget, Expression.Default(type)) - //); - //var myfunc = Expression.Lambda>(myfuncBody, myfuncParam1).Compile(); - //time.Restart(); - //adolist1 = new List(); - //fsql.Ado.ExecuteReader(dr => - //{ - // var values = new object[dr.FieldCount]; - // dr.GetValues(values); - // var xim = myfunc(values); + // } + // } + // } // adolist1.Add(xim); //}, "select * from freesql_song"); //time.Stop(); - //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderMyFunc Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderMyFunc*"); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderObject Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderObject*"); + + ////var type = typeof(Song); + ////var myfuncParam1 = Expression.Parameter(typeof(object[]), "values"); + ////var retExp = Expression.Variable(type, "ret"); + ////var objExp = Expression.Variable(typeof(object), "obj"); + ////var returnTarget = Expression.Label(type); + ////var myfuncBody = Expression.Block( + //// new[] { retExp, objExp }, + //// Expression.Assign(retExp, type.InternalNewExpression()), + //// Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(0))), + //// Utils.GetConvertExpression(type.GetProperty("Id").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Id")), Expression.Convert(objExp, type.GetProperty("Id").PropertyType)), + //// Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(1))), + //// Utils.GetConvertExpression(type.GetProperty("Create_time").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Create_time")), Expression.Convert(objExp, type.GetProperty("Create_time").PropertyType)), + //// Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(2))), + //// Utils.GetConvertExpression(type.GetProperty("Is_deleted").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Is_deleted")), Expression.Convert(objExp, type.GetProperty("Is_deleted").PropertyType)), + //// Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(3))), + //// Utils.GetConvertExpression(type.GetProperty("Title").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Title")), Expression.Convert(objExp, type.GetProperty("Title").PropertyType)), + //// Expression.Assign(objExp, Expression.ArrayIndex(myfuncParam1, Expression.Constant(4))), + //// Utils.GetConvertExpression(type.GetProperty("Url").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Url")), Expression.Convert(objExp, type.GetProperty("Url").PropertyType)), + //// Expression.Return(returnTarget, retExp), + //// Expression.Label(returnTarget, Expression.Default(type)) + ////); + ////var myfunc = Expression.Lambda>(myfuncBody, myfuncParam1).Compile(); + ////time.Restart(); + ////adolist1 = new List(); + ////fsql.Ado.ExecuteReader(dr => + ////{ + //// var values = new object[dr.FieldCount]; + //// dr.GetValues(values); + //// var xim = myfunc(values); + //// adolist1.Add(xim); + ////}, "select * from freesql_song"); + ////time.Stop(); + ////sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderMyFunc Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderMyFunc*"); - //var methodDrgv = typeof(DbDataReader).GetMethod("GetValue"); - //var myfunc2Param1 = Expression.Parameter(typeof(DbDataReader), "dr"); - //var myfunc2Body = Expression.Block( - // new[] { retExp, objExp }, - // Expression.Assign(retExp, type.InternalNewExpression()), - // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(0))), - // Utils.GetConvertExpression(type.GetProperty("Id").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Id")), Expression.Convert(objExp, type.GetProperty("Id").PropertyType)), - // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(1))), - // Utils.GetConvertExpression(type.GetProperty("Create_time").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Create_time")), Expression.Convert(objExp, type.GetProperty("Create_time").PropertyType)), - // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(2))), - // Utils.GetConvertExpression(type.GetProperty("Is_deleted").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Is_deleted")), Expression.Convert(objExp, type.GetProperty("Is_deleted").PropertyType)), - // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(3))), - // Utils.GetConvertExpression(type.GetProperty("Title").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Title")), Expression.Convert(objExp, type.GetProperty("Title").PropertyType)), - // Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(4))), - // Utils.GetConvertExpression(type.GetProperty("Url").PropertyType, objExp), - // Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Url")), Expression.Convert(objExp, type.GetProperty("Url").PropertyType)), - // Expression.Return(returnTarget, retExp), - // Expression.Label(returnTarget, Expression.Default(type)) - //); - //var myfunc2 = Expression.Lambda>(myfunc2Body, myfunc2Param1).Compile(); - //time.Restart(); - //adolist1 = new List(); - //fsql.Ado.ExecuteReader(dr => - //{ - // var xim = myfunc2(dr); - // adolist1.Add(xim); - //}, "select * from freesql_song"); - //time.Stop(); - //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderMyFunc22 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderMyFunc22*"); - - - time.Restart(); - adolist1 = new List(); - fsql.Ado.ExecuteReader(dr => - { - var xim = new Song(); - dr.GetFieldValue(0); - dr.GetFieldValue(1); - dr.GetFieldValue(2); - dr.GetFieldValue(3); - dr.GetFieldValue(4); - adolist1.Add(xim); - }, "select * from freesql_song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader0000 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader0000*"); - - time.Restart(); - adolist1 = new List(); - fsql.Ado.ExecuteReader(dr => - { - var xim = new Song(); - Utils.GetDataReaderValue(typeof(int), dr.GetValue(0)); - Utils.GetDataReaderValue(typeof(DateTime), dr.GetValue(1)); - Utils.GetDataReaderValue(typeof(bool), dr.GetValue(2)); - Utils.GetDataReaderValue(typeof(string), dr.GetValue(3)); - Utils.GetDataReaderValue(typeof(string), dr.GetValue(4)); - adolist1.Add(xim); - }, "select * from freesql_song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader1111 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader1111*"); + ////var methodDrgv = typeof(DbDataReader).GetMethod("GetValue"); + ////var myfunc2Param1 = Expression.Parameter(typeof(DbDataReader), "dr"); + ////var myfunc2Body = Expression.Block( + //// new[] { retExp, objExp }, + //// Expression.Assign(retExp, type.InternalNewExpression()), + //// Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(0))), + //// Utils.GetConvertExpression(type.GetProperty("Id").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Id")), Expression.Convert(objExp, type.GetProperty("Id").PropertyType)), + //// Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(1))), + //// Utils.GetConvertExpression(type.GetProperty("Create_time").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Create_time")), Expression.Convert(objExp, type.GetProperty("Create_time").PropertyType)), + //// Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(2))), + //// Utils.GetConvertExpression(type.GetProperty("Is_deleted").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Is_deleted")), Expression.Convert(objExp, type.GetProperty("Is_deleted").PropertyType)), + //// Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(3))), + //// Utils.GetConvertExpression(type.GetProperty("Title").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Title")), Expression.Convert(objExp, type.GetProperty("Title").PropertyType)), + //// Expression.Assign(objExp, Expression.Call(myfunc2Param1, methodDrgv, Expression.Constant(4))), + //// Utils.GetConvertExpression(type.GetProperty("Url").PropertyType, objExp), + //// Expression.Assign(Expression.MakeMemberAccess(retExp, type.GetProperty("Url")), Expression.Convert(objExp, type.GetProperty("Url").PropertyType)), + //// Expression.Return(returnTarget, retExp), + //// Expression.Label(returnTarget, Expression.Default(type)) + ////); + ////var myfunc2 = Expression.Lambda>(myfunc2Body, myfunc2Param1).Compile(); + ////time.Restart(); + ////adolist1 = new List(); + ////fsql.Ado.ExecuteReader(dr => + ////{ + //// var xim = myfunc2(dr); + //// adolist1.Add(xim); + ////}, "select * from freesql_song"); + ////time.Stop(); + ////sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReaderMyFunc22 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReaderMyFunc22*"); //time.Restart(); @@ -274,34 +243,46 @@ namespace orm_vs //fsql.Ado.ExecuteReader(dr => //{ // var xim = new Song(); - // Utils.GetConvertValue(typeof(int), dr.GetValue(0)); - // Utils.GetConvertValue(typeof(DateTime), dr.GetValue(1)); - // Utils.GetConvertValue(typeof(bool), dr.GetValue(2)); - // Utils.GetConvertValue(typeof(string), dr.GetValue(3)); - // Utils.GetConvertValue(typeof(string), dr.GetValue(4)); + // dr.GetFieldValue(0); + // dr.GetFieldValue(1); + // dr.GetFieldValue(2); + // dr.GetFieldValue(3); + // dr.GetFieldValue(4); // adolist1.Add(xim); //}, "select * from freesql_song"); //time.Stop(); - //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader11112222 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader11112222*"); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader0000 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader0000*"); + + //time.Restart(); + //adolist1 = new List(); + //fsql.Ado.ExecuteReader(dr => + //{ + // var xim = new Song(); + // Utils.GetDataReaderValue(typeof(int), dr.GetValue(0)); + // Utils.GetDataReaderValue(typeof(DateTime), dr.GetValue(1)); + // Utils.GetDataReaderValue(typeof(bool), dr.GetValue(2)); + // Utils.GetDataReaderValue(typeof(string), dr.GetValue(3)); + // Utils.GetDataReaderValue(typeof(string), dr.GetValue(4)); + // adolist1.Add(xim); + //}, "select * from freesql_song"); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader1111 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader1111*"); - time.Restart(); - adolist1 = new List(); - fsql.Ado.ExecuteReader(dr => - { - var values = new object[dr.FieldCount]; - dr.GetValues(values); - - var xim = new Song(); - xim.Id = (int)Utils.GetDataReaderValue(typeof(int), values[0]); - xim.Create_time = (DateTime)Utils.GetDataReaderValue(typeof(DateTime), values[1]); - xim.Is_deleted = (bool)Utils.GetDataReaderValue(typeof(bool), values[2]); - xim.Title = (string)Utils.GetDataReaderValue(typeof(string), values[3]); - xim.Url = (string)Utils.GetDataReaderValue(typeof(string), values[4]); - adolist1.Add(xim); - }, "select * from freesql_song"); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader1111 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader1111*"); + ////time.Restart(); + ////adolist1 = new List(); + ////fsql.Ado.ExecuteReader(dr => + ////{ + //// var xim = new Song(); + //// Utils.GetConvertValue(typeof(int), dr.GetValue(0)); + //// Utils.GetConvertValue(typeof(DateTime), dr.GetValue(1)); + //// Utils.GetConvertValue(typeof(bool), dr.GetValue(2)); + //// Utils.GetConvertValue(typeof(string), dr.GetValue(3)); + //// Utils.GetConvertValue(typeof(string), dr.GetValue(4)); + //// adolist1.Add(xim); + ////}, "select * from freesql_song"); + ////time.Stop(); + ////sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader11112222 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader11112222*"); //time.Restart(); @@ -312,35 +293,54 @@ namespace orm_vs // dr.GetValues(values); // var xim = new Song(); - // xim.Id = (int)Utils.GetConvertValue(typeof(int), values[0]); - // xim.Create_time = (DateTime)Utils.GetConvertValue(typeof(DateTime), values[1]); - // xim.Is_deleted = (bool)Utils.GetConvertValue(typeof(bool), values[2]); - // xim.Title = (string)Utils.GetConvertValue(typeof(string), values[3]); - // xim.Url = (string)Utils.GetConvertValue(typeof(string), values[4]); + // xim.Id = (int)Utils.GetDataReaderValue(typeof(int), values[0]); + // xim.Create_time = (DateTime)Utils.GetDataReaderValue(typeof(DateTime), values[1]); + // xim.Is_deleted = (bool)Utils.GetDataReaderValue(typeof(bool), values[2]); + // xim.Title = (string)Utils.GetDataReaderValue(typeof(string), values[3]); + // xim.Url = (string)Utils.GetDataReaderValue(typeof(string), values[4]); // adolist1.Add(xim); //}, "select * from freesql_song"); //time.Stop(); - //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader11112222 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader11112222*"); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader1111 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader1111*"); - time.Restart(); - List dplist1 = null; - using (var conn = fsql.Ado.MasterPool.Get()) - { - dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song").ToList(); - } - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); + ////time.Restart(); + ////adolist1 = new List(); + ////fsql.Ado.ExecuteReader(dr => + ////{ + //// var values = new object[dr.FieldCount]; + //// dr.GetValues(values); - time.Restart(); - t3 = fsql.Select().ToList(); - time.Stop(); - sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); + //// var xim = new Song(); + //// xim.Id = (int)Utils.GetConvertValue(typeof(int), values[0]); + //// xim.Create_time = (DateTime)Utils.GetConvertValue(typeof(DateTime), values[1]); + //// xim.Is_deleted = (bool)Utils.GetConvertValue(typeof(bool), values[2]); + //// xim.Title = (string)Utils.GetConvertValue(typeof(string), values[3]); + //// xim.Url = (string)Utils.GetConvertValue(typeof(string), values[4]); + //// adolist1.Add(xim); + ////}, "select * from freesql_song"); + ////time.Stop(); + ////sb.AppendLine($"Elapsed: {time.Elapsed}; ExecuteReader11112222 Entity Counts: {adolist1.Count}; ORM: FreeSql ExecuteReader11112222*"); - Console.WriteLine(sb.ToString()); - Console.ReadKey(); - return; + //time.Restart(); + //List dplist1 = null; + //using (var conn = fsql.Ado.MasterPool.Get()) + //{ + // dplist1 = Dapper.SqlMapper.Query(conn.Value, "select * from freesql_song").ToList(); + //} + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper"); + + //time.Restart(); + //t3 = fsql.Select().ToList(); + //time.Stop(); + //sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*"); + + //Console.WriteLine(sb.ToString()); + //Console.ReadKey(); + + #endregion var testlist1 = fsql.Select().OrderBy(a => a.Id).ToList(); var testlist2 = new List(); @@ -353,20 +353,20 @@ namespace orm_vs //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements - sugar.Aop.OnLogExecuted = (s, e) => - { - Trace.WriteLine(s); - }; + //sugar.Aop.OnLogExecuted = (s, e) => + //{ + // Trace.WriteLine(s); + //}; //测试前清空数据 fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); fsql.Ado.ExecuteNonQuery("delete from efcore_song"); Console.WriteLine("插入性能:"); - Insert(sb, 1000, 1); + Insert(sb, 100, 1); Console.Write(sb.ToString()); sb.Clear(); - Insert(sb, 1000, 10); + Insert(sb, 100, 10); Console.Write(sb.ToString()); sb.Clear(); @@ -384,10 +384,10 @@ namespace orm_vs sb.Clear(); Console.WriteLine("查询性能:"); - Select(sb, 1000, 1); + Select(sb, 100, 1); Console.Write(sb.ToString()); sb.Clear(); - Select(sb, 1000, 10); + Select(sb, 100, 10); Console.Write(sb.ToString()); sb.Clear(); @@ -405,10 +405,10 @@ namespace orm_vs sb.Clear(); Console.WriteLine("更新:"); - Update(sb, 1000, 1); + Update(sb, 100, 1); Console.Write(sb.ToString()); sb.Clear(); - Update(sb, 1000, 10); + Update(sb, 100, 10); Console.Write(sb.ToString()); sb.Clear(); From 8331f43252ce471830a64f9079db3ba6b49b6925 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 28 May 2020 02:05:57 +0800 Subject: [PATCH 0673/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Gene?= =?UTF-8?q?rator=20=E4=BA=BA=E5=A4=A7=E9=87=91=E4=BB=93=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=B1=BB=E7=94=9F=E6=88=90=E5=99=A8=EF=BC=9B#325?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 11 +- .../FreeSql.Generator.csproj | 1 + FreeSql.DbContext/FreeSql.DbContext.xml | 16 - .../FreeSql.Tests.Provider.Odbc.csproj | 5 + .../FreeSql.Tests.Provider.Odbc.xml | 103 +++++ .../KingbaseES/KingbaseESDbFirstTest.cs | 5 +- .../OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs | 1 - .../KingbaseES/OdbcKingbaseESCodeFirst.cs | 270 +++++------- .../KingbaseES/OdbcKingbaseESDbFirst.cs | 388 +++++++++++++++++- .../KingbaseES/OdbcKingbaseESUtils.cs | 2 +- 10 files changed, 608 insertions(+), 194 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index cf65031c..040f374f 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -109,7 +109,10 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -DB ""{10},Data Source=document.db"" -DB ""{11},server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user;poolsize=2"" - {11} 是国产达梦数据库 + {11} 达梦数据库 + + -DB ""{12},Driver={KingbaseES 8.2 ODBC Driver ANSI};Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=数据库"" + {12} 人大金仓数据库 -Filter Table+View+StoreProcedure 默认生成:表+视图+存储过程 @@ -120,7 +123,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -FileName 文件名,默认:{name}.cs -Output 保存路径,默认为当前 shell 所在目录 - {12} + {13} ", Color.SlateGray, new Colorful.Formatter("使用 FreeSql 快速生成数据库的实体类", Color.SlateGray), @@ -135,6 +138,7 @@ new Colorful.Formatter("PostgreSQL", Color.Yellow), new Colorful.Formatter("Oracle", Color.Yellow), new Colorful.Formatter("Sqlite", Color.Yellow), new Colorful.Formatter("Dameng", Color.Yellow), +new Colorful.Formatter("OdbcKingbaseES", Color.Yellow), new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新所有实体类", Color.ForestGreen) ); wait.Set(); @@ -175,7 +179,8 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 case "oracle": ArgsDbType = DataType.Oracle; break; case "sqlite": ArgsDbType = DataType.Sqlite; break; case "dameng": ArgsDbType = DataType.Dameng; break; - default: throw new ArgumentException($"-DB 参数错误,不支持的类型:{dbargs[0]}"); + case "odbckingbasees": ArgsDbType = DataType.OdbcKingbaseES; break; + default: throw new ArgumentException($"-DB 参数错误,不支持的类型:\"{dbargs[0]}\""); } ArgsConnectionString = dbargs[1].Trim(); a++; diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d4318157..0f6294e3 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -31,6 +31,7 @@ + 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.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj index 3ece19a4..6aded025 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj @@ -6,6 +6,11 @@ false + + FreeSql.Tests.Provider.Odbc.xml + 3 + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml new file mode 100644 index 00000000..95f041b4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml @@ -0,0 +1,103 @@ + + + + FreeSql.Tests.Provider.Odbc + + + + + 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 类型 + + + + + 内容简介 + + + + + 缩略图 + + + + + 点击量 + + + + + + + + + + + + + + + + + + + + + + + + + 测试中文重命名id + + + + + 姓名 + + + + + 试卷表 + + + + + 考核计划ID + + + + + 总分 + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs index 39adb728..eb3dc40b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs @@ -9,16 +9,13 @@ namespace FreeSql.Tests.Odbc.KingbaseES [Fact] public void GetDatabases() { - var t1 = g.kingbaseES.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - - //var t2 = g.kingbaseES.DbFirst.GetTablesByDatabase(); + var t2 = g.kingbaseES.DbFirst.GetTablesByDatabase(); //var tb = g.kingbaseES.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs index 0a3d947f..b647490f 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs @@ -39,7 +39,6 @@ namespace FreeSql.Odbc.KingbaseES if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) param = Utils.GetDataReaderValue(mapType, param); - bool isdic; if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; else if (param is string || param is char) diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs index f777d3ae..efde626e 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs @@ -42,7 +42,7 @@ namespace FreeSql.Odbc.KingbaseES { typeof(bool).FullName, CsToDb.New(OdbcType.Bit, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OdbcType.Bit, "bool","bool", null, true, null) }, { typeof(Byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "bytea", "bytea", false, null, new byte[0]) }, - { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "char", "char(36)", false, true, null) }, + { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "uuid", "uuid", false, true, null) }, }; public override DbInfoResult GetDbInfo(Type type) @@ -75,18 +75,9 @@ namespace FreeSql.Odbc.KingbaseES protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { - var userId = (_orm.Ado.MasterPool as OdbcKingbaseESConnectionPool)?.UserId; - if (string.IsNullOrEmpty(userId)) - using (var conn = _orm.Ado.MasterPool.Get()) - { - userId = OdbcKingbaseESConnectionPool.GetUserId(conn.Value.ConnectionString); - } - - var defaultSchema = "PUBLIC"; - var seqcols = new List>(); //序列:列,表,自增 - var seqnameDel = new List(); //要删除的序列+触发器 - var sb = new StringBuilder(); + var seqcols = new List>(); //序列 + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -94,42 +85,40 @@ namespace FreeSql.Odbc.KingbaseES if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); var tbname = _commonUtils.SplitTableName(tb.DbName); - if (tbname?.Length == 1) tbname = new[] { defaultSchema, tbname[0] }; + if (tbname?.Length == 1) tbname = new[] { "PUBLIC", tbname[0] }; var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { defaultSchema, tboldname[0] }; - var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + if (tboldname?.Length == 1) tboldname = new[] { "PUBLIC", tboldname[0] }; if (string.IsNullOrEmpty(obj.tableName) == false) { var tbtmpname = _commonUtils.SplitTableName(obj.tableName); - if (tbtmpname?.Length == 1) tbtmpname = new[] { defaultSchema, tbtmpname[0] }; + if (tbtmpname?.Length == 1) tbtmpname = new[] { "PUBLIC", tbtmpname[0] }; if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) { tbname = tbtmpname; tboldname = null; - primaryKeyName = null; } } - //codefirst 不支持表名中带 . + //codefirst 不支持表名、模式名、数据库名中带 . - if (string.Compare(tbname[0], defaultSchema) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" SELECT 1 FROM information_schema.schemata WHERE schema_name={0}", tbname[0])) == null) //创建数据库 + if (string.Compare(tbname[0], "PUBLIC", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys_namespace where nspname={0}", tbname[0])) == null) //创建模式 sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); var sbalter = new StringBuilder(); var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from information_schema.tables where table_schema={0} and table_name={1}", tbname)) == null) + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from sys_tables a inner join sys_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tbname)) == null) { //表不存在 if (tboldname != null) { - if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from information_schema.tables where table_schema={0} and table_name={1}", tboldname)) == null) - //模式或表不存在 + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from sys_tables a inner join sys_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tboldname)) == null) + //旧表不存在 tboldname = null; } if (tboldname == null) { //创建表 var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); - sb.Append("CREATE TABLE ").Append(createTableName).Append(" ( "); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); @@ -137,13 +126,13 @@ namespace FreeSql.Odbc.KingbaseES } if (tb.Primarys.Any()) { - var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_PK1"; + var pkname = $"{tbname[0]}_{tbname[1]}_PKEY"; sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n);\r\n"); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { @@ -168,7 +157,7 @@ namespace FreeSql.Odbc.KingbaseES sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); continue; } - //如果新表,旧表在一个模式下,直接修改表名 + //如果新表,旧表在一个数据库和模式下,直接修改表名 if (string.Compare(tbname[0], tboldname[0], true) == 0) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); else @@ -181,32 +170,53 @@ namespace FreeSql.Odbc.KingbaseES tboldname = null; //如果新表已经存在,不走改表名逻辑 //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = _commonUtils.FormatSql($@" -select -a.column_name, -a.data_type, -a.data_length, -a.data_precision, -a.data_scale, -a.char_used, -case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where upper(sequence_owner)={{0}} and upper(sequence_name)=upper({{2}}||'_'||{{1}}||'_seq_'||a.column_name) limit 1), 0), -b.comments -from all_tab_columns a -left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner={{0}} and a.table_name={{1}}", userId, (tboldname ?? tbname)[1], (tboldname ?? tbname)[0]); + var sql = _commonUtils.FormatSql(@" +select +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem > 0 and t.typinput::varchar = 'ARRAY_IN' then t2.typname else t.typname end, +case when a.attnotnull then '0' else '1' end as is_nullable, +--e.adsrc, +(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid limit 1) is_identity, +a.attndims, +d.description as comment +from sys_class c +inner join sys_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join sys_type t on t.oid = a.atttypid +left join sys_type t2 on t2.oid = t.typelem +left join sys_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join sys_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join sys_namespace ns on ns.oid = c.relnamespace +inner join sys_namespace ns2 on ns2.oid = t.typnamespace +where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds.Length != ds.Select(a => string.Concat(a[0])).Count()) throw new Exception("检查到多个模式下存在相同的表名,无法完成对比结构"); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { - var sqlType = GetKingbaseESSqlTypeFullName(a); + var attndims = int.Parse(string.Concat(a[6])); + var type = string.Concat(a[1]); + var sqlType = string.Concat(a[3]); + var max_length = long.Parse(string.Concat(a[2])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); return new { column = string.Concat(a[0]), - sqlType, - is_nullable = string.Concat(a[6]) == "1", - is_identity = string.Concat(a[7]) == "1", - comment = string.Concat(a[8]) + sqlType = string.Concat(sqlType), + max_length = long.Parse(string.Concat(a[2])), + is_nullable = string.Concat(a[4]) == "1", + is_identity = string.Concat(a[5]).StartsWith(@"NEXTVAL('") && string.Concat(a[5]).EndsWith(@"'::REGCLASS)"), + attndims, + comment = string.Concat(a[7]) }; }, StringComparer.CurrentCultureIgnoreCase); @@ -214,71 +224,51 @@ where a.owner={{0}} and a.table_name={{1}}", userId, (tboldname ?? tbname)[1], ( { foreach (var tbcol in tb.ColumnsByPosition) { - var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) - { - istmpatler = true; - if (istmpatler && tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) - && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) - istmpatler = false; - if (istmpatler && Regex.IsMatch(tbcol.Attribute.DbType, @"\(\d+") == false && Regex.IsMatch(tbstructcol.sqlType, @"\(\d+") - && string.Compare(tbcol.Attribute.DbType, Regex.Replace(tbstructcol.sqlType, @"\([^\)]+\)", ""), StringComparison.CurrentCultureIgnoreCase) == 0) - istmpatler = false; - if (istmpatler) - break; - } + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { - if (tbcol.Attribute.IsNullable == false) - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(tbcol.Attribute.IsNullable == true ? " DROP NOT NULL" : " SET NOT NULL").Append(";\r\n"); + if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } } + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) - { - if (tbstructcol.is_identity) - seqnameDel.Add(Utils.GetCsName($"{tbname[1]}_seq_{tbstructcol.column}")); //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); - if (tbcol.Attribute.IsIdentity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - } - else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) - sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")).Append(";\r\n"); + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); continue; } //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(");\r\n"); - if (tbcol.Attribute.IsNullable == false) - { - sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - } + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); + if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); - if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")).Append(";\r\n"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } - } - if (istmpatler == false) - { var dsuksql = _commonUtils.FormatSql(@" select -c.column_name, -a.index_name, -case when c.descend = 'DESC' then 1 else 0 end, -case when a.uniqueness = 'UNIQUE' then 1 else 0 end -from all_indexes a, -all_ind_columns c -where a.index_name = c.index_name -and a.table_owner = c.table_owner -and a.table_name = c.table_name -and a.owner in ({0}) and a.table_name in ({1}) -and not exists(select 1 from all_constraints where index_name = a.index_name and constraint_type = 'P')", userId, (tboldname ?? tbname)[1]); - var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]).Trim('"'), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }).ToArray(); +c.attname, +b.relname, +case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +case when indisunique = 't' then 1 else 0 end IsUnique +from sys_index a +inner join sys_class b on b.oid = a.indexrelid +inner join sys_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_class d on d.oid = a.indrelid +where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; @@ -301,22 +291,32 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and } if (istmpatler == false) { - var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", userId, tbname[1]))); + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select +d.description +from sys_class a +inner join sys_namespace b on b.oid = a.relnamespace +left join sys_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('SYS_CATALOG', 'INFORMATION_SCHEMA', 'TOPOLOGY', 'SYSAUDIT', 'SYSLOGICAL', 'SYS_TEMP_1', 'SYS_TOAST', 'SYS_TOAST_TEMP_1', 'XLOG_RECORD_READ') and a.relkind in ('r') and b.nspname = {0} and a.relname = {1} +and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS')", tbname[0], tbname[1]))); if (dbcomment != (tb.Comment ?? "")) sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); sb.Append(sbalter); continue; } - var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", userId, tbname[1]))?.ToString(); + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select sys_constraint.conname as pk_name from sys_constraint +inner join sys_class on sys_constraint.conrelid = sys_class.oid +inner join sys_namespace on sys_namespace.oid = sys_class.relnamespace +where sys_namespace.nspname={0} and sys_class.relname={1} and sys_constraint.contype='p' +", tbname))?.ToString(); if (string.IsNullOrEmpty(oldpk) == false) - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(oldpk)).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); //创建临时表 - sb.Append("CREATE TABLE ").Append(tmptablename).Append(" ( "); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); @@ -324,13 +324,13 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and } if (tb.Primarys.Any()) { - var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_PK2"; + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n);\r\n"); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); //备注 foreach (var tbcol in tb.ColumnsByPosition) { @@ -352,20 +352,17 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and { insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) - { - var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); - insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; - } + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) - insertvalue = $"nvl({insertvalue},{tbcol.DbDefaultValue})"; + insertvalue = $"coalesce({insertvalue},{tbcol.DbDefaultValue})"; } else if (tbcol.Attribute.IsNullable == false) insertvalue = tbcol.DbDefaultValue; - sb.Append(insertvalue.Replace("'", "''")).Append(", "); + sb.Append(insertvalue).Append(", "); } sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { @@ -384,7 +381,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_seq").ToUpper(); ; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); @@ -392,68 +389,11 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and if (seqcol.Item3) { sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); - sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);\r\n"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT NEXTVAL('").Append(seqname).Append("'::REGCLASS);\r\n"); sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); } } return sb.Length == 0 ? null : sb.ToString(); } - - public override int ExecuteDDLStatements(string ddl) - { - if (string.IsNullOrEmpty(ddl)) return 0; - var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray(); - - if (scripts.Any() == false) return 0; - if (scripts.Length == 1) return base.ExecuteDDLStatements(ddl); - - var affrows = 0; - foreach (var script in scripts) - affrows += base.ExecuteDDLStatements(script); - return affrows; - } - - internal static string GetKingbaseESSqlTypeFullName(object[] row) - { - var a = row; - var sqlType = string.Concat(a[1]).ToUpper(); - var data_length = long.Parse(string.Concat(a[2])); - long.TryParse(string.Concat(a[3]), out var data_precision); - long.TryParse(string.Concat(a[4]), out var data_scale); - //var char_used = string.Concat(a[5]); - if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) - { - } - else if (sqlType.StartsWith("BLOB")) - { - } - else if (sqlType == "DOUBLE" || sqlType == "FLOAT") - { - } - else if (sqlType == "INT2" || sqlType == "INT4" || sqlType == "INT8") - { - } - else if (sqlType == "TINYINT") - { - } - else if (sqlType == "BOOL") - { - } - else if (sqlType == "FLOAT4" || sqlType == "FLOAT8") - { - } - else if (sqlType == "TIME" || sqlType == "TIMESTAMP") - { - } - else if (sqlType == "NUMERIC") - sqlType += $"({data_precision},{data_scale})"; - else if (data_precision > 0 && data_scale > 0) - sqlType += $"({data_precision},{data_scale})"; - else if (data_precision > 0) - sqlType += $"({data_precision})"; - else - sqlType += $"({data_length})"; - return sqlType; - } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs index 4a4c3f47..41c69855 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs @@ -105,16 +105,396 @@ namespace FreeSql.Odbc.KingbaseES public List GetDatabases() { - var sql = @" select schema_name from information_schema.schemata where schema_owner<>'SYSTEM'"; + var sql = @" select datname from sys_database where datname not in ('TEMPLATE1', 'TEMPLATE0', 'TEMPLATE2')"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - return new[] { "PUBLIC" }.Concat(ds.Select(a => a.FirstOrDefault()?.ToString())).ToList(); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } - public List GetTablesByDatabase(params string[] database2) => throw new NotImplementedException(); + public List GetTablesByDatabase(params string[] database) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + var tables = new List(); + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = $@" +select +b.nspname || '.' || a.tablename, +a.schemaname, +a.tablename , +d.description, +'TABLE' +from sys_tables a +inner join sys_namespace b on b.nspname = a.schemaname +inner join sys_class c on c.relnamespace = b.oid and c.relname = a.tablename +left join sys_description d on d.objoid = c.oid and objsubid = 0 +where a.schemaname not in ('SYS_CATALOG', 'INFORMATION_SCHEMA', 'TOPOLOGY', 'SYSAUDIT', 'SYSLOGICAL', 'SYS_TEMP_1', 'SYS_TOAST', 'SYS_TOAST_TEMP_1', 'XLOG_RECORD_READ') +and b.nspname || '.' || a.tablename not in ('PUBLIC.SPATIAL_REF_SYS') + +union all + +select +b.nspname || '.' || a.relname, +b.nspname, +a.relname, +d.description, +'VIEW' +from sys_class a +inner join sys_namespace b on b.oid = a.relnamespace +left join sys_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('SYS_CATALOG', 'INFORMATION_SCHEMA', 'TOPOLOGY', 'SYSAUDIT', 'SYSLOGICAL', 'SYS_TEMP_1', 'SYS_TOAST', 'SYS_TOAST_TEMP_1', 'XLOG_RECORD_READ') and a.relkind in ('m','v') +and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS') +"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = $@" +select +ns.nspname || '.' || c.relname as id, +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem = 0 then t.typname else t2.typname end, +case when a.attnotnull then 0 else 1 end as is_nullable, +--e.adsrc as is_identity, pg12以下 +(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid limit 1) is_identity, +d.description as comment, +a.attndims, +case when t.typelem = 0 then t.typtype else t2.typtype end, +ns2.nspname, +a.attnum +from sys_class c +inner join sys_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join sys_type t on t.oid = a.atttypid +left join sys_type t2 on t2.oid = t.typelem +left join sys_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join sys_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join sys_namespace ns on ns.oid = c.relnamespace +inner join sys_namespace ns2 on ns2.oid = t.typnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")}"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var position = 0; + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var type = string.Concat(row[2]); + var max_length = int.Parse(string.Concat(row[3])); + var sqlType = string.Concat(row[4]); + var is_nullable = string.Concat(row[5]) == "1"; + var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && string.Concat(row[6]).EndsWith(@"'::REGCLASS)"); + var comment = string.Concat(row[7]); + var defaultValue = string.Concat(row[6]); + int attndims = int.Parse(string.Concat(row[8])); + string typtype = string.Concat(row[9]); + string owner = string.Concat(row[10]); + int attnum = int.Parse(string.Concat(row[11])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (max_length <= 0) max_length = -1; + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + if (max_length > 0) + { + switch (sqlType.ToLower()) + { + //case "numeric": sqlType += $"({max_length})"; break; + case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; + } + } + + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Coment = comment, + DefaultValue = defaultValue, + Position = ++position + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } + + sql = $@" +select +ns.nspname || '.' || d.relname as table_id, +c.attname, +b.relname as index_id, +case when a.indisunique then 1 else 0 end IsUnique, +case when a.indisprimary then 1 else 0 end IsPrimary, +case when a.indisclustered then 0 else 1 end IsClustered, +case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +a.indkey::text, +c.attnum +from sys_index a +inner join sys_class b on b.oid = a.indexrelid +inner join sys_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_class d on d.oid = a.indrelid +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var index_id = string.Concat(row[2]); + var is_unique = string.Concat(row[3]) == "1"; + var is_primary_key = string.Concat(row[4]) == "1"; + var is_clustered = string.Concat(row[5]) == "1"; + var is_desc = string.Concat(row[6]) == "1"; + var inkey = string.Concat(row[7]).Split(' '); + var attnum = int.Parse(string.Concat(row[8])); + attnum = int.Parse(inkey[attnum - 1]); + foreach (string tc in loc3[object_id].Keys) + { + if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) + { + column = tc; + break; + } + } + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + var loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = $@" +select +ns.nspname || '.' || b.relname as table_id, +array(select attname from sys_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, +a.conname as FKId, +ns2.nspname || '.' || c.relname as ref_table_id, +1 as IsForeignKey, +array(select attname from sys_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, +null ref_sln, +null ref_table +from sys_constraint a +inner join sys_class b on b.oid = a.conrelid +inner join sys_class c on c.oid = a.confrelid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_namespace ns2 on ns2.oid = c.relnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } + + public class GetEnumsByDatabaseQueryInfo + { + public string name { get; set; } + public string label { get; set; } + } public List GetEnumsByDatabase(params string[] database) { - return new List(); + if (database == null || database.Length == 0) return new List(); + var drs = _orm.Ado.Query(CommandType.Text, _commonUtils.FormatSql(@" +select +ns.nspname || '.' || a.typname AS name, +b.enumlabel AS label +from sys_type a +inner join sys_enum b on b.enumtypid = a.oid +inner join sys_namespace ns on ns.oid = a.typnamespace +where a.typtype = 'e' and ns.nspname in (SELECT schema_name FROM information_schema.schemata where catalog_name in {0})", database)); + var ret = new Dictionary>(); + foreach (var dr in drs) + { + if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); + var key = dr.label; + if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) + key = $"Unkown{ret[dr.name].Count + 1}"; + if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); + } + return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs index 3cddc2e4..56bb6382 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs @@ -113,7 +113,7 @@ namespace FreeSql.Odbc.KingbaseES public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $"@{name.ToUpper()}"; public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs.Select((a, b) => b == 0 ? $"{a}::varchar" : a))}"; //First ::varchar public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; public override string Now => "current_timestamp"; From 46bc69d1392ad5c36619b1c06fc4758326817804 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 28 May 2020 14:53:13 +0800 Subject: [PATCH 0674/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IFreeSql.Ins?= =?UTF-8?q?ertOrUpdate=20Merge=20into=20=E6=9C=AA=E5=A4=84=E7=90=86=20CanU?= =?UTF-8?q?pdate=20=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B#330?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ .../Curd/DamengInsertOrUpdate.cs | 11 ++++++----- .../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 11 ++++++----- .../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 11 ++++++----- .../Curd/OdbcSqlServerInsertOrUpdate.cs | 12 ++++++------ .../Curd/OracleInsertOrUpdate.cs | 11 ++++++----- .../Curd/SqlServerInsertOrUpdate.cs | 12 ++++++------ 7 files changed, 52 insertions(+), 32 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index ec7370ad..1f4046e2 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -33,7 +33,7 @@ namespace FreeSql.Dameng.Curd { if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING ("); + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); @@ -46,10 +46,11 @@ namespace FreeSql.Dameng.Curd $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index d36ee50a..a6305e38 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -33,7 +33,7 @@ namespace FreeSql.Odbc.Dameng { if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING ("); + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); @@ -46,10 +46,11 @@ namespace FreeSql.Odbc.Dameng $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index 1a0766a1..ed63ad31 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -33,7 +33,7 @@ namespace FreeSql.Odbc.Oracle { if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING ("); + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); @@ -46,10 +46,11 @@ namespace FreeSql.Odbc.Oracle $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index 69b11d78..18779fe2 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -35,8 +35,7 @@ namespace FreeSql.Odbc.SqlServer var sb = new StringBuilder(); if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n"); - sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") - .Append("USING ("); + sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); @@ -49,10 +48,11 @@ namespace FreeSql.Odbc.SqlServer $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;"); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index 426f1f16..a79c1694 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -33,7 +33,7 @@ namespace FreeSql.Oracle.Curd { if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); - var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n").Append("USING ("); + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); @@ -46,10 +46,11 @@ namespace FreeSql.Oracle.Curd $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index f8162605..b05b9e2c 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -35,8 +35,7 @@ namespace FreeSql.SqlServer.Curd var sb = new StringBuilder(); if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n"); - sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\n") - .Append("USING ("); + sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); @@ -49,10 +48,11 @@ namespace FreeSql.SqlServer.Curd $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); - cols = _table.Columns.Values; - sb.Append("WHEN NOT MATCHED THEN \r\n") - .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") - .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(");"); if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;"); From add59235263cf2dea9f45c07201673065dba14f0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 28 May 2020 15:00:51 +0800 Subject: [PATCH 0675/1029] 1.6.0-preview0101 #330 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 18 insertions(+), 34 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a0d3fad9..713275e2 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 98a98e88..5229e4bc 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 8ddd707a..fe229642 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 50004381..474b859f 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 0f6294e3..db9c919b 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.5.0 + 1.6.0-preview0101 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 1245fcd6..ef98252f 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 0ddefede..5f640dcd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access 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.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7418ac57..fa433bce 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.5.0 + 1.6.0-preview0101 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index aeaae6e0..e9075b5a 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index e5b093a4..33406746 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 47d9ffac..03ec013d 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 11397cde..2d3cb0c8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6e8a0fe4..606f4a36 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index b0c6295d..3a7285bd 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d945c3ac..75001744 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0a38c0b2..2149e62a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index be525381..44b42c4c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7d7c5bce..809fd860 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.5.0 + 1.6.0-preview0101 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 560534f3bc2c021b7672dc29be5dacacb87bf133 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 28 May 2020 17:23:24 +0800 Subject: [PATCH 0676/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IUpdate=20Se?= =?UTF-8?q?t(=E8=A1=A8=E8=BE=BE=E5=BC=8F)=20MapType=20=E6=9C=AA=E7=94=9F?= =?UTF-8?q?=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/Issues/311.cs | 40 +++++++++++++++++++ .../Internal/CommonProvider/UpdateProvider.cs | 6 +-- 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/311.cs diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/311.cs b/FreeSql.Tests/FreeSql.Tests/Issues/311.cs new file mode 100644 index 00000000..aed5245c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/311.cs @@ -0,0 +1,40 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _311 + { + [Fact] + public void SelectTest() + { + IFreeSql db = g.mysql; + + var sql = db.Update(1).Set(a => new UpdateSetEnum01 { Status01 = EnumStatus01.E01001, Status02 = EnumStatus02.E02003 }).ToSql(); + Assert.Equal(@"UPDATE `UpdateSetEnum01` SET `Status01` = 'E01001', `Status02` = 2 +WHERE (`ID` = 1)", sql); + + sql = db.Update(1).Set(a => new UpdateSetEnum01 { Status01 = null, Status02 = null }).ToSql(); + Assert.Equal(@"UPDATE `UpdateSetEnum01` SET `Status01` = NULL, `Status02` = NULL +WHERE (`ID` = 1)", sql); + + sql = db.Update(1).Set(a => a.Status01 == null).Set(a => a.Status02 == null).ToSql(); + Assert.Equal(@"UPDATE `UpdateSetEnum01` SET `Status01` = NULL, `Status02` = NULL +WHERE (`ID` = 1)", sql); + } + + public class UpdateSetEnum01 + { + public int ID { get; set; } + public EnumStatus01? Status01 { get; set; } + [Column(MapType = typeof(int))] + public EnumStatus02? Status02 { get; set; } + } + + public enum EnumStatus01 { E01001, E01002, E01003 } + public enum EnumStatus02 { E02001, E02002, E02003 } + } +} diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 1757826b..7385aa2f 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -420,7 +420,7 @@ namespace FreeSql.Internal.CommonProvider case ExpressionType.Equal: var equalBinaryExp = body as BinaryExpression; var eqval = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, body, null, null); - if (eqval.EndsWith(" IS NULL")) eqval = $"{eqval.Remove(eqval.Length - 10)} = NULL"; //issues/311 + if (eqval.EndsWith(" IS NULL")) eqval = $"{eqval.Remove(eqval.Length - 10)} = NULL"; //#311 _set.Append(", ").Append(eqval); return this; case ExpressionType.MemberInit: @@ -434,7 +434,7 @@ namespace FreeSql.Internal.CommonProvider var memberName = initExp.Bindings[a].Member.Name; if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); - var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { isQuoteName = true }); + var memberValue = _commonExpression.ExpressionLambdaToSql(initAssignExp.Expression, new CommonExpression.ExpTSC { isQuoteName = true, mapType = col.Attribute.MapType }); _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); } } @@ -448,7 +448,7 @@ namespace FreeSql.Internal.CommonProvider var memberName = newExp.Members[a].Name; if (_table.ColumnsByCsIgnore.ContainsKey(memberName)) continue; if (_table.ColumnsByCs.TryGetValue(memberName, out var col) == false) throw new Exception($"找不到属性:{memberName}"); - var memberValue = _commonExpression.ExpressionLambdaToSql(newExp.Arguments[a], new CommonExpression.ExpTSC { isQuoteName = true }); + var memberValue = _commonExpression.ExpressionLambdaToSql(newExp.Arguments[a], new CommonExpression.ExpTSC { isQuoteName = true, mapType = col.Attribute.MapType }); _setIncr.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(memberValue); } } From 6f53658dde51698d44d862aa2acc4230defc72ec Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 28 May 2020 17:25:30 +0800 Subject: [PATCH 0677/1029] 1.6.0-preview0102 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 713275e2..e7ceed94 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 5229e4bc..58368471 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index fe229642..57df2768 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 474b859f..5a8355a0 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index db9c919b..cdb928d0 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0101 + 1.6.0-preview0102 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index ef98252f..bda8bb51 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 5f640dcd..2f301d88 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index fa433bce..8b4ea646 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e9075b5a..cc172b09 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 33406746..09129956 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 03ec013d..5f7ab7ed 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 2d3cb0c8..210201e6 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 606f4a36..4505980c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3a7285bd..ea39913e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 75001744..41957748 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2149e62a..15dfc451 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 44b42c4c..68f5fa3d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 809fd860..21591c85 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0101 + 1.6.0-preview0102 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 909fe9bc7afb1e47c815230317baef7eff49dd58 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 31 May 2020 10:42:26 +0800 Subject: [PATCH 0678/1029] update kingbaseES --- .../Controllers/SongController.cs | 17 +-- Examples/repository_01/Startup.cs | 8 + FreeSql.DbContext/DbSet/DbSet.cs | 1 + FreeSql.DbContext/DbSet/DbSetAsync.cs | 2 + FreeSql.DbContext/DbSet/DbSetSync.cs | 2 + FreeSql.DbContext/FreeSql.DbContext.xml | 16 -- FreeSql/FreeSql.xml | 143 ------------------ FreeSql/Internal/UtilsExpressionTree.cs | 1 + 8 files changed, 19 insertions(+), 171 deletions(-) diff --git a/Examples/repository_01/Controllers/SongController.cs b/Examples/repository_01/Controllers/SongController.cs index f64a1a8c..4381d575 100644 --- a/Examples/repository_01/Controllers/SongController.cs +++ b/Examples/repository_01/Controllers/SongController.cs @@ -1,5 +1,6 @@ using FreeSql; using Microsoft.AspNetCore.Mvc; +using repository_01; using restful.Entitys; using System; using System.Collections.Generic; @@ -32,32 +33,24 @@ namespace restful.Controllers public SongsController(IFreeSql fsql, - GuidRepository repos1, - GuidRepository repos2, - - DefaultRepository repos11, - DefaultRepository repos21, - BaseRepository repos3, BaseRepository repos4, IBaseRepository repos31, IBaseRepository repos41, - SongRepository reposSong + SongRepository reposSong, + IBaseRepository reposTest ) { - _songRepository = repos4; + Console.Write(reposTest.Select.ToSql()); + _songRepository = repos4; //test code var curd1 = fsql.GetRepository(); var curd2 = fsql.GetRepository(); var curd3 = fsql.GetRepository(); var curd4 = fsql.GetGuidRepository(); - Console.WriteLine(repos1.Select.ToSql()); Console.WriteLine(reposSong.Select.ToSql()); - Console.WriteLine(repos2.Select.ToSql()); - Console.WriteLine(repos21.Select.ToSql()); - using (reposSong.DataFilter.DisableAll()) { Console.WriteLine(reposSong.Select.ToSql()); diff --git a/Examples/repository_01/Startup.cs b/Examples/repository_01/Startup.cs index 65bb13c2..a0b904ee 100644 --- a/Examples/repository_01/Startup.cs +++ b/Examples/repository_01/Startup.cs @@ -84,4 +84,12 @@ namespace repository_01 { bool IsDeleted { get; set; } } + + public class TestSoftDelete : ISoftDelete + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + public bool IsDeleted { get; set; } + } } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 6af6b0d2..4180e750 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -276,6 +276,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: return true; default: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 774269ee..52626a89 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -41,6 +41,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { await DbContextFlushCommandAsync(); @@ -102,6 +103,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: await DbContextFlushCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 039fed10..743dfeef 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -40,6 +40,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: if (_tableIdentitys.Length == 1) { DbContextFlushCommand(); @@ -105,6 +106,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: DbContextFlushCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); 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/FreeSql.xml b/FreeSql/FreeSql.xml index 06756040..1808426b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2411,137 +2411,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3144,12 +3013,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3220,12 +3083,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 7bbd8a63..4d21d6d9 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -242,6 +242,7 @@ namespace FreeSql.Internal break; case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: if (strlen < 0) colattr.DbType = "TEXT"; else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; From 4dd4f232571068ca8969ed83d8b213edc60cb0db Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 1 Jun 2020 10:36:34 +0800 Subject: [PATCH 0679/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20WhereDynamic?= =?UTF-8?q?Filter=20=E6=93=8D=E4=BD=9C=E7=AC=A6=20Range/Any=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=8C=83=E5=9B=B4/In=E6=9F=A5=E8=AF=A2?= =?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 ++ .../Sqlite/Curd/SqliteSelectTest.cs | 38 +++- FreeSql/FreeSql.xml | 170 +++++++++++++++++- .../SelectProvider/Select0Provider.cs | 17 +- FreeSql/Internal/Model/DynamicFilterInfo.cs | 24 ++- 5 files changed, 260 insertions(+), 5 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 577f59bd..d8f7e2bf 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1918,6 +1918,8 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" public virtual string ParentCode { get; set; } public DateTime CreateTime { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict @@ -1976,12 +1978,44 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" ] } ")).ToSql(); - Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""ParentCode"" + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode"" FROM ""D_District"" a WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") LIKE '%val3' OR a.""ParentCode"" = 'val4' OR a.""CreateTime"" >= '2010-10-10 00:00:00'))", sql); sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" { + ""Logic"" : ""Or"", + ""Filters"" : + [ + { + ""Field"" : ""CreateTime"", + ""Operator"" : ""Range"", + ""Value"" : ""2010-10-10,2010-12-10"" + }, + { + ""Field"" : ""Name"", + ""Operator"" : ""Any"", + ""Value"" : ""val1,val2,val3,val4"" + }, + { + ""Field"" : ""testint"", + ""Operator"" : ""Range"", + ""Value"" : ""100,555"" + }, + { + ""Field"" : ""testint"", + ""Operator"" : ""Any"", + ""Value"" : ""1,5,11,15"" + } + ] +} +")).ToSql(); + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode"" +FROM ""D_District"" a +WHERE ((a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-12-10 00:00:00' OR ((a.""Name"") in ('val1','val2','val3','val4')) OR a.""testint"" >= 100 AND a.""testint"" < 555 OR ((a.""testint"") in (1,5,11,15))))", sql); + + sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" +{ ""Logic"" : ""Or"", ""Filters"" : [ @@ -2035,7 +2069,7 @@ WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") ] } ")).ToSql(); - Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""ParentCode"", a__Parent.""Code"" as5, a__Parent.""Name"" as6, a__Parent.""CreateTime"" as7, a__Parent.""ParentCode"" as8 + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode"", a__Parent.""Code"" as6, a__Parent.""Name"" as7, a__Parent.""CreateTime"" as8, a__Parent.""testint"" as9, a__Parent.""ParentCode"" as10 FROM ""D_District"" a LEFT JOIN ""D_District"" a__Parent ON a__Parent.""Code"" = a.""ParentCode"" WHERE ((not((a.""Code"") LIKE '%val1%') AND not((a.""Name"") LIKE 'val2%') OR not((a.""Name"") LIKE '%val3') OR a.""ParentCode"" <> 'val4' OR a__Parent.""Code"" = 'val11' AND (a__Parent.""Name"") LIKE '%val22%' OR a__Parent.""Name"" = 'val33' OR a__Parent.""ParentCode"" = 'val44'))", sql); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1808426b..91c6a3fb 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2411,6 +2411,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 }) + + + + + + 可自定义解析表达式 @@ -2939,9 +3070,22 @@ like + + + = + Equal/Equals/Eq 效果相同 + + - = + = + Equal/Equals/Eq 效果相同 + + + + + = + Equal/Equals/Eq 效果相同 @@ -2969,6 +3113,18 @@ <= + + + >= and < + 此时 Value 的值格式为逗号分割:value1,value2 + + + + + in (1,2,3) + 此时 Value 的值格式为逗号分割:value1,value2,value3... + + 中间表,多对多 @@ -3013,6 +3169,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3083,6 +3245,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index e4b1a515..b1d550c5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1029,6 +1029,8 @@ namespace FreeSql.Internal.CommonProvider static MethodInfo MethodStringContains = typeof(string).GetMethod("Contains", new[] { typeof(string) }); static MethodInfo MethodStringStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); static MethodInfo MethodStringEndsWith = typeof(string).GetMethod("EndsWith", new[] { typeof(string) }); + static ConcurrentDictionary MethodEnumerableContainsDic = new ConcurrentDictionary(); + static MethodInfo GetMethodEnumerableContains(Type elementType) => MethodEnumerableContainsDic.GetOrAdd(elementType, et => typeof(Enumerable).GetMethods().Where(a => a.Name == "Contains").FirstOrDefault().MakeGenericMethod(elementType)); public TSelect WhereDynamicFilter(DynamicFilterInfo filter) { if (filter == null) return this as TSelect; @@ -1089,14 +1091,27 @@ namespace FreeSql.Internal.CommonProvider case DynamicFilterOperator.NotStartsWith: exp = Expression.Not(Expression.Call(exp, MethodStringStartsWith, Expression.Constant(fi.Value))); break; case DynamicFilterOperator.NotEndsWith: exp = Expression.Not(Expression.Call(exp, MethodStringEndsWith, Expression.Constant(fi.Value))); break; + case DynamicFilterOperator.Eq: case DynamicFilterOperator.Equals: - case DynamicFilterOperator.Eq: exp = Expression.Equal(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.Equal: exp = Expression.Equal(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.NotEqual: exp = Expression.NotEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.GreaterThan: exp = Expression.GreaterThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.GreaterThanOrEqual: exp = Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.LessThan: exp = Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.Range: + var fiValueRangeArray = fi.Value.Split(','); + if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 对应 Value 应该逗号分割,并且长度为 2"); + exp = Expression.AndAlso( + Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[0]), exp.Type)), + Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[1]), exp.Type))); + break; + case DynamicFilterOperator.Any: + var fiValueAnyArray = fi.Value.Split(','); + var fiValueAnyArrayType = exp.Type.MakeArrayType(); + exp = Expression.Call(GetMethodEnumerableContains(exp.Type), Expression.Constant(Utils.GetDataReaderValue(fiValueAnyArrayType, fiValueAnyArray), fiValueAnyArrayType), exp); + break; } var sql = _commonExpression.ExpressionWhereLambda(_tables, exp, null, null, _params); diff --git a/FreeSql/Internal/Model/DynamicFilterInfo.cs b/FreeSql/Internal/Model/DynamicFilterInfo.cs index 81ffc35e..fac235fa 100644 --- a/FreeSql/Internal/Model/DynamicFilterInfo.cs +++ b/FreeSql/Internal/Model/DynamicFilterInfo.cs @@ -55,9 +55,19 @@ namespace FreeSql.Internal.Model NotEndsWith, /// - /// = + /// = + /// Equal/Equals/Eq 效果相同 + /// + Equal, + /// + /// = + /// Equal/Equals/Eq 效果相同 /// Equals, + /// + /// = + /// Equal/Equals/Eq 效果相同 + /// Eq, /// /// <> @@ -80,5 +90,17 @@ namespace FreeSql.Internal.Model /// <= /// LessThanOrEqual, + + /// + /// >= and < + /// 此时 Value 的值格式为逗号分割:value1,value2 + /// + Range, + + /// + /// in (1,2,3) + /// 此时 Value 的值格式为逗号分割:value1,value2,value3... + /// + Any } } From 43e2af2bee395b8b2daed68831c13970b6b625c9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 1 Jun 2020 12:46:57 +0800 Subject: [PATCH 0680/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20WhereDynamic?= =?UTF-8?q?Filter=20=E6=93=8D=E4=BD=9C=E7=AC=A6=20DateRange=EF=BC=8C?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E8=8C=83=E5=9B=B4=E6=9F=A5=E8=AF=A2=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sqlite/Curd/SqliteSelectTest.cs | 37 +++++++++++++++++++ FreeSql/FreeSql.xml | 13 +++++++ .../SelectProvider/Select0Provider.cs | 16 +++++++- FreeSql/Internal/Model/DynamicFilterInfo.cs | 13 +++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index d8f7e2bf..f2304308 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1984,6 +1984,43 @@ WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" { + ""Logic"" : ""Or"", + ""Filters"" : + [ + { + ""Field"" : ""CreateTime"", + ""Operator"" : ""DateRange"", + ""Value"" : ""2010-10-10,2010-11-10"" + }, + { + ""Field"" : ""CreateTime"", + ""Operator"" : ""DateRange"", + ""Value"" : ""2010-10-10,2010-11"" + }, + { + ""Field"" : ""CreateTime"", + ""Operator"" : ""DateRange"", + ""Value"" : ""2010-10-10,2010"" + }, + { + ""Field"" : ""CreateTime"", + ""Operator"" : ""DateRange"", + ""Value"" : ""2010-10-10,2010-11-10 11"" + }, + { + ""Field"" : ""CreateTime"", + ""Operator"" : ""DateRange"", + ""Value"" : ""2010-10-10,2010-11-10 11:20"" + }, + ] +} +")).ToSql(); + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode"" +FROM ""D_District"" a +WHERE ((a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-11 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-12-01 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2011-01-01 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-10 12:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-10 11:21:00'))", sql); + + sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" +{ ""Logic"" : ""Or"", ""Filters"" : [ diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 91c6a3fb..50fab767 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3119,6 +3119,19 @@ 此时 Value 的值格式为逗号分割:value1,value2 + + + >= and < + 此时 Value 的值格式为逗号分割:date1,date2 + 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: + 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 + 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 + 当 date2 选择的是 2020,那查询的时候是 < 2021 + 当 date2 选择的是 2020-05-30 12,那查询的时候是 < 2020-05-30 13 + 当 date2 选择的是 2020-05-30 12:30,那查询的时候是 < 2020-05-30 12:31 + 并且 date2 只支持以上 5 种格式 (date1 没有限制) + + in (1,2,3) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index b1d550c5..a77c9b65 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -1102,11 +1103,24 @@ namespace FreeSql.Internal.CommonProvider case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.Range: var fiValueRangeArray = fi.Value.Split(','); - if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 对应 Value 应该逗号分割,并且长度为 2"); + if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 要求 Value 应该逗号分割,并且长度为 2"); exp = Expression.AndAlso( Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[0]), exp.Type)), Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[1]), exp.Type))); break; + case DynamicFilterOperator.DateRange: + var fiValueDateRangeArray = fi.Value.Split(','); + if (fiValueDateRangeArray.Length != 2) throw new ArgumentException($"DateRange 要求 Value 应该逗号分割,并且长度为 2"); + if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse(fiValueDateRangeArray[1]).AddDays(1).ToString("yyyy-MM-dd HH:mm:ss"); + else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}-01").AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss"); + else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}-01-01").AddYears(1).ToString("yyyy-MM-dd HH:mm:ss"); + else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}:00:00").AddHours(1).ToString("yyyy-MM-dd HH:mm:ss"); + else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?:\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}:00").AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss"); + else throw new ArgumentException($"DateRange 要求 Value[1] 格式必须为:yyyy、yyyy-MM、yyyy-MM-dd、yyyy-MM-dd HH、yyyy、yyyy-MM-dd HH:mm"); + exp = Expression.AndAlso( + Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[0]), exp.Type)), + Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[1]), exp.Type))); + break; case DynamicFilterOperator.Any: var fiValueAnyArray = fi.Value.Split(','); var fiValueAnyArrayType = exp.Type.MakeArrayType(); diff --git a/FreeSql/Internal/Model/DynamicFilterInfo.cs b/FreeSql/Internal/Model/DynamicFilterInfo.cs index fac235fa..69424118 100644 --- a/FreeSql/Internal/Model/DynamicFilterInfo.cs +++ b/FreeSql/Internal/Model/DynamicFilterInfo.cs @@ -97,6 +97,19 @@ namespace FreeSql.Internal.Model /// Range, + /// + /// >= and < + /// 此时 Value 的值格式为逗号分割:date1,date2 + /// 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: + /// 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 + /// 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 + /// 当 date2 选择的是 2020,那查询的时候是 < 2021 + /// 当 date2 选择的是 2020-05-30 12,那查询的时候是 < 2020-05-30 13 + /// 当 date2 选择的是 2020-05-30 12:30,那查询的时候是 < 2020-05-30 12:31 + /// 并且 date2 只支持以上 5 种格式 (date1 没有限制) + /// + DateRange, + /// /// in (1,2,3) /// 此时 Value 的值格式为逗号分割:value1,value2,value3... From 875c10914486fdb9e3cb18fa8e1c850e4c312dd5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 1 Jun 2020 12:59:58 +0800 Subject: [PATCH 0681/1029] 1.6.0-preview0601 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 6 ++++++ .../CommonProvider/SelectProvider/Select0Provider.cs | 2 ++ FreeSql/Internal/Model/DynamicFilterInfo.cs | 7 ++++++- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 32 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index e7ceed94..346f9492 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 58368471..5cc99a67 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 57df2768..db3627b3 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 5a8355a0..689228be 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index cdb928d0..00fcb65b 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0102 + 1.6.0-preview0601 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index bda8bb51..204a836e 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2f301d88..ebdcc3c6 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8b4ea646..61733812 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cc172b09..0c303491 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 50fab767..3e9c6a22 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3138,6 +3138,12 @@ 此时 Value 的值格式为逗号分割:value1,value2,value3... + + + not in (1,2,3) + 此时 Value 的值格式为逗号分割:value1,value2,value3... + + 中间表,多对多 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index a77c9b65..f4037586 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1122,9 +1122,11 @@ namespace FreeSql.Internal.CommonProvider Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[1]), exp.Type))); break; case DynamicFilterOperator.Any: + case DynamicFilterOperator.NotAny: var fiValueAnyArray = fi.Value.Split(','); var fiValueAnyArrayType = exp.Type.MakeArrayType(); exp = Expression.Call(GetMethodEnumerableContains(exp.Type), Expression.Constant(Utils.GetDataReaderValue(fiValueAnyArrayType, fiValueAnyArray), fiValueAnyArrayType), exp); + if (fi.Operator == DynamicFilterOperator.NotAny) exp = Expression.Not(exp); break; } diff --git a/FreeSql/Internal/Model/DynamicFilterInfo.cs b/FreeSql/Internal/Model/DynamicFilterInfo.cs index 69424118..892e6755 100644 --- a/FreeSql/Internal/Model/DynamicFilterInfo.cs +++ b/FreeSql/Internal/Model/DynamicFilterInfo.cs @@ -114,6 +114,11 @@ namespace FreeSql.Internal.Model /// in (1,2,3) /// 此时 Value 的值格式为逗号分割:value1,value2,value3... /// - Any + Any, + /// + /// not in (1,2,3) + /// 此时 Value 的值格式为逗号分割:value1,value2,value3... + /// + NotAny } } diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 09129956..1719ea9b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 5f7ab7ed..aaa1482a 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 210201e6..082bab6c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4505980c..8378ec7d 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index ea39913e..8651ae0f 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 41957748..16175f13 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 15dfc451..a3b21db1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 68f5fa3d..cb7dfbbd 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 21591c85..4a71b855 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0102 + 1.6.0-preview0601 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 1f02eb6a1351a8ada65c83181c706791747339a3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 1 Jun 2020 22:36:38 +0800 Subject: [PATCH 0682/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20WhereDynamic?= =?UTF-8?q?Filter=20Value=20=E6=94=AF=E6=8C=81=E6=95=B0=E7=BB=84=E6=88=96?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ------ .../Sqlite/Curd/SqliteSelectTest.cs | 12 ++++---- .../SelectProvider/Select0Provider.cs | 29 ++++++++++++++++--- FreeSql/Internal/Model/DynamicFilterInfo.cs | 10 +++---- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,14 +486,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index f2304308..f117bdd9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1990,34 +1990,34 @@ WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") { ""Field"" : ""CreateTime"", ""Operator"" : ""DateRange"", - ""Value"" : ""2010-10-10,2010-11-10"" + ""Value"" : [""2010-10-10"", ""2010-11-10""] }, { ""Field"" : ""CreateTime"", ""Operator"" : ""DateRange"", - ""Value"" : ""2010-10-10,2010-11"" + ""Value"" : ""2010-10,2010-11"" }, { ""Field"" : ""CreateTime"", ""Operator"" : ""DateRange"", - ""Value"" : ""2010-10-10,2010"" + ""Value"" : ""2010,2010"" }, { ""Field"" : ""CreateTime"", ""Operator"" : ""DateRange"", - ""Value"" : ""2010-10-10,2010-11-10 11"" + ""Value"" : ""2010-10-10 11,2010-11-10 11"" }, { ""Field"" : ""CreateTime"", ""Operator"" : ""DateRange"", - ""Value"" : ""2010-10-10,2010-11-10 11:20"" + ""Value"" : ""2010-10-10 11:20,2010-11-10 11:20"" }, ] } ")).ToSql(); Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode"" FROM ""D_District"" a -WHERE ((a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-11 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-12-01 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2011-01-01 00:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-10 12:00:00' OR a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-10 11:21:00'))", sql); +WHERE ((a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-11-11 00:00:00' OR a.""CreateTime"" >= '2010-10-01 00:00:00' AND a.""CreateTime"" < '2010-12-01 00:00:00' OR a.""CreateTime"" >= '2010-01-01 00:00:00' AND a.""CreateTime"" < '2011-01-01 00:00:00' OR a.""CreateTime"" >= '2010-10-10 11:00:00' AND a.""CreateTime"" < '2010-11-10 12:00:00' OR a.""CreateTime"" >= '2010-10-10 11:20:00' AND a.""CreateTime"" < '2010-11-10 11:21:00'))", sql); sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index f4037586..5841a265 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1,5 +1,6 @@ using FreeSql.Internal.Model; using System; +using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -1102,34 +1103,54 @@ namespace FreeSql.Internal.CommonProvider case DynamicFilterOperator.LessThan: exp = Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; case DynamicFilterOperator.Range: - var fiValueRangeArray = fi.Value.Split(','); + var fiValueRangeArray = getFiListValue(); if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 要求 Value 应该逗号分割,并且长度为 2"); exp = Expression.AndAlso( Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[0]), exp.Type)), Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueRangeArray[1]), exp.Type))); break; case DynamicFilterOperator.DateRange: - var fiValueDateRangeArray = fi.Value.Split(','); - if (fiValueDateRangeArray.Length != 2) throw new ArgumentException($"DateRange 要求 Value 应该逗号分割,并且长度为 2"); + var fiValueDateRangeArray = getFiListValue(); + if (fiValueDateRangeArray?.Length != 2) throw new ArgumentException($"DateRange 要求 Value 应该逗号分割,并且长度为 2"); if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse(fiValueDateRangeArray[1]).AddDays(1).ToString("yyyy-MM-dd HH:mm:ss"); else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}-01").AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss"); else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}-01-01").AddYears(1).ToString("yyyy-MM-dd HH:mm:ss"); else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}:00:00").AddHours(1).ToString("yyyy-MM-dd HH:mm:ss"); else if (Regex.IsMatch(fiValueDateRangeArray[1], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?:\d\d?$")) fiValueDateRangeArray[1] = DateTime.Parse($"{fiValueDateRangeArray[1]}:00").AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss"); else throw new ArgumentException($"DateRange 要求 Value[1] 格式必须为:yyyy、yyyy-MM、yyyy-MM-dd、yyyy-MM-dd HH、yyyy、yyyy-MM-dd HH:mm"); + + if (Regex.IsMatch(fiValueDateRangeArray[0], @"^\d\d\d\d[\-/]\d\d?$")) fiValueDateRangeArray[0] = DateTime.Parse($"{fiValueDateRangeArray[0]}-01").ToString("yyyy-MM-dd HH:mm:ss"); + else if (Regex.IsMatch(fiValueDateRangeArray[0], @"^\d\d\d\d$")) fiValueDateRangeArray[0] = DateTime.Parse($"{fiValueDateRangeArray[0]}-01-01").ToString("yyyy-MM-dd HH:mm:ss"); + else if (Regex.IsMatch(fiValueDateRangeArray[0], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?$")) fiValueDateRangeArray[0] = DateTime.Parse($"{fiValueDateRangeArray[0]}:00:00").ToString("yyyy-MM-dd HH:mm:ss"); + else if (Regex.IsMatch(fiValueDateRangeArray[0], @"^\d\d\d\d[\-/]\d\d?[\-/]\d\d? \d\d?:\d\d?$")) fiValueDateRangeArray[0] = DateTime.Parse($"{fiValueDateRangeArray[0]}:00").ToString("yyyy-MM-dd HH:mm:ss"); + exp = Expression.AndAlso( Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[0]), exp.Type)), Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fiValueDateRangeArray[1]), exp.Type))); break; case DynamicFilterOperator.Any: case DynamicFilterOperator.NotAny: - var fiValueAnyArray = fi.Value.Split(','); + var fiValueAnyArray = getFiListValue(); + if (fiValueAnyArray.Length == 0) break; var fiValueAnyArrayType = exp.Type.MakeArrayType(); exp = Expression.Call(GetMethodEnumerableContains(exp.Type), Expression.Constant(Utils.GetDataReaderValue(fiValueAnyArrayType, fiValueAnyArray), fiValueAnyArrayType), exp); if (fi.Operator == DynamicFilterOperator.NotAny) exp = Expression.Not(exp); break; } + string[] getFiListValue() + { + if (fi.Value is string fiValueString) return fiValueString.Split(','); + if (fi.Value is IEnumerable fiValueIe) + { + var fiValueList = new List(); + foreach (var fiValueIeItem in fiValueIe) + fiValueList.Add(string.Concat(fiValueIeItem)); + return fiValueList.ToArray(); + } + return new string[0]; + } + var sql = _commonExpression.ExpressionWhereLambda(_tables, exp, null, null, _params); sb.Append(sql); diff --git a/FreeSql/Internal/Model/DynamicFilterInfo.cs b/FreeSql/Internal/Model/DynamicFilterInfo.cs index 892e6755..64adb791 100644 --- a/FreeSql/Internal/Model/DynamicFilterInfo.cs +++ b/FreeSql/Internal/Model/DynamicFilterInfo.cs @@ -28,7 +28,7 @@ namespace FreeSql.Internal.Model /// /// 值 /// - public string Value { get; set; } + public object Value { get; set; } /// /// Filters 下的逻辑运算符 @@ -93,13 +93,13 @@ namespace FreeSql.Internal.Model /// /// >= and < - /// 此时 Value 的值格式为逗号分割:value1,value2 + /// 此时 Value 的值格式为逗号分割:value1,value2 或者数组 /// Range, /// /// >= and < - /// 此时 Value 的值格式为逗号分割:date1,date2 + /// 此时 Value 的值格式为逗号分割:date1,date2 或者数组 /// 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: /// 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 /// 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 @@ -112,12 +112,12 @@ namespace FreeSql.Internal.Model /// /// in (1,2,3) - /// 此时 Value 的值格式为逗号分割:value1,value2,value3... + /// 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 /// Any, /// /// not in (1,2,3) - /// 此时 Value 的值格式为逗号分割:value1,value2,value3... + /// 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 /// NotAny } From 926d8353c1746707b0fb44c43c2e71c23c9c8803 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 1 Jun 2020 22:38:23 +0800 Subject: [PATCH 0683/1029] 1.6.0-preview0602 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 8 ++++---- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 22 insertions(+), 29 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 346f9492..d6cf5e22 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 5cc99a67..f508f737 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index db3627b3..3388b4ab 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 689228be..4f3f91c3 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 00fcb65b..575333ba 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0601 + 1.6.0-preview0602 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 204a836e..3a5d6783 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ebdcc3c6..95f24a56 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..132d875e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 61733812..8e1cdffb 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0c303491..7c716707 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3e9c6a22..b9a3434c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3116,13 +3116,13 @@ >= and < - 此时 Value 的值格式为逗号分割:value1,value2 + 此时 Value 的值格式为逗号分割:value1,value2 或者数组 >= and < - 此时 Value 的值格式为逗号分割:date1,date2 + 此时 Value 的值格式为逗号分割:date1,date2 或者数组 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 @@ -3135,13 +3135,13 @@ in (1,2,3) - 此时 Value 的值格式为逗号分割:value1,value2,value3... + 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 not in (1,2,3) - 此时 Value 的值格式为逗号分割:value1,value2,value3... + 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 1719ea9b..39cf0ce5 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index aaa1482a..948b3006 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 082bab6c..0a960295 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8378ec7d..9b137c2e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 8651ae0f..08a0aa31 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 16175f13..53ffb4a7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a3b21db1..0707f21c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cb7dfbbd..2f5ceced 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4a71b855..2569fb0a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0601 + 1.6.0-preview0602 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From b9948f45081682a020e68a8eef62328484fa46f6 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 6 Jun 2020 19:02:41 +0800 Subject: [PATCH 0684/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20MySql=20Stri?= =?UTF-8?q?ngLength/MaxLength=20-2=20=E4=BA=A7=E7=94=9F=20LongText=20?= =?UTF-8?q?=E6=98=A0=E5=B0=84=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++ .../MySqlConnector/MySqlCodeFirstTest.cs | 88 ++++++++++++++++++ .../Dameng/Curd/DamengInsertTest.cs | 2 +- .../Dameng/Curd/DamengUpdateTest.cs | 2 +- .../Dameng/DamengCodeFirstTest.cs | 73 ++++++++++++++- .../Dameng/MapType/BoolNullableTest.cs | 28 +----- .../FreeSql.Tests/Dameng/MapType/EnumTest.cs | 32 +------ .../Dameng/MapType/ToStringTest.cs | 92 ++----------------- .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 88 ++++++++++++++++++ FreeSql/DataAnnotations/ColumnAttribute.cs | 6 +- FreeSql/FreeSql.xml | 6 +- .../SelectProvider/Select0Provider.cs | 4 +- FreeSql/Internal/UtilsExpressionTree.cs | 9 +- .../DamengCodeFirst.cs | 18 +++- .../Dameng/OdbcDamengCodeFirst.cs | 8 +- .../Oracle/OdbcOracleCodeFirst.cs | 2 +- .../OracleCodeFirst.cs | 2 +- 17 files changed, 311 insertions(+), 165 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index fed6cd4f..9947a09a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -10,6 +10,94 @@ namespace FreeSql.Tests.MySqlConnector { public class MySqlCodeFirstTest { + [Fact] + public void Text_StringLength_1() + { + var str1 = string.Join(",", Enumerable.Range(0, 1000).Select(a => "й")); + + var item1 = new TS_TEXT02 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT02 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT02 + { + public Guid Id { get; set; } + [Column(StringLength = -1)] + public string Data { get; set; } + } + + [Fact] + public void Text() + { + var str1 = string.Join(",", Enumerable.Range(0, 1000).Select(a => "й")); + + var item1 = new TS_TEXT01 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT01 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT01 + { + public Guid Id { get; set; } + [Column(DbType = "text")] + public string Data { get; set; } + } + + [Fact] + public void Text_StringLength_2() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_TEXT04 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT04 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT04 + { + public Guid Id { get; set; } + [Column(StringLength = -2)] + public string Data { get; set; } + } + + [Fact] + public void LongText() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_TEXT03 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT03 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT03 + { + public Guid Id { get; set; } + [Column(DbType = "longtext")] + public string Data { get; set; } + } + [Fact] public void StringLength() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs index 4bb00a07..988f0685 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs @@ -9,7 +9,7 @@ namespace FreeSql.Tests.Dameng public class DamengInsertTest { - IInsert insert => g.dameng.Insert(); //�������� + IInsert insert => g.dameng.Insert().NoneParameter(); [Table(Name = "tb_topic_insert")] class Topic diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs index 06c53408..995d5c31 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs @@ -7,7 +7,7 @@ namespace FreeSql.Tests.Dameng { public class DamengUpdateTest { - IUpdate update => g.dameng.Update(); + IUpdate update => g.dameng.Update().NoneParameter(); [Table(Name = "tb_topic")] class Topic diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs index e8b064db..df3ff443 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs @@ -10,6 +10,74 @@ namespace FreeSql.Tests.Dameng { public class DamengCodeFirstTest { + [Fact] + public void Text_StringLength_1() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_TEXT02 { Data = str1 }; + Assert.Equal(1, g.dameng.Insert(item1).ExecuteAffrows()); + + var item2 = g.dameng.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT02 { Data = str1 }; + Assert.Equal(1, g.dameng.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT02 + { + public Guid Id { get; set; } + [Column(StringLength = -1)] + public string Data { get; set; } + } + + [Fact] + public void Text() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_TEXT01 { Data = str1 }; + Assert.Equal(1, g.dameng.Insert(item1).ExecuteAffrows()); + + var item2 = g.dameng.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT01 { Data = str1 }; + Assert.Equal(1, g.dameng.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT01 + { + public Guid Id { get; set; } + [Column(DbType = "text")] + public string Data { get; set; } + } + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.dameng.Insert(item1).ExecuteAffrows()); + + var item2 = g.dameng.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Throws(() => g.dameng.Insert(item1).NoneParameter().ExecuteAffrows()); + //DmException: ַض + } + class TS_BLB01 + { + public Guid Id { get; set; } + public byte[] Data { get; set; } + } [Fact] public void StringLength() { @@ -238,11 +306,6 @@ namespace FreeSql.Tests.Dameng [Fact] public void CurdAllField() { - var item = new TableAllType { }; - item.Id = (int)insert.AppendData(item).ExecuteIdentity(); - - var newitem = select.Where(a => a.Id == item.Id).ToOne(); - var item2 = new TableAllType { Bool = true, diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolNullableTest.cs index d9b748ac..5932dd22 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolNullableTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/BoolNullableTest.cs @@ -1497,15 +1497,6 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.tostring, find.tostring); Assert.Equal(false, find.tostring); - item = new BoolNullableMap { tostring = null }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - //update all item.tostring = true; Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); @@ -1523,15 +1514,6 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.tostring, find.tostring); Assert.Equal(false, find.tostring); - item.tostring = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.tostring, find.tostring); - Assert.Null(find.tostring); - //update set Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); @@ -1545,17 +1527,9 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.id, find.id); Assert.Equal(false, find.tostring); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); - find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.tostring); - //delete Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); Assert.Null(orm.Select().Where(a => a.id == item.id).First()); } diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/EnumTest.cs index 44e4c52b..2de960fb 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/EnumTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/EnumTest.cs @@ -84,17 +84,9 @@ namespace FreeSql.Tests.DamengMapType { //insert var orm = g.dameng; - var item = new EnumTestMap { }; + var item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); - - item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); Assert.NotNull(find); Assert.Equal(item.id, find.id); Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); @@ -109,15 +101,6 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); - //update set Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); @@ -125,19 +108,10 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.id, find.id); Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); - //delete Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + Assert.NotNull(orm.Select().Where(a => a.id == item.id).First()); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/ToStringTest.cs index fbe05387..f3d35cef 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/ToStringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/MapType/ToStringTest.cs @@ -99,17 +99,9 @@ namespace FreeSql.Tests.DamengMapType { //insert var orm = g.dameng; - var item = new ToStringMap { }; + var item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); - - item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); Assert.NotNull(find); Assert.Equal(item.id, find.id); Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); @@ -124,15 +116,6 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); - item.enumnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); - Assert.Null(find.enumnullable_to_string); - //update set Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); @@ -140,19 +123,10 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.id, find.id); Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); - find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.enumnullable_to_string); - //delete Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + Assert.NotNull(orm.Select().Where(a => a.id == item.id).First()); } [Fact] public void BigInteger1() @@ -216,17 +190,9 @@ namespace FreeSql.Tests.DamengMapType { //insert var orm = g.dameng; - var item = new ToStringMap { }; + var item = new ToStringMap { bigintegernullable_to_string = 101 }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); - - item = new ToStringMap { bigintegernullable_to_string = 101 }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); Assert.NotNull(find); Assert.Equal(item.id, find.id); Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); @@ -241,15 +207,6 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); Assert.Equal(2004, find.bigintegernullable_to_string); - item.bigintegernullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); - Assert.Null(find.bigintegernullable_to_string); - //update set Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); @@ -257,18 +214,9 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.id, find.id); Assert.Equal(998, find.bigintegernullable_to_string); - - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); - Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); - find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.bigintegernullable_to_string); - //delete - Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); Assert.Null(orm.Select().Where(a => a.id == item.id).First()); } [Fact] @@ -513,18 +461,10 @@ namespace FreeSql.Tests.DamengMapType { //insert var orm = g.dameng; - var item = new ToStringMap { }; - Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); - var newid = Guid.NewGuid(); - item = new ToStringMap { guidnullable_to_string = newid }; + var item = new ToStringMap { guidnullable_to_string = newid }; Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); Assert.NotNull(find); Assert.Equal(item.id, find.id); Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); @@ -540,14 +480,6 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); Assert.Equal(newid, find.guidnullable_to_string); - item.guidnullable_to_string = null; - Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); - Assert.Null(find.guidnullable_to_string); - //update set newid = Guid.NewGuid(); Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); @@ -556,14 +488,8 @@ namespace FreeSql.Tests.DamengMapType Assert.Equal(item.id, find.id); Assert.Equal(newid, find.guidnullable_to_string); - Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); - find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); - Assert.NotNull(find); - Assert.Equal(item.id, find.id); - Assert.Null(find.guidnullable_to_string); - //delete - Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); Assert.Null(orm.Select().Where(a => a.id == item.id).First()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 27a3ab52..809cc6a3 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -10,6 +10,94 @@ namespace FreeSql.Tests.MySql { public class MySqlCodeFirstTest { + [Fact] + public void Text_StringLength_1() + { + var str1 = string.Join(",", Enumerable.Range(0, 1000).Select(a => "й")); + + var item1 = new TS_TEXT02 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT02 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT02 + { + public Guid Id { get; set; } + [Column(StringLength = -1)] + public string Data { get; set; } + } + + [Fact] + public void Text() + { + var str1 = string.Join(",", Enumerable.Range(0, 1000).Select(a => "й")); + + var item1 = new TS_TEXT01 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT01 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT01 + { + public Guid Id { get; set; } + [Column(DbType = "text")] + public string Data { get; set; } + } + + [Fact] + public void Text_StringLength_2() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_TEXT04 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT04 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT04 + { + public Guid Id { get; set; } + [Column(StringLength = -2)] + public string Data { get; set; } + } + + [Fact] + public void LongText() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_TEXT03 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT03 { Data = str1 }; + Assert.Equal(1, g.mysql.Insert(item1).NoneParameter().ExecuteAffrows()); + } + class TS_TEXT03 + { + public Guid Id { get; set; } + [Column(DbType = "longtext")] + public string Data { get; set; } + } + [Fact] public void StringLength() { diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 96cc37b5..ae45c75c 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -89,11 +89,11 @@ namespace FreeSql.DataAnnotations /// Oracle -> nvarchar2(100) /// Sqlite -> nvarchar(100) /// --- - /// StringLength = -1 时,对应 DbType: - /// MySql -> text + /// StringLength < 0 时,对应 DbType: + /// MySql -> text (StringLength = -2 时,对应 DbType longtext) /// SqlServer -> nvarchar(max) /// PostgreSQL -> text - /// Oracle -> nvarchar2(4000) + /// Oracle -> nclob /// Sqlite -> text /// public int StringLength { get => _StringLength ?? 0; set => _StringLength = value; } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b9a3434c..97257dce 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -90,11 +90,11 @@ Oracle -> nvarchar2(100) Sqlite -> nvarchar(100) --- - StringLength = -1 时,对应 DbType: - MySql -> text + StringLength < 0 时,对应 DbType: + MySql -> text (StringLength = -2 时,对应 DbType longtext) SqlServer -> nvarchar(max) PostgreSQL -> text - Oracle -> nvarchar2(4000) + Oracle -> nclob Sqlite -> text diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 5841a265..88b3bdf2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1218,12 +1218,12 @@ namespace FreeSql.Internal.CommonProvider break; case DataType.Oracle: case DataType.OdbcOracle: + case DataType.Dameng: + case DataType.OdbcDameng: _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; break; case DataType.Sqlite: break; - case DataType.OdbcDameng: - case DataType.Dameng: case DataType.OdbcKingbaseES: _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; break; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 4d21d6d9..5c036e53 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -232,7 +232,8 @@ namespace FreeSql.Internal { case DataType.MySql: case DataType.OdbcMySql: - if (strlen < 0) colattr.DbType = "TEXT"; + if (strlen == -2) colattr.DbType = "LONGTEXT"; + else if (strlen < 0) colattr.DbType = "TEXT"; else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; case DataType.SqlServer: @@ -250,9 +251,13 @@ namespace FreeSql.Internal if (strlen < 0) colattr.DbType = "NCLOB"; //v1.3.2+ https://github.com/dotnetcore/FreeSql/issues/259 else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; + case DataType.Dameng: + if (strlen < 0) colattr.DbType = "TEXT"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; case DataType.OdbcOracle: case DataType.OdbcDameng: - if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(4000)"); + if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(4000)"); //ODBC 不支持 NCLOB else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; case DataType.Sqlite: diff --git a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs index 67910e61..09cb67f1 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs @@ -15,7 +15,6 @@ namespace FreeSql.Dameng class DamengCodeFirst : Internal.CommonProvider.CodeFirstProvider { - public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } public DamengCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); @@ -310,8 +309,9 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and continue; } var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); - if (string.IsNullOrEmpty(oldpk) == false) - sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); + //if (string.IsNullOrEmpty(oldpk) == false) + // sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(oldpk)).Append("';\r\n"); + //执行失败(语句1) 试图删除聚集主键 //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); @@ -325,7 +325,8 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and } if (tb.Primarys.Any()) { - var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; + if (string.IsNullOrEmpty(oldpk) == false && oldpk == pkname) pkname = $"{pkname}1"; sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); @@ -457,6 +458,15 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and else if (sqlType.StartsWith("BLOB")) { } + else if (sqlType.StartsWith("CLOB")) + { + } + else if (sqlType.StartsWith("NCLOB")) + { + } + else if (sqlType.StartsWith("TEXT")) + { + } else if (sqlType == "REAL" || sqlType == "DOUBLE" || sqlType == "FLOAT") { } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 1440f806..bca00ccd 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -310,8 +310,9 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and continue; } var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); - if (string.IsNullOrEmpty(oldpk) == false) - sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); + //if (string.IsNullOrEmpty(oldpk) == false) + // sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(oldpk)).Append("';\r\n"); + //执行失败(语句1) 试图删除聚集主键 //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); @@ -325,7 +326,8 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and } if (tb.Primarys.Any()) { - var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; + if (string.IsNullOrEmpty(oldpk) == false && oldpk == pkname) pkname = $"{pkname}1"; sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index f1d03da1..8120f32c 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -309,7 +309,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam } var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); if (string.IsNullOrEmpty(oldpk) == false) - sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); + sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(oldpk)).Append("';\r\n"); //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index fbc93fe7..f7236949 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -310,7 +310,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam } var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); if (string.IsNullOrEmpty(oldpk) == false) - sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n"); + sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(oldpk)).Append("';\r\n"); //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); From f4ffcfff7c7fdc944e28ec13306fdb26a96106e5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 9 Jun 2020 14:24:54 +0800 Subject: [PATCH 0685/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=20Not=20=E4=BD=8D=E8=BF=90=E7=AE=97=E7=AC=A6?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF=EF=BC=9B#340?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs | 1 + FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 4 ++++ FreeSql/Internal/CommonExpression.cs | 1 + 3 files changed, 6 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs index df3ff443..bb456652 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs @@ -306,6 +306,7 @@ namespace FreeSql.Tests.Dameng [Fact] public void CurdAllField() { + g.dameng.Delete().Where("1=1").ExecuteAffrows(); var item2 = new TableAllType { Bool = true, diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index e77bb1b4..28ea2939 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -155,6 +155,10 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var tttrule = 8; + var tttid = new long[] { 18, 19, 4017 }; + g.sqlserver.Update().Set(it => it.SongId == (short)(it.SongId & ~tttrule)).Where(it => (it.SongId & tttrule) == tttrule && !tttid.Contains(it.Id)).ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Insert(new Song123(1)).ExecuteAffrows(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 542e7859..c870a2f9 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -580,6 +580,7 @@ namespace FreeSql.Internal { case ExpressionType.Not: var notExp = (exp as UnaryExpression)?.Operand; + if (notExp.Type.IsNumberType()) return $"~{ExpressionLambdaToSql(notExp, tsc)}"; //位操作 if (notExp.NodeType == ExpressionType.MemberAccess) { var notBody = ExpressionLambdaToSql(notExp, tsc); From 6b110a7ba60797474cf2a3e1554792a1f5711795 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 9 Jun 2020 17:17:53 +0800 Subject: [PATCH 0686/1029] update orm_vs for pgsql --- Examples/orm_vs/Program.cs | 81 +++++++++++++++++++++-------------- Examples/orm_vs/orm_vs.csproj | 2 + 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 62c95808..0a1b1ef5 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -18,8 +18,9 @@ namespace orm_vs class Program { static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") - .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=20") + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + //.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=20") + //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=20") .UseAutoSyncStructure(false) .UseNoneCommandParameter(true) //.UseConfigEntityFromDbFirst(true) @@ -29,10 +30,12 @@ namespace orm_vs { get => new SqlSugarClient(new ConnectionConfig() { - //ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", - //DbType = DbType.SqlServer, - ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", - DbType = DbType.MySql, + ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + DbType = DbType.SqlServer, + //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + //DbType = DbType.MySql, + //ConnectionString = "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=21", + //DbType = DbType.PostgreSQL, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute }); @@ -43,16 +46,34 @@ namespace orm_vs public DbSet Songs { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - //optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); - optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); + optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); + //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); + //optionsBuilder.UseNpgsql("Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=21"); } } static void Main(string[] args) { + //fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); + //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements + fsql.CodeFirst.SyncStructure(typeof(Song), "freesql_song"); + fsql.CodeFirst.SyncStructure(typeof(Song), "sugar_song"); + fsql.CodeFirst.SyncStructure(typeof(Song), "efcore_song"); + + fsql.CodeFirst.SyncStructure(typeof(Song_tag), "freesql_song_tag"); + fsql.CodeFirst.SyncStructure(typeof(Song_tag), "sugar_song_tag"); + fsql.CodeFirst.SyncStructure(typeof(Song_tag), "efcore_song_tag"); + + fsql.CodeFirst.SyncStructure(typeof(Tag), "freesql_tag"); + fsql.CodeFirst.SyncStructure(typeof(Tag), "sugar_tag"); + fsql.CodeFirst.SyncStructure(typeof(Tag), "efcore_tag"); + var sb = new StringBuilder(); var time = new Stopwatch(); + var sql222 = fsql.Select().Where(a => DateTime.Now.Subtract(a.create_time.Value).TotalHours > 0).ToSql(); + #region ET test ////var t31 = fsql.Select().ToList(); //fsql.Select().First(); @@ -98,7 +119,7 @@ namespace orm_vs // { // if (locvalue is string) // { - + // } // } // } @@ -342,24 +363,20 @@ namespace orm_vs #endregion - var testlist1 = fsql.Select().OrderBy(a => a.Id).ToList(); + var testlist1 = fsql.Select().OrderBy(a => a.id).ToList(); var testlist2 = new List(); - fsql.Select().OrderBy(a => a.Id).ToChunk(0, list => + fsql.Select().OrderBy(a => a.id).ToChunk(0, list => { testlist2.AddRange(list); }); - - fsql.CodeFirst.SyncStructure(typeof(Song), typeof(Song_tag), typeof(Tag)); - //sugar.CodeFirst.InitTables(typeof(Song), typeof(Song_tag), typeof(Tag)); - //sugar创建表失败:SqlSugar.SqlSugarException: Sequence contains no elements //sugar.Aop.OnLogExecuted = (s, e) => //{ // Trace.WriteLine(s); //}; //测试前清空数据 - fsql.Delete().Where(a => a.Id > 0).ExecuteAffrows(); - sugar.Deleteable().Where(a => a.Id > 0).ExecuteCommand(); + fsql.Delete().Where(a => a.id > 0).ExecuteAffrows(); + sugar.Deleteable().Where(a => a.id > 0).ExecuteCommand(); fsql.Ado.ExecuteNonQuery("delete from efcore_song"); Console.WriteLine("插入性能:"); @@ -469,10 +486,10 @@ namespace orm_vs { var songs = Enumerable.Range(0, size).Select(a => new Song { - Create_time = DateTime.Now, - Is_deleted = false, - Title = $"Insert_{a}", - Url = $"Url_{a}" + create_time = DateTime.Now, + is_deleted = false, + title = $"Insert_{a}", + url = $"Url_{a}" }); //预热 @@ -585,11 +602,11 @@ namespace orm_vs [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - public DateTime? Create_time { get; set; } - public bool? Is_deleted { get; set; } - public string Title { get; set; } - public string Url { get; set; } + public int id { get; set; } + public DateTime? create_time { get; set; } + public bool? is_deleted { get; set; } + public string title { get; set; } + public string url { get; set; } [SugarColumn(IsIgnore = true)] [NotMapped] @@ -600,12 +617,12 @@ namespace orm_vs [Table("efcore_song_tag")] public class Song_tag { - public int Song_id { get; set; } + public int song_id { get; set; } [SugarColumn(IsIgnore = true)] [NotMapped] public virtual Song Song { get; set; } - public int Tag_id { get; set; } + public int tag_id { get; set; } [SugarColumn(IsIgnore = true)] [NotMapped] public virtual Tag Tag { get; set; } @@ -619,14 +636,14 @@ namespace orm_vs [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - public int? Parent_id { get; set; } + public int id { get; set; } + public int? parent_id { get; set; } [SugarColumn(IsIgnore = true)] [NotMapped] public virtual Tag Parent { get; set; } - public decimal? Ddd { get; set; } - public string Name { get; set; } + public decimal? ddd { get; set; } + public string name { get; set; } [SugarColumn(IsIgnore = true)] [NotMapped] diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index c691f109..1a49a72a 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -8,6 +8,7 @@ + @@ -15,6 +16,7 @@ + From 7cc33740544b6d97d208cc048939837967d26cd5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 9 Jun 2020 19:16:39 +0800 Subject: [PATCH 0687/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Expression?= =?UTF-8?q?=20Or/And=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=E5=9C=A8?= =?UTF-8?q?=E5=A4=9A=E8=A1=A8=E4=B8=AD=E5=8F=AF=E8=83=BD=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../Extensions/LambadaExpressionExtensions.cs | 6 +++--- 2 files changed, 3 insertions(+), 19 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/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 1b05dbf1..000a6d72 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -20,9 +20,9 @@ namespace System.Linq.Expressions if (exp1 == null) return exp2; if (exp2 == null) return exp1; - var newParameters = exp1.Parameters.Select((a, b) => Expression.Parameter(a.Type, $"new{b}")).ToArray(); + var newParameters = exp1.Parameters.Select((a, b) => Expression.Parameter(a.Type, a.Name /*$"new{b}"*/)).ToArray(); - var left = new NewExpressionVisitor(newParameters, exp2.Parameters.ToArray()).Replace(exp1.Body); + var left = new NewExpressionVisitor(newParameters, exp1.Parameters.ToArray()).Replace(exp1.Body); var right = new NewExpressionVisitor(newParameters, exp2.Parameters.ToArray()).Replace(exp2.Body); var body = isAndAlso ? Expression.AndAlso(left, right) : Expression.OrElse(left, right); return Expression.Lambda(exp1.Type, body, newParameters); @@ -32,7 +32,7 @@ namespace System.Linq.Expressions if (condition == false) return exp; if (exp == null) return null; - var newParameters = exp.Parameters.Select((a, b) => Expression.Parameter(a.Type, $"new{b}")).ToArray(); + var newParameters = exp.Parameters.Select((a, b) => Expression.Parameter(a.Type, a.Name /*$"new{b}"*/)).ToArray(); var body = Expression.Not(exp.Body); return Expression.Lambda(exp.Type, body, newParameters); } From aa187eb18a7b1b7acbb0cf7dd306ca06a3f79e7c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 9 Jun 2020 19:26:07 +0800 Subject: [PATCH 0688/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IUnitOfWork?= =?UTF-8?q?=20Orm=20=E5=B1=9E=E6=80=A7=E7=9B=B4=E6=8E=A5=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=20IFreeSql=20CRUD=20=E4=BA=8B=E5=8A=A1=E4=B8=8E=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=8D=95=E5=85=83=E4=B8=80=E8=87=B4=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.DbContext/UnitOfWork/IUnitOfWork.cs | 7 ++++--- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 3 +++ .../UnitOfWork/UnitOfWorkManager.cs | 3 +++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index be92522b..db67ee47 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -10,6 +10,7 @@ namespace FreeSql /// public interface IUnitOfWork : IDisposable { + IFreeSql Orm { get; } /// /// 开启事务,或者返回已开启的事务 @@ -27,7 +28,7 @@ namespace FreeSql /// /// 是否启用工作单元 /// - [Obsolete("即将删除(保留到2020-08-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] + [Obsolete("即将删除(保留到2020-12-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] bool Enable { get; } /// @@ -36,13 +37,13 @@ namespace FreeSql /// /// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 /// - [Obsolete("即将删除(保留到2020-08-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] + [Obsolete("即将删除(保留到2020-12-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] void Close(); /// /// 开启工作单元 /// - [Obsolete("即将删除(保留到2020-08-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] + [Obsolete("即将删除(保留到2020-12-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] void Open(); /// diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 941cdac8..7dea638a 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -64,6 +64,9 @@ namespace FreeSql Enable = true; } + DbContextScopedFreeSql _ormScoped; + public IFreeSql Orm => _ormScoped ?? (_ormScoped = DbContextScopedFreeSql.Create(_fsql, null, () => this)); + public IsolationLevel? IsolationLevel { get; set; } public DbTransaction GetOrBeginTransaction(bool isCreate = true) diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs index 428fd7fb..2cf087b3 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs @@ -184,6 +184,7 @@ namespace FreeSql IUnitOfWork _baseUow; internal Action OnDispose; public UnitOfWorkOrginal(IUnitOfWork baseUow) => _baseUow = baseUow; + public IFreeSql Orm => _baseUow.Orm; public IsolationLevel? IsolationLevel { get => _baseUow.IsolationLevel; set => _baseUow.IsolationLevel = value; } public DbContext.EntityChangeReport EntityChangeReport => _baseUow.EntityChangeReport; @@ -205,6 +206,7 @@ namespace FreeSql IUnitOfWork _baseUow; internal Action OnDispose; public UnitOfWorkVirtual(IUnitOfWork baseUow) => _baseUow = baseUow; + public IFreeSql Orm => _baseUow.Orm; public IsolationLevel? IsolationLevel { get => _baseUow.IsolationLevel; set { } } public DbContext.EntityChangeReport EntityChangeReport => _baseUow.EntityChangeReport; @@ -222,6 +224,7 @@ namespace FreeSql internal IFreeSql _fsql; internal Action OnDispose; public UnitOfWorkNothing(IFreeSql fsql) => _fsql = fsql; + public IFreeSql Orm => _fsql; public IsolationLevel? IsolationLevel { get; set; } public DbContext.EntityChangeReport EntityChangeReport { get; } = new DbContext.EntityChangeReport(); From 7cd7e665daf24117b660f5fcd713c727132f619c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 9 Jun 2020 19:35:15 +0800 Subject: [PATCH 0689/1029] v1.6.0-preview0609 #340 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d6cf5e22..aac0fec4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index f508f737..bea96bee 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 3388b4ab..113fe5a6 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 4f3f91c3..3e4591b1 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 575333ba..1a4d7180 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0602 + 1.6.0-preview0609 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3a5d6783..59d69755 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 95f24a56..586caf91 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8e1cdffb..13ecb580 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7c716707..7555a395 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 39cf0ce5..a5d05619 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 948b3006..ec0ab40c 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0a960295..e3e4d84d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 9b137c2e..31eb4b83 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 08a0aa31..d425235b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 53ffb4a7..c3d9e42c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0707f21c..67641a1d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2f5ceced..582ccdd6 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 2569fb0a..55a45749 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0-preview0609 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 49aa899f81ecec555ca13c5444c3775c3ce346f3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 10 Jun 2020 02:07:55 +0800 Subject: [PATCH 0690/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E7=A5=9E?= =?UTF-8?q?=E5=B7=9E=E9=80=9A=E7=94=A8=20ShenTong=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9B#325?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSet.cs | 1 + FreeSql.DbContext/DbSet/DbSetAsync.cs | 2 + FreeSql.DbContext/DbSet/DbSetSync.cs | 2 + FreeSql.DbContext/FreeSql.DbContext.xml | 16 - .../FreeSql.Tests/FreeSql.Tests.csproj | 7 + .../ShenTong/Curd/ShenTongDeleteTest.cs | 105 + .../Curd/ShenTongInsertOrUpdateTest.cs | 323 +++ .../ShenTong/Curd/ShenTongInsertTest.cs | 141 ++ .../ShenTong/Curd/ShenTongSelectTest.cs | 1863 +++++++++++++++++ .../ShenTong/Curd/ShenTongUpdateTest.cs | 189 ++ .../ShenTong/MapType/BoolNullableTest.cs | 1571 ++++++++++++++ .../ShenTong/MapType/BoolTest.cs | 1105 ++++++++++ .../ShenTong/MapType/DateTimeOffSetTest.cs | 54 + .../ShenTong/MapType/EnumTest.cs | 261 +++ .../ShenTong/MapType/ToStringTest.cs | 570 +++++ .../ShenTong/ShenTongAdo/ShenTongAdoTest.cs | 68 + .../FreeSql.Tests/ShenTong/ShenTongAopTest.cs | 40 + .../ShenTong/ShenTongCodeFirstTest.cs | 348 +++ .../ShenTong/ShenTongDbFirstTest.cs | 25 + .../ShenTongExpression/ConvertTest.cs | 169 ++ .../ShenTongExpression/DateTimeTest.cs | 348 +++ .../ShenTong/ShenTongExpression/MathTest.cs | 156 ++ .../ShenTong/ShenTongExpression/OtherTest.cs | 221 ++ .../ShenTong/ShenTongExpression/StringTest.cs | 728 +++++++ .../ShenTongExpression/TimeSpanTest.cs | 293 +++ FreeSql.Tests/FreeSql.Tests/g.cs | 26 + FreeSql.sln | 17 +- FreeSql/DataType.cs | 7 +- FreeSql/FreeSql.xml | 8 +- FreeSql/FreeSqlBuilder.cs | 5 + FreeSql/Interface/Curd/ISelect/ISelect0.cs | 3 +- .../SelectProvider/Select0Provider.cs | 5 +- FreeSql/Internal/UtilsExpressionTree.cs | 1 + .../Curd/OnConflictDoUpdate.cs | 207 ++ .../Curd/ShenTongDelete.cs | 99 + .../Curd/ShenTongInsert.cs | 216 ++ .../Curd/ShenTongInsertOrUpdate.cs | 72 + .../Curd/ShenTongSelect.cs | 174 ++ .../Curd/ShenTongUpdate.cs | 164 ++ .../FreeSql.Provider.ShenTong.csproj | 52 + .../ShenTongAdo/ShenTongAdo.cs | 77 + .../ShenTongAdo/ShenTongConnectionPool.cs | 247 +++ .../ShenTongCodeFirst.cs | 412 ++++ .../ShenTongDbFirst.cs | 513 +++++ .../ShenTongExpression.cs | 571 +++++ .../ShenTongExtensions.cs | 17 + .../ShenTongProvider.cs | 64 + .../ShenTongUtils.cs | 173 ++ Providers/FreeSql.Provider.ShenTong/key.snk | Bin 0 -> 596 bytes .../lib/Mono.Security.dll | Bin 0 -> 282624 bytes .../lib/System.Data.OscarClient.dll | Bin 0 -> 454656 bytes 51 files changed, 11714 insertions(+), 22 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/TimeSpanTest.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/Curd/OnConflictDoUpdate.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj create mode 100644 Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/ShenTongExtensions.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs create mode 100644 Providers/FreeSql.Provider.ShenTong/key.snk create mode 100644 Providers/FreeSql.Provider.ShenTong/lib/Mono.Security.dll create mode 100644 Providers/FreeSql.Provider.ShenTong/lib/System.Data.OscarClient.dll diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 4180e750..a86991d8 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -277,6 +277,7 @@ namespace FreeSql case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: case DataType.OdbcKingbaseES: + case DataType.ShenTong: return true; default: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 52626a89..a88e711e 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -42,6 +42,7 @@ namespace FreeSql case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: case DataType.OdbcKingbaseES: + case DataType.ShenTong: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { await DbContextFlushCommandAsync(); @@ -104,6 +105,7 @@ namespace FreeSql case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: case DataType.OdbcKingbaseES: + case DataType.ShenTong: await DbContextFlushCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 743dfeef..343ea58b 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -41,6 +41,7 @@ namespace FreeSql case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: case DataType.OdbcKingbaseES: + case DataType.ShenTong: if (_tableIdentitys.Length == 1) { DbContextFlushCommand(); @@ -107,6 +108,7 @@ namespace FreeSql case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: case DataType.OdbcKingbaseES: + case DataType.ShenTong: DbContextFlushCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); 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/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 1748585d..96f5e946 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -39,6 +39,7 @@ + @@ -47,6 +48,12 @@ ..\..\Providers\FreeSql.Provider.Dameng\lib\DmProvider\netstandard2.0\DmProvider.dll + + ..\..\Providers\FreeSql.Provider.ShenTong\lib\System.Data.OscarClient.dll + + + ..\..\Providers\FreeSql.Provider.ShenTong\lib\Mono.Security.dll + diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongDeleteTest.cs new file mode 100644 index 00000000..6f07533b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongDeleteTest.cs @@ -0,0 +1,105 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongDeleteTest + { + + IDelete delete => g.shentong.Delete(); + + [Table(Name = "tb_topic_del")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.shentong.Delete().ToSql()); + var sql = g.shentong.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.shentong.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); + + sql = g.shentong.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.shentong.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); + + sql = g.shentong.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.shentong.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + delete.Where(a => a.Id > 0).ExecuteDeleted(); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.shentong.Delete().ToSql()); + var sql = g.shentong.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.shentong.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + + sql = g.shentong.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + + sql = g.shentong.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs new file mode 100644 index 00000000..4efd6731 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs @@ -0,0 +1,323 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongInsertOrUpdateTestpublic + { + IFreeSql fsql => g.shentong; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 2 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ID +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '011' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 2 as ID, '02' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '01' as NAME +UNION ALL + SELECT 2, '02' +UNION ALL + SELECT 3, '03' +UNION ALL + SELECT 4, '04' ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ID, '001' as NAME +UNION ALL + SELECT 2, '002' +UNION ALL + SELECT 3, '003' +UNION ALL + SELECT 4, '004' ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME +UNION ALL + SELECT 2, '02', '02' +UNION ALL + SELECT 3, '03', '03' +UNION ALL + SELECT 4, '04', '04' ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME +UNION ALL + SELECT 2, '02', '002' +UNION ALL + SELECT 3, '03', '003' +UNION ALL + SELECT 4, '04', '004' ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME +UNION ALL + SELECT 2, '02', 0, current_timestamp +UNION ALL + SELECT 3, '03', 0, current_timestamp +UNION ALL + SELECT 4, '04', 0, current_timestamp ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, current_timestamp as CREATETIME +UNION ALL + SELECT 2, '002', 0, current_timestamp +UNION ALL + SELECT 3, '003', 0, current_timestamp +UNION ALL + SELECT 4, '004', 0, current_timestamp ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs new file mode 100644 index 00000000..d036d099 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongInsertTest + { + + IInsert insert => g.shentong.Insert(); + + [Table(Name = "TB_TOPIC_INSERT")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"TITLE\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"TITLE\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + + g.shentong.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.shentong.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.shentong.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "TB_TOPICIGNORECOLUMNS")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + insert.AppendData(items.First()).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"TITLE\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"TITLE\") VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\") VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs new file mode 100644 index 00000000..57b20641 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs @@ -0,0 +1,1863 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongSelectTest + { + + ISelect select => g.shentong.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.shentong.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.shentong.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.shentong.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.shentong.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.shentong.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Single(g.shentong.Insert().AppendData(items.First()).ExecuteInserted()); + Assert.Equal(10, g.shentong.Insert().AppendData(items).ExecuteInserted().Count); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.shentong.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 222"); + var dt3 = select.Limit(10).ToDataTable(a => new { id = a.Id, name2 = a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + var t1 = g.shentong.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t2 = g.shentong.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.shentong.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new + { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.shentong.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.shentong.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.shentong.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.shentong.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.shentong.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.shentong.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.shentong.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.shentong.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.shentong.Select().ToList(); + var testGuidId6 = g.shentong.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.shentong.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.shentong.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.shentong.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.shentong.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = @id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = @id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.shentong.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.shentong.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") + FROM ""TB_TOPIC"" b + limit 1) as6 +FROM ""TB_TOPIC"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") + FROM ""TB_TOPIC"" b + limit 1) as6 +FROM ""TB_TOPIC"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") + FROM ""TB_TOPIC"" b + limit 1) as6 +FROM ""TB_TOPIC"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") + FROM ""TB_TOPIC"" b + limit 1) as6 +FROM ""TB_TOPIC"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC"" a +WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPICASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.shentong.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.shentong.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.shentong.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.shentong.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.shentong.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.shentong.Insert(model4s).ExecuteAffrows()); + + var t0 = g.shentong.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.shentong.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.shentong.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.shentong.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.shentong.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.shentong.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.shentong.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.shentong.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.shentong.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.shentong.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.shentong.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.shentong.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.shentong.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.shentong.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.shentong.Insert(model1).ExecuteIdentity(); + + var t1 = g.shentong.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.shentong.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.shentong.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.shentong.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.shentong.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.shentong.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.shentong.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.shentong.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.shentong.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.shentong.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.shentong.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.shentong.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.shentong.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.shentong.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.shentong.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.shentong.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.shentong.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.shentong.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.shentong.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.shentong.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.shentong.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.shentong.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.shentong.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.shentong.Insert(song3).ExecuteIdentity(); + + g.shentong.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.shentong.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.shentong.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.shentong.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.shentong.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.shentong.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.shentong.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.shentong.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.shentong.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.shentong.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.shentong, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.shentong.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.shentong.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.shentong.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.shentong.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.shentong.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.shentong.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.shentong.Select().Count()); + g.shentong.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.shentong.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.shentong.Select().Count()); + Assert.Equal(3, g.shentong.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.shentong.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.shentong.Select().Count()); + g.shentong.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.shentong.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.shentong.Select().Count()); + Assert.Equal(3, g.shentong.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.shentong.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.shentong.Select().Count()); + g.shentong.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.shentong.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.shentong.Select().Count()); + Assert.Equal(3, g.shentong.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.shentong.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.shentong.Select().Count()); + g.shentong.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.shentong.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.shentong.Select().Count()); + Assert.Equal(5, g.shentong.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.shentong.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.shentong.Select().Count()); + g.shentong.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.shentong.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.shentong.Select().Count()); + Assert.Equal(5, g.shentong.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.shentong.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.shentong.Select().Count()); + g.shentong.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.shentong.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.shentong.Select().Count()); + Assert.Equal(5, g.shentong.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.shentong; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a limit 1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a limit 1 for update", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + [Fact] + public void ToTreeList() + { + var fsql = g.shentong; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京市", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs new file mode 100644 index 00000000..549114dc --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs @@ -0,0 +1,189 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongUpdateTest + { + IUpdate update => g.shentong.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.shentong.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1, \"CREATETIME\" = @p_2 WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = @p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.shentong.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.shentong.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = @p_0, \"CREATETIME\" = @p_1 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = \"CLICKS\" * 10 / 1 WHERE (\"ID\" = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > '2000-01-01 00:00:00.000000' then 1 else 2 end WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + @incrClick WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1 WHERE (\"ID\" = 1)", sql); + sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1 WHERE (\"ID\" = 1)", sql); + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.shentong.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..8da136d8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.ShenTongMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.shentong; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/BoolTest.cs new file mode 100644 index 00000000..d26079a7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.ShenTongMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.shentong; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..88eac7b3 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.ShenTongMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.shentong; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/EnumTest.cs new file mode 100644 index 00000000..8eb15a3f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.ShenTongMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.shentong; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.shentong; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.shentong; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.shentong; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/ToStringTest.cs new file mode 100644 index 00000000..5b964d94 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.ShenTongMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.shentong; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs new file mode 100644 index 00000000..84daa489 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs @@ -0,0 +1,68 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.shentong.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.shentong.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + g.shentong.CodeFirst.SyncStructure(); + var t3 = g.shentong.Ado.Query("select * from xxx"); + + var t4 = g.shentong.Ado.Query<(int, string, string)>("select * from xxx"); + + var t5 = g.shentong.Ado.Query("select * from xxx"); + } + + [Fact] + public void QueryMultipline() + { + g.shentong.CodeFirst.SyncStructure(); + var t3 = g.shentong.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + } + + class xxx + { + public string Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAopTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAopTest.cs new file mode 100644 index 00000000..f737d867 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.shentong.Aop.AuditValue += audit; + + g.shentong.Insert(item).ExecuteAffrows(); + + g.shentong.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs new file mode 100644 index 00000000..23475c9f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs @@ -0,0 +1,348 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongCodeFirstTest + { + [Fact] + public void StringLength() + { + var dll = g.shentong.CodeFirst.GetComparisonDDLStatements(); + g.shentong.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void ı_ֶ() + { + var sql = g.shentong.CodeFirst.GetComparisonDDLStatements<ı>(); + g.shentong.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.shentong.Insert<ı>().NoneParameter().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.shentong.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.shentong.Update<ı>().NoneParameter().SetSource(item).ExecuteAffrows()); + item2 = g.shentong.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.shentong.GetRepository<ı>(); + repo.DbContextOptions.NoneParameter = true; + Assert.Equal(1, repo.Update(item)); + item2 = g.shentong.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.shentong.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] + public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.shentong.CodeFirst.GetComparisonDDLStatements(); + g.shentong.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", false)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + + [Fact] + public void AddField() + { + var sql = g.shentong.CodeFirst.GetComparisonDDLStatements(); + g.shentong.Select(); + + var id = g.shentong.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } + + [Table(Name = "ccc.TopicAddField", OldName = "TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } = "xxx"; + + public int clicks { get; set; } = 10; + //public int name { get; set; } = 3000; + + //[Column(DbType = "varchar(200) not null", OldName = "title")] + //public string title222 { get; set; } = "333"; + + //[Column(DbType = "varchar(200) not null")] + //public string title222333 { get; set; } = "xxx"; + + //[Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] + //public string titleaaa { get; set; } = "fsdf"; + + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.shentong.CodeFirst.GetComparisonDDLStatements(); + g.shentong.Select(); + } + + IInsert insert => g.shentong.Insert(); + ISelect select => g.shentong.Select(); + + [Fact] + public void CurdAllField() + { + //var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql(); + //var sql2 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql(); + + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + //testFieldBoolArray = new[] { true, true, false, false }, + //testFieldBoolArrayNullable = new bool?[] { true, true, null, false, false }, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + //testFieldByteArray = new byte[] { 0, 1, 2, 3, 4, 5, 6 }, + //testFieldByteArrayNullable = new byte?[] { 0, 1, 2, 3, null, 4, 5, 6 }, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + //testFieldBytesArray = new[] { Encoding.UTF8.GetBytes("й"), Encoding.UTF8.GetBytes("й") }, + testFieldDateTime = DateTime.Now, + //testFieldDateTimeArray = new[] { DateTime.Now, DateTime.Now.AddHours(2) }, + //testFieldDateTimeArrayNullable = new DateTime?[] { DateTime.Now, null, DateTime.Now.AddHours(2) }, + testFieldDateTimeNullable = DateTime.Now.AddDays(-1), + testFieldDecimal = 999.99M, + //testFieldDecimalArray = new[] { 999.91M, 999.92M, 999.93M }, + //testFieldDecimalArrayNullable = new decimal?[] { 998.11M, 998.12M, 998.13M }, + testFieldDecimalNullable = 111.11M, + testFieldDouble = 888.88, + //testFieldDoubleArray = new[] { 888.81, 888.82, 888.83 }, + //testFieldDoubleArrayNullable = new double?[] { 888.11, 888.12, null, 888.13 }, + testFieldDoubleNullable = 222.22, + testFieldEnum1 = TableAllTypeEnumType1.e3, + //testFieldEnum1Array = new[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, TableAllTypeEnumType1.e1 }, + //testFieldEnum1ArrayNullable = new TableAllTypeEnumType1?[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, null, TableAllTypeEnumType1.e1 }, + testFieldEnum1Nullable = TableAllTypeEnumType1.e2, + testFieldEnum2 = TableAllTypeEnumType2.f2, + //testFieldEnum2Array = new[] { TableAllTypeEnumType2.f3, TableAllTypeEnumType2.f1 }, + //testFieldEnum2ArrayNullable = new TableAllTypeEnumType2?[] { TableAllTypeEnumType2.f3, null, TableAllTypeEnumType2.f1 }, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 777.77F, + //testFieldFloatArray = new[] { 777.71F, 777.72F, 777.73F }, + //testFieldFloatArrayNullable = new float?[] { 777.71F, 777.72F, null, 777.73F }, + testFieldFloatNullable = 333.33F, + testFieldGuid = Guid.NewGuid(), + //testFieldGuidArray = new[] { Guid.NewGuid(), Guid.NewGuid() }, + //testFieldGuidArrayNullable = new Guid?[] { Guid.NewGuid(), null, Guid.NewGuid() }, + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + //testFieldIntArray = new[] { 1, 2, 3, 4, 5 }, + //testFieldIntArrayNullable = new int?[] { 1, 2, 3, null, 4, 5 }, + testFieldIntNullable = int.MinValue, + testFieldLong = long.MaxValue, + //testFieldLongArray = new long[] { 10, 20, 30, 40, 50 }, + testFieldSByte = sbyte.MaxValue, + //testFieldSByteArray = new sbyte[] { 1, 2, 3, 4, 5 }, + //testFieldSByteArrayNullable = new sbyte?[] { 1, 2, 3, null, 4, 5 }, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + //testFieldShortArray = new short[] { 1, 2, 3, 4, 5 }, + //testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 }, + testFieldShortNullable = short.MinValue, + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + //testFieldStringArray = new[] { "йString1", "йString2", null, "йString3" }, + testFieldTimeSpan = TimeSpan.FromHours(10), + //testFieldTimeSpanArray = new[] { TimeSpan.FromHours(10), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }, + //testFieldTimeSpanArrayNullable = new TimeSpan?[] { TimeSpan.FromHours(10), TimeSpan.FromSeconds(10), null, TimeSpan.FromSeconds(60) }, + testFieldTimeSpanNullable = TimeSpan.FromSeconds(90), + testFieldUInt = uint.MaxValue, + //testFieldUIntArray = new uint[] { 1, 2, 3, 4, 5 }, + //testFieldUIntArrayNullable = new uint?[] { 1, 2, 3, null, 4, 5 }, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + //testFieldULongArray = new ulong[] { 10, 20, 30, 40, 50 }, + //testFieldULongArrayNullable = new ulong?[] { 10, 20, 30, null, 40, 50 }, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + //testFieldUShortArray = new ushort[] { 11, 12, 13, 14, 15 }, + //testFieldUShortArrayNullable = new ushort?[] { 11, 12, 13, null, 14, 15 }, + testFieldUShortNullable = ushort.MinValue, + //testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 }, + testFielLongNullable = long.MinValue + }; + + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); + + var item3 = insert.AppendData(item2).ExecuteInserted().First(); + var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); + newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime testFieldDateTime { get; set; } + + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? testFieldDateTimeNullable { get; set; } + + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + + /* array */ + //public bool[] testFieldBoolArray { get; set; } + //public sbyte[] testFieldSByteArray { get; set; } + //public short[] testFieldShortArray { get; set; } + //public int[] testFieldIntArray { get; set; } + //public long[] testFieldLongArray { get; set; } + //public byte[] testFieldByteArray { get; set; } + //public ushort[] testFieldUShortArray { get; set; } + //public uint[] testFieldUIntArray { get; set; } + //public ulong[] testFieldULongArray { get; set; } + //public double[] testFieldDoubleArray { get; set; } + //public float[] testFieldFloatArray { get; set; } + //public decimal[] testFieldDecimalArray { get; set; } + //public TimeSpan[] testFieldTimeSpanArray { get; set; } + //public DateTime[] testFieldDateTimeArray { get; set; } + //public byte[][] testFieldBytesArray { get; set; } + //public string[] testFieldStringArray { get; set; } + //public Guid[] testFieldGuidArray { get; set; } + + //public bool?[] testFieldBoolArrayNullable { get; set; } + //public sbyte?[] testFieldSByteArrayNullable { get; set; } + //public short?[] testFieldShortArrayNullable { get; set; } + //public int?[] testFieldIntArrayNullable { get; set; } + //public long?[] testFielLongArrayNullable { get; set; } + //public byte?[] testFieldByteArrayNullable { get; set; } + //public ushort?[] testFieldUShortArrayNullable { get; set; } + //public uint?[] testFieldUIntArrayNullable { get; set; } + //public ulong?[] testFieldULongArrayNullable { get; set; } + //public double?[] testFieldDoubleArrayNullable { get; set; } + //public float?[] testFieldFloatArrayNullable { get; set; } + //public decimal?[] testFieldDecimalArrayNullable { get; set; } + //public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; } + //public DateTime?[] testFieldDateTimeArrayNullable { get; set; } + //public Guid?[] testFieldGuidArrayNullable { get; set; } + + //public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; } + //public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; } + //public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; } + //public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs new file mode 100644 index 00000000..e331b44a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs @@ -0,0 +1,25 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongDbFirstTest + { + [Fact] + public void GetDatabases() + { + + var t1 = g.shentong.DbFirst.GetDatabases(); + + } + + [Fact] + public void GetTablesByDatabase() + { + + var t2 = g.shentong.DbFirst.GetTablesByDatabase(g.shentong.DbFirst.GetDatabases()[1]); + + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/ConvertTest.cs new file mode 100644 index 00000000..a0debb15 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTongExpression +{ + public class ConvertTest + { + + ISelect select => g.shentong.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + //data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/DateTimeTest.cs new file mode 100644 index 00000000..a9aa76cf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/DateTimeTest.cs @@ -0,0 +1,348 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTongExpression +{ + public class DateTimeTest + { + + ISelect select => g.shentong.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } = DateTime.Now; + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } = DateTime.Now; + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + + g.shentong.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + } + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/MathTest.cs new file mode 100644 index 00000000..3024b5ac --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTongExpression +{ + public class MathTest + { + + ISelect select => g.shentong.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs new file mode 100644 index 00000000..8c9b039a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs @@ -0,0 +1,221 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using Xunit; + +namespace FreeSql.Tests.ShenTongExpression +{ + public class OtherTest + { + + ISelect select => g.shentong.Select(); + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).Limit(10).ToList(); + var t4 = select.Where(a => !a.testFieldBool).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldBool).Limit(10).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).Limit(10).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).Limit(10).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).Limit(10).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).Limit(10).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).Limit(10).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).Limit(10).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).Limit(10).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).Limit(10).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).Limit(10).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).Limit(10).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).Limit(10).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).Limit(10).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).Limit(10).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).Limit(10).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).Limit(10).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).Limit(10).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).Limit(10).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).Limit(10).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).Limit(10).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).Limit(10).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).Limit(10).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).Limit(10).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).Limit(10).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).Limit(10).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).Limit(10).ToList(); + } + + [Fact] + public void Array() + { + //g.shentong.Aop.CurdAfter = (s, e) => { + // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); + //}; + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList(); + //var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList(); + //var sql121 = select.Where(a => a.testFieldStringArray.Contains("aaa") == false).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToSql(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToSql(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToSql(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + //var sql1111112 = select.ToList(a => inarray); + //var sql1111113 = select.ToList(a => a.testFieldIntArray); + + + //var sql3 = select.Where(a => a.testFieldIntArray.Any()).ToList(); + //var sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList(); + + //var sql5 = select.ToList(a => a.testFieldIntArray.Concat(new[] { 1, 2, 3 })); + + //var sql6 = select.Where(a => a.testFieldIntArray.GetLength(1) > 0).ToList(); + //var sql7 = select.Where(a => a.testFieldIntArray.GetLongLength(1) > 0).ToList(); + //var sql8 = select.Where(a => a.testFieldIntArray.Length > 0).ToList(); + //var sql9 = select.Where(a => a.testFieldIntArray.Count() > 0).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + + ///* array */ + //public bool[] testFieldBoolArray { get; set; } + //public sbyte[] testFieldSByteArray { get; set; } + //public short[] testFieldShortArray { get; set; } + //public int[] testFieldIntArray { get; set; } + //public long[] testFieldLongArray { get; set; } + //public byte[] testFieldByteArray { get; set; } + //public ushort[] testFieldUShortArray { get; set; } + //public uint[] testFieldUIntArray { get; set; } + //public ulong[] testFieldULongArray { get; set; } + //public double[] testFieldDoubleArray { get; set; } + //public float[] testFieldFloatArray { get; set; } + //public decimal[] testFieldDecimalArray { get; set; } + //public TimeSpan[] testFieldTimeSpanArray { get; set; } + //public DateTime[] testFieldDateTimeArray { get; set; } + //public byte[][] testFieldBytesArray { get; set; } + //public string[] testFieldStringArray { get; set; } + //public Guid[] testFieldGuidArray { get; set; } + + //public bool?[] testFieldBoolArrayNullable { get; set; } + //public sbyte?[] testFieldSByteArrayNullable { get; set; } + //public short?[] testFieldShortArrayNullable { get; set; } + //public int?[] testFieldIntArrayNullable { get; set; } + //public long?[] testFielLongArrayNullable { get; set; } + //public byte?[] testFieldByteArrayNullable { get; set; } + //public ushort?[] testFieldUShortArrayNullable { get; set; } + //public uint?[] testFieldUIntArrayNullable { get; set; } + //public ulong?[] testFieldULongArrayNullable { get; set; } + //public double?[] testFieldDoubleArrayNullable { get; set; } + //public float?[] testFieldFloatArrayNullable { get; set; } + //public decimal?[] testFieldDecimalArrayNullable { get; set; } + //public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; } + //public DateTime?[] testFieldDateTimeArrayNullable { get; set; } + //public Guid?[] testFieldGuidArrayNullable { get; set; } + + //public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; } + //public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; } + //public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; } + //public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs new file mode 100644 index 00000000..c3818765 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs @@ -0,0 +1,728 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTongExpression +{ + public class StringTest + { + + ISelect select => g.shentong.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.shentong.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/TimeSpanTest.cs new file mode 100644 index 00000000..00b5e651 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTongExpression +{ + public class TimeSpanTest + { + + ISelect select => g.shentong.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 79f636fc..1fc3ae7d 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -120,4 +120,30 @@ public class g (cmd, traceLog) => Console.WriteLine(traceLog)) .Build()); public static IFreeSql dameng => damengLazy.Value; + + static Lazy shentongLazy = new Lazy(() => + { + var connString = new System.Data.OscarClient.OscarConnectionStringBuilder { + Host = "192.168.164.10", + Port = 2003, + UserName = "SYSDBA", + Password = "szoscar55", + Database = "OSRDB", + Pooling = true, + MaxPoolSize = 2 + }; + return new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.ShenTong, "HOST=192.168.164.10;PORT=2003;DATABASE=OSRDB;USERNAME=SYSDBA;PASSWORD=szoscar55;MAXPOOLSIZE=2") + //.UseConnectionFactory(FreeSql.DataType.ShenTong, () => new System.Data.OscarClient.OscarConnection("HOST=192.168.164.10;PORT=2003;DATABASE=OSRDB;USERNAME=SYSDBA;PASSWORD=szoscar55;MAXPOOLSIZE=2")) + .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) + .Build(); + }); + public static IFreeSql shentong => shentongLazy.Value; } diff --git a/FreeSql.sln b/FreeSql.sln index 0f8259b1..c27f7820 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -78,7 +78,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.Linq", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Dameng", "Providers\FreeSql.Provider.Dameng\FreeSql.Provider.Dameng.csproj", "{E74D90E8-1CBC-4677-817B-1CA05AB97937}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aspnetcore_transaction", "Examples\aspnetcore_transaction\aspnetcore_transaction.csproj", "{07AB0B37-A8B1-4FB1-9259-7B804E369E36}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "aspnetcore_transaction", "Examples\aspnetcore_transaction\aspnetcore_transaction.csproj", "{07AB0B37-A8B1-4FB1-9259-7B804E369E36}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.ShenTong", "Providers\FreeSql.Provider.ShenTong\FreeSql.Provider.ShenTong.csproj", "{938173AF-157F-4040-AED3-171DA1809CAA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -486,6 +488,18 @@ Global {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|x64.Build.0 = Release|Any CPU {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|x86.ActiveCfg = Release|Any CPU {07AB0B37-A8B1-4FB1-9259-7B804E369E36}.Release|x86.Build.0 = Release|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Debug|x64.ActiveCfg = Debug|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Debug|x64.Build.0 = Debug|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Debug|x86.ActiveCfg = Debug|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Debug|x86.Build.0 = Debug|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Release|Any CPU.Build.0 = Release|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Release|x64.ActiveCfg = Release|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Release|x64.Build.0 = Release|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Release|x86.ActiveCfg = Release|Any CPU + {938173AF-157F-4040-AED3-171DA1809CAA}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -514,6 +528,7 @@ Global {57B3F5B0-D46A-4442-8EC6-9A9A784404B7} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} {E74D90E8-1CBC-4677-817B-1CA05AB97937} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {07AB0B37-A8B1-4FB1-9259-7B804E369E36} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {938173AF-157F-4040-AED3-171DA1809CAA} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 2a194b94..0d00c721 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -39,6 +39,11 @@ namespace FreeSql /// /// 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 /// - OdbcKingbaseES + OdbcKingbaseES, + + /// + /// 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 + /// + ShenTong } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 97257dce..a029e482 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -556,6 +556,11 @@ 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 + + + 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null @@ -1367,7 +1372,8 @@ Oracle: for update nowait Sqlite: 无效果 达梦: for update nowait - 人大金仓: for update nowait + 人大金仓: for update nowait + 神通: for update nowait noawait diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 5602f681..f5e63e37 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -239,6 +239,11 @@ namespace FreeSql if (type == null) throwNotFind("FreeSql.Provider.Odbc.dll", "FreeSql.Odbc.KingbaseES.OdbcKingbaseESProvider<>"); break; + case DataType.ShenTong: + type = Type.GetType("FreeSql.ShenTong.ShenTongProvider`1,FreeSql.Provider.ShenTong")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.ShenTong.dll", "FreeSql.ShenTong.ShenTongProvider<>"); + break; + default: throw new Exception("未指定 UseConnectionString 或者 UseConnectionFactory"); } } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index ef2602cb..101503ed 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -285,7 +285,8 @@ namespace FreeSql /// Oracle: for update nowait /// Sqlite: 无效果 /// 达梦: for update nowait - /// 人大金仓: for update nowait + /// 人大金仓: for update nowait + /// 神通: for update /// /// noawait /// diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 88b3bdf2..62b9784d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1214,6 +1214,7 @@ namespace FreeSql.Internal.CommonProvider break; case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; break; case DataType.Oracle: @@ -1224,8 +1225,8 @@ namespace FreeSql.Internal.CommonProvider break; case DataType.Sqlite: break; - case DataType.OdbcKingbaseES: - _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; + case DataType.ShenTong: //神通测试中发现,不支持 nowait + _tosqlAppendContent = " for update"; break; } return this as TSelect; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 5c036e53..b45f3d28 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -244,6 +244,7 @@ namespace FreeSql.Internal case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: case DataType.OdbcKingbaseES: + case DataType.ShenTong: if (strlen < 0) colattr.DbType = "TEXT"; else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/OnConflictDoUpdate.cs new file mode 100644 index 00000000..7857f92f --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/Curd/OnConflictDoUpdate.cs @@ -0,0 +1,207 @@ +using FreeSql.Aop; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.ShenTong.Curd +{ + public class OnConflictDoUpdate where T1 : class + { + internal ShenTongInsert _oscarInsert; + internal ShenTongUpdate _oscarUpdatePriv; + internal ShenTongUpdate _oscarUpdate => _oscarUpdatePriv ?? + (_oscarUpdatePriv = new ShenTongUpdate(_oscarInsert.InternalOrm, _oscarInsert.InternalCommonUtils, _oscarInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } + .NoneParameter().SetSource(_oscarInsert.InternalSource) as ShenTongUpdate); + ColumnInfo[] _columns; + bool _doNothing; + + public OnConflictDoUpdate(IInsert insert, Expression> columns = null) + { + _oscarInsert = insert as ShenTongInsert; + if (_oscarInsert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.ShenTong 特有的功能"); + + if (columns != null) + { + var colsList = new List(); + var cols = _oscarInsert.InternalCommonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); + foreach (var col in _oscarInsert.InternalTable.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name)) + colsList.Add(col); + _columns = colsList.ToArray(); + } + if (_columns == null || _columns.Any() == false) + _columns = _oscarInsert.InternalTable.Primarys; + if (_columns.Any() == false) throw new Exception("OnConflictDoUpdate 功能要求实体类必须设置 IsPrimary 属性"); + } + + protected void ClearData() + { + _oscarInsert.InternalClearData(); + _oscarUpdatePriv = null; + } + + public OnConflictDoUpdate IgnoreColumns(Expression> columns) + { + _oscarUpdate.IgnoreColumns(columns); + return this; + } + public OnConflictDoUpdate UpdateColumns(Expression> columns) + { + _oscarUpdate.UpdateColumns(columns); + return this; + } + public OnConflictDoUpdate IgnoreColumns(string[] columns) + { + _oscarUpdate.IgnoreColumns(columns); + return this; + } + public OnConflictDoUpdate UpdateColumns(string[] columns) + { + _oscarUpdate.UpdateColumns(columns); + return this; + } + + public OnConflictDoUpdate Set(Expression> column, TMember value) + { + _oscarUpdate.Set(column, value); + return this; + } + //由于表达式解析问题,ON CONFLICT("id") DO UPDATE SET 需要指定表别名,如 Set(a => a.Clicks + 1) 解析会失败 + //暂时不开放这个功能,如有需要使用 SetRaw("click = t.click + 1") 替代该操作 + //public OnConflictDoUpdate Set(Expression> exp) + //{ + // _oscarUpdate.Set(exp); + // return this; + //} + public OnConflictDoUpdate SetRaw(string sql) + { + _oscarUpdate.SetRaw(sql); + return this; + } + + public OnConflictDoUpdate DoNothing() + { + _doNothing = true; + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + sb.Append(_oscarInsert.ToSql()).Append("\r\nON CONFLICT("); + for (var a = 0; a < _columns.Length; a++) + { + if (a > 0) sb.Append(", "); + sb.Append(_oscarInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + } + if (_doNothing) + { + sb.Append(") DO NOTHING"); + } + else + { + sb.Append(") DO UPDATE SET\r\n"); + + var sbSetEmpty = _oscarUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _oscarUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_oscarUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _oscarUpdate.InternalSbSetIncr.ToString().Substring(2) : _oscarUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _oscarInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _oscarUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true) + { + var field = _oscarInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(_oscarInsert.InternalCommonUtils.QuoteSqlName(_oscarInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); + } + else if (_oscarInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _oscarUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _oscarUpdate.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _oscarInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = EXCLUDED.").Append(field); + } + ++colidx; + } + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_oscarInsert.InternalTable.Type, _oscarInsert.InternalTable, CurdType.Insert, sql, _oscarInsert.InternalParams); + _oscarInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_oscarInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _oscarInsert.InternalOrm.Ado.ExecuteNonQuery(_oscarInsert.InternalConnection, _oscarInsert.InternalTransaction, CommandType.Text, sql, _oscarInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _oscarInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_oscarInsert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_oscarInsert.InternalTable.Type, _oscarInsert.InternalTable, CurdType.Insert, sql, _oscarInsert.InternalParams); + _oscarInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_oscarInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _oscarInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_oscarInsert.InternalConnection, _oscarInsert.InternalTransaction, CommandType.Text, sql, _oscarInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _oscarInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_oscarInsert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs new file mode 100644 index 00000000..154af784 --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs @@ -0,0 +1,99 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.ShenTong.Curd +{ + + class ShenTongDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public ShenTongDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + +#if net40 +#else + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + this.ClearData(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs new file mode 100644 index 00000000..4c3c144b --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs @@ -0,0 +1,216 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.ShenTong.Curd +{ + + class ShenTongInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public ShenTongInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 206); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 206); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 206); + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs new file mode 100644 index 00000000..f3ec0b2d --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs @@ -0,0 +1,72 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.ShenTong.Curd +{ + + class ShenTongInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public ShenTongInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + if (cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs new file mode 100644 index 00000000..f3393d8e --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs @@ -0,0 +1,174 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.ShenTong.Curd +{ + + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_limit > 0) + sb.Append(" \r\nlimit ").Append(_limit); + if (_skip > 0) + sb.Append(" \r\noffset ").Append(_skip); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs new file mode 100644 index 00000000..28baa171 --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -0,0 +1,164 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.ShenTong.Curd +{ + + class ShenTongUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public ShenTongUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + internal string InternalTableAlias; + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 206); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 206); + + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + var pk = _table.Primarys.First(); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || '+' || "); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || '+' || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + ++pkidx; + } + sb.Append(")"); + } + + protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) + { + if (_noneParameter == false) return; + var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; + if (dbtype == null) return; + + sb.Append("::").Append(dbtype); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj new file mode 100644 index 00000000..75de475b --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -0,0 +1,52 @@ + + + + netstandard2.0;net45;net40 + 1.6.0-preview0602 + true + ncc;YeXiangQin + FreeSql 数据库实现,基于 神州通用数据库 7.0.8 + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM;ShenTong;Oscar;神通;神州通用 + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + + + + + + + + + + + + Always + + + + + + + + + + lib\System.Data.OscarClient.dll + false + + + + + ns20;netstandard20 + + + net40 + + + diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs new file mode 100644 index 00000000..fee92115 --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs @@ -0,0 +1,77 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.OscarClient; +using System.Text; +using System.Threading; + +namespace FreeSql.ShenTong +{ + class ShenTongAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public ShenTongAdo() : base(DataType.ShenTong, null, null) { } + public ShenTongAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.ShenTong, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.ShenTong, connectionFactory); + return; + } + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new ShenTongConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new ShenTongConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is bool || param is bool?) + return (bool)param ? "'t'" : "'f'"; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).TotalSeconds; + else if (param is byte[]) + return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new OscarCommand(); + } + + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + var rawPool = pool as ShenTongConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongConnectionPool.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongConnectionPool.cs new file mode 100644 index 00000000..43c1766b --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongConnectionPool.cs @@ -0,0 +1,247 @@ +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections.Concurrent; +using System.Data; +using System.Data.Common; +using System.Data.OscarClient; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.ShenTong +{ + + class ShenTongConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public ShenTongConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + var policy = new ShenTongConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is OscarException) + { + + if (exception is System.IO.IOException) + { + + base.SetUnavailable(exception); + + } + else if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class ShenTongConnectionPoolPolicy : IPolicy + { + + internal ShenTongConnectionPool _pool; + public string Name { get; set; } = "ShenTong OscarConnection 对象池"; + public int PoolSize { get; set; } = 50; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max(imum)?\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[2].Value, out var poolsize) == false || poolsize <= 0) poolsize = 50; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"MAXPOOLSIZE={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};MAXPOOLSIZE={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min(imum)?\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[2].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new OscarConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + try { if (obj.State != ConnectionState.Closed) obj.Close(); } catch { } + try { (obj as OscarConnection)?.ClearPool(); } catch { } + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs new file mode 100644 index 00000000..7d5d6fd3 --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs @@ -0,0 +1,412 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.OscarClient; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.ShenTong +{ + + class ShenTongCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + + public ShenTongCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + + { typeof(sbyte).FullName, CsToDb.New(OscarDbType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OscarDbType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(short).FullName, CsToDb.New(OscarDbType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OscarDbType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(int).FullName, CsToDb.New(OscarDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OscarDbType.Integer, "int4", "int4", false, true, null) }, + { typeof(long).FullName, CsToDb.New(OscarDbType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OscarDbType.BigInt, "int8", "int8", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(OscarDbType.SmallInt, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OscarDbType.SmallInt, "int2", "int2", false, true, null) }, + { typeof(ushort).FullName, CsToDb.New(OscarDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OscarDbType.Integer, "int4", "int4", false, true, null) }, + { typeof(uint).FullName, CsToDb.New(OscarDbType.BigInt, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OscarDbType.BigInt, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, CsToDb.New(OscarDbType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OscarDbType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, + + { typeof(float).FullName, CsToDb.New(OscarDbType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OscarDbType.Real, "float4", "float4", false, true, null) }, + { typeof(double).FullName, CsToDb.New(OscarDbType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OscarDbType.Double, "float8", "float8", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(OscarDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OscarDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, + + { typeof(string).FullName, CsToDb.New(OscarDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + + { typeof(TimeSpan).FullName, CsToDb.New(OscarDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OscarDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(OscarDbType.TimeStamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OscarDbType.TimeStamp, "timestamp", "timestamp", false, true, null) }, + + { typeof(bool).FullName, CsToDb.New(OscarDbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OscarDbType.Boolean, "bool","bool", null, true, null) }, + { typeof(Byte[]).FullName, CsToDb.New(OscarDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) }, + { typeof(Guid).FullName, CsToDb.New(OscarDbType.Char, "bpchar", "bpchar(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OscarDbType.Char, "bpchar", "bpchar(36)", false, true, null) }, + + }; + + public override DbInfoResult GetDbInfo(Type type) + { + var isarray = type.FullName != "System.Byte[]" && type.IsArray; + var elementType = isarray ? type.GetElementType() : type; + var info = GetDbInfoNoneArray(elementType); + if (info == null) return null; + if (isarray == false) return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue); + var dbtypefull = Regex.Replace(info.dbtypeFull, $@"{info.dbtype}(\s*\([^\)]+\))?", "$0[]").Replace(" NOT NULL", ""); + return new DbInfoResult((int)(info.type | OscarDbType.Array), $"{info.dbtype}[]", dbtypefull, null, Array.CreateInstance(elementType, 0)); + } + CsToDb GetDbInfoNoneArray(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc; + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(OscarDbType.BigInt, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(OscarDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return newItem; + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + var sb = new StringBuilder(); + var seqcols = new List>(); //序列 + + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { "PUBLIC", tbname[0] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { "PUBLIC", tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { "PUBLIC", tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } + //codefirst 不支持表名、模式名、数据库名中带 . + + if (string.Compare(tbname[0], "PUBLIC", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys_namespace where nspname={0}", tbname[0])) == null) //创建模式 + sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from tables a inner join sys_namespace b on b.nspname = a.table_schem where b.nspname || '.' || a.table_name = '{0}.{1}'", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from tables a inner join sys_namespace b on b.nspname = a.table_schem where b.nspname || '.' || a.table_name = '{0}.{1}'", tboldname)) == null) + //旧表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = $"{tbname[0]}_{tbname[1]}_PKEY"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) BINLOG ON;\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql(@" +select +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem > 0 and t.typinput = 'ARRAY_IN' then t2.typname else t.typname end, +case when a.attnotnull then '0' else '1' end as is_nullable, +--e.adsrc, +(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid limit 1) is_identity, +a.attndims, +d.description as comment +from sys_class c +inner join sys_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join sys_type t on t.oid = a.atttypid +left join sys_type t2 on t2.oid = t.typelem +left join sys_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join sys_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join sys_namespace ns on ns.oid = c.relnamespace +inner join sys_namespace ns2 on ns2.oid = t.typnamespace +where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var attndims = int.Parse(string.Concat(a[6])); + var type = string.Concat(a[1]); + var sqlType = string.Concat(a[3]); + var max_length = long.Parse(string.Concat(a[2])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + return new + { + column = string.Concat(a[0]), + sqlType = string.Concat(sqlType), + max_length = long.Parse(string.Concat(a[2])), + is_nullable = string.Concat(a[4]) == "1", + is_identity = string.Concat(a[5]).StartsWith(@"NEXTVAL('") && string.Concat(a[5]).EndsWith(@"'::text)"), + attndims, + comment = string.Concat(a[7]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } + } + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (isCommentChanged) + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); + if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" +select +c.attname, +b.relname, +--case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +0, +case when indisunique = 't' then 1 else 0 end IsUnique +from sys_index a +inner join sys_class b on b.oid = a.indexrelid +inner join sys_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_class d on d.oid = a.indrelid +where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select +d.description +from sys_class a +inner join sys_namespace b on b.oid = a.relnamespace +left join sys_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') and a.relkind in ('r') and b.nspname = {0} and a.relname = {1} +and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS')", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select sys_constraint.conname as pk_name from sys_constraint +inner join sys_class on sys_constraint.conrelid = sys_class.oid +inner join sys_namespace on sys_namespace.oid = sys_class.relnamespace +where sys_namespace.nspname={0} and sys_class.relname={1} and sys_constraint.contype='p' +", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) BINLOG ON;\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"coalesce({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_seq").ToUpper(); ; + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); + sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); + if (seqcol.Item3) + { + sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT NEXTVAL('").Append(seqname).Append("'::text);\r\n"); + sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); + } + } + return sb.Length == 0 ? null : sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs new file mode 100644 index 00000000..dcea104e --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs @@ -0,0 +1,513 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.OscarClient; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.ShenTong +{ + class ShenTongDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public ShenTongDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetOscarDbType(column); + OscarDbType GetOscarDbType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + var isarray = dbtype.EndsWith("[]"); + if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); + OscarDbType ret = OscarDbType.Oidvector; + switch (dbtype.ToLower().TrimStart('_')) + { + case "int2": ret = OscarDbType.SmallInt; break; + case "int4": ret = OscarDbType.Integer; break; + case "int8": ret = OscarDbType.BigInt; break; + case "numeric": ret = OscarDbType.Numeric; break; + case "float4": ret = OscarDbType.Real; break; + case "float8": ret = OscarDbType.Double; break; + + case "bpchar": ret = OscarDbType.Char; break; + case "varchar": ret = OscarDbType.VarChar; break; + case "text": ret = OscarDbType.Text; break; + + case "timestamp": ret = OscarDbType.TimeStamp; break; + case "timestamptz": ret = OscarDbType.TimestampTZ; break; + case "date": ret = OscarDbType.Date; break; + case "time": ret = OscarDbType.Time; break; + case "timetz": ret = OscarDbType.TimeTZ; break; + case "interval": ret = OscarDbType.Interval; break; + + case "bool": ret = OscarDbType.Boolean; break; + case "bytea": ret = OscarDbType.Bytea; break; + case "bit": ret = OscarDbType.Bit; break; + + case "uuid": ret = OscarDbType.Char; break; + } + return isarray ? (ret | OscarDbType.Array) : ret; + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)OscarDbType.SmallInt, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)OscarDbType.Integer, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)OscarDbType.BigInt, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)OscarDbType.Numeric, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)OscarDbType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)OscarDbType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + + { (int)OscarDbType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OscarDbType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)OscarDbType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)OscarDbType.TimeStamp, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OscarDbType.TimestampTZ, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OscarDbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)OscarDbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)OscarDbType.TimeTZ, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)OscarDbType.Interval, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + + { (int)OscarDbType.Boolean, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)OscarDbType.Bytea, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + /*** array ***/ + + { (int)(OscarDbType.SmallInt | OscarDbType.Array), new DbToCs("(short[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "short[]", typeof(short[]), typeof(short[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Integer | OscarDbType.Array), new DbToCs("(int[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "int[]", typeof(int[]), typeof(int[]), "{0}", "GetValue") }, + { (int)(OscarDbType.BigInt | OscarDbType.Array), new DbToCs("(long[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "long[]", typeof(long[]), typeof(long[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Numeric | OscarDbType.Array), new DbToCs("(decimal[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "decimal[]", typeof(decimal[]), typeof(decimal[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Real | OscarDbType.Array), new DbToCs("(float[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "float[]", typeof(float[]), typeof(float[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Double | OscarDbType.Array), new DbToCs("(double[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "double[]", typeof(double[]), typeof(double[]), "{0}", "GetValue") }, + + { (int)(OscarDbType.Char | OscarDbType.Array), new DbToCs("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, + { (int)(OscarDbType.VarChar | OscarDbType.Array), new DbToCs("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Text | OscarDbType.Array), new DbToCs("(string[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "string[]", typeof(string[]), typeof(string[]), "{0}", "GetValue") }, + + { (int)(OscarDbType.TimeStamp | OscarDbType.Array), new DbToCs("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, + { (int)(OscarDbType.TimestampTZ | OscarDbType.Array), new DbToCs("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Date | OscarDbType.Array), new DbToCs("(DateTime[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "DateTime[]", typeof(DateTime[]), typeof(DateTime[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Time | OscarDbType.Array), new DbToCs("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, + { (int)(OscarDbType.TimeTZ | OscarDbType.Array), new DbToCs("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Interval | OscarDbType.Array), new DbToCs("(TimeSpan[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "TimeSpan[]", typeof(TimeSpan[]), typeof(TimeSpan[]), "{0}", "GetValue") }, + + { (int)(OscarDbType.Boolean | OscarDbType.Array), new DbToCs("(bool[])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "bool[]", typeof(bool[]), typeof(bool[]), "{0}", "GetValue") }, + { (int)(OscarDbType.Bytea | OscarDbType.Array), new DbToCs("(byte[][])", "JsonConvert.DeserializeObject({0})", "JsonConvert.SerializeObject({0})", "byte[][]", typeof(byte[][]), typeof(byte[][]), "{0}", "GetValue") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select datname from sys_database"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public List GetTablesByDatabase(params string[] database) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + var tables = new List(); + + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = $@" +select +b.nspname || '.' || a.tablename, +a.schemaname, +a.tablename , +d.description, +'TABLE' +from sys_tables a +inner join sys_namespace b on b.nspname = a.schemaname +inner join sys_class c on c.relnamespace = b.oid and c.relname = a.tablename +left join sys_description d on d.objoid = c.oid and objsubid = 0 +where a.schemaname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') +and b.nspname || '.' || a.tablename not in ('PUBLIC.SPATIAL_REF_SYS') + +union all + +select +b.nspname || '.' || a.relname, +b.nspname, +a.relname, +d.description, +'VIEW' +from sys_class a +inner join sys_namespace b on b.oid = a.relnamespace +left join sys_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') and a.relkind in ('m','v') +and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS') +"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = $@" +select +ns.nspname || '.' || c.relname as id, +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem = 0 then t.typname else t2.typname end, +case when a.attnotnull then 0 else 1 end as is_nullable, +--e.adsrc as is_identity, pg12以下 +(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid limit 1) is_identity, +d.description as comment, +a.attndims, +case when t.typelem = 0 then t.typtype else t2.typtype end, +ns2.nspname, +a.attnum +from sys_class c +inner join sys_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join sys_type t on t.oid = a.atttypid +left join sys_type t2 on t2.oid = t.typelem +left join sys_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join sys_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join sys_namespace ns on ns.oid = c.relnamespace +inner join sys_namespace ns2 on ns2.oid = t.typnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")}"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var position = 0; + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var type = string.Concat(row[2]); + var max_length = int.Parse(string.Concat(row[3])); + var sqlType = string.Concat(row[4]); + var is_nullable = string.Concat(row[5]) == "1"; + var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && string.Concat(row[6]).EndsWith(@"'::REGCLASS)"); + var comment = string.Concat(row[7]); + var defaultValue = string.Concat(row[6]); + int attndims = int.Parse(string.Concat(row[8])); + string typtype = string.Concat(row[9]); + string owner = string.Concat(row[10]); + int attnum = int.Parse(string.Concat(row[11])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (max_length <= 0) max_length = -1; + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + if (max_length > 0) + { + switch (sqlType.ToLower()) + { + //case "numeric": sqlType += $"({max_length})"; break; + case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; + } + } + + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Coment = comment, + DefaultValue = defaultValue, + Position = ++position + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } + + sql = $@" +select +ns.nspname || '.' || d.relname as table_id, +c.attname, +b.relname as index_id, +case when a.indisunique then 1 else 0 end IsUnique, +case when a.indisprimary then 1 else 0 end IsPrimary, +case when a.indisclustered then 0 else 1 end IsClustered, +case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +a.indkey::text, +c.attnum +from sys_index a +inner join sys_class b on b.oid = a.indexrelid +inner join sys_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_class d on d.oid = a.indrelid +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var index_id = string.Concat(row[2]); + var is_unique = string.Concat(row[3]) == "1"; + var is_primary_key = string.Concat(row[4]) == "1"; + var is_clustered = string.Concat(row[5]) == "1"; + var is_desc = string.Concat(row[6]) == "1"; + var inkey = string.Concat(row[7]).Split(' '); + var attnum = int.Parse(string.Concat(row[8])); + attnum = int.Parse(inkey[attnum - 1]); + foreach (string tc in loc3[object_id].Keys) + { + if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) + { + column = tc; + break; + } + } + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + var loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } + + sql = $@" +select +ns.nspname || '.' || b.relname as table_id, +array(select attname from sys_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, +a.conname as FKId, +ns2.nspname || '.' || c.relname as ref_table_id, +1 as IsForeignKey, +array(select attname from sys_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, +null ref_sln, +null ref_table +from sys_constraint a +inner join sys_class b on b.oid = a.conrelid +inner join sys_class c on c.oid = a.confrelid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_namespace ns2 on ns2.oid = c.relnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } + + public class GetEnumsByDatabaseQueryInfo + { + public string name { get; set; } + public string label { get; set; } + } + public List GetEnumsByDatabase(params string[] database) + { + if (database == null || database.Length == 0) return new List(); + var drs = _orm.Ado.Query(CommandType.Text, _commonUtils.FormatSql(@" +select +ns.nspname || '.' || a.typname AS name, +b.enumlabel AS label +from sys_type a +inner join sys_enum b on b.enumtypid = a.oid +inner join sys_namespace ns on ns.oid = a.typnamespace +where a.typtype = 'e' and ns.nspname in (SELECT schema_name FROM information_schema.schemata where catalog_name in {0})", database)); + var ret = new Dictionary>(); + foreach (var dr in drs) + { + if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); + var key = dr.label; + if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) + key = $"Unkown{ret[dr.name].Count + 1}"; + if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); + } + return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs new file mode 100644 index 00000000..35e04a67 --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -0,0 +1,571 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.ShenTong +{ + class ShenTongExpression : CommonExpression + { + + public ShenTongExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(operandExp)})::text not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(operandExp)})::int2"; + case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.Decimal": return $"({getExp(operandExp)})::numeric"; + case "System.Double": return $"({getExp(operandExp)})::float8"; + case "System.Int16": return $"({getExp(operandExp)})::int2"; + case "System.Int32": return $"({getExp(operandExp)})::int4"; + case "System.Int64": return $"({getExp(operandExp)})::int8"; + case "System.SByte": return $"({getExp(operandExp)})::int2"; + case "System.Single": return $"({getExp(operandExp)})::float4"; + case "System.String": return $"({getExp(operandExp)})::text"; + case "System.UInt16": return $"({getExp(operandExp)})::int2"; + case "System.UInt32": return $"({getExp(operandExp)})::int4"; + case "System.UInt64": return $"({getExp(operandExp)})::int8"; + case "System.Guid": return $"({getExp(operandExp)})::bpchar(36)"; + } + } + break; + case ExpressionType.ArrayLength: + var arrOperExp = getExp((exp as UnaryExpression).Operand); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::text not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; + case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; + case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; + case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.Guid": return $"({getExp(callExp.Arguments[0])})::bpchar(36)"; + } + break; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int8"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + string left = null; + switch (callExp.Method.Name) + { + case "Any": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; + case "Contains": + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + //判断 in 或 array @> array + if (left.StartsWith("array[") || left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + args1 = $"array[{args1}]"; + if (objExp != null) + { + var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); + if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; + } + return $"({left} @> {args1})"; + case "Concat": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + var right2 = getExp(callExp.Arguments[argIndex]); + if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; + return $"({left} || {right2})"; + case "GetLength": + case "GetLongLength": + case "Length": + case "Count": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + break; + case ExpressionType.MemberAccess: + var memExp = exp as MemberExpression; + var memParentExp = memExp.Expression?.Type; + if (memParentExp?.FullName == "System.Byte[]") return null; + if (memParentExp != null) + { + if (memParentExp.IsArray == true) + { + var left = getExp(memExp.Expression); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + switch (memExp.Member.Name) + { + case "Length": + case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("array["); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append("]").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "date_trunc('D',current_date)"; + case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; + case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"date_trunc('D',{left})"; + case "TimeOfDay": return $"datediff('second',date_trunc('D',{left}),{left})"; + case "DayOfWeek": return $"(dayofweek({left})-1)"; + case "Day": return $"dayofmonth({left})"; + case "DayOfYear": return $"dayofyear({left})"; + case "Month": return $"month({left})"; + case "Year": return $"year({left})"; + case "Hour": return $"hour({left})"; + case "Minute": return $"minute({left})"; + case "Second": return $"second({left})"; + case "Millisecond": return $"(datepart(millisecond,{left})-datepart(second,{left})*1000)"; + case "Ticks": return $"(datediff('second','1970-1-1',{left})::int8*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{60 * 60}%24)"; + case "Milliseconds": return $"(({left})::int8*1000)"; + case "Minutes": return $"floor(({left})/60%60)"; + case "Seconds": return $"(({left})%60)"; + case "Ticks": return $"(({left})::int8*10000000)"; + case "TotalDays": return $"(({left})/{60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{60 * 60})"; + case "TotalMilliseconds": return $"(({left})::int8*1000)"; + case "TotalMinutes": return $"(({left})/60)"; + case "TotalSeconds": return $"({left})"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + var likeOpt = "LIKE"; + if (exp.Arguments.Count > 1) + { + if (exp.Arguments[1].Type == typeof(bool) || + exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::text || '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + var trimArg1 = ""; + var trimArg2 = ""; + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + var trimChr = getExp(argsTrim01).Trim('\''); + if (trimChr.Length == 1) trimArg1 += trimChr; + else trimArg2 += $" || ({trimChr})"; + } + } + if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::text)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"dayofmonth(dateadd('day',-1,dateadd('month',1,({getExp(exp.Arguments[0])})::text||'-'||({getExp(exp.Arguments[1])})::text||'-1')))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; + + case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"dateadd('second',{args1},{left})"; + case "AddDays": return $"dateadd('day',{args1},{left})"; + case "AddHours": return $"dateadd('hour',{args1},{left})"; + case "AddMilliseconds": return $"dateadd('second',({args1})/1000,{left})"; + case "AddMinutes": return $"dateadd('minute',{args1},{left})"; + case "AddMonths": return $"dateadd('month',{args1},{left})"; + case "AddSeconds": return $"dateadd('second', {args1}, {left})"; + case "AddTicks": return $"dateadd('second',({args1})/10000000,{left})"; + case "AddYears": return $"dateadd('year',{args1},{left})"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"datediff('second',{args1},{left})"; + case "System.TimeSpan": return $"dateadd('second',({args1})*-1,{left})"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"datediff('second',{args1},{left})"; + case "ToString": + if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + } + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; + case "FromSeconds": return $"({getExp(exp.Arguments[0])})"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; + case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"({left})::text"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::text not in ('0','false','f','no'))"; + case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; + case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; + case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; + case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; + case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; + case "ToString": return $"({getExp(exp.Arguments[0])})::text"; + case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExtensions.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExtensions.cs new file mode 100644 index 00000000..69d2f475 --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExtensions.cs @@ -0,0 +1,17 @@ +using FreeSql; +using FreeSql.ShenTong.Curd; +using System; +using System.Linq.Expressions; + +public static partial class FreeSqlShenTongGlobalExtensions +{ + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatShenTong(this string that, params object[] args) => _shentongAdo.Addslashes(that, args); + static FreeSql.ShenTong.ShenTongAdo _shentongAdo = new FreeSql.ShenTong.ShenTongAdo(); +} diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs new file mode 100644 index 00000000..25f30f08 --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using FreeSql.ShenTong.Curd; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq.Expressions; +using System.Net; +using System.Net.NetworkInformation; +using System.Threading; + +namespace FreeSql.ShenTong +{ + + public class ShenTongProvider : IFreeSql + { + public ISelect Select() where T1 : class => new ShenTongSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new ShenTongSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new ShenTongInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new ShenTongUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new ShenTongUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new ShenTongDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new ShenTongDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new ShenTongInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst => throw new NotImplementedException("正在支持中"); + public ShenTongProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new ShenTongUtils(this); + this.InternalCommonExpression = new ShenTongExpression(this.InternalCommonUtils); + + this.Ado = new ShenTongAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + //this.DbFirst = new ShenTongDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new ShenTongCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + + ~ShenTongProvider() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs new file mode 100644 index 00000000..227d7c13 --- /dev/null +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs @@ -0,0 +1,173 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.OscarClient; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Text; + +namespace FreeSql.ShenTong +{ + + class ShenTongUtils : CommonUtils + { + public ShenTongUtils(IFreeSql orm) : base(orm) + { + } + + static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) + { + var valueArr = value as Array; + var len = valueArr.GetLength(0); + var ret = Array.CreateInstance(arrayType, len); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); + } + return ret; + } + static Dictionary> dicGetParamterValue = new Dictionary> { + { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, + { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, + { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, + { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + }; + static object getParamterValue(Type type, object value, int level = 0) + { + if (type.FullName == "System.Byte[]") return value; + if (type.IsArray && level == 0) + { + var elementType = type.GetElementType(); + Type enumType = null; + if (elementType.IsEnum) enumType = elementType; + else if (elementType.IsNullableType()) + { + var genericTypesFirst = elementType.GetGenericArguments().First(); + if (genericTypesFirst.IsEnum) enumType = genericTypesFirst; + } + if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()); + return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; + } + if (type.IsNullableType()) type = type.GetGenericArguments().First(); + if (type.IsEnum) return (int)value; + if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); + return value; + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value != null) value = getParamterValue(type, value); + var ret = new OscarParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OscarDbType = (OscarDbType)tp.Value; + if (col != null) + { + var dbtype = (OscarDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText }); + if (dbtype != OscarDbType.Oidvector) + { + ret.OscarDbType = dbtype; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + } + } + //} + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => + { + if (value != null) value = getParamterValue(type, value); + var ret = new OscarParameter { ParameterName = $"@{name}", Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.OscarDbType = (OscarDbType)tp.Value; + //} + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatShenTong(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); + public override string QuoteParamterName(string name) => $"@{name}"; + public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "current_timestamp"; + public override string NowUtc => "(current_timestamp at time zone 'UTC')"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + value = getParamterValue(type, value); + var type2 = value.GetType(); + if (type2 == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + var hh = Math.Min(24, (int)Math.Floor(ts.TotalHours)); + if (hh >= 24) hh = 0; + value = $"{hh}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; + } + else if (value is Array) + { + var valueArr = value as Array; + var eleType = type2.GetElementType(); + var len = valueArr.GetLength(0); + var sb = new StringBuilder().Append("ARRAY["); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + if (a > 0) sb.Append(","); + sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + } + sb.Append("]"); + var dbinfo = _orm.CodeFirst.GetDbInfo(type); + if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype); + return sb.ToString(); + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.ShenTong/key.snk b/Providers/FreeSql.Provider.ShenTong/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..be1149357b2060cb16aa173fa54ed5712e14d886 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098e+`w>!pw~z{kC)(11aic*UA-FJmj*Dw%pGP3~em+rOVqNP@MPQ<0SE0Jw z18wO2D&7?q5r~)y-xHI!=Z`X~3NABfxO*Rt(RKB5xZ1m4DrJj|kVnrZK!68?r~F(^ zF8&@B#vuvJ#~ISY*N$A>FP8GV$Gww<4lAIG`fLSf8o=U$8Q2V1Dw!uRoO@@IXo{{& zGRd>cseR-YBR9`Y3Sh=ZL3z~q?`Grcb>lHDLxwW3}jwu`6-eT*nfH1(XM}Q}C z10NXPe~;ciLC3eO6W_Y0G5RRIAI`cz)T{=Wk%f7<+bDoBRp}Jl!>1+*GaI5un*m5A zkcb_mp6S*!@b5a)>R_yLok1277f`x;0vtz@?PY`FIKqT%3pJ(P8dH+sTWP4`7ovcs zP!O_$q&X`AkNRQULp(?74(v}<+FqM*HT3bo-qLW6n9X*AD6e%;#Z)6<@>~y2hlubU z`Y}D>OQ(AcS4{b1_FAgVBYrD+k!dUgJF0}jGb`A|sl|+^Ai@M&x=dhq`GiOJT&(@p zSnV_FdZQ_y4H|c{MA$s3-uJ>b`BkX%wA!qSd{u8a`l*9Q;gOChlC^WMd@Ts92&B^Q iBbsxrKxd~B8LVo7`w{*T8NJ6Jg9$1yt#;1QpFdUzz91$5 literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.ShenTong/lib/Mono.Security.dll b/Providers/FreeSql.Provider.ShenTong/lib/Mono.Security.dll new file mode 100644 index 0000000000000000000000000000000000000000..6accde79112f9dec05ca6faf540f9f8f16cbe481 GIT binary patch literal 282624 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%0AntS9A%ww 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%0DRJ0X5BgE4dU*BxAX-~e7=Ax-aEg| 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
Zl4A2)gkl|ov#WxYyTbSy{QR0;^ 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%0A~*%!r&l;H*7_(z#ef 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

sEC$+=7I=VvHI~u$^=dZ#` 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%0D%!WrJpg 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

0yD&}im1*}!YV$5rREoE$V^f2=}V5fRu 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

H(WMul8a)}DlDHuS{b!qVSa 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 Yz$^x4F))jPSq#i#U={=apJU+v0sdcDM*si- literal 0 HcmV?d00001 From 19f97d5d76c5b424f6a1f3988826c7f06d619411 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 10 Jun 2020 02:08:36 +0800 Subject: [PATCH 0691/1029] update readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index e997a53e..510992f8 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 丰富的表达式函数,以及灵活的自定义解析; - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; - [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; -- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access; +- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access; ## 📚 Documentation From 91b652c19166ab5713bd12935676083ad2b094a3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 10 Jun 2020 15:17:58 +0800 Subject: [PATCH 0692/1029] =?UTF-8?q?-=20=E5=AE=8C=E6=88=90=20=E7=A5=9E?= =?UTF-8?q?=E9=80=9A=E6=95=B0=E6=8D=AE=E5=BA=93=E6=89=80=E6=9C=89=E9=80=82?= =?UTF-8?q?=E9=85=8D=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++ .../ShenTong/ShenTongDbFirstTest.cs | 2 +- FreeSql/FreeSql.xml | 2 +- Providers/FreeSql.Provider.Odbc/readme.md | 2 +- .../ShenTongDbFirst.cs | 107 ++++++------------ .../ShenTongProvider.cs | 4 +- 6 files changed, 57 insertions(+), 76 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + +

+ 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs index e331b44a..c7d757f5 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.ShenTong public void GetTablesByDatabase() { - var t2 = g.shentong.DbFirst.GetTablesByDatabase(g.shentong.DbFirst.GetDatabases()[1]); + var t2 = g.shentong.DbFirst.GetTablesByDatabase(g.shentong.DbFirst.GetDatabases()[0]); } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a029e482..7f3b7221 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1373,7 +1373,7 @@ Sqlite: 无效果 达梦: for update nowait 人大金仓: for update nowait - 神通: for update nowait + 神通: for update noawait diff --git a/Providers/FreeSql.Provider.Odbc/readme.md b/Providers/FreeSql.Provider.Odbc/readme.md index 68529582..dc698f7c 100644 --- a/Providers/FreeSql.Provider.Odbc/readme.md +++ b/Providers/FreeSql.Provider.Odbc/readme.md @@ -1,6 +1,6 @@ FreeSql.Provider.Odbc 实现 ODBC 访问数据库,ODBC 属于比较原始的技术,更新慢,各大数据库厂支持得标准不一,不到万不得已最好别用 odbc,坑比较多。 -FreeSql.Provider.Odbc 做了四种数据库的专用实现:SqlServer、PostgreSQL、Oracle、MySql,和一种通用实现。 +FreeSql.Provider.Odbc 做了四种数据库的专用实现:SqlServer、PostgreSQL、Oracle、MySql、达梦、人大金仓,和一种通用实现。 专用实现比较有针对性,和原来的 FreeSql.Provider.SqlServer ado.net 相比,只支持较少的基础类型,其他功能几乎都有,包括 CodeFirst 自动迁移。 diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs index dcea104e..a79c01ae 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs @@ -143,17 +143,16 @@ namespace FreeSql.ShenTong var sql = $@" select -b.nspname || '.' || a.tablename, -a.schemaname, -a.tablename , +b.nspname || '.' || a.relname, +b.nspname, +a.relname, d.description, 'TABLE' -from sys_tables a -inner join sys_namespace b on b.nspname = a.schemaname -inner join sys_class c on c.relnamespace = b.oid and c.relname = a.tablename -left join sys_description d on d.objoid = c.oid and objsubid = 0 -where a.schemaname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') -and b.nspname || '.' || a.tablename not in ('PUBLIC.SPATIAL_REF_SYS') +from sys_class a +inner join sys_namespace b on b.oid = a.relnamespace +left join sys_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') and a.relkind in ('r') +and b.nspname || '.' || a.relname not in ('PUBLIC.SPATIAL_REF_SYS') union all @@ -167,7 +166,7 @@ from sys_class a inner join sys_namespace b on b.oid = a.relnamespace left join sys_description d on d.objoid = a.oid and objsubid = 0 where b.nspname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') and a.relkind in ('m','v') -and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS') +and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS','PUBLIC.DBA_JOBS') "; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -260,7 +259,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && string.Concat(row[6]).EndsWith(@"'::REGCLASS)"); + var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && string.Concat(row[6]).EndsWith(@"'::text)"); var comment = string.Concat(row[7]); var defaultValue = string.Concat(row[6]); int attndims = int.Parse(string.Concat(row[8])); @@ -314,8 +313,9 @@ b.relname as index_id, case when a.indisunique then 1 else 0 end IsUnique, case when a.indisprimary then 1 else 0 end IsPrimary, case when a.indisclustered then 0 else 1 end IsClustered, -case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, -a.indkey::text, +--case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +0, +a.indkey, c.attnum from sys_index a inner join sys_class b on b.oid = a.indexrelid @@ -385,50 +385,41 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname") sql = $@" select -ns.nspname || '.' || b.relname as table_id, -array(select attname from sys_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, -a.conname as FKId, -ns2.nspname || '.' || c.relname as ref_table_id, -1 as IsForeignKey, -array(select attname from sys_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, -null ref_sln, -null ref_table -from sys_constraint a -inner join sys_class b on b.oid = a.conrelid -inner join sys_class c on c.oid = a.confrelid -inner join sys_namespace ns on ns.oid = b.relnamespace -inner join sys_namespace ns2 on ns2.oid = c.relnamespace -where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} +a.pktable_schem || '.' || a.pktable_name, +a.pkcolumn_name, +a.fk_name, +a.fktable_schem || '.' || a.fktable_name, +1, +a.fkcolumn_name +from v_sys_foreign_keys a +where {loc8.ToString().Replace("a.table_name", "a.pktable_schem || '.' || a.pktable_name")} "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; var fkColumns = new Dictionary>(); - foreach (object[] row in ds) + foreach (var row in ds) { - var table_id = string.Concat(row[0]); - var column = row[1] as string[]; - var fk_id = string.Concat(row[2]); - var ref_table_id = string.Concat(row[3]); - var is_foreign_key = string.Concat(row[4]) == "1"; - var referenced_column = row[5] as string[]; - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); - + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; Dictionary loc12 = null; DbForeignInfo loc13 = null; if (!fkColumns.TryGetValue(table_id, out loc12)) fkColumns.Add(table_id, loc12 = new Dictionary()); if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); - - for (int a = 0; a < column.Length; a++) - { - loc13.Columns.Add(loc3[table_id][column[a]]); - loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); - } + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); } foreach (var table_id in fkColumns.Keys) foreach (var fk in fkColumns[table_id]) @@ -482,32 +473,6 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname") return tables; } - public class GetEnumsByDatabaseQueryInfo - { - public string name { get; set; } - public string label { get; set; } - } - public List GetEnumsByDatabase(params string[] database) - { - if (database == null || database.Length == 0) return new List(); - var drs = _orm.Ado.Query(CommandType.Text, _commonUtils.FormatSql(@" -select -ns.nspname || '.' || a.typname AS name, -b.enumlabel AS label -from sys_type a -inner join sys_enum b on b.enumtypid = a.oid -inner join sys_namespace ns on ns.oid = a.typnamespace -where a.typtype = 'e' and ns.nspname in (SELECT schema_name FROM information_schema.schemata where catalog_name in {0})", database)); - var ret = new Dictionary>(); - foreach (var dr in drs) - { - if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); - var key = dr.label; - if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) - key = $"Unkown{ret[dr.name].Count + 1}"; - if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); - } - return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); - } + public List GetEnumsByDatabase(params string[] database) => new List(); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs index 25f30f08..7258038d 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs @@ -32,7 +32,7 @@ namespace FreeSql.ShenTong public IAdo Ado { get; } public IAop Aop { get; } public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst => throw new NotImplementedException("正在支持中"); + public IDbFirst DbFirst { get; } public ShenTongProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new ShenTongUtils(this); @@ -41,7 +41,7 @@ namespace FreeSql.ShenTong this.Ado = new ShenTongAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); this.Aop = new AopProvider(); - //this.DbFirst = new ShenTongDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.DbFirst = new ShenTongDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); this.CodeFirst = new ShenTongCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } From f086d5cd16bc015e47b141acc8c52301d7db971e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 10 Jun 2020 16:42:32 +0800 Subject: [PATCH 0693/1029] update functions png --- functions08.png | Bin 115875 -> 0 bytes functions09.png | Bin 0 -> 77613 bytes readme.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 functions08.png create mode 100644 functions09.png diff --git a/functions08.png b/functions08.png deleted file mode 100644 index 90620eec6da5a7f91ea4a1ab92fb7dec16f9db5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115875 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 z

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 diff --git a/functions09.png b/functions09.png new file mode 100644 index 0000000000000000000000000000000000000000..a6b84f3af17fe3e7b64a8a31994a2316c9607f2a GIT binary patch literal 77613 zcma&Oby!v1+Qz$p1uS~e-6xvulqB(6Evn1eaT^W69S8-yz>%3z?9pn^akj2E(!svr;o@Flz<1RglZC@?62 zKvbX?l49x}aC`d5uhg_|lbgh#lImb77|dZ+T&gqR`(Q&E>VZm)?&YRsS?z4G>trBq zM2SS%gH#y;KC&(&b3HclyNITh$Ih`s4-A$7I=Yo#DTYFqi(HGR^QpJ%nIzZO*GXG3 zP%1D4PTc?ZA>e(mzlGE+>weOI{16TsUebTd83uvE2ZN}8AMi2ZXkhpU$z!1?|C|UM zAW$Eqe_aPoJg1!+1}0rmJKwXxAD@PntwDw4o$^#wZ7oR0@u}n!KEE@ z?&0Zfd$&$|96?xB_yVYmhr*FF?nl#FxH4PYJ6}cS+$bH~D(tssV79$MJ(WxMczD@I zlfy8-&Q0Na?DC>*IDC}&>G6K^emc4^p`s#6C6Dg zG4A`(8VCtYVb#aCGBHU^PCnTGwSBOPcTe@Xp=M&9{az`|ut;yt?dEEQebvAYWk$5m zPuWCO&byuTD5gg#`?l7u%>qrBSi~EKRp?A}xQMmr4oPG=Q|BW*nTfcnj*K+E|32mJ zxL%^C!TCkMq&sQ1?idp;V`p|vmDb&|6uv~WeYfrd$p=@PiQpMD+dY*5uHnqA%(?CD z?JPbo>(iab4_dqnwY#9~C=yg@e@JW~T*0qDOF$tEg1$W!mEM{I_qEK}&R~XBSQvq! z_}fzX#OP@7B4TavCcEK1xf}Kwy&%i?FhjxAPdQ?3Xxt_}SwYJL%Pej@b~#mT4hpJJ zvHGcjOoCPgqdObno>`*y?p3<(_nHGg5&FO3-b2_#$`xJfONPH+zWB`0y@jNwVa}CM zT56jcOYvrqFI?W+Y0_$5bB<<=X;vF0ghf}A6M46t zo}(ga?gH~*4ABk&!KW7qWu>q4^GA0?S{PWi&40}4?|S6|&VjeyTM@94wdcZJ%gA{3 z@@14RkKNs@7f<0Kx(Jw%_y{Gn5B4%AA1=+m9qACoei6Rj{SenQyGK4G$AMKr#fUQ*jBSr19axFJ&Jt`<`>iXWSpz(z$e+!iO~;o*dT{=WH<=q?hQ%H{R?3XbP$ zMs%&4AiENJWVjCsKHi?8kr5xtE=i%1g$08fq3a{(`V$umfhYFAmj_bg57~d0!DU=< ztF3pV5aYlrctoWL28y+2BG3f_WzKc~B~^Qi=Z)T^FoXEy?c-^7SrPvcCDI#+-$}jwENbJcX zX?*0L^XX-%Hg6`zw{f{kX13f8J{#NRt&bLGcz`s2nQ2l7goBEPf6}P@sjtd3V4_>< zry)2CI5<)yU?y|}lIlYCzoTtM27Wj4W_sG{7gAs_R9OlbWYMZVZQ7qRnJmFZ*MZ

OddwyeD6}|l=um4)mm1Tx6eL1Y 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 literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index 510992f8..a3c5bda3 100644 --- a/readme.md +++ b/readme.md @@ -41,7 +41,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [内容管理系统](https://github.com/hejiyong/fscms)

- +

## 🚀 Quick start From c4ec1304512845dcf3912833a15a8cdaaee7a272 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 10 Jun 2020 22:38:07 +0800 Subject: [PATCH 0694/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IncludeMany?= =?UTF-8?q?=20=E5=8F=AA=E5=A1=AB=E5=85=85=E5=AD=90=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E4=B8=AD=E5=8F=8C=E5=90=91=E5=85=B3=E7=B3=BB=E7=9A=84=20ManyTo?= =?UTF-8?q?One=20=E5=AF=B9=E8=B1=A1=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/CommonProvider/SelectProvider/Select1Provider.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index c9bd0f50..92bc2bc5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -637,6 +637,7 @@ namespace FreeSql.Internal.CommonProvider if (tr2ref == null) continue; if (tr2ref.RefType != TableRefType.ManyToOne) continue; if (tr2ref.RefEntityType != tb.Type) continue; + if (string.Join(",", tr2ref.Columns.Select(a => a.CsName).OrderBy(a => a)) != string.Join(",", tbref.RefColumns.Select(a => a.CsName).OrderBy(a => a))) continue; //防止把 ManyToOne 多个相同类型的导航属性值都填充了 parentNavs.Add(navProp.Key); } foreach (var nav in subList) From a76ae83eab78c919bf268aa97609f085cc93fede Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 11 Jun 2020 00:06:53 +0800 Subject: [PATCH 0695/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IncludeMany?= =?UTF-8?q?=20=E5=8F=AA=E5=A1=AB=E5=85=85=E5=AD=90=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E4=B8=AD=E5=8F=8C=E5=90=91=E5=85=B3=E7=B3=BB=E7=9A=84=20ManyTo?= =?UTF-8?q?One=20=E5=AF=B9=E8=B1=A1=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj | 2 ++ .../FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs | 1 + .../Internal/CommonProvider/SelectProvider/Select1Provider.cs | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 96f5e946..9e16a3d0 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -9,6 +9,8 @@ FreeSql.Tests.xml 3 + false + x86 diff --git a/FreeSql.Tests/FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs index 6bc941f9..3af1e098 100644 --- a/FreeSql.Tests/FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Linq/QueryableRestoreToSelectTest.cs @@ -42,6 +42,7 @@ namespace FreeSql.Tests.Linq [Fact] public void RestoreToSelect() { + fsql.Insert(new qt01[] { new qt01 { name = "001" }, new qt01 { name = "001" } }).ExecuteAffrows(); Assert.Equal(fsql.Select().Skip(2).First(a => a.name), fsql.Select().AsQueryable().Skip(2).Take(1).RestoreToSelect().First(a => a.name)); Assert.Equal(fsql.Select().Skip(2).First(a => new { a.name }).name, fsql.Select().AsQueryable().Skip(2).Take(1).RestoreToSelect().First(a => new { a.name }).name); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 92bc2bc5..dc57b536 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -637,7 +637,7 @@ namespace FreeSql.Internal.CommonProvider if (tr2ref == null) continue; if (tr2ref.RefType != TableRefType.ManyToOne) continue; if (tr2ref.RefEntityType != tb.Type) continue; - if (string.Join(",", tr2ref.Columns.Select(a => a.CsName).OrderBy(a => a)) != string.Join(",", tbref.RefColumns.Select(a => a.CsName).OrderBy(a => a))) continue; //防止把 ManyToOne 多个相同类型的导航属性值都填充了 + if (string.Join(",", tr2ref.Columns.Select(a => a.CsName).OrderBy(a => a)) != string.Join(",", tbref.RefColumns.Select(a => a.CsName).OrderBy(a => a))) continue; //- 修复 IncludeMany 只填充子属性中双向关系的 ManyToOne 对象值;防止把 ManyToOne 多个相同类型的导航属性值都填充了 parentNavs.Add(navProp.Key); } foreach (var nav in subList) From 03b9ad6ff570a979ddba195d2bd726885f728cf8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 11 Jun 2020 00:11:51 +0800 Subject: [PATCH 0696/1029] v1.6.0-preview0610 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index aac0fec4..48505d38 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index bea96bee..a1f3ae94 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 113fe5a6..f831235c 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 3e4591b1..a67e9251 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 1a4d7180..d9cd7d92 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0609 + 1.6.0-preview0610 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 59d69755..85dc9bfa 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 586caf91..6fc535c7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 13ecb580..37e4cac6 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7555a395..07c8d164 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index a5d05619..f9ba4bab 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index ec0ab40c..d54296ef 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e3e4d84d..6e3ffa12 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 31eb4b83..fa61bba4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d425235b..1b38b2a4 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index c3d9e42c..077204c0 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 67641a1d..8a518901 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 582ccdd6..c0573488 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 55a45749..59cc0a98 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0609 + 1.6.0-preview0610 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 117ef11274a1f2c591b6a5dc49af6c68351a96a4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 11 Jun 2020 18:21:18 +0800 Subject: [PATCH 0697/1029] optimize AdoProvider.Dispose --- FreeSql/FreeSql.xml | 312 ++++++++++-------- .../AdoProvider/AdoProviderTransaction.cs | 12 +- 2 files changed, 175 insertions(+), 149 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 7f3b7221..01940f0f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2417,137 +2417,6 @@
- - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3194,12 +3063,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3270,12 +3133,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3917,3 +3774,172 @@ +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 条件 + + + + diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 41c4f539..42966cc7 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -132,8 +132,8 @@ namespace FreeSql.Internal.CommonProvider if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { - var trans = _trans.Values.ToArray(); - foreach (var tran in trans) CommitTransaction(false, tran, null, "Dispose自动提交"); + var trans = _trans?.Values.ToArray(); + if (trans != null) foreach (var tran in trans) CommitTransaction(false, tran, null, "Dispose自动提交"); } catch { } @@ -142,8 +142,8 @@ namespace FreeSql.Internal.CommonProvider { try { - pools = SlavePools.ToArray(); - SlavePools.Clear(); + pools = SlavePools?.ToArray(); + SlavePools?.Clear(); break; } catch @@ -154,10 +154,10 @@ namespace FreeSql.Internal.CommonProvider { foreach (var pool in pools) { - try { pool.Dispose(); } catch { } + try { pool?.Dispose(); } catch { } } } - try { MasterPool.Dispose(); } catch { } + try { MasterPool?.Dispose(); } catch { } } } } \ No newline at end of file From 40941e9b7ca32cb0a46a4df4e43b2d0fcf8a350b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 11 Jun 2020 21:08:25 +0800 Subject: [PATCH 0698/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=20pgsql=209.4=20CodeFirst/DbFirst=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 14 ++++++++++---- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 13 ++++++++++++- .../PostgreSQLCodeFirst.cs | 14 ++++++++++---- .../PostgreSQLDbFirst.cs | 13 ++++++++++++- 5 files changed, 44 insertions(+), 26 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/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 734a0e25..aed5198f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -84,6 +84,12 @@ namespace FreeSql.Odbc.PostgreSQL var sb = new StringBuilder(); var seqcols = new List>(); //序列 + var is96 = true; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + is96 = OdbcPostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion); + } + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -262,24 +268,24 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } - var dsuksql = _commonUtils.FormatSql(@" + var dsuksql = _commonUtils.FormatSql($@" select c.attname, b.relname, -case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, case when indisunique = 't' then 1 else 0 end IsUnique from pg_index a inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); +where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", tboldname ?? tbname); var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || is96 == false)).Any()).Count() != uk.Columns.Length) { if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); sbalter.Append("CREATE "); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 613e8c4b..b9104da5 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -103,9 +103,11 @@ namespace FreeSql.Odbc.PostgreSQL public List GetTablesByDatabase(params string[] database) { var olddatabase = ""; + var is96 = true; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { olddatabase = conn.Value.Database; + is96 = PgVersionIs96(conn.Value.ServerVersion); } var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; var tables = new List(); @@ -291,7 +293,7 @@ b.relname as index_id, case when a.indisunique then 1 else 0 end IsUnique, case when a.indisprimary then 1 else 0 end IsPrimary, case when a.indisclustered then 0 else 1 end IsClustered, -case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, a.indkey::text, c.attnum from pg_index a @@ -486,5 +488,14 @@ where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information } return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); } + + public static bool PgVersionIs96(string serverVersion) + { + int[] version = serverVersion.Split('.').Select(a => int.TryParse(a, out var tryint) ? tryint : 0).ToArray(); + if (version?.Any() != true) return true; + if (version[0] > 9) return true; + if (version[0] == 9 && version.Length > 1 && version[1] >= 6) return true; + return false; + } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index fa581e60..6a0b4c3b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -119,6 +119,12 @@ namespace FreeSql.PostgreSQL var sb = new StringBuilder(); var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + var is96 = true; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + is96 = PostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion); + } + foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -297,24 +303,24 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } - var dsuksql = _commonUtils.FormatSql(@" + var dsuksql = _commonUtils.FormatSql($@" select c.attname, b.relname, -case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, case when indisunique = 't' then 1 else 0 end IsUnique from pg_index a inner join pg_class b on b.oid = a.indexrelid inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_class d on d.oid = a.indrelid -where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); +where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", tboldname ?? tbname); var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); - if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || is96 == false)).Any()).Count() != uk.Columns.Length) { if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); sbalter.Append("CREATE "); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index bba4d80a..225c2ab3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -213,9 +213,11 @@ namespace FreeSql.PostgreSQL public List GetTablesByDatabase(params string[] database) { var olddatabase = ""; + var is96 = true; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { olddatabase = conn.Value.Database; + is96 = PgVersionIs96(conn.Value.ServerVersion); } var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; var tables = new List(); @@ -401,7 +403,7 @@ b.relname as index_id, case when a.indisunique then 1 else 0 end IsUnique, case when a.indisprimary then 1 else 0 end IsPrimary, case when a.indisclustered then 0 else 1 end IsClustered, -case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, a.indkey::text, c.attnum from pg_index a @@ -591,5 +593,14 @@ where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information } return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); } + + public static bool PgVersionIs96(string serverVersion) + { + int[] version = serverVersion.Split('.').Select(a => int.TryParse(a, out var tryint) ? tryint : 0).ToArray(); + if (version?.Any() != true) return true; + if (version[0] > 9) return true; + if (version[0] == 9 && version.Length > 1 && version[1] >= 6) return true; + return false; + } } } \ No newline at end of file From 86ff99503263ecc6664fd8b864fcdaaa463e86b0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 11 Jun 2020 23:36:00 +0800 Subject: [PATCH 0699/1029] =?UTF-8?q?=E5=85=BC=E5=AE=B9=20MySql8.0=20CodeF?= =?UTF-8?q?irst=20=E7=B1=BB=E5=9E=8B=E5=AF=B9=E6=AF=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlDeleteTest.cs | 18 ++--- .../MySqlConnector/Curd/MySqlInsertTest.cs | 41 +++++++++--- .../Curd/OnDuplicateKeyUpdateTest.cs | 66 +++++++++---------- .../MySql/Curd/MySqlDeleteTest.cs | 18 ++--- .../MySql/Curd/MySqlInsertTest.cs | 20 +++--- .../MySql/Curd/OnDuplicateKeyUpdateTest.cs | 2 +- .../MySql/Curd/MySqlDeleteTest.cs | 18 ++--- .../MySql/Curd/MySqlInsertTest.cs | 18 ++--- .../MySql/Curd/OnDuplicateKeyUpdateTest.cs | 2 +- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 9 ++- .../MySql/OdbcMySqlCodeFirst.cs | 9 ++- 11 files changed, 129 insertions(+), 92 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs index 558613c3..1d711cc4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs @@ -11,7 +11,7 @@ namespace FreeSql.Tests.MySqlConnector IDelete delete => g.mysql.Delete(); //�������� - [Table(Name = "tb_topic")] + [Table(Name = "tb_topic_delete")] class Topic { [Column(IsIdentity = true, IsPrimary = true)] @@ -26,16 +26,16 @@ namespace FreeSql.Tests.MySqlConnector { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); sql = g.mysql.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); Assert.Equal("DELETE FROM `MultiPkTopic` WHERE (`Id1` = 1 AND `Id2` = 10 OR `Id1` = 2 AND `Id2` = 20)", sql); @@ -55,20 +55,20 @@ namespace FreeSql.Tests.MySqlConnector public void Where() { var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (id = @id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs index f80add2f..73b8e612 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs @@ -11,7 +11,7 @@ namespace FreeSql.Tests.MySqlConnector IInsert insert => g.mysql.Insert(); //�������� - [Table(Name = "tb_topic")] + [Table(Name = "tb_topic_insert")] class Topic { [Column(IsIdentity = true, IsPrimary = true)] @@ -36,16 +36,16 @@ namespace FreeSql.Tests.MySqlConnector for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`, `CreateTime`) VALUES(@Clicks_0, @Title_0, @CreateTime_0), (@Clicks_1, @Title_1, @CreateTime_1), (@Clicks_2, @Title_2, @CreateTime_2), (@Clicks_3, @Title_3, @CreateTime_3), (@Clicks_4, @Title_4, @CreateTime_4), (@Clicks_5, @Title_5, @CreateTime_5), (@Clicks_6, @Title_6, @CreateTime_6), (@Clicks_7, @Title_7, @CreateTime_7), (@Clicks_8, @Title_8, @CreateTime_8), (@Clicks_9, @Title_9, @CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Now }).ToSql(); Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES(@type_0, @time_0)", sql); @@ -61,10 +61,10 @@ namespace FreeSql.Tests.MySqlConnector for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Title`) VALUES(@Title_0), (@Title_1), (@Title_2), (@Title_3), (@Title_4), (@Title_5), (@Title_6), (@Title_7), (@Title_8), (@Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); } [Fact] public void IgnoreColumns() @@ -73,10 +73,10 @@ namespace FreeSql.Tests.MySqlConnector for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(@Clicks_0, @Title_0), (@Clicks_1, @Title_1), (@Clicks_2, @Title_2), (@Clicks_3, @Title_3), (@Clicks_4, @Title_4), (@Clicks_5, @Title_5), (@Clicks_6, @Title_6), (@Clicks_7, @Title_7), (@Clicks_8, @Title_8), (@Clicks_9, @Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`) VALUES(@Clicks_0), (@Clicks_1), (@Clicks_2), (@Clicks_3), (@Clicks_4), (@Clicks_5), (@Clicks_6), (@Clicks_7), (@Clicks_8), (@Clicks_9)", sql); g.mysql.Delete().Where("1=1").ExecuteAffrows(); var itemsIgnore = new List(); @@ -128,6 +128,29 @@ namespace FreeSql.Tests.MySqlConnector //insert.AppendData(items.First()).ExecuteInserted(); } + [Fact] + public void MySqlIgnoreInto() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.MySqlIgnoreInto().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.MySqlIgnoreInto().AppendData(items).ExecuteAffrows()); + + Assert.Equal(1, g.mysql.Insert().MySqlIgnoreInto().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); + Assert.Equal(1, g.mysql.Insert().MySqlIgnoreInto().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + + items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.MySqlIgnoreInto().AppendData(items.First()).ExecuteIdentity()); + + var id = g.mysql.Insert().MySqlIgnoreInto().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + id = g.mysql.Insert().MySqlIgnoreInto().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] public void AsTable() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs index 2145dedb..81ad6cab 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs @@ -13,7 +13,7 @@ namespace FreeSql.Tests.MySqlConnector [Column(IsIdentity = true)] public int id { get; set; } public string title { get; set; } - public DateTime time { get; set; } + public DateTime? time { get; set; } } [Fact] @@ -21,10 +21,10 @@ namespace FreeSql.Tests.MySqlConnector { g.mysql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = VALUES(`time`)", odku1.ToSql()); +`time` = VALUES(`time`)"); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -32,10 +32,10 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = VALUES(`time`)", odku2.ToSql()); +`time` = VALUES(`time`)"); odku2.ExecuteAffrows(); } @@ -44,10 +44,10 @@ ON DUPLICATE KEY UPDATE { g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); +`time` = '2000-01-01 00:00:00.000'"); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -55,21 +55,21 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), `time` = CASE `id` WHEN 200 THEN '2000-01-01 00:00:00.000' WHEN 201 THEN '2000-01-01 00:00:00.000' -WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); +WHEN 202 THEN '2000-01-01 00:00:00.000' END"); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') ON DUPLICATE KEY UPDATE -`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); +`time` = '2000-01-01 00:00:00.000'"); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -77,12 +77,12 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON DUPLICATE KEY UPDATE `time` = CASE `id` WHEN 200 THEN '2000-01-01 00:00:00.000' WHEN 201 THEN '2000-01-01 00:00:00.000' -WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); +WHEN 202 THEN '2000-01-01 00:00:00.000' END"); odku2.ExecuteAffrows(); } @@ -91,10 +91,10 @@ WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); { g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); +`time` = '2000-01-01 00:00:00.000'"); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -102,21 +102,21 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), `time` = CASE `id` WHEN 300 THEN '2000-01-01 00:00:00.000' WHEN 301 THEN '2000-01-01 00:00:00.000' -WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); +WHEN 302 THEN '2000-01-01 00:00:00.000' END"); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') ON DUPLICATE KEY UPDATE -`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); +`time` = '2000-01-01 00:00:00.000'"); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -124,12 +124,12 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON DUPLICATE KEY UPDATE `time` = CASE `id` WHEN 300 THEN '2000-01-01 00:00:00.000' WHEN 301 THEN '2000-01-01 00:00:00.000' -WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); +WHEN 302 THEN '2000-01-01 00:00:00.000' END"); odku2.ExecuteAffrows(); } @@ -138,9 +138,9 @@ WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); { g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); +`time` = '2020-01-01 00:00:00.000'"); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -148,18 +148,18 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); +`time` = '2020-01-01 00:00:00.000'"); odku2.ExecuteAffrows(); var dt2020 = DateTime.Parse("2020-1-1"); g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); +`time` = '2020-01-01 00:00:00.000'"); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -167,17 +167,17 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); +`time` = '2020-01-01 00:00:00.000'"); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku1.ToSql()); +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -185,9 +185,9 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); - Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku2.ToSql()); +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); odku2.ExecuteAffrows(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs index 277df59a..cbc3303a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs @@ -11,7 +11,7 @@ namespace FreeSql.Tests.Odbc.MySql IDelete delete => g.mysql.Delete(); //�������� - [Table(Name = "tb_topic")] + [Table(Name = "tb_topic_delete")] class Topic { [Column(IsIdentity = true, IsPrimary = true)] @@ -26,16 +26,16 @@ namespace FreeSql.Tests.Odbc.MySql { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); sql = g.mysql.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); Assert.Equal("DELETE FROM `MultiPkTopic` WHERE (`Id1` = 1 AND `Id2` = 10 OR `Id1` = 2 AND `Id2` = 20)", sql); @@ -55,20 +55,20 @@ namespace FreeSql.Tests.Odbc.MySql public void Where() { var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (id = @id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertTest.cs index 9eeecd86..08cd06ad 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertTest.cs @@ -11,7 +11,7 @@ namespace FreeSql.Tests.Odbc.MySql IInsert insert => g.mysql.Insert(); //�������� - [Table(Name = "tb_topic")] + [Table(Name = "tb_topic_insert")] class Topic { [Column(IsIdentity = true, IsPrimary = true)] @@ -36,16 +36,16 @@ namespace FreeSql.Tests.Odbc.MySql for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000')", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000')", sql); sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000'), (100, 'newtitle1', '0001-01-01 00:00:00.000'), (200, 'newtitle2', '0001-01-01 00:00:00.000'), (300, 'newtitle3', '0001-01-01 00:00:00.000'), (400, 'newtitle4', '0001-01-01 00:00:00.000'), (500, 'newtitle5', '0001-01-01 00:00:00.000'), (600, 'newtitle6', '0001-01-01 00:00:00.000'), (700, 'newtitle7', '0001-01-01 00:00:00.000'), (800, 'newtitle8', '0001-01-01 00:00:00.000'), (900, 'newtitle9', '0001-01-01 00:00:00.000')", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000'), (100, 'newtitle1', '0001-01-01 00:00:00.000'), (200, 'newtitle2', '0001-01-01 00:00:00.000'), (300, 'newtitle3', '0001-01-01 00:00:00.000'), (400, 'newtitle4', '0001-01-01 00:00:00.000'), (500, 'newtitle5', '0001-01-01 00:00:00.000'), (600, 'newtitle6', '0001-01-01 00:00:00.000'), (700, 'newtitle7', '0001-01-01 00:00:00.000'), (800, 'newtitle8', '0001-01-01 00:00:00.000'), (900, 'newtitle9', '0001-01-01 00:00:00.000')", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Title`) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Parse("2019-09-19 21:26:51.030") }).ToSql(); Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '2019-09-19 21:26:51.030')", sql); @@ -61,10 +61,10 @@ namespace FreeSql.Tests.Odbc.MySql for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Title`) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); } [Fact] public void IgnoreColumns() @@ -73,10 +73,10 @@ namespace FreeSql.Tests.Odbc.MySql for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); g.mysql.Delete().Where("1=1").ExecuteAffrows(); var itemsIgnore = new List(); @@ -85,7 +85,7 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal(2072, itemsIgnore.Count); Assert.Equal(2072, g.mysql.Select().Where(a => a.Title == null).Count()); } - [Table(Name = "tb_topicIgnoreColumns")] + [Table(Name = "tb_topic_insertIgnoreColumns")] class TopicIgnore { [Column(IsIdentity = true, IsPrimary = true)] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/OnDuplicateKeyUpdateTest.cs index 1bf715b6..9cbad1ed 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/OnDuplicateKeyUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/OnDuplicateKeyUpdateTest.cs @@ -14,7 +14,7 @@ namespace FreeSql.Tests.Odbc.MySql [Column(IsIdentity = true)] public int id { get; set; } public string title { get; set; } - public DateTime time { get; set; } + public DateTime? time { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs index de9c83a8..3fcb503f 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs @@ -11,7 +11,7 @@ namespace FreeSql.Tests.MySql IDelete delete => g.mysql.Delete(); //�������� - [Table(Name = "tb_topic")] + [Table(Name = "tb_topic_delete")] class Topic { [Column(IsIdentity = true, IsPrimary = true)] @@ -27,16 +27,16 @@ namespace FreeSql.Tests.MySql { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); sql = g.mysql.Delete(new { id = 1 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); Assert.Equal("DELETE FROM `MultiPkTopic` WHERE (`Id1` = 1 AND `Id2` = 10 OR `Id1` = 2 AND `Id2` = 20)", sql); @@ -56,20 +56,20 @@ namespace FreeSql.Tests.MySql public void Where() { var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (id = @id)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (id = @id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = delete.Where(item).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = delete.Where(items).ToSql().Replace("\r\n", ""); - Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs index 4e1c40ae..3f4ee371 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs @@ -11,7 +11,7 @@ namespace FreeSql.Tests.MySql IInsert insert => g.mysql.Insert(); //�������� - [Table(Name = "tb_topic")] + [Table(Name = "tb_topic_insert")] class Topic { [Column(IsIdentity = true, IsPrimary = true)] @@ -37,16 +37,16 @@ namespace FreeSql.Tests.MySql for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items.First()).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0)", sql); sql = insert.AppendData(items).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0), (?Clicks_1, ?Title_1, ?CreateTime_1), (?Clicks_2, ?Title_2, ?CreateTime_2), (?Clicks_3, ?Title_3, ?CreateTime_3), (?Clicks_4, ?Title_4, ?CreateTime_4), (?Clicks_5, ?Title_5, ?CreateTime_5), (?Clicks_6, ?Title_6, ?CreateTime_6), (?Clicks_7, ?Title_7, ?CreateTime_7), (?Clicks_8, ?Title_8, ?CreateTime_8), (?Clicks_9, ?Title_9, ?CreateTime_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks_0, ?Title_0, ?CreateTime_0), (?Clicks_1, ?Title_1, ?CreateTime_1), (?Clicks_2, ?Title_2, ?CreateTime_2), (?Clicks_3, ?Title_3, ?CreateTime_3), (?Clicks_4, ?Title_4, ?CreateTime_4), (?Clicks_5, ?Title_5, ?CreateTime_5), (?Clicks_6, ?Title_6, ?CreateTime_6), (?Clicks_7, ?Title_7, ?CreateTime_7), (?Clicks_8, ?Title_8, ?CreateTime_8), (?Clicks_9, ?Title_9, ?CreateTime_9)", sql); sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Now }).ToSql(); Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES(?type_0, ?time_0)", sql); @@ -62,10 +62,10 @@ namespace FreeSql.Tests.MySql for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Title`) VALUES(?Title_0), (?Title_1), (?Title_2), (?Title_3), (?Title_4), (?Title_5), (?Title_6), (?Title_7), (?Title_8), (?Title_9)", sql); sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); } [Fact] public void IgnoreColumns() @@ -74,10 +74,10 @@ namespace FreeSql.Tests.MySql for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(?Clicks_0, ?Title_0), (?Clicks_1, ?Title_1), (?Clicks_2, ?Title_2), (?Clicks_3, ?Title_3), (?Clicks_4, ?Title_4), (?Clicks_5, ?Title_5), (?Clicks_6, ?Title_6), (?Clicks_7, ?Title_7), (?Clicks_8, ?Title_8), (?Clicks_9, ?Title_9)", sql); sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); - Assert.Equal("INSERT INTO `tb_topic`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`) VALUES(?Clicks_0), (?Clicks_1), (?Clicks_2), (?Clicks_3), (?Clicks_4), (?Clicks_5), (?Clicks_6), (?Clicks_7), (?Clicks_8), (?Clicks_9)", sql); g.mysql.Delete().Where("1=1").ExecuteAffrows(); var itemsIgnore = new List(); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/OnDuplicateKeyUpdateTest.cs index 00ec83ad..8edb9f1c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/OnDuplicateKeyUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/OnDuplicateKeyUpdateTest.cs @@ -13,7 +13,7 @@ namespace FreeSql.Tests.MySql [Column(IsIdentity = true)] public int id { get; set; } public string title { get; set; } - public DateTime time { get; set; } + public DateTime? time { get; set; } } [Fact] diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 76ba3291..673a6220 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -227,8 +227,15 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); var isDbTypeChanged = tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false; - if (tbstructcol.sqlType == "datetime(0)" && Regex.IsMatch(tbcol.Attribute.DbType, @"datetime\s+\(", RegexOptions.IgnoreCase) == false) + if (tbstructcol.sqlType == "datetime(0)" && Regex.IsMatch(tbcol.Attribute.DbType, @"datetime\s*\(", RegexOptions.IgnoreCase) == false) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase) == false || + (int.TryParse(Regex.Match(tbcol.Attribute.DbType, @"datetime\s*\((\d*)", RegexOptions.IgnoreCase).Groups[1].Value, out var trydtrd) ? trydtrd : 3) != + (int.TryParse(Regex.Match(tbstructcol.sqlType, @"datetime\s*\((\d*)", RegexOptions.IgnoreCase).Groups[1].Value, out var trydtrd2) ? trydtrd2 : 3); + else if (tbstructcol.sqlType.StartsWith("int", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("int", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("tinyint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("tinyint", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("smallint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("smallint", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("bigint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("bigint", StringComparison.CurrentCultureIgnoreCase) == false; if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || isDbTypeChanged || diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 7b976b31..8bc6b09a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -220,8 +220,15 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); var isDbTypeChanged = tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false; - if (tbstructcol.sqlType == "datetime(0)" && Regex.IsMatch(tbcol.Attribute.DbType, @"datetime\s+\(", RegexOptions.IgnoreCase) == false) + if (tbstructcol.sqlType == "datetime(0)" && Regex.IsMatch(tbcol.Attribute.DbType, @"datetime\s*\(", RegexOptions.IgnoreCase) == false) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase) == false || + (int.TryParse(Regex.Match(tbcol.Attribute.DbType, @"datetime\s*\((\d*)", RegexOptions.IgnoreCase).Groups[1].Value, out var trydtrd) ? trydtrd : 3) != + (int.TryParse(Regex.Match(tbstructcol.sqlType, @"datetime\s*\((\d*)", RegexOptions.IgnoreCase).Groups[1].Value, out var trydtrd2) ? trydtrd2 : 3); + else if (tbstructcol.sqlType.StartsWith("int", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("int", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("tinyint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("tinyint", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("smallint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("smallint", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("bigint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("bigint", StringComparison.CurrentCultureIgnoreCase) == false; if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || isDbTypeChanged || From 107e638996dccd952157944519cac9f084bb197d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 12 Jun 2020 01:08:21 +0800 Subject: [PATCH 0700/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Select`2-10?= =?UTF-8?q?=20ToOne/First=20=E6=B2=A1=E6=9C=89=E5=A4=84=E7=90=86=20Limit(1?= =?UTF-8?q?)=20=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 312 ++++++++---------- .../SelectProvider/Select10Provider.cs | 12 +- .../SelectProvider/Select2Provider.cs | 12 +- .../SelectProvider/Select3Provider.cs | 12 +- .../SelectProvider/Select4Provider.cs | 12 +- .../SelectProvider/Select5Provider.cs | 12 +- .../SelectProvider/Select6Provider.cs | 12 +- .../SelectProvider/Select7Provider.cs | 12 +- .../SelectProvider/Select8Provider.cs | 12 +- .../SelectProvider/Select9Provider.cs | 12 +- readme.md | 3 +- 11 files changed, 199 insertions(+), 224 deletions(-) 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 条件 - - - - diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index b960c579..d754293d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -171,9 +171,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -234,9 +234,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 40e80a2d..2ca2fc1d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -148,9 +148,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -211,9 +211,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 90177071..27e36b4c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -151,9 +151,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -214,9 +214,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 36fb28ad..f7cfa25e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -154,9 +154,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -217,9 +217,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index b7b028bc..aeaf7daf 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -157,9 +157,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -220,9 +220,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 33d85c40..a4522c5e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -160,9 +160,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -223,9 +223,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 2a7c84a8..3b0b4979 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -163,9 +163,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -226,9 +226,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 7942d59d..821d9032 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -167,9 +167,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -230,9 +230,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index de4a8a57..fc9e0479 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -164,9 +164,9 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); } - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).ToList().FirstOrDefault(); + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); #if net40 #else @@ -228,9 +228,9 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToListAsync(select?.Body); } - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).ToListAsync()).FirstOrDefault(); + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); #endif } diff --git a/readme.md b/readme.md index a3c5bda3..d6fb36c2 100644 --- a/readme.md +++ b/readme.md @@ -184,7 +184,8 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [LiaoLiaoWuJu](https://github.com/LiaoLiaoWuJu)、 [hd2y](https://github.com/hd2y)、 [tky753](https://github.com/tky753)、 -[feijie999](https://github.com/feijie999) +[feijie999](https://github.com/feijie999)、 +constantine (QQ群:4336577) From 7a2000a29e4ec6b68c85214df8f1a9c7d523e292 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 12 Jun 2020 01:11:05 +0800 Subject: [PATCH 0701/1029] v1.6.0-preview0611 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 48505d38..ad136138 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a1f3ae94..9f9a497f 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index f831235c..e6f10e2b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index a67e9251..4d6dd7a5 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d9cd7d92..da52b2f6 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0610 + 1.6.0-preview0611 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 85dc9bfa..e7cd2370 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6fc535c7..b8ba031c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 37e4cac6..e71c1361 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 07c8d164..bc41bc35 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index f9ba4bab..53791498 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index d54296ef..d1e96566 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6e3ffa12..6f020774 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fa61bba4..f85165be 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 1b38b2a4..04a0f691 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 077204c0..9d63174c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8a518901..b9b3ef37 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c0573488..2046438b 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 59cc0a98..ff6ec9aa 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0610 + 1.6.0-preview0611 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 72cccffc30fff26f90c0b2df2a9d4aa9b5c95880 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 14 Jun 2020 10:38:53 +0800 Subject: [PATCH 0702/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20SqlExt=20?= =?UTF-8?q?=E5=B8=B8=E7=94=A8=E5=BC=80=E7=AA=97=E5=87=BD=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=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 | 17 +++++ .../FreeSqlGlobalExpressionCallExtensions.cs | 64 +++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 24 +++++-- 4 files changed, 117 insertions(+), 4 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 28ea2939..762fdaa9 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -155,6 +155,23 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var sqlextOver = g.sqlserver.Select() + .InnerJoin((a, b) => b.Id == a.Id) + .ToSql((a, b) => new + { + Id = a.Id, + EdiId = b.Id, + over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue() + }); + var sqlextOverToList = g.sqlserver.Select() + .InnerJoin((a, b) => b.Id == a.Id) + .ToList((a, b) => new + { + Id = a.Id, + EdiId = b.Id, + over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue() + }); + var tttrule = 8; var tttid = new long[] { 18, 19, 4017 }; g.sqlserver.Update().Set(it => it.SongId == (short)(it.SongId & ~tttrule)).Where(it => (it.SongId & tttrule) == tttrule && !tttid.Contains(it.Id)).ExecuteAffrows(); diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index 63c48c4e..c8de533c 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using System; +using System.Text; using System.Threading; [ExpressionCall] @@ -39,4 +40,67 @@ public static class FreeSqlGlobalExpressionCallExtensions expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} >= {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["that"]} < {expContext.Value.ParsedContent["end"]}"; return false; } +} + +namespace FreeSql +{ + [ExpressionCall] + 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()"); + public static ISqlOver Count() => Over("COUNT()"); + public static ISqlOver Sum(object column) => Over($"Sum({expContext.Value.ParsedContent["column"]})"); + public static ISqlOver Avg() => Over($"AVG({expContext.Value.ParsedContent["column"]})"); + public static ISqlOver Max(T column) => Over($"MAX({expContext.Value.ParsedContent["column"]})"); + public static ISqlOver Min(T column) => Over($"MIN({expContext.Value.ParsedContent["column"]})"); + public static ISqlOver RowNumber() => Over("ROW_NUMBER()"); + + #region .. over([partition by ..] order by ...) + static ISqlOver Over(string sqlFunc) + { + expSb.Value = new StringBuilder(); + expSbIsOrderBy.Value = false; + expSb.Value.Append($"{sqlFunc} "); + return null; + } + public static ISqlOver Over(this ISqlOver that) + { + expSb.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(","); + 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) + { + sb.Append("ORDER BY "); + expSbIsOrderBy.Value = true; + } + sb.Append(expContext.Value.ParsedContent["column"]); + if (isDesc) sb.Append(" desc"); + sb.Append(","); + return that; + } + public static TValue ToValue(this ISqlOver that) + { + var sb = expSb.Value.ToString().TrimEnd(','); + expSb.Value.Clear(); + expContext.Value.Result = $"{sb})"; + return default; + } + public interface ISqlOver { } + #endregion + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index c870a2f9..e620643c 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -627,8 +627,11 @@ namespace FreeSql.Internal }; var exp3MethodParams = exp3.Method.GetParameters(); var dbParamsIndex = tsc.dbParams?.Count; - ecc.RawExpression.Add(exp3MethodParams[0].Name, exp3.Arguments[0]); - ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[0], tsc)); + if (exp3MethodParams.Any()) + { + ecc.RawExpression.Add(exp3MethodParams[0].Name, exp3.Arguments[0]); + ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[0], tsc)); + } if (tsc.dbParams?.Count > dbParamsIndex) ecc.DbParameter = tsc.dbParams.Last(); List oldDbParams = tsc.SetDbParamsReturnOld(null); for (var a = 1; a < exp3.Arguments.Count; a++) @@ -646,7 +649,20 @@ namespace FreeSql.Internal { var eccContent = ecc.ParsedContent[exp3MethodParams[a].Name]; if (eccContent == null) - exp3InvokeParams[a] = Expression.Lambda(exp3.Arguments[a]).Compile().DynamicInvoke(); + { + var isdyInvoke = true; + if (exp3.Arguments[a].NodeType == ExpressionType.Call) //判断如果参数也是标记 ExpressionCall + { + var exp3ArgsACallExp = exp3.Arguments[a] as MethodCallExpression; + if (exp3ArgsACallExp.Object == null && ( + _dicTypeExistsExpressionCallAttribute.GetOrAdd(exp3ArgsACallExp.Method.DeclaringType, dttp => dttp.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any()) || + exp3ArgsACallExp.Method.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any() + )) + isdyInvoke = false; + } + if (isdyInvoke) + exp3InvokeParams[a] = Expression.Lambda(exp3.Arguments[a]).Compile().DynamicInvoke(); + } else if (exp3.Arguments[a].IsParameter()) exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); else @@ -668,7 +684,7 @@ namespace FreeSql.Internal { var sqlRet = exp3.Method.Invoke(null, exp3InvokeParams); if (string.IsNullOrEmpty(ecc.Result) && sqlRet is string) ecc.Result = string.Concat(sqlRet); - if (string.IsNullOrEmpty(ecc.Result)) ecc.Result = ecc.ParsedContent[exp3MethodParams[0].Name]; + if (string.IsNullOrEmpty(ecc.Result) && exp3MethodParams.Any()) ecc.Result = ecc.ParsedContent[exp3MethodParams[0].Name]; if (ecc.UserParameters?.Any() == true) tsc.dbParams?.AddRange(ecc.UserParameters); return ecc.Result; } From 6581e435adcef710fddf248cff10fcd0ddee7f04 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 15 Jun 2020 23:38:51 +0800 Subject: [PATCH 0703/1029] update readme --- readme.md | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/readme.md b/readme.md index d6fb36c2..3402518e 100644 --- a/readme.md +++ b/readme.md @@ -1,14 +1,10 @@ -

- -

- -FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+ 或 Xamarin - -扶摇直上,至强ORM只为自由编码;鹏程万里,至简Linq可使保留黑发;横批:FreeSql(诗人:Coder) +## FreeSql [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/2881099/FreeSql/master/LICENSE.txt) -## 🐮 Features +FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+ 或 Xamarin + +## 🐮  Features - [x] 支持 CodeFirst 迁移,哪怕使用 Access 数据库也支持; - [x] 支持 DbFirst 从数据库导入实体类,[安装实体类生成工具](https://github.com/2881099/FreeSql/wiki/DbFirst); @@ -18,7 +14,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; - [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access; -## 📚 Documentation +## 📚  Documentation | | | | - | - | @@ -44,7 +40,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+

-## 🚀 Quick start +## 🚀  Quick start > dotnet add package FreeSql.Provider.Sqlite @@ -83,7 +79,7 @@ class Tag { } ``` -## 🔎 Query +## 🔎  Query ```csharp //OneToOne、ManyToOne fsql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToList(); @@ -119,7 +115,7 @@ fsql.Select().OrderBy(a => Guid.NewGuid()).Limit(10).ToList(); ``` [More..](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) -## 🚁 Repository +## 🚁  Repository > dotnet add package FreeSql.Repository @@ -142,7 +138,7 @@ public void Add() { 参考:[在 asp.net core 中使用 TransactionalAttribute + UnitOfWorkManager 实现多种事务传播](https://github.com/dotnetcore/FreeSql/issues/289) -## 💪 Performance +## 💪  Performance FreeSql Query & Dapper Query ```shell @@ -170,7 +166,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [More..](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd) -## 👯 Contributors +## 👯  Contributors [systemhejiyong](https://github.com/systemhejiyong)、 [LambertW](https://github.com/LambertW)、 @@ -189,7 +185,7 @@ constantine (QQ群:4336577) -## 💕 Donation +## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元 From 7f52c3995ff133d3898020b5924dc81cb2b2f98d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 15 Jun 2020 23:43:30 +0800 Subject: [PATCH 0704/1029] update readme --- readme.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 3402518e..4ab26f46 100644 --- a/readme.md +++ b/readme.md @@ -1,10 +1,8 @@ -## FreeSql +## 🦄  FreeSql [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/2881099/FreeSql/master/LICENSE.txt) -FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+ 或 Xamarin - -## 🐮  Features +FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+ 或 Xamarin。 - [x] 支持 CodeFirst 迁移,哪怕使用 Access 数据库也支持; - [x] 支持 DbFirst 从数据库导入实体类,[安装实体类生成工具](https://github.com/2881099/FreeSql/wiki/DbFirst); From 005cddcac94503a876cf7e086e5b04e77253fd9e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 15 Jun 2020 23:54:08 +0800 Subject: [PATCH 0705/1029] remove .github --- .github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md | 61 ------------------------ 1 file changed, 61 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md deleted file mode 100644 index 0af344a2..00000000 --- a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,61 +0,0 @@ -##### 问题描述 - -```csharp -// c# 代码段 -``` - - -##### 重现问题步骤(如果可以) - -1. ... -2. ... - - -##### 发现问题的模块 - -- [ ] FreeSql 版本: -- [ ] FreeSql.Provider.?? -- [ ] FreeSql.Repository -- [ ] FreeSql.DbContext - - -##### 模块对应的 .net 版本 - -- [ ] .net 4.0 -- [ ] .net 4.5 -- [ ] .net 4.6 -- [ ] .net 4.7 -- [ ] .net standard 2.0 -- [ ] .net core 2.x -- [x] .net core 3.x - - -##### 数据库环境 - -- [x] MySql,版本: -- [ ] SqlServer,版本: -- [ ] PostgreSQL,版本: -- [ ] Oracle,版本: -- [ ] Sqlite -- [ ] Access,版本: -- [ ] 达梦,版本: - - -##### 开发环境 - -- [ ] Visual Studio 2015 -- [ ] Visual Studio 2017 -- [x] Visual Studio 2019 -- [ ] Visual Studio Code -- [ ] 其他: - - -##### 系统环境 - -- [x] Windows,版本: -- [ ] Linux,版本: -- [ ] Mac,版本: -- [ ] 其他: - - -> 发布问题后,请保持对 issue 的关注,有时会有需要进一步沟通的信息,很长时间内没有得到答复的 issue 将被关闭。 \ No newline at end of file From 12bb21d944af84e527564f5177bfaff60e7f894c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 16 Jun 2020 15:33:52 +0800 Subject: [PATCH 0706/1029] update csproj Description --- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b8ba031c..2bd16d7c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -5,7 +5,7 @@ 1.6.0-preview0611 true ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access https://github.com/2881099/FreeSql/wiki/DbContext FreeSql ORM DbContext git diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e71c1361..11b8e9d3 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -4,7 +4,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.6.0-preview0611 ncc;YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/Access, and read/write separation、and split table. + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository true diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index bc41bc35..897d706c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -5,7 +5,7 @@ 1.6.0-preview0611 true ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git From c88efe24d12f3b2d7a8bf931fdd1adc7792aef12 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 18 Jun 2020 17:32:47 +0800 Subject: [PATCH 0707/1029] add IncludeMany exception tips --- .../Internal/CommonProvider/SelectProvider/Select1Provider.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index dc57b536..952770d6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -372,6 +372,7 @@ namespace FreeSql.Internal.CommonProvider if (whereExp == null) { tbref = tb.GetTableRef(collMem.Member.Name, true); + if (tbref == null) throw new Exception($"IncludeMany 类型 {tb.Type.DisplayCsharp()} 的属性 {collMem.Member.Name} 不是有效的导航属性,提示:IsIgnore = true 不会成为导航属性"); } else { From 31e4b2d8faf4d2850d4c70ecce5d7c17bcb8b38d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 19 Jun 2020 16:56:52 +0800 Subject: [PATCH 0708/1029] Optimize inner expression parser --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql/Internal/CommonExpression.cs | 2 ++ 2 files changed, 2 insertions(+), 16 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/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index e620643c..0cafcea1 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -341,6 +341,7 @@ namespace FreeSql.Internal case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, getSelectGroupingMapString); case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString) }; + case ExpressionType.Call: case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries); case ExpressionType.New: var newExp = exp as NewExpression; @@ -354,6 +355,7 @@ namespace FreeSql.Internal var newArrMembers = new List(); foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, getSelectGroupingMapString)); return newArrMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); + default: throw new ArgumentException($"无法解析表达式:{exp}"); } return new string[0]; } From f1e144daaf488779ba966fbea2dac3334ed517ea Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 19 Jun 2020 23:48:53 +0800 Subject: [PATCH 0709/1029] =?UTF-8?q?=E8=A1=A5=E5=85=85=20FreeSql.Generato?= =?UTF-8?q?r=20ManyToMany=20=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Generator/RazorContentManager.cs | 18 ++++++++++++++++-- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Extensions/FreeSql.Generator/RazorContentManager.cs b/Extensions/FreeSql.Generator/RazorContentManager.cs index a5d9de6b..baa57000 100644 --- a/Extensions/FreeSql.Generator/RazorContentManager.cs +++ b/Extensions/FreeSql.Generator/RazorContentManager.cs @@ -206,8 +206,7 @@ namespace @gen.NameSpace { @:#endregion } @if (isManyToMany) { -@: - @:#region 外键 => 导航属性,ManyToMany + var manyAny = false; foreach (var ft in gen.tables) { if (ft != gen.table) { var ftfks = ft.Foreigns.Where(ftfk => ftfk.Columns.Where(ftfkcol => ftfkcol.IsPrimary == false).Any() == false).ToArray(); @@ -230,15 +229,30 @@ namespace @gen.NameSpace { { fkTableName = fkTableName.Replace(rightft.Schema + ""."", """"); } + var middleTableName = (midft.Schema + ""."" + midft.Name).Trim('.'); + if (midft.Schema == ""public"" || midft.Schema == ""dbo"") + { + middleTableName = middleTableName.Replace(midft.Schema + ""."", """"); + } var csname = rightft.Name; + if (manyAny == false) + { + manyAny = true; @: + @:#region 外键 => 导航属性,ManyToMany + } +@: + @:[Navigate(ManyToMany = typeof(@gen.GetCsName(middleTableName)))] @:public@(isLazying ? "" virtual"" : """") List<@gen.GetCsName(fkTableName)> @gen.GetCsName(csname)s { get; set; } } } } } + if (manyAny) + { @: @:#endregion + } } } @gen.GetMySqlEnumSetDefine() diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + From 3d80bc0c4b9ee25f6d50d44b11074525def854ec Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 20 Jun 2020 11:07:41 +0800 Subject: [PATCH 0710/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20[JsonMap]=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=9C=A8=20lambda=20=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E4=B8=AD=E8=A7=A3=E6=9E=90=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 5 +++++ FreeSql/Internal/CommonExpression.cs | 30 ++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index d67d7994..b08dd7f2 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -141,6 +141,11 @@ namespace base_entity new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); var testconfigs11 = S_SysConfig.Select.ToList(); + var testconfigs111 = S_SysConfig.Select.ToList(a => a.Name); + var testconfigs112 = S_SysConfig.Select.ToList(a => a.Config); + var testconfigs1122 = S_SysConfig.Select.ToList(a => new { a.Name, a.Config }); + var testconfigs113 = S_SysConfig.Select.ToList(a => a.Config2); + var testconfigs1133 = S_SysConfig.Select.ToList(a => new { a.Name, a.Config2 }); var repo = BaseEntity.Orm.Select().Limit(10).ToList(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 0cafcea1..6507bd24 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -80,8 +80,15 @@ namespace FreeSql.Internal return false; case ExpressionType.Parameter: case ExpressionType.MemberAccess: - if (_common.GetTableByEntity(exp.Type) != null) - { //加载表所有字段 + if (_common.GetTableByEntity(exp.Type) != null && + //判断 [JsonMap] 并非导航对象 + (exp.NodeType == ExpressionType.Parameter || exp is MemberExpression expMem && ( + _common.GetTableByEntity(expMem.Expression.Type)?.ColumnsByCs.ContainsKey(expMem.Member.Name) == false || + expMem.Expression.NodeType == ExpressionType.Parameter && expMem.Expression.Type.IsAnonymousType()) //<>h__TransparentIdentifier 是 Linq To Sql 的类型判断,此时为匿名类型 + ) + ) + { + //加载表所有字段 var map = new List(); ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString); var tb = parent.Table = map.First().Table.Table; @@ -1272,9 +1279,24 @@ namespace FreeSql.Internal var exp2Type = exp2.Type; if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GetGenericArguments().LastOrDefault() ?? exp2.Type; - var tb2tmp = _common.GetTableByEntity(exp2Type); var mp2 = exp2 as MemberExpression; if (mp2?.Member.Name == "Key" && mp2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) continue; + + ColumnInfo col2 = null; + if (tb2?.ColumnsByCs.TryGetValue(mp2.Member.Name, out col2) == true) + { + if (tsc._selectColumnMap != null && find2 != null) + { + tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 }); + return ""; + } + name2 = col2.Attribute.Name; + tsc.SetMapColumnTmp(col2); + break; + } + //判断 [JsonMap] 并非导航对象,所以在上面提前判断 ColumnsByCs + + var tb2tmp = _common.GetTableByEntity(exp2Type); if (tb2tmp != null) { if (exp2.NodeType == ExpressionType.Parameter) @@ -1317,7 +1339,7 @@ namespace FreeSql.Internal throw new ArgumentException($"{tb2.DbName}.{mp2.Member.Name} 导航属性集合忘了 .AsSelect() 吗?如果在 ToList(a => a.{mp2.Member.Name}) 中使用,请移步参考 IncludeMany 文档。"); throw new ArgumentException($"{tb2.DbName} 找不到列 {mp2.Member.Name}"); } - var col2 = tb2.ColumnsByCs[mp2.Member.Name]; + col2 = tb2.ColumnsByCs[mp2.Member.Name]; if (tsc._selectColumnMap != null && find2 != null) { tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 }); From 46641807f953ca4c2432602242190176b62128ab Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 20 Jun 2020 11:10:31 +0800 Subject: [PATCH 0711/1029] v1.6.0-preview0620 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 312 ++++++++++-------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 187 insertions(+), 161 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index ad136138..aea3506c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 9f9a497f..8b07ec12 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e6f10e2b..ffbe3c16 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 4d6dd7a5..3ee5d9d1 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index da52b2f6..b35ee153 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0611 + 1.6.0-preview0620 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index e7cd2370..c7aba80e 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2bd16d7c..b8628fac 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 11b8e9d3..78a6942d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 897d706c..d87346b7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 7f3b7221..01940f0f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2417,137 +2417,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3194,12 +3063,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3270,12 +3133,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -3917,3 +3774,172 @@ +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 条件 + + + + diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 53791498..44043e3b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index d1e96566..02a270f6 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6f020774..c42e69ae 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f85165be..4f28bd36 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 04a0f691..42f590ea 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 9d63174c..5aa46bf1 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b9b3ef37..7ee3e480 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2046438b..c19d389e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ff6ec9aa..68d66e76 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0611 + 1.6.0-preview0620 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 4ddf4c01a60044a046ffbaff871b66d0a3d44ab5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 20 Jun 2020 17:45:15 +0800 Subject: [PATCH 0712/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=20SqlExt.Ca?= =?UTF-8?q?se().When(..).End()=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=87=BD?= =?UTF-8?q?=E6=95=B0=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 条件 - - - - From 73eb3c8b2180c3a35001ba6327a41dbf2a756ed1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 23 Jun 2020 14:48:06 +0800 Subject: [PATCH 0713/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20StringLength?= =?UTF-8?q?/MaxLength=20=E5=AF=B9=20byte[]=20=E7=9A=84=E6=94=AF=E6=8C=81?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 20 +++++++++ .../MySqlConnector/MySqlCodeFirstTest.cs | 33 +++++++++++++++ .../Dameng/DamengCodeFirstTest.cs | 2 + .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 33 +++++++++++++++ .../Oracle/OracleCodeFirstTest.cs | 2 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 33 +++++++++++++++ .../ShenTong/ShenTongCodeFirstTest.cs | 2 + .../SqlServer/SqlServerCodeFirstTest.cs | 33 +++++++++++++++ .../Sqlite/SqliteCodeFirstTest.cs | 33 +++++++++++++++ FreeSql/DataAnnotations/ColumnAttribute.cs | 5 ++- FreeSql/FreeSql.xml | 5 ++- FreeSql/Internal/UtilsExpressionTree.cs | 42 +++++++++++++++++++ 12 files changed, 239 insertions(+), 4 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index b08dd7f2..9d674f29 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -149,6 +149,26 @@ namespace base_entity var repo = BaseEntity.Orm.Select().Limit(10).ToList(); + + //void ConfigEntityProperty(object sender, FreeSql.Aop.ConfigEntityPropertyEventArgs e) + //{ + // if (e.Property.PropertyType == typeof(byte[])) + // { + // var orm = sender as IFreeSql; + // switch (orm.Ado.DataType) + // { + // case DataType.SqlServer: + // e.ModifyResult.DbType = "image"; + // break; + // case DataType.MySql: + // e.ModifyResult.DbType = "longblob"; + // break; + // } + // } + //} + //fsql.Aop.ConfigEntityProperty += ConfigEntityProperty; + + Task.Run(async () => { using (var uow = BaseEntity.Orm.CreateUnitOfWork()) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 9947a09a..6d04609c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using Xunit; @@ -98,6 +99,38 @@ namespace FreeSql.Tests.MySqlConnector public string Data { get; set; } } + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.mysql.Insert().NoneParameter().AppendData(item1).ExecuteAffrows()); + + item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + } + class TS_BLB01 + { + public Guid Id { get; set; } + [MaxLength(-2)] + public byte[] Data { get; set; } + } + [Fact] public void StringLength() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs index bb456652..bc5688c8 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using Xunit; @@ -76,6 +77,7 @@ namespace FreeSql.Tests.Dameng class TS_BLB01 { public Guid Id { get; set; } + [MaxLength(-1)] public byte[] Data { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 809cc6a3..4b927196 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using Xunit; @@ -98,6 +99,38 @@ namespace FreeSql.Tests.MySql public string Data { get; set; } } + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.mysql.Insert().NoneParameter().AppendData(item1).ExecuteAffrows()); + + item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + } + class TS_BLB01 + { + public Guid Id { get; set; } + [MaxLength(-2)] + public byte[] Data { get; set; } + } + [Fact] public void StringLength() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 8080c0fa..a751c4ea 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -3,6 +3,7 @@ using Newtonsoft.Json; using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using Xunit; @@ -101,6 +102,7 @@ namespace FreeSql.Tests.Oracle class TS_BLB01 { public Guid Id { get; set; } + [MaxLength(-1)] public byte[] Data { get; set; } } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index ca7ab03e..169a2707 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -7,6 +7,7 @@ using NpgsqlTypes; using System; using System.Collections; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Net; using System.Net.NetworkInformation; @@ -17,6 +18,38 @@ namespace FreeSql.Tests.PostgreSQL { public class PostgreSQLCodeFirstTest { + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.pgsql.Insert(item1).ExecuteAffrows()); + + var item2 = g.pgsql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.pgsql.Insert().NoneParameter().AppendData(item1).ExecuteAffrows()); + + item2 = g.pgsql.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + } + class TS_BLB01 + { + public Guid Id { get; set; } + [MaxLength(-1)] + public byte[] Data { get; set; } + } + [Fact] public void StringLength() { diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs index 23475c9f..4f4dbba4 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using System; using System.Collections; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Net; using System.Net.NetworkInformation; @@ -12,6 +13,7 @@ namespace FreeSql.Tests.ShenTong { public class ShenTongCodeFirstTest { + [Fact] public void StringLength() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index a835f5e5..e9334de5 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -3,6 +3,7 @@ using FreeSql.Tests.DataContext.SqlServer; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using Xunit; @@ -11,6 +12,38 @@ namespace FreeSql.Tests.SqlServer { public class SqlServerCodeFirstTest { + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.sqlserver.Insert(item1).ExecuteAffrows()); + + var item2 = g.sqlserver.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.sqlserver.Insert().NoneParameter().AppendData(item1).ExecuteAffrows()); + + item2 = g.sqlserver.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + } + class TS_BLB01 + { + public Guid Id { get; set; } + [MaxLength(-1)] + public byte[] Data { get; set; } + } + [Fact] public void StringLength() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index e8084e14..98ecf805 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using Xunit; @@ -10,6 +11,38 @@ namespace FreeSql.Tests.Sqlite { public class SqliteCodeFirstTest { + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.sqlite.Insert(item1).ExecuteAffrows()); + + var item2 = g.sqlite.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.sqlite.Insert().NoneParameter().AppendData(item1).ExecuteAffrows()); + + item2 = g.sqlite.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + } + class TS_BLB01 + { + public Guid Id { get; set; } + [MaxLength(-1)] + public byte[] Data { get; set; } + } + [Fact] public void StringLength() { diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index ae45c75c..b6b11569 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -79,7 +79,7 @@ namespace FreeSql.DataAnnotations internal int? _StringLength; /// - /// 设置长度,针对 string 类型避免 DbType 的繁琐设置 + /// 设置长度,针对 string/byte[] 类型避免 DbType 的繁琐设置 /// 提示:也可以使用 [MaxLength(100)] /// --- /// StringLength = 100 时,对应 DbType: @@ -90,11 +90,12 @@ namespace FreeSql.DataAnnotations /// Sqlite -> nvarchar(100) /// --- /// StringLength < 0 时,对应 DbType: - /// MySql -> text (StringLength = -2 时,对应 DbType longtext) + /// MySql -> text (StringLength = -2 时,对应 longtext) /// SqlServer -> nvarchar(max) /// PostgreSQL -> text /// Oracle -> nclob /// Sqlite -> text + /// v1.6.0+ byte[] 支持设置 StringLength /// public int StringLength { get => _StringLength ?? 0; set => _StringLength = value; } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 7f3b7221..b749f144 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -80,7 +80,7 @@ - 设置长度,针对 string 类型避免 DbType 的繁琐设置 + 设置长度,针对 string/byte[] 类型避免 DbType 的繁琐设置 提示:也可以使用 [MaxLength(100)] --- StringLength = 100 时,对应 DbType: @@ -91,11 +91,12 @@ Sqlite -> nvarchar(100) --- StringLength < 0 时,对应 DbType: - MySql -> text (StringLength = -2 时,对应 DbType longtext) + MySql -> text (StringLength = -2 时,对应 longtext) SqlServer -> nvarchar(max) PostgreSQL -> text Oracle -> nclob Sqlite -> text + v1.6.0+ byte[] 支持设置 StringLength diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index b45f3d28..272e09e7 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -272,6 +272,48 @@ namespace FreeSql.Internal break; } } + if (colattr.MapType == typeof(byte[]) && colattr.StringLength != 0) + { + int strlen = colattr.StringLength; + var charPatten = @"(VARBINARY|BINARY|BYTEA)\s*(\([^\)]*\))?"; + switch (common._orm.Ado.DataType) + { + case DataType.MySql: + case DataType.OdbcMySql: + if (strlen == -2) colattr.DbType = "LONGBLOB"; + else if (strlen < 0) colattr.DbType = "BLOB"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.SqlServer: + case DataType.OdbcSqlServer: + if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(MAX)"); + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: + case DataType.ShenTong: //驱动引发的异常:“System.Data.OscarClient.OscarException”(位于 System.Data.OscarClient.dll 中) + colattr.DbType = "BYTEA"; //变长二进制串 + break; + case DataType.Oracle: + colattr.DbType = "BLOB"; + break; + case DataType.Dameng: + colattr.DbType = "BLOB"; + break; + case DataType.OdbcOracle: + case DataType.OdbcDameng: + colattr.DbType = "BLOB"; + break; + case DataType.Sqlite: + colattr.DbType = "BLOB"; + break; + case DataType.MsAccess: + if (strlen < 0) colattr.DbType = "BLOB"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; + } + } if (trytb.Columns.ContainsKey(colattr.Name)) throw new Exception($"ColumnAttribute.Name {colattr.Name} 重复存在,请检查(注意:不区分大小写)"); if (trytb.ColumnsByCs.ContainsKey(p.Name)) throw new Exception($"属性名 {p.Name} 重复存在,请检查(注意:不区分大小写)"); From e54b22cee54f75e339de6c144a70eda303e4dfba Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 23 Jun 2020 17:12:16 +0800 Subject: [PATCH 0714/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20SqlExt.Group?= =?UTF-8?q?Concat=20MySql=20=E5=87=BD=E6=95=B0=E8=A7=A3=E5=86=B3=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 37 +++- .../FreeSqlGlobalExpressionCallExtensions.cs | 195 ++++++++++++++---- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 1 + FreeSql/FreeSql.xml | 71 +++++++ 4 files changed, 263 insertions(+), 41 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index a0be59b2..54f51f72 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -155,6 +155,37 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var sqlextGroupConcat = g.mysql.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(), + groupct1 = SqlExt.GroupConcat(a.Id).Distinct().OrderBy(b.EdiId).Separator("_").ToValue() + }); + var sqlextGroupConcatToList = g.mysql.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(), + groupct1 = SqlExt.GroupConcat(a.Id).Distinct().OrderBy(b.EdiId).Separator("_").ToValue() + }); + var sqlextCase = g.sqlserver.Select() .InnerJoin((a, b) => b.Id == a.Id) .ToSql((a, b) => new @@ -167,7 +198,8 @@ namespace FreeSql.Tests .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() + .End(), + over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue(), }); var sqlextCaseToList = g.sqlserver.Select() .InnerJoin((a, b) => b.Id == a.Id) @@ -181,7 +213,8 @@ namespace FreeSql.Tests .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() + .End(), + over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue(), }); diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index 7fe955da..abbcb35e 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; +using static FreeSql.SqlExtExtensions; [ExpressionCall] public static class FreeSqlGlobalExpressionCallExtensions @@ -46,99 +47,215 @@ public static class FreeSqlGlobalExpressionCallExtensions namespace FreeSql { + /// + /// SqlExt 是利用自定表达式函数解析功能,解析默认常用的SQL函数,欢迎 PR + /// [ExpressionCall] public static class SqlExt { - public static ThreadLocal expContext = new ThreadLocal(); + internal static ThreadLocal expContext = new ThreadLocal(); - public static ISqlOver Rank() => Over("RANK()"); - public static ISqlOver DenseRank() => Over("DENSE_RANK()"); - public static ISqlOver Count() => Over("COUNT()"); - public static ISqlOver Sum(object column) => Over($"Sum({expContext.Value.ParsedContent["column"]})"); - public static ISqlOver Avg() => Over($"AVG({expContext.Value.ParsedContent["column"]})"); - public static ISqlOver Max(T column) => Over($"MAX({expContext.Value.ParsedContent["column"]})"); - public static ISqlOver Min(T column) => Over($"MIN({expContext.Value.ParsedContent["column"]})"); - public static ISqlOver RowNumber() => Over("ROW_NUMBER()"); + #region SqlServer/PostgreSQL over + /// + /// rank() over(order by ...) + /// + /// + public static ISqlOver Rank() => Over("rank()"); + /// + /// dense_rank() over(order by ...) + /// + /// + public static ISqlOver DenseRank() => Over("dense_rank()"); + /// + /// count() over(order by ...) + /// + /// + public static ISqlOver Count() => Over("count()"); + /// + /// sum(..) over(order by ...) + /// + /// + /// + public static ISqlOver Sum(object column) => Over($"sum({expContext.Value.ParsedContent["column"]})"); + /// + /// avg(..) over(order by ...) + /// + /// + public static ISqlOver Avg() => Over($"avg({expContext.Value.ParsedContent["column"]})"); + /// + /// max(..) over(order by ...) + /// + /// + /// + /// + public static ISqlOver Max(T column) => Over($"max({expContext.Value.ParsedContent["column"]})"); + /// + /// min(..) over(order by ...) + /// + /// + /// + /// + public static ISqlOver Min(T column) => Over($"min({expContext.Value.ParsedContent["column"]})"); + /// + /// SqlServer row_number() over(order by ...) + /// + /// + public static ISqlOver RowNumber() => Over("row_number()"); + #endregion + + /// + /// case when .. then .. end + /// + /// + public static ICaseWhenEnd Case() => SqlExtExtensions.Case(); + /// + /// MySql group_concat(distinct .. order by .. separator ..) + /// + /// + /// + public static IGroupConcat GroupConcat(object column) => SqlExtExtensions.GroupConcat(column); + } + + [ExpressionCall] + public static class SqlExtExtensions //这个类存在的意义,是不想使用者方法名污染 + { + static ThreadLocal expContextSelf = new ThreadLocal(); + static ExpressionCallContext expContext => expContextSelf.Value ?? SqlExt.expContext.Value; + internal static ThreadLocal> expSb = new ThreadLocal>(); + internal static ExpSbInfo expSbLast => expSb.Value.Last(); + internal class ExpSbInfo + { + public StringBuilder Sb { get; } = new StringBuilder(); + public bool IsOrderBy = false; + public bool IsDistinct = false; + } #region .. over([partition by ..] order by ...) - static ThreadLocal expOverSb = new ThreadLocal(); - static ThreadLocal expOverSbIsOrderBy = new ThreadLocal(); - static ISqlOver Over(string sqlFunc) + internal static ISqlOver Over(string sqlFunc) { - expOverSb.Value = new StringBuilder(); - expOverSbIsOrderBy.Value = false; - expOverSb.Value.Append($"{sqlFunc} "); + if (expSb.Value == null) expSb.Value = new List(); + expSb.Value.Add(new ExpSbInfo()); + expSbLast.Sb.Append(sqlFunc).Append(" "); return null; } public static ISqlOver Over(this ISqlOver that) { - expOverSb.Value.Append("OVER("); + expSbLast.Sb.Append("over("); return that; } public static ISqlOver PartitionBy(this ISqlOver that, object column) { - expOverSb.Value.Append("PARTITION BY ").Append(expContext.Value.ParsedContent["column"]).Append(","); + expSbLast.Sb.Append(" partition by ").Append(expContext.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) + public static ISqlOver OrderBy(this ISqlOver that, object column) => OrderByPriv(that, false); + public static ISqlOver OrderByDescending(this ISqlOver that, object column) => OrderByPriv(that, true); + static ISqlOver OrderByPriv(this ISqlOver that, bool isDesc) { - var sb = expOverSb.Value; - if (expOverSbIsOrderBy.Value == false) + var sb = expSbLast.Sb; + if (expSbLast.IsOrderBy == false) { - sb.Append("ORDER BY "); - expOverSbIsOrderBy.Value = true; + sb.Append(" order by "); + expSbLast.IsOrderBy = true; } - sb.Append(expContext.Value.ParsedContent["column"]); + sb.Append(expContext.ParsedContent["column"]); if (isDesc) sb.Append(" desc"); sb.Append(","); return that; } public static TValue ToValue(this ISqlOver that) { - var sb = expOverSb.Value.ToString().TrimEnd(','); - expOverSb.Value.Clear(); - expContext.Value.Result = $"{sb})"; + var sql = expSbLast.Sb.ToString().TrimEnd(','); + expSbLast.Sb.Clear(); + expSb.Value.RemoveAt(expSb.Value.Count - 1); + expContext.Result = $"{sql})"; 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 ")); + if (expSb.Value == null) expSb.Value = new List(); + expSb.Value.Add(new ExpSbInfo()); + expSbLast.Sb.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"]); + expSbLast.Sb.Append($"\r\n{"".PadRight(expSb.Value.Count * 2)}when ").Append(expContext.ParsedContent["test"]).Append(" then ").Append(expContext.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"]); + expSbLast.Sb.Append($"\r\n{"".PadRight(expSb.Value.Count * 2)}when ").Append(expContext.ParsedContent["test"]).Append(" then ").Append(expContext.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"]); + expSbLast.Sb.Append($"\r\n{"".PadRight(expSb.Value.Count * 2)}else ").Append(expContext.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; + var sql = expSbLast.Sb.Append($"\r\n{"".PadRight(expSb.Value.Count * 2 - 2)}end").ToString(); + expSbLast.Sb.Clear(); + expSb.Value.RemoveAt(expSb.Value.Count - 1); + expContext.Result = sql; return default; } public interface ICaseWhenEnd { } public interface ICaseWhenEnd { } #endregion + + #region group_concat + public static IGroupConcat GroupConcat(object column) + { + if (expSb.Value == null) expSb.Value = new List(); + expSb.Value.Add(new ExpSbInfo()); + expSbLast.Sb.Append("group_concat(").Append(expContext.ParsedContent["column"]); + return null; + } + public static IGroupConcat Distinct(this IGroupConcat that) + { + if (expSbLast.IsDistinct == false) + { + expSbLast.Sb.Insert(expSbLast.Sb.ToString().LastIndexOf("group_concat(") + 13, "distinct "); + expSbLast.IsDistinct = true; + } + return that; + } + public static IGroupConcat Separator(this IGroupConcat that, object separator) + { + if (expSbLast.IsOrderBy) expSbLast.Sb.Remove(expSbLast.Sb.Length - 1, 1); + expSbLast.Sb.Append(" separator ").Append(expContext.ParsedContent["separator"]); + return that; + } + public static IGroupConcat OrderBy(this IGroupConcat that, object column) => OrderByPriv(that, false); + public static IGroupConcat OrderByDescending(this IGroupConcat that, object column) => OrderByPriv(that, true); + static IGroupConcat OrderByPriv(this IGroupConcat that, bool isDesc) + { + var sb = expSbLast.Sb; + if (expSbLast.IsOrderBy == false) + { + sb.Append(" order by "); + expSbLast.IsOrderBy = true; + } + sb.Append(expContext.ParsedContent["column"]); + if (isDesc) sb.Append(" desc"); + sb.Append(","); + return that; + } + public static string ToValue(this IGroupConcat that) + { + var sql = expSbLast.Sb.ToString().TrimEnd(','); + expSbLast.Sb.Clear(); + expSb.Value.RemoveAt(expSb.Value.Count - 1); + expContext.Result = $"{sql})"; + return default; + } + public interface IGroupConcat { } + #endregion } } \ No newline at end of file diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 9537f680..ab1b955e 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -130,6 +130,7 @@ public static partial class FreeSqlGlobalExtensions if (that == typeof(string)) return default(string); if (that == typeof(Guid)) return default(Guid); if (that.IsArray) return Array.CreateInstance(that, 0); + if (that.IsInterface || that.IsAbstract) return null; var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters(); if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, true); return Activator.CreateInstance(that, ctorParms diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b749f144..5d1ff11c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -684,6 +684,77 @@ + + + SqlExt 是利用自定表达式函数解析功能,解析默认常用的SQL函数,欢迎 PR + + + + + rank() over(order by ...) + + + + + + dense_rank() over(order by ...) + + + + + + count() over(order by ...) + + + + + + sum(..) over(order by ...) + + + + + + + avg(..) over(order by ...) + + + + + + max(..) over(order by ...) + + + + + + + + min(..) over(order by ...) + + + + + + + + SqlServer row_number() over(order by ...) + + + + + + case when .. then .. end + + + + + + MySql group_concat(distinct .. order by .. separator ..) + + + + 使用连接串(推荐) From 9a7eb967094adb163346a12efef4013ef7b0bbc5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 23 Jun 2020 17:16:10 +0800 Subject: [PATCH 0715/1029] v1.6.0-preview0623 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index aea3506c..9e4308f4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 8b07ec12..0155dbaf 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ffbe3c16..fc0a9f0e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 3ee5d9d1..5a39cef0 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index b35ee153..f9645e51 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0620 + 1.6.0-preview0623 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index c7aba80e..e6343a29 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b8628fac..cb912c2b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 78a6942d..ea945e79 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index d87346b7..2dad85df 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 44043e3b..c9a9074a 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 02a270f6..016e6bcc 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c42e69ae..15105602 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4f28bd36..23d5ff65 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 42f590ea..3d287855 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 5aa46bf1..bb9c4ef8 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7ee3e480..b8ca94f2 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c19d389e..2f1dd062 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 68d66e76..b11c9c65 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0620 + 1.6.0-preview0623 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From ec077ba7a35155fa800f6eacaa540885d1ad8d45 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 24 Jun 2020 12:21:24 +0800 Subject: [PATCH 0716/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20sqlserver=20?= =?UTF-8?q?=E8=A1=A8=E4=B8=AD=E5=B8=A6=E7=82=B9=20codefirst=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests.Provider.Odbc.xml | 10 ++++++ .../SqlServer/SqlServerCodeFirstTest.cs | 34 +++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 15 ++++++++ .../SqlServer/SqlServerCodeFirstTest.cs | 34 +++++++++++++++++++ .../SqlServer/OdbcSqlServerCodeFirst.cs | 24 +++++++------ .../SqlServerCodeFirst.cs | 24 +++++++------ 6 files changed, 119 insertions(+), 22 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml index 95f041b4..81f32e84 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml @@ -9,6 +9,16 @@ 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert + + + 表中带点 + + + + + 主键 + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index a0e1bb2d..77987554 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -28,6 +28,40 @@ namespace FreeSql.Tests.Odbc.SqlServer public string TitleSub { get; set; } } + [Fact] + public void е() + { + var item = new tbdot01 { name = "insert" }; + g.sqlserver.Insert(item).ExecuteAffrows(); + + var find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("insert", find.name); + + Assert.Equal(1, g.sqlserver.Update().Set(a => a.name == "update").Where(a => a.id == item.id).ExecuteAffrows()); + find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("update", find.name); + + Assert.Equal(1, g.sqlserver.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.Null(find); + } + /// + /// д + /// + [Table(Name = "[freesql.T].[dbo].[sys.tbdot01]")] + class tbdot01 + { + /// + /// + /// + public Guid id { get; set; } + public string name { get; set; } + } + [Fact] public void ı_ֶ() { diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 6750270a..31e282c8 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -9,6 +9,16 @@ 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert + + + 表中带点 + + + + + 主键 + + @@ -262,6 +272,11 @@ 导航属性 + + + 设置字符串的 Include,使用方法和格式跟 EF Core 一样 + + 调价单 diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index e9334de5..be6415ff 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -60,6 +60,40 @@ namespace FreeSql.Tests.SqlServer public string TitleSub { get; set; } } + [Fact] + public void е() + { + var item = new tbdot01 { name = "insert" }; + g.sqlserver.Insert(item).ExecuteAffrows(); + + var find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("insert", find.name); + + Assert.Equal(1, g.sqlserver.Update().Set(a => a.name == "update").Where(a => a.id == item.id).ExecuteAffrows()); + find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("update", find.name); + + Assert.Equal(1, g.sqlserver.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.Null(find); + } + /// + /// д + /// + [Table(Name = "[freesql.T].[dbo].[sys.tbdot01]")] + class tbdot01 + { + /// + /// + /// + public Guid id { get; set; } + public string name { get; set; } + } + [Fact] public void ı_ֶ() { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index d6eae2bc..73519a67 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -204,8 +204,8 @@ ELSE if (tboldname == null) { //创建表 - var createTableName = _commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}"); - sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(createTableName).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName(tbname[1], tbname[2]); + sb.Append("use [").Append(tbname[0]).Append("];\r\nCREATE TABLE ").Append(createTableName).Append(" ( "); var pkidx = 0; foreach (var tbcol in tb.ColumnsByPosition) { @@ -252,7 +252,7 @@ ELSE //如果新表,旧表在一个数据库和模式下,直接修改表名 if (string.Compare(tbname[0], tboldname[0], true) == 0 && string.Compare(tbname[1], tboldname[1], true) == 0) - sbalter.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(_commonUtils.FormatSql(";\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"), tbname[2])); + sbalter.Append("use [").Append(tbname[0]).Append(_commonUtils.FormatSql("];\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName(tboldname[0], tboldname[1], tboldname[2]), tbname[2])); else { //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 @@ -317,7 +317,7 @@ use [" + database + "];", tboldname ?? tbname); continue; } //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1], tbname[2])).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" default(").Append(GetTransferDbDefaultValue(tbcol)).Append(")"); sbalter.Append(";\r\n"); @@ -345,10 +345,10 @@ use [" + database + "];", tboldname ?? tbname); var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -361,18 +361,20 @@ use [" + database + "];", tboldname ?? tbname); } if (istmpatler == false) { - var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)")); + var dbcommentsql = $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)"; + if (string.Compare(tbname[0], database, true) != 0) dbcommentsql = $"use [{tbname[0]}];{dbcommentsql};use [{database}];"; + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, dbcommentsql)); if (dbcomment != (tb.Comment ?? "")) - AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); + AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tb.Comment); if (sbalter.Length > 0) - sb.Append(sbalter).Append("\r\nuse " + database); + sb.Append($"use [{tbname[0]}];").Append(sbalter).Append("\r\nuse [").Append(database).Append("];"); continue; } //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 bool idents = false; - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.FreeSqlTmp_{tbname[2]}"); + var tablename = tboldname == null ? _commonUtils.QuoteSqlName(tbname[0], tbname[1], tbname[2]) : _commonUtils.QuoteSqlName(tboldname[0], tboldname[1], tboldname[2]); + var tmptablename = _commonUtils.QuoteSqlName(tbname[0], tbname[1], $"FreeSqlTmp_{tbname[2]}"); sb.Append("BEGIN TRANSACTION\r\n") .Append("SET QUOTED_IDENTIFIER ON\r\n") .Append("SET ARITHABORT ON\r\n") diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index c5f0959e..38e38853 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -203,8 +203,8 @@ ELSE if (tboldname == null) { //创建表 - var createTableName = _commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}"); - sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(createTableName).Append(" ( "); + var createTableName = _commonUtils.QuoteSqlName(tbname[1], tbname[2]); + sb.Append("use [").Append(tbname[0]).Append("];\r\nCREATE TABLE ").Append(createTableName).Append(" ( "); var pkidx = 0; foreach (var tbcol in tb.ColumnsByPosition) { @@ -251,7 +251,7 @@ ELSE //如果新表,旧表在一个数据库和模式下,直接修改表名 if (string.Compare(tbname[0], tboldname[0], true) == 0 && string.Compare(tbname[1], tboldname[1], true) == 0) - sbalter.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(_commonUtils.FormatSql(";\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"), tbname[2])); + sbalter.Append("use [").Append(tbname[0]).Append(_commonUtils.FormatSql("];\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName(tboldname[0], tboldname[1], tboldname[2]), tbname[2])); else { //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 @@ -316,7 +316,7 @@ use [" + database + "];", tboldname ?? tbname); continue; } //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1], tbname[2])).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" default(").Append(GetTransferDbDefaultValue(tbcol)).Append(")"); sbalter.Append(";\r\n"); @@ -344,10 +344,10 @@ use [" + database + "];", tboldname ?? tbname); var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -360,18 +360,20 @@ use [" + database + "];", tboldname ?? tbname); } if (istmpatler == false) { - var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)")); + var dbcommentsql = $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)"; + if (string.Compare(tbname[0], database, true) != 0) dbcommentsql = $"use [{tbname[0]}];{dbcommentsql};use [{database}];"; + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, dbcommentsql)); if (dbcomment != (tb.Comment ?? "")) - AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); + AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tb.Comment); if (sbalter.Length > 0) - sb.Append(sbalter).Append("\r\nuse " + database); + sb.Append($"use [{tbname[0]}];").Append(sbalter).Append("\r\nuse [").Append(database).Append("];"); continue; } //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 bool idents = false; - var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.FreeSqlTmp_{tbname[2]}"); + var tablename = tboldname == null ? _commonUtils.QuoteSqlName(tbname[0], tbname[1], tbname[2]) : _commonUtils.QuoteSqlName(tboldname[0], tboldname[1], tboldname[2]); + var tmptablename = _commonUtils.QuoteSqlName(tbname[0], tbname[1], $"FreeSqlTmp_{tbname[2]}"); sb.Append("BEGIN TRANSACTION\r\n") .Append("SET QUOTED_IDENTIFIER ON\r\n") .Append("SET ARITHABORT ON\r\n") From 889af5e40c206d16737d4a29438c70c72e12907d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 24 Jun 2020 12:31:56 +0800 Subject: [PATCH 0717/1029] v1.6.0-preview0624 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 5 ----- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 9e4308f4..86001bb8 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0155dbaf..8073c4c7 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index fc0a9f0e..4e17fef1 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 5a39cef0..a9754f39 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index f9645e51..6fd1408d 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0623 + 1.6.0-preview0624 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index e6343a29..518347f7 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index cb912c2b..e3c0bba6 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index ea945e79..2c5272bb 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 31e282c8..3cae4dac 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -272,11 +272,6 @@ 导航属性 - - - 设置字符串的 Include,使用方法和格式跟 EF Core 一样 - - 调价单 diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2dad85df..0d1e2f35 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index c9a9074a..60e9ab55 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 016e6bcc..5e201425 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 15105602..8f258e47 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 23d5ff65..6f31314f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3d287855..bcfb5ad4 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index bb9c4ef8..8a0a3f85 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b8ca94f2..0b4b0bb6 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2f1dd062..b98e553d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index b11c9c65..07b680ce 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0623 + 1.6.0-preview0624 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From dc8f575b18bd3e495f5afebba64f1605d3ecece2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 26 Jun 2020 07:58:09 +0800 Subject: [PATCH 0718/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20sqlserver=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20cast(..=20as=20nvarchar)=20=E6=88=AA?= =?UTF-8?q?=E6=96=AD=E9=95=BF=E5=BA=A6=2030=20=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B#335?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SqlServer/Curd/SqlServerSelectTest.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 2 +- .../SqlServer/OdbcSqlServerExpression.cs | 26 +++++++++++++------ .../SqlServerExpression.cs | 25 ++++++++++++------ 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index ff5031e9..ffd98967 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -876,7 +876,7 @@ FROM [tb_topic22] a", subquery); var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a -WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] +WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] FROM [tb_topic22] b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index d21f844e..dd8daa73 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -925,7 +925,7 @@ FROM [tb_topic22] a", subquery); var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a -WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] +WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] FROM [tb_topic22] b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 086a6daf..1f4bb307 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -36,7 +36,10 @@ namespace FreeSql.Odbc.SqlServer case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)"; case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; - case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)"; + case "System.String": + return gentype == typeof(Guid) ? + $"cast({getExp(operandExp)} as varchar(36))" : + $"cast({getExp(operandExp)} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})"; case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)"; case "System.UInt32": return $"cast({getExp(operandExp)} as int)"; case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)"; @@ -86,7 +89,10 @@ namespace FreeSql.Odbc.SqlServer if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; return null; case "ToString": - if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null; + var gentype2 = callExp.Object.Type.NullableTypeOrThis(); + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (gentype2 == typeof(Guid) ? + $"cast({getExp(callExp.Object)} as varchar(36))" : + $"cast({getExp(callExp.Object)} as nvarchar{(gentype2.IsNumberType() || gentype2.IsEnum ? "(100)" : "(max)")})") : null; return null; } @@ -262,10 +268,10 @@ namespace FreeSql.Odbc.SqlServer case "Contains": var args0Value = getExp(exp.Arguments[0]); if (args0Value == "NULL") return $"({left}) IS NULL"; - if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar(max))+'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar(max)))")}"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')"; + return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar(max))+'%')"; case "ToLower": return $"lower({left})"; case "ToUpper": return $"upper({left})"; case "Substring": @@ -336,7 +342,7 @@ namespace FreeSql.Odbc.SqlServer switch (exp.Method.Name) { case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; - case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))"; + case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar(100)) + '-' + cast({getExp(exp.Arguments[1])} as varchar(100)) + '-1')))"; case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; case "IsLeapYear": @@ -454,7 +460,7 @@ namespace FreeSql.Odbc.SqlServer case "Subtract": return $"({left}-({args1}))"; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"({left}-({args1}))"; - case "ToString": return $"cast({left} as varchar)"; + case "ToString": return $"cast({left} as varchar(100))"; } } return null; @@ -477,7 +483,11 @@ namespace FreeSql.Odbc.SqlServer case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; - case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)"; + case "ToString": + var gentype = exp.Arguments[0].Type.NullableTypeOrThis(); + return gentype == typeof(Guid) ? + $"cast({getExp(exp.Arguments[0])} as varchar(36))" : + $"cast({getExp(exp.Arguments[0])} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})"; case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index a657b039..78f44002 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -36,7 +36,9 @@ namespace FreeSql.SqlServer case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)"; case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; - case "System.String": return operandExp.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(operandExp)} as varchar(36))" : $"cast({getExp(operandExp)} as nvarchar)"; + case "System.String": return gentype == typeof(Guid) ? + $"cast({getExp(operandExp)} as varchar(36))" : + $"cast({getExp(operandExp)} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})"; case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)"; case "System.UInt32": return $"cast({getExp(operandExp)} as int)"; case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)"; @@ -86,7 +88,10 @@ namespace FreeSql.SqlServer if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; return null; case "ToString": - if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (callExp.Object.Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(callExp.Object)} as varchar(36))" : $"cast({getExp(callExp.Object)} as nvarchar)") : null; + var gentype2 = callExp.Object.Type.NullableTypeOrThis(); + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (gentype2 == typeof(Guid) ? + $"cast({getExp(callExp.Object)} as varchar(36))" : + $"cast({getExp(callExp.Object)} as nvarchar{(gentype2.IsNumberType() || gentype2.IsEnum ? "(100)" : "(max)")})") : null; return null; } @@ -262,10 +267,10 @@ namespace FreeSql.SqlServer case "Contains": var args0Value = getExp(exp.Arguments[0]); if (args0Value == "NULL") return $"({left}) IS NULL"; - if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar(max))+'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar(max)))")}"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')"; + return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar(max))+'%')"; case "ToLower": return $"lower({left})"; case "ToUpper": return $"upper({left})"; case "Substring": @@ -336,7 +341,7 @@ namespace FreeSql.SqlServer switch (exp.Method.Name) { case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; - case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar) + '-' + cast({getExp(exp.Arguments[1])} as varchar) + '-1')))"; + case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar(100)) + '-' + cast({getExp(exp.Arguments[1])} as varchar(100)) + '-1')))"; case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; case "IsLeapYear": @@ -452,7 +457,7 @@ namespace FreeSql.SqlServer case "Subtract": return $"({left}-({args1}))"; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"({left}-({args1}))"; - case "ToString": return $"cast({left} as varchar)"; + case "ToString": return $"cast({left} as varchar(100))"; } } return null; @@ -475,7 +480,11 @@ namespace FreeSql.SqlServer case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; - case "ToString": return exp.Arguments[0].Type.NullableTypeOrThis() == typeof(Guid) ? $"cast({getExp(exp.Arguments[0])} as varchar(36))" : $"cast({getExp(exp.Arguments[0])} as nvarchar)"; + case "ToString": + var gentype = exp.Arguments[0].Type.NullableTypeOrThis(); + return gentype == typeof(Guid) ? + $"cast({getExp(exp.Arguments[0])} as varchar(36))" : + $"cast({getExp(exp.Arguments[0])} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})"; case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; From 4cde2a328087879fa67be68fc703ad7102e06bec Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 27 Jun 2020 04:21:00 +0800 Subject: [PATCH 0719/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.AsCt?= =?UTF-8?q?eTree()=20=E9=80=92=E5=BD=92=E6=9F=A5=E8=AF=A2=E6=A0=91?= =?UTF-8?q?=E8=A1=A8=E6=89=80=E6=9C=89=E5=AD=90=E8=AE=B0=E5=BD=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---- .../MySqlConnector/Curd/MySqlSelectTest.cs | 24 +++++- .../Dameng/Curd/DamengSelectTest.cs | 24 +++++- .../KingbaseES/Curd/KingbaseESSelectTest.cs | 24 +++++- .../MySql/Curd/MySqlSelectTest.cs | 24 +++++- .../Oracle/Curd/OracleSelectTest.cs | 24 +++++- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 24 +++++- .../SqlServer/Curd/SqlServerSelectTest.cs | 24 +++++- .../Dameng/Curd/DamengSelectTest.cs | 24 +++++- .../MySql/Curd/MySqlSelectTest.cs | 24 +++++- .../Oracle/Curd/OracleSelectTest.cs | 24 +++++- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 24 +++++- .../SqlServer/Curd/SqlServerSelectTest.cs | 24 +++++- .../Sqlite/Curd/SqliteSelectTest.cs | 24 +++++- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 76 +++++++++++++++++++ FreeSql/FreeSql.xml | 10 +++ .../CommonProvider/AdoProvider/AdoProvider.cs | 2 +- .../AdoProvider/AdoProviderAsync.cs | 2 +- .../AdoProvider/AdoProviderUtils.cs | 6 ++ .../SelectProvider/Select0Provider.cs | 4 +- 20 files changed, 395 insertions(+), 33 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.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 554be95f..956d0aaf 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1865,7 +1865,7 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1903,6 +1903,28 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + //Assert.Single(t3); + //Assert.Equal("100000", t3[0].Code); + //Assert.Single(t3[0].Childs); + //Assert.Equal("110000", t3[0].Childs[0].Code); + //Assert.Equal(2, t3[0].Childs[0].Childs.Count); + //Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + //Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + //Assert.Equal(4, t3.Count); + //Assert.Equal("100000", t3[0].Code); + //Assert.Equal("110000", t3[1].Code); + //Assert.Equal("110100", t3[2].Code); + //Assert.Equal("110101", t3[3].Code); + + //t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + //Assert.Equal(3, t3.Count); + //Assert.Equal("110000", t3[0].Code); + //Assert.Equal("110100", t3[1].Code); + //Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 20705c2a..6eeafa37 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -1715,7 +1715,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1753,6 +1753,28 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs index fed8ea69..0e0d8697 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs @@ -1680,7 +1680,7 @@ WHERE ((((a.""ID"")::varchar) in (SELECT b.""TITLE"" new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1718,6 +1718,28 @@ WHERE ((((a.""ID"")::varchar) in (SELECT b.""TITLE"" Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index fc1cd64f..546a0e06 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1876,7 +1876,7 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1914,6 +1914,28 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + //Assert.Single(t3); + //Assert.Equal("100000", t3[0].Code); + //Assert.Single(t3[0].Childs); + //Assert.Equal("110000", t3[0].Childs[0].Code); + //Assert.Equal(2, t3[0].Childs[0].Childs.Count); + //Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + //Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + //Assert.Equal(4, t3.Count); + //Assert.Equal("100000", t3[0].Code); + //Assert.Equal("110000", t3[1].Code); + //Assert.Equal("110100", t3[2].Code); + //Assert.Equal("110101", t3[3].Code); + + //t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + //Assert.Equal(3, t3.Count); + //Assert.Equal("110000", t3[0].Code); + //Assert.Equal("110100", t3[1].Code); + //Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index fa4e36d9..8b849b1a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -1716,7 +1716,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1754,6 +1754,28 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index f0e048a1..96cec0f8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1775,7 +1775,7 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1813,6 +1813,28 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index ffd98967..92b4fe3f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -1666,7 +1666,7 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1704,6 +1704,28 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index c19346f9..c6e2751f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -1716,7 +1716,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1754,6 +1754,28 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index bfe8db80..d4166792 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1929,7 +1929,7 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1967,6 +1967,28 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + //Assert.Single(t3); + //Assert.Equal("100000", t3[0].Code); + //Assert.Single(t3[0].Childs); + //Assert.Equal("110000", t3[0].Childs[0].Code); + //Assert.Equal(2, t3[0].Childs[0].Childs.Count); + //Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + //Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + //Assert.Equal(4, t3.Count); + //Assert.Equal("100000", t3[0].Code); + //Assert.Equal("110000", t3[1].Code); + //Assert.Equal("110100", t3[2].Code); + //Assert.Equal("110101", t3[3].Code); + + //t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + //Assert.Equal(3, t3.Count); + //Assert.Equal("110000", t3[0].Code); + //Assert.Equal("110100", t3[1].Code); + //Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index c61ce957..3a922613 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -1716,7 +1716,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1754,6 +1754,28 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index db9854e2..4ce6ea32 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1791,7 +1791,7 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1829,6 +1829,28 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index dd8daa73..3efaedbf 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1747,7 +1747,7 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1785,6 +1785,28 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index f117bdd9..9631464f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1865,7 +1865,7 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" new VM_District_Child { Code = "110000", - Name = "北京市", + Name = "北京", Childs = new List(new[] { new VM_District_Child{ Code="110100", Name = "北京市" }, new VM_District_Child{ Code="110101", Name = "东城区" }, @@ -1903,6 +1903,28 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" Assert.Equal(2, t3[0].Childs[0].Childs.Count); Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); } [Table(Name = "D_District")] diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index ab1b955e..9b16690d 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -385,4 +385,80 @@ public static partial class FreeSqlGlobalExtensions } #endif #endregion + + #region WhereTree(..) 递归查询 + /// + /// 使用递归 CTE 查询树型的所有子数据。 + /// 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + /// + /// + /// + /// 深度 + /// + public static ISelect AsCteTree(this ISelect that, int depth = -1) where T1 : class + { + var select = that as Select1Provider; + var tb = select._tables[0].Table; + var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) + .Where(a => a != null && + a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && + a.RefEntityType == tb.Type).ToArray(); + + if (navs.Length != 1) throw new ArgumentException($"{tb.Type.FullName} 不是父子关系,无法使用该功能"); + var tbref = navs[0]; + + var cteName = "as_cte_tree"; + if (select._orm.CodeFirst.IsSyncStructureToLower) cteName = cteName.ToLower(); + if (select._orm.CodeFirst.IsSyncStructureToUpper) cteName = cteName.ToUpper(); + var sql1 = select.ToSql($"0 as as_cte_tree_depth, {select.GetAllFieldExpressionTreeLevel2().Field}").Trim(); + + select._where.Clear(); + select.As("wct2"); + var sql2Field = select.GetAllFieldExpressionTreeLevel2().Field; + var sql2 = select + .AsAlias((type, old) => type == tb.Type ? old.Replace("wct2", "wct1") : old) + .AsTable((type, old) => type == tb.Type ? cteName : old) + .InnerJoin($"{select._commonUtils.QuoteSqlName(tb.DbName)} wct2 ON {string.Join(" and ", tbref.Columns.Select((a,z) => $"wct2.{select._commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)} = wct1.{select._commonUtils.QuoteSqlName(a.Attribute.Name)}"))}") + .ToSql($"wct1.as_cte_tree_depth + 1 as as_cte_tree_depth, {sql2Field}").Trim(); + + var newSelect = select._orm.Select() + .AsType(tb.Type) + .AsTable((type, old) => type == tb.Type ? cteName : old) + .WhereIf(depth > 0, $"a.as_cte_tree_depth < {depth + 1}") as Select1Provider; + + var nsselsb = new StringBuilder(); + if (AdoProvider.IsFromSlave(select._select) == false) nsselsb.Append(" "); //读写分离规则,如果强制读主库,则在前面加个空格 + nsselsb.Append("WITH "); + switch (select._orm.Ado.DataType) + { + case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: + case DataType.ShenTong: //神通测试未通过 + case DataType.MySql: + case DataType.OdbcMySql: + nsselsb.Append("RECURSIVE "); + break; + } + nsselsb.Append(select._commonUtils.QuoteSqlName(cteName)); + switch (select._orm.Ado.DataType) + { + case DataType.Oracle: //[Err] ORA-32039: recursive WITH clause must have column alias list + case DataType.OdbcOracle: + case DataType.Dameng: //递归 WITH 子句必须具有列别名列表 + case DataType.OdbcDameng: + nsselsb.Append($"(as_cte_tree_depth, {sql2Field.Replace("wct2.", "")})"); + break; + } + nsselsb.Append(@" +as +( +").Append(sql1).Append("\r\n\r\nunion all\r\n\r\n").Append(sql2).Append(@" +) +SELECT "); + newSelect._select = nsselsb.ToString(); + nsselsb.Clear(); + return newSelect; + } + #endregion } \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5d1ff11c..8738cbb9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3653,6 +3653,16 @@ + + + 使用递归 CTE 查询树型的所有子数据。 + 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + + + + 深度 + + 使用 and 拼接两个 lambda 表达式 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 1d31f146..bde0e6e8 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -533,7 +533,7 @@ namespace FreeSql.Internal.CommonProvider if (transaction == null && connection == null) { //读写分离规则 - if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) + if (this.SlavePools.Any() && IsFromSlave(cmdText)) { var availables = slaveUnavailables == 0 ? //查从库 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 356222af..f6784181 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -458,7 +458,7 @@ namespace FreeSql.Internal.CommonProvider if (transaction == null && connection == null) { //读写分离规则 - if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) + if (this.SlavePools.Any() && IsFromSlave(cmdText)) { var availables = slaveUnavailables == 0 ? //查从库 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs index a8b1d542..a5461a4d 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs @@ -45,5 +45,11 @@ namespace FreeSql.Internal.CommonProvider return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); } + + public static bool IsFromSlave(string cmdText) + { + return cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase) || + cmdText.StartsWith("WITH ", StringComparison.CurrentCultureIgnoreCase); + } } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 62b9784d..79fb1956 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -596,7 +596,7 @@ namespace FreeSql.Internal.CommonProvider public int FieldCount { get; set; } public Func Read { get; set; } } - protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevelAll() + public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevelAll() { return _dicGetAllFieldExpressionTree.GetOrAdd($"*{string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}"))}", s => { @@ -735,7 +735,7 @@ namespace FreeSql.Internal.CommonProvider }; }); } - protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2() + public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2() { return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s => { From 838dd83e479562e3f153907d8e5eb5157668c2ad Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 27 Jun 2020 17:01:51 +0800 Subject: [PATCH 0720/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.AsTr?= =?UTF-8?q?eeCte()=20=E9=80=92=E5=BD=92=E6=9F=A5=E8=AF=A2=E6=A0=91?= =?UTF-8?q?=E8=A1=A8=EF=BC=88=E5=90=91=E4=B8=8B=E6=88=96=E5=90=91=E4=B8=8B?= =?UTF-8?q?=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dameng/Curd/DamengSelectTest.cs | 30 +++++++- .../KingbaseES/Curd/KingbaseESSelectTest.cs | 32 +++++++-- .../Oracle/Curd/OracleSelectTest.cs | 30 +++++++- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 32 +++++++-- .../SqlServer/Curd/SqlServerSelectTest.cs | 30 +++++++- .../Dameng/Curd/DamengSelectTest.cs | 30 +++++++- .../Oracle/Curd/OracleSelectTest.cs | 30 +++++++- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 32 +++++++-- .../SqlServer/Curd/SqlServerSelectTest.cs | 30 +++++++- .../Sqlite/Curd/SqliteSelectTest.cs | 30 +++++++- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 72 ++++++++++++++++--- FreeSql/FreeSql.xml | 12 ++-- .../KingbaseES/OdbcKingbaseESExpression.cs | 14 ++-- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 14 ++-- .../SqlServer/OdbcSqlServerUtils.cs | 3 +- .../PostgreSQLExpression.cs | 16 ++--- .../SqlServerUtils.cs | 3 +- 17 files changed, 368 insertions(+), 72 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 6eeafa37..0f6cc2f5 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -1754,7 +1754,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1763,18 +1763,42 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs index 0e0d8697..5e0b9a0d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs @@ -889,7 +889,7 @@ FROM ""TB_TOPIC22"" a", subquery); var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" FROM ""TB_TOPIC22"" a -WHERE ((((a.""ID"")::varchar) in (SELECT b.""TITLE"" +WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" FROM ""TB_TOPIC22"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } @@ -1719,7 +1719,7 @@ WHERE ((((a.""ID"")::varchar) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1728,18 +1728,42 @@ WHERE ((((a.""ID"")::varchar) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 8b849b1a..827fa198 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -1755,7 +1755,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1764,18 +1764,42 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 96cec0f8..00e356e7 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -985,7 +985,7 @@ FROM ""tb_topic"" a", subquery); var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime"" FROM ""tb_topic"" a -WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" +WHERE ((((a.""id"")::text) in (SELECT b.""title"" FROM ""tb_topic"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } @@ -1814,7 +1814,7 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1823,18 +1823,42 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 92b4fe3f..4cd9858b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -1705,7 +1705,7 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1714,18 +1714,42 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index c6e2751f..c5597f2a 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -1755,7 +1755,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1764,18 +1764,42 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 3a922613..0b7888c2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -1755,7 +1755,7 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1764,18 +1764,42 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 4ce6ea32..2bede6a8 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1002,7 +1002,7 @@ FROM ""tb_topic"" a", subquery); var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime"" FROM ""tb_topic"" a -WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" +WHERE ((((a.""id"")::text) in (SELECT b.""title"" FROM ""tb_topic"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } @@ -1830,7 +1830,7 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1839,18 +1839,42 @@ WHERE ((((a.""id"")::varchar) in (SELECT b.""title"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 3efaedbf..de245c0c 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1786,7 +1786,7 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1795,18 +1795,42 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 9631464f..7ec386cc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1904,7 +1904,7 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); Assert.Single(t3); Assert.Equal("100000", t3[0].Code); Assert.Single(t3[0].Childs); @@ -1913,18 +1913,42 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(4, t3.Count); Assert.Equal("100000", t3[0].Code); Assert.Equal("110000", t3[1].Code); Assert.Equal("110100", t3[2].Code); Assert.Equal("110101", t3[3].Code); - t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); Assert.Equal(3, t3.Count); Assert.Equal("110000", t3[0].Code); Assert.Equal("110100", t3[1].Code); Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); } [Table(Name = "D_District")] diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 9b16690d..a1a56715 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -386,16 +386,24 @@ public static partial class FreeSqlGlobalExtensions #endif #endregion - #region WhereTree(..) 递归查询 + #region AsTreeCte(..) 递归查询 /// - /// 使用递归 CTE 查询树型的所有子数据。 - /// 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + /// 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 + /// 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + /// 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) /// /// /// - /// 深度 + /// false(默认):由父级向子级的递归查询true:由子级向父级的递归查询 + /// 路径内容选择 + /// 连接路径内容 + /// 递归层级 /// - public static ISelect AsCteTree(this ISelect that, int depth = -1) where T1 : class + public static ISelect AsTreeCte(this ISelect that, + Expression> pathSelector = null, + bool up = false, + string pathSeparator = " -> ", + int level = -1) where T1 : class { var select = that as Select1Provider; var tb = select._tables[0].Table; @@ -407,24 +415,66 @@ public static partial class FreeSqlGlobalExtensions if (navs.Length != 1) throw new ArgumentException($"{tb.Type.FullName} 不是父子关系,无法使用该功能"); var tbref = navs[0]; - var cteName = "as_cte_tree"; + var cteName = "as_tree_cte"; if (select._orm.CodeFirst.IsSyncStructureToLower) cteName = cteName.ToLower(); if (select._orm.CodeFirst.IsSyncStructureToUpper) cteName = cteName.ToUpper(); - var sql1 = select.ToSql($"0 as as_cte_tree_depth, {select.GetAllFieldExpressionTreeLevel2().Field}").Trim(); + var sql1ctePath = ""; + if (pathSelector != null) + { + select._tables[0].Parameter = pathSelector?.Parameters[0]; + switch (select._orm.Ado.DataType) + { + case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: + case DataType.ShenTong: //神通测试未通过 + case DataType.SqlServer: + case DataType.OdbcSqlServer: + sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, Expression.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(string) }), pathSelector?.Body), null, null, null); + break; + default: + sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, pathSelector?.Body, null, null, null); + break; + } + sql1ctePath = $"{sql1ctePath} as cte_path, "; + } + var sql1 = select.ToSql($"0 as cte_level, {sql1ctePath}{select.GetAllFieldExpressionTreeLevel2().Field}").Trim(); select._where.Clear(); select.As("wct2"); var sql2Field = select.GetAllFieldExpressionTreeLevel2().Field; + var sql2InnerJoinOn = up == false ? + string.Join(" and ", tbref.Columns.Select((a, z) => $"wct2.{select._commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)} = wct1.{select._commonUtils.QuoteSqlName(a.Attribute.Name)}")) : + string.Join(" and ", tbref.Columns.Select((a, z) => $"wct2.{select._commonUtils.QuoteSqlName(a.Attribute.Name)} = wct1.{select._commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}")); + + var sql2ctePath = ""; + if (pathSelector != null) + { + select._tables[0].Parameter = pathSelector?.Parameters[0]; + var wct2ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, pathSelector?.Body, null, null, null); + sql2ctePath = select._commonUtils.StringConcat( + new string[] { + up == false ? "wct1.cte_path" : wct2ctePath, + select._commonUtils.FormatSql("{0}", pathSeparator), + up == false ? wct2ctePath : "wct1.cte_path" + }, new Type[] { + typeof(string), + typeof(string), + typeof(string) + }); + sql2ctePath = $"{sql2ctePath} as cte_path, "; + } var sql2 = select .AsAlias((type, old) => type == tb.Type ? old.Replace("wct2", "wct1") : old) .AsTable((type, old) => type == tb.Type ? cteName : old) - .InnerJoin($"{select._commonUtils.QuoteSqlName(tb.DbName)} wct2 ON {string.Join(" and ", tbref.Columns.Select((a,z) => $"wct2.{select._commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)} = wct1.{select._commonUtils.QuoteSqlName(a.Attribute.Name)}"))}") - .ToSql($"wct1.as_cte_tree_depth + 1 as as_cte_tree_depth, {sql2Field}").Trim(); + .InnerJoin($"{select._commonUtils.QuoteSqlName(tb.DbName)} wct2 ON {sql2InnerJoinOn}") + .ToSql($"wct1.cte_level + 1 as cte_level, {sql2ctePath}{sql2Field}").Trim(); var newSelect = select._orm.Select() .AsType(tb.Type) .AsTable((type, old) => type == tb.Type ? cteName : old) - .WhereIf(depth > 0, $"a.as_cte_tree_depth < {depth + 1}") as Select1Provider; + .WhereIf(level > 0, $"a.cte_level < {level + 1}") + .OrderBy(up, "a.cte_level desc") as Select1Provider; var nsselsb = new StringBuilder(); if (AdoProvider.IsFromSlave(select._select) == false) nsselsb.Append(" "); //读写分离规则,如果强制读主库,则在前面加个空格 @@ -447,7 +497,7 @@ public static partial class FreeSqlGlobalExtensions case DataType.OdbcOracle: case DataType.Dameng: //递归 WITH 子句必须具有列别名列表 case DataType.OdbcDameng: - nsselsb.Append($"(as_cte_tree_depth, {sql2Field.Replace("wct2.", "")})"); + nsselsb.Append($"(cte_level, {(pathSelector == null ? "" : "cte_path, ")}{sql2Field.Replace("wct2.", "")})"); break; } nsselsb.Append(@" diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8738cbb9..1fa49bdd 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3653,14 +3653,18 @@ - + - 使用递归 CTE 查询树型的所有子数据。 - 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 + 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) - 深度 + false(默认):由父级向子级的递归查询true:由子级向父级的递归查询 + 路径内容选择 + 连接路径内容 + 递归层级 diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index f3a2155d..d92d1bb3 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.KingbaseES case "System.Int64": return $"({getExp(operandExp)})::int8"; case "System.SByte": return $"({getExp(operandExp)})::int2"; case "System.Single": return $"({getExp(operandExp)})::float4"; - case "System.String": return $"({getExp(operandExp)})::varchar"; + case "System.String": return $"({getExp(operandExp)})::text"; case "System.UInt16": return $"({getExp(operandExp)})::int2"; case "System.UInt32": return $"({getExp(operandExp)})::int4"; case "System.UInt64": return $"({getExp(operandExp)})::int8"; @@ -87,7 +87,7 @@ namespace FreeSql.Odbc.KingbaseES if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; return null; case "ToString": - if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null; return null; } @@ -332,10 +332,10 @@ namespace FreeSql.Odbc.KingbaseES if (exp.Arguments[1].Type == typeof(bool) || exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; } - if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::text || '%')"; case "ToLower": return $"lower({left})"; case "ToUpper": return $"upper({left})"; case "Substring": @@ -378,7 +378,7 @@ namespace FreeSql.Odbc.KingbaseES return left; case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; - case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::text)"; } } return null; @@ -573,7 +573,7 @@ namespace FreeSql.Odbc.KingbaseES case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; - case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; + case "ToString": return $"({getExp(exp.Arguments[0])})::text"; case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index e31e3aee..c3265c27 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.PostgreSQL case "System.Int64": return $"({getExp(operandExp)})::int8"; case "System.SByte": return $"({getExp(operandExp)})::int2"; case "System.Single": return $"({getExp(operandExp)})::float4"; - case "System.String": return $"({getExp(operandExp)})::varchar"; + case "System.String": return $"({getExp(operandExp)})::text"; case "System.UInt16": return $"({getExp(operandExp)})::int2"; case "System.UInt32": return $"({getExp(operandExp)})::int4"; case "System.UInt64": return $"({getExp(operandExp)})::int8"; @@ -87,7 +87,7 @@ namespace FreeSql.Odbc.PostgreSQL if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; return null; case "ToString": - if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null; return null; } @@ -354,10 +354,10 @@ namespace FreeSql.Odbc.PostgreSQL if (exp.Arguments[1].Type == typeof(bool) || exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; } - if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::text || '%')"; case "ToLower": return $"lower({left})"; case "ToUpper": return $"upper({left})"; case "Substring": @@ -405,7 +405,7 @@ namespace FreeSql.Odbc.PostgreSQL return left; case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; - case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::text)"; } } return null; @@ -598,7 +598,7 @@ namespace FreeSql.Odbc.PostgreSQL case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; - case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; + case "ToString": return $"({getExp(exp.Arguments[0])})::text"; case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index cfe4abdd..214a7d1b 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -73,7 +73,8 @@ namespace FreeSql.Odbc.SqlServer { if (types[a] == typeof(string)) news[a] = objs[a]; else if (types[a].NullableTypeOrThis() == typeof(Guid)) news[a] = $"cast({objs[a]} as char(36))"; - else news[a] = $"cast({objs[a]} as nvarchar)"; + else if (types[a].IsNumberType()) news[a] = $"cast({objs[a]} as varchar)"; + else news[a] = $"cast({objs[a]} as nvarchar(max))"; } return string.Join(" + ", news); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 42d1a495..0e2c5fe1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -38,7 +38,7 @@ namespace FreeSql.PostgreSQL case "System.Int64": return $"({getExp(operandExp)})::int8"; case "System.SByte": return $"({getExp(operandExp)})::int2"; case "System.Single": return $"({getExp(operandExp)})::float4"; - case "System.String": return $"({getExp(operandExp)})::varchar"; + case "System.String": return $"({getExp(operandExp)})::text"; case "System.UInt16": return $"({getExp(operandExp)})::int2"; case "System.UInt32": return $"({getExp(operandExp)})::int4"; case "System.UInt64": return $"({getExp(operandExp)})::int8"; @@ -88,7 +88,7 @@ namespace FreeSql.PostgreSQL if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; return null; case "ToString": - if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::varchar" : null; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null; return null; } @@ -120,7 +120,7 @@ namespace FreeSql.PostgreSQL case "Contains": var json = getExp(callExp.Arguments[argIndex]); if (objType == typeof(JArray)) - return $"(coalesce({left},'[]') ? ({json})::varchar)"; + return $"(coalesce({left},'[]') ? ({json})::text)"; if (json.StartsWith("'") && json.EndsWith("'")) return $"(coalesce({left},'{{}}') @> {_common.FormatSql("{0}", JToken.Parse(json.Trim('\'')))})"; return $"(coalesce({left},'{{}}') @> ({json})::jsonb)"; @@ -385,10 +385,10 @@ namespace FreeSql.PostgreSQL if (exp.Arguments[1].Type == typeof(bool) || exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; } - if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}"; - if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}"; + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; - return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::text || '%')"; case "ToLower": return $"lower({left})"; case "ToUpper": return $"upper({left})"; case "Substring": @@ -436,7 +436,7 @@ namespace FreeSql.PostgreSQL return left; case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; - case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::varchar)"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::text)"; } } return null; @@ -629,7 +629,7 @@ namespace FreeSql.PostgreSQL case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; - case "ToString": return $"({getExp(exp.Arguments[0])})::varchar"; + case "ToString": return $"({getExp(exp.Arguments[0])})::text"; case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 8814ae3e..f05d3a8c 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -85,7 +85,8 @@ namespace FreeSql.SqlServer { if (types[a] == typeof(string)) news[a] = objs[a]; else if (types[a].NullableTypeOrThis() == typeof(Guid)) news[a] = $"cast({objs[a]} as char(36))"; - else news[a] = $"cast({objs[a]} as nvarchar)"; + else if (types[a].IsNumberType()) news[a] = $"cast({objs[a]} as varchar)"; + else news[a] = $"cast({objs[a]} as nvarchar(max))"; } return string.Join(" + ", news); } From 3a407694f224abc38f25146514d223517a58df3e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 27 Jun 2020 17:12:05 +0800 Subject: [PATCH 0721/1029] v1.6.0 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 86001bb8..ee6a5a52 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 8073c4c7..1c0b4576 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 4e17fef1..47482be9 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index a9754f39..d19f99af 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 6fd1408d..9db113c6 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0-preview0624 + 1.6.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 518347f7..8146f247 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e3c0bba6..6514356f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 2c5272bb..326b0af1 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0-preview0624 + 1.6.0 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0d1e2f35..11acfec9 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 60e9ab55..02bf553d 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 5e201425..20993689 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 8f258e47..090247f0 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6f31314f..8fe0f7e2 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index bcfb5ad4..b8930b22 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8a0a3f85..912cc7b1 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0b4b0bb6..17a6f544 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b98e553d..c6ee830e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 07b680ce..0f16de2d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0624 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From afa713e61de864e123c1412bd6696c3783850314 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 28 Jun 2020 04:34:05 +0800 Subject: [PATCH 0722/1029] =?UTF-8?q?FreeSql.Generator=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=A5=9E=E9=80=9A=20DbFirst=20=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 7 ++++++- .../FreeSql.Generator/FreeSql.Generator.csproj | 8 +++++++- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../ShenTong/ShenTongDbFirstTest.cs | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 7 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 040f374f..8150beb4 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -114,6 +114,9 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -DB ""{12},Driver={KingbaseES 8.2 ODBC Driver ANSI};Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=数据库"" {12} 人大金仓数据库 + -DB ""{13},HOST=192.168.164.10;PORT=2003;DATABASE=OSRDB;USERNAME=SYSDBA;PASSWORD=szoscar55;MAXPOOLSIZE=2"" + {13} 神州通用数据库 + -Filter Table+View+StoreProcedure 默认生成:表+视图+存储过程 如果不想生成视图和存储过程 -Filter View+StoreProcedure @@ -123,7 +126,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -FileName 文件名,默认:{name}.cs -Output 保存路径,默认为当前 shell 所在目录 - {13} + {14} ", Color.SlateGray, new Colorful.Formatter("使用 FreeSql 快速生成数据库的实体类", Color.SlateGray), @@ -139,6 +142,7 @@ new Colorful.Formatter("Oracle", Color.Yellow), new Colorful.Formatter("Sqlite", Color.Yellow), new Colorful.Formatter("Dameng", Color.Yellow), new Colorful.Formatter("OdbcKingbaseES", Color.Yellow), +new Colorful.Formatter("ShenTong", Color.Yellow), new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新所有实体类", Color.ForestGreen) ); wait.Set(); @@ -180,6 +184,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 case "sqlite": ArgsDbType = DataType.Sqlite; break; case "dameng": ArgsDbType = DataType.Dameng; break; case "odbckingbasees": ArgsDbType = DataType.OdbcKingbaseES; break; + case "shentong": ArgsDbType = DataType.ShenTong; break; default: throw new ArgumentException($"-DB 参数错误,不支持的类型:\"{dbargs[0]}\""); } ArgsConnectionString = dbargs[1].Trim(); diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 9db113c6..4bc161c7 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0 + 1.6.102 FreeSql DbFirst 实体生成器 @@ -27,6 +27,11 @@ ..\..\Providers\FreeSql.Provider.Dameng\lib\DmProvider\netstandard2.0\DmProvider.dll + + + ..\..\Providers\FreeSql.Provider.ShenTong\lib\System.Data.OscarClient.dll + + @@ -34,6 +39,7 @@ + diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6514356f..86e60abd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -37,7 +37,7 @@ - + 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/ShenTong/ShenTongDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs index c7d757f5..12b7a897 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs @@ -17,7 +17,7 @@ namespace FreeSql.Tests.ShenTong [Fact] public void GetTablesByDatabase() { - + var t1 = g.shentong.DbFirst.GetTablesByDatabase(); var t2 = g.shentong.DbFirst.GetTablesByDatabase(g.shentong.DbFirst.GetDatabases()[0]); } diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8fe0f7e2..5842fd0b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 0f16de2d..9752d7ef 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -26,7 +26,7 @@ - + From d3b9047ab41cfda6077c9f9624207a8bfe90bb5b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 28 Jun 2020 08:08:15 +0800 Subject: [PATCH 0723/1029] update ShenTong chinese name --- Extensions/FreeSql.Generator/ConsoleApp.cs | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 4 ++-- readme.md | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 8150beb4..b67febfc 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -115,7 +115,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam {12} 人大金仓数据库 -DB ""{13},HOST=192.168.164.10;PORT=2003;DATABASE=OSRDB;USERNAME=SYSDBA;PASSWORD=szoscar55;MAXPOOLSIZE=2"" - {13} 神州通用数据库 + {13} 神舟通用数据库 -Filter Table+View+StoreProcedure 默认生成:表+视图+存储过程 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 86e60abd..a2b4d1d9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -5,7 +5,7 @@ 1.6.0 true ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access https://github.com/2881099/FreeSql/wiki/DbContext FreeSql ORM DbContext git diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 326b0af1..e1f3d7dd 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -4,7 +4,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.6.0 ncc;YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access, and read/write separation、and split table. + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository true diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index d6a151b4..0f812460 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -98,7 +98,7 @@ public class g public static IFreeSql kingbaseES => kingbaseESLazy.Value; - //启动神州通用数据库 /etc/init.d/oscardb_OSRDBd start + //启动神舟通用数据库 /etc/init.d/oscardb_OSRDBd start //SYSDBA 密码 szoscar55 diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 11acfec9..7501ec5d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -5,7 +5,7 @@ 1.6.0 true ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神州通用, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 75de475b..c59f1b29 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -5,12 +5,12 @@ 1.6.0-preview0602 true ncc;YeXiangQin - FreeSql 数据库实现,基于 神州通用数据库 7.0.8 + FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git MIT - FreeSql;ORM;ShenTong;Oscar;神通;神州通用 + FreeSql;ORM;ShenTong;Oscar;神通;神舟通用 $(AssemblyName) logo.png $(AssemblyName) diff --git a/readme.md b/readme.md index 4ab26f46..d2fee9ab 100644 --- a/readme.md +++ b/readme.md @@ -10,7 +10,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 丰富的表达式函数,以及灵活的自定义解析; - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; - [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; -- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神州通用/Access; +- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access; ## 📚  Documentation From 9ad274336e12ba044669e4ac1bcd03dd0fd103f5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 28 Jun 2020 08:14:48 +0800 Subject: [PATCH 0724/1029] upload ShenTong nuget --- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index c59f1b29..e575e96e 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0-preview0602 + 1.6.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 From 68981d03acb33ac0b722d4e157208d3e9665fd60 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 28 Jun 2020 18:36:26 +0800 Subject: [PATCH 0725/1029] hack mysql ExpressionCall value --- FreeSql/Internal/CommonExpression.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6507bd24..8ca5c1c0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -675,10 +675,19 @@ namespace FreeSql.Internal else if (exp3.Arguments[a].IsParameter()) exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue(); else - exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, - eccContent.StartsWith("N'") ? + { + var exp3CsValue = eccContent.StartsWith("N'") ? eccContent.Substring(1).Trim('\'').Replace("''", "'") : - eccContent.Trim('\'').Replace("''", "'")); + eccContent.Trim('\'').Replace("''", "'"); + switch (_ado.DataType) + { + case DataType.MySql: + case DataType.OdbcMySql: + exp3CsValue = exp3CsValue.Replace("\\\\", "\\"); + break; + } + exp3InvokeParams[a] = Utils.GetDataReaderValue(exp3.Arguments[a].Type, exp3CsValue); + } } else exp3InvokeParams[a] = ecc; From 806c826187706e27da542db92e50c9a13cc2fdc2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 30 Jun 2020 01:34:38 +0800 Subject: [PATCH 0726/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20pgsql=20dbfi?= =?UTF-8?q?rst=20=E6=9C=AA=E5=A4=84=E7=90=86=E6=95=B0=E7=BB=84=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=94=9F=E6=88=90=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ .../PostgreSQL/PostgreSQLDbFirstTest.cs | 3 +++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 6 ++++++ .../KingbaseES/OdbcKingbaseESDbFirst.cs | 3 ++- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 3 ++- .../PostgreSQLDbFirst.cs | 3 ++- .../FreeSql.Provider.ShenTong/ShenTongDbFirst.cs | 3 ++- 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs index f6c823c4..9bd86da7 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using System; +using System.Linq; using Xunit; namespace FreeSql.Tests.PostgreSQL @@ -20,6 +21,8 @@ namespace FreeSql.Tests.PostgreSQL var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[1]); + var tb_alltype = t2.Where(a => a.Name == "tb_alltype").FirstOrDefault(); + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 54f51f72..75026510 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -16,6 +16,10 @@ using kwlib; using System.Diagnostics; using System.IO; using System.Text; +using Newtonsoft.Json; +using System.Net.NetworkInformation; +using System.Net; +using System.Collections; namespace FreeSql.Tests { @@ -502,3 +506,5 @@ namespace FreeSql.Tests } } + + diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs index 41c69855..62156ec7 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs @@ -220,7 +220,7 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, --e.adsrc as is_identity, pg12以下 -(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid limit 1) is_identity, +(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid and adnum = e.adnum limit 1) is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, @@ -274,6 +274,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; } } + if (attndims > 0) type += "[]"; loc3[object_id].Add(column, new DbColumnInfo { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index b9104da5..52400443 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -212,7 +212,7 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, --e.adsrc as is_identity, pg12以下 -(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid and adnum = e.adnum limit 1) is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, @@ -266,6 +266,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; } } + if (attndims > 0) type += "[]"; loc3[object_id].Add(column, new DbColumnInfo { diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 225c2ab3..11afd1cf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -322,7 +322,7 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, --e.adsrc as is_identity, pg12以下 -(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid and adnum = e.adnum limit 1) is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, @@ -376,6 +376,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; } } + if (attndims > 0) type += "[]"; loc3[object_id].Add(column, new DbColumnInfo { diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs index a79c01ae..6f6e10b1 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs @@ -232,7 +232,7 @@ case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.at case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, --e.adsrc as is_identity, pg12以下 -(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid limit 1) is_identity, +(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid and adnum = e.adnum limit 1) is_identity, d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, @@ -286,6 +286,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; } } + if (attndims > 0) type += "[]"; loc3[object_id].Add(column, new DbColumnInfo { From a4c049fcf25e8340aa079cf523c3f49ce77f54c9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 30 Jun 2020 01:46:04 +0800 Subject: [PATCH 0727/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20FreeSql.Gene?= =?UTF-8?q?rator=20=E7=94=9F=E6=88=90=E6=95=B0=E6=8D=AE=E5=BA=93=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Generator.csproj | 2 +- .../FreeSql.Generator/RazorContentManager.cs | 28 +-- Extensions/FreeSql.Generator/RazorModel.cs | 172 +++++++++++++++++- 3 files changed, 183 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 4bc161c7..3b9f5a91 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.102 + 1.6.0 FreeSql DbFirst 实体生成器 diff --git a/Extensions/FreeSql.Generator/RazorContentManager.cs b/Extensions/FreeSql.Generator/RazorContentManager.cs index baa57000..a52036a6 100644 --- a/Extensions/FreeSql.Generator/RazorContentManager.cs +++ b/Extensions/FreeSql.Generator/RazorContentManager.cs @@ -7,17 +7,17 @@ namespace FreeSql.Generator class RazorContentManager { public static string 实体类_特性_cshtml = - #region 长内容 - @"@using FreeSql.DatabaseModel;@{ + #region 长内容 + @"using FreeSql.DatabaseModel;@{ var gen = Model as RazorModel; Func GetAttributeString = attr => { - if (string.IsNullOrEmpty(attr)) return null; + if (string.IsNullOrEmpty(attr)) return """"; return string.Concat("", "", attr.Trim('[', ']')); }; -Func GetDefaultValue = col => { - if (col.CsType == typeof(string)) return "" = string.Empty;""; - return """"; +Func GetDefaultValue = defval => { + if (string.IsNullOrEmpty(defval)) return """"; + return "" = "" + defval + "";""; }; }@{ switch (gen.fsql.Ado.DataType) { @@ -68,8 +68,8 @@ namespace @gen.NameSpace { @:/// @col.Coment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") @:/// } - @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col)) + ""]"") - @:public @gen.GetCsType(col) @gen.GetCsName(col.Name) { get; set; }@GetDefaultValue(col) + @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col, true)) + ""]"") + @:public @gen.GetCsType(col) @gen.GetCsName(col.Name) { get; set; }@GetDefaultValue(gen.GetColumnDefaultValue(col, false)) @: } } @@ -89,9 +89,13 @@ var gen = Model as RazorModel; var fks = gen.table.Foreigns; Func GetAttributeString = attr => { - if (string.IsNullOrEmpty(attr)) return null; + if (string.IsNullOrEmpty(attr)) return """"; return string.Concat("", "", attr.Trim('[', ']')); }; +Func GetDefaultValue = defval => { + if (string.IsNullOrEmpty(defval)) return """"; + return "" = "" + defval + "";""; +}; Func GetFkObjectName = fkx => { var eqfks = fks.Where(fk22a => fk22a.ReferencedTable.Name == fkx.ReferencedTable.Name); @@ -155,9 +159,9 @@ namespace @gen.NameSpace { @:/// @col.Coment.Replace(""\r\n"", ""\n"").Replace(""\n"", ""\r\n /// "") @:/// } - @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col)) + ""]"") + @:@(""[JsonProperty"" + GetAttributeString(gen.GetColumnAttribute(col, true)) + ""]"") if (findfks.Any() == false) { - @:public @gen.GetCsType(col) @csname { get; set; } + @:public @gen.GetCsType(col) @csname { get; set; }@GetDefaultValue(gen.GetColumnDefaultValue(col, false)) } else { @:public @gen.GetCsType(col) @csname { get => _@csname; set { @:if (_@csname == value) return; @@ -166,7 +170,7 @@ namespace @gen.NameSpace { @:@gen.GetCsName(GetFkObjectName(fkcok2)) = null; } @:} } - @:private @gen.GetCsType(col) _@csname; + @:private @gen.GetCsType(col) _@csname@GetDefaultValue(gen.GetColumnDefaultValue(col, false)).TrimEnd(';'); } @: } diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index e2be6979..85296c72 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -1,4 +1,7 @@ -using FreeSql.DatabaseModel; +using FreeSql; +using FreeSql.DataAnnotations; +using FreeSql.DatabaseModel; +using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; using System.Linq; @@ -50,7 +53,8 @@ public class RazorModel { } #region 特性 - public string GetTableAttribute() { + public string GetTableAttribute() + { var sb = new List(); if (GetCsName(this.FullTableName) != this.FullTableName) @@ -61,10 +65,12 @@ public class RazorModel { sb.Add("Name = \"" + this.FullTableName + "\""); //Todo: QuoteSqlName } + sb.Add("DisableSyncStructure = true"); if (sb.Any() == false) return null; return "[Table(" + string.Join(", ", sb) + ")]"; } - public string GetColumnAttribute(DbColumnInfo col) { + public string GetColumnAttribute(DbColumnInfo col, bool isInsertValueSql = false) + { var sb = new List(); if (GetCsName(col.Name) != col.Name) @@ -74,7 +80,98 @@ public class RazorModel { { var dbinfo = fsql.CodeFirst.GetDbInfo(col.CsType); if (dbinfo != null && string.Compare(dbinfo.dbtypeFull.Replace("NOT NULL", "").Trim(), col.DbTypeTextFull, true) != 0) - sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + { + #region StringLength 反向 + switch (fsql.Ado.DataType) + { + case DataType.MySql: + case DataType.OdbcMySql: + switch (col.DbTypeTextFull.ToLower()) + { + case "longtext": sb.Add("StringLength = -2"); break; + case "text": sb.Add("StringLength = -1"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^varchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.SqlServer: + case DataType.OdbcSqlServer: + switch (col.DbTypeTextFull.ToLower()) + { + case "nvarchar(max)": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^nvarchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.PostgreSQL: + case DataType.OdbcPostgreSQL: + case DataType.OdbcKingbaseES: + case DataType.ShenTong: + switch (col.DbTypeTextFull.ToLower()) + { + case "text": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^varchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.Oracle: + case DataType.OdbcOracle: + switch (col.DbTypeTextFull.ToLower()) + { + case "nclob": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^nvarchar2\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.Dameng: + case DataType.OdbcDameng: + switch (col.DbTypeTextFull.ToLower()) + { + case "text": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^nvarchar2\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.Sqlite: + switch (col.DbTypeTextFull.ToLower()) + { + case "text": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^nvarchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + case DataType.MsAccess: + switch (col.DbTypeTextFull.ToLower()) + { + case "longtext": sb.Add("StringLength = -2"); break; + default: + var m_stringLength = Regex.Match(col.DbTypeTextFull, @"^varchar\s*\((\w+)\)$", RegexOptions.IgnoreCase); + if (m_stringLength.Success) sb.Add($"StringLength = {m_stringLength.Groups[1].Value}"); + else sb.Add("DbType = \"" + col.DbTypeTextFull + "\""); + break; + } + break; + } + #endregion + } if (col.IsPrimary) sb.Add("IsPrimary = true"); if (col.IsIdentity) @@ -87,15 +184,75 @@ public class RazorModel { if (col.IsNullable == false && fsql.DbFirst.GetCsType(col).Contains("?") == true) sb.Add("IsNullable = false"); } + + if (isInsertValueSql) + { + var defval = GetColumnDefaultValue(col, false); + if (defval == null) //c#默认属性值,就不需要设置 InsertValueSql 了 + { + defval = GetColumnDefaultValue(col, true); + if (defval != null) + { + sb.Add("InsertValueSql = \"" + defval.Replace("\"", "\\\"") + "\""); + sb.Add("CanInsert = false"); + } + } + else + sb.Add("CanInsert = false"); + } } if (sb.Any() == false) return null; return "[Column(" + string.Join(", ", sb) + ")]"; } + public string GetColumnDefaultValue(DbColumnInfo col, bool isInsertValueSql) + { + var defval = col.DefaultValue?.Trim(); + if (string.IsNullOrEmpty(defval)) return null; + var cstype = col.CsType.NullableTypeOrThis(); + if (fsql.Ado.DataType == DataType.SqlServer || fsql.Ado.DataType == DataType.OdbcSqlServer) + { + if (defval.StartsWith("((") && defval.EndsWith("))")) defval = defval.Substring(2, defval.Length - 4); + else if (defval.StartsWith("('") && defval.EndsWith("')")) defval = defval.Substring(2, defval.Length - 4).Replace("''", "'"); + else if (defval.StartsWith("(") && defval.EndsWith(")")) defval = defval.Substring(1, defval.Length - 2); + else return null; + } + else if ((cstype == typeof(string) && defval.StartsWith("'") && defval.EndsWith("'::character varying") || + cstype == typeof(Guid) && defval.StartsWith("'") && defval.EndsWith("'::uuid") + ) && (fsql.Ado.DataType == DataType.PostgreSQL || fsql.Ado.DataType == DataType.OdbcPostgreSQL || + fsql.Ado.DataType == DataType.OdbcKingbaseES || + fsql.Ado.DataType == DataType.ShenTong)) + { + defval = defval.Substring(1, defval.LastIndexOf("'::") - 1).Replace("''", "'"); + } + else if (defval.StartsWith("'") && defval.EndsWith("'")) + { + defval = defval.Substring(1, defval.Length - 2).Replace("''", "'"); + if (fsql.Ado.DataType == DataType.MySql || fsql.Ado.DataType == DataType.OdbcMySql) defval = defval.Replace("\\\\", "\\"); + } + if (cstype.IsNumberType() && decimal.TryParse(defval, out var trydec)) + { + if (isInsertValueSql) return defval; + if (cstype == typeof(float)) return defval + "f"; + if (cstype == typeof(double)) return defval + "d"; + if (cstype == typeof(decimal)) return defval + "M"; + return defval; + } + if (cstype == typeof(Guid) && Guid.TryParse(defval, out var tryguid)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"Guid.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; + if (cstype == typeof(DateTime) && DateTime.TryParse(defval, out var trydt)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"DateTime.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; + if (cstype == typeof(TimeSpan) && TimeSpan.TryParse(defval, out var tryts)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"TimeSpan.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; + if (cstype == typeof(string)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\""; + if (cstype == typeof(bool)) return isInsertValueSql ? defval : (defval == "1" || defval == "t" ? "true" : "false"); + if (fsql.Ado.DataType == DataType.MySql || fsql.Ado.DataType == DataType.OdbcMySql) + if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) + if (isInsertValueSql) return (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval); + return isInsertValueSql ? defval : null; //sql function or exp + } #endregion #region mysql enum/set - public string GetMySqlEnumSetDefine() { - if (fsql.Ado.DataType != FreeSql.DataType.MySql) return null; + public string GetMySqlEnumSetDefine() + { + if (fsql.Ado.DataType != FreeSql.DataType.MySql && fsql.Ado.DataType != FreeSql.DataType.OdbcMySql) return null; var sb = new StringBuilder(); foreach (var col in table.Columns) { if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) { @@ -150,4 +307,7 @@ Unknow{1}", str2.Replace("\"", "\\\""), ++unknow_idx); #endregion } +[Table(DisableSyncStructure = true)] +class TestTb { public Guid id { get; set; } } + From a41da0dc950851c7ed2edd486b6c3bddbeaf7f6e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 30 Jun 2020 11:29:00 +0800 Subject: [PATCH 0728/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20dm7=20dbfirs?= =?UTF-8?q?t=20SQL=20=E4=B8=AD=E5=AD=98=E5=9C=A8=E7=89=B9=E6=AE=8A?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- .../FreeSql.Provider.Dameng/DamengCodeFirst.cs | 2 +- .../FreeSql.Provider.Dameng/DamengDbFirst.cs | 18 +++++++++--------- .../Dameng/OdbcDamengDbFirst.cs | 18 +++++++++--------- 4 files changed, 19 insertions(+), 28 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,14 +486,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs index 09cb67f1..61e0573b 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs @@ -272,7 +272,7 @@ a.index_name, case when c.descend = 'DESC' then 1 else 0 end, case when a.uniqueness = 'UNIQUE' then 1 else 0 end from all_indexes a, -all_ind_columns c +all_ind_columns c where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index fc926d72..49c7ddfb 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -459,15 +459,15 @@ all_constraints b, all_cons_columns c, --外键表 all_cons_columns d --主键表 where -a.r_constraint_name = b.constraint_name    -and a.constraint_type = 'R'    -and b.constraint_type = 'P'    -and a.r_owner = b.owner    -and a.constraint_name = c.constraint_name    -and b.constraint_name = d.constraint_name    -and a.owner = c.owner    -and a.table_name = c.table_name    -and b.owner = d.owner    +a.r_constraint_name = b.constraint_name +and a.constraint_type = 'R' +and b.constraint_type = 'P' +and a.r_owner = b.owner +and a.constraint_name = c.constraint_name +and b.constraint_name = d.constraint_name +and a.owner = c.owner +and a.table_name = c.table_name +and b.owner = d.owner and b.table_name = d.table_name and a.owner in ({1}) and {0} ", loc8, databaseIn); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index eb2e1ddc..e941e104 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -459,15 +459,15 @@ all_constraints b, all_cons_columns c, --外键表 all_cons_columns d --主键表 where -a.r_constraint_name = b.constraint_name    -and a.constraint_type = 'R'    -and b.constraint_type = 'P'    -and a.r_owner = b.owner    -and a.constraint_name = c.constraint_name    -and b.constraint_name = d.constraint_name    -and a.owner = c.owner    -and a.table_name = c.table_name    -and b.owner = d.owner    +a.r_constraint_name = b.constraint_name +and a.constraint_type = 'R' +and b.constraint_type = 'P' +and a.r_owner = b.owner +and a.constraint_name = c.constraint_name +and b.constraint_name = d.constraint_name +and a.owner = c.owner +and a.table_name = c.table_name +and b.owner = d.owner and b.table_name = d.table_name and a.owner in ({1}) and {0} ", loc8, databaseIn); From 181813ce1a1f783a07de577a305f2c7aef738230 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 3 Jul 2020 15:04:07 +0800 Subject: [PATCH 0729/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20WhereDynamic?= =?UTF-8?q?Filter=20=E5=A4=9A=E7=BA=A7=20Logic=20=E6=9C=AA=E7=94=9F?= =?UTF-8?q?=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 10 ++++++++++ .../CommonProvider/SelectProvider/Select0Provider.cs | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 75026510..8ea5fe0f 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -159,6 +159,16 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var sql123 = g.sqlserver.Select() + + .WithSql( + g.sqlserver.Select().ToSql(a => new { a.Id }, FieldAliasOptions.AsProperty) + + " UNION ALL " + + g.sqlserver.Select().ToSql(a => new { a.Id }, FieldAliasOptions.AsProperty)) + + .Page(1, 10).ToSql("Id"); + + var sqlextGroupConcat = g.mysql.Select() .InnerJoin((a, b) => b.Id == a.Id) .ToSql((a, b) => new diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 79fb1956..dd0f788b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1169,7 +1169,7 @@ namespace FreeSql.Internal.CommonProvider { if (string.IsNullOrEmpty(fi.Field) == false || fi.Filters?.Any() == true) { - switch (filter.Logic) + switch (logic) { case DynamicFilterLogic.And: sb.Append(" AND "); break; case DynamicFilterLogic.Or: sb.Append(" OR "); break; From 1d48f17f813926f4e6b942095111cdec0f0f80ca Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 4 Jul 2020 19:21:22 +0800 Subject: [PATCH 0730/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20$""=20lambda?= =?UTF-8?q?=20=E8=A7=A3=E6=9E=90=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 | 7 +++++++ FreeSql/Internal/CommonExpression.cs | 26 +++++++++++++++++++++++- 3 files changed, 32 insertions(+), 17 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 8ea5fe0f..e2b66169 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -159,6 +159,13 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var testStringFormat = g.sqlite.Select().First(a => new { + str = $"x{a.Id}_{DateTime.Now.ToString("yyyyMM")}z", + str2 = string.Format("{0}x{0}_{1}z", a.Id, DateTime.Now.ToString("yyyyMM")) + }); + + + var sql123 = g.sqlserver.Select() .WithSql( diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 8ca5c1c0..9cf22a92 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -716,7 +716,31 @@ namespace FreeSql.Internal string other3Exp = null; switch (callType.FullName) { - case "System.String": other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); break; + case "System.String": + //$"{id}_{name}" + if (exp3.Method.Name == "Format" && exp3.Object == null && exp3.Arguments[0].NodeType == ExpressionType.Constant) + { + if (exp3.Arguments.Count == 1) return ExpressionLambdaToSql(exp3.Arguments[0], tsc); + var exp3Args0 = (exp3.Arguments[0] as ConstantExpression)?.Value?.ToString().Replace("{{", "{{_freesql_tMp_fLag_"); + var exp3Args1n = exp3.Arguments.Where((a, z) => z > 0).Select(a => ExpressionLambdaToSql(a, tsc)).ToArray(); + var exp3Args0Spt = Regex.Split(exp3Args0, @"{(\d+)}"); + var exp3ArgsConcatType = new Type[exp3Args0Spt.Length]; + exp3Args0Spt[0] = _common.FormatSql("{0}", exp3Args0Spt[0].Replace("{{_freesql_tMp_fLag_", "{{")); + exp3ArgsConcatType[0] = typeof(string); + for (var exp3Args0SptIndex = 1; exp3Args0SptIndex < exp3Args0Spt.Length; exp3Args0SptIndex += 2) + { + var exp3Args1nIndex = int.Parse(exp3Args0Spt[exp3Args0SptIndex]); + exp3Args0Spt[exp3Args0SptIndex] = exp3Args1n[exp3Args1nIndex]; + var expArgsType = exp3.Arguments[exp3Args1nIndex + 1]; + exp3ArgsConcatType[exp3Args0SptIndex] = (expArgsType as UnaryExpression)?.Operand.Type ?? expArgsType.Type; + + exp3Args0Spt[exp3Args0SptIndex + 1] = _common.FormatSql("{0}", exp3Args0Spt[exp3Args0SptIndex + 1].Replace("{{_freesql_tMp_fLag_", "{{")); + exp3ArgsConcatType[exp3Args0SptIndex + 1] = typeof(string); + } + return _common.StringConcat(exp3Args0Spt, exp3ArgsConcatType); + } + other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); + break; case "System.Math": other3Exp = ExpressionLambdaToSqlCallMath(exp3, tsc); break; case "System.DateTime": other3Exp = ExpressionLambdaToSqlCallDateTime(exp3, tsc); break; case "System.TimeSpan": other3Exp = ExpressionLambdaToSqlCallTimeSpan(exp3, tsc); break; From d61997d1b206e11d878c373eb310e187db1cf152 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 5 Jul 2020 06:32:13 +0800 Subject: [PATCH 0731/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20$"{id}=5F{na?= =?UTF-8?q?me}"=20lambda=20=E8=A7=A3=E6=9E=90=E4=B8=8E=E6=B5=8B=E8=AF=95?= =?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 ++++++++++++ .../MySqlConnectorExpression/StringTest.cs | 23 ++++++++++++++++ .../Dameng/DamengExpression/ConvertTest.cs | 4 +-- .../Dameng/DamengExpression/StringTest.cs | 22 ++++++++++++++++ .../KingbaseESExpression/StringTest.cs | 22 ++++++++++++++++ .../MySql/MySqlExpression/StringTest.cs | 23 ++++++++++++++++ .../Oracle/OracleExpression/StringTest.cs | 22 ++++++++++++++++ .../PostgreSQLExpression/StringTest.cs | 22 ++++++++++++++++ .../SqlServerExpression/StringTest.cs | 23 ++++++++++++++++ .../Dameng/DamengExpression/ConvertTest.cs | 4 +-- .../Dameng/DamengExpression/StringTest.cs | 22 ++++++++++++++++ .../MsAccess/MsAccessExpression/StringTest.cs | 23 ++++++++++++++++ .../MySql/MySqlExpression/StringTest.cs | 23 ++++++++++++++++ .../Oracle/OracleExpression/StringTest.cs | 22 ++++++++++++++++ .../PostgreSQLExpression/StringTest.cs | 22 ++++++++++++++++ .../ShenTong/ShenTongExpression/StringTest.cs | 22 ++++++++++++++++ .../SqlServerExpression/StringTest.cs | 23 ++++++++++++++++ .../Sqlite/SqliteExpression/StringTest.cs | 23 ++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 26 +------------------ .../DamengExpression.cs | 8 ++++-- .../MsAccessExpression.cs | 4 +++ .../FreeSql.Provider.MySql/MySqlExpression.cs | 5 ++++ .../Dameng/OdbcDamengExpression.cs | 8 ++++-- .../KingbaseES/OdbcKingbaseESExpression.cs | 4 +++ .../MySql/OdbcMySqlExpression.cs | 5 ++++ .../Oracle/OdbcOracleExpression.cs | 6 ++++- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 4 +++ .../SqlServer/OdbcSqlServerExpression.cs | 14 ++++++++++ .../OracleExpression.cs | 6 ++++- .../PostgreSQLExpression.cs | 4 +++ .../ShenTongExpression.cs | 4 +++ .../SqlServerExpression.cs | 14 ++++++++++ .../SqliteExpression.cs | 4 +++ 33 files changed, 442 insertions(+), 35 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 485a1d4f..55f11292 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -52,6 +52,29 @@ namespace FreeSql.Tests.MySqlConnectorExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void Format() + { + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs index f3a89e5b..2c513229 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/ConvertTest.cs @@ -162,8 +162,8 @@ namespace FreeSql.Tests.Odbc.DamengExpression public void Random() { var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + data.Add(select.OrderBy(a => new Random().Next()).Limit(10).ToList()); + data.Add(select.OrderBy(a => new Random().NextDouble()).Limit(10).ToList()); } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs index f945fc5e..7f3f3a92 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.Odbc.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.dameng.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs index 7e59d641..99ee1aa8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.Odbc.KingbaseESExpression list.Add(g.kingbaseES.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.kingbaseES.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs index ff5fb312..370a2b01 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,29 @@ namespace FreeSql.Tests.Odbc.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void Format() + { + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs index f645a2da..7df9d90d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.Odbc.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.oracle.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs index d4f3d51e..60f1eb3b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.pgsql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as1, ''||((a.""id"" + 1))||'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as2 +FROM ""tb_topic"" a +WHERE (a.""id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs index 4954105c..7b6834e1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs @@ -51,6 +51,29 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.sqlserver.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as1, N''+cast((a.[Id] + 1) as varchar)+N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs index 881fc900..036384b5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/ConvertTest.cs @@ -162,8 +162,8 @@ namespace FreeSql.Tests.DamengExpression public void Random() { var data = new List(); - data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); - data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + data.Add(select.OrderBy(a => new Random().Next()).Limit(10).ToList()); + data.Add(select.OrderBy(a => new Random().NextDouble()).Limit(10).ToList()); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs index 7ac61af1..2a9d28a9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.dameng.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs index b89066fa..60b9fd18 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs @@ -50,6 +50,29 @@ namespace FreeSql.Tests.MsAccessExpression list.Add(g.msaccess.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.msaccess.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'+cstr((a.[Id] + 1))+'z-'+(format(a.[CreateTime],'yyyyMM'))+''+(a.[Title])+'' as as1, ''+cstr((a.[Id] + 1))+'x'+cstr((a.[Id] + 1))+'z-'+(format(a.[CreateTime],'yyyyMM'))+''+(a.[Title])+'' as as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index f7610659..0724c12c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,29 @@ namespace FreeSql.Tests.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void Format() + { + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index d46de5c1..bb970771 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.oracle.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index 3facac11..43fac79b 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.pgsql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as1, ''||((a.""id"" + 1))||'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as2 +FROM ""tb_topic"" a +WHERE (a.""id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs index c3818765..745192bf 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs @@ -50,6 +50,28 @@ namespace FreeSql.Tests.ShenTongExpression list.Add(g.shentong.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.shentong.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } [Fact] public void Empty() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index ecdadd3b..02d36262 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -65,6 +65,29 @@ namespace FreeSql.Tests.SqlServerExpression list.Add(select.Where(a => a.TitleVarchar == "aaa").ToList()); } + [Fact] + public void Format() + { + var item = g.sqlserver.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as1, N''+cast((a.[Id] + 1) as varchar)+N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index 0143271c..a64ce3ad 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -50,6 +50,29 @@ namespace FreeSql.Tests.SqliteExpression list.Add(g.sqlite.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void Format() + { + var item = g.sqlite.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||((a.""Id"" + 1))||'z-'||(strftime('%Y%m',a.""CreateTime""))||''||(a.""Title"")||'' as1, ''||((a.""Id"" + 1))||'x'||((a.""Id"" + 1))||'z-'||(strftime('%Y%m',a.""CreateTime""))||''||(a.""Title"")||'' as2 +FROM ""tb_topic"" a +WHERE (a.""Id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 9cf22a92..8ca5c1c0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -716,31 +716,7 @@ namespace FreeSql.Internal string other3Exp = null; switch (callType.FullName) { - case "System.String": - //$"{id}_{name}" - if (exp3.Method.Name == "Format" && exp3.Object == null && exp3.Arguments[0].NodeType == ExpressionType.Constant) - { - if (exp3.Arguments.Count == 1) return ExpressionLambdaToSql(exp3.Arguments[0], tsc); - var exp3Args0 = (exp3.Arguments[0] as ConstantExpression)?.Value?.ToString().Replace("{{", "{{_freesql_tMp_fLag_"); - var exp3Args1n = exp3.Arguments.Where((a, z) => z > 0).Select(a => ExpressionLambdaToSql(a, tsc)).ToArray(); - var exp3Args0Spt = Regex.Split(exp3Args0, @"{(\d+)}"); - var exp3ArgsConcatType = new Type[exp3Args0Spt.Length]; - exp3Args0Spt[0] = _common.FormatSql("{0}", exp3Args0Spt[0].Replace("{{_freesql_tMp_fLag_", "{{")); - exp3ArgsConcatType[0] = typeof(string); - for (var exp3Args0SptIndex = 1; exp3Args0SptIndex < exp3Args0Spt.Length; exp3Args0SptIndex += 2) - { - var exp3Args1nIndex = int.Parse(exp3Args0Spt[exp3Args0SptIndex]); - exp3Args0Spt[exp3Args0SptIndex] = exp3Args1n[exp3Args1nIndex]; - var expArgsType = exp3.Arguments[exp3Args1nIndex + 1]; - exp3ArgsConcatType[exp3Args0SptIndex] = (expArgsType as UnaryExpression)?.Operand.Type ?? expArgsType.Type; - - exp3Args0Spt[exp3Args0SptIndex + 1] = _common.FormatSql("{0}", exp3Args0Spt[exp3Args0SptIndex + 1].Replace("{{_freesql_tMp_fLag_", "{{")); - exp3ArgsConcatType[exp3Args0SptIndex + 1] = typeof(string); - } - return _common.StringConcat(exp3Args0Spt, exp3ArgsConcatType); - } - other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); - break; + case "System.String": other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); break; case "System.Math": other3Exp = ExpressionLambdaToSqlCallMath(exp3, tsc); break; case "System.DateTime": other3Exp = ExpressionLambdaToSqlCallDateTime(exp3, tsc); break; case "System.TimeSpan": other3Exp = ExpressionLambdaToSqlCallTimeSpan(exp3, tsc); break; diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index 8e36b3de..b9fb0a5f 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -77,7 +77,7 @@ namespace FreeSql.Dameng case "NewGuid": return null; case "Next": - if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as number)"; return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; @@ -222,7 +222,7 @@ namespace FreeSql.Dameng { case "Days": return $"extract(day from {left})"; case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; case "Minutes": return $"extract(minute from {left})"; case "Seconds": return $"floor(extract(second from {left}))"; case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; @@ -250,6 +250,10 @@ namespace FreeSql.Dameng return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs index 87b1ec06..84686afc 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -220,6 +220,10 @@ namespace FreeSql.MsAccess return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'+{(((a as UnaryExpression)?.Operand.Type ?? a.Type) == typeof(string) ? $"({ExpressionLambdaToSql(a, tsc)})" : $"cstr({ExpressionLambdaToSql(a, tsc)})")}+'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 8fd09ef4..1c409970 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -248,6 +248,11 @@ namespace FreeSql.MySql return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{ExpressionLambdaToSql(a, tsc)},'").ToArray(); + return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; } } else diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index a04c563d..4220259f 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -77,7 +77,7 @@ namespace FreeSql.Odbc.Dameng case "NewGuid": return null; case "Next": - if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as number)"; return null; case "NextDouble": if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; @@ -222,7 +222,7 @@ namespace FreeSql.Odbc.Dameng { case "Days": return $"extract(day from {left})"; case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; case "Minutes": return $"extract(minute from {left})"; case "Seconds": return $"floor(extract(second from {left}))"; case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; @@ -250,6 +250,10 @@ namespace FreeSql.Odbc.Dameng return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index d92d1bb3..710fb0b7 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -314,6 +314,10 @@ namespace FreeSql.Odbc.KingbaseES return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index ed583629..cbadc1e1 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -246,6 +246,11 @@ namespace FreeSql.Odbc.MySql return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{ExpressionLambdaToSql(a, tsc)},'").ToArray(); + return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; } } else diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index ac6dbf3c..b68ff8c4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -222,7 +222,7 @@ namespace FreeSql.Odbc.Oracle { case "Days": return $"extract(day from {left})"; case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; case "Minutes": return $"extract(minute from {left})"; case "Seconds": return $"floor(extract(second from {left}))"; case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; @@ -250,6 +250,10 @@ namespace FreeSql.Odbc.Oracle return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index c3265c27..448007ba 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -336,6 +336,10 @@ namespace FreeSql.Odbc.PostgreSQL return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 1f4bb307..c6ffd0a2 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -256,6 +256,20 @@ namespace FreeSql.Odbc.SqlServer return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs0 = ExpressionLambdaToSql(exp.Arguments[0], tsc); + if (exp.Arguments.Count == 1) return expArgs0; + var nchar = expArgs0.StartsWith("N'") ? "N" : ""; + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'+({ExpressionLambdaToSql(a, tsc)})+{nchar}'"; + if (atype == typeof(Guid)) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as char(36))+{nchar}'"; + if (atype.IsNumberType()) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as varchar)+{nchar}'"; + return $"'+cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))+{nchar}'"; + }).ToArray(); + return string.Format(expArgs0, expArgs); } } else diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 7fe04b96..989921f7 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -222,7 +222,7 @@ namespace FreeSql.Oracle { case "Days": return $"extract(day from {left})"; case "Hours": return $"extract(hour from {left})"; - case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),2,3) as number)"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; case "Minutes": return $"extract(minute from {left})"; case "Seconds": return $"floor(extract(second from {left}))"; case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; @@ -250,6 +250,10 @@ namespace FreeSql.Oracle return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 0e2c5fe1..3d989330 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -367,6 +367,10 @@ namespace FreeSql.PostgreSQL return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index 35e04a67..8476885f 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -297,6 +297,10 @@ namespace FreeSql.ShenTong return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 78f44002..65bb2fd1 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -255,6 +255,20 @@ namespace FreeSql.SqlServer return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs0 = ExpressionLambdaToSql(exp.Arguments[0], tsc); + if (exp.Arguments.Count == 1) return expArgs0; + var nchar = expArgs0.StartsWith("N'") ? "N" : ""; + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'+({ExpressionLambdaToSql(a, tsc)})+{nchar}'"; + if (atype == typeof(Guid)) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as char(36))+{nchar}'"; + if (atype.IsNumberType()) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as varchar)+{nchar}'"; + return $"'+cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))+{nchar}'"; + }).ToArray(); + return string.Format(expArgs0, expArgs); } } else diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 5a82b092..83888e2b 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -246,6 +246,10 @@ namespace FreeSql.Sqlite return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; case "Concat": return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } else From 644de4ac2e2ccaf8664caf974e2f3f81b8a1c326 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 5 Jul 2020 17:24:50 +0800 Subject: [PATCH 0732/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbSet/Reposi?= =?UTF-8?q?tory=20=E6=89=B9=E9=87=8F=E7=BA=A7=E8=81=94=E4=BF=9D=E5=AD=98(E?= =?UTF-8?q?xecuteInserted)=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98=20?= =?UTF-8?q?#362=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Interface/IAdo.cs | 2 ++ .../CommonProvider/AdoProvider/AdoProvider.cs | 14 ++++++++------ .../CommonProvider/AdoProvider/AdoProviderAsync.cs | 14 ++++++++------ .../FreeSql.Provider.MySql/Curd/MySqlDelete.cs | 4 ++-- .../FreeSql.Provider.MySql/Curd/MySqlInsert.cs | 4 ++-- .../FreeSql.Provider.MySql/Curd/MySqlUpdate.cs | 4 ++-- .../KingbaseES/Curd/OdbcKingbaseESDelete.cs | 4 ++-- .../KingbaseES/Curd/OdbcKingbaseESInsert.cs | 4 ++-- .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 4 ++-- .../MySql/Curd/OdbcMySqlDelete.cs | 4 ++-- .../MySql/Curd/OdbcMySqlInsert.cs | 4 ++-- .../MySql/Curd/OdbcMySqlUpdate.cs | 4 ++-- .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 4 ++-- .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 4 ++-- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 4 ++-- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 4 ++-- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 4 ++-- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 4 ++-- .../Curd/PostgreSQLDelete.cs | 4 ++-- .../Curd/PostgreSQLInsert.cs | 4 ++-- .../Curd/PostgreSQLUpdate.cs | 4 ++-- .../Curd/ShenTongDelete.cs | 4 ++-- .../Curd/ShenTongInsert.cs | 4 ++-- .../Curd/ShenTongUpdate.cs | 4 ++-- .../Curd/SqlServerDelete.cs | 4 ++-- .../Curd/SqlServerInsert.cs | 4 ++-- .../Curd/SqlServerUpdate.cs | 4 ++-- 27 files changed, 66 insertions(+), 60 deletions(-) diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 6db5bbd1..dade30c1 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -172,6 +172,7 @@ namespace FreeSql List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) /// @@ -344,6 +345,7 @@ namespace FreeSql Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) /// diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index bde0e6e8..0612f43d 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -94,16 +94,18 @@ namespace FreeSql.Internal.CommonProvider var props = tb?.Properties ?? type.GetPropertiesDictIgnoreCase(); return props; } - public List Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public List Query(string cmdText, object parms = null) => Query(null, null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(null, connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, null, cmdType, cmdText, cmdParms); + public List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, transaction, cmdType, cmdText, cmdParms); + public List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, connection, transaction, cmdType, cmdText, cmdParms); + public List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new List(); if (string.IsNullOrEmpty(cmdText)) return ret; var type = typeof(T); + if (resultType != null && type != resultType) type = resultType; string flag = null; int[] indexes = null; var props = GetQueryTypeProperties(type); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index f6784181..8254462b 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -14,16 +14,18 @@ namespace FreeSql.Internal.CommonProvider { partial class AdoProvider { - public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, null, cmdType, cmdText, cmdParms); + public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, transaction, cmdType, cmdText, cmdParms); + public Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, connection, transaction, cmdType, cmdText, cmdParms); + async public Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new List(); if (string.IsNullOrEmpty(cmdText)) return ret; var type = typeof(T); + if (resultType != null && type != resultType) type = resultType; string flag = null; int[] indexes = null; var props = GetQueryTypeProperties(type); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index 296a6fd3..9b5c9c2e 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 6e7d5cae..277a27c1 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -89,7 +89,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { @@ -158,7 +158,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 4f8c1178..6bb18142 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -51,7 +51,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) @@ -132,7 +132,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs index f75be644..290a40e4 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs index 908c8869..296e2435 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs @@ -105,7 +105,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index 6fe8f076..a0e14d1a 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) @@ -144,7 +144,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index a81acc88..0b4a96e7 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index 94f6a20b..e2afe42e 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -101,7 +101,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { @@ -181,7 +181,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index d86a8c93..ded5aa0c 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -51,7 +51,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) @@ -132,7 +132,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index 0d50f9dc..e133b8e2 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index e8367ac5..2c9e1b94 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -105,7 +105,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index d83fff64..20d3d697 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) @@ -144,7 +144,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index 6370377c..5de7dc0e 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -43,7 +43,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -89,7 +89,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 4fc3e5f0..ff92df61 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -87,7 +87,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { @@ -171,7 +171,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index b564ef82..9d441c5a 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -49,7 +49,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) @@ -133,7 +133,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index 9a275042..a4fc1cd4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index 8745d19b..0e8d423e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -105,7 +105,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 364a7f00..fee9268a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) @@ -144,7 +144,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs index 154af784..b4188d56 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs index 4c3c144b..86f7fdaf 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs @@ -105,7 +105,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index 28baa171..9f6c08f5 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) @@ -144,7 +144,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index 175084a9..681c40ba 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -43,7 +43,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -89,7 +89,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 0017f5c5..a801cdb9 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -92,7 +92,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { @@ -176,7 +176,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index c67b1b25..02df6442 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -50,7 +50,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) @@ -134,7 +134,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); ValidateVersionAndThrow(ret.Count); } catch (Exception ex) From 1caaba4005386d5980b26c79c7cc29c79326ce88 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 5 Jul 2020 17:29:10 +0800 Subject: [PATCH 0733/1029] v1.7.0-preview0705 #362 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 19 insertions(+), 28 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index ee6a5a52..571ca7d6 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 1c0b4576..6d6a02e5 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 47482be9..b051df49 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index d19f99af..0a3cd1aa 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 3b9f5a91..5f23b2e1 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.6.0 + 1.7.0-preview0705 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 8146f247..b4261eef 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a2b4d1d9..7ee93182 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,14 +486,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e1f3d7dd..af1b4df8 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.6.0 + 1.7.0-preview0705 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7501ec5d..3f47957d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 02bf553d..afe89161 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 20993689..9bdf462c 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 090247f0..5dba344b 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 5842fd0b..a4584ee3 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index b8930b22..cd58ba55 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 912cc7b1..621e27c3 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 17a6f544..84ba2ae4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index e575e96e..5bd2117f 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c6ee830e..918945cb 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9752d7ef..12250752 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.6.0 + 1.7.0-preview0705 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From bc77869cf7c2a2a327a2c8b2e153d1526e6242ad Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 6 Jul 2020 16:10:36 +0800 Subject: [PATCH 0734/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=A4=9A?= =?UTF-8?q?=E5=AF=B9=E5=A4=9A=E5=AF=BC=E8=88=AA=E5=B1=9E=E6=80=A7=20AsSele?= =?UTF-8?q?ct()=20=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8=20.Count()=20?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B#362?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 6 ++++ .../Sqlite/Curd/SqliteSelectTest.cs | 11 +++++++ FreeSql/Internal/CommonExpression.cs | 32 +++++++++++++------ 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index de245c0c..48d87b2c 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -111,6 +111,12 @@ namespace FreeSql.Tests.SqlServer // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) // limit 0, 1)) // limit 0, 1)) + + var t3 = g.sqlserver.Select().ToList(r => new + { + r.Title, + count = r.Tags.AsSelect().Count() + }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 7ec386cc..e7201fb6 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -107,6 +107,17 @@ namespace FreeSql.Tests.Sqlite // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) // limit 0, 1)) // limit 0, 1)) + + var t3 = g.sqlite.Select().ToList(r => new + { + r.Title, + count = r.Tags.AsSelect().Count(), + //sum = r.Tags.AsSelect().Sum(b => b.Id + 0), + //avg = r.Tags.AsSelect().Avg(b => b.Id + 1), + //max = r.Tags.AsSelect().Max(b => b.Id + 2), + //min = r.Tags.AsSelect().Min(b => b.Id + 3), + //first = r.Tags.AsSelect().First(b => b.Name) + }); } [Fact] diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 8ca5c1c0..6a8cda46 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -426,7 +426,7 @@ namespace FreeSql.Internal static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectMethodInfo = new ConcurrentDictionary(); static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectWhereMethodInfo = new ConcurrentDictionary(); static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo = new ConcurrentDictionary(); - static ConcurrentDictionary _dicExpressionLambdaToSqlAsSelectAnyMethodInfo = new ConcurrentDictionary(); + static ConcurrentDictionary> _dicExpressionLambdaToSqlAsSelectAggMethodInfo = new ConcurrentDictionary>(); internal static ConcurrentDictionary _dicNullableValueProperty = new ConcurrentDictionary(); static ConcurrentDictionary _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary(); static MethodInfo MethodDateTimeSubtractDateTime = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(DateTime) }); @@ -915,8 +915,8 @@ namespace FreeSql.Internal } var fsqlWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(asSelectEntityType, asSelectEntityType3 => typeof(ISelect<>).MakeGenericType(asSelectEntityType3).GetMethod("Where", new[] { - typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool))) - })); + typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(asSelectEntityType3, typeof(bool))) + })); var parm123Tb = _common.GetTableByEntity(asSelectParentExp.Type); var parm123Ref = parm123Tb.GetTableRef(asSelectParentExp1.Member.Name, true); if (parm123Ref != null) @@ -929,12 +929,10 @@ namespace FreeSql.Internal var manyTb = _common.GetTableByEntity(parm123Ref.RefMiddleEntityType); var manySubSelectWhere = _dicExpressionLambdaToSqlAsSelectWhereMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => typeof(ISelect<>).MakeGenericType(refMiddleEntityType3).GetMethod("Where", new[] { - typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool))) - })); + typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(refMiddleEntityType3, typeof(bool))) + })); var manySubSelectWhereSql = _dicExpressionLambdaToSqlAsSelectWhereSqlMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Where", new[] { typeof(string), typeof(object) })); - var manySubSelectAny = _dicExpressionLambdaToSqlAsSelectAnyMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => - typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(refMiddleEntityType3), refMiddleEntityType3).GetMethod("Any", new Type[0])); var manySubSelectAsSelectExp = _dicFreeSqlGlobalExtensionsAsSelectExpression.GetOrAdd(parm123Ref.RefMiddleEntityType, refMiddleEntityType3 => Expression.Call( typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3), @@ -987,9 +985,25 @@ namespace FreeSql.Internal var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); if (string.IsNullOrEmpty(sql2) == false) manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace("\r\n", "\r\n\t")})"), Expression.Constant(null)); - manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAny); + MethodInfo manySubSelectAggMethod = null; + switch (exp3.Method.Name) //https://github.com/dotnetcore/FreeSql/issues/362 + { + case "Any": + case "Count": + manySubSelectAggMethod = _dicExpressionLambdaToSqlAsSelectAggMethodInfo.GetOrAdd(parm123Ref.RefMiddleEntityType, _ => new ConcurrentDictionary()).GetOrAdd(exp3.Method.Name, exp3MethodName => + typeof(ISelect0<,>).MakeGenericType(typeof(ISelect<>).MakeGenericType(parm123Ref.RefMiddleEntityType), parm123Ref.RefMiddleEntityType).GetMethod(exp3MethodName, new Type[0])); + manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAggMethod); + break; + case "Sum": + case "Min": + case "Max": + case "Avg": + case "ToList": + case "ToOne": + case "First": + throw new ArgumentException($"ManyToMany 导航属性 .AsSelect() 暂时不可用于 Sum/Avg/Max/Min/First/ToOne/ToList 方法"); + } asSelectBefores.Clear(); - return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); } for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) From 9c3b5b15c45b0693bf4295c36039d2bd1bffd4ee Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 12 Jul 2020 11:16:26 +0800 Subject: [PATCH 0735/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=8F=92=E5=85=A5=E7=9A=84=E6=97=B6=E5=80=99=E6=8A=A5?= =?UTF-8?q?=E9=94=99System.DivideByZeroException=20#365=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/InsertProvider.cs | 1 + FreeSql/Internal/CommonProvider/UpdateProvider.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 6883a596..fae63436 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -181,6 +181,7 @@ namespace FreeSql.Internal.CommonProvider if (_noneParameter == false) { var colSum = _table.Columns.Count - _ignore.Count; + if (colSum <= 0) colSum = 1; takeMax = parameterLimit / colSum; if (takeMax > valuesLimit) takeMax = valuesLimit; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 7385aa2f..39e62aa4 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -126,6 +126,7 @@ namespace FreeSql.Internal.CommonProvider if (_noneParameter == false) { var colSum = _table.Columns.Count - _ignore.Count; + if (colSum <= 0) colSum = 1; takeMax = parameterLimit / colSum; if (takeMax > valuesLimit) takeMax = valuesLimit; } From 8c3892233108545015290c159b3f3ee70700ee8c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 12 Jul 2020 12:34:55 +0800 Subject: [PATCH 0736/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20CodeFirst=20?= =?UTF-8?q?+=20AsTable=20+=20=E8=87=AA=E5=8A=A8=E8=BF=81=E7=A7=BB=EF=BC=8C?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E7=B4=A2=E6=80=A7=E5=90=8D=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20#366=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlCodeFirstTest.cs | 1 + .../Dameng/DamengCodeFirstTest.cs | 9 ++++---- .../KingbaseES/KingbaseESCodeFirstTest.cs | 7 +++--- .../MySql/MySqlCodeFirstTest.cs | 1 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 7 +++--- .../SqlServer/SqlServerCodeFirstTest.cs | 1 + .../Dameng/DamengCodeFirstTest.cs | 9 ++++---- .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 1 + .../Oracle/OracleCodeFirstTest.cs | 1 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 7 +++--- .../ShenTong/ShenTongCodeFirstTest.cs | 7 +++--- .../SqlServer/SqlServerCodeFirstTest.cs | 1 + .../Sqlite/SqliteCodeFirstTest.cs | 7 +++--- FreeSql/DataAnnotations/IndexAttribute.cs | 17 +++++++++++++- FreeSql/FreeSql.xml | 23 ++++++++++++++++++- .../CommonProvider/CodeFirstProvider.cs | 3 +++ .../DamengCodeFirst.cs | 11 +++++---- .../MsAccessCodeFirst.cs | 6 +++-- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 11 +++++---- .../Dameng/OdbcDamengCodeFirst.cs | 11 +++++---- .../KingbaseES/OdbcKingbaseESCodeFirst.cs | 11 +++++---- .../MySql/OdbcMySqlCodeFirst.cs | 11 +++++---- .../Oracle/OdbcOracleCodeFirst.cs | 11 +++++---- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 11 +++++---- .../SqlServer/OdbcSqlServerCodeFirst.cs | 11 +++++---- .../OracleCodeFirst.cs | 11 +++++---- .../PostgreSQLCodeFirst.cs | 11 +++++---- .../ShenTongCodeFirst.cs | 11 +++++---- .../SqlServerCodeFirst.cs | 11 +++++---- .../SqliteCodeFirst.cs | 7 +++--- 30 files changed, 157 insertions(+), 90 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 6d04609c..00410106 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -238,6 +238,7 @@ namespace FreeSql.Tests.MySqlConnector { var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); g.mysql.CodeFirst.SyncStructure(); + g.mysql.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] [Index("uk_phone", "phone", true)] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index 0fcc7897..319fdfbf 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -134,11 +134,12 @@ namespace FreeSql.Tests.Odbc.Dameng { var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); g.dameng.CodeFirst.SyncStructure(); + g.dameng.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInf1"); } - [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - [Index("uk_phone", "phone", true)] - [Index("uk_group_index", "group,index", true)] - [Index("uk_group_index22", "group, index22", true)] + [Table(Name = "AddUniquesInf", OldName = "AddUniquesInfo2")] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs index 8d72a1b3..68194038 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs @@ -134,11 +134,12 @@ namespace FreeSql.Tests.Odbc.KingbaseES { var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); g.kingbaseES.CodeFirst.SyncStructure(); + g.kingbaseES.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - [Index("uk_phone", "phone", true)] - [Index("uk_group_index", "group,index", true)] - [Index("uk_group_index22", "group, index22", true)] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index 967151b0..efa92779 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -109,6 +109,7 @@ namespace FreeSql.Tests.Odbc.MySql { var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); g.mysql.CodeFirst.SyncStructure(); + g.mysql.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] [Index("uk_phone", "phone", true)] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs index c6d33cb5..9b8e95e7 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -85,11 +85,12 @@ namespace FreeSql.Tests.Odbc.PostgreSQL { var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); g.pgsql.CodeFirst.SyncStructure(); + g.pgsql.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - [Index("uk_phone", "phone", true)] - [Index("uk_group_index", "group,index", true)] - [Index("uk_group_index22", "group, index22", true)] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index 77987554..2642bf0c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -118,6 +118,7 @@ namespace FreeSql.Tests.Odbc.SqlServer { var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); g.sqlserver.CodeFirst.SyncStructure(); + g.sqlserver.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] [Index("uk_phone", "phone", true)] diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs index bc5688c8..94af3999 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs @@ -204,11 +204,12 @@ namespace FreeSql.Tests.Dameng { var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); g.dameng.CodeFirst.SyncStructure(); + g.dameng.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInf1"); } - [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - [Index("uk_phone", "phone", true)] - [Index("uk_group_index", "group,index", true)] - [Index("uk_group_index22", "group, index22", true)] + [Table(Name = "AddUniquesInf", OldName = "AddUniquesInfo2")] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group, index22", true)] class AddUniquesInfo { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 4b927196..58274df0 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -237,6 +237,7 @@ namespace FreeSql.Tests.MySql { var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); g.mysql.CodeFirst.SyncStructure(); + g.mysql.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] [Index("uk_phone", "phone", true)] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index a751c4ea..cf5e4834 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -234,6 +234,7 @@ namespace FreeSql.Tests.Oracle { var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); g.oracle.CodeFirst.SyncStructure(); + //g.oracle.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] [Index("uk_phone", "phone", true)] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index 169a2707..b96b1eec 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -125,11 +125,12 @@ namespace FreeSql.Tests.PostgreSQL { var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); g.pgsql.CodeFirst.SyncStructure(); + g.pgsql.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - [Index("uk_phone", "phone", true)] - [Index("uk_group_index", "group,index", true)] - [Index("uk_group_index22", "group, index22", false)] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group, index22", false)] class AddUniquesInfo { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs index 4f4dbba4..8031a61f 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs @@ -90,11 +90,12 @@ namespace FreeSql.Tests.ShenTong { var sql = g.shentong.CodeFirst.GetComparisonDDLStatements(); g.shentong.CodeFirst.SyncStructure(); + g.shentong.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] - [Index("uk_phone", "phone", true)] - [Index("uk_group_index", "group,index", true)] - [Index("uk_group_index22", "group, index22", false)] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group, index22", false)] class AddUniquesInfo { public Guid id { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index be6415ff..c32f9287 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -154,6 +154,7 @@ namespace FreeSql.Tests.SqlServer { var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); g.sqlserver.CodeFirst.SyncStructure(); + g.sqlserver.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] [Index("uk_phone", "phone", true)] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index 98ecf805..65c62fc1 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -146,11 +146,12 @@ namespace FreeSql.Tests.Sqlite { var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements(); g.sqlite.CodeFirst.SyncStructure(); + g.sqlite.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); } [Table(Name = "AddUniquesInfo2", OldName = "AddUniquesInfo")] - [Index("uk_phone", "phone", true)] - [Index("uk_group_index", "group,index", true)] - [Index("uk_group_index22", "group desc, index22", true)] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group desc, index22", true)] class AddUniquesInfo { public Guid id { get; set; } diff --git a/FreeSql/DataAnnotations/IndexAttribute.cs b/FreeSql/DataAnnotations/IndexAttribute.cs index 9115dfd0..ed36653c 100644 --- a/FreeSql/DataAnnotations/IndexAttribute.cs +++ b/FreeSql/DataAnnotations/IndexAttribute.cs @@ -4,14 +4,28 @@ using System.Text; namespace FreeSql.DataAnnotations { + /// + /// 索引设置,如:[Index("{tablename}_idx_01", "name")] + /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class IndexAttribute : Attribute { + /// + /// 索引设置,如:[Index("{tablename}_idx_01", "name")] + /// + /// 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + /// 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC public IndexAttribute(string name, string fields) { this.Name = name; this.Fields = fields; } + /// + /// 索引设置,如:[Index("{tablename}_idx_01", "name", true)] + /// + /// 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + /// 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + /// 是否唯一 public IndexAttribute(string name, string fields, bool isUnique) { this.Name = name; @@ -19,7 +33,8 @@ namespace FreeSql.DataAnnotations this.IsUnique = isUnique; } /// - /// 索引名 + /// 索引名 + /// v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) /// public string Name { get; set; } /// diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1fa49bdd..c70e644b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -274,9 +274,30 @@ + + + 索引设置,如:[Index("{tablename}_idx_01", "name")] + + + + + 索引设置,如:[Index("{tablename}_idx_01", "name")] + + 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + 索引设置,如:[Index("{tablename}_idx_01", "name", true)] + + 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + - 索引名 + 索引名 + v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 619f9d23..c9350e78 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -9,6 +9,7 @@ using System.Data.Common; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider @@ -124,5 +125,7 @@ namespace FreeSql.Internal.CommonProvider } public virtual int ExecuteDDLStatements(string ddl) => _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); + + public static string ReplaceIndexName(string indexName, string tbname) => string.IsNullOrEmpty(indexName) ? indexName : Regex.Replace(indexName, @"\{\s*TableName\s*\}", tbname, RegexOptions.IgnoreCase); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs index 61e0573b..6da2899d 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs @@ -149,7 +149,7 @@ namespace FreeSql.Dameng { sb.Append("execute immediate 'CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -282,13 +282,14 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append("';\r\n"); + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append("';\r\n"); sbalter.Append("execute immediate 'CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -373,7 +374,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and { sb.Append("execute immediate 'CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs index 463c0001..dcffefd5 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs @@ -139,13 +139,14 @@ namespace FreeSql.MsAccess }; Action createTableIndex = tn => { + var oldtn = tn; tn = _commonUtils.QuoteSqlName(tn); //创建表的索引 foreach (var uk in tb.Indexes) { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tn).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, oldtn))).Append(" ON ").Append(tn).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -379,7 +380,8 @@ namespace FreeSql.MsAccess foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) istmpatler = true; } diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 673a6220..b57ae165 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -167,7 +167,7 @@ namespace FreeSql.MySql { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -282,13 +282,14 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -364,7 +365,7 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index bca00ccd..72a18e0a 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -150,7 +150,7 @@ namespace FreeSql.Odbc.Dameng { sb.Append("execute immediate 'CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -283,13 +283,14 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append("';\r\n"); + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append("';\r\n"); sbalter.Append("execute immediate 'CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -374,7 +375,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and { sb.Append("execute immediate 'CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs index efde626e..6ea23cb2 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs @@ -138,7 +138,7 @@ namespace FreeSql.Odbc.KingbaseES { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -272,13 +272,14 @@ where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tbol foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -368,7 +369,7 @@ where sys_namespace.nspname={0} and sys_class.relname={1} and sys_constraint.con { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 8bc6b09a..4832a458 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -160,7 +160,7 @@ namespace FreeSql.Odbc.MySql { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -275,13 +275,14 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -357,7 +358,7 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 8120f32c..fb6f9549 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -150,7 +150,7 @@ namespace FreeSql.Odbc.Oracle { sb.Append("execute immediate 'CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -281,13 +281,14 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append("';\r\n"); + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append("';\r\n"); sbalter.Append("execute immediate 'CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -370,7 +371,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam { sb.Append("execute immediate 'CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index aed5198f..ee4f79d5 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -150,7 +150,7 @@ namespace FreeSql.Odbc.PostgreSQL { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -284,13 +284,14 @@ where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || is96 == false)).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -380,7 +381,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 73519a67..f319e1cb 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -230,7 +230,7 @@ ELSE { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -342,13 +342,14 @@ use [" + database + "];", tboldname ?? tbname); foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -450,7 +451,7 @@ use [" + database + "];", tboldname ?? tbname); { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index f7236949..6bb3411a 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -151,7 +151,7 @@ namespace FreeSql.Oracle { sb.Append("execute immediate 'CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -282,13 +282,14 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append("';\r\n"); + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append("';\r\n"); sbalter.Append("execute immediate 'CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -371,7 +372,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam { sb.Append("execute immediate 'CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 6a0b4c3b..e62d578d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -185,7 +185,7 @@ namespace FreeSql.PostgreSQL { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -319,13 +319,14 @@ where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || is96 == false)).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -415,7 +416,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs index 7d5d6fd3..efe5d19e 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs @@ -150,7 +150,7 @@ namespace FreeSql.ShenTong { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -285,13 +285,14 @@ where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tbol foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -381,7 +382,7 @@ where sys_namespace.nspname={0} and sys_class.relname={1} and sys_constraint.con { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 38e38853..ff1ab63a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -229,7 +229,7 @@ ELSE { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[2]))).Append(" ON ").Append(createTableName).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -341,13 +341,14 @@ use [" + database + "];", tboldname ?? tbname); foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[2]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) { - if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append(";\r\n"); + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append(";\r\n"); sbalter.Append("CREATE "); if (uk.IsUnique) sbalter.Append("UNIQUE "); - sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append("("); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append("("); foreach (var tbcol in uk.Columns) { sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -449,7 +450,7 @@ use [" + database + "];", tboldname ?? tbname); { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tablename).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[2]))).Append(" ON ").Append(tablename).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 044e1e4c..3d8dc14f 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -135,7 +135,7 @@ namespace FreeSql.Sqlite { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(tbname[1]).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tbname[1]).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); @@ -223,7 +223,8 @@ namespace FreeSql.Sqlite foreach (var uk in tb.Indexes) { if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; - var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray(); + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) istmpatler = true; } @@ -290,7 +291,7 @@ namespace FreeSql.Sqlite { sb.Append("CREATE "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON \"").Append(tablenameOnlyTb).Append("\"("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON \"").Append(tablenameOnlyTb).Append("\"("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); From 8e14759fdd9483f2565129f5407eecdd84702ed8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 12 Jul 2020 12:55:19 +0800 Subject: [PATCH 0737/1029] debug #367 --- .../CommonProvider/SelectProvider/Select1Provider.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 952770d6..78bf79be 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -372,7 +372,12 @@ namespace FreeSql.Internal.CommonProvider if (whereExp == null) { tbref = tb.GetTableRef(collMem.Member.Name, true); - if (tbref == null) throw new Exception($"IncludeMany 类型 {tb.Type.DisplayCsharp()} 的属性 {collMem.Member.Name} 不是有效的导航属性,提示:IsIgnore = true 不会成为导航属性"); + if (tbref == null) + { + tb = _commonUtils.GetTableByEntity(collMem.Expression.Type); //debug https://github.com/dotnetcore/FreeSql/issues/367 + tbref = tb.GetTableRef(collMem.Member.Name, true); + if (tbref == null) throw new Exception($"IncludeMany 类型 {tb.Type.DisplayCsharp()} 的属性 {collMem.Member.Name} 不是有效的导航属性,提示:IsIgnore = true 不会成为导航属性"); + } } else { From f2fba673d23366834b064da0d50a14bd3381972e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 12 Jul 2020 20:47:07 +0800 Subject: [PATCH 0738/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Prov?= =?UTF-8?q?ider.PostgreSQL=20NetTopologySuite=20=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=98=A0=E5=B0=84=EF=BC=8C=E4=BF=9D=E7=95=99=20LegacyPostgis?= =?UTF-8?q?=20=E6=98=A0=E5=B0=84=20#369=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...rovider.PostgreSQL.NetTopologySuite.csproj | 25 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 448 ++++++++++++++++++ .../g.cs | 27 ++ FreeSql.sln | 14 + .../SelectProvider/Select1Provider.cs | 7 +- .../FreeSql.Provider.PostgreSQL.csproj | 5 + .../PostgreSQLCodeFirst.cs | 14 +- .../PostgreSQLProvider.cs | 14 + .../PostgreSQLUtils.cs | 26 +- 9 files changed, 569 insertions(+), 11 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/g.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj new file mode 100644 index 00000000..04119115 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp3.1 + + false + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs new file mode 100644 index 00000000..5d0b0a30 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -0,0 +1,448 @@ +using FreeSql.DataAnnotations; +using NetTopologySuite.Geometries; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Npgsql; +using NpgsqlTypes; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.PostgreSQL.NetTopologySuite +{ + public class PostgreSQLCodeFirstTest + { + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.Select(); + } + + IInsert insert => g.pgsql.Insert(); + ISelect select => g.pgsql.Select(); + + [Fact] + public void CurdAllField() + { + var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql(); + var sql2 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql(); + + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBitArray = new BitArray(Encoding.UTF8.GetBytes("")), + testFieldBitArrayArray = new[] { new BitArray(Encoding.UTF8.GetBytes("й")), new BitArray(Encoding.UTF8.GetBytes("")) }, + testFieldBool = true, + testFieldBoolArray = new[] { true, true, false, false }, + testFieldBoolArrayNullable = new bool?[] { true, true, null, false, false }, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + testFieldByteArray = new byte[] { 0, 1, 2, 3, 4, 5, 6 }, + testFieldByteArrayNullable = new byte?[] { 0, 1, 2, 3, null, 4, 5, 6 }, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.UTF8.GetBytes("й"), + testFieldBytesArray = new[] { Encoding.UTF8.GetBytes("й"), Encoding.UTF8.GetBytes("й") }, + testFieldCidr = (IPAddress.Parse("10.0.0.0"), 8), + testFieldCidrArray = new[] { (IPAddress.Parse("10.0.0.0"), 8), (IPAddress.Parse("192.168.0.0"), 16) }, + testFieldCidrArrayNullable = new (IPAddress, int)?[] { (IPAddress.Parse("10.0.0.0"), 8), null, (IPAddress.Parse("192.168.0.0"), 16) }, + testFieldCidrNullable = (IPAddress.Parse("192.168.0.0"), 16), + testFieldDateTime = DateTime.Now, + testFieldDateTimeArray = new[] { DateTime.Now, DateTime.Now.AddHours(2) }, + testFieldDateTimeArrayNullable = new DateTime?[] { DateTime.Now, null, DateTime.Now.AddHours(2) }, + testFieldDateTimeNullable = DateTime.Now.AddDays(-1), + testFieldDecimal = 999.99M, + testFieldDecimalArray = new[] { 999.91M, 999.92M, 999.93M }, + testFieldDecimalArrayNullable = new decimal?[] { 998.11M, 998.12M, 998.13M }, + testFieldDecimalNullable = 111.11M, + testFieldDouble = 888.88, + testFieldDoubleArray = new[] { 888.81, 888.82, 888.83 }, + testFieldDoubleArrayNullable = new double?[] { 888.11, 888.12, null, 888.13 }, + testFieldDoubleNullable = 222.22, + testFieldEnum1 = TableAllTypeEnumType1.e3, + testFieldEnum1Array = new[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, TableAllTypeEnumType1.e1 }, + testFieldEnum1ArrayNullable = new TableAllTypeEnumType1?[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, null, TableAllTypeEnumType1.e1 }, + testFieldEnum1Nullable = TableAllTypeEnumType1.e2, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Array = new[] { TableAllTypeEnumType2.f3, TableAllTypeEnumType2.f1 }, + testFieldEnum2ArrayNullable = new TableAllTypeEnumType2?[] { TableAllTypeEnumType2.f3, null, TableAllTypeEnumType2.f1 }, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 777.77F, + testFieldFloatArray = new[] { 777.71F, 777.72F, 777.73F }, + testFieldFloatArrayNullable = new float?[] { 777.71F, 777.72F, null, 777.73F }, + testFieldFloatNullable = 333.33F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidArray = new[] { Guid.NewGuid(), Guid.NewGuid() }, + testFieldGuidArrayNullable = new Guid?[] { Guid.NewGuid(), null, Guid.NewGuid() }, + testFieldGuidNullable = Guid.NewGuid(), + testFieldHStore = new Dictionary { { "111", "value111" }, { "222", "value222" }, { "333", "value333" } }, + testFieldHStoreArray = new[] { new Dictionary { { "111", "value111" }, { "222", "value222" }, { "333", "value333" } }, new Dictionary { { "444", "value444" }, { "555", "value555" }, { "666", "value666" } } }, + testFieldInet = IPAddress.Parse("192.168.1.1"), + testFieldInetArray = new[] { IPAddress.Parse("192.168.1.1"), IPAddress.Parse("192.168.1.2"), IPAddress.Parse("192.168.1.3") }, + testFieldInt = int.MaxValue, + testFieldInt4range = new NpgsqlRange(10, 20), + testFieldInt4rangeArray = new[] { new NpgsqlRange(10, 20), new NpgsqlRange(50, 100), new NpgsqlRange(200, 300) }, + testFieldInt4rangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(10, 20), new NpgsqlRange(50, 100), null, new NpgsqlRange(200, 300) }, + testFieldInt4rangeNullable = new NpgsqlRange(100, 200), + testFieldInt8range = new NpgsqlRange(100, 200), + testFieldInt8rangeArray = new[] { new NpgsqlRange(100, 200), new NpgsqlRange(500, 1000), new NpgsqlRange(2000, 3000) }, + testFieldInt8rangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(100, 200), new NpgsqlRange(500, 1000), null, new NpgsqlRange(2000, 3000) }, + testFieldInt8rangeNullable = new NpgsqlRange(1000, 2000), + testFieldIntArray = new[] { 1, 2, 3, 4, 5 }, + testFieldIntArrayNullable = new int?[] { 1, 2, 3, null, 4, 5 }, + testFieldIntNullable = int.MinValue, + testFieldJArray = JArray.Parse("[1,2,3,4,5]"), + testFieldJArrayArray = new[] { JArray.Parse("[1,2,3,4,5]"), JArray.Parse("[10,20,30,40,50]") }, + testFieldJObject = JObject.Parse("{ \"a\":1, \"b\":2, \"c\":3 }"), + testFieldJObjectArray = new[] { JObject.Parse("{ \"a\":1, \"b\":2, \"c\":3 }"), JObject.Parse("{ \"a\":10, \"b\":20, \"c\":30 }") }, + testFieldJToken = JToken.Parse("{ \"a\":1, \"b\":2, \"c\":3, \"d\":[1,2,3,4,5] }"), + testFieldJTokenArray = new[] { JToken.Parse("{ \"a\":1, \"b\":2, \"c\":3, \"d\":[1,2,3,4,5] }"), JToken.Parse("{ \"a\":10, \"b\":20, \"c\":30, \"d\":[10,20,30,40,50] }") }, + testFieldLong = long.MaxValue, + testFieldLongArray = new long[] { 10, 20, 30, 40, 50 }, + testFieldMacaddr = PhysicalAddress.Parse("A1-A2-CD-DD-FF-02"), + testFieldMacaddrArray = new[] { PhysicalAddress.Parse("A1-A2-CD-DD-FF-02"), PhysicalAddress.Parse("A2-22-22-22-22-02") }, + testFieldNpgsqlBox = new NpgsqlBox(10, 100, 100, 10), + testFieldNpgsqlBoxArray = new[] { new NpgsqlBox(10, 100, 100, 10), new NpgsqlBox(200, 2000, 2000, 200) }, + testFieldNpgsqlBoxArrayNullable = new NpgsqlBox?[] { new NpgsqlBox(10, 100, 100, 10), null, new NpgsqlBox(200, 2000, 2000, 200) }, + testFieldNpgsqlBoxNullable = new NpgsqlBox(200, 2000, 2000, 200), + testFieldNpgsqlCircle = new NpgsqlCircle(50, 50, 100), + testFieldNpgsqlCircleArray = new[] { new NpgsqlCircle(50, 50, 100), new NpgsqlCircle(80, 80, 100) }, + testFieldNpgsqlCircleArrayNullable = new NpgsqlCircle?[] { new NpgsqlCircle(50, 50, 100), null, new NpgsqlCircle(80, 80, 100) }, + testFieldNpgsqlCircleNullable = new NpgsqlCircle(80, 80, 100), + testFieldNpgsqlLine = new NpgsqlLine(30, 30, 30), + testFieldNpgsqlLineArray = new[] { new NpgsqlLine(30, 30, 30), new NpgsqlLine(35, 35, 35) }, + testFieldNpgsqlLineArrayNullable = new NpgsqlLine?[] { new NpgsqlLine(30, 30, 30), null, new NpgsqlLine(35, 35, 35) }, + testFieldNpgsqlLineNullable = new NpgsqlLine(60, 60, 60), + testFieldNpgsqlLSeg = new NpgsqlLSeg(80, 10, 800, 20), + testFieldNpgsqlLSegArray = new[] { new NpgsqlLSeg(80, 10, 800, 20), new NpgsqlLSeg(180, 20, 260, 50) }, + testFieldNpgsqlLSegArrayNullable = new NpgsqlLSeg?[] { new NpgsqlLSeg(80, 10, 800, 20), null, new NpgsqlLSeg(180, 20, 260, 50) }, + testFieldNpgsqlLSegNullable = new NpgsqlLSeg(180, 20, 260, 50), + testFieldNpgsqlPath = new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), + testFieldNpgsqlPathArray = new[] { new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)) }, + testFieldNpgsqlPathArrayNullable = new NpgsqlPath?[] { new NpgsqlPath(new NpgsqlPoint(10, 10), new NpgsqlPoint(15, 10), new NpgsqlPoint(17, 10), new NpgsqlPoint(19, 10)), null, new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)) }, + testFieldNpgsqlPathNullable = new NpgsqlPath(new NpgsqlPoint(210, 10), new NpgsqlPoint(215, 10), new NpgsqlPoint(217, 10), new NpgsqlPoint(219, 10)), + testFieldNpgsqlPoint = new NpgsqlPoint(666, 666), + testFieldNpgsqlPointArray = new[] { new NpgsqlPoint(666, 666), new NpgsqlPoint(888, 888) }, + testFieldNpgsqlPointArrayNullable = new NpgsqlPoint?[] { new NpgsqlPoint(666, 666), null, new NpgsqlPoint(888, 888) }, + testFieldNpgsqlPointNullable = new NpgsqlPoint(888, 888), + testFieldNpgsqlPolygon = new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), + testFieldNpgsqlPolygonArray = new[] { new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)) }, + testFieldNpgsqlPolygonArrayNullable = new NpgsqlPolygon?[] { new NpgsqlPolygon(new NpgsqlPoint(36, 30), new NpgsqlPoint(36, 50), new NpgsqlPoint(38, 80), new NpgsqlPoint(36, 30)), null, new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)) }, + testFieldNpgsqlPolygonNullable = new NpgsqlPolygon(new NpgsqlPoint(136, 130), new NpgsqlPoint(136, 150), new NpgsqlPoint(138, 180), new NpgsqlPoint(136, 130)), + testFieldNumrange = new NpgsqlRange(888.88M, 999.99M), + testFieldNumrangeArray = new[] { new NpgsqlRange(888.88M, 999.99M), new NpgsqlRange(18888.88M, 19998.99M) }, + testFieldNumrangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(888.88M, 999.99M), null, new NpgsqlRange(18888.88M, 19998.99M) }, + testFieldNumrangeNullable = new NpgsqlRange(18888.88M, 19998.99M), + testFieldGeometry = new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }) { SRID = 4326 }, + testFieldGeometryArray = new Geometry[] { + new Point(555,551), + new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new MultiLineString(new[] { new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), new LineString(new[] { new Coordinate(20, 21), new Coordinate(200, 210) }) }), + new MultiPoint(new[] { new Point(20, 21), new Point(210, 220) }), + new MultiPolygon(new []{ + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new Polygon(new LinearRing(new[] { new Coordinate(50, 51), new Coordinate(500, 510), new Coordinate(800, 810), new Coordinate(50, 51) })) + }) + }, + testFieldGeometryCollection = new GeometryCollection(new Geometry[] { + new Point(555,551), + new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new MultiLineString(new[] { new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), new LineString(new[] { new Coordinate(20, 21), new Coordinate(200, 210) }) }), + new MultiPoint(new[] { new Point(20, 21), new Point(210, 220) }), + new MultiPolygon(new []{ + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new Polygon(new LinearRing(new[] { new Coordinate(50, 51), new Coordinate(500, 510), new Coordinate(800, 810), new Coordinate(50, 51) })) + }) + }), + testFieldGeometryCollectionArray = new[] { + new GeometryCollection(new Geometry[] { + new Point(555,551), + new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new MultiLineString(new[] { new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), new LineString(new[] { new Coordinate(20, 21), new Coordinate(200, 210) }) }), + new MultiPoint(new[] { new Point(20, 21), new Point(210, 220) }), + new MultiPolygon(new []{ + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new Polygon(new LinearRing(new[] { new Coordinate(50, 51), new Coordinate(500, 510), new Coordinate(800, 810), new Coordinate(50, 51) })) + }) + }),new GeometryCollection(new Geometry[] { + new Point(555,551), + new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new MultiLineString(new[] { new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), new LineString(new[] { new Coordinate(20, 21), new Coordinate(200, 210) }) }), + new MultiPoint(new[] { new Point(20, 21), new Point(210, 220) }), + new MultiPolygon(new []{ + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new Polygon(new LinearRing(new[] { new Coordinate(50, 51), new Coordinate(500, 510), new Coordinate(800, 810), new Coordinate(50, 51) })) + }) + }) + }, + testFieldLineString = new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), + testFieldLineStringArray = new[] { new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), new LineString(new[] { new Coordinate(20, 21), new Coordinate(200, 220) }) }, + testFieldMultiPoint = new MultiPoint(new[] { new Point(20, 21), new Point(210, 220) }), + testFieldMultiPointArray = new[] { new MultiPoint(new[] { new Point(20, 21), new Point(210, 220) }), new MultiPoint(new[] { new Point(120, 121), new Point(1210, 1220) }) }, + testFieldPoint = new Point(555, 551), + testFieldPointArray = new[] { new Point(555, 551), new Point(53355, 3551) }, + testFieldPolygon = new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + testFieldPolygonArray = new[]{ + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new Polygon(new LinearRing(new[] { new Coordinate(50, 51), new Coordinate(500, 510), new Coordinate(800, 810), new Coordinate(50, 51) })) + }, + testFieldMultiLineString = new MultiLineString(new[] { new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), new LineString(new[] { new Coordinate(20, 21), new Coordinate(200, 210) }) }), + testFieldMultiLineStringArray = new[] { + new MultiLineString(new[] { new LineString(new[] { new Coordinate(10, 11), new Coordinate(100, 110) }), new LineString(new[] { new Coordinate(20, 21), new Coordinate(200, 210) }) }), + new MultiLineString(new[] { new LineString(new[] { new Coordinate(20, 21), new Coordinate(200, 220) }), new LineString(new[] { new Coordinate(820, 821), new Coordinate(800, 810) }) }) + }, + testFieldMultiPolygon = new MultiPolygon(new[]{ + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new Polygon(new LinearRing(new[] { new Coordinate(50, 51), new Coordinate(500, 510), new Coordinate(800, 810), new Coordinate(50, 51) })) + }), + testFieldMultiPolygonArray = new[] { + new MultiPolygon(new[]{ + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new Polygon(new LinearRing(new[] { new Coordinate(50, 51), new Coordinate(500, 510), new Coordinate(800, 810), new Coordinate(50, 51) })) + }), + new MultiPolygon(new[]{ + new Polygon(new LinearRing(new[] { new Coordinate(10, 11), new Coordinate(100, 110), new Coordinate(300, 310), new Coordinate(10, 11) })), + new Polygon(new LinearRing(new[] { new Coordinate(50, 51), new Coordinate(500, 510), new Coordinate(800, 810), new Coordinate(50, 51) })) + }) + }, + testFieldSByte = sbyte.MaxValue, + testFieldSByteArray = new sbyte[] { 1, 2, 3, 4, 5 }, + testFieldSByteArrayNullable = new sbyte?[] { 1, 2, 3, null, 4, 5 }, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + testFieldShortArray = new short[] { 1, 2, 3, 4, 5 }, + testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 }, + testFieldShortNullable = short.MinValue, + testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldStringArray = new[] { "йString1", "йString2", null, "йString3" }, + testFieldTimeSpan = TimeSpan.FromDays(1), + testFieldTimeSpanArray = new[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }, + testFieldTimeSpanArrayNullable = new TimeSpan?[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), null, TimeSpan.FromSeconds(60) }, + testFieldTimeSpanNullable = TimeSpan.FromSeconds(90), + testFieldTsrange = new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), + testFieldTsrangeArray = new[] { new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)) }, + testFieldTsrangeArrayNullable = new NpgsqlRange?[] { new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(1)), null, new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)) }, + testFieldTsrangeNullable = new NpgsqlRange(DateTime.Now, DateTime.Now.AddMonths(2)), + testFieldUInt = uint.MaxValue, + testFieldUIntArray = new uint[] { 1, 2, 3, 4, 5 }, + testFieldUIntArrayNullable = new uint?[] { 1, 2, 3, null, 4, 5 }, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongArray = new ulong[] { 10, 20, 30, 40, 50 }, + testFieldULongArrayNullable = new ulong?[] { 10, 20, 30, null, 40, 50 }, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortArray = new ushort[] { 11, 12, 13, 14, 15 }, + testFieldUShortArrayNullable = new ushort?[] { 11, 12, 13, null, 14, 15 }, + testFieldUShortNullable = ushort.MinValue, + testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 }, + testFielLongNullable = long.MinValue + }; + + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); + + var item3 = insert.AppendData(item2).ExecuteInserted().First(); + var newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); + newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype_nts")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime testFieldDateTime { get; set; } + + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + public NpgsqlPoint testFieldNpgsqlPoint { get; set; } + public NpgsqlLine testFieldNpgsqlLine { get; set; } + public NpgsqlLSeg testFieldNpgsqlLSeg { get; set; } + public NpgsqlBox testFieldNpgsqlBox { get; set; } + public NpgsqlPath testFieldNpgsqlPath { get; set; } + public NpgsqlPolygon testFieldNpgsqlPolygon { get; set; } + public NpgsqlCircle testFieldNpgsqlCircle { get; set; } + public (IPAddress Address, int Subnet) testFieldCidr { get; set; } + public NpgsqlRange testFieldInt4range { get; set; } + public NpgsqlRange testFieldInt8range { get; set; } + public NpgsqlRange testFieldNumrange { get; set; } + public NpgsqlRange testFieldTsrange { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? testFieldDateTimeNullable { get; set; } + + public Guid? testFieldGuidNullable { get; set; } + public NpgsqlPoint? testFieldNpgsqlPointNullable { get; set; } + public NpgsqlLine? testFieldNpgsqlLineNullable { get; set; } + public NpgsqlLSeg? testFieldNpgsqlLSegNullable { get; set; } + public NpgsqlBox? testFieldNpgsqlBoxNullable { get; set; } + public NpgsqlPath? testFieldNpgsqlPathNullable { get; set; } + public NpgsqlPolygon? testFieldNpgsqlPolygonNullable { get; set; } + public NpgsqlCircle? testFieldNpgsqlCircleNullable { get; set; } + public (IPAddress Address, int Subnet)? testFieldCidrNullable { get; set; } + public NpgsqlRange? testFieldInt4rangeNullable { get; set; } + public NpgsqlRange? testFieldInt8rangeNullable { get; set; } + public NpgsqlRange? testFieldNumrangeNullable { get; set; } + public NpgsqlRange? testFieldTsrangeNullable { get; set; } + + public BitArray testFieldBitArray { get; set; } + public IPAddress testFieldInet { get; set; } + public PhysicalAddress testFieldMacaddr { get; set; } + public JToken testFieldJToken { get; set; } + public JObject testFieldJObject { get; set; } + public JArray testFieldJArray { get; set; } + public Dictionary testFieldHStore { get; set; } + public Point testFieldPoint { get; set; } + public LineString testFieldLineString { get; set; } + public Polygon testFieldPolygon { get; set; } + public MultiPoint testFieldMultiPoint { get; set; } + public MultiLineString testFieldMultiLineString { get; set; } + public MultiPolygon testFieldMultiPolygon { get; set; } + public Geometry testFieldGeometry { get; set; } + public GeometryCollection testFieldGeometryCollection { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + + /* array */ + public bool[] testFieldBoolArray { get; set; } + public sbyte[] testFieldSByteArray { get; set; } + public short[] testFieldShortArray { get; set; } + public int[] testFieldIntArray { get; set; } + public long[] testFieldLongArray { get; set; } + public byte[] testFieldByteArray { get; set; } + public ushort[] testFieldUShortArray { get; set; } + public uint[] testFieldUIntArray { get; set; } + public ulong[] testFieldULongArray { get; set; } + public double[] testFieldDoubleArray { get; set; } + public float[] testFieldFloatArray { get; set; } + public decimal[] testFieldDecimalArray { get; set; } + public TimeSpan[] testFieldTimeSpanArray { get; set; } + public DateTime[] testFieldDateTimeArray { get; set; } + public byte[][] testFieldBytesArray { get; set; } + public string[] testFieldStringArray { get; set; } + public Guid[] testFieldGuidArray { get; set; } + public NpgsqlPoint[] testFieldNpgsqlPointArray { get; set; } + public NpgsqlLine[] testFieldNpgsqlLineArray { get; set; } + public NpgsqlLSeg[] testFieldNpgsqlLSegArray { get; set; } + public NpgsqlBox[] testFieldNpgsqlBoxArray { get; set; } + public NpgsqlPath[] testFieldNpgsqlPathArray { get; set; } + public NpgsqlPolygon[] testFieldNpgsqlPolygonArray { get; set; } + public NpgsqlCircle[] testFieldNpgsqlCircleArray { get; set; } + public (IPAddress Address, int Subnet)[] testFieldCidrArray { get; set; } + public NpgsqlRange[] testFieldInt4rangeArray { get; set; } + public NpgsqlRange[] testFieldInt8rangeArray { get; set; } + public NpgsqlRange[] testFieldNumrangeArray { get; set; } + public NpgsqlRange[] testFieldTsrangeArray { get; set; } + + public bool?[] testFieldBoolArrayNullable { get; set; } + public sbyte?[] testFieldSByteArrayNullable { get; set; } + public short?[] testFieldShortArrayNullable { get; set; } + public int?[] testFieldIntArrayNullable { get; set; } + public long?[] testFielLongArrayNullable { get; set; } + public byte?[] testFieldByteArrayNullable { get; set; } + public ushort?[] testFieldUShortArrayNullable { get; set; } + public uint?[] testFieldUIntArrayNullable { get; set; } + public ulong?[] testFieldULongArrayNullable { get; set; } + public double?[] testFieldDoubleArrayNullable { get; set; } + public float?[] testFieldFloatArrayNullable { get; set; } + public decimal?[] testFieldDecimalArrayNullable { get; set; } + public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; } + public DateTime?[] testFieldDateTimeArrayNullable { get; set; } + public Guid?[] testFieldGuidArrayNullable { get; set; } + public NpgsqlPoint?[] testFieldNpgsqlPointArrayNullable { get; set; } + public NpgsqlLine?[] testFieldNpgsqlLineArrayNullable { get; set; } + public NpgsqlLSeg?[] testFieldNpgsqlLSegArrayNullable { get; set; } + public NpgsqlBox?[] testFieldNpgsqlBoxArrayNullable { get; set; } + public NpgsqlPath?[] testFieldNpgsqlPathArrayNullable { get; set; } + public NpgsqlPolygon?[] testFieldNpgsqlPolygonArrayNullable { get; set; } + public NpgsqlCircle?[] testFieldNpgsqlCircleArrayNullable { get; set; } + public (IPAddress Address, int Subnet)?[] testFieldCidrArrayNullable { get; set; } + public NpgsqlRange?[] testFieldInt4rangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldInt8rangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldNumrangeArrayNullable { get; set; } + public NpgsqlRange?[] testFieldTsrangeArrayNullable { get; set; } + + public BitArray[] testFieldBitArrayArray { get; set; } + public IPAddress[] testFieldInetArray { get; set; } + public PhysicalAddress[] testFieldMacaddrArray { get; set; } + public JToken[] testFieldJTokenArray { get; set; } + public JObject[] testFieldJObjectArray { get; set; } + public JArray[] testFieldJArrayArray { get; set; } + public Dictionary[] testFieldHStoreArray { get; set; } + public Point[] testFieldPointArray { get; set; } + public LineString[] testFieldLineStringArray { get; set; } + public Polygon[] testFieldPolygonArray { get; set; } + public MultiPoint[] testFieldMultiPointArray { get; set; } + public MultiLineString[] testFieldMultiLineStringArray { get; set; } + public MultiPolygon[] testFieldMultiPolygonArray { get; set; } + public Geometry[] testFieldGeometryArray { get; set; } + public GeometryCollection[] testFieldGeometryCollectionArray { get; set; } + + public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; } + public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; } + public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; } + public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/g.cs new file mode 100644 index 00000000..6af8b546 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/g.cs @@ -0,0 +1,27 @@ +using Npgsql; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; + +public class g +{ + static Lazy pgsqlLazy = new Lazy(() => + { + NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite(); + return new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") + //.UseConnectionFactory(FreeSql.DataType.PostgreSQL, () => new Npgsql.NpgsqlConnection("Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;")) + .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) + .Build(); + }); + public static IFreeSql pgsql => pgsqlLazy.Value; +} diff --git a/FreeSql.sln b/FreeSql.sln index c27f7820..c84703c1 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -82,6 +82,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "aspnetcore_transaction", "E EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.ShenTong", "Providers\FreeSql.Provider.ShenTong\FreeSql.Provider.ShenTong.csproj", "{938173AF-157F-4040-AED3-171DA1809CAA}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite", "FreeSql.Tests\FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite\FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj", "{330F15A7-5089-456B-B553-A98B14DEB764}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -500,6 +502,18 @@ Global {938173AF-157F-4040-AED3-171DA1809CAA}.Release|x64.Build.0 = Release|Any CPU {938173AF-157F-4040-AED3-171DA1809CAA}.Release|x86.ActiveCfg = Release|Any CPU {938173AF-157F-4040-AED3-171DA1809CAA}.Release|x86.Build.0 = Release|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Debug|Any CPU.Build.0 = Debug|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Debug|x64.ActiveCfg = Debug|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Debug|x64.Build.0 = Debug|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Debug|x86.ActiveCfg = Debug|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Debug|x86.Build.0 = Debug|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Release|Any CPU.ActiveCfg = Release|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Release|Any CPU.Build.0 = Release|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Release|x64.ActiveCfg = Release|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Release|x64.Build.0 = Release|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Release|x86.ActiveCfg = Release|Any CPU + {330F15A7-5089-456B-B553-A98B14DEB764}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 78bf79be..952770d6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -372,12 +372,7 @@ namespace FreeSql.Internal.CommonProvider if (whereExp == null) { tbref = tb.GetTableRef(collMem.Member.Name, true); - if (tbref == null) - { - tb = _commonUtils.GetTableByEntity(collMem.Expression.Type); //debug https://github.com/dotnetcore/FreeSql/issues/367 - tbref = tb.GetTableRef(collMem.Member.Name, true); - if (tbref == null) throw new Exception($"IncludeMany 类型 {tb.Type.DisplayCsharp()} 的属性 {collMem.Member.Name} 不是有效的导航属性,提示:IsIgnore = true 不会成为导航属性"); - } + if (tbref == null) throw new Exception($"IncludeMany 类型 {tb.Type.DisplayCsharp()} 的属性 {collMem.Member.Name} 不是有效的导航属性,提示:IsIgnore = true 不会成为导航属性"); } else { diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 84ba2ae4..5ac3581a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -31,6 +31,7 @@ + @@ -41,6 +42,10 @@ net45 + + nts + + diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index e62d578d..c7834ba8 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -70,6 +70,7 @@ namespace FreeSql.PostgreSQL { typeof(NpgsqlRange).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false, NpgsqlRange.Empty) },{ typeof(NpgsqlRange?).FullName, CsToDb.New(NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange", false, true, null) }, { typeof(Dictionary).FullName, CsToDb.New(NpgsqlDbType.Hstore, "hstore", "hstore", false, null, new Dictionary()) }, + { typeof(PostgisPoint).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, { typeof(PostgisLineString).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) }, { typeof(PostgisPolygon).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } })) }, @@ -78,7 +79,18 @@ namespace FreeSql.PostgreSQL { typeof(PostgisMultiPolygon).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPolygon(new[]{new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }),new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }) })) }, { typeof(PostgisGeometry).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) }, { typeof(PostgisGeometryCollection).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisGeometryCollection(new[]{new PostgisPoint(0, 0),new PostgisPoint(0, 0) })) }, - }; + +#if nts + { typeof(NetTopologySuite.Geometries.Point).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new NetTopologySuite.Geometries.Point(0, 0)) }, + { typeof(NetTopologySuite.Geometries.LineString).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new NetTopologySuite.Geometries.LineString(new []{new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0) })) }, + { typeof(NetTopologySuite.Geometries.Polygon).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new NetTopologySuite.Geometries.Polygon(new NetTopologySuite.Geometries.LinearRing(new []{ new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0), new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0) }))) }, + { typeof(NetTopologySuite.Geometries.MultiPoint).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new NetTopologySuite.Geometries.MultiPoint(new []{new NetTopologySuite.Geometries.Point(0, 0),new NetTopologySuite.Geometries.Point(0, 0) })) }, + { typeof(NetTopologySuite.Geometries.MultiLineString).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new NetTopologySuite.Geometries.MultiLineString(new[]{new NetTopologySuite.Geometries.LineString(new []{new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0) }),new NetTopologySuite.Geometries.LineString(new []{new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0) }) })) }, + { typeof(NetTopologySuite.Geometries.MultiPolygon).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new NetTopologySuite.Geometries.MultiPolygon(new[]{new NetTopologySuite.Geometries.Polygon(new NetTopologySuite.Geometries.LinearRing(new []{ new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0), new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0) })), new NetTopologySuite.Geometries.Polygon(new NetTopologySuite.Geometries.LinearRing(new []{ new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0), new NetTopologySuite.Geometries.Coordinate(0, 0),new NetTopologySuite.Geometries.Coordinate(0, 0) })) })) }, + { typeof(NetTopologySuite.Geometries.Geometry).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new NetTopologySuite.Geometries.Point(0, 0)) }, + { typeof(NetTopologySuite.Geometries.GeometryCollection).FullName, CsToDb.New(NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new NetTopologySuite.Geometries.GeometryCollection(new[]{new NetTopologySuite.Geometries.Point(0, 0),new NetTopologySuite.Geometries.Point(0, 0) })) }, +#endif + }; public override DbInfoResult GetDbInfo(Type type) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index 839b9421..63f00d91 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -37,6 +37,7 @@ namespace FreeSql.PostgreSQL Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPoint)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisLineString)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPolygon)] = true; @@ -45,6 +46,18 @@ namespace FreeSql.PostgreSQL Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPolygon)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometry)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometryCollection)] = true; + +#if nts + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Point)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.LineString)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Polygon)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiPoint)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiLineString)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiPolygon)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Geometry)] = true; + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.GeometryCollection)] = true; +#endif + Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Dictionary)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JToken)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JObject)] = true; @@ -61,6 +74,7 @@ namespace FreeSql.PostgreSQL case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject))); case "Newtonsoft.Json.Linq.JArray": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray))); case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Return(returnTarget, valueExp); + case "NetTopologySuite.Geometries.Geometry": return Expression.Return(returnTarget, valueExp); } return null; }); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index cf1b6baf..ed6cb447 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -44,19 +44,28 @@ namespace FreeSql.PostgreSQL { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(NpgsqlPath).FullName, a => { var path = (NpgsqlPath)a; try { int count = path.Count; return path; } catch { return new NpgsqlPath(new NpgsqlPoint(0, 0)); } - } }, { typeof(NpgsqlPath[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPath), a, new NpgsqlPath(new NpgsqlPoint(0, 0))) }, { typeof(NpgsqlPath?[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPath?), a, null) }, + } }, + { typeof(NpgsqlPath[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPath), a, new NpgsqlPath(new NpgsqlPoint(0, 0))) }, + { typeof(NpgsqlPath?[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPath?), a, null) }, + { typeof(NpgsqlPolygon).FullName, a => { var polygon = (NpgsqlPolygon)a; try { int count = polygon.Count; return polygon; } catch { return new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0)); } - } }, { typeof(NpgsqlPolygon[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPolygon), a, new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0))) }, { typeof(NpgsqlPolygon?[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPolygon?), a, null) }, + } }, + { typeof(NpgsqlPolygon[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPolygon), a, new NpgsqlPolygon(new NpgsqlPoint(0, 0), new NpgsqlPoint(0, 0))) }, + { typeof(NpgsqlPolygon?[]).FullName, a => getParamterArrayValue(typeof(NpgsqlPolygon?), a, null) }, + { typeof((IPAddress Address, int Subnet)).FullName, a => { var inet = ((IPAddress Address, int Subnet))a; if (inet.Address == null) return (IPAddress.Any, inet.Subnet); return inet; - } }, { typeof((IPAddress Address, int Subnet)[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)), a, (IPAddress.Any, 0)) }, { typeof((IPAddress Address, int Subnet)?[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)?), a, null) }, + } }, + { typeof((IPAddress Address, int Subnet)[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)), a, (IPAddress.Any, 0)) }, + { typeof((IPAddress Address, int Subnet)?[]).FullName, a => getParamterArrayValue(typeof((IPAddress Address, int Subnet)?), a, null) }, }; static object getParamterValue(Type type, object value, int level = 0) { @@ -156,7 +165,16 @@ namespace FreeSql.PostgreSQL { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); - if (_dicIsAssignableFromPostgisGeometry.GetOrAdd(type, t2 => typeof(PostgisGeometry).IsAssignableFrom(type.IsArray ? type.GetElementType() : type))) + if (_dicIsAssignableFromPostgisGeometry.GetOrAdd(type, t2 => + { + var t2type = t2.IsArray ? t2.GetElementType() : t2; + return typeof(PostgisGeometry).IsAssignableFrom(t2type) + #if nts + || + typeof(NetTopologySuite.Geometries.Geometry).IsAssignableFrom(t2type) + #endif + ; + })) { var pam = AppendParamter(specialParams, null, null, type, value); return pam.ParameterName; From 4447500d574df2a9bb170df1a98e93b46249d100 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 12 Jul 2020 20:49:40 +0800 Subject: [PATCH 0739/1029] v1.7.0-preview0712 #369 #366 #365 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 571ca7d6..70ebee4f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 6d6a02e5..ebb90921 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b051df49..b12c9cd2 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 0a3cd1aa..81bd5c24 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 5f23b2e1..de537bab 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0705 + 1.7.0-preview0712 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index b4261eef..2c05d285 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 7ee93182..1fda78b4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index af1b4df8..e931cd18 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3f47957d..7d0c1259 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index afe89161..aa50be02 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 9bdf462c..898cb10f 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5dba344b..7c498ea9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a4584ee3..8060ac7d 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index cd58ba55..c81f92e7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 621e27c3..74b2d650 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 5ac3581a..bd560571 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 5bd2117f..fe93dd90 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 918945cb..44d510df 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 12250752..fac18527 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0705 + 1.7.0-preview0712 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From f93e0f1b5482108521b96e4e09ebe352b2ac700e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 13 Jul 2020 18:12:06 +0800 Subject: [PATCH 0740/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20WhereDynamic?= =?UTF-8?q?Filter=20=E5=9C=A8=20System.Text.Json=20=E4=B8=8B=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20#371=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 68 ++++++++++++++++++- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 6 ++ .../SelectProvider/Select0Provider.cs | 12 ++-- 4 files changed, 78 insertions(+), 17 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 9d674f29..a6a50839 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -7,8 +7,12 @@ using Newtonsoft.Json.Linq; using System; using System.Data.Odbc; using System.Data.SqlClient; +using System.Data.SQLite; using System.Diagnostics; using System.Linq.Expressions; +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; @@ -40,8 +44,23 @@ namespace base_entity static AsyncLocal _asyncUow = new AsyncLocal(); + public class TestEnumCls + { + public CollationTypeEnum val { get; set; } = CollationTypeEnum.Binary; + } + static void Main(string[] args) { +// var result2 = Newtonsoft.Json.JsonConvert.DeserializeObject(@" +//{ +// ""val"": ""Binary"" +//}"); +// var result1 = System.Text.Json.JsonSerializer.Deserialize(@" +//{ +// ""val"": ""Binary"" +//}"); + + #region 初始化 IFreeSql var fsql = new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) @@ -90,7 +109,7 @@ namespace base_entity new Products { title = "product-4" }.Save(); new Products { title = "product-5" }.Save(); - Products.Select.WhereDynamicFilter(JsonConvert.DeserializeObject(@" + var wdy1 = JsonConvert.DeserializeObject(@" { ""Logic"" : ""Or"", ""Filters"" : @@ -125,7 +144,52 @@ namespace base_entity }, ] } -")).ToList(); +"); + var config = new JsonSerializerOptions() + { + PropertyNamingPolicy = null, + AllowTrailingCommas = true, + IgnoreNullValues = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + Converters = { new JsonStringEnumConverter() } + }; + var wdy2 = System.Text.Json.JsonSerializer.Deserialize(@" +{ + ""Logic"" : 1, + ""Filters"" : + [ + { + ""Field"" : ""title"", + ""Operator"" : 8, + ""Value"" : ""product-1"", + ""Filters"" : + [ + { + ""Field"" : ""title"", + ""Operator"" : 0, + ""Value"" : ""product-1111"" + } + ] + }, + { + ""Field"" : ""title"", + ""Operator"" : 8, + ""Value"" : ""product-2"" + }, + { + ""Field"" : ""title"", + ""Operator"" : 8, + ""Value"" : ""product-3"" + }, + { + ""Field"" : ""title"", + ""Operator"" : 8, + ""Value"" : ""product-4"" + } + ] +} +", config); + Products.Select.WhereDynamicFilter(wdy2).ToList(); var items1 = Products.Select.Limit(10).OrderByDescending(a => a.CreateTime).ToList(); var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,14 +486,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index e2b66169..0ee3d1bb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -175,6 +175,12 @@ namespace FreeSql.Tests .Page(1, 10).ToSql("Id"); + var sqlextMax1 = g.mysql.Select() + .GroupBy(a => a.Id) + .ToSql(a => new + { + Id = a.Key, EdiId = SqlExt.Max(a.Key).Over().ToValue() + }); var sqlextGroupConcat = g.mysql.Select() .InnerJoin((a, b) => b.Id == a.Id) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index dd0f788b..62e2d64d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1086,12 +1086,12 @@ namespace FreeSql.Internal.CommonProvider switch (fi.Operator) { - case DynamicFilterOperator.Contains: exp = Expression.Call(exp, MethodStringContains, Expression.Constant(fi.Value)); break; - case DynamicFilterOperator.StartsWith: exp = Expression.Call(exp, MethodStringStartsWith, Expression.Constant(fi.Value)); break; - case DynamicFilterOperator.EndsWith: exp = Expression.Call(exp, MethodStringEndsWith, Expression.Constant(fi.Value)); break; - case DynamicFilterOperator.NotContains: exp = Expression.Not(Expression.Call(exp, MethodStringContains, Expression.Constant(fi.Value))); break; - case DynamicFilterOperator.NotStartsWith: exp = Expression.Not(Expression.Call(exp, MethodStringStartsWith, Expression.Constant(fi.Value))); break; - case DynamicFilterOperator.NotEndsWith: exp = Expression.Not(Expression.Call(exp, MethodStringEndsWith, Expression.Constant(fi.Value))); break; + case DynamicFilterOperator.Contains: exp = Expression.Call(exp, MethodStringContains, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.StartsWith: exp = Expression.Call(exp, MethodStringStartsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.EndsWith: exp = Expression.Call(exp, MethodStringEndsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.NotContains: exp = Expression.Not(Expression.Call(exp, MethodStringContains, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type))); break; + case DynamicFilterOperator.NotStartsWith: exp = Expression.Not(Expression.Call(exp, MethodStringStartsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type))); break; + case DynamicFilterOperator.NotEndsWith: exp = Expression.Not(Expression.Call(exp, MethodStringEndsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type))); break; case DynamicFilterOperator.Eq: case DynamicFilterOperator.Equals: From e466ca30986fe949fe4d65811a20f12ac1f1af1f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 13 Jul 2020 18:14:40 +0800 Subject: [PATCH 0741/1029] v1.7.0-preview0713 #371 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 19 insertions(+), 26 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 70ebee4f..1ce357ef 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ebb90921..fd1ca3ac 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b12c9cd2..6d42ef87 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 81bd5c24..c8658fb3 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index de537bab..9cd441d6 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0712 + 1.7.0-preview0713 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 2c05d285..091a6afc 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 1fda78b4..6b3a24bd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..132d875e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e931cd18..394504f7 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7d0c1259..6e862dd3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index aa50be02..0948e550 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 898cb10f..528fdc3c 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 7c498ea9..cfd531ee 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8060ac7d..f79d43a7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c81f92e7..108cf448 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 74b2d650..c873c96d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index bd560571..23be8eb3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index fe93dd90..a26647a2 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 44d510df..fb737473 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fac18527..50a3e120 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0712 + 1.7.0-preview0713 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 309f70f02f0e19f35cd8f19511cb8d538353232d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 14 Jul 2020 00:09:06 +0800 Subject: [PATCH 0742/1029] update summary --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql/FreeSql.xml | 14 +++++++++----- FreeSql/FreeSqlBuilder.cs | 5 +++-- FreeSql/Interface/ICodeFirst.cs | 9 ++++++--- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c70e644b..e0ffd602 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -803,9 +803,10 @@ - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + 注意:生产环境中谨慎使用 - true:运行时检查自动同步结构, false:不同步结构 + true:运行时检查自动同步结构, false:不同步结构(默认) @@ -2961,19 +2962,22 @@ - 同步实体类型到数据库 + 同步实体类型到数据库 + 注意:生产环境中谨慎使用 - 同步实体类型集合到数据库 + 同步实体类型集合到数据库 + 注意:生产环境中谨慎使用 - 同步实体类型到数据库(指定表名) + 同步实体类型到数据库(指定表名) + 注意:生产环境中谨慎使用 实体类型 指定表名对比 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index f5e63e37..adb6298b 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -72,9 +72,10 @@ namespace FreeSql return this; } /// - /// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + /// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + /// 注意:生产环境中谨慎使用 /// - /// true:运行时检查自动同步结构, false:不同步结构 + /// true:运行时检查自动同步结构, false:不同步结构(默认) /// public FreeSqlBuilder UseAutoSyncStructure(bool value) { diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index e316be66..02393445 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -63,17 +63,20 @@ namespace FreeSql /// string GetComparisonDDLStatements(Type entityType, string tableName); /// - /// 同步实体类型到数据库 + /// 同步实体类型到数据库 + /// 注意:生产环境中谨慎使用 /// /// void SyncStructure(); /// - /// 同步实体类型集合到数据库 + /// 同步实体类型集合到数据库 + /// 注意:生产环境中谨慎使用 /// /// void SyncStructure(params Type[] entityTypes); /// - /// 同步实体类型到数据库(指定表名) + /// 同步实体类型到数据库(指定表名) + /// 注意:生产环境中谨慎使用 /// /// 实体类型 /// 指定表名对比 From 0c4939057eace04d6e50b80ab969cf424fbb5222 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Tue, 14 Jul 2020 19:46:18 +0800 Subject: [PATCH 0743/1029] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index d2fee9ab..be745985 100644 --- a/readme.md +++ b/readme.md @@ -185,7 +185,7 @@ constantine ## 💕  Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元 > Thank you for your donation From 58240836bf2b9d2c1b79b352af8266a3674e3f66 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 15 Jul 2020 11:49:36 +0800 Subject: [PATCH 0744/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20Ado.ExecuteD?= =?UTF-8?q?ataTable=20Columns=20=E5=8C=85=E5=90=AB=20DataType=20=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 1 + .../MySqlConnector/MySqlCodeFirstTest.cs | 1 + .../FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs | 1 + .../FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs | 1 + .../KingbaseES/KingbaseESCodeFirstTest.cs | 1 + .../FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs | 1 + .../FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs | 1 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 1 + .../SqlServer/SqlServerCodeFirstTest.cs | 1 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 1 + FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs | 1 + FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs | 1 + FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 1 + FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs | 1 + .../FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs | 1 + FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs | 1 + .../FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs | 1 + FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs | 1 + FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs | 4 ++-- .../Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs | 4 ++-- 20 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index a6a50839..311f0383 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -205,6 +205,7 @@ namespace base_entity new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); var testconfigs11 = S_SysConfig.Select.ToList(); + var testconfigs11tb = S_SysConfig.Select.ToDataTable(); var testconfigs111 = S_SysConfig.Select.ToList(a => a.Name); var testconfigs112 = S_SysConfig.Select.ToList(a => a.Config); var testconfigs1122 = S_SysConfig.Select.ToList(a => new { a.Name, a.Config }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 00410106..98cec1d3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -417,6 +417,7 @@ namespace FreeSql.Tests.MySqlConnector Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index 319fdfbf..be8559fe 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -295,6 +295,7 @@ namespace FreeSql.Tests.Odbc.Dameng Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs index ed20c3ba..f58d1305 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs @@ -123,6 +123,7 @@ namespace FreeSql.Tests.Odbc.Default Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype_notime")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs index 68194038..271a76bf 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs @@ -270,6 +270,7 @@ namespace FreeSql.Tests.Odbc.KingbaseES Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index efa92779..43176a37 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -271,6 +271,7 @@ namespace FreeSql.Tests.Odbc.MySql Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs index a9e24fc5..95cd2720 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -294,6 +294,7 @@ namespace FreeSql.Tests.Odbc.Oracle Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs index 9b8e95e7..d46ae080 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -208,6 +208,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index 2642bf0c..48bfefbd 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -240,6 +240,7 @@ namespace FreeSql.Tests.Odbc.SqlServer Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [JsonObject(MemberSerialization.OptIn), Table(Name = "dbo.tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs index 5d0b0a30..59fa573c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -268,6 +268,7 @@ namespace FreeSql.Tests.PostgreSQL.NetTopologySuite Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype_nts")] diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs index 94af3999..4369ea87 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs @@ -361,6 +361,7 @@ namespace FreeSql.Tests.Dameng Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs index e11d0b2b..5c2dc9c0 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -286,6 +286,7 @@ namespace FreeSql.Tests.MsAccess Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 58274df0..346a806c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -422,6 +422,7 @@ namespace FreeSql.Tests.MySql Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index cf5e4834..7e334513 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -395,6 +395,7 @@ namespace FreeSql.Tests.Oracle Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index b96b1eec..094a3afa 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -426,6 +426,7 @@ namespace FreeSql.Tests.PostgreSQL Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs index 8031a61f..6c6f93d5 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs @@ -251,6 +251,7 @@ namespace FreeSql.Tests.ShenTong Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index c32f9287..20723d8b 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -276,6 +276,7 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(item2.testFieldString, newitem2.testFieldString); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [JsonObject(MemberSerialization.OptIn), Table(Name = "dbo.tb_alltype")] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index 65c62fc1..d3634ce2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -347,6 +347,7 @@ namespace FreeSql.Tests.Sqlite Assert.Equal(item2.String, newitem2.String); var items = select.ToList(); + var itemstb = select.ToDataTable(); } [Table(Name = "tb_alltype")] diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 0612f43d..8d1d81d7 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -675,7 +675,7 @@ namespace FreeSql.Internal.CommonProvider { var name = dr.GetName(a); if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - dt.Columns.Add(name); + dt.Columns.Add(name, dr.GetFieldType(a)); } } object[] values = new object[dt.Columns.Count]; @@ -699,7 +699,7 @@ namespace FreeSql.Internal.CommonProvider { var name = dr.GetName(a); if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - ret.Columns.Add(name); + ret.Columns.Add(name, dr.GetFieldType(a)); } object[] values = new object[ret.Columns.Count]; dr.GetValues(values); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 8254462b..92e873e3 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -598,7 +598,7 @@ namespace FreeSql.Internal.CommonProvider { var name = dr.GetName(a); if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - dt.Columns.Add(name); + dt.Columns.Add(name, dr.GetFieldType(a)); } } object[] values = new object[dt.Columns.Count]; @@ -622,7 +622,7 @@ namespace FreeSql.Internal.CommonProvider { var name = dr.GetName(a); if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - ret.Columns.Add(name); + ret.Columns.Add(name, dr.GetFieldType(a)); } object[] values = new object[ret.Columns.Count]; for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); From a0d37533c32128fb334e7b0aabdc30705bb4c9a8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 15 Jul 2020 11:53:48 +0800 Subject: [PATCH 0745/1029] v1.7.0-preview0715 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 -- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 143 ------------------ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 19 insertions(+), 178 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1ce357ef..04ccca30 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index fd1ca3ac..bc62e35c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6d42ef87..7ed0d9fd 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index c8658fb3..6c717a8c 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 9cd441d6..bf57ce04 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0713 + 1.7.0-preview0715 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 091a6afc..53eeafd2 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6b3a24bd..1d303e66 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access 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.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 394504f7..635ca5fa 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 6e862dd3..9dfb5163 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e0ffd602..c4545e99 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2511,137 +2511,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3291,12 +3160,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3367,12 +3230,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 0948e550..226b115d 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 528fdc3c..a0516426 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index cfd531ee..ad53ef74 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f79d43a7..433b3a8f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 108cf448..0163e21e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index c873c96d..79c62adc 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 23be8eb3..3c0bb16a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index a26647a2..5902e2dc 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index fb737473..7dcf504a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 50a3e120..6639057b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0713 + 1.7.0-preview0715 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From c9c91590a15bfe14a40b24d4302d1a2bb9f025b4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Jul 2020 09:36:34 +0800 Subject: [PATCH 0746/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20BaseReposito?= =?UTF-8?q?ry=20Delete=20=E6=96=B9=E6=B3=95=E6=9C=AA=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=BD=B1=E5=93=8D=E7=9A=84=E8=A1=8C=E5=80=BC?= =?UTF-8?q?=20#373=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetAsync.cs | 2 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index a88e711e..aefaa719 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -424,7 +424,7 @@ namespace FreeSql if (dels.Any() == false) return 0; var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); - return Math.Max(dels.Length, affrows); + return affrows; } /// /// 根据 lambda 条件删除数据 diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 343ea58b..d2a83da7 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -465,7 +465,7 @@ namespace FreeSql if (dels.Any() == false) return 0; var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); - return Math.Max(dels.Length, affrows); + return affrows; //https://github.com/dotnetcore/FreeSql/issues/373 } /// diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 0ee3d1bb..44d9bd13 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -159,6 +159,11 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var aff1 = g.sqlite.GetRepository().Delete(10086); + var aff2 = g.sqlite.Delete(10086).ExecuteAffrows(); + Assert.Equal(aff1, aff2); + + var testStringFormat = g.sqlite.Select().First(a => new { str = $"x{a.Id}_{DateTime.Now.ToString("yyyyMM")}z", str2 = string.Format("{0}x{0}_{1}z", a.Id, DateTime.Now.ToString("yyyyMM")) From d103dc7edf65a4e493e813c792c9ca2213a7e941 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Jul 2020 10:50:01 +0800 Subject: [PATCH 0747/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20EFCore=20Str?= =?UTF-8?q?ingLengthAttribute=20=E7=89=B9=E6=80=A7=E7=9A=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataAnnotations/EFCoreAttributeTest.cs | 3 + FreeSql/FreeSql.xml | 143 ++++++++++++++++++ FreeSql/FreeSqlBuilder.cs | 14 ++ 3 files changed, 160 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs index f3dd26ae..b3868ad2 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs @@ -33,12 +33,15 @@ namespace FreeSql.Tests.DataAnnotations { fsql.CodeFirst.SyncStructure(); Assert.Equal("NVARCHAR(100)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb03)).ColumnsByCs["title"].Attribute.DbType); + Assert.Equal("NVARCHAR(101)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb03)).ColumnsByCs["title2"].Attribute.DbType); } class eftesttb03 { public Guid id { get; set; } [System.ComponentModel.DataAnnotations.MaxLength(100)] public string title { get; set; } + [System.ComponentModel.DataAnnotations.StringLength(101)] + public string title2 { get; set; } } [Fact] diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c4545e99..e0ffd602 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2511,6 +2511,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 }) + + + + + + 可自定义解析表达式 @@ -3160,6 +3291,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3230,6 +3367,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index adb6298b..5f7b6056 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -326,6 +326,20 @@ namespace FreeSql } } + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.Name == "StringLengthAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + var lenProps = dyattr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).ToArray(); + var lenProp = lenProps.Length == 1 ? lenProps.FirstOrDefault() : lenProps.Where(a => a.Name == "MaximumLength").FirstOrDefault(); + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(dyattr, null)), out var tryval) && tryval != 0) + { + e.ModifyResult.StringLength = tryval; + } + } + + dyattr = attrs?.Where(a => { return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.RequiredAttribute"; }).FirstOrDefault(); From facfafa9ef4f0dc164b90638abc6537b43cf7abe Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Jul 2020 18:02:24 +0800 Subject: [PATCH 0748/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20EFCore=20Dat?= =?UTF-8?q?abaseGeneratedAttribute=20=E7=89=B9=E6=80=A7=E7=9A=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20#378=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataAnnotations/EFCoreAttributeTest.cs | 30 +- FreeSql/FreeSql.xml | 312 ++++++++++-------- FreeSql/FreeSqlBuilder.cs | 46 ++- 3 files changed, 230 insertions(+), 158 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs index b3868ad2..c1e549ac 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs @@ -33,13 +33,23 @@ namespace FreeSql.Tests.DataAnnotations { fsql.CodeFirst.SyncStructure(); Assert.Equal("NVARCHAR(100)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb03)).ColumnsByCs["title"].Attribute.DbType); - Assert.Equal("NVARCHAR(101)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb03)).ColumnsByCs["title2"].Attribute.DbType); } class eftesttb03 { public Guid id { get; set; } [System.ComponentModel.DataAnnotations.MaxLength(100)] public string title { get; set; } + } + + [Fact] + public void StringLengthAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.Equal("NVARCHAR(101)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb033)).ColumnsByCs["title2"].Attribute.DbType); + } + class eftesttb033 + { + public Guid id { get; set; } [System.ComponentModel.DataAnnotations.StringLength(101)] public string title2 { get; set; } } @@ -109,5 +119,23 @@ namespace FreeSql.Tests.DataAnnotations [System.ComponentModel.DataAnnotations.Key] public string title { get; set; } } + + [Fact] + public void DatabaseGeneratedAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.True(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb08)).ColumnsByCs["id"].Attribute.IsPrimary); + Assert.True(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb08)).ColumnsByCs["id"].Attribute.IsIdentity); + Assert.False(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb08)).ColumnsByCs["createtime"].Attribute.CanInsert); + Assert.False(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb08)).ColumnsByCs["createtime"].Attribute.CanUpdate); + } + class eftesttb08 + { + [System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)] + public int id { get; set; } + public string title { get; set; } + [System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed)] + public string createtime { get; set; } + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e0ffd602..90034009 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2511,137 +2511,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3291,12 +3160,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3367,12 +3230,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4028,3 +3885,172 @@ +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 条件 + + + + diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 5f7b6056..e4ff315f 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -326,20 +326,6 @@ namespace FreeSql } } - dyattr = attrs?.Where(a => { - return ((a as Attribute)?.TypeId as Type)?.Name == "StringLengthAttribute"; - }).FirstOrDefault(); - if (dyattr != null) - { - var lenProps = dyattr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).ToArray(); - var lenProp = lenProps.Length == 1 ? lenProps.FirstOrDefault() : lenProps.Where(a => a.Name == "MaximumLength").FirstOrDefault(); - if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(dyattr, null)), out var tryval) && tryval != 0) - { - e.ModifyResult.StringLength = tryval; - } - } - - dyattr = attrs?.Where(a => { return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.RequiredAttribute"; }).FirstOrDefault(); @@ -380,6 +366,38 @@ namespace FreeSql { e.ModifyResult.IsPrimary = true; } + + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.StringLengthAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + var lenProps = dyattr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).ToArray(); + var lenProp = lenProps.Length == 1 ? lenProps.FirstOrDefault() : lenProps.Where(a => a.Name == "MaximumLength").FirstOrDefault(); + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(dyattr, null)), out var tryval) && tryval != 0) + { + e.ModifyResult.StringLength = tryval; + } + } + + //https://github.com/dotnetcore/FreeSql/issues/378 + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + switch(string.Concat(dyattr.GetType().GetProperty("DatabaseGeneratedOption")?.GetValue(dyattr, null))) + { + case "Identity": + case "1": + e.ModifyResult.IsIdentity = true; + break; + default: + e.ModifyResult.CanInsert = false; + e.ModifyResult.CanUpdate = false; + break; + } + } }); //EFCore 特性 ret.Aop.ConfigEntity += new EventHandler((s, e) => From 9cd3d99812dbba0f44f0b4b6e7c08fc14c18dbf3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Jul 2020 18:13:49 +0800 Subject: [PATCH 0749/1029] =?UTF-8?q?-=20=E9=98=B2=E6=AD=A2=20Object=20?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E4=B9=9F=E6=89=A7=E8=A1=8C=E8=BF=81=E7=A7=BB?= =?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 + .../SqlServer/Curd/SqlServerSelectTest.cs | 6 + FreeSql/FreeSql.xml | 312 ++++++++---------- .../CommonProvider/CodeFirstProvider.cs | 2 +- 4 files changed, 166 insertions(+), 170 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 48d87b2c..2e82786a 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using FreeSql.Tests.DataContext.SqlServer; +using NetTaste; using System; using System.Collections.Generic; using System.Linq; @@ -1049,6 +1050,11 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] a.Id, a.Clicks }); + + var testUnionAll2 = g.sqlite.Select() + .WithSql("SELECT * FROM [tb_topic22] where id = 10") + .WithSql("SELECT * FROM [tb_topic22] where id = 11") + .ToDataTable("*"); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 90034009..e0ffd602 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2511,6 +2511,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 }) + + + + + + 可自定义解析表达式 @@ -3160,6 +3291,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3230,6 +3367,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3885,172 +4028,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 条件 - - - - diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index c9350e78..e2e4cdad 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -90,7 +90,7 @@ namespace FreeSql.Internal.CommonProvider protected void SyncStructure(params TypeAndName[] objects) { if (objects == null) return; - var syncObjects = objects.Where(a => _dicSycedGetOrAdd(a.entityType).ContainsKey(GetTableNameLowerOrUpper(a.tableName)) == false && GetTableByEntity(a.entityType)?.DisableSyncStructure == false) + var syncObjects = objects.Where(a => a.entityType != typeof(object) && _dicSycedGetOrAdd(a.entityType).ContainsKey(GetTableNameLowerOrUpper(a.tableName)) == false && GetTableByEntity(a.entityType)?.DisableSyncStructure == false) .Select(a => new TypeAndName(a.entityType, GetTableNameLowerOrUpper(a.tableName))).ToArray(); if (syncObjects.Any() == false) return; var before = new Aop.SyncStructureBeforeEventArgs(syncObjects.Select(a => a.entityType).ToArray()); From ba38d25a9b22e6a6c79a2482ed7d7caa0bd21d23 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Jul 2020 18:25:50 +0800 Subject: [PATCH 0750/1029] v1.7.0-preview0716 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 04ccca30..504d34a4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index bc62e35c..39eb95d0 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7ed0d9fd..bacc6b63 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 6c717a8c..8fdce8d2 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index bf57ce04..cf170247 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0715 + 1.7.0-preview0716 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 53eeafd2..3bc0524c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 1d303e66..4e2af9c7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 635ca5fa..5a3954a4 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9dfb5163..1c0870b6 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 226b115d..c560d269 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index a0516426..af3565ad 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index ad53ef74..6fc45db9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 433b3a8f..f0e67c02 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0163e21e..5b5060e5 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 79c62adc..d528b6db 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 3c0bb16a..35191e91 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 5902e2dc..7918bce6 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 7dcf504a..edbb0f76 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 6639057b..9aa0a038 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0715 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 76e1db3778dadc3257c139af2b36809b635c9c81 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Jul 2020 18:27:06 +0800 Subject: [PATCH 0751/1029] v1.7.0-preview0716 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 504d34a4..f38b02f3 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 39eb95d0..13767667 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index bacc6b63..966a0d30 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 8fdce8d2..14cac809 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index cf170247..94754bcb 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0716 + 1.7.0-preview0716 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3bc0524c..1e923884 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4e2af9c7..2c0f406c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5a3954a4..c16b8c27 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1c0870b6..2415e31f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index c560d269..db1147bb 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index af3565ad..100432e9 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6fc45db9..3863f0d5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f0e67c02..536f8ec9 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 5b5060e5..e7ac08db 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d528b6db..8cc31846 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 35191e91..dd7af705 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 7918bce6..b74404cb 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index edbb0f76..1e8b83be 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9aa0a038..a69d59dd 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From a67e6a8cb58541d7ff957b37d0a8195a611f0007 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Jul 2020 18:27:44 +0800 Subject: [PATCH 0752/1029] 1.7.0-preview0716 #378 #373 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f38b02f3..504d34a4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 13767667..39eb95d0 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 966a0d30..bacc6b63 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 14cac809..8fdce8d2 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 94754bcb..cf170247 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0716 + 1.7.0-preview0716 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 1e923884..3bc0524c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2c0f406c..4e2af9c7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c16b8c27..5a3954a4 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2415e31f..1c0870b6 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index db1147bb..c560d269 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 100432e9..af3565ad 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3863f0d5..6fc45db9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 536f8ec9..f0e67c02 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e7ac08db..5b5060e5 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8cc31846..d528b6db 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index dd7af705..35191e91 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index b74404cb..7918bce6 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 1e8b83be..edbb0f76 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a69d59dd..9aa0a038 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0716 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From e616f8e4a6cd6deee9fc52face4d7cb3e93695e8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 17 Jul 2020 18:20:06 +0800 Subject: [PATCH 0753/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Exte?= =?UTF-8?q?nsions.Linq=20ThenBy/ThenByDescending=20=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E6=96=B9=E6=B3=95=20#380=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.Linq.xml | 10 ++++ .../FreeSqlExtensionsLinq.cs | 9 +++ FreeSql.DbContext/FreeSql.DbContext.xml | 16 ----- .../Linq/ISelectLinqToSqlTests.cs | 58 +++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 18 ++++-- 5 files changed, 91 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml index f5004a0a..0b221156 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.xml @@ -47,5 +47,15 @@ 【linq to sql】专用扩展方法,不建议直接使用 + + + 【linq to sql】专用扩展方法,不建议直接使用 + + + + + 【linq to sql】专用扩展方法,不建议直接使用 + + diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs b/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs index 5df25a29..92d9aefa 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs +++ b/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs @@ -141,4 +141,13 @@ public static class FreeSqlExtensionsLinqSql { return that; } + + /// + /// 【linq to sql】专用扩展方法,不建议直接使用 + /// + public static ISelect ThenBy(this ISelect that, Expression> column) where T1 : class => that.OrderBy(column); + /// + /// 【linq to sql】专用扩展方法,不建议直接使用 + /// + public static ISelect ThenByDescending(this ISelect that, Expression> column) where T1 : class => that.OrderByDescending(column); } 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/Linq/ISelectLinqToSqlTests.cs b/FreeSql.Tests/FreeSql.Tests/Linq/ISelectLinqToSqlTests.cs index 584b94c3..6caafb05 100644 --- a/FreeSql.Tests/FreeSql.Tests/Linq/ISelectLinqToSqlTests.cs +++ b/FreeSql.Tests/FreeSql.Tests/Linq/ISelectLinqToSqlTests.cs @@ -43,6 +43,63 @@ namespace FreeSql.Tests.Linq Assert.Equal(item.id, t1[0].id); } + [Fact] + public void OrderBy() + { + var item = new TestLinqToSql { name = Guid.NewGuid().ToString() }; + g.sqlite.Insert().AppendData(item).ExecuteAffrows(); + + var t1 = (from a in g.sqlite.Select() + where a.id == item.id + orderby a.id + select a).ToList(); + Assert.True(t1.Any()); + Assert.Equal(item.id, t1[0].id); + + Assert.Equal((from a in g.sqlite.Select() + where a.id == item.id + orderby a.id + select a).ToSql(), + (from a in g.sqlite.Select() + where a.id == item.id + orderby a.id ascending + select a).ToSql()); + + Assert.Equal((from a in g.sqlite.Select() + where a.id == item.id + orderby a.id ascending + select a).ToSql(), + g.sqlite.Select().Where(a => a.id == item.id).OrderBy(a => a.id).ToSql()); + + Assert.Equal((from a in g.sqlite.Select() + where a.id == item.id + orderby a.id descending + select a).ToSql(), + g.sqlite.Select().Where(a => a.id == item.id).OrderByDescending(a => a.id).ToSql()); + + + Assert.Equal((from a in g.sqlite.Select() + where a.id == item.id + orderby a.id, a.createtime ascending, a.name descending + select a).ToSql(), + (from a in g.sqlite.Select() + where a.id == item.id + orderby a.id, a.createtime, a.name descending + select a).ToSql()); + + Assert.Equal((from a in g.sqlite.Select() + where a.id == item.id + orderby a.id ascending, a.createtime ascending, a.name descending + select a).ToSql(), + g.sqlite.Select().Where(a => a.id == item.id).OrderBy(a => a.id).OrderBy(a => a.createtime).OrderByDescending(a => a.name).ToSql()); + + Assert.Equal((from a in g.sqlite.Select() + where a.id == item.id + orderby a.id descending, a.createtime ascending, a.name descending + select a).ToSql(), + g.sqlite.Select().Where(a => a.id == item.id).OrderByDescending(a => a.id).OrderBy(a => a.createtime).OrderByDescending(a => a.name).ToSql()); + } + [Fact] public void Select() { @@ -111,6 +168,7 @@ namespace FreeSql.Tests.Linq var t1 = (from a in g.sqlite.Select() join b in g.sqlite.Select() on a.id equals b.TestLinqToSqlId + orderby b.id descending select a).ToList(); Assert.True(t1.Any()); //Assert.Equal(item.id, t1[0].id); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6a8cda46..d85749c3 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1320,19 +1320,29 @@ namespace FreeSql.Internal //判断 [JsonMap] 并非导航对象,所以在上面提前判断 ColumnsByCs var tb2tmp = _common.GetTableByEntity(exp2Type); + var exp2IsParameter = false; if (tb2tmp != null) { if (exp2.NodeType == ExpressionType.Parameter) { parmExp2 = (exp2 as ParameterExpression); alias2 = parmExp2.Name; + exp2IsParameter = true; } - else alias2 = $"{alias2}__{mp2.Member.Name}"; - find2 = getOrAddTable(tb2tmp, alias2, exp2.NodeType == ExpressionType.Parameter, parmExp2, mp2); + else if (string.IsNullOrEmpty(alias2) && exp2 is MemberExpression expMem && ( + _common.GetTableByEntity(expMem.Expression.Type)?.ColumnsByCs.ContainsKey(expMem.Member.Name) == false || + expMem.Expression.NodeType == ExpressionType.Parameter && expMem.Expression.Type.IsAnonymousType())) //<>h__TransparentIdentifier 是 Linq To Sql 的类型判断,此时为匿名类型 + { + alias2 = mp2.Member.Name; + exp2IsParameter = true; + } + else + alias2 = $"{alias2}__{mp2.Member.Name}"; + find2 = getOrAddTable(tb2tmp, alias2, exp2IsParameter, parmExp2, mp2); alias2 = find2.Alias; tb2 = tb2tmp; } - if (exp2.NodeType == ExpressionType.Parameter && expStack.Any() == false) + if (exp2IsParameter && expStack.Any() == false) { //附加选择的参数所有列 if (tsc._selectColumnMap != null) { @@ -1349,7 +1359,7 @@ namespace FreeSql.Internal var tb3 = _common.GetTableByEntity(mp2.Type); if (tb3 != null) { - var find3 = getOrAddTable(tb2tmp, alias2 /*$"{alias2}__{mp2.Member.Name}"*/, exp2.NodeType == ExpressionType.Parameter, parmExp2, mp2); + var find3 = getOrAddTable(tb2tmp, alias2 /*$"{alias2}__{mp2.Member.Name}"*/, exp2IsParameter, parmExp2, mp2); foreach (var tb3c in tb3.Columns.Values) tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find3, Column = tb3c }); From f97e7c21ebcf8e5b5917a8dc3874cc716d68cad0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 17 Jul 2020 18:23:31 +0800 Subject: [PATCH 0754/1029] 1.7.0-preview0718 #380 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 35 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 504d34a4..dc717ee4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 39eb95d0..d970fa1f 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index bacc6b63..b22c90fe 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 8fdce8d2..17f7e517 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index cf170247..e1c5efb7 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0716 + 1.7.0-preview0718 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3bc0524c..e792b8d8 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4e2af9c7..5156e768 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5a3954a4..66ecb7e6 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1c0870b6..309b5433 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index c560d269..2cb79490 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index af3565ad..ba8eeaab 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6fc45db9..15025909 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f0e67c02..911d3bd7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 5b5060e5..0d55ce64 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d528b6db..fb5b9009 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 35191e91..79ac5af3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 7918bce6..cb2102f7 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index edbb0f76..046517a2 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9aa0a038..185e76fb 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0716 + 1.7.0-preview0718 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 8d11993e6c9c3044e08631f56d3291ebb58b6b7a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 18 Jul 2020 11:58:58 +0800 Subject: [PATCH 0755/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20fsql.InsertO?= =?UTF-8?q?rUpdate=20IfExistsDoNothing=20=E6=95=B0=E6=8D=AE=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E6=97=B6=E4=B8=8D=E5=81=9A=E4=BB=BB=E4=BD=95=E4=BA=8B?= =?UTF-8?q?(=E4=B8=8D=E6=9B=B4=E6=96=B0)=20#330=20#316=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++++++++++++++++ ...DamengInsertOrUpdateIfExistsNothingTest.cs | 425 ++++++++++++++++ .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 4 +- ...aseESInsertOrUpdateIfExistsDoNotingTest.cs | 266 ++++++++++ .../Curd/KingbaseESInsertOrUpdateTest.cs | 4 +- ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++++++++++++++++ ...acleInsertOrUpdateIfExistsDoNothingTest.cs | 425 ++++++++++++++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 4 +- ...reSQLInsertOrUpdateIfExistsDoNotingTest.cs | 266 ++++++++++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 4 +- ...rverInsertOrUpdateIfExistsDoNothingTest.cs | 422 ++++++++++++++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 4 +- ...DamengInsertOrUpdateIfExistsNothingTest.cs | 425 ++++++++++++++++ .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 4 +- ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++++++++++++++++ ...acleInsertOrUpdateIfExistsDoNothingTest.cs | 425 ++++++++++++++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 4 +- ...reSQLInsertOrUpdateIfExistsDoNotingTest.cs | 266 ++++++++++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 4 +- ...TongInsertOrUpdateIfExistsDoNothingTest.cs | 293 +++++++++++ .../Curd/ShenTongInsertOrUpdateTest.cs | 6 +- ...rverInsertOrUpdateIfExistsDoNothingTest.cs | 424 ++++++++++++++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 4 +- ...liteInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++++++++++++++++ .../Sqlite/Curd/SqliteInsertOrUpdateTest.cs | 4 +- FreeSql/FreeSql.xml | 24 +- FreeSql/Interface/Curd/IInsertOrUpdate.cs | 7 + FreeSql/Interface/IFreeSql.cs | 17 +- .../CommonProvider/InsertOrUpdateProvider.cs | 7 + .../Internal/CommonProvider/InsertProvider.cs | 4 +- .../Curd/DamengInsertOrUpdate.cs | 2 +- .../Curd/MySqlInsertOrUpdate.cs | 18 +- .../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 2 +- .../Curd/OdbcKingbaseESInsertOrUpdate.cs | 2 +- .../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 19 +- .../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 2 +- .../Curd/OdbcPostgreSQLInsertOrUpdate.cs | 2 +- .../Curd/OdbcSqlServerInsertOrUpdate.cs | 2 +- .../Curd/OracleInsertOrUpdate.cs | 2 +- .../Curd/PostgreSQLInsertOrUpdate.cs | 2 +- .../Curd/ShenTongInsertOrUpdate.cs | 2 +- .../Curd/SqlServerInsertOrUpdate.cs | 2 +- .../Curd/SqliteInsertOrUpdate.cs | 31 +- 44 files changed, 5585 insertions(+), 73 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs 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.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..078e59e2 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) + +; + +INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs new file mode 100644 index 00000000..1f65a142 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengInsertOrUpdateIfExistsNothingTest + { + IFreeSql fsql => g.dameng; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn01 { id = 1 }, new tbioudn01 { id = 2 }, new tbioudn01 { id = 3 }, new tbioudn01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn01 { id = 1 }, new tbioudn01 { id = 2 }, new tbioudn01 { id = 3 }, new tbioudn01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbioudn01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn02 { id = 1, name = "01" }, new tbioudn02 { id = 2, name = "02" }, new tbioudn02 { id = 3, name = "03" }, new tbioudn02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn02 { id = 1, name = "001" }, new tbioudn02 { id = 2, name = "002" }, new tbioudn02 { id = 3, name = "003" }, new tbioudn02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudn02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "01" }, new tbioudn022 { id = 2, name = "02" }, new tbioudn022 { id = 3, name = "03" }, new tbioudn022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "001" }, new tbioudn022 { id = 2, name = "002" }, new tbioudn022 { id = 3, name = "003" }, new tbioudn022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { name = "01" }, new tbioudn022 { name = "02" }, new tbioudn022 { name = "03" }, new tbioudn022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('01') +INTO ""TBIOUDN022""(""NAME"") VALUES('02') +INTO ""TBIOUDN022""(""NAME"") VALUES('03') +INTO ""TBIOUDN022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { name = "001" }, new tbioudn022 { name = "002" }, new tbioudn022 { name = "003" }, new tbioudn022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('001') +INTO ""TBIOUDN022""(""NAME"") VALUES('002') +INTO ""TBIOUDN022""(""NAME"") VALUES('003') +INTO ""TBIOUDN022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "100001" }, new tbioudn022 { name = "00001" }, new tbioudn022 { id = 2, name = "100002" }, new tbioudn022 { name = "00002" }, new tbioudn022 { id = 3, name = "100003" }, new tbioudn022 { name = "00003" }, new tbioudn022 { id = 4, name = "100004" }, new tbioudn022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('00001') +INTO ""TBIOUDN022""(""NAME"") VALUES('00002') +INTO ""TBIOUDN022""(""NAME"") VALUES('00003') +INTO ""TBIOUDN022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudn022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn03 { id1 = 1, id2 = "01", name = "01" }, new tbioudn03 { id1 = 2, id2 = "02", name = "02" }, new tbioudn03 { id1 = 3, id2 = "03", name = "03" }, new tbioudn03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn03 { id1 = 1, id2 = "01", name = "001" }, new tbioudn03 { id1 = 2, id2 = "02", name = "002" }, new tbioudn03 { id1 = 3, id2 = "03", name = "003" }, new tbioudn03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudn03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn04 { id = 1, name = "01" }, new tbioudn04 { id = 2, name = "02" }, new tbioudn04 { id = 3, name = "03" }, new tbioudn04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn04 { id = 1, name = "001" }, new tbioudn04 { id = 2, name = "002" }, new tbioudn04 { id = 3, name = "003" }, new tbioudn04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudn04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs index 3901c553..5143f004 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -313,10 +313,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); iou.ExecuteAffrows(); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs new file mode 100644 index 00000000..740d3dbe --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs @@ -0,0 +1,266 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESInsertOrUpdateIfExistsDoNotingTest + { + IFreeSql fsql => g.kingbaseES; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(2) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '01') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '011') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(2, '02') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '01') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '011') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(2, '02') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""ID"") DO NOTHING + +; + +INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '011') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(2, '02', '02') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs index 4a1cff8f..971cfe25 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs @@ -107,9 +107,9 @@ ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET ""NAME"" = EXCLUDED.""NAME""", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); - Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '02', '011') + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '011') ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET ""NAME"" = EXCLUDED.""NAME""", sql); Assert.Equal(1, iou.ExecuteAffrows()); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..2aa81af4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) + +; + +INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..87c2cc30 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.oracle; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('01') +INTO ""TBIOUDB022""(""NAME"") VALUES('02') +INTO ""TBIOUDB022""(""NAME"") VALUES('03') +INTO ""TBIOUDB022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('001') +INTO ""TBIOUDB022""(""NAME"") VALUES('002') +INTO ""TBIOUDB022""(""NAME"") VALUES('003') +INTO ""TBIOUDB022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('00001') +INTO ""TBIOUDB022""(""NAME"") VALUES('00002') +INTO ""TBIOUDB022""(""NAME"") VALUES('00003') +INTO ""TBIOUDB022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs index 8ed896b3..0081c3b1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -314,10 +314,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); iou.ExecuteAffrows(); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs new file mode 100644 index 00000000..5ddbb0a4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs @@ -0,0 +1,266 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLInsertOrUpdateIfExistsDoNotingTest + { + IFreeSql fsql => g.pgsql; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(2) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""id"") DO NOTHING + +; + +INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs index e539b712..c1ba0fb4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -194,9 +194,9 @@ ON CONFLICT(""id1"", ""id2"") DO UPDATE SET ""name"" = EXCLUDED.""name""", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); - Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011') + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') ON CONFLICT(""id1"", ""id2"") DO UPDATE SET ""name"" = EXCLUDED.""name""", sql); Assert.Equal(1, iou.ExecuteAffrows()); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..623205b1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,422 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + public class SqlServerInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 2 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'100001' as name +UNION ALL + SELECT 2, N'100002' +UNION ALL + SELECT 3, N'100003' +UNION ALL + SELECT 4, N'100004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF; + +; + +INSERT INTO [tbioudb022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 2 as id1, N'02' as id2, N'02' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name +UNION ALL + SELECT 2, N'02', N'02' +UNION ALL + SELECT 3, N'03', N'03' +UNION ALL + SELECT 4, N'04', N'04' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'001' as name +UNION ALL + SELECT 2, N'02', N'002' +UNION ALL + SELECT 3, N'03', N'003' +UNION ALL + SELECT 4, N'04', N'004' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'011' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 2 as id, N'02' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'02', 0, getdate() +UNION ALL + SELECT 3, N'03', 0, getdate() +UNION ALL + SELECT 4, N'04', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'001' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'002', 0, getdate() +UNION ALL + SELECT 3, N'003', 0, getdate() +UNION ALL + SELECT 4, N'004', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs index 90bc5604..148a0e1b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -311,10 +311,10 @@ WHEN NOT MATCHED THEN values (t2.id1, t2.id2, t2.name);", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO [tbiou03] t1 -USING (SELECT 1 as id1, N'02' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +USING (SELECT 1 as id1, N'01' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) WHEN MATCHED THEN update set [name] = t2.name WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs new file mode 100644 index 00000000..68a5bc27 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengInsertOrUpdateIfExistsNothingTest + { + IFreeSql fsql => g.dameng; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn01 { id = 1 }, new tbioudn01 { id = 2 }, new tbioudn01 { id = 3 }, new tbioudn01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn01 { id = 1 }, new tbioudn01 { id = 2 }, new tbioudn01 { id = 3 }, new tbioudn01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbioudn01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn02 { id = 1, name = "01" }, new tbioudn02 { id = 2, name = "02" }, new tbioudn02 { id = 3, name = "03" }, new tbioudn02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn02 { id = 1, name = "001" }, new tbioudn02 { id = 2, name = "002" }, new tbioudn02 { id = 3, name = "003" }, new tbioudn02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudn02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "01" }, new tbioudn022 { id = 2, name = "02" }, new tbioudn022 { id = 3, name = "03" }, new tbioudn022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "001" }, new tbioudn022 { id = 2, name = "002" }, new tbioudn022 { id = 3, name = "003" }, new tbioudn022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { name = "01" }, new tbioudn022 { name = "02" }, new tbioudn022 { name = "03" }, new tbioudn022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('01') +INTO ""TBIOUDN022""(""NAME"") VALUES('02') +INTO ""TBIOUDN022""(""NAME"") VALUES('03') +INTO ""TBIOUDN022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { name = "001" }, new tbioudn022 { name = "002" }, new tbioudn022 { name = "003" }, new tbioudn022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('001') +INTO ""TBIOUDN022""(""NAME"") VALUES('002') +INTO ""TBIOUDN022""(""NAME"") VALUES('003') +INTO ""TBIOUDN022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "100001" }, new tbioudn022 { name = "00001" }, new tbioudn022 { id = 2, name = "100002" }, new tbioudn022 { name = "00002" }, new tbioudn022 { id = 3, name = "100003" }, new tbioudn022 { name = "00003" }, new tbioudn022 { id = 4, name = "100004" }, new tbioudn022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('00001') +INTO ""TBIOUDN022""(""NAME"") VALUES('00002') +INTO ""TBIOUDN022""(""NAME"") VALUES('00003') +INTO ""TBIOUDN022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudn022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn03 { id1 = 1, id2 = "01", name = "01" }, new tbioudn03 { id1 = 2, id2 = "02", name = "02" }, new tbioudn03 { id1 = 3, id2 = "03", name = "03" }, new tbioudn03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn03 { id1 = 1, id2 = "01", name = "001" }, new tbioudn03 { id1 = 2, id2 = "02", name = "002" }, new tbioudn03 { id1 = 3, id2 = "03", name = "003" }, new tbioudn03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudn03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn04 { id = 1, name = "01" }, new tbioudn04 { id = 2, name = "02" }, new tbioudn04 { id = 3, name = "03" }, new tbioudn04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn04 { id = 1, name = "001" }, new tbioudn04 { id = 2, name = "002" }, new tbioudn04 { id = 3, name = "003" }, new tbioudn04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudn04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs index 3a4ceb48..e3dea03d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -314,10 +314,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); iou.ExecuteAffrows(); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..e1dd894b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySql +{ + public class MySqlInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) + +; + +INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..d3becb46 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Oracle +{ + public class OracleInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.oracle; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('01') +INTO ""TBIOUDB022""(""NAME"") VALUES('02') +INTO ""TBIOUDB022""(""NAME"") VALUES('03') +INTO ""TBIOUDB022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('001') +INTO ""TBIOUDB022""(""NAME"") VALUES('002') +INTO ""TBIOUDB022""(""NAME"") VALUES('003') +INTO ""TBIOUDB022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('00001') +INTO ""TBIOUDB022""(""NAME"") VALUES('00002') +INTO ""TBIOUDB022""(""NAME"") VALUES('00003') +INTO ""TBIOUDB022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs index d383cea5..69ef7b71 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -314,10 +314,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs new file mode 100644 index 00000000..d41f8281 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs @@ -0,0 +1,266 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLInsertOrUpdateIfExistsDoNotingTest + { + IFreeSql fsql => g.pgsql; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(2) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""id"") DO NOTHING + +; + +INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs index 4049b04d..0cd580cc 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -194,9 +194,9 @@ ON CONFLICT(""id1"", ""id2"") DO UPDATE SET ""name"" = EXCLUDED.""name""", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); - Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011') + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') ON CONFLICT(""id1"", ""id2"") DO UPDATE SET ""name"" = EXCLUDED.""name""", sql); Assert.Equal(1, iou.ExecuteAffrows()); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..c9a8fc85 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.shentong; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 2 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '011' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 2 as ID, '02' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME +UNION ALL + SELECT 2, '02' +UNION ALL + SELECT 3, '03' +UNION ALL + SELECT 4, '04' ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '001' as NAME +UNION ALL + SELECT 2, '002' +UNION ALL + SELECT 3, '003' +UNION ALL + SELECT 4, '004' ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME +UNION ALL + SELECT 2, '02', '02' +UNION ALL + SELECT 3, '03', '03' +UNION ALL + SELECT 4, '04', '04' ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME +UNION ALL + SELECT 2, '02', '002' +UNION ALL + SELECT 3, '03', '003' +UNION ALL + SELECT 4, '04', '004' ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME +UNION ALL + SELECT 2, '02', 0, current_timestamp +UNION ALL + SELECT 3, '03', 0, current_timestamp +UNION ALL + SELECT 4, '04', 0, current_timestamp ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, current_timestamp as CREATETIME +UNION ALL + SELECT 2, '002', 0, current_timestamp +UNION ALL + SELECT 3, '003', 0, current_timestamp +UNION ALL + SELECT 4, '004', 0, current_timestamp ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs index 4efd6731..801851ae 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs @@ -6,7 +6,7 @@ using Xunit; namespace FreeSql.Tests.ShenTong { - public class ShenTongInsertOrUpdateTestpublic + public class ShenTongInsertOrUpdateTest { IFreeSql fsql => g.shentong; @@ -170,10 +170,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..350ce5b8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,424 @@ +using FreeSql.DataAnnotations; +using FreeSql.Tests.DataContext.SqlServer; +using SaleIDO.Entity.Storeage; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.SqlServer +{ + public class SqlServerInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 2 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'100001' as name +UNION ALL + SELECT 2, N'100002' +UNION ALL + SELECT 3, N'100003' +UNION ALL + SELECT 4, N'100004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF; + +; + +INSERT INTO [tbioudb022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 2 as id1, N'02' as id2, N'02' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name +UNION ALL + SELECT 2, N'02', N'02' +UNION ALL + SELECT 3, N'03', N'03' +UNION ALL + SELECT 4, N'04', N'04' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'001' as name +UNION ALL + SELECT 2, N'02', N'002' +UNION ALL + SELECT 3, N'03', N'003' +UNION ALL + SELECT 4, N'04', N'004' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'011' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 2 as id, N'02' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'02', 0, getdate() +UNION ALL + SELECT 3, N'03', 0, getdate() +UNION ALL + SELECT 4, N'04', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'001' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'002', 0, getdate() +UNION ALL + SELECT 3, N'003', 0, getdate() +UNION ALL + SELECT 4, N'004', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs index dcbb2a3b..7ea53b8e 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -313,10 +313,10 @@ WHEN NOT MATCHED THEN values (t2.id1, t2.id2, t2.name);", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO [tbiou03] t1 -USING (SELECT 1 as id1, N'02' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +USING (SELECT 1 as id1, N'01' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) WHEN MATCHED THEN update set [name] = t2.name WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..07ca702a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Sqlite +{ + public class SqliteInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.sqlite; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '011' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 2, '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '001' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '011' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 2, '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '001' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '100001' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1) + +; + +INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '011' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 2, '02', '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 3 AND a.""id2"" = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 4 AND a.""id2"" = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '001' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 3 AND a.""id2"" = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 4 AND a.""id2"" = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '01', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '011', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 2, '02', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '01', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '001', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs index 2e793f17..d0e650ad 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs @@ -166,9 +166,9 @@ INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('0000 Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01')", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); - Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011')", sql); + Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011')", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e0ffd602..6a822109 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1151,6 +1151,13 @@ 实体集合 + + + 当记录存在时,什么都不做 + 换句话:只有记录不存在时才插入 + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; @@ -3929,14 +3936,17 @@ - 插入或更新数据 - MySql: on duplicate key update - PostgreSQL: on conflict do update - SqlServer: merge into - Oracle: merge into + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 - Dameng: merge into - 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法 + 达梦: merge into + 人大金仓:on conflict do update + 神通:merge into + MsAccess:不支持 + 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) diff --git a/FreeSql/Interface/Curd/IInsertOrUpdate.cs b/FreeSql/Interface/Curd/IInsertOrUpdate.cs index c6db9222..639a3ac2 100644 --- a/FreeSql/Interface/Curd/IInsertOrUpdate.cs +++ b/FreeSql/Interface/Curd/IInsertOrUpdate.cs @@ -35,6 +35,13 @@ namespace FreeSql /// IInsertOrUpdate SetSource(IEnumerable source); + /// + /// 当记录存在时,什么都不做 + /// 换句话:只有记录不存在时才插入 + /// + /// + IInsertOrUpdate IfExistsDoNothing(); + /// /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; /// diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index bb42ba92..bdc61fa0 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -45,14 +45,17 @@ public interface IFreeSql : IDisposable IInsert Insert(IEnumerable source) where T1 : class; /// - /// 插入或更新数据 - /// MySql: on duplicate key update - /// PostgreSQL: on conflict do update - /// SqlServer: merge into - /// Oracle: merge into + /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + /// 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 - /// Dameng: merge into - /// 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法 + /// 达梦: merge into + /// 人大金仓:on conflict do update + /// 神通:merge into + /// MsAccess:不支持 + /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) /// /// /// diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index ba76d54d..310ecdb7 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -19,6 +19,7 @@ namespace FreeSql.Internal.CommonProvider protected CommonUtils _commonUtils; protected CommonExpression _commonExpression; protected List _source = new List(); + protected bool _doNothing = false; protected Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); protected TableInfo _table; protected Func _tableRule; @@ -106,6 +107,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IInsertOrUpdate IfExistsDoNothing() + { + _doNothing = true; + return this; + } + protected string TableRuleInvoke() { if (_tableRule == null) return _table.DbName; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index fae63436..281837e2 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -494,7 +494,8 @@ namespace FreeSql.Internal.CommonProvider public virtual string ToSql() => ToSqlValuesOrSelectUnionAll(true); - public string ToSqlValuesOrSelectUnionAll(bool isValues = true) + public string ToSqlValuesOrSelectUnionAll(bool isValues = true) => ToSqlValuesOrSelectUnionAllExtension101(isValues, null); + public string ToSqlValuesOrSelectUnionAllExtension101(bool isValues, Action onrow) { if (_source == null || _source.Any() == false) return null; var sb = new StringBuilder(); @@ -541,6 +542,7 @@ namespace FreeSql.Internal.CommonProvider ++colidx2; } if (isValues) sb.Append(")"); + onrow?.Invoke(d, didx, sb); ++didx; } if (_noneParameter && specialParams.Any()) diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index 1f4046e2..d4da4540 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Dameng.Curd sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index 1106945d..e61d1491 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -40,7 +40,23 @@ namespace FreeSql.MySql.Curd string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); - else sql = new OnDuplicateKeyUpdate(insert.InsertIdentity()).ToSql(); + else + { + insert.InsertIdentity(); + if (_doNothing == false) + sql = new OnDuplicateKeyUpdate(insert).ToSql(); + else + { + if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + MySql 要求实体类 {_table.CsName} 必须有主键"); + sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => + sb.Append(" \r\n FROM dual WHERE NOT EXISTS(").Append( + _orm.Select() + .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) + .DisableGlobalFilter() + .WhereDynamic(rowd) + .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + } + } if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); return sql; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index a6305e38..ed5f4257 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.Dameng sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs index 9125b467..4dce4686 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs @@ -44,7 +44,7 @@ namespace FreeSql.Odbc.KingbaseES { var ocdu = new OdbcKingbaseESOnConflictDoUpdate(insert.InsertIdentity()); ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index 86747427..c1e7592a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; @@ -38,7 +39,23 @@ namespace FreeSql.Odbc.MySql string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); - else sql = new OdbcMySqlOnDuplicateKeyUpdate(insert.InsertIdentity()).ToSql(); + else + { + insert.InsertIdentity(); + if (_doNothing == false) + sql = new OdbcMySqlOnDuplicateKeyUpdate(insert).ToSql(); + else + { + if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + MySql 要求实体类 {_table.CsName} 必须有主键"); + sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => + sb.Append(" \r\n FROM dual WHERE NOT EXISTS(").Append( + _orm.Select() + .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) + .DisableGlobalFilter() + .WhereDynamic(rowd) + .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + } + } if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); return sql; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index ed63ad31..7ea43d2f 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.Oracle sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs index 311e46b2..2f3a8a0f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -42,7 +42,7 @@ namespace FreeSql.Odbc.PostgreSQL { var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert.InsertIdentity()); ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index 18779fe2..d4e711b2 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -40,7 +40,7 @@ namespace FreeSql.Odbc.SqlServer sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index a79c1694..36d50d18 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Oracle.Curd sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index a8a48263..c3a8461c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -42,7 +42,7 @@ namespace FreeSql.PostgreSQL.Curd { var ocdu = new OnConflictDoUpdate(insert.InsertIdentity()); ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs index f3ec0b2d..b03afa5a 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.ShenTong.Curd sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index b05b9e2c..d9834bd8 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -40,7 +40,7 @@ namespace FreeSql.SqlServer.Curd sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index ba2d2189..696d6920 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -37,15 +37,32 @@ namespace FreeSql.Sqlite.Curd .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; - if (IdentityColumn != null && flagInsert == false) insert.InsertIdentity(); - - var sql = insert.ToSql(); + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else + { + insert.InsertIdentity(); + if (_doNothing == false) + { + sql = insert.ToSql(); + if (sql?.StartsWith("INSERT INTO ") == true) + sql = $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}"; + } + else + { + if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + Sqlite 要求实体类 {_table.CsName} 必须有主键"); + sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => + sb.Append(" \r\n WHERE NOT EXISTS(").Append( + _orm.Select() + .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) + .DisableGlobalFilter() + .WhereDynamic(rowd) + .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + } + } if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); - if (IdentityColumn != null && flagInsert) return sql; - - if (sql.StartsWith("INSERT INTO ") == false) return null; - return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}"; + return sql; } } } From 7471df592464a7feb46e9c35b786c287eff6dbd4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 18 Jul 2020 13:50:26 +0800 Subject: [PATCH 0756/1029] =?UTF-8?q?=E5=86=85=E9=83=A8=20SQL=20=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 + .../BankOutlets.cs | 82 ++--- .../Banks.cs | 62 ++-- ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 288 +++++++++--------- .../MySqlConnector/Curd/MySqlSelectTest.cs | 48 +-- .../Dameng/Curd/DamengSelectTest.cs | 42 +-- .../Default/Curd/OdbcSelectTest.cs | 34 +-- .../Default/OdbcAdo/OdbcAdoTest.cs | 16 +- .../FreeSql.Tests.Provider.Odbc.xml | 24 +- .../KingbaseES/Curd/KingbaseESSelectTest.cs | 42 +-- ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 288 +++++++++--------- .../MySql/Curd/MySqlSelectTest.cs | 48 +-- .../Oracle/Curd/OracleSelectTest.cs | 42 +-- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 48 +-- .../PostgreSQLExpression/OtherTest.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 34 +-- .../SqlServerAdo/SqlServerAdoTest.cs | 16 +- .../FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 42 +-- .../Dameng/Curd/DamengSelectTest.cs | 42 +-- .../DataAnnotations/MySqlFluentTest.cs | 6 +- .../DataAnnotations/SqlServerFluentTest.cs | 6 +- .../FreeSql.Tests/FreeSql.Tests.csproj | 84 ++--- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 24 +- .../MsAccess/Curd/MsAccessSelectTest.cs | 34 +-- ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 288 +++++++++--------- .../MySql/Curd/MySqlSelectTest.cs | 54 ++-- .../Oracle/Curd/OracleSelectTest.cs | 42 +-- .../Other/CustomerCheckupGroup.cs | 86 +++--- .../FreeSql.Tests/Other/CustomerMember.cs | 102 +++---- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 48 +-- .../PostgreSQLExpression/OtherTest.cs | 2 +- .../ShenTong/Curd/ShenTongSelectTest.cs | 48 +-- .../ShenTong/ShenTongExpression/OtherTest.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 34 +-- .../SqlServerAdo/SqlServerAdoTest.cs | 16 +- ...liteInsertOrUpdateIfExistsDoNothingTest.cs | 288 +++++++++--------- .../Sqlite/Curd/SqliteSelectTest.cs | 42 +-- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 42 +-- FreeSql/Internal/CommonExpression.cs | 10 +- .../SelectProvider/Select0Provider.cs | 2 +- .../Curd/DamengSelect.cs | 2 +- .../Curd/MsAccessSelect.cs | 2 +- .../Curd/MySqlInsertOrUpdate.cs | 2 +- .../Curd/MySqlSelect.cs | 2 +- .../Dameng/Curd/OdbcDamengSelect.cs | 2 +- .../Default/Curd/OdbcSelect.cs | 2 +- .../KingbaseES/Curd/OdbcKingbaseESSelect.cs | 2 +- .../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 2 +- .../MySql/Curd/OdbcMySqlSelect.cs | 2 +- .../Oracle/Curd/OdbcOracleSelect.cs | 2 +- .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 2 +- .../SqlServer/Curd/OdbcSqlServerSelect.cs | 4 +- .../Curd/OracleSelect.cs | 2 +- .../Curd/PostgreSQLSelect.cs | 2 +- .../Curd/ShenTongSelect.cs | 2 +- .../Curd/SqlServerSelect.cs | 2 +- .../Curd/SqliteInsertOrUpdate.cs | 2 +- .../Curd/SqliteSelect.cs | 2 +- 58 files changed, 1265 insertions(+), 1249 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs index 25ab8b30..00453c66 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs @@ -13,63 +13,63 @@ using Newtonsoft.Json; using FreeSql.DataAnnotations; namespace FreeSql.Jhfw.Models { - public interface IBaseModel - { - TKey Id { get; set; } - } - [JsonObject(MemberSerialization.OptIn), Table(Name = "bank_outlets")] - public partial class BankOutlets : IBaseModel + public interface IBaseModel + { + TKey Id { get; set; } + } + [JsonObject(MemberSerialization.OptIn), Table(Name = "bank_outlets")] + public partial class BankOutlets : IBaseModel { - [JsonProperty] - public int? BankId { get => _BankId; set { - if (_BankId == value) return; - _BankId = value; - OneBanks = null; - }} - private int? _BankId; + [JsonProperty] + public int? BankId { get => _BankId; set { + if (_BankId == value) return; + _BankId = value; + OneBanks = null; + }} + private int? _BankId; - [JsonProperty] - public int? ParentId { get => _ParentId; set { - if (_ParentId == value) return; - _ParentId = value; - OneBankOutlets = null; - }} - private int? _ParentId; + [JsonProperty] + public int? ParentId { get => _ParentId; set { + if (_ParentId == value) return; + _ParentId = value; + OneBankOutlets = null; + }} + private int? _ParentId; - [JsonProperty] - public string Address { get; set; } = ""; + [JsonProperty] + public string Address { get; set; } = ""; - [JsonProperty, Column(DbType = "varchar(50)")] - public string Area { get; set; } = ""; + [JsonProperty, Column(DbType = "varchar(50)")] + public string Area { get; set; } = ""; - [JsonProperty, Column(Name = "ID", IsIdentity = true)] - public int Id { get; set; } + [JsonProperty, Column(Name = "ID", IsIdentity = true)] + public int Id { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Name { get; set; } = ""; + [JsonProperty, Column(DbType = "varchar(50)")] + public string Name { get; set; } = ""; - #region 外键 => 导航属性,ManyToOne/OneToOne + #region 外键 => 导航属性,ManyToOne/OneToOne - [Navigate("BankId")] - public virtual Banks OneBanks { get; set; } + [Navigate("BankId")] + public virtual Banks OneBanks { get; set; } - [Navigate("ParentId")] - public virtual BankOutlets OneBankOutlets { get; set; } + [Navigate("ParentId")] + public virtual BankOutlets OneBankOutlets { get; set; } - #endregion + #endregion - #region 外键 => 导航属性,OneToMany + #region 外键 => 导航属性,OneToMany - [Navigate("ParentId")] - public virtual List ManyBankOutlets { get; set; } + [Navigate("ParentId")] + public virtual List ManyBankOutlets { get; set; } - #endregion + #endregion - #region 外键 => 导航属性,ManyToMany + #region 外键 => 导航属性,ManyToMany - #endregion - } + #endregion + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs index 17f26cdb..d1394362 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs @@ -13,54 +13,54 @@ using Newtonsoft.Json; using FreeSql.DataAnnotations; namespace FreeSql.Jhfw.Models { - [JsonObject(MemberSerialization.OptIn), Table(Name = "banks")] - public partial class Banks : IBaseModel + [JsonObject(MemberSerialization.OptIn), Table(Name = "banks")] + public partial class Banks : IBaseModel { - [JsonProperty, Column(DbType = "datetime")] - public DateTime? Addtime { get; set; } + [JsonProperty, Column(DbType = "datetime")] + public DateTime? Addtime { get; set; } - [JsonProperty, Column(DbType = "varchar(250)")] - public string Banner { get; set; } = ""; + [JsonProperty, Column(DbType = "varchar(250)")] + public string Banner { get; set; } = ""; - [JsonProperty, Column(DbType = "varchar(20)")] - public string City { get; set; } = ""; + [JsonProperty, Column(DbType = "varchar(20)")] + public string City { get; set; } = ""; - [JsonProperty, Column(Name = "ID", IsIdentity = true)] - public int Id { get; set; } + [JsonProperty, Column(Name = "ID", IsIdentity = true)] + public int Id { get; set; } - [JsonProperty, Column(DbType = "tinyint(1)")] - public bool IsDelete { get; set; } + [JsonProperty, Column(DbType = "tinyint(1)")] + public bool IsDelete { get; set; } - [JsonProperty, Column(DbType = "tinyint(1)")] - public bool IsGrab { get; set; } + [JsonProperty, Column(DbType = "tinyint(1)")] + public bool IsGrab { get; set; } - [JsonProperty, Column(DbType = "tinyint(1)")] - public bool IsJoinHmd { get; set; } + [JsonProperty, Column(DbType = "tinyint(1)")] + public bool IsJoinHmd { get; set; } - [JsonProperty, Column(DbType = "varchar(100)")] - public string LoanType { get; set; } = ""; + [JsonProperty, Column(DbType = "varchar(100)")] + public string LoanType { get; set; } = ""; - [JsonProperty, Column(DbType = "varchar(250)")] - public string Logo { get; set; } = ""; + [JsonProperty, Column(DbType = "varchar(250)")] + public string Logo { get; set; } = ""; - [JsonProperty] - public string Name { get; set; } = ""; + [JsonProperty] + public string Name { get; set; } = ""; - [JsonProperty, Column(DbType = "varchar(3000)")] - public string Notice { get; set; } = ""; + [JsonProperty, Column(DbType = "varchar(3000)")] + public string Notice { get; set; } = ""; - #region 外键 => 导航属性,OneToMany + #region 外键 => 导航属性,OneToMany - [Navigate("BankId")] - public virtual List ManyBankOutlets { get; set; } + [Navigate("BankId")] + public virtual List ManyBankOutlets { get; set; } - #endregion + #endregion - #region 外键 => 导航属性,ManyToMany + #region 外键 => 导航属性,ManyToMany - #endregion - } + #endregion + } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs index 078e59e2..173fa8eb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -19,81 +19,81 @@ namespace FreeSql.Tests.MySqlConnector var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); @@ -111,81 +111,81 @@ UNION ALL var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); @@ -221,27 +221,27 @@ UNION ALL sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '100002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '100003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '100004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) ; @@ -265,81 +265,81 @@ INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004' var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) UNION ALL SELECT 2, '02', '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) UNION ALL SELECT 3, '03', '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 3 AND a.`id2` = '03') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) UNION ALL SELECT 4, '04', '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 4 AND a.`id2` = '04') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) UNION ALL SELECT 2, '02', '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) UNION ALL SELECT 3, '03', '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 3 AND a.`id2` = '03') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) UNION ALL SELECT 4, '04', '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 4 AND a.`id2` = '04') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); @@ -361,81 +361,81 @@ UNION ALL var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 956d0aaf..7b587941 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -104,22 +104,22 @@ namespace FreeSql.Tests.MySqlConnector //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -203,9 +203,9 @@ namespace FreeSql.Tests.MySqlConnector var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) //.Where(a => a.Id == 1).ToSql(); var sql4 = select.From((s, b, c) => s @@ -929,8 +929,8 @@ namespace FreeSql.Tests.MySqlConnector count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -947,8 +947,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -965,8 +965,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -983,8 +983,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -999,7 +999,7 @@ FROM `tb_topic` a", subquery); Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` - FROM `tb_topic` b)))", subquery); + FROM `tb_topic` b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1077,12 +1077,12 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALL SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 0f6cc2f5..a3cead83 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -96,22 +96,22 @@ namespace FreeSql.Tests.Odbc.Dameng //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.dameng.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -855,8 +855,8 @@ namespace FreeSql.Tests.Odbc.Dameng count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -873,8 +873,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -891,8 +891,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -909,8 +909,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -925,7 +925,7 @@ FROM ""TB_TOPIC22"" a", subquery); Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" FROM ""TB_TOPIC22"" a WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" - FROM ""TB_TOPIC22"" b)))", subquery); + FROM ""TB_TOPIC22"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1004,12 +1004,12 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 617e15d3..59c91446 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -85,22 +85,22 @@ namespace FreeSql.Tests.Odbc.Default //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] //FROM [Tag] a //WHERE (exists(SELECT 1 - // FROM [Tag] t - // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] - // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) - // limit 0,1)) + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) //ManyToMany var t2 = g.odbc.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] //FROM [Song] a //WHERE(exists(SELECT 1 - // FROM [Song_tag] Mt_Ms - // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 - // FROM [Tag] t - // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) - // limit 0, 1)) - // limit 0, 1)) + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -830,7 +830,7 @@ namespace FreeSql.Tests.Odbc.Default count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -847,7 +847,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -864,7 +864,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -881,7 +881,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -896,7 +896,7 @@ FROM [tb_topic22] a", subquery); Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] - FROM [tb_topic22] b)))", subquery); + FROM [tb_topic22] b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -974,12 +974,12 @@ WHERE (((cast(a.[Id] as nvarchar)) in (SELECT b.[Title] query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs index bec8f773..8a81857e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs @@ -45,20 +45,20 @@ namespace FreeSql.Tests.Odbc.Default { //var tt1 = g.odbc.Select() - // .LeftJoin(a => a.ParentId == a.Parent.Id) - // .ToSql(a => new { a.Id, a.Title }); + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToSql(a => new { a.Id, a.Title }); //var tt2result = g.odbc.Select() - // .LeftJoin(a => a.ParentId == a.Parent.Id) - // .ToList(a => new { a.Id, a.Title }); + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToList(a => new { a.Id, a.Title }); //var tt = g.odbc.Select() - // .LeftJoin((a, b) => b.Id == a.Id) - // .ToSql(a => new { a.Id, a.Title }); + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToSql(a => new { a.Id, a.Title }); //var ttresult = g.odbc.Select() - // .LeftJoin((a, b) => b.Id == a.Id) - // .ToList(a => new { a.Id, a.Title }); + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToList(a => new { a.Id, a.Title }); var tnsql1 = g.odbc.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml index 81f32e84..7edc81cc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.xml @@ -27,62 +27,62 @@ - + - + - + - + 类型 - + 内容简介 - + 缩略图 - + 点击量 - + - + - + - + - + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs index 5e0b9a0d..bba60c6e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs @@ -96,22 +96,22 @@ namespace FreeSql.Tests.Odbc.KingbaseES //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.kingbaseES.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -820,8 +820,8 @@ namespace FreeSql.Tests.Odbc.KingbaseES count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - limit 1) as6 + FROM ""TB_TOPIC22"" b + limit 1) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -838,8 +838,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - limit 1) as6 + FROM ""TB_TOPIC22"" b + limit 1) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -856,8 +856,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - limit 1) as6 + FROM ""TB_TOPIC22"" b + limit 1) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -874,8 +874,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - limit 1) as6 + FROM ""TB_TOPIC22"" b + limit 1) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -890,7 +890,7 @@ FROM ""TB_TOPIC22"" a", subquery); Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" FROM ""TB_TOPIC22"" a WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" - FROM ""TB_TOPIC22"" b)))", subquery); + FROM ""TB_TOPIC22"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -969,12 +969,12 @@ WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs index 2aa81af4..4b72f7e4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -19,81 +19,81 @@ namespace FreeSql.Tests.Odbc.MySql var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); @@ -111,81 +111,81 @@ UNION ALL var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); @@ -221,27 +221,27 @@ UNION ALL sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '100002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '100003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '100004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) ; @@ -265,81 +265,81 @@ INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004' var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) UNION ALL SELECT 2, '02', '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) UNION ALL SELECT 3, '03', '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 3 AND a.`id2` = '03') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) UNION ALL SELECT 4, '04', '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 4 AND a.`id2` = '04') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) UNION ALL SELECT 2, '02', '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) UNION ALL SELECT 3, '03', '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 3 AND a.`id2` = '03') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) UNION ALL SELECT 4, '04', '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 4 AND a.`id2` = '04') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); @@ -361,81 +361,81 @@ UNION ALL var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 546a0e06..00203bd0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -104,22 +104,22 @@ namespace FreeSql.Tests.Odbc.MySql //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -213,9 +213,9 @@ namespace FreeSql.Tests.Odbc.MySql //); //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) //.Where(a => a.Id == 1).ToSql(); var sql4 = select.From((s, b, c) => s @@ -940,8 +940,8 @@ namespace FreeSql.Tests.Odbc.MySql count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -958,8 +958,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -976,8 +976,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -994,8 +994,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -1010,7 +1010,7 @@ FROM `tb_topic` a", subquery); Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` - FROM `tb_topic` b)))", subquery); + FROM `tb_topic` b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1088,12 +1088,12 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALL SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 827fa198..a21ab06c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -96,22 +96,22 @@ namespace FreeSql.Tests.Odbc.Oracle //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.oracle.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -856,8 +856,8 @@ namespace FreeSql.Tests.Odbc.Oracle count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -874,8 +874,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -892,8 +892,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -910,8 +910,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -926,7 +926,7 @@ FROM ""TB_TOPIC22"" a", subquery); Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" FROM ""TB_TOPIC22"" a WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" - FROM ""TB_TOPIC22"" b)))", subquery); + FROM ""TB_TOPIC22"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1005,12 +1005,12 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 00e356e7..5dad0dd0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -86,22 +86,22 @@ namespace FreeSql.Tests.Odbc.PostgreSQL //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.pgsql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -189,9 +189,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL //); //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) //.Where(a => a.Id == 1).ToSql(); var sql4 = select.From((s, b, c) => s @@ -916,8 +916,8 @@ namespace FreeSql.Tests.Odbc.PostgreSQL count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT sum(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b + limit 1) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -934,8 +934,8 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT min(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b + limit 1) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -952,8 +952,8 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT max(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b + limit 1) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -970,8 +970,8 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT avg(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b + limit 1) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -986,7 +986,7 @@ FROM ""tb_topic"" a", subquery); Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime"" FROM ""tb_topic"" a WHERE ((((a.""id"")::text) in (SELECT b.""title"" - FROM ""tb_topic"" b)))", subquery); + FROM ""tb_topic"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1064,12 +1064,12 @@ WHERE ((((a.""id"")::text) in (SELECT b.""title"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb UNION ALLSELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb UNION ALL SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs index a418e8ac..bb6fb5ca 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -81,7 +81,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression public void Array() { //g.pgsql.Aop.CurdAfter = (s, e) => { - // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); + // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); //}; IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 4cd9858b..78f16fee 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -85,22 +85,22 @@ namespace FreeSql.Tests.Odbc.SqlServer //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] //FROM [Tag] a //WHERE (exists(SELECT 1 - // FROM [Tag] t - // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] - // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) - // limit 0,1)) + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) //ManyToMany var t2 = g.sqlserver.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] //FROM [Song] a //WHERE(exists(SELECT 1 - // FROM [Song_tag] Mt_Ms - // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 - // FROM [Tag] t - // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) - // limit 0, 1)) - // limit 0, 1)) + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -811,7 +811,7 @@ namespace FreeSql.Tests.Odbc.SqlServer count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -828,7 +828,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -845,7 +845,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -862,7 +862,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -877,7 +877,7 @@ FROM [tb_topic22] a", subquery); Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] - FROM [tb_topic22] b)))", subquery); + FROM [tb_topic22] b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -955,12 +955,12 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index 5dd43624..bdb889d9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -46,20 +46,20 @@ namespace FreeSql.Tests.Odbc.SqlServer { //var tt1 = g.sqlserver.Select() - // .LeftJoin(a => a.ParentId == a.Parent.Id) - // .ToSql(a => new { a.Id, a.Title }); + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToSql(a => new { a.Id, a.Title }); //var tt2result = g.sqlserver.Select() - // .LeftJoin(a => a.ParentId == a.Parent.Id) - // .ToList(a => new { a.Id, a.Title }); + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToList(a => new { a.Id, a.Title }); //var tt = g.sqlserver.Select() - // .LeftJoin((a, b) => b.Id == a.Id) - // .ToSql(a => new { a.Id, a.Title }); + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToSql(a => new { a.Id, a.Title }); //var ttresult = g.sqlserver.Select() - // .LeftJoin((a, b) => b.Id == a.Id) - // .ToList(a => new { a.Id, a.Title }); + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToList(a => new { a.Id, a.Title }); var tnsql1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); var tnsql2 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToSql(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index 4f26b4ac..a74ab260 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -134,73 +134,73 @@ namespace FreeSql.Tests.Odbc { /// /// - /// + /// [Column(Name = "article_id", IsIdentity = true, IsPrimary = true)] public int ArticleId { get; set; } /// /// - /// + /// [Column(Name = "article_title")] public string ArticleTitle { get; set; } /// /// - /// + /// [Column(Name = "category_id")] public int CategoryId { get; set; } /// /// - /// + /// [Column(Name = "channel_id")] public int ChannelId { get; set; } /// /// 类型 - /// + /// [Column(Name = "type_id")] public int TypeId { get; set; } /// /// 内容简介 - /// + /// [Column(Name = "summary")] public string Summary { get; set; } /// /// 缩略图 - /// + /// [Column(Name = "thumbnail")] public string Thumbnail { get; set; } /// /// 点击量 - /// + /// [Column(Name = "hits")] public int Hits { get; set; } /// /// - /// + /// [Column(Name = "is_display")] public int IsDisplay { get; set; } /// /// - /// + /// [Column(Name = "status")] public int Status { get; set; } /// /// - /// + /// [Column(Name = "create_time")] public int CreateTime { get; set; } /// /// - /// + /// [Column(Name = "release_time")] public int ReleaseTime { get; set; } @@ -475,14 +475,14 @@ WHERE ROWNUM < 11"; //var testaddlist = new List(); //for(var a = 0; a < 133905; a++) { - // testaddlist.Add(new NewsArticle { - // ArticleTitle = "testaddlist_topic" + a, - // Hits = a, - // }); + // testaddlist.Add(new NewsArticle { + // ArticleTitle = "testaddlist_topic" + a, + // Hits = a, + // }); //} //g.mysql.Insert(testaddlist) - // //.NoneParameter() - // .ExecuteAffrows(); + // //.NoneParameter() + // .ExecuteAffrows(); g.mysql.Aop.ParseExpression += (s, e) => @@ -872,9 +872,9 @@ WHERE ROWNUM < 11"; //); //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) //.Where(a => a.Id == 1).ToSql(); var sql4 = select.From((s, b, c) => s diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index c5597f2a..a3a9400f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -96,22 +96,22 @@ namespace FreeSql.Tests.Dameng //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.dameng.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -855,8 +855,8 @@ namespace FreeSql.Tests.Dameng count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -873,8 +873,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -891,8 +891,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -909,8 +909,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -925,7 +925,7 @@ FROM ""TB_TOPIC22"" a", subquery); Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" FROM ""TB_TOPIC22"" a WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" - FROM ""TB_TOPIC22"" b)))", subquery); + FROM ""TB_TOPIC22"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1005,12 +1005,12 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index 06fb7aec..c86d4fd8 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -68,9 +68,9 @@ namespace FreeSql.Tests.DataAnnotations { g.mysql.CodeFirst //.ConfigEntity(a => { - // a.Name("xxdkdkdk1"); - // a.Property(b => b.Id).Name("Id22").IsIdentity(true); - // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); + // a.Name("xxdkdkdk1"); + // a.Property(b => b.Id).Name("Id22").IsIdentity(true); + // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); //}) .ConfigEntity(typeof(TestFluenttb1), a => diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs index ce6bda66..0ee5d8d8 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs @@ -41,9 +41,9 @@ namespace FreeSql.Tests.DataAnnotations { g.sqlserver.CodeFirst //.ConfigEntity(a => { - // a.Name("xxdkdkdk1"); - // a.Property(b => b.Id).Name("Id22").IsIdentity(true); - // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); + // a.Name("xxdkdkdk1"); + // a.Property(b => b.Id).Name("Id22").IsIdentity(true); + // a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); //}) .ConfigEntity(typeof(TestFluenttb1), a => diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 9e16a3d0..9e16a021 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -1,61 +1,61 @@  - - netcoreapp3.1 + + netcoreapp3.1 - false - + false + - - FreeSql.Tests.xml + + FreeSql.Tests.xml 3 false x86 - + - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - - - + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - ..\..\Providers\FreeSql.Provider.Dameng\lib\DmProvider\netstandard2.0\DmProvider.dll - + + + ..\..\Providers\FreeSql.Provider.Dameng\lib\DmProvider\netstandard2.0\DmProvider.dll + ..\..\Providers\FreeSql.Provider.ShenTong\lib\System.Data.OscarClient.dll ..\..\Providers\FreeSql.Provider.ShenTong\lib\Mono.Security.dll - + diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 3cae4dac..b54c9d60 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -27,62 +27,62 @@ - + - + - + - + 类型 - + 内容简介 - + 缩略图 - + 点击量 - + - + - + - + - + diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index 8a51a097..24c806a0 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -85,22 +85,22 @@ namespace FreeSql.Tests.MsAccess //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] //FROM [Tag] a //WHERE (exists(SELECT 1 - // FROM [Tag] t - // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] - // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) - // limit 0,1)) + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) //ManyToMany var t2 = g.msaccess.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] //FROM [Song] a //WHERE(exists(SELECT 1 - // FROM [Song_tag] Mt_Ms - // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 - // FROM [Tag] t - // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) - // limit 0, 1)) - // limit 0, 1)) + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -831,7 +831,7 @@ namespace FreeSql.Tests.MsAccess count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 sum(b.[Id]) - FROM [tb_topic22] b) as as6 + FROM [tb_topic22] b) as as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -848,7 +848,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 min(b.[Id]) - FROM [tb_topic22] b) as as6 + FROM [tb_topic22] b) as as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -865,7 +865,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 max(b.[Id]) - FROM [tb_topic22] b) as as6 + FROM [tb_topic22] b) as as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -882,7 +882,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 avg(b.[Id]) - FROM [tb_topic22] b) as as6 + FROM [tb_topic22] b) as as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -897,7 +897,7 @@ FROM [tb_topic22] a", subquery); Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (((cstr(a.[Id])) in (SELECT b.[Title] - FROM [tb_topic22] b)))", subquery); + FROM [tb_topic22] b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -975,12 +975,12 @@ WHERE (((cstr(a.[Id])) in (SELECT b.[Title] query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs index e1dd894b..6b6a02d1 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -19,81 +19,81 @@ namespace FreeSql.Tests.MySql var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb02` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); @@ -111,81 +111,81 @@ UNION ALL var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); @@ -221,27 +221,27 @@ UNION ALL sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '100002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '100003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '100004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb022` a - WHERE (a.`id` = 4) - limit 0,1) + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) ; @@ -265,81 +265,81 @@ INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004' var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) UNION ALL SELECT 2, '02', '02' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) UNION ALL SELECT 3, '03', '03' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 3 AND a.`id2` = '03') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) UNION ALL SELECT 4, '04', '04' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 4 AND a.`id2` = '04') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 1 AND a.`id2` = '01') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) UNION ALL SELECT 2, '02', '002' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 2 AND a.`id2` = '02') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) UNION ALL SELECT 3, '03', '003' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 3 AND a.`id2` = '03') - limit 0,1) + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) UNION ALL SELECT 4, '04', '004' FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb03` a - WHERE (a.`id1` = 4 AND a.`id2` = '04') - limit 0,1)", sql); + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); @@ -361,81 +361,81 @@ UNION ALL var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '02', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '03', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '04', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 1) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) UNION ALL SELECT 2, '002', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 2) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) UNION ALL SELECT 3, '003', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 3) - limit 0,1) + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) UNION ALL SELECT 4, '004', 0, now(3) FROM dual WHERE NOT EXISTS(SELECT 1 - FROM `tbioudb04` a - WHERE (a.`id` = 4) - limit 0,1)", sql); + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index d4166792..29f58ac3 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -104,22 +104,22 @@ namespace FreeSql.Tests.MySql //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -213,9 +213,9 @@ namespace FreeSql.Tests.MySql //); //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) //.Where(a => a.Id == 1).ToSql(); var sql4 = select.From((s, b, c) => s @@ -976,8 +976,8 @@ namespace FreeSql.Tests.MySql count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -994,8 +994,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -1012,8 +1012,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -1030,8 +1030,8 @@ FROM `tb_topic` a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b + limit 0,1) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -1046,7 +1046,7 @@ FROM `tb_topic` a", subquery); Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` - FROM `tb_topic` b)))", subquery); + FROM `tb_topic` b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1124,12 +1124,12 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALL SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); @@ -1157,10 +1157,10 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2 FROM (SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks - FROM `tb_topic_1` a) ftb - + FROM `tb_topic_1` a) ftb + UNION ALL - + SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks FROM `tb_topic_2` a) ftb) a limit 0,20", select diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 0b7888c2..6839731b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -96,22 +96,22 @@ namespace FreeSql.Tests.Oracle //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.oracle.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -856,8 +856,8 @@ namespace FreeSql.Tests.Oracle count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -874,8 +874,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -892,8 +892,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -910,8 +910,8 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 2) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -926,7 +926,7 @@ FROM ""TB_TOPIC22"" a", subquery); Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" FROM ""TB_TOPIC22"" a WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" - FROM ""TB_TOPIC22"" b)))", subquery); + FROM ""TB_TOPIC22"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1005,12 +1005,12 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs b/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs index 788cafab..0dfaa1bc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs +++ b/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs @@ -18,67 +18,67 @@ using FreeSql.DataAnnotations; namespace ZX.Model { - [JsonObject(MemberSerialization.OptIn)] - public class CustomerCheckupGroup { + [JsonObject(MemberSerialization.OptIn)] + public class CustomerCheckupGroup { - [JsonProperty, Column(IsPrimary = true)] - public short ShopId { get => _ShopId; set { - if (_ShopId == value) return; - _ShopId = value; - } } - private short _ShopId; + [JsonProperty, Column(IsPrimary = true)] + public short ShopId { get => _ShopId; set { + if (_ShopId == value) return; + _ShopId = value; + } } + private short _ShopId; - [JsonProperty, Column(DbType = "varchar(50)", IsPrimary = true)] - public string Id { get; set; } + [JsonProperty, Column(DbType = "varchar(50)", IsPrimary = true)] + public string Id { get; set; } - [JsonProperty, Column(DbType = "nvarchar(50)")] - public string MemberId { get => _MemberId; set { - if (_MemberId == value) return; - _MemberId = value; - } } - private string _MemberId; + [JsonProperty, Column(DbType = "nvarchar(50)")] + public string MemberId { get => _MemberId; set { + if (_MemberId == value) return; + _MemberId = value; + } } + private string _MemberId; - [JsonProperty, Column(DbType = "varchar(50)")] - public string Discount { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Discount { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Doctor { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Doctor { get; set; } - [JsonProperty] - public DateTime? FirstTime { get; set; } + [JsonProperty] + public DateTime? FirstTime { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Group { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Group { get; set; } - [JsonProperty] - public DateTime? InsertTime { get; set; } + [JsonProperty] + public DateTime? InsertTime { get; set; } - [JsonProperty, Column(Name = "isOK")] - public bool? IsOK { get; set; } + [JsonProperty, Column(Name = "isOK")] + public bool? IsOK { get; set; } - [JsonProperty, Column(Name = "isPay", DbType = "varchar(50)")] - public string IsPay { get; set; } + [JsonProperty, Column(Name = "isPay", DbType = "varchar(50)")] + public string IsPay { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Office { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Office { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string PayType { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string PayType { get; set; } - [JsonProperty, Column(DbType = "decimal(9,2)")] - public decimal? Price { get; set; } + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? Price { get; set; } - [JsonProperty] - public DateTime? UpdateTime { get; set; } + [JsonProperty] + public DateTime? UpdateTime { get; set; } - [JsonProperty, Column(DbType = "decimal(9,2)")] - public decimal? Value { get; set; } + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? Value { get; set; } - #region 外键 => 导航属性,ManyToOne/OneToOne + #region 外键 => 导航属性,ManyToOne/OneToOne - [Navigate("ShopId, MemberId")] - public virtual CustomerMember CustomerMember { get; set; } + [Navigate("ShopId, MemberId")] + public virtual CustomerMember CustomerMember { get; set; } #endregion #region 外键 => 导航属性,ManyToMany diff --git a/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs b/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs index fabf1500..33c92afe 100644 --- a/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs +++ b/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs @@ -25,84 +25,84 @@ namespace ZX.Model { CheckupGroups = new List(); } - [JsonProperty, Column(DbType = "nvarchar(50)", IsPrimary = true)] - public string MemberId { get; set; } + [JsonProperty, Column(DbType = "nvarchar(50)", IsPrimary = true)] + public string MemberId { get; set; } - [JsonProperty, Column(IsPrimary = true)] - public short ShopId { get; set; } + [JsonProperty, Column(IsPrimary = true)] + public short ShopId { get; set; } - [JsonProperty] - public long? CustomerId { get => _CustomerId; set { - if (_CustomerId == value) return; - _CustomerId = value; - } } - private long? _CustomerId; + [JsonProperty] + public long? CustomerId { get => _CustomerId; set { + if (_CustomerId == value) return; + _CustomerId = value; + } } + private long? _CustomerId; - [JsonProperty, Column(DbType = "varchar(500)")] - public string Address { get; set; } + [JsonProperty, Column(DbType = "varchar(500)")] + public string Address { get; set; } - [JsonProperty, Column(DbType = "smalldatetime")] - public DateTime? Birthday { get; set; } + [JsonProperty, Column(DbType = "smalldatetime")] + public DateTime? Birthday { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string CardNo { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string CardNo { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string CardType { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string CardType { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Doctor { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Doctor { get; set; } - [JsonProperty] - public DateTime? EndDate { get; set; } + [JsonProperty] + public DateTime? EndDate { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Group { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Group { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Marry { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Marry { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Name { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Name { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Part { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Part { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string PayType { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string PayType { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Phone { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Phone { get; set; } - [JsonProperty, Column(DbType = "varchar(10)")] - public string Sex { get; set; } + [JsonProperty, Column(DbType = "varchar(10)")] + public string Sex { get; set; } - [JsonProperty] - public DateTime? StartDate { get; set; } + [JsonProperty] + public DateTime? StartDate { get; set; } - [JsonProperty, Column(DbType = "text")] - public string Suggest { get; set; } + [JsonProperty, Column(DbType = "text")] + public string Suggest { get; set; } - [JsonProperty, Column(DbType = "text")] - public string SumUp { get; set; } + [JsonProperty, Column(DbType = "text")] + public string SumUp { get; set; } - [JsonProperty, Column(DbType = "varchar(50)")] - public string Team { get; set; } + [JsonProperty, Column(DbType = "varchar(50)")] + public string Team { get; set; } - [JsonProperty, Column(DbType = "decimal(9,2)")] - public decimal? TotalFee { get; set; } + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? TotalFee { get; set; } - #region 外键 => 导航属性,ManyToOne/OneToOne + #region 外键 => 导航属性,ManyToOne/OneToOne [Navigate("MemberId,ShopId")] public virtual List CheckupGroups { get; set; } - #endregion + #endregion - #region 外键 => 导航属性,ManyToMany + #region 外键 => 导航属性,ManyToMany - #endregion - } + #endregion + } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 2bede6a8..bd253f74 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -86,22 +86,22 @@ namespace FreeSql.Tests.PostgreSQL //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.pgsql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -189,9 +189,9 @@ namespace FreeSql.Tests.PostgreSQL //); //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) //.Where(a => a.Id == 1).ToSql(); var sql4 = select.From((s, b, c) => s @@ -933,8 +933,8 @@ namespace FreeSql.Tests.PostgreSQL count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT sum(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b + limit 1) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -951,8 +951,8 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT min(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b + limit 1) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -969,8 +969,8 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT max(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b + limit 1) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -987,8 +987,8 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT avg(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b + limit 1) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -1003,7 +1003,7 @@ FROM ""tb_topic"" a", subquery); Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime"" FROM ""tb_topic"" a WHERE ((((a.""id"")::text) in (SELECT b.""title"" - FROM ""tb_topic"" b)))", subquery); + FROM ""tb_topic"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1081,12 +1081,12 @@ WHERE ((((a.""id"")::text) in (SELECT b.""title"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb UNION ALLSELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb UNION ALL SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index 034c1ae3..e18c9ef2 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -85,7 +85,7 @@ namespace FreeSql.Tests.PostgreSQLExpression public void Array() { //g.pgsql.Aop.CurdAfter = (s, e) => { - // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); + // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); //}; IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs index 57b20641..8eca4e32 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs @@ -86,22 +86,22 @@ namespace FreeSql.Tests.ShenTong //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.shentong.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) } [Fact] @@ -189,9 +189,9 @@ namespace FreeSql.Tests.ShenTong //); //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) //.Where(a => a.Id == 1).ToSql(); var sql4 = select.From((s, b, c) => s @@ -933,8 +933,8 @@ namespace FreeSql.Tests.ShenTong count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC"" b - limit 1) as6 + FROM ""TB_TOPIC"" b + limit 1) as6 FROM ""TB_TOPIC"" a", subquery); var subqueryList = select.ToList(a => new { @@ -951,8 +951,8 @@ FROM ""TB_TOPIC"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC"" b - limit 1) as6 + FROM ""TB_TOPIC"" b + limit 1) as6 FROM ""TB_TOPIC"" a", subquery); var subqueryList = select.ToList(a => new { @@ -969,8 +969,8 @@ FROM ""TB_TOPIC"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC"" b - limit 1) as6 + FROM ""TB_TOPIC"" b + limit 1) as6 FROM ""TB_TOPIC"" a", subquery); var subqueryList = select.ToList(a => new { @@ -987,8 +987,8 @@ FROM ""TB_TOPIC"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC"" b - limit 1) as6 + FROM ""TB_TOPIC"" b + limit 1) as6 FROM ""TB_TOPIC"" a", subquery); var subqueryList = select.ToList(a => new { @@ -1003,7 +1003,7 @@ FROM ""TB_TOPIC"" a", subquery); Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" FROM ""TB_TOPIC"" a WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" - FROM ""TB_TOPIC"" b)))", subquery); + FROM ""TB_TOPIC"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1081,12 +1081,12 @@ WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a) ftb UNION ALL SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs index 8c9b039a..573d250f 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs @@ -76,7 +76,7 @@ namespace FreeSql.Tests.ShenTongExpression public void Array() { //g.shentong.Aop.CurdAfter = (s, e) => { - // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); + // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); //}; IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 2e82786a..34377feb 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -96,22 +96,22 @@ namespace FreeSql.Tests.SqlServer //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] //FROM [Tag] a //WHERE (exists(SELECT 1 - // FROM [Tag] t - // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] - // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) - // limit 0,1)) + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) //ManyToMany var t2 = g.sqlserver.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] //FROM [Song] a //WHERE(exists(SELECT 1 - // FROM [Song_tag] Mt_Ms - // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 - // FROM [Tag] t - // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) - // limit 0, 1)) - // limit 0, 1)) + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) var t3 = g.sqlserver.Select().ToList(r => new { @@ -867,7 +867,7 @@ namespace FreeSql.Tests.SqlServer count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -884,7 +884,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -901,7 +901,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -918,7 +918,7 @@ FROM [tb_topic22] a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) - FROM [tb_topic22] b) as6 + FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new { @@ -933,7 +933,7 @@ FROM [tb_topic22] a", subquery); Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] - FROM [tb_topic22] b)))", subquery); + FROM [tb_topic22] b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1011,12 +1011,12 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index 31d25d6a..3845a2d0 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -53,20 +53,20 @@ namespace FreeSql.Tests.SqlServer { //var tt1 = g.sqlserver.Select() - // .LeftJoin(a => a.ParentId == a.Parent.Id) - // .ToSql(a => new { a.Id, a.Title }); + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToSql(a => new { a.Id, a.Title }); //var tt2result = g.sqlserver.Select() - // .LeftJoin(a => a.ParentId == a.Parent.Id) - // .ToList(a => new { a.Id, a.Title }); + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToList(a => new { a.Id, a.Title }); //var tt = g.sqlserver.Select() - // .LeftJoin((a, b) => b.Id == a.Id) - // .ToSql(a => new { a.Id, a.Title }); + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToSql(a => new { a.Id, a.Title }); //var ttresult = g.sqlserver.Select() - // .LeftJoin((a, b) => b.Id == a.Id) - // .ToList(a => new { a.Id, a.Title }); + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToList(a => new { a.Id, a.Title }); var tnsql1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); var tnsql2 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToSql(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs index 07ca702a..46e0685d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs @@ -19,81 +19,81 @@ namespace FreeSql.Tests.Sqlite var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '01' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 1) - limit 0,1)", sql); + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '011' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 1) - limit 0,1)", sql); + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 2, '02' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 2) - limit 0,1)", sql); + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '01' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 1) - limit 0,1) + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1) UNION ALL SELECT 2, '02' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 2) - limit 0,1) + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1) UNION ALL SELECT 3, '03' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 3) - limit 0,1) + FROM ""tbioudb02"" a + WHERE (a.""id"" = 3) + limit 0,1) UNION ALL SELECT 4, '04' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 4) - limit 0,1)", sql); + FROM ""tbioudb02"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '001' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 1) - limit 0,1) + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1) UNION ALL SELECT 2, '002' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 2) - limit 0,1) + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1) UNION ALL SELECT 3, '003' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 3) - limit 0,1) + FROM ""tbioudb02"" a + WHERE (a.""id"" = 3) + limit 0,1) UNION ALL SELECT 4, '004' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb02"" a - WHERE (a.""id"" = 4) - limit 0,1)", sql); + FROM ""tbioudb02"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); @@ -111,81 +111,81 @@ UNION ALL var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '01' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 1) - limit 0,1)", sql); + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '011' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 1) - limit 0,1)", sql); + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 2, '02' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 2) - limit 0,1)", sql); + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '01' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 1) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) UNION ALL SELECT 2, '02' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 2) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) UNION ALL SELECT 3, '03' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 3) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) UNION ALL SELECT 4, '04' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 4) - limit 0,1)", sql); + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '001' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 1) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) UNION ALL SELECT 2, '002' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 2) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) UNION ALL SELECT 3, '003' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 3) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) UNION ALL SELECT 4, '004' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 4) - limit 0,1)", sql); + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); @@ -221,27 +221,27 @@ UNION ALL sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '100001' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 1) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) UNION ALL SELECT 2, '100002' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 2) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) UNION ALL SELECT 3, '100003' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 3) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) UNION ALL SELECT 4, '100004' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb022"" a - WHERE (a.""id"" = 4) - limit 0,1) + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1) ; @@ -265,81 +265,81 @@ INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00 var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '01' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 1 AND a.""id2"" = '01') - limit 0,1)", sql); + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '011' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 1 AND a.""id2"" = '01') - limit 0,1)", sql); + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 2, '02', '02' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 2 AND a.""id2"" = '02') - limit 0,1)", sql); + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '01' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 1 AND a.""id2"" = '01') - limit 0,1) + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1) UNION ALL SELECT 2, '02', '02' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 2 AND a.""id2"" = '02') - limit 0,1) + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1) UNION ALL SELECT 3, '03', '03' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 3 AND a.""id2"" = '03') - limit 0,1) + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 3 AND a.""id2"" = '03') + limit 0,1) UNION ALL SELECT 4, '04', '04' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 4 AND a.""id2"" = '04') - limit 0,1)", sql); + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 4 AND a.""id2"" = '04') + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '001' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 1 AND a.""id2"" = '01') - limit 0,1) + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1) UNION ALL SELECT 2, '02', '002' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 2 AND a.""id2"" = '02') - limit 0,1) + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1) UNION ALL SELECT 3, '03', '003' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 3 AND a.""id2"" = '03') - limit 0,1) + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 3 AND a.""id2"" = '03') + limit 0,1) UNION ALL SELECT 4, '04', '004' WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb03"" a - WHERE (a.""id1"" = 4 AND a.""id2"" = '04') - limit 0,1)", sql); + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 4 AND a.""id2"" = '04') + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); @@ -361,81 +361,81 @@ UNION ALL var sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '01', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 1) - limit 0,1)", sql); + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '011', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 1) - limit 0,1)", sql); + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 2, '02', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 2) - limit 0,1)", sql); + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '01', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 1) - limit 0,1) + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1) UNION ALL SELECT 2, '02', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 2) - limit 0,1) + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1) UNION ALL SELECT 3, '03', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 3) - limit 0,1) + FROM ""tbioudb04"" a + WHERE (a.""id"" = 3) + limit 0,1) UNION ALL SELECT 4, '04', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 4) - limit 0,1)", sql); + FROM ""tbioudb04"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); Assert.Equal(2, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); sql = iou.ToSql(); Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '001', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 1) - limit 0,1) + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1) UNION ALL SELECT 2, '002', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 2) - limit 0,1) + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1) UNION ALL SELECT 3, '003', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 3) - limit 0,1) + FROM ""tbioudb04"" a + WHERE (a.""id"" = 3) + limit 0,1) UNION ALL SELECT 4, '004', 0, datetime(current_timestamp,'localtime') WHERE NOT EXISTS(SELECT 1 - FROM ""tbioudb04"" a - WHERE (a.""id"" = 4) - limit 0,1)", sql); + FROM ""tbioudb04"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); Assert.Equal(0, iou.ExecuteAffrows()); var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index e7201fb6..7cc33e4e 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -91,22 +91,22 @@ namespace FreeSql.Tests.Sqlite //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` //FROM `Tag` a //WHERE (exists(SELECT 1 - // FROM `Tag` t - // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` - // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) - // limit 0,1)) + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) //ManyToMany var t2 = g.sqlite.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` //FROM `Song` a //WHERE(exists(SELECT 1 - // FROM `Song_tag` Mt_Ms - // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 - // FROM `Tag` t - // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) - // limit 0, 1)) - // limit 0, 1)) + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) var t3 = g.sqlite.Select().ToList(r => new { @@ -821,8 +821,8 @@ namespace FreeSql.Tests.Sqlite count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT sum(b.""Id"") - FROM ""tb_topic22"" b - limit 0,1) as6 + FROM ""tb_topic22"" b + limit 0,1) as6 FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -839,8 +839,8 @@ FROM ""tb_topic22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT min(b.""Id"") - FROM ""tb_topic22"" b - limit 0,1) as6 + FROM ""tb_topic22"" b + limit 0,1) as6 FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -857,8 +857,8 @@ FROM ""tb_topic22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT max(b.""Id"") - FROM ""tb_topic22"" b - limit 0,1) as6 + FROM ""tb_topic22"" b + limit 0,1) as6 FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -875,8 +875,8 @@ FROM ""tb_topic22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT avg(b.""Id"") - FROM ""tb_topic22"" b - limit 0,1) as6 + FROM ""tb_topic22"" b + limit 0,1) as6 FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -891,7 +891,7 @@ FROM ""tb_topic22"" a", subquery); Assert.Equal(@"SELECT a.""Id"", a.""Clicks"", a.""TypeGuid"", a.""Title"", a.""CreateTime"" FROM ""tb_topic22"" a WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" - FROM ""tb_topic22"" b)))", subquery); + FROM ""tb_topic22"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } [Fact] @@ -1001,12 +1001,12 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a) ftb UNION ALLSELECT * from (SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a) ftb UNION ALL SELECT * from (SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22\" a) ftb", sql); query.ToList(); query = select.AsTable((_, old) => old).AsTable((_, old) => old); sql = query.ToSql("count(1) as1").Replace("\r\n", ""); - Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"tb_topic22\" a) ftb", sql); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic22\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"tb_topic22\" a) ftb", sql); query.Count(); select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index f8499441..48baf05b 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -183,73 +183,73 @@ namespace FreeSql.Tests { /// /// - /// + /// [Column(Name = "article_id", IsIdentity = true, IsPrimary = true)] public int ArticleId { get; set; } /// /// - /// + /// [Column(Name = "article_title")] public string ArticleTitle { get; set; } /// /// - /// + /// [Column(Name = "category_id")] public int CategoryId { get; set; } /// /// - /// + /// [Column(Name = "channel_id")] public int ChannelId { get; set; } /// /// 类型 - /// + /// [Column(Name = "type_id")] public int TypeId { get; set; } /// /// 内容简介 - /// + /// [Column(Name = "summary")] public string Summary { get; set; } /// /// 缩略图 - /// + /// [Column(Name = "thumbnail")] public string Thumbnail { get; set; } /// /// 点击量 - /// + /// [Column(Name = "hits")] public int Hits { get; set; } /// /// - /// + /// [Column(Name = "is_display")] public int IsDisplay { get; set; } /// /// - /// + /// [Column(Name = "status")] public int Status { get; set; } /// /// - /// + /// [Column(Name = "create_time")] public int CreateTime { get; set; } /// /// - /// + /// [Column(Name = "release_time")] public int ReleaseTime { get; set; } @@ -762,14 +762,14 @@ namespace FreeSql.Tests //var testaddlist = new List(); //for(var a = 0; a < 133905; a++) { - // testaddlist.Add(new NewsArticle { - // ArticleTitle = "testaddlist_topic" + a, - // Hits = a, - // }); + // testaddlist.Add(new NewsArticle { + // ArticleTitle = "testaddlist_topic" + a, + // Hits = a, + // }); //} //g.sqlite.Insert(testaddlist) - // //.NoneParameter() - // .ExecuteAffrows(); + // //.NoneParameter() + // .ExecuteAffrows(); g.mysql.Aop.ParseExpression += (s, e) => @@ -1225,9 +1225,9 @@ namespace FreeSql.Tests //); //var sql4 = select.From((a, b, c) => new SelectFrom() - // .InnerJoin(a.TypeGuid == b.Guid) - // .LeftJoin(c.Id == b.ParentId) - // .Where(b.Name == "xxx")) + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) //.Where(a => a.Id == 1).ToSql(); var sql4 = select.From((s, b, c) => s diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index d85749c3..f27f2600 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -984,7 +984,7 @@ namespace FreeSql.Internal fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); var sql2 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); if (string.IsNullOrEmpty(sql2) == false) - manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace("\r\n", "\r\n\t")})"), Expression.Constant(null)); + manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectWhereSql, Expression.Constant($"exists({sql2.Replace(" \r\n", " \r\n ")})"), Expression.Constant(null)); MethodInfo manySubSelectAggMethod = null; switch (exp3.Method.Name) //https://github.com/dotnetcore/FreeSql/issues/362 { @@ -1031,12 +1031,12 @@ namespace FreeSql.Internal case "Any": var sql = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "1" })?.ToString(); if (string.IsNullOrEmpty(sql) == false) - return $"exists({sql.Replace("\r\n", "\r\n\t")})"; + return $"exists({sql.Replace(" \r\n", " \r\n ")})"; break; case "Count": var sqlCount = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { "count(1)" })?.ToString(); if (string.IsNullOrEmpty(sqlCount) == false) - return $"({sqlCount.Replace("\r\n", "\r\n\t")})"; + return $"({sqlCount.Replace(" \r\n", " \r\n ")})"; break; case "Sum": case "Min": @@ -1047,7 +1047,7 @@ namespace FreeSql.Internal tscClone1._tables = fsqltables; var sqlSum = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone1)})" })?.ToString(); if (string.IsNullOrEmpty(sqlSum) == false) - return $"({sqlSum.Replace("\r\n", "\r\n\t")})"; + return $"({sqlSum.Replace(" \r\n", " \r\n ")})"; break; case "ToList": case "ToOne": @@ -1057,7 +1057,7 @@ namespace FreeSql.Internal tscClone2._tables = fsqltables; var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone2) })?.ToString(); if (string.IsNullOrEmpty(sqlFirst) == false) - return $"({sqlFirst.Replace("\r\n", "\r\n\t")})"; + return $"({sqlFirst.Replace(" \r\n", " \r\n ")})"; break; } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 62e2d64d..93982fd4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -990,7 +990,7 @@ namespace FreeSql.Internal.CommonProvider if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, name); } else - name = name.Replace("\r\n", "\r\n "); + name = name.Replace(" \r\n", " \r\n "); } dict.Add(tb.Table.Type, name); } diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs index c9087dff..2d7e0e73 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Dameng.Curd var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs index b692561a..ff0fbd41 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs @@ -26,7 +26,7 @@ namespace FreeSql.MsAccess.Curd var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index e61d1491..d2fe72dd 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -54,7 +54,7 @@ namespace FreeSql.MySql.Curd .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) .DisableGlobalFilter() .WhereDynamic(rowd) - .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + .Limit(1).ToSql("1").Replace(" \r\n", " \r\n ")).Append(")")); } } if (string.IsNullOrEmpty(sql)) return null; diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index 802bc791..5f1b4966 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.MySql.Curd var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs index b876790a..7a43e528 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.Dameng var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index 7479b256..0ccddfa8 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.Default var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs index 33b21595..8a2af80c 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.KingbaseES var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index c1e7592a..65f8affa 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.MySql .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) .DisableGlobalFilter() .WhereDynamic(rowd) - .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + .Limit(1).ToSql("1").Replace(" \r\n", " \r\n ")).Append(")")); } } if (string.IsNullOrEmpty(sql)) return null; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index 078ec66f..c607f773 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.MySql var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index ccefb0f7..c353b428 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.Oracle var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 86d3e7de..81703262 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Odbc.PostgreSQL var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index 9a6d2cde..f6a91c1b 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -31,7 +31,7 @@ namespace FreeSql.Odbc.SqlServer var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; @@ -146,7 +146,7 @@ namespace FreeSql.Odbc.SqlServer var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 7a725285..9663db7c 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Oracle.Curd var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 80b28769..8b902795 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.PostgreSQL.Curd var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs index f3393d8e..4d78874b 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.ShenTong.Curd var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 024bc957..97994329 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -146,7 +146,7 @@ namespace FreeSql.SqlServer.Curd var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index 696d6920..3d028dbe 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -57,7 +57,7 @@ namespace FreeSql.Sqlite.Curd .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) .DisableGlobalFilter() .WhereDynamic(rowd) - .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + .Limit(1).ToSql("1").Replace(" \r\n", " \r\n ")).Append(")")); } } if (string.IsNullOrEmpty(sql)) return null; diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index bf2af50d..054265fd 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -25,7 +25,7 @@ namespace FreeSql.Sqlite.Curd var tbUnionsGt0 = tbUnions.Count > 1; for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) { - if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); var tbUnion = tbUnions[tbUnionsIdx]; From 4a4647de1d9fe5593089aea9420f33182181ad27 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Jul 2020 07:22:48 +0800 Subject: [PATCH 0757/1029] update MySqlConnector 1.0.0 --- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs | 6 +++++- .../MySqlAdo/MySqlConnectionPool.cs | 8 ++++++-- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 6 +++++- Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs | 6 +++++- Providers/FreeSql.Provider.MySql/MySqlUtils.cs | 4 ++++ .../FreeSql.Provider.MySqlConnector.csproj | 7 +++++-- .../FreeSqlMySqlConnectorGlobalExtensions.cs | 6 +++++- .../MySqlConnectorUtils.cs | 2 +- .../FreeSql.Provider.Oracle.csproj | 4 ++-- readme.md | 2 +- 13 files changed, 41 insertions(+), 30 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 5156e768..046d3b9c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -37,7 +37,7 @@ - + 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/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 15025909..665d61b2 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index 17ea6496..64427c6a 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -1,12 +1,16 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using MySql.Data.MySqlClient; using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; using System.Text; using System.Threading; +#if MySqlConnector +using MySqlConnector; +#else +using MySql.Data.MySqlClient; +#endif namespace FreeSql.MySql { diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 5c3fa614..770194fe 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -1,5 +1,4 @@ -using MySql.Data.MySqlClient; -using FreeSql.Internal.ObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -7,6 +6,11 @@ using System.Data; using System.Data.Common; using System.Text.RegularExpressions; using System.Threading.Tasks; +#if MySqlConnector +using MySqlConnector; +#else +using MySql.Data.MySqlClient; +#endif namespace FreeSql.MySql { diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index b57ae165..7ee233bf 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -1,12 +1,16 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Text.RegularExpressions; +#if MySqlConnector +using MySqlConnector; +#else +using MySql.Data.MySqlClient; +#endif namespace FreeSql.MySql { diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 48a7b416..7253870b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -1,13 +1,17 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; using FreeSql.Internal.Model; -using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Text.RegularExpressions; +#if MySqlConnector +using MySqlConnector; +#else +using MySql.Data.MySqlClient; +#endif namespace FreeSql.MySql { diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index fe49cd80..3986c65b 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -1,6 +1,10 @@ using FreeSql.Internal; using FreeSql.Internal.Model; +#if MySqlConnector +using MySqlConnector; +#else using MySql.Data.MySqlClient; +#endif using System; using System.Collections.Generic; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 911d3bd7..255cb6d9 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -26,13 +26,12 @@ - + - @@ -40,5 +39,9 @@ + + + MySqlConnector + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs index 6b22af02..87c24e7c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs @@ -1,9 +1,13 @@ using FreeSql; -using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; +#if MySqlConnector +using MySqlConnector; +#else +using MySql.Data.MySqlClient; +#endif public static class FreeSqlMySqlConnectorGlobalExtensions { diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 085f2375..df8e23b4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using MySql.Data.MySqlClient; +using MySqlConnector; using System; using System.Collections.Generic; using System.Collections.Concurrent; diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fb5b9009..b8eb1a89 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -26,11 +26,11 @@ - + - + diff --git a/readme.md b/readme.md index be745985..91ef06e9 100644 --- a/readme.md +++ b/readme.md @@ -181,7 +181,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [feijie999](https://github.com/feijie999)、 constantine -(QQ群:4336577) +QQ群:4336577(已满)、8578575(在线) ## 💕  Donation From 8a3823ff2d714a31ee12a4dbd4c4def03529d25d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Jul 2020 08:14:00 +0800 Subject: [PATCH 0758/1029] update readme --- readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 91ef06e9..ecc18614 100644 --- a/readme.md +++ b/readme.md @@ -30,8 +30,9 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ > 学习项目 +- [iusaas.com SaaS 企业应用管理系统](https://github.com/alonsoalon/TenantSite.Server) - [zhontai.net Admin 后台管理系统](https://github.com/zhontai/Admin.Core) -- [A simple and practical CMS implememted by .NET Core 2.2](https://github.com/luoyunchong/lin-cms-dotnetcore) +- [A simple and practical CMS implememted by .NET Core](https://github.com/luoyunchong/lin-cms-dotnetcore) - [内容管理系统](https://github.com/hejiyong/fscms)

From 3e3dd62fd7629398422c7b08beb903df6d61487f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Jul 2020 08:14:58 +0800 Subject: [PATCH 0759/1029] update readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index ecc18614..e273748a 100644 --- a/readme.md +++ b/readme.md @@ -28,7 +28,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - 要么[FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext),有点像efcore的使用习惯; - 要么[FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity),求简单使用这个; -> 学习项目 +> 示范项目 - [iusaas.com SaaS 企业应用管理系统](https://github.com/alonsoalon/TenantSite.Server) - [zhontai.net Admin 后台管理系统](https://github.com/zhontai/Admin.Core) From 7e3eff1f8b3c336356b8bea681163c63a20c2f48 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Jul 2020 10:38:32 +0800 Subject: [PATCH 0760/1029] update MySqlConnector 1.0.0 --- Extensions/FreeSql.Generator/RazorModel.cs | 15 ++++++++------- .../MySqlConnectorExpression/OtherTest.cs | 2 +- .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 1 + .../ShenTong/ShenTongExpression/OtherTest.cs | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 85296c72..8e1d8ca9 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -2,6 +2,7 @@ using FreeSql.DataAnnotations; using FreeSql.DatabaseModel; using FreeSql.Internal.CommonProvider; +using MySqlConnector; using System; using System.Collections.Generic; using System.Linq; @@ -47,7 +48,7 @@ public class RazorModel { public string GetCsType(DbColumnInfo col) { if (fsql.Ado.DataType == FreeSql.DataType.MySql) - if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) + if (col.DbType == (int)MySqlDbType.Enum || col.DbType == (int)MySqlDbType.Set) return $"{this.GetCsName(this.FullTableName)}{this.GetCsName(col.Name).ToUpper()}{(col.IsNullable ? "?" : "")}"; return fsql.DbFirst.GetCsType(col); } @@ -243,7 +244,7 @@ public class RazorModel { if (cstype == typeof(string)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\""; if (cstype == typeof(bool)) return isInsertValueSql ? defval : (defval == "1" || defval == "t" ? "true" : "false"); if (fsql.Ado.DataType == DataType.MySql || fsql.Ado.DataType == DataType.OdbcMySql) - if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) + if (col.DbType == (int)MySqlDbType.Enum || col.DbType == (int)MySqlDbType.Set) if (isInsertValueSql) return (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval); return isInsertValueSql ? defval : null; //sql function or exp } @@ -255,10 +256,10 @@ public class RazorModel { if (fsql.Ado.DataType != FreeSql.DataType.MySql && fsql.Ado.DataType != FreeSql.DataType.OdbcMySql) return null; var sb = new StringBuilder(); foreach (var col in table.Columns) { - if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) { - if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) sb.Append("\r\n\t[Flags]"); + if (col.DbType == (int)MySqlDbType.Enum || col.DbType == (int)MySqlDbType.Set) { + if (col.DbType == (int)MySqlDbType.Set) sb.Append("\r\n\t[Flags]"); sb.Append($"\r\n\tpublic enum {this.GetCsName(this.FullTableName)}{this.GetCsName(col.Name).ToUpper()}"); - if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) sb.Append(" : long"); + if (col.DbType == (int)MySqlDbType.Set) sb.Append(" : long"); sb.Append(" {\r\n\t\t"); string slkdgjlksdjg = ""; @@ -289,9 +290,9 @@ public class RazorModel { ///

[Description(""{0}"")] Unknow{1}", str2.Replace("\"", "\\\""), ++unknow_idx); - if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) + if (col.DbType == (int)MySqlDbType.Set) slkdgjlksdjg += " = " + Math.Pow(2, field_idx++); - if (col.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum && field_idx++ == 0) + if (col.DbType == (int)MySqlDbType.Enum && field_idx++ == 0) slkdgjlksdjg += " = 1"; break; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs index cc32f9b0..ce521316 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/OtherTest.cs @@ -1,5 +1,5 @@ using FreeSql.DataAnnotations; -using MySql.Data.MySqlClient; +using MySqlConnector; using System; using System.Collections.Generic; using System.Linq; diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs index 5143f004..dfbaeb07 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -154,6 +154,7 @@ WHEN NOT MATCHED THEN public int id { get; set; } public string name { get; set; } } + [Fact] public void InsertOrUpdate_OnePrimaryAndIdentity() { fsql.Delete().Where("1=1").ExecuteAffrows(); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs index 573d250f..75c634bb 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/OtherTest.cs @@ -174,7 +174,7 @@ namespace FreeSql.Tests.ShenTongExpression public TableAllTypeEnumType2 testFieldEnum2 { get; set; } public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } - ///* array */ + //* array */ //public bool[] testFieldBoolArray { get; set; } //public sbyte[] testFieldSByteArray { get; set; } //public short[] testFieldShortArray { get; set; } From cff9d3d00c9dc9975c7de4c9464049dc41d9049d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Jul 2020 10:50:23 +0800 Subject: [PATCH 0761/1029] update readme --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index e273748a..6e7db65c 100644 --- a/readme.md +++ b/readme.md @@ -33,6 +33,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [iusaas.com SaaS 企业应用管理系统](https://github.com/alonsoalon/TenantSite.Server) - [zhontai.net Admin 后台管理系统](https://github.com/zhontai/Admin.Core) - [A simple and practical CMS implememted by .NET Core](https://github.com/luoyunchong/lin-cms-dotnetcore) +- [EasyCms 满足企业建站,政府部门、事业单位使用的CMS管理系统](https://github.com/jasonyush/EasyCMS) - [内容管理系统](https://github.com/hejiyong/fscms)

From a363ab82a7b3954b2da6a0facb70bddaa622eaec Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Jul 2020 10:52:30 +0800 Subject: [PATCH 0762/1029] update readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 6e7db65c..f1a89f03 100644 --- a/readme.md +++ b/readme.md @@ -33,7 +33,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [iusaas.com SaaS 企业应用管理系统](https://github.com/alonsoalon/TenantSite.Server) - [zhontai.net Admin 后台管理系统](https://github.com/zhontai/Admin.Core) - [A simple and practical CMS implememted by .NET Core](https://github.com/luoyunchong/lin-cms-dotnetcore) -- [EasyCms 满足企业建站,政府部门、事业单位使用的CMS管理系统](https://github.com/jasonyush/EasyCMS) +- [EasyCms 满足企业建站,事业单位使用的CMS管理系统](https://github.com/jasonyush/EasyCMS) - [内容管理系统](https://github.com/hejiyong/fscms)

From f2f1495efc2f55871283b2a4d648fedc2dc2996a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Jul 2020 15:22:33 +0800 Subject: [PATCH 0763/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IInsert/IUpd?= =?UTF-8?q?ate=20BatchProgress=20=E6=96=B9=E6=B3=95=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=8F=92=E5=85=A5/=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E8=BF=9B=E5=BA=A6=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 6 +- FreeSql/FreeSql.xml | 164 +++++++++++------- FreeSql/Interface/Curd/IInsert.cs | 14 +- FreeSql/Interface/Curd/IUpdate.cs | 14 +- .../Internal/CommonProvider/InsertProvider.cs | 17 ++ .../Internal/CommonProvider/UpdateProvider.cs | 13 ++ .../Internal/Model/BatchProgressEventArgs.cs | 32 ++++ .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 60 ++++--- .../MySql/OdbcMySqlCodeFirst.cs | 60 ++++--- .../SqlServer/OdbcSqlServerCodeFirst.cs | 59 ++++--- .../SqlServerCodeFirst.cs | 59 ++++--- 11 files changed, 325 insertions(+), 173 deletions(-) create mode 100644 FreeSql/Internal/Model/BatchProgressEventArgs.cs diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 44d9bd13..5125fee2 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -433,8 +433,12 @@ namespace FreeSql.Tests new SendInfo{ Code = "002", Binary = Encoding.UTF8.GetBytes("我是地球人") }, new SendInfo{ Code = "003", Binary = Encoding.UTF8.GetBytes("我是.net")}, new SendInfo{ Code = "004", Binary = Encoding.UTF8.GetBytes("我是freesql") }, + new SendInfo{ Code = "005", Binary = Encoding.UTF8.GetBytes("我是freesql233") }, }) - .NoneParameter().ExecuteAffrows(); + .NoneParameter() + .BatchOptions(3, 200) + .BatchProgress(a => Trace.WriteLine($"{a.Current}/{a.Total}")) + .ExecuteAffrows(); var slslsl = g.oracle.Select().ToList(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6a822109..dc3e9926 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1069,11 +1069,18 @@ Sqlite 5000 999 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - 指定根据 values 数量拆分执行 - 指定根据 parameters 数量拆分执行 + 指定根据 values 上限数量拆分执行 + 指定根据 parameters 上限数量拆分执行 是否自动开启事务 + +

+ 批量执行时,分批次执行的进度状态 + + 批量执行时的回调委托 + +
设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; @@ -2142,11 +2149,18 @@ Sqlite 200 999 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - 指定根据 rows 数量拆分执行 - 指定根据 parameters 数量拆分执行 + 指定根据 rows 上限数量拆分执行 + 指定根据 parameters 上限数量拆分执行 是否自动开启事务 + + + 批量执行时,分批次执行的进度状态 + + 批量执行时的回调委托 + + 更新数据,设置更新的实体 @@ -2919,89 +2933,104 @@ 转大写同步结构,适用 Oracle/达梦/人大金仓 - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + - - 不使用命令参数化执行,针对 Insert/Update - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - + - + - 将实体类型集合与数据库对比,返回DDL语句 + 获取c#类型对象 - 实体类型 + - + - 将实体类型与数据库对比,返回DDL语句(指定表名) + 获取ado.net读取方法, GetBoolean、GetInt64 - 实体类型 - 指定表名对比 + - + - 同步实体类型到数据库 - 注意:生产环境中谨慎使用 + 序列化 - + + - + - 同步实体类型集合到数据库 - 注意:生产环境中谨慎使用 + 反序列化 - + + - + - 同步实体类型到数据库(指定表名) - 注意:生产环境中谨慎使用 + 获取数据库枚举类型,适用 PostgreSQL - 实体类型 - 指定表名对比 + + - + - 根据 System.Type 获取数据库信息 + 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 动态读取 DescriptionAttribute 注释文本 - + - FreeSql FluentApi 配置实体,方法名与特性相同 + 通过属性的注释文本,通过 xml 读取 - - + + Dict:key=属性名,value=注释 + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 当前操作的数据 + + + + + 当前批次 + + + + + 总批次数量 + + + + + me="entity"> @@ -3142,6 +3171,21 @@ 表达式 + + + 当前操作的数据 + + + + + 当前批次 + + + + + 总批次数量 + + 动态过滤条件 diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 025f875b..739c046d 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -91,12 +92,19 @@ namespace FreeSql /// Sqlite 5000 999 /// 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 /// - /// 指定根据 values 数量拆分执行 - /// 指定根据 parameters 数量拆分执行 + /// 指定根据 values 上限数量拆分执行 + /// 指定根据 parameters 上限数量拆分执行 /// 是否自动开启事务 /// IInsert BatchOptions(int valuesLimit, int parameterLimit, bool autoTransaction = true); + /// + /// 批量执行时,分批次执行的进度状态 + /// + /// 批量执行时的回调委托 + /// + IInsert BatchProgress(Action> callback); + /// /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; /// diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index cc28b273..c2fd0b2b 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data.Common; using System.Linq.Expressions; @@ -39,12 +40,19 @@ namespace FreeSql /// Sqlite 200 999 /// 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 /// - /// 指定根据 rows 数量拆分执行 - /// 指定根据 parameters 数量拆分执行 + /// 指定根据 rows 上限数量拆分执行 + /// 指定根据 parameters 上限数量拆分执行 /// 是否自动开启事务 /// IUpdate BatchOptions(int rowsLimit, int parameterLimit, bool autoTransaction = true); + /// + /// 批量执行时,分批次执行的进度状态 + /// + /// 批量执行时的回调委托 + /// + IUpdate BatchProgress(Action> callback); + /// /// 更新数据,设置更新的实体 /// diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 281837e2..d60bfa2a 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -26,6 +26,7 @@ namespace FreeSql.Internal.CommonProvider public bool _noneParameter, _insertIdentity; public int _batchValuesLimit, _batchParameterLimit; public bool _batchAutoTransaction = true; + public Action> _batchProgress; public DbParameter[] _params; public DbTransaction _transaction; public DbConnection _connection; @@ -55,6 +56,7 @@ namespace FreeSql.Internal.CommonProvider { _batchValuesLimit = _batchParameterLimit = 0; _batchAutoTransaction = true; + _batchProgress = null; _insertIdentity = false; _source.Clear(); _ignore.Clear(); @@ -96,6 +98,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IInsert BatchProgress(Action> callback) + { + _batchProgress = callback; + return this; + } + public IInsert AppendData(T1 source) { if (source != null) @@ -204,6 +212,7 @@ namespace FreeSql.Internal.CommonProvider } if (ss.Length == 1) { + _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = this.RawExecuteAffrows(); ClearData(); return ret; @@ -221,6 +230,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret += this.RawExecuteAffrows(); } } @@ -236,6 +246,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret += this.RawExecuteAffrows(); } _transaction.Commit(); @@ -276,6 +287,7 @@ namespace FreeSql.Internal.CommonProvider } if (ss.Length == 1) { + _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = this.RawExecuteIdentity(); ClearData(); return ret; @@ -293,6 +305,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); if (a < ss.Length - 1) this.RawExecuteAffrows(); else ret = this.RawExecuteIdentity(); } @@ -309,6 +322,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); if (a < ss.Length - 1) this.RawExecuteAffrows(); else ret = this.RawExecuteIdentity(); } @@ -350,6 +364,7 @@ namespace FreeSql.Internal.CommonProvider } if (ss.Length == 1) { + _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = this.RawExecuteInserted(); ClearData(); return ret; @@ -367,6 +382,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret.AddRange(this.RawExecuteInserted()); } } @@ -382,6 +398,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret.AddRange(this.RawExecuteInserted()); } _transaction.Commit(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 39e62aa4..8fbf566f 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -32,6 +32,7 @@ namespace FreeSql.Internal.CommonProvider public bool _noneParameter; public int _batchRowsLimit, _batchParameterLimit; public bool _batchAutoTransaction = true; + public Action> _batchProgress; public DbTransaction _transaction; public DbConnection _connection; @@ -101,6 +102,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IUpdate BatchProgress(Action> callback) + { + _batchProgress = callback; + return this; + } + protected void ValidateVersionAndThrow(int affrows) { if (_table.VersionColumn != null && _source.Count > 0) @@ -144,6 +151,7 @@ namespace FreeSql.Internal.CommonProvider var ret = 0; if (ss.Length <= 1) { + if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = this.RawExecuteAffrows(); ClearData(); return ret; @@ -161,6 +169,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret += this.RawExecuteAffrows(); } } @@ -176,6 +185,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret += this.RawExecuteAffrows(); } _transaction.Commit(); @@ -211,6 +221,7 @@ namespace FreeSql.Internal.CommonProvider var ret = new List(); if (ss.Length <= 1) { + if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = this.RawExecuteUpdated(); ClearData(); return ret; @@ -228,6 +239,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret.AddRange(this.RawExecuteUpdated()); } } @@ -243,6 +255,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret.AddRange(this.RawExecuteUpdated()); } _transaction.Commit(); diff --git a/FreeSql/Internal/Model/BatchProgressEventArgs.cs b/FreeSql/Internal/Model/BatchProgressEventArgs.cs new file mode 100644 index 00000000..cb5d335b --- /dev/null +++ b/FreeSql/Internal/Model/BatchProgressEventArgs.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; + +namespace FreeSql.Internal.Model +{ + public class BatchProgressStatus + { + /// + /// 当前操作的数据 + /// + public IEnumerable Data { get; } + + /// + /// 当前批次 + /// + public int Current { get; } + + /// + /// 总批次数量 + /// + public int Total { get; } + + public BatchProgressStatus(List data, int current, int total) + { + this.Data = data; + this.Current = current; + this.Total = total; + } + } +} diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 7ee233bf..7b997653 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -6,6 +6,8 @@ using System.Data; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Data.Common; +using FreeSql.Internal.ObjectPool; #if MySqlConnector using MySqlConnector; #else @@ -85,28 +87,15 @@ namespace FreeSql.MySql protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { - var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); - var database = conn.Value.Database; - Func ExecuteScalar = (db, sql) => - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); - try - { - using (var cmd = conn.Value.CreateCommand()) - { - cmd.CommandText = sql; - cmd.CommandType = CommandType.Text; - return cmd.ExecuteScalar(); - } - } - finally - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); - } - }; - var sb = new StringBuilder(); + Object conn = null; + string database = null; + try { + conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + database = conn.Value.Database; + + var sb = new StringBuilder(); foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -129,17 +118,17 @@ namespace FreeSql.MySql } } - if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 + if (string.Compare(tbname[0], database, true) != 0 && LocalExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n"); var sbalter = new StringBuilder(); var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (ExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) + if (LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) { //表不存在 if (tboldname != null) { - if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null || - ExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null) + if (string.Compare(tboldname[0], tbname[0], true) != 0 && LocalExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null || + LocalExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null) //数据库或表不存在 tboldname = null; } @@ -222,7 +211,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); if (istmpatler == false) { - var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); + var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); foreach (var tbcol in tb.ColumnsByPosition) { var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; @@ -385,7 +374,8 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI { try { - conn.Value.ChangeDatabase(database); + if (string.IsNullOrEmpty(database) == false) + conn.Value.ChangeDatabase(database); _orm.Ado.MasterPool.Return(conn); } catch @@ -393,6 +383,24 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI _orm.Ado.MasterPool.Return(conn, true); } } + + object LocalExecuteScalar(string db, string sql) + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + } } } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 4832a458..6fc5f92d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -1,8 +1,10 @@ using FreeSql.Internal; using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Data.Odbc; using System.Linq; using System.Text; @@ -74,28 +76,15 @@ namespace FreeSql.Odbc.MySql protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { - var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); - var database = conn.Value.Database; - Func ExecuteScalar = (db, sql) => - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); - try - { - using (var cmd = conn.Value.CreateCommand()) - { - cmd.CommandText = sql; - cmd.CommandType = CommandType.Text; - return cmd.ExecuteScalar(); - } - } - finally - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); - } - }; - var sb = new StringBuilder(); + Object conn = null; + string database = null; + try { + conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + database = conn.Value.Database; + + var sb = new StringBuilder(); foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -118,17 +107,17 @@ namespace FreeSql.Odbc.MySql } } - if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 + if (string.Compare(tbname[0], database, true) != 0 && LocalExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n"); var sbalter = new StringBuilder(); var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (ExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) + if (LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) { //表不存在 if (tboldname != null) { - if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null || - ExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null) + if (string.Compare(tboldname[0], tbname[0], true) != 0 && LocalExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null || + LocalExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null) //数据库或表不存在 tboldname = null; } @@ -211,7 +200,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); if (istmpatler == false) { - var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); + var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); foreach (var tbcol in tb.ColumnsByPosition) { var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; @@ -374,7 +363,8 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI { try { - conn.Value.ChangeDatabase(database); + if (string.IsNullOrEmpty(database) == false) + conn.Value.ChangeDatabase(database); _orm.Ado.MasterPool.Return(conn); } catch @@ -382,6 +372,24 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI _orm.Ado.MasterPool.Return(conn, true); } } + + object LocalExecuteScalar(string db, string sql) + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + } } public override int ExecuteDDLStatements(string ddl) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index f319e1cb..8636b79b 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -1,8 +1,10 @@ using FreeSql.Internal; using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Data.Odbc; using System.Linq; using System.Text; @@ -134,30 +136,15 @@ ELSE } protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { - var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + Object conn = null; string database = null; + try { + conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); database = conn.Value.Database; - Func ExecuteScalar = (db, sql) => - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); - try - { - using (var cmd = conn.Value.CreateCommand()) - { - cmd.CommandText = sql; - cmd.CommandType = CommandType.Text; - return cmd.ExecuteScalar(); - } - } - finally - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); - } - }; - var sb = new StringBuilder(); + var sb = new StringBuilder(); foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -184,20 +171,20 @@ ELSE } //codefirst 不支持表名、模式名、数据库名中带 . - if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 - ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); - if (string.Compare(tbname[1], "dbo", true) != 0 && ExecuteScalar(tbname[0], $" select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 - ExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); + if (string.Compare(tbname[0], database, true) != 0 && LocalExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 + LocalExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); + if (string.Compare(tbname[1], "dbo", true) != 0 && LocalExecuteScalar(tbname[0], $" select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 + LocalExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); var sbalter = new StringBuilder(); var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (ExecuteScalar(tbname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tbname[1]}].[{tbname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + if (LocalExecuteScalar(tbname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tbname[1]}].[{tbname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) { //表不存在 if (tboldname != null) { - if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tboldname[0]}'") == null || - string.Compare(tboldname[1], tbname[1], true) != 0 && ExecuteScalar(tboldname[0], $" select 1 from sys.schemas where name='{tboldname[1]}'") == null || - ExecuteScalar(tboldname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tboldname[1]}].[{tboldname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + if (string.Compare(tboldname[0], tbname[0], true) != 0 && LocalExecuteScalar(database, $" select 1 from sys.databases where name='{tboldname[0]}'") == null || + string.Compare(tboldname[1], tbname[1], true) != 0 && LocalExecuteScalar(tboldname[0], $" select 1 from sys.schemas where name='{tboldname[1]}'") == null || + LocalExecuteScalar(tboldname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tboldname[1]}].[{tboldname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) //数据库或模式或表不存在 tboldname = null; } @@ -477,6 +464,24 @@ use [" + database + "];", tboldname ?? tbname); _orm.Ado.MasterPool.Return(conn, true); } } + + object LocalExecuteScalar(string db, string sql) + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + } } string GetTransferDbDefaultValue(ColumnInfo col) { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index ff1ab63a..a62f4e24 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -1,8 +1,10 @@ using FreeSql.Internal; using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; using System.Linq; using System.Text; @@ -133,30 +135,15 @@ ELSE } protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { - var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + Object conn = null; string database = null; + try { + conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); database = conn.Value.Database; - Func ExecuteScalar = (db, sql) => - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); - try - { - using (var cmd = conn.Value.CreateCommand()) - { - cmd.CommandText = sql; - cmd.CommandType = CommandType.Text; - return cmd.ExecuteScalar(); - } - } - finally - { - if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); - } - }; - var sb = new StringBuilder(); + var sb = new StringBuilder(); foreach (var obj in objects) { if (sb.Length > 0) sb.Append("\r\n"); @@ -183,20 +170,20 @@ ELSE } //codefirst 不支持表名、模式名、数据库名中带 . - if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 - ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); - if (string.Compare(tbname[1], "dbo", true) != 0 && ExecuteScalar(tbname[0], $" select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 - ExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); + if (string.Compare(tbname[0], database, true) != 0 && LocalExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 + LocalExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];"); + if (string.Compare(tbname[1], "dbo", true) != 0 && LocalExecuteScalar(tbname[0], $" select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 + LocalExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); var sbalter = new StringBuilder(); var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 - if (ExecuteScalar(tbname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tbname[1]}].[{tbname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + if (LocalExecuteScalar(tbname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tbname[1]}].[{tbname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) { //表不存在 if (tboldname != null) { - if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tboldname[0]}'") == null || - string.Compare(tboldname[1], tbname[1], true) != 0 && ExecuteScalar(tboldname[0], $" select 1 from sys.schemas where name='{tboldname[1]}'") == null || - ExecuteScalar(tboldname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tboldname[1]}].[{tboldname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + if (string.Compare(tboldname[0], tbname[0], true) != 0 && LocalExecuteScalar(database, $" select 1 from sys.databases where name='{tboldname[0]}'") == null || + string.Compare(tboldname[1], tbname[1], true) != 0 && LocalExecuteScalar(tboldname[0], $" select 1 from sys.schemas where name='{tboldname[1]}'") == null || + LocalExecuteScalar(tboldname[0], $" select 1 from dbo.sysobjects where id = object_id(N'[{tboldname[1]}].[{tboldname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) //数据库或模式或表不存在 tboldname = null; } @@ -476,6 +463,24 @@ use [" + database + "];", tboldname ?? tbname); _orm.Ado.MasterPool.Return(conn, true); } } + + object LocalExecuteScalar(string db, string sql) + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + try + { + using (var cmd = conn.Value.CreateCommand()) + { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); + } + } + finally + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); + } + } } string GetTransferDbDefaultValue(ColumnInfo col) { From cd60c9dbd9481bed490a583fe270d1d23f6a4190 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 21 Jul 2020 17:40:30 +0800 Subject: [PATCH 0764/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect=20To?= =?UTF-8?q?Chunk=20=E5=81=9C=E6=AD=A2=E8=AF=BB=E5=8F=96=E7=9A=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E6=8E=A7=E5=88=B6=20#360=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs/Program.cs | 4 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++ .../MySqlAdoTest.cs | 24 +-- .../Curd/OnDuplicateKeyUpdateTest.cs | 64 ++++---- FreeSql/FreeSql.xml | 144 ++++++++-------- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 2 +- FreeSql/Interface/IAdo.cs | 26 +-- .../CommonProvider/AdoProvider/AdoProvider.cs | 154 +++++++++--------- .../AdoProvider/AdoProviderAsync.cs | 154 +++++++++--------- .../SelectProvider/Select0Provider.cs | 70 ++++---- FreeSql/Internal/Model/FetchCallbackArgs.cs | 16 ++ 11 files changed, 356 insertions(+), 318 deletions(-) create mode 100644 FreeSql/Internal/Model/FetchCallbackArgs.cs diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 0a1b1ef5..929ebbf7 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -365,9 +365,9 @@ namespace orm_vs var testlist1 = fsql.Select().OrderBy(a => a.id).ToList(); var testlist2 = new List(); - fsql.Select().OrderBy(a => a.id).ToChunk(0, list => + fsql.Select().OrderBy(a => a.id).ToChunk(2, fetch => { - testlist2.AddRange(list); + testlist2.AddRange(fetch.Object); }); //sugar.Aop.OnLogExecuted = (s, e) => diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs index 3a792b77..85056d7b 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs @@ -170,14 +170,14 @@ namespace FreeSql.Tests.PerformanceTest time.Restart(); var adolist1 = new List(); - g.mysql.Ado.ExecuteReader(dr => + g.mysql.Ado.ExecuteReader(fetch => { var xim = new xxx(); - dr.GetValue(0); - dr.GetValue(1); - dr.GetValue(2); - dr.GetValue(3); - dr.GetValue(4); + fetch.Object.GetValue(0); + fetch.Object.GetValue(1); + fetch.Object.GetValue(2); + fetch.Object.GetValue(3); + fetch.Object.GetValue(4); adolist1.Add(xim); }, "select * from freesql_song"); time.Stop(); @@ -185,14 +185,14 @@ namespace FreeSql.Tests.PerformanceTest time.Restart(); adolist1 = new List(); - g.mysql.Ado.ExecuteReader(dr => + g.mysql.Ado.ExecuteReader(fetch => { var xim = new xxx(); - dr.GetFieldValue(0); - dr.GetFieldValue(1); - dr.GetFieldValue(2); - dr.GetFieldValue(3); - dr.GetFieldValue(4); + fetch.Object.GetFieldValue(0); + fetch.Object.GetFieldValue(1); + fetch.Object.GetFieldValue(2); + fetch.Object.GetFieldValue(3); + fetch.Object.GetFieldValue(4); adolist1.Add(xim); }, "select * from freesql_song"); time.Stop(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs index 81ad6cab..e3fa639d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/OnDuplicateKeyUpdateTest.cs @@ -21,10 +21,10 @@ namespace FreeSql.Tests.MySqlConnector { g.mysql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = VALUES(`time`)"); +`time` = VALUES(`time`)", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -32,10 +32,10 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = VALUES(`time`)"); +`time` = VALUES(`time`)", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -44,10 +44,10 @@ ON DUPLICATE KEY UPDATE { g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -55,21 +55,21 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), `time` = CASE `id` WHEN 200 THEN '2000-01-01 00:00:00.000' WHEN 201 THEN '2000-01-01 00:00:00.000' -WHEN 202 THEN '2000-01-01 00:00:00.000' END"); +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') ON DUPLICATE KEY UPDATE -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -77,12 +77,12 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } }).IgnoreColumns(a => a.time).NoneParameter().OnDuplicateKeyUpdate().IgnoreColumns(a => a.title); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') ON DUPLICATE KEY UPDATE `time` = CASE `id` WHEN 200 THEN '2000-01-01 00:00:00.000' WHEN 201 THEN '2000-01-01 00:00:00.000' -WHEN 202 THEN '2000-01-01 00:00:00.000' END"); +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -91,10 +91,10 @@ WHEN 202 THEN '2000-01-01 00:00:00.000' END"); { g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -102,21 +102,21 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate(); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON DUPLICATE KEY UPDATE `title` = VALUES(`title`), `time` = CASE `id` WHEN 300 THEN '2000-01-01 00:00:00.000' WHEN 301 THEN '2000-01-01 00:00:00.000' -WHEN 302 THEN '2000-01-01 00:00:00.000' END"); +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') ON DUPLICATE KEY UPDATE -`time` = '2000-01-01 00:00:00.000'"); +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -124,12 +124,12 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } }).InsertColumns(a => a.title).NoneParameter().OnDuplicateKeyUpdate().UpdateColumns(a => a.time); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') ON DUPLICATE KEY UPDATE `time` = CASE `id` WHEN 300 THEN '2000-01-01 00:00:00.000' WHEN 301 THEN '2000-01-01 00:00:00.000' -WHEN 302 THEN '2000-01-01 00:00:00.000' END"); +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); odku2.ExecuteAffrows(); } @@ -138,9 +138,9 @@ WHEN 302 THEN '2000-01-01 00:00:00.000' END"); { g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); var odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); var odku2 = g.mysql.Insert(new[] { @@ -148,18 +148,18 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time, DateTime.Parse("2020-1-1")); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); odku2.ExecuteAffrows(); var dt2020 = DateTime.Parse("2020-1-1"); g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -167,17 +167,17 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => a.time == dt2020); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000'"); +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); odku2.ExecuteAffrows(); g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); odku1 = g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); - Assert.Equal(odku1.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku1.ToSql()); Assert.Equal(1, odku1.ExecuteAffrows()); odku2 = g.mysql.Insert(new[] { @@ -185,9 +185,9 @@ ON DUPLICATE KEY UPDATE new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } }).NoneParameter().OnDuplicateKeyUpdate().Set(a => new { time = dt2020, title = a.title + "123" }); - Assert.Equal(odku2.ToSql(), @"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') ON DUPLICATE KEY UPDATE -`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')"); +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku2.ToSql()); odku2.ExecuteAffrows(); } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index dc3e9926..2fcf5adc 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1250,7 +1250,7 @@ false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 @@ -2401,16 +2401,16 @@ 当前线程的事务 - + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - + - + 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) @@ -2532,7 +2532,7 @@ - + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 @@ -2541,7 +2541,7 @@ - + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) @@ -2933,104 +2933,89 @@ 转大写同步结构,适用 Oracle/达梦/人大金仓 - - - - + - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - + - AsType, Ctor, ClearData 三处地方需要重新加载 + 不使用命令参数化执行,针对 Insert/Update - + - 动态读取 DescriptionAttribute 注释文本 + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - + - 通过属性的注释文本,通过 xml 读取 + 延时加载导航属性对象,导航属性需要声明 virtual - - Dict:key=属性名,value=注释 - + - 创建一个过滤器 + 将实体类型与数据库对比,返回DDL语句 - 名字 - 表达式 - + - 当前操作的数据 + 将实体类型集合与数据库对比,返回DDL语句 + 实体类型 + - + - 当前批次 + 将实体类型与数据库对比,返回DDL语句(指定表名) + 实体类型 + 指定表名对比 + - + - 总批次数量 + 同步实体类型到数据库 + 注意:生产环境中谨慎使用 + - + - me="entity"> + 同步实体类型集合到数据库 + 注意:生产环境中谨慎使用 + + + + + + 同步实体类型到数据库(指定表名) + 注意:生产环境中谨慎使用 + + 实体类型 + 指定表名对比 + + + + 根据 System.Type 获取数据库信息 + + + + + + + FreeSql FluentApi 配置实体,方法名与特性相同 + + + @@ -3298,6 +3283,11 @@ 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 + + + 是否放弃继续读取 + + 中间表,多对多 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 101503ed..a7b61482 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -79,7 +79,7 @@ namespace FreeSql /// 数据块的大小 /// 处理数据块 /// false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - void ToChunk(int size, Action> done, bool includeNestedMembers = false); + void ToChunk(int size, Action>> done, bool includeNestedMembers = false); /// /// 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 /// diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index dade30c1..02626f8e 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -58,21 +58,21 @@ namespace FreeSql /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 /// - /// + /// /// /// /// - void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// /// /// - void ExecuteReader(Action readerHander, string cmdText, object parms = null); - void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null); - void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, string cmdText, object parms = null); + void ExecuteReader(Action> fetchHandler, string cmdText, object parms = null); + void ExecuteReader(DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null); + void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null); /// /// 查询 /// @@ -235,17 +235,17 @@ namespace FreeSql /// /// /// - Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// /// /// - Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null); - Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(Func, Task> readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null); /// /// 查询 /// diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 8d1d81d7..613f0e85 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -109,15 +109,15 @@ namespace FreeSql.Internal.CommonProvider string flag = null; int[] indexes = null; var props = GetQueryTypeProperties(type); - ExecuteReader(connection, transaction, dr => + ExecuteReader(connection, transaction, fetch => { if (indexes == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -125,7 +125,7 @@ namespace FreeSql.Internal.CommonProvider indexes = props.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag = sbflag.ToString(); } - ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); + ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, fetch.Object, 0, _util).Value); }, cmdType, cmdText, cmdParms); return ret; } @@ -149,7 +149,7 @@ namespace FreeSql.Internal.CommonProvider string flag2 = null; int[] indexes2 = null; var props2 = GetQueryTypeProperties(type2); - ExecuteReaderMultiple(2, connection, transaction, (dr, result) => + ExecuteReaderMultiple(2, connection, transaction, (fetch, result) => { switch (result) { @@ -158,9 +158,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -168,16 +168,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -185,7 +185,7 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; } }, cmdType, cmdText, cmdParms); @@ -217,7 +217,7 @@ namespace FreeSql.Internal.CommonProvider string flag3 = null; int[] indexes3 = null; var props3 = GetQueryTypeProperties(type3); - ExecuteReaderMultiple(3, connection, transaction, (dr, result) => + ExecuteReaderMultiple(3, connection, transaction, (fetch, result) => { switch (result) { @@ -226,9 +226,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -236,16 +236,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -253,16 +253,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -270,7 +270,7 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; } }, cmdType, cmdText, cmdParms); @@ -308,7 +308,7 @@ namespace FreeSql.Internal.CommonProvider string flag4 = null; int[] indexes4 = null; var props4 = GetQueryTypeProperties(type4); - ExecuteReaderMultiple(4, connection, transaction, (dr, result) => + ExecuteReaderMultiple(4, connection, transaction, (fetch, result) => { switch (result) { @@ -317,9 +317,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -327,16 +327,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -344,16 +344,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -361,16 +361,16 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; case 3: if (indexes4 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -378,7 +378,7 @@ namespace FreeSql.Internal.CommonProvider indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag4 = sbflag.ToString(); } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; } }, cmdType, cmdText, cmdParms); @@ -422,7 +422,7 @@ namespace FreeSql.Internal.CommonProvider string flag5 = null; int[] indexes5 = null; var props5 = GetQueryTypeProperties(type5); - ExecuteReaderMultiple(5, connection, transaction, (dr, result) => + ExecuteReaderMultiple(5, connection, transaction, (fetch, result) => { switch (result) { @@ -431,9 +431,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -441,16 +441,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -458,16 +458,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -475,16 +475,16 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; case 3: if (indexes4 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -492,16 +492,16 @@ namespace FreeSql.Internal.CommonProvider indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag4 = sbflag.ToString(); } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; case 4: if (indexes5 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -509,7 +509,7 @@ namespace FreeSql.Internal.CommonProvider indexes5 = props5.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag5 = sbflag.ToString(); } - ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); + ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, fetch.Object, 0, _util).Value); break; } }, cmdType, cmdText, cmdParms); @@ -517,13 +517,13 @@ namespace FreeSql.Internal.CommonProvider } #endregion - public void ExecuteReader(Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(connection, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, readerHander, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, readerHander, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (dr, result) => readerHander(dr), cmdType, cmdText, cmdParms); - void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public void ExecuteReader(Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(null, null, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(null, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(connection, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, fetchHandler, cmdType, cmdText, cmdParms); + public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, fetchHandler, cmdType, cmdText, cmdParms); + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => fetchHandler(fetch), cmdType, cmdText, cmdParms); + void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action, int> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -586,7 +586,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - ExecuteReaderMultiple(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); + ExecuteReaderMultiple(multipleResult, connection, transaction, fetchHandler, cmdType, cmdText, cmdParms); return; } } @@ -603,6 +603,7 @@ namespace FreeSql.Internal.CommonProvider using (var dr = pc.cmd.ExecuteReader()) { int resultIndex = 0; + var fetch = new FetchCallbackArgs { Object = dr }; while (true) { while (true) @@ -610,8 +611,15 @@ namespace FreeSql.Internal.CommonProvider bool isread = dr.Read(); if (isread == false) break; - if (readerHander != null) - readerHander(dr, resultIndex); + if (fetchHandler != null) + { + fetchHandler(fetch, resultIndex); + if (fetch.IsBreak) + { + resultIndex = multipleResult; + break; + } + } } if (++resultIndex >= multipleResult || dr.NextResult() == false) break; } @@ -649,10 +657,10 @@ namespace FreeSql.Internal.CommonProvider public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { List ret = new List(); - ExecuteReader(connection, transaction, dr => + ExecuteReader(connection, transaction, fetch => { - object[] values = new object[dr.FieldCount]; - dr.GetValues(values); + object[] values = new object[fetch.Object.FieldCount]; + fetch.Object.GetValues(values); ret.Add(values); }, cmdType, cmdText, cmdParms); return ret.ToArray(); @@ -666,20 +674,20 @@ namespace FreeSql.Internal.CommonProvider { var ret = new DataSet(); DataTable dt = null; - ExecuteReaderMultiple(16, connection, transaction, (dr, result) => + ExecuteReaderMultiple(16, connection, transaction, (fetch, result) => { if (ret.Tables.Count <= result) { dt = ret.Tables.Add(); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - dt.Columns.Add(name, dr.GetFieldType(a)); + dt.Columns.Add(name, fetch.Object.GetFieldType(a)); } } object[] values = new object[dt.Columns.Count]; - dr.GetValues(values); + fetch.Object.GetValues(values); dt.Rows.Add(values); }, cmdType, cmdText, cmdParms); return ret; @@ -692,17 +700,17 @@ namespace FreeSql.Internal.CommonProvider public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); - ExecuteReader(connection, transaction, dr => + ExecuteReader(connection, transaction, fetch => { if (ret.Columns.Count == 0) - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - ret.Columns.Add(name, dr.GetFieldType(a)); + ret.Columns.Add(name, fetch.Object.GetFieldType(a)); } object[] values = new object[ret.Columns.Count]; - dr.GetValues(values); + fetch.Object.GetValues(values); ret.Rows.Add(values); }, cmdType, cmdText, cmdParms); return ret; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 92e873e3..612ff0b2 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -29,15 +29,15 @@ namespace FreeSql.Internal.CommonProvider string flag = null; int[] indexes = null; var props = GetQueryTypeProperties(type); - await ExecuteReaderAsync(connection, transaction, dr => + await ExecuteReaderAsync(connection, transaction, fetch => { if (indexes == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -45,7 +45,7 @@ namespace FreeSql.Internal.CommonProvider indexes = props.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag = sbflag.ToString(); } - ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, dr, 0, _util).Value); + ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, fetch.Object, 0, _util).Value); return Task.FromResult(false); }, cmdType, cmdText, cmdParms); return ret; @@ -70,7 +70,7 @@ namespace FreeSql.Internal.CommonProvider string flag2 = null; int[] indexes2 = null; var props2 = GetQueryTypeProperties(type2); - await ExecuteReaderMultipleAsync(2, connection, transaction, (dr, result) => + await ExecuteReaderMultipleAsync(2, connection, transaction, (fetch, result) => { switch (result) { @@ -79,9 +79,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -89,16 +89,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -106,7 +106,7 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; } return Task.FromResult(false); @@ -139,7 +139,7 @@ namespace FreeSql.Internal.CommonProvider string flag3 = null; int[] indexes3 = null; var props3 = GetQueryTypeProperties(type3); - await ExecuteReaderMultipleAsync(3, connection, transaction, (dr, result) => + await ExecuteReaderMultipleAsync(3, connection, transaction, (fetch, result) => { switch (result) { @@ -148,9 +148,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -158,16 +158,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -175,16 +175,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -192,7 +192,7 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; } return Task.FromResult(false); @@ -231,7 +231,7 @@ namespace FreeSql.Internal.CommonProvider string flag4 = null; int[] indexes4 = null; var props4 = GetQueryTypeProperties(type4); - await ExecuteReaderMultipleAsync(4, connection, transaction, (dr, result) => + await ExecuteReaderMultipleAsync(4, connection, transaction, (fetch, result) => { switch (result) { @@ -240,9 +240,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -250,16 +250,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -267,16 +267,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -284,16 +284,16 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; case 3: if (indexes4 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -301,7 +301,7 @@ namespace FreeSql.Internal.CommonProvider indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag4 = sbflag.ToString(); } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; } return Task.FromResult(false); @@ -346,7 +346,7 @@ namespace FreeSql.Internal.CommonProvider string flag5 = null; int[] indexes5 = null; var props5 = GetQueryTypeProperties(type5); - await ExecuteReaderMultipleAsync(5, connection, transaction, (dr, result) => + await ExecuteReaderMultipleAsync(5, connection, transaction, (fetch, result) => { switch (result) { @@ -355,9 +355,9 @@ namespace FreeSql.Internal.CommonProvider { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -365,16 +365,16 @@ namespace FreeSql.Internal.CommonProvider indexes1 = props1.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag1 = sbflag.ToString(); } - ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, dr, 0, _util).Value); + ret1.Add((T1)Utils.ExecuteArrayRowReadClassOrTuple(flag1, type1, indexes1, fetch.Object, 0, _util).Value); break; case 1: if (indexes2 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -382,16 +382,16 @@ namespace FreeSql.Internal.CommonProvider indexes2 = props2.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag2 = sbflag.ToString(); } - ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, dr, 0, _util).Value); + ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; case 2: if (indexes3 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -399,16 +399,16 @@ namespace FreeSql.Internal.CommonProvider indexes3 = props3.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag3 = sbflag.ToString(); } - ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, dr, 0, _util).Value); + ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; case 3: if (indexes4 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -416,16 +416,16 @@ namespace FreeSql.Internal.CommonProvider indexes4 = props4.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag4 = sbflag.ToString(); } - ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, dr, 0, _util).Value); + ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; case 4: if (indexes5 == null) { var sbflag = new StringBuilder().Append("adoQuery"); var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dic.ContainsKey(name)) continue; sbflag.Append(name).Append(":").Append(a).Append(","); dic.Add(name, a); @@ -433,7 +433,7 @@ namespace FreeSql.Internal.CommonProvider indexes5 = props5.Select(a => dic.TryGetValue(a.Key, out var tryint) ? tryint : -1).ToArray(); flag5 = sbflag.ToString(); } - ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, dr, 0, _util).Value); + ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, fetch.Object, 0, _util).Value); break; } return Task.FromResult(false); @@ -442,13 +442,13 @@ namespace FreeSql.Internal.CommonProvider } #endregion - public Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, readerHander, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, readerHander, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (dr, result) => readerHander(dr), cmdType, cmdText, cmdParms); - async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteReaderAsync(Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, cmdParms); + public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, cmdParms); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), cmdType, cmdText, cmdParms); + async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -511,7 +511,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, readerHander, cmdType, cmdText, cmdParms); + await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, fetchHandler, cmdType, cmdText, cmdParms); return; } } @@ -528,6 +528,7 @@ namespace FreeSql.Internal.CommonProvider using (var dr = await pc.cmd.ExecuteReaderAsync()) { int resultIndex = 0; + var fetch = new FetchCallbackArgs { Object = dr }; while (true) { while (true) @@ -535,8 +536,15 @@ namespace FreeSql.Internal.CommonProvider bool isread = await dr.ReadAsync(); if (isread == false) break; - if (readerHander != null) - await readerHander(dr, resultIndex); + if (fetchHandler != null) + { + await fetchHandler(fetch, resultIndex); + if (fetch.IsBreak) + { + resultIndex = multipleResult; + break; + } + } } if (++resultIndex >= multipleResult || dr.NextResult() == false) break; } @@ -571,10 +579,10 @@ namespace FreeSql.Internal.CommonProvider async public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { List ret = new List(); - await ExecuteReaderAsync(connection, transaction, async dr => + await ExecuteReaderAsync(connection, transaction, async fetch => { - object[] values = new object[dr.FieldCount]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + object[] values = new object[fetch.Object.FieldCount]; + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); ret.Add(values); }, cmdType, cmdText, cmdParms); return ret.ToArray(); @@ -589,20 +597,20 @@ namespace FreeSql.Internal.CommonProvider { var ret = new DataSet(); DataTable dt = null; - await ExecuteReaderMultipleAsync(16, connection, transaction, async (dr, result) => + await ExecuteReaderMultipleAsync(16, connection, transaction, async (fetch, result) => { if (ret.Tables.Count <= result) { dt = ret.Tables.Add(); - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - dt.Columns.Add(name, dr.GetFieldType(a)); + dt.Columns.Add(name, fetch.Object.GetFieldType(a)); } } object[] values = new object[dt.Columns.Count]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); dt.Rows.Add(values); }, cmdType, cmdText, cmdParms); return ret; @@ -615,17 +623,17 @@ namespace FreeSql.Internal.CommonProvider async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); - await ExecuteReaderAsync(connection, transaction, async dr => + await ExecuteReaderAsync(connection, transaction, async fetch => { if (ret.Columns.Count == 0) - for (var a = 0; a < dr.FieldCount; a++) + for (var a = 0; a < fetch.Object.FieldCount; a++) { - var name = dr.GetName(a); + var name = fetch.Object.GetName(a); if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - ret.Columns.Add(name, dr.GetFieldType(a)); + ret.Columns.Add(name, fetch.Object.GetFieldType(a)); } object[] values = new object[ret.Columns.Count]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); ret.Rows.Add(values); }, cmdType, cmdText, cmdParms); return ret; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 93982fd4..b223326c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -341,9 +341,9 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); ret.Add((TTuple)read.Value); }, CommandType.Text, sql, dbParms); } @@ -368,14 +368,14 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { - ret.Add(af.Read(_orm, dr)); + ret.Add(af.Read(_orm, fetch.Object)); if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); } }, CommandType.Text, sql, dbParms); } @@ -409,37 +409,37 @@ namespace FreeSql.Internal.CommonProvider return ToListAfPrivate(sql, af, otherData); } #region ToChunk - internal void ToListAfChunkPrivate(int chunkSize, Action> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + internal void ToListAfChunkPrivate(int chunkSize, Action>> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); + var ret = new FetchCallbackArgs> { Object = new List() }; var retCount = 0; Exception exception = null; var checkDoneTimes = 0; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { - ret.Add(af.Read(_orm, dr)); + ret.Object.Add(af.Read(_orm, fetch.Object)); retCount++; if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); } - if (chunkSize > 0 && chunkSize == ret.Count) + if (chunkSize > 0 && chunkSize == ret.Object.Count) { checkDoneTimes++; - foreach (var include in _includeToList) include?.Invoke(ret); - _trackToList?.Invoke(ret); + foreach (var include in _includeToList) include?.Invoke(ret.Object); + _trackToList?.Invoke(ret.Object); chunkDone(ret); - + fetch.IsBreak = ret.IsBreak; - ret.Clear(); + ret.Object.Clear(); if (otherData != null) foreach (var other in otherData) other.retlist.Clear(); @@ -456,14 +456,14 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, retCount); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } - if (ret.Any() || checkDoneTimes == 0) + if (ret.Object.Any() || checkDoneTimes == 0) { - foreach (var include in _includeToList) include?.Invoke(ret); - _trackToList?.Invoke(ret); + foreach (var include in _includeToList) include?.Invoke(ret.Object); + _trackToList?.Invoke(ret.Object); chunkDone(ret); } } - internal void ToListChunkPrivate(int chunkSize, Action> chunkDone, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + internal void ToListChunkPrivate(int chunkSize, Action>> chunkDone, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { string sql = null; if (otherData?.Length > 0) @@ -478,7 +478,7 @@ namespace FreeSql.Internal.CommonProvider ToListAfChunkPrivate(chunkSize, chunkDone, sql, af, otherData); } - public void ToChunk(int size, Action> done, bool includeNestedMembers = false) + public void ToChunk(int size, Action>> done, bool includeNestedMembers = false) { if (_selectExpression != null) throw new ArgumentException("Chunk 功能之前不可使用 Select"); this.ToListChunkPrivate(size, done, includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); @@ -498,9 +498,9 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { - var item = af.Read(_orm, dr); + var item = af.Read(_orm, fetch.Object); ret.Add(keySelector(item), elementSelector(item)); }, CommandType.Text, sql, dbParms); } @@ -540,13 +540,13 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, dr => + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false, null)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); }, CommandType.Text, sql, dbParms); } catch (Exception ex) @@ -1373,9 +1373,9 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils); + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); ret.Add((TTuple)read.Value); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); @@ -1402,14 +1402,14 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { - ret.Add(af.Read(_orm, dr)); + ret.Add(af.Read(_orm, fetch.Object)); if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); } return Task.FromResult(false); }, CommandType.Text, sql, dbParms); @@ -1459,9 +1459,9 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { - var item = af.Read(_orm, dr); + var item = af.Read(_orm, fetch.Object); ret.Add(keySelector(item), elementSelector(item)); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); @@ -1503,13 +1503,13 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false, null)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } diff --git a/FreeSql/Internal/Model/FetchCallbackArgs.cs b/FreeSql/Internal/Model/FetchCallbackArgs.cs new file mode 100644 index 00000000..b7f4ccb9 --- /dev/null +++ b/FreeSql/Internal/Model/FetchCallbackArgs.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.Internal.Model +{ + public class FetchCallbackArgs + { + public T Object { get; set; } + + /// + /// 是否放弃继续读取 + /// + public bool IsBreak { get; set; } + } +} From 72739a27c6c3f6967028929d864e4b0dc6dc5436 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 22 Jul 2020 09:44:12 +0800 Subject: [PATCH 0765/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E5=B1=9E=E6=80=A7=20char=20=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E7=9A=84=E6=98=A0=E5=B0=84#381=20#235=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlCodeFirstTest.cs | 60 +++------------ .../Dameng/DamengCodeFirstTest.cs | 56 ++------------ .../Default/OdbcCodeFirstTest.cs | 4 + .../KingbaseES/KingbaseESCodeFirstTest.cs | 9 ++- .../MySql/MySqlCodeFirstTest.cs | 60 +++------------ .../Oracle/OracleCodeFirstTest.cs | 69 ++++------------- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 6 +- .../SqlServer/SqlServerCodeFirstTest.cs | 11 ++- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 6 +- .../Dameng/DamengCodeFirstTest.cs | 57 ++------------ .../MsAccess/MsAccessCodeFirstTest.cs | 53 ++----------- .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 60 +++------------ .../Oracle/OracleCodeFirstTest.cs | 56 ++------------ .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 6 +- .../ShenTong/ShenTongCodeFirstTest.cs | 6 +- .../SqlServer/SqlServerCodeFirstTest.cs | 11 ++- .../Sqlite/SqliteCodeFirstTest.cs | 52 ++----------- FreeSql/Internal/UtilsExpressionTree.cs | 75 +++++++++++++------ .../DamengAdo/DamengAdo.cs | 4 +- .../DamengCodeFirst.cs | 1 + .../MsAccessAdo/MsAccessAdo.cs | 4 +- .../MsAccessCodeFirst.cs | 1 + .../MySqlAdo/MySqlAdo.cs | 4 +- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 1 + .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 4 +- .../Dameng/OdbcDamengCodeFirst.cs | 1 + .../Default/OdbcAdapter.cs | 1 + .../Default/OdbcAdo/OdbcAdo.cs | 2 +- .../Default/OdbcCodeFirst.cs | 1 + .../OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs | 4 +- .../KingbaseES/OdbcKingbaseESCodeFirst.cs | 1 + .../KingbaseES/OdbcKingbaseESUtils.cs | 1 + .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 4 +- .../MySql/OdbcMySqlCodeFirst.cs | 1 + .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 4 +- .../Oracle/OdbcOracleCodeFirst.cs | 1 + .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 4 +- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 1 + .../PostgreSQL/OdbcPostgreSQLUtils.cs | 1 + .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 2 +- .../SqlServer/OdbcSqlServerCodeFirst.cs | 1 + .../OracleAdo/OracleAdo.cs | 4 +- .../OracleCodeFirst.cs | 1 + .../PostgreSQLAdo/PostgreSQLAdo.cs | 4 +- .../PostgreSQLCodeFirst.cs | 1 + .../PostgreSQLUtils.cs | 2 + .../ShenTongAdo/ShenTongAdo.cs | 4 +- .../ShenTongCodeFirst.cs | 3 +- .../ShenTongUtils.cs | 1 + .../SqlServerAdo/SqlServerAdo.cs | 2 +- .../SqlServerCodeFirst.cs | 1 + .../SqliteAdo/SqliteAdo.cs | 4 +- .../SqliteCodeFirst.cs | 1 + 53 files changed, 232 insertions(+), 502 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 98cec1d3..8d279e69 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -282,57 +282,7 @@ namespace FreeSql.Tests.MySqlConnector { var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( - `Id` INT(11) NOT NULL AUTO_INCREMENT, - `testFieldBool` BIT(1) NOT NULL, - `testFieldSByte` TINYINT(3) NOT NULL, - `testFieldShort` SMALLINT(6) NOT NULL, - `testFieldInt` INT(11) NOT NULL, - `testFieldLong` BIGINT(20) NOT NULL, - `testFieldByte` TINYINT(3) UNSIGNED NOT NULL, - `testFieldUShort` SMALLINT(5) UNSIGNED NOT NULL, - `testFieldUInt` INT(10) UNSIGNED NOT NULL, - `testFieldULong` BIGINT(20) UNSIGNED NOT NULL, - `testFieldDouble` DOUBLE NOT NULL, - `testFieldFloat` FLOAT NOT NULL, - `testFieldDecimal` DECIMAL(10,2) NOT NULL, - `testFieldTimeSpan` TIME NOT NULL, - `testFieldDateTime` DATETIME(3) NOT NULL, - `testFieldBytes` VARBINARY(255), - `testFieldString` VARCHAR(255), - `testFieldGuid` VARCHAR(36), - `testFieldBoolNullable` BIT(1), - `testFieldSByteNullable` TINYINT(3), - `testFieldShortNullable` SMALLINT(6), - `testFieldIntNullable` INT(11), - `testFielLongNullable` BIGINT(20), - `testFieldByteNullable` TINYINT(3) UNSIGNED, - `testFieldUShortNullable` SMALLINT(5) UNSIGNED, - `testFieldUIntNullable` INT(10) UNSIGNED, - `testFieldULongNullable` BIGINT(20) UNSIGNED, - `testFieldDoubleNullable` DOUBLE, - `testFieldFloatNullable` FLOAT, - `testFieldDecimalNullable` DECIMAL(10,2), - `testFieldTimeSpanNullable` TIME, - `testFieldDateTimeNullable` DATETIME(3), - `testFieldGuidNullable` VARCHAR(36), - `testFieldPoint` POINT, - `testFieldLineString` LINESTRING, - `testFieldPolygon` POLYGON, - `testFieldMultiPoint` MULTIPOINT, - `testFieldMultiLineString` MULTILINESTRING, - `testFieldMultiPolygon` MULTIPOLYGON, - `testFieldEnum1` ENUM('E1','E2','E3') NOT NULL, - `testFieldEnum1Nullable` ENUM('E1','E2','E3'), - `testFieldEnum2` SET('F1','F2','F3') NOT NULL, - `testFieldEnum2Nullable` SET('F1','F2','F3'), - PRIMARY KEY (`Id`) -) Engine=InnoDB; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); } @@ -398,6 +348,7 @@ namespace FreeSql.Tests.MySqlConnector testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), testFieldUInt = uint.MaxValue, @@ -411,10 +362,12 @@ namespace FreeSql.Tests.MySqlConnector item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -561,6 +514,10 @@ namespace FreeSql.Tests.MySqlConnector public string TestFieldString { get; set; } + [JsonProperty, Column(Name = "testFieldChar", DbType = "char(1)", IsNullable = true)] + public char testFieldChar { get; set; } + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] public TimeSpan TestFieldTimeSpan { get; set; } @@ -665,6 +622,7 @@ namespace FreeSql.Tests.MySqlConnector public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs index be8559fe..fed58cd8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengCodeFirstTest.cs @@ -179,57 +179,7 @@ namespace FreeSql.Tests.Odbc.Dameng { var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( - `Id` INT(11) NOT NULL AUTO_INCREMENT, - `Bool` BIT(1) NOT NULL, - `SByte` TINYINT(3) NOT NULL, - `Short` SMALLINT(6) NOT NULL, - `Int` INT(11) NOT NULL, - `Long` BIGINT(20) NOT NULL, - `Byte` TINYINT(3) UNSIGNED NOT NULL, - `UShort` SMALLINT(5) UNSIGNED NOT NULL, - `UInt` INT(10) UNSIGNED NOT NULL, - `ULong` BIGINT(20) UNSIGNED NOT NULL, - `Double` DOUBLE NOT NULL, - `Float` FLOAT NOT NULL, - `Decimal` DECIMAL(10,2) NOT NULL, - `TimeSpan` TIME NOT NULL, - `DateTime` DATETIME NOT NULL, - `Bytes` VARBINARY(255), - `String` VARCHAR(255), - `Guid` VARCHAR(36), - `BoolNullable` BIT(1), - `SByteNullable` TINYINT(3), - `ShortNullable` SMALLINT(6), - `IntNullable` INT(11), - `testFielLongNullable` BIGINT(20), - `ByteNullable` TINYINT(3) UNSIGNED, - `UShortNullable` SMALLINT(5) UNSIGNED, - `UIntNullable` INT(10) UNSIGNED, - `ULongNullable` BIGINT(20) UNSIGNED, - `DoubleNullable` DOUBLE, - `FloatNullable` FLOAT, - `DecimalNullable` DECIMAL(10,2), - `TimeSpanNullable` TIME, - `DateTimeNullable` DATETIME, - `GuidNullable` VARCHAR(36), - `Point` POINT, - `LineString` LINESTRING, - `Polygon` POLYGON, - `MultiPoint` MULTIPOINT, - `MultiLineString` MULTILINESTRING, - `MultiPolygon` MULTIPOLYGON, - `Enum1` ENUM('E1','E2','E3') NOT NULL, - `Enum1Nullable` ENUM('E1','E2','E3'), - `Enum2` SET('F1','F2','F3') NOT NULL, - `Enum2Nullable` SET('F1','F2','F3'), - PRIMARY KEY (`Id`) -) Engine=InnoDB; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ //sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); } @@ -272,6 +222,7 @@ namespace FreeSql.Tests.Odbc.Dameng Short = short.MaxValue, ShortNullable = short.MinValue, String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -289,10 +240,12 @@ namespace FreeSql.Tests.Odbc.Dameng item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -323,6 +276,7 @@ namespace FreeSql.Tests.Odbc.Dameng public DateTime DateTimeOffSet { get; set; } public byte[] Bytes { get; set; } public string String { get; set; } + public char Char { get; set; } public Guid Guid { get; set; } public bool? BoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs index f58d1305..b47bb3dc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcCodeFirstTest.cs @@ -99,6 +99,7 @@ namespace FreeSql.Tests.Odbc.Default testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, testFieldString = "我是中国人string'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldUInt = uint.MaxValue, testFieldUIntNullable = uint.MinValue, testFieldULong = ulong.MaxValue, @@ -117,10 +118,12 @@ namespace FreeSql.Tests.Odbc.Default var item3 = insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -148,6 +151,7 @@ namespace FreeSql.Tests.Odbc.Default public DateTime testFieldDateTime { get; set; } public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs index 271a76bf..2b6f2a61 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESCodeFirstTest.cs @@ -177,8 +177,8 @@ namespace FreeSql.Tests.Odbc.KingbaseES [Fact] public void GetComparisonDDLStatements() { - var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //κ //sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); } @@ -221,6 +221,7 @@ namespace FreeSql.Tests.Odbc.KingbaseES Short = short.MaxValue, ShortNullable = short.MinValue, String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -255,19 +256,22 @@ namespace FreeSql.Tests.Odbc.KingbaseES a.DateTimeOffSet, a.Bytes, a.String, + a.Char, a.Guid }); var newitem22 = select.Where(a => a.Id == item2.Id).First(a => new { - a.Id, a.id2, a.SByte, a.Short, a.Int, a.Long, a.Byte, a.UShort, a.UInt, a.ULong, a.Double, a.Float, a.Decimal, a.TimeSpan, a.DateTime, a.DateTimeOffSet, a.Bytes, a.String, a.Guid + a.Id, a.id2, a.SByte, a.Short, a.Int, a.Long, a.Byte, a.UShort, a.UInt, a.ULong, a.Double, a.Float, a.Decimal, a.TimeSpan, a.DateTime, a.DateTimeOffSet, a.Bytes, a.String, a.Char, a.Guid }); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -298,6 +302,7 @@ namespace FreeSql.Tests.Odbc.KingbaseES public DateTime DateTimeOffSet { get; set; } public byte[] Bytes { get; set; } public string String { get; set; } + public char Char { get; set; } public Guid Guid { get; set; } public bool? BoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index 43176a37..3be75126 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -153,57 +153,7 @@ namespace FreeSql.Tests.Odbc.MySql { var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( - `Id` INT(11) NOT NULL AUTO_INCREMENT, - `testFieldBool` BIT(1) NOT NULL, - `testFieldSByte` TINYINT(3) NOT NULL, - `testFieldShort` SMALLINT(6) NOT NULL, - `testFieldInt` INT(11) NOT NULL, - `testFieldLong` BIGINT(20) NOT NULL, - `testFieldByte` TINYINT(3) UNSIGNED NOT NULL, - `testFieldUShort` SMALLINT(5) UNSIGNED NOT NULL, - `testFieldUInt` INT(10) UNSIGNED NOT NULL, - `testFieldULong` BIGINT(20) UNSIGNED NOT NULL, - `testFieldDouble` DOUBLE NOT NULL, - `testFieldFloat` FLOAT NOT NULL, - `testFieldDecimal` DECIMAL(10,2) NOT NULL, - `testFieldTimeSpan` TIME NOT NULL, - `testFieldDateTime` DATETIME(3) NOT NULL, - `testFieldBytes` VARBINARY(255), - `testFieldString` VARCHAR(255), - `testFieldGuid` VARCHAR(36), - `testFieldBoolNullable` BIT(1), - `testFieldSByteNullable` TINYINT(3), - `testFieldShortNullable` SMALLINT(6), - `testFieldIntNullable` INT(11), - `testFielLongNullable` BIGINT(20), - `testFieldByteNullable` TINYINT(3) UNSIGNED, - `testFieldUShortNullable` SMALLINT(5) UNSIGNED, - `testFieldUIntNullable` INT(10) UNSIGNED, - `testFieldULongNullable` BIGINT(20) UNSIGNED, - `testFieldDoubleNullable` DOUBLE, - `testFieldFloatNullable` FLOAT, - `testFieldDecimalNullable` DECIMAL(10,2), - `testFieldTimeSpanNullable` TIME, - `testFieldDateTimeNullable` DATETIME(3), - `testFieldGuidNullable` VARCHAR(36), - `testFieldPoint` POINT, - `testFieldLineString` LINESTRING, - `testFieldPolygon` POLYGON, - `testFieldMultiPoint` MULTIPOINT, - `testFieldMultiLineString` MULTILINESTRING, - `testFieldMultiPolygon` MULTIPOLYGON, - `testFieldEnum1` ENUM('E1','E2','E3') NOT NULL, - `testFieldEnum1Nullable` ENUM('E1','E2','E3'), - `testFieldEnum2` SET('F1','F2','F3') NOT NULL, - `testFieldEnum2Nullable` SET('F1','F2','F3'), - PRIMARY KEY (`Id`) -) Engine=InnoDB; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); } @@ -246,6 +196,7 @@ namespace FreeSql.Tests.Odbc.MySql testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), testFieldUInt = uint.MaxValue, @@ -265,10 +216,12 @@ namespace FreeSql.Tests.Odbc.MySql item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -391,6 +344,10 @@ namespace FreeSql.Tests.Odbc.MySql public string TestFieldString { get; set; } + [JsonProperty, Column(Name = "testFieldChar", DbType = "char(1)", IsNullable = true)] + public char testFieldChar { get; set; } + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] public TimeSpan TestFieldTimeSpan { get; set; } @@ -492,6 +449,7 @@ namespace FreeSql.Tests.Odbc.MySql public DateTime testFieldDateTime { get; set; } public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs index 95cd2720..5c0ead2e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleCodeFirstTest.cs @@ -176,59 +176,8 @@ namespace FreeSql.Tests.Odbc.Oracle [Fact] public void GetComparisonDDLStatements() { - var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( - `Id` INT(11) NOT NULL AUTO_INCREMENT, - `Bool` BIT(1) NOT NULL, - `SByte` TINYINT(3) NOT NULL, - `Short` SMALLINT(6) NOT NULL, - `Int` INT(11) NOT NULL, - `Long` BIGINT(20) NOT NULL, - `Byte` TINYINT(3) UNSIGNED NOT NULL, - `UShort` SMALLINT(5) UNSIGNED NOT NULL, - `UInt` INT(10) UNSIGNED NOT NULL, - `ULong` BIGINT(20) UNSIGNED NOT NULL, - `Double` DOUBLE NOT NULL, - `Float` FLOAT NOT NULL, - `Decimal` DECIMAL(10,2) NOT NULL, - `TimeSpan` TIME NOT NULL, - `DateTime` DATETIME NOT NULL, - `Bytes` VARBINARY(255), - `String` VARCHAR(255), - `Guid` VARCHAR(36), - `BoolNullable` BIT(1), - `SByteNullable` TINYINT(3), - `ShortNullable` SMALLINT(6), - `IntNullable` INT(11), - `testFielLongNullable` BIGINT(20), - `ByteNullable` TINYINT(3) UNSIGNED, - `UShortNullable` SMALLINT(5) UNSIGNED, - `UIntNullable` INT(10) UNSIGNED, - `ULongNullable` BIGINT(20) UNSIGNED, - `DoubleNullable` DOUBLE, - `FloatNullable` FLOAT, - `DecimalNullable` DECIMAL(10,2), - `TimeSpanNullable` TIME, - `DateTimeNullable` DATETIME, - `GuidNullable` VARCHAR(36), - `Point` POINT, - `LineString` LINESTRING, - `Polygon` POLYGON, - `MultiPoint` MULTIPOINT, - `MultiLineString` MULTILINESTRING, - `MultiPolygon` MULTIPOLYGON, - `Enum1` ENUM('E1','E2','E3') NOT NULL, - `Enum1Nullable` ENUM('E1','E2','E3'), - `Enum2` SET('F1','F2','F3') NOT NULL, - `Enum2Nullable` SET('F1','F2','F3'), - PRIMARY KEY (`Id`) -) Engine=InnoDB; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ //sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); } @@ -239,7 +188,17 @@ namespace FreeSql.Tests.Odbc.Oracle public void CurdAllField() { var item = new TableAllType { }; - item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + for (var a = 0; a < 100; a++) + { + try //ERROR [23000] [Oracle][ODBC][Ora]ORA-00001: ΥΨһԼ (1ODBC.1ODBC_TB_ALLTYPE_pk2) + { + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + break; + } + catch + { + } + } var newitem = select.Where(a => a.Id == item.Id).ToOne(); @@ -271,6 +230,7 @@ namespace FreeSql.Tests.Odbc.Oracle Short = short.MaxValue, ShortNullable = short.MinValue, String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -288,10 +248,12 @@ namespace FreeSql.Tests.Odbc.Oracle item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -322,6 +284,7 @@ namespace FreeSql.Tests.Odbc.Oracle public DateTime DateTimeOffSet { get; set; } public byte[] Bytes { get; set; } public string String { get; set; } + public char Char { get; set; } public Guid Guid { get; set; } public bool? BoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs index d46ae080..99312f7e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -105,8 +105,8 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public void AddField() { var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //κ g.pgsql.Select(); - var id = g.pgsql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); } @@ -184,6 +184,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldTimeSpan = TimeSpan.FromDays(1), testFieldTimeSpanNullable = TimeSpan.FromSeconds(90), testFieldUInt = uint.MaxValue, @@ -202,10 +203,12 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var item3 = insert.AppendData(item2).ExecuteInserted().First(); var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -233,6 +236,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public DateTime testFieldDateTime { get; set; } public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs index 48bfefbd..9bb412ea 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerCodeFirstTest.cs @@ -166,9 +166,8 @@ namespace FreeSql.Tests.Odbc.SqlServer [Fact] public void GetComparisonDDLStatements() { - var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); - + Assert.True(string.IsNullOrEmpty(sql)); //κ sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); } @@ -214,6 +213,7 @@ namespace FreeSql.Tests.Odbc.SqlServer testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(30), testFieldUInt = uint.MaxValue, @@ -234,10 +234,12 @@ namespace FreeSql.Tests.Odbc.SqlServer var item3 = insert.AppendData(item2).ExecuteInserted(); var newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted(); newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -367,6 +369,10 @@ namespace FreeSql.Tests.Odbc.SqlServer public string TestFieldString { get; set; } + [JsonProperty, Column(Name = "testFieldChar", DbType = "char(1)", IsNullable = true)] + public char testFieldChar { get; set; } + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] public TimeSpan TestFieldTimeSpan { get; set; } @@ -427,6 +433,7 @@ namespace FreeSql.Tests.Odbc.SqlServer public DateTimeOffset testFieldDateTimeOffset { get; set; } public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs index 59fa573c..5fd6226e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -22,8 +22,8 @@ namespace FreeSql.Tests.PostgreSQL.NetTopologySuite [Fact] public void GetComparisonDDLStatements() { - var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //κ g.pgsql.Select(); } @@ -230,6 +230,7 @@ namespace FreeSql.Tests.PostgreSQL.NetTopologySuite testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 }, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldStringArray = new[] { "йString1", "йString2", null, "йString3" }, testFieldTimeSpan = TimeSpan.FromDays(1), testFieldTimeSpanArray = new[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }, @@ -262,10 +263,12 @@ namespace FreeSql.Tests.PostgreSQL.NetTopologySuite var item3 = insert.AppendData(item2).ExecuteInserted().First(); var newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -296,6 +299,7 @@ namespace FreeSql.Tests.PostgreSQL.NetTopologySuite public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public NpgsqlPoint testFieldNpgsqlPoint { get; set; } public NpgsqlLine testFieldNpgsqlLine { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs index 4369ea87..de3a6c69 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs @@ -247,59 +247,8 @@ namespace FreeSql.Tests.Dameng [Fact] public void GetComparisonDDLStatements() { - var sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( - `Id` INT(11) NOT NULL AUTO_INCREMENT, - `Bool` BIT(1) NOT NULL, - `SByte` TINYINT(3) NOT NULL, - `Short` SMALLINT(6) NOT NULL, - `Int` INT(11) NOT NULL, - `Long` BIGINT(20) NOT NULL, - `Byte` TINYINT(3) UNSIGNED NOT NULL, - `UShort` SMALLINT(5) UNSIGNED NOT NULL, - `UInt` INT(10) UNSIGNED NOT NULL, - `ULong` BIGINT(20) UNSIGNED NOT NULL, - `Double` DOUBLE NOT NULL, - `Float` FLOAT NOT NULL, - `Decimal` DECIMAL(10,2) NOT NULL, - `TimeSpan` TIME NOT NULL, - `DateTime` DATETIME NOT NULL, - `Bytes` VARBINARY(255), - `String` VARCHAR(255), - `Guid` VARCHAR(36), - `BoolNullable` BIT(1), - `SByteNullable` TINYINT(3), - `ShortNullable` SMALLINT(6), - `IntNullable` INT(11), - `testFielLongNullable` BIGINT(20), - `ByteNullable` TINYINT(3) UNSIGNED, - `UShortNullable` SMALLINT(5) UNSIGNED, - `UIntNullable` INT(10) UNSIGNED, - `ULongNullable` BIGINT(20) UNSIGNED, - `DoubleNullable` DOUBLE, - `FloatNullable` FLOAT, - `DecimalNullable` DECIMAL(10,2), - `TimeSpanNullable` TIME, - `DateTimeNullable` DATETIME, - `GuidNullable` VARCHAR(36), - `Point` POINT, - `LineString` LINESTRING, - `Polygon` POLYGON, - `MultiPoint` MULTIPOINT, - `MultiLineString` MULTILINESTRING, - `MultiPolygon` MULTIPOLYGON, - `Enum1` ENUM('E1','E2','E3') NOT NULL, - `Enum1Nullable` ENUM('E1','E2','E3'), - `Enum2` SET('F1','F2','F3') NOT NULL, - `Enum2Nullable` SET('F1','F2','F3'), - PRIMARY KEY (`Id`) -) Engine=InnoDB; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ //sql = g.dameng.CodeFirst.GetComparisonDDLStatements(); } @@ -338,6 +287,7 @@ namespace FreeSql.Tests.Dameng Short = short.MaxValue, ShortNullable = short.MinValue, String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -355,10 +305,12 @@ namespace FreeSql.Tests.Dameng item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -389,6 +341,7 @@ namespace FreeSql.Tests.Dameng public DateTime DateTimeOffSet { get; set; } public byte[] Bytes { get; set; } public string String { get; set; } + public char Char { get; set; } public Guid Guid { get; set; } public bool? BoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs index 5c2dc9c0..622c63d3 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -177,54 +177,7 @@ namespace FreeSql.Tests.MsAccess { var sql = g.msaccess.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE [tb_alltype] ( - [Id] AUTOINCREMENT, - [Bool] BIT NOT NULL, - [SByte] DECIMAL(3,0) NOT NULL, - [Short] DECIMAL(6,0) NOT NULL, - [Int] DECIMAL(11,0) NOT NULL, - [Long] DECIMAL(20,0) NOT NULL, - [Byte] DECIMAL(3,0) NOT NULL, - [UShort] DECIMAL(5,0) NOT NULL, - [UInt] DECIMAL(10,0) NOT NULL, - [ULong] DECIMAL(20,0) NOT NULL, - [Double] DOUBLE NOT NULL, - [Float] SINGLE NOT NULL, - [Decimal] DECIMAL(10,2) NOT NULL, - [TimeSpan] TIME NOT NULL, - [DateTime] DATETIME NOT NULL, - [DateTimeOffSet] DATETIME NOT NULL, - [Bytes] BINARY(255), - [String] VARCHAR(255), - [Guid] VARCHAR(36) NOT NULL, - [BoolNullable] BIT, - [SByteNullable] DECIMAL(3,0), - [ShortNullable] DECIMAL(6,0), - [IntNullable] DECIMAL(11,0), - [testFielLongNullable] DECIMAL(20,0), - [ByteNullable] DECIMAL(3,0), - [UShortNullable] DECIMAL(5,0), - [UIntNullable] DECIMAL(10,0), - [ULongNullable] DECIMAL(20,0), - [DoubleNullable] DOUBLE, - [FloatNullable] SINGLE, - [DecimalNullable] DECIMAL(10,2), - [TimeSpanNullable] TIME, - [DateTimeNullable] DATETIME, - [DateTimeOffSetNullable] DATETIME, - [GuidNullable] VARCHAR(36), - [Enum1] DECIMAL(11,0) NOT NULL, - [Enum1Nullable] DECIMAL(11,0), - [Enum2] DECIMAL(20,0) NOT NULL, - [Enum2Nullable] DECIMAL(20,0), - PRIMARY KEY ([Id]) -) -; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ //sql = g.msaccess.CodeFirst.GetComparisonDDLStatements(); } @@ -267,6 +220,7 @@ namespace FreeSql.Tests.MsAccess Short = short.MaxValue, ShortNullable = short.MinValue, String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -280,10 +234,12 @@ namespace FreeSql.Tests.MsAccess item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -318,6 +274,7 @@ namespace FreeSql.Tests.MsAccess public byte[] Bytes { get; set; } public string String { get; set; } + public char Char { get; set; } public Guid Guid { get; set; } public bool? BoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 346a806c..463a101e 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -281,57 +281,7 @@ namespace FreeSql.Tests.MySql { var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( - `Id` INT(11) NOT NULL AUTO_INCREMENT, - `testFieldBool` BIT(1) NOT NULL, - `testFieldSByte` TINYINT(3) NOT NULL, - `testFieldShort` SMALLINT(6) NOT NULL, - `testFieldInt` INT(11) NOT NULL, - `testFieldLong` BIGINT(20) NOT NULL, - `testFieldByte` TINYINT(3) UNSIGNED NOT NULL, - `testFieldUShort` SMALLINT(5) UNSIGNED NOT NULL, - `testFieldUInt` INT(10) UNSIGNED NOT NULL, - `testFieldULong` BIGINT(20) UNSIGNED NOT NULL, - `testFieldDouble` DOUBLE NOT NULL, - `testFieldFloat` FLOAT NOT NULL, - `testFieldDecimal` DECIMAL(10,2) NOT NULL, - `testFieldTimeSpan` TIME NOT NULL, - `testFieldDateTime` DATETIME(3) NOT NULL, - `testFieldBytes` VARBINARY(255), - `testFieldString` VARCHAR(255), - `testFieldGuid` VARCHAR(36), - `testFieldBoolNullable` BIT(1), - `testFieldSByteNullable` TINYINT(3), - `testFieldShortNullable` SMALLINT(6), - `testFieldIntNullable` INT(11), - `testFielLongNullable` BIGINT(20), - `testFieldByteNullable` TINYINT(3) UNSIGNED, - `testFieldUShortNullable` SMALLINT(5) UNSIGNED, - `testFieldUIntNullable` INT(10) UNSIGNED, - `testFieldULongNullable` BIGINT(20) UNSIGNED, - `testFieldDoubleNullable` DOUBLE, - `testFieldFloatNullable` FLOAT, - `testFieldDecimalNullable` DECIMAL(10,2), - `testFieldTimeSpanNullable` TIME, - `testFieldDateTimeNullable` DATETIME(3), - `testFieldGuidNullable` VARCHAR(36), - `testFieldPoint` POINT, - `testFieldLineString` LINESTRING, - `testFieldPolygon` POLYGON, - `testFieldMultiPoint` MULTIPOINT, - `testFieldMultiLineString` MULTILINESTRING, - `testFieldMultiPolygon` MULTIPOLYGON, - `testFieldEnum1` ENUM('E1','E2','E3') NOT NULL, - `testFieldEnum1Nullable` ENUM('E1','E2','E3'), - `testFieldEnum2` SET('F1','F2','F3') NOT NULL, - `testFieldEnum2Nullable` SET('F1','F2','F3'), - PRIMARY KEY (`Id`) -) Engine=InnoDB; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); } @@ -397,6 +347,7 @@ namespace FreeSql.Tests.MySql testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), testFieldUInt = uint.MaxValue, @@ -416,10 +367,12 @@ namespace FreeSql.Tests.MySql item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -566,6 +519,10 @@ namespace FreeSql.Tests.MySql public string TestFieldString { get; set; } + [JsonProperty, Column(Name = "testFieldChar", DbType = "char(1)", IsNullable = true)] + public char testFieldChar { get; set; } + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] public TimeSpan TestFieldTimeSpan { get; set; } @@ -670,6 +627,7 @@ namespace FreeSql.Tests.MySql public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 7e334513..5774f0a6 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -279,57 +279,7 @@ namespace FreeSql.Tests.Oracle { var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( - `Id` INT(11) NOT NULL AUTO_INCREMENT, - `Bool` BIT(1) NOT NULL, - `SByte` TINYINT(3) NOT NULL, - `Short` SMALLINT(6) NOT NULL, - `Int` INT(11) NOT NULL, - `Long` BIGINT(20) NOT NULL, - `Byte` TINYINT(3) UNSIGNED NOT NULL, - `UShort` SMALLINT(5) UNSIGNED NOT NULL, - `UInt` INT(10) UNSIGNED NOT NULL, - `ULong` BIGINT(20) UNSIGNED NOT NULL, - `Double` DOUBLE NOT NULL, - `Float` FLOAT NOT NULL, - `Decimal` DECIMAL(10,2) NOT NULL, - `TimeSpan` TIME NOT NULL, - `DateTime` DATETIME NOT NULL, - `Bytes` VARBINARY(255), - `String` VARCHAR(255), - `Guid` VARCHAR(36), - `BoolNullable` BIT(1), - `SByteNullable` TINYINT(3), - `ShortNullable` SMALLINT(6), - `IntNullable` INT(11), - `testFielLongNullable` BIGINT(20), - `ByteNullable` TINYINT(3) UNSIGNED, - `UShortNullable` SMALLINT(5) UNSIGNED, - `UIntNullable` INT(10) UNSIGNED, - `ULongNullable` BIGINT(20) UNSIGNED, - `DoubleNullable` DOUBLE, - `FloatNullable` FLOAT, - `DecimalNullable` DECIMAL(10,2), - `TimeSpanNullable` TIME, - `DateTimeNullable` DATETIME, - `GuidNullable` VARCHAR(36), - `Point` POINT, - `LineString` LINESTRING, - `Polygon` POLYGON, - `MultiPoint` MULTIPOINT, - `MultiLineString` MULTILINESTRING, - `MultiPolygon` MULTIPOLYGON, - `Enum1` ENUM('E1','E2','E3') NOT NULL, - `Enum1Nullable` ENUM('E1','E2','E3'), - `Enum2` SET('F1','F2','F3') NOT NULL, - `Enum2Nullable` SET('F1','F2','F3'), - PRIMARY KEY (`Id`) -) Engine=InnoDB; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ //sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); } @@ -372,6 +322,7 @@ namespace FreeSql.Tests.Oracle Short = short.MaxValue, ShortNullable = short.MinValue, String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -389,10 +340,12 @@ namespace FreeSql.Tests.Oracle item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -427,6 +380,7 @@ namespace FreeSql.Tests.Oracle public byte[] Bytes { get; set; } public string String { get; set; } + public char Char { get; set; } public Guid Guid { get; set; } public bool? BoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index 094a3afa..f4ee21d6 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -145,8 +145,8 @@ namespace FreeSql.Tests.PostgreSQL public void AddField() { var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //κ g.pgsql.Select(); - var id = g.pgsql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); } @@ -388,6 +388,7 @@ namespace FreeSql.Tests.PostgreSQL testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 }, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldStringArray = new[] { "йString1", "йString2", null, "йString3" }, testFieldTimeSpan = TimeSpan.FromDays(1), testFieldTimeSpanArray = new[] { TimeSpan.FromDays(1), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }, @@ -420,10 +421,12 @@ namespace FreeSql.Tests.PostgreSQL var item3 = insert.AppendData(item2).ExecuteInserted().First(); var newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); newitem2 = select.Where(a => a.Id == item3.Id && object.Equals(a.testFieldJToken["a"], "1")).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -454,6 +457,7 @@ namespace FreeSql.Tests.PostgreSQL public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public NpgsqlPoint testFieldNpgsqlPoint { get; set; } public NpgsqlLine testFieldNpgsqlLine { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs index 6c6f93d5..2716341e 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongCodeFirstTest.cs @@ -143,8 +143,8 @@ namespace FreeSql.Tests.ShenTong [Fact] public void GetComparisonDDLStatements() { - var sql = g.shentong.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //κ g.shentong.Select(); } @@ -217,6 +217,7 @@ namespace FreeSql.Tests.ShenTong //testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 }, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', //testFieldStringArray = new[] { "йString1", "йString2", null, "йString3" }, testFieldTimeSpan = TimeSpan.FromHours(10), //testFieldTimeSpanArray = new[] { TimeSpan.FromHours(10), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) }, @@ -245,10 +246,12 @@ namespace FreeSql.Tests.ShenTong var item3 = insert.AppendData(item2).ExecuteInserted().First(); var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -279,6 +282,7 @@ namespace FreeSql.Tests.ShenTong public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 20723d8b..34c6c2e4 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -202,9 +202,8 @@ namespace FreeSql.Tests.SqlServer [Fact] public void GetComparisonDDLStatements() { - var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); - + Assert.True(string.IsNullOrEmpty(sql)); //κ sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); } @@ -250,6 +249,7 @@ namespace FreeSql.Tests.SqlServer testFieldShort = short.MaxValue, testFieldShortNullable = short.MinValue, testFieldString = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', testFieldTimeSpan = TimeSpan.FromSeconds(999), testFieldTimeSpanNullable = TimeSpan.FromSeconds(30), testFieldUInt = uint.MaxValue, @@ -270,10 +270,12 @@ namespace FreeSql.Tests.SqlServer var item3 = insert.AppendData(item2).ExecuteInserted(); var newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted(); newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -403,6 +405,10 @@ namespace FreeSql.Tests.SqlServer public string TestFieldString { get; set; } + [JsonProperty, Column(Name = "testFieldChar", DbType = "char(1)", IsNullable = true)] + public char testFieldChar { get; set; } + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] public TimeSpan TestFieldTimeSpan { get; set; } @@ -467,6 +473,7 @@ namespace FreeSql.Tests.SqlServer public byte[] testFieldBytes { get; set; } public string testFieldString { get; set; } + public char testFieldChar { get; set; } public Guid testFieldGuid { get; set; } public bool? testFieldBoolNullable { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index d3634ce2..9f00a265 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -239,53 +239,7 @@ namespace FreeSql.Tests.Sqlite { var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements(); - if (string.IsNullOrEmpty(sql) == false) - { - Assert.Equal(@"CREATE TABLE IF NOT EXISTS ""main"".""tb_alltype"" ( - ""Id"" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - ""Bool"" BOOLEAN NOT NULL, - ""SByte"" SMALLINT NOT NULL, - ""Short"" SMALLINT NOT NULL, - ""Int"" INTEGER NOT NULL, - ""Long"" INTEGER NOT NULL, - ""Byte"" INT2 NOT NULL, - ""UShort"" UNSIGNED NOT NULL, - ""UInt"" DECIMAL(10,0) NOT NULL, - ""ULong"" DECIMAL(21,0) NOT NULL, - ""Double"" DOUBLE NOT NULL, - ""Float"" FLOAT NOT NULL, - ""Decimal"" DECIMAL(10,2) NOT NULL, - ""TimeSpan"" BIGINT NOT NULL, - ""DateTime"" DATETIME NOT NULL, - ""DateTimeOffSet"" DATETIME NOT NULL, - ""Bytes"" BLOB, - ""String"" NVARCHAR(255), - ""Guid"" CHARACTER(36) NOT NULL, - ""BoolNullable"" BOOLEAN, - ""SByteNullable"" SMALLINT, - ""ShortNullable"" SMALLINT, - ""IntNullable"" INTEGER, - ""testFielLongNullable"" INTEGER, - ""ByteNullable"" INT2, - ""UShortNullable"" UNSIGNED, - ""UIntNullable"" DECIMAL(10,0), - ""ULongNullable"" DECIMAL(21,0), - ""DoubleNullable"" DOUBLE, - ""FloatNullable"" FLOAT, - ""DecimalNullable"" DECIMAL(10,2), - ""TimeSpanNullable"" BIGINT, - ""DateTimeNullable"" DATETIME, - ""DateTimeOffSetNullable"" DATETIME, - ""GuidNullable"" CHARACTER(36), - ""Enum1"" MEDIUMINT NOT NULL, - ""Enum1Nullable"" MEDIUMINT, - ""Enum2"" BIGINT NOT NULL, - ""Enum2Nullable"" BIGINT -) -; -", sql); - } - + Assert.True(string.IsNullOrEmpty(sql)); //κ //sql = g.Sqlite.CodeFirst.GetComparisonDDLStatements(); } @@ -328,6 +282,7 @@ namespace FreeSql.Tests.Sqlite Short = short.MaxValue, ShortNullable = short.MinValue, String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', TimeSpan = TimeSpan.FromSeconds(999), TimeSpanNullable = TimeSpan.FromSeconds(60), UInt = uint.MaxValue, @@ -341,10 +296,12 @@ namespace FreeSql.Tests.Sqlite item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); var items = select.ToList(); var itemstb = select.ToDataTable(); @@ -379,6 +336,7 @@ namespace FreeSql.Tests.Sqlite public byte[] Bytes { get; set; } public string String { get; set; } + public char Char { get; set; } public Guid Guid { get; set; } public bool? BoolNullable { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 272e09e7..e9f4d453 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -451,6 +451,7 @@ namespace FreeSql.Internal var m = Regex.Match(col.Attribute.DbType, ltp); if (m.Success == false) continue; var sizeStr = m.Groups[1].Value.Trim(); + if (sizeStr.EndsWith(" BYTE") || sizeStr.EndsWith(" CHAR")) sizeStr = sizeStr.Remove(sizeStr.Length - 5); //ORACLE if (string.Compare(sizeStr, "max", true) == 0) { col.DbSize = -1; @@ -1257,6 +1258,7 @@ namespace FreeSql.Internal [typeof(DateTimeOffset)] = true, [typeof(byte[])] = true, [typeof(string)] = true, + [typeof(char)] = true, [typeof(Guid)] = true, //[typeof(MygisPoint)] = true, //[typeof(MygisLineString)] = true, @@ -1719,6 +1721,11 @@ namespace FreeSql.Internal if (bytes == null) return Guid.Empty; return Guid.TryParse(BitConverter.ToString(bytes, 0, Math.Min(bytes.Length, 36)).Replace("-", ""), out var tryguid) ? tryguid : Guid.Empty; } + static char StringToChar(string str) + { + if (string.IsNullOrEmpty(str)) return default(char); + return str.ToCharArray(0, 1)[0]; + } static ConcurrentDictionary>> _dicGetDataReaderValue = new ConcurrentDictionary>>(); static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) }); @@ -1749,6 +1756,8 @@ namespace FreeSql.Internal static Encoding DefaultEncoding = Encoding.UTF8; static MethodInfo MethodEncodingGetBytes = typeof(Encoding).GetMethod("GetBytes", new[] { typeof(string) }); static MethodInfo MethodEncodingGetString = typeof(Encoding).GetMethod("GetString", new[] { typeof(byte[]) }); + static MethodInfo MethodStringToCharArray = typeof(string).GetMethod("ToCharArray", new Type[0]); + static MethodInfo MethodStringToChar = typeof(Utils).GetMethod("StringToChar", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); static MethodInfo MethodGuidToBytes = typeof(Utils).GetMethod("GuidToBytes", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(Guid) }, null); static MethodInfo MethodBytesToGuid = typeof(Utils).GetMethod("BytesToGuid", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(byte[]) }, null); @@ -1760,21 +1769,35 @@ namespace FreeSql.Internal var valueExp = Expression.Variable(typeof(object), "locvalue"); Func funcGetExpression = () => { - if (type.FullName == "System.Byte[]") return Expression.IfThenElse( - Expression.TypeEqual(valueExp, type), - Expression.Return(returnTarget, valueExp), - Expression.IfThenElse( - Expression.TypeEqual(valueExp, typeof(string)), - Expression.Return(returnTarget, Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetBytes, Expression.Convert(valueExp, typeof(string)))), - Expression.IfThenElse( - Expression.OrElse(Expression.TypeEqual(valueExp, typeof(Guid)), Expression.TypeEqual(valueExp, typeof(Guid?))), - Expression.Return(returnTarget, Expression.Call(MethodGuidToBytes, Expression.Convert(valueExp, typeof(Guid)))), - Expression.Return(returnTarget, Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetBytes, Expression.Call(MethodToString, valueExp))) - ) - ) - ); if (type.IsArray) { + switch (type.FullName) + { + case "System.Byte[]": + return Expression.IfThenElse( + Expression.TypeEqual(valueExp, type), + Expression.Return(returnTarget, valueExp), + Expression.IfThenElse( + Expression.TypeEqual(valueExp, typeof(string)), + Expression.Return(returnTarget, Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetBytes, Expression.Convert(valueExp, typeof(string)))), + Expression.IfThenElse( + Expression.OrElse(Expression.TypeEqual(valueExp, typeof(Guid)), Expression.TypeEqual(valueExp, typeof(Guid?))), + Expression.Return(returnTarget, Expression.Call(MethodGuidToBytes, Expression.Convert(valueExp, typeof(Guid)))), + Expression.Return(returnTarget, Expression.Call(Expression.Constant(DefaultEncoding), MethodEncodingGetBytes, Expression.Call(MethodToString, valueExp))) + ) + ) + ); + case "System.Char[]": + return Expression.IfThenElse( + Expression.TypeEqual(valueExp, type), + Expression.Return(returnTarget, valueExp), + Expression.IfThenElse( + Expression.TypeEqual(valueExp, typeof(string)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(valueExp, typeof(string)), MethodStringToCharArray)), + Expression.Return(returnTarget, Expression.Call(Expression.Call(MethodToString, valueExp), MethodStringToCharArray)) + ) + ); + } var elementType = type.GetElementType(); var arrNewExp = Expression.Variable(type, "arrNew"); var arrExp = Expression.Variable(typeof(Array), "arr"); @@ -1817,14 +1840,6 @@ namespace FreeSql.Internal } var typeOrg = type; if (type.IsNullableType()) type = type.GetGenericArguments().First(); - if (type.IsEnum) - return Expression.Block( - Expression.IfThenElse( - Expression.Equal(Expression.TypeAs(valueExp, typeof(string)), Expression.Constant(string.Empty)), - Expression.Return(returnTarget, Expression.Convert(Expression.Default(type), typeof(object))), - Expression.Return(returnTarget, Expression.Call(MethodEnumParse, Expression.Constant(type, typeof(Type)), Expression.Call(MethodToString, valueExp), Expression.Constant(true, typeof(bool)))) - ) - ); Expression tryparseExp = null; Expression tryparseBooleanExp = null; ParameterExpression tryparseVarExp = null; @@ -1860,6 +1875,16 @@ namespace FreeSql.Internal ) } ); + case "System.Char": + return Expression.IfThenElse( + Expression.TypeEqual(valueExp, type), + Expression.Return(returnTarget, valueExp), + Expression.IfThenElse( + Expression.TypeEqual(valueExp, typeof(string)), + Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodStringToChar, Expression.Convert(valueExp, typeof(string))), typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodStringToChar, Expression.Call(MethodToString, valueExp)), typeof(object))) + ) + ); case "System.SByte": tryparseExp = Expression.Block( new[] { tryparseVarExp = Expression.Variable(typeof(sbyte)) }, @@ -2029,6 +2054,14 @@ namespace FreeSql.Internal ); break; default: + if (type.IsEnum) + return Expression.Block( + Expression.IfThenElse( + Expression.Equal(Expression.TypeAs(valueExp, typeof(string)), Expression.Constant(string.Empty)), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(type), typeof(object))), + Expression.Return(returnTarget, Expression.Call(MethodEnumParse, Expression.Constant(type, typeof(Type)), Expression.Call(MethodToString, valueExp), Expression.Constant(true, typeof(bool)))) + ) + ); foreach (var switchFunc in GetDataReaderValueBlockExpressionSwitchTypeFullName) { var switchFuncRet = switchFunc(returnTarget, valueExp, type); diff --git a/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs b/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs index af9caf76..68f0c7ed 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs @@ -41,8 +41,10 @@ namespace FreeSql.Dameng return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; else if (param is bool || param is bool?) return (bool)param ? 1 : 0; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs index 6da2899d..2e1736fd 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs @@ -42,6 +42,7 @@ namespace FreeSql.Dameng { typeof(byte[]).FullName, CsToDb.New(DmDbType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(DmDbType.VarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(char).FullName, CsToDb.New(DmDbType.Char, "char", "char(1) NULL", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(DmDbType.Char, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DmDbType.Char, "char", "char(36) NULL", false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs index 496e9d1e..a86c5a4f 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs @@ -42,8 +42,10 @@ namespace FreeSql.MsAccess if (param is bool || param is bool?) return (bool)param ? -1 : 0; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs index dcffefd5..6f419a8e 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessCodeFirst.cs @@ -39,6 +39,7 @@ namespace FreeSql.MsAccess { typeof(byte[]).FullName, CsToDb.New(OleDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(OleDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OleDbType.VarChar, "varchar", "varchar(1)", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(OleDbType.Guid, "varchar", "varchar(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OleDbType.Guid, "varchar", "varchar(36)", false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index 64427c6a..dd9fdbab 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -45,8 +45,10 @@ namespace FreeSql.MySql if (param is bool || param is bool?) return (bool)param ? 1 : 0; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //只有 mysql 需要处理反斜杠 + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\").Replace('\0', ' '), "'"); else if (param is Enum) return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //((Enum)val).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 7b997653..45cd3dda 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -45,6 +45,7 @@ namespace FreeSql.MySql { typeof(byte[]).FullName, CsToDb.New(MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(MySqlDbType.VarChar, "char", "char(1)", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(MySqlDbType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(MySqlDbType.VarChar, "char", "char(36)", false, true, null) }, diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index 71547169..478dec5e 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -42,8 +42,10 @@ namespace FreeSql.Odbc.Dameng return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; else if (param is bool || param is bool?) return (bool)param ? 1 : 0; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 72a18e0a..8fd5f373 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -43,6 +43,7 @@ namespace FreeSql.Odbc.Dameng { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(OdbcType.NVarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OdbcType.Char, "char", "char(1) NULL", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(OdbcType.Char, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.Char, "char", "char(36) NULL", false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs index 745091fe..7a9cbfd4 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdapter.cs @@ -38,6 +38,7 @@ namespace FreeSql.Odbc.Default public virtual string MappingOdbcTypeDateTime => "datetime"; public virtual string MappingOdbcTypeVarBinary => "varbinary"; public virtual string MappingOdbcTypeVarChar => "nvarchar"; + public virtual string MappingOdbcTypeChar => "char"; public virtual string MappingOdbcTypeText => "nvarchar(max)"; public virtual string MappingOdbcTypeUniqueIdentifier => "uniqueidentifier"; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index eb17053b..ce5ca081 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -45,7 +45,7 @@ namespace FreeSql.Odbc.Default else if (param is string) return Adapter.UnicodeStringRawSql(param, mapColumn); else if (param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs index 5d758171..5e848443 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs @@ -56,6 +56,7 @@ namespace FreeSql.Odbc.Default { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, _utils.Adapter.MappingOdbcTypeVarBinary, $"{_utils.Adapter.MappingOdbcTypeVarBinary}(255)", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, _utils.Adapter.MappingOdbcTypeVarChar, $"{_utils.Adapter.MappingOdbcTypeVarChar}(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OdbcType.Char, _utils.Adapter.MappingOdbcTypeChar, $"{_utils.Adapter.MappingOdbcTypeChar}(1)", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, deleteBrackets(_utils.Adapter.MappingOdbcTypeUniqueIdentifier), $"{_utils.Adapter.MappingOdbcTypeUniqueIdentifier} NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, deleteBrackets(_utils.Adapter.MappingOdbcTypeUniqueIdentifier), _utils.Adapter.MappingOdbcTypeUniqueIdentifier, false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs index b647490f..11d37474 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs @@ -41,8 +41,10 @@ namespace FreeSql.Odbc.KingbaseES if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs index 6ea23cb2..1c75a1e0 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs @@ -35,6 +35,7 @@ namespace FreeSql.Odbc.KingbaseES { typeof(decimal).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OdbcType.Char, "bpchar", "bpchar(1) NULL", false, null, '\0') }, { typeof(TimeSpan).FullName, CsToDb.New(OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OdbcType.Time, "time", "time",false, true, null) }, { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp", false, true, null) }, diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs index 56bb6382..9c8d470c 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs @@ -35,6 +35,7 @@ namespace FreeSql.Odbc.KingbaseES { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() }, }; static object getParamterValue(Type type, object value, int level = 0) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index 4b9196ca..b1d7573d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -41,8 +41,10 @@ namespace FreeSql.Odbc.MySql if (param is bool || param is bool?) return (bool)param ? 1 : 0; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //只有 mysql 需要处理反斜杠 + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\").Replace('\0', ' '), "'"); else if (param is Enum) return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //((Enum)val).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 6fc5f92d..e1fb6792 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -41,6 +41,7 @@ namespace FreeSql.Odbc.MySql { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OdbcType.Char, "char", "char(1) NULL", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(OdbcType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.VarChar, "char", "char(36)", false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index 699f2912..e0041666 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -42,8 +42,10 @@ namespace FreeSql.Odbc.Oracle return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; else if (param is bool || param is bool?) return (bool)param ? 1 : 0; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index fb6f9549..18b7a2cd 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -43,6 +43,7 @@ namespace FreeSql.Odbc.Oracle { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(OdbcType.NVarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OdbcType.Char, "char", "char(1 CHAR) NULL", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(OdbcType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index d37dc5ba..72c196a5 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -42,8 +42,10 @@ namespace FreeSql.Odbc.PostgreSQL if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index ee4f79d5..471b4f54 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -33,6 +33,7 @@ namespace FreeSql.Odbc.PostgreSQL { typeof(decimal).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OdbcType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, { typeof(string).FullName, CsToDb.New(OdbcType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OdbcType.Char, "char", "char(1) NULL", false, null, '\0') }, { typeof(TimeSpan).FullName, CsToDb.New(OdbcType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OdbcType.Time, "time", "time",false, true, null) }, { typeof(DateTime).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OdbcType.DateTime, "timestamp", "timestamp", false, true, null) }, diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 7a223e82..1182028e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -35,6 +35,7 @@ namespace FreeSql.Odbc.PostgreSQL { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() }, }; static object getParamterValue(Type type, object value, int level = 0) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index 0bba96e3..c6277105 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -50,7 +50,7 @@ namespace FreeSql.Odbc.SqlServer return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); } else if (param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 8636b79b..a5ea6588 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -41,6 +41,7 @@ namespace FreeSql.Odbc.SqlServer { typeof(byte[]).FullName, CsToDb.New(OdbcType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(OdbcType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OdbcType.Char, "char", "char(1) NULL", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OdbcType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 59ac3c98..f0c42708 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -42,8 +42,10 @@ namespace FreeSql.Oracle return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; else if (param is bool || param is bool?) return (bool)param ? 1 : 0; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 6bb3411a..7cdeeeb0 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -44,6 +44,7 @@ namespace FreeSql.Oracle { typeof(byte[]).FullName, CsToDb.New(OracleDbType.Blob, "blob", "blob NULL", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OracleDbType.Char, "char", "char(1 CHAR) NULL", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(OracleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OracleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index 3e9423dc..12bfafcc 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -44,8 +44,10 @@ namespace FreeSql.PostgreSQL bool isdic; if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index c7834ba8..c0bc4d02 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -39,6 +39,7 @@ namespace FreeSql.PostgreSQL { typeof(decimal).FullName, CsToDb.New(NpgsqlDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(NpgsqlDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, { typeof(string).FullName, CsToDb.New(NpgsqlDbType.Varchar, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(NpgsqlDbType.Char, "bpchar", "bpchar(1)", false, null, '\0') }, { typeof(TimeSpan).FullName, CsToDb.New(NpgsqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(NpgsqlDbType.Time, "time", "time",false, true, null) }, { typeof(DateTime).FullName, CsToDb.New(NpgsqlDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(NpgsqlDbType.Timestamp, "timestamp", "timestamp", false, true, null) }, diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index ed6cb447..30d9422c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -44,6 +44,7 @@ namespace FreeSql.PostgreSQL { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() }, { typeof(NpgsqlPath).FullName, a => { var path = (NpgsqlPath)a; @@ -70,6 +71,7 @@ namespace FreeSql.PostgreSQL static object getParamterValue(Type type, object value, int level = 0) { if (type.FullName == "System.Byte[]") return value; + if (type.FullName == "System.Char[]") return value; if (type.IsArray && level == 0) { var elementType = type.GetElementType(); diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs index fee92115..eaa0e7b3 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs @@ -42,8 +42,10 @@ namespace FreeSql.ShenTong if (param is bool || param is bool?) return (bool)param ? "'t'" : "'f'"; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs index efe5d19e..2b369a01 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs @@ -37,6 +37,7 @@ namespace FreeSql.ShenTong { typeof(decimal).FullName, CsToDb.New(OscarDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OscarDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, { typeof(string).FullName, CsToDb.New(OscarDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(OscarDbType.Char, "bpchar", "bpchar(1)", false, null, '\0') }, { typeof(TimeSpan).FullName, CsToDb.New(OscarDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OscarDbType.Time, "time", "time",false, true, null) }, { typeof(DateTime).FullName, CsToDb.New(OscarDbType.TimeStamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OscarDbType.TimeStamp, "timestamp", "timestamp", false, true, null) }, @@ -242,7 +243,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER TYPE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs index 227d7c13..bf0e67f4 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs @@ -38,6 +38,7 @@ namespace FreeSql.ShenTong { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() }, }; static object getParamterValue(Type type, object value, int level = 0) { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index ea278f04..577eb94a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -51,7 +51,7 @@ namespace FreeSql.SqlServer return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); } else if (param is char) - return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index a62f4e24..450555ff 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -40,6 +40,7 @@ namespace FreeSql.SqlServer { typeof(byte[]).FullName, CsToDb.New(SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(SqlDbType.Char, "char", "char(1)", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) }, }; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index c1cc9252..1f928e46 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -43,8 +43,10 @@ namespace FreeSql.Sqlite if (param is bool || param is bool?) return (bool)param ? 1 : 0; - else if (param is string || param is char) + else if (param is string) return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); else if (param is Enum) return ((Enum)param).ToInt64(); else if (decimal.TryParse(string.Concat(param), out var trydec)) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 3d8dc14f..fee7a0b0 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -38,6 +38,7 @@ namespace FreeSql.Sqlite { typeof(byte[]).FullName, CsToDb.New(DbType.Binary, "blob", "blob", false, null, new byte[0]) }, { typeof(string).FullName, CsToDb.New(DbType.String, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(DbType.AnsiString, "char", "char(1)", false, null, '\0') }, { typeof(Guid).FullName, CsToDb.New(DbType.Guid, "character", "character(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DbType.Guid, "character", "character(36)", false, true, null) }, }; From dd22727a119c2899388daa6948796f89427780da Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 22 Jul 2020 09:46:09 +0800 Subject: [PATCH 0766/1029] 1.7.0-preview0722 #381 #235 #360 #330 #316 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index dc717ee4..129e7fdc 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index d970fa1f..9d9dbb2b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b22c90fe..ac80a610 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 17f7e517..ea73e7f6 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index e1c5efb7..a8235cf9 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0718 + 1.7.0-preview0722 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index e792b8d8..442ae8a7 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 046d3b9c..7bb0f5c6 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 66ecb7e6..ee1e554b 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 309b5433..3c5af36b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 2cb79490..8d18b377 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index ba8eeaab..75fadc51 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 665d61b2..b2898a0a 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 255cb6d9..4e042349 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0d55ce64..0de3e856 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b8eb1a89..23e97f86 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 79ac5af3..eb160d58 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index cb2102f7..039137c9 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 046517a2..b0364443 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 185e76fb..932c0142 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0718 + 1.7.0-preview0722 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From b3ed610f824691c00685212fc946a6a62cb4c599 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 22 Jul 2020 22:35:42 +0800 Subject: [PATCH 0767/1029] update readme --- readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/readme.md b/readme.md index f1a89f03..59830565 100644 --- a/readme.md +++ b/readme.md @@ -191,7 +191,6 @@ L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.9 > Thank you for your donation -| | | +| [Alipay](https://images.cnblogs.com/cnblogs_com/kellynic/133561/o_200417052520IMG_7936(20200123-155553).png) | [WeChat](https://images.cnblogs.com/cnblogs_com/kellynic/133561/o_200417052707IMG_7935(20200123-155553).png) | | - | - | | | | - From 83f4c69d21559951f25513692c6ac69553115e32 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Thu, 23 Jul 2020 23:40:00 +0800 Subject: [PATCH 0768/1029] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 59830565..2a395ae4 100644 --- a/readme.md +++ b/readme.md @@ -30,10 +30,10 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ > 示范项目 -- [iusaas.com SaaS 企业应用管理系统](https://github.com/alonsoalon/TenantSite.Server) - [zhontai.net Admin 后台管理系统](https://github.com/zhontai/Admin.Core) - [A simple and practical CMS implememted by .NET Core](https://github.com/luoyunchong/lin-cms-dotnetcore) -- [EasyCms 满足企业建站,事业单位使用的CMS管理系统](https://github.com/jasonyush/EasyCMS) +- [iusaas.com SaaS 企业应用管理系统](https://github.com/alonsoalon/TenantSite.Server) +- [EasyCms 企业建站,事业单位使用的CMS管理系统](https://github.com/jasonyush/EasyCMS) - [内容管理系统](https://github.com/hejiyong/fscms)

From 2565dbd8194b1f9fa006307d59de09465402126d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 24 Jul 2020 23:46:22 +0800 Subject: [PATCH 0769/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20pgsql=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20Contains=20ilik?= =?UTF-8?q?e=20=E5=88=A4=E6=96=AD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KingbaseES/OdbcKingbaseESExpression.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 2 +- Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs | 2 +- Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index 710fb0b7..2026e132 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -334,7 +334,7 @@ namespace FreeSql.Odbc.KingbaseES if (exp.Arguments.Count > 1) { if (exp.Arguments[1].Type == typeof(bool) || - exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + exp.Arguments[1].Type == typeof(StringComparison)) likeOpt = "ILIKE"; } if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 448007ba..af295373 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -356,7 +356,7 @@ namespace FreeSql.Odbc.PostgreSQL if (exp.Arguments.Count > 1) { if (exp.Arguments[1].Type == typeof(bool) || - exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + exp.Arguments[1].Type == typeof(StringComparison)) likeOpt = "ILIKE"; } if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 3d989330..6d242474 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -387,7 +387,7 @@ namespace FreeSql.PostgreSQL if (exp.Arguments.Count > 1) { if (exp.Arguments[1].Type == typeof(bool) || - exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + exp.Arguments[1].Type == typeof(StringComparison)) likeOpt = "ILIKE"; } if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index 8476885f..bf246b69 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -317,7 +317,7 @@ namespace FreeSql.ShenTong if (exp.Arguments.Count > 1) { if (exp.Arguments[1].Type == typeof(bool) || - exp.Arguments[1].Type == typeof(StringComparison) && getExp(exp.Arguments[0]).Contains("IgnoreCase")) likeOpt = "ILIKE"; + exp.Arguments[1].Type == typeof(StringComparison)) likeOpt = "ILIKE"; } if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; From e80f1796638d74ae7c0573633fadaadb245dbd86 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 26 Jul 2020 09:34:49 +0800 Subject: [PATCH 0770/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20$"{a.Code}?= =?UTF-8?q?=5F{a.Id}"=20lambda=20=E8=A7=A3=E6=9E=90=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=20null=20=E7=9B=B8=E8=BF=9E=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../MySqlConnectorExpression/StringTest.cs | 2 +- .../Dameng/DamengExpression/StringTest.cs | 2 +- .../KingbaseESExpression/StringTest.cs | 2 +- .../MySql/MySqlExpression/StringTest.cs | 2 +- .../Oracle/OracleExpression/StringTest.cs | 2 +- .../PostgreSQLExpression/StringTest.cs | 2 +- .../SqlServer/SqlServerExpression/StringTest.cs | 2 +- .../Dameng/DamengExpression/StringTest.cs | 2 +- .../MsAccess/MsAccessExpression/StringTest.cs | 2 +- .../MySql/MySqlExpression/StringTest.cs | 2 +- .../Oracle/OracleExpression/StringTest.cs | 2 +- .../PostgreSQLExpression/StringTest.cs | 2 +- .../ShenTong/ShenTongExpression/StringTest.cs | 2 +- .../SqlServer/SqlServerExpression/StringTest.cs | 2 +- .../Sqlite/SqliteExpression/StringTest.cs | 2 +- .../FreeSql.Provider.Dameng/DamengExpression.cs | 2 +- .../MsAccessExpression.cs | 7 ++++++- .../FreeSql.Provider.MySql/MySqlExpression.cs | 2 +- .../Dameng/OdbcDamengExpression.cs | 2 +- .../KingbaseES/OdbcKingbaseESExpression.cs | 7 ++++++- .../MySql/OdbcMySqlExpression.cs | 2 +- .../Oracle/OdbcOracleExpression.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 7 ++++++- .../SqlServer/OdbcSqlServerExpression.cs | 8 ++++---- .../FreeSql.Provider.Oracle/OracleExpression.cs | 2 +- .../PostgreSQLExpression.cs | 7 ++++++- .../ShenTongExpression.cs | 2 +- .../SqlServerExpression.cs | 8 ++++---- .../FreeSql.Provider.Sqlite/SqliteExpression.cs | 2 +- 30 files changed, 55 insertions(+), 51 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.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 55f11292..967a0d3c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -61,7 +61,7 @@ namespace FreeSql.Tests.MySqlConnectorExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 + Assert.Equal($@"SELECT concat('x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'') as1, concat('',ifnull((a.`Id` + 1), ''),'x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'') as2 FROM `tb_topic` a WHERE (a.`Id` = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs index 7f3f3a92..21bf1473 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.Odbc.DamengExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as2 FROM ""TB_TOPIC"" a WHERE (a.""ID"" = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs index 99ee1aa8..f686574a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.Odbc.KingbaseESExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as2 + Assert.Equal($@"SELECT 'x'||coalesce(((a.""ID"" + 1))::text, '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce(((a.""ID"" + 1))::text, '')||'x'||coalesce(((a.""ID"" + 1))::text, '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||'' as2 FROM ""TB_TOPIC"" a WHERE (a.""ID"" = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs index 370a2b01..6696908e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs @@ -61,7 +61,7 @@ namespace FreeSql.Tests.Odbc.MySqlExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 + Assert.Equal($@"SELECT concat('x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'') as1, concat('',ifnull((a.`Id` + 1), ''),'x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'') as2 FROM `tb_topic` a WHERE (a.`Id` = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs index 7df9d90d..10dac97a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.Odbc.OracleExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as2 FROM ""TB_TOPIC"" a WHERE (a.""ID"" = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs index 60f1eb3b..a189c1d2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as1, ''||((a.""id"" + 1))||'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as2 + Assert.Equal($@"SELECT 'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||'' as1, ''||coalesce(((a.""id"" + 1))::text, '')||'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||'' as2 FROM ""tb_topic"" a WHERE (a.""id"" = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs index 7b6834e1..97cd6e1d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs @@ -60,7 +60,7 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as1, N''+cast((a.[Id] + 1) as varchar)+N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as2 + Assert.Equal($@"SELECT N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N'' as1, N''+isnull(cast((a.[Id] + 1) as varchar), '')+N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N'' as2 FROM [tb_topic] a WHERE (a.[Id] = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs index 2a9d28a9..93789c17 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.DamengExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as2 FROM ""TB_TOPIC"" a WHERE (a.""ID"" = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs index 60b9fd18..5940417e 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.MsAccessExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'+cstr((a.[Id] + 1))+'z-'+(format(a.[CreateTime],'yyyyMM'))+''+(a.[Title])+'' as as1, ''+cstr((a.[Id] + 1))+'x'+cstr((a.[Id] + 1))+'z-'+(format(a.[CreateTime],'yyyyMM'))+''+(a.[Title])+'' as as2 + Assert.Equal($@"SELECT 'x'+iif(isnull(cstr((a.[Id] + 1))), '', cstr((a.[Id] + 1)))+'z-'+iif(isnull(format(a.[CreateTime],'yyyyMM')), '', format(a.[CreateTime],'yyyyMM'))+''+iif(isnull(a.[Title]), '', a.[Title])+'' as as1, ''+iif(isnull(cstr((a.[Id] + 1))), '', cstr((a.[Id] + 1)))+'x'+iif(isnull(cstr((a.[Id] + 1))), '', cstr((a.[Id] + 1)))+'z-'+iif(isnull(format(a.[CreateTime],'yyyyMM')), '', format(a.[CreateTime],'yyyyMM'))+''+iif(isnull(a.[Title]), '', a.[Title])+'' as as2 FROM [tb_topic] a WHERE (a.[Id] = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index 0724c12c..ad563009 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -61,7 +61,7 @@ namespace FreeSql.Tests.MySqlExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT concat('x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as1, concat('',(a.`Id` + 1),'x',(a.`Id` + 1),'z-',date_format(a.`CreateTime`,'%Y%m'),'',a.`Title`,'') as2 + Assert.Equal($@"SELECT concat('x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'') as1, concat('',ifnull((a.`Id` + 1), ''),'x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'') as2 FROM `tb_topic` a WHERE (a.`Id` = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index bb970771..d5e7dbcc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.OracleExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char(a.""CREATETIME"",'YYYYMM'))||''||(a.""TITLE"")||'' as2 + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as2 FROM ""TB_TOPIC"" a WHERE (a.""ID"" = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index 43fac79b..e8701a56 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.PostgreSQLExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as1, ''||((a.""id"" + 1))||'x'||((a.""id"" + 1))||'z-'||(to_char((a.""createtime"")::timestamp,'YYYYMM'))||''||(a.""title"")||'' as2 + Assert.Equal($@"SELECT 'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||'' as1, ''||coalesce(((a.""id"" + 1))::text, '')||'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||'' as2 FROM ""tb_topic"" a WHERE (a.""id"" = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs index 745192bf..0e263375 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.ShenTongExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as1, ''||((a.""ID"" + 1))||'x'||((a.""ID"" + 1))||'z-'||(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'))||''||(a.""TITLE"")||'' as2 + Assert.Equal($@"SELECT 'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce((a.""ID"" + 1), '')||'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||'' as2 FROM ""TB_TOPIC"" a WHERE (a.""ID"" = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index 02d36262..425c02e3 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -74,7 +74,7 @@ namespace FreeSql.Tests.SqlServerExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as1, N''+cast((a.[Id] + 1) as varchar)+N'x'+cast((a.[Id] + 1) as varchar)+N'z-'+(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6))+N''+(a.[Title])+N'' as2 + Assert.Equal($@"SELECT N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N'' as1, N''+isnull(cast((a.[Id] + 1) as varchar), '')+N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N'' as2 FROM [tb_topic] a WHERE (a.[Id] = {item.Id})", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index a64ce3ad..be68623e 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -59,7 +59,7 @@ namespace FreeSql.Tests.SqliteExpression str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) }); - Assert.Equal($@"SELECT 'x'||((a.""Id"" + 1))||'z-'||(strftime('%Y%m',a.""CreateTime""))||''||(a.""Title"")||'' as1, ''||((a.""Id"" + 1))||'x'||((a.""Id"" + 1))||'z-'||(strftime('%Y%m',a.""CreateTime""))||''||(a.""Title"")||'' as2 + Assert.Equal($@"SELECT 'x'||ifnull((a.""Id"" + 1), '')||'z-'||ifnull(strftime('%Y%m',a.""CreateTime""), '')||''||ifnull(a.""Title"", '')||'' as1, ''||ifnull((a.""Id"" + 1), '')||'x'||ifnull((a.""Id"" + 1), '')||'z-'||ifnull(strftime('%Y%m',a.""CreateTime""), '')||''||ifnull(a.""Title"", '')||'' as2 FROM ""tb_topic"" a WHERE (a.""Id"" = {item.Id})", sql); diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index b9fb0a5f..145a843b 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -252,7 +252,7 @@ namespace FreeSql.Dameng return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs index 84686afc..5ba654dd 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -222,7 +222,12 @@ namespace FreeSql.MsAccess return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'+{(((a as UnaryExpression)?.Operand.Type ?? a.Type) == typeof(string) ? $"({ExpressionLambdaToSql(a, tsc)})" : $"cstr({ExpressionLambdaToSql(a, tsc)})")}+'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + { + var asql = ((a as UnaryExpression)?.Operand.Type ?? a.Type) == typeof(string) ? $"{ExpressionLambdaToSql(a, tsc)}" : $"cstr({ExpressionLambdaToSql(a, tsc)})"; + return $"'+{_common.IsNull(asql, "''")}+'"; + } + ).ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 1c409970..3365aacb 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -251,7 +251,7 @@ namespace FreeSql.MySql case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{ExpressionLambdaToSql(a, tsc)},'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; } } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index 4220259f..d5cbb4cb 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -252,7 +252,7 @@ namespace FreeSql.Odbc.Dameng return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index 2026e132..ad1c40da 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -316,7 +316,12 @@ namespace FreeSql.Odbc.KingbaseES return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'"; + return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'"; + }).ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index cbadc1e1..128e750c 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -249,7 +249,7 @@ namespace FreeSql.Odbc.MySql case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{ExpressionLambdaToSql(a, tsc)},'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index b68ff8c4..7ed64b54 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -252,7 +252,7 @@ namespace FreeSql.Odbc.Oracle return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index af295373..c8ee191c 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -338,7 +338,12 @@ namespace FreeSql.Odbc.PostgreSQL return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'"; + return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'"; + }).ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index c6ffd0a2..c0aaa4e3 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -264,10 +264,10 @@ namespace FreeSql.Odbc.SqlServer var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => { var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); - if (atype == typeof(string)) return $"'+({ExpressionLambdaToSql(a, tsc)})+{nchar}'"; - if (atype == typeof(Guid)) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as char(36))+{nchar}'"; - if (atype.IsNumberType()) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as varchar)+{nchar}'"; - return $"'+cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))+{nchar}'"; + if (atype == typeof(string)) return $"'+{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}+{nchar}'"; + if (atype == typeof(Guid)) return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as char(36))", "''")}+{nchar}'"; + if (atype.IsNumberType()) return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as varchar)", "''")}+{nchar}'"; + return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))", "''")}+{nchar}'"; }).ToArray(); return string.Format(expArgs0, expArgs); } diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 989921f7..2c9f768b 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -252,7 +252,7 @@ namespace FreeSql.Oracle return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 6d242474..a65ff443 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -369,7 +369,12 @@ namespace FreeSql.PostgreSQL return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'"; + return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'"; + }).ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index bf246b69..078128c9 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -299,7 +299,7 @@ namespace FreeSql.ShenTong return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 65bb2fd1..1e29c6db 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -263,10 +263,10 @@ namespace FreeSql.SqlServer var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => { var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); - if (atype == typeof(string)) return $"'+({ExpressionLambdaToSql(a, tsc)})+{nchar}'"; - if (atype == typeof(Guid)) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as char(36))+{nchar}'"; - if (atype.IsNumberType()) return $"'+cast({ExpressionLambdaToSql(a, tsc)} as varchar)+{nchar}'"; - return $"'+cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))+{nchar}'"; + if (atype == typeof(string)) return $"'+{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}+{nchar}'"; + if (atype == typeof(Guid)) return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as char(36))", "''")}+{nchar}'"; + if (atype.IsNumberType()) return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as varchar)", "''")}+{nchar}'"; + return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))", "''")}+{nchar}'"; }).ToArray(); return string.Format(expArgs0, expArgs); } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 83888e2b..ba7f0093 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -248,7 +248,7 @@ namespace FreeSql.Sqlite return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||({ExpressionLambdaToSql(a, tsc)})||'").ToArray(); + var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } From 072a8b7cfaad91096bc5b76de0fa4474afacaa17 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 27 Jul 2020 19:39:12 +0800 Subject: [PATCH 0771/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20FreeSql.Prov?= =?UTF-8?q?ider.SqlServer=20=E5=BC=95=E7=94=A8Microsoft.Data.SqlClient=20#?= =?UTF-8?q?391=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj | 1 + .../SqlServer/SqlServerAdo/SqlServerAdoTest.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 2 +- FreeSql.Tests/FreeSql.Tests/g.cs | 1 + .../FreeSql.Provider.PostgreSQL.csproj | 4 ++-- .../FreeSql.Provider.SqlServer.csproj | 11 +++++++---- .../SqlServerAdo/SqlServerAdo.cs | 15 ++++++++++++++- .../SqlServerAdo/SqlServerConnectionPool.cs | 4 ++++ .../SqlServerExtensions.cs | 4 ++++ .../FreeSql.Provider.SqlServer/SqlServerUtils.cs | 6 +++++- 10 files changed, 40 insertions(+), 10 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 9e16a021..926e775f 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -17,6 +17,7 @@ + diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index 3845a2d0..7dc5c181 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -79,7 +79,7 @@ namespace FreeSql.Tests.SqlServer var t4 = g.sqlserver.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); var t5 = g.sqlserver.Ado.Query(System.Data.CommandType.Text, "select * from xxx where Id = @Id", - new System.Data.SqlClient.SqlParameter("Id", 1)); + new Microsoft.Data.SqlClient.SqlParameter("Id", 1)); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 3d0d109b..b93400ef 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -11,7 +11,7 @@ using System.Linq.Expressions; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; using System.Threading; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using kwlib; using System.Text; diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 1fc3ae7d..0e99a61a 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -41,6 +41,7 @@ public class g static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + //.UseConnectionFactory(FreeSql.DataType.SqlServer, () => new Microsoft.Data.SqlClient.SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;")) //.UseConnectionFactory(FreeSql.DataType.SqlServer, () => new System.Data.SqlClient.SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;")) //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;Max Pool Size=3") //.UseConnectionFactory(FreeSql.DataType.SqlServer, () => new System.Data.SqlClient.SqlConnection("Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;")) diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index eb160d58..18cc1ba4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -30,8 +30,8 @@ - - + + diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b0364443..d0ee8a19 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net451;net45;net40 + netstandard2.0;net461;net40 1.7.0-preview0722 true ncc;YeXiangQin @@ -25,14 +25,17 @@ - - + + - + + + microsoft + net40 diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 577eb94a..f7b1be7d 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -4,7 +4,11 @@ using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; +#if microsoft +using Microsoft.Data.SqlClient; +#else using System.Data.SqlClient; +#endif using System.Linq; using System.Text; using System.Threading; @@ -19,7 +23,9 @@ namespace FreeSql.SqlServer base._util = util; if (connectionFactory != null) { - MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.SqlServer, connectionFactory); + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Sqlite, connectionFactory); + MasterPool = pool; + _CreateCommandConnection = pool.TestConnection; return; } if (!string.IsNullOrEmpty(masterConnectionString)) @@ -76,8 +82,15 @@ namespace FreeSql.SqlServer return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } + DbConnection _CreateCommandConnection; protected override DbCommand CreateCommand() { + if (_CreateCommandConnection != null) + { + var cmd = _CreateCommandConnection.CreateCommand(); + cmd.Connection = null; + return cmd; + } return new SqlCommand(); } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 6e543e31..4ab167c7 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -4,7 +4,11 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Data.Common; +#if microsoft +using Microsoft.Data.SqlClient; +#else using System.Data.SqlClient; +#endif using System.Text.RegularExpressions; using System.Threading.Tasks; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 5fc21290..5cc172ad 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -3,7 +3,11 @@ using FreeSql.Internal.Model; using System; using System.Collections.Concurrent; using System.Collections.Generic; +#if microsoft +using Microsoft.Data.SqlClient; +#else using System.Data.SqlClient; +#endif using System.Threading.Tasks; public static partial class FreeSqlSqlServerGlobalExtensions diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index f05d3a8c..be0468f3 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -4,7 +4,11 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.Common; +#if microsoft +using Microsoft.Data.SqlClient; +#else using System.Data.SqlClient; +#endif using System.Globalization; using System.Text; @@ -44,7 +48,7 @@ namespace FreeSql.SqlServer } public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => - Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); var ret = new SqlParameter { ParameterName = $"@{name}", Value = value }; From b9a0251ef1fafacd437993a45fbf6a262429a629 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 27 Jul 2020 19:57:53 +0800 Subject: [PATCH 0772/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20GroupBy(..).?= =?UTF-8?q?Count()=20=E5=BC=80=E5=90=AF=E5=8F=82=E6=95=B0=E5=8C=96?= =?UTF-8?q?=E6=97=A0=E6=95=88=E7=9A=84=20bug=20#390=EF=BC=9B=20UseGenerate?= =?UTF-8?q?CommandParameterWithLambda?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/Issues/390.cs | 60 +++++++++++++++++++ .../SelectProvider/SelectGroupingProvider.cs | 21 ++++--- 2 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/390.cs diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/390.cs b/FreeSql.Tests/FreeSql.Tests/Issues/390.cs new file mode 100644 index 00000000..bac347c8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/390.cs @@ -0,0 +1,60 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _390 + { + [Fact] + public void SelectTest() + { + IFreeSql db = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=1") + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + .UseGenerateCommandParameterWithLambda(true) + .UseAutoSyncStructure(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build(); + + var startTime = DateTime.Now; + var endTime = DateTime.Now; + + var cou = db.Select() + .Where(a => a.ScheduledDttm.Date >= startTime.Date && a.ScheduledDttm.Date <= (endTime.AddDays(1)).Date) + .GroupBy(a => + new + { + a.HospitalName, + a.Dep, + a.Instrna, + a.ConfirmDoctorName, + a.ScheduledDttm.Date + }) + .Count(); + } + + [Table(Name = "V_HospitalReport")] + public class V_HospitalReport + { + [Column(Name = "hospital_name")] + public string HospitalName { get; set; } + + [Column(Name = "dep")] + public string Dep { get; set; } + + [Column(Name = "instrna")] + public string Instrna { get; set; } + + [Column(Name = "confirm_doctor_name")] + public string ConfirmDoctorName { get; set; } + + [Column(Name = "Scheduled_Dttm")] + public DateTime ScheduledDttm { get; set; } + } + } +} diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index e353c0f5..85f208d0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Data; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -13,13 +14,13 @@ namespace FreeSql.Internal.CommonProvider public class SelectGroupingProvider { public IFreeSql _orm; - public object _select; + public Select0Provider _select; public ReadAnonymousTypeInfo _map; public string _field; public CommonExpression _comonExp; public List _tables; - public SelectGroupingProvider(IFreeSql orm, object select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List tables) + public SelectGroupingProvider(IFreeSql orm, Select0Provider select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List tables) { _orm = orm; _select = select; @@ -139,7 +140,7 @@ namespace FreeSql.Internal.CommonProvider public class SelectGroupingProvider : SelectGroupingProvider, ISelectGrouping { - public SelectGroupingProvider(IFreeSql orm, object select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List tables) + public SelectGroupingProvider(IFreeSql orm, Select0Provider select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List tables) :base(orm, select, map, field, comonExp, tables) { } public string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) => InternalToSql(select, fieldAlias); @@ -154,26 +155,24 @@ namespace FreeSql.Internal.CommonProvider public ISelectGrouping Skip(int offset) { - var method = _select.GetType().GetMethod("Skip", new[] { typeof(int) }); - method.Invoke(_select, new object[] { offset }); + _select._skip = offset; return this; } public ISelectGrouping Offset(int offset) => this.Skip(offset); public ISelectGrouping Limit(int limit) { - var method = _select.GetType().GetMethod("Limit", new[] { typeof(int) }); - method.Invoke(_select, new object[] { limit }); + _select._limit = limit; return this; } public ISelectGrouping Take(int limit) => this.Limit(limit); public ISelectGrouping Page(int pageNumber, int pageSize) { - var method = _select.GetType().GetMethod("Page", new[] { typeof(int), typeof(int) }); - method.Invoke(_select, new object[] { pageNumber, pageSize }); + _select._skip = Math.Max(0, pageNumber - 1) * pageSize; + _select._limit = pageSize; return this; } - public long Count() => long.TryParse(string.Concat(_orm.Ado.ExecuteScalar($"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta")), out var trylng) ? trylng : default(long); + public long Count() => long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._params.ToArray())), out var trylng) ? trylng : default(long); public ISelectGrouping Count(out long count) { count = this.Count(); @@ -202,7 +201,7 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync($"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta")), out var trylng) ? trylng : default(long); + async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._params.ToArray())), out var trylng) ? trylng : default(long); public Task> ToListAsync(Expression, TReturn>> select) => InternalToList(select, typeof(TReturn), true) as Task>; async public Task> ToDictionaryAsync(Expression, TElement>> elementSelector) From c2749bad655bd92465ce6b3be7127c54a0d4ef8e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 27 Jul 2020 20:21:14 +0800 Subject: [PATCH 0773/1029] v1.7.0 #391 #390 #382 #381 #380 #371 #369 #366 #365 #362 #360 #235 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 35 insertions(+), 19 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 129e7fdc..a4e4d38c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 9d9dbb2b..ced431c1 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ac80a610..486ed182 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index ea73e7f6..c913d8ca 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index a8235cf9..1f216a0f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0-preview0722 + 1.7.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 442ae8a7..9ae898d9 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 7bb0f5c6..99bbdf7f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index ee1e554b..766232a7 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0-preview0722 + 1.7.0 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3c5af36b..315751b6 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 8d18b377..fccaad5c 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 75fadc51..2f33a2fe 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b2898a0a..c54c97f4 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4e042349..97d21f2a 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0de3e856..3ce18b1f 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 23e97f86..1c16358b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 18cc1ba4..116b962a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 039137c9..e5d12327 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d0ee8a19..5b94bcfc 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 932c0142..e3ac160b 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0-preview0722 + 1.7.0 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From de86beba4f92806192cd2a5ad1d9a0c527ba8d42 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 29 Jul 2020 10:59:47 +0800 Subject: [PATCH 0774/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20$"{a.Code}?= =?UTF-8?q?=5F{a.Id}"=20lambda=20=E8=A7=A3=E6=9E=90=E5=BD=93=20{}=20?= =?UTF-8?q?=E5=A4=9A=E4=BA=8E3=E4=B8=AA=E6=97=B6=E7=9A=84=20bug=EF=BC=88.n?= =?UTF-8?q?et=20=E5=86=85=E9=83=A8=E6=9C=BA=E5=88=B6=E5=BE=88=E5=9D=91?= =?UTF-8?q?=EF=BC=89=EF=BC=9B=20>=203=E4=B8=AA=20{}=20=E6=97=B6=EF=BC=8CAr?= =?UTF-8?q?guments[1..3]=20=E8=A7=A3=E6=9E=90=E5=87=BA=E6=9D=A5=E6=98=AF?= =?UTF-8?q?=E5=88=86=E5=BC=80=E7=9A=84=20>=204=E4=B8=AA=20{}=20=E6=97=B6?= =?UTF-8?q?=EF=BC=8CArguments[1]=20=E5=8F=AA=E8=83=BD=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E8=BF=99=E4=B8=AA=E5=87=BA=E6=9D=A5=EF=BC=8C=E7=84=B6=E5=90=8E?= =?UTF-8?q?=20[1]=20=E9=87=8C=E9=9D=A2=E6=98=AF=20NewArray=20[]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ------------ .../MySqlConnectorExpression/StringTest.cs | 25 +++++++++++++++++++ .../Dameng/DamengExpression/StringTest.cs | 25 +++++++++++++++++++ .../KingbaseESExpression/StringTest.cs | 25 +++++++++++++++++++ .../MySql/MySqlExpression/StringTest.cs | 25 +++++++++++++++++++ .../Oracle/OracleExpression/StringTest.cs | 25 +++++++++++++++++++ .../PostgreSQLExpression/StringTest.cs | 25 +++++++++++++++++++ .../SqlServerExpression/StringTest.cs | 25 +++++++++++++++++++ .../Dameng/DamengExpression/StringTest.cs | 25 +++++++++++++++++++ .../MsAccess/MsAccessExpression/StringTest.cs | 25 +++++++++++++++++++ .../MySql/MySqlExpression/StringTest.cs | 25 +++++++++++++++++++ .../Oracle/OracleExpression/StringTest.cs | 25 +++++++++++++++++++ .../PostgreSQLExpression/StringTest.cs | 25 +++++++++++++++++++ .../ShenTong/ShenTongExpression/StringTest.cs | 25 +++++++++++++++++++ .../SqlServerExpression/StringTest.cs | 25 +++++++++++++++++++ .../Sqlite/SqliteExpression/StringTest.cs | 25 +++++++++++++++++++ .../DamengExpression.cs | 6 ++++- .../MsAccessExpression.cs | 6 ++++- .../FreeSql.Provider.MySql/MySqlExpression.cs | 6 ++++- .../Dameng/OdbcDamengExpression.cs | 6 ++++- .../KingbaseES/OdbcKingbaseESExpression.cs | 6 ++++- .../MySql/OdbcMySqlExpression.cs | 6 ++++- .../Oracle/OdbcOracleExpression.cs | 6 ++++- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 6 ++++- .../SqlServer/OdbcSqlServerExpression.cs | 6 ++++- .../OracleExpression.cs | 6 ++++- .../PostgreSQLExpression.cs | 6 ++++- .../ShenTongExpression.cs | 6 ++++- .../SqlServerExpression.cs | 6 ++++- .../SqliteExpression.cs | 6 ++++- 30 files changed, 445 insertions(+), 30 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.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 967a0d3c..99f276bb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -75,6 +75,31 @@ WHERE (a.`Id` = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT concat('x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'',ifnull(a.`Title`, ''),'') as1, concat('',ifnull((a.`Id` + 1), ''),'x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'',ifnull(a.`Title`, ''),'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs index 21bf1473..fd7682f3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""ID"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.dameng.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs index f686574a..37b61702 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""ID"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.kingbaseES.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce(((a.""ID"" + 1))::text, '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce(((a.""ID"" + 1))::text, '')||'x'||coalesce(((a.""ID"" + 1))::text, '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs index 6696908e..de5d5cc9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs @@ -75,6 +75,31 @@ WHERE (a.`Id` = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT concat('x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'',ifnull(a.`Title`, ''),'') as1, concat('',ifnull((a.`Id` + 1), ''),'x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'',ifnull(a.`Title`, ''),'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs index 10dac97a..d5078378 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""ID"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.oracle.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs index a189c1d2..f8fec850 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""id"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.pgsql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||''||coalesce(a.""title"", '')||'' as1, ''||coalesce(((a.""id"" + 1))::text, '')||'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||''||coalesce(a.""title"", '')||'' as2 +FROM ""tb_topic"" a +WHERE (a.""id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs index 97cd6e1d..8f23765d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs @@ -74,6 +74,31 @@ WHERE (a.[Id] = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.sqlserver.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N''+isnull(a.[Title], '')+N'' as1, N''+isnull(cast((a.[Id] + 1) as varchar), '')+N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N''+isnull(a.[Title], '')+N'' as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs index 93789c17..0ac24166 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""ID"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.dameng.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs index 5940417e..7db32843 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.[Id] = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.msaccess.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'+iif(isnull(cstr((a.[Id] + 1))), '', cstr((a.[Id] + 1)))+'z-'+iif(isnull(format(a.[CreateTime],'yyyyMM')), '', format(a.[CreateTime],'yyyyMM'))+''+iif(isnull(a.[Title]), '', a.[Title])+''+iif(isnull(a.[Title]), '', a.[Title])+'' as as1, ''+iif(isnull(cstr((a.[Id] + 1))), '', cstr((a.[Id] + 1)))+'x'+iif(isnull(cstr((a.[Id] + 1))), '', cstr((a.[Id] + 1)))+'z-'+iif(isnull(format(a.[CreateTime],'yyyyMM')), '', format(a.[CreateTime],'yyyyMM'))+''+iif(isnull(a.[Title]), '', a.[Title])+''+iif(isnull(a.[Title]), '', a.[Title])+'' as as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index ad563009..cb7f4e17 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -75,6 +75,31 @@ WHERE (a.`Id` = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT concat('x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'',ifnull(a.`Title`, ''),'') as1, concat('',ifnull((a.`Id` + 1), ''),'x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'',ifnull(a.`Title`, ''),'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index d5e7dbcc..6a63b551 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""ID"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.oracle.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index e8701a56..1a284e3b 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""id"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.pgsql.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||''||coalesce(a.""title"", '')||'' as1, ''||coalesce(((a.""id"" + 1))::text, '')||'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||''||coalesce(a.""title"", '')||'' as2 +FROM ""tb_topic"" a +WHERE (a.""id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs index 0e263375..55a89bfa 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""ID"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.shentong.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce((a.""ID"" + 1), '')||'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index 425c02e3..3e36a8cf 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -88,6 +88,31 @@ WHERE (a.[Id] = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.sqlserver.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N''+isnull(a.[Title], '')+N'' as1, N''+isnull(cast((a.[Id] + 1) as varchar), '')+N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N''+isnull(a.[Title], '')+N'' as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index be68623e..bb4dcf58 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -73,6 +73,31 @@ WHERE (a.""Id"" = {item.Id})", sql); Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); } + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.sqlite.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||ifnull((a.""Id"" + 1), '')||'z-'||ifnull(strftime('%Y%m',a.""CreateTime""), '')||''||ifnull(a.""Title"", '')||''||ifnull(a.""Title"", '')||'' as1, ''||ifnull((a.""Id"" + 1), '')||'x'||ifnull((a.""Id"" + 1), '')||'z-'||ifnull(strftime('%Y%m',a.""CreateTime""), '')||''||ifnull(a.""Title"", '')||''||ifnull(a.""Title"", '')||'' as2 +FROM ""tb_topic"" a +WHERE (a.""Id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + [Fact] public void Empty() { diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index 145a843b..aa59c52a 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -252,7 +252,11 @@ namespace FreeSql.Dameng return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs index 5ba654dd..7f075618 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -222,7 +222,11 @@ namespace FreeSql.MsAccess return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => { var asql = ((a as UnaryExpression)?.Operand.Type ?? a.Type) == typeof(string) ? $"{ExpressionLambdaToSql(a, tsc)}" : $"cstr({ExpressionLambdaToSql(a, tsc)})"; return $"'+{_common.IsNull(asql, "''")}+'"; diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 3365aacb..8db4fbde 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -251,7 +251,11 @@ namespace FreeSql.MySql case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; } } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index d5cbb4cb..4f1b6a13 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -252,7 +252,11 @@ namespace FreeSql.Odbc.Dameng return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index ad1c40da..622bb403 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -316,7 +316,11 @@ namespace FreeSql.Odbc.KingbaseES return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => { var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'"; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 128e750c..2225443a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -249,7 +249,11 @@ namespace FreeSql.Odbc.MySql case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 7ed64b54..6526cf70 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -252,7 +252,11 @@ namespace FreeSql.Odbc.Oracle return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index c8ee191c..625f06d8 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -338,7 +338,11 @@ namespace FreeSql.Odbc.PostgreSQL return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => { var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'"; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index c0aaa4e3..f9ff49cf 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -261,7 +261,11 @@ namespace FreeSql.Odbc.SqlServer var expArgs0 = ExpressionLambdaToSql(exp.Arguments[0], tsc); if (exp.Arguments.Count == 1) return expArgs0; var nchar = expArgs0.StartsWith("N'") ? "N" : ""; - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => { var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); if (atype == typeof(string)) return $"'+{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}+{nchar}'"; diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 2c9f768b..25233bca 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -252,7 +252,11 @@ namespace FreeSql.Oracle return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index a65ff443..cc445d6f 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -369,7 +369,11 @@ namespace FreeSql.PostgreSQL return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => { var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'"; diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index 078128c9..00bf94d8 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -299,7 +299,11 @@ namespace FreeSql.ShenTong return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 1e29c6db..c81e40aa 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -260,7 +260,11 @@ namespace FreeSql.SqlServer var expArgs0 = ExpressionLambdaToSql(exp.Arguments[0], tsc); if (exp.Arguments.Count == 1) return expArgs0; var nchar = expArgs0.StartsWith("N'") ? "N" : ""; - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => { var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); if (atype == typeof(string)) return $"'+{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}+{nchar}'"; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index ba7f0093..18b5e4ad 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -248,7 +248,11 @@ namespace FreeSql.Sqlite return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); case "Format": if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); - var expArgs = exp.Arguments.Where((a, z) => z > 0).Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); } } From a8d1db861488f8fe81966f936c35a8b4f3961aa9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 29 Jul 2020 13:19:47 +0800 Subject: [PATCH 0775/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20ColumnAttrib?= =?UTF-8?q?ute=20IsNullable=20=E5=AF=B9=20int/long=20=E7=AD=89=E5=80=BC?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E4=B9=9F=E5=8F=AF=E7=94=9F=E6=95=88=EF=BC=9B?= =?UTF-8?q?#384?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 2 ++ Examples/base_entity/Test01/User.cs | 9 ++++++--- .../FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs | 2 +- FreeSql/Internal/UtilsExpressionTree.cs | 4 ++++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 311f0383..502f11dd 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -97,6 +97,8 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + var sql = fsql.CodeFirst.GetComparisonDDLStatements(typeof(EMSServerModel.Model.User), "testxsx001"); + var test01 = EMSServerModel.Model.User.Select.IncludeMany(a => a.Roles).ToList(); var test02 = EMSServerModel.Model.UserRole.Select.ToList(); var test01tb = EMSServerModel.Model.User.Orm.CodeFirst.GetTableByEntity(typeof(EMSServerModel.Model.User)); diff --git a/Examples/base_entity/Test01/User.cs b/Examples/base_entity/Test01/User.cs index be4fbeb2..e790301c 100644 --- a/Examples/base_entity/Test01/User.cs +++ b/Examples/base_entity/Test01/User.cs @@ -94,10 +94,13 @@ namespace EMSServerModel.Model /// /// 职务编号 /// - [JsonProperty] - public long? TitleId { get; set; } + [JsonProperty, Column(IsNullable = true)] + public long TitleId { get; set; } + + [JsonProperty] + public long TitleId2 { get; set; } + - ///// ///// 创建时间 ///// diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs index 622c63d3..5a6a3941 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessCodeFirstTest.cs @@ -245,7 +245,7 @@ namespace FreeSql.Tests.MsAccess var itemstb = select.ToDataTable(); } - [Table(Name = "tb_alltype")] + [Table(Name = "tb_alltype_insert")] class TableAllType { [Column(IsIdentity = true, IsPrimary = true)] diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index e9f4d453..a499e1ff 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -101,6 +101,8 @@ namespace FreeSql.Internal continue; } if (tp == null && colattr != null) colattr.IsIgnore = true; //无法匹配的属性,认定是导航属性,且自动过滤 + var colattrIsNullable = colattr?._IsNullable; + var colattrIsNull = colattr == null; if (colattr == null) colattr = new ColumnAttribute { @@ -119,6 +121,8 @@ namespace FreeSql.Internal else colattr.DbType = colattr.DbType.ToUpper(); + if (colattrIsNull == false && colattrIsNullable == true) colattr.DbType = colattr.DbType.Replace("NOT NULL", ""); + if (colattrIsNull == false && colattrIsNullable == false) colattr.DbType = Regex.Replace(colattr.DbType, @"\bNULL\b", "").Trim() + " NOT NULL"; if (colattr._IsNullable == null && tp != null && tp.isnullable == null) colattr.IsNullable = tp.dbtypeFull.Contains("NOT NULL") == false; if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; From 06b301395fa4d8d6abfaaba473ded97bd25e3bb2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 29 Jul 2020 15:32:14 +0800 Subject: [PATCH 0776/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20fsql.InsertO?= =?UTF-8?q?rUpdate=20UpdateColumns=20=E6=95=B0=E6=8D=AE=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=97=B6=E5=8F=AA=E6=9B=B4=E6=96=B0=E6=8C=87=E5=AE=9A=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ++++ .../RepositoryTests.cs | 1 + FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 2 ++ FreeSql/FreeSql.xml | 14 ++++++++ FreeSql/Interface/Curd/IInsertOrUpdate.cs | 13 +++++++ .../CommonProvider/InsertOrUpdateProvider.cs | 34 +++++++++++++------ .../Curd/DamengInsertOrUpdate.cs | 2 +- .../Curd/MySqlInsertOrUpdate.cs | 7 +++- .../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 2 +- .../Curd/OdbcKingbaseESInsertOrUpdate.cs | 5 +-- .../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 7 +++- .../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 2 +- .../Curd/OdbcPostgreSQLInsertOrUpdate.cs | 5 +-- .../Curd/OdbcSqlServerInsertOrUpdate.cs | 2 +- .../Curd/OracleInsertOrUpdate.cs | 2 +- .../Curd/PostgreSQLInsertOrUpdate.cs | 5 +-- .../Curd/ShenTongInsertOrUpdate.cs | 2 +- .../Curd/SqlServerInsertOrUpdate.cs | 2 +- .../Curd/SqliteInsertOrUpdate.cs | 1 + 19 files changed, 89 insertions(+), 26 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 3804be96..d7630a0a 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -296,6 +296,7 @@ namespace FreeSql.Tests public void EnableAddOrUpdateNavigateList_OneToMany() { var repo = g.sqlite.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; var cts = new[] { new Cagetory { diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 5125fee2..c8761dff 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -159,6 +159,8 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var sqlxx = g.pgsql.InsertOrUpdate().SetSource(new userinfo { userid = 10 }).UpdateColumns(a => new { a.birthday, a.CardNo }).ToSql(); + var aff1 = g.sqlite.GetRepository().Delete(10086); var aff2 = g.sqlite.Delete(10086).ExecuteAffrows(); Assert.Equal(aff1, aff2); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 2fcf5adc..78dd9783 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1165,6 +1165,20 @@ + + + 当记录存在时,指定只更新的字段,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 当记录存在时,指定只更新的字段 + + 属性名,或者字段名 + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; diff --git a/FreeSql/Interface/Curd/IInsertOrUpdate.cs b/FreeSql/Interface/Curd/IInsertOrUpdate.cs index 639a3ac2..53698f3f 100644 --- a/FreeSql/Interface/Curd/IInsertOrUpdate.cs +++ b/FreeSql/Interface/Curd/IInsertOrUpdate.cs @@ -42,6 +42,19 @@ namespace FreeSql /// IInsertOrUpdate IfExistsDoNothing(); + /// + /// 当记录存在时,指定只更新的字段,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + /// + /// lambda选择列 + /// + IInsertOrUpdate UpdateColumns(Expression> columns); + /// + /// 当记录存在时,指定只更新的字段 + /// + /// 属性名,或者字段名 + /// + IInsertOrUpdate UpdateColumns(string[] columns); + /// /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; /// diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 310ecdb7..c67fd47c 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -15,17 +15,18 @@ namespace FreeSql.Internal.CommonProvider public abstract partial class InsertOrUpdateProvider : IInsertOrUpdate where T1 : class { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected List _source = new List(); - protected bool _doNothing = false; - protected Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - protected TableInfo _table; - protected Func _tableRule; - protected DbParameter[] _params; - protected DbTransaction _transaction; - protected DbConnection _connection; + public IFreeSql _orm; + public CommonUtils _commonUtils; + public CommonExpression _commonExpression; + public List _source = new List(); + public bool _doNothing = false; + public Dictionary _updateIgnore = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + public TableInfo _table; + public Func _tableRule; + public DbParameter[] _params; + public DbTransaction _transaction; + public DbConnection _connection; public ColumnInfo IdentityColumn { get; } public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) @@ -57,6 +58,17 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IInsertOrUpdate UpdateColumns(Expression> columns) => UpdateColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null)); + public IInsertOrUpdate UpdateColumns(string[] columns) + { + var cols = columns.Distinct().ToDictionary(a => a); + _updateIgnore.Clear(); + foreach (var col in _table.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name) == false && cols.ContainsKey(col.CsName) == false) + _updateIgnore.Add(col.Attribute.Name, true); + return this; + } + public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data?.Any() != true) return; diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index d4da4540..92cf3456 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -37,7 +37,7 @@ namespace FreeSql.Dameng.Curd WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index d2fe72dd..9a275be2 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -44,7 +44,12 @@ namespace FreeSql.MySql.Curd { insert.InsertIdentity(); if (_doNothing == false) - sql = new OnDuplicateKeyUpdate(insert).ToSql(); + { + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + sql = new OnDuplicateKeyUpdate(insert) + .UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()) + .ToSql(); + } else { if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + MySql 要求实体类 {_table.CsName} 必须有主键"); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index ed5f4257..fccbb8ad 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.Dameng WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs index 4dce4686..d4258280 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs @@ -43,8 +43,9 @@ namespace FreeSql.Odbc.KingbaseES else { var ocdu = new OdbcKingbaseESOnConflictDoUpdate(insert.InsertIdentity()); - ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); + if (_doNothing == true || cols.Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index 65f8affa..38c5dfab 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -43,7 +43,12 @@ namespace FreeSql.Odbc.MySql { insert.InsertIdentity(); if (_doNothing == false) - sql = new OdbcMySqlOnDuplicateKeyUpdate(insert).ToSql(); + { + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + sql = new OdbcMySqlOnDuplicateKeyUpdate(insert) + .UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()) + .ToSql(); + } else { if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + MySql 要求实体类 {_table.CsName} 必须有主键"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index 7ea43d2f..d87a9204 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -37,7 +37,7 @@ namespace FreeSql.Odbc.Oracle WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs index 2f3a8a0f..c709a6d3 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -41,8 +41,9 @@ namespace FreeSql.Odbc.PostgreSQL else { var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert.InsertIdentity()); - ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); + if (_doNothing == true || cols.Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index d4e711b2..bb702281 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -39,7 +39,7 @@ namespace FreeSql.Odbc.SqlServer WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index 36d50d18..4758bec8 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -37,7 +37,7 @@ namespace FreeSql.Oracle.Curd WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index c3a8461c..7af97ef1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -41,8 +41,9 @@ namespace FreeSql.PostgreSQL.Curd else { var ocdu = new OnConflictDoUpdate(insert.InsertIdentity()); - ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); + if (_doNothing == true || cols.Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs index b03afa5a..302343b7 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs @@ -37,7 +37,7 @@ namespace FreeSql.ShenTong.Curd WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index d9834bd8..e844e2c3 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -39,7 +39,7 @@ namespace FreeSql.SqlServer.Curd WriteSourceSelectUnionAll(data, sb, dbParams); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); - var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index 3d028dbe..2e0b442e 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -44,6 +44,7 @@ namespace FreeSql.Sqlite.Curd insert.InsertIdentity(); if (_doNothing == false) { + if (_updateIgnore.Any()) throw new Exception($"fsql.InsertOrUpdate Sqlite 无法完成 UpdateColumns 操作"); sql = insert.ToSql(); if (sql?.StartsWith("INSERT INTO ") == true) sql = $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}"; From 4279df276edcbf351724db59b34ab31cb72ef40f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 30 Jul 2020 15:44:47 +0800 Subject: [PATCH 0777/1029] update csproj --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ .../FreeSql.Provider.SqlServer.csproj | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 5b94bcfc..95061999 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net461;net40 + netstandard2.0;net46;net40 1.7.0 true ncc;YeXiangQin @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + microsoft From f63a69c55c5d31f9b60c67f5aff343c52a670e58 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 30 Jul 2020 15:47:58 +0800 Subject: [PATCH 0778/1029] update csproj --- .../FreeSql.Provider.SqlServer.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 95061999..d8d2b524 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net46;net40 + netstandard2.0;net46;net45;net40 1.7.0 true ncc;YeXiangQin From af153295f8b6a14b429369b272df21a7c2fcfe7e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 31 Jul 2020 02:28:37 +0800 Subject: [PATCH 0779/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20"x1".First/F?= =?UTF-8?q?irstOrDefault=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnectorExpression/StringTest.cs | 13 +++++++++++++ .../Dameng/DamengExpression/StringTest.cs | 13 +++++++++++++ .../Default/OdbcExpression/StringTest.cs | 13 +++++++++++++ .../KingbaseES/KingbaseESExpression/StringTest.cs | 13 +++++++++++++ .../MySql/MySqlExpression/StringTest.cs | 13 +++++++++++++ .../Oracle/OracleExpression/StringTest.cs | 13 +++++++++++++ .../PostgreSQL/PostgreSQLExpression/StringTest.cs | 13 +++++++++++++ .../SqlServer/SqlServerExpression/StringTest.cs | 13 +++++++++++++ .../Dameng/DamengExpression/StringTest.cs | 13 +++++++++++++ .../DataContext/SqlServer/SqlServerFixture.cs | 2 +- .../MsAccess/MsAccessExpression/StringTest.cs | 13 +++++++++++++ .../MySql/MySqlExpression/StringTest.cs | 13 +++++++++++++ .../Oracle/OracleExpression/StringTest.cs | 13 +++++++++++++ .../PostgreSQL/PostgreSQLExpression/StringTest.cs | 13 +++++++++++++ .../ShenTong/ShenTongExpression/StringTest.cs | 13 +++++++++++++ .../SqlServer/SqlServerExpression/StringTest.cs | 14 ++++++++++++++ .../Sqlite/SqliteExpression/StringTest.cs | 13 +++++++++++++ FreeSql/Internal/CommonExpression.cs | 4 ++++ .../FreeSql.Provider.Dameng/DamengExpression.cs | 10 ++++++++++ .../MsAccessExpression.cs | 10 ++++++++++ .../FreeSql.Provider.MySql/MySqlExpression.cs | 10 ++++++++++ .../Dameng/OdbcDamengExpression.cs | 10 ++++++++++ .../Default/OdbcExpression.cs | 10 ++++++++++ .../KingbaseES/OdbcKingbaseESExpression.cs | 10 ++++++++++ .../MySql/OdbcMySqlExpression.cs | 10 ++++++++++ .../Oracle/OdbcOracleExpression.cs | 10 ++++++++++ .../PostgreSQL/OdbcPostgreSQLExpression.cs | 10 ++++++++++ .../SqlServer/OdbcSqlServerExpression.cs | 10 ++++++++++ .../FreeSql.Provider.Oracle/OracleExpression.cs | 10 ++++++++++ .../PostgreSQLExpression.cs | 10 ++++++++++ .../ShenTongExpression.cs | 10 ++++++++++ .../SqlServerExpression.cs | 10 ++++++++++ .../FreeSql.Provider.Sqlite/SqliteExpression.cs | 10 ++++++++++ 33 files changed, 364 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 99f276bb..9ebf65b3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -52,6 +52,19 @@ namespace FreeSql.Tests.MySqlConnectorExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs index fd7682f3..4dfa9e9d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.Odbc.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/StringTest.cs index b88748f6..19b84f34 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.Odbc.DefaultExpression list.Add(g.odbc.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Empty() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs index 37b61702..faa481b1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.Odbc.KingbaseESExpression list.Add(g.kingbaseES.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs index de5d5cc9..61b5db83 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,19 @@ namespace FreeSql.Tests.Odbc.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs index d5078378..d5d4cdee 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.Odbc.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs index f8fec850..4105eea9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs index 8f23765d..82a5d84d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs @@ -51,6 +51,19 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs index 0ac24166..139555bc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs index 4cdefe0c..3177a215 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataContext/SqlServer/SqlServerFixture.cs @@ -42,7 +42,7 @@ namespace FreeSql.Tests.DataContext.SqlServer "TestTypeParentInfo23123", "xxdkdkdk1222", "xxx"}; foreach (var tempTable in tempTables) { - DeleteTmpTable(dataTables, tempTable); + //DeleteTmpTable(dataTables, tempTable); } } diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs index 7db32843..e4639294 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.MsAccessExpression list.Add(g.msaccess.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index cb7f4e17..bafb962a 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,19 @@ namespace FreeSql.Tests.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index 6a63b551..aff45a18 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index 1a284e3b..4b0b9fea 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs index 55a89bfa..fc4fd9da 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.ShenTongExpression list.Add(g.shentong.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index 3e36a8cf..c261353e 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using FreeSql.Tests.DataContext.SqlServer; +using Microsoft.EntityFrameworkCore.Internal; using System; using System.Collections.Generic; using System.Linq; @@ -65,6 +66,19 @@ namespace FreeSql.Tests.SqlServerExpression list.Add(select.Where(a => a.TitleVarchar == "aaa").ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index bb4dcf58..9bb2a1e7 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -50,6 +50,19 @@ namespace FreeSql.Tests.SqliteExpression list.Add(g.sqlite.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + [Fact] public void Format() { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index f27f2600..5f6fb7ea 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -41,6 +41,7 @@ namespace FreeSql.Internal field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); + if (parent.CsType == null) parent.CsType = exp.Type; return false; case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Constant: @@ -60,6 +61,7 @@ namespace FreeSql.Internal field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); + if (parent.CsType == null) parent.CsType = exp.Type; return false; case ExpressionType.Call: var callExp = exp as MethodCallExpression; @@ -77,6 +79,7 @@ namespace FreeSql.Internal field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); + if (parent.CsType == null) parent.CsType = exp.Type; return false; case ExpressionType.Parameter: case ExpressionType.MemberAccess: @@ -262,6 +265,7 @@ namespace FreeSql.Internal field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); + if (parent.CsType == null) parent.CsType = exp.Type; return false; } public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue) diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index aa59c52a..669d2bc5 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -100,6 +100,16 @@ namespace FreeSql.Dameng objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs index 7f075618..0de463bc 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -70,6 +70,16 @@ namespace FreeSql.MsAccess objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"left({getExp(callExp.Arguments[0])}, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 8db4fbde..7968d10e 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -98,6 +98,16 @@ namespace FreeSql.MySql objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index 4f1b6a13..439dbd20 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -100,6 +100,16 @@ namespace FreeSql.Odbc.Dameng objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs index df861404..673f5f52 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcExpression.cs @@ -104,6 +104,16 @@ namespace FreeSql.Odbc.Default objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return _utils.Adapter.LambdaString_Substring(getExp(callExp.Arguments[0]), "1", "1"); + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index 622bb403..12be160a 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -101,6 +101,16 @@ namespace FreeSql.Odbc.KingbaseES objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 2225443a..af5ed688 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -96,6 +96,16 @@ namespace FreeSql.Odbc.MySql objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 6526cf70..21ac435c 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -100,6 +100,16 @@ namespace FreeSql.Odbc.Oracle objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 625f06d8..cf939b59 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -101,6 +101,16 @@ namespace FreeSql.Odbc.PostgreSQL objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index f9ff49cf..ed2ef297 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -106,6 +106,16 @@ namespace FreeSql.Odbc.SqlServer objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 25233bca..3daf210d 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -100,6 +100,16 @@ namespace FreeSql.Oracle objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index cc445d6f..99b46cb3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -102,6 +102,16 @@ namespace FreeSql.PostgreSQL objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index 00bf94d8..b8c3d179 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -101,6 +101,16 @@ namespace FreeSql.ShenTong objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index c81e40aa..e0a87762 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -105,6 +105,16 @@ namespace FreeSql.SqlServer objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substring({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 18b5e4ad..14280137 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -96,6 +96,16 @@ namespace FreeSql.Sqlite objExp = callExp.Arguments.FirstOrDefault(); objType = objExp?.Type; argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } } if (objType == null) objType = callExp.Method.DeclaringType; if (objType != null || objType.IsArrayOrList()) From 73c87513d2ed69dd7698c3d6a10fdb1806679a07 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 31 Jul 2020 03:07:13 +0800 Subject: [PATCH 0780/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ColumnAttrib?= =?UTF-8?q?ute=20Precision/Scale=20=E8=AE=BE=E7=BD=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EfCoreFluentApi/EfCoreColumnFluent.cs | 6 + FreeSql.DbContext/FreeSql.DbContext.xml | 9 - FreeSql/DataAnnotations/ColumnAttribute.cs | 11 + FreeSql/DataAnnotations/ColumnFluent.cs | 13 + FreeSql/FreeSql.xml | 328 ++++++++++-------- FreeSql/Internal/CommonExpression.cs | 8 +- FreeSql/Internal/CommonUtils.cs | 6 +- FreeSql/Internal/UtilsExpressionTree.cs | 15 +- .../SqlServer/OdbcSqlServerExpression.cs | 2 +- 9 files changed, 235 insertions(+), 163 deletions(-) diff --git a/FreeSql.DbContext/EfCoreFluentApi/EfCoreColumnFluent.cs b/FreeSql.DbContext/EfCoreFluentApi/EfCoreColumnFluent.cs index 0b87862c..1f89fc59 100644 --- a/FreeSql.DbContext/EfCoreFluentApi/EfCoreColumnFluent.cs +++ b/FreeSql.DbContext/EfCoreFluentApi/EfCoreColumnFluent.cs @@ -54,5 +54,11 @@ namespace FreeSql.Extensions.EfCoreFluentApi //{ // return this; //} + public EfCoreColumnFluent HasPrecision(int precision, int scale = 0) + { + _cf.Precision(precision, scale); + return this; + } + } } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..474ea8d5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,14 +486,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index b6b11569..4dd251ed 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -104,5 +104,16 @@ namespace FreeSql.DataAnnotations /// 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 /// public string InsertValueSql { get; set; } + + internal int? _Precision; + /// + /// decimal/numeric 类型的长度 + /// + public int Precision { get => _Precision ?? 0; set => _Precision = value; } + internal int? _Scale; + /// + /// decimal/numeric 类型的小数位长度 + /// + public int Scale { get => _Scale ?? 0; set => _Scale = value; } } } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index 4a1adc93..4b5b1e09 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -176,5 +176,18 @@ namespace FreeSql.DataAnnotations _column.InsertValueSql = value; return this; } + + /// + /// decimal/numeric 类型的长度/小数位长度 + /// + /// 总长度 + /// 小数位长度 + /// + public ColumnFluent Precision(int precision, int scale = 0) + { + _column.Precision = precision; + _column.Scale = scale; + return this; + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 78dd9783..7feb5fa9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -105,6 +105,16 @@ 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + decimal/numeric 类型的长度 + + + + + decimal/numeric 类型的小数位长度 + + 数据库列名 @@ -213,6 +223,14 @@ + + + decimal/numeric 类型的长度/小数位长度 + + 总长度 + 小数位长度 + + 自定义表达式函数解析 @@ -2546,137 +2564,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3346,12 +3233,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3422,12 +3303,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4085,4 +3960,171 @@ + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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 5f6fb7ea..1050d677 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -41,7 +41,7 @@ namespace FreeSql.Internal field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); - if (parent.CsType == null) parent.CsType = exp.Type; + if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Constant: @@ -61,7 +61,7 @@ namespace FreeSql.Internal field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); - if (parent.CsType == null) parent.CsType = exp.Type; + if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; case ExpressionType.Call: var callExp = exp as MethodCallExpression; @@ -79,7 +79,7 @@ namespace FreeSql.Internal field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); - if (parent.CsType == null) parent.CsType = exp.Type; + if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; case ExpressionType.Parameter: case ExpressionType.MemberAccess: @@ -265,7 +265,7 @@ namespace FreeSql.Internal field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); - if (parent.CsType == null) parent.CsType = exp.Type; + if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; } public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue) diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index ef10b55a..922d1573 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -154,6 +154,8 @@ namespace FreeSql.Internal if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime; if (trycol._StringLength != null) attr.StringLength = trycol.StringLength; if (!string.IsNullOrEmpty(trycol.InsertValueSql)) attr.InsertValueSql = trycol.InsertValueSql; + if (trycol._Precision != null) attr.Precision = trycol.Precision; + if (trycol._Scale != null) attr.Scale = trycol.Scale; } var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); foreach (var tryattrobj in attrs) @@ -174,7 +176,9 @@ namespace FreeSql.Internal if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate; if (tryattr.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = tryattr.ServerTime; if (tryattr._StringLength != null) attr.StringLength = tryattr.StringLength; - if (!string.IsNullOrEmpty(tryattr.InsertValueSql)) attr.InsertValueSql = tryattr.InsertValueSql; + if (!string.IsNullOrEmpty(tryattr.InsertValueSql)) attr.InsertValueSql = tryattr.InsertValueSql; + if (tryattr._Precision != null) attr.Precision = tryattr.Precision; + if (tryattr._Scale != null) attr.Scale = tryattr.Scale; } ColumnAttribute ret = null; if (!string.IsNullOrEmpty(attr.Name)) ret = attr; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index a499e1ff..98d6edeb 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -279,19 +279,19 @@ namespace FreeSql.Internal if (colattr.MapType == typeof(byte[]) && colattr.StringLength != 0) { int strlen = colattr.StringLength; - var charPatten = @"(VARBINARY|BINARY|BYTEA)\s*(\([^\)]*\))?"; + var bytePatten = @"(VARBINARY|BINARY|BYTEA)\s*(\([^\)]*\))?"; switch (common._orm.Ado.DataType) { case DataType.MySql: case DataType.OdbcMySql: if (strlen == -2) colattr.DbType = "LONGBLOB"; else if (strlen < 0) colattr.DbType = "BLOB"; - else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + else colattr.DbType = Regex.Replace(colattr.DbType, bytePatten, $"$1({strlen})"); break; case DataType.SqlServer: case DataType.OdbcSqlServer: - if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1(MAX)"); - else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + if (strlen < 0) colattr.DbType = Regex.Replace(colattr.DbType, bytePatten, $"$1(MAX)"); + else colattr.DbType = Regex.Replace(colattr.DbType, bytePatten, $"$1({strlen})"); break; case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: @@ -314,10 +314,15 @@ namespace FreeSql.Internal break; case DataType.MsAccess: if (strlen < 0) colattr.DbType = "BLOB"; - else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + else colattr.DbType = Regex.Replace(colattr.DbType, bytePatten, $"$1({strlen})"); break; } } + if (colattr.MapType == typeof(decimal) && colattr.Precision > 0) + { + var decimalPatten = @"(DECIMAL|NUMERIC|NUMBER)\s*(\([^\)]*\))?"; + colattr.DbType = Regex.Replace(colattr.DbType, decimalPatten, $"$1({colattr.Precision},{colattr.Scale})"); + } if (trytb.Columns.ContainsKey(colattr.Name)) throw new Exception($"ColumnAttribute.Name {colattr.Name} 重复存在,请检查(注意:不区分大小写)"); if (trytb.ColumnsByCs.ContainsKey(p.Name)) throw new Exception($"属性名 {p.Name} 重复存在,请检查(注意:不区分大小写)"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index ed2ef297..76f2ae6d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -113,7 +113,7 @@ namespace FreeSql.Odbc.SqlServer { case "First": case "FirstOrDefault": - return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + return $"substring({getExp(callExp.Arguments[0])}, 1, 1)"; } } } From f15d34c918c3f6b0a09ef6587ddb6d44f46f7d33 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 31 Jul 2020 03:09:31 +0800 Subject: [PATCH 0781/1029] update code --- FreeSql/Internal/CommonUtils.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 922d1573..1fbac9fa 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -196,6 +196,8 @@ namespace FreeSql.Internal if (attr.ServerTime != DateTimeKind.Unspecified) ret = attr; if (attr._StringLength != null) ret = attr; if (!string.IsNullOrEmpty(attr.InsertValueSql)) ret = attr; + if (attr._Precision != null) ret = attr; + if (attr._Scale != null) ret = attr; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; } From 35ea431470d8fa5cd67e54aababd5444d6f15b78 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 31 Jul 2020 03:46:13 +0800 Subject: [PATCH 0782/1029] update tests --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 + .../Dameng/Curd/DamengSelectTest.cs | 9 + .../Dameng/Curd/DamengSelectTest.cs | 9 + FreeSql/FreeSql.xml | 310 ++++++++---------- 4 files changed, 170 insertions(+), 167 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 474ea8d5..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -486,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index a3cead83..f1705d77 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -1076,6 +1076,11 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" [Fact] public void Include_OneToMany() { + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; model1.id = (int)g.dameng.Insert(model1).ExecuteIdentity(); var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; @@ -1194,6 +1199,10 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" [Fact] public void Include_OneToMany2() { + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + string setting = "x"; var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.dameng.Insert(model2).ExecuteIdentity(); diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index a3a9400f..bb33c0bb 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -1077,6 +1077,11 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" [Fact] public void Include_OneToMany() { + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; model1.id = (int)g.dameng.Insert(model1).ExecuteIdentity(); var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; @@ -1195,6 +1200,10 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" [Fact] public void Include_OneToMany2() { + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + g.dameng.Delete().Where("1=1").ExecuteAffrows(); + string setting = "x"; var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; model2.id = (int)g.dameng.Insert(model2).ExecuteIdentity(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 7feb5fa9..1f38c4cd 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2564,6 +2564,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 }) + + + + + + 可自定义解析表达式 @@ -3233,6 +3364,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3303,6 +3440,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3960,171 +4103,4 @@ - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 条件 - - - From fee937a67770755d1df806318cdaef37554a506f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 31 Jul 2020 14:51:11 +0800 Subject: [PATCH 0783/1029] update code --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql/Internal/Model/DbToCs.cs | 1 - .../FreeSql.Provider.SqlServer.csproj | 9 ++++++--- 3 files changed, 6 insertions(+), 20 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/Internal/Model/DbToCs.cs b/FreeSql/Internal/Model/DbToCs.cs index 1d1de47d..181bcab7 100644 --- a/FreeSql/Internal/Model/DbToCs.cs +++ b/FreeSql/Internal/Model/DbToCs.cs @@ -51,7 +51,6 @@ namespace FreeSql.Internal.Model } } - public class DbInfoResult { public int type { get; } diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index d8d2b524..75872f9e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net46;net45;net40 + netstandard2.0;net451;net45;net40 1.7.0 true ncc;YeXiangQin @@ -25,7 +25,10 @@ - + + + + @@ -33,7 +36,7 @@ - + microsoft From f897aa0a716090a17cc5428b68098430b6a62907 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 1 Aug 2020 12:03:12 +0800 Subject: [PATCH 0784/1029] =?UTF-8?q?v1.7.1(=E5=85=BC=E5=AE=B9=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20Microsoft.Data.SqliClient)=20#394=20#384=20#330=20#?= =?UTF-8?q?115=20#17?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/DbSet/DbSet.cs | 3 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 86 +++++++++++ FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests.DbContext/UnitTest1.cs | 15 ++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 8 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 143 ------------------ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 25 files changed, 142 insertions(+), 167 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a4e4d38c..6dab843f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ced431c1..de883633 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 486ed182..914ba8c3 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index c913d8ca..45150f02 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 1f216a0f..032b934d 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.0 + 1.7.1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 9ae898d9..4b75f6be 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index a86991d8..69fedabd 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -47,6 +47,8 @@ namespace FreeSql { this._dicUpdateTimes.Clear(); this._states.Clear(); + this._statesEditing.Clear(); + this._dataEditing = null; } finally { @@ -123,7 +125,6 @@ namespace FreeSql public ISelect WhereIf(bool condition, Expression> exp) => this.OrmSelect(null).WhereIf(condition, exp); protected ConcurrentDictionary _states = new ConcurrentDictionary(); - internal ConcurrentDictionary _statesInternal => _states; TableInfo _tablePriv; protected TableInfo _table => _tablePriv ?? (_tablePriv = _db.OrmOriginal.CodeFirst.GetTableByEntity(_entityType)); ColumnInfo[] _tableIdentitysPriv, _tableServerTimesPriv; diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index d2a83da7..63762df5 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -530,5 +530,91 @@ namespace FreeSql } } #endregion + + #region BeginEdit + protected List _dataEditing; + protected ConcurrentDictionary _statesEditing = new ConcurrentDictionary(); + + /// + /// 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 + /// 场景:winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】 + /// 示例:https://github.com/dotnetcore/FreeSql/issues/397 + /// + /// + //public void BeginEdit(List data) + //{ + // if (data == null || data.Any() == false) return; + // if (_table.Primarys.Any() == false) throw new Exception($"不可进行编辑,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data.First())}"); + // _statesEditing.Clear(); + // _dataEditing = data; + // foreach (var item in data) + // { + // var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); + // if (string.IsNullOrEmpty(key)) continue; + + // _statesEditing.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => + // { + // _db.OrmOriginal.MapEntityValue(_entityType, item, ov.Value); + // ov.Time = DateTime.Now; + // return ov; + // }); + // } + //} + ///// + ///// 完成编辑数据,进行保存动作 + ///// 该方法根据 BeginEdit 传入的状态分析出添加、修改、删除 SQL 语句 + ///// + ///// + //public int EndEdit() + //{ + // var beforeAffrows = 0; + // if (_dataEditing == null) return 0; + // var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; + // _db.Options.EnableAddOrUpdateNavigateList = false; + // try + // { + // DbContextFlushCommand(); + // var addList = new List(); + // var ediList = new List(); + // foreach (var item in _dataEditing) + // { + // var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); + // if (_statesEditing.TryRemove(key, out var state) == false) + // { + // addList.Add(item); + // continue; + // } + // _states.AddOrUpdate(key, k => state, (k, ov) => + // { + // ov.Value = state.Value; + // ov.Time = DateTime.Now; + // return ov; + // }); + // if (_db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, item, state.Value, false).Any()) + // ediList.Add(item); + // } + // beforeAffrows = _db._affrows; + // AddRange(addList); + // UpdateRange(ediList); + + // DbContextFlushCommand(); + // var delList = _statesEditing.Values.OrderBy(a => a.Time).ToArray(); + // _db._affrows += DbContextBatchRemove(delList); //为了减的少不必要的开销,此处没有直接调用 RemoveRange + // foreach (var state in delList) + // { + // _db.OrmOriginal.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, state.Value); + // _states.TryRemove(state.Key, out var oldstate); + // } + // DbContextFlushCommand(); + // } + // finally + // { + // _dataEditing = null; + // _statesEditing.Clear(); + // _db.Options.EnableAddOrUpdateNavigateList = oldEnable; + // } + // return _db._affrows - beforeAffrows; + //} + #endregion } } diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 99bbdf7f..f13cbb4a 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 132d875e..4854f49c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -479,5 +486,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 766232a7..a061be6c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.0 + 1.7.1 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index c723b02b..616ee676 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -68,6 +68,21 @@ namespace FreeSql.Tests using (var ctx = g.sqlite.CreateDbContext()) { + //var setTag = ctx.Set(); + //var tags = setTag.Select.Limit(10).ToList(); + //setTag.BeginEdit(tags); + + //tags.Add(new Tag + //{ + // Ddd = DateTime.Now.Second, + // Name = "test_manytoMany_01_й2234234" + //}); + //tags[0].Name = "123123"; + //tags.RemoveAt(1); + + //tags.Clear(); + + //Assert.Equal(10, setTag.EndEdit()); var test150_02 = ctx.Set() .Select.From((s, b) => s.InnerJoin(a => a.Id == b.Id)) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index a1a56715..4cf89817 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -306,9 +306,9 @@ public static partial class FreeSqlGlobalExtensions { var tb = orm.CodeFirst.GetTableByEntity(typeof(T1)); if (tb == null || tb.Primarys.Any() == false) - (orm.CodeFirst as FreeSql.Internal.CommonProvider.CodeFirstProvider)._dicSycedTryAdd(typeof(T1)); //._dicSyced.TryAdd(typeof(TReturn), true); + (orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(T1)); //._dicSyced.TryAdd(typeof(TReturn), true); } - var select = orm.Select().IncludeMany(navigateSelector, then) as FreeSql.Internal.CommonProvider.Select1Provider; + var select = orm.Select().IncludeMany(navigateSelector, then) as Select1Provider; select.SetList(list); return list; } @@ -322,9 +322,9 @@ public static partial class FreeSqlGlobalExtensions { var tb = orm.CodeFirst.GetTableByEntity(typeof(T1)); if (tb == null || tb.Primarys.Any() == false) - (orm.CodeFirst as FreeSql.Internal.CommonProvider.CodeFirstProvider)._dicSycedTryAdd(typeof(T1)); //._dicSyced.TryAdd(typeof(TReturn), true); + (orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(T1)); //._dicSyced.TryAdd(typeof(TReturn), true); } - var select = orm.Select().IncludeMany(navigateSelector, then) as FreeSql.Internal.CommonProvider.Select1Provider; + var select = orm.Select().IncludeMany(navigateSelector, then) as Select1Provider; await select.SetListAsync(list); return list; } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 315751b6..8f557987 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1f38c4cd..2f7bca79 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2564,137 +2564,6 @@ - - - 查询,若使用读写分离,查询【从库】条件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 }) - - - - - - 可自定义解析表达式 @@ -3364,12 +3233,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3440,12 +3303,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index fccaad5c..026ccaf3 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 2f33a2fe..15c9934b 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c54c97f4..33815edd 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 97d21f2a..6fcf5dda 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3ce18b1f..ff428c26 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 1c16358b..be32e3ea 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 116b962a..89d242db 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index e5d12327..0ea2a297 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 75872f9e..9d9c1031 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e3ac160b..0b25ae25 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.0 + 1.7.1 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 688f7540367f3b0a11a2759b0e46c9952182153f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 1 Aug 2020 21:57:56 +0800 Subject: [PATCH 0785/1029] =?UTF-8?q?=E8=A1=A5=E5=85=85=20=20object=20parm?= =?UTF-8?q?s=20=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 211 +++++++++++++++++++-- FreeSql/Interface/Curd/IDelete.cs | 3 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 27 ++- FreeSql/Interface/Curd/IUpdate.cs | 6 +- FreeSql/Interface/IAdo.cs | 48 +++-- 5 files changed, 247 insertions(+), 48 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 2f7bca79..bde37cf0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -932,7 +932,8 @@ - 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 @@ -1441,7 +1442,8 @@ - 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 @@ -1449,7 +1451,8 @@ - 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 @@ -1457,7 +1460,8 @@ - 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 @@ -1473,7 +1477,8 @@ - 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 @@ -1481,7 +1486,8 @@ - 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> true 时生效 sql语法条件 @@ -1520,7 +1526,8 @@ - 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法 参数 @@ -1528,7 +1535,8 @@ - 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 @@ -1536,7 +1544,8 @@ - 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法 参数 @@ -1544,7 +1553,8 @@ - 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> true 时生效 sql语法 @@ -2291,7 +2301,8 @@ - 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法 参数 @@ -2317,7 +2328,8 @@ - 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 参数 @@ -2444,7 +2456,8 @@ - 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> @@ -2458,7 +2471,8 @@ - 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> @@ -2473,7 +2487,8 @@ - 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> @@ -2488,7 +2503,8 @@ - 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> @@ -2504,7 +2520,8 @@ - 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> @@ -2520,7 +2537,8 @@ - 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> @@ -2538,7 +2556,8 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> @@ -2557,7 +2576,147 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> @@ -3233,6 +3392,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3303,6 +3468,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index deab6936..0edfd394 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -30,7 +30,8 @@ namespace FreeSql /// IDelete Where(Expression> exp); /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 /// 参数 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index a7b61482..3e7fee26 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -218,21 +218,24 @@ namespace FreeSql TSelect RightJoin(Expression> exp); /// - /// 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 /// 参数 /// TSelect LeftJoin(string sql, object parms = null); /// - /// 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 /// 参数 /// TSelect InnerJoin(string sql, object parms = null); /// - /// 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 /// 参数 @@ -247,14 +250,16 @@ namespace FreeSql TSelect RawJoin(string sql); /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 /// 参数 /// TSelect Where(string sql, object parms = null); /// - /// 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + /// 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// true 时生效 /// sql语法条件 @@ -293,14 +298,16 @@ namespace FreeSql TSelect ForUpdate(bool nowait = false); /// - /// 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + /// 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法 /// 参数 /// TSelect GroupBy(string sql, object parms = null); /// - /// 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + /// 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 /// 参数 @@ -308,14 +315,16 @@ namespace FreeSql TSelect Having(string sql, object parms = null); /// - /// 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + /// 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法 /// 参数 /// TSelect OrderBy(string sql, object parms = null); /// - /// 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + /// 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// true 时生效 /// sql语法 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index c2fd0b2b..5d4fb144 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -142,7 +142,8 @@ namespace FreeSql /// IUpdate SetIf(bool condition, Expression> exp); /// - /// 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + /// 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法 /// 参数 @@ -167,7 +168,8 @@ namespace FreeSql /// IUpdate Where(Expression> exp); /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 /// 参数 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 02626f8e..788fbcb9 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -66,7 +66,8 @@ namespace FreeSql void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -82,7 +83,8 @@ namespace FreeSql object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -99,7 +101,8 @@ namespace FreeSql DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + /// 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -116,7 +119,8 @@ namespace FreeSql DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -134,7 +138,8 @@ namespace FreeSql int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + /// 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -152,7 +157,8 @@ namespace FreeSql object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + /// 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -174,7 +180,8 @@ namespace FreeSql List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -196,7 +203,8 @@ namespace FreeSql NaviteTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -239,7 +247,8 @@ namespace FreeSql Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -255,7 +264,8 @@ namespace FreeSql Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -272,7 +282,8 @@ namespace FreeSql Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + /// 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -289,7 +300,8 @@ namespace FreeSql Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -307,7 +319,8 @@ namespace FreeSql Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -325,7 +338,8 @@ namespace FreeSql Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -347,7 +361,8 @@ namespace FreeSql Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) + /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// @@ -369,7 +384,8 @@ namespace FreeSql Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// From 552926dd9639deb91513879e42b37950e37349c9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 2 Aug 2020 13:38:23 +0800 Subject: [PATCH 0786/1029] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=91=BD=E5=90=8D?= =?UTF-8?q?=20NaviteTuple=20=E4=B8=BA=20NativeTuple?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 6 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 152 +++++++++--------- FreeSql.DbContext/FreeSql.DbContext.xml | 50 ++++-- .../Repository/Repository/BaseRepository.cs | 9 +- .../Repository/Repository/IBaseRepository.cs | 16 ++ .../RepositoryTests.cs | 30 ++++ .../FreeSql.Tests.DbContext/UnitTest1.cs | 22 +-- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect4.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect5.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect6.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect7.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect8.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect9.cs | 2 +- FreeSql/Interface/IAdo.cs | 96 +++++------ .../CommonProvider/AdoProvider/AdoProvider.cs | 64 ++++---- .../AdoProvider/AdoProviderAsync.cs | 64 ++++---- .../CommonProvider/InsertOrUpdateProvider.cs | 10 +- .../Internal/CommonProvider/InsertProvider.cs | 4 +- .../SelectProvider/Select10Provider.cs | 6 +- .../SelectProvider/Select1Provider.cs | 4 +- .../SelectProvider/Select2Provider.cs | 6 +- .../SelectProvider/Select3Provider.cs | 6 +- .../SelectProvider/Select4Provider.cs | 6 +- .../SelectProvider/Select5Provider.cs | 6 +- .../SelectProvider/Select6Provider.cs | 6 +- .../SelectProvider/Select7Provider.cs | 6 +- .../SelectProvider/Select8Provider.cs | 6 +- .../SelectProvider/Select9Provider.cs | 6 +- .../Model/{NaviteTuple.cs => NativeTuple.cs} | 56 +++---- FreeSql/Internal/UtilsExpressionTree.cs | 6 +- .../DamengCodeFirst.cs | 12 +- .../Dameng/OdbcDamengCodeFirst.cs | 12 +- .../KingbaseES/OdbcKingbaseESCodeFirst.cs | 10 +- .../Oracle/OdbcOracleCodeFirst.cs | 12 +- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 10 +- .../OracleCodeFirst.cs | 12 +- .../ShenTongCodeFirst.cs | 10 +- .../SqlServerExtensions.cs | 4 +- 41 files changed, 407 insertions(+), 336 deletions(-) rename FreeSql/Internal/Model/{NaviteTuple.cs => NativeTuple.cs} (68%) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 0666a4c3..be8eb704 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -78,19 +78,19 @@ namespace FreeSql protected virtual void OnModelCreating(ICodeFirst codefirst) { } #region Set - static ConcurrentDictionary> _dicGetDbSetProps = new ConcurrentDictionary>(); + static ConcurrentDictionary> _dicGetDbSetProps = new ConcurrentDictionary>(); internal void InitPropSets() { var thisType = this.GetType(); var dicval = _dicGetDbSetProps.GetOrAdd(thisType, tp => - NaviteTuple.Create( + NativeTuple.Create( tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) .Where(a => a.PropertyType.IsGenericType && a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GetGenericArguments()[0])).ToArray(), false)); if (dicval.Item2 == false) { - if (_dicGetDbSetProps.TryUpdate(thisType, NaviteTuple.Create(dicval.Item1, true), dicval)) + if (_dicGetDbSetProps.TryUpdate(thisType, NativeTuple.Create(dicval.Item1, true), dicval)) OnModelCreating(OrmOriginal.CodeFirst); } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 63762df5..b6a38362 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -1,12 +1,13 @@ using FreeSql.Extensions.EntityUtil; +using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Reflection; using System.Text; -using System.Linq.Expressions; namespace FreeSql { @@ -539,82 +540,85 @@ namespace FreeSql /// 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 /// 场景:winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】 /// 示例:https://github.com/dotnetcore/FreeSql/issues/397 + /// 注意:* 本方法只支持单表操作,不支持导航属性级联保存 /// /// - //public void BeginEdit(List data) - //{ - // if (data == null || data.Any() == false) return; - // if (_table.Primarys.Any() == false) throw new Exception($"不可进行编辑,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data.First())}"); - // _statesEditing.Clear(); - // _dataEditing = data; - // foreach (var item in data) - // { - // var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); - // if (string.IsNullOrEmpty(key)) continue; + public void BeginEdit(List data) + { + if (data == null || data.Any() == false) return; + if (_table.Primarys.Any() == false) throw new Exception($"不可进行编辑,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data.First())}"); + _statesEditing.Clear(); + _dataEditing = data; + foreach (var item in data) + { + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); + if (string.IsNullOrEmpty(key)) continue; - // _statesEditing.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => - // { - // _db.OrmOriginal.MapEntityValue(_entityType, item, ov.Value); - // ov.Time = DateTime.Now; - // return ov; - // }); - // } - //} - ///// - ///// 完成编辑数据,进行保存动作 - ///// 该方法根据 BeginEdit 传入的状态分析出添加、修改、删除 SQL 语句 - ///// - ///// - //public int EndEdit() - //{ - // var beforeAffrows = 0; - // if (_dataEditing == null) return 0; - // var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; - // _db.Options.EnableAddOrUpdateNavigateList = false; - // try - // { - // DbContextFlushCommand(); - // var addList = new List(); - // var ediList = new List(); - // foreach (var item in _dataEditing) - // { - // var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); - // if (_statesEditing.TryRemove(key, out var state) == false) - // { - // addList.Add(item); - // continue; - // } - // _states.AddOrUpdate(key, k => state, (k, ov) => - // { - // ov.Value = state.Value; - // ov.Time = DateTime.Now; - // return ov; - // }); - // if (_db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, item, state.Value, false).Any()) - // ediList.Add(item); - // } - // beforeAffrows = _db._affrows; - // AddRange(addList); - // UpdateRange(ediList); + _statesEditing.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => + { + _db.OrmOriginal.MapEntityValue(_entityType, item, ov.Value); + ov.Time = DateTime.Now; + return ov; + }); + } + } + /// + /// 完成编辑数据,进行保存动作 + /// 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句 + /// 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + /// + /// + public int EndEdit() + { + var beforeAffrows = 0; + if (_dataEditing == null) return 0; + var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; + _db.Options.EnableAddOrUpdateNavigateList = false; + try + { + DbContextFlushCommand(); + var addList = new List(); + var ediList = new List>(); + foreach (var item in _dataEditing) + { + var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); + if (_statesEditing.TryRemove(key, out var state) == false) + { + addList.Add(item); + continue; + } + _states.AddOrUpdate(key, k => state, (k, ov) => + { + ov.Value = state.Value; + ov.Time = DateTime.Now; + return ov; + }); + var edicmp = _db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, item, state.Value, false); + if (edicmp.Any()) + ediList.Add(NativeTuple.Create(item, string.Join(",", edicmp))); + } + beforeAffrows = _db._affrows; + AddRange(addList); + UpdateRange(ediList.OrderBy(a => a.Item2).Select(a => a.Item1).ToList()); - // DbContextFlushCommand(); - // var delList = _statesEditing.Values.OrderBy(a => a.Time).ToArray(); - // _db._affrows += DbContextBatchRemove(delList); //为了减的少不必要的开销,此处没有直接调用 RemoveRange - // foreach (var state in delList) - // { - // _db.OrmOriginal.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, state.Value); - // _states.TryRemove(state.Key, out var oldstate); - // } - // DbContextFlushCommand(); - // } - // finally - // { - // _dataEditing = null; - // _statesEditing.Clear(); - // _db.Options.EnableAddOrUpdateNavigateList = oldEnable; - // } - // return _db._affrows - beforeAffrows; - //} + DbContextFlushCommand(); + var delList = _statesEditing.Values.OrderBy(a => a.Time).ToArray(); + _db._affrows += DbContextBatchRemove(delList); //为了减的少不必要的开销,此处没有直接调用 RemoveRange + foreach (var state in delList) + { + _db.OrmOriginal.ClearEntityPrimaryValueWithIdentityAndGuid(_entityType, state.Value); + _states.TryRemove(state.Key, out var oldstate); + } + DbContextFlushCommand(); + } + finally + { + _dataEditing = null; + _statesEditing.Clear(); + _db.Options.EnableAddOrUpdateNavigateList = oldEnable; + } + return _db._affrows - beforeAffrows; + } #endregion } } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..65c54b71 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -174,6 +167,23 @@ + + + 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 + 场景:winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】 + 示例:https://github.com/dotnetcore/FreeSql/issues/397 + 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + + + + + + 完成编辑数据,进行保存动作 + 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句 + 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + + + 使用 FreeSql FluentApi 方法,当 EFCore FluentApi 方法无法表示的时候使用 @@ -304,6 +314,23 @@ 实体对象 属性名 + + + 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 + 场景:winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】 + 示例:https://github.com/dotnetcore/FreeSql/issues/397 + 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + + + + + + 完成编辑数据,进行保存动作 + 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句 + 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + + + 工作单元 @@ -486,14 +513,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 2f78dd05..675cf0b4 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -119,11 +119,11 @@ namespace FreeSql return _db.SaveChanges(); } - public void Attach(TEntity data) => _db.Attach(data); - public void Attach(IEnumerable data) => _db.AttachRange(data); + public void Attach(TEntity data) => _dbset.Attach(data); + public void Attach(IEnumerable data) => _dbset.AttachRange(data); public IBaseRepository AttachOnlyPrimary(TEntity data) { - _db.AttachOnlyPrimary(data); + _dbset.AttachOnlyPrimary(data); return this; } public void FlushState() => _dbset.FlushState(); @@ -140,6 +140,9 @@ namespace FreeSql _dbset.SaveMany(entity, propertyName); _db.SaveChanges(); } + + public void BeginEdit(List data) => _dbset.BeginEdit(data); + public int EndEdit() => _dbset.EndEdit(); } public abstract partial class BaseRepository : BaseRepository, IBaseRepository diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index e172073f..c66937ee 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -79,6 +79,22 @@ namespace FreeSql int Delete(IEnumerable entitys); int Delete(Expression> predicate); + /// + /// 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 + /// 场景:winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】 + /// 示例:https://github.com/dotnetcore/FreeSql/issues/397 + /// 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + /// + /// + void BeginEdit(List data); + /// + /// 完成编辑数据,进行保存动作 + /// 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句 + /// 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + /// + /// + int EndEdit(); + #if net40 #else Task InsertAsync(TEntity entity); diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index d7630a0a..a65081bb 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -528,5 +528,35 @@ namespace FreeSql.Tests public Guid TagId { get; set; } public Tag Tag { get; set; } } + + [Fact] + public void BeginEdit() + { + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.sqlite.GetRepository(); + var cts = new[] { + new BeginEdit01 { Name = "1" }, + new BeginEdit01 { Name = "1_1" }, + new BeginEdit01 { Name = "1_2" }, + new BeginEdit01 { Name = "1_3" }, + new BeginEdit01 { Name = "2" }, + new BeginEdit01 { Name = "2_1" }, + new BeginEdit01 { Name = "2_2" } + }.ToList(); + repo.Insert(cts); + + repo.BeginEdit(cts); + + cts.Add(new BeginEdit01 { Name = "2_3" }); + cts[0].Name = "123123"; + cts.RemoveAt(1); + + Assert.Equal(3, repo.EndEdit()); + } + class BeginEdit01 + { + public Guid Id { get; set; } + public string Name { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs index 616ee676..8cf62928 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/UnitTest1.cs @@ -68,21 +68,21 @@ namespace FreeSql.Tests using (var ctx = g.sqlite.CreateDbContext()) { - //var setTag = ctx.Set(); - //var tags = setTag.Select.Limit(10).ToList(); - //setTag.BeginEdit(tags); + var setTag = ctx.Set(); + var tags = setTag.Select.Limit(10).ToList(); + setTag.BeginEdit(tags); - //tags.Add(new Tag - //{ - // Ddd = DateTime.Now.Second, - // Name = "test_manytoMany_01_й2234234" - //}); - //tags[0].Name = "123123"; - //tags.RemoveAt(1); + tags.Add(new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_й2234234" + }); + tags[0].Name = "123123"; + tags.RemoveAt(1); //tags.Clear(); - //Assert.Equal(10, setTag.EndEdit()); + Assert.Equal(3, setTag.EndEdit()); var test150_02 = ctx.Set() .Select.From((s, b) => s.InnerJoin(a => a.Id == b.Id)) diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 52121b8a..f041b8b1 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 9461c992..3bbd6b0c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index e3195e00..1dc6e71e 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 845ad08f..29bc56f6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index 02002672..a82866c7 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 756e1c38..16be4dfc 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index 5b115d56..be8873c9 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 502eef4c..a61b4955 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 043bc3c8..ff8ff51d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -51,7 +51,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelectGrouping> GroupBy(Expression> exp); + ISelectGrouping> GroupBy(Expression> exp); ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 788fbcb9..ba922dc0 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -199,9 +199,9 @@ namespace FreeSql /// /// /// - NaviteTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -210,28 +210,28 @@ namespace FreeSql /// /// /// - NaviteTuple, List> Query(string cmdText, object parms = null); - NaviteTuple, List> Query(DbTransaction transaction, string cmdText, object parms = null); - NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + NativeTuple, List> Query(string cmdText, object parms = null); + NativeTuple, List> Query(DbTransaction transaction, string cmdText, object parms = null); + NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - NaviteTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List> Query(string cmdText, object parms = null); - NaviteTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); - NaviteTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - NaviteTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List, List> Query(string cmdText, object parms = null); - NaviteTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); - NaviteTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - NaviteTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NaviteTuple, List, List, List, List> Query(string cmdText, object parms = null); - NaviteTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); - NaviteTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + NativeTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List> Query(string cmdText, object parms = null); + NativeTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); + NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + NativeTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List, List> Query(string cmdText, object parms = null); + NativeTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); + NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + NativeTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List, List, List> Query(string cmdText, object parms = null); + NativeTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); + NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); #if net40 #else @@ -380,9 +380,9 @@ namespace FreeSql /// /// /// - Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -391,28 +391,28 @@ namespace FreeSql /// /// /// - Task, List>> QueryAsync(string cmdText, object parms = null); - Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List>> QueryAsync(string cmdText, object parms = null); + Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List>> QueryAsync(string cmdText, object parms = null); - Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List>> QueryAsync(string cmdText, object parms = null); - Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null); - Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List>> QueryAsync(string cmdText, object parms = null); + Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List>> QueryAsync(string cmdText, object parms = null); + Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null); + Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); + Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); #endregion #endif } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 613f0e85..840faa80 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -130,14 +130,14 @@ namespace FreeSql.Internal.CommonProvider return ret; } #region query multi - public NaviteTuple, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public NaviteTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public NaviteTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NativeTuple, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public NativeTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -189,17 +189,17 @@ namespace FreeSql.Internal.CommonProvider break; } }, cmdType, cmdText, cmdParms); - return NaviteTuple.Create(ret1, ret2); + return NativeTuple.Create(ret1, ret2); } - public NaviteTuple, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public NaviteTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public NaviteTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NativeTuple, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public NativeTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -274,17 +274,17 @@ namespace FreeSql.Internal.CommonProvider break; } }, cmdType, cmdText, cmdParms); - return NaviteTuple.Create(ret1, ret2, ret3); + return NativeTuple.Create(ret1, ret2, ret3); } - public NaviteTuple, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public NaviteTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public NaviteTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NativeTuple, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public NativeTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -382,17 +382,17 @@ namespace FreeSql.Internal.CommonProvider break; } }, cmdType, cmdText, cmdParms); - return NaviteTuple.Create(ret1, ret2, ret3, ret4); + return NativeTuple.Create(ret1, ret2, ret3, ret4); } - public NaviteTuple, List, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NaviteTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public NaviteTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public NaviteTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NativeTuple, List, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); + public NativeTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); + public NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -513,7 +513,7 @@ namespace FreeSql.Internal.CommonProvider break; } }, cmdType, cmdText, cmdParms); - return NaviteTuple.Create(ret1, ret2, ret3, ret4, ret5); + return NativeTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 612ff0b2..264ac27e 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -51,14 +51,14 @@ namespace FreeSql.Internal.CommonProvider return ret; } #region QueryAsync multi - public Task, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -111,17 +111,17 @@ namespace FreeSql.Internal.CommonProvider } return Task.FromResult(false); }, cmdType, cmdText, cmdParms); - return NaviteTuple.Create(ret1, ret2); + return NativeTuple.Create(ret1, ret2); } - public Task, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -197,17 +197,17 @@ namespace FreeSql.Internal.CommonProvider } return Task.FromResult(false); }, cmdType, cmdText, cmdParms); - return NaviteTuple.Create(ret1, ret2, ret3); + return NativeTuple.Create(ret1, ret2, ret3); } - public Task, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -306,17 +306,17 @@ namespace FreeSql.Internal.CommonProvider } return Task.FromResult(false); }, cmdType, cmdText, cmdParms); - return NaviteTuple.Create(ret1, ret2, ret3, ret4); + return NativeTuple.Create(ret1, ret2, ret3, ret4); } - public Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); + public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); + async public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { - if (string.IsNullOrEmpty(cmdText)) return NaviteTuple.Create(new List(), new List(), new List(), new List(), new List()); + if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List(), new List()); var ret1 = new List(); var type1 = typeof(T1); string flag1 = null; @@ -438,7 +438,7 @@ namespace FreeSql.Internal.CommonProvider } return Task.FromResult(false); }, cmdType, cmdText, cmdParms); - return NaviteTuple.Create(ret1, ret2, ret3, ret4, ret5); + return NativeTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index c67fd47c..99d2c609 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -191,12 +191,12 @@ namespace FreeSql.Internal.CommonProvider /// /// /// - public NaviteTuple, List> SplitSourceByIdentityValueIsNull(List source) + public NativeTuple, List> SplitSourceByIdentityValueIsNull(List source) { - if (_SplitSourceByIdentityValueIsNullFlag == 1) return NaviteTuple.Create(source, new List()); - if (_SplitSourceByIdentityValueIsNullFlag == 2) return NaviteTuple.Create(new List(), source); - if (IdentityColumn == null) return NaviteTuple.Create(source, new List()); - var ret = NaviteTuple.Create(new List(), new List()); + if (_SplitSourceByIdentityValueIsNullFlag == 1) return NativeTuple.Create(source, new List()); + if (_SplitSourceByIdentityValueIsNullFlag == 2) return NativeTuple.Create(new List(), source); + if (IdentityColumn == null) return NativeTuple.Create(source, new List()); + var ret = NativeTuple.Create(new List(), new List()); foreach (var item in source) { if (object.Equals(_orm.GetEntityValueWithPropertyName(_table.Type, item, IdentityColumn.CsName), IdentityColumn.CsType.CreateInstanceGetDefaultValue())) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index d60bfa2a..e8bb406e 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -571,13 +571,13 @@ namespace FreeSql.Internal.CommonProvider { var dt = new DataTable(); dt.TableName = TableRuleInvoke(); - var dtCols = new List>(); + var dtCols = new List>(); foreach (var col in _table.ColumnsByPosition) { if (col.Attribute.IsIdentity && _insertIdentity == false) continue; if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; dt.Columns.Add(col.Attribute.Name, col.Attribute.MapType.NullableTypeOrThis()); - dtCols.Add(NaviteTuple.Create(col, col.Attribute.MapType.NullableTypeOrThis(), col.Attribute.MapType.IsNullableType())); + dtCols.Add(NativeTuple.Create(col, col.Attribute.MapType.NullableTypeOrThis(), col.Attribute.MapType.IsNullableType())); } if (dt.Columns.Count == 0) return dt; var didx = 0; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index d754293d..a62868c4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -43,11 +43,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 952770d6..1a9c1fcf 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -292,7 +292,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - static NaviteTuple> GetExpressionStack(Expression exp) + static NativeTuple> GetExpressionStack(Expression exp) { Expression tmpExp = exp; ParameterExpression param = null; @@ -316,7 +316,7 @@ namespace FreeSql.Internal.CommonProvider } } if (param == null) throw new Exception($"表达式错误,它的顶级对象不是 ParameterExpression:{exp}"); - return NaviteTuple.Create(param, members.ToList()); + return NativeTuple.Create(param, members.ToList()); } static MethodInfo GetEntityValueWithPropertyNameMethod = typeof(EntityUtilExtensions).GetMethod("GetEntityValueWithPropertyName"); static ConcurrentDictionary> _dicTypeMethod = new ConcurrentDictionary>(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 2ca2fc1d..0bf4d0fc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -27,11 +27,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 27e36b4c..ebded494 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -29,11 +29,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index f7cfa25e..2824aa01 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -31,11 +31,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index aeaf7daf..1278e64f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -33,11 +33,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index a4522c5e..f4b9caa5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -35,11 +35,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 3b0b4979..b094c500 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -37,11 +37,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 821d9032..fbc2ed51 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -39,11 +39,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index fc9e0479..021298f4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -41,11 +41,11 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - ISelectGrouping> ISelect.GroupBy(Expression> exp) + ISelectGrouping> ISelect.GroupBy(Expression> exp) { - if (exp == null) return this.InternalGroupBy>(exp?.Body); + if (exp == null) return this.InternalGroupBy>(exp?.Body); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); + return this.InternalGroupBy>(exp?.Body); } TMember ISelect.Max(Expression> column) diff --git a/FreeSql/Internal/Model/NaviteTuple.cs b/FreeSql/Internal/Model/NativeTuple.cs similarity index 68% rename from FreeSql/Internal/Model/NaviteTuple.cs rename to FreeSql/Internal/Model/NativeTuple.cs index 8e9dfd46..fcc3036f 100644 --- a/FreeSql/Internal/Model/NaviteTuple.cs +++ b/FreeSql/Internal/Model/NativeTuple.cs @@ -4,48 +4,48 @@ using System.Text; namespace FreeSql.Internal.Model { - public static class NaviteTuple + public static class NativeTuple { - public static NaviteTuple Create(T1 item1, T2 item2) => new NaviteTuple(item1, item2); - public static NaviteTuple Create(T1 item1, T2 item2, T3 item3) => new NaviteTuple(item1, item2, item3); - public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) => new NaviteTuple(item1, item2, item3, item4); - public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) => new NaviteTuple(item1, item2, item3, item4, item5); - public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) => new NaviteTuple(item1, item2, item3, item4, item5, item6); - public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) => new NaviteTuple(item1, item2, item3, item4, item5, item6, item7); - public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) => new NaviteTuple(item1, item2, item3, item4, item5, item6, item7, item8); - public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9) => new NaviteTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9); - public static NaviteTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10) => new NaviteTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10); + public static NativeTuple Create(T1 item1, T2 item2) => new NativeTuple(item1, item2); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3) => new NativeTuple(item1, item2, item3); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) => new NativeTuple(item1, item2, item3, item4); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) => new NativeTuple(item1, item2, item3, item4, item5); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) => new NativeTuple(item1, item2, item3, item4, item5, item6); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10); } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } - public NaviteTuple(T1 item1, T2 item2) + public NativeTuple(T1 item1, T2 item2) { Item1 = item1; Item2 = item2; } } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } public T3 Item3 { get; } - public NaviteTuple(T1 item1, T2 item2, T3 item3) + public NativeTuple(T1 item1, T2 item2, T3 item3) { Item1 = item1; Item2 = item2; Item3 = item3; } } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } public T3 Item3 { get; } public T4 Item4 { get; } - public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4) + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4) { Item1 = item1; Item2 = item2; @@ -53,14 +53,14 @@ namespace FreeSql.Internal.Model Item4 = item4; } } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } public T3 Item3 { get; } public T4 Item4 { get; } public T5 Item5 { get; } - public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { Item1 = item1; Item2 = item2; @@ -69,7 +69,7 @@ namespace FreeSql.Internal.Model Item5 = item5; } } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } @@ -77,7 +77,7 @@ namespace FreeSql.Internal.Model public T4 Item4 { get; } public T5 Item5 { get; } public T6 Item6 { get; } - public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { Item1 = item1; Item2 = item2; @@ -87,7 +87,7 @@ namespace FreeSql.Internal.Model Item6 = item6; } } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } @@ -96,7 +96,7 @@ namespace FreeSql.Internal.Model public T5 Item5 { get; } public T6 Item6 { get; } public T7 Item7 { get; } - public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { Item1 = item1; Item2 = item2; @@ -107,7 +107,7 @@ namespace FreeSql.Internal.Model Item7 = item7; } } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } @@ -117,7 +117,7 @@ namespace FreeSql.Internal.Model public T6 Item6 { get; } public T7 Item7 { get; } public T8 Item8 { get; } - public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { Item1 = item1; Item2 = item2; @@ -129,7 +129,7 @@ namespace FreeSql.Internal.Model Item8 = item8; } } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } @@ -140,7 +140,7 @@ namespace FreeSql.Internal.Model public T7 Item7 { get; } public T8 Item8 { get; } public T9 Item9 { get; } - public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9) + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9) { Item1 = item1; Item2 = item2; @@ -153,7 +153,7 @@ namespace FreeSql.Internal.Model Item9 = item9; } } - public class NaviteTuple + public class NativeTuple { public T1 Item1 { get; } public T2 Item2 { get; } @@ -165,7 +165,7 @@ namespace FreeSql.Internal.Model public T8 Item8 { get; } public T9 Item9 { get; } public T10 Item10 { get; } - public NaviteTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10) + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10) { Item1 = item1; Item2 = item2; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 98d6edeb..2b81e503 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -66,7 +66,7 @@ namespace FreeSql.Internal trytb.DbOldName = trytb.DbOldName?.ToUpper(); } if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; - var propsLazy = new List>(); + var propsLazy = new List>(); var propsNavObjs = new List(); var propsComment = CommonUtils.GetProperyCommentBySummary(entity); var propsCommentByDescAttr = CommonUtils.GetPropertyCommentByDescriptionAttribute(entity); @@ -95,7 +95,7 @@ namespace FreeSql.Internal var getIsVirtual = getMethod?.IsVirtual == true && getMethod?.IsFinal == false;// trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual; var setIsVirtual = setMethod?.IsVirtual == true && setMethod?.IsFinal == false; if (getIsVirtual == true || setIsVirtual == true) - propsLazy.Add(NaviteTuple.Create(p, getIsVirtual, setIsVirtual, getMethod, setMethod)); + propsLazy.Add(NativeTuple.Create(p, getIsVirtual, setIsVirtual, getMethod, setMethod)); } propsNavObjs.Add(p); continue; @@ -534,7 +534,7 @@ namespace FreeSql.Internal return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb; } - public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, NaviteTuple vp, StringBuilder cscode) + public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, NativeTuple vp, StringBuilder cscode) { var getMethod = vp?.Item4; var setMethod = vp?.Item5; diff --git a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs index 2e1736fd..6f34c0bd 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengCodeFirst.cs @@ -83,7 +83,7 @@ namespace FreeSql.Dameng { userId = DamengConnectionPool.GetUserId(conn.Value.ConnectionString); } - var seqcols = new List>(); //序列:列,表,自增 + var seqcols = new List>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 var sb = new StringBuilder(); @@ -134,7 +134,7 @@ namespace FreeSql.Dameng foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -245,10 +245,10 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); if (tbcol.Attribute.IsIdentity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; @@ -260,7 +260,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } } @@ -323,7 +323,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 8fd5f373..7abc2669 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -84,7 +84,7 @@ namespace FreeSql.Odbc.Dameng { userId = OdbcDamengConnectionPool.GetUserId(conn.Value.ConnectionString); } - var seqcols = new List>(); //序列:列,表,自增 + var seqcols = new List>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 var sb = new StringBuilder(); @@ -135,7 +135,7 @@ namespace FreeSql.Odbc.Dameng foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -246,10 +246,10 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); if (tbcol.Attribute.IsIdentity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; @@ -261,7 +261,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } } @@ -324,7 +324,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs index 1c75a1e0..a174427c 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs @@ -77,7 +77,7 @@ namespace FreeSql.Odbc.KingbaseES protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var sb = new StringBuilder(); - var seqcols = new List>(); //序列 + var seqcols = new List>(); //序列 foreach (var obj in objects) { @@ -123,7 +123,7 @@ namespace FreeSql.Odbc.KingbaseES foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -242,7 +242,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); } } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); @@ -254,7 +254,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql(@" @@ -322,7 +322,7 @@ where sys_namespace.nspname={0} and sys_class.relname={1} and sys_constraint.con foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 18b7a2cd..47eb5034 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -84,7 +84,7 @@ namespace FreeSql.Odbc.Oracle { userId = OdbcOracleConnectionPool.GetUserId(conn.Value.ConnectionString); } - var seqcols = new List>(); //序列:列,表,自增 + var seqcols = new List>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 var sb = new StringBuilder(); @@ -135,7 +135,7 @@ namespace FreeSql.Odbc.Oracle foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -243,10 +243,10 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); if (tbcol.Attribute.IsIdentity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; @@ -258,7 +258,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } } @@ -321,7 +321,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 471b4f54..22df7fb2 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -83,7 +83,7 @@ namespace FreeSql.Odbc.PostgreSQL protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var sb = new StringBuilder(); - var seqcols = new List>(); //序列 + var seqcols = new List>(); //序列 var is96 = true; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) @@ -135,7 +135,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -254,7 +254,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); } } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); @@ -266,7 +266,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql($@" @@ -334,7 +334,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 7cdeeeb0..e6a22742 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -85,7 +85,7 @@ namespace FreeSql.Oracle { userId = OracleConnectionPool.GetUserId(conn.Value.ConnectionString); } - var seqcols = new List>(); //序列:列,表,自增 + var seqcols = new List>(); //序列:列,表,自增 var seqnameDel = new List(); //要删除的序列+触发器 var sb = new StringBuilder(); @@ -136,7 +136,7 @@ namespace FreeSql.Oracle foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -244,10 +244,10 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); //修改列名 sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); if (tbcol.Attribute.IsIdentity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); } else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (isCommentChanged) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); continue; @@ -259,7 +259,7 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); } - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); } } @@ -322,7 +322,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs index 2b369a01..06ff4d52 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs @@ -89,7 +89,7 @@ namespace FreeSql.ShenTong protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { var sb = new StringBuilder(); - var seqcols = new List>(); //序列 + var seqcols = new List>(); //序列 foreach (var obj in objects) { @@ -135,7 +135,7 @@ namespace FreeSql.ShenTong foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { @@ -254,7 +254,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); } } if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) - seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); @@ -266,7 +266,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } var dsuksql = _commonUtils.FormatSql(@" @@ -335,7 +335,7 @@ where sys_namespace.nspname={0} and sys_class.relname={1} and sys_constraint.con foreach (var tbcol in tb.ColumnsByPosition) { sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); - if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, true)); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); } if (tb.Primarys.Any()) { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 5cc172ad..021d09e5 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -42,11 +42,11 @@ public static partial class FreeSqlSqlServerGlobalExtensions /// public static IFreeSql SetGlobalSelectWithLock(this IFreeSql that, SqlServerLock lockType, Dictionary rule) { - var value = NaviteTuple.Create(lockType, rule); + var value = NativeTuple.Create(lockType, rule); _dicSetGlobalSelectWithLock.AddOrUpdate(that.Ado.Identifier, value, (_, __) => value); return that; } - internal static ConcurrentDictionary>> _dicSetGlobalSelectWithLock = new ConcurrentDictionary>>(); + internal static ConcurrentDictionary>> _dicSetGlobalSelectWithLock = new ConcurrentDictionary>>(); #region ExecuteSqlBulkCopy /// From 51c6a733bc3a19a55513d551145aaf4f7c29fa98 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 2 Aug 2020 20:00:39 +0800 Subject: [PATCH 0787/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20pgsql=20DbFi?= =?UTF-8?q?rst=20=E5=BA=8F=E5=88=97=E7=9A=84=E8=AF=86=E5=88=AB=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=20pgsql10=20=E7=9A=84=E8=87=AA=E5=A2=9E?= =?UTF-8?q?=E8=AF=86=E5=88=AB=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++++++++++ .../PostgreSQL/PostgreSQLDbFirstTest.cs | 4 +++ .../PostgreSQL/PostgreSQLDbFirstTest.cs | 2 ++ .../KingbaseES/OdbcKingbaseESCodeFirst.cs | 2 +- .../KingbaseES/OdbcKingbaseESDbFirst.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 27 +++++++++++++++++-- .../PostgreSQLCodeFirst.cs | 2 +- .../PostgreSQLDbFirst.cs | 27 +++++++++++++++++-- .../ShenTongCodeFirst.cs | 2 +- .../ShenTongDbFirst.cs | 2 +- 11 files changed, 78 insertions(+), 10 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 65c54b71..e76e3740 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -513,5 +520,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs index e32c5ffb..1abfd208 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using System; +using System.Linq; using Xunit; namespace FreeSql.Tests.Odbc.PostgreSQL @@ -20,6 +21,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[2]); + var tb_alltype = t2.Where(a => a.Name == "tb_alltype").FirstOrDefault(); + + var tb_identity = t2.Where(a => a.Name == "test_new").FirstOrDefault(); } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs index 9bd86da7..a41e6896 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -23,6 +23,8 @@ namespace FreeSql.Tests.PostgreSQL var tb_alltype = t2.Where(a => a.Name == "tb_alltype").FirstOrDefault(); + var tb_identity = t2.Where(a => a.Name == "test_new").FirstOrDefault(); + } } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs index a174427c..1bdb9b64 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESCodeFirst.cs @@ -215,7 +215,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"NEXTVAL('") && string.Concat(a[5]).EndsWith(@"'::REGCLASS)"), + is_identity = string.Concat(a[5]).StartsWith(@"NEXTVAL('") && (string.Concat(a[5]).EndsWith(@"'::REGCLASS)") || string.Concat(a[5]).EndsWith(@"')")), attndims, comment = string.Concat(a[7]) }; diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs index 62156ec7..cd15ba6a 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs @@ -247,7 +247,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && string.Concat(row[6]).EndsWith(@"'::REGCLASS)"); + var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && (string.Concat(row[6]).EndsWith(@"'::REGCLASS)") || string.Concat(row[6]).EndsWith(@"')")); var comment = string.Concat(row[7]); var defaultValue = string.Concat(row[6]); int attndims = int.Parse(string.Concat(row[8])); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 22df7fb2..9f9b0d50 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -227,7 +227,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && (string.Concat(a[5]).EndsWith(@"'::regclass)") || string.Concat(a[5]).EndsWith(@"')")), attndims, comment = string.Concat(a[7]) }; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 52400443..1da4d276 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -23,6 +23,28 @@ namespace FreeSql.Odbc.PostgreSQL _commonExpression = commonExpression; } + public bool IsPg10 => ServerVersion >= 10; + public int ServerVersion + { + get + { + if (_ServerVersionValue == 0 && _orm.Ado.MasterPool != null) + using (var conn = _orm.Ado.MasterPool.Get()) + { + try + { + _ServerVersionValue = int.Parse(conn.Value.ServerVersion.Split('.')[0]); + } + catch + { + _ServerVersionValue = 9; + } + } + return _ServerVersionValue; + } + } + int _ServerVersionValue = 0; + public int GetDbType(DbColumnInfo column) => (int)GetOdbcType(column); OdbcType GetOdbcType(DbColumnInfo column) { @@ -217,7 +239,7 @@ d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, ns2.nspname, -a.attnum +a.attnum{(IsPg10 ? ", a.attidentity" : "")} from pg_class c inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid inner join pg_type t on t.oid = a.atttypid @@ -239,7 +261,8 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && (string.Concat(row[6]).EndsWith(@"'::regclass)") || string.Concat(row[6]).EndsWith(@"')")) + || IsPg10 && new[] { "a", "d" }.Contains(string.Concat(row[12])); //pg10 GENERATED { BY DEFAULT | AWAYS } AS IDENTITY var comment = string.Concat(row[7]); var defaultValue = string.Concat(row[6]); int attndims = int.Parse(string.Concat(row[8])); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index c0bc4d02..1d053470 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -274,7 +274,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && (string.Concat(a[5]).EndsWith(@"'::regclass)") || string.Concat(a[5]).EndsWith(@"')")), //pgsql10 attndims, comment = string.Concat(a[7]) }; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 11afd1cf..6420a5c5 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -29,6 +29,28 @@ namespace FreeSql.PostgreSQL _commonExpression = commonExpression; } + public bool IsPg10 => ServerVersion >= 10; + public int ServerVersion + { + get + { + if (_ServerVersionValue == 0 && _orm.Ado.MasterPool != null) + using (var conn = _orm.Ado.MasterPool.Get()) + { + try + { + _ServerVersionValue = int.Parse(conn.Value.ServerVersion.Split('.')[0]); + } + catch + { + _ServerVersionValue = 9; + } + } + return _ServerVersionValue; + } + } + int _ServerVersionValue = 0; + public int GetDbType(DbColumnInfo column) => (int)GetNpgsqlDbType(column); NpgsqlDbType GetNpgsqlDbType(DbColumnInfo column) { @@ -327,7 +349,7 @@ d.description as comment, a.attndims, case when t.typelem = 0 then t.typtype else t2.typtype end, ns2.nspname, -a.attnum +a.attnum{(IsPg10 ? ", a.attidentity" : "")} from pg_class c inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid inner join pg_type t on t.oid = a.atttypid @@ -349,7 +371,8 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"'::regclass)"); + var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && (string.Concat(row[6]).EndsWith(@"'::regclass)") || string.Concat(row[6]).EndsWith(@"')")) + || IsPg10 && new[] { "a", "d" }.Contains(string.Concat(row[12])); //pg10 GENERATED { BY DEFAULT | AWAYS } AS IDENTITY var comment = string.Concat(row[7]); var defaultValue = string.Concat(row[6]); int attndims = int.Parse(string.Concat(row[8])); diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs index 06ff4d52..075c7ad3 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongCodeFirst.cs @@ -227,7 +227,7 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); sqlType = string.Concat(sqlType), max_length = long.Parse(string.Concat(a[2])), is_nullable = string.Concat(a[4]) == "1", - is_identity = string.Concat(a[5]).StartsWith(@"NEXTVAL('") && string.Concat(a[5]).EndsWith(@"'::text)"), + is_identity = string.Concat(a[5]).StartsWith(@"NEXTVAL('") && (string.Concat(a[5]).EndsWith(@"'::text)") || string.Concat(a[5]).EndsWith(@"')")), attndims, comment = string.Concat(a[7]) }; diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs index 6f6e10b1..99dacadf 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs @@ -259,7 +259,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname") var max_length = int.Parse(string.Concat(row[3])); var sqlType = string.Concat(row[4]); var is_nullable = string.Concat(row[5]) == "1"; - var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && string.Concat(row[6]).EndsWith(@"'::text)"); + var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && (string.Concat(row[6]).EndsWith(@"'::text)") || string.Concat(row[6]).EndsWith(@"')")); var comment = string.Concat(row[7]); var defaultValue = string.Concat(row[6]); int attndims = int.Parse(string.Concat(row[8])); From 78c5433a092cf515f5f3981cf0877fc137e2b193 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Aug 2020 11:29:17 +0800 Subject: [PATCH 0788/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Prov?= =?UTF-8?q?ider.SqlServerForSystem=20=E4=BD=BF=E7=94=A8=20System.Data.SqlC?= =?UTF-8?q?lient.dll=20=E5=85=BC=E5=AE=B9=E6=9B=B4=E5=A4=9A=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E5=B9=B3=E5=8F=B0=EF=BC=9B#401=20#398=20#395=20#392?= =?UTF-8?q?=20#391?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SqlServerAdo/SqlServerAdoTest.cs | 6 ++- FreeSql.sln | 15 ++++++ FreeSql/FreeSqlBuilder.cs | 7 +-- ...FreeSql.Provider.SqlServerForSystem.csproj | 44 ++++++++++++++++++ .../key.snk | Bin 0 -> 596 bytes 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj create mode 100644 Providers/FreeSql.Provider.SqlServerForSystem/key.snk diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index 7dc5c181..e0a074d8 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -1,6 +1,8 @@ using FreeSql.DataAnnotations; using FreeSql.Tests.DataContext.SqlServer; +using NetTaste; using System; +using System.Collections.Generic; using Xunit; namespace FreeSql.Tests.SqlServer @@ -78,8 +80,8 @@ namespace FreeSql.Tests.SqlServer var t4 = g.sqlserver.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); - var t5 = g.sqlserver.Ado.Query(System.Data.CommandType.Text, "select * from xxx where Id = @Id", - new Microsoft.Data.SqlClient.SqlParameter("Id", 1)); + var t5 = g.sqlserver.Ado.Query("select * from xxx where Id = @Id", + new Dictionary { ["id"] = 1 }); } [Fact] diff --git a/FreeSql.sln b/FreeSql.sln index c84703c1..e1c05120 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -84,6 +84,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.ShenTong", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite", "FreeSql.Tests\FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite\FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj", "{330F15A7-5089-456B-B553-A98B14DEB764}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.SqlServerForSystem", "Providers\FreeSql.Provider.SqlServerForSystem\FreeSql.Provider.SqlServerForSystem.csproj", "{3D2BD8EC-253A-437F-B4C8-74BC0D91429B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -514,6 +516,18 @@ Global {330F15A7-5089-456B-B553-A98B14DEB764}.Release|x64.Build.0 = Release|Any CPU {330F15A7-5089-456B-B553-A98B14DEB764}.Release|x86.ActiveCfg = Release|Any CPU {330F15A7-5089-456B-B553-A98B14DEB764}.Release|x86.Build.0 = Release|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Debug|x64.Build.0 = Debug|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Debug|x86.Build.0 = Debug|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|Any CPU.Build.0 = Release|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x64.ActiveCfg = Release|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x64.Build.0 = Release|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x86.ActiveCfg = Release|Any CPU + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -543,6 +557,7 @@ Global {E74D90E8-1CBC-4677-817B-1CA05AB97937} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {07AB0B37-A8B1-4FB1-9259-7B804E369E36} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {938173AF-157F-4040-AED3-171DA1809CAA} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {3D2BD8EC-253A-437F-B4C8-74BC0D91429B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index e4ff315f..58fc9ee8 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -178,12 +178,13 @@ namespace FreeSql switch (_dataType) { case DataType.MySql: - type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); - if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); + type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark)); //MySql.Data.dll + if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark)); //MySqlConnector.dll if (type == null) throwNotFind("FreeSql.Provider.MySql.dll", "FreeSql.MySql.MySqlProvider<>"); break; case DataType.SqlServer: - type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); + type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark)); //Microsoft.Data.SqliClient.dll + if (type == null) type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServerForSystem")?.MakeGenericType(typeof(TMark)); //System.Data.SqliClient.dll if (type == null) throwNotFind("FreeSql.Provider.SqlServer.dll", "FreeSql.SqlServer.SqlServerProvider<>"); break; case DataType.PostgreSQL: diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj new file mode 100644 index 00000000..2debe31c --- /dev/null +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -0,0 +1,44 @@ + + + + netstandard2.0;net451;net45;net40 + 1.7.1 + true + ncc;YeXiangQin + FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + true + key.snk + false + + + + + + + + + + + + + + + + + + + + net40 + + + diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/key.snk b/Providers/FreeSql.Provider.SqlServerForSystem/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..ee20b4b1a0815eac842bc01d4becaa8814ae0b14 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097nKW;Q)(l0*2_LP37mJV1_SL_wJp_%19 zz}Ioucr4R)UNZq%r-$=RryFiI8)w!j<{z)y2~@p##L$SPx^Ow#GA*zK`{`cfYL7{l+Kxddb$Rvhs&7lm@`8>uzw0+OE7j#mY{c`qYhBLw zcTGv3<(P)_%zO>@*n(qI-%i9l@ajAusufL6g2Vv#NI96{=y#u{9B_yQKTPz)Y1$HZ zD>)q$vf8;gu0YshJ#~JP;~%_{2fSYfOELVZHBw(!Q9B`pKjDnCeY`_d!%4(WhMfK$ zib<3?gsgWm`U%MfEU6k^$B1oKeoOR+6Ka49G&ay?N* zWrr4(9T)d$I0G(sI2kIll6}TqEoiT#l$9WiCiIHArG(J)@}oPH&x7=*Q#zIO2)&${ zs=8;1+&r`77n1*!D3-|5;1jS&VG_ExzZ)Nhn^BcViCiS4rX}W|LSx7qNZbgPU3FF1 zjjOa|%br?&bZxd+I~%#VD@?Y)q9}!bhgyA-Znito|8TOd$`r z#f$F8O#2i?@t)1AqE6%gl3yp72kFp8Z&aePj>(S716o zDo}MQ0!f+r8b6a|9OKhVLMi>I(pfb~lkYJ>SkhIf*VGAzeZPoUrp+NtlKmiYU*A)1 iK9<^9bbhHh%Datqpbh^L1ZmM}I29}Y1xF)Q!$<>NydEt8 literal 0 HcmV?d00001 From 2f254d23f9609bb6a0871d2aa00d61fd541860c3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Aug 2020 11:48:57 +0800 Subject: [PATCH 0789/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IsNullable?= =?UTF-8?q?=20=3D=20false=20=E6=8F=92=E5=85=A5=E7=9A=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=80=BC=E4=B8=BA=20null=20=E5=88=99=E4=BB=A5=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E6=8F=92=E5=85=A5=EF=BC=88=E9=98=B2=E6=AD=A2?= =?UTF-8?q?DB=E6=8A=A5=E9=94=99=EF=BC=89=EF=BC=9B#384?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/InsertProvider.cs | 1 + Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs | 1 + Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs | 1 + Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs | 1 + Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs | 1 + 5 files changed, 5 insertions(+) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index e8bb406e..3abd94b2 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -548,6 +548,7 @@ namespace FreeSql.Internal.CommonProvider else { object val = col.GetMapValue(d); + if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index addd7d09..643da775 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -67,6 +67,7 @@ namespace FreeSql.Dameng.Curd else { object val = col.GetMapValue(d); + if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index 01bb6ae5..da81f57b 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -67,6 +67,7 @@ namespace FreeSql.Odbc.Dameng else { object val = col.GetMapValue(d); + if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index 0f2af13a..cb49ddf8 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -67,6 +67,7 @@ namespace FreeSql.Odbc.Oracle else { object val = col.GetMapValue(d); + if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index bf9c9902..98117dc5 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -69,6 +69,7 @@ namespace FreeSql.Oracle.Curd else { object val = col.GetMapValue(d); + if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else From 0b1865f7e7da23aa887d81a994b827317f61b863 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Aug 2020 11:58:46 +0800 Subject: [PATCH 0790/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IsNullable?= =?UTF-8?q?=20=3D=20false=20=E6=8F=92=E5=85=A5=E7=9A=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=80=BC=E4=B8=BA=20null=20=E5=88=99=E4=BB=A5=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E6=8F=92=E5=85=A5=EF=BC=88=E9=98=B2=E6=AD=A2?= =?UTF-8?q?DB=E6=8A=A5=E9=94=99=EF=BC=89=EF=BC=9B#384?= 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 | 14 ++++++++++++++ .../Internal/CommonProvider/InsertProvider.cs | 2 +- .../FreeSql.Provider.Dameng/Curd/DamengInsert.cs | 2 +- .../Dameng/Curd/OdbcDamengInsert.cs | 2 +- .../Oracle/Curd/OdbcOracleInsert.cs | 2 +- .../FreeSql.Provider.Oracle/Curd/OracleInsert.cs | 2 +- 7 files changed, 19 insertions(+), 21 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index e76e3740..65c54b71 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -520,14 +513,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index c8761dff..1f93eca1 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -156,9 +156,23 @@ namespace FreeSql.Tests } } + class testInsertNullable + { + [Column(IsIdentity = true)] + public long Id { get; set; } + + [Column(IsNullable = false)] + public string str1 { get; set; } + [Column(IsNullable = false)] + public int? int1 { get; set; } + } + [Fact] public void Test03() { + g.sqlite.Insert(new testInsertNullable()).NoneParameter().ExecuteAffrows(); + + var sqlxx = g.pgsql.InsertOrUpdate().SetSource(new userinfo { userid = 10 }).UpdateColumns(a => new { a.birthday, a.CardNo }).ToSql(); var aff1 = g.sqlite.GetRepository().Delete(10086); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 3abd94b2..6275a822 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -548,7 +548,7 @@ namespace FreeSql.Internal.CommonProvider else { object val = col.GetMapValue(d); - if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 + if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index 643da775..2bee3fba 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -67,7 +67,7 @@ namespace FreeSql.Dameng.Curd else { object val = col.GetMapValue(d); - if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 + if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index da81f57b..de1f043d 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -67,7 +67,7 @@ namespace FreeSql.Odbc.Dameng else { object val = col.GetMapValue(d); - if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 + if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index cb49ddf8..f4ea0596 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -67,7 +67,7 @@ namespace FreeSql.Odbc.Oracle else { object val = col.GetMapValue(d); - if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 + if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 98117dc5..371191d9 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -69,7 +69,7 @@ namespace FreeSql.Oracle.Curd else { object val = col.GetMapValue(d); - if (val == null && col.Attribute.IsNullable == false) val = Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 + if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); else From 270085e50b61fd346414fc51ba8617b831a895ed Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Aug 2020 12:30:28 +0800 Subject: [PATCH 0791/1029] v1.8.0-preview0803 #401 #398 #397 #395 #392 #391 #384 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 332 ++++++++++-------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 208 insertions(+), 171 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6dab843f..1bb2356e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index de883633..9fd8f321 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 914ba8c3..c965997f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 45150f02..48c6ed84 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 032b934d..058b4d7c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.7.1 + 1.8.0-preview0803 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 4b75f6be..38c8f0a4 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index f13cbb4a..b2fd920f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 65c54b71..7ce0c897 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index a061be6c..2f08e7d6 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.7.1 + 1.8.0-preview0803 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8f557987..53341b57 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index bde37cf0..4663af8b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2584,145 +2584,6 @@ - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3392,12 +3253,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3468,12 +3323,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4132,3 +3981,184 @@ +.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 026ccaf3..8c48dabf 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 15c9934b..5c99c0a8 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 33815edd..f3ec6b98 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6fcf5dda..9dd27214 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index ff428c26..b1458912 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index be32e3ea..7c7749c2 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 89d242db..3179215e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 0ea2a297..2f4fc06c 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9d9c1031..6bad3a14 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 2debe31c..8b8e79ea 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 0b25ae25..69e8640e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.7.1 + 1.8.0-preview0803 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From c7cd1cda3b54dc51e0777b0f17f9dc596c95fb5d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Aug 2020 14:35:43 +0800 Subject: [PATCH 0792/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20fsql.InsertO?= =?UTF-8?q?rUpdate=20=E5=9C=A8=E5=90=8C=E7=BA=BF=E7=A8=8B=E4=BA=8B?= =?UTF-8?q?=E5=8A=A1=E6=A8=A1=E5=BC=8F=E5=86=85=E4=BD=BF=E7=94=A8=E7=9A=84?= =?UTF-8?q?=20bug=20#402=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 - FreeSql/FreeSql.xml | 332 ++++++++---------- .../CommonProvider/InsertOrUpdateProvider.cs | 6 + 3 files changed, 157 insertions(+), 188 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 7ce0c897..65c54b71 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4663af8b..bde37cf0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2584,6 +2584,145 @@ + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3253,6 +3392,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3323,6 +3468,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3981,184 +4132,3 @@ -.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 99d2c609..915eeca5 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -214,6 +214,9 @@ namespace FreeSql.Internal.CommonProvider var ss = SplitSourceByIdentityValueIsNull(_source); try { + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { _source = ss.Item1; @@ -314,6 +317,9 @@ namespace FreeSql.Internal.CommonProvider var ss = SplitSourceByIdentityValueIsNull(_source); try { + if (_transaction == null) + this.WithTransaction(_orm.Ado.TransactionCurrentThread); + if (_transaction != null) { _source = ss.Item1; From 78ac7ab6aedfc56f3456e197745e7786cd5651c2 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Aug 2020 15:28:51 +0800 Subject: [PATCH 0793/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20fsql.Ado.Exe?= =?UTF-8?q?cuteDataTable=20=E5=BD=93=E8=AE=B0=E5=BD=95=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E6=97=B6=EF=BC=8C=E6=9C=AA=E8=BF=94=E5=9B=9E=20Column?= =?UTF-8?q?s=20=E8=AE=BE=E7=BD=AE=20403=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++ .../CommonProvider/AdoProvider/AdoProvider.cs | 56 ++++++++++--------- .../AdoProvider/AdoProviderAsync.cs | 56 ++++++++++--------- 3 files changed, 78 insertions(+), 50 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 65c54b71..e76e3740 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -513,5 +520,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 840faa80..977621fd 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -188,7 +188,7 @@ namespace FreeSql.Internal.CommonProvider ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; } - }, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdParms); return NativeTuple.Create(ret1, ret2); } @@ -273,7 +273,7 @@ namespace FreeSql.Internal.CommonProvider ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; } - }, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdParms); return NativeTuple.Create(ret1, ret2, ret3); } @@ -381,7 +381,7 @@ namespace FreeSql.Internal.CommonProvider ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; } - }, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdParms); return NativeTuple.Create(ret1, ret2, ret3, ret4); } @@ -512,7 +512,7 @@ namespace FreeSql.Internal.CommonProvider ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, fetch.Object, 0, _util).Value); break; } - }, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdParms); return NativeTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion @@ -522,8 +522,8 @@ namespace FreeSql.Internal.CommonProvider public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(connection, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public void ExecuteReader(Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, fetchHandler, cmdType, cmdText, cmdParms); public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, fetchHandler, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => fetchHandler(fetch), cmdType, cmdText, cmdParms); - void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action, int> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdParms); + void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action, int> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -586,7 +586,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - ExecuteReaderMultiple(multipleResult, connection, transaction, fetchHandler, cmdType, cmdText, cmdParms); + ExecuteReaderMultiple(multipleResult, connection, transaction, fetchHandler, schemaHandler, cmdType, cmdText, cmdParms); return; } } @@ -606,9 +606,15 @@ namespace FreeSql.Internal.CommonProvider var fetch = new FetchCallbackArgs { Object = dr }; while (true) { + bool isfirst = true; while (true) { bool isread = dr.Read(); + if (schemaHandler != null && isfirst) + { + isfirst = false; + schemaHandler(dr, resultIndex); + } if (isread == false) break; if (fetchHandler != null) @@ -676,19 +682,18 @@ namespace FreeSql.Internal.CommonProvider DataTable dt = null; ExecuteReaderMultiple(16, connection, transaction, (fetch, result) => { - if (ret.Tables.Count <= result) - { - dt = ret.Tables.Add(); - for (var a = 0; a < fetch.Object.FieldCount; a++) - { - var name = fetch.Object.GetName(a); - if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - dt.Columns.Add(name, fetch.Object.GetFieldType(a)); - } - } object[] values = new object[dt.Columns.Count]; fetch.Object.GetValues(values); dt.Rows.Add(values); + }, (dr, result) => + { + dt = ret.Tables.Add(); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; + dt.Columns.Add(name, dr.GetFieldType(a)); + } }, cmdType, cmdText, cmdParms); return ret; } @@ -700,18 +705,19 @@ namespace FreeSql.Internal.CommonProvider public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); - ExecuteReader(connection, transaction, fetch => + ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => { - if (ret.Columns.Count == 0) - for (var a = 0; a < fetch.Object.FieldCount; a++) - { - var name = fetch.Object.GetName(a); - if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - ret.Columns.Add(name, fetch.Object.GetFieldType(a)); - } object[] values = new object[ret.Columns.Count]; fetch.Object.GetValues(values); ret.Rows.Add(values); + }, (dr, result) => + { + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; + ret.Columns.Add(name, dr.GetFieldType(a)); + } }, cmdType, cmdText, cmdParms); return ret; } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 264ac27e..a16381b2 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -110,7 +110,7 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdParms); return NativeTuple.Create(ret1, ret2); } @@ -196,7 +196,7 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdParms); return NativeTuple.Create(ret1, ret2, ret3); } @@ -305,7 +305,7 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdParms); return NativeTuple.Create(ret1, ret2, ret3, ret4); } @@ -437,7 +437,7 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdParms); return NativeTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion @@ -447,8 +447,8 @@ namespace FreeSql.Internal.CommonProvider public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public Task ExecuteReaderAsync(Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, cmdParms); public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), cmdType, cmdText, cmdParms); - async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdParms); + async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -511,7 +511,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, fetchHandler, cmdType, cmdText, cmdParms); + await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, fetchHandler, schemaHandler, cmdType, cmdText, cmdParms); return; } } @@ -531,9 +531,15 @@ namespace FreeSql.Internal.CommonProvider var fetch = new FetchCallbackArgs { Object = dr }; while (true) { + bool isfirst = true; while (true) { bool isread = await dr.ReadAsync(); + if (schemaHandler != null && isfirst) + { + isfirst = false; + schemaHandler(dr, resultIndex); + } if (isread == false) break; if (fetchHandler != null) @@ -599,19 +605,18 @@ namespace FreeSql.Internal.CommonProvider DataTable dt = null; await ExecuteReaderMultipleAsync(16, connection, transaction, async (fetch, result) => { - if (ret.Tables.Count <= result) - { - dt = ret.Tables.Add(); - for (var a = 0; a < fetch.Object.FieldCount; a++) - { - var name = fetch.Object.GetName(a); - if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - dt.Columns.Add(name, fetch.Object.GetFieldType(a)); - } - } object[] values = new object[dt.Columns.Count]; for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); dt.Rows.Add(values); + }, (dr, result) => + { + dt = ret.Tables.Add(); + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; + dt.Columns.Add(name, dr.GetFieldType(a)); + } }, cmdType, cmdText, cmdParms); return ret; } @@ -623,18 +628,19 @@ namespace FreeSql.Internal.CommonProvider async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); - await ExecuteReaderAsync(connection, transaction, async fetch => + await ExecuteReaderMultipleAsync(1, connection, transaction, async (fetch, result) => { - if (ret.Columns.Count == 0) - for (var a = 0; a < fetch.Object.FieldCount; a++) - { - var name = fetch.Object.GetName(a); - if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; - ret.Columns.Add(name, fetch.Object.GetFieldType(a)); - } object[] values = new object[ret.Columns.Count]; for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); ret.Rows.Add(values); + }, (dr, result) => + { + for (var a = 0; a < dr.FieldCount; a++) + { + var name = dr.GetName(a); + if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; + ret.Columns.Add(name, dr.GetFieldType(a)); + } }, cmdType, cmdText, cmdParms); return ret; } From 885b759c3bf1efead5ab67c751a6c5c2035f01a8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 3 Aug 2020 15:32:24 +0800 Subject: [PATCH 0794/1029] v1.8.0-preview0805 #403 #402 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1bb2356e..65d079c4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 9fd8f321..15e9ce0d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c965997f..e11401f7 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 48c6ed84..c3675937 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 058b4d7c..07689bc9 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0803 + 1.8.0-preview0805 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 38c8f0a4..bbcfee13 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b2fd920f..4356ef7f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 2f08e7d6..46d45a32 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 53341b57..0a3e515b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 8c48dabf..2c47cf7f 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 5c99c0a8..1ccf5644 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index f3ec6b98..3b56d9bf 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 9dd27214..0299f9bd 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index b1458912..11becb77 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7c7749c2..7c2e0d45 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 3179215e..92aeb904 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 2f4fc06c..c7772eb2 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 6bad3a14..e6c86e49 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 8b8e79ea..a46792b6 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 69e8640e..c39aecce 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0803 + 1.8.0-preview0805 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 255cbf33aa26cd2d7487d5dc42e2aaee9ead0834 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 4 Aug 2020 12:55:14 +0800 Subject: [PATCH 0795/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20Repository?= =?UTF-8?q?=20EndEdit=20=E4=BB=A5=E4=BA=8B=E5=8A=A1=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=EF=BC=8C=E8=8B=A5=E5=A4=96=E9=83=A8=E6=9C=AA?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=BA=8B=E5=8A=A1=E5=88=99=E8=87=AA=E5=B7=B1?= =?UTF-8?q?=E5=BC=80=E5=90=AF=E4=BA=8B=E5=8A=A1=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/Repository/BaseRepository.cs | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 675cf0b4..027c53a2 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -142,7 +142,33 @@ namespace FreeSql } public void BeginEdit(List data) => _dbset.BeginEdit(data); - public int EndEdit() => _dbset.EndEdit(); + public int EndEdit() + { + _db.FlushCommand(); + if (UnitOfWork?.GetOrBeginTransaction(true) == null && _db.OrmOriginal.Ado.TransactionCurrentThread == null) + { + int affrows = 0; + IUnitOfWork olduow = UnitOfWork; + UnitOfWork = new UnitOfWork(_db.OrmOriginal); + try + { + affrows = _dbset.EndEdit(); + UnitOfWork.Commit(); + } + catch + { + UnitOfWork.Rollback(); + throw; + } + finally + { + UnitOfWork.Dispose(); + UnitOfWork = olduow; + } + return affrows; + } + return _dbset.EndEdit(); + } } public abstract partial class BaseRepository : BaseRepository, IBaseRepository From 18cabd22b98b3f51fcd4d839dff4a44403d4d87c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 4 Aug 2020 20:54:15 +0800 Subject: [PATCH 0796/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20AsTreeCte=20?= =?UTF-8?q?+=20ToUpdate/ToDelete=20=E5=AE=9E=E7=8E=B0=E6=A0=91=E6=89=80?= =?UTF-8?q?=E6=9C=89=E5=AD=90=E8=8A=82=E7=82=B9=E5=88=A0=E9=99=A4=E6=88=96?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetSync.cs | 8 +- FreeSql.DbContext/FreeSql.DbContext.xml | 22 +---- .../Repository/Repository/BaseRepository.cs | 6 +- .../Repository/Repository/IBaseRepository.cs | 3 +- .../MySqlConnector/Curd/MySqlSelectTest.cs | 24 ++++- .../g.cs | 1 + .../Dameng/Curd/DamengSelectTest.cs | 18 ++++ .../KingbaseES/Curd/KingbaseESSelectTest.cs | 18 ++++ .../MySql/Curd/MySqlSelectTest.cs | 24 ++++- .../Oracle/Curd/OracleSelectTest.cs | 18 ++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 18 ++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 18 ++++ .../FreeSql.Tests.Provider.Odbc/g.cs | 1 + .../Dameng/Curd/DamengSelectTest.cs | 18 ++++ .../MySql/Curd/MySqlSelectTest.cs | 24 ++++- .../Oracle/Curd/OracleSelectTest.cs | 18 ++++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 18 ++++ .../ShenTong/Curd/ShenTongSelectTest.cs | 2 + .../SqlServer/Curd/SqlServerSelectTest.cs | 18 ++++ .../Sqlite/Curd/SqliteSelectTest.cs | 16 ++++ FreeSql.Tests/FreeSql.Tests/g.cs | 1 + .../Internal/CommonProvider/DeleteProvider.cs | 24 ++--- .../SelectProvider/Select0Provider.cs | 89 +++++++++++++++---- .../Internal/CommonProvider/UpdateProvider.cs | 2 + 24 files changed, 346 insertions(+), 63 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index b6a38362..a6dddb08 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -567,11 +567,13 @@ namespace FreeSql /// 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句 /// 注意:* 本方法只支持单表操作,不支持导航属性级联保存 /// + /// 可选参数:手工传递最终的 data 值进行对比默认:如果不传递,则使用 BeginEdit 传入的 data 引用进行对比 /// - public int EndEdit() + public int EndEdit(List data = null) { + if (data == null) data = _dataEditing; var beforeAffrows = 0; - if (_dataEditing == null) return 0; + if (data == null) return 0; var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; _db.Options.EnableAddOrUpdateNavigateList = false; try @@ -579,7 +581,7 @@ namespace FreeSql DbContextFlushCommand(); var addList = new List(); var ediList = new List>(); - foreach (var item in _dataEditing) + foreach (var item in data) { var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); if (_statesEditing.TryRemove(key, out var state) == false) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index e76e3740..d61f6f2f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -183,12 +176,13 @@ - + 完成编辑数据,进行保存动作 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + 可选参数:手工传递最终的 data 值进行对比默认:如果不传递,则使用 BeginEdit 传入的 data 引用进行对比 @@ -330,12 +324,13 @@ - + 完成编辑数据,进行保存动作 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + 可选参数:手工传递最终的 data 值进行对比默认:如果不传递,则使用 BeginEdit 传入的 data 引用进行对比 @@ -520,14 +515,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 027c53a2..3a166cd5 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -142,7 +142,7 @@ namespace FreeSql } public void BeginEdit(List data) => _dbset.BeginEdit(data); - public int EndEdit() + public int EndEdit(List data = null) { _db.FlushCommand(); if (UnitOfWork?.GetOrBeginTransaction(true) == null && _db.OrmOriginal.Ado.TransactionCurrentThread == null) @@ -152,7 +152,7 @@ namespace FreeSql UnitOfWork = new UnitOfWork(_db.OrmOriginal); try { - affrows = _dbset.EndEdit(); + affrows = _dbset.EndEdit(data); UnitOfWork.Commit(); } catch @@ -167,7 +167,7 @@ namespace FreeSql } return affrows; } - return _dbset.EndEdit(); + return _dbset.EndEdit(data); } } diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index c66937ee..29832d44 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -92,8 +92,9 @@ namespace FreeSql /// 该方法根据 BeginEdit 传入的数据状态分析出添加、修改、删除 SQL 语句 /// 注意:* 本方法只支持单表操作,不支持导航属性级联保存 /// + /// 可选参数:手工传递最终的 data 值进行对比默认:如果不传递,则使用 BeginEdit 传入的 data 引用进行对比 /// - int EndEdit(); + int EndEdit(List data = null); #if net40 #else diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 7b587941..c9d9dc32 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1904,7 +1904,7 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); //Assert.Single(t3); //Assert.Equal("100000", t3[0].Code); //Assert.Single(t3[0].Childs); @@ -1913,18 +1913,34 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 //Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); //Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); //Assert.Equal(4, t3.Count); //Assert.Equal("100000", t3[0].Code); //Assert.Equal("110000", t3[1].Code); //Assert.Equal("110100", t3[2].Code); //Assert.Equal("110101", t3[3].Code); - //t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + //t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); //Assert.Equal(3, t3.Count); //Assert.Equal("110000", t3[0].Code); //Assert.Equal("110100", t3[1].Code); //Assert.Equal("110101", t3[2].Code); + + //var select = fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte() + // //.OrderBy("a.cte_level desc") //递归层级 + // ; + //// var list = select.ToList(); //自己调试看查到的数据 + //select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + //Assert.Equal(855, fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte().Distinct().First(a => a.testint)); + + //Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + //Assert.False(fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1938,6 +1954,8 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs index bd67be80..efaeec3a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/g.cs @@ -10,6 +10,7 @@ public class g static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") //.UseConnectionFactory(FreeSql.DataType.MySql, () => new MySql.Data.MySqlClient.MySqlConnection("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;")) + //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=192.168.164.10;Port=33061;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index f1705d77..a50acd5b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -1808,6 +1808,22 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1821,6 +1837,8 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs index bba60c6e..6abeb543 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs @@ -1764,6 +1764,22 @@ WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1777,6 +1793,8 @@ WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 00203bd0..d4a1cc95 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1915,7 +1915,7 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); //Assert.Single(t3); //Assert.Equal("100000", t3[0].Code); //Assert.Single(t3[0].Childs); @@ -1924,18 +1924,34 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 //Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); //Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); //Assert.Equal(4, t3.Count); //Assert.Equal("100000", t3[0].Code); //Assert.Equal("110000", t3[1].Code); //Assert.Equal("110100", t3[2].Code); //Assert.Equal("110101", t3[3].Code); - //t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + //t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); //Assert.Equal(3, t3.Count); //Assert.Equal("110000", t3[0].Code); //Assert.Equal("110100", t3[1].Code); //Assert.Equal("110101", t3[2].Code); + + //var select = fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte() + // //.OrderBy("a.cte_level desc") //递归层级 + // ; + //// var list = select.ToList(); //自己调试看查到的数据 + //select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + //Assert.Equal(855, fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte().Distinct().First(a => a.testint)); + + //Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + //Assert.False(fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1949,6 +1965,8 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index a21ab06c..5e18bcfc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -1800,6 +1800,22 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1813,6 +1829,8 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 5dad0dd0..bccdf194 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1859,6 +1859,22 @@ WHERE ((((a.""id"")::text) in (SELECT b.""title"" Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1872,6 +1888,8 @@ WHERE ((((a.""id"")::text) in (SELECT b.""title"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 78f16fee..dcfcc65d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -1750,6 +1750,22 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1763,6 +1779,8 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs index 0f812460..fbe03f84 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/g.cs @@ -9,6 +9,7 @@ public class g static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.OdbcMySql, "Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Max pool size=2") //.UseConnectionFactory(FreeSql.DataType.OdbcMySql, () => new System.Data.Odbc.OdbcConnection("Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;")) + //.UseConnectionString(FreeSql.DataType.OdbcMySql, "Driver={MySQL ODBC 8.0 Unicode Driver};Server=192.168.164.10;port=33061;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Max pool size=2") .UseAutoSyncStructure(true) .UseMonitorCommand( cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index bb33c0bb..441fc1f9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -1809,6 +1809,22 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1822,6 +1838,8 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 29f58ac3..92eade33 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1968,7 +1968,7 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToTreeList(); + //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); //Assert.Single(t3); //Assert.Equal("100000", t3[0].Code); //Assert.Single(t3[0].Childs); @@ -1977,18 +1977,34 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 //Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); //Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - //t3 = fsql.Select().Where(a => a.Name == "中国").AsCteTree().OrderBy(a => a.Code).ToList(); + //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); //Assert.Equal(4, t3.Count); //Assert.Equal("100000", t3[0].Code); //Assert.Equal("110000", t3[1].Code); //Assert.Equal("110100", t3[2].Code); //Assert.Equal("110101", t3[3].Code); - //t3 = fsql.Select().Where(a => a.Name == "北京").AsCteTree().OrderBy(a => a.Code).ToList(); + //t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); //Assert.Equal(3, t3.Count); //Assert.Equal("110000", t3[0].Code); //Assert.Equal("110100", t3[1].Code); //Assert.Equal("110101", t3[2].Code); + + //var select = fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte() + // //.OrderBy("a.cte_level desc") //递归层级 + // ; + //// var list = select.ToList(); //自己调试看查到的数据 + //select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + //Assert.Equal(855, fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte().Distinct().First(a => a.testint)); + + //Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + //Assert.False(fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -2002,6 +2018,8 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 6839731b..4ec7bdc4 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -1800,6 +1800,22 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1813,6 +1829,8 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index bd253f74..7cf806bd 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -1875,6 +1875,22 @@ WHERE ((((a.""id"")::text) in (SELECT b.""title"" Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1888,6 +1904,8 @@ WHERE ((((a.""id"")::text) in (SELECT b.""title"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs index 8eca4e32..07176067 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs @@ -1842,6 +1842,8 @@ WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 34377feb..429b64d9 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1843,6 +1843,22 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] @@ -1856,6 +1872,8 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] [Column(StringLength = 6)] public virtual string ParentCode { get; set; } + + public int testint { get; set; } } [Table(Name = "D_District", DisableSyncStructure = true)] public class VM_District_Child : BaseDistrict diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 7cc33e4e..fe68188f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1960,6 +1960,22 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 0e99a61a..7b814ff5 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -11,6 +11,7 @@ public class g static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .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=5") //.UseConnectionFactory(FreeSql.DataType.MySql, () => new MySql.Data.MySqlClient.MySqlConnection("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;")) + //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=192.168.164.10;Port=33061;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") .UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index f4179e1d..5e28e3a9 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -13,17 +13,18 @@ namespace FreeSql.Internal.CommonProvider public abstract partial class DeleteProvider : IDelete where T1 : class { - protected IFreeSql _orm; - protected CommonUtils _commonUtils; - protected CommonExpression _commonExpression; - protected TableInfo _table; - protected Func _tableRule; - protected StringBuilder _where = new StringBuilder(); - protected int _whereTimes = 0; - protected List _whereGlobalFilter; - protected List _params = new List(); - protected DbTransaction _transaction; - protected DbConnection _connection; + public IFreeSql _orm; + public CommonUtils _commonUtils; + public CommonExpression _commonExpression; + public TableInfo _table; + public Func _tableRule; + public StringBuilder _where = new StringBuilder(); + public int _whereTimes = 0; + public List _whereGlobalFilter; + public List _params = new List(); + public DbTransaction _transaction; + public DbConnection _connection; + public Action _interceptSql; public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { @@ -155,6 +156,7 @@ namespace FreeSql.Internal.CommonProvider if (string.IsNullOrEmpty(globalFilterCondi) == false) sb.Append(" AND ").Append(globalFilterCondi); } + _interceptSql?.Invoke(sb); return sb.ToString(); } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index b223326c..ec88baf0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -928,43 +928,96 @@ namespace FreeSql.Internal.CommonProvider string GetToDeleteWhere(string alias) { var pks = _tables[0].Table.Primarys; - if (pks.Length == 1) - return $"{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)} in (select * from ({this.ToSql($"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)}")}) {alias})"; - else + var old_selectVal = _select; + switch (_orm.Ado.DataType) { - var concatTypes = new Type[pks.Length * 2 - 1]; - var concatMainCols = new string[pks.Length * 2 - 1]; - var concatInCols = new string[pks.Length * 2 - 1]; - var concatSplit = _commonUtils.FormatSql("{0}", $",{alias},"); - for (var a = 0; a < pks.Length; a++) + case DataType.Dameng: + case DataType.OdbcDameng: //达梦不能这样 + case DataType.Oracle: + case DataType.OdbcOracle: + break; + default: + _select = "SELECT "; + break; + } + try + { + if (pks.Length == 1) + return $"{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)} in (select * from ({this.ToSql($"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(_tables[0].Table.Primarys[0].Attribute.Name)}")}) {alias})"; + else { - concatTypes[a * 2] = pks[a].CsType; - concatMainCols[a * 2] = _commonUtils.QuoteSqlName(pks[a].Attribute.Name); - concatInCols[a * 2] = $"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(pks[a].Attribute.Name)}"; - if (a < pks.Length - 1) + var concatTypes = new Type[pks.Length * 2 - 1]; + var concatMainCols = new string[pks.Length * 2 - 1]; + var concatInCols = new string[pks.Length * 2 - 1]; + var concatSplit = _commonUtils.FormatSql("{0}", $",{alias},"); + for (var a = 0; a < pks.Length; a++) { - concatTypes[a * 2 + 1] = typeof(string); - concatMainCols[a * 2 + 1] = concatSplit; - concatInCols[a * 2 + 1] = concatSplit; + concatTypes[a * 2] = pks[a].CsType; + concatMainCols[a * 2] = _commonUtils.QuoteSqlName(pks[a].Attribute.Name); + concatInCols[a * 2] = $"{_tables[0].Alias}.{_commonUtils.QuoteSqlName(pks[a].Attribute.Name)}"; + if (a < pks.Length - 1) + { + concatTypes[a * 2 + 1] = typeof(string); + concatMainCols[a * 2 + 1] = concatSplit; + concatInCols[a * 2 + 1] = concatSplit; + } } + return $"{_commonUtils.StringConcat(concatMainCols, concatTypes)} in (select * from ({this.ToSql($"{_commonUtils.StringConcat(concatInCols, concatTypes)} as as1")}) {alias})"; } - return $"{_commonUtils.StringConcat(concatMainCols, concatTypes)} in (select * from ({this.ToSql($"{_commonUtils.StringConcat(concatInCols, concatTypes)} as as1")}) {alias})"; + } + finally + { + _select = old_selectVal; } } public IDelete ToDelete() { if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToDelete 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); - var del = _orm.Delete(); + var del = _orm.Delete() as DeleteProvider; if (_tables[0].Table.Type != typeof(T1)) del.AsType(_tables[0].Table.Type); if (_params.Any()) del.GetType().GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(del, new List(_params.ToArray())); + switch (_orm.Ado.DataType) + { + case DataType.Dameng: + case DataType.OdbcDameng: //达梦不能这样 + case DataType.Oracle: + case DataType.OdbcOracle: + break; + default: + var beforeSql = this._select; + if (beforeSql.EndsWith("SELECT ", StringComparison.OrdinalIgnoreCase)) + { + beforeSql = beforeSql.Substring(0, beforeSql.Length - 7); + if (string.IsNullOrEmpty(beforeSql) == false) + del._interceptSql = sb => sb.Insert(0, beforeSql); + } + break; + } return del.Where(GetToDeleteWhere("ftb_del")); } public IUpdate ToUpdate() { if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToUpdate 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); - var upd = _orm.Update(); + var upd = _orm.Update() as UpdateProvider; if (_tables[0].Table.Type != typeof(T1)) upd.AsType(_tables[0].Table.Type); if (_params.Any()) upd.GetType().GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(upd, new List(_params.ToArray())); + switch (_orm.Ado.DataType) + { + case DataType.Dameng: + case DataType.OdbcDameng: //达梦不能这样 + case DataType.Oracle: + case DataType.OdbcOracle: + break; + default: + var beforeSql = this._select; + if (beforeSql.EndsWith("SELECT ", StringComparison.OrdinalIgnoreCase)) + { + beforeSql = beforeSql.Substring(0, beforeSql.Length - 7); + if (string.IsNullOrEmpty(beforeSql) == false) + upd._interceptSql = sb => sb.Insert(0, beforeSql); + } + break; + } return upd.Where(GetToDeleteWhere("ftb_upd")); } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 8fbf566f..93b500a3 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -35,6 +35,7 @@ namespace FreeSql.Internal.CommonProvider public Action> _batchProgress; public DbTransaction _transaction; public DbConnection _connection; + public Action _interceptSql; public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { @@ -766,6 +767,7 @@ namespace FreeSql.Internal.CommonProvider sb.Append(" AND ").Append(versionCondi); } + _interceptSql?.Invoke(sb); return sb.ToString(); } } From e092d10feeb620b0ecbd22eb89bc5da778638e16 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 4 Aug 2020 21:55:52 +0800 Subject: [PATCH 0797/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E6=96=B0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20BeginEdit=20bug=EF=BC=9B#397?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetSync.cs | 2 +- .../FreeSql.Tests.DbContext/RepositoryTests.cs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index a6dddb08..2377a59c 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -545,7 +545,7 @@ namespace FreeSql /// public void BeginEdit(List data) { - if (data == null || data.Any() == false) return; + if (data == null) return; if (_table.Primarys.Any() == false) throw new Exception($"不可进行编辑,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data.First())}"); _statesEditing.Clear(); _dataEditing = data; diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index a65081bb..0e65d5a9 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -552,6 +552,23 @@ namespace FreeSql.Tests cts.RemoveAt(1); Assert.Equal(3, repo.EndEdit()); + + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + repo = g.sqlite.GetRepository(); + cts = repo.Select.ToList(); + repo.BeginEdit(cts); + + cts.AddRange(new[] { + new BeginEdit01 { Name = "1" }, + new BeginEdit01 { Name = "1_1" }, + new BeginEdit01 { Name = "1_2" }, + new BeginEdit01 { Name = "1_3" }, + new BeginEdit01 { Name = "2" }, + new BeginEdit01 { Name = "2_1" }, + new BeginEdit01 { Name = "2_2" } + }); + + Assert.Equal(7, repo.EndEdit()); } class BeginEdit01 { From db42c5cd9dfdc215b21c1b363823027337fcc05c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 4 Aug 2020 21:59:22 +0800 Subject: [PATCH 0798/1029] 1.8.0-preview0806 #397 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 65d079c4..8636e280 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 15e9ce0d..3b39b712 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e11401f7..c4dffbab 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index c3675937..9bb39d42 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 07689bc9..b0ff6151 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0805 + 1.8.0-preview0806 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index bbcfee13..99193ac0 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4356ef7f..a9047c72 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d61f6f2f..e54cbf74 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,6 +125,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -515,5 +522,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 46d45a32..9a9c89da 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0a3e515b..7516ac4d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 2c47cf7f..c7ea7052 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 1ccf5644..695b2db1 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3b56d9bf..5dadd6e3 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0299f9bd..90ef0ab4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 11becb77..1fdf1025 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7c2e0d45..590af991 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 92aeb904..e1661462 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index c7772eb2..343c867a 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e6c86e49..446672d0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index a46792b6..e02212ed 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c39aecce..dd808462 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0805 + 1.8.0-preview0806 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From dcb4fef9e228921fea4068a6a7682957dd3fddf1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 5 Aug 2020 09:41:25 +0800 Subject: [PATCH 0799/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IInsert/IUpd?= =?UTF-8?q?ate=20BatchProgress=20=E5=BC=82=E6=AD=A5=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/CommonProvider/InsertProviderAsync.cs | 13 +++++++++++-- .../Internal/CommonProvider/UpdateProviderAsync.cs | 8 +++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index ddd24bf9..d738874a 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -27,6 +27,7 @@ namespace FreeSql.Internal.CommonProvider } if (ss.Length == 1) { + _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = await this.RawExecuteAffrowsAsync(); ClearData(); return ret; @@ -43,7 +44,8 @@ namespace FreeSql.Internal.CommonProvider { for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; + _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret += await this.RawExecuteAffrowsAsync(); } } @@ -59,6 +61,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret += await this.RawExecuteAffrowsAsync(); } _transaction.Commit(); @@ -99,6 +102,7 @@ namespace FreeSql.Internal.CommonProvider } if (ss.Length == 1) { + _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = await this.RawExecuteIdentityAsync(); ClearData(); return ret; @@ -116,6 +120,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); else ret = await this.RawExecuteIdentityAsync(); } @@ -132,6 +137,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); else ret = await this.RawExecuteIdentityAsync(); } @@ -173,6 +179,7 @@ namespace FreeSql.Internal.CommonProvider } if (ss.Length == 1) { + _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = await this.RawExecuteInsertedAsync(); ClearData(); return ret; @@ -189,7 +196,8 @@ namespace FreeSql.Internal.CommonProvider { for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; + _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret.AddRange(await this.RawExecuteInsertedAsync()); } } @@ -205,6 +213,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret.AddRange(await this.RawExecuteInsertedAsync()); } _transaction.Commit(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index 87ca9d41..2e85688f 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -23,6 +23,7 @@ namespace FreeSql.Internal.CommonProvider var ret = 0; if (ss.Length <= 1) { + if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = await this.RawExecuteAffrowsAsync(); ClearData(); return ret; @@ -40,6 +41,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret += await this.RawExecuteAffrowsAsync(); } } @@ -55,6 +57,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret += await this.RawExecuteAffrowsAsync(); } _transaction.Commit(); @@ -89,6 +92,7 @@ namespace FreeSql.Internal.CommonProvider var ret = new List(); if (ss.Length <= 1) { + if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); ret = await this.RawExecuteUpdatedAsync(); ClearData(); return ret; @@ -105,7 +109,8 @@ namespace FreeSql.Internal.CommonProvider { for (var a = 0; a < ss.Length; a++) { - _source = ss[a]; + _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret.AddRange(await this.RawExecuteUpdatedAsync()); } } @@ -121,6 +126,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < ss.Length; a++) { _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); ret.AddRange(await this.RawExecuteUpdatedAsync()); } _transaction.Commit(); From dfac9434959993806afdecbd93bef925a443cba3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 5 Aug 2020 13:43:49 +0800 Subject: [PATCH 0800/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20DbContext/Un?= =?UTF-8?q?itOfWork=20EntityChange=20=E6=9B=B4=E6=96=B0=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E4=B9=8B=E5=89=8D=E7=9A=84=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContext.cs | 4 ++++ FreeSql.DbContext/DbSet/DbSetAsync.cs | 11 ++++++----- FreeSql.DbContext/DbSet/DbSetSync.cs | 12 +++++++----- FreeSql.DbContext/FreeSql.DbContext.xml | 5 +++++ FreeSql.DbContext/readme.md | 2 +- FreeSql.Repository/readme.md | 2 +- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index be8eb704..dedde15f 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -243,6 +243,10 @@ namespace FreeSql public class ChangeInfo { public object Object { get; set; } + /// + /// Type = Update 的时候,获取更新之前的对象 + /// + public object BeforeObject { get; set; } public EntityChangeType Type { get; set; } } /// diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index aefaa719..0c602322 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -363,15 +363,16 @@ namespace FreeSql if (data?.Count > 0) { - if (cuig.Length == _table.Columns.Count) return ups.Length == data.Count ? -998 : -997; - var updateSource = data.Select(a => a.Value).ToArray(); - var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); - + var update = this.OrmUpdate(null).SetSource(data.Select(a => a.Value)).IgnoreColumns(cuig); var affrows = await update.ExecuteAffrowsAsync(); - _db._entityChangeReport.AddRange(updateSource.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Update })); + _db._entityChangeReport.AddRange(data.Select(a => new DbContext.EntityChangeReport.ChangeInfo { + Object = a.Value, + BeforeObject = _states.TryGetValue(a.Key, out var beforeVal) ? beforeVal.Value : null, + Type = DbContext.EntityChangeType.Update + })); foreach (var newval in data) { diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 2377a59c..dd260438 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -399,15 +399,17 @@ namespace FreeSql if (data?.Count > 0) { - if (cuig.Length == _table.Columns.Count) return ups.Length == data.Count ? -998 : -997; - var updateSource = data.Select(a => a.Value).ToArray(); - var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); - + var update = this.OrmUpdate(null).SetSource(data.Select(a => a.Value)).IgnoreColumns(cuig); var affrows = update.ExecuteAffrows(); - _db._entityChangeReport.AddRange(updateSource.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Update })); + _db._entityChangeReport.AddRange(data.Select(a => new DbContext.EntityChangeReport.ChangeInfo + { + Object = a.Value, + BeforeObject = _states.TryGetValue(a.Key, out var beforeVal) ? beforeVal.Value : null, + Type = DbContext.EntityChangeType.Update + })); foreach (var newval in data) { diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index e54cbf74..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -57,6 +57,11 @@ + + + Type = Update 的时候,获取更新之前的对象 + + 实体变化记录 diff --git a/FreeSql.DbContext/readme.md b/FreeSql.DbContext/readme.md index ac006f8d..1540ea3b 100644 --- a/FreeSql.DbContext/readme.md +++ b/FreeSql.DbContext/readme.md @@ -191,7 +191,7 @@ uow.OnEntityChange = report => { 参数 report 是一个 List 集合,集合元素的类型定义如下: ```csharp -public class EntityChangeInfo +public class ChangeInfo { public object Object { get; set; } public EntityChangeType Type { get; set; } diff --git a/FreeSql.Repository/readme.md b/FreeSql.Repository/readme.md index 4c58c538..70620dec 100644 --- a/FreeSql.Repository/readme.md +++ b/FreeSql.Repository/readme.md @@ -213,7 +213,7 @@ uow.OnEntityChange = report => { 参数 report 是一个 List 集合,集合元素的类型定义如下: ```csharp -public class EntityChangeInfo +public class ChangeInfo { public object Object { get; set; } public EntityChangeType Type { get; set; } From 7efe02f69cc0796478674c9b83250c607b763d78 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 7 Aug 2020 00:00:39 +0800 Subject: [PATCH 0801/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20GroupBy=20To?= =?UTF-8?q?List=20=E4=B8=AD=E5=8F=AF=E4=BB=A5=E7=9B=B4=E6=8E=A5=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20a.Key=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 2 +- .../Dameng/Curd/DamengSelectTest.cs | 2 +- .../Default/Curd/OdbcSelectTest.cs | 2 +- .../KingbaseES/Curd/KingbaseESSelectTest.cs | 2 +- .../MySql/Curd/MySqlSelectTest.cs | 2 +- .../Oracle/Curd/OracleSelectTest.cs | 2 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 2 +- .../Dameng/Curd/DamengSelectTest.cs | 2 +- .../MsAccess/Curd/MsAccessSelectTest.cs | 2 +- .../MySql/Curd/MySqlSelectTest.cs | 2 +- .../Oracle/Curd/OracleSelectTest.cs | 2 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 2 +- .../ShenTong/Curd/ShenTongSelectTest.cs | 2 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 2 +- .../Sqlite/Curd/SqliteSelectTest.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 27 ++++++ FreeSql/Internal/CommonExpression.cs | 82 ++++++++++--------- .../SelectProvider/SelectGroupingProvider.cs | 14 ++-- .../Internal/Model/ReadAnonymousTypeInfo.cs | 14 ++++ 21 files changed, 109 insertions(+), 62 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index c9d9dc32..3ab5e820 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -866,7 +866,7 @@ namespace FreeSql.Tests.MySqlConnector { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index a50acd5b..7d20cdcb 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -793,7 +793,7 @@ namespace FreeSql.Tests.Odbc.Dameng { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 59c91446..1e44d9f8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -784,7 +784,7 @@ namespace FreeSql.Tests.Odbc.Default { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs index 6abeb543..5839a06f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs @@ -758,7 +758,7 @@ namespace FreeSql.Tests.Odbc.KingbaseES { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index d4a1cc95..b5752d54 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -877,7 +877,7 @@ namespace FreeSql.Tests.Odbc.MySql { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 5e18bcfc..e7c817c8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -794,7 +794,7 @@ namespace FreeSql.Tests.Odbc.Oracle { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index bccdf194..cd197462 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -854,7 +854,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index dcfcc65d..7d4f9edd 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -749,7 +749,7 @@ namespace FreeSql.Tests.Odbc.SqlServer { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index 441fc1f9..5a824785 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -793,7 +793,7 @@ namespace FreeSql.Tests.Dameng { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index 24c806a0..f1b932d9 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -785,7 +785,7 @@ namespace FreeSql.Tests.MsAccess { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 92eade33..64950b72 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -913,7 +913,7 @@ namespace FreeSql.Tests.MySql { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 4ec7bdc4..4b478551 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -794,7 +794,7 @@ namespace FreeSql.Tests.Oracle { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 7cf806bd..472df22f 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -871,7 +871,7 @@ namespace FreeSql.Tests.PostgreSQL { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs index 07176067..39a32ff7 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs @@ -871,7 +871,7 @@ namespace FreeSql.Tests.ShenTong { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 429b64d9..03e49134 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -805,7 +805,7 @@ namespace FreeSql.Tests.SqlServer { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index fe68188f..b13c6c65 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -759,7 +759,7 @@ namespace FreeSql.Tests.Sqlite { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid) }); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 48baf05b..81dd4ac7 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -996,7 +996,7 @@ namespace FreeSql.Tests { b.Key.Title, b.Key.yyyy, - + b.Key, cou = b.Count(), sum = b.Sum(b.Key.yyyy), sum2 = b.Sum(b.Value.TypeGuid) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 1f93eca1..167fda11 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -179,6 +179,17 @@ namespace FreeSql.Tests var aff2 = g.sqlite.Delete(10086).ExecuteAffrows(); Assert.Equal(aff1, aff2); + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + g.sqlserver.Insert(new[] { new Edi { Id = 1 }, new Edi { Id = 2 }, new Edi { Id = 3 }, new Edi { Id = 4 }, new Edi { Id = 5 } }).ExecuteAffrows(); + g.sqlserver.Insert(new[] { + new EdiItem { Id = 1, EdiId = 1 }, new EdiItem { Id = 2, EdiId = 1 }, new EdiItem { Id = 3, EdiId = 1 } , + new EdiItem { Id = 4, EdiId = 2 }, new EdiItem { Id = 5, EdiId = 2 }, + new EdiItem { Id = 6, EdiId = 3 }, new EdiItem { Id = 7, EdiId = 3 }, + new EdiItem { Id = 8, EdiId = 4 }, new EdiItem { Id = 9, EdiId = 4 }, + new EdiItem { Id = 10, EdiId = 5 }, new EdiItem { Id = 11, EdiId = 5 }, + }).ExecuteAffrows(); + var testStringFormat = g.sqlite.Select().First(a => new { str = $"x{a.Id}_{DateTime.Now.ToString("yyyyMM")}z", @@ -265,6 +276,22 @@ namespace FreeSql.Tests over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue(), }); + var sqlextCaseGroupBy1 = g.sqlserver.Select() + .InnerJoin((a, b) => b.Id == a.Id) + .GroupBy((a, b) => new { aid = a.Id, bid = b.Id }) + .ToDictionary(a => new + { + sum = a.Sum(a.Value.Item2.EdiId) + }); + + var sqlextCaseGroupBy2 = g.sqlserver.Select() + .InnerJoin((a, b) => b.Id == a.Id) + .GroupBy((a, b) => new { aid = a.Id, bid = b.Id }) + .ToList(a => new + { + a.Key, sum = a.Sum(a.Value.Item2.EdiId) + }); + var sqlextOver = g.sqlserver.Select() .InnerJoin((a, b) => b.Id == a.Id) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 1050d677..8c2132ef 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -28,13 +28,13 @@ namespace FreeSql.Internal } internal const int ReadAnonymousFieldAsCsName = -53129; - public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression, bool isAllDtoMap) + public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, SelectGroupingProvider grouping, List whereCascadeExpression, bool isAllDtoMap) { - Func getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; + Func getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; switch (exp.NodeType) { - case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); - case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); + case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, grouping, whereCascadeExpression, isAllDtoMap); + case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, grouping, whereCascadeExpression, isAllDtoMap); case ExpressionType.Negate: case ExpressionType.NegateChecked: parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; @@ -43,7 +43,7 @@ namespace FreeSql.Internal else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; - case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); + case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, grouping, whereCascadeExpression, isAllDtoMap); case ExpressionType.Constant: var constExp = exp as ConstantExpression; //处理自定义SQL语句,如: ToList(new { @@ -93,7 +93,7 @@ namespace FreeSql.Internal { //加载表所有字段 var map = new List(); - ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString); + ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, grouping); var tb = parent.Table = map.First().Table.Table; parent.CsType = tb.Type; parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst(); @@ -115,6 +115,12 @@ namespace FreeSql.Internal } else { + if (grouping != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) + { + field.Append(grouping._field); + grouping._map.CopyTo(parent); + return false; + } parent.CsType = exp.Type; parent.DbField = ExpressionLambdaToSql(exp, getTSC()); field.Append(", ").Append(parent.DbField); @@ -141,7 +147,7 @@ namespace FreeSql.Internal MapType = initExp.NewExpression.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], getSelectGroupingMapString, whereCascadeExpression, false); + ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], grouping, whereCascadeExpression, false); } } else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) @@ -164,7 +170,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), grouping, whereCascadeExpression, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -190,7 +196,7 @@ namespace FreeSql.Internal MapType = initAssignExp.Expression.Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString, whereCascadeExpression, false); + ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, grouping, whereCascadeExpression, false); } } if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); @@ -223,7 +229,7 @@ namespace FreeSql.Internal MapType = newExp.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString, whereCascadeExpression, false); + ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], grouping, whereCascadeExpression, false); } } else @@ -247,7 +253,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), grouping, whereCascadeExpression, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -339,32 +345,32 @@ namespace FreeSql.Internal return null; } - public string ExpressionSelectColumn_MemberAccess(List _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, Func getSelectGroupingMapString) + public string ExpressionSelectColumn_MemberAccess(List _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, SelectGroupingProvider grouping) { - return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns }); + return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, grouping = grouping, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns }); } - public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List _tables, Expression exp, bool isQuoteName, Func getSelectGroupingMapString) + public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List _tables, Expression exp, bool isQuoteName, SelectGroupingProvider grouping) { switch (exp?.NodeType) { - case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); - case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, getSelectGroupingMapString); - case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); - case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString) }; + case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, grouping); + case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, grouping); + case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, grouping); + case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, grouping) }; case ExpressionType.Call: - case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries); + case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, grouping).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries); case ExpressionType.New: var newExp = exp as NewExpression; if (newExp == null) break; var newExpMembers = new string[newExp.Members.Count]; - for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, getSelectGroupingMapString); + for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, grouping); return newExpMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); case ExpressionType.NewArrayInit: var newArr = exp as NewArrayExpression; if (newArr == null) break; var newArrMembers = new List(); - foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, getSelectGroupingMapString)); + foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, grouping)); return newArrMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); default: throw new ArgumentException($"无法解析表达式:{exp}"); } @@ -389,22 +395,22 @@ namespace FreeSql.Internal { ExpressionType.Equal, "=" }, }; - public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString, List dbParams) + public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, SelectGroupingProvider groupingProvider, List dbParams) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = dbParams }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = dbParams }); return GetBoolString(exp, sql); } - public string ExpressionWhereLambda(List _tables, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression, List dbParams) + public string ExpressionWhereLambda(List _tables, Expression exp, SelectGroupingProvider groupingProvider, List whereCascadeExpression, List dbParams) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = dbParams }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = dbParams }); return GetBoolString(exp, sql); } static ConcurrentDictionary dicRegexAlias = new ConcurrentDictionary(); - public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString, List whereCascadeExpression) + public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, SelectGroupingProvider groupingProvider, List whereCascadeExpression) { var tbidx = _tables.Count; - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); sql = GetBoolString(exp, sql); if (_tables.Count > tbidx) @@ -813,7 +819,7 @@ namespace FreeSql.Internal var testExecuteExp = asSelectParentExp; if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联 testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key); - var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List(), tsc.getSelectGroupingMapString, SelectTableInfoType.LeftJoin); + var tsc2 = tsc.CloneSetselectColumnMapAndgroupingAndtbtype(new List(), tsc.grouping, SelectTableInfoType.LeftJoin); tsc2.isDisableDiyParse = true; tsc2.style = ExpressionStyle.AsSelect; asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2); @@ -1167,11 +1173,11 @@ namespace FreeSql.Internal return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); } if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); - if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) + if (tsc.grouping != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { - if (tsc.getSelectGroupingMapString != null) + if (tsc.grouping != null) { - var expText = tsc.getSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray()); + var expText = tsc.grouping.GetSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray()); if (string.IsNullOrEmpty(expText) == false) return expText; } } @@ -1281,9 +1287,9 @@ namespace FreeSql.Internal if (find.Type == SelectTableInfoType.InnerJoin || find.Type == SelectTableInfoType.LeftJoin || find.Type == SelectTableInfoType.RightJoin) - find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type)); + find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetselectColumnMapAndgroupingAndtbtype(null, null, find.Type)); else - find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type)); + find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetselectColumnMapAndgroupingAndtbtype(null, null, find.Type)); } } } @@ -1429,7 +1435,7 @@ namespace FreeSql.Internal { public List _tables { get; set; } public List _selectColumnMap { get; set; } - public Func getSelectGroupingMapString { get; set; } + public SelectGroupingProvider grouping { get; set; } public SelectTableInfoType tbtype { get; set; } public bool isQuoteName { get; set; } public bool isDisableDiyParse { get; set; } @@ -1469,13 +1475,13 @@ namespace FreeSql.Internal return old; } - public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List v1, Func v2, SelectTableInfoType v3) + public ExpTSC CloneSetselectColumnMapAndgroupingAndtbtype(List v1, SelectGroupingProvider v2, SelectTableInfoType v3) { return new ExpTSC { _tables = this._tables, _selectColumnMap = v1, - getSelectGroupingMapString = v2, + grouping = v2, tbtype = v3, isQuoteName = this.isQuoteName, isDisableDiyParse = this.isDisableDiyParse, @@ -1495,7 +1501,7 @@ namespace FreeSql.Internal { _tables = this._tables, _selectColumnMap = this._selectColumnMap, - getSelectGroupingMapString = this.getSelectGroupingMapString, + grouping = this.grouping, tbtype = this.tbtype, isQuoteName = this.isQuoteName, isDisableDiyParse = true, @@ -1537,7 +1543,7 @@ namespace FreeSql.Internal ); var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = isMultitb ? new List(new[] { tb }) : null, - _selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + _selectColumnMap = null, grouping = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); whereSql = GetBoolString(expExp.Body, whereSql); if (isEmpty == false) sb.Append(" AND "); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 85f208d0..559befe1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -30,7 +30,7 @@ namespace FreeSql.Internal.CommonProvider _tables = tables; } - public string getSelectGroupingMapString(Expression[] members) + public string GetSelectGroupingMapString(Expression[] members) { if (members.Any() == false) return _map.DbField; var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name; @@ -90,13 +90,13 @@ namespace FreeSql.Internal.CommonProvider public void InternalHaving(Expression exp) { - var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null, null); + var sql = _comonExp.ExpressionWhereLambda(null, exp, this, null, null); var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { sql, null }); } public void InternalOrderBy(Expression exp, bool isDescending) { - var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null, null); + var sql = _comonExp.ExpressionWhereLambda(null, exp, this, null, null); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { isDescending ? $"{sql} DESC" : sql, null }); } @@ -106,7 +106,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, this, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; var method = _select.GetType().GetMethod(isAsync ? "ToListMapReaderAsync" : "ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(elementType); @@ -118,7 +118,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, getSelectGroupingMapString, null, false); + _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, this, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; var method = _select.GetType().GetMethod("ToListMapReaderPrivate", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(elementType); @@ -132,7 +132,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, this, null, false); var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; } @@ -210,7 +210,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, getSelectGroupingMapString, null, false); + _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, this, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement); var method = _select.GetType().GetMethod("ToListMapReaderPrivateAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TElement)); diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index f7018bc7..c782cf5b 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -17,6 +17,20 @@ namespace FreeSql.Internal.Model public TableInfo Table { get; set; } public bool IsEntity { get; set; } public bool IsDefaultCtor { get; set; } + + public void CopyTo(ReadAnonymousTypeInfo target) + { + target.Property = Property; + target.CsName = CsName; + target.CsType = CsType; + target.MapType = MapType; + target.DbField = DbField; + target.Consturctor = Consturctor; + target.Childs = Childs; + target.Table = Table; + target.IsEntity = IsEntity; + target.IsDefaultCtor = IsDefaultCtor; + } } public class ReadAnonymousTypeAfInfo { From 25e73117b124e93e6a5757a95ca96aadb5ab55fb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 7 Aug 2020 01:36:11 +0800 Subject: [PATCH 0802/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20lambda=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=20a=20=3D=3D=20null=20=3F=201=20:=200=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=B1=BB=E4=BC=BC=E8=BF=99=E6=A0=B7=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E5=88=A4=E6=96=AD=E5=AE=9E=E4=BD=93=E7=9A=84=E6=83=85?= =?UTF-8?q?=E5=86=B5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KingbaseES/Curd/KingbaseESUpdateTest.cs | 4 +- .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 4 +- .../ShenTong/Curd/ShenTongUpdateTest.cs | 60 +++++++++---------- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 13 +++- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 16 +++-- FreeSql/Internal/CommonExpression.cs | 7 +++ .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 9 ++- .../KingbaseES/OdbcKingbaseESUtils.cs | 2 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 9 ++- .../Curd/PostgreSQLUpdate.cs | 9 ++- .../Curd/ShenTongUpdate.cs | 12 +++- 11 files changed, 94 insertions(+), 51 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs index 383406e0..d1c5cd91 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs @@ -41,10 +41,10 @@ namespace FreeSql.Tests.Odbc.KingbaseES items[0].Clicks = null; sql = update.SetSource(items).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END::int4, \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::varchar, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN '0001-01-01 00:00:00.000000' WHEN 2 THEN '0001-01-01 00:00:00.000000' WHEN 3 THEN '0001-01-01 00:00:00.000000' WHEN 4 THEN '0001-01-01 00:00:00.000000' WHEN 5 THEN '0001-01-01 00:00:00.000000' WHEN 6 THEN '0001-01-01 00:00:00.000000' WHEN 7 THEN '0001-01-01 00:00:00.000000' WHEN 8 THEN '0001-01-01 00:00:00.000000' WHEN 9 THEN '0001-01-01 00:00:00.000000' WHEN 10 THEN '0001-01-01 00:00:00.000000' END::timestamp WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END::int4, \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::text, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN '0001-01-01 00:00:00.000000' WHEN 2 THEN '0001-01-01 00:00:00.000000' WHEN 3 THEN '0001-01-01 00:00:00.000000' WHEN 4 THEN '0001-01-01 00:00:00.000000' WHEN 5 THEN '0001-01-01 00:00:00.000000' WHEN 6 THEN '0001-01-01 00:00:00.000000' WHEN 7 THEN '0001-01-01 00:00:00.000000' WHEN 8 THEN '0001-01-01 00:00:00.000000' WHEN 9 THEN '0001-01-01 00:00:00.000000' WHEN 10 THEN '0001-01-01 00:00:00.000000' END::timestamp WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::varchar WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::text WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = '2020-01-01 00:00:00.000000' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index a474aea2..165f4b1b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -42,10 +42,10 @@ namespace FreeSql.Tests.Odbc.PostgreSQL items[0].Clicks = null; sql = update.SetSource(items).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = CASE \"id\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END::int4, \"title\" = CASE \"id\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::varchar, \"createtime\" = CASE \"id\" WHEN 1 THEN '0001-01-01 00:00:00.000000' WHEN 2 THEN '0001-01-01 00:00:00.000000' WHEN 3 THEN '0001-01-01 00:00:00.000000' WHEN 4 THEN '0001-01-01 00:00:00.000000' WHEN 5 THEN '0001-01-01 00:00:00.000000' WHEN 6 THEN '0001-01-01 00:00:00.000000' WHEN 7 THEN '0001-01-01 00:00:00.000000' WHEN 8 THEN '0001-01-01 00:00:00.000000' WHEN 9 THEN '0001-01-01 00:00:00.000000' WHEN 10 THEN '0001-01-01 00:00:00.000000' END::timestamp WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = CASE \"id\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END::int4, \"title\" = CASE \"id\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::text, \"createtime\" = CASE \"id\" WHEN 1 THEN '0001-01-01 00:00:00.000000' WHEN 2 THEN '0001-01-01 00:00:00.000000' WHEN 3 THEN '0001-01-01 00:00:00.000000' WHEN 4 THEN '0001-01-01 00:00:00.000000' WHEN 5 THEN '0001-01-01 00:00:00.000000' WHEN 6 THEN '0001-01-01 00:00:00.000000' WHEN 7 THEN '0001-01-01 00:00:00.000000' WHEN 8 THEN '0001-01-01 00:00:00.000000' WHEN 9 THEN '0001-01-01 00:00:00.000000' WHEN 10 THEN '0001-01-01 00:00:00.000000' END::timestamp WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = CASE \"id\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::varchar WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = CASE \"id\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::text WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"tb_topic\" SET \"createtime\" = '2020-01-01 00:00:00.000000' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs index 549114dc..0662a1fd 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs @@ -10,7 +10,7 @@ namespace FreeSql.Tests.ShenTong { IUpdate update => g.shentong.Update(); - [Table(Name = "tb_topic")] + [Table(Name = "tb_topic_insert")] class Topic { [Column(IsIdentity = true, IsPrimary = true)] @@ -25,30 +25,30 @@ namespace FreeSql.Tests.ShenTong public void Dywhere() { Assert.Null(g.shentong.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } [Fact] public void SetSource() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1, \"CREATETIME\" = @p_2 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1, \"CREATETIME\" = @p_2 WHERE (\"ID\" = 1)", sql); var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); items[0].Clicks = null; sql = update.SetSource(items).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = @p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CREATETIME\" = @p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); sql = g.shentong.Update().SetSource(new[] { new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, @@ -81,85 +81,85 @@ namespace FreeSql.Tests.ShenTong public void IgnoreColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); } [Fact] public void UpdateColumns() { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); } [Fact] public void Set() { var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = @p_0, \"CREATETIME\" = @p_1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0, \"CREATETIME\" = @p_1 WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); int incrv = 10; sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = \"CLICKS\" * 10 / 1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = \"CLICKS\" * 10 / 1 WHERE (\"ID\" = 1)", sql); var dt2000 = DateTime.Parse("2000-01-01"); sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > '2000-01-01 00:00:00.000000' then 1 else 2 end WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = case when \"CREATETIME\" > '2000-01-01 00:00:00.000000' then 1 else 2 end WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); } [Fact] public void SetRaw() { var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + @incrClick WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET clicks = clicks + @incrClick WHERE (\"ID\" = 1)", sql); } [Fact] public void SetDto() { var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1 WHERE (\"ID\" = 1)", sql); sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1 WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1 WHERE (\"ID\" = 1)", sql); sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); } [Fact] public void Where() { var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = @id)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='newtitle' WHERE (id = @id)", sql); var item = new Topic { Id = 1, Title = "newtitle" }; sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); var items = new List(); for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); } [Fact] public void ExecuteAffrows() diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index b93400ef..a5b2757e 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -147,6 +147,8 @@ namespace FreeSql.Tests public class LinUser { public long id { get; set; } + public string name { get; set; } + public string nick { get; set; } } public class Comment @@ -530,9 +532,14 @@ namespace FreeSql.Tests var comments2 = g.mysql.Select() - .Include(r => r.UserInfo) - .From((z, b) => z.LeftJoin(u => u.Id == b.SubjectId)) - .ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo }); + .Include(r => r.UserInfo) + .From((z, b) => z.LeftJoin(u => u.Id == b.SubjectId)) + .ToList((a, b) => new { comment = a, b.SubjectId, user = a.UserInfo, + testb1 = a.UserInfo == null ? 1 : 0, + testb2 = a.UserInfo != null ? 2 : 0, + testb4 = b == null ? 3 : 0, + testb5 = b != null ? 4 : 0, + }); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); g.sqlite.Delete().Where("1=1").ExecuteAffrows(); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 167fda11..ba54689f 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -227,7 +227,9 @@ namespace FreeSql.Tests .When(a.Id == 4, 13) .When(a.Id == 5, SqlExt.Case().When(b.Id == 1, 10000).Else(999).End()) .End(), - groupct1 = SqlExt.GroupConcat(a.Id).Distinct().OrderBy(b.EdiId).Separator("_").ToValue() + groupct1 = SqlExt.GroupConcat(a.Id).Distinct().OrderBy(b.EdiId).Separator("_").ToValue(), + testb1 = b == null ? 1 : 0, + testb2 = b != null ? 1 : 0, }); var sqlextGroupConcatToList = g.mysql.Select() .InnerJoin((a, b) => b.Id == a.Id) @@ -242,7 +244,9 @@ namespace FreeSql.Tests .When(a.Id == 4, 13) .When(a.Id == 5, SqlExt.Case().When(b.Id == 1, 10000).Else(999).End()) .End(), - groupct1 = SqlExt.GroupConcat(a.Id).Distinct().OrderBy(b.EdiId).Separator("_").ToValue() + groupct1 = SqlExt.GroupConcat(a.Id).Distinct().OrderBy(b.EdiId).Separator("_").ToValue(), + testb1 = b == null ? 1 : 0, + testb2 = b != null ? 1 : 0, }); var sqlextCase = g.sqlserver.Select() @@ -281,7 +285,9 @@ namespace FreeSql.Tests .GroupBy((a, b) => new { aid = a.Id, bid = b.Id }) .ToDictionary(a => new { - sum = a.Sum(a.Value.Item2.EdiId) + sum = a.Sum(a.Value.Item2.EdiId), + testb1 = a.Value.Item2 == null ? 1 : 0, + testb2 = a.Value.Item2 != null ? 1 : 0, }); var sqlextCaseGroupBy2 = g.sqlserver.Select() @@ -289,7 +295,9 @@ namespace FreeSql.Tests .GroupBy((a, b) => new { aid = a.Id, bid = b.Id }) .ToList(a => new { - a.Key, sum = a.Sum(a.Value.Item2.EdiId) + a.Key, sum = a.Sum(a.Value.Item2.EdiId), + testb1 = a.Value.Item2 == null ? 1 : 0, + testb2 = a.Value.Item2 != null ? 1 : 0, }); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 8c2132ef..85cdb639 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -496,6 +496,13 @@ namespace FreeSql.Internal return ExpressionLambdaToSql(Expression.Call(leftExp, MethodDateTimeSubtractTimeSpan, rightExp), tsc); } return $"({ExpressionLambdaToSql(leftExp, tsc)} {oper} {ExpressionLambdaToSql(rightExp, tsc)})"; + case "=": + case "<>": + var exptb = _common.GetTableByEntity(leftExp.Type); + if (exptb != null) leftExp = Expression.MakeMemberAccess(leftExp, exptb.Properties[(exptb.Primarys.FirstOrDefault() ?? exptb.Columns.FirstOrDefault().Value).CsName]); + exptb = _common.GetTableByEntity(leftExp.Type); + if (exptb?.Primarys.Any() == true) rightExp = Expression.MakeMemberAccess(rightExp, exptb.Properties[(exptb.Primarys.FirstOrDefault() ?? exptb.Columns.FirstOrDefault().Value).CsName]); + break; } Type oldMapType = null; diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index a0e14d1a..b0eab467 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -83,7 +83,7 @@ namespace FreeSql.Odbc.KingbaseES { if (pkidx > 0) caseWhen.Append(" || '+' || "); if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::text"); ++pkidx; } caseWhen.Append(")"); @@ -101,7 +101,7 @@ namespace FreeSql.Odbc.KingbaseES foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::text"); ++pkidx; } sb.Append(")"); @@ -110,6 +110,11 @@ namespace FreeSql.Odbc.KingbaseES protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) { if (_noneParameter == false) return; + if (col.Attribute.MapType == typeof(string)) + { + sb.Append("::text"); + return; + } var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; if (dbtype == null) return; diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs index 9c8d470c..f46f3c13 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs @@ -114,7 +114,7 @@ namespace FreeSql.Odbc.KingbaseES public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); public override string QuoteParamterName(string name) => $"@{name.ToUpper()}"; public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; - public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs.Select((a, b) => b == 0 ? $"{a}::varchar" : a))}"; //First ::varchar + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs.Select((a, b) => b == 0 ? $"{a}::text" : a))}"; //First ::text public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; public override string Now => "current_timestamp"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 20d3d697..f4c2cbc2 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -83,7 +83,7 @@ namespace FreeSql.Odbc.PostgreSQL { if (pkidx > 0) caseWhen.Append(" || '+' || "); if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::text"); ++pkidx; } caseWhen.Append(")"); @@ -101,7 +101,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::text"); ++pkidx; } sb.Append(")"); @@ -110,6 +110,11 @@ namespace FreeSql.Odbc.PostgreSQL protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) { if (_noneParameter == false) return; + if (col.Attribute.MapType == typeof(string)) + { + sb.Append("::text"); + return; + } var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; if (dbtype == null) return; diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index fee9268a..cc74c1d1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -83,7 +83,7 @@ namespace FreeSql.PostgreSQL.Curd { if (pkidx > 0) caseWhen.Append(" || '+' || "); if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::text"); ++pkidx; } caseWhen.Append(")"); @@ -101,7 +101,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::text"); ++pkidx; } sb.Append(")"); @@ -110,6 +110,11 @@ namespace FreeSql.PostgreSQL.Curd protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) { if (_noneParameter == false) return; + if (col.Attribute.MapType == typeof(string)) + { + sb.Append("::text"); + return; + } var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; if (dbtype == null) return; diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index 9f6c08f5..97ce5c1f 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -1,4 +1,5 @@ -using FreeSql.Internal; +using FreeSql.DataAnnotations; +using FreeSql.Internal; using FreeSql.Internal.Model; using System; using System.Collections.Generic; @@ -83,7 +84,7 @@ namespace FreeSql.ShenTong.Curd { if (pkidx > 0) caseWhen.Append(" || '+' || "); if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); - caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::text"); ++pkidx; } caseWhen.Append(")"); @@ -101,7 +102,7 @@ namespace FreeSql.ShenTong.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar"); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::text"); ++pkidx; } sb.Append(")"); @@ -110,6 +111,11 @@ namespace FreeSql.ShenTong.Curd protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) { if (_noneParameter == false) return; + if (col.Attribute.MapType == typeof(string)) + { + sb.Append("::text"); + return; + } var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; if (dbtype == null) return; From 1a8c7ce86dba5f91129323da81891fa3c0ad5eb8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 8 Aug 2020 00:53:27 +0800 Subject: [PATCH 0803/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20SqlServer=20?= =?UTF-8?q?lambda=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=A0=91=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=AD=90=E6=9F=A5=E8=AF=A2=20ToList=20+=20string.Join()=20?= =?UTF-8?q?=E4=BA=A7=E7=94=9F=20=E7=B1=BB=E4=BC=BC=20group=5Fconcat=20?= =?UTF-8?q?=E7=9A=84=E6=95=88=E6=9E=9C=EF=BC=9B#405?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SqlServerExpression/StringTest.cs | 18 +++++++++++++++++ .../FreeSqlGlobalExpressionCallExtensions.cs | 12 +++++++++++ .../Extensions/LambadaExpressionExtensions.cs | 20 +++++++++++++++++++ .../SqlServerExpression.cs | 18 +++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index c261353e..b094b06c 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -66,6 +66,24 @@ namespace FreeSql.Tests.SqlServerExpression list.Add(select.Where(a => a.TitleVarchar == "aaa").ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)) + ","; + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index abbcb35e..b3785bbb 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -114,6 +114,18 @@ namespace FreeSql /// /// public static IGroupConcat GroupConcat(object column) => SqlExtExtensions.GroupConcat(column); + + /// + /// PostgreSQL string_agg(.., ..) + /// + /// + /// + /// + public static string StringAgg(object column, object delimiter) + { + expContext.Value.Result = $"string_agg({expContext.Value.ParsedContent["column"]}, {expContext.Value.ParsedContent["delimiter"]})"; + return ""; + } } [ExpressionCall] diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 000a6d72..203010a9 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -233,6 +233,26 @@ namespace System.Linq.Expressions test.Visit(exp); return test.Result; } + + public static bool IsStringJoin(this MethodCallExpression exp, out MethodCallExpression joinExpArgs1Out, out LambdaExpression joinExpArgs1Args0Out) + { + if (exp.Arguments.Count == 2 && + exp.Arguments[1].NodeType == ExpressionType.Call && + exp.Arguments[1].Type.FullName.StartsWith("System.Collections.Generic.List`1") && + exp.Arguments[1] is MethodCallExpression joinExpArgs1 && + joinExpArgs1.Method.Name == "ToList" && + joinExpArgs1.Arguments.Count == 1 && + joinExpArgs1.Arguments[0] is UnaryExpression joinExpArgs1Args0Tmp && + joinExpArgs1Args0Tmp.Operand is LambdaExpression joinExpArgs1Args0) + { + joinExpArgs1Out = joinExpArgs1; + joinExpArgs1Args0Out = joinExpArgs1Args0; + return true; + } + joinExpArgs1Out = null; + joinExpArgs1Args0Out = null; + return false; + } } internal class NewExpressionVisitor : ExpressionVisitor diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index e0a87762..f59a05f0 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -283,6 +283,24 @@ namespace FreeSql.SqlServer return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))", "''")}+{nchar}'"; }).ToArray(); return string.Format(expArgs0, expArgs); + case "Join": + if (exp.IsStringJoin(out var joinExpArgs1, out var joinExpArgs1Args0)) + { + var newToListArgs0 = Expression.Call(joinExpArgs1.Object, joinExpArgs1.Method, + Expression.Lambda( + Expression.Call( + typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }), + Expression.Convert(joinExpArgs1Args0.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + joinExpArgs1Args0.Parameters)); + var newToListSql = getExp(newToListArgs0); + if (string.IsNullOrEmpty(newToListSql) == false && newToListSql.StartsWith("(") && newToListSql.EndsWith(")")) + { + newToListSql = $"{newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH(''))"; + return newToListSql; + } + } + break; } } else From b3ec6cdf8d32c3bc760018481c8f76a5dbf08c4b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 8 Aug 2020 16:18:10 +0800 Subject: [PATCH 0804/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20lambda=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=A0=91=E8=A7=A3=E6=9E=90=E5=AD=90?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=20ToList=20+=20string.Join()=20=E4=BA=A7?= =?UTF-8?q?=E7=94=9F=20=E7=B1=BB=E4=BC=BC=20group=5Fconcat=20=E7=9A=84?= =?UTF-8?q?=E6=95=88=E6=9E=9C=EF=BC=88=E9=80=82=E9=85=8D=E4=BA=86=20sqlser?= =?UTF-8?q?ver/pgsql/oracle/mysql/sqlite/=E8=BE=BE=E6=A2=A6/=E9=87=91?= =?UTF-8?q?=E4=BB=93)=20#405=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnectorExpression/StringTest.cs | 30 ++++++++++++++++ .../Dameng/DamengExpression/StringTest.cs | 30 ++++++++++++++++ .../KingbaseESExpression/StringTest.cs | 30 ++++++++++++++++ .../MySql/MySqlExpression/StringTest.cs | 30 ++++++++++++++++ .../Oracle/OracleExpression/StringTest.cs | 30 ++++++++++++++++ .../PostgreSQLExpression/StringTest.cs | 30 ++++++++++++++++ .../SqlServerExpression/StringTest.cs | 30 ++++++++++++++++ .../Dameng/DamengExpression/StringTest.cs | 30 ++++++++++++++++ .../MySql/MySqlExpression/StringTest.cs | 30 ++++++++++++++++ .../Oracle/OracleExpression/StringTest.cs | 30 ++++++++++++++++ .../PostgreSQLExpression/StringTest.cs | 30 ++++++++++++++++ .../SqlServerExpression/StringTest.cs | 14 +++++++- .../Sqlite/SqliteExpression/StringTest.cs | 30 ++++++++++++++++ .../FreeSqlGlobalExpressionCallExtensions.cs | 36 +++++++++++++++++++ .../Extensions/LambadaExpressionExtensions.cs | 25 +++++++------ FreeSql/FreeSql.xml | 8 +++++ FreeSql/Internal/CommonExpression.cs | 4 +++ .../DamengExpression.cs | 14 ++++++++ .../FreeSql.Provider.MySql/MySqlExpression.cs | 14 ++++++++ .../Dameng/OdbcDamengExpression.cs | 14 ++++++++ .../KingbaseES/OdbcKingbaseESExpression.cs | 14 ++++++++ .../MySql/OdbcMySqlExpression.cs | 14 ++++++++ .../Oracle/OdbcOracleExpression.cs | 14 ++++++++ .../PostgreSQL/OdbcPostgreSQLExpression.cs | 14 ++++++++ .../SqlServer/OdbcSqlServerExpression.cs | 18 ++++++++++ .../OracleExpression.cs | 14 ++++++++ .../PostgreSQLExpression.cs | 14 ++++++++ .../ShenTongExpression.cs | 14 ++++++++ .../SqlServerExpression.cs | 12 +++---- .../SqliteExpression.cs | 14 ++++++++ 30 files changed, 614 insertions(+), 17 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 9ebf65b3..2b64b531 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -52,6 +52,36 @@ namespace FreeSql.Tests.MySqlConnectorExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs index 4dfa9e9d..a375a82a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.dameng; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs index faa481b1..adc32074 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.KingbaseESExpression list.Add(g.kingbaseES.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.kingbaseES; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs index 61b5db83..d5488cc4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,36 @@ namespace FreeSql.Tests.Odbc.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs index d5d4cdee..30346e3b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs index 4105eea9..f5073512 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs index 82a5d84d..48644371 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs @@ -51,6 +51,36 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs index 139555bc..49d61bd8 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.dameng; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index bafb962a..3a3ab212 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,36 @@ namespace FreeSql.Tests.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index aff45a18..c15b5cae 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index 4b0b9fea..341d8aa7 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index b094b06c..ad7714d9 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -73,9 +73,21 @@ namespace FreeSql.Tests.SqlServerExpression fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); - var val1 = string.Join(",", fsql.Select().ToList(a => a.name)) + ","; + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); } class StringJoin01 { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index 9bb2a1e7..e1c2e382 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.SqliteExpression list.Add(g.sqlite.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.sqlite; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + [Fact] public void First() { diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index b3785bbb..d8903744 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -269,5 +269,41 @@ namespace FreeSql } public interface IGroupConcat { } #endregion + + #region string.Join 反射处理,此块代卖用于反射,所以别修改定义 + public static string StringJoinSqliteGroupConcat(object column, object delimiter) + { + expContext.Result = $"group_concat({expContext.ParsedContent["column"]},{expContext.ParsedContent["delimiter"]})"; + return null; + } + public static string StringJoinPgsqlGroupConcat(object column, object delimiter) + { + expContext.Result = $"string_agg(({expContext.ParsedContent["column"]})::text,{expContext.ParsedContent["delimiter"]})"; + return null; + } + public static string StringJoinMySqlGroupConcat(object column, object delimiter) + { + expContext.Result = $"group_concat({expContext.ParsedContent["column"]} separator {expContext.ParsedContent["delimiter"]})"; + return null; + } + public static string StringJoinOracleGroupConcat(object column, object delimiter) + { + string orderby = null; + var subSelect = expContext._tsc?.subSelect001; + if (subSelect != null) + { + orderby = subSelect?._orderby?.Trim('\r', '\n'); + if (string.IsNullOrEmpty(orderby)) + { + var subSelectTb1 = subSelect._tables.FirstOrDefault(); + if (subSelectTb1 != null && subSelectTb1.Table.Primarys.Any() == true) + orderby = $"order by {string.Join(",", subSelectTb1.Table.Primarys.Select(a => $"{subSelectTb1.Alias}.{subSelect._commonUtils.QuoteSqlName(a.Attribute.Name)}"))}"; + } + } + if (string.IsNullOrEmpty(orderby)) orderby = "order by 1"; + expContext.Result = $"listagg(to_char({expContext.ParsedContent["column"]}),{expContext.ParsedContent["delimiter"]}) within group({orderby})"; + return null; + } + #endregion } } \ No newline at end of file diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 203010a9..3ed0f207 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -234,23 +234,28 @@ namespace System.Linq.Expressions return test.Result; } - public static bool IsStringJoin(this MethodCallExpression exp, out MethodCallExpression joinExpArgs1Out, out LambdaExpression joinExpArgs1Args0Out) + static ConcurrentDictionary> _dicTypeMethod = new ConcurrentDictionary>(); + public static bool IsStringJoin(this MethodCallExpression exp, out Expression tolistObjectExpOut, out MethodInfo toListMethodOut, out LambdaExpression toListArgs0Out) { if (exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.Call && exp.Arguments[1].Type.FullName.StartsWith("System.Collections.Generic.List`1") && - exp.Arguments[1] is MethodCallExpression joinExpArgs1 && - joinExpArgs1.Method.Name == "ToList" && - joinExpArgs1.Arguments.Count == 1 && - joinExpArgs1.Arguments[0] is UnaryExpression joinExpArgs1Args0Tmp && - joinExpArgs1Args0Tmp.Operand is LambdaExpression joinExpArgs1Args0) + exp.Arguments[1] is MethodCallExpression toListMethod && + toListMethod.Method.Name == "ToList" && + toListMethod.Arguments.Count == 1 && + toListMethod.Arguments[0] is UnaryExpression joinExpArgs1Args0Tmp && + joinExpArgs1Args0Tmp.Operand is LambdaExpression toListArgs0) { - joinExpArgs1Out = joinExpArgs1; - joinExpArgs1Args0Out = joinExpArgs1Args0; + tolistObjectExpOut = toListMethod.Object; + toListMethodOut = toListMethod.Type.GetGenericArguments().FirstOrDefault() == typeof(string) ? + toListMethod.Method : + toListMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(typeof(string)); + toListArgs0Out = toListArgs0; return true; } - joinExpArgs1Out = null; - joinExpArgs1Args0Out = null; + tolistObjectExpOut = null; + toListMethodOut = null; + toListArgs0Out = null; return false; } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index bde37cf0..ea460a59 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -794,6 +794,14 @@ + + + PostgreSQL string_agg(.., ..) + + + + + 使用连接串(推荐) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 85cdb639..01004c01 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1060,6 +1060,7 @@ namespace FreeSql.Internal case "Max": case "Avg": var tscClone1 = tsc.CloneDisableDiyParse(); + tscClone1.subSelect001 = fsql as Select0Provider; //#405 Oracle within group(order by ..) tscClone1.isDisableDiyParse = false; tscClone1._tables = fsqltables; var sqlSum = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone1)})" })?.ToString(); @@ -1070,6 +1071,7 @@ namespace FreeSql.Internal case "ToOne": case "First": var tscClone2 = tsc.CloneDisableDiyParse(); + tscClone2.subSelect001 = fsql as Select0Provider; //#405 Oracle within group(order by ..) tscClone2.isDisableDiyParse = false; tscClone2._tables = fsqltables; var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone2) })?.ToString(); @@ -1443,6 +1445,7 @@ namespace FreeSql.Internal public List _tables { get; set; } public List _selectColumnMap { get; set; } public SelectGroupingProvider grouping { get; set; } + public Select0Provider subSelect001 { get; set; } //#405 Oracle within group(order by ..) public SelectTableInfoType tbtype { get; set; } public bool isQuoteName { get; set; } public bool isDisableDiyParse { get; set; } @@ -1509,6 +1512,7 @@ namespace FreeSql.Internal _tables = this._tables, _selectColumnMap = this._selectColumnMap, grouping = this.grouping, + subSelect001 = this.subSelect001, tbtype = this.tbtype, isQuoteName = this.isQuoteName, isDisableDiyParse = true, diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index 669d2bc5..acc956e9 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -268,6 +268,20 @@ namespace FreeSql.Dameng //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 7968d10e..d54733b2 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -267,6 +267,20 @@ namespace FreeSql.MySql //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinMySqlGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index 439dbd20..f7a344e3 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -268,6 +268,20 @@ namespace FreeSql.Odbc.Dameng //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index 12be160a..f819d74e 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -337,6 +337,20 @@ namespace FreeSql.Odbc.KingbaseES return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'"; }).ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index af5ed688..0867c078 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -265,6 +265,20 @@ namespace FreeSql.Odbc.MySql //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinMySqlGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 21ac435c..7ee2af4a 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -268,6 +268,20 @@ namespace FreeSql.Odbc.Oracle //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index cf939b59..d4fc852d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -359,6 +359,20 @@ namespace FreeSql.Odbc.PostgreSQL return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'"; }).ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 76f2ae6d..65e0779d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -284,6 +284,24 @@ namespace FreeSql.Odbc.SqlServer return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))", "''")}+{nchar}'"; }).ToArray(); return string.Format(expArgs0, expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }), + Expression.Convert(exp.Arguments[0], typeof(object)), + Expression.Convert(toListArgs1.Body, typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + if (string.IsNullOrEmpty(newToListSql) == false && newToListSql.StartsWith("(") && newToListSql.EndsWith(")")) + { + newToListSql = $"stuff({newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH('')),1,len({getExp(exp.Arguments[0])}),'')"; + return newToListSql; + } + } + break; } } else diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 3daf210d..0d483ca3 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -268,6 +268,20 @@ namespace FreeSql.Oracle //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 99b46cb3..f584472c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -390,6 +390,20 @@ namespace FreeSql.PostgreSQL return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'"; }).ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index b8c3d179..aedaa4eb 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -315,6 +315,20 @@ namespace FreeSql.ShenTong //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": //未通用测试 #405 + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index f59a05f0..91ead6ed 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -284,19 +284,19 @@ namespace FreeSql.SqlServer }).ToArray(); return string.Format(expArgs0, expArgs); case "Join": - if (exp.IsStringJoin(out var joinExpArgs1, out var joinExpArgs1Args0)) + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) { - var newToListArgs0 = Expression.Call(joinExpArgs1.Object, joinExpArgs1.Method, + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, Expression.Lambda( Expression.Call( typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }), - Expression.Convert(joinExpArgs1Args0.Body, typeof(object)), - Expression.Convert(exp.Arguments[0], typeof(object))), - joinExpArgs1Args0.Parameters)); + Expression.Convert(exp.Arguments[0], typeof(object)), + Expression.Convert(toListArgs1.Body, typeof(object))), + toListArgs1.Parameters)); var newToListSql = getExp(newToListArgs0); if (string.IsNullOrEmpty(newToListSql) == false && newToListSql.StartsWith("(") && newToListSql.EndsWith(")")) { - newToListSql = $"{newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH(''))"; + newToListSql = $"stuff({newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH('')),1,len({getExp(exp.Arguments[0])}),'')"; return newToListSql; } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 14280137..fa3c394a 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -264,6 +264,20 @@ namespace FreeSql.Sqlite //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinSqliteGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else From aee82f9caa6ba4516cf339e01d34bf00ef499a00 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 8 Aug 2020 16:30:44 +0800 Subject: [PATCH 0805/1029] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=20SqlServerPro?= =?UTF-8?q?vider=20=E7=89=88=E6=9C=AC=E5=8F=B7=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- .../SqlServer/OdbcSqlServerProvider.cs | 10 +++++----- .../FreeSql.Provider.SqlServer/SqlServerProvider.cs | 10 +++++----- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..c46aa1e3 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -527,14 +527,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index ffe9ad80..d1e6aab7 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -41,15 +41,15 @@ namespace FreeSql.Odbc.SqlServer this.CodeFirst = new OdbcSqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); if (this.Ado.MasterPool != null) - using (var conn = this.Ado.MasterPool.Get()) + try { - try + using (var conn = this.Ado.MasterPool.Get()) { (this.InternalCommonUtils as OdbcSqlServerUtils).ServerVersion = int.Parse(conn.Value.ServerVersion.Split('.')[0]); } - catch - { - } + } + catch + { } } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index 0b130c33..8ab8e0a8 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -42,15 +42,15 @@ namespace FreeSql.SqlServer this.CodeFirst = new SqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); if (this.Ado.MasterPool != null) - using (var conn = this.Ado.MasterPool.Get()) + try { - try + using (var conn = this.Ado.MasterPool.Get()) { (this.InternalCommonUtils as SqlServerUtils).ServerVersion = int.Parse(conn.Value.ServerVersion.Split('.')[0]); } - catch - { - } + } + catch + { } } From e49f8b56fc5fd9dd733c1902df0a62dd404b52f5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 8 Aug 2020 16:33:50 +0800 Subject: [PATCH 0806/1029] v1.8.0-preview0808 #405 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 29 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 8636e280..51fe68ac 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 3b39b712..a1221933 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c4dffbab..f639d78a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 9bb39d42..e7441b1d 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index b0ff6151..8a7db017 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0806 + 1.8.0-preview0808 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 99193ac0..f25db86a 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a9047c72..a8118531 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index c46aa1e3..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -527,5 +527,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 9a9c89da..7a9e3454 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7516ac4d..ce247e34 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index c7ea7052..4c750789 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 695b2db1..b0960389 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5dadd6e3..f218d371 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 90ef0ab4..cf1ae1a6 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 1fdf1025..c68e173b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 590af991..20e71028 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e1661462..25468e04 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 343c867a..4ffdacb5 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 446672d0..0736aec0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index e02212ed..f5e2e69a 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index dd808462..bf08a835 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0806 + 1.8.0-preview0808 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 4bf81111f064e5b89eb6d963285e2252cc2980b8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 10 Aug 2020 00:41:11 +0800 Subject: [PATCH 0807/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20preview0808?= =?UTF-8?q?=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=20null=20?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests.VB/UnitTest1.vb | 11 +++++++++++ FreeSql/Internal/CommonExpression.cs | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests.VB/UnitTest1.vb b/FreeSql.Tests.VB/UnitTest1.vb index c8966d58..d9e12fa3 100644 --- a/FreeSql.Tests.VB/UnitTest1.vb +++ b/FreeSql.Tests.VB/UnitTest1.vb @@ -4,6 +4,17 @@ Imports Xunit Namespace FreeSql.Tests.VB Public Class UnitTest1 + + + Sub IsNothing() + Dim sql = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = 100 AndAlso a.Title Is Nothing).ToSql() + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Id] = 100 AND a.[Title] IS NULL)", sql) + + Dim lst = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = 100 AndAlso a.Title Is Nothing).ToList() + End Sub + Sub TestSub() diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 01004c01..fe9e51ab 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -499,9 +499,9 @@ namespace FreeSql.Internal case "=": case "<>": var exptb = _common.GetTableByEntity(leftExp.Type); - if (exptb != null) leftExp = Expression.MakeMemberAccess(leftExp, exptb.Properties[(exptb.Primarys.FirstOrDefault() ?? exptb.Columns.FirstOrDefault().Value).CsName]); + if (exptb?.Properties.Any() == true) leftExp = Expression.MakeMemberAccess(leftExp, exptb.Properties[(exptb.Primarys.FirstOrDefault() ?? exptb.Columns.FirstOrDefault().Value)?.CsName]); exptb = _common.GetTableByEntity(leftExp.Type); - if (exptb?.Primarys.Any() == true) rightExp = Expression.MakeMemberAccess(rightExp, exptb.Properties[(exptb.Primarys.FirstOrDefault() ?? exptb.Columns.FirstOrDefault().Value).CsName]); + if (exptb?.Properties.Any() == true) rightExp = Expression.MakeMemberAccess(rightExp, exptb.Properties[(exptb.Primarys.FirstOrDefault() ?? exptb.Columns.FirstOrDefault().Value).CsName]); break; } From 549d36974d14065ed051353cccdaea37427fb114 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 10 Aug 2020 00:59:48 +0800 Subject: [PATCH 0808/1029] v1.8.0-preview0810 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 20 insertions(+), 36 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 51fe68ac..f4c71e9c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a1221933..ab1a9cab 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index f639d78a..e7c697bc 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index e7441b1d..3f836eb4 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 8a7db017..067fc880 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0808 + 1.8.0-preview0810 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index f25db86a..52547a32 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a8118531..b141441c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..5ca74890 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -527,14 +520,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7a9e3454..ed8cde2d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index ce247e34..ce7ebfd8 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 4c750789..d0102ab7 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index b0960389..def6505d 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index f218d371..6daa14ec 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index cf1ae1a6..84e5af16 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c68e173b..affae313 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 20e71028..d886014b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 25468e04..21b4d604 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 4ffdacb5..2a1e7213 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 0736aec0..e40c35e1 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index f5e2e69a..855952fa 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index bf08a835..5b728753 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0808 + 1.8.0-preview0810 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From d602dfbaaae17494ad1ff466a20304b06d9d327d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 10 Aug 2020 12:27:39 +0800 Subject: [PATCH 0809/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=201.7.1=20IsNu?= =?UTF-8?q?llable=20=E9=81=97=E7=95=99=E9=97=AE=E9=A2=98=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 | 14 ++++++++++++-- FreeSql/Internal/UtilsExpressionTree.cs | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5ca74890..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -520,5 +527,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index ba54689f..d89e4db3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -158,20 +158,30 @@ namespace FreeSql.Tests class testInsertNullable { - [Column(IsIdentity = true)] + [Column(IsNullable = false, IsIdentity = true)] public long Id { get; set; } [Column(IsNullable = false)] public string str1 { get; set; } [Column(IsNullable = false)] public int? int1 { get; set; } + [Column(IsNullable = true)] + public int int2 { get; set; } } [Fact] public void Test03() { g.sqlite.Insert(new testInsertNullable()).NoneParameter().ExecuteAffrows(); - + var ddlsql = g.sqlite.CodeFirst.GetComparisonDDLStatements(typeof(testInsertNullable), "tb123123"); + Assert.Equal(@"CREATE TABLE IF NOT EXISTS ""main"".""tb123123"" ( + ""Id"" INTEGER PRIMARY KEY AUTOINCREMENT, + ""str1"" NVARCHAR(255) NOT NULL, + ""int1"" INTEGER NOT NULL, + ""int2"" INTEGER +) +; +", ddlsql); var sqlxx = g.pgsql.InsertOrUpdate().SetSource(new userinfo { userid = 10 }).UpdateColumns(a => new { a.birthday, a.CardNo }).ToSql(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 2b81e503..549cdac1 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -122,7 +122,7 @@ namespace FreeSql.Internal colattr.DbType = colattr.DbType.ToUpper(); if (colattrIsNull == false && colattrIsNullable == true) colattr.DbType = colattr.DbType.Replace("NOT NULL", ""); - if (colattrIsNull == false && colattrIsNullable == false) colattr.DbType = Regex.Replace(colattr.DbType, @"\bNULL\b", "").Trim() + " NOT NULL"; + if (colattrIsNull == false && colattrIsNullable == false && colattr.DbType.Contains("NOT NULL") == false) colattr.DbType = Regex.Replace(colattr.DbType, @"\bNULL\b", "").Trim() + " NOT NULL"; if (colattr._IsNullable == null && tp != null && tp.isnullable == null) colattr.IsNullable = tp.dbtypeFull.Contains("NOT NULL") == false; if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; From 93562fd8029406233a76343475731b010d55fb06 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 10 Aug 2020 17:57:29 +0800 Subject: [PATCH 0810/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20NoneParamete?= =?UTF-8?q?r=20Oracle=20=E6=96=87=E6=9C=AC=E8=B6=85=E9=95=BF=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Oracle/OracleCodeFirstTest.cs | 30 ++- .../Sqlite/SqliteCodeFirstTest.cs | 7 + .../CommonProvider/InsertOrUpdateProvider.cs | 2 +- .../Internal/CommonProvider/InsertProvider.cs | 6 +- .../Internal/CommonProvider/UpdateProvider.cs | 10 +- FreeSql/Internal/CommonUtils.cs | 2 +- FreeSql/Internal/UtilsExpressionTree.cs | 2 +- .../Curd/DamengInsert.cs | 3 +- .../FreeSql.Provider.Dameng/DamengUtils.cs | 2 +- .../MsAccessUtils.cs | 2 +- .../Curd/MySqlInsertOrUpdate.cs | 1 + .../Curd/OnDuplicateKeyUpdate.cs | 1 + .../FreeSql.Provider.MySql/MySqlUtils.cs | 2 +- .../MySqlConnectorUtils.cs | 2 +- .../Dameng/Curd/OdbcDamengInsert.cs | 3 +- .../Dameng/OdbcDamengUtils.cs | 2 +- .../Default/OdbcUtils.cs | 2 +- .../Curd/OdbcKingbaseESInsertOrUpdate.cs | 1 + .../Curd/OdbcKingbaseESOnConflictDoUpdate.cs | 1 + .../KingbaseES/OdbcKingbaseESUtils.cs | 4 +- .../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 1 + .../Curd/OdbcMySqlOnDuplicateKeyUpdate.cs | 1 + .../MySql/OdbcMySqlUtils.cs | 2 +- .../Oracle/Curd/OdbcOracleInsert.cs | 3 +- .../Oracle/OdbcOracleUtils.cs | 23 +- .../Curd/OdbcPostgreSQLInsertOrUpdate.cs | 1 + .../Curd/OdbcPostgreSQLOnConflictDoUpdate.cs | 1 + .../PostgreSQL/OdbcPostgreSQLUtils.cs | 4 +- .../SqlServer/OdbcSqlServerUtils.cs | 2 +- .../Curd/OracleInsert.cs | 3 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 23 +- .../Curd/OnConflictDoUpdate.cs | 1 + .../Curd/PostgreSQLInsertOrUpdate.cs | 1 + .../PostgreSQLUtils.cs | 6 +- .../Curd/OnConflictDoUpdate.cs | 207 ------------------ .../ShenTongUtils.cs | 4 +- .../SqlServerUtils.cs | 2 +- .../Curd/SqliteInsertOrUpdate.cs | 1 + .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 7 +- 39 files changed, 129 insertions(+), 249 deletions(-) delete mode 100644 Providers/FreeSql.Provider.ShenTong/Curd/OnConflictDoUpdate.cs diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 5774f0a6..bdf17b8d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -25,8 +25,11 @@ namespace FreeSql.Tests.Oracle //NoneParameter item1 = new TS_NCLB02 { Data = str1 }; - Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + Assert.Equal(1, g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ + + item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); } class TS_NCLB02 { @@ -48,8 +51,11 @@ namespace FreeSql.Tests.Oracle //NoneParameter item1 = new TS_NCLB01 { Data = str1 }; - Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + Assert.Equal(1, g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ + + item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); } class TS_NCLB01 { @@ -70,8 +76,11 @@ namespace FreeSql.Tests.Oracle //NoneParameter item1 = new TS_CLB01 { Data = str1 }; - Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + Assert.Equal(1, g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ + + item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); } class TS_CLB01 { @@ -96,8 +105,21 @@ namespace FreeSql.Tests.Oracle //NoneParameter item1 = new TS_BLB01 { Data = data1 }; - Assert.Throws(() => g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); + Assert.Equal(1, g.oracle.Insert(item1).NoneParameter().ExecuteAffrows()); //Oracle.ManagedDataAccess.Client.OracleException:ORA-01704: ַ̫ + + item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + Assert.Equal(1, g.oracle.InsertOrUpdate().SetSource(new TS_BLB01 { Data = data1 }).ExecuteAffrows()); + item2 = g.oracle.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); } class TS_BLB01 { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs index 9f00a265..ab378295 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs @@ -35,6 +35,13 @@ namespace FreeSql.Tests.Sqlite str2 = Encoding.UTF8.GetString(item2.Data); Assert.Equal(str1, str2); + + Assert.Equal(1, g.sqlite.InsertOrUpdate().SetSource(new TS_BLB01 { Data = data1 }).ExecuteAffrows()); + item2 = g.sqlite.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); } class TS_BLB01 { diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 915eeca5..28bffde0 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -167,7 +167,7 @@ namespace FreeSql.Internal.CommonProvider else { object val = col.GetMapValue(d); - sb.Append(_commonUtils.GetNoneParamaterSqlValue(dbParams, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(dbParams, "cu", col.Attribute.MapType, val)); } if (didx == 0) sb.Append(" as ").Append(col.Attribute.Name); ++colidx2; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 6275a822..596a58b7 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -23,6 +23,7 @@ namespace FreeSql.Internal.CommonProvider public Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public TableInfo _table; public Func _tableRule; + public string _noneParameterFlag = "c"; public bool _noneParameter, _insertIdentity; public int _batchValuesLimit, _batchParameterLimit; public bool _batchAutoTransaction = true; @@ -550,7 +551,7 @@ namespace FreeSql.Internal.CommonProvider object val = col.GetMapValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); @@ -563,8 +564,7 @@ namespace FreeSql.Internal.CommonProvider onrow?.Invoke(d, didx, sb); ++didx; } - if (_noneParameter && specialParams.Any()) - _params = specialParams.ToArray(); + if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray(); return sb.ToString(); } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 93b500a3..5b5f36db 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -409,7 +409,7 @@ namespace FreeSql.Internal.CommonProvider _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); if (_noneParameter) { - _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, col.Attribute.MapType, paramVal)); + _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, "u", col.Attribute.MapType, paramVal)); } else { @@ -565,7 +565,7 @@ namespace FreeSql.Internal.CommonProvider var sb = new StringBuilder(); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, col.GetMapValue(_source.First())))); + sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, col.GetMapValue(_source.First())))); return sb.ToString(); @@ -589,7 +589,7 @@ namespace FreeSql.Internal.CommonProvider ToSqlWhen(cwsb, _table.Primarys, d); cwsb.Append(" THEN "); var val = col.GetMapValue(d); - cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val))); + cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val))); if (val == null || val == DBNull.Value) nulls++; } cwsb.Append(" END"); @@ -661,7 +661,7 @@ namespace FreeSql.Internal.CommonProvider { var val = col.GetMapValue(_source.First()); if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); @@ -705,7 +705,7 @@ namespace FreeSql.Internal.CommonProvider cwsb.Append(" THEN "); var val = col.GetMapValue(d); if (_noneParameter) - cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, val)); + cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val)); else { cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 1fbac9fa..7d0704c0 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -23,7 +23,7 @@ namespace FreeSql.Internal public abstract class CommonUtils { - public abstract string GetNoneParamaterSqlValue(List specialParams, Type type, object value); + public abstract string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value); public abstract DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value); public abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); public abstract string FormatSql(string sql, params object[] args); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 549cdac1..ab180445 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -187,7 +187,7 @@ namespace FreeSql.Internal } try { - col.DbDefaultValue = common.GetNoneParamaterSqlValue(new List(), colattr.MapType, defaultValue); + col.DbDefaultValue = common.GetNoneParamaterSqlValue(new List(), "init", colattr.MapType, defaultValue); } catch { diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index 2bee3fba..b2181171 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -69,7 +69,7 @@ namespace FreeSql.Dameng.Curd object val = col.GetMapValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); @@ -81,6 +81,7 @@ namespace FreeSql.Dameng.Curd sb.Append(")"); ++didx; } + if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray(); if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs index 8d26e29f..b9500106 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs @@ -93,7 +93,7 @@ namespace FreeSql.Dameng public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs index c5c7aa2d..ed8fc51b 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -82,7 +82,7 @@ namespace FreeSql.MsAccess public override string FieldAsAlias(string alias) => $" as {alias}"; public override string IIF(string test, string ifTrue, string ifElse) => $"iif({test}, {ifTrue}, {ifElse})"; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index 9a275be2..46fc44d6 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -37,6 +37,7 @@ namespace FreeSql.MySql.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs index 66118ee1..802ab4c1 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -17,6 +17,7 @@ namespace FreeSql.MySql.Curd { _mysqlInsert = insert as MySqlInsert; if (_mysqlInsert == null) throw new Exception("OnDuplicateKeyUpdate 是 FreeSql.Provider.MySql/FreeSql.Provider.MySqlConnector 特有的功能"); + if (_mysqlInsert._noneParameterFlag == "c") _mysqlInsert._noneParameterFlag = "cu"; } protected void ClearData() diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 3986c65b..5a4ced4d 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -126,7 +126,7 @@ namespace FreeSql.MySql return columnName; } - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index df8e23b4..221855b1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -146,7 +146,7 @@ namespace FreeSql.MySql return columnName; } - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index de1f043d..85dcab11 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -69,7 +69,7 @@ namespace FreeSql.Odbc.Dameng object val = col.GetMapValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); @@ -81,6 +81,7 @@ namespace FreeSql.Odbc.Dameng sb.Append(")"); ++didx; } + if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray(); if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index 50391fab..a9edc60d 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -99,7 +99,7 @@ namespace FreeSql.Odbc.Dameng public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index ebf3b993..64fd5d83 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -69,7 +69,7 @@ namespace FreeSql.Odbc.Default public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => Adapter.FieldSql(type, columnName); - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs index d4258280..7eaf2fee 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs @@ -37,6 +37,7 @@ namespace FreeSql.Odbc.KingbaseES .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs index 432020c1..d8802705 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs @@ -24,6 +24,7 @@ namespace FreeSql.Odbc.KingbaseES { _pgsqlInsert = insert as OdbcKingbaseESInsert; if (_pgsqlInsert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.Odbc/KingbaseES 特有的功能"); + if (_pgsqlInsert._noneParameterFlag == "c") _pgsqlInsert._noneParameterFlag = "cu"; if (columns != null) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs index f46f3c13..b1a3a680 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs @@ -123,7 +123,7 @@ namespace FreeSql.Odbc.KingbaseES public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -145,7 +145,7 @@ namespace FreeSql.Odbc.KingbaseES { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index 38c5dfab..822fb089 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -36,6 +36,7 @@ namespace FreeSql.Odbc.MySql .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs index cc4649fb..5d12c106 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs @@ -17,6 +17,7 @@ namespace FreeSql.Odbc.MySql { _mysqlInsert = insert as OdbcMySqlInsert; if (_mysqlInsert == null) throw new Exception("OnDuplicateKeyUpdate 是 FreeSql.Provider.Odbc/MySql 特有的功能"); + if (_mysqlInsert._noneParameterFlag == "c") _mysqlInsert._noneParameterFlag = "cu"; } protected void ClearData() diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index 6ce28f10..dc65db27 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -93,7 +93,7 @@ namespace FreeSql.Odbc.MySql return columnName; } - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index f4ea0596..2f73dc42 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -69,7 +69,7 @@ namespace FreeSql.Odbc.Oracle object val = col.GetMapValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); @@ -81,6 +81,7 @@ namespace FreeSql.Odbc.Oracle sb.Append(")"); ++didx; } + if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray(); if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index dddeda5f..1279be50 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -99,11 +99,30 @@ namespace FreeSql.Odbc.Oracle public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); - if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; + if (type == typeof(string)) + { + var valueString = value as string; + if (valueString != null) + { + if (valueString.Length < 4000) return string.Concat("'", valueString.Replace("'", "''"), "'"); + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value); + return pam.ParameterName; + } + } + if (type == typeof(byte[])) + { + var valueBytes = value as byte[]; + if (valueBytes != null) + { + if (valueBytes.Length < 4000) return $"hextoraw('{CommonUtils.BytesSqlRaw(valueBytes)}')"; + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value); + return pam.ParameterName; + } + } return FormatSql("{0}", value, 1); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs index c709a6d3..8f438e22 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.Odbc.PostgreSQL .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs index 4d59b8af..879bba71 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs @@ -24,6 +24,7 @@ namespace FreeSql.Odbc.PostgreSQL { _pgsqlInsert = insert as OdbcPostgreSQLInsert; if (_pgsqlInsert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.Odbc/PostgreSQL 特有的功能"); + if (_pgsqlInsert._noneParameterFlag == "c") _pgsqlInsert._noneParameterFlag = "cu"; if (columns != null) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index 1182028e..c65c1788 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -123,7 +123,7 @@ namespace FreeSql.Odbc.PostgreSQL public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -145,7 +145,7 @@ namespace FreeSql.Odbc.PostgreSQL { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index 214a7d1b..bb2fc858 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -86,7 +86,7 @@ namespace FreeSql.Odbc.SqlServer public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 371191d9..04c8d2ad 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -71,7 +71,7 @@ namespace FreeSql.Oracle.Curd object val = col.GetMapValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); @@ -83,6 +83,7 @@ namespace FreeSql.Oracle.Curd sb.Append(")"); ++didx; } + if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray(); if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); return sb.ToString(); } diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 90121043..c6eaca38 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -98,11 +98,30 @@ namespace FreeSql.Oracle public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); - if (type == typeof(byte[])) return $"hextoraw('{CommonUtils.BytesSqlRaw(value as byte[])}')"; + if (type == typeof(string)) + { + var valueString = value as string; + if (valueString != null) + { + if (valueString.Length < 4000) return string.Concat("'", valueString.Replace("'", "''"), "'"); + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value); + return pam.ParameterName; + } + } + if (type == typeof(byte[])) + { + var valueBytes = value as byte[]; + if (valueBytes != null) + { + if (valueBytes.Length < 4000) return $"hextoraw('{CommonUtils.BytesSqlRaw(valueBytes)}')"; + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value); + return pam.ParameterName; + } + } return FormatSql("{0}", value, 1); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index 2fbdf279..cc02ec6c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -24,6 +24,7 @@ namespace FreeSql.PostgreSQL.Curd { _pgsqlInsert = insert as PostgreSQLInsert; if (_pgsqlInsert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.PostgreSQL 特有的功能"); + if (_pgsqlInsert._noneParameterFlag == "c") _pgsqlInsert._noneParameterFlag = "cu"; if (columns != null) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index 7af97ef1..6d5a6291 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.PostgreSQL.Curd .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; + insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index 30d9422c..bf384eda 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -163,7 +163,7 @@ namespace FreeSql.PostgreSQL public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; static ConcurrentDictionary _dicIsAssignableFromPostgisGeometry = new ConcurrentDictionary(); - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -178,7 +178,7 @@ namespace FreeSql.PostgreSQL ; })) { - var pam = AppendParamter(specialParams, null, null, type, value); + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value); return pam.ParameterName; } value = getParamterValue(type, value); @@ -199,7 +199,7 @@ namespace FreeSql.PostgreSQL { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/OnConflictDoUpdate.cs deleted file mode 100644 index 7857f92f..00000000 --- a/Providers/FreeSql.Provider.ShenTong/Curd/OnConflictDoUpdate.cs +++ /dev/null @@ -1,207 +0,0 @@ -using FreeSql.Aop; -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; - -namespace FreeSql.ShenTong.Curd -{ - public class OnConflictDoUpdate where T1 : class - { - internal ShenTongInsert _oscarInsert; - internal ShenTongUpdate _oscarUpdatePriv; - internal ShenTongUpdate _oscarUpdate => _oscarUpdatePriv ?? - (_oscarUpdatePriv = new ShenTongUpdate(_oscarInsert.InternalOrm, _oscarInsert.InternalCommonUtils, _oscarInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } - .NoneParameter().SetSource(_oscarInsert.InternalSource) as ShenTongUpdate); - ColumnInfo[] _columns; - bool _doNothing; - - public OnConflictDoUpdate(IInsert insert, Expression> columns = null) - { - _oscarInsert = insert as ShenTongInsert; - if (_oscarInsert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.ShenTong 特有的功能"); - - if (columns != null) - { - var colsList = new List(); - var cols = _oscarInsert.InternalCommonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); - foreach (var col in _oscarInsert.InternalTable.Columns.Values) - if (cols.ContainsKey(col.Attribute.Name)) - colsList.Add(col); - _columns = colsList.ToArray(); - } - if (_columns == null || _columns.Any() == false) - _columns = _oscarInsert.InternalTable.Primarys; - if (_columns.Any() == false) throw new Exception("OnConflictDoUpdate 功能要求实体类必须设置 IsPrimary 属性"); - } - - protected void ClearData() - { - _oscarInsert.InternalClearData(); - _oscarUpdatePriv = null; - } - - public OnConflictDoUpdate IgnoreColumns(Expression> columns) - { - _oscarUpdate.IgnoreColumns(columns); - return this; - } - public OnConflictDoUpdate UpdateColumns(Expression> columns) - { - _oscarUpdate.UpdateColumns(columns); - return this; - } - public OnConflictDoUpdate IgnoreColumns(string[] columns) - { - _oscarUpdate.IgnoreColumns(columns); - return this; - } - public OnConflictDoUpdate UpdateColumns(string[] columns) - { - _oscarUpdate.UpdateColumns(columns); - return this; - } - - public OnConflictDoUpdate Set(Expression> column, TMember value) - { - _oscarUpdate.Set(column, value); - return this; - } - //由于表达式解析问题,ON CONFLICT("id") DO UPDATE SET 需要指定表别名,如 Set(a => a.Clicks + 1) 解析会失败 - //暂时不开放这个功能,如有需要使用 SetRaw("click = t.click + 1") 替代该操作 - //public OnConflictDoUpdate Set(Expression> exp) - //{ - // _oscarUpdate.Set(exp); - // return this; - //} - public OnConflictDoUpdate SetRaw(string sql) - { - _oscarUpdate.SetRaw(sql); - return this; - } - - public OnConflictDoUpdate DoNothing() - { - _doNothing = true; - return this; - } - - public string ToSql() - { - var sb = new StringBuilder(); - sb.Append(_oscarInsert.ToSql()).Append("\r\nON CONFLICT("); - for (var a = 0; a < _columns.Length; a++) - { - if (a > 0) sb.Append(", "); - sb.Append(_oscarInsert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); - } - if (_doNothing) - { - sb.Append(") DO NOTHING"); - } - else - { - sb.Append(") DO UPDATE SET\r\n"); - - var sbSetEmpty = _oscarUpdate.InternalSbSet.Length == 0; - var sbSetIncrEmpty = _oscarUpdate.InternalSbSetIncr.Length == 0; - if (sbSetEmpty == false || sbSetIncrEmpty == false) - { - if (sbSetEmpty == false) sb.Append(_oscarUpdate.InternalSbSet.ToString().Substring(2)); - if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _oscarUpdate.InternalSbSetIncr.ToString().Substring(2) : _oscarUpdate.InternalSbSetIncr.ToString()); - } - else - { - var colidx = 0; - foreach (var col in _oscarInsert.InternalTable.Columns.Values) - { - if (col.Attribute.IsPrimary || _oscarUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; - - if (colidx > 0) sb.Append(", \r\n"); - - if (col.Attribute.IsVersion == true) - { - var field = _oscarInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); - sb.Append(field).Append(" = ").Append(_oscarInsert.InternalCommonUtils.QuoteSqlName(_oscarInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); - } - else if (_oscarInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) - { - var caseWhen = _oscarUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); - sb.Append(caseWhen); - if (caseWhen.EndsWith(" END")) _oscarUpdate.InternalToSqlCaseWhenEnd(sb, col); - } - else - { - var field = _oscarInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); - sb.Append(field).Append(" = EXCLUDED.").Append(field); - } - ++colidx; - } - } - } - - return sb.ToString(); - } - - public long ExecuteAffrows() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - - var before = new CurdBeforeEventArgs(_oscarInsert.InternalTable.Type, _oscarInsert.InternalTable, CurdType.Insert, sql, _oscarInsert.InternalParams); - _oscarInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_oscarInsert, before); - long ret = 0; - Exception exception = null; - try - { - ret = _oscarInsert.InternalOrm.Ado.ExecuteNonQuery(_oscarInsert.InternalConnection, _oscarInsert.InternalTransaction, CommandType.Text, sql, _oscarInsert.InternalParams); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new CurdAfterEventArgs(before, exception, ret); - _oscarInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_oscarInsert, after); - ClearData(); - } - return ret; - } - -#if net40 -#else - async public Task ExecuteAffrowsAsync() - { - var sql = this.ToSql(); - if (string.IsNullOrEmpty(sql)) return 0; - - var before = new CurdBeforeEventArgs(_oscarInsert.InternalTable.Type, _oscarInsert.InternalTable, CurdType.Insert, sql, _oscarInsert.InternalParams); - _oscarInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_oscarInsert, before); - long ret = 0; - Exception exception = null; - try - { - ret = await _oscarInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_oscarInsert.InternalConnection, _oscarInsert.InternalTransaction, CommandType.Text, sql, _oscarInsert.InternalParams); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new CurdAfterEventArgs(before, exception, ret); - _oscarInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_oscarInsert, after); - ClearData(); - } - return ret; - } -#endif - } -} diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs index bf0e67f4..b29ce343 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs @@ -137,7 +137,7 @@ namespace FreeSql.ShenTong public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -161,7 +161,7 @@ namespace FreeSql.ShenTong { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index be0468f3..88a36219 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -102,7 +102,7 @@ namespace FreeSql.SqlServer public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index 2e0b442e..b6b4422e 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -35,6 +35,7 @@ namespace FreeSql.Sqlite.Curd .WithConnection(_connection) .WithTransaction(_transaction) .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._noneParameterFlag = flagInsert ? "c" : "cu"; insert._source = data; string sql = ""; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 616b01ef..98ed34bd 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -98,10 +98,15 @@ namespace FreeSql.Sqlite public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + if (type == typeof(byte[])) + { + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", null, type, value); + return pam.ParameterName; + } return FormatSql("{0}", value, 1); } } From 3018fc8b2b48d94d95c851850ba6de2d824f9970 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 10 Aug 2020 18:10:19 +0800 Subject: [PATCH 0811/1029] v1.8.0-preview0811 #409 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 151 ------------------ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 20 insertions(+), 171 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f4c71e9c..4ab6c226 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ab1a9cab..0249724b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e7c697bc..361d6962 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 3f836eb4..768c9044 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 067fc880..185ed507 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0810 + 1.8.0-preview0811 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 52547a32..ffd0af98 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b141441c..9afc235e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index ed8cde2d..4e3e3e59 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index ce7ebfd8..cc60e7f2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ea460a59..8b29e434 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2592,145 +2592,6 @@ - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3400,12 +3261,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3476,12 +3331,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index d0102ab7..978069a3 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index def6505d..8249c17f 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6daa14ec..a4b48b36 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 84e5af16..068e75b7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index affae313..29dc1959 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d886014b..05bd7d83 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 21b4d604..1facd8ff 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 2a1e7213..18f5bbc9 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e40c35e1..7c476a33 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 855952fa..2c661f88 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5b728753..c62a139e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0810 + 1.8.0-preview0811 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 8da3c16c4096bda818b85eed1a91ca7809af9db1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 10 Aug 2020 18:44:05 +0800 Subject: [PATCH 0812/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20SetSource=20?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=E4=B8=8D=E6=9B=B4=E6=96=B0=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 -- .../DataAnnotations/MySqlFluentTest.cs | 2 +- .../Sqlite/Curd/SqliteUpdateTest.cs | 33 ++++ FreeSql/FreeSql.xml | 151 ++++++++++++++++++ .../Internal/CommonProvider/UpdateProvider.cs | 2 + 5 files changed, 187 insertions(+), 17 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..5ca74890 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -527,14 +520,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index c86d4fd8..bf551099 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -179,7 +179,7 @@ namespace FreeSql.Tests.DataAnnotations item.title = "testtitle_update"; item.testfield2 = 0; sql = g.mysql.Update().SetSource(item).ToSql().Replace("\r\n", ""); - Assert.Equal($"UPDATE `TestCanInsert` SET `id` = ?p_0, `title` = ?p_1, `testfield1` = ?p_2 WHERE (`id` = '{item.id}')", sql); + Assert.Equal($"UPDATE `TestCanInsert` SET `title` = ?p_0, `testfield1` = ?p_1 WHERE (`id` = '{item.id}')", sql); Assert.Equal(1, g.mysql.Update().SetSource(item).ExecuteAffrows()); find = g.mysql.Select().Where(a => a.id == item.id).First(); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index 49c868b5..b9a0e04f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -21,6 +21,17 @@ namespace FreeSql.Tests.Sqlite public string Title { get; set; } public DateTime CreateTime { get; set; } } + [Table(Name = "tb_topic_setsource")] + class Topic22 + { + [Column(IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } [Fact] public void Dywhere() @@ -65,6 +76,28 @@ namespace FreeSql.Tests.Sqlite public string xx { get; set; } } [Fact] + public void SetSourceNoIdentity() + { + var fsql = g.sqlite; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var sql = fsql.Update().SetSource(new Topic22 { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic_setsource\" SET \"Clicks\" = @p_0, \"Title\" = @p_1, \"CreateTime\" = @p_2 WHERE (\"Id\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic22 { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.Equal(10, fsql.Insert(items).ExecuteAffrows()); + items[0].Clicks = null; + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic_setsource\" SET \"Clicks\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"Title\" = CASE \"Id\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CreateTime\" = CASE \"Id\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic_setsource\" SET \"Title\" = CASE \"Id\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic_setsource\" SET \"CreateTime\" = @p_0 WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] public void SetSourceIgnore() { Assert.Equal("UPDATE \"tssi01\" SET \"tint\" = 10 WHERE (\"id\" = '00000000-0000-0000-0000-000000000000')", diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8b29e434..ea460a59 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2592,6 +2592,145 @@ + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3261,6 +3400,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3331,6 +3476,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 5b5f36db..1c87af5b 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -650,6 +650,7 @@ namespace FreeSql.Internal.CommonProvider var colidx = 0; foreach (var col in _table.Columns.Values) { + if (col.Attribute.IsPrimary) continue; if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false) { if (colidx > 0) sb.Append(", "); @@ -687,6 +688,7 @@ namespace FreeSql.Internal.CommonProvider var colidx = 0; foreach (var col in _table.Columns.Values) { + if (col.Attribute.IsPrimary) continue; if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false) { if (colidx > 0) sb.Append(", "); From 1ab1d16e53c5d13b3659498f46e491cd5978532a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 11 Aug 2020 08:39:03 +0800 Subject: [PATCH 0813/1029] =?UTF-8?q?=E4=BC=98=E5=8C=96=20vb.net=20?= =?UTF-8?q?=E5=8C=BF=E5=90=8D=E7=B1=BB=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++++ FreeSql.Tests.VB/UnitTest1.vb | 67 ++++++++++++++++++- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- FreeSql/Internal/CommonExpression.cs | 27 ++++---- 4 files changed, 94 insertions(+), 18 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5ca74890..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -520,5 +527,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests.VB/UnitTest1.vb b/FreeSql.Tests.VB/UnitTest1.vb index d9e12fa3..8551d581 100644 --- a/FreeSql.Tests.VB/UnitTest1.vb +++ b/FreeSql.Tests.VB/UnitTest1.vb @@ -20,20 +20,81 @@ WHERE (a.[Id] = 100 AND a.[Title] IS NULL)", sql) REM VB.net ʽԲ Dim id As Integer = 100 + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Id] = 100)", g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = 100).ToSql()) Dim List1 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = 100).ToList() + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Id] = 100)", g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = id).ToSql()) Dim List2 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Id = id).ToList() + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[IdNullable] = 100)", g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = 100).ToSql()) Dim List11 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = 100).ToList() + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[IdNullable] = 100)", g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = id).ToSql()) Dim List22 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = id).ToList() + Dim idNullable As Integer? = 100 + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[IdNullable] = 100)", g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = idNullable).ToSql()) Dim List222 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IdNullable = idNullable).ToList() + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Title] = N'xxx')", g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = "xxx").ToSql()) Dim List3 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = "xxx").ToList() + Dim title As String = "xxx" + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Title] = N'xxx')", g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = title).ToSql()) Dim List4 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = title).ToList() + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Title] <> N'xxx')", g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> "xxx").ToSql()) Dim List5 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> "xxx").ToList() + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Title] <> N'xxx')", g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> title).ToSql()) Dim List6 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> title).ToList() - Dim List7 = g.sqlserver.Select(Of Testvb).ToList(Function(a) New With {a, a.Id, a.Title}) - Dim List8 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IsDeleted).ToList() + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Title] = a.[Title])", g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = a.Title).ToSql()) + Dim List7 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = a.Title).ToList() + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[Title] <> a.[Title])", g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title <> a.Title).ToSql()) + Dim List71 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.Title = a.Title).ToList() + + Assert.Equal("SELECT a.[Id] as1, a.[Title] as2, a.[IsDeleted] as3, a.[IdNullable] as4, a.[Id] as5, a.[Title] as6 +FROM [Testvb] a", g.sqlserver.Select(Of Testvb).ToSql(Function(a) New With {a, a.Id, a.Title})) + Dim List8 = g.sqlserver.Select(Of Testvb).ToList(Function(a) New With {a, a.Id, a.Title}) + + Assert.Equal("SELECT a.[Id] as1, a.[Title] as2 +FROM [Testvb] a", g.sqlserver.Select(Of Testvb).ToSql(Function(a) New With {a.Id, a.Title})) + Dim List81 = g.sqlserver.Select(Of Testvb).ToList(Function(a) New With {a.Id, a.Title}) + + Assert.Equal("SELECT a.[Id], a.[Title], a.[IsDeleted], a.[IdNullable] +FROM [Testvb] a +WHERE (a.[IsDeleted] = 1)", g.sqlserver.Select(Of Testvb).Where(Function(a) a.IsDeleted).ToSql()) + Dim List9 = g.sqlserver.Select(Of Testvb).Where(Function(a) a.IsDeleted).ToList() + + REM Microsoft.VisualBasic.CompilerServices.Operators.CompareObjectEqual( + g.sqlserver.Delete(Of Testvb2).Where("1=1").ExecuteAffrows() @@ -48,7 +109,7 @@ WHERE (a.[Id] = 100 AND a.[Title] IS NULL)", sql) g.sqlserver.Insert(New Testvb2 With {.Id = 5, .TestvbId = 2, .Context = "Context22"}).ExecuteAffrows() g.sqlserver.Insert(New Testvb2 With {.Id = 6, .TestvbId = 3, .Context = "Context31"}).ExecuteAffrows() - Dim List9 = g.sqlserver.Select(Of Testvb).IncludeMany(Function(a) a.Testvb2s).ToList() + Dim List10 = g.sqlserver.Select(Of Testvb).IncludeMany(Function(a) a.Testvb2s).ToList() BaseEntity.Initialization(g.sqlserver, Nothing) Dim cowR As CowRecord = New CowRecord diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 4cf89817..416646bc 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -44,7 +44,7 @@ public static partial class FreeSqlGlobalExtensions public static bool IsIntegerType(this Type that) => that == null ? false : (_dicIsNumberType.Value.TryGetValue(that, out var tryval) ? tryval : false); public static bool IsNumberType(this Type that) => that == null ? false : _dicIsNumberType.Value.ContainsKey(that); public static bool IsNullableType(this Type that) => that.IsArray == false && that?.FullName.StartsWith("System.Nullable`1[") == true; - public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true; + public static bool IsAnonymousType(this Type that) => that == null ? false : (that.FullName.StartsWith("<>f__AnonymousType") || that.FullName.StartsWith("VB$AnonymousType")); public static bool IsArrayOrList(this Type that) => that == null ? false : (that.IsArray || typeof(IList).IsAssignableFrom(that)); public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GetGenericArguments().First() : that; internal static string NotNullAndConcat(this string that, params object[] args) => string.IsNullOrEmpty(that) ? null : string.Concat(new object[] { that }.Concat(args)); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index fe9e51ab..f2d1512a 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -465,20 +465,6 @@ namespace FreeSql.Internal } public string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) { - if (leftExp.NodeType == ExpressionType.Call && - rightExp.NodeType == ExpressionType.Constant && - new[] { "=", "<>" }.Contains(oper)) - { - var leftExpCall = leftExp as MethodCallExpression; - //vb 语法,将字符串比较转换为了 CompareString - if (leftExpCall.Method.Name == "CompareString" && - leftExpCall.Method.DeclaringType?.FullName == "Microsoft.VisualBasic.CompilerServices.Operators" && - leftExpCall.Arguments.Count == 3 && - leftExpCall.Arguments[2].Type == typeof(bool) && - rightExp.Type == typeof(int) && - (int)(rightExp as ConstantExpression).Value == 0) - return ExpressionBinary(oper, leftExpCall.Arguments[0], leftExpCall.Arguments[1], tsc); - } switch (oper) { case "OR": @@ -498,6 +484,19 @@ namespace FreeSql.Internal return $"({ExpressionLambdaToSql(leftExp, tsc)} {oper} {ExpressionLambdaToSql(rightExp, tsc)})"; case "=": case "<>": + if (leftExp.NodeType == ExpressionType.Call && + rightExp.NodeType == ExpressionType.Constant) + { + var leftExpCall = leftExp as MethodCallExpression; + //vb 语法,将字符串比较转换为了 CompareString + if (leftExpCall.Method.Name == "CompareString" && + leftExpCall.Method.DeclaringType?.FullName == "Microsoft.VisualBasic.CompilerServices.Operators" && + leftExpCall.Arguments.Count == 3 && + leftExpCall.Arguments[2].Type == typeof(bool) && + rightExp.Type == typeof(int) && + (int)(rightExp as ConstantExpression).Value == 0) + return ExpressionBinary(oper, leftExpCall.Arguments[0], leftExpCall.Arguments[1], tsc); + } var exptb = _common.GetTableByEntity(leftExp.Type); if (exptb?.Properties.Any() == true) leftExp = Expression.MakeMemberAccess(leftExp, exptb.Properties[(exptb.Primarys.FirstOrDefault() ?? exptb.Columns.FirstOrDefault().Value)?.CsName]); exptb = _common.GetTableByEntity(leftExp.Type); From da6effcf52b0760bda6569dfb49221543f1a28ab Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 11 Aug 2020 12:48:26 +0800 Subject: [PATCH 0814/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IDbFirst.Exi?= =?UTF-8?q?stsTable=20=E6=96=B9=E6=B3=95=E5=88=A4=E6=96=AD=E8=A1=A8?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E5=AD=98=E5=9C=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ----------- .../MySqlConnector/MySqlDbFirstTest.cs | 27 +++++++++++++++++++ .../Dameng/DamengDbFirstTest.cs | 27 +++++++++++++++++++ .../KingbaseES/KingbaseESDbFirstTest.cs | 27 +++++++++++++++++++ .../MySql/MySqlDbFirstTest.cs | 27 +++++++++++++++++++ .../Oracle/OracleDbFirstTest.cs | 27 +++++++++++++++++++ .../PostgreSQL/PostgreSQLDbFirstTest.cs | 27 +++++++++++++++++++ .../SqlServer/SqlServerDbFirstTest.cs | 27 +++++++++++++++++++ .../FreeSql.Tests/Dameng/DamengDbFirstTest.cs | 27 +++++++++++++++++++ .../FreeSql.Tests/MySql/MySqlDbFirstTest.cs | 27 +++++++++++++++++++ .../FreeSql.Tests/Oracle/OracleDbFirstTest.cs | 27 +++++++++++++++++++ .../PostgreSQL/PostgreSQLDbFirstTest.cs | 27 +++++++++++++++++++ .../ShenTong/ShenTongDbFirstTest.cs | 27 +++++++++++++++++++ .../SqlServer/SqlServerDbFirstTest.cs | 27 +++++++++++++++++++ .../FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs | 27 +++++++++++++++++++ FreeSql/FreeSql.xml | 8 ++++++ FreeSql/Interface/IDbFirst.cs | 10 +++++++ .../FreeSql.Provider.Dameng/DamengDbFirst.cs | 19 +++++++++++++ .../FreeSql.Provider.MySql/MySqlDbFirst.cs | 18 +++++++++++++ .../Dameng/OdbcDamengDbFirst.cs | 19 +++++++++++++ .../KingbaseES/OdbcKingbaseESDbFirst.cs | 10 +++++++ .../MySql/OdbcMySqlDbFirst.cs | 18 +++++++++++++ .../Oracle/OdbcOracleDbFirst.cs | 19 +++++++++++++ .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 10 +++++++ .../SqlServer/OdbcSqlServerDbFirst.cs | 25 +++++++++++++++++ .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 19 +++++++++++++ .../PostgreSQLDbFirst.cs | 10 +++++++ .../ShenTongDbFirst.cs | 16 +++++++++++ .../SqlServerDbFirst.cs | 25 +++++++++++++++++ .../FreeSql.Provider.Sqlite/SqliteDbFirst.cs | 13 ++++++++- 30 files changed, 616 insertions(+), 17 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..5ca74890 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -527,14 +520,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs index 5ce6d981..901ec1c6 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.MySqlConnector var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); } + + [Fact] + public void ExistsTable() + { + var fsql = g.mysql; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_mysqlconnector.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_mysqlconnector.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_mysqlconnector.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_mysqlconnector.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("cccddd_mysqlconnector.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_mysqlconnector.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "cccddd_mysqlconnector.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_mysqlconnector.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_mysqlconnector.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table cccddd_mysqlconnector.test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs index 7c40e69d..12dee40a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.Odbc.Dameng var t2 = g.dameng.DbFirst.GetTablesByDatabase(); //var tb = g.dameng.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + + [Fact] + public void ExistsTable() + { + var fsql = g.dameng; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("1user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "1user.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("1user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"1USER\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs index eb3dc40b..0098989e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs @@ -18,5 +18,32 @@ namespace FreeSql.Tests.Odbc.KingbaseES var t2 = g.kingbaseES.DbFirst.GetTablesByDatabase(); //var tb = g.kingbaseES.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + + [Fact] + public void ExistsTable() + { + var fsql = g.kingbaseES; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "tbexts.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"TBEXTS\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs index a12f5ab3..1a687cbc 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.Odbc.MySql var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); } + + [Fact] + public void ExistsTable() + { + var fsql = g.mysql; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_odbc.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "cccddd_odbc.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_odbc.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table cccddd_odbc.test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs index 9b12a2c7..5012ceee 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.Odbc.Oracle var t2 = g.oracle.DbFirst.GetTablesByDatabase(); //var tb = g.oracle.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + + [Fact] + public void ExistsTable() + { + var fsql = g.oracle; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("1odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("11odbcuser.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "1odbc.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("1odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"1ODBC\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs index 1abfd208..70892d7c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -25,5 +25,32 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var tb_identity = t2.Where(a => a.Name == "test_new").FirstOrDefault(); } + + [Fact] + public void ExistsTable() + { + var fsql = g.pgsql; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "tbexts.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"tbexts\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs index c52f6e28..90b3e2d8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs @@ -22,5 +22,32 @@ namespace FreeSql.Tests.Odbc.SqlServer var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(); } + + [Fact] + public void ExistsTable() + { + var fsql = g.sqlserver; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("dbo.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("dbo.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("dbo.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.True(fsql.DbFirst.ExistsTable("dbo.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "xxxtb.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("xxxtb.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table xxxtb.test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs index 833dff93..4e6698b9 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.Dameng var t2 = g.dameng.DbFirst.GetTablesByDatabase(); //var tb = g.dameng.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + + [Fact] + public void ExistsTable() + { + var fsql = g.dameng; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("2user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("2user.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("2user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("2user.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("2user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("2user.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "2user.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("2user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("2user.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"2USER\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs index fc0859ae..9e2fa376 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.MySql var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); } + + [Fact] + public void ExistsTable() + { + var fsql = g.mysql; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("cccddd.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("cccddd.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("cccddd.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.True(fsql.DbFirst.ExistsTable("cccddd.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("cccddd.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("cccddd.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "cccddd.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("cccddd.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("cccddd.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table cccddd.test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs index 53bd72fb..19fc547d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.Oracle var t2 = g.oracle.DbFirst.GetTablesByDatabase(); //var tb = g.oracle.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + + [Fact] + public void ExistsTable() + { + var fsql = g.oracle; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("1user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "1user.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("1user.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1user.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"1USER\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs index a41e6896..507694a5 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -26,5 +26,32 @@ namespace FreeSql.Tests.PostgreSQL var tb_identity = t2.Where(a => a.Name == "test_new").FirstOrDefault(); } + + [Fact] + public void ExistsTable() + { + var fsql = g.pgsql; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "tbexts.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"tbexts\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs index 12b7a897..bd26596a 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.ShenTong var t2 = g.shentong.DbFirst.GetTablesByDatabase(g.shentong.DbFirst.GetDatabases()[0]); } + + [Fact] + public void ExistsTable() + { + var fsql = g.shentong; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "tbexts.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"TBEXTS\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs index c78eebe7..8a5b251a 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs @@ -31,5 +31,32 @@ namespace FreeSql.Tests.SqlServer var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(); } + + [Fact] + public void ExistsTable() + { + var fsql = g.sqlserver; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("dbo.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("dbo.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("dbo.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.True(fsql.DbFirst.ExistsTable("dbo.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "xxxtb.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("xxxtb.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table xxxtb.test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs index 8725e453..0f7d304d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs @@ -21,5 +21,32 @@ namespace FreeSql.Tests.Sqlite var t2 = g.sqlite.DbFirst.GetTablesByDatabase(); } + + [Fact] + public void ExistsTable() + { + var fsql = g.sqlite; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("main.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("main.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("main.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("main.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "xxxtb.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table xxxtb.test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index ea460a59..bc504527 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3184,6 +3184,14 @@ + + + 判断表是否存在 + + 表名,如:dbo.table1 + 是否忽略大小写 + + 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert diff --git a/FreeSql/Interface/IDbFirst.cs b/FreeSql/Interface/IDbFirst.cs index 1c444593..3a385384 100644 --- a/FreeSql/Interface/IDbFirst.cs +++ b/FreeSql/Interface/IDbFirst.cs @@ -75,5 +75,15 @@ namespace FreeSql /// /// List GetEnumsByDatabase(params string[] database); + + /// + /// 判断表是否存在 + /// + /// 表名,如:dbo.table1 + /// 是否忽略大小写 + /// + bool ExistsTable(string name, bool ignoreCase = true); + + //DbTableInfo GetTableByName(string name); } } diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index 49c7ddfb..d3525e7c 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -212,6 +212,25 @@ namespace FreeSql.Dameng return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) + { + var userId = (_orm.Ado.MasterPool as DamengConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = DamengConnectionPool.GetUserId(conn.Value.ConnectionString); + } + tbname = new[] { userId, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from all_tab_comments where {(ignoreCase ? "lower(owner)" : "owner")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(table_name)" : "table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database2) { var loc1 = new List(); diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 7253870b..03923720 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -148,6 +148,24 @@ namespace FreeSql.MySql return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) + { + var database = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + database = conn.Value.Database; + } + tbname = new[] { database, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" SELECT 1 FROM information_schema.TABLES WHERE {(ignoreCase ? "lower(table_schema)" : "table_schema")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(table_name)" : "table_name")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database2) { var loc1 = new List(); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index e941e104..5b3d808f 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -212,6 +212,25 @@ namespace FreeSql.Odbc.Dameng return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) + { + var userId = (_orm.Ado.MasterPool as OdbcDamengConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = OdbcDamengConnectionPool.GetUserId(conn.Value.ConnectionString); + } + tbname = new[] { userId, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from all_tab_comments where {(ignoreCase ? "lower(owner)" : "owner")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(table_name)" : "table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database2) { var loc1 = new List(); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs index cd15ba6a..b7f0853f 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs @@ -110,6 +110,16 @@ namespace FreeSql.Odbc.KingbaseES return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from sys_tables a inner join sys_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database) { var olddatabase = ""; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index 66734859..07661662 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -114,6 +114,24 @@ namespace FreeSql.Odbc.MySql return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) + { + var database = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + database = conn.Value.Database; + } + tbname = new[] { database, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" SELECT 1 FROM information_schema.TABLES WHERE {(ignoreCase ? "lower(table_schema)" : "table_schema")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(table_name)" : "table_name")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database2) { var loc1 = new List(); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index 23c409a4..f426d221 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -166,6 +166,25 @@ namespace FreeSql.Odbc.Oracle return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) + { + var userId = (_orm.Ado.MasterPool as OdbcOracleConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = OdbcOracleConnectionPool.GetUserId(conn.Value.ConnectionString); + } + tbname = new[] { userId, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from all_tab_comments where {(ignoreCase ? "lower(owner)" : "owner")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(table_name)" : "table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database2) { var loc1 = new List(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 1da4d276..e3e66b20 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -122,6 +122,16 @@ namespace FreeSql.Odbc.PostgreSQL return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database) { var olddatabase = ""; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index 7c5eb871..d958b0bb 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -107,6 +107,31 @@ namespace FreeSql.Odbc.SqlServer return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { olddatabase, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { olddatabase, tbname[0], tbname[1] }; + tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $@" +use [{tbname[0]}]; +select +1 +from sys.tables a +inner join sys.schemas b on b.schema_id = a.schema_id +where lower(b.name) = {_commonUtils.FormatSql("{0}", tbname[1])} and lower(a.name) = {_commonUtils.FormatSql("{0}", tbname[2])} +; +use [{olddatabase}]; +"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database) { var olddatabase = ""; diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index fb01732d..f8e7e3d1 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -166,6 +166,25 @@ namespace FreeSql.Oracle return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) + { + var userId = (_orm.Ado.MasterPool as OracleConnectionPool)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = OracleConnectionPool.GetUserId(conn.Value.ConnectionString); + } + tbname = new[] { userId, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from all_tab_comments where {(ignoreCase ? "lower(owner)" : "owner")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(table_name)" : "table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database2) { var loc1 = new List(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index 6420a5c5..b5681333 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -232,6 +232,16 @@ namespace FreeSql.PostgreSQL return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database) { var olddatabase = ""; diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs index 99dacadf..1d573b84 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs @@ -123,6 +123,22 @@ namespace FreeSql.ShenTong return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { "PUBLIC", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $@" +select +1 +from sys_class a +inner join sys_namespace b on b.oid = a.relnamespace +where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.relname)" : "a.relname")} = {_commonUtils.FormatSql("{0}", tbname[1])} and a.relkind in ('r') +"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database) { var olddatabase = ""; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index ff0dd7e4..f376bf61 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -110,6 +110,31 @@ namespace FreeSql.SqlServer return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { olddatabase, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { olddatabase, tbname[0], tbname[1] }; + tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $@" +use [{tbname[0]}]; +select +1 +from sys.tables a +inner join sys.schemas b on b.schema_id = a.schema_id +where lower(b.name) = {_commonUtils.FormatSql("{0}", tbname[1])} and lower(a.name) = {_commonUtils.FormatSql("{0}", tbname[2])} +; +use [{olddatabase}]; +"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database) { var olddatabase = ""; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs index 38b64903..e3fe5077 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs @@ -149,6 +149,16 @@ namespace FreeSql.Sqlite return _orm.Ado.ExecuteArray("PRAGMA database_list").Select(a => string.Concat(a[1])).ToList(); } + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $@" select 1 from {_commonUtils.QuoteSqlName(tbname[0])}.sqlite_master where type = 'table' and {(ignoreCase ? "lower(tbl_name)" : "tbl_name")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public List GetTablesByDatabase(params string[] database2) { var loc1 = new List(); @@ -194,7 +204,8 @@ namespace FreeSql.Sqlite foreach (var db in database) { - var sql = $@"select + var sql = $@" +select '{db}.' || tbl_name, '{db}', tbl_name, From 0d832a5a231cff9071eae867e64816cc73916933 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 11 Aug 2020 23:23:54 +0800 Subject: [PATCH 0815/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IDbFirst.Get?= =?UTF-8?q?TableByName=20=E6=96=B9=E6=B3=95=E8=8E=B7=E5=8F=96=E5=8D=95?= =?UTF-8?q?=E8=A1=A8=E4=BF=A1=E6=81=AF=EF=BC=8C=E5=8C=85=E6=8B=AC=E5=88=97?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E3=80=81=E4=B8=BB=E9=94=AE=E3=80=81=E5=94=AF?= =?UTF-8?q?=E4=B8=80=E9=94=AE=E3=80=81=E7=B4=A2=E5=BC=95=E3=80=81=E5=A4=87?= =?UTF-8?q?=E6=B3=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlDbFirstTest.cs | 18 ++- .../Dameng/DamengDbFirstTest.cs | 19 ++- .../KingbaseES/KingbaseESDbFirstTest.cs | 17 ++- .../MySql/MySqlDbFirstTest.cs | 18 ++- .../Oracle/OracleDbFirstTest.cs | 19 ++- .../PostgreSQL/PostgreSQLDbFirstTest.cs | 23 ++-- .../SqlServer/SqlServerDbFirstTest.cs | 18 ++- .../FreeSql.Tests/Dameng/DamengDbFirstTest.cs | 19 ++- .../FreeSql.Tests/MySql/MySqlDbFirstTest.cs | 18 ++- .../FreeSql.Tests/Oracle/OracleDbFirstTest.cs | 19 ++- .../PostgreSQL/PostgreSQLDbFirstTest.cs | 22 ++-- .../ShenTong/ShenTongDbFirstTest.cs | 18 ++- .../SqlServer/SqlServerDbFirstTest.cs | 18 ++- .../FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs | 18 ++- FreeSql/FreeSql.xml | 24 ++-- FreeSql/Interface/IDbFirst.cs | 26 ++-- .../FreeSql.Provider.Dameng/DamengDbFirst.cs | 110 ++++++++++------- .../FreeSql.Provider.MySql/MySqlDbFirst.cs | 112 +++++++++++------- .../Dameng/OdbcDamengDbFirst.cs | 110 ++++++++++------- .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 2 +- .../KingbaseES/OdbcKingbaseESDbFirst.cs | 86 ++++++++------ .../MySql/OdbcMySqlDbFirst.cs | 112 +++++++++++------- .../Oracle/OdbcOracleDbFirst.cs | 110 ++++++++++------- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 84 +++++++------ .../SqlServer/OdbcSqlServerDbFirst.cs | 102 +++++++++------- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 110 ++++++++++------- .../Curd/PostgreSQLUpdate.cs | 2 +- .../PostgreSQLDbFirst.cs | 84 +++++++------ .../Curd/ShenTongUpdate.cs | 2 +- .../ShenTongDbFirst.cs | 80 +++++++------ .../SqlServerDbFirst.cs | 100 +++++++++------- .../FreeSql.Provider.Sqlite/SqliteDbFirst.cs | 73 +++++++----- 33 files changed, 994 insertions(+), 601 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs index 901ec1c6..ddf2f1a0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlDbFirstTest.cs @@ -9,17 +9,29 @@ namespace FreeSql.Tests.MySqlConnector [Fact] public void GetDatabases() { - var t1 = g.mysql.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); + Assert.True(t2.Count > 0); + } + [Fact] + public void GetTableByName() + { + var fsql = g.mysql; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("cccddd_mysqlconnector.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs index 12dee40a..ee4a2119 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengDbFirstTest.cs @@ -9,19 +9,32 @@ namespace FreeSql.Tests.Odbc.Dameng [Fact] public void GetDatabases() { - var t1 = g.dameng.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.dameng.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); //var tb = g.dameng.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + [Fact] + public void GetTableByName() + { + var fsql = g.dameng; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("2user.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + [Fact] public void ExistsTable() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs index 0098989e..cebd3ac1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESDbFirstTest.cs @@ -16,7 +16,22 @@ namespace FreeSql.Tests.Odbc.KingbaseES public void GetTablesByDatabase() { var t2 = g.kingbaseES.DbFirst.GetTablesByDatabase(); - //var tb = g.kingbaseES.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); + Assert.True(t2.Count > 0); + } + + [Fact] + public void GetTableByName() + { + var fsql = g.kingbaseES; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("public.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs index 1a687cbc..613ca970 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlDbFirstTest.cs @@ -9,17 +9,29 @@ namespace FreeSql.Tests.Odbc.MySql [Fact] public void GetDatabases() { - var t1 = g.mysql.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); + Assert.True(t2.Count > 0); + } + [Fact] + public void GetTableByName() + { + var fsql = g.mysql; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("cccddd_odbc.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs index 5012ceee..1b1eb6f3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleDbFirstTest.cs @@ -9,19 +9,32 @@ namespace FreeSql.Tests.Odbc.Oracle [Fact] public void GetDatabases() { - var t1 = g.oracle.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.oracle.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); //var tb = g.oracle.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + [Fact] + public void GetTableByName() + { + var fsql = g.oracle; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("1odbc.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + [Fact] public void ExistsTable() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs index 70892d7c..ca76dae8 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -10,20 +10,29 @@ namespace FreeSql.Tests.Odbc.PostgreSQL [Fact] public void GetDatabases() { - var t1 = g.pgsql.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { + var t2 = g.pgsql.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); + } - var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[2]); - - var tb_alltype = t2.Where(a => a.Name == "tb_alltype").FirstOrDefault(); - - var tb_identity = t2.Where(a => a.Name == "test_new").FirstOrDefault(); + [Fact] + public void GetTableByName() + { + var fsql = g.pgsql; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("public.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs index 90b3e2d8..95ebf376 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerDbFirstTest.cs @@ -10,17 +10,29 @@ namespace FreeSql.Tests.Odbc.SqlServer [Fact] public void GetDatabases() { - var t1 = g.sqlserver.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); + } + [Fact] + public void GetTableByName() + { + var fsql = g.sqlserver; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("dbo.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs index 4e6698b9..8ae7578a 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs @@ -9,19 +9,32 @@ namespace FreeSql.Tests.Dameng [Fact] public void GetDatabases() { - var t1 = g.dameng.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.dameng.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); //var tb = g.dameng.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + [Fact] + public void GetTableByName() + { + var fsql = g.dameng; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("2user.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + [Fact] public void ExistsTable() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs index 9e2fa376..b6e9c337 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs @@ -9,17 +9,29 @@ namespace FreeSql.Tests.MySql [Fact] public void GetDatabases() { - var t1 = g.mysql.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); + Assert.True(t2.Count > 0); + } + [Fact] + public void GetTableByName() + { + var fsql = g.mysql; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("cccddd.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs index 19fc547d..c3cfaaa0 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs @@ -9,19 +9,32 @@ namespace FreeSql.Tests.Oracle [Fact] public void GetDatabases() { - var t1 = g.oracle.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.oracle.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); //var tb = g.oracle.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); } + [Fact] + public void GetTableByName() + { + var fsql = g.oracle; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("1user.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + [Fact] public void ExistsTable() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs index 507694a5..bd7dfcb5 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -10,21 +10,29 @@ namespace FreeSql.Tests.PostgreSQL [Fact] public void GetDatabases() { - var t1 = g.pgsql.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[1]); + Assert.True(t2.Count > 0); + } - var tb_alltype = t2.Where(a => a.Name == "tb_alltype").FirstOrDefault(); - - var tb_identity = t2.Where(a => a.Name == "test_new").FirstOrDefault(); - + [Fact] + public void GetTableByName() + { + var fsql = g.pgsql; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("public.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs index bd26596a..db4bdd3a 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongDbFirstTest.cs @@ -9,9 +9,7 @@ namespace FreeSql.Tests.ShenTong [Fact] public void GetDatabases() { - var t1 = g.shentong.DbFirst.GetDatabases(); - } [Fact] @@ -19,7 +17,23 @@ namespace FreeSql.Tests.ShenTong { var t1 = g.shentong.DbFirst.GetTablesByDatabase(); var t2 = g.shentong.DbFirst.GetTablesByDatabase(g.shentong.DbFirst.GetDatabases()[0]); + Assert.True(t1.Count > 0); + Assert.True(t2.Count > 0); + } + [Fact] + public void GetTableByName() + { + var fsql = g.shentong; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("public.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs index 8a5b251a..21917375 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs @@ -19,17 +19,29 @@ namespace FreeSql.Tests.SqlServer [Fact] public void GetDatabases() { - var t1 = g.sqlserver.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); + } + [Fact] + public void GetTableByName() + { + var fsql = g.sqlserver; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("dbo.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs index 0f7d304d..e152584f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteDbFirstTest.cs @@ -9,17 +9,29 @@ namespace FreeSql.Tests.Sqlite [Fact] public void GetDatabases() { - var t1 = g.sqlite.DbFirst.GetDatabases(); - } [Fact] public void GetTablesByDatabase() { - var t2 = g.sqlite.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); + } + [Fact] + public void GetTableByName() + { + var fsql = g.sqlite; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("main.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); } [Fact] diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index bc504527..4f5d13e2 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3121,6 +3121,22 @@ + + + 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 + + 表名,如:dbo.table1 + 是否忽略大小写 + + + + + 判断表是否存在 + + 表名,如:dbo.table1 + 是否忽略大小写 + + 获取数据库枚举类型int值 @@ -3184,14 +3200,6 @@ - - - 判断表是否存在 - - 表名,如:dbo.table1 - 是否忽略大小写 - - 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert diff --git a/FreeSql/Interface/IDbFirst.cs b/FreeSql/Interface/IDbFirst.cs index 3a385384..de614453 100644 --- a/FreeSql/Interface/IDbFirst.cs +++ b/FreeSql/Interface/IDbFirst.cs @@ -19,6 +19,22 @@ namespace FreeSql /// List GetTablesByDatabase(params string[] database); + /// + /// 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 + /// + /// 表名,如:dbo.table1 + /// 是否忽略大小写 + /// + DbTableInfo GetTableByName(string name, bool ignoreCase = true); + + /// + /// 判断表是否存在 + /// + /// 表名,如:dbo.table1 + /// 是否忽略大小写 + /// + bool ExistsTable(string name, bool ignoreCase = true); + /// /// 获取数据库枚举类型int值 /// @@ -75,15 +91,5 @@ namespace FreeSql /// /// List GetEnumsByDatabase(params string[] database); - - /// - /// 判断表是否存在 - /// - /// 表名,如:dbo.table1 - /// 是否忽略大小写 - /// - bool ExistsTable(string name, bool ignoreCase = true); - - //DbTableInfo GetTableByName(string name); } } diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index d3525e7c..9f20d709 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -231,21 +231,36 @@ namespace FreeSql.Dameng return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database2) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var loc1 = new List(); var loc2 = new Dictionary(); var loc3 = new Dictionary>(); - var database = database2?.ToArray(); - - if (database == null || database.Any() == false) + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) + { + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + tbname = new[] { userUsers, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) { var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); if (string.IsNullOrEmpty(userUsers)) return loc1; database = new[] { userUsers }; } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); - var sql = string.Format(@" + var sql = $@" select a.owner || '.' || a.table_name, a.owner, @@ -254,7 +269,7 @@ b.comments, 'TABLE' from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' -where a.owner in ({0})", databaseIn); +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -315,7 +330,7 @@ where a.owner in ({0})", databaseIn); } loc8.Append(")"); - sql = string.Format(@" + sql = $@" select a.owner || '.' || a.table_name, a.column_name, @@ -330,8 +345,8 @@ b.comments, a.data_default from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner in ({1}) and {0} -", loc8, databaseIn); +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -386,7 +401,7 @@ where a.owner in ({1}) and {0} loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); } - sql = string.Format(@" + sql = $@" select a.table_owner || '.' || a.table_name, c.column_name, @@ -401,8 +416,8 @@ all_ind_columns c where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.table_owner in ({1}) and {0} -", loc8, databaseIn); +and {(ignoreCase ? "lower(a.table_owner)" : "a.table_owner")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -454,7 +469,9 @@ and a.table_owner in ({1}) and {0} } } - sql = string.Format(@" + if (tbname == null) + { + sql = $@" select a.owner || '.' || a.table_name, c.column_name, @@ -488,43 +505,44 @@ and a.owner = c.owner and a.table_name = c.table_name and b.owner = d.owner and b.table_name = d.table_name -and a.owner in ({1}) and {0} -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; +and {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) - { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) + var fkColumns = new Dictionary>(); + foreach (var row in ds) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs index 03923720..5ec430ec 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlDbFirst.cs @@ -166,14 +166,30 @@ namespace FreeSql.MySql return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database2) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var loc1 = new List(); var loc2 = new Dictionary(); var loc3 = new Dictionary>(); - var database = database2?.ToArray(); - - if (database == null || database.Any() == false) + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) + { + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + if (string.IsNullOrEmpty(conn.Value.Database)) return loc1; + tbname = new[] { conn.Value.Database, tbname[0] }; + } + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) { using (var conn = _orm.Ado.MasterPool.Get()) { @@ -181,8 +197,9 @@ namespace FreeSql.MySql database = new[] { conn.Value.Database }; } } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); - var sql = string.Format(@" + var sql = $@" select concat(a.table_schema, '.', a.table_name) 'id', a.table_schema 'schema', @@ -190,7 +207,7 @@ a.table_name 'table', a.table_comment, a.table_type 'type' from information_schema.tables a -where a.table_schema in ({0})", databaseIn); +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -251,7 +268,7 @@ where a.table_schema in ({0})", databaseIn); } loc8.Append(")"); - sql = string.Format(@" + sql = $@" select concat(a.table_schema, '.', a.table_name), a.column_name, @@ -263,8 +280,8 @@ case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', a.column_comment 'comment', a.column_default 'default_value' from information_schema.columns a -where a.table_schema in ({1}) and {0} -", loc8, databaseIn); +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -305,7 +322,7 @@ where a.table_schema in ({1}) and {0} loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); } - sql = string.Format(@" + sql = $@" select concat(a.table_schema, '.', a.table_name) 'table_id', a.column_name, @@ -315,8 +332,8 @@ case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' from information_schema.statistics a -where a.table_schema in ({1}) and {0} -", loc8, databaseIn); +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -367,7 +384,9 @@ where a.table_schema in ({1}) and {0} } } - sql = string.Format(@" + if (tbname == null) + { + sql = $@" select concat(a.constraint_schema, '.', a.table_name) 'table_id', a.column_name, @@ -376,43 +395,44 @@ concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', 1 'IsForeignKey', a.referenced_column_name 'ref_column' from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and {0} and not isnull(position_in_unique_constraint) -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; +where {(ignoreCase ? "lower(a.constraint_schema)" : "a.constraint_schema")} in ({databaseIn}) and {loc8} and not isnull(position_in_unique_constraint) +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) - { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) + var fkColumns = new Dictionary>(); + foreach (var row in ds) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 5b3d808f..a7b6d741 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -231,21 +231,36 @@ namespace FreeSql.Odbc.Dameng return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database2) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var loc1 = new List(); var loc2 = new Dictionary(); var loc3 = new Dictionary>(); - var database = database2?.ToArray(); - - if (database == null || database.Any() == false) + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) + { + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + tbname = new[] { userUsers, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) { var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); if (string.IsNullOrEmpty(userUsers)) return loc1; database = new[] { userUsers }; } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); - var sql = string.Format(@" + var sql = $@" select a.owner || '.' || a.table_name, a.owner, @@ -254,7 +269,7 @@ b.comments, 'TABLE' from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' -where a.owner in ({0})", databaseIn); +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -315,7 +330,7 @@ where a.owner in ({0})", databaseIn); } loc8.Append(")"); - sql = string.Format(@" + sql = $@" select a.owner || '.' || a.table_name, a.column_name, @@ -330,8 +345,8 @@ b.comments, a.data_default from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner in ({1}) and {0} -", loc8, databaseIn); +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -386,7 +401,7 @@ where a.owner in ({1}) and {0} loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); } - sql = string.Format(@" + sql = $@" select a.table_owner || '.' || a.table_name, c.column_name, @@ -401,8 +416,8 @@ all_ind_columns c where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.table_owner in ({1}) and {0} -", loc8, databaseIn); +and {(ignoreCase ? "lower(a.table_owner)" : "a.table_owner")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -454,7 +469,9 @@ and a.table_owner in ({1}) and {0} } } - sql = string.Format(@" + if (tbname == null) + { + sql = $@" select a.owner || '.' || a.table_name, c.column_name, @@ -488,43 +505,44 @@ and a.owner = c.owner and a.table_name = c.table_name and b.owner = d.owner and b.table_name = d.table_name -and a.owner in ({1}) and {0} -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; +and {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) - { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) + var fkColumns = new Dictionary>(); + foreach (var row in ds) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index b0eab467..44f5013d 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -18,7 +18,7 @@ namespace FreeSql.Odbc.KingbaseES { } - internal string InternalTableAlias; + internal string InternalTableAlias { get; set; } internal StringBuilder InternalSbSet => _set; internal StringBuilder InternalSbSetIncr => _setIncr; internal Dictionary InternalIgnore => _ignore; diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs index b7f0853f..006d7f34 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESDbFirst.cs @@ -116,20 +116,31 @@ namespace FreeSql.Odbc.KingbaseES var tbname = _commonUtils.SplitTableName(name); if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); - var sql = $" select 1 from sys_tables a inner join sys_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + var sql = $" select 1 from sys_tables a inner join sys_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}"; return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var olddatabase = ""; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { olddatabase = conn.Value.Database; } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; - var tables = new List(); + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { olddatabase }; + } + var tables = new List(); foreach (var db in dbs) { if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; @@ -139,7 +150,7 @@ namespace FreeSql.Odbc.KingbaseES var loc3 = new Dictionary>(); var sql = $@" -select +{(tbname == null ? "" : $"select * from (")}select b.nspname || '.' || a.tablename, a.schemaname, a.tablename , @@ -165,7 +176,7 @@ inner join sys_namespace b on b.oid = a.relnamespace left join sys_description d on d.objoid = a.oid and objsubid = 0 where b.nspname not in ('SYS_CATALOG', 'INFORMATION_SCHEMA', 'TOPOLOGY', 'SYSAUDIT', 'SYSLOGICAL', 'SYS_TEMP_1', 'SYS_TOAST', 'SYS_TOAST_TEMP_1', 'XLOG_RECORD_READ') and a.relkind in ('m','v') and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS') -"; +{(tbname == null ? "" : $") ft_dbf where {(ignoreCase ? "lower(schemaname)" : "schemaname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(tablename)" : "tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -381,7 +392,9 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname") } } - sql = $@" + if (tbname == null) + { + sql = $@" select ns.nspname || '.' || b.relname as table_id, array(select attname from sys_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, @@ -398,39 +411,40 @@ inner join sys_namespace ns on ns.oid = b.relnamespace inner join sys_namespace ns2 on ns2.oid = c.relnamespace where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (object[] row in ds) - { - var table_id = string.Concat(row[0]); - var column = row[1] as string[]; - var fk_id = string.Concat(row[2]); - var ref_table_id = string.Concat(row[3]); - var is_foreign_key = string.Concat(row[4]) == "1"; - var referenced_column = row[5] as string[]; - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); - - if (loc2.ContainsKey(ref_table_id) == false) continue; - - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); - - for (int a = 0; a < column.Length; a++) + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) { - loc13.Columns.Add(loc3[table_id][column[a]]); - loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs index 07661662..b655037c 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlDbFirst.cs @@ -132,14 +132,30 @@ namespace FreeSql.Odbc.MySql return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database2) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var loc1 = new List(); var loc2 = new Dictionary(); var loc3 = new Dictionary>(); - var database = database2?.ToArray(); - - if (database == null || database.Any() == false) + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) + { + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + if (string.IsNullOrEmpty(conn.Value.Database)) return loc1; + tbname = new[] { conn.Value.Database, tbname[0] }; + } + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) { using (var conn = _orm.Ado.MasterPool.Get()) { @@ -147,8 +163,9 @@ namespace FreeSql.Odbc.MySql database = new[] { conn.Value.Database }; } } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); - var sql = string.Format(@" + var sql = $@" select concat(a.table_schema, '.', a.table_name) 'id', a.table_schema 'schema', @@ -156,7 +173,7 @@ a.table_name 'table', a.table_comment, a.table_type 'type' from information_schema.tables a -where a.table_schema in ({0})", databaseIn); +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -217,7 +234,7 @@ where a.table_schema in ({0})", databaseIn); } loc8.Append(")"); - sql = string.Format(@" + sql = $@" select concat(a.table_schema, '.', a.table_name), a.column_name, @@ -229,8 +246,8 @@ case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity', a.column_comment 'comment', a.column_default 'default_value' from information_schema.columns a -where a.table_schema in ({1}) and {0} -", loc8, databaseIn); +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -271,7 +288,7 @@ where a.table_schema in ({1}) and {0} loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); } - sql = string.Format(@" + sql = $@" select concat(a.table_schema, '.', a.table_name) 'table_id', a.column_name, @@ -281,8 +298,8 @@ case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' from information_schema.statistics a -where a.table_schema in ({1}) and {0} -", loc8, databaseIn); +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -333,7 +350,9 @@ where a.table_schema in ({1}) and {0} } } - sql = string.Format(@" + if (tbname == null) + { + sql = $@" select concat(a.constraint_schema, '.', a.table_name) 'table_id', a.column_name, @@ -342,43 +361,44 @@ concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', 1 'IsForeignKey', a.referenced_column_name 'ref_column' from information_schema.key_column_usage a -where a.constraint_schema in ({1}) and {0} and not isnull(position_in_unique_constraint) -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; +where {(ignoreCase ? "lower(a.constraint_schema)" : "a.constraint_schema")} in ({databaseIn}) and {loc8} and not isnull(position_in_unique_constraint) +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) - { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) + var fkColumns = new Dictionary>(); + foreach (var row in ds) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index f426d221..c9f477cb 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -185,21 +185,36 @@ namespace FreeSql.Odbc.Oracle return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database2) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var loc1 = new List(); var loc2 = new Dictionary(); var loc3 = new Dictionary>(); - var database = database2?.ToArray(); - - if (database == null || database.Any() == false) + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) + { + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + tbname = new[] { userUsers, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) { var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); if (string.IsNullOrEmpty(userUsers)) return loc1; database = new[] { userUsers }; } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); - var sql = string.Format(@" + var sql = $@" select a.owner || '.' || a.table_name, a.owner, @@ -208,7 +223,7 @@ b.comments, 'TABLE' from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' -where a.owner in ({0})", databaseIn); +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -288,7 +303,7 @@ BEGIN RETURN TEXT_C1; END;"); - sql = string.Format(@" + sql = $@" select a.owner || '.' || a.table_name, a.column_name, @@ -303,8 +318,8 @@ to_char(b.comments), nvl(FREESQL_LONG_TO_CHAR_DEFAULT(a.table_name, a.column_name),'') from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner in ({1}) and {0} -", loc8, databaseIn); +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -360,7 +375,7 @@ where a.owner in ({1}) and {0} } OdbcOracleCodeFirst.CreateOracleFunction(_orm); - sql = string.Format(@" + sql = $@" select a.table_owner || '.' || a.table_name, nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), @@ -375,8 +390,8 @@ all_ind_columns c where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.table_owner in ({1}) and {0} -", loc8, databaseIn); +and {(ignoreCase ? "lower(a.table_owner)" : "a.table_owner")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -428,7 +443,9 @@ and a.table_owner in ({1}) and {0} } } - sql = string.Format(@" + if (tbname == null) + { + sql = $@" select a.owner || '.' || a.table_name, c.column_name, @@ -462,43 +479,44 @@ and a.owner = c.owner    and a.table_name = c.table_name    and b.owner = d.owner    and b.table_name = d.table_name -and a.owner in ({1}) and {0} -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; +and {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) - { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) + var fkColumns = new Dictionary>(); + foreach (var row in ds) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index f4c2cbc2..b713b56b 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -18,7 +18,7 @@ namespace FreeSql.Odbc.PostgreSQL { } - internal string InternalTableAlias; + internal string InternalTableAlias { get; set; } internal StringBuilder InternalSbSet => _set; internal StringBuilder InternalSbSetIncr => _setIncr; internal Dictionary InternalIgnore => _ignore; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index e3e66b20..ef6fc7bf 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -128,11 +128,14 @@ namespace FreeSql.Odbc.PostgreSQL var tbname = _commonUtils.SplitTableName(name); if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); - var sql = $" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + var sql = $" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}"; return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var olddatabase = ""; var is96 = true; @@ -141,7 +144,15 @@ namespace FreeSql.Odbc.PostgreSQL olddatabase = conn.Value.Database; is96 = PgVersionIs96(conn.Value.ServerVersion); } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { olddatabase }; + } var tables = new List(); foreach (var db in dbs) @@ -153,7 +164,7 @@ namespace FreeSql.Odbc.PostgreSQL var loc3 = new Dictionary>(); var sql = $@" -select +{(tbname == null ? "" : $"select * from (")}select b.nspname || '.' || a.tablename, a.schemaname, a.tablename , @@ -179,7 +190,7 @@ inner join pg_namespace b on b.oid = a.relnamespace left join pg_description d on d.objoid = a.oid and objsubid = 0 where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('m','v') and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews') -"; +{(tbname == null ? "" : $") ft_dbf where {(ignoreCase ? "lower(schemaname)" : "schemaname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(tablename)" : "tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -396,7 +407,9 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname") } } - sql = $@" + if (tbname == null) + { + sql = $@" select ns.nspname || '.' || b.relname as table_id, array(select attname from pg_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, @@ -413,39 +426,40 @@ inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_namespace ns2 on ns2.oid = c.relnamespace where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (object[] row in ds) - { - var table_id = string.Concat(row[0]); - var column = row[1] as string[]; - var fk_id = string.Concat(row[2]); - var ref_table_id = string.Concat(row[3]); - var is_foreign_key = string.Concat(row[4]) == "1"; - var referenced_column = row[5] as string[]; - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); - - if (loc2.ContainsKey(ref_table_id) == false) continue; - - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); - - for (int a = 0; a < column.Length; a++) + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) { - loc13.Columns.Add(loc3[table_id][column[a]]); - loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs index d958b0bb..146936a0 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerDbFirst.cs @@ -7,7 +7,6 @@ using System.Data; using System.Data.Odbc; using System.Linq; using System.Text; -using System.Text.RegularExpressions; namespace FreeSql.Odbc.SqlServer { @@ -125,21 +124,32 @@ select 1 from sys.tables a inner join sys.schemas b on b.schema_id = a.schema_id -where lower(b.name) = {_commonUtils.FormatSql("{0}", tbname[1])} and lower(a.name) = {_commonUtils.FormatSql("{0}", tbname[2])} +where lower(b.name)={_commonUtils.FormatSql("{0}", tbname[1])} and lower(a.name)={_commonUtils.FormatSql("{0}", tbname[2])} ; use [{olddatabase}]; "; return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); - public List GetTablesByDatabase(params string[] database) + public List GetTables(string[] database, string tablename, bool ignoreCase) { var olddatabase = ""; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { olddatabase = conn.Value.Database; } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { olddatabase, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { olddatabase, tbname[0], tbname[1] }; + tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { tbname[0] }; + } var tables = new List(); foreach (var db in dbs) @@ -152,6 +162,7 @@ use [{olddatabase}]; var sql = $@" use [{db}]; +select * from ( select a.Object_id ,b.name 'Owner' @@ -180,8 +191,8 @@ select from sys.procedures a inner join sys.schemas b on b.schema_id = a.schema_id where a.type = 'P' and charindex('diagram', a.name) = 0 -order by type desc, b.name, a.name -; +) ft_dbf{(tbname == null ? "" : _commonUtils.FormatSql(" where lower([owner])={0} and lower([Name])={1}", new[] { tbname[1], tbname[2] }))} +order by type desc, [owner], [Name]; use [{olddatabase}]; "; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -264,7 +275,7 @@ isnull(e.name,'') + '.' + isnull(d.name,'') else cast(a.max_length as varchar) end + ')' when b.name in ('Numeric', 'Decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')' else '' end as 'SqlType' -,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'Comment' +,( select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'Comment' {0} a inner join sys.types b on b.user_type_id = a.user_type_id left join sys.tables d on d.object_id = a.object_id @@ -392,7 +403,9 @@ use [{olddatabase}]; } } - sql = $@" + if (tbname == null) + { + sql = $@" use [{db}]; select b.object_id 'Object_id' @@ -412,47 +425,48 @@ where {loc8.ToString().Replace("a.table_name", "b.object_id")} ; use [{olddatabase}]; "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (object[] row in ds) - { - int object_id, referenced_object_id; - int.TryParse(string.Concat(row[0]), out object_id); - var column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - int.TryParse(string.Concat(row[3]), out referenced_object_id); - var is_foreign_key = bool.Parse(string.Concat(row[4])); - var referenced_column = string.Concat(row[5]); - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); - DbColumnInfo loc9 = loc3[object_id][column]; - DbTableInfo loc10 = null; - DbColumnInfo loc11 = null; - bool isThisSln = referenced_object_id != 0; - - if (isThisSln) - { - loc10 = loc2[referenced_object_id]; - loc11 = loc3[referenced_object_id][referenced_column]; - } - else + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) { + int object_id, referenced_object_id; + int.TryParse(string.Concat(row[0]), out object_id); + var column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + int.TryParse(string.Concat(row[3]), out referenced_object_id); + var is_foreign_key = bool.Parse(string.Concat(row[4])); + var referenced_column = string.Concat(row[5]); + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + DbColumnInfo loc9 = loc3[object_id][column]; + DbTableInfo loc10 = null; + DbColumnInfo loc11 = null; + bool isThisSln = referenced_object_id != 0; + if (isThisSln) + { + loc10 = loc2[referenced_object_id]; + loc11 = loc3[referenced_object_id][referenced_column]; + } + else + { + + } + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(object_id, out loc12)) + fkColumns.Add(object_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); } - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(object_id, out loc12)) - fkColumns.Add(object_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index f8e7e3d1..2231f27a 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -185,21 +185,36 @@ namespace FreeSql.Oracle return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database2) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var loc1 = new List(); var loc2 = new Dictionary(); var loc3 = new Dictionary>(); - var database = database2?.ToArray(); - - if (database == null || database.Any() == false) + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) + { + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + tbname = new[] { userUsers, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) { var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); if (string.IsNullOrEmpty(userUsers)) return loc1; database = new[] { userUsers }; } + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); - var sql = string.Format(@" + var sql = $@" select a.owner || '.' || a.table_name, a.owner, @@ -208,7 +223,7 @@ b.comments, 'TABLE' from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' -where a.owner in ({0})", databaseIn); +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -288,7 +303,7 @@ BEGIN RETURN TEXT_C1; END;"); - sql = string.Format(@" + sql = $@" select a.owner || '.' || a.table_name, a.column_name, @@ -303,8 +318,8 @@ to_char(b.comments), nvl(FREESQL_LONG_TO_CHAR_DEFAULT(a.table_name, a.column_name),'') from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner in ({1}) and {0} -", loc8, databaseIn); +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -360,7 +375,7 @@ where a.owner in ({1}) and {0} } OracleCodeFirst.CreateOracleFunction(_orm); - sql = string.Format(@" + sql = $@" select a.table_owner || '.' || a.table_name, nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), @@ -375,8 +390,8 @@ all_ind_columns c where a.index_name = c.index_name and a.table_owner = c.table_owner and a.table_name = c.table_name -and a.table_owner in ({1}) and {0} -", loc8, databaseIn); +and {(ignoreCase ? "lower(a.table_owner)" : "a.table_owner")} in ({databaseIn}) and {loc8} +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -428,7 +443,9 @@ and a.table_owner in ({1}) and {0} } } - sql = string.Format(@" + if (tbname == null) + { + sql = $@" select a.owner || '.' || a.table_name, c.column_name, @@ -462,43 +479,44 @@ and a.owner = c.owner    and a.table_name = c.table_name    and b.owner = d.owner    and b.table_name = d.table_name -and a.owner in ({1}) and {0} -", loc8, databaseIn); - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; +and {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) - { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (database.Length == 1) + var fkColumns = new Dictionary>(); + foreach (var row in ds) { - table_id = table_id.Substring(table_id.IndexOf('.') + 1); - ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); - } - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index cc74c1d1..6991e799 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -18,7 +18,7 @@ namespace FreeSql.PostgreSQL.Curd { } - internal string InternalTableAlias; + internal string InternalTableAlias { get; set; } internal StringBuilder InternalSbSet => _set; internal StringBuilder InternalSbSetIncr => _setIncr; internal Dictionary InternalIgnore => _ignore; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index b5681333..96ebf9bb 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -238,11 +238,14 @@ namespace FreeSql.PostgreSQL var tbname = _commonUtils.SplitTableName(name); if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); - var sql = $" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + var sql = $" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}"; return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var olddatabase = ""; var is96 = true; @@ -251,7 +254,15 @@ namespace FreeSql.PostgreSQL olddatabase = conn.Value.Database; is96 = PgVersionIs96(conn.Value.ServerVersion); } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { olddatabase }; + } var tables = new List(); foreach (var db in dbs) @@ -263,7 +274,7 @@ namespace FreeSql.PostgreSQL var loc3 = new Dictionary>(); var sql = $@" -select +{(tbname == null ? "" : $"select * from (")}select b.nspname || '.' || a.tablename, a.schemaname, a.tablename , @@ -289,7 +300,7 @@ inner join pg_namespace b on b.oid = a.relnamespace left join pg_description d on d.objoid = a.oid and objsubid = 0 where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('m','v') and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews') -"; +{(tbname == null ? "" : $") ft_dbf where {(ignoreCase ? "lower(schemaname)" : "schemaname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(tablename)" : "tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -506,7 +517,9 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname") } } - sql = $@" + if (tbname == null) + { + sql = $@" select ns.nspname || '.' || b.relname as table_id, array(select attname from pg_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, @@ -523,39 +536,40 @@ inner join pg_namespace ns on ns.oid = b.relnamespace inner join pg_namespace ns2 on ns2.oid = c.relnamespace where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (object[] row in ds) - { - var table_id = string.Concat(row[0]); - var column = row[1] as string[]; - var fk_id = string.Concat(row[2]); - var ref_table_id = string.Concat(row[3]); - var is_foreign_key = string.Concat(row[4]) == "1"; - var referenced_column = row[5] as string[]; - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); - - if (loc2.ContainsKey(ref_table_id) == false) continue; - - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); - - for (int a = 0; a < column.Length; a++) + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) { - loc13.Columns.Add(loc3[table_id][column[a]]); - loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index 97ce5c1f..c5ca315e 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -19,7 +19,7 @@ namespace FreeSql.ShenTong.Curd { } - internal string InternalTableAlias; + internal string InternalTableAlias { get; set; } internal StringBuilder InternalSbSet => _set; internal StringBuilder InternalSbSetIncr => _setIncr; internal Dictionary InternalIgnore => _ignore; diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs index 1d573b84..0f9ce722 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongDbFirst.cs @@ -134,19 +134,30 @@ select 1 from sys_class a inner join sys_namespace b on b.oid = a.relnamespace -where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.relname)" : "a.relname")} = {_commonUtils.FormatSql("{0}", tbname[1])} and a.relkind in ('r') +where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.relname)" : "a.relname")}={_commonUtils.FormatSql("{0}", tbname[1])} and a.relkind in ('r') "; return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var olddatabase = ""; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { olddatabase = conn.Value.Database; } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { "PUBLIC", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { olddatabase }; + } var tables = new List(); foreach (var db in dbs) @@ -158,7 +169,7 @@ where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")} = {_commonUtils.FormatSq var loc3 = new Dictionary>(); var sql = $@" -select +{(tbname == null ? "" : $"select * from (")}select b.nspname || '.' || a.relname, b.nspname, a.relname, @@ -183,7 +194,7 @@ inner join sys_namespace b on b.oid = a.relnamespace left join sys_description d on d.objoid = a.oid and objsubid = 0 where b.nspname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') and a.relkind in ('m','v') and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS','PUBLIC.DBA_JOBS') -"; +{(tbname == null ? "" : $") ft_dbf where {(ignoreCase ? "lower(nspname)" : "nspname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(relname)" : "relname")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; @@ -400,7 +411,9 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname") } } - sql = $@" + if (tbname == null) + { + sql = $@" select a.pktable_schem || '.' || a.pktable_name, a.pkcolumn_name, @@ -411,36 +424,37 @@ a.fkcolumn_name from v_sys_foreign_keys a where {loc8.ToString().Replace("a.table_name", "a.pktable_schem || '.' || a.pktable_name")} "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (var row in ds) - { - string table_id = string.Concat(row[0]); - string column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - string ref_table_id = string.Concat(row[3]); - bool is_foreign_key = string.Concat(row[4]) == "1"; - string referenced_column = string.Concat(row[5]); - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + var fkColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs index f376bf61..36459b46 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerDbFirst.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; -using System.Text.RegularExpressions; namespace FreeSql.SqlServer { @@ -128,21 +127,32 @@ select 1 from sys.tables a inner join sys.schemas b on b.schema_id = a.schema_id -where lower(b.name) = {_commonUtils.FormatSql("{0}", tbname[1])} and lower(a.name) = {_commonUtils.FormatSql("{0}", tbname[2])} +where lower(b.name)={_commonUtils.FormatSql("{0}", tbname[1])} and lower(a.name)={_commonUtils.FormatSql("{0}", tbname[2])} ; use [{olddatabase}]; "; return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); - public List GetTablesByDatabase(params string[] database) + public List GetTables(string[] database, string tablename, bool ignoreCase) { var olddatabase = ""; using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { olddatabase = conn.Value.Database; } - var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { olddatabase, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { olddatabase, tbname[0], tbname[1] }; + tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { tbname[0] }; + } var tables = new List(); foreach (var db in dbs) @@ -155,6 +165,7 @@ use [{olddatabase}]; var sql = $@" use [{db}]; +select * from ( select a.Object_id ,b.name 'Owner' @@ -183,8 +194,8 @@ select from sys.procedures a inner join sys.schemas b on b.schema_id = a.schema_id where a.type = 'P' and charindex('diagram', a.name) = 0 -order by type desc, b.name, a.name -; +) ft_dbf{(tbname == null ? "" : _commonUtils.FormatSql(" where lower([owner])={0} and lower([Name])={1}", new[] { tbname[1], tbname[2] }))} +order by type desc, [owner], [Name]; use [{olddatabase}]; "; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); @@ -395,7 +406,9 @@ use [{olddatabase}]; } } - sql = $@" + if (tbname == null) + { + sql = $@" use [{db}]; select b.object_id 'Object_id' @@ -415,47 +428,48 @@ where {loc8.ToString().Replace("a.table_name", "b.object_id")} ; use [{olddatabase}]; "; - ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - if (ds == null) return loc1; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; - var fkColumns = new Dictionary>(); - foreach (object[] row in ds) - { - int object_id, referenced_object_id; - int.TryParse(string.Concat(row[0]), out object_id); - var column = string.Concat(row[1]); - string fk_id = string.Concat(row[2]); - int.TryParse(string.Concat(row[3]), out referenced_object_id); - var is_foreign_key = bool.Parse(string.Concat(row[4])); - var referenced_column = string.Concat(row[5]); - var referenced_db = string.Concat(row[6]); - var referenced_table = string.Concat(row[7]); - DbColumnInfo loc9 = loc3[object_id][column]; - DbTableInfo loc10 = null; - DbColumnInfo loc11 = null; - bool isThisSln = referenced_object_id != 0; - - if (isThisSln) - { - loc10 = loc2[referenced_object_id]; - loc11 = loc3[referenced_object_id][referenced_column]; - } - else + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) { + int object_id, referenced_object_id; + int.TryParse(string.Concat(row[0]), out object_id); + var column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + int.TryParse(string.Concat(row[3]), out referenced_object_id); + var is_foreign_key = bool.Parse(string.Concat(row[4])); + var referenced_column = string.Concat(row[5]); + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + DbColumnInfo loc9 = loc3[object_id][column]; + DbTableInfo loc10 = null; + DbColumnInfo loc11 = null; + bool isThisSln = referenced_object_id != 0; + if (isThisSln) + { + loc10 = loc2[referenced_object_id]; + loc11 = loc3[referenced_object_id][referenced_column]; + } + else + { + + } + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(object_id, out loc12)) + fkColumns.Add(object_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); } - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(object_id, out loc12)) - fkColumns.Add(object_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id]) - loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs index e3fe5077..46b3bdeb 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteDbFirst.cs @@ -155,18 +155,28 @@ namespace FreeSql.Sqlite var tbname = _commonUtils.SplitTableName(name); if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] }; if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); - var sql = $@" select 1 from {_commonUtils.QuoteSqlName(tbname[0])}.sqlite_master where type = 'table' and {(ignoreCase ? "lower(tbl_name)" : "tbl_name")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + var sql = $@" select 1 from {_commonUtils.QuoteSqlName(tbname[0])}.sqlite_master where type='table' and {(ignoreCase ? "lower(tbl_name)" : "tbl_name")}={_commonUtils.FormatSql("{0}", tbname[1])}"; return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; } - public List GetTablesByDatabase(params string[] database2) + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) { var loc1 = new List(); var loc2 = new Dictionary(); var loc3 = new Dictionary>(); - var database = database2?.ToArray(); - - if (database == null || database.Any() == false) database = GetDatabases().ToArray(); + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) + database = GetDatabases().ToArray(); if (database.Any() == false) return loc1; Action addColumn = (row, position) => @@ -212,7 +222,7 @@ tbl_name, '' Comment, 'TABLE', sql -from {db}.sqlite_master where type = 'table'"; +from {db}.sqlite_master where type='table'{(tbname == null ? "" : $" and {(ignoreCase ? "lower(tbl_name)" : "tbl_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) continue; @@ -284,34 +294,37 @@ from {db}.sqlite_master where type = 'table'"; addColumn(ds2item, ++position); } - var fks = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA \"{db}\".foreign_key_list(\"{table}\")"); - if (fks != null && fks.Length > 0) + if (tbname == null) { - var fkColumns = new Dictionary>(); - foreach (var fk in fks) + var fks = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA \"{db}\".foreign_key_list(\"{table}\")"); + if (fks != null && fks.Length > 0) { - string column = string.Concat(fk[3]); - string fk_id = $"{db}.{table}.{fk[0]}"; - string ref_table_id = database.Length == 1 ? string.Concat(fk[2]) : $"{db}.{fk[2]}"; - string referenced_column = string.Concat(fk[4]); - if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; - var loc9 = loc3[table_id][column]; - if (loc2.ContainsKey(ref_table_id) == false) continue; - var loc10 = loc2[ref_table_id]; - var loc11 = loc3[ref_table_id][referenced_column]; + var fkColumns = new Dictionary>(); + foreach (var fk in fks) + { + string column = string.Concat(fk[3]); + string fk_id = $"{db}.{table}.{fk[0]}"; + string ref_table_id = database.Length == 1 ? string.Concat(fk[2]) : $"{db}.{fk[2]}"; + string referenced_column = string.Concat(fk[4]); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; - Dictionary loc12 = null; - DbForeignInfo loc13 = null; - if (!fkColumns.TryGetValue(table_id, out loc12)) - fkColumns.Add(table_id, loc12 = new Dictionary()); - if (!loc12.TryGetValue(fk_id, out loc13)) - loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); - loc13.Columns.Add(loc9); - loc13.ReferencedColumns.Add(loc11); + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id2 in fkColumns.Keys) + foreach (var fk in fkColumns[table_id2]) + loc2[table_id2].ForeignsDict.Add(fk.Key, fk.Value); } - foreach (var table_id2 in fkColumns.Keys) - foreach (var fk in fkColumns[table_id2]) - loc2[table_id2].ForeignsDict.Add(fk.Key, fk.Value); } } } From 882e671eee0e4ec865d61f9ebbe77c4e4513f8b7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 12 Aug 2020 04:11:22 +0800 Subject: [PATCH 0816/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E6=97=A0?= =?UTF-8?q?=E4=B8=BB=E9=94=AE=E4=BD=BF=E7=94=A8=20IUpdate.SetSource=20?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=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 | 7 + FreeSql/FreeSql.xml | 157 +----------------- FreeSql/Interface/Curd/IUpdate.cs | 6 +- .../Internal/CommonProvider/UpdateProvider.cs | 3 + 5 files changed, 34 insertions(+), 155 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5ca74890..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -520,5 +527,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index d89e4db3..4693b4fb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -169,9 +169,16 @@ namespace FreeSql.Tests public int int2 { get; set; } } + class testUpdateNonePk + { + public string name { get; set; } + } + [Fact] public void Test03() { + Assert.Throws(() => g.sqlite.Update().SetSource(new testUpdateNonePk()).ExecuteAffrows()); + g.sqlite.Insert(new testInsertNullable()).NoneParameter().ExecuteAffrows(); var ddlsql = g.sqlite.CodeFirst.GetComparisonDDLStatements(typeof(testInsertNullable), "tb123123"); Assert.Equal(@"CREATE TABLE IF NOT EXISTS ""main"".""tb123123"" ( diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4f5d13e2..b4918bb3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2213,14 +2213,16 @@ - 更新数据,设置更新的实体 + 更新数据,设置更新的实体 + 注意:实体必须定义主键,并且最终会自动附加条件 where id = source.Id 实体 - 更新数据,设置更新的实体集合 + 更新数据,设置更新的实体集合 + 注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id) 实体集合 @@ -2592,145 +2594,6 @@ - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3416,12 +3279,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3492,12 +3349,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 5d4fb144..2abbdf64 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -54,13 +54,15 @@ namespace FreeSql IUpdate BatchProgress(Action> callback); /// - /// 更新数据,设置更新的实体 + /// 更新数据,设置更新的实体 + /// 注意:实体必须定义主键,并且最终会自动附加条件 where id = source.Id /// /// 实体 /// IUpdate SetSource(T1 source); /// - /// 更新数据,设置更新的实体集合 + /// 更新数据,设置更新的实体集合 + /// 注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id) /// /// 实体集合 /// diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 1c87af5b..72a31b3b 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -750,7 +750,10 @@ namespace FreeSql.Internal.CommonProvider sb.Append(" \r\nWHERE "); if (_source.Any()) + { + if (_table.Primarys.Any() == false) throw new ArgumentException($"{_table.Type.DisplayCsharp()} 没有定义主键,无法使用 SetSource,请尝试 SetDto"); sb.Append("(").Append(_commonUtils.WhereItems(_table, "", _source)).Append(")"); + } if (_where.Length > 0) sb.Append(_source.Any() ? _where.ToString() : _where.ToString().Substring(5)); From d10816d62caac66d745fe4de9bfb1b0235313468 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 12 Aug 2020 15:50:56 +0800 Subject: [PATCH 0817/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Oracle=20nva?= =?UTF-8?q?rchar2=20=E4=B8=BB=E9=94=AE=E6=89=B9=E9=87=8F=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B#411?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Oracle/Curd/OracleUpdateTest.cs | 13 +- .../Oracle/Curd/OracleUpdateTest.cs | 13 +- FreeSql/FreeSql.xml | 151 ++++++++++++++++++ .../Oracle/Curd/OdbcOracleUpdate.cs | 4 +- .../Curd/OracleUpdate.cs | 4 +- 5 files changed, 181 insertions(+), 4 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs index f71c827d..be5869d3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -53,6 +53,17 @@ namespace FreeSql.Tests.Odbc.Oracle new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } }).NoneParameter().ToSql().Replace("\r\n", ""); + + var uuids = new[] + { + new tssi01{tint = 1, title = "title01"}, + new tssi01{tint = 2, title = "title02"}, + new tssi01{tint = 3, title = "title03"}, + }; + g.oracle.Insert(uuids).ExecuteAffrows(); + g.oracle.Update().SetSource(uuids).ExecuteAffrows(); + + var tssi01tb = g.oracle.DbFirst.GetTableByName("tssi01"); } public class ts_source_mpk { @@ -71,7 +82,7 @@ namespace FreeSql.Tests.Odbc.Oracle } public class tssi01 { - [Column(CanUpdate = false)] + [Column(CanUpdate = false, DbType = "nvarchar2(36)")] public Guid id { get; set; } public int tint { get; set; } public string title { get; set; } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index 13abb3ef..da976c0d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -53,6 +53,17 @@ namespace FreeSql.Tests.Oracle new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } }).NoneParameter().ToSql().Replace("\r\n", ""); + + var uuids = new[] + { + new tssi01{tint = 1, title = "title01"}, + new tssi01{tint = 2, title = "title02"}, + new tssi01{tint = 3, title = "title03"}, + }; + g.oracle.Insert(uuids).ExecuteAffrows(); + g.oracle.Update().SetSource(uuids).ExecuteAffrows(); + + var tssi01tb = g.oracle.DbFirst.GetTableByName("tssi01"); } public class ts_source_mpk { @@ -71,7 +82,7 @@ namespace FreeSql.Tests.Oracle } public class tssi01 { - [Column(CanUpdate = false)] + [Column(CanUpdate = false, DbType = "nvarchar2(36)")] public Guid id { get; set; } public int tint { get; set; } public string title { get; set; } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b4918bb3..36068d41 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2594,6 +2594,145 @@ + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3279,6 +3418,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3349,6 +3494,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index 9e52f3c7..e8332f8d 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -50,7 +50,9 @@ namespace FreeSql.Odbc.Oracle { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + if (_table.Primarys[0].Attribute.DbType.Contains("NVARCHAR2")) + sb.Append("N"); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetMapValue(d))); return; } sb.Append("("); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index 0b65e0fb..02c0ac49 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -50,7 +50,9 @@ namespace FreeSql.Oracle.Curd { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + if (_table.Primarys[0].Attribute.DbType.Contains("NVARCHAR2")) + sb.Append("N"); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetMapValue(d))); return; } sb.Append("("); From 31a67a990d56ab483ae18bb1ce2657b019f3ac27 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 12 Aug 2020 16:18:44 +0800 Subject: [PATCH 0818/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ICodeFirst.S?= =?UTF-8?q?yncStructure=20=E5=BC=BA=E5=88=B6=E5=90=8C=E6=AD=A5=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20isForceSync=EF=BC=9B#412?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../Dameng/Curd/DamengSelectTest.cs | 2 ++ FreeSql/FreeSql.xml | 3 ++- FreeSql/Interface/ICodeFirst.cs | 3 ++- .../Internal/CommonProvider/CodeFirstProvider.cs | 10 +++++++--- 5 files changed, 13 insertions(+), 21 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..5ca74890 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -527,14 +520,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index 5a824785..40d64009 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -937,6 +937,8 @@ WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" public void AsTable() { g.dameng.CodeFirst.SyncStructure(typeof(Topic), "TB_TOPIC"); + g.dameng.CodeFirst.SyncStructure(typeof(Topic), "TB_TOPIC"); + g.dameng.CodeFirst.SyncStructure(typeof(Topic), "TB_TOPIC", isForceSync: true); var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 36068d41..91e5723b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3065,13 +3065,14 @@ - + 同步实体类型到数据库(指定表名) 注意:生产环境中谨慎使用 实体类型 指定表名对比 + 强制同步结构,无视缓存每次都同步 diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 02393445..8aa20684 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -80,7 +80,8 @@ namespace FreeSql /// /// 实体类型 /// 指定表名对比 - void SyncStructure(Type entityType, string tableName); + /// 强制同步结构,无视缓存每次都同步 + void SyncStructure(Type entityType, string tableName, bool isForceSync = false); /// /// 根据 System.Type 获取数据库信息 diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index e2e4cdad..bff2baa9 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -69,7 +69,7 @@ namespace FreeSql.Internal.CommonProvider static object syncStructureLock = new object(); object _dicSycedLock = new object(); - ConcurrentDictionary> _dicSynced = new ConcurrentDictionary>(); + public ConcurrentDictionary> _dicSynced = new ConcurrentDictionary>(); internal ConcurrentDictionary _dicSycedGetOrAdd(Type entityType) { if (_dicSynced.TryGetValue(entityType, out var trydic) == false) @@ -85,8 +85,12 @@ namespace FreeSql.Internal.CommonProvider this.SyncStructure(new TypeAndName(typeof(TEntity), "")); public void SyncStructure(params Type[] entityTypes) => this.SyncStructure(entityTypes?.Distinct().Select(a => new TypeAndName(a, "")).ToArray()); - public void SyncStructure(Type entityType, string tableName) => - this.SyncStructure(new TypeAndName(entityType, GetTableNameLowerOrUpper(tableName))); + public void SyncStructure(Type entityType, string tableName, bool isForceSync) + { + tableName = GetTableNameLowerOrUpper(tableName); + if (isForceSync && _dicSynced.TryGetValue(entityType, out var dic)) dic.TryRemove(tableName, out var old); + this.SyncStructure(new TypeAndName(entityType, tableName)); + } protected void SyncStructure(params TypeAndName[] objects) { if (objects == null) return; From ae5695262102102793b7ed647336a400c6ef53f8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 12 Aug 2020 20:42:15 +0800 Subject: [PATCH 0819/1029] update readme --- .../Controllers/HomeController.cs | 53 +++++++++++++++++++ .../aspnetcore_transaction.csproj | 2 +- .../FreeSql.Tests/FreeSql.Tests.csproj | 2 +- readme.md | 2 +- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/Examples/aspnetcore_transaction/Controllers/HomeController.cs b/Examples/aspnetcore_transaction/Controllers/HomeController.cs index 35129473..269d1f0d 100644 --- a/Examples/aspnetcore_transaction/Controllers/HomeController.cs +++ b/Examples/aspnetcore_transaction/Controllers/HomeController.cs @@ -1,8 +1,12 @@ using FreeSql; using FreeSql.DataAnnotations; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Threading; using System.Threading.Tasks; namespace aspnetcore_transaction.Controllers @@ -102,4 +106,53 @@ namespace aspnetcore_transaction.Controllers public int SongId { get; set; } public string Title { get; set; } } + + public static class IdleBusExtesions + { + static AsyncLocal AsyncLocalTenantId = new AsyncLocal(); + public static IdleBus ChangeTenant(this IdleBus ib, string tenantId) + { + AsyncLocalTenantId.Value = tenantId; + return ib; + } + public static IFreeSql Get(this IdleBus ib) => ib.Get(AsyncLocalTenantId.Value ?? "default"); + public static IBaseRepository GetRepository(this IdleBus ib) where T : class => ib.Get().GetRepository(); + + static void test() + { + IdleBus ib = null; //单例注入 + + var fsql = ib.Get(); //获取当前租户对应的 IFreeSql + + var fsql00102 = ib.ChangeTenant("00102").Get(); //切换租户,后面的操作都是针对 00102 + + var songRepository = ib.GetRepository(); + var detailRepository = ib.GetRepository(); + } + + public static IServiceCollection AddRepository(this IServiceCollection services, params Assembly[] assemblies) + { + services.AddScoped(typeof(IBaseRepository<>), typeof(YourDefaultRepository<>)); + services.AddScoped(typeof(BaseRepository<>), typeof(YourDefaultRepository<>)); + + services.AddScoped(typeof(IBaseRepository<,>), typeof(YourDefaultRepository<,>)); + services.AddScoped(typeof(BaseRepository<,>), typeof(YourDefaultRepository<,>)); + + if (assemblies?.Any() == true) + foreach (var asse in assemblies) + foreach (var repo in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(IBaseRepository).IsAssignableFrom(a))) + services.AddScoped(repo); + + return services; + } + } + + class YourDefaultRepository : BaseRepository where T : class + { + public YourDefaultRepository(IdleBus ib) : base(ib.Get(), null, null) { } + } + class YourDefaultRepository : BaseRepository where T : class + { + public YourDefaultRepository(IdleBus ib) : base(ib.Get(), null, null) { } + } } diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj index 77ed7fb2..6a13bfe0 100644 --- a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj @@ -12,7 +12,7 @@ - + diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 926e775f..0acabc69 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/readme.md b/readme.md index 2a395ae4..ff4a56b6 100644 --- a/readme.md +++ b/readme.md @@ -187,7 +187,7 @@ QQ群:4336577(已满)、8578575(在线) ## 💕  Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元 > Thank you for your donation From 5f645f194f0c384132bbbd943803cfd7e3a16c61 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 13 Aug 2020 10:25:01 +0800 Subject: [PATCH 0820/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20ISelect.W?= =?UTF-8?q?ithSql=20=E6=96=B9=E6=B3=95=EF=BC=8C=E6=94=AF=E6=8C=81=E4=BC=A0?= =?UTF-8?q?=E5=85=A5=E5=8F=82=E6=95=B0=E5=8C=96=20#413=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SqlServer/Curd/SqlServerSelectTest.cs | 13 +- FreeSql/FreeSql.xml | 158 +----------------- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 7 +- .../SelectProvider/Select1Provider.cs | 3 +- 4 files changed, 23 insertions(+), 158 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 03e49134..2c73658e 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1043,14 +1043,23 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] }); var testUnionAll = select - .WithSql("SELECT * FROM [tb_topic22] where id = 10") - .WithSql("SELECT * FROM [tb_topic22] where id = 11") + .WithSql("SELECT * FROM [tb_topic22] where id = @id1", new { id1 = 10 }) + .WithSql("SELECT * FROM [tb_topic22] where id = @id2", new { id2 = 11 }) .ToSql(a => new { a.Id, a.Clicks }); + var testUnionAllToList = select + .WithSql("SELECT * FROM [tb_topic22] where id = @id1", new { id1 = 10 }) + .WithSql("SELECT * FROM [tb_topic22] where id = @id2", new { id2 = 11 }) + .ToList(a => new + { + a.Id, + a.Clicks + }); + var testUnionAll2 = g.sqlite.Select() .WithSql("SELECT * FROM [tb_topic22] where id = 10") .WithSql("SELECT * FROM [tb_topic22] where id = 11") diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 91e5723b..1c323bd5 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1983,12 +1983,15 @@ 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - + 实现 select .. from ( select ... from t ) a 这样的功能 - 使用 AsTable 方法也可以达到效果 + 使用 AsTable 方法也可以达到效果 + 示例:WithSql("select * from id=?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> SQL语句 + 参数 @@ -2594,145 +2597,6 @@ - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3419,12 +3283,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3495,12 +3353,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index acf1bcf3..1d44bfe6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -373,10 +373,13 @@ namespace FreeSql /// /// 实现 select .. from ( select ... from t ) a 这样的功能 - /// 使用 AsTable 方法也可以达到效果 + /// 使用 AsTable 方法也可以达到效果 + /// 示例:WithSql("select * from id=?id", new { id = 1 }) + /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// SQL语句 + /// 参数 /// - ISelect WithSql(string sql); + ISelect WithSql(string sql, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 1a9c1fcf..4519bad1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -256,13 +256,14 @@ namespace FreeSql.Internal.CommonProvider return this; } - public ISelect WithSql(string sql) + public ISelect WithSql(string sql, object parms = null) { this.AsTable((type, old) => { if (type == _tables.First().Table?.Type) return $"( {sql} )"; return old; }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); return this; } From 4650af0e00b166a550119cf283b2d45bb2c07d02 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 13 Aug 2020 10:25:58 +0800 Subject: [PATCH 0821/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=20DbFirst=20=E6=97=A0=E6=B3=95=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=98=AF=E5=90=A6=E4=B8=BA=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs | 2 +- Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index 9f20d709..e92dd4fa 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -407,7 +407,7 @@ a.table_owner || '.' || a.table_name, c.column_name, c.index_name, case when a.uniqueness = 'UNIQUE' then 1 else 0 end, -case when exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') then 1 else 0 end, +case when exists(select 1 from all_constraints where index_name = a.index_name and constraint_type = 'P') then 1 else 0 end, 0, case when c.descend = 'DESC' then 1 else 0 end, c.column_position diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index a7b6d741..eedf46e0 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -407,7 +407,7 @@ a.table_owner || '.' || a.table_name, c.column_name, c.index_name, case when a.uniqueness = 'UNIQUE' then 1 else 0 end, -case when exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') then 1 else 0 end, +case when exists(select 1 from all_constraints where index_name = a.index_name and constraint_type = 'P') then 1 else 0 end, 0, case when c.descend = 'DESC' then 1 else 0 end, c.column_position From 3529f69cb6d9762239adee6116e15943cb2dd7bc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 13 Aug 2020 10:30:48 +0800 Subject: [PATCH 0822/1029] v1.8.0-preview0811 #411 #412 #413 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 151 ++++++++++++++++++ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 187 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 4ab6c226..e86f2101 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0249724b..a115c1b5 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 361d6962..c1ab2146 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 768c9044..ede9f14e 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 185ed507..f9430629 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0811 + 1.8.0-preview0813 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index ffd0af98..506848ca 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 9afc235e..a0c8688b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5ca74890..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -520,5 +527,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4e3e3e59..e40b879c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cc60e7f2..96b77049 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1c323bd5..c71bee29 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2597,6 +2597,145 @@ + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3283,6 +3422,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3353,6 +3498,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 978069a3..f48d673d 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 8249c17f..4d4ea5b8 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index a4b48b36..3d442bbf 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 068e75b7..c3b718f8 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 29dc1959..4f5cf909 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 05bd7d83..da03f53e 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1facd8ff..1f198b74 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 18f5bbc9..7db69224 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 7c476a33..12170bc0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 2c661f88..ce5cfc75 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c62a139e..66b6c0e5 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0811 + 1.8.0-preview0813 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From e4b51e5d207ff4747636ce7a034774989cc024b5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 14 Aug 2020 03:06:11 +0800 Subject: [PATCH 0823/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect<2..1?= =?UTF-8?q?0>=20=E5=A4=9A=E8=A1=A8=20WithSql=20=E6=96=B9=E6=B3=95=20#413?= =?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 --------------- .../SqlServer/Curd/SqlServerSelectTest.cs | 11 ++++++++++ FreeSql/Interface/Curd/ISelect/ISelect10.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect2.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect3.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect4.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect5.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect6.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect7.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect8.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect9.cs | 2 ++ .../SelectProvider/Select10Provider.cs | 20 +++++++++++++++++++ .../SelectProvider/Select1Provider.cs | 2 +- .../SelectProvider/Select2Provider.cs | 12 +++++++++++ .../SelectProvider/Select3Provider.cs | 13 ++++++++++++ .../SelectProvider/Select4Provider.cs | 14 +++++++++++++ .../SelectProvider/Select5Provider.cs | 15 ++++++++++++++ .../SelectProvider/Select6Provider.cs | 16 +++++++++++++++ .../SelectProvider/Select7Provider.cs | 17 ++++++++++++++++ .../SelectProvider/Select8Provider.cs | 18 +++++++++++++++++ .../SelectProvider/Select9Provider.cs | 19 ++++++++++++++++++ 21 files changed, 174 insertions(+), 17 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..5ca74890 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -527,14 +520,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 2c73658e..2f9398d8 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -1064,6 +1064,17 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] .WithSql("SELECT * FROM [tb_topic22] where id = 10") .WithSql("SELECT * FROM [tb_topic22] where id = 11") .ToDataTable("*"); + + var multiWithSql = g.sqlite.Select() + .WithSql( + "select * from TestInclude_OneToManyModel1 where id=@id1", + "select * from TestInclude_OneToManyModel2 where model2id=@id2", + null, + new { id1 = 10, id2 = 11, id3 = 13 } + ) + .LeftJoin((a, b, c) => b.model2id == a.id) + .LeftJoin((a, b, c) => c.model2111Idaaa == b.model2id) + .ToList(); } public class TestInclude_OneToManyModel1 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index f041b8b1..e4cdafd6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 3bbd6b0c..bd9692e5 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index 1dc6e71e..00836d0a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 29bc56f6..8890624b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index a82866c7..f8d6cd7e 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 16be4dfc..63db674e 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index be8873c9..fc99ef10 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index a61b4955..836ee3fb 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index ff8ff51d..8f44436d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -55,5 +55,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms = null); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index a62868c4..8f9a4398 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -36,6 +36,26 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; + if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return 0; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 4519bad1..f4a18423 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -260,7 +260,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { - if (type == _tables.First().Table?.Type) return $"( {sql} )"; + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sql) == false) return $"( {sql} )"; return old; }); if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 0bf4d0fc..79583b79 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -20,6 +20,18 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index ebded494..1ccd1d5c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -22,6 +22,19 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 2824aa01..c97b75b7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -24,6 +24,20 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 1278e64f..27d8a023 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -26,6 +26,21 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index f4b9caa5..b5fb37c8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -28,6 +28,22 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"( {sqlT6} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index b094c500..52e1c4fb 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -30,6 +30,23 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"( {sqlT7} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index fbc2ed51..da9c40a5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -32,6 +32,24 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"( {sqlT8} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 021298f4..5bfc03a1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -34,6 +34,25 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); } + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"( {sqlT9} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9}", parms)); + return this; + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); From cad63308a3719e33b1b26d1a21d2afbdb14c5044 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 14 Aug 2020 03:26:57 +0800 Subject: [PATCH 0824/1029] v1.8.0-preview0814 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index e86f2101..1bf7d6d9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index a115c1b5..2a06a464 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c1ab2146..6deec660 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index ede9f14e..3d923084 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index f9430629..bb2faf94 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0813 + 1.8.0-preview0814 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 506848ca..6b012c04 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a0c8688b..8d8a4cd9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5ca74890..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -520,5 +527,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e40b879c..68e7bc58 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 96b77049..354647fc 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index f48d673d..da72f023 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 4d4ea5b8..0f796c19 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3d442bbf..747d5686 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index c3b718f8..471de3b5 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 4f5cf909..36a8f648 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index da03f53e..e9773c63 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1f198b74..e00028c7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 7db69224..465e21f8 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 12170bc0..ad90e2eb 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index ce5cfc75..8f12265b 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 66b6c0e5..1f715a17 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0813 + 1.8.0-preview0814 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 66f123fbed1a561549facf6a7c8ab222f6a00171 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 14 Aug 2020 15:30:58 +0800 Subject: [PATCH 0825/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20WhereDynamic?= =?UTF-8?q?=20=E4=BC=A0=E5=85=A5=E9=9B=86=E5=90=88=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E9=80=BB=E8=BE=91=20OR=20=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?=20IN=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 -------------- .../MySqlConnector/Curd/MySqlDeleteTest.cs | 8 +++---- .../MySqlConnector/Curd/MySqlUpdateTest.cs | 8 +++---- .../Dameng/Curd/DamengDeleteTest.cs | 8 +++---- .../Dameng/Curd/DamengUpdateTest.cs | 8 +++---- .../Default/Curd/OdbcDeleteTest.cs | 8 +++---- .../Default/Curd/OdbcUpdateTest.cs | 8 +++---- .../KingbaseES/Curd/KingbaseESDeleteTest.cs | 8 +++---- .../KingbaseES/Curd/KingbaseESUpdateTest.cs | 8 +++---- .../MySql/Curd/MySqlDeleteTest.cs | 8 +++---- .../MySql/Curd/MySqlUpdateTest.cs | 8 +++---- .../Oracle/Curd/OracleDeleteTest.cs | 8 +++---- .../Oracle/Curd/OracleUpdateTest.cs | 8 +++---- .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 8 +++---- .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 8 +++---- .../SqlServer/Curd/SqlServerDeleteTest.cs | 8 +++---- .../SqlServer/Curd/SqlServerUpdateTest.cs | 8 +++---- .../Dameng/Curd/DamengDeleteTest.cs | 8 +++---- .../Dameng/Curd/DamengUpdateTest.cs | 8 +++---- .../MsAccess/Curd/MsAccessDeleteTest.cs | 8 +++---- .../MsAccess/Curd/MsAccessUpdateTest.cs | 8 +++---- .../MySql/Curd/MySqlDeleteTest.cs | 8 +++---- .../MySql/Curd/MySqlUpdateTest.cs | 8 +++---- .../Oracle/Curd/OracleDeleteTest.cs | 8 +++---- .../Oracle/Curd/OracleUpdateTest.cs | 8 +++---- .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 8 +++---- .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 8 +++---- .../ShenTong/Curd/ShenTongDeleteTest.cs | 8 +++---- .../ShenTong/Curd/ShenTongUpdateTest.cs | 8 +++---- .../SqlServer/Curd/SqlServerDeleteTest.cs | 8 +++---- .../SqlServer/Curd/SqlServerUpdateTest.cs | 8 +++---- .../Sqlite/Curd/SqliteDeleteTest.cs | 8 +++---- .../Sqlite/Curd/SqliteUpdateTest.cs | 8 +++---- FreeSql/Internal/CommonUtils.cs | 22 +++++++++++++++++++ 34 files changed, 150 insertions(+), 144 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..5ca74890 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -527,14 +520,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs index 1d711cc4..2954f27e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlDeleteTest.cs @@ -26,13 +26,13 @@ namespace FreeSql.Tests.MySqlConnector { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); @@ -89,13 +89,13 @@ namespace FreeSql.Tests.MySqlConnector { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs index 646a508b..72ced82d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlUpdateTest.cs @@ -32,9 +32,9 @@ namespace FreeSql.Tests.MySqlConnector public void Dywhere() { Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -370,9 +370,9 @@ limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a public void AsTable() { Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs index d424fe0e..d83e78ee 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.Odbc.Dameng { Assert.Null(g.dameng.Delete().ToSql()); var sql = g.dameng.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.dameng.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); sql = g.dameng.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.dameng.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); @@ -91,13 +91,13 @@ namespace FreeSql.Tests.Odbc.Dameng { Assert.Null(g.dameng.Delete().ToSql()); var sql = g.dameng.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.dameng.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); sql = g.dameng.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.dameng.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs index 8375a89b..93b22780 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengUpdateTest.cs @@ -24,9 +24,9 @@ namespace FreeSql.Tests.Odbc.Dameng public void Dywhere() { Assert.Null(g.dameng.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -181,9 +181,9 @@ namespace FreeSql.Tests.Odbc.Dameng public void AsTable() { Assert.Null(g.dameng.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs index 65ce7624..7bb38d8c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcDeleteTest.cs @@ -26,13 +26,13 @@ namespace FreeSql.Tests.Odbc.Default { Assert.Null(g.odbc.Delete().ToSql()); var sql = g.odbc.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); sql = g.odbc.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); sql = g.odbc.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); sql = g.odbc.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); @@ -83,13 +83,13 @@ namespace FreeSql.Tests.Odbc.Default { Assert.Null(g.odbc.Delete().ToSql()); var sql = g.odbc.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] IN (1,2))", sql); sql = g.odbc.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); sql = g.odbc.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] IN (1,2))", sql); sql = g.odbc.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs index 77a5e25e..cc979c42 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcUpdateTest.cs @@ -26,9 +26,9 @@ namespace FreeSql.Tests.Odbc.Default public void Dywhere() { Assert.Null(g.odbc.Update().ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.odbc.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.odbc.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.odbc.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.odbc.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.odbc.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.odbc.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -175,9 +175,9 @@ namespace FreeSql.Tests.Odbc.Default public void AsTable() { Assert.Null(g.odbc.Update().ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.odbc.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.odbc.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.odbc.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.odbc.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.odbc.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.odbc.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESDeleteTest.cs index 40ea21d9..a9f8498e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.Odbc.KingbaseES { Assert.Null(g.kingbaseES.Delete().ToSql()); var sql = g.kingbaseES.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.kingbaseES.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); sql = g.kingbaseES.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.kingbaseES.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); @@ -91,13 +91,13 @@ namespace FreeSql.Tests.Odbc.KingbaseES { Assert.Null(g.kingbaseES.Delete().ToSql()); var sql = g.kingbaseES.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.kingbaseES.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); sql = g.kingbaseES.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.kingbaseES.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs index d1c5cd91..4690b744 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESUpdateTest.cs @@ -24,9 +24,9 @@ namespace FreeSql.Tests.Odbc.KingbaseES public void Dywhere() { Assert.Null(g.kingbaseES.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.kingbaseES.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.kingbaseES.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.kingbaseES.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.kingbaseES.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -181,9 +181,9 @@ namespace FreeSql.Tests.Odbc.KingbaseES public void AsTable() { Assert.Null(g.kingbaseES.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.kingbaseES.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.kingbaseES.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.kingbaseES.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.kingbaseES.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs index cbc3303a..f4b3a11d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlDeleteTest.cs @@ -26,13 +26,13 @@ namespace FreeSql.Tests.Odbc.MySql { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); @@ -89,13 +89,13 @@ namespace FreeSql.Tests.Odbc.MySql { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs index 0ea494df..90ed0971 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlUpdateTest.cs @@ -32,9 +32,9 @@ namespace FreeSql.Tests.Odbc.MySql public void Dywhere() { Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -311,9 +311,9 @@ limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a public void AsTable() { Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs index be99ef40..605f7759 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.Odbc.Oracle { Assert.Null(g.oracle.Delete().ToSql()); var sql = g.oracle.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.oracle.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); @@ -91,13 +91,13 @@ namespace FreeSql.Tests.Odbc.Oracle { Assert.Null(g.oracle.Delete().ToSql()); var sql = g.oracle.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.oracle.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs index be5869d3..13315f4b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleUpdateTest.cs @@ -24,9 +24,9 @@ namespace FreeSql.Tests.Odbc.Oracle public void Dywhere() { Assert.Null(g.oracle.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -182,9 +182,9 @@ namespace FreeSql.Tests.Odbc.Oracle public void AsTable() { Assert.Null(g.oracle.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index 1378d0d9..7b71cf0b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.Odbc.PostgreSQL { Assert.Null(g.pgsql.Delete().ToSql()); var sql = g.pgsql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2))", sql); sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2))", sql); sql = g.pgsql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); @@ -90,13 +90,13 @@ namespace FreeSql.Tests.Odbc.PostgreSQL { Assert.Null(g.pgsql.Delete().ToSql()); var sql = g.pgsql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" IN (1,2))", sql); sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" IN (1,2))", sql); sql = g.pgsql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 165f4b1b..0920fa3e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -25,9 +25,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public void Dywhere() { Assert.Null(g.pgsql.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -176,9 +176,9 @@ namespace FreeSql.Tests.Odbc.PostgreSQL public void AsTable() { Assert.Null(g.pgsql.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topicastable\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs index 89802f75..b9a1670e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.Odbc.SqlServer { Assert.Null(g.sqlserver.Delete().ToSql()); var sql = g.sqlserver.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); sql = g.sqlserver.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); @@ -97,13 +97,13 @@ namespace FreeSql.Tests.Odbc.SqlServer { Assert.Null(g.sqlserver.Delete().ToSql()); var sql = g.sqlserver.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] IN (1,2))", sql); sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] IN (1,2))", sql); sql = g.sqlserver.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs index 237b8064..3349c4a0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerUpdateTest.cs @@ -27,9 +27,9 @@ namespace FreeSql.Tests.Odbc.SqlServer public void Dywhere() { Assert.Null(g.sqlserver.Update().ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -190,9 +190,9 @@ namespace FreeSql.Tests.Odbc.SqlServer public void AsTable() { Assert.Null(g.sqlserver.Update().ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengDeleteTest.cs index 17ba3c06..46946215 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.Dameng { Assert.Null(g.dameng.Delete().ToSql()); var sql = g.dameng.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.dameng.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); sql = g.dameng.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.dameng.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); @@ -91,13 +91,13 @@ namespace FreeSql.Tests.Dameng { Assert.Null(g.dameng.Delete().ToSql()); var sql = g.dameng.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.dameng.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); sql = g.dameng.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.dameng.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs index 995d5c31..87dccf81 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengUpdateTest.cs @@ -24,9 +24,9 @@ namespace FreeSql.Tests.Dameng public void Dywhere() { Assert.Null(g.dameng.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -181,9 +181,9 @@ namespace FreeSql.Tests.Dameng public void AsTable() { Assert.Null(g.dameng.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.dameng.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.dameng.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.dameng.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs index e2fca832..dedfc922 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.MsAccess { Assert.Null(g.msaccess.Delete().ToSql()); var sql = g.msaccess.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); sql = g.msaccess.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); sql = g.msaccess.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); sql = g.msaccess.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); @@ -91,13 +91,13 @@ namespace FreeSql.Tests.MsAccess { Assert.Null(g.msaccess.Delete().AsTable(a => "TopicAsTable").ToSql()); var sql = g.msaccess.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] IN (1,2))", sql); sql = g.msaccess.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] = 1)", sql); sql = g.msaccess.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] IN (1,2))", sql); sql = g.msaccess.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM [TopicAsTable] WHERE ([Id] = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs index d493de00..5f52c6d0 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessUpdateTest.cs @@ -26,9 +26,9 @@ namespace FreeSql.Tests.MsAccess public void Dywhere() { Assert.Null(g.msaccess.Update().ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.msaccess.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.msaccess.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.msaccess.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.msaccess.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.msaccess.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.msaccess.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -185,9 +185,9 @@ namespace FreeSql.Tests.MsAccess public void AsTable() { Assert.Null(g.msaccess.Update().ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.msaccess.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.msaccess.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.msaccess.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.msaccess.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.msaccess.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.msaccess.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs index 3fcb503f..bca53e7f 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.MySql { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); @@ -90,13 +90,13 @@ namespace FreeSql.Tests.MySql { Assert.Null(g.mysql.Delete().ToSql()); var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1 OR `Id` = 2)", sql); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` IN (1,2))", sql); sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs index 5ff9a1b3..3294d265 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlUpdateTest.cs @@ -33,9 +33,9 @@ namespace FreeSql.Tests.MySql public void Dywhere() { Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -372,9 +372,9 @@ limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a public void AsTable() { Assert.Null(g.mysql.Update().ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1 OR `Id` = 2)", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs index 6b3cee7f..5be0eb9e 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.Oracle { Assert.Null(g.oracle.Delete().ToSql()); var sql = g.oracle.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); sql = g.oracle.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); @@ -91,13 +91,13 @@ namespace FreeSql.Tests.Oracle { Assert.Null(g.oracle.Delete().ToSql()); var sql = g.oracle.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.oracle.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs index da976c0d..5a8cd4cd 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleUpdateTest.cs @@ -24,9 +24,9 @@ namespace FreeSql.Tests.Oracle public void Dywhere() { Assert.Null(g.oracle.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -186,9 +186,9 @@ namespace FreeSql.Tests.Oracle public void AsTable() { Assert.Null(g.oracle.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs index 3a0e19d5..e56e1fa1 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.PostgreSQL { Assert.Null(g.pgsql.Delete().ToSql()); var sql = g.pgsql.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2))", sql); sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2))", sql); sql = g.pgsql.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); @@ -90,13 +90,13 @@ namespace FreeSql.Tests.PostgreSQL { Assert.Null(g.pgsql.Delete().ToSql()); var sql = g.pgsql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" IN (1,2))", sql); sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" IN (1,2))", sql); sql = g.pgsql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs index 47267c86..637235d4 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -25,9 +25,9 @@ namespace FreeSql.Tests.PostgreSQL public void Dywhere() { Assert.Null(g.pgsql.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -180,9 +180,9 @@ namespace FreeSql.Tests.PostgreSQL public void AsTable() { Assert.Null(g.pgsql.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topicastable\" SET title='test' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1 OR \"id\" = 2)", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongDeleteTest.cs index 6f07533b..a5840e10 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.ShenTong { Assert.Null(g.shentong.Delete().ToSql()); var sql = g.shentong.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" IN (1,2))", sql); sql = g.shentong.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); sql = g.shentong.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" IN (1,2))", sql); sql = g.shentong.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); @@ -90,13 +90,13 @@ namespace FreeSql.Tests.ShenTong { Assert.Null(g.shentong.Delete().ToSql()); var sql = g.shentong.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.shentong.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); sql = g.shentong.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1 OR \"ID\" = 2)", sql); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); sql = g.shentong.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs index 0662a1fd..22578cfb 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongUpdateTest.cs @@ -25,9 +25,9 @@ namespace FreeSql.Tests.ShenTong public void Dywhere() { Assert.Null(g.shentong.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.shentong.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.shentong.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -180,9 +180,9 @@ namespace FreeSql.Tests.ShenTong public void AsTable() { Assert.Null(g.shentong.Update().ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.shentong.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1 OR \"ID\" = 2)", g.shentong.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.shentong.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.shentong.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs index 713f77f1..d36d73e2 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs @@ -35,13 +35,13 @@ namespace FreeSql.Tests.SqlServer { Assert.Null(g.sqlserver.Delete().ToSql()); var sql = g.sqlserver.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); sql = g.sqlserver.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); @@ -105,13 +105,13 @@ namespace FreeSql.Tests.SqlServer { Assert.Null(g.sqlserver.Delete().ToSql()); var sql = g.sqlserver.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] IN (1,2))", sql); sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); - Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1 OR [Id] = 2)", sql); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] IN (1,2))", sql); sql = g.sqlserver.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs index 80474061..a32bf3d4 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs @@ -36,9 +36,9 @@ namespace FreeSql.Tests.SqlServer public void Dywhere() { Assert.Null(g.sqlserver.Update().ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -203,9 +203,9 @@ namespace FreeSql.Tests.SqlServer public void AsTable() { Assert.Null(g.sqlserver.Update().ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs index 4be2cd43..dad8da8b 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs @@ -27,13 +27,13 @@ namespace FreeSql.Tests.Sqlite { Assert.Null(g.sqlite.Delete().ToSql()); var sql = g.sqlite.Delete(new[] { 1, 2 }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" IN (1,2))", sql); sql = g.sqlite.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); sql = g.sqlite.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); - Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); + Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" IN (1,2))", sql); sql = g.sqlite.Delete(new { id = 1 }).ToSql(); Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); @@ -91,13 +91,13 @@ namespace FreeSql.Tests.Sqlite { Assert.Null(g.sqlite.Delete().AsTable(a => "TopicAsTable").ToSql()); var sql = g.sqlite.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" IN (1,2))", sql); sql = g.sqlite.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1)", sql); sql = g.sqlite.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); - Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); + Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" IN (1,2))", sql); sql = g.sqlite.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); Assert.Equal("DELETE FROM \"TopicAsTable\" WHERE (\"Id\" = 1)", sql); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs index b9a0e04f..738852d4 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteUpdateTest.cs @@ -37,9 +37,9 @@ namespace FreeSql.Tests.Sqlite public void Dywhere() { Assert.Null(g.sqlite.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"Id\" IN (1,2))", g.sqlite.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); - Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" IN (1,2))", g.sqlite.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); } @@ -234,9 +234,9 @@ namespace FreeSql.Tests.Sqlite public void AsTable() { Assert.Null(g.sqlite.Update().ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test' \r\nWHERE (\"Id\" IN (1,2))", g.sqlite.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); - Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1 OR \"Id\" = 2)", g.sqlite.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" IN (1,2))", g.sqlite.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); Assert.Equal("UPDATE \"tb_topicAsTable\" SET title='test1' \r\nWHERE (\"Id\" = 1)", g.sqlite.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); } } diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 7d0704c0..76229b54 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -286,6 +286,28 @@ namespace FreeSql.Internal { return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}"; } + else if (primarys.Length == 1 && dywhere is IEnumerable) + { + var sb = new StringBuilder(); + var ie = dywhere as IEnumerable; + var ieidx = 0; + var isEntityType = false; + sb.Append(aliasAndDot).Append(this.QuoteSqlName(pk1.Attribute.Name)).Append(" IN ("); //or会造成扫全表 + foreach (var i in ie) + { + if (ieidx > 0) sb.Append(","); + if (ieidx == 0) + { + var itype = i.GetType(); + isEntityType = (itype == table.Type || itype.BaseType == table.Type); + } + if (isEntityType) sb.Append(this.FormatSql("{0}", primarys[0].GetMapValue(i))); + else sb.Append(this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, i))); + ++ieidx; + } + sb.Append(")"); + return sb.ToString(); + } else if (dywhere is IEnumerable) { var sb = new StringBuilder(); From d3c4bbb87996f9cfb46fc5bc4897eba65bda1844 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 15 Aug 2020 00:32:11 +0800 Subject: [PATCH 0826/1029] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=20SqlExt=20Par?= =?UTF-8?q?titionBy=20=E6=97=A0=E6=B3=95=E4=BC=A0=E5=85=A5=E5=A4=9A?= =?UTF-8?q?=E5=88=97=E7=9A=84=E9=97=AE=E9=A2=98=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 | 6 +- .../FreeSqlGlobalExpressionCallExtensions.cs | 55 ++++++++++++++++--- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5ca74890..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -520,5 +527,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 4693b4fb..dcfab4da 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -224,11 +224,13 @@ namespace FreeSql.Tests .Page(1, 10).ToSql("Id"); - var sqlextMax1 = g.mysql.Select() + var sqlextMax1 = g.sqlserver.Select() .GroupBy(a => a.Id) .ToSql(a => new { - Id = a.Key, EdiId = SqlExt.Max(a.Key).Over().ToValue() + Id = a.Key, + EdiId1 = SqlExt.Max(a.Key).Over().PartitionBy(new { a.Value.EdiId, a.Value.Id }).OrderByDescending(new { a.Value.EdiId, a.Value.Id }).ToValue(), + EdiId2 = SqlExt.Max(a.Key).Over().PartitionBy(a.Value.EdiId).OrderByDescending(a.Value.Id).ToValue(), }); var sqlextGroupConcat = g.mysql.Select() diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index d8903744..a5cecf49 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Text; using System.Threading; using static FreeSql.SqlExtExtensions; @@ -157,7 +158,19 @@ namespace FreeSql } public static ISqlOver PartitionBy(this ISqlOver that, object column) { - expSbLast.Sb.Append(" partition by ").Append(expContext.ParsedContent["column"]).Append(","); + var sb = expSbLast.Sb; + sb.Append(" partition by "); + var exp = expContext.RawExpression["column"]; + if (exp.NodeType == ExpressionType.New) + { + var expNew = exp as NewExpression; + for (var a = 0; a < expNew.Arguments.Count; a++) + { + if (a > 0) sb.Append(","); + sb.Append(expContext.Utility.ParseExpression(expNew.Arguments[a])); + } + } else + sb.Append(expContext.ParsedContent["column"]); return that; } public static ISqlOver OrderBy(this ISqlOver that, object column) => OrderByPriv(that, false); @@ -170,9 +183,23 @@ namespace FreeSql sb.Append(" order by "); expSbLast.IsOrderBy = true; } - sb.Append(expContext.ParsedContent["column"]); - if (isDesc) sb.Append(" desc"); - sb.Append(","); + var exp = expContext.RawExpression["column"]; + if (exp.NodeType == ExpressionType.New) + { + var expNew = exp as NewExpression; + for (var a = 0; a < expNew.Arguments.Count; a++) + { + sb.Append(expContext.Utility.ParseExpression(expNew.Arguments[a])); + if (isDesc) sb.Append(" desc"); + sb.Append(","); + } + } + else + { + sb.Append(expContext.ParsedContent["column"]); + if (isDesc) sb.Append(" desc"); + sb.Append(","); + } return that; } public static TValue ToValue(this ISqlOver that) @@ -254,9 +281,23 @@ namespace FreeSql sb.Append(" order by "); expSbLast.IsOrderBy = true; } - sb.Append(expContext.ParsedContent["column"]); - if (isDesc) sb.Append(" desc"); - sb.Append(","); + var exp = expContext.RawExpression["column"]; + if (exp.NodeType == ExpressionType.New) + { + var expNew = exp as NewExpression; + for (var a = 0; a < expNew.Arguments.Count; a++) + { + sb.Append(expContext.Utility.ParseExpression(expNew.Arguments[a])); + if (isDesc) sb.Append(" desc"); + sb.Append(","); + } + } + else + { + sb.Append(expContext.ParsedContent["column"]); + if (isDesc) sb.Append(" desc"); + sb.Append(","); + } return that; } public static string ToValue(this IGroupConcat that) From 91a7fc8694e34fa470e1d2ac8abeebb9981a3acd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 15 Aug 2020 22:26:42 +0800 Subject: [PATCH 0827/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20WhereDynamic?= =?UTF-8?q?Filter=20System.Text.Json=20=E5=8F=8D=E5=BA=8F=E5=8C=96?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20#371=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 11 +++++++++ .../SelectProvider/Select0Provider.cs | 24 +++++++++---------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 502f11dd..e654af94 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -40,6 +40,7 @@ namespace base_entity public class Products : BaseEntity { public string title { get; set; } + public int testint { get; set; } } static AsyncLocal _asyncUow = new AsyncLocal(); @@ -187,6 +188,16 @@ namespace base_entity ""Field"" : ""title"", ""Operator"" : 8, ""Value"" : ""product-4"" + }, + { + ""Field"" : ""testint"", + ""Operator"" : 8, + ""Value"" : 11 + }, + { + ""Field"" : ""testint"", + ""Operator"" : 8, + ""Value"" : ""12"" } ] } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index ec88baf0..a5166fc2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -1139,22 +1139,22 @@ namespace FreeSql.Internal.CommonProvider switch (fi.Operator) { - case DynamicFilterOperator.Contains: exp = Expression.Call(exp, MethodStringContains, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; - case DynamicFilterOperator.StartsWith: exp = Expression.Call(exp, MethodStringStartsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; - case DynamicFilterOperator.EndsWith: exp = Expression.Call(exp, MethodStringEndsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; - case DynamicFilterOperator.NotContains: exp = Expression.Not(Expression.Call(exp, MethodStringContains, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type))); break; - case DynamicFilterOperator.NotStartsWith: exp = Expression.Not(Expression.Call(exp, MethodStringStartsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type))); break; - case DynamicFilterOperator.NotEndsWith: exp = Expression.Not(Expression.Call(exp, MethodStringEndsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type))); break; + case DynamicFilterOperator.Contains: exp = Expression.Call(exp, MethodStringContains, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.StartsWith: exp = Expression.Call(exp, MethodStringStartsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.EndsWith: exp = Expression.Call(exp, MethodStringEndsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.NotContains: exp = Expression.Not(Expression.Call(exp, MethodStringContains, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type))); break; + case DynamicFilterOperator.NotStartsWith: exp = Expression.Not(Expression.Call(exp, MethodStringStartsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type))); break; + case DynamicFilterOperator.NotEndsWith: exp = Expression.Not(Expression.Call(exp, MethodStringEndsWith, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type))); break; case DynamicFilterOperator.Eq: case DynamicFilterOperator.Equals: - case DynamicFilterOperator.Equal: exp = Expression.Equal(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; - case DynamicFilterOperator.NotEqual: exp = Expression.NotEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.Equal: exp = Expression.Equal(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.NotEqual: exp = Expression.NotEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; - case DynamicFilterOperator.GreaterThan: exp = Expression.GreaterThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; - case DynamicFilterOperator.GreaterThanOrEqual: exp = Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; - case DynamicFilterOperator.LessThan: exp = Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; - case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value), exp.Type)); break; + case DynamicFilterOperator.GreaterThan: exp = Expression.GreaterThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.GreaterThanOrEqual: exp = Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.LessThan: exp = Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; case DynamicFilterOperator.Range: var fiValueRangeArray = getFiListValue(); if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 要求 Value 应该逗号分割,并且长度为 2"); From bcb4abf7e41a807b7834b00339c134acd3324298 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 15 Aug 2020 22:42:11 +0800 Subject: [PATCH 0828/1029] v1.8.0-preview0815 #371 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1bf7d6d9..d16994ed 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 2a06a464..8b615ea2 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6deec660..318c14ab 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 3d923084..15ab1ddd 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index bb2faf94..e16c37d5 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0814 + 1.8.0-preview0815 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 6b012c04..e3c96b3a 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8d8a4cd9..53f59d50 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 68e7bc58..99b0fce7 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 354647fc..7a040edd 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index da72f023..2d03ba3b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 0f796c19..fa8de250 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 747d5686..66f6a2ea 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 471de3b5..be7588c7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 36a8f648..711dd803 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index e9773c63..40a22761 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e00028c7..8227bb23 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 465e21f8..42e9d494 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index ad90e2eb..b37e0c0d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 8f12265b..c8ee19e0 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 1f715a17..fc2528c9 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0814 + 1.8.0-preview0815 true ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 5eb0b78d85116e88cffa7e1d3b8c7e94ec141510 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 16 Aug 2020 02:01:46 +0800 Subject: [PATCH 0829/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E5=8C=85=20FreeSql.Extensions.AdoNet=20#267=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 6 +- .../FreeSql.Extensions.AdoNet.csproj | 37 +++ .../FreeSqlAdoNetExtensions.cs | 265 ++++++++++++++++++ .../Volo.Abp.Dapper.FreeSqlExtensions.xml | 217 ++++++++++++++ Extensions/FreeSql.Extensions.AdoNet/key.snk | Bin 0 -> 596 bytes .../FreeSql.Extensions.AdoNet/readme.md | 19 ++ .../FreeSql.Tests.Extensions.AdoNet.csproj | 26 ++ .../MySqlConnectionExtensionsTest.cs | 70 +++++ .../NpgsqlConnectionExtensionsTest.cs | 70 +++++ .../OracleConnectionExtensionsTest.cs | 70 +++++ .../SQLiteConnectionExtensionsTest.cs | 72 +++++ .../SqlConnectionExtensionsTest.cs | 70 +++++ .../FreeSql.Tests.Extensions.AdoNet/g.cs | 80 ++++++ FreeSql.sln | 29 ++ 14 files changed, 1030 insertions(+), 1 deletion(-) create mode 100644 Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj create mode 100644 Extensions/FreeSql.Extensions.AdoNet/FreeSqlAdoNetExtensions.cs create mode 100644 Extensions/FreeSql.Extensions.AdoNet/Volo.Abp.Dapper.FreeSqlExtensions.xml create mode 100644 Extensions/FreeSql.Extensions.AdoNet/key.snk create mode 100644 Extensions/FreeSql.Extensions.AdoNet/readme.md create mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/FreeSql.Tests.Extensions.AdoNet.csproj create mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/MySqlConnectionExtensionsTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/NpgsqlConnectionExtensionsTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/OracleConnectionExtensionsTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SQLiteConnectionExtensionsTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SqlConnectionExtensionsTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/g.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index e654af94..0a945606 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -1,6 +1,7 @@ using FreeSql; using FreeSql.DataAnnotations; using FreeSql.Extensions; +using FreeSql.Internal.CommonProvider; using FreeSql.Internal.Model; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -69,7 +70,7 @@ namespace base_entity .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=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=2") + .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=2") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") @@ -98,6 +99,9 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + var names = (fsql.Select() as Select0Provider)._commonUtils.SplitTableName("`Backups.ProductStockBak`"); + + var sql = fsql.CodeFirst.GetComparisonDDLStatements(typeof(EMSServerModel.Model.User), "testxsx001"); var test01 = EMSServerModel.Model.User.Select.IncludeMany(a => a.Roles).ToList(); diff --git a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj new file mode 100644 index 00000000..d1b1a589 --- /dev/null +++ b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj @@ -0,0 +1,37 @@ + + + + netstandard2.0;net45;net40 + 1.8.0-preview0815 + true + ncc;YeXiangQin + FreeSql AdoNet 扩展包,增加 IDbConnection/IDbTransaction 对象的扩展方法 Select/Insert/Update/Delete 实现 CRUD。 + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + true + key.snk + false + + + + + + + + Volo.Abp.Dapper.FreeSqlExtensions.xml + 3 + + + + + + + diff --git a/Extensions/FreeSql.Extensions.AdoNet/FreeSqlAdoNetExtensions.cs b/Extensions/FreeSql.Extensions.AdoNet/FreeSqlAdoNetExtensions.cs new file mode 100644 index 00000000..e79b09f3 --- /dev/null +++ b/Extensions/FreeSql.Extensions.AdoNet/FreeSqlAdoNetExtensions.cs @@ -0,0 +1,265 @@ +using FreeSql; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; + +public static class FreeSqlAdoNetExtensions +{ + static Dictionary _dicCurd = new Dictionary(); + static object _dicCurdLock = new object(); + static IFreeSql GetCrud(IDbConnection dbconn) + { + if (dbconn == null) throw new ArgumentNullException($"{nameof(dbconn)} 不能为 null"); ; + Type dbconType = dbconn.GetType(); + var connType = dbconType.UnderlyingSystemType; + if (_dicCurd.TryGetValue(connType, out var fsql)) return fsql; + + Type providerType = null; + switch (connType.Name) + { + case "MySqlConnection": + providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(connType); + if (providerType == null) providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); + break; + case "SqlConnection": + providerType = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); + break; + case "NpgsqlConnection": + providerType = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); + break; + case "OracleConnection": + providerType = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); + break; + case "SQLiteConnection": + providerType = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); + break; + case "DmConnection": + providerType = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Dameng.dll,可前往 nuget 下载"); + break; + case "OscarConnection": + providerType = Type.GetType("FreeSql.ShenTong.ShenTongProvider`1,FreeSql.Provider.ShenTong")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.ShenTong.dll,可前往 nuget 下载"); + break; + default: + throw new Exception("未实现"); + } + lock (_dicCurdLock) + { + if (_dicCurd.TryGetValue(connType, out fsql)) return fsql; + lock (_dicCurdLock) + _dicCurd.Add(connType, fsql = Activator.CreateInstance(providerType, new object[] { null, null, null }) as IFreeSql); + } + return fsql; + } + static IFreeSql GetCrud(IDbTransaction dbtran) + { + if (dbtran == null) throw new ArgumentNullException($"{nameof(dbtran)} 不能为 null"); + return GetCrud(dbtran.Connection); + } + + /// + /// 获取 IDbConnection 对应的 IFreeSql 实例 + /// + /// + /// + public static IFreeSql GetIFreeSql(this IDbConnection that) => GetCrud(that); + + #region IDbConnection + /// + /// 插入数据 + /// + /// + /// + public static IInsert Insert(this IDbConnection that) where T1 : class => GetCrud(that).Insert().WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体数组 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, List source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + + /// + /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + /// 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 + /// 达梦: merge into + /// 人大金仓:on conflict do update + /// 神通:merge into + /// MsAccess:不支持 + /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + /// + /// + /// + public static IInsertOrUpdate InsertOrUpdate(this IDbConnection that) where T1 : class => GetCrud(that).InsertOrUpdate().WithConnection(that as DbConnection); + + /// + /// 修改数据 + /// + /// + /// + public static IUpdate Update(this IDbConnection that) where T1 : class => GetCrud(that).Update().WithConnection(that as DbConnection); + /// + /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IUpdate Update(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithConnection(that as DbConnection); + + /// + /// 查询数据 + /// + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class => GetCrud(that).Select().WithConnection(that as DbConnection); + /// + /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static ISelect Select(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithConnection(that as DbConnection); + + /// + /// 删除数据 + /// + /// + /// + public static IDelete Delete(this IDbConnection that) where T1 : class => GetCrud(that).Delete().WithConnection(that as DbConnection); + /// + /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IDelete Delete(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithConnection(that as DbConnection); + #endregion + + #region IDbTransaction + /// + /// 插入数据 + /// + /// + /// + public static IInsert Insert(this IDbTransaction that) where T1 : class => GetCrud(that).Insert().WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体数组 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, List source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + + /// + /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + /// 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 + /// 达梦: merge into + /// 人大金仓:on conflict do update + /// 神通:merge into + /// MsAccess:不支持 + /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + /// + /// + /// + public static IInsertOrUpdate InsertOrUpdate(this IDbTransaction that) where T1 : class => GetCrud(that).InsertOrUpdate().WithTransaction(that as DbTransaction); + + /// + /// 修改数据 + /// + /// + /// + public static IUpdate Update(this IDbTransaction that) where T1 : class => GetCrud(that).Update().WithTransaction(that as DbTransaction); + /// + /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IUpdate Update(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithTransaction(that as DbTransaction); + + /// + /// 查询数据 + /// + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class => GetCrud(that).Select().WithTransaction(that as DbTransaction); + /// + /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static ISelect Select(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithTransaction(that as DbTransaction); + + /// + /// 删除数据 + /// + /// + /// + public static IDelete Delete(this IDbTransaction that) where T1 : class => GetCrud(that).Delete().WithTransaction(that as DbTransaction); + /// + /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IDelete Delete(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithTransaction(that as DbTransaction); + #endregion +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.AdoNet/Volo.Abp.Dapper.FreeSqlExtensions.xml b/Extensions/FreeSql.Extensions.AdoNet/Volo.Abp.Dapper.FreeSqlExtensions.xml new file mode 100644 index 00000000..c05792be --- /dev/null +++ b/Extensions/FreeSql.Extensions.AdoNet/Volo.Abp.Dapper.FreeSqlExtensions.xml @@ -0,0 +1,217 @@ + + + + FreeSql.Extensions.AdoNet + + + + + 获取 IDbConnection 对应的 IFreeSql 实例 + + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + diff --git a/Extensions/FreeSql.Extensions.AdoNet/key.snk b/Extensions/FreeSql.Extensions.AdoNet/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..e580bc8d5d64e7c5a0c62b971545d38cfbe7d837 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096c(W3|+clf|4d2=6Xc+R`Gd@9@k@Meh} zR8`}1=JPk=q?Zlr?i$1O?SgX-{{&z z|LRF?-aWODhAO}h_7M!wz}uPXx}n-g{((r9{{%_ z4)%gVXcj;Ru@GYAIZI@e#GBtO#O5m-Qr4X_lbAV}=qNRkd0^`@I6i9k`wSe@ZPxVo zk;MXig(S-cYHE!0GWWlp7EH@E!WkF6jS+3z4rvW0%Sq;U1bq`B9*HNJjxo*23*7Vw zHyt>{2CR~8==`lYLgAmwsXPXYZ_AEAKy|PuUz0(G)L1xO{{*n6Bn?mV~QKg!055THihpc>GOh(U-NgO?4_DzY4uq!p9=Q;`G i9;v3GkC674Mbx4_b$)?7a0%Z%&zUjzbGs@!l^s|B literal 0 HcmV?d00001 diff --git a/Extensions/FreeSql.Extensions.AdoNet/readme.md b/Extensions/FreeSql.Extensions.AdoNet/readme.md new file mode 100644 index 00000000..0513475d --- /dev/null +++ b/Extensions/FreeSql.Extensions.AdoNet/readme.md @@ -0,0 +1,19 @@ +FreeSql AdoNet 扩展包,增加 IDbConnection/IDbTransaction 对象的扩展方法 Select/Insert/Update/Delete 实现 CRUD。 + +## 如果在 abp-vnext 中使用? + +> dotnet add package FreeSql.Extensions.AdoNet + +```csharp +IDapperRepository repo = ...; + +repo.DbConnection.Select().Where(...).ToList(); + +repo.DbConnection.Insert(new T {}).ExecuteAffrows(); + +repo.DbConnection.Update().SetSource(new T {}).ExecuteAffrows(); + +repo.DbConnection.Delete().Where(...).ExecuteAffrows(); + +IFreeSql fsql = repo.DbConnection.GetFreeSql(); //获取 IFreeSql 实例 +``` diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/FreeSql.Tests.Extensions.AdoNet.csproj b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/FreeSql.Tests.Extensions.AdoNet.csproj new file mode 100644 index 00000000..09688700 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/FreeSql.Tests.Extensions.AdoNet.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp3.1 + false + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/MySqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/MySqlConnectionExtensionsTest.cs new file mode 100644 index 00000000..367fdd53 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/MySqlConnectionExtensionsTest.cs @@ -0,0 +1,70 @@ +using MySql.Data.MySqlClient; +using System; +using System.Collections.Generic; +using Xunit; + +namespace Tests.MySqlConnectionExtensions { + public class Methods { + + string _connectString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5"; + + public Methods() { + g.mysql.CodeFirst.SyncStructure(); + } + + [Fact] + public void Insert() { + var affrows = 0; + using (var conn = new MySqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Update() { + var affrows = 0; + using (var conn = new MySqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testupdate" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item = conn.Select().First(); + affrows = conn.Update().SetSource(item).Set(a => a.title, "testupdated").ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Delete() { + var affrows = 0; + using (var conn = new MySqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testdelete" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + affrows = conn.Delete().Where(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Select() { + var list = new List(); + var affrows = 0; + using (var conn = new MySqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testselect" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + list = conn.Select().Where(a => a.id == item.id).ToList(); + conn.Close(); + } + Assert.Single(list); + } + + class TestConnectionExt { + public Guid id { get; set; } + public string title { get; set; } + public DateTime createTime { get; set; } = DateTime.Now; + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/NpgsqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/NpgsqlConnectionExtensionsTest.cs new file mode 100644 index 00000000..26acbcf6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/NpgsqlConnectionExtensionsTest.cs @@ -0,0 +1,70 @@ +using Npgsql; +using System; +using System.Collections.Generic; +using Xunit; + +namespace Tests.NpgsqlConnectionExtensions { + public class Methods { + + string _connectString = "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=5"; + + public Methods() { + g.pgsql.CodeFirst.SyncStructure(); + } + + [Fact] + public void Insert() { + var affrows = 0; + using (var conn = new NpgsqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Update() { + var affrows = 0; + using (var conn = new NpgsqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testupdate" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item = conn.Select().First(); + affrows = conn.Update().SetSource(item).Set(a => a.title, "testupdated").ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Delete() { + var affrows = 0; + using (var conn = new NpgsqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testdelete" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + affrows = conn.Delete().Where(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Select() { + var list = new List(); + var affrows = 0; + using (var conn = new NpgsqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testselect" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + list = conn.Select().Where(a => a.id == item.id).ToList(); + conn.Close(); + } + Assert.Single(list); + } + + class TestConnectionExt { + public Guid id { get; set; } + public string title { get; set; } + public DateTime createTime { get; set; } = DateTime.Now; + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/OracleConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/OracleConnectionExtensionsTest.cs new file mode 100644 index 00000000..c838f938 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/OracleConnectionExtensionsTest.cs @@ -0,0 +1,70 @@ +using Oracle.ManagedDataAccess.Client; +using System; +using System.Collections.Generic; +using Xunit; + +namespace Tests.OracleConnectionExtensions { + public class Methods { + + string _connectString = "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=5"; + + public Methods() { + g.oracle.CodeFirst.SyncStructure(); + } + + [Fact] + public void Insert() { + var affrows = 0; + using (var conn = new OracleConnection(_connectString)) { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Update() { + var affrows = 0; + using (var conn = new OracleConnection(_connectString)) { + var item = new TestConnectionExt { title = "testupdate" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item = conn.Select().First(); + affrows = conn.Update().SetSource(item).Set(a => a.title, "testupdated").ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Delete() { + var affrows = 0; + using (var conn = new OracleConnection(_connectString)) { + var item = new TestConnectionExt { title = "testdelete" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + affrows = conn.Delete().Where(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Select() { + var list = new List(); + var affrows = 0; + using (var conn = new OracleConnection(_connectString)) { + var item = new TestConnectionExt { title = "testselect" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + list = conn.Select().Where(a => a.id == item.id).ToList(); + conn.Close(); + } + Assert.Single(list); + } + + class TestConnectionExt { + public Guid id { get; set; } + public string title { get; set; } + public DateTime createTime { get; set; } = DateTime.Now; + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SQLiteConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SQLiteConnectionExtensionsTest.cs new file mode 100644 index 00000000..77c2dd7c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SQLiteConnectionExtensionsTest.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.SQLite; +using Xunit; + +namespace Tests.SQLiteConnectionExtensions { + public class Methods { + + string _connectString = "Data Source=|DataDirectory|/document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=5"; + + public Methods() { + g.sqlite.CodeFirst.SyncStructure(); + } + + [Fact] + public void Insert() { + var affrows = 0; + using (var conn = new SQLiteConnection(_connectString)) { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Update() { + var affrows = 0; + using (var conn = new SQLiteConnection(_connectString)) { + var item = new TestConnectionExt { title = "testupdate" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item = conn.Select().First(); + affrows = conn.Update().SetSource(item).Set(a => a.title, "testupdated").ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Delete() { + var affrows = 0; + using (var conn = new SQLiteConnection(_connectString)) { + var item = new TestConnectionExt { title = "testdelete" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + affrows = conn.Delete().Where(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Select() { + var list = new List(); + var affrows = 0; + using (var conn = new SQLiteConnection(_connectString)) { + var item = new TestConnectionExt { title = "testselect" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + list = conn.Select().Where(a => a.id == item.id).ToList(); + conn.Close(); + } + Assert.Single(list); + } + + class TestConnectionExt { + public Guid id { get; set; } + public string title { get; set; } + public DateTime createTime { get; set; } = DateTime.Now; + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SqlConnectionExtensionsTest.cs new file mode 100644 index 00000000..e7f4329f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SqlConnectionExtensionsTest.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using Microsoft.Data.SqlClient; +using Xunit; + +namespace Tests.SqlConnectionExtensions { + public class Methods { + + string _connectString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=5"; + + public Methods() { + g.sqlserver.CodeFirst.SyncStructure(); + } + + [Fact] + public void Insert() { + var affrows = 0; + using (var conn = new SqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Update() { + var affrows = 0; + using (var conn = new SqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testupdate" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item = conn.Select().First(); + affrows = conn.Update().SetSource(item).Set(a => a.title, "testupdated").ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Delete() { + var affrows = 0; + using (var conn = new SqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testdelete" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + affrows = conn.Delete().Where(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] + public void Select() { + var list = new List(); + var affrows = 0; + using (var conn = new SqlConnection(_connectString)) { + var item = new TestConnectionExt { title = "testselect" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + list = conn.Select().Where(a => a.id == item.id).ToList(); + conn.Close(); + } + Assert.Single(list); + } + + class TestConnectionExt { + public Guid id { get; set; } + public string title { get; set; } + public DateTime createTime { get; set; } = DateTime.Now; + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/g.cs b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/g.cs new file mode 100644 index 00000000..de01953d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/g.cs @@ -0,0 +1,80 @@ +using System; +using System.Diagnostics; + + +public class g { + + static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .Build()); + public static IFreeSql sqlserver => sqlserverLazy.Value; + + static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .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") + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .UseLazyLoading(true) + .Build()); + public static IFreeSql mysql => mysqlLazy.Value; + + static Lazy pgsqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") + .UseAutoSyncStructure(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .Build()); + public static IFreeSql pgsql => pgsqlLazy.Value; + + static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .Build()); + public static IFreeSql oracle = oracleLazy.Value; + + static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => { + Trace.WriteLine(cmd.CommandText); + }, //监听SQL命令对象,在执行前 + (cmd, traceLog) => { + Console.WriteLine(traceLog); + }) //监听SQL命令对象,在执行后 + .Build()); + public static IFreeSql sqlite = sqliteLazy.Value; +} diff --git a/FreeSql.sln b/FreeSql.sln index e1c05120..8ca3a57a 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -86,6 +86,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Post EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.SqlServerForSystem", "Providers\FreeSql.Provider.SqlServerForSystem\FreeSql.Provider.SqlServerForSystem.csproj", "{3D2BD8EC-253A-437F-B4C8-74BC0D91429B}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.AdoNet", "Extensions\FreeSql.Extensions.AdoNet\FreeSql.Extensions.AdoNet.csproj", "{774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Extensions.AdoNet", "FreeSql.Tests\FreeSql.Tests.Extensions.AdoNet\FreeSql.Tests.Extensions.AdoNet.csproj", "{02B31331-9B6E-44D2-B135-38DAE92F8A40}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -528,6 +532,30 @@ Global {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x64.Build.0 = Release|Any CPU {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x86.ActiveCfg = Release|Any CPU {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x86.Build.0 = Release|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|x64.ActiveCfg = Debug|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|x64.Build.0 = Debug|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|x86.ActiveCfg = Debug|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|x86.Build.0 = Debug|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|Any CPU.Build.0 = Release|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|x64.ActiveCfg = Release|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|x64.Build.0 = Release|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|x86.ActiveCfg = Release|Any CPU + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|x86.Build.0 = Release|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|x64.ActiveCfg = Debug|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|x64.Build.0 = Debug|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|x86.ActiveCfg = Debug|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|x86.Build.0 = Debug|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|Any CPU.Build.0 = Release|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|x64.ActiveCfg = Release|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|x64.Build.0 = Release|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|x86.ActiveCfg = Release|Any CPU + {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -558,6 +586,7 @@ Global {07AB0B37-A8B1-4FB1-9259-7B804E369E36} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {938173AF-157F-4040-AED3-171DA1809CAA} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {3D2BD8EC-253A-437F-B4C8-74BC0D91429B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} From 4ba6e087e1a0158c495a3f184ee5bb91272a5142 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 16 Aug 2020 02:05:53 +0800 Subject: [PATCH 0830/1029] update readme --- Extensions/FreeSql.Extensions.AdoNet/readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Extensions/FreeSql.Extensions.AdoNet/readme.md b/Extensions/FreeSql.Extensions.AdoNet/readme.md index 0513475d..a7ad6912 100644 --- a/Extensions/FreeSql.Extensions.AdoNet/readme.md +++ b/Extensions/FreeSql.Extensions.AdoNet/readme.md @@ -2,6 +2,10 @@ ## 如果在 abp-vnext 中使用? +本方法依赖 Volo.Abp.Dapper,所以也依赖 Volo.Abp.EntityFrameworkCore + +提示:FreeSql 兼容 EFCore 99% 的实体特性 + > dotnet add package FreeSql.Extensions.AdoNet ```csharp From f0b09f468c1ba6eb3cf4de5111da46e9c8e16b29 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 16 Aug 2020 03:32:06 +0800 Subject: [PATCH 0831/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20DbUpdateVers?= =?UTF-8?q?ionException=20IsVersion=20=E8=A1=8C=E7=89=88=E6=9C=AC=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.AdoNet.csproj | 2 +- ...ions.xml => FreeSql.Extensions.AdoNet.xml} | 0 FreeSql.DbContext/FreeSql.DbContext.xml | 9 ---- FreeSql/FreeSql.xml | 30 +++++++++++ .../Internal/CommonProvider/UpdateProvider.cs | 6 +-- .../CommonProvider/UpdateProviderAsync.cs | 2 +- .../Exception/DbUpdateVersionException.cs | 50 +++++++++++++++++++ .../Curd/MySqlUpdate.cs | 4 +- .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 4 +- .../MySql/Curd/OdbcMySqlUpdate.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 4 +- .../Curd/PostgreSQLUpdate.cs | 4 +- .../Curd/ShenTongUpdate.cs | 4 +- .../Curd/SqlServerUpdate.cs | 4 +- 15 files changed, 101 insertions(+), 30 deletions(-) rename Extensions/FreeSql.Extensions.AdoNet/{Volo.Abp.Dapper.FreeSqlExtensions.xml => FreeSql.Extensions.AdoNet.xml} (100%) create mode 100644 FreeSql/Internal/Exception/DbUpdateVersionException.cs diff --git a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj index d1b1a589..cb964f9e 100644 --- a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj +++ b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj @@ -26,7 +26,7 @@ - Volo.Abp.Dapper.FreeSqlExtensions.xml + FreeSql.Extensions.AdoNet.xml 3 diff --git a/Extensions/FreeSql.Extensions.AdoNet/Volo.Abp.Dapper.FreeSqlExtensions.xml b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.xml similarity index 100% rename from Extensions/FreeSql.Extensions.AdoNet/Volo.Abp.Dapper.FreeSqlExtensions.xml rename to Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.xml diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..c46aa1e3 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -527,14 +527,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c71bee29..71cbd656 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3237,6 +3237,36 @@ Dict:key=属性名,value=注释 + + + 更新实体的元数据 + + + + + 执行更新的 SQL + + + + + 执行更新命令的参数 + + + + + 执行更新命令影响的行 + + + + + 更新的实体数量 + + + + + 更新的实体 + + 创建一个过滤器 diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 72a31b3b..8680da3e 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -109,12 +109,12 @@ namespace FreeSql.Internal.CommonProvider return this; } - protected void ValidateVersionAndThrow(int affrows) + protected void ValidateVersionAndThrow(int affrows, string sql, DbParameter[] dbParms) { if (_table.VersionColumn != null && _source.Count > 0) { if (affrows != _source.Count) - throw new Exception($"记录可能不存在,或者【行级乐观锁】版本过旧,更新数量{_source.Count},影响的行数{affrows}。"); + throw new DbUpdateVersionException($"记录可能不存在,或者【行级乐观锁】版本过旧,更新数量{_source.Count},影响的行数{affrows}。", _table, sql, dbParms, affrows, _source.Select(a => (object)a)); foreach (var d in _source) _orm.SetEntityIncrByWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, 1); } @@ -299,7 +299,7 @@ namespace FreeSql.Internal.CommonProvider try { affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(affrows); + ValidateVersionAndThrow(affrows, sql, dbParms); } catch (Exception ex) { diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index 2e85688f..4d0194aa 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -168,7 +168,7 @@ namespace FreeSql.Internal.CommonProvider try { affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(affrows); + ValidateVersionAndThrow(affrows, sql, dbParms); } catch (Exception ex) { diff --git a/FreeSql/Internal/Exception/DbUpdateVersionException.cs b/FreeSql/Internal/Exception/DbUpdateVersionException.cs new file mode 100644 index 00000000..d41ce6b1 --- /dev/null +++ b/FreeSql/Internal/Exception/DbUpdateVersionException.cs @@ -0,0 +1,50 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.Internal +{ + public class DbUpdateVersionException : Exception + { + public DbUpdateVersionException(string message, TableInfo table, string sql, DbParameter[] dbParms, int affrows, IEnumerable source) : + base(message) + { + this.Table = table; + this.Sql = sql; + this.DbParams = DbParams; + this.Affrows = affrows; + this.EntitySource = source; + this.EntitySourceCount = source.Count(); + } + + /// + /// 更新实体的元数据 + /// + public TableInfo Table { get; } + /// + /// 执行更新的 SQL + /// + public string Sql { get; } + /// + /// 执行更新命令的参数 + /// + public DbParameter[] DbParams { get; } + + /// + /// 执行更新命令影响的行 + /// + public int Affrows { get; } + /// + /// 更新的实体数量 + /// + public int EntitySourceCount { get; } + + /// + /// 更新的实体 + /// + public IEnumerable EntitySource { get; } + } +} diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 6bb18142..35a98726 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.MySql.Curd try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { @@ -133,7 +133,7 @@ namespace FreeSql.MySql.Curd try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index 44f5013d..a4585379 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.KingbaseES try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { @@ -150,7 +150,7 @@ namespace FreeSql.Odbc.KingbaseES try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index ded5aa0c..edabbb1f 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.Odbc.MySql try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { @@ -133,7 +133,7 @@ namespace FreeSql.Odbc.MySql try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index b713b56b..33ab8a7f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.PostgreSQL try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { @@ -150,7 +150,7 @@ namespace FreeSql.Odbc.PostgreSQL try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index 9d441c5a..a03413b5 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -50,7 +50,7 @@ namespace FreeSql.Odbc.SqlServer try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { @@ -134,7 +134,7 @@ namespace FreeSql.Odbc.SqlServer try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 6991e799..04b8fd09 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -53,7 +53,7 @@ namespace FreeSql.PostgreSQL.Curd try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { @@ -150,7 +150,7 @@ namespace FreeSql.PostgreSQL.Curd try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index c5ca315e..645ab6ad 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -54,7 +54,7 @@ namespace FreeSql.ShenTong.Curd try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { @@ -151,7 +151,7 @@ namespace FreeSql.ShenTong.Curd try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index 02df6442..a6ba72af 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -51,7 +51,7 @@ namespace FreeSql.SqlServer.Curd try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { @@ -135,7 +135,7 @@ namespace FreeSql.SqlServer.Curd try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); - ValidateVersionAndThrow(ret.Count); + ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) { From 8c6ea70663f1dad97d59cf96de3d3cc6714fc73b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 16 Aug 2020 03:56:47 +0800 Subject: [PATCH 0832/1029] update Authors --- .../FreeSql.Extensions.AdoNet.csproj | 2 +- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj index cb964f9e..693e24bf 100644 --- a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj +++ b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql AdoNet 扩展包,增加 IDbConnection/IDbTransaction 对象的扩展方法 Select/Insert/Update/Delete 实现 CRUD。 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d16994ed..46c12e2f 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 8b615ea2..0affadca 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 318c14ab..9436ad33 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -4,7 +4,7 @@ netstandard2.0;netstandard2.1;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 15ab1ddd..7860452c 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index e16c37d5..e471eae9 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -6,7 +6,7 @@ true true true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin 2881099 FreeSql 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index e3c96b3a..06df2d66 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 https://github.com/2881099/FreeSql.DbContext FreeSql ORM DbContext diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 53f59d50..e36bfc7b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -4,7 +4,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access https://github.com/2881099/FreeSql/wiki/DbContext FreeSql ORM DbContext diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index c46aa1e3..2acb6679 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -527,5 +527,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 99b0fce7..bb587f1d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -3,7 +3,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.8.0-preview0815 - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7a040edd..45a71714 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 2d03ba3b..97bf06ce 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index fa8de250..8e112662 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 66f6a2ea..e96d4a74 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -4,7 +4,7 @@ netstandard2.0;net452;net451;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index be7588c7..02bf708d 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 711dd803..a2190dd0 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 40a22761..dcbf26ef 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8227bb23..c8b38490 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -4,7 +4,7 @@ netstandard2.0;net461;net452;net451;net45 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 42e9d494..ef623bec 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b37e0c0d..975ad172 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -4,7 +4,7 @@ netstandard2.0;net451;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index c8ee19e0..1a6c5ddc 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -4,7 +4,7 @@ netstandard2.0;net451;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index fc2528c9..d7d6c49c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -4,7 +4,7 @@ netstandard2.0;net45;net40 1.8.0-preview0815 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql From 7c89aafe792b91d16528ca2e28ab76c62aacf1eb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 16 Aug 2020 04:26:54 +0800 Subject: [PATCH 0833/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IDbConnectio?= =?UTF-8?q?n/IDbTransaction=20=E5=AF=B9=E8=B1=A1=E7=9A=84=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E6=96=B9=E6=B3=95=20Select/Insert/Update/Delete=20?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20CRUD=20#267=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.AdoNet.csproj | 37 --- .../FreeSql.Extensions.AdoNet.xml | 217 -------------- .../FreeSqlAdoNetExtensions.cs | 265 ------------------ Extensions/FreeSql.Extensions.AdoNet/key.snk | Bin 596 -> 0 bytes .../FreeSql.Extensions.AdoNet/readme.md | 23 -- .../FreeSql.Tests.Extensions.AdoNet.csproj | 26 -- .../FreeSql.Tests.Extensions.AdoNet/g.cs | 80 ------ .../MySqlConnectionExtensionsTest.cs | 2 +- .../NpgsqlConnectionExtensionsTest.cs | 2 +- .../OracleConnectionExtensionsTest.cs | 2 +- .../SQLiteConnectionExtensionsTest.cs | 2 +- .../SqlConnectionExtensionsTest.cs | 2 +- FreeSql.sln | 29 -- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 262 +++++++++++++++++ FreeSql/FreeSql.xml | 209 ++++++++++++++ 15 files changed, 476 insertions(+), 682 deletions(-) delete mode 100644 Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj delete mode 100644 Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.xml delete mode 100644 Extensions/FreeSql.Extensions.AdoNet/FreeSqlAdoNetExtensions.cs delete mode 100644 Extensions/FreeSql.Extensions.AdoNet/key.snk delete mode 100644 Extensions/FreeSql.Extensions.AdoNet/readme.md delete mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/FreeSql.Tests.Extensions.AdoNet.csproj delete mode 100644 FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/g.cs rename FreeSql.Tests/{FreeSql.Tests.Extensions.AdoNet => FreeSql.Tests/AdoNetExtensions}/MySqlConnectionExtensionsTest.cs (97%) rename FreeSql.Tests/{FreeSql.Tests.Extensions.AdoNet => FreeSql.Tests/AdoNetExtensions}/NpgsqlConnectionExtensionsTest.cs (96%) rename FreeSql.Tests/{FreeSql.Tests.Extensions.AdoNet => FreeSql.Tests/AdoNetExtensions}/OracleConnectionExtensionsTest.cs (96%) rename FreeSql.Tests/{FreeSql.Tests.Extensions.AdoNet => FreeSql.Tests/AdoNetExtensions}/SQLiteConnectionExtensionsTest.cs (96%) rename FreeSql.Tests/{FreeSql.Tests.Extensions.AdoNet => FreeSql.Tests/AdoNetExtensions}/SqlConnectionExtensionsTest.cs (97%) diff --git a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj deleted file mode 100644 index 693e24bf..00000000 --- a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - netstandard2.0;net45;net40 - 1.8.0-preview0815 - true - FreeSql;ncc;YeXiangQin - FreeSql AdoNet 扩展包,增加 IDbConnection/IDbTransaction 对象的扩展方法 Select/Insert/Update/Delete 实现 CRUD。 - https://github.com/2881099/FreeSql - https://github.com/2881099/FreeSql - git - MIT - FreeSql;ORM - $(AssemblyName) - logo.png - $(AssemblyName) - true - true - true - key.snk - false - - - - - - - - FreeSql.Extensions.AdoNet.xml - 3 - - - - - - - diff --git a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.xml b/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.xml deleted file mode 100644 index c05792be..00000000 --- a/Extensions/FreeSql.Extensions.AdoNet/FreeSql.Extensions.AdoNet.xml +++ /dev/null @@ -1,217 +0,0 @@ - - - - FreeSql.Extensions.AdoNet - - - - - 获取 IDbConnection 对应的 IFreeSql 实例 - - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - diff --git a/Extensions/FreeSql.Extensions.AdoNet/FreeSqlAdoNetExtensions.cs b/Extensions/FreeSql.Extensions.AdoNet/FreeSqlAdoNetExtensions.cs deleted file mode 100644 index e79b09f3..00000000 --- a/Extensions/FreeSql.Extensions.AdoNet/FreeSqlAdoNetExtensions.cs +++ /dev/null @@ -1,265 +0,0 @@ -using FreeSql; -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; - -public static class FreeSqlAdoNetExtensions -{ - static Dictionary _dicCurd = new Dictionary(); - static object _dicCurdLock = new object(); - static IFreeSql GetCrud(IDbConnection dbconn) - { - if (dbconn == null) throw new ArgumentNullException($"{nameof(dbconn)} 不能为 null"); ; - Type dbconType = dbconn.GetType(); - var connType = dbconType.UnderlyingSystemType; - if (_dicCurd.TryGetValue(connType, out var fsql)) return fsql; - - Type providerType = null; - switch (connType.Name) - { - case "MySqlConnection": - providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(connType); - if (providerType == null) providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); - break; - case "SqlConnection": - providerType = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); - break; - case "NpgsqlConnection": - providerType = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); - break; - case "OracleConnection": - providerType = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); - break; - case "SQLiteConnection": - providerType = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); - break; - case "DmConnection": - providerType = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Dameng.dll,可前往 nuget 下载"); - break; - case "OscarConnection": - providerType = Type.GetType("FreeSql.ShenTong.ShenTongProvider`1,FreeSql.Provider.ShenTong")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.ShenTong.dll,可前往 nuget 下载"); - break; - default: - throw new Exception("未实现"); - } - lock (_dicCurdLock) - { - if (_dicCurd.TryGetValue(connType, out fsql)) return fsql; - lock (_dicCurdLock) - _dicCurd.Add(connType, fsql = Activator.CreateInstance(providerType, new object[] { null, null, null }) as IFreeSql); - } - return fsql; - } - static IFreeSql GetCrud(IDbTransaction dbtran) - { - if (dbtran == null) throw new ArgumentNullException($"{nameof(dbtran)} 不能为 null"); - return GetCrud(dbtran.Connection); - } - - /// - /// 获取 IDbConnection 对应的 IFreeSql 实例 - /// - /// - /// - public static IFreeSql GetIFreeSql(this IDbConnection that) => GetCrud(that); - - #region IDbConnection - /// - /// 插入数据 - /// - /// - /// - public static IInsert Insert(this IDbConnection that) where T1 : class => GetCrud(that).Insert().WithConnection(that as DbConnection); - /// - /// 插入数据,传入实体 - /// - /// - /// - /// - public static IInsert Insert(this IDbConnection that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); - /// - /// 插入数据,传入实体数组 - /// - /// - /// - /// - public static IInsert Insert(this IDbConnection that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - public static IInsert Insert(this IDbConnection that, List source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - public static IInsert Insert(this IDbConnection that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); - - /// - /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - /// 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 - /// 达梦: merge into - /// 人大金仓:on conflict do update - /// 神通:merge into - /// MsAccess:不支持 - /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) - /// - /// - /// - public static IInsertOrUpdate InsertOrUpdate(this IDbConnection that) where T1 : class => GetCrud(that).InsertOrUpdate().WithConnection(that as DbConnection); - - /// - /// 修改数据 - /// - /// - /// - public static IUpdate Update(this IDbConnection that) where T1 : class => GetCrud(that).Update().WithConnection(that as DbConnection); - /// - /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static IUpdate Update(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithConnection(that as DbConnection); - - /// - /// 查询数据 - /// - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class => GetCrud(that).Select().WithConnection(that as DbConnection); - /// - /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static ISelect Select(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithConnection(that as DbConnection); - - /// - /// 删除数据 - /// - /// - /// - public static IDelete Delete(this IDbConnection that) where T1 : class => GetCrud(that).Delete().WithConnection(that as DbConnection); - /// - /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static IDelete Delete(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithConnection(that as DbConnection); - #endregion - - #region IDbTransaction - /// - /// 插入数据 - /// - /// - /// - public static IInsert Insert(this IDbTransaction that) where T1 : class => GetCrud(that).Insert().WithTransaction(that as DbTransaction); - /// - /// 插入数据,传入实体 - /// - /// - /// - /// - public static IInsert Insert(this IDbTransaction that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); - /// - /// 插入数据,传入实体数组 - /// - /// - /// - /// - public static IInsert Insert(this IDbTransaction that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - public static IInsert Insert(this IDbTransaction that, List source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - public static IInsert Insert(this IDbTransaction that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); - - /// - /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - /// 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 - /// 达梦: merge into - /// 人大金仓:on conflict do update - /// 神通:merge into - /// MsAccess:不支持 - /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) - /// - /// - /// - public static IInsertOrUpdate InsertOrUpdate(this IDbTransaction that) where T1 : class => GetCrud(that).InsertOrUpdate().WithTransaction(that as DbTransaction); - - /// - /// 修改数据 - /// - /// - /// - public static IUpdate Update(this IDbTransaction that) where T1 : class => GetCrud(that).Update().WithTransaction(that as DbTransaction); - /// - /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static IUpdate Update(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithTransaction(that as DbTransaction); - - /// - /// 查询数据 - /// - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class => GetCrud(that).Select().WithTransaction(that as DbTransaction); - /// - /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static ISelect Select(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithTransaction(that as DbTransaction); - - /// - /// 删除数据 - /// - /// - /// - public static IDelete Delete(this IDbTransaction that) where T1 : class => GetCrud(that).Delete().WithTransaction(that as DbTransaction); - /// - /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static IDelete Delete(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithTransaction(that as DbTransaction); - #endregion -} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.AdoNet/key.snk b/Extensions/FreeSql.Extensions.AdoNet/key.snk deleted file mode 100644 index e580bc8d5d64e7c5a0c62b971545d38cfbe7d837..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096c(W3|+clf|4d2=6Xc+R`Gd@9@k@Meh} zR8`}1=JPk=q?Zlr?i$1O?SgX-{{&z z|LRF?-aWODhAO}h_7M!wz}uPXx}n-g{((r9{{%_ z4)%gVXcj;Ru@GYAIZI@e#GBtO#O5m-Qr4X_lbAV}=qNRkd0^`@I6i9k`wSe@ZPxVo zk;MXig(S-cYHE!0GWWlp7EH@E!WkF6jS+3z4rvW0%Sq;U1bq`B9*HNJjxo*23*7Vw zHyt>{2CR~8==`lYLgAmwsXPXYZ_AEAKy|PuUz0(G)L1xO{{*n6Bn?mV~QKg!055THihpc>GOh(U-NgO?4_DzY4uq!p9=Q;`G i9;v3GkC674Mbx4_b$)?7a0%Z%&zUjzbGs@!l^s|B diff --git a/Extensions/FreeSql.Extensions.AdoNet/readme.md b/Extensions/FreeSql.Extensions.AdoNet/readme.md deleted file mode 100644 index a7ad6912..00000000 --- a/Extensions/FreeSql.Extensions.AdoNet/readme.md +++ /dev/null @@ -1,23 +0,0 @@ -FreeSql AdoNet 扩展包,增加 IDbConnection/IDbTransaction 对象的扩展方法 Select/Insert/Update/Delete 实现 CRUD。 - -## 如果在 abp-vnext 中使用? - -本方法依赖 Volo.Abp.Dapper,所以也依赖 Volo.Abp.EntityFrameworkCore - -提示:FreeSql 兼容 EFCore 99% 的实体特性 - -> dotnet add package FreeSql.Extensions.AdoNet - -```csharp -IDapperRepository repo = ...; - -repo.DbConnection.Select().Where(...).ToList(); - -repo.DbConnection.Insert(new T {}).ExecuteAffrows(); - -repo.DbConnection.Update().SetSource(new T {}).ExecuteAffrows(); - -repo.DbConnection.Delete().Where(...).ExecuteAffrows(); - -IFreeSql fsql = repo.DbConnection.GetFreeSql(); //获取 IFreeSql 实例 -``` diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/FreeSql.Tests.Extensions.AdoNet.csproj b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/FreeSql.Tests.Extensions.AdoNet.csproj deleted file mode 100644 index 09688700..00000000 --- a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/FreeSql.Tests.Extensions.AdoNet.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - netcoreapp3.1 - false - - - - - - - - - - - - - - - - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/g.cs b/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/g.cs deleted file mode 100644 index de01953d..00000000 --- a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/g.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Diagnostics; - - -public class g { - - static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseLazyLoading(true) - .Build()); - public static IFreeSql sqlserver => sqlserverLazy.Value; - - static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .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") - .UseAutoSyncStructure(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .UseLazyLoading(true) - .Build()); - public static IFreeSql mysql => mysqlLazy.Value; - - static Lazy pgsqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") - .UseAutoSyncStructure(true) - .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) - .UseLazyLoading(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build()); - public static IFreeSql pgsql => pgsqlLazy.Value; - - static Lazy oracleLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) - //.UseNoneCommandParameter(true) - - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build()); - public static IFreeSql oracle = oracleLazy.Value; - - static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") - .UseAutoSyncStructure(true) - .UseLazyLoading(true) - .UseMonitorCommand( - cmd => { - Trace.WriteLine(cmd.CommandText); - }, //监听SQL命令对象,在执行前 - (cmd, traceLog) => { - Console.WriteLine(traceLog); - }) //监听SQL命令对象,在执行后 - .Build()); - public static IFreeSql sqlite = sqliteLazy.Value; -} diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/MySqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs similarity index 97% rename from FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/MySqlConnectionExtensionsTest.cs rename to FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs index 367fdd53..c16eb020 100644 --- a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/MySqlConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using Xunit; -namespace Tests.MySqlConnectionExtensions { +namespace FreeSql.Tests.AdoNetExtensions.MySqlConnectionExtensions { public class Methods { string _connectString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5"; diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/NpgsqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/NpgsqlConnectionExtensionsTest.cs similarity index 96% rename from FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/NpgsqlConnectionExtensionsTest.cs rename to FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/NpgsqlConnectionExtensionsTest.cs index 26acbcf6..18b70be9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/NpgsqlConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/NpgsqlConnectionExtensionsTest.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using Xunit; -namespace Tests.NpgsqlConnectionExtensions { +namespace FreeSql.Tests.AdoNetExtensions.NpgsqlConnectionExtensions { public class Methods { string _connectString = "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=5"; diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/OracleConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/OracleConnectionExtensionsTest.cs similarity index 96% rename from FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/OracleConnectionExtensionsTest.cs rename to FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/OracleConnectionExtensionsTest.cs index c838f938..faec49a6 100644 --- a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/OracleConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/OracleConnectionExtensionsTest.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using Xunit; -namespace Tests.OracleConnectionExtensions { +namespace FreeSql.Tests.AdoNetExtensions.OracleConnectionExtensions { public class Methods { string _connectString = "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=5"; diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SQLiteConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SQLiteConnectionExtensionsTest.cs similarity index 96% rename from FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SQLiteConnectionExtensionsTest.cs rename to FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SQLiteConnectionExtensionsTest.cs index 77c2dd7c..9ee8faa0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SQLiteConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SQLiteConnectionExtensionsTest.cs @@ -5,7 +5,7 @@ using System.Data.Common; using System.Data.SQLite; using Xunit; -namespace Tests.SQLiteConnectionExtensions { +namespace FreeSql.Tests.AdoNetExtensions.SQLiteConnectionExtensions { public class Methods { string _connectString = "Data Source=|DataDirectory|/document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=5"; diff --git a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SqlConnectionExtensionsTest.cs similarity index 97% rename from FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SqlConnectionExtensionsTest.cs rename to FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SqlConnectionExtensionsTest.cs index e7f4329f..ca6a80ea 100644 --- a/FreeSql.Tests/FreeSql.Tests.Extensions.AdoNet/SqlConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SqlConnectionExtensionsTest.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using Microsoft.Data.SqlClient; using Xunit; -namespace Tests.SqlConnectionExtensions { +namespace FreeSql.Tests.AdoNetExtensions.SqlConnectionExtensions { public class Methods { string _connectString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=5"; diff --git a/FreeSql.sln b/FreeSql.sln index 8ca3a57a..e1c05120 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -86,10 +86,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Post EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.SqlServerForSystem", "Providers\FreeSql.Provider.SqlServerForSystem\FreeSql.Provider.SqlServerForSystem.csproj", "{3D2BD8EC-253A-437F-B4C8-74BC0D91429B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.AdoNet", "Extensions\FreeSql.Extensions.AdoNet\FreeSql.Extensions.AdoNet.csproj", "{774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Extensions.AdoNet", "FreeSql.Tests\FreeSql.Tests.Extensions.AdoNet\FreeSql.Tests.Extensions.AdoNet.csproj", "{02B31331-9B6E-44D2-B135-38DAE92F8A40}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -532,30 +528,6 @@ Global {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x64.Build.0 = Release|Any CPU {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x86.ActiveCfg = Release|Any CPU {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x86.Build.0 = Release|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|x64.ActiveCfg = Debug|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|x64.Build.0 = Debug|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|x86.ActiveCfg = Debug|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Debug|x86.Build.0 = Debug|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|Any CPU.Build.0 = Release|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|x64.ActiveCfg = Release|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|x64.Build.0 = Release|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|x86.ActiveCfg = Release|Any CPU - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD}.Release|x86.Build.0 = Release|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|Any CPU.Build.0 = Debug|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|x64.ActiveCfg = Debug|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|x64.Build.0 = Debug|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|x86.ActiveCfg = Debug|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Debug|x86.Build.0 = Debug|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|Any CPU.ActiveCfg = Release|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|Any CPU.Build.0 = Release|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|x64.ActiveCfg = Release|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|x64.Build.0 = Release|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|x86.ActiveCfg = Release|Any CPU - {02B31331-9B6E-44D2-B135-38DAE92F8A40}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -586,7 +558,6 @@ Global {07AB0B37-A8B1-4FB1-9259-7B804E369E36} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {938173AF-157F-4040-AED3-171DA1809CAA} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {3D2BD8EC-253A-437F-B4C8-74BC0D91429B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} - {774A7AAD-60F2-40E2-93E1-E74FC2C1BBFD} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 416646bc..e72c637b 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -7,6 +7,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Data.Common; using System.Drawing; using System.Linq; using System.Linq.Expressions; @@ -511,4 +512,265 @@ SELECT "); return newSelect; } #endregion + + #region Ado.net 扩展方法,类似于 Dapper + + static Dictionary _dicCurd = new Dictionary(); + static object _dicCurdLock = new object(); + static IFreeSql GetCrud(IDbConnection dbconn) + { + if (dbconn == null) throw new ArgumentNullException($"{nameof(dbconn)} 不能为 null"); ; + Type dbconType = dbconn.GetType(); + var connType = dbconType.UnderlyingSystemType; + if (_dicCurd.TryGetValue(connType, out var fsql)) return fsql; + + Type providerType = null; + switch (connType.Name) + { + case "MySqlConnection": + providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(connType); + if (providerType == null) providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); + break; + case "SqlConnection": + providerType = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); + break; + case "NpgsqlConnection": + providerType = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); + break; + case "OracleConnection": + providerType = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); + break; + case "SQLiteConnection": + providerType = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); + break; + case "DmConnection": + providerType = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Dameng.dll,可前往 nuget 下载"); + break; + case "OscarConnection": + providerType = Type.GetType("FreeSql.ShenTong.ShenTongProvider`1,FreeSql.Provider.ShenTong")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.ShenTong.dll,可前往 nuget 下载"); + break; + default: + throw new Exception("未实现"); + } + lock (_dicCurdLock) + { + if (_dicCurd.TryGetValue(connType, out fsql)) return fsql; + lock (_dicCurdLock) + _dicCurd.Add(connType, fsql = Activator.CreateInstance(providerType, new object[] { null, null, null }) as IFreeSql); + } + return fsql; + } + static IFreeSql GetCrud(IDbTransaction dbtran) + { + if (dbtran == null) throw new ArgumentNullException($"{nameof(dbtran)} 不能为 null"); + return GetCrud(dbtran.Connection); + } + + /// + /// 获取 IDbConnection 对应的 IFreeSql 实例 + /// + /// + /// + public static IFreeSql GetIFreeSql(this IDbConnection that) => GetCrud(that); + + #region IDbConnection + /// + /// 插入数据 + /// + /// + /// + public static IInsert Insert(this IDbConnection that) where T1 : class => GetCrud(that).Insert().WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体数组 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, List source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + + /// + /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + /// 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 + /// 达梦: merge into + /// 人大金仓:on conflict do update + /// 神通:merge into + /// MsAccess:不支持 + /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + /// + /// + /// + public static IInsertOrUpdate InsertOrUpdate(this IDbConnection that) where T1 : class => GetCrud(that).InsertOrUpdate().WithConnection(that as DbConnection); + + /// + /// 修改数据 + /// + /// + /// + public static IUpdate Update(this IDbConnection that) where T1 : class => GetCrud(that).Update().WithConnection(that as DbConnection); + /// + /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IUpdate Update(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithConnection(that as DbConnection); + + /// + /// 查询数据 + /// + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class => GetCrud(that).Select().WithConnection(that as DbConnection); + /// + /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static ISelect Select(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithConnection(that as DbConnection); + + /// + /// 删除数据 + /// + /// + /// + public static IDelete Delete(this IDbConnection that) where T1 : class => GetCrud(that).Delete().WithConnection(that as DbConnection); + /// + /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IDelete Delete(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithConnection(that as DbConnection); + #endregion + + #region IDbTransaction + /// + /// 插入数据 + /// + /// + /// + public static IInsert Insert(this IDbTransaction that) where T1 : class => GetCrud(that).Insert().WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体数组 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, List source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + + /// + /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + /// 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 + /// 达梦: merge into + /// 人大金仓:on conflict do update + /// 神通:merge into + /// MsAccess:不支持 + /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + /// + /// + /// + public static IInsertOrUpdate InsertOrUpdate(this IDbTransaction that) where T1 : class => GetCrud(that).InsertOrUpdate().WithTransaction(that as DbTransaction); + + /// + /// 修改数据 + /// + /// + /// + public static IUpdate Update(this IDbTransaction that) where T1 : class => GetCrud(that).Update().WithTransaction(that as DbTransaction); + /// + /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IUpdate Update(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithTransaction(that as DbTransaction); + + /// + /// 查询数据 + /// + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class => GetCrud(that).Select().WithTransaction(that as DbTransaction); + /// + /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static ISelect Select(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithTransaction(that as DbTransaction); + + /// + /// 删除数据 + /// + /// + /// + public static IDelete Delete(this IDbTransaction that) where T1 : class => GetCrud(that).Delete().WithTransaction(that as DbTransaction); + /// + /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IDelete Delete(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithTransaction(that as DbTransaction); + #endregion + + #endregion } \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 71cbd656..2bff73de 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3853,6 +3853,215 @@ 递归层级 + + + 获取 IDbConnection 对应的 IFreeSql 实例 + + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + 使用 and 拼接两个 lambda 表达式 From 46c187e4462f4d1e020c52cced77f04a964f58b8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 16 Aug 2020 15:28:49 +0800 Subject: [PATCH 0834/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20Ado.Net=20?= =?UTF-8?q?=E5=A4=9A=E8=A1=A8=E7=9A=84=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= =?UTF-8?q?=20Select=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnectionExtensionsTest.cs | 7 ++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 110 ++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs index c16eb020..7f4a3296 100644 --- a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs @@ -1,6 +1,7 @@ using MySql.Data.MySqlClient; using System; using System.Collections.Generic; +using System.Diagnostics; using Xunit; namespace FreeSql.Tests.AdoNetExtensions.MySqlConnectionExtensions { @@ -10,6 +11,12 @@ namespace FreeSql.Tests.AdoNetExtensions.MySqlConnectionExtensions { public Methods() { g.mysql.CodeFirst.SyncStructure(); + using (var conn = new MySqlConnection(_connectString)) + { + var fsql = conn.GetIFreeSql(); + fsql.CodeFirst.IsNoneCommandParameter = true; + fsql.Aop.CommandBefore += (_, e) => Trace.WriteLine("SQL: " + e.Command.CommandText); + } } [Fact] diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index e72c637b..8870e1c3 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -674,6 +674,61 @@ SELECT "); /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IDelete Delete(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithConnection(that as DbConnection); + + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class => + GetCrud(that).Select().From((s, b) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class => + GetCrud(that).Select().From((s, b, c) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class => + GetCrud(that).Select().From((s, b, c, d) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => + GetCrud(that).Select().From((s, b, c, d, e) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => + GetCrud(that).Select().From((s, b, c, d, e, f) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => + GetCrud(that).Select().From((s, b, c, d, e, f, g) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) 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 => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) 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 => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i, j) => s); #endregion #region IDbTransaction @@ -770,6 +825,61 @@ SELECT "); /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IDelete Delete(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithTransaction(that as DbTransaction); + + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class => + GetCrud(that).Select().From((s, b) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class => + GetCrud(that).Select().From((s, b, c) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class => + GetCrud(that).Select().From((s, b, c, d) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => + GetCrud(that).Select().From((s, b, c, d, e) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => + GetCrud(that).Select().From((s, b, c, d, e, f) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => + GetCrud(that).Select().From((s, b, c, d, e, f, g) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) 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 => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) 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 => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i, j) => s); #endregion #endregion From d6853e93fec47cfa83de2738f7691a6083981df1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 16 Aug 2020 15:38:00 +0800 Subject: [PATCH 0835/1029] arrange code --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 -- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 5 +- FreeSql/FreeSql.xml | 108 ++++++++++++++++++ 3 files changed, 112 insertions(+), 10 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2acb6679..c46aa1e3 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -527,14 +527,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 8870e1c3..7ce20615 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -17,6 +17,7 @@ using System.Threading; public static partial class FreeSqlGlobalExtensions { + #region Type 对象扩展方法 static Lazy> _dicIsNumberType = new Lazy>(() => new Dictionary { [typeof(sbyte)] = true, @@ -167,6 +168,7 @@ public static partial class FreeSqlGlobalExtensions } return dict; }); + #endregion /// /// 测量两个经纬度的距离,返回单位:米 @@ -183,6 +185,7 @@ public static partial class FreeSqlGlobalExtensions 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; } + #region Enum 对象扩展方法 static ConcurrentDictionary _dicGetFields = new ConcurrentDictionary(); public static object GetEnum(this IDataReader dr, int index) { @@ -195,7 +198,6 @@ public static partial class FreeSqlGlobalExtensions } return null; } - public static string ToDescriptionOrString(this Enum item) { string name = item.ToString(); @@ -218,6 +220,7 @@ public static partial class FreeSqlGlobalExtensions } return ret; } + #endregion /// /// 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 2bff73de..07cb2cc2 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3961,6 +3961,60 @@ 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + 插入数据 @@ -4062,6 +4116,60 @@ 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + 使用 and 拼接两个 lambda 表达式 From 4acbc712d69bb15df2aefb95dbd35008a4ac1779 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 17 Aug 2020 07:02:32 +0800 Subject: [PATCH 0836/1029] =?UTF-8?q?-=20=E4=BF=AE=E6=AD=A3=20UnitOfWorkMa?= =?UTF-8?q?nager=20Requierd=20=E5=91=BD=E5=90=8D=E4=B8=BA=20Required?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TransactionalAttribute.cs | 2 +- .../UnitOfWork/UnitOfWorkManager.cs | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Examples/aspnetcore_transaction/TransactionalAttribute.cs b/Examples/aspnetcore_transaction/TransactionalAttribute.cs index 71f8cbc4..2dd58ad2 100644 --- a/Examples/aspnetcore_transaction/TransactionalAttribute.cs +++ b/Examples/aspnetcore_transaction/TransactionalAttribute.cs @@ -14,7 +14,7 @@ namespace FreeSql [AttributeUsage(AttributeTargets.Method)] public class TransactionalAttribute : DynamicProxyAttribute, IActionFilter { - public Propagation Propagation { get; set; } = Propagation.Requierd; + public Propagation Propagation { get; set; } = Propagation.Required; public IsolationLevel IsolationLevel { get => _IsolationLevelPriv.Value; set => _IsolationLevelPriv = value; } IsolationLevel? _IsolationLevelPriv; diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs index 2cf087b3..e4ae8931 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs @@ -85,11 +85,12 @@ namespace FreeSql /// 事务传播方式 /// 事务隔离级别 /// - public IUnitOfWork Begin(Propagation propagation = Propagation.Requierd, IsolationLevel? isolationLevel = null) + public IUnitOfWork Begin(Propagation propagation = Propagation.Required, IsolationLevel? isolationLevel = null) { + if (propagation == Propagation.Requierd) propagation = Propagation.Required; switch (propagation) { - case Propagation.Requierd: return FindedUowCreateVirtual() ?? CreateUow(isolationLevel); + case Propagation.Required: return FindedUowCreateVirtual() ?? CreateUow(isolationLevel); case Propagation.Supports: return FindedUowCreateVirtual() ?? CreateUowNothing(_allUows.LastOrDefault()?.IsNotSupported ?? false); case Propagation.Mandatory: return FindedUowCreateVirtual() ?? throw new Exception("Propagation_Mandatory: 使用当前事务,如果没有当前事务,就抛出异常"); case Propagation.NotSupported: return CreateUowNothing(true); @@ -252,7 +253,7 @@ namespace FreeSql /// /// 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。 /// - Requierd, + Required, /// /// 支持当前事务,如果没有当前事务,就以非事务方法执行。 /// @@ -272,6 +273,13 @@ namespace FreeSql /// /// 以嵌套事务方式执行。 /// - Nested + Nested, + + + /// + /// 错误的命名,请使用 Required,在 2.0.0 删除 + /// + [Obsolete("错误的命名,请使用 Required,在 2.0.0 删除")] + Requierd = 404 } } From 7dd8eacce327dba556946bd4b5fe32a22aa3eb8a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 17 Aug 2020 08:58:34 +0800 Subject: [PATCH 0837/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20ToChunk=20?= =?UTF-8?q?=E5=88=86=E5=9D=97=E5=8A=A0=E8=BD=BD=E6=9F=A5=E8=AF=A2=EF=BC=8C?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E5=88=B0=20ISelect`1..10=20=E4=B8=AD?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs/Program.cs | 6 + FreeSql.DbContext/FreeSql.DbContext.xml | 14 +- FreeSql/FreeSql.xml | 9 + FreeSql/Interface/Curd/ISelect/ISelect1.cs | 11 +- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect2.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect3.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect4.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect5.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect6.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect7.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect8.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect9.cs | 1 + .../SelectProvider/Select0Provider.cs | 986 +----------------- .../SelectProvider/Select0ProviderReader.cs | 962 +++++++++++++++++ .../SelectProvider/Select10Provider.cs | 6 + .../SelectProvider/Select1Provider.cs | 7 +- .../SelectProvider/Select2Provider.cs | 7 +- .../SelectProvider/Select3Provider.cs | 7 +- .../SelectProvider/Select4Provider.cs | 7 +- .../SelectProvider/Select5Provider.cs | 7 +- .../SelectProvider/Select6Provider.cs | 7 +- .../SelectProvider/Select7Provider.cs | 7 +- .../SelectProvider/Select8Provider.cs | 8 +- .../SelectProvider/Select9Provider.cs | 6 + 25 files changed, 1084 insertions(+), 982 deletions(-) create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 929ebbf7..b27b8fad 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -370,6 +370,12 @@ namespace orm_vs testlist2.AddRange(fetch.Object); }); + var testlist22 = new List(); + fsql.Select().LeftJoin((a, b) => a.id == b.song_id).ToChunk((a, b) => new { a.title, a.create_time, b.tag_id }, 2, fetch => + { + testlist22.AddRange(fetch.Object); + }); + //sugar.Aop.OnLogExecuted = (s, e) => //{ // Trace.WriteLine(s); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index c46aa1e3..68241282 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -421,7 +414,7 @@ 事务传播方式 - + 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。 @@ -451,6 +444,11 @@ 以嵌套事务方式执行。 + + + 错误的命名,请使用 Required,在 2.0.0 删除 + + EFCore 95% 相似的 FluentApi 扩展方法 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 07cb2cc2..6134627d 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1645,6 +1645,15 @@ + + + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + + 返回类型 + 选择列 + 数据块的大小 + 处理数据块 + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 1d44bfe6..08ccda4b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -56,6 +57,14 @@ namespace FreeSql /// /// List ToList(); + /// + /// 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + /// + /// 返回类型 + /// 选择列 + /// 数据块的大小 + /// 处理数据块 + void ToChunk(Expression> select, int size, Action>> done); /// /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index e4cdafd6..2d1107e4 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index bd9692e5..b7890fec 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index 00836d0a..413bbe72 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 8890624b..cfd3b6ac 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index f8d6cd7e..b26c016d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 63db674e..e3c46a93 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index fc99ef10..23fd0fbc 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 836ee3fb..22e2b933 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 8f44436d..87463c8e 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -32,6 +32,7 @@ namespace FreeSql DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); + void ToChunk(Expression> select, int size, Action>> done); TReturn ToOne(Expression> select); TReturn First(Expression> select); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index a5166fc2..153655e0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -4,9 +4,7 @@ using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Data; using System.Data.Common; -using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -17,7 +15,6 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract partial class Select0Provider { public int _limit, _skip; @@ -157,32 +154,6 @@ namespace FreeSql.Internal.CommonProvider return this as TSelect; } - public bool Any() - { - this.Limit(1); - return this.ToList($"{1}{_commonUtils.FieldAsAlias("as1")}").Sum() > 0; //这里的 Sum 为了分表查询 - } - - public long Count() - { - var tmpOrderBy = _orderby; - _orderby = null; //解决 select count(1) from t order by id 这样的 SQL 错误 - try - { - return this.ToList($"count(1){_commonUtils.FieldAsAlias("as1")}").Sum(); //这里的 Sum 为了分表查询 - } - finally - { - _orderby = tmpOrderBy; - } - } - - public TSelect Count(out long count) - { - count = this.Count(); - return this as TSelect; - } - public TSelect GroupBy(string sql, object parms = null) { _groupby = sql; @@ -304,627 +275,6 @@ namespace FreeSql.Internal.CommonProvider return this as TSelect; } - public DataTable ToDataTable(string field = null) - { - var sql = this.ToSql(field); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; - try - { - ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return ret; - } - - public List ToList(string field) - { - var sql = this.ToSql(field); - var type = typeof(TTuple); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); - var flagStr = $"ToListField:{field}"; - Exception exception = null; - try - { - _orm.Ado.ExecuteReader(_connection, _transaction, fetch => - { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); - ret.Add((TTuple)read.Value); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return ret; - } - internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - _orm.Ado.ExecuteReader(_connection, _transaction, fetch => - { - ret.Add(af.Read(_orm, fetch.Object)); - if (otherData != null) - { - var idx = af.FieldCount - 1; - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); - } - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - foreach (var include in _includeToList) include?.Invoke(ret); - _trackToList?.Invoke(ret); - return ret; - } - internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - string sql = null; - if (otherData?.Length > 0) - { - var sbField = new StringBuilder().Append(af.Field); - foreach (var other in otherData) - sbField.Append(other.field); - sql = this.ToSql(sbField.ToString()); - } - else - sql = this.ToSql(af.Field); - - return ToListAfPrivate(sql, af, otherData); - } - #region ToChunk - internal void ToListAfChunkPrivate(int chunkSize, Action>> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new FetchCallbackArgs> { Object = new List() }; - var retCount = 0; - Exception exception = null; - var checkDoneTimes = 0; - try - { - _orm.Ado.ExecuteReader(_connection, _transaction, fetch => - { - ret.Object.Add(af.Read(_orm, fetch.Object)); - retCount++; - if (otherData != null) - { - var idx = af.FieldCount - 1; - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); - } - if (chunkSize > 0 && chunkSize == ret.Object.Count) - { - checkDoneTimes++; - - foreach (var include in _includeToList) include?.Invoke(ret.Object); - _trackToList?.Invoke(ret.Object); - chunkDone(ret); - fetch.IsBreak = ret.IsBreak; - - ret.Object.Clear(); - if (otherData != null) - foreach (var other in otherData) - other.retlist.Clear(); - } - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, retCount); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - if (ret.Object.Any() || checkDoneTimes == 0) - { - foreach (var include in _includeToList) include?.Invoke(ret.Object); - _trackToList?.Invoke(ret.Object); - chunkDone(ret); - } - } - internal void ToListChunkPrivate(int chunkSize, Action>> chunkDone, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - string sql = null; - if (otherData?.Length > 0) - { - var sbField = new StringBuilder().Append(af.Field); - foreach (var other in otherData) - sbField.Append(other.field); - sql = this.ToSql(sbField.ToString()); - } - else - sql = this.ToSql(af.Field); - - ToListAfChunkPrivate(chunkSize, chunkDone, sql, af, otherData); - } - public void ToChunk(int size, Action>> done, bool includeNestedMembers = false) - { - if (_selectExpression != null) throw new ArgumentException("Chunk 功能之前不可使用 Select"); - this.ToListChunkPrivate(size, done, includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); - } - #endregion - public Dictionary ToDictionary(Func keySelector) => ToDictionary(keySelector, a => a); - public Dictionary ToDictionary(Func keySelector, Func elementSelector) - { - if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); - if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); - var af = this.GetAllFieldExpressionTreeLevel2(); - var sql = this.ToSql(af.Field); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new Dictionary(); - Exception exception = null; - try - { - _orm.Ado.ExecuteReader(_connection, _transaction, fetch => - { - var item = af.Read(_orm, fetch.Object); - ret.Add(keySelector(item), elementSelector(item)); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - if (typeof(TElement) == typeof(T1)) _trackToList?.Invoke(ret.Values); - return ret; - } - public virtual List ToList(bool includeNestedMembers = false) - { - if (_selectExpression != null) return this.InternalToList(_selectExpression); - return this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); - } - public T1 ToOne() - { - this.Limit(1); - return this.ToList().FirstOrDefault(); - } - - public T1 First() => this.ToOne(); - - internal List ToListMrPrivate(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - var type = typeof(TReturn); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - _orm.Ado.ExecuteReader(_connection, _transaction, fetch => - { - var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); - if (otherData != null) - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - if (typeof(TReturn) == typeof(T1)) - foreach (var include in _includeToList) include?.Invoke(ret); - _trackToList?.Invoke(ret); - return ret; - } - internal List ToListMapReaderPrivate(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - string sql = null; - if (otherData?.Length > 0) - { - var sbField = new StringBuilder().Append(af.field); - foreach (var other in otherData) - sbField.Append(other.field); - sql = this.ToSql(sbField.ToString()); - } - else - sql = this.ToSql(af.field); - - return ToListMrPrivate(sql, af, otherData); - } - protected List ToListMapReader(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivate(af, null); - protected ReadAnonymousTypeAfInfo GetExpressionField(Expression newexp, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) - { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; - - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true); - return new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); - } - static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); - public class GetAllFieldExpressionTreeInfo - { - public string Field { get; set; } - public int FieldCount { get; set; } - public Func Read { get; set; } - } - public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevelAll() - { - return _dicGetAllFieldExpressionTree.GetOrAdd($"*{string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}"))}", s => - { - var type = _tables.First().Table.TypeLazy ?? _tables.First().Table.Type; - var ormExp = Expression.Parameter(typeof(IFreeSql), "orm"); - var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); - var returnTarget = Expression.Label(type); - var retExp = Expression.Variable(type, "ret"); - var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); - var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); - var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); - var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); - var blockExp = new List(); - blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, type.InternalNewExpression()), - Expression.Assign(dataIndexExp, Expression.Constant(0)) - }); - //typeof(Topic).GetMethod("get_Type").IsVirtual - - var field = new StringBuilder(); - var dicfield = new Dictionary(); - var tb = _tables.First(); - var index = 0; - - var tborder = new[] { tb }.Concat(_tables.ToArray().Where((a, b) => b > 0).OrderBy(a => a.Alias)); - var tbiindex = 0; - foreach (var tbi in tborder) - { - if (tbiindex > 0 && tbi.Type == SelectTableInfoType.From) continue; - if (tbiindex > 0 && tbi.Alias.StartsWith($"{tb.Alias}__") == false) continue; - - var typei = tbi.Table.TypeLazy ?? tbi.Table.Type; - Expression curExp = retExp; - - var colidx = 0; - foreach (var col in tbi.Table.Columns.Values) - { - if (index > 0) - { - field.Append(", "); - if (tbiindex > 0 && colidx == 0) field.Append("\r\n"); - } - var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); - else dicfield.Add(quoteName, true); - ++colidx; - } - tbiindex++; - - if (tbiindex == 0) - blockExp.AddRange(new Expression[] { - Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), - Expression.IfThen( - Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex) - ), - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Assign(retExp, Expression.Convert(readExpValue, typei)) - ) - }); - else - { - Expression curExpIfNotNull = Expression.IsTrue(Expression.Constant(true)); - var curTb = tb; - var parentNameSplits = tbi.Alias.Split(new[] { "__" }, StringSplitOptions.None); - var iscontinue = false; - for (var k = 1; k < parentNameSplits.Length; k++) - { - var curPropName = parentNameSplits[k]; - if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out var tryprop) == false) - { - k++; - curPropName = $"{curPropName}__{parentNameSplits[k]}"; - if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out tryprop) == false) - { - iscontinue = true; - break; - } - } - curExp = Expression.MakeMemberAccess(curExp, tryprop); - if (k + 1 < parentNameSplits.Length) - curExpIfNotNull = Expression.AndAlso(curExpIfNotNull, Expression.NotEqual(curExp, Expression.Default(tryprop.PropertyType))); - curTb = _tables.Where(a => a.Alias == $"{curTb.Alias}__{curPropName}" && a.Table.Type == tryprop.PropertyType).FirstOrDefault(); - if (curTb == null) - { - iscontinue = true; - break; - } - } - if (iscontinue) continue; - - blockExp.Add( - Expression.IfThenElse( - curExpIfNotNull, - Expression.Block(new Expression[] { - Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), - Expression.IfThen( - Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex) - ), - Expression.IfThenElse( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Assign(curExp, Expression.Convert(readExpValue, typei)), - Expression.Assign(curExp, Expression.Constant(null, typei)) - ) - }), - Expression.Block( - Expression.Assign(readExpValue, Expression.Constant(null, typeof(object))), - Expression.Assign(dataIndexExp, Expression.Constant(index)) - ) - ) - ); - } - - if (tbi.Table.TypeLazy != null) - blockExp.Add( - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(Expression.TypeAs(readExpValue, typei), tbi.Table.TypeLazySetOrm, ormExp) - ) - ); //将 orm 传递给 lazy - } - - blockExp.AddRange(new Expression[] { - Expression.Return(returnTarget, retExp), - Expression.Label(returnTarget, Expression.Default(type)) - }); - return new GetAllFieldExpressionTreeInfo - { - Field = field.ToString(), - FieldCount = index, - Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile() - }; - }); - } - public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2() - { - return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s => - { - var tb1 = _tables.First().Table; - var type = tb1.TypeLazy ?? tb1.Type; - var props = tb1.Properties; - - var ormExp = Expression.Parameter(typeof(IFreeSql), "orm"); - var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); - var returnTarget = Expression.Label(type); - var retExp = Expression.Variable(type, "ret"); - var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); - var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); - var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); - var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); - var blockExp = new List(); - blockExp.AddRange(new Expression[] { - Expression.Assign(retExp, type.InternalNewExpression()), - Expression.Assign(dataIndexExp, Expression.Constant(0)) - }); - //typeof(Topic).GetMethod("get_Type").IsVirtual - - var field = new StringBuilder(); - var dicfield = new Dictionary(); - var tb = _tables.First(); - var index = 0; - var otherindex = 0; - foreach (var prop in props.Values) - { - if (tb.Table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue; - - if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) - { //普通字段 - if (index > 0) field.Append(", "); - var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); - else dicfield.Add(quoteName, true); - } - else - { - var tb2 = _tables.Where((a, b) => b > 0 && - (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) && - string.IsNullOrEmpty(a.On) == false && - a.Alias.StartsWith($"{tb.Alias}__") && //开头结尾完全匹配 - a.Alias.EndsWith($"__{prop.Name}") //不清楚会不会有其他情况 求大佬优化 - ).FirstOrDefault(); //判断 b > 0 防止 parent 递归关系 - if (tb2 == null && props.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) - tb2 = _tables.Where((a, b) => b > 0 && - (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) && - string.IsNullOrEmpty(a.On) == false && - a.Table.Type == prop.PropertyType).FirstOrDefault(); - if (tb2 == null) continue; - foreach (var col2 in tb2.Table.Columns.Values) - { - if (index > 0) field.Append(", "); - var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col2.CsType, col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); - ++index; - ++otherindex; - if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); - else dicfield.Add(quoteName, true); - } - } - //只读到二级属性 - var propGetSetMethod = prop.GetSetMethod(true); - Expression readExpAssign = null; //加速缓存 - if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor, - Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })), - //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ); - else - { - var proptypeGeneric = prop.PropertyType; - if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GetGenericArguments().First(); - if (proptypeGeneric.IsEnum || - Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor, - Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })), - //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), - Expression.Add(dataIndexExp, Expression.Constant(1)) - ); - else - { - var propLazyType = _commonUtils.GetTableByEntity(prop.PropertyType)?.TypeLazy ?? prop.PropertyType; - readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(propLazyType), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) }); - } - } - blockExp.AddRange(new Expression[] { - Expression.Assign(readExp, readExpAssign), - Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex)), - //Expression.Call(typeof(Trace).GetMethod("WriteLine", new Type[]{typeof(string)}), Expression.Call(typeof(string).GetMethod("Concat", new Type[]{typeof(object) }), readExpValue)), - - tb1.TypeLazy != null ? - Expression.IfThenElse( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Constant(null)), prop.PropertyType)) - ) : - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)) - ) - }); - } - if (otherindex == 0) - { //不读导航属性,优化单表读取性能 - blockExp.Clear(); - blockExp.AddRange(new Expression[] { - Expression.Assign(dataIndexExp, Expression.Constant(0)), - Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(type), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Assign(retExp, Expression.Convert(readExpValue, type)) - ) - }); - } - if (tb1.TypeLazy != null) - blockExp.Add( - Expression.IfThen( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(retExp, tb1.TypeLazySetOrm, ormExp) - ) - ); //将 orm 传递给 lazy - blockExp.AddRange(new Expression[] { - Expression.Return(returnTarget, retExp), - Expression.Label(returnTarget, Expression.Default(type)) - }); - return new GetAllFieldExpressionTreeInfo - { - Field = field.ToString(), - Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile() - }; - }); - } - protected ReadAnonymousTypeAfInfo GetAllFieldReflection() - { - var tb1 = _tables.First().Table; - var type = tb1.TypeLazy ?? tb1.Type; - var constructor = type.InternalGetTypeConstructor0OrFirst(); - var map = new ReadAnonymousTypeInfo { CsType = type, Consturctor = constructor, IsEntity = true }; - - var field = new StringBuilder(); - var dicfield = new Dictionary(); - var tb = _tables.First(); - var index = 0; - var ps = tb1.Properties; - foreach (var p in ps.Values) - { - var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name }; - if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) - { //普通字段 - if (index > 0) field.Append(", "); - var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); - else dicfield.Add(quoteName, true); - } - else - { - var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault(); - if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault(); - if (tb2 == null) continue; - child.CsType = (tb2.Table.TypeLazy ?? tb2.Table.Type); - child.Consturctor = child.CsType.InternalGetTypeConstructor0OrFirst(); - child.IsEntity = true; - foreach (var col2 in tb2.Table.Columns.Values) - { - if (index > 0) field.Append(", "); - var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col2.CsType, col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); - else dicfield.Add(quoteName, true); - child.Childs.Add(new ReadAnonymousTypeInfo - { - Property = tb2.Table.Type.GetProperty(col2.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), - CsName = col2.CsName - }); - } - } - map.Childs.Add(child); - } - return new ReadAnonymousTypeAfInfo(map, field.ToString()); - } - string GetToDeleteWhere(string alias) { var pks = _tables[0].Table.Primarys; @@ -1284,88 +634,41 @@ namespace FreeSql.Internal.CommonProvider } return this as TSelect; } - #region common - protected double InternalAvg(Expression exp) + public bool Any() { - var list = this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"); - return list.Sum() / list.Count; + this.Limit(1); + return this.ToList($"{1}{_commonUtils.FieldAsAlias("as1")}").Sum() > 0; //这里的 Sum 为了分表查询 } - protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Max(); - protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Min(); - protected decimal InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Sum(); - - public ISelectGrouping InternalGroupBy(Expression columns) + public long Count() { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = -10000; //临时规则,不返回 as1 - - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression, false); //不走 DTO 映射 - var sql = field.ToString(); - this.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); - return new SelectGroupingProvider(_orm, this, map, sql, _commonExpression, _tables); - } - public TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) - { - _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); - return this as TSelect; - } - protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) - { - var tb = _commonUtils.GetTableByEntity(typeof(T2)); - if (tb == null) throw new ArgumentException("T2 类型错误"); - _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType }); - _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); - return this as TSelect; - } - protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); - protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); - - public List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); - protected string InternalToSql(Expression select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) - { - var af = this.GetExpressionField(select, fieldAlias); - return this.ToSql(af.field); - } - - protected DataTable InternalToDataTable(Expression select) - { - var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; + var tmpOrderBy = _orderby; + _orderby = null; //解决 select count(1) from t order by id 这样的 SQL 错误 try { - ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; + return this.ToList($"count(1){_commonUtils.FieldAsAlias("as1")}").Sum(); //这里的 Sum 为了分表查询 } finally { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); + _orderby = tmpOrderBy; } - return ret; } - - protected TReturn InternalToAggregate(Expression select) + public TSelect Count(out long count) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; - - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射 - return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); + count = this.Count(); + return this as TSelect; } - - public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params)); - #endregion + public virtual List ToList(bool includeNestedMembers = false) + { + if (_selectExpression != null) return this.InternalToList(_selectExpression); + return this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); + } + public T1 ToOne() + { + this.Limit(1); + return this.ToList().FirstOrDefault(); + } + public T1 First() => this.ToOne(); #if net40 #else @@ -1374,7 +677,6 @@ namespace FreeSql.Internal.CommonProvider this.Limit(1); return (await this.ToListAsync($"1{_commonUtils.FieldAsAlias("as1")}")).Sum() > 0; //这里的 Sum 为了分表查询 } - async public Task CountAsync() { var tmpOrderBy = _orderby; @@ -1388,261 +690,17 @@ namespace FreeSql.Internal.CommonProvider _orderby = tmpOrderBy; } } - - async public Task ToDataTableAsync(string field = null) - { - var sql = this.ToSql(field); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; - try - { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return ret; - } - - async public Task> ToListAsync(string field) - { - var sql = this.ToSql(field); - var type = typeof(TTuple); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); - var flagStr = $"ToListField:{field}"; - Exception exception = null; - try - { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => - { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); - ret.Add((TTuple)read.Value); - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return ret; - } - - async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => - { - ret.Add(af.Read(_orm, fetch.Object)); - if (otherData != null) - { - var idx = af.FieldCount - 1; - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); - } - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - foreach (var include in _includeToListAsync) await include?.Invoke(ret); - _trackToList?.Invoke(ret); - return ret; - } - - internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - string sql = null; - if (otherData?.Length > 0) - { - var sbField = new StringBuilder().Append(af.Field); - foreach (var other in otherData) - sbField.Append(other.field); - sql = this.ToSql(sbField.ToString()); - } - else - sql = this.ToSql(af.Field); - - return ToListAfPrivateAsync(sql, af, otherData); - } - - public Task> ToDictionaryAsync(Func keySelector) => ToDictionaryAsync(keySelector, a => a); - async public Task> ToDictionaryAsync(Func keySelector, Func elementSelector) - { - if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); - if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); - var af = this.GetAllFieldExpressionTreeLevel2(); - var sql = this.ToSql(af.Field); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new Dictionary(); - Exception exception = null; - try - { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => - { - var item = af.Read(_orm, fetch.Object); - ret.Add(keySelector(item), elementSelector(item)); - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - if (typeof(TElement) == typeof(T1)) _trackToList?.Invoke(ret.Values); - return ret; - } public virtual Task> ToListAsync(bool includeNestedMembers = false) { if (_selectExpression != null) return this.InternalToListAsync(_selectExpression); return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); } - async public Task ToOneAsync() { this.Limit(1); return (await this.ToListAsync()).FirstOrDefault(); } - public Task FirstAsync() => this.ToOneAsync(); - - async internal Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - var type = typeof(TReturn); - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); - Exception exception = null; - try - { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => - { - var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); - if (otherData != null) - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - if (typeof(TReturn) == typeof(T1)) - foreach (var include in _includeToListAsync) await include?.Invoke(ret); - _trackToList?.Invoke(ret); - return ret; - } - internal Task> ToListMapReaderPrivateAsync(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) - { - string sql = null; - if (otherData?.Length > 0) - { - var sbField = new StringBuilder().Append(af.field); - foreach (var other in otherData) - sbField.Append(other.field); - sql = this.ToSql(sbField.ToString()); - } - else - sql = this.ToSql(af.field); - - return ToListMrPrivateAsync(sql, af, otherData); - } - protected Task> ToListMapReaderAsync(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivateAsync(af, null); - - async protected Task InternalAvgAsync(Expression exp) - { - var list = await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"); - return list.Sum() / list.Count; - } - async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Max(); - async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Min(); - async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Sum(); - - protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); - - async protected Task InternalToDataTableAsync(Expression select) - { - var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty - var dbParms = _params.ToArray(); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - DataTable ret = null; - Exception exception = null; - try - { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw ex; - } - finally - { - var after = new Aop.CurdAfterEventArgs(before, exception, ret); - _orm.Aop.CurdAfterHandler?.Invoke(this, after); - } - return ret; - } - - async protected Task InternalToAggregateAsync(Expression select) - { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; - - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射 - return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); - } #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs new file mode 100644 index 00000000..113c8554 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -0,0 +1,962 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data; +using System.Data.Common; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + partial class Select0Provider + { + public DataTable ToDataTable(string field = null) + { + var sql = this.ToSql(field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + public List ToList(string field) + { + var sql = this.ToSql(field); + var type = typeof(TTuple); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + var flagStr = $"ToListField:{field}"; + Exception exception = null; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); + ret.Add((TTuple)read.Value); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + ret.Add(af.Read(_orm, fetch.Object)); + if (otherData != null) + { + var idx = af.FieldCount - 1; + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); + } + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + foreach (var include in _includeToList) include?.Invoke(ret); + _trackToList?.Invoke(ret); + return ret; + } + internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.Field); + + return ToListAfPrivate(sql, af, otherData); + } + #region ToChunk + internal void ToListAfChunkPrivate(int chunkSize, Action>> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new FetchCallbackArgs> { Object = new List() }; + var retCount = 0; + Exception exception = null; + var checkDoneTimes = 0; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + ret.Object.Add(af.Read(_orm, fetch.Object)); + retCount++; + if (otherData != null) + { + var idx = af.FieldCount - 1; + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); + } + if (chunkSize > 0 && chunkSize == ret.Object.Count) + { + checkDoneTimes++; + + foreach (var include in _includeToList) include?.Invoke(ret.Object); + _trackToList?.Invoke(ret.Object); + chunkDone(ret); + fetch.IsBreak = ret.IsBreak; + + ret.Object.Clear(); + if (otherData != null) + foreach (var other in otherData) + other.retlist.Clear(); + } + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, retCount); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + if (ret.Object.Any() || checkDoneTimes == 0) + { + foreach (var include in _includeToList) include?.Invoke(ret.Object); + _trackToList?.Invoke(ret.Object); + chunkDone(ret); + } + } + internal void ToListChunkPrivate(int chunkSize, Action>> chunkDone, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.Field); + + ToListAfChunkPrivate(chunkSize, chunkDone, sql, af, otherData); + } + public void ToChunk(int size, Action>> done, bool includeNestedMembers = false) + { + if (_selectExpression != null) throw new ArgumentException("Chunk 功能之前不可使用 Select"); + this.ToListChunkPrivate(size, done, includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); + } + + internal void ToListMrChunkPrivate(int chunkSize, Action>> chunkDone, string sql, ReadAnonymousTypeAfInfo af) + { + var type = typeof(TReturn); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new FetchCallbackArgs> { Object = new List() }; + var retCount = 0; + Exception exception = null; + var checkDoneTimes = 0; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + var index = -1; + ret.Object.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); + retCount++; + if (chunkSize > 0 && chunkSize == ret.Object.Count) + { + checkDoneTimes++; + + foreach (var include in _includeToList) include?.Invoke(ret.Object); + _trackToList?.Invoke(ret.Object); + chunkDone(ret); + fetch.IsBreak = ret.IsBreak; + + ret.Object.Clear(); + } + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, retCount); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + if (ret.Object.Any() || checkDoneTimes == 0) + { + foreach (var include in _includeToList) include?.Invoke(ret.Object); + _trackToList?.Invoke(ret.Object); + chunkDone(ret); + } + } + public void InternalToChunk(Expression select, int size, Action>> done) + { + var af = this.GetExpressionField(select); + var sql = this.ToSql(af.field); + this.ToListMrChunkPrivate(size, done, sql, af); + } + #endregion + + public Dictionary ToDictionary(Func keySelector) => ToDictionary(keySelector, a => a); + public Dictionary ToDictionary(Func keySelector, Func elementSelector) + { + if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); + if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); + var af = this.GetAllFieldExpressionTreeLevel2(); + var sql = this.ToSql(af.Field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new Dictionary(); + Exception exception = null; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + var item = af.Read(_orm, fetch.Object); + ret.Add(keySelector(item), elementSelector(item)); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + if (typeof(TElement) == typeof(T1)) _trackToList?.Invoke(ret.Values); + return ret; + } + + internal List ToListMrPrivate(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + var type = typeof(TReturn); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + var index = -1; + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); + if (otherData != null) + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + if (typeof(TReturn) == typeof(T1)) + foreach (var include in _includeToList) include?.Invoke(ret); + _trackToList?.Invoke(ret); + return ret; + } + internal List ToListMapReaderPrivate(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.field); + + return ToListMrPrivate(sql, af, otherData); + } + protected List ToListMapReader(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivate(af, null); + protected ReadAnonymousTypeAfInfo GetExpressionField(Expression newexp, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; + + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true); + return new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); + } + static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); + public class GetAllFieldExpressionTreeInfo + { + public string Field { get; set; } + public int FieldCount { get; set; } + public Func Read { get; set; } + } + public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevelAll() + { + return _dicGetAllFieldExpressionTree.GetOrAdd($"*{string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}"))}", s => + { + var type = _tables.First().Table.TypeLazy ?? _tables.First().Table.Type; + var ormExp = Expression.Parameter(typeof(IFreeSql), "orm"); + var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); + var returnTarget = Expression.Label(type); + var retExp = Expression.Variable(type, "ret"); + var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); + var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); + var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); + var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); + var blockExp = new List(); + blockExp.AddRange(new Expression[] { + Expression.Assign(retExp, type.InternalNewExpression()), + Expression.Assign(dataIndexExp, Expression.Constant(0)) + }); + //typeof(Topic).GetMethod("get_Type").IsVirtual + + var field = new StringBuilder(); + var dicfield = new Dictionary(); + var tb = _tables.First(); + var index = 0; + + var tborder = new[] { tb }.Concat(_tables.ToArray().Where((a, b) => b > 0).OrderBy(a => a.Alias)); + var tbiindex = 0; + foreach (var tbi in tborder) + { + if (tbiindex > 0 && tbi.Type == SelectTableInfoType.From) continue; + if (tbiindex > 0 && tbi.Alias.StartsWith($"{tb.Alias}__") == false) continue; + + var typei = tbi.Table.TypeLazy ?? tbi.Table.Type; + Expression curExp = retExp; + + var colidx = 0; + foreach (var col in tbi.Table.Columns.Values) + { + if (index > 0) + { + field.Append(", "); + if (tbiindex > 0 && colidx == 0) field.Append("\r\n"); + } + var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); + else dicfield.Add(quoteName, true); + ++colidx; + } + tbiindex++; + + if (tbiindex == 0) + blockExp.AddRange(new Expression[] { + Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), + Expression.IfThen( + Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex) + ), + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Assign(retExp, Expression.Convert(readExpValue, typei)) + ) + }); + else + { + Expression curExpIfNotNull = Expression.IsTrue(Expression.Constant(true)); + var curTb = tb; + var parentNameSplits = tbi.Alias.Split(new[] { "__" }, StringSplitOptions.None); + var iscontinue = false; + for (var k = 1; k < parentNameSplits.Length; k++) + { + var curPropName = parentNameSplits[k]; + if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out var tryprop) == false) + { + k++; + curPropName = $"{curPropName}__{parentNameSplits[k]}"; + if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out tryprop) == false) + { + iscontinue = true; + break; + } + } + curExp = Expression.MakeMemberAccess(curExp, tryprop); + if (k + 1 < parentNameSplits.Length) + curExpIfNotNull = Expression.AndAlso(curExpIfNotNull, Expression.NotEqual(curExp, Expression.Default(tryprop.PropertyType))); + curTb = _tables.Where(a => a.Alias == $"{curTb.Alias}__{curPropName}" && a.Table.Type == tryprop.PropertyType).FirstOrDefault(); + if (curTb == null) + { + iscontinue = true; + break; + } + } + if (iscontinue) continue; + + blockExp.Add( + Expression.IfThenElse( + curExpIfNotNull, + Expression.Block(new Expression[] { + Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), + Expression.IfThen( + Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex) + ), + Expression.IfThenElse( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Assign(curExp, Expression.Convert(readExpValue, typei)), + Expression.Assign(curExp, Expression.Constant(null, typei)) + ) + }), + Expression.Block( + Expression.Assign(readExpValue, Expression.Constant(null, typeof(object))), + Expression.Assign(dataIndexExp, Expression.Constant(index)) + ) + ) + ); + } + + if (tbi.Table.TypeLazy != null) + blockExp.Add( + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(Expression.TypeAs(readExpValue, typei), tbi.Table.TypeLazySetOrm, ormExp) + ) + ); //将 orm 传递给 lazy + } + + blockExp.AddRange(new Expression[] { + Expression.Return(returnTarget, retExp), + Expression.Label(returnTarget, Expression.Default(type)) + }); + return new GetAllFieldExpressionTreeInfo + { + Field = field.ToString(), + FieldCount = index, + Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile() + }; + }); + } + public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2() + { + return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s => + { + var tb1 = _tables.First().Table; + var type = tb1.TypeLazy ?? tb1.Type; + var props = tb1.Properties; + + var ormExp = Expression.Parameter(typeof(IFreeSql), "orm"); + var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); + var returnTarget = Expression.Label(type); + var retExp = Expression.Variable(type, "ret"); + var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); + var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); + var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); + var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); + var blockExp = new List(); + blockExp.AddRange(new Expression[] { + Expression.Assign(retExp, type.InternalNewExpression()), + Expression.Assign(dataIndexExp, Expression.Constant(0)) + }); + //typeof(Topic).GetMethod("get_Type").IsVirtual + + var field = new StringBuilder(); + var dicfield = new Dictionary(); + var tb = _tables.First(); + var index = 0; + var otherindex = 0; + foreach (var prop in props.Values) + { + if (tb.Table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue; + + if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) + { //普通字段 + if (index > 0) field.Append(", "); + var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tb.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); + else dicfield.Add(quoteName, true); + } + else + { + var tb2 = _tables.Where((a, b) => b > 0 && + (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) && + string.IsNullOrEmpty(a.On) == false && + a.Alias.StartsWith($"{tb.Alias}__") && //开头结尾完全匹配 + a.Alias.EndsWith($"__{prop.Name}") //不清楚会不会有其他情况 求大佬优化 + ).FirstOrDefault(); //判断 b > 0 防止 parent 递归关系 + if (tb2 == null && props.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) + tb2 = _tables.Where((a, b) => b > 0 && + (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) && + string.IsNullOrEmpty(a.On) == false && + a.Table.Type == prop.PropertyType).FirstOrDefault(); + if (tb2 == null) continue; + foreach (var col2 in tb2.Table.Columns.Values) + { + if (index > 0) field.Append(", "); + var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col2.CsType, col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}")); + ++index; + ++otherindex; + if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}")); + else dicfield.Add(quoteName, true); + } + } + //只读到二级属性 + var propGetSetMethod = prop.GetSetMethod(true); + Expression readExpAssign = null; //加速缓存 + if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor, + Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })), + //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else + { + var proptypeGeneric = prop.PropertyType; + if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GetGenericArguments().First(); + if (proptypeGeneric.IsEnum || + Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor, + Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })), + //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else + { + var propLazyType = _commonUtils.GetTableByEntity(prop.PropertyType)?.TypeLazy ?? prop.PropertyType; + readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(propLazyType), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) }); + } + } + blockExp.AddRange(new Expression[] { + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex)), + //Expression.Call(typeof(Trace).GetMethod("WriteLine", new Type[]{typeof(string)}), Expression.Call(typeof(string).GetMethod("Concat", new Type[]{typeof(object) }), readExpValue)), + + tb1.TypeLazy != null ? + Expression.IfThenElse( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Constant(null)), prop.PropertyType)) + ) : + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)) + ) + }); + } + if (otherindex == 0) + { //不读导航属性,优化单表读取性能 + blockExp.Clear(); + blockExp.AddRange(new Expression[] { + Expression.Assign(dataIndexExp, Expression.Constant(0)), + Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(type), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Assign(retExp, Expression.Convert(readExpValue, type)) + ) + }); + } + if (tb1.TypeLazy != null) + blockExp.Add( + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, tb1.TypeLazySetOrm, ormExp) + ) + ); //将 orm 传递给 lazy + blockExp.AddRange(new Expression[] { + Expression.Return(returnTarget, retExp), + Expression.Label(returnTarget, Expression.Default(type)) + }); + return new GetAllFieldExpressionTreeInfo + { + Field = field.ToString(), + Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile() + }; + }); + } + + protected double InternalAvg(Expression exp) + { + var list = this.ToList($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"); + return list.Sum() / list.Count; + } + protected TMember InternalMax(Expression exp) => this.ToList($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Max(); + protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Min(); + protected decimal InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Sum(); + + public ISelectGrouping InternalGroupBy(Expression columns) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = -10000; //临时规则,不返回 as1 + + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression, false); //不走 DTO 映射 + var sql = field.ToString(); + this.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); + return new SelectGroupingProvider(_orm, this, map, sql, _commonExpression, _tables); + } + public TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) + { + _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); + return this as TSelect; + } + protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) + { + var tb = _commonUtils.GetTableByEntity(typeof(T2)); + if (tb == null) throw new ArgumentException("T2 类型错误"); + _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType }); + _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); + return this as TSelect; + } + protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); + protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); + + public List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); + protected string InternalToSql(Expression select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) + { + var af = this.GetExpressionField(select, fieldAlias); + return this.ToSql(af.field); + } + + protected DataTable InternalToDataTable(Expression select) + { + var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected TReturn InternalToAggregate(Expression select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射 + return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); + } + + public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params)); + + #region Async +#if net40 +#else + async public Task ToDataTableAsync(string field = null) + { + var sql = this.ToSql(field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + async public Task> ToListAsync(string field) + { + var sql = this.ToSql(field); + var type = typeof(TTuple); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + var flagStr = $"ToListField:{field}"; + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + { + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); + ret.Add((TTuple)read.Value); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + { + ret.Add(af.Read(_orm, fetch.Object)); + if (otherData != null) + { + var idx = af.FieldCount - 1; + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); + } + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + foreach (var include in _includeToListAsync) await include?.Invoke(ret); + _trackToList?.Invoke(ret); + return ret; + } + + internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.Field); + + return ToListAfPrivateAsync(sql, af, otherData); + } + + public Task> ToDictionaryAsync(Func keySelector) => ToDictionaryAsync(keySelector, a => a); + async public Task> ToDictionaryAsync(Func keySelector, Func elementSelector) + { + if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); + if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); + var af = this.GetAllFieldExpressionTreeLevel2(); + var sql = this.ToSql(af.Field); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new Dictionary(); + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + { + var item = af.Read(_orm, fetch.Object); + ret.Add(keySelector(item), elementSelector(item)); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + if (typeof(TElement) == typeof(T1)) _trackToList?.Invoke(ret.Values); + return ret; + } + + async internal Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + var type = typeof(TReturn); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + { + var index = -1; + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); + if (otherData != null) + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + if (typeof(TReturn) == typeof(T1)) + foreach (var include in _includeToListAsync) await include?.Invoke(ret); + _trackToList?.Invoke(ret); + return ret; + } + internal Task> ToListMapReaderPrivateAsync(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + string sql = null; + if (otherData?.Length > 0) + { + var sbField = new StringBuilder().Append(af.field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } + else + sql = this.ToSql(af.field); + + return ToListMrPrivateAsync(sql, af, otherData); + } + protected Task> ToListMapReaderAsync(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivateAsync(af, null); + + async protected Task InternalAvgAsync(Expression exp) + { + var list = await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"); + return list.Sum() / list.Count; + } + async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Max(); + async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Min(); + async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Sum(); + + protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); + + async protected Task InternalToDataTableAsync(Expression select) + { + var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + DataTable ret = null; + Exception exception = null; + try + { + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + async protected Task InternalToAggregateAsync(Expression select) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射 + return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); + } +#endif + #endregion + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 8f9a4398..cfbdf04e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -134,6 +134,12 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index f4a18423..c8b7474c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -174,7 +174,6 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = select.Parameters[0]; return this.InternalToList(select.Body); } - public List ToList() => ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { @@ -182,6 +181,12 @@ namespace FreeSql.Internal.CommonProvider typeof(TDto).InternalNewExpression(), _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + _tables[0].Parameter = select.Parameters[0]; + this.InternalToChunk(select.Body, size, done); + } public DataTable ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 79583b79..722e98ad 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -94,7 +94,6 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { @@ -103,6 +102,12 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 1ccd1d5c..a1a0482f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -97,7 +97,6 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { @@ -107,6 +106,12 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index c97b75b7..7ad1d657 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -100,7 +100,6 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { @@ -111,6 +110,12 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 27d8a023..8d370dca 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -103,7 +103,6 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { @@ -115,6 +114,12 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index b5fb37c8..24017074 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -106,7 +106,6 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { @@ -119,6 +118,12 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 52e1c4fb..be823cc8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -109,7 +109,6 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { @@ -123,6 +122,12 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index da9c40a5..4f24a463 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -112,9 +112,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() { return Expression.Lambda>( @@ -128,6 +126,12 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 5bfc03a1..33625d93 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -130,6 +130,12 @@ namespace FreeSql.Internal.CommonProvider Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i")); } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } DataTable ISelect.ToDataTable(Expression> select) { From f43d42bc2e8ecdf1fa2166861316571329ea91e9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 17 Aug 2020 13:59:27 +0800 Subject: [PATCH 0838/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IAdo.GetDbPa?= =?UTF-8?q?ramtersByObject=20=E6=96=B9=E6=B3=95=E8=8E=B7=E5=8F=96=20DbPara?= =?UTF-8?q?meter[]=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 6 ++++++ FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql/FreeSql.xml | 7 +++++++ FreeSql/Interface/IAdo.cs | 7 +++++++ .../CommonProvider/AdoProvider/AdoProvider.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 5 +++-- 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 0a945606..8f68b189 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -102,6 +102,12 @@ namespace base_entity var names = (fsql.Select() as Select0Provider)._commonUtils.SplitTableName("`Backups.ProductStockBak`"); + var dbparams = fsql.Ado.GetDbParamtersByObject(new { id = 1, name = "xxx" }); + + + + + var sql = fsql.CodeFirst.GetComparisonDDLStatements(typeof(EMSServerModel.Model.User), "testxsx001"); var test01 = EMSServerModel.Model.User.Select.IncludeMany(a => a.Roles).ToList(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 68241282..312b0c42 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6134627d..5a5b90aa 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2467,6 +2467,13 @@ 当前线程的事务 + + + 将 new { id = 1 } 或者 Dictionary<string, object> 转换为 DbParameter[] + + new { id = 1 } 或者 Dictionary<string, object> + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index ba922dc0..afa01638 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -55,6 +55,13 @@ namespace FreeSql DbTransaction TransactionCurrentThread { get; } #endregion + /// + /// 将 new { id = 1 } 或者 Dictionary<string, object> 转换为 DbParameter[] + /// + /// new { id = 1 } 或者 Dictionary<string, object> + /// + DbParameter[] GetDbParamtersByObject(object obj); + /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 /// diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 977621fd..c0c757ea 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -18,6 +18,7 @@ namespace FreeSql.Internal.CommonProvider protected abstract void ReturnConnection(IObjectPool pool, Object conn, Exception ex); protected abstract DbCommand CreateCommand(); protected abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); + public DbParameter[] GetDbParamtersByObject(object obj) => GetDbParamtersByObject("*", obj); protected bool IsTracePerformance => _util?._orm?.Aop.CommandAfterHandler != null; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index ab180445..a90c057a 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1218,6 +1218,7 @@ namespace FreeSql.Internal public static T[] GetDbParamtersByObject(string sql, object obj, string paramPrefix, Func constructorParamter) { if (string.IsNullOrEmpty(sql) || obj == null) return new T[0]; + var isCheckSql = sql != "*"; var ttype = typeof(T); var type = obj.GetType(); if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) }; @@ -1227,7 +1228,7 @@ namespace FreeSql.Internal { foreach (var key in dic.Keys) { - if (string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{key}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; + if (isCheckSql && string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{key}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; var val = dic[key]; var valType = val == null ? typeof(string) : val.GetType(); if (valType == ttype) ret.Add((T)Convert.ChangeType(val, ttype)); @@ -1239,7 +1240,7 @@ namespace FreeSql.Internal var ps = type.GetPropertiesDictIgnoreCase().Values; foreach (var p in ps) { - if (string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; + if (isCheckSql && string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; var pvalue = p.GetValue(obj, null); if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype)); else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue)); From 309b4ba60aaad7d0026cbb5e43d1363d530ae12e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 17 Aug 2020 14:01:39 +0800 Subject: [PATCH 0839/1029] v1.8.0-preview0818 #267 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 46c12e2f..c02038e4 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0affadca..7faa319d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 9436ad33..0db93dee 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 7860452c..bf31156e 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index e471eae9..6fe4ed65 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0815 + 1.8.0-preview0818 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 06df2d66..67ca0edd 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e36bfc7b..550f94ac 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index bb587f1d..35f64c31 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 45a71714..96e91273 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 97bf06ce..1f0a1ff3 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 8e112662..87862534 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e96d4a74..98f91beb 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 02bf708d..30870c3c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a2190dd0..33e57267 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index dcbf26ef..8a08c77b 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index c8b38490..d6812197 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index ef623bec..ba077d43 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 975ad172..371b2262 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 1a6c5ddc..b07277a4 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index d7d6c49c..8277e69a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0815 + 1.8.0-preview0818 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 113a5d3092b6a9208b6dd3a525c47167b7eab7ea Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 17 Aug 2020 22:05:05 +0800 Subject: [PATCH 0840/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect=20To?= =?UTF-8?q?List("id,title")=20=E5=B1=9E=E6=80=A7=E5=92=8C=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E9=A1=BA=E5=BA=8F=E4=B8=8D=E5=90=8C=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 --------- .../MySqlAdoTest.cs | 36 +++++++++++++++++++ .../SelectProvider/Select0ProviderReader.cs | 32 +++++++++++------ readme.md | 3 +- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 312b0c42..68241282 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs index 85056d7b..151f01da 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs @@ -73,6 +73,42 @@ namespace FreeSql.Tests.PerformanceTest time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*"); + var t411 = g.mysql.Select().Limit(1).ToList("id,title,url").FirstOrDefault(); + var t412 = g.mysql.Select().Limit(1).Where(a => a.Id == t411.Id).ToList("id,url,title").FirstOrDefault(); + var t413 = g.mysql.Select().Limit(1).Where(a => a.Id == t411.Id).ToList("id,title,url").FirstOrDefault(); + var t414 = g.mysql.Select().Limit(1).Where(a => a.Id == t411.Id).ToList("id,url,title").FirstOrDefault(); + var t415 = g.mysql.Select().Limit(1).Where(a => a.Id == t411.Id).ToList("url,title,id").FirstOrDefault(); + var t416 = g.mysql.Select().Limit(1).Where(a => a.Id == t411.Id).ToList("title,url,id").FirstOrDefault(); + + Assert.Equal(t411.Title, t412.Title); + Assert.Equal(t412.Title, t413.Title); + Assert.Equal(t413.Title, t414.Title); + Assert.Equal(t414.Title, t415.Title); + Assert.Equal(t415.Title, t416.Title); + + Assert.Equal(t411.Url, t412.Url); + Assert.Equal(t412.Url, t413.Url); + Assert.Equal(t413.Url, t414.Url); + Assert.Equal(t414.Url, t415.Url); + Assert.Equal(t415.Url, t416.Url); + + Assert.Equal(t411.Id, t412.Id); + Assert.Equal(t412.Id, t413.Id); + Assert.Equal(t413.Id, t414.Id); + Assert.Equal(t414.Id, t415.Id); + Assert.Equal(t415.Id, t416.Id); + } + class xxx_dto1 + { + public int Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + } + class xxx_dto2 + { + public int Id { get; set; } + public string Url { get; set; } + public string Title { get; set; } } [Fact] diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 113c8554..4ff5160c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -52,15 +52,20 @@ namespace FreeSql.Internal.CommonProvider var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - var flagStr = $"ToListField:{field}"; Exception exception = null; try { - _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + if (type.IsClass) + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + else { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); - ret.Add((TTuple)read.Value); - }, CommandType.Text, sql, dbParms); + var flagStr = $"ToListField:{field}"; + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); + ret.Add((TTuple)read.Value); + }, CommandType.Text, sql, dbParms); + } } catch (Exception ex) { @@ -748,16 +753,21 @@ namespace FreeSql.Internal.CommonProvider var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); - var flagStr = $"ToListField:{field}"; Exception exception = null; try { - await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + if (type.IsClass) + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + else { - var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); - ret.Add((TTuple)read.Value); - return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); + var flagStr = $"ToListField:{field}"; + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + { + var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); + ret.Add((TTuple)read.Value); + return Task.FromResult(false); + }, CommandType.Text, sql, dbParms); + } } catch (Exception ex) { diff --git a/readme.md b/readme.md index ff4a56b6..a6db0eb8 100644 --- a/readme.md +++ b/readme.md @@ -187,7 +187,8 @@ QQ群:4336577(已满)、8578575(在线) ## 💕  Donation -L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元 +L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 +无名 100元 > Thank you for your donation From 8c1dd496c72a6acb9105f462f1958772deb50b37 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 17 Aug 2020 22:07:34 +0800 Subject: [PATCH 0841/1029] v1.8.0-preview0819 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index c02038e4..933ed2c5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 7faa319d..372c1a43 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 0db93dee..a35e0c5f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index bf31156e..0b929446 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 6fe4ed65..f9b05517 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0818 + 1.8.0-preview0819 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 67ca0edd..6d1bdb74 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 550f94ac..b0481453 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 68241282..312b0c42 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 35f64c31..1c6fbba2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 96e91273..b2f97e9e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 1f0a1ff3..75d26f32 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 87862534..af8619de 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 98f91beb..b09880b1 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 30870c3c..3c5e6327 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 33e57267..d6640828 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 8a08c77b..6d410ddb 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d6812197..e1a16334 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index ba077d43..90aaa5e5 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 371b2262..46a37f9d 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index b07277a4..92ca1f7d 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 8277e69a..ce74fae3 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0818 + 1.8.0-preview0819 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 90b6d765106f8e7490314a04f17579700692d732 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 17 Aug 2020 23:19:29 +0800 Subject: [PATCH 0842/1029] update Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index a6db0eb8..702c44b3 100644 --- a/readme.md +++ b/readme.md @@ -188,7 +188,7 @@ QQ群:4336577(已满)、8578575(在线) ## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 -无名 100元 +无名 100元、无名 99.99元 > Thank you for your donation From 8cec3e396bd3232d401da915d05ba8f51653d704 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 18 Aug 2020 18:14:02 +0800 Subject: [PATCH 0843/1029] =?UTF-8?q?=E5=86=85=E9=83=A8=20ColumnInfo=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs/Program.cs | 9 ++ FreeSql.DbContext/FreeSql.DbContext.xml | 16 --- .../RepositoryTests.cs | 7 +- .../MySql/Curd/MySqlSelectTest.cs | 11 +++ FreeSql/Extensions/EntityUtilExtensions.cs | 97 +++++++++++++++---- FreeSql/FreeSql.xml | 20 ++++ .../CommonProvider/InsertOrUpdateProvider.cs | 10 +- .../Internal/CommonProvider/InsertProvider.cs | 20 ++-- .../Internal/CommonProvider/UpdateProvider.cs | 26 ++--- FreeSql/Internal/CommonUtils.cs | 8 +- FreeSql/Internal/Model/ColumnInfo.cs | 31 ++++++ .../Curd/DamengInsert.cs | 2 +- .../Curd/DamengUpdate.cs | 4 +- .../Curd/MsAccessUpdate.cs | 4 +- .../Curd/MySqlUpdate.cs | 4 +- .../Dameng/Curd/OdbcDamengInsert.cs | 2 +- .../Dameng/Curd/OdbcDamengUpdate.cs | 4 +- .../Default/Curd/OdbcUpdate.cs | 4 +- .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 4 +- .../MySql/Curd/OdbcMySqlUpdate.cs | 4 +- .../Oracle/Curd/OdbcOracleInsert.cs | 2 +- .../Oracle/Curd/OdbcOracleUpdate.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 4 +- .../Curd/OracleInsert.cs | 2 +- .../Curd/OracleUpdate.cs | 4 +- .../Curd/PostgreSQLUpdate.cs | 4 +- .../Curd/ShenTongUpdate.cs | 4 +- .../Curd/SqlServerUpdate.cs | 4 +- .../Curd/SqliteUpdate.cs | 4 +- readme.md | 2 +- 31 files changed, 223 insertions(+), 102 deletions(-) diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index b27b8fad..5de46db7 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -50,6 +50,15 @@ namespace orm_vs //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); //optionsBuilder.UseNpgsql("Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=21"); } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .Property(a => a.create_time) + .HasConversion(a => int.Parse(a.ToString()), a => new DateTime(a)); + } } static void Main(string[] args) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 312b0c42..68241282 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 0e65d5a9..2e310cec 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -332,6 +332,9 @@ namespace FreeSql.Tests cts[1].Goodss.Add(new Goods { Name = "Ʒ55" }); repo.Update(cts); + var cts2 = repo.Select.WhereDynamic(cts).IncludeMany(a => a.Goodss).ToList(); + cts2[0].Goodss[0].Name += 123; + repo.Update(cts2[0]); } [Table(Name = "EAUNL_OTM_CT")] class Cagetory @@ -490,7 +493,9 @@ namespace FreeSql.Tests var repo = g.sqlite.GetRepository(); repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; //򿪼湦 repo.Insert(ss); - //repo.SaveMany(ss[0], "Tags"); //ָ Tags Զ + + ss[0].Tags[0].TagName = "101"; + repo.SaveMany(ss[0], "Tags"); //ָ Tags Զ ss[0].Name = "һ.mp5"; ss[0].Tags.Clear(); diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 64950b72..0ee8ba66 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1,8 +1,10 @@ using FreeSql.DataAnnotations; +using FreeSql.Internal.CommonProvider; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Intrinsics.X86; using Xunit; namespace FreeSql.Tests.MySql @@ -1311,6 +1313,15 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 }; Assert.Equal(5, g.mysql.Insert(model4s).ExecuteAffrows()); + var sel = g.mysql.Select(); + //var tb1 = (sel as Select0Provider)._tables[1]; + //tb1.Type = Internal.Model.SelectTableInfoType.LeftJoin; + //tb1.On = $"b.id = ({g.mysql.Select().As("b2").Where("a.model2id = model2111Idaaa").Limit(1).ToSql("id")})"; + var sql = sel + .LeftJoin((a,b) => b.id == g.mysql.Select().As("b2").Where(b2 => a.model2id == b2.model2111Idaaa).First(b2 => b2.id)) + .ToSql((a, b) => new { a, b }); + + var t0 = g.mysql.Select() .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) .Where(a => a.model2id <= model1.id) diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 4236a48d..97732054 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.Internal.Model; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -27,7 +28,6 @@ namespace FreeSql.Extensions.EntityUtil /// 当Guid无值时,会生成有序的新值 /// /// - //public static string GetEntityKeyString(this IFreeSql orm, TEntity entity, string splitString = "*|_,[,_|*") => GetEntityKeyString(orm, typeof(TEntity), entity, splitString); public static string GetEntityKeyString(this IFreeSql orm, Type entityType, object entity, bool genGuid, string splitString = "*|_,[,_|*") { if (entity == null) return null; @@ -141,7 +141,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static object[] GetEntityKeyValues(this IFreeSql orm, TEntity entity) => GetEntityKeyValues(orm, typeof(TEntity), entity); public static object[] GetEntityKeyValues(this IFreeSql orm, Type entityType, object entity) { if (entity == null) return null; @@ -184,7 +183,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static object GetEntityValueWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName) => GetEntityKeyValues(orm, typeof(TEntity), entity, propertyName); public static object GetEntityValueWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName) { if (entity == null) return null; @@ -194,8 +192,8 @@ namespace FreeSql.Extensions.EntityUtil .GetOrAdd(entityType, et => new ConcurrentDictionary>()) .GetOrAdd(propertyName, pn => { - var _table = orm.CodeFirst.GetTableByEntity(entityType); - var pks = _table.Primarys; + var table = orm.CodeFirst.GetTableByEntity(entityType); + var pks = table.Primarys; var returnTarget = Expression.Label(typeof(object)); var parm1 = Expression.Parameter(typeof(object)); var var1Parm = Expression.Variable(entityType); @@ -204,7 +202,35 @@ namespace FreeSql.Extensions.EntityUtil Expression.Assign(var1Parm, Expression.TypeAs(parm1, entityType)), Expression.Assign( var2Ret, - Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pn]), typeof(object)) + Expression.Convert(Expression.MakeMemberAccess(var1Parm, table.Properties[pn]), typeof(object)) + ) + }); + exps.AddRange(new Expression[] { + Expression.Return(returnTarget, var2Ret), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + }); + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Ret }, exps), new[] { parm1 }).Compile(); + }); + return func(entity); + } + public static object GetPropertyValue(this TableInfo table, object entity, string propertyName) + { + if (table == null || entity == null) return null; + var func = _dicGetEntityValueWithPropertyName + .GetOrAdd(DataType.MsAccess, dt => new ConcurrentDictionary>>()) + .GetOrAdd(table.Type, et => new ConcurrentDictionary>()) + .GetOrAdd(propertyName, pn => + { + var pks = table.Primarys; + var returnTarget = Expression.Label(typeof(object)); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(table.Type); + var var2Ret = Expression.Variable(typeof(object)); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, table.Type)), + Expression.Assign( + var2Ret, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, table.Properties[pn]), typeof(object)) ) }); exps.AddRange(new Expression[] { @@ -223,7 +249,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static string GetEntityString(this IFreeSql orm, TEntity entity) => GetEntityString(orm, typeof(TEntity), entity); public static string GetEntityString(this IFreeSql orm, Type entityType, object entity) { if (entity == null) return null; @@ -270,7 +295,6 @@ namespace FreeSql.Extensions.EntityUtil /// 使用新实体的值,复盖旧实体的值 /// static ConcurrentDictionary>> _dicMapEntityValue = new ConcurrentDictionary>>(); - //public static void MapEntityValue(this IFreeSql orm, TEntity entityFrom, TEntity entityTo) => MapEntityValue(orm, typeof(TEntity), entityFrom, entityTo); public static void MapEntityValue(this IFreeSql orm, Type entityType, object entityFrom, object entityTo) { if (entityType == null) entityType = entityFrom?.GetType() ?? entityTo?.GetType(); @@ -316,7 +340,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// 使用新实体的主键值,复盖旧实体的主键值 /// - //public static void MapEntityKeyValue(this IFreeSql orm, TEntity entityFrom, TEntity entityTo) => MapEntityKeyValue(orm, typeof(TEntity), entityFrom, entityTo); public static void MapEntityKeyValue(this IFreeSql orm, Type entityType, object entityFrom, object entityTo) { if (entityType == null) entityType = entityFrom?.GetType() ?? entityTo?.GetType(); @@ -354,7 +377,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static void SetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity entity, long idtval) => SetEntityIdentityValueWithPrimary(orm, typeof(TEntity), entity, idtval); public static void SetEntityIdentityValueWithPrimary(this IFreeSql orm, Type entityType, object entity, long idtval) { if (entity == null) return; @@ -390,7 +412,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static long GetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity entity) => GetEntityIdentityValueWithPrimary(orm, typeof(TEntity), entity); public static long GetEntityIdentityValueWithPrimary(this IFreeSql orm, Type entityType, object entity) { if (entity == null) return 0; @@ -440,7 +461,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static void ClearEntityPrimaryValueWithIdentityAndGuid(this IFreeSql orm, TEntity entity) => ClearEntityPrimaryValueWithIdentityAndGuid(orm, typeof(TEntity), entity); public static void ClearEntityPrimaryValueWithIdentityAndGuid(this IFreeSql orm, Type entityType, object entity) { if (entity == null) return; @@ -489,7 +509,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static void ClearEntityPrimaryValueWithIdentity(this IFreeSql orm, TEntity entity) => ClearEntityPrimaryValueWithIdentity(orm, typeof(TEntity), entity); public static void ClearEntityPrimaryValueWithIdentity(this IFreeSql orm, Type entityType, object entity) { if (entity == null) return; @@ -530,7 +549,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static string[] CompareEntityValueReturnColumns(this IFreeSql orm, TEntity entity1, TEntity entity2, bool isEqual) => CompareEntityValueReturnColumns(orm, typeof(TEntity), entity1, entity2, isEqual); public static string[] CompareEntityValueReturnColumns(this IFreeSql orm, Type entityType, object entity1, object entity2, bool isEqual) { if (entityType == null) entityType = entity1?.GetType() ?? entity2?.GetType(); @@ -598,7 +616,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static void SetEntityIncrByWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName, int incrBy) => SetEntityIncrByWithPropertyName(orm, typeof(TEntity), entity, propertyName, incrBy); public static void SetEntityIncrByWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName, int incrBy) { if (entity == null) return; @@ -643,7 +660,6 @@ namespace FreeSql.Extensions.EntityUtil /// /// /// - //public static void SetEntityValueWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName, object value) => SetEntityValueWithPropertyName(orm, typeof(TEntity), entity, propertyName, value); public static void SetEntityValueWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName, object value) { if (entity == null) return; @@ -694,6 +710,53 @@ namespace FreeSql.Extensions.EntityUtil }); func(entity, propertyName, value); } + public static void SetPropertyValue(this TableInfo table, object entity, string propertyName, object value) + { + if (table == null || entity == null) return; + var func = _dicSetEntityValueWithPropertyName.GetOrAdd(DataType.MsAccess, dt => new ConcurrentDictionary>>()) + .GetOrAdd(table.Type, et => new ConcurrentDictionary>()) + .GetOrAdd(propertyName, pn => + { + var parm1 = Expression.Parameter(typeof(object)); + var parm2 = Expression.Parameter(typeof(string)); + var parm3 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(table.Type); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, table.Type)) + }); + if (table.Properties.ContainsKey(pn)) + { + var prop = table.Properties[pn]; + + if (table.ColumnsByCs.ContainsKey(pn)) + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.Convert( + FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(prop.PropertyType, parm3), + prop.PropertyType + ) + ) + ); + } + else + { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.Convert( + parm3, + prop.PropertyType + ) + ) + ); + } + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); + }); + func(entity, propertyName, value); + } static ConcurrentDictionary _dicAppendEntityUpdateSetWithColumnMethods = new ConcurrentDictionary(); static ConcurrentDictionary> _dicAppendEntityUpdateSetWithColumnMethod = new ConcurrentDictionary>(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5a5b90aa..4f53ec7b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3307,6 +3307,26 @@ 总批次数量 + + + 获取 obj.CsName 属性值 MapType 之后的数据库值 + + + + + + + 获取 obj.CsName 属性原始值(不经过 MapType) + + + + + + 设置 obj.CsName 属性值 + + + + 动态过滤条件 diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 28bffde0..61d2bcb3 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -78,12 +78,12 @@ namespace FreeSql.Internal.CommonProvider if (d == null) continue; foreach (var col in table.Columns.Values) { - object val = col.GetMapValue(d); + object val = col.GetValue(d); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.IsChanged) { - col.SetMapValue(d, val = auditArgs.Value); + col.SetValue(d, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) changedDict.Add(col.Attribute.Name, true); } @@ -98,12 +98,12 @@ namespace FreeSql.Internal.CommonProvider throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); foreach (var col in table.Columns.Values) { - object val = col.GetMapValue(data); + object val = col.GetValue(data); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.IsChanged) { - col.SetMapValue(data, val = auditArgs.Value); + col.SetValue(data, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) changedDict.Add(col.Attribute.Name, true); } @@ -166,7 +166,7 @@ namespace FreeSql.Internal.CommonProvider sb.Append(col.DbInsertValue); else { - object val = col.GetMapValue(d); + object val = col.GetDbValue(d); sb.Append(_commonUtils.GetNoneParamaterSqlValue(dbParams, "cu", col.Attribute.MapType, val)); } if (didx == 0) sb.Append(" as ").Append(col.Attribute.Name); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 596a58b7..1dc8da61 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -147,30 +147,28 @@ namespace FreeSql.Internal.CommonProvider throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); foreach (var col in table.Columns.Values) { - object val = col.GetMapValue(data); + object val = col.GetValue(data); if (orm.Aop.AuditValueHandler != null) { var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.IsChanged) { - col.SetMapValue(data, val = auditArgs.Value); + col.SetValue(data, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) changedDict.Add(col.Attribute.Name, true); } } if (col.Attribute.IsPrimary) { + val = col.GetDbValue(data); if (col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty)) - col.SetMapValue(data, val = FreeUtil.NewMongodbId()); + col.SetValue(data, val = FreeUtil.NewMongodbId()); else if (col.CsType.NullableTypeOrThis() == typeof(Guid)) { - var guidVal = orm.GetEntityValueWithPropertyName(table.Type, data, col.CsName); - if (guidVal == null || (Guid)guidVal == Guid.Empty) - { - orm.SetEntityValueWithPropertyName(table.Type, data, col.CsName, FreeUtil.NewMongodbId()); - val = col.GetMapValue(data); - } + val = col.GetValue(data); + if (val == null || (Guid)val == Guid.Empty) + col.SetValue(data, val = FreeUtil.NewMongodbId()); } } } @@ -548,7 +546,7 @@ namespace FreeSql.Internal.CommonProvider sb.Append(col.DbInsertValue); else { - object val = col.GetMapValue(d); + object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); @@ -588,7 +586,7 @@ namespace FreeSql.Internal.CommonProvider var rowIndex = 0; foreach (var col in dtCols) { - var val = col.Item1.GetMapValue(d); + var val = col.Item1.GetDbValue(d); if (col.Item3 == true) { //if (val == null) throw new Exception($"[{didx}].{col.Item1.CsName} 值不可为 null;DataTable 限制不可使用 int?/long? 可空类型,IInsert.ToDataTable 将映射成 int/long,因此不可接受 null 值"); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 8680da3e..a2b50eaa 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -350,12 +350,12 @@ namespace FreeSql.Internal.CommonProvider if (d == null) continue; foreach (var col in table.Columns.Values) { - object val = col.GetMapValue(d); + object val = col.GetValue(d); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.IsChanged) { - col.SetMapValue(d, val = auditArgs.Value); + col.SetValue(d, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) changedDict.Add(col.Attribute.Name, true); } @@ -370,12 +370,12 @@ namespace FreeSql.Internal.CommonProvider throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); foreach (var col in table.Columns.Values) { - object val = col.GetMapValue(data); + object val = col.GetValue(data); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); if (auditArgs.IsChanged) { - col.SetMapValue(data, val = auditArgs.Value); + col.SetValue(data, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) changedDict.Add(col.Attribute.Name, true); } @@ -403,18 +403,18 @@ namespace FreeSql.Internal.CommonProvider protected void SetPriv(ColumnInfo col, object value) { - object paramVal = null; - if (col.Attribute.MapType == col.CsType) paramVal = value; - else paramVal = Utils.GetDataReaderValue(col.Attribute.MapType, value); + object val = null; + if (col.Attribute.MapType == col.CsType) val = value; + else val = Utils.GetDataReaderValue(col.Attribute.MapType, value); _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); if (_noneParameter) { - _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, "u", col.Attribute.MapType, paramVal)); + _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, "u", col.Attribute.MapType, val)); } else { _set.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}")); - _commonUtils.AppendParamter(_params, null, col, col.Attribute.MapType, paramVal); + _commonUtils.AppendParamter(_params, null, col, col.Attribute.MapType, val); } } public IUpdate Set(Expression> column, TMember value) @@ -565,7 +565,7 @@ namespace FreeSql.Internal.CommonProvider var sb = new StringBuilder(); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, col.GetMapValue(_source.First())))); + sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, col.GetDbValue(_source.First())))); return sb.ToString(); @@ -588,7 +588,7 @@ namespace FreeSql.Internal.CommonProvider cwsb.Append(" \r\nWHEN "); ToSqlWhen(cwsb, _table.Primarys, d); cwsb.Append(" THEN "); - var val = col.GetMapValue(d); + var val = col.GetDbValue(d); cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val))); if (val == null || val == DBNull.Value) nulls++; } @@ -660,7 +660,7 @@ namespace FreeSql.Internal.CommonProvider sb.Append(col.DbUpdateValue); else { - var val = col.GetMapValue(_source.First()); + var val = col.GetDbValue(_source.First()); if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val)); else @@ -705,7 +705,7 @@ namespace FreeSql.Internal.CommonProvider cwsb.Append(" \r\nWHEN "); ToSqlWhen(cwsb, _table.Primarys, d); cwsb.Append(" THEN "); - var val = col.GetMapValue(d); + var val = col.GetDbValue(d); if (_noneParameter) cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val)); else diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 76229b54..9c1ae1ce 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -277,7 +277,7 @@ namespace FreeSql.Internal { if (pkidx > 0) sb.Append(" AND "); sb.Append(aliasAndDot).Append(this.QuoteSqlName(pk.Attribute.Name)); - sb.Append(this.FormatSql(" = {0}", pk.GetMapValue(dywhere))); + sb.Append(this.FormatSql(" = {0}", pk.GetDbValue(dywhere))); ++pkidx; } return sb.ToString(); @@ -301,7 +301,7 @@ namespace FreeSql.Internal var itype = i.GetType(); isEntityType = (itype == table.Type || itype.BaseType == table.Type); } - if (isEntityType) sb.Append(this.FormatSql("{0}", primarys[0].GetMapValue(i))); + if (isEntityType) sb.Append(this.FormatSql("{0}", primarys[0].GetDbValue(i))); else sb.Append(this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, i))); ++ieidx; } @@ -352,7 +352,7 @@ namespace FreeSql.Internal { var sbin = new StringBuilder(); sbin.Append(aliasAndDot).Append(this.QuoteSqlName(pk1.Attribute.Name)); - var indt = its.Select(a => pk1.GetMapValue(a)).Where(a => a != null).ToArray(); + var indt = its.Select(a => pk1.GetDbValue(a)).Where(a => a != null).ToArray(); if (indt.Any() == false) return null; if (indt.Length == 1) sbin.Append(" = ").Append(this.FormatSql("{0}", indt.First())); else sbin.Append(" IN (").Append(string.Join(",", indt.Select(a => this.FormatSql("{0}", a)))).Append(")"); @@ -365,7 +365,7 @@ namespace FreeSql.Internal { var filter = ""; foreach (var pk in table.Primarys) - filter += $" AND {aliasAndDot}{this.QuoteSqlName(pk.Attribute.Name)} = {this.FormatSql("{0}", pk.GetMapValue(item))}"; + filter += $" AND {aliasAndDot}{this.QuoteSqlName(pk.Attribute.Name)} = {this.FormatSql("{0}", pk.GetDbValue(item))}"; if (string.IsNullOrEmpty(filter)) continue; if (sb != null) { diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index ef164b67..ef69fcc6 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -1,4 +1,5 @@ using FreeSql.DataAnnotations; +using FreeSql.Extensions.EntityUtil; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -20,8 +21,37 @@ namespace FreeSql.Internal.Model public int DbSize { get; internal set; } public byte DbPrecision { get; internal set; } public byte DbScale { get; internal set; } + //public Func ConversionCsToDb { get; internal set; } + //public Func ConversionDbToCs { get; internal set; } + + /// + /// 获取 obj.CsName 属性值 MapType 之后的数据库值 + /// + /// + /// + public object GetDbValue(object obj) + { + var dbval = Table.GetPropertyValue(obj, CsName); + //if (ConversionCsToDb != null) dbval = ConversionCsToDb(dbval); + if (Attribute.MapType != CsType) dbval = Utils.GetDataReaderValue(Attribute.MapType, dbval); + return dbval; + } + /// + /// 获取 obj.CsName 属性原始值(不经过 MapType) + /// + /// + public object GetValue(object obj) => Table.GetPropertyValue(obj, CsName); + /// + /// 设置 obj.CsName 属性值 + /// + /// + /// + public void SetValue(object obj, object val) => Table.SetPropertyValue(obj, CsName, Utils.GetDataReaderValue(CsType, val)); + + static ConcurrentDictionary> _dicGetMapValue = new ConcurrentDictionary>(); + [Obsolete("请使用 GetDbValue 或者 GetValue")] public object GetMapValue(object obj) { var func = _dicGetMapValue.GetOrAdd(this, col => @@ -57,6 +87,7 @@ namespace FreeSql.Internal.Model return func(obj); } static ConcurrentDictionary> _dicSetMapValue = new ConcurrentDictionary>(); + [Obsolete("请使用 SetValue")] public void SetMapValue(object obj, object val) { var func = _dicSetMapValue.GetOrAdd(this, col => diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index b2181171..6b3ea61a 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -66,7 +66,7 @@ namespace FreeSql.Dameng.Curd sb.Append(col.DbInsertValue); else { - object val = col.GetMapValue(d); + object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs index 97f8d70c..9fa70101 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs @@ -49,7 +49,7 @@ namespace FreeSql.Dameng.Curd { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -57,7 +57,7 @@ namespace FreeSql.Dameng.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs index 03fa7091..91e345e3 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs @@ -54,14 +54,14 @@ namespace FreeSql.MsAccess.Curd { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } var pkidx = 0; foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" + '+' + "); - sb.Append(MsAccessUtils.GetCastSql(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)), typeof(string))); + sb.Append(MsAccessUtils.GetCastSql(_commonUtils.FormatSql("{0}", pk.GetDbValue(d)), typeof(string))); ++pkidx; } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 35a98726..1665cd94 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -90,7 +90,7 @@ namespace FreeSql.MySql.Curd { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("CONCAT("); @@ -98,7 +98,7 @@ namespace FreeSql.MySql.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(", '+', "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index 85dcab11..d5bc3fb0 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -66,7 +66,7 @@ namespace FreeSql.Odbc.Dameng sb.Append(col.DbInsertValue); else { - object val = col.GetMapValue(d); + object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs index 847863bb..6626c0d7 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -50,7 +50,7 @@ namespace FreeSql.Odbc.Dameng { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -58,7 +58,7 @@ namespace FreeSql.Odbc.Dameng foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs index e33c4a14..3b4169b6 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs @@ -47,14 +47,14 @@ namespace FreeSql.Odbc.Default { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } var pkidx = 0; foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" + '+' + "); - sb.Append(_utils.Adapter.CastSql(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)), _utils.Adapter.MappingOdbcTypeVarChar)); + sb.Append(_utils.Adapter.CastSql(_commonUtils.FormatSql("{0}", pk.GetDbValue(d)), _utils.Adapter.MappingOdbcTypeVarChar)); ++pkidx; } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index a4585379..b3c0f838 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -93,7 +93,7 @@ namespace FreeSql.Odbc.KingbaseES { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -101,7 +101,7 @@ namespace FreeSql.Odbc.KingbaseES foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::text"); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append("::text"); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index edabbb1f..34a41055 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -90,7 +90,7 @@ namespace FreeSql.Odbc.MySql { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("CONCAT("); @@ -98,7 +98,7 @@ namespace FreeSql.Odbc.MySql foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(", '+', "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index 2f73dc42..5313decc 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -66,7 +66,7 @@ namespace FreeSql.Odbc.Oracle sb.Append(col.DbInsertValue); else { - object val = col.GetMapValue(d); + object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index e8332f8d..9ab74f81 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.Odbc.Oracle { if (_table.Primarys[0].Attribute.DbType.Contains("NVARCHAR2")) sb.Append("N"); - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -60,7 +60,7 @@ namespace FreeSql.Odbc.Oracle foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 33ab8a7f..8ebffb29 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -93,7 +93,7 @@ namespace FreeSql.Odbc.PostgreSQL { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -101,7 +101,7 @@ namespace FreeSql.Odbc.PostgreSQL foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::text"); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append("::text"); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index a03413b5..f8d98ecc 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -88,14 +88,14 @@ namespace FreeSql.Odbc.SqlServer { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } var pkidx = 0; foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" + '+' + "); - sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append(" as varchar)"); + sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append(" as varchar)"); ++pkidx; } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 04c8d2ad..d5807859 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -68,7 +68,7 @@ namespace FreeSql.Oracle.Curd sb.Append(col.DbInsertValue); else { - object val = col.GetMapValue(d); + object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index 02c0ac49..a1e4cdcf 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.Oracle.Curd { if (_table.Primarys[0].Attribute.DbType.Contains("NVARCHAR2")) sb.Append("N"); - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -60,7 +60,7 @@ namespace FreeSql.Oracle.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 04b8fd09..e8b735ab 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -93,7 +93,7 @@ namespace FreeSql.PostgreSQL.Curd { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -101,7 +101,7 @@ namespace FreeSql.PostgreSQL.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::text"); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append("::text"); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index 645ab6ad..5d71a4fe 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -94,7 +94,7 @@ namespace FreeSql.ShenTong.Curd { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -102,7 +102,7 @@ namespace FreeSql.ShenTong.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::text"); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append("::text"); ++pkidx; } sb.Append(")"); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index a6ba72af..6faac879 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -89,14 +89,14 @@ namespace FreeSql.SqlServer.Curd { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } var pkidx = 0; foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" + '+' + "); - sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append(" as varchar)"); + sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append(" as varchar)"); ++pkidx; } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index fdf9c3c6..7900160f 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -50,7 +50,7 @@ namespace FreeSql.Sqlite.Curd { if (_table.Primarys.Length == 1) { - sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); return; } sb.Append("("); @@ -58,7 +58,7 @@ namespace FreeSql.Sqlite.Curd foreach (var pk in _table.Primarys) { if (pkidx > 0) sb.Append(" || '+' || "); - sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); ++pkidx; } sb.Append(")"); diff --git a/readme.md b/readme.md index 702c44b3..ce04c0d3 100644 --- a/readme.md +++ b/readme.md @@ -188,7 +188,7 @@ QQ群:4336577(已满)、8578575(在线) ## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 -无名 100元、无名 99.99元 +无名 100元、蛰伏 99.99元 > Thank you for your donation From cdbc6d5a0417275672d3e38ea34330ff7acc3708 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 18 Aug 2020 18:19:16 +0800 Subject: [PATCH 0844/1029] =?UTF-8?q?-=20=E4=BF=AE=E6=AD=A3=20Aop.CommandA?= =?UTF-8?q?fter=20Exception=20=E6=B2=A1=E6=9C=89=E8=B5=8B=E5=80=BC=20#425?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index c0c757ea..5d3100ad 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -56,7 +56,7 @@ namespace FreeSql.Internal.CommonProvider if (ex == null) { - _util?._orm?.Aop.CommandAfterHandler?.Invoke(_util._orm, new Aop.CommandAfterEventArgs(pc.before, null, logtxt.ToString())); + _util?._orm?.Aop.CommandAfterHandler?.Invoke(_util._orm, new Aop.CommandAfterEventArgs(pc.before, ex, logtxt.ToString())); return; } @@ -79,7 +79,7 @@ namespace FreeSql.Internal.CommonProvider RollbackTransaction(ex); } - _util?._orm?.Aop.CommandAfterHandler?.Invoke(_util._orm, new Aop.CommandAfterEventArgs(pc.before, null, logtxt.ToString())); + _util?._orm?.Aop.CommandAfterHandler?.Invoke(_util._orm, new Aop.CommandAfterEventArgs(pc.before, ex, logtxt.ToString())); cmd.Parameters.Clear(); if (isThrowException) From 09d7623b1b142e8df448d78515075aff6e44d50a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 18 Aug 2020 19:30:58 +0800 Subject: [PATCH 0845/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E5=AF=BC=E8=88=AA=E5=B1=9E=E6=80=A7=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=A6=82=E6=9E=9C=E4=B8=8B=E7=BA=A7=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E5=B1=9E=E6=80=A7=E8=A2=AB=20Include=20=E8=BF=87?= =?UTF-8?q?=EF=BC=8C=E5=88=99=E5=B0=86=E4=BB=96=E4=BB=AC=E4=B9=9F=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=87=BA=E6=9D=A5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++ .../MySql/Curd/MySqlSelectTest.cs | 14 ++++++++++ FreeSql/Internal/CommonExpression.cs | 26 ++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 68241282..312b0c42 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 0ee8ba66..3dc86b69 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -512,6 +512,20 @@ namespace FreeSql.Tests.MySql sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); query.ToList(); + + sql = select.ToSql(a => a.Type.Parent); + Assert.Equal(@"SELECT a__Type__Parent.`Id` as1, a__Type__Parent.`Name` as2 +FROM `tb_topic` a +LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` +LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + var ccdata1 = select.ToList(a => a.Type.Parent); + + sql = select.Include(a => a.Type.Parent).ToSql(a => a.Type); + Assert.Equal(@"SELECT a__Type.`Guid` as1, a__Type.`ParentId` as2, a__Type.`Name` as3, a__Type__Parent.`Id` as4, a__Type__Parent.`Name` as5 +FROM `tb_topic` a +LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` +LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + var ccdata2 = select.Include(a => a.Type.Parent).ToList(a => a.Type); } [Fact] public void InnerJoin() diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index f2d1512a..d6382158 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -83,7 +83,7 @@ namespace FreeSql.Internal return false; case ExpressionType.Parameter: case ExpressionType.MemberAccess: - if (_common.GetTableByEntity(exp.Type) != null && + if (_common.GetTableByEntity(exp.Type) != null && //判断 [JsonMap] 并非导航对象 (exp.NodeType == ExpressionType.Parameter || exp is MemberExpression expMem && ( _common.GetTableByEntity(expMem.Expression.Type)?.ColumnsByCs.ContainsKey(expMem.Member.Name) == false || @@ -112,6 +112,30 @@ namespace FreeSql.Internal if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); parent.Childs.Add(child); } + if (_tables.Count > 1) { //如果下级导航属性被 Include 过,则将他们也查询出来 + foreach (var memProp in tb.Properties.Values) + { + var memtbref = tb.GetTableRef(memProp.Name, false); + if (memtbref == null) continue; + switch (memtbref.RefType) + { + case TableRefType.ManyToMany: + case TableRefType.OneToMany: + continue; + } + if (_tables.Any(a => a.Alias == $"{map.First().Table.Alias}__{memProp.Name}") == false) continue; + + var child = new ReadAnonymousTypeInfo + { + Property = memProp, + CsName = memProp.Name, + CsType = memProp.PropertyType, + MapType = memProp.PropertyType + }; + parent.Childs.Add(child); + ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), grouping, whereCascadeExpression, false); + } + } } else { From 306f619e90558df042ff4166b5386b4ad44f0a4c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 19 Aug 2020 16:11:22 +0800 Subject: [PATCH 0846/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Dto=20?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E6=9F=A5=E8=AF=A2=E5=B1=9E=E6=80=A7=E5=90=8D?= =?UTF-8?q?=E4=B8=8D=E5=8C=BA=E5=88=86=E5=A4=A7=E5=B0=8F=E5=86=99=20bug=20?= =?UTF-8?q?#427=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DbContext/DbContextOptions.cs | 4 ++-- FreeSql.DbContext/FreeSql.DbContext.xml | 20 ++----------------- FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 15 ++++++++++++++ FreeSql/Internal/CommonExpression.cs | 4 ++-- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContextOptions.cs b/FreeSql.DbContext/DbContext/DbContextOptions.cs index e43ff5ae..25cd8df4 100644 --- a/FreeSql.DbContext/DbContext/DbContextOptions.cs +++ b/FreeSql.DbContext/DbContext/DbContextOptions.cs @@ -16,8 +16,8 @@ namespace FreeSql /// - 保存的时候,实体的属性集合是空的,如何操作?记录全部删除? /// - 保存的时候,由于数据库中记录非常之多,那么只想保存子表的部分数据,或者只需要添加,如何操作? /// - /// 【多对多】模型下,我们对中间表的保存是完整对比操作,对外部实体的操作只作新增(注意不会更新) - /// - 属性集合为空时,删除他们的所有关联数据(中间表) + /// 【多对多】模型下,我们对中间表的保存是完整对比操作,对外部实体的操作只作新增(*注意不会更新) + /// - 属性集合为空时,删除他们的所有关联数据(中间表) /// - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录 /// public bool EnableAddOrUpdateNavigateList { get; set; } = false; diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 312b0c42..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -86,8 +86,8 @@ - 保存的时候,实体的属性集合是空的,如何操作?记录全部删除? - 保存的时候,由于数据库中记录非常之多,那么只想保存子表的部分数据,或者只需要添加,如何操作? - 【多对多】模型下,我们对中间表的保存是完整对比操作,对外部实体的操作只作新增(注意不会更新) - - 属性集合为空时,删除他们的所有关联数据(中间表) + 【多对多】模型下,我们对中间表的保存是完整对比操作,对外部实体的操作只作新增(*注意不会更新) + - 属性集合为空时,删除他们的所有关联数据(中间表) - 属性集合不为空时,与数据库存在的关联数据(中间表)完全对比,计算出应该删除和添加的记录 @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 81dd4ac7..63226af1 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -435,9 +435,24 @@ namespace FreeSql.Tests } public enum TestUpdateModelEnum { x1, x2, x3 } + public class Cadre + { + public int? education { get; set; } + public int? Education { get; set; } + } + public class TbCadre + { + public Guid Id { get; set; } + public int? Education2 { get; set; } + } + [Fact] public void Test1() { + g.sqlite.Insert(new[] { new TbCadre { Education2 = 10 }, new TbCadre { Education2 = 11 } }).ExecuteAffrows(); + var tst102 = g.sqlite.Select().First(a => new Cadre { Education = a.Education2 }); + + var testemoji = new TestGuidId { xxx = "💐🌸💮🌹🌺🌻🌼🌷🌱🌿🍀" }; Assert.Equal(1, g.sqlserver.Insert(testemoji).ExecuteAffrows()); var emoji = g.sqlserver.Select().Where(a => a.Id == testemoji.Id).First(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index d6382158..584962a2 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -102,7 +102,7 @@ namespace FreeSql.Internal { var child = new ReadAnonymousTypeInfo { - Property = tb.Properties.TryGetValue(map[idx].Column.CsName, out var tryprop) ? tryprop : tb.Type.GetProperty(map[idx].Column.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), + Property = tb.Properties.TryGetValue(map[idx].Column.CsName, out var tryprop) ? tryprop : tb.Type.GetProperty(map[idx].Column.CsName, BindingFlags.Public | BindingFlags.Instance), CsName = map[idx].Column.CsName, DbField = $"{map[idx].Table.Alias}.{_common.QuoteSqlName(map[idx].Column.Attribute.Name)}", CsType = map[idx].Column.CsType, @@ -214,7 +214,7 @@ namespace FreeSql.Internal if (initAssignExp == null) continue; var child = new ReadAnonymousTypeInfo { - Property = initExp.Type.GetProperty(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), + Property = initExp.Type.GetProperty(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.Instance), CsName = initExp.Bindings[a].Member.Name, CsType = initAssignExp.Expression.Type, MapType = initAssignExp.Expression.Type From d74f5e3d0b390ab608afeb4d72b8ed2efc3dc0a9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 19 Aug 2020 16:15:09 +0800 Subject: [PATCH 0847/1029] v1.8.0-preview0820 #427 #425 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 37 insertions(+), 21 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 933ed2c5..28ed494e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 372c1a43..84bc713c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a35e0c5f..1155141a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 0b929446..3a1d6d7a 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index f9b05517..2e01e114 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0819 + 1.8.0-preview0820 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 6d1bdb74..2bf8b1a4 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b0481453..87c8f2e7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 1c6fbba2..d01c6d19 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b2f97e9e..379f745c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 584962a2..89c9e696 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -214,7 +214,7 @@ namespace FreeSql.Internal if (initAssignExp == null) continue; var child = new ReadAnonymousTypeInfo { - Property = initExp.Type.GetProperty(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.Instance), + Property = initExp.Type.GetProperty(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.Instance), //#427 不能使用 BindingFlags.IgnoreCase CsName = initExp.Bindings[a].Member.Name, CsType = initAssignExp.Expression.Type, MapType = initAssignExp.Expression.Type diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 75d26f32..7103da4e 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index af8619de..b099277c 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b09880b1..fa4ebec9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 3c5e6327..7f31fefc 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d6640828..ed5b22af 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6d410ddb..bc5fd792 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e1a16334..e97c6347 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 90aaa5e5..370be19d 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 46a37f9d..be378538 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 92ca1f7d..bfae5cf5 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ce74fae3..07a0b536 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0819 + 1.8.0-preview0820 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From adcff6feaf711128b621ba0113e8b352e09f0b7a Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Thu, 20 Aug 2020 09:22:04 +0800 Subject: [PATCH 0848/1029] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index ce04c0d3..c2d5c118 100644 --- a/readme.md +++ b/readme.md @@ -188,7 +188,7 @@ QQ群:4336577(已满)、8578575(在线) ## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 -无名 100元、蛰伏 99.99元 +无名 100元、蛰伏 99.99元、TCYM 66.66元 > Thank you for your donation From 1f8841e5e230eef84215630139b4bec4bf91db5c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 20 Aug 2020 22:31:39 +0800 Subject: [PATCH 0849/1029] test dm char(36) --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 -- .../Dameng/DamengCodeFirstTest.cs | 40 +++++ .../Oracle/OracleCodeFirstTest.cs | 20 +++ FreeSql/FreeSql.xml | 151 ------------------ 4 files changed, 60 insertions(+), 167 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs index de3a6c69..a53525b3 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengCodeFirstTest.cs @@ -3,6 +3,7 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Data; using System.Linq; using System.Text; using Xunit; @@ -11,6 +12,45 @@ namespace FreeSql.Tests.Dameng { public class DamengCodeFirstTest { + [Fact] + public void StringLength36() + { + using (var conn = g.dameng.Ado.MasterPool.Get()) + { + var cmd = conn.Value.CreateCommand(); + cmd.CommandText = @"SELECT a.""ID"", a.""CREATORID"" +FROM ""TS_SL361"" a +WHERE (a.""ID"" = 1) AND ROWNUM < 2"; + using (var dr = cmd.ExecuteReader()) + { + if (dr.Read()) + { + var id1 = dr.GetInt64(0); + var creatorId1 = dr.GetString(1); + + var id = dr.GetValue(0); + //var creatorId = dr.GetValue(1); // + } + } + } + + //var repo = g.dameng.GetRepository(); + + //var item1 = new TS_SL361 { CreatorId = "xxx '123 " }; + //repo.Insert(item1); + //var item2 = repo.Get(item1.Id); + + //Assert.Equal(item1.CreatorId, item2.CreatorId); + } + class TS_SL361 + { + [Column(IsIdentity = true)] + public long Id { get; set; } + [Column(StringLength = 36)] + public string CreatorId { get; set; } + } + + [Fact] public void Text_StringLength_1() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index bdf17b8d..8faf37e7 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Security.Cryptography.X509Certificates; using System.Text; using Xunit; @@ -12,6 +13,25 @@ namespace FreeSql.Tests.Oracle { public class OracleCodeFirstTest { + [Fact] + public void StringLength36() + { + var repo = g.oracle.GetRepository(); + + var item1 = new TS_SL361 { CreatorId = "xxx '123 " }; + repo.Insert(item1); + var item2 = repo.Get(item1.Id); + + Assert.Equal(item1.CreatorId, item2.CreatorId); + } + class TS_SL361 + { + [Column(IsIdentity = true)] + public long Id { get; set; } + [Column(StringLength = 36)] + public string CreatorId { get; set; } + } + [Fact] public void NClob_StringLength_1() { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4f53ec7b..1426df9f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2613,145 +2613,6 @@ - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3488,12 +3349,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3564,12 +3419,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 From f7ce4dc63612482ee984589aba9edbea005809c1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 21 Aug 2020 19:46:23 +0800 Subject: [PATCH 0850/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E4=BA=BA?= =?UTF-8?q?=E5=A4=A7=E9=87=91=E4=BB=93=20Ado.Net=20=E5=AE=9E=E7=8E=B0=20Fr?= =?UTF-8?q?eeSql.Provider.KingbaseES=20#325=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 2 +- .../FreeSql.Generator.csproj | 2 +- Extensions/FreeSql.Generator/RazorModel.cs | 3 +- FreeSql.DbContext/DbSet/DbSet.cs | 1 + FreeSql.DbContext/DbSet/DbSetAsync.cs | 2 + FreeSql.DbContext/DbSet/DbSetSync.cs | 2 + FreeSql.DbContext/FreeSql.DbContext.xml | 16 + .../FreeSql.Tests/FreeSql.Tests.csproj | 16 +- .../KingbaseES/Curd/KingbaseESDeleteTest.cs | 106 + ...aseESInsertOrUpdateIfExistsDoNotingTest.cs | 266 +++ .../Curd/KingbaseESInsertOrUpdateTest.cs | 205 ++ .../KingbaseES/Curd/KingbaseESInsertTest.cs | 141 ++ .../KingbaseES/Curd/KingbaseESSelectTest.cs | 1816 +++++++++++++++++ .../KingbaseES/Curd/KingbaseESUpdateTest.cs | 190 ++ .../KingbaseES/Curd/OnConflictDoUpdateTest.cs | 158 ++ .../KingbaseESAdo/KingbaseESAdoTest.cs | 66 + .../KingbaseES/KingbaseESAopTest.cs | 40 + .../KingbaseES/KingbaseESCodeFirstTest.cs | 334 +++ .../KingbaseES/KingbaseESDbFirstTest.cs | 64 + .../KingbaseESExpression/ConvertTest.cs | 169 ++ .../KingbaseESExpression/DateTimeTest.cs | 732 +++++++ .../KingbaseESExpression/MathTest.cs | 156 ++ .../KingbaseESExpression/OtherTest.cs | 165 ++ .../KingbaseESExpression/StringTest.cs | 816 ++++++++ .../KingbaseESExpression/TimeSpanTest.cs | 293 +++ .../KingbaseES/MapType/BoolNullableTest.cs | 1571 ++++++++++++++ .../KingbaseES/MapType/BoolTest.cs | 1105 ++++++++++ .../KingbaseES/MapType/DateTimeOffSetTest.cs | 54 + .../KingbaseES/MapType/EnumTest.cs | 261 +++ .../KingbaseES/MapType/ToStringTest.cs | 570 ++++++ FreeSql.Tests/FreeSql.Tests/g.cs | 14 + FreeSql.sln | 15 + FreeSql/DataType.cs | 7 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 + FreeSql/FreeSql.xml | 156 ++ FreeSql/FreeSqlBuilder.cs | 5 + .../SelectProvider/Select0Provider.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 2 + .../Curd/KingbaseESDelete.cs | 99 + .../Curd/KingbaseESInsert.cs | 216 ++ .../Curd/KingbaseESInsertOrUpdate.cs | 57 + .../Curd/KingbaseESOnConflictDoUpdate.cs | 208 ++ .../Curd/KingbaseESSelect.cs | 174 ++ .../Curd/KingbaseESUpdate.cs | 169 ++ .../FreeSql.Provider.KingbaseES.csproj | 45 + .../KingbaseESAdo/KingbaseESAdo.cs | 78 + .../KingbaseESAdo/KingbaseESConnectionPool.cs | 258 +++ .../KingbaseESCodeFirst.cs | 397 ++++ .../KingbaseESDbFirst.cs | 524 +++++ .../KingbaseESExpression.cs | 622 ++++++ .../KingbaseESExtensions.cs | 12 + .../KingbaseESProvider.cs | 60 + .../KingbaseESUtils.cs | 163 ++ Providers/FreeSql.Provider.KingbaseES/key.snk | Bin 0 -> 596 bytes .../lib/Kdbndp.dll | Bin 0 -> 732672 bytes 55 files changed, 12596 insertions(+), 10 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/OnConflictDoUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/ToStringTest.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj create mode 100644 Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/KingbaseESCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/KingbaseESExtensions.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/KingbaseESProvider.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/KingbaseESUtils.cs create mode 100644 Providers/FreeSql.Provider.KingbaseES/key.snk create mode 100644 Providers/FreeSql.Provider.KingbaseES/lib/Kdbndp.dll diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index b67febfc..38a4f7fa 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -183,7 +183,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 case "oracle": ArgsDbType = DataType.Oracle; break; case "sqlite": ArgsDbType = DataType.Sqlite; break; case "dameng": ArgsDbType = DataType.Dameng; break; - case "odbckingbasees": ArgsDbType = DataType.OdbcKingbaseES; break; + case "kingbasees": ArgsDbType = DataType.KingbaseES; break; case "shentong": ArgsDbType = DataType.ShenTong; break; default: throw new ArgumentException($"-DB 参数错误,不支持的类型:\"{dbargs[0]}\""); } diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 2e01e114..1841b3b0 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -35,8 +35,8 @@ + - diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 8e1d8ca9..63e2e77f 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -112,6 +112,7 @@ public class RazorModel { break; case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: switch (col.DbTypeTextFull.ToLower()) @@ -220,7 +221,7 @@ public class RazorModel { else if ((cstype == typeof(string) && defval.StartsWith("'") && defval.EndsWith("'::character varying") || cstype == typeof(Guid) && defval.StartsWith("'") && defval.EndsWith("'::uuid") ) && (fsql.Ado.DataType == DataType.PostgreSQL || fsql.Ado.DataType == DataType.OdbcPostgreSQL || - fsql.Ado.DataType == DataType.OdbcKingbaseES || + fsql.Ado.DataType == DataType.KingbaseES || fsql.Ado.DataType == DataType.OdbcKingbaseES || fsql.Ado.DataType == DataType.ShenTong)) { defval = defval.Substring(1, defval.LastIndexOf("'::") - 1).Replace("''", "'"); diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 69fedabd..f4aef4f3 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -277,6 +277,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: return true; diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 0c602322..1c2fa9aa 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -41,6 +41,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) @@ -104,6 +105,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: await DbContextFlushCommandAsync(); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index dd260438..59e173a3 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -41,6 +41,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: if (_tableIdentitys.Length == 1) @@ -108,6 +109,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: DbContextFlushCommand(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 0acabc69..e6703320 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -38,6 +38,7 @@ + @@ -51,12 +52,15 @@ ..\..\Providers\FreeSql.Provider.Dameng\lib\DmProvider\netstandard2.0\DmProvider.dll - - ..\..\Providers\FreeSql.Provider.ShenTong\lib\System.Data.OscarClient.dll - - - ..\..\Providers\FreeSql.Provider.ShenTong\lib\Mono.Security.dll - + + ..\..\Providers\FreeSql.Provider.ShenTong\lib\System.Data.OscarClient.dll + + + ..\..\Providers\FreeSql.Provider.ShenTong\lib\Mono.Security.dll + + + ..\..\Providers\FreeSql.Provider.KingbaseES\lib\Kdbndp.dll + diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESDeleteTest.cs new file mode 100644 index 00000000..2e5a42e4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESDeleteTest.cs @@ -0,0 +1,106 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESDeleteTest + { + + IDelete delete => g.kingbaseES.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.kingbaseES.Delete().ToSql()); + var sql = g.kingbaseES.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.kingbaseES.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.kingbaseES.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.kingbaseES.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.kingbaseES.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.kingbaseES.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //var item = g.kingbaseES.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.kingbaseES.Delete().ToSql()); + var sql = g.kingbaseES.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.kingbaseES.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + + sql = g.kingbaseES.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.kingbaseES.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs new file mode 100644 index 00000000..7f8756fd --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs @@ -0,0 +1,266 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESInsertOrUpdateIfExistsDoNotingTest + { + IFreeSql fsql => g.kingbaseES; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(2) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '01') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '011') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(2, '02') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '01') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '011') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(2, '02') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""ID"") DO NOTHING + +; + +INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '011') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(2, '02', '02') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs new file mode 100644 index 00000000..7d7c6758 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs @@ -0,0 +1,205 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESInsertOrUpdateTest + { + IFreeSql fsql => g.kingbaseES; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(2) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(1, '01') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(1, '011') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(2, '02') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU02""(""ID"", ""NAME"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '011') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(2, '02', '02') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""ID"") DO UPDATE SET +""NAME"" = EXCLUDED.""NAME"", +""VERSION"" = ""TBIOU04"".""VERSION"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertTest.cs new file mode 100644 index 00000000..bf4411ca --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESInsertTest + { + + IInsert insert => g.kingbaseES.Insert(); + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000000'), (100, 'newtitle1', '0001-01-01 00:00:00.000000'), (200, 'newtitle2', '0001-01-01 00:00:00.000000'), (300, 'newtitle3', '0001-01-01 00:00:00.000000'), (400, 'newtitle4', '0001-01-01 00:00:00.000000'), (500, 'newtitle5', '0001-01-01 00:00:00.000000'), (600, 'newtitle6', '0001-01-01 00:00:00.000000'), (700, 'newtitle7', '0001-01-01 00:00:00.000000'), (800, 'newtitle8', '0001-01-01 00:00:00.000000'), (900, 'newtitle9', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"TITLE\") VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"TITLE\") VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\") VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.kingbaseES.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.kingbaseES.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.kingbaseES.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + insert.AppendData(items.First()).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000000'), (100, 'newTitle1', '0001-01-01 00:00:00.000000'), (200, 'newTitle2', '0001-01-01 00:00:00.000000'), (300, 'newTitle3', '0001-01-01 00:00:00.000000'), (400, 'newTitle4', '0001-01-01 00:00:00.000000'), (500, 'newTitle5', '0001-01-01 00:00:00.000000'), (600, 'newTitle6', '0001-01-01 00:00:00.000000'), (700, 'newTitle7', '0001-01-01 00:00:00.000000'), (800, 'newTitle8', '0001-01-01 00:00:00.000000'), (900, 'newTitle9', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"TITLE\") VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"TITLE\") VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\") VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESSelectTest.cs new file mode 100644 index 00000000..14a9788a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESSelectTest.cs @@ -0,0 +1,1816 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESSelectTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.kingbaseES.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.kingbaseES.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.kingbaseES.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.kingbaseES.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.kingbaseES.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.kingbaseES.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.kingbaseES.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.kingbaseES.Insert(items).ExecuteAffrows()); + + //var dt1 = select.ToDataTable(); + //var dt2 = select.ToDataTable("id, 111222"); + //var dt3 = select.ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + g.kingbaseES.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.kingbaseES.Select().ToList(); + var testGuidId6 = g.kingbaseES.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.kingbaseES.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.kingbaseES.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.kingbaseES.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + g.kingbaseES.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.kingbaseES.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); + query2.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.kingbaseES.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.kingbaseES.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") + FROM ""TB_TOPIC22"" b + limit 1) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") + FROM ""TB_TOPIC22"" b + limit 1) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") + FROM ""TB_TOPIC22"" b + limit 1) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") + FROM ""TB_TOPIC22"" b + limit 1) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE ((((a.""ID"")::text) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.kingbaseES.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.kingbaseES.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.kingbaseES.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.kingbaseES.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.kingbaseES.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.kingbaseES.Insert(model4s).ExecuteAffrows()); + + var t0 = g.kingbaseES.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.kingbaseES.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.kingbaseES.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.kingbaseES.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.kingbaseES.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.kingbaseES.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.kingbaseES.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.kingbaseES.Insert(model1).ExecuteIdentity(); + + var t1 = g.kingbaseES.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.kingbaseES.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.kingbaseES.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.kingbaseES.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.kingbaseES.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.kingbaseES.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.kingbaseES.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.kingbaseES.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.kingbaseES.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.kingbaseES.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.kingbaseES.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.kingbaseES.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.kingbaseES.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.kingbaseES.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.kingbaseES.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.kingbaseES.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.kingbaseES.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.kingbaseES.Insert(song3).ExecuteIdentity(); + + g.kingbaseES.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.kingbaseES.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.kingbaseES.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.kingbaseES.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.kingbaseES, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.kingbaseES.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.kingbaseES.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.kingbaseES.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.kingbaseES.Select().Count()); + Assert.Equal(3, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.kingbaseES.Select().Count()); + Assert.Equal(3, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.kingbaseES.Select().Count()); + Assert.Equal(3, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.kingbaseES.Select().Count()); + Assert.Equal(5, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.kingbaseES.Select().Count()); + Assert.Equal(5, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.kingbaseES.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.kingbaseES.Select().Count()); + g.kingbaseES.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.kingbaseES.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.kingbaseES.Select().Count()); + Assert.Equal(5, g.kingbaseES.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.kingbaseES; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a limit 1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a limit 1 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.kingbaseES; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + + public int testint { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESUpdateTest.cs new file mode 100644 index 00000000..021d4b5d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESUpdateTest.cs @@ -0,0 +1,190 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESUpdateTest + { + IUpdate update => g.kingbaseES.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.kingbaseES.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.kingbaseES.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.kingbaseES.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL, \"TITLE\" = 'newtitle', \"CREATETIME\" = '0001-01-01 00:00:00.000000' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END::int4, \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::text, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN '0001-01-01 00:00:00.000000' WHEN 2 THEN '0001-01-01 00:00:00.000000' WHEN 3 THEN '0001-01-01 00:00:00.000000' WHEN 4 THEN '0001-01-01 00:00:00.000000' WHEN 5 THEN '0001-01-01 00:00:00.000000' WHEN 6 THEN '0001-01-01 00:00:00.000000' WHEN 7 THEN '0001-01-01 00:00:00.000000' WHEN 8 THEN '0001-01-01 00:00:00.000000' WHEN 9 THEN '0001-01-01 00:00:00.000000' WHEN 10 THEN '0001-01-01 00:00:00.000000' END::timestamp WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::text WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = '2020-01-01 00:00:00.000000' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + if (g.kingbaseES.Select().Where(a => a.id1 == 1 && a.id2 == 7).Any() == false) + g.kingbaseES.Insert(new ts_source_mpk { id1 = 1, id2 = 7 }).ExecuteAffrows(); + if (g.kingbaseES.Select().Where(a => a.id1 == 1 && a.id2 == 8).Any() == false) + g.kingbaseES.Insert(new ts_source_mpk { id1 = 1, id2 = 8 }).ExecuteAffrows(); + + sql = g.kingbaseES.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + g.kingbaseES.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ExecuteAffrows(); + var testlist = g.kingbaseES.Select().ToList(); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.kingbaseES.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle', \"CREATETIME\" = '2020-01-01 00:00:00.000000' WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = coalesce(\"CLICKS\", 0) * 10 / 1 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = \"CLICKS\" * 10 / 1 WHERE (\"ID\" = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > '2000-01-01 00:00:00.000000' then 1 else 2 end WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + ? WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.kingbaseES.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.kingbaseES.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.kingbaseES.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.kingbaseES.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/OnConflictDoUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/OnConflictDoUpdateTest.cs new file mode 100644 index 00000000..8dd53840 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/OnConflictDoUpdateTest.cs @@ -0,0 +1,158 @@ +using FreeSql.DataAnnotations; +using FreeSql.KingbaseES; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class OnConflictDoUpdateTest + { + class TestOnConflictDoUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime? time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.kingbaseES.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"", ""TIME"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = EXCLUDED.""TIME""", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"", ""TIME"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000'), (101, 'title-101', '2000-01-01 00:00:00.000000'), (102, 'title-102', '2000-01-01 00:00:00.000000') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = EXCLUDED.""TIME""", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.kingbaseES.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(200, 'title-200') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = CASE EXCLUDED.""ID"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.kingbaseES.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(200, 'title-200') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = CASE EXCLUDED.""ID"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.kingbaseES.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(300, 'title-300') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""ID"") DO UPDATE SET +""TITLE"" = EXCLUDED.""TITLE"", +""TIME"" = CASE EXCLUDED.""ID"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.kingbaseES.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(300, 'title-300') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = CASE EXCLUDED.""ID"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.kingbaseES.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"", ""TIME"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = '2020-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new KingbaseESOnConflictDoUpdate(g.kingbaseES.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO ""TESTONCONFLICTDOUPDATEINFO""(""ID"", ""TITLE"", ""TIME"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +ON CONFLICT(""ID"") DO UPDATE SET +""TIME"" = '2020-01-01 00:00:00.000000'", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs new file mode 100644 index 00000000..ad9c7cf5 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs @@ -0,0 +1,66 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.kingbaseES.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.kingbaseES.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t3 = g.kingbaseES.Ado.Query("select * from \"TB_TOPIC\""); + + var t4 = g.kingbaseES.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + + var t5 = g.kingbaseES.Ado.Query("select * from \"TB_TOPIC\""); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.kingbaseES.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAopTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAopTest.cs new file mode 100644 index 00000000..abe66863 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.kingbaseES.Aop.AuditValue += audit; + + g.kingbaseES.Insert(item).ExecuteAffrows(); + + g.kingbaseES.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESCodeFirstTest.cs new file mode 100644 index 00000000..65197cba --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESCodeFirstTest.cs @@ -0,0 +1,334 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESCodeFirstTest + { + [Fact] + public void StringLength() + { + var dll = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + g.kingbaseES.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void ֱ_ֶ() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements<ֱ>(); + g.kingbaseES.CodeFirst.SyncStructure<ֱ>(); + + var item = new ֱ + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.kingbaseES.Insert<ֱ>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.kingbaseES.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.kingbaseES.Update<ֱ>().SetSource(item).ExecuteAffrows()); + item2 = g.kingbaseES.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.kingbaseES.GetRepository<ֱ>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.kingbaseES.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.kingbaseES.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + [Table(Name = "123ֱ")] + class ֱ + { + [Column(IsPrimary = true, Name = "123")] + public Guid { get; set; } + + [Column(Name = "123")] + public string { get; set; } + + [Column(Name = "123ʱ")] + public DateTime ʱ { get; set; } + } + + [Fact] + public void ı_ֶ() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements<ı>(); + g.kingbaseES.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.kingbaseES.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.kingbaseES.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.kingbaseES.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.kingbaseES.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.kingbaseES.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.kingbaseES.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.kingbaseES.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + g.kingbaseES.CodeFirst.SyncStructure(); + g.kingbaseES.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group, index22", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + + var id = g.kingbaseES.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.kingbaseES.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar2(200) not null", OldName = "title")] + public string title2 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + var sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //κ + //sql = g.kingbaseES.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.kingbaseES.Insert(); + ISelect select => g.kingbaseES.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem21 = select.Where(a => a.Id == item2.Id).First(a => new + { + a.Id, + a.id2, + a.SByte, + a.Short, + a.Int, + a.Long, + a.Byte, + a.UShort, + a.UInt, + a.ULong, + a.Double, + a.Float, + a.Decimal, + a.TimeSpan, + a.DateTimeOffSet, + a.Bytes, + a.String, + a.Char, + a.Guid + }); + var newitem22 = select.Where(a => a.Id == item2.Id).First(a => new + { + a.Id, a.id2, a.SByte, a.Short, a.Int, a.Long, a.Byte, a.UShort, a.UInt, a.ULong, a.Double, a.Float, a.Decimal, a.TimeSpan, a.DateTime, a.DateTimeOffSet, a.Bytes, a.String, a.Char, a.Guid + }); + + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); + + var items = select.ToList(); + var itemstb = select.ToDataTable(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public char Char { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESDbFirstTest.cs new file mode 100644 index 00000000..d4fa8964 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESDbFirstTest.cs @@ -0,0 +1,64 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.KingbaseES +{ + public class KingbaseESDbFirstTest + { + [Fact] + public void GetDatabases() + { + var t1 = g.kingbaseES.DbFirst.GetDatabases(); + } + + [Fact] + public void GetTablesByDatabase() + { + var t2 = g.kingbaseES.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); + } + + [Fact] + public void GetTableByName() + { + var fsql = g.kingbaseES; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("public.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + + [Fact] + public void ExistsTable() + { + var fsql = g.kingbaseES; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "tbexts.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"TBEXTS\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/ConvertTest.cs new file mode 100644 index 00000000..6c36c3cb --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseESExpression +{ + public class ConvertTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/DateTimeTest.cs new file mode 100644 index 00000000..5181c96a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/DateTimeTest.cs @@ -0,0 +1,732 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseESExpression +{ + public class DateTimeTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } = DateTime.Now; + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } = DateTime.Now; + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.kingbaseES.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + //data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + //data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + //data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + //data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + //data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/MathTest.cs new file mode 100644 index 00000000..58be916d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseESExpression +{ + public class MathTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/OtherTest.cs new file mode 100644 index 00000000..09864b3b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/OtherTest.cs @@ -0,0 +1,165 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseESExpression +{ + public class OtherTest + { + + ISelect select => g.kingbaseES.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).Limit(10).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/StringTest.cs new file mode 100644 index 00000000..084f1cc2 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/StringTest.cs @@ -0,0 +1,816 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseESExpression +{ + public class StringTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.kingbaseES.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void StringJoin() + { + var fsql = g.kingbaseES; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + + [Fact] + public void Format() + { + var item = g.kingbaseES.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce(((a.""ID"" + 1))::text, '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce(((a.""ID"" + 1))::text, '')||'x'||coalesce(((a.""ID"" + 1))::text, '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.kingbaseES.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce(((a.""ID"" + 1))::text, '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce(((a.""ID"" + 1))::text, '')||'x'||coalesce(((a.""ID"" + 1))::text, '')||'z-'||coalesce(to_char((a.""CREATETIME"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/TimeSpanTest.cs new file mode 100644 index 00000000..155797cb --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.KingbaseESExpression +{ + public class TimeSpanTest + { + + ISelect select => g.kingbaseES.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..6035da7b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.KingbaseESMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.kingbaseES; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/BoolTest.cs new file mode 100644 index 00000000..51e28099 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.KingbaseESMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.kingbaseES; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..cf40ca11 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.KingbaseESMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.kingbaseES; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/EnumTest.cs new file mode 100644 index 00000000..ebee3c47 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.KingbaseESMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.kingbaseES; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.kingbaseES; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.kingbaseES; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.kingbaseES; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/ToStringTest.cs new file mode 100644 index 00000000..2d00035b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.KingbaseESMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.kingbaseES; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 7b814ff5..02e4b983 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -148,4 +148,18 @@ public class g .Build(); }); public static IFreeSql shentong => shentongLazy.Value; + + static Lazy kingbaseESLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.KingbaseES, "Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=TDB2") + //.UseConnectionFactory(FreeSql.DataType.KingbaseES, () => new Kdbndp.KdbndpConnection("Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=TDB2")) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + .UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql kingbaseES => kingbaseESLazy.Value; } diff --git a/FreeSql.sln b/FreeSql.sln index e1c05120..8ffb0633 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -86,6 +86,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Post EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.SqlServerForSystem", "Providers\FreeSql.Provider.SqlServerForSystem\FreeSql.Provider.SqlServerForSystem.csproj", "{3D2BD8EC-253A-437F-B4C8-74BC0D91429B}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.KingbaseES", "Providers\FreeSql.Provider.KingbaseES\FreeSql.Provider.KingbaseES.csproj", "{CDD6A896-F6DF-44CB-B430-06B383916EB0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -528,6 +530,18 @@ Global {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x64.Build.0 = Release|Any CPU {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x86.ActiveCfg = Release|Any CPU {3D2BD8EC-253A-437F-B4C8-74BC0D91429B}.Release|x86.Build.0 = Release|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Debug|x64.ActiveCfg = Debug|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Debug|x64.Build.0 = Debug|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Debug|x86.ActiveCfg = Debug|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Debug|x86.Build.0 = Debug|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|Any CPU.Build.0 = Release|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|x64.ActiveCfg = Release|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|x64.Build.0 = Release|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|x86.ActiveCfg = Release|Any CPU + {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -558,6 +572,7 @@ Global {07AB0B37-A8B1-4FB1-9259-7B804E369E36} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {938173AF-157F-4040-AED3-171DA1809CAA} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {3D2BD8EC-253A-437F-B4C8-74BC0D91429B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {CDD6A896-F6DF-44CB-B430-06B383916EB0} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 0d00c721..78f0d7cb 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -44,6 +44,11 @@ namespace FreeSql /// /// 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 /// - ShenTong + ShenTong, + + /// + /// 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 + /// + KingbaseES } } diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 7ce20615..c90437a1 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -430,6 +430,7 @@ public static partial class FreeSqlGlobalExtensions { case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: //神通测试未通过 case DataType.SqlServer: @@ -487,6 +488,7 @@ public static partial class FreeSqlGlobalExtensions { case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: //神通测试未通过 case DataType.MySql: diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1426df9f..a5622151 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -601,6 +601,11 @@ 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 + + + 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null @@ -2613,6 +2618,145 @@ + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3349,6 +3493,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3419,6 +3569,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 58fc9ee8..727d0fc4 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -246,6 +246,11 @@ namespace FreeSql if (type == null) throwNotFind("FreeSql.Provider.ShenTong.dll", "FreeSql.ShenTong.ShenTongProvider<>"); break; + case DataType.KingbaseES: + type = Type.GetType("FreeSql.KingbaseES.KingbaseESProvider`1,FreeSql.Provider.KingbaseES")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.KingbaseES.dll", "FreeSql.KingbaseES.KingbaseESProvider<>"); + break; + default: throw new Exception("未指定 UseConnectionString 或者 UseConnectionFactory"); } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 153655e0..89c341d5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -617,6 +617,7 @@ namespace FreeSql.Internal.CommonProvider break; case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: _tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; break; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index a90c057a..24aeb1f8 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -247,6 +247,7 @@ namespace FreeSql.Internal break; case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: if (strlen < 0) colattr.DbType = "TEXT"; @@ -295,6 +296,7 @@ namespace FreeSql.Internal break; case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: + case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: //驱动引发的异常:“System.Data.OscarClient.OscarException”(位于 System.Data.OscarClient.dll 中) colattr.DbType = "BYTEA"; //变长二进制串 diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs new file mode 100644 index 00000000..8b9018e8 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs @@ -0,0 +1,99 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.KingbaseES +{ + + class KingbaseESDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public KingbaseESDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + +#if net40 +#else + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + this.ClearData(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs new file mode 100644 index 00000000..f76a3683 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs @@ -0,0 +1,216 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.KingbaseES +{ + + class KingbaseESInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public KingbaseESInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs new file mode 100644 index 00000000..6a4fd4a4 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsertOrUpdate.cs @@ -0,0 +1,57 @@ +using FreeSql.Internal; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; + +namespace FreeSql.KingbaseES +{ + + class KingbaseESInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public KingbaseESInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getInsertSql(ds.Item1, false); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2, true); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; + + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else + { + var ocdu = new KingbaseESOnConflictDoUpdate(insert.InsertIdentity()); + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); + if (_doNothing == true || cols.Any() == false) + ocdu.DoNothing(); + sql = ocdu.ToSql(); + } + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs new file mode 100644 index 00000000..e1e55dd7 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs @@ -0,0 +1,208 @@ +using FreeSql.Aop; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.KingbaseES +{ + public class KingbaseESOnConflictDoUpdate where T1 : class + { + internal KingbaseESInsert _insert; + internal KingbaseESUpdate _updatePriv; + internal KingbaseESUpdate _update => _updatePriv ?? + (_updatePriv = new KingbaseESUpdate(_insert.InternalOrm, _insert.InternalCommonUtils, _insert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } + .NoneParameter().SetSource(_insert.InternalSource) as KingbaseESUpdate); + ColumnInfo[] _columns; + bool _doNothing; + + public KingbaseESOnConflictDoUpdate(IInsert insert, Expression> columns = null) + { + _insert = insert as KingbaseESInsert; + if (_insert == null) throw new Exception("OnConflictDoUpdate 是 FreeSql.Provider.KingbaseES 特有的功能"); + if (_insert._noneParameterFlag == "c") _insert._noneParameterFlag = "cu"; + + if (columns != null) + { + var colsList = new List(); + var cols = _insert.InternalCommonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null).ToDictionary(a => a, a => true); + foreach (var col in _insert.InternalTable.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name)) + colsList.Add(col); + _columns = colsList.ToArray(); + } + if (_columns == null || _columns.Any() == false) + _columns = _insert.InternalTable.Primarys; + if (_columns.Any() == false) throw new Exception("OnConflictDoUpdate 功能要求实体类必须设置 IsPrimary 属性"); + } + + protected void ClearData() + { + _insert.InternalClearData(); + _updatePriv = null; + } + + public KingbaseESOnConflictDoUpdate IgnoreColumns(Expression> columns) + { + _update.IgnoreColumns(columns); + return this; + } + public KingbaseESOnConflictDoUpdate UpdateColumns(Expression> columns) + { + _update.UpdateColumns(columns); + return this; + } + public KingbaseESOnConflictDoUpdate IgnoreColumns(string[] columns) + { + _update.IgnoreColumns(columns); + return this; + } + public KingbaseESOnConflictDoUpdate UpdateColumns(string[] columns) + { + _update.UpdateColumns(columns); + return this; + } + + public KingbaseESOnConflictDoUpdate Set(Expression> column, TMember value) + { + _update.Set(column, value); + return this; + } + //由于表达式解析问题,ON CONFLICT("id") DO UPDATE SET 需要指定表别名,如 Set(a => a.Clicks + 1) 解析会失败 + //暂时不开放这个功能,如有需要使用 SetRaw("click = t.click + 1") 替代该操作 + //public OnConflictDoUpdate Set(Expression> exp) + //{ + // _update.Set(exp); + // return this; + //} + public KingbaseESOnConflictDoUpdate SetRaw(string sql) + { + _update.SetRaw(sql); + return this; + } + + public KingbaseESOnConflictDoUpdate DoNothing() + { + _doNothing = true; + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + sb.Append(_insert.ToSql()).Append("\r\nON CONFLICT("); + for (var a = 0; a < _columns.Length; a++) + { + if (a > 0) sb.Append(", "); + sb.Append(_insert.InternalCommonUtils.QuoteSqlName(_columns[a].Attribute.Name)); + } + if (_doNothing) + { + sb.Append(") DO NOTHING"); + } + else + { + sb.Append(") DO UPDATE SET\r\n"); + + var sbSetEmpty = _update.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _update.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_update.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _update.InternalSbSetIncr.ToString().Substring(2) : _update.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _insert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _update.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true) + { + var field = _insert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(_insert.InternalCommonUtils.QuoteSqlName(_insert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); + } + else if (_insert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _update.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _update.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _insert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = EXCLUDED.").Append(field); + } + ++colidx; + } + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_insert.InternalTable.Type, _insert.InternalTable, CurdType.Insert, sql, _insert.InternalParams); + _insert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_insert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _insert.InternalOrm.Ado.ExecuteNonQuery(_insert.InternalConnection, _insert.InternalTransaction, CommandType.Text, sql, _insert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _insert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_insert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_insert.InternalTable.Type, _insert.InternalTable, CurdType.Insert, sql, _insert.InternalParams); + _insert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_insert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _insert.InternalOrm.Ado.ExecuteNonQueryAsync(_insert.InternalConnection, _insert.InternalTransaction, CommandType.Text, sql, _insert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _insert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_insert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs new file mode 100644 index 00000000..fea0cca1 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs @@ -0,0 +1,174 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.KingbaseES +{ + + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_limit > 0) + sb.Append(" \r\nlimit ").Append(_limit); + if (_skip > 0) + sb.Append(" \r\noffset ").Append(_skip); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs new file mode 100644 index 00000000..7b4428a8 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs @@ -0,0 +1,169 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.KingbaseES +{ + + class KingbaseESUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public KingbaseESUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + internal string InternalTableAlias { get; set; } + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + var pk = _table.Primarys.First(); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(" || '+' || "); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::text"); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(" || '+' || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append("::text"); + ++pkidx; + } + sb.Append(")"); + } + + protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) + { + if (_noneParameter == false) return; + if (col.Attribute.MapType == typeof(string)) + { + sb.Append("::text"); + return; + } + var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; + if (dbtype == null) return; + + sb.Append("::").Append(dbtype); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj new file mode 100644 index 00000000..a5aab1b8 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -0,0 +1,45 @@ + + + + netstandard2.0;net461 + 1.8.0-preview0820 + true + FreeSql;ncc;YeXiangQin + FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM;人大金仓;金仓;Kdbndp + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + + + + + + + + Always + + + + + + + + + + lib\Kdbndp.dll + false + + + + + ns20;netstandard20 + + + diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs new file mode 100644 index 00000000..a3f33988 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs @@ -0,0 +1,78 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using Kdbndp; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data.Common; +using System.Text; +using System.Threading; + +namespace FreeSql.KingbaseES +{ + class KingbaseESAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + public KingbaseESAdo() : base(DataType.KingbaseES, null, null) { } + public KingbaseESAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.KingbaseES, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + MasterPool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.KingbaseES, connectionFactory); + return; + } + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new KingbaseESConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new KingbaseESConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is bool || param is bool?) + return (bool)param ? "'t'" : "'f'"; + else if (param is string) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + protected override DbCommand CreateCommand() + { + return new KdbndpCommand(); + } + + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + var rawPool = pool as KingbaseESConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESConnectionPool.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESConnectionPool.cs new file mode 100644 index 00000000..44e2b2e9 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESConnectionPool.cs @@ -0,0 +1,258 @@ +using FreeSql.Internal.ObjectPool; +using Kdbndp; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.KingbaseES +{ + + class KingbaseESConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + internal string UserId { get; set; } + + public KingbaseESConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + this.UserId = KingbaseESConnectionPool.GetUserId(connectionString); + + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + var policy = new KingbaseESConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + } + + public static string GetUserId(string connectionString) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + return userIdMatch.Groups[2].Value.Trim().ToUpper(); + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is KdbndpException) + { + + if (exception is System.IO.IOException) + { + + base.SetUnavailable(exception); + + } + else if (obj.Value.Ping() == false) + { + + base.SetUnavailable(exception); + } + } + base.Return(obj, isRecreate); + } + } + + class KingbaseESConnectionPoolPolicy : IPolicy + { + + internal KingbaseESConnectionPool _pool; + public string Name { get; set; } = "KingbaseES KdbndpConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"MaxPoolSize={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};MaxPoolSize={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new KdbndpConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + if (obj.State != ConnectionState.Closed) obj.Close(); + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select 1"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESCodeFirst.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESCodeFirst.cs new file mode 100644 index 00000000..b641c526 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESCodeFirst.cs @@ -0,0 +1,397 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using KdbndpTypes; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; + +namespace FreeSql.KingbaseES +{ + + class KingbaseESCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public KingbaseESCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(sbyte).FullName, CsToDb.New(KdbndpDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(KdbndpDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(short).FullName, CsToDb.New(KdbndpDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(KdbndpDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(int).FullName, CsToDb.New(KdbndpDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(KdbndpDbType.Integer, "int4", "int4", false, true, null) }, + { typeof(long).FullName, CsToDb.New(KdbndpDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(KdbndpDbType.Bigint, "int8", "int8", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(KdbndpDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, CsToDb.New(KdbndpDbType.Smallint, "int2", "int2", false, true, null) }, + { typeof(ushort).FullName, CsToDb.New(KdbndpDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(KdbndpDbType.Integer, "int4", "int4", false, true, null) }, + { typeof(uint).FullName, CsToDb.New(KdbndpDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, CsToDb.New(KdbndpDbType.Bigint, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, CsToDb.New(KdbndpDbType.Numeric, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(KdbndpDbType.Numeric, "numeric", "numeric(20,0)", false, true, null) }, + + { typeof(float).FullName, CsToDb.New(KdbndpDbType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(KdbndpDbType.Real, "float4", "float4", false, true, null) }, + { typeof(double).FullName, CsToDb.New(KdbndpDbType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(KdbndpDbType.Double, "float8", "float8", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(KdbndpDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(KdbndpDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) }, + + { typeof(string).FullName, CsToDb.New(KdbndpDbType.Varchar, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(KdbndpDbType.Char, "bpchar", "bpchar(1) NULL", false, null, '\0') }, + + { typeof(TimeSpan).FullName, CsToDb.New(KdbndpDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(KdbndpDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(KdbndpDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(KdbndpDbType.Timestamp, "timestamp", "timestamp", false, true, null) }, + + { typeof(bool).FullName, CsToDb.New(KdbndpDbType.Bit, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(KdbndpDbType.Bit, "bool","bool", null, true, null) }, + { typeof(Byte[]).FullName, CsToDb.New(KdbndpDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) }, + + { typeof(Guid).FullName, CsToDb.New(KdbndpDbType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(KdbndpDbType.Uuid, "uuid", "uuid", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(KdbndpDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(KdbndpDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + var sb = new StringBuilder(); + var seqcols = new List>(); //序列 + + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { "PUBLIC", tbname[0] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { "PUBLIC", tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { "PUBLIC", tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } + //codefirst 不支持表名、模式名、数据库名中带 . + + if (string.Compare(tbname[0], "PUBLIC", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys_namespace where nspname={0}", tbname[0])) == null) //创建模式 + sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from sys_tables a inner join sys_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from sys_tables a inner join sys_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tboldname)) == null) + //旧表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = $"{tbname[0]}_{tbname[1]}_PKEY"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + else + { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql(@" +select +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem > 0 and t.typinput::varchar = 'ARRAY_IN' then t2.typname else t.typname end, +case when a.attnotnull then '0' else '1' end as is_nullable, +--e.adsrc, +(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid limit 1) is_identity, +a.attndims, +d.description as comment +from sys_class c +inner join sys_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join sys_type t on t.oid = a.atttypid +left join sys_type t2 on t2.oid = t.typelem +left join sys_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join sys_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join sys_namespace ns on ns.oid = c.relnamespace +inner join sys_namespace ns2 on ns2.oid = t.typnamespace +where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var attndims = int.Parse(string.Concat(a[6])); + var type = string.Concat(a[1]); + var sqlType = string.Concat(a[3]); + var max_length = long.Parse(string.Concat(a[2])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + return new + { + column = string.Concat(a[0]), + sqlType = string.Concat(sqlType), + max_length = long.Parse(string.Concat(a[2])), + is_nullable = string.Concat(a[4]) == "1", + is_identity = string.Concat(a[5]).StartsWith(@"NEXTVAL('") && (string.Concat(a[5]).EndsWith(@"'::REGCLASS)") || string.Concat(a[5]).EndsWith(@"')")), + attndims, + comment = string.Concat(a[7]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } + } + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (isCommentChanged) + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n"); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); + if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" +select +c.attname, +b.relname, +case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +case when indisunique = 't' then 1 else 0 end IsUnique +from sys_index a +inner join sys_class b on b.oid = a.indexrelid +inner join sys_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_class d on d.oid = a.indrelid +where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select +d.description +from sys_class a +inner join sys_namespace b on b.oid = a.relnamespace +left join sys_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('SYS_CATALOG', 'INFORMATION_SCHEMA', 'TOPOLOGY', 'SYSAUDIT', 'SYSLOGICAL', 'SYS_TEMP_1', 'SYS_TOAST', 'SYS_TOAST_TEMP_1', 'XLOG_RECORD_READ') and a.relkind in ('r') and b.nspname = {0} and a.relname = {1} +and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS')", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select sys_constraint.conname as pk_name from sys_constraint +inner join sys_class on sys_constraint.conrelid = sys_class.oid +inner join sys_namespace on sys_namespace.oid = sys_class.relnamespace +where sys_namespace.nspname={0} and sys_class.relname={1} and sys_constraint.contype='p' +", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"coalesce({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + sb.Append(insertvalue).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_seq").ToUpper(); ; + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); + sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); + if (seqcol.Item3) + { + sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT NEXTVAL('").Append(seqname).Append("'::REGCLASS);\r\n"); + sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); + } + } + return sb.Length == 0 ? null : sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs new file mode 100644 index 00000000..bf079acd --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESDbFirst.cs @@ -0,0 +1,524 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using KdbndpTypes; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.KingbaseES +{ + class KingbaseESDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public KingbaseESDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + KdbndpDbType GetSqlDbType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + var isarray = dbtype.EndsWith("[]"); + if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); + var ret = KdbndpDbType.Unknown; + switch (dbtype.ToLower().TrimStart('_')) + { + case "tinyint": ret = KdbndpDbType.Smallint; break; + case "int2": ret = KdbndpDbType.Smallint; break; + case "int4": ret = KdbndpDbType.Integer; break; + case "int8": ret = KdbndpDbType.Bigint; break; + case "numeric": ret = KdbndpDbType.Numeric; break; + case "float4": ret = KdbndpDbType.Real; break; + case "float8": ret = KdbndpDbType.Double; break; + case "money": ret = KdbndpDbType.Money; break; + + case "char": ret = column.MaxLength == 36 ? KdbndpDbType.Uuid : KdbndpDbType.Char; break; + case "bpchar": ret = KdbndpDbType.Char; break; + case "varchar": ret = KdbndpDbType.Varchar; break; + case "text": ret = KdbndpDbType.Text; break; + + case "timestamp": ret = KdbndpDbType.Timestamp; break; + case "timestamptz": ret = KdbndpDbType.Timestamp; break; + case "date": ret = KdbndpDbType.Date; break; + case "time": ret = KdbndpDbType.Time; break; + case "timetz": ret = KdbndpDbType.Time; break; + case "interval": ret = KdbndpDbType.Time; break; + + case "bool": ret = KdbndpDbType.Bit; break; + case "blob": ret = KdbndpDbType.Bytea; break; + case "bytea": ret = KdbndpDbType.Bytea; break; + case "bit": ret = KdbndpDbType.Bit; break; + case "varbit": ret = KdbndpDbType.Varbit; break; + + case "uuid": ret = KdbndpDbType.Uuid; break; + } + return ret; + } + + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(); + static KingbaseESDbFirst() + { + var defaultDbToCs = new Dictionary() { + { (int)KdbndpDbType.Smallint, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(int), typeof(int?), "{0}.Value", "GetInt16") }, + { (int)KdbndpDbType.Integer, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(long), typeof(long?), "{0}.Value", "GetInt32") }, + { (int)KdbndpDbType.Bigint, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)KdbndpDbType.Real, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)KdbndpDbType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)KdbndpDbType.Numeric, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { (int)KdbndpDbType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)KdbndpDbType.Varchar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)KdbndpDbType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)KdbndpDbType.Timestamp, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)KdbndpDbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)KdbndpDbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + + { (int)KdbndpDbType.Bit, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)KdbndpDbType.Bytea, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)KdbndpDbType.Uuid, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select datname from sys_database where datname not in ('TEMPLATE1', 'TEMPLATE0', 'TEMPLATE2')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from sys_tables a inner join sys_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { olddatabase }; + } + + var tables = new List(); + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = $@" +{(tbname == null ? "" : $"select * from (")}select +b.nspname || '.' || a.tablename, +a.schemaname, +a.tablename , +d.description, +'TABLE' +from sys_tables a +inner join sys_namespace b on b.nspname = a.schemaname +inner join sys_class c on c.relnamespace = b.oid and c.relname = a.tablename +left join sys_description d on d.objoid = c.oid and objsubid = 0 +where a.schemaname not in ('SYS_CATALOG', 'INFORMATION_SCHEMA', 'TOPOLOGY', 'SYSAUDIT', 'SYSLOGICAL', 'SYS_TEMP_1', 'SYS_TOAST', 'SYS_TOAST_TEMP_1', 'XLOG_RECORD_READ') +and b.nspname || '.' || a.tablename not in ('PUBLIC.SPATIAL_REF_SYS') + +union all + +select +b.nspname || '.' || a.relname, +b.nspname, +a.relname, +d.description, +'VIEW' +from sys_class a +inner join sys_namespace b on b.oid = a.relnamespace +left join sys_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('SYS_CATALOG', 'INFORMATION_SCHEMA', 'TOPOLOGY', 'SYSAUDIT', 'SYSLOGICAL', 'SYS_TEMP_1', 'SYS_TOAST', 'SYS_TOAST_TEMP_1', 'XLOG_RECORD_READ') and a.relkind in ('m','v') +and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS') +{(tbname == null ? "" : $") ft_dbf where {(ignoreCase ? "lower(schemaname)" : "schemaname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(tablename)" : "tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = $@" +select +ns.nspname || '.' || c.relname as id, +a.attname, +t.typname, +case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, +case when t.typelem = 0 then t.typname else t2.typname end, +case when a.attnotnull then 0 else 1 end as is_nullable, +--e.adsrc as is_identity, pg12以下 +(select sys_get_expr(adbin, adrelid) from sys_attrdef where adrelid = e.adrelid and adnum = e.adnum limit 1) is_identity, +d.description as comment, +a.attndims, +case when t.typelem = 0 then t.typtype else t2.typtype end, +ns2.nspname, +a.attnum +from sys_class c +inner join sys_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join sys_type t on t.oid = a.atttypid +left join sys_type t2 on t2.oid = t.typelem +left join sys_description d on d.objoid = a.attrelid and d.objsubid = a.attnum +left join sys_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum +inner join sys_namespace ns on ns.oid = c.relnamespace +inner join sys_namespace ns2 on ns2.oid = t.typnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")}"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var position = 0; + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var type = string.Concat(row[2]); + var max_length = int.Parse(string.Concat(row[3])); + var sqlType = string.Concat(row[4]); + var is_nullable = string.Concat(row[5]) == "1"; + var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && (string.Concat(row[6]).EndsWith(@"'::REGCLASS)") || string.Concat(row[6]).EndsWith(@"')")); + var comment = string.Concat(row[7]); + var defaultValue = string.Concat(row[6]); + int attndims = int.Parse(string.Concat(row[8])); + string typtype = string.Concat(row[9]); + string owner = string.Concat(row[10]); + int attnum = int.Parse(string.Concat(row[11])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (max_length <= 0) max_length = -1; + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + if (max_length > 0) + { + switch (sqlType.ToLower()) + { + //case "numeric": sqlType += $"({max_length})"; break; + case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; + } + } + if (attndims > 0) type += "[]"; + + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Coment = comment, + DefaultValue = defaultValue, + Position = ++position + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } + + sql = $@" +select +ns.nspname || '.' || d.relname as table_id, +c.attname, +b.relname as index_id, +case when a.indisunique then 1 else 0 end IsUnique, +case when a.indisprimary then 1 else 0 end IsPrimary, +case when a.indisclustered then 0 else 1 end IsClustered, +case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc, +a.indkey::text, +c.attnum +from sys_index a +inner join sys_class b on b.oid = a.indexrelid +inner join sys_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_class d on d.oid = a.indrelid +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var index_id = string.Concat(row[2]); + var is_unique = string.Concat(row[3]) == "1"; + var is_primary_key = string.Concat(row[4]) == "1"; + var is_clustered = string.Concat(row[5]) == "1"; + var is_desc = string.Concat(row[6]) == "1"; + var inkey = string.Concat(row[7]).Split(' '); + var attnum = int.Parse(string.Concat(row[8])); + attnum = int.Parse(inkey[attnum - 1]); + foreach (string tc in loc3[object_id].Keys) + { + if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) + { + column = tc; + break; + } + } + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + var loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } + + if (tbname == null) + { + sql = $@" +select +ns.nspname || '.' || b.relname as table_id, +array(select attname from sys_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, +a.conname as FKId, +ns2.nspname || '.' || c.relname as ref_table_id, +1 as IsForeignKey, +array(select attname from sys_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, +null ref_sln, +null ref_table +from sys_constraint a +inner join sys_class b on b.oid = a.conrelid +inner join sys_class c on c.oid = a.confrelid +inner join sys_namespace ns on ns.oid = b.relnamespace +inner join sys_namespace ns2 on ns2.oid = c.relnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + } + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } + + public class GetEnumsByDatabaseQueryInfo + { + public string name { get; set; } + public string label { get; set; } + } + public List GetEnumsByDatabase(params string[] database) + { + if (database == null || database.Length == 0) return new List(); + var drs = _orm.Ado.Query(CommandType.Text, _commonUtils.FormatSql(@" +select +ns.nspname || '.' || a.typname AS name, +b.enumlabel AS label +from sys_type a +inner join sys_enum b on b.enumtypid = a.oid +inner join sys_namespace ns on ns.oid = a.typnamespace +where a.typtype = 'e' and ns.nspname in (SELECT schema_name FROM information_schema.schemata where catalog_name in {0})", database)); + var ret = new Dictionary>(); + foreach (var dr in drs) + { + if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); + var key = dr.label; + if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) + key = $"Unkown{ret[dr.name].Count + 1}"; + if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); + } + return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs new file mode 100644 index 00000000..13f2b195 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs @@ -0,0 +1,622 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.KingbaseES +{ + class KingbaseESExpression : CommonExpression + { + + public KingbaseESExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(operandExp)})::int2"; + case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(operandExp)})::timestamp"; + case "System.Decimal": return $"({getExp(operandExp)})::numeric"; + case "System.Double": return $"({getExp(operandExp)})::float8"; + case "System.Int16": return $"({getExp(operandExp)})::int2"; + case "System.Int32": return $"({getExp(operandExp)})::int4"; + case "System.Int64": return $"({getExp(operandExp)})::int8"; + case "System.SByte": return $"({getExp(operandExp)})::int2"; + case "System.Single": return $"({getExp(operandExp)})::float4"; + case "System.String": return $"({getExp(operandExp)})::text"; + case "System.UInt16": return $"({getExp(operandExp)})::int2"; + case "System.UInt32": return $"({getExp(operandExp)})::int4"; + case "System.UInt64": return $"({getExp(operandExp)})::int8"; + case "System.Guid": return $"({getExp(operandExp)})::uuid"; + } + } + break; + case ExpressionType.ArrayLength: + var arrOperExp = getExp((exp as UnaryExpression).Operand); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; + case "System.DateTime": return $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; + case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; + case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; + case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid"; + } + break; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + string left = null; + if (objType.FullName == typeof(Dictionary).FullName) + { + left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "Contains": + var right = getExp(callExp.Arguments[argIndex]); + return $"({left} @> ({right}))"; + case "ContainsKey": return $"({left} ? {getExp(callExp.Arguments[argIndex])})"; + case "Concat": return $"({left} || {getExp(callExp.Arguments[argIndex])})"; + case "GetLength": + case "GetLongLength": + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + switch (callExp.Method.Name) + { + case "Any": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; + case "Contains": + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + //判断 in 或 array @> array + if (left.StartsWith("array[") || left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + args1 = $"array[{args1}]"; + if (objExp != null) + { + var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); + if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; + } + return $"({left} @> {args1})"; + case "Concat": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + var right2 = getExp(callExp.Arguments[argIndex]); + if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; + return $"({left} || {right2})"; + case "GetLength": + case "GetLongLength": + case "Length": + case "Count": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + break; + case ExpressionType.MemberAccess: + var memExp = exp as MemberExpression; + var memParentExp = memExp.Expression?.Type; + if (memParentExp?.FullName == "System.Byte[]") return null; + if (memParentExp != null) + { + if (memParentExp.IsArray == true) + { + var left = getExp(memExp.Expression); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + switch (memExp.Member.Name) + { + case "Length": + case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("array["); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append("]").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "current_date"; + case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; + case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"({left})::date"; + case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)"; + case "DayOfWeek": return $"extract(dow from ({left})::timestamp)"; + case "Day": return $"extract(day from ({left})::timestamp)"; + case "DayOfYear": return $"extract(doy from ({left})::timestamp)"; + case "Month": return $"extract(month from ({left})::timestamp)"; + case "Year": return $"extract(year from ({left})::timestamp)"; + case "Hour": return $"extract(hour from ({left})::timestamp)"; + case "Minute": return $"extract(minute from ({left})::timestamp)"; + case "Second": return $"extract(second from ({left})::timestamp)"; + case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)"; + case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)"; + case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)"; + case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)"; + case "Seconds": return $"(floor(({left})/1000000)::int8%60)"; + case "Ticks": return $"(({left})*10)"; + case "TotalDays": return $"(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left})/1000)"; + case "TotalMinutes": return $"(({left})/{(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left})/1000000)"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'"; + return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'"; + }).ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + var likeOpt = "LIKE"; + if (exp.Arguments.Count > 1) + { + if (exp.Arguments[1].Type == typeof(bool) || + exp.Arguments[1].Type == typeof(StringComparison)) likeOpt = "ILIKE"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::text || '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::text)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": + if (exp.Arguments.Count > 1) return $"log({getExp(exp.Arguments[1])},{getExp(exp.Arguments[0])})"; + return $"log(2.7182818284590451,{getExp(exp.Arguments[0])})"; + case "Log10": return $"log({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)"; + case "DaysInMonth": return $"extract(day from ({getExp(exp.Arguments[0])} || '-' || {getExp(exp.Arguments[1])} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)"; + case "Equals": return $"(({getExp(exp.Arguments[0])})::timestamp = ({getExp(exp.Arguments[1])})::timestamp)"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; + + case "Parse": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::timestamp"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"(({left})::timestamp+((({args1})/1000)||' milliseconds')::interval)"; + case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; + case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; + case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; + case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)"; + case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)"; + case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)"; + case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; + case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; + case "System.TimeSpan": return $"(({left})::timestamp-((({args1})/1000)||' milliseconds')::interval)"; + } + break; + case "Equals": return $"({left} = ({args1})::timestamp)"; + case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; + case "ToString": + if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + } + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"({left})::varchar"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; + case "ToDateTime": return $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; + case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; + case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; + case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; + case "ToString": return $"({getExp(exp.Arguments[0])})::text"; + case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExtensions.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExtensions.cs new file mode 100644 index 00000000..be34f19b --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExtensions.cs @@ -0,0 +1,12 @@ +public static partial class FreeSqlKingbaseESGlobalExtensions +{ + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatKingbaseES(this string that, params object[] args) => _kingbaseesAdo.Addslashes(that, args); + static FreeSql.KingbaseES.KingbaseESAdo _kingbaseesAdo = new FreeSql.KingbaseES.KingbaseESAdo(); +} diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESProvider.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESProvider.cs new file mode 100644 index 00000000..c91f9507 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESProvider.cs @@ -0,0 +1,60 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.KingbaseES +{ + + public class KingbaseESProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new KingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new KingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new KingbaseESInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new KingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new KingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new KingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new KingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new KingbaseESInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public KingbaseESProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new KingbaseESUtils(this); + this.InternalCommonExpression = new KingbaseESExpression(this.InternalCommonUtils); + + this.Ado = new KingbaseESAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new KingbaseESDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new KingbaseESCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + + ~KingbaseESProvider() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESUtils.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESUtils.cs new file mode 100644 index 00000000..91bc9f92 --- /dev/null +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESUtils.cs @@ -0,0 +1,163 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using Kdbndp; +using KdbndpTypes; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace FreeSql.KingbaseES +{ + + class KingbaseESUtils : CommonUtils + { + public KingbaseESUtils(IFreeSql orm) : base(orm) + { + } + + static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) + { + var valueArr = value as Array; + var len = valueArr.GetLength(0); + var ret = Array.CreateInstance(arrayType, len); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); + } + return ret; + } + static Dictionary> dicGetParamterValue = new Dictionary> { + { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, + { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, + { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, + { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() }, + }; + static object getParamterValue(Type type, object value, int level = 0) + { + if (type.FullName == "System.Byte[]") return value; + if (type.IsArray && level == 0) + { + var elementType = type.GetElementType(); + Type enumType = null; + if (elementType.IsEnum) enumType = elementType; + else if (elementType.IsNullableType()) + { + var genericTypesFirst = elementType.GetGenericArguments().First(); + if (genericTypesFirst.IsEnum) enumType = genericTypesFirst; + } + if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()); + return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; + } + if (type.IsNullableType()) type = type.GetGenericArguments().First(); + if (type.IsEnum) return (int)value; + if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); + return value; + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value != null) value = getParamterValue(type, value); + var ret = new KdbndpParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.KdbndpDbType = (KdbndpDbType)tp.Value; + //} + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value != null) value = getParamterValue(type, value); + var ret = new KdbndpParameter { ParameterName = $"@{name.ToUpper()}", Value = value }; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.KdbndpDbType = (KdbndpDbType)tp.Value; + //} + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatKingbaseES(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); + public override string QuoteParamterName(string name) => $"@{name.ToUpper()}"; + public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs.Select((a, b) => b == 0 ? $"{a}::text" : a))}"; //First ::text + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "current_timestamp"; + public override string NowUtc => "(current_timestamp at time zone 'UTC')"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + value = getParamterValue(type, value); + var type2 = value.GetType(); + if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; + if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; + } + else if (value is Array) + { + var valueArr = value as Array; + var eleType = type2.GetElementType(); + var len = valueArr.GetLength(0); + var sb = new StringBuilder().Append("ARRAY["); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + if (a > 0) sb.Append(","); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); + } + sb.Append("]"); + var dbinfo = _orm.CodeFirst.GetDbInfo(type); + if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype); + return sb.ToString(); + } + else if (dicGetParamterValue.ContainsKey(type2.FullName)) + { + value = string.Concat(value); + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.KingbaseES/key.snk b/Providers/FreeSql.Provider.KingbaseES/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..be1149357b2060cb16aa173fa54ed5712e14d886 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098e+`w>!pw~z{kC)(11aic*UA-FJmj*Dw%pGP3~em+rOVqNP@MPQ<0SE0Jw z18wO2D&7?q5r~)y-xHI!=Z`X~3NABfxO*Rt(RKB5xZ1m4DrJj|kVnrZK!68?r~F(^ zF8&@B#vuvJ#~ISY*N$A>FP8GV$Gww<4lAIG`fLSf8o=U$8Q2V1Dw!uRoO@@IXo{{& zGRd>cseR-YBR9`Y3Sh=ZL3z~q?`Grcb>lHDLxwW3}jwu`6-eT*nfH1(XM}Q}C z10NXPe~;ciLC3eO6W_Y0G5RRIAI`cz)T{=Wk%f7<+bDoBRp}Jl!>1+*GaI5un*m5A zkcb_mp6S*!@b5a)>R_yLok1277f`x;0vtz@?PY`FIKqT%3pJ(P8dH+sTWP4`7ovcs zP!O_$q&X`AkNRQULp(?74(v}<+FqM*HT3bo-qLW6n9X*AD6e%;#Z)6<@>~y2hlubU z`Y}D>OQ(AcS4{b1_FAgVBYrD+k!dUgJF0}jGb`A|sl|+^Ai@M&x=dhq`GiOJT&(@p zSnV_FdZQ_y4H|c{MA$s3-uJ>b`BkX%wA!qSd{u8a`l*9Q;gOChlC^WMd@Ts92&B^Q iBbsxrKxd~B8LVo7`w{*T8NJ6Jg9$1yt#;1QpFdUzz91$5 literal 0 HcmV?d00001 diff --git a/Providers/FreeSql.Provider.KingbaseES/lib/Kdbndp.dll b/Providers/FreeSql.Provider.KingbaseES/lib/Kdbndp.dll new file mode 100644 index 0000000000000000000000000000000000000000..af774bbe0f7706374301fc4cb6f1718f13bfa0a4 GIT binary patch literal 732672 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

b_^-pZms9n#W6{fj#ZYIP{y?jSid3 zrUg&2Wn9J-YTsq;QfTvBwvEeOa#~a$djoT++Zd^HtL29GL^+=d<=z&~MEkg8e+`}J zw)f89;;eOnJPT+2Jv7%{jk_Coj0yfW(ILxXNaLgk zl4kd};!KJmO~ELGY!O4UjL8*eml)ElnLi*OjUlbt3kPJ}svvj`8|6fDLEQs6;WBS8 zf}oCoJcaGK@v9zZbA!B^fD{e#asootkm~USWR^kBA?GNcE`z)`j#vt zle=2CHpu?)RH@En)=ZEw9D|SYnG!;Njs5F6PYo7ZoS(*VI(4dmR9}hXbOyV?&M|x? z$4BL#g%=+Pnl~O3T=9h+_?PLzV@v z1348)7q+$Ivo2u229VRAjvy@!GgHEF*(naex^C!BT?OPIw3AW^qI=WE1b>A;o=

z-cXA(*B}Qz?2z}6Y5}cgOfd0shnyIk z({QuJxt{*ax$)VC?;7NVm_O$OQSH1-E%>R0mcgWj*DoZf=;Gnq+bAyU!uFHOx=-8f1@g4!N}9eW}kGr3MG75aAfKbgG>pzx-2+0b(lf+ z4Que|hGSF9GU9v%n?XFRG#sBg-s1Gcsm@5PHpmfSsz(~mNL^{ApL$G$;aRC`4AL5N z{*u&BGgqNM{`joNVcjD2P)4*Ld}fsD($p`21i>3I6_=)dX=VK)ru~Z4uQQVQgW|S) zedu^okYa})e`)6JTz(!% zrLs!(*w_feAEp|!>MNhP+99j>0(g_f`FV`cl>4Y(}$WooR&`TUctzFZUV zh5BEn#sOh{CWbtfnwJ%Ssv(4PQmMsg!ZATJnnbCV0ogUHS{~1vLtaQ7kUjPPqwYVT ztSXj1Zn*Y7XU?1%GDuPojvx|5K$4<}8B|mTbOgkJGJp|8k_vi8V3Z^xK_rPvP(T4e zf|5a^0*VSK86=1Sl`P2jud43eXNJM+{hs@-^}ek2Jl6f~>gww1?&{vX_t^uT{I6N^ zi~q3H)pfX%F7%uKl#oUEGivSNcPsyhAD6nOqg_n!?E$}+khKXUD|sBQyokJEb^3}w zFE3N_2}<=#<_s{yl*$6>FXWvIRp&K2>5md}@i$5`K*kH1X#B~bQ~swy4q$$%ho}4n zLcTDToBOByB|;`4YhC&WRucb=|E>5_3Z9gG4cMuwUJ%rDlWVjdCDBBjn2R-M;CE{Jjuc0jwhE^Ng@ zB}Hew@o*u?g+hKdI!o~!u(Xis#_|e~GD7Y|sGT9AMM@U)Y;buQ6 zbd`8`yYny-!b_oO#ZKd47DYl0#lwou!<0~C(V5^pObOj7b|R*BoZg4hMCYWllNxF& zWVI`mFLYm&N5bpIpXPr45YImBdrhh3Ag!d-N2V3OQi0GDLVB1|e}FtCr8*a}EiD*& zMo2r;U&p9m=vgV1$Fy{_UpSN{=X z4nDtPbaqpz&?F%pjfaK3(xJ&h+89y{j07f~K%NlN(pc^a(m_a7Q|ft;XN4?*&eibeMUZYnWNE;% z6`gm+Skfw#H1jypRZCtrWZh6p1{$)c zuO+h$p;?y9H)Q8bOO_cj&G_7hRvNO()wR};YS=?^OZ(79Ll!tYTMfCPqt)5T1btD> zkPO;m$oF+rhe<_513N416Eud$LzPnFD0TQNOU{OBrSi_9Lq1C=Twg3taeYDI20~gH ze_Hrn_(mzU4*sg;%fk4H7A#lBy+gm++@}@815-I0`?$|#vcRtr9x7xl_G9~S0+m5E z!mEUQm_XJFxoI8Va>hO(gRTsJC6-@;&rC{%Ylk)|GSby`WB9Q6Q@=lE7XH zW-Mo*{sN*i!09v#m&wDe_@NUbvYTiF-4l)p+0#|YH*|lvhL8%KEqO3pSIDnjENLCS zUP!fPEol?JMaWK9s$KXlAy>LmPlQ_tscCdJ&{JW210VjBF?Kdkr!YS54KmGH?i%hQ zWRbJ;T(~<3PUcK2zM&VxFNsdSZtBkl{MCXiAz!(64Gi}a^0*_fg$D^a{fuqJ;P4P3 z-CQe%gh%9w!=Do*W}@xS+u{F>O&L5Uy9D>rmhT{Wyl;;R|d@vZxo#& zrllD)C;Xj|SDnt>@D_>cv4Pf~&%%2}XN`&2-tfZk&q9tTkl%#7nLz#!@`LkdVfd(! zSB%a#v?zQ^$ThC*i^FGy^l@ZKIGmTt7NiEIR0h5tnw*!%;dp2Hn{X8&f4lg68@@uw zTGy`c!dD8p!L@x;xVDg%uCC4DtMYQDt?NeAmT>*NeBaa@>yGx$w(u>`A=+4t$2s@c z{_w+jLm-`z6Zl^rIvZ}CgM^Y==k?+95uB6oztxn&1f_;Nrlb!@J0ZtUTT&1t6}5MJ zS;;Vbp{rfqPz>klS1HM$5=mWikPDNZL+u4=RXJPgqNE;qi-LUih9$A27e%LH)Y`c; zDO1RO1uUtM)JsVH;+9;N)JMquS6Dk0lU@<>DO$q+GN^7+-@N=L;c?zM2&tFUKZl3c zCk>NQnYf=)otu*00wKC=h>||kFlkhdQjM9Q6+^MCaLA}mOPU5 zfskJ+S@J~E6d^BFvEbvptb<%G_ z-gWWWob)>4cC!!%8yfNYW`Gce|(_O*$>4nQwJM zk-vqMlrt8-OG=JVJ{}1*U7YdBX(68Lul$jakkVyr?H5Iog#6-KaY-aOACB;7ZXwkv z=~s%R2pOM1^5yFTow0?jKb0bd^7TUPV>ViHd8Dw`<;L?Bkzzs$US?~r9w{NDrqj7P za$&ygbNQM`DbdMa)t0IsDI;X0YsHO`n2^>^r(vX=kS|=j?u=Y2WWhz&PP52mLTX=Q zNy|tjAw^9~htWfkDnh23%r=bLMXCxR*E^jf)r5R@xwZ3rq=t|K$lLsH7{wzsgyBsEEOGU#xmr;weF9F4pr z{~V-D@{oL- zZGL}VJ;am8#D>^zjbTy)kt4_ha%l-yF@S$-^ewdmw`mLE(0Qpk$19SP4Q zuLnu=r&ID*qSL_5rcTM<3Tfi}c|Lhl4u9gwTad>JQWj1)`CkUToV-;^{pf1%mAp;J zC^x$YB<~PX)n$n{l6MKI;7YxnyhliTSNr7TABC*dsxS+tCm#?}(T&4-$v+7h>g+5} z{#i@8h^9=$|JeV50^Mav5rQ`z>{d(jF) z$hBfhw4#vpZg)B}S~-WEInm2OaN_vA+9~NTj9wvRU;?=^KkuXX-7o%^K?|dG#Li|n z>Xt?83aRKKwmy2bkYFVI5WPl7+_hqVw7!te`K{%H(FXamujYrMH;YcPTk(I5HWKoe zD|I+}yO6-2-=mF%oObKi$>?4Ai(rg3#3?cV8%AfNO++UcQQ?#{A>X*j=S^vrL+65& zdvoZNO1V$S3^xwTr?e1~*NwxfDfbK6?)s~C$^$|gxc;i2@{o|tZclPcN^2pvy76;o z%A-PV*MOlF_oieB3F7=fN;@Gd-Rh8$@>q_jKArM}=nQl7t7FR3`T34x@!x7XgSw}5 z6w(Rjb^I@bo=bU4NSEH0^hg<TPdH2&IUIU#-%I} z@}0Yvc_(F&kd`hdOiEcIq@nAJsVU2Z>~=euk5fJu(#e%tn6gsH56tK61nz~f&s5n!AWuvf~^(8=TKpXPWB^OFloxavQfcS)F-q zY*2$^=RwOljxtdL;c zxjNM=z-whK*NPibLqa}xc5X{e60*$Y=VqzNLOyajEmKp3@E^M2f4Fl=%_Ah))t-@> zPsj>K9#1VGq?5ZVc{;U_kV~9S*VH0H^3}JNd!!Z>vft^voLXGS^NzfdS~3UepL$Ua zGAOll4l*RQjF6yRZ>GkCw012WlUhzlLs!?ksh8#;6H_lM5Tnj_63xe+F-FxOEf(o` zW6N%FY?RY0?O0H@m19BKL5{U|W#fi<)W0>+H8`2`=mSW6Mwc6lL^{?c8ji`69#2P> z<`U`g4M(gra;}x~4YX2SBjqg1b)?4!kJH-H;}d?j(r_brw6zW1%fhPb(Tk5->2dhi zQP}ZJWidK!yo%A2{fTaZ-So+>cqYhX$#YlB1Hj$_iO4Ol99hK7K>(<&< zeqf|J)NPd2YvZJTcuz#jK5V44_*hdSEnW=m;8>-_i{q+FzwK5Qqe)n2xNMA8_rhB? z5ti8d#^MWmmFB!siEC4dYhx)b{y3gKu;s+)wnrkk7gy8c{JR2`x_xD(WjJwE_We{V zb#NuR=Cft_jeFH=fI5s7XRm#4dvz6hP_Oc@1XOz0*&9F4GXC9zUagC#`6@*m`x_&I>cSKTIZ}hK9lV7*eazstpqid|x#_9FJyQF&c^fY_*0eAI9ceS)@$F@^euafhs zl#`kwN2$F$XRK7hNyE2U))(*8s@`@Nmp>ZYs|ROTY3~XvCA3U&ojSYgP;>Or z7ho|u)x_q%?M5m`uO7trVQ^K)eJdI5;XcaJ<6M@nrpNb=wrqowHV?7vBPZQ8#=S<@ctpGt-g~MKW5nrBdxR=eWZG?VD_jq#LU(7_~jqi{BkiQy}H=sjXD&D zr;nhHI`rl!D{Wh?QjE4AvKhoXX{DM!s}+w{Awq3YwgT~d<6fvhUp}RJ9$kyMrTH{^ z48PKc9^OcAZu9A*D2u-{3U&5(C}U0B>ug! z>P23+B@Vc&{g8+B>NLmNxH{T6w$Vw?BVTEWGAFDw$ay*(E!V5R-D;&S$b`x!n6im; zl^=S}kd{wDR$(b|1^Wdfd$wFHg;=T79JQ&md$5(h!z@$Q5A#>0wE2ilx-Yh=+j9#rlzoG1pa`pZr_=~WRiqLvwi_;?g<)q&*f0Z5k%}U#yw8Tl1 zob;nBdjawgmn}qnklT5z)u8cH;1xz*q6a}nzonVBye7@rfbUpei@(o6 zJM2%-EU3ybUSuS>ix_` z@LsH(#k;ARZCgTW1Qw&;{=^qnL~4)Bb+71+dK%dqQVn@qxs6D6icjq1zqcWa5n`Id>%-U(&X;}0LT zQU%1BnMc)J#BUj|Bgdm*Mhek|uHWq3szGo5q_fPUG9Tl2(_*Cr=9c<=K&1Thu?C2=yg5dgUWGIaQVj}2 zZ=^^+K8Y_Mi&Px3|48({LDV!ZcNt$iDm}=yvd+s^T92}-SE`4V!f`8o0xR0K$&)NQ ziFu?Yu6ox>*YvT{wvPC!j(AWR*-XoJM>|wHjHsz}7CU{FUhQeiJ~qo#a0!fbFedjei?`v{F16I1|6F zlzQz9h|vbOy4W!pqrqlOdej$Jzml>&9VOLxc>2|ORkUa6Nib(lUqPj?jp24rHM6U&Up`J)JA*IB) zgw3ZOHN@JZW3o)Tm3AWUDqC@n&Y5iE>NcEjz+QU%c9d1=eT-O@G9639OjdTUW2KNg zmGPd2CAHiNu}P0}_U7JCkAI7vQE9%D;>bhH5`8K9A<@m^OC=|jTcZs52KoLrT=nQ0 zcyJe_BDA7AvNWU`v;{NtLAlx|!)As?kaV2dU4}=GV?W+r^kNU&xD3X;)Cj!*_LN+` z3sLJP(nDaGB5i@xU!>uXhKY0p(%X-#U>VK4IIt0=@qom@jWZ{2*7SkHh?c6wH9cKI-~65qp&$f6Yl1v2H1=fc=n4 z2Vj{ck9gOjb8!DJ_?4Bg{_T_nb=08(*l+xStA!~4E}g%)qpzuYY4P$#Dn~YI9zA-W zwR|P=Mh}_i6A)vK!C}OJ?_pz954ltO*X|iY^a7&6EJQ_?X^9ZMdI%@g@E}Gnp)b|v zPm!;9y^PTwj2xAI$9U1a@dw(*qurzV&snJ@;>Tq}^mZ10jRSijS`R6TxgMexFWS+$ z39K-fN1HM&%ZGf$naiVm%`7{LnXK&crue4a6?}Cg=Kgz^v$Q;oWFPBM7OrY5--ge{ z#d2fgvq!xkl@c}yQB%Ek(Boa7M^D^~7UF7*GO=fBd2@g8hcJaW9mU*~51eA=@u@O~KgJab?G|M?*16bT2gp@#A|skM4$7d@kjYJ)w%x9E=x@>GBnJHf}#lbe%*u zSP_GJ4I8x>eLEe|gx{c~JAvT?z;M>^Vw+Xw}5iP2K*C>o)T5ba%RTUiMa zx)Ut72zm5A#wgE#LiE!TwOok0&C+NTqW(q-d=4b6QTy;49%=byZEWvf4_i7W4`Li> zO#7!>X`RdHJzH3I6lGQKThr5+Gg!s7k0v@RQD^0M%nvP5xtW!c?y=HCj>R1N+?9CN zvA#}P0uNfD9awul)itFC-GH{WmbU$Wr5!Q40~w?pd~OyeGXrYS0j$%Ua|%&DjQb~X zwGcgl$C@177;(1cU0RHWnf?e7pOkZSLo|1Vj`0xPwA=Pa=X89TLE_TY^f|KQt#$?! zL`}N;n*FfeBi5j@KdO|t_N>C{!dBAbjh)oONqe32iIJM<;95VdnGn4!~fI`bN?1|z#!{5L#b(6UebOf*>REkLdt1t~3_ zyu(_a*+XL$qrY&c#5p!bbw4H=CnbV4z9_N?k1&r`nzNvq^cvza0W3s6_0{zwL>cc9 zO&7huKfd4RyV)4csBg#krLdyA@aAsCv6&`lM_PQ{G3#ky&+hMI^z#F{_P}yY{00m4 z#%NF$&ZR{99MTsey~`_|NR9eo-5066kvw|rL9HXGw+8jZNc>&&jw8z-gM?k>7VFE& zKKPQWTy20llDl!e_d+TnQUOS1AR*VenOqD#&Fe4DJ29>i zL#jj1-$67Q5>5wO;rWM1T_NeZ|1S2xlY~u3$MXP@-hT+^{30!JQeCVSvxPNr(l>YF z>`>TYC*9T*Sx;CyC(V0Qcds7pXkn!#PC5gLR}GI!!WWeeWmvrsatZHLJz9vXx*sYE z50w3h-KL(3&%zvEj(TxE9G7qQp*vv@C%7M} zlz4SA&XKr}a8}Ssdn-L&2Rr4Xt#hk(Ju6v{J@qE5&}WQhg_7 zAxp94L|;ar-XF!6VmNVCsoZmx6{)LIVhMbUg?^F}t5@T!N~C#CYK!@ytax`T;oC8W z?eA?_f5brbDmlIT(KcpUn?`(i4V@L~@tIC)=A?Di?bSn0>hGjyE845goRoH%WvPxm z<5*QE-HWltvoSq>1IC(4c^x}Z*0L^+wGQ;0e>Xc{Iy*MivFeVscWjvR;9wbB#{$O+ zxqA0Hc9mmSxE4L=*qe^^a%_=fQykmp*w>C#cWo+{M{O$QDQcy^G0&MLTH)`e9uX`1o%ExT5V#^saYO9U~>$%bbg|P0{P?q^8Il${ui1H+S_G$Lbg<(Oy3=&g1EE_Ee=`ob;=^ zddRVFoOIMlJB^fRc|2mpYe0JZb;L@g6NnH?iF%8$i{TX_J-!UJu@oYF6^TNab0M0B zcH|SO@CDcvh}8HZD@}l9Wpkah26ZUg<)i}WL1lZ(TWKq5)3b+KPAa*>vbV5ya~=;- z)!LeiLv)9ertQTkj`&gvV<;vPVUJl;q#FmT&oNrF8}GD%;W^s|wTyf0Id(l?=2&yb z-o3}JF84LGQZYn>SDYer1n-0BieuN%wD@CKS9#@3i?5z-Esq&zYn$k#DQ4$^ui>?` zdXKt#J7FK8C-nT3f}c%z_<<_Ucg6c1Z&>M9BgN>a2{`kWs~h`i2FCv0+564ik={{2 zeTh+x;?}EA(I485cd;_D6r-Vt#$96XKpouiic|(GldiRQW!jy>C;RXnAGvzNWPM`i zQScmW;8nK7O)h>@4%_y=;G~Ww25IrGsEv1I9`%FtfLLzr*i}v%fk>(^zul%%9U53u zpMS(?)(VW0F5C`#1{$L+$SPXG?)h;Bg`I-#B5OP8E9`>WO1(wzv#kv7adxJul^6|} zj$gz>FGj~9vE>*w$Bs;;f4Zvkja!MgFrQK@>G7i2Td=+K__WnlI)!#9yBTY;O1wW{ zsSr)Tj)!Y2L?5mrdREvWj6Y^YU!uATT zR-h7yEW-p zFi17UQ})lJ8(Y|j^O=$EMT0ZJzv2CGDccx*#I3}aiLoc-r{-z#z8&lxm3`J0qh_d0 z_xC+;RmWBEgrg;D<2P4=vVnyDg-6<=9kc&U*_zaPBu*y8zn~o%*yXAR*1w<*ZTSQ# zF$kV&du_|{#18G{uh0hfZ$Vj)2B7zK)^0L&c+{!+`D=?&+9$R}V+U#3z#iUb-L6;D z;tyb_#lED)kK=ApV{mo4%?!WSwGyAv>eW2x1#V?cdI}kspW@Y|2X3)am}xr79Ze?bEqvno_vXw%3f-vX-`_|1t(qOr2SLv)ktkCRYNbR zy>7LvG~G!TxT_65)T?-Ah_>l0volZQve!lEphPHm3SiIv6Q2jzCmf!<19TDk5?KXv zLFazU=30kZ{#EQ{XMYL{&Xqqh(e>!Glm6dxJ|2t%ZP5vMAER1mFVB5tXPo3C3wtyX zCrbQGI7ZJvFBvRGkKis)pF%z5q_&N1o(!^Hu;$%{^^K$J(I*ese#^cN>eWX(*e7Sf z)3l=SK%cAGQ>L2UvMaF`!Izre%<@FVM0&F->JSO9^qQ+Zo!&cntzI(5m6qLKfvBvM zsF@F6&lBlxr+0ZVe34ODDy(Q78?gheChRuM^I9TxM~SONdKw<6^i55iqYFEY5?b~z zSkc<>$*2=uU$q{sOkf0g(hf0h#U+BDSP z2c*ZVTw|rhQ?0~h8;cb#%Ti)lekZ!ET;;EjsMHSoI+a?rvuqPiCX`)2NToz8yv9Ev zR=%idrIUz(vKO2bHIhejk=r@bVDF9n+MQ^59ZE$E?t@f}s)VuXI@XrsLU#_)(G;QX z>!FPpMra{+6#T?9LYJcDymsTSwx-c+`dHQp7+devd+>=dc>^ zlj;cFu>)45wm{lF2d8hjc<_=iu8rShi_ly1^qe(9_v7stevdKHtCO(u1(-)q6(H)1 zve=`S#2J)ICG0y1Rk7ab+oaZej|yY_#gSt?+K&=HH(}|(#n`%|Y=mCD$okwJQbqB_ zdX*MG`Gn2<_PvZ4@p~D%=W1#4eT-V%WA%!eY^MD&26YspRuP=oi1cB8{LNOW_gmbt z$XY>@aIV7kB6KmvhO)XCO*vN*ey@e!q)d;m#yYK1$wpSXFWaG4cZof=vQH$QZ-=F9_OX$1`G2-&t>oaE&)d0G2vRY+u&ABW{V;oq z2|J5*P^ICRM`gi0mv=q-+k-z~8cBX%Uj3^DmiXkS;6$QprEI&Qc2>M~iUgh52 zpllFvYb6+Kcz4yc{J(GIxt4WY@tcJnWnfj)NV4U7;j^v~4?!wM$FM^18{N5kA9$Ku zJM7F$jO1Cgqm9JndGz38kRr716i(k{e~>*37Q2E7`LwVXZ=#9WV1<)vmfEO#gTrfh`XIfnO|MG8D`$|MpgWm= zXD>p_H`rBU=U=wHHZ$NJ&(+3zi-f(8#DM2aZav6<(^gxq?Xcd1!CyW1=5cx|m-zi( z%4*AVYtcRCIfQ!Uzrg-kuke;K+M)UMTg+IM&gY+wu>Zb}dKfus`C3HspX*2#|2SXe z^t2WFgYQF;MPWrH_OyVM$UY8?6=eD1IqY#y>)mV+18YTh9=Y|5wmd&h-?VIQ{@JL- zXaRO^`p)rL_r$3je9@LqKz3B=>=ZkvD>qRoLfLzZtpvRlp{B>JUiS8?e>`>r|FV}& zoP+Fr_Nx(k6L;l&ej1^Th!FdixJqWPtr*T_bTsiVJR&rBo-L6*ro6}0m`)Ih@5&eb zCpRY>c|El=_|_~+dp1G`g&nI%ZM?AX~-ND=OoSPLB1DsVAquUV!J+;csKfB|OP~ac$xOJb+J8t!l zYts`$UeDQktz$A`py#Z))uHn!dmZZif3AZwgVr$(b*MB;YMYmYHLr?g^Moz(l@+5Y zXfIzaM!%!a1HFZ!HynG`Wg?Zu`RO`HIU|0jtRxG~%9NPf?U>YzUQhHMTY)oBNQrZX zSHHzLdCvV@x$#Df94X7=UafR;nPJ>!Jf+1|ZErql$5PzmaXWH)8k`=ryxi8NtCiiG z1+y_i**)#u^jv$oS_Li7-d=v5lG94|bt^)jzk=tXa_5kJtOcHaUiH8Alvl*uBN@b* zBdM0hcGurlMJRhD`75Z!$VRdbC8Lk@E;YNS+WTy8B1&kzId=d-bhF3woo03>ABA-O z-a4OU9Ybs-XW5F?&gYBu)T8f9*xk|@>`4aQ!@eZpTwtt7BanHN1$pBxjI&8{^;?WC z-D&ac&TVWw^)EcwiuFUSq+|bb@x6(&0&mP9+v?TB@Jg=+wehISzSd&pbo0ozGD7F} zZ_Ze0&dJSQV1+GLtR3Cft0gF!Mr?Q9p@jDTV6Qdn6&f5quOZs9_Zm)E!pm8 zG;d5YBO<3)2gI_qlG_{%dMjtyKmLVRHugEoYBcPe)+~Q2hrPfnn;q4cv(ic)&&fS( z_AUge7`=&=sTic3wVi*Q@(9zYUE=2S73Ykc|IS_+cyRux{j)E6f_A>B{c~A8aXsnU zG1iTP-&{U8pXK20X-kd&G}dyiOhGQ5)ZEU1pGDe=?4xT+_RODK@1L*U^UsR%($m2x zS?Kl=!Fc%?(cn8skN$11+O?&EusF^ z7JHnzt`o^-!eC7fMxtiho1o`WYmD(UDUrQrS_(Tik~%}V4!i-3nWvexEJm2VVP(Bf zTzh6?9n>+&bM?JeT((06TjE-*gM9Vh&n<3cd-0EFt(N_#_Wu8CS?>q`pRoLtc>mv6 z?jj}5*B=^wtVgG7W}oqaJv)zb&iIE~p4)HjYh||*l;wWoI`A7E z%o+ZgpGSvF*M6#e;t;fnWS%pZIU{-_RT_%55BQU*6b_ z+wop5`R|{6iBNEwl3O-o%cI2up51zvpIfgs9HnzVL>peT(kzTFKE)2v!SD2Kv=DXp zp6DIe3(*Kj#ao>_VuLl0e_@&X-iLQp!CkrTrT9)g3VZl|4#sX_k$9iYb!dhQ&KYt$ zSqx_0Ki504NA~e@zIs)UGi#7-bF26KGk{~SzMLET#1YFU3EJ{47|Yu7If#M2|JMfj zUi+IcC_;@*|< z5%t8F+T5Pgzx>eqzx$Wd%76B+$a(zJ9xNqS?Ktpg%{iG1U$;XaX}@LfnV6L2`Jq;V zKC<@Cf9_L7%4WA$>wj$Ty8p4gM*m}bP5;OCTK$jh=}Zaw_b`4@z`x+mEg$4Ia&pd; zw&GtfO6*Jt&NlIz0XP1BE3Mz(O`J13%)Ods$BwY4=gM8ga`w@5{&{}ocAP7tM51M$ zM}349DUA~EI-50=K;L3=ky>L8#%4;d-lPddhjG40AVui=q58|++i%cqZpjCgul6 zNN4Ca8DYG?Duy*)pI+~FSNF?Repmcwk@#KlhBBzx;*C z+$|Syx!CrWzP(shET4g8zOTsLGH3bRc8vNSt+n^xmDMj`y0Y?DI`q2`fAz*2weTuE zJ|4e^P>FxTrV@X_L#1*vtn?_pt)z^<*QZh*CzZxZr|gvh_A1{mDLa5Mpwd?_S*bB< zSJnV?TBS2DSc(6Rgt8?@((e;iMX4GTS%vQfLBf~Q(#>u-;V+QzFHq`A+xQnKD)BE+ zRN`Ntu%sjGT1ds{Z``ln;Mg6)_=%JL;$b&NF-y6}p67HEl+g1qeaGR!($L2E!!I|m zN7vlW_jLNUdS{F-eP8dlD*C>j<^z2jlJDOCdHuLoYP%C-jlVAyS3 zPkMSr%Y8mYTJ+zXx#=?uE<0Vy22XG7I6Z$fKFJop^Xq+@O|MB=!oRHOQG8qAIgi`b z+>j5D)f*RK^01N;-M10lDmvYTte{apW5y%*hG>x?#jyqr#O@+YM+})X9`6MRc{N7( zmlZvnqIHFdzd6EWMW)sjrV&b9U16FoB&aJw#|^P{CDY|tnelE6*}9Txv5>522JTt7 zUCFe{kS*AuaJ!OegA!L)G955>Y`apZ8nQlHwsoaa8$)besdPd}5W`f`zsH;veH=Sm zt}B(I<=IY_t1Fet3JKbkm)aR(>&i!?4Y76Qqw1H69T&rVbd@26@#QnFD<562#MPCL znhOc)DnM@=V(ThM-xy-+DoE`sXkGVxto>DxIvO%(ySA$!bywo*DoC#j3F<0Ln+&ma z6`{PBvE`t@iqJSA8Xt5Q6`}XfA=A$xbI&1*&mpVMAsfyi-zShom>)%mzlvo0>vNC` z=+^|Y7NjVJD~e8Z`2l?M3#2&Z6_OeK7KH5-r=muu_Cf5zK}t|*qjL)gTP{HrR7YaS zZ7)gH6A0TWN%ay4m%5N{P9W^hMbuJ>^QSaDA|&vqG(BN-tUnhMf7=RABcj%yi>Zg| zIDg7e?*vj5+GS{nu~QcLfoFGF8fENU4#GNRX?%`SG5RQhY=h62&~jsE#7WH(<>?D! zX95V@DNo-To!$HJ#18?wl(re2V<1?1LHMgvw!b)r73kM<$gu>%mMai{mx}YxwoI-4 zGP=r;pFmjWGP*&?3jAeZk7lB!73pRrbZ{`<7CRfzP?shhg#IekXIZTXUGK~SRMUqwOP?eV42sHTJ*QkiB826 z1@R{p?~37!BzmZ}Emc@ZR&)j|^Ju9>Wen+!J0&HR4Qc7fRfdciVoSw^45rI}C)y;n ze`iSQ8q8YMUYky9DVlnMs5D3&YJ<16Frug&N-?QRrwti(NXb<+zq;y-x)t9JgwEAe zs|J%^#H2DvJ(?n9pVxi>`T^ux`Xqs%yXZPPU32ikUZ^_F=`SH!Gzi&-`=TYK)Y95nrz6PybghuV zC0@k-=Q)rE=!_7Zr#*$##`v@Or!UCEbV~x^S@|g4lR$<+rww&VAn$@aL2o1wp54#V ztOPP1{neS4C6K2;y3*H5qJt5i>9Es{zBlAWM0Esoy3uY!>>TVyzZqiZU^n@Do172r z9PCCZb);Qx4tAqrhS)jSjmjBfXIwX`Zb&jl<`KZH27@$N(-5Wv<81i8+e3MyX zxcn+9MejJ$>1rmL4?h*1xR78c(~Z7R9m%VUL}zL}F163&S@}6gcPe@flVF}cN7W6n zbMSe3Rfx{qwJ3$##%t9M&t;yuFHp=7&Juhw(}Suc5DYqckscJ1CAnn_bmH_>0@(?Y zNj(hVtaSk7WtwkwkhPffqEm)&uKN|FH%05SKUwtt5hZ=7m?5M0E6JkrhJ3t3$t!fF zA%_fkm996W5aM$Lmitm?LwHuQ&;6)(0yzcJpH2%I9_9J&#qoweMXqCil%#^ZMg5O>GR} zT*qWAbvC5T8SHC7#!(L?v;*^$$vf2B=y3MC9OPXZC?ty-jMI_%9*q<-n4a#7^$j}j z(PkwsM~$bd4G8~wMbmre-ex@2Hl!wUUVW4rPxY0^?&1a^&4gq{w_=|1ebYp`-;i03 zJZebAF}hYxq>hH17;Q;UL%tbeNk2m-J2JwM2DnG#b$KF9P$K>`gg+B$W&*hzk0n`(~fRf89+Xv6NYp@h;KcD%%xjyU>#lKTEy|z5#4PF z_dAn?)JjM&PZv{fAv%})!_E?#dn4Nk?huz!lbe*-JE^6#Q;6=hWm>Chv?=6(h=lyYL!4TQECk|o!MnKa^t>VOov`F( zTMF4mb@~}%*RSpLrXd%aHDx<3Go(2@+?9tde`iP$M-CdY03NE&X+tLMx1>NL!awX7 z;i2kWV#q9bsHCk$kV9(4Uiqw)#@0sllmI64*sytE*fpf zT=>IeH%&8SG5le&hn5<$6#g*TOWzvu3H)L5BOMT;d42@QJ}P+|;h*kpnCz$94LLj* ze{%`s0JS%y(n3py8nPdCsm^Lc{&a-Dt;v=bqjuFPdb^T!j?^+_&orxZw;_Kz(#w$2 zPmxL;9Z$O%7GO1>S?LyO#BL&PdtiwHySb@q$n&G^By(i@KKxrpj2`12}4eU zR1?zAkjp0O%2>jC!;pF)1!1RzH%f{4%$7@f6B9@s*tyV~kwC5kDdlYzvdp*fDdP=o zfx?Jt>2~<54bX{sqYb$Xq_L0*N~A6(mw5Aq1a``K6-dTTs3+^I8>UpakV4@?l2go&^-p4IX?Sl_EB zWS>XdunUGxeXp^QUEZ#(yjNxNppak|)b~0H$%@8m>uOcs>u$(pAj2}bRHh*fjLvml zUqkrLm36N3-cTYD8wt|D`#^~1)o~y>Rf7j5KHuCsy%W+i0IG^BFH1bXv z@(c*C-M4xEqpH)*=-lSzG2}O+bGui>kfTQDcCVBYiN;)5zQem#i2A$;(!6noa15C=^QH<3vgp0u0wGz^ zH$(b2@$U6LH{=}Cz^U}TV3~3L-I_cgHCDPKpAoqF463DM0Exb}0 z+%9eVF^~tm{X&AaKj;-~o4xH1dIN-L+s~lXgWhbTW840aw@!$*J^V7xQoPNEaNC(Y z;_Vd@w7rdYR7h5I5wZ=ptBrTYkaZy3t~Oo-E#$FL#pq;s`3EvC7)i-hU zKI@GX5=8!4Z;FttXvMj@qCM-)G^7RyuV~MD^OZE{FL`YYsfWMK+TLTGc1pay<1kBL=OwR;A^i93*>c?LZAihBy6(K}yFs@H$b^-cTd>^6TVu!@V^rrAZ?hr1I<$q( ztKLsSg4N+w?}*XivGI)P-2Vi}C&<`+y=R5!Xz31}eqK*Qc(gDX;0-XP?7sIk?}Qtl4K&2|;BarWA+`rcc#{pWJ@}S4*AUx-BfZZJ zu{}7_+h~aG!BO6BLu?O@@eUhedvL7hKg|&fdT^|lSBTE{zKGaZuZ@tP2jBL32+- zd$Z>G5530>N!gqD=P5RKReu=9~OTSySGY2F4QI##DcXS&z*ne1(!;k_?JqdEsV zGrW%t;ixj1=`A*;Y*at-P6`P!EUFBhogj<6pM+@Se*#(J73!?D+qG$_ zSIH0?v1Q)PLNw05qtr6*E<-rZOg{Ho3dxH0{{p+$IHKk~V#p+rzo4_ydt8ac=d6(D zg{VJCz3|sRywO5}k+8;_Wr+1>t+z~w`jZ!>)_PwW!u~M%(%WK6+3dI8`%6exbPf&* z_zrQs7wW=o&x|ew;l5b!W8fZp_yhkx{9BQ4Ewa~j(6K~M25uHoup8?v z%d^DXNp17^uUsac18g&PmKFGNl19~$7Y!EoePu~0&m}Jr+zC#2#M!qRQ)Vo zB>$BJau#yLACy4Cy>ZItb6>M%wvz%9_17ej{2(d*9ws=wyb)_t5s*~>sE{GiZ#Lmn zARm*{h73D_ug-{06#qZ5ms9;mg$$uT=Hlc@be=o7@7He>cbxD7^_>BbxH~e z#!r5~g6c#E{-Sv!zh6C}R8`o_@0ZPDJDIcvYZH4|(4Q+Li?-uk8ouKw=)e97>tqps zi?%jO74)O82ILwcorPr58_>B4q>z7YU(tzvKSSG9*uPT=m0P2A754iH$)qoDwPd*= z$8WP_uaJG79rK0#BZkCW;3Awk3n`>Tyk%P>y);9+5ZtB_tUK1KY! zsuP`qwsT(;@x%Suvc{PsR>VIbB$M`yct)LH|$*O z*GeD*K+5{B2w4&R(wu&m^9LES&76Lh^QRheSwu&8d4G=~^*}J>sl1;D(Zt#vy&q%$ zyZkse_KO(u1jsNUrGzYxUb+N-X%Mwn@XH%g2V{(pD}~^BCCGS?%lvB%DF!lG$S5Hz zq8DL>~0awX$CkV+*4t zT6m>euIyJgq#6iYuIyiLNFDr@jXAJf#cyOt6Oj2rnhU|2@*{rbUIBUBf7p=dK0JYf z&gK4NLNcQb5z93oRsGIJCk&1+o{;5q6LxW%pmT*kMMxIi3$jhf z$Ep*ZxERkEg?y?y(anDl9Tc)$NG~e-r?q_jFjRoin}4Y#i{Dhz3cn%J+VhTNvVwR{ zE2%0Zi#lNE`9muEb8Q0QJbZ;87m_KZPJmSNXN_VzS#-kKsqSwW%_Ng{pe~Mcb$|2Q zO8$n=TvrYMx^YZ;MQb6~alhB_Z#Cpr5H3~2zgr0Qy^m?BEB&VpdBl;pAveG;_UB4} zgCUP&f5@b!U-liszf3BG_%NyEcQhmmJ~OH9FEC^y&XLZ7)bY0(Qu1}xxyrx%UAD7= zs-RuGI$Z7FV@Sbkux|HZGJ*-VA*@pfq@I7+=;TMvtnJ|mf?w)AwbP;=<}q}x_1iN+ zDb}eBQr}-7I$1Q~OFX*(Y2dF(AoYc87P6e4gq>SKuJQf;rq9;@J`CwyzsUazNf0Z+BV}FMs zB|&%(d8fbMkV;19PCxuU*FIck+*nw?%g-w$i)vzIvd?$>MH9#bA(ahDYOgv?{F(`b zb(;8%3~6L^()_dp!a8YwTOrG-^lI$PL7Mu#40$<@K8@ns(;t~YwkBcE>Q6PK&wABq z?$0%3)HgUwz-VdV=lg)$l}TekK859$ehDEf=%KHP*iI|Iy&)Y8dBEQ#q*t^xMg&Lf zLI0p3_TK72|92so(QZE>XTtJ>{wbrAv$*^eIq9G`Q3csOu4b%2XyRqNg$QxTS6US%wrs+qteb{(d1@(FI95elq+chExe_ z-pKI157o|bvkGVU`GsUf?Yf-dUu1MzzovC%_;n4bhgFYj&+zXtrM|+62WQa?zqKK0 zajWyRkY3SypS0u!L;5+(uNt!1krBquhi~A$6|_CWulSMr%xj#IJA^E!dmZ5!ep{pS2lB=tvD3lm+>c)7+|t(XoK@7NsZs# zkd=l!myf{psYdHYA2fXsNA+?EeF6msmcmgxX-N-XvteOlbv;1i2mLS-<)$CHH`&fpqpa z7}5`{^10|IiZh#%8(5vC-m_v z&QYJ4@Qx_U=ijmNN>tBek}SW8AtP?nypiQUVTiqt%kujP>E+h1EPo;s>?L;9#`;#4 zEq|CmZWb~(fqYdMf8WLb4M1J5IZ_v7D9G!MR0U~{I1W9>&M>FLcHTuP{&FbSwZdaN zlR@5c#M&8ij-9bihwbqF{y0b2&LWU^9I+=e-4C9a^Hp%ZHB#77~e>^fHuPOW_bQebEB>x*j_&M4oF!a9vF!CVZ!}7DOFW}*1 zzq^nX#80UTMDROSf05B)vI#m<{S8LPo+y6khZeJ)6;w2zC#630%M01(@e?sF^^xC3 zNG5eE>d`f&@dYq{w2&3_ z!4SI+e&SzYNG;?Iq%r!$f65TM>dp4M81l3k&$Io0hIlV)9-HI8VMu-uu4|4z$q>8h z&Gn}l@(9*J)|u-sH^lFucINqC7*YU)b>{iI4B7gU>U`=SG~_S{>wN0}ZOGebDX+qx z`H`i#fM`qx;j!_VU)GSW*h_Nmo$psPqz?$&neW#(WaB%kv%tT_kbNMmv%qg@$cIK} zq5p^>pBkNoem6sGo?qm@WXKhL)XpM*s3G5Wz{xlIeX&2VN2-Z_>*AjoB zAq58O4u6Ti*^qh|`>eCn-)Tq-5N`WY|CAx?kZo9JneQ*d1;l3u2wNJ$ogJtXRSZk5I$FCJ8S*rhIGKLXCTlQ{uhP}1Yw;o{C$QT!Kh=MFa5)Y zkU87=(!cd{^~dfr*ZFrDV$Xlp`7axCr`esZ_Xil#-q>01Z!^U1AvgFx8ZyDm(+&P9 zL+q~dE8kzCwI4P*U-`uiX+K)q^|fEdkggy}Q2*L*X2>uQ?$eF_{f0~g;l9}DcQGWx z#PA!xry8b)V}-^GwmaZ>VR;Z zxA`>;xp2SgZ1=A=A!k6?&Tjt`LnqBM^P~TrAtgar=SP3HkY4nrx!c<3A2WncGx#~h1;+P=>(Z-{-mz2C1ZWM4}1Nj#52#P<8Q8FJ?VwEYz(t(18D?n-_kQw`xaRW1TK z=+76joGR_X&H^d&px<~6*S^cU?p9s9fAZ6XWJQ}{4^SDUe)b%8p`|*Q7#{Z*2??In9`{!oV(-L{`|GuoyW2YMZ!*N*TOIdzm{KY4;v5CFANThg zoeM$k6LQ$-oLP@k3Xl{238RyD1McsIco-9WuXim7pNXIJQ-owj8-wsu>63n8qtms% zj^0!Lg+`}82#?-VemSF4-RS(~S25&bjGAX)`7ghwDOC-mn~-ab4xfR%2y)uL*^rw+ zdJDPJkgqVp`-7bE?=@sU$Y3E48e&iR{`T7%Vo&-0_B$A2&+yOs-3%$VM9=Wg`f(wd z(TnhufpZjvUNt&Z_(=qZDm2vStTro%7g}U=PQ&LB@W&6WG^GC&Jqh$f>kYXHBa5Fi z`k_sRGza0|-uj`PhTOG9;~WYdFytW+aVPYpLX%H ziEya75Pf#c&+(H&y%Pw(4-g4W!6?B9cc(qk&|E|8E;kzb+z`8OiH5#5#O}VLp&f?U zJyJCEvmy43C>lCxh}|PaLlKNN9)~uIMne|}$&A{yI~rK>`EGePyjn2Dxw#E55CG?{q8*kI>ml8T`NFLk^tIla9a$+_ImQzBlz7h}VdW_!X zAbCTxgk(}iSKYJa4{iOLbuy_kXLWQ~fl$YdO74PXwo@Rq!H~SC@HP}k;ZVizREOWC z`4*%|C~ioT!x$SNMMGOKwh$lM)CGH5kYXVoZA{MKT!MFu#X|)*EBT<4>XZmoHzW%3 z8%mW7HBTTXKrRfm!PsIu&!H9kM7VUQ^Hu=78B%`+>H&#`-e&@xk{HjN*)9o%k(WWD zw=L3$l?$~Jl1XRGtSlE=Wyp)rLEx!;=(s6mPnODu&Z!c+45j2F&QUI zsQuDVK_R_p5ALnlPNmQnLNaL=$h|2{Uf;o`a4zwi)>S2R{Z1wJNobYO2_eDr(<&j_ zr8Ass(ZJC}z>3kjZ|ULIQY|0C;8z^$6vIDqfl-us+=&e=oxDxnlb zAqpW)D$N7UrBX^1(xge6ZYQ@;lm^kDD1}fO6ru4-np9LI_mYH=CXx95@4Mc0_P*8g zc)q@0?^=6Jd+oKy^BtwaQ$uJmDo;go298Ozb^TmZMe}PMM@jTGhl=J2kwpGPED>CsPmCr3^ z3hAk)J$k9V;1;t&M4F;rx0<6_vW-j57{+Mq7gf#eEaBCIYUTl!DaKQ#dM>4!Y5hVu zXB*iT)*HyDnt74P0g>uv8Ij7EQ@bFh22vNiZlgtAx9NqLS`wqKxAcS5&WOHFQtyI% z>Sto;dJElCXqXYY-ZB#TG|q_5r@48EOPJ#{Z-T2vh`Gxwd6deCYq=tKn{7mjFTj&I zh-qO?5V=~UrMXT?W+l_g{4^pjAyq4LUqtBMdTaB?h)~P7HBYl(9ffDr<{?#kv(T?p zo{hLOhi}e6I+?ymACzztq^o(8$n7Z4;Ub1{pV^Kj$0^rKT_Nvg-Y;@1gv!&+>@BiT zV!E4;i>#KI?&cVg{GKYG`_1P>PCzK1`^_05!9yyhhq*xH3JAsYFyB_f?eks`D zl{6EXn6IU?NT*d=dW#I%qGh;<(_6~~5q+h-zd4ma zrU!&(k^$!1ENN#X>a`m+eau|RlI=`@9Ax=eVlKxF_cLUm`H93_4>`rMQ(_t;Rn}9u z8gK5Cm<|w^C0}AHqs2-<2Ae-gOf5)Rmg5q$7O5&hhM0d#%x*|E789k%Jmz#qss@mu zW{M@-831X?QdDAQ-i)^-Adj0RMLLYay-1dFBE7P;R8(RdKt5yTt$B||` zmT;yWX^vq@JM(0Z8)-hxlI^@Dd)!EKip0E(<1^i-9%arHc?x%&X>B~pd{t7-qI=NT z>L_zD3+}cz#<_Ai)Wkd_^07#^c?r(jF{?YHagT$>&lvM+k+N^85jDoF!lG8Nv|b%! z)>FdQpXZ|PX>%$|E3kuDHrl|M(FALU65xol3tBxgdr0$(naLijJ%3xx@e6w$?R~Naz1Rl{jaLmWb*(^ zu5lR0Wh&uhb0AhrbQgwV@{#lN=2j9M^*%z`X|zl=58$XtG8rvKwU}yN^A}03bI0rI zOktW?QADq4rCTJ&KynFlUI+Gl3*8nZHUtXIH2@VzbQCBJaM07DY{GoBxUY`x(Bu9mkoH>6}$t zUv@Rl9qQoyf3t|l8Z4f>V)ZcByj0|i(s)J~+nQ&V6``m5|AM??Ruow>U$w@o<}D&s zFnaOn7-PO!OQh!$c)k^~z-%Zo67A$dUNc*W{M-yrSwa??oka#5!8`_8WWK6|@2C9d z*HVbFbD9$!oL)t<Ftg-PkOOH&JP|JRirC=}5KRtiqDZUv+*6 zF*{89sxifkycuH$F+0tH5_8u$^f}~nbFs*cBD>5ykq&4>>aX2qc}vxTu31e*j(f~X zEIG!;ThM!m*<-e1$U4UP;^d z!dxyftyZg;FU-Rd(-&i(V!kxbl0=>?`qFgp+z<6dW9$>lQJyc&wk+XHyVrb(WkVr7 zAMP_BC&}7SNY8Bh&BYR?oZYG{<4sgZQ?2LPL6tfdT zCO&3BY=z33XzujW>k zv_ba(=?UuJ%!(IL&S|3(M)(QHALe`(+@qh2t4hz{s-u}JG7kNofSfURvSf2iame51 zF^PGqKCUG|{xOSUO+$NJbEK*OIcIiY$u=nFHpqYG5{apZU5Qdgg`Dq!q^ubthY?d} zG_FcpdqiGCOb^5qwkj9re4N49gX!q`KdUi|+MD_!=6_ZnmTcqC#%ixDZl%vlRot4- zqE<5RT#Rcj)@Bh}$qYq4mso`_RyCcA_8AW;WesJ?<>$=lovbUYSt2u$YC2-dS%)MQ zJ)Qn4q=MC?1m%H4_PHES>RP>6a*T`6 zgX<7e*;>Mq%`u-tZnnHjRjTIL7X9s3tFXvkE$q4iiT>qV8y zScmbWbTXE$9sT4y#5)=xSsBUH|HtR5_QI}bv$XdUZO zNp%J0`CG7&y4E0(DiFGgRo5CR`OsTvf1u^>v~om-L;hrWPUP$^!}u3c&w4>5z8fX4 zNHSNXeqZeU6Y#AMYY|Jf(*}}cS;`U~3mRBQBSKGoG_VSlqSjC`MUbkIbx}l0K$=)r zMx+d+nRQb{DnRbG>PF;7NGq#nM5;mBSrZ~s57N;(8j<#p9#*r0X)>9(%TM2aaV4(H9NX|Np1Z;hf^^(X`$c!sP z&RU#Lqo%{H#v&cD*V6B&jIdg=q@70~6InWnjQm?|Yos-lWrO*|9$X*5-aXQ~{z|G> z+8B=6hGdl0f@Oob5HlprEu*caB8?&S(j?nha*emp@05Owl~tDWaaOET+ZtnCEV3md zm08r2@bo^&80%-2@M-xm)^U|8vt}D(x#c)#;}our(BH;bC0W#0jHaTdW2|N(^o-d| zNZNXpMSaiVRmhXpauJGo1CnE1dKKlD!`~@=7c$;z%#xpVwmzP6f;?rlmYAopr>uuO zZFP^x7RUr^Xhilvp0g%Jy3!~0-0fb6p`bQ7p?sw^jzFo$V}@FV;i2fqSQtNsp z20d4B1y)u|ttKq_iL*GXpnR5D%_Y?!6Tf56(ow}^O+A1W6Uw~I>Mi-`GrMKhXpyx; zu=?PbeJmS|9IWuGL6%#;N2Cs9g>^<`3St^TR$9fbqk3&LNLoNvS>;#`^EX2}K;E}* z5~04J(ffhbSA^QRD`GyhMvG8ikbGoq6QR042>IALz=E&j;>@fsWSw=C1^50CLvzbI zYhXnxPukggLbd98YbQ&NV`49O9RIl9+9z@mWDZL{OL!#OVErbdk3<`+e^jc>-o4SX zuBUCOWA0#-XQOp#MCd4-YgLX29fdbrjaW7m((~9B>wt)!wLY_MyMc1vP)N^OpINP0 z(#~9*DN?_0vpTWhnkR(j-fdP7mRv`#d$(J?MfBQuyERbd!?mC{Nw-^7D$%yWb@)ze zkBDB2?zWDI(CVF5_`9u>l_^#DKJ1s)+#5;4b>^4WeK(PWcOLgz?}+HLiM`eimRv`# z%=cQmlw{V=d#(KA@pBM9uHIOBIzw#R^n zIL6VpBMw?GiL8c?n_>#=^Oqu#gH2O_&^MU5JMYi$&1 ziTj=ulV|Nw!Xx1sY%9;ITZLL9$DmoCt`Z-zTCk*9D4)aD@QA#KR6kmqM5ZAXT|52R z+9z_~TwHxZ%rBNp6BCZq^v*S%%N(`Ju;9!85IS@D)fz;Sm18{p60S8N)$i5_k(VK~ zM*7`)Qe@86n29-NQbd-rEEgGv82Zl1F>7r^RwCw@bx4Gs!=l#s!#Wm`4-oT*RrFR> zo^gn&IU3({u*yVaEn<#a^+eX9Kj{qdgw-MWpEK4Zk*zwjB^BJu}f&RGMis+{Ti>VJ?d zd$!12Y>QT&roEU2?;%3s&yt)F(PxO3ZPLLQqlISv9^-IcWLIaIVodrSS2B>wwtI>c z#>z^`6qd=xo}Tz3DaXu>NI6Ktu3L?Ao@_jfnx;IYv~QF5_;M1$5M%BHXJ)C8_@qC_^qb!q+#eHy| zhkVM}wd+%=aQ3^({;Uy+n*Hc5)m8Q$mhjr?)%GC~eWkR#?KY-V;g!+~b_WrCrSw{R zG)uNY(i&U8&fX_6`r7IB_CHNjKKk0}4ff`yB;j?@N_LrMO7wNn8||SY`daSI_GT7* zpJb`J;#$Q%DpH{u?(<{ox7d}NBcH5nj(HSvn?0Tcwa|AEZnsymWE)$tj-r37Wq-z! z<2+YIjow=JZjl!tw1%u@9}t=RG|se;^BwjfmbCLKWF*V45>pprgJzQ2_9=;J3Zbif zwe5c;Mt^O-jvc#;N|AP|->hQl*a1t9lY_O*lgPQQeX+z;&Bgg3%grK`t*XEB zRNuaWCA@Y~-@Zdh=34~y?S?FAr}#SLgITM--9lpYH`{fvlSx3sdSuw*;>xp(f1+fh<1-%wLNmi3S=tQ8|yHBI@@(b7D4EG%e{6Jmb9@5s|)NXMi;xSj)CMN zRad)fL_UMuXAc#59x=M@9TA~^f7)&# z(lLQEXv9pk7l^Dzd1$YE&fYIVYa3e6PqK|psyt&F;y8d*lk7GTX$qNce=x=lED_FuAV2)jx<#5)f`naQkRlywl$@5ap zvnR1^H1zX7^X#`(jH92coM*3O$#!O885M+T};y#kJal;{uO33T>P?pI??{9G>46@i>+)btW_^6V% z?Z>;5gh!$!b~Z~`_a*j372`}Ps=gSo#GWQH7eXUpi9JVT)AQ1pWo`~zHoZq!S7AXm#RPWlGMT%l2L#dY8J4H%EC}x?xU!+|jmCtfJU!*I9 zVwT%Ki_p0+o!zXkkBiW`FaUB^TIwV>sxJnz{>MJ|ERw%)T# ziS)zy8O5x!uM!ysp_o?{5AGNBKjKs8he09g>042hxRa$>JZB3Lpv?<6=pWt)<^a; zBHu$O<|BKmNDa(t6!Wn?OQb%8Vm`JPh|t%PC}yqwmdJ+^v({dzB(qnpv)8hyl{uXO zt+QY2LA{gfOz5xjS#Pfu(f9h-+qHVC9-RIkuF+yISZ_CANjvi)b68ri^!5I+ACi~jn9AhjmX&4KT&nI>*mT;EXYeo`^ggq#M=9rUAKYpWV#&$ugInzpB6=U(YUhaPeQ=xotcczRx7ja< z=zVaz{j!MO2e;b`Mf5(n-CiQ1_rV?ZDiOU8?y%R1=zVaf{i%rF2Y1@LMD#xRx&4)h z-UmOozZcQ_;4b?Y5xo!YvQKJ}eQ>w^kBHs}ciVO!YQr2y?}K}6Pekv7d+g#OdLR74 zzFb7_gJ0O?Mf5)SrCmux?}K03RYmkZxYw>NqW8hQc4HB}5AL&Dis*fCpWRWULbe*u z`|a)`dLP_xKO&;{!LRJcMD#xRl|5WU?}K04V@32n__aMzMDK$K>}eu;A3R{sQIgpQ zzp)pwg!|w(_OpFeI}dskGX(a6gZ6Y56+>SmIfy-+{^Z&{amSFp((`Rb=**8K&tAZ( zrWj}TVQ)h|`SvOidawUemVy0fTT_hb4e$&n|93AM0f7qVO z67Efh?K2WXZ+57dMgu6Hv{UI_)$)h!79#XsQa*A%Y`n16i`22O)IC|Ir>HG2I)hx5kdxPm1(~&|70i>}N#|A5vd+`^laz`TPS}k6Gd; z`(>6XMkD0>8_M&u{jtbfld)o)gfln$Q@lvpG2%5m zSq(X5&l7nAt7-bT)Ak;bV;PALq<;y&fO^^vSi*KbZC}Qcc3x?`Nqs* zF=IwH#ZES|cc~aFRzu`X5j!?sBp-VL=HAwkSZt9(dSK`x42%o4V0u~;jXusp?L9WRjX zEZLcFBo>SHV^K57C&;;2Y$MCztflDp&mkAbI*g^QAI_rh1nz^Bh;@Ea30=+j7IH~! zd5#jgo|2)UhWQTmQN)yrUG@y+lXmobwO7Q-is<)h zuZUF?`F*!~a^}id6_LyKtG(&USPhnJ=XwZDvRB3$shG^ZQ#Q6!iLvNr>=W2}x!5t0 z1rQ81EN?*ahBc@`^dX{2xjqz)@U;QFRp#z-)}~FD#hF>q11xh z6x%peNhOT2_K@3R!>1|v8L4_hs>e>Uq>c5>kQ?NV*!<}f6Yd3dVoO-E@stnFml0DZ zmMe0pkEa75bz=uaYGFTq1#)LB_5$TI-T4PcSen`E$2^v_qx-#nteD7+7~#t}rW8xK z_4={ODuzb_}Y1*z_d&CvNkDzMBG`LalsLEq`^ z7<*mhS4cIM5=(Btl~T>&*3aRGJD2miRh8}P^{c5Dn^gYM`Dk$ zOg6S*)Qv(d9*r$#QN1$`(kE86C1dyq*4iTZRI?sqrhzRXp zGh@q@WPUYcR&0%k9(A)~8%6Y}n-$wCqDS4V*d7r*>So0bu!JKD`78*_d$M>xx?Y=NOE}dggJK#X)#lhSmhX*s z-@@~~sKsZo-xpENhxti(s@KlgX%SubFJk9dHW_P>PdntZFLv4MlxmZ44`jeCcy=Y$ zjAgR1?h!nLUlFYz8~-N7gmXfEY$}WT#gI3!cjrr)H`*0(_4|6H`Y!eX$K+>?uZJhx zAwR@&SvC~<5^Kor*!q#!zKA>u`6W|#D)VKyM*Vw6s5MI9uGk;3T8mX1(pyL)k?Lfu z2}`c=%$Il;6mlwd4@=lzr(@k%(vE&!^mObY5&gXAY1!5$n|g=(>raslaot~MGxDj_ z;@<*7waAJO;G8#@x~6t~L_{dYiBC{lH|V>gx(6@L zi0;8lGpXpkEoz_A8PP3PCjOHuPiiz;wHKQ63W>?JbsL8A^lt2J$mh!VQBF11*uN2b z5~OV0dW-r3XRO)kXkIQ}lx2!RzgR6(k?LL5!Ki#@>Bx+)HN$@9^`*Duu%%;qq zTPc1((uc3wW+;py3h6TUi06vvGCvUCBcglf!T3p*um>NCcU}?p4)xcg@#PVr8L5AK56f8N zU@FTvf~^mXS6oS{#v0e-YQ`t6@kD(*n`N@$<>IPRC9DDB&x$;N{o-TDK_~KQn7J6*t#A~l6 z3Fq)<;=Ne1jl;-iU|Y;D@tq<8@)-}A8o%{@N~PMF-XfV1ugwy+*o*N+Ea8kjJH9z0 z)P{58r9Mz)KAcc<=KT1zEMb2wiZ>V0{q=gh9ZNXI-iY@Sp&nd|oZpPEWy#NauO^;n zgS-u2Hpp$gdfC@MTC0!yT4&v$V@B4ZKrUAzQK*gN0HN3*D!QoVkR&y5Jx{pa|Y78YcK(wXszndTbxz?;Di!tn6OhVIFP8kQ zQg`6GI;4s-F%t7Sq^dJbV&1NU`3F+nnJw}hdii5WEoXs90NDbm^KnGZK$<)2BZAL@7WecOii%IBR=IOcF7lsznJgs;4rV#uV77^Mj>8$NVr-=yFl+JEu zWwxdFuX)b>924$w^PERm!u@ofGmIr%L%!lX#S-qh^D{Z?nPh=8O>z!pek5nA#RBI9 zi<(=g7KjBd#bT$Jh_1yu&J8SK370!HS;7*oaGJ4%C4A56Ao=L^*ea(hOSq0& z?et_(Ba@ErtDV7;O0V$WcXC+5BlQQ)^CJ34y~ddGF>2Am|=R=lomN?~XVhOi(+S$eu&Jw4coh;!jaoRbod>Y$2>nsu(a3}s9@}FbxR58zDR(D>&)zU;6kpmDqQpXcBSi<=yl_>c+ zrOM@_49!1&Vthns{wb1(?V=df7ndXFqKPXbLdW-u6XjXtJs`-XiKBNYL z&`eS;F`p%ypWLJQ=bFSZ7S)5-Vp}&PuGy`&PVG$VgqsspSaP%UJXSSPgC#tA-k#{J zV)%$pZCEW)au4Mbj=EZjiXwW{)kzE#(Icu}qW>3^Dx4u3Cq}cVZB<7J?@G*I3HOT@ ziCF^ zT13}!nvU5V3Swz}H0Jb_6Bwa9Vk zt#Ep-V0og52)z{!fK(P){hE5?U`3*;$Xm^{)E4QV$l|vWRwNpU(EIprqdY4TEtK$8 z^yMt~MTDL%UYVH7GM(=leSnzv63azqHo%buvMN#XJ1X;Zqf?N@@_u5x$i_Z+a|$tQ z65jU|6JD42C{cw)^~D#6`6y9Cg!&>6vMzCl2=&Dg$c98Cmas2!6D=b7(7HD_(SapD z>+L#fZTxAXhsdvx6Ub+4qMwLf8}CRwA)?pDyAtC>zNw9KCZzfzF-2q+gvz`x@v=xS zoaZKH;5u#M9Tqi*(`xx(;$0RsKhtVCFR>ybv|9cyu__|8>OPeCAR@()^Wnrt5xE?4 zB(W|c)M7s;Hb&%X#2ih0!lLFDT4Vo~*eNm8s@FjNNPHC$T4SF~9Eu37)&ETV8j;G# z`R~N(h*XE1OIU}fm(|gM`pZcA5ov@NGg*Qq?7>*F42v2GbeK*EfYm(1P4D}B6SHe681&gZ*JK?Q)fd#x-I7ftM)yUJWSfXkfAvgui3s(@ z!^vI|p}u%DIUpj`7yXjMBSL-gSn_F>urCHDr?RNNpt)sma;*r>kW`DulZ6jcJF7BN zK2Ib^u!Q-HOpccrTH#YZBa_Av)jN8I%uW^-(S15LSw=+n>9}NNk-O2$boJorWNi`M z%M+6=MRYGuO7>t;eM)7Xk}Uj_nkA?fw0})YmW~MZ=?lplB0?kK#bnKhP%qC+Hj4=L z^6X@%h)|!tob1gKw$Hre+@ICfb)U{pE{O>B>B8jNh|oxQBe^po)XQ%r^CCjMyd-%n zBGk*vlK267^iJ3pE0YdOcpO}rEY6~OnT|3mlb5sPXX!RvoxGMs?FCfRHOcEG6}2I? z#z)D@5<~T(t*=d1lNb^z;fCa$EMa+alT9Ut#zt$z^S@N^q#2L_7$gboZiJ_b)L%vA9$)f5t53)D8T4JcoZ$kDbw@VDk zN00-_A6UX#e4G4LQc*2FL(I2H<0!TK6#lL7eUR^xEm<}ibSIQb_+zp&OIX5RlH*yz zRqk)eioa4m;Whj}l7FzM@q85doKF4~5vtdjWb8LJ#;B%LufLN;S=2Z@4f!WoIwDll z|B_WCm9A-_R5O+-Mpx9`d=cxvRGtWZkt~2DQkVZ;aEv8W6I_SG<>b=TRmZ5z;oZQJ zsR}G%pO#EjjtG4OL%XhRI07YC-cO@<*6}BGWQwFq@IlALt8DAnivtvxlHO6 zmN4flQp-hXL{&rkT$$P4KPRQ|11kQmFCs z2;}-y1rf?;5TsJ73rm>KO{oVZhRQPrF*l_~Me=zLa!V>5$>&ALZK=iQrf%vA5o({kkou_#B2=$@NW;`q zEMdKxq^3sl`3*5mQu&d5vT&|)SL#?Kp8(P_)!+neJMj;F=C4FdyHqz3Do-WI zJ*fvos64krI;FDD%co0fLL{FCi0P8rAIaw)NcYr{NIpFw52R|HELfh0Q;k?ud4?h8 z;nX6Q{H!8qu?dhqslulyResjxb#SDD3`h+XsZ|eej6nvc@ORQG)Dn@kNc9V3Osd466q9ZI(hu(?XQQQ36Ij%!`xi0eQu8Gyj`m66&4i~@lg>~o zHAfYJJd--cf-fhVSsXJd^}t^gqh{=~h?$(~7m*twQ&Uewu;)8IHK02in6F4{0TAZQV)sHi24VzDK%AuN|>C5tEs7<&&y|9>NtzK0#gbx+fvrq zg4^1jawCEZ`^NTENfx#B>yTm9sa}l8u=B4IHJ~RW2M5_GM63K^-u+KmarBdhA zwy1XG5t#@1DOFU2O85rkm(6ymav4!Q?EyaN_afAO7hVq zJdyfFM3?7uDo=#APTM+@O8iS@4*TnD>I#-{TmPi4VNuuF+IScZsoE@IfBlV^}EFya$ zDR;04)glk#xl>uPjfTkiD5S94A&c_KHt20`l8f9jg;dUZY!r3hVhQVhvAc;Sta}M} zTSTbtCER_I54AIm)l1zLCgrTgD%G@l9|KQ;;&QVNr~lNebcmS6SC$QS%Sg z;wra8L}>I@aF<9bDzl4J*SY&yRGBY<+~6K&3Cmo`{VgIiHY&M>t?Eu?rt(yF+py$k zJyJ*2;%0ZC$lLc=dh?+&6Nu|qthg%}1>aJV9 zuDdfLG!E;#H^wO@tVJWYp%Q1=N_B0pk=sUz@fz-;mq&RTxobq0LMlNTyGKR7S%wt> zq=|c@!#O+Y;_9kn6So;lcvjNHofxPX`u0doPBl%0zCCg$%N&u#pI~Kb;_(Aao`4F87?y2ff@Ca<^+2R^{0Od4Rmon?t-d_a!CfkH2J%n|^oRSt z$j0R=<{o#w$QKZbxySuXG^0dTscK;PQQu-Ke{${b@Jttd<7KO>rR7^{Ki%P; zJ1^%Qu6rw$XJZz<^GG$_;TC3@ZuB386&%XE)9oR`Pm8^bXXD&&Si-dWum0w)5=mklQa-=CRqs(TZLoDp zbWhEe9uKOR4g*xZ{&Bw-Y4|qQ zV(8^_?op9;kT%HqKet{_l`4f2(pRvuys07|p$$n2dHEu=n9NtX5?&P+wGOAzlJGi+=-+N|y&ftR-?gXTZYb<+ zl^Fe?4n{+1WjqL{ZtVrU)Czb@f@DU$hh3Ga}kqL@cf z=2BkgM=0m;n`vb|r?=Xc{#}N0UZBKTv>r1A#`D!)agh}ey1RX~S4w2tLKRcqD<`7A zsaxJ_B%;5&Ti)xfgnyTT@+t28i4=VY&+#GVI&X#ueamYqq_THR8UNw_0L8g;2~x-g=428Lna;_O?jOix7%=*xM~Jt46DsN4&2k<}(Pz zJmMXanC&A}OmFX~#Nd;+}kBF`t7`7-d8N)uQ?3! zzL%H>v0kl-5%Yxii^L3o(3cFK@J>q1of0$L`$uA0NX&509;wDgovpZXFc8PklE<8>Sz&LmyX8soenEQhluVm|B%dD@%AqUJh^dB%H-CD%BERZ1Vov)&q! z-!Z}mL7qeI^e5NW`Ao@(PBk?nI@L6^?!$_RQoZWU6`^fq&&6}y-eM8j7Re%Sl?ZK%KOn3ga5 z-U61e-{1EZvxFn_18+G?_)Bmfcxza~k??`{v54-|HQqXw@aVbL+s2aPRK>hXzvr^n z`+`M15j`JeUhCOus{4jQlTP87<6!mRl@eJGc^fgCyz5w0suhr2uf}<)KK0g~muibQ zA%}9FY+Q`ipuONTum5XoB7t3y6}yv;0W=Pk(BEIT9l(6;t?hgA%3{SaiYXFNq^ z&NXHt75(zaS6&5{!&xMMBj#&wGs|?Rc2S(i&BKi2?GkAwa?s0@d@k;*&dBn-4o|C` z^*5RGyeiL-gguz&J;;*d48TlGJ(%b9VF~M==S^f$W1ebp$eR_B6w33XcSQ2hU$Oqh zJ0{WydnH`~{>3{ZqJMk(7tfeL<;iiXp$AorBl1|bmTN>}nV1_zwxqI*|6%LDc(=2p zojs6CSn5j5;vt4n26EJEA~7o=SF^Nc*vFPI^T|ZpBra_b_Xn@-7i+0a?Rxr4r+o=W#Sg&ZoUbEE@{Z{fl~-+5YlovxF^n z*4xAq&PZpyZ7LsUa7{IO&w5{oT!Hl%U2{0=eWQf;owf;*6D%8&bdE+b=e$3a6zb|{ z8Fyjp=e!Ef7TgQ|_3mIvJ9-@c>osJ_cJyzc|Le7om>l#@8`SGRuY<(Qg3uYoe_l5g z!*%ZlG5i56VR;JqX(gHR6!Mp`gsoxvJ6XckF#UZj>PVf1j7>i;A~X_AztnS7uW(zI ze~psNwk*F9OSmoDzndkjyY06Z(RH`|`$TlzV}36YUH6#ZUkTU!5!5~IKf@B1C*jXh zk||HZ-^vn}C+Yvh64pKG|G|>Z>?ukAFP3aa?@4^vYkN?3Vrp$rggC#6;VgDkv|UN$~Ri$e|{?#HR{@rBk8S#+i)Uciu(H^G8a<9KgkmA@0a?GpD(z_ zmGmEBNjqQH$DDxcUnTv=ShAfTA#|^#q(59@rkquMTFM_QF$*Bnr=|Rf67#+6@0a`2 zB<2)^VlMaRvP>~5;{MJel(4jaNTm2xxQ+xV<5!x><0o?^xvYO1i|Q{bPg%d6is8Di zMyhgtKbEkj<^4@8VSioYZ&j%{=M6}8jsKlWm6@Zi^WAAY5;FaMoj-sj?fiu!Fttxb zf4CCPXAAPF=-)rR;P|=GAEG3a&yD^pmdQrr*YRE(Qr+ZNe1TF;Hh#u6nFEkp{PrU6 z--P$kAh-E_SyaFO3c1~%z!L5kHT>x!>k6saxQ0JRNoMOc{1q%=Yt-~NvxK9!raxl_ zm1l}k3&)F7*j7z{4@)@e>iFL);g&aF!IdTd7)#jlclz~Tq~C7CkU_eYzsgHgo(-9t8~K}A z!darR|20ck!p8phDpe+*#{S{+@@ee<$r9GIiT^K4Si&ZLawcs(%(;nw5ldM2CVnv` znG!bfuVx8zZt7pp66W00zn$f9g1)6(3&+!@J~o6u8-gsX7?bForhZM13D1d|`t?~h zB*U0SEMWUlw`$1X@U_<~d;FG%(D1*s;oq@6?O)IQkMpQiG0 zeudDS(A1yHGR2@TNM?iY42r2B8w(!CCA_U3ILfs0cbu21wZB_Z>ElIf z|LaJqvM6(F|D42>z{sTIU|ZjwO|7ANP>Cn9>qB)+Y3r9zlBsE1KQV_=g|%qs7h?(Q z-p;>-B|Lt$^RH0C`A~V<`FBbT&Ed554t}#p47Gd*e-}%*t$X}~EaCojkN=(IqgTTB z_&>AY7v-=vM#jcH{t1cEYvYdoS&6w7t7VGm=vyyyYh>EFlV6S{+*W750!z48cJ?c? zgeC0k*SH{6?F&*hx*$~>mb9aP9jUY5S*6PSI#Or<0g2J)jQ9GFN{s&HqkH|q5>xk# zx_;QjA1N_SA$0w)i$7k)@LqWx`l74v&f`8cKF3=97DzY0hR7{j)%}Yeem|D5H6HW_ zvV=4CgEH6UdV2PI&>zk*>CCS&KIo5S34e|8L4TseOvIR{->U2BPm`Eg5c;Kf6)x&<5^HM$HKX_iMNBoB)sqRLqNBn{3rRwbuX9-)iw?A6NIQkr|w?CdG z+u0{;w%-0^7FCN5$oWx!rb?A*jXwUXEMd-l{Dmr?NX$Dd;Zd)T|E`kEQLm4`fh8Q_ zef=FQVa|R1-7M)$nfv-*vxH^t>mO1v-11#f=6?QfEMd#{_fNBgIrsPfR{3Pg+}|(s zY9aJ#Sf2jA&yvpk4nlvwI7_ype+QwzUs_`HZyXHp%S+52%!hOqFu<=YG5VJy9`mb8 z%#8jj<}tsH#OPl=80a^a82zgU1N~MKqkr{akl#^a^sgQa^6!_JMeEf}JJ^3jV(5-4 z%}9g&ff93EVutv`B}V`1!4UsRiHYN08_l9a{fQEzfAwIfKV4$cKGo9f{GudN9miB{BL}51#PXN{s&1gD3n?B}U)38t#8CG5WsMaQ`cb(f3M5 z_}@v4zE?8B|3zXdWUHgYNdJVyREJQ1jr9MK82zgUqkL;Vjg4$a|LVag-(yKT`d1G| z`^6+i|LVbL|8j}Zzj~1EUoA2ER}ZrN$|{D(AeCEV6nKWibCCn`2exb?BV#}bx# ztbfS`sY+dt>Z%J;-FQK&TUgRgXWR>T2JJJ}uc`8Jo`6hdX`o`b7JX5RC;hf8;S7-D z->ZbLNDoC!j{ks4m1&I}e{3Y5G{@9jM0HQ|9jNCZ%C6-gl#y%Z^V-3bF0~inc%;nBy%-vs{gKtz9KZ$|3F0F#hd1D zV99p$UA$@jR+b#+z-)EYo9^!s`3XWtz3KipBIYhtix>PKM2bRamUzMcjV0~qyMZ(O z(<1tA;0*si5xN^lN7xtr_#0GHbvKZ<^`c)`q&}{PTUe9514*)!7fH)rIn%Eu zau((J7psezeqEMqC%zl`S0rgFF(2+xF|+*E60;3LF|+*65~J^p&i0=ZDT}c~-&vaN z&sM1n`aNhm;?MR!lbA>TQdebX`(NsOGLp{{p0&;PFMgBi9*(-%ei@c2#y`0K^%i=0 zw%>sT-(mO)&r9M;`W$}@ORn+fay(avm^uDbkr|&Tnd>hS`5Q5d?!*^G{XHTx5wixV z7WfBP!mYpVA5!8hi>o>Ob^oZy8VJpGuluJWsYu@N?Zsg&wjk#>{lYBj%D`U8TYgoR zDaMLpxOM?q;G|AV~ie;_gX*VUK%J6XauT<+I?oAOcjT;i|d zPM<%CCA=@Q!e1n!@35@&SFou2GCoqR^gkA%`!Xb}{H-kE9QD4xk0ore_x(JUv{A*v z6*Z)K-#>L;sx^MrJ6zMuys^elu%wNA`~!`jHNMM|pEU>VtYn|abGTYx0kp#Qo5*&|D*<$y|HOHzw)<&`nTPhd58K-AzseGBYlr{Nd8u~z?@6kICeB)rYKOl? zf=`PyH!tzgX8{wfh2bHE?CqhQPdf2@d( z`Np5SvtZ0O{t^)#bI>2Xr(n!M|5=u>4Zrngu%wL!DbTX>EyIv1&o3!b1p9k7B;T(ha^=N%-URZU-%KPI+gb?u z-Y@ng<(xLk;b1|}+Z^&siPX3f`xat;@XLs_y$b&h`O&W+a@DoCzY00xR~C8uIvl$p zKlxQfKD}Pa&whQ8+bXFt|Khh0sfIGx^Km!XZ!NM9E#^ah^~a0ML+Oe^e)InnnT9c6 z67suWXs@b85;Y|`=6fuv#gNeW!!OB_pLGvr5}H?!`)x$1PkVum`_?|nC);?jsE#Sa zlAq|9g*hBKANMOL$+`x2PgFjYBxW~aZsB}tu&5&}{pQqhza0yXdbeY}hV{=0zlR9j z&!s1R|MbVRWM`i5{oDUdV)S#l|N8%k=x28e1!eZDGLwu)&UTQ)lAHPU-b657L_evU z2%Zz!yGT8kn+m2Yar9HTZt$XrehSwOW{K!$Zr$Kz5&bl;8@wj6XuW#A*A3nh(a!+8 z!E%;xJbS?!maxUVU=vIDo`N6jVF~9SKd`=`x`*?R9~2eQ`)LpyI9MMu$a#*_{!u%wND zaBQL@QR!g3$P8JxlnG|Agj+8YEdRIQ*2@GNMRZNC2%Idlz}UDVC?TR_t_(U9Dj0Jm zwuxr|q=Yx%h+bACH><|um}ODIt1@yMqz39$AtTpAnnSL?AfFpDF_e#w;#bZH<mZ&{9&Zk@Zi5pfgL@?+t^0f`VIb7`TNCmatJ!qe#J+MnN+XU5m!Sfr|>p zG!Bl6=$Ix!?V<%^nglIGbWGD=Rk4CGO@qxMI;L5$r+C4bX2Bs59n(A*UZP-3^I(FA zj=3v1c4@(wy8`1fB|7Hr;FySB&)*#wB@4#12#$&9m==Lis$fjZ;MnB_x79K*N*9c2 z6`UzkFs4=DTv0HlbujeGf-$Xw@glm+ZGz?H3dXbvHj3z&w!xaK3&yk!wy>lfyNNoZ zZx`%h$##lD=sBx)!PhD#b1klY@Us$Q!#V6Fb#dn?xTHMgoSQl7bqq?1=%Zf8ptOiS z>U9jti|C_X$KX~anfFsV1~nx{9|t=H%|!HZuv5@aQt9Jz=is>tT%OFayGt-#M8DC~ zC73Is*8p9Ets;7z&^;(|4ds)~-+En!8Q{SnPh|N5tm`0;1h-tPwxw4feS#VydX>^Y zxRWK@(7#bQC}_hHz6UfYn8Omz0E2@?ENOhhORakc2gg{#eR*&&t0HYZJa!Kb-e3vy z84@gK!Hk5};9it@NbrxO(qm&tQ0B&h`3wmvi|Cl4!M-X5V}=GtM0CvKfpu%an8$;n zB06SRu(4{vm|?*l5gqeHu=w_ZF;4_*M0CvXz^Yy_W_VCkM8}K>PM#MtA}CaYQmHl4 zU1?m|4vHw@@l0#cQNg7w;dmYuloHY7c~nqFM33iDL0J(!o<{}OD#?uJQNfK8qsQ~; zpsI)-&!dAoB$Xb|*+B!5<_pzoIUU?3qQ`SOcvwV_=dnS55j~#A1w%#jSbZj#Afm_W zv%yXlwSLaSXn8&uT9aBV+t`9JPx3-=P(+XCS;6lt;dq`EoM8#a>g?c9?SlO^J2=h~ zj@3EAKP>nSM;Y^Tf;x35RWzm7B;nEgm7q9FSkqU6 z%UROK6$t$eE&obTQRG_>?`T3^4ek{A1W(+P%nw?NTze(H!h$|q5Ofi_^C~5;1#?9H zcP)O80x=7Nl`LU-76t2B!tyK%wn(b?EUdhcYEiIDq!G>{t3qB6_KECAd1^u42#zV? zBS-_to55c!;aSPzAl9s4Yb*{fVhOjtIJlH0ZN#z4eX}XvObD(Jsev^g$=g8%maqqx z1SRh(*z!w)iXysqmIftS6pUFKT+I@;#=F5yEMa-x4XUxEjebZ>tL}G$W-Q^>mjxAC z70h{Aa4Sog^YWlBOPKTWpb1ObsDpN8%pH;z^=jF31I4G$$*m$cKYt2=G)t1T=Zhdu7 zm?hl$>YxNm+V~V(r&OzhS|TfunB@JSt;kuFhvb8xH%plFnqVkPnDd%ow4|Dg6!)SQ zYl7!QuEp5s0r^nQ3sfpPEBPpMra)&C>#--S%?O=MJc3jkGeTz*qaj;@8Ju(2%Ugq? z?F#nA)*y!^EaA3b5=+`BDl^iy;0uXOm zzik?izx{sy*RNjJIiGXSJ@?#m&pr3yb3fnYeuwHxm-=^pIaAV}@bCQ6?`G-)9!C+K z-^@>bFO%oZ{31sYo`L+5A7t_j$@Vu43wkDJ3t^9v6CEfP7^EWUh-S)ThryNhE z7ML|Souk?F?fe0zq+9WJ{@7WWlHbnX%Tc8EckFNm(9tP^KO2HqlldM@{c_|ljptsS&kw+gZZ^T&g2=)uXhyT zc|SjVMkdeu`2|c#_xlI=J1`|}=MVCCVaftSm!ei+?0k?v$;lDPALiGbnJM|h{5nSw z9uw4`mC0j*CPxt-FF0#%CXW{^bQIwU1xwD(7M8H`?($&(DmJBsk+1+5on z^5g{_jv_p%py`rKo>b7{D8iE;ti3doCqMWXQ__AI1RI!=9`8XgLUN9sj&srA z#VnnRgY`^F_fBz8e0`=hii1)|5sU2{l;4=ivvW}8D8jQ#P}r8qvrDiOQ_@!5H7H@q z0$we>4V`xlF3sW@A6)HtPTT<}uCUnn;8sW3=Zm)O6N393WyQ{xXZPSyN4aD-%Tp3O z&6IRp{ZjA`rlj@xQt+B9_2UTc$=rxvuLw3e%D=I{CUM>afnBR!j`0F(qyJy@NY$&9vCw!2?W5*R@aZC{q>~@v(h^y!Ny{ z#n5n{U@TM8l1qc|?U|BGgF;7<{@OQ~bVnx7zQHs{5uPsxgUd2`z8oa)v=rglFDUHD zGMb`;^66im4%lV?(Jl%ojGds6j>FN1?#hT4h$asU1nVe2G2N($T=vuqcfA|pkRfg2+zSmup*P^;9#ty z2+x$DdQ~RRl;A|Bq`h})@Drw_ePe3ybEYgXN2BoW@Pw(s5+_F_9}*09WlBCI$a#n; z>HEE32?{NRchGx7&R2rHhEV9eXL-;xgfa;{hX;K_C{sY09(WJ4WWA+xM3A%;^VdJv zlcghqeVK9z|J}*MQ0jYq zNBLG@R+HpQ%#?&@P6f}5V3MO8gRh?Ff>IsSGv%^)b0<#8K>1$K$`qVX9fo_3pnO00 zr{g(v6{LZ3Trl8x4mb(>FHn9E?Dd#!MX944AJjSu{k|W`nH3B$<+Av(xD7>eW(VdE zw$vb^G4;+#LAj$8K@R^SVo>WS#g1}v(CjEBj&f?y=_t!4SWlP}gr9I$O$y}+N4a{O zP&%HnJYShCl;mG6<<9MJ9s_;m1hX7vENn>noF07rY0D#CR~MY_DCA>zp;TSa&Xn|M zstY9RPY+Ylqp~hoy9v)LPR<)xtCLmhf;SxHA)Gl7<&5B6N4X8N3{id(_|LG; zJa&Eu%9+8oOi7=4o)r``{s zvo~3R%+u8ctw2hz#jR>pyBz!3P;%+ z{k0a9rr?i`@=Np=Q7#C29pwk;ua`mjb?~C2Tmm`&0_DP>-%+;5soDT27X|MyC0+ZX z;6ul=H_k4o_C-Ok&bC6@b#d^-KQh~Oaj@1=gy)iA+Dn-{mjuT;itscCRj*|7GzT?~ zB0QG{Mg5sPmj)${B0QG`#sA9WxhyDk6ydo%IPJeOc`gs;Ig0RH5nS{}CeIbY5=Rl9 z#X;xBOrFKTV@yf+>6O7>nUc2ZmBI5&SzxLWt!a0BW$a25X!f|M7Zz91cEtuyhq%*Aw zZV#?vioO55J4)Ri+~6p5|CuOv1a~qe-L5->2bhxfu{(oDnX@6(;P*3RtDjcOrDiNp`!@Ts-Sm|OrBLizoQ7xgF*M6nLG~$y^bP0UBMF* zGkLm#wT>b@4+UrKlgaZ?u+UM2=iy)jUD6*CTOJPL`&x?dJQAGsWNy9GJ=T2dq-?3qFsbAtq#Q zn@S1q*9AtTRHpTLjHKZ)xQp)Kbbkt_5UUbFd; zJBGrLdDGc>8p{uvdhRdJWIw-;-67R;4C~_=d6xEM^MBUQ(#|czkjZXeCVzH5?6xnp zD`dXK&@;AQ#IC*>+hE&m<%IY-2z=8vdnkRl{tBDN28b_Wy4X*m=FGLY!4<@`{O0?4 z^X2f1NoId8AJ_8YH>LelPe|$ZIqfgfU!S!9#IHXqDE)LY#}m(3nB6}iN8dF6v-Yo% z#&=&c% z{J`VEcjF<<YTK@_ySPW= zm-6j+_FQ{Je`!Cy9m|Nbo)P;9%+43P%J>|qKeF?syg->JQrr(A{3Xov{6X`^@(*k~ zvgQ0|o@KsCL-DV?Nfa+b=3n?8kL)h=G0%|xA+y%4EA~0SwnzL___E;(_=PX_BZeW9 zc-xkjxH<2sQL;sR}Mlu?JxOL9=c%9>${kYv>b31-BpZ&|N$3AVn&$)g-oS|o0-MZQOfp5OR>%6eB{hwY> zeNwwV!hRew-@KRX=^6W+hC<&Ddu*~t=Cfy{|1AvZIJ*t!@+42_na`e)XMx{kJBIN0 zajiXt{;}=p`XRd=R)5h);Qt(b#qY9V;Tp0d*4OV?duEO+U+GdV+g>srGRsN4Ot0Ie zyuc&hvh}vPeU^R3-*M@-di)(<(NO;i+}W+i2!=o>ewr_&e70UA>2np=6EgR@`lP(X z>FoHI{VeVH@aI;~hyO`1Wd7*%?s~#Luf-ROw63bc+b3$z#(U^F9e4J5z&`(s*ZCoH z21Cz0u!QI#v$LB&?DKH+G~Z25k2i2KNA)aTZtb))_GR)+l<(mCOVZ2A5363nXJN?v z{AaeD)z33R@A$o?XFm)58*V*V%_%aLB2>fxEBv*$agH^A@aJcap{ z=GmJNFKK_X!-Yf-oBiB6cNETksa?;UW?>GmZ$jn<7vH3xJ}Ru|eLMDDy;h!a{qw{H z_F39{{w(_}`{g(OYM=k^=5gWsnd8f>KV+7iYxylbWWMd%Ezg&__-6I-%tPE?0z>9! zD{Xm8muKII{WI%J``f3bi~o|}Q2*@m=FoP)KR~Dc*fI>6YS(YVH&ib9g**$id};cs zXKg(e4o|n`e3h5o{%2dQoVy+-h<%b<&ppR+aZ|e;<>u=j@%qIx*-*}p#_>Gko4d{< zxnXn8MFc(b>)R~6WM1a8)OYoth#oShF0uK07~FIl}T47vLK zP3o_3{wnPp?e-@YZn{p9d|4+A_e^w}hs6)G?8KmDieAnW+-_3(Lao<1GF zxk)`LdLH+>)!WXu+3SXMoS(*g>2-+kdmm7FS!bmAMgHdvWgOf2*fX*|l5rsQ+jt@R zr{{}Ix~J=oOnNrI#GUlKB)w77nh{9A6b^~$rXw;pAGNRJ1~r}CDL^I2E!^MbO!_;~W+*Y8n#a9;id!LWIl zpCjh)H`DWQdZ*iI>)Z5s%W_FJ{qxLk+&cMkw~ze`*B>@hd7mA@&oq!9$-gwe&G%jY z$a>oNa^=x(blpViklOWirO(5*lC#-4kG-8>a>@jlA@G@sn%<`)ao^Q1hB zJ>^6hhaey3*|pQ4w|m*+I!K2KUZ-N^0q%>h5Pa)&z?+B`jd zE;C%dw14yYcpt>$6YnG3c(vzHA6>5Wztm&ppuN0)@SI$EPPadkFTMT~c^0PoQ=X+B ziH~xwYS%k*{$-oP#F zc~m}RY<*Jhqvl7967F)-S>z+3q4opq2ko{ZjlU-A>U@ z^vLu#;Y-8e>>>6Oy#x}S_W4VmA$xB+zGOcsa%KJ#c|sR^id;)iw_Ex_=<=Kmr9OF| zBj@)bS73I1@+{}C^8CcPwq3*dmB^EGT{_1iJ8V9_4o{c3mKh&6wP)K6R=z-~KO2fZ zzvlB|@r$t8-K{@uyibo0c@L3E_suunvGqy(6+Vf(7N+Iwb+_gJq|m#^mKSK(ah|a- zWbArQ_PN8+!@7?Y{ft{*O?K@UzmWZe-G}1-6rcNr%`e@#*l_s`O{8Z;`A)#^O;f)M zznmZbXP>d&a`RWV9!I`w_03*y$~sfl;o0lV>~&=3`qDGm`NQptGS{o=`CjT3f0O4e zum3k4C)wj6`&ssNLMQvs`c2NmrG9CD_Oq<}v!RS*k(&)i8kbU!lp8LNNdA^#$jCU% zbL#w`=&j?U0F@=|@m`s}JRTRQ?k?Y&r2i z8Q=EYZHT>EEZ=bXPn}8mA#>|p1by=--am)U5iiqoI-X_A-S9Z&hs>S(SibD%On>|M zHf~@6EZvelgj%}UYO7If*_*rpF_YdSggTRyBJ(9~^{-uxF`YavmLGDlAoW0D_t^APrZX?BApYJ))eU0^4 zXHh@>AY&_`{j@Oyt)1vZu|+|>M8d`;P1Rn4Lkcq%s~S=&d&M5Z@oh@CelPaid_MWDmA`4e_2aPXhvD)! zrCWK!m&>frGw;BU$?oLOl>=?P`c-u>peM|i0A4B^^+LLWZE6@51 z#YySMYkxJ=Khx`MyZ*NRH&p&d(d*;r`%&a=$^UHoHyvl6wBN*jpQOClRUpL&vG32E zoh6P~{|K3f96dXZWIt~%zHG@ZpQistk~_42KaIV}KA%;2@$ccrQ z#(Q?Z)4GcGyYyX`lov>HKJ7U8r2Q@XW~pDEzt6ei_h6I$91+nC{9beMQ>{V(D)|%E}54F%6$we_n&I-=KAZC#(|;s$(B1@Jo}_{ zv0JwNKkc*Cd(-*p^P+!N{xF>Xh~74T(|w-U@w4Kya^$>z(|v*LD?jUcKdL;@FY|px zdcL*e)t-ORye9o4<%Z7FL+3N8|C9EE#EIe7^Z!%zlKqOzTeO~)^@zYN%_}3>_2cAk zDgM~?TDqS{>M!cYp>cd9eyiv3=P6SDv*HuK%)amNdHJW*C-au{%g}K&bUbV>|C7!u zTUuWZt$(O|vG;J}@$;sCR{bpP7)hS}U54~Ip>5yiAMYiee^kGa_IzCXkJNsVI})G7 z(T_TAti0jpv!VGT#h;<$L-hT)b{LL-q;^YvpB10%_qTi3o(szSC2>ORob4CG#iyZm zl=1%mqrIe^!^N#^I|@J9ZK!`qe`c?DrGJI~Y0KMsN8yVp>*<}Pr9%8yyb{}q<{WX&$gZaefu0~=clcAX#Wfy4@2qy6Z&7;``_Kq zpVq#j_va;NXg~d5|84&Ki2OI(Z$7X7__+N&T>pujk@Oy}{80M;jo<%${Xbm)4d)jl z`H7UXa?|!0TF=n3x~-53MKN4y#?ZerY|z z<}|){wRyg@oXqy6%cu4EwEGBY$7gL9k(b@?_V=Sgrk(Ho`R+Za*hAWt+3unC5V_fU zXV0m8Y>W{C-{h;FJ3QXK7y=mvk=q zarU{k{^8FVhw8UE`J2lhdT#bVJ^!WCsDIPrF}oine?9Ilkspj?FX11_FS6_T@8Tax zf6?QAJKyH~?xT#0z4`v~$o(wmQsoP*{|v2f=sYnTUF@7ae`G&PKa4~deJb2{D8tn| z9Q{9~&v5l-w>z_aA@fP?K3w}PUFQ3AJjk|t_H(wL(jJkw<>&M|^z&%n=GJK+Pye)j zne9l^GxZkx+4*v~aWGV`q5UzGF7;*WJJR!(`y;Kl$j|1t-^s}LGU5km_z>>N(mf6P zyBTS^mG?jIS$=;|ez*A1$0%Nf&2~2ujF=r5M$KrZ$4r91uZx>~=TSb|AK$w`Do8+`8)7;O!)5G)%SYB%HM|T^G$vsJ%`O`SO04_&@+C2 zi@!ti%tWT+`w_=a`62Kp-Xj<>XNBx{5tbj{z3}h<`sOP)S-HQsz{=Z!>j{}-x1(p@ zw7Pol;b3*0x@csmT;C}Z6z=@`ar%jwf6OleE&PD!}19fy{&(x{q2aQmQV7nAEx!9I79U zE=`wwfe$RP^;-GE@r8`&nOP3Mdz%%9t-aE}MELgdJIg_|#j_{jYkF$*|8NA>p*#6PVa z<@b5g{wDL+@0`Dh|JvWx@XT2p=R)RJ41KeJ<6YQX&rsq++COYPzLCF=B>nx_(zELu z`T4t(sGmb-M~>6J`S37$4x4{4^vs+5yBQ%DFMY=sc6<@#%WMzgCx5Ss->d&6$@9z< zhUsTJ{?p^{R2LtIizgNAm!65bzYE~A-k$rNXWS=+|C9ed`>3t&%=-w2%s-y7&jRK9 zZ23-eTb{><{9Z%Gd(}<-LHy!>3zWa>_53_*2Z6_)mia7nY8Txry8!+`>$(jLeKUi9 z|1$kMZ9yqjPpln3 zPC2ssQ2j}c)iY$~Z?N(Nid=z1%aI)U{UQ0?f-mqo#5dG_@=v)xmYJWP&%_Sda^?An zTC0zRA@{q)zIogI?!udg+I$Ps^N{?mlhr%De)eDmFXs9e~b(M>So;$_sleKkGD+r8m|3fzmf9O_7y*t^RdkMnC8p2oA~i?c9eXX z2L#G|kPTNXv3@6UT;LV%y^h4K1+Q7Y?B{Gfvd35Uv;BMN_`B4+-;lo(n1&MnhJ)Gh zM}BY2`a$-+7SH|Onf$(RcK)XE$KKOO{~cOs-_h=TPM$~7!}@91{XSB}-N#Lz&t~hr zW&W6plkrXBr0661jii@tpM2N#`PoPG`mCY+9oElU?&l>hyFcz|w&Tdc;s0LO=F5p6 z<99k(jywK`|lQJHJFIU|tp^RhspTNpCp z2lm_o=ac+9nw##Iv+K`3PnP}`KP5k=^VAOphx$$WJUV;7p8cFH|6=!dZv|%S^FR4{ zTin0c7Jo})TeB1?h16z7n*yY5kd`8S0jbSwXLc~#<9U1F+nZgGc0=09>}tM*^r{(e z_BRvEL7*ODb~lHa67yB0uOWQ{=~bj}nms_<1GGIr+XJ*c%(qecduC7b1GAU;k=fgf z@%A>`dy|n4Kq^BjM>^E3H-`cq26!0Y;pS@Zt4LonCqmjONT(yc3aQ(B)#k3yab{iU zN9HZ0jYwB}CzxNF6UW`=*R`L2I~ z86Rpk=b1~*#b&X&%v^1*L%I>^7PG|Mho^>6t7!_|XdW{+nLi`_73o=|=gqC==Fn~C zj?iz+y`ekJOXhC#E>g(5+k5~R1)LV@MA?-nx6{5FL|qww+b>> zfxZg#RiLi|{Xx(l1pPsjc@XpmL4OeRhd_S_^oKxy2xT5Z-b2WH80k^-Rc|%YGv=2_ z=OUel^lPMxkuLN8Vea-`G^>yv_FjPv-bH#3DdfH4`AA`JbT|iTl=qmoi`Q-TMfx(* zen^v$CLhanw~^mX*~H@pMAZy|jj={TgBNIyXOAyN&} z@kl>HI??-yInjF^X?yQvq*FjU73nmjIY_4?{TQhZ=_g2MA=M+Djr4P*2BcphEktTW zIuGf5q$Z>bkbaGHA<{)ii;ylxx&)~i=~ARCkgi0!3aJI@YNTtBu0>jcbRE)7NH-(3 zA+NFTNZm+}BmEKSPe@N7J&E*Zq#mTF zkp7DFG}1FjYmlBr`WsR&(sM}9BfWsM7HJ*Q-;w@-)Q9vE(#uG%BK;F-J<=OU|3=z? z^d8b6()&msAbp5rLI-*tQV7XM3L{03qDV2M1X2OgR!D_N+aird8iVu&r0tN3khVwK z0cmHXU66J~8jrMF=#Sohp)Z>QfR`a1h;$Ir!AMh(rXn4J^cAFXq(hMoLpmI38q##6 zuOc0RRDpCP($|o_j&u}K!kqOSop~BFim?c=F-jZ9SPp0t84G|-*4(L#(Pgqq#=Zb- zhSFv#He0bdip^DQzG97vEmCZ;VoMcU#@JZYwwy82ex+h-7~2K3bxPaFSP5vJC+%%y zjI=K|vziPd8`|L!_H$sXHTOx+z(Tat9v70bvl$zQisy!|iDBi0+_|9(aZWrQXd~zD z32Y5xRL2CL$`Ur&-|ifP*kH_3rL`$$Y19iAn+(1QVJb_u?=e>$W)LG#8`DUG$)Vbd zY!9ySNS9fl^_zcto|y}5jd$#Ol1ntIcM+E*T^1|0RO_(yQf;#%UHifsC^05V8c=N$ z7;6MJkul=4B`yMOfc3kEvHkIOfONqk0%dOlR_rY~)R?uv${9=H$g4uJD#hv)YgVk4 zF)G`xSchVriVZMEk_QzFhp1knB^4`YjO0})R;5_AV$F($eU+kEp<+df6)RSvSS@2z zTZ3XvinaQ6M;g-^Hm23z6W9u1tJQbg{c(7Y`ZQ?m{#E_(YG55o>rh&|zb)Q3y}`MH ztu{Bc;tdttX+r!=oZ=>db^GsB*xI`NLtSk>{#8zc9)EjB>s76K{c1<+)3Sa3g^t$m z&vIq^{dtb|s%k$<$J^w%jDQL8DTSW-DRi02w0XeBdG}py%ms{H^;`HTu;t+udl+*W zV|Sn(EsP!X3cLx}DDOl3y@THZ8^?7lXRH-vR{~pY$Oa^Dh8Kg?x`9=4ZRi9uBVP0Z zYzo@UI9aF{*kT>=i@h^u!_G`2>=j@W;)isIB^#F*vk|n}DsMvk0Z91(w3+cUF&e{B zDnWb+#vaFwW71_p{H)iF$p>wQHy5{ZM-vv0oMg_pN`zQ-gDU9)iXwQ%vY=t*bHwGw7;0Kxw)RX zg0cCq!8MFgiB@29)uwa3XJJWd+g$HP#V&eTXx9u#%c*VmqHJUQ?sj7yW9(eSrY9Jy z14gwq#_z}1HEVz^8e-kQV+2?)-UU+r3%PSWvh!Pv(Wr>Th(>nVhOt$+tFb*}E1-eJ z?tNLXKSEPWo3Pem1OB^5*-nQU*9a?`bj64p3S-W4$L*?Znri*bBI& za5U%s0(G1QY_%axe++DpN9{b$CEEFn9lW)TnAQ`i2M7G|7!?#n2mBtqT_enTXFHd; z#nA@*4Y<=rxz;Cn#)*^U2bu3!NbUwUA%5^1m_-;nXNmRVrRpUU;>5RxOT4%SqXO6> z?}h8(kHFfzWj{0KC1A_q+dhk4VA@L<6&rxfRsWmoT@Tw^k05{f5V_0aG8&h&?~aO- zE@Mxo|5Iv&E_*U|(fh`f0$b)?dI9Xr*#7AAslb+VpC8WHJ`FUUiFPdJnQt;iwZRcV z+Z|GV0Gb__vw>Nw{fsdgjmy0q!S_op`~Gs{q+I)e#cYgdrK|aX%q6@{&T<`3s;GYQ05F`x4Wp z;~je`V-%GS1~wsH;i7k8n4;~WpcRK#z}u~q)xeJ764W1Lm%=cuTByCnYN2AK6^3bj za0W~M_r1m}1oou*ix+CV(U==RTN8g8Bbj_W5z2)Zw}ZAWPFmf`B`6*&2WDrwE?{1I z^~JN_A3-bC_F9bevlw|!X;@lWs%ig{ zCWNTvmEfz;ew!Y8?5oC{09s|J9T-_{dT7V#c3e&m-S!0H5a+Jk-;H{{D7$l~xyCikXReaE3SE&F5{}q8T2=lBZC1u6I9XoOQq^ zBsM&QwS1D=@%UB7YzwSj+fl_{N9+4~9Ul`CFT9U(%qRX*ubx;HPSeD9>(vt{C%*U& z;t-<1K-v%}zPSN62U~@fQPXe3a9l8oFWGsvs@giVr zwB8vWMXpOZ_u1RwyTE2A=HTrBt%sI*w_G4I&i%lyMQ+ECmYN3-R8h%B)yY6rS{D7ikPx!_Z z#uoS{a#^y~oW%4cw)cCuEW{!Aq+daM@b!jQpe&8<-td7=7aQ-}IhP_ZNuHV@?SBhe z-;fr~T?Q{ki|k1G6LM$!60auu-$5OJ1#P1LIChoPmyNt*q1qb#n^5*$idV6$+ zD2zySEQ-j?S*%!5L`FcdV#$cur7$A9|sk)gB~4&JvwXjXuJpQFl+lVUd!9@b|G%Al?28VMP$BQ6r~m&3fiLR*>TSt z0jxYi`rQVsA|f7E6`?5g9B5S$iBeS&ic&Oss<{ODWQ~@nj-2OmYq=~%xLPe+%VjCT zP4sVg9On_E1Ump&otCXr$@MC^LFF~5yatswKSAdaP!wyfZy_?!y2N6%kDBRI@9#@K zl%O@z?OgA!Q9Hv<^!En_HfXio&#Y%p^d|x%d3HpRZ!FXCvCO|}4aOv-Eb|lCvDn-R zifzOlPV%8;{ut0Kw$E&=i@DyPoPwPQmyOJ_v}OJ@hb>Ax*NEtW*uLB+zoIp;U0XcK zC4M=NR@)@`d}y$iY1i~%g$&H@b?usq;vdDt3Gqam-TO_5Q_QB-Ay&VRHbYx9!yg5^ zP&+EagIIf$&TBaLeMp|+Z^Zg4RsgL+6wP*FZ07yO>;-Ib;wr@ZFEe)epKaOYA&QQc z?@NfvWyqc3%S@c$=v@U`B0*XaHaSZBfb)P&h_Ax@dnseZPfJ9no!lQlo9k`0*3N1( z{B`?c&S$D5OvU;SE-TEV${EtVQG0YkGHW~(Vm~i$CrV% zMt+MuEX9phjvy7F%?__Y%&BBP8QqmS2HU&|nDf4c-1Z@3uozNK0j)!6or-lS)~(po z#2m!VQJDLCl-8@*)WpNctw(O3()tw}P^^+?``1#D2QF{sw4%|UR{~^@qFt!^Vvc)H^=_~^LNH%wO$#z z2hoRpJhb>)w356%6jAIeD3RC}5l&~njfpu+U|G<-96IsZ4%p-1@q*boRGszE;>qV%Qvw<}x&b=P%I$#Oz%QJwj*66s}FP>%0Elm3|usayLNomWK zw(bPsdlQ)D%bzW@alnW+lk2z#*mT9Jw12A=t5K|0u{y=-6>DJ6rqk{w_3UPCZ_5x& z#$c8DP_<$;iq$Gsr&zsW_VkjX?MAi`h6m2)WJlT_l{G_qRMrgbQCTyzYX7#Xyk>1j zi(*Y|7aC=)N^8{q=wz>>wMv(IT}M>bdL3MX{I4S_>#%Oss#~?{R;_xpjv}qM(SKm9^B&&;+awX$?HUn*MM*!AO_o;nqJP;(<08l{N5SRMxoDPqL{35i(|6R9us~UFLR_SPOP5;F}w%pN_X_jD78Qf^CHrg{9qakEM+XAF{!iUx05SYj6&*Qf?)!a!a+9 zrQAwd<(6?f$ZBOViA`lO@rd#m?RDv#wLC@Wq&JA(FPguHWSV5=kFueU3=)e+eRu4c(3<;loH z&}w%sK{ISAur}{>*yR9Vv%|DXJ49&}OzS%dXOY0XIJKi1SXJz$*RWq@Y&Yz6X?j3ysS-SA3{ity>eL`GZDsZA|8mI;GVstwAL> zXdgAGlqN0FtR-x0qS<+)|LpC?d}Rlkg~%tVFPDXV>{CtwtwqbWYT0(JtzBzt*V>ka zWgXk0zF{$hMAMY4tzD~)-F<=q4+6ia6MqfoESJrwo6 z&$;_z9<;fYz-aYgVeo;iuV`uwv7TKkC>59pW)5Uh7NYfRQ^`GS% zvm@0Z^9O1}jG%R55wFMTjJ8`NLw8KpWCueNi04fnRXqv4mlSsiqIOp9J=(x)_l{Rx%I^StL&*kPfX5BmW7YJNqng8P+Qwn zj>;FH?9}K*SR*w9o36C!O7n8Y-EGIr)SPwCy62KgI>02{#c@s&ZB`%&#A{gU^ifWTpRVd#b}0@9KFir&g5KVnwimM7}NWq#LVb^ z|1jntV3j%Kr{%!LgsH?4!0b8j3}6%e=Wr5ZqqmfupflLG96D2&1HRS%b<1EYU^aIi zVf;3T_5n89wu1I#}Z z+T8d%Uq&wgv$R8i*?v0~*i5#wX9)Z7Y!@SP>d_xGE@$S%{$@w$%$y^ywAfr;-JD92 zqmQCqDmyoN>Zx|EJU9B*v&Ni-+)?4nPq1TuZge)}S=!fdazgQ-GBLduCz{}!nxI|z zjlgU?rT1#~boF7-1~pC&s>KI2PB!uh2A|R;u7LxEzlf2cd%xzWjKM~q-m}w6D;$@3 zwNO`wv%NiGp#xDi$?ptlCs(Lgkz&P)l_=Jyw?O8zJleA_i_o4kT#OpMllDV<;aAHd z@4|kx%CJ}xxux;9R>O8MU>VD!$Th>4vyt++#IQE6=C{dyHRw-7kSWR5kW;JnH zo7wjPEhsxG(e$A)kCRq8tMA1O3v52eacb}EoW~GpUf|pw^eSPsaoNw*^2rWGvo@~` z`^&dDS7y3e)pUlpHKGrlKi9@3cGj_eeHqpSzWVrg;IWr7CaaA4xQzV<C|8Vxy{-~Es8A< zU3P~tV|Ssr(dov~%INANY>QS#X9C+3xhtc;+Gw%Gi9`PkKLBlYv~QZ_TOBP#d?CIk zqwh6{UABJ=t0$H$``?ZJA22TIZQn-!Z;I`Q5lXaH?W1axZUftWq{28>3(f!dj>fa{LeSvAy z9IaJ7tX;7V#kv%0S1;~TtS3%8f-moinJ!K{0y=Z+jmx~>r@G+%Huz}QJHUK2RtJ?9 zPRMSeRV63+q=O?!Ldq5?UyH`3PA$bRjkc>>s-6`Y4d)%%KFQbkyl@|zEPppty1ewjMcwv%xh>{V@~1} z^ck?ygjl!Di~Y)&_n0Q9h)voHO+#!Yvqm-BV50MMEe648simYcEH z-Hm7x+l#z|KpPEObAonH`!n{y66{16qwjBNP1Br^eN=N|_QTi{b1ucJBN>ypW@p_K zL2Kc+$ZMf$OX4QfQ4d-x>qpwRCg_Wb70|miLA71Qxl%`~>e8B^UpQUDxrMp*Eq808 z;xESBz_im5J4wHm1g(N@2dzCp(R&rJHqWfHJ>8L56~%YYyJJ)&a`wcVIL5j`qx(5i z6K7w9yHTKdvCB}~cwlYb?v2*=UhL?fT3RRj3$66K)L+`Xg)Y)~u}83fD`zRRZaRvk zymAuun@qbHYsVilb|q|j2Io%3>Uut7#CJaDzWD)K#2A&hTCq09PR5DD-Ha9B-1b4n z4!;nw4_H@1qK_B*`>n7Q=bpWQzKn=$c--h_BWuX;qUdPHx6JmPpRAs*4kk{5thq`uqFlCKA?pL?HttzYH!tGs@e zN2})kgvj$^WS768tQR9|ybf$Y+g9(#^Zj8U(KRp%soQ$2E%Or!au z)Z2KX9igS(6HggKeO}Jm-w3{PwOYAatz6q%u2w5&t5KvWSF2U1lnRwnp=B%7&J|js z)O#Lp8eT!YRXNgw)heZ0rBthwnjASzrip1V{wyl|n z2&`@ES6lUKEBn<}{oG!T+1lP}ZEua%F`(KHsP+S@{Y?M9tF3;6>e;ngHk?~<2Tths zM)b+;xC?t)V98ur6Ba7AJp2LPf6(pO!d%&D7HQe!5SmD-*E;Nuc_Abh<^K75xZ?`U z-toE|SYuS)2^Z$dIyR|Tm?gJ@uR-NCDOQ{-BeWz}M`*6R!SCl0PqRU3E}fdvzM?Ew z;!s(x#GJBRi8)RBHAi`__+$lZKqqZ2T5p$PRVuGa{6q)s>!|bZ+MT$CCK)71FKbewJNWc<^2JQ?vrx8K<+Z3KThx+0+?T%qU#t3BD@*3}u1aprm6^R&HE7M1nY}ev zX7<)xnb})&Z*q~fT}!mH6uQgau64Ally*f3FceH5+lqX*Py4q|?b63~;WJvbOCf*bM614j9<{XkAJ9=d zkSi$FH)S;A$hy`_qkC27piC@V|Km?=xjm?=xjm?=xjm?=xr zm?3MFC1uQ%Bqhd{BxNsNs#r->8ZF*PQ+t(x1S_odpIMiID*B@@=6 zv}&bwYS}Kux)tkDtXHv`q|9$MNtxejk}|*bDPO;0wOXQ9OVnzK0p+VxzB=WrQ@(o5 zt=HUo&27-!2F-2I+$PO!(%dG^ZPwgo&284)7R_zZ+!oDk)!bIiZPncNq{O=RqyGb#!VSomxj1_a#N7sfnd`;rsymjZ%FxRi;?^ z5KK-DW_XuhWp9_y;Je*)l3(uA`e5|_&{0cNDb}5&oi&{lRViP!=GG|oWPA?d-*iZM zGX6b>)o6(s-qHp3`@Bkim-Q3yRmSM1`!5(Htq7ap-KKnmUBtO}{nD1L)7t74v-cw| z17E#B$)wDyeLB1Jv1Bv|R{NmXT5VD6 zj5qN<3Uw@w-Gx*B9>y+#_7?jqR$dl+Ua@tG^(yv?V%?Y_sl?paqI>Py!rq^x`Fvx} z7xu+lF2u==ISZc0Y081rzkk9kOmAOj#J={PjjS7UE^)biI#%shtEByGej9l*%5Kd0 z9o}YGdA~jtQkb^QQe%F~7)hB=b@04J?=)w47h>M0uRNhI)nkHk$B6l3GP<8<}sQotEYnlU(fDu4*J@{() zfD??_1AMQBSHj|@z}ETXod*C5=gFETso1)3IeLrco^|2B&@BdFC3-VtLhgg0U5&C6 zbI&d`=0;$PVv}ydDiv5EOCkFe=7~2IDQz;ZEcZDWt02uS)Hj7wc}2$aTkbdOZ9As( zcN3?hL>u4QI1AXi@C`V({W-8#!-v0(u>}n8?w`XB0oXF;yBOH=*zaNcD}b#FU;C_; zhuU7ZcQuyj-H$fKDs^>OnM?M&24#!YF4OrNiB+IY$X)AffVMe#a}u}SZ{NMoNerO( zSA%a+Y){zb&%mZ8zW5m4v;r$pYn0^4{XcsXm8|APB!bxctO00~qjGCwGT(PxI0bL( zb3eS=`u)t@^*5pyKwG2!vQDx2v4VdY^E`5AbBp?b&B>jM^$hju{Md7k;4KPh6XLfx z3wfbK&#_-cd7(2PnZ9wK8+(P;@>GKRe4DA%w)1ckrU)2rY9D5A{cZGVy+(JVO7mp) zE7SIt<;k}}mPTW>O#Pr-?OdVQ8{CeCsG~}0rFqBVMEwfT%JOI(%ik^LiMKzU+PtTn|IOt$Y{Flz^1Ge<8Hhz%1=tt#>gn zOS^ZT@cjXprTy`2p{)gGX;-Mcn^fM3x8Yt8>s$})dB$3=5!!EoS=uQdiq5|TW_9*( zv&PIDMBt9<;@|uVDo20W85cb;zbmIU*ed+R|Kl^HUCNVr+7w)uqil0-Ammv^I@b z_Kwm~poR7Q`Aq#1xLCajUw2{5kk=LK&9g+DR@W<0cDnweLu2BM>y7y*X!!1Z3BFqd zww$BrJHS@5eh`8&Nb!%pHmS{{JuH1~Qky5UbD`cPULK~~F=b!DeugbXW$W@}k65Rp zu~c(QHMdlAyZDwZ)mE>yHRQ?3SVNwiht;bF%i^cJjJ*u%UF5ynfiG==4fyoc?{Aq# zvk>WGzpke5Fz|IX`jXZl#rl<6v-WCnSib5m)~}q4^~T2p{z9M56X)w)=Q$zo2xI<% z+UA7nAF}r-=7d_&`&927{pA~bi{^ds*)OI1a#%>e_FNa5bcZcb6Bc>)D~)e~&wg9* zJuV?Fs^vMJc6ZfbiTCSteLvS*k5%7K^QaEmN6{VOb)kn4Rc1lT%+URayQeTV8)NII zz*_R;j%#b)1hj~5S+wTKZP#|q?a$CavNJ>Uz13<+ZqJib$(pcO zs3uGnB0sGO%WngDA^L@bzoEoLU#w9d5nZYxVi(+b-yd&A55*hLsN^>Kw?iK3-01)6 zt9Ayfib!o$5vi>zBDK}3yjta}RlZu~>r~&cUw;>3e9a6U?JU%wQW{iBgGy;oDP4K% z;c>Jt>&}xKTRkk9dT??0$MbD$>Q-8pV%>Rd$fa}OuDpjGHZ?)t&Yc2XdR4!kyfw9! zuP5(#%od09zh@WGPlCz^3bZcOCEAXy-bSwfZe`C$cUNFh;s`Qwbd@ zs}r|E(+@yPrep*Zs#b-n)yxonyw2=99d-%D-o+{xSW!w=xs{g&?QJRu7kJ6N!c}$JaN_sMEfZvos45R%~SxQb3+oLiT%2E=G z+oR&`?NRae_NaJ!d5ZSfbnm}BRXN$1qcBFwQ}R_n1?xwnu_{HsyiM=pt5Wn^_;k0T zDkZ0bRVg_gtXA!-Qglw(1bI~{IVY^v7FBDD#w3quL~FpeG;$>7yxSNnycl=4fYqvn z5{W~Q`%TolH1hpb7OT_TZf$wDwzpf`+pX9)LrT6&Xh{8NTil(gAewxa(4cmn z=+A)Xd;_`7F&Q5XsTdaR-{BHuar$bZDJ9xZ^i$pT+u^2^Xy23)?VD1f{Y3v9NWO|B ztGBnPHCogLjXrtFYVbAsbeH&fU=6b{YYVlUKcw!vtP06k7R<&*`Tk@o@QLdbE zx2q*PQZ(|`qK;0+=OM{c|JN4xe% zyY|Pj@Kvz$iC?Fc!f3RO))C9X{{)SG&!b%L=JjZA^{NKFTCeTZA035At=6@(B=ul( zRPK-ts>KJ@;)81OQeIh7+%1b2BZ?9(lB2|6>NH>!Pm}pn+dR;c`J!_&|M=~!2H|{JEhY15ypaaUd>L=! z_=M$hE=&4Ri`u*w&o$;{(AvDSme?C*g{oCyK8=04Racn*0CFj^7Us))m%@CBtc6?~ z`D7v2Mt5C`@?~@v=1bfy%9qhylrN*ZC|^c*G1qp`H!usa6ne*3th#jQy|0pdn(4@& zOYq=R7ZpA+@Lx)sQnsL(+0I)18YV1 zjB0YE_Z#w`9c^dghWz(2axSc*vm3gddI_+G{Kyxvl4k5{@S2+#dun$nK{`{fHsoKi zvy`P@2KYTodF@1dZc&pXepQnrepQnre$}k)Xx4T#Yde~?9nIQ~W^M=FZ)#C5Zq*Um zoZpMtkJc8J7QyIl&i^JN<_^aYcHT}lw>f`3+Gc6ej@EqH;kM{lXwk9IqGO?*H9Z>g z+SS9_wH+O-J-vnR&=z&%%Uk%4e0lfYkuUGwJG7Oh-b*;Ks)OWGFMl$Al?zx4_c@K< zmK=&N%Ry_+se|pQXK-5yZR7STA5Pz}5~MSu)|`SJ@!J?E(W&}%vQ~6QsY`vlQ!U=9 zx^${PcXBJ~j#9T;yjQ)rPrbO4M`Ob`5sTG}JJpLj)r7r6szw zM7NgcR=#fK>sG#AjTVF2%0X>gkLHF0iJ0L);^Y|qhLX+%lYz`f$$%n1-JB{6B!(pe ziBicxB7e2sN=yb69Vu=k16h|8Y1wLxO(lWEwNlk38PNE+=~(!rYE`a$6+`%_-}=E< zp?t|e=A&dF^Gq`6#mJ*bJ)rg*Q2Pz2{RY&2gE?|9V=zbVWmE-vTAM4;EX?Qf)aU(r zZ>cj^T2!r?R;zwxxe}YoawRsEX#Uuiu~T;uKI$!6nNQI7Wj#i2t~3Sr zJa1RIO~JSBv?n%=QTZjErhwL%v_i(OP5;)uhi%ptHFJyTj!m<+s9DEWv$m~SM_Dts z@_OjktgS57J2o{*88bCW838p(838p(83DD*SF3!r%2%s=b;{SSE$?8ATGXDD-_fj7 zDRnBPPNfX;Jrvp%wP<{4)e%*%b+qb;s#kgSDz9GUHE4+jGR^HQTSxp!@Gf{8+ z1iZc38`v^0^eFZPz$PZ-w`^zl??mnImMsraEAK>Zm-WbmJvthDbd>c3a;DW2$eC7;j>aAygA~1c zcns1>R&O99ua9j?Cu6;VjKSVO#$azCW3XS(BPw-l^=sMwK&;yzh{f%1FK&$%4QP}f z(8xca`W5S%dVu2#?Ii~S`2uP{XM*3qsdI`ZXaf2~I9xqujIhn&$1q^a^iRhDUiN467VG)|<%B)!vsG9_L_< zcK|=n@}@AX^$ultn)g+Pb>7z*p5;|BtoLRxoacRyVT1QWh6}w}3>&>mPoQ=*c_;Jp zMc(NQo4qp`Ug6ai$ z+T)u6FT!wx7iT!=fapPWIdMYvqI#T z5mVyN#B;>#<^Pajsee4fN&X28%lz34r}!r^EcZ`lIL$wmVTC`3;ZgpN8CLmcFg(^j zlVP<#m*H{#&luMDXEU7T|AJwyKcC@g{sM+|{y7ZK@_)s!-fv_$&p)4GgMR_Th5m&M zoBTx#n;riZ{v~*hnM#6sbT8RD1J%!T877luLH#20b_ayf9HepLzpQoT<+kL4CCgRF!cleP8&a` z%s}`C@W;^wR^M>M>Kl((efNsw&7u6#h}EMzV&lU2sO2w-TK>JFmVc6?mpS?rM}Hz} z+dV$!%Eer{m@QWtv-y)^)-Gi+YnLf8YnSpE*(HKsce4F@RLt7FDrWol*jNGUd7P79 zzw|XVxR<9s#^(u^8y++5aUZwFuu4htw3}6U1BgoEi zGd{5c(@PRx1WcK|665*#G)Hf7a0%xZnCB8yUx8WY;EN8v>fq}RzTx0o4sLYteFwc9 zD<{D)ZjQ^b@qCGUZq2dnxjDzSr#;8{Uyk#?9Bb#bIp1M@`*V(CxK}R4>j>`fQ{0G~ zG0IZ4~@x}=SdXC;s4a`j0&U$i7`eM^!yzP7sZHz!YIzV_s)4DU!_t31aGr1Vg4ubE@jx0cR9mn@)k4f&AW=> z+Pte7_T^p6@Rd9pzxwlR{92!9t7sK+@y$q+Ne#fvP z^#EYV9Le>^%u%V8Ovn3DhR3EJVOX7djNx&q#~Ie7o?tjD^%sVAX3)Ef+&Qv(dINWH_bCG{@DC8_rr zwx;lh?$FMgQ$EA?RFvTzsRYB0RFdJnseFc=sRD*8Qd=|ZN{wdtXlgr#-KiZIK9L&7 zuqRc_us22VHfGkQcID^3)NTx4N$tU~KeZQN1aE(A|7~#nH<+^XtjXVp^TYXeevRi- zyo#70-}QIC>+gK>^OzZ%zc0%z&Y#3^eEtDkelN#g>i8!ye*|wYY&}!*4`ROZ`~~dC z)AFbA^HKTMzp7mMV_o@bSN=FxzQ*Y}%jsF0e+ZYabLG!+T9geyis;t&@k#~e!gPV8Qk8RN7?zHeUx1fbd93O#p{*xeXzPg=+Ij*mOTa>mOfu9_w4;`1f-BrH+4+<1cgk<&JNffabx1s!yiHs)yD=<%vrso3ll!I#=+;@znPj>J?2d6rCsDslT zJkr5R2QPJSv4dATxYWTL9Bgy&HV2nEIPnX%{&O6B&cW9meBZ&uc9w6EgKZ8jckoFE zUv=;;2fZR&Zj^)DJGh5~lN~(U!TAm@cW||XPdWIagKs!^^7dB#9ENe+qM-gLFpC`h zQU{khxXi(o4nFSS`wq_8!OA<^!KDt~;NWrxH#!*E(ef{L@CFB;bnq<)XN(leBHq}9DLuwyf0e5?H!!pV5Ni09DLQmw~8(Qkvm)XT?c17IF}*T z!@Jmgk73+|cX8uz7xM1{Gs@*Jc5u1y?`q49V;DCJ9c zsPT3`Q#Ic1n~oiC_fgg3?f&Pu@orx<{xU8!7^mcR44vyR1J|F7fIscEkH;;~@_}jj#swWeY35$RWB04d+pyGzOMQ}nuWOcy} zQJENAA}T7bxG*swMpVRIB06CZL{vn?9hi^^f(s&UxG^!HL~%vMo%hpSQ{Q>-`}qFO zeV_NA=Q*6~>JQ&qy1Ki%x@M+klHJbBZVx%Yrk|AEPS0)^X18mz+aI&r9eUdQy|dej z>~?Z?yEwbu;h^k(v)hxh+dHz`hqBxEvs-3>K1?P{kE z3I5+k^$z~uM(LyM^?s_KpI%IvMXJxI{LMNj6}$&^AQTbmq`LBctRL&Dx@W0Gm1k*x zH8e}Tq(rI2%GJr))FJ8&p|wxi`i7{Jo_6%=0!RBSbTs8zOC!`4KDqE)FiMp?XQ@&h zl%=uim@JJ~P zUo~WFsex=QNlC4j)Rd&ACAC3P8zr?_Vl5Km&FJht_~O*(DS&LgsN^e=)R@G|p(pg-)LaQQs)L}KfCfQH$(NE? zT4Jjpd!;iHYk>|8+Se+nygip~sR!BA0?3x_Av8!R4%u^13E2`p*%DPk3CULt*>g|> z*>g}U`I3^aUh<_NTk|~0mzI1Dl5drywm`PTMyOwKlm&cZY+DtDY@547HnoSO#w4}B zr1D+0Y}vS^R!J-&u@>kXbu!mO=eZKaLS;e~LN$;rkrK*4_6)T^>(p7)#~W#`=Ro$@ zq7o~C8r7}ji%Bda#EYD4*#hWjdzVS9hs0tMtAP52k7E?A4(JppDXH~AYz(oq#2SLw z6~vk#yN~7|Rzqx~#55C@e&KtFMIn2X#X+o|Sa-;ljY+Eiw-x(^pCPpzir8^YQY(Vg zrKDCu_PmUNY%K}NR~_VggM9S?eF8NE)Cx5Rv<+&3_SgP1fImLXe)IUWxj3NCPzhvH z%YxWm#L6XB5yW~Es}86fst@QCs1dSPx;coQORNQIRMWX`KFtWOj4t%|dl{)7^l=a? z4q_9Dl}M~Ch}}V~BA_~`8d|5GhU$aZ8&E?)87KqU`kI4$KM~Ure{Y3+;_gBA*ovWb zYFA=D^$Q;ll?5~sstD);s5+plpc=>?TYV6_g;+yC4?@iWJqGC_zrMv#aX>4fvVcB< zDgycjst)LPs6L?Z2I>o_Gt>gvy(zv^V~;2*6ch6QUR%F#2_@nZs|aF;6H7>}I*1J- zRv*yWP(wf$LCpbO1L<~teUqT#fbN6J0-6QYL$*IR2z77odg2(NCZUZ&<*b3RJ-Y(3 zwNygu)C~GYwZv*9mJ(`#Y}xW1+}ZH|epI7cO-O6!dKAtQO9=#F~X#pb4c1e95`r(UtI^38hC9^Z(|MZA-DFmI+l! zYArNM`!hG6Y=5bjeDfsLC!5+Jsd^{3-vTJRH;I)A^_SE^kgcT>T3tGbmX49sDoORp z)>jSLvr#LtdWof=D@sqL7N2I7p0nA~&83$KO%s|U^rFyeq2?^DF8u|XEqiMcYKClE zTA@*PBxI$ijro5C$i~VfHVCrEQ6*F>`RXNK3Yt}FTDj5^YlK#pUPf#cWNU7g)K-c4 zWY4K)6_{;{2hA#-K-mJwmi5WzE0%mE&=sY>lCOv4^U3BblYHgStkNUCVHGrFX9X3K zS{bCyBehy$H9>6GE%Ym>T(|kvQk~u~Vq^wVMdII@; zO6fUSx;uD>#E%Wp&k##P_8c@qvr3<)mQ|2#flqb%CGz={(wnk0qubUj*%o9-wY9WB z6H0ggmU}gz{e_Mc8X$BU)Ji_PH=pYCc53!1rH5{_G^5*@S+aZcSn<_WS5eld38ntu zcPW5uEk4!h1SNc$AKa@xrSx0b*o*)~tbKuOEk4!hGbrm*O23*VTT3Oe<)vp)qDo5m zRHxr1pHC@W@Vli&!BP4#Teb$8P`ZV(wUFJLPj!07-)$_VkIhoHM@YVTLB117^(m#R zvy{tckFAl^38m@>`UYh8;ZvQypAtT$^ePjz}D`Fu+0egCv%OOz8^ zUOJKzgCJYNr#gKc`Fu+0d$MFpR0bt(rbLyL@TpEOCZA6!z58F5ve$^1En5REFP%%- zTFCCrr#gKoC45ThOR{83q=FJ}QevKz@TpGULO!2Tx+zODx^2i(son}T24#Pw>?$ei zQ=Qg-+gM5;nI*fomY~EgKXPTHgim#P2>E>C*#5C(OL$%VJEfcw1yH#@id3ICe_2XN z%$D#|?RhDImX{9siR&R{eX7$}Q`V=Ho|z?E){hO*{<|~f(5%vHDLV+V`}L_#KSv3l zQu>oD*|L6Yi2jLKm6Y(QPXC#WrSz5CZK^Hdrw-9~6RUxqEv;v7wNlonI$cMqPbnQy zIv`utj}6fW5Stg2=$)lHU7n?sUXdkR!p}EEuOrq7-Cf#iE7wTM`c$VsCDo^tzDirN zW&N0)hqX!xpX&5&QkM5FH0$X5Wm;r$83oz$>&p@?n|mq z+=E%N`D%zwD824y&b^fIsZP%!pHC^B$M=AIvL)t8KA-AzH&T5{=?Al9^R1G6KGB;< z^(m!Cuo}{*T)rW?idd_Z@TpE;k&UHvd;WTaAG0NVvLy<-`RCa`8$Q+Py~*cON{`Hv zE#b%PNZ3P4_*AE_BcD$xJugeP#30G%Q=MKxs!u7MY-7phtCD;^)#>L+^(m#h^Q}Rj za`}enGGet-!lybtI2%jpyR&3V%qG>gd7hN;sZP%$pHDnFSqJKqEwM`S`BbMXNcAbD zU&@lr*Baz|kC;z&`l~FZ^xpguf*-T_3U>F;uAk4RIz50?pHg~mmTbOaV)i-RBPg+g zRG;XbSxV{7{FaX&vn705r+N}AgKXLUkUic(5LcD5KG|A)O6iLz;ghY!r*&#Fu`!S> zTLsy&KH0K9rSxm$^U0R=X`T9nSS@5r_{1}wmApQs^r>00CH&YrRYj~GIyrddH5nDMu?DECUc~Fw;yqj~RYJ8wB~kYpdlh8&R#xoJT7^)_ zp6*?jvhFUmKV(Z(K(@`5kbTXblzeHSjgT!7+RITfWUo;fWNR5CsntT0gzAMtd%Id< zQ1(hoEH1HTA+?Xor-hAKQ0; zdbnCjAX`g?P$Tq4FdJ@xY*}wVmoEg_vs)suG9mx_u-W>A5<=BNH9|?DdZCn1TBuPd zBh(_~?eF$mE>tO01=%*&3Z*2qQD_xZ8oWwvk=RDamTiR^_0RNspR(_2NUC>$Ye4~I zQ+=`}e6qDfC0~h94`_rQ*N*W8vSodGLw`yvCi%*R20i&Qfb6`^C!1O#sXZWjjeN4H<&ru`Vm^(~)wHx0vPYSM?7O}ZIM{3#B^^tBB27v9#M(J zdPuBHV&y`EB((yvEvS^#DoL%DSgpiT5}PNnRYEP2x)HK9w@Ru$+{HY|j$s9mZGExC zN`%UU%7rS0YJ^fk^B`Maqr_H8tVLq267$JkbMFXg6=ZAaAyfw0BPy4CgCw<5VpS5W zkyx$7QWBdD+4|;5YLmoPNvs93=c-j=-jOa=0A*V$R3@qALjG@D+Pw{ud=-*fDO4q? zH4>|p*gT;INo^EbC8^C4YZ1~%xi))3B|tO0Ba{+q6lxLjN?m;gkbQ5xL}EQ8=F{L{%@S*om=|*`C=n_biVIZ=C4_2(QbLVF zEke4?f2F>D1D}{c_S{E>N`zuU<&b^tR}I;7kdo9^iRpf>z8K``RnIXimsq7xLa0V4 zDU=dw6lxJt<$lfEso8^U>x+d-gvx}E8`nZ(M4Duk+q>V;B54MMA+kAo*kt5Crp7b}MB_3a_CK|*oJ9#NIVY9U)f4|b^q zkljbI#L9#!gsLQ8wZ!TnTVI3FD#_O@`C27bFvRW6|MeTY-xy?DI!I!1iB(CgR%qUT zp==AJ#41Vk$)+|-svhe0Rwh&nWor>C9_I4JAluRg$UgU*AzMNZclnAT8!MAog;2Fn zy->w z`#sNEM9B6;b*d{Hf@~}b*-#H&A(Rwq z5YnSuiDIEukZoVH#9Ae$&vGRSAe*mPVm%~QCb0^kYN2|e2BBu5jgURN`fRtiVxcmj zNsyg0)Jv>Es98v#Bee*X2~`Ny3#ElJLTa?DB`Q=bloUz}WrS4Rm8}peu5hsg^l|W{ z^J$$*Kd)3$Vm_@?+lZwDI_w43fd(`lQs?@q3!rE~KSFURTc1!;s2;M{twE@w(#5Kw z>>U7QYZ>FH;X;?%ETpSktXQZ_s6wb(s9vZ+s98u~B=rfE2~`MH3)KrX2sI0BgtEP9 ztgAT$*;ui}%7pq$YK6qcNNkc&lh8(?(8aFi^i@iY)xBTjmsYQKXEzGjvzvfCeHE$6 zfM!GKfIfvX0kwaL>wAr#uMCPp_PWI&TT5JMjHD(cmJ~`0H9=kV{Xer0iK%N{eNmy9 zP+TY>GzsD}NNPz+EF+|@llp{WLUEylP*Nx@lo3)Bq&}gTP(mmvlorYesq3W{p_ouy zXv~dr1tCw5e~EJy(8EyZCO789AWyF)mI&x?s415^(LHhEkiBlzkiBj?;V3E;6RNIu zC6YJ$`#A7r`UaG}FNIW%i$#SJkf+a~L`Gt2lH?PL3B@P7)C!@5P_7)F9L> zq;GLG7Yj8{ak1#Fj$%S_p$egdP_7)F6}*QnhYx6++cQ^+F9o%|iM%S2ikC zEEE$e6N(EZgsO#-LiIvvp$4IhP_vMl>e`}(qC&+&F`>9ng-}AMS|}-$7HSa62sI0- z+g)3tLNTE-$oBiV#Hxkrh14B>k9~+9t0CLRi-i(GNuhe7v`~XkMyOdx-RWwM3dMxV zg#5onWLr=zq^G&#sE4xm?_G{!kf)nyeIlT(P;$B-JKz<@?7MwB1BwN7Go4c)Wd%40%97n`wc;MAH@av8`qdpCSVo9GS zK*@j>KpP>uw@|%%a{6RrQHc7;H%4N!C7(~(va=lZ7m7pnh!R4RBsD3q2B9WNZ59fp zT+LC)))y1%FR5{fC4?qPYEoipp(aVqNKDOk`v^hVb0D$q5{pSJE;J^WI@i?_7pf2% z1KFAr5~~(U3e^iW2sH~O9(Vgl3Z;cILTaAN7Zr*L#f1_=Nue=MxR$CX-PjZriV4Mq z5<*F#v`|J!Jtg%CWrSi+^S9@8=cT+-ddB5T2qlHmLKz{o(3OZo+5RV#e%8e@LQRX@ zz2E;iN8J}Ynj|z^C=J<~n9nLMSPe7Rm^z23KEvxub+o6J$r= zSfk&*`)NTO`q;jT7D@-H%Sp{hOf|WDvDaM9aiN4zQYbBy5mGCpEad4Q*hf-gX`ziP z{Z~pK{LFb?<=Q++sQYSn#`_D65t<~FenaxT>1v5Xp6<#S^C|m05=uk14`qa6Z}}yL zQ^F@(A}*8&Qm2sWlT8i1?e-gmY<=A&7L!<9C?S*9nLMSPe7Rm^zwNjr@Oeijt5K0QAg)&0wU8zqfCKMOq&7ACcjtV7( z;_tcCF;I4tmsnCLEz~6W)cdY%R467C7fJ{vg=Rx`Z)u4&2xWxS2eJ>L?vO1TlUQ6R zA(RwK3uT1Vhf=dpOeijt5K0QAg)&0wBdJd)CKMM+2qlHodRI37v7>}gQYa&&K5_Y? zLNTGZP(mpEsVk8Y+6dV*>Hjq|dpE|RY(L1+2LC=!`*$)F2|klc2C?sn`DA11AhsJL ztxq9nMo4`lC4^!^ zaiN5e+9D-{VmbQWrN)I4LP?>tQ0xa+BK@P^UvB1_$F@og^7L|IiJx68DU|rdPwlvz zRLFkTk^Ie%o$AN_a3vCd`my_nB?DRwWdh3Md942OQ;&sWfBSSD6c1=Ilnm%+C=<}Z zJh#<9u4bQJu{{jpom5hj0X+ew13HYSwc75d`p@!oK%YUGfI6=rRq^dBJp_sdbTgC) z=p`r}&@WI1vi;d7yWcTdyE_l^^btJi72ntL^o39evi&6*#AXmnc&?Th-;wh4n|>^y z?NE|$3VHgF*ZEdAlTO!G~hqC+N+b^E}ofaelI&2kJkQMs8(uC3hJ?s-J_snC6!a zXe|^!(2sRyE|d&tB$Ns0QAi!+r?x`TfNo$06bq;WGnRNj^-v<9L)TDCK+B=%!G76M z%p6$e4$XyP0sRDx;m@Vn^VcNQ{b(1PB$R>dacq^(TZ zQCui9(8bj8j^dD~`!Ww517&-nP$o#djMVOfTxuNh^de%DB(_ng|6rFdImFNRGx^d1 z?av%G6Hp}-AL^&h^kV^i3Pp$cu>xkZv4BdUWIz`}V@`B6Hwkq=$;BoKZ4~N%vP+Gh z?v8g1l)Wn?mJ~`0WrWlju545&CKMM+2qlHmLdlV?mL|ylhQXvWU0Y^DHr9QVqyA?( znhn`DZcQJnmAH6^^3kI*JL!g%Uz(p^T8K zbY-JLF`?)fml_j_3nhe-LTRClkUG!R5*3OG#f1_=X~@&}(wm~^yRtE%jF7s(rACEf zLdgqVYFa2Gq^cxUC?ljUa;Z_F^jH_m2&s!*EGiTeN<*Gr&2gwpB%e@BC@z!`N(#j< z^=r|*0#xIqmdhM9LAE!k%l&+%9nLMSPe7E0dW%BF=fLh44B8Wl?4NnTU_r9O>q>3vVBM>DU`m|rDlXwt&2s4VnT7Dgiul_EtC;bw@H0M zNujh*Mo3L{B{H`=Qg=8?K=vL?PIEI_HQiAhvd5bcN(!ZgGD7Kl{X6+`|Bk=U)e;j* z2&IM8{gO{8A(R$U5BN1NrRL;Au0&cWI>W_cLUExC4G4+g}`UMmV=qTPZOGDYVEOZnT$}DoR z=yQ(JLh;2e7JboC9P;!%)T~}|v2>1Jb}{vepRW_|)uo|q3tn{;6G{lBAy3~yiRcoS zFD{f6$_Pc5Nc?`lvY zw%WxKLTMqsZ0}kxln_b_sW&B`P(mmzq~4NzLK&e+@4NB2Nl1O*N`xRgddDP|5SlHi z>LXVoCX^7G1ld|<3#BEsNn#s?)OuH62(o3n3&kY0zr@A}B_uU1l=#GrDoG*!D409X zLJ6U?Q2aAjHod`>@PAg>-fuCXgiu;YHA_CBgiu;YeIfaT5<+Pq)gt+X5<+PqwNdg3 zC4|yKYLm;?)Y)V|5!)yf+R?>kL-s1PQDODq6-sH9PuJhyXjRDe0JagfJ=sRt9>}(s z?Lln!WqUB&gV`R!_7Jv*vOSD#FSccD4`bVpZEv>y*&c2%wWsHMi5J4Vdu{N&ydr$> zAYPp3XWBE*Pc6yARQJHQ`x*J6DL<|Y!ni5$Lta4>p>1dn^7TRk(I_+y-GXMLmFOMx zJ?c#1-BAfT0QEv;=y-H88iSrh&!S~$6Z#7kacYL6v(YW+KJ+M>gBGDM&559$(4}Y= zDkz{Ws17}f)}sva|GIWQr+5$48y$;=qBGD^6y~%ajmDw{XeHW&wx9z!S%Xm(8jmt) z=eGPdIhupMMt`DEJN`y3>VpQM3N#j7jcz~>qfgP1?P(jDkDfy-(XXg)2hInoK$oG3 z=uR{fEk&!*x2SLjrFKL8Q6-v)9!AfjkI}d2XVk7E=N|2fjz{OCYtc=p4$Vc2&@%Kf z+JH8p?~v}qFGO~R(Y`yQ&}(QFdJAnwB~hhLLg%7e(G2t?dIN1hKcF5AEB(+J=mK;#nv5PmbI@YcfLc&1 zitNd#gGQiAbQ79_>d*`5O|%ttEa6^9-O)kaX)~IS)}b%apD41IQb(b|Xe1hsW}`*u z6SVi>AW_W*vM6+MeO_T<{3r_e{}dsKTMpCF;nkUog~=q~g+`U#nXxwdEkszOhq z#pnmr_7M6MDo3ZHN$4Il3oS%xv>E+@b~}_O0Xhv`ie5xpk?F->xIibO(dbfiBie}C zGyETm?m`RD+sOX~jbG6Yz1cT95{*Ls?_Z2XHE0fc5q*h%K|K!Ve4-yvrz1F@D2nz* z15q4Zg&ssNq7CQ=^cyIN=wq}Ebv}ygfQF;7=vMRuT8R8#Dp-N^ z(Mokd2cTZ46!k;H(MU7~jYX5tZRim+7d?YkqPNgGv_~mrQ5hPBMxh(gL+Dv_MGS9DQd?pO3OT7^DC zU!h^g(#O$HNXIxF6wUJ{pV0qb2AAv<(&ZS85IV z0{w_011OJqhEe?)to%)O41Xd~)4f@c=$ zdJ0>#0v&xS*8(j^-=Gbr(eBf^N6Gt)o2SUI-6%Sx)|MyUPT*G(K*D?31~dJ z2R(!yMYGX-v>1Jj{y>M0W^6}Sqgkj4ZA2a8jQi*WbOB1D#prYN7wT9+|3ib&EocM! z1$94{eu7>`zo5>Qj7P}-2HHdD8MG2@K#?)b!O%!_J-P=yiI$_m%(l-^o;pkADekUI zI1`$y{VHdR?Pc_?GuW0sM$c!vg5K9)3}rn2g(#D!@>Q6>8ko-8 zRnFH{2B+5)# zexrI_PgHO7rJc3Nh=4{jQ&2eeHbpr+!lXrJquN>!;N}dV$)mpXagns?uheGUiRy z#=NZx%$KUre5H!aX4THLs(sBLs)zZT*G&KTua|T$MP7{dc5hTuQt2u>&zZ{f{E%I z%%1$JZi${~y6bAQm%iETt!vCada~J9-(q^`DP})?tJz=QW)9F(O;3HhIZ)qe4${-i z!FswmMBif$)%TlT`a#oMKV%Nq51S+OOmn1u#2lq(nWOa_Q>y2hWAx*ukDh1x>iOna z{gjF61*S|tWBTa^Q?8er{<_Hw(65=}^a?Xjziy7#Z<-VI$7Y27%#75Zn~QXd8LKy$ z`}NnRUjJYU%`c|A*=CL~zZ>r0)yxj&(%IEh)r@BW{aoN;t0i{TjyjvK19yeZmn-|+ zlP;Dk+qZyMm_dD?E_U_3^0~|R-Dd9MAT{2~^E;q_iyh3}H6loz_d8>4K!1G6)5n&e zeKzK`(`r-@yOsS`1eA(6dP-=wLKnOD4W3;=K7UPzrC#$K)ltI6ia555f_&ficBzXg zVOwx(XPu>Ug#2&d*wiQPV$=xAHr4Rt3g~~o-`w7MZeh#{YB}U0*OtA7YG%0DTF$d= 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 &40Tg@BFui#J*$e#>P+* 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 literal 0 HcmV?d00001 From b9c1399ec3dde9f59fc1af8c0172e069e8da6ad7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 21 Aug 2020 19:51:48 +0800 Subject: [PATCH 0851/1029] v1.8.0-preview0821 #325 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 9005 ++++++++--------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 4474 insertions(+), 4573 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 28ed494e..8cd4b7aa 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 84bc713c..b110fca8 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 1155141a..b8ebc422 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 3a1d6d7a..078fe794 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 1841b3b0..1a94dc78 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0820 + 1.8.0-preview0821 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 2bf8b1a4..0c7503eb 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 87c8f2e7..5dcf289f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d01c6d19..e4d6b103 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 379f745c..1452ccb5 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a5622151..860b3f03 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1,4552 +1,4453 @@ - - - - FreeSql - - - - - 数据库列名 - - - - - 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - - - - - 数据库类型,如: varchar(255) - 字符串长度,可使用特性 [MaxLength(255)] - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 忽略此列,不迁移、不插入 - - - - - 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) - - - - - 类型映射,除了可做基本的类型映射外,特别介绍的功能: - 1、将 enum 属性映射成 typeof(string) - 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap - - - - - 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: - - >0时排前面,1,2,3... - - =0时排中间(默认) - - <0时排后面,...-3,-2,-1 - - - - - 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 - - - - - 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 - - - - - 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 - - - - - 设置长度,针对 string/byte[] 类型避免 DbType 的繁琐设置 - 提示:也可以使用 [MaxLength(100)] - --- - StringLength = 100 时,对应 DbType: - MySql -> varchar(100) - SqlServer -> nvarchar(100) - PostgreSQL -> varchar(100) - Oracle -> nvarchar2(100) - Sqlite -> nvarchar(100) - --- - StringLength < 0 时,对应 DbType: - MySql -> text (StringLength = -2 时,对应 longtext) - SqlServer -> nvarchar(max) - PostgreSQL -> text - Oracle -> nclob - Sqlite -> text - v1.6.0+ byte[] 支持设置 StringLength - - - - - 执行 Insert 方法时使用此值 - 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 - - - - - decimal/numeric 类型的长度 - - - - - decimal/numeric 类型的小数位长度 - - - - - 数据库列名 - - - - - 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - - - - - 数据库类型,如: varchar(255) - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 忽略此列,不迁移、不插入 - - - - - 乐观锁 - - - - - 类型映射,比如:可将 enum 属性映射成 typeof(string) - - - - - - - 创建表时字段位置,规则如下: - - >0时排前面 - - =0时排中间(默认) - - <0时排后面 - - - - - - - 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 - - - - - - - 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 - - - - - - - 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 - - - - - - - 设置长度,针对 string 类型避免 DbType 的繁琐设置 - --- - StringLength = 100 时,对应 DbType: - MySql -> varchar(100) - SqlServer -> nvarchar(100) - PostgreSQL -> varchar(100) - Oracle -> nvarchar2(100) - Sqlite -> nvarchar(100) - --- - StringLength = -1 时,对应 DbType: - MySql -> text - SqlServer -> nvarchar(max) - PostgreSQL -> text - Oracle -> nvarchar2(4000) - Sqlite -> text - - - - - 执行 Insert 方法时使用此值 - 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 - - - - - - - decimal/numeric 类型的长度/小数位长度 - - 总长度 - 小数位长度 - - - - - 自定义表达式函数解析 - 注意:请使用静态方法、或者在类上标记 - - - - - 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 - - - - - 数据库类型,可用于适配多种数据库环境 - - - - - 已解析的表达式中参数内容 - - - - - 表达式原始值 - - - - - 主对象的参数化对象,可重塑其属性 - - - - - 可附加参数化对象 - 注意:本属性只有 Where 的表达式解析才可用 - - - - - 将 c# 对象转换为 SQL - - - - - 返回表达式函数表示的 SQL 字符串 - - - - - 获取实体元数据 - - - - - - - 解析表达式 - - - - - - - 索引设置,如:[Index("{tablename}_idx_01", "name")] - - - - - 索引设置,如:[Index("{tablename}_idx_01", "name")] - - 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - - - - 索引设置,如:[Index("{tablename}_idx_01", "name", true)] - - 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - 索引名 - v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) - - - - - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - - - - - 是否唯一 - - - - - 手工绑定 OneToMany、ManyToOne 导航关系 - - - - - 手工绑定 ManyToMany 导航关系 - - - - - 主键名 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 导航关系Fluent,与 NavigateAttribute 对应 - - - - 多对多关系的中间实体类型 - - - - - 设置实体的索引 - - 索引名 - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 导航关系Fluent,与 NavigateAttribute 对应 - - - - - 多对多关系的中间实体类型 - - - - - 设置实体的索引 - - 索引名 - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - - 所属表 - - - - - 列名 - - - - - 映射到 C# 类型 - - - - - 数据库枚举类型int值 - - - - - 数据库类型,字符串,varchar - - - - - 数据库类型,字符串,varchar(255) - - - - - 最大长度 - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 备注 - - - - - 数据库默认值 - - - - - 字段位置 - - - - - 枚举类型标识 - - - - - 枚举项 - - - - - 唯一标识 - - - - - SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 - - - - - 表名 - - - - - 表备注,SqlServer下是扩展属性 MS_Description - - - - - 表/视图 - - - - - 列 - - - - - 自增列 - - - - - 主键/组合 - - - - - 唯一键/组合 - - - - - 索引/组合 - - - - - 外键 - - - - - 类型标识 - - - - - 枚举项 - - - - - 通用的 Odbc 实现,只能做基本的 Crud 操作 - 不支持实体结构迁移、不支持分页(只能 Take 查询) - - 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 - 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 - - 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 - - - - - 武汉达梦数据库有限公司,基于 Odbc 的实现 - - - - - Microsoft Office Access 是由微软发布的关联式数据库管理系统 - - - - - 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 - - - - - 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 - - - - - 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 - - - - - 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 - - - - - 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null - - - - - 当Guid无值时,会生成有序的新值 - - - - - - 获取实体的主键值,多个主键返回数组 - - - - - - - - - 获取实体的属性值 - - - - - - - - - - 获取实体的所有数据,以 (1, 2, xxx) 的形式 - - - - - - - - - 使用新实体的值,复盖旧实体的值 - - - - - 使用新实体的主键值,复盖旧实体的主键值 - - - - - 设置实体中主键内的自增字段值(若存在) - - - - - - - - - 获取实体中主键内的自增字段值(若存在) - - - - - - - - 清除实体的主键值,将自增、Guid类型的主键值清除 - - - - - - - - 清除实体的主键值,将自增、Guid类型的主键值清除 - - - - - - - - 对比两个实体值,返回相同/或不相同的列名 - - - - - - - - - - - 设置实体中某属性的数值增加指定的值 - - - - - - - - - - 设置实体中某属性的值 - - - - - - - - - - 缓存执行 IUpdate.Set - - - - - - - - - SqlExt 是利用自定表达式函数解析功能,解析默认常用的SQL函数,欢迎 PR - - - - - rank() over(order by ...) - - - - - - dense_rank() over(order by ...) - - - - - - count() over(order by ...) - - - - - - sum(..) over(order by ...) - - - - - - - avg(..) over(order by ...) - - - - - - max(..) over(order by ...) - - - - - - - - min(..) over(order by ...) - - - - - - - - SqlServer row_number() over(order by ...) - - - - - - case when .. then .. end - - - - - - MySql group_concat(distinct .. order by .. separator ..) - - - - - - - PostgreSQL string_agg(.., ..) - - - - - - - - 使用连接串(推荐) - - 数据库类型 - 数据库连接串 - 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 - - - - - 使用从数据库,支持多个 - - 从数据库连接串 - - - - - 使用自定义数据库连接对象(放弃内置对象连接池技术) - - 数据库类型 - 数据库连接对象创建器 - 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - 注意:生产环境中谨慎使用 - - true:运行时检查自动同步结构, false:不同步结构(默认) - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - - - 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() - - - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - - - 监视数据库命令对象 - - 执行前 - 执行后,可监视执行性能 - - - - - 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) - 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] - - - - - - - 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池 - 默认值: true - - - - - - - 转小写同步结构 - - true:转小写, false:不转 - - - - - 转大写同步结构 - - true:转大写, false:不转 - - - - - 自动转换实体属性名称 Entity Property -> Db Filed - - *不会覆盖 [Column] 特性设置的Name - - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - lambda表达式条件,仅支持实体基础成员(不包含导航对象) - 若想使用导航对象,请使用 ISelect.ToDelete() 方法 - - lambda表达式条件 - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 传入实体,将主键作为条件 - - 实体 - - - - - 传入实体集合,将主键作为条件 - - 实体集合 - - - - - 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回被删除的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 追加准备插入的实体 - - 实体 - - - - - 追加准备插入的实体 - - 实体 - - - - - 追加准备插入的实体集合 - - 实体集合 - - - - - 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 只插入的列 - - 属性名,或者字段名 - - - - - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 忽略的列 - - 属性名,或者字段名 - - - - - 指定可插入自增字段 - - - - - - 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - - 是否不使用参数化 - - - - - 批量执行选项设置,一般不需要使用该方法 - 各数据库 values, parameters 限制不一样,默认设置: - MySql 5000 3000 - PostgreSQL 5000 3000 - SqlServer 1000 2100 - Oracle 500 999 - Sqlite 5000 999 - 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - - 指定根据 values 上限数量拆分执行 - 指定根据 parameters 上限数量拆分执行 - 是否自动开启事务 - - - - - 批量执行时,分批次执行的进度状态 - - 批量执行时的回调委托 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回自增值 - 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] - - - - - - 执行SQL语句,返回插入后的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 返回 DataTable 以便做 BulkCopy 数据做准备 - 此方法会处理: - 类型、表名、字段名映射 - IgnoreColumns、InsertColumns - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 添加或更新,设置实体 - - 实体 - - - - - 添加或更新,设置实体集合 - - 实体集合 - - - - - 当记录存在时,什么都不做 - 换句话:只有记录不存在时才插入 - - - - - - 当记录存在时,指定只更新的字段,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 当记录存在时,指定只更新的字段 - - 属性名,或者字段名 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 自动产生 as1, as2, as3 .... 字段别名 - 这种方法可以最大程度防止多表,存在相同字段的问题 - - - - - 使用属性名作为字段别名 - - - - - 指定事务对象 - - - - - - - 指定连接对象 - - - - - - - 审核或跟踪 ToList 即将返回的数据 - - - - - - - 执行SQL查询,返回 DataTable - - - - - - 以字典的形式返回查询结果 - 注意:字典的特点会导致返回的数据无序 - - - - - - - - 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 - 注意: - 1、ToList(a => a) 可以返回 a 所有实体 - 2、ToList(a => new { a }) 这样也可以 - 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 - 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() - - false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - - - - - 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 - - 数据块的大小 - 处理数据块 - false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - - - - 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 - - - - - - - - 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - - - - - - 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - - - - - - 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: - fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() - 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: - DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) - 复杂删除使用该方案的好处: - 1、删除前可预览测试数据,防止错误删除操作; - 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); - - - - - - 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: - fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() - 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: - UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) - 复杂更新使用该方案的好处: - 1、更新前可预览测试数据,防止错误更新操作; - 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); - - - - - - 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; - 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 - 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); - select * from (SELECT a."Id" as1 FROM "table_1" a) ftb - UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb - UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb - 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() - - - - - - - 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 - 如:select.AsAlias((_, old) => $"{old} with(lock)") - - - - - - - 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - 指定字段 - - - - - 执行SQL查询,是否有记录 - - - - - - 查询的记录数量 - - - - - - 查询的记录数量,以参数out形式返回 - - 返回的变量 - - - - - 指定从主库查询(默认查询从库) - - - - - - 左联查询,使用导航属性自动生成SQL - - 表达式 - - - - - 联接查询,使用导航属性自动生成SQL - - 表达式 - - - - - 右联查询,使用导航属性自动生成SQL - - 表达式 - - - - - 左联查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 联接查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 右联查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 在 JOIN 位置插入 SQL 内容 - 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") - - - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - true 时生效 - sql语法条件 - 参数 - - - - - 动态过滤条件 - - - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 排他更新锁 - 注意:务必在开启事务后使用该功能 - MySql: for update - SqlServer: With(UpdLock, RowLock, NoWait) - PostgreSQL: for update nowait - Oracle: for update nowait - Sqlite: 无效果 - 达梦: for update nowait - 人大金仓: for update nowait - 神通: for update - - noawait - - - - - 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法 - 参数 - - - - - 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法 - 参数 - - - - - 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - true 时生效 - sql语法 - 参数 - - - - - 查询向后偏移行数 - - - - - - - 查询向后偏移行数 - - 行数 - - - - - 查询多少条数据 - - - - - - - 查询多少条数据 - - - - - - - 分页 - - 第几页 - 每页多少 - - - - - 查询数据前,去重 - - .Distinct().ToList(x => x.GroupName) 对指定字段去重 - - - .Distinct().ToList() 对整个查询去重 - - - - - - - 执行SQL查询,是否有记录 - - lambda表达式 - - - - - 执行SQL查询,返回 DataTable - - - - - - 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 - - - - - - - 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 - - 返回类型 - 选择列 - 数据块的大小 - 处理数据块 - - - - 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 - - - - - - - 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 - - - - - - - 返回即将执行的SQL语句 - - 返回类型 - 选择列 - 字段别名 - - - - - 执行SQL查询,返回指定字段的聚合结果 - - - - - - - - 求和 - - 返回类型 - 列 - - - - - 最小值 - - 返回类型 - 列 - - - - - 最大值 - - 返回类型 - 列 - - - - - 平均值 - - 返回类型 - 列 - - - - - 指定别名 - - 别名 - - - - - 多表查询 - - - - - - - - 多表查询 - - - - - - - - - 多表查询 - - - - - - - - - - 多表查询 - - - - - - - - - - - 多表查询 - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - - lambda表达式 - - - - - 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - - true 时生效 - lambda表达式 - - - - - 多表条件查询 - - - lambda表达式 - - - - - 多表条件查询 - - - lambda表达式 - - - - - 多表条件查询 - - - - lambda表达式 - - - - - 多表条件查询 - - - - - lambda表达式 - - - - - 多表条件查询 - - - - - lambda表达式 - - - - - 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 多表查询时,该方法标记后,表达式条件将对所有表进行附加 - - 例如:软删除、租户,每个表都给条件,挺麻烦的 - - fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) - - 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) - - 当其中的实体可附加表达式才会进行,表越多时收益越大 - - - - - - - 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) - - - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列排序,OrderBy(true, a => a.Time) - - - true 时生效 - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 按列倒向排序,OrderByDescending(true, a => a.Time) - - true 时生效 - 列 - - - - - 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 - - - 选择一个导航属性 - - - - - 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 实现 select .. from ( select ... from t ) a 这样的功能 - 使用 AsTable 方法也可以达到效果 - 示例:WithSql("select * from id=?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - SQL语句 - 参数 - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - - lambda表达式 - - - - - 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - - true 时生效 - lambda表达式 - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 按聚合条件过滤,Where(a => a.Count() > 10) - - lambda表达式 - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - - 返回类型 - 选择列 - - - - - 【linq to sql】专用方法,不建议直接使用 - - - - - 返回即将执行的SQL语句 - - 返回类型 - 选择列 - - - - - 返回即将执行的SQL语句 - - 指定字段 - - - - - 查询向后偏移行数 - - - - - - - 查询向后偏移行数 - - 行数 - - - - - 查询多少条数据 - - - - - - - 查询多少条数据 - - - - - - - 分页 - - 第几页 - 每页多少 - - - - - 查询的记录数量 - - - - - - 查询的记录数量,以参数out形式返回 - - 返回的变量 - - - - - 分组的数据 - - - - - 记录总数 - - - - - - 求和 - - - - - - - - 平均值 - - - - - - - - 最大值 - - - - - - - - 最小值 - - - - - - - 所有元素 - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - - 是否不使用参数化 - - - - - 批量执行选项设置,一般不需要使用该方法 - 各数据库 rows, parameters 限制不一样,默认设置: - MySql 500 3000 - PostgreSQL 500 3000 - SqlServer 500 2100 - Oracle 200 999 - Sqlite 200 999 - 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - - 指定根据 rows 上限数量拆分执行 - 指定根据 parameters 上限数量拆分执行 - 是否自动开启事务 - - - - - 批量执行时,分批次执行的进度状态 - - 批量执行时的回调委托 - - - - - 更新数据,设置更新的实体 - 注意:实体必须定义主键,并且最终会自动附加条件 where id = source.Id - - 实体 - - - - - 更新数据,设置更新的实体集合 - 注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id) - - 实体集合 - - - - - 更新数据,设置更新的实体,同时设置忽略的列 - 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null) - 注意:参数 ignore 与 IUpdate.IgnoreColumns/UpdateColumns 不能同时使用 - - 实体 - 属性值忽略判断, true忽略 - - - - - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - 注意:不能与 UpdateColumns 不能同时使用 - - lambda选择列 - - - - - 忽略的列 - 注意:不能与 UpdateColumns 不能同时使用 - - 属性名,或者字段名 - - - - - 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) - 注意:不能与 IgnoreColumns 不能同时使用 - - lambda选择列 - - - - - 指定的列 - 注意:不能与 IgnoreColumns 同时使用 - - 属性名,或者字段名 - - - - - 设置列的新值,Set(a => a.Name, "newvalue") - - - lambda选择列 - 新值 - - - - - 设置列的新值,Set(a => a.Name, "newvalue") - - - true 时生效 - lambda选择列 - 新值 - - - - - 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 - - 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' - - - - - - - - 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 - - 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' - - - true 时生效 - - - - - - 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法 - 参数 - - - - - 设置更新的列 - SetDto(new { title = "xxx", clicks = 2 }) - SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) - 注意:标记 [Column(CanUpdate = false)] 的属性不会被更新 - - dto 或 Dictionary<string, object> - - - - - lambda表达式条件,仅支持实体基础成员(不包含导航对象) - 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 - - lambda表达式条件 - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 传入实体,将主键作为条件 - - 实体 - - - - - 传入实体集合,将主键作为条件 - - 实体集合 - - - - - 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回更新后的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 主库连接池 - - - - - 从库连接池 - - - - - 数据库类型 - - - - - UseConnectionString 时候的值 - - - - - UseSalve 时候的值 - - - - - 唯一标识 - - - - - 开启事务(不支持异步) - - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - - - - 当前线程的事务 - - - - - 将 new { id = 1 } 或者 Dictionary<string, object> 转换为 DbParameter[] - - new { id = 1 } 或者 Dictionary<string, object> - - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 可自定义解析表达式 - - - - - 自定义实体的配置,方便和多个 ORM 共同使用 - - - - - 自定义实体的属性配置,方便和多个 ORM 共同使用 - - - - - 增删查改,执行命令之前触发 - - - - - 增删查改,执行命令完成后触发 - - - - - CodeFirst迁移,执行之前触发 - - - - - CodeFirst迁移,执行完成触发 - - - - - Insert/Update自动值处理 - - - - - 监视数据库命令对象(执行前,调试) - - - - - 监视数据库命令对象(执行后,用于监视执行性能) - - - - - 跟踪开始 - - - - - 跟踪结束 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 - - - - - 备注 - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构,适用 PostgreSQL - - - - - 转大写同步结构,适用 Oracle/达梦/人大金仓 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - - - - - - 将实体类型集合与数据库对比,返回DDL语句 - - 实体类型 - - - - - 将实体类型与数据库对比,返回DDL语句(指定表名) - - 实体类型 - 指定表名对比 - - - - - 同步实体类型到数据库 - 注意:生产环境中谨慎使用 - - - - - - 同步实体类型集合到数据库 - 注意:生产环境中谨慎使用 - - - - - - 同步实体类型到数据库(指定表名) - 注意:生产环境中谨慎使用 - - 实体类型 - 指定表名对比 - 强制同步结构,无视缓存每次都同步 - - - - 根据 System.Type 获取数据库信息 - - - - - - - FreeSql FluentApi 配置实体,方法名与特性相同 - - - - - - - - FreeSql FluentApi 配置实体,方法名与特性相同 - - - - - - - - 获取 FreeSql FluentApi 配置实体的元数据 - - - 未使用ConfigEntity配置时,返回null - - - - 获取实体类核心配置 - - - - - - - 获取所有数据库 - - - - - - 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 - - - - - - - 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 - - 表名,如:dbo.table1 - 是否忽略大小写 - - - - - 判断表是否存在 - - 表名,如:dbo.table1 - 是否忽略大小写 - - - - - 获取数据库枚举类型int值 - - - - - - - 获取c#转换,(int)、(long) - - - - - - - 获取c#值 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 动态读取 DescriptionAttribute 注释文本 - - - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 更新实体的元数据 - - - - - 执行更新的 SQL - - - - - 执行更新命令的参数 - - - - - 执行更新命令影响的行 - - - - - 更新的实体数量 - - - - - 更新的实体 - - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 当前操作的数据 - - - - - 当前批次 - - - - - 总批次数量 - - - - - 获取 obj.CsName 属性值 MapType 之后的数据库值 - - - - - - - 获取 obj.CsName 属性原始值(不经过 MapType) - - - - - - 设置 obj.CsName 属性值 - - - - - - - 动态过滤条件 - - - - - 属性名:Name - 导航属性:Parent.Name - 多表:b.Name - - - - - 操作符 - - - - - 值 - - - - - Filters 下的逻辑运算符 - - - - - 子过滤条件,它与当前的逻辑关系是 And - 注意:当前 Field 可以留空 - - - - - like - - - - - = - Equal/Equals/Eq 效果相同 - - - - - = - Equal/Equals/Eq 效果相同 - - - - - = - Equal/Equals/Eq 效果相同 - - - - - <> - - - - - > - - - - - >= - - - - - < - - - - - <= - - - - - >= and < - 此时 Value 的值格式为逗号分割:value1,value2 或者数组 - - - - - >= and < - 此时 Value 的值格式为逗号分割:date1,date2 或者数组 - 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: - 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 - 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 - 当 date2 选择的是 2020,那查询的时候是 < 2021 - 当 date2 选择的是 2020-05-30 12,那查询的时候是 < 2020-05-30 13 - 当 date2 选择的是 2020-05-30 12:30,那查询的时候是 < 2020-05-30 12:31 - 并且 date2 只支持以上 5 种格式 (date1 没有限制) - - - - - in (1,2,3) - 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 - - - - - not in (1,2,3) - 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 - - - - - 是否放弃继续读取 - - - - - 中间表,多对多 - - - - - 是否可用 - - - - - 不可用错误 - - - - - 不可用时间 - - - - - 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 - - - 由【可用】变成【不可用】时返回true,否则返回false - - - - 统计对象池中的对象 - - - - - 统计对象池中的对象(完整) - - - - - 获取资源 - - 超时 - - - - - 获取资源 - - - - - - 使用完毕后,归还资源 - - 对象 - 是否重新创建 - - - - 名称 - - - - - 池容量 - - - - - 默认获取超时设置 - - - - - 空闲时间,获取时若超出,则重新创建 - - - - - 异步获取排队队列大小,小于等于0不生效 - - - - - 获取超时后,是否抛出异常 - - - - - 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 - - - - - 后台定时检查可用性间隔秒数 - - - - - 对象池的对象被创建时 - - 返回被创建的对象 - - - - 销毁对象 - - 资源对象 - - - - 从对象池获取对象超时的时候触发,通过该方法统计 - - - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - - - - 归还对象给对象池的时候触发 - - 资源对象 - - - - 检查可用性 - - 资源对象 - - - - - 事件:可用时触发 - - - - - 事件:不可用时触发 - - - - - 所属对象池 - - - - - 在对象池中的唯一标识 - - - - - 资源对象 - - - - - 被获取的总次数 - - - - 最后获取时的时间 - - - - 最后归还时的时间 - - - - - 创建时间 - - - - - 最后获取时的线程id - - - - - 最后归还时的线程id - - - - - 重置 Value 值 - - - - - 对象池管理类 - - 对象类型 - - - - 后台定时检查可用性 - - - - - - 创建对象池 - - 池大小 - 池内对象的创建委托 - 获取池内对象成功后,进行使用前操作 - - - - 创建对象池 - - 策略 - - - - 获取可用资源,或创建资源 - - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - C#: that >= between && that <= and - SQL: that BETWEEN between AND and - - - - - - - - - 注意:这个方法和 Between 有细微区别 - C#: that >= start && that < end - SQL: that >= start and that < end - - - - - - - - - 获取 Type 的原始 c# 文本表示 - - - - - - - 测量两个经纬度的距离,返回单位:米 - - 经纬坐标1 - 经纬坐标2 - 返回距离(单位:米) - - - - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。 - - - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 - 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 查询数据,加工为树型 List 返回 - 注意:实体需要配置父子导航属性 - - - - - - - - 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 - 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 - 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) - - - - false(默认):由父级向子级的递归查询true:由子级向父级的递归查询 - 路径内容选择 - 连接路径内容 - 递归层级 - - - - - 获取 IDbConnection 对应的 IFreeSql 实例 - - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 条件 - - - - + + + + FreeSql + + + + + 数据库列名 + + + + + 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + + + + + 数据库类型,如: varchar(255) + 字符串长度,可使用特性 [MaxLength(255)] + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 忽略此列,不迁移、不插入 + + + + + 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) + + + + + 类型映射,除了可做基本的类型映射外,特别介绍的功能: + 1、将 enum 属性映射成 typeof(string) + 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap + + + + + 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: + + >0时排前面,1,2,3... + + =0时排中间(默认) + + <0时排后面,...-3,-2,-1 + + + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + + 设置长度,针对 string/byte[] 类型避免 DbType 的繁琐设置 + 提示:也可以使用 [MaxLength(100)] + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength < 0 时,对应 DbType: + MySql -> text (StringLength = -2 时,对应 longtext) + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nclob + Sqlite -> text + v1.6.0+ byte[] 支持设置 StringLength + + + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + + decimal/numeric 类型的长度 + + + + + decimal/numeric 类型的小数位长度 + + + + + 数据库列名 + + + + + 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + + + + + 数据库类型,如: varchar(255) + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 忽略此列,不迁移、不插入 + + + + + 乐观锁 + + + + + 类型映射,比如:可将 enum 属性映射成 typeof(string) + + + + + + + 创建表时字段位置,规则如下: + + >0时排前面 + + =0时排中间(默认) + + <0时排后面 + + + + + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + + + + decimal/numeric 类型的长度/小数位长度 + + 总长度 + 小数位长度 + + + + + 自定义表达式函数解析 + 注意:请使用静态方法、或者在类上标记 + + + + + 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 + + + + + 数据库类型,可用于适配多种数据库环境 + + + + + 已解析的表达式中参数内容 + + + + + 表达式原始值 + + + + + 主对象的参数化对象,可重塑其属性 + + + + + 可附加参数化对象 + 注意:本属性只有 Where 的表达式解析才可用 + + + + + 将 c# 对象转换为 SQL + + + + + 返回表达式函数表示的 SQL 字符串 + + + + + 获取实体元数据 + + + + + + + 解析表达式 + + + + + + + 索引设置,如:[Index("{tablename}_idx_01", "name")] + + + + + 索引设置,如:[Index("{tablename}_idx_01", "name")] + + 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + 索引设置,如:[Index("{tablename}_idx_01", "name", true)] + + 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + 索引名 + v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + + + + + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + + 是否唯一 + + + + + 手工绑定 OneToMany、ManyToOne 导航关系 + + + + + 手工绑定 ManyToMany 导航关系 + + + + + 主键名 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + 多对多关系的中间实体类型 + + + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + + 多对多关系的中间实体类型 + + + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + + 所属表 + + + + + 列名 + + + + + 映射到 C# 类型 + + + + + 数据库枚举类型int值 + + + + + 数据库类型,字符串,varchar + + + + + 数据库类型,字符串,varchar(255) + + + + + 最大长度 + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 备注 + + + + + 数据库默认值 + + + + + 字段位置 + + + + + 枚举类型标识 + + + + + 枚举项 + + + + + 唯一标识 + + + + + SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 + + + + + 表名 + + + + + 表备注,SqlServer下是扩展属性 MS_Description + + + + + 表/视图 + + + + + 列 + + + + + 自增列 + + + + + 主键/组合 + + + + + 唯一键/组合 + + + + + 索引/组合 + + + + + 外键 + + + + + 类型标识 + + + + + 枚举项 + + + + + 通用的 Odbc 实现,只能做基本的 Crud 操作 + 不支持实体结构迁移、不支持分页(只能 Take 查询) + + 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 + 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 + + 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 + + + + + 武汉达梦数据库有限公司,基于 Odbc 的实现 + + + + + Microsoft Office Access 是由微软发布的关联式数据库管理系统 + + + + + 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 + + + + + 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 + + + + + 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 + + + + + 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 + + + + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null + + + + + 当Guid无值时,会生成有序的新值 + + + + + + 获取实体的主键值,多个主键返回数组 + + + + + + + + + 获取实体的属性值 + + + + + + + + + + 获取实体的所有数据,以 (1, 2, xxx) 的形式 + + + + + + + + + 使用新实体的值,复盖旧实体的值 + + + + + 使用新实体的主键值,复盖旧实体的主键值 + + + + + 设置实体中主键内的自增字段值(若存在) + + + + + + + + + 获取实体中主键内的自增字段值(若存在) + + + + + + + + 清除实体的主键值,将自增、Guid类型的主键值清除 + + + + + + + + 清除实体的主键值,将自增、Guid类型的主键值清除 + + + + + + + + 对比两个实体值,返回相同/或不相同的列名 + + + + + + + + + + + 设置实体中某属性的数值增加指定的值 + + + + + + + + + + 设置实体中某属性的值 + + + + + + + + + + 缓存执行 IUpdate.Set + + + + + + + + + SqlExt 是利用自定表达式函数解析功能,解析默认常用的SQL函数,欢迎 PR + + + + + rank() over(order by ...) + + + + + + dense_rank() over(order by ...) + + + + + + count() over(order by ...) + + + + + + sum(..) over(order by ...) + + + + + + + avg(..) over(order by ...) + + + + + + max(..) over(order by ...) + + + + + + + + min(..) over(order by ...) + + + + + + + + SqlServer row_number() over(order by ...) + + + + + + case when .. then .. end + + + + + + MySql group_concat(distinct .. order by .. separator ..) + + + + + + + PostgreSQL string_agg(.., ..) + + + + + + + + 使用连接串(推荐) + + 数据库类型 + 数据库连接串 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + + + + 使用从数据库,支持多个 + + 从数据库连接串 + + + + + 使用自定义数据库连接对象(放弃内置对象连接池技术) + + 数据库类型 + 数据库连接对象创建器 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + 注意:生产环境中谨慎使用 + + true:运行时检查自动同步结构, false:不同步结构(默认) + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + + + 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() + + + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + + + 监视数据库命令对象 + + 执行前 + 执行后,可监视执行性能 + + + + + 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) + 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] + + + + + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池 + 默认值: true + + + + + + + 转小写同步结构 + + true:转小写, false:不转 + + + + + 转大写同步结构 + + true:转大写, false:不转 + + + + + 自动转换实体属性名称 Entity Property -> Db Filed + + *不会覆盖 [Column] 特性设置的Name + + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToDelete() 方法 + + lambda表达式条件 + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 传入实体,将主键作为条件 + + 实体 + + + + + 传入实体集合,将主键作为条件 + + 实体集合 + + + + + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回被删除的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 追加准备插入的实体 + + 实体 + + + + + 追加准备插入的实体 + + 实体 + + + + + 追加准备插入的实体集合 + + 实体集合 + + + + + 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 只插入的列 + + 属性名,或者字段名 + + + + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 忽略的列 + + 属性名,或者字段名 + + + + + 指定可插入自增字段 + + + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + + 是否不使用参数化 + + + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 values, parameters 限制不一样,默认设置: + MySql 5000 3000 + PostgreSQL 5000 3000 + SqlServer 1000 2100 + Oracle 500 999 + Sqlite 5000 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 values 上限数量拆分执行 + 指定根据 parameters 上限数量拆分执行 + 是否自动开启事务 + + + + + 批量执行时,分批次执行的进度状态 + + 批量执行时的回调委托 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回自增值 + 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] + + + + + + 执行SQL语句,返回插入后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 返回 DataTable 以便做 BulkCopy 数据做准备 + 此方法会处理: + 类型、表名、字段名映射 + IgnoreColumns、InsertColumns + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 添加或更新,设置实体 + + 实体 + + + + + 添加或更新,设置实体集合 + + 实体集合 + + + + + 当记录存在时,什么都不做 + 换句话:只有记录不存在时才插入 + + + + + + 当记录存在时,指定只更新的字段,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 当记录存在时,指定只更新的字段 + + 属性名,或者字段名 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 自动产生 as1, as2, as3 .... 字段别名 + 这种方法可以最大程度防止多表,存在相同字段的问题 + + + + + 使用属性名作为字段别名 + + + + + 指定事务对象 + + + + + + + 指定连接对象 + + + + + + + 审核或跟踪 ToList 即将返回的数据 + + + + + + + 执行SQL查询,返回 DataTable + + + + + + 以字典的形式返回查询结果 + 注意:字典的特点会导致返回的数据无序 + + + + + + + + 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + 注意: + 1、ToList(a => a) 可以返回 a 所有实体 + 2、ToList(a => new { a }) 这样也可以 + 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 + 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() + + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + + + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + + 数据块的大小 + 处理数据块 + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + + 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 + + + + + + + + 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + + + + + + 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + + + + + + 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: + DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂删除使用该方案的好处: + 1、删除前可预览测试数据,防止错误删除操作; + 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); + + + + + + 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: + UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂更新使用该方案的好处: + 1、更新前可预览测试数据,防止错误更新操作; + 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); + + + + + + 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 + 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); + select * from (SELECT a."Id" as1 FROM "table_1" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb + 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() + + + + + + + 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 + 如:select.AsAlias((_, old) => $"{old} with(lock)") + + + + + + + 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + 指定字段 + + + + + 执行SQL查询,是否有记录 + + + + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + + + + 指定从主库查询(默认查询从库) + + + + + + 左联查询,使用导航属性自动生成SQL + + 表达式 + + + + + 联接查询,使用导航属性自动生成SQL + + 表达式 + + + + + 右联查询,使用导航属性自动生成SQL + + 表达式 + + + + + 左联查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 联接查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 右联查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 在 JOIN 位置插入 SQL 内容 + 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") + + + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + true 时生效 + sql语法条件 + 参数 + + + + + 动态过滤条件 + + + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 排他更新锁 + 注意:务必在开启事务后使用该功能 + MySql: for update + SqlServer: With(UpdLock, RowLock, NoWait) + PostgreSQL: for update nowait + Oracle: for update nowait + Sqlite: 无效果 + 达梦: for update nowait + 人大金仓: for update nowait + 神通: for update + + noawait + + + + + 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法 + 参数 + + + + + 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法 + 参数 + + + + + 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + true 时生效 + sql语法 + 参数 + + + + + 查询向后偏移行数 + + + + + + + 查询向后偏移行数 + + 行数 + + + + + 查询多少条数据 + + + + + + + 查询多少条数据 + + + + + + + 分页 + + 第几页 + 每页多少 + + + + + 查询数据前,去重 + + .Distinct().ToList(x => x.GroupName) 对指定字段去重 + + + .Distinct().ToList() 对整个查询去重 + + + + + + + 执行SQL查询,是否有记录 + + lambda表达式 + + + + + 执行SQL查询,返回 DataTable + + + + + + 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 + + + + + + + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + + 返回类型 + 选择列 + 数据块的大小 + 处理数据块 + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + + + + 返回即将执行的SQL语句 + + 返回类型 + 选择列 + 字段别名 + + + + + 执行SQL查询,返回指定字段的聚合结果 + + + + + + + + 求和 + + 返回类型 + 列 + + + + + 最小值 + + 返回类型 + 列 + + + + + 最大值 + + 返回类型 + 列 + + + + + 平均值 + + 返回类型 + 列 + + + + + 指定别名 + + 别名 + + + + + 多表查询 + + + + + + + + 多表查询 + + + + + + + + + 多表查询 + + + + + + + + + + 多表查询 + + + + + + + + + + + 多表查询 + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 多表条件查询 + + + lambda表达式 + + + + + 多表条件查询 + + + lambda表达式 + + + + + 多表条件查询 + + + + lambda表达式 + + + + + 多表条件查询 + + + + + lambda表达式 + + + + + 多表条件查询 + + + + + lambda表达式 + + + + + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 多表查询时,该方法标记后,表达式条件将对所有表进行附加 + + 例如:软删除、租户,每个表都给条件,挺麻烦的 + + fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) + + 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) + + 当其中的实体可附加表达式才会进行,表越多时收益越大 + + + + + + + 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) + + + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列排序,OrderBy(true, a => a.Time) + + + true 时生效 + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 按列倒向排序,OrderByDescending(true, a => a.Time) + + true 时生效 + 列 + + + + + 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 + + + 选择一个导航属性 + + + + + 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 实现 select .. from ( select ... from t ) a 这样的功能 + 使用 AsTable 方法也可以达到效果 + 示例:WithSql("select * from id=?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + SQL语句 + 参数 + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 按聚合条件过滤,Where(a => a.Count() > 10) + + lambda表达式 + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + + 返回类型 + 选择列 + + + + + 【linq to sql】专用方法,不建议直接使用 + + + + + 返回即将执行的SQL语句 + + 返回类型 + 选择列 + + + + + 返回即将执行的SQL语句 + + 指定字段 + + + + + 查询向后偏移行数 + + + + + + + 查询向后偏移行数 + + 行数 + + + + + 查询多少条数据 + + + + + + + 查询多少条数据 + + + + + + + 分页 + + 第几页 + 每页多少 + + + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + + + + 分组的数据 + + + + + 记录总数 + + + + + + 求和 + + + + + + + + 平均值 + + + + + + + + 最大值 + + + + + + + + 最小值 + + + + + + + 所有元素 + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + + 是否不使用参数化 + + + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 rows, parameters 限制不一样,默认设置: + MySql 500 3000 + PostgreSQL 500 3000 + SqlServer 500 2100 + Oracle 200 999 + Sqlite 200 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 rows 上限数量拆分执行 + 指定根据 parameters 上限数量拆分执行 + 是否自动开启事务 + + + + + 批量执行时,分批次执行的进度状态 + + 批量执行时的回调委托 + + + + + 更新数据,设置更新的实体 + 注意:实体必须定义主键,并且最终会自动附加条件 where id = source.Id + + 实体 + + + + + 更新数据,设置更新的实体集合 + 注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id) + + 实体集合 + + + + + 更新数据,设置更新的实体,同时设置忽略的列 + 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null) + 注意:参数 ignore 与 IUpdate.IgnoreColumns/UpdateColumns 不能同时使用 + + 实体 + 属性值忽略判断, true忽略 + + + + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + 注意:不能与 UpdateColumns 不能同时使用 + + lambda选择列 + + + + + 忽略的列 + 注意:不能与 UpdateColumns 不能同时使用 + + 属性名,或者字段名 + + + + + 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + 注意:不能与 IgnoreColumns 不能同时使用 + + lambda选择列 + + + + + 指定的列 + 注意:不能与 IgnoreColumns 同时使用 + + 属性名,或者字段名 + + + + + 设置列的新值,Set(a => a.Name, "newvalue") + + + lambda选择列 + 新值 + + + + + 设置列的新值,Set(a => a.Name, "newvalue") + + + true 时生效 + lambda选择列 + 新值 + + + + + 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + + 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + + + + + + + + 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + + 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + + + true 时生效 + + + + + + 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法 + 参数 + + + + + 设置更新的列 + SetDto(new { title = "xxx", clicks = 2 }) + SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + 注意:标记 [Column(CanUpdate = false)] 的属性不会被更新 + + dto 或 Dictionary<string, object> + + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 + + lambda表达式条件 + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 传入实体,将主键作为条件 + + 实体 + + + + + 传入实体集合,将主键作为条件 + + 实体集合 + + + + + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回更新后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 主库连接池 + + + + + 从库连接池 + + + + + 数据库类型 + + + + + UseConnectionString 时候的值 + + + + + UseSalve 时候的值 + + + + + 唯一标识 + + + + + 开启事务(不支持异步) + + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + + + + 当前线程的事务 + + + + + 将 new { id = 1 } 或者 Dictionary<string, object> 转换为 DbParameter[] + + new { id = 1 } 或者 Dictionary<string, object> + + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 可自定义解析表达式 + + + + + 自定义实体的配置,方便和多个 ORM 共同使用 + + + + + 自定义实体的属性配置,方便和多个 ORM 共同使用 + + + + + 增删查改,执行命令之前触发 + + + + + 增删查改,执行命令完成后触发 + + + + + CodeFirst迁移,执行之前触发 + + + + + CodeFirst迁移,执行完成触发 + + + + + Insert/Update自动值处理 + + + + + 监视数据库命令对象(执行前,调试) + + + + + 监视数据库命令对象(执行后,用于监视执行性能) + + + + + 跟踪开始 + + + + + 跟踪结束 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 + + + + + 备注 + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构,适用 PostgreSQL + + + + + 转大写同步结构,适用 Oracle/达梦/人大金仓 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + 将实体类型与数据库对比,返回DDL语句 + + + + + + + 将实体类型集合与数据库对比,返回DDL语句 + + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 + + + + + 同步实体类型到数据库 + 注意:生产环境中谨慎使用 + + + + + + 同步实体类型集合到数据库 + 注意:生产环境中谨慎使用 + + + + + + 同步实体类型到数据库(指定表名) + 注意:生产环境中谨慎使用 + + 实体类型 + 指定表名对比 + 强制同步结构,无视缓存每次都同步 + + + + 根据 System.Type 获取数据库信息 + + + + + + + FreeSql FluentApi 配置实体,方法名与特性相同 + + + + + + + + FreeSql FluentApi 配置实体,方法名与特性相同 + + + + + + + + 获取 FreeSql FluentApi 配置实体的元数据 + + + 未使用ConfigEntity配置时,返回null + + + + 获取实体类核心配置 + + + + + + + 获取所有数据库 + + + + + + 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 + + + + + + + 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 + + 表名,如:dbo.table1 + 是否忽略大小写 + + + + + 判断表是否存在 + + 表名,如:dbo.table1 + 是否忽略大小写 + + + + + 获取数据库枚举类型int值 + + + + + + + 获取c#转换,(int)、(long) + + + + + + + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 动态读取 DescriptionAttribute 注释文本 + + + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 更新实体的元数据 + + + + + 执行更新的 SQL + + + + + 执行更新命令的参数 + + + + + 执行更新命令影响的行 + + + + + 更新的实体数量 + + + + + 更新的实体 + + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 当前操作的数据 + + + + + 当前批次 + + + + + 总批次数量 + + + + + 获取 obj.CsName 属性值 MapType 之后的数据库值 + + + + + + + 获取 obj.CsName 属性原始值(不经过 MapType) + + + + + + 设置 obj.CsName 属性值 + + + + + + + 动态过滤条件 + + + + + 属性名:Name + 导航属性:Parent.Name + 多表:b.Name + + + + + 操作符 + + + + + 值 + + + + + Filters 下的逻辑运算符 + + + + + 子过滤条件,它与当前的逻辑关系是 And + 注意:当前 Field 可以留空 + + + + + like + + + + + = + Equal/Equals/Eq 效果相同 + + + + + = + Equal/Equals/Eq 效果相同 + + + + + = + Equal/Equals/Eq 效果相同 + + + + + <> + + + + + > + + + + + >= + + + + + < + + + + + <= + + + + + >= and < + 此时 Value 的值格式为逗号分割:value1,value2 或者数组 + + + + + >= and < + 此时 Value 的值格式为逗号分割:date1,date2 或者数组 + 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: + 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 + 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 + 当 date2 选择的是 2020,那查询的时候是 < 2021 + 当 date2 选择的是 2020-05-30 12,那查询的时候是 < 2020-05-30 13 + 当 date2 选择的是 2020-05-30 12:30,那查询的时候是 < 2020-05-30 12:31 + 并且 date2 只支持以上 5 种格式 (date1 没有限制) + + + + + in (1,2,3) + 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 + + + + + not in (1,2,3) + 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 + + + + + 是否放弃继续读取 + + + + + 中间表,多对多 + + + + + 是否可用 + + + + + 不可用错误 + + + + + 不可用时间 + + + + + 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + + + 由【可用】变成【不可用】时返回true,否则返回false + + + + 统计对象池中的对象 + + + + + 统计对象池中的对象(完整) + + + + + 获取资源 + + 超时 + + + + + 使用完毕后,归还资源 + + 对象 + 是否重新创建 + + + + 名称 + + + + + 池容量 + + + + + 默认获取超时设置 + + + + + 空闲时间,获取时若超出,则重新创建 + + + + + 异步获取排队队列大小,小于等于0不生效 + + + + + 获取超时后,是否抛出异常 + + + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 + + + + + 后台定时检查可用性间隔秒数 + + + + + 对象池的对象被创建时 + + 返回被创建的对象 + + + + 销毁对象 + + 资源对象 + + + + 从对象池获取对象超时的时候触发,通过该方法统计 + + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + + + + 归还对象给对象池的时候触发 + + 资源对象 + + + + 检查可用性 + + 资源对象 + + + + + 事件:可用时触发 + + + + + 事件:不可用时触发 + + + + + 所属对象池 + + + + + 在对象池中的唯一标识 + + + + + 资源对象 + + + + + 被获取的总次数 + + + + 最后获取时的时间 + + + + 最后归还时的时间 + + + + + 创建时间 + + + + + 最后获取时的线程id + + + + + 最后归还时的线程id + + + + + 重置 Value 值 + + + + + 对象池管理类 + + 对象类型 + + + + 后台定时检查可用性 + + + + + + 创建对象池 + + 池大小 + 池内对象的创建委托 + 获取池内对象成功后,进行使用前操作 + + + + 创建对象池 + + 策略 + + + + 获取可用资源,或创建资源 + + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + + + + + + + 获取 Type 的原始 c# 文本表示 + + + + + + + 测量两个经纬度的距离,返回单位:米 + + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) + + + + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。 + + + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 + 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 查询数据,加工为树型 List 返回 + 注意:实体需要配置父子导航属性 + + + + + + + + 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 + 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) + + + + false(默认):由父级向子级的递归查询true:由子级向父级的递归查询 + 路径内容选择 + 连接路径内容 + 递归层级 + + + + + 获取 IDbConnection 对应的 IFreeSql 实例 + + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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 条件 + + + + + + + + + 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 + + 事务体 () => {} + + + + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 + + + 事务体 () => {} + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 7103da4e..c9976187 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index a5aab1b8..ec93a260 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index b099277c..eb5add33 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index fa4ebec9..232daff8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7f31fefc..d70745cb 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index ed5b22af..5a654328 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index bc5fd792..cd3fe253 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e97c6347..0f55e375 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 370be19d..c6bdb9d6 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index be378538..c81428c0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index bfae5cf5..caea7b46 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 07a0b536..dfd22328 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0820 + 1.8.0-preview0821 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From bb089438e24ec471c88f5a6f27cb110a6bbd85ef Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 23 Aug 2020 05:07:11 +0800 Subject: [PATCH 0852/1029] update function png --- functions09.png | Bin 77613 -> 0 bytes functions10.png | Bin 0 -> 130769 bytes readme.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 functions09.png create mode 100644 functions10.png diff --git a/functions09.png b/functions09.png deleted file mode 100644 index a6b84f3af17fe3e7b64a8a31994a2316c9607f2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77613 zcma&Oby!v1+Qz$p1uS~e-6xvulqB(6Evn1eaT^W69S8-yz>%3z?9pn^akj2E(!svr;o@Flz<1RglZC@?62 zKvbX?l49x}aC`d5uhg_|lbgh#lImb77|dZ+T&gqR`(Q&E>VZm)?&YRsS?z4G>trBq zM2SS%gH#y;KC&(&b3HclyNITh$Ih`s4-A$7I=Yo#DTYFqi(HGR^QpJ%nIzZO*GXG3 zP%1D4PTc?ZA>e(mzlGE+>weOI{16TsUebTd83uvE2ZN}8AMi2ZXkhpU$z!1?|C|UM zAW$Eqe_aPoJg1!+1}0rmJKwXxAD@PntwDw4o$^#wZ7oR0@u}n!KEE@ z?&0Zfd$&$|96?xB_yVYmhr*FF?nl#FxH4PYJ6}cS+$bH~D(tssV79$MJ(WxMczD@I zlfy8-&Q0Na?DC>*IDC}&>G6K^emc4^p`s#6C6Dg zG4A`(8VCtYVb#aCGBHU^PCnTGwSBOPcTe@Xp=M&9{az`|ut;yt?dEEQebvAYWk$5m zPuWCO&byuTD5gg#`?l7u%>qrBSi~EKRp?A}xQMmr4oPG=Q|BW*nTfcnj*K+E|32mJ zxL%^C!TCkMq&sQ1?idp;V`p|vmDb&|6uv~WeYfrd$p=@PiQpMD+dY*5uHnqA%(?CD z?JPbo>(iab4_dqnwY#9~C=yg@e@JW~T*0qDOF$tEg1$W!mEM{I_qEK}&R~XBSQvq! z_}fzX#OP@7B4TavCcEK1xf}Kwy&%i?FhjxAPdQ?3Xxt_}SwYJL%Pej@b~#mT4hpJJ zvHGcjOoCPgqdObno>`*y?p3<(_nHGg5&FO3-b2_#$`xJfONPH+zWB`0y@jNwVa}CM zT56jcOYvrqFI?W+Y0_$5bB<<=X;vF0ghf}A6M46t zo}(ga?gH~*4ABk&!KW7qWu>q4^GA0?S{PWi&40}4?|S6|&VjeyTM@94wdcZJ%gA{3 z@@14RkKNs@7f<0Kx(Jw%_y{Gn5B4%AA1=+m9qACoei6Rj{SenQyGK4G$AMKr#fUQ*jBSr19axFJ&Jt`<`>iXWSpz(z$e+!iO~;o*dT{=WH<=q?hQ%H{R?3XbP$ zMs%&4AiENJWVjCsKHi?8kr5xtE=i%1g$08fq3a{(`V$umfhYFAmj_bg57~d0!DU=< ztF3pV5aYlrctoWL28y+2BG3f_WzKc~B~^Qi=Z)T^FoXEy?c-^7SrPvcCDI#+-$}jwENbJcX zX?*0L^XX-%Hg6`zw{f{kX13f8J{#NRt&bLGcz`s2nQ2l7goBEPf6}P@sjtd3V4_>< zry)2CI5<)yU?y|}lIlYCzoTtM27Wj4W_sG{7gAs_R9OlbWYMZVZQ7qRnJmFZ*MZ

OddwyeD6}|l=um4)mm1Tx6eL1Y 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 diff --git a/functions10.png b/functions10.png new file mode 100644 index 0000000000000000000000000000000000000000..5e3f623d7453a53d3a728dca8d52629b8413c64a GIT binary patch literal 130769 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

r}auhs) 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 SO`bd7jjPlQ@Uoa?Zu;G9UdZ;zMa?+#}Q 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%0A;Q^kaR1@AZ_9$#T*<6e7)W(z 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 - +

## 🚀  Quick start From d266446062b1dfcd694f7d213191cd2383410025 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 24 Aug 2020 10:12:23 +0800 Subject: [PATCH 0853/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=201.8.0-previe?= =?UTF-8?q?w=20WhereDynamic=20IN=20=E6=9C=BA=E5=88=B6=EF=BC=9B#431?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 50 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 - FreeSql/FreeSql.xml | 9005 ++++++++++++----------- FreeSql/Internal/CommonUtils.cs | 3 + 4 files changed, 4591 insertions(+), 4476 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 8f68b189..127586bd 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -51,18 +51,26 @@ namespace base_entity public CollationTypeEnum val { get; set; } = CollationTypeEnum.Binary; } + class Sys_reg_user + { + public Guid Id { get; set; } + public Guid OwnerId { get; set; } + public string UnionId { get; set; } + + [Navigate(nameof(OwnerId))] + public Sys_owner Owner { get; set; } + } + class Sys_owner + { + public Guid Id { get; set; } + public Guid RegUserId { get; set; } + + [Navigate(nameof(RegUserId))] + public Sys_reg_user RegUser { get; set; } + } + static void Main(string[] args) { -// var result2 = Newtonsoft.Json.JsonConvert.DeserializeObject(@" -//{ -// ""val"": ""Binary"" -//}"); -// var result1 = System.Text.Json.JsonSerializer.Deserialize(@" -//{ -// ""val"": ""Binary"" -//}"); - - #region 初始化 IFreeSql var fsql = new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) @@ -99,6 +107,15 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + var tsql1 = fsql.Select() + .Include(a => a.Owner) + .Where(a => a.UnionId == "xxx") + .ToSql(); + var tsql2 = fsql.Select() + .Where(a => a.RegUser.UnionId == "xxx2") + .ToSql(); + + var names = (fsql.Select() as Select0Provider)._commonUtils.SplitTableName("`Backups.ProductStockBak`"); @@ -124,19 +141,22 @@ namespace base_entity var wdy1 = JsonConvert.DeserializeObject(@" { - ""Logic"" : ""Or"", + ""Logic"" : ""And"", ""Filters"" : [ { - ""Field"" : ""title"", - ""Operator"" : ""eq"", - ""Value"" : ""product-1"", + ""Logic"" : ""Or"", ""Filters"" : [ { ""Field"" : ""title"", ""Operator"" : ""contains"", ""Value"" : ""product-1111"", + }, + { + ""Field"" : ""title"", + ""Operator"" : ""contains"", + ""Value"" : ""product-2222"", } ] }, @@ -212,8 +232,10 @@ namespace base_entity ] } ", config); + Products.Select.WhereDynamicFilter(wdy1).ToList(); Products.Select.WhereDynamicFilter(wdy2).ToList(); + var items1 = Products.Select.Limit(10).OrderByDescending(a => a.CreateTime).ToList(); var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,14 +532,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 860b3f03..a5622151 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1,4453 +1,4552 @@ - - - - FreeSql - - - - - 数据库列名 - - - - - 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - - - - - 数据库类型,如: varchar(255) - 字符串长度,可使用特性 [MaxLength(255)] - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 忽略此列,不迁移、不插入 - - - - - 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) - - - - - 类型映射,除了可做基本的类型映射外,特别介绍的功能: - 1、将 enum 属性映射成 typeof(string) - 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap - - - - - 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: - - >0时排前面,1,2,3... - - =0时排中间(默认) - - <0时排后面,...-3,-2,-1 - - - - - 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 - - - - - 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 - - - - - 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 - - - - - 设置长度,针对 string/byte[] 类型避免 DbType 的繁琐设置 - 提示:也可以使用 [MaxLength(100)] - --- - StringLength = 100 时,对应 DbType: - MySql -> varchar(100) - SqlServer -> nvarchar(100) - PostgreSQL -> varchar(100) - Oracle -> nvarchar2(100) - Sqlite -> nvarchar(100) - --- - StringLength < 0 时,对应 DbType: - MySql -> text (StringLength = -2 时,对应 longtext) - SqlServer -> nvarchar(max) - PostgreSQL -> text - Oracle -> nclob - Sqlite -> text - v1.6.0+ byte[] 支持设置 StringLength - - - - - 执行 Insert 方法时使用此值 - 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 - - - - - decimal/numeric 类型的长度 - - - - - decimal/numeric 类型的小数位长度 - - - - - 数据库列名 - - - - - 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 - - - - - 数据库类型,如: varchar(255) - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 忽略此列,不迁移、不插入 - - - - - 乐观锁 - - - - - 类型映射,比如:可将 enum 属性映射成 typeof(string) - - - - - - - 创建表时字段位置,规则如下: - - >0时排前面 - - =0时排中间(默认) - - <0时排后面 - - - - - - - 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 - - - - - - - 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 - - - - - - - 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 - - - - - - - 设置长度,针对 string 类型避免 DbType 的繁琐设置 - --- - StringLength = 100 时,对应 DbType: - MySql -> varchar(100) - SqlServer -> nvarchar(100) - PostgreSQL -> varchar(100) - Oracle -> nvarchar2(100) - Sqlite -> nvarchar(100) - --- - StringLength = -1 时,对应 DbType: - MySql -> text - SqlServer -> nvarchar(max) - PostgreSQL -> text - Oracle -> nvarchar2(4000) - Sqlite -> text - - - - - 执行 Insert 方法时使用此值 - 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 - - - - - - - decimal/numeric 类型的长度/小数位长度 - - 总长度 - 小数位长度 - - - - - 自定义表达式函数解析 - 注意:请使用静态方法、或者在类上标记 - - - - - 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 - - - - - 数据库类型,可用于适配多种数据库环境 - - - - - 已解析的表达式中参数内容 - - - - - 表达式原始值 - - - - - 主对象的参数化对象,可重塑其属性 - - - - - 可附加参数化对象 - 注意:本属性只有 Where 的表达式解析才可用 - - - - - 将 c# 对象转换为 SQL - - - - - 返回表达式函数表示的 SQL 字符串 - - - - - 获取实体元数据 - - - - - - - 解析表达式 - - - - - - - 索引设置,如:[Index("{tablename}_idx_01", "name")] - - - - - 索引设置,如:[Index("{tablename}_idx_01", "name")] - - 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - - - - 索引设置,如:[Index("{tablename}_idx_01", "name", true)] - - 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - 索引名 - v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) - - - - - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - - - - - 是否唯一 - - - - - 手工绑定 OneToMany、ManyToOne 导航关系 - - - - - 手工绑定 ManyToMany 导航关系 - - - - - 主键名 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 导航关系Fluent,与 NavigateAttribute 对应 - - - - 多对多关系的中间实体类型 - - - - - 设置实体的索引 - - 索引名 - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - - 数据库表名 - - - - - 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 - - - - - 禁用 CodeFirst 同步结构迁移 - - - - - 导航关系Fluent,与 NavigateAttribute 对应 - - - - - 多对多关系的中间实体类型 - - - - - 设置实体的索引 - - 索引名 - 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC - 是否唯一 - - - - - 所属表 - - - - - 列名 - - - - - 映射到 C# 类型 - - - - - 数据库枚举类型int值 - - - - - 数据库类型,字符串,varchar - - - - - 数据库类型,字符串,varchar(255) - - - - - 最大长度 - - - - - 主键 - - - - - 自增标识 - - - - - 是否可DBNull - - - - - 备注 - - - - - 数据库默认值 - - - - - 字段位置 - - - - - 枚举类型标识 - - - - - 枚举项 - - - - - 唯一标识 - - - - - SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 - - - - - 表名 - - - - - 表备注,SqlServer下是扩展属性 MS_Description - - - - - 表/视图 - - - - - 列 - - - - - 自增列 - - - - - 主键/组合 - - - - - 唯一键/组合 - - - - - 索引/组合 - - - - - 外键 - - - - - 类型标识 - - - - - 枚举项 - - - - - 通用的 Odbc 实现,只能做基本的 Crud 操作 - 不支持实体结构迁移、不支持分页(只能 Take 查询) - - 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 - 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 - - 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 - - - - - 武汉达梦数据库有限公司,基于 Odbc 的实现 - - - - - Microsoft Office Access 是由微软发布的关联式数据库管理系统 - - - - - 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 - - - - - 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 - - - - - 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 - - - - - 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 - - - - - 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null - - - - - 当Guid无值时,会生成有序的新值 - - - - - - 获取实体的主键值,多个主键返回数组 - - - - - - - - - 获取实体的属性值 - - - - - - - - - - 获取实体的所有数据,以 (1, 2, xxx) 的形式 - - - - - - - - - 使用新实体的值,复盖旧实体的值 - - - - - 使用新实体的主键值,复盖旧实体的主键值 - - - - - 设置实体中主键内的自增字段值(若存在) - - - - - - - - - 获取实体中主键内的自增字段值(若存在) - - - - - - - - 清除实体的主键值,将自增、Guid类型的主键值清除 - - - - - - - - 清除实体的主键值,将自增、Guid类型的主键值清除 - - - - - - - - 对比两个实体值,返回相同/或不相同的列名 - - - - - - - - - - - 设置实体中某属性的数值增加指定的值 - - - - - - - - - - 设置实体中某属性的值 - - - - - - - - - - 缓存执行 IUpdate.Set - - - - - - - - - SqlExt 是利用自定表达式函数解析功能,解析默认常用的SQL函数,欢迎 PR - - - - - rank() over(order by ...) - - - - - - dense_rank() over(order by ...) - - - - - - count() over(order by ...) - - - - - - sum(..) over(order by ...) - - - - - - - avg(..) over(order by ...) - - - - - - max(..) over(order by ...) - - - - - - - - min(..) over(order by ...) - - - - - - - - SqlServer row_number() over(order by ...) - - - - - - case when .. then .. end - - - - - - MySql group_concat(distinct .. order by .. separator ..) - - - - - - - PostgreSQL string_agg(.., ..) - - - - - - - - 使用连接串(推荐) - - 数据库类型 - 数据库连接串 - 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 - - - - - 使用从数据库,支持多个 - - 从数据库连接串 - - - - - 使用自定义数据库连接对象(放弃内置对象连接池技术) - - 数据库类型 - 数据库连接对象创建器 - 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - 注意:生产环境中谨慎使用 - - true:运行时检查自动同步结构, false:不同步结构(默认) - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - - - 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() - - - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - - - 监视数据库命令对象 - - 执行前 - 执行后,可监视执行性能 - - - - - 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) - 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] - - - - - - - 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池 - 默认值: true - - - - - - - 转小写同步结构 - - true:转小写, false:不转 - - - - - 转大写同步结构 - - true:转大写, false:不转 - - - - - 自动转换实体属性名称 Entity Property -> Db Filed - - *不会覆盖 [Column] 特性设置的Name - - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - lambda表达式条件,仅支持实体基础成员(不包含导航对象) - 若想使用导航对象,请使用 ISelect.ToDelete() 方法 - - lambda表达式条件 - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 传入实体,将主键作为条件 - - 实体 - - - - - 传入实体集合,将主键作为条件 - - 实体集合 - - - - - 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回被删除的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 追加准备插入的实体 - - 实体 - - - - - 追加准备插入的实体 - - 实体 - - - - - 追加准备插入的实体集合 - - 实体集合 - - - - - 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 只插入的列 - - 属性名,或者字段名 - - - - - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 忽略的列 - - 属性名,或者字段名 - - - - - 指定可插入自增字段 - - - - - - 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - - 是否不使用参数化 - - - - - 批量执行选项设置,一般不需要使用该方法 - 各数据库 values, parameters 限制不一样,默认设置: - MySql 5000 3000 - PostgreSQL 5000 3000 - SqlServer 1000 2100 - Oracle 500 999 - Sqlite 5000 999 - 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - - 指定根据 values 上限数量拆分执行 - 指定根据 parameters 上限数量拆分执行 - 是否自动开启事务 - - - - - 批量执行时,分批次执行的进度状态 - - 批量执行时的回调委托 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回自增值 - 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] - - - - - - 执行SQL语句,返回插入后的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 返回 DataTable 以便做 BulkCopy 数据做准备 - 此方法会处理: - 类型、表名、字段名映射 - IgnoreColumns、InsertColumns - - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 添加或更新,设置实体 - - 实体 - - - - - 添加或更新,设置实体集合 - - 实体集合 - - - - - 当记录存在时,什么都不做 - 换句话:只有记录不存在时才插入 - - - - - - 当记录存在时,指定只更新的字段,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) - - lambda选择列 - - - - - 当记录存在时,指定只更新的字段 - - 属性名,或者字段名 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 自动产生 as1, as2, as3 .... 字段别名 - 这种方法可以最大程度防止多表,存在相同字段的问题 - - - - - 使用属性名作为字段别名 - - - - - 指定事务对象 - - - - - - - 指定连接对象 - - - - - - - 审核或跟踪 ToList 即将返回的数据 - - - - - - - 执行SQL查询,返回 DataTable - - - - - - 以字典的形式返回查询结果 - 注意:字典的特点会导致返回的数据无序 - - - - - - - - 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 - 注意: - 1、ToList(a => a) 可以返回 a 所有实体 - 2、ToList(a => new { a }) 这样也可以 - 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 - 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() - - false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - - - - - 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 - - 数据块的大小 - 处理数据块 - false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 - - - - 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 - - - - - - - - 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - - - - - - 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null - - - - - - 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: - fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() - 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: - DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) - 复杂删除使用该方案的好处: - 1、删除前可预览测试数据,防止错误删除操作; - 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); - - - - - - 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: - fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() - 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: - UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) - 复杂更新使用该方案的好处: - 1、更新前可预览测试数据,防止错误更新操作; - 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); - - - - - - 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; - 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 - 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); - select * from (SELECT a."Id" as1 FROM "table_1" a) ftb - UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb - UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb - 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() - - - - - - - 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 - 如:select.AsAlias((_, old) => $"{old} with(lock)") - - - - - - - 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - 指定字段 - - - - - 执行SQL查询,是否有记录 - - - - - - 查询的记录数量 - - - - - - 查询的记录数量,以参数out形式返回 - - 返回的变量 - - - - - 指定从主库查询(默认查询从库) - - - - - - 左联查询,使用导航属性自动生成SQL - - 表达式 - - - - - 联接查询,使用导航属性自动生成SQL - - 表达式 - - - - - 右联查询,使用导航属性自动生成SQL - - 表达式 - - - - - 左联查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 联接查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 右联查询,指定关联的实体类型 - - 关联的实体类型 - 表达式 - - - - - 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 在 JOIN 位置插入 SQL 内容 - 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") - - - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - true 时生效 - sql语法条件 - 参数 - - - - - 动态过滤条件 - - - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 排他更新锁 - 注意:务必在开启事务后使用该功能 - MySql: for update - SqlServer: With(UpdLock, RowLock, NoWait) - PostgreSQL: for update nowait - Oracle: for update nowait - Sqlite: 无效果 - 达梦: for update nowait - 人大金仓: for update nowait - 神通: for update - - noawait - - - - - 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法 - 参数 - - - - - 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法 - 参数 - - - - - 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - true 时生效 - sql语法 - 参数 - - - - - 查询向后偏移行数 - - - - - - - 查询向后偏移行数 - - 行数 - - - - - 查询多少条数据 - - - - - - - 查询多少条数据 - - - - - - - 分页 - - 第几页 - 每页多少 - - - - - 查询数据前,去重 - - .Distinct().ToList(x => x.GroupName) 对指定字段去重 - - - .Distinct().ToList() 对整个查询去重 - - - - - - - 执行SQL查询,是否有记录 - - lambda表达式 - - - - - 执行SQL查询,返回 DataTable - - - - - - 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 - - - - - - - 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 - - 返回类型 - 选择列 - 数据块的大小 - 处理数据块 - - - - 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 - - - - - - - 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 - - 返回类型 - 选择列 - - - - - 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 - - - - - - - 返回即将执行的SQL语句 - - 返回类型 - 选择列 - 字段别名 - - - - - 执行SQL查询,返回指定字段的聚合结果 - - - - - - - - 求和 - - 返回类型 - 列 - - - - - 最小值 - - 返回类型 - 列 - - - - - 最大值 - - 返回类型 - 列 - - - - - 平均值 - - 返回类型 - 列 - - - - - 指定别名 - - 别名 - - - - - 多表查询 - - - - - - - - 多表查询 - - - - - - - - - 多表查询 - - - - - - - - - - 多表查询 - - - - - - - - - - - 多表查询 - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - - lambda表达式 - - - - - 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - - true 时生效 - lambda表达式 - - - - - 多表条件查询 - - - lambda表达式 - - - - - 多表条件查询 - - - lambda表达式 - - - - - 多表条件查询 - - - - lambda表达式 - - - - - 多表条件查询 - - - - - lambda表达式 - - - - - 多表条件查询 - - - - - lambda表达式 - - - - - 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 多表查询时,该方法标记后,表达式条件将对所有表进行附加 - - 例如:软删除、租户,每个表都给条件,挺麻烦的 - - fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) - - 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) - - 当其中的实体可附加表达式才会进行,表越多时收益越大 - - - - - - - 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) - - - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列排序,OrderBy(true, a => a.Time) - - - true 时生效 - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 按列倒向排序,OrderByDescending(true, a => a.Time) - - true 时生效 - 列 - - - - - 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 - - - 选择一个导航属性 - - - - - 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 实现 select .. from ( select ... from t ) a 这样的功能 - 使用 AsTable 方法也可以达到效果 - 示例:WithSql("select * from id=?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - SQL语句 - 参数 - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") - - lambda表达式 - - - - - 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") - - true 时生效 - lambda表达式 - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 按聚合条件过滤,Where(a => a.Count() > 10) - - lambda表达式 - - - - - 按列排序,OrderBy(a => a.Time) - - - - - - - - 按列倒向排序,OrderByDescending(a => a.Time) - - 列 - - - - - 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 - - 返回类型 - 选择列 - - - - - 【linq to sql】专用方法,不建议直接使用 - - - - - 返回即将执行的SQL语句 - - 返回类型 - 选择列 - - - - - 返回即将执行的SQL语句 - - 指定字段 - - - - - 查询向后偏移行数 - - - - - - - 查询向后偏移行数 - - 行数 - - - - - 查询多少条数据 - - - - - - - 查询多少条数据 - - - - - - - 分页 - - 第几页 - 每页多少 - - - - - 查询的记录数量 - - - - - - 查询的记录数量,以参数out形式返回 - - 返回的变量 - - - - - 分组的数据 - - - - - 记录总数 - - - - - - 求和 - - - - - - - - 平均值 - - - - - - - - 最大值 - - - - - - - - 最小值 - - - - - - - 所有元素 - - - - - 指定事务对象 - - - - - - - 指定事务对象 - - - - - - - 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 - - 是否不使用参数化 - - - - - 批量执行选项设置,一般不需要使用该方法 - 各数据库 rows, parameters 限制不一样,默认设置: - MySql 500 3000 - PostgreSQL 500 3000 - SqlServer 500 2100 - Oracle 200 999 - Sqlite 200 999 - 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 - - 指定根据 rows 上限数量拆分执行 - 指定根据 parameters 上限数量拆分执行 - 是否自动开启事务 - - - - - 批量执行时,分批次执行的进度状态 - - 批量执行时的回调委托 - - - - - 更新数据,设置更新的实体 - 注意:实体必须定义主键,并且最终会自动附加条件 where id = source.Id - - 实体 - - - - - 更新数据,设置更新的实体集合 - 注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id) - - 实体集合 - - - - - 更新数据,设置更新的实体,同时设置忽略的列 - 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null) - 注意:参数 ignore 与 IUpdate.IgnoreColumns/UpdateColumns 不能同时使用 - - 实体 - 属性值忽略判断, true忽略 - - - - - 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) - 注意:不能与 UpdateColumns 不能同时使用 - - lambda选择列 - - - - - 忽略的列 - 注意:不能与 UpdateColumns 不能同时使用 - - 属性名,或者字段名 - - - - - 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) - 注意:不能与 IgnoreColumns 不能同时使用 - - lambda选择列 - - - - - 指定的列 - 注意:不能与 IgnoreColumns 同时使用 - - 属性名,或者字段名 - - - - - 设置列的新值,Set(a => a.Name, "newvalue") - - - lambda选择列 - 新值 - - - - - 设置列的新值,Set(a => a.Name, "newvalue") - - - true 时生效 - lambda选择列 - 新值 - - - - - 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 - - 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' - - - - - - - - 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 - - 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' - - - true 时生效 - - - - - - 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法 - 参数 - - - - - 设置更新的列 - SetDto(new { title = "xxx", clicks = 2 }) - SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) - 注意:标记 [Column(CanUpdate = false)] 的属性不会被更新 - - dto 或 Dictionary<string, object> - - - - - lambda表达式条件,仅支持实体基础成员(不包含导航对象) - 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 - - lambda表达式条件 - - - - - 原生sql语法条件,Where("id = ?id", new { id = 1 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - sql语法条件 - 参数 - - - - - 传入实体,将主键作为条件 - - 实体 - - - - - 传入实体集合,将主键作为条件 - - 实体集合 - - - - - 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - 是否标识为NOT - - - - - 禁用全局过滤功能,不传参数时将禁用所有 - - 零个或多个过滤器名字 - - - - - 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; - - - - - - - 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 - - - - - - - 返回即将执行的SQL语句 - - - - - - 执行SQL语句,返回影响的行数 - - - - - - 执行SQL语句,返回更新后的记录 - 注意:此方法只有 Postgresql/SqlServer 有效果 - - - - - - 主库连接池 - - - - - 从库连接池 - - - - - 数据库类型 - - - - - UseConnectionString 时候的值 - - - - - UseSalve 时候的值 - - - - - 唯一标识 - - - - - 开启事务(不支持异步) - - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - - - - 当前线程的事务 - - - - - 将 new { id = 1 } 或者 Dictionary<string, object> 转换为 DbParameter[] - - new { id = 1 } 或者 Dictionary<string, object> - - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 可自定义解析表达式 - - - - - 自定义实体的配置,方便和多个 ORM 共同使用 - - - - - 自定义实体的属性配置,方便和多个 ORM 共同使用 - - - - - 增删查改,执行命令之前触发 - - - - - 增删查改,执行命令完成后触发 - - - - - CodeFirst迁移,执行之前触发 - - - - - CodeFirst迁移,执行完成触发 - - - - - Insert/Update自动值处理 - - - - - 监视数据库命令对象(执行前,调试) - - - - - 监视数据库命令对象(执行后,用于监视执行性能) - - - - - 跟踪开始 - - - - - 跟踪结束 - - - - - 内置解析功能,可辅助您进行解析 - - - - - 需要您解析的表达式 - - - - - 解析后的内容 - - - - - 实体类型 - - - - - 实体配置 - - - - - 索引配置 - - - - - 实体类型 - - - - - 实体的属性 - - - - - 实体的属性配置 - - - - - 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 - - - - - 操作类型 - - - - - 实体类型 - - - - - 实体类型的元数据 - - - - - 执行的 SQL - - - - - 参数化命令 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 - - - - - 实体类型 - - - - - 执行的 SQL - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 类型 - - - - - 属性列的元数据 - - - - - 反射的属性信息 - - - - - 获取实体的属性值,也可以设置实体的属性新值 - - - - - 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 - - - - - 备注 - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构,适用 PostgreSQL - - - - - 转大写同步结构,适用 Oracle/达梦/人大金仓 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - - - - - - 将实体类型集合与数据库对比,返回DDL语句 - - 实体类型 - - - - - 将实体类型与数据库对比,返回DDL语句(指定表名) - - 实体类型 - 指定表名对比 - - - - - 同步实体类型到数据库 - 注意:生产环境中谨慎使用 - - - - - - 同步实体类型集合到数据库 - 注意:生产环境中谨慎使用 - - - - - - 同步实体类型到数据库(指定表名) - 注意:生产环境中谨慎使用 - - 实体类型 - 指定表名对比 - 强制同步结构,无视缓存每次都同步 - - - - 根据 System.Type 获取数据库信息 - - - - - - - FreeSql FluentApi 配置实体,方法名与特性相同 - - - - - - - - FreeSql FluentApi 配置实体,方法名与特性相同 - - - - - - - - 获取 FreeSql FluentApi 配置实体的元数据 - - - 未使用ConfigEntity配置时,返回null - - - - 获取实体类核心配置 - - - - - - - 获取所有数据库 - - - - - - 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 - - - - - - - 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 - - 表名,如:dbo.table1 - 是否忽略大小写 - - - - - 判断表是否存在 - - 表名,如:dbo.table1 - 是否忽略大小写 - - - - - 获取数据库枚举类型int值 - - - - - - - 获取c#转换,(int)、(long) - - - - - - - 获取c#值 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 动态读取 DescriptionAttribute 注释文本 - - - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 更新实体的元数据 - - - - - 执行更新的 SQL - - - - - 执行更新命令的参数 - - - - - 执行更新命令影响的行 - - - - - 更新的实体数量 - - - - - 更新的实体 - - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 当前操作的数据 - - - - - 当前批次 - - - - - 总批次数量 - - - - - 获取 obj.CsName 属性值 MapType 之后的数据库值 - - - - - - - 获取 obj.CsName 属性原始值(不经过 MapType) - - - - - - 设置 obj.CsName 属性值 - - - - - - - 动态过滤条件 - - - - - 属性名:Name - 导航属性:Parent.Name - 多表:b.Name - - - - - 操作符 - - - - - 值 - - - - - Filters 下的逻辑运算符 - - - - - 子过滤条件,它与当前的逻辑关系是 And - 注意:当前 Field 可以留空 - - - - - like - - - - - = - Equal/Equals/Eq 效果相同 - - - - - = - Equal/Equals/Eq 效果相同 - - - - - = - Equal/Equals/Eq 效果相同 - - - - - <> - - - - - > - - - - - >= - - - - - < - - - - - <= - - - - - >= and < - 此时 Value 的值格式为逗号分割:value1,value2 或者数组 - - - - - >= and < - 此时 Value 的值格式为逗号分割:date1,date2 或者数组 - 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: - 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 - 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 - 当 date2 选择的是 2020,那查询的时候是 < 2021 - 当 date2 选择的是 2020-05-30 12,那查询的时候是 < 2020-05-30 13 - 当 date2 选择的是 2020-05-30 12:30,那查询的时候是 < 2020-05-30 12:31 - 并且 date2 只支持以上 5 种格式 (date1 没有限制) - - - - - in (1,2,3) - 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 - - - - - not in (1,2,3) - 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 - - - - - 是否放弃继续读取 - - - - - 中间表,多对多 - - - - - 是否可用 - - - - - 不可用错误 - - - - - 不可用时间 - - - - - 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 - - - 由【可用】变成【不可用】时返回true,否则返回false - - - - 统计对象池中的对象 - - - - - 统计对象池中的对象(完整) - - - - - 获取资源 - - 超时 - - - - - 使用完毕后,归还资源 - - 对象 - 是否重新创建 - - - - 名称 - - - - - 池容量 - - - - - 默认获取超时设置 - - - - - 空闲时间,获取时若超出,则重新创建 - - - - - 异步获取排队队列大小,小于等于0不生效 - - - - - 获取超时后,是否抛出异常 - - - - - 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 - - - - - 后台定时检查可用性间隔秒数 - - - - - 对象池的对象被创建时 - - 返回被创建的对象 - - - - 销毁对象 - - 资源对象 - - - - 从对象池获取对象超时的时候触发,通过该方法统计 - - - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - - - - 归还对象给对象池的时候触发 - - 资源对象 - - - - 检查可用性 - - 资源对象 - - - - - 事件:可用时触发 - - - - - 事件:不可用时触发 - - - - - 所属对象池 - - - - - 在对象池中的唯一标识 - - - - - 资源对象 - - - - - 被获取的总次数 - - - - 最后获取时的时间 - - - - 最后归还时的时间 - - - - - 创建时间 - - - - - 最后获取时的线程id - - - - - 最后归还时的线程id - - - - - 重置 Value 值 - - - - - 对象池管理类 - - 对象类型 - - - - 后台定时检查可用性 - - - - - - 创建对象池 - - 池大小 - 池内对象的创建委托 - 获取池内对象成功后,进行使用前操作 - - - - 创建对象池 - - 策略 - - - - 获取可用资源,或创建资源 - - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - 不进行任何处理 - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串 - - BigApple -> Big_Apple - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 - - BigApple -> BIG_APPLE - - - - - 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 - - BigApple -> big_apple - - - - - 将字符串转换为大写 - - BigApple -> BIGAPPLE - - - - - 将字符串转换为小写 - - BigApple -> bigapple - - - - - C#: that >= between && that <= and - SQL: that BETWEEN between AND and - - - - - - - - - 注意:这个方法和 Between 有细微区别 - C#: that >= start && that < end - SQL: that >= start and that < end - - - - - - - - - 获取 Type 的原始 c# 文本表示 - - - - - - - 测量两个经纬度的距离,返回单位:米 - - 经纬坐标1 - 经纬坐标2 - 返回距离(单位:米) - - - - 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。 - - - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 - 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); - 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany - - - 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) - 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) - 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) - 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) - - 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) - - - - - 查询数据,加工为树型 List 返回 - 注意:实体需要配置父子导航属性 - - - - - - - - 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 - 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 - 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) - - - - false(默认):由父级向子级的递归查询true:由子级向父级的递归查询 - 路径内容选择 - 连接路径内容 - 递归层级 - - - - - 获取 IDbConnection 对应的 IFreeSql 实例 - - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 条件 - - - - - - - - - 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步) - v1.5.0 关闭了线程事务超时自动提交的机制 - - 事务体 () => {} - - - - 开启事务(不支持异步) - v1.5.0 关闭了线程事务超时自动提交的机制 - - - 事务体 () => {} - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - + + + + FreeSql + + + + + 数据库列名 + + + + + 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + + + + + 数据库类型,如: varchar(255) + 字符串长度,可使用特性 [MaxLength(255)] + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 忽略此列,不迁移、不插入 + + + + + 设置行锁(乐观锁)版本号,每次更新累加版本号,若更新整个实体时会附带当前的版本号判断(修改失败时抛出异常) + + + + + 类型映射,除了可做基本的类型映射外,特别介绍的功能: + 1、将 enum 属性映射成 typeof(string) + 2、将 对象 属性映射成 typeof(string),请安装扩展包 FreeSql.Extensions.JsonMap + + + + + 创建表时字段的位置(场景:实体继承后设置字段顺序),规则如下: + + >0时排前面,1,2,3... + + =0时排中间(默认) + + <0时排后面,...-3,-2,-1 + + + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + + 设置长度,针对 string/byte[] 类型避免 DbType 的繁琐设置 + 提示:也可以使用 [MaxLength(100)] + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength < 0 时,对应 DbType: + MySql -> text (StringLength = -2 时,对应 longtext) + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nclob + Sqlite -> text + v1.6.0+ byte[] 支持设置 StringLength + + + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + + decimal/numeric 类型的长度 + + + + + decimal/numeric 类型的小数位长度 + + + + + 数据库列名 + + + + + 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 + + + + + 数据库类型,如: varchar(255) + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 忽略此列,不迁移、不插入 + + + + + 乐观锁 + + + + + 类型映射,比如:可将 enum 属性映射成 typeof(string) + + + + + + + 创建表时字段位置,规则如下: + + >0时排前面 + + =0时排中间(默认) + + <0时排后面 + + + + + + + 该字段是否可以插入,默认值true,指定为false插入时该字段会被忽略 + + + + + + + 该字段是否可以更新,默认值true,指定为false更新时该字段会被忽略 + + + + + + + 标记属性为数据库服务器时间(utc/local),在插入的时候使用类似 getdate() 执行 + + + + + + + 设置长度,针对 string 类型避免 DbType 的繁琐设置 + --- + StringLength = 100 时,对应 DbType: + MySql -> varchar(100) + SqlServer -> nvarchar(100) + PostgreSQL -> varchar(100) + Oracle -> nvarchar2(100) + Sqlite -> nvarchar(100) + --- + StringLength = -1 时,对应 DbType: + MySql -> text + SqlServer -> nvarchar(max) + PostgreSQL -> text + Oracle -> nvarchar2(4000) + Sqlite -> text + + + + + 执行 Insert 方法时使用此值 + 注意:如果是 getdate() 这种请可考虑使用 ServerTime,因为它对数据库间作了适配 + + + + + + + decimal/numeric 类型的长度/小数位长度 + + 总长度 + 小数位长度 + + + + + 自定义表达式函数解析 + 注意:请使用静态方法、或者在类上标记 + + + + + 自定义表达式函数解析的时候,指定参数不解析 SQL,而是直接传进来 + + + + + 数据库类型,可用于适配多种数据库环境 + + + + + 已解析的表达式中参数内容 + + + + + 表达式原始值 + + + + + 主对象的参数化对象,可重塑其属性 + + + + + 可附加参数化对象 + 注意:本属性只有 Where 的表达式解析才可用 + + + + + 将 c# 对象转换为 SQL + + + + + 返回表达式函数表示的 SQL 字符串 + + + + + 获取实体元数据 + + + + + + + 解析表达式 + + + + + + + 索引设置,如:[Index("{tablename}_idx_01", "name")] + + + + + 索引设置,如:[Index("{tablename}_idx_01", "name")] + + 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + 索引设置,如:[Index("{tablename}_idx_01", "name", true)] + + 索引名v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + 索引名 + v1.7.0 增加占位符 {TableName} 表名区分索引名 (解决 AsTable 分表 CodeFirst 导致索引名重复的问题) + + + + + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + + + + + 是否唯一 + + + + + 手工绑定 OneToMany、ManyToOne 导航关系 + + + + + 手工绑定 ManyToMany 导航关系 + + + + + 主键名 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + 多对多关系的中间实体类型 + + + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + + 数据库表名 + + + + + 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 + + + + + 禁用 CodeFirst 同步结构迁移 + + + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + + 多对多关系的中间实体类型 + + + + + 设置实体的索引 + + 索引名 + 索引字段,为属性名以逗号分隔,如:Create_time ASC, Title ASC + 是否唯一 + + + + + 所属表 + + + + + 列名 + + + + + 映射到 C# 类型 + + + + + 数据库枚举类型int值 + + + + + 数据库类型,字符串,varchar + + + + + 数据库类型,字符串,varchar(255) + + + + + 最大长度 + + + + + 主键 + + + + + 自增标识 + + + + + 是否可DBNull + + + + + 备注 + + + + + 数据库默认值 + + + + + 字段位置 + + + + + 枚举类型标识 + + + + + 枚举项 + + + + + 唯一标识 + + + + + SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 + + + + + 表名 + + + + + 表备注,SqlServer下是扩展属性 MS_Description + + + + + 表/视图 + + + + + 列 + + + + + 自增列 + + + + + 主键/组合 + + + + + 唯一键/组合 + + + + + 索引/组合 + + + + + 外键 + + + + + 类型标识 + + + + + 枚举项 + + + + + 通用的 Odbc 实现,只能做基本的 Crud 操作 + 不支持实体结构迁移、不支持分页(只能 Take 查询) + + 通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库 + 默认适配 SqlServer,可以继承后重新适配 FreeSql.Odbc.Default.OdbcAdapter,最好去看下代码 + + 适配新的 OdbcAdapter,请在 FreeSqlBuilder.Build 之后调用 IFreeSql.SetOdbcAdapter 方法设置 + + + + + 武汉达梦数据库有限公司,基于 Odbc 的实现 + + + + + Microsoft Office Access 是由微软发布的关联式数据库管理系统 + + + + + 武汉达梦数据库有限公司,基于 DmProvider.dll 的实现 + + + + + 北京人大金仓信息技术股份有限公司,基于 Odbc 的实现 + + + + + 天津神舟通用数据技术有限公司,基于 System.Data.OscarClient.dll 的实现 + + + + + 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 + + + + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null + + + + + 当Guid无值时,会生成有序的新值 + + + + + + 获取实体的主键值,多个主键返回数组 + + + + + + + + + 获取实体的属性值 + + + + + + + + + + 获取实体的所有数据,以 (1, 2, xxx) 的形式 + + + + + + + + + 使用新实体的值,复盖旧实体的值 + + + + + 使用新实体的主键值,复盖旧实体的主键值 + + + + + 设置实体中主键内的自增字段值(若存在) + + + + + + + + + 获取实体中主键内的自增字段值(若存在) + + + + + + + + 清除实体的主键值,将自增、Guid类型的主键值清除 + + + + + + + + 清除实体的主键值,将自增、Guid类型的主键值清除 + + + + + + + + 对比两个实体值,返回相同/或不相同的列名 + + + + + + + + + + + 设置实体中某属性的数值增加指定的值 + + + + + + + + + + 设置实体中某属性的值 + + + + + + + + + + 缓存执行 IUpdate.Set + + + + + + + + + SqlExt 是利用自定表达式函数解析功能,解析默认常用的SQL函数,欢迎 PR + + + + + rank() over(order by ...) + + + + + + dense_rank() over(order by ...) + + + + + + count() over(order by ...) + + + + + + sum(..) over(order by ...) + + + + + + + avg(..) over(order by ...) + + + + + + max(..) over(order by ...) + + + + + + + + min(..) over(order by ...) + + + + + + + + SqlServer row_number() over(order by ...) + + + + + + case when .. then .. end + + + + + + MySql group_concat(distinct .. order by .. separator ..) + + + + + + + PostgreSQL string_agg(.., ..) + + + + + + + + 使用连接串(推荐) + + 数据库类型 + 数据库连接串 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + + + + 使用从数据库,支持多个 + + 从数据库连接串 + + + + + 使用自定义数据库连接对象(放弃内置对象连接池技术) + + 数据库类型 + 数据库连接对象创建器 + 提供者的类型,一般不需要指定,如果一直提示“缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载”的错误,说明反射获取不到类型,此时该参数可排上用场 + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + 注意:生产环境中谨慎使用 + + true:运行时检查自动同步结构, false:不同步结构(默认) + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + + + 不使用命令参数化执行,针对 Insert/Update,也可临时使用 IInsert/IUpdate.NoneParameter() + + + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + + + 监视数据库命令对象 + + 执行前 + 执行后,可监视执行性能 + + + + + 实体类名 -> 数据库表名,命名转换(类名、属性名都生效) + 优先级小于 [Table(Name = "xxx")]、[Column(Name = "xxx")] + + + + + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池 + 默认值: true + + + + + + + 转小写同步结构 + + true:转小写, false:不转 + + + + + 转大写同步结构 + + true:转大写, false:不转 + + + + + 自动转换实体属性名称 Entity Property -> Db Filed + + *不会覆盖 [Column] 特性设置的Name + + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToDelete() 方法 + + lambda表达式条件 + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 传入实体,将主键作为条件 + + 实体 + + + + + 传入实体集合,将主键作为条件 + + 实体集合 + + + + + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Delete<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回被删除的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 追加准备插入的实体 + + 实体 + + + + + 追加准备插入的实体 + + 实体 + + + + + 追加准备插入的实体集合 + + 实体集合 + + + + + 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 只插入的列 + + 属性名,或者字段名 + + + + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 忽略的列 + + 属性名,或者字段名 + + + + + 指定可插入自增字段 + + + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + + 是否不使用参数化 + + + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 values, parameters 限制不一样,默认设置: + MySql 5000 3000 + PostgreSQL 5000 3000 + SqlServer 1000 2100 + Oracle 500 999 + Sqlite 5000 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 values 上限数量拆分执行 + 指定根据 parameters 上限数量拆分执行 + 是否自动开启事务 + + + + + 批量执行时,分批次执行的进度状态 + + 批量执行时的回调委托 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Insert<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回自增值 + 注意:请检查实体类是否标记了 [Column(IsIdentity = true)] + + + + + + 执行SQL语句,返回插入后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 返回 DataTable 以便做 BulkCopy 数据做准备 + 此方法会处理: + 类型、表名、字段名映射 + IgnoreColumns、InsertColumns + + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 添加或更新,设置实体 + + 实体 + + + + + 添加或更新,设置实体集合 + + 实体集合 + + + + + 当记录存在时,什么都不做 + 换句话:只有记录不存在时才插入 + + + + + + 当记录存在时,指定只更新的字段,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + + lambda选择列 + + + + + 当记录存在时,指定只更新的字段 + + 属性名,或者字段名 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 自动产生 as1, as2, as3 .... 字段别名 + 这种方法可以最大程度防止多表,存在相同字段的问题 + + + + + 使用属性名作为字段别名 + + + + + 指定事务对象 + + + + + + + 指定连接对象 + + + + + + + 审核或跟踪 ToList 即将返回的数据 + + + + + + + 执行SQL查询,返回 DataTable + + + + + + 以字典的形式返回查询结果 + 注意:字典的特点会导致返回的数据无序 + + + + + + + + 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 + 注意: + 1、ToList(a => a) 可以返回 a 所有实体 + 2、ToList(a => new { a }) 这样也可以 + 3、ToList((a, b, c) => new { a, b, c }) 这样也可以 + 4、abc 怎么来的?请试试 fsql.Select<T1, T2, T3>() + + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + + + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + + 数据块的大小 + 处理数据块 + false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据 + + + + 执行SQL查询,返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表 + + + + + + + + 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + + + + + + 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + + + + + + 将查询转为删除对象,以便支持导航对象或其他查询功能删除数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行: + DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂删除使用该方案的好处: + 1、删除前可预览测试数据,防止错误删除操作; + 2、支持更加复杂的删除操作(IDelete 默认只支持简单的操作); + + + + + + 将查询转为更新对象,以便支持导航对象或其他查询功能更新数据,如下: + fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToUpdate().Set(a => a.Title, "111").ExecuteAffrows() + 注意:此方法不是将数据查询到内存循环更新,上面的代码产生如下 SQL 执行: + UPDATE `T1` SET Title = '111' WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1) + 复杂更新使用该方案的好处: + 1、更新前可预览测试数据,防止错误更新操作; + 2、支持更加复杂的更新操作(IUpdate 默认只支持简单的操作); + + + + + + 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; + 设置多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行。 + 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); + select * from (SELECT a."Id" as1 FROM "table_1" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_2" a) ftb + UNION ALL select * from (SELECT a."Id" as1 FROM "table_3" a) ftb + 还可以这样:select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList() + + + + + + + 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 + 如:select.AsAlias((_, old) => $"{old} with(lock)") + + + + + + + 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + 指定字段 + + + + + 执行SQL查询,是否有记录 + + + + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + + + + 指定从主库查询(默认查询从库) + + + + + + 左联查询,使用导航属性自动生成SQL + + 表达式 + + + + + 联接查询,使用导航属性自动生成SQL + + 表达式 + + + + + 右联查询,使用导航属性自动生成SQL + + 表达式 + + + + + 左联查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 联接查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 右联查询,指定关联的实体类型 + + 关联的实体类型 + 表达式 + + + + + 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 在 JOIN 位置插入 SQL 内容 + 如:.RawJoin("OUTER APPLY ( select id from t2 ) b") + + + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + true 时生效 + sql语法条件 + 参数 + + + + + 动态过滤条件 + + + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 排他更新锁 + 注意:务必在开启事务后使用该功能 + MySql: for update + SqlServer: With(UpdLock, RowLock, NoWait) + PostgreSQL: for update nowait + Oracle: for update nowait + Sqlite: 无效果 + 达梦: for update nowait + 人大金仓: for update nowait + 神通: for update + + noawait + + + + + 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法 + 参数 + + + + + 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法 + 参数 + + + + + 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + true 时生效 + sql语法 + 参数 + + + + + 查询向后偏移行数 + + + + + + + 查询向后偏移行数 + + 行数 + + + + + 查询多少条数据 + + + + + + + 查询多少条数据 + + + + + + + 分页 + + 第几页 + 每页多少 + + + + + 查询数据前,去重 + + .Distinct().ToList(x => x.GroupName) 对指定字段去重 + + + .Distinct().ToList() 对整个查询去重 + + + + + + + 执行SQL查询,是否有记录 + + lambda表达式 + + + + + 执行SQL查询,返回 DataTable + + + + + + 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Count 为 0 的列表 + + + + + + + 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。 + + 返回类型 + 选择列 + 数据块的大小 + 处理数据块 + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + + + + 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值 + + 返回类型 + 选择列 + + + + + 执行SQL查询,返回 TDto 映射的字段,记录不存在时返回 Dto 默认值 + + + + + + + 返回即将执行的SQL语句 + + 返回类型 + 选择列 + 字段别名 + + + + + 执行SQL查询,返回指定字段的聚合结果 + + + + + + + + 求和 + + 返回类型 + 列 + + + + + 最小值 + + 返回类型 + 列 + + + + + 最大值 + + 返回类型 + 列 + + + + + 平均值 + + 返回类型 + 列 + + + + + 指定别名 + + 别名 + + + + + 多表查询 + + + + + + + + 多表查询 + + + + + + + + + 多表查询 + + + + + + + + + + 多表查询 + + + + + + + + + + + 多表查询 + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + + 多表查询 + + + + + + + + + + + + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 多表条件查询 + + + lambda表达式 + + + + + 多表条件查询 + + + lambda表达式 + + + + + 多表条件查询 + + + + lambda表达式 + + + + + 多表条件查询 + + + + + lambda表达式 + + + + + 多表条件查询 + + + + + lambda表达式 + + + + + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 多表查询时,该方法标记后,表达式条件将对所有表进行附加 + + 例如:软删除、租户,每个表都给条件,挺麻烦的 + + fsql.Select<T1>().LeftJoin<T2>(...).Where<T2>((t1, t2 => t1.IsDeleted == false && t2.IsDeleted == false) + + 修改:fsql.Select<T1>().LeftJoin<T2>(...).WhereCascade(t1 => t1.IsDeleted == false) + + 当其中的实体可附加表达式才会进行,表越多时收益越大 + + + + + + + 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) + + + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列排序,OrderBy(true, a => a.Time) + + + true 时生效 + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 按列倒向排序,OrderByDescending(true, a => a.Time) + + true 时生效 + 列 + + + + + 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 + + + 选择一个导航属性 + + + + + 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 实现 select .. from ( select ... from t ) a 这样的功能 + 使用 AsTable 方法也可以达到效果 + 示例:WithSql("select * from id=?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + SQL语句 + 参数 + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + + lambda表达式 + + + + + 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + + true 时生效 + lambda表达式 + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 按聚合条件过滤,Where(a => a.Count() > 10) + + lambda表达式 + + + + + 按列排序,OrderBy(a => a.Time) + + + + + + + + 按列倒向排序,OrderByDescending(a => a.Time) + + 列 + + + + + 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + + 返回类型 + 选择列 + + + + + 【linq to sql】专用方法,不建议直接使用 + + + + + 返回即将执行的SQL语句 + + 返回类型 + 选择列 + + + + + 返回即将执行的SQL语句 + + 指定字段 + + + + + 查询向后偏移行数 + + + + + + + 查询向后偏移行数 + + 行数 + + + + + 查询多少条数据 + + + + + + + 查询多少条数据 + + + + + + + 分页 + + 第几页 + 每页多少 + + + + + 查询的记录数量 + + + + + + 查询的记录数量,以参数out形式返回 + + 返回的变量 + + + + + 分组的数据 + + + + + 记录总数 + + + + + + 求和 + + + + + + + + 平均值 + + + + + + + + 最大值 + + + + + + + + 最小值 + + + + + + + 所有元素 + + + + + 指定事务对象 + + + + + + + 指定事务对象 + + + + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 + + 是否不使用参数化 + + + + + 批量执行选项设置,一般不需要使用该方法 + 各数据库 rows, parameters 限制不一样,默认设置: + MySql 500 3000 + PostgreSQL 500 3000 + SqlServer 500 2100 + Oracle 200 999 + Sqlite 200 999 + 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。 + + 指定根据 rows 上限数量拆分执行 + 指定根据 parameters 上限数量拆分执行 + 是否自动开启事务 + + + + + 批量执行时,分批次执行的进度状态 + + 批量执行时的回调委托 + + + + + 更新数据,设置更新的实体 + 注意:实体必须定义主键,并且最终会自动附加条件 where id = source.Id + + 实体 + + + + + 更新数据,设置更新的实体集合 + 注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id) + + 实体集合 + + + + + 更新数据,设置更新的实体,同时设置忽略的列 + 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null) + 注意:参数 ignore 与 IUpdate.IgnoreColumns/UpdateColumns 不能同时使用 + + 实体 + 属性值忽略判断, true忽略 + + + + + 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) + 注意:不能与 UpdateColumns 不能同时使用 + + lambda选择列 + + + + + 忽略的列 + 注意:不能与 UpdateColumns 不能同时使用 + + 属性名,或者字段名 + + + + + 指定的列,UpdateColumns(a => a.Name) | UpdateColumns(a => new{a.Name,a.Time}) | UpdateColumns(a => new[]{"name","time"}) + 注意:不能与 IgnoreColumns 不能同时使用 + + lambda选择列 + + + + + 指定的列 + 注意:不能与 IgnoreColumns 同时使用 + + 属性名,或者字段名 + + + + + 设置列的新值,Set(a => a.Name, "newvalue") + + + lambda选择列 + 新值 + + + + + 设置列的新值,Set(a => a.Name, "newvalue") + + + true 时生效 + lambda选择列 + 新值 + + + + + 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + + 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + + + + + + + + 设置列的的新值为基础上增加,格式:Set(a => a.Clicks + 1) 相当于 clicks=clicks+1 + + 指定更新,格式:Set(a => new T { Clicks = a.Clicks + 1, Time = DateTime.Now }) 相当于 set clicks=clicks+1,time='2019-06-19....' + + + true 时生效 + + + + + + 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法 + 参数 + + + + + 设置更新的列 + SetDto(new { title = "xxx", clicks = 2 }) + SetDto(new Dictionary<string, object> { ["title"] = "xxx", ["clicks"] = 2 }) + 注意:标记 [Column(CanUpdate = false)] 的属性不会被更新 + + dto 或 Dictionary<string, object> + + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 + + lambda表达式条件 + + + + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + sql语法条件 + 参数 + + + + + 传入实体,将主键作为条件 + + 实体 + + + + + 传入实体集合,将主键作为条件 + + 实体集合 + + + + + 传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT + + + + + 禁用全局过滤功能,不传参数时将禁用所有 + + 零个或多个过滤器名字 + + + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; + + + + + + + 动态Type,在使用 Update<object> 后使用本方法,指定实体类型 + + + + + + + 返回即将执行的SQL语句 + + + + + + 执行SQL语句,返回影响的行数 + + + + + + 执行SQL语句,返回更新后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + + + + 主库连接池 + + + + + 从库连接池 + + + + + 数据库类型 + + + + + UseConnectionString 时候的值 + + + + + UseSalve 时候的值 + + + + + 唯一标识 + + + + + 开启事务(不支持异步) + + 事务体 () => {} + + + + 开启事务(不支持异步) + + + 事务体 () => {} + + + + 当前线程的事务 + + + + + 将 new { id = 1 } 或者 Dictionary<string, object> 转换为 DbParameter[] + + new { id = 1 } 或者 Dictionary<string, object> + + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 可自定义解析表达式 + + + + + 自定义实体的配置,方便和多个 ORM 共同使用 + + + + + 自定义实体的属性配置,方便和多个 ORM 共同使用 + + + + + 增删查改,执行命令之前触发 + + + + + 增删查改,执行命令完成后触发 + + + + + CodeFirst迁移,执行之前触发 + + + + + CodeFirst迁移,执行完成触发 + + + + + Insert/Update自动值处理 + + + + + 监视数据库命令对象(执行前,调试) + + + + + 监视数据库命令对象(执行后,用于监视执行性能) + + + + + 跟踪开始 + + + + + 跟踪结束 + + + + + 内置解析功能,可辅助您进行解析 + + + + + 需要您解析的表达式 + + + + + 解析后的内容 + + + + + 实体类型 + + + + + 实体配置 + + + + + 索引配置 + + + + + 实体类型 + + + + + 实体的属性 + + + + + 实体的属性配置 + + + + + 标识符,可将 CurdBefore 与 CurdAfter 进行匹配 + + + + + 操作类型 + + + + + 实体类型 + + + + + 实体类型的元数据 + + + + + 执行的 SQL + + + + + 参数化命令 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 SyncStructureBeforeEventArgs 与 SyncStructureAfterEventArgs 进行匹配 + + + + + 实体类型 + + + + + 执行的 SQL + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 类型 + + + + + 属性列的元数据 + + + + + 反射的属性信息 + + + + + 获取实体的属性值,也可以设置实体的属性新值 + + + + + 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 + + + + + 备注 + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构,适用 PostgreSQL + + + + + 转大写同步结构,适用 Oracle/达梦/人大金仓 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + 将实体类型与数据库对比,返回DDL语句 + + + + + + + 将实体类型集合与数据库对比,返回DDL语句 + + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 + + + + + 同步实体类型到数据库 + 注意:生产环境中谨慎使用 + + + + + + 同步实体类型集合到数据库 + 注意:生产环境中谨慎使用 + + + + + + 同步实体类型到数据库(指定表名) + 注意:生产环境中谨慎使用 + + 实体类型 + 指定表名对比 + 强制同步结构,无视缓存每次都同步 + + + + 根据 System.Type 获取数据库信息 + + + + + + + FreeSql FluentApi 配置实体,方法名与特性相同 + + + + + + + + FreeSql FluentApi 配置实体,方法名与特性相同 + + + + + + + + 获取 FreeSql FluentApi 配置实体的元数据 + + + 未使用ConfigEntity配置时,返回null + + + + 获取实体类核心配置 + + + + + + + 获取所有数据库 + + + + + + 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 + + + + + + + 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 + + 表名,如:dbo.table1 + 是否忽略大小写 + + + + + 判断表是否存在 + + 表名,如:dbo.table1 + 是否忽略大小写 + + + + + 获取数据库枚举类型int值 + + + + + + + 获取c#转换,(int)、(long) + + + + + + + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 动态读取 DescriptionAttribute 注释文本 + + + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 更新实体的元数据 + + + + + 执行更新的 SQL + + + + + 执行更新命令的参数 + + + + + 执行更新命令影响的行 + + + + + 更新的实体数量 + + + + + 更新的实体 + + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 当前操作的数据 + + + + + 当前批次 + + + + + 总批次数量 + + + + + 获取 obj.CsName 属性值 MapType 之后的数据库值 + + + + + + + 获取 obj.CsName 属性原始值(不经过 MapType) + + + + + + 设置 obj.CsName 属性值 + + + + + + + 动态过滤条件 + + + + + 属性名:Name + 导航属性:Parent.Name + 多表:b.Name + + + + + 操作符 + + + + + 值 + + + + + Filters 下的逻辑运算符 + + + + + 子过滤条件,它与当前的逻辑关系是 And + 注意:当前 Field 可以留空 + + + + + like + + + + + = + Equal/Equals/Eq 效果相同 + + + + + = + Equal/Equals/Eq 效果相同 + + + + + = + Equal/Equals/Eq 效果相同 + + + + + <> + + + + + > + + + + + >= + + + + + < + + + + + <= + + + + + >= and < + 此时 Value 的值格式为逗号分割:value1,value2 或者数组 + + + + + >= and < + 此时 Value 的值格式为逗号分割:date1,date2 或者数组 + 这是专门为日期范围查询定制的操作符,它会处理 date2 + 1,比如: + 当 date2 选择的是 2020-05-30,那查询的时候是 < 2020-05-31 + 当 date2 选择的是 2020-05,那查询的时候是 < 2020-06 + 当 date2 选择的是 2020,那查询的时候是 < 2021 + 当 date2 选择的是 2020-05-30 12,那查询的时候是 < 2020-05-30 13 + 当 date2 选择的是 2020-05-30 12:30,那查询的时候是 < 2020-05-30 12:31 + 并且 date2 只支持以上 5 种格式 (date1 没有限制) + + + + + in (1,2,3) + 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 + + + + + not in (1,2,3) + 此时 Value 的值格式为逗号分割:value1,value2,value3... 或者数组 + + + + + 是否放弃继续读取 + + + + + 中间表,多对多 + + + + + 是否可用 + + + + + 不可用错误 + + + + + 不可用时间 + + + + + 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + + + 由【可用】变成【不可用】时返回true,否则返回false + + + + 统计对象池中的对象 + + + + + 统计对象池中的对象(完整) + + + + + 获取资源 + + 超时 + + + + + 获取资源 + + + + + + 使用完毕后,归还资源 + + 对象 + 是否重新创建 + + + + 名称 + + + + + 池容量 + + + + + 默认获取超时设置 + + + + + 空闲时间,获取时若超出,则重新创建 + + + + + 异步获取排队队列大小,小于等于0不生效 + + + + + 获取超时后,是否抛出异常 + + + + + 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放 + + + + + 后台定时检查可用性间隔秒数 + + + + + 对象池的对象被创建时 + + 返回被创建的对象 + + + + 销毁对象 + + 资源对象 + + + + 从对象池获取对象超时的时候触发,通过该方法统计 + + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + + + + 归还对象给对象池的时候触发 + + 资源对象 + + + + 检查可用性 + + 资源对象 + + + + + 事件:可用时触发 + + + + + 事件:不可用时触发 + + + + + 所属对象池 + + + + + 在对象池中的唯一标识 + + + + + 资源对象 + + + + + 被获取的总次数 + + + + 最后获取时的时间 + + + + 最后归还时的时间 + + + + + 创建时间 + + + + + 最后获取时的线程id + + + + + 最后归还时的线程id + + + + + 重置 Value 值 + + + + + 对象池管理类 + + 对象类型 + + + + 后台定时检查可用性 + + + + + + 创建对象池 + + 池大小 + 池内对象的创建委托 + 获取池内对象成功后,进行使用前操作 + + + + 创建对象池 + + 策略 + + + + 获取可用资源,或创建资源 + + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + C#: that >= between && that <= and + SQL: that BETWEEN between AND and + + + + + + + + + 注意:这个方法和 Between 有细微区别 + C#: that >= start && that < end + SQL: that >= start and that < end + + + + + + + + + 获取 Type 的原始 c# 文本表示 + + + + + + + 测量两个经纬度的距离,返回单位:米 + + 经纬坐标1 + 经纬坐标2 + 返回距离(单位:米) + + + + 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。 + + + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 + 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); + 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) + 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) + 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) + 可以 .Select 设置只查询部分字段,如: (a => new TNavigate { Title = a.Title }) + + 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + + + 查询数据,加工为树型 List 返回 + 注意:实体需要配置父子导航属性 + + + + + + + + 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 + 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) + + + + false(默认):由父级向子级的递归查询true:由子级向父级的递归查询 + 路径内容选择 + 连接路径内容 + 递归层级 + + + + + 获取 IDbConnection 对应的 IFreeSql 实例 + + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 9c1ae1ce..9b2ee4f5 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -292,9 +292,11 @@ namespace FreeSql.Internal var ie = dywhere as IEnumerable; var ieidx = 0; var isEntityType = false; + var isAny = false; sb.Append(aliasAndDot).Append(this.QuoteSqlName(pk1.Attribute.Name)).Append(" IN ("); //or会造成扫全表 foreach (var i in ie) { + isAny = true; if (ieidx > 0) sb.Append(","); if (ieidx == 0) { @@ -305,6 +307,7 @@ namespace FreeSql.Internal else sb.Append(this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, i))); ++ieidx; } + if (isAny == false) return ""; sb.Append(")"); return sb.ToString(); } From d951b475d9b9e28a491a82ecc5963e7b8db5dcec Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 24 Aug 2020 12:39:22 +0800 Subject: [PATCH 0854/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IAdo.Execute?= =?UTF-8?q?ConnectTest=20=E5=BF=AB=E9=80=9F=E5=88=A4=E6=96=AD=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E6=98=AF=E5=90=A6=E5=8F=AF=E7=94=A8=20#113=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++++++++ .../MySqlConnectorAdo/MySqlAdoTest.cs | 5 +++++ .../Dameng/DamengAdo/DamengAdoTest.cs | 5 +++++ .../Default/OdbcAdo/OdbcAdoTest.cs | 5 +++++ .../KingbaseESAdo/KingbaseESAdoTest.cs | 5 +++++ .../MySql/MySqlAdo/MySqlAdoTest.cs | 5 +++++ .../Oracle/OracleAdo/OracleAdoTest.cs | 5 +++++ .../PostgreSQLAdo/PostgreSQLAdoTest.cs | 5 +++++ .../SqlServerAdo/SqlServerAdoTest.cs | 5 +++++ .../Dameng/DamengAdo/DamengAdoTest.cs | 5 +++++ .../MsAccess/MsAccessAdo/MsAccessAdoTest.cs | 6 ++++++ .../MySql/MySqlAdo/MySqlAdoTest.cs | 5 +++++ .../Oracle/OracleAdo/OracleAdoTest.cs | 5 +++++ .../PostgreSQLAdo/PostgreSQLAdoTest.cs | 5 +++++ .../ShenTong/ShenTongAdo/ShenTongAdoTest.cs | 5 +++++ .../SqlServerAdo/SqlServerAdoTest.cs | 5 +++++ .../Sqlite/SqliteAdo/SqliteAdoTest.cs | 6 ++++++ FreeSql/FreeSql.xml | 16 ++++++++++++++ FreeSql/Interface/IAdo.cs | 16 ++++++++++++++ .../CommonProvider/AdoProvider/AdoProvider.cs | 21 +++++++++++++++++++ .../AdoProvider/AdoProviderAsync.cs | 20 ++++++++++++++++++ 21 files changed, 164 insertions(+) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs index 9fc81f4a..2b3d9f5c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.MySqlConnector var t2 = g.mysql.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.mysql.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs index 408d4ee4..43f8191a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengAdo/DamengAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.Odbc.Dameng var t2 = g.dameng.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.dameng.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs index 8a81857e..525d86a7 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/OdbcAdo/OdbcAdoTest.cs @@ -19,6 +19,11 @@ namespace FreeSql.Tests.Odbc.Default var t2 = g.odbc.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.odbc.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs index f37a4b02..6b382d2f 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.Odbc.KingbaseES var t2 = g.kingbaseES.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.kingbaseES.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs index e38cd06b..0029774e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlAdo/MySqlAdoTest.cs @@ -19,6 +19,11 @@ namespace FreeSql.Tests.Odbc.MySql var t2 = g.mysql.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.mysql.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAdo/OracleAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAdo/OracleAdoTest.cs index 419dac02..2c315e56 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAdo/OracleAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleAdo/OracleAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.Odbc.Oracle var t2 = g.oracle.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.oracle.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs index 61f111de..82e59608 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.Odbc.PostgreSQL var t2 = g.pgsql.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.pgsql.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index bdb889d9..24d3c318 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -20,6 +20,11 @@ namespace FreeSql.Tests.Odbc.SqlServer var t2 = g.sqlserver.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.sqlserver.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs index 796e0a6e..01f589f6 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.Dameng var t2 = g.dameng.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.dameng.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs index fca67875..3e6ba0ef 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs @@ -17,6 +17,12 @@ namespace FreeSql.Tests.MsAccess { var t2 = g.msaccess.Ado.SlavePools.Count; } + + [Fact] + public void ExecuteTest() + { + Assert.True(g.msaccess.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs index ab37eda6..3ba3a825 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.MySql var t2 = g.mysql.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.mysql.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs index a2c24d8e..ae86f397 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.Oracle var t2 = g.oracle.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.oracle.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs index c84cf19d..aef0967d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.PostgreSQL var t2 = g.pgsql.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.pgsql.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs index 84daa489..dd62f210 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs @@ -18,6 +18,11 @@ namespace FreeSql.Tests.ShenTong var t2 = g.shentong.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.shentong.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index e0a074d8..d366322c 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -29,6 +29,11 @@ namespace FreeSql.Tests.SqlServer var t2 = g.sqlserver.Ado.SlavePools.Count; } + [Fact] + public void ExecuteTest() + { + Assert.True(g.sqlserver.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs index 02bb40dc..004aec54 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs @@ -17,6 +17,12 @@ namespace FreeSql.Tests.Sqlite { var t2 = g.sqlite.Ado.SlavePools.Count; } + + [Fact] + public void ExecuteTest() + { + Assert.True(g.sqlite.Ado.ExecuteConnectTest()); + } [Fact] public void ExecuteReader() { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a5622151..b588f700 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2479,6 +2479,14 @@ new { id = 1 } 或者 Dictionary<string, object> + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + true: 成功, false: 失败 + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 @@ -2618,6 +2626,14 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + true: 成功, false: 失败 + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index afa01638..238bfc04 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -62,6 +62,14 @@ namespace FreeSql /// DbParameter[] GetDbParamtersByObject(object obj); + /// + /// 测试数据库是否连接正确,本方法执行如下命令: + /// MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + /// Oracle: SELECT 1 FROM dual + /// + /// true: 成功, false: 失败 + bool ExecuteConnectTest(); + /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 /// @@ -243,6 +251,14 @@ namespace FreeSql #if net40 #else #region async + /// + /// 测试数据库是否连接正确,本方法执行如下命令: + /// MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + /// Oracle: SELECT 1 FROM dual + /// + /// true: 成功, false: 失败 + Task ExecuteConnectTestAsync(); + /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 /// diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 5d3100ad..921673f6 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -95,6 +95,27 @@ namespace FreeSql.Internal.CommonProvider var props = tb?.Properties ?? type.GetPropertiesDictIgnoreCase(); return props; } + + public bool ExecuteConnectTest() + { + try + { + switch (DataType) + { + case DataType.Oracle: + case DataType.OdbcOracle: + ExecuteNonQuery(" SELECT 1 FROM dual"); + return true; + } + ExecuteNonQuery(" SELECT 1"); + return true; + } + catch + { + return false; + } + } + public List Query(string cmdText, object parms = null) => Query(null, null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(null, connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index a16381b2..6d40ebcc 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -14,6 +14,26 @@ namespace FreeSql.Internal.CommonProvider { partial class AdoProvider { + async public Task ExecuteConnectTestAsync() + { + try + { + switch (DataType) + { + case DataType.Oracle: + case DataType.OdbcOracle: + await ExecuteNonQueryAsync(" SELECT 1 FROM dual"); + return true; + } + await ExecuteNonQueryAsync(" SELECT 1"); + return true; + } + catch + { + return false; + } + } + public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); From 824d60cbb2cbcffe67a6cddcc73fed84644d33e5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 24 Aug 2020 13:35:48 +0800 Subject: [PATCH 0855/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=8C=96=20Column=20DbType=20=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E5=80=BC=E6=97=B6=E7=9A=84=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=88=A4=E6=96=AD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/MySqlCodeFirstTest.cs | 45 +++++++++++++++++++ .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 45 +++++++++++++++++++ .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 45 +++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 6 +-- .../FreeSql.Provider.Oracle/OracleUtils.cs | 2 +- 5 files changed, 139 insertions(+), 4 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index 8d279e69..cef82a4c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -11,6 +11,51 @@ namespace FreeSql.Tests.MySqlConnector { public class MySqlCodeFirstTest { + [Fact] + public void DateTime_1() + { + var item1 = new TS_DATETIME01 { CreateTime = DateTime.Now }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + + item1.CreateTime = DateTime.Now; + Assert.Equal(1, g.mysql.Update().SetSource(item1).ExecuteAffrows()); + item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + } + class TS_DATETIME01 + { + public Guid Id { get; set; } + [Column(DbType = "datetime NULL")] + public DateTime? CreateTime { get; set; } + } + [Fact] + public void DateTime_2() + { + var item1 = new TS_DATETIME02 { CreateTime = DateTime.Now }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + + item1.CreateTime = DateTime.Now; + Assert.Equal(1, g.mysql.Update().SetSource(item1).ExecuteAffrows()); + item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + } + class TS_DATETIME02 + { + public Guid Id { get; set; } + [Column(DbType = "datetime NOT NULL")] + public DateTime? CreateTime { get; set; } + } + [Fact] public void Text_StringLength_1() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 463a101e..2612b4b2 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -11,6 +11,51 @@ namespace FreeSql.Tests.MySql { public class MySqlCodeFirstTest { + [Fact] + public void DateTime_1() + { + var item1 = new TS_DATETIME01 { CreateTime = DateTime.Now }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + + item1.CreateTime = DateTime.Now; + Assert.Equal(1, g.mysql.Update().SetSource(item1).ExecuteAffrows()); + item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + } + class TS_DATETIME01 + { + public Guid Id { get; set; } + [Column(DbType = "datetime NULL")] + public DateTime? CreateTime { get; set; } + } + [Fact] + public void DateTime_2() + { + var item1 = new TS_DATETIME02 { CreateTime = DateTime.Now }; + Assert.Equal(1, g.mysql.Insert(item1).ExecuteAffrows()); + + var item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + + item1.CreateTime = DateTime.Now; + Assert.Equal(1, g.mysql.Update().SetSource(item1).ExecuteAffrows()); + item2 = g.mysql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + } + class TS_DATETIME02 + { + public Guid Id { get; set; } + [Column(DbType = "datetime NOT NULL")] + public DateTime? CreateTime { get; set; } + } + [Fact] public void Text_StringLength_1() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index f4ee21d6..bfb8976e 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -18,6 +18,51 @@ namespace FreeSql.Tests.PostgreSQL { public class PostgreSQLCodeFirstTest { + [Fact] + public void DateTime_1() + { + var item1 = new TS_DATETIME01 { CreateTime = DateTime.Now }; + Assert.Equal(1, g.pgsql.Insert(item1).ExecuteAffrows()); + + var item2 = g.pgsql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + + item1.CreateTime = DateTime.Now; + Assert.Equal(1, g.pgsql.Update().SetSource(item1).ExecuteAffrows()); + item2 = g.pgsql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + } + class TS_DATETIME01 + { + public Guid Id { get; set; } + [Column(DbType = "timestamp NULL")] + public DateTime? CreateTime { get; set; } + } + [Fact] + public void DateTime_2() + { + var item1 = new TS_DATETIME02 { CreateTime = DateTime.Now }; + Assert.Equal(1, g.pgsql.Insert(item1).ExecuteAffrows()); + + var item2 = g.pgsql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + + item1.CreateTime = DateTime.Now; + Assert.Equal(1, g.pgsql.Update().SetSource(item1).ExecuteAffrows()); + item2 = g.pgsql.Select().Where(a => a.Id == item1.Id).First(); + Assert.NotNull(item2.CreateTime); + Assert.True(1 > Math.Abs(item2.CreateTime.Value.Subtract(item1.CreateTime.Value).TotalSeconds)); + } + class TS_DATETIME02 + { + public Guid Id { get; set; } + [Column(DbType = "timestamp NOT NULL")] + public DateTime? CreateTime { get; set; } + } + [Fact] public void Blob() { diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 24aeb1f8..42b027d0 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -453,12 +453,12 @@ namespace FreeSql.Internal foreach (var col in trytb.Primarys) { col.Attribute.IsNullable = false; - col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "").Trim(); + col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "").Replace(" NULL", "").Trim(); } foreach (var col in trytb.Columns.Values) { var ltp = @"\(([^\)]+)\)"; - col.DbTypeText = Regex.Replace(col.Attribute.DbType.Replace("NOT NULL", "").Trim(), ltp, ""); + col.DbTypeText = Regex.Replace(col.Attribute.DbType.Replace("NOT NULL", "").Replace(" NULL", "").Trim(), ltp, ""); var m = Regex.Match(col.Attribute.DbType, ltp); if (m.Success == false) continue; var sizeStr = m.Groups[1].Value.Trim(); @@ -884,7 +884,7 @@ namespace FreeSql.Internal foreach (var col in tbmid.Primarys) { col.Attribute.IsNullable = false; - col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "").Trim(); + col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "").Replace(" NULL", "").Trim(); } } } diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index c6eaca38..4538a0ff 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -28,7 +28,7 @@ namespace FreeSql.Oracle var ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype, Value = value }; if (col != null) { - var dbtype2 = (OracleDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeTextFull = col.Attribute.DbType.Replace("NOT NULL", "").Trim(), DbTypeText = col.DbTypeText }); + var dbtype2 = (OracleDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeTextFull = col.Attribute.DbType.Replace("NOT NULL", "").Replace(" NULL", "").Trim(), DbTypeText = col.DbTypeText }); switch (dbtype2) { case OracleDbType.Char: From fbf62b6630ac448193f7d6f1ae591c0b380722f7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 25 Aug 2020 12:42:58 +0800 Subject: [PATCH 0856/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Aop.AuditDat?= =?UTF-8?q?aReader=20=E4=BA=8B=E4=BB=B6=E6=8B=A6=E6=88=AA=20DataReader=20?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E5=80=BC=20#436=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ------ .../Oracle/OracleCodeFirstTest.cs | 47 ++++++++++++++++ FreeSql/FreeSql.xml | 20 +++++++ FreeSql/Interface/IAop.cs | 54 ++++++++++++++++++- FreeSql/Internal/CommonExpression.cs | 2 +- .../Internal/CommonProvider/AopProvider.cs | 2 + .../CommonProvider/InsertOrUpdateProvider.cs | 4 +- .../Internal/CommonProvider/InsertProvider.cs | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 4 +- FreeSql/Internal/UtilsExpressionTree.cs | 11 +++- 10 files changed, 136 insertions(+), 26 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs index 8faf37e7..78e554ef 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs @@ -4,15 +4,62 @@ using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Diagnostics; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; +using System.Threading; using Xunit; namespace FreeSql.Tests.Oracle { public class OracleCodeFirstTest { + [Fact] + public void StringNullToEmpty() + { + using (var fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=5;min pool size=1") + .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) + .UseLazyLoading(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine("\r\n߳" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //SQLִǰ + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) + .Build()) + { + var repo = fsql.GetRepository(); + + var item1 = new TS_SL361 { CreatorId = "" }; + repo.Insert(item1); + var item2 = repo.Get(item1.Id); + + Assert.Null(item2.CreatorId); + + fsql.Aop.AuditDataReader += (_, e) => + { + if (e.DataReader.GetFieldType(e.Index) == typeof(string) && e.Value == DBNull.Value) + e.Value = ""; + }; + + item1 = new TS_SL361 { CreatorId = "" }; + repo.Insert(item1); + item2 = repo.Get(item1.Id); + + Assert.Equal(item1.CreatorId, item2.CreatorId); + } + } + class TS_SNTE + { + [Column(IsIdentity = true)] + public long Id { get; set; } + public string CreatorId { get; set; } + } + [Fact] public void StringLength36() { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b588f700..c3f1bb5e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2813,6 +2813,11 @@ Insert/Update自动值处理 + + + ADO.NET DataReader 拦截 + + 监视数据库命令对象(执行前,调试) @@ -2978,6 +2983,21 @@ 获取实体的属性值,也可以设置实体的属性新值 + + + ADO.NET 数据流读取对象 + + + + + DataReader 对应的 Index 位置 + + + + + 获取 Index 对应的值,也可以设置拦截的新值 + + 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 diff --git a/FreeSql/Interface/IAop.cs b/FreeSql/Interface/IAop.cs index bef5f515..a3913c4d 100644 --- a/FreeSql/Interface/IAop.cs +++ b/FreeSql/Interface/IAop.cs @@ -57,6 +57,12 @@ namespace FreeSql event EventHandler AuditValue; EventHandler AuditValueHandler { get; } + /// + /// ADO.NET DataReader 拦截 + /// + event EventHandler AuditDataReader; + EventHandler AuditDataReaderHandler { get; } + /// /// 监视数据库命令对象(执行前,调试) /// @@ -318,15 +324,59 @@ namespace FreeSql.Aop set { _value = value; - this.IsChanged = true; + this.ValueIsChanged = true; } } private object _value; - public bool IsChanged { get; private set; } + public bool ValueIsChanged { get; private set; } } public enum AuditValueType { Update, Insert, InsertOrUpdate } #endregion + #region AuditDataReader + public class AuditDataReaderEventArgs : EventArgs + { + public AuditDataReaderEventArgs(DbDataReader dataReader, int index) + { + this.DataReader = dataReader; + this.Index = index; + } + + /// + /// ADO.NET 数据流读取对象 + /// + public DbDataReader DataReader { get; } + /// + /// DataReader 对应的 Index 位置 + /// + public int Index { get; } + /// + /// 获取 Index 对应的值,也可以设置拦截的新值 + /// + public object Value + { + get + { + if (_valueIsGeted == false) + { + _value = DataReader.GetValue(Index); + _valueIsGeted = true; + } + return _value; + } + set + { + _value = value; + ValueIsChanged = true; + _valueIsGeted = true; + } + } + private object _value; + internal bool _valueIsGeted; + public bool ValueIsChanged { get; private set; } + } + #endregion + #region CommandBefore/After public class CommandBeforeEventArgs : EventArgs { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 89c9e696..8c867350 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -309,7 +309,7 @@ namespace FreeSql.Internal return Utils.GetDataReaderValue(parent.Property.PropertyType, null); return Utils.GetDataReaderValue(parent.CsType, null); } - object objval = dr.GetValue(++index); + object objval = Utils.InternalDataReaderGetValue(_common, dr, ++index); // dr.GetValue(++index); if (dbValue != null) dbValue.DbValue = objval == DBNull.Value ? null : objval; if (parent.CsType != parent.MapType) objval = Utils.GetDataReaderValue(parent.MapType, objval); diff --git a/FreeSql/Internal/CommonProvider/AopProvider.cs b/FreeSql/Internal/CommonProvider/AopProvider.cs index 1f426e04..648d29fe 100644 --- a/FreeSql/Internal/CommonProvider/AopProvider.cs +++ b/FreeSql/Internal/CommonProvider/AopProvider.cs @@ -18,6 +18,7 @@ namespace FreeSql.Internal.CommonProvider public event EventHandler SyncStructureAfter; public event EventHandler AuditValue; + public event EventHandler AuditDataReader; public event EventHandler CommandBefore; public event EventHandler CommandAfter; @@ -36,6 +37,7 @@ namespace FreeSql.Internal.CommonProvider public EventHandler SyncStructureAfterHandler => SyncStructureAfter; public EventHandler AuditValueHandler => AuditValue; + public EventHandler AuditDataReaderHandler => AuditDataReader; public EventHandler CommandBeforeHandler => CommandBefore; public EventHandler CommandAfterHandler => CommandAfter; diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 61d2bcb3..4a2df3fc 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -81,7 +81,7 @@ namespace FreeSql.Internal.CommonProvider object val = col.GetValue(d); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); - if (auditArgs.IsChanged) + if (auditArgs.ValueIsChanged) { col.SetValue(d, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) @@ -101,7 +101,7 @@ namespace FreeSql.Internal.CommonProvider object val = col.GetValue(data); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); - if (auditArgs.IsChanged) + if (auditArgs.ValueIsChanged) { col.SetValue(data, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 1dc8da61..30495e56 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -152,7 +152,7 @@ namespace FreeSql.Internal.CommonProvider { var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Insert, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); - if (auditArgs.IsChanged) + if (auditArgs.ValueIsChanged) { col.SetValue(data, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index a2b50eaa..63a46ea0 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -353,7 +353,7 @@ namespace FreeSql.Internal.CommonProvider object val = col.GetValue(d); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); - if (auditArgs.IsChanged) + if (auditArgs.ValueIsChanged) { col.SetValue(d, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) @@ -373,7 +373,7 @@ namespace FreeSql.Internal.CommonProvider object val = col.GetValue(data); var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.Update, col, table.Properties[col.CsName], val); orm.Aop.AuditValueHandler(sender, auditArgs); - if (auditArgs.IsChanged) + if (auditArgs.ValueIsChanged) { col.SetValue(data, val = auditArgs.Value); if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 42b027d0..29e03050 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1324,7 +1324,14 @@ namespace FreeSql.Internal internal static PropertyInfo PropertyDataReaderFieldCount = typeof(DbDataReader).GetProperty("FieldCount"); internal static object InternalDataReaderGetValue(CommonUtils commonUtil, DbDataReader dr, int index) { - if (commonUtil._orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null; + var orm = commonUtil._orm; + if (orm.Aop.AuditDataReaderHandler != null) + { + var args = new Aop.AuditDataReaderEventArgs(dr, index); + orm.Aop.AuditDataReaderHandler(orm, args); + return args.Value; + } + if (orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null; //OdbcDameng 不会报错 return dr.GetValue(index); } internal static RowInfo ExecuteArrayRowReadClassOrTuple(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) @@ -1447,7 +1454,7 @@ namespace FreeSql.Internal var name = row2.GetName(a); //expando[name] = row2.GetValue(a); if (expandodic.ContainsKey(name)) continue; - expandodic.Add(name, row2.GetValue(a)); + expandodic.Add(name, Utils.InternalDataReaderGetValue(_commonUtils, row2, a)); } //expando = expandodic; return new RowInfo(expandodic, fc); From d0c5d84780888e30d292a27e2c38f80620711162 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 25 Aug 2020 13:25:27 +0800 Subject: [PATCH 0857/1029] v1.8.0 #325 #397 #401 #398 #395 #392 #391 #405 #412 #267 #113 #436 #402 #403 #411 #371 #427 #384 #413 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 4 ++-- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 4 ++-- .../FreeSql.Provider.SqlServerForSystem.csproj | 4 ++-- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 8cd4b7aa..1f86b925 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index b110fca8..23e9cbd8 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b8ebc422..6d3416ae 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 078fe794..0f724b74 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 1a94dc78..86d0ca5c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0-preview0821 + 1.8.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 0c7503eb..abb54786 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 5dcf289f..be01e79b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e4d6b103..2d758a16 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0-preview0821 + 1.8.0 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1452ccb5..9d751a62 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index c9976187..942a5926 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index ec93a260..70673472 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index eb5add33..59be3394 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 232daff8..e8d5ab54 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d70745cb..7a972e59 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 5a654328..9d10e24c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index cd3fe253..674d0ed6 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 0f55e375..82c3a609 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index c6bdb9d6..776a007e 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c81428c0..4e4570fc 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index caea7b46..c0d32f7a 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index dfd22328..220f78b5 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0-preview0821 + 1.8.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 6cbc452e466da69ea6f1d31202a6ec1504216f38 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 25 Aug 2020 14:08:02 +0800 Subject: [PATCH 0858/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20WhereDynamic?= =?UTF-8?q?Filter=20System.Text.Json=20=E4=B8=8B=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 21 ++++++++++++++++++- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- .../SelectProvider/Select0Provider.cs | 14 +++++++++++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 127586bd..4ce60e3a 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -175,6 +175,16 @@ namespace base_entity ""Operator"" : ""eq"", ""Value"" : ""product-4"" }, + { + ""Field"" : ""testint"", + ""Operator"" : ""Range"", + ""Value"" : [100,200] + }, + { + ""Field"" : ""testint"", + ""Operator"" : ""Range"", + ""Value"" : [""101"",""202""] + }, ] } "); @@ -228,6 +238,16 @@ namespace base_entity ""Field"" : ""testint"", ""Operator"" : 8, ""Value"" : ""12"" + }, + { + ""Field"" : ""testint"", + ""Operator"" : ""Range"", + ""Value"" : [100,200] + }, + { + ""Field"" : ""testint"", + ""Operator"" : ""Range"", + ""Value"" : [""101"",""202""] } ] } @@ -235,7 +255,6 @@ namespace base_entity Products.Select.WhereDynamicFilter(wdy1).ToList(); Products.Select.WhereDynamicFilter(wdy2).ToList(); - var items1 = Products.Select.Limit(10).OrderByDescending(a => a.CreateTime).ToList(); var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 89c341d5..89ea4ce5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -551,6 +551,20 @@ namespace FreeSql.Internal.CommonProvider fiValueList.Add(string.Concat(fiValueIeItem)); return fiValueList.ToArray(); } + var fiValueType = fi.Value.GetType(); + if (fiValueType.FullName == "System.Text.Json.JsonElement") + { + var fiValueKind = fiValueType.GetProperty("ValueKind").GetValue(fi.Value, null).ToString(); + if (fiValueKind == "Array") + { + fiValueIe = fiValueType.GetMethod("EnumerateArray", new Type[0])?.Invoke(fi.Value, null) as IEnumerable; + var fiValueList = new List(); + foreach (var fiValueIeItem in fiValueIe) + fiValueList.Add(string.Concat(fiValueIeItem)); + return fiValueList.ToArray(); + } + return fi.Value.ToString().Split(','); + } return new string[0]; } From a9f9832b5c5c9c7b56d4a5711ab95c859f507fb8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 25 Aug 2020 14:11:02 +0800 Subject: [PATCH 0859/1029] v1.9.0-preview0825 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 37 insertions(+), 21 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1f86b925..1467c1e7 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 23e9cbd8..77ab70c2 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6d3416ae..483058d0 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 0f724b74..7b061c66 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 86d0ca5c..22ba0d72 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.0 + 1.9.0-preview0825 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index abb54786..2e13d6f0 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index be01e79b..fc30132e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 2d758a16..c7a90aa0 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.0 + 1.9.0-preview0825 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9d751a62..40453b7d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 942a5926..05762ba6 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 70673472..c1cc164e 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 59be3394..7bef76b9 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e8d5ab54..35d2888d 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7a972e59..eeb48a99 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 9d10e24c..eaff4b37 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 674d0ed6..9d9f2fc0 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 82c3a609..4411ddff 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 776a007e..3c4f5297 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4e4570fc..cdd52781 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index c0d32f7a..011dfebb 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 220f78b5..6803ae92 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.0 + 1.9.0-preview0825 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From a634192af96e5882bb0c51c2437781ff4ff925c4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 25 Aug 2020 16:36:01 +0800 Subject: [PATCH 0860/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20InsertOrUpda?= =?UTF-8?q?te=20AsType=20=E4=BD=BF=E7=94=A8=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E5=8F=8B=E5=A5=BD=E6=8F=90=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- .../CommonProvider/InsertOrUpdateProvider.cs | 19 ++----------------- 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 4a2df3fc..1d8a13c4 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -72,30 +72,15 @@ namespace FreeSql.Internal.CommonProvider public static void AuditDataValue(object sender, IEnumerable data, IFreeSql orm, TableInfo table, Dictionary changedDict) { if (data?.Any() != true) return; - if (orm.Aop.AuditValueHandler == null) return; foreach (var d in data) - { - if (d == null) continue; - foreach (var col in table.Columns.Values) - { - object val = col.GetValue(d); - var auditArgs = new Aop.AuditValueEventArgs(Aop.AuditValueType.InsertOrUpdate, col, table.Properties[col.CsName], val); - orm.Aop.AuditValueHandler(sender, auditArgs); - if (auditArgs.ValueIsChanged) - { - col.SetValue(d, val = auditArgs.Value); - if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) - changedDict.Add(col.Attribute.Name, true); - } - } - } + AuditDataValue(sender, d, orm, table, changedDict); } public static void AuditDataValue(object sender, T1 data, IFreeSql orm, TableInfo table, Dictionary changedDict) { - if (orm.Aop.AuditValueHandler == null) return; if (data == null) return; if (typeof(T1) == typeof(object) && new[] { table.Type, table.TypeLazy }.Contains(data.GetType()) == false) throw new Exception($"操作的数据类型({data.GetType().DisplayCsharp()}) 与 AsType({table.Type.DisplayCsharp()}) 不一致,请检查。"); + if (orm.Aop.AuditValueHandler == null) return; foreach (var col in table.Columns.Values) { object val = col.GetValue(data); From 6ae92976849a5e2e3edaf8197380df4fcc388d46 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 27 Aug 2020 00:48:08 +0800 Subject: [PATCH 0861/1029] v1.8.1 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../ShenTong/Curd/ShenTongSelectTest.cs | 3 +- .../Sqlite/Curd/SqliteSelectTest.cs | 16 ++ FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 159 ------------------ FreeSql/Internal/CommonExpression.cs | 2 + .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 26 files changed, 57 insertions(+), 181 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1467c1e7..98a11dd9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 77ab70c2..f31f6ce4 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 483058d0..7837526f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 7b061c66..ebc89fa4 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 22ba0d72..1b1f9dcd 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0825 + 1.8.1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 2e13d6f0..3bd6c82c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index fc30132e..825bf8a1 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index c7a90aa0..b55b263d 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0825 + 1.8.1 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs index 39a32ff7..fed62921 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs @@ -883,7 +883,8 @@ namespace FreeSql.Tests.ShenTong b.Key, cou = b.Count(), sum2 = b.Sum(b.Value.TypeGuid), - sum3 = b.Sum(b.Value.Type.Parent.Id) + sum3 = b.Sum(b.Value.Type.Parent.Id), + Name = aggsql1 == null ? "未定义类型" : b.Key }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index b13c6c65..a26bfbd5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -773,7 +773,23 @@ namespace FreeSql.Tests.Sqlite sum2 = b.Sum(b.Value.TypeGuid), sum3 = b.Sum(b.Value.Type.Parent.Id) }); + + + + var aggsql4 = select + .GroupBy(a => a.Title) + .ToList(b => new TestGroupByDto01 + { + Name = b.Key, + TotalCount = b.Count() + }); } + class TestGroupByDto01 + { + public string Name { get; set; } + public int TotalCount { get; set; } + } + [Fact] public void ToAggregate() { diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 40453b7d..4fbf1d1f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c3f1bb5e..e19b9432 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2626,153 +2626,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3529,12 +3382,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3605,12 +3452,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 8c867350..705a1aa2 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -142,7 +142,9 @@ namespace FreeSql.Internal if (grouping != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { field.Append(grouping._field); + var parentProp = parent.Property; grouping._map.CopyTo(parent); + parent.Property = parentProp; //若不加此行,会引用 GroupBy(..).ToList(a => new Dto { key = a.Key }) null 错误,CopyTo 之后 Property 变为 null return false; } parent.CsType = exp.Type; diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 05762ba6..f1f5beeb 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index c1cc164e..c8c34f0e 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 7bef76b9..820726bc 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 35d2888d..5e948a72 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index eeb48a99..f3001404 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index eaff4b37..fe5dbfe7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 9d9f2fc0..acc4b2b3 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 4411ddff..6808417e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 3c4f5297..0382ab4d 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cdd52781..ddf554a5 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 011dfebb..eebac265 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 6803ae92..15bc275a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0825 + 1.8.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 2326c34126bee387b77d4b82e3eb19cbcb0bde38 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 27 Aug 2020 01:10:34 +0800 Subject: [PATCH 0862/1029] update qq group --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 79202843..9b18aaac 100644 --- a/readme.md +++ b/readme.md @@ -183,7 +183,7 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [feijie999](https://github.com/feijie999)、 constantine -QQ群:4336577(已满)、8578575(在线) +QQ群:4336577(已满)、8578575(在线)、52508226(在线) ## 💕  Donation From b69a65903357865eb67fdcf7d5409b87e7c2377d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 27 Aug 2020 12:10:14 +0800 Subject: [PATCH 0863/1029] update readme --- readme.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 9b18aaac..83186f0d 100644 --- a/readme.md +++ b/readme.md @@ -192,6 +192,4 @@ L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.9 > Thank you for your donation -| [Alipay](https://images.cnblogs.com/cnblogs_com/kellynic/133561/o_200417052520IMG_7936(20200123-155553).png) | [WeChat](https://images.cnblogs.com/cnblogs_com/kellynic/133561/o_200417052707IMG_7935(20200123-155553).png) | -| - | - | -| | | +| [Alipay](https://www.cnblogs.com/FreeSql/gallery/image/290628.html) | [WeChat](https://www.cnblogs.com/FreeSql/gallery/image/290627.html) | From a46ea19e56ad971a0e467aeba02fe203dece8d98 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 27 Aug 2020 12:17:19 +0800 Subject: [PATCH 0864/1029] update readme --- readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 83186f0d..de2c1507 100644 --- a/readme.md +++ b/readme.md @@ -188,8 +188,10 @@ QQ群:4336577(已满)、8578575(在线)、52508226(在线) ## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 -无名 100元、蛰伏 99.99元、TCYM 66.66元 +无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元 > Thank you for your donation -| [Alipay](https://www.cnblogs.com/FreeSql/gallery/image/290628.html) | [WeChat](https://www.cnblogs.com/FreeSql/gallery/image/290627.html) | +- [Alipay](https://www.cnblogs.com/FreeSql/gallery/image/290628.html) + +- [WeChat](https://www.cnblogs.com/FreeSql/gallery/image/290627.html) From 00d2199fc3c59b751e1d08a4838dcabedf24c39f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 28 Aug 2020 04:05:00 +0800 Subject: [PATCH 0865/1029] update Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index de2c1507..71ef6eb8 100644 --- a/readme.md +++ b/readme.md @@ -188,7 +188,7 @@ QQ群:4336577(已满)、8578575(在线)、52508226(在线) ## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 -无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元 +无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元 > Thank you for your donation From b1029be4700d6611da92069ad2c88a5a98b96e20 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 31 Aug 2020 18:54:48 +0800 Subject: [PATCH 0866/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20=20AdoNet=20?= =?UTF-8?q?CRUD=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=E5=88=B0=20namespac?= =?UTF-8?q?e=20FreeSql=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Extensions/AdoNetExtensions.cs | 381 +++++++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 378 +-------- FreeSql/FreeSql.xml | 793 +++++++++++------- 3 files changed, 861 insertions(+), 691 deletions(-) create mode 100644 FreeSql/Extensions/AdoNetExtensions.cs diff --git a/FreeSql/Extensions/AdoNetExtensions.cs b/FreeSql/Extensions/AdoNetExtensions.cs new file mode 100644 index 00000000..ac63b308 --- /dev/null +++ b/FreeSql/Extensions/AdoNetExtensions.cs @@ -0,0 +1,381 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; + +namespace FreeSql +{ + public static class AdoNetExtensions + { + #region Ado.net 扩展方法,类似于 Dapper + + static Dictionary _dicCurd = new Dictionary(); + static object _dicCurdLock = new object(); + static IFreeSql GetCrud(IDbConnection dbconn) + { + if (dbconn == null) throw new ArgumentNullException($"{nameof(dbconn)} 不能为 null"); ; + Type dbconType = dbconn.GetType(); + var connType = dbconType.UnderlyingSystemType; + if (_dicCurd.TryGetValue(connType, out var fsql)) return fsql; + + Type providerType = null; + switch (connType.Name) + { + case "MySqlConnection": + providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(connType); + if (providerType == null) providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); + break; + case "SqlConnection": + providerType = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); + break; + case "NpgsqlConnection": + providerType = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); + break; + case "OracleConnection": + providerType = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); + break; + case "SQLiteConnection": + providerType = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); + break; + case "DmConnection": + providerType = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Dameng.dll,可前往 nuget 下载"); + break; + case "OscarConnection": + providerType = Type.GetType("FreeSql.ShenTong.ShenTongProvider`1,FreeSql.Provider.ShenTong")?.MakeGenericType(connType); + if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.ShenTong.dll,可前往 nuget 下载"); + break; + default: + throw new Exception("未实现"); + } + lock (_dicCurdLock) + { + if (_dicCurd.TryGetValue(connType, out fsql)) return fsql; + lock (_dicCurdLock) + _dicCurd.Add(connType, fsql = Activator.CreateInstance(providerType, new object[] { null, null, null }) as IFreeSql); + } + return fsql; + } + static IFreeSql GetCrud(IDbTransaction dbtran) + { + if (dbtran == null) throw new ArgumentNullException($"{nameof(dbtran)} 不能为 null"); + return GetCrud(dbtran.Connection); + } + + /// + /// 获取 IDbConnection 对应的 IFreeSql 实例 + /// + /// + /// + public static IFreeSql GetIFreeSql(this IDbConnection that) => GetCrud(that); + + #region IDbConnection + /// + /// 插入数据 + /// + /// + /// + public static IInsert Insert(this IDbConnection that) where T1 : class => GetCrud(that).Insert().WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体数组 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, List source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbConnection that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); + + /// + /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + /// 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 + /// 达梦: merge into + /// 人大金仓:on conflict do update + /// 神通:merge into + /// MsAccess:不支持 + /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + /// + /// + /// + public static IInsertOrUpdate InsertOrUpdate(this IDbConnection that) where T1 : class => GetCrud(that).InsertOrUpdate().WithConnection(that as DbConnection); + + /// + /// 修改数据 + /// + /// + /// + public static IUpdate Update(this IDbConnection that) where T1 : class => GetCrud(that).Update().WithConnection(that as DbConnection); + /// + /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IUpdate Update(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithConnection(that as DbConnection); + + /// + /// 查询数据 + /// + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class => GetCrud(that).Select().WithConnection(that as DbConnection); + /// + /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static ISelect Select(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithConnection(that as DbConnection); + + /// + /// 删除数据 + /// + /// + /// + public static IDelete Delete(this IDbConnection that) where T1 : class => GetCrud(that).Delete().WithConnection(that as DbConnection); + /// + /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IDelete Delete(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithConnection(that as DbConnection); + + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class => + GetCrud(that).Select().From((s, b) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class => + GetCrud(that).Select().From((s, b, c) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class => + GetCrud(that).Select().From((s, b, c, d) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => + GetCrud(that).Select().From((s, b, c, d, e) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => + GetCrud(that).Select().From((s, b, c, d, e, f) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => + GetCrud(that).Select().From((s, b, c, d, e, f, g) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) 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 => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbConnection that) 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 => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i, j) => s); + #endregion + + #region IDbTransaction + /// + /// 插入数据 + /// + /// + /// + public static IInsert Insert(this IDbTransaction that) where T1 : class => GetCrud(that).Insert().WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体数组 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, List source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + /// + /// 插入数据,传入实体集合 + /// + /// + /// + /// + public static IInsert Insert(this IDbTransaction that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); + + /// + /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + /// 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 + /// 达梦: merge into + /// 人大金仓:on conflict do update + /// 神通:merge into + /// MsAccess:不支持 + /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + /// + /// + /// + public static IInsertOrUpdate InsertOrUpdate(this IDbTransaction that) where T1 : class => GetCrud(that).InsertOrUpdate().WithTransaction(that as DbTransaction); + + /// + /// 修改数据 + /// + /// + /// + public static IUpdate Update(this IDbTransaction that) where T1 : class => GetCrud(that).Update().WithTransaction(that as DbTransaction); + /// + /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IUpdate Update(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithTransaction(that as DbTransaction); + + /// + /// 查询数据 + /// + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class => GetCrud(that).Select().WithTransaction(that as DbTransaction); + /// + /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static ISelect Select(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithTransaction(that as DbTransaction); + + /// + /// 删除数据 + /// + /// + /// + public static IDelete Delete(this IDbTransaction that) where T1 : class => GetCrud(that).Delete().WithTransaction(that as DbTransaction); + /// + /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + /// + /// + /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// + public static IDelete Delete(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithTransaction(that as DbTransaction); + + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class => + GetCrud(that).Select().From((s, b) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class => + GetCrud(that).Select().From((s, b, c) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class => + GetCrud(that).Select().From((s, b, c, d) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => + GetCrud(that).Select().From((s, b, c, d, e) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => + GetCrud(that).Select().From((s, b, c, d, e, f) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => + GetCrud(that).Select().From((s, b, c, d, e, f, g) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) 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 => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i) => s); + /// + /// 多表查询 + /// + /// + public static ISelect Select(this IDbTransaction that) 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 => + GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i, j) => s); + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index c90437a1..0a3cf29b 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -137,7 +137,7 @@ public static partial class FreeSqlGlobalExtensions if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, true); return Activator.CreateInstance(that, ctorParms .Select(a => a.ParameterType.IsInterface || a.ParameterType.IsAbstract || a.ParameterType == typeof(string) || a.ParameterType.IsArray ? - null : + null : Activator.CreateInstance(a.ParameterType, null)).ToArray()); } internal static NewExpression InternalNewExpression(this Type that) @@ -348,7 +348,7 @@ public static partial class FreeSqlGlobalExtensions var select = that as Select1Provider; var tb = select._tables[0].Table; var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) - .Where(a => a != null && + .Where(a => a != null && a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray(); @@ -451,7 +451,7 @@ public static partial class FreeSqlGlobalExtensions var sql2InnerJoinOn = up == false ? string.Join(" and ", tbref.Columns.Select((a, z) => $"wct2.{select._commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)} = wct1.{select._commonUtils.QuoteSqlName(a.Attribute.Name)}")) : string.Join(" and ", tbref.Columns.Select((a, z) => $"wct2.{select._commonUtils.QuoteSqlName(a.Attribute.Name)} = wct1.{select._commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}")); - + var sql2ctePath = ""; if (pathSelector != null) { @@ -518,374 +518,4 @@ SELECT "); } #endregion - #region Ado.net 扩展方法,类似于 Dapper - - static Dictionary _dicCurd = new Dictionary(); - static object _dicCurdLock = new object(); - static IFreeSql GetCrud(IDbConnection dbconn) - { - if (dbconn == null) throw new ArgumentNullException($"{nameof(dbconn)} 不能为 null"); ; - Type dbconType = dbconn.GetType(); - var connType = dbconType.UnderlyingSystemType; - if (_dicCurd.TryGetValue(connType, out var fsql)) return fsql; - - Type providerType = null; - switch (connType.Name) - { - case "MySqlConnection": - providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(connType); - if (providerType == null) providerType = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载"); - break; - case "SqlConnection": - providerType = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载"); - break; - case "NpgsqlConnection": - providerType = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载"); - break; - case "OracleConnection": - providerType = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载"); - break; - case "SQLiteConnection": - providerType = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载"); - break; - case "DmConnection": - providerType = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Dameng.dll,可前往 nuget 下载"); - break; - case "OscarConnection": - providerType = Type.GetType("FreeSql.ShenTong.ShenTongProvider`1,FreeSql.Provider.ShenTong")?.MakeGenericType(connType); - if (providerType == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.ShenTong.dll,可前往 nuget 下载"); - break; - default: - throw new Exception("未实现"); - } - lock (_dicCurdLock) - { - if (_dicCurd.TryGetValue(connType, out fsql)) return fsql; - lock (_dicCurdLock) - _dicCurd.Add(connType, fsql = Activator.CreateInstance(providerType, new object[] { null, null, null }) as IFreeSql); - } - return fsql; - } - static IFreeSql GetCrud(IDbTransaction dbtran) - { - if (dbtran == null) throw new ArgumentNullException($"{nameof(dbtran)} 不能为 null"); - return GetCrud(dbtran.Connection); - } - - /// - /// 获取 IDbConnection 对应的 IFreeSql 实例 - /// - /// - /// - public static IFreeSql GetIFreeSql(this IDbConnection that) => GetCrud(that); - - #region IDbConnection - /// - /// 插入数据 - /// - /// - /// - public static IInsert Insert(this IDbConnection that) where T1 : class => GetCrud(that).Insert().WithConnection(that as DbConnection); - /// - /// 插入数据,传入实体 - /// - /// - /// - /// - public static IInsert Insert(this IDbConnection that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); - /// - /// 插入数据,传入实体数组 - /// - /// - /// - /// - public static IInsert Insert(this IDbConnection that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - public static IInsert Insert(this IDbConnection that, List source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - public static IInsert Insert(this IDbConnection that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); - - /// - /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - /// 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 - /// 达梦: merge into - /// 人大金仓:on conflict do update - /// 神通:merge into - /// MsAccess:不支持 - /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) - /// - /// - /// - public static IInsertOrUpdate InsertOrUpdate(this IDbConnection that) where T1 : class => GetCrud(that).InsertOrUpdate().WithConnection(that as DbConnection); - - /// - /// 修改数据 - /// - /// - /// - public static IUpdate Update(this IDbConnection that) where T1 : class => GetCrud(that).Update().WithConnection(that as DbConnection); - /// - /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static IUpdate Update(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithConnection(that as DbConnection); - - /// - /// 查询数据 - /// - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class => GetCrud(that).Select().WithConnection(that as DbConnection); - /// - /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static ISelect Select(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithConnection(that as DbConnection); - - /// - /// 删除数据 - /// - /// - /// - public static IDelete Delete(this IDbConnection that) where T1 : class => GetCrud(that).Delete().WithConnection(that as DbConnection); - /// - /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static IDelete Delete(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithConnection(that as DbConnection); - - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class => - GetCrud(that).Select().From((s, b) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class => - GetCrud(that).Select().From((s, b, c) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class => - GetCrud(that).Select().From((s, b, c, d) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => - GetCrud(that).Select().From((s, b, c, d, e) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => - GetCrud(that).Select().From((s, b, c, d, e, f) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => - GetCrud(that).Select().From((s, b, c, d, e, f, g) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => - GetCrud(that).Select().From((s, b, c, d, e, f, g, h) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) 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 => - GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbConnection that) 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 => - GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i, j) => s); - #endregion - - #region IDbTransaction - /// - /// 插入数据 - /// - /// - /// - public static IInsert Insert(this IDbTransaction that) where T1 : class => GetCrud(that).Insert().WithTransaction(that as DbTransaction); - /// - /// 插入数据,传入实体 - /// - /// - /// - /// - public static IInsert Insert(this IDbTransaction that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); - /// - /// 插入数据,传入实体数组 - /// - /// - /// - /// - public static IInsert Insert(this IDbTransaction that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - public static IInsert Insert(this IDbTransaction that, List source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); - /// - /// 插入数据,传入实体集合 - /// - /// - /// - /// - public static IInsert Insert(this IDbTransaction that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); - - /// - /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - /// 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 - /// 达梦: merge into - /// 人大金仓:on conflict do update - /// 神通:merge into - /// MsAccess:不支持 - /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) - /// - /// - /// - public static IInsertOrUpdate InsertOrUpdate(this IDbTransaction that) where T1 : class => GetCrud(that).InsertOrUpdate().WithTransaction(that as DbTransaction); - - /// - /// 修改数据 - /// - /// - /// - public static IUpdate Update(this IDbTransaction that) where T1 : class => GetCrud(that).Update().WithTransaction(that as DbTransaction); - /// - /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static IUpdate Update(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithTransaction(that as DbTransaction); - - /// - /// 查询数据 - /// - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class => GetCrud(that).Select().WithTransaction(that as DbTransaction); - /// - /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static ISelect Select(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithTransaction(that as DbTransaction); - - /// - /// 删除数据 - /// - /// - /// - public static IDelete Delete(this IDbTransaction that) where T1 : class => GetCrud(that).Delete().WithTransaction(that as DbTransaction); - /// - /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - /// - /// - /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - /// - public static IDelete Delete(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithTransaction(that as DbTransaction); - - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class => - GetCrud(that).Select().From((s, b) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class => - GetCrud(that).Select().From((s, b, c) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class => - GetCrud(that).Select().From((s, b, c, d) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => - GetCrud(that).Select().From((s, b, c, d, e) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => - GetCrud(that).Select().From((s, b, c, d, e, f) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => - GetCrud(that).Select().From((s, b, c, d, e, f, g) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => - GetCrud(that).Select().From((s, b, c, d, e, f, g, h) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) 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 => - GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i) => s); - /// - /// 多表查询 - /// - /// - public static ISelect Select(this IDbTransaction that) 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 => - GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i, j) => s); - #endregion - - #endregion -} \ No newline at end of file +} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e19b9432..a7b0965c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -606,6 +606,323 @@ 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 + + + 获取 IDbConnection 对应的 IFreeSql 实例 + + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + + + + 多表查询 + + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null @@ -2626,6 +2943,153 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3382,6 +3846,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3452,6 +3922,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3771,323 +4247,6 @@ 递归层级 - - - 获取 IDbConnection 对应的 IFreeSql 实例 - - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - 使用 and 拼接两个 lambda 表达式 From 94401334db327a1c06d49f975f32f4fb50436afa Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 31 Aug 2020 19:00:16 +0800 Subject: [PATCH 0867/1029] v1.9.0-preview0901 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 21 insertions(+), 30 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 98a11dd9..cd3f5979 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index f31f6ce4..e494f93a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 7837526f..42069c21 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index ebc89fa4..3e316cdd 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 1b1f9dcd..56d10d1b 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.1 + 1.9.0-preview0901 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3bd6c82c..03a53377 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 825bf8a1..abb867fa 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,14 +532,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index b55b263d..fddb8c7a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.1 + 1.9.0-preview0901 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 4fbf1d1f..5d494fa3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index f1f5beeb..cfdfe54e 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index c8c34f0e..4b1fc014 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 820726bc..f77b1ad2 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5e948a72..92b4e686 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f3001404..86d39a46 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index fe5dbfe7..e66129dd 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index acc4b2b3..4364fc5c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 6808417e..cbe5e542 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 0382ab4d..b01e0b55 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index ddf554a5..babd687e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index eebac265..4f50f7de 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 15bc275a..c35b2cf4 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.1 + 1.9.0-preview0901 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From ea81fde340119a2f6b8f2bb87710a6f8bddd0a78 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 2 Sep 2020 18:19:49 +0800 Subject: [PATCH 0868/1029] =?UTF-8?q?-=20=E4=BF=AE=E6=AD=A3=20SqlServer=20?= =?UTF-8?q?UseConnectionFactory=20=E7=B1=BB=E5=9E=8B=E6=A0=87=E8=AF=86?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index f7b1be7d..52edb94b 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -23,7 +23,7 @@ namespace FreeSql.SqlServer base._util = util; if (connectionFactory != null) { - var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Sqlite, connectionFactory); + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.SqlServer, connectionFactory); MasterPool = pool; _CreateCommandConnection = pool.TestConnection; return; From 9e9891ded45dfa5a8f14e33ef63bff38c84c31ba Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 2 Sep 2020 18:29:42 +0800 Subject: [PATCH 0869/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IUpdate/IDel?= =?UTF-8?q?ete=20WhereIf=20=E6=96=B9=E6=B3=95=20#466=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 383 ++++++++++-------- FreeSql/Interface/Curd/IDelete.cs | 8 + FreeSql/Interface/Curd/IUpdate.cs | 8 + .../Internal/CommonProvider/DeleteProvider.cs | 7 +- .../Internal/CommonProvider/UpdateProvider.cs | 7 +- 5 files changed, 235 insertions(+), 178 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a7b0965c..0c309880 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1260,6 +1260,15 @@ lambda表达式条件 + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 + + true 时生效 + lambda表达式条件 + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) @@ -2670,6 +2679,15 @@ lambda表达式条件 + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) + 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 + + true 时生效 + lambda表达式条件 + + 原生sql语法条件,Where("id = ?id", new { id = 1 }) @@ -3311,182 +3329,7 @@ - - 获取 Index 对应的值,也可以设置拦截的新值 - - - - - 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 - - - - - 发生的错误 - - - - - 执行SQL命令,返回的结果 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 - - - - - 备注 - - - - - 发生的错误 - - - - - 耗时(单位:Ticks) - - - - - 耗时(单位:毫秒) - - - - - 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 - - - - - 转小写同步结构,适用 PostgreSQL - - - - - 转大写同步结构,适用 Oracle/达梦/人大金仓 - - - - - 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 - 本功能会影响 IFreeSql 首次访问的速度。 - 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 - - - - - 不使用命令参数化执行,针对 Insert/Update - - - - - 是否生成命令参数化执行,针对 lambda 表达式解析 - 注意:常量不会参数化,变量才会做参数化 - var id = 100; - fsql.Select<T>().Where(a => a.id == id) 会参数化 - fsql.Select<T>().Where(a => a.id == 100) 不会参数化 - - - - - 延时加载导航属性对象,导航属性需要声明 virtual - - - - - 将实体类型与数据库对比,返回DDL语句 - - - - - - - 将实体类型集合与数据库对比,返回DDL语句 - - 实体类型 - - - - - 将实体类型与数据库对比,返回DDL语句(指定表名) - - 实体类型 - 指定表名对比 - - - - - 同步实体类型到数据库 - 注意:生产环境中谨慎使用 - - - - - - 同步实体类型集合到数据库 - 注意:生产环境中谨慎使用 - - - - - - 同步实体类型到数据库(指定表名) - 注意:生产环境中谨慎使用 - - 实体类型 - 指定表名对比 - 强制同步结构,无视缓存每次都同步 - - - - 根据 System.Type 获取数据库信息 - - - - - - - FreeSql FluentApi 配置实体,方法名与特性相同 - - - - - - - - FreeSql FluentApi 配置实体,方法名与特性相同 - - - - - - - - 获取 FreeSql FluentApi 配置实体的元数据 - - - 未使用ConfigEntity配置时,返回null - - - - 获取实体类核心配置 - - - + @@ -3678,6 +3521,194 @@ + + + 设置 obj.CsName 属性值 + + + + 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 + + + + + + + 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 + + 表名,如:dbo.table1 + 是否忽略大小写 + + + + + 判断表是否存在 + + 表名,如:dbo.table1 + 是否忽略大小写 + + + + + 获取数据库枚举类型int值 + + + + + + + 获取c#转换,(int)、(long) + + + + + + + 获取c#值 + + + + + + + 获取c#类型,int、long + + + + + + + 获取c#类型对象 + + + + + + + 获取ado.net读取方法, GetBoolean、GetInt64 + + + + + + + 序列化 + + + + + + + 反序列化 + + + + + + + 获取数据库枚举类型,适用 PostgreSQL + + + + + + + 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert + + + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + AsType, Ctor, ClearData 三处地方需要重新加载 + + + + + 动态读取 DescriptionAttribute 注释文本 + + + + + + + 通过属性的注释文本,通过 xml 读取 + + + Dict:key=属性名,value=注释 + + + + 更新实体的元数据 + + + + + 执行更新的 SQL + + + + + 执行更新命令的参数 + + + + + 执行更新命令影响的行 + + + + + 更新的实体数量 + + + + + 更新的实体 + + + + + 创建一个过滤器 + + + 名字 + 表达式 + + + + + 当前操作的数据 + + + + + 当前批次 + + + + + 总批次数量 + + + + + 获取 obj.CsName 属性值 MapType 之后的数据库值 + + + + + + + 获取 obj.CsName 属性原始值(不经过 MapType) + + + 设置 obj.CsName 属性值 diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 0edfd394..09515f8a 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -30,6 +30,14 @@ namespace FreeSql /// IDelete Where(Expression> exp); /// + /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) + /// 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 + /// + /// true 时生效 + /// lambda表达式条件 + /// + IDelete WhereIf(bool condition, Expression> exp); + /// /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 2abbdf64..49acf355 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -170,6 +170,14 @@ namespace FreeSql /// IUpdate Where(Expression> exp); /// + /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) + /// 若想使用导航对象,请使用 ISelect.ToUpdate() 方法 + /// + /// true 时生效 + /// lambda表达式条件 + /// + IUpdate WhereIf(bool condition, Expression> exp); + /// /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 5e28e3a9..56b21f5a 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -86,7 +86,12 @@ namespace FreeSql.Internal.CommonProvider } public abstract List ExecuteDeleted(); - public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _params)); + public IDelete Where(Expression> exp) => WhereIf(true, exp); + public IDelete WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + return this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _params)); + } public IDelete Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 63a46ea0..b6a24926 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -519,7 +519,12 @@ namespace FreeSql.Internal.CommonProvider return this; } - public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null, _params)); + public IUpdate Where(Expression> exp) => WhereIf(true, exp); + public IUpdate WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + return this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null, _params)); + } public IUpdate Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; From d025603997104a76528f1810b4e0268cd233b709 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 2 Sep 2020 18:44:22 +0800 Subject: [PATCH 0870/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=20ISelect?= =?UTF-8?q?=20OrderByIf=20=E6=96=B9=E6=B3=95=20#446=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 375 +++++++++--------- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 9 + .../SelectProvider/Select1Provider.cs | 2 + 3 files changed, 197 insertions(+), 189 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 0c309880..983c8c85 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2286,6 +2286,16 @@ + + + 按列排序,OrderByIf(true, a => a.Time) + + + true 时生效 + + true: DESC, false: ASC + + 按列倒向排序,OrderByDescending(a => a.Time) @@ -3329,7 +3339,182 @@ - + + 获取 Index 对应的值,也可以设置拦截的新值 + + + + + 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 + + + + + 发生的错误 + + + + + 执行SQL命令,返回的结果 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配 + + + + + 备注 + + + + + 发生的错误 + + + + + 耗时(单位:Ticks) + + + + + 耗时(单位:毫秒) + + + + + 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 + + + + + 转小写同步结构,适用 PostgreSQL + + + + + 转大写同步结构,适用 Oracle/达梦/人大金仓 + + + + + 将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。 + 本功能会影响 IFreeSql 首次访问的速度。 + 若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除 + + + + + 不使用命令参数化执行,针对 Insert/Update + + + + + 是否生成命令参数化执行,针对 lambda 表达式解析 + 注意:常量不会参数化,变量才会做参数化 + var id = 100; + fsql.Select<T>().Where(a => a.id == id) 会参数化 + fsql.Select<T>().Where(a => a.id == 100) 不会参数化 + + + + + 延时加载导航属性对象,导航属性需要声明 virtual + + + + + 将实体类型与数据库对比,返回DDL语句 + + + + + + + 将实体类型集合与数据库对比,返回DDL语句 + + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 + + + + + 同步实体类型到数据库 + 注意:生产环境中谨慎使用 + + + + + + 同步实体类型集合到数据库 + 注意:生产环境中谨慎使用 + + + + + + 同步实体类型到数据库(指定表名) + 注意:生产环境中谨慎使用 + + 实体类型 + 指定表名对比 + 强制同步结构,无视缓存每次都同步 + + + + 根据 System.Type 获取数据库信息 + + + + + + + FreeSql FluentApi 配置实体,方法名与特性相同 + + + + + + + + FreeSql FluentApi 配置实体,方法名与特性相同 + + + + + + + + 获取 FreeSql FluentApi 配置实体的元数据 + + + 未使用ConfigEntity配置时,返回null + + + + 获取实体类核心配置 + + + @@ -3521,194 +3706,6 @@ - - - 设置 obj.CsName 属性值 - - - - 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注 - - - - - - - 获取指定单表信息,包括列详情、主键、唯一键、索引、备注 - - 表名,如:dbo.table1 - 是否忽略大小写 - - - - - 判断表是否存在 - - 表名,如:dbo.table1 - 是否忽略大小写 - - - - - 获取数据库枚举类型int值 - - - - - - - 获取c#转换,(int)、(long) - - - - - - - 获取c#值 - - - - - - - 获取c#类型,int、long - - - - - - - 获取c#类型对象 - - - - - - - 获取ado.net读取方法, GetBoolean、GetInt64 - - - - - - - 序列化 - - - - - - - 反序列化 - - - - - - - 获取数据库枚举类型,适用 PostgreSQL - - - - - - - 如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert - - - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - AsType, Ctor, ClearData 三处地方需要重新加载 - - - - - 动态读取 DescriptionAttribute 注释文本 - - - - - - - 通过属性的注释文本,通过 xml 读取 - - - Dict:key=属性名,value=注释 - - - - 更新实体的元数据 - - - - - 执行更新的 SQL - - - - - 执行更新命令的参数 - - - - - 执行更新命令影响的行 - - - - - 更新的实体数量 - - - - - 更新的实体 - - - - - 创建一个过滤器 - - - 名字 - 表达式 - - - - - 当前操作的数据 - - - - - 当前批次 - - - - - 总批次数量 - - - - - 获取 obj.CsName 属性值 MapType 之后的数据库值 - - - - - - - 获取 obj.CsName 属性原始值(不经过 MapType) - - - 设置 obj.CsName 属性值 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 08ccda4b..96daf821 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -346,6 +346,15 @@ namespace FreeSql /// ISelect OrderBy(bool condition, Expression> column); /// + /// 按列排序,OrderByIf(true, a => a.Time) + /// + /// + /// true 时生效 + /// + /// true: DESC, false: ASC + /// + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + /// /// 按列倒向排序,OrderByDescending(a => a.Time) /// /// 列 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index c8b7474c..dc9b92f5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -160,6 +160,8 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = column.Parameters[0]; return this.InternalOrderByDescending(column.Body); } + public ISelect OrderByIf(bool condition, Expression> column, bool descending = false) => + descending ? this.OrderByDescending(condition, column) : this.OrderBy(condition, column); public decimal Sum(Expression> column) { From 8eadde930f4b1233b634ccf4b9e591d484f251e9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 2 Sep 2020 19:20:41 +0800 Subject: [PATCH 0871/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20string=20IsN?= =?UTF-8?q?ullable=20=3D=20false=20=E6=97=B6=E6=8F=92=E5=85=A5=20null=20?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=BD=AC=E4=B8=BA=20""=20#445=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ .../Internal/CommonProvider/InsertOrUpdateProvider.cs | 2 ++ FreeSql/Internal/CommonProvider/InsertProvider.cs | 2 ++ FreeSql/Internal/CommonProvider/UpdateProvider.cs | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 1d8a13c4..92c5b536 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -92,6 +92,8 @@ namespace FreeSql.Internal.CommonProvider if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) changedDict.Add(col.Attribute.Name, true); } + if (val == null && col.Attribute.MapType == typeof(string) && col.Attribute.IsNullable == false) + col.SetValue(data, val = ""); } } diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 30495e56..1d394457 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -171,6 +171,8 @@ namespace FreeSql.Internal.CommonProvider col.SetValue(data, val = FreeUtil.NewMongodbId()); } } + if (val == null && col.Attribute.MapType == typeof(string) && col.Attribute.IsNullable == false) + col.SetValue(data, val = ""); } } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index b6a24926..1de0b502 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -359,6 +359,8 @@ namespace FreeSql.Internal.CommonProvider if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) changedDict.Add(col.Attribute.Name, true); } + if (val == null && col.Attribute.MapType == typeof(string) && col.Attribute.IsNullable == false) + col.SetValue(data, val = ""); } } } @@ -379,6 +381,8 @@ namespace FreeSql.Internal.CommonProvider if (changedDict != null && changedDict.ContainsKey(col.Attribute.Name) == false) changedDict.Add(col.Attribute.Name, true); } + if (val == null && col.Attribute.MapType == typeof(string) && col.Attribute.IsNullable == false) + col.SetValue(data, val = ""); } } From 9c8d6160821ad6246a70f30c0d6a4649d19ec722 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 2 Sep 2020 19:23:52 +0800 Subject: [PATCH 0872/1029] v1.9.0-preview0902 #445 #446 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 21 insertions(+), 37 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index cd3f5979..bbcc9948 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index e494f93a..981d8f6a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 42069c21..6b39a33e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 3e316cdd..d663270e 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 56d10d1b..2fe1d2ee 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0901 + 1.9.0-preview0902 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 03a53377..c254e550 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index abb867fa..b25e5110 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index fddb8c7a..db323a66 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 5d494fa3..decf1884 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index cfdfe54e..2fc15c8a 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 4b1fc014..6d2fcb13 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index f77b1ad2..23ff6d7a 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 92b4e686..8c3b00e9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 86d39a46..3ccc0142 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e66129dd..038d2110 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 4364fc5c..1250d645 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index cbe5e542..bd089692 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index b01e0b55..820cc582 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index babd687e..73f486d3 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 4f50f7de..cb67d9a3 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index c35b2cf4..3d8c6b2d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0901 + 1.9.0-preview0902 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From c75cdc51ae18a1fe62c107bb841d17b6c2de0d8b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 3 Sep 2020 18:22:06 +0800 Subject: [PATCH 0873/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=20ISelect`2?= =?UTF-8?q?-10=20OrderByIf=20=E6=96=B9=E6=B3=95=20#446=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 2 ++ FreeSql/Interface/Curd/ISelect/ISelect10.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect2.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect3.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect4.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect5.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect6.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect7.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect8.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect9.cs | 1 + .../CommonProvider/SelectProvider/Select10Provider.cs | 7 +++++++ .../CommonProvider/SelectProvider/Select2Provider.cs | 7 +++++++ .../CommonProvider/SelectProvider/Select3Provider.cs | 7 +++++++ .../CommonProvider/SelectProvider/Select4Provider.cs | 7 +++++++ .../CommonProvider/SelectProvider/Select5Provider.cs | 7 +++++++ .../CommonProvider/SelectProvider/Select6Provider.cs | 7 +++++++ .../CommonProvider/SelectProvider/Select7Provider.cs | 7 +++++++ .../CommonProvider/SelectProvider/Select8Provider.cs | 7 +++++++ .../CommonProvider/SelectProvider/Select9Provider.cs | 7 +++++++ 19 files changed, 74 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index dcfab4da..eccdba92 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -231,6 +231,8 @@ namespace FreeSql.Tests Id = a.Key, EdiId1 = SqlExt.Max(a.Key).Over().PartitionBy(new { a.Value.EdiId, a.Value.Id }).OrderByDescending(new { a.Value.EdiId, a.Value.Id }).ToValue(), EdiId2 = SqlExt.Max(a.Key).Over().PartitionBy(a.Value.EdiId).OrderByDescending(a.Value.Id).ToValue(), + + Sub1 = g.sqlite.Select().Where(b => b.Id == a.Key).Count() }); var sqlextGroupConcat = g.mysql.Select() diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 2d1107e4..1acf96da 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms = null); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index b7890fec..6bcdaac6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, object parms = null); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index 413bbe72..ea441d28 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, object parms = null); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index cfd3b6ac..28e2c5f1 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms = null); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index b26c016d..d1947791 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms = null); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index e3c46a93..700cdf03 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms = null); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index 23fd0fbc..d7117d0c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms = null); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 22e2b933..8ed0514a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms = null); } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 87463c8e..96da6b7a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -56,6 +56,7 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms = null); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index cfbdf04e..4058a933 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -98,6 +98,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 722e98ad..b6617bc4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -74,6 +74,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index a1a0482f..502b1e04 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -77,6 +77,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 7ad1d657..c7f86211 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -80,6 +80,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 8d370dca..1624a6ed 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -83,6 +83,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 24017074..c63eba00 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -86,6 +86,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index be823cc8..1a583037 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -89,6 +89,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 4f24a463..35f87674 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -92,6 +92,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 33625d93..7f3d0505 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -95,6 +95,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalOrderByDescending(column?.Body); } + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + decimal ISelect.Sum(Expression> column) { if (column == null) this.InternalOrderBy(column?.Body); From 80ac7d90a86089f76cda012ebedf90598c264de5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 3 Sep 2020 18:39:06 +0800 Subject: [PATCH 0874/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect=20An?= =?UTF-8?q?y(lambda)=20=E6=9D=A1=E4=BB=B6=E8=A2=AB=E9=99=84=E5=8A=A0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E4=B8=8D=E4=BE=BF=E4=BA=8E?= =?UTF-8?q?=E5=86=8D=E6=AC=A1=E4=BD=BF=E7=94=A8=20ISelect=20=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 2 +- .../SelectProvider/Select10Provider.cs | 14 ++++++++++---- .../SelectProvider/Select1Provider.cs | 16 ++++++++++++++-- .../SelectProvider/Select2Provider.cs | 14 ++++++++++---- .../SelectProvider/Select3Provider.cs | 14 ++++++++++---- .../SelectProvider/Select4Provider.cs | 14 ++++++++++---- .../SelectProvider/Select5Provider.cs | 14 ++++++++++---- .../SelectProvider/Select6Provider.cs | 14 ++++++++++---- .../SelectProvider/Select7Provider.cs | 14 ++++++++++---- .../SelectProvider/Select8Provider.cs | 14 ++++++++++---- .../SelectProvider/Select9Provider.cs | 14 ++++++++++---- 11 files changed, 105 insertions(+), 39 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index eccdba92..2dec40eb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -232,7 +232,7 @@ namespace FreeSql.Tests EdiId1 = SqlExt.Max(a.Key).Over().PartitionBy(new { a.Value.EdiId, a.Value.Id }).OrderByDescending(new { a.Value.EdiId, a.Value.Id }).ToValue(), EdiId2 = SqlExt.Max(a.Key).Over().PartitionBy(a.Value.EdiId).OrderByDescending(a.Value.Id).ToValue(), - Sub1 = g.sqlite.Select().Where(b => b.Id == a.Key).Count() + Sub1 = g.sqlserver.Select().Where(b => b.Id == a.Key).Count() }); var sqlextGroupConcat = g.mysql.Select() diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 4058a933..3a074d5b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -201,7 +201,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -260,11 +263,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index dc9b92f5..41afd44a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -274,7 +274,13 @@ namespace FreeSql.Internal.CommonProvider return this; } - public bool Any(Expression> exp) => this.Where(exp).Any(); + public bool Any(Expression> exp) + { + var oldwhere = _where.ToString(); + var ret = this.Where(exp).Any(); + _where.Clear().Append(oldwhere); + return ret; + } public TReturn ToOne(Expression> select) => this.Limit(1).ToList(select).FirstOrDefault(); public TDto ToOne() => this.Limit(1).ToList().FirstOrDefault(); @@ -1083,7 +1089,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToAggregateAsync(select?.Body); } - public Task AnyAsync(Expression> exp) => this.Where(exp).AnyAsync(); + async public Task AnyAsync(Expression> exp) + { + var oldwhere = _where.ToString(); + var ret = await this.Where(exp).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } async public Task ToOneAsync(Expression> select) => (await this.Limit(1).ToListAsync(select)).FirstOrDefault(); async public Task ToOneAsync() => (await this.Limit(1).ToListAsync()).FirstOrDefault(); public Task FirstAsync(Expression> select) => this.ToOneAsync(select); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index b6617bc4..25a71766 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -169,7 +169,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -228,11 +231,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 502b1e04..e8bac16d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -173,7 +173,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -232,11 +235,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index c7f86211..d4c9f644 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -177,7 +177,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -236,11 +239,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 1624a6ed..7a824b06 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -181,7 +181,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -240,11 +243,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index c63eba00..8dcf25e6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -185,7 +185,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -244,11 +247,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 1a583037..703f446b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -189,7 +189,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -248,11 +251,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 35f87674..6ff53f5a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -193,7 +193,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -252,11 +255,14 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 7f3d0505..63fb5ae0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -193,7 +193,10 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; } TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); @@ -202,11 +205,14 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect.AnyAsync(Expression> exp) + async Task ISelect.AnyAsync(Expression> exp) { - if (exp == null) return this.AnyAsync(); + if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; } Task ISelect.ToDataTableAsync(Expression> select) From 46862bc10ff35a3ddc3cdab5be78b100a33908a4 Mon Sep 17 00:00:00 2001 From: luoyunchong Date: Thu, 3 Sep 2020 23:00:28 +0800 Subject: [PATCH 0875/1029] FreeSqlDbContextExtensions remove test code --- Examples/efcore_to_freesql/Entitys/Song.cs | 48 ++++++ .../FreeSqlExtensions/CodeFirstExtensions.cs | 111 +++++++++++- Examples/efcore_to_freesql/Startup.cs | 6 +- .../EfCoreFluentApiExtensions.cs | 152 ----------------- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++ FreeSql.DbContext/TempExtensions.cs | 7 - FreeSql/FreeSql.xml | 159 ------------------ 7 files changed, 177 insertions(+), 322 deletions(-) create mode 100644 Examples/efcore_to_freesql/Entitys/Song.cs delete mode 100644 FreeSql.DbContext/TempExtensions.cs diff --git a/Examples/efcore_to_freesql/Entitys/Song.cs b/Examples/efcore_to_freesql/Entitys/Song.cs new file mode 100644 index 00000000..4ae2ffc7 --- /dev/null +++ b/Examples/efcore_to_freesql/Entitys/Song.cs @@ -0,0 +1,48 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; + +namespace efcore_to_freesql.Entitys +{ + public class SongType + { + public int Id { get; set; } + public string Name { get; set; } + + public List Songs { get; set; } + } + + public class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime CreateTime { get; set; } + + public int TypeId { get; set; } + public SongType Type { get; set; } + public List Tags { get; set; } + + public int Field1 { get; set; } + public long RowVersion { get; set; } + } + public class Song_tag + { + public int Song_id { get; set; } + public Song Song { get; set; } + + public int Tag_id { get; set; } + public Tag Tag { get; set; } + } + + public class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string Name { get; set; } + + public List Songs { get; set; } + } +} diff --git a/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs b/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs index 096f5b9f..9dcf1145 100644 --- a/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs +++ b/Examples/efcore_to_freesql/FreeSqlExtensions/CodeFirstExtensions.cs @@ -1,4 +1,5 @@ -using FreeSql; +using efcore_to_freesql.Entitys; +using FreeSql; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using System; @@ -69,4 +70,112 @@ public static class CodeFirstExtensions }); } } + + public static void EfCoreFluentApiTestGeneric(this ICodeFirst cf) + { + cf.Entity(eb => + { + eb.ToTable("tb_song1"); + eb.Ignore(a => a.Field1); + eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); + eb.Property(a => a.Url).HasMaxLength(100); + + eb.Property(a => a.RowVersion).IsRowVersion(); + eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp"); + + eb.HasKey(a => a.Id); + eb.HasIndex(a => a.Title).IsUnique().HasName("idx_tb_song1111"); + + //一对多、多对一 + eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); + + //多对多 + eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); + }); + cf.Entity(eb => + { + eb.ToTable("tb_songtype1"); + eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); + + eb.HasData(new[] + { + new SongType + { + Id = 1, + Name = "流行", + Songs = new List(new[] + { + new Song{ Title = "真的爱你" }, + new Song{ Title = "爱你一万年" }, + }) + }, + new SongType + { + Id = 2, + Name = "乡村", + Songs = new List(new[] + { + new Song{ Title = "乡里乡亲" }, + }) + }, + }); + }); + + cf.SyncStructure(); + cf.SyncStructure(); + } + + public static void EfCoreFluentApiTestDynamic(this ICodeFirst cf) + { + cf.Entity(typeof(Song), eb => + { + eb.ToTable("tb_song2"); + eb.Ignore("Field1"); + eb.Property("Title").HasColumnType("varchar(50)").IsRequired(); + eb.Property("Url").HasMaxLength(100); + + eb.Property("RowVersion").IsRowVersion(); + eb.Property("CreateTime").HasDefaultValueSql("current_timestamp"); + + eb.HasKey("Id"); + eb.HasIndex("Title").IsUnique().HasName("idx_tb_song2222"); + + //一对多、多对一 + eb.HasOne("Type").HasForeignKey("TypeId").WithMany("Songs"); + + //多对多 + eb.HasMany("Tags").WithMany("Songs", typeof(Song_tag)); + }); + cf.Entity(typeof(SongType), eb => + { + eb.ToTable("tb_songtype2"); + eb.HasMany("Songs").WithOne("Type").HasForeignKey("TypeId"); + + eb.HasData(new[] + { + new SongType + { + Id = 1, + Name = "流行", + Songs = new List(new[] + { + new Song{ Title = "真的爱你" }, + new Song{ Title = "爱你一万年" }, + }) + }, + new SongType + { + Id = 2, + Name = "乡村", + Songs = new List(new[] + { + new Song{ Title = "乡里乡亲" }, + }) + }, + }); + }); + + cf.SyncStructure(); + cf.SyncStructure(); + } } \ No newline at end of file diff --git a/Examples/efcore_to_freesql/Startup.cs b/Examples/efcore_to_freesql/Startup.cs index 0245f0c9..3debf0b1 100644 --- a/Examples/efcore_to_freesql/Startup.cs +++ b/Examples/efcore_to_freesql/Startup.cs @@ -27,10 +27,10 @@ namespace efcore_to_freesql .UseAutoSyncStructure(true) .Build(); - //FreeSqlDbContextExtensions.EfCoreFluentApiTestGeneric(Fsql); - FreeSqlDbContextExtensions.EfCoreFluentApiTestDynamic(Fsql); + //Fsql.CodeFirst.EfCoreFluentApiTestGeneric(); + Fsql.CodeFirst.EfCoreFluentApiTestDynamic(); - DBContexts.BaseDBContext.Fsql = Fsql; + BaseDBContext.Fsql = Fsql; var sql11 = Fsql.Select().ToSql(); //SELECT a."Id", a."Title", a."CreateTime" FROM "Topic1" a diff --git a/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs b/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs index e31ac3fe..f6974811 100644 --- a/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs +++ b/FreeSql.DbContext/EfCoreFluentApi/EfCoreFluentApiExtensions.cs @@ -34,156 +34,4 @@ partial class FreeSqlDbContextExtensions codeFirst.ConfigEntity(entityType, tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf, entityType))); return codeFirst; } - - public static void EfCoreFluentApiTestGeneric(IFreeSql fsql) - { - var cf = fsql.CodeFirst; - cf.Entity(eb => - { - eb.ToTable("tb_song1"); - eb.Ignore(a => a.Field1); - eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired(); - eb.Property(a => a.Url).HasMaxLength(100); - - eb.Property(a => a.RowVersion).IsRowVersion(); - eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp"); - - eb.HasKey(a => a.Id); - eb.HasIndex(a => a.Title).IsUnique().HasName("idx_tb_song1111"); - - //一对多、多对一 - eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs); - - //多对多 - eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag)); - }); - cf.Entity(eb => - { - eb.ToTable("tb_songtype1"); - eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId); - - eb.HasData(new[] - { - new SongType - { - Id = 1, - Name = "流行", - Songs = new List(new[] - { - new Song{ Title = "真的爱你" }, - new Song{ Title = "爱你一万年" }, - }) - }, - new SongType - { - Id = 2, - Name = "乡村", - Songs = new List(new[] - { - new Song{ Title = "乡里乡亲" }, - }) - }, - }); - }); - - cf.SyncStructure(); - cf.SyncStructure(); - } - - public static void EfCoreFluentApiTestDynamic(IFreeSql fsql) - { - var cf = fsql.CodeFirst; - cf.Entity(typeof(Song), eb => - { - eb.ToTable("tb_song2"); - eb.Ignore("Field1"); - eb.Property("Title").HasColumnType("varchar(50)").IsRequired(); - eb.Property("Url").HasMaxLength(100); - - eb.Property("RowVersion").IsRowVersion(); - eb.Property("CreateTime").HasDefaultValueSql("current_timestamp"); - - eb.HasKey("Id"); - eb.HasIndex("Title").IsUnique().HasName("idx_tb_song2222"); - - //一对多、多对一 - eb.HasOne("Type").HasForeignKey("TypeId").WithMany("Songs"); - - //多对多 - eb.HasMany("Tags").WithMany("Songs", typeof(Song_tag)); - }); - cf.Entity(typeof(SongType), eb => - { - eb.ToTable("tb_songtype2"); - eb.HasMany("Songs").WithOne("Type").HasForeignKey("TypeId"); - - eb.HasData(new[] - { - new SongType - { - Id = 1, - Name = "流行", - Songs = new List(new[] - { - new Song{ Title = "真的爱你" }, - new Song{ Title = "爱你一万年" }, - }) - }, - new SongType - { - Id = 2, - Name = "乡村", - Songs = new List(new[] - { - new Song{ Title = "乡里乡亲" }, - }) - }, - }); - }); - - cf.SyncStructure(); - cf.SyncStructure(); - } - - public class SongType - { - public int Id { get; set; } - public string Name { get; set; } - - public List Songs { get; set; } - } - - public class Song - { - [Column(IsIdentity = true)] - public int Id { get; set; } - public string Title { get; set; } - public string Url { get; set; } - public DateTime CreateTime { get; set; } - - public int TypeId { get; set; } - public SongType Type { get; set; } - public List Tags { get; set; } - - public int Field1 { get; set; } - public long RowVersion { get; set; } - } - public class Song_tag - { - public int Song_id { get; set; } - public Song Song { get; set; } - - public int Tag_id { get; set; } - public Tag Tag { get; set; } - } - - public class Tag - { - [Column(IsIdentity = true)] - public int Id { get; set; } - - public string Name { get; set; } - - public List Songs { get; set; } - } } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.DbContext/TempExtensions.cs b/FreeSql.DbContext/TempExtensions.cs deleted file mode 100644 index 43528138..00000000 --- a/FreeSql.DbContext/TempExtensions.cs +++ /dev/null @@ -1,7 +0,0 @@ - -namespace FreeSql.Extensions.EntityUtil -{ - public static class TempExtensions - { - } -} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 983c8c85..f990b954 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2971,153 +2971,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3874,12 +3727,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3950,12 +3797,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 From dd477482f184f928e33098ec4670562777908ad7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 4 Sep 2020 12:12:37 +0800 Subject: [PATCH 0876/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect=20Ag?= =?UTF-8?q?gregate(lambda,=20out=20var=20result)=20=E6=96=B9=E6=B3=95?= =?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 | 7 +++++++ .../FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs | 4 ++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 2 -- FreeSql/FreeSql.xml | 12 ++++++++++++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 11 +++++++++++ FreeSql/Interface/Curd/ISelect/ISelect10.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect2.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect3.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect4.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect5.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect6.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect7.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect8.cs | 1 + FreeSql/Interface/Curd/ISelect/ISelect9.cs | 1 + .../SelectProvider/Select10Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select1Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select2Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select3Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select4Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select5Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select6Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select7Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select8Provider.cs | 5 +++++ .../CommonProvider/SelectProvider/Select9Provider.cs | 5 +++++ 24 files changed, 93 insertions(+), 2 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index 40d64009..3eefc1ef 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -812,6 +812,10 @@ namespace FreeSql.Tests.Dameng public void ToAggregate() { var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + + select + .Aggregate(a => new { sum = a.Sum(a.Key.Id), count = a.Count() }, out var output) + .ToList(); } [Fact] public void OrderBy() diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 2dec40eb..dcfab4da 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -231,8 +231,6 @@ namespace FreeSql.Tests Id = a.Key, EdiId1 = SqlExt.Max(a.Key).Over().PartitionBy(new { a.Value.EdiId, a.Value.Id }).OrderByDescending(new { a.Value.EdiId, a.Value.Id }).ToValue(), EdiId2 = SqlExt.Max(a.Key).Over().PartitionBy(a.Value.EdiId).OrderByDescending(a.Value.Id).ToValue(), - - Sub1 = g.sqlserver.Select().Where(b => b.Id == a.Key).Count() }); var sqlextGroupConcat = g.mysql.Select() diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 983c8c85..030132d4 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2032,6 +2032,18 @@ + + + 执行SQL查询,返回指定字段的聚合结果给 output 参数 + fsql.Select<T>() + .Aggregate(a => new { count = a.Count, sum = a.Sum(a.Key.Price) }, out var agg) + .Page(1, 10).ToList(); + + + + + + 求和 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 96daf821..fd7a814c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -110,6 +110,17 @@ namespace FreeSql /// /// TReturn ToAggregate(Expression, TReturn>> select); + /// + /// 执行SQL查询,返回指定字段的聚合结果给 output 参数 + /// fsql.Select<T>() + /// .Aggregate(a => new { count = a.Count, sum = a.Sum(a.Key.Price) }, out var agg) + /// .Page(1, 10).ToList(); + /// + /// + /// + /// + /// + ISelect Aggregate(Expression, TReturn>> select, out TReturn result); /// /// 求和 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 1acf96da..f35462e6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 6bcdaac6..a6aeaa28 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index ea441d28..35a6212a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 28e2c5f1..93c6f809 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index d1947791..12f4714b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index 700cdf03..a6f6dffb 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index d7117d0c..50c4f0a6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 8ed0514a..f03b7904 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 96da6b7a..99218e60 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -40,6 +40,7 @@ namespace FreeSql string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); decimal Sum(Expression> column); TMember Min(Expression> column); TMember Max(Expression> column); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 3a074d5b..1e9a712a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -118,6 +118,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 41afd44a..76fbf170 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -210,6 +210,11 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = select.Parameters[0]; return this.InternalToAggregate(select?.Body); } + public ISelect Aggregate(Expression, TReturn>> select, out TReturn result) + { + result = ToAggregate(select); + return this; + } public ISelect Where(Expression> exp) => WhereIf(true, exp); public ISelect WhereIf(bool condition, Expression> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 25a71766..005e485b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -94,6 +94,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index e8bac16d..707eccf8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -97,6 +97,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index d4c9f644..c23c314c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -100,6 +100,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 7a824b06..d85e2577 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -103,6 +103,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 8dcf25e6..71e7edd6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -106,6 +106,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 703f446b..5b9657c3 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -109,6 +109,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 6ff53f5a..ae1eb8bd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -112,6 +112,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 63fb5ae0..f14ae04f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -115,6 +115,11 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregate(select?.Body); } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } List ISelect.ToList(Expression> select) { From 9866f866ca353a0ddf4d4658ec29feecf172c90d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 4 Sep 2020 12:17:49 +0800 Subject: [PATCH 0877/1029] v1.9.0-preview0905 #446 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index bbcc9948..6698e82b 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 981d8f6a..2e03a933 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 6b39a33e..280d2772 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index d663270e..afeef64e 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 2fe1d2ee..8d57b65f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0902 + 1.9.0-preview0905 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index c254e550..cbe1bb9c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index b25e5110..3d9b1515 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index db323a66..42a3049f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index decf1884..cfae1c3e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 2fc15c8a..a72c57ab 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 6d2fcb13..37d44c87 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 23ff6d7a..e9c51370 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 8c3b00e9..d73874fb 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 3ccc0142..45b2ff42 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 038d2110..57e36c98 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 1250d645..38d94577 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index bd089692..a050b534 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 820cc582..07163bcc 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 73f486d3..75cd249c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index cb67d9a3..67f87f5f 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 3d8c6b2d..b0c25a6e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0902 + 1.9.0-preview0905 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From f4b4358c00838d8f2a9fb2a595ddbdcc4646ef39 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Fri, 4 Sep 2020 18:44:13 +0800 Subject: [PATCH 0878/1029] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 71ef6eb8..df42d9cf 100644 --- a/readme.md +++ b/readme.md @@ -19,7 +19,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | | | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) | | | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分表分库》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | > FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: From beb2eaada2002a0bd98542a37471d5d1171993c8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 5 Sep 2020 06:50:56 +0800 Subject: [PATCH 0879/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20GlobalFilter?= =?UTF-8?q?.ApplyIf=20=E5=88=9B=E5=BB=BA=E5=8A=A8=E6=80=81=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=99=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 -- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 6 + FreeSql/FreeSql.xml | 174 ++++++++++++++++++++++- FreeSql/Internal/GlobalFilter.cs | 21 ++- 4 files changed, 196 insertions(+), 14 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,14 +532,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index a5b2757e..16d3d8ea 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -280,6 +280,12 @@ namespace FreeSql.Tests var kwrepo = g.sqlite.GetRepository(); kwrepo.Insert(u1); + g.sqlite.GlobalFilter.ApplyIf("random_filter", () => new Random().Next(0, 2) % 2 == 0 ? true : false, a => a.rowstate > 0); + + Enumerable.Range(0, 10).ToList().ForEach(aidx => + { + var sql1 = g.sqlite.Select().ToSql(); + }); g.sqlite.GlobalFilter.Apply("gft1", a => a.rowstate > -1 && g.sqlite.Select().Any(b => b.id == a.id)) .Apply("gft2", a => a.rowstate > -2) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index fd1680d0..8af604f0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2983,6 +2983,153 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3536,13 +3683,26 @@ - 创建一个过滤器 + 创建一个过滤器 + 提示:判断登陆身份,请参考资料 AsyncLocal 名字 表达式 + + + 创建一个动态过滤器,当 condition 返回值为 true 时才生效 + 场景:当登陆身份是管理员,则过滤条件不生效 + 提示:判断登陆身份,请参考资料 AsyncLocal + + + 名字 + 委托,返回值为 true 时才生效 + 表达式 + + 当前操作的数据 @@ -3739,6 +3899,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3809,6 +3975,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/GlobalFilter.cs b/FreeSql/Internal/GlobalFilter.cs index f0250d8b..9da950ff 100644 --- a/FreeSql/Internal/GlobalFilter.cs +++ b/FreeSql/Internal/GlobalFilter.cs @@ -16,22 +16,35 @@ namespace FreeSql.Internal { public int Id { get; internal set; } public string Name { get; internal set; } + internal Func Condition { get; set; } public LambdaExpression Where { get; internal set; } } /// - /// 创建一个过滤器 + /// 创建一个过滤器 + /// 提示:判断登陆身份,请参考资料 AsyncLocal /// /// /// 名字 /// 表达式 /// - public GlobalFilter Apply(string name, Expression> where) + public GlobalFilter Apply(string name, Expression> where) => ApplyIf(name, () => true, where); + /// + /// 创建一个动态过滤器,当 condition 返回值为 true 时才生效 + /// 场景:当登陆身份是管理员,则过滤条件不生效 + /// 提示:判断登陆身份,请参考资料 AsyncLocal + /// + /// + /// 名字 + /// 委托,返回值为 true 时才生效 + /// 表达式 + /// + public GlobalFilter ApplyIf(string name, Func condition, Expression> where) { if (name == null) throw new ArgumentNullException(nameof(name)); if (where == null) return this; _filters.TryGetValue(name, out var item); - if (item == null) item = new Item { Id = ++_id, Name = name }; + if (item == null) item = new Item { Id = ++_id, Name = name, Condition = condition }; var newParameter = Expression.Parameter(typeof(TEntity), $"gf{_id}"); var newlambda = Expression.Lambda>( @@ -44,6 +57,6 @@ namespace FreeSql.Internal } public void Remove(string name) => _filters.TryRemove(name ?? throw new ArgumentNullException(nameof(name)), out var _); - public List GetFilters() => _filters.Values.OrderBy(a => a.Id).ToList(); + public List GetFilters() => _filters.Values.Where(a => a.Condition?.Invoke() != false).OrderBy(a => a.Id).ToList(); } } From 59ecfdf2880cd072c07c00f94b19a384c5400db0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 5 Sep 2020 18:45:36 +0800 Subject: [PATCH 0880/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Ado.Net=20Cr?= =?UTF-8?q?ud=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=8F=8B=E5=A5=BD=E5=BC=82=E5=B8=B8=E6=8F=90=E7=A4=BA?= =?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 | 9 +++++++++ .../MySqlConnectionExtensionsTest.cs | 15 +++++++++++++++ .../NpgsqlConnectionExtensionsTest.cs | 15 +++++++++++++++ .../OracleConnectionExtensionsTest.cs | 15 +++++++++++++++ .../SQLiteConnectionExtensionsTest.cs | 15 +++++++++++++++ .../SqlConnectionExtensionsTest.cs | 15 +++++++++++++++ FreeSql/Extensions/AdoNetExtensions.cs | 2 +- .../CommonProvider/InsertOrUpdateProvider.cs | 14 ++++++++++---- .../Internal/CommonProvider/InsertProvider.cs | 18 +++++++++++++++--- .../CommonProvider/InsertProviderAsync.cs | 18 +++++++++++++++--- .../Internal/CommonProvider/UpdateProvider.cs | 12 ++++++++++-- .../CommonProvider/UpdateProviderAsync.cs | 12 ++++++++++-- 12 files changed, 145 insertions(+), 15 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs index 7f4a3296..fa1386b9 100644 --- a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/MySqlConnectionExtensionsTest.cs @@ -30,6 +30,21 @@ namespace FreeSql.Tests.AdoNetExtensions.MySqlConnectionExtensions { Assert.Equal(1, affrows); } [Fact] + public void InsertOrUpdate() + { + var affrows = 0; + using (var conn = new MySqlConnection(_connectString)) + { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item.title = "testinsertorupdate"; + var affrows2 = conn.InsertOrUpdate().SetSource(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] public void Update() { var affrows = 0; using (var conn = new MySqlConnection(_connectString)) { diff --git a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/NpgsqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/NpgsqlConnectionExtensionsTest.cs index 18b70be9..542e083a 100644 --- a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/NpgsqlConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/NpgsqlConnectionExtensionsTest.cs @@ -23,6 +23,21 @@ namespace FreeSql.Tests.AdoNetExtensions.NpgsqlConnectionExtensions { Assert.Equal(1, affrows); } [Fact] + public void InsertOrUpdate() + { + var affrows = 0; + using (var conn = new NpgsqlConnection(_connectString)) + { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item.title = "testinsertorupdate"; + var affrows2 = conn.InsertOrUpdate().SetSource(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] public void Update() { var affrows = 0; using (var conn = new NpgsqlConnection(_connectString)) { diff --git a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/OracleConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/OracleConnectionExtensionsTest.cs index faec49a6..359e5451 100644 --- a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/OracleConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/OracleConnectionExtensionsTest.cs @@ -23,6 +23,21 @@ namespace FreeSql.Tests.AdoNetExtensions.OracleConnectionExtensions { Assert.Equal(1, affrows); } [Fact] + public void InsertOrUpdate() + { + var affrows = 0; + using (var conn = new OracleConnection(_connectString)) + { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item.title = "testinsertorupdate"; + var affrows2 = conn.InsertOrUpdate().SetSource(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] public void Update() { var affrows = 0; using (var conn = new OracleConnection(_connectString)) { diff --git a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SQLiteConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SQLiteConnectionExtensionsTest.cs index 9ee8faa0..4352555b 100644 --- a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SQLiteConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SQLiteConnectionExtensionsTest.cs @@ -25,6 +25,21 @@ namespace FreeSql.Tests.AdoNetExtensions.SQLiteConnectionExtensions { Assert.Equal(1, affrows); } [Fact] + public void InsertOrUpdate() + { + var affrows = 0; + using (var conn = new SQLiteConnection(_connectString)) + { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item.title = "testinsertorupdate"; + var affrows2 = conn.InsertOrUpdate().SetSource(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] public void Update() { var affrows = 0; using (var conn = new SQLiteConnection(_connectString)) { diff --git a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SqlConnectionExtensionsTest.cs b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SqlConnectionExtensionsTest.cs index ca6a80ea..945af494 100644 --- a/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SqlConnectionExtensionsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/AdoNetExtensions/SqlConnectionExtensionsTest.cs @@ -23,6 +23,21 @@ namespace FreeSql.Tests.AdoNetExtensions.SqlConnectionExtensions { Assert.Equal(1, affrows); } [Fact] + public void InsertOrUpdate() + { + var affrows = 0; + using (var conn = new SqlConnection(_connectString)) + { + var item = new TestConnectionExt { title = "testinsert" }; + affrows = conn.Insert().AppendData(item).ExecuteAffrows(); + Assert.Equal(1, affrows); + item.title = "testinsertorupdate"; + var affrows2 = conn.InsertOrUpdate().SetSource(item).ExecuteAffrows(); + conn.Close(); + } + Assert.Equal(1, affrows); + } + [Fact] public void Update() { var affrows = 0; using (var conn = new SqlConnection(_connectString)) { diff --git a/FreeSql/Extensions/AdoNetExtensions.cs b/FreeSql/Extensions/AdoNetExtensions.cs index ac63b308..451d7c7c 100644 --- a/FreeSql/Extensions/AdoNetExtensions.cs +++ b/FreeSql/Extensions/AdoNetExtensions.cs @@ -13,7 +13,7 @@ namespace FreeSql static object _dicCurdLock = new object(); static IFreeSql GetCrud(IDbConnection dbconn) { - if (dbconn == null) throw new ArgumentNullException($"{nameof(dbconn)} 不能为 null"); ; + if (dbconn == null) throw new ArgumentNullException($"{nameof(dbconn)} 不能为 null"); Type dbconType = dbconn.GetType(); var connType = dbconType.UnderlyingSystemType; if (_dicCurd.TryGetValue(connType, out var fsql)) return fsql; diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 92c5b536..7799c8ff 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -202,9 +202,12 @@ namespace FreeSql.Internal.CommonProvider try { if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } - if (_transaction != null) + if (_transaction != null || _orm.Ado.MasterPool == null) { _source = ss.Item1; _SplitSourceByIdentityValueIsNullFlag = 1; @@ -305,9 +308,12 @@ namespace FreeSql.Internal.CommonProvider try { if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } - if (_transaction != null) + if (_transaction != null || _orm.Ado.MasterPool == null) { _source = ss.Item1; _SplitSourceByIdentityValueIsNullFlag = 1; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 1d394457..2d03379b 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -219,7 +219,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrows", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -237,6 +240,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = _orm.Ado.MasterPool.Get()) { _transaction = conn.Value.BeginTransaction(); @@ -294,7 +298,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteIdentity", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -313,6 +320,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = _orm.Ado.MasterPool.Get()) { _transaction = conn.Value.BeginTransaction(); @@ -371,7 +379,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteInserted", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -389,6 +400,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = _orm.Ado.MasterPool.Get()) { _transaction = conn.Value.BeginTransaction(); diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index d738874a..92f5ff79 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -33,7 +33,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrowsAsync", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -51,6 +54,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = await _orm.Ado.MasterPool.GetAsync()) { _transaction = conn.Value.BeginTransaction(); @@ -108,7 +112,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteIdentityAsync", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -127,6 +134,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = await _orm.Ado.MasterPool.GetAsync()) { _transaction = conn.Value.BeginTransaction(); @@ -185,7 +193,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteInsertedAsync", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -203,6 +214,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = await _orm.Ado.MasterPool.GetAsync()) { _transaction = conn.Value.BeginTransaction(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 1de0b502..7ffa1982 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -158,7 +158,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrows", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -176,6 +179,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = _orm.Ado.MasterPool.Get()) { _transaction = conn.Value.BeginTransaction(); @@ -228,7 +232,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteUpdated", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -246,6 +253,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = _orm.Ado.MasterPool.Get()) { _transaction = conn.Value.BeginTransaction(); diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index 4d0194aa..a3593472 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -29,7 +29,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrowsAsync", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -47,6 +50,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = await _orm.Ado.MasterPool.GetAsync()) { _transaction = conn.Value.BeginTransaction(); @@ -98,7 +102,10 @@ namespace FreeSql.Internal.CommonProvider return ret; } if (_transaction == null) - this.WithTransaction(_orm.Ado.TransactionCurrentThread); + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } var before = new Aop.TraceBeforeEventArgs("SplitExecuteUpdatedAsync", null); _orm.Aop.TraceBeforeHandler?.Invoke(this, before); @@ -116,6 +123,7 @@ namespace FreeSql.Internal.CommonProvider } else { + if (_orm.Ado.MasterPool == null) throw new Exception("Ado.MasterPool 值为 null,该操作无法自启用事务,请显式传递【事务对象】解决"); using (var conn = await _orm.Ado.MasterPool.GetAsync()) { _transaction = conn.Value.BeginTransaction(); From 24e0fcd0af36284414b39ea70f983c6c57fca68a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 6 Sep 2020 00:42:44 +0800 Subject: [PATCH 0881/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IncludeMany(?= =?UTF-8?q?a=20=3D>=20a.Childs).ToList(a=20=3D>=20new=20{=20a.Childs=20})?= =?UTF-8?q?=20=E6=8C=87=E5=AE=9A=E9=9B=86=E5=90=88=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 -- .../Sqlite/Curd/SqliteSelectTest.cs | 111 +++++++++++++++++- FreeSql/Internal/CommonExpression.cs | 61 +++++++--- .../SelectProvider/Select0Provider.cs | 2 + .../SelectProvider/Select0ProviderReader.cs | 34 ++++-- .../SelectProvider/Select1Provider.cs | 80 ++++++++++++- .../SelectProvider/SelectGroupingProvider.cs | 8 +- .../Internal/Model/ReadAnonymousTypeInfo.cs | 4 + 8 files changed, 265 insertions(+), 44 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,14 +532,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index a26bfbd5..9216cbcc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1114,33 +1114,89 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) .Where(a => a.model2id <= model1.id) .ToList(); + var t001 = g.sqlite.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(a => new + { + a.model1.id, + a.childs, + childs2 = a.childs + }); var t1 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) .Where(a => a.id <= model1.id) .ToList(); + var t111 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(a => new + { + a.id, + a.model2.childs, + childs2 = a.model2.childs + }); var t2 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + var t222 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(a => new + { + a.id, + a.model2.childs, + childs2 = a.model2.childs + }); var t00 = g.sqlite.Select() .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) .Where(a => a.model2id <= model1.id) .ToList(); + var t0001 = g.sqlite.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(a => new + { + a.model1.id, + a.childs, + childs2 = a.childs + }); var t11 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) .Where(a => a.id <= model1.id) .ToList(); + var t1111 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(a => new + { + a.id, + a.model2.childs, + childs2 = a.model2.childs + }); var t22 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) .Where(a => a.id <= model1.id) .ToList(); + var t2222 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(a => new + { + a.id, + a.model2.childs, + childs2 = a.model2.childs + }); //---- Select ---- @@ -1148,33 +1204,77 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) .Where(a => a.model2id <= model1.id) .ToList(); + var at001 = g.sqlite.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(a => new + { + a.model2id, a.childs, childs2 = a.childs + }); var at1 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) .Where(a => a.id <= model1.id) - .ToList(); + .ToList(); + var at111 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(a => new + { + a.id, a.model2.childs, childs2 = a.model2.childs + }); var at2 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) .Where(a => a.id <= model1.id) .ToList(); + var at2222 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(a => new + { + a.id, a.model2.childs, childs2 = a.model2.childs + }); var at00 = g.sqlite.Select() .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) .Where(a => a.model2id <= model1.id) .ToList(); + var at011 = g.sqlite.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(a => new + { + a.model2id, a.childs, childs2 = a.childs + }); var at11 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) .Where(a => a.id <= model1.id) .ToList(); + var at1112 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(a => new + { + a.id, a.model2.childs, childs2 = a.model2.childs + }); var at22 = g.sqlite.Select() .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) .Where(a => a.id <= model1.id) .ToList(); + var at2223 = g.sqlite.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(a => new + { + a.id, a.model2.childs, childs2 = a.model2.childs + }); } public class TestInclude_OneToManyModel11 @@ -1557,6 +1657,15 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) .ToList(true); + + var asongs2222 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(a => new + { + a.Id, a.Is_deleted, a.Tags + }); } [Fact] diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 705a1aa2..d1177708 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -28,13 +28,13 @@ namespace FreeSql.Internal } internal const int ReadAnonymousFieldAsCsName = -53129; - public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, SelectGroupingProvider grouping, List whereCascadeExpression, bool isAllDtoMap) + public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, SelectGroupingProvider grouping, List whereCascadeExpression, List findIncludeMany, bool isAllDtoMap) { Func getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; switch (exp.NodeType) { - case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, grouping, whereCascadeExpression, isAllDtoMap); - case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, grouping, whereCascadeExpression, isAllDtoMap); + case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); + case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); case ExpressionType.Negate: case ExpressionType.NegateChecked: parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; @@ -43,7 +43,7 @@ namespace FreeSql.Internal else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; - case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, grouping, whereCascadeExpression, isAllDtoMap); + case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); case ExpressionType.Constant: var constExp = exp as ConstantExpression; //处理自定义SQL语句,如: ToList(new { @@ -133,12 +133,36 @@ namespace FreeSql.Internal MapType = memProp.PropertyType }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), grouping, whereCascadeExpression, false); + ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, grouping, whereCascadeExpression, findIncludeMany, false); } } } else { + if (select != null && findIncludeMany != null && select._includeToList.Any() && exp.Type.IsGenericType && + typeof(IEnumerable).IsAssignableFrom(exp.Type) && + typeof(ICollection<>).MakeGenericType(exp.Type.GetGenericArguments().FirstOrDefault()).IsAssignableFrom(exp.Type)) + { + var includeKey = ""; + var memExp = exp as MemberExpression; + while (memExp != null) + { + includeKey = $"{memExp.Member.Name}.{includeKey}"; + if (memExp.Expression.NodeType == ExpressionType.Parameter) break; + memExp = memExp.Expression as MemberExpression; + } + if (memExp != null && string.IsNullOrEmpty(includeKey) == false) + { + includeKey = includeKey.TrimEnd('.'); + if (select._includeInfo.ContainsKey(includeKey)) + { + parent.IncludeManyKey = includeKey; + parent.CsType = exp.Type.GetGenericArguments().FirstOrDefault(); + findIncludeMany?.Add(includeKey); + return false; + } + } + } if (grouping != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { field.Append(grouping._field); @@ -173,7 +197,7 @@ namespace FreeSql.Internal MapType = initExp.NewExpression.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], grouping, whereCascadeExpression, false); + ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, grouping, whereCascadeExpression, findIncludeMany, false); } } else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) @@ -196,7 +220,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), grouping, whereCascadeExpression, isAllDtoMap); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -222,7 +246,7 @@ namespace FreeSql.Internal MapType = initAssignExp.Expression.Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, grouping, whereCascadeExpression, false); + ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, grouping, whereCascadeExpression, findIncludeMany, false); } } if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); @@ -255,7 +279,7 @@ namespace FreeSql.Internal MapType = newExp.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], grouping, whereCascadeExpression, false); + ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, grouping, whereCascadeExpression, findIncludeMany, false); } } else @@ -279,7 +303,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), grouping, whereCascadeExpression, isAllDtoMap); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -300,9 +324,9 @@ namespace FreeSql.Internal if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; } - public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue) + public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue, int rowIndex, List> fillIncludeMany) { - if (parent.Childs.Any() == false) + if (parent.Childs.Any() == false && string.IsNullOrEmpty(parent.IncludeManyKey)) { if (notRead) { @@ -316,19 +340,24 @@ namespace FreeSql.Internal if (parent.CsType != parent.MapType) objval = Utils.GetDataReaderValue(parent.MapType, objval); objval = Utils.GetDataReaderValue(parent.CsType, objval); - if (parent.Property != null && parent.CsType != parent.Property.PropertyType) + if (parent.Property != null && parent.CsType != parent.Property.PropertyType) objval = Utils.GetDataReaderValue(parent.Property.PropertyType, objval); return objval; } var ctorParmsLength = 0; object ret; - if (parent.IsDefaultCtor || parent.IsEntity || (ctorParmsLength = parent.Consturctor.GetParameters()?.Length ?? 0) == 0) + if (string.IsNullOrEmpty(parent.IncludeManyKey) == false) + { + ret = typeof(List<>).MakeGenericType(parent.CsType).CreateInstanceGetDefaultValue(); + fillIncludeMany?.Add(NativeTuple.Create(parent.IncludeManyKey, ret as IList, rowIndex)); + } + else if (parent.IsDefaultCtor || parent.IsEntity || (ctorParmsLength = parent.Consturctor.GetParameters()?.Length ?? 0) == 0) ret = parent.CsType?.CreateInstanceGetDefaultValue() ?? parent.Consturctor.Invoke(null); else { var ctorParms = new object[ctorParmsLength]; for (var c = 0; c < ctorParmsLength; c++) - ctorParms[c] = ReadAnonymous(parent.Childs[c], dr, ref index, notRead, null); + ctorParms[c] = ReadAnonymous(parent.Childs[c], dr, ref index, notRead, null, rowIndex, fillIncludeMany); ret = parent.Consturctor.Invoke(ctorParms); } @@ -337,7 +366,7 @@ namespace FreeSql.Internal { var prop = parent.Childs[b].Property; var dbval = parent.IsEntity ? new ReadAnonymousDbValueRef() : null; - var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval); + var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval, rowIndex, fillIncludeMany); if (isnull == false && parent.IsEntity && dbval.DbValue == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) isnull = true; if (isnull == false && prop.CanWrite) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 89ea4ce5..bde34d53 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -37,6 +37,7 @@ namespace FreeSql.Internal.CommonProvider #else public List> _includeToListAsync = new List>(); #endif + public Dictionary _includeInfo = new Dictionary(); public bool _distinct; public Expression _selectExpression; public List _whereCascadeExpression = new List(); @@ -57,6 +58,7 @@ namespace FreeSql.Internal.CommonProvider #else _includeToListAsync.Clear(); #endif + _includeInfo.Clear(); _selectExpression = null; _whereCascadeExpression.Clear(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 4ff5160c..78014870 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -85,6 +85,7 @@ namespace FreeSql.Internal.CommonProvider var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); + var retCount = 0; Exception exception = null; try { @@ -95,8 +96,9 @@ namespace FreeSql.Internal.CommonProvider { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null, retCount, null)); } + retCount++; }, CommandType.Text, sql, dbParms); } catch (Exception ex) @@ -143,13 +145,13 @@ namespace FreeSql.Internal.CommonProvider _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { ret.Object.Add(af.Read(_orm, fetch.Object)); - retCount++; if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null, ret.Object.Count - 1, null)); } + retCount++; if (chunkSize > 0 && chunkSize == ret.Object.Count) { checkDoneTimes++; @@ -219,7 +221,7 @@ namespace FreeSql.Internal.CommonProvider _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { var index = -1; - ret.Object.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); + ret.Object.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null, ret.Object.Count, af.fillIncludeMany)); retCount++; if (chunkSize > 0 && chunkSize == ret.Object.Count) { @@ -300,16 +302,18 @@ namespace FreeSql.Internal.CommonProvider var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); + var retCount = 0; Exception exception = null; try { _orm.Ado.ExecuteReader(_connection, _transaction, fetch => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null, retCount, af.fillIncludeMany)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null)); + retCount++; }, CommandType.Text, sql, dbParms); } catch (Exception ex) @@ -349,7 +353,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, this, null, _whereCascadeExpression, null, true); return new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); } static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); @@ -652,7 +656,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression, false); //不走 DTO 映射 + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany var sql = field.ToString(); this.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); return new SelectGroupingProvider(_orm, this, map, sql, _commonExpression, _tables); @@ -711,7 +715,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射 + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } @@ -788,6 +792,7 @@ namespace FreeSql.Internal.CommonProvider var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); + var retCount = 0; Exception exception = null; try { @@ -798,8 +803,9 @@ namespace FreeSql.Internal.CommonProvider { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null, retCount, null)); } + retCount++; return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } @@ -876,16 +882,18 @@ namespace FreeSql.Internal.CommonProvider var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); + var retCount = 0; Exception exception = null; try { await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null, retCount, af.fillIncludeMany)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null)); + retCount++; return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } @@ -963,7 +971,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射 + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); } #endif diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 76fbf170..490acdbb 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -170,11 +170,84 @@ namespace FreeSql.Internal.CommonProvider return this.InternalSum(column.Body); } + class IncludeManyNewInit + { + public TableInfo Table { get; } + public Dictionary Childs { get; } = new Dictionary(); + public Expression CurrentExpression { get; } + public bool IsOutputPrimary { get; set; } + public IncludeManyNewInit(TableInfo table, Expression currentExpression) + { + this.Table = table; + this.CurrentExpression = currentExpression; + } + } public List ToList(Expression> select) { if (select == null) return this.InternalToList(select?.Body); _tables[0].Parameter = select.Parameters[0]; - return this.InternalToList(select.Body); + if (_includeToList?.Any() != true) return this.InternalToList(select.Body); + + var findIncludeMany = new List(); + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select.Body, this, null, _whereCascadeExpression, findIncludeMany, true); + var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); + if (findIncludeMany.Any() == false) return this.ToListMapReaderPrivate(af, null); + + var parmExp = Expression.Parameter(_tables[0].Table.Type, _tables[0].Alias); + var incNewInit = new IncludeManyNewInit(_tables[0].Table, parmExp); + foreach (var inc in _includeInfo) + { + var curIncNewInit = incNewInit; + Expression curParmExp = parmExp; + for (var a = 0; a < inc.Value.Length - 1; a++) + { + curParmExp = Expression.MakeMemberAccess(parmExp, inc.Value[a].Member); + if (curIncNewInit.Childs.ContainsKey(inc.Value[a].Member.Name) == false) + curIncNewInit.Childs.Add(inc.Value[a].Member.Name, curIncNewInit = new IncludeManyNewInit(_orm.CodeFirst.GetTableByEntity(inc.Value[a].Type), curParmExp)); + else + curIncNewInit = curIncNewInit.Childs[inc.Value[a].Member.Name]; + } + curIncNewInit.IsOutputPrimary = true; + } + MemberInitExpression GetIncludeManyNewInitExpression(IncludeManyNewInit imni) + { + var bindings = new List(); + if (imni.IsOutputPrimary) bindings.AddRange(imni.Table.Primarys.Select(a => Expression.Bind(imni.Table.Properties[a.CsName], Expression.MakeMemberAccess(imni.CurrentExpression, imni.Table.Properties[a.CsName])))); + if (imni.Childs.Any()) bindings.AddRange(imni.Childs.Select(a => Expression.Bind(imni.Table.Properties[a.Key], GetIncludeManyNewInitExpression(a.Value)))); + return Expression.MemberInit(imni.Table.Type.InternalNewExpression(), bindings); + } + + var otherNewInit = GetIncludeManyNewInitExpression(incNewInit); //获取 IncludeMany 包含的最简化字段 + if (otherNewInit.Bindings.Any() == false) return this.ToListMapReaderPrivate(af, null); + + var otherMap = new ReadAnonymousTypeInfo(); + field.Clear(); + _commonExpression.ReadAnonymousField(_tables, field, otherMap, ref index, otherNewInit, this, null, _whereCascadeExpression, null, true); + var otherRet = new List(); + var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); + + af.fillIncludeMany = new List>(); + var ret = this.ToListMapReaderPrivate(af, new[] { otherAf }); + this.SetList(otherRet.Select(a => (T1)a).ToList()); //级联加载 + + foreach (var fim in af.fillIncludeMany) + { + var splitKeys = fim.Item1.Split('.'); + var otherRetItem = otherRet[fim.Item3]; + var otherRetItemType = _tables[0].Table.Type; + foreach(var splitKey in splitKeys) + { + otherRetItem = _orm.GetEntityValueWithPropertyName(otherRetItemType, otherRetItem, splitKey); + otherRetItemType = _orm.CodeFirst.GetTableByEntity(otherRetItemType).Properties[splitKey].PropertyType; + } + if (otherRetItem == null) continue; + var otherList = otherRetItem as IEnumerable; + foreach (var otherListItem in otherList) fim.Item2.Add(otherListItem); + } + return ret; } public List ToList() => ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() @@ -1031,6 +1104,11 @@ namespace FreeSql.Internal.CommonProvider }); _includeToListAsync.Add(listObj => includeToListSyncOrAsync(listObj, true)); #endif + var includeValue = new MemberExpression[members.Count + 1]; + for (var a = 0; a < members.Count; a++) includeValue[a] = members[a]; + includeValue[includeValue.Length - 1] = expBody as MemberExpression; + var includeKey = $"{string.Join(".", includeValue.Select(a => a.Member.Name))}"; + if (_includeInfo.ContainsKey(includeKey) == false) _includeInfo.Add(includeKey, includeValue); return this; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 559befe1..3a3bfccf 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -106,7 +106,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, this, null, false); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, null, this, null, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; var method = _select.GetType().GetMethod(isAsync ? "ToListMapReaderAsync" : "ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(elementType); @@ -118,7 +118,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, this, null, false); + _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, null, this, null, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; var method = _select.GetType().GetMethod("ToListMapReaderPrivate", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(elementType); @@ -132,7 +132,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, select, this, null, false); + _comonExp.ReadAnonymousField(null, field, map, ref index, select, null, this, null, null, false); var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; } @@ -210,7 +210,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, this, null, false); + _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, null, this, null, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement); var method = _select.GetType().GetMethod("ToListMapReaderPrivateAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TElement)); diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index c782cf5b..d2790276 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Text; @@ -17,6 +18,7 @@ namespace FreeSql.Internal.Model public TableInfo Table { get; set; } public bool IsEntity { get; set; } public bool IsDefaultCtor { get; set; } + public string IncludeManyKey { get; set; } //ToList(a => new { a.Childs }) 集合属性指定加载 public void CopyTo(ReadAnonymousTypeInfo target) { @@ -30,12 +32,14 @@ namespace FreeSql.Internal.Model target.Table = Table; target.IsEntity = IsEntity; target.IsDefaultCtor = IsDefaultCtor; + target.IncludeManyKey = IncludeManyKey; } } public class ReadAnonymousTypeAfInfo { public ReadAnonymousTypeInfo map { get; } public string field { get; } + public List> fillIncludeMany { get; set; } //回填集合属性的数据 public ReadAnonymousTypeAfInfo(ReadAnonymousTypeInfo map, string field) { this.map = map; From 8200b0e2e047c899fb79592bf09a163359caca27 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 6 Sep 2020 00:52:39 +0800 Subject: [PATCH 0882/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20SqlExt.IsNul?= =?UTF-8?q?l=20=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 6 ++++++ .../FreeSqlGlobalExpressionCallExtensions.cs | 15 ++++++++++++++- FreeSql/FreeSql.xml | 9 +++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index dcfab4da..93056dd7 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -233,6 +233,12 @@ namespace FreeSql.Tests EdiId2 = SqlExt.Max(a.Key).Over().PartitionBy(a.Value.EdiId).OrderByDescending(a.Value.Id).ToValue(), }); + var sqlextIsNull = g.sqlserver.Select() + .ToSql(a => new + { + nvl = SqlExt.IsNull(a.EdiId, 0) + }); + var sqlextGroupConcat = g.mysql.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 a5cecf49..a625db9d 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -104,6 +104,19 @@ namespace FreeSql public static ISqlOver RowNumber() => Over("row_number()"); #endregion + /// + /// isnull、ifnull、coalesce、nvl + /// + /// + /// + /// + /// + public static TValue IsNull(TValue value, TValue defaultValue) + { + expContext.Value.Result = expContext.Value._commonExp._common.IsNull(expContext.Value.ParsedContent["value"], expContext.Value.ParsedContent["defaultValue"]); + return default(TValue); + } + /// /// case when .. then .. end /// @@ -311,7 +324,7 @@ namespace FreeSql public interface IGroupConcat { } #endregion - #region string.Join 反射处理,此块代卖用于反射,所以别修改定义 + #region string.Join 反射处理,此块代码用于反射,所以别修改定义 public static string StringJoinSqliteGroupConcat(object column, object delimiter) { expContext.Result = $"group_concat({expContext.ParsedContent["column"]},{expContext.ParsedContent["delimiter"]})"; diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8af604f0..a550efcb 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1103,6 +1103,15 @@ + + + isnull、ifnull、coalesce、nvl + + + + + + case when .. then .. end From 1380895bb3a9ff45d2f95100f2217ae229943145 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 6 Sep 2020 01:02:12 +0800 Subject: [PATCH 0883/1029] v1.9.0-preview0906 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 21 insertions(+), 30 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6698e82b..e7067ad5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 2e03a933..ad55ff30 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 280d2772..ef415431 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index afeef64e..16f46017 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 8d57b65f..2bdcb72a 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0905 + 1.9.0-preview0906 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index cbe1bb9c..38a9fee5 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 3d9b1515..ac4f50df 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,14 +532,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 42a3049f..5ab549d2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cfae1c3e..0a85eb15 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index a72c57ab..69f7ce11 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 37d44c87..82b8bdac 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index e9c51370..6e6eeaf0 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d73874fb..25bd1a44 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 45b2ff42..4e8322d1 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 57e36c98..697a263e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 38d94577..d32c69f7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a050b534..690a878a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 07163bcc..ecc482d0 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 75cd249c..cc895138 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 67f87f5f..7e81b0b6 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index b0c25a6e..0e362aba 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0905 + 1.9.0-preview0906 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 6ac2e48cc596b8cc00e01589b3d3ab559cb1344e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 8 Sep 2020 18:11:29 +0800 Subject: [PATCH 0884/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=20DbFirst=20=E8=8E=B7=E5=8F=96=E5=AD=97=E6=AE=B5=20Is?= =?UTF-8?q?Nullable=20=E6=97=A0=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B#454?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs | 4 ++-- .../FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index e92dd4fa..045cd100 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -358,8 +358,8 @@ where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} ds2item[1] = row[1]; ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); ds2item[4] = DamengCodeFirst.GetDamengSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); - ds2item[5] = string.Concat(row[7]) == "1"; - ds2item[6] = string.Concat(row[8]) == "1"; + ds2item[5] = string.Concat(row[7]); + ds2item[6] = string.Concat(row[8]); ds2item[7] = string.Concat(row[9]); ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index eedf46e0..49e866fc 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -358,8 +358,8 @@ where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} ds2item[1] = row[1]; ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); ds2item[4] = OdbcDamengCodeFirst.GetDamengSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); - ds2item[5] = string.Concat(row[7]) == "1"; - ds2item[6] = string.Concat(row[8]) == "1"; + ds2item[5] = string.Concat(row[7]); + ds2item[6] = string.Concat(row[8]); ds2item[7] = string.Concat(row[9]); ds2item[8] = string.Concat(row[10]); ds2.Add(ds2item); From 020eddb3150d2d6be9d9539aa91209cb5b22fc39 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 11 Sep 2020 12:11:55 +0800 Subject: [PATCH 0885/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20GetDbParamte?= =?UTF-8?q?rsByObject=20=E5=8F=82=E6=95=B0=E4=B8=BA=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E6=97=B6=E4=BF=AE=E5=89=AA=20@=3F:=20=E5=89=8D=E8=BE=8D=20#456?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 346 +++++++++++++----------- FreeSql/Internal/UtilsExpressionTree.cs | 5 +- 2 files changed, 190 insertions(+), 161 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index a550efcb..36d2a15f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2992,153 +2992,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3908,12 +3761,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3984,12 +3831,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4648,3 +4489,190 @@ +ons.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 29e03050..8424bd4b 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1230,11 +1230,12 @@ namespace FreeSql.Internal { foreach (var key in dic.Keys) { - if (isCheckSql && string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{key}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; + var dbkey = key.ToString().TrimStart('@', '?', ':'); + if (isCheckSql && string.IsNullOrEmpty(paramPrefix) == false && sql.IndexOf($"{paramPrefix}{dbkey}", StringComparison.CurrentCultureIgnoreCase) == -1) continue; var val = dic[key]; var valType = val == null ? typeof(string) : val.GetType(); if (valType == ttype) ret.Add((T)Convert.ChangeType(val, ttype)); - else ret.Add(constructorParamter(key.ToString(), valType, val)); + else ret.Add(constructorParamter(dbkey, valType, val)); } } else From 951e917015222e234d7449f6ebacbe1dcaf3ec45 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 12 Sep 2020 05:46:53 +0800 Subject: [PATCH 0886/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Prov?= =?UTF-8?q?ider.Firebird=20=E6=95=B0=E6=8D=AE=E5=BA=93=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=20#443=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - .../Firebird/Curd/FirebirdDeleteTest.cs | 105 + ...birdInsertOrUpdateIfExistsDoNothingTest.cs | 428 ++++ .../Curd/FirebirdInsertOrUpdateTest.cs | 470 +++++ .../Firebird/Curd/FirebirdInsertTest.cs | 394 ++++ .../Firebird/Curd/FirebirdSelectTest.cs | 1848 +++++++++++++++++ .../Firebird/Curd/FirebirdUpdateTest.cs | 189 ++ .../Firebird/ExtensionsAdo/FirebirdAdoTest.cs | 71 + .../FreeSql.Tests/Firebird/FirebirdAopTest.cs | 40 + .../Firebird/FirebirdCodeFirstTest.cs | 374 ++++ .../Firebird/FirebirdDbFirstTest.cs | 51 + .../FirebirdExpression/ConvertTest.cs | 169 ++ .../FirebirdExpression/DateTimeTest.cs | 706 +++++++ .../Firebird/FirebirdExpression/MathTest.cs | 150 ++ .../Firebird/FirebirdExpression/OtherTest.cs | 173 ++ .../Firebird/FirebirdExpression/StringTest.cs | 726 +++++++ .../FirebirdExpression/TimeSpanTest.cs | 293 +++ .../Firebird/MapType/BoolNullableTest.cs | 1571 ++++++++++++++ .../Firebird/MapType/BoolTest.cs | 1105 ++++++++++ .../Firebird/MapType/DateTimeOffSetTest.cs | 54 + .../Firebird/MapType/EnumTest.cs | 261 +++ .../Firebird/MapType/ToStringTest.cs | 570 +++++ .../FreeSql.Tests/FreeSql.Tests.csproj | 1 + FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 5 + FreeSql.Tests/FreeSql.Tests/g.cs | 15 + FreeSql.sln | 15 + FreeSql/DataType.cs | 7 +- FreeSql/Extensions/AdoNetExtensions.cs | 1 + FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 4 +- FreeSql/FreeSql.xml | 354 ++-- FreeSql/FreeSqlBuilder.cs | 5 + .../CommonProvider/AdoProvider/AdoProvider.cs | 3 + .../AdoProvider/AdoProviderAsync.cs | 3 + .../CommonProvider/InsertOrUpdateProvider.cs | 9 + .../Internal/CommonProvider/InsertProvider.cs | 8 +- .../SelectProvider/Select0Provider.cs | 6 + FreeSql/Internal/UtilsExpressionTree.cs | 8 + .../Curd/FirebirdDelete.cs | 99 + .../Curd/FirebirdInsert.cs | 225 ++ .../Curd/FirebirdInsertOrUpdate.cs | 72 + .../Curd/FirebirdSelect.cs | 176 ++ .../Curd/FirebirdUpdate.cs | 145 ++ .../FirebirdAdo/FirebirdAdo.cs | 85 + .../FirebirdAdo/FirebirdConnectionPool.cs | 237 +++ .../FirebirdCodeFirst.cs | 273 +++ .../FirebirdDbFirst.cs | 391 ++++ .../FirebirdExpression.cs | 472 +++++ .../FirebirdExtensions.cs | 15 + .../FirebirdProvider.cs | 62 + .../FirebirdUtils.cs | 98 + .../FreeSql.Provider.Firebird.csproj | 36 + Providers/FreeSql.Provider.Firebird/key.snk | Bin 0 -> 596 bytes .../新建文本文档.txt | 21 + .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 1 - readme.md | 2 +- 55 files changed, 12407 insertions(+), 211 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/ExtensionsAdo/FirebirdAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Firebird/MapType/ToStringTest.cs create mode 100644 Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs create mode 100644 Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs create mode 100644 Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs create mode 100644 Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdConnectionPool.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FirebirdExtensions.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs create mode 100644 Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj create mode 100644 Providers/FreeSql.Provider.Firebird/key.snk create mode 100644 Providers/FreeSql.Provider.Firebird/新建文本文档.txt diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdDeleteTest.cs new file mode 100644 index 00000000..58ac2ba4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdDeleteTest.cs @@ -0,0 +1,105 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdDeleteTest + { + + IDelete delete => g.firebird.Delete(); + + [Table(Name = "tb_topic_del")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.firebird.Delete().ToSql()); + var sql = g.firebird.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.firebird.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); + + sql = g.firebird.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.firebird.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); + + sql = g.firebird.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC_DEL\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.firebird.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + delete.Where(a => a.Id > 0).ExecuteDeleted(); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.firebird.Delete().ToSql()); + var sql = g.firebird.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.firebird.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + + sql = g.firebird.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.firebird.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..204c696d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,428 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.firebird; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT FIRST 1 1 as ID FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT FIRST 1 1 as ID FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT FIRST 1 2 as ID FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT FIRST 1 1 as ID FROM rdb$database +UNION ALL + SELECT FIRST 1 2 FROM rdb$database +UNION ALL + SELECT FIRST 1 3 FROM rdb$database +UNION ALL + SELECT FIRST 1 4 FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT FIRST 1 1 as ID FROM rdb$database +UNION ALL + SELECT FIRST 1 2 FROM rdb$database +UNION ALL + SELECT FIRST 1 3 FROM rdb$database +UNION ALL + SELECT FIRST 1 4 FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT FIRST 1 1 as ID, '011' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT FIRST 1 2 as ID, '02' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT FIRST 1 1 as ID, '001' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '002' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '003' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '004' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT FIRST 1 1 as ID, '011' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT FIRST 1 2 as ID, '02' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT FIRST 1 1 as ID, '001' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '002' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '003' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '004' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") SELECT FIRST 1 '01' FROM rdb$database +UNION ALL + SELECT FIRST 1 '02' FROM rdb$database +UNION ALL + SELECT FIRST 1 '03' FROM rdb$database +UNION ALL + SELECT FIRST 1 '04' FROM rdb$database", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") SELECT FIRST 1 '001' FROM rdb$database +UNION ALL + SELECT FIRST 1 '002' FROM rdb$database +UNION ALL + SELECT FIRST 1 '003' FROM rdb$database +UNION ALL + SELECT FIRST 1 '004' FROM rdb$database", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT FIRST 1 1 as ID, '100001' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '100002' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '100003' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '100004' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT INTO ""TBIOUDB022""(""NAME"") SELECT FIRST 1 '00001' FROM rdb$database +UNION ALL + SELECT FIRST 1 '00002' FROM rdb$database +UNION ALL + SELECT FIRST 1 '00003' FROM rdb$database +UNION ALL + SELECT FIRST 1 '00004' FROM rdb$database", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT FIRST 1 1 as ID1, '01' as ID2, '01' as NAME FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT FIRST 1 1 as ID1, '01' as ID2, '011' as NAME FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT FIRST 1 2 as ID1, '02' as ID2, '02' as NAME FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT FIRST 1 1 as ID1, '01' as ID2, '01' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02', '02' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03', '03' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04', '04' FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT FIRST 1 1 as ID1, '01' as ID2, '001' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02', '002' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03', '003' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04', '004' FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT FIRST 1 1 as ID, '011' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT FIRST 1 2 as ID, '02' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02', 0, current_timestamp FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03', 0, current_timestamp FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04', 0, current_timestamp FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT FIRST 1 1 as ID, '001' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '002', 0, current_timestamp FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '003', 0, current_timestamp FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '004', 0, current_timestamp FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertOrUpdateTest.cs new file mode 100644 index 00000000..2164984d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertOrUpdateTest.cs @@ -0,0 +1,470 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdInsertOrUpdateTest + { + IFreeSql fsql => g.firebird; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT FIRST 1 1 as ID FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT FIRST 1 1 as ID FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT FIRST 1 2 as ID FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT FIRST 1 1 as ID FROM rdb$database +UNION ALL + SELECT FIRST 1 2 FROM rdb$database +UNION ALL + SELECT FIRST 1 3 FROM rdb$database +UNION ALL + SELECT FIRST 1 4 FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT FIRST 1 1 as ID FROM rdb$database +UNION ALL + SELECT FIRST 1 2 FROM rdb$database +UNION ALL + SELECT FIRST 1 3 FROM rdb$database +UNION ALL + SELECT FIRST 1 4 FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT FIRST 1 1 as ID, '011' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT FIRST 1 2 as ID, '02' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT FIRST 1 1 as ID, '001' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '002' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '003' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '004' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT FIRST 1 1 as ID, '011' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT FIRST 1 2 as ID, '02' as NAME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT FIRST 1 1 as ID, '001' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '002' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '003' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '004' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") SELECT FIRST 1 '01' FROM rdb$database +UNION ALL + SELECT FIRST 1 '02' FROM rdb$database +UNION ALL + SELECT FIRST 1 '03' FROM rdb$database +UNION ALL + SELECT FIRST 1 '04' FROM rdb$database", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") SELECT FIRST 1 '001' FROM rdb$database +UNION ALL + SELECT FIRST 1 '002' FROM rdb$database +UNION ALL + SELECT FIRST 1 '003' FROM rdb$database +UNION ALL + SELECT FIRST 1 '004' FROM rdb$database", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT FIRST 1 1 as ID, '100001' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '100002' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '100003' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '100004' FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT INTO ""TBIOU022""(""NAME"") SELECT FIRST 1 '00001' FROM rdb$database +UNION ALL + SELECT FIRST 1 '00002' FROM rdb$database +UNION ALL + SELECT FIRST 1 '00003' FROM rdb$database +UNION ALL + SELECT FIRST 1 '00004' FROM rdb$database", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT FIRST 1 1 as ID1, '01' as ID2, '01' as NAME FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT FIRST 1 1 as ID1, '01' as ID2, '011' as NAME FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT FIRST 1 2 as ID1, '02' as ID2, '02' as NAME FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT FIRST 1 1 as ID1, '01' as ID2, '01' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02', '02' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03', '03' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04', '04' FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT FIRST 1 1 as ID1, '01' as ID2, '001' as NAME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02', '002' FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03', '003' FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04', '004' FROM rdb$database ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT FIRST 1 1 as ID, '011' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT FIRST 1 2 as ID, '02' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT FIRST 1 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '02', 0, current_timestamp FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '03', 0, current_timestamp FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '04', 0, current_timestamp FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT FIRST 1 1 as ID, '001' as NAME, 0 as VERSION, current_timestamp as CREATETIME FROM rdb$database +UNION ALL + SELECT FIRST 1 2, '002', 0, current_timestamp FROM rdb$database +UNION ALL + SELECT FIRST 1 3, '003', 0, current_timestamp FROM rdb$database +UNION ALL + SELECT FIRST 1 4, '004', 0, current_timestamp FROM rdb$database ) t2 ON (t1.""ID"" = t2.ID) +WHEN MATCHED THEN + update set ""NAME"" = t2.NAME, ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs new file mode 100644 index 00000000..0f14a9b8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs @@ -0,0 +1,394 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdInsertTest + { + + IInsert insert => g.firebird.Insert(); + + [Table(Name = "TB_TOPIC_INSERT")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal(@"INSERT INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") SELECT FIRST 1 @Clicks_0, @Title_0, @CreateTime_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1, @Title_1, @CreateTime_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2, @Title_2, @CreateTime_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3, @Title_3, @CreateTime_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4, @Title_4, @CreateTime_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5, @Title_5, @CreateTime_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6, @Title_6, @CreateTime_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7, @Title_7, @CreateTime_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8, @Title_8, @CreateTime_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9, @Title_9, @CreateTime_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT INTO ""TB_TOPIC_INSERT""(""TITLE"") SELECT FIRST 1 @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") SELECT FIRST 1 @Clicks_0, @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1, @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2, @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3, @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4, @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5, @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6, @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7, @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8, @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9, @Title_9 FROM rdb$database", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT INTO ""TB_TOPIC_INSERT""(""TITLE"") SELECT FIRST 1 @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal(@"INSERT INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") SELECT FIRST 1 @Clicks_0, @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1, @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2, @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3, @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4, @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5, @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6, @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7, @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8, @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9, @Title_9 FROM rdb$database", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") SELECT FIRST 1 @Clicks_0, @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1, @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2, @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3, @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4, @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5, @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6, @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7, @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8, @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9, @Title_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal(@"INSERT INTO ""TB_TOPIC_INSERT""(""CLICKS"") SELECT FIRST 1 @Clicks_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9 FROM rdb$database", sql); + + g.firebird.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.firebird.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.firebird.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "TB_TOPICIGNORECOLUMNS")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.NoneParameter().AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var ret1 = insert.AppendData(items.First()).ExecuteInserted(); + var ret2 = insert.NoneParameter().AppendData(items).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(@Clicks_0, @Title_0, @CreateTime_0)", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") SELECT FIRST 1 @Clicks_0, @Title_0, @CreateTime_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1, @Title_1, @CreateTime_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2, @Title_2, @CreateTime_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3, @Title_3, @CreateTime_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4, @Title_4, @CreateTime_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5, @Title_5, @CreateTime_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6, @Title_6, @CreateTime_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7, @Title_7, @CreateTime_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8, @Title_8, @CreateTime_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9, @Title_9, @CreateTime_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO ""TOPIC_INSERTASTABLE""(""TITLE"") SELECT FIRST 1 @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") SELECT FIRST 1 @Clicks_0, @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1, @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2, @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3, @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4, @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5, @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6, @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7, @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8, @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9, @Title_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO ""TOPIC_INSERTASTABLE""(""TITLE"") SELECT FIRST 1 @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Title_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") SELECT FIRST 1 @Clicks_0, @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1, @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2, @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3, @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4, @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5, @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6, @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7, @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8, @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9, @Title_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") SELECT FIRST 1 @Clicks_0, @Title_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1, @Title_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2, @Title_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3, @Title_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4, @Title_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5, @Title_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6, @Title_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7, @Title_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8, @Title_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9, @Title_9 FROM rdb$database", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT INTO ""TOPIC_INSERTASTABLE""(""CLICKS"") SELECT FIRST 1 @Clicks_0 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_1 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_2 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_3 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_4 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_5 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_6 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_7 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_8 FROM rdb$database +UNION ALL + SELECT FIRST 1 @Clicks_9 FROM rdb$database", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs new file mode 100644 index 00000000..33c14af4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs @@ -0,0 +1,1848 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdSelectTest + { + + ISelect select => g.firebird.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.firebird.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.firebird.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.firebird.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.firebird.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.firebird.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.firebird.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.firebird.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.firebird.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + g.firebird.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.firebird.Select().ToList(); + var testGuidId6 = g.firebird.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.firebird.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.firebird.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.firebird.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + g.firebird.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.firebird.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.Where(a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.Where("a.\"CLICKS\" > 100 and a.\"ID\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = @id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.WhereIf(true, a => a.Id == 10); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE ((a.\"ID\" = 10 AND a.\"ID\" > 10 OR a.\"CLICKS\" > 100))", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"ID\" = 10) AND (a.\"CLICKS\" > 100)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(true, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c WHERE (a.\"ID\" = 10 AND c.\"NAME\" = 'xxx') AND (b.\"PARENTID\" = 20)", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(true, "a.\"CLICKS\" > 100 and a.\"ID\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = @id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") + .WhereIf(false, a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.WhereIf(false, "a.\"CLICKS\" > 100 and a.\"ID\" = @id", new { id = 10 }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.firebird.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.firebird.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT FIRST 1 sum(b.""ID"") + FROM ""TB_TOPIC22"" b) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT FIRST 1 min(b.""ID"") + FROM ""TB_TOPIC22"" b) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Min(b => b.Id) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT FIRST 1 max(b.""ID"") + FROM ""TB_TOPIC22"" b) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Max(b => b.Id) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT FIRST 1 avg(b.""ID"") + FROM ""TB_TOPIC22"" b) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE (((cast(a.""ID"" as char)) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic22 where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALLSELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + //select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.firebird.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.firebird.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.firebird.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.firebird.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.firebird.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.firebird.Insert(model4s).ExecuteAffrows()); + + var t0 = g.firebird.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.firebird.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.firebird.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.firebird.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.firebird.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.firebird.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.firebird.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.firebird.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.firebird.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.firebird.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.firebird.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.firebird.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.firebird.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.firebird.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.firebird.Insert(model1).ExecuteIdentity(); + + var t1 = g.firebird.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.firebird.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.firebird.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.firebird.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.firebird.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.firebird.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.firebird.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.firebird.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.firebird.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.firebird.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.firebird.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.firebird.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.firebird.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.firebird.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.firebird.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.firebird.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.firebird.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.firebird.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.firebird.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.firebird.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.firebird.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.firebird.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.firebird.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.firebird.Insert(song3).ExecuteIdentity(); + + g.firebird.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.firebird.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.firebird.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.firebird.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.firebird.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.firebird.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.firebird.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.firebird.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.firebird.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.firebird.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.firebird, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.firebird.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.firebird.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.firebird.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.firebird.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.firebird.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.firebird.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.firebird.Select().Count()); + g.firebird.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.firebird.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.firebird.Select().Count()); + Assert.Equal(3, g.firebird.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.firebird.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.firebird.Select().Count()); + g.firebird.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.firebird.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.firebird.Select().Count()); + Assert.Equal(3, g.firebird.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.firebird.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.firebird.Select().Count()); + g.firebird.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.firebird.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.firebird.Select().Count()); + Assert.Equal(3, g.firebird.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.firebird.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.firebird.Select().Count()); + g.firebird.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.firebird.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.firebird.Select().Count()); + Assert.Equal(5, g.firebird.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.firebird.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.firebird.Select().Count()); + g.firebird.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.firebird.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.firebird.Select().Count()); + Assert.Equal(5, g.firebird.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.firebird.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.firebird.Select().Count()); + g.firebird.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.firebird.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.firebird.Select().Count()); + Assert.Equal(5, g.firebird.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.firebird; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT FIRST 1 a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a for update with lock", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT FIRST 1 a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a for update with lock", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.firebird; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + + public int testint { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs new file mode 100644 index 00000000..0cb43def --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs @@ -0,0 +1,189 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdUpdateTest + { + IUpdate update => g.firebird.Update(); + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.firebird.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.firebird.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.firebird.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.firebird.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.firebird.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1, \"CREATETIME\" = @p_2 WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CREATETIME\" = @p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.firebird.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.firebird.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0, \"CREATETIME\" = @p_1 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = trunc(coalesce(\"CLICKS\", 0) * 10/1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = trunc(coalesce(\"CLICKS\", 0) * 10/1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10/1) WHERE (\"ID\" = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = case when \"CREATETIME\" > timestamp '2000-01-01 00:00:00.000' then 1 else 2 end WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET clicks = clicks + @incrClick WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1 WHERE (\"ID\" = 1)", sql); + sql = update.NoneParameter().SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1 WHERE (\"ID\" = 1)", sql); + sql = update.NoneParameter().SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='newtitle' WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.firebird.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.firebird.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.firebird.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.firebird.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.firebird.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/ExtensionsAdo/FirebirdAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/ExtensionsAdo/FirebirdAdoTest.cs new file mode 100644 index 00000000..2ddeab02 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/ExtensionsAdo/FirebirdAdoTest.cs @@ -0,0 +1,71 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.firebird.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.firebird.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteTest() + { + Assert.True(g.firebird.Ado.ExecuteConnectTest()); + } + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t3 = g.firebird.Ado.Query("select * from \"TB_TOPIC22\""); + + var t4 = g.firebird.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC22\""); + + var t5 = g.firebird.Ado.Query("select * from \"TB_TOPIC22\""); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.firebird.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdAopTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdAopTest.cs new file mode 100644 index 00000000..15b84ac8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.firebird.Aop.AuditValue += audit; + + g.firebird.Insert(item).ExecuteAffrows(); + + g.firebird.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdCodeFirstTest.cs new file mode 100644 index 00000000..32ae41b0 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdCodeFirstTest.cs @@ -0,0 +1,374 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdCodeFirstTest + { + [Fact] + public void Text_StringLength_1() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + + var item1 = new TS_TEXT02 { Data = str1 }; + Assert.Equal(1, g.firebird.Insert(item1).ExecuteAffrows()); + + var item2 = g.firebird.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + + //NoneParameter + item1 = new TS_TEXT02 { Data = str1 }; + Assert.Equal(1, g.firebird.Insert(item1).NoneParameter().ExecuteAffrows()); + item2 = g.firebird.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(str1, item2.Data); + //Assert.Throws(() => g.firebird.Insert(item1).NoneParameter().ExecuteAffrows()); + //Dynamic SQL Error + //SQL error code = -104 + //String literal with 159999 bytes exceeds the maximum length of 65535 bytes + } + class TS_TEXT02 + { + public Guid Id { get; set; } + [Column(StringLength = - 1)] + public string Data { get; set; } + } + + [Fact] + public void Blob() + { + var str1 = string.Join(",", Enumerable.Range(0, 10000).Select(a => "й")); + var data1 = Encoding.UTF8.GetBytes(str1); + + var item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.firebird.Insert(item1).ExecuteAffrows()); + + var item2 = g.firebird.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + var str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + + //NoneParameter + item1 = new TS_BLB01 { Data = data1 }; + Assert.Equal(1, g.firebird.Insert(item1).NoneParameter().ExecuteAffrows()); + item2 = g.firebird.Select().Where(a => a.Id == item1.Id).First(); + Assert.Equal(item1.Data.Length, item2.Data.Length); + str2 = Encoding.UTF8.GetString(item2.Data); + Assert.Equal(str1, str2); + //Assert.Throws(() => g.firebird.Insert(item1).NoneParameter().ExecuteAffrows()); + //Dynamic SQL Error + //SQL error code = -104 + //String literal with 159999 bytes exceeds the maximum length of 65535 bytes + } + class TS_BLB01 + { + public Guid Id { get; set; } + public byte[] Data { get; set; } + } + [Fact] + public void StringLength() + { + var dll = g.firebird.CodeFirst.GetComparisonDDLStatements(); + g.firebird.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void ֱ_ֶ() + { + var sql = g.firebird.CodeFirst.GetComparisonDDLStatements<ֱ>(); + g.firebird.CodeFirst.SyncStructure<ֱ>(); + + var item = new ֱ + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.firebird.Insert<ֱ>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.firebird.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.firebird.Update<ֱ>().SetSource(item).ExecuteAffrows()); + item2 = g.firebird.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.firebird.GetRepository<ֱ>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.firebird.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.firebird.Select<ֱ>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + [Table(Name = "123tb")] + [OraclePrimaryKeyName("pk1_123tb")] + class ֱ + { + [Column(IsPrimary = true, Name = "123id")] + public Guid { get; set; } + + [Column(Name = "123title")] + public string { get; set; } + + [Column(Name = "123time")] + public DateTime ʱ { get; set; } + } + + [Fact] + public void ı_ֶ() + { + var sql = g.firebird.CodeFirst.GetComparisonDDLStatements<ı>(); + g.firebird.CodeFirst.SyncStructure<ı>(); + + var item = new ı + { + = "Ա", + ʱ = DateTime.Now + }; + Assert.Equal(1, g.firebird.Insert<ı>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.); + var item2 = g.firebird.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա"; + Assert.Equal(1, g.firebird.Update<ı>().SetSource(item).ExecuteAffrows()); + item2 = g.firebird.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo"; + var repo = g.firebird.GetRepository<ı>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.firebird.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + + item. = "Ա_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.firebird.Select<ı>().Where(a => a. == item.).First(); + Assert.NotNull(item2); + Assert.Equal(item., item2.); + Assert.Equal(item., item2.); + } + class ı + { + [Column(IsPrimary = true)] + public Guid { get; set; } + + public string { get; set; } + + [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)] + public DateTime ʱ { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime ʱ { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.firebird.CodeFirst.GetComparisonDDLStatements(); + g.firebird.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index2", "group,index", false)] + class AddUniquesInfo + { + /// + /// + /// + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.firebird.CodeFirst.GetComparisonDDLStatements(); + + var id = g.firebird.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.firebird.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title2 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + var sql = g.firebird.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.firebird.Insert(); + ISelect select => g.firebird.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + insert.AppendData(item).ExecuteAffrows(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("й"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "йstring'\\?!@#$%^&*()_+{}}{~?><<>", + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = long.MaxValue, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + + insert.AppendData(item2).ExecuteAffrows(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + item2.Id = Guid.NewGuid(); + insert.NoneParameter().AppendData(item2).ExecuteAffrows(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + + var items = select.ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsPrimary = true)] + public Guid Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime DateTime { get; set; } + [Column(ServerTime = DateTimeKind.Local)] + public DateTime DateTimeOffSet { get; set; } + + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? DateTimeNullable { get; set; } + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? DateTimeOffSetNullable { get; set; } + + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdDbFirstTest.cs new file mode 100644 index 00000000..d927e0d1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdDbFirstTest.cs @@ -0,0 +1,51 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Firebird +{ + public class FirebirdDbFirstTest + { + [Fact] + public void GetDatabases() + { + var t1 = g.firebird.DbFirst.GetDatabases(); + } + + [Fact] + public void GetTablesByDatabase() + { + var t1 = g.firebird.DbFirst.GetTablesByDatabase(); + var t2 = g.firebird.DbFirst.GetTablesByDatabase(g.firebird.DbFirst.GetDatabases()[0]); + Assert.True(t1.Count > 0); + Assert.True(t2.Count > 0); + } + + [Fact] + public void GetTableByName() + { + var fsql = g.firebird; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + Assert.NotNull(t1); + Assert.True(t1.Columns.Count > 0); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + + [Fact] + public void ExistsTable() + { + var fsql = g.firebird; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb011")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb011", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb011)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb011")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb011", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb011"); + } + class test_existstb011 + { + public Guid id { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/ConvertTest.cs new file mode 100644 index 00000000..2bbd2e57 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.FirebirdExpression +{ + public class ConvertTest + { + + ISelect select => g.firebird.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs new file mode 100644 index 00000000..57f8512e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs @@ -0,0 +1,706 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.FirebirdExpression +{ + public class DateTimeTest + { + + ISelect select => g.firebird.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/MathTest.cs new file mode 100644 index 00000000..57b4dc07 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/MathTest.cs @@ -0,0 +1,150 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.FirebirdExpression +{ + public class MathTest + { + + ISelect select => g.firebird.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/OtherTest.cs new file mode 100644 index 00000000..ab011e3d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/OtherTest.cs @@ -0,0 +1,173 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.FirebirdExpression +{ + public class OtherTest + { + + ISelect select => g.firebird.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Int > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Int > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Int > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Int > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Int > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Int > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Int > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Int > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Int > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Int > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Int > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Int > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Int > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Int > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Int > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Int > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Int > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Int > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Int > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Int > 0 && a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsPrimary = true)] + public Guid Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime DateTime { get; set; } + [Column(ServerTime = DateTimeKind.Local)] + public DateTime DateTimeOffSet { get; set; } + + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? DateTimeNullable { get; set; } + [Column(ServerTime = DateTimeKind.Local)] + public DateTime? DateTimeOffSetNullable { get; set; } + + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs new file mode 100644 index 00000000..a58e6eb1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs @@ -0,0 +1,726 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.FirebirdExpression +{ + public class StringTest + { + + ISelect select => g.firebird.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.firebird.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 + //FROM `tb_topic` a, `TestTypeInfo` a__Type + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/TimeSpanTest.cs new file mode 100644 index 00000000..4be90e4b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.FirebirdExpression +{ + public class TimeSpanTest + { + + ISelect select => g.firebird.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..fc4f6470 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.FirebirdMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.firebird; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/BoolTest.cs new file mode 100644 index 00000000..3d7041ac --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.FirebirdMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.firebird; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..9ef5ee0f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.FirebirdMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.firebird; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/EnumTest.cs new file mode 100644 index 00000000..e8e357e7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.FirebirdMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.firebird; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.firebird; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.firebird; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.firebird; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/ToStringTest.cs new file mode 100644 index 00000000..f2e44542 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.FirebirdMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.firebird; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index e6703320..266bb4e9 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -38,6 +38,7 @@ + diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index b54c9d60..c8168e34 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -4,6 +4,11 @@ FreeSql.Tests + + + 编号 + + 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 02e4b983..533be9f6 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -162,4 +162,19 @@ public class g (cmd, traceLog) => Console.WriteLine(traceLog)) .Build()); public static IFreeSql kingbaseES => kingbaseESLazy.Value; + + static Lazy firebirdLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Firebird, @"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5") + //.UseConnectionFactory(FreeSql.DataType.Firebird, () => new FirebirdSql.Data.FirebirdClient.FbConnection(@"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5")) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql firebird => firebirdLazy.Value; + } diff --git a/FreeSql.sln b/FreeSql.sln index 8ffb0633..fa28ac8e 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -88,6 +88,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.SqlServerF EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.KingbaseES", "Providers\FreeSql.Provider.KingbaseES\FreeSql.Provider.KingbaseES.csproj", "{CDD6A896-F6DF-44CB-B430-06B383916EB0}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Firebird", "Providers\FreeSql.Provider.Firebird\FreeSql.Provider.Firebird.csproj", "{101B11D2-7780-4E14-9B72-77F5D69B3DF9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -542,6 +544,18 @@ Global {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|x64.Build.0 = Release|Any CPU {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|x86.ActiveCfg = Release|Any CPU {CDD6A896-F6DF-44CB-B430-06B383916EB0}.Release|x86.Build.0 = Release|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Debug|x64.ActiveCfg = Debug|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Debug|x64.Build.0 = Debug|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Debug|x86.ActiveCfg = Debug|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Debug|x86.Build.0 = Debug|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Release|Any CPU.Build.0 = Release|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Release|x64.ActiveCfg = Release|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Release|x64.Build.0 = Release|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Release|x86.ActiveCfg = Release|Any CPU + {101B11D2-7780-4E14-9B72-77F5D69B3DF9}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -573,6 +587,7 @@ Global {938173AF-157F-4040-AED3-171DA1809CAA} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {3D2BD8EC-253A-437F-B4C8-74BC0D91429B} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {CDD6A896-F6DF-44CB-B430-06B383916EB0} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {101B11D2-7780-4E14-9B72-77F5D69B3DF9} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index 78f0d7cb..e91745d9 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -49,6 +49,11 @@ namespace FreeSql /// /// 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 /// - KingbaseES + KingbaseES, + + /// + /// Firebird 是一个跨平台的关系数据库,能作为多用户环境下的数据库服务器运行,也提供嵌入式数据库的实现 + /// + Firebird } } diff --git a/FreeSql/Extensions/AdoNetExtensions.cs b/FreeSql/Extensions/AdoNetExtensions.cs index 451d7c7c..b9f874ba 100644 --- a/FreeSql/Extensions/AdoNetExtensions.cs +++ b/FreeSql/Extensions/AdoNetExtensions.cs @@ -117,6 +117,7 @@ namespace FreeSql /// SqlServer 2008+: merge into /// Oracle 11+: merge into /// Sqlite: replace into + /// Firebird: merge into /// 达梦: merge into /// 人大金仓:on conflict do update /// 神通:merge into diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 0a3cf29b..717db8f2 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -393,7 +393,7 @@ public static partial class FreeSqlGlobalExtensions #region AsTreeCte(..) 递归查询 /// /// 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 - /// 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + /// 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓 /// 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) /// /// @@ -435,6 +435,7 @@ public static partial class FreeSqlGlobalExtensions case DataType.ShenTong: //神通测试未通过 case DataType.SqlServer: case DataType.OdbcSqlServer: + case DataType.Firebird: sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, Expression.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(string) }), pathSelector?.Body), null, null, null); break; default: @@ -493,6 +494,7 @@ public static partial class FreeSqlGlobalExtensions case DataType.ShenTong: //神通测试未通过 case DataType.MySql: case DataType.OdbcMySql: + case DataType.Firebird: nsselsb.Append("RECURSIVE "); break; } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 36d2a15f..dbca2d52 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -606,6 +606,11 @@ 北京人大金仓信息技术股份有限公司,基于 Kdbndp.dll 的实现 + + + Firebird 是一个跨平台的关系数据库,能作为多用户环境下的数据库服务器运行,也提供嵌入式数据库的实现 + + 获取 IDbConnection 对应的 IFreeSql 实例 @@ -660,6 +665,7 @@ SqlServer 2008+: merge into Oracle 11+: merge into Sqlite: replace into + Firebird: merge into 达梦: merge into 人大金仓:on conflict do update 神通:merge into @@ -2992,6 +2998,153 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3761,6 +3914,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3831,6 +3990,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4139,7 +4304,7 @@ 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 - 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、达梦、人大金仓 + 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) @@ -4489,190 +4654,3 @@ -ons.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 727d0fc4..c6ce3ac3 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -251,6 +251,11 @@ namespace FreeSql if (type == null) throwNotFind("FreeSql.Provider.KingbaseES.dll", "FreeSql.KingbaseES.KingbaseESProvider<>"); break; + case DataType.Firebird: + type = Type.GetType("FreeSql.Firebird.FirebirdProvider`1,FreeSql.Provider.Firebird")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.Firebird.dll", "FreeSql.Firebird.FirebirdProvider<>"); + break; + default: throw new Exception("未指定 UseConnectionString 或者 UseConnectionFactory"); } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 921673f6..c73f7235 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -106,6 +106,9 @@ namespace FreeSql.Internal.CommonProvider case DataType.OdbcOracle: ExecuteNonQuery(" SELECT 1 FROM dual"); return true; + case DataType.Firebird: + ExecuteNonQuery(" SELECT FIRST 1 1 FROM rdb$database"); + return true; } ExecuteNonQuery(" SELECT 1"); return true; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 6d40ebcc..64adc306 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -24,6 +24,9 @@ namespace FreeSql.Internal.CommonProvider case DataType.OdbcOracle: await ExecuteNonQueryAsync(" SELECT 1 FROM dual"); return true; + case DataType.Firebird: + await ExecuteNonQueryAsync(" SELECT FIRST 1 1 FROM rdb$database"); + return true; } await ExecuteNonQueryAsync(" SELECT 1"); return true; diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 7799c8ff..efc2646c 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -145,6 +145,12 @@ namespace FreeSql.Internal.CommonProvider { if (didx > 0) sb.Append(" \r\nUNION ALL\r\n "); sb.Append("SELECT "); + switch (_orm.Ado.DataType) + { + case DataType.Firebird: + sb.Append("FIRST 1 "); + break; + } var colidx2 = 0; foreach (var col in _table.Columns.Values) { @@ -167,6 +173,9 @@ namespace FreeSql.Internal.CommonProvider case DataType.Dameng: sb.Append(" FROM dual"); break; + case DataType.Firebird: + sb.Append(" FROM rdb$database"); + break; } ++didx; } diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 2d03379b..76d27e9c 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -522,10 +522,11 @@ namespace FreeSql.Internal.CommonProvider return this; } - public virtual string ToSql() => ToSqlValuesOrSelectUnionAll(true); + public virtual string ToSql() => ToSqlValuesOrSelectUnionAllExtension102(true, null, null); - public string ToSqlValuesOrSelectUnionAll(bool isValues = true) => ToSqlValuesOrSelectUnionAllExtension101(isValues, null); - public string ToSqlValuesOrSelectUnionAllExtension101(bool isValues, Action onrow) + public string ToSqlValuesOrSelectUnionAll(bool isValues = true) => ToSqlValuesOrSelectUnionAllExtension102(isValues, null, null); + public string ToSqlValuesOrSelectUnionAllExtension101(bool isValues, Action onrow) => ToSqlValuesOrSelectUnionAllExtension102(isValues, null, onrow); + public string ToSqlValuesOrSelectUnionAllExtension102(bool isValues, Action onrowPre, Action onrow) { if (_source == null || _source.Any() == false) return null; var sb = new StringBuilder(); @@ -549,6 +550,7 @@ namespace FreeSql.Internal.CommonProvider { if (didx > 0) sb.Append(isValues ? ", " : " \r\nUNION ALL\r\n "); sb.Append(isValues ? "(" : "SELECT "); + onrowPre?.Invoke(d, didx, sb); var colidx2 = 0; foreach (var col in _table.Columns.Values) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index bde34d53..f803a212 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -287,6 +287,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.OdbcDameng: //达梦不能这样 case DataType.Oracle: case DataType.OdbcOracle: + case DataType.Firebird: break; default: _select = "SELECT "; @@ -334,6 +335,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.OdbcDameng: //达梦不能这样 case DataType.Oracle: case DataType.OdbcOracle: + case DataType.Firebird: break; default: var beforeSql = this._select; @@ -359,6 +361,7 @@ namespace FreeSql.Internal.CommonProvider case DataType.OdbcDameng: //达梦不能这样 case DataType.Oracle: case DataType.OdbcOracle: + case DataType.Firebird: break; default: var beforeSql = this._select; @@ -648,6 +651,9 @@ namespace FreeSql.Internal.CommonProvider case DataType.ShenTong: //神通测试中发现,不支持 nowait _tosqlAppendContent = " for update"; break; + case DataType.Firebird: + _tosqlAppendContent = " for update with lock"; + break; } return this as TSelect; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 8424bd4b..83c5c442 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -275,6 +275,11 @@ namespace FreeSql.Internal if (strlen < 0) colattr.DbType = "LONGTEXT"; else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); break; + case DataType.Firebird: + charPatten = @"(CHAR|CHAR2|CHARACTER|TEXT)\s*(\([^\)]*\))?"; + if (strlen < 0) colattr.DbType = "BLOB SUB_TYPE 1"; + else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})"); + break; } } if (colattr.MapType == typeof(byte[]) && colattr.StringLength != 0) @@ -318,6 +323,9 @@ namespace FreeSql.Internal if (strlen < 0) colattr.DbType = "BLOB"; else colattr.DbType = Regex.Replace(colattr.DbType, bytePatten, $"$1({strlen})"); break; + case DataType.Firebird: + colattr.DbType = "BLOB"; + break; } } if (colattr.MapType == typeof(decimal) && colattr.Precision > 0) diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs new file mode 100644 index 00000000..7ed41a5b --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs @@ -0,0 +1,99 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Firebird.Curd +{ + + class FirebirdDelete : Internal.CommonProvider.DeleteProvider where T1 : class + { + public FirebirdDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + this.ClearData(); + return ret; + } + +#if net40 +#else + async public override Task> ExecuteDeletedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + this.ClearData(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs new file mode 100644 index 00000000..c22f3394 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs @@ -0,0 +1,225 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Firebird.Curd +{ + + class FirebirdInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public FirebirdInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() + { + base.NoneParameter(_source?.Count > 1); + return base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + } + public override long ExecuteIdentity() + { + base.NoneParameter(_source?.Count > 1); + return base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + } + public override List ExecuteInserted() => base.SplitExecuteInserted(1, 999); + + public override string ToSql() => + _source?.Count <= 1 ? + base.ToSqlValuesOrSelectUnionAll() : + base.ToSqlValuesOrSelectUnionAllExtension102(false, (rowd, idx, sb) => sb.Append("FIRST 1 "), (rowd, idx, sb) => sb.Append(" FROM rdb$database")); + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() + { + base.NoneParameter(_source?.Count > 1); + return base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + } + public override Task ExecuteIdentityAsync() + { + base.NoneParameter(_source?.Count > 1); + return base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + } + public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1, 1000); + + async protected override Task RawExecuteIdentityAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs new file mode 100644 index 00000000..a4272fe9 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs @@ -0,0 +1,72 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.Firebird.Curd +{ + + class FirebirdInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public FirebirdInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var dbParams = new List(); + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = getMergeSql(ds.Item1); + if (ds.Item2.Any()) sqls[1] = getInsertSql(ds.Item2); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getMergeSql(List data) + { + if (_table.Primarys.Any() == false) throw new Exception($"InsertOrUpdate 功能执行 merge into 要求实体类 {_table.CsName} 必须有主键"); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + if (_doNothing == false && cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{a.Attribute.Name}"))).Append(")"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs new file mode 100644 index 00000000..a4289cc4 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs @@ -0,0 +1,176 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Firebird.Curd +{ + + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereCascadeExpression.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + + if (_limit > 0 && _skip > 0) sb.Append("FIRST ").Append(_limit).Append(" SKIP ").Append(_skip).Append(" "); + else if (_limit > 0) sb.Append("FIRST ").Append(_limit).Append(" "); + else if (_skip > 0) sb.Append("SKIP ").Append(_skip).Append(" "); + + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + if (tb.Type == SelectTableInfoType.Parent) continue; + switch (tb.Type) + { + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } +} + diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs new file mode 100644 index 00000000..0b9e9080 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs @@ -0,0 +1,145 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Firebird.Curd +{ + + class FirebirdUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + { + + public FirebirdUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + + protected override List RawExecuteUpdated() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"new.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (_table.Primarys.Length == 1) + { + var pk = _table.Primarys.First(); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) caseWhen.Append(", '+', "); + caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (_table.Primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys[0].GetDbValue(d))); + return; + } + sb.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in _table.Primarys) + { + if (pkidx > 0) sb.Append(", '+', "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); + ++pkidx; + } + sb.Append(")"); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + + async protected override Task> RawExecuteUpdatedAsync() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"new.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var dbParms = _params.Concat(_paramsSource).ToArray(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ValidateVersionAndThrow(ret.Count, sql, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs b/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs new file mode 100644 index 00000000..7f5988e2 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs @@ -0,0 +1,85 @@ +using FirebirdSql.Data.FirebirdClient; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Text; +using System.Threading; + +namespace FreeSql.Firebird +{ + class FirebirdAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + + public FirebirdAdo() : base(DataType.Firebird, null, null) { } + public FirebirdAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.Firebird, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.Firebird, connectionFactory); + MasterPool = pool; + _CreateCommandConnection = pool.TestConnection; + return; + } + if (!string.IsNullOrEmpty(masterConnectionString)) + MasterPool = new FirebirdConnectionPool("主库", masterConnectionString, null, null); + if (slaveConnectionStrings != null) + { + foreach (var slaveConnectionString in slaveConnectionStrings) + { + var slavePool = new FirebirdConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); + SlavePools.Add(slavePool); + } + } + } + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is bool || param is bool?) + return (bool)param ? "true" : "false"; + else if (param is string || param is char) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("timestamp '", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"x'{CommonUtils.BytesSqlRaw(param as byte[])}'"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + DbConnection _CreateCommandConnection; + protected override DbCommand CreateCommand() + { + if (_CreateCommandConnection != null) + { + var cmd = _CreateCommandConnection.CreateCommand(); + cmd.Connection = null; + return cmd; + } + return new FbCommand(); + } + + protected override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + var rawPool = pool as FirebirdConnectionPool; + if (rawPool != null) rawPool.Return(conn, ex); + else pool.Return(conn); + } + + protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdConnectionPool.cs b/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdConnectionPool.cs new file mode 100644 index 00000000..8b0c930a --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdConnectionPool.cs @@ -0,0 +1,237 @@ +using FirebirdSql.Data.FirebirdClient; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace FreeSql.Firebird +{ + + class FirebirdConnectionPool : ObjectPool + { + + internal Action availableHandler; + internal Action unavailableHandler; + + public FirebirdConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) + { + this.availableHandler = availableHandler; + this.unavailableHandler = unavailableHandler; + var policy = new FirebirdConnectionPoolPolicy + { + _pool = this, + Name = name + }; + this.Policy = policy; + policy.ConnectionString = connectionString; + } + + public void Return(Object obj, Exception exception, bool isRecreate = false) + { + if (exception != null && exception is FbException) + { + try { if (obj.Value.Ping() == false) obj.Value.Open(); } catch { base.SetUnavailable(exception); } + } + base.Return(obj, isRecreate); + } + } + + class FirebirdConnectionPoolPolicy : IPolicy + { + + internal FirebirdConnectionPool _pool; + public string Name { get; set; } = "Firebird FbConnection 对象池"; + public int PoolSize { get; set; } = 100; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(20); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public bool IsAutoDisposeWithSystem { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + static ConcurrentDictionary dicConnStrIncr = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + private string _connectionString; + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value ?? ""; + + var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)"; + var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100; + var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => Math.Min(5, oldval + 1)); + PoolSize = poolsize + connStrIncr; + _connectionString = m.Success ? + Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) : + $"{_connectionString};Max pool size={PoolSize}"; + + pattern = @"Connection\s*LifeTime\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value)); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + var minPoolSize = 0; + pattern = @"Min\s*pool\s*size\s*=\s*(\d+)"; + m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase); + if (m.Success) + { + minPoolSize = int.Parse(m.Groups[1].Value); + _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase); + } + + FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize); + } + } + + public bool OnCheckAvailable(Object obj) + { + if (obj.Value.State == ConnectionState.Closed) obj.Value.Open(); + return obj.Value.Ping(true); + } + + public DbConnection OnCreate() + { + var conn = new FbConnection(_connectionString); + return conn; + } + + public void OnDestroy(DbConnection obj) + { + try { if (obj.State != ConnectionState.Closed) obj.Close(); } catch { } + try { FbConnection.ClearPool(obj as FbConnection); } catch { } + obj.Dispose(); + } + + public void OnGet(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) + { + + try + { + obj.Value.Open(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } + +#if net40 +#else + async public Task OnGetAsync(Object obj) + { + + if (_pool.IsAvailable) + { + if (obj.Value == null) + { + if (_pool.SetUnavailable(new Exception("连接字符串错误")) == true) + throw new Exception($"【{this.Name}】连接字符串错误,请检查。"); + return; + } + + if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) + { + + try + { + await obj.Value.OpenAsync(); + } + catch (Exception ex) + { + if (_pool.SetUnavailable(ex) == true) + throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}"); + } + } + } + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + //if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { } + } + + public void OnAvailable() + { + _pool.availableHandler?.Invoke(); + } + + public void OnUnavailable() + { + _pool.unavailableHandler?.Invoke(); + } + } + + static class DbConnectionExtensions + { + + static DbCommand PingCommand(DbConnection conn) + { + var cmd = conn.CreateCommand(); + cmd.CommandTimeout = 5; + cmd.CommandText = "select first 1 1 from rdb$database"; + return cmd; + } + public static bool Ping(this DbConnection that, bool isThrow = false) + { + try + { + PingCommand(that).ExecuteNonQuery(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } + +#if net40 +#else + async public static Task PingAsync(this DbConnection that, bool isThrow = false) + { + try + { + await PingCommand(that).ExecuteNonQueryAsync(); + return true; + } + catch + { + if (that.State != ConnectionState.Closed) try { that.Close(); } catch { } + if (isThrow) throw; + return false; + } + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs b/Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs new file mode 100644 index 00000000..49c12b1a --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs @@ -0,0 +1,273 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FirebirdSql.Data.FirebirdClient; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using FreeSql.DataAnnotations; + +namespace FreeSql.Firebird +{ + + class FirebirdCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + + public FirebirdCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(sbyte).FullName, CsToDb.New(FbDbType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(FbDbType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, CsToDb.New(FbDbType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(FbDbType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, CsToDb.New(FbDbType.Integer, "integer","integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(FbDbType.Integer, "integer", "integer", false, true, null) }, + { typeof(long).FullName, CsToDb.New(FbDbType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(FbDbType.BigInt, "bigint", "bigint", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(FbDbType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(byte?).FullName, CsToDb.New(FbDbType.SmallInt, "smallint", "smallint", false, true, null) }, + { typeof(ushort).FullName, CsToDb.New(FbDbType.Integer, "integer","integer NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(FbDbType.Integer, "integer", "integer", false, true, null) }, + { typeof(uint).FullName, CsToDb.New(FbDbType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(uint?).FullName, CsToDb.New(FbDbType.BigInt, "bigint", "bigint", false, true, null) }, + { typeof(ulong).FullName, CsToDb.New(FbDbType.Decimal, "decimal","decimal(18,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(FbDbType.Decimal, "decimal", "decimal(18,0)", false, true, null) }, + + { typeof(float).FullName, CsToDb.New(FbDbType.Float, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(FbDbType.Float, "float", "float", false, true, null) }, + { typeof(double).FullName, CsToDb.New(FbDbType.Double, "double precision","double precision NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(FbDbType.Double, "double precision", "double precision", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(FbDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(FbDbType.Numeric, "decimal", "decimal(10,2)", false, true, null) }, + + { typeof(string).FullName, CsToDb.New(FbDbType.VarChar, "varchar", "varchar(255)", false, null, "") }, + + { typeof(TimeSpan).FullName, CsToDb.New(FbDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(FbDbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(FbDbType.TimeStamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(FbDbType.TimeStamp, "timestamp", "timestamp", false, true, null) }, + + { typeof(bool).FullName, CsToDb.New(FbDbType.Boolean, "boolean","boolean NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(FbDbType.Boolean, "boolean","boolean", null, true, null) }, + { typeof(byte[]).FullName, CsToDb.New(FbDbType.Binary, "blob", "blob", false, null, new byte[0]) }, + + { typeof(Guid).FullName, CsToDb.New(FbDbType.Guid, "char(36)", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(FbDbType.Guid, "char(36)", "char(36)", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + var info = GetDbInfoNoneArray(type); + if (info == null) return null; + return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue); + //var isarray = type.FullName != "System.Byte[]" && type.IsArray; + //var elementType = isarray ? type.GetElementType() : type; + //var info = GetDbInfoNoneArray(elementType); + //if (info == null) return null; + //if (isarray == false) return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue); + //var dbtypefull = Regex.Replace(info.dbtypeFull, $@"{info.dbtype}(\s*\([^\)]+\))?", "$0[]").Replace(" NOT NULL", ""); + //return new DbInfoResult((int)(info.type | FbDbType.Array), $"{info.dbtype}[]", dbtypefull, null, Array.CreateInstance(elementType, 0)); + } + CsToDb GetDbInfoNoneArray(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc; + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(FbDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(FbDbType.Integer, "integer", $"integer{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return newItem; + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + var sb = new StringBuilder(); + + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移"); + if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个"); + var tbname = tb.DbName; + var tboldname = tb.DbOldName; //旧表名 + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = obj.tableName; + if (tbname != tbtmpname) + { + tbname = tbtmpname; + tboldname = null; + } + } + + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from rdb$relations where rdb$system_flag = 0 and trim(rdb$relation_name) = '{0}'", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format(" select 1 from rdb$relations where rdb$system_flag = 0 and trim(rdb$relation_name) = '{0}'", tboldname)) == null) + //旧表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName(tbname); + sb.Append("CREATE TABLE ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + var pkname = $"{tbname}_PKEY"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName(tbname)).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + continue; + } + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tboldname)).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname)).Append(";\r\n"); + } + else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = _commonUtils.FormatSql(@" +select +trim(a.rdb$field_name), +case + when b.rdb$field_sub_type = 2 then (select 'DECIMAL(' || rdb$field_precision || ',' || abs(rdb$field_scale) || ')' from rdb$types where b.rdb$field_sub_type = 2 and rdb$type = b.rdb$field_sub_type and rdb$field_name = 'RDB$FIELD_SUB_TYPE' rows 1) + when b.rdb$field_type = 14 then 'CHAR(' || b.rdb$character_length || ')' + when b.rdb$field_type = 37 then 'VARCHAR(' || b.rdb$character_length || ')' + when b.rdb$field_type = 8 then 'INTEGER' + when b.rdb$field_type = 16 then 'BIGINT' + when b.rdb$field_type = 27 then 'DOUBLE PRECISION' + when b.rdb$field_type = 7 then 'SMALLINT' + else + (select trim(rdb$type_name) from rdb$types where rdb$type = b.rdb$field_type and rdb$field_name = 'RDB$FIELD_TYPE' rows 1) || + coalesce((select ' SUB_TYPE ' || rdb$type from rdb$types where b.rdb$field_type = 261 and rdb$type = b.rdb$field_sub_type and rdb$field_name = 'RDB$FIELD_SUB_TYPE' rows 1),'') + end || trim(case when b.rdb$dimensions = 1 then '[]' else '' end), +case when a.rdb$null_flag = 1 then 0 else 1 end, +case when a.rdb$identity_type = 1 then 1 else 0 end, +a.rdb$description +from rdb$relation_fields a +inner join rdb$fields b on b.rdb$field_name = a.rdb$field_source +inner join rdb$relations d on d.rdb$relation_name = a.rdb$relation_name +where a.rdb$system_flag = 0 and trim(d.rdb$relation_name) = {0} +order by a.rdb$relation_name, a.rdb$field_position", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var a1 = string.Concat(a[1]); + if (a1 == "BLOB SUB_TYPE 0") a1 = "BLOB"; + return new + { + column = string.Concat(a[0]), + sqlType = a1, + is_nullable = string.Concat(a[2]) == "1", + is_identity = string.Concat(a[3]) == "1", + comment = string.Concat(a[4]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + var existsPrimary = _orm.Ado.ExecuteScalar(_commonUtils.FormatSql(@" select 1 from rdb$relation_constraints d where d.rdb$constraint_type = 'PRIMARY KEY' and trim(d.rdb$relation_name) = {0}", tbname)); + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + var isDbTypeChanged = tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false; + + if (isDbTypeChanged || + tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + { + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable && tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + sb.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(tbname)).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname)).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Replace("NOT NULL", "")); + if (tbcol.Attribute.IsIdentity == true && tbstructcol.is_identity == false) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + sb.Append(";\r\n"); + } + //if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + // sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname)).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(tbcol.Attribute.IsNullable ? " SET DEFAULT NULL" : $" SET DEFAULT {tbcol.DbDefaultValue}").Append(";\r\n"); + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) //修改列名 + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname)).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (isCommentChanged) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")).Append(";\r\n"); + continue; + } + //添加列 + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname)).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Replace("NOT NULL", "")); + if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sb.Append(" DEFAULT ").Append(tbcol.DbDefaultValue); + if (tbcol.Attribute.IsIdentity == true) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + if (tbcol.Attribute.DbType.Contains("NOT NULL")) sb.Append(" NOT NULL"); + sb.Append(";\r\n"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")).Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" +select +trim(c.rdb$field_name), +trim(d.rdb$index_name), +0, +case when d.rdb$unique_flag = 1 then 1 else 0 end +from rdb$indices d +inner join rdb$index_segments c on c.rdb$index_name = d.rdb$index_name +where d.rdb$index_type = 0 and trim(d.rdb$relation_name) = {0}", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var ukname = ReplaceIndexName(uk.Name, tbname); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sb.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname)).Append(";\r\n"); + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname)).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + } + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select trim(rdb$external_description) from rdb$relations where rdb$system_flag=0 and trim(rdb$relation_name) = {0}", tbname))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname)).Append(" COMMENT ").Append(" ").Append(_commonUtils.FormatSql("{0}", tb.Comment ?? "")).Append(";\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs b/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs new file mode 100644 index 00000000..07ffd201 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs @@ -0,0 +1,391 @@ +using FirebirdSql.Data.FirebirdClient; +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Firebird +{ + class FirebirdDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public FirebirdDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetFbDbType(column); + FbDbType GetFbDbType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + var isarray = dbtype.EndsWith("[]"); + if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); + FbDbType ret = FbDbType.VarChar; + switch (dbtype.ToLower().TrimStart('_')) + { + case "bigint": ret = FbDbType.BigInt; break; + case "blob": ret = FbDbType.Binary; break; + case "nchar": + case "char": + case "character": ret = FbDbType.Char; break; + case "date": ret = FbDbType.Date; break; + case "decimal": ret = FbDbType.Decimal; break; + case "double": + case "double precision": ret = FbDbType.Double; break; + case "float": ret = FbDbType.Float; break; + case "integer": + case "int": ret = FbDbType.Integer; break; + case "numeric": + case "numeric precision": ret = FbDbType.Numeric; break; + case "smallint": ret = FbDbType.SmallInt; break; + case "time": ret = FbDbType.Time; break; + case "timestamp": ret = FbDbType.TimeStamp; break; + case "varchar": + case "char varying": + case "character varying": ret = FbDbType.VarChar; break; + + case "text": ret = FbDbType.Text; break; + case "boolean": ret = FbDbType.Boolean; break; + case "char(36)": ret = FbDbType.Guid; break; + } + return isarray ? (ret | FbDbType.Array) : ret; + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)FbDbType.SmallInt, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)FbDbType.Integer, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)FbDbType.BigInt, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + { (int)FbDbType.Numeric, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)FbDbType.Float, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)FbDbType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)FbDbType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { (int)FbDbType.Char, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)FbDbType.VarChar, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)FbDbType.Text, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)FbDbType.TimeStamp, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)FbDbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)FbDbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + + { (int)FbDbType.Boolean, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + { (int)FbDbType.Binary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)FbDbType.Guid, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select trim(rdb$owner_name) from rdb$roles"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).Distinct().ToList(); + } + + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (ignoreCase) tbname = tbname.Select(a => a.ToUpper()).ToArray(); + var sql = $" select 1 from rdb$relations where rdb$system_flag=0 and {(ignoreCase ? "upper(trim(rdb$relation_name))" : "trim(rdb$relation_name)")} = {_commonUtils.FormatSql("{0}", tbname.Last())}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) + { + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (ignoreCase) tbname = tbname.Select(a => a.ToUpper()).ToArray(); + } + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = @" +select +trim(rdb$relation_name) as id, +trim(rdb$owner_name) as owner, +trim(rdb$relation_name) as name, +trim(rdb$external_description) as comment, +rdb$relation_type as type +from rdb$relations +where rdb$system_flag=0" + (tbname == null ? "" : $" and {(ignoreCase ? "upper(trim(rdb$relation_name))" : "trim(rdb$relation_name)")} = {_commonUtils.FormatSql("{0}", tbname.Last())}"); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + DbTableType type = DbTableType.TABLE; + switch (string.Concat(row[4])) + { + case "1": type = DbTableType.VIEW; break; + } + if (database?.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("trim(d.rdb$relation_name) in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = string.Format(@" +select +trim(d.rdb$relation_name), +trim(a.rdb$field_name), +case + when b.rdb$field_sub_type = 2 then 'DECIMAL' + when b.rdb$field_type = 14 then 'CHAR' + when b.rdb$field_type = 37 then 'VARCHAR' + when b.rdb$field_type = 8 then 'INTEGER' + when b.rdb$field_type = 16 then 'BIGINT' + when b.rdb$field_type = 27 then 'DOUBLE PRECISION' + when b.rdb$field_type = 7 then 'SMALLINT' + else + (select trim(rdb$type_name) from rdb$types where rdb$type = b.rdb$field_type and rdb$field_name = 'RDB$FIELD_TYPE' rows 1) || + coalesce((select ' SUB_TYPE ' || rdb$type from rdb$types where b.rdb$field_type = 261 and rdb$type = b.rdb$field_sub_type and rdb$field_name = 'RDB$FIELD_SUB_TYPE' rows 1),'') + end || trim(case when b.rdb$dimensions = 1 then '[]' else '' end), +b.rdb$character_length, +case + when b.rdb$field_sub_type = 2 then (select 'DECIMAL(' || rdb$field_precision || ',' || abs(rdb$field_scale) || ')' from rdb$types where b.rdb$field_sub_type = 2 and rdb$type = b.rdb$field_sub_type and rdb$field_name = 'RDB$FIELD_SUB_TYPE' rows 1) + when b.rdb$field_type = 14 then 'CHAR(' || b.rdb$character_length || ')' + when b.rdb$field_type = 37 then 'VARCHAR(' || b.rdb$character_length || ')' + when b.rdb$field_type = 8 then 'INTEGER' + when b.rdb$field_type = 16 then 'BIGINT' + when b.rdb$field_type = 27 then 'DOUBLE PRECISION' + when b.rdb$field_type = 7 then 'SMALLINT' + else + (select trim(rdb$type_name) from rdb$types where rdb$type = b.rdb$field_type and rdb$field_name = 'RDB$FIELD_TYPE' rows 1) || + coalesce((select ' SUB_TYPE ' || rdb$type from rdb$types where b.rdb$field_type = 261 and rdb$type = b.rdb$field_sub_type and rdb$field_name = 'RDB$FIELD_SUB_TYPE' rows 1),'') + end || trim(case when b.rdb$dimensions = 1 then '[]' else '' end), +case when a.rdb$null_flag = 1 then 0 else 1 end, +case when a.rdb$identity_type = 1 then 1 else 0 end, +a.rdb$description, +a.rdb$default_value +from rdb$relation_fields a +inner join rdb$fields b on b.rdb$field_name = a.rdb$field_source +inner join rdb$relations d on d.rdb$relation_name = a.rdb$relation_name +where a.rdb$system_flag = 0 and {0} +order by a.rdb$relation_name, a.rdb$field_position +", loc8); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var position = 0; + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]).Trim(); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]).Trim(); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); + if (max_length == 0) max_length = -1; + if (database?.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Coment = comment, + DefaultValue = defaultValue, + Position = ++position + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } + + sql = string.Format(@" +select +trim(d.rdb$relation_name), +trim(c.rdb$field_name), +trim(d.rdb$index_name), +case when d.rdb$unique_flag = 1 then 1 else 0 end, +case when exists(select first 1 1 from rdb$relation_constraints where rdb$index_name = d.rdb$index_name and rdb$constraint_type = 'PRIMARY KEY') then 1 else 0 end, +0, +0 +from rdb$indices d +inner join rdb$index_segments c on c.rdb$index_name = d.rdb$index_name +where {0}", loc8); + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + bool is_desc = string.Concat(row[6]) == "1"; + if (database?.Length == 1) + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs new file mode 100644 index 00000000..02e20989 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs @@ -0,0 +1,472 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Firebird +{ + class FirebirdExpression : CommonExpression + { + + public FirebirdExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Char": return $"substring(cast({getExp(operandExp)} as varchar(10)) from 1 for 1)"; + case "System.DateTime": return $"cast({getExp(operandExp)} as timestamp)"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(18,6))"; + case "System.Double": return $"cast({getExp(operandExp)} as decimal(18,10))"; + case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Int32": return $"cast({getExp(operandExp)} as integer)"; + case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; + case "System.SByte": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; + case "System.String": return $"cast({getExp(operandExp)} as blob sub_type 1)"; + case "System.UInt16": return $"cast({getExp(operandExp)} as integer)"; + case "System.UInt32": return $"cast({getExp(operandExp)} as bigint)"; + case "System.UInt64": return $"cast({getExp(operandExp)} as decimal(21,0))"; + case "System.Guid": return $"substring(cast({getExp(operandExp)} as char) from 1 for 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as varchar(10)) from 1 for 1)"; + case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as timestamp)"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,6))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,10))"; + case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Int32": return $"cast({getExp(callExp.Arguments[0])} as integer)"; + case "System.Int64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; + case "System.String": return $"cast({getExp(callExp.Arguments[0])} as blob sub_type 1)"; + case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as integer)"; + case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,0))"; + case "System.Guid": return $"substring(cast({getExp(callExp.Arguments[0])} as char) from 1 for 36)"; + } + return null; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as integer)"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "rand()"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + if (argIndex >= callExp.Arguments.Count) break; + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = tsc.SetDbParamsReturnOld(null); + var left = objExp == null ? null : getExp(objExp); + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + tsc.SetDbParamsReturnOld(oldDbParams); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "current_date"; + case "MinValue": return "timestamp '0001/1/1 0:00:00'"; + case "MaxValue": return "timestamp'9999/12/31 23:59:59'"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"cast(extract(year from {left}) || '-' || extract(month from {left}) || '-' || extract(day from {left}) as timestamp)"; + case "TimeOfDay": return $"datediff(second from cast(extract(year from {left}) || '-' || extract(month from {left}) || '-' || extract(day from {left}) as timestamp) to {left})"; + case "DayOfWeek": return $"extract(weekday from {left})"; + case "Day": return $"extract(day from {left})"; + case "DayOfYear": return $"datediff(day from {left} to cast(extract(year from {left}) || '-' || extract(month from {left}) || '-' || extract(day from {left}) as timestamp))"; + case "Month": return $"extract(month from {left})"; + case "Year": return $"extract(year from {left})"; + case "Hour": return $"extract(hour from {left})"; + case "Minute": return $"extract(minute from {left})"; + case "Second": return $"extract(second from {left})"; + case "Millisecond": return $"extract(millisecond from {left})"; + case "Ticks": return $"(extract(second from {left})*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685.477580"; //秒 Ticks / 1000,000,0 + case "MaxValue": return "922337203685.477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{60 * 60 * 24})"; + case "Hours": return $"mod(({left})/{60 * 60},24)"; + case "Milliseconds": return $"(cast({left} as bigint)*1000)"; + case "Minutes": return $"mod(({left})/60,60)"; + case "Seconds": return $"mod({left},60)"; + case "Ticks": return $"(cast({left} as bigint)*10000000)"; + case "TotalDays": return $"(({left})/{60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{60 * 60})"; + case "TotalMilliseconds": return $"(cast({left} as bigint)*1000)"; + case "TotalMinutes": return $"(({left})/60)"; + case "TotalSeconds": return $"({left})"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or trim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception($"未实现函数表达式 {exp} 解析,参数 {exp.Arguments[0]} 必须为常量"); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"({args0Value})||'%'")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"'%'||({args0Value})")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) CONTAINING {args0Value}"; + return $"({left}) CONTAINING ({args0Value})"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substring({left} from {substrArgs1})"; + return $"substring({left} from {substrArgs1} for {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(position({indexOfFindStr}, {left}, {locateArgs1})-1)"; + } + return $"(position({indexOfFindStr}, {left})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"trim(leading from {left})"; + if (exp.Method.Name == "TrimEnd") return $"trim(trailing from {left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim({getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"trim(leading {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {getExp(argsTrim01)} from {left})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"extract(day from dateadd(-1 day to dateadd(1 month to cast({getExp(exp.Arguments[0])}||'-'||{getExp(exp.Arguments[1])}||'-01' as date))))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0"; + + case "Parse": return $"cast({getExp(exp.Arguments[0])} as timestamp)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as timestamp)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"dateadd({args1} second to {left})"; + case "AddDays": return $"dateadd({args1} day to {left})"; + case "AddHours": return $"dateadd({args1} hour to {left})"; + case "AddMilliseconds": return $"dateadd(({args1})/1000 second to {left})"; + case "AddMinutes": return $"dateadd({args1} minute to {left})"; + case "AddMonths": return $"dateadd({args1} month to {left})"; + case "AddSeconds": return $"dateadd({args1} second to {left})"; + case "AddTicks": return $"dateadd(({args1})/10000000 second to {left})"; + case "AddYears": return $"dateadd({args1} year to {left})"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"datediff(second from {left} to {args1})"; + case "System.TimeSpan": return $"dateadd(({args1})*-1 second to {left})"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"datediff(second from {left} to {args1})"; + case "ToString": return exp.Arguments.Count == 0 ? $"cast({left} as varchar(50))" : null; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])}))"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"cast({left} as varchar(50))"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as varchar(10)) from 1 for 1)"; + case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as timestamp)"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(18,6))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(18,10))"; + case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToInt32": return $"cast({getExp(exp.Arguments[0])} as integer)"; + case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; + case "ToString": return $"cast({getExp(exp.Arguments[0])} as blob sub_type 1)"; + case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as integer)"; + case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as decimal(18,0))"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdExtensions.cs b/Providers/FreeSql.Provider.Firebird/FirebirdExtensions.cs new file mode 100644 index 00000000..6caeeb89 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FirebirdExtensions.cs @@ -0,0 +1,15 @@ +using FreeSql; +using FreeSql.Firebird.Curd; +using System; + +public static partial class FreeSqlFirebirdGlobalExtensions +{ + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + public static string FormatFirebird(this string that, params object[] args) => _firebirdAdo.Addslashes(that, args); + static FreeSql.Firebird.FirebirdAdo _firebirdAdo = new FreeSql.Firebird.FirebirdAdo(); +} diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs b/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs new file mode 100644 index 00000000..a70f3b91 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs @@ -0,0 +1,62 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using FreeSql.Firebird.Curd; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq.Expressions; +using System.Threading; + +namespace FreeSql.Firebird +{ + + public class FirebirdProvider : IFreeSql + { + + public ISelect Select() where T1 : class => new FirebirdSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new FirebirdSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new FirebirdInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => new FirebirdUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new FirebirdUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new FirebirdDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new FirebirdDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => new FirebirdInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public IAdo Ado { get; } + public IAop Aop { get; } + public ICodeFirst CodeFirst { get; } + public IDbFirst DbFirst { get; } + public FirebirdProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new FirebirdUtils(this); + this.InternalCommonExpression = new FirebirdExpression(this.InternalCommonUtils); + + this.Ado = new FirebirdAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new FirebirdDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new FirebirdCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + internal CommonUtils InternalCommonUtils { get; } + internal CommonExpression InternalCommonExpression { get; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + + ~FirebirdProvider() => this.Dispose(); + int _disposeCounter; + public void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + (this.Ado as AdoProvider)?.Dispose(); + } + } +} diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs b/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs new file mode 100644 index 00000000..98a9cb76 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs @@ -0,0 +1,98 @@ +using FirebirdSql.Data.FirebirdClient; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Globalization; + +namespace FreeSql.Firebird +{ + + class FirebirdUtils : CommonUtils + { + public FirebirdUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var ret = new FbParameter { ParameterName = QuoteParamterName(parameterName), Value = value }; + var dbtype = (FbDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + if (col != null) + { + var dbtype2 = (FbDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText, DbTypeTextFull = col.Attribute.DbType, MaxLength = col.DbSize }); + switch (dbtype2) + { + case FbDbType.Binary: + break; + default: + dbtype = dbtype2; + if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; + } + } + ret.FbDbType = dbtype; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => + { + var ret = new FbParameter { ParameterName = $"@{name}", Value = value }; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.FbDbType = (FbDbType)tp.Value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatFirebird(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 1); + public override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; + public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left},{right})"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left}/{right})"; + public override string Now => "current_timestamp"; + public override string NowUtc => "current_timestamp"; + + public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; + public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + if (type == typeof(byte[])) return $"x'{CommonUtils.BytesSqlRaw(value as byte[])}'"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj new file mode 100644 index 00000000..c6642849 --- /dev/null +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -0,0 +1,36 @@ + + + + netstandard2.0;net452 + 1.9.0-preview0906 + true + ncc;YeXiangQin + FreeSql 数据库实现,基于 Firebird + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + true + key.snk + false + + + + + + + + + + + + + + + diff --git a/Providers/FreeSql.Provider.Firebird/key.snk b/Providers/FreeSql.Provider.Firebird/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..e79b743ef689402c29a35ed40cf1cd626e191cf4 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098mlQtd#DKxkU(coL?g6M=pQRIc+v_Qiy zOp;kcE<10_leO93Qy(34{x16yxc?0Oux7d@A_Pf14CV}k5%xf9&hjoce)}KBM)7d{ zkcC4~?S1TXEiowbW-8o{D%+JTd%igWNT9x5Bunh3eyC267IF)x2M8LqpPuFxWJ%C> zXRa&N$R%$We)Bh^n-y1%^RrxSr2|R>x4b#7XhRE|2Z>?}<-^l%xw#RC?xkzW8V0Zx zgt2{y|LjeTh{4}4Qwmj$#lwVdjlipD-1($Zr1|dD`wHGrX2=?^RlS(e-x5Bb(K73y z#I9J^%|#5cEco5&dD|8EN-r?@FHP=45}?Zv1Zc8V55EkD)gs*!c|ntt&1zl%hbe;Y zlPF9*q9b|E^aNEX0Z|yR#CjXo&&4@>mLlJuc95;yA!JBpLN!kjqpo}|yT(tA@aEz+ zJyi>KQ$KNltr?CWRA<&5{2Ic`AV;ZJ(ud-gSS5UoQ(h8aZk+vBs4%@lP<4n0G5R^w_d9cG%~ z({>#4-O9XuAGb~VYL@;6Hw@#MLzz?X9`awlgW5{_hvKA}Z6KwKB&bm5r}COiGm(%T zOkfLfZ?`-OGxy3NR<$o9zDX7oQmOn(nwcMCNccm!Xze09D&E?TROk1?OZ@^bd`gJy i8(9;r){w?;g!M2Hq2gMgJtdf3ag_7{BPMm"); + break; + + + + + static Lazy firebirdLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Firebird, @"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5") + //.UseConnectionFactory(FreeSql.DataType.Firebird, () => new FirebirdSql.Data.FirebirdClient.FbConnection(@"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5")) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build()); + public static IFreeSql firebird => firebirdLazy.Value; \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 45cd3dda..69d6c835 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -215,7 +215,6 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); foreach (var tbcol in tb.ColumnsByPosition) { - var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { diff --git a/readme.md b/readme.md index df42d9cf..59867ec7 100644 --- a/readme.md +++ b/readme.md @@ -10,7 +10,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 丰富的表达式函数,以及灵活的自定义解析; - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; - [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; -- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access; +- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access; ## 📚  Documentation From 37a1ea6489286488eb2d59c469d5c21e11ac09ac Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 12 Sep 2020 05:49:42 +0800 Subject: [PATCH 0887/1029] v1.9.0-preview0912 #443 #456 #454 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 38 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index e7067ad5..fe83a839 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index ad55ff30..b857487a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ef415431..16204fc6 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 16f46017..304f74c6 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 2bdcb72a..1046f241 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0906 + 1.9.0-preview0912 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 38a9fee5..06df65b7 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ac4f50df..9c46c676 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5ab549d2..a22a9bd5 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0a85eb15..68a2a1a3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 69f7ce11..5333d2a2 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index c6642849..1f61b4eb 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0-preview0906 + 1.9.0-preview0912 true ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 82b8bdac..f1dcaeff 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 6e6eeaf0..4c1d3d40 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 25bd1a44..aa4ecb7f 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4e8322d1..8cef6bbe 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 697a263e..83ae1417 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d32c69f7..ecdecb32 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 690a878a..39c62ae0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index ecc482d0..b29b5226 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cc895138..82a55f1e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 7e81b0b6..218cb892 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 0e362aba..9bacf2a2 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0906 + 1.9.0-preview0912 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 06909cb428cccc757a28175471fe41fcecba7119 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 12 Sep 2020 06:06:51 +0800 Subject: [PATCH 0888/1029] update readme --- Examples/restful/001.png | Bin 0 -> 16194 bytes Examples/restful/002.png | Bin 0 -> 16547 bytes Examples/restful/003.png | Bin 0 -> 17138 bytes Examples/restful/004.png | Bin 0 -> 16922 bytes functions10.png | Bin 130769 -> 0 bytes functions11.png | Bin 0 -> 119324 bytes readme.md | 10 +++++----- 7 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 Examples/restful/001.png create mode 100644 Examples/restful/002.png create mode 100644 Examples/restful/003.png create mode 100644 Examples/restful/004.png delete mode 100644 functions10.png create mode 100644 functions11.png diff --git a/Examples/restful/001.png b/Examples/restful/001.png new file mode 100644 index 0000000000000000000000000000000000000000..a32288c1de19448ece623ce918aaa5e98494fa85 GIT binary patch literal 16194 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 Js-#SU{|7RRtf2q^ literal 0 HcmV?d00001 diff --git a/Examples/restful/002.png b/Examples/restful/002.png new file mode 100644 index 0000000000000000000000000000000000000000..43b8a9367f968260be6500f576abff6165640201 GIT binary patch literal 16547 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 literal 0 HcmV?d00001 diff --git a/Examples/restful/003.png b/Examples/restful/003.png new file mode 100644 index 0000000000000000000000000000000000000000..32cf27bdf7a5365241ec6fd4af0e2bb553a34ff3 GIT binary patch literal 17138 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 z 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 D)O%v6 literal 0 HcmV?d00001 diff --git a/functions10.png b/functions10.png deleted file mode 100644 index 5e3f623d7453a53d3a728dca8d52629b8413c64a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130769 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

r}auhs) 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 SO`bd7jjPlQ@Uoa?Zu;G9UdZ;zMa?+#}Q z8M|Isd|&{Onf4iUBVPw-VxL!8FmB+%4c!f_X;Z&0`4b`~!qm@Es})JkwpNWU%^~oi z(w)lE093lfjA%j%*heV6Cq~t=1iZaXpfJ8G5$9d+go_x~thJoKTDXra zOMTcr#(%YXAQHXq^95Z5?Q4gzs%qK|;Qoo@Q1T3W`L6OTGC!svWS6YP+AB)hauXCABDwcwc+jcxi3;w zj1+!Ci03IZ+9s9UkD3ck^wFW__? z`F|8sTL9^`&<3f{Mpegcheb0mm_JycX(~0|TdiNKPk%RK)2IYjBg~d=$?V*B2Yw}F z@};u!^6<$2OdL(*{Ql%Le1O&;XH%vzcDdA+AHH2%YrKzUkkda7$e3AXF@@!3B~(@M0{Otciv!+c1@Q?3Too z@q$7>5OpT!<`NNwJ^_7{9z)bM0rQMBnJAPgrV$?LA%{Rsj}3G(bs)0KxD_AY9s&OJ ze=+vfK|z0Cx3C~7-5}l4NJ)c$w1{+iG5EPV{s9;?Dg*(CH$r0qmsVpfEQDMw!`Zi(BZ9OzkO-d(!~I{A_4Ti;5R-n# zVbapiW{*Q9n3~F$&(-S+e#@nTOd7(^&tE!Ef=a%2(hkwj>4lKJR`H7?i~_PwSkS_O`63WO9oHa0p8+iGlHHRj4JX_k;yp+s=) zv|<7^kpavU$UU$|z`R~UT2FkQb7FOtagqNJlOKINDH)>0=ugU^N5VRY$$ydE4S06o z{{(+PyXhP9@8P@cDDkgBEFRg_0%m(}jyT!{>Rg$Kanex3IW|Lxl$T$Pmp0#nGDG6+Y&{7%O(=gc$dKnb>f%?M$Nl%8hft?g|C;63HOS@_ zWzCd-+kRvq9?p zWO&>yAc6>D>_g3!0#6?Immf5tTE0H%f(NEWJ(8Dn>g|!JOp?dN@JknOP@*}7!wBzd zsNh@WmDZG%@6GmCR9{1}E$ICoglcsd*$(-v4+oTOd>#)q_?>b2j3*TiG4HxceiQRY zCnO{!2eEu%^X^5=Q5PXmhT9y8Ry28jTK!`oAp2QH5LG&^dw53j(}dj0ly*eu69+@# z$w_X*ymb42r5b9`yL6p3{s&=NCUzCGNEOu2%Mv9c>`~N|mrwW1Z9z zKFBlY8r`_JOd*ed6KHd7OK~;UC=BfTA6?~4AmuJhz-*e%H|Eve- znIJZlb2iIlNwK|lOu0DBar;EHrH27&e{Br_G_MJ{$Et+sX4O>iu*CtOX_pgf?_@Xj z0nJ}%?LUeOnwz^$#{f;Y!+zo`{WKE*!Cod0*HhBtzVdsw58>VM;>?K}MHpP%Yhc3C zM?vBI|NZtbJm*w@RF6My`^*mM2VEU?g#XAVjM>0l_}cBQj!m>BH@}zF1}t~}V9$0( z9~j25Aaz_XUFh>2Cr8^xV!SStJYO0}H+Xr=#pV@ueNLa_Q@ft!Q;_JBos&aJoht|@ z^vGE3dX=^J9B$BAz5sBGRE@uEdXHM0n7I~IraCT5(l^vG0KLwi8*tt%#mh@^~c)BdIw{Nqg`ycKw|TQ zNr>w5=}F4AwxXu-Z}g*eZr?-M#)HGC?*4_b%YXJGNVs})Rf0^V zFx4k3hAvd1)ub*SA?fa%&{XrlS7VH3ROEHqLXF5Z;(Ut=x4^0hKPEK?X>KXsA zd{Hv>{(m%I)kc+wXP&QooqfMs>~iD&@3$*~yv~?Nsd7u$d_Y~}J!kVjJl~4+)_BKj_&5X(Iw2#gh&d;#JnmR%qNqTo+~(OGm*EvPMYc0@h& zlC%xX_C?yQm`uu-3J`xUP;XEJ83ak;hiq!@i>0cvd~ZVANaQmUP$)JOTfVPsQ1`d? zhRj&{EQ^J`9EC^H9n-~0(x>TNd;!?gi)4b?EVd!M#UL#C_o4&Gn8=GYACo=E)g{R< zE*i9V!As*(AKNdnD4xu;M~BDSh-!38Nc2lAe!ss@FHYb9VicTq%aV69w1b#sLlHO63+X@#wE>e~uCxk;yohhqw* zAj)iP;H_4u+Sulso_0aZU{&7rFYPv7=#kCntwCg@oKo>hz`Gi^KzWY<+_3SwJ*HErdhCqBcnoT8es-3P^S4W zn&%#imZhs?t^rBlGR_3gkr_4DB~#h@o_5fVCHJU#GW(XG0roUpf@T9?Xy;(}4nHDPySKN~r$~ zO6LV+W4Rx_4IQxzw;@wX?!XI#kPttM(drMQ-4?pNyvzXk^%%yWKnCDvoIccsSX-MdhBS;o%k>F)V{+LkKzYM^%ewJ6oZcC*t(TwF%t zJ(36J_3C!8(DpIl4}dI3AP9=a&j7OU{$l2X*@$$tUqaST9DZl%YNkJEYb=^z0BqTrY`>y|dD1(V9Fm%&l3?d`>*Uw3Z zJoXdr`8rd_*NuTE-&dIeJQe+4dJ=;jg$R-Tu?v}9G>qp*Ga!sItE|<)SG@%+(rw?j z+kA}5^o)4PRSnRY2K_~p71Td;qPZ$Dget%~feSLKAzFRYL=&9dwyCXm2s_I%sT2i) z9YxS{Y&FPCoOU)+etF^Vb@}W}Z4?)?d3{7LraHT9taP}B9_ih*s0HTiT>N%RU#IXr z@VW&rvuNawLq|NKsg?!<`l_l1B$Yjlu$MM9IRn_+{$zMX$m#uO26)vmh!FM935luz z0}=YSf(Hy~_`Sf^%v!>)dv?>c;yI@Ii>5;}&HvHyH~Cycs3DVhwfK!7-(Ae=H0q z2?aY}N7~i)$Wy)S4@~cN$0-)u;Z6_qL8$UcC%Q$m?zM!muAd1HIAV7F!4>7&CN2bq z%q##&)8N$FKw0okLp|dmBU!G^&wq&(*$*u_Z_Z_R&TL3V>Y$7vANXO-G|m(XGVo^& zlTuJnP&eNBjW55iU9}4mbWq}2Hpg<(I|Di>ri5|xr*O8Bjc32UC1{BeUS4I3Df;cBNQx(Y6;{h9 zk1R`xD={ispy&CpwXLD4kRy$SG{DmAfcx3c5rraAZp;$7gn+QKiG3<(F zS&Eletm6x06M6rLE7(6Ld=hdofagE>f*>L(8T^N;-p{zC6ylVYCc0)c*_4tol!*2= zn2IVr!x|DRa{Kgza&gxh_hY-Y@(Gr@P%51y3sGd0Fi1+czE|=QhzM?rm4swE)6Xu@ zL62BJaDl?VK<2;wv4V(C!p)FdjqL}T=Gtk5;?3&Yv@}tMPO*^hZ=ihD=A0~3)hU3{ z!Tz4qzuOIQyB>X|p$nPQuupCOQLlK&;Y-##u!*q6yk51bFOp{?0cHbcmaJU&2y=Rc30{QipeG8dQ@#xPF>^+lkMz9vRaf0Us2Cn&{ zy^~QAi|4OSNA>7H(znfS4EA^}O$mCPI_@b|O@RUPmbD0a0jB9~c_eYBVZeE#8c+>> z3)v6F@E8)W1+E3Yg7B}}Sx9dDYrH&os+)`se+e3wVj!sTP(~pEJ{89SfvYA_*oiVf zP8N#lHf6OQBTbP$9cWnwOZN3LM!STc-QZ$p`EmW`KegUtDnXLSXv3@HatEQHoY zJ&p1ptEMGZ_u<%fFZE#fmJ*(@1N|==&jav8S*D; zY>##sn#a$3tWDfYw?Ab&5>bYG5>$`pcQvZZR83Z6yNd8BSet4d_L?&g+~puDeypiF zeriYNirRCt_nPNa1gYMG*W2@RXyX0jEyHz3Vva`zx{-3NTQ zw5n2SPA_p1tTJycO8_F(U{z)fl$&U@&{*wz_mmvpAJ9eT*OX7445B`B`;ifTrBy1G zw8KPR#gzMZ{R`qIzn`r$3Y>H>T~h5qUS;q}Ed&rD11+M_K)vMzMIfkEs2RrUXC%&j zU5Tiy(Z9TKYc3yX0wMvAGR=`T>JcqbYD;LRTf?2@4#4}luQQyFk(?{HrOOW~2GIKh zl_kV4>3qbcCUq*;OYEnbSC+6r?YRBEKPG&8Zdmh@-@)gBfSFaZidnq4P?axcbS>|(fE%FPi?ZYz7SOeU%I3hZvHO$8{Np-vXVLUuD z4Br}SYt(y`9z2tr*9R#%R=1O3zgjI4aqG4EBDhh95wU$)4t@}mv9TMfgix2FHIO>M z6$%idiX1(WCqA;40AbdpX&-*%>Jm9Mz99K0WN{>BEdhGQF_g}N`qOUtj#j#li4}tY zxcGgYH(mLJg7HgqaeAiwM!jSqj^u@;+L zH?B|LYu7bImsXXTEEU-RFR%J=KK1;V5M~w=Jh{YrfX?!fxdk9zJQ~zo<5wT9Z6}Z` z8=3{BltZ_~IA+6fA$NyTAWj~QGUQY!tDsF-agYH+ZfC=yZ`Y3 zk}13IfR0|F7zZrJB{8#JKTs~b%J5MACFl02Iti!|t`UZ&Lf|qe;!oG0AnpGmLNnqS zZkv=ae=JT6OqMUKKp3|w5%AEvX~nRW#5=8 z{&GLC)X(TAqT6_WoQJ(s2Ksw|jX+JEYt6Sk#hh0RjS2cciQtkihlgrOTc^Ir|CvL0 za9ysRot`lZ^=rWC2Pe}7#1$Lh>?eOolOhK?ZoTxzMuj1$Ka&%I8tT@zkOgACxDd8z z-n|3*M+COHkCA%7>{YPA2~B_CGH!X!>>W7v7UXRrgQUndRo#o1SA>h4|vZy=bkB)&P|<2bGUD*0V4G3kSISWtUoqu&2%1l!0)_h4FS`jnQM zk}@+)U=}1-AI>|~eyoA8cA;$ki2kvz@rn8MpBVQ*6~MIH)FR@vy#*}#MIj-oEK)8E zhz?Z$C+gLmzKVEAG3ZE;iS&bpe$~1wfq{O+?y8$`w-JC}QinkG^mqpkA+^QXe|XWw zL=Az-Ri<@=Bx?9d1<^YaQk#{$x-i>hMVtX#uejJj>5VlojQ830Rvd=&=T> z8hH}FU+`tcDh(a9Ma|t*I3t+>wa0#cw(Zpi{;{Zm@ng%pZxtt_HcCe@7*;1X>`hG6YC;^pP;Ner@sb%sy4$@07wFeD%Uvytw#`H z_o57t?XWeFRLocK+-}6W5rO_XQ{o}UVUBcHIn~1f9VND#)9BV>ew71cK|x*8)q_(Y zxn;7z0tc_-DmN;ww`svZcu`f$C+&pTjkg>*GVyYyMqnfW#cIbz;qI6a471!z(F_u9SODrdl zcDvh_xxaCB3X2>#3nU`-Uco{nt2-Tu1yiB3N0bC*4S{MpgoKB4ULdPJiT`W%N^C0W zJ+71Q%Y#3P#ZVWaOAkdJ7oZA-TNJ(b84yF0i)HcDS%xKjUZBY7qcSQ$qUJfAg9{6GU=~&G7#mCY#2^ zA`CJopZ#DVq_fX^xoZ!F3bZrz2QNOgtO8c_a5BehJaY3_h^&*eoihts>^?o865r{K zD&Ksg3O8Jjm8-@s{9|dXj$qw*&sQmG{}h&0mmS;hCo7$!7SNY%_4fPCCB52fB5WL< zawW6HIzF4u)nA-Amm%t6*N+WQFo=(8@mgC0uGln(gYzsju{Ul#+7ELfGtB5;SCz?* z;fhG0$VB-()w*(dsqy9#Yd0yZ7CcJLkCX;ag;7}+jp2V`%xR{+GKhHDJ)hTf_IbnW zJ$WwUgBf|oD^(jp$ALV7wf1#_#G56Z?HG9m2M(M=#^bIqiW%%4zt>h? z*mv*Cl`2|YVSl8Q?8_sg1#m^qo&7WfX_IR_WeC`n6HzZ3%w}t}-5*T`GINKS9`3Y7 z7#`nRur;TR5tz&pHJeFQp?mU8I;??Vxs*-9TC^#>8_`DT(4*LUel#Ql9`wJot^`-0 zWRLjL-C&0jPEL*YW~P1CVQ3+k6lpVq_<{1ya>=miryMFz3~pB`c`gyGTMP6*i-YbO z2^$QBV*Fd^x%{h#ffGBw)}`$_vDMU#Zr?36rzI=rM{_k3HnT#PpatTP zC!t%GWUI23_Ghy`V6#v$Hq0%ilxlY2NxkQ_YD<28^*0ss;Bx(ZOTJ9m#NhRwRct|J1M_~ zsloOkhKkC5SnCo8rqS&;QCk?`T)$}_K%F44`j&#IjxesM>nCaU3Q39LrNwpoFF$WO z{regdJRa7thawQ>81MuYQp$gio^9Dt3C&k!s_TpnYgWUMrm6LAVusW?TKB%=qZ&~= zU)8Prml(B3Yh4udFw%ghaO}`}!wWwX=K0dLZka#A6Uc+jRBVxOxX-w*D2&Vi8iYKB z*Vm3yrugHrkD|-?kZ`)jl*Rp*ADAZEN}RMO-Dev3b z*>&c0P#@+jeN!<+ihnDT(un`N%Q9~sgaB1IdEhzzP3Qei!cZ3-2QuF4`RWfOgRG7? zq(0;=2NQXgL(MCn-l#Q`?l%JB*Wr<3aN+>_=-#d@>dT~oX|Zi1kpJUm|LE6XmL+;= zyC&47mYdK0C$};C!(SC_u1e&(*s8n)j><+UQ;m*xJ{4!-$e2I2(?i5sq~a;=FCBEn!d^u_NW-**s? z+`lM-O>G2u#dl6!=9Vv7l3*x)A5Fnq9W$D>3T^yu4M*6U!n5+s{k&kUTh@-dS6J{8 zT6GKYScRcPD8Sf1`m)aTi7AQUr>8np&m>?=<4+Z`?>F%09SRssk4w#1+8Zy~FQPo4 z1_pf~{vZ&4zpy^U^Hiu+H$JON%2|^s_;^1o^PST#)4PS(oFNByruD5cM$U*B7e-Xl z(Ny-4fco`d3NKlrb})$RlnL*n`M$GXMC|e)`;3&-6N{!zsFl1KP*X6 zAsO=O5r$wpdS0(T&GDd|<^}%>!;tjyLv=+U^?Mzzl`XORQLt4A>(5IidY$(qv}E6W zGTgt7L!)7SNbnNOdoKw`xJQX9zDo)3M-kAJfoq!hh#CSI25Jd{4D` zT(>hAzo1@y@@FscQzwVO#m^76OExQmD)pu>S3{k@yjaKW33XPi6OfgLioQc3ep=xP z5HmTgMLu4^Fx_b7mM6>#pbz&Vf*Wnf4pdA-29>_z$TJGNgwqNxI#|#6aE_1a@r^XI&a*pZbczFSY3PZur zS~9!6Tyh{hq9os6pmL8(#B!zGW?T?0c#f+XfvjHK+KO<%}(aoF8Jc#D@^G zI&f|sZKLnCWe%1qFlfIfUa@~y5=NxX;Dc?Pwdf1JVnX!%dZukg&ZyZ`y{s^YNHI5{6U0Q!dochuP{l=CBa@;7In@Lzm=rjBUkHd^o|J)1c zgT92xZR|&7%ZPSMIy~R7(-zOB`qfcZ{XXrpk!^2}`i_N{GkQb&ind$*{uWm0cRz0a z#8{r$dnl~iizKx|Fd?xOZk{x_xBbps!FOGg!_45rciR2^`?grz!sq@m`hI})9OJ0z zm2=~0@dHLK>5<^d{L!OI+3~?Av2VB^l8QLrC=!1wMw6AugRoeOSSWSCxi^6mUBWHL z-&ilI{z%%uQ}vc$l1i-8#GJh_`%;e9ZvC>Zw)SqM+6o^2G_(rE{M>5Sa}0rqYttse z2>zR7abF6z8&QnK48F(&Q7AfzndXkD4JXqH z0@#F)kGlNJ<&Qs6v@i^2DXz?vd+<}rGO0&Ad5`acAGb!E!)szWeTjyGv1t_Y(qaz_ z)w~Gv5`gNoi>vcDM$|+mZLRn=biK^XFDENM0!=C{FOWqpbpxli%--!!7Znh+SH{Xx z@$=iXMJhTEbf0bqA!2uhU`0gt`|RtJ!q#bR>W5&_C}hdbn=JJo=NK>$(#NfJ*vn3b z3mU?YF80&Et)_-RFJ*^d5Jqq%aUCrnV%SosYE+*KrBFcDRj4+nNRO}%e1Z!pR56+; z)(F6Ke0xV|Oc&e1Aq9 z=Xx{xwj;1zJ-g@~?Op7}*%b{mAevK{OZc2oNoOY39P9JOjf&@-XXdL|Suqh*2kf?) zD&7nKCafbQoG7(K;%p9eT?+c{zagU{A{X!eXR$2PYMuH-ufP8qkA9#}Xt)CwC4vgv zK{f}&#XN7f{k=jtmq|dyJz{@liB>r%TxnyP$S7e@9Nql)0|Ure!|nb2V|n~`NKz&xok#`l1okCDRV|ln(`TXf#_XRW=f5|z zaW2IBM0Z(5T*k|qa^QTk%mM|o+*=J9c3&uu443-e%;i~zNku553c`^?xD|dU;0cSu zvZf?;fjKvAjeP%QGVpLQx^vGW6i6sH0WtS!3O5%F1p}*Fbgk|t9qJ}WTNUJljXpi~?NfC|(X^6-W zfznYx^H!Rj14BZkcL)AGf6jOmyCE5T^boxq$4`Xiw~-hHa$boDJ0u-5>Fz-nvBowu z@thiX1F`(1>1&l{2BT@>5k4F$9`UK8%M<3)dBb+e>L>&pFnH|T%{ScW=-Y#P0ju0u zZ$v~N%d6&W8cf9AAOPzjex}j7Za=?XsZZQy>y&1FmVuw@h8TN1*hIjFF zNdlw&tZ_CNH{_FHSjPEmAZ1dU(z<{{9ada%-&i{%!w4Dv2UI8EI;sZ#mNdg$@p+r89|c ztT)%2=hE_V=%_ZndCCq(bxyl_tWGfzmK&+JeR-nphurCk92ffcwvW@JP5UObhVM>2 z>Kbpc;S>#0RD#@bzaA0h%_A<95fjeV=tabc1xQc&-pc2mEL%SW@7Y({+23PFM=lg+B%M|9k;weS-ZJ zN!$zS@ROj5DhkR`kBM5&JPDrYa%^C&)1jVg9|yZyLp8H2hXsT9w{NVSXmi^JRCoa| z-D)U!rj|6?K`a3&jIpl|;#IpvwAL7=x)c;rePnSo(My4d7x0`!5DDtvYYZpjpptyO zn9GQ?o04iR!}ddU4BC>TbA@p*74T<^#-%BAuN`VpWAi9G*WGHE!{ayo)J!?$JkDc? zggyNe%|1-32A{Ll6PRGx;VvqP>iP+NMPqxj6vwzaW1HuYSq`qheXxJ?hW)F+k8{*7 zd|z4hwvA*J_W2hEyjHd1_G2!SwfdFzUOrkj6H9_~b;r^(tUQrAbE&$5bmpYsd*Z3P z#nkPgLW#h6gc9S877})x%~t~>*}KcG-&c8cFcSm2U8h3iB;0q#obTyed}AWC0+QZn zIZV*MB`EV(@N)-a4fi^R2XCG`$_yVyVUqf*2}af#dkicprIPt8YXzHngxeb(sz~O$ zYV4f6t)+4~Y-iSG1~G0|I`S5L@xoQ&O(jF?@AzgDM|*Ov^^NIP=~tH#L6i{= zi1Wvk53W);)06MumW=9ftatnX1HGjZw3Avn5Iz!bJ%j%yEBJ@iNJ3aYP5u0n!u~|3 zoLr451u0CqDz@`mnvq7z=nDCm2yybjn(}s<{&i{nq*3TV`10TZRCZl^-Qb&Jtx_#H z?|RPBJ{qdS(x0utt-mO7#D~e}YSHJGKO3Fe>`}p|Pewq4O1J3D!d}}kc$|$QkQ|h& zO)fPbdp30N$kVo#OwSB`L*bcc`eRgA{fP|Qp-(6^*mDbowL6p@RpdEIf8V~YX@DL7 zfV-~F4~hKi*IR;=5JRmi)H2c7*pJHiR51~-a$N2Oy7WHqb!?Ix^gn?KK>-s&E|XS> zgc5J%hpIGZXc09i2jw*5e#Dp|D63;$RCXr~5j6SpX~wM38HRD`3+FJ`FW&ninsk1- z&Sh;n%@(K|Cn4f5+f230Sk>b0Yf_NJW6u~L_4!qVE}oN2ek~|>=sA_FW@7uZN&V6| z8$ve-d}<7CbkVjFE3+9)GzW#X^OnTan5o0B0=3jRNp(YSocj1POD$*{d#ZC$CdIpGM z@pfCJV$Z{JMGFRCt40IRRtws=-(%n*$BP)2KTxW+$c4jEHI~7^Q`li14JzRMd&Rty zkkcun!4OFx@G)vJ@Cvac;7($)qsAnob-`20SZll?Cgw3fI!J9wX{MzrNH#Un8p}4eGCS012 z9!^47o8QA%&NLt97Zt5Qp5+f^-~ZVo}>VEN4Dcwt~pXb?@sCY;NWl_ zTbCo#i-!^y`~|FR&%q!M2egq4H%lb}LuF)n5|it3Z5gC->IgZaD?t)1c+OukiPHDf z9^&tZ$NBQ8JAr^ROpVP8Ni>9xkjfJbZIm1g%~bC=FwRvB%?ns-Q-O~~3S#pULx|L$C1q@b z*$9DpUOx%2evGmHlF#cGWuNhx;mZNq?5+9sH%dd0 zOonY5r!krzB`eS&e3|H629y%q~++dK7 zl-9bRqV{gEoj}UDn}Ih@g)pNt>)z@|_|gEV!w;?D*|L8?Rnw)HGz;~SC>!k`R1Eff z5TlP&sh(SMdwy%3V6EPOmg-4Qf5$Nt)T^8tf1z0c<|A-$vgGqx4Vf{gKisU-hY^lM z1C^h#iw-^>{tR7$MgIk9JM!ALP-S}2XM5d<=b1Vb2Qx*uW@ikV_CS;U80pQRj?Fu- zA~QR<%rMto0L^fM4WC7Ii;tubyT_E#dO!}s#A2tCTes>7%5 zybiHXGzV2 z`Qm%gB~PuKhDslDNoA5>241z51U`M{OZ|+c90R*`#(+Mjp8-{@V{=)1^+QiERtxM- z`SQaMwgA_|FIAyC3j*-1@dxmexc^g||F z60?Jo%Wk_!xp00Go_rvRHYFJpUtctx$=g5K!Eo4eb=*{`K544GlQ(+2onBoYdOg)8 zO-fKf^spRGm=60Xh0kiP>`mBn#?E%kvXb8|cy`WuxBBx%fE`?v9u_a&j@`vu{5B(B z8XW7}KJU7^Uf-cJC$$+|`n-=$z~r}R!RB!NgZN&!<8yDdD`~A|YhtF7)oj2nr{5n+ zN=l0*wCR$WLb!dmhXp{v`fb>|^IUnZa2Jf!j%Q^6d9;B!e2K)Qe^o zu80w35y~Y?-x`Ruck&DLFwZLN`_>)Ipb0qL35e6-FTDxGg;yG!PWoa{(20j19Port z&r-U)s)8@LcT%8)Jm(9!8^g%q6&*@FwxV}C zs)?h>BfYpFMd4XH&wAd?1ZSP@Wx$3wV5_p(iVU+;GZ)UxUlNf0wsbgns-A7PKXwOR zTrSSgjp<~Au;U3IuhrN&^h6JNo|W}eioio7)OK4~VvTQe(sY9nwZbFE!NC;1kW6Yw zZ#3PG7fu6%YT2WI+X>U7nMG$dh!y(Su>7w$m1016vKz8iXgwq>PJP-&clfA8DpKGI zJvWu(W-ZM_$_XU9Pwem_n(K?P(5V6i!HSLCVfa5ipZswE;ZyHVxovG8-AuR4W1j-v zAcEuPDal716lg0=E|lxFV-K3I+%YAuEN9C5ZUu~#@^`5>H5xnzCMG&M$XhT&AQ1=7 zoB7cq0xloaodO=NoKE}w<;j1T?~i38mG;Jb<0{e^JGmK-)@^I)@Ki6?BV>fn8ga1n z__G@`iWD+NLfYn>7$4ON2|pVPV6D6Jon3GkUQ_FIR~gJ@hHWVvB|>ZEfs@&mOT`)y zvY-6N&mjgsv>fNA)$PbJU*^F`b*d$mFJWJ5H$hN~U+wCklFYy9J<8hG2UiE0O-<&r zHeakKbD~*L6hn?uM{2T2i&D8n1Bd*V-?6~@j(UC9#MNh2puv}mKRKUzIG+DMuq$`T zFrLdhw+AK8W{`QH)YqahA?h%?TXuv~ApJ22vlucq`%4wRkh zE|&_Sy276>CY5a*&sE=D?kIEGKqlmYjx1JVYu_Eko+dP;Xeb4j3t70j^1Lh_xERn& z`Mf*mrsSPf`>Oom=lKvCy+WOZHc8o_hZXR0q*cCrg=8*6m3uQtizXUJ@afxbTUIX@ z*Xmv*L?D?FObMA$z*w2)bbNr=qdPP&9|`{UE1~WBYr-6YT=~RpW)!L?W@0PVr#{$U zK`iExw^fDDyy~%^Mgl~?Jw80y8f*71AjCu(%U6o03qd#OYfnKQ3Qjc=jv{GMjzQ~P zYz-j%O2EV?By@Z7#`|T2Q~0Y>(}WwsSL^@)%dcPb`Wc@ zC`1}9HVwvTR@tg=y2`;@g&Z8>R&+uh&xg3=s*FCpEqVg7Nf5QE%hk%l=yA#3NGeP6Po%?Bajcf()! z!aLNyQF!)&9HFY8j3+eJ_4L$KSJknZbQH5ZcOE#0BG-$tg)m7d6@s z4D4IW_-qYzu$jf{9pN-Uw7?O2jXcyZSr_)K;`0)yk@$-EauciE}=Qhj47a+hW*5J1mYrCAfoA7*-h2veKK(Jp zkjU;=Oj&vB^czB4N?clm--F^$xF$%x(|msS6>g=mfCH+UO2=&`1`zh+?_9EuVoM?5 zSnF0Tn7IQO1Cqv@&$wYq31-IgWK!s`LVo=*mtkrN zP3Y0#%KZ-*hNHMOV!3Ko@#TB^3m=%Lc^+BCpWIuwGmJCZSLk#S;C3e4dF^N#6g%6m zSegPyD3Yw+dTF2T`}XdqOe1vWfHhGplJF~rVc5SQSTp`pMDL)k%^ytQLhC3(URtVR zG5G_eVK>36p!jM~y}OJpCfS#09G%}r6p_lEjEtic1%jz7>F#S;5(HF}dGl={%0A;Q^kaR1@AZ_9$#T*<6e7)W(z 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

XD@C2N|4~*N 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

- +

## 🚀  Quick start From 9d692c5c2534510dfaa19ff00b8fda9eaaf6f42b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 12 Sep 2020 06:08:05 +0800 Subject: [PATCH 0889/1029] update readme --- readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 83080c14..1715c75b 100644 --- a/readme.md +++ b/readme.md @@ -16,10 +16,10 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | | | - | - | -| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) | -| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分表分库》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分表分库》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | > FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: From 7e2903df22d56e2335a3b8b0ae229e08f00a2015 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 13 Sep 2020 01:00:57 +0800 Subject: [PATCH 0890/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Firebird=20D?= =?UTF-8?q?ateTime=20ToString=20yyyyMMdd=20=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20#443=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Firebird/Curd/FirebirdUpdateTest.cs | 50 ++++++ .../FirebirdExpression/DateTimeTest.cs | 142 +++++------------- .../Firebird/FirebirdExpression/StringTest.cs | 92 +++++++++++- .../Sqlite/SqliteExpression/DateTimeTest.cs | 11 -- .../FirebirdExpression.cs | 45 +++++- 5 files changed, 219 insertions(+), 121 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs index 0cb43def..84f02ff4 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs @@ -20,6 +20,17 @@ namespace FreeSql.Tests.Firebird public string Title { get; set; } public DateTime CreateTime { get; set; } } + [Table(Name = "tb_topic_setsource")] + class Topic22 + { + [Column(IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } [Fact] public void Dywhere() @@ -64,6 +75,28 @@ namespace FreeSql.Tests.Firebird public string xx { get; set; } } [Fact] + public void SetSourceNoIdentity() + { + var fsql = g.firebird; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var sql = fsql.Update().SetSource(new Topic22 { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_SETSOURCE\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1, \"CREATETIME\" = @p_2 WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic22 { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.Equal(10, fsql.Insert(items).ExecuteAffrows()); + items[0].Clicks = null; + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_SETSOURCE\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_SETSOURCE\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_SETSOURCE\" SET \"CREATETIME\" = @p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] public void SetSourceIgnore() { Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", @@ -82,6 +115,20 @@ namespace FreeSql.Tests.Firebird { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new object[] { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new[] { "Clicks", "CreateTime" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + var cols = new[] { "Clicks", "CreateTime" }; + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => cols).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + cols = new[] { "Clicks", "CreateTime" }; + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(cols).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); } [Fact] public void UpdateColumns() @@ -123,6 +170,9 @@ namespace FreeSql.Tests.Firebird sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs index 57f8512e..4dc4735c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs @@ -41,6 +41,42 @@ namespace FreeSql.Tests.FirebirdExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + + g.firebird.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } + [Fact] public void Now() { @@ -301,25 +337,6 @@ namespace FreeSql.Tests.FirebirdExpression //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) } [Fact] - public void Ticks() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) - } - [Fact] public void Add() { var data = new List(); @@ -494,40 +511,9 @@ namespace FreeSql.Tests.FirebirdExpression public void Subtract() { var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); } [Fact] public void _ЧͬSubtract() @@ -536,37 +522,6 @@ namespace FreeSql.Tests.FirebirdExpression data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") } [Fact] public void this_Equals() @@ -587,25 +542,6 @@ namespace FreeSql.Tests.FirebirdExpression //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) } - [Fact] - public void this_ToString() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) - } [Fact] public void DateTime_Compare() diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs index a58e6eb1..b3dceb92 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs @@ -50,6 +50,96 @@ namespace FreeSql.Tests.FirebirdExpression list.Add(g.firebird.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.sqlite; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + + [Fact] + public void Format() + { + var item = g.firebird.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(lpad(extract(year from cast(a.""CREATETIME"" as timestamp)),4,'0')||lpad(extract(month from cast(a.""CREATETIME"" as timestamp)),2,'0'), '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce((a.""ID"" + 1), '')||'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(lpad(extract(year from cast(a.""CREATETIME"" as timestamp)),4,'0')||lpad(extract(month from cast(a.""CREATETIME"" as timestamp)),2,'0'), '')||''||coalesce(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + + [Fact] + public void Format4() + { + //3 {} ʱArguments Ƿֿ + //4 {} ʱArguments[1] ֻܽȻ NewArray [] + var item = g.firebird.GetRepository().Insert(new Topic { Clicks = 101, Title = "й101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(lpad(extract(year from cast(a.""CREATETIME"" as timestamp)),4,'0')||lpad(extract(month from cast(a.""CREATETIME"" as timestamp)),2,'0'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce((a.""ID"" + 1), '')||'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(lpad(extract(year from cast(a.""CREATETIME"" as timestamp)),4,'0')||lpad(extract(month from cast(a.""CREATETIME"" as timestamp)),2,'0'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } [Fact] public void Empty() @@ -58,7 +148,7 @@ namespace FreeSql.Tests.FirebirdExpression data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 //FROM `tb_topic` a - //WHERE (ifnull(a.`Title`, '') = '') + //WHERE (coalesce(a.`Title`, '') = '') } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs index 0ca17964..c0c76b6a 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs @@ -49,17 +49,6 @@ namespace FreeSql.Tests.SqliteExpression data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type - //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); - - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 - //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent - //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) g.sqlite.Insert(new Topic()).ExecuteAffrows(); var dtn = DateTime.Parse("2020-1-1 0:0:0"); diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs index 02e20989..203022c4 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs @@ -1,11 +1,10 @@ using FreeSql.Internal; -using FreeSql.Internal.Model; using System; using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Firebird { @@ -41,7 +40,7 @@ namespace FreeSql.Firebird case "System.UInt16": return $"cast({getExp(operandExp)} as integer)"; case "System.UInt32": return $"cast({getExp(operandExp)} as bigint)"; case "System.UInt64": return $"cast({getExp(operandExp)} as decimal(21,0))"; - case "System.Guid": return $"substring(cast({getExp(operandExp)} as char) from 1 for 36)"; + case "System.Guid": return $"substring(cast({getExp(operandExp)} as char(36)) from 1 for 36)"; } } break; @@ -69,7 +68,7 @@ namespace FreeSql.Firebird case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as integer)"; case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,0))"; - case "System.Guid": return $"substring(cast({getExp(callExp.Arguments[0])} as char) from 1 for 36)"; + case "System.Guid": return $"substring(cast({getExp(callExp.Arguments[0])} as char(36)) from 1 for 36)"; } return null; case "NewGuid": @@ -84,7 +83,7 @@ namespace FreeSql.Firebird if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; return null; case "ToString": - if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as blob sub_type 1)" : null; return null; } @@ -401,7 +400,41 @@ namespace FreeSql.Firebird break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second from {left} to {args1})"; - case "ToString": return exp.Arguments.Count == 0 ? $"cast({left} as varchar(50))" : null; + case "ToString": + if (left.EndsWith(" as timestamp)") == false && left.StartsWith("timestamp") == false) left = $"cast({left} as timestamp)"; + if (exp.Arguments.Count == 0) return $"lpad(extract(year from {left}),4,'0')||'-'||lpad(extract(month from {left}),2,'0')||'-'||lpad(extract(day from {left}),2,'0')||' '||lpad(extract(hour from {left}),2,'0')||':'||lpad(extract(minute from {left}),2,'0')||':'||lpad(trunc(extract(second from {left})),2,'0')"; + switch (args1.TrimStart('N')) + { + case "'yyyyMMdd'": return $"lpad(extract(year from {left}),4,'0')||lpad(extract(month from {left}),2,'0')||lpad(extract(day from {left}),2,'0')"; + case "'yyyyMM'": return $"lpad(extract(year from {left}),4,'0')||lpad(extract(month from {left}),2,'0')"; + case "'yyyy'": return $"lpad(extract(year from {left}),4,'0')"; + } + var isMatched = false; + args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "yyyy": return $"'||lpad(extract(year from {left}),4,'0')||'"; + case "yy": return $"'||substring(lpad(extract(year from {left}),4,'0') from 3 for 2)||'"; + case "MM": return $"'||lpad(extract(month from {left}),2,'0')||'"; + case "M": return $"'||extract(month from {left})||'"; + case "dd": return $"'||lpad(extract(day from {left}),2,'0')||'"; + case "d": return $"'||extract(day from {left})||'"; + case "HH": return $"'||lpad(extract(hour from {left}),2,'0')||'"; + case "H": return $"'||extract(hour from {left})||'"; + case "hh": return $"'||case when mod(extract(hour from {left}),12) = 0 then '12' else lpad(mod(extract(hour from {left}),12),2,'0') end||'"; + case "h": return $"'||trim(case when mod(extract(hour from {left}),12) = 0 then '12' else mod(extract(hour from {left}),12) end)||'"; + case "mm": return $"'||lpad(extract(minute from {left}),2,'0')||'"; + case "m": return $"'||extract(minute from {left})||'"; + case "ss": return $"'||lpad(trunc(extract(second from {left})),2,'0')||'"; + case "s": return $"'||trunc(extract(second from {left}))||'"; + case "tt": return $"'||case when extract(hour from {left}) >= 12 then 'PM' else 'AM' end||'"; + case "t": return $"'||case when extract(hour from {left}) >= 12 then 'P' else 'A' end||'"; + } + return m.Groups[0].Value; + }); + return isMatched == false ? args1 : $"({args1})"; } } return null; From 7240181ff565a724ff8ec29d162eb464d91805e1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 13 Sep 2020 01:09:02 +0800 Subject: [PATCH 0891/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Firebird=20s?= =?UTF-8?q?tring.Join=20+=20ToList=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E5=AE=9E=E7=8E=B0=E4=B8=8E=20MySql=20group?= =?UTF-8?q?=5Fconcat=20=E7=9B=B8=E5=90=8C=E7=9A=84=E6=95=88=E6=9E=9C=20#44?= =?UTF-8?q?3=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Firebird/FirebirdExpression/StringTest.cs | 2 +- .../FreeSqlGlobalExpressionCallExtensions.cs | 5 +++++ .../FirebirdExpression.cs | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs index b3dceb92..83b41cdc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs @@ -53,7 +53,7 @@ namespace FreeSql.Tests.FirebirdExpression [Fact] public void StringJoin() { - var fsql = g.sqlite; + var fsql = g.firebird; fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Insert(new[] { new StringJoin01 { name = "" }, new StringJoin01 { name = "Ϻ" }, new StringJoin01 { name = "" }, }).ExecuteAffrows(); diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index a625db9d..d534c527 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -358,6 +358,11 @@ namespace FreeSql expContext.Result = $"listagg(to_char({expContext.ParsedContent["column"]}),{expContext.ParsedContent["delimiter"]}) within group({orderby})"; return null; } + public static string StringJoinFirebirdList(object column, object delimiter) + { + expContext.Result = $"list({expContext.ParsedContent["column"]},{expContext.ParsedContent["delimiter"]})"; + return null; + } #endregion } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs index 203022c4..c2f6a1e1 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs @@ -255,6 +255,20 @@ namespace FreeSql.Firebird //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinFirebirdList"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; } } else From ad12402926674d6b1e9c57db30d209c897ab1866 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 13 Sep 2020 10:45:14 +0800 Subject: [PATCH 0892/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect<11..?= =?UTF-8?q?16>=2016=20=E4=B8=AA=E5=A4=9A=E8=81=94=E8=A1=A8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 14 +- .../Firebird/Curd/FirebirdSelectTest.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 73 ++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 45 +-- FreeSql/FreeSql.xml | 148 --------- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 91 +---- FreeSql/Interface/Curd/ISelect/ISelect11.cs | 64 ++++ FreeSql/Interface/Curd/ISelect/ISelect12.cs | 64 ++++ FreeSql/Interface/Curd/ISelect/ISelect13.cs | 64 ++++ FreeSql/Interface/Curd/ISelect/ISelect14.cs | 64 ++++ FreeSql/Interface/Curd/ISelect/ISelect15.cs | 64 ++++ FreeSql/Interface/Curd/ISelect/ISelect16.cs | 64 ++++ .../SelectProvider/Select11Provider.cs | 291 ++++++++++++++++ .../SelectProvider/Select12Provider.cs | 295 +++++++++++++++++ .../SelectProvider/Select13Provider.cs | 299 +++++++++++++++++ .../SelectProvider/Select14Provider.cs | 303 +++++++++++++++++ .../SelectProvider/Select15Provider.cs | 307 +++++++++++++++++ .../SelectProvider/Select16Provider.cs | 311 ++++++++++++++++++ .../SelectProvider/Select1Provider.cs | 7 + FreeSql/Internal/Model/NativeTuple.cs | 205 ++++++++++++ .../Curd/DamengSelect.cs | 38 +++ .../Curd/FirebirdSelect.cs | 38 +++ .../FreeSql.Provider.Firebird.csproj | 4 +- .../Curd/KingbaseESSelect.cs | 38 +++ .../Curd/MsAccessSelect.cs | 92 ++++-- .../Curd/MySqlSelect.cs | 38 +++ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../Dameng/Curd/OdbcDamengSelect.cs | 38 +++ .../Default/Curd/OdbcSelect.cs | 38 +++ .../FreeSql.Provider.Odbc.csproj | 2 +- .../KingbaseES/Curd/OdbcKingbaseESSelect.cs | 38 +++ .../MySql/Curd/OdbcMySqlSelect.cs | 38 +++ .../Oracle/Curd/OdbcOracleSelect.cs | 38 +++ .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 38 +++ .../SqlServer/Curd/OdbcSqlServerSelect.cs | 38 +++ .../Curd/OracleSelect.cs | 38 +++ .../FreeSql.Provider.Oracle.csproj | 2 +- .../Curd/PostgreSQLSelect.cs | 38 +++ .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../Curd/ShenTongSelect.cs | 38 +++ .../Curd/SqlServerSelect.cs | 38 +++ .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../Curd/SqliteSelect.cs | 38 +++ 45 files changed, 3188 insertions(+), 305 deletions(-) create mode 100644 FreeSql/Interface/Curd/ISelect/ISelect11.cs create mode 100644 FreeSql/Interface/Curd/ISelect/ISelect12.cs create mode 100644 FreeSql/Interface/Curd/ISelect/ISelect13.cs create mode 100644 FreeSql/Interface/Curd/ISelect/ISelect14.cs create mode 100644 FreeSql/Interface/Curd/ISelect/ISelect15.cs create mode 100644 FreeSql/Interface/Curd/ISelect/ISelect16.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..8cc83aba 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -329,10 +329,7 @@ - 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 - 场景:winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】 - 示例:https://github.com/dotnetcore/FreeSql/issues/397 - 注意:* 本方法只支持单表操作,不支持导航属性级联保存 + 开始编辑数据,然后调用方法 EndEdit 分析出添加方法只支持单表操作,不支持导航属性级联保存 @@ -532,6 +529,15 @@ + + +me="M:FreeSqlDbContextExtensions.CreateUnitOfWork(IFreeSql)"> + + 创建基于仓储功能的工作单元,务必使用 using 包含使用 + + + + 批量注入 Repository,可以参考代码自行调整 diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs index 33c14af4..bf5b6c9c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs @@ -921,7 +921,7 @@ FROM ""TB_TOPIC22"" a", subquery); var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" FROM ""TB_TOPIC22"" a -WHERE (((cast(a.""ID"" as char)) in (SELECT b.""TITLE"" +WHERE (((cast(a.""ID"" as blob sub_type 1)) in (SELECT b.""TITLE"" FROM ""TB_TOPIC22"" b)))", subquery); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 93056dd7..1f3ef8df 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -190,6 +190,79 @@ namespace FreeSql.Tests ; ", ddlsql); + var select16Sql1 = g.sqlite.Select() + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => b.userid == a.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => c.userid == b.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => d.userid == c.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => e.userid == d.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => f.userid == e.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => g.userid == f.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => h.userid == g.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => i.userid == h.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => j.userid == i.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => k.userid == j.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => l.userid == k.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => m.userid == l.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => n.userid == m.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => o.userid == n.userid) + .InnerJoin((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => p.userid == o.userid) + .ToSql((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => p); + Assert.Equal(@"SELECT p.""userid"" as1, p.""badgenumber"" as2, p.""ssn"" as3, p.""IDCardNo"" as4, p.""name"" as5, p.""title"" as6, p.""birthday"" as7, p.""hiredday"" as8, p.""hetongdate"" as9, p.""street"" as10, p.""zip"" as11, p.""ophone"" as12, p.""pager"" as13, p.""fphone"" as14, p.""CardNo"" as15, p.""email"" as16, p.""idcardvalidtime"" as17, p.""homeaddress"" as18, p.""minzu"" as19, p.""leavedate"" as20, p.""loginpass"" as21, p.""picurl"" as22, p.""managerid"" as23 +FROM ""userinfo"" a +INNER JOIN ""userinfo"" b ON b.""userid"" = a.""userid"" +INNER JOIN ""userinfo"" c ON c.""userid"" = b.""userid"" +INNER JOIN ""userinfo"" d ON d.""userid"" = c.""userid"" +INNER JOIN ""userinfo"" e ON e.""userid"" = d.""userid"" +INNER JOIN ""userinfo"" f ON f.""userid"" = e.""userid"" +INNER JOIN ""userinfo"" g ON g.""userid"" = f.""userid"" +INNER JOIN ""userinfo"" h ON h.""userid"" = g.""userid"" +INNER JOIN ""userinfo"" i ON i.""userid"" = h.""userid"" +INNER JOIN ""userinfo"" j ON j.""userid"" = i.""userid"" +INNER JOIN ""userinfo"" k ON k.""userid"" = j.""userid"" +INNER JOIN ""userinfo"" l ON l.""userid"" = k.""userid"" +INNER JOIN ""userinfo"" m ON m.""userid"" = l.""userid"" +INNER JOIN ""userinfo"" n ON n.""userid"" = m.""userid"" +INNER JOIN ""userinfo"" o ON o.""userid"" = n.""userid"" +INNER JOIN ""userinfo"" p ON p.""userid"" = o.""userid""", select16Sql1); + var select16Sql2 = g.sqlite.Select() + .From( + (s, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => s + .InnerJoin(a => b.userid == a.userid) + .InnerJoin(a => c.userid == b.userid) + .InnerJoin(a => d.userid == c.userid) + .InnerJoin(a => e.userid == d.userid) + .InnerJoin(a => f.userid == e.userid) + .InnerJoin(a => g.userid == f.userid) + .InnerJoin(a => h.userid == g.userid) + .InnerJoin(a => i.userid == h.userid) + .InnerJoin(a => j.userid == i.userid) + .InnerJoin(a => k.userid == j.userid) + .InnerJoin(a => l.userid == k.userid) + .InnerJoin(a => m.userid == l.userid) + .InnerJoin(a => n.userid == m.userid) + .InnerJoin(a => o.userid == n.userid) + .InnerJoin(a => p.userid == o.userid) + ) + .ToSql((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => p); + Assert.Equal(@"SELECT p.""userid"" as1, p.""badgenumber"" as2, p.""ssn"" as3, p.""IDCardNo"" as4, p.""name"" as5, p.""title"" as6, p.""birthday"" as7, p.""hiredday"" as8, p.""hetongdate"" as9, p.""street"" as10, p.""zip"" as11, p.""ophone"" as12, p.""pager"" as13, p.""fphone"" as14, p.""CardNo"" as15, p.""email"" as16, p.""idcardvalidtime"" as17, p.""homeaddress"" as18, p.""minzu"" as19, p.""leavedate"" as20, p.""loginpass"" as21, p.""picurl"" as22, p.""managerid"" as23 +FROM ""userinfo"" a +INNER JOIN ""userinfo"" b ON b.""userid"" = a.""userid"" +INNER JOIN ""userinfo"" c ON c.""userid"" = b.""userid"" +INNER JOIN ""userinfo"" d ON d.""userid"" = c.""userid"" +INNER JOIN ""userinfo"" e ON e.""userid"" = d.""userid"" +INNER JOIN ""userinfo"" f ON f.""userid"" = e.""userid"" +INNER JOIN ""userinfo"" g ON g.""userid"" = f.""userid"" +INNER JOIN ""userinfo"" h ON h.""userid"" = g.""userid"" +INNER JOIN ""userinfo"" i ON i.""userid"" = h.""userid"" +INNER JOIN ""userinfo"" j ON j.""userid"" = i.""userid"" +INNER JOIN ""userinfo"" k ON k.""userid"" = j.""userid"" +INNER JOIN ""userinfo"" l ON l.""userid"" = k.""userid"" +INNER JOIN ""userinfo"" m ON m.""userid"" = l.""userid"" +INNER JOIN ""userinfo"" n ON n.""userid"" = m.""userid"" +INNER JOIN ""userinfo"" o ON o.""userid"" = n.""userid"" +INNER JOIN ""userinfo"" p ON p.""userid"" = o.""userid""", select16Sql2); + + var sqlxx = g.pgsql.InsertOrUpdate().SetSource(new userinfo { userid = 10 }).UpdateColumns(a => new { a.birthday, a.CardNo }).ToSql(); var aff1 = g.sqlite.GetRepository().Delete(10086); diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 717db8f2..bc78db29 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -239,54 +239,35 @@ public static partial class FreeSqlGlobalExtensions /// public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class => freesql.Select().From((s, b) => s); - /// - /// 多表查询 - /// - /// public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class => freesql.Select().From((s, b, c) => s); - /// - /// 多表查询 - /// - /// public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class => freesql.Select().From((s, b, c, d) => s); - /// - /// 多表查询 - /// - /// public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => freesql.Select().From((s, b, c, d, e) => s); - /// - /// 多表查询 - /// - /// public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => freesql.Select().From((s, b, c, d, e, f) => s); - /// - /// 多表查询 - /// - /// public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => freesql.Select().From((s, b, c, d, e, f, g) => s); - /// - /// 多表查询 - /// - /// public static ISelect Select(this IFreeSql freesql) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => freesql.Select().From((s, b, c, d, e, f, g, h) => s); - /// - /// 多表查询 - /// - /// public static ISelect Select(this IFreeSql freesql) 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 => freesql.Select().From((s, b, c, d, e, f, g, h, i) => s); - /// - /// 多表查询 - /// - /// public static ISelect Select(this IFreeSql freesql) 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 => freesql.Select().From((s, b, c, d, e, f, g, h, i, j) => s); + + public static ISelect Select(this IFreeSql freesql) 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 where T11 : class => + freesql.Select().From((s, b, c, d, e, f, g, h, i, j, k) => s); + public static ISelect Select(this IFreeSql freesql) 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 where T11 : class where T12 : class => + freesql.Select().From((s, b, c, d, e, f, g, h, i, j, k, l) => s); + public static ISelect Select(this IFreeSql freesql) 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 where T11 : class where T12 : class where T13 : class => + freesql.Select().From((s, b, c, d, e, f, g, h, i, j, k, l, m) => s); + public static ISelect Select(this IFreeSql freesql) 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 where T11 : class where T12 : class where T13 : class where T14 : class => + freesql.Select().From((s, b, c, d, e, f, g, h, i, j, k, l, m, n) => s); + public static ISelect Select(this IFreeSql freesql) 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => + freesql.Select().From((s, b, c, d, e, f, g, h, i, j, k, l, m, n, o) => s); + public static ISelect Select(this IFreeSql freesql) 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => + freesql.Select().From((s, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => s); #endregion #region IncludeMany diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index dbca2d52..8869f42b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2106,106 +2106,6 @@ - - - 多表查询 - - - - - - - - - 多表查询 - - - - - - - - - - 多表查询 - - - - - - - - - - - 多表查询 - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - - - 多表查询 - - - - - - - - - - - - - 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") @@ -4229,54 +4129,6 @@ - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - - - - 多表查询 - - - 本方法实现从已知的内存 List 数据,进行和 ISelect.IncludeMany 相同功能的贪婪加载 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index fd7a814c..b6cef93a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -165,98 +165,21 @@ namespace FreeSql /// /// ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - /// ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; - /// - /// 多表查询 - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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; + + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) 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; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) 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; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) 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; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) 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; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) 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; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) 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; /// /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") diff --git a/FreeSql/Interface/Curd/ISelect/ISelect11.cs b/FreeSql/Interface/Curd/ISelect/ISelect11.cs new file mode 100644 index 00000000..57e19df4 --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelect11.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql +{ + 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 where T11 : class + { + +#if net40 +#else + Task AnyAsync(Expression> exp); + Task ToDataTableAsync(Expression> select); + Task> ToListAsync(Expression> select); + Task> ToListAsync(); + + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task SumAsync(Expression> column); + Task MinAsync(Expression> column); + Task MaxAsync(Expression> column); + Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms = null); + } +} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect12.cs b/FreeSql/Interface/Curd/ISelect/ISelect12.cs new file mode 100644 index 00000000..05422fa9 --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelect12.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql +{ + 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 where T11 : class where T12 : class + { + +#if net40 +#else + Task AnyAsync(Expression> exp); + Task ToDataTableAsync(Expression> select); + Task> ToListAsync(Expression> select); + Task> ToListAsync(); + + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task SumAsync(Expression> column); + Task MinAsync(Expression> column); + Task MaxAsync(Expression> column); + Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms = null); + } +} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect13.cs b/FreeSql/Interface/Curd/ISelect/ISelect13.cs new file mode 100644 index 00000000..fb87f33a --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelect13.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql +{ + 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 where T11 : class where T12 : class where T13 : class + { + +#if net40 +#else + Task AnyAsync(Expression> exp); + Task ToDataTableAsync(Expression> select); + Task> ToListAsync(Expression> select); + Task> ToListAsync(); + + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task SumAsync(Expression> column); + Task MinAsync(Expression> column); + Task MaxAsync(Expression> column); + Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms = null); + } +} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect14.cs b/FreeSql/Interface/Curd/ISelect/ISelect14.cs new file mode 100644 index 00000000..786fa125 --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelect14.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql +{ + 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + +#if net40 +#else + Task AnyAsync(Expression> exp); + Task ToDataTableAsync(Expression> select); + Task> ToListAsync(Expression> select); + Task> ToListAsync(); + + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task SumAsync(Expression> column); + Task MinAsync(Expression> column); + Task MaxAsync(Expression> column); + Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms = null); + } +} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect15.cs b/FreeSql/Interface/Curd/ISelect/ISelect15.cs new file mode 100644 index 00000000..9bdd3238 --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelect15.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql +{ + 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + +#if net40 +#else + Task AnyAsync(Expression> exp); + Task ToDataTableAsync(Expression> select); + Task> ToListAsync(Expression> select); + Task> ToListAsync(); + + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task SumAsync(Expression> column); + Task MinAsync(Expression> column); + Task MaxAsync(Expression> column); + Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms = null); + } +} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect16.cs b/FreeSql/Interface/Curd/ISelect/ISelect16.cs new file mode 100644 index 00000000..7d1651ba --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelect16.cs @@ -0,0 +1,64 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql +{ + 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + +#if net40 +#else + Task AnyAsync(Expression> exp); + Task ToDataTableAsync(Expression> select); + Task> ToListAsync(Expression> select); + Task> ToListAsync(); + + Task ToOneAsync(Expression> select); + Task FirstAsync(Expression> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + Task SumAsync(Expression> column); + Task MinAsync(Expression> column); + Task MaxAsync(Expression> column); + Task AvgAsync(Expression> column); +#endif + + bool Any(Expression> exp); + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms = null); + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs new file mode 100644 index 00000000..593a7744 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs @@ -0,0 +1,291 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + public abstract class Select11Provider : Select0Provider, T1>, ISelect + 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 + where T11 : class + { + + public Select11Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; + if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; + if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return 0; + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h"), + Expression.Parameter(typeof(T9), "i"), + Expression.Parameter(typeof(T10), "j"), + Expression.Parameter(typeof(T11), "k")); + } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + async Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + +#endif + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs new file mode 100644 index 00000000..f24459c2 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs @@ -0,0 +1,295 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + public abstract class Select12Provider : Select0Provider, T1>, ISelect + 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 + where T11 : class + where T12 : class + { + + public Select12Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; + if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; + if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; + if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return 0; + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h"), + Expression.Parameter(typeof(T9), "i"), + Expression.Parameter(typeof(T10), "j"), + Expression.Parameter(typeof(T11), "k"), + Expression.Parameter(typeof(T12), "l")); + } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + async Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + +#endif + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs new file mode 100644 index 00000000..d2006c68 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs @@ -0,0 +1,299 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + public abstract class Select13Provider : Select0Provider, T1>, ISelect + 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 + where T11 : class + where T12 : class + where T13 : class + { + + public Select13Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; + if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; + if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; + if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; + if (type == _tables[12].Table?.Type) return $"( {sqlT13} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return 0; + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h"), + Expression.Parameter(typeof(T9), "i"), + Expression.Parameter(typeof(T10), "j"), + Expression.Parameter(typeof(T11), "k"), + Expression.Parameter(typeof(T12), "l"), + Expression.Parameter(typeof(T13), "m")); + } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + async Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + +#endif + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs new file mode 100644 index 00000000..e8f7a9fe --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs @@ -0,0 +1,303 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + public abstract class Select14Provider : Select0Provider, T1>, ISelect + 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 + where T11 : class + where T12 : class + where T13 : class + where T14 : class + { + + public Select14Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; + if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; + if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; + if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; + if (type == _tables[12].Table?.Type) return $"( {sqlT13} )"; + if (type == _tables[13].Table?.Type) return $"( {sqlT14} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return 0; + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h"), + Expression.Parameter(typeof(T9), "i"), + Expression.Parameter(typeof(T10), "j"), + Expression.Parameter(typeof(T11), "k"), + Expression.Parameter(typeof(T12), "l"), + Expression.Parameter(typeof(T13), "m"), + Expression.Parameter(typeof(T14), "n")); + } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + async Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + +#endif + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs new file mode 100644 index 00000000..bb70221a --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs @@ -0,0 +1,307 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + public abstract class Select15Provider : Select0Provider, T1>, ISelect + 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 + where T11 : class + where T12 : class + where T13 : class + where T14 : class + where T15 : class + { + + public Select15Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T15)), Alias = $"SP10o", On = null, Type = SelectTableInfoType.From }); + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; + if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; + if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; + if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; + if (type == _tables[12].Table?.Type) return $"( {sqlT13} )"; + if (type == _tables[13].Table?.Type) return $"( {sqlT14} )"; + if (type == _tables[14].Table?.Type) return $"( {sqlT15} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return 0; + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h"), + Expression.Parameter(typeof(T9), "i"), + Expression.Parameter(typeof(T10), "j"), + Expression.Parameter(typeof(T11), "k"), + Expression.Parameter(typeof(T12), "l"), + Expression.Parameter(typeof(T13), "m"), + Expression.Parameter(typeof(T14), "n"), + Expression.Parameter(typeof(T15), "o")); + } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + async Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + +#endif + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs new file mode 100644 index 00000000..9388a4e7 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs @@ -0,0 +1,311 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + public abstract class Select16Provider : Select0Provider, T1>, ISelect + 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 + where T11 : class + where T12 : class + where T13 : class + where T14 : class + where T15 : class + where T16 : class + { + + public Select16Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15), typeof(T16)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T15)), Alias = $"SP10o", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T16)), Alias = $"SP10p", On = null, Type = SelectTableInfoType.From }); + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; + if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; + if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; + if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; + if (type == _tables[12].Table?.Type) return $"( {sqlT13} )"; + if (type == _tables[13].Table?.Type) return $"( {sqlT14} )"; + if (type == _tables[14].Table?.Type) return $"( {sqlT15} )"; + if (type == _tables[15].Table?.Type) return $"( {sqlT16} )"; + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};\r\n{sqlT16}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return 0; + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), + Expression.Parameter(typeof(T2), "b"), + Expression.Parameter(typeof(T3), "c"), + Expression.Parameter(typeof(T4), "d"), + Expression.Parameter(typeof(T5), "e"), + Expression.Parameter(typeof(T6), "f"), + Expression.Parameter(typeof(T7), "g"), + Expression.Parameter(typeof(T8), "h"), + Expression.Parameter(typeof(T9), "i"), + Expression.Parameter(typeof(T10), "j"), + Expression.Parameter(typeof(T11), "k"), + Expression.Parameter(typeof(T12), "l"), + Expression.Parameter(typeof(T13), "m"), + Expression.Parameter(typeof(T14), "n"), + Expression.Parameter(typeof(T15), "o"), + Expression.Parameter(typeof(T16), "p")); + } + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect.MaxAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect.MinAsync(Expression> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect.SumAsync(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect.ToListAsync(Expression> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + async Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + +#endif + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 490acdbb..1f14404d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -119,6 +119,13 @@ namespace FreeSql.Internal.CommonProvider public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) 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; + + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) 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; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) 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; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) 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; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) 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; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) 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; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) 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; public ISelectGrouping GroupBy(Expression> columns) { diff --git a/FreeSql/Internal/Model/NativeTuple.cs b/FreeSql/Internal/Model/NativeTuple.cs index fcc3036f..138a897f 100644 --- a/FreeSql/Internal/Model/NativeTuple.cs +++ b/FreeSql/Internal/Model/NativeTuple.cs @@ -15,6 +15,13 @@ namespace FreeSql.Internal.Model public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8); public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9); public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10); + + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12, T13 item13) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12, T13 item13, T14 item14) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12, T13 item13, T14 item14, T15 item15) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14, item15); + public static NativeTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12, T13 item13, T14 item14, T15 item15, T16 item16) => new NativeTuple(item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14, item15, item16); } public class NativeTuple @@ -179,4 +186,202 @@ namespace FreeSql.Internal.Model Item10 = item10; } } + public class NativeTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public T9 Item9 { get; } + public T10 Item10 { get; } + public T11 Item11 { get; } + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + Item9 = item9; + Item10 = item10; + Item11 = item11; + } + } + public class NativeTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public T9 Item9 { get; } + public T10 Item10 { get; } + public T11 Item11 { get; } + public T12 Item12 { get; } + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + Item9 = item9; + Item10 = item10; + Item11 = item11; + Item12 = item12; + } + } + public class NativeTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public T9 Item9 { get; } + public T10 Item10 { get; } + public T11 Item11 { get; } + public T12 Item12 { get; } + public T13 Item13 { get; } + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12, T13 item13) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + Item9 = item9; + Item10 = item10; + Item11 = item11; + Item12 = item12; + Item13 = item13; + } + } + public class NativeTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public T9 Item9 { get; } + public T10 Item10 { get; } + public T11 Item11 { get; } + public T12 Item12 { get; } + public T13 Item13 { get; } + public T14 Item14 { get; } + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12, T13 item13, T14 item14) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + Item9 = item9; + Item10 = item10; + Item11 = item11; + Item12 = item12; + Item13 = item13; + Item14 = item14; + } + } + public class NativeTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public T9 Item9 { get; } + public T10 Item10 { get; } + public T11 Item11 { get; } + public T12 Item12 { get; } + public T13 Item13 { get; } + public T14 Item14 { get; } + public T15 Item15 { get; } + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12, T13 item13, T14 item14, T15 item15) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + Item9 = item9; + Item10 = item10; + Item11 = item11; + Item12 = item12; + Item13 = item13; + Item14 = item14; + Item15 = item15; + } + } + public class NativeTuple + { + public T1 Item1 { get; } + public T2 Item2 { get; } + public T3 Item3 { get; } + public T4 Item4 { get; } + public T5 Item5 { get; } + public T6 Item6 { get; } + public T7 Item7 { get; } + public T8 Item8 { get; } + public T9 Item9 { get; } + public T10 Item10 { get; } + public T11 Item11 { get; } + public T12 Item12 { get; } + public T13 Item13 { get; } + public T14 Item14 { get; } + public T15 Item15 { get; } + public T16 Item16 { get; } + public NativeTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8, T9 item9, T10 item10, T11 item11, T12 item12, T13 item13, T14 item14, T15 item15, T16 item16) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Item8 = item8; + Item9 = item9; + Item10 = item10; + Item11 = item11; + Item12 = item12; + Item13 = item13; + Item14 = item14; + Item15 = item15; + Item16 = item16; + } + } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs index 2d7e0e73..0d5f65d9 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs @@ -134,6 +134,13 @@ namespace FreeSql.Dameng.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -181,4 +188,35 @@ namespace FreeSql.Dameng.Curd public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class DamengSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class DamengSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs index a4289cc4..d751ea6d 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs @@ -125,6 +125,13 @@ namespace FreeSql.Firebird.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -172,5 +179,36 @@ namespace FreeSql.Firebird.Curd public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 1f61b4eb..0f3b10cc 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -4,13 +4,13 @@ netstandard2.0;net452 1.9.0-preview0912 true - ncc;YeXiangQin + FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;Firebird;火鸟 $(AssemblyName) logo.png $(AssemblyName) diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs index fea0cca1..77f59b9c 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs @@ -124,6 +124,13 @@ namespace FreeSql.KingbaseES public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -171,4 +178,35 @@ namespace FreeSql.KingbaseES public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs index ff0fbd41..352b5710 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs @@ -135,60 +135,98 @@ namespace FreeSql.MsAccess.Curd } public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new AccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } - class AccessSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { - public AccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index 5f1b4966..37d427fe 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -122,6 +122,13 @@ namespace FreeSql.MySql.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -169,4 +176,35 @@ namespace FreeSql.MySql.Curd public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class MySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class MySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index aa4ecb7f..53284f95 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -10,7 +10,7 @@ https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;MySql;MariaDB;Tidb $(AssemblyName) logo.png $(AssemblyName) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 8cef6bbe..21abcba7 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -10,7 +10,7 @@ https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;MySql;MariaDB;Tidb $(AssemblyName) logo.png $(AssemblyName) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs index 7a43e528..fca54b41 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs @@ -134,6 +134,13 @@ namespace FreeSql.Odbc.Dameng public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -181,4 +188,35 @@ namespace FreeSql.Odbc.Dameng public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index 0ccddfa8..963db3a3 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -138,6 +138,13 @@ namespace FreeSql.Odbc.Default public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -185,4 +192,35 @@ namespace FreeSql.Odbc.Default public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class OdbcSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 83ae1417..975bd812 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -10,7 +10,7 @@ https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;Odbc $(AssemblyName) logo.png $(AssemblyName) diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs index 8a2af80c..cf1dc1ee 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs @@ -124,6 +124,13 @@ namespace FreeSql.Odbc.KingbaseES public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -171,4 +178,35 @@ namespace FreeSql.Odbc.KingbaseES public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index c607f773..290db614 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -122,6 +122,13 @@ namespace FreeSql.Odbc.MySql public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -169,4 +176,35 @@ namespace FreeSql.Odbc.MySql public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index c353b428..8e85005c 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -140,6 +140,13 @@ namespace FreeSql.Odbc.Oracle public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -187,4 +194,35 @@ namespace FreeSql.Odbc.Oracle public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 81703262..11a6b689 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -124,6 +124,13 @@ namespace FreeSql.Odbc.PostgreSQL public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -171,4 +178,35 @@ namespace FreeSql.Odbc.PostgreSQL public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index f6a91c1b..d98c3bbe 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -258,6 +258,13 @@ namespace FreeSql.Odbc.SqlServer public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -305,4 +312,35 @@ namespace FreeSql.Odbc.SqlServer public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 9663db7c..0f6bf97a 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -140,6 +140,13 @@ namespace FreeSql.Oracle.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -187,4 +194,35 @@ namespace FreeSql.Oracle.Curd public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class OracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class OracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index ecdecb32..a9a7492c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -10,7 +10,7 @@ https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;Oracle $(AssemblyName) logo.png $(AssemblyName) diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 8b902795..e689d042 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -124,6 +124,13 @@ namespace FreeSql.PostgreSQL.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -171,4 +178,35 @@ namespace FreeSql.PostgreSQL.Curd public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 39c62ae0..b47ac363 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -10,7 +10,7 @@ https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;PostgreSQL;pgsql $(AssemblyName) logo.png $(AssemblyName) diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs index 4d78874b..9a23877f 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs @@ -124,6 +124,13 @@ namespace FreeSql.ShenTong.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -171,4 +178,35 @@ namespace FreeSql.ShenTong.Curd public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 97994329..82fbff16 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -261,6 +261,13 @@ namespace FreeSql.SqlServer.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -308,4 +315,35 @@ namespace FreeSql.SqlServer.Curd public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 82a55f1e..557ce6f9 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -10,7 +10,7 @@ https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;SqlServer;mssql $(AssemblyName) logo.png $(AssemblyName) diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 218cb892..45bd93ee 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -10,7 +10,7 @@ https://github.com/2881099/FreeSql git MIT - FreeSql;ORM + FreeSql;ORM;SqlServer;mssql $(AssemblyName) logo.png $(AssemblyName) diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index 054265fd..e08c29c4 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -122,6 +122,13 @@ namespace FreeSql.Sqlite.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class @@ -169,4 +176,35 @@ namespace FreeSql.Sqlite.Curd public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); } + + class SqliteSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } + class SqliteSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + } } From 704e59bf218bd7d875f6cf2609fa1919ef35acab Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 14 Sep 2020 11:33:20 +0800 Subject: [PATCH 0893/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20FreeSql.DbCo?= =?UTF-8?q?ntext=20=E5=AF=B9=E5=90=8C=E4=B8=80=E5=AE=9E=E4=BD=93=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=20Update=EF=BC=8C=E7=AC=AC=E4=BA=8C=E6=AC=A1=E6=97=A0?= =?UTF-8?q?=E6=95=88=E7=9A=84=20Bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbSet/DbSetAsync.cs | 11 +++++++++ FreeSql.DbContext/DbSet/DbSetSync.cs | 11 +++++++++ FreeSql.DbContext/FreeSql.DbContext.xml | 23 ++++--------------- .../Firebird/FirebirdDbFirstTest.cs | 5 ++++ 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 1c2fa9aa..b75f3fb4 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -408,7 +408,18 @@ namespace FreeSql foreach (var item in data) { if (_dicUpdateTimes.ContainsKey(item)) + { + var itemCopy = CreateEntityState(item).Value; await DbContextFlushCommandAsync(); + if (_table.VersionColumn != null) + { + var itemVersion = _db.OrmOriginal.GetEntityValueWithPropertyName(_entityType, item, _table.VersionColumn.CsName); + _db.OrmOriginal.MapEntityValue(_entityType, itemCopy, item); + _db.OrmOriginal.SetEntityValueWithPropertyName(_entityType, item, _table.VersionColumn.CsName, itemVersion); + } + else + _db.OrmOriginal.MapEntityValue(_entityType, itemCopy, item); + } _dicUpdateTimes.Add(item, 1); var state = CreateEntityState(item); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 59e173a3..7932c65c 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -451,7 +451,18 @@ namespace FreeSql foreach (var item in data) { if (_dicUpdateTimes.ContainsKey(item)) + { + var itemCopy = CreateEntityState(item).Value; DbContextFlushCommand(); + if (_table.VersionColumn != null) + { + var itemVersion = _db.OrmOriginal.GetEntityValueWithPropertyName(_entityType, item, _table.VersionColumn.CsName); + _db.OrmOriginal.MapEntityValue(_entityType, itemCopy, item); + _db.OrmOriginal.SetEntityValueWithPropertyName(_entityType, item, _table.VersionColumn.CsName, itemVersion); + } + else + _db.OrmOriginal.MapEntityValue(_entityType, itemCopy, item); + } _dicUpdateTimes.Add(item, 1); var state = CreateEntityState(item); diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 8cc83aba..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -329,7 +329,10 @@ - 开始编辑数据,然后调用方法 EndEdit 分析出添加方法只支持单表操作,不支持导航属性级联保存 + 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 + 场景:winform 加载表数据后,一顿添加、修改、删除操作之后,最后才点击【保存】 + 示例:https://github.com/dotnetcore/FreeSql/issues/397 + 注意:* 本方法只支持单表操作,不支持导航属性级联保存 @@ -531,21 +534,3 @@ -me="M:FreeSqlDbContextExtensions.CreateUnitOfWork(IFreeSql)"> - - 创建基于仓储功能的工作单元,务必使用 using 包含使用 - - - - - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdDbFirstTest.cs index d927e0d1..8dfb7b9f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdDbFirstTest.cs @@ -36,6 +36,11 @@ namespace FreeSql.Tests.Firebird public void ExistsTable() { var fsql = g.firebird; + try + { + fsql.Ado.ExecuteNonQuery("drop table test_existstb011"); + } + catch { } Assert.False(fsql.DbFirst.ExistsTable("test_existstb011")); Assert.False(fsql.DbFirst.ExistsTable("test_existstb011", false)); fsql.CodeFirst.SyncStructure(typeof(test_existstb011)); From 2df5f0b3a37a939e0cec337e7b5a66c6bf1e9ca1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 14 Sep 2020 11:37:35 +0800 Subject: [PATCH 0894/1029] v1.9.0-preview0915 #443 #456 #454 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index fe83a839..6e671628 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index b857487a..f5b94a10 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 16204fc6..f499faac 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 304f74c6..64b950c7 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 1046f241..5aec42b3 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0912 + 1.9.0-preview0915 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 06df65b7..3c6c63f9 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 9c46c676..e259d98f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index a22a9bd5..dfea8bb2 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 68a2a1a3..7448b38b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 5333d2a2..6e4ded39 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 0f3b10cc..673cd7fb 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index f1dcaeff..bf7559a2 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 4c1d3d40..c249f07e 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 53284f95..187bb64a 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 21abcba7..55f8efbf 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 975bd812..da2455d7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a9a7492c..5202a8a5 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b47ac363..5985fb5e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index b29b5226..713326e2 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 557ce6f9..4a3d2624 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 45bd93ee..aeb085e0 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9bacf2a2..7f04f698 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0912 + 1.9.0-preview0915 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From cc39bfee5144448d83e399430912f67933986654 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 15 Sep 2020 15:04:11 +0800 Subject: [PATCH 0895/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=20DbFirst=20int=20=E7=B1=BB=E5=9E=8B=E8=AF=86?= =?UTF-8?q?=E5=88=AB=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs | 1 + Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index 045cd100..cba1151a 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -69,6 +69,7 @@ namespace FreeSql.Dameng case "tinyint": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(3)"]); return DmDbType.Byte; + case "int": case "integer": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(11)"]); return DmDbType.Int32; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 49e866fc..3c410edc 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -69,6 +69,7 @@ namespace FreeSql.Odbc.Dameng case "tinyint": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(3)"]); return OdbcType.TinyInt; + case "int": case "integer": _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(11)"]); return OdbcType.Int; From d659e874e20c4a4dee0502549abfcd7daffa72cb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 15 Sep 2020 15:47:27 +0800 Subject: [PATCH 0896/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Gene?= =?UTF-8?q?rator=20Firebird=20=E7=94=9F=E6=88=90=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E7=B1=BB=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 51 ++++++++----------- .../FreeSql.Generator.csproj | 1 + 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 38a4f7fa..119364dd 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -85,37 +85,27 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam > {1} {2} 1 {3} 0,0,0,0 {4} MyProject {5} ""MySql,Data Source=127.0.0.1;..."" -Razor 1 * 选择模板:实体类+特性 - -Razor 2 * 选择模板:实体类+特性+导航属性 - -Razor ""d:\diy.cshtml"" * 自定义模板文件 - - -NameOptions * 总共4个布尔值,分别对应: - # 首字母大写 - # 首字母大写,其他小写 - # 全部小写 - # 下划线转驼峰 - + + -NameOptions * 4个布尔值对应: + 首字母大写 + 首字母大写,其他小写 + 全部小写 + 下划线转驼峰 + -NameSpace * 命名空间 - - -DB ""{6},Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=数据库;Charset=utf8;SslMode=none;Max pool size=2"" - - -DB ""{7},Data Source=.;Integrated Security=True;Initial Catalog=数据库;Pooling=true;Max Pool Size=2"" - - -DB ""{8},Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=数据库;Pooling=true;Maximum Pool Size=2"" - - -DB ""{9},user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2"" - -DB ""{10},Data Source=document.db"" - + -DB ""{6},data source=127.0.0.1;port=3306;user id=root;password=root;initial catalog=数据库;charset=utf8;sslmode=none;max pool size=2"" + -DB ""{7},data source=.;integrated security=True;initial catalog=数据库;pooling=true;max pool size=2"" + -DB ""{8},host=192.168.164.10;port=5432;username=postgres;password=123456;database=数据库;pooling=true;maximum pool size=2"" + -DB ""{9},user id=user1;password=123456;data source=//127.0.0.1:1521/XE;pooling=true;max pool size=2"" + -DB ""{10},data source=document.db"" + -DB ""{14},database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=2"" -DB ""{11},server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user;poolsize=2"" - {11} 达梦数据库 - - -DB ""{12},Driver={KingbaseES 8.2 ODBC Driver ANSI};Server=127.0.0.1;Port=54321;UID=USER2;PWD=123456789;database=数据库"" - {12} 人大金仓数据库 - - -DB ""{13},HOST=192.168.164.10;PORT=2003;DATABASE=OSRDB;USERNAME=SYSDBA;PASSWORD=szoscar55;MAXPOOLSIZE=2"" - {13} 神舟通用数据库 + -DB ""{12},server=127.0.0.1;port=54321;uid=USER2;pwd=123456789;database=数据库"" + -DB ""{13},host=192.168.164.10;port=2003;database=数据库;username=SYSDBA;password=szoscar55;maxpoolsize=2"" + * {11}(达梦数据库)、{12}(人大金仓数据库)、{13}(神舟通用数据库) -Filter Table+View+StoreProcedure 默认生成:表+视图+存储过程 @@ -124,12 +114,11 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam -Match 正则表达式,只生成匹配的表,如:dbo\.TB_.+ -FileName 文件名,默认:{name}.cs - -Output 保存路径,默认为当前 shell 所在目录 - {14} + {15} ", Color.SlateGray, -new Colorful.Formatter("使用 FreeSql 快速生成数据库的实体类", Color.SlateGray), +new Colorful.Formatter("FreeSql 快速生成数据库的实体类", Color.SlateGray), new Colorful.Formatter("FreeSql.Generator", Color.White), new Colorful.Formatter("-Razor", Color.ForestGreen), new Colorful.Formatter("-NameOptions", Color.ForestGreen), @@ -141,8 +130,9 @@ new Colorful.Formatter("PostgreSQL", Color.Yellow), new Colorful.Formatter("Oracle", Color.Yellow), new Colorful.Formatter("Sqlite", Color.Yellow), new Colorful.Formatter("Dameng", Color.Yellow), -new Colorful.Formatter("OdbcKingbaseES", Color.Yellow), +new Colorful.Formatter("KingbaseES", Color.Yellow), new Colorful.Formatter("ShenTong", Color.Yellow), +new Colorful.Formatter("Firebird", Color.Yellow), new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新所有实体类", Color.ForestGreen) ); wait.Set(); @@ -182,6 +172,7 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 case "postgresql": ArgsDbType = DataType.PostgreSQL; break; case "oracle": ArgsDbType = DataType.Oracle; break; case "sqlite": ArgsDbType = DataType.Sqlite; break; + case "firebird": ArgsDbType = DataType.Firebird; break; case "dameng": ArgsDbType = DataType.Dameng; break; case "kingbasees": ArgsDbType = DataType.KingbaseES; break; case "shentong": ArgsDbType = DataType.ShenTong; break; diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 5aec42b3..648604f8 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -35,6 +35,7 @@ + From f39234c6a40262b8180ff4ea1a003661d6db7ce1 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Wed, 16 Sep 2020 02:55:00 +0800 Subject: [PATCH 0897/1029] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 1715c75b..06695cc2 100644 --- a/readme.md +++ b/readme.md @@ -192,6 +192,6 @@ L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.9 > Thank you for your donation -- [Alipay](https://www.cnblogs.com/FreeSql/gallery/image/290628.html) +- [Alipay](https://www.cnblogs.com/FreeSql/gallery/image/338860.html) -- [WeChat](https://www.cnblogs.com/FreeSql/gallery/image/290627.html) +- [WeChat](https://www.cnblogs.com/FreeSql/gallery/image/338859.html) From e30a57ad046b4b0699c900c5ae9aaccdea9bad01 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 16 Sep 2020 12:34:46 +0800 Subject: [PATCH 0898/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=9F=A5=E8=AF=A2=E5=8F=82=E6=95=B0=E5=8C=96=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=97=B6=20ToList=20=E5=AD=90=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=9C=AA=E4=BC=A0=E6=92=AD=E5=8F=82=E6=95=B0=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B#462?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++++ FreeSql.Tests/FreeSql.Tests/Issues/462.cs | 60 +++++++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 2 +- 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/462.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/462.cs b/FreeSql.Tests/FreeSql.Tests/Issues/462.cs new file mode 100644 index 00000000..0fa0162f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/462.cs @@ -0,0 +1,60 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _462 + { + [Fact] + public void SelectTest() + { + IFreeSql db = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=1") + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + .UseGenerateCommandParameterWithLambda(true) + .UseAutoSyncStructure(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build(); + + var startTime = DateTime.Now; + var endTime = DateTime.Now; + + var exp0 = 10; + var cou = db.Select() + .Where(a => a.ScheduledDttm.Date >= startTime.Date && a.ScheduledDttm.Date <= (endTime.AddDays(1)).Date) + .ToList(a => new + { + subCount = db.Select().Where(b => b.SCHEDULED_DTTM == exp0).Count() + }); + } + + [Table(Name = "V_HospitalReport22")] + public class V_HospitalReport + { + [Column(Name = "hospital_name")] + public string HospitalName { get; set; } + + [Column(Name = "dep")] + public string Dep { get; set; } + + [Column(Name = "instrna")] + public string Instrna { get; set; } + + [Column(Name = "confirm_doctor_name")] + public string ConfirmDoctorName { get; set; } + + [Column(Name = "Scheduled_Dttm")] + public DateTime ScheduledDttm { get; set; } + } + [Table(Name = "V_HOSPITALREPORT22111")] + public class V_HOSPITALREPORT + { + public int SCHEDULED_DTTM { get; set; } + } + } +} diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index d1177708..7d5c22c0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -30,7 +30,7 @@ namespace FreeSql.Internal internal const int ReadAnonymousFieldAsCsName = -53129; public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, SelectGroupingProvider grouping, List whereCascadeExpression, List findIncludeMany, bool isAllDtoMap) { - Func getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; + Func getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = select?._params }; //#462 添加 DbParams 解决 switch (exp.NodeType) { case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); From 999e1bb46a806f5af059665a243595b293c01719 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 16 Sep 2020 12:38:09 +0800 Subject: [PATCH 0899/1029] v1.9.0-preview0916 #462 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 22 insertions(+), 38 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 6e671628..7cb668d9 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index f5b94a10..02389cdc 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index f499faac..eefac104 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 64b950c7..3d10d3f3 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 648604f8..c6400c6a 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0915 + 1.9.0-preview0916 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 3c6c63f9..20b5b94d 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e259d98f..ec6f85ef 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index dfea8bb2..6d7dcc6c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 7448b38b..3e35875f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 6e4ded39..965c1eda 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 673cd7fb..87d4c8f3 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index bf7559a2..90bfb1a4 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index c249f07e..462fcd14 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 187bb64a..c1c28a41 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 55f8efbf..36c6d461 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index da2455d7..eff3376b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 5202a8a5..fe745857 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 5985fb5e..d1bfdf35 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 713326e2..07ce6e69 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4a3d2624..e7726f2c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index aeb085e0..98dc39de 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7f04f698..a199f800 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0915 + 1.9.0-preview0916 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From fd8ed29c028c2d729a92ad1510eb7aacedc12792 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 16 Sep 2020 13:54:04 +0800 Subject: [PATCH 0900/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=AD=90?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=20Count/Max/Min/Avg/Sum=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E4=BA=86=20Limit(1)=20=E7=9A=84=20bug=EF=BC=9B#462?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 12 ++++-------- .../Dameng/Curd/DamengSelectTest.cs | 12 ++++-------- .../Default/Curd/OdbcSelectTest.cs | 8 ++++---- .../KingbaseES/Curd/KingbaseESSelectTest.cs | 12 ++++-------- .../MySql/Curd/MySqlSelectTest.cs | 12 ++++-------- .../Oracle/Curd/OracleSelectTest.cs | 12 ++++-------- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 12 ++++-------- .../SqlServer/Curd/SqlServerSelectTest.cs | 8 ++++---- .../FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs | 12 ++++-------- .../Firebird/Curd/FirebirdSelectTest.cs | 8 ++++---- .../MsAccess/Curd/MsAccessSelectTest.cs | 8 ++++---- .../FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 12 ++++-------- .../FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs | 14 +++++--------- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 12 ++++-------- .../ShenTong/Curd/ShenTongSelectTest.cs | 12 ++++-------- .../SqlServer/Curd/SqlServerSelectTest.cs | 8 ++++---- .../FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 12 ++++-------- FreeSql/Internal/CommonExpression.cs | 8 +++++++- 18 files changed, 76 insertions(+), 118 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index 3ab5e820..fbc94dee 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -929,8 +929,7 @@ namespace FreeSql.Tests.MySqlConnector count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -947,8 +946,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -965,8 +963,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -983,8 +980,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs index 7d20cdcb..d3fd2d50 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengSelectTest.cs @@ -855,8 +855,7 @@ namespace FreeSql.Tests.Odbc.Dameng count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -873,8 +872,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -891,8 +889,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -909,8 +906,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs index 1e44d9f8..67c0323c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Default/Curd/OdbcSelectTest.cs @@ -829,7 +829,7 @@ namespace FreeSql.Tests.Odbc.Default all = a, count = (long)select.As("b").Sum(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT sum(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -846,7 +846,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Min(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT min(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -863,7 +863,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Max(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT max(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -880,7 +880,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Avg(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT avg(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs index 5839a06f..d6b8bb72 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESSelectTest.cs @@ -820,8 +820,7 @@ namespace FreeSql.Tests.Odbc.KingbaseES count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - limit 1) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -838,8 +837,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - limit 1) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -856,8 +854,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - limit 1) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -874,8 +871,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - limit 1) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index b5752d54..871d4408 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -940,8 +940,7 @@ namespace FreeSql.Tests.Odbc.MySql count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -958,8 +957,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -976,8 +974,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -994,8 +991,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index e7c817c8..6c7bb950 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -856,8 +856,7 @@ namespace FreeSql.Tests.Odbc.Oracle count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -874,8 +873,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -892,8 +890,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -910,8 +907,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs index cd197462..d1883cf9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -916,8 +916,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT sum(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -934,8 +933,7 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT min(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -952,8 +950,7 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT max(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -970,8 +967,7 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT avg(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs index 7d4f9edd..20fda333 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerSelectTest.cs @@ -810,7 +810,7 @@ namespace FreeSql.Tests.Odbc.SqlServer all = a, count = (long)select.As("b").Sum(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT sum(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -827,7 +827,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Min(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT min(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -844,7 +844,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Max(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT max(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -861,7 +861,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Avg(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT avg(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index 3eefc1ef..7eebc719 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -859,8 +859,7 @@ namespace FreeSql.Tests.Dameng count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -877,8 +876,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -895,8 +893,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -913,8 +910,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs index bf5b6c9c..04e9a3d3 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdSelectTest.cs @@ -855,7 +855,7 @@ namespace FreeSql.Tests.Firebird all = a, count = (long)select.As("b").Sum(b => b.Id) }); - Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT FIRST 1 sum(b.""ID"") + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new @@ -872,7 +872,7 @@ FROM ""TB_TOPIC22"" a", subquery); all = a, count = select.As("b").Min(b => b.Id) }); - Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT FIRST 1 min(b.""ID"") + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new @@ -889,7 +889,7 @@ FROM ""TB_TOPIC22"" a", subquery); all = a, count = select.As("b").Max(b => b.Id) }); - Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT FIRST 1 max(b.""ID"") + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new @@ -906,7 +906,7 @@ FROM ""TB_TOPIC22"" a", subquery); all = a, count = select.As("b").Avg(b => b.Id) }); - Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT FIRST 1 avg(b.""ID"") + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs index f1b932d9..17b9102f 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessSelectTest.cs @@ -830,7 +830,7 @@ namespace FreeSql.Tests.MsAccess all = a, count = (long)select.As("b").Sum(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 sum(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT sum(b.[Id]) FROM [tb_topic22] b) as as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -847,7 +847,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Min(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 min(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT min(b.[Id]) FROM [tb_topic22] b) as as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -864,7 +864,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Max(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 max(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT max(b.[Id]) FROM [tb_topic22] b) as as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -881,7 +881,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Avg(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT TOP 1 avg(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as as1, a.[Clicks] as as2, a.[TypeGuid] as as3, a.[Title] as as4, a.[CreateTime] as as5, (SELECT avg(b.[Id]) FROM [tb_topic22] b) as as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 3dc86b69..3eb3d8c3 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -992,8 +992,7 @@ LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT sum(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -1010,8 +1009,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT min(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -1028,8 +1026,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT max(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { @@ -1046,8 +1043,7 @@ FROM `tb_topic` a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, (SELECT avg(b.`Id`) - FROM `tb_topic` b - limit 0,1) as6 + FROM `tb_topic` b) as6 FROM `tb_topic` a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 4b478551..14ff9c76 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -856,8 +856,7 @@ namespace FreeSql.Tests.Oracle count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -874,8 +873,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -892,8 +890,7 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -910,10 +907,9 @@ FROM ""TB_TOPIC22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC22"" b - WHERE ROWNUM < 2) as6 + FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); - var subqueryList = select.ToList(a => new + var subqueryList = select.Limit(100).ToList(a => new { all = a, count = select.As("b").Avg(b => b.Id) diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 472df22f..a522d1e3 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -933,8 +933,7 @@ namespace FreeSql.Tests.PostgreSQL count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT sum(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -951,8 +950,7 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT min(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -969,8 +967,7 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT max(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { @@ -987,8 +984,7 @@ FROM ""tb_topic"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, (SELECT avg(b.""id"") - FROM ""tb_topic"" b - limit 1) as6 + FROM ""tb_topic"" b) as6 FROM ""tb_topic"" a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs index fed62921..b6a31412 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongSelectTest.cs @@ -934,8 +934,7 @@ namespace FreeSql.Tests.ShenTong count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT sum(b.""ID"") - FROM ""TB_TOPIC"" b - limit 1) as6 + FROM ""TB_TOPIC"" b) as6 FROM ""TB_TOPIC"" a", subquery); var subqueryList = select.ToList(a => new { @@ -952,8 +951,7 @@ FROM ""TB_TOPIC"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT min(b.""ID"") - FROM ""TB_TOPIC"" b - limit 1) as6 + FROM ""TB_TOPIC"" b) as6 FROM ""TB_TOPIC"" a", subquery); var subqueryList = select.ToList(a => new { @@ -970,8 +968,7 @@ FROM ""TB_TOPIC"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT max(b.""ID"") - FROM ""TB_TOPIC"" b - limit 1) as6 + FROM ""TB_TOPIC"" b) as6 FROM ""TB_TOPIC"" a", subquery); var subqueryList = select.ToList(a => new { @@ -988,8 +985,7 @@ FROM ""TB_TOPIC"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") - FROM ""TB_TOPIC"" b - limit 1) as6 + FROM ""TB_TOPIC"" b) as6 FROM ""TB_TOPIC"" a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index 2f9398d8..b8651287 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -866,7 +866,7 @@ namespace FreeSql.Tests.SqlServer all = a, count = (long)select.As("b").Sum(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 sum(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT sum(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -883,7 +883,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Min(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 min(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT min(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -900,7 +900,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Max(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 max(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT max(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new @@ -917,7 +917,7 @@ FROM [tb_topic22] a", subquery); all = a, count = select.As("b").Avg(b => b.Id) }); - Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT TOP 1 avg(b.[Id]) + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, (SELECT avg(b.[Id]) FROM [tb_topic22] b) as6 FROM [tb_topic22] a", subquery); var subqueryList = select.ToList(a => new diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 9216cbcc..b2d9a63d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -837,8 +837,7 @@ namespace FreeSql.Tests.Sqlite count = (long)select.As("b").Sum(b => b.Id) }); Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT sum(b.""Id"") - FROM ""tb_topic22"" b - limit 0,1) as6 + FROM ""tb_topic22"" b) as6 FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -855,8 +854,7 @@ FROM ""tb_topic22"" a", subquery); count = select.As("b").Min(b => b.Id) }); Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT min(b.""Id"") - FROM ""tb_topic22"" b - limit 0,1) as6 + FROM ""tb_topic22"" b) as6 FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -873,8 +871,7 @@ FROM ""tb_topic22"" a", subquery); count = select.As("b").Max(b => b.Id) }); Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT max(b.""Id"") - FROM ""tb_topic22"" b - limit 0,1) as6 + FROM ""tb_topic22"" b) as6 FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { @@ -891,8 +888,7 @@ FROM ""tb_topic22"" a", subquery); count = select.As("b").Avg(b => b.Id) }); Assert.Equal(@"SELECT a.""Id"" as1, a.""Clicks"" as2, a.""TypeGuid"" as3, a.""Title"" as4, a.""CreateTime"" as5, (SELECT avg(b.""Id"") - FROM ""tb_topic22"" b - limit 0,1) as6 + FROM ""tb_topic22"" b) as6 FROM ""tb_topic22"" a", subquery); var subqueryList = select.ToList(a => new { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 7d5c22c0..3096b6f4 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -921,7 +921,13 @@ namespace FreeSql.Internal fsqlType = fsql?.GetType(); if (fsqlType == null) break; var fsqlSelect0 = fsql as Select0Provider; - if (exp3.Method.Name != "ToList") fsqlSelect0._limit = 1; + switch (exp3.Method.Name) { + case "Any": //exists + case "ToOne": + case "First": + fsqlSelect0._limit = 1; //#462 + break; + } if (tsc.dbParams != null) fsqlSelect0._params = tsc.dbParams; fsqltables = fsqlSelect0._tables; //fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}"; From e591c8d1f13c800fe031731fdc80d74a8a98828a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 16 Sep 2020 14:01:12 +0800 Subject: [PATCH 0901/1029] v1.9.0-preview0917 #462 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7cb668d9..f655633a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 02389cdc..658763c4 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index eefac104..c473acb9 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 3d10d3f3..abe2051d 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index c6400c6a..d96846bd 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0916 + 1.9.0-preview0917 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 20b5b94d..dc89fc2e 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ec6f85ef..a557ee2c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 6d7dcc6c..0b8108df 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3e35875f..97993f10 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 965c1eda..8c903d9f 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 87d4c8f3..9d6adad8 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 90bfb1a4..401c396c 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 462fcd14..9aeb3268 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index c1c28a41..e8e11dda 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 36c6d461..0f057afd 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index eff3376b..bc4d072c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index fe745857..b625abc1 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d1bfdf35..c6280d45 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 07ce6e69..fcfa54c2 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index e7726f2c..f4fba588 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 98dc39de..549fee35 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a199f800..b25c1d93 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0916 + 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 194bff47b8d8cfcb9164d083fcdcd2b7ed48d0b7 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 16 Sep 2020 22:40:24 +0800 Subject: [PATCH 0902/1029] update csproj Description --- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a557ee2c..6a4693a5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -5,7 +5,7 @@ 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access https://github.com/2881099/FreeSql/wiki/DbContext FreeSql ORM DbContext git diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0b8108df..21e7e3cc 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -4,7 +4,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.9.0-preview0917 FreeSql;ncc;YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository true diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 97993f10..b3fdbcf0 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -5,7 +5,7 @@ 1.9.0-preview0917 true FreeSql;ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Odbc, 达梦, 人大金仓, 神舟通用, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git From 4c26fa414c1127aa878a34c38e481b0f2df82922 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 17 Sep 2020 13:24:54 +0800 Subject: [PATCH 0903/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IAdo.Query?= =?UTF-8?q?=20=E8=BF=94=E5=9B=9E=E5=AE=9E=E4=BD=93=E4=B8=AD=E5=B8=A6?= =?UTF-8?q?=E6=9C=89=E5=BB=B6=E6=97=B6=E5=AF=BC=E8=88=AA=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=EF=BC=8C=E8=AF=BB=E5=8F=96=E9=A1=BA=E5=BA=8F=E4=B8=8D=E5=AF=B9?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 +++++++ FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index c73f7235..48d30256 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -91,9 +91,10 @@ namespace FreeSql.Internal.CommonProvider internal Dictionary GetQueryTypeProperties(Type type) { - var tb = _util.GetTableByEntity(type); - var props = tb?.Properties ?? type.GetPropertiesDictIgnoreCase(); - return props; + return type.GetPropertiesDictIgnoreCase(); //与 ExecuteArrayRowReadClassOrTuple 顺序同步,防止【延时属性】获取到位置不对的问题 + //var tb = _util.GetTableByEntity(type); + //var props = tb?.Properties ?? type.GetPropertiesDictIgnoreCase(); + //return props; } public bool ExecuteConnectTest() From 65f9be0b27b87be5c0d278c21c66644cdf9e4513 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 17 Sep 2020 13:36:33 +0800 Subject: [PATCH 0904/1029] v1.9.0-preview0918 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 346 ++++++++++-------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 24 files changed, 218 insertions(+), 181 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index f655633a..02769a71 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 658763c4..b5660e64 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c473acb9..4d96a44f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index abe2051d..cb43529e 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d96846bd..573b7531 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0917 + 1.9.0-preview0918 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index dc89fc2e..19a80ec1 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 6a4693a5..f7f8d865 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 21e7e3cc..7cbb85ca 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b3fdbcf0..769ebf5c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8869f42b..8e952c15 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2898,153 +2898,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3814,12 +3667,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3890,12 +3737,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4506,3 +4347,190 @@ +ons.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 8c903d9f..35edeb87 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 9d6adad8..83a7cb62 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 401c396c..47405e6d 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 9aeb3268..e392d7f7 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e8e11dda..5fe907f8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0f057afd..54414244 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index bc4d072c..6ff0b114 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b625abc1..1692c540 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index c6280d45..97f20d2a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index fcfa54c2..e39fbf86 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index f4fba588..eee937a3 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 549fee35..b2af2ea2 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index b25c1d93..670eb3c0 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0917 + 1.9.0-preview0918 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From c4b3487274abfe1610f3117608fec4016776a848 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 17 Sep 2020 14:07:00 +0800 Subject: [PATCH 0905/1029] add Contributors --- readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 06695cc2..4e85ca24 100644 --- a/readme.md +++ b/readme.md @@ -181,7 +181,8 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [hd2y](https://github.com/hd2y)、 [tky753](https://github.com/tky753)、 [feijie999](https://github.com/feijie999)、 -constantine +constantine、 +[JohnZhou2020](https://github.com/JohnZhou2020) QQ群:4336577(已满)、8578575(在线)、52508226(在线) From 39334710b68f2ec231dec44a2ba4e9df036f7617 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 17 Sep 2020 17:42:21 +0800 Subject: [PATCH 0906/1029] add Donation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 4e85ca24..09f208b0 100644 --- a/readme.md +++ b/readme.md @@ -189,7 +189,7 @@ QQ群:4336577(已满)、8578575(在线)、52508226(在线) ## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 -无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元 +无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元、建爽 66元 > Thank you for your donation From 0718be20472ec91d88c80f61c66a26ee59aa8bd3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 18 Sep 2020 06:35:33 +0800 Subject: [PATCH 0907/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20SqlExt.Sum/M?= =?UTF-8?q?ax/Min/Avg=20=E5=90=8C=E6=97=B6=E6=94=AF=E6=8C=81=E5=BC=80?= =?UTF-8?q?=E7=AA=97=E6=88=96=E6=99=AE=E9=80=9A=E8=81=9A=E5=90=88=E5=87=BD?= =?UTF-8?q?=E6=95=B0=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 | 13 + .../FreeSqlGlobalExpressionCallExtensions.cs | 9 +- FreeSql/FreeSql.xml | 346 ++++++++---------- 4 files changed, 178 insertions(+), 206 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 1f3ef8df..003bd4d2 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -177,6 +177,17 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var sqlextMax112 = g.sqlserver.Select() + .GroupBy(a => a.Id) + .ToSql(a => new + { + Id = a.Key, + EdiId1 = SqlExt.Max(a.Key).Over().PartitionBy(new { a.Value.EdiId, a.Value.Id }).OrderByDescending(new { a.Value.EdiId, a.Value.Id }).ToValue(), + EdiId2 = SqlExt.Max(a.Key).Over().PartitionBy(a.Value.EdiId).OrderByDescending(a.Value.Id).ToValue(), + EdiId3 = SqlExt.Sum(a.Key).ToValue(), + EdiId4 = a.Sum(a.Key) + }); + Assert.Throws(() => g.sqlite.Update().SetSource(new testUpdateNonePk()).ExecuteAffrows()); g.sqlite.Insert(new testInsertNullable()).NoneParameter().ExecuteAffrows(); @@ -304,6 +315,8 @@ INNER JOIN ""userinfo"" p ON p.""userid"" = o.""userid""", select16Sql2); Id = a.Key, EdiId1 = SqlExt.Max(a.Key).Over().PartitionBy(new { a.Value.EdiId, a.Value.Id }).OrderByDescending(new { a.Value.EdiId, a.Value.Id }).ToValue(), EdiId2 = SqlExt.Max(a.Key).Over().PartitionBy(a.Value.EdiId).OrderByDescending(a.Value.Id).ToValue(), + EdiId3 = SqlExt.Sum(a.Key).ToValue(), + EdiId4 = a.Sum(a.Key) }); var sqlextIsNull = g.sqlserver.Select() diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index d534c527..9540c72a 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -152,6 +152,7 @@ namespace FreeSql internal class ExpSbInfo { public StringBuilder Sb { get; } = new StringBuilder(); + public bool IsOver = false; public bool IsOrderBy = false; public bool IsDistinct = false; } @@ -161,12 +162,13 @@ namespace FreeSql { if (expSb.Value == null) expSb.Value = new List(); expSb.Value.Add(new ExpSbInfo()); - expSbLast.Sb.Append(sqlFunc).Append(" "); + expSbLast.Sb.Append(sqlFunc); return null; } public static ISqlOver Over(this ISqlOver that) { - expSbLast.Sb.Append("over("); + expSbLast.Sb.Append(" over("); + expSbLast.IsOver = true; return that; } public static ISqlOver PartitionBy(this ISqlOver that, object column) @@ -218,9 +220,10 @@ namespace FreeSql public static TValue ToValue(this ISqlOver that) { var sql = expSbLast.Sb.ToString().TrimEnd(','); + if (expSbLast.IsOver) sql = $"{sql})"; expSbLast.Sb.Clear(); expSb.Value.RemoveAt(expSb.Value.Count - 1); - expContext.Result = $"{sql})"; + expContext.Result = sql; return default; } public interface ISqlOver { } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8e952c15..8869f42b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2898,6 +2898,153 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3667,6 +3814,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3737,6 +3890,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4347,190 +4506,3 @@ -ons.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 条件 - - - - From 8f9efe1f11aa5c744ef24313509fc189d366d2aa Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 18 Sep 2020 09:00:01 +0800 Subject: [PATCH 0908/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect/IIns?= =?UTF-8?q?ert/IUpdate/IDelete=20CommandTimeout=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=91=BD=E4=BB=A4=E8=B6=85=E6=97=B6=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql/FreeSql.xml | 41 ++++- FreeSql/Interface/Curd/IDelete.cs | 6 + FreeSql/Interface/Curd/IInsert.cs | 6 + FreeSql/Interface/Curd/IInsertOrUpdate.cs | 6 + FreeSql/Interface/Curd/ISelect/ISelect0.cs | 6 + FreeSql/Interface/Curd/IUpdate.cs | 6 + FreeSql/Interface/IAdo.cs | 54 +++--- .../CommonProvider/AdoProvider/AdoProvider.cs | 171 +++++++++--------- .../AdoProvider/AdoProviderAsync.cs | 171 +++++++++--------- .../Internal/CommonProvider/DeleteProvider.cs | 8 +- .../CommonProvider/DeleteProviderAsync.cs | 2 +- .../CommonProvider/InsertOrUpdateProvider.cs | 10 +- .../Internal/CommonProvider/InsertProvider.cs | 8 +- .../CommonProvider/InsertProviderAsync.cs | 2 +- .../SelectProvider/Select0Provider.cs | 6 + .../SelectProvider/Select0ProviderReader.cs | 32 ++-- .../SelectProvider/SelectGroupingProvider.cs | 4 +- .../Internal/CommonProvider/UpdateProvider.cs | 8 +- .../CommonProvider/UpdateProviderAsync.cs | 2 +- .../Curd/DamengInsert.cs | 8 +- .../Curd/FirebirdDelete.cs | 4 +- .../Curd/FirebirdInsert.cs | 12 +- .../Curd/FirebirdUpdate.cs | 4 +- .../Curd/KingbaseESDelete.cs | 4 +- .../Curd/KingbaseESInsert.cs | 12 +- .../Curd/KingbaseESOnConflictDoUpdate.cs | 4 +- .../Curd/KingbaseESUpdate.cs | 4 +- .../Curd/MsAccessInsert.cs | 20 +- .../Curd/MySqlDelete.cs | 4 +- .../Curd/MySqlInsert.cs | 8 +- .../Curd/MySqlUpdate.cs | 4 +- .../Curd/OnDuplicateKeyUpdate.cs | 4 +- .../Dameng/Curd/OdbcDamengInsert.cs | 8 +- .../Default/Curd/OdbcInsert.cs | 8 +- .../KingbaseES/Curd/OdbcKingbaseESDelete.cs | 4 +- .../KingbaseES/Curd/OdbcKingbaseESInsert.cs | 12 +- .../Curd/OdbcKingbaseESOnConflictDoUpdate.cs | 4 +- .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 4 +- .../MySql/Curd/OdbcMySqlDelete.cs | 4 +- .../MySql/Curd/OdbcMySqlInsert.cs | 14 +- .../Curd/OdbcMySqlOnDuplicateKeyUpdate.cs | 4 +- .../MySql/Curd/OdbcMySqlUpdate.cs | 4 +- .../Oracle/Curd/OdbcOracleInsert.cs | 8 +- .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 12 +- .../Curd/OdbcPostgreSQLOnConflictDoUpdate.cs | 4 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 4 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 8 +- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 4 +- .../Curd/OracleInsert.cs | 8 +- .../Curd/OnConflictDoUpdate.cs | 4 +- .../Curd/PostgreSQLDelete.cs | 4 +- .../Curd/PostgreSQLInsert.cs | 12 +- .../Curd/PostgreSQLUpdate.cs | 4 +- .../Curd/ShenTongDelete.cs | 4 +- .../Curd/ShenTongInsert.cs | 12 +- .../Curd/ShenTongUpdate.cs | 4 +- .../Curd/SqlServerDelete.cs | 4 +- .../Curd/SqlServerInsert.cs | 8 +- .../Curd/SqlServerUpdate.cs | 4 +- .../Curd/SqliteInsert.cs | 4 +- 63 files changed, 471 insertions(+), 363 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8869f42b..79039cd6 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1267,6 +1267,13 @@ + + + 命令超时设置(秒) + + + + lambda表达式条件,仅支持实体基础成员(不包含导航对象) @@ -1369,6 +1376,13 @@ + + + 命令超时设置(秒) + + + + 追加准备插入的实体 @@ -1517,6 +1531,13 @@ + + + 命令超时设置(秒) + + + + 添加或更新,设置实体 @@ -1603,6 +1624,13 @@ + + + 命令超时设置(秒) + + + + 审核或跟踪 ToList 即将返回的数据 @@ -2461,6 +2489,13 @@ + + + 命令超时设置(秒) + + + + 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 @@ -2751,12 +2786,13 @@ new { id = 1 } 或者 Dictionary<string, object> - + 测试数据库是否连接正确,本方法执行如下命令: MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 Oracle: SELECT 1 FROM dual + 命令超时设置(秒) true: 成功, false: 失败 @@ -2898,12 +2934,13 @@ - + 测试数据库是否连接正确,本方法执行如下命令: MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 Oracle: SELECT 1 FROM dual + 命令超时设置(秒) true: 成功, false: 失败 diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 09515f8a..de01bf23 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -21,6 +21,12 @@ namespace FreeSql /// /// IDelete WithConnection(DbConnection connection); + /// + /// 命令超时设置(秒) + /// + /// + /// + IDelete CommandTimeout(int timeout); /// /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 739c046d..234495ae 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -23,6 +23,12 @@ namespace FreeSql /// /// IInsert WithConnection(DbConnection connection); + /// + /// 命令超时设置(秒) + /// + /// + /// + IInsert CommandTimeout(int timeout); /// /// 追加准备插入的实体 diff --git a/FreeSql/Interface/Curd/IInsertOrUpdate.cs b/FreeSql/Interface/Curd/IInsertOrUpdate.cs index 53698f3f..0299d065 100644 --- a/FreeSql/Interface/Curd/IInsertOrUpdate.cs +++ b/FreeSql/Interface/Curd/IInsertOrUpdate.cs @@ -21,6 +21,12 @@ namespace FreeSql /// /// IInsertOrUpdate WithConnection(DbConnection connection); + /// + /// 命令超时设置(秒) + /// + /// + /// + IInsertOrUpdate CommandTimeout(int timeout); /// /// 添加或更新,设置实体 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 3e7fee26..7180b408 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -39,6 +39,12 @@ namespace FreeSql /// /// TSelect WithConnection(DbConnection connection); + /// + /// 命令超时设置(秒) + /// + /// + /// + TSelect CommandTimeout(int timeout); /// /// 审核或跟踪 ToList 即将返回的数据 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 49acf355..ed4ece43 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -22,6 +22,12 @@ namespace FreeSql /// /// IUpdate WithConnection(DbConnection connection); + /// + /// 命令超时设置(秒) + /// + /// + /// + IUpdate CommandTimeout(int timeout); /// /// 不使用参数化,可通过 IFreeSql.CodeFirst.IsNotCommandParameter 全局性设置 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 238bfc04..a0e5dde9 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -67,8 +67,9 @@ namespace FreeSql /// MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 /// Oracle: SELECT 1 FROM dual /// + /// 命令超时设置(秒) /// true: 成功, false: 失败 - bool ExecuteConnectTest(); + bool ExecuteConnectTest(int commandTimeout = 0); /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 @@ -79,7 +80,7 @@ namespace FreeSql /// void ExecuteReader(Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -96,7 +97,7 @@ namespace FreeSql /// object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -114,7 +115,7 @@ namespace FreeSql /// DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -132,7 +133,7 @@ namespace FreeSql /// DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -151,7 +152,7 @@ namespace FreeSql /// int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -170,7 +171,7 @@ namespace FreeSql /// object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -192,8 +193,8 @@ namespace FreeSql /// List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -216,7 +217,7 @@ namespace FreeSql /// NativeTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); NativeTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -231,19 +232,19 @@ namespace FreeSql NativeTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); NativeTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); NativeTuple, List, List> Query(string cmdText, object parms = null); NativeTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); NativeTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); NativeTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); NativeTuple, List, List, List> Query(string cmdText, object parms = null); NativeTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); NativeTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); NativeTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); NativeTuple, List, List, List, List> Query(string cmdText, object parms = null); NativeTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null); NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); @@ -256,8 +257,9 @@ namespace FreeSql /// MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 /// Oracle: SELECT 1 FROM dual /// + /// 命令超时设置(秒) /// true: 成功, false: 失败 - Task ExecuteConnectTestAsync(); + Task ExecuteConnectTestAsync(int commandTimeout = 0); /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 @@ -268,7 +270,7 @@ namespace FreeSql /// Task ExecuteReaderAsync(Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -285,7 +287,7 @@ namespace FreeSql /// Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -303,7 +305,7 @@ namespace FreeSql /// Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -321,7 +323,7 @@ namespace FreeSql /// Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -340,7 +342,7 @@ namespace FreeSql /// Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -359,7 +361,7 @@ namespace FreeSql /// Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -381,8 +383,8 @@ namespace FreeSql /// Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -405,7 +407,7 @@ namespace FreeSql /// Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -420,19 +422,19 @@ namespace FreeSql Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); Task, List, List>> QueryAsync(string cmdText, object parms = null); Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); Task, List, List, List>> QueryAsync(string cmdText, object parms = null); Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null); Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 48d30256..f38845ba 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -97,7 +97,7 @@ namespace FreeSql.Internal.CommonProvider //return props; } - public bool ExecuteConnectTest() + public bool ExecuteConnectTest(int commandTimeout = 0) { try { @@ -105,13 +105,13 @@ namespace FreeSql.Internal.CommonProvider { case DataType.Oracle: case DataType.OdbcOracle: - ExecuteNonQuery(" SELECT 1 FROM dual"); + ExecuteNonQuery(null, null, CommandType.Text, " SELECT 1 FROM dual", commandTimeout); return true; case DataType.Firebird: - ExecuteNonQuery(" SELECT FIRST 1 1 FROM rdb$database"); + ExecuteNonQuery(null, null, CommandType.Text, " SELECT FIRST 1 1 FROM rdb$database", commandTimeout); return true; } - ExecuteNonQuery(" SELECT 1"); + ExecuteNonQuery(null, null, CommandType.Text, " SELECT 1", commandTimeout); return true; } catch @@ -120,13 +120,13 @@ namespace FreeSql.Internal.CommonProvider } } - public List Query(string cmdText, object parms = null) => Query(null, null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(null, connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, null, cmdType, cmdText, cmdParms); - public List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, transaction, cmdType, cmdText, cmdParms); - public List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, connection, transaction, cmdType, cmdText, cmdParms); - public List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public List Query(string cmdText, object parms = null) => Query(null, null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(null, connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, null, cmdType, cmdText, 0, cmdParms); + public List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, transaction, cmdType, cmdText, 0, cmdParms); + public List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) => Query(null, connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms); + public List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { var ret = new List(); if (string.IsNullOrEmpty(cmdText)) return ret; @@ -152,16 +152,16 @@ namespace FreeSql.Internal.CommonProvider flag = sbflag.ToString(); } ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, fetch.Object, 0, _util).Value); - }, cmdType, cmdText, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms); return ret; } #region query multi - public NativeTuple, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public NativeTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NativeTuple, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, 0, cmdParms); + public NativeTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, 0, cmdParms); + public NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List()); var ret1 = new List(); @@ -214,16 +214,16 @@ namespace FreeSql.Internal.CommonProvider ret2.Add((T2)Utils.ExecuteArrayRowReadClassOrTuple(flag2, type2, indexes2, fetch.Object, 0, _util).Value); break; } - }, null, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms); return NativeTuple.Create(ret1, ret2); } - public NativeTuple, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public NativeTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NativeTuple, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, 0, cmdParms); + public NativeTuple, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, 0, cmdParms); + public NativeTuple, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List()); var ret1 = new List(); @@ -299,16 +299,16 @@ namespace FreeSql.Internal.CommonProvider ret3.Add((T3)Utils.ExecuteArrayRowReadClassOrTuple(flag3, type3, indexes3, fetch.Object, 0, _util).Value); break; } - }, null, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms); return NativeTuple.Create(ret1, ret2, ret3); } - public NativeTuple, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public NativeTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NativeTuple, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, 0, cmdParms); + public NativeTuple, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, 0, cmdParms); + public NativeTuple, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List()); var ret1 = new List(); @@ -407,16 +407,16 @@ namespace FreeSql.Internal.CommonProvider ret4.Add((T4)Utils.ExecuteArrayRowReadClassOrTuple(flag4, type4, indexes4, fetch.Object, 0, _util).Value); break; } - }, null, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms); return NativeTuple.Create(ret1, ret2, ret3, ret4); } - public NativeTuple, List, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public NativeTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, cmdParms); - public NativeTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, cmdParms); - public NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public NativeTuple, List, List, List, List> Query(string cmdText, object parms = null) => Query(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List, List> Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public NativeTuple, List, List, List, List> Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, null, cmdType, cmdText, 0, cmdParms); + public NativeTuple, List, List, List, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, transaction, cmdType, cmdText, 0, cmdParms); + public NativeTuple, List, List, List, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List(), new List()); var ret1 = new List(); @@ -538,18 +538,18 @@ namespace FreeSql.Internal.CommonProvider ret5.Add((T5)Utils.ExecuteArrayRowReadClassOrTuple(flag5, type5, indexes5, fetch.Object, 0, _util).Value); break; } - }, null, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms); return NativeTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion - public void ExecuteReader(Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(null, null, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(null, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(connection, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, fetchHandler, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, fetchHandler, cmdType, cmdText, cmdParms); - public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdParms); - void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action, int> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public void ExecuteReader(Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(null, null, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(null, transaction, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, string cmdText, object parms = null) => ExecuteReader(connection, transaction, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public void ExecuteReader(Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms); + public void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms); + public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms); + void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action, int> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -579,7 +579,7 @@ namespace FreeSql.Internal.CommonProvider } Object conn = null; - var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); if (IsTracePerformance) { logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); @@ -612,7 +612,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - ExecuteReaderMultiple(multipleResult, connection, transaction, fetchHandler, schemaHandler, cmdType, cmdText, cmdParms); + ExecuteReaderMultiple(multipleResult, connection, transaction, fetchHandler, schemaHandler, cmdType, cmdText, cmdTimeout, cmdParms); return; } } @@ -681,12 +681,12 @@ namespace FreeSql.Internal.CommonProvider pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); } - public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, null, cmdType, cmdText, cmdParms); - public object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, transaction, cmdType, cmdText, cmdParms); - public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, null, cmdType, cmdText, 0, cmdParms); + public object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, transaction, cmdType, cmdText, 0, cmdParms); + public object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { List ret = new List(); ExecuteReader(connection, transaction, fetch => @@ -694,15 +694,15 @@ namespace FreeSql.Internal.CommonProvider object[] values = new object[fetch.Object.FieldCount]; fetch.Object.GetValues(values); ret.Add(values); - }, cmdType, cmdText, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms); return ret.ToArray(); } - public DataSet ExecuteDataSet(string cmdText, object parms = null) => ExecuteDataSet(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataSet ExecuteDataSet(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSet(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSet(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSet(null, null, cmdType, cmdText, cmdParms); - public DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSet(null, transaction, cmdType, cmdText, cmdParms); - public DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public DataSet ExecuteDataSet(string cmdText, object parms = null) => ExecuteDataSet(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public DataSet ExecuteDataSet(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSet(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSet(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSet(null, null, cmdType, cmdText, 0, cmdParms); + public DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSet(null, transaction, cmdType, cmdText, 0, cmdParms); + public DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { var ret = new DataSet(); DataTable dt = null; @@ -720,15 +720,15 @@ namespace FreeSql.Internal.CommonProvider if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; dt.Columns.Add(name, dr.GetFieldType(a)); } - }, cmdType, cmdText, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms); return ret; } - public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataTable ExecuteDataTable(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, null, cmdType, cmdText, cmdParms); - public DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, transaction, cmdType, cmdText, cmdParms); - public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public DataTable ExecuteDataTable(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, null, cmdType, cmdText, 0, cmdParms); + public DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, transaction, cmdType, cmdText, 0, cmdParms); + public DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { var ret = new DataTable(); ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => @@ -744,22 +744,22 @@ namespace FreeSql.Internal.CommonProvider if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; ret.Columns.Add(name, dr.GetFieldType(a)); } - }, cmdType, cmdText, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms); return ret; } - public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public int ExecuteNonQuery(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, null, cmdType, cmdText, cmdParms); - public int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, transaction, cmdType, cmdText, cmdParms); - public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public int ExecuteNonQuery(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, null, cmdType, cmdText, 0, cmdParms); + public int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, transaction, cmdType, cmdText, 0, cmdParms); + public int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return 0; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); int val = 0; Exception ex = null; try @@ -783,19 +783,19 @@ namespace FreeSql.Internal.CommonProvider if (DataType == DataType.Sqlite) pc.cmd.Dispose(); return val; } - public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object ExecuteScalar(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object ExecuteScalar(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, null, cmdType, cmdText, cmdParms); - public object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, transaction, cmdType, cmdText, cmdParms); - public object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public object ExecuteScalar(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public object ExecuteScalar(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, null, cmdType, cmdText, 0, cmdParms); + public object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, transaction, cmdType, cmdText, 0, cmdParms); + public object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return null; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); object val = null; Exception ex = null; try @@ -832,13 +832,14 @@ namespace FreeSql.Internal.CommonProvider this.isclose = isclose; } } - PrepareCommandResult PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) + PrepareCommandResult PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, StringBuilder logtxt) { var dt = DateTime.Now; DbCommand cmd = CreateCommand(); bool isclose = false; cmd.CommandType = cmdType; cmd.CommandText = cmdText; + if (cmdTimeout > 0) cmd.CommandTimeout = cmdTimeout; if (cmdParms != null) { diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 64adc306..1ff333fb 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -14,7 +14,7 @@ namespace FreeSql.Internal.CommonProvider { partial class AdoProvider { - async public Task ExecuteConnectTestAsync() + async public Task ExecuteConnectTestAsync(int commandTimeout = 0) { try { @@ -22,13 +22,13 @@ namespace FreeSql.Internal.CommonProvider { case DataType.Oracle: case DataType.OdbcOracle: - await ExecuteNonQueryAsync(" SELECT 1 FROM dual"); + await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT 1 FROM dual", commandTimeout); return true; case DataType.Firebird: - await ExecuteNonQueryAsync(" SELECT FIRST 1 1 FROM rdb$database"); + await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT FIRST 1 1 FROM rdb$database", commandTimeout); return true; } - await ExecuteNonQueryAsync(" SELECT 1"); + await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT 1", commandTimeout); return true; } catch @@ -37,13 +37,13 @@ namespace FreeSql.Internal.CommonProvider } } - public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, null, cmdType, cmdText, cmdParms); - public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, transaction, cmdType, cmdText, cmdParms); - public Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, connection, transaction, cmdType, cmdText, cmdParms); - async public Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, null, cmdType, cmdText, 0, cmdParms); + public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, transaction, cmdType, cmdText, 0, cmdParms); + public Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) => QueryAsync(null, connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms); + async public Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { var ret = new List(); if (string.IsNullOrEmpty(cmdText)) return ret; @@ -70,16 +70,16 @@ namespace FreeSql.Internal.CommonProvider } ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, fetch.Object, 0, _util).Value); return Task.FromResult(false); - }, cmdType, cmdText, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms); return ret; } #region QueryAsync multi - public Task, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List()); var ret1 = new List(); @@ -133,16 +133,16 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, null, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms); return NativeTuple.Create(ret1, ret2); } - public Task, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List()); var ret1 = new List(); @@ -219,16 +219,16 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, null, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms); return NativeTuple.Create(ret1, ret2, ret3); } - public Task, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List()); var ret1 = new List(); @@ -328,16 +328,16 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, null, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms); return NativeTuple.Create(ret1, ret2, ret3, ret4); } - public Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List(), new List()); var ret1 = new List(); @@ -460,18 +460,18 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, null, cmdType, cmdText, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms); return NativeTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion - public Task ExecuteReaderAsync(Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, fetchHandler, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, cmdParms); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdParms); - async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteReaderAsync(Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteReaderAsync(Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms); + public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms); + async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -501,7 +501,7 @@ namespace FreeSql.Internal.CommonProvider } Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); if (IsTracePerformance) { logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); @@ -534,7 +534,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, fetchHandler, schemaHandler, cmdType, cmdText, cmdParms); + await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, fetchHandler, schemaHandler, cmdType, cmdText, cmdTimeout, cmdParms); return; } } @@ -600,12 +600,12 @@ namespace FreeSql.Internal.CommonProvider pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); } - public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { List ret = new List(); await ExecuteReaderAsync(connection, transaction, async fetch => @@ -613,16 +613,16 @@ namespace FreeSql.Internal.CommonProvider object[] values = new object[fetch.Object.FieldCount]; for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); ret.Add(values); - }, cmdType, cmdText, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms); return ret.ToArray(); } - public Task ExecuteDataSetAsync(string cmdText, object parms = null) => ExecuteDataSetAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteDataSetAsync(string cmdText, object parms = null) => ExecuteDataSetAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { var ret = new DataSet(); DataTable dt = null; @@ -640,15 +640,15 @@ namespace FreeSql.Internal.CommonProvider if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; dt.Columns.Add(name, dr.GetFieldType(a)); } - }, cmdType, cmdText, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms); return ret; } - public Task ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { var ret = new DataTable(); await ExecuteReaderMultipleAsync(1, connection, transaction, async (fetch, result) => @@ -664,22 +664,22 @@ namespace FreeSql.Internal.CommonProvider if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; ret.Columns.Add(name, dr.GetFieldType(a)); } - }, cmdType, cmdText, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms); return ret; } - public Task ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return 0; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); int val = 0; Exception ex = null; try @@ -703,19 +703,19 @@ namespace FreeSql.Internal.CommonProvider if (DataType == DataType.Sqlite) pc.cmd.Dispose(); return val; } - public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(null, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(connection, transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, null, cmdType, cmdText, cmdParms); - public Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, transaction, cmdType, cmdText, cmdParms); - async public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) + public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, null, cmdType, cmdText, 0, cmdParms); + public Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, transaction, cmdType, cmdText, 0, cmdParms); + async public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) { if (string.IsNullOrEmpty(cmdText)) return null; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt); + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); object val = null; Exception ex = null; try @@ -740,13 +740,14 @@ namespace FreeSql.Internal.CommonProvider return val; } - async Task PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) + async Task PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, StringBuilder logtxt) { DateTime dt = DateTime.Now; DbCommand cmd = CreateCommand(); bool isclose = false; cmd.CommandType = cmdType; cmd.CommandText = cmdText; + if (cmdTimeout > 0) cmd.CommandTimeout = cmdTimeout; if (cmdParms != null) { diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 56b21f5a..338f4d99 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -24,6 +24,7 @@ namespace FreeSql.Internal.CommonProvider public List _params = new List(); public DbTransaction _transaction; public DbConnection _connection; + public int _commandTimeout = 0; public Action _interceptSql; public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) @@ -57,6 +58,11 @@ namespace FreeSql.Internal.CommonProvider _connection = connection; return this; } + public IDelete CommandTimeout(int timeout) + { + _commandTimeout = timeout; + return this; + } public int ExecuteAffrows() { @@ -69,7 +75,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs index 45afc9d5..380ee6f8 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs @@ -24,7 +24,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index efc2646c..ac621b0d 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -27,6 +27,7 @@ namespace FreeSql.Internal.CommonProvider public DbParameter[] _params; public DbTransaction _transaction; public DbConnection _connection; + public int _commandTimeout = 0; public ColumnInfo IdentityColumn { get; } public InsertOrUpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) @@ -57,6 +58,11 @@ namespace FreeSql.Internal.CommonProvider _connection = connection; return this; } + public IInsertOrUpdate CommandTimeout(int timeout) + { + _commandTimeout = timeout; + return this; + } public IInsertOrUpdate UpdateColumns(Expression> columns) => UpdateColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false, null)); public IInsertOrUpdate UpdateColumns(string[] columns) @@ -270,7 +276,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -296,7 +302,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 76d27e9c..3ede179a 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -31,6 +31,7 @@ namespace FreeSql.Internal.CommonProvider public DbParameter[] _params; public DbTransaction _transaction; public DbConnection _connection; + public int _commandTimeout = 0; public InsertProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { @@ -78,6 +79,11 @@ namespace FreeSql.Internal.CommonProvider _connection = connection; return this; } + public IInsert CommandTimeout(int timeout) + { + _commandTimeout = timeout; + return this; + } public IInsert InsertIdentity() { @@ -451,7 +457,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index 92f5ff79..0cc8ac76 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -264,7 +264,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index f803a212..9a67dc82 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -31,6 +31,7 @@ namespace FreeSql.Internal.CommonProvider public CommonExpression _commonExpression; public DbTransaction _transaction; public DbConnection _connection; + public int _commandTimeout = 0; public Action _trackToList; public List> _includeToList = new List>(); #if net40 @@ -155,6 +156,11 @@ namespace FreeSql.Internal.CommonProvider _connection = connection; return this as TSelect; } + public TSelect CommandTimeout(int timeout) + { + _commandTimeout = timeout; + return this as TSelect; + } public TSelect GroupBy(string sql, object parms = null) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 78014870..a347470a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -29,7 +29,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -56,7 +56,7 @@ namespace FreeSql.Internal.CommonProvider try { if (type.IsClass) - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); else { var flagStr = $"ToListField:{field}"; @@ -64,7 +64,7 @@ namespace FreeSql.Internal.CommonProvider { var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); ret.Add((TTuple)read.Value); - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } } catch (Exception ex) @@ -99,7 +99,7 @@ namespace FreeSql.Internal.CommonProvider other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null, retCount, null)); } retCount++; - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -166,7 +166,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var other in otherData) other.retlist.Clear(); } - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -234,7 +234,7 @@ namespace FreeSql.Internal.CommonProvider ret.Object.Clear(); } - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -279,7 +279,7 @@ namespace FreeSql.Internal.CommonProvider { var item = af.Read(_orm, fetch.Object); ret.Add(keySelector(item), elementSelector(item)); - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -314,7 +314,7 @@ namespace FreeSql.Internal.CommonProvider foreach (var other in otherData) other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null)); retCount++; - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -694,7 +694,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -734,7 +734,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -761,7 +761,7 @@ namespace FreeSql.Internal.CommonProvider try { if (type.IsClass) - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); else { var flagStr = $"ToListField:{field}"; @@ -770,7 +770,7 @@ namespace FreeSql.Internal.CommonProvider var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); ret.Add((TTuple)read.Value); return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } } catch (Exception ex) @@ -807,7 +807,7 @@ namespace FreeSql.Internal.CommonProvider } retCount++; return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -859,7 +859,7 @@ namespace FreeSql.Internal.CommonProvider var item = af.Read(_orm, fetch.Object); ret.Add(keySelector(item), elementSelector(item)); return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -895,7 +895,7 @@ namespace FreeSql.Internal.CommonProvider other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null)); retCount++; return Task.FromResult(false); - }, CommandType.Text, sql, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -950,7 +950,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 3a3bfccf..25694049 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -172,7 +172,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public long Count() => long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._params.ToArray())), out var trylng) ? trylng : default(long); + public long Count() => long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_select._connection, _select._transaction, CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._commandTimeout, _select._params.ToArray())), out var trylng) ? trylng : default(long); public ISelectGrouping Count(out long count) { count = this.Count(); @@ -201,7 +201,7 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._params.ToArray())), out var trylng) ? trylng : default(long); + async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_select._connection, _select._transaction, CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._commandTimeout, _select._params.ToArray())), out var trylng) ? trylng : default(long); public Task> ToListAsync(Expression, TReturn>> select) => InternalToList(select, typeof(TReturn), true) as Task>; async public Task> ToDictionaryAsync(Expression, TElement>> elementSelector) diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 7ffa1982..fc55bdce 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -35,6 +35,7 @@ namespace FreeSql.Internal.CommonProvider public Action> _batchProgress; public DbTransaction _transaction; public DbConnection _connection; + public int _commandTimeout = 0; public Action _interceptSql; public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) @@ -88,6 +89,11 @@ namespace FreeSql.Internal.CommonProvider _connection = connection; return this; } + public IUpdate CommandTimeout(int timeout) + { + _commandTimeout = timeout; + return this; + } public IUpdate NoneParameter(bool isNotCommandParameter = true) { @@ -306,7 +312,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(affrows, sql, dbParms); } catch (Exception ex) diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index a3593472..1b3d7756 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -175,7 +175,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(affrows, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index 6b3ea61a..c1e3047c 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -102,7 +102,7 @@ namespace FreeSql.Dameng.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -125,7 +125,7 @@ namespace FreeSql.Dameng.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) @@ -172,7 +172,7 @@ namespace FreeSql.Dameng.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -195,7 +195,7 @@ namespace FreeSql.Dameng.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs index 7ed41a5b..84b5f537 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs index c22f3394..89d7cac4 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs @@ -51,7 +51,7 @@ namespace FreeSql.Firebird.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -70,7 +70,7 @@ namespace FreeSql.Firebird.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -106,7 +106,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -151,7 +151,7 @@ namespace FreeSql.Firebird.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -170,7 +170,7 @@ namespace FreeSql.Firebird.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -206,7 +206,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs index 0b9e9080..1963ab68 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs @@ -44,7 +44,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -125,7 +125,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs index 8b9018e8..ef5b5579 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs index f76a3683..545c7c63 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs @@ -49,7 +49,7 @@ namespace FreeSql.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -68,7 +68,7 @@ namespace FreeSql.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -105,7 +105,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -142,7 +142,7 @@ namespace FreeSql.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -161,7 +161,7 @@ namespace FreeSql.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs index e1e55dd7..b550fd08 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs @@ -159,7 +159,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = _insert.InternalOrm.Ado.ExecuteNonQuery(_insert.InternalConnection, _insert.InternalTransaction, CommandType.Text, sql, _insert.InternalParams); + ret = _insert.InternalOrm.Ado.ExecuteNonQuery(_insert.InternalConnection, _insert.InternalTransaction, CommandType.Text, sql, _insert._commandTimeout, _insert.InternalParams); } catch (Exception ex) { @@ -188,7 +188,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = await _insert.InternalOrm.Ado.ExecuteNonQueryAsync(_insert.InternalConnection, _insert.InternalTransaction, CommandType.Text, sql, _insert.InternalParams); + ret = await _insert.InternalOrm.Ado.ExecuteNonQueryAsync(_insert.InternalConnection, _insert.InternalTransaction, CommandType.Text, sql, _insert._commandTimeout, _insert.InternalParams); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs index 7b4428a8..c47a4adc 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -149,7 +149,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs index 0e2950f1..9a31e8cc 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs @@ -36,7 +36,7 @@ namespace FreeSql.MsAccess.Curd Exception exception = null; try { - affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + affrows = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -67,14 +67,14 @@ namespace FreeSql.MsAccess.Curd using (var conn = _orm.Ado.MasterPool.Get()) { _connection = conn.Value; - _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, "SELECT @@identity", _params)), out ret); + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, "SELECT @@identity", _commandTimeout, _params)), out ret); } } else { - _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, "SELECT @@identity", _params)), out ret); + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, "SELECT @@identity", _commandTimeout, _params)), out ret); } } catch (Exception ex) @@ -115,7 +115,7 @@ namespace FreeSql.MsAccess.Curd Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -146,14 +146,14 @@ namespace FreeSql.MsAccess.Curd using (var conn = await _orm.Ado.MasterPool.GetAsync()) { _connection = conn.Value; - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _params)), out ret); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _commandTimeout, _params)), out ret); } } else { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _params)), out ret); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _commandTimeout, _params)), out ret); } } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index 9b5c9c2e..d982938e 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 277a27c1..74aacd75 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -53,7 +53,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0; + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -89,7 +89,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -122,7 +122,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0; + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -158,7 +158,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 1665cd94..a15cc11a 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -51,7 +51,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -132,7 +132,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs index 802ab4c1..7ce2055f 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -118,7 +118,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = _mysqlInsert.InternalOrm.Ado.ExecuteNonQuery(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert.InternalParams); + ret = _mysqlInsert.InternalOrm.Ado.ExecuteNonQuery(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams); } catch (Exception ex) { @@ -147,7 +147,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert.InternalParams); + ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index d5bc3fb0..ee2ca1a0 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -102,7 +102,7 @@ namespace FreeSql.Odbc.Dameng _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -125,7 +125,7 @@ namespace FreeSql.Odbc.Dameng _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) @@ -172,7 +172,7 @@ namespace FreeSql.Odbc.Dameng _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -195,7 +195,7 @@ namespace FreeSql.Odbc.Dameng _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index 823d76ed..54c04672 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -42,8 +42,8 @@ namespace FreeSql.Odbc.Default poolConn = _orm.Ado.MasterPool.Get(); conn = poolConn.Value; } - _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, $" {_utils.Adapter.InsertAfterGetIdentitySql}")), out var trylng) ? trylng : 0; + _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, $" {_utils.Adapter.InsertAfterGetIdentitySql}", _commandTimeout)), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -88,8 +88,8 @@ namespace FreeSql.Odbc.Default poolConn = _orm.Ado.MasterPool.Get(); conn = poolConn.Value; } - await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, $" {_utils.Adapter.InsertAfterGetIdentitySql}")), out var trylng) ? trylng : 0; + await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, $" {_utils.Adapter.InsertAfterGetIdentitySql}", _commandTimeout)), out var trylng) ? trylng : 0; } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs index 290a40e4..9d13cbc5 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs index 296e2435..2c2ca22b 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs @@ -49,7 +49,7 @@ namespace FreeSql.Odbc.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -68,7 +68,7 @@ namespace FreeSql.Odbc.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -105,7 +105,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -142,7 +142,7 @@ namespace FreeSql.Odbc.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -161,7 +161,7 @@ namespace FreeSql.Odbc.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs index d8802705..4e0b3774 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs @@ -159,7 +159,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); } catch (Exception ex) { @@ -188,7 +188,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index b3c0f838..4ba4b5f8 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -149,7 +149,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index 0b4a96e7..cb81a24d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index e2afe42e..e877bcdc 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -48,7 +48,7 @@ namespace FreeSql.Odbc.MySql if (string.IsNullOrEmpty(sql)) return 0; Object poolConn = null; - var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();", _commandTimeout), _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; @@ -61,8 +61,8 @@ namespace FreeSql.Odbc.MySql poolConn = _orm.Ado.MasterPool.Get(); conn = poolConn.Value; } - _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; + _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()", _commandTimeout)), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -101,7 +101,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -141,8 +141,8 @@ namespace FreeSql.Odbc.MySql poolConn = _orm.Ado.MasterPool.Get(); conn = poolConn.Value; } - await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _params); - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()")), out var trylng) ? trylng : 0; + await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()", _commandTimeout)), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -181,7 +181,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs index 5d12c106..92868d26 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs @@ -118,7 +118,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = _mysqlInsert.InternalOrm.Ado.ExecuteNonQuery(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert.InternalParams); + ret = _mysqlInsert.InternalOrm.Ado.ExecuteNonQuery(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams); } catch (Exception ex) { @@ -147,7 +147,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert.InternalParams); + ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index 34a41055..31524a6a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -51,7 +51,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -132,7 +132,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index 5313decc..d2903b2d 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -102,7 +102,7 @@ namespace FreeSql.Odbc.Oracle _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -125,7 +125,7 @@ namespace FreeSql.Odbc.Oracle _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) @@ -172,7 +172,7 @@ namespace FreeSql.Odbc.Oracle _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -195,7 +195,7 @@ namespace FreeSql.Odbc.Oracle _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index e133b8e2..f9245c03 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index 2c9e1b94..d1fe614d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -49,7 +49,7 @@ namespace FreeSql.Odbc.PostgreSQL _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -68,7 +68,7 @@ namespace FreeSql.Odbc.PostgreSQL _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -105,7 +105,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -142,7 +142,7 @@ namespace FreeSql.Odbc.PostgreSQL _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -161,7 +161,7 @@ namespace FreeSql.Odbc.PostgreSQL _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs index 879bba71..2a2f302b 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs @@ -159,7 +159,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); } catch (Exception ex) { @@ -188,7 +188,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 8ebffb29..9e9dce01 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -149,7 +149,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index 5de7dc0e..0530a4a9 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -43,7 +43,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -89,7 +89,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index ff92df61..1551bd21 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -36,7 +36,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -87,7 +87,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -120,7 +120,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -171,7 +171,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index f8d98ecc..58a2f5cb 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -49,7 +49,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -133,7 +133,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index d5807859..be0e5b0e 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -104,7 +104,7 @@ namespace FreeSql.Oracle.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -127,7 +127,7 @@ namespace FreeSql.Oracle.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, dbParms); + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) @@ -173,7 +173,7 @@ namespace FreeSql.Oracle.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -196,7 +196,7 @@ namespace FreeSql.Oracle.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, dbParms); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index cc02ec6c..5ab98652 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -159,7 +159,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); } catch (Exception ex) { @@ -188,7 +188,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert.InternalParams); + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index a4fc1cd4..57e33eaf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index 0e8d423e..367a967a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -49,7 +49,7 @@ namespace FreeSql.PostgreSQL.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -68,7 +68,7 @@ namespace FreeSql.PostgreSQL.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -105,7 +105,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -142,7 +142,7 @@ namespace FreeSql.PostgreSQL.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -161,7 +161,7 @@ namespace FreeSql.PostgreSQL.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index e8b735ab..a6fd43aa 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -52,7 +52,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -149,7 +149,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs index b4188d56..c67a0b3c 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs @@ -38,7 +38,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -79,7 +79,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs index 86f7fdaf..9dadb1a5 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs @@ -49,7 +49,7 @@ namespace FreeSql.ShenTong.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -68,7 +68,7 @@ namespace FreeSql.ShenTong.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -105,7 +105,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -142,7 +142,7 @@ namespace FreeSql.ShenTong.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -161,7 +161,7 @@ namespace FreeSql.ShenTong.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -197,7 +197,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index 5d71a4fe..ba4b22ea 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -53,7 +53,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -150,7 +150,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index 681c40ba..75eaf638 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -43,7 +43,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { @@ -89,7 +89,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index a801cdb9..f1ee76ae 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -41,7 +41,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -92,7 +92,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -125,7 +125,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -176,7 +176,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index 6faac879..8dbb9708 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -50,7 +50,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) @@ -134,7 +134,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index 49dd1191..a9165dc3 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -32,7 +32,7 @@ namespace FreeSql.Sqlite.Curd Exception exception = null; try { - long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { @@ -75,7 +75,7 @@ namespace FreeSql.Sqlite.Curd Exception exception = null; try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { From 46bc2189c45b851e766f5eba85135e561c311ef1 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 18 Sep 2020 12:33:07 +0800 Subject: [PATCH 0909/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect=20Or?= =?UTF-8?q?derByPropertyName=20=E6=96=B9=E6=B3=95=20#446=20#278=20#380=20#?= =?UTF-8?q?361=20#197=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++ .../Sqlite/Curd/SqliteSelectTest.cs | 61 ++++++++++++ FreeSql/FreeSql.xml | 19 ++++ FreeSql/Interface/Curd/ISelect/ISelect0.cs | 17 ++++ .../SelectProvider/Select0Provider.cs | 93 +++++++++++-------- 5 files changed, 161 insertions(+), 38 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index b2d9a63d..3d7caa44 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -2304,6 +2304,67 @@ WHERE ((a.""CreateTime"" >= '2010-10-10 00:00:00' AND a.""CreateTime"" < '2010-1 FROM ""D_District"" a LEFT JOIN ""D_District"" a__Parent ON a__Parent.""Code"" = a.""ParentCode"" WHERE ((not((a.""Code"") LIKE '%val1%') AND not((a.""Name"") LIKE 'val2%') OR not((a.""Name"") LIKE '%val3') OR a.""ParentCode"" <> 'val4' OR a__Parent.""Code"" = 'val11' AND (a__Parent.""Name"") LIKE '%val22%' OR a__Parent.""Name"" = 'val33' OR a__Parent.""ParentCode"" = 'val44'))", sql); + + sql = fsql.Select().OrderByPropertyName("Parent.Name").WhereDynamicFilter(JsonConvert.DeserializeObject(@" +{ + ""Logic"" : ""Or"", + ""Filters"" : + [ + { + ""Field"" : ""Code"", + ""Operator"" : ""NotContains"", + ""Value"" : ""val1"", + ""Filters"" : + [ + { + ""Field"" : ""Name"", + ""Operator"" : ""NotStartsWith"", + ""Value"" : ""val2"", + } + ] + }, + { + ""Field"" : ""Name"", + ""Operator"" : ""NotEndsWith"", + ""Value"" : ""val3"" + }, + { + ""Field"" : ""ParentCode"", + ""Operator"" : ""NotEqual"", + ""Value"" : ""val4"" + }, + + { + ""Field"" : ""Parent.Code"", + ""Operator"" : ""eq"", + ""Value"" : ""val11"", + ""Filters"" : + [ + { + ""Field"" : ""Parent.Name"", + ""Operator"" : ""contains"", + ""Value"" : ""val22"", + } + ] + }, + { + ""Field"" : ""Parent.Name"", + ""Operator"" : ""eq"", + ""Value"" : ""val33"" + }, + { + ""Field"" : ""Parent.ParentCode"", + ""Operator"" : ""eq"", + ""Value"" : ""val44"" + } + ] +} +")).ToSql(); + Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode"", a__Parent.""Code"" as6, a__Parent.""Name"" as7, a__Parent.""CreateTime"" as8, a__Parent.""testint"" as9, a__Parent.""ParentCode"" as10 +FROM ""D_District"" a +LEFT JOIN ""D_District"" a__Parent ON a__Parent.""Code"" = a.""ParentCode"" +WHERE ((not((a.""Code"") LIKE '%val1%') AND not((a.""Name"") LIKE 'val2%') OR not((a.""Name"") LIKE '%val3') OR a.""ParentCode"" <> 'val4' OR a__Parent.""Code"" = 'val11' AND (a__Parent.""Name"") LIKE '%val22%' OR a__Parent.""Name"" = 'val33' OR a__Parent.""ParentCode"" = 'val44')) +ORDER BY a__Parent.""Name""", sql); } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 79039cd6..b99f558c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1943,6 +1943,25 @@ 参数 + + + 按属性名字符串排序(支持导航属性) + 属性名:Name导航属性:Parent.Name多表:b.Name + + 属性名:Name导航属性:Parent.Name多表:b.Name + 顺序 | 倒序 + + + + + 按属性名字符串排序(支持导航属性) + 属性名:Name导航属性:Parent.Name多表:b.Name + + true 时生效 + 属性名:Name导航属性:Parent.Name多表:b.Name + 顺序 | 倒序 + + 查询向后偏移行数 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 7180b408..4ef554fd 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -337,6 +337,23 @@ namespace FreeSql /// 参数 /// TSelect OrderBy(bool condition, string sql, object parms = null); + /// + /// 按属性名字符串排序(支持导航属性) + /// 属性名:Name导航属性:Parent.Name多表:b.Name + /// + /// 属性名:Name导航属性:Parent.Name多表:b.Name + /// 顺序 | 倒序 + /// + TSelect OrderByPropertyName(string property, bool isAscending = true); + /// + /// 按属性名字符串排序(支持导航属性) + /// 属性名:Name导航属性:Parent.Name多表:b.Name + /// + /// true 时生效 + /// 属性名:Name导航属性:Parent.Name多表:b.Name + /// 顺序 | 倒序 + /// + TSelect OrderByPropertyNameIf(bool condition, string property, bool isAscending = true); /// /// 查询向后偏移行数 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 9a67dc82..d8ca14e4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -442,6 +442,60 @@ namespace FreeSql.Internal.CommonProvider return this as TSelect; } + public Expression ConvertStringPropertyToExpression(string property) + { + if (string.IsNullOrEmpty(property)) return null; + var field = property.Split('.').Select(a => a.Trim()).ToArray(); + Expression exp = null; + + if (field.Length == 1) + { + foreach (var tb in _tables) + { + if (tb.Table.ColumnsByCs.TryGetValue(field[0], out var col) && + tb.Table.Properties.TryGetValue(field[0], out var prop)) + { + tb.Parameter = Expression.Parameter(tb.Table.Type, tb.Alias); + exp = Expression.MakeMemberAccess(tb.Parameter, prop); + break; + } + } + if (exp == null) throw new Exception($"无法匹配 {property}"); + } + else + { + var firstTb = _tables[0]; + var firstTbs = _tables.Where(a => a.AliasInit == field[0]).ToArray(); + if (firstTbs.Length == 1) firstTb = firstTbs[0]; + + firstTb.Parameter = Expression.Parameter(firstTb.Table.Type, firstTb.Alias); + var currentType = firstTb.Table.Type; + Expression currentExp = firstTb.Parameter; + + for (var x = 0; x < field.Length; x++) + { + var tmp1 = field[x]; + if (_commonUtils.GetTableByEntity(currentType).Properties.TryGetValue(tmp1, out var prop) == false) + throw new ArgumentException($"{currentType.DisplayCsharp()} 无法找到属性名 {tmp1}"); + currentType = prop.PropertyType; + currentExp = Expression.MakeMemberAccess(currentExp, prop); + } + exp = currentExp; + } + return exp; + } + + public TSelect OrderByPropertyName(string property, bool isAscending = true) => OrderByPropertyNameIf(true, property, isAscending); + public TSelect OrderByPropertyNameIf(bool condition, string property, bool isAscending = true) + { + if (condition == false) return this as TSelect; + Expression exp = ConvertStringPropertyToExpression(property); + if (exp == null) return this as TSelect; + var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null); + if (isAscending) return this.OrderBy(field); + return this.OrderBy($"{field} DESC"); + } + static MethodInfo MethodStringContains = typeof(string).GetMethod("Contains", new[] { typeof(string) }); static MethodInfo MethodStringStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); static MethodInfo MethodStringEndsWith = typeof(string).GetMethod("EndsWith", new[] { typeof(string) }); @@ -460,44 +514,7 @@ namespace FreeSql.Internal.CommonProvider { if (string.IsNullOrEmpty(fi.Field) == false) { - var field = fi.Field.Split('.').Select(a => a.Trim()).ToArray(); - Expression exp = null; - - if (field.Length == 1) - { - foreach (var tb in _tables) - { - if (tb.Table.ColumnsByCs.TryGetValue(field[0], out var col) && - tb.Table.Properties.TryGetValue(field[0], out var prop)) - { - tb.Parameter = Expression.Parameter(tb.Table.Type, tb.Alias); - exp = Expression.MakeMemberAccess(tb.Parameter, prop); - break; - } - } - if (exp == null) throw new Exception($"无法匹配 {fi.Field}"); - } - else - { - var firstTb = _tables[0]; - var firstTbs = _tables.Where(a => a.AliasInit == field[0]).ToArray(); - if (firstTbs.Length == 1) firstTb = firstTbs[0]; - - firstTb.Parameter = Expression.Parameter(firstTb.Table.Type, firstTb.Alias); - var currentType = firstTb.Table.Type; - Expression currentExp = firstTb.Parameter; - - for (var x = 0; x < field.Length; x++) - { - var tmp1 = field[x]; - if (_commonUtils.GetTableByEntity(currentType).Properties.TryGetValue(tmp1, out var prop) == false) - throw new ArgumentException($"{currentType.DisplayCsharp()} 无法找到属性名 {tmp1}"); - currentType = prop.PropertyType; - currentExp = Expression.MakeMemberAccess(currentExp, prop); - } - exp = currentExp; - } - + Expression exp = ConvertStringPropertyToExpression(fi.Field); switch (fi.Operator) { case DynamicFilterOperator.Contains: exp = Expression.Call(exp, MethodStringContains, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; From ce15c121db875c1fe16dfcf37b123fe38da5f2c4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 18 Sep 2020 12:37:41 +0800 Subject: [PATCH 0910/1029] 1.9.0-preview0919 #446 #278 #380 #361 #197 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 22 insertions(+), 31 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 02769a71..99d6babe 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index b5660e64..4ca39812 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 4d96a44f..c8a4978f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index cb43529e..11919316 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 573b7531..37d425fa 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0918 + 1.9.0-preview0919 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 19a80ec1..5faa556e 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index f7f8d865..5f8c18a8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,14 +532,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7cbb85ca..41701554 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 769ebf5c..3029ce27 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 35edeb87..32ec497b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 83a7cb62..6151ee98 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 47405e6d..c82ddf6b 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index e392d7f7..c5248a11 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5fe907f8..71f4863c 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 54414244..e0e564ad 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 6ff0b114..a9bca898 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 1692c540..cfff2841 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 97f20d2a..2af4c814 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index e39fbf86..e64bd05f 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index eee937a3..985f51f0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index b2af2ea2..799de8f2 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 670eb3c0..115f8eac 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0918 + 1.9.0-preview0919 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 63dccf3e4c0c2542fd4aaaa813a9f0187ef5c647 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 19 Sep 2020 07:26:24 +0800 Subject: [PATCH 0911/1029] optimize internal methods --- .../SelectProvider/Select0Provider.cs | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index d8ca14e4..4a9a4066 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -124,6 +124,49 @@ namespace FreeSql.Internal.CommonProvider to._whereCascadeExpression = new List(from._whereCascadeExpression.ToArray()); to._whereGlobalFilter = new List(from._whereGlobalFilter.ToArray()); } + + public Expression ConvertStringPropertyToExpression(string property) + { + if (string.IsNullOrEmpty(property)) return null; + var field = property.Split('.').Select(a => a.Trim()).ToArray(); + Expression exp = null; + + if (field.Length == 1) + { + foreach (var tb in _tables) + { + if (tb.Table.ColumnsByCs.TryGetValue(field[0], out var col) && + tb.Table.Properties.TryGetValue(field[0], out var prop)) + { + tb.Parameter = Expression.Parameter(tb.Table.Type, tb.Alias); + exp = Expression.MakeMemberAccess(tb.Parameter, prop); + break; + } + } + if (exp == null) throw new Exception($"无法匹配 {property}"); + } + else + { + var firstTb = _tables[0]; + var firstTbs = _tables.Where(a => a.AliasInit == field[0]).ToArray(); + if (firstTbs.Length == 1) firstTb = firstTbs[0]; + + firstTb.Parameter = Expression.Parameter(firstTb.Table.Type, firstTb.Alias); + var currentType = firstTb.Table.Type; + Expression currentExp = firstTb.Parameter; + + for (var x = 0; x < field.Length; x++) + { + var tmp1 = field[x]; + if (_commonUtils.GetTableByEntity(currentType).Properties.TryGetValue(tmp1, out var prop) == false) + throw new ArgumentException($"{currentType.DisplayCsharp()} 无法找到属性名 {tmp1}"); + currentType = prop.PropertyType; + currentExp = Expression.MakeMemberAccess(currentExp, prop); + } + exp = currentExp; + } + return exp; + } } public abstract partial class Select0Provider : Select0Provider, ISelect0 where TSelect : class where T1 : class @@ -442,49 +485,6 @@ namespace FreeSql.Internal.CommonProvider return this as TSelect; } - public Expression ConvertStringPropertyToExpression(string property) - { - if (string.IsNullOrEmpty(property)) return null; - var field = property.Split('.').Select(a => a.Trim()).ToArray(); - Expression exp = null; - - if (field.Length == 1) - { - foreach (var tb in _tables) - { - if (tb.Table.ColumnsByCs.TryGetValue(field[0], out var col) && - tb.Table.Properties.TryGetValue(field[0], out var prop)) - { - tb.Parameter = Expression.Parameter(tb.Table.Type, tb.Alias); - exp = Expression.MakeMemberAccess(tb.Parameter, prop); - break; - } - } - if (exp == null) throw new Exception($"无法匹配 {property}"); - } - else - { - var firstTb = _tables[0]; - var firstTbs = _tables.Where(a => a.AliasInit == field[0]).ToArray(); - if (firstTbs.Length == 1) firstTb = firstTbs[0]; - - firstTb.Parameter = Expression.Parameter(firstTb.Table.Type, firstTb.Alias); - var currentType = firstTb.Table.Type; - Expression currentExp = firstTb.Parameter; - - for (var x = 0; x < field.Length; x++) - { - var tmp1 = field[x]; - if (_commonUtils.GetTableByEntity(currentType).Properties.TryGetValue(tmp1, out var prop) == false) - throw new ArgumentException($"{currentType.DisplayCsharp()} 无法找到属性名 {tmp1}"); - currentType = prop.PropertyType; - currentExp = Expression.MakeMemberAccess(currentExp, prop); - } - exp = currentExp; - } - return exp; - } - public TSelect OrderByPropertyName(string property, bool isAscending = true) => OrderByPropertyNameIf(true, property, isAscending); public TSelect OrderByPropertyNameIf(bool condition, string property, bool isAscending = true) { From 103ae63e9fa1d6086833d497eed9de7c9aa5b36e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 20 Sep 2020 13:36:49 +0800 Subject: [PATCH 0912/1029] optimize internal methods --- FreeSql.DbContext/DbSet/DbSetAsync.cs | 5 +++-- FreeSql.DbContext/DbSet/DbSetSync.cs | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index b75f3fb4..c2fe6994 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -44,7 +44,8 @@ namespace FreeSql case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) + case DataType.Firebird: //firebird 只支持单条插入 returning + if (_tableIdentitys.Length == 1) { await DbContextFlushCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); @@ -68,7 +69,7 @@ namespace FreeSql } return; default: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) + if (_tableIdentitys.Length == 1) { await DbContextFlushCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 7932c65c..3df68e7f 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -44,6 +44,7 @@ namespace FreeSql case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: + case DataType.Firebird: //firebird 只支持单条插入 returning if (_tableIdentitys.Length == 1) { DbContextFlushCommand(); From 72dedc992ce2dce44e6246569d71d1f1a4ebf5c0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 20 Sep 2020 18:38:14 +0800 Subject: [PATCH 0913/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect=20To?= =?UTF-8?q?Delete/ToUpdate=20=E4=BA=8B=E5=8A=A1=E5=AF=B9=E8=B1=A1=E6=9C=AA?= =?UTF-8?q?=E4=BC=A0=E6=92=AD=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ .../CommonProvider/SelectProvider/Select0Provider.cs | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 4a9a4066..e6020a4a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -377,7 +377,9 @@ namespace FreeSql.Internal.CommonProvider if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToDelete 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); var del = _orm.Delete() as DeleteProvider; if (_tables[0].Table.Type != typeof(T1)) del.AsType(_tables[0].Table.Type); - if (_params.Any()) del.GetType().GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(del, new List(_params.ToArray())); + if (_params.Any()) del._params = new List(_params.ToArray()); + if (_whereGlobalFilter.Any()) del._whereGlobalFilter = new List(_whereGlobalFilter.ToArray()); + del.WithConnection(_connection).WithTransaction(_transaction).CommandTimeout(_commandTimeout); switch (_orm.Ado.DataType) { case DataType.Dameng: @@ -403,7 +405,9 @@ namespace FreeSql.Internal.CommonProvider if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToUpdate 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); var upd = _orm.Update() as UpdateProvider; if (_tables[0].Table.Type != typeof(T1)) upd.AsType(_tables[0].Table.Type); - if (_params.Any()) upd.GetType().GetField("_params", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(upd, new List(_params.ToArray())); + if (_params.Any()) upd._params = new List(_params.ToArray()); + if (_whereGlobalFilter.Any()) upd._whereGlobalFilter = new List(_whereGlobalFilter.ToArray()); + upd.WithConnection(_connection).WithTransaction(_transaction).CommandTimeout(_commandTimeout); switch (_orm.Ado.DataType) { case DataType.Dameng: From fc8a0da48ff4cabd7948cee83955abaf8427647b Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 20 Sep 2020 18:47:00 +0800 Subject: [PATCH 0914/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ISelect=20In?= =?UTF-8?q?clude=20=E5=A4=9A=E8=A1=A8=E5=AD=97=E6=AE=B5=E5=90=8D=E7=9B=B8?= =?UTF-8?q?=E5=90=8C=EF=BC=88=E4=B8=8D=E5=8C=BA=E5=88=86=E5=A4=A7=E5=B0=8F?= =?UTF-8?q?=E6=97=B6=EF=BC=89=E6=97=B6=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommonProvider/SelectProvider/Select0ProviderReader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index a347470a..079c25e2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -384,7 +384,7 @@ namespace FreeSql.Internal.CommonProvider //typeof(Topic).GetMethod("get_Type").IsVirtual var field = new StringBuilder(); - var dicfield = new Dictionary(); + var dicfield = new Dictionary(StringComparer.CurrentCultureIgnoreCase); var tb = _tables.First(); var index = 0; @@ -526,7 +526,7 @@ namespace FreeSql.Internal.CommonProvider //typeof(Topic).GetMethod("get_Type").IsVirtual var field = new StringBuilder(); - var dicfield = new Dictionary(); + var dicfield = new Dictionary(StringComparer.CurrentCultureIgnoreCase); var tb = _tables.First(); var index = 0; var otherindex = 0; From 11402eb8fadac36fdcf6d68b8dc26cfeea243afd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 20 Sep 2020 19:51:58 +0800 Subject: [PATCH 0915/1029] v1.9.0-preview0920 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 99d6babe..bb478d71 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 4ca39812..4e476ada 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c8a4978f..15032267 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 11919316..75b1a262 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 37d425fa..d8deda05 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0919 + 1.9.0-preview0920 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 5faa556e..75101dcc 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 5f8c18a8..35421898 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 41701554..fd153a1f 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3029ce27..fd4bb33d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 32ec497b..c700dd6e 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 6151ee98..7ef779fa 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index c82ddf6b..6b8c065d 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index c5248a11..40e60095 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 71f4863c..7e64c360 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index e0e564ad..714b9d23 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a9bca898..0d1f405e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index cfff2841..697abb2d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2af4c814..2b526333 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index e64bd05f..0b4a4c88 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 985f51f0..63a03a61 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 799de8f2..6e44dfd9 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 115f8eac..a9cf2dc4 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0919 + 1.9.0-preview0920 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 3c812d4305acfd79e64ff5e1c7536d88f472264d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 22 Sep 2020 15:33:45 +0800 Subject: [PATCH 0916/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ToSql=20Fiel?= =?UTF-8?q?dAliasOptions.AsProperty=20=E5=88=AB=E5=90=8D=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B#467?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 15 + FreeSql.Tests/FreeSql.Tests/Issues/467.cs | 65 ++++ FreeSql/FreeSql.xml | 347 ++++++++++-------- FreeSql/Internal/CommonExpression.cs | 4 +- 4 files changed, 270 insertions(+), 161 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/467.cs diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index c8168e34..c482a1d3 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -9,6 +9,21 @@ 编号 + + + 收款金额 + + + + + 订单时间 + + + + + 支付Id + + 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/467.cs b/FreeSql.Tests/FreeSql.Tests/Issues/467.cs new file mode 100644 index 00000000..3719b768 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/467.cs @@ -0,0 +1,65 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _467 + { + [Fact] + public void SelectTest() + { + IFreeSql fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=1") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + .UseGenerateCommandParameterWithLambda(true) + .UseAutoSyncStructure(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build(); + + var orderSql = fsql + .Select() + .As(nameof(PayOrder).ToLower()) + .Where(p => p.Status == 1) + .ToSql(p => new + { + p.PayOrderId, + p.Money, + p.OrderTime + }, FreeSql.FieldAliasOptions.AsProperty); + + Assert.Equal(@"SELECT payorder.""PayOrderId"", payorder.""Money"", payorder.""OrderTime"" +FROM ""pay_order"" payorder +WHERE (payorder.""Status"" = 1)", orderSql); + } + + [JsonObject(MemberSerialization.OptIn), Table(Name = "pay_order", DisableSyncStructure = true)] + public partial class PayOrder + { + /// + /// 收款金额 + /// + [JsonProperty, Column(DbType = "money")] + public decimal Money { get; set; } + + /// + /// 订单时间 + /// + [JsonProperty, Column(DbType = "timestamptz")] + public DateTime? OrderTime { get; set; } + + /// + /// 支付Id + /// + [JsonProperty, Column(StringLength = 50)] + public string PayOrderId { get; set; } + + public int Status { get; set; } + } + } +} diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b99f558c..74d77883 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2953,154 +2953,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3870,12 +3722,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3946,12 +3792,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4562,3 +4402,190 @@ +essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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 3096b6f4..cf3fbaac 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -175,7 +175,9 @@ namespace FreeSql.Internal parent.DbField = ExpressionLambdaToSql(exp, getTSC()); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); + else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false && + parent.DbField.EndsWith(_common.QuoteSqlName(parent.CsName), StringComparison.CurrentCultureIgnoreCase) == false //DbField 和 CsName 相同的时候,不处理 + ) field.Append(_common.FieldAsAlias(parent.CsName)); parent.MapType = SearchColumnByField(_tables, null, parent.DbField)?.Attribute.MapType ?? exp.Type; return false; } From ede456f1bf654b80010ade8da4b156b7569c7c48 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 22 Sep 2020 15:54:26 +0800 Subject: [PATCH 0917/1029] update tests --- .../MySqlConnector/Curd/MySqlSelectTest.cs | 4 ++-- .../MySql/Curd/MySqlSelectTest.cs | 4 ++-- FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 8 ++++---- FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs | 3 +++ .../FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs | 4 ++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs index fbc94dee..f59bf2e9 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlSelectTest.cs @@ -1126,12 +1126,12 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` WF_ProcessInstance = p }); - Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName + Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId`, a.`NodeId`, a.`NodeName` FROM `WF_Task` a WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName`", sqltmp12); Assert.Equal(@"SELECT a.`TaskId` as1, a.`TaskType` as2, a.`ProcessId` as3, a.`NodeId` as4, a.`NodeName` as5, b.`Id` as6, b.`TaskType` as7, b.`ProcessId` as8, b.`NodeId` as9, b.`CreateTime` as10, b.`IsFinished` as11, b.`EnabledMark` as12 -FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName +FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId`, a.`NodeId`, a.`NodeName` FROM `WF_Task` a WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs index 871d4408..399e3fca 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlSelectTest.cs @@ -1137,12 +1137,12 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` WF_ProcessInstance = p }); - Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName + Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId`, a.`NodeId`, a.`NodeName` FROM `WF_Task` a WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName`", sqltmp12); Assert.Equal(@"SELECT a.`TaskId` as1, a.`TaskType` as2, a.`ProcessId` as3, a.`NodeId` as4, a.`NodeName` as5, b.`Id` as6, b.`TaskType` as7, b.`ProcessId` as8, b.`NodeId` as9, b.`CreateTime` as10, b.`IsFinished` as11, b.`EnabledMark` as12 -FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName +FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId`, a.`NodeId`, a.`NodeName` FROM `WF_Task` a WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 3eb3d8c3..292da596 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1168,12 +1168,12 @@ WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` }); Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2 -FROM (SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks +FROM (SELECT * from (SELECT a.`Id`, a.`Clicks` FROM `tb_topic_1` a) ftb UNION ALL - SELECT * from (SELECT a.`Id` Id, a.`Clicks` Clicks + SELECT * from (SELECT a.`Id`, a.`Clicks` FROM `tb_topic_2` a) ftb) a limit 0,20", select .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) @@ -1206,12 +1206,12 @@ limit 0,20", select WF_ProcessInstance = p }); - Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName + Assert.Equal(@"SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId`, a.`NodeId`, a.`NodeName` FROM `WF_Task` a WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName`", sqltmp12); Assert.Equal(@"SELECT a.`TaskId` as1, a.`TaskType` as2, a.`ProcessId` as3, a.`NodeId` as4, a.`NodeName` as5, b.`Id` as6, b.`TaskType` as7, b.`ProcessId` as8, b.`NodeId` as9, b.`CreateTime` as10, b.`IsFinished` as11, b.`EnabledMark` as12 -FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId` ProcessId, a.`NodeId` NodeId, a.`NodeName` NodeName +FROM ( SELECT max(a.`Id`) TaskId, max(a.`Type`) TaskType, a.`ProcessId`, a.`NodeId`, a.`NodeName` FROM `WF_Task` a WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs index b6e9c337..51afef22 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlDbFirstTest.cs @@ -32,6 +32,9 @@ namespace FreeSql.Tests.MySql Assert.Equal(t1.Columns.Count, t2.Columns.Count); var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); Assert.Null(t3); + + var t11 = fsql.DbFirst.GetTableByName("blog"); + } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 14ff9c76..4aae89fc 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -909,10 +909,10 @@ FROM ""TB_TOPIC22"" a", subquery); Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, (SELECT avg(b.""ID"") FROM ""TB_TOPIC22"" b) as6 FROM ""TB_TOPIC22"" a", subquery); - var subqueryList = select.Limit(100).ToList(a => new + var subqueryList = select.Limit(10).ToList(a => new { all = a, - count = select.As("b").Avg(b => b.Id) + count = select.As("b").Limit(10).Avg(b => b.Id) }); } [Fact] From ced9fbb47611868f850a7c1d0d85e7b26218a401 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 22 Sep 2020 18:03:31 +0800 Subject: [PATCH 0918/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20FreeSql.Gene?= =?UTF-8?q?rator=20-Match=20=E6=94=AF=E6=8C=81=E7=94=9F=E6=88=90=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E8=A1=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 19 +- FreeSql/FreeSql.xml | 347 ++++++++++----------- 2 files changed, 176 insertions(+), 190 deletions(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index 119364dd..f0662070 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -1,5 +1,7 @@ -using RazorEngine.Templating; +using FreeSql.DatabaseModel; +using RazorEngine.Templating; using System; +using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; @@ -111,7 +113,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam 默认生成:表+视图+存储过程 如果不想生成视图和存储过程 -Filter View+StoreProcedure - -Match 正则表达式,只生成匹配的表,如:dbo\.TB_.+ + -Match 表名或正则表达式,只生成匹配的表,如:dbo\.TB_.+ -FileName 文件名,默认:{name}.cs -Output 保存路径,默认为当前 shell 所在目录 @@ -219,7 +221,18 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 .UseMonitorCommand(cmd => Console.WriteFormatted(cmd.CommandText + "\r\n", Color.SlateGray)) .Build()) { - var tables = fsql.DbFirst.GetTablesByDatabase(); + List tables = new List(); + if (string.IsNullOrEmpty(ArgsMatch) == false) + { + try + { + var matchTable = fsql.DbFirst.GetTableByName(ArgsMatch); + if (matchTable != null) tables.Add(matchTable); + } + catch { } + } + if (tables.Any() == false) + tables = fsql.DbFirst.GetTablesByDatabase(); var outputTables = tables; //开始生成操作 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 74d77883..b99f558c 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2953,6 +2953,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3722,6 +3870,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3792,6 +3946,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4402,190 +4562,3 @@ -essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 条件 - - - - From bf84bf0fcbc0636922c165ba06c6f4c81ba345a3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 22 Sep 2020 22:45:34 +0800 Subject: [PATCH 0919/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20IAdo.Query\(sql)=20=E9=94=99=E8=AF=AF?= =?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 | 9 --------- FreeSql/Internal/UtilsExpressionTree.cs | 21 ++++++++++++++++++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,14 +532,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 83c5c442..148ac6c4 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1463,7 +1463,7 @@ namespace FreeSql.Internal var name = row2.GetName(a); //expando[name] = row2.GetValue(a); if (expandodic.ContainsKey(name)) continue; - expandodic.Add(name, Utils.InternalDataReaderGetValue(_commonUtils, row2, a)); + expandodic.Add(name, Utils.InternalDataReaderGetValue(commonUtils2, row2, a)); } //expando = expandodic; return new RowInfo(expandodic, fc); @@ -1471,6 +1471,8 @@ namespace FreeSql.Internal return dynamicFunc;// Expression.Lambda>(null); } + if (type.IsAnonymousType()) return ExecuteArrayRowReadAnonymousType; + //类注入属性 var typetb = GetTableByEntity(type, _commonUtils); var retExp = Expression.Variable(type, "ret"); @@ -1596,12 +1598,13 @@ namespace FreeSql.Internal var propIndex = 0; foreach (var prop in props) { - if (typetb.ColumnsByCsIgnore.ContainsKey(prop.Name)) + if (typetb?.ColumnsByCsIgnore.ContainsKey(prop.Name) == true) { ++propIndex; continue; } - var readType = typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) ? trycol.Attribute.MapType : prop.PropertyType; + ColumnInfo trycol = null; + var readType = typetb?.ColumnsByCs.TryGetValue(prop.Name, out trycol) == true ? trycol.Attribute.MapType : prop.PropertyType; var ispkExp = new List(); var propGetSetMethod = prop.GetSetMethod(true); @@ -1700,6 +1703,18 @@ namespace FreeSql.Internal return func(typeOrg, indexes, row, dataIndex, _commonUtils); } + internal static RowInfo ExecuteArrayRowReadAnonymousType(Type type2, int[] indexes2, DbDataReader row2, int dataindex2, CommonUtils commonUtils2) + { + var ctor = type2.InternalGetTypeConstructor0OrFirst(); + var ctorParms = new object[ctor.GetParameters().Length]; + if (indexes2?.Length != ctorParms.Length) + indexes2 = ctor.GetParameters().Select(c => row2.GetOrdinal(c.Name)).ToArray(); + + for (var c = 0; c < ctorParms.Length; c++) + ctorParms[c] = Utils.InternalDataReaderGetValue(commonUtils2, row2, indexes2[c]); + return new RowInfo(ctor.Invoke(ctorParms), ctorParms.Length); + } + internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic); internal static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.NonPublic); From 2d2a0e211ed6d888d768826dd647c8e95efbc289 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 23 Sep 2020 11:21:21 +0800 Subject: [PATCH 0920/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Oracle=20DbF?= =?UTF-8?q?irst=20=E8=A7=86=E5=9B=BE=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Generator.csproj | 2 +- .../FreeSql.Tests/Oracle/OracleDbFirstTest.cs | 2 ++ .../SqlServerAdo/SqlServerAdoTest.cs | 10 +++++++++- .../Oracle/OdbcOracleDbFirst.cs | 19 ++++++++++++++++--- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 19 ++++++++++++++++--- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d8deda05..390f6b4c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0920 + 1.8.1.330 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs index c3cfaaa0..3ffdad38 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleDbFirstTest.cs @@ -33,6 +33,8 @@ namespace FreeSql.Tests.Oracle Assert.Equal(t1.Columns.Count, t2.Columns.Count); var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); Assert.Null(t3); + + var t4 = fsql.DbFirst.GetTableByName("V_DTOS_DT"); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index d366322c..6a01369e 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -1,5 +1,6 @@ using FreeSql.DataAnnotations; using FreeSql.Tests.DataContext.SqlServer; +using Microsoft.Data.SqlClient; using NetTaste; using System; using System.Collections.Generic; @@ -47,7 +48,14 @@ namespace FreeSql.Tests.SqlServer [Fact] public void ExecuteNonQuery() { - + var ps = new[] + { + new SqlParameter("@TableName", "tb1"), + new SqlParameter("@FInterID", System.Data.SqlDbType.Int) + }; + ps[1].Direction = System.Data.ParameterDirection.Output; + g.sqlserver.Ado.ExecuteNonQuery(System.Data.CommandType.StoredProcedure, "dbo.GetICMaxNum", ps); + Assert.Equal(100, ps[1].Value); } [Fact] public void ExecuteScalar() diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index c9f477cb..e07f4437 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -216,14 +216,27 @@ namespace FreeSql.Odbc.Oracle var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); var sql = $@" select -a.owner || '.' || a.table_name, +a.owner || '.' || a.table_name AS tbname, a.owner, a.table_name, b.comments, -'TABLE' +'TABLE' AS tp from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' -where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")} + +UNION ALL + +select +a.owner || '.' || a.view_name, +a.owner, +a.view_name, +b.comments, +'VIEW' AS tp +from all_views a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.view_name and b.table_type = 'VIEW' +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.view_name)" : "a.view_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")} +"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 2231f27a..fc249b8d 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -216,14 +216,27 @@ namespace FreeSql.Oracle var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); var sql = $@" select -a.owner || '.' || a.table_name, +a.owner || '.' || a.table_name AS tbname, a.owner, a.table_name, b.comments, -'TABLE' +'TABLE' AS tp from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' -where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")} + +UNION ALL + +select +a.owner || '.' || a.view_name, +a.owner, +a.view_name, +b.comments, +'VIEW' AS tp +from all_views a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.view_name and b.table_type = 'VIEW' +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.view_name)" : "a.view_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")} +"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; From 9b93200237c88b1fac273e907ba8a9cb60f46d2e Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 23 Sep 2020 17:59:57 +0800 Subject: [PATCH 0921/1029] =?UTF-8?q?-=20=E8=B0=83=E6=95=B4=20FreeSql.Gene?= =?UTF-8?q?rator=20=E7=A7=BB=E9=99=A4=20CanInsert=20=3D=20false=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E7=94=9F=E6=88=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/RazorModel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 63e2e77f..40009156 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -196,11 +196,11 @@ public class RazorModel { if (defval != null) { sb.Add("InsertValueSql = \"" + defval.Replace("\"", "\\\"") + "\""); - sb.Add("CanInsert = false"); + //sb.Add("CanInsert = false"); } } - else - sb.Add("CanInsert = false"); + //else + //sb.Add("CanInsert = false"); } } if (sb.Any() == false) return null; From 8a0862d6fec76d1c6428052f5d3c6a1a4e2dfc92 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 23 Sep 2020 22:00:48 +0800 Subject: [PATCH 0922/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IAdo.Command?= =?UTF-8?q?Fluent(sql)=20=E6=96=B9=E6=B3=95=E6=89=A7=E8=A1=8C=20SQL=20?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=EF=BC=9B=20-=20=E4=BF=AE=E5=A4=8D=20SqlServe?= =?UTF-8?q?r=20SqlBulkCopy=20IgnoreColumns=20=E6=97=A0=E6=95=88=E7=9A=84?= =?UTF-8?q?=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 -- .../SqlServer/Curd/SqlServerInsertTest.cs | 1 + FreeSql/FreeSql.xml | 52 ++++++++ FreeSql/Interface/IAdo.cs | 15 +++ .../CommonProvider/AdoProvider/AdoProvider.cs | 7 +- FreeSql/Internal/Model/AdoCommandFluent.cs | 113 ++++++++++++++++++ .../DamengAdo/DamengAdo.cs | 4 +- .../FirebirdAdo/FirebirdAdo.cs | 4 +- .../KingbaseESAdo/KingbaseESAdo.cs | 4 +- .../MsAccessAdo/MsAccessAdo.cs | 4 +- .../MySqlAdo/MySqlAdo.cs | 4 +- .../Dameng/OdbcDamengAdo/OdbcDamengAdo.cs | 4 +- .../Default/OdbcAdo/OdbcAdo.cs | 4 +- .../OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs | 4 +- .../MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs | 4 +- .../Oracle/OdbcOracleAdo/OdbcOracleAdo.cs | 4 +- .../OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs | 4 +- .../OdbcSqlServerAdo/OdbcSqlServerAdo.cs | 4 +- .../OracleAdo/OracleAdo.cs | 4 +- .../PostgreSQLAdo/PostgreSQLAdo.cs | 4 +- .../ShenTongAdo/ShenTongAdo.cs | 4 +- .../SqlServerAdo/SqlServerAdo.cs | 4 +- .../SqlServerExtensions.cs | 4 + .../SqliteAdo/SqliteAdo.cs | 4 +- 25 files changed, 225 insertions(+), 44 deletions(-) create mode 100644 FreeSql/Internal/Model/AdoCommandFluent.cs diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 390f6b4c..d8deda05 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.1.330 + 1.9.0-preview0920 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..5a0c8bd0 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index 356f5fcf..eb7d8c0f 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -171,6 +171,7 @@ namespace FreeSql.Tests.SqlServer for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); insert.AppendData(items).InsertIdentity().ExecuteSqlBulkCopy(); + insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.Clicks }).ExecuteSqlBulkCopy(); // System.NotSupportedException:“DataSet does not support System.Nullable<>.” } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b99f558c..330dc4ac 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2805,6 +2805,21 @@ new { id = 1 } 或者 Dictionary<string, object> + + + SQL 命令执行类,fsql.Ado.CommandFluent("select * from user where age > ?age", new { age = 25 }) + .WithConnection(connection) + .WithTransaction(transaction) + .WithParameter("age", 25) + .WithParameter("id", 11) + .CommandType(CommandType.Text) + .CommandTimeout(60) + .Query<T>(); 或者 ExecuteNonQuery/ExecuteScalar/ExecuteDataTable/ExecuteDataSet/ExecuteArray + + + + + 测试数据库是否连接正确,本方法执行如下命令: @@ -3674,6 +3689,43 @@ 表达式 + + + 使用指定 DbConnection 连接执行 + + + + + + + 使用指定 DbTransaction 事务执行 + + + + + + + 增加参数化对象 + + 参数名 + 参数值 + 修改本次创建好的参数化对象,比如将 parameterName 参数修改为 Output 类型 + + + + + 设置执行的命令类型,SQL文本、或存储过程 + + + + + + + 设置命令执行超时(秒) + + + + 当前操作的数据 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index a0e5dde9..69ce18f9 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -62,6 +62,21 @@ namespace FreeSql /// DbParameter[] GetDbParamtersByObject(object obj); + /// + /// SQL 命令执行类,fsql.Ado.CommandFluent("select * from user where age > ?age", new { age = 25 }) + /// .WithConnection(connection) + /// .WithTransaction(transaction) + /// .WithParameter("age", 25) + /// .WithParameter("id", 11) + /// .CommandType(CommandType.Text) + /// .CommandTimeout(60) + /// .Query<T>(); 或者 ExecuteNonQuery/ExecuteScalar/ExecuteDataTable/ExecuteDataSet/ExecuteArray + /// + /// + /// + /// + AdoCommandFluent CommandFluent(string cmdText, object parms = null); + /// /// 测试数据库是否连接正确,本方法执行如下命令: /// MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index f38845ba..6abba992 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -16,8 +16,8 @@ namespace FreeSql.Internal.CommonProvider { protected abstract void ReturnConnection(IObjectPool pool, Object conn, Exception ex); - protected abstract DbCommand CreateCommand(); - protected abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); + public abstract DbCommand CreateCommand(); + public abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); public DbParameter[] GetDbParamtersByObject(object obj) => GetDbParamtersByObject("*", obj); protected bool IsTracePerformance => _util?._orm?.Aop.CommandAfterHandler != null; @@ -28,6 +28,7 @@ namespace FreeSql.Internal.CommonProvider public string ConnectionString { get; } public string[] SlaveConnectionStrings { get; } public Guid Identifier { get; } + protected CommonUtils _util { get; set; } protected int slaveUnavailables = 0; private object slaveLock = new object(); @@ -97,6 +98,8 @@ namespace FreeSql.Internal.CommonProvider //return props; } + public AdoCommandFluent CommandFluent(string cmdText, object parms = null) => new AdoCommandFluent(this, cmdText, parms); + public bool ExecuteConnectTest(int commandTimeout = 0) { try diff --git a/FreeSql/Internal/Model/AdoCommandFluent.cs b/FreeSql/Internal/Model/AdoCommandFluent.cs new file mode 100644 index 00000000..8accc9aa --- /dev/null +++ b/FreeSql/Internal/Model/AdoCommandFluent.cs @@ -0,0 +1,113 @@ +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.Model +{ + public class AdoCommandFluent + { + internal protected AdoProvider Ado { get; protected set; } + internal protected DbConnection Connection { get; protected set; } + internal protected DbTransaction Transaction { get; protected set; } + internal protected CommandType CmdType { get; protected set; } = System.Data.CommandType.Text; + internal protected string CmdText { get; protected set; } + internal protected int CmdTimeout { get; protected set; } + internal protected List CmdParameters { get; } = new List(); + + public AdoCommandFluent(AdoProvider ado, string commandText, object parms) + { + this.Ado = ado; + this.CmdText = commandText; + this.CmdParameters.AddRange(this.Ado.GetDbParamtersByObject(parms)); + } + + /// + /// 使用指定 DbConnection 连接执行 + /// + /// + /// + public AdoCommandFluent WithConnection(DbConnection conn) + { + this.Transaction = null; + this.Connection = conn; + return this; + } + /// + /// 使用指定 DbTransaction 事务执行 + /// + /// + /// + public AdoCommandFluent WithTransaction(DbTransaction tran) + { + this.Transaction = tran; + if (tran != null) this.Connection = tran.Connection; + return this; + } + + /// + /// 增加参数化对象 + /// + /// 参数名 + /// 参数值 + /// 修改本次创建好的参数化对象,比如将 parameterName 参数修改为 Output 类型 + /// + public AdoCommandFluent WithParameter(string parameterName, object value, Action modify = null) + { + var param = this.Ado.GetDbParamtersByObject(new Dictionary { [parameterName] = value }).FirstOrDefault(); + modify?.Invoke(param); + this.CmdParameters.Add(param); + return this; + } + + /// + /// 设置执行的命令类型,SQL文本、或存储过程 + /// + /// + /// + public AdoCommandFluent CommandType(CommandType commandType) + { + this.CmdType = commandType; + return this; + } + /// + /// 设置命令执行超时(秒) + /// + /// + /// + public AdoCommandFluent CommandTimeout(int commandTimeout) + { + this.CmdTimeout = commandTimeout; + return this; + } + + public int ExecuteNonQuery() => this.Ado.ExecuteNonQuery(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public object ExecuteScalar() => this.Ado.ExecuteScalar(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public DataTable ExecuteDataTable() => this.Ado.ExecuteDataTable(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public DataSet ExecuteDataSet() => this.Ado.ExecuteDataSet(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public object[][] ExecuteArray() => this.Ado.ExecuteArray(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public List Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public NativeTuple, List> Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public NativeTuple, List, List> Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public NativeTuple, List, List, List> Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public NativeTuple, List, List, List, List> Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + +#if net40 +#else + public Task ExecuteNonQueryAsync() => this.Ado.ExecuteNonQueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task ExecuteScalarAsync() => this.Ado.ExecuteScalarAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task ExecuteDataTableAsync() => this.Ado.ExecuteDataTableAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task ExecuteDataSetAsync() => this.Ado.ExecuteDataSetAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task ExecuteArrayAsync() => this.Ado.ExecuteArrayAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task, List>> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task, List, List>> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task, List, List, List>> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task, List, List, List, List>> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); +#endif + } +} diff --git a/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs b/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs index 68f0c7ed..64634235 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengAdo/DamengAdo.cs @@ -60,7 +60,7 @@ namespace FreeSql.Dameng //if (param is string) return string.Concat('N', nparms[a]); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new DmCommand(); } @@ -72,6 +72,6 @@ namespace FreeSql.Dameng else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs b/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs index 7f5988e2..40bbf313 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs @@ -62,7 +62,7 @@ namespace FreeSql.Firebird } DbConnection _CreateCommandConnection; - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { if (_CreateCommandConnection != null) { @@ -80,6 +80,6 @@ namespace FreeSql.Firebird else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs index a3f33988..cad591ac 100644 --- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESAdo/KingbaseESAdo.cs @@ -61,7 +61,7 @@ namespace FreeSql.KingbaseES return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new KdbndpCommand(); } @@ -73,6 +73,6 @@ namespace FreeSql.KingbaseES else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs index a86c5a4f..1f69bec9 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs @@ -65,7 +65,7 @@ namespace FreeSql.MsAccess return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OleDbCommand(); } @@ -77,6 +77,6 @@ namespace FreeSql.MsAccess else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index dd9fdbab..66f62f8e 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -67,7 +67,7 @@ namespace FreeSql.MySql return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new MySqlCommand(); } @@ -79,6 +79,6 @@ namespace FreeSql.MySql else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index 478dec5e..56ea4ebd 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -61,7 +61,7 @@ namespace FreeSql.Odbc.Dameng //if (param is string) return string.Concat('N', nparms[a]); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OdbcCommand(); } @@ -73,6 +73,6 @@ namespace FreeSql.Odbc.Dameng else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index ce5ca081..bda2426b 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -62,7 +62,7 @@ namespace FreeSql.Odbc.Default return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OdbcCommand(); } @@ -74,6 +74,6 @@ namespace FreeSql.Odbc.Default else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs index 11d37474..94b9bda8 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESAdo/OdbcKingbaseESAdo.cs @@ -61,7 +61,7 @@ namespace FreeSql.Odbc.KingbaseES return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OdbcCommand(); } @@ -73,6 +73,6 @@ namespace FreeSql.Odbc.KingbaseES else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index b1d7573d..0c18f7b7 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -61,7 +61,7 @@ namespace FreeSql.Odbc.MySql return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OdbcCommand(); } @@ -73,6 +73,6 @@ namespace FreeSql.Odbc.MySql else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index e0041666..4e81bef1 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -61,7 +61,7 @@ namespace FreeSql.Odbc.Oracle //if (param is string) return string.Concat('N', nparms[a]); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OdbcCommand(); } @@ -73,6 +73,6 @@ namespace FreeSql.Odbc.Oracle else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index 72c196a5..e8f0c53e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -62,7 +62,7 @@ namespace FreeSql.Odbc.PostgreSQL return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OdbcCommand(); } @@ -74,6 +74,6 @@ namespace FreeSql.Odbc.PostgreSQL else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index c6277105..73ad461f 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -75,7 +75,7 @@ namespace FreeSql.Odbc.SqlServer return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OdbcCommand(); } @@ -87,6 +87,6 @@ namespace FreeSql.Odbc.SqlServer else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index f0c42708..57d161e0 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -61,7 +61,7 @@ namespace FreeSql.Oracle //if (param is string) return string.Concat('N', nparms[a]); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { var cmd = new OracleCommand(); cmd.BindByName = true; @@ -75,6 +75,6 @@ namespace FreeSql.Oracle else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index 12bfafcc..857ca688 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -79,7 +79,7 @@ namespace FreeSql.PostgreSQL return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new NpgsqlCommand(); } @@ -91,6 +91,6 @@ namespace FreeSql.PostgreSQL else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs index eaa0e7b3..33da3ebd 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongAdo/ShenTongAdo.cs @@ -62,7 +62,7 @@ namespace FreeSql.ShenTong return string.Concat("'", param.ToString().Replace("'", "''"), "'"); } - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { return new OscarCommand(); } @@ -74,6 +74,6 @@ namespace FreeSql.ShenTong else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 52edb94b..9266c037 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -83,7 +83,7 @@ namespace FreeSql.SqlServer } DbConnection _CreateCommandConnection; - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { if (_CreateCommandConnection != null) { @@ -101,6 +101,6 @@ namespace FreeSql.SqlServer else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 021d09e5..e399bd74 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -82,6 +82,8 @@ public static partial class FreeSqlSqlServerGlobalExtensions if (batchSize.HasValue) bulkCopy.BatchSize = batchSize.Value; if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; bulkCopy.DestinationTableName = dt.TableName; + for (int i = 0; i < dt.Columns.Count; i++) + bulkCopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); bulkCopy.WriteToServer(dt); }; @@ -157,6 +159,8 @@ public static partial class FreeSqlSqlServerGlobalExtensions if (batchSize.HasValue) bulkCopy.BatchSize = batchSize.Value; if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; bulkCopy.DestinationTableName = dt.TableName; + for (int i = 0; i < dt.Columns.Count; i++) + bulkCopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); return bulkCopy.WriteToServerAsync(dt); }; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 1f928e46..a911d9b1 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -64,7 +64,7 @@ namespace FreeSql.Sqlite } DbConnection _CreateCommandConnection; - protected override DbCommand CreateCommand() + public override DbCommand CreateCommand() { if (_CreateCommandConnection != null) { @@ -82,6 +82,6 @@ namespace FreeSql.Sqlite else pool.Return(conn); } - protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); } } From 5a664180c257a6b040fe1d756ffe9e17c864d8ec Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 23 Sep 2020 22:07:10 +0800 Subject: [PATCH 0923/1029] v1.9.0 #467 #462 #456 #454 #450 #446 #445 #443 #380 #361 #278 #197 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 38 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index bb478d71..656d0a46 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 4e476ada..6149376f 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 15032267..9e005ee7 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 75b1a262..07163fff 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d8deda05..304692b9 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0-preview0920 + 1.9.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 75101dcc..499e4f86 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 35421898..16bdbdd6 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 5a0c8bd0..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index fd153a1f..7310b4dd 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0-preview0920 + 1.9.0 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fd4bb33d..b65ff569 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index c700dd6e..2d7846d6 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 7ef779fa..b16b8c6d 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 6b8c065d..d7da136a 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 40e60095..26cc244e 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 7e64c360..89ac1e76 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 714b9d23..de583b22 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0d1f405e..034a3e15 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 697abb2d..92c1bbd0 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2b526333..1f837f47 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 0b4a4c88..f7339e79 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 63a03a61..acdc89d9 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 6e44dfd9..292ad836 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index a9cf2dc4..ca56966c 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0-preview0920 + 1.9.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 89e79d270faa4606e330fa9a43f04bca1c3f86e9 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@users.noreply.github.com> Date: Thu, 24 Sep 2020 22:56:47 +0800 Subject: [PATCH 0924/1029] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 09f208b0..e880b81a 100644 --- a/readme.md +++ b/readme.md @@ -189,7 +189,7 @@ QQ群:4336577(已满)、8578575(在线)、52508226(在线) ## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 -无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元、建爽 66元 +无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元、建爽 66元、无名 200元、LambertWu 100元 > Thank you for your donation From 8fb330b528ccf459cd7ca31adab8f07a37b56076 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 26 Sep 2020 14:30:40 +0800 Subject: [PATCH 0925/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20AsTreeCte=20?= =?UTF-8?q?=E5=BC=80=E5=90=AF=E8=87=AA=E5=8A=A8=E8=BF=81=E7=A7=BB=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E9=94=99=E8=AF=AF=E7=9A=84=E5=88=9B=E5=BB=BA=E4=BA=86?= =?UTF-8?q?=20as=5Ftree=5Fcte=20=E8=A1=A8=EF=BC=9B#476?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ---- FreeSql.Tests/FreeSql.Tests/Issues/390.cs | 45 ++++++++++--------- FreeSql.Tests/FreeSql.Tests/Issues/462.cs | 34 +++++++------- FreeSql.Tests/FreeSql.Tests/Issues/467.cs | 39 ++++++++-------- FreeSql.Tests/FreeSql.Tests/Issues/476.cs | 36 +++++++++++++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 + 6 files changed, 99 insertions(+), 66 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/476.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..9c6cd88b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,14 +532,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/390.cs b/FreeSql.Tests/FreeSql.Tests/Issues/390.cs index bac347c8..05c5cd96 100644 --- a/FreeSql.Tests/FreeSql.Tests/Issues/390.cs +++ b/FreeSql.Tests/FreeSql.Tests/Issues/390.cs @@ -13,29 +13,30 @@ namespace FreeSql.Tests.Issues [Fact] public void SelectTest() { - IFreeSql db = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=1") - .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) - .UseGenerateCommandParameterWithLambda(true) - .UseAutoSyncStructure(true) - .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) - .Build(); + using (IFreeSql db = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=1") + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + .UseGenerateCommandParameterWithLambda(true) + .UseAutoSyncStructure(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build()) + { + var startTime = DateTime.Now; + var endTime = DateTime.Now; - var startTime = DateTime.Now; - var endTime = DateTime.Now; - - var cou = db.Select() - .Where(a => a.ScheduledDttm.Date >= startTime.Date && a.ScheduledDttm.Date <= (endTime.AddDays(1)).Date) - .GroupBy(a => - new - { - a.HospitalName, - a.Dep, - a.Instrna, - a.ConfirmDoctorName, - a.ScheduledDttm.Date - }) - .Count(); + var cou = db.Select() + .Where(a => a.ScheduledDttm.Date >= startTime.Date && a.ScheduledDttm.Date <= (endTime.AddDays(1)).Date) + .GroupBy(a => + new + { + a.HospitalName, + a.Dep, + a.Instrna, + a.ConfirmDoctorName, + a.ScheduledDttm.Date + }) + .Count(); + } } [Table(Name = "V_HospitalReport")] diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/462.cs b/FreeSql.Tests/FreeSql.Tests/Issues/462.cs index 0fa0162f..9811134a 100644 --- a/FreeSql.Tests/FreeSql.Tests/Issues/462.cs +++ b/FreeSql.Tests/FreeSql.Tests/Issues/462.cs @@ -13,24 +13,26 @@ namespace FreeSql.Tests.Issues [Fact] public void SelectTest() { - IFreeSql db = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=1") - .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) - .UseGenerateCommandParameterWithLambda(true) - .UseAutoSyncStructure(true) - .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) - .Build(); + using (var db = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=1") + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + .UseGenerateCommandParameterWithLambda(true) + .UseAutoSyncStructure(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build()) + { - var startTime = DateTime.Now; - var endTime = DateTime.Now; + var startTime = DateTime.Now; + var endTime = DateTime.Now; - var exp0 = 10; - var cou = db.Select() - .Where(a => a.ScheduledDttm.Date >= startTime.Date && a.ScheduledDttm.Date <= (endTime.AddDays(1)).Date) - .ToList(a => new - { - subCount = db.Select().Where(b => b.SCHEDULED_DTTM == exp0).Count() - }); + var exp0 = 10; + var cou = db.Select() + .Where(a => a.ScheduledDttm.Date >= startTime.Date && a.ScheduledDttm.Date <= (endTime.AddDays(1)).Date) + .ToList(a => new + { + subCount = db.Select().Where(b => b.SCHEDULED_DTTM == exp0).Count() + }); + } } [Table(Name = "V_HospitalReport22")] diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/467.cs b/FreeSql.Tests/FreeSql.Tests/Issues/467.cs index 3719b768..708246f2 100644 --- a/FreeSql.Tests/FreeSql.Tests/Issues/467.cs +++ b/FreeSql.Tests/FreeSql.Tests/Issues/467.cs @@ -14,28 +14,29 @@ namespace FreeSql.Tests.Issues [Fact] public void SelectTest() { - IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=1") - //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) - .UseGenerateCommandParameterWithLambda(true) - .UseAutoSyncStructure(true) - .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) - .Build(); + using (IFreeSql fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=1") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + .UseGenerateCommandParameterWithLambda(true) + .UseAutoSyncStructure(true) + .UseMonitorCommand(cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText)) + .Build()) + { + var orderSql = fsql + .Select() + .As(nameof(PayOrder).ToLower()) + .Where(p => p.Status == 1) + .ToSql(p => new + { + p.PayOrderId, + p.Money, + p.OrderTime + }, FreeSql.FieldAliasOptions.AsProperty); - var orderSql = fsql - .Select() - .As(nameof(PayOrder).ToLower()) - .Where(p => p.Status == 1) - .ToSql(p => new - { - p.PayOrderId, - p.Money, - p.OrderTime - }, FreeSql.FieldAliasOptions.AsProperty); - - Assert.Equal(@"SELECT payorder.""PayOrderId"", payorder.""Money"", payorder.""OrderTime"" + Assert.Equal(@"SELECT payorder.""PayOrderId"", payorder.""Money"", payorder.""OrderTime"" FROM ""pay_order"" payorder WHERE (payorder.""Status"" = 1)", orderSql); + } } [JsonObject(MemberSerialization.OptIn), Table(Name = "pay_order", DisableSyncStructure = true)] diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/476.cs b/FreeSql.Tests/FreeSql.Tests/Issues/476.cs new file mode 100644 index 00000000..592ed47f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/476.cs @@ -0,0 +1,36 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _476 + { + [Fact] + public void SelectTest() + { + var fsql = g.mysql; + var repo = fsql.GetRepository(); + var list = repo.Select.Where(m => m.Name == "辽宁省").AsTreeCte().ToList(); + } + + [Table(Name = "Area476")] + public class AreaEntity + { + [Column(IsIdentity = true)] + public long Id { get; set; } + public string Name { get; set; } + public long ParentId { get; set; } + + [Navigate(nameof(ParentId))] + public AreaEntity Parent { get; set; } + [Navigate(nameof(ParentId))] + public List Childs { get; set; } + } + } +} diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index bc78db29..d8657041 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -451,6 +451,8 @@ public static partial class FreeSqlGlobalExtensions }); sql2ctePath = $"{sql2ctePath} as cte_path, "; } + if (select._orm.CodeFirst.IsAutoSyncStructure) + (select._orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(tb.Type, cteName); //#476 var sql2 = select .AsAlias((type, old) => type == tb.Type ? old.Replace("wct2", "wct1") : old) .AsTable((type, old) => type == tb.Type ? cteName : old) From 070b9a1e66961a513814c7b840377a5c719f017d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 28 Sep 2020 03:11:33 +0800 Subject: [PATCH 0926/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=A0=91=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=97=B6=EF=BC=8C=E5=BC=80=E6=94=BE(=E9=9D=9E?= =?UTF-8?q?=E5=85=AC=E5=BC=80)=E5=86=85=E9=83=A8=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=20Utility.CommonUtils=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/DataAnnotations/ExpressionCallAttribute.cs | 7 ++++++- FreeSql/FreeSql.xml | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs index 6970eca9..85daa395 100644 --- a/FreeSql/DataAnnotations/ExpressionCallAttribute.cs +++ b/FreeSql/DataAnnotations/ExpressionCallAttribute.cs @@ -85,6 +85,11 @@ namespace FreeSql.DataAnnotations /// /// string ParseExpression(Expression exp); + + /// + /// (非公开)内部公共工具类方法 + /// + CommonUtils CommonUtils { get; } } class DefaultUtility : IUtility @@ -92,8 +97,8 @@ namespace FreeSql.DataAnnotations internal ExpressionCallContext _context; public TableInfo GetTableByEntity(Type entityType) => _context?._commonExp._common.GetTableByEntity(entityType); - public string ParseExpression(Expression exp) => _context?._commonExp.ExpressionLambdaToSql(exp, _context._tsc.CloneDisableDiyParse()); + public CommonUtils CommonUtils => _context?._commonExp._common; } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 330dc4ac..4cea215e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -292,6 +292,11 @@ + + + (非公开)内部公共工具类方法 + + 索引设置,如:[Index("{tablename}_idx_01", "name")] From e22c2617c4faf650e1aefeb47c1e299baed7535f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 28 Sep 2020 04:33:55 +0800 Subject: [PATCH 0927/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E9=80=9A?= =?UTF-8?q?=E7=94=A8=20Odbc=20=E6=94=AF=E6=8C=81=20Limit=20=E9=A3=8E?= =?UTF-8?q?=E6=A0=BC=E7=9A=84=E5=88=86=E9=A1=B5=EF=BC=9B#469?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Default/Curd/OdbcSelect.cs | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index 963db3a3..8452c685 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -34,18 +34,9 @@ namespace FreeSql.Odbc.Default if (_distinct) sb.Append("DISTINCT "); if (_limit > 0 && _utils.Adapter.SelectTopStyle == OdbcAdapter.SelecTopStyle.Top) sb.Append("TOP ").Append(_skip + _limit).Append(" "); sb.Append(field); - if (_skip > 0) - { - if (string.IsNullOrEmpty(_orderby)) - { - var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); - if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); - else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); - } - sb.Append(", ROW_NUMBER() OVER(").Append(_orderby).Append(") AS __rownum__"); - + if (_skip > 0 && _utils.Adapter.SelectTopStyle == OdbcAdapter.SelecTopStyle.Top) throw new NotImplementedException("FreeSql.Odbc.Default 未实现 Skip/Offset 功能,如果需要分页请使用判断上一次 id"); - } + sb.Append(" \r\nFROM "); var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); @@ -116,13 +107,11 @@ namespace FreeSql.Odbc.Default if (string.IsNullOrEmpty(_having) == false) sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); } - if (_skip <= 0) - sb.Append(_orderby); - else - sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); + sb.Append(_orderby); + if (_limit > 0 && _utils.Adapter.SelectTopStyle == OdbcAdapter.SelecTopStyle.Limit) sb.Append(" \r\nLIMIT ").Append(_limit); + if (_skip > 0 && _utils.Adapter.SelectTopStyle == OdbcAdapter.SelecTopStyle.Limit) sb.Append(" \r\nOFFSET ").Append(_skip); sbnav.Clear(); - if (_limit > 0 && _utils.Adapter.SelectTopStyle == OdbcAdapter.SelecTopStyle.Limit) sb.Append(" \r\nLIMIT ").Append(_skip + _limit); if (tbUnionsGt0) sb.Append(") ftb"); } return sb.Append(_tosqlAppendContent).ToString(); From 31775bee2545769e7957a90409c63c532b3e2809 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 28 Sep 2020 21:03:38 +0800 Subject: [PATCH 0928/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20IncludeMany?= =?UTF-8?q?=20=E7=AD=9B=E9=80=89=E5=AD=97=E6=AE=B5=E4=B8=AD=E6=9C=AA?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E4=B8=BB=E9=94=AE=EF=BC=8C=E5=B9=B6=E4=B8=94?= =?UTF-8?q?=20then.IncludeMany=20=E7=BB=A7=E7=BB=AD=E5=90=91=E4=B8=8B?= =?UTF-8?q?=EF=BC=8C=E5=88=99=E8=87=AA=E5=8A=A8=E9=99=84=E5=8A=A0=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E4=B8=BB=E9=94=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 11 +- .../Sqlite/Curd/SqliteSelectTest.cs | 6 + FreeSql/FreeSql.xml | 347 ++++++++++-------- .../SelectProvider/Select1Provider.cs | 9 + 4 files changed, 206 insertions(+), 167 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 9c6cd88b..645b01c3 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -179,6 +172,10 @@ + + + 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 + 场景:winform 加载表数据后,一顿添加ember> 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 3d7caa44..302d38e4 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -1648,6 +1648,12 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" Assert.Equal(1, songs22[1].Tags.Count); Assert.Equal(1, songs22[2].Tags.Count); + var asongs222211 = g.sqlite.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + var atags33 = g.sqlite.Select() .Include(a => a.Tag.Parent) .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4cea215e..7c9e44f2 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2973,154 +2973,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3927,12 +3779,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4003,12 +3849,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4619,3 +4459,190 @@ +essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 1f14404d..387a0993 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -806,6 +806,15 @@ namespace FreeSql.Internal.CommonProvider var tmpMemberInfo = tbrefCol.Table.Properties[tbrefCol.CsName]; newinitExpBindings.Add(Expression.Bind(tmpMemberInfo, Expression.MakeMemberAccess(selectExp.Parameters[0], tmpMemberInfo))); } + if (subSelect._includeToList.Any()) //如果还有向下 IncludeMany,要把它的主键也查出来 + { + foreach (var tbrefPkCol in _commonUtils.GetTableByEntity(tbref.RefEntityType).Primarys) + { + if (newinitExpBindings.Any(a => a.Member.Name == tbrefPkCol.CsName)) continue; + var tmpMemberInfo = tbrefPkCol.Table.Properties[tbrefPkCol.CsName]; + newinitExpBindings.Add(Expression.Bind(tmpMemberInfo, Expression.MakeMemberAccess(selectExp.Parameters[0], tmpMemberInfo))); + } + } Expression newinitExp = Expression.MemberInit(tmpinitExp.NewExpression, newinitExpBindings.ToList()); var selectExpParam = subSelect._tables[0].Parameter ?? Expression.Parameter(typeof(TNavigate), subSelectT1Alias); newinitExp = new NewExpressionVisitor(selectExpParam, selectExp.Parameters[0]).Replace(newinitExp); From 05ddec4f64381e297801ce7a8897631beb82a16c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 28 Sep 2020 21:38:21 +0800 Subject: [PATCH 0929/1029] update tests --- FreeSql.Tests/FreeSql.Tests/Issues/476.cs | 2 +- .../FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/476.cs b/FreeSql.Tests/FreeSql.Tests/Issues/476.cs index 592ed47f..700d9857 100644 --- a/FreeSql.Tests/FreeSql.Tests/Issues/476.cs +++ b/FreeSql.Tests/FreeSql.Tests/Issues/476.cs @@ -14,7 +14,7 @@ namespace FreeSql.Tests.Issues [Fact] public void SelectTest() { - var fsql = g.mysql; + var fsql = g.sqlite; var repo = fsql.GetRepository(); var list = repo.Select.Where(m => m.Name == "辽宁省").AsTreeCte().ToList(); } diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index eb7d8c0f..20f73c87 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -171,7 +171,7 @@ namespace FreeSql.Tests.SqlServer for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); insert.AppendData(items).InsertIdentity().ExecuteSqlBulkCopy(); - insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.Clicks }).ExecuteSqlBulkCopy(); + //insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.Clicks }).ExecuteSqlBulkCopy(); // System.NotSupportedException:“DataSet does not support System.Nullable<>.” } From 837c38d158512b633187b2d2797f122058d1eae8 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 29 Sep 2020 10:46:56 +0800 Subject: [PATCH 0930/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20WhereDynamic?= =?UTF-8?q?Filter=20=E6=94=AF=E6=8C=81=20string=20=E6=AF=94=E8=BE=83?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=20>=20<=20>=3D=20<=3D=EF=BC=9B#479?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 22 +- .../Sqlite/Curd/SqliteSelectTest.cs | 22 +- .../FreeSqlGlobalExpressionCallExtensions.cs | 39 ++ FreeSql/FreeSql.xml | 371 +++++++++--------- .../SelectProvider/Select0Provider.cs | 8 +- 5 files changed, 266 insertions(+), 196 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 645b01c3..7ff55af8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -172,10 +179,6 @@ - - - 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 - 场景:winform 加载表数据后,一顿添加ember> 开始编辑数据,然后调用方法 EndEdit 分析出添加、修改、删除 SQL 语句进行执行 @@ -531,3 +534,14 @@ +Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])"> + + 批量注入 Repository,可以参考代码自行调整 + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 302d38e4..151a25d5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -2174,13 +2174,33 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" ""Field"" : ""CreateTime"", ""Operator"" : ""GreaterThanOrEqual"", ""Value"" : ""2010-10-10"" + }, + { + ""Field"" : ""Name"", + ""Operator"" : ""GreaterThan"", + ""Value"" : ""val31"", + }, + { + ""Field"" : ""Name"", + ""Operator"" : ""GreaterThanOrEqual"", + ""Value"" : ""val32"", + }, + { + ""Field"" : ""Name"", + ""Operator"" : ""LessThan"", + ""Value"" : ""val33"", + }, + { + ""Field"" : ""Name"", + ""Operator"" : ""LessThanOrEqual"", + ""Value"" : ""val34"", } ] } ")).ToSql(); Assert.Equal(@"SELECT a.""Code"", a.""Name"", a.""CreateTime"", a.""testint"", a.""ParentCode"" FROM ""D_District"" a -WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") LIKE '%val3' OR a.""ParentCode"" = 'val4' OR a.""CreateTime"" >= '2010-10-10 00:00:00'))", sql); +WHERE (((a.""Code"") LIKE '%val1%' AND (a.""Name"") LIKE 'val2%' OR (a.""Name"") LIKE '%val3' OR a.""ParentCode"" = 'val4' OR a.""CreateTime"" >= '2010-10-10 00:00:00' OR a.""Name"" > 'val31' OR a.""Name"" >= 'val32' OR a.""Name"" < 'val33' OR a.""Name"" <= 'val34'))", sql); sql = fsql.Select().WhereDynamicFilter(JsonConvert.DeserializeObject(@" { diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index 9540c72a..2524d1af 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -117,6 +117,45 @@ namespace FreeSql return default(TValue); } + #region 大小判断 + /// + /// 大于 > + /// + /// + public static bool GreaterThan(TValue value1, TValue value2) + { + expContext.Value.Result = $"{expContext.Value.ParsedContent["value1"]} > {expContext.Value.ParsedContent["value2"]}"; + return false; + } + /// + /// 大于或等于 >= + /// + /// + public static bool GreaterThanOrEqual(TValue value1, TValue value2) + { + expContext.Value.Result = $"{expContext.Value.ParsedContent["value1"]} >= {expContext.Value.ParsedContent["value2"]}"; + return false; + } + /// + /// 小于 < + /// + /// + public static bool LessThan(TValue value1, TValue value2) + { + expContext.Value.Result = $"{expContext.Value.ParsedContent["value1"]} < {expContext.Value.ParsedContent["value2"]}"; + return false; + } + /// + /// 小于或等于 <= + /// + /// + public static bool LessThanOrEqual(TValue value1, TValue value2) + { + expContext.Value.Result = $"{expContext.Value.ParsedContent["value1"]} <= {expContext.Value.ParsedContent["value2"]}"; + return false; + } + #endregion + /// /// case when .. then .. end /// diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 7c9e44f2..8fd7f738 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1123,6 +1123,30 @@ + + + 大于 > + + + + + + 大于或等于 >= + + + + + + 小于 < + + + + + + 小于或等于 <= + + + case when .. then .. end @@ -2973,6 +2997,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3779,6 +3951,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3849,6 +4027,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4459,190 +4643,3 @@ -essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index e6020a4a..962039dd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -533,10 +533,10 @@ namespace FreeSql.Internal.CommonProvider case DynamicFilterOperator.Equal: exp = Expression.Equal(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; case DynamicFilterOperator.NotEqual: exp = Expression.NotEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; - case DynamicFilterOperator.GreaterThan: exp = Expression.GreaterThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; - case DynamicFilterOperator.GreaterThanOrEqual: exp = Expression.GreaterThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; - case DynamicFilterOperator.LessThan: exp = Expression.LessThan(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; - case DynamicFilterOperator.LessThanOrEqual: exp = Expression.LessThanOrEqual(exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.GreaterThan: exp = Expression.Call(typeof(SqlExt).GetMethod("GreaterThan").MakeGenericMethod(exp.Type), exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.GreaterThanOrEqual: exp = Expression.Call(typeof(SqlExt).GetMethod("GreaterThanOrEqual").MakeGenericMethod(exp.Type), exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.LessThan: exp = Expression.Call(typeof(SqlExt).GetMethod("LessThan").MakeGenericMethod(exp.Type), exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; + case DynamicFilterOperator.LessThanOrEqual: exp = Expression.Call(typeof(SqlExt).GetMethod("LessThanOrEqual").MakeGenericMethod(exp.Type), exp, Expression.Constant(Utils.GetDataReaderValue(exp.Type, fi.Value?.ToString()), exp.Type)); break; case DynamicFilterOperator.Range: var fiValueRangeArray = getFiListValue(); if (fiValueRangeArray.Length != 2) throw new ArgumentException($"Range 要求 Value 应该逗号分割,并且长度为 2"); From d617b237de5181a8c63910a5ca836f63236ad1de Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 29 Sep 2020 11:31:57 +0800 Subject: [PATCH 0931/1029] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E6=96=B9=E6=B3=95=20ToListAsync(a=20=3D>=20{})=20?= =?UTF-8?q?=E5=AF=B9=20IncludeMany=20=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectProvider/Select1Provider.cs | 69 +++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 387a0993..a940c2f7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -195,7 +195,7 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = select.Parameters[0]; if (_includeToList?.Any() != true) return this.InternalToList(select.Body); - var findIncludeMany = new List(); + var findIncludeMany = new List(); //支持指定已经使用 IncudeMany 的导航属性 var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = 0; @@ -1167,11 +1167,72 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = column.Parameters[0]; return this.InternalSumAsync(column?.Body); } - public Task> ToListAsync(Expression> select) + async public Task> ToListAsync(Expression> select) { - if (select == null) return this.InternalToListAsync(select?.Body); + if (select == null) return await this.InternalToListAsync(select?.Body); _tables[0].Parameter = select.Parameters[0]; - return this.InternalToListAsync(select?.Body); + if (_includeToList?.Any() != true) return await this.InternalToListAsync(select.Body); + + var findIncludeMany = new List(); //支持指定已经使用 IncudeMany 的导航属性 + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select.Body, this, null, _whereCascadeExpression, findIncludeMany, true); + var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); + if (findIncludeMany.Any() == false) return await this.ToListMapReaderPrivateAsync(af, null); + + var parmExp = Expression.Parameter(_tables[0].Table.Type, _tables[0].Alias); + var incNewInit = new IncludeManyNewInit(_tables[0].Table, parmExp); + foreach (var inc in _includeInfo) + { + var curIncNewInit = incNewInit; + Expression curParmExp = parmExp; + for (var a = 0; a < inc.Value.Length - 1; a++) + { + curParmExp = Expression.MakeMemberAccess(parmExp, inc.Value[a].Member); + if (curIncNewInit.Childs.ContainsKey(inc.Value[a].Member.Name) == false) + curIncNewInit.Childs.Add(inc.Value[a].Member.Name, curIncNewInit = new IncludeManyNewInit(_orm.CodeFirst.GetTableByEntity(inc.Value[a].Type), curParmExp)); + else + curIncNewInit = curIncNewInit.Childs[inc.Value[a].Member.Name]; + } + curIncNewInit.IsOutputPrimary = true; + } + MemberInitExpression GetIncludeManyNewInitExpression(IncludeManyNewInit imni) + { + var bindings = new List(); + if (imni.IsOutputPrimary) bindings.AddRange(imni.Table.Primarys.Select(a => Expression.Bind(imni.Table.Properties[a.CsName], Expression.MakeMemberAccess(imni.CurrentExpression, imni.Table.Properties[a.CsName])))); + if (imni.Childs.Any()) bindings.AddRange(imni.Childs.Select(a => Expression.Bind(imni.Table.Properties[a.Key], GetIncludeManyNewInitExpression(a.Value)))); + return Expression.MemberInit(imni.Table.Type.InternalNewExpression(), bindings); + } + + var otherNewInit = GetIncludeManyNewInitExpression(incNewInit); //获取 IncludeMany 包含的最简化字段 + if (otherNewInit.Bindings.Any() == false) return await this.ToListMapReaderPrivateAsync(af, null); + + var otherMap = new ReadAnonymousTypeInfo(); + field.Clear(); + _commonExpression.ReadAnonymousField(_tables, field, otherMap, ref index, otherNewInit, this, null, _whereCascadeExpression, null, true); + var otherRet = new List(); + var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); + + af.fillIncludeMany = new List>(); + var ret = await this.ToListMapReaderPrivateAsync(af, new[] { otherAf }); + await this.SetListAsync(otherRet.Select(a => (T1)a).ToList()); //级联加载 + + foreach (var fim in af.fillIncludeMany) + { + var splitKeys = fim.Item1.Split('.'); + var otherRetItem = otherRet[fim.Item3]; + var otherRetItemType = _tables[0].Table.Type; + foreach (var splitKey in splitKeys) + { + otherRetItem = _orm.GetEntityValueWithPropertyName(otherRetItemType, otherRetItem, splitKey); + otherRetItemType = _orm.CodeFirst.GetTableByEntity(otherRetItemType).Properties[splitKey].PropertyType; + } + if (otherRetItem == null) continue; + var otherList = otherRetItem as IEnumerable; + foreach (var otherListItem in otherList) fim.Item2.Add(otherListItem); + } + return ret; } public Task> ToListAsync() => ToListAsync(GetToListDtoSelector()); From 35069609de6c472c9227e14e2acd9acef12b329d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 29 Sep 2020 11:54:16 +0800 Subject: [PATCH 0932/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20WhereDynamic?= =?UTF-8?q?=20=E4=BC=A0=E5=85=A5=20DynamicFilterInfo=20=E4=B9=9F=E8=83=BD?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectProvider/Select1Provider.cs | 23 ++++++++++++++++--- readme.md | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index a940c2f7..7e52c879 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -338,9 +338,26 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter = exp.Parameters[0]; return this.InternalWhere(exp?.Body); } - public ISelect WhereDynamic(object dywhere, bool not = false) => not == false ? - this.Where(_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere)) : - this.Where($"not({_commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere)})"); + public ISelect WhereDynamic(object dywhere, bool not = false) + { + if (dywhere is DynamicFilterInfo dyfilter) + { + if (not == false) return this.WhereDynamicFilter(dyfilter); + + var oldwhere = _where.ToString(); + _where.Clear(); + + this.WhereDynamicFilter(dyfilter); + var newwhere = _where.ToString(); + _where.Clear(); + + return this + .Where(oldwhere) + .WhereIf(string.IsNullOrWhiteSpace(newwhere) == false, $"not({newwhere})"); + } + var wheresql = _commonUtils.WhereObject(_tables.First().Table, $"{_tables.First().Alias}.", dywhere); + return not == false ? this.Where(wheresql) : this.Where($"not({wheresql})"); + } public ISelect WhereCascade(Expression> exp) { diff --git a/readme.md b/readme.md index e880b81a..52a00d81 100644 --- a/readme.md +++ b/readme.md @@ -189,7 +189,7 @@ QQ群:4336577(已满)、8578575(在线)、52508226(在线) ## 💕  Donation L*y 58元、花花 88元、麦兜很乖 50元、网络来者 2000元、John 99.99元、alex 666元、bacongao 36元、无名 100元、Eternity 188元、无名 10元、⌒.Helper~..oO 66元、习惯与被习惯 100元、无名 100元、蔡易喋 88.88元、中讯科技 1000元、Good Good Work 24元、炽焰 6.6元、Nothing 100元、兰州天擎赵 500元、哈利路亚 300元、 -无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元、建爽 66元、无名 200元、LambertWu 100元 +无名 100元、蛰伏 99.99元、TCYM 66.66元、MOTA 5元、LDZXG 30元、Near 30元、建爽 66元、无名 200元、LambertWu 100元、无名 18.88元、乌龙 50元 > Thank you for your donation From a36c2d036cd2e1a1529175de4fe1523c0a18ce96 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 29 Sep 2020 12:56:43 +0800 Subject: [PATCH 0933/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=B1=BB=E6=B3=A8=E9=87=8A=EF=BC=8C=E5=9F=BA=E7=B1=BB?= =?UTF-8?q?=E5=9C=A8=E5=85=B6=E4=BB=96=20Assembly=20=E6=97=B6=E4=B9=9F?= =?UTF-8?q?=E8=83=BD=E8=AF=BB=E5=8F=96=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 4 +- .../MySql/Curd/MySqlSelectTest.cs | 4 +- FreeSql/Internal/CommonUtils.cs | 109 ++++++++++-------- 3 files changed, 64 insertions(+), 53 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 7ff55af8..743835e4 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,9 +532,7 @@ - - -Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])"> + 批量注入 Repository,可以参考代码自行调整 diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 292da596..2d0bacb3 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -825,13 +825,13 @@ LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type .WhereIf(false, a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); - query2.ToList(); + query2.Limit(100).ToList(); //������϶����㲻�� query = select.WhereIf(false, "a.clicks > 100 and a.id = ?id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); - query.ToList(); + query.Limit(100).ToList(); } [Fact] public void WhereExists() diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 9b2ee4f5..6b8f85d0 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -451,56 +451,69 @@ namespace FreeSql.Internal /// Dict:key=属性名,value=注释 public static Dictionary GetProperyCommentBySummary(Type type) { - if (type.Assembly.IsDynamic) return null; - //动态生成的程序集,访问不了 Assembly.Location/Assembly.CodeBase - var regex = new Regex(@"\.(dll|exe)", RegexOptions.IgnoreCase); - var xmlPath = regex.Replace(type.Assembly.Location, ".xml"); - if (File.Exists(xmlPath) == false) + return LocalGetComment(type, 0); + + Dictionary LocalGetComment(Type localType, int level) { - if (string.IsNullOrEmpty(type.Assembly.CodeBase)) return null; - xmlPath = regex.Replace(type.Assembly.CodeBase, ".xml"); - if (xmlPath.StartsWith("file:///") && Uri.TryCreate(xmlPath, UriKind.Absolute, out var tryuri)) - xmlPath = tryuri.LocalPath; - if (File.Exists(xmlPath) == false) return null; + if (localType.Assembly.IsDynamic) return null; + //动态生成的程序集,访问不了 Assembly.Location/Assembly.CodeBase + var regex = new Regex(@"\.(dll|exe)", RegexOptions.IgnoreCase); + var xmlPath = regex.Replace(localType.Assembly.Location, ".xml"); + if (File.Exists(xmlPath) == false) + { + if (string.IsNullOrEmpty(localType.Assembly.CodeBase)) return null; + xmlPath = regex.Replace(localType.Assembly.CodeBase, ".xml"); + if (xmlPath.StartsWith("file:///") && Uri.TryCreate(xmlPath, UriKind.Absolute, out var tryuri)) + xmlPath = tryuri.LocalPath; + if (File.Exists(xmlPath) == false) return null; + } + + var dic = new Dictionary(); + var sReader = new StringReader(File.ReadAllText(xmlPath)); + using (var xmlReader = XmlReader.Create(sReader)) + { + XPathDocument xpath = null; + try + { + xpath = new XPathDocument(xmlReader); + } + catch + { + return null; + } + var xmlNav = xpath.CreateNavigator(); + + var className = (localType.IsNested ? $"{localType.Namespace}.{localType.DeclaringType.Name}.{localType.Name}" : $"{localType.Namespace}.{localType.Name}").Trim('.'); + var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='T:{className}']/summary"); + if (node != null) + { + var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); + if (string.IsNullOrEmpty(comment) == false) dic.Add("", comment); //class注释 + } + + var props = localType.GetPropertiesDictIgnoreCase().Values; + foreach (var prop in props) + { + className = (prop.DeclaringType.IsNested ? $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.DeclaringType.Name}.{prop.DeclaringType.Name}" : $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.Name}").Trim('.'); + node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); + if (node == null) + { + if (level == 0 && prop.DeclaringType.Assembly != localType.Assembly) + { + var cbs = LocalGetComment(prop.DeclaringType, level + 1); + if (cbs != null && cbs.TryGetValue(prop.Name, out var otherComment) && string.IsNullOrEmpty(otherComment) == false) + dic.Add(prop.Name, otherComment); + } + continue; + } + var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); + if (string.IsNullOrEmpty(comment)) continue; + + dic.Add(prop.Name, comment); + } + } + return dic; } - - var dic = new Dictionary(); - var sReader = new StringReader(File.ReadAllText(xmlPath)); - using (var xmlReader = XmlReader.Create(sReader)) - { - XPathDocument xpath = null; - try - { - xpath = new XPathDocument(xmlReader); - } - catch - { - return null; - } - var xmlNav = xpath.CreateNavigator(); - - var className = (type.IsNested ? $"{type.Namespace}.{type.DeclaringType.Name}.{type.Name}" : $"{type.Namespace}.{type.Name}").Trim('.'); - var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='T:{className}']/summary"); - if (node != null) - { - var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); - if (string.IsNullOrEmpty(comment) == false) dic.Add("", comment); //class注释 - } - - var props = type.GetPropertiesDictIgnoreCase().Values; - foreach (var prop in props) - { - className = (prop.DeclaringType.IsNested ? $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.DeclaringType.Name}.{prop.DeclaringType.Name}" : $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.Name}").Trim('.'); - node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); - if (node == null) continue; - var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); - if (string.IsNullOrEmpty(comment)) continue; - - dic.Add(prop.Name, comment); - } - } - - return dic; } public static void PrevReheatConnectionPool(ObjectPool pool, int minPoolSize) From 9fa4350062c53a4585902332b6ce6592e079aebb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 29 Sep 2020 13:07:25 +0800 Subject: [PATCH 0934/1029] v1.10.0-preview1001 #479 #476 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 160 ------------------ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 22 insertions(+), 182 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 656d0a46..661f7fbe 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 6149376f..42740a68 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 9e005ee7..60b93e2f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 07163fff..cfcd57d4 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 304692b9..5513ab70 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.0 + 1.10.0-preview1001 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 499e4f86..8d049d9b 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 16bdbdd6..226a0456 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7310b4dd..8b7d5e15 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.0 + 1.10.0-preview1001 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b65ff569..53905f91 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8fd7f738..4b1686ea 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2997,154 +2997,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3951,12 +3803,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4027,12 +3873,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 2d7846d6..93ae57c7 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index b16b8c6d..aab90efc 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index d7da136a..fbeab70d 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 26cc244e..fdd79e88 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 89ac1e76..5cc6cfe5 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index de583b22..fbcbc845 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 034a3e15..78c698b7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 92c1bbd0..79bfb27d 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1f837f47..a9e5fa94 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index f7339e79..6d8619bc 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index acdc89d9..03dc1dd7 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 292ad836..ba715425 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index ca56966c..641479e0 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.0 + 1.10.0-preview1001 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From c12c5523525818abaa05b03d2dfd6ae70b6e7964 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 7 Oct 2020 22:28:07 +0800 Subject: [PATCH 0935/1029] update summary --- .../Extensions/FreeSqlDbContextExtensions.cs | 2 +- FreeSql/FreeSql.xml | 160 ++++++++++++++++++ 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs index f0ad468e..60a7394f 100644 --- a/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs +++ b/FreeSql.DbContext/Extensions/FreeSqlDbContextExtensions.cs @@ -17,7 +17,7 @@ public static partial class FreeSqlDbContextExtensions } /// - /// 不跟踪查询的实体数据(在不需要更新其数据时使用),可提长查询性能 + /// 不跟踪查询的实体数据(在不需要更新其数据时使用),可提升查询性能 /// /// /// diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 4b1686ea..8fd7f738 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2997,6 +2997,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3803,6 +3951,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3873,6 +4027,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 From efa71e8cba14f905ca2b313e0805ceb17c85f009 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 10 Oct 2020 16:58:29 +0800 Subject: [PATCH 0936/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20WhereDynamic?= =?UTF-8?q?=20=E6=94=AF=E6=8C=81=E6=8C=89=E5=AD=97=E6=AE=B5=E5=90=8D?= =?UTF-8?q?=E3=80=81=E5=B1=9E=E6=80=A7=E5=90=8D=E5=8C=B9=E9=85=8D=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 18 +-------------- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 28 ++++++++++++++---------- FreeSql/Internal/CommonUtils.cs | 5 ++++- 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 743835e4..d198eb6c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -483,7 +476,7 @@ - 不跟踪查询的实体数据(在不需要更新其数据时使用),可提长查询性能 + 不跟踪查询的实体数据(在不需要更新其数据时使用),可提升查询性能 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 003bd4d2..2898efc6 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -156,18 +156,18 @@ namespace FreeSql.Tests } } - class testInsertNullable - { - [Column(IsNullable = false, IsIdentity = true)] - public long Id { get; set; } +class testInsertNullable +{ + [Column(IsNullable = false, IsIdentity = true)] + public long Id { get; set; } - [Column(IsNullable = false)] - public string str1 { get; set; } - [Column(IsNullable = false)] - public int? int1 { get; set; } - [Column(IsNullable = true)] - public int int2 { get; set; } - } + [Column(IsNullable = false)] + public string str1 { get; set; } + [Column(IsNullable = false)] + public int? int1 { get; set; } + [Column(IsNullable = true)] + public int int2 { get; set; } +} class testUpdateNonePk { @@ -177,6 +177,12 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var updateSql = g.sqlite.Update() + .AsType(typeof(testInsertNullable)) + .SetDto(new { str1 = "xxx" }) + .WhereDynamic(1) + .ToSql(); + var sqlextMax112 = g.sqlserver.Select() .GroupBy(a => a.Id) .ToSql(a => new diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 6b8f85d0..0bcd1bbd 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -333,7 +333,10 @@ namespace FreeSql.Internal var psidx = 0; foreach (var p in ps) { - if (table.Columns.TryGetValue(p.Name, out var trycol) == false) continue; + table.Columns.TryGetValue(p.Name, out var trycol); + if (trycol == null) table.ColumnsByCs.TryGetValue(p.Name, out trycol); + if (trycol == null) continue; + if (psidx > 0) sb.Append(" AND "); sb.Append(aliasAndDot).Append(this.QuoteSqlName(trycol.Attribute.Name)); sb.Append(this.FormatSql(" = {0}", Utils.GetDataReaderValue(trycol.Attribute.MapType, p.GetValue(dywhere, null)))); From e777e7e86f9e92cdcabee9672ea2aa836324f9cc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 12 Oct 2020 12:53:16 +0800 Subject: [PATCH 0937/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=86=85?= =?UTF-8?q?=E9=83=A8=20decimal=20=E9=BB=98=E8=AE=A4=E5=80=BC=E5=9C=A8=20co?= =?UTF-8?q?re=203.1+=20=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 23 +++++++++++++++++++ Examples/base_entity/base_entity.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++++++++++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 4ce60e3a..946fc5ca 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -69,6 +69,24 @@ namespace base_entity public Sys_reg_user RegUser { get; set; } } + public class tttorder + { + [Column(IsPrimary = true)] + public long Id { get; set; } + public string Title { get; set; } + public int Quantity { get; set; } + public decimal Price { get; set; } + + + public tttorder(string title, int quantity, decimal price) + { + Id = DateTime.Now.Ticks; + Title = title; + Quantity = quantity; + Price = price; + } + } + static void Main(string[] args) { #region 初始化 IFreeSql @@ -107,6 +125,11 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + fsql.Insert(new tttorder("xx1", 1, 10)).ExecuteAffrows(); + fsql.Insert(new tttorder("xx2", 2, 20)).ExecuteAffrows(); + + var tttorders = fsql.Select().Limit(2).ToList(); + var tsql1 = fsql.Select() .Include(a => a.Owner) .Where(a => a.UnionId == "xxx") diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index 201c18db..b2bcd550 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1 + netcoreapp3.1 diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d198eb6c..ce9ce69d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index d8657041..c4534b31 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -151,7 +151,7 @@ public static partial class FreeSqlGlobalExtensions { var ret = _dicInternalGetTypeConstructor0OrFirst.GetOrAdd(that, tp => tp.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null) ?? - tp.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault()); + tp.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).OrderBy(a => a.IsPublic ? 0 : 1).FirstOrDefault()); if (ret == null && isThrow) throw new ArgumentException($"{that.FullName} 类型无方法访问构造函数"); return ret; } From e1a265f7aa0337ca12ad51ad5f61f7830bd8976d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Oct 2020 09:52:19 +0800 Subject: [PATCH 0938/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ToAggregate?= =?UTF-8?q?=20=E6=89=A7=E8=A1=8C=E6=97=B6=E5=BF=BD=E7=95=A5=E5=B7=B2?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=9A=84=20OrderBy=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectProvider/Select0ProviderReader.cs | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 079c25e2..408d1193 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -711,12 +711,21 @@ namespace FreeSql.Internal.CommonProvider protected TReturn InternalToAggregate(Expression select) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; + var tmpOrderBy = _orderby; + _orderby = null; //解决 select count(1) from t order by id 这样的 SQL 错误 + try + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany - return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany + return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); + } + finally + { + _orderby = tmpOrderBy; + } } public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params)); @@ -967,12 +976,21 @@ namespace FreeSql.Internal.CommonProvider async protected Task InternalToAggregateAsync(Expression select) { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; + var tmpOrderBy = _orderby; + _orderby = null; //解决 select count(1) from t order by id 这样的 SQL 错误 + try + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany - return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany + return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); + } + finally + { + _orderby = tmpOrderBy; + } } #endif #endregion From 4473fc2be5096b17ac772365e98a97639d654d3f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Oct 2020 10:09:28 +0800 Subject: [PATCH 0939/1029] v1.10.0-preview1013 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 347 ++++++++++-------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 209 insertions(+), 182 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 661f7fbe..1e4031bd 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 42740a68..fa1ffb8c 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 60b93e2f..d39e126d 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index cfcd57d4..d811f00f 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 5513ab70..c5ffd570 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.0-preview1001 + 1.10.0-preview1013 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 8d049d9b..0aa51a3c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 226a0456..64a0d3cf 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 8b7d5e15..73aac0a7 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 53905f91..303081cf 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8fd7f738..c65b9fa8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2997,154 +2997,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3951,12 +3803,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4027,12 +3873,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4643,3 +4483,190 @@ +essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 93ae57c7..738b0c39 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index aab90efc..748ec88d 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index fbeab70d..1abaf886 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index fdd79e88..37aa494d 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5cc6cfe5..ad0be2bd 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index fbcbc845..b37aa0ff 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 78c698b7..76ae1a7c 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 79bfb27d..6d25723e 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index a9e5fa94..7b8ddfc3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 6d8619bc..c0b8b044 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 03dc1dd7..9b113f4a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index ba715425..790460a7 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 641479e0..5b84cabf 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1001 + 1.10.0-preview1013 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 682b5b35b80e3e288eaccc45d1b46bf8e14ea550 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Oct 2020 17:26:12 +0800 Subject: [PATCH 0940/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20DbContext/Un?= =?UTF-8?q?itOfWork=20EntityChangeReport=20=E5=8F=82=E6=95=B0=20BeforeObje?= =?UTF-8?q?ct=20=E5=80=BC=E6=97=A0=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ValuesController.cs | 2 + FreeSql.DbContext/DbSet/DbSetAsync.cs | 2 +- FreeSql.DbContext/DbSet/DbSetSync.cs | 2 +- FreeSql/FreeSql.xml | 347 ++++++++---------- 4 files changed, 164 insertions(+), 189 deletions(-) diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs index 6bedf450..08586291 100644 --- a/Examples/dbcontext_01/Controllers/ValuesController.cs +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -44,6 +44,8 @@ namespace dbcontext_01.Controllers var song = new Song { Title = "empty" }; repos2Song.Insert(song); + song.Title = "empty01"; + repos2Song.Update(song); id = song.Id; var adds = Enumerable.Range(0, 100) diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index c2fe6994..8844e7f1 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -373,7 +373,7 @@ namespace FreeSql var affrows = await update.ExecuteAffrowsAsync(); _db._entityChangeReport.AddRange(data.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, - BeforeObject = _states.TryGetValue(a.Key, out var beforeVal) ? beforeVal.Value : null, + BeforeObject = _states.TryGetValue(a.Key, out var beforeVal) ? CreateEntityState(beforeVal.Value).Value : null, Type = DbContext.EntityChangeType.Update })); diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 3df68e7f..82d61482 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -410,7 +410,7 @@ namespace FreeSql _db._entityChangeReport.AddRange(data.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, - BeforeObject = _states.TryGetValue(a.Key, out var beforeVal) ? beforeVal.Value : null, + BeforeObject = _states.TryGetValue(a.Key, out var beforeVal) ? CreateEntityState(beforeVal.Value).Value : null, Type = DbContext.EntityChangeType.Update })); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c65b9fa8..8fd7f738 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2997,6 +2997,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3803,6 +3951,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3873,6 +4027,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4483,190 +4643,3 @@ -essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 条件 - - - - From 7153cdf9f6a20a4d770196b9ba074352dfe26533 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 13 Oct 2020 17:27:57 +0800 Subject: [PATCH 0941/1029] v1.10.0-preview1015 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 22 insertions(+), 38 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1e4031bd..162fdf23 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index fa1ffb8c..57902c2a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index d39e126d..a59cb606 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index d811f00f..41d7bf4e 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index c5ffd570..27e4fe2f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.0-preview1013 + 1.10.0-preview1015 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 0aa51a3c..8c99c97e 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 64a0d3cf..abf8b68f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ce9ce69d..d198eb6c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 73aac0a7..39bee866 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 303081cf..1d6287fe 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 738b0c39..0fb38d34 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 748ec88d..57cdd24c 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 1abaf886..4146c374 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 37aa494d..87e5acb8 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index ad0be2bd..97070150 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index b37aa0ff..6255fc52 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 76ae1a7c..f381e6b6 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6d25723e..aed77b08 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7b8ddfc3..f6d0bf70 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index c0b8b044..4c64fa62 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9b113f4a..eff9bc7c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 790460a7..86e95480 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5b84cabf..9842d7ca 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1013 + 1.10.0-preview1015 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 38d8a3756c80686e9c8df9609cbf7ae825030e1d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 14 Oct 2020 17:55:49 +0800 Subject: [PATCH 0942/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20decimal=3F?= =?UTF-8?q?=20=E5=8F=AF=E7=A9=BA=E6=95=B0=E5=AD=97=E8=AE=BE=E7=BD=AE=20Col?= =?UTF-8?q?umn=20Scale=20=E6=97=A0=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98(dec?= =?UTF-8?q?imal=E6=AD=A3=E5=B8=B8)=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 | 25 +- FreeSql/FreeSql.xml | 347 ++++++++++++----------- FreeSql/Internal/UtilsExpressionTree.cs | 6 +- 4 files changed, 221 insertions(+), 173 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d198eb6c..ce9ce69d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 2898efc6..e60d9450 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -156,18 +156,21 @@ namespace FreeSql.Tests } } -class testInsertNullable -{ - [Column(IsNullable = false, IsIdentity = true)] - public long Id { get; set; } + class testInsertNullable + { + [Column(IsNullable = false, IsIdentity = true)] + public long Id { get; set; } - [Column(IsNullable = false)] - public string str1 { get; set; } - [Column(IsNullable = false)] - public int? int1 { get; set; } - [Column(IsNullable = true)] - public int int2 { get; set; } -} + [Column(IsNullable = false)] + public string str1 { get; set; } + [Column(IsNullable = false)] + public int? int1 { get; set; } + [Column(IsNullable = true)] + public int int2 { get; set; } + + [Column(Precision = 10, Scale = 5)] + public decimal? price { get; set; } + } class testUpdateNonePk { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8fd7f738..c65b9fa8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2997,154 +2997,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3951,12 +3803,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4027,12 +3873,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4643,3 +4483,190 @@ +essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 148ac6c4..0d286190 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -228,7 +228,7 @@ namespace FreeSql.Internal col.DbDefaultValue = colattr.InsertValueSql; col.DbInsertValue = colattr.InsertValueSql; } - if (colattr.MapType == typeof(string) && colattr.StringLength != 0) + if (colattr.MapType.NullableTypeOrThis() == typeof(string) && colattr.StringLength != 0) { int strlen = colattr.StringLength; var charPatten = @"(CHARACTER|CHAR2|CHAR)\s*(\([^\)]*\))?"; @@ -328,8 +328,10 @@ namespace FreeSql.Internal break; } } - if (colattr.MapType == typeof(decimal) && colattr.Precision > 0) + if (colattr.MapType.NullableTypeOrThis() == typeof(decimal) && (colattr.Precision > 0 || colattr.Scale > 0)) { + if (colattr.Precision <= 0) colattr.Precision = 10; + if (colattr.Scale <= 0) colattr.Scale = 0; var decimalPatten = @"(DECIMAL|NUMERIC|NUMBER)\s*(\([^\)]*\))?"; colattr.DbType = Regex.Replace(colattr.DbType, decimalPatten, $"$1({colattr.Precision},{colattr.Scale})"); } From 013a7ada3681555c5a0c43039425193509e05d04 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 14 Oct 2020 20:40:59 +0800 Subject: [PATCH 0943/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20lambda=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E6=97=B6=E7=9A=84=20bug=EF=BC=9B#490?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 7 + FreeSql/FreeSql.xml | 347 ++++++++---------- FreeSql/Internal/CommonExpression.cs | 3 +- 4 files changed, 169 insertions(+), 204 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ce9ce69d..d198eb6c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 2612b4b2..e018ae54 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -421,6 +421,13 @@ namespace FreeSql.Tests.MySql var items = select.ToList(); var itemstb = select.ToDataTable(); + + var sql1 = select.Where(a => a.testFieldInt == (int)Tb_alltypeTESTFIELDENUM1.E2).ToSql(); + var sql2id = (int)Tb_alltypeTESTFIELDENUM1.E2; + var sql2 = select.Where(a => a.testFieldInt == sql2id).ToSql(); + var sql3id = Tb_alltypeTESTFIELDENUM1.E2; + var sql4 = select.Where(a => a.testFieldInt == (int)sql3id).ToSql(); + } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c65b9fa8..8fd7f738 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2997,6 +2997,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3803,6 +3951,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3873,6 +4027,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4483,190 +4643,3 @@ -essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 cf3fbaac..a82aa611 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -680,7 +680,8 @@ namespace FreeSql.Internal case ExpressionType.ConvertChecked: //var othercExp = ExpressionLambdaToSqlOther(exp, tsc); //if (string.IsNullOrEmpty(othercExp) == false) return othercExp; - return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); + if (exp.IsParameter()) return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); + return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); //bug: Where(a => a.Id = (int)enum) case ExpressionType.Negate: case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, null); From 9d33779092d1444afce566222091e96de08329f0 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 15 Oct 2020 01:31:50 +0800 Subject: [PATCH 0944/1029] v1.10.0-preview1018 #490 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../PostgreSQLExpression/OtherTest.cs | 44 +++++++++---------- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 3 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 6 ++- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 25 files changed, 50 insertions(+), 47 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 162fdf23..413d951e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 57902c2a..debc943a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a59cb606..684b17db 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 41d7bf4e..1a225537 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 27e4fe2f..25a5b8dd 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.0-preview1015 + 1.10.0-preview1018 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 8c99c97e..610e9f42 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index abf8b68f..5872588d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 39bee866..11fe0bdb 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index e18c9ef2..a70426b1 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -142,34 +142,34 @@ namespace FreeSql.Tests.PostgreSQLExpression public void Jsonb() { - var sql1 = select.Where(a => a.testFieldJToken.Contains(JToken.Parse("{a:1}"))).ToList(); - var sql2 = select.Where(a => a.testFieldJToken.Contains(JToken.Parse("{a:1}")) == false).ToList(); - var sql111 = select.Where(a => a.testFieldJToken.Contains("{a:1}")).ToList(); - var sql222 = select.Where(a => a.testFieldJToken.Contains("{a:1}") == false).ToList(); + var sql1 = select.Where(a => a.testFieldJToken.Contains(JToken.Parse("{a:1}"))).Limit(10).ToList(); + var sql2 = select.Where(a => a.testFieldJToken.Contains(JToken.Parse("{a:1}")) == false).Limit(10).ToList(); + var sql111 = select.Where(a => a.testFieldJToken.Contains("{\"a\":1}")).Limit(10).ToList(); + var sql222 = select.Where(a => a.testFieldJToken.Contains("{\"a\":1}") == false).Limit(10).ToList(); - var sql3 = select.Where(a => a.testFieldJObject.ContainsKey("a")).ToList(); - var sql4 = select.Where(a => a.testFieldJObject.ContainsKey("a") == false).ToList(); + var sql3 = select.Where(a => a.testFieldJObject.ContainsKey("a")).Limit(10).ToList(); + var sql4 = select.Where(a => a.testFieldJObject.ContainsKey("a") == false).Limit(10).ToList(); - var sql5 = select.Where(a => a.testFieldJArray.Contains(1)).ToList(); - var sql6 = select.Where(a => a.testFieldJArray.Contains(1) == false).ToList(); - var sql555 = select.Where(a => a.testFieldJArray.Contains(1)).ToList(); - var sql666 = select.Where(a => a.testFieldJArray.Contains(1) == false).ToList(); + var sql5 = select.Where(a => a.testFieldJArray.Contains(1)).Limit(10).ToList(); + var sql6 = select.Where(a => a.testFieldJArray.Contains(1) == false).Limit(10).ToList(); + var sql555 = select.Where(a => a.testFieldJArray.Contains(1)).Limit(10).ToList(); + var sql666 = select.Where(a => a.testFieldJArray.Contains(1) == false).Limit(10).ToList(); - //var sql7 = select.Where(a => a.testFieldJToken.Any()).ToList(); - //var sql8 = select.Where(a => a.testFieldJToken.Any() == false).ToList(); + //var sql7 = select.Where(a => a.testFieldJToken.Any()).Limit(10).ToList(); + //var sql8 = select.Where(a => a.testFieldJToken.Any() == false).Limit(10).ToList(); - var sql9 = select.Where(a => a.testFieldJArray.Any()).ToList(); - var sql10 = select.Where(a => a.testFieldJArray.Any() == false).ToList(); + var sql9 = select.Where(a => a.testFieldJArray.Any()).Limit(10).ToList(); + var sql10 = select.Where(a => a.testFieldJArray.Any() == false).Limit(10).ToList(); - //var sql11 = select.ToList(a => a.testFieldJToken.Concat(JToken.Parse("{a:1}"))); - //var sql12 = select.ToList(a => a.testFieldJObject.Concat(JToken.Parse("{a:1}"))); - //var sql13 = select.ToList(a => a.testFieldJArray.Concat(JToken.Parse("{a:1}"))); + //var sql11 = select.Limit(10).ToList(a => a.testFieldJToken.Concat(JToken.Parse("{a:1}"))); + //var sql12 = select.Limit(10).ToList(a => a.testFieldJObject.Concat(JToken.Parse("{a:1}"))); + //var sql13 = select.Limit(10).ToList(a => a.testFieldJArray.Concat(JToken.Parse("{a:1}"))); - //var sql14 = select.Where(a => a.testFieldJToken.Count() > 0).ToList(); - //var sql15 = select.Where(a => a.testFieldJObject.Count > 0).ToList(); - var sql16 = select.Where(a => a.testFieldJArray.Count() > 0).ToList(); - var sql17 = select.Where(a => a.testFieldJArray.LongCount() > 0).ToList(); - var sql18 = select.Where(a => a.testFieldJArray.Count > 0).ToList(); + //var sql14 = select.Where(a => a.testFieldJToken.Count() > 0).Limit(10).ToList(); + //var sql15 = select.Where(a => a.testFieldJObject.Count > 0).Limit(10).ToList(); + var sql16 = select.Where(a => a.testFieldJArray.Count() > 0).Limit(10).ToList(); + var sql17 = select.Where(a => a.testFieldJArray.LongCount() > 0).Limit(10).ToList(); + var sql18 = select.Where(a => a.testFieldJArray.Count > 0).Limit(10).ToList(); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index e60d9450..ede9eb88 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -205,7 +205,8 @@ namespace FreeSql.Tests ""Id"" INTEGER PRIMARY KEY AUTOINCREMENT, ""str1"" NVARCHAR(255) NOT NULL, ""int1"" INTEGER NOT NULL, - ""int2"" INTEGER + ""int2"" INTEGER , + ""price"" DECIMAL(10,5) ) ; ", ddlsql); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 1d6287fe..fdf00b9b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index a82aa611..94ee782b 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -680,8 +680,10 @@ namespace FreeSql.Internal case ExpressionType.ConvertChecked: //var othercExp = ExpressionLambdaToSqlOther(exp, tsc); //if (string.IsNullOrEmpty(othercExp) == false) return othercExp; - if (exp.IsParameter()) return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); - return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); //bug: Where(a => a.Id = (int)enum) + var expOperand = (exp as UnaryExpression)?.Operand; + if (expOperand.Type.NullableTypeOrThis().IsEnum && exp.IsParameter() == false) + return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); //bug: Where(a => a.Id = (int)enum) + return ExpressionLambdaToSql(expOperand, tsc); case ExpressionType.Negate: case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType, tsc.mapColumnTmp, null); diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 0fb38d34..2c4714bd 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 57cdd24c..26cf8f6d 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 4146c374..9f588046 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 87e5acb8..809affa8 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 97070150..e1615a94 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 6255fc52..7a5a69cf 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index f381e6b6..630a754a 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index aed77b08..63d431c4 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index f6d0bf70..b848db4b 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 4c64fa62..c8f999a9 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index eff9bc7c..b1c06514 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 86e95480..6a9c80cd 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 9842d7ca..2a675e0a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1015 + 1.10.0-preview1018 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From db6a13c6f16857a13030099d50891d01f9302069 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 15 Oct 2020 11:48:58 +0800 Subject: [PATCH 0945/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=AE=9E=E4=BD=93=E7=B1=BB=E4=BD=BF=E7=94=A8=20new=20?= =?UTF-8?q?=E9=87=8D=E5=86=99=E5=B1=9E=E6=80=A7=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ++ .../MySql/MySqlCodeFirstTest.cs | 79 +++++++++++++++++++ .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 79 +++++++++++++++++++ .../SqlServer/SqlServerCodeFirstTest.cs | 79 +++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/g.cs | 5 -- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 6 +- 6 files changed, 249 insertions(+), 6 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d198eb6c..ab4c3bf2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs index 3be75126..e269e7e0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlCodeFirstTest.cs @@ -10,6 +10,85 @@ namespace FreeSql.Tests.Odbc.MySql { public class MySqlCodeFirstTest { + [Fact] + public void EnumStartValue1() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + + var repo = fsql.GetRepository(); + var item1 = repo.Insert(new TS_ESV1 { Status = TS_TSV1_Status.Status1 }); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status1' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status1).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status2' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status2).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status3' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status3).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status1' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status1).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status2' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status2).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status3' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status3).ToSql().Replace("\r\n", "")); + + item1.Status = TS_TSV1_Status.Status1; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status2; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status3; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status3; + fsql.GetRepository().Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status2; + fsql.GetRepository().Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + } + public class TS_ESV1 + { + public Guid Id { get; set; } + public TS_TSV1_Status Status { get; set; } + } + public enum TS_TSV1_Status + { + Status1 = 1, + Status2 = 3, + Status3 = 5 + } + [Fact] public void StringLength() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index e018ae54..43501614 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -11,6 +11,85 @@ namespace FreeSql.Tests.MySql { public class MySqlCodeFirstTest { + [Fact] + public void EnumStartValue1() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + + var repo = fsql.GetRepository(); + var item1 = repo.Insert(new TS_ESV1 { Status = TS_TSV1_Status.Status1 }); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status1' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status1).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status2' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status2).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status3' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status3).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status1' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status1).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status2' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status2).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status3' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status3).ToSql().Replace("\r\n", "")); + + item1.Status = TS_TSV1_Status.Status1; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status2; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status3; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status3; + fsql.GetRepository().Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status2; + fsql.GetRepository().Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + } + public class TS_ESV1 + { + public Guid Id { get; set; } + public TS_TSV1_Status Status { get; set; } + } + public enum TS_TSV1_Status + { + Status1 = 1, + Status2 = 3, + Status3 = 5 + } + [Fact] public void DateTime_1() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 34c6c2e4..fac3b6e9 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -12,6 +12,85 @@ namespace FreeSql.Tests.SqlServer { public class SqlServerCodeFirstTest { + [Fact] + public void EnumStartValue1() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + + var repo = fsql.GetRepository(); + var item1 = repo.Insert(new TS_ESV1 { Status = TS_TSV1_Status.Status1 }); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + Assert.Equal($"UPDATE [TS_ESV1] SET [Status] = 1 WHERE ([Id] = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status1).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE [TS_ESV1] SET [Status] = 3 WHERE ([Id] = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status2).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE [TS_ESV1] SET [Status] = 5 WHERE ([Id] = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status3).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE [TS_ESV1] SET [Status] = 1 WHERE ([Id] = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status1).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE [TS_ESV1] SET [Status] = 3 WHERE ([Id] = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status2).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE [TS_ESV1] SET [Status] = 5 WHERE ([Id] = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status3).ToSql().Replace("\r\n", "")); + + item1.Status = TS_TSV1_Status.Status1; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status2; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status3; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status3; + fsql.GetRepository().Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status2; + fsql.GetRepository().Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + } + public class TS_ESV1 + { + public Guid Id { get; set; } + public TS_TSV1_Status Status { get; set; } + } + public enum TS_TSV1_Status + { + Status1 = 1, + Status2 = 3, + Status3 = 5 + } + [Fact] public void Blob() { diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 533be9f6..43f83258 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -42,12 +42,7 @@ public class g static Lazy sqlserverLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") - //.UseConnectionFactory(FreeSql.DataType.SqlServer, () => new Microsoft.Data.SqlClient.SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;")) - //.UseConnectionFactory(FreeSql.DataType.SqlServer, () => new System.Data.SqlClient.SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;")) - //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;Max Pool Size=3") - //.UseConnectionFactory(FreeSql.DataType.SqlServer, () => new System.Data.SqlClient.SqlConnection("Data Source=192.168.164.129;uid=sa;pwd=123456;Initial Catalog=ds_shop;Pooling=true;")) .UseAutoSyncStructure(true) - //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 //, (cmd, traceLog) => Console.WriteLine(traceLog) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index c4534b31..7925f280 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -163,7 +163,11 @@ public static partial class FreeSqlGlobalExtensions var dict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); foreach (var prop in props) { - if (dict.ContainsKey(prop.Name)) continue; + if (dict.TryGetValue(prop.Name, out var existsProp)) + { + if (existsProp.DeclaringType != prop) dict[prop.Name] = prop; + continue; + } dict.Add(prop.Name, prop); } return dict; From b3f8c112f13c111c78006a550df0fc3c5c74868c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 15 Oct 2020 11:53:37 +0800 Subject: [PATCH 0946/1029] v1.10.0-preview1019 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 31 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 413d951e..7b217885 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index debc943a..0dbdcdb2 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 684b17db..f7a526a7 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 1a225537..8f9b96ba 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 25a5b8dd..50c3c79d 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.0-preview1018 + 1.10.0-preview1019 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 610e9f42..df173ce9 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 5872588d..8d878662 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ab4c3bf2..ce9ce69d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -532,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 11fe0bdb..57bbc41a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fdf00b9b..c7b39b64 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 2c4714bd..387c3e27 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 26cf8f6d..6326d0e4 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 9f588046..188feb38 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 809affa8..1ce556ac 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e1615a94..d32befa1 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7a5a69cf..a1efd6a5 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 630a754a..cdc2be36 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 63d431c4..dab2fb45 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b848db4b..d842f101 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index c8f999a9..4cf5007b 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b1c06514..eb6cdca0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 6a9c80cd..5294ab0c 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 2a675e0a..2e5cef7f 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1018 + 1.10.0-preview1019 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 935cd5ba8c47b7386a1217e7f23965c851706efd Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 16 Oct 2020 13:32:34 +0800 Subject: [PATCH 0947/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20dto=20?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E6=9F=A5=E8=AF=A2=E6=97=B6=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E5=B7=B2=E6=8C=87=E5=AE=9A=E7=9A=84=E6=98=A0=E5=B0=84=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E9=87=8D=E5=A4=8D=E6=9F=A5=E8=AF=A2=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=9B#494?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/CommonExpression.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 94ee782b..da329ba1 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -204,6 +204,7 @@ namespace FreeSql.Internal } else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) { + var dicBindings = initExp.Bindings?.Select(a => a.Member.Name).Distinct().ToDictionary(a => a, a => false); //dto 映射 var dtoProps = initExp.NewExpression.Type.GetPropertiesDictIgnoreCase().Values; foreach (var dtoProp in dtoProps) @@ -212,6 +213,7 @@ namespace FreeSql.Internal { if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue; if (trydtocol.Attribute.IsIgnore == true) continue; + if (dicBindings?.ContainsKey(dtoProp.Name) == true) continue; var child = new ReadAnonymousTypeInfo { From fc47407fbaa1a2e1b05c27ea913e4d2e4a6324d4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 16 Oct 2020 14:29:36 +0800 Subject: [PATCH 0948/1029] Add test code #494 --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 -------- FreeSql.Tests/FreeSql.Tests/Issues/494.cs | 47 +++++++++++++++++++++++ 2 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/494.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ce9ce69d..d198eb6c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/494.cs b/FreeSql.Tests/FreeSql.Tests/Issues/494.cs new file mode 100644 index 00000000..09e87f56 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/494.cs @@ -0,0 +1,47 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _494 + { + [Fact] + public void SelectTest() + { + var fsql = g.sqlite; + var sql = fsql.Queryable().ToSql(w => new LocStatusViewModel + { + CardNumber = w.Number.ToString(), + CardType = w.CommType + 1, + Name = w.Address, + No = w.Number.ToString() + }, FieldAliasOptions.AsProperty); + Assert.Equal(@"SELECT cast(a.""Number"" as character) CardNumber, ((a.""CommType"" + 1)) CardType, a.""Address"" Name, cast(a.""Number"" as character) No +FROM ""WorkSite"" a", sql); + } + + public class WorkSite + { + [Column(IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + public string Name { get; set; } + public int Number { get; set; } + public int CommType { get; set; } + public string Address { get; set; } + } + public class LocStatusViewModel + { + public string CardNumber { get; set; } + public int CardType { get; set; } + public string Name { get; set; } + public string No { get; set; } + } + } +} From acf26ecbefa3d9b2255161838d55eade03aaabb4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 16 Oct 2020 22:01:00 +0800 Subject: [PATCH 0949/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect.Inse?= =?UTF-8?q?rtInto=20=E5=B0=86=E6=9F=A5=E8=AF=A2=E8=BD=AC=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?=20INSERT=20INTO=20t1=20SELECT=20...=20FROM=20t2=20=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E6=8F=92=E5=85=A5=EF=BC=9B#469?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 + .../MySqlConnector/Curd/MySqlInsertTest.cs | 5 + .../Dameng/Curd/DamengInsertTest.cs | 5 + .../Firebird/Curd/FirebirdInsertTest.cs | 5 + .../KingbaseES/Curd/KingbaseESInsertTest.cs | 5 + .../MsAccess/Curd/MsAccessInsertTest.cs | 5 + .../MySql/Curd/MySqlInsertTest.cs | 5 + .../Oracle/Curd/OracleInsertTest.cs | 5 + .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 5 + .../ShenTong/Curd/ShenTongInsertTest.cs | 5 + .../SqlServer/Curd/SqlServerInsertTest.cs | 5 + .../Sqlite/Curd/SqliteInsertTest.cs | 5 + FreeSql/FreeSql.xml | 356 ++++++++++-------- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 10 + FreeSql/Interface/Curd/ISelect/ISelect10.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect11.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect12.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect13.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect14.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect15.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect16.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect2.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect3.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect4.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect5.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect6.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect7.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect8.cs | 2 + FreeSql/Interface/Curd/ISelect/ISelect9.cs | 2 + .../SelectProvider/Select0ProviderReader.cs | 81 ++++ .../SelectProvider/Select10Provider.cs | 14 + .../SelectProvider/Select11Provider.cs | 14 + .../SelectProvider/Select12Provider.cs | 14 + .../SelectProvider/Select13Provider.cs | 14 + .../SelectProvider/Select14Provider.cs | 14 + .../SelectProvider/Select15Provider.cs | 14 + .../SelectProvider/Select16Provider.cs | 14 + .../SelectProvider/Select1Provider.cs | 4 + .../SelectProvider/Select2Provider.cs | 16 + .../SelectProvider/Select3Provider.cs | 14 + .../SelectProvider/Select4Provider.cs | 14 + .../SelectProvider/Select5Provider.cs | 14 + .../SelectProvider/Select6Provider.cs | 14 + .../SelectProvider/Select7Provider.cs | 14 + .../SelectProvider/Select8Provider.cs | 14 + .../SelectProvider/Select9Provider.cs | 79 ++-- 46 files changed, 638 insertions(+), 191 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d198eb6c..ce9ce69d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -525,5 +532,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs index 73b8e612..48c9376e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertTest.cs @@ -105,6 +105,11 @@ namespace FreeSql.Tests.MySqlConnector Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + + Assert.Equal(10, g.mysql.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs index 988f0685..fbbf4931 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs @@ -177,6 +177,11 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(900) Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(10, g.dameng.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs index 0f14a9b8..1d7d3161 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdInsertTest.cs @@ -215,6 +215,11 @@ UNION ALL Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); Assert.Equal(10, insert.NoneParameter().AppendData(items).ExecuteAffrows()); + + Assert.Equal(10, g.firebird.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertTest.cs index bf4411ca..eb400cf0 100644 --- a/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/Curd/KingbaseESInsertTest.cs @@ -89,6 +89,11 @@ namespace FreeSql.Tests.KingbaseES Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(10, g.kingbaseES.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs index c2e44197..3e8fcf0e 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/Curd/MsAccessInsertTest.cs @@ -92,6 +92,11 @@ namespace FreeSql.Tests.MsAccess //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); //Assert.Equal(9989, g.msaccess.Insert(items).ExecuteAffrows()); + + Assert.Equal(10, g.msaccess.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs index 3f4ee371..ff75484b 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertTest.cs @@ -106,6 +106,11 @@ namespace FreeSql.Tests.MySql Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + + Assert.Equal(10, g.mysql.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs index 6f0bff0f..64315042 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs @@ -177,6 +177,11 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_9) Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(10, g.oracle.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs index 3617db5c..0803513d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -89,6 +89,11 @@ namespace FreeSql.Tests.PostgreSQL Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(10, g.pgsql.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs index d036d099..e771cee9 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertTest.cs @@ -89,6 +89,11 @@ namespace FreeSql.Tests.ShenTong Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(10, g.shentong.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs index 20f73c87..7122c4fe 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs @@ -100,6 +100,11 @@ namespace FreeSql.Tests.SqlServer Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); Assert.Equal(10, insert.AppendData(items).NoneParameter().ExecuteAffrows()); + Assert.Equal(10, g.sqlserver.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); //Assert.Equal(9989, g.sqlserver.Insert(items).ExecuteAffrows()); diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs index ac532f9d..d3579aa0 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertTest.cs @@ -89,6 +89,11 @@ namespace FreeSql.Tests.Sqlite Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(10, g.sqlite.Select().Limit(10).InsertInto(null, a => new Topic + { + Title = a.Title + })); } [Fact] public void ExecuteIdentity() diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 8fd7f738..e984b6cb 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2046,6 +2046,15 @@ lambda表达式 + + + 将查询转换为 INSERT INTO tableName SELECT ... FROM t 执行插入 + + + 指定插入的表名,若为 null 则使用 TTargetEntity 实体表名 + 选择列 + 返回影响的行数 + 执行SQL查询,返回 DataTable @@ -2997,154 +3006,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3951,12 +3812,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4027,12 +3882,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4643,3 +4492,190 @@ +essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index b6cef93a..b5e061f5 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -15,6 +15,7 @@ namespace FreeSql #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -38,6 +39,15 @@ namespace FreeSql /// bool Any(Expression> exp); + /// + /// 将查询转换为 INSERT INTO tableName SELECT ... FROM t 执行插入 + /// + /// + /// 指定插入的表名,若为 null 则使用 TTargetEntity 实体表名 + /// 选择列 + /// 返回影响的行数 + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + /// /// 执行SQL查询,返回 DataTable /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index f35462e6..4b0a2862 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect11.cs b/FreeSql/Interface/Curd/ISelect/ISelect11.cs index 57e19df4..ef22e1a8 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect11.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect11.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect12.cs b/FreeSql/Interface/Curd/ISelect/ISelect12.cs index 05422fa9..c41853a9 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect12.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect12.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect13.cs b/FreeSql/Interface/Curd/ISelect/ISelect13.cs index fb87f33a..b1a5f708 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect13.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect13.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect14.cs b/FreeSql/Interface/Curd/ISelect/ISelect14.cs index 786fa125..42d8dbec 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect14.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect14.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect15.cs b/FreeSql/Interface/Curd/ISelect/ISelect15.cs index 9bdd3238..a0eaf778 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect15.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect15.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect16.cs b/FreeSql/Interface/Curd/ISelect/ISelect16.cs index 7d1651ba..2261ce16 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect16.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect16.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index a6aeaa28..0302108f 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index 35a6212a..7343cabe 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 93c6f809..622351c8 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index 12f4714b..ec19c52a 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index a6f6dffb..b18bdac0 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index 50c4f0a6..f16a7063 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index f03b7904..31f7d5c3 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 99218e60..7a528689 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -13,6 +13,7 @@ namespace FreeSql #if net40 #else Task AnyAsync(Expression> exp); + Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; Task ToDataTableAsync(Expression> select); Task> ToListAsync(Expression> select); Task> ToListAsync(); @@ -29,6 +30,7 @@ namespace FreeSql #endif bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); List ToList(Expression> select); List ToList(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 408d1193..550d1ad9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -683,6 +683,61 @@ namespace FreeSql.Internal.CommonProvider var af = this.GetExpressionField(select, fieldAlias); return this.ToSql(af.field); } + protected string InternalGetInsertIntoToSql(string tableName, Expression select) + { + var tb = _orm.CodeFirst.GetTableByEntity(typeof(TTargetEntity)); + if (tb == null) throw new ArgumentException($"ISelect.InsertInto() 类型错误: {typeof(TTargetEntity).DisplayCsharp()}"); + if (string.IsNullOrEmpty(tableName)) tableName = tb.DbName; + if (_orm.CodeFirst.IsSyncStructureToLower) tableName = tableName.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) tableName = tableName.ToUpper(); + + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = -10000; //临时规则,不返回 as1 + + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany + + var childs = map.Childs; + if (childs.Any() == false) throw new ArgumentException($"ISelect.InsertInto() 未选择属性: {typeof(TTargetEntity).DisplayCsharp()}"); + foreach(var col in tb.Columns.Values) + { + if (col.Attribute.IsIdentity && string.IsNullOrEmpty(col.DbInsertValue)) continue; + if (col.Attribute.CanInsert == false) continue; + if (childs.Any(a => a.CsName == col.CsName)) continue; + var dbfield = string.IsNullOrWhiteSpace(col.DbInsertValue) == false ? col.DbInsertValue : col.DbDefaultValue; + childs.Add(new ReadAnonymousTypeInfo { DbField = dbfield, CsName = col.CsName }); + } + var selectField = string.Join(", ", childs.Select(a => a.DbField)); + var selectSql = this.ToSql(selectField); + var insertField = string.Join(", ", childs.Select(a => _commonUtils.QuoteSqlName(tb.Columns[a.CsName].Attribute.Name))); + var sql = $"INSERT INTO {_commonUtils.QuoteSqlName(tableName)}({insertField})\r\n{selectSql}"; + return sql; + } + public int InternalInsertInto(string tableName, Expression select) + { + var sql = this.InternalGetInsertIntoToSql(tableName, select); + var dbParms = _params.ToArray(); + var tb = _orm.CodeFirst.GetTableByEntity(typeof(TTargetEntity)); + var before = new Aop.CurdBeforeEventArgs(tb.Type, tb, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + int ret = 0; + Exception exception = null; + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } protected DataTable InternalToDataTable(Expression select) { @@ -949,6 +1004,32 @@ namespace FreeSql.Internal.CommonProvider protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); + async public Task InternalInsertIntoAsync(string tableName, Expression select) + { + var sql = this.InternalGetInsertIntoToSql(tableName, select); + var dbParms = _params.ToArray(); + var tb = _orm.CodeFirst.GetTableByEntity(typeof(TTargetEntity)); + var before = new Aop.CurdBeforeEventArgs(tb.Type, tb, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + int ret = 0; + Exception exception = null; + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected Task InternalToDataTableAsync(Expression select) { var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 1e9a712a..f4027dcd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -160,6 +160,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -268,6 +275,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs index 593a7744..bef394ab 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs @@ -164,6 +164,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -272,6 +279,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs index f24459c2..bb338340 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs @@ -168,6 +168,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -276,6 +283,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs index d2006c68..8d859e11 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs @@ -172,6 +172,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -280,6 +287,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs index e8f7a9fe..92265894 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs @@ -176,6 +176,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -284,6 +291,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs index bb70221a..a9e85428 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs @@ -180,6 +180,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -288,6 +295,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs index 9388a4e7..81f078f2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs @@ -184,6 +184,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -292,6 +299,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 7e52c879..afda8923 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -392,6 +392,8 @@ namespace FreeSql.Internal.CommonProvider public override List ToList(bool includeNestedMembers = false) => base.ToList(_isIncluded || includeNestedMembers); + public int InsertInto(string tableName, Expression> select) where TTargetEntity : class => base.InternalInsertInto(tableName, select); + bool _isIncluded = false; public ISelect Include(Expression> navigateSelector) where TNavigate : class { @@ -1253,6 +1255,8 @@ namespace FreeSql.Internal.CommonProvider } public Task> ToListAsync() => ToListAsync(GetToListDtoSelector()); + public Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class => base.InternalInsertIntoAsync(tableName, select); + public Task ToDataTableAsync(Expression> select) { if (select == null) return this.InternalToDataTableAsync(select?.Body); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 005e485b..bba3c916 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -106,6 +106,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { @@ -114,6 +115,7 @@ namespace FreeSql.Internal.CommonProvider _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -128,6 +130,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -236,6 +245,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 707eccf8..e5d59a90 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -132,6 +132,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -240,6 +247,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index c23c314c..80752cd5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -136,6 +136,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -244,6 +251,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index d85e2577..ca7b7e23 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -140,6 +140,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -248,6 +255,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 71e7edd6..622e2b16 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -144,6 +144,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -252,6 +259,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 5b9657c3..70d4b819 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -148,6 +148,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -256,6 +263,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index ae1eb8bd..e7c71db7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -152,6 +152,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTable(select?.Body); } + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -260,6 +267,13 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToDataTableAsync(select?.Body); } + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + async Task ISelect.AnyAsync(Expression> exp) { if (exp == null) return await this.AnyAsync(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index f14ae04f..9e7c80f5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -38,15 +38,15 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"( {sqlT9} )"; + if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; + if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; + if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; + if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; + if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; + if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; + if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; + if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; + if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; return old; }); if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9}", parms)); @@ -55,7 +55,7 @@ namespace FreeSql.Internal.CommonProvider double ISelect.Avg(Expression> column) { - if (column == null) return default(double); + if (column == null) return 0; for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -155,6 +155,14 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToDataTable(select?.Body); } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) { if (select == null) return this.InternalToSql(select?.Body, fieldAlias); @@ -168,12 +176,14 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); } + ISelect ISelect.InnerJoin(Expression> exp) { if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); } + ISelect ISelect.RightJoin(Expression> exp) { if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); @@ -187,11 +197,12 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); } + ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this; + if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -210,25 +221,6 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - Task ISelect.AvgAsync(Expression> column) { if (column == null) return Task.FromResult(default(double)); @@ -270,6 +262,31 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToListAsync(select?.Body); } + Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); + + Task ISelect.ToDataTableAsync(Expression> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + + async Task ISelect.AnyAsync(Expression> exp) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); From 0783b432cff50d1193c6ced1a26bd41bf4089181 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 16 Oct 2020 22:08:29 +0800 Subject: [PATCH 0950/1029] v1.10.0-preview1020 #469 #494 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 347 ++++++++---------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 182 insertions(+), 209 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7b217885..a905979e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 0dbdcdb2..b06b232b 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index f7a526a7..5eb8853f 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 8f9b96ba..82a460e5 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 50c3c79d..d3c7bfdf 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.0-preview1019 + 1.10.0-preview1020 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index df173ce9..0bb71ac9 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 8d878662..846b89a7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 57bbc41a..3c031e37 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c7b39b64..551d50cb 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e984b6cb..1f74d636 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3006,6 +3006,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3812,6 +3960,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3882,6 +4036,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4492,190 +4652,3 @@ -essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 387c3e27..5992776d 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 6326d0e4..21624b54 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 188feb38..361f081b 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 1ce556ac..ce68fbac 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d32befa1..e2fb3eda 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a1efd6a5..80b94f73 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index cdc2be36..16e0bb78 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index dab2fb45..bc1f3c56 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index d842f101..7113d672 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 4cf5007b..1c7a1206 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index eb6cdca0..dfa01eee 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 5294ab0c..0e950996 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 2e5cef7f..de9c599e 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1019 + 1.10.0-preview1020 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From b91fe2ca4d34bb414f07a2b64b1df36dd4ccefbc Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 18 Oct 2020 19:23:13 +0800 Subject: [PATCH 0951/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Firebird=20E?= =?UTF-8?q?mbedded=20=E7=89=88=E6=9C=AC=E7=B3=BB=E7=BB=9F=E8=A1=A8=20iside?= =?UTF-8?q?ntity=5Ftype=20=E5=85=BC=E5=AE=B9=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FirebirdAdo/FirebirdAdo.cs | 23 +++++++++++++++++++ .../FirebirdCodeFirst.cs | 6 ++--- .../FirebirdDbFirst.cs | 8 +++---- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs b/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs index 40bbf313..63e06ea5 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdAdo/FirebirdAdo.cs @@ -35,6 +35,29 @@ namespace FreeSql.Firebird } } } + + public bool IsFirebird2_5 => ServerVersion.Contains("Firebird 2.5"); + public string ServerVersion + { + get + { + if (string.IsNullOrEmpty(_serverVersion) && MasterPool != null) + using (var conn = MasterPool.Get()) + { + try + { + _serverVersion = conn.Value.ServerVersion; + } + catch + { + _serverVersion = "3.0.0"; + } + } + return _serverVersion; + } + } + string _serverVersion; + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) { if (param == null) return "NULL"; diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs b/Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs index 49c12b1a..74118fa1 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs @@ -160,7 +160,7 @@ namespace FreeSql.Firebird tboldname = null; //如果新表已经存在,不走改表名逻辑 //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var sql = _commonUtils.FormatSql(@" + var sql = _commonUtils.FormatSql($@" select trim(a.rdb$field_name), case @@ -176,12 +176,12 @@ case coalesce((select ' SUB_TYPE ' || rdb$type from rdb$types where b.rdb$field_type = 261 and rdb$type = b.rdb$field_sub_type and rdb$field_name = 'RDB$FIELD_SUB_TYPE' rows 1),'') end || trim(case when b.rdb$dimensions = 1 then '[]' else '' end), case when a.rdb$null_flag = 1 then 0 else 1 end, -case when a.rdb$identity_type = 1 then 1 else 0 end, +{((_orm.Ado as FirebirdAdo)?.IsFirebird2_5 == true ? "0" : "case when a.rdb$identity_type = 1 then 1 else 0 end")}, a.rdb$description from rdb$relation_fields a inner join rdb$fields b on b.rdb$field_name = a.rdb$field_source inner join rdb$relations d on d.rdb$relation_name = a.rdb$relation_name -where a.rdb$system_flag = 0 and trim(d.rdb$relation_name) = {0} +where a.rdb$system_flag = 0 and trim(d.rdb$relation_name) = {{0}} order by a.rdb$relation_name, a.rdb$field_position", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs b/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs index 07ffd201..fa7fb0f0 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdDbFirst.cs @@ -196,7 +196,7 @@ where rdb$system_flag=0" + (tbname == null ? "" : $" and {(ignoreCase ? "upper(t } loc8.Append(")"); - sql = string.Format(@" + sql = $@" select trim(d.rdb$relation_name), trim(a.rdb$field_name), @@ -226,15 +226,15 @@ case coalesce((select ' SUB_TYPE ' || rdb$type from rdb$types where b.rdb$field_type = 261 and rdb$type = b.rdb$field_sub_type and rdb$field_name = 'RDB$FIELD_SUB_TYPE' rows 1),'') end || trim(case when b.rdb$dimensions = 1 then '[]' else '' end), case when a.rdb$null_flag = 1 then 0 else 1 end, -case when a.rdb$identity_type = 1 then 1 else 0 end, +{((_orm.Ado as FirebirdAdo)?.IsFirebird2_5 == true ? "0" : "case when a.rdb$identity_type = 1 then 1 else 0 end")}, a.rdb$description, a.rdb$default_value from rdb$relation_fields a inner join rdb$fields b on b.rdb$field_name = a.rdb$field_source inner join rdb$relations d on d.rdb$relation_name = a.rdb$relation_name -where a.rdb$system_flag = 0 and {0} +where a.rdb$system_flag = 0 and {loc8} order by a.rdb$relation_name, a.rdb$field_position -", loc8); +"; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; From 3812a1736a2d0bfc68b98c709f4b9237d048d730 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 18 Oct 2020 20:23:54 +0800 Subject: [PATCH 0952/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20Firebird=20E?= =?UTF-8?q?mbedded=202.5=20=E4=B8=8D=E6=94=AF=E6=8C=81=20boolean=20?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 347 ++++++++++-------- .../FirebirdProvider.cs | 7 + 2 files changed, 194 insertions(+), 160 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 1f74d636..e984b6cb 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3006,154 +3006,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3960,12 +3812,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4036,12 +3882,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4652,3 +4492,190 @@ +essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs b/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs index a70f3b91..24f2fbd6 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs @@ -41,6 +41,13 @@ namespace FreeSql.Firebird this.DbFirst = new FirebirdDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); this.CodeFirst = new FirebirdCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + + if ((this.Ado as FirebirdAdo).IsFirebird2_5) + this.Aop.ConfigEntityProperty += (_, e) => + { + if (e.Property.PropertyType.NullableTypeOrThis() == typeof(bool)) + e.ModifyResult.MapType = typeof(short); + }; } internal CommonUtils InternalCommonUtils { get; } From 3fe4b44ca827ffd271749ed8b8bc20413b45b5c9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 18 Oct 2020 21:44:56 +0800 Subject: [PATCH 0953/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Gene?= =?UTF-8?q?rator=20=E5=8F=82=E6=95=B0=20-readkey=200=20=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/ConsoleApp.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Generator/ConsoleApp.cs b/Extensions/FreeSql.Generator/ConsoleApp.cs index f0662070..178df09f 100644 --- a/Extensions/FreeSql.Generator/ConsoleApp.cs +++ b/Extensions/FreeSql.Generator/ConsoleApp.cs @@ -23,6 +23,7 @@ namespace FreeSql.Generator string ArgsFilter { get; } string ArgsMatch { get; } string ArgsFileName { get; } + bool ArgsReadKey { get; } internal string ArgsOutput { get; private set; } public ConsoleApp(string[] args, ManualResetEvent wait) @@ -62,6 +63,7 @@ new Colorful.Formatter("v" + string.Join(".", typeof(ConsoleApp).Assembly.GetNam ArgsFilter = ""; ArgsMatch = ""; ArgsFileName = "{name}.cs"; + ArgsReadKey = true; Action setArgsOutput = value => { ArgsOutput = value; @@ -196,6 +198,10 @@ new Colorful.Formatter("推荐在实体类目录创建 gen.bat,双击它重新 ArgsFileName = args[a + 1]; a++; break; + case "-readkey": + ArgsReadKey = args[a + 1].Trim() == "1"; + a++; + break; case "-output": setArgsOutput(args[a + 1]); a++; @@ -321,7 +327,8 @@ FreeSql.Generator -Razor ""__razor.cshtml.txt"" -NameOptions {string.Join(",", A Console.WriteFormatted($"\r\n[{DateTime.Now.ToString("MM-dd HH:mm:ss")}] 生成完毕,总共生成了 {outputCounter} 个文件,目录:\"{ArgsOutput}\"\r\n", Color.DarkGreen); - Console.ReadKey(); + if (ArgsReadKey) + Console.ReadKey(); wait.Set(); } } From 324fde304edd9ad9dc0944d6aadee8770b5a9e2c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 22 Oct 2020 02:59:38 +0800 Subject: [PATCH 0954/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20GlobalFilter?= =?UTF-8?q?.ApplyOnly=20=E7=BB=A7=E6=89=BF=E7=9A=84=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E6=89=8D=E7=94=9F=E6=95=88=EF=BC=9B#495?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 12 + FreeSql/FreeSql.xml | 213 ++---------------- FreeSql/Internal/CommonExpression.cs | 55 ++--- .../Internal/CommonProvider/DeleteProvider.cs | 2 +- .../SelectProvider/Select0Provider.cs | 8 +- .../SelectProvider/Select0ProviderReader.cs | 16 +- .../SelectProvider/Select10Provider.cs | 8 +- .../SelectProvider/Select11Provider.cs | 8 +- .../SelectProvider/Select12Provider.cs | 8 +- .../SelectProvider/Select13Provider.cs | 8 +- .../SelectProvider/Select14Provider.cs | 8 +- .../SelectProvider/Select15Provider.cs | 8 +- .../SelectProvider/Select16Provider.cs | 8 +- .../SelectProvider/Select1Provider.cs | 21 +- .../SelectProvider/Select2Provider.cs | 8 +- .../SelectProvider/Select3Provider.cs | 8 +- .../SelectProvider/Select4Provider.cs | 8 +- .../SelectProvider/Select5Provider.cs | 8 +- .../SelectProvider/Select6Provider.cs | 8 +- .../SelectProvider/Select7Provider.cs | 8 +- .../SelectProvider/Select8Provider.cs | 8 +- .../SelectProvider/Select9Provider.cs | 8 +- .../Internal/CommonProvider/UpdateProvider.cs | 2 +- FreeSql/Internal/GlobalFilter.cs | 37 ++- .../Curd/DamengSelect.cs | 46 ++-- .../Curd/FirebirdSelect.cs | 46 ++-- .../Curd/KingbaseESSelect.cs | 46 ++-- .../Curd/MsAccessSelect.cs | 46 ++-- .../Curd/MySqlSelect.cs | 46 ++-- .../Dameng/Curd/OdbcDamengSelect.cs | 46 ++-- .../Default/Curd/OdbcSelect.cs | 46 ++-- .../KingbaseES/Curd/OdbcKingbaseESSelect.cs | 46 ++-- .../MySql/Curd/OdbcMySqlSelect.cs | 46 ++-- .../Oracle/Curd/OdbcOracleSelect.cs | 46 ++-- .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 46 ++-- .../SqlServer/Curd/OdbcSqlServerSelect.cs | 66 +++--- .../Curd/OracleSelect.cs | 46 ++-- .../Curd/PostgreSQLSelect.cs | 46 ++-- .../Curd/ShenTongSelect.cs | 46 ++-- .../Curd/SqlServerSelect.cs | 66 +++--- .../Curd/SqliteSelect.cs | 46 ++-- 41 files changed, 588 insertions(+), 720 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 16d3d8ea..a8dc0eb7 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -244,10 +244,22 @@ namespace FreeSql.Tests public int id { get; set; } public string title { get; set; } } + public class otot3 : otot1 + { + + } [Fact] public void Test02() { + g.sqlite.GlobalFilter + .ApplyOnly("id1", a => a.name == "123"); + + var sqlonly = g.sqlite.Select() + .InnerJoin((a, b, c) => a.id == b.id) + .InnerJoin((a, b, c) => b.id == c.id) + .ToSql(); + g.sqlite.Update(Guid.Empty).Set(a => a.ct1 == a.ct2).ExecuteAffrows(); g.sqlite.Insert(new otot1 { name = "otot1_name1" }).ExecuteAffrows(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e984b6cb..fb99c6a7 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3560,7 +3560,7 @@ 创建一个过滤器 - 提示:判断登陆身份,请参考资料 AsyncLocal + 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal 名字 @@ -3571,7 +3571,29 @@ 创建一个动态过滤器,当 condition 返回值为 true 时才生效 场景:当登陆身份是管理员,则过滤条件不生效 - 提示:判断登陆身份,请参考资料 AsyncLocal + 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal + + + 名字 + 委托,返回值为 true 时才生效 + 表达式 + + + + + 创建一个过滤器(实体类型 属于指定 TEntity 才会生效) + 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal + + + 名字 + 表达式 + + + + + 创建一个过滤器(实体类型 属于指定 TEntity 才会生效) + 场景:当登陆身份是管理员,则过滤条件不生效 + 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal 名字 @@ -4492,190 +4514,3 @@ -essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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 da329ba1..c0f2f2a2 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -28,13 +28,13 @@ namespace FreeSql.Internal } internal const int ReadAnonymousFieldAsCsName = -53129; - public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, SelectGroupingProvider grouping, List whereCascadeExpression, List findIncludeMany, bool isAllDtoMap) + public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, SelectGroupingProvider grouping, List whereGlobalFilter, List findIncludeMany, bool isAllDtoMap) { - Func getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = select?._params }; //#462 添加 DbParams 解决 + Func getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = select?._params }; //#462 添加 DbParams 解决 switch (exp.NodeType) { - case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); - case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); + case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); + case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); case ExpressionType.Negate: case ExpressionType.NegateChecked: parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; @@ -43,7 +43,7 @@ namespace FreeSql.Internal else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; - case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); + case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); case ExpressionType.Constant: var constExp = exp as ConstantExpression; //处理自定义SQL语句,如: ToList(new { @@ -133,7 +133,7 @@ namespace FreeSql.Internal MapType = memProp.PropertyType }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, grouping, whereCascadeExpression, findIncludeMany, false); + ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, grouping, whereGlobalFilter, findIncludeMany, false); } } } @@ -199,7 +199,7 @@ namespace FreeSql.Internal MapType = initExp.NewExpression.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, grouping, whereCascadeExpression, findIncludeMany, false); + ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, grouping, whereGlobalFilter, findIncludeMany, false); } } else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) @@ -224,7 +224,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -250,7 +250,7 @@ namespace FreeSql.Internal MapType = initAssignExp.Expression.Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, grouping, whereCascadeExpression, findIncludeMany, false); + ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, grouping, whereGlobalFilter, findIncludeMany, false); } } if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); @@ -283,7 +283,7 @@ namespace FreeSql.Internal MapType = newExp.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, grouping, whereCascadeExpression, findIncludeMany, false); + ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, grouping, whereGlobalFilter, findIncludeMany, false); } } else @@ -307,7 +307,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereCascadeExpression, findIncludeMany, isAllDtoMap); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -460,16 +460,16 @@ namespace FreeSql.Internal return GetBoolString(exp, sql); } - public string ExpressionWhereLambda(List _tables, Expression exp, SelectGroupingProvider groupingProvider, List whereCascadeExpression, List dbParams) + public string ExpressionWhereLambda(List _tables, Expression exp, SelectGroupingProvider groupingProvider, List whereGlobalFilter, List dbParams) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = dbParams }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = dbParams }); return GetBoolString(exp, sql); } static ConcurrentDictionary dicRegexAlias = new ConcurrentDictionary(); - public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, SelectGroupingProvider groupingProvider, List whereCascadeExpression) + public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, SelectGroupingProvider groupingProvider, List whereGlobalFilter) { var tbidx = _tables.Count; - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter }); sql = GetBoolString(exp, sql); if (_tables.Count > tbidx) @@ -947,11 +947,11 @@ namespace FreeSql.Internal Type = SelectTableInfoType.Parent, Parameter = a.Parameter })); - if (tsc.whereCascadeExpression?.Any() == true) + if (tsc.whereGlobalFilter?.Any() == true) { - var fsqlCascade = fsqlSelect0._whereCascadeExpression; - if (fsqlCascade != tsc.whereCascadeExpression) - fsqlCascade.AddRange(tsc.whereCascadeExpression); + var fsqlGlobalFilter = fsqlSelect0._whereGlobalFilter; + if (fsqlGlobalFilter != tsc.whereGlobalFilter) + fsqlGlobalFilter.AddRange(tsc.whereGlobalFilter); } } else if (fsqlType != null) @@ -1521,7 +1521,7 @@ namespace FreeSql.Internal public Type mapTypeTmp { get; set; } public ColumnInfo mapColumnTmp { get; set; } public TableInfo currentTable { get; set; } - public List whereCascadeExpression { get; set; } + public List whereGlobalFilter { get; set; } public List dbParams { get; set; } public string alias001 { get; set; } //单表字段的表别名 @@ -1567,7 +1567,7 @@ namespace FreeSql.Internal //mapTypeTmp = this.mapTypeTmp, //mapColumnTmp = this.mapColumnTmp, currentTable = this.currentTable, - whereCascadeExpression = this.whereCascadeExpression, + whereGlobalFilter = this.whereGlobalFilter, dbParams = this.dbParams, alias001 = this.alias001 }; @@ -1588,7 +1588,7 @@ namespace FreeSql.Internal mapTypeTmp = this.mapTypeTmp, mapColumnTmp = this.mapColumnTmp, currentTable = this.currentTable, - whereCascadeExpression = this.whereCascadeExpression, + whereGlobalFilter = this.whereGlobalFilter, dbParams = this.dbParams, alias001 = this.alias001 }; @@ -1596,19 +1596,20 @@ namespace FreeSql.Internal } static ConcurrentDictionary> _dicGetWhereCascadeSqlError = new ConcurrentDictionary>(); - public string GetWhereCascadeSql(SelectTableInfo tb, List _whereCascadeExpression, bool isMultitb) + public string GetWhereCascadeSql(SelectTableInfo tb, List filters, bool isMultitb) { - if (_whereCascadeExpression.Any()) + if (filters.Any()) { var newParameter = Expression.Parameter(tb.Table.Type, tb.Alias); tb.Parameter = newParameter; var sb = new StringBuilder(); var isEmpty = true; - foreach (var fl in _whereCascadeExpression) + foreach (var fl in filters) { + if (fl.Only && fl.Where.Parameters.FirstOrDefault()?.Type.IsAssignableFrom(tb.Table.Type) == false) continue; var dicSqlError = _dicGetWhereCascadeSqlError.GetOrAdd(tb.Table.Type, tp => new ConcurrentDictionary()); - var errorKey = FreeUtil.Sha1($"{(isMultitb ? 1 : 0)},{fl.ToString()}"); + var errorKey = FreeUtil.Sha1($"{(isMultitb ? 1 : 0)},{fl.Where.ToString()}"); if (dicSqlError.ContainsKey(errorKey)) continue; var visitor = new ReplaceVisitor(); @@ -1616,7 +1617,7 @@ namespace FreeSql.Internal { var expExp = Expression.Lambda( typeof(Func<,>).MakeGenericType(tb.Table.Type, typeof(bool)), - new ReplaceVisitor().Modify(fl, newParameter), + new ReplaceVisitor().Modify(fl.Where, newParameter), newParameter ); var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 338f4d99..774812cc 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -163,7 +163,7 @@ namespace FreeSql.Internal.CommonProvider if (_whereGlobalFilter.Any()) { - var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList(), false); + var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter, false); if (string.IsNullOrEmpty(globalFilterCondi) == false) sb.Append(" AND ").Append(globalFilterCondi); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 962039dd..3236d246 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -41,7 +41,6 @@ namespace FreeSql.Internal.CommonProvider public Dictionary _includeInfo = new Dictionary(); public bool _distinct; public Expression _selectExpression; - public List _whereCascadeExpression = new List(); public List _whereGlobalFilter; int _disposeCounter; @@ -61,9 +60,7 @@ namespace FreeSql.Internal.CommonProvider #endif _includeInfo.Clear(); _selectExpression = null; - _whereCascadeExpression.Clear(); - _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); - _whereCascadeExpression.AddRange(_whereGlobalFilter.Select(a => a.Where)); + _whereGlobalFilter.Clear(); } public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection lambParms) @@ -121,7 +118,6 @@ namespace FreeSql.Internal.CommonProvider #endif to._distinct = from._distinct; to._selectExpression = from._selectExpression; - to._whereCascadeExpression = new List(from._whereCascadeExpression.ToArray()); to._whereGlobalFilter = new List(from._whereGlobalFilter.ToArray()); } @@ -633,7 +629,6 @@ namespace FreeSql.Internal.CommonProvider if (_whereGlobalFilter.Any() == false) return this as TSelect; if (name?.Any() != true) { - _whereCascadeExpression.RemoveRange(0, _whereGlobalFilter.Count); _whereGlobalFilter.Clear(); return this as TSelect; } @@ -642,7 +637,6 @@ namespace FreeSql.Internal.CommonProvider if (n == null) continue; var idx = _whereGlobalFilter.FindIndex(a => string.Compare(a.Name, n, true) == 0); if (idx == -1) continue; - _whereCascadeExpression.RemoveAt(idx); _whereGlobalFilter.RemoveAt(idx); } return this as TSelect; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 550d1ad9..85fd66ec 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -353,7 +353,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, this, null, _whereCascadeExpression, null, true); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, this, null, _whereGlobalFilter, null, true); return new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); } static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); @@ -656,14 +656,14 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, null, _whereGlobalFilter, null, false); //不走 DTO 映射,不处理 IncludeMany var sql = field.ToString(); this.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); return new SelectGroupingProvider(_orm, this, map, sql, _commonExpression, _tables); } public TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { - _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); + _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereGlobalFilter); return this as TSelect; } protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) @@ -671,7 +671,7 @@ namespace FreeSql.Internal.CommonProvider var tb = _commonUtils.GetTableByEntity(typeof(T2)); if (tb == null) throw new ArgumentException("T2 类型错误"); _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType }); - _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression); + _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereGlobalFilter); return this as TSelect; } protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); @@ -695,7 +695,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereGlobalFilter, null, false); //不走 DTO 映射,不处理 IncludeMany var childs = map.Childs; if (childs.Any() == false) throw new ArgumentException($"ISelect.InsertInto() 未选择属性: {typeof(TTargetEntity).DisplayCsharp()}"); @@ -774,7 +774,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereGlobalFilter, null, false); //不走 DTO 映射,不处理 IncludeMany return this.ToListMapReader(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault(); } finally @@ -783,7 +783,7 @@ namespace FreeSql.Internal.CommonProvider } } - public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params)); + public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereGlobalFilter, _params)); #region Async #if net40 @@ -1065,7 +1065,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereCascadeExpression, null, false); //不走 DTO 映射,不处理 IncludeMany + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereGlobalFilter, null, false); //不走 DTO 映射,不处理 IncludeMany return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); } finally diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index f4027dcd..0f7bbb0c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -199,14 +199,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -214,7 +214,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -287,7 +287,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs index bef394ab..d63ad2c4 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs @@ -203,14 +203,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -218,7 +218,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -291,7 +291,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs index bb338340..3f0ee2be 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs @@ -207,14 +207,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -222,7 +222,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -295,7 +295,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs index 8d859e11..733d3752 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs @@ -211,14 +211,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -226,7 +226,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -299,7 +299,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs index 92265894..b7444508 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs @@ -215,14 +215,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -230,7 +230,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -303,7 +303,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs index a9e85428..e97afd94 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs @@ -219,14 +219,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -234,7 +234,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -307,7 +307,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs index 81f078f2..a1747eb2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs @@ -223,14 +223,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -238,7 +238,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -311,7 +311,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index afda8923..d7bba456 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -23,7 +23,6 @@ namespace FreeSql.Internal.CommonProvider public Select1Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); - _whereCascadeExpression.AddRange(_whereGlobalFilter.Select(a => a.Where)); } protected ISelect InternalFrom(LambdaExpression lambdaExp) @@ -199,7 +198,7 @@ namespace FreeSql.Internal.CommonProvider var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select.Body, this, null, _whereCascadeExpression, findIncludeMany, true); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select.Body, this, null, _whereGlobalFilter, findIncludeMany, true); var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); if (findIncludeMany.Any() == false) return this.ToListMapReaderPrivate(af, null); @@ -232,7 +231,7 @@ namespace FreeSql.Internal.CommonProvider var otherMap = new ReadAnonymousTypeInfo(); field.Clear(); - _commonExpression.ReadAnonymousField(_tables, field, otherMap, ref index, otherNewInit, this, null, _whereCascadeExpression, null, true); + _commonExpression.ReadAnonymousField(_tables, field, otherMap, ref index, otherNewInit, this, null, _whereGlobalFilter, null, true); var otherRet = new List(); var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); @@ -361,7 +360,7 @@ namespace FreeSql.Internal.CommonProvider public ISelect WhereCascade(Expression> exp) { - if (exp != null) _whereCascadeExpression.Add(exp); + if (exp != null) _whereGlobalFilter.Add(new GlobalFilter.Item { Name = "WhereCascade", Only = false, Where = exp }); return this; } @@ -806,8 +805,8 @@ namespace FreeSql.Internal.CommonProvider if (_tableRules?.Any() == true) foreach (var tr in _tableRules) subSelect.AsTable(tr); - if (_whereCascadeExpression.Any()) - subSelect._whereCascadeExpression.AddRange(_whereCascadeExpression.ToArray()); + if (_whereGlobalFilter.Any()) + subSelect._whereGlobalFilter.AddRange(_whereGlobalFilter.ToArray()); //subSelect._aliasRule = _aliasRule; //把 SqlServer 查询锁传递下去 then?.Invoke(subSelect); @@ -957,11 +956,11 @@ namespace FreeSql.Internal.CommonProvider { if (z > 0) sbJoin.Append(" AND "); sbJoin.Append($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}"); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) { - var cascade = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Alias = "midtb", AliasInit = "midtb", Table = tbrefMid, Type = SelectTableInfoType.InnerJoin }, _whereCascadeExpression, true); + var cascade = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Alias = "midtb", AliasInit = "midtb", Table = tbrefMid, Type = SelectTableInfoType.InnerJoin }, _whereGlobalFilter, true); if (string.IsNullOrEmpty(cascade) == false) - sbJoin.Append(" AND (").Append(cascade).Append(")"); + sbJoin.Append(" AND ").Append(cascade); } } subSelect.InnerJoin(sbJoin.ToString()); @@ -1196,7 +1195,7 @@ namespace FreeSql.Internal.CommonProvider var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select.Body, this, null, _whereCascadeExpression, findIncludeMany, true); + _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select.Body, this, null, _whereGlobalFilter, findIncludeMany, true); var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); if (findIncludeMany.Any() == false) return await this.ToListMapReaderPrivateAsync(af, null); @@ -1229,7 +1228,7 @@ namespace FreeSql.Internal.CommonProvider var otherMap = new ReadAnonymousTypeInfo(); field.Clear(); - _commonExpression.ReadAnonymousField(_tables, field, otherMap, ref index, otherNewInit, this, null, _whereCascadeExpression, null, true); + _commonExpression.ReadAnonymousField(_tables, field, otherMap, ref index, otherNewInit, this, null, _whereGlobalFilter, null, true); var otherRet = new List(); var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index bba3c916..380fb784 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -169,14 +169,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -184,7 +184,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -257,7 +257,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index e5d59a90..5e0d9d7d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -171,14 +171,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -186,7 +186,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -259,7 +259,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 80752cd5..94726b48 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -175,14 +175,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -190,7 +190,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -263,7 +263,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index ca7b7e23..7de632c5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -179,14 +179,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -194,7 +194,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -267,7 +267,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 622e2b16..1878e668 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -183,14 +183,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -198,7 +198,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -271,7 +271,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 70d4b819..29ea495e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -187,14 +187,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -202,7 +202,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -275,7 +275,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index e7c71db7..8d4be242 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -191,14 +191,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -206,7 +206,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -279,7 +279,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 9e7c80f5..8f1861ec 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -195,14 +195,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)) : this; + return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; } bool ISelect.Any(Expression> exp) @@ -210,7 +210,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -283,7 +283,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereCascadeExpression, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index fc55bdce..6742062d 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -783,7 +783,7 @@ namespace FreeSql.Internal.CommonProvider if (_whereGlobalFilter.Any()) { - var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter.Select(a => a.Where).ToList(), false); + var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter, false); if (string.IsNullOrEmpty(globalFilterCondi) == false) sb.Append(" AND ").Append(globalFilterCondi); } diff --git a/FreeSql/Internal/GlobalFilter.cs b/FreeSql/Internal/GlobalFilter.cs index 9da950ff..e17a788b 100644 --- a/FreeSql/Internal/GlobalFilter.cs +++ b/FreeSql/Internal/GlobalFilter.cs @@ -18,33 +18,57 @@ namespace FreeSql.Internal public string Name { get; internal set; } internal Func Condition { get; set; } public LambdaExpression Where { get; internal set; } + public bool Only { get; internal set; } } /// /// 创建一个过滤器 - /// 提示:判断登陆身份,请参考资料 AsyncLocal + /// 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal /// /// /// 名字 /// 表达式 /// - public GlobalFilter Apply(string name, Expression> where) => ApplyIf(name, () => true, where); + public GlobalFilter Apply(string name, Expression> where) => Apply(false, name, () => true, where); /// /// 创建一个动态过滤器,当 condition 返回值为 true 时才生效 /// 场景:当登陆身份是管理员,则过滤条件不生效 - /// 提示:判断登陆身份,请参考资料 AsyncLocal + /// 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal /// /// /// 名字 /// 委托,返回值为 true 时才生效 /// 表达式 /// - public GlobalFilter ApplyIf(string name, Func condition, Expression> where) + public GlobalFilter ApplyIf(string name, Func condition, Expression> where) => Apply(false, name, condition, where); + + /// + /// 创建一个过滤器(实体类型 属于指定 TEntity 才会生效) + /// 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal + /// + /// + /// 名字 + /// 表达式 + /// + public GlobalFilter ApplyOnly(string name, Expression> where) => Apply(true, name, () => true, where); + /// + /// 创建一个过滤器(实体类型 属于指定 TEntity 才会生效) + /// 场景:当登陆身份是管理员,则过滤条件不生效 + /// 提示:在 Lambda 中判断登陆身份,请参考资料 AsyncLocal + /// + /// + /// 名字 + /// 委托,返回值为 true 时才生效 + /// 表达式 + /// + public GlobalFilter ApplyOnlyIf(string name, Func condition, Expression> where) => Apply(true, name, condition, where); + + GlobalFilter Apply(bool only, string name, Func condition, Expression> where) { if (name == null) throw new ArgumentNullException(nameof(name)); if (where == null) return this; _filters.TryGetValue(name, out var item); - if (item == null) item = new Item { Id = ++_id, Name = name, Condition = condition }; + if (item == null) item = new Item { Id = ++_id, Name = name }; var newParameter = Expression.Parameter(typeof(TEntity), $"gf{_id}"); var newlambda = Expression.Lambda>( @@ -52,9 +76,12 @@ namespace FreeSql.Internal newParameter ); item.Where = newlambda; + item.Condition = condition; + item.Only = only; _filters.AddOrUpdate(name, item, (_, __) => item); return this; } + public void Remove(string name) => _filters.TryRemove(name ?? throw new ArgumentNullException(nameof(name)), out var _); public List GetFilters() => _filters.Values.Where(a => a.Condition?.Invoke() != false).OrderBy(a => a.Id).ToList(); diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs index 0d5f65d9..de817e0e 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Dameng.Curd class DamengSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -55,7 +55,7 @@ namespace FreeSql.Dameng.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -65,7 +65,7 @@ namespace FreeSql.Dameng.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -85,14 +85,14 @@ namespace FreeSql.Dameng.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); @@ -141,82 +141,82 @@ namespace FreeSql.Dameng.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class DamengSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs index d751ea6d..d8a69c52 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Firebird.Curd class FirebirdSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -58,7 +58,7 @@ namespace FreeSql.Firebird.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -68,7 +68,7 @@ namespace FreeSql.Firebird.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -88,14 +88,14 @@ namespace FreeSql.Firebird.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -132,83 +132,83 @@ namespace FreeSql.Firebird.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class FirebirdSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs index 77f59b9c..303cae0f 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.KingbaseES class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -53,7 +53,7 @@ namespace FreeSql.KingbaseES if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -63,7 +63,7 @@ namespace FreeSql.KingbaseES { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -83,14 +83,14 @@ namespace FreeSql.KingbaseES break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -131,82 +131,82 @@ namespace FreeSql.KingbaseES public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs index 352b5710..430f784d 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs @@ -13,14 +13,14 @@ namespace FreeSql.MsAccess.Curd class MsAccessSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -61,7 +61,7 @@ namespace FreeSql.MsAccess.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } sb.Append(")"); } @@ -72,7 +72,7 @@ namespace FreeSql.MsAccess.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -95,7 +95,7 @@ namespace FreeSql.MsAccess.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON (").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); sb.Append(")"); } @@ -114,7 +114,7 @@ namespace FreeSql.MsAccess.Curd sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -151,82 +151,82 @@ namespace FreeSql.MsAccess.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MsAccessSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index 37d427fe..ffa78e01 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.MySql.Curd class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -53,7 +53,7 @@ namespace FreeSql.MySql.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -63,7 +63,7 @@ namespace FreeSql.MySql.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -83,14 +83,14 @@ namespace FreeSql.MySql.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -129,82 +129,82 @@ namespace FreeSql.MySql.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs index fca54b41..46fc5c79 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Odbc.Dameng class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -55,7 +55,7 @@ namespace FreeSql.Odbc.Dameng if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -65,7 +65,7 @@ namespace FreeSql.Odbc.Dameng { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -85,14 +85,14 @@ namespace FreeSql.Odbc.Dameng break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); @@ -141,82 +141,82 @@ namespace FreeSql.Odbc.Dameng public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index 8452c685..db1bb730 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -11,15 +11,15 @@ namespace FreeSql.Odbc.Default class OdbcSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { var _utils = _commonUtils as OdbcUtils; if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -58,7 +58,7 @@ namespace FreeSql.Odbc.Default if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -68,7 +68,7 @@ namespace FreeSql.Odbc.Default { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -88,14 +88,14 @@ namespace FreeSql.Odbc.Default break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -134,82 +134,82 @@ namespace FreeSql.Odbc.Default public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs index cf1dc1ee..647eca33 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Odbc.KingbaseES class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.KingbaseES if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -63,7 +63,7 @@ namespace FreeSql.Odbc.KingbaseES { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -83,14 +83,14 @@ namespace FreeSql.Odbc.KingbaseES break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -131,82 +131,82 @@ namespace FreeSql.Odbc.KingbaseES public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index 290db614..df77a38e 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Odbc.MySql class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.MySql if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -63,7 +63,7 @@ namespace FreeSql.Odbc.MySql { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -83,14 +83,14 @@ namespace FreeSql.Odbc.MySql break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -129,82 +129,82 @@ namespace FreeSql.Odbc.MySql public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index 8e85005c..6e8c5240 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Odbc.Oracle class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -55,7 +55,7 @@ namespace FreeSql.Odbc.Oracle if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -65,7 +65,7 @@ namespace FreeSql.Odbc.Oracle { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -85,14 +85,14 @@ namespace FreeSql.Odbc.Oracle break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); @@ -147,82 +147,82 @@ namespace FreeSql.Odbc.Oracle public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 11a6b689..0c4664a3 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Odbc.PostgreSQL class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -53,7 +53,7 @@ namespace FreeSql.Odbc.PostgreSQL if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -63,7 +63,7 @@ namespace FreeSql.Odbc.PostgreSQL { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -83,14 +83,14 @@ namespace FreeSql.Odbc.PostgreSQL break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -131,82 +131,82 @@ namespace FreeSql.Odbc.PostgreSQL public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index d98c3bbe..f522f11a 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -12,20 +12,20 @@ namespace FreeSql.Odbc.SqlServer class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) => (_commonUtils as OdbcSqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -71,7 +71,7 @@ namespace FreeSql.Odbc.SqlServer if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -81,7 +81,7 @@ namespace FreeSql.Odbc.SqlServer { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -101,14 +101,14 @@ namespace FreeSql.Odbc.SqlServer break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -133,14 +133,14 @@ namespace FreeSql.Odbc.SqlServer #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -176,7 +176,7 @@ namespace FreeSql.Odbc.SqlServer if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -186,7 +186,7 @@ namespace FreeSql.Odbc.SqlServer { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -206,14 +206,14 @@ namespace FreeSql.Odbc.SqlServer break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -265,82 +265,82 @@ namespace FreeSql.Odbc.SqlServer public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 0f6bf97a..6e364d8d 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Oracle.Curd class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -55,7 +55,7 @@ namespace FreeSql.Oracle.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -65,7 +65,7 @@ namespace FreeSql.Oracle.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -85,14 +85,14 @@ namespace FreeSql.Oracle.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); @@ -147,82 +147,82 @@ namespace FreeSql.Oracle.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index e689d042..49eb4488 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.PostgreSQL.Curd class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -53,7 +53,7 @@ namespace FreeSql.PostgreSQL.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -63,7 +63,7 @@ namespace FreeSql.PostgreSQL.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -83,14 +83,14 @@ namespace FreeSql.PostgreSQL.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -131,82 +131,82 @@ namespace FreeSql.PostgreSQL.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs index 9a23877f..7495185b 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.ShenTong.Curd class ShenTongSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -53,7 +53,7 @@ namespace FreeSql.ShenTong.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -63,7 +63,7 @@ namespace FreeSql.ShenTong.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -83,14 +83,14 @@ namespace FreeSql.ShenTong.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -131,82 +131,82 @@ namespace FreeSql.ShenTong.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class ShenTongSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 82fbff16..9f35cc47 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -12,20 +12,20 @@ namespace FreeSql.SqlServer.Curd class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) => (_commonUtils as SqlServerUtils).IsSelectRowNumber ? - ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm) : - ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); #region SqlServer 2005 row_number - internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -71,7 +71,7 @@ namespace FreeSql.SqlServer.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -81,7 +81,7 @@ namespace FreeSql.SqlServer.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -101,14 +101,14 @@ namespace FreeSql.SqlServer.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -133,14 +133,14 @@ namespace FreeSql.SqlServer.Curd #endregion #region SqlServer 2012+ offset feach next - internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -176,7 +176,7 @@ namespace FreeSql.SqlServer.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -186,7 +186,7 @@ namespace FreeSql.SqlServer.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -206,14 +206,14 @@ namespace FreeSql.SqlServer.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -268,82 +268,82 @@ namespace FreeSql.SqlServer.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index e08c29c4..782e094f 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -12,14 +12,14 @@ namespace FreeSql.Sqlite.Curd class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class { - internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereCascadeExpression, IFreeSql _orm) + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); - if (_whereCascadeExpression.Any()) + if (_whereGlobalFilter.Any()) foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) - tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereCascadeExpression, true); + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); var sb = new StringBuilder(); var tbUnionsGt0 = tbUnions.Count > 1; @@ -53,7 +53,7 @@ namespace FreeSql.Sqlite.Curd if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) { if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); - else sb.Append(" AND (").Append(tbsfrom[b].Cascade).Append(")"); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); } } } @@ -63,7 +63,7 @@ namespace FreeSql.Sqlite.Curd { if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); - if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND (").Append(tbsfrom[a].Cascade).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); } if (a < tbsfrom.Length - 1) sb.Append(", "); } @@ -83,14 +83,14 @@ namespace FreeSql.Sqlite.Curd break; } sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); - if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND (").Append(tb.Cascade).Append(")"); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); } if (_join.Length > 0) sb.Append(_join); sbnav.Append(_where); if (!string.IsNullOrEmpty(_tables[0].Cascade)) - sbnav.Append(" AND (").Append(_tables[0].Cascade).Append(")"); + sbnav.Append(" AND ").Append(_tables[0].Cascade); if (sbnav.Length > 0) { @@ -129,82 +129,82 @@ namespace FreeSql.Sqlite.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereCascadeExpression, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } } From 698ace9674d84456a750894c58c17052422b29bb Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 22 Oct 2020 03:29:01 +0800 Subject: [PATCH 0955/1029] v1.10.0 #469 #495 #479 #494 #476 #490 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 4 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/FreeSql.Tests.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 160 ++++++++++++++++++ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 4 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 6 +- .../FreeSql.Provider.PostgreSQL.csproj | 8 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 4 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 24 files changed, 191 insertions(+), 31 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a905979e..a2e046de 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index b06b232b..45ff93ea 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5eb8853f..a0bae9ca 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 82a460e5..3cc1f764 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d3c7bfdf..e7e6bfc3 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.0-preview1020 + 1.10.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 0bb71ac9..25f236c3 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 846b89a7..abda47bd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access @@ -37,7 +37,7 @@ - + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3c031e37..f586eaa3 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0-preview1020 + 1.10.0 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 266bb4e9..0d018a86 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 551d50cb..715095bc 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index fb99c6a7..3844b008 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3006,6 +3006,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3834,6 +3982,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3904,6 +4058,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 5992776d..8e5cb86e 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 21624b54..4a808ad3 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 361f081b..66ed9fe7 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index ce68fbac..6d8af734 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e2fb3eda..64d54185 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 80b94f73..5b65d10c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 16e0bb78..353e99fc 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index bc1f3c56..7f17f066 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 @@ -26,11 +26,11 @@ - + - + diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 7113d672..8bfc40dd 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 @@ -30,12 +30,12 @@ - - + + - + diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 1c7a1206..fb6c69d2 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index dfa01eee..2fc4fae3 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -29,7 +29,7 @@ - + diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 0e950996..3dc0ed2d 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index de9c599e..d7d9b29a 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0-preview1020 + 1.10.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 1fc4c9c46e9514805badf7fa523cb15963f81157 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 22 Oct 2020 16:52:53 +0800 Subject: [PATCH 0956/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20MySql=20Code?= =?UTF-8?q?First=20=E7=B4=A2=E5=BC=95=E7=9A=84=E5=BB=BA=E7=AB=8B=20?= =?UTF-8?q?=EF=BC=9B#498?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 18 +++++++++--------- .../MySql/OdbcMySqlCodeFirst.cs | 18 +++++++++--------- readme.md | 3 ++- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 64d54185..4c2ffd7e 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -26,7 +26,7 @@ - + diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 69d6c835..9b9a827e 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -151,25 +151,25 @@ namespace FreeSql.MySql foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB"); - if (string.IsNullOrEmpty(tb.Comment) == false) - sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); - sb.Append(";\r\n"); - //创建表的索引 + //创建表的索引,感谢 @mafeng8,这样写可以支持自增不是主键的情况 foreach (var uk in tb.Indexes) { - sb.Append("CREATE "); + sb.Append(" \r\n "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); if (tbcol.IsDesc) sb.Append(" DESC"); sb.Append(", "); } - sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + sb.Remove(sb.Length - 2, 2).Append("),"); } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); continue; } //如果新表,旧表在一个数据库下,直接修改表名 diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index e1fb6792..0bb333da 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -140,25 +140,25 @@ namespace FreeSql.Odbc.MySql foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); sb.Remove(sb.Length - 2, 2).Append("),"); } - sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB"); - if (string.IsNullOrEmpty(tb.Comment) == false) - sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); - sb.Append(";\r\n"); - //创建表的索引 + //创建表的索引,感谢 @mafeng8,这样写可以支持自增不是主键的情况 foreach (var uk in tb.Indexes) { - sb.Append("CREATE "); + sb.Append(" \r\n "); if (uk.IsUnique) sb.Append("UNIQUE "); - sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append("("); foreach (var tbcol in uk.Columns) { sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); if (tbcol.IsDesc) sb.Append(" DESC"); sb.Append(", "); } - sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + sb.Remove(sb.Length - 2, 2).Append("),"); } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); continue; } //如果新表,旧表在一个数据库下,直接修改表名 diff --git a/readme.md b/readme.md index 52a00d81..9d31601f 100644 --- a/readme.md +++ b/readme.md @@ -182,7 +182,8 @@ Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper [tky753](https://github.com/tky753)、 [feijie999](https://github.com/feijie999)、 constantine、 -[JohnZhou2020](https://github.com/JohnZhou2020) +[JohnZhou2020](https://github.com/JohnZhou2020)、 +[mafeng8](https://github.com/mafeng8) QQ群:4336577(已满)、8578575(在线)、52508226(在线) From b0ec71d1147a0a045bbe9e58e2d38336913b8ebd Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 22 Oct 2020 16:57:02 +0800 Subject: [PATCH 0957/1029] =?UTF-8?q?v1.10.1=20mysql.data.dll=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E9=99=8D=E4=BD=8E=E8=87=B3=208.0.21=20(8.0.22=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=9C=89=20bug)=20#498=20#469=20#495=20#479?= =?UTF-8?q?=20#494=20#476=20#490?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index a2e046de..485e89e1 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 45ff93ea..7bfa2140 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a0bae9ca..4c72ee94 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 3cc1f764..c586c771 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index e7e6bfc3..a2b7862c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.0 + 1.10.1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 25f236c3..5576da37 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index abda47bd..4d852265 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index f586eaa3..d9e7e31c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.0 + 1.10.1 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 715095bc..fbd04268 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 8e5cb86e..070b8ee6 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 4a808ad3..9ebb08dd 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 66ed9fe7..69d86376 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 6d8af734..9343d122 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 4c2ffd7e..93cb8447 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 5b65d10c..93ef579a 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 353e99fc..9f15b946 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7f17f066..d9865716 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8bfc40dd..cb36b0c4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index fb6c69d2..4e6e71f1 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 2fc4fae3..65346eac 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 3dc0ed2d..58466673 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index d7d9b29a..54f08a62 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.0 + 1.10.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From faf883b62ae9b5b175a081de7b94059a7d85aa1b Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 22 Oct 2020 20:24:49 +0800 Subject: [PATCH 0958/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E6=A0=91=20SqlExt.IsNull=20=E5=AF=B9?= =?UTF-8?q?=E5=B8=83=E5=B0=94=E7=B1=BB=E5=9E=8B=E7=9A=84=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=EF=BC=9B#500?= 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 | 28 ++ FreeSql/FreeSql.xml | 347 ++++++++++++----------- FreeSql/Internal/CommonExpression.cs | 36 +-- 4 files changed, 235 insertions(+), 192 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ce9ce69d..d198eb6c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -532,14 +525,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index ede9eb88..172f4232 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -177,9 +177,37 @@ namespace FreeSql.Tests public string name { get; set; } } + class tq01 + { + public Guid id { get; set; } + } + class t102 + { + public Guid id { get; set; } + public bool isxx { get; set; } + } + [Fact] public void Test03() { + var testisnullsql1 = g.sqlite.Select().Where(a => SqlExt.IsNull(a.isxx, false).Equals( true)).ToSql(); + var testisnullsql2 = g.sqlite.Select().Where(a => SqlExt.IsNull(a.isxx, false).Equals(false)).ToSql(); + + var guid1 = Guid.NewGuid(); + var guid2 = Guid.NewGuid(); + var guid3 = Guid.NewGuid(); + var tqsql = g.sqlite.Select() + .WithSql( + g.sqlite.Select().As("sub1").Where(a => a.id == guid1).ToSql(), + g.sqlite.Select().As("sub2").Where(a => a.id == guid2).ToSql(), + g.sqlite.Select().As("sub3").Where(a => a.id == guid3).ToSql() + ) + .LeftJoin((a, b, c) => a.id == b.id) + .LeftJoin((a, b, c) => b.id == c.id) + .ToSql(); + + + var updateSql = g.sqlite.Update() .AsType(typeof(testInsertNullable)) .SetDto(new { str1 = "xxx" }) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3844b008..d3216e1f 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3006,154 +3006,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3982,12 +3834,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4058,12 +3904,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4674,3 +4514,190 @@ +essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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 c0f2f2a2..6952905d 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -604,23 +604,27 @@ namespace FreeSql.Internal } if (leftExp.Type.NullableTypeOrThis() == typeof(bool) && (leftExp.NodeType != ExpressionType.MemberAccess && rightExp.NodeType != ExpressionType.MemberAccess)) { - if (oper == "=") + var leftExpCall = leftExp as MethodCallExpression; + if (leftExpCall == null || !(leftExpCall.Method.DeclaringType == typeof(SqlExt) && leftExpCall.Method.Name == nameof(SqlExt.IsNull))) { - var trueVal = formatSql(true, null, null, null); - var falseVal = formatSql(false, null, null, null); - if (left == trueVal) return right; - else if (left == falseVal) return $"not({right})"; - else if (right == trueVal) return left; - else if (right == falseVal) return $"not({left})"; - } - else if (oper == "<>") - { - var trueVal = formatSql(true, null, null, null); - var falseVal = formatSql(false, null, null, null); - if (left == trueVal) return $"not({right})"; - else if (left == falseVal) return right; - else if (right == trueVal) return $"not({left})"; - else if (right == falseVal) return left; + if (oper == "=") + { + var trueVal = formatSql(true, null, null, null); + var falseVal = formatSql(false, null, null, null); + if (left == trueVal) return right; + else if (left == falseVal) return $"not({right})"; + else if (right == trueVal) return left; + else if (right == falseVal) return $"not({left})"; + } + else if (oper == "<>") + { + var trueVal = formatSql(true, null, null, null); + var falseVal = formatSql(false, null, null, null); + if (left == trueVal) return $"not({right})"; + else if (left == falseVal) return right; + else if (right == trueVal) return $"not({left})"; + else if (right == falseVal) return left; + } } } if (left == "NULL") From 4dfa5c3b9553ae87282d33a88282a5330bae4e37 Mon Sep 17 00:00:00 2001 From: IGeekFan Date: Fri, 23 Oct 2020 09:49:34 +0800 Subject: [PATCH 0959/1029] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 9d31601f..a21825db 100644 --- a/readme.md +++ b/readme.md @@ -31,7 +31,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ > 示范项目 - [zhontai.net Admin 后台管理系统](https://github.com/zhontai/Admin.Core) -- [A simple and practical CMS implememted by .NET Core](https://github.com/luoyunchong/lin-cms-dotnetcore) +- [A simple and practical CMS implemented by .NET Core](https://github.com/luoyunchong/lin-cms-dotnetcore) - [iusaas.com SaaS 企业应用管理系统](https://github.com/alonsoalon/TenantSite.Server) - [EasyCms 企业建站,事业单位使用的CMS管理系统](https://github.com/jasonyush/EasyCMS) - [内容管理系统](https://github.com/hejiyong/fscms) From bad7107126486877055541a36cfde793b1f53131 Mon Sep 17 00:00:00 2001 From: IGeekFan Date: Fri, 23 Oct 2020 18:46:13 +0800 Subject: [PATCH 0960/1029] Create gitee-mirror.yml --- .github/workflows/gitee-mirror.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/gitee-mirror.yml diff --git a/.github/workflows/gitee-mirror.yml b/.github/workflows/gitee-mirror.yml new file mode 100644 index 00000000..e48bd05b --- /dev/null +++ b/.github/workflows/gitee-mirror.yml @@ -0,0 +1,17 @@ +name: Publish +on: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Sync to Gitee 💕 + uses: wearerequired/git-mirror-action@master + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + with: + source-repo: "git@github.com:dotnetcore/freesql.git" + destination-repo: "git@gitee.com:FreeSql/FreeSql-ORM.git" From ecd7425be91c8d3c8cec624533b6813a0f3e85eb Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 26 Oct 2020 02:48:10 +0800 Subject: [PATCH 0961/1029] - add Oracle ToSqlBatchIdentityColumn --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 + FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- FreeSql/FreeSql.xml | 187 ------------------ .../Curd/OracleInsert.cs | 72 +++++++ 4 files changed, 80 insertions(+), 188 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d198eb6c..ab4c3bf2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 7925f280..75c679ca 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -131,7 +131,7 @@ public static partial class FreeSqlGlobalExtensions if (that == null) return null; if (that == typeof(string)) return default(string); if (that == typeof(Guid)) return default(Guid); - if (that.IsArray) return Array.CreateInstance(that, 0); + if (that.IsArray) return Array.CreateInstance(that.GetElementType(), 0); if (that.IsInterface || that.IsAbstract) return null; var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters(); if (ctorParms == null || ctorParms.Any() == false) return Activator.CreateInstance(that, true); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d3216e1f..fb99c6a7 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -4514,190 +4514,3 @@ -essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index be0e5b0e..e7f68355 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -23,6 +23,78 @@ namespace FreeSql.Oracle.Curd public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + /// + /// 批量插入时,如果有序列 + DbInsertValue 设置,则用这个 + /// + /// + public string ToSqlBatchIdentityColumn() + { + if (_source == null || _source.Any() == false) return null; + var cols = new List(); + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + + cols.Add(col); + } + + _identCol = null; + var sb = new StringBuilder(); + var tmpsb = new StringBuilder(); + sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("("); + var colidx = 0; + foreach (var col in cols) + { + if (col.Attribute.IsIdentity) _identCol = col; + if (colidx > 0) + { + sb.Append(", "); + tmpsb.Append(", "); + } + var colname = _commonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(colname); + tmpsb.Append(col.Attribute.IsIdentity && !string.IsNullOrEmpty(col.DbInsertValue) ? col.DbInsertValue : colname); + ++colidx; + } + sb.Append(") ").Append("\r\nSELECT ").Append(tmpsb.ToString()).Append(" FROM \r\n(\r\n"); + tmpsb.Clear(); + + _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; + var specialParams = new List(); + var didx = 0; + foreach (var d in _source) + { + if (_source.Count > 1) sb.Append("\r\n UNION ALL\r\n "); + sb.Append(" SELECT "); + var colidx2 = 0; + foreach (var col in cols) + { + if (colidx2 > 0) sb.Append(", "); + if (string.IsNullOrEmpty(col.DbInsertValue) == false) + sb.Append(col.DbInsertValue); + else + { + object val = col.GetDbValue(d); + if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 + if (_noneParameter) + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); + else + { + sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + } + } + if (didx == 0) sb.Append(" as ").Append(col.Attribute.Name); + ++colidx2; + } + sb.Append(" FROM dual "); + ++didx; + } + sb.Append(")"); + if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray(); + return sb.ToString(); + } public override string ToSql() { From 1a05d63a96824e6e417205f5e2fbdc0507d546c7 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 26 Oct 2020 02:51:42 +0800 Subject: [PATCH 0962/1029] - maintain CreateInstanceGetDefaultValue --- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 75c679ca..a1b82bbe 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -131,6 +131,7 @@ public static partial class FreeSqlGlobalExtensions if (that == null) return null; if (that == typeof(string)) return default(string); if (that == typeof(Guid)) return default(Guid); + if (that == typeof(byte[])) return default(byte[]); if (that.IsArray) return Array.CreateInstance(that.GetElementType(), 0); if (that.IsInterface || that.IsAbstract) return null; var ctorParms = that.InternalGetTypeConstructor0OrFirst(false)?.GetParameters(); From 32353bb335ef362929ea302151f3b30a9bb18701 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 26 Oct 2020 21:08:10 +0800 Subject: [PATCH 0963/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E4=BA=8B=E5=8A=A1=E5=B5=8C=E5=A5=97=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=20bug=EF=BC=9B#502?= 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 | 16 ++ FreeSql/FreeSql.xml | 160 ++++++++++++++++++ .../AdoProvider/AdoProviderTransaction.cs | 7 +- 4 files changed, 189 insertions(+), 10 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ab4c3bf2..045d21f7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -534,3 +527,12 @@ +me="M:FreeSqlDbContextExtensions.CreateUnitOfWork(IFreeSql)"> + + 创建基于仓储功能的工作单元,务必使用 using 包含使用 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 172f4232..ff52cea6 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -187,9 +187,25 @@ namespace FreeSql.Tests public bool isxx { get; set; } } + public class tcate01 + { + [Column(IsIdentity = true)] + public int? Id { get; set; } + } + public class tshop01 + { + public Guid Id { get; set; } + + public int cateId { get; set; } + public tcate01 cate { get; set; } + } + [Fact] public void Test03() { + var tshop01sql = g.sqlite.Select().Include(a => a.cate).ToSql(); + + var testisnullsql1 = g.sqlite.Select().Where(a => SqlExt.IsNull(a.isxx, false).Equals( true)).ToSql(); var testisnullsql2 = g.sqlite.Select().Where(a => SqlExt.IsNull(a.isxx, false).Equals(false)).ToSql(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index fb99c6a7..3844b008 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3006,6 +3006,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3834,6 +3982,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3904,6 +4058,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 42966cc7..2ea6f90c 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -112,15 +112,16 @@ namespace FreeSql.Internal.CommonProvider void TransactionInternal(IsolationLevel? isolationLevel, Action handler) { + var requireTran = TransactionCurrentThread == null; try { - BeginTransaction(isolationLevel); + if (requireTran) BeginTransaction(isolationLevel); handler(); - CommitTransaction(); + if (requireTran) CommitTransaction(); } catch (Exception ex) { - RollbackTransaction(ex); + if (requireTran) RollbackTransaction(ex); throw ex; } } From b86676df4e8d214d9a9a4230cb7282590f786dee Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 26 Oct 2020 21:16:31 +0800 Subject: [PATCH 0964/1029] v2.0.0-preview1026 #502 #500 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 40 +++------ FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 21 ----- .../UnitOfWork/UnitOfWorkManager.cs | 22 +---- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../RepositoryTests.cs | 83 ------------------- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 26 files changed, 35 insertions(+), 175 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 485e89e1..3a409b49 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 7bfa2140..729d5dcc 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 4c72ee94..252b3143 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index c586c771..7a1d0e8b 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index a2b7862c..6a4c59df 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.1 + 2.0.0-preview1026 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 5576da37..e1318f78 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4d852265..bfa0c070 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 045d21f7..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -350,24 +357,6 @@ 若未开启事务,则开启 - - - 是否启用工作单元 - - - - - 禁用工作单元 - - - 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 - - - - - 开启工作单元 - - 工作单元内的实体变化跟踪 @@ -444,11 +433,6 @@ 以嵌套事务方式执行。 - - - 错误的命名,请使用 Required,在 2.0.0 删除 - - EFCore 95% 相似的 FluentApi 扩展方法 @@ -525,13 +509,13 @@ - - -me="M:FreeSqlDbContextExtensions.CreateUnitOfWork(IFreeSql)"> + - 创建基于仓储功能的工作单元,务必使用 using 包含使用 + 批量注入 Repository,可以参考代码自行调整 - + + + diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index db67ee47..2e9a53be 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -25,27 +25,6 @@ namespace FreeSql void Rollback(); - /// - /// 是否启用工作单元 - /// - [Obsolete("即将删除(保留到2020-12-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] - bool Enable { get; } - - /// - /// 禁用工作单元 - /// - /// - /// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用 - /// - [Obsolete("即将删除(保留到2020-12-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] - void Close(); - - /// - /// 开启工作单元 - /// - [Obsolete("即将删除(保留到2020-12-01),请改用 UnitOfWorkManager 的方式管理事务 https://github.com/dotnetcore/FreeSql/issues/289")] - void Open(); - /// /// 工作单元内的实体变化跟踪 /// diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs index e4ae8931..b5892dbd 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWorkManager.cs @@ -87,7 +87,6 @@ namespace FreeSql /// public IUnitOfWork Begin(Propagation propagation = Propagation.Required, IsolationLevel? isolationLevel = null) { - if (propagation == Propagation.Requierd) propagation = Propagation.Required; switch (propagation) { case Propagation.Required: return FindedUowCreateVirtual() ?? CreateUow(isolationLevel); @@ -189,10 +188,6 @@ namespace FreeSql public IsolationLevel? IsolationLevel { get => _baseUow.IsolationLevel; set => _baseUow.IsolationLevel = value; } public DbContext.EntityChangeReport EntityChangeReport => _baseUow.EntityChangeReport; - public bool Enable => _baseUow.Enable; - public void Close() => _baseUow.Close(); - public void Open() => _baseUow.Open(); - public DbTransaction GetOrBeginTransaction(bool isCreate = true) => _baseUow.GetOrBeginTransaction(isCreate); public void Commit() => _baseUow.Commit(); public void Rollback() => _baseUow.Rollback(); @@ -211,10 +206,6 @@ namespace FreeSql public IsolationLevel? IsolationLevel { get => _baseUow.IsolationLevel; set { } } public DbContext.EntityChangeReport EntityChangeReport => _baseUow.EntityChangeReport; - public bool Enable => _baseUow.Enable; - public void Close() => _baseUow.Close(); - public void Open() => _baseUow.Open(); - public DbTransaction GetOrBeginTransaction(bool isCreate = true) => _baseUow.GetOrBeginTransaction(isCreate); public void Commit() { } public void Rollback() => _baseUow.Rollback(); @@ -229,10 +220,6 @@ namespace FreeSql public IsolationLevel? IsolationLevel { get; set; } public DbContext.EntityChangeReport EntityChangeReport { get; } = new DbContext.EntityChangeReport(); - public bool Enable { get; } - public void Close() { } - public void Open() { } - public DbTransaction GetOrBeginTransaction(bool isCreate = true) => null; public void Commit() { @@ -273,13 +260,6 @@ namespace FreeSql /// /// 以嵌套事务方式执行。 /// - Nested, - - - /// - /// 错误的命名,请使用 Required,在 2.0.0 删除 - /// - [Obsolete("错误的命名,请使用 Required,在 2.0.0 删除")] - Requierd = 404 + Nested } } diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index d9e7e31c..0fea82fa 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.1 + 2.0.0-preview1026 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs index 2e310cec..a0a28791 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/RepositoryTests.cs @@ -135,89 +135,6 @@ namespace FreeSql.Tests } } - [Fact] - public void UnitOfWorkRepositoryWithDisableBeforeInsert() - { - foreach (var fsql in new[] { g.sqlite, }) - { - fsql.CodeFirst.ConfigEntity(f => - { - f.Property(b => b.UserId).IsPrimary(true); - f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); - f.Property(b => b.Name).IsNullable(false); - }); - - var flowRepos = fsql.GetRepository(); - - var flow = new FlowModel() - { - CreateTime = DateTime.Now, - Name = "aaa", - LastModifyTime = DateTime.Now, - UserId = 1, - }; - - //ݿѴڵݣΪ˽IJ - flowRepos.Delete(a => a.UserId == 1 && a.Name == "aaa"); - - using (var uow = fsql.CreateUnitOfWork()) - { - //رչԪῪʼ - uow.Close(); - var uowFlowRepos = uow.GetRepository(); - uowFlowRepos.Insert(flow); - uowFlowRepos.Orm.Select().ToList(); - //ѹرչԪ᲻ύûӰ죬˴עȷԪǷЧرˣCommitҲӦò - //uow.Commit(); - } - - Assert.True(flowRepos.Select.Any(a => a.UserId == 1 && a.Name == "aaa")); - } - - } - - [Fact] - public void UnitOfWorkRepositoryWithDisableAfterInsert() - { - foreach (var fsql in new[] { g.sqlite, }) - { - fsql.CodeFirst.ConfigEntity(f => - { - f.Property(b => b.UserId).IsPrimary(true); - f.Property(b => b.Id).IsPrimary(true).IsIdentity(true); - f.Property(b => b.Name).IsNullable(false); - }); - - var flowRepos = fsql.GetRepository(); - - //ݿѴڵݣΪ˽IJ - flowRepos.Delete(a => a.UserId == 1 && a.Name == "aaa"); - - var flow = new FlowModel() - { - CreateTime = DateTime.Now, - Name = "aaa", - LastModifyTime = DateTime.Now, - UserId = 1, - }; - - - Assert.Throws(() => - { - using (var uow = fsql.CreateUnitOfWork()) - { - var uowFlowRepos = uow.GetRepository(); - uowFlowRepos.Insert(flow); - uowFlowRepos.Orm.Select().ToList(); - // Insert/Update/Delete ùرuowķᷢ쳣 - uow.Close(); - uow.Commit(); - } - - }); - } - } - [Fact] public void UnitOfWorkRepositoryWithoutDisable() { diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fbd04268..225d0ee4 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 070b8ee6..3a5a9313 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 9ebb08dd..022b8894 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 69d86376..146940bb 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 9343d122..300ecfd3 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 93cb8447..eea5aab4 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 93ef579a..ab903e6c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 9f15b946..7141780f 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index d9865716..af67b441 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index cb36b0c4..8a515533 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 4e6e71f1..2d395ebc 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 65346eac..dd6ec8e9 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 58466673..89a03524 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 54f08a62..0d9e5eaa 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.1 + 2.0.0-preview1026 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 454eb8cc44a1eaa04b4822c31ce6eaa4551b423b Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sat, 31 Oct 2020 07:03:00 +0800 Subject: [PATCH 0965/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E6=A0=91=E5=87=BD=E6=95=B0=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=20byte[]=20Length=EF=BC=9B#505?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 80 +++++++++ FreeSql.Tests/FreeSql.Tests/Issues/505.cs | 52 ++++++ FreeSql.Tests/FreeSql.Tests/Issues/507.cs | 163 ++++++++++++++++++ .../DamengExpression.cs | 4 + .../FirebirdExpression.cs | 4 + .../KingbaseESExpression.cs | 10 +- .../MsAccessExpression.cs | 4 + .../FreeSql.Provider.MySql/MySqlExpression.cs | 4 + .../Dameng/OdbcDamengExpression.cs | 4 + .../KingbaseES/OdbcKingbaseESExpression.cs | 10 +- .../MySql/OdbcMySqlExpression.cs | 4 + .../Oracle/OdbcOracleExpression.cs | 4 + .../PostgreSQL/OdbcPostgreSQLExpression.cs | 10 +- .../SqlServer/OdbcSqlServerExpression.cs | 4 + .../OracleExpression.cs | 4 + .../PostgreSQLExpression.cs | 10 +- .../ShenTongExpression.cs | 10 +- .../SqlServerExpression.cs | 4 + .../SqliteExpression.cs | 4 + 19 files changed, 369 insertions(+), 20 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/505.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/507.cs diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index c482a1d3..bf9e6d4d 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -24,6 +24,86 @@ 支付Id + + + 班期标识-BodyScheduleEntity班期主键 + + + + + 姓名 + + + + + 出生日期 + + + + + 身份证 + + + + + 联系电话 + + + + + 学校名称 + + + + + 初潮年龄 + + + + + 联系地址 + + + + + 审核人标识 + + + + + 审核人 + + + + + 审核时间 + + + + + 拒绝原因 + + + + + 采集时间 + + + + + 附件标识(多附件) + + + + + 性别 + + + + + 班期信息 + + 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/505.cs b/FreeSql.Tests/FreeSql.Tests/Issues/505.cs new file mode 100644 index 00000000..9a12b9ac --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/505.cs @@ -0,0 +1,52 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _505 + { + [Fact] + public void ByteLengthTest() + { + TestLocal(g.sqlserver); + TestLocal(g.mysql); + TestLocal(g.pgsql); + TestLocal(g.oracle); + TestLocal(g.sqlite); + TestLocal(g.firebird); + TestLocal(g.dameng); + //TestLocal(g.kingbaseES); // + //TestLocal(g.shentong); // OCTET_LENGTH(xx) 返回结果32,值不符合 + //TestLocal(g.msaccess); //lenb(xx) 返回结果 15,值不符合 + + void TestLocal(IFreeSql fsql) + { + var byteArray = Encoding.UTF8.GetBytes("我是中国人"); + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new Model505 { ByteLength = byteArray.Length, ByteArray = byteArray }).ExecuteAffrows(); + + var item = fsql.Select() + //.Where(x => x.ByteArray.Length == x.ByteLength) + .First(a => new { item = a, length = a.ByteArray.Length }); + + Assert.NotNull(item); + Assert.Equal(Encoding.UTF8.GetString(byteArray), Encoding.UTF8.GetString(item.item.ByteArray)); + Assert.Equal(byteArray.Length, item.item.ByteLength); + Assert.Equal(byteArray.Length, item.length); + } + } + public class Model505 + { + public Guid id { get; set; } + public byte[] ByteArray { get; set; } + public int ByteLength { get; set; } + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/507.cs b/FreeSql.Tests/FreeSql.Tests/Issues/507.cs new file mode 100644 index 00000000..83884472 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/507.cs @@ -0,0 +1,163 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _507 + { + [Fact] + public void SelectTest() + { + var fsql = g.sqlite; + var _bodyAuditRepository = fsql.GetRepository(); + + var sql = _bodyAuditRepository.Select + .Include(a => a.ClassInfo) + .Count(out var total) + .OrderBy(true, a => a.ClassInfo.period) + .OrderBy(true, a => a.ClassInfo.className) + .Page(2, 10) + .ToList(); + } + public class BodyAuditEntity + { + public string Id { get; set; } + + /// + /// 班期标识-BodyScheduleEntity班期主键 + /// + [Column(Name = "ClassId", StringLength = 70, Position = 2)] + public string ClassId { get; set; } + + /// + /// 姓名 + /// + [Column(Name = "Name", StringLength = 20, Position = 3)] + public string Name { get; set; } + + + + /// + /// 出生日期 + /// + [Column(Name = "Birthday", StringLength = 20, Position = 5)] + public string Birthday { get; set; } + + /// + /// 身份证 + /// + [Column(Name = "IdCard", StringLength = 20, Position = 6)] + public string IdCard { get; set; } + + /// + /// 联系电话 + /// + [Column(Name = "TelPhone", StringLength = 15, Position = 7)] + public string TelPhone { get; set; } + + /// + /// 学校名称 + /// + [Column(Name = "SchoolName", StringLength = 50, Position = 8)] + public string SchoolName { get; set; } + + /// + /// 初潮年龄 + /// + [Column(Name = "StuCCNL", StringLength = 20, Position = 9)] + public int? StuCCNL { get; set; } + + /// + /// 联系地址 + /// + [Column(Name = "Address", StringLength = 100, Position = 10)] + public string Address { get; set; } + + /// + /// 审核人标识 + /// + [Column(Name = "CheckUserId", StringLength = 70)] + public string CheckUserId { get; set; } + + /// + /// 审核人 + /// + [Column(Name = "CheckUserName", StringLength = 20)] + public string CheckUserName { get; set; } + + /// + /// 审核时间 + /// + [Column(Name = "CheckTime")] + public DateTime? CheckTime { get; set; } + + /// + /// 拒绝原因 + /// + [Column(Name = "RefuseReason", StringLength = 100)] + public string RefuseReason { get; set; } + + /// + /// 采集时间 + /// + [Column(Name = "CollectionDate")] + public DateTime? CollectionDate { get; set; } + + /// + /// 附件标识(多附件) + /// + [Column(Name = "AttachmentId", StringLength = 500)] + public string AttachmentId { get; set; } + + /// + /// 性别 + /// + [Column(Name = "Sex", StringLength = 2, Position = 4)] + public string Sex { get; set; } + + #region 导航属性 + /// + /// 班期信息 + /// + [Navigate(nameof(ClassId))] + public virtual BodyScheduleEntity ClassInfo { get; set; } + #endregion + } + public class BodyScheduleEntity + { + public string Id { get; set; } + + [Column(Name = "period")] + public int? period { get; set; } + + [Column(Name = "maxQuota")] + public int? maxQuota { get; set; } + + [Column(Name = "allDays")] + public int? allDays { get; set; } + + [Column(Name = "schoolId", StringLength = 64)] + public string bodySchoolId { get; set; } + + [Column(Name = "ownership", StringLength = 64)] + public string ownership { get; set; } + + + [Column(Name = "className", StringLength = 20)] + public string className { get; set; } + + [Column(Name = "sex", StringLength = 10)] + public string sex { get; set; } + + [Column(Name = "classType", StringLength = 20)] + public string classType { get; set; } + } + + } +} diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index acc956e9..e97e9c88 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.Dameng Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"lengthb({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs index c2f6a1e1..f52cc8e6 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.Firebird Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs index 13f2b195..1c174d31 100644 --- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs @@ -19,6 +19,12 @@ namespace FreeSql.KingbaseES Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + var arrOperExp = getExp(arrOper); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); @@ -45,10 +51,6 @@ namespace FreeSql.KingbaseES } } break; - case ExpressionType.ArrayLength: - var arrOperExp = getExp((exp as UnaryExpression).Operand); - if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; - return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Call: var callExp = exp as MethodCallExpression; diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs index 0de463bc..337bba13 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessExpression.cs @@ -19,6 +19,10 @@ namespace FreeSql.MsAccess Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + //case ExpressionType.ArrayLength: + // var arrOper = (exp as UnaryExpression)?.Operand; + // if (arrOper.Type == typeof(byte[])) return $"lenb({getExp(arrOper)})"; #505 + // break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index d54733b2..8f784c47 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -20,6 +20,10 @@ namespace FreeSql.MySql Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index f7a344e3..0c9c5f84 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.Odbc.Dameng Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"lengthb({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index f819d74e..c9299d53 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -19,6 +19,12 @@ namespace FreeSql.Odbc.KingbaseES Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + var arrOperExp = getExp(arrOper); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); @@ -45,10 +51,6 @@ namespace FreeSql.Odbc.KingbaseES } } break; - case ExpressionType.ArrayLength: - var arrOperExp = getExp((exp as UnaryExpression).Operand); - if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; - return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Call: var callExp = exp as MethodCallExpression; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index 0867c078..bbf238d4 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.Odbc.MySql Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 7ee2af4a..f1adc650 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.Odbc.Oracle Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"dbms_lob.getlength({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index d4fc852d..fb932479 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -19,6 +19,12 @@ namespace FreeSql.Odbc.PostgreSQL Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + var arrOperExp = getExp(arrOper); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); @@ -45,10 +51,6 @@ namespace FreeSql.Odbc.PostgreSQL } } break; - case ExpressionType.ArrayLength: - var arrOperExp = getExp((exp as UnaryExpression).Operand); - if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; - return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Call: var callExp = exp as MethodCallExpression; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 65e0779d..97703237 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.Odbc.SqlServer Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"datalength({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 0d483ca3..d29a4041 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.Oracle Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"dbms_lob.getlength({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index f584472c..d2524cb4 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -20,6 +20,12 @@ namespace FreeSql.PostgreSQL Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + var arrOperExp = getExp(arrOper); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); @@ -46,10 +52,6 @@ namespace FreeSql.PostgreSQL } } break; - case ExpressionType.ArrayLength: - var arrOperExp = getExp((exp as UnaryExpression).Operand); - if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; - return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Call: var callExp = exp as MethodCallExpression; diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index aedaa4eb..81fc8592 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -19,6 +19,12 @@ namespace FreeSql.ShenTong Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + var arrOperExp = getExp(arrOper); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + //if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; #505 + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); @@ -45,10 +51,6 @@ namespace FreeSql.ShenTong } } break; - case ExpressionType.ArrayLength: - var arrOperExp = getExp((exp as UnaryExpression).Operand); - if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; - return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; case ExpressionType.Call: var callExp = exp as MethodCallExpression; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index 91ead6ed..ce8ddd09 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.SqlServer Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"datalength({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index fa3c394a..b6413643 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -18,6 +18,10 @@ namespace FreeSql.Sqlite Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); switch (exp.NodeType) { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"length({getExp(arrOper)})"; + break; case ExpressionType.Convert: var operandExp = (exp as UnaryExpression)?.Operand; var gentype = exp.Type.NullableTypeOrThis(); From eb3f38a0b4f9be4322652cafee47efe6b8b6b9ad Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 2 Nov 2020 19:37:52 +0800 Subject: [PATCH 0966/1029] =?UTF-8?q?-=20=E7=A7=BB=E9=99=A4=20ISelect/I?= =?UTF-8?q?Update/IDelete=20class=20=E7=BA=A6=E6=9D=9F=E9=99=90?= =?UTF-8?q?=E5=88=B6=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql/Interface/Curd/IDelete.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect11.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect12.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect13.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect14.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect15.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect16.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect4.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect5.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect6.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect7.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect8.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect9.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelectFrom.cs | 2 +- FreeSql/Interface/Curd/IUpdate.cs | 2 +- 21 files changed, 20 insertions(+), 29 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b54d4d0e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -509,14 +509,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index de01bf23..4d9bd3e8 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface IDelete where T1 : class + public interface IDelete { /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 4ef554fd..a35f2516 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace FreeSql { - public partial interface ISelect0 where T1 : class + public partial interface ISelect0 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index b5e061f5..88c8d412 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class + public interface ISelect : ISelect0, T1> { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 4b0a2862..24a0a9a9 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 + public interface ISelect : ISelect0, T1> 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 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect11.cs b/FreeSql/Interface/Curd/ISelect/ISelect11.cs index ef22e1a8..1e3aa5fd 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect11.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect11.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 where T11 : class + public interface ISelect : ISelect0, T1> 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 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect12.cs b/FreeSql/Interface/Curd/ISelect/ISelect12.cs index c41853a9..54762344 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect12.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect12.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 where T11 : class where T12 : class + public interface ISelect : ISelect0, T1> 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 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect13.cs b/FreeSql/Interface/Curd/ISelect/ISelect13.cs index b1a5f708..177fc863 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect13.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect13.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 where T11 : class where T12 : class where T13 : class + public interface ISelect : ISelect0, T1> 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 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect14.cs b/FreeSql/Interface/Curd/ISelect/ISelect14.cs index 42d8dbec..d9eaaca2 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect14.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect14.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 where T11 : class where T12 : class where T13 : class where T14 : class + public interface ISelect : ISelect0, T1> 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 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect15.cs b/FreeSql/Interface/Curd/ISelect/ISelect15.cs index a0eaf778..7e359c40 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect15.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect15.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + public interface ISelect : ISelect0, T1> 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 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect16.cs b/FreeSql/Interface/Curd/ISelect/ISelect16.cs index 2261ce16..feb4849f 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect16.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect16.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + public interface ISelect : ISelect0, T1> 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 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 0302108f..b576af5b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class + public interface ISelect : ISelect0, T1> where T2 : class { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index 7343cabe..7502091b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 622351c8..fc17cb64 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index ec19c52a..694b3505 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index b18bdac0..ed696e72 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index f16a7063..e27c5859 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 31f7d5c3..83d123c7 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 7a528689..b4c20825 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - 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 + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs b/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs index 6020ae4f..c7993c40 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs @@ -4,7 +4,7 @@ using System.Linq.Expressions; namespace FreeSql { - public interface ISelectFromExpression where T1 : class + public interface ISelectFromExpression { ISelectFromExpression LeftJoin(Expression> exp); diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index ed4ece43..004939c3 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { - public interface IUpdate where T1 : class + public interface IUpdate { /// From 5580602a1993883a3698fd4f41d20d7b8ccc3417 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 2 Nov 2020 19:42:40 +0800 Subject: [PATCH 0967/1029] v2.0.0-preview1102 #515 #505 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 31 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 3a409b49..7c500d83 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 729d5dcc..6ab501b6 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 252b3143..b68e5a5c 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 7a1d0e8b..f3f175c5 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 6a4c59df..826d2aba 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1026 + 2.0.0-preview1102 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index e1318f78..56f14cfb 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index bfa0c070..4691cf25 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b54d4d0e..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -509,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0fea82fa..582e897c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 225d0ee4..401f7500 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 3a5a9313..3dc9abe2 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 022b8894..d28e286d 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 146940bb..1125943e 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 300ecfd3..9ca67cb9 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index eea5aab4..ec6f5626 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index ab903e6c..19159d71 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 7141780f..6cdfd3ed 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index af67b441..074e8776 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 8a515533..76e9b176 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 2d395ebc..47059469 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index dd6ec8e9..a87d2dd0 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 89a03524..c5915f2c 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 0d9e5eaa..feed3695 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1026 + 2.0.0-preview1102 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From f3bc47feca7d14bb52a9dc57b376464d8cc58d71 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 2 Nov 2020 21:01:07 +0800 Subject: [PATCH 0968/1029] =?UTF-8?q?-=20=E7=A7=BB=E9=99=A4=20ISelect?= =?UTF-8?q?=20where=20T=20:=20class=20=E7=BA=A6=E6=9D=9F=E9=99=90=E5=88=B6?= =?UTF-8?q?=EF=BC=9B#515?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSqlExtensionsLinq.cs | 4 +- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 4 ++ .../Internal/CommonProvider/BaseDbProvider.cs | 43 ++++++++++++++++++ .../Internal/CommonProvider/DeleteProvider.cs | 2 +- .../SelectProvider/Select0Provider.cs | 6 +-- .../SelectProvider/Select10Provider.cs | 1 - .../SelectProvider/Select11Provider.cs | 1 - .../SelectProvider/Select12Provider.cs | 1 - .../SelectProvider/Select13Provider.cs | 1 - .../SelectProvider/Select14Provider.cs | 1 - .../SelectProvider/Select15Provider.cs | 1 - .../SelectProvider/Select16Provider.cs | 1 - .../SelectProvider/Select1Provider.cs | 1 - .../SelectProvider/Select2Provider.cs | 1 - .../SelectProvider/Select3Provider.cs | 1 - .../SelectProvider/Select4Provider.cs | 1 - .../SelectProvider/Select5Provider.cs | 1 - .../SelectProvider/Select6Provider.cs | 1 - .../SelectProvider/Select7Provider.cs | 1 - .../SelectProvider/Select8Provider.cs | 1 - .../SelectProvider/Select9Provider.cs | 1 - .../Internal/CommonProvider/UpdateProvider.cs | 2 +- .../Curd/DamengDelete.cs | 2 +- .../Curd/DamengSelect.cs | 32 +++++++------- .../Curd/DamengUpdate.cs | 2 +- .../FreeSql.Provider.Dameng/DamengProvider.cs | 37 +++------------- .../Curd/FirebirdDelete.cs | 2 +- .../Curd/FirebirdSelect.cs | 32 +++++++------- .../Curd/FirebirdUpdate.cs | 2 +- .../FirebirdProvider.cs | 40 ++++------------- .../Curd/KingbaseESDelete.cs | 2 +- .../Curd/KingbaseESSelect.cs | 32 +++++++------- .../Curd/KingbaseESUpdate.cs | 2 +- .../KingbaseESProvider.cs | 39 ++++------------ .../Curd/MsAccessDelete.cs | 2 +- .../Curd/MsAccessSelect.cs | 32 +++++++------- .../Curd/MsAccessUpdate.cs | 2 +- .../MsAccessProvider.cs | 43 +++++------------- .../Curd/MySqlDelete.cs | 2 +- .../Curd/MySqlSelect.cs | 32 +++++++------- .../Curd/MySqlUpdate.cs | 2 +- .../FreeSql.Provider.MySql/MySqlProvider.cs | 36 +++------------ .../Dameng/Curd/OdbcDamengDelete.cs | 2 +- .../Dameng/Curd/OdbcDamengSelect.cs | 32 +++++++------- .../Dameng/Curd/OdbcDamengUpdate.cs | 2 +- .../Dameng/OdbcDamengProvider.cs | 39 ++++------------ .../Default/Curd/OdbcDelete.cs | 2 +- .../Default/Curd/OdbcSelect.cs | 32 +++++++------- .../Default/Curd/OdbcUpdate.cs | 2 +- .../Default/OdbcProvider.cs | 35 ++++----------- .../KingbaseES/Curd/OdbcKingbaseESDelete.cs | 2 +- .../KingbaseES/Curd/OdbcKingbaseESSelect.cs | 32 +++++++------- .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 2 +- .../KingbaseES/OdbcKingbaseESProvider.cs | 39 ++++------------ .../MySql/Curd/OdbcMySqlDelete.cs | 2 +- .../MySql/Curd/OdbcMySqlSelect.cs | 32 +++++++------- .../MySql/Curd/OdbcMySqlUpdate.cs | 2 +- .../MySql/OdbcMySqlProvider.cs | 44 ++++--------------- .../Oracle/Curd/OdbcOracleDelete.cs | 2 +- .../Oracle/Curd/OdbcOracleSelect.cs | 32 +++++++------- .../Oracle/Curd/OdbcOracleUpdate.cs | 2 +- .../Oracle/OdbcOracleProvider.cs | 39 ++++------------ .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 2 +- .../PostgreSQL/Curd/OdbcPostgreSQLSelect.cs | 32 +++++++------- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLProvider.cs | 43 ++++-------------- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 2 +- .../SqlServer/Curd/OdbcSqlServerSelect.cs | 32 +++++++------- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 2 +- .../SqlServer/OdbcSqlServerProvider.cs | 39 ++++------------ .../Curd/OracleDelete.cs | 2 +- .../Curd/OracleSelect.cs | 32 +++++++------- .../Curd/OracleUpdate.cs | 2 +- .../FreeSql.Provider.Oracle/OracleProvider.cs | 39 ++++------------ .../Curd/PostgreSQLDelete.cs | 2 +- .../Curd/PostgreSQLSelect.cs | 32 +++++++------- .../Curd/PostgreSQLUpdate.cs | 2 +- .../PostgreSQLProvider.cs | 33 +++----------- .../Curd/ShenTongDelete.cs | 2 +- .../Curd/ShenTongSelect.cs | 32 +++++++------- .../Curd/ShenTongUpdate.cs | 2 +- .../ShenTongProvider.cs | 42 ++++-------------- .../Curd/SqlServerDelete.cs | 2 +- .../Curd/SqlServerSelect.cs | 32 +++++++------- .../Curd/SqlServerUpdate.cs | 2 +- .../SqlServerExpression.cs | 1 + .../SqlServerExtensions.cs | 2 +- .../SqlServerProvider.cs | 39 ++++------------ .../Curd/SqliteDelete.cs | 2 +- .../Curd/SqliteSelect.cs | 32 +++++++------- .../Curd/SqliteUpdate.cs | 2 +- .../FreeSql.Provider.Sqlite/SqliteProvider.cs | 39 ++++------------ 92 files changed, 497 insertions(+), 860 deletions(-) create mode 100644 FreeSql/Internal/CommonProvider/BaseDbProvider.cs diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs b/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs index 92d9aefa..45920717 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs +++ b/Extensions/FreeSql.Extensions.Linq/FreeSqlExtensionsLinq.cs @@ -40,7 +40,7 @@ public static class FreeSqlExtensionsLinqSql /// /// 【linq to sql】专用扩展方法,不建议直接使用 /// - public static ISelect Select(this ISelect that, Expression> select) where T1 : class where TReturn : class + public static ISelect Select(this ISelect that, Expression> select) { var s1p = that as Select1Provider; if (typeof(TReturn) == typeof(T1)) return that as ISelect; @@ -48,7 +48,7 @@ public static class FreeSqlExtensionsLinqSql s1p._selectExpression = select.Body; if (s1p._orm.CodeFirst.IsAutoSyncStructure) (s1p._orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TReturn)); //._dicSyced.TryAdd(typeof(TReturn), true); - var ret = s1p._orm.Select() as Select1Provider; + var ret = (s1p._orm as BaseDbProvider).CreateSelectProvider(null) as Select1Provider; Select0Provider.CopyData(s1p, ret, null); return ret; } diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index ff52cea6..626486b4 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -244,6 +244,10 @@ namespace FreeSql.Tests Assert.Throws(() => g.sqlite.Update().SetSource(new testUpdateNonePk()).ExecuteAffrows()); g.sqlite.Insert(new testInsertNullable()).NoneParameter().ExecuteAffrows(); + + + g.sqlite.Select().Select(a => a.Id).ToList(); + var ddlsql = g.sqlite.CodeFirst.GetComparisonDDLStatements(typeof(testInsertNullable), "tb123123"); Assert.Equal(@"CREATE TABLE IF NOT EXISTS ""main"".""tb123123"" ( ""Id"" INTEGER PRIMARY KEY AUTOINCREMENT, diff --git a/FreeSql/Internal/CommonProvider/BaseDbProvider.cs b/FreeSql/Internal/CommonProvider/BaseDbProvider.cs new file mode 100644 index 00000000..69077daa --- /dev/null +++ b/FreeSql/Internal/CommonProvider/BaseDbProvider.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; + +namespace FreeSql.Internal.CommonProvider +{ + public abstract partial class BaseDbProvider : IFreeSql + { + public abstract ISelect CreateSelectProvider(object dywhere); + public abstract IInsert CreateInsertProvider() where T1 : class; + public abstract IUpdate CreateUpdateProvider(object dywhere); + public abstract IDelete CreateDeleteProvider(object dywhere); + public abstract IInsertOrUpdate CreateInsertOrUpdateProvider() where T1 : class; + + public ISelect Select() where T1 : class => CreateSelectProvider(null); + public ISelect Select(object dywhere) where T1 : class => CreateSelectProvider(dywhere); + public IInsert Insert() where T1 : class => CreateInsertProvider(); + public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); + public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); + public IUpdate Update() where T1 : class => CreateUpdateProvider(null); + public IUpdate Update(object dywhere) where T1 : class => CreateUpdateProvider(dywhere); + public IDelete Delete() where T1 : class => CreateDeleteProvider(null); + public IDelete Delete(object dywhere) where T1 : class => CreateDeleteProvider(dywhere); + public IInsertOrUpdate InsertOrUpdate() where T1 : class => CreateInsertOrUpdateProvider(); + + public IAdo Ado { get; protected set; } + public IAop Aop { get; protected set; } + public ICodeFirst CodeFirst { get; protected set; } + public virtual IDbFirst DbFirst { get; protected set; } + + public CommonUtils InternalCommonUtils { get; protected set; } + public CommonExpression InternalCommonExpression { get; protected set; } + + public void Transaction(Action handler) => Ado.Transaction(handler); + public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); + + public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); + public abstract void Dispose(); + } +} diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 774812cc..69eb0b82 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract partial class DeleteProvider : IDelete where T1 : class + public abstract partial class DeleteProvider : IDelete { public IFreeSql _orm; public CommonUtils _commonUtils; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 3236d246..ca3712fd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -165,7 +165,7 @@ namespace FreeSql.Internal.CommonProvider } } - public abstract partial class Select0Provider : Select0Provider, ISelect0 where TSelect : class where T1 : class + public abstract partial class Select0Provider : Select0Provider, ISelect0 where TSelect : class { public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { @@ -371,7 +371,7 @@ namespace FreeSql.Internal.CommonProvider public IDelete ToDelete() { if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToDelete 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); - var del = _orm.Delete() as DeleteProvider; + var del = (_orm as BaseDbProvider).CreateDeleteProvider(null) as DeleteProvider; if (_tables[0].Table.Type != typeof(T1)) del.AsType(_tables[0].Table.Type); if (_params.Any()) del._params = new List(_params.ToArray()); if (_whereGlobalFilter.Any()) del._whereGlobalFilter = new List(_whereGlobalFilter.ToArray()); @@ -399,7 +399,7 @@ namespace FreeSql.Internal.CommonProvider public IUpdate ToUpdate() { if (_tables[0].Table.Primarys.Any() == false) throw new Exception($"ToUpdate 功能要求实体类 {_tables[0].Table.CsName} 必须有主键"); - var upd = _orm.Update() as UpdateProvider; + var upd = (_orm as BaseDbProvider).CreateUpdateProvider(null) as UpdateProvider; if (_tables[0].Table.Type != typeof(T1)) upd.AsType(_tables[0].Table.Type); if (_params.Any()) upd._params = new List(_params.ToArray()); if (_whereGlobalFilter.Any()) upd._whereGlobalFilter = new List(_whereGlobalFilter.ToArray()); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 0f7bbb0c..cb17d03d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select10Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs index d63ad2c4..3613cf42 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select11Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs index 3f0ee2be..98077570 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select12Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs index 733d3752..88c63d3f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select13Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs index b7444508..c027caf6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select14Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs index e97afd94..61ee7e0b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select15Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs index a1747eb2..f439e26d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select16Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index d7bba456..cc8e1e7a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -18,7 +18,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select1Provider : Select0Provider, T1>, ISelect - where T1 : class { public Select1Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 380fb784..08d0d55c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select2Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 5e0d9d7d..5d214f83 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select3Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 94726b48..b2d451fb 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select4Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 7de632c5..0e29039c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select5Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 1878e668..bbeb94ac 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select6Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 29ea495e..3927f2af 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select7Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 8d4be242..2ec77898 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select8Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 8f1861ec..93c5f395 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -10,7 +10,6 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select9Provider : Select0Provider, T1>, ISelect - where T1 : class where T2 : class where T3 : class where T4 : class diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 6742062d..40720ec1 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -13,7 +13,7 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract partial class UpdateProvider : IUpdate where T1 : class + public abstract partial class UpdateProvider : IUpdate { public IFreeSql _orm; public CommonUtils _commonUtils; diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs index 99141060..67c82634 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Dameng.Curd { - class DamengDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class DamengDelete : Internal.CommonProvider.DeleteProvider { public DamengDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs index de817e0e..b78215b1 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Dameng.Curd { - class DamengSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -143,78 +143,78 @@ namespace FreeSql.Dameng.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new DamengSelect(_orm, _commonUtils, _commonExpression, null); DamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class DamengSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class DamengSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class DamengSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class DamengSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public DamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => DamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs index 9fa70101..c4b88741 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace FreeSql.Dameng.Curd { - class DamengUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class DamengUpdate : Internal.CommonProvider.UpdateProvider { public DamengUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Dameng/DamengProvider.cs b/Providers/FreeSql.Provider.Dameng/DamengProvider.cs index 64b83116..eae036aa 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengProvider.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengProvider.cs @@ -1,35 +1,20 @@ using FreeSql.Dameng.Curd; -using FreeSql.Internal; using FreeSql.Internal.CommonProvider; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.Dameng { - public class DamengProvider : IFreeSql + public class DamengProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new DamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new DamengInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new DamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new DamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new DamengInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new DamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new DamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new DamengInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new DamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new DamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new DamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new DamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new DamengInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public DamengProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new DamengUtils(this); @@ -42,17 +27,9 @@ namespace FreeSql.Dameng this.CodeFirst = new DamengCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~DamengProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs index 84b5f537..8d00109a 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Firebird.Curd { - class FirebirdDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class FirebirdDelete : Internal.CommonProvider.DeleteProvider { public FirebirdDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs index d8a69c52..a31791d0 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Firebird.Curd { - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -134,78 +134,78 @@ namespace FreeSql.Firebird.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new FirebirdSelect(_orm, _commonUtils, _commonExpression, null); FirebirdSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class FirebirdSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class FirebirdSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public FirebirdSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => FirebirdSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs index 1963ab68..793554ff 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Firebird.Curd { - class FirebirdUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class FirebirdUpdate : Internal.CommonProvider.UpdateProvider { public FirebirdUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs b/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs index 24f2fbd6..af5f203d 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdProvider.cs @@ -1,36 +1,20 @@ -using FreeSql.Internal; +using FreeSql.Firebird.Curd; using FreeSql.Internal.CommonProvider; -using FreeSql.Firebird.Curd; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; -using System.Linq.Expressions; using System.Threading; namespace FreeSql.Firebird { - public class FirebirdProvider : IFreeSql + public class FirebirdProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new FirebirdSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new FirebirdInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new FirebirdUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new FirebirdDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new FirebirdInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new FirebirdSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new FirebirdSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new FirebirdInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new FirebirdUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new FirebirdUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new FirebirdDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new FirebirdDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new FirebirdInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public FirebirdProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new FirebirdUtils(this); @@ -50,17 +34,9 @@ namespace FreeSql.Firebird }; } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~FirebirdProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs index ef5b5579..f44eebb4 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.KingbaseES { - class KingbaseESDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class KingbaseESDelete : Internal.CommonProvider.DeleteProvider { public KingbaseESDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs index 303cae0f..927a26cd 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.KingbaseES { - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -133,78 +133,78 @@ namespace FreeSql.KingbaseES public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new KingbaseESSelect(_orm, _commonUtils, _commonExpression, null); KingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class KingbaseESSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public KingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => KingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs index c47a4adc..cb086288 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.KingbaseES { - class KingbaseESUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class KingbaseESUpdate : Internal.CommonProvider.UpdateProvider { public KingbaseESUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESProvider.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESProvider.cs index c91f9507..76a7dde8 100644 --- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESProvider.cs +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESProvider.cs @@ -1,34 +1,19 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.KingbaseES { - public class KingbaseESProvider : IFreeSql + public class KingbaseESProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new KingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new KingbaseESInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new KingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new KingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new KingbaseESInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new KingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new KingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new KingbaseESInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new KingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new KingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new KingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new KingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new KingbaseESInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public KingbaseESProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new KingbaseESUtils(this); @@ -41,17 +26,9 @@ namespace FreeSql.KingbaseES this.CodeFirst = new KingbaseESCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~KingbaseESProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs index 7990aae6..c0b00c49 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.MsAccess.Curd { - class MsAccessDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class MsAccessDelete : Internal.CommonProvider.DeleteProvider { public MsAccessDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs index 430f784d..9abd47c1 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessSelect.cs @@ -10,7 +10,7 @@ using System.Text.RegularExpressions; namespace FreeSql.MsAccess.Curd { - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -153,78 +153,78 @@ namespace FreeSql.MsAccess.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MsAccessSelect(_orm, _commonUtils, _commonExpression, null); MsAccessSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MsAccessSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class MsAccessSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public MsAccessSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MsAccessSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs index 91e345e3..47dcd294 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.MsAccess.Curd { - class MsAccessUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class MsAccessUpdate : Internal.CommonProvider.UpdateProvider { public MsAccessUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs index 9632ec87..a7dd41e5 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs @@ -1,35 +1,21 @@ -using FreeSql.MsAccess.Curd; -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; +using FreeSql.MsAccess.Curd; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.MsAccess { - public class MsAccessProvider : IFreeSql + public class MsAccessProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new MsAccessSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new MsAccessInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new MsAccessUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new MsAccessDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => throw new NotImplementedException(); - public ISelect Select() where T1 : class => new MsAccessSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new MsAccessSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new MsAccessInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new MsAccessUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new MsAccessUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new MsAccessDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new MsAccessDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => throw new NotImplementedException(); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); + public override IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); public MsAccessProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new MsAccessUtils(this); @@ -40,18 +26,9 @@ namespace FreeSql.MsAccess this.CodeFirst = new MsAccessCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~MsAccessProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index d982938e..1c04f9d4 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.MySql.Curd { - class MySqlDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class MySqlDelete : Internal.CommonProvider.DeleteProvider { public MySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs index ffa78e01..eb5177a0 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.MySql.Curd { - class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -131,78 +131,78 @@ namespace FreeSql.MySql.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class MySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class MySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index a15cc11a..659fa00d 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.MySql.Curd { - class MySqlUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class MySqlUpdate : Internal.CommonProvider.UpdateProvider { public MySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs index 8ebe5666..8002e559 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlProvider.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlProvider.cs @@ -2,8 +2,6 @@ using FreeSql.Internal.CommonProvider; using FreeSql.MySql.Curd; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; @@ -11,9 +9,8 @@ using System.Threading; namespace FreeSql.MySql { - public class MySqlProvider : IFreeSql + public class MySqlProvider : BaseDbProvider, IFreeSql { - static MySqlProvider() { Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPoint)] = true; @@ -39,23 +36,12 @@ namespace FreeSql.MySql }); } - public ISelect Select() where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new MySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new MySqlInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override ISelect CreateSelectProvider(object dywhere) => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new MySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new MySqlInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public MySqlProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new MySqlUtils(this); @@ -68,17 +54,9 @@ namespace FreeSql.MySql this.CodeFirst = new MySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~MySqlProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs index c7904f30..01b4db9f 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.Dameng { - class OdbcDamengDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class OdbcDamengDelete : Internal.CommonProvider.DeleteProvider { public OdbcDamengDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs index 46fc5c79..88b9d25d 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Odbc.Dameng { - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -143,78 +143,78 @@ namespace FreeSql.Odbc.Dameng public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcDamengSelect(_orm, _commonUtils, _commonExpression, null); OdbcDamengSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class OdbcDamengSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public OdbcDamengSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcDamengSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs index 6626c0d7..9f039209 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.Dameng { - class OdbcDamengUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class OdbcDamengUpdate : Internal.CommonProvider.UpdateProvider { public OdbcDamengUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs index 3644623c..7d3bae6c 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengProvider.cs @@ -1,34 +1,19 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.Odbc.Dameng { - public class OdbcDamengProvider : IFreeSql + public class OdbcDamengProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new OdbcDamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new OdbcDamengInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new OdbcDamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new OdbcDamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new OdbcDamengInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new OdbcDamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OdbcDamengSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OdbcDamengInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OdbcDamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OdbcDamengUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OdbcDamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OdbcDamengDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcDamengInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public OdbcDamengProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcDamengUtils(this); @@ -41,17 +26,9 @@ namespace FreeSql.Odbc.Dameng this.CodeFirst = new OdbcDamengCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcDamengProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs index cfc4663d..74350ebc 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.Default { - class OdbcDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class OdbcDelete : Internal.CommonProvider.DeleteProvider { public OdbcDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs index db1bb730..cb35af9b 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Odbc.Default { - class OdbcSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) { @@ -136,78 +136,78 @@ namespace FreeSql.Odbc.Default public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSelect(_orm, _commonUtils, _commonExpression, null); OdbcSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class OdbcSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public OdbcSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs index 3b4169b6..9e588197 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.Default { - class OdbcUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class OdbcUpdate : Internal.CommonProvider.UpdateProvider { OdbcUtils _utils; public OdbcUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs index 138487cb..383f93f9 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcProvider.cs @@ -12,26 +12,15 @@ using System.Threading; namespace FreeSql.Odbc.Default { - public class OdbcProvider : IFreeSql + public class OdbcProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new OdbcSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new OdbcInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => throw new NotImplementedException(); - public ISelect Select() where T1 : class => new OdbcSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OdbcSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OdbcInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OdbcUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OdbcDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => throw new NotImplementedException(); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + public override IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); /// /// 生成一个普通访问功能的 IFreeSql 对象,用来访问 odbc @@ -82,17 +71,9 @@ namespace FreeSql.Odbc.Default }); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; try diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs index 9d13cbc5..80e0e261 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.KingbaseES { - class OdbcKingbaseESDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class OdbcKingbaseESDelete : Internal.CommonProvider.DeleteProvider { public OdbcKingbaseESDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs index 647eca33..dece7c0a 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Odbc.KingbaseES { - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -133,78 +133,78 @@ namespace FreeSql.Odbc.KingbaseES public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcKingbaseESSelect(_orm, _commonUtils, _commonExpression, null); OdbcKingbaseESSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class OdbcKingbaseESSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public OdbcKingbaseESSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcKingbaseESSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index 4ba4b5f8..4cdfaf27 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.KingbaseES { - class OdbcKingbaseESUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class OdbcKingbaseESUpdate : Internal.CommonProvider.UpdateProvider { public OdbcKingbaseESUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESProvider.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESProvider.cs index 883cb633..86d5d77d 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESProvider.cs @@ -1,34 +1,19 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.Odbc.KingbaseES { - public class OdbcKingbaseESProvider : IFreeSql + public class OdbcKingbaseESProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new OdbcKingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new OdbcKingbaseESInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new OdbcKingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new OdbcKingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new OdbcKingbaseESInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new OdbcKingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OdbcKingbaseESSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OdbcKingbaseESInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OdbcKingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OdbcKingbaseESUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OdbcKingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OdbcKingbaseESDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcKingbaseESInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public OdbcKingbaseESProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcKingbaseESUtils(this); @@ -41,17 +26,9 @@ namespace FreeSql.Odbc.KingbaseES this.CodeFirst = new OdbcKingbaseESCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcKingbaseESProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index cb81a24d..5bf46d38 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.MySql { - class OdbcMySqlDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class OdbcMySqlDelete : Internal.CommonProvider.DeleteProvider { public OdbcMySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs index df77a38e..de181810 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Odbc.MySql { - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -131,78 +131,78 @@ namespace FreeSql.Odbc.MySql public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); OdbcMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index 31524a6a..6a07f83b 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.MySql { - class OdbcMySqlUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class OdbcMySqlUpdate : Internal.CommonProvider.UpdateProvider { public OdbcMySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs index 2d97a4d2..4b0622af 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlProvider.cs @@ -1,39 +1,19 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; -using System.Linq.Expressions; using System.Threading; namespace FreeSql.Odbc.MySql { - public class OdbcMySqlProvider : IFreeSql + public class OdbcMySqlProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new OdbcMySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new OdbcMySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new OdbcMySqlInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - static OdbcMySqlProvider() - { - } - - public ISelect Select() where T1 : class => new OdbcMySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OdbcMySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OdbcMySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OdbcMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OdbcMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcMySqlInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public OdbcMySqlProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcMySqlUtils(this); @@ -46,17 +26,9 @@ namespace FreeSql.Odbc.MySql this.CodeFirst = new OdbcMySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcMySqlProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs index 73085e57..992edefd 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.Oracle { - class OdbcOracleDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class OdbcOracleDelete : Internal.CommonProvider.DeleteProvider { public OdbcOracleDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs index 6e8c5240..04f69ca7 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Odbc.Oracle { - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -149,78 +149,78 @@ namespace FreeSql.Odbc.Oracle public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); OdbcOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index 9ab74f81..2ef008c9 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.Oracle { - class OdbcOracleUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class OdbcOracleUpdate : Internal.CommonProvider.UpdateProvider { public OdbcOracleUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs index fc9449fc..ec26bf9a 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleProvider.cs @@ -1,34 +1,19 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.Odbc.Oracle { - public class OdbcOracleProvider : IFreeSql + public class OdbcOracleProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new OdbcOracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new OdbcOracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new OdbcOracleInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new OdbcOracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OdbcOracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OdbcOracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OdbcOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OdbcOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcOracleInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public OdbcOracleProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcOracleUtils(this); @@ -47,17 +32,9 @@ namespace FreeSql.Odbc.Oracle //}); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcOracleProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index f9245c03..bf41c0da 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.PostgreSQL { - class OdbcPostgreSQLDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class OdbcPostgreSQLDelete : Internal.CommonProvider.DeleteProvider { public OdbcPostgreSQLDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs index 0c4664a3..79677e82 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Odbc.PostgreSQL { - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -133,78 +133,78 @@ namespace FreeSql.Odbc.PostgreSQL public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); OdbcPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index 9e9dce01..dd21bcef 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.PostgreSQL { - class OdbcPostgreSQLUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class OdbcPostgreSQLUpdate : Internal.CommonProvider.UpdateProvider { public OdbcPostgreSQLUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs index 041bb2f9..c226a0ee 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLProvider.cs @@ -1,38 +1,19 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.Odbc.PostgreSQL { - public class OdbcPostgreSQLProvider : IFreeSql + public class OdbcPostgreSQLProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new OdbcPostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new OdbcPostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new OdbcPostgreSQLInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - static OdbcPostgreSQLProvider() - { - } - - public ISelect Select() where T1 : class => new OdbcPostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OdbcPostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OdbcPostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OdbcPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OdbcPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcPostgreSQLInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public OdbcPostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcPostgreSQLUtils(this); @@ -45,17 +26,9 @@ namespace FreeSql.Odbc.PostgreSQL this.CodeFirst = new OdbcPostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcPostgreSQLProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index 0530a4a9..186dab45 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.SqlServer { - class OdbcSqlServerDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class OdbcSqlServerDelete : Internal.CommonProvider.DeleteProvider { public OdbcSqlServerDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index f522f11a..6302576f 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Odbc.SqlServer { - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -267,78 +267,78 @@ namespace FreeSql.Odbc.SqlServer public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OdbcSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index 58a2f5cb..b1009017 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Odbc.SqlServer { - class OdbcSqlServerUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class OdbcSqlServerUpdate : Internal.CommonProvider.UpdateProvider { public OdbcSqlServerUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs index d1e6aab7..26cdd0a2 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerProvider.cs @@ -1,34 +1,19 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.Odbc.SqlServer { - public class OdbcSqlServerProvider : IFreeSql + public class OdbcSqlServerProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new OdbcSqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new OdbcSqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new OdbcSqlServerInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new OdbcSqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OdbcSqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OdbcSqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OdbcSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OdbcSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OdbcSqlServerInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public OdbcSqlServerProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OdbcSqlServerUtils(this); @@ -53,17 +38,9 @@ namespace FreeSql.Odbc.SqlServer } } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OdbcSqlServerProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs index 8bd84136..ddc12132 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Oracle.Curd { - class OracleDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class OracleDelete : Internal.CommonProvider.DeleteProvider { public OracleDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs index 6e364d8d..0a04eac5 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Oracle.Curd { - class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -149,78 +149,78 @@ namespace FreeSql.Oracle.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class OracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class OracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index a1e4cdcf..f0652f8d 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Oracle.Curd { - class OracleUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class OracleUpdate : Internal.CommonProvider.UpdateProvider { public OracleUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs index f65b8200..272ab1a8 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleProvider.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleProvider.cs @@ -1,35 +1,20 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using FreeSql.Oracle.Curd; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.Oracle { - public class OracleProvider : IFreeSql + public class OracleProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new OracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new OracleInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new OracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new OracleInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public OracleProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new OracleUtils(this); @@ -42,17 +27,9 @@ namespace FreeSql.Oracle this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~OracleProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index 57e33eaf..dc640615 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.PostgreSQL.Curd { - class PostgreSQLDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class PostgreSQLDelete : Internal.CommonProvider.DeleteProvider { public PostgreSQLDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs index 49eb4488..76df4935 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.PostgreSQL.Curd { - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -133,78 +133,78 @@ namespace FreeSql.PostgreSQL.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index a6fd43aa..085ac4bd 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.PostgreSQL.Curd { - class PostgreSQLUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class PostgreSQLUpdate : Internal.CommonProvider.UpdateProvider { public PostgreSQLUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs index 63f00d91..951b8373 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLProvider.cs @@ -17,7 +17,7 @@ using System.Threading; namespace FreeSql.PostgreSQL { - public class PostgreSQLProvider : IFreeSql + public class PostgreSQLProvider : BaseDbProvider, IFreeSql { static PostgreSQLProvider() @@ -80,23 +80,12 @@ namespace FreeSql.PostgreSQL }); } - public ISelect Select() where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new PostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new PostgreSQLInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override ISelect CreateSelectProvider(object dywhere) => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new PostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new PostgreSQLInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public PostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new PostgreSQLUtils(this); @@ -109,17 +98,9 @@ namespace FreeSql.PostgreSQL this.CodeFirst = new PostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~PostgreSQLProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs index c67a0b3c..a7d7aba2 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.ShenTong.Curd { - class ShenTongDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class ShenTongDelete : Internal.CommonProvider.DeleteProvider { public ShenTongDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs index 7495185b..36fbaca0 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.ShenTong.Curd { - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -133,78 +133,78 @@ namespace FreeSql.ShenTong.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new ShenTongSelect(_orm, _commonUtils, _commonExpression, null); ShenTongSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class ShenTongSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class ShenTongSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public ShenTongSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => ShenTongSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index ba4b22ea..50c293e7 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; namespace FreeSql.ShenTong.Curd { - class ShenTongUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class ShenTongUpdate : Internal.CommonProvider.UpdateProvider { public ShenTongUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs index 7258038d..f0e0e4e6 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongProvider.cs @@ -1,38 +1,20 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using FreeSql.ShenTong.Curd; using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; using System.Data.Common; -using System.Linq.Expressions; -using System.Net; -using System.Net.NetworkInformation; using System.Threading; namespace FreeSql.ShenTong { - public class ShenTongProvider : IFreeSql + public class ShenTongProvider : BaseDbProvider, IFreeSql { - public ISelect Select() where T1 : class => new ShenTongSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new ShenTongSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new ShenTongInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new ShenTongUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new ShenTongUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new ShenTongDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new ShenTongDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new ShenTongInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override ISelect CreateSelectProvider(object dywhere) => new ShenTongSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new ShenTongInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new ShenTongUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new ShenTongDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new ShenTongInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public ShenTongProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new ShenTongUtils(this); @@ -45,17 +27,9 @@ namespace FreeSql.ShenTong this.CodeFirst = new ShenTongCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~ShenTongProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index 75eaf638..21a877d4 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.SqlServer.Curd { - class SqlServerDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class SqlServerDelete : Internal.CommonProvider.DeleteProvider { public SqlServerDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index 9f35cc47..fa1c1af6 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.SqlServer.Curd { - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -270,78 +270,78 @@ namespace FreeSql.SqlServer.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class SqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index 8dbb9708..f70a8143 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.SqlServer.Curd { - class SqlServerUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class SqlServerUpdate : Internal.CommonProvider.UpdateProvider { public SqlServerUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index ce8ddd09..ef1a02fc 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -320,6 +320,7 @@ namespace FreeSql.SqlServer if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar(max))+'%')")}"; if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar(max)))")}"; if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + if (args0Value.StartsWith("N'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(2, "%").Insert(args0Value.Length, "%")}"; return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar(max))+'%')"; case "ToLower": return $"lower({left})"; case "ToUpper": return $"upper({left})"; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index e399bd74..3c294f85 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -30,7 +30,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions /// /// 多表查询时的锁规则 /// - public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) where T : class + public static ISelect WithLock(this ISelect that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary rule = null) => rule == null ? that.AsAlias((type, old) => $"{old} With({lockType.ToString()})") : that.AsAlias((type, old) => rule.TryGetValue(type, out var trybool) && trybool ? $"{old} With({lockType.ToString()})" : old); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs index 8ab8e0a8..3e7e6667 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerProvider.cs @@ -1,35 +1,20 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using FreeSql.SqlServer.Curd; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.SqlServer { - public class SqlServerProvider : IFreeSql + public class SqlServerProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new SqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new SqlServerInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new SqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new SqlServerInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; } public SqlServerProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new SqlServerUtils(this); @@ -54,17 +39,9 @@ namespace FreeSql.SqlServer } } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~SqlServerProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs index d71498cf..25c104ff 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FreeSql.Sqlite.Curd { - class SqliteDelete : Internal.CommonProvider.DeleteProvider where T1 : class + class SqliteDelete : Internal.CommonProvider.DeleteProvider { public SqliteDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs index 782e094f..30843855 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteSelect.cs @@ -9,7 +9,7 @@ using System.Text; namespace FreeSql.Sqlite.Curd { - class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider where T1 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select1Provider { internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) @@ -131,78 +131,78 @@ namespace FreeSql.Sqlite.Curd public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret, exp?.Parameters); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider 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 + class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); } - class SqliteSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + class SqliteSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index 7900160f..1fefc121 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FreeSql.Sqlite.Curd { - class SqliteUpdate : Internal.CommonProvider.UpdateProvider where T1 : class + class SqliteUpdate : Internal.CommonProvider.UpdateProvider { public SqliteUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs index ddb71c02..24a82779 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteProvider.cs @@ -1,35 +1,20 @@ -using FreeSql.Internal; -using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.CommonProvider; using FreeSql.Sqlite.Curd; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; using System.Threading; namespace FreeSql.Sqlite { - public class SqliteProvider : IFreeSql + public class SqliteProvider : BaseDbProvider, IFreeSql { + public override ISelect CreateSelectProvider(object dywhere) => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new SqliteInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new SqliteInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - public ISelect Select() where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new SqliteInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); - public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(T1[] source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(List source) where T1 : class => this.Insert().AppendData(source); - public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsertOrUpdate InsertOrUpdate() where T1 : class => new SqliteInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); - - public IAdo Ado { get; } - public IAop Aop { get; } - public ICodeFirst CodeFirst { get; } - public IDbFirst DbFirst { get; }// => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); public SqliteProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new SqliteUtils(this); @@ -43,17 +28,9 @@ namespace FreeSql.Sqlite if (connectionFactory != null) this.CodeFirst.IsNoneCommandParameter = true; } - internal CommonUtils InternalCommonUtils { get; } - internal CommonExpression InternalCommonExpression { get; } - - public void Transaction(Action handler) => Ado.Transaction(handler); - public void Transaction(IsolationLevel isolationLevel, Action handler) => Ado.Transaction(isolationLevel, handler); - - public GlobalFilter GlobalFilter { get; } = new GlobalFilter(); - ~SqliteProvider() => this.Dispose(); int _disposeCounter; - public void Dispose() + public override void Dispose() { if (Interlocked.Increment(ref _disposeCounter) != 1) return; (this.Ado as AdoProvider)?.Dispose(); From 768cbdc97ad88e70efe2263be70f7af1ba02e2a8 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 2 Nov 2020 22:24:59 +0800 Subject: [PATCH 0969/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20HzyTuple=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=9B=BF=E6=8D=A2=E7=B1=BB=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 5 +++ FreeSql/Interface/Curd/ISelect/ISelect0.cs | 4 ++- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 1 + FreeSql/Internal/CommonExpression.cs | 33 +++++++++++++++++++ .../SelectProvider/Select0Provider.cs | 2 +- .../SelectProvider/Select2Provider.cs | 8 +++++ 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index a74ab260..b415c3d0 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -379,6 +379,11 @@ WHERE ROWNUM < 11"; var dkkdksdjgj22 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.Subtract(dt1970).TotalSeconds).ToSql(); + var xxxhzytuple = g.sqlserver.Select() + .Where(a => a.Item1.Code == "xxx" && a.Item2.OptionsEntity03 == true) + .ToSql(); + + var xxxkdkd = g.oracle.Select() .InnerJoin((a,b) => true) .Where((a,b) => (DateTime.Now - a.EditTime).TotalMinutes > 100) diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index a35f2516..b4839cfb 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -9,7 +9,9 @@ using System.Threading.Tasks; namespace FreeSql { - public partial interface ISelect0 + public partial interface ISelect0 { } + + public partial interface ISelect0 : ISelect0 { #if net40 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index b576af5b..1b57b273 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -54,6 +54,7 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); + ISelect Where(Expression, bool>> exp); ISelectGrouping> GroupBy(Expression> exp); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6952905d..44df11aa 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1664,6 +1664,39 @@ namespace FreeSql.Internal } } + internal class ReplaceHzyTupleToMultiParam : ExpressionVisitor + { + private List tables; + private ParameterExpression[] parameters; + public LambdaExpression Modify(LambdaExpression lambda, List tables) + { + this.tables = tables; + parameters = tables.Select(a => a.Parameter ?? Expression.Parameter(a.Table.Type, a.Alias)).ToArray(); + var exp = Visit(lambda.Body); + return Expression.Lambda(exp, parameters); + } + + protected override Expression VisitMember(MemberExpression node) + { + int widx; + if (node.Expression?.NodeType == ExpressionType.MemberAccess) + { + var parent = node.Expression as MemberExpression; + if (parent.Expression?.NodeType == ExpressionType.Parameter && + parent.Expression.Type.Name.StartsWith("NativeTuple`") == true && + int.TryParse(parent.Member.Name.Replace("Item", ""), out widx) && widx > 0 && widx <= tables.Count) + return Expression.Property(parameters[widx - 1], node.Member.Name); + } + + if (node.Expression?.NodeType == ExpressionType.Parameter && + node.Expression.Type.Name.StartsWith("NativeTuple`") == true && + int.TryParse(node.Member.Name.Replace("Item", ""), out widx) && widx > 0 && widx <= tables.Count) + return parameters[widx - 1]; + + return base.VisitMember(node); + } + } + public string formatSql(object obj, Type mapType, ColumnInfo mapColumn, List dbParams) { //参数化设置,日后优化 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index ca3712fd..bafaf7be 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -60,7 +60,7 @@ namespace FreeSql.Internal.CommonProvider #endif _includeInfo.Clear(); _selectExpression = null; - _whereGlobalFilter.Clear(); + _whereGlobalFilter?.Clear(); } public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection lambParms) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 08d0d55c..3c65f7b7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -178,6 +178,14 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } + ISelect ISelect.Where(Expression, bool>> exp) + { + if (exp == null) return this.Where(null); + var exp2 = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + for (var a = 0; a < exp2.Parameters.Count; a++) _tables[a].Parameter = exp2.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp2, null, _whereGlobalFilter, _params)); + } + bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); From d88b465022e70ced99b0c8d359f58d53a7ec4445 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 3 Nov 2020 12:00:24 +0800 Subject: [PATCH 0970/1029] - debug code --- .../FreeSql.Extensions.Linq.csproj | 6 +- .../SelectedQueryProvider.cs | 175 ++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 96 +++++----- .../SelectProvider/SelectGroupingProvider.cs | 6 +- 4 files changed, 233 insertions(+), 50 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index f3f175c5..f11ca82d 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -29,7 +29,11 @@ FreeSql.Extensions.Linq.xml 3 - + + + net40 + + diff --git a/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs new file mode 100644 index 00000000..8d58c3c9 --- /dev/null +++ b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs @@ -0,0 +1,175 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql +{ + public interface ISelectedQuery + { +#if net40 +#else + Task> ToListAsync(); + Task ToOneAsync(); + Task FirstAsync(); + + Task AnyAsync(); + Task CountAsync(); +#endif + + List ToList(); + TOut ToOne(); + TOut First(); + + string ToSql(); + bool Any(); + + long Count(); + ISelectedQuery Count(out long count); + + ISelectedQuery Skip(int offset); + ISelectedQuery Offset(int offset); + ISelectedQuery Limit(int limit); + ISelectedQuery Take(int limit); + ISelectedQuery Page(int pageNumber, int pageSize); + + ISelectedQuery Where(Expression> exp); + ISelectedQuery WhereIf(bool condition, Expression> exp); + + ISelectedQuery OrderBy(Expression> column); + ISelectedQuery OrderByIf(bool condition, Expression> column, bool descending = false); + ISelectedQuery OrderByDescending(Expression> column); + } +} + +namespace FreeSql.Internal.CommonProvider +{ + public class SelectedQueryProvider : BaseDiyMemberExpression, ISelectedQuery + { + public Select0Provider _select; + public CommonExpression _comonExp; + public SelectedQueryProvider(Select0Provider select, Expression selector) + { + _select = select; + _comonExp = _select._commonExpression; + _map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = -10000; //临时规则,不返回 as1 + + if (selector != null) + _comonExp.ReadAnonymousField(_select._tables, field, _map, ref index, selector, null, null, _select._whereGlobalFilter, null, false); //不走 DTO 映射,不处理 IncludeMany + _field = field.ToString(); + } + + public override string ParseExp(Expression[] members) + { + if (members.Any() == false) return _map.DbField; + var read = _map; + for (var a = 0; a < members.Length; a++) + { + read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault(); + if (read == null) return null; + } + return read.DbField; + } + +#if net40 +#else + public Task> ToListAsync() + { + var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(typeof(TOut)); + return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(_map, _field.Length > 0 ? _field.Remove(0, 2).ToString() : null) }) as Task>; + } + async public Task ToOneAsync() => (await ToListAsync()).FirstOrDefault(); + public Task FirstAsync() => ToOneAsync(); + + public Task AnyAsync() + { + var method = _select.GetType().GetMethod("AnyAsync", new Type[0]); + return method.Invoke(_select, new object[0]) as Task; + } + public Task CountAsync() + { + var method = _select.GetType().GetMethod("CountAsync", new Type[0]); + return method.Invoke(_select, new object[0]) as Task; + } +#endif + + public List ToList() + { + var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(typeof(TOut)); + return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(_map, _field.Length > 0 ? _field.Remove(0, 2).ToString() : null) }) as List; + } + public TOut ToOne() => ToList().FirstOrDefault(); + public TOut First() => ToOne(); + + public string ToSql() + { + var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); + return method.Invoke(_select, new object[] { _field.Length > 0 ? _field.Remove(0, 2).ToString() : null }) as string; + } + + public bool Any() + { + var method = _select.GetType().GetMethod("Any", new Type[0]); + return (bool)method.Invoke(_select, new object[0]); + } + public long Count() + { + var method = _select.GetType().GetMethod("Count", new Type[0]); + return (long)method.Invoke(_select, new object[0]); + } + public ISelectedQuery Count(out long count) + { + count = this.Count(); + return this; + } + + public ISelectedQuery Skip(int offset) + { + _select._skip = offset; + return this; + } + public ISelectedQuery Offset(int offset) => Skip(offset); + public ISelectedQuery Limit(int limit) => Take(limit); + public ISelectedQuery Take(int limit) + { + _select._limit = limit; + return this; + } + public ISelectedQuery Page(int pageNumber, int pageSize) + { + this.Skip(Math.Max(0, pageNumber - 1) * pageSize); + return this.Limit(pageSize); + } + + public ISelectedQuery OrderBy(Expression> column) => OrderByIf(true, column); + public ISelectedQuery OrderByIf(bool condition, Expression> column, bool descending = false) + { + if (condition == false) return this; + var sql = _comonExp.ExpressionWhereLambda(null, column, this, null, null); + var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); + method.Invoke(_select, new object[] { descending ? $"{sql} DESC" : sql, null }); + return this; + } + public ISelectedQuery OrderByDescending(Expression> column) => OrderByIf(true, column, true); + + public ISelectedQuery Where(Expression> exp) => WhereIf(true, exp); + public ISelectedQuery WhereIf(bool condition, Expression> exp) + { + if (condition == false) return this; + var sql = _comonExp.ExpressionWhereLambda(null, exp, this, null, null); + var method = _select.GetType().GetMethod("Where", new[] { typeof(string), typeof(object) }); + method.Invoke(_select, new object[] { sql, null }); + return this; + } + } +} diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 44df11aa..ca0880af 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -16,6 +16,13 @@ using System.Threading; namespace FreeSql.Internal { + public abstract class BaseDiyMemberExpression + { + public ReadAnonymousTypeInfo _map; + public string _field; + public abstract string ParseExp(Expression[] members); + } + public abstract class CommonExpression { @@ -28,13 +35,13 @@ namespace FreeSql.Internal } internal const int ReadAnonymousFieldAsCsName = -53129; - public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, SelectGroupingProvider grouping, List whereGlobalFilter, List findIncludeMany, bool isAllDtoMap) + public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, BaseDiyMemberExpression diymemexp, List whereGlobalFilter, List findIncludeMany, bool isAllDtoMap) { - Func getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = select?._params }; //#462 添加 DbParams 解决 + Func getTSC = () => new ExpTSC { _tables = _tables, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = select?._params }; //#462 添加 DbParams 解决 switch (exp.NodeType) { - case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); - case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); + case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap); + case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap); case ExpressionType.Negate: case ExpressionType.NegateChecked: parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; @@ -43,7 +50,7 @@ namespace FreeSql.Internal else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; - case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); + case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap); case ExpressionType.Constant: var constExp = exp as ConstantExpression; //处理自定义SQL语句,如: ToList(new { @@ -93,7 +100,7 @@ namespace FreeSql.Internal { //加载表所有字段 var map = new List(); - ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, grouping); + ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, diymemexp); var tb = parent.Table = map.First().Table.Table; parent.CsType = tb.Type; parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst(); @@ -133,7 +140,7 @@ namespace FreeSql.Internal MapType = memProp.PropertyType }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, grouping, whereGlobalFilter, findIncludeMany, false); + ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, diymemexp, whereGlobalFilter, findIncludeMany, false); } } } @@ -163,11 +170,11 @@ namespace FreeSql.Internal } } } - if (grouping != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) + if (diymemexp != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { - field.Append(grouping._field); + field.Append(diymemexp._field); var parentProp = parent.Property; - grouping._map.CopyTo(parent); + diymemexp._map.CopyTo(parent); parent.Property = parentProp; //若不加此行,会引用 GroupBy(..).ToList(a => new Dto { key = a.Key }) null 错误,CopyTo 之后 Property 变为 null return false; } @@ -199,7 +206,7 @@ namespace FreeSql.Internal MapType = initExp.NewExpression.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, grouping, whereGlobalFilter, findIncludeMany, false); + ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, false); } } else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) @@ -224,7 +231,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -250,7 +257,7 @@ namespace FreeSql.Internal MapType = initAssignExp.Expression.Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, grouping, whereGlobalFilter, findIncludeMany, false); + ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, diymemexp, whereGlobalFilter, findIncludeMany, false); } } if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); @@ -283,7 +290,7 @@ namespace FreeSql.Internal MapType = newExp.Arguments[a].Type }; parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, grouping, whereGlobalFilter, findIncludeMany, false); + ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, false); } } else @@ -307,7 +314,7 @@ namespace FreeSql.Internal }; parent.Childs.Add(child); if (dtTb.Parameter != null) - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap); + ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap); else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; @@ -404,32 +411,32 @@ namespace FreeSql.Internal return null; } - public string ExpressionSelectColumn_MemberAccess(List _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, SelectGroupingProvider grouping) + public string ExpressionSelectColumn_MemberAccess(List _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, BaseDiyMemberExpression diymemexp) { - return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, grouping = grouping, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns }); + return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, diymemexp = diymemexp, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns }); } - public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List _tables, Expression exp, bool isQuoteName, SelectGroupingProvider grouping) + public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List _tables, Expression exp, bool isQuoteName, BaseDiyMemberExpression diymemexp) { switch (exp?.NodeType) { - case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, grouping); - case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, grouping); - case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, grouping); - case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, grouping) }; + case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, diymemexp); + case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, diymemexp); + case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, diymemexp); + case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, diymemexp) }; case ExpressionType.Call: - case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, grouping).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries); + case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, diymemexp).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries); case ExpressionType.New: var newExp = exp as NewExpression; if (newExp == null) break; var newExpMembers = new string[newExp.Members.Count]; - for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, grouping); + for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, diymemexp); return newExpMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); case ExpressionType.NewArrayInit: var newArr = exp as NewArrayExpression; if (newArr == null) break; var newArrMembers = new List(); - foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, grouping)); + foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, diymemexp)); return newArrMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); default: throw new ArgumentException($"无法解析表达式:{exp}"); } @@ -454,22 +461,22 @@ namespace FreeSql.Internal { ExpressionType.Equal, "=" }, }; - public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, SelectGroupingProvider groupingProvider, List dbParams) + public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, BaseDiyMemberExpression diymemexp, List dbParams) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = dbParams }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = dbParams }); return GetBoolString(exp, sql); } - public string ExpressionWhereLambda(List _tables, Expression exp, SelectGroupingProvider groupingProvider, List whereGlobalFilter, List dbParams) + public string ExpressionWhereLambda(List _tables, Expression exp, BaseDiyMemberExpression diymemexp, List whereGlobalFilter, List dbParams) { - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = dbParams }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = dbParams }); return GetBoolString(exp, sql); } static ConcurrentDictionary dicRegexAlias = new ConcurrentDictionary(); - public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, SelectGroupingProvider groupingProvider, List whereGlobalFilter) + public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, BaseDiyMemberExpression diymemexp, List whereGlobalFilter) { var tbidx = _tables.Count; - var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter }); + var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, diymemexp = diymemexp, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter }); sql = GetBoolString(exp, sql); if (_tables.Count > tbidx) @@ -891,7 +898,7 @@ namespace FreeSql.Internal var testExecuteExp = asSelectParentExp; if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联 testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key); - var tsc2 = tsc.CloneSetselectColumnMapAndgroupingAndtbtype(new List(), tsc.grouping, SelectTableInfoType.LeftJoin); + var tsc2 = tsc.Clone_selectColumnMap_diymemexp_tbtype(new List(), tsc.diymemexp, SelectTableInfoType.LeftJoin); tsc2.isDisableDiyParse = true; tsc2.style = ExpressionStyle.AsSelect; asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2); @@ -1253,13 +1260,12 @@ namespace FreeSql.Internal return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); } if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); - if (tsc.grouping != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) + if (tsc.diymemexp != null) { - if (tsc.grouping != null) - { - var expText = tsc.grouping.GetSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray()); - if (string.IsNullOrEmpty(expText) == false) return expText; - } + var expStackFirst = expStack.First(); + var bidx = expStackFirst.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`") ? 2 : 1; //.Key .Value + var expText = tsc.diymemexp.ParseExp(expStack.Where((a, b) => b >= bidx).ToArray()); + if (string.IsNullOrEmpty(expText) == false) return expText; } if (tsc._tables == null) @@ -1367,9 +1373,9 @@ namespace FreeSql.Internal if (find.Type == SelectTableInfoType.InnerJoin || find.Type == SelectTableInfoType.LeftJoin || find.Type == SelectTableInfoType.RightJoin) - find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetselectColumnMapAndgroupingAndtbtype(null, null, find.Type)); + find.On = ExpressionLambdaToSql(navCondExp, tsc.Clone_selectColumnMap_diymemexp_tbtype(null, null, find.Type)); else - find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetselectColumnMapAndgroupingAndtbtype(null, null, find.Type)); + find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.Clone_selectColumnMap_diymemexp_tbtype(null, null, find.Type)); } } } @@ -1515,7 +1521,7 @@ namespace FreeSql.Internal { public List _tables { get; set; } public List _selectColumnMap { get; set; } - public SelectGroupingProvider grouping { get; set; } + public BaseDiyMemberExpression diymemexp { get; set; } public Select0Provider subSelect001 { get; set; } //#405 Oracle within group(order by ..) public SelectTableInfoType tbtype { get; set; } public bool isQuoteName { get; set; } @@ -1556,13 +1562,13 @@ namespace FreeSql.Internal return old; } - public ExpTSC CloneSetselectColumnMapAndgroupingAndtbtype(List v1, SelectGroupingProvider v2, SelectTableInfoType v3) + public ExpTSC Clone_selectColumnMap_diymemexp_tbtype(List v1, BaseDiyMemberExpression v2, SelectTableInfoType v3) { return new ExpTSC { _tables = this._tables, _selectColumnMap = v1, - grouping = v2, + diymemexp = v2, tbtype = v3, isQuoteName = this.isQuoteName, isDisableDiyParse = this.isDisableDiyParse, @@ -1582,7 +1588,7 @@ namespace FreeSql.Internal { _tables = this._tables, _selectColumnMap = this._selectColumnMap, - grouping = this.grouping, + diymemexp = this.diymemexp, subSelect001 = this.subSelect001, tbtype = this.tbtype, isQuoteName = this.isQuoteName, @@ -1626,7 +1632,7 @@ namespace FreeSql.Internal ); var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = isMultitb ? new List(new[] { tb }) : null, - _selectColumnMap = null, grouping = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); + _selectColumnMap = null, diymemexp = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); whereSql = GetBoolString(expExp.Body, whereSql); if (isEmpty == false) sb.Append(" AND "); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 25694049..33299b9f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -11,12 +11,10 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public class SelectGroupingProvider + public class SelectGroupingProvider : BaseDiyMemberExpression { public IFreeSql _orm; public Select0Provider _select; - public ReadAnonymousTypeInfo _map; - public string _field; public CommonExpression _comonExp; public List _tables; @@ -30,7 +28,7 @@ namespace FreeSql.Internal.CommonProvider _tables = tables; } - public string GetSelectGroupingMapString(Expression[] members) + public override string ParseExp(Expression[] members) { if (members.Any() == false) return _map.DbField; var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name; From 8e67cb3d73d477ba6a76d21bdcb30ec6fc5d9f3a Mon Sep 17 00:00:00 2001 From: hzy <1396510655@qq.com> Date: Tue, 3 Nov 2020 22:57:51 +0800 Subject: [PATCH 0971/1029] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E5=A4=9A=E8=A1=A8=E6=9F=A5=E8=AF=A2=E8=AF=AD=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E7=AE=80=E5=8C=96=20=E5=AE=9A=E4=B9=89=20=E4=B8=80=E5=A0=86=20?= =?UTF-8?q?abcd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Internal/Model/HzyTuple.cs | 382 +++++++++++++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 FreeSql/Internal/Model/HzyTuple.cs diff --git a/FreeSql/Internal/Model/HzyTuple.cs b/FreeSql/Internal/Model/HzyTuple.cs new file mode 100644 index 00000000..f7afb40d --- /dev/null +++ b/FreeSql/Internal/Model/HzyTuple.cs @@ -0,0 +1,382 @@ +namespace HzySql.Models +{ + using HzySql.Interface; + + public class HzyTuple + { + /// + /// 在 拉姆达表达式 where 表达式中使用 w => w.In(w.t1.Member_ID, guidsArray) + /// + /// + /// + /// + /// + public bool In(T field, params T2[] array) => true; + + /// + /// 子查询 只能在 Where 中使用 + /// + /// + /// + /// + /// + public bool In(T field, T2 iCurdBase) where T2 : ISqlContext => true; + + /// + /// 在 拉姆达表达式 where 表达式中使用 w => w.NotIn(w.t1.Member_ID, guidsArray) + /// + /// + /// + /// + /// + public bool NotIn(T field, params T2[] array) => true; + + /// + /// 子查询 只能在 Where 中使用 + /// + /// + /// + /// + /// + public bool NotIn(T field, T2 iCurdBase) where T2 : ISqlContext => true; + + /// + /// like %123% 只能在 Where 中使用 + /// + /// + /// + /// + public bool Like(T field, T2 value) => true; + + /// + /// like 123% 只能在 Where 中使用 + /// + /// + /// + /// + public bool LikeStart(T field, T2 value) => true; + + /// + /// like %123 只能在 Where 中使用 + /// + /// + /// + /// + public bool LikeEnd(T field, T2 value) => true; + + /// + /// 一般在Where 条件中使用 例如 : w.HzySql("convert(varchar(50),UserName,23) > convert(varchar(50),GetDate(),23)") + /// 一般用来支持这种语法》CONVERT(varchar(100), GETDATE(), 23) -- 2006-05-16 + /// + /// + /// + /// + /// + public bool HzySql(string value) => true; + + /// + /// 一般在Where 条件中使用 例如 : w.HzySql("convert(varchar(50),UserName,23)") > DateTime.Now.ToString("yyyy-MM-dd") + /// 一般用来支持这种语法》CONVERT(varchar(100), GETDATE(), 23) -- 2006-05-16 + /// + /// + /// + /// + /// + public TR HzySql(string value) => default(TR); + } + + public class HzyTuple : HzyTuple + { + public HzyTuple(T t) + { + this.t1 = t; + } + + public T t1 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2) + { + this.t1 = t1; this.t2 = t2; + } + + public T1 t1 { get; } + public T2 t2 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; this.t9 = t9; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + public T9 t9 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; this.t9 = t9; this.t10 = t10; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + public T9 t9 { get; } + public T10 t10 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; this.t9 = t9; this.t10 = t10; this.t11 = t11; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + public T9 t9 { get; } + public T10 t10 { get; } + public T11 t11 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; this.t9 = t9; this.t10 = t10; this.t11 = t11; this.t12 = t12; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + public T9 t9 { get; } + public T10 t10 { get; } + public T11 t11 { get; } + public T12 t12 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; this.t9 = t9; this.t10 = t10; this.t11 = t11; this.t12 = t12; this.t13 = t13; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + public T9 t9 { get; } + public T10 t10 { get; } + public T11 t11 { get; } + public T12 t12 { get; } + public T13 t13 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; this.t9 = t9; this.t10 = t10; this.t11 = t11; this.t12 = t12; this.t13 = t13; this.t14 = t14; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + public T9 t9 { get; } + public T10 t10 { get; } + public T11 t11 { get; } + public T12 t12 { get; } + public T13 t13 { get; } + public T14 t14 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; this.t9 = t9; this.t10 = t10; this.t11 = t11; this.t12 = t12; this.t13 = t13; this.t14 = t14; this.t15 = t15; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + public T9 t9 { get; } + public T10 t10 { get; } + public T11 t11 { get; } + public T12 t12 { get; } + public T13 t13 { get; } + public T14 t14 { get; } + public T15 t15 { get; } + } + + + public class HzyTuple : HzyTuple + { + public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16) + { + this.t1 = t1; this.t2 = t2; this.t3 = t3; this.t4 = t4; this.t5 = t5; this.t6 = t6; this.t7 = t7; this.t8 = t8; this.t9 = t9; this.t10 = t10; this.t11 = t11; this.t12 = t12; this.t13 = t13; this.t14 = t14; this.t15 = t15; this.t16 = t16; + } + + public T1 t1 { get; } + public T2 t2 { get; } + public T3 t3 { get; } + public T4 t4 { get; } + public T5 t5 { get; } + public T6 t6 { get; } + public T7 t7 { get; } + public T8 t8 { get; } + public T9 t9 { get; } + public T10 t10 { get; } + public T11 t11 { get; } + public T12 t12 { get; } + public T13 t13 { get; } + public T14 t14 { get; } + public T15 t15 { get; } + public T16 t16 { get; } + } +} From f3aa07abb684c006c31f7995024f834501503c9f Mon Sep 17 00:00:00 2001 From: hzy <1396510655@qq.com> Date: Tue, 3 Nov 2020 23:05:11 +0800 Subject: [PATCH 0972/1029] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E5=A4=9A=E8=A1=A8=E6=9F=A5=E8=AF=A2=E8=AF=AD=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E7=AE=80=E5=8C=96=20=E5=AE=9A=E4=B9=89=20=E4=B8=80=E5=A0=86=20?= =?UTF-8?q?abcd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests.Provider.Odbc/UnitTest1.cs | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 50 ++++ FreeSql/Interface/Curd/ISelect/ISelect10.cs | 55 +++- FreeSql/Interface/Curd/ISelect/ISelect11.cs | 55 +++- FreeSql/Interface/Curd/ISelect/ISelect12.cs | 55 +++- FreeSql/Interface/Curd/ISelect/ISelect13.cs | 56 +++- FreeSql/Interface/Curd/ISelect/ISelect14.cs | 55 +++- FreeSql/Interface/Curd/ISelect/ISelect15.cs | 55 +++- FreeSql/Interface/Curd/ISelect/ISelect16.cs | 54 +++- FreeSql/Interface/Curd/ISelect/ISelect2.cs | 58 +++- FreeSql/Interface/Curd/ISelect/ISelect3.cs | 55 ++++ FreeSql/Interface/Curd/ISelect/ISelect4.cs | 54 ++++ FreeSql/Interface/Curd/ISelect/ISelect5.cs | 56 ++++ FreeSql/Interface/Curd/ISelect/ISelect6.cs | 53 ++++ FreeSql/Interface/Curd/ISelect/ISelect7.cs | 54 ++++ FreeSql/Interface/Curd/ISelect/ISelect8.cs | 54 ++++ FreeSql/Interface/Curd/ISelect/ISelect9.cs | 53 ++++ FreeSql/Internal/CommonExpression.cs | 8 +- .../SelectProvider/Select10Provider.cs | 244 +++++++++++++--- .../SelectProvider/Select11Provider.cs | 248 +++++++++++++--- .../SelectProvider/Select12Provider.cs | 253 ++++++++++++++--- .../SelectProvider/Select13Provider.cs | 255 ++++++++++++++--- .../SelectProvider/Select14Provider.cs | 259 ++++++++++++++--- .../SelectProvider/Select15Provider.cs | 264 +++++++++++++---- .../SelectProvider/Select16Provider.cs | 267 ++++++++++++++---- .../SelectProvider/Select2Provider.cs | 216 +++++++++++++- .../SelectProvider/Select3Provider.cs | 212 +++++++++++++- .../SelectProvider/Select4Provider.cs | 215 +++++++++++++- .../SelectProvider/Select5Provider.cs | 219 +++++++++++++- .../SelectProvider/Select6Provider.cs | 221 +++++++++++++-- .../SelectProvider/Select7Provider.cs | 232 +++++++++++++-- .../SelectProvider/Select8Provider.cs | 231 +++++++++++++-- .../SelectProvider/Select9Provider.cs | 239 ++++++++++++++-- FreeSql/Internal/Model/HzyTuple.cs | 119 ++------ 34 files changed, 4022 insertions(+), 554 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/UnitTest4.cs diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs index b415c3d0..34f896e3 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/UnitTest1.cs @@ -380,7 +380,7 @@ WHERE ROWNUM < 11"; var xxxhzytuple = g.sqlserver.Select() - .Where(a => a.Item1.Code == "xxx" && a.Item2.OptionsEntity03 == true) + .Where(a => a.t1.Code == "xxx" && a.t2.OptionsEntity03 == true) .ToSql(); diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs new file mode 100644 index 00000000..a7fcec8f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; +using static FreeSql.Tests.UnitTest1; + +namespace FreeSql.Tests +{ + public class UnitTest4 + { + static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;") + //.UseConnectionFactory(FreeSql.DataType.Sqlite, () => + //{ + // var conn = new System.Data.SQLite.SQLiteConnection(@"Data Source=|DataDirectory|\document.db;Pooling=true;"); + // //conn.Open(); + // //var cmd = conn.CreateCommand(); + // //cmd.CommandText = $"attach database [xxxtb.db] as [xxxtb];\r\n"; + // //cmd.ExecuteNonQuery(); + // //cmd.Dispose(); + // return conn; + //}) + .UseAutoSyncStructure(true) + //.UseGenerateCommandParameterWithLambda(true) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 + //, (cmd, traceLog) => Console.WriteLine(traceLog) + ) + .Build()); + public static IFreeSql sqlite => sqliteLazy.Value; + + + [Fact] + public void TestHzyTuple() + { + var xxxhzytuple = g.sqlite.Select() + .LeftJoin(w => w.t1.Id2 == w.t2.TemplatesId) + .Where(w => w.t1.Code == "xxx" && w.t2.OptionsEntity03 == true) + .OrderBy(w => w.t1.AddTime) + .ToSql(); + + } + + + + } +} diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 24a0a9a9..0b1bb45f 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> 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 { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -59,8 +78,42 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect11.cs b/FreeSql/Interface/Curd/ISelect/ISelect11.cs index 1e3aa5fd..c5d6a83c 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect11.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect11.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> 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 { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -59,8 +78,42 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect12.cs b/FreeSql/Interface/Curd/ISelect/ISelect12.cs index 54762344..c4edcfd2 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect12.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect12.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> 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 { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -59,8 +78,42 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect13.cs b/FreeSql/Interface/Curd/ISelect/ISelect13.cs index 177fc863..0f3c7d7f 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect13.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect13.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> 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 { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -59,8 +78,43 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect14.cs b/FreeSql/Interface/Curd/ISelect/ISelect14.cs index d9eaaca2..811dc203 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect14.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect14.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> 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 { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -59,8 +78,42 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect15.cs b/FreeSql/Interface/Curd/ISelect/ISelect15.cs index 7e359c40..c6fad4f6 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect15.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect15.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> 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 { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -59,8 +78,42 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect16.cs b/FreeSql/Interface/Curd/ISelect/ISelect16.cs index feb4849f..53cb1950 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect16.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect16.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> 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 { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -59,8 +78,41 @@ namespace FreeSql ISelect OrderBy(Expression> column); ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression < Func> column, bool descending = false); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 1b57b273..7949ff3b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> where T2 : class { @@ -27,12 +28,30 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); int InsertInto(string tableName, Expression> select) where TTargetEntity : class; DataTable ToDataTable(Expression> select); - List ToList(Expression> select); + List ToList(Expression> select); List ToList(); void ToChunk(Expression> select, int size, Action>> done); @@ -54,7 +73,6 @@ namespace FreeSql ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect Where(Expression, bool>> exp); ISelectGrouping> GroupBy(Expression> exp); @@ -63,5 +81,41 @@ namespace FreeSql ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + + + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index 7502091b..fe33ff88 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; namespace FreeSql { + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class { @@ -27,6 +29,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -62,5 +82,40 @@ namespace FreeSql ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index fc17cb64..b28ab64b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; namespace FreeSql { + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class { @@ -27,6 +29,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -62,5 +82,39 @@ namespace FreeSql ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index 694b3505..bab8b26f 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; namespace FreeSql { + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class { @@ -27,6 +29,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -62,5 +82,41 @@ namespace FreeSql ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + + + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index ed696e72..c70e04e4 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -62,5 +81,39 @@ namespace FreeSql ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index e27c5859..b38ab3b4 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -62,5 +81,40 @@ namespace FreeSql ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 83d123c7..febb1120 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -62,5 +81,40 @@ namespace FreeSql ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + + } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index b4c20825..ee41d171 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; namespace FreeSql { + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { @@ -27,6 +28,24 @@ namespace FreeSql Task MinAsync(Expression> column); Task MaxAsync(Expression> column); Task AvgAsync(Expression> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #endregion + #endif bool Any(Expression> exp); @@ -62,5 +81,39 @@ namespace FreeSql ISelect OrderByIf(bool condition, Expression> column, bool descending = false); ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + } + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index ca0880af..0eb05c0a 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1689,14 +1689,14 @@ namespace FreeSql.Internal { var parent = node.Expression as MemberExpression; if (parent.Expression?.NodeType == ExpressionType.Parameter && - parent.Expression.Type.Name.StartsWith("NativeTuple`") == true && - int.TryParse(parent.Member.Name.Replace("Item", ""), out widx) && widx > 0 && widx <= tables.Count) + parent.Expression.Type.Name.StartsWith("HzyTuple`") == true && + int.TryParse(parent.Member.Name.Replace("t", ""), out widx) && widx > 0 && widx <= tables.Count) return Expression.Property(parameters[widx - 1], node.Member.Name); } if (node.Expression?.NodeType == ExpressionType.Parameter && - node.Expression.Type.Name.StartsWith("NativeTuple`") == true && - int.TryParse(node.Member.Name.Replace("Item", ""), out widx) && widx > 0 && widx <= tables.Count) + node.Expression.Type.Name.StartsWith("HzyTuple`") == true && + int.TryParse(node.Member.Name.Replace("t", ""), out widx) && widx > 0 && widx <= tables.Count) return parameters[widx - 1]; return base.VisitMember(node); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index cb17d03d..dbd36784 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -10,15 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select10Provider : Select0Provider, T1>, ISelect - 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 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 { public Select10Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -33,31 +25,32 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; - if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};", parms)); return this; } double ISelect.Avg(Expression> column) { - if (column == null) return 0; + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -129,22 +122,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i"), - Expression.Parameter(typeof(T10), "j")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -203,9 +189,9 @@ namespace FreeSql.Internal.CommonProvider ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); + if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -222,6 +208,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -295,6 +410,69 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs index 3613cf42..59a549dd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs @@ -10,16 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select11Provider : Select0Provider, T1>, ISelect - 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 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 { public Select11Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -35,32 +26,33 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; - if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; - if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};", parms)); return this; } double ISelect.Avg(Expression> column) { - if (column == null) return 0; + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -132,23 +124,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i"), - Expression.Parameter(typeof(T10), "j"), - Expression.Parameter(typeof(T11), "k")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -207,9 +191,9 @@ namespace FreeSql.Internal.CommonProvider ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); + if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -226,6 +210,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -299,6 +412,69 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs index 98077570..c9e0e016 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs @@ -9,18 +9,9 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { + public abstract class Select12Provider : Select0Provider, T1>, ISelect - 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 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 { public Select12Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -37,33 +28,34 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; - if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; - if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; - if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};", parms)); return this; } double ISelect.Avg(Expression> column) { - if (column == null) return 0; + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -135,24 +127,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i"), - Expression.Parameter(typeof(T10), "j"), - Expression.Parameter(typeof(T11), "k"), - Expression.Parameter(typeof(T12), "l")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -211,9 +194,9 @@ namespace FreeSql.Internal.CommonProvider ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); + if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -230,6 +213,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -303,6 +415,69 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs index 88c63d3f..2d3d691e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs @@ -10,18 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select13Provider : Select0Provider, T1>, ISelect - 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 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 { public Select13Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -39,34 +28,35 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; - if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; - if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; - if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; - if (type == _tables[12].Table?.Type) return $"( {sqlT13} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};", parms)); return this; } double ISelect.Avg(Expression> column) { - if (column == null) return 0; + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -138,25 +128,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i"), - Expression.Parameter(typeof(T10), "j"), - Expression.Parameter(typeof(T11), "k"), - Expression.Parameter(typeof(T12), "l"), - Expression.Parameter(typeof(T13), "m")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -215,9 +195,9 @@ namespace FreeSql.Internal.CommonProvider ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); + if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -234,6 +214,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -307,6 +416,68 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs index c027caf6..6df2c42e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs @@ -10,19 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select14Provider : Select0Provider, T1>, ISelect - 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 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 { public Select14Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -41,35 +29,36 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; - if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; - if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; - if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; - if (type == _tables[12].Table?.Type) return $"( {sqlT13} )"; - if (type == _tables[13].Table?.Type) return $"( {sqlT14} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; + if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};", parms)); return this; } double ISelect.Avg(Expression> column) { - if (column == null) return 0; + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -141,26 +130,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i"), - Expression.Parameter(typeof(T10), "j"), - Expression.Parameter(typeof(T11), "k"), - Expression.Parameter(typeof(T12), "l"), - Expression.Parameter(typeof(T13), "m"), - Expression.Parameter(typeof(T14), "n")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -219,9 +197,9 @@ namespace FreeSql.Internal.CommonProvider ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); + if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -238,6 +216,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -311,6 +418,68 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs index 61ee7e0b..f4bb94fe 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs @@ -10,20 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select15Provider : Select0Provider, T1>, ISelect - 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 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 { public Select15Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -43,36 +30,37 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T15)), Alias = $"SP10o", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; - if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; - if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; - if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; - if (type == _tables[12].Table?.Type) return $"( {sqlT13} )"; - if (type == _tables[13].Table?.Type) return $"( {sqlT14} )"; - if (type == _tables[14].Table?.Type) return $"( {sqlT15} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; + if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; + if (type == _tables[14].Table?.Type && string.IsNullOrEmpty(sqlT15) == false) return $"({sqlT15})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};", parms)); return this; } double ISelect.Avg(Expression> column) { - if (column == null) return 0; + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -144,27 +132,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i"), - Expression.Parameter(typeof(T10), "j"), - Expression.Parameter(typeof(T11), "k"), - Expression.Parameter(typeof(T12), "l"), - Expression.Parameter(typeof(T13), "m"), - Expression.Parameter(typeof(T14), "n"), - Expression.Parameter(typeof(T15), "o")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n"), Expression.Parameter(typeof(T15), "o")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -223,9 +199,9 @@ namespace FreeSql.Internal.CommonProvider ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); + if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -242,6 +218,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -315,6 +420,69 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs index f439e26d..438470e7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs @@ -10,21 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select16Provider : Select0Provider, T1>, ISelect - 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 + 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 { public Select16Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -45,37 +31,38 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T15)), Alias = $"SP10o", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T16)), Alias = $"SP10p", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; - if (type == _tables[9].Table?.Type) return $"( {sqlT10} )"; - if (type == _tables[10].Table?.Type) return $"( {sqlT11} )"; - if (type == _tables[11].Table?.Type) return $"( {sqlT12} )"; - if (type == _tables[12].Table?.Type) return $"( {sqlT13} )"; - if (type == _tables[13].Table?.Type) return $"( {sqlT14} )"; - if (type == _tables[14].Table?.Type) return $"( {sqlT15} )"; - if (type == _tables[15].Table?.Type) return $"( {sqlT16} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; + if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; + if (type == _tables[14].Table?.Type && string.IsNullOrEmpty(sqlT15) == false) return $"({sqlT15})"; + if (type == _tables[15].Table?.Type && string.IsNullOrEmpty(sqlT16) == false) return $"({sqlT16})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};\r\n{sqlT16}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};\r\n{sqlT16};", parms)); return this; } double ISelect.Avg(Expression> column) { - if (column == null) return 0; + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -147,28 +134,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i"), - Expression.Parameter(typeof(T10), "j"), - Expression.Parameter(typeof(T11), "k"), - Expression.Parameter(typeof(T12), "l"), - Expression.Parameter(typeof(T13), "m"), - Expression.Parameter(typeof(T14), "n"), - Expression.Parameter(typeof(T15), "o"), - Expression.Parameter(typeof(T16), "p")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n"), Expression.Parameter(typeof(T15), "o"), Expression.Parameter(typeof(T16), "p")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -227,9 +201,9 @@ namespace FreeSql.Internal.CommonProvider ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); + if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -246,6 +220,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -319,6 +422,68 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 3c65f7b7..6441c35e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -9,6 +9,8 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { + + public abstract class Select2Provider : Select0Provider, T1>, ISelect where T2 : class { @@ -17,17 +19,18 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2)); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};", parms)); return this; } @@ -111,8 +114,7 @@ namespace FreeSql.Internal.CommonProvider { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b")); } public void ToChunk(Expression> select, int size, Action>> done) @@ -178,14 +180,6 @@ namespace FreeSql.Internal.CommonProvider return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } - ISelect ISelect.Where(Expression, bool>> exp) - { - if (exp == null) return this.Where(null); - var exp2 = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - for (var a = 0; a < exp2.Parameters.Count; a++) _tables[a].Parameter = exp2.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp2, null, _whereGlobalFilter, _params)); - } - bool ISelect.Any(Expression> exp) { if (exp == null) return this.Any(); @@ -200,6 +194,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -273,6 +396,73 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + + + + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 5d214f83..b6ee8e7b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -9,9 +9,10 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { + + public abstract class Select3Provider : Select0Provider, T1>, ISelect - where T2 : class - where T3 : class + where T2 : class where T3 : class { public Select3Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -19,18 +20,19 @@ namespace FreeSql.Internal.CommonProvider if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3)); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};", parms)); return this; } @@ -108,15 +110,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -194,6 +196,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -267,6 +398,69 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index b2d451fb..044622e0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -9,10 +9,9 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { + public abstract class Select4Provider : Select0Provider, T1>, ISelect - where T2 : class - where T3 : class - where T4 : class + where T2 : class where T3 : class where T4 : class { public Select4Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -21,19 +20,20 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};", parms)); return this; } @@ -111,16 +111,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -198,6 +197,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -271,6 +399,69 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 0e29039c..1a15b9c1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -10,10 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select5Provider : Select0Provider, T1>, ISelect - where T2 : class - where T3 : class - where T4 : class - where T5 : class + where T2 : class where T3 : class where T4 : class where T5 : class { public Select5Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -23,20 +20,21 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};", parms)); return this; } @@ -114,17 +112,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -202,6 +198,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -275,6 +400,70 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index bbeb94ac..fc16cb9c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -10,11 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select6Provider : Select0Provider, T1>, ISelect - where T2 : class - where T3 : class - where T4 : class - where T5 : class - where T6 : class + where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public Select6Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -25,21 +21,22 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"( {sqlT6} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};", parms)); return this; } @@ -117,18 +114,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -206,6 +200,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -279,6 +402,68 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 3927f2af..9a134de8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -10,12 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select7Provider : Select0Provider, T1>, ISelect - where T2 : class - where T3 : class - where T4 : class - where T5 : class - where T6 : class - where T7 : class + where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public Select7Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -27,22 +22,23 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"( {sqlT7} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};", parms)); return this; } @@ -120,19 +116,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -210,6 +202,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -246,7 +367,7 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToAggregateAsync(select?.Body); } - + Task> ISelect.ToListAsync(Expression> select) { if (select == null) return this.InternalToListAsync(select?.Body); @@ -254,7 +375,7 @@ namespace FreeSql.Internal.CommonProvider return this.InternalToListAsync(select?.Body); } Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - + Task ISelect.ToDataTableAsync(Expression> select) { if (select == null) return this.InternalToDataTableAsync(select?.Body); @@ -283,6 +404,71 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 2ec77898..98b3b85a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -9,14 +9,9 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { + public abstract class Select8Provider : Select0Provider, T1>, ISelect - where T2 : class - where T3 : class - where T4 : class - where T5 : class - where T6 : class - where T7 : class - where T8 : class + where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public Select8Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -29,23 +24,24 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"( {sqlT8} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};", parms)); return this; } @@ -123,20 +119,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -214,6 +205,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -287,6 +407,69 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 93c5f395..da95085d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -10,14 +10,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract class Select9Provider : Select0Provider, T1>, ISelect - 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 T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public Select9Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) @@ -31,30 +24,31 @@ namespace FreeSql.Internal.CommonProvider _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + } ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms) { this.AsTable((type, old) => { - if (type == _tables[0].Table?.Type) return $"( {sqlT1} )"; - if (type == _tables[1].Table?.Type) return $"( {sqlT2} )"; - if (type == _tables[2].Table?.Type) return $"( {sqlT3} )"; - if (type == _tables[3].Table?.Type) return $"( {sqlT4} )"; - if (type == _tables[4].Table?.Type) return $"( {sqlT5} )"; - if (type == _tables[5].Table?.Type) return $"( {sqlT6} )"; - if (type == _tables[6].Table?.Type) return $"( {sqlT7} )"; - if (type == _tables[7].Table?.Type) return $"( {sqlT8} )"; - if (type == _tables[8].Table?.Type) return $"( {sqlT9} )"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9}", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};", parms)); return this; } double ISelect.Avg(Expression> column) { - if (column == null) return 0; + if (column == null) return default(double); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; return this.InternalAvg(column?.Body); } @@ -126,21 +120,15 @@ namespace FreeSql.Internal.CommonProvider for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; return this.InternalToList(select?.Body); } + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { return Expression.Lambda>( typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), - Expression.Parameter(typeof(T2), "b"), - Expression.Parameter(typeof(T3), "c"), - Expression.Parameter(typeof(T4), "d"), - Expression.Parameter(typeof(T5), "e"), - Expression.Parameter(typeof(T6), "f"), - Expression.Parameter(typeof(T7), "g"), - Expression.Parameter(typeof(T8), "h"), - Expression.Parameter(typeof(T9), "i")); + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i")); } + public void ToChunk(Expression> select, int size, Action>> done) { if (select == null || done == null) return; @@ -199,9 +187,9 @@ namespace FreeSql.Internal.CommonProvider ISelect ISelect.WhereIf(bool condition, Expression> exp) { - if (condition == false || exp == null) return this.Where(null); + if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)) : this; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -218,6 +206,135 @@ namespace FreeSql.Internal.CommonProvider TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + #if net40 #else Task ISelect.AvgAsync(Expression> column) @@ -291,6 +408,68 @@ namespace FreeSql.Internal.CommonProvider async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify); + } + + Task ISelect.MaxAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify); + } + + Task ISelect.MinAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify); + } + + Task ISelect.SumAsync(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select) + => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + #endif } + } \ No newline at end of file diff --git a/FreeSql/Internal/Model/HzyTuple.cs b/FreeSql/Internal/Model/HzyTuple.cs index f7afb40d..ed3da6fc 100644 --- a/FreeSql/Internal/Model/HzyTuple.cs +++ b/FreeSql/Internal/Model/HzyTuple.cs @@ -1,91 +1,6 @@ -namespace HzySql.Models +namespace FreeSql.Internal.Model { - using HzySql.Interface; - - public class HzyTuple - { - /// - /// 在 拉姆达表达式 where 表达式中使用 w => w.In(w.t1.Member_ID, guidsArray) - /// - /// - /// - /// - /// - public bool In(T field, params T2[] array) => true; - - /// - /// 子查询 只能在 Where 中使用 - /// - /// - /// - /// - /// - public bool In(T field, T2 iCurdBase) where T2 : ISqlContext => true; - - /// - /// 在 拉姆达表达式 where 表达式中使用 w => w.NotIn(w.t1.Member_ID, guidsArray) - /// - /// - /// - /// - /// - public bool NotIn(T field, params T2[] array) => true; - - /// - /// 子查询 只能在 Where 中使用 - /// - /// - /// - /// - /// - public bool NotIn(T field, T2 iCurdBase) where T2 : ISqlContext => true; - - /// - /// like %123% 只能在 Where 中使用 - /// - /// - /// - /// - public bool Like(T field, T2 value) => true; - - /// - /// like 123% 只能在 Where 中使用 - /// - /// - /// - /// - public bool LikeStart(T field, T2 value) => true; - - /// - /// like %123 只能在 Where 中使用 - /// - /// - /// - /// - public bool LikeEnd(T field, T2 value) => true; - - /// - /// 一般在Where 条件中使用 例如 : w.HzySql("convert(varchar(50),UserName,23) > convert(varchar(50),GetDate(),23)") - /// 一般用来支持这种语法》CONVERT(varchar(100), GETDATE(), 23) -- 2006-05-16 - /// - /// - /// - /// - /// - public bool HzySql(string value) => true; - - /// - /// 一般在Where 条件中使用 例如 : w.HzySql("convert(varchar(50),UserName,23)") > DateTime.Now.ToString("yyyy-MM-dd") - /// 一般用来支持这种语法》CONVERT(varchar(100), GETDATE(), 23) -- 2006-05-16 - /// - /// - /// - /// - /// - public TR HzySql(string value) => default(TR); - } - - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T t) { @@ -96,7 +11,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2) { @@ -108,7 +23,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3) { @@ -121,7 +36,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4) { @@ -135,7 +50,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { @@ -150,7 +65,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { @@ -166,7 +81,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) { @@ -183,7 +98,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) { @@ -201,7 +116,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) { @@ -220,7 +135,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10) { @@ -240,7 +155,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11) { @@ -261,7 +176,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12) { @@ -283,7 +198,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13) { @@ -306,7 +221,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14) { @@ -330,7 +245,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15) { @@ -355,7 +270,7 @@ } - public class HzyTuple : HzyTuple + public class HzyTuple { public HzyTuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16) { From 579df2e0c4fd93398576ea54a68259d3c1806418 Mon Sep 17 00:00:00 2001 From: hzy <1396510655@qq.com> Date: Wed, 4 Nov 2020 00:11:46 +0800 Subject: [PATCH 0973/1029] =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=85=83=E7=A5=96?= =?UTF-8?q?=20=E5=AE=9E=E7=8E=B0=E6=96=B0=E5=A4=9A=E8=A1=A8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=20=E8=AF=AD=E6=B3=95=20=E5=AF=BC=E8=87=B4=E6=97=A7?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BC=BA=E5=A4=B1=E9=97=AE=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20=E6=B7=BB=E5=8A=A0selectprovider=20=E7=9A=84T4?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.csproj | 4 + .../SelectProvider/Select10Provider.cs | 39 +- .../SelectProvider/Select11Provider.cs | 38 +- .../SelectProvider/Select12Provider.cs | 38 +- .../SelectProvider/Select13Provider.cs | 37 +- .../SelectProvider/Select14Provider.cs | 37 +- .../SelectProvider/Select15Provider.cs | 37 +- .../SelectProvider/Select16Provider.cs | 37 +- .../SelectProvider/Select2Provider.cs | 44 +- .../SelectProvider/Select3Provider.cs | 40 +- .../SelectProvider/Select4Provider.cs | 39 +- .../SelectProvider/Select5Provider.cs | 39 +- .../SelectProvider/Select6Provider.cs | 38 +- .../SelectProvider/Select7Provider.cs | 39 +- .../SelectProvider/Select8Provider.cs | 39 +- .../SelectProvider/Select9Provider.cs | 37 +- .../SelectProvider/T4Temp/ISelect.tt | 161 ++++++ .../SelectProvider/T4Temp/SelectProvider.tt | 524 ++++++++++++++++++ 18 files changed, 979 insertions(+), 288 deletions(-) create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect.tt create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/SelectProvider.tt diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 401f7500..70dcaf2e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -24,6 +24,10 @@ + + + + FreeSql.xml diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index dbd36784..b6f190b8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -32,6 +32,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -44,7 +45,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10}", parms)); return this; } @@ -235,61 +236,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -418,43 +419,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) @@ -475,4 +476,6 @@ namespace FreeSql.Internal.CommonProvider } + + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs index 59a549dd..5f58506a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs @@ -33,6 +33,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -46,7 +47,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11}", parms)); return this; } @@ -237,61 +238,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -420,43 +421,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) @@ -476,5 +477,4 @@ namespace FreeSql.Internal.CommonProvider #endif } - } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs index c9e0e016..282edd57 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs @@ -9,7 +9,6 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract class Select12Provider : Select0Provider, T1>, ISelect 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 { @@ -35,6 +34,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -49,7 +49,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12}", parms)); return this; } @@ -240,61 +240,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -423,43 +423,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs index 2d3d691e..e89ef83d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs @@ -35,6 +35,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -50,7 +51,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13}", parms)); return this; } @@ -241,61 +242,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -424,43 +425,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs index 6df2c42e..2397fc47 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs @@ -36,6 +36,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -52,7 +53,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14}", parms)); return this; } @@ -243,61 +244,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -426,43 +427,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs index f4bb94fe..c6c878ef 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs @@ -37,6 +37,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -54,7 +55,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15}", parms)); return this; } @@ -245,61 +246,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -428,43 +429,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs index 438470e7..e2fcaa72 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs @@ -38,6 +38,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -56,7 +57,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};\r\n{sqlT16};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};\r\n{sqlT16}", parms)); return this; } @@ -247,61 +248,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -430,43 +431,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 6441c35e..1e550e25 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -8,9 +8,6 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - - - public abstract class Select2Provider : Select0Provider, T1>, ISelect where T2 : class { @@ -26,11 +23,12 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2}", parms)); return this; } @@ -221,61 +219,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -404,43 +402,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) @@ -461,8 +459,4 @@ namespace FreeSql.Internal.CommonProvider } - - - - } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index b6ee8e7b..8d7f5b40 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -8,9 +8,6 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - - - public abstract class Select3Provider : Select0Provider, T1>, ISelect where T2 : class where T3 : class { @@ -27,12 +24,13 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3}", parms)); return this; } @@ -223,61 +221,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -406,43 +404,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index 044622e0..5890fa7f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -9,7 +9,6 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract class Select4Provider : Select0Provider, T1>, ISelect where T2 : class where T3 : class where T4 : class { @@ -27,13 +26,14 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4}", parms)); return this; } @@ -224,61 +224,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -407,43 +407,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) @@ -464,4 +464,5 @@ namespace FreeSql.Internal.CommonProvider } + } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index 1a15b9c1..7ce48dac 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract class Select5Provider : Select0Provider, T1>, ISelect where T2 : class where T3 : class where T4 : class where T5 : class { @@ -27,6 +26,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -34,7 +34,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5}", parms)); return this; } @@ -225,61 +225,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -408,43 +408,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) @@ -465,5 +465,4 @@ namespace FreeSql.Internal.CommonProvider } - } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index fc16cb9c..7c39a101 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - public abstract class Select6Provider : Select0Provider, T1>, ISelect where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { @@ -28,6 +27,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -36,7 +36,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6}", parms)); return this; } @@ -227,61 +227,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -410,43 +410,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 9a134de8..117039f2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -9,6 +9,8 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { + + public abstract class Select7Provider : Select0Provider, T1>, ISelect where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { @@ -29,6 +31,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -38,7 +41,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7}", parms)); return this; } @@ -229,61 +232,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -412,43 +415,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index 98b3b85a..10f6a5a6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -8,8 +8,6 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - - public abstract class Select8Provider : Select0Provider, T1>, ISelect where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { @@ -31,6 +29,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -41,7 +40,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8}", parms)); return this; } @@ -232,61 +231,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -415,43 +414,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index da95085d..186d3d17 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -31,6 +31,7 @@ namespace FreeSql.Internal.CommonProvider { this.AsTable((type, old) => { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; @@ -42,7 +43,7 @@ namespace FreeSql.Internal.CommonProvider return old; }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};", parms)); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9}", parms)); return this; } @@ -233,61 +234,61 @@ namespace FreeSql.Internal.CommonProvider TMember ISelect.Min(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); + return (this as ISelect).Min((Expression>)expModify); } ISelect ISelect.OrderBy(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); + return (this as ISelect).OrderBy((Expression>)expModify); } ISelect ISelect.OrderByDescending(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); + return (this as ISelect).OrderByDescending((Expression>)expModify); } ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); } decimal ISelect.Sum(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); + return (this as ISelect).Sum((Expression>)expModify); } List ISelect.ToList(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); + return (this as ISelect).ToList((Expression>)expModify); } public void ToChunk(Expression, TReturn>> select, int size, Action>> done) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); + (this as ISelect).ToChunk((Expression>)expModify, size, done); } DataTable ISelect.ToDataTable(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); + return (this as ISelect).ToDataTable((Expression>)expModify); } int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); } string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); } ISelect ISelect.LeftJoin(Expression, bool>> exp) @@ -416,43 +417,43 @@ namespace FreeSql.Internal.CommonProvider Task ISelect.AvgAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); + return (this as ISelect).AvgAsync((Expression>)expModify); } Task ISelect.MaxAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); + return (this as ISelect).MaxAsync((Expression>)expModify); } Task ISelect.MinAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); + return (this as ISelect).MinAsync((Expression>)expModify); } Task ISelect.SumAsync(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); + return (this as ISelect).SumAsync((Expression>)expModify); } Task> ISelect.ToListAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); + return (this as ISelect).ToListAsync((Expression>)expModify); } Task ISelect.ToDataTableAsync(Expression, TReturn>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); + return (this as ISelect).ToDataTableAsync((Expression>)expModify); } Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); } async Task ISelect.AnyAsync(Expression, bool>> exp) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect.tt b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect.tt new file mode 100644 index 00000000..ad346020 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect.tt @@ -0,0 +1,161 @@ +<#@ template language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> + +<# + if (1 == 2) + { +#> +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql +{ + + <# + var Str = ""; + var whereStr = ""; + var ISelectGroupingAggregate = new List(); + var WithSql=new List(); + for (int i = 1; i < 17; i++) + { + Str += "T" + i + ","; + var NewStr = Str.Substring(0, Str.Length - 1); +#> + + <# + if (i > 1) + { + whereStr += $"where T{i} : class "; + } #> + + <# + { + ISelectGroupingAggregate.Add($"ISelectGroupingAggregate"); + WithSql.Add($"string sqlT{i}"); + } #> + + <# + if (i == 1) continue; #> + +public interface ISelect<<#=NewStr #>> : ISelect0>, T1> <#=whereStr #> + { + +#if net40 +#else + Task AnyAsync(Expression, bool>> exp); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select); + Task> ToListAsync(Expression, TReturn>> select); + Task> ToListAsync(); + + Task ToOneAsync(Expression, TReturn>> select); + Task FirstAsync(Expression, TReturn>> select); + Task FirstAsync(); + + Task ToAggregateAsync(Expression, TReturn>> select); + Task SumAsync(Expression, TMember>> column); + Task MinAsync(Expression, TMember>> column); + Task MaxAsync(Expression, TMember>> column); + Task AvgAsync(Expression, TMember>> column); + + #region HzyTuple 元组 + + Task AnyAsync(Expression>, bool>> exp); + Task InsertIntoAsync(string tableName, Expression>, TTargetEntity>> select) where TTargetEntity : class; + Task ToDataTableAsync(Expression>, TReturn>> select); + Task> ToListAsync(Expression>, TReturn>> select); + + Task ToOneAsync(Expression>, TReturn>> select); + Task FirstAsync(Expression>, TReturn>> select); + + Task SumAsync(Expression>, TMember>> column); + Task MinAsync(Expression>, TMember>> column); + Task MaxAsync(Expression>, TMember>> column); + Task AvgAsync(Expression>, TMember>> column); + + #endregion + +#endif + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + List ToList(); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + TDto First(); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, TReturn>> select); + ISelect<<#=NewStr #>> Aggregate(Expression, TReturn>> select, out TReturn result); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect<<#=NewStr #>> LeftJoin(Expression, bool>> exp); + ISelect<<#=NewStr #>> InnerJoin(Expression, bool>> exp); + ISelect<<#=NewStr #>> RightJoin(Expression, bool>> exp); + + ISelect<<#=NewStr #>> Where(Expression, bool>> exp); + ISelect<<#=NewStr #>> WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping>> GroupBy(Expression, TKey>> exp); + + ISelect<<#=NewStr #>> OrderBy(Expression, TMember>> column); + ISelect<<#=NewStr #>> OrderByDescending(Expression, TMember>> column); + ISelect<<#=NewStr #>> OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + ISelect<<#=NewStr #>> WithSql(<#=string.Join(",",WithSql)#>, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression>, bool>> exp); + int InsertInto(string tableName, Expression>, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression>, TReturn>> select); + List ToList(Expression>, TReturn>> select); + void ToChunk(Expression>, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression>, TReturn>> select); + TReturn First(Expression>, TReturn>> select); + + string ToSql(Expression>, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression>, TMember>> column); + TMember Min(Expression>, TMember>> column); + TMember Max(Expression>, TMember>> column); + double Avg(Expression>, TMember>> column); + + ISelect<<#=NewStr #>> LeftJoin(Expression>, bool>> exp); + ISelect<<#=NewStr #>> InnerJoin(Expression>, bool>> exp); + ISelect<<#=NewStr #>> RightJoin(Expression>, bool>> exp); + + ISelect<<#=NewStr #>> Where(Expression>, bool>> exp); + ISelect<<#=NewStr #>> WhereIf(bool condition, Expression>, bool>> exp); + + ISelectGrouping>> GroupBy(Expression>, TKey>> exp); + + ISelect<<#=NewStr #>> OrderBy(Expression>, TMember>> column); + ISelect<<#=NewStr #>> OrderByDescending(Expression>, TMember>> column); + ISelect<<#=NewStr #>> OrderByIf(bool condition, Expression>, TMember>> column, bool descending = false); + + #endregion + + } + + <# + } #> +} + + +<# + } #> \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/SelectProvider.tt b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/SelectProvider.tt new file mode 100644 index 00000000..2c5314e9 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/SelectProvider.tt @@ -0,0 +1,524 @@ +<#@ template language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> + +<# + if (1 == 2) + { +#> +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + <# + var Str = ""; + var whereStr = ""; + var ISelectGroupingAggregate = new List(); + var WithSql = new List(); + + List SyncStructure = new List(); + StringBuilder _tables = new StringBuilder(); + StringBuilder AsTable = new StringBuilder(); + var GetDbParamtersByObject = new List(); + var GetToListDtoSelector = new List(); + string[] abc = new[] + { + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", + "w", + "x", "y", "z" + }; + for (int i = 1; i < 17; i++) + { + Str += "T" + i + ","; + var NewStr = Str.Substring(0, Str.Length - 1); +#> + + <# + if (i > 1) + { + whereStr += $"where T{i} : class "; + SyncStructure.Add($"typeof(T{i})"); + _tables.Append("_tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T" + i + + ")), Alias = $\"SP10" + abc[i - 1] + "\", On = null, Type = SelectTableInfoType.From });\r\n"); + + } #> + + <# + { + ISelectGroupingAggregate.Add($"ISelectGroupingAggregate"); + WithSql.Add($"string sqlT{i}"); + GetToListDtoSelector.Add("Expression.Parameter(typeof(T" + i + "), \"" + (abc[i - 1]) + "\")"); + + AsTable.Append("if (type == _tables[" + (i - 1) + "].Table?.Type && string.IsNullOrEmpty(sqlT" + i + + ") == false) return $\"({sqlT" + i + "})\";\r\n"); + GetDbParamtersByObject.Add("{sqlT" + i + "}"); + + } #> + + <# + if (i == 1) continue; #> + + public abstract class Select<#=i #>Provider<<#=NewStr #>> : Select0Provider>, T1>, ISelect<<#=NewStr #>> + <#=whereStr #> + { + + public Select<#=i #>Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(<#=string.Join(",", SyncStructure) #>); + <#=_tables.ToString() #> + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.WithSql(<#=string.Join(",", WithSql) #>, object parms) + { + this.AsTable((type, old) => + { + <#=AsTable.ToString() #> + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"<#=string.Join(";\\r\\n", GetDbParamtersByObject) #>", parms)); + return this; + } + + double ISelect<<#=NewStr #>>.Avg(Expression, TMember>> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping>> ISelect<<#=NewStr #>>.GroupBy(Expression, TKey>> exp) + { + if (exp == null) return this.InternalGroupBy>>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>>(exp?.Body); + } + + TMember ISelect<<#=NewStr #>>.Max(Expression, TMember>> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect<<#=NewStr #>>.Min(Expression, TMember>> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.OrderBy(Expression, TMember>> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.OrderByDescending(Expression, TMember>> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect<<#=NewStr #>>.Sum(Expression, TMember>> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect<<#=NewStr #>>.ToAggregate(Expression, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.Aggregate(Expression, TReturn>> select, out TReturn result) + { + result = (this as ISelect<<#=NewStr #>>).ToAggregate(select); + return this; + } + + List ISelect<<#=NewStr #>>.ToList(Expression, TReturn>> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect<<#=NewStr #>>.ToList() => (this as ISelect<<#=NewStr #>>).ToList(GetToListDtoSelector()); + Expression, TDto>> GetToListDtoSelector() + { + return Expression.Lambda, TDto>>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? <#=string.Join(",", GetToListDtoSelector) #>); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect<<#=NewStr #>>.ToDataTable(Expression, TReturn>> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect<<#=NewStr #>>.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect<<#=NewStr #>>.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.LeftJoin(Expression, bool>> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.InnerJoin(Expression, bool>> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.RightJoin(Expression, bool>> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.Where(Expression, bool>> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.WhereIf(bool condition, Expression, bool>> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect<<#=NewStr #>>.Any(Expression, bool>> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect<<#=NewStr #>>.ToOne(Expression, TReturn>> select) => (this as ISelect<<#=NewStr #>>).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect<<#=NewStr #>>.First(Expression, TReturn>> select) => (this as ISelect<<#=NewStr #>>).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect<<#=NewStr #>>.First() => (this as ISelect<<#=NewStr #>>).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect<<#=NewStr #>>.Avg(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).Avg((Expression, TMember>>)expModify); + } + + ISelectGrouping>> ISelect<<#=NewStr #>>.GroupBy(Expression>, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect<<#=NewStr #>>).GroupBy((Expression, TKey>>)expModify); + } + + TMember ISelect<<#=NewStr #>>.Max(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).Max((Expression, TMember>>)expModify); + } + + TMember ISelect<<#=NewStr #>>.Min(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).Min((Expression, TMember>>)expModify); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.OrderBy(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).OrderBy((Expression, TMember>>)expModify); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.OrderByDescending(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).OrderByDescending((Expression, TMember>>)expModify); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.OrderByIf(bool condition, Expression>, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).OrderByIf(condition,(Expression, TMember>>)expModify,descending); + } + + decimal ISelect<<#=NewStr #>>.Sum(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).Sum((Expression, TMember>>)expModify); + } + + List ISelect<<#=NewStr #>>.ToList(Expression>, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect<<#=NewStr #>>).ToList((Expression, TReturn>>)expModify); + } + + public void ToChunk(Expression>, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect<<#=NewStr #>>).ToChunk((Expression, TReturn>>)expModify,size,done); + } + + DataTable ISelect<<#=NewStr #>>.ToDataTable(Expression>, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect<<#=NewStr #>>).ToDataTable((Expression, TReturn>>)expModify); + } + + int ISelect<<#=NewStr #>>.InsertInto(string tableName, Expression>, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect<<#=NewStr #>>).InsertInto(tableName,(Expression, TTargetEntity>>)expModify); + } + + string ISelect<<#=NewStr #>>.ToSql(Expression>, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect<<#=NewStr #>>).ToSql((Expression, TReturn>>)expModify,fieldAlias); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.LeftJoin(Expression>, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect<<#=NewStr #>>).LeftJoin((Expression, bool>>)expModify); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.InnerJoin(Expression>, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect<<#=NewStr #>>).InnerJoin((Expression, bool>>)expModify); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.RightJoin(Expression>, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect<<#=NewStr #>>).RightJoin((Expression, bool>>)expModify); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.Where(Expression>, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect<<#=NewStr #>>).Where((Expression, bool>>)expModify); + } + + ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.WhereIf(bool condition, Expression>, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect<<#=NewStr #>>).WhereIf(condition,(Expression, bool>>)expModify); + } + + bool ISelect<<#=NewStr #>>.Any(Expression>, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect<<#=NewStr #>>).Any((Expression, bool>>)expModify); + } + + TReturn ISelect<<#=NewStr #>>.ToOne(Expression>, TReturn>> select) + => (this as ISelect<<#=NewStr #>>).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect<<#=NewStr #>>.First(Expression>, TReturn>> select) + => (this as ISelect<<#=NewStr #>>).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect<<#=NewStr #>>.AvgAsync(Expression, TMember>> column) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body); + } + + Task ISelect<<#=NewStr #>>.MaxAsync(Expression, TMember>> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body); + } + + Task ISelect<<#=NewStr #>>.MinAsync(Expression, TMember>> column) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body); + } + + Task ISelect<<#=NewStr #>>.SumAsync(Expression, TMember>> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body); + } + + Task ISelect<<#=NewStr #>>.ToAggregateAsync(Expression, TReturn>> select) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body); + } + + Task> ISelect<<#=NewStr #>>.ToListAsync(Expression, TReturn>> select) + { + if (select == null) return this.InternalToListAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body); + } + Task> ISelect<<#=NewStr #>>.ToListAsync() => (this as ISelect<<#=NewStr #>>).ToListAsync(GetToListDtoSelector()); + + Task ISelect<<#=NewStr #>>.ToDataTableAsync(Expression, TReturn>> select) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body); + } + + Task ISelect<<#=NewStr #>>.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body); + } + + async Task ISelect<<#=NewStr #>>.AnyAsync(Expression, bool>> exp) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect<<#=NewStr #>>.ToOneAsync(Expression, TReturn>> select) => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect<<#=NewStr #>>.FirstAsync(Expression, TReturn>> select) => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect<<#=NewStr #>>.FirstAsync() => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync()).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect<<#=NewStr #>>.AvgAsync(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).AvgAsync((Expression, TMember>>)expModify); + } + + Task ISelect<<#=NewStr #>>.MaxAsync(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).MaxAsync((Expression, TMember>>)expModify); + } + + Task ISelect<<#=NewStr #>>.MinAsync(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).MinAsync((Expression, TMember>>)expModify); + } + + Task ISelect<<#=NewStr #>>.SumAsync(Expression>, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect<<#=NewStr #>>).SumAsync((Expression, TMember>>)expModify); + } + + Task> ISelect<<#=NewStr #>>.ToListAsync(Expression>, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect<<#=NewStr #>>).ToListAsync((Expression, TReturn>>)expModify); + } + + Task ISelect<<#=NewStr #>>.ToDataTableAsync(Expression>, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect<<#=NewStr #>>).ToDataTableAsync((Expression, TReturn>>)expModify); + } + + Task ISelect<<#=NewStr #>>.InsertIntoAsync(string tableName, Expression>, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect<<#=NewStr #>>).InsertIntoAsync(tableName,(Expression, TTargetEntity>>)expModify); + } + + async Task ISelect<<#=NewStr #>>.AnyAsync(Expression>, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect<<#=NewStr #>>).AnyAsync((Expression, bool>>)expModify); + } + + async Task ISelect<<#=NewStr #>>.ToOneAsync(Expression>, TReturn>> select) + => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect<<#=NewStr #>>.FirstAsync(Expression>, TReturn>> select) + => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select)).FirstOrDefault(); + + + #endregion + +#endif + } + + + <# + } #> +} + + +<# + } #> \ No newline at end of file From 05e164a63fb96d6b1f4177a7256a5707cb915ea6 Mon Sep 17 00:00:00 2001 From: "1396510655@qq.com" Date: Wed, 4 Nov 2020 10:30:01 +0800 Subject: [PATCH 0974/1029] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=A4=9A=E8=A1=A8?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=96=B0=E8=AF=AD=E6=B3=95=20groupby=20?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?= 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/UnitTest4.cs | 7 +++++++ 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -509,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index a7fcec8f..1ee8fe8a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -42,6 +42,13 @@ namespace FreeSql.Tests .OrderBy(w => w.t1.AddTime) .ToSql(); + var xxxhzytupleGroupBy = g.sqlite.Select() + .LeftJoin(w => w.t1.Id2 == w.t2.TemplatesId) + .Where(w => w.t1.Code == "xxx" && w.t2.OptionsEntity03 == true) + .GroupBy(w => new { w.t1 }) + .OrderBy(w => w.Key.t1.AddTime) + .ToSql(w => new { w.Key.t1 }); + } From 856ecf279d196b9f6257ef7e6f317c24a7e56b71 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 4 Nov 2020 11:14:37 +0800 Subject: [PATCH 0975/1029] v2.0.0-preview1105 #515 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 27 +------------------ FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 24 files changed, 39 insertions(+), 48 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 7c500d83..04e9ac53 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 6ab501b6..6773983a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b68e5a5c..c94d8252 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index f11ca82d..44a804fd 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 826d2aba..88543072 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1102 + 2.0.0-preview1105 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 56f14cfb..8469f9a0 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 4691cf25..2e5c5847 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -502,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 582e897c..3d416f7e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index 1ee8fe8a..d369cc98 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -10,28 +10,6 @@ namespace FreeSql.Tests { public class UnitTest4 { - static Lazy sqliteLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;") - //.UseConnectionFactory(FreeSql.DataType.Sqlite, () => - //{ - // var conn = new System.Data.SQLite.SQLiteConnection(@"Data Source=|DataDirectory|\document.db;Pooling=true;"); - // //conn.Open(); - // //var cmd = conn.CreateCommand(); - // //cmd.CommandText = $"attach database [xxxtb.db] as [xxxtb];\r\n"; - // //cmd.ExecuteNonQuery(); - // //cmd.Dispose(); - // return conn; - //}) - .UseAutoSyncStructure(true) - //.UseGenerateCommandParameterWithLambda(true) - .UseLazyLoading(true) - .UseMonitorCommand( - cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 - //, (cmd, traceLog) => Console.WriteLine(traceLog) - ) - .Build()); - public static IFreeSql sqlite => sqliteLazy.Value; - [Fact] public void TestHzyTuple() @@ -47,11 +25,8 @@ namespace FreeSql.Tests .Where(w => w.t1.Code == "xxx" && w.t2.OptionsEntity03 == true) .GroupBy(w => new { w.t1 }) .OrderBy(w => w.Key.t1.AddTime) - .ToSql(w => new { w.Key.t1 }); + .ToSql(w => w.Key ); } - - - } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 70dcaf2e..a533eb3d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 3dc9abe2..17f90c31 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index d28e286d..d285cd12 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 1125943e..4feebcbf 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 9ca67cb9..559cb319 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index ec6f5626..234d199b 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 19159d71..81cfb315 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 6cdfd3ed..596c91d8 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 074e8776..6798ce46 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 76e9b176..94d6475c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 47059469..a38b1205 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index a87d2dd0..c852dfab 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index c5915f2c..f9c43c39 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index feed3695..4a17febc 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1102 + 2.0.0-preview1105 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From b701ad8421bcebaa525b736290392520acac15f0 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 4 Nov 2020 18:03:47 +0800 Subject: [PATCH 0976/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IncludeByPro?= =?UTF-8?q?pertyName=20=E6=8C=89=E5=B1=9E=E6=80=A7=E5=90=8D=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=20Include/IncludeMany=20=E6=93=8D=E4=BD=9C=EF=BC=9B#2?= =?UTF-8?q?78?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 25 ++++++++++++++++ FreeSql/FreeSql.xml | 7 +++++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 7 +++++ .../SelectProvider/Select0Provider.cs | 4 +-- .../SelectProvider/Select1Provider.cs | 30 +++++++++++++++++++ 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 626486b4..490e7498 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -191,6 +191,10 @@ namespace FreeSql.Tests { [Column(IsIdentity = true)] public int? Id { get; set; } + + public string name { get; set; } + [Navigate(nameof(tshop01.cateId))] + public List tshops { get; set; } } public class tshop01 { @@ -203,7 +207,28 @@ namespace FreeSql.Tests [Fact] public void Test03() { + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var tshoprepo = g.sqlite.GetRepository(); + tshoprepo.DbContextOptions.EnableAddOrUpdateNavigateList = true; + tshoprepo.Insert(new tcate01[] + { + new tcate01 { name = "tcate1", tshops = new List{ new tshop01(), new tshop01(), new tshop01() } }, + new tcate01 { name = "tcate1", tshops = new List{ new tshop01(), new tshop01(), new tshop01() } } + }); + var tshop01sql = g.sqlite.Select().Include(a => a.cate).ToSql(); + var tshop02sql = g.sqlite.Select().IncludeByPropertyName("cate").ToSql(); + + var tshop03sql = g.sqlite.Select().IncludeMany(a => a.cate.tshops).ToSql(); + var tshop04sql = g.sqlite.Select().IncludeByPropertyName("cate.tshops").ToSql(); + + var tshop01lst = g.sqlite.Select().Include(a => a.cate).ToList(); + var tshop02lst = g.sqlite.Select().IncludeByPropertyName("cate").ToList(); + + var tshop03lst = g.sqlite.Select().IncludeMany(a => a.cate.tshops).ToList(); + var tshop04lst = g.sqlite.Select().IncludeByPropertyName("cate.tshops").ToList(); + var testisnullsql1 = g.sqlite.Select().Where(a => SqlExt.IsNull(a.isxx, false).Equals( true)).ToSql(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3844b008..b0083f17 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2345,6 +2345,13 @@ 即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?) + + + 按属性名字符串进行 Include/IncludeMany 操作 + + + + 实现 select .. from ( select ... from t ) a 这样的功能 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 88c8d412..cefb5ced 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -333,6 +333,13 @@ namespace FreeSql /// ISelect IncludeMany(Expression>> navigateSelector, Action> then = null) where TNavigate : class; + /// + /// 按属性名字符串进行 Include/IncludeMany 操作 + /// + /// + /// + ISelect IncludeByPropertyName(string property); + /// /// 实现 select .. from ( select ... from t ) a 这样的功能 /// 使用 AsTable 方法也可以达到效果 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index bafaf7be..9d1d8782 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -121,13 +121,13 @@ namespace FreeSql.Internal.CommonProvider to._whereGlobalFilter = new List(from._whereGlobalFilter.ToArray()); } - public Expression ConvertStringPropertyToExpression(string property) + public Expression ConvertStringPropertyToExpression(string property, bool fromFirstTable = false) { if (string.IsNullOrEmpty(property)) return null; var field = property.Split('.').Select(a => a.Trim()).ToArray(); Expression exp = null; - if (field.Length == 1) + if (field.Length == 1 && fromFirstTable == false) { foreach (var tb in _tables) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index cc8e1e7a..896d31f7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -392,6 +392,36 @@ namespace FreeSql.Internal.CommonProvider public int InsertInto(string tableName, Expression> select) where TTargetEntity : class => base.InternalInsertInto(tableName, select); + public ISelect IncludeByPropertyName(string property) + { + var exp = ConvertStringPropertyToExpression(property, true); + if (exp == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树"); + var memExp = exp as MemberExpression; + if (memExp == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树2"); + var parTb = _commonUtils.GetTableByEntity(memExp.Expression.Type); + if (parTb == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树3"); + var parTbref = parTb.GetTableRef(memExp.Member.Name, true); + if (parTbref == null) throw new ArgumentException($"{nameof(property)} 不是有效的导航属性"); + switch (parTbref.RefType) + { + case TableRefType.ManyToMany: + case TableRefType.OneToMany: + var funcType = typeof(Func<,>).MakeGenericType(_tables[0].Table.Type, typeof(IEnumerable<>).MakeGenericType(parTbref.RefEntityType)); + var navigateSelector = Expression.Lambda(funcType, exp, _tables[0].Parameter); + var incMethod = this.GetType().GetMethod("IncludeMany"); + if (incMethod == null) throw new Exception("运行时错误,反射获取 IncludeMany 方法失败"); + incMethod.MakeGenericMethod(parTbref.RefEntityType).Invoke(this, new object[] { navigateSelector, null }); + break; + case TableRefType.ManyToOne: + case TableRefType.OneToOne: + _isIncluded = true; + var curTb = _commonUtils.GetTableByEntity(exp.Type); + _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(exp, curTb.Properties[curTb.ColumnsByCs.First().Value.CsName]), null, null, null); + break; + } + return this; + } + bool _isIncluded = false; public ISelect Include(Expression> navigateSelector) where TNavigate : class { From 639d30fafe945414bace60f159964d4091894b53 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 4 Nov 2020 19:23:03 +0800 Subject: [PATCH 0977/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20varchar/nvar?= =?UTF-8?q?char=20=E7=9A=84=20NoneParameter=20=E5=A4=84=E7=90=86=EF=BC=9B#?= =?UTF-8?q?519?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 35 +++++++++ FreeSql.Tests/FreeSql.Tests/Issues/518.cs | 59 +++++++++++++++ FreeSql.Tests/FreeSql.Tests/Issues/519.cs | 72 +++++++++++++++++++ .../CommonProvider/InsertOrUpdateProvider.cs | 2 +- .../Internal/CommonProvider/InsertProvider.cs | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 10 +-- FreeSql/Internal/CommonUtils.cs | 24 +++---- FreeSql/Internal/UtilsExpressionTree.cs | 2 +- .../Curd/DamengInsert.cs | 2 +- .../FreeSql.Provider.Dameng/DamengUtils.cs | 2 +- .../FirebirdUtils.cs | 2 +- .../KingbaseESUtils.cs | 4 +- .../MsAccessUtils.cs | 2 +- .../FreeSql.Provider.MySql/MySqlUtils.cs | 2 +- .../MySqlConnectorUtils.cs | 2 +- .../Dameng/Curd/OdbcDamengInsert.cs | 2 +- .../Dameng/OdbcDamengUtils.cs | 2 +- .../Default/OdbcUtils.cs | 2 +- .../KingbaseES/OdbcKingbaseESUtils.cs | 4 +- .../MySql/OdbcMySqlUtils.cs | 2 +- .../Oracle/Curd/OdbcOracleInsert.cs | 2 +- .../Oracle/OdbcOracleUtils.cs | 2 +- .../PostgreSQL/OdbcPostgreSQLUtils.cs | 4 +- .../SqlServer/OdbcSqlServerUtils.cs | 5 +- .../Curd/OracleInsert.cs | 4 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 2 +- .../PostgreSQLUtils.cs | 4 +- .../ShenTongUtils.cs | 4 +- .../SqlServerUtils.cs | 5 +- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 2 +- 30 files changed, 218 insertions(+), 50 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/518.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/519.cs diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index bf9e6d4d..a21af7db 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -104,6 +104,41 @@ 班期信息 + + + 库位 + + + + + 工厂 + + + + + 物料号 + + + + + 条码号 + + + + + 创建时间 + + + + + 创建人 + + + + + 创建人名称 + + 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/518.cs b/FreeSql.Tests/FreeSql.Tests/Issues/518.cs new file mode 100644 index 00000000..a69536ae --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/518.cs @@ -0,0 +1,59 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _518 + { + [Fact] + public void SelectTest() + { + IFreeSql free = g.sqlserver; + + //创建测试数据 + using (var db = free.CreateDbContext()) + { + db.Set().Remove(t => true); //清空旧数据 + db.SaveChanges(); + + //插入三条测试数据 + db.Add(new TestEntity518() { ID = "A", Name = "张三", Age = 18 }); + db.Add(new TestEntity518() { ID = "B", Name = "李四", Age = 19 }); + db.Add(new TestEntity518() { ID = "C", Name = "王五", Age = 20 }); + db.SaveChanges(); + } + + //开始测试 + using (var db = free.CreateDbContext()) + { + var entities = db.Set().Where(t => true).ToDictionary(t => t.ID); + + entities["A"].Age = 25; + db.Update(entities["A"]); + + entities["B"].Age = 26; + db.Update(entities["B"]); + + entities["C"].Age = 27; + //entities["C"].Name = "王五5"; //注释掉这一行就不会报错 + db.Update(entities["C"]); + + db.Add(new TestEntity518() { ID = "D", Name = "马六", Age = 30 }); + + db.SaveChanges(); + } + } + class TestEntity518 + { + public string ID { get; set; } + public string Name { get; set; } + public int Age { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/519.cs b/FreeSql.Tests/FreeSql.Tests/Issues/519.cs new file mode 100644 index 00000000..bcaf78ce --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/519.cs @@ -0,0 +1,72 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _519 + { + [Fact] + public void SelectTest() + { + IFreeSql fsql = g.sqlserver; + + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] + { + new ST_Stock519 { StoreHouse = "001", Works = "101", MaterialCode = "201", BatchCode = "301", CreatedTime = DateTime.Now }, + new ST_Stock519 { StoreHouse = "002", Works = "102", MaterialCode = "202", BatchCode = "302", CreatedTime = DateTime.Now }, + new ST_Stock519 { StoreHouse = "003", Works = "103", MaterialCode = "203", BatchCode = "303", CreatedTime = DateTime.Now } + }).ExecuteAffrows(); + + var list = fsql.Select().ToList(); + var sql1 = fsql.Insert(list).NoneParameter().ToSql(); + var sql2 = fsql.Update().SetSource(list).NoneParameter().ToSql(); + var sql3 = fsql.InsertOrUpdate().SetSource(list).ToSql(); + } + class ST_Stock519 + { + /// + /// 库位 + /// + [Column(IsPrimary = true, DbType = "varchar(50)")] + public string StoreHouse { get; set; } = string.Empty; + + /// + /// 工厂 + /// + [Column(IsPrimary = true, DbType = "varchar(50)")] + public string Works { get; set; } = string.Empty; + /// + /// 物料号 + /// + [Column(IsPrimary = true, DbType = "varchar(50)")] + public string MaterialCode { get; set; } = string.Empty; + /// + /// 条码号 + /// + [Column(IsPrimary = true, DbType = "varchar(50)")] + public string BatchCode { get; set; } = string.Empty; + + /// + /// 创建时间 + /// + public DateTime? CreatedTime { get; set; } + + /// + /// 创建人 + /// + public string CreatorID { get; set; } = string.Empty; + + /// + /// 创建人名称 + /// + public string CreatorName { get; set; } = string.Empty; + } + } +} diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index ac621b0d..d2ed7a35 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -166,7 +166,7 @@ namespace FreeSql.Internal.CommonProvider else { object val = col.GetDbValue(d); - sb.Append(_commonUtils.GetNoneParamaterSqlValue(dbParams, "cu", col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(dbParams, "cu", col, col.Attribute.MapType, val)); } if (didx == 0) sb.Append(" as ").Append(col.Attribute.Name); ++colidx2; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 3ede179a..cb14f9cb 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -571,7 +571,7 @@ namespace FreeSql.Internal.CommonProvider object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 40720ec1..5d579daf 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -427,7 +427,7 @@ namespace FreeSql.Internal.CommonProvider _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); if (_noneParameter) { - _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, "u", col.Attribute.MapType, val)); + _set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, "u", col, col.Attribute.MapType, val)); } else { @@ -588,7 +588,7 @@ namespace FreeSql.Internal.CommonProvider var sb = new StringBuilder(); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); - sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, col.GetDbValue(_source.First())))); + sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, col.GetDbValue(_source.First())))); return sb.ToString(); @@ -612,7 +612,7 @@ namespace FreeSql.Internal.CommonProvider ToSqlWhen(cwsb, _table.Primarys, d); cwsb.Append(" THEN "); var val = col.GetDbValue(d); - cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val))); + cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val))); if (val == null || val == DBNull.Value) nulls++; } cwsb.Append(" END"); @@ -685,7 +685,7 @@ namespace FreeSql.Internal.CommonProvider { var val = col.GetDbValue(_source.First()); if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); @@ -730,7 +730,7 @@ namespace FreeSql.Internal.CommonProvider cwsb.Append(" THEN "); var val = col.GetDbValue(d); if (_noneParameter) - cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col.Attribute.MapType, val)); + cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val)); else { cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"))); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 0bcd1bbd..37963385 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -23,7 +23,7 @@ namespace FreeSql.Internal public abstract class CommonUtils { - public abstract string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value); + public abstract string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value); public abstract DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value); public abstract DbParameter[] GetDbParamtersByObject(string sql, object obj); public abstract string FormatSql(string sql, params object[] args); @@ -267,7 +267,7 @@ namespace FreeSql.Internal var pk1 = primarys.FirstOrDefault(); if (primarys.Length == 1 && (type == pk1.CsType || type.IsNumberType() && pk1.CsType.IsNumberType())) { - return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}"; + return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {GetNoneParamaterSqlValue(null, null, pk1, pk1.Attribute.MapType, Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}"; } else if (primarys.Length > 0 && (type == table.Type || type.BaseType == table.Type)) { @@ -276,15 +276,15 @@ namespace FreeSql.Internal foreach (var pk in primarys) { if (pkidx > 0) sb.Append(" AND "); - sb.Append(aliasAndDot).Append(this.QuoteSqlName(pk.Attribute.Name)); - sb.Append(this.FormatSql(" = {0}", pk.GetDbValue(dywhere))); + sb.Append(aliasAndDot).Append(this.QuoteSqlName(pk.Attribute.Name)).Append(" = "); + sb.Append(GetNoneParamaterSqlValue(null, null, pk, pk.Attribute.MapType, pk.GetDbValue(dywhere))); ++pkidx; } return sb.ToString(); } else if (primarys.Length == 1 && type == typeof(string)) { - return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}"; + return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {GetNoneParamaterSqlValue(null, null, pk1, pk1.Attribute.MapType, Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}"; } else if (primarys.Length == 1 && dywhere is IEnumerable) { @@ -303,8 +303,8 @@ namespace FreeSql.Internal var itype = i.GetType(); isEntityType = (itype == table.Type || itype.BaseType == table.Type); } - if (isEntityType) sb.Append(this.FormatSql("{0}", primarys[0].GetDbValue(i))); - else sb.Append(this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, i))); + if (isEntityType) sb.Append(GetNoneParamaterSqlValue(null, null, primarys[0], primarys[0].Attribute.MapType, primarys[0].GetDbValue(i))); + else sb.Append(GetNoneParamaterSqlValue(null, null, pk1, pk1.Attribute.MapType, Utils.GetDataReaderValue(pk1.Attribute.MapType, i))); ++ieidx; } if (isAny == false) return ""; @@ -338,8 +338,8 @@ namespace FreeSql.Internal if (trycol == null) continue; if (psidx > 0) sb.Append(" AND "); - sb.Append(aliasAndDot).Append(this.QuoteSqlName(trycol.Attribute.Name)); - sb.Append(this.FormatSql(" = {0}", Utils.GetDataReaderValue(trycol.Attribute.MapType, p.GetValue(dywhere, null)))); + sb.Append(aliasAndDot).Append(this.QuoteSqlName(trycol.Attribute.Name)).Append(" = "); + sb.Append(GetNoneParamaterSqlValue(null, null, trycol, trycol.Attribute.MapType, Utils.GetDataReaderValue(trycol.Attribute.MapType, p.GetValue(dywhere, null)))); ++psidx; } if (psidx == 0) return ""; @@ -360,8 +360,8 @@ namespace FreeSql.Internal sbin.Append(aliasAndDot).Append(this.QuoteSqlName(pk1.Attribute.Name)); var indt = its.Select(a => pk1.GetDbValue(a)).Where(a => a != null).ToArray(); if (indt.Any() == false) return null; - if (indt.Length == 1) sbin.Append(" = ").Append(this.FormatSql("{0}", indt.First())); - else sbin.Append(" IN (").Append(string.Join(",", indt.Select(a => this.FormatSql("{0}", a)))).Append(")"); + if (indt.Length == 1) sbin.Append(" = ").Append(GetNoneParamaterSqlValue(null, null, pk1, pk1.Attribute.MapType, indt.First())); + else sbin.Append(" IN (").Append(string.Join(",", indt.Select(a => GetNoneParamaterSqlValue(null, null, pk1, pk1.Attribute.MapType, a)))).Append(")"); return sbin.ToString(); } var dicpk = its.Length > 5 ? new Dictionary() : null; @@ -371,7 +371,7 @@ namespace FreeSql.Internal { var filter = ""; foreach (var pk in table.Primarys) - filter += $" AND {aliasAndDot}{this.QuoteSqlName(pk.Attribute.Name)} = {this.FormatSql("{0}", pk.GetDbValue(item))}"; + filter += $" AND {aliasAndDot}{this.QuoteSqlName(pk.Attribute.Name)} = {GetNoneParamaterSqlValue(null, null, pk, pk.Attribute.MapType, pk.GetDbValue(item))}"; if (string.IsNullOrEmpty(filter)) continue; if (sb != null) { diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 0d286190..0786b1ec 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -187,7 +187,7 @@ namespace FreeSql.Internal } try { - col.DbDefaultValue = common.GetNoneParamaterSqlValue(new List(), "init", colattr.MapType, defaultValue); + col.DbDefaultValue = common.GetNoneParamaterSqlValue(new List(), "init", col, colattr.MapType, defaultValue); } catch { diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index c1e3047c..e0e0173c 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -69,7 +69,7 @@ namespace FreeSql.Dameng.Curd object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); diff --git a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs index b9500106..d8faa6f5 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs @@ -93,7 +93,7 @@ namespace FreeSql.Dameng public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs b/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs index 98a9cb76..a20c5fbc 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdUtils.cs @@ -82,7 +82,7 @@ namespace FreeSql.Firebird public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESUtils.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESUtils.cs index 91bc9f92..f0667e70 100644 --- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESUtils.cs +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESUtils.cs @@ -124,7 +124,7 @@ namespace FreeSql.KingbaseES public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -146,7 +146,7 @@ namespace FreeSql.KingbaseES { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs index ed8fc51b..9898dcac 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessUtils.cs @@ -82,7 +82,7 @@ namespace FreeSql.MsAccess public override string FieldAsAlias(string alias) => $" as {alias}"; public override string IIF(string test, string ifTrue, string ifElse) => $"iif({test}, {ifTrue}, {ifElse})"; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs index 5a4ced4d..6d2555bc 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlUtils.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlUtils.cs @@ -126,7 +126,7 @@ namespace FreeSql.MySql return columnName; } - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs index 221855b1..c8cdabb2 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/MySqlConnectorUtils.cs @@ -146,7 +146,7 @@ namespace FreeSql.MySql return columnName; } - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index ee2ca1a0..ac099657 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -69,7 +69,7 @@ namespace FreeSql.Odbc.Dameng object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs index a9edc60d..edaa12e1 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengUtils.cs @@ -99,7 +99,7 @@ namespace FreeSql.Odbc.Dameng public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs index 64fd5d83..d24daf3b 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcUtils.cs @@ -69,7 +69,7 @@ namespace FreeSql.Odbc.Default public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => Adapter.FieldSql(type, columnName); - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs index b1a3a680..6b661ab8 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESUtils.cs @@ -123,7 +123,7 @@ namespace FreeSql.Odbc.KingbaseES public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -145,7 +145,7 @@ namespace FreeSql.Odbc.KingbaseES { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs index dc65db27..87a54520 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlUtils.cs @@ -93,7 +93,7 @@ namespace FreeSql.Odbc.MySql return columnName; } - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index d2903b2d..f687a17d 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -69,7 +69,7 @@ namespace FreeSql.Odbc.Oracle object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs index 1279be50..9c4b68b0 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleUtils.cs @@ -99,7 +99,7 @@ namespace FreeSql.Odbc.Oracle public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs index c65c1788..68a21b0f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLUtils.cs @@ -123,7 +123,7 @@ namespace FreeSql.Odbc.PostgreSQL public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -145,7 +145,7 @@ namespace FreeSql.Odbc.PostgreSQL { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs index bb2fc858..666f01d0 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerUtils.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; using FreeSql.Internal.Model; using System; using System.Collections.Generic; @@ -86,7 +87,7 @@ namespace FreeSql.Odbc.SqlServer public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -96,7 +97,7 @@ namespace FreeSql.Odbc.SqlServer var ts = (TimeSpan)value; value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; } - return FormatSql("{0}", value, 1); + return string.Format(CultureInfo.InvariantCulture, "{0}", (_orm.Ado as AdoProvider).AddslashesProcessParam(value, type, col)); } } } diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index e7f68355..ce124df9 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -78,7 +78,7 @@ namespace FreeSql.Oracle.Curd object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); @@ -143,7 +143,7 @@ namespace FreeSql.Oracle.Curd object val = col.GetDbValue(d); if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 if (_noneParameter) - sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col.Attribute.MapType, val)); + sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val)); else { sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"))); diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 4538a0ff..9d66f317 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -98,7 +98,7 @@ namespace FreeSql.Oracle public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs index bf384eda..71c5f478 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLUtils.cs @@ -163,7 +163,7 @@ namespace FreeSql.PostgreSQL public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; static ConcurrentDictionary _dicIsAssignableFromPostgisGeometry = new ConcurrentDictionary(); - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -199,7 +199,7 @@ namespace FreeSql.PostgreSQL { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs index b29ce343..a413ae16 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongUtils.cs @@ -137,7 +137,7 @@ namespace FreeSql.ShenTong public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -161,7 +161,7 @@ namespace FreeSql.ShenTong { var item = valueArr.GetValue(a); if (a > 0) sb.Append(","); - sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, eleType, item)); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, eleType, item)); } sb.Append("]"); var dbinfo = _orm.CodeFirst.GetDbInfo(type); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs index 88a36219..9295faec 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerUtils.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; using FreeSql.Internal.Model; using System; using System.Collections.Generic; @@ -102,7 +103,7 @@ namespace FreeSql.SqlServer public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); @@ -112,7 +113,7 @@ namespace FreeSql.SqlServer var ts = (TimeSpan)value; value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; } - return FormatSql("{0}", value, 1); + return string.Format(CultureInfo.InvariantCulture, "{0}", (_orm.Ado as AdoProvider).AddslashesProcessParam(value, type, col)); } } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index 98ed34bd..ffdbb89c 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -98,7 +98,7 @@ namespace FreeSql.Sqlite public override string QuoteWriteParamter(Type type, string paramterName) => paramterName; public override string QuoteReadColumn(Type type, Type mapType, string columnName) => columnName; - public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, Type type, object value) + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) { if (value == null) return "NULL"; if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); From fa52398c513f6ede9d3be8e87c1e43e4d1a76364 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 4 Nov 2020 19:28:14 +0800 Subject: [PATCH 0978/1029] v2.0.0-preview1106 #519 #278 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 04e9ac53..71df2fdd 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 6773983a..c2f34b8d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c94d8252..72eaf1cb 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 44a804fd..6da16279 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 88543072..4b3ce1ea 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1105 + 2.0.0-preview1106 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 8469f9a0..97d7a13f 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2e5c5847..a40794cd 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 3d416f7e..0ca01940 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index a533eb3d..3c164981 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 17f90c31..95245496 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index d285cd12..b7dd9eb9 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 4feebcbf..a5afa724 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 559cb319..b453c18e 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 234d199b..67edf51a 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 81cfb315..65a687ad 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 596c91d8..0b7ca1cb 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6798ce46..a8760576 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 94d6475c..ce7ace54 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index a38b1205..ec9aab5e 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c852dfab..c2815f8f 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index f9c43c39..7ec171fb 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 4a17febc..187b4248 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1105 + 2.0.0-preview1106 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 9a0d2cd0e6e6f32d6b0838374323f04726634392 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 5 Nov 2020 17:01:01 +0800 Subject: [PATCH 0979/1029] add mysql timestamp Tests --- .../MySqlConnector/MySqlCodeFirstTest.cs | 42 +++++++++++++++++++ .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 42 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs index cef82a4c..b7ec0ce2 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlCodeFirstTest.cs @@ -11,6 +11,48 @@ namespace FreeSql.Tests.MySqlConnector { public class MySqlCodeFirstTest { + [Fact] + public void Timestamp01() + { + var fsql = g.mysql; + var items = fsql.Select().ToList(); + fsql.Delete().Where("1=1").ExecuteAffrows(); + + var item = new timestamp01 { time = DateTime.Now }; + fsql.Insert(item).ExecuteAffrows(); + var newitem = fsql.Select().WhereDynamic(item).First(); + Assert.Equal(item.id, newitem.id); + Assert.Equal(item.time.ToString("yyyy-MM-dd HH:mm"), newitem.time.ToString("yyyy-MM-dd HH:mm")); + + item = new timestamp01 { time = DateTime.Now }; + fsql.Insert(item).NoneParameter().ExecuteAffrows(); + newitem = fsql.Select().WhereDynamic(item).First(); + Assert.Equal(item.time.ToString("yyyy-MM-dd HH:mm"), newitem.time.ToString("yyyy-MM-dd HH:mm")); + + + fsql.Delete().Where("1=1").ExecuteAffrows(); + var user01 = new timestamp02(); + fsql.Insert(user01).ExecuteAffrows(); + var user01s = fsql.Select().Count(out var count).Page(0, 100).ToList(); + } + class timestamp01 + { + public Guid id { get; set; } + [Column(DbType = "timestamp")] + public DateTime time { get; set; } + } + public class timestamp02 + { + public long UID { get; set; } = 123; + public string Alias { get; set; } + public bool Fixed { get; set; } + public string Avatar { get; set; } + public DateTime Created { get; set; } //= DateTime.Now; + public long CreatedBy { get; set; } + public DateTime Modified { get; set; }// = DateTime.Now; + public long ModifiedBy { get; set; } + } + [Fact] public void DateTime_1() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 43501614..626d726c 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -11,6 +11,48 @@ namespace FreeSql.Tests.MySql { public class MySqlCodeFirstTest { + [Fact] + public void Timestamp01() + { + var fsql = g.mysql; + var items = fsql.Select().ToList(); + fsql.Delete().Where("1=1").ExecuteAffrows(); + + var item = new timestamp01 { time = DateTime.Now }; + fsql.Insert(item).ExecuteAffrows(); + var newitem = fsql.Select().WhereDynamic(item).First(); + Assert.Equal(item.id, newitem.id); + Assert.Equal(item.time.ToString("yyyy-MM-dd HH:mm"), newitem.time.ToString("yyyy-MM-dd HH:mm")); + + item = new timestamp01 { time = DateTime.Now }; + fsql.Insert(item).NoneParameter().ExecuteAffrows(); + newitem = fsql.Select().WhereDynamic(item).First(); + Assert.Equal(item.time.ToString("yyyy-MM-dd HH:mm"), newitem.time.ToString("yyyy-MM-dd HH:mm")); + + + fsql.Delete().Where("1=1").ExecuteAffrows(); + var user01 = new timestamp02(); + fsql.Insert(user01).ExecuteAffrows(); + var user01s = fsql.Select().Count(out var count).Page(0, 100).ToList(); + } + class timestamp01 + { + public Guid id { get; set; } + [Column(DbType = "timestamp")] + public DateTime time { get; set; } + } + public class timestamp02 + { + public long UID { get; set; } = 123; + public string Alias { get; set; } + public bool Fixed { get; set; } + public string Avatar { get; set; } + public DateTime Created { get; set; } //= DateTime.Now; + public long CreatedBy { get; set; } + public DateTime Modified { get; set; }// = DateTime.Now; + public long ModifiedBy { get; set; } + } + [Fact] public void EnumStartValue1() { From 5ad30ccb91f00033d6765cf86a0d37fe970aa01d Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 5 Nov 2020 17:43:59 +0800 Subject: [PATCH 0980/1029] add TestCode #521 --- FreeSql.Tests/FreeSql.Tests/Issues/521.cs | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/521.cs diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/521.cs b/FreeSql.Tests/FreeSql.Tests/Issues/521.cs new file mode 100644 index 00000000..890ca1f8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/521.cs @@ -0,0 +1,48 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics; +using System.Text; +using System.Threading; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _521 + { + [Fact] + public void SelectTest() + { + IFreeSql fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new ts521 { ID = 1000000000000000001 }).ExecuteAffrows(); + + var item = new List(); + item.Add(new ts521 { ID = 1000000000000000001, SpellCode = "ces", Version = 1 }); + + fsql.Update().SetSource(item).UpdateColumns(info => info.SpellCode).ExecuteAffrows(); + } + class ts521 + { + [Key] + public long ID { get; set; } + + [Description("名字")] + public string Name { get; set; } + + [Description("账号")] + [Column(IsNullable = false)] + public string Account { get; set; } + + [Description("名称拼音首字母")] + public string SpellCode { get; set; } + + [Description("乐观锁")] + [Column(IsVersion = true, InsertValueSql = "1")] + public long Version { get; set; } + } + } +} From a73e882f4e2f0ee4ef2d18e7ca98cd2b2bc85fab Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 6 Nov 2020 08:42:56 +0800 Subject: [PATCH 0981/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20#454=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=81=97=E7=95=99=E7=9A=84=20bug=EF=BC=8C?= =?UTF-8?q?=E5=BD=B1=E5=93=8D=20Aop.AuditValue=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=EF=BC=9B#521?= 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/Issues/521.cs | 15 +++++++++++++++ .../Internal/CommonProvider/UpdateProvider.cs | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -509,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/521.cs b/FreeSql.Tests/FreeSql.Tests/Issues/521.cs index 890ca1f8..6e338e66 100644 --- a/FreeSql.Tests/FreeSql.Tests/Issues/521.cs +++ b/FreeSql.Tests/FreeSql.Tests/Issues/521.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics; +using System.Reflection; using System.Text; using System.Threading; using Xunit; @@ -17,6 +18,18 @@ namespace FreeSql.Tests.Issues public void SelectTest() { IFreeSql fsql = g.sqlserver; + + //fsql.Aop.AuditValue += (s, e) => { + // if (e.Column.CsType == typeof(long) + // && e.Property.GetCustomAttribute(false) != null + // && e.Value?.ToString() == "0") + // { + // e.Value = 1; + // } + + //}; + + fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Insert(new ts521 { ID = 1000000000000000001 }).ExecuteAffrows(); @@ -28,6 +41,7 @@ namespace FreeSql.Tests.Issues class ts521 { [Key] + [Snowflake] public long ID { get; set; } [Description("名字")] @@ -44,5 +58,6 @@ namespace FreeSql.Tests.Issues [Column(IsVersion = true, InsertValueSql = "1")] public long Version { get; set; } } + public class SnowflakeAttribute: Attribute { } } } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 5d579daf..14fb2985 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -374,7 +374,7 @@ namespace FreeSql.Internal.CommonProvider changedDict.Add(col.Attribute.Name, true); } if (val == null && col.Attribute.MapType == typeof(string) && col.Attribute.IsNullable == false) - col.SetValue(data, val = ""); + col.SetValue(d, val = ""); } } } From c4a16693cca81715957c5ecf0b817edc96f6f55b Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 6 Nov 2020 08:45:38 +0800 Subject: [PATCH 0982/1029] v1.8.2 #521 #454 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 38 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 71df2fdd..1cf82c1c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index c2f34b8d..1f6aa302 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 72eaf1cb..e118efd4 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 6da16279..24eda2e8 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 4b3ce1ea..479ca96b 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1106 + 1.8.2 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 97d7a13f..9e6719e3 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a40794cd..97226ba7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -502,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0ca01940..b702c36c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1106 + 1.8.2 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3c164981..e53949b6 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 95245496..13ef23be 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index b7dd9eb9..bc0c726b 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index a5afa724..0744eb70 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index b453c18e..01a6d1d1 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 67edf51a..3b51c910 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 65a687ad..5ddfbe37 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0b7ca1cb..8f12ed1b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index a8760576..49bc1016 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ce7ace54..2a8c0def 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index ec9aab5e..c78ebd56 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c2815f8f..825f21fa 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 7ec171fb..3d7738c1 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 187b4248..f6d00565 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1106 + 1.8.2 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 4471e0c39bb81a8afa3e6f9d56125d63fa686e31 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 6 Nov 2020 08:48:11 +0800 Subject: [PATCH 0983/1029] v1.9.1 #521 #445 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 347 ++++++++++-------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 24 files changed, 209 insertions(+), 198 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 1cf82c1c..95dc72cf 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 1f6aa302..62663d38 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e118efd4..c7adca1b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 24eda2e8..0b449555 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 479ca96b..5b1190bc 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.8.2 + 1.9.1 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 9e6719e3..ba52d548 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 97226ba7..2e03fa6e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -509,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index b702c36c..e0bfbcc1 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.8.2 + 1.9.1 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e53949b6..fe8e6720 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b0083f17..9d2a797b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3013,154 +3013,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -3989,12 +3841,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4065,12 +3911,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4681,3 +4521,190 @@ +essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 13ef23be..e5b6ef55 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index bc0c726b..0ebdeb7b 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 0744eb70..3674fe0c 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 01a6d1d1..9cbe419f 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 3b51c910..5bbc7606 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 5ddfbe37..7c2e539f 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 8f12ed1b..0736ada7 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 49bc1016..c7d6196c 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2a8c0def..2a8662ac 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index c78ebd56..8eeeefc6 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 825f21fa..cb5c57a8 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 3d7738c1..8588e90b 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index f6d00565..b7e9ef53 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.8.2 + 1.9.1 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 5601cc35772c3e67265d3fa91065cbeba1096ac0 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 6 Nov 2020 08:50:41 +0800 Subject: [PATCH 0984/1029] v1.10.3 #521 #445 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 347 ++++++++---------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 24 files changed, 198 insertions(+), 209 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 95dc72cf..97d6645e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 62663d38..01c29409 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c7adca1b..11362aa5 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 0b449555..d738b93d 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 5b1190bc..fa345874 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.9.1 + 1.10.3 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index ba52d548..8fc3b15c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2e03fa6e..ac5c5a98 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -502,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index e0bfbcc1..0a596969 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.9.1 + 1.10.3 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fe8e6720..e7efd4a7 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9d2a797b..b0083f17 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3013,6 +3013,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3841,6 +3989,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3911,6 +4065,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4521,190 +4681,3 @@ -essions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index e5b6ef55..5fe6f86b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 0ebdeb7b..9ed4645c 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 3674fe0c..c710d534 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 9cbe419f..e877e3c3 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 5bbc7606..0e24f88a 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 7c2e539f..a153399b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 0736ada7..d55005f3 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index c7d6196c..b08f5a10 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2a8662ac..6b978f9a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 8eeeefc6..8d19173e 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cb5c57a8..cd6e674e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 8588e90b..18cbdc04 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index b7e9ef53..e2e5b006 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.9.1 + 1.10.3 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From a47fd0e3a737f251f25e6feb04d3e5b1a2d55408 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 6 Nov 2020 09:16:41 +0800 Subject: [PATCH 0985/1029] =?UTF-8?q?update=20support=20=E7=BF=B0=E9=AB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Repository/readme.md | 2 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 2 +- FreeSql/FreeSql.csproj | 2 +- readme.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index ac5c5a98..e03d121d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -5,7 +5,7 @@ 1.10.3 true FreeSql;ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access https://github.com/2881099/FreeSql/wiki/DbContext FreeSql ORM DbContext git diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 0a596969..4de2466c 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -4,7 +4,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 1.10.3 FreeSql;ncc;YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access, and read/write separation、and split table. + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository FreeSql ORM Repository true diff --git a/FreeSql.Repository/readme.md b/FreeSql.Repository/readme.md index 70620dec..04f18f82 100644 --- a/FreeSql.Repository/readme.md +++ b/FreeSql.Repository/readme.md @@ -98,7 +98,7 @@ var logRepository = fsql.GetGuidRepository(null, oldname => $"{oldname}_{Da ## 兼容问题 -FreeSql 支持多种数据库,分别为 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/MsAccess,虽然他们都为关系型数据库,但各自有着独特的技术亮点,有许多亮点值得我们使用; +FreeSql 支持多种数据库,分别为 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/达梦/人大金仓/翰高/MsAccess,虽然他们都为关系型数据库,但各自有着独特的技术亮点,有许多亮点值得我们使用; 比如 SqlServer 提供的 output inserted 特性,在表使用了自增或数据库定义了默认值的时候,使用它可以快速将 insert 的数据返回。PostgreSQL 也有相应的功能,如此方便却不是每个数据库都支持。 diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index a1b82bbe..9a093d29 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -379,7 +379,7 @@ public static partial class FreeSqlGlobalExtensions #region AsTreeCte(..) 递归查询 /// /// 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 - /// 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓 + /// 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓、翰高 /// 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) /// /// diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e7efd4a7..2f9199fc 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -5,7 +5,7 @@ 1.10.3 true FreeSql;ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, And Access + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql git diff --git a/readme.md b/readme.md index a21825db..4125cb4c 100644 --- a/readme.md +++ b/readme.md @@ -10,7 +10,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [x] 支持 丰富的表达式函数,以及灵活的自定义解析; - [x] 支持 导航属性一对多、多对多贪婪加载,以及延时加载; - [x] 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁; -- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/Access; +- [x] 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access; ## 📚  Documentation From 0de96ef7ec4d955036be941bf2c583c47129bf94 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 6 Nov 2020 13:57:43 +0800 Subject: [PATCH 0986/1029] v2.0.0-preview1108 #521 #445 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 97d6645e..99a19bab 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 01c29409..4b9e018d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 11362aa5..e05c4bff 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index d738b93d..17cc43e3 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index fa345874..0f67e063 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 1.10.3 + 2.0.0-preview1108 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 8fc3b15c..033663ea 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index e03d121d..dfa92ba7 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4de2466c..63b09ffa 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 1.10.3 + 2.0.0-preview1108 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 2f9199fc..9f0cbacb 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b0083f17..3d1bfc1b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -4331,7 +4331,7 @@ 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 - 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓 + 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓、翰高 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 5fe6f86b..1c7602e4 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 9ed4645c..e94d38ef 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index c710d534..4950bac8 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index e877e3c3..5c5dc17d 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0e24f88a..a71eb3ae 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a153399b..74f8c21b 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index d55005f3..69afde0e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b08f5a10..1c371534 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 6b978f9a..62d1a61d 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 8d19173e..d850a261 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index cd6e674e..453e0e0c 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 18cbdc04..71c664ff 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index e2e5b006..7217cf12 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 1.10.3 + 2.0.0-preview1108 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From d01cbdd8dfe0cffb8ccd7f38a5f4888234404bb4 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 6 Nov 2020 14:31:36 +0800 Subject: [PATCH 0987/1029] v2.0.0-preview1109 #521 #445 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../SelectedQueryProvider.cs | 7 ++++++- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 8 ++++---- FreeSql/Internal/GlobalFilter.cs | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 26 files changed, 33 insertions(+), 44 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 99a19bab..4a87cb9a 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 4b9e018d..8fdb957a 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index e05c4bff..ffa64be2 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 17cc43e3..cdecbacc 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs index 8d58c3c9..75177574 100644 --- a/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs +++ b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs @@ -1,4 +1,5 @@ -using FreeSql.Internal.Model; +using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -13,6 +14,8 @@ namespace FreeSql { public interface ISelectedQuery { + Select0Provider SelectOwner { get; } + #if net40 #else Task> ToListAsync(); @@ -79,6 +82,8 @@ namespace FreeSql.Internal.CommonProvider return read.DbField; } + public Select0Provider SelectOwner => _select; + #if net40 #else public Task> ToListAsync() diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 0f67e063..d7d057de 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1108 + 2.0.0-preview1109 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 033663ea..ddf637e8 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index dfa92ba7..59074358 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -509,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 63b09ffa..9fd60073 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 9f0cbacb..b142a887 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 0eb05c0a..07739905 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1622,12 +1622,12 @@ namespace FreeSql.Internal var errorKey = FreeUtil.Sha1($"{(isMultitb ? 1 : 0)},{fl.Where.ToString()}"); if (dicSqlError.ContainsKey(errorKey)) continue; - var visitor = new ReplaceVisitor(); + var visitor = new ReplaceParameterVisitor(); try { var expExp = Expression.Lambda( typeof(Func<,>).MakeGenericType(tb.Table.Type, typeof(bool)), - new ReplaceVisitor().Modify(fl.Where, newParameter), + new ReplaceParameterVisitor().Modify(fl.Where, newParameter), newParameter ); var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = @@ -1652,7 +1652,7 @@ namespace FreeSql.Internal } return null; } - internal class ReplaceVisitor : ExpressionVisitor + public class ReplaceParameterVisitor : ExpressionVisitor { private ParameterExpression parameter; private ParameterExpression oldParameter; @@ -1670,7 +1670,7 @@ namespace FreeSql.Internal } } - internal class ReplaceHzyTupleToMultiParam : ExpressionVisitor + public class ReplaceHzyTupleToMultiParam : ExpressionVisitor { private List tables; private ParameterExpression[] parameters; diff --git a/FreeSql/Internal/GlobalFilter.cs b/FreeSql/Internal/GlobalFilter.cs index e17a788b..a09fb5c7 100644 --- a/FreeSql/Internal/GlobalFilter.cs +++ b/FreeSql/Internal/GlobalFilter.cs @@ -72,7 +72,7 @@ namespace FreeSql.Internal var newParameter = Expression.Parameter(typeof(TEntity), $"gf{_id}"); var newlambda = Expression.Lambda>( - new CommonExpression.ReplaceVisitor().Modify(where, newParameter), + new CommonExpression.ReplaceParameterVisitor().Modify(where, newParameter), newParameter ); item.Where = newlambda; diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 1c7602e4..03c420d8 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index e94d38ef..c00a9a3c 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 4950bac8..daaaf0a3 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 5c5dc17d..a5a3647b 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index a71eb3ae..6c2b1f37 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 74f8c21b..f9c87445 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 69afde0e..329f36cb 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 1c371534..36ff42f7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 62d1a61d..03a42283 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index d850a261..c41bb2db 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 453e0e0c..47166f17 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 71c664ff..b7fade71 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 7217cf12..33e2e388 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1108 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 58be3b77f35ab2ac9dc2f9b234e1e849336d1424 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 9 Nov 2020 00:57:53 +0800 Subject: [PATCH 0988/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20MapRead=20?= =?UTF-8?q?=E5=AF=B9=20NULL=20=E5=AD=97=E6=AE=B5=E7=9A=84=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 35 ++++++++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 4 +-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index d369cc98..4538707a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -10,6 +10,41 @@ namespace FreeSql.Tests { public class UnitTest4 { + [Fact] + public void LeftJoinNull01() + { + var fsql = g.sqlite; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Delete().Where("1=1").ExecuteAffrows(); + + var item = new leftjoin_null01 { name = "xx01" }; + fsql.Insert(item).ExecuteAffrows(); + + var sel1 = fsql.Select() + .LeftJoin((a, b) => a.id == b.null01_id) + .First((a, b) => new + { + a.id, + a.name, + id2 = (Guid?)b.id, + time2 = (DateTime?)b.time + }); + Assert.Null(sel1.id2); + Assert.Null(sel1.time2); + } + + class leftjoin_null01 + { + public Guid id { get; set; } + public string name { get; set; } + } + class leftjoin_null02 + { + public Guid id { get; set; } + public Guid null01_id { get; set; } + public DateTime time { get; set; } + } + [Fact] public void TestHzyTuple() diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 07739905..0952cf1f 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -178,14 +178,14 @@ namespace FreeSql.Internal parent.Property = parentProp; //若不加此行,会引用 GroupBy(..).ToList(a => new Dto { key = a.Key }) null 错误,CopyTo 之后 Property 变为 null return false; } - parent.CsType = exp.Type; + if (parent.CsType == null) parent.CsType = exp.Type; parent.DbField = ExpressionLambdaToSql(exp, getTSC()); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false && parent.DbField.EndsWith(_common.QuoteSqlName(parent.CsName), StringComparison.CurrentCultureIgnoreCase) == false //DbField 和 CsName 相同的时候,不处理 ) field.Append(_common.FieldAsAlias(parent.CsName)); - parent.MapType = SearchColumnByField(_tables, null, parent.DbField)?.Attribute.MapType ?? exp.Type; + if (parent.MapType == null) parent.MapType = SearchColumnByField(_tables, null, parent.DbField)?.Attribute.MapType ?? exp.Type; return false; } return false; From 2cac4c3094839ec3520fb33cb7a3fb4e5df2328c Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 04:31:51 +0800 Subject: [PATCH 0989/1029] update to .net5.0 --- .editorconfig | 7 ++ .../TransactionalAttribute.cs | 2 + .../aspnetcore_transaction.csproj | 35 +++---- Examples/base_entity/base_entity.csproj | 49 +++++----- Examples/benchmarker/benchmarker.csproj | 6 +- Examples/dbcontext_01/dbcontext_01.csproj | 26 ++--- .../efcore_to_freesql.csproj | 24 ++--- Examples/orm_vs/Program.cs | 36 +++---- Examples/orm_vs/orm_vs.csproj | 44 ++++----- Examples/orm_vs_net40/orm_vs_net40.csproj | 5 + Examples/repository_01/repository_01.csproj | 10 +- Examples/restful/restful.csproj | 8 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 97 +++++++++---------- FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++ FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 6 ++ FreeSql.Repository/FreeSql.Repository.csproj | 52 +++++----- FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj | 16 ++- .../FreeSql.Tests.DbContext.csproj | 50 +++++----- .../FreeSql.Tests.PerformanceTests.csproj | 49 +++++----- ...eeSql.Tests.Provider.MySqlConnector.csproj | 41 ++++---- .../FreeSql.Tests.Provider.Odbc.csproj | 42 ++++---- ...rovider.PostgreSQL.NetTopologySuite.csproj | 41 ++++---- .../FreeSql.Tests/FreeSql.Tests.csproj | 18 ++-- FreeSql/FreeSql.csproj | 25 +++-- .../FreeSql.Provider.Dameng.csproj | 86 ++++++++-------- .../FreeSql.Provider.Firebird.csproj | 22 ++--- .../FreeSql.Provider.KingbaseES.csproj | 44 ++++----- .../FreeSql.Provider.MsAccess.csproj | 32 +++--- .../FreeSql.Provider.MySql.csproj | 36 +++---- .../FreeSql.Provider.MySqlConnector.csproj | 24 ++--- .../FreeSql.Provider.Odbc.csproj | 32 +++--- .../FreeSql.Provider.Oracle.csproj | 26 ++--- .../FreeSql.Provider.PostgreSQL.csproj | 56 +++++------ .../FreeSql.Provider.ShenTong.csproj | 58 +++++------ .../FreeSql.Provider.SqlServer.csproj | 40 ++++---- ...FreeSql.Provider.SqlServerForSystem.csproj | 26 ++--- .../FreeSql.Provider.Sqlite.csproj | 30 +++--- 38 files changed, 641 insertions(+), 578 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..dc8efc5d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +[*.cs] + +# Default severity for analyzer diagnostics with category 'Style' +dotnet_analyzer_diagnostic.category-Style.severity = none + +# CS0649: 从未对字段“TransactionalAttribute._uowManager”赋值,字段将一直保持其默认值 null +dotnet_diagnostic.CS0649.severity = none diff --git a/Examples/aspnetcore_transaction/TransactionalAttribute.cs b/Examples/aspnetcore_transaction/TransactionalAttribute.cs index 2dd58ad2..875e03df 100644 --- a/Examples/aspnetcore_transaction/TransactionalAttribute.cs +++ b/Examples/aspnetcore_transaction/TransactionalAttribute.cs @@ -19,7 +19,9 @@ namespace FreeSql IsolationLevel? _IsolationLevelPriv; [DynamicProxyFromServices] +#pragma warning disable IDE0044 // 添加只读修饰符 UnitOfWorkManager _uowManager; +#pragma warning restore IDE0044 // 添加只读修饰符 IUnitOfWork _uow; public override Task Before(DynamicProxyBeforeArguments args) => OnBefore(_uowManager); diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj index 6a13bfe0..ee51821c 100644 --- a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj @@ -1,23 +1,24 @@  - - netcoreapp3.1 - + + net5.0 + - - aspnetcore_transaction.xml - 3 - + + aspnetcore_transaction.xml + 3 + 1701;1702;1591 + - - - - - + + + + + + + + + + - - - - - diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index b2bcd550..aab00eea 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -1,31 +1,32 @@  - - Exe - netcoreapp3.1 - + + Exe + net5.0 + - - base_entity.xml - 3 - + + base_entity.xml + 3 + 1701;1702;1591 + - - - + + + - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/Examples/benchmarker/benchmarker.csproj b/Examples/benchmarker/benchmarker.csproj index 0a83a6e9..57d35001 100644 --- a/Examples/benchmarker/benchmarker.csproj +++ b/Examples/benchmarker/benchmarker.csproj @@ -2,17 +2,17 @@ Exe - netcoreapp3.1 + net5.0 - + - + diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj index 5a84476d..2b5846c8 100644 --- a/Examples/dbcontext_01/dbcontext_01.csproj +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -1,19 +1,19 @@  - - netcoreapp3.1 - InProcess - + + net5.0 + InProcess + - - - + + + - - - - - - + + + + + + diff --git a/Examples/efcore_to_freesql/efcore_to_freesql.csproj b/Examples/efcore_to_freesql/efcore_to_freesql.csproj index e6a6a3fb..738b47d0 100644 --- a/Examples/efcore_to_freesql/efcore_to_freesql.csproj +++ b/Examples/efcore_to_freesql/efcore_to_freesql.csproj @@ -1,18 +1,18 @@  - - netcoreapp3.1 - InProcess - + + net5.0 + InProcess + - - - + + + - - - - - + + + + + diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 5de46db7..262b9816 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -18,8 +18,8 @@ namespace orm_vs class Program { static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") - //.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=20") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=20") + .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=20") //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=20") .UseAutoSyncStructure(false) .UseNoneCommandParameter(true) @@ -30,10 +30,10 @@ namespace orm_vs { get => new SqlSugarClient(new ConnectionConfig() { - ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", - DbType = DbType.SqlServer, - //ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", - //DbType = DbType.MySql, + //ConnectionString = "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=20;Max Pool Size=20", + //DbType = DbType.SqlServer, + ConnectionString = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20", + DbType = DbType.MySql, //ConnectionString = "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=21", //DbType = DbType.PostgreSQL, IsAutoCloseConnection = true, @@ -46,8 +46,8 @@ namespace orm_vs public DbSet Songs { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); - //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); + //optionsBuilder.UseSqlServer(@"Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Min Pool Size=21;Max Pool Size=21"); + optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); //optionsBuilder.UseNpgsql("Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=21"); } @@ -481,11 +481,11 @@ namespace orm_vs { using (var db = new SongContext()) { - db.Songs.Take(size).AsNoTracking().ToList(); + //db.Songs.Take(size).AsNoTracking().ToList(); } } sw.Stop(); - sb.AppendLine($"EFCore Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms"); + sb.AppendLine($"EFCore Select {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms .net5.0无效"); sw.Restart(); using (var conn = fsql.Ado.MasterPool.Get()) @@ -513,8 +513,8 @@ namespace orm_vs using (var db = new SongContext()) { //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.AddRange(songs.First()); - db.SaveChanges(); + //db.Songs.AddRange(songs.First()); + //db.SaveChanges(); //.net5.0 throw Microsoft.EntityFrameworkCore.DbUpdateException } Stopwatch sw = new Stopwatch(); @@ -552,12 +552,12 @@ namespace orm_vs using (var db = new SongContext()) { //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.AddRange(songs.ToArray()); - db.SaveChanges(); + //db.Songs.AddRange(songs.ToArray()); + //db.SaveChanges(); //.net5.0 throw Microsoft.EntityFrameworkCore.DbUpdateException } } sw.Stop(); - sb.AppendLine($"EFCore Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); + sb.AppendLine($"EFCore Insert {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms .net5.0无效\r\n"); } static void Update(StringBuilder sb, int forTime, int size) @@ -599,12 +599,12 @@ namespace orm_vs using (var db = new SongContext()) { //db.Configuration.AutoDetectChangesEnabled = false; - db.Songs.UpdateRange(songs.ToArray()); - db.SaveChanges(); + //db.Songs.UpdateRange(songs.ToArray()); + //db.SaveChanges(); } } sw.Stop(); - sb.AppendLine($"EFCore Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms\r\n"); + sb.AppendLine($"EFCore Update {size}条数据,循环{forTime}次,耗时{sw.ElapsedMilliseconds}ms .net5.0无效\r\n"); } } diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index 1a49a72a..a7a240e4 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -1,29 +1,29 @@  - - Exe - netcoreapp3.1 - + + Exe + net5.0 + - - - - - - - + + + + + + + - - - - - - + + + + + + - - - ..\..\..\..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.entityframeworkcore\2.2.0\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll - - + + + ..\..\..\..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.entityframeworkcore\2.2.0\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll + + diff --git a/Examples/orm_vs_net40/orm_vs_net40.csproj b/Examples/orm_vs_net40/orm_vs_net40.csproj index 42978d4e..b26d2626 100644 --- a/Examples/orm_vs_net40/orm_vs_net40.csproj +++ b/Examples/orm_vs_net40/orm_vs_net40.csproj @@ -66,5 +66,10 @@ 12.0.3 + + + .editorconfig + + \ No newline at end of file diff --git a/Examples/repository_01/repository_01.csproj b/Examples/repository_01/repository_01.csproj index fce8cda4..117523d1 100644 --- a/Examples/repository_01/repository_01.csproj +++ b/Examples/repository_01/repository_01.csproj @@ -1,18 +1,18 @@  - netcoreapp3.1 + net5.0 InProcess - + - - - + + + diff --git a/Examples/restful/restful.csproj b/Examples/restful/restful.csproj index 67461b06..9cdfdeff 100644 --- a/Examples/restful/restful.csproj +++ b/Examples/restful/restful.csproj @@ -1,17 +1,17 @@  - netcoreapp3.1 + net5.0 InProcess - + - - + + diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d7d057de..09c9a53f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -19,7 +19,7 @@ - + diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 59074358..77905329 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -1,56 +1,55 @@  - - netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1109 - true - FreeSql;ncc;YeXiangQin - FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access - https://github.com/2881099/FreeSql/wiki/DbContext - FreeSql ORM DbContext - git - MIT - $(AssemblyName) - logo.png - $(AssemblyName) - true - true - true - key.snk - false - + + netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 + 2.0.0-preview1109 + true + FreeSql;ncc;YeXiangQin + FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access + https://github.com/2881099/FreeSql/wiki/DbContext + FreeSql ORM DbContext + git + MIT + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + true + key.snk + false + - - - - - - FreeSql.DbContext.xml - 3 - + + + - - net40 - - - netcoreapp - - - - - - - - - - - - - - + + FreeSql.DbContext.xml + 3 + 1701;1702;1591 + - - - + + net40 + + + netcoreapp + + + + + + + + + + + + + + + + diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -502,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 7dea638a..6f0acb92 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -99,7 +99,9 @@ namespace FreeSql catch (Exception ex) { _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "失败", ex)); +#pragma warning disable CA2200 // 再次引发以保留堆栈详细信息 throw ex; +#pragma warning restore CA2200 // 再次引发以保留堆栈详细信息 } return _tran; } @@ -123,7 +125,9 @@ namespace FreeSql { if (isCommited == false) _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "提交失败", ex)); +#pragma warning disable CA2200 // 再次引发以保留堆栈详细信息 throw ex; +#pragma warning restore CA2200 // 再次引发以保留堆栈详细信息 } finally { @@ -147,7 +151,9 @@ namespace FreeSql { if (isRollbacked == false) _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "回滚失败", ex)); +#pragma warning disable CA2200 // 再次引发以保留堆栈详细信息 throw ex; +#pragma warning restore CA2200 // 再次引发以保留堆栈详细信息 } finally { diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 9fd60073..b9b3403e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -1,31 +1,31 @@  - - netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 - 2.0.0-preview1109 - FreeSql;ncc;YeXiangQin - FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. - https://github.com/2881099/FreeSql/wiki/Repository - FreeSql ORM Repository - true - git - MIT - $(AssemblyName) - logo.png - $(AssemblyName) - true - true - true - key.snk - false - + + netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 + 2.0.0-preview1109 + FreeSql;ncc;YeXiangQin + FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. + https://github.com/2881099/FreeSql/wiki/Repository + FreeSql ORM Repository + true + git + MIT + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + true + key.snk + false + - - - - - - - + + + + + + + diff --git a/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj b/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj index ef69f571..82e4790d 100644 --- a/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj +++ b/FreeSql.Tests.VB/FreeSql.Tests.VB.vbproj @@ -2,16 +2,22 @@ FreeSql.Tests.VB - netcoreapp3.1 + net5.0 false - - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj index a0c1aeda..a5199d85 100644 --- a/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj +++ b/FreeSql.Tests/FreeSql.Tests.DbContext/FreeSql.Tests.DbContext.csproj @@ -1,29 +1,33 @@  - - netcoreapp3.1 + + net5.0 + false + - false - + + 3 + 1701;1702;1591 + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + - - - - - - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj index c86a28d6..4e2c84a2 100644 --- a/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj @@ -1,29 +1,34 @@  - - netcoreapp3.1 + + net5.0 - false - + false + - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + 3 + 1701;1702;1591 + - - - - - - - - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj index 07efc1f8..dd790895 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/FreeSql.Tests.Provider.MySqlConnector.csproj @@ -1,25 +1,30 @@  - - netcoreapp3.1 + + net5.0 - false - + false + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + 3 + 1701;1702;1591 + - - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj index 6aded025..c6dc638d 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/FreeSql.Tests.Provider.Odbc.csproj @@ -1,27 +1,31 @@  - - netcoreapp3.1 + + net5.0 - false - + false + - - FreeSql.Tests.Provider.Odbc.xml - 3 - + + FreeSql.Tests.Provider.Odbc.xml + 3 + 1701;1702;1591 + - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - - - - + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj index 04119115..651c636c 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj +++ b/FreeSql.Tests/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite/FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite.csproj @@ -1,25 +1,30 @@  - - netcoreapp3.1 + + net5.0 - false - + false + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + 3 + 1701;1702;1591 + - - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 0d018a86..e67d2aa5 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -1,26 +1,26 @@  - netcoreapp3.1 - + net5.0 false - FreeSql.Tests.xml - 3 - false - x86 + FreeSql.Tests.xml + 3 + 1701;1702;1591 + false + x86 - + - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b142a887..e2f0deeb 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,21 +21,18 @@ false - - - - - - - + + + - FreeSql.xml - 3 + FreeSql.xml + 3 + 1701;1702;1591 - - net40 - - + + net40 + + diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 03c420d8..17810cc7 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -1,50 +1,50 @@  - - netstandard2.0;net45;net40 - 2.0.0-preview1109 - true - FreeSql;ncc;YeXiangQin - FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) - https://github.com/2881099/FreeSql - https://github.com/2881099/FreeSql - git - MIT - FreeSql;ORM;DM8;Dameng;达梦 - $(AssemblyName) - logo.png - $(AssemblyName) - true - true - + + netstandard2.0;net45;net40 + 2.0.0-preview1109 + true + FreeSql;ncc;YeXiangQin + FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM;DM8;Dameng;达梦 + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + - - - - - - - Always - - + + + + + + + Always + + - - - + + + - - - lib\DmProvider\netstandard2.0\DmProvider.dll - false - - + + + lib\DmProvider\netstandard2.0\DmProvider.dll + false + + + + + ns20;netstandard20 + + + net40 + - - ns20;netstandard20 - - - net40 - - - + diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index c00a9a3c..3a7f7690 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1109 + 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird @@ -12,7 +12,7 @@ MIT FreeSql;ORM;Firebird;火鸟 $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,16 +21,16 @@ false - - - + + + - - - + + + - - - + + + diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index daaaf0a3..09125c62 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net461 + netstandard2.0;net461 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin @@ -12,34 +12,34 @@ MIT FreeSql;ORM;人大金仓;金仓;Kdbndp $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true - - - - - - Always - - + + + + + + Always + + - - - + + + - - - lib\Kdbndp.dll - false - - + + + lib\Kdbndp.dll + false + + - - ns20;netstandard20 - + + ns20;netstandard20 + diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index a5a3647b..d47ddf37 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;Access $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,21 +21,21 @@ false - - - - - - - - - + - - - net40 - - + + + + + + + + + + + net40 + + - + diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 6c2b1f37..e33bc0a9 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;MySql;MariaDB;Tidb $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,24 +21,24 @@ false - - - - - - - - - - - - - + - - net40 - - + + + + + + + + + + + + + + net40 + + diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f9c87445..a450b62e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;MySql;MariaDB;Tidb $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,27 +21,27 @@ false - - - - - + + + + + - + - + - - MySqlConnector - - + + MySqlConnector + + diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 329f36cb..83aaa64b 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;Odbc $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,21 +21,21 @@ false - - - - - - - - - + - - - net40 - - + + + + + + + + + + + net40 + + - + diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 36ff42f7..da2baff1 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;Oracle $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,25 +21,25 @@ false - - - - + + + + - + - + - + - - net40 - - + + net40 + + - + diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 03a42283..e26ef931 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;PostgreSQL;pgsql $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,33 +21,33 @@ false - - - - - - - - - - - - - - - - - - net45 - - - - nts - - - - + - + + + + + + + + + + + + + + + + net45 + + + + nts + + + + + + diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index c41bb2db..748e0c04 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45;net40 + netstandard2.0;net45;net40 2.0.0-preview1109 true FreeSql;ncc;YeXiangQin @@ -12,41 +12,41 @@ MIT FreeSql;ORM;ShenTong;Oscar;神通;神舟通用 $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true - - - - - - - - - - Always - - + + + + + + + + + + Always + + - - - + + + - - - lib\System.Data.OscarClient.dll - false - - + + + lib\System.Data.OscarClient.dll + false + + - - ns20;netstandard20 - - - net40 - + + ns20;netstandard20 + + + net40 + diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 47166f17..3693d6e8 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;SqlServer;mssql $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,26 +21,26 @@ key.snk - - - - - - - - - - - - + - - microsoft - - - net40 - - + + + + + + + + + + + + + microsoft + + + net40 + + diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index b7fade71..6330b3e3 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;SqlServer;mssql $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,24 +21,24 @@ false - - - - - - - + + + + + + + - + - - net40 - - + + net40 + + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 33e2e388..97accd42 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -12,7 +12,7 @@ MIT FreeSql;ORM;sqlite $(AssemblyName) - logo.png + logo.png $(AssemblyName) true true @@ -21,23 +21,23 @@ false - - - - - - + + - + - - ns20;netstandard20 - - - net40 - - + + + + + + ns20;netstandard20 + + + net40 + + From dad05d83c9827fbc7043e338ad0a171d93d4b5cb Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 04:43:10 +0800 Subject: [PATCH 0990/1029] test record class --- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index 4538707a..672b4cdf 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -10,10 +10,23 @@ namespace FreeSql.Tests { public class UnitTest4 { + + public record ts_record(DateTime Date, int TemperatureC, int TemperatureF, string Summary) + { + public ts_record parent { get; set; } + } + [Fact] public void LeftJoinNull01() { var fsql = g.sqlite; + + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new ts_record(DateTime.Now, 1, 2, "123")).ExecuteAffrows(); + var fores = fsql.Select().ToList(); + + + fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Delete().Where("1=1").ExecuteAffrows(); From 4ef38817ffdf5b623332cdcf7a0ef239e882ec5a Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 05:11:05 +0800 Subject: [PATCH 0991/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=B1=BB=E6=8B=A5=E6=9C=89=E6=9E=84=E9=80=A0=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=97=B6=EF=BC=8CToList\=20=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=97=A0=E6=95=88=E7=9A=84=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 3 +++ FreeSql/Internal/CommonExpression.cs | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index 672b4cdf..09bce801 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -15,6 +15,7 @@ namespace FreeSql.Tests { public ts_record parent { get; set; } } + public record ts_record_dto(DateTime Date, int TemperatureC, string Summary); [Fact] public void LeftJoinNull01() @@ -24,6 +25,8 @@ namespace FreeSql.Tests fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Insert(new ts_record(DateTime.Now, 1, 2, "123")).ExecuteAffrows(); var fores = fsql.Select().ToList(); + var fores_dtos1 = fsql.Select().ToList(); + var fores_dtos2 = fsql.Select().ToList(a => new ts_record_dto(a.Date, a.TemperatureC, a.Summary)); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 0952cf1f..b173c125 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -273,9 +273,9 @@ namespace FreeSql.Internal { if (a.NodeType != ExpressionType.Constant) return true; var constVal = (a as ConstantExpression)?.Value; - if (constVal == null) return true; - if (object.Equals(constVal, a.Type.CreateInstanceGetDefaultValue()) == false) return true; - return false; + if (constVal == null) return false; //- 修复 实体类拥有构造参数时,ToList\ 映射查询无效的 bug; + if (object.Equals(constVal, a.Type.CreateInstanceGetDefaultValue())) return false; + return true; }) )) { From 16642296f38e3d9eab9e17cca5ebbe9747c2601e Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 05:21:23 +0800 Subject: [PATCH 0992/1029] v2.0.0-preview1112 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---------------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 22 insertions(+), 38 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 4a87cb9a..cd70c641 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 8fdb957a..c3e53b66 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ffa64be2..14be0c61 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index cdecbacc..d0488ca6 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 09c9a53f..ba322436 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1109 + 2.0.0-preview1112 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index ddf637e8..afd6f56c 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 77905329..a15331b6 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -509,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index b9b3403e..7a49741b 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index e2f0deeb..b1e30b18 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 17810cc7..e5f44ac8 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 3a7f7690..eb1b1f2f 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 09125c62..7cf7f2b2 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index d47ddf37..d7bf96db 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index e33bc0a9..d186d1b4 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a450b62e..0c1302c2 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 83aaa64b..04363b6a 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index da2baff1..46d8f965 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e26ef931..e7dac034 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 748e0c04..fcb73c5b 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 3693d6e8..89a3c444 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 6330b3e3..dda58e2e 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 97accd42..5f3cf863 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1109 + 2.0.0-preview1112 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 2222fa269ea0038325cee60587ef9689f0b57751 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 05:32:36 +0800 Subject: [PATCH 0993/1029] update Aggregate tests --- FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index 7eebc719..762ed3a1 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -813,9 +813,13 @@ namespace FreeSql.Tests.Dameng { var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - select + var sel1 = select .Aggregate(a => new { sum = a.Sum(a.Key.Id), count = a.Count() }, out var output) .ToList(); + + var sel2 = select + .Aggregate(a => Convert.ToInt32("count(distinct title)"), out var output2) + .ToList(); } [Fact] public void OrderBy() From 8bbb7329f979ea8b976c58667140f084cb822c25 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 06:35:29 +0800 Subject: [PATCH 0994/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Async=20Canc?= =?UTF-8?q?ellationToken=20IInsert/IUdate/IInsertOrUpdate=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/FreeSql.xml | 34 ++-- FreeSql/Interface/Curd/IInsert.cs | 7 +- FreeSql/Interface/Curd/IInsertOrUpdate.cs | 3 +- FreeSql/Interface/Curd/IUpdate.cs | 5 +- FreeSql/Interface/IAdo.cs | 137 ++++++------- .../AdoProvider/AdoProviderAsync.cs | 187 +++++++++--------- .../CommonProvider/InsertOrUpdateProvider.cs | 15 +- .../CommonProvider/InsertProviderAsync.cs | 43 ++-- .../CommonProvider/UpdateProviderAsync.cs | 27 +-- FreeSql/Internal/Model/AdoCommandFluent.cs | 21 +- .../Curd/DamengInsert.cs | 17 +- .../Curd/DamengUpdate.cs | 7 +- .../Curd/FirebirdInsert.cs | 21 +- .../Curd/FirebirdUpdate.cs | 9 +- .../Curd/KingbaseESInsert.cs | 17 +- .../Curd/KingbaseESUpdate.cs | 9 +- .../Curd/MsAccessInsert.cs | 25 +-- .../Curd/MsAccessUpdate.cs | 7 +- .../Curd/MySqlInsert.cs | 15 +- .../Curd/MySqlUpdate.cs | 9 +- .../Dameng/Curd/OdbcDamengInsert.cs | 17 +- .../Dameng/Curd/OdbcDamengUpdate.cs | 7 +- .../Default/Curd/OdbcInsert.cs | 15 +- .../Default/Curd/OdbcUpdate.cs | 7 +- .../KingbaseES/Curd/OdbcKingbaseESInsert.cs | 17 +- .../KingbaseES/Curd/OdbcKingbaseESUpdate.cs | 9 +- .../MySql/Curd/OdbcMySqlInsert.cs | 17 +- .../MySql/Curd/OdbcMySqlUpdate.cs | 9 +- .../Oracle/Curd/OdbcOracleInsert.cs | 17 +- .../Oracle/Curd/OdbcOracleUpdate.cs | 7 +- .../PostgreSQL/Curd/OdbcPostgreSQLInsert.cs | 17 +- .../PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs | 9 +- .../SqlServer/Curd/OdbcSqlServerInsert.cs | 15 +- .../SqlServer/Curd/OdbcSqlServerUpdate.cs | 9 +- .../Curd/OracleInsert.cs | 17 +- .../Curd/OracleUpdate.cs | 7 +- .../Curd/PostgreSQLInsert.cs | 17 +- .../Curd/PostgreSQLUpdate.cs | 9 +- .../Curd/ShenTongInsert.cs | 17 +- .../Curd/ShenTongUpdate.cs | 9 +- .../Curd/SqlServerInsert.cs | 15 +- .../Curd/SqlServerUpdate.cs | 9 +- .../Curd/SqliteInsert.cs | 15 +- .../Curd/SqliteUpdate.cs | 7 +- 45 files changed, 492 insertions(+), 433 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -502,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3d1bfc1b..751d06c0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3013,7 +3013,7 @@ - + 测试数据库是否连接正确,本方法执行如下命令: MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 @@ -3022,7 +3022,7 @@ 命令超时设置(秒) true: 成功, false: 失败 - + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 @@ -3031,7 +3031,7 @@ - + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3039,14 +3039,14 @@ - + 查询 - + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3055,14 +3055,14 @@ - + 查询 - + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3071,14 +3071,14 @@ - + 查询 - + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3087,7 +3087,7 @@ - + 在【主库】执行 @@ -3095,7 +3095,7 @@ - + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3104,7 +3104,7 @@ - + 在【主库】执行 @@ -3112,7 +3112,7 @@ - + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3121,7 +3121,7 @@ - + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -3131,7 +3131,7 @@ - + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3141,7 +3141,7 @@ - + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -3151,7 +3151,7 @@ - + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 234495ae..4cbcfd8c 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -157,9 +158,9 @@ namespace FreeSql #if net40 #else - Task ExecuteAffrowsAsync(); - Task ExecuteIdentityAsync(); - Task> ExecuteInsertedAsync(); + Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); + Task ExecuteIdentityAsync(CancellationToken cancellationToken = default); + Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default); #endif } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/IInsertOrUpdate.cs b/FreeSql/Interface/Curd/IInsertOrUpdate.cs index 0299d065..f2926980 100644 --- a/FreeSql/Interface/Curd/IInsertOrUpdate.cs +++ b/FreeSql/Interface/Curd/IInsertOrUpdate.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data.Common; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -86,7 +87,7 @@ namespace FreeSql #if net40 #else - Task ExecuteAffrowsAsync(); + Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); #endif } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 004939c3..87a372f7 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -249,8 +250,8 @@ namespace FreeSql #if net40 #else - Task ExecuteAffrowsAsync(); - Task> ExecuteUpdatedAsync(); + Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); + Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default); #endif } } \ No newline at end of file diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 69ce18f9..7e8f53f1 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -274,7 +275,7 @@ namespace FreeSql /// /// 命令超时设置(秒) /// true: 成功, false: 失败 - Task ExecuteConnectTestAsync(int commandTimeout = 0); + Task ExecuteConnectTestAsync(int commandTimeout = 0, CancellationToken cancellationToken = default); /// /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 @@ -283,26 +284,26 @@ namespace FreeSql /// /// /// - Task ExecuteReaderAsync(Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(Func, Task> readerHander, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// /// - Task ExecuteReaderAsync(Func, Task> readerHander, string cmdText, object parms = null); - Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null); - Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(Func, Task> readerHander, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 查询 /// /// /// - Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task ExecuteArrayAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -310,17 +311,17 @@ namespace FreeSql /// /// /// - Task ExecuteArrayAsync(string cmdText, object parms = null); - Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteArrayAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 查询 /// /// /// - Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -328,17 +329,17 @@ namespace FreeSql /// /// /// - Task ExecuteDataSetAsync(string cmdText, object parms = null); - Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteDataSetAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 查询 /// /// /// - Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -346,18 +347,18 @@ namespace FreeSql /// /// /// - Task ExecuteDataTableAsync(string cmdText, object parms = null); - Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteDataTableAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 在【主库】执行 /// /// /// /// - Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -365,18 +366,18 @@ namespace FreeSql /// /// /// - Task ExecuteNonQueryAsync(string cmdText, object parms = null); - Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteNonQueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 在【主库】执行 /// /// /// /// - Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task ExecuteScalarAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -384,9 +385,9 @@ namespace FreeSql /// /// /// - Task ExecuteScalarAsync(string cmdText, object parms = null); - Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null); - Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task ExecuteScalarAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -396,10 +397,10 @@ namespace FreeSql /// /// /// - Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); - Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -408,9 +409,9 @@ namespace FreeSql /// /// /// - Task> QueryAsync(string cmdText, object parms = null); - Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -420,9 +421,9 @@ namespace FreeSql /// /// /// - Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + Task, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -431,28 +432,28 @@ namespace FreeSql /// /// /// - Task, List>> QueryAsync(string cmdText, object parms = null); - Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); - Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); - Task, List, List>> QueryAsync(string cmdText, object parms = null); - Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); - Task, List, List, List>> QueryAsync(string cmdText, object parms = null); - Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); - Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); - Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); - Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null); - Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); - Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); #endregion #endif } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 1ff333fb..f6d6bab5 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; #if net40 @@ -14,7 +15,7 @@ namespace FreeSql.Internal.CommonProvider { partial class AdoProvider { - async public Task ExecuteConnectTestAsync(int commandTimeout = 0) + async public Task ExecuteConnectTestAsync(int commandTimeout = 0, CancellationToken cancellationToken = default) { try { @@ -22,13 +23,13 @@ namespace FreeSql.Internal.CommonProvider { case DataType.Oracle: case DataType.OdbcOracle: - await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT 1 FROM dual", commandTimeout); + await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT 1 FROM dual", commandTimeout, null, cancellationToken); return true; case DataType.Firebird: - await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT FIRST 1 1 FROM rdb$database", commandTimeout); + await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT FIRST 1 1 FROM rdb$database", commandTimeout, null, cancellationToken); return true; } - await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT 1", commandTimeout); + await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT 1", commandTimeout, null, cancellationToken); return true; } catch @@ -37,13 +38,13 @@ namespace FreeSql.Internal.CommonProvider } } - public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, null, cmdType, cmdText, 0, cmdParms); - public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, transaction, cmdType, cmdText, 0, cmdParms); - public Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) => QueryAsync(null, connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms); - async public Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); + async public Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { var ret = new List(); if (string.IsNullOrEmpty(cmdText)) return ret; @@ -70,16 +71,16 @@ namespace FreeSql.Internal.CommonProvider } ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(flag, type, indexes, fetch.Object, 0, _util).Value); return Task.FromResult(false); - }, cmdType, cmdText, cmdTimeout, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return ret; } #region QueryAsync multi - public Task, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List()); var ret1 = new List(); @@ -133,16 +134,16 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, null, cmdType, cmdText, cmdTimeout, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return NativeTuple.Create(ret1, ret2); } - public Task, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task, List, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List()); var ret1 = new List(); @@ -219,16 +220,16 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, null, cmdType, cmdText, cmdTimeout, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return NativeTuple.Create(ret1, ret2, ret3); } - public Task, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task, List, List, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List()); var ret1 = new List(); @@ -328,16 +329,16 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, null, cmdType, cmdText, cmdTimeout, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return NativeTuple.Create(ret1, ret2, ret3, ret4); } - public Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task, List, List, List, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task, List, List, List, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task, List, List, List, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => QueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task, List, List, List, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(cmdText)) return NativeTuple.Create(new List(), new List(), new List(), new List(), new List()); var ret1 = new List(); @@ -460,18 +461,18 @@ namespace FreeSql.Internal.CommonProvider break; } return Task.FromResult(false); - }, null, cmdType, cmdText, cmdTimeout, cmdParms); + }, null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return NativeTuple.Create(ret1, ret2, ret3, ret4, ret5); } #endregion - public Task ExecuteReaderAsync(Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, null, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(null, transaction, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null) => ExecuteReaderAsync(connection, transaction, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteReaderAsync(Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms); - public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms); - public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms); - async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task ExecuteReaderAsync(Func, Task> fetchHandler, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, null, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, transaction, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteReaderAsync(connection, transaction, fetchHandler, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteReaderAsync(Func, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); + async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func, int, Task> fetchHandler, Action schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; @@ -501,7 +502,7 @@ namespace FreeSql.Internal.CommonProvider } Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt, cancellationToken); if (IsTracePerformance) { logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); @@ -534,7 +535,7 @@ namespace FreeSql.Internal.CommonProvider LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); - await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, fetchHandler, schemaHandler, cmdType, cmdText, cmdTimeout, cmdParms); + await ExecuteReaderMultipleAsync(multipleResult, connection, transaction, fetchHandler, schemaHandler, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return; } } @@ -548,7 +549,7 @@ namespace FreeSql.Internal.CommonProvider logtxt.Append("Pool.Get: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); logtxt_dt = DateTime.Now; } - using (var dr = await pc.cmd.ExecuteReaderAsync()) + using (var dr = await pc.cmd.ExecuteReaderAsync(cancellationToken)) { int resultIndex = 0; var fetch = new FetchCallbackArgs { Object = dr }; @@ -557,7 +558,7 @@ namespace FreeSql.Internal.CommonProvider bool isfirst = true; while (true) { - bool isread = await dr.ReadAsync(); + bool isread = await dr.ReadAsync(cancellationToken); if (schemaHandler != null && isfirst) { isfirst = false; @@ -600,36 +601,36 @@ namespace FreeSql.Internal.CommonProvider pc.cmd.Parameters.Clear(); if (DataType == DataType.Sqlite) pc.cmd.Dispose(); } - public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task ExecuteArrayAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteArrayAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteArrayAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteArrayAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteArrayAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteArrayAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { List ret = new List(); await ExecuteReaderAsync(connection, transaction, async fetch => { object[] values = new object[fetch.Object.FieldCount]; - for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a, cancellationToken)) values[a] = await fetch.Object.GetFieldValueAsync(a, cancellationToken); ret.Add(values); - }, cmdType, cmdText, cmdTimeout, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return ret.ToArray(); } - public Task ExecuteDataSetAsync(string cmdText, object parms = null) => ExecuteDataSetAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataSetAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataSetAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task ExecuteDataSetAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteDataSetAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteDataSetAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteDataSetAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteDataSetAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteDataSetAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { var ret = new DataSet(); DataTable dt = null; await ExecuteReaderMultipleAsync(16, connection, transaction, async (fetch, result) => { object[] values = new object[dt.Columns.Count]; - for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a, cancellationToken)) values[a] = await fetch.Object.GetFieldValueAsync(a, cancellationToken); dt.Rows.Add(values); }, (dr, result) => { @@ -640,21 +641,21 @@ namespace FreeSql.Internal.CommonProvider if (dt.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; dt.Columns.Add(name, dr.GetFieldType(a)); } - }, cmdType, cmdText, cmdTimeout, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return ret; } - public Task ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task ExecuteDataTableAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteDataTableAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteDataTableAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteDataTableAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteDataTableAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteDataTableAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { var ret = new DataTable(); await ExecuteReaderMultipleAsync(1, connection, transaction, async (fetch, result) => { object[] values = new object[ret.Columns.Count]; - for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a)) values[a] = await fetch.Object.GetFieldValueAsync(a); + for (int a = 0; a < values.Length; a++) if (!await fetch.Object.IsDBNullAsync(a, cancellationToken)) values[a] = await fetch.Object.GetFieldValueAsync(a, cancellationToken); ret.Rows.Add(values); }, (dr, result) => { @@ -664,28 +665,28 @@ namespace FreeSql.Internal.CommonProvider if (ret.Columns.Contains(name)) name = $"{name}_{Guid.NewGuid().ToString("N").Substring(0, 4)}"; ret.Columns.Add(name, dr.GetFieldType(a)); } - }, cmdType, cmdText, cmdTimeout, cmdParms); + }, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); return ret; } - public Task ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task ExecuteNonQueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteNonQueryAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteNonQueryAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteNonQueryAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteNonQueryAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteNonQueryAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(cmdText)) return 0; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt, cancellationToken); int val = 0; Exception ex = null; try { if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await this.MasterPool.GetAsync()).Value; - val = await pc.cmd.ExecuteNonQueryAsync(); + val = await pc.cmd.ExecuteNonQueryAsync(cancellationToken); } catch (Exception ex2) { @@ -703,25 +704,25 @@ namespace FreeSql.Internal.CommonProvider if (DataType == DataType.Sqlite) pc.cmd.Dispose(); return val; } - public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); - public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, null, cmdType, cmdText, 0, cmdParms); - public Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, transaction, cmdType, cmdText, 0, cmdParms); - async public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) + public Task ExecuteScalarAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteScalarAsync(null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteScalarAsync(null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => ExecuteScalarAsync(connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); + public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteScalarAsync(null, null, cmdType, cmdText, 0, cmdParms, cancellationToken); + public Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteScalarAsync(null, transaction, cmdType, cmdText, 0, cmdParms, cancellationToken); + async public Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(cmdText)) return null; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt); + var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdTimeout, cmdParms, logtxt, cancellationToken); object val = null; Exception ex = null; try { if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = await this.MasterPool.GetAsync()).Value; - val = await pc.cmd.ExecuteScalarAsync(); + val = await pc.cmd.ExecuteScalarAsync(cancellationToken); } catch (Exception ex2) { @@ -740,7 +741,7 @@ namespace FreeSql.Internal.CommonProvider return val; } - async Task PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, StringBuilder logtxt) + async Task PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, StringBuilder logtxt, CancellationToken cancellationToken = default) { DateTime dt = DateTime.Now; DbCommand cmd = CreateCommand(); @@ -774,7 +775,7 @@ namespace FreeSql.Internal.CommonProvider if (connection.State != ConnectionState.Open) { if (IsTracePerformance) dt = DateTime.Now; - await connection.OpenAsync(); + await connection.OpenAsync(cancellationToken); if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpen: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); isclose = true; } diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index d2ed7a35..270dc44e 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider @@ -292,7 +293,7 @@ namespace FreeSql.Internal.CommonProvider } #if net40 #else - async public Task RawExecuteAffrowsAsync() + async public Task RawExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -302,7 +303,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -316,7 +317,7 @@ namespace FreeSql.Internal.CommonProvider } return affrows; } - async public Task ExecuteAffrowsAsync() + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var affrows = 0; var ss = SplitSourceByIdentityValueIsNull(_source); @@ -332,10 +333,10 @@ namespace FreeSql.Internal.CommonProvider { _source = ss.Item1; _SplitSourceByIdentityValueIsNullFlag = 1; - affrows += await this.RawExecuteAffrowsAsync(); + affrows += await this.RawExecuteAffrowsAsync(cancellationToken); _source = ss.Item2; _SplitSourceByIdentityValueIsNullFlag = 2; - affrows += await this.RawExecuteAffrowsAsync(); + affrows += await this.RawExecuteAffrowsAsync(cancellationToken); } else { @@ -348,10 +349,10 @@ namespace FreeSql.Internal.CommonProvider { _source = ss.Item1; _SplitSourceByIdentityValueIsNullFlag = 1; - affrows += await this.RawExecuteAffrowsAsync(); + affrows += await this.RawExecuteAffrowsAsync(cancellationToken); _source = ss.Item2; _SplitSourceByIdentityValueIsNullFlag = 2; - affrows += await this.RawExecuteAffrowsAsync(); + affrows += await this.RawExecuteAffrowsAsync(cancellationToken); _transaction.Commit(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); } diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index 0cc8ac76..b1123aa7 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -7,6 +7,7 @@ using System.Data.Common; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider @@ -16,7 +17,7 @@ namespace FreeSql.Internal.CommonProvider { #if net40 #else - async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) + async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default) { var ss = SplitSource(valuesLimit, parameterLimit); var ret = 0; @@ -28,7 +29,7 @@ namespace FreeSql.Internal.CommonProvider if (ss.Length == 1) { _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = await this.RawExecuteAffrowsAsync(); + ret = await this.RawExecuteAffrowsAsync(cancellationToken); ClearData(); return ret; } @@ -49,7 +50,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret += await this.RawExecuteAffrowsAsync(); + ret += await this.RawExecuteAffrowsAsync(cancellationToken); } } else @@ -66,7 +67,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret += await this.RawExecuteAffrowsAsync(); + ret += await this.RawExecuteAffrowsAsync(cancellationToken); } _transaction.Commit(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); @@ -95,7 +96,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async protected Task SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit) + async protected Task SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default) { var ss = SplitSource(valuesLimit, parameterLimit); long ret = 0; @@ -107,7 +108,7 @@ namespace FreeSql.Internal.CommonProvider if (ss.Length == 1) { _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = await this.RawExecuteIdentityAsync(); + ret = await this.RawExecuteIdentityAsync(cancellationToken); ClearData(); return ret; } @@ -128,8 +129,8 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); - else ret = await this.RawExecuteIdentityAsync(); + if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(cancellationToken); + else ret = await this.RawExecuteIdentityAsync(cancellationToken); } } else @@ -146,8 +147,8 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(); - else ret = await this.RawExecuteIdentityAsync(); + if (a < ss.Length - 1) await this.RawExecuteAffrowsAsync(cancellationToken); + else ret = await this.RawExecuteIdentityAsync(cancellationToken); } _transaction.Commit(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); @@ -176,7 +177,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async protected Task> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) + async protected Task> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default) { var ss = SplitSource(valuesLimit, parameterLimit); var ret = new List(); @@ -188,7 +189,7 @@ namespace FreeSql.Internal.CommonProvider if (ss.Length == 1) { _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = await this.RawExecuteInsertedAsync(); + ret = await this.RawExecuteInsertedAsync(cancellationToken); ClearData(); return ret; } @@ -209,7 +210,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(await this.RawExecuteInsertedAsync()); + ret.AddRange(await this.RawExecuteInsertedAsync(cancellationToken)); } } else @@ -226,7 +227,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(await this.RawExecuteInsertedAsync()); + ret.AddRange(await this.RawExecuteInsertedAsync(cancellationToken)); } _transaction.Commit(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); @@ -255,7 +256,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async protected virtual Task RawExecuteAffrowsAsync() + async protected virtual Task RawExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = ToSql(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); @@ -264,7 +265,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -279,12 +280,12 @@ namespace FreeSql.Internal.CommonProvider return affrows; } - protected abstract Task RawExecuteIdentityAsync(); - protected abstract Task> RawExecuteInsertedAsync(); + protected abstract Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default); + protected abstract Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default); - public abstract Task ExecuteAffrowsAsync(); - public abstract Task ExecuteIdentityAsync(); - public abstract Task> ExecuteInsertedAsync(); + public abstract Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); + public abstract Task ExecuteIdentityAsync(CancellationToken cancellationToken = default); + public abstract Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default); #endif } } diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index 1b3d7756..55599457 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider @@ -17,14 +18,14 @@ namespace FreeSql.Internal.CommonProvider { #if net40 #else - async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) + async protected Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default) { var ss = SplitSource(valuesLimit, parameterLimit); var ret = 0; if (ss.Length <= 1) { if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = await this.RawExecuteAffrowsAsync(); + ret = await this.RawExecuteAffrowsAsync(cancellationToken); ClearData(); return ret; } @@ -45,7 +46,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret += await this.RawExecuteAffrowsAsync(); + ret += await this.RawExecuteAffrowsAsync(cancellationToken); } } else @@ -62,7 +63,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret += await this.RawExecuteAffrowsAsync(); + ret += await this.RawExecuteAffrowsAsync(cancellationToken); } _transaction.Commit(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); @@ -90,14 +91,14 @@ namespace FreeSql.Internal.CommonProvider ClearData(); return ret; } - async protected Task> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit) + async protected Task> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default) { var ss = SplitSource(valuesLimit, parameterLimit); var ret = new List(); if (ss.Length <= 1) { if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = await this.RawExecuteUpdatedAsync(); + ret = await this.RawExecuteUpdatedAsync(cancellationToken); ClearData(); return ret; } @@ -118,7 +119,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(await this.RawExecuteUpdatedAsync()); + ret.AddRange(await this.RawExecuteUpdatedAsync(cancellationToken)); } } else @@ -135,7 +136,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(await this.RawExecuteUpdatedAsync()); + ret.AddRange(await this.RawExecuteUpdatedAsync(cancellationToken)); } _transaction.Commit(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "提交", null)); @@ -164,7 +165,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async protected Task RawExecuteAffrowsAsync() + async protected Task RawExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -175,7 +176,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(affrows, sql, dbParms); } catch (Exception ex) @@ -190,10 +191,10 @@ namespace FreeSql.Internal.CommonProvider } return affrows; } - protected abstract Task> RawExecuteUpdatedAsync(); + protected abstract Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default); - public abstract Task ExecuteAffrowsAsync(); - public abstract Task> ExecuteUpdatedAsync(); + public abstract Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); + public abstract Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default); #endif } } diff --git a/FreeSql/Internal/Model/AdoCommandFluent.cs b/FreeSql/Internal/Model/AdoCommandFluent.cs index 8accc9aa..322f4e47 100644 --- a/FreeSql/Internal/Model/AdoCommandFluent.cs +++ b/FreeSql/Internal/Model/AdoCommandFluent.cs @@ -5,6 +5,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.Model @@ -98,16 +99,16 @@ namespace FreeSql.Internal.Model #if net40 #else - public Task ExecuteNonQueryAsync() => this.Ado.ExecuteNonQueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task ExecuteScalarAsync() => this.Ado.ExecuteScalarAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task ExecuteDataTableAsync() => this.Ado.ExecuteDataTableAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task ExecuteDataSetAsync() => this.Ado.ExecuteDataSetAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task ExecuteArrayAsync() => this.Ado.ExecuteArrayAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task, List>> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task, List, List>> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task, List, List, List>> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); - public Task, List, List, List, List>> QueryAsync() => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public Task ExecuteNonQueryAsync(CancellationToken cancellationToken = default) => this.Ado.ExecuteNonQueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task ExecuteScalarAsync(CancellationToken cancellationToken = default) => this.Ado.ExecuteScalarAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task ExecuteDataTableAsync(CancellationToken cancellationToken = default) => this.Ado.ExecuteDataTableAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task ExecuteDataSetAsync(CancellationToken cancellationToken = default) => this.Ado.ExecuteDataSetAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task ExecuteArrayAsync(CancellationToken cancellationToken = default) => this.Ado.ExecuteArrayAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task, List>> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task, List, List>> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task, List, List, List>> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + public Task, List, List, List, List>> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); #endif } } diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index e0e0173c..d07499a3 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Dameng.Curd @@ -153,11 +154,11 @@ namespace FreeSql.Dameng.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -172,7 +173,7 @@ namespace FreeSql.Dameng.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -195,7 +196,7 @@ namespace FreeSql.Dameng.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) @@ -210,13 +211,13 @@ namespace FreeSql.Dameng.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var ret = _source.ToList(); - await this.RawExecuteAffrowsAsync(); + await this.RawExecuteAffrowsAsync(cancellationToken); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs index c4b88741..3ab0bc8f 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengUpdate.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Dameng.Curd @@ -65,10 +66,10 @@ namespace FreeSql.Dameng.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync() + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs index 89d7cac4..e7140830 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Firebird.Curd @@ -123,19 +124,19 @@ namespace FreeSql.Firebird.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { base.NoneParameter(_source?.Count > 1); - return base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + return base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); } - public override Task ExecuteIdentityAsync() + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) { base.NoneParameter(_source?.Count > 1); - return base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + return base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); } - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1, 1000); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(1, 1000, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -151,7 +152,7 @@ namespace FreeSql.Firebird.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -170,7 +171,7 @@ namespace FreeSql.Firebird.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -184,7 +185,7 @@ namespace FreeSql.Firebird.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -206,7 +207,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs index 793554ff..ad701a6e 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Firebird.Curd @@ -99,10 +100,10 @@ namespace FreeSql.Firebird.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -125,7 +126,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs index 545c7c63..b012359d 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.KingbaseES @@ -122,11 +123,11 @@ namespace FreeSql.KingbaseES #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -142,7 +143,7 @@ namespace FreeSql.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -161,7 +162,7 @@ namespace FreeSql.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -175,7 +176,7 @@ namespace FreeSql.KingbaseES } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -197,7 +198,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs index cb086288..e31c0ba6 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.KingbaseES @@ -123,10 +124,10 @@ namespace FreeSql.KingbaseES #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -149,7 +150,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs index 9a31e8cc..464a3ff9 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.MsAccess.Curd @@ -102,11 +103,11 @@ namespace FreeSql.MsAccess.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1, 1000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(1, 1000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(1, 1000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(1, 1000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(1, 1000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(1, 1000, cancellationToken); - async protected override Task RawExecuteAffrowsAsync() + async protected override Task RawExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); @@ -115,7 +116,7 @@ namespace FreeSql.MsAccess.Curd Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -129,7 +130,7 @@ namespace FreeSql.MsAccess.Curd } return affrows; } - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -146,14 +147,14 @@ namespace FreeSql.MsAccess.Curd using (var conn = await _orm.Ado.MasterPool.GetAsync()) { _connection = conn.Value; - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _commandTimeout, _params)), out ret); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _commandTimeout, _params, cancellationToken)), out ret); } } else { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _commandTimeout, _params)), out ret); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, "SELECT @@identity", _commandTimeout, _params, cancellationToken)), out ret); } } catch (Exception ex) @@ -169,13 +170,13 @@ namespace FreeSql.MsAccess.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var ret = _source.ToList(); - await this.RawExecuteAffrowsAsync(); + await this.RawExecuteAffrowsAsync(cancellationToken); return ret; } #endif diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs index 47dcd294..04411b04 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.MsAccess.Curd @@ -68,10 +69,10 @@ namespace FreeSql.MsAccess.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(1, 1000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(1, 1000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(1, 1000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(1, 1000, cancellationToken); - protected override Task> RawExecuteUpdatedAsync() + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 74aacd75..23f8e59e 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.MySql.Curd @@ -106,11 +107,11 @@ namespace FreeSql.MySql.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -122,7 +123,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out var trylng) ? trylng : 0; + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -136,7 +137,7 @@ namespace FreeSql.MySql.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -158,7 +159,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index 659fa00d..e1196549 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.MySql.Curd @@ -106,10 +107,10 @@ namespace FreeSql.MySql.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -132,7 +133,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs index ac099657..96dce1fc 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Dameng @@ -153,11 +154,11 @@ namespace FreeSql.Odbc.Dameng #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -172,7 +173,7 @@ namespace FreeSql.Odbc.Dameng _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -195,7 +196,7 @@ namespace FreeSql.Odbc.Dameng _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) @@ -210,13 +211,13 @@ namespace FreeSql.Odbc.Dameng } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var ret = _source.ToList(); - await this.RawExecuteAffrowsAsync(); + await this.RawExecuteAffrowsAsync(cancellationToken); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs index 9f039209..451c40ef 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Dameng @@ -66,10 +67,10 @@ namespace FreeSql.Odbc.Dameng #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync() + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index 54c04672..4ff987f7 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Default @@ -65,11 +66,11 @@ namespace FreeSql.Odbc.Default #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : _utils.Adapter.InsertBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -88,8 +89,8 @@ namespace FreeSql.Odbc.Default poolConn = _orm.Ado.MasterPool.Get(); conn = poolConn.Value; } - await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params); - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, $" {_utils.Adapter.InsertAfterGetIdentitySql}", _commandTimeout)), out var trylng) ? trylng : 0; + await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, $" {_utils.Adapter.InsertAfterGetIdentitySql}", _commandTimeout, null, cancellationToken)), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -106,7 +107,7 @@ namespace FreeSql.Odbc.Default } return ret; } - protected override Task> RawExecuteInsertedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); #endif } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs index 9e588197..2f9605ff 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Default @@ -61,10 +62,10 @@ namespace FreeSql.Odbc.Default #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : _utils.Adapter.UpdateBatchSplitLimit, _batchParameterLimit > 0 ? _batchParameterLimit : 255, cancellationToken); - protected override Task> RawExecuteUpdatedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs index 2c2ca22b..8c1f56cd 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.KingbaseES @@ -122,11 +123,11 @@ namespace FreeSql.Odbc.KingbaseES #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -142,7 +143,7 @@ namespace FreeSql.Odbc.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -161,7 +162,7 @@ namespace FreeSql.Odbc.KingbaseES _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -175,7 +176,7 @@ namespace FreeSql.Odbc.KingbaseES } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -197,7 +198,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs index 4cdfaf27..bc744a65 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.KingbaseES @@ -123,10 +124,10 @@ namespace FreeSql.Odbc.KingbaseES #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -149,7 +150,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index e877bcdc..1ab8e494 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.MySql @@ -118,11 +119,11 @@ namespace FreeSql.Odbc.MySql #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -141,8 +142,8 @@ namespace FreeSql.Odbc.MySql poolConn = _orm.Ado.MasterPool.Get(); conn = poolConn.Value; } - await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params); - ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()", _commandTimeout)), out var trylng) ? trylng : 0; + await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()", _commandTimeout, null, cancellationToken)), out var trylng) ? trylng : 0; } catch (Exception ex) { @@ -159,7 +160,7 @@ namespace FreeSql.Odbc.MySql } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -181,7 +182,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs index 6a07f83b..596472cb 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.MySql @@ -106,10 +107,10 @@ namespace FreeSql.Odbc.MySql #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -132,7 +133,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs index f687a17d..87d33c14 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Oracle @@ -153,11 +154,11 @@ namespace FreeSql.Odbc.Oracle #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -172,7 +173,7 @@ namespace FreeSql.Odbc.Oracle _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -195,7 +196,7 @@ namespace FreeSql.Odbc.Oracle _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) @@ -210,13 +211,13 @@ namespace FreeSql.Odbc.Oracle } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var ret = _source.ToList(); - await this.RawExecuteAffrowsAsync(); + await this.RawExecuteAffrowsAsync(cancellationToken); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs index 2ef008c9..4d7172ba 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Oracle @@ -68,10 +69,10 @@ namespace FreeSql.Odbc.Oracle #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync() + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs index d1fe614d..dc1e0673 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.PostgreSQL @@ -122,11 +123,11 @@ namespace FreeSql.Odbc.PostgreSQL #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -142,7 +143,7 @@ namespace FreeSql.Odbc.PostgreSQL _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -161,7 +162,7 @@ namespace FreeSql.Odbc.PostgreSQL _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -175,7 +176,7 @@ namespace FreeSql.Odbc.PostgreSQL } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -197,7 +198,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs index dd21bcef..77c63351 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.PostgreSQL @@ -123,10 +124,10 @@ namespace FreeSql.Odbc.PostgreSQL #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -149,7 +150,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index 1551bd21..b1626bc5 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.SqlServer @@ -104,11 +105,11 @@ namespace FreeSql.Odbc.SqlServer #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -120,7 +121,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -134,7 +135,7 @@ namespace FreeSql.Odbc.SqlServer } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -171,7 +172,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs index b1009017..0b08e1b2 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.SqlServer @@ -102,10 +103,10 @@ namespace FreeSql.Odbc.SqlServer #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -133,7 +134,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index ce124df9..b4a33b6d 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -7,6 +7,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Oracle.Curd @@ -226,11 +227,11 @@ namespace FreeSql.Oracle.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -245,7 +246,7 @@ namespace FreeSql.Oracle.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -268,7 +269,7 @@ namespace FreeSql.Oracle.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); long.TryParse(string.Concat(identParam.Value), out ret); } catch (Exception ex) @@ -283,13 +284,13 @@ namespace FreeSql.Oracle.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var ret = _source.ToList(); - await this.RawExecuteAffrowsAsync(); + await this.RawExecuteAffrowsAsync(cancellationToken); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs index f0652f8d..b0beee38 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Oracle.Curd @@ -68,10 +69,10 @@ namespace FreeSql.Oracle.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync() + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs index 367a967a..13b0d2ea 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.PostgreSQL.Curd @@ -122,11 +123,11 @@ namespace FreeSql.PostgreSQL.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -142,7 +143,7 @@ namespace FreeSql.PostgreSQL.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -161,7 +162,7 @@ namespace FreeSql.PostgreSQL.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -175,7 +176,7 @@ namespace FreeSql.PostgreSQL.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -197,7 +198,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs index 085ac4bd..a8cd23b3 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.PostgreSQL.Curd @@ -123,10 +124,10 @@ namespace FreeSql.PostgreSQL.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -149,7 +150,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs index 9dadb1a5..60a2951e 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsert.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.ShenTong.Curd @@ -122,11 +123,11 @@ namespace FreeSql.ShenTong.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -142,7 +143,7 @@ namespace FreeSql.ShenTong.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { @@ -161,7 +162,7 @@ namespace FreeSql.ShenTong.Curd _orm.Aop.CurdBeforeHandler?.Invoke(this, before); try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -175,7 +176,7 @@ namespace FreeSql.ShenTong.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -197,7 +198,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs index 50c293e7..44102c15 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongUpdate.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.ShenTong.Curd @@ -124,10 +125,10 @@ namespace FreeSql.ShenTong.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -150,7 +151,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index f1ee76ae..fca5e0b8 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.SqlServer.Curd @@ -109,11 +110,11 @@ namespace FreeSql.SqlServer.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -125,7 +126,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -139,7 +140,7 @@ namespace FreeSql.SqlServer.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -176,7 +177,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index f70a8143..b70438d6 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.SqlServer.Curd @@ -103,10 +104,10 @@ namespace FreeSql.SqlServer.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync() + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -134,7 +135,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); ValidateVersionAndThrow(ret.Count, sql, dbParms); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs index a9165dc3..ba1b143a 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsert.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Sqlite.Curd @@ -59,11 +60,11 @@ namespace FreeSql.Sqlite.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - async protected override Task RawExecuteIdentityAsync() + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -75,7 +76,7 @@ namespace FreeSql.Sqlite.Curd Exception exception = null; try { - long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); } catch (Exception ex) { @@ -89,13 +90,13 @@ namespace FreeSql.Sqlite.Curd } return ret; } - async protected override Task> RawExecuteInsertedAsync() + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var ret = _source.ToList(); - await this.RawExecuteAffrowsAsync(); + await this.RawExecuteAffrowsAsync(cancellationToken); return ret; } #endif diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs index 1fefc121..6db2c026 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteUpdate.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Sqlite.Curd @@ -66,10 +67,10 @@ namespace FreeSql.Sqlite.Curd #if net40 #else - public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); - public override Task> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); - protected override Task> RawExecuteUpdatedAsync() + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } From 37cd18d7c4343d0cd582c639f9638a85a456da00 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 06:43:45 +0800 Subject: [PATCH 0995/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Async=20Canc?= =?UTF-8?q?ellationToken=20IDelete=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/Interface/Curd/IDelete.cs | 5 +++-- .../CommonProvider/DeleteProviderAsync.cs | 7 ++++--- .../FreeSql.Provider.Dameng/Curd/DamengDelete.cs | 3 ++- .../Curd/FirebirdDelete.cs | 5 +++-- .../Curd/KingbaseESDelete.cs | 5 +++-- .../Curd/MsAccessDelete.cs | 3 ++- .../FreeSql.Provider.MySql/Curd/MySqlDelete.cs | 5 +++-- .../Dameng/Curd/OdbcDamengDelete.cs | 3 ++- .../Default/Curd/OdbcDelete.cs | 3 ++- .../KingbaseES/Curd/OdbcKingbaseESDelete.cs | 5 +++-- .../MySql/Curd/OdbcMySqlDelete.cs | 5 +++-- .../Oracle/Curd/OdbcOracleDelete.cs | 3 ++- .../PostgreSQL/Curd/OdbcPostgreSQLDelete.cs | 5 +++-- .../SqlServer/Curd/OdbcSqlServerDelete.cs | 5 +++-- .../FreeSql.Provider.Oracle/Curd/OracleDelete.cs | 3 ++- .../Curd/PostgreSQLDelete.cs | 5 +++-- .../Curd/ShenTongDelete.cs | 5 +++-- .../Curd/SqlServerDelete.cs | 5 +++-- .../FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs | 3 ++- 20 files changed, 51 insertions(+), 48 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -509,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 4d9bd3e8..7a460d31 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data.Common; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -109,8 +110,8 @@ namespace FreeSql #if net40 #else - Task ExecuteAffrowsAsync(); - Task> ExecuteDeletedAsync(); + Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); + Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default); #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs index 380ee6f8..64af2765 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs @@ -5,6 +5,7 @@ using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider @@ -13,7 +14,7 @@ namespace FreeSql.Internal.CommonProvider { #if net40 #else - async public Task ExecuteAffrowsAsync() + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -24,7 +25,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + affrows = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { @@ -39,7 +40,7 @@ namespace FreeSql.Internal.CommonProvider this.ClearData(); return affrows; } - public abstract Task> ExecuteDeletedAsync(); + public abstract Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default); #endif } } diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs index 67c82634..800b2a10 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Dameng.Curd @@ -22,7 +23,7 @@ namespace FreeSql.Dameng.Curd #if net40 #else - public override Task> ExecuteDeletedAsync() + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs index 8d00109a..4821de2b 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Firebird.Curd @@ -56,7 +57,7 @@ namespace FreeSql.Firebird.Curd #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -79,7 +80,7 @@ namespace FreeSql.Firebird.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs index f44eebb4..b7b9c8a6 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.KingbaseES @@ -56,7 +57,7 @@ namespace FreeSql.KingbaseES #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -79,7 +80,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs index c0b00c49..3c5fd1fd 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.MsAccess.Curd @@ -22,7 +23,7 @@ namespace FreeSql.MsAccess.Curd #if net40 #else - public override Task> ExecuteDeletedAsync() + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index 1c04f9d4..ecc9038a 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.MySql.Curd @@ -56,7 +57,7 @@ namespace FreeSql.MySql.Curd #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -79,7 +80,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs index 01b4db9f..a57a8a84 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Dameng @@ -22,7 +23,7 @@ namespace FreeSql.Odbc.Dameng #if net40 #else - public override Task> ExecuteDeletedAsync() + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs index 74350ebc..76e0495e 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Default @@ -19,7 +20,7 @@ namespace FreeSql.Odbc.Default #if net40 #else - public override Task> ExecuteDeletedAsync() => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能"); #endif } } diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs index 80e0e261..e5e2a6ad 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.KingbaseES @@ -56,7 +57,7 @@ namespace FreeSql.Odbc.KingbaseES #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -79,7 +80,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs index 5bf46d38..ba40ad77 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.MySql @@ -56,7 +57,7 @@ namespace FreeSql.Odbc.MySql #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -79,7 +80,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs index 992edefd..a5e87939 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.Oracle @@ -22,7 +23,7 @@ namespace FreeSql.Odbc.Oracle #if net40 #else - public override Task> ExecuteDeletedAsync() + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs index bf41c0da..e944faef 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.PostgreSQL @@ -56,7 +57,7 @@ namespace FreeSql.Odbc.PostgreSQL #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -79,7 +80,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs index 186dab45..ed74709e 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.SqlServer @@ -61,7 +62,7 @@ namespace FreeSql.Odbc.SqlServer #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -89,7 +90,7 @@ namespace FreeSql.Odbc.SqlServer Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs index ddc12132..618819b8 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Oracle.Curd @@ -22,7 +23,7 @@ namespace FreeSql.Oracle.Curd #if net40 #else - public override Task> ExecuteDeletedAsync() + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs index dc640615..febe1cd7 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.PostgreSQL.Curd @@ -56,7 +57,7 @@ namespace FreeSql.PostgreSQL.Curd #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -79,7 +80,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs index a7d7aba2..326b0bb1 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.ShenTong.Curd @@ -56,7 +57,7 @@ namespace FreeSql.ShenTong.Curd #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -79,7 +80,7 @@ namespace FreeSql.ShenTong.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index 21a877d4..d7a9fe92 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.SqlServer.Curd @@ -61,7 +62,7 @@ namespace FreeSql.SqlServer.Curd #if net40 #else - async public override Task> ExecuteDeletedAsync() + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); @@ -89,7 +90,7 @@ namespace FreeSql.SqlServer.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs index 25c104ff..3a108707 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteDelete.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Sqlite.Curd @@ -22,7 +23,7 @@ namespace FreeSql.Sqlite.Curd #if net40 #else - public override Task> ExecuteDeletedAsync() + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } From b25bcf8ee5658af59b9981f09b80ac171661cbe8 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 06:48:52 +0800 Subject: [PATCH 0996/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Async=20Canc?= =?UTF-8?q?ellationToken=20OnDuplicateKeyUpdate/OnConflictDoUpdate?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Curd/KingbaseESOnConflictDoUpdate.cs | 5 +++-- .../FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs | 5 +++-- .../KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs | 5 +++-- .../MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs | 5 +++-- .../PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs | 5 +++-- .../FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs | 5 +++-- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs index b550fd08..aa86a9d9 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs @@ -6,6 +6,7 @@ using System.Data; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.KingbaseES @@ -177,7 +178,7 @@ namespace FreeSql.KingbaseES #if net40 #else - async public Task ExecuteAffrowsAsync() + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -188,7 +189,7 @@ namespace FreeSql.KingbaseES Exception exception = null; try { - ret = await _insert.InternalOrm.Ado.ExecuteNonQueryAsync(_insert.InternalConnection, _insert.InternalTransaction, CommandType.Text, sql, _insert._commandTimeout, _insert.InternalParams); + ret = await _insert.InternalOrm.Ado.ExecuteNonQueryAsync(_insert.InternalConnection, _insert.InternalTransaction, CommandType.Text, sql, _insert._commandTimeout, _insert.InternalParams, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs index 7ce2055f..14205596 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -3,6 +3,7 @@ using System; using System.Data; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.MySql.Curd @@ -136,7 +137,7 @@ namespace FreeSql.MySql.Curd #if net40 #else - async public Task ExecuteAffrowsAsync() + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -147,7 +148,7 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams); + ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs index 4e0b3774..3ff78116 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs @@ -6,6 +6,7 @@ using System.Data; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.KingbaseES @@ -177,7 +178,7 @@ namespace FreeSql.Odbc.KingbaseES #if net40 #else - async public Task ExecuteAffrowsAsync() + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -188,7 +189,7 @@ namespace FreeSql.Odbc.KingbaseES Exception exception = null; try { - ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs index 92868d26..ae552a90 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs @@ -3,6 +3,7 @@ using System; using System.Data; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.MySql @@ -136,7 +137,7 @@ namespace FreeSql.Odbc.MySql #if net40 #else - async public Task ExecuteAffrowsAsync() + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -147,7 +148,7 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams); + ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs index 2a2f302b..3f1262a0 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs @@ -6,6 +6,7 @@ using System.Data; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Odbc.PostgreSQL @@ -177,7 +178,7 @@ namespace FreeSql.Odbc.PostgreSQL #if net40 #else - async public Task ExecuteAffrowsAsync() + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -188,7 +189,7 @@ namespace FreeSql.Odbc.PostgreSQL Exception exception = null; try { - ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams, cancellationToken); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index 5ab98652..383910d0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -6,6 +6,7 @@ using System.Data; using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.PostgreSQL.Curd @@ -177,7 +178,7 @@ namespace FreeSql.PostgreSQL.Curd #if net40 #else - async public Task ExecuteAffrowsAsync() + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -188,7 +189,7 @@ namespace FreeSql.PostgreSQL.Curd Exception exception = null; try { - ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams, cancellationToken); } catch (Exception ex) { From f9a46e3a1220f2968b0dc9857af6e5e9f6f06094 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 09:10:47 +0800 Subject: [PATCH 0997/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Async=20Canc?= =?UTF-8?q?ellationToken=20ISelect=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectedQueryProvider.cs | 31 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 + .../Dameng/Curd/DamengSelectTest.cs | 4 + FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 15 +- FreeSql/FreeSql.csproj | 12 + FreeSql/Interface/Curd/ISelect/ISelect0.cs | 19 +- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 29 +- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 119 - FreeSql/Interface/Curd/ISelect/ISelect11.cs | 119 - FreeSql/Interface/Curd/ISelect/ISelect12.cs | 119 - FreeSql/Interface/Curd/ISelect/ISelect13.cs | 120 - FreeSql/Interface/Curd/ISelect/ISelect14.cs | 119 - FreeSql/Interface/Curd/ISelect/ISelect15.cs | 119 - FreeSql/Interface/Curd/ISelect/ISelect16.cs | 118 - FreeSql/Interface/Curd/ISelect/ISelect2.cs | 121 - FreeSql/Interface/Curd/ISelect/ISelect2`16.cs | 1631 ++++ FreeSql/Interface/Curd/ISelect/ISelect3.cs | 121 - FreeSql/Interface/Curd/ISelect/ISelect4.cs | 120 - FreeSql/Interface/Curd/ISelect/ISelect5.cs | 122 - FreeSql/Interface/Curd/ISelect/ISelect6.cs | 119 - FreeSql/Interface/Curd/ISelect/ISelect7.cs | 120 - FreeSql/Interface/Curd/ISelect/ISelect8.cs | 120 - FreeSql/Interface/Curd/ISelect/ISelect9.cs | 119 - .../Interface/Curd/ISelect/ISelectGrouping.cs | 7 +- .../SelectProvider/Select0Provider.cs | 24 +- .../SelectProvider/Select0ProviderReader.cs | 62 +- .../SelectProvider/Select10Provider.cs | 481 -- .../SelectProvider/Select11Provider.cs | 480 -- .../SelectProvider/Select12Provider.cs | 483 -- .../SelectProvider/Select13Provider.cs | 484 -- .../SelectProvider/Select14Provider.cs | 486 -- .../SelectProvider/Select15Provider.cs | 489 -- .../SelectProvider/Select16Provider.cs | 490 -- .../SelectProvider/Select1Provider.cs | 81 +- .../SelectProvider/Select1Provider2`16.cs | 7005 +++++++++++++++++ .../SelectProvider/Select2Provider.cs | 462 -- .../SelectProvider/Select3Provider.cs | 464 -- .../SelectProvider/Select4Provider.cs | 468 -- .../SelectProvider/Select5Provider.cs | 468 -- .../SelectProvider/Select6Provider.cs | 469 -- .../SelectProvider/Select7Provider.cs | 477 -- .../SelectProvider/Select8Provider.cs | 474 -- .../SelectProvider/Select9Provider.cs | 476 -- .../SelectProvider/SelectGroupingProvider.cs | 26 +- .../T4Temp/{ISelect.tt => ISelect2`16.tt} | 50 +- ...lectProvider.tt => Select1Provider2`16.tt} | 107 +- .../FreeSqlMySqlConnectorGlobalExtensions.cs | 9 +- .../PostgreSQLExtensions.cs | 7 +- .../SqlServerExtensions.cs | 7 +- 49 files changed, 8914 insertions(+), 9174 deletions(-) delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect10.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect11.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect12.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect13.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect14.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect15.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect16.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect2.cs create mode 100644 FreeSql/Interface/Curd/ISelect/ISelect2`16.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect3.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect4.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect5.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect6.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect7.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect8.cs delete mode 100644 FreeSql/Interface/Curd/ISelect/ISelect9.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider2`16.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs delete mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs rename FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/{ISelect.tt => ISelect2`16.tt} (81%) rename FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/{SelectProvider.tt => Select1Provider2`16.tt} (87%) diff --git a/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs index 75177574..6c3ad1d9 100644 --- a/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs +++ b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -18,12 +19,12 @@ namespace FreeSql #if net40 #else - Task> ToListAsync(); - Task ToOneAsync(); - Task FirstAsync(); + Task> ToListAsync(CancellationToken cancellationToken = default); + Task ToOneAsync(CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task AnyAsync(); - Task CountAsync(); + Task AnyAsync(CancellationToken cancellationToken = default); + Task CountAsync(CancellationToken cancellationToken = default); #endif List ToList(); @@ -86,24 +87,24 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - public Task> ToListAsync() + public Task> ToListAsync(CancellationToken cancellationToken = default) { var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TOut)); - return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(_map, _field.Length > 0 ? _field.Remove(0, 2).ToString() : null) }) as Task>; + return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(_map, _field.Length > 0 ? _field.Remove(0, 2).ToString() : null), cancellationToken }) as Task>; } - async public Task ToOneAsync() => (await ToListAsync()).FirstOrDefault(); - public Task FirstAsync() => ToOneAsync(); + async public Task ToOneAsync(CancellationToken cancellationToken = default) => (await ToListAsync(cancellationToken)).FirstOrDefault(); + public Task FirstAsync(CancellationToken cancellationToken = default) => ToOneAsync(cancellationToken); - public Task AnyAsync() + public Task AnyAsync(CancellationToken cancellationToken = default) { - var method = _select.GetType().GetMethod("AnyAsync", new Type[0]); - return method.Invoke(_select, new object[0]) as Task; + var method = _select.GetType().GetMethod("AnyAsync", new Type[] { typeof(CancellationToken) }); + return method.Invoke(_select, new object[] { cancellationToken }) as Task; } - public Task CountAsync() + public Task CountAsync(CancellationToken cancellationToken = default) { - var method = _select.GetType().GetMethod("CountAsync", new Type[0]); - return method.Invoke(_select, new object[0]) as Task; + var method = _select.GetType().GetMethod("CountAsync", new Type[] { typeof(CancellationToken) }); + return method.Invoke(_select, new object[] { cancellationToken }) as Task; } #endif diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -502,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index 762ed3a1..86e4eadb 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -213,6 +213,10 @@ namespace FreeSql.Tests.Dameng var ddd = g.dameng.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); Assert.Single(ddd); Assert.Equal(2, ddd[0].Childs.Count); + + ddd = g.dameng.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeListAsync().Result; + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); } public class District { diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 9a093d29..67dbad00 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -14,6 +14,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading; +using System.Threading.Tasks; public static partial class FreeSqlGlobalExtensions { @@ -305,7 +306,7 @@ public static partial class FreeSqlGlobalExtensions #if net40 #else - async public static System.Threading.Tasks.Task> IncludeManyAsync(this List list, IFreeSql orm, Expression>> navigateSelector, Action> then = null) where T1 : class where TNavigate : class + async public static Task> IncludeManyAsync(this List list, IFreeSql orm, Expression>> navigateSelector, Action> then = null, CancellationToken cancellationToken = default) where T1 : class where TNavigate : class { if (list == null || list.Any() == false) return list; if (orm.CodeFirst.IsAutoSyncStructure) @@ -315,7 +316,7 @@ public static partial class FreeSqlGlobalExtensions (orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(T1)); //._dicSyced.TryAdd(typeof(TReturn), true); } var select = orm.Select().IncludeMany(navigateSelector, then) as Select1Provider; - await select.SetListAsync(list); + await select.SetListAsync(list, cancellationToken); return list; } #endif @@ -338,8 +339,8 @@ public static partial class FreeSqlGlobalExtensions a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray(); - if (navs.Length != 1) return select.ToList(); var list = select.ToList(); + if (navs.Length != 1) return list; select._trackToList = null; select._includeToList.Clear(); @@ -352,7 +353,7 @@ public static partial class FreeSqlGlobalExtensions } #if net40 #else - async public static System.Threading.Tasks.Task> ToTreeListAsync(this ISelect that) where T1 : class + async public static Task> ToTreeListAsync(this ISelect that, CancellationToken cancellationToken = default) where T1 : class { var select = that as Select1Provider; var tb = select._tables[0].Table; @@ -361,8 +362,8 @@ public static partial class FreeSqlGlobalExtensions a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray(); - if (navs.Length != 1) return await select.ToListAsync(); - var list = await select.ToListAsync(); + var list = await select.ToListAsync(false, cancellationToken); + if (navs.Length != 1) return list; select._trackToList = null; select._includeToList.Clear(); @@ -370,7 +371,7 @@ public static partial class FreeSqlGlobalExtensions var navigateSelector = Expression.Lambda>>(Expression.MakeMemberAccess(navigateSelectorParamExp, navs[0].Property), navigateSelectorParamExp); select.IncludeMany(navigateSelector); select._includeManySubListOneToManyTempValue1 = list; - select.SetList(list); + await select.SetListAsync(list, cancellationToken); return list.Except(list.SelectMany(a => FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityValueWithPropertyName(select._orm, tb.Type, a, navs[0].Property.Name) as IEnumerable)).ToList(); } #endif diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b1e30b18..172f1b10 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -24,6 +24,18 @@ + + + + + + + + True + True + TextTemplate1.tt + + FreeSql.xml diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index b4839cfb..11a54853 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -5,6 +5,7 @@ using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -16,17 +17,17 @@ namespace FreeSql #if net40 #else - Task ToDataTableAsync(string field = null); - Task> ToDictionaryAsync(Func keySelector); - Task> ToDictionaryAsync(Func keySelector, Func elementSelector); - Task> ToListAsync(bool includeNestedMembers = false); - Task> ToListAsync(string field); + Task ToDataTableAsync(string field = null, CancellationToken cancellationToken = default); + Task> ToDictionaryAsync(Func keySelector, CancellationToken cancellationToken = default); + Task> ToDictionaryAsync(Func keySelector, Func elementSelector, CancellationToken cancellationToken = default); + Task> ToListAsync(bool includeNestedMembers = false, CancellationToken cancellationToken = default); + Task> ToListAsync(string field, CancellationToken cancellationToken = default); - Task ToOneAsync(); - Task FirstAsync(); + Task ToOneAsync(CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task AnyAsync(); - Task CountAsync(); + Task AnyAsync(CancellationToken cancellationToken = default); + Task CountAsync(CancellationToken cancellationToken = default); #endif /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index cefb5ced..74372279 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -13,23 +14,23 @@ namespace FreeSql #if net40 #else - Task AnyAsync(Expression> exp); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select); - Task ToOneAsync(); - Task FirstAsync(Expression> select); - Task FirstAsync(); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task ToOneAsync(CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); + Task ToAggregateAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #endif /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs deleted file mode 100644 index 0b1bb45f..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ /dev/null @@ -1,119 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> 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 - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect11.cs b/FreeSql/Interface/Curd/ISelect/ISelect11.cs deleted file mode 100644 index c5d6a83c..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect11.cs +++ /dev/null @@ -1,119 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> 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 - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect12.cs b/FreeSql/Interface/Curd/ISelect/ISelect12.cs deleted file mode 100644 index c4edcfd2..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect12.cs +++ /dev/null @@ -1,119 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> 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 - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect13.cs b/FreeSql/Interface/Curd/ISelect/ISelect13.cs deleted file mode 100644 index 0f3c7d7f..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect13.cs +++ /dev/null @@ -1,120 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> 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 - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect14.cs b/FreeSql/Interface/Curd/ISelect/ISelect14.cs deleted file mode 100644 index 811dc203..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect14.cs +++ /dev/null @@ -1,119 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> 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 - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect15.cs b/FreeSql/Interface/Curd/ISelect/ISelect15.cs deleted file mode 100644 index c6fad4f6..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect15.cs +++ /dev/null @@ -1,119 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> 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 - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect16.cs b/FreeSql/Interface/Curd/ISelect/ISelect16.cs deleted file mode 100644 index 53cb1950..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect16.cs +++ /dev/null @@ -1,118 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> 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 - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs deleted file mode 100644 index 7949ff3b..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ /dev/null @@ -1,121 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> where T2 : class - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - - - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs b/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs new file mode 100644 index 00000000..b825f8d9 --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs @@ -0,0 +1,1631 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql +{ + + public interface ISelect : ISelect0, T1> where T2 : class + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> 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 + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> 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 + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> 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 + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> 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 + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> 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 + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> 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 + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + + + public interface ISelect : ISelect0, T1> 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 + { +#if net40 +#else + Task AnyAsync(Expression> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); + + Task ToOneAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(Expression> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); + + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression> column, CancellationToken cancellationToken); + Task MinAsync(Expression> column, CancellationToken cancellationToken); + Task MaxAsync(Expression> column, CancellationToken cancellationToken); + Task AvgAsync(Expression> column, CancellationToken cancellationToken); + + #region HzyTuple 元组 + + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + + #endregion + +#endif + + bool Any(Expression> exp); + int InsertInto(string tableName, Expression> select) where TTargetEntity : class; + DataTable ToDataTable(Expression> select); + List ToList(Expression> select); + List ToList(); + void ToChunk(Expression> select, int size, Action>> done); + + TReturn ToOne(Expression> select); + TReturn First(Expression> select); + TDto First(); + + string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); + ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); + decimal Sum(Expression> column); + TMember Min(Expression> column); + TMember Max(Expression> column); + double Avg(Expression> column); + + ISelect LeftJoin(Expression> exp); + ISelect InnerJoin(Expression> exp); + ISelect RightJoin(Expression> exp); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping> GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + ISelect OrderByIf(bool condition, Expression> column, bool descending = false); + + ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms = null); + + #region HzyTuple 元组 + + bool Any(Expression, bool>> exp); + int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; + DataTable ToDataTable(Expression, TReturn>> select); + List ToList(Expression, TReturn>> select); + void ToChunk(Expression, TReturn>> select, int size, Action>> done); + + TReturn ToOne(Expression, TReturn>> select); + TReturn First(Expression, TReturn>> select); + + string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); + decimal Sum(Expression, TMember>> column); + TMember Min(Expression, TMember>> column); + TMember Max(Expression, TMember>> column); + double Avg(Expression, TMember>> column); + + ISelect LeftJoin(Expression, bool>> exp); + ISelect InnerJoin(Expression, bool>> exp); + ISelect RightJoin(Expression, bool>> exp); + + ISelect Where(Expression, bool>> exp); + ISelect WhereIf(bool condition, Expression, bool>> exp); + + ISelectGrouping> GroupBy(Expression, TKey>> exp); + + ISelect OrderBy(Expression, TMember>> column); + ISelect OrderByDescending(Expression, TMember>> column); + ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + + #endregion + + } + +} diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs deleted file mode 100644 index fe33ff88..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ /dev/null @@ -1,121 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - - public interface ISelect : ISelect0, T1> where T2 : class where T3 : class - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs deleted file mode 100644 index b28ab64b..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ /dev/null @@ -1,120 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - - public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs deleted file mode 100644 index bab8b26f..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ /dev/null @@ -1,122 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - - public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - - - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs deleted file mode 100644 index c70e04e4..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ /dev/null @@ -1,119 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs deleted file mode 100644 index b38ab3b4..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ /dev/null @@ -1,120 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs deleted file mode 100644 index febb1120..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ /dev/null @@ -1,120 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs deleted file mode 100644 index ee41d171..00000000 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ /dev/null @@ -1,119 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql -{ - - public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class - { - -#if net40 -#else - Task AnyAsync(Expression> exp); - Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select); - Task> ToListAsync(Expression> select); - Task> ToListAsync(); - - Task ToOneAsync(Expression> select); - Task FirstAsync(Expression> select); - Task FirstAsync(); - - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - Task SumAsync(Expression> column); - Task MinAsync(Expression> column); - Task MaxAsync(Expression> column); - Task AvgAsync(Expression> column); - - #region HzyTuple 元组 - - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); - - #endregion - -#endif - - bool Any(Expression> exp); - int InsertInto(string tableName, Expression> select) where TTargetEntity : class; - DataTable ToDataTable(Expression> select); - List ToList(Expression> select); - List ToList(); - void ToChunk(Expression> select, int size, Action>> done); - - TReturn ToOne(Expression> select); - TReturn First(Expression> select); - TDto First(); - - string ToSql(Expression> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); - ISelect Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result); - decimal Sum(Expression> column); - TMember Min(Expression> column); - TMember Max(Expression> column); - double Avg(Expression> column); - - ISelect LeftJoin(Expression> exp); - ISelect InnerJoin(Expression> exp); - ISelect RightJoin(Expression> exp); - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - - ISelectGrouping> GroupBy(Expression> exp); - - ISelect OrderBy(Expression> column); - ISelect OrderByDescending(Expression> column); - ISelect OrderByIf(bool condition, Expression> column, bool descending = false); - - ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms = null); - - #region HzyTuple 元组 - - bool Any(Expression, bool>> exp); - int InsertInto(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - DataTable ToDataTable(Expression, TReturn>> select); - List ToList(Expression, TReturn>> select); - void ToChunk(Expression, TReturn>> select, int size, Action>> done); - - TReturn ToOne(Expression, TReturn>> select); - TReturn First(Expression, TReturn>> select); - - string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); - decimal Sum(Expression, TMember>> column); - TMember Min(Expression, TMember>> column); - TMember Max(Expression, TMember>> column); - double Avg(Expression, TMember>> column); - - ISelect LeftJoin(Expression, bool>> exp); - ISelect InnerJoin(Expression, bool>> exp); - ISelect RightJoin(Expression, bool>> exp); - - ISelect Where(Expression, bool>> exp); - ISelect WhereIf(bool condition, Expression, bool>> exp); - - ISelectGrouping> GroupBy(Expression, TKey>> exp); - - ISelect OrderBy(Expression, TMember>> column); - ISelect OrderByDescending(Expression, TMember>> column); - ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); - - #endregion - - } - -} \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 7e73a743..1e311a29 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -11,9 +12,9 @@ namespace FreeSql #if net40 #else - Task CountAsync(); - Task> ToListAsync(Expression, TReturn>> select); - Task> ToDictionaryAsync(Expression, TElement>> elementSelector); + Task CountAsync(CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToDictionaryAsync(Expression, TElement>> elementSelector, CancellationToken cancellationToken = default); #endif /// diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 9d1d8782..ea4c9606 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -36,7 +36,7 @@ namespace FreeSql.Internal.CommonProvider public List> _includeToList = new List>(); #if net40 #else - public List> _includeToListAsync = new List>(); + public List> _includeToListAsync = new List>(); #endif public Dictionary _includeInfo = new Dictionary(); public bool _distinct; @@ -114,7 +114,7 @@ namespace FreeSql.Internal.CommonProvider to._includeToList = new List>(from._includeToList.ToArray()); #if net40 #else - to._includeToListAsync = new List>(from._includeToListAsync.ToArray()); + to._includeToListAsync = new List>(from._includeToListAsync.ToArray()); #endif to._distinct = from._distinct; to._selectExpression = from._selectExpression; @@ -716,35 +716,35 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - async public Task AnyAsync() + async public Task AnyAsync(CancellationToken cancellationToken = default) { this.Limit(1); - return (await this.ToListAsync($"1{_commonUtils.FieldAsAlias("as1")}")).Sum() > 0; //这里的 Sum 为了分表查询 + return (await this.ToListAsync($"1{_commonUtils.FieldAsAlias("as1")}", cancellationToken)).Sum() > 0; //这里的 Sum 为了分表查询 } - async public Task CountAsync() + async public Task CountAsync(CancellationToken cancellationToken = default) { var tmpOrderBy = _orderby; _orderby = null; try { - return (await this.ToListAsync($"count(1){_commonUtils.FieldAsAlias("as1")}")).Sum(); //这里的 Sum 为了分表查询 + return (await this.ToListAsync($"count(1){_commonUtils.FieldAsAlias("as1")}", cancellationToken)).Sum(); //这里的 Sum 为了分表查询 } finally { _orderby = tmpOrderBy; } } - public virtual Task> ToListAsync(bool includeNestedMembers = false) + public virtual Task> ToListAsync(bool includeNestedMembers = false, CancellationToken cancellationToken = default) { - if (_selectExpression != null) return this.InternalToListAsync(_selectExpression); - return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); + if (_selectExpression != null) return this.InternalToListAsync(_selectExpression, cancellationToken); + return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null, cancellationToken); } - async public Task ToOneAsync() + async public Task ToOneAsync(CancellationToken cancellationToken = default) { this.Limit(1); - return (await this.ToListAsync()).FirstOrDefault(); + return (await this.ToListAsync(false, cancellationToken)).FirstOrDefault(); } - public Task FirstAsync() => this.ToOneAsync(); + public Task FirstAsync(CancellationToken cancellationToken = default) => this.ToOneAsync(cancellationToken); #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 85fd66ec..91c3f7c8 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -788,7 +788,7 @@ namespace FreeSql.Internal.CommonProvider #region Async #if net40 #else - async public Task ToDataTableAsync(string field = null) + async public Task ToDataTableAsync(string field, CancellationToken cancellationToken) { var sql = this.ToSql(field); var dbParms = _params.ToArray(); @@ -798,7 +798,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { @@ -813,7 +813,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async public Task> ToListAsync(string field) + async public Task> ToListAsync(string field, CancellationToken cancellationToken) { var sql = this.ToSql(field); var type = typeof(TTuple); @@ -825,7 +825,7 @@ namespace FreeSql.Internal.CommonProvider try { if (type.IsClass) - ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.QueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); else { var flagStr = $"ToListField:{field}"; @@ -834,7 +834,7 @@ namespace FreeSql.Internal.CommonProvider var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils); ret.Add((TTuple)read.Value); return Task.FromResult(false); - }, CommandType.Text, sql, _commandTimeout, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } } catch (Exception ex) @@ -850,7 +850,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) { var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); @@ -871,7 +871,7 @@ namespace FreeSql.Internal.CommonProvider } retCount++; return Task.FromResult(false); - }, CommandType.Text, sql, _commandTimeout, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { @@ -883,12 +883,12 @@ namespace FreeSql.Internal.CommonProvider var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } - foreach (var include in _includeToListAsync) await include?.Invoke(ret); + foreach (var include in _includeToListAsync) await include?.Invoke(ret, cancellationToken); _trackToList?.Invoke(ret); return ret; } - internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) + internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) { string sql = null; if (otherData?.Length > 0) @@ -901,11 +901,11 @@ namespace FreeSql.Internal.CommonProvider else sql = this.ToSql(af.Field); - return ToListAfPrivateAsync(sql, af, otherData); + return ToListAfPrivateAsync(sql, af, otherData, cancellationToken); } - public Task> ToDictionaryAsync(Func keySelector) => ToDictionaryAsync(keySelector, a => a); - async public Task> ToDictionaryAsync(Func keySelector, Func elementSelector) + public Task> ToDictionaryAsync(Func keySelector, CancellationToken cancellationToken) => ToDictionaryAsync(keySelector, a => a, cancellationToken); + async public Task> ToDictionaryAsync(Func keySelector, Func elementSelector, CancellationToken cancellationToken) { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); @@ -923,7 +923,7 @@ namespace FreeSql.Internal.CommonProvider var item = af.Read(_orm, fetch.Object); ret.Add(keySelector(item), elementSelector(item)); return Task.FromResult(false); - }, CommandType.Text, sql, _commandTimeout, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { @@ -939,7 +939,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async internal Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) + async internal Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) { var type = typeof(TReturn); var dbParms = _params.ToArray(); @@ -959,7 +959,7 @@ namespace FreeSql.Internal.CommonProvider other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null)); retCount++; return Task.FromResult(false); - }, CommandType.Text, sql, _commandTimeout, dbParms); + }, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { @@ -972,11 +972,11 @@ namespace FreeSql.Internal.CommonProvider _orm.Aop.CurdAfterHandler?.Invoke(this, after); } if (typeof(TReturn) == typeof(T1)) - foreach (var include in _includeToListAsync) await include?.Invoke(ret); + foreach (var include in _includeToListAsync) await include?.Invoke(ret, cancellationToken); _trackToList?.Invoke(ret); return ret; } - internal Task> ToListMapReaderPrivateAsync(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) + internal Task> ToListMapReaderPrivateAsync(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) { string sql = null; if (otherData?.Length > 0) @@ -989,22 +989,22 @@ namespace FreeSql.Internal.CommonProvider else sql = this.ToSql(af.field); - return ToListMrPrivateAsync(sql, af, otherData); + return ToListMrPrivateAsync(sql, af, otherData, cancellationToken); } - protected Task> ToListMapReaderAsync(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivateAsync(af, null); + protected Task> ToListMapReaderAsync(ReadAnonymousTypeAfInfo af, CancellationToken cancellationToken) => ToListMapReaderPrivateAsync(af, null, cancellationToken); - async protected Task InternalAvgAsync(Expression exp) + async protected Task InternalAvgAsync(Expression exp, CancellationToken cancellationToken) { - var list = await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"); + var list = await this.ToListAsync($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}", cancellationToken); return list.Sum() / list.Count; } - async protected Task InternalMaxAsync(Expression exp) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Max(); - async protected Task InternalMinAsync(Expression exp) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Min(); - async protected Task InternalSumAsync(Expression exp) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Sum(); + async protected Task InternalMaxAsync(Expression exp, CancellationToken cancellationToken) => (await this.ToListAsync($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}", cancellationToken)).Max(); + async protected Task InternalMinAsync(Expression exp, CancellationToken cancellationToken) => (await this.ToListAsync($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}", cancellationToken)).Min(); + async protected Task InternalSumAsync(Expression exp, CancellationToken cancellationToken) => (await this.ToListAsync($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}", cancellationToken)).Sum(); - protected Task> InternalToListAsync(Expression select) => this.ToListMapReaderAsync(this.GetExpressionField(select)); + protected Task> InternalToListAsync(Expression select, CancellationToken cancellationToken) => this.ToListMapReaderAsync(this.GetExpressionField(select), cancellationToken); - async public Task InternalInsertIntoAsync(string tableName, Expression select) + async public Task InternalInsertIntoAsync(string tableName, Expression select, CancellationToken cancellationToken) { var sql = this.InternalGetInsertIntoToSql(tableName, select); var dbParms = _params.ToArray(); @@ -1015,7 +1015,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { @@ -1030,7 +1030,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async protected Task InternalToDataTableAsync(Expression select) + async protected Task InternalToDataTableAsync(Expression select, CancellationToken cancellationToken) { var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty var dbParms = _params.ToArray(); @@ -1040,7 +1040,7 @@ namespace FreeSql.Internal.CommonProvider Exception exception = null; try { - ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); } catch (Exception ex) { @@ -1055,7 +1055,7 @@ namespace FreeSql.Internal.CommonProvider return ret; } - async protected Task InternalToAggregateAsync(Expression select) + async protected Task InternalToAggregateAsync(Expression select, CancellationToken cancellationToken) { var tmpOrderBy = _orderby; _orderby = null; //解决 select count(1) from t order by id 这样的 SQL 错误 @@ -1066,7 +1066,7 @@ namespace FreeSql.Internal.CommonProvider var index = 0; _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, null, _whereGlobalFilter, null, false); //不走 DTO 映射,不处理 IncludeMany - return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); + return (await this.ToListMapReaderAsync(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null), cancellationToken)).FirstOrDefault(); } finally { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs deleted file mode 100644 index b6f190b8..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ /dev/null @@ -1,481 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select10Provider : Select0Provider, T1>, ISelect - 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 - { - - public Select10Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; - if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs deleted file mode 100644 index 5f58506a..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select11Provider.cs +++ /dev/null @@ -1,480 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select11Provider : Select0Provider, T1>, ISelect - 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 - { - - public Select11Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; - if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; - if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs deleted file mode 100644 index 282edd57..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select12Provider.cs +++ /dev/null @@ -1,483 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select12Provider : Select0Provider, T1>, ISelect - 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 - { - - public Select12Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; - if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; - if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; - if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs deleted file mode 100644 index e89ef83d..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select13Provider.cs +++ /dev/null @@ -1,484 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select13Provider : Select0Provider, T1>, ISelect - 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 - { - - public Select13Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; - if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; - if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; - if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; - if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs deleted file mode 100644 index 2397fc47..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select14Provider.cs +++ /dev/null @@ -1,486 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select14Provider : Select0Provider, T1>, ISelect - 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 - { - - public Select14Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; - if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; - if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; - if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; - if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; - if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs deleted file mode 100644 index c6c878ef..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select15Provider.cs +++ /dev/null @@ -1,489 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select15Provider : Select0Provider, T1>, ISelect - 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 - { - - public Select15Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T15)), Alias = $"SP10o", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; - if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; - if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; - if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; - if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; - if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; - if (type == _tables[14].Table?.Type && string.IsNullOrEmpty(sqlT15) == false) return $"({sqlT15})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n"), Expression.Parameter(typeof(T15), "o")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs deleted file mode 100644 index e2fcaa72..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select16Provider.cs +++ /dev/null @@ -1,490 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select16Provider : Select0Provider, T1>, ISelect - 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 - { - - public Select16Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15), typeof(T16)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T15)), Alias = $"SP10o", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T16)), Alias = $"SP10p", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; - if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; - if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; - if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; - if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; - if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; - if (type == _tables[14].Table?.Type && string.IsNullOrEmpty(sqlT15) == false) return $"({sqlT15})"; - if (type == _tables[15].Table?.Type && string.IsNullOrEmpty(sqlT16) == false) return $"({sqlT16})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};\r\n{sqlT16}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n"), Expression.Parameter(typeof(T15), "o"), Expression.Parameter(typeof(T16), "p")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 896d31f7..c336fcf0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -12,6 +12,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider @@ -633,7 +634,7 @@ namespace FreeSql.Internal.CommonProvider { isAsync = false; #else - Func includeToListSyncOrAsync = async (listObj, isAsync) => + Func includeToListSyncOrAsync = async (listObj, isAsync, cancellationToken) => { #endif @@ -916,8 +917,8 @@ namespace FreeSql.Internal.CommonProvider { #if net40 #else - if (selectExp == null) subList = await subSelect.ToListAfPrivateAsync(sbSql.ToString(), af, null); - else subList = await subSelect.ToListMrPrivateAsync(sbSql.ToString(), mf, null); + if (selectExp == null) subList = await subSelect.ToListAfPrivateAsync(sbSql.ToString(), af, null, cancellationToken); + else subList = await subSelect.ToListMrPrivateAsync(sbSql.ToString(), mf, null, cancellationToken); #endif } else @@ -959,8 +960,8 @@ namespace FreeSql.Internal.CommonProvider { #if net40 #else - if (selectExp == null) subList = await subSelect.ToListAsync(true); - else subList = await subSelect.ToListAsync(selectExp); + if (selectExp == null) subList = await subSelect.ToListAsync(true, cancellationToken); + else subList = await subSelect.ToListAsync(selectExp, cancellationToken); #endif } else @@ -1084,8 +1085,8 @@ namespace FreeSql.Internal.CommonProvider { #if net40 #else - if (selectExp == null) subList = await subSelect.ToListAfPrivateAsync(sbSql.ToString(), af, otherData == null ? null : new[] { new ReadAnonymousTypeOtherInfo(otherData.field, otherData.map, midList) }); - else subList = await subSelect.ToListMrPrivateAsync(sbSql.ToString(), mf, otherData == null ? null : new[] { new ReadAnonymousTypeOtherInfo(otherData.field, otherData.map, midList) }); + if (selectExp == null) subList = await subSelect.ToListAfPrivateAsync(sbSql.ToString(), af, otherData == null ? null : new[] { new ReadAnonymousTypeOtherInfo(otherData.field, otherData.map, midList) }, cancellationToken); + else subList = await subSelect.ToListMrPrivateAsync(sbSql.ToString(), mf, otherData == null ? null : new[] { new ReadAnonymousTypeOtherInfo(otherData.field, otherData.map, midList) }, cancellationToken); #endif } else @@ -1162,10 +1163,10 @@ namespace FreeSql.Internal.CommonProvider #else _includeToList.Add(listObj => { - var task = includeToListSyncOrAsync(listObj, false); + var task = includeToListSyncOrAsync(listObj, false, default); if (task.Exception != null) throw task.Exception.InnerException ?? task.Exception; }); - _includeToListAsync.Add(listObj => includeToListSyncOrAsync(listObj, true)); + _includeToListAsync.Add((listObj, cancellationToken) => includeToListSyncOrAsync(listObj, true, cancellationToken)); #endif var includeValue = new MemberExpression[members.Count + 1]; for (var a = 0; a < members.Count; a++) includeValue[a] = members[a]; @@ -1184,41 +1185,41 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - async internal Task SetListAsync(IEnumerable list) + async internal Task SetListAsync(IEnumerable list, CancellationToken cancellationToken = default) { - foreach (var include in _includeToListAsync) await include?.Invoke(list); + foreach (var include in _includeToListAsync) await include?.Invoke(list, cancellationToken); _trackToList?.Invoke(list); } - public Task AvgAsync(Expression> column) + public Task AvgAsync(Expression> column, CancellationToken cancellationToken = default) { if (column == null) return Task.FromResult(default(double)); _tables[0].Parameter = column.Parameters[0]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body, cancellationToken); } - public Task MaxAsync(Expression> column) + public Task MaxAsync(Expression> column, CancellationToken cancellationToken = default) { if (column == null) return Task.FromResult(default(TMember)); _tables[0].Parameter = column.Parameters[0]; - return this.InternalMaxAsync(column?.Body); + return this.InternalMaxAsync(column?.Body, cancellationToken); } - public Task MinAsync(Expression> column) + public Task MinAsync(Expression> column, CancellationToken cancellationToken = default) { if (column == null) return Task.FromResult(default(TMember)); _tables[0].Parameter = column.Parameters[0]; - return this.InternalMinAsync(column?.Body); + return this.InternalMinAsync(column?.Body, cancellationToken); } - public Task SumAsync(Expression> column) + public Task SumAsync(Expression> column, CancellationToken cancellationToken = default) { if (column == null) return Task.FromResult(default(decimal)); _tables[0].Parameter = column.Parameters[0]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body, cancellationToken); } - async public Task> ToListAsync(Expression> select) + async public Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default) { - if (select == null) return await this.InternalToListAsync(select?.Body); + if (select == null) return await this.InternalToListAsync(select?.Body, cancellationToken); _tables[0].Parameter = select.Parameters[0]; - if (_includeToList?.Any() != true) return await this.InternalToListAsync(select.Body); + if (_includeToList?.Any() != true) return await this.InternalToListAsync(select.Body, cancellationToken); var findIncludeMany = new List(); //支持指定已经使用 IncudeMany 的导航属性 var map = new ReadAnonymousTypeInfo(); @@ -1226,7 +1227,7 @@ namespace FreeSql.Internal.CommonProvider var index = 0; _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select.Body, this, null, _whereGlobalFilter, findIncludeMany, true); var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); - if (findIncludeMany.Any() == false) return await this.ToListMapReaderPrivateAsync(af, null); + if (findIncludeMany.Any() == false) return await this.ToListMapReaderPrivateAsync(af, null, cancellationToken); var parmExp = Expression.Parameter(_tables[0].Table.Type, _tables[0].Alias); var incNewInit = new IncludeManyNewInit(_tables[0].Table, parmExp); @@ -1253,7 +1254,7 @@ namespace FreeSql.Internal.CommonProvider } var otherNewInit = GetIncludeManyNewInitExpression(incNewInit); //获取 IncludeMany 包含的最简化字段 - if (otherNewInit.Bindings.Any() == false) return await this.ToListMapReaderPrivateAsync(af, null); + if (otherNewInit.Bindings.Any() == false) return await this.ToListMapReaderPrivateAsync(af, null, cancellationToken); var otherMap = new ReadAnonymousTypeInfo(); field.Clear(); @@ -1262,8 +1263,8 @@ namespace FreeSql.Internal.CommonProvider var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); af.fillIncludeMany = new List>(); - var ret = await this.ToListMapReaderPrivateAsync(af, new[] { otherAf }); - await this.SetListAsync(otherRet.Select(a => (T1)a).ToList()); //级联加载 + var ret = await this.ToListMapReaderPrivateAsync(af, new[] { otherAf }, cancellationToken); + await this.SetListAsync(otherRet.Select(a => (T1)a).ToList(), cancellationToken); //级联加载 foreach (var fim in af.fillIncludeMany) { @@ -1281,35 +1282,35 @@ namespace FreeSql.Internal.CommonProvider } return ret; } - public Task> ToListAsync() => ToListAsync(GetToListDtoSelector()); + public Task> ToListAsync(CancellationToken cancellationToken = default) => ToListAsync(GetToListDtoSelector(), cancellationToken); - public Task InsertIntoAsync(string tableName, Expression> select) where TTargetEntity : class => base.InternalInsertIntoAsync(tableName, select); + public Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class => base.InternalInsertIntoAsync(tableName, select, cancellationToken); - public Task ToDataTableAsync(Expression> select) + public Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); _tables[0].Parameter = select.Parameters[0]; - return this.InternalToDataTableAsync(select?.Body); + return this.InternalToDataTableAsync(select?.Body, cancellationToken); } - public Task ToAggregateAsync(Expression, TReturn>> select) + public Task ToAggregateAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default) { if (select == null) return Task.FromResult(default(TReturn)); _tables[0].Parameter = select.Parameters[0]; - return this.InternalToAggregateAsync(select?.Body); + return this.InternalToAggregateAsync(select?.Body, cancellationToken); } - async public Task AnyAsync(Expression> exp) + async public Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default) { var oldwhere = _where.ToString(); - var ret = await this.Where(exp).AnyAsync(); + var ret = await this.Where(exp).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } - async public Task ToOneAsync(Expression> select) => (await this.Limit(1).ToListAsync(select)).FirstOrDefault(); - async public Task ToOneAsync() => (await this.Limit(1).ToListAsync()).FirstOrDefault(); - public Task FirstAsync(Expression> select) => this.ToOneAsync(select); - public Task FirstAsync() => this.ToOneAsync(); - public override Task> ToListAsync(bool includeNestedMembers = false) => base.ToListAsync(_isIncluded || includeNestedMembers); + async public Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default) => (await this.Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async public Task ToOneAsync(CancellationToken cancellationToken = default) => (await this.Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + public Task FirstAsync(Expression> select, CancellationToken cancellationToken = default) => this.ToOneAsync(select, cancellationToken); + public Task FirstAsync(CancellationToken cancellationToken = default) => this.ToOneAsync(cancellationToken); + public override Task> ToListAsync(bool includeNestedMembers = false, CancellationToken cancellationToken = default) => base.ToListAsync(_isIncluded || includeNestedMembers, cancellationToken); #endif } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider2`16.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider2`16.cs new file mode 100644 index 00000000..6daa6e10 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider2`16.cs @@ -0,0 +1,7005 @@ + +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider +{ + + public abstract class Select2Provider : Select0Provider, T1>, ISelect + where T2 : class + { + + public Select2Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select3Provider : Select0Provider, T1>, ISelect + where T2 : class where T3 : class + { + + public Select3Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select4Provider : Select0Provider, T1>, ISelect + where T2 : class where T3 : class where T4 : class + { + + public Select4Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select5Provider : Select0Provider, T1>, ISelect + where T2 : class where T3 : class where T4 : class where T5 : class + { + + public Select5Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select6Provider : Select0Provider, T1>, ISelect + where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + + public Select6Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select7Provider : Select0Provider, T1>, ISelect + where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + + public Select7Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select8Provider : Select0Provider, T1>, ISelect + where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + + public Select8Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select9Provider : Select0Provider, T1>, ISelect + where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class + { + + public Select9Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select10Provider : Select0Provider, T1>, ISelect + 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 + { + + public Select10Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select11Provider : Select0Provider, T1>, ISelect + 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 + { + + public Select11Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select12Provider : Select0Provider, T1>, ISelect + 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 + { + + public Select12Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select13Provider : Select0Provider, T1>, ISelect + 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 + { + + public Select13Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select14Provider : Select0Provider, T1>, ISelect + 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 + { + + public Select14Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; + if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select15Provider : Select0Provider, T1>, ISelect + 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 + { + + public Select15Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T15)), Alias = $"SP10o", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; + if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; + if (type == _tables[14].Table?.Type && string.IsNullOrEmpty(sqlT15) == false) return $"({sqlT15})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n"), Expression.Parameter(typeof(T15), "o")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + + + public abstract class Select16Provider : Select0Provider, T1>, ISelect + 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 + { + + public Select16Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) + { + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15), typeof(T16)); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T10)), Alias = $"SP10j", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T11)), Alias = $"SP10k", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T12)), Alias = $"SP10l", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T13)), Alias = $"SP10m", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T14)), Alias = $"SP10n", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T15)), Alias = $"SP10o", On = null, Type = SelectTableInfoType.From }); + _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T16)), Alias = $"SP10p", On = null, Type = SelectTableInfoType.From }); + + } + + ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms) + { + this.AsTable((type, old) => + { + if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; + if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; + if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; + if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; + if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; + if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; + if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; + if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; + if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; + if (type == _tables[9].Table?.Type && string.IsNullOrEmpty(sqlT10) == false) return $"({sqlT10})"; + if (type == _tables[10].Table?.Type && string.IsNullOrEmpty(sqlT11) == false) return $"({sqlT11})"; + if (type == _tables[11].Table?.Type && string.IsNullOrEmpty(sqlT12) == false) return $"({sqlT12})"; + if (type == _tables[12].Table?.Type && string.IsNullOrEmpty(sqlT13) == false) return $"({sqlT13})"; + if (type == _tables[13].Table?.Type && string.IsNullOrEmpty(sqlT14) == false) return $"({sqlT14})"; + if (type == _tables[14].Table?.Type && string.IsNullOrEmpty(sqlT15) == false) return $"({sqlT15})"; + if (type == _tables[15].Table?.Type && string.IsNullOrEmpty(sqlT16) == false) return $"({sqlT16})"; + + return old; + }); + if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9};\r\n{sqlT10};\r\n{sqlT11};\r\n{sqlT12};\r\n{sqlT13};\r\n{sqlT14};\r\n{sqlT15};\r\n{sqlT16}", parms)); + return this; + } + + double ISelect.Avg(Expression> column) + { + if (column == null) return default(double); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvg(column?.Body); + } + + ISelectGrouping> ISelect.GroupBy(Expression> exp) + { + if (exp == null) return this.InternalGroupBy>(exp?.Body); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalGroupBy>(exp?.Body); + } + + TMember ISelect.Max(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMax(column?.Body); + } + + TMember ISelect.Min(Expression> column) + { + if (column == null) return default(TMember); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMin(column?.Body); + } + + ISelect ISelect.OrderBy(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderBy(column?.Body); + } + + ISelect ISelect.OrderByDescending(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalOrderByDescending(column?.Body); + } + + ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) + { + if (condition == false || column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); + } + + decimal ISelect.Sum(Expression> column) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSum(column?.Body); + } + + TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) + { + if (select == null) return default(TReturn); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregate(select?.Body); + } + ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) + { + result = (this as ISelect).ToAggregate(select); + return this; + } + + List ISelect.ToList(Expression> select) + { + if (select == null) return this.InternalToList(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToList(select?.Body); + } + + List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); + Expression> GetToListDtoSelector() + { + return Expression.Lambda>( + typeof(TDto).InternalNewExpression(), + _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i"), Expression.Parameter(typeof(T10), "j"), Expression.Parameter(typeof(T11), "k"), Expression.Parameter(typeof(T12), "l"), Expression.Parameter(typeof(T13), "m"), Expression.Parameter(typeof(T14), "n"), Expression.Parameter(typeof(T15), "o"), Expression.Parameter(typeof(T16), "p")); + } + + public void ToChunk(Expression> select, int size, Action>> done) + { + if (select == null || done == null) return; + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + this.InternalToChunk(select.Body, size, done); + } + + DataTable ISelect.ToDataTable(Expression> select) + { + if (select == null) return this.InternalToDataTable(select?.Body); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTable(select?.Body); + } + + int ISelect.InsertInto(string tableName, Expression> select) + { + if (select == null) return this.InternalInsertInto(tableName, select); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertInto(tableName, select?.Body); + } + + string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) + { + if (select == null) return this.InternalToSql(select?.Body, fieldAlias); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToSql(select?.Body, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + } + + ISelect ISelect.InnerJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); + } + + ISelect ISelect.RightJoin(Expression> exp) + { + if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); + } + + ISelect ISelect.Where(Expression> exp) + { + if (exp == null) return this.Where(null); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + ISelect ISelect.WhereIf(bool condition, Expression> exp) + { + if (condition == false || exp == null) return this; + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); + } + + bool ISelect.Any(Expression> exp) + { + if (exp == null) return this.Any(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + _where.Clear().Append(oldwhere); + return ret; + } + + TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); + + + + + + #region HzyTuple 元组 + + double ISelect.Avg(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Avg((Expression>)expModify); + } + + ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).GroupBy((Expression>)expModify); + } + + TMember ISelect.Max(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Max((Expression>)expModify); + } + + TMember ISelect.Min(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Min((Expression>)expModify); + } + + ISelect ISelect.OrderBy(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderBy((Expression>)expModify); + } + + ISelect ISelect.OrderByDescending(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByDescending((Expression>)expModify); + } + + ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); + } + + decimal ISelect.Sum(Expression, TMember>> column) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).Sum((Expression>)expModify); + } + + List ISelect.ToList(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToList((Expression>)expModify); + } + + public void ToChunk(Expression, TReturn>> select, int size, Action>> done) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + (this as ISelect).ToChunk((Expression>)expModify, size, done); + } + + DataTable ISelect.ToDataTable(Expression, TReturn>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTable((Expression>)expModify); + } + + int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertInto(tableName, (Expression>)expModify); + } + + string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); + } + + ISelect ISelect.LeftJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).LeftJoin((Expression>)expModify); + } + + ISelect ISelect.InnerJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).InnerJoin((Expression>)expModify); + } + + ISelect ISelect.RightJoin(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).RightJoin((Expression>)expModify); + } + + ISelect ISelect.Where(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Where((Expression>)expModify); + } + + ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).WhereIf(condition, (Expression>)expModify); + } + + bool ISelect.Any(Expression, bool>> exp) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return (this as ISelect).Any((Expression>)expModify); + } + + TReturn ISelect.ToOne(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + TReturn ISelect.First(Expression, TReturn>> select) + => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); + + #endregion + + + +#if net40 +#else + Task ISelect.AvgAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(double)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalAvgAsync(column?.Body, cancellationToken); + } + + Task ISelect.MaxAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMaxAsync(column?.Body, cancellationToken); + } + + Task ISelect.MinAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) return Task.FromResult(default(TMember)); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalMinAsync(column?.Body, cancellationToken); + } + + Task ISelect.SumAsync(Expression> column, CancellationToken cancellationToken) + { + if (column == null) this.InternalOrderBy(column?.Body); + for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; + return this.InternalSumAsync(column?.Body, cancellationToken); + } + + Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken) + { + if (select == null) return Task.FromResult(default(TReturn)); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToAggregateAsync(select?.Body, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToListAsync(select?.Body, cancellationToken); + } + Task> ISelect.ToListAsync(CancellationToken cancellationToken) => (this as ISelect).ToListAsync(GetToListDtoSelector(), cancellationToken); + + Task ISelect.ToDataTableAsync(Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalToDataTableAsync(select?.Body, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) + { + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); + for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression> exp, CancellationToken cancellationToken) + { + if (exp == null) return await this.AnyAsync(); + for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; + var oldwhere = _where.ToString(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + _where.Clear().Append(oldwhere); + return ret; + } + + async Task ISelect.ToOneAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression> select, CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); + + + + + #region HzyTuple 元组 + + Task ISelect.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).AvgAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MaxAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).MinAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); + return (this as ISelect).SumAsync((Expression>)expModify, cancellationToken); + } + + Task> ISelect.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToListAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).ToDataTableAsync((Expression>)expModify, cancellationToken); + } + + Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); + return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify, cancellationToken); + } + + async Task ISelect.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); + return await (this as ISelect).AnyAsync((Expression>)expModify, cancellationToken); + } + + async Task ISelect.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + + + #endregion + +#endif + } + + +} + + diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs deleted file mode 100644 index 1e550e25..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ /dev/null @@ -1,462 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - public abstract class Select2Provider : Select0Provider, T1>, ISelect - where T2 : class - { - - public Select2Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs deleted file mode 100644 index 8d7f5b40..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ /dev/null @@ -1,464 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - public abstract class Select3Provider : Select0Provider, T1>, ISelect - where T2 : class where T3 : class - { - - public Select3Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs deleted file mode 100644 index 5890fa7f..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ /dev/null @@ -1,468 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select4Provider : Select0Provider, T1>, ISelect - where T2 : class where T3 : class where T4 : class - { - - public Select4Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs deleted file mode 100644 index 7ce48dac..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ /dev/null @@ -1,468 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - public abstract class Select5Provider : Select0Provider, T1>, ISelect - where T2 : class where T3 : class where T4 : class where T5 : class - { - - public Select5Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs deleted file mode 100644 index 7c39a101..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ /dev/null @@ -1,469 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - public abstract class Select6Provider : Select0Provider, T1>, ISelect - where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class - { - - public Select6Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs deleted file mode 100644 index 117039f2..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ /dev/null @@ -1,477 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - - - public abstract class Select7Provider : Select0Provider, T1>, ISelect - where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class - { - - public Select7Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs deleted file mode 100644 index 10f6a5a6..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ /dev/null @@ -1,474 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - public abstract class Select8Provider : Select0Provider, T1>, ISelect - where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class - { - - public Select8Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs deleted file mode 100644 index 186d3d17..00000000 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ /dev/null @@ -1,476 +0,0 @@ -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql.Internal.CommonProvider -{ - - public abstract class Select9Provider : Select0Provider, T1>, ISelect - where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class - { - - public Select9Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) - { - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9)); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T2)), Alias = $"SP10b", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T3)), Alias = $"SP10c", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T4)), Alias = $"SP10d", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T5)), Alias = $"SP10e", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T6)), Alias = $"SP10f", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T7)), Alias = $"SP10g", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T8)), Alias = $"SP10h", On = null, Type = SelectTableInfoType.From }); - _tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T9)), Alias = $"SP10i", On = null, Type = SelectTableInfoType.From }); - - } - - ISelect ISelect.WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms) - { - this.AsTable((type, old) => - { - if (type == _tables[0].Table?.Type && string.IsNullOrEmpty(sqlT1) == false) return $"({sqlT1})"; - if (type == _tables[1].Table?.Type && string.IsNullOrEmpty(sqlT2) == false) return $"({sqlT2})"; - if (type == _tables[2].Table?.Type && string.IsNullOrEmpty(sqlT3) == false) return $"({sqlT3})"; - if (type == _tables[3].Table?.Type && string.IsNullOrEmpty(sqlT4) == false) return $"({sqlT4})"; - if (type == _tables[4].Table?.Type && string.IsNullOrEmpty(sqlT5) == false) return $"({sqlT5})"; - if (type == _tables[5].Table?.Type && string.IsNullOrEmpty(sqlT6) == false) return $"({sqlT6})"; - if (type == _tables[6].Table?.Type && string.IsNullOrEmpty(sqlT7) == false) return $"({sqlT7})"; - if (type == _tables[7].Table?.Type && string.IsNullOrEmpty(sqlT8) == false) return $"({sqlT8})"; - if (type == _tables[8].Table?.Type && string.IsNullOrEmpty(sqlT9) == false) return $"({sqlT9})"; - - return old; - }); - if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject($"{sqlT1};\r\n{sqlT2};\r\n{sqlT3};\r\n{sqlT4};\r\n{sqlT5};\r\n{sqlT6};\r\n{sqlT7};\r\n{sqlT8};\r\n{sqlT9}", parms)); - return this; - } - - double ISelect.Avg(Expression> column) - { - if (column == null) return default(double); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvg(column?.Body); - } - - ISelectGrouping> ISelect.GroupBy(Expression> exp) - { - if (exp == null) return this.InternalGroupBy>(exp?.Body); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalGroupBy>(exp?.Body); - } - - TMember ISelect.Max(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMax(column?.Body); - } - - TMember ISelect.Min(Expression> column) - { - if (column == null) return default(TMember); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMin(column?.Body); - } - - ISelect ISelect.OrderBy(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderBy(column?.Body); - } - - ISelect ISelect.OrderByDescending(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalOrderByDescending(column?.Body); - } - - ISelect ISelect.OrderByIf(bool condition, Expression> column, bool descending) - { - if (condition == false || column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return descending ? this.InternalOrderByDescending(column?.Body) : this.InternalOrderBy(column?.Body); - } - - decimal ISelect.Sum(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSum(column?.Body); - } - - TReturn ISelect.ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return default(TReturn); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregate(select?.Body); - } - ISelect ISelect.Aggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, out TReturn result) - { - result = (this as ISelect).ToAggregate(select); - return this; - } - - List ISelect.ToList(Expression> select) - { - if (select == null) return this.InternalToList(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToList(select?.Body); - } - - List ISelect.ToList() => (this as ISelect).ToList(GetToListDtoSelector()); - Expression> GetToListDtoSelector() - { - return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"), Expression.Parameter(typeof(T2), "b"), Expression.Parameter(typeof(T3), "c"), Expression.Parameter(typeof(T4), "d"), Expression.Parameter(typeof(T5), "e"), Expression.Parameter(typeof(T6), "f"), Expression.Parameter(typeof(T7), "g"), Expression.Parameter(typeof(T8), "h"), Expression.Parameter(typeof(T9), "i")); - } - - public void ToChunk(Expression> select, int size, Action>> done) - { - if (select == null || done == null) return; - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - this.InternalToChunk(select.Body, size, done); - } - - DataTable ISelect.ToDataTable(Expression> select) - { - if (select == null) return this.InternalToDataTable(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTable(select?.Body); - } - - int ISelect.InsertInto(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertInto(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertInto(tableName, select?.Body); - } - - string ISelect.ToSql(Expression> select, FieldAliasOptions fieldAlias) - { - if (select == null) return this.InternalToSql(select?.Body, fieldAlias); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToSql(select?.Body, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - } - - ISelect ISelect.InnerJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin); - } - - ISelect ISelect.RightJoin(Expression> exp) - { - if (exp == null) return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin); - } - - ISelect ISelect.Where(Expression> exp) - { - if (exp == null) return this.Where(null); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - ISelect ISelect.WhereIf(bool condition, Expression> exp) - { - if (condition == false || exp == null) return this; - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)); - } - - bool ISelect.Any(Expression> exp) - { - if (exp == null) return this.Any(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).Any(); - _where.Clear().Append(oldwhere); - return ret; - } - - TReturn ISelect.ToOne(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression> select) => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TDto ISelect.First() => (this as ISelect).Limit(1).ToList().FirstOrDefault(); - - - - - - #region HzyTuple 元组 - - double ISelect.Avg(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Avg((Expression>)expModify); - } - - ISelectGrouping> ISelect.GroupBy(Expression, TKey>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).GroupBy((Expression>)expModify); - } - - TMember ISelect.Max(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Max((Expression>)expModify); - } - - TMember ISelect.Min(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Min((Expression>)expModify); - } - - ISelect ISelect.OrderBy(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderBy((Expression>)expModify); - } - - ISelect ISelect.OrderByDescending(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByDescending((Expression>)expModify); - } - - ISelect ISelect.OrderByIf(bool condition, Expression, TMember>> column, bool descending) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).OrderByIf(condition, (Expression>)expModify, descending); - } - - decimal ISelect.Sum(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).Sum((Expression>)expModify); - } - - List ISelect.ToList(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToList((Expression>)expModify); - } - - public void ToChunk(Expression, TReturn>> select, int size, Action>> done) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - (this as ISelect).ToChunk((Expression>)expModify, size, done); - } - - DataTable ISelect.ToDataTable(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTable((Expression>)expModify); - } - - int ISelect.InsertInto(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertInto(tableName, (Expression>)expModify); - } - - string ISelect.ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToSql((Expression>)expModify, fieldAlias); - } - - ISelect ISelect.LeftJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).LeftJoin((Expression>)expModify); - } - - ISelect ISelect.InnerJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).InnerJoin((Expression>)expModify); - } - - ISelect ISelect.RightJoin(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).RightJoin((Expression>)expModify); - } - - ISelect ISelect.Where(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Where((Expression>)expModify); - } - - ISelect ISelect.WhereIf(bool condition, Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).WhereIf(condition, (Expression>)expModify); - } - - bool ISelect.Any(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return (this as ISelect).Any((Expression>)expModify); - } - - TReturn ISelect.ToOne(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - TReturn ISelect.First(Expression, TReturn>> select) - => (this as ISelect).Limit(1).ToList(select).FirstOrDefault(); - - #endregion - - - -#if net40 -#else - Task ISelect.AvgAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(double)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); - } - - Task ISelect.MaxAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); - } - - Task ISelect.MinAsync(Expression> column) - { - if (column == null) return Task.FromResult(default(TMember)); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); - } - - Task ISelect.SumAsync(Expression> column) - { - if (column == null) this.InternalOrderBy(column?.Body); - for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); - } - - Task ISelect.ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select) - { - if (select == null) return Task.FromResult(default(TReturn)); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); - } - - Task> ISelect.ToListAsync(Expression> select) - { - if (select == null) return this.InternalToListAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); - } - Task> ISelect.ToListAsync() => (this as ISelect).ToListAsync(GetToListDtoSelector()); - - Task ISelect.ToDataTableAsync(Expression> select) - { - if (select == null) return this.InternalToDataTableAsync(select?.Body); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression> select) - { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); - for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); - } - - async Task ISelect.AnyAsync(Expression> exp) - { - if (exp == null) return await this.AnyAsync(); - for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); - _where.Clear().Append(oldwhere); - return ret; - } - - async Task ISelect.ToOneAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression> select) => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync() => (await (this as ISelect).Limit(1).ToListAsync()).FirstOrDefault(); - - - - - #region HzyTuple 元组 - - Task ISelect.AvgAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).AvgAsync((Expression>)expModify); - } - - Task ISelect.MaxAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MaxAsync((Expression>)expModify); - } - - Task ISelect.MinAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).MinAsync((Expression>)expModify); - } - - Task ISelect.SumAsync(Expression, TMember>> column) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect).SumAsync((Expression>)expModify); - } - - Task> ISelect.ToListAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToListAsync((Expression>)expModify); - } - - Task ISelect.ToDataTableAsync(Expression, TReturn>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).ToDataTableAsync((Expression>)expModify); - } - - Task ISelect.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect).InsertIntoAsync(tableName, (Expression>)expModify); - } - - async Task ISelect.AnyAsync(Expression, bool>> exp) - { - var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect).AnyAsync((Expression>)expModify); - } - - async Task ISelect.ToOneAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect.FirstAsync(Expression, TReturn>> select) - => (await (this as ISelect).Limit(1).ToListAsync(select)).FirstOrDefault(); - - - #endregion - -#endif - } - -} \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 33299b9f..44c1b28d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider @@ -98,7 +99,7 @@ namespace FreeSql.Internal.CommonProvider var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { isDescending ? $"{sql} DESC" : sql, null }); } - public object InternalToList(Expression select, Type elementType, bool isAsync) + public object InternalToList(Expression select, Type elementType) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); @@ -106,7 +107,7 @@ namespace FreeSql.Internal.CommonProvider _comonExp.ReadAnonymousField(null, field, map, ref index, select, null, this, null, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; - var method = _select.GetType().GetMethod(isAsync ? "ToListMapReaderAsync" : "ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); + var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(elementType); return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }); } @@ -194,15 +195,26 @@ namespace FreeSql.Internal.CommonProvider } public List Select(Expression, TReturn>> select) => ToList(select); - public List ToList(Expression, TReturn>> select) => InternalToList(select, typeof(TReturn), false) as List; + public List ToList(Expression, TReturn>> select) => InternalToList(select, typeof(TReturn)) as List; public Dictionary ToDictionary(Expression, TElement>> elementSelector) => InternalToKeyValuePairs(elementSelector, typeof(TElement)).ToDictionary(a => (TKey)a.Key, a => (TElement)a.Value); #if net40 #else - async public Task CountAsync() => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_select._connection, _select._transaction, CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._commandTimeout, _select._params.ToArray())), out var trylng) ? trylng : default(long); + async public Task CountAsync(CancellationToken cancellationToken = default) => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_select._connection, _select._transaction, CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._commandTimeout, _select._params.ToArray(), cancellationToken)), out var trylng) ? trylng : default(long); - public Task> ToListAsync(Expression, TReturn>> select) => InternalToList(select, typeof(TReturn), true) as Task>; - async public Task> ToDictionaryAsync(Expression, TElement>> elementSelector) + public Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default) + { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + + _comonExp.ReadAnonymousField(null, field, map, ref index, select, null, this, null, null, false); + if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); + var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic); + method = method.MakeGenericMethod(typeof(TReturn)); + return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null), cancellationToken }) as Task>; + } + async public Task> ToDictionaryAsync(Expression, TElement>> elementSelector, CancellationToken cancellationToken = default) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); @@ -213,7 +225,7 @@ namespace FreeSql.Internal.CommonProvider var method = _select.GetType().GetMethod("ToListMapReaderPrivateAsync", BindingFlags.Instance | BindingFlags.NonPublic); method = method.MakeGenericMethod(typeof(TElement)); var otherAf = new ReadAnonymousTypeOtherInfo(_field, _map, new List()); - var values = await (method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null), new[] { otherAf } }) as Task>); + var values = await (method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null), new[] { otherAf }, cancellationToken }) as Task>); return otherAf.retlist.Select((a, b) => new KeyValuePair((TKey)a, values[b])).ToDictionary(a => a.Key, a => a.Value); } #endif diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect.tt b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt similarity index 81% rename from FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect.tt rename to FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt index ad346020..e4064230 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect.tt +++ b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt @@ -3,9 +3,10 @@ <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> <# - if (1 == 2) + if (1 == 1) { #> using FreeSql.Internal.Model; @@ -13,6 +14,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -49,36 +51,36 @@ public interface ISelect<<#=NewStr #>> : ISelect0>, T1> <#= #if net40 #else - Task AnyAsync(Expression, bool>> exp); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select); - Task> ToListAsync(Expression, TReturn>> select); - Task> ToListAsync(); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(CancellationToken cancellationToken); - Task ToOneAsync(Expression, TReturn>> select); - Task FirstAsync(Expression, TReturn>> select); - Task FirstAsync(); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(CancellationToken cancellationToken); - Task ToAggregateAsync(Expression, TReturn>> select); - Task SumAsync(Expression, TMember>> column); - Task MinAsync(Expression, TMember>> column); - Task MaxAsync(Expression, TMember>> column); - Task AvgAsync(Expression, TMember>> column); + Task ToAggregateAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); #region HzyTuple 元组 - Task AnyAsync(Expression>, bool>> exp); - Task InsertIntoAsync(string tableName, Expression>, TTargetEntity>> select) where TTargetEntity : class; - Task ToDataTableAsync(Expression>, TReturn>> select); - Task> ToListAsync(Expression>, TReturn>> select); + Task AnyAsync(Expression>, bool>> exp, CancellationToken cancellationToken); + Task InsertIntoAsync(string tableName, Expression>, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; + Task ToDataTableAsync(Expression>, TReturn>> select, CancellationToken cancellationToken); + Task> ToListAsync(Expression>, TReturn>> select, CancellationToken cancellationToken); - Task ToOneAsync(Expression>, TReturn>> select); - Task FirstAsync(Expression>, TReturn>> select); + Task ToOneAsync(Expression>, TReturn>> select, CancellationToken cancellationToken); + Task FirstAsync(Expression>, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression>, TMember>> column); - Task MinAsync(Expression>, TMember>> column); - Task MaxAsync(Expression>, TMember>> column); - Task AvgAsync(Expression>, TMember>> column); + Task SumAsync(Expression>, TMember>> column, CancellationToken cancellationToken); + Task MinAsync(Expression>, TMember>> column, CancellationToken cancellationToken); + Task MaxAsync(Expression>, TMember>> column, CancellationToken cancellationToken); + Task AvgAsync(Expression>, TMember>> column, CancellationToken cancellationToken); #endregion diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/SelectProvider.tt b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/Select1Provider2`16.tt similarity index 87% rename from FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/SelectProvider.tt rename to FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/Select1Provider2`16.tt index 2c5314e9..a52eb6ba 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/SelectProvider.tt +++ b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/Select1Provider2`16.tt @@ -3,6 +3,7 @@ <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> <# if (1 == 2) @@ -14,12 +15,12 @@ using System.Collections.Generic; using System.Data; using System.Linq; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { - - <# +<# var Str = ""; var whereStr = ""; var ISelectGroupingAggregate = new List(); @@ -40,9 +41,7 @@ namespace FreeSql.Internal.CommonProvider { Str += "T" + i + ","; var NewStr = Str.Substring(0, Str.Length - 1); -#> - - <# +#><# if (i > 1) { whereStr += $"where T{i} : class "; @@ -50,9 +49,7 @@ namespace FreeSql.Internal.CommonProvider _tables.Append("_tables.Add(new SelectTableInfo { Table = _commonUtils.GetTableByEntity(typeof(T" + i + ")), Alias = $\"SP10" + abc[i - 1] + "\", On = null, Type = SelectTableInfoType.From });\r\n"); - } #> - - <# + } #><# { ISelectGroupingAggregate.Add($"ISelectGroupingAggregate"); WithSql.Add($"string sqlT{i}"); @@ -62,9 +59,7 @@ namespace FreeSql.Internal.CommonProvider ") == false) return $\"({sqlT" + i + "})\";\r\n"); GetDbParamtersByObject.Add("{sqlT" + i + "}"); - } #> - - <# + } #><# if (i == 1) continue; #> public abstract class Select<#=i #>Provider<<#=NewStr #>> : Select0Provider>, T1>, ISelect<<#=NewStr #>> @@ -379,134 +374,134 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - Task ISelect<<#=NewStr #>>.AvgAsync(Expression, TMember>> column) + Task ISelect<<#=NewStr #>>.AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken) { if (column == null) return Task.FromResult(default(double)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalAvgAsync(column?.Body); + return this.InternalAvgAsync(column?.Body, cancellationToken); } - Task ISelect<<#=NewStr #>>.MaxAsync(Expression, TMember>> column) + Task ISelect<<#=NewStr #>>.MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken) { if (column == null) return Task.FromResult(default(TMember)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMaxAsync(column?.Body); + return this.InternalMaxAsync(column?.Body, cancellationToken); } - Task ISelect<<#=NewStr #>>.MinAsync(Expression, TMember>> column) + Task ISelect<<#=NewStr #>>.MinAsync(Expression, TMember>> column, CancellationToken cancellationToken) { if (column == null) return Task.FromResult(default(TMember)); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalMinAsync(column?.Body); + return this.InternalMinAsync(column?.Body, cancellationToken); } - Task ISelect<<#=NewStr #>>.SumAsync(Expression, TMember>> column) + Task ISelect<<#=NewStr #>>.SumAsync(Expression, TMember>> column, CancellationToken cancellationToken) { if (column == null) this.InternalOrderBy(column?.Body); for (var a = 0; a < column.Parameters.Count; a++) _tables[a].Parameter = column.Parameters[a]; - return this.InternalSumAsync(column?.Body); + return this.InternalSumAsync(column?.Body, cancellationToken); } - Task ISelect<<#=NewStr #>>.ToAggregateAsync(Expression, TReturn>> select) + Task ISelect<<#=NewStr #>>.ToAggregateAsync(Expression, TReturn>> select, CancellationToken cancellationToken) { if (select == null) return Task.FromResult(default(TReturn)); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToAggregateAsync(select?.Body); + return this.InternalToAggregateAsync(select?.Body, cancellationToken); } - Task> ISelect<<#=NewStr #>>.ToListAsync(Expression, TReturn>> select) + Task> ISelect<<#=NewStr #>>.ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken) { - if (select == null) return this.InternalToListAsync(select?.Body); + if (select == null) return this.InternalToListAsync(select?.Body, cancellationToken); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToListAsync(select?.Body); + return this.InternalToListAsync(select?.Body, cancellationToken); } - Task> ISelect<<#=NewStr #>>.ToListAsync() => (this as ISelect<<#=NewStr #>>).ToListAsync(GetToListDtoSelector()); + Task> ISelect<<#=NewStr #>>.ToListAsync(CancellationToken cancellationToken) => (this as ISelect<<#=NewStr #>>).ToListAsync(GetToListDtoSelector(), cancellationToken); - Task ISelect<<#=NewStr #>>.ToDataTableAsync(Expression, TReturn>> select) + Task ISelect<<#=NewStr #>>.ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken) { - if (select == null) return this.InternalToDataTableAsync(select?.Body); + if (select == null) return this.InternalToDataTableAsync(select?.Body, cancellationToken); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalToDataTableAsync(select?.Body); + return this.InternalToDataTableAsync(select?.Body, cancellationToken); } - Task ISelect<<#=NewStr #>>.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select) + Task ISelect<<#=NewStr #>>.InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) { - if (select == null) return this.InternalInsertIntoAsync(tableName, select); + if (select == null) return this.InternalInsertIntoAsync(tableName, select, cancellationToken); for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a]; - return this.InternalInsertIntoAsync(tableName, select?.Body); + return this.InternalInsertIntoAsync(tableName, select?.Body, cancellationToken); } - async Task ISelect<<#=NewStr #>>.AnyAsync(Expression, bool>> exp) + async Task ISelect<<#=NewStr #>>.AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken) { if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } - async Task ISelect<<#=NewStr #>>.ToOneAsync(Expression, TReturn>> select) => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect<<#=NewStr #>>.FirstAsync(Expression, TReturn>> select) => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect<<#=NewStr #>>.FirstAsync() => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync()).FirstOrDefault(); + async Task ISelect<<#=NewStr #>>.ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken) => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect<<#=NewStr #>>.FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken) => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect<<#=NewStr #>>.FirstAsync(CancellationToken cancellationToken) => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(cancellationToken)).FirstOrDefault(); #region HzyTuple 元组 - Task ISelect<<#=NewStr #>>.AvgAsync(Expression>, TMember>> column) + Task ISelect<<#=NewStr #>>.AvgAsync(Expression>, TMember>> column, CancellationToken cancellationToken) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect<<#=NewStr #>>).AvgAsync((Expression, TMember>>)expModify); + return (this as ISelect<<#=NewStr #>>).AvgAsync((Expression, TMember>>)expModify, cancellationToken); } - Task ISelect<<#=NewStr #>>.MaxAsync(Expression>, TMember>> column) + Task ISelect<<#=NewStr #>>.MaxAsync(Expression>, TMember>> column, CancellationToken cancellationToken) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect<<#=NewStr #>>).MaxAsync((Expression, TMember>>)expModify); + return (this as ISelect<<#=NewStr #>>).MaxAsync((Expression, TMember>>)expModify, cancellationToken); } - Task ISelect<<#=NewStr #>>.MinAsync(Expression>, TMember>> column) + Task ISelect<<#=NewStr #>>.MinAsync(Expression>, TMember>> column, CancellationToken cancellationToken) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect<<#=NewStr #>>).MinAsync((Expression, TMember>>)expModify); + return (this as ISelect<<#=NewStr #>>).MinAsync((Expression, TMember>>)expModify, cancellationToken); } - Task ISelect<<#=NewStr #>>.SumAsync(Expression>, TMember>> column) + Task ISelect<<#=NewStr #>>.SumAsync(Expression>, TMember>> column, CancellationToken cancellationToken) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); - return (this as ISelect<<#=NewStr #>>).SumAsync((Expression, TMember>>)expModify); + return (this as ISelect<<#=NewStr #>>).SumAsync((Expression, TMember>>)expModify, cancellationToken); } - Task> ISelect<<#=NewStr #>>.ToListAsync(Expression>, TReturn>> select) + Task> ISelect<<#=NewStr #>>.ToListAsync(Expression>, TReturn>> select, CancellationToken cancellationToken) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect<<#=NewStr #>>).ToListAsync((Expression, TReturn>>)expModify); + return (this as ISelect<<#=NewStr #>>).ToListAsync((Expression, TReturn>>)expModify, cancellationToken); } - Task ISelect<<#=NewStr #>>.ToDataTableAsync(Expression>, TReturn>> select) + Task ISelect<<#=NewStr #>>.ToDataTableAsync(Expression>, TReturn>> select, CancellationToken cancellationToken) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect<<#=NewStr #>>).ToDataTableAsync((Expression, TReturn>>)expModify); + return (this as ISelect<<#=NewStr #>>).ToDataTableAsync((Expression, TReturn>>)expModify, cancellationToken); } - Task ISelect<<#=NewStr #>>.InsertIntoAsync(string tableName, Expression>, TTargetEntity>> select) + Task ISelect<<#=NewStr #>>.InsertIntoAsync(string tableName, Expression>, TTargetEntity>> select, CancellationToken cancellationToken) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(select, _tables); - return (this as ISelect<<#=NewStr #>>).InsertIntoAsync(tableName,(Expression, TTargetEntity>>)expModify); + return (this as ISelect<<#=NewStr #>>).InsertIntoAsync(tableName,(Expression, TTargetEntity>>)expModify, cancellationToken); } - async Task ISelect<<#=NewStr #>>.AnyAsync(Expression>, bool>> exp) + async Task ISelect<<#=NewStr #>>.AnyAsync(Expression>, bool>> exp, CancellationToken cancellationToken) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(exp, _tables); - return await (this as ISelect<<#=NewStr #>>).AnyAsync((Expression, bool>>)expModify); + return await (this as ISelect<<#=NewStr #>>).AnyAsync((Expression, bool>>)expModify, cancellationToken); } - async Task ISelect<<#=NewStr #>>.ToOneAsync(Expression>, TReturn>> select) - => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select)).FirstOrDefault(); - async Task ISelect<<#=NewStr #>>.FirstAsync(Expression>, TReturn>> select) - => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select)).FirstOrDefault(); + async Task ISelect<<#=NewStr #>>.ToOneAsync(Expression>, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); + async Task ISelect<<#=NewStr #>>.FirstAsync(Expression>, TReturn>> select, CancellationToken cancellationToken) + => (await (this as ISelect<<#=NewStr #>>).Limit(1).ToListAsync(select, cancellationToken)).FirstOrDefault(); #endregion diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs index 87c24e7c..ed18ca2c 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; +using System.Threading; #if MySqlConnector using MySqlConnector; #else @@ -89,7 +90,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions } #if net40 #else - async public static Task ExecuteMySqlBulkCopyAsync(this IInsert that, int? bulkCopyTimeout = null) where T : class + async public static Task ExecuteMySqlBulkCopyAsync(this IInsert that, int? bulkCopyTimeout = null, CancellationToken cancellationToken = default) where T : class { var insert = that as FreeSql.MySql.Curd.MySqlInsert; if (insert == null) throw new Exception("ExecuteMySqlBulkCopyAsync 是 FreeSql.Provider.MySqlConnector 特有的功能"); @@ -101,7 +102,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions { if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; bulkCopy.DestinationTableName = dt.TableName; - return bulkCopy.WriteToServerAsync(dt); + return bulkCopy.WriteToServerAsync(dt, cancellationToken); }; try @@ -124,7 +125,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions if (conn.State != System.Data.ConnectionState.Open) { isNotOpen = true; - conn.Open(); + await conn.OpenAsync(cancellationToken); } try { @@ -133,7 +134,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions finally { if (isNotOpen) - conn.Close(); + await conn.CloseAsync(); } } else diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs index b2c75baf..265f9747 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExtensions.cs @@ -5,6 +5,7 @@ using System; using System.Data; using System.Linq.Expressions; using System.Text; +using System.Threading; using System.Threading.Tasks; public static partial class FreeSqlPostgreSQLGlobalExtensions @@ -119,7 +120,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions #if net45 #else - async public static Task ExecutePgCopyAsync(this IInsert that) where T : class + async public static Task ExecutePgCopyAsync(this IInsert that, CancellationToken cancellationToken = default) where T : class { var insert = that as FreeSql.PostgreSQL.Curd.PostgreSQLInsert; if (insert == null) throw new Exception("ExecutePgCopyAsync 是 FreeSql.Provider.PostgreSQL 特有的功能"); @@ -139,7 +140,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions using (var writer = conn.BeginBinaryImport(copyFromCommand.ToString())) { foreach (DataRow item in dt.Rows) - await writer.WriteRowAsync(System.Threading.CancellationToken.None, item.ItemArray); + await writer.WriteRowAsync(cancellationToken, item.ItemArray); writer.Complete(); } copyFromCommand.Clear(); @@ -165,7 +166,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions if (conn.State != System.Data.ConnectionState.Open) { isNotOpen = true; - await conn.OpenAsync(); + await conn.OpenAsync(cancellationToken); } try { diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index 3c294f85..a3fe2972 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -3,6 +3,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Threading; #if microsoft using Microsoft.Data.SqlClient; #else @@ -146,7 +147,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions } #if net40 #else - async public static Task ExecuteSqlBulkCopyAsync(this IInsert that, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? batchSize = null, int? bulkCopyTimeout = null) where T : class + async public static Task ExecuteSqlBulkCopyAsync(this IInsert that, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? batchSize = null, int? bulkCopyTimeout = null, CancellationToken cancellationToken = default) where T : class { var insert = that as FreeSql.SqlServer.Curd.SqlServerInsert; if (insert == null) throw new Exception("ExecuteSqlBulkCopyAsync 是 FreeSql.Provider.SqlServer 特有的功能"); @@ -161,7 +162,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions bulkCopy.DestinationTableName = dt.TableName; for (int i = 0; i < dt.Columns.Count; i++) bulkCopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); - return bulkCopy.WriteToServerAsync(dt); + return bulkCopy.WriteToServerAsync(dt, cancellationToken); }; try @@ -194,7 +195,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions if (conn.State != System.Data.ConnectionState.Open) { isNotOpen = true; - await conn.OpenAsync(); + await conn.OpenAsync(cancellationToken); } try { From f25e56be586dae3c78b7127953091f396fc00101 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 19:34:34 +0800 Subject: [PATCH 0998/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20SqlExt.FindI?= =?UTF-8?q?nSet=20find=5Fin=5Fset=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E8=A7=A3=E6=9E=90=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSqlGlobalExpressionCallExtensions.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index 2524d1af..69ac375f 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -167,6 +167,18 @@ namespace FreeSql /// /// public static IGroupConcat GroupConcat(object column) => SqlExtExtensions.GroupConcat(column); + /// + /// MySql find_in_set(str, strlist) + /// + /// + /// + /// + /// + public static int FindInSet(TValue str, string strlist) + { + expContext.Value.Result = $"find_in_set({expContext.Value.ParsedContent["str"]}, {expContext.Value.ParsedContent["strlist"]})"; + return 0; + } /// /// PostgreSQL string_agg(.., ..) From f93261d8e2c54680582a3dc2a7f7dd9c2a36160d Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 22:03:17 +0800 Subject: [PATCH 0999/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20ISelect=20Ca?= =?UTF-8?q?ncel=20=E7=94=A8=E4=BA=8E=E5=8F=96=E6=B6=88=E6=9C=AC=E6=AC=A1?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20IncludeI?= =?UTF-8?q?f/IncludeByPropertyNameIf=20=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ---- FreeSql/FreeSql.xml | 37 +++++++++++++++ FreeSql/Interface/Curd/ISelect/ISelect0.cs | 11 +++++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 15 ++++++ .../SelectProvider/Select0Provider.cs | 9 ++++ .../SelectProvider/Select0ProviderReader.cs | 46 +++++++++++++------ .../SelectProvider/Select1Provider.cs | 2 + .../SelectProvider/SelectGroupingProvider.cs | 4 +- 8 files changed, 108 insertions(+), 25 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b54d4d0e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -509,14 +509,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 751d06c0..b25afc15 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1160,6 +1160,15 @@ + + + MySql find_in_set(str, strlist) + + + + + + PostgreSQL string_agg(.., ..) @@ -1639,6 +1648,17 @@ 使用属性名作为字段别名 + + + 控制取消本次查询 + * 不会产生额外的异常 + * 取消成功,则不执行 SQL 命令 + * 取消成功,直接返回没有记录时候的返回值 + * 取消成功,如 List<T> 返回 0 元素列表,不是 null,仍然是旧机制 + + 返回 true,则不会执行 SQL 命令 + + 指定事务对象 @@ -2331,6 +2351,15 @@ 选择一个导航属性 + + + 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 + + + true 时生效 + 选择一个导航属性 + + 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 @@ -2352,6 +2381,14 @@ + + + 按属性名字符串进行 Include/IncludeMany 操作 + + true 时生效 + + + 实现 select .. from ( select ... from t ) a 这样的功能 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 11a54853..3f0119fc 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -30,6 +30,17 @@ namespace FreeSql Task CountAsync(CancellationToken cancellationToken = default); #endif + /// + /// 控制取消本次查询 + /// * 不会产生额外的异常 + /// * 取消成功,则不执行 SQL 命令 + /// * 取消成功,直接返回没有记录时候的返回值 + /// * 取消成功,如 List<T> 返回 0 元素列表,不是 null,仍然是旧机制 + /// + /// 返回 true,则不会执行 SQL 命令 + /// + TSelect Cancel(Func cancel); + /// /// 指定事务对象 /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 74372279..4bff2524 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -321,6 +321,14 @@ namespace FreeSql /// ISelect Include(Expression> navigateSelector) where TNavigate : class; /// + /// 贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作 + /// + /// + /// true 时生效 + /// 选择一个导航属性 + /// + ISelect IncludeIf(bool condition, Expression> navigateSelector) where TNavigate : class; + /// /// 贪婪加载集合的导航属性,其实是分两次查询,ToList 后进行了数据重装 /// 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany /// @@ -340,6 +348,13 @@ namespace FreeSql /// /// ISelect IncludeByPropertyName(string property); + /// + /// 按属性名字符串进行 Include/IncludeMany 操作 + /// + /// true 时生效 + /// + /// + ISelect IncludeByPropertyNameIf(bool condition, string property); /// /// 实现 select .. from ( select ... from t ) a 这样的功能 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index ea4c9606..0e69ee7f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -42,6 +42,7 @@ namespace FreeSql.Internal.CommonProvider public bool _distinct; public Expression _selectExpression; public List _whereGlobalFilter; + public Func _cancel; int _disposeCounter; ~Select0Provider() @@ -61,6 +62,7 @@ namespace FreeSql.Internal.CommonProvider _includeInfo.Clear(); _selectExpression = null; _whereGlobalFilter?.Clear(); + _cancel = null; } public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection lambParms) @@ -119,6 +121,7 @@ namespace FreeSql.Internal.CommonProvider to._distinct = from._distinct; to._selectExpression = from._selectExpression; to._whereGlobalFilter = new List(from._whereGlobalFilter.ToArray()); + to._cancel = from._cancel; } public Expression ConvertStringPropertyToExpression(string property, bool fromFirstTable = false) @@ -183,6 +186,12 @@ namespace FreeSql.Internal.CommonProvider return this as TSelect; } + public TSelect Cancel(Func cancel) + { + _cancel = cancel; + return this as TSelect; + } + public TSelect WithTransaction(DbTransaction transaction) { _transaction = transaction; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 91c3f7c8..d4bf7c3d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -21,11 +21,12 @@ namespace FreeSql.Internal.CommonProvider { public DataTable ToDataTable(string field = null) { + DataTable ret = null; + if (_cancel?.Invoke() == true) return ret; var sql = this.ToSql(field); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - DataTable ret = null; Exception exception = null; try { @@ -46,12 +47,13 @@ namespace FreeSql.Internal.CommonProvider public List ToList(string field) { + var ret = new List(); + if (_cancel?.Invoke() == true) return ret; var sql = this.ToSql(field); var type = typeof(TTuple); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); Exception exception = null; try { @@ -81,10 +83,11 @@ namespace FreeSql.Internal.CommonProvider } internal List ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { + var ret = new List(); + if (_cancel?.Invoke() == true) return ret; var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); var retCount = 0; Exception exception = null; try @@ -133,6 +136,7 @@ namespace FreeSql.Internal.CommonProvider #region ToChunk internal void ToListAfChunkPrivate(int chunkSize, Action>> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData) { + if (_cancel?.Invoke() == true) return; var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -208,6 +212,7 @@ namespace FreeSql.Internal.CommonProvider internal void ToListMrChunkPrivate(int chunkSize, Action>> chunkDone, string sql, ReadAnonymousTypeAfInfo af) { + if (_cancel?.Invoke() == true) return; var type = typeof(TReturn); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); @@ -266,12 +271,14 @@ namespace FreeSql.Internal.CommonProvider { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); + + var ret = new Dictionary(); + if (_cancel?.Invoke() == true) return ret; var af = this.GetAllFieldExpressionTreeLevel2(); var sql = this.ToSql(af.Field); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new Dictionary(); Exception exception = null; try { @@ -297,11 +304,12 @@ namespace FreeSql.Internal.CommonProvider internal List ToListMrPrivate(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) { + var ret = new List(); + if (_cancel?.Invoke() == true) return ret; var type = typeof(TReturn); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); var retCount = 0; Exception exception = null; try @@ -715,12 +723,13 @@ namespace FreeSql.Internal.CommonProvider } public int InternalInsertInto(string tableName, Expression select) { + int ret = 0; + if (_cancel?.Invoke() == true) return ret; var sql = this.InternalGetInsertIntoToSql(tableName, select); var dbParms = _params.ToArray(); var tb = _orm.CodeFirst.GetTableByEntity(typeof(TTargetEntity)); var before = new Aop.CurdBeforeEventArgs(tb.Type, tb, Aop.CurdType.Insert, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - int ret = 0; Exception exception = null; try { @@ -741,11 +750,12 @@ namespace FreeSql.Internal.CommonProvider protected DataTable InternalToDataTable(Expression select) { + DataTable ret = null; + if (_cancel?.Invoke() == true) return ret; var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - DataTable ret = null; Exception exception = null; try { @@ -790,11 +800,12 @@ namespace FreeSql.Internal.CommonProvider #else async public Task ToDataTableAsync(string field, CancellationToken cancellationToken) { + DataTable ret = null; + if (_cancel?.Invoke() == true) return ret; var sql = this.ToSql(field); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - DataTable ret = null; Exception exception = null; try { @@ -815,12 +826,13 @@ namespace FreeSql.Internal.CommonProvider async public Task> ToListAsync(string field, CancellationToken cancellationToken) { + var ret = new List(); + if (_cancel?.Invoke() == true) return ret; var sql = this.ToSql(field); var type = typeof(TTuple); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); Exception exception = null; try { @@ -852,10 +864,11 @@ namespace FreeSql.Internal.CommonProvider async internal Task> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) { + var ret = new List(); + if (_cancel?.Invoke() == true) return ret; var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); var retCount = 0; Exception exception = null; try @@ -909,12 +922,14 @@ namespace FreeSql.Internal.CommonProvider { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector)); + + var ret = new Dictionary(); + if (_cancel?.Invoke() == true) return ret; var af = this.GetAllFieldExpressionTreeLevel2(); var sql = this.ToSql(af.Field); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new Dictionary(); Exception exception = null; try { @@ -941,11 +956,12 @@ namespace FreeSql.Internal.CommonProvider async internal Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) { + var ret = new List(); + if (_cancel?.Invoke() == true) return ret; var type = typeof(TReturn); var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var ret = new List(); var retCount = 0; Exception exception = null; try @@ -1006,12 +1022,13 @@ namespace FreeSql.Internal.CommonProvider async public Task InternalInsertIntoAsync(string tableName, Expression select, CancellationToken cancellationToken) { + int ret = 0; + if (_cancel?.Invoke() == true) return ret; var sql = this.InternalGetInsertIntoToSql(tableName, select); var dbParms = _params.ToArray(); var tb = _orm.CodeFirst.GetTableByEntity(typeof(TTargetEntity)); var before = new Aop.CurdBeforeEventArgs(tb.Type, tb, Aop.CurdType.Insert, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - int ret = 0; Exception exception = null; try { @@ -1032,11 +1049,12 @@ namespace FreeSql.Internal.CommonProvider async protected Task InternalToDataTableAsync(Expression select, CancellationToken cancellationToken) { + DataTable ret = null; + if (_cancel?.Invoke() == true) return ret; var sql = this.InternalToSql(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty var dbParms = _params.ToArray(); var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - DataTable ret = null; Exception exception = null; try { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index c336fcf0..03360ada 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -393,6 +393,7 @@ namespace FreeSql.Internal.CommonProvider public int InsertInto(string tableName, Expression> select) where TTargetEntity : class => base.InternalInsertInto(tableName, select); + public ISelect IncludeByPropertyNameIf(bool condition, string property) => condition ? IncludeByPropertyName(property) : this; public ISelect IncludeByPropertyName(string property) { var exp = ConvertStringPropertyToExpression(property, true); @@ -424,6 +425,7 @@ namespace FreeSql.Internal.CommonProvider } bool _isIncluded = false; + public ISelect IncludeIf(bool condition, Expression> navigateSelector) where TNavigate : class => condition ? Include(navigateSelector) : this; public ISelect Include(Expression> navigateSelector) where TNavigate : class { var expBody = navigateSelector?.Body; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 44c1b28d..a25b713d 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -171,7 +171,7 @@ namespace FreeSql.Internal.CommonProvider return this; } - public long Count() => long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_select._connection, _select._transaction, CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._commandTimeout, _select._params.ToArray())), out var trylng) ? trylng : default(long); + public long Count() => _select._cancel?.Invoke() == true ? 0 : long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_select._connection, _select._transaction, CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._commandTimeout, _select._params.ToArray())), out var trylng) ? trylng : default(long); public ISelectGrouping Count(out long count) { count = this.Count(); @@ -200,7 +200,7 @@ namespace FreeSql.Internal.CommonProvider #if net40 #else - async public Task CountAsync(CancellationToken cancellationToken = default) => long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_select._connection, _select._transaction, CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._commandTimeout, _select._params.ToArray(), cancellationToken)), out var trylng) ? trylng : default(long); + async public Task CountAsync(CancellationToken cancellationToken = default) => _select._cancel?.Invoke() == true ? 0 : long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_select._connection, _select._transaction, CommandType.Text, $"select count(1) from ({this.ToSql($"1{_comonExp._common.FieldAsAlias("as1")}")}) fta", _select._commandTimeout, _select._params.ToArray(), cancellationToken)), out var trylng) ? trylng : default(long); public Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default) { From d3f95e11774529cf10b62ebfc71e175cd0fc577c Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 12 Nov 2020 22:07:00 +0800 Subject: [PATCH 1000/1029] v2.0.0-preview1113 #537 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 7 ------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 22 insertions(+), 29 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index cd70c641..cbcb470d 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index c3e53b66..18b9d1b5 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 14be0c61..b775f41b 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index d0488ca6..c14edfff 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index ba322436..9ff75647 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1112 + 2.0.0-preview1113 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index afd6f56c..5f97f587 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index a15331b6..30f2a63e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b54d4d0e..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 7a49741b..bc0de9f3 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 172f1b10..0367f610 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index e5f44ac8..37410d9c 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index eb1b1f2f..c0f729e9 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 7cf7f2b2..23a55a5a 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index d7bf96db..047e301e 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index d186d1b4..558508d2 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0c1302c2..723195c0 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 04363b6a..3630a923 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 46d8f965..7b919468 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e7dac034..e3662441 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index fcb73c5b..0a4e899f 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 89a3c444..9fea8e86 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index dda58e2e..fd1a9c14 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5f3cf863..39749228 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1112 + 2.0.0-preview1113 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 14ba84c24b4a4a87ed6e8d9c1a26c668ed896a88 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 13 Nov 2020 10:21:09 +0800 Subject: [PATCH 1001/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E6=A0=91=E4=B8=89=E5=85=83=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E8=A7=A3=E6=9E=90=EF=BC=8C=E5=BD=93=20Test=20?= =?UTF-8?q?=E4=B8=BA=E5=8F=98=E9=87=8F=E6=97=B6=E4=B8=8D=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E6=88=90=20case=20when=20end=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 95 +++++++++++++++++++++++- FreeSql/Internal/CommonExpression.cs | 32 ++++++-- 2 files changed, 121 insertions(+), 6 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index 09bce801..a6ff160e 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -1,4 +1,5 @@ -using System; +using FreeSql.DataAnnotations; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; @@ -11,6 +12,98 @@ namespace FreeSql.Tests public class UnitTest4 { + public record ts_iif(Guid id, string title); + [Fact] + public void IIF() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var id = Guid.NewGuid(); + fsql.Insert(new ts_iif(id, "001")).ExecuteAffrows(); + + var item = fsql.Select().Where(a => a.id == (id != Guid.NewGuid() ? id : a.id)).First(); + Assert.Equal(id, item.id); + + var item2 = fsql.Select().First(a => new + { + xxx = id != Guid.NewGuid() ? a.id : Guid.Empty + }); + Assert.Equal(id, item2.xxx); + + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Delete().Where("1=1").ExecuteAffrows(); + var typeid = Guid.NewGuid(); + fsql.Insert(new ts_iif_type { id = typeid, name = "type001" }).ExecuteAffrows(); + fsql.Insert(new ts_iif_topic { id = id, typeid = typeid, title = "title001" }).ExecuteAffrows(); + + var more1 = true; + var more2 = (bool?)true; + var more3 = (bool?)false; + var more4 = (bool?)null; + var moreitem = fsql.Select().First(a => new + { + a.id, + a.title, + a.type + }); + Assert.Equal(id, moreitem.id); + Assert.Equal("title001", moreitem.title); + Assert.Equal(typeid, moreitem.type.id); + Assert.Equal("type001", moreitem.type.name); + var moreitem1 = fsql.Select().First(a => new + { + a.id, + a.title, + type1 = more1 == true ? a.type : null, + }); + Assert.Equal(id, moreitem1.id); + Assert.Equal("title001", moreitem1.title); + Assert.Equal(typeid, moreitem1.type1.id); + Assert.Equal("type001", moreitem1.type1.name); + var moreitem2 = fsql.Select().First(a => new + { + a.id, + a.title, + type2 = more2 == true ? a.type : null, + }); + Assert.Equal(id, moreitem2.id); + Assert.Equal("title001", moreitem2.title); + Assert.Equal(typeid, moreitem2.type2.id); + Assert.Equal("type001", moreitem2.type2.name); + var moreitem3 = fsql.Select().First(a => new + { + a.id, + a.title, + type3 = more3 == true ? a.type : null, + }); + Assert.Equal(id, moreitem3.id); + Assert.Equal("title001", moreitem3.title); + Assert.Null(moreitem3.type3); + var moreitem4 = fsql.Select().First(a => new + { + a.id, + a.title, + type4 = more4 == true ? a.type : null, + }); + Assert.Equal(id, moreitem4.id); + Assert.Equal("title001", moreitem4.title); + Assert.Null(moreitem4.type4); + } + class ts_iif_topic + { + public Guid id { get; set; } + public Guid typeid { get; set; } + [Navigate(nameof(typeid))] + public ts_iif_type type { get; set; } + public string title { get; set; } + } + class ts_iif_type + { + public Guid id { get; set; } + public string name { get; set; } + } + + public record ts_record(DateTime Date, int TemperatureC, int TemperatureF, string Summary) { public ts_record parent { get; set; } diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b173c125..3e7ea011 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -70,6 +70,11 @@ namespace FreeSql.Internal else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; + case ExpressionType.Conditional: + var condExp = exp as ConditionalExpression; + if (condExp.Test.IsParameter() == false) return ReadAnonymousField(_tables, field, parent, ref index, + (bool)Expression.Lambda(condExp.Test).Compile().DynamicInvoke() ? condExp.IfTrue : condExp.IfFalse, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap); + break; case ExpressionType.Call: var callExp = exp as MethodCallExpression; //处理自定义SQL语句,如: ToList(new { @@ -703,11 +708,28 @@ namespace FreeSql.Internal case ExpressionType.Conditional: var condExp = exp as ConditionalExpression; var conditionalTestOldMapType = tsc.SetMapTypeReturnOld(null); - var conditionalTestSql = ExpressionLambdaToSql(condExp.Test, tsc); - tsc.SetMapTypeReturnOld(conditionalTestOldMapType); - var conditionalSql = _common.IIF(conditionalTestSql, ExpressionLambdaToSql(condExp.IfTrue, tsc), ExpressionLambdaToSql(condExp.IfFalse, tsc)); - tsc.SetMapTypeReturnOld(null); - return conditionalSql; + if (condExp.Test.IsParameter()) + { + var conditionalTestSql = ExpressionLambdaToSql(condExp.Test, tsc); + tsc.SetMapTypeReturnOld(conditionalTestOldMapType); + var conditionalSql = _common.IIF(conditionalTestSql, ExpressionLambdaToSql(condExp.IfTrue, tsc), ExpressionLambdaToSql(condExp.IfFalse, tsc)); + tsc.SetMapTypeReturnOld(null); + return conditionalSql; + } + if ((bool)Expression.Lambda(condExp.Test).Compile().DynamicInvoke()) + { + tsc.SetMapTypeReturnOld(conditionalTestOldMapType); + var conditionalSql = ExpressionLambdaToSql(condExp.IfTrue, tsc); + tsc.SetMapTypeReturnOld(null); + return conditionalSql; + } + else + { + tsc.SetMapTypeReturnOld(conditionalTestOldMapType); + var conditionalSql = ExpressionLambdaToSql(condExp.IfFalse, tsc); + tsc.SetMapTypeReturnOld(null); + return conditionalSql; + } case ExpressionType.Call: tsc.mapType = null; var exp3 = exp as MethodCallExpression; From cf60f26759c3271887eaa48805e0cac77452d28b Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 13 Nov 2020 10:24:40 +0800 Subject: [PATCH 1002/1029] 2.0.0-preview1115 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ++++++++++++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 38 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index cbcb470d..c4537ea0 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 18b9d1b5..c0fd2995 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b775f41b..aafefb37 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index c14edfff..bff31e6a 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 9ff75647..987d74f5 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1113 + 2.0.0-preview1115 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 5f97f587..6e5da60a 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 30f2a63e..2c7a9546 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,6 +130,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -502,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index bc0de9f3..bc578f32 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 0367f610..77dbb2f3 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 37410d9c..7eced38b 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index c0f729e9..d6f84c29 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 23a55a5a..f955043c 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 047e301e..7e6987c8 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 558508d2..bbd40ed0 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 723195c0..d9668dc8 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 3630a923..7340311d 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 7b919468..4f95f860 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index e3662441..ba3b8169 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 0a4e899f..33566c79 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9fea8e86..b0823c0a 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index fd1a9c14..a825c6ec 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 39749228..64eb1c89 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1113 + 2.0.0-preview1115 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From bbc4f91d9b02868987588abc8a858b9523b52c47 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 13 Nov 2020 19:32:50 +0800 Subject: [PATCH 1003/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20AsTreeCte=20?= =?UTF-8?q?=E5=AF=B9=20MySql=205.6=20=E7=9A=84=E5=85=BC=E5=AE=B9=EF=BC=9B#?= =?UTF-8?q?536?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --- .../MySql/Curd/MySqlSelectTest.cs | 72 ++++++++++--------- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 2 +- FreeSql.Tests/FreeSql.Tests/g.cs | 2 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 68 +++++++++++++++++- FreeSql/FreeSql.xml | 3 +- 6 files changed, 110 insertions(+), 46 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b54d4d0e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -509,14 +509,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 2d0bacb3..3f9792de 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -1989,43 +1989,49 @@ WHERE ((b.`IsFinished` OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql1 Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); - //Assert.Single(t3); - //Assert.Equal("100000", t3[0].Code); - //Assert.Single(t3[0].Childs); - //Assert.Equal("110000", t3[0].Childs[0].Code); - //Assert.Equal(2, t3[0].Childs[0].Childs.Count); - //Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); - //Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); - //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); - //Assert.Equal(4, t3.Count); - //Assert.Equal("100000", t3[0].Code); - //Assert.Equal("110000", t3[1].Code); - //Assert.Equal("110100", t3[2].Code); - //Assert.Equal("110101", t3[3].Code); + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); - //t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); - //Assert.Equal(3, t3.Count); - //Assert.Equal("110000", t3[0].Code); - //Assert.Equal("110100", t3[1].Code); - //Assert.Equal("110101", t3[2].Code); + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); - //var select = fsql.Select() - // .Where(a => a.Name == "中国") - // .AsTreeCte() - // //.OrderBy("a.cte_level desc") //递归层级 - // ; - //// var list = select.ToList(); //自己调试看查到的数据 - //select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); - //Assert.Equal(855, fsql.Select() - // .Where(a => a.Name == "中国") - // .AsTreeCte().Distinct().First(a => a.testint)); + var t4 = fsql.Select().Where(a => a.Name == "东城区").AsTreeCte(up: true).ToList(); + Assert.Equal(3, t4.Count); + Assert.Equal("110101", t4[0].Code); + Assert.Equal("110000", t4[1].Code); + Assert.Equal("100000", t4[2].Code); - //Assert.Equal(4, select.ToDelete().ExecuteAffrows()); - //Assert.False(fsql.Select() - // .Where(a => a.Name == "中国") - // .AsTreeCte().Any()); + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); } [Table(Name = "D_District")] diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index a6ff160e..84a3effb 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -30,7 +30,7 @@ namespace FreeSql.Tests }); Assert.Equal(id, item2.xxx); - fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Delete().Where("1=1").ExecuteAffrows(); var typeid = Guid.NewGuid(); fsql.Insert(new ts_iif_type { id = typeid, name = "type001" }).ExecuteAffrows(); diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 43f83258..a4f0f11d 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -9,7 +9,7 @@ public class g { static Lazy mysqlLazy = new Lazy(() => new FreeSql.FreeSqlBuilder() - .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=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=5;Allow User Variables=True") //.UseConnectionFactory(FreeSql.DataType.MySql, () => new MySql.Data.MySqlClient.MySqlConnection("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;")) //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=192.168.164.10;Port=33061;User ID=root;Password=root;Initial Catalog=cccddd_mysqlconnector;Charset=utf8;SslMode=none;Max pool size=10") .UseAutoSyncStructure(true) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 67dbad00..531a8f8b 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -1,6 +1,7 @@ using FreeSql; using FreeSql.DataAnnotations; using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Concurrent; @@ -378,10 +379,12 @@ public static partial class FreeSqlGlobalExtensions #endregion #region AsTreeCte(..) 递归查询 + static ConcurrentDictionary _dicMySqlVersion = new ConcurrentDictionary(); /// /// 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 /// 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓、翰高 - /// 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) + /// 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) + /// * v2.0.0 兼容 MySql5.6 向上或向下查询,但不支持 pathSelector/pathSeparator 详细:https://github.com/dotnetcore/FreeSql/issues/536 /// /// /// @@ -409,6 +412,69 @@ public static partial class FreeSqlGlobalExtensions var cteName = "as_tree_cte"; if (select._orm.CodeFirst.IsSyncStructureToLower) cteName = cteName.ToLower(); if (select._orm.CodeFirst.IsSyncStructureToUpper) cteName = cteName.ToUpper(); + + switch (select._orm.Ado.DataType) //MySql5.6 + { + case DataType.MySql: + case DataType.OdbcMySql: + var mysqlConnectionString = select._orm.Ado?.ConnectionString ?? select._connection?.ConnectionString ?? ""; + if (_dicMySqlVersion.TryGetValue(mysqlConnectionString, out var mysqlVersion) == false) + { + if (select._orm.Ado?.ConnectionString != null) + { + using (var mysqlconn = select._orm.Ado.MasterPool.Get()) + mysqlVersion = mysqlconn.Value.ServerVersion; + } + else if (select._connection != null) + { + var isclosed = select._connection.State != ConnectionState.Open; + if (isclosed) select._connection.Open(); + mysqlVersion = select._connection.ServerVersion; + if (isclosed) select._connection.Close(); + } + } + if (int.TryParse((mysqlVersion ?? "").Split('.')[0], out var mysqlVersionFirst) && mysqlVersionFirst < 8) + { + if (tbref.Columns.Count > 1) throw new ArgumentException($"{tb.Type.FullName} 是父子关系,但是 MySql 8.0 以下版本中不支持组合多主键"); + var mysql56Sql = ""; + if (up == false) + { + mysql56Sql = $@"SELECT cte_tbc.cte_level, {select.GetAllFieldExpressionTreeLevel2().Field} + FROM ( + SELECT @cte_ids as cte_ids, ( + SELECT @cte_ids := group_concat({select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)}) + FROM {select._commonUtils.QuoteSqlName(tb.DbName)} + WHERE find_in_set({select._commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)}, @cte_ids) + ) as cte_cids, @cte_level := @cte_idcte_levels + 1 as cte_level + FROM {select._commonUtils.QuoteSqlName(tb.DbName)}, ( + SELECT @cte_ids := a.{select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)}, @cte_idcte_levels := 0 + FROM {select._commonUtils.QuoteSqlName(tb.DbName)} a + WHERE 1=1{select._where} + LIMIT 1) cte_tbb + WHERE @cte_ids IS NOT NULL + ) cte_tbc, {select._commonUtils.QuoteSqlName(tb.DbName)} a + WHERE find_in_set(a.{select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)}, cte_tbc.cte_ids)"; + select.WithSql(mysql56Sql).OrderBy("a.cte_level DESC"); + select._where.Clear(); + return select; + } + mysql56Sql = $@"SELECT cte_tbc.cte_level, {select.GetAllFieldExpressionTreeLevel2().Field} +FROM ( + SELECT @cte_pid as cte_id, (SELECT @cte_pid := {select._commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)} FROM {select._commonUtils.QuoteSqlName(tb.DbName)} WHERE {select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)} = cte_id) as cte_pid, @cte_level := @cte_level + 1 as cte_level + FROM {select._commonUtils.QuoteSqlName(tb.DbName)}, ( + SELECT @cte_pid := a.{select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)}, @cte_level := 0 + FROM {select._commonUtils.QuoteSqlName(tb.DbName)} a + WHERE 1=1{select._where} + LIMIT 1) cte_tbb +) cte_tbc +JOIN {select._commonUtils.QuoteSqlName(tb.DbName)} a ON cte_tbc.cte_id = a.{select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)}"; + select.WithSql(mysql56Sql).OrderBy("a.cte_level"); + select._where.Clear(); + return select; + } + break; + } + var sql1ctePath = ""; if (pathSelector != null) { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index b25afc15..3632c4f9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -4369,7 +4369,8 @@ 使用递归 CTE 查询树型的所有子记录,或者所有父记录。 通过测试的数据库:MySql8.0、SqlServer、PostgreSQL、Oracle、Sqlite、Firebird、达梦、人大金仓、翰高 - 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) + 返回隐藏字段:.ToList(a => new { item = a, level = "a.cte_level", path = "a.cte_path" }) + * v2.0.0 兼容 MySql5.6 向上或向下查询,但不支持 pathSelector/pathSeparator 详细:https://github.com/dotnetcore/FreeSql/issues/536 From c2f1b73755e9731aee1e4deacff294d141a59666 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 17 Nov 2020 18:54:39 +0800 Subject: [PATCH 1004/1029] Optimize internal code --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 +++++++++ .../FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs | 2 ++ .../SelectProvider/Select0ProviderReader.cs | 11 +++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b54d4d0e..2d6d3409 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -509,5 +509,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs index 86e4eadb..cf174b9f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengSelectTest.cs @@ -336,6 +336,7 @@ namespace FreeSql.Tests.Dameng var sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); query.ToList(); + query.ToList(true); query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); @@ -475,6 +476,7 @@ namespace FreeSql.Tests.Dameng var sql = query.ToSql().Replace("\r\n", ""); Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); query.ToList(); + query.ToList(true); query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index d4bf7c3d..ca961a7f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -475,10 +475,13 @@ namespace FreeSql.Internal.CommonProvider Expression.GreaterThan(readExpDataIndex, dataIndexExp), Expression.Assign(dataIndexExp, readExpDataIndex) ), - Expression.IfThenElse( - Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Assign(curExp, Expression.Convert(readExpValue, typei)), - Expression.Assign(curExp, Expression.Constant(null, typei)) + Expression.IfThen( + Expression.NotEqual(retExp, Expression.Constant(null)), + Expression.IfThenElse( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Assign(curExp, Expression.Convert(readExpValue, typei)), + Expression.Assign(curExp, Expression.Constant(null, typei)) + ) ) }), Expression.Block( From c04a32659d7cf88bd245989871f36a19b5bfa59e Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 17 Nov 2020 19:06:42 +0800 Subject: [PATCH 1005/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20=E6=9C=AA?= =?UTF-8?q?=E5=A4=84=E7=90=86=20Oracle=20DbFirst=20=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E5=88=97=EF=BC=9B#542?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs | 2 +- Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs | 2 +- Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs | 2 +- Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 47eb5034..77f7d095 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -197,7 +197,7 @@ nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsNa b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); +where a.owner={{0}} and a.table_name={{1}} and a.column_id is not null", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs index e07f4437..3d75a870 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleDbFirst.cs @@ -331,7 +331,7 @@ to_char(b.comments), nvl(FREESQL_LONG_TO_CHAR_DEFAULT(a.table_name, a.column_name),'') from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} and a.column_id is not null "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index e6a22742..e125eb65 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -198,7 +198,7 @@ nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsNa b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); +where a.owner={{0}} and a.table_name={{1}} and a.column_id is not null", tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => { diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index fc249b8d..a5036b80 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -331,7 +331,7 @@ to_char(b.comments), nvl(FREESQL_LONG_TO_CHAR_DEFAULT(a.table_name, a.column_name),'') from all_tab_cols a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name -where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} and a.column_id is not null "; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; From 2947572f054a54c81bd3d439313a8f7af8a6fe5d Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 17 Nov 2020 19:44:47 +0800 Subject: [PATCH 1006/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.DbCo?= =?UTF-8?q?ntext/Repository=20Async=20CancellationToken=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=EF=BC=9B#537?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/DbContext/DbContextAsync.cs | 22 ++-- FreeSql.DbContext/DbSet/DbSetAsync.cs | 120 +++++++++--------- FreeSql.DbContext/DbSet/DbSetSync.cs | 16 +-- FreeSql.DbContext/FreeSql.DbContext.xml | 16 --- .../ContextSet/RepositoryDbContext.cs | 5 +- .../Repository/Repository/BaseRepository.cs | 4 +- .../Repository/BaseRepositoryAsync.cs | 51 ++++---- .../Repository/Repository/IBaseRepository.cs | 25 ++-- 8 files changed, 122 insertions(+), 137 deletions(-) diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 9195cd1b..1915e5f0 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Threading; using System.Threading.Tasks; #if net40 @@ -12,14 +13,14 @@ namespace FreeSql { partial class DbContext { - async public virtual Task SaveChangesAsync() + async public virtual Task SaveChangesAsync(CancellationToken cancellationToken = default) { - await FlushCommandAsync(); + await FlushCommandAsync(cancellationToken); return SaveChangesSuccess(); } - static ConcurrentDictionary>>> _dicFlushCommandDbSetBatchAsync = new ConcurrentDictionary>>>(); - async internal Task FlushCommandAsync() + static ConcurrentDictionary>>> _dicFlushCommandDbSetBatchAsync = new ConcurrentDictionary>>>(); + async internal Task FlushCommandAsync(CancellationToken cancellationToken) { if (isFlushCommanding) return; if (_prevCommands.Any() == false) return; @@ -31,25 +32,26 @@ namespace FreeSql Task dbsetBatch(string method) { var tryfunc = _dicFlushCommandDbSetBatchAsync - .GetOrAdd(oldinfo.stateType, stateType => new ConcurrentDictionary>>()) + .GetOrAdd(oldinfo.stateType, stateType => new ConcurrentDictionary>>()) .GetOrAdd(method, methodName => { var arrType = oldinfo.stateType.MakeArrayType(); var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType, typeof(CancellationToken) }, null); var returnTarget = Expression.Label(typeof(Task)); var parm1DbSet = Expression.Parameter(typeof(object)); var parm2Vals = Expression.Parameter(typeof(object[])); + var parm3CancelToken = Expression.Parameter(typeof(CancellationToken)); var var1Vals = Expression.Variable(arrType); - return Expression.Lambda>>(Expression.Block( + return Expression.Lambda>>(Expression.Block( new[] { var1Vals }, Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals, parm3CancelToken)), Expression.Label(returnTarget, Expression.Default(typeof(Task))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); + ), new[] { parm1DbSet, parm2Vals, parm3CancelToken }).Compile(); }); - return tryfunc(oldinfo.dbSet, states.ToArray()); + return tryfunc(oldinfo.dbSet, states.ToArray(), cancellationToken); } async Task funcDelete() { diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 8844e7f1..3e68273f 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Threading; using System.Threading.Tasks; #if net40 @@ -14,22 +15,22 @@ namespace FreeSql { partial class DbSet { - Task DbContextFlushCommandAsync() + Task DbContextFlushCommandAsync(CancellationToken cancellationToken) { _dicUpdateTimes.Clear(); - return _db.FlushCommandAsync(); + return _db.FlushCommandAsync(cancellationToken); } - async Task DbContextBatchAddAsync(EntityState[] adds) + async Task DbContextBatchAddAsync(EntityState[] adds, CancellationToken cancellationToken) { if (adds.Any() == false) return 0; - var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(); + var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(cancellationToken); _db._entityChangeReport.AddRange(adds.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Insert })); return affrows; } #region Add - async Task AddPrivAsync(TEntity data, bool isCheck) + async Task AddPrivAsync(TEntity data, bool isCheck, CancellationToken cancellationToken) { if (isCheck && CanAdd(data, true) == false) return; if (_tableIdentitys.Length > 0) @@ -47,38 +48,38 @@ namespace FreeSql case DataType.Firebird: //firebird 只支持单条插入 returning if (_tableIdentitys.Length == 1) { - await DbContextFlushCommandAsync(); - var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); + await DbContextFlushCommandAsync(cancellationToken); + var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(cancellationToken); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data, true); + await AddOrUpdateNavigateListAsync(data, true, null, cancellationToken); } else { - await DbContextFlushCommandAsync(); - var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); + await DbContextFlushCommandAsync(cancellationToken); + var newval = (await this.OrmInsert(data).ExecuteInsertedAsync(cancellationToken)).First(); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); _db.OrmOriginal.MapEntityValue(_entityType, newval, data); Attach(newval); if (_db.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data, true); + await AddOrUpdateNavigateListAsync(data, true, null, cancellationToken); } return; default: if (_tableIdentitys.Length == 1) { - await DbContextFlushCommandAsync(); - var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); + await DbContextFlushCommandAsync(cancellationToken); + var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(cancellationToken); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data, true); + await AddOrUpdateNavigateListAsync(data, true, null, cancellationToken); } return; } @@ -86,15 +87,15 @@ namespace FreeSql EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(data)); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - await AddOrUpdateNavigateListAsync(data, true); + await AddOrUpdateNavigateListAsync(data, true, null, cancellationToken); } - public Task AddAsync(TEntity data) => AddPrivAsync(data, true); - async public Task AddRangeAsync(IEnumerable data) + public Task AddAsync(TEntity data, CancellationToken cancellationToken = default) => AddPrivAsync(data, true, cancellationToken); + async public Task AddRangeAsync(IEnumerable data, CancellationToken cancellationToken = default) { if (CanAdd(data, true) == false) return; if (data.ElementAtOrDefault(1) == default(TEntity)) { - await AddAsync(data.First()); + await AddAsync(data.First(), cancellationToken); return; } if (_tableIdentitys.Length > 0) @@ -109,8 +110,8 @@ namespace FreeSql case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: - await DbContextFlushCommandAsync(); - var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); + await DbContextFlushCommandAsync(cancellationToken); + var rets = await this.OrmInsert(data).ExecuteInsertedAsync(cancellationToken); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); var idx = 0; @@ -120,11 +121,11 @@ namespace FreeSql AttachRange(rets); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - await AddOrUpdateNavigateListAsync(item, true); + await AddOrUpdateNavigateListAsync(item, true, null, cancellationToken); return; default: foreach (var s in data) - await AddPrivAsync(s, false); + await AddPrivAsync(s, false, cancellationToken); return; } } @@ -136,11 +137,11 @@ namespace FreeSql AttachRange(data); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - await AddOrUpdateNavigateListAsync(item, true); + await AddOrUpdateNavigateListAsync(item, true, null, cancellationToken); } } - async public Task SaveManyAsync(TEntity item, string propertyName) + async public Task SaveManyAsync(TEntity item, string propertyName, CancellationToken cancellationToken = default) { if (item == null) return; if (string.IsNullOrEmpty(propertyName)) return; @@ -156,15 +157,15 @@ namespace FreeSql throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 OneToMany 或 ManyToMany 特性"); } - await DbContextFlushCommandAsync(); + await DbContextFlushCommandAsync(cancellationToken); var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; _db.Options.EnableAddOrUpdateNavigateList = false; try { - await AddOrUpdateNavigateListAsync(item, false, propertyName); + await AddOrUpdateNavigateListAsync(item, false, propertyName, cancellationToken); if (tref.RefType == Internal.Model.TableRefType.OneToMany) { - await DbContextFlushCommandAsync(); + await DbContextFlushCommandAsync(cancellationToken); //删除没有保存的数据,求出主体的条件 var deleteWhereParentParam = Expression.Parameter(typeof(object), "a"); Expression whereParentExp = null; @@ -189,7 +190,7 @@ namespace FreeSql subDelete.WhereDynamic(propValEach, true); break; } - await subDelete.ExecuteAffrowsAsync(); + await subDelete.ExecuteAffrowsAsync(cancellationToken); } } finally @@ -197,7 +198,7 @@ namespace FreeSql _db.Options.EnableAddOrUpdateNavigateList = oldEnable; } } - async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd, string propertyName = null) + async Task AddOrUpdateNavigateListAsync(TEntity item, bool isAdd, string propertyName, CancellationToken cancellationToken) { Func action = async prop => { @@ -225,9 +226,9 @@ namespace FreeSql curList.Add(propValItem); var flagExists = refSet.ExistsInStates(propValItem); if (flagExists == false) - flagExists = await refSet.Select.WhereDynamic(propValItem).AnyAsync(); + flagExists = await refSet.Select.WhereDynamic(propValItem).AnyAsync(cancellationToken); if (refSet.CanAdd(propValItem, false) && flagExists != true) - await refSet.AddAsync(propValItem); + await refSet.AddAsync(propValItem, cancellationToken); } var midSelectParam = Expression.Parameter(typeof(object), "a"); var midWheres = new List>>(); @@ -246,7 +247,7 @@ namespace FreeSql .WithTransaction(_uow?.GetOrBeginTransaction()); foreach (var midWhere in midWheres) delall.Where(midWhere); var sql = delall.ToSql(); - await delall.ExecuteAffrowsAsync(); + await delall.ExecuteAffrowsAsync(cancellationToken); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); } else //保存 @@ -257,7 +258,7 @@ namespace FreeSql { var midSelect = midSet.Select; foreach (var midWhere in midWheres) midSelect.Where(midWhere); - midList = await midSelect.ToListAsync(); + midList = await midSelect.ToListAsync(false, cancellationToken); } else midList = new List(); @@ -307,7 +308,7 @@ namespace FreeSql } midListAdd.Add(newItem); } - await midSet.AddRangeAsync(midListAdd); + await midSet.AddRangeAsync(midListAdd, cancellationToken); } break; case Internal.Model.TableRefType.OneToMany: @@ -318,7 +319,7 @@ namespace FreeSql var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.RefColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)); _db.OrmOriginal.SetEntityValueWithPropertyName(tref.RefEntityType, propValItem, tref.RefColumns[colidx].CsName, val); } - await refSet.AddOrUpdateAsync(propValItem); + await refSet.AddOrUpdateAsync(propValItem, cancellationToken); } break; } @@ -333,9 +334,9 @@ namespace FreeSql #endregion #region UpdateAsync - Task DbContextBatchUpdateAsync(EntityState[] ups) => DbContextBatchUpdatePrivAsync(ups, false); - Task DbContextBatchUpdateNowAsync(EntityState[] ups) => DbContextBatchUpdatePrivAsync(ups, true); - async Task DbContextBatchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate) + Task DbContextBatchUpdateAsync(EntityState[] ups, CancellationToken cancellationToken) => DbContextBatchUpdatePrivAsync(ups, false, cancellationToken); + Task DbContextBatchUpdateNowAsync(EntityState[] ups, CancellationToken cancellationToken) => DbContextBatchUpdatePrivAsync(ups, true, cancellationToken); + async Task DbContextBatchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate, CancellationToken cancellationToken) { if (ups.Any() == false) return 0; var uplst1 = ups[ups.Length - 1]; @@ -370,7 +371,7 @@ namespace FreeSql return ups.Length == data.Count ? -998 : -997; var update = this.OrmUpdate(null).SetSource(data.Select(a => a.Value)).IgnoreColumns(cuig); - var affrows = await update.ExecuteAffrowsAsync(); + var affrows = await update.ExecuteAffrowsAsync(cancellationToken); _db._entityChangeReport.AddRange(data.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, BeforeObject = _states.TryGetValue(a.Key, out var beforeVal) ? CreateEntityState(beforeVal.Value).Value : null, @@ -390,20 +391,20 @@ namespace FreeSql //等待下次对比再保存 return 0; } - async public Task UpdateAsync(TEntity data) + async public Task UpdateAsync(TEntity data, CancellationToken cancellationToken = default) { var exists = ExistsInStates(data); if (exists == null) throw new Exception($"不可更新,未设置主键的值:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); if (exists == false) { - var olddata = await OrmSelect(data).FirstAsync(); + var olddata = await OrmSelect(data).FirstAsync(cancellationToken); if (olddata == null) throw new Exception($"不可更新,数据库不存在该记录:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); } - await UpdateRangePrivAsync(new[] { data }, true); + await UpdateRangePrivAsync(new[] { data }, true, cancellationToken); } - public Task UpdateRangeAsync(IEnumerable data) => UpdateRangePrivAsync(data, true); - async Task UpdateRangePrivAsync(IEnumerable data, bool isCheck) + public Task UpdateRangeAsync(IEnumerable data, CancellationToken cancellationToken = default) => UpdateRangePrivAsync(data, true, cancellationToken); + async Task UpdateRangePrivAsync(IEnumerable data, bool isCheck, CancellationToken cancellationToken) { if (CanUpdate(data, true) == false) return; foreach (var item in data) @@ -411,7 +412,7 @@ namespace FreeSql if (_dicUpdateTimes.ContainsKey(item)) { var itemCopy = CreateEntityState(item).Value; - await DbContextFlushCommandAsync(); + await DbContextFlushCommandAsync(cancellationToken); if (_table.VersionColumn != null) { var itemVersion = _db.OrmOriginal.GetEntityValueWithPropertyName(_entityType, item, _table.VersionColumn.CsName); @@ -429,32 +430,27 @@ namespace FreeSql } if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - await AddOrUpdateNavigateListAsync(item, false); + await AddOrUpdateNavigateListAsync(item, false, null, cancellationToken); } #endregion #region RemoveAsync - async Task DbContextBatchRemoveAsync(EntityState[] dels) + async Task DbContextBatchRemoveAsync(EntityState[] dels, CancellationToken cancellationToken) { if (dels.Any() == false) return 0; - var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); + var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(cancellationToken); _db._entityChangeReport.AddRange(dels.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a.Value, Type = DbContext.EntityChangeType.Delete })); return affrows; } - /// - /// 根据 lambda 条件删除数据 - /// - /// - /// - async public Task RemoveAsync(Expression> predicate) + async public Task RemoveAsync(Expression> predicate, CancellationToken cancellationToken = default) { - await DbContextFlushCommandAsync(); - return await this.OrmDelete(null).Where(predicate).ExecuteAffrowsAsync(); + await DbContextFlushCommandAsync(cancellationToken); + return await this.OrmDelete(null).Where(predicate).ExecuteAffrowsAsync(cancellationToken); } #endregion #region AddOrUpdateAsync - async public Task AddOrUpdateAsync(TEntity data) + async public Task AddOrUpdateAsync(TEntity data, CancellationToken cancellationToken = default) { if (data == null) throw new ArgumentNullException(nameof(data)); if (_table.Primarys.Any() == false) throw new Exception($"不可添加,实体没有主键:{_db.OrmOriginal.GetEntityString(_entityType, data)}"); @@ -462,23 +458,23 @@ namespace FreeSql var flagExists = ExistsInStates(data); if (flagExists == false) { - var olddata = await OrmSelect(data).FirstAsync(); + var olddata = await OrmSelect(data).FirstAsync(cancellationToken); flagExists = olddata != null; } if (flagExists == true && CanUpdate(data, false)) { - await DbContextFlushCommandAsync(); + await DbContextFlushCommandAsync(cancellationToken); var affrows = _db._affrows; - await UpdateRangePrivAsync(new[] { data }, false); - await DbContextFlushCommandAsync(); + await UpdateRangePrivAsync(new[] { data }, false, cancellationToken); + await DbContextFlushCommandAsync(cancellationToken); affrows = _db._affrows - affrows; if (affrows > 0) return; } if (CanAdd(data, false)) { _db.OrmOriginal.ClearEntityPrimaryValueWithIdentity(_entityType, data); - await AddPrivAsync(data, false); + await AddPrivAsync(data, false, cancellationToken); } } #endregion diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 82d61482..7f09665d 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -54,7 +54,7 @@ namespace FreeSql _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data, true); + AddOrUpdateNavigateList(data, true, null); } else { @@ -65,7 +65,7 @@ namespace FreeSql _db.OrmOriginal.MapEntityValue(_entityType, newval, data); Attach(newval); if (_db.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data, true); + AddOrUpdateNavigateList(data, true, null); } return; default: @@ -78,7 +78,7 @@ namespace FreeSql _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = data, Type = DbContext.EntityChangeType.Insert }); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data, true); + AddOrUpdateNavigateList(data, true, null); } return; } @@ -86,7 +86,7 @@ namespace FreeSql EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(data)); Attach(data); if (_db.Options.EnableAddOrUpdateNavigateList) - AddOrUpdateNavigateList(data, true); + AddOrUpdateNavigateList(data, true, null); } /// /// 添加 @@ -124,7 +124,7 @@ namespace FreeSql AttachRange(rets); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - AddOrUpdateNavigateList(item, true); + AddOrUpdateNavigateList(item, true, null); return; default: foreach (var s in data) @@ -140,7 +140,7 @@ namespace FreeSql AttachRange(data); if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - AddOrUpdateNavigateList(item, true); + AddOrUpdateNavigateList(item, true, null); } } @@ -210,7 +210,7 @@ namespace FreeSql _db.Options.EnableAddOrUpdateNavigateList = oldEnable; } } - void AddOrUpdateNavigateList(TEntity item, bool isAdd, string propertyName = null) + void AddOrUpdateNavigateList(TEntity item, bool isAdd, string propertyName) { Action action = prop => { @@ -472,7 +472,7 @@ namespace FreeSql } if (_db.Options.EnableAddOrUpdateNavigateList) foreach (var item in data) - AddOrUpdateNavigateList(item, false); + AddOrUpdateNavigateList(item, false, null); } #endregion diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2d6d3409..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -130,13 +130,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -509,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 458f4d65..bf6c0f7a 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Reflection; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -81,9 +82,9 @@ namespace FreeSql } #if net40 #else - async public override Task SaveChangesAsync() + async public override Task SaveChangesAsync(CancellationToken cancellationToken = default) { - await FlushCommandAsync(); + await FlushCommandAsync(cancellationToken); return SaveChangesSuccess(); } #endif diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 3a166cd5..cae91630 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -189,7 +189,7 @@ namespace FreeSql } public virtual int Delete(TKey id) => Delete(CheckTKeyAndReturnIdEntity(id)); - public virtual TEntity Find(TKey id) => Select.WhereDynamic(CheckTKeyAndReturnIdEntity(id)).ToOne(); - public TEntity Get(TKey id) => Find(id); + public virtual TEntity Find(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); + public TEntity Get(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOne(); } } diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs index 431db113..959d8d8f 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepositoryAsync.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; #if net40 @@ -13,68 +14,68 @@ namespace FreeSql where TEntity : class { - async virtual public Task DeleteAsync(Expression> predicate) + async virtual public Task DeleteAsync(Expression> predicate, CancellationToken cancellationToken = default) { var delete = _dbset.OrmDeleteInternal(null).Where(predicate); var sql = delete.ToSql(); - var affrows = await delete.ExecuteAffrowsAsync(); + var affrows = await delete.ExecuteAffrowsAsync(cancellationToken); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = sql, Type = DbContext.EntityChangeType.SqlRaw }); return affrows; } - public virtual Task DeleteAsync(TEntity entity) + public virtual Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default) { _dbset.Remove(entity); - return _db.SaveChangesAsync(); + return _db.SaveChangesAsync(cancellationToken); } - public virtual Task DeleteAsync(IEnumerable entitys) + public virtual Task DeleteAsync(IEnumerable entitys, CancellationToken cancellationToken = default) { _dbset.RemoveRange(entitys); - return _db.SaveChangesAsync(); + return _db.SaveChangesAsync(cancellationToken); } - async public virtual Task InsertAsync(TEntity entity) + async public virtual Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default) { - await _dbset.AddAsync(entity); - await _db.SaveChangesAsync(); + await _dbset.AddAsync(entity, cancellationToken); + await _db.SaveChangesAsync(cancellationToken); return entity; } - async public virtual Task> InsertAsync(IEnumerable entitys) + async public virtual Task> InsertAsync(IEnumerable entitys, CancellationToken cancellationToken = default) { - await _dbset.AddRangeAsync(entitys); - await _db.SaveChangesAsync(); + await _dbset.AddRangeAsync(entitys, cancellationToken); + await _db.SaveChangesAsync(cancellationToken); return entitys.ToList(); } - public virtual Task UpdateAsync(TEntity entity) + public virtual Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) { _dbset.Update(entity); - return _db.SaveChangesAsync(); + return _db.SaveChangesAsync(cancellationToken); } - public virtual Task UpdateAsync(IEnumerable entitys) + public virtual Task UpdateAsync(IEnumerable entitys, CancellationToken cancellationToken = default) { _dbset.UpdateRange(entitys); - return _db.SaveChangesAsync(); + return _db.SaveChangesAsync(cancellationToken); } - async public virtual Task InsertOrUpdateAsync(TEntity entity) + async public virtual Task InsertOrUpdateAsync(TEntity entity, CancellationToken cancellationToken = default) { - await _dbset.AddOrUpdateAsync(entity); - await _db.SaveChangesAsync(); + await _dbset.AddOrUpdateAsync(entity, cancellationToken); + await _db.SaveChangesAsync(cancellationToken); return entity; } - async public Task SaveManyAsync(TEntity entity, string propertyName) + async public Task SaveManyAsync(TEntity entity, string propertyName, CancellationToken cancellationToken = default) { - await _dbset.SaveManyAsync(entity, propertyName); - await _db.SaveChangesAsync(); + await _dbset.SaveManyAsync(entity, propertyName, cancellationToken); + await _db.SaveChangesAsync(cancellationToken); } } partial class BaseRepository { - public virtual Task DeleteAsync(TKey id) => DeleteAsync(CheckTKeyAndReturnIdEntity(id)); - public virtual Task FindAsync(TKey id) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(); - public Task GetAsync(TKey id) => FindAsync(id); + public virtual Task DeleteAsync(TKey id, CancellationToken cancellationToken = default) => DeleteAsync(CheckTKeyAndReturnIdEntity(id), cancellationToken); + public virtual Task FindAsync(TKey id, CancellationToken cancellationToken = default) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(cancellationToken); + public Task GetAsync(TKey id, CancellationToken cancellationToken = default) => _dbset.OrmSelectInternal(CheckTKeyAndReturnIdEntity(id)).ToOneAsync(cancellationToken); } } #endif \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs index 29832d44..91dd05fc 100644 --- a/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IBaseRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; namespace FreeSql @@ -98,17 +99,17 @@ namespace FreeSql #if net40 #else - Task InsertAsync(TEntity entity); - Task> InsertAsync(IEnumerable entitys); + Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default); + Task> InsertAsync(IEnumerable entitys, CancellationToken cancellationToken = default); - Task UpdateAsync(TEntity entity); - Task UpdateAsync(IEnumerable entitys); - Task InsertOrUpdateAsync(TEntity entity); - Task SaveManyAsync(TEntity entity, string propertyName); + Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default); + Task UpdateAsync(IEnumerable entitys, CancellationToken cancellationToken = default); + Task InsertOrUpdateAsync(TEntity entity, CancellationToken cancellationToken = default); + Task SaveManyAsync(TEntity entity, string propertyName, CancellationToken cancellationToken = default); - Task DeleteAsync(TEntity entity); - Task DeleteAsync(IEnumerable entitys); - Task DeleteAsync(Expression> predicate); + Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default); + Task DeleteAsync(IEnumerable entitys, CancellationToken cancellationToken = default); + Task DeleteAsync(Expression> predicate, CancellationToken cancellationToken = default); #endif } @@ -121,9 +122,9 @@ namespace FreeSql #if net40 #else - Task GetAsync(TKey id); - Task FindAsync(TKey id); - Task DeleteAsync(TKey id); + Task GetAsync(TKey id, CancellationToken cancellationToken = default); + Task FindAsync(TKey id, CancellationToken cancellationToken = default); + Task DeleteAsync(TKey id, CancellationToken cancellationToken = default); #endif } } \ No newline at end of file From 4ae78b1dd169d2572c31ba9f463328c5aca69d00 Mon Sep 17 00:00:00 2001 From: luoyunchong Date: Wed, 18 Nov 2020 00:58:55 +0800 Subject: [PATCH 1007/1029] =?UTF-8?q?#503=20=E5=A4=84=E7=90=86=E5=A4=96?= =?UTF-8?q?=E9=83=A8using=20=E6=8E=89DbTransaction=E7=9A=84=E6=83=85?= =?UTF-8?q?=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 6f0acb92..906ea944 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -111,7 +111,7 @@ namespace FreeSql var isCommited = false; try { - if (_tran != null) + if (_tran != null && _tran.Connection != null) { _tran.Commit(); isCommited = true; @@ -140,7 +140,7 @@ namespace FreeSql var isRollbacked = false; try { - if (_tran != null) + if (_tran != null && _tran.Connection != null) { _tran.Rollback(); isRollbacked = true; From d3fd02200098a01ce51b0776d6be22989b2ca53a Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 18 Nov 2020 09:42:09 +0800 Subject: [PATCH 1008/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Oracle/?= =?UTF-8?q?=E8=BE=BE=E6=A2=A6=20BulkCopy=20=E6=94=AF=E6=8C=81=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++ .../Dameng/Curd/DamengInsertTest.cs | 10 ++ .../Oracle/Curd/OracleInsertTest.cs | 20 ++++ .../Curd/DamengInsert.cs | 4 + .../DamengExtensions.cs | 93 +++++++++++++++++- .../FreeSqlMySqlConnectorGlobalExtensions.cs | 4 +- .../Curd/OracleInsert.cs | 4 + .../FreeSql.Provider.Oracle.csproj | 4 +- .../OracleExtensions.cs | 95 ++++++++++++++++++- .../SqlServerExtensions.cs | 8 +- 10 files changed, 239 insertions(+), 12 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..e4208f1f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -502,5 +502,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs index fbbf4931..3929e55d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertTest.cs @@ -200,6 +200,16 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(900) //var items2 = insert.AppendData(items).ExecuteInserted(); } + //[Fact] + //public void ExecuteDmBulkCopy() + //{ + // var items = new List(); + // for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + // insert.AppendData(items).InsertIdentity().ExecuteDmBulkCopy(); + // //Dm.DmException:The fastloading dll not loading! + //} + [Fact] public void AsTable() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs index 64315042..4c627ad7 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertTest.cs @@ -200,6 +200,26 @@ INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(:Clicks_9) //var items2 = insert.AppendData(items).ExecuteInserted(); } + [Fact] + public void ExecuteOracleBulkCopy() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic_bulkcopy { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + g.oracle.Insert().AppendData(items).InsertIdentity().ExecuteOracleBulkCopy(); + //insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.Clicks }).ExecuteSqlBulkCopy(); + // System.NotSupportedException:“DataSet does not support System.Nullable<>.” + } + [Table(Name = "tb_topic_bulkcopy")] + class Topic_bulkcopy + { + public Guid Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] public void AsTable() { diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs index d07499a3..54d465ca 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsert.cs @@ -19,6 +19,10 @@ namespace FreeSql.Dameng.Curd { } + internal IFreeSql InternalOrm => _orm as IFreeSql; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); diff --git a/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs b/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs index a44e710b..7774195f 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExtensions.cs @@ -1,4 +1,8 @@ -public static partial class FreeSqlDamengGlobalExtensions +using Dm; +using FreeSql; +using System; + +public static partial class FreeSqlDamengGlobalExtensions { /// @@ -9,4 +13,91 @@ /// public static string FormatDameng(this string that, params object[] args) => _damengAdo.Addslashes(that, args); static FreeSql.Dameng.DamengAdo _damengAdo = new FreeSql.Dameng.DamengAdo(); + + #region ExecuteDmBulkCopy + /// + /// 达梦 CopyBulk 批量插入功能 + /// 使用 IgnoreColumns/InsertColumns 设置忽略/指定导入的列 + /// 使用 WithConnection/WithTransaction 传入连接/事务对象 + /// 提示:若本方法不能满足,请使用 IInsert<T>.ToDataTable 方法得到 DataTable 对象后,自行处理。 + /// + /// + /// + /// + /// + /// + public static void ExecuteDmBulkCopy(this IInsert that, DmBulkCopyOptions copyOptions = DmBulkCopyOptions.Default, int? batchSize = null, int? bulkCopyTimeout = null) where T : class + { + var insert = that as FreeSql.Dameng.Curd.DamengInsert; + if (insert == null) throw new Exception("ExecuteDmBulkCopy 是 FreeSql.Provider.Dameng 特有的功能"); + + var dt = that.ToDataTable(); + if (dt.Rows.Count == 0) return; + + Action writeToServer = bulkCopy => + { + if (batchSize.HasValue) bulkCopy.BatchSize = batchSize.Value; + if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; + bulkCopy.DestinationTableName = dt.TableName; + for (int i = 0; i < dt.Columns.Count; i++) + bulkCopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); + bulkCopy.WriteToServer(dt); + }; + + try + { + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + using (var bulkCopy = copyOptions == DmBulkCopyOptions.Default ? + new DmBulkCopy(conn.Value as DmConnection) : + new DmBulkCopy(conn.Value as DmConnection, copyOptions, insert.InternalTransaction as DmTransaction)) + { + writeToServer(bulkCopy); + } + } + } + else if (insert.InternalTransaction != null) + { + using (var bulkCopy = new DmBulkCopy(insert.InternalTransaction.Connection as DmConnection, copyOptions, insert.InternalTransaction as DmTransaction)) + { + writeToServer(bulkCopy); + } + } + else if (insert.InternalConnection != null) + { + var conn = insert.InternalConnection as DmConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + conn.Open(); + } + try + { + using (var bulkCopy = copyOptions == DmBulkCopyOptions.Default ? + new DmBulkCopy(conn) : + new DmBulkCopy(conn, copyOptions, null)) + { + writeToServer(bulkCopy); + } + } + finally + { + if (isNotOpen) + conn.Close(); + } + } + else + { + throw new NotImplementedException("ExecuteDmBulkCopy 未实现错误,请反馈给作者"); + } + } + finally + { + dt.Clear(); + } + } + #endregion } diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs index ed18ca2c..e24ecc00 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs @@ -57,7 +57,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions } else if (insert.InternalTransaction != null) { - writeToServer(new MySqlBulkCopy(insert.InternalTransaction.Connection as MySqlConnection)); + writeToServer(new MySqlBulkCopy(insert.InternalTransaction.Connection as MySqlConnection, insert.InternalTransaction as MySqlTransaction)); } else if (insert.InternalConnection != null) { @@ -116,7 +116,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions } else if (insert.InternalTransaction != null) { - await writeToServer(new MySqlBulkCopy(insert.InternalTransaction.Connection as MySqlConnection)); + await writeToServer(new MySqlBulkCopy(insert.InternalTransaction.Connection as MySqlConnection, insert.InternalTransaction as MySqlTransaction)); } else if (insert.InternalConnection != null) { diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index b4a33b6d..abd8a788 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -20,6 +20,10 @@ namespace FreeSql.Oracle.Curd { } + internal IFreeSql InternalOrm => _orm as IFreeSql; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 4f95f860..dbad8099 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -26,11 +26,11 @@ - + - + diff --git a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs index 8913644b..dff0b1c9 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs @@ -1,4 +1,8 @@ -public static partial class FreeSqlOracleGlobalExtensions +using FreeSql; +using Oracle.ManagedDataAccess.Client; +using System; + +public static partial class FreeSqlOracleGlobalExtensions { /// @@ -9,4 +13,93 @@ /// public static string FormatOracle(this string that, params object[] args) => _oracleAdo.Addslashes(that, args); static FreeSql.Oracle.OracleAdo _oracleAdo = new FreeSql.Oracle.OracleAdo(); + + #region ExecuteOracleBulkCopy + /// + /// Oracle CopyBulk 批量插入功能 + /// 使用 IgnoreColumns/InsertColumns 设置忽略/指定导入的列 + /// 使用 WithConnection/WithTransaction 传入连接/事务对象 + /// 提示:若本方法不能满足,请使用 IInsert<T>.ToDataTable 方法得到 DataTable 对象后,自行处理。 + /// + /// + /// + /// + /// + /// + public static void ExecuteOracleBulkCopy(this IInsert that, OracleBulkCopyOptions copyOptions = OracleBulkCopyOptions.Default, int? batchSize = null, int? bulkCopyTimeout = null) where T : class + { + var insert = that as FreeSql.Oracle.Curd.OracleInsert; + if (insert == null) throw new Exception("ExecuteOracleBulkCopy 是 FreeSql.Provider.Oracle 特有的功能"); + + var dt = that.ToDataTable(); + if (dt.Rows.Count == 0) return; + + Action writeToServer = bulkCopy => + { + if (batchSize.HasValue) bulkCopy.BatchSize = batchSize.Value; + if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; + bulkCopy.DestinationTableName = dt.TableName; + for (int i = 0; i < dt.Columns.Count; i++) + bulkCopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); + bulkCopy.WriteToServer(dt); + }; + + try + { + if (insert.InternalConnection == null && insert.InternalTransaction == null) + { + using (var conn = insert.InternalOrm.Ado.MasterPool.Get()) + { + using (var bulkCopy = copyOptions == OracleBulkCopyOptions.Default ? + new OracleBulkCopy(conn.Value as OracleConnection) : + new OracleBulkCopy(conn.Value as OracleConnection, copyOptions)) + { + writeToServer(bulkCopy); + } + } + } + else if (insert.InternalTransaction != null) + { + using (var bulkCopy = copyOptions == OracleBulkCopyOptions.Default ? + new OracleBulkCopy(insert.InternalTransaction.Connection as OracleConnection) : + new OracleBulkCopy(insert.InternalTransaction.Connection as OracleConnection, copyOptions)) + { + writeToServer(bulkCopy); + } + } + else if (insert.InternalConnection != null) + { + var conn = insert.InternalConnection as OracleConnection; + var isNotOpen = false; + if (conn.State != System.Data.ConnectionState.Open) + { + isNotOpen = true; + conn.Open(); + } + try + { + using (var bulkCopy = copyOptions == OracleBulkCopyOptions.Default ? + new OracleBulkCopy(conn) : + new OracleBulkCopy(conn, copyOptions)) + { + writeToServer(bulkCopy); + } + } + finally + { + if (isNotOpen) + conn.Close(); + } + } + else + { + throw new NotImplementedException("ExecuteOracleBulkCopy 未实现错误,请反馈给作者"); + } + } + finally + { + dt.Clear(); + } + } + #endregion } diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs index a3fe2972..b96e4b42 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExtensions.cs @@ -104,9 +104,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions } else if (insert.InternalTransaction != null) { - using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? - new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection) : - new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection, copyOptions, insert.InternalTransaction as SqlTransaction)) + using (var bulkCopy = new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection, copyOptions, insert.InternalTransaction as SqlTransaction)) { writeToServer(bulkCopy); } @@ -181,9 +179,7 @@ public static partial class FreeSqlSqlServerGlobalExtensions } else if (insert.InternalTransaction != null) { - using (var bulkCopy = copyOptions == SqlBulkCopyOptions.Default ? - new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection) : - new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection, copyOptions, insert.InternalTransaction as SqlTransaction)) + using (var bulkCopy = new SqlBulkCopy(insert.InternalTransaction.Connection as SqlConnection, copyOptions, insert.InternalTransaction as SqlTransaction)) { await writeToServerAsync(bulkCopy); } From 60682936fafcce75b1899e5cfbcb0fc28cc154f4 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 18 Nov 2020 10:17:11 +0800 Subject: [PATCH 1009/1029] v2.0.0-preview1119 #542 #537 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 8 ++++---- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 24 files changed, 26 insertions(+), 35 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index c4537ea0..5ccea96d 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index c0fd2995..85e2127e 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index aafefb37..1064d329 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index bff31e6a..75e21e4b 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 987d74f5..5c2ed2cb 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1115 + 2.0.0-preview1119 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 6e5da60a..82a59e1e 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 2c7a9546..0a0e402d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index e4208f1f..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -502,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 906ea944..2480ac88 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -111,9 +111,9 @@ namespace FreeSql var isCommited = false; try { - if (_tran != null && _tran.Connection != null) + if (_tran != null) { - _tran.Commit(); + if (_tran.Connection != null) _tran.Commit(); isCommited = true; _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "提交", null)); @@ -140,9 +140,9 @@ namespace FreeSql var isRollbacked = false; try { - if (_tran != null && _tran.Connection != null) + if (_tran != null) { - _tran.Rollback(); + if (_tran.Connection != null) _tran.Rollback(); isRollbacked = true; _fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "回滚", null)); } diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index bc578f32..98e6e236 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 77dbb2f3..614f766b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 7eced38b..3f130eff 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index d6f84c29..b194a413 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index f955043c..0211bb5f 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 7e6987c8..faca294a 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index bbd40ed0..2408fe73 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index d9668dc8..4db32d6e 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 7340311d..f35549c3 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index dbad8099..96d1b780 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index ba3b8169..44f3cd92 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 33566c79..fa1f08ac 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index b0823c0a..c5a2f7a2 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index a825c6ec..4077ce7d 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 64eb1c89..76e25c5d 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1115 + 2.0.0-preview1119 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From d38be498a37a571941e68500abbb3738e52bd049 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 19 Nov 2020 20:21:32 +0800 Subject: [PATCH 1010/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IsVersion=20?= =?UTF-8?q?=E5=AF=B9=20byte[]=20=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=9B#548?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++++ FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 49 +++++++++++++++++++ .../Internal/CommonProvider/InsertProvider.cs | 2 + .../Internal/CommonProvider/UpdateProvider.cs | 19 ++++++- FreeSql/Internal/UtilsExpressionTree.cs | 25 +++++----- .../Curd/DamengInsertOrUpdate.cs | 2 +- .../Curd/FirebirdInsertOrUpdate.cs | 2 +- .../Curd/KingbaseESOnConflictDoUpdate.cs | 2 +- .../Curd/OnDuplicateKeyUpdate.cs | 2 +- .../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 2 +- .../Curd/OdbcKingbaseESOnConflictDoUpdate.cs | 2 +- .../Curd/OdbcMySqlOnDuplicateKeyUpdate.cs | 2 +- .../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 2 +- .../Curd/OdbcPostgreSQLOnConflictDoUpdate.cs | 2 +- .../Curd/OdbcSqlServerInsertOrUpdate.cs | 2 +- .../Curd/OracleInsertOrUpdate.cs | 2 +- .../Curd/OnConflictDoUpdate.cs | 2 +- .../Curd/ShenTongInsertOrUpdate.cs | 2 +- .../Curd/SqlServerInsertOrUpdate.cs | 2 +- 19 files changed, 104 insertions(+), 28 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..e4208f1f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -502,5 +502,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index 84a3effb..f4b11936 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -1,4 +1,5 @@ using FreeSql.DataAnnotations; +using FreeSql.Internal; using System; using System.Collections.Generic; using System.Diagnostics; @@ -11,6 +12,54 @@ namespace FreeSql.Tests { public class UnitTest4 { + [Fact] + public void VersionByte() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var id = Guid.NewGuid(); + Assert.Equal(1, fsql.Insert(new ts_ver_byte { id = id, title = "001" }).ExecuteAffrows()); + + var item = fsql.Select(id).First(); + item.title = "002"; + Assert.Equal(1, fsql.Update().SetSource(item).ExecuteAffrows()); + item.title = "003"; + Assert.Equal(1, fsql.Update().SetSource(item).ExecuteAffrows()); + + item.version = Utils.GuidToBytes(Guid.NewGuid()); + item.title = "004"; + Assert.Throws(() => fsql.Update().SetSource(item).ExecuteAffrows()); + + fsql.Delete().Where("1=1").ExecuteAffrows(); + Assert.Equal(2, fsql.Insert(new[] { new ts_ver_byte { id = Guid.NewGuid(), title = "001" }, new ts_ver_byte { id = Guid.NewGuid(), title = "0011" } }).ExecuteAffrows()); + var items = fsql.Select().OrderBy(a => a.title).ToList(); + Assert.Equal(2, items.Count); + items[0].title = "002"; + items[1].title = "0022"; + Assert.Equal(2, fsql.Update().SetSource(items).ExecuteAffrows()); + items[0].title = "003"; + items[1].title = "0033"; + Assert.Equal(2, fsql.Update().SetSource(items).ExecuteAffrows()); + + items[0].version = Utils.GuidToBytes(Guid.NewGuid()); + items[0].title = "004"; + items[1].title = "0044"; + Assert.Throws(() => fsql.Update().SetSource(items).ExecuteAffrows()); + + items[0].version = Utils.GuidToBytes(Guid.NewGuid()); + items[1].version = Utils.GuidToBytes(Guid.NewGuid()); + items[0].title = "004"; + items[1].title = "0044"; + Assert.Throws(() => fsql.Update().SetSource(items).ExecuteAffrows()); + } + class ts_ver_byte + { + public Guid id { get; set; } + public string title { get; set; } + [Column(IsVersion = true)] + public byte[] version { get; set; } + } + public record ts_iif(Guid id, string title); [Fact] diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index cb14f9cb..2862a900 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -179,6 +179,8 @@ namespace FreeSql.Internal.CommonProvider } if (val == null && col.Attribute.MapType == typeof(string) && col.Attribute.IsNullable == false) col.SetValue(data, val = ""); + if (val == null && col.Attribute.MapType == typeof(byte[]) && col.Attribute.IsVersion) + col.SetValue(data, val = Utils.GuidToBytes(Guid.NewGuid())); } } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 14fb2985..ef22fe9c 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -37,6 +37,7 @@ namespace FreeSql.Internal.CommonProvider public DbConnection _connection; public int _commandTimeout = 0; public Action _interceptSql; + public byte[] _updateVersionValue; public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { @@ -75,6 +76,9 @@ namespace FreeSql.Internal.CommonProvider _paramsSource.Clear(); IgnoreCanUpdate(); _whereGlobalFilter = _orm.GlobalFilter.GetFilters(); + _batchProgress = null; + _interceptSql = null; + _updateVersionValue = null; } public IUpdate WithTransaction(DbTransaction transaction) @@ -122,7 +126,12 @@ namespace FreeSql.Internal.CommonProvider if (affrows != _source.Count) throw new DbUpdateVersionException($"记录可能不存在,或者【行级乐观锁】版本过旧,更新数量{_source.Count},影响的行数{affrows}。", _table, sql, dbParms, affrows, _source.Select(a => (object)a)); foreach (var d in _source) - _orm.SetEntityIncrByWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, 1); + { + if (_table.VersionColumn.Attribute.MapType == typeof(byte[])) + _orm.SetEntityValueWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, _updateVersionValue); + else + _orm.SetEntityIncrByWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, 1); + } } } @@ -768,7 +777,13 @@ namespace FreeSql.Internal.CommonProvider if (_table.VersionColumn != null) { var vcname = _commonUtils.QuoteSqlName(_table.VersionColumn.Attribute.Name); - sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.IsNull(vcname, 0)).Append(" + 1"); + if (_table.VersionColumn.Attribute.MapType == typeof(byte[])) + { + _updateVersionValue = Utils.GuidToBytes(Guid.NewGuid()); + sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "uv", _table.VersionColumn, _table.VersionColumn.Attribute.MapType, _updateVersionValue)); + } + else + sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.IsNull(vcname, 0)).Append(" + 1"); } sb.Append(" \r\nWHERE "); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 0786b1ec..3438b9c7 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -282,6 +282,7 @@ namespace FreeSql.Internal break; } } + if (colattr.MapType == typeof(byte[]) && colattr.IsVersion == true) colattr.StringLength = 16; if (colattr.MapType == typeof(byte[]) && colattr.StringLength != 0) { int strlen = colattr.StringLength; @@ -346,8 +347,8 @@ namespace FreeSql.Internal trytb.VersionColumn = trytb.Columns.Values.Where(a => a.Attribute.IsVersion == true).LastOrDefault(); if (trytb.VersionColumn != null) { - if (trytb.VersionColumn.Attribute.MapType.IsNullableType() || trytb.VersionColumn.Attribute.MapType.IsNumberType() == false) - throw new Exception($"属性{trytb.VersionColumn.CsName} 被标注为行锁(乐观锁)(IsVersion),但其必须为数字类型,并且不可为 Nullable"); + if (trytb.VersionColumn.Attribute.MapType.IsNullableType() || trytb.VersionColumn.Attribute.MapType.IsNumberType() == false && trytb.VersionColumn.Attribute.MapType != typeof(byte[])) + throw new Exception($"属性{trytb.VersionColumn.CsName} 被标注为行锁(乐观锁)(IsVersion),但其必须为数字类型 或者 byte[],并且不可为 Nullable"); } var indexesDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); @@ -1742,18 +1743,18 @@ namespace FreeSql.Internal act(info, value); } - static BigInteger ToBigInteger(string that) + public static BigInteger ToBigInteger(string that) { if (string.IsNullOrEmpty(that)) return 0; if (BigInteger.TryParse(that, System.Globalization.NumberStyles.Any, null, out var trybigint)) return trybigint; return 0; } - static string ToStringConcat(object obj) + public static string ToStringConcat(object obj) { if (obj == null) return null; return string.Concat(obj); } - static byte[] GuidToBytes(Guid guid) + public static byte[] GuidToBytes(Guid guid) { var bytes = new byte[16]; var guidN = guid.ToString("N"); @@ -1761,12 +1762,12 @@ namespace FreeSql.Internal bytes[a / 2] = byte.Parse($"{guidN[a]}{guidN[a + 1]}", System.Globalization.NumberStyles.HexNumber); return bytes; } - static Guid BytesToGuid(byte[] bytes) + public static Guid BytesToGuid(byte[] bytes) { if (bytes == null) return Guid.Empty; return Guid.TryParse(BitConverter.ToString(bytes, 0, Math.Min(bytes.Length, 36)).Replace("-", ""), out var tryguid) ? tryguid : Guid.Empty; } - static char StringToChar(string str) + public static char StringToChar(string str) { if (string.IsNullOrEmpty(str)) return default(char); return str.ToCharArray(0, 1)[0]; @@ -1793,8 +1794,8 @@ namespace FreeSql.Internal static MethodInfo MethodTimeSpanTryParse = typeof(TimeSpan).GetMethod("TryParse", new[] { typeof(string), typeof(TimeSpan).MakeByRefType() }); static MethodInfo MethodDateTimeTryParse = typeof(DateTime).GetMethod("TryParse", new[] { typeof(string), typeof(DateTime).MakeByRefType() }); static MethodInfo MethodDateTimeOffsetTryParse = typeof(DateTimeOffset).GetMethod("TryParse", new[] { typeof(string), typeof(DateTimeOffset).MakeByRefType() }); - static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null); - static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); + static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(object) }, null); + static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null); static PropertyInfo PropertyDateTimeOffsetDateTime = typeof(DateTimeOffset).GetProperty("DateTime", BindingFlags.Instance | BindingFlags.Public); static PropertyInfo PropertyDateTimeTicks = typeof(DateTime).GetProperty("Ticks", BindingFlags.Instance | BindingFlags.Public); static ConstructorInfo CtorDateTimeOffsetArgsTicks = typeof(DateTimeOffset). GetConstructor(new[] { typeof(long), typeof(TimeSpan) }); @@ -1802,9 +1803,9 @@ namespace FreeSql.Internal static MethodInfo MethodEncodingGetBytes = typeof(Encoding).GetMethod("GetBytes", new[] { typeof(string) }); static MethodInfo MethodEncodingGetString = typeof(Encoding).GetMethod("GetString", new[] { typeof(byte[]) }); static MethodInfo MethodStringToCharArray = typeof(string).GetMethod("ToCharArray", new Type[0]); - static MethodInfo MethodStringToChar = typeof(Utils).GetMethod("StringToChar", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null); - static MethodInfo MethodGuidToBytes = typeof(Utils).GetMethod("GuidToBytes", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(Guid) }, null); - static MethodInfo MethodBytesToGuid = typeof(Utils).GetMethod("BytesToGuid", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(byte[]) }, null); + static MethodInfo MethodStringToChar = typeof(Utils).GetMethod("StringToChar", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null); + static MethodInfo MethodGuidToBytes = typeof(Utils).GetMethod("GuidToBytes", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(Guid) }, null); + static MethodInfo MethodBytesToGuid = typeof(Utils).GetMethod("BytesToGuid", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(byte[]) }, null); public static ConcurrentBag> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag>(); public static ConcurrentBag> GetDataReaderValueBlockExpressionObjectToStringIfThenElse = new ConcurrentBag>(); diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index 92cf3456..d28c3773 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.Dameng.Curd if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); diff --git a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs index a4272fe9..33a3883c 100644 --- a/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Firebird/Curd/FirebirdInsertOrUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.Firebird.Curd if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); diff --git a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs index aa86a9d9..063823cc 100644 --- a/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.KingbaseES/Curd/KingbaseESOnConflictDoUpdate.cs @@ -125,7 +125,7 @@ namespace FreeSql.KingbaseES if (colidx > 0) sb.Append(", \r\n"); - if (col.Attribute.IsVersion == true) + if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[])) { var field = _insert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); sb.Append(field).Append(" = ").Append(_insert.InternalCommonUtils.QuoteSqlName(_insert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs index 14205596..dbf05870 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -85,7 +85,7 @@ namespace FreeSql.MySql.Curd if (colidx > 0) sb.Append(", \r\n"); - if (col.Attribute.IsVersion == true) + if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[])) { var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); sb.Append(field).Append(" = ").Append(field).Append(" + 1"); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index fccbb8ad..0cb0719e 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.Odbc.Dameng if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs index 3ff78116..13c27ab3 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESOnConflictDoUpdate.cs @@ -125,7 +125,7 @@ namespace FreeSql.Odbc.KingbaseES if (colidx > 0) sb.Append(", \r\n"); - if (col.Attribute.IsVersion == true) + if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[])) { var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs index ae552a90..9a5931b6 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlOnDuplicateKeyUpdate.cs @@ -85,7 +85,7 @@ namespace FreeSql.Odbc.MySql if (colidx > 0) sb.Append(", \r\n"); - if (col.Attribute.IsVersion == true) + if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[])) { var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); sb.Append(field).Append(" = ").Append(field).Append(" + 1"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index d87a9204..3c0cda03 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.Odbc.Oracle if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs index 3f1262a0..1e096d04 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLOnConflictDoUpdate.cs @@ -125,7 +125,7 @@ namespace FreeSql.Odbc.PostgreSQL if (colidx > 0) sb.Append(", \r\n"); - if (col.Attribute.IsVersion == true) + if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[])) { var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index bb702281..a7f80b15 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -43,7 +43,7 @@ namespace FreeSql.Odbc.SqlServer if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index 4758bec8..07d5f3e6 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.Oracle.Curd if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs index 383910d0..50145b35 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/OnConflictDoUpdate.cs @@ -125,7 +125,7 @@ namespace FreeSql.PostgreSQL.Curd if (colidx > 0) sb.Append(", \r\n"); - if (col.Attribute.IsVersion == true) + if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[])) { var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs index 302343b7..3043cfd5 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs @@ -41,7 +41,7 @@ namespace FreeSql.ShenTong.Curd if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index e844e2c3..09e455c0 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -43,7 +43,7 @@ namespace FreeSql.SqlServer.Curd if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => - a.Attribute.IsVersion ? + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}" ))).Append(" \r\n"); From db3fa7d5758a5b63f801b731dfbb4121e1de828b Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 19 Nov 2020 20:37:28 +0800 Subject: [PATCH 1011/1029] v2.0.0-preview1120 #548 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --------- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 22 insertions(+), 31 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5ccea96d..4bfc0432 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 85e2127e..52548c96 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 1064d329..c69450ee 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 75e21e4b..e012d8cf 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 5c2ed2cb..63a13275 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1119 + 2.0.0-preview1120 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 82a59e1e..5bf477c5 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 0a0e402d..504e41b9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index e4208f1f..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -502,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 98e6e236..be016764 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 614f766b..95b5bd37 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 3f130eff..6a08cb8f 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index b194a413..85c448a7 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 0211bb5f..5a8200c2 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index faca294a..abdaf261 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 2408fe73..b7366e52 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4db32d6e..f35b52ec 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index f35549c3..cd7bcb1d 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 96d1b780..197f8614 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 44f3cd92..2c88f96c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index fa1f08ac..8ddaca04 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index c5a2f7a2..be1b59be 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 4077ce7d..8d95f94c 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 76e25c5d..24050497 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1119 + 2.0.0-preview1120 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 6ba85cfc75ee5268b030401b983ac8153f527c7d Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sun, 22 Nov 2020 12:40:02 +0800 Subject: [PATCH 1012/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20SqlServer=20?= =?UTF-8?q?RowNumber=20=E5=88=86=E9=A1=B5=E6=9C=89=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E4=BA=A7=E7=94=9F=E9=A1=BA=E5=BA=8F=E4=B8=8D=E5=AF=B9=E7=9A=84?= =?UTF-8?q?=20bug=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 160 ------------------ .../SqlServer/Curd/OdbcSqlServerSelect.cs | 5 +- .../Curd/SqlServerSelect.cs | 5 +- 3 files changed, 6 insertions(+), 164 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3632c4f9..c52db9a4 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3050,154 +3050,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - 可自定义解析表达式 @@ -4026,12 +3878,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4102,12 +3948,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs index 6302576f..342d74ed 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerSelect.cs @@ -38,7 +38,8 @@ namespace FreeSql.Odbc.SqlServer var sbnav = new StringBuilder(); sb.Append(_select); if (_distinct) sb.Append("DISTINCT "); - if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); + //if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); //TOP 会引发 __rownum__ 无序的问题 + if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); sb.Append(field); if (_skip > 0) { @@ -123,7 +124,7 @@ namespace FreeSql.Odbc.SqlServer if (_skip <= 0) sb.Append(_orderby); else - sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); + sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ between ").Append(_skip + 1).Append(" and ").Append(_skip + _limit); sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs index fa1c1af6..25698185 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerSelect.cs @@ -38,7 +38,8 @@ namespace FreeSql.SqlServer.Curd var sbnav = new StringBuilder(); sb.Append(_select); if (_distinct) sb.Append("DISTINCT "); - if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); + //if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); //TOP 会引发 __rownum__ 无序的问题 + if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); sb.Append(field); if (_skip > 0) { @@ -123,7 +124,7 @@ namespace FreeSql.SqlServer.Curd if (_skip <= 0) sb.Append(_orderby); else - sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ > ").Append(_skip); + sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__ between ").Append(_skip + 1).Append(" and ").Append(_skip + _limit); sbnav.Clear(); if (tbUnionsGt0) sb.Append(") ftb"); From 9dd63f165bd462399d904e9b914ffb3dacc56667 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sun, 22 Nov 2020 12:44:11 +0800 Subject: [PATCH 1013/1029] v2.0.0-preview1122 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 + FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 160 ++++++++++++++++++ .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 24 files changed, 191 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 4bfc0432..79fe9b00 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 52548c96..4d688e99 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index c69450ee..b076f78e 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index e012d8cf..cbe0915a 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 63a13275..296c6e6c 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1120 + 2.0.0-preview1122 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 5bf477c5..8e043fb0 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 504e41b9..48305a07 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..e4208f1f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -502,5 +502,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index be016764..beabc1f8 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 95b5bd37..173c87bd 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c52db9a4..3632c4f9 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3050,6 +3050,154 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + 可自定义解析表达式 @@ -3878,6 +4026,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3948,6 +4102,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 6a08cb8f..691659a3 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 85c448a7..c7f29620 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 5a8200c2..b64f9da4 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index abdaf261..838a98a8 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index b7366e52..bd9126f8 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index f35b52ec..bae4b425 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index cd7bcb1d..a1b814f1 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 197f8614..6b81ee39 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 2c88f96c..c4aae049 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 8ddaca04..ef2385fd 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index be1b59be..3b01d818 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 8d95f94c..508b0c53 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 24050497..6c4cac03 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1120 + 2.0.0-preview1122 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 44e6eb29796be061dd85e0a2eb19cd625f930eb4 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 23 Nov 2020 10:36:35 +0800 Subject: [PATCH 1014/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20.net5=20?= =?UTF-8?q?=E5=8D=95=E6=96=87=E6=9C=AC=E9=83=A8=E7=BD=B2=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E6=8A=A5=E9=94=99=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dbcontext_01/.config/dotnet-tools.json | 12 ++++ .../PublishProfiles/FolderProfile.pubxml | 22 +++++++ Examples/dbcontext_01/dbcontext_01.csproj | 7 +- Examples/dbcontext_01/dbcontext_01.xml | 8 +++ FreeSql/Extensions/AdoNetExtensions.cs | 31 +++++++++ FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 18 +++-- FreeSql/FreeSql.xml | 66 +++++++++++++++++++ FreeSql/Interface/Curd/ISelect/ISelect1.cs | 1 + .../Interface/Curd/ISelect/ISelectGrouping.cs | 1 + FreeSql/Interface/IAdo.cs | 29 ++++++++ .../AdoProvider/AdoProviderTransaction.cs | 4 +- .../CommonProvider/CodeFirstProvider.cs | 2 +- .../Internal/CommonProvider/DeleteProvider.cs | 4 +- .../CommonProvider/DeleteProviderAsync.cs | 2 +- .../CommonProvider/InsertOrUpdateProvider.cs | 8 +-- .../Internal/CommonProvider/InsertProvider.cs | 18 ++--- .../CommonProvider/InsertProviderAsync.cs | 14 ++-- .../SelectProvider/Select0ProviderReader.cs | 32 ++++----- .../Internal/CommonProvider/UpdateProvider.cs | 20 +++--- .../CommonProvider/UpdateProviderAsync.cs | 10 +-- FreeSql/Internal/CommonUtils.cs | 24 +++++-- 21 files changed, 262 insertions(+), 71 deletions(-) create mode 100644 Examples/dbcontext_01/.config/dotnet-tools.json create mode 100644 Examples/dbcontext_01/Properties/PublishProfiles/FolderProfile.pubxml create mode 100644 Examples/dbcontext_01/dbcontext_01.xml diff --git a/Examples/dbcontext_01/.config/dotnet-tools.json b/Examples/dbcontext_01/.config/dotnet-tools.json new file mode 100644 index 00000000..c735fef1 --- /dev/null +++ b/Examples/dbcontext_01/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "5.0.0", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/Examples/dbcontext_01/Properties/PublishProfiles/FolderProfile.pubxml b/Examples/dbcontext_01/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 00000000..d895b3b8 --- /dev/null +++ b/Examples/dbcontext_01/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,22 @@ + + + + + True + False + True + Release + Any CPU + FileSystem + bin\Release\net5.0\publish\ + FileSystem + + net5.0 + win-x86 + 690f89e0-a721-423f-8f5d-d262f73235ea + true + True + + \ No newline at end of file diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj index 2b5846c8..46c1f9de 100644 --- a/Examples/dbcontext_01/dbcontext_01.csproj +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -3,6 +3,11 @@ net5.0 InProcess + f2b3f543-99d4-4be7-b894-6df3c6cbad7e + + + + dbcontext_01.xml @@ -12,7 +17,7 @@ - + diff --git a/Examples/dbcontext_01/dbcontext_01.xml b/Examples/dbcontext_01/dbcontext_01.xml new file mode 100644 index 00000000..b9d14721 --- /dev/null +++ b/Examples/dbcontext_01/dbcontext_01.xml @@ -0,0 +1,8 @@ + + + + dbcontext_01 + + + + diff --git a/FreeSql/Extensions/AdoNetExtensions.cs b/FreeSql/Extensions/AdoNetExtensions.cs index b9f874ba..a4275d06 100644 --- a/FreeSql/Extensions/AdoNetExtensions.cs +++ b/FreeSql/Extensions/AdoNetExtensions.cs @@ -85,6 +85,7 @@ namespace FreeSql /// 插入数据,传入实体 /// /// + /// /// /// public static IInsert Insert(this IDbConnection that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); @@ -92,6 +93,7 @@ namespace FreeSql /// 插入数据,传入实体数组 /// /// + /// /// /// public static IInsert Insert(this IDbConnection that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); @@ -99,6 +101,7 @@ namespace FreeSql /// 插入数据,传入实体集合 /// /// + /// /// /// public static IInsert Insert(this IDbConnection that, List source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); @@ -106,6 +109,7 @@ namespace FreeSql /// 插入数据,传入实体集合 /// /// + /// /// /// public static IInsert Insert(this IDbConnection that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithConnection(that as DbConnection); @@ -125,6 +129,7 @@ namespace FreeSql /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) /// /// + /// /// public static IInsertOrUpdate InsertOrUpdate(this IDbConnection that) where T1 : class => GetCrud(that).InsertOrUpdate().WithConnection(that as DbConnection); @@ -132,12 +137,14 @@ namespace FreeSql /// 修改数据 /// /// + /// /// public static IUpdate Update(this IDbConnection that) where T1 : class => GetCrud(that).Update().WithConnection(that as DbConnection); /// /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// + /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IUpdate Update(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithConnection(that as DbConnection); @@ -146,12 +153,14 @@ namespace FreeSql /// 查询数据 /// /// + /// /// public static ISelect Select(this IDbConnection that) where T1 : class => GetCrud(that).Select().WithConnection(that as DbConnection); /// /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// + /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static ISelect Select(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithConnection(that as DbConnection); @@ -160,12 +169,14 @@ namespace FreeSql /// 删除数据 /// /// + /// /// public static IDelete Delete(this IDbConnection that) where T1 : class => GetCrud(that).Delete().WithConnection(that as DbConnection); /// /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// + /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IDelete Delete(this IDbConnection that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithConnection(that as DbConnection); @@ -173,54 +184,63 @@ namespace FreeSql /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class => GetCrud(that).Select().From((s, b) => s); /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class => GetCrud(that).Select().From((s, b, c) => s); /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class => GetCrud(that).Select().From((s, b, c, d) => s); /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => GetCrud(that).Select().From((s, b, c, d, e) => s); /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => GetCrud(that).Select().From((s, b, c, d, e, f) => s); /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => GetCrud(that).Select().From((s, b, c, d, e, f, g) => s); /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => GetCrud(that).Select().From((s, b, c, d, e, f, g, h) => s); /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) 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 => GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i) => s); /// /// 多表查询 /// + /// /// public static ISelect Select(this IDbConnection that) 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 => GetCrud(that).Select().From((s, b, c, d, e, f, g, h, i, j) => s); @@ -237,6 +257,7 @@ namespace FreeSql /// 插入数据,传入实体 /// /// + /// /// /// public static IInsert Insert(this IDbTransaction that, T1 source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); @@ -244,6 +265,7 @@ namespace FreeSql /// 插入数据,传入实体数组 /// /// + /// /// /// public static IInsert Insert(this IDbTransaction that, T1[] source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); @@ -251,6 +273,7 @@ namespace FreeSql /// 插入数据,传入实体集合 /// /// + /// /// /// public static IInsert Insert(this IDbTransaction that, List source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); @@ -258,6 +281,7 @@ namespace FreeSql /// 插入数据,传入实体集合 /// /// + /// /// /// public static IInsert Insert(this IDbTransaction that, IEnumerable source) where T1 : class => GetCrud(that).Insert(source).WithTransaction(that as DbTransaction); @@ -276,6 +300,7 @@ namespace FreeSql /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) /// /// + /// /// public static IInsertOrUpdate InsertOrUpdate(this IDbTransaction that) where T1 : class => GetCrud(that).InsertOrUpdate().WithTransaction(that as DbTransaction); @@ -283,12 +308,14 @@ namespace FreeSql /// 修改数据 /// /// + /// /// public static IUpdate Update(this IDbTransaction that) where T1 : class => GetCrud(that).Update().WithTransaction(that as DbTransaction); /// /// 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// + /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IUpdate Update(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Update(dywhere).WithTransaction(that as DbTransaction); @@ -297,12 +324,14 @@ namespace FreeSql /// 查询数据 /// /// + /// /// public static ISelect Select(this IDbTransaction that) where T1 : class => GetCrud(that).Select().WithTransaction(that as DbTransaction); /// /// 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// + /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static ISelect Select(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Select(dywhere).WithTransaction(that as DbTransaction); @@ -311,12 +340,14 @@ namespace FreeSql /// 删除数据 /// /// + /// /// public static IDelete Delete(this IDbTransaction that) where T1 : class => GetCrud(that).Delete().WithTransaction(that as DbTransaction); /// /// 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// + /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 /// public static IDelete Delete(this IDbTransaction that, object dywhere) where T1 : class => GetCrud(that).Delete(dywhere).WithTransaction(that as DbTransaction); diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 531a8f8b..79d62f2e 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -56,6 +56,7 @@ public static partial class FreeSqlGlobalExtensions /// 获取 Type 的原始 c# 文本表示 /// /// + /// /// internal static string DisplayCsharp(this Type type, bool isNameSpace = true) { @@ -88,14 +89,14 @@ public static partial class FreeSqlGlobalExtensions if (genericParameters.Any() == false) return sb.Append(type.Name).ToString(); - sb.Append(type.Name.Remove(type.Name.IndexOf('`'))).Append("<"); + sb.Append(type.Name.Remove(type.Name.IndexOf('`'))).Append('<'); var genericTypeIndex = 0; foreach (var genericType in genericParameters) { if (genericTypeIndex++ > 0) sb.Append(", "); sb.Append(DisplayCsharp(genericType, true)); } - return sb.Append(">").ToString(); + return sb.Append('>').ToString(); } internal static string DisplayCsharp(this MethodInfo method, bool isOverride) { @@ -109,7 +110,7 @@ public static partial class FreeSqlGlobalExtensions if (method.IsStatic) sb.Append("static "); if (method.IsAbstract && method.DeclaringType.IsInterface == false) sb.Append("abstract "); if (method.IsVirtual && method.DeclaringType.IsInterface == false) sb.Append(isOverride ? "override " : "virtual "); - sb.Append(method.ReturnType.DisplayCsharp()).Append(" ").Append(method.Name); + sb.Append(method.ReturnType.DisplayCsharp()).Append(' ').Append(method.Name); var genericParameters = method.GetGenericArguments(); if (method.DeclaringType.IsNested && method.DeclaringType.DeclaringType.IsGenericType) @@ -121,11 +122,11 @@ public static partial class FreeSqlGlobalExtensions genericParameters = dic.Values.ToArray(); } if (genericParameters.Any()) - sb.Append("<") + sb.Append('<') .Append(string.Join(", ", genericParameters.Select(a => a.DisplayCsharp()))) - .Append(">"); + .Append('>'); - sb.Append("(").Append(string.Join(", ", method.GetParameters().Select(a => $"{a.ParameterType.DisplayCsharp()} {a.Name}"))).Append(")"); + sb.Append('(').Append(string.Join(", ", method.GetParameters().Select(a => $"{a.ParameterType.DisplayCsharp()} {a.Name}"))).Append(')'); return sb.ToString(); } public static object CreateInstanceGetDefaultValue(this Type that) @@ -283,7 +284,10 @@ public static partial class FreeSqlGlobalExtensions /// 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); /// 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany /// + /// /// + /// + /// /// 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) /// 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) /// 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) @@ -538,7 +542,7 @@ JOIN {select._commonUtils.QuoteSqlName(tb.DbName)} a ON cte_tbc.cte_id = a.{sele .OrderBy(up, "a.cte_level desc") as Select1Provider; var nsselsb = new StringBuilder(); - if (AdoProvider.IsFromSlave(select._select) == false) nsselsb.Append(" "); //读写分离规则,如果强制读主库,则在前面加个空格 + if (AdoProvider.IsFromSlave(select._select) == false) nsselsb.Append(' '); //读写分离规则,如果强制读主库,则在前面加个空格 nsselsb.Append("WITH "); switch (select._orm.Ado.DataType) { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 3632c4f9..5140edee 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -635,6 +635,7 @@ 插入数据,传入实体 + @@ -643,6 +644,7 @@ 插入数据,传入实体数组 + @@ -651,6 +653,7 @@ 插入数据,传入实体集合 + @@ -659,6 +662,7 @@ 插入数据,传入实体集合 + @@ -678,6 +682,7 @@ 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + @@ -685,6 +690,7 @@ 修改数据 + @@ -692,6 +698,7 @@ 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -700,6 +707,7 @@ 查询数据 + @@ -707,6 +715,7 @@ 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -715,6 +724,7 @@ 删除数据 + @@ -722,6 +732,7 @@ 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -729,54 +740,63 @@ 多表查询 + 多表查询 + 多表查询 + 多表查询 + 多表查询 + 多表查询 + 多表查询 + 多表查询 + 多表查询 + @@ -791,6 +811,7 @@ 插入数据,传入实体 + @@ -799,6 +820,7 @@ 插入数据,传入实体数组 + @@ -807,6 +829,7 @@ 插入数据,传入实体集合 + @@ -815,6 +838,7 @@ 插入数据,传入实体集合 + @@ -833,6 +857,7 @@ 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + @@ -840,6 +865,7 @@ 修改数据 + @@ -847,6 +873,7 @@ 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -855,6 +882,7 @@ 查询数据 + @@ -862,6 +890,7 @@ 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -870,6 +899,7 @@ 删除数据 + @@ -877,6 +907,7 @@ 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 @@ -2268,6 +2299,7 @@ + lambda表达式 @@ -2471,6 +2503,7 @@ 返回类型 选择列 + @@ -2925,6 +2958,7 @@ 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> + @@ -2932,6 +2966,7 @@ 查询 + @@ -2948,6 +2983,7 @@ 查询 + @@ -2964,6 +3000,7 @@ 查询 + @@ -3035,6 +3072,7 @@ 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + @@ -3046,6 +3084,7 @@ 提示:parms 参数还可以传 Dictionary<string, object> + @@ -3057,6 +3096,7 @@ Oracle: SELECT 1 FROM dual 命令超时设置(秒) + true: 成功, false: 失败 @@ -3067,21 +3107,26 @@ + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> + + 查询 + + @@ -3090,14 +3135,17 @@ + 查询 + + @@ -3106,14 +3154,17 @@ + 查询 + + @@ -3122,6 +3173,7 @@ + @@ -3131,6 +3183,7 @@ + @@ -3139,6 +3192,7 @@ + @@ -3148,6 +3202,7 @@ + @@ -3156,6 +3211,7 @@ + @@ -3166,6 +3222,7 @@ + @@ -3176,6 +3233,7 @@ + @@ -3183,9 +3241,11 @@ 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + @@ -3194,8 +3254,10 @@ 提示:parms 参数还可以传 Dictionary<string, object> + + @@ -4317,6 +4379,7 @@ 获取 Type 的原始 c# 文本表示 + @@ -4347,7 +4410,10 @@ 示例:new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags); 文档:https://github.com/2881099/FreeSql/wiki/%e8%b4%aa%e5%a9%aa%e5%8a%a0%e8%bd%bd#%E5%AF%BC%E8%88%AA%E5%B1%9E%E6%80%A7-onetomanymanytomany + + + 选择一个集合的导航属性,如: .IncludeMany(a => a.Tags) 可以 .Where 设置临时的关系映射,如: .IncludeMany(a => a.Tags.Where(tag => tag.TypeId == a.Id)) 可以 .Take(5) 每个子集合只取5条,如: .IncludeMany(a => a.Tags.Take(5)) diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 4bff2524..d2537fcb 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -242,6 +242,7 @@ namespace FreeSql /// /// /// + /// /// lambda表达式 /// ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class where T5 : class; diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 1e311a29..295b7411 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -57,6 +57,7 @@ namespace FreeSql /// /// 返回类型 /// 选择列 + /// /// string ToSql(Expression, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex); /// diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 7e8f53f1..56855659 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -101,6 +101,7 @@ namespace FreeSql /// 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// + /// /// /// void ExecuteReader(Action> fetchHandler, string cmdText, object parms = null); @@ -109,6 +110,7 @@ namespace FreeSql /// /// 查询 /// + /// /// /// object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); @@ -127,6 +129,7 @@ namespace FreeSql /// /// 查询 /// + /// /// /// DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); @@ -145,6 +148,7 @@ namespace FreeSql /// /// 查询 /// + /// /// /// DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); @@ -227,6 +231,7 @@ namespace FreeSql /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) /// /// + /// /// /// /// @@ -239,6 +244,7 @@ namespace FreeSql /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// + /// /// /// /// @@ -274,6 +280,7 @@ namespace FreeSql /// Oracle: SELECT 1 FROM dual /// /// 命令超时设置(秒) + /// /// true: 成功, false: 失败 Task ExecuteConnectTestAsync(int commandTimeout = 0, CancellationToken cancellationToken = default); @@ -284,6 +291,7 @@ namespace FreeSql /// /// /// + /// Task ExecuteReaderAsync(Func, Task> readerHander, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); @@ -291,16 +299,20 @@ namespace FreeSql /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// + /// /// /// + /// Task ExecuteReaderAsync(Func, Task> readerHander, string cmdText, object parms = null, CancellationToken cancellationToken = default); Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null, CancellationToken cancellationToken = default); Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 查询 /// + /// /// /// + /// Task ExecuteArrayAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); @@ -310,6 +322,7 @@ namespace FreeSql /// /// /// + /// /// Task ExecuteArrayAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); @@ -317,8 +330,10 @@ namespace FreeSql /// /// 查询 /// + /// /// /// + /// Task ExecuteDataSetAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); @@ -328,6 +343,7 @@ namespace FreeSql /// /// /// + /// /// Task ExecuteDataSetAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); Task ExecuteDataSetAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); @@ -335,8 +351,10 @@ namespace FreeSql /// /// 查询 /// + /// /// /// + /// Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); @@ -346,6 +364,7 @@ namespace FreeSql /// /// /// + /// /// Task ExecuteDataTableAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); @@ -356,6 +375,7 @@ namespace FreeSql /// /// /// + /// Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); @@ -365,6 +385,7 @@ namespace FreeSql /// /// /// + /// /// Task ExecuteNonQueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); @@ -375,6 +396,7 @@ namespace FreeSql /// /// /// + /// Task ExecuteScalarAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); @@ -384,6 +406,7 @@ namespace FreeSql /// /// /// + /// /// Task ExecuteScalarAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); @@ -396,6 +419,7 @@ namespace FreeSql /// /// /// + /// /// Task> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); @@ -408,6 +432,7 @@ namespace FreeSql /// /// /// + /// /// Task> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); @@ -417,9 +442,11 @@ namespace FreeSql /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) /// /// + /// /// /// /// + /// /// Task, List>> QueryAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); @@ -429,8 +456,10 @@ namespace FreeSql /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// + /// /// /// + /// /// Task, List>> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); Task, List>> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 2ea6f90c..e728e02d 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -57,7 +57,7 @@ namespace FreeSql.Internal.CommonProvider MasterPool.Return(conn); var after = new Aop.TraceAfterEventArgs(before, "", ex); _util?._orm?.Aop.TraceAfterHandler?.Invoke(this, after); - throw ex; + throw; } if (_trans.ContainsKey(tid)) CommitTransaction(); _trans.TryAdd(tid, tran); @@ -122,7 +122,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { if (requireTran) RollbackTransaction(ex); - throw ex; + throw; } } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index bff2baa9..2ce2889e 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -119,7 +119,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 69eb0b82..e6530fd5 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -80,7 +80,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -102,7 +102,7 @@ namespace FreeSql.Internal.CommonProvider { if (string.IsNullOrEmpty(sql)) return this; if (++_whereTimes > 1) _where.Append(" AND "); - _where.Append("(").Append(sql).Append(")"); + _where.Append('(').Append(sql).Append(')'); if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); return this; } diff --git a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs index 64af2765..85073150 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProviderAsync.cs @@ -30,7 +30,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index 270dc44e..5c585114 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -254,7 +254,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -282,7 +282,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -308,7 +308,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -360,7 +360,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 2862a900..04cd04b2 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -269,7 +269,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -278,7 +278,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -350,7 +350,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -359,7 +359,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -429,7 +429,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -438,7 +438,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -464,7 +464,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -538,7 +538,7 @@ namespace FreeSql.Internal.CommonProvider { if (_source == null || _source.Any() == false) return null; var sb = new StringBuilder(); - sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("("); + sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append('('); var colidx = 0; foreach (var col in _table.Columns.Values) { @@ -582,7 +582,7 @@ namespace FreeSql.Internal.CommonProvider } ++colidx2; } - if (isValues) sb.Append(")"); + if (isValues) sb.Append(')'); onrow?.Invoke(d, didx, sb); ++didx; } diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index b1123aa7..828dba7d 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -76,7 +76,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -85,7 +85,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -157,7 +157,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -166,7 +166,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -236,7 +236,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -245,7 +245,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -270,7 +270,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index ca961a7f..954eb0fc 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -35,7 +35,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -72,7 +72,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -107,7 +107,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -175,7 +175,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -244,7 +244,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -291,7 +291,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -327,7 +327,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -741,7 +741,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -767,7 +767,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -817,7 +817,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -855,7 +855,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -892,7 +892,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -946,7 +946,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -983,7 +983,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -1040,7 +1040,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -1066,7 +1066,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index ef22fe9c..2f8aed58 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -215,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -224,7 +224,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -289,7 +289,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -298,7 +298,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -327,7 +327,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -555,7 +555,7 @@ namespace FreeSql.Internal.CommonProvider public IUpdate Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; - _where.Append(" AND (").Append(sql).Append(")"); + _where.Append(" AND (").Append(sql).Append(')'); if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); return this; } @@ -587,7 +587,7 @@ namespace FreeSql.Internal.CommonProvider { if (_source.Any() == false) return null; if (_table.ColumnsByCs.ContainsKey(CsName) == false) throw new Exception($"找不到 {CsName} 对应的列"); - if (thenValue == null) throw new ArgumentNullException("thenValue 参数不可为 null"); + if (thenValue == null) throw new ArgumentNullException(nameof(thenValue)); if (_source.Count == 0) return null; if (_source.Count == 1) @@ -626,7 +626,7 @@ namespace FreeSql.Internal.CommonProvider } cwsb.Append(" END"); if (nulls == _source.Count) sb.Append("NULL"); - else sb.Append(cwsb.ToString()); + else sb.Append(cwsb); cwsb.Clear(); return sb.ToString(); @@ -752,7 +752,7 @@ namespace FreeSql.Internal.CommonProvider else { ToSqlCaseWhenEnd(cwsb, col); - sb.Append(cwsb.ToString()); + sb.Append(cwsb); } cwsb.Clear(); } @@ -790,7 +790,7 @@ namespace FreeSql.Internal.CommonProvider if (_source.Any()) { if (_table.Primarys.Any() == false) throw new ArgumentException($"{_table.Type.DisplayCsharp()} 没有定义主键,无法使用 SetSource,请尝试 SetDto"); - sb.Append("(").Append(_commonUtils.WhereItems(_table, "", _source)).Append(")"); + sb.Append('(').Append(_commonUtils.WhereItems(_table, "", _source)).Append(')'); } if (_where.Length > 0) diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index 55599457..32e97a6c 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -72,7 +72,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -81,7 +81,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -145,7 +145,7 @@ namespace FreeSql.Internal.CommonProvider { _transaction.Rollback(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, "回滚", ex)); - throw ex; + throw; } _transaction = null; } @@ -154,7 +154,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -182,7 +182,7 @@ namespace FreeSql.Internal.CommonProvider catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 37963385..bc7e6f7b 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -14,6 +14,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using System.Xml; using System.Xml.XPath; @@ -297,7 +298,7 @@ namespace FreeSql.Internal foreach (var i in ie) { isAny = true; - if (ieidx > 0) sb.Append(","); + if (ieidx > 0) sb.Append(','); if (ieidx == 0) { var itype = i.GetType(); @@ -308,7 +309,7 @@ namespace FreeSql.Internal ++ieidx; } if (isAny == false) return ""; - sb.Append(")"); + sb.Append(')'); return sb.ToString(); } else if (dywhere is IEnumerable) @@ -361,7 +362,7 @@ namespace FreeSql.Internal var indt = its.Select(a => pk1.GetDbValue(a)).Where(a => a != null).ToArray(); if (indt.Any() == false) return null; if (indt.Length == 1) sbin.Append(" = ").Append(GetNoneParamaterSqlValue(null, null, pk1, pk1.Attribute.MapType, indt.First())); - else sbin.Append(" IN (").Append(string.Join(",", indt.Select(a => GetNoneParamaterSqlValue(null, null, pk1, pk1.Attribute.MapType, a)))).Append(")"); + else sbin.Append(" IN (").Append(string.Join(",", indt.Select(a => GetNoneParamaterSqlValue(null, null, pk1, pk1.Attribute.MapType, a)))).Append(')'); return sbin.ToString(); } var dicpk = its.Length > 5 ? new Dictionary() : null; @@ -377,7 +378,7 @@ namespace FreeSql.Internal { sb.Append(" OR ("); sb.Append(filter.Substring(5)); - sb.Append(")"); + sb.Append(')'); ++iidx; } if (dicpk != null) @@ -399,7 +400,7 @@ namespace FreeSql.Internal { sb.Append(" OR ("); sb.Append(fil.Key); - sb.Append(")"); + sb.Append(')'); } } return iidx == 1 ? sb.Remove(0, 5).Remove(sb.Length - 1, 1).ToString() : sb.Remove(0, 4).ToString(); @@ -447,6 +448,7 @@ namespace FreeSql.Internal } } + static int _CodeBaseNotSupportedException = 0; /// /// 通过属性的注释文本,通过 xml 读取 /// @@ -464,7 +466,17 @@ namespace FreeSql.Internal var xmlPath = regex.Replace(localType.Assembly.Location, ".xml"); if (File.Exists(xmlPath) == false) { - if (string.IsNullOrEmpty(localType.Assembly.CodeBase)) return null; + if (_CodeBaseNotSupportedException == 1) return null; + try + { + if (string.IsNullOrEmpty(localType.Assembly.CodeBase)) return null; + } + catch (NotSupportedException) //NotSupportedException: CodeBase is not supported on assemblies loaded from a single-file bundle. + { + Interlocked.Exchange(ref _CodeBaseNotSupportedException, 1); + return null; + } + xmlPath = regex.Replace(localType.Assembly.CodeBase, ".xml"); if (xmlPath.StartsWith("file:///") && Uri.TryCreate(xmlPath, UriKind.Absolute, out var tryuri)) xmlPath = tryuri.LocalPath; From 441309e0d079f6ced9511bb562702aee11e0b72e Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 23 Nov 2020 10:56:55 +0800 Subject: [PATCH 1015/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20pgsql=20?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=A0=91=E8=A7=A3=E6=9E=90=20hstore?= =?UTF-8?q?[""]=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostgreSQL/PostgreSQLExpression/OtherTest.cs | 3 ++- .../FreeSql.Provider.KingbaseES/KingbaseESExpression.cs | 3 ++- .../KingbaseES/OdbcKingbaseESExpression.cs | 3 ++- .../PostgreSQL/OdbcPostgreSQLExpression.cs | 5 +++-- .../FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs | 5 +++-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs index a70426b1..18dc637d 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -175,9 +175,10 @@ namespace FreeSql.Tests.PostgreSQLExpression [Fact] public void HStore() { - var sql1 = select.Where(a => a.testFieldHStore.ContainsKey("a")).ToList(); var sql2 = select.Where(a => a.testFieldHStore.ContainsKey("a") == false).ToList(); + + var sql3 = select.Where(a => a.testFieldHStore["a"] == "xxx").ToList(); } [Table(Name = "tb_alltype")] diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs index 1c174d31..1514da29 100644 --- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs @@ -118,11 +118,12 @@ namespace FreeSql.KingbaseES if (objType != null || objType.IsArrayOrList()) { string left = null; - if (objType.FullName == typeof(Dictionary).FullName) + if (objType == typeof(Dictionary)) { left = objExp == null ? null : getExp(objExp); switch (callExp.Method.Name) { + case "get_Item": return $"{left}->{getExp(callExp.Arguments[argIndex])}"; case "Contains": var right = getExp(callExp.Arguments[argIndex]); return $"({left} @> ({right}))"; diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index c9299d53..47adfaba 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -118,11 +118,12 @@ namespace FreeSql.Odbc.KingbaseES if (objType != null || objType.IsArrayOrList()) { string left = null; - if (objType.FullName == typeof(Dictionary).FullName) + if (objType == typeof(Dictionary)) { left = objExp == null ? null : getExp(objExp); switch (callExp.Method.Name) { + case "get_Item": return $"{left}->{getExp(callExp.Arguments[argIndex])}"; case "Contains": var right = getExp(callExp.Arguments[argIndex]); return $"({left} @> ({right}))"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index fb932479..be0a6e73 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -118,11 +118,12 @@ namespace FreeSql.Odbc.PostgreSQL if (objType != null || objType.IsArrayOrList()) { string left = null; - if (objType.FullName == typeof(Dictionary).FullName) + if (objType == typeof(Dictionary)) { left = objExp == null ? null : getExp(objExp); switch (callExp.Method.Name) { + case "get_Item": return $"{left}->{getExp(callExp.Arguments[argIndex])}"; case "Contains": var right = getExp(callExp.Arguments[argIndex]); return $"({left} @> ({right}))"; @@ -206,7 +207,7 @@ namespace FreeSql.Odbc.PostgreSQL } break; } - if (memParentExp.FullName == typeof(Dictionary).FullName) + if (memParentExp == typeof(Dictionary)) { var left = getExp(memExp.Expression); switch (memExp.Member.Name) diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index d2524cb4..d536881e 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -149,11 +149,12 @@ namespace FreeSql.PostgreSQL } break; } - if (objType.FullName == typeof(Dictionary).FullName) + if (objType == typeof(Dictionary)) { left = objExp == null ? null : getExp(objExp); switch (callExp.Method.Name) { + case "get_Item": return $"{left}->{getExp(callExp.Arguments[argIndex])}"; case "Contains": var right = getExp(callExp.Arguments[argIndex]); return $"({left} @> ({right}))"; @@ -237,7 +238,7 @@ namespace FreeSql.PostgreSQL } break; } - if (memParentExp.FullName == typeof(Dictionary).FullName) + if (memParentExp == typeof(Dictionary)) { var left = getExp(memExp.Expression); switch (memExp.Member.Name) From fd99eccd29d00f23707fa0c8f479a00b84e0a739 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 23 Nov 2020 10:58:35 +0800 Subject: [PATCH 1016/1029] v2.0.0-preview1123 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj | 2 +- Extensions/FreeSql.Generator/FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- .../FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj | 2 +- Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 79fe9b00..5b36dc68 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 4d688e99..b7125dc9 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index b076f78e..5c4b7a2a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index cbe0915a..ff211022 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 296c6e6c..6750bdf5 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1122 + 2.0.0-preview1123 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 8e043fb0..7f13d581 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 48305a07..0420d521 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index beabc1f8..4d491583 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 173c87bd..b522aa2c 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 691659a3..1b756bae 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index c7f29620..8ea23f14 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index b64f9da4..b72d9898 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 838a98a8..7face202 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index bd9126f8..0c9c04a7 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index bae4b425..a24f6cb2 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index a1b814f1..c2181e42 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 6b81ee39..552fd353 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index c4aae049..b1d76a78 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index ef2385fd..4d3802df 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 3b01d818..4fd3a441 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 508b0c53..6f1cc0d0 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 6c4cac03..3b3ea1bc 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1122 + 2.0.0-preview1123 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 3b9b10fd2fd68d60b740a34f55c0e3e40b7b609c Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 23 Nov 2020 11:23:51 +0800 Subject: [PATCH 1017/1029] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20FreeSql.Gene?= =?UTF-8?q?rator=20=E5=A4=84=E7=90=86=20SqlServer=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Generator/RazorModel.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 40009156..6ce2502b 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -217,8 +217,9 @@ public class RazorModel { else if (defval.StartsWith("('") && defval.EndsWith("')")) defval = defval.Substring(2, defval.Length - 4).Replace("''", "'"); else if (defval.StartsWith("(") && defval.EndsWith(")")) defval = defval.Substring(1, defval.Length - 2); else return null; + if (defval.StartsWith("N'") && defval.EndsWith("'")) defval = defval.Substring(1); } - else if ((cstype == typeof(string) && defval.StartsWith("'") && defval.EndsWith("'::character varying") || + if ((cstype == typeof(string) && defval.StartsWith("'") && defval.EndsWith("'::character varying") || cstype == typeof(Guid) && defval.StartsWith("'") && defval.EndsWith("'::uuid") ) && (fsql.Ado.DataType == DataType.PostgreSQL || fsql.Ado.DataType == DataType.OdbcPostgreSQL || fsql.Ado.DataType == DataType.KingbaseES || fsql.Ado.DataType == DataType.OdbcKingbaseES || From d2d3870de0162590d5338330712030898b9de1f4 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 23 Nov 2020 16:23:42 +0800 Subject: [PATCH 1018/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=88=86?= =?UTF-8?q?=E9=A1=B5=20Page(..).Count()=20=E9=A1=BA=E5=BA=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommonProvider/SelectProvider/Select0Provider.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 0e69ee7f..1b230ff2 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -696,7 +696,11 @@ namespace FreeSql.Internal.CommonProvider public long Count() { var tmpOrderBy = _orderby; + var tmpSkip = _skip; + var tmpLimit = _limit; _orderby = null; //解决 select count(1) from t order by id 这样的 SQL 错误 + _skip = 0; + _limit = 0; try { return this.ToList($"count(1){_commonUtils.FieldAsAlias("as1")}").Sum(); //这里的 Sum 为了分表查询 @@ -704,6 +708,8 @@ namespace FreeSql.Internal.CommonProvider finally { _orderby = tmpOrderBy; + _skip = tmpSkip; + _limit = tmpLimit; } } public TSelect Count(out long count) @@ -733,7 +739,11 @@ namespace FreeSql.Internal.CommonProvider async public Task CountAsync(CancellationToken cancellationToken = default) { var tmpOrderBy = _orderby; + var tmpSkip = _skip; + var tmpLimit = _limit; _orderby = null; + _skip = 0; + _limit = 0; try { return (await this.ToListAsync($"count(1){_commonUtils.FieldAsAlias("as1")}", cancellationToken)).Sum(); //这里的 Sum 为了分表查询 @@ -741,6 +751,8 @@ namespace FreeSql.Internal.CommonProvider finally { _orderby = tmpOrderBy; + _skip = tmpSkip; + _limit = tmpLimit; } } public virtual Task> ToListAsync(bool includeNestedMembers = false, CancellationToken cancellationToken = default) From 4b875eaf7c897b86bdbeac3309f95bb8e9c58eda Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 23 Nov 2020 22:12:18 +0800 Subject: [PATCH 1019/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=20IsIgnore=20=E5=A4=84=E7=90=86=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/AppSetting.cs | 946 ++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 366 +++++++ FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 17 +- FreeSql/Internal/UtilsExpressionTree.cs | 13 + 4 files changed, 1341 insertions(+), 1 deletion(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/AppSetting.cs diff --git a/FreeSql.Tests/FreeSql.Tests/AppSetting.cs b/FreeSql.Tests/FreeSql.Tests/AppSetting.cs new file mode 100644 index 00000000..bd82b2d1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/AppSetting.cs @@ -0,0 +1,946 @@ +using System; +using System.Diagnostics; +using System.Runtime.Serialization.Formatters.Binary; +using System.IO; +using System.ComponentModel; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Newtonsoft.Json; +using System.Runtime.Serialization.Json; +using System.Threading.Tasks; +using FreeSql.DataAnnotations; + +namespace AME.Helpers +{ + + + + #region COREIDS + + public class COREIDS : INotifyPropertyChanged + { + #region INotifyPropertyChanged + protected bool SetProperty(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null, bool force = false) + { + if (!force && EqualityComparer.Default.Equals(backingStore, value)) + return false; + + backingStore = value; + onChanged?.Invoke(); + OnPropertyChanged(propertyName); + return true; + } + + + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged([CallerMemberName] string propertyName = "") + { + var changed = PropertyChanged; + if (changed == null) + return; + + changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + #endregion + string name; + public string Name { get => name; set => SetProperty(ref name, value); } + string coreid; + public string COREID { get => coreid; set => SetProperty(ref coreid, value); } + int syncprice = 1; + public int SyncPrice { get => syncprice; set => SetProperty(ref syncprice, value); } + bool syncProductName = true; + public bool SyncProductName { get => syncProductName; set => SetProperty(ref syncProductName, value); } + } + public class FTPs : INotifyPropertyChanged + { + #region INotifyPropertyChanged + protected bool SetProperty(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null, bool force = false) + { + if (!force && EqualityComparer.Default.Equals(backingStore, value)) + return false; + + backingStore = value; + onChanged?.Invoke(); + OnPropertyChanged(propertyName); + return true; + } + + + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged([CallerMemberName] string propertyName = "") + { + var changed = PropertyChanged; + if (changed == null) + return; + + changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + #endregion + string name; + public string Name { get => name; set => SetProperty(ref name, value); } + string hostName; + public string HostName { get => hostName; set => SetProperty(ref hostName, value); } + int port = 21; + public int Port { get => port; set => SetProperty(ref port, value); } + string username; + public string Username { get => username; set => SetProperty(ref username, value); } + string password; + public string Password { get => password; set => SetProperty(ref password, value); } + string token; + public string Token { get => token; set => SetProperty(ref token, value); } + bool autoSend; + public bool AutoSend { get => autoSend; set => SetProperty(ref autoSend, value); } + } + public class COREIDS_Sync : INotifyPropertyChanged + { + #region INotifyPropertyChanged + protected bool SetProperty(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null, bool force = false) + { + if (!force && EqualityComparer.Default.Equals(backingStore, value)) + return false; + + backingStore = value; + onChanged?.Invoke(); + OnPropertyChanged(propertyName); + return true; + } + + + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged([CallerMemberName] string propertyName = "") + { + var changed = PropertyChanged; + if (changed == null) + return; + + changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + #endregion + string name; + public string Name { get => name; set => SetProperty(ref name, value); } + string coreid; + public string COREID { get => coreid; set => SetProperty(ref coreid, value); } + string status; + public string Status { get => status; set => SetProperty(ref status, value); } + bool doit; + public bool Doit { get => doit; set => SetProperty(ref doit, value); } + string info; + public string Info { get => info; set => SetProperty(ref info, value); } + public bool SyncCategories { get; set; } = true; + public bool SyncSuppliers { get; set; } = true; + public bool SyncPricePurchase { get; set; } = true; + public int SyncPrice { get; set; } = 1; + public bool SyncProductName { get; set; } = true; + } + #endregion + + + public class AppSettingII : INotifyPropertyChanged + { + #region INotifyPropertyChanged + protected bool SetProperty(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null, bool force = false) + { + if (!force && EqualityComparer.Default.Equals(backingStore, value)) + return false; + + backingStore = value; + onChanged?.Invoke(); + OnPropertyChanged(propertyName); + return true; + } + + + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged([CallerMemberName] string propertyName = "") + { + var changed = PropertyChanged; + if (changed == null) + return; + + changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + #endregion + + + [JsonProperty, Column(IsPrimary = true, IsIdentity = true)] + public int ID { get; set; } + + /// + /// 配置名称 + /// + [DisplayName("配置名称")] + public string SettingName { get; set; } + + /// + /// 配置文件路径 + /// + [JsonIgnore] + [DisplayName("配置文件路径")] + public string FilePath { get; set; } + + #region WPF + private bool _ConsoleWrite; + public bool ConsoleWrite { get => _ConsoleWrite; set { if (SetProperty(ref _ConsoleWrite, value)) SaveAI(); } } + + + private int _DebugLevel; + public int DebugLevel { get => _DebugLevel; set { if (SetProperty(ref _DebugLevel, value)) SaveAI(); } } + + + private int _DebugOutput; + public int DebugOutput { get => _DebugOutput; set { if (SetProperty(ref _DebugOutput, value)) SaveAI(); } } + + private string _cfgs; + public string cfgs { get => _cfgs; set { if (SetProperty(ref _cfgs, value)) SaveAI(); } } + + private bool autoStartPrintServer; + public bool AutoStartPrintServer { get => autoStartPrintServer; set { if (SetProperty(ref autoStartPrintServer, value)) SaveAI(); } } + + private bool pdf; + public bool PDF { get => pdf; set { if (SetProperty(ref pdf, value)) SaveAI(); } } + + private bool _isdebug; + public bool isdebug { get => _isdebug; set { if (SetProperty(ref _isdebug, value)) SaveAI(); } } + + bool isDark = false; + public bool IsDark { get => isDark; set { if (SetProperty(ref isDark, value)) SaveAI(); } } + + string mainWindowMax = "Maximized"; + public string MainWindowMax { get => mainWindowMax; set { if (SetProperty(ref mainWindowMax, value)) SaveAI(); } } + + string myFontFamily = "幼圆"; + public string MyFontFamily { get => myFontFamily; set { if (SetProperty(ref myFontFamily, value)) SaveAI(); } } + + int myfontsize = 13; + public int Myfontsize { get => myfontsize; set { if (SetProperty(ref myfontsize, value)) SaveAI(); } } + + //public List WindowState = new List { "Maximized", "Normal", "Minimized" }; + + string cif; + public string Cif { get => cif; set { if (SetProperty(ref cif, value)) SaveAI(); } } + + string hddid; + public string Hddid { get => hddid; set { if (SetProperty(ref hddid, value)) SaveAI(); } } + + string regkey; + public string Regkey { get => regkey; set { if (SetProperty(ref regkey, value)) SaveAI(); } } + + bool loadAllProduct = false; + public bool LoadAllProduct { get => loadAllProduct; set { if (SetProperty(ref loadAllProduct, value)) SaveAI(); } } + + bool autoDownloadPhoto = false; + public bool AutoDownloadPhoto { get => autoDownloadPhoto; set { if (SetProperty(ref autoDownloadPhoto, value)) SaveAI(); } } + + int ver; + public int VER { get => ver; set { if (SetProperty(ref ver, value)) SaveAI(); } } + #endregion + + //同步app第一版设置 + #region app第一版设置 + string printerIP = "192.168.1.232"; + public string PrinterIP { get => printerIP; set { if (SetProperty(ref printerIP, value)) SaveAI(); } } + + string dsid = "demo"; + public string DSID { get => dsid; set { if (SetProperty(ref dsid, value)) { dsid = dsid.ToLower(); SaveAI(); } } } + + public string localuuid { get; set; } + public string DSIDsin { get => (string.IsNullOrEmpty(localuuid) ? "" : localuuid + "_") + DSID.Replace(":", "").Replace(",", "").Replace(".", "").Replace("*", ""); } + + string dsuser = "t9"; + public string DSUser { get => dsuser; set { if (SetProperty(ref dsuser, value)) SaveAI(); } } + + string dspassword = "0"; + public string DSPassword { get => dspassword; set { if (SetProperty(ref dspassword, value)) SaveAI(); } } + + string syncTime; + public string SyncTime { get => syncTime; set { if (SetProperty(ref syncTime, value)) SaveAI(); } } + + string uuid; + public string UUID { get => uuid; set { if (SetProperty(ref uuid, value)) SaveAI(); } } + + bool isLocalDB = false; + public bool IsLocalDB { get => isLocalDB; set { if (SetProperty(ref isLocalDB, value)) SaveAI(); } } + + string ip = "192.168.1.100"; + public string IP { get => ip; set { if (SetProperty(ref ip, value)) SaveAI(); } } + + string port = "1200"; + public string PORT { get => port; set { if (SetProperty(ref port, value)) SaveAI(); } } + + bool autologin = false; + public bool Autologin + { + get => autologin; set + { + if (SetProperty(ref autologin, value)) + { + if (!value) DSPassword = ""; + SaveAI(); + } + } + } + + bool printA4_2 = false; + public bool PrintA4_2 { get => printA4_2; set { if (SetProperty(ref printA4_2, value)) SaveAI(); } } + + bool printA4_3 = false; + public bool PrintA4_3 { get => printA4_3; set { if (SetProperty(ref printA4_3, value)) SaveAI(); } } + + string cOREID; + public string COREID { get => cOREID; set { if (SetProperty(ref cOREID, value)) SaveAI(); } } + + bool useCache = false; + public bool UseCache { get => useCache; set { if (SetProperty(ref useCache, value)) SaveAI(); } } + + string cachePath; + public string CachePath { get => cachePath; set { if (SetProperty(ref cachePath, value)) SaveAI(); } } + + public Guid GUID { get; set; } = Guid.NewGuid(); + + bool productsShowPhoto = true; + public bool ProductsShowPhoto { get => productsShowPhoto; set { if (SetProperty(ref productsShowPhoto, value)) SaveAI(); } } + + bool productsSelectKeepShow = false; + public bool ProductsSelectKeepShow { get => productsSelectKeepShow; set { if (SetProperty(ref productsSelectKeepShow, value)) SaveAI(); } } + + COREIDS[] coreIDs = new COREIDS[] { + new COREIDS { Name = "1" }, + new COREIDS { Name = "2" }, + new COREIDS { Name = "3" }, + new COREIDS { Name = "4" }, + new COREIDS { Name = "5" }, + new COREIDS { Name = "6" }}; + [JsonProperty, Column(IsIgnore = true)] + public COREIDS[] COREIDS { get => coreIDs; set { if (SetProperty(ref coreIDs, value)) SaveAI(); } } + + #endregion + + #region 销售窗体设置 + string orderDetailsWindowMax = "Maximized"; + public string OrderDetailsWindowMax { get => orderDetailsWindowMax; set { if (SetProperty(ref orderDetailsWindowMax, value)) SaveAI(); } } + + bool orderDetailsShowMore = false; + public bool OrderDetailsShowMore { get => orderDetailsShowMore; set { if (SetProperty(ref orderDetailsShowMore, value)) SaveAI(); } } + + bool orderDetailsShowDetailsCard = true; + public bool OrderDetailsShowDetailsCard { get => orderDetailsShowDetailsCard; set { if (SetProperty(ref orderDetailsShowDetailsCard, value)) SaveAI(); } } + + bool orderDetailsShowCategories = false; + public bool OrderDetailsShowCategories { get => orderDetailsShowCategories; set { if (SetProperty(ref orderDetailsShowCategories, value)) SaveAI(); } } + + bool orderDetailsShowSuppliers = false; + public bool OrderDetailsShowSuppliers { get => orderDetailsShowSuppliers; set { if (SetProperty(ref orderDetailsShowSuppliers, value)) SaveAI(); } } + + int orderDetailsImagePreviewWidth = 30; + public int OrderDetailsImagePreviewWidth { get => orderDetailsImagePreviewWidth; set { if (SetProperty(ref orderDetailsImagePreviewWidth, value)) SaveAI(); } } + #endregion + + #region 商品窗体设置 + /// + /// 管理:商品库存过滤 + /// + bool filterStock = false; + public bool FilterStock { get => filterStock; set { if (SetProperty(ref filterStock, value)) SaveAI(); } } + + string productsWindowMax = "Maximized"; + public string ProductsWindowMax { get => productsWindowMax; set { if (SetProperty(ref productsWindowMax, value)) SaveAI(); } } + + bool productsShowMore = false; + public bool ProductsShowMore { get => productsShowMore; set { if (SetProperty(ref productsShowMore, value)) SaveAI(); } } + + bool productsShowDetailsCard = true; + public bool ProductsShowDetailsCard { get => productsShowDetailsCard; set { if (SetProperty(ref productsShowDetailsCard, value)) SaveAI(); } } + + bool productsShowCategories = false; + public bool ProductsShowCategories { get => productsShowCategories; set { if (SetProperty(ref productsShowCategories, value)) SaveAI(); } } + + bool productsShowSuppliers = false; + public bool ProductsShowSuppliers { get => productsShowSuppliers; set { if (SetProperty(ref productsShowSuppliers, value)) SaveAI(); } } + + int productImagePreviewWidth = 30; + public int ProductImagePreviewWidth { get => productImagePreviewWidth; set { if (SetProperty(ref productImagePreviewWidth, value)) SaveAI(); } } + #endregion + + #region 类别窗体设置 + string categoriesWindowMax = "Maximized"; + public string CategoriesWindowMax { get => categoriesWindowMax; set { if (SetProperty(ref categoriesWindowMax, value)) SaveAI(); } } + + bool showCategories2 = false; + public bool ShowCategories2 { get => showCategories2; set { if (SetProperty(ref showCategories2, value)) SaveAI(); } } + + bool categoriesShowMore = false; + public bool CategoriesShowMore { get => categoriesShowMore; set { if (SetProperty(ref categoriesShowMore, value)) SaveAI(); } } + + bool categoriesShowDetailsCard = true; + public bool CategoriesShowDetailsCard { get => categoriesShowDetailsCard; set { if (SetProperty(ref categoriesShowDetailsCard, value)) SaveAI(); } } + + int categoriesImagePreviewWidth = 30; + public int CategoriesImagePreviewWidth { get => categoriesImagePreviewWidth; set { if (SetProperty(ref categoriesImagePreviewWidth, value)) SaveAI(); } } + + bool ignoreSecondLevelCategories; + public bool IgnoreSecondLevelCategories { get => ignoreSecondLevelCategories; set { if (SetProperty(ref ignoreSecondLevelCategories, value)) SaveAI(); } } + #endregion + + #region 客户窗体设置 + string customersWindowMax = "Maximized"; + public string CustomersWindowMax { get => customersWindowMax; set { if (SetProperty(ref customersWindowMax, value)) SaveAI(); } } + + bool customersShowMore = false; + public bool CustomersShowMore { get => customersShowMore; set { if (SetProperty(ref customersShowMore, value)) SaveAI(); } } + + bool customersShowDetailsCard = true; + public bool CustomersShowDetailsCard { get => customersShowDetailsCard; set { if (SetProperty(ref customersShowDetailsCard, value)) SaveAI(); } } + + int customersImagePreviewWidth = 30; + public int CustomersImagePreviewWidth { get => customersImagePreviewWidth; set { if (SetProperty(ref customersImagePreviewWidth, value)) SaveAI(); } } + #endregion + + #region 供应商窗体设置 + string suppliersWindowMax = "Maximized"; + public string SuppliersWindowMax { get => suppliersWindowMax; set { if (SetProperty(ref suppliersWindowMax, value)) SaveAI(); } } + + bool suppliersShowMore = false; + public bool SuppliersShowMore { get => suppliersShowMore; set { if (SetProperty(ref suppliersShowMore, value)) SaveAI(); } } + + bool suppliersShowDetailsCard = true; + public bool SuppliersShowDetailsCard { get => suppliersShowDetailsCard; set { if (SetProperty(ref suppliersShowDetailsCard, value)) SaveAI(); } } + + int suppliersImagePreviewWidth = 30; + public int SuppliersImagePreviewWidth { get => suppliersImagePreviewWidth; set { if (SetProperty(ref suppliersImagePreviewWidth, value)) SaveAI(); } } + #endregion + + #region 用户窗体设置 + string usersWindowMax = "Maximized"; + public string UsersWindowMax { get => usersWindowMax; set { if (SetProperty(ref usersWindowMax, value)) SaveAI(); } } + + bool usersShowMore = false; + public bool UsersShowMore { get => usersShowMore; set { if (SetProperty(ref usersShowMore, value)) SaveAI(); } } + + bool usersShowDetailsCard = true; + public bool UsersShowDetailsCard { get => usersShowDetailsCard; set { if (SetProperty(ref usersShowDetailsCard, value)) SaveAI(); } } + + int usersImagePreviewWidth = 30; + public int UsersImagePreviewWidth { get => usersImagePreviewWidth; set { if (SetProperty(ref usersImagePreviewWidth, value)) SaveAI(); } } + #endregion + + #region 图片窗体设置 + string photosWindowMax = "Maximized"; + public string PhotosWindowMax { get => photosWindowMax; set { if (SetProperty(ref photosWindowMax, value)) SaveAI(); } } + + int photosImagePreviewWidth = 30; + public int PhotosImagePreviewWidth { get => photosImagePreviewWidth; set { if (SetProperty(ref photosImagePreviewWidth, value)) SaveAI(); } } + #endregion + + #region 单据列表窗体设置 + string orderListWindowMax = "Maximized"; + public string OrderListWindowMax { get => orderListWindowMax; set { if (SetProperty(ref orderListWindowMax, value)) SaveAI(); } } + + bool orderListShowMore = false; + public bool OrderListShowMore { get => orderListShowMore; set { if (SetProperty(ref orderListShowMore, value)) SaveAI(); } } + + bool orderListShowDetailsCard = true; + public bool OrderListShowDetailsCard { get => orderListShowDetailsCard; set { if (SetProperty(ref orderListShowDetailsCard, value)) SaveAI(); } } + #endregion + + #region 小程序/VIP客户 + string miniOrderDetailsOrderBy = "BarCode"; + public string MiniOrderDetailsOrderBy { get => miniOrderDetailsOrderBy; set { if (SetProperty(ref miniOrderDetailsOrderBy, value)) SaveAI(); } } + bool miniOrderDetailsShowBarcode; + public bool MiniOrderDetailsShowBarcode { get => miniOrderDetailsShowBarcode; set { if (SetProperty(ref miniOrderDetailsShowBarcode, value)) SaveAI(); } } + + /// + /// 销售:商品库存过滤 + /// + bool filterStockVIP = false; + public bool FilterStockVIP { get => filterStockVIP; set { if (SetProperty(ref filterStockVIP, value)) SaveAI(); } } + + /// + /// 销售:商品状态过滤 + /// + bool filterStatusVIP = false; + public bool FilterStatusVIP { get => filterStatusVIP; set { if (SetProperty(ref filterStatusVIP, value)) SaveAI(); } } + + /// + /// 销售:商品状态过滤字符串形式 + /// + string filterStatusVIPstr; + public string FilterStatusVIPstr { get => filterStatusVIPstr; set { if (SetProperty(ref filterStatusVIPstr, value)) SaveAI(); } } + + bool forceOneNewOrder = false; + public bool ForceOneNewOrder { get => forceOneNewOrder; set { if (SetProperty(ref forceOneNewOrder, value)) SaveAI(); } } + + bool inputNumber2 = false; + public bool InputNumber2 { get => inputNumber2; set { if (SetProperty(ref inputNumber2, value)) SaveAI(); } } + + /// + /// 销售父类排序 + /// + string categories2OrderBy; + public string Categories2OrderBy { get => categories2OrderBy; set { if (SetProperty(ref categories2OrderBy, value)) SaveAI(); } } + + /// + /// 销售类别排序 + /// + string categoriesOrderBy = "CategoryID"; + public string CategoriesOrderBy { get => categoriesOrderBy; set { if (SetProperty(ref categoriesOrderBy, value)) SaveAI(); } } + + /// + /// 销售商品排序 + /// + string productOrderBy; + public string ProductOrderBy { get => productOrderBy; set { if (SetProperty(ref productOrderBy, value)) SaveAI(); } } + + + /// + /// 自定义首页 + /// + string vipIndex; + public string VipIndex { get => vipIndex; set { if (SetProperty(ref vipIndex, value)) SaveAI(); } } + + /// + /// 用户资料锁定 + /// + bool lockVIPDatas = false; + public bool LockVIPDatas { get => lockVIPDatas; set { if (SetProperty(ref lockVIPDatas, value)) SaveAI(); } } + + /// + /// 禁止单位[件] + /// + bool disabledOrderSingleQuantity; + public bool DisabledOrderSingleQuantity { get => disabledOrderSingleQuantity; set { if (SetProperty(ref disabledOrderSingleQuantity, value)) SaveAI(); } } + + /// + /// 指定游客账号ID + /// + string guestID; + public string GuestID { get => guestID; set { if (SetProperty(ref guestID, value)) SaveAI(); } } + + /// + /// 默认注册email后缀 + /// + string email; + public string Email { get => email; set { if (SetProperty(ref email, value)) SaveAI(); } } + + /// + /// 默认Code + /// + string code; + [DisplayName("默认Code")] + public string Code { get => code; set { if (SetProperty(ref code, value)) SaveAI(); } } + + /// + /// 配货单列表排序 + /// + string pickupListOrderBy = "PostalCode,OrderID"; + public string PickupListOrderBy { get => pickupListOrderBy; set { if (SetProperty(ref pickupListOrderBy, value)) SaveAI(); } } + + /// + /// 配货单据排序 + /// + string pickupOrderBy = "BarCode"; + public string PickupOrderBy { get => pickupOrderBy; set { if (SetProperty(ref pickupOrderBy, value)) SaveAI(); } } + + /// + /// 使用紧凑型左类别条 + /// + bool useLiteCategoriesBar; + public bool UseLiteCategoriesBar { get => useLiteCategoriesBar; set { if (SetProperty(ref useLiteCategoriesBar, value)) SaveAI(); } } + + #endregion + + #region 日志 + string nlog_All; + public string Nlog_All { get => nlog_All; set { if (SetProperty(ref nlog_All, value)) SaveAI(); } } + string nlog_warn; + public string Nlog_warn { get => nlog_warn; set { if (SetProperty(ref nlog_warn, value)) SaveAI(); } } + #endregion + + #region 新加配置 + string urlPhoto; + public string UrlPhoto { get => urlPhoto; set { if (SetProperty(ref urlPhoto, value)) SaveAI(); } } + string unsyncPriceTag; + public string UnsyncPriceTag { get => unsyncPriceTag; set { if (SetProperty(ref unsyncPriceTag, value)) SaveAI(); } } + bool syncPricePurchase = true; + public bool SyncPricePurchase { get => syncPricePurchase; set { if (SetProperty(ref syncPricePurchase, value)) SaveAI(); } } + bool syncStatus; + public bool SyncStatus { get => syncStatus; set { if (SetProperty(ref syncStatus, value)) SaveAI(); } } + + /// + /// 旧版app图片路径,用于导入 + /// + string appPhotoUrl; + public string AppPhotoUrl { get => appPhotoUrl; set { if (SetProperty(ref appPhotoUrl, value)) SaveAI(); } } + + /// + /// 显示APP面板 + /// + bool showAppPanel; + public bool ShowAppPanel { get => showAppPanel; set { if (SetProperty(ref showAppPanel, value)) SaveAI(); } } + + bool autoUsercode; + public bool AutoUsercode { get => autoUsercode; set { if (SetProperty(ref autoUsercode, value)) SaveAI(); } } + + + /// + /// H5的Url + /// + string h5url = "https://menu.freepos.es/"; + public string H5url { get => h5url; set { if (SetProperty(ref h5url, value)) SaveAI(); } } + bool loadH5url; + public bool LoadH5url { get => loadH5url; set { if (SetProperty(ref loadH5url, value)) SaveAI(); } } + + /// + /// 监控输出SQL语句 + /// + bool useMonitorCommand; + public bool UseMonitorCommand { get => useMonitorCommand; set { if (SetProperty(ref useMonitorCommand, value)) SaveAI(); } } + + + #region Winform版设置 + + bool productEditor20; + public bool ProductEditor20 { get => productEditor20; set { if (SetProperty(ref productEditor20, value)) SaveAI(); } } + /// + /// 打开内测功能 + /// + bool enableBataFunction; + public bool EnableBataFunction { get => enableBataFunction; set { if (SetProperty(ref enableBataFunction, value)) SaveAI(); } } + + /// + /// 类别供应商显示序号 + /// + bool categoriesDisplayID = true; + public bool CategoriesDisplayID { get => categoriesDisplayID; set { if (SetProperty(ref categoriesDisplayID, value)) SaveAI(); } } + + /// + /// 导入单据过滤数量0的行 + /// + bool importOrderSkipQuantityZero; + public bool ImportOrderSkipQuantityZero { get => importOrderSkipQuantityZero; set { if (SetProperty(ref importOrderSkipQuantityZero, value)) SaveAI(); } } + + /// + /// 导入单据过滤库存0的行 + /// + bool importOrderSkipStockZero; + public bool ImportOrderSkipStockZero { get => importOrderSkipStockZero; set { if (SetProperty(ref importOrderSkipStockZero, value)) SaveAI(); } } + + /// + /// 打印通道3重定向到小票 + /// + bool printA4_3_to_Ticket; + public bool PrintA4_3_to_Ticket { get => printA4_3_to_Ticket; set { if (SetProperty(ref printA4_3_to_Ticket, value)) SaveAI(); } } + + /// + /// 精度计算:使用格式化2位后再累加 + /// + bool taxDetalisCalculationAccuracyMethod2 = true; + public bool TaxDetalisCalculationAccuracyMethod2 { get => taxDetalisCalculationAccuracyMethod2; set { if (SetProperty(ref taxDetalisCalculationAccuracyMethod2, value)) SaveAI(); } } + + /// + /// 测试功能:强制同步类别ID,供应商ID, 用于误删除商品表恢复数据 + /// + bool forceSyncCategoryIDSupplierID; + public bool ForceSyncCategoryIDSupplierID { get => forceSyncCategoryIDSupplierID; set { if (SetProperty(ref forceSyncCategoryIDSupplierID, value)) SaveAI(); } } + + /// + /// 使用极速版 + /// + bool useORM = true; + public bool UseORM { get => useORM; set { if (SetProperty(ref useORM, value)) SaveAI(); } } + + /// + /// 使用多发票序列 + /// + bool useMoreFacturaSeriel; + public bool UseMoreFacturaSeriel { get => useMoreFacturaSeriel; set { if (SetProperty(ref useMoreFacturaSeriel, value)) SaveAI(); } } + + /// + /// 显示独立结账提示窗体 + /// + bool useExCheckOutDSP; + public bool UseExCheckOutDSP { get => useExCheckOutDSP; set { if (SetProperty(ref useExCheckOutDSP, value)) SaveAI(); } } + + /// + /// 结账前提示输入邮编 + /// + bool analysisOrderPostcode; + public bool AnalysisOrderPostcode { get => analysisOrderPostcode; set { if (SetProperty(ref analysisOrderPostcode, value)) SaveAI(); } } + + /// + /// 只读的单元格显示大字体 + /// + bool cellReadonlyToGreen; + public bool CellReadonlyToGreen { get => cellReadonlyToGreen; set { if (SetProperty(ref cellReadonlyToGreen, value)) SaveAI(); } } + + /// + /// 接口历史文件地址 + /// + string[] interfacePath = new string[] { "", "", "", "", "", "", "", "", "", "" }; + public string[] InterfacePath { get => interfacePath; set { if (SetProperty(ref interfacePath, value)) SaveAI(); } } + + /// + /// 客户评级 + /// + bool customerStar; + public bool CustomerStar { get => customerStar; set { if (SetProperty(ref customerStar, value)) SaveAI(); } } + + /// + /// 客户供应商删除限制 + /// + bool customerDisableDel = true; + public bool CustomerDisableDel { get => customerDisableDel; set { if (SetProperty(ref customerDisableDel, value)) SaveAI(); } } + + /// + /// 导出资料自动传送 + /// + bool autoSend; + public bool AutoSend { get => autoSend; set { if (SetProperty(ref autoSend, value)) SaveAI(); } } + + /// + /// FTP资料 + /// + FTPs[] _FTPs = new FTPs[] { + new FTPs { Name = "1.Directialogistica" }, + new FTPs { Name = "2.Saveb2b" }, + new FTPs { Name = "3" }, + new FTPs { Name = "4" }, + new FTPs { Name = "5" }, + new FTPs { Name = "6" }}; + [JsonProperty, Column(IsIgnore = true)] + public FTPs[] FTPs { get => _FTPs; set { if (SetProperty(ref _FTPs, value)) SaveAI(); } } + + /// + /// 导出单据使用名称替换条码 + /// + bool expOrderWithName; + public bool ExpOrderWithName { get => expOrderWithName; set { if (SetProperty(ref expOrderWithName, value)) SaveAI(); } } + + /// + /// 预热数据连接 + /// + bool warmupDataConnection; + public bool WarmupDataConnection { get => warmupDataConnection; set { if (SetProperty(ref warmupDataConnection, value)) SaveAI(); } } + + /// + /// 销售单内部查找包含名称模糊查找 + /// + bool orderSearchIncName; + public bool OrderSearchIncName { get => orderSearchIncName; set { if (SetProperty(ref orderSearchIncName, value)) SaveAI(); } } + + /// + /// 销售单商品重复提示 + /// + bool orderItemDuplicateReminder; + public bool OrderItemDuplicateReminder { get => orderItemDuplicateReminder; set { if (SetProperty(ref orderItemDuplicateReminder, value)) SaveAI(); } } + + /// + /// VP过滤VO单据 + /// + bool vPfiltersVO; + public bool VPfiltersVO { get => vPfiltersVO; set { if (SetProperty(ref vPfiltersVO, value)) SaveAI(); } } + + /// + /// VP过滤VO单据并过滤金额 + /// + bool vPfiltersVOwithAmount; + public bool VPfiltersVOwithAmount { get => vPfiltersVOwithAmount; set { if (SetProperty(ref vPfiltersVOwithAmount, value)) SaveAI(); } } + + /// + /// 导出单据附加发票号码到备注 + /// + bool expOrderWithInvoiceID; + public bool ExpOrderWithInvoiceID { get => expOrderWithInvoiceID; set { if (SetProperty(ref expOrderWithInvoiceID, value)) SaveAI(); } } + + + /// + /// 优先用webapi或者本机连接 + /// + bool vipUseWebAPI; + public bool VipUseWebAPI { get => vipUseWebAPI; set { if (SetProperty(ref vipUseWebAPI, value)) SaveAI(); } } + + /// + /// 比对-销售数量完整后不能再更改 + /// + bool comparisonOrderCompleteReadonly; + public bool ComparisonOrderCompleteReadonly { get => comparisonOrderCompleteReadonly; set { if (SetProperty(ref comparisonOrderCompleteReadonly, value)) SaveAI(); } } + + /// + /// 比对-超数量提醒 + /// + bool comparisonOrderSuperAlert; + public bool ComparisonOrderSuperAlert { get => comparisonOrderSuperAlert; set { if (SetProperty(ref comparisonOrderSuperAlert, value)) SaveAI(); } } + + /// + /// 比对-点货数量正确才打勾 + /// + bool comparisonOnlyQtqCorrctCheck; + public bool ComparisonOnlyQtqCorrctCheck { get => comparisonOnlyQtqCorrctCheck; set { if (SetProperty(ref comparisonOnlyQtqCorrctCheck, value)) SaveAI(); } } + + /// + /// 比对-进价加税 + /// + bool comparisonPurchasePriceAddTax; + public bool ComparisonPurchasePriceAddTax { get => comparisonPurchasePriceAddTax; set { if (SetProperty(ref comparisonPurchasePriceAddTax, value)) SaveAI(); } } + #endregion + + /// + /// 比对-售价为零,进价相同,自动使用系统售价 + /// + bool comparisonUnitpriceAuto1; + public bool ComparisonUnitpriceAuto1 { get => comparisonUnitpriceAuto1; set { if (SetProperty(ref comparisonUnitpriceAuto1, value)) SaveAI(); } } + + /// + /// 比对-数量默认为追加 + /// + bool comparisonDefaultAdditionalQuantity; + public bool ComparisonDefaultAdditionalQuantity { get => comparisonDefaultAdditionalQuantity; set { if (SetProperty(ref comparisonDefaultAdditionalQuantity, value)) SaveAI(); } } + + /// + /// 销售-计算重量总计 + /// + bool salesCalcWeightTotal; + public bool SalesCalcWeightTotal { get => salesCalcWeightTotal; set { if (SetProperty(ref salesCalcWeightTotal, value)) SaveAI(); } } + + /// + /// 测试年结送优惠券/月结送优惠券,宽松条件方式 + /// + bool testMonthlyOff; + public bool TestMonthlyOff { get => testMonthlyOff; set { if (SetProperty(ref testMonthlyOff, value)) SaveAI(); } } + + + /// + /// 比对-调用供应商的销售价公式 + /// + bool comparisonUseSuppliersSalesPriceFormula = true; + public bool ComparisonUseSuppliersSalesPriceFormula { get => comparisonUseSuppliersSalesPriceFormula; set { if (SetProperty(ref comparisonUseSuppliersSalesPriceFormula, value)) SaveAI(); } } + + /// + /// 比对-毛利率公式II => 毛利率 =(1-不含税进价/不含税售价)×100% + /// + bool comparisonGrossFormulaII = true; + public bool ComparisonGrossFormulaII { get => comparisonGrossFormulaII; set { if (SetProperty(ref comparisonGrossFormulaII, value)) SaveAI(); } } + + /// + /// 比对-四舍五入 + /// + bool comparisonRounding = true; + public bool ComparisonRounding { get => comparisonRounding; set { if (SetProperty(ref comparisonRounding, value)) SaveAI(); } } + + /// + /// 打开单据不关闭挂单列表 + /// + bool doNotCloseListOfOrders; + public bool DoNotCloseListOfOrders { get => doNotCloseListOfOrders; set { if (SetProperty(ref doNotCloseListOfOrders, value)) SaveAI(); } } + + /// + /// 销售-启用Lote + /// + bool salesEnableLote; + [DisplayName("销售-启用Lote")] + public bool SalesEnableLote { get => salesEnableLote; set { if (SetProperty(ref salesEnableLote, value)) SaveAI(); } } + + /// + /// 精度计算:发票含税单据合计直接使用商品合计,不反算税率合计 + /// + bool orderSubtotalUseOldMethod; + [DisplayName("精度计算:发票含税单据合计直接使用商品合计,不反算税率合计")] + public bool OrderSubtotalUseOldMethod { get => orderSubtotalUseOldMethod; set { if (SetProperty(ref orderSubtotalUseOldMethod, value)) SaveAI(); } } + + /// + /// 小票:打印Json格式收货地址 + /// + bool ticketWithJsonRemark; + [DisplayName("小票:打印Json格式收货地址")] + public bool TicketWithJsonRemark { get => ticketWithJsonRemark; set { if (SetProperty(ref ticketWithJsonRemark, value)) SaveAI(); } } + + /// + /// 小票:打印客户资料地址II + /// + bool ticketClientDataII; + [DisplayName("小票:打印客户资料地址II")] + public bool TicketClientDataII { get => ticketClientDataII; set { if (SetProperty(ref ticketClientDataII, value)) SaveAI(); } } + + /// + /// 小票:打印备注 + /// + bool ticketWithRemark; + [DisplayName("小票:打印备注")] + public bool TicketWithRemark { get => ticketWithRemark; set { if (SetProperty(ref ticketWithRemark, value)) SaveAI(); } } + + /// + /// 小票:打印部分备注 + /// + bool ticketWithRemarkLite; + [DisplayName("小票:打印部分备注")] + public bool TicketWithRemarkLite { get => ticketWithRemarkLite; set { if (SetProperty(ref ticketWithRemarkLite, value)) SaveAI(); } } + + /// + /// 大票:打印Json格式收货地址 + /// + bool a4WithJsonRemark; + [DisplayName("大票:打印Json格式收货地址")] + public bool A4WithJsonRemark { get => a4WithJsonRemark; set { if (SetProperty(ref a4WithJsonRemark, value)) SaveAI(); } } + + /// + /// 大票:打印收货地址(客户资料地址II) + /// + bool a4WithClientDataII; + [DisplayName("大票:打印收货地址(客户资料地址II)")] + public bool A4WithClientDataII { get => a4WithClientDataII; set { if (SetProperty(ref a4WithClientDataII, value)) SaveAI(); } } + + /// + /// 小程序客户名称自动转拼音 + /// + bool autoAppCustomerNameTransToPinyin; + [DisplayName("自动")] + public bool AutoAppCustomerNameTransToPinyin { get => autoAppCustomerNameTransToPinyin; set { if (SetProperty(ref autoAppCustomerNameTransToPinyin, value)) SaveAI(); } } + + /// + /// 更新客户资料到原始小程序单据 + /// + bool autoAppSaveInfoII2miniOrders; + [DisplayName("更新客户资料到原始小程序单据")] + public bool AutoAppSaveInfoII2miniOrders { get => autoAppSaveInfoII2miniOrders; set { if (SetProperty(ref autoAppSaveInfoII2miniOrders, value)) SaveAI(); } } + + /// + /// 小程序单据窗口最大化 + /// + bool formMiniWebAPPWindowMax = true; + [DisplayName("窗口最大化")] + public bool FormMiniWebAPPWindowMax { get => formMiniWebAPPWindowMax; set { if (SetProperty(ref formMiniWebAPPWindowMax, value)) SaveAI(); } } + + /// + /// 小程序单据自动调入详单 + /// + bool formMiniWebAppAutoLoadOrderDetails = true; + [DisplayName("详单")] + public bool FormMiniWebAppAutoLoadOrderDetails { get => formMiniWebAppAutoLoadOrderDetails; set { if (SetProperty(ref formMiniWebAppAutoLoadOrderDetails, value)) SaveAI(); } } + + /// + /// 使用会员卡&优惠券窗口自动关闭 + /// + bool formUsingCouponAutoClose = true; + [DisplayName("自动关闭")] + public bool FormUsingCouponAutoClose { get => formUsingCouponAutoClose; set { if (SetProperty(ref formUsingCouponAutoClose, value)) SaveAI(); } } + #endregion + + /// + /// 提醒非正常商品状态 + /// + bool alertProductStatus; + [DisplayName("提醒非正常商品状态")] + public bool AlertProductStatus { get => alertProductStatus; set { if (SetProperty(ref alertProductStatus, value)) SaveAI(); } } + + /// + /// 新打印模块 + /// + bool newPrintModel; + [DisplayName("新小票打印模块")] + public bool NewPrintModel { get => newPrintModel; set { if (SetProperty(ref newPrintModel, value)) SaveAI(); } } + + public void SaveAI() + { + + } + } +} \ No newline at end of file diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index a21af7db..79e53cb8 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -407,6 +407,372 @@ 导航属性 + + + 配置名称 + + + + + 配置文件路径 + + + + + 管理:商品库存过滤 + + + + + 销售:商品库存过滤 + + + + + 销售:商品状态过滤 + + + + + 销售:商品状态过滤字符串形式 + + + + + 销售父类排序 + + + + + 销售类别排序 + + + + + 销售商品排序 + + + + + 自定义首页 + + + + + 用户资料锁定 + + + + + 禁止单位[件] + + + + + 指定游客账号ID + + + + + 默认注册email后缀 + + + + + 默认Code + + + + + 配货单列表排序 + + + + + 配货单据排序 + + + + + 使用紧凑型左类别条 + + + + + 旧版app图片路径,用于导入 + + + + + 显示APP面板 + + + + + H5的Url + + + + + 监控输出SQL语句 + + + + + 打开内测功能 + + + + + 类别供应商显示序号 + + + + + 导入单据过滤数量0的行 + + + + + 导入单据过滤库存0的行 + + + + + 打印通道3重定向到小票 + + + + + 精度计算:使用格式化2位后再累加 + + + + + 测试功能:强制同步类别ID,供应商ID, 用于误删除商品表恢复数据 + + + + + 使用极速版 + + + + + 使用多发票序列 + + + + + 显示独立结账提示窗体 + + + + + 结账前提示输入邮编 + + + + + 只读的单元格显示大字体 + + + + + 接口历史文件地址 + + + + + 客户评级 + + + + + 客户供应商删除限制 + + + + + 导出资料自动传送 + + + + + FTP资料 + + + + + 导出单据使用名称替换条码 + + + + + 预热数据连接 + + + + + 销售单内部查找包含名称模糊查找 + + + + + 销售单商品重复提示 + + + + + VP过滤VO单据 + + + + + VP过滤VO单据并过滤金额 + + + + + 导出单据附加发票号码到备注 + + + + + 优先用webapi或者本机连接 + + + + + 比对-销售数量完整后不能再更改 + + + + + 比对-超数量提醒 + + + + + 比对-点货数量正确才打勾 + + + + + 比对-进价加税 + + + + + 比对-售价为零,进价相同,自动使用系统售价 + + + + + 比对-数量默认为追加 + + + + + 销售-计算重量总计 + + + + + 测试年结送优惠券/月结送优惠券,宽松条件方式 + + + + + 比对-调用供应商的销售价公式 + + + + + 比对-毛利率公式II => 毛利率 =(1-不含税进价/不含税售价)×100% + + + + + 比对-四舍五入 + + + + + 打开单据不关闭挂单列表 + + + + + 销售-启用Lote + + + + + 精度计算:发票含税单据合计直接使用商品合计,不反算税率合计 + + + + + 小票:打印Json格式收货地址 + + + + + 小票:打印客户资料地址II + + + + + 小票:打印备注 + + + + + 小票:打印部分备注 + + + + + 大票:打印Json格式收货地址 + + + + + 大票:打印收货地址(客户资料地址II) + + + + + 小程序客户名称自动转拼音 + + + + + 更新客户资料到原始小程序单据 + + + + + 小程序单据窗口最大化 + + + + + 小程序单据自动调入详单 + + + + + + 提醒非正常商品状态 + + + + + 新打印模块 + + 调价单 diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index f4b11936..9dd324e6 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -1,4 +1,5 @@ -using FreeSql.DataAnnotations; +using AME.Helpers; +using FreeSql.DataAnnotations; using FreeSql.Internal; using System; using System.Collections.Generic; @@ -15,6 +16,20 @@ namespace FreeSql.Tests [Fact] public void VersionByte() { + g.sqlserver.Insert(new AppSettingII + { + + }).ExecuteAffrows(); + var item33 = g.sqlserver.Select().ToList(); + var sql22 = g.sqlserver.Select() + .OrderBy(a => a.ID) + .Count(out var total) + .Page(1, 10).ToSql(); + var items22 = g.sqlserver.Select().WithSql(sql22).ToList(); + + var defv1 = typeof(decimal).CreateInstanceGetDefaultValue(); + var defv2 = typeof(decimal?).CreateInstanceGetDefaultValue(); + var fsql = g.mysql; fsql.Delete().Where("1=1").ExecuteAffrows(); var id = Guid.NewGuid(); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 3438b9c7..622ed4bc 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -524,6 +524,19 @@ namespace FreeSql.Internal var isLazy = vp != null && vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName); AddTableRef(common, trytb, pnv, isLazy, vp, cscode); + if (trytb.GetTableRef(pnv.Name, false) == null) + { + trytb.ColumnsByCsIgnore.Add(pnv.Name, new ColumnInfo + { + Table = trytb, + CsName = pnv.Name, + CsType = pnv.PropertyType, + Attribute = new ColumnAttribute + { + IsIgnore = true + } + }); + } } if (cscode?.Length > cscodeLength) { From 3014e6faf083adbb3975e84c85766959f0c353e7 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 23 Nov 2020 22:33:37 +0800 Subject: [PATCH 1020/1029] - FreeSql.Generator DefaultValue --- Extensions/FreeSql.Generator/RazorModel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 6ce2502b..95d51cdc 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -218,6 +218,8 @@ public class RazorModel { else if (defval.StartsWith("(") && defval.EndsWith(")")) defval = defval.Substring(1, defval.Length - 2); else return null; if (defval.StartsWith("N'") && defval.EndsWith("'")) defval = defval.Substring(1); + if (cstype == typeof(Guid) && string.Compare(defval, "newid()", true) == 0) return $"Guid.NewGuid()"; + if (cstype == typeof(string) && string.Compare(defval, "newid()", true) == 0) return $"Guid.NewGuid().ToString().ToUpper()"; } if ((cstype == typeof(string) && defval.StartsWith("'") && defval.EndsWith("'::character varying") || cstype == typeof(Guid) && defval.StartsWith("'") && defval.EndsWith("'::uuid") From c9a1e2a7b86d5dd32fafe366212efd6de9fb6fb8 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 23 Nov 2020 22:38:52 +0800 Subject: [PATCH 1021/1029] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20JsonMap=20St?= =?UTF-8?q?ringLength=20=3D=20-2=EF=BC=9B#556?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index a0f6855d..24262eab 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -49,6 +49,7 @@ public static class FreeSqlJsonMapCoreExtensions if (isJsonMap) { e.ModifyResult.MapType = typeof(string); + e.ModifyResult.StringLength = -2; if (_dicTypes.TryAdd(e.Property.PropertyType, true)) { FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => From 3aec26337a6c9b7bc7604665e2b7cfbba2b4fefc Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 24 Nov 2020 00:17:12 +0800 Subject: [PATCH 1022/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=20IN=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E6=89=A9=E5=B1=95=20where=20id=20in=20@ids?= =?UTF-8?q?=EF=BC=9B#560?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlConnectorAdo/MySqlAdoTest.cs | 2 + .../Dameng/DamengAdo/DamengAdoTest.cs | 2 + .../Firebird/ExtensionsAdo/FirebirdAdoTest.cs | 2 + .../KingbaseESAdo/KingbaseESAdoTest.cs | 2 + .../MsAccess/MsAccessAdo/MsAccessAdoTest.cs | 2 + .../MySql/MySqlAdo/MySqlAdoTest.cs | 2 + .../Oracle/OracleAdo/OracleAdoTest.cs | 2 + .../PostgreSQLAdo/PostgreSQLAdoTest.cs | 2 + .../ShenTong/ShenTongAdo/ShenTongAdoTest.cs | 2 + .../SqlServerAdo/SqlServerAdoTest.cs | 2 + .../Sqlite/SqliteAdo/SqliteAdoTest.cs | 2 + FreeSql/FreeSql.xml | 402 ++++++++++-------- .../CommonProvider/AdoProvider/AdoProvider.cs | 28 +- .../AdoProvider/AdoProviderAsync.cs | 20 +- .../FreeSql.Provider.Dameng/DamengUtils.cs | 31 +- .../FreeSql.Provider.Oracle/OracleUtils.cs | 6 +- .../FreeSql.Provider.Sqlite/SqliteUtils.cs | 30 +- 17 files changed, 322 insertions(+), 217 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs index 2b3d9f5c..e87dac33 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorAdo/MySqlAdoTest.cs @@ -64,6 +64,8 @@ namespace FreeSql.Tests.MySqlConnector var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); var t5 = g.mysql.Ado.Query("select * from song"); + + var t6 = g.mysql.Ado.Query("select * from song where id in @ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs index 01f589f6..5bf7503f 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengAdo/DamengAdoTest.cs @@ -53,6 +53,8 @@ namespace FreeSql.Tests.Dameng var t4 = g.dameng.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); var t5 = g.dameng.Ado.Query("select * from \"TB_TOPIC\""); + + var t6 = g.dameng.Ado.Query("select * from \"TB_TOPIC\" where \"ID\" in @ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/ExtensionsAdo/FirebirdAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/ExtensionsAdo/FirebirdAdoTest.cs index 2ddeab02..5701d1d8 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/ExtensionsAdo/FirebirdAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/ExtensionsAdo/FirebirdAdoTest.cs @@ -53,6 +53,8 @@ namespace FreeSql.Tests.Firebird var t4 = g.firebird.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC22\""); var t5 = g.firebird.Ado.Query("select * from \"TB_TOPIC22\""); + + var t6 = g.firebird.Ado.Query("select * from \"TB_TOPIC22\" where \"ID\" in @ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs index ad9c7cf5..5c319ed3 100644 --- a/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/KingbaseES/KingbaseESAdo/KingbaseESAdoTest.cs @@ -48,6 +48,8 @@ namespace FreeSql.Tests.KingbaseES var t4 = g.kingbaseES.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); var t5 = g.kingbaseES.Ado.Query("select * from \"TB_TOPIC\""); + + var t6 = g.kingbaseES.Ado.Query("select * from TB_TOPIC where id in @ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs index 3e6ba0ef..b64a7bf7 100644 --- a/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MsAccess/MsAccessAdo/MsAccessAdoTest.cs @@ -59,6 +59,8 @@ namespace FreeSql.Tests.MsAccess var t4 = g.msaccess.Ado.Query<(int, string, string)>("select * from [song]"); var t5 = g.msaccess.Ado.Query("select * from [song]"); + + var t6 = g.msaccess.Ado.Query("select * from song where id in @ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs index 3ba3a825..7f24092d 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs @@ -52,6 +52,8 @@ namespace FreeSql.Tests.MySql var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); var t5 = g.mysql.Ado.Query("select * from song"); + + var t6 = g.mysql.Ado.Query("select * from song where id in ?ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs index ae86f397..8997a6b5 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs @@ -53,6 +53,8 @@ namespace FreeSql.Tests.Oracle var t4 = g.oracle.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); var t5 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + + var t6 = g.oracle.Ado.Query("select * from TB_TOPIC where id in :ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs index aef0967d..14e74edf 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs @@ -54,6 +54,8 @@ namespace FreeSql.Tests.PostgreSQL var t4 = g.pgsql.Ado.Query<(int, string, string)>("select * from xxx"); var t5 = g.pgsql.Ado.Query("select * from xxx"); + + var t6 = g.pgsql.Ado.Query("select * from xxx where id in @ids", new { ids = new[] { "1", "2", "3" } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs index dd62f210..712e5894 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/ShenTongAdo/ShenTongAdoTest.cs @@ -54,6 +54,8 @@ namespace FreeSql.Tests.ShenTong var t4 = g.shentong.Ado.Query<(int, string, string)>("select * from xxx"); var t5 = g.shentong.Ado.Query("select * from xxx"); + + var t6 = g.shentong.Ado.Query("select * from xxx where id in @ids", new { ids = new[] { "1", "2", "3" } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs index 6a01369e..8c4c4c42 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -95,6 +95,8 @@ namespace FreeSql.Tests.SqlServer var t5 = g.sqlserver.Ado.Query("select * from xxx where Id = @Id", new Dictionary { ["id"] = 1 }); + + var t6 = g.sqlserver.Ado.Query("select * from xxx where id in @ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs index 004aec54..b7ce8564 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs @@ -59,6 +59,8 @@ namespace FreeSql.Tests.Sqlite var t4 = g.sqlite.Ado.Query<(int, string, string)>("select * from \"song\""); var t5 = g.sqlite.Ado.Query("select * from \"song\""); + + var t6 = g.sqlite.Ado.Query("select * from song where id in @ids", new { ids = new[] { 1, 2, 3 } }); } [Fact] diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5140edee..837f0039 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3089,177 +3089,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 在【主库】执行 - - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 在【主库】执行 - - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行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 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 可自定义解析表达式 @@ -4088,12 +3917,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4164,12 +3987,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4785,3 +4602,222 @@ +ystem.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + 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 + 达梦: 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/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 6abba992..7cbcfb9e 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -1,14 +1,16 @@ -using FreeSql.Internal.ObjectPool; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; using System; -using System.Collections.Generic; +using System.Collections; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Diagnostics; using System.Linq; -using System.Text; using System.Reflection; -using FreeSql.Internal.Model; +using System.Text; +using System.Text.RegularExpressions; namespace FreeSql.Internal.CommonProvider { @@ -849,8 +851,24 @@ namespace FreeSql.Internal.CommonProvider foreach (var parm in cmdParms) { if (parm == null) continue; + var isnew = false; if (parm.Value == null) parm.Value = DBNull.Value; - cmd.Parameters.Add(parm); + else + { + if (parm.Value is Array || parm.Value is IList) + { + cmd.CommandText = Regex.Replace(cmd.CommandText, @"\s+(in|In|IN|iN)\s+[\:\?\@]" + parm.ParameterName.TrimStart('@', '?', ':'), m => + { + isnew = true; + var arr = parm.Value as IEnumerable; + if (arr == null) return " IS NULL"; + var vals = new List(); + foreach (var val in arr) vals.Add(val); + return $" in {_util.FormatSql("{0}", new object[] { vals })}"; + }); + } + } + if (isnew == false) cmd.Parameters.Add(parm); } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index f6d6bab5..cc9a3d05 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -1,11 +1,13 @@ using FreeSql.Internal.Model; using FreeSql.Internal.ObjectPool; using System; +using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -755,8 +757,24 @@ namespace FreeSql.Internal.CommonProvider foreach (var parm in cmdParms) { if (parm == null) continue; + var isnew = false; if (parm.Value == null) parm.Value = DBNull.Value; - cmd.Parameters.Add(parm); + else + { + if (parm.Value is Array || parm.Value is IList) + { + cmd.CommandText = Regex.Replace(cmd.CommandText, @"\s+(in|In|IN|iN)\s+[\:\?\@]" + parm.ParameterName.TrimStart('@', '?', ':'), m => + { + isnew = true; + var arr = parm.Value as IEnumerable; + if (arr == null) return " IS NULL"; + var vals = new List(); + foreach (var val in arr) vals.Add(val); + return $" in {_util.FormatSql("{0}", new object[] { vals })}"; + }); + } + } + if (isnew == false) cmd.Parameters.Add(parm); } } diff --git a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs index d8faa6f5..07400898 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengUtils.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengUtils.cs @@ -41,22 +41,27 @@ namespace FreeSql.Dameng public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => { - var dbtype = (DmDbType)_orm.CodeFirst.GetDbInfo(type)?.type; - switch (dbtype) + var typeint = _orm.CodeFirst.GetDbInfo(type)?.type; + var dbtype = typeint != null ? (DmDbType?)typeint : null; + if (dbtype != null) { - case DmDbType.Bit: - if (value == null) value = null; - else value = (bool)value == true ? 1 : 0; - dbtype = DmDbType.Int32; - break; + switch (dbtype) + { + case DmDbType.Bit: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = DmDbType.Int32; + break; - case DmDbType.Char: - case DmDbType.VarChar: - case DmDbType.Text: - value = string.Concat(value); - break; + case DmDbType.Char: + case DmDbType.VarChar: + case DmDbType.Text: + value = string.Concat(value); + break; + } } - var ret = new DmParameter { ParameterName = $":{name}", DmSqlType = dbtype, Value = value }; + var ret = new DmParameter { ParameterName = $":{name}", Value = value }; + if (dbtype != null) ret.DmSqlType = dbtype.Value; return ret; }); diff --git a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs index 9d66f317..479d77b4 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleUtils.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleUtils.cs @@ -54,14 +54,16 @@ namespace FreeSql.Oracle public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => Utils.GetDbParamtersByObject(sql, obj, ":", (name, type, value) => { - var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; + var dbtypeint = _orm.CodeFirst.GetDbInfo(type)?.type; + var dbtype = dbtypeint != null ? (OracleDbType?)dbtypeint : null; if (dbtype == OracleDbType.Boolean) { if (value == null) value = null; else value = (bool)value == true ? 1 : 0; dbtype = OracleDbType.Int16; } - var ret = new OracleParameter { ParameterName = $":{name}", OracleDbType = dbtype, Value = value }; + var ret = new OracleParameter { ParameterName = $":{name}", Value = value }; + if (dbtype != null) ret.OracleDbType = dbtype.Value; return ret; }); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs index ffdbb89c..1915d8b8 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteUtils.cs @@ -44,23 +44,27 @@ namespace FreeSql.Sqlite public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { - var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; - switch (dbtype) + var typeint = _orm.CodeFirst.GetDbInfo(type)?.type; + var dbtype = typeint != null ? (DbType?)typeint : null; + if (dbtype != null) { - case DbType.Guid: - if (value == null) value = null; - else value = ((Guid)value).ToString(); - dbtype = DbType.String; - break; - case DbType.Time: - if (value == null) value = null; - else value = ((TimeSpan)value).Ticks / 10000; - dbtype = DbType.Int64; - break; + switch (dbtype.Value) + { + case DbType.Guid: + if (value == null) value = null; + else value = ((Guid)value).ToString(); + dbtype = DbType.String; + break; + case DbType.Time: + if (value == null) value = null; + else value = ((TimeSpan)value).Ticks / 10000; + dbtype = DbType.Int64; + break; + } } var ret = new SQLiteParameter(); ret.ParameterName = $"@{name}"; - ret.DbType = dbtype; + if (dbtype != null) ret.DbType = dbtype.Value; ret.Value = value; return ret; }); From f3eb49040c7a1a5ce38f0847fa3d8ab16b987d9b Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 24 Nov 2020 00:27:15 +0800 Subject: [PATCH 1023/1029] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IAdo.QuerySi?= =?UTF-8?q?ngle=20=E6=9F=A5=E8=AF=A2=E5=8D=95=E6=9D=A1=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=EF=BC=9B#560?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/Interface/IAdo.cs | 4 ++++ FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs | 2 ++ .../Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs | 2 ++ FreeSql/Internal/Model/AdoCommandFluent.cs | 2 ++ 4 files changed, 10 insertions(+) diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 56855659..de93f269 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -215,6 +215,7 @@ namespace FreeSql List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); List Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); + T QuerySingle(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -226,6 +227,7 @@ namespace FreeSql List Query(string cmdText, object parms = null); List Query(DbTransaction transaction, string cmdText, object parms = null); List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); + T QuerySingle(string cmdText, object parms = null); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -425,6 +427,7 @@ namespace FreeSql Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); + Task QuerySingleAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); /// /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> @@ -437,6 +440,7 @@ namespace FreeSql Task> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); + Task QuerySingleAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 7cbcfb9e..3ed9be74 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -125,6 +125,8 @@ namespace FreeSql.Internal.CommonProvider } } + public T QuerySingle(string cmdText, object parms = null) => Query(cmdText, parms).FirstOrDefault(); + public T QuerySingle(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(cmdType, cmdText, cmdParms).FirstOrDefault(); public List Query(string cmdText, object parms = null) => Query(null, null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(null, null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); public List Query(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null) => Query(null, connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms)); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index cc9a3d05..8421208a 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -40,6 +40,8 @@ namespace FreeSql.Internal.CommonProvider } } + async public Task QuerySingleAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => (await QueryAsync(cmdText, parms, cancellationToken)).FirstOrDefault(); + async public Task QuerySingleAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => (await QueryAsync(cmdType, cmdText, cmdParms, cancellationToken)).FirstOrDefault(); public Task> QueryAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, null, null, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, null, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); public Task> QueryAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default) => QueryAsync(null, connection, transaction, CommandType.Text, cmdText, 0, GetDbParamtersByObject(cmdText, parms), cancellationToken); diff --git a/FreeSql/Internal/Model/AdoCommandFluent.cs b/FreeSql/Internal/Model/AdoCommandFluent.cs index 322f4e47..3fc66659 100644 --- a/FreeSql/Internal/Model/AdoCommandFluent.cs +++ b/FreeSql/Internal/Model/AdoCommandFluent.cs @@ -92,6 +92,7 @@ namespace FreeSql.Internal.Model public DataSet ExecuteDataSet() => this.Ado.ExecuteDataSet(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); public object[][] ExecuteArray() => this.Ado.ExecuteArray(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); public List Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); + public T QuerySingle() => Query().FirstOrDefault(); public NativeTuple, List> Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); public NativeTuple, List, List> Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); public NativeTuple, List, List, List> Query() => this.Ado.Query(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray()); @@ -105,6 +106,7 @@ namespace FreeSql.Internal.Model public Task ExecuteDataSetAsync(CancellationToken cancellationToken = default) => this.Ado.ExecuteDataSetAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); public Task ExecuteArrayAsync(CancellationToken cancellationToken = default) => this.Ado.ExecuteArrayAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); public Task> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); + async public Task QuerySingleAsync(CancellationToken cancellationToken = default) => (await QueryAsync(cancellationToken)).FirstOrDefault(); public Task, List>> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); public Task, List, List>> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); public Task, List, List, List>> QueryAsync(CancellationToken cancellationToken = default) => this.Ado.QueryAsync(this.Connection, this.Transaction, this.CmdType, this.CmdText, this.CmdTimeout, this.CmdParameters.ToArray(), cancellationToken); From f179943d4e89fd04340e92e544cfd375ce43e811 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 24 Nov 2020 22:16:43 +0800 Subject: [PATCH 1024/1029] v2.0.0 #278 #511 #505 #537 #548 #560 #519 #500 #536 #502 #521 --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/FreeSql.xml | 402 ++++++++---------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 23 files changed, 205 insertions(+), 241 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 5b36dc68..d8e77dd7 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index b7125dc9..2cfd7288 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 5c4b7a2a..671afe32 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index ff211022..2879a2c3 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 6750bdf5..84b2bff0 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0-preview1123 + 2.0.0 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 7f13d581..005062e4 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 0420d521..9de4ba6c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 4d491583..89c5df17 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0-preview1123 + 2.0.0 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index b522aa2c..8d6bcc40 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 837f0039..5140edee 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3089,6 +3089,177 @@ + + + 测试数据库是否连接正确,本方法执行如下命令: + MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 + Oracle: SELECT 1 FROM dual + + 命令超时设置(秒) + + true: 成功, false: 失败 + + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 查询 + + + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 查询 + + + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 查询 + + + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 在【主库】执行 + + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 在【主库】执行 + + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + 执行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 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + + + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 提示:parms 参数还可以传 Dictionary<string, object> + + + + + + + + 可自定义解析表达式 @@ -3917,6 +4088,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3987,6 +4164,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -4602,222 +4785,3 @@ -ystem.Boolean}})"> - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 使用 and 拼接两个 lambda 表达式 - - - - - - 使用 and 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - 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 - 达梦: 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/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 1b756bae..abd70758 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 8ea23f14..502a495d 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index b72d9898..70794158 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 7face202..71aff1ab 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 0c9c04a7..24368a38 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index a24f6cb2..4c493fac 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index c2181e42..e6a6be15 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 552fd353..caa4473e 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index b1d76a78..6fc976eb 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 4d3802df..585e14d6 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 4fd3a441..9e3c1572 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 6f1cc0d0..b3adc0dd 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 3b3ea1bc..6728e379 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0-preview1123 + 2.0.0 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From dddfbe56afce90feed2167a65cac3fd3c2a2e128 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 25 Nov 2020 10:36:44 +0800 Subject: [PATCH 1025/1029] =?UTF-8?q?v2.0.100=20=E8=A1=A5=E5=85=85=20cance?= =?UTF-8?q?llationToken=3Ddefault?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 14 +- FreeSql/Interface/Curd/ISelect/ISelect2`16.cs | 757 ++++++++++-------- .../SelectProvider/T4Temp/ISelect2`16.tt | 46 +- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Odbc.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- ...FreeSql.Provider.SqlServerForSystem.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 24 files changed, 456 insertions(+), 403 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index d8e77dd7..975c1222 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 2cfd7288..68bd12dd 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 671afe32..a8d05a60 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index 2879a2c3..d42f4d90 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 84b2bff0..131eb90f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.0 + 2.0.100 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index 005062e4..e93956ae 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 9de4ba6c..96ddbf44 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 89c5df17..ef138d95 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.0 + 2.0.100 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8d6bcc40..f47f3eb2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access @@ -24,18 +24,6 @@ - - - - - - - - True - True - TextTemplate1.tt - - FreeSql.xml diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs b/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs index b825f8d9..b619f156 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs @@ -1,4 +1,5 @@ -using FreeSql.Internal.Model; + +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -9,40 +10,48 @@ using System.Threading.Tasks; namespace FreeSql { + + + + + + + public interface ISelect : ISelect0, T1> where T2 : class { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -117,40 +126,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -225,40 +238,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -333,40 +350,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -441,40 +462,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -549,40 +574,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -657,40 +686,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -765,40 +798,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -873,40 +910,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> 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 { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -981,40 +1022,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> 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 { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -1089,40 +1134,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> 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 { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -1197,40 +1246,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> 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 { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -1305,40 +1358,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> 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 { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -1413,40 +1470,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> 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 { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion @@ -1521,40 +1582,44 @@ namespace FreeSql } + + + public interface ISelect : ISelect0, T1> 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 { + #if net40 #else - Task AnyAsync(Expression> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(Expression> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression> column, CancellationToken cancellationToken); - Task MinAsync(Expression> column, CancellationToken cancellationToken); - Task MaxAsync(Expression> column, CancellationToken cancellationToken); - Task AvgAsync(Expression> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #endregion diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt index e4064230..d166885a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt +++ b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt @@ -51,36 +51,36 @@ public interface ISelect<<#=NewStr #>> : ISelect0>, T1> <#= #if net40 #else - Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(CancellationToken cancellationToken); + Task AnyAsync(Expression, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(CancellationToken cancellationToken = default); - Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(CancellationToken cancellationToken); + Task ToOneAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(CancellationToken cancellationToken = default); - Task ToAggregateAsync(Expression, TReturn>> select, CancellationToken cancellationToken); - Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken); + Task ToAggregateAsync(Expression, TReturn>> select, CancellationToken cancellationToken = default); + Task SumAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression, TMember>> column, CancellationToken cancellationToken = default); #region HzyTuple 元组 - Task AnyAsync(Expression>, bool>> exp, CancellationToken cancellationToken); - Task InsertIntoAsync(string tableName, Expression>, TTargetEntity>> select, CancellationToken cancellationToken) where TTargetEntity : class; - Task ToDataTableAsync(Expression>, TReturn>> select, CancellationToken cancellationToken); - Task> ToListAsync(Expression>, TReturn>> select, CancellationToken cancellationToken); + Task AnyAsync(Expression>, bool>> exp, CancellationToken cancellationToken = default); + Task InsertIntoAsync(string tableName, Expression>, TTargetEntity>> select, CancellationToken cancellationToken = default) where TTargetEntity : class; + Task ToDataTableAsync(Expression>, TReturn>> select, CancellationToken cancellationToken = default); + Task> ToListAsync(Expression>, TReturn>> select, CancellationToken cancellationToken = default); - Task ToOneAsync(Expression>, TReturn>> select, CancellationToken cancellationToken); - Task FirstAsync(Expression>, TReturn>> select, CancellationToken cancellationToken); + Task ToOneAsync(Expression>, TReturn>> select, CancellationToken cancellationToken = default); + Task FirstAsync(Expression>, TReturn>> select, CancellationToken cancellationToken = default); - Task SumAsync(Expression>, TMember>> column, CancellationToken cancellationToken); - Task MinAsync(Expression>, TMember>> column, CancellationToken cancellationToken); - Task MaxAsync(Expression>, TMember>> column, CancellationToken cancellationToken); - Task AvgAsync(Expression>, TMember>> column, CancellationToken cancellationToken); + Task SumAsync(Expression>, TMember>> column, CancellationToken cancellationToken = default); + Task MinAsync(Expression>, TMember>> column, CancellationToken cancellationToken = default); + Task MaxAsync(Expression>, TMember>> column, CancellationToken cancellationToken = default); + Task AvgAsync(Expression>, TMember>> column, CancellationToken cancellationToken = default); #endregion diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index abd70758..41e18a07 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 502a495d..0776fe1c 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 70794158..88f6ba01 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index 71aff1ab..debe8a3c 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 24368a38..7f078cbd 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 4c493fac..cb32cdbd 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index e6a6be15..6f42497e 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index caa4473e..89c77d53 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 6fc976eb..4433465a 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 585e14d6..47c1f1a5 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 9e3c1572..6c95158e 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index b3adc0dd..18f4e134 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 6728e379..d60e06e5 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.0 + 2.0.100 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From 8373411f6341d0d4b50f06910e99ffb3d9eb82f4 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 25 Nov 2020 11:06:31 +0800 Subject: [PATCH 1026/1029] =?UTF-8?q?-=20=E5=AE=8C=E5=96=84=20=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=20DbFirst=20=E6=94=AF=E6=8C=81=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Tests/Dameng/DamengDbFirstTest.cs | 3 +++ Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs | 14 +++++++++++++- .../Dameng/OdbcDamengDbFirst.cs | 14 +++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs index 8ae7578a..6466f826 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengDbFirstTest.cs @@ -33,6 +33,9 @@ namespace FreeSql.Tests.Dameng Assert.Equal(t1.Columns.Count, t2.Columns.Count); var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); Assert.Null(t3); + + var t4 = fsql.DbFirst.GetTableByName("v_2user_v1"); + Assert.NotNull(t4); } [Fact] diff --git a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs index cba1151a..5dc2d3f4 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengDbFirst.cs @@ -270,7 +270,19 @@ b.comments, 'TABLE' from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' -where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")} + +UNION ALL + +select +a.owner || '.' || a.view_name, +a.owner, +a.view_name, +b.comments, +'VIEW' AS tp +from all_views a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.view_name and b.table_type = 'VIEW' +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.view_name)" : "a.view_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs index 3c410edc..1baceecb 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengDbFirst.cs @@ -270,7 +270,19 @@ b.comments, 'TABLE' from all_tables a left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' -where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")} + +UNION ALL + +select +a.owner || '.' || a.view_name, +a.owner, +a.view_name, +b.comments, +'VIEW' AS tp +from all_views a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.view_name and b.table_type = 'VIEW' +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.view_name)" : "a.view_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; From 1bbf00a3e26296e035977f610ca3746a42ed8220 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 26 Nov 2020 18:38:15 +0800 Subject: [PATCH 1027/1029] update summary --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 --- FreeSql.Tests/FreeSql.Tests/AppSetting.cs | 2 +- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 6 +- FreeSql/FreeSql.xml | 68 +++++++++---------- FreeSql/Interface/Curd/IDelete.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 18 ++--- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect2`16.cs | 10 +-- FreeSql/Interface/Curd/IUpdate.cs | 4 +- FreeSql/Interface/IAdo.cs | 42 ++++++------ .../FreeSql.Provider.MySqlConnector.csproj | 4 +- 11 files changed, 77 insertions(+), 90 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index e4208f1f..b3c14870 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -502,14 +502,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/AppSetting.cs b/FreeSql.Tests/FreeSql.Tests/AppSetting.cs index bd82b2d1..ade54964 100644 --- a/FreeSql.Tests/FreeSql.Tests/AppSetting.cs +++ b/FreeSql.Tests/FreeSql.Tests/AppSetting.cs @@ -917,7 +917,7 @@ namespace AME.Helpers public bool FormMiniWebAppAutoLoadOrderDetails { get => formMiniWebAppAutoLoadOrderDetails; set { if (SetProperty(ref formMiniWebAppAutoLoadOrderDetails, value)) SaveAI(); } } /// - /// 使用会员卡&优惠券窗口自动关闭 + /// 使用会员卡优惠券窗口自动关闭 /// bool formUsingCouponAutoClose = true; [DisplayName("自动关闭")] diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 79e53cb8..010c32bc 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -762,7 +762,11 @@ 小程序单据自动调入详单 - + + + 使用会员卡优惠券窗口自动关闭 + + 提醒非正常商品状态 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 5140edee..f5d2d1db 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1362,7 +1362,7 @@ - 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 原生sql语法条件,Where("id = @id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 @@ -1904,7 +1904,7 @@ - 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 @@ -1913,7 +1913,7 @@ - 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 @@ -1922,7 +1922,7 @@ - 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 @@ -1939,7 +1939,7 @@ - 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 原生sql语法条件,Where("id = @id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 @@ -1948,7 +1948,7 @@ - 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + 原生sql语法条件,WhereIf(true, "id = @id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> true 时生效 @@ -1988,7 +1988,7 @@ - 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + 按原生sql语法分组,GroupBy("concat(name, @cc)", new { cc = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法 @@ -1997,7 +1997,7 @@ - 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + 按原生sql语法聚合条件过滤,Having("count(name) = @cc", new { cc = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 @@ -2006,7 +2006,7 @@ - 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + 按原生sql语法排序,OrderBy("count(name) + @cc desc", new { cc = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法 @@ -2015,7 +2015,7 @@ - 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + 按原生sql语法排序,OrderBy(true, "count(name) + @cc desc", new { cc = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> true 时生效 @@ -2425,7 +2425,7 @@ 实现 select .. from ( select ... from t ) a 这样的功能 使用 AsTable 方法也可以达到效果 - 示例:WithSql("select * from id=?id", new { id = 1 }) + 示例:WithSql("select * from id=@id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> SQL语句 @@ -2760,7 +2760,7 @@ - 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + 设置值,自定义SQL语法,SetRaw("title = @title", new { title = "newtitle" }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法 @@ -2796,7 +2796,7 @@ - 原生sql语法条件,Where("id = ?id", new { id = 1 }) + 原生sql语法条件,Where("id = @id", new { id = 1 }) 提示:parms 参数还可以传 Dictionary<string, object> sql语法条件 @@ -2922,7 +2922,7 @@ - SQL 命令执行类,fsql.Ado.CommandFluent("select * from user where age > ?age", new { age = 25 }) + SQL 命令执行类,fsql.Ado.CommandFluent("select * from user where age > @age", new { age = 25 }) .WithConnection(connection) .WithTransaction(transaction) .WithParameter("age", 25) @@ -2955,7 +2955,7 @@ - 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -2972,7 +2972,7 @@ - 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteArray("select * from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -2989,7 +2989,7 @@ - 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + 查询,ExecuteDataSet("select * from user where age > @age; select 2", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3006,7 +3006,7 @@ - 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3023,7 +3023,7 @@ - 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3040,7 +3040,7 @@ - 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3049,7 +3049,7 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -3059,7 +3059,7 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3069,7 +3069,7 @@ - 执行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 SqlParameter { ParameterName = "age", Value = 25 }) @@ -3080,7 +3080,7 @@ - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) + 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3111,7 +3111,7 @@ - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3130,7 +3130,7 @@ - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3149,7 +3149,7 @@ - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3168,7 +3168,7 @@ - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3187,7 +3187,7 @@ - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3206,7 +3206,7 @@ - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3216,7 +3216,7 @@ - 执行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 SqlParameter { ParameterName = "age", Value = 25 }) @@ -3227,7 +3227,7 @@ - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> @@ -3238,7 +3238,7 @@ - 执行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 SqlParameter { ParameterName = "age", Value = 25 }) @@ -3250,7 +3250,7 @@ - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + 执行SQL返回对象集合,Query<User, Address>("select * from user where age > @age; select * from address", new { age = 25 }) 提示:parms 参数还可以传 Dictionary<string, object> diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 7a460d31..7a034789 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -45,7 +45,7 @@ namespace FreeSql /// IDelete WhereIf(bool condition, Expression> exp); /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 原生sql语法条件,Where("id = @id", new { id = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 3f0119fc..1ecab564 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -238,7 +238,7 @@ namespace FreeSql TSelect RightJoin(Expression> exp); /// - /// 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 左联查询,使用原生sql语法,LeftJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 @@ -246,7 +246,7 @@ namespace FreeSql /// TSelect LeftJoin(string sql, object parms = null); /// - /// 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 联接查询,使用原生sql语法,InnerJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 @@ -254,7 +254,7 @@ namespace FreeSql /// TSelect InnerJoin(string sql, object parms = null); /// - /// 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > ?clicks", new { clicks = 1 }) + /// 右联查询,使用原生sql语法,RightJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 @@ -270,7 +270,7 @@ namespace FreeSql TSelect RawJoin(string sql); /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 原生sql语法条件,Where("id = @id", new { id = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 @@ -278,7 +278,7 @@ namespace FreeSql /// TSelect Where(string sql, object parms = null); /// - /// 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) + /// 原生sql语法条件,WhereIf(true, "id = @id", new { id = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// true 时生效 @@ -318,7 +318,7 @@ namespace FreeSql TSelect ForUpdate(bool nowait = false); /// - /// 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) + /// 按原生sql语法分组,GroupBy("concat(name, @cc)", new { cc = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法 @@ -326,7 +326,7 @@ namespace FreeSql /// TSelect GroupBy(string sql, object parms = null); /// - /// 按原生sql语法聚合条件过滤,Having("count(name) = ?cc", new { cc = 1 }) + /// 按原生sql语法聚合条件过滤,Having("count(name) = @cc", new { cc = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 @@ -335,7 +335,7 @@ namespace FreeSql TSelect Having(string sql, object parms = null); /// - /// 按原生sql语法排序,OrderBy("count(name) + ?cc desc", new { cc = 1 }) + /// 按原生sql语法排序,OrderBy("count(name) + @cc desc", new { cc = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法 @@ -343,7 +343,7 @@ namespace FreeSql /// TSelect OrderBy(string sql, object parms = null); /// - /// 按原生sql语法排序,OrderBy(true, "count(name) + ?cc desc", new { cc = 1 }) + /// 按原生sql语法排序,OrderBy(true, "count(name) + @cc desc", new { cc = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// true 时生效 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index d2537fcb..5a483835 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -360,7 +360,7 @@ namespace FreeSql /// /// 实现 select .. from ( select ... from t ) a 这样的功能 /// 使用 AsTable 方法也可以达到效果 - /// 示例:WithSql("select * from id=?id", new { id = 1 }) + /// 示例:WithSql("select * from id=@id", new { id = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// SQL语句 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs b/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs index b619f156..4cd64f36 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs @@ -1,5 +1,4 @@ - -using FreeSql.Internal.Model; +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -10,13 +9,6 @@ using System.Threading.Tasks; namespace FreeSql { - - - - - - - public interface ISelect : ISelect0, T1> where T2 : class { diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 87a372f7..f18eeb3b 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -151,7 +151,7 @@ namespace FreeSql /// IUpdate SetIf(bool condition, Expression> exp); /// - /// 设置值,自定义SQL语法,SetRaw("title = ?title", new { title = "newtitle" }) + /// 设置值,自定义SQL语法,SetRaw("title = @title", new { title = "newtitle" }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法 @@ -185,7 +185,7 @@ namespace FreeSql /// IUpdate WhereIf(bool condition, Expression> exp); /// - /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) + /// 原生sql语法条件,Where("id = @id", new { id = 1 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// sql语法条件 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index de93f269..41a6a708 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -64,7 +64,7 @@ namespace FreeSql DbParameter[] GetDbParamtersByObject(object obj); /// - /// SQL 命令执行类,fsql.Ado.CommandFluent("select * from user where age > ?age", new { age = 25 }) + /// SQL 命令执行类,fsql.Ado.CommandFluent("select * from user where age > @age", new { age = 25 }) /// .WithConnection(connection) /// .WithTransaction(transaction) /// .WithParameter("age", 25) @@ -98,7 +98,7 @@ namespace FreeSql void ExecuteReader(DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); void ExecuteReader(DbConnection connection, DbTransaction transaction, Action> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// - /// 查询,ExecuteReader(dr => {}, "select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -117,7 +117,7 @@ namespace FreeSql object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); object[][] ExecuteArray(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// - /// 查询,ExecuteArray("select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteArray("select * from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -136,7 +136,7 @@ namespace FreeSql DataSet ExecuteDataSet(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); DataSet ExecuteDataSet(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataSet("select * from user where age > ?age; select 2", new { age = 25 }) + /// 查询,ExecuteDataSet("select * from user where age > @age; select 2", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -155,7 +155,7 @@ namespace FreeSql DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); DataTable ExecuteDataTable(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// - /// 查询,ExecuteDataTable("select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -174,7 +174,7 @@ namespace FreeSql int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); int ExecuteNonQuery(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteNonQuery("delete from user where age > ?age", new { age = 25 }) + /// 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -193,7 +193,7 @@ namespace FreeSql object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); object ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// - /// 在【主库】执行,ExecuteScalar("select 1 from user where age > ?age", new { age = 25 }) + /// 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -204,7 +204,7 @@ namespace FreeSql object ExecuteScalar(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) /// /// /// @@ -217,7 +217,7 @@ namespace FreeSql List Query(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); T QuerySingle(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -230,7 +230,7 @@ namespace FreeSql T QuerySingle(string cmdText, object parms = null); /// - /// 执行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 SqlParameter { ParameterName = "age", Value = 25 }) /// /// /// @@ -242,7 +242,7 @@ namespace FreeSql NativeTuple, List> Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); NativeTuple, List> Query(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms); /// - /// 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -298,7 +298,7 @@ namespace FreeSql Task ExecuteReaderAsync(DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func, Task> readerHander, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// - /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -319,7 +319,7 @@ namespace FreeSql Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteArrayAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// - /// 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -340,7 +340,7 @@ namespace FreeSql Task ExecuteDataSetAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteDataSetAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// - /// 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + /// 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -361,7 +361,7 @@ namespace FreeSql Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteDataTableAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// - /// 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + /// 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -382,7 +382,7 @@ namespace FreeSql Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteNonQueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// - /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -403,7 +403,7 @@ namespace FreeSql Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// - /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -415,7 +415,7 @@ namespace FreeSql Task ExecuteScalarAsync(DbConnection connection, DbTransaction transaction, string cmdText, object parms = null, CancellationToken cancellationToken = default); /// - /// 执行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 SqlParameter { ParameterName = "age", Value = 25 }) /// /// /// @@ -429,7 +429,7 @@ namespace FreeSql Task> QueryAsync(Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task QuerySingleAsync(string cmdText, object parms = null, CancellationToken cancellationToken = default); /// - /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) + /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// @@ -443,7 +443,7 @@ namespace FreeSql Task QuerySingleAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// - /// 执行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 SqlParameter { ParameterName = "age", Value = 25 }) /// /// /// @@ -456,7 +456,7 @@ namespace FreeSql Task, List>> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default); Task, List>> QueryAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default); /// - /// 执行SQL返回对象集合,Query<User, Address>("select * from user where age > ?age; select * from address", new { age = 25 }) + /// 执行SQL返回对象集合,Query<User, Address>("select * from user where age > @age; select * from address", new { age = 25 }) /// 提示:parms 参数还可以传 Dictionary<string, object> /// /// diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index cb32cdbd..3e0ba464 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySqlConnector @@ -26,7 +26,7 @@ - + From d95524f4fed984d9174f6dc0a5c18bb7db973b23 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 26 Nov 2020 20:21:36 +0800 Subject: [PATCH 1028/1029] =?UTF-8?q?v2.0.101=20-=20=E4=BF=AE=E5=A4=8D=202?= =?UTF-8?q?.0=20bug=E3=80=81net50=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/dbcontext_01/dbcontext_01.csproj | 5 ++-- .../FreeSql.Extensions.BaseEntity.csproj | 2 +- .../FreeSql.Extensions.JsonMap.csproj | 2 +- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- .../FreeSql.Extensions.Linq.csproj | 2 +- .../FreeSql.Generator.csproj | 2 +- FreeSql.All/FreeSql.All.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 ++++++ FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/FreeSql.Tests.csproj | 2 +- FreeSql.Tests/FreeSql.Tests/UnitTest4.cs | 29 +++++++++++++++++++ FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/UtilsExpressionTree.cs | 21 ++++---------- .../FreeSql.Provider.Dameng.csproj | 2 +- .../FreeSql.Provider.Firebird.csproj | 2 +- .../FreeSql.Provider.KingbaseES.csproj | 2 +- .../FreeSql.Provider.MsAccess.csproj | 2 +- .../Curd/MySqlDelete.cs | 4 +-- .../Curd/MySqlInsert.cs | 8 ++--- .../Curd/MySqlUpdate.cs | 4 +-- .../Curd/OnDuplicateKeyUpdate.cs | 4 +-- .../FreeSql.Provider.MySql.csproj | 3 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSqlMySqlConnectorGlobalExtensions.cs | 4 +-- .../FreeSql.Provider.Odbc.csproj | 2 +- .../Curd/OracleInsert.cs | 8 ++--- .../FreeSql.Provider.Oracle.csproj | 6 ++-- .../FreeSql.Provider.PostgreSQL.csproj | 8 ++--- .../FreeSql.Provider.ShenTong.csproj | 2 +- .../Curd/SqlServerDelete.cs | 4 +-- .../Curd/SqlServerInsert.cs | 8 ++--- .../Curd/SqlServerUpdate.cs | 4 +-- .../FreeSql.Provider.SqlServer.csproj | 10 +++---- ...FreeSql.Provider.SqlServerForSystem.csproj | 6 ++-- .../FreeSql.Provider.Sqlite.csproj | 2 +- 36 files changed, 104 insertions(+), 77 deletions(-) diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj index 46c1f9de..a6f778a8 100644 --- a/Examples/dbcontext_01/dbcontext_01.csproj +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -3,11 +3,12 @@ net5.0 InProcess - f2b3f543-99d4-4be7-b894-6df3c6cbad7e - dbcontext_01.xml + dbcontext_01.xml + 3 + 1701;1702;1591 diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index 975c1222..f78e0029 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj index 68bd12dd..00d58516 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现实体类属性为对象时,以JSON形式映射存储. diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index a8d05a60..b6ab2917 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;netstandard2.1;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj index d42f4d90..7c666ab2 100644 --- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj +++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 扩展包,实现 linq queryable 和 linq to sql 语法进行开发. diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index 131eb90f..235d341f 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -12,7 +12,7 @@ 使用 FreeSql 快速生成数据库的实体类,安装:dotnet tool install -g FreeSql.Generator https://github.com/2881099/FreeSql https://github.com/2881099/FreeSql - 2.0.100 + 2.0.101 FreeSql DbFirst 实体生成器 diff --git a/FreeSql.All/FreeSql.All.csproj b/FreeSql.All/FreeSql.All.csproj index e93956ae..17ac79e2 100644 --- a/FreeSql.All/FreeSql.All.csproj +++ b/FreeSql.All/FreeSql.All.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 全家桶,懒人专用 diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 96ddbf44..cc1e7e7d 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b3c14870..e4208f1f 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -502,5 +502,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index ef138d95..511757b7 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net50;netcoreapp31;netcoreapp21;net45;net40 - 2.0.100 + 2.0.101 FreeSql;ncc;YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/Access, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index e67d2aa5..0b4d3e53 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs index 9dd324e6..3768615a 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest4.cs @@ -13,9 +13,38 @@ namespace FreeSql.Tests { public class UnitTest4 { + class ts_lawsuit + { + public Guid id { get; set; } + public Guid lawsuit_member_id { get; set; } + public Guid lawsuit_memberObligee_id { get; set; } + + public ts_lawsuit_member ts_lawsuit_member { get; set; } + public ts_lawsuit_member ts_lawsuit_memberObligee { get; set; } + + } + class ts_lawsuit_member + { + public Guid id { get; set; } + public string title { get; set; } + } + [Fact] public void VersionByte() { + var ts_lawsuititem = new ts_lawsuit { id = Guid.NewGuid(), lawsuit_memberObligee_id = Guid.NewGuid(), lawsuit_member_id = Guid.NewGuid() }; + g.mysql.Insert(new[] + { + new ts_lawsuit_member{id = ts_lawsuititem.lawsuit_member_id, title = "ts_lawsuit_member_title"}, + new ts_lawsuit_member{id = ts_lawsuititem.lawsuit_memberObligee_id, title = "ts_lawsuit_memberObligee_title"} + }).ExecuteAffrows(); + g.mysql.Insert(ts_lawsuititem).ExecuteAffrows(); + + var xxx = g.mysql.Select() + .LeftJoin(a => a.ts_lawsuit_member.id == a.lawsuit_member_id) + .LeftJoin(a => a.ts_lawsuit_memberObligee.id == a.lawsuit_memberObligee_id) + .First(); + g.sqlserver.Insert(new AppSettingII { diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index f47f3eb2..80e7fb4e 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 翰高, And Access diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 622ed4bc..06028c6e 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -524,19 +524,6 @@ namespace FreeSql.Internal var isLazy = vp != null && vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName); AddTableRef(common, trytb, pnv, isLazy, vp, cscode); - if (trytb.GetTableRef(pnv.Name, false) == null) - { - trytb.ColumnsByCsIgnore.Add(pnv.Name, new ColumnInfo - { - Table = trytb, - CsName = pnv.Name, - CsType = pnv.PropertyType, - Attribute = new ColumnAttribute - { - IsIgnore = true - } - }); - } } if (cscode?.Length > cscodeLength) { @@ -1620,8 +1607,12 @@ namespace FreeSql.Internal continue; } ColumnInfo trycol = null; - var readType = typetb?.ColumnsByCs.TryGetValue(prop.Name, out trycol) == true ? trycol.Attribute.MapType : prop.PropertyType; - + if (typetb != null && typetb.ColumnsByCs.TryGetValue(prop.Name, out trycol) == false) + { + ++propIndex; + continue; + } + var readType = trycol?.Attribute.MapType ?? prop.PropertyType; var ispkExp = new List(); var propGetSetMethod = prop.GetSetMethod(true); Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(MethodDataReaderGetValue, new Expression[] { commonUtilExp, rowExp, tryidxExp })); diff --git a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj index 41e18a07..8720d7b6 100644 --- a/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj +++ b/Providers/FreeSql.Provider.Dameng/FreeSql.Provider.Dameng.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 达梦数据库 Ado.net (DmProvider) diff --git a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj index 0776fe1c..52cf867f 100644 --- a/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj +++ b/Providers/FreeSql.Provider.Firebird/FreeSql.Provider.Firebird.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Firebird diff --git a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj index 88f6ba01..30d9d049 100644 --- a/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj +++ b/Providers/FreeSql.Provider.KingbaseES/FreeSql.Provider.KingbaseES.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 人大金仓数据库 Ado.Net (Kdbndp) diff --git a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj index debe8a3c..775d92c7 100644 --- a/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj +++ b/Providers/FreeSql.Provider.MsAccess/FreeSql.Provider.MsAccess.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Ms Access 实现 diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs index ecc9038a..980a9b62 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlDelete.cs @@ -44,7 +44,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -85,7 +85,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 23f8e59e..507cf3ff 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -59,7 +59,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -95,7 +95,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -128,7 +128,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -164,7 +164,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs index e1196549..0e6177b4 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlUpdate.cs @@ -58,7 +58,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -139,7 +139,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs index dbf05870..8c3a5dcf 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/OnDuplicateKeyUpdate.cs @@ -124,7 +124,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -153,7 +153,7 @@ namespace FreeSql.MySql.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 7f078cbd..015b9cfc 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452;net451;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 MySql 5.6,Ado.Net 驱动是 MySql.Data(Oracle官方) @@ -28,7 +28,6 @@ - diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 3e0ba464..92fd9750 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0;net50;net45 2.0.101 true FreeSql;ncc;YeXiangQin diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs index e24ecc00..3a43ed35 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSqlMySqlConnectorGlobalExtensions.cs @@ -98,11 +98,11 @@ public static class FreeSqlMySqlConnectorGlobalExtensions var dt = that.ToDataTable(); if (dt.Rows.Count == 0) return; - Func writeToServer = bulkCopy => + Func writeToServer = async bulkCopy => { if (bulkCopyTimeout.HasValue) bulkCopy.BulkCopyTimeout = bulkCopyTimeout.Value; bulkCopy.DestinationTableName = dt.TableName; - return bulkCopy.WriteToServerAsync(dt, cancellationToken); + await bulkCopy.WriteToServerAsync(dt, cancellationToken); }; try diff --git a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj index 6f42497e..9b8bd0c6 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj +++ b/Providers/FreeSql.Provider.Odbc/FreeSql.Provider.Odbc.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库 Odbc 实现,基于 {Oracle}、{SQL Server}、{MySQL ODBC 8.0 Unicode Driver}、{PostgreSQL Unicode(x64)}、{DM8 ODBC Driver} 专用访问实现,以及通用 Odbc 访问所有数据库 diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index abd8a788..f93d1852 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -186,7 +186,7 @@ namespace FreeSql.Oracle.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -210,7 +210,7 @@ namespace FreeSql.Oracle.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -255,7 +255,7 @@ namespace FreeSql.Oracle.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -279,7 +279,7 @@ namespace FreeSql.Oracle.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 89c77d53..75114dfb 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -1,8 +1,8 @@  - netstandard2.0;net45;net40 - 2.0.100 + netstandard2.0;net50;net45;net40 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Oracle 11 @@ -25,7 +25,7 @@ - + diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 4433465a..50a47827 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net461;net452;net451;net45 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 @@ -30,10 +30,9 @@ - - + + - @@ -41,7 +40,6 @@ net45 - nts diff --git a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj index 47c1f1a5..2d60205d 100644 --- a/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj +++ b/Providers/FreeSql.Provider.ShenTong/FreeSql.Provider.ShenTong.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 神舟通用数据库 7.0.8 diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs index d7a9fe92..4291e811 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerDelete.cs @@ -49,7 +49,7 @@ namespace FreeSql.SqlServer.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -95,7 +95,7 @@ namespace FreeSql.SqlServer.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index fca5e0b8..0609ff57 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -47,7 +47,7 @@ namespace FreeSql.SqlServer.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -98,7 +98,7 @@ namespace FreeSql.SqlServer.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -131,7 +131,7 @@ namespace FreeSql.SqlServer.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -182,7 +182,7 @@ namespace FreeSql.SqlServer.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs index b70438d6..abeaa77c 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerUpdate.cs @@ -57,7 +57,7 @@ namespace FreeSql.SqlServer.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -141,7 +141,7 @@ namespace FreeSql.SqlServer.Curd catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 6c95158e..072cd0e3 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -1,8 +1,8 @@  - netstandard2.0;net451;net45;net40 - 2.0.100 + netstandard2.0;net50;net451;net45;net40 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -28,15 +28,15 @@ - - + + - + microsoft diff --git a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj index 18f4e134..973bd16d 100644 --- a/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj +++ b/Providers/FreeSql.Provider.SqlServerForSystem/FreeSql.Provider.SqlServerForSystem.csproj @@ -1,8 +1,8 @@  - netstandard2.0;net451;net45;net40 - 2.0.100 + netstandard2.0;net50;net451;net45;net40 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 System.Data.SqlClient + SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next @@ -25,7 +25,7 @@ - + diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index d60e06e5..d4a77874 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45;net40 - 2.0.100 + 2.0.101 true FreeSql;ncc;YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0,支持 .NetCore、.NetFramework、Xamarin From cf555ae5e778172d2caee779a88a8b0e57ed58cb Mon Sep 17 00:00:00 2001 From: alex chow Date: Fri, 27 Nov 2020 01:33:20 +0100 Subject: [PATCH 1029/1029] =?UTF-8?q?=E6=B7=BB=E5=8A=A0xamarinFormApp?= =?UTF-8?q?=E4=BE=8B=E5=AD=90,=E5=AE=89=E5=8D=93,iOS,WPF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xamarinFormApp/xamarinForm.Wpf/App.config | 6 + .../xamarinFormApp/xamarinForm.Wpf/App.xaml | 9 + .../xamarinForm.Wpf/App.xaml.cs | 17 + .../xamarinForm.Wpf/MainWindow.xaml | 13 + .../xamarinForm.Wpf/MainWindow.xaml.cs | 32 + .../Properties/AssemblyInfo.cs | 55 + .../Properties/Resources.Designer.cs | 70 + .../xamarinForm.Wpf/Properties/Resources.resx | 117 + .../Properties/Settings.Designer.cs | 29 + .../Properties/Settings.settings | 7 + .../xamarinForm.Wpf/xamarinForm.Wpf.csproj | 109 + .../Assets/AboutAssets.txt | 19 + .../xamarinFormApp.Android/MainActivity.cs | 33 + .../Properties/AndroidManifest.xml | 6 + .../Properties/AssemblyInfo.cs | 30 + .../Resources/AboutResources.txt | 50 + .../Resources/Resource.designer.cs | 14056 ++++++++++++++++ .../Resources/drawable/icon_about.png | Bin 0 -> 518 bytes .../Resources/drawable/icon_feed.png | Bin 0 -> 415 bytes .../Resources/drawable/xamarin_logo.png | Bin 0 -> 21481 bytes .../Resources/layout/Tabbar.xml | 11 + .../Resources/layout/Toolbar.xml | 9 + .../Resources/mipmap-anydpi-v26/icon.xml | 5 + .../mipmap-anydpi-v26/icon_round.xml | 5 + .../Resources/mipmap-hdpi/icon.png | Bin 0 -> 4754 bytes .../mipmap-hdpi/launcher_foreground.png | Bin 0 -> 11695 bytes .../Resources/mipmap-mdpi/icon.png | Bin 0 -> 2807 bytes .../mipmap-mdpi/launcher_foreground.png | Bin 0 -> 6439 bytes .../Resources/mipmap-xhdpi/icon.png | Bin 0 -> 7028 bytes .../mipmap-xhdpi/launcher_foreground.png | Bin 0 -> 17898 bytes .../Resources/mipmap-xxhdpi/icon.png | Bin 0 -> 12827 bytes .../mipmap-xxhdpi/launcher_foreground.png | Bin 0 -> 33484 bytes .../Resources/mipmap-xxxhdpi/icon.png | Bin 0 -> 19380 bytes .../mipmap-xxxhdpi/launcher_foreground.png | Bin 0 -> 52285 bytes .../Resources/values/colors.xml | 7 + .../Resources/values/styles.xml | 18 + .../xamarinFormApp.Android.csproj | 115 + .../xamarinFormApp.iOS/AppDelegate.cs | 32 + .../AppIcon.appiconset/Contents.json | 117 + .../AppIcon.appiconset/Icon1024.png | Bin 0 -> 70429 bytes .../AppIcon.appiconset/Icon120.png | Bin 0 -> 3773 bytes .../AppIcon.appiconset/Icon152.png | Bin 0 -> 4750 bytes .../AppIcon.appiconset/Icon167.png | Bin 0 -> 4692 bytes .../AppIcon.appiconset/Icon180.png | Bin 0 -> 5192 bytes .../AppIcon.appiconset/Icon20.png | Bin 0 -> 1313 bytes .../AppIcon.appiconset/Icon29.png | Bin 0 -> 845 bytes .../AppIcon.appiconset/Icon40.png | Bin 0 -> 1101 bytes .../AppIcon.appiconset/Icon58.png | Bin 0 -> 1761 bytes .../AppIcon.appiconset/Icon60.png | Bin 0 -> 2537 bytes .../AppIcon.appiconset/Icon76.png | Bin 0 -> 2332 bytes .../AppIcon.appiconset/Icon80.png | Bin 0 -> 2454 bytes .../AppIcon.appiconset/Icon87.png | Bin 0 -> 2758 bytes .../xamarinFormApp.iOS/Entitlements.plist | 7 + .../xamarinFormApp.iOS/Info.plist | 38 + .../xamarinFormApp/xamarinFormApp.iOS/Main.cs | 20 + .../Properties/AssemblyInfo.cs | 36 + .../Resources/Default-568h@2x.png | Bin 0 -> 8884 bytes .../Resources/Default-Portrait.png | Bin 0 -> 10710 bytes .../Resources/Default-Portrait@2x.png | Bin 0 -> 34540 bytes .../xamarinFormApp.iOS/Resources/Default.png | Bin 0 -> 7243 bytes .../Resources/Default@2x.png | Bin 0 -> 8368 bytes .../Resources/LaunchScreen.storyboard | 39 + .../Resources/icon_about.png | Bin 0 -> 518 bytes .../Resources/icon_about@2x.png | Bin 0 -> 1137 bytes .../Resources/icon_about@3x.png | Bin 0 -> 2019 bytes .../Resources/icon_feed.png | Bin 0 -> 415 bytes .../Resources/icon_feed@2x.png | Bin 0 -> 863 bytes .../Resources/icon_feed@3x.png | Bin 0 -> 1400 bytes .../Resources/xamarin_logo.png | Bin 0 -> 4250 bytes .../Resources/xamarin_logo@2x.png | Bin 0 -> 9337 bytes .../Resources/xamarin_logo@3x.png | Bin 0 -> 21481 bytes .../xamarinFormApp.iOS.csproj | 145 + Examples/xamarinFormApp/xamarinFormApp.sln | 97 + .../xamarinFormApp/xamarinFormApp/App.xaml | 32 + .../xamarinFormApp/xamarinFormApp/App.xaml.cs | 95 + .../xamarinFormApp/AppShell.xaml | 46 + .../xamarinFormApp/AppShell.xaml.cs | 19 + .../xamarinFormApp/AssemblyInfo.cs | 3 + .../xamarinFormApp/GettingStarted.txt | 34 + .../xamarinFormApp/Models/Item.cs | 15 + .../xamarinFormApp/Services/IDataStore.cs | 15 + .../xamarinFormApp/Services/MockDataStore.cs | 65 + .../ViewModels/AboutViewModel.cs | 18 + .../ViewModels/BaseViewModel.cs | 56 + .../ViewModels/ItemDetailViewModel.cs | 57 + .../ViewModels/ItemsViewModel.cs | 86 + .../ViewModels/LoginViewModel.cs | 24 + .../ViewModels/NewItemViewModel.cs | 65 + .../xamarinFormApp/Views/AboutPage.xaml | 52 + .../xamarinFormApp/Views/AboutPage.xaml.cs | 15 + .../xamarinFormApp/Views/ItemDetailPage.xaml | 14 + .../Views/ItemDetailPage.xaml.cs | 15 + .../xamarinFormApp/Views/ItemsPage.xaml | 44 + .../xamarinFormApp/Views/ItemsPage.xaml.cs | 32 + .../xamarinFormApp/Views/LoginPage.xaml | 14 + .../xamarinFormApp/Views/LoginPage.xaml.cs | 21 + .../xamarinFormApp/Views/NewItemPage.xaml | 22 + .../xamarinFormApp/Views/NewItemPage.xaml.cs | 22 + .../xamarinFormApp/xamarinFormApp.csproj | 15 + 99 files changed, 16255 insertions(+) create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/App.config create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/App.xaml create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/App.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/MainWindow.xaml create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/MainWindow.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/Properties/AssemblyInfo.cs create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Resources.Designer.cs create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Resources.resx create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Settings.Designer.cs create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Settings.settings create mode 100644 Examples/xamarinFormApp/xamarinForm.Wpf/xamarinForm.Wpf.csproj create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Assets/AboutAssets.txt create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/MainActivity.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Properties/AndroidManifest.xml create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Properties/AssemblyInfo.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/AboutResources.txt create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/Resource.designer.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/drawable/icon_about.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/drawable/icon_feed.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/drawable/xamarin_logo.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/layout/Tabbar.xml create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/layout/Toolbar.xml create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-anydpi-v26/icon.xml create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-anydpi-v26/icon_round.xml create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-hdpi/icon.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-hdpi/launcher_foreground.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-mdpi/icon.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-mdpi/launcher_foreground.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-xhdpi/icon.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-xhdpi/launcher_foreground.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-xxhdpi/icon.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-xxhdpi/launcher_foreground.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-xxxhdpi/icon.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/values/colors.xml create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/Resources/values/styles.xml create mode 100644 Examples/xamarinFormApp/xamarinFormApp.Android/xamarinFormApp.Android.csproj create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/AppDelegate.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Entitlements.plist create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Info.plist create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Main.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Properties/AssemblyInfo.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default-568h@2x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default-Portrait.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default-Portrait@2x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default@2x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/LaunchScreen.storyboard create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about@2x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about@3x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_feed.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_feed@2x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_feed@3x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/xamarin_logo.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/xamarin_logo@2x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/xamarin_logo@3x.png create mode 100644 Examples/xamarinFormApp/xamarinFormApp.iOS/xamarinFormApp.iOS.csproj create mode 100644 Examples/xamarinFormApp/xamarinFormApp.sln create mode 100644 Examples/xamarinFormApp/xamarinFormApp/App.xaml create mode 100644 Examples/xamarinFormApp/xamarinFormApp/App.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/AppShell.xaml create mode 100644 Examples/xamarinFormApp/xamarinFormApp/AppShell.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/AssemblyInfo.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/GettingStarted.txt create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Models/Item.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Services/IDataStore.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Services/MockDataStore.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/ViewModels/AboutViewModel.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/ViewModels/BaseViewModel.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/ViewModels/ItemDetailViewModel.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/ViewModels/ItemsViewModel.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/ViewModels/LoginViewModel.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/ViewModels/NewItemViewModel.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/AboutPage.xaml create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/AboutPage.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/ItemDetailPage.xaml create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/ItemDetailPage.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/ItemsPage.xaml create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/ItemsPage.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/LoginPage.xaml create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/LoginPage.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/NewItemPage.xaml create mode 100644 Examples/xamarinFormApp/xamarinFormApp/Views/NewItemPage.xaml.cs create mode 100644 Examples/xamarinFormApp/xamarinFormApp/xamarinFormApp.csproj diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/App.config b/Examples/xamarinFormApp/xamarinForm.Wpf/App.config new file mode 100644 index 00000000..56efbc7b --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/App.xaml b/Examples/xamarinFormApp/xamarinForm.Wpf/App.xaml new file mode 100644 index 00000000..2b4d9192 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/App.xaml.cs b/Examples/xamarinFormApp/xamarinForm.Wpf/App.xaml.cs new file mode 100644 index 00000000..cda63518 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace xamarinForm.Wpf +{ + /// + /// App.xaml 的交互逻辑 + /// + public partial class App : Application + { + } +} diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/MainWindow.xaml b/Examples/xamarinFormApp/xamarinForm.Wpf/MainWindow.xaml new file mode 100644 index 00000000..64cc1c6f --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/MainWindow.xaml @@ -0,0 +1,13 @@ + + + + + diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/MainWindow.xaml.cs b/Examples/xamarinFormApp/xamarinForm.Wpf/MainWindow.xaml.cs new file mode 100644 index 00000000..8d33ac6f --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/MainWindow.xaml.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Xamarin.Forms; +using Xamarin.Forms.Platform.WPF; + +namespace xamarinForm.Wpf +{ + /// + /// MainWindow.xaml 的交互逻辑 + /// + public partial class MainWindow : FormsApplicationPage + { + public MainWindow() + { + InitializeComponent(); + Forms.Init(); + LoadApplication(new xamarinFormApp.App()); + } + } +} diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/AssemblyInfo.cs b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..b8721468 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("xamarinForm.Wpf")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("xamarinForm.Wpf")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +//若要开始生成可本地化的应用程序,请设置 +//.csproj 文件中的 CultureYouAreCodingWith +//例如,如果您在源文件中使用的是美国英语, +//使用的是美国英语,请将 设置为 en-US。 然后取消 +//对以下 NeutralResourceLanguage 特性的注释。 更新 +//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。 + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //主题特定资源词典所处位置 + //(未在页面中找到资源时使用, + //或应用程序资源字典中找到时使用) + ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 + //(未在页面中找到资源时使用, + //、应用程序或任何主题专用资源字典中找到时使用) +)] + + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Resources.Designer.cs b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Resources.Designer.cs new file mode 100644 index 00000000..57797d3c --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Resources.Designer.cs @@ -0,0 +1,70 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本: 4.0.30319.42000 +// +// 对此文件的更改可能导致不正确的行为,如果 +// 重新生成代码,则所做更改将丢失。 +// +//------------------------------------------------------------------------------ + + +namespace xamarinForm.Wpf.Properties +{ + /// + /// 强类型资源类,用于查找本地化字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// 返回此类使用的缓存 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("xamarinForm.Wpf.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Resources.resx b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Settings.Designer.cs b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Settings.Designer.cs new file mode 100644 index 00000000..1d307d2b --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Settings.Designer.cs @@ -0,0 +1,29 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +namespace xamarinForm.Wpf.Properties +{ + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Settings.settings b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Settings.settings new file mode 100644 index 00000000..033d7a5e --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinForm.Wpf/xamarinForm.Wpf.csproj b/Examples/xamarinFormApp/xamarinForm.Wpf/xamarinForm.Wpf.csproj new file mode 100644 index 00000000..1f06a30e --- /dev/null +++ b/Examples/xamarinFormApp/xamarinForm.Wpf/xamarinForm.Wpf.csproj @@ -0,0 +1,109 @@ + + + + + Debug + AnyCPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06} + WinExe + xamarinForm.Wpf + xamarinForm.Wpf + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + 4.8.0.1687 + + + + + {e4094717-ed1a-4174-8d86-a65d2ad1380c} + xamarinFormApp + + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Assets/AboutAssets.txt b/Examples/xamarinFormApp/xamarinFormApp.Android/Assets/AboutAssets.txt new file mode 100644 index 00000000..072563f8 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Assets/AboutAssets.txt @@ -0,0 +1,19 @@ +Any raw assets you want to be deployed with your application can be placed in +this directory (and child directories) and given a Build Action of "AndroidAsset". + +These files will be deployed with your package and will be accessible using Android's +AssetManager, like this: + +public class ReadAsset : Activity +{ + protected override void OnCreate (Bundle bundle) + { + base.OnCreate (bundle); + + InputStream input = Assets.Open ("my_asset.txt"); + } +} + +Additionally, some Android functions will automatically load asset files: + +Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/MainActivity.cs b/Examples/xamarinFormApp/xamarinFormApp.Android/MainActivity.cs new file mode 100644 index 00000000..60cfb4d8 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/MainActivity.cs @@ -0,0 +1,33 @@ +using System; + +using Android.App; +using Android.Content.PM; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Android.OS; + +namespace xamarinFormApp.Droid +{ + [Activity(Label = "xamarinFormApp", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )] + public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity + { + protected override void OnCreate(Bundle savedInstanceState) + { + TabLayoutResource = Resource.Layout.Tabbar; + ToolbarResource = Resource.Layout.Toolbar; + + base.OnCreate(savedInstanceState); + + Xamarin.Essentials.Platform.Init(this, savedInstanceState); + global::Xamarin.Forms.Forms.Init(this, savedInstanceState); + LoadApplication(new App()); + } + public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) + { + Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); + + base.OnRequestPermissionsResult(requestCode, permissions, grantResults); + } + } +} \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Properties/AndroidManifest.xml b/Examples/xamarinFormApp/xamarinFormApp.Android/Properties/AndroidManifest.xml new file mode 100644 index 00000000..bc36f679 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Properties/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Properties/AssemblyInfo.cs b/Examples/xamarinFormApp/xamarinFormApp.Android/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..ee17ccb5 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Android.App; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("xamarinFormApp.Android")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("xamarinFormApp.Android")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +// Add some common permissions, these can be removed if not needed +[assembly: UsesPermission(Android.Manifest.Permission.Internet)] +[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/AboutResources.txt b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/AboutResources.txt new file mode 100644 index 00000000..cb30f20b --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/AboutResources.txt @@ -0,0 +1,50 @@ +Images, layout descriptions, binary blobs and string dictionaries can be included +in your application as resource files. Various Android APIs are designed to +operate on the resource IDs instead of dealing with images, strings or binary blobs +directly. + +For example, a sample Android app that contains a user interface layout (main.xml), +an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) +would keep its resources in the "Resources" directory of the application: + +Resources/ + drawable-hdpi/ + icon.png + + drawable-ldpi/ + icon.png + + drawable-mdpi/ + icon.png + + layout/ + main.xml + + values/ + strings.xml + +In order to get the build system to recognize Android resources, set the build action to +"AndroidResource". The native Android APIs do not operate directly with filenames, but +instead operate on resource IDs. When you compile an Android application that uses resources, +the build system will package the resources for distribution and generate a class called +"Resource" that contains the tokens for each one of the resources included. For example, +for the above Resources layout, this is what the Resource class would expose: + +public class Resource { + public class drawable { + public const int icon = 0x123; + } + + public class layout { + public const int main = 0x456; + } + + public class strings { + public const int first_string = 0xabc; + public const int second_string = 0xbcd; + } +} + +You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main +to reference the layout/main.xml file, or Resource.strings.first_string to reference the first +string in the dictionary file values/strings.xml. diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/Resource.designer.cs b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/Resource.designer.cs new file mode 100644 index 00000000..4de324a8 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/Resource.designer.cs @@ -0,0 +1,14056 @@ +#pragma warning disable 1591 +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +[assembly: global::Android.Runtime.ResourceDesignerAttribute("xamarinFormApp.Droid.Resource", IsApplication=true)] + +namespace xamarinFormApp.Droid +{ + + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] + public partial class Resource + { + + static Resource() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + public static void UpdateIdValues() + { + global::Xamarin.Essentials.Resource.Attribute.alpha = global::xamarinFormApp.Droid.Resource.Attribute.alpha; + global::Xamarin.Essentials.Resource.Attribute.coordinatorLayoutStyle = global::xamarinFormApp.Droid.Resource.Attribute.coordinatorLayoutStyle; + global::Xamarin.Essentials.Resource.Attribute.font = global::xamarinFormApp.Droid.Resource.Attribute.font; + global::Xamarin.Essentials.Resource.Attribute.fontProviderAuthority = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderAuthority; + global::Xamarin.Essentials.Resource.Attribute.fontProviderCerts = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderCerts; + global::Xamarin.Essentials.Resource.Attribute.fontProviderFetchStrategy = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderFetchStrategy; + global::Xamarin.Essentials.Resource.Attribute.fontProviderFetchTimeout = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderFetchTimeout; + global::Xamarin.Essentials.Resource.Attribute.fontProviderPackage = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderPackage; + global::Xamarin.Essentials.Resource.Attribute.fontProviderQuery = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderQuery; + global::Xamarin.Essentials.Resource.Attribute.fontStyle = global::xamarinFormApp.Droid.Resource.Attribute.fontStyle; + global::Xamarin.Essentials.Resource.Attribute.fontVariationSettings = global::xamarinFormApp.Droid.Resource.Attribute.fontVariationSettings; + global::Xamarin.Essentials.Resource.Attribute.fontWeight = global::xamarinFormApp.Droid.Resource.Attribute.fontWeight; + global::Xamarin.Essentials.Resource.Attribute.keylines = global::xamarinFormApp.Droid.Resource.Attribute.keylines; + global::Xamarin.Essentials.Resource.Attribute.layout_anchor = global::xamarinFormApp.Droid.Resource.Attribute.layout_anchor; + global::Xamarin.Essentials.Resource.Attribute.layout_anchorGravity = global::xamarinFormApp.Droid.Resource.Attribute.layout_anchorGravity; + global::Xamarin.Essentials.Resource.Attribute.layout_behavior = global::xamarinFormApp.Droid.Resource.Attribute.layout_behavior; + global::Xamarin.Essentials.Resource.Attribute.layout_dodgeInsetEdges = global::xamarinFormApp.Droid.Resource.Attribute.layout_dodgeInsetEdges; + global::Xamarin.Essentials.Resource.Attribute.layout_insetEdge = global::xamarinFormApp.Droid.Resource.Attribute.layout_insetEdge; + global::Xamarin.Essentials.Resource.Attribute.layout_keyline = global::xamarinFormApp.Droid.Resource.Attribute.layout_keyline; + global::Xamarin.Essentials.Resource.Attribute.statusBarBackground = global::xamarinFormApp.Droid.Resource.Attribute.statusBarBackground; + global::Xamarin.Essentials.Resource.Attribute.ttcIndex = global::xamarinFormApp.Droid.Resource.Attribute.ttcIndex; + global::Xamarin.Essentials.Resource.Color.browser_actions_bg_grey = global::xamarinFormApp.Droid.Resource.Color.browser_actions_bg_grey; + global::Xamarin.Essentials.Resource.Color.browser_actions_divider_color = global::xamarinFormApp.Droid.Resource.Color.browser_actions_divider_color; + global::Xamarin.Essentials.Resource.Color.browser_actions_text_color = global::xamarinFormApp.Droid.Resource.Color.browser_actions_text_color; + global::Xamarin.Essentials.Resource.Color.browser_actions_title_color = global::xamarinFormApp.Droid.Resource.Color.browser_actions_title_color; + global::Xamarin.Essentials.Resource.Color.notification_action_color_filter = global::xamarinFormApp.Droid.Resource.Color.notification_action_color_filter; + global::Xamarin.Essentials.Resource.Color.notification_icon_bg_color = global::xamarinFormApp.Droid.Resource.Color.notification_icon_bg_color; + global::Xamarin.Essentials.Resource.Color.ripple_material_light = global::xamarinFormApp.Droid.Resource.Color.ripple_material_light; + global::Xamarin.Essentials.Resource.Color.secondary_text_default_material_light = global::xamarinFormApp.Droid.Resource.Color.secondary_text_default_material_light; + global::Xamarin.Essentials.Resource.Dimension.browser_actions_context_menu_max_width = global::xamarinFormApp.Droid.Resource.Dimension.browser_actions_context_menu_max_width; + global::Xamarin.Essentials.Resource.Dimension.browser_actions_context_menu_min_padding = global::xamarinFormApp.Droid.Resource.Dimension.browser_actions_context_menu_min_padding; + global::Xamarin.Essentials.Resource.Dimension.compat_button_inset_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_inset_horizontal_material; + global::Xamarin.Essentials.Resource.Dimension.compat_button_inset_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_inset_vertical_material; + global::Xamarin.Essentials.Resource.Dimension.compat_button_padding_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_padding_horizontal_material; + global::Xamarin.Essentials.Resource.Dimension.compat_button_padding_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_padding_vertical_material; + global::Xamarin.Essentials.Resource.Dimension.compat_control_corner_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_control_corner_material; + global::Xamarin.Essentials.Resource.Dimension.compat_notification_large_icon_max_height = global::xamarinFormApp.Droid.Resource.Dimension.compat_notification_large_icon_max_height; + global::Xamarin.Essentials.Resource.Dimension.compat_notification_large_icon_max_width = global::xamarinFormApp.Droid.Resource.Dimension.compat_notification_large_icon_max_width; + global::Xamarin.Essentials.Resource.Dimension.notification_action_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_action_icon_size; + global::Xamarin.Essentials.Resource.Dimension.notification_action_text_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_action_text_size; + global::Xamarin.Essentials.Resource.Dimension.notification_big_circle_margin = global::xamarinFormApp.Droid.Resource.Dimension.notification_big_circle_margin; + global::Xamarin.Essentials.Resource.Dimension.notification_content_margin_start = global::xamarinFormApp.Droid.Resource.Dimension.notification_content_margin_start; + global::Xamarin.Essentials.Resource.Dimension.notification_large_icon_height = global::xamarinFormApp.Droid.Resource.Dimension.notification_large_icon_height; + global::Xamarin.Essentials.Resource.Dimension.notification_large_icon_width = global::xamarinFormApp.Droid.Resource.Dimension.notification_large_icon_width; + global::Xamarin.Essentials.Resource.Dimension.notification_main_column_padding_top = global::xamarinFormApp.Droid.Resource.Dimension.notification_main_column_padding_top; + global::Xamarin.Essentials.Resource.Dimension.notification_media_narrow_margin = global::xamarinFormApp.Droid.Resource.Dimension.notification_media_narrow_margin; + global::Xamarin.Essentials.Resource.Dimension.notification_right_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_right_icon_size; + global::Xamarin.Essentials.Resource.Dimension.notification_right_side_padding_top = global::xamarinFormApp.Droid.Resource.Dimension.notification_right_side_padding_top; + global::Xamarin.Essentials.Resource.Dimension.notification_small_icon_background_padding = global::xamarinFormApp.Droid.Resource.Dimension.notification_small_icon_background_padding; + global::Xamarin.Essentials.Resource.Dimension.notification_small_icon_size_as_large = global::xamarinFormApp.Droid.Resource.Dimension.notification_small_icon_size_as_large; + global::Xamarin.Essentials.Resource.Dimension.notification_subtext_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_subtext_size; + global::Xamarin.Essentials.Resource.Dimension.notification_top_pad = global::xamarinFormApp.Droid.Resource.Dimension.notification_top_pad; + global::Xamarin.Essentials.Resource.Dimension.notification_top_pad_large_text = global::xamarinFormApp.Droid.Resource.Dimension.notification_top_pad_large_text; + global::Xamarin.Essentials.Resource.Drawable.notification_action_background = global::xamarinFormApp.Droid.Resource.Drawable.notification_action_background; + global::Xamarin.Essentials.Resource.Drawable.notification_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg; + global::Xamarin.Essentials.Resource.Drawable.notification_bg_low = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low; + global::Xamarin.Essentials.Resource.Drawable.notification_bg_low_normal = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low_normal; + global::Xamarin.Essentials.Resource.Drawable.notification_bg_low_pressed = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low_pressed; + global::Xamarin.Essentials.Resource.Drawable.notification_bg_normal = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_normal; + global::Xamarin.Essentials.Resource.Drawable.notification_bg_normal_pressed = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_normal_pressed; + global::Xamarin.Essentials.Resource.Drawable.notification_icon_background = global::xamarinFormApp.Droid.Resource.Drawable.notification_icon_background; + global::Xamarin.Essentials.Resource.Drawable.notification_template_icon_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_template_icon_bg; + global::Xamarin.Essentials.Resource.Drawable.notification_template_icon_low_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_template_icon_low_bg; + global::Xamarin.Essentials.Resource.Drawable.notification_tile_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_tile_bg; + global::Xamarin.Essentials.Resource.Drawable.notify_panel_notification_icon_bg = global::xamarinFormApp.Droid.Resource.Drawable.notify_panel_notification_icon_bg; + global::Xamarin.Essentials.Resource.Id.actions = global::xamarinFormApp.Droid.Resource.Id.actions; + global::Xamarin.Essentials.Resource.Id.action_container = global::xamarinFormApp.Droid.Resource.Id.action_container; + global::Xamarin.Essentials.Resource.Id.action_divider = global::xamarinFormApp.Droid.Resource.Id.action_divider; + global::Xamarin.Essentials.Resource.Id.action_image = global::xamarinFormApp.Droid.Resource.Id.action_image; + global::Xamarin.Essentials.Resource.Id.action_text = global::xamarinFormApp.Droid.Resource.Id.action_text; + global::Xamarin.Essentials.Resource.Id.all = global::xamarinFormApp.Droid.Resource.Id.all; + global::Xamarin.Essentials.Resource.Id.async = global::xamarinFormApp.Droid.Resource.Id.async; + global::Xamarin.Essentials.Resource.Id.blocking = global::xamarinFormApp.Droid.Resource.Id.blocking; + global::Xamarin.Essentials.Resource.Id.bottom = global::xamarinFormApp.Droid.Resource.Id.bottom; + global::Xamarin.Essentials.Resource.Id.browser_actions_header_text = global::xamarinFormApp.Droid.Resource.Id.browser_actions_header_text; + global::Xamarin.Essentials.Resource.Id.browser_actions_menu_items = global::xamarinFormApp.Droid.Resource.Id.browser_actions_menu_items; + global::Xamarin.Essentials.Resource.Id.browser_actions_menu_item_icon = global::xamarinFormApp.Droid.Resource.Id.browser_actions_menu_item_icon; + global::Xamarin.Essentials.Resource.Id.browser_actions_menu_item_text = global::xamarinFormApp.Droid.Resource.Id.browser_actions_menu_item_text; + global::Xamarin.Essentials.Resource.Id.browser_actions_menu_view = global::xamarinFormApp.Droid.Resource.Id.browser_actions_menu_view; + global::Xamarin.Essentials.Resource.Id.center = global::xamarinFormApp.Droid.Resource.Id.center; + global::Xamarin.Essentials.Resource.Id.center_horizontal = global::xamarinFormApp.Droid.Resource.Id.center_horizontal; + global::Xamarin.Essentials.Resource.Id.center_vertical = global::xamarinFormApp.Droid.Resource.Id.center_vertical; + global::Xamarin.Essentials.Resource.Id.chronometer = global::xamarinFormApp.Droid.Resource.Id.chronometer; + global::Xamarin.Essentials.Resource.Id.clip_horizontal = global::xamarinFormApp.Droid.Resource.Id.clip_horizontal; + global::Xamarin.Essentials.Resource.Id.clip_vertical = global::xamarinFormApp.Droid.Resource.Id.clip_vertical; + global::Xamarin.Essentials.Resource.Id.end = global::xamarinFormApp.Droid.Resource.Id.end; + global::Xamarin.Essentials.Resource.Id.fill = global::xamarinFormApp.Droid.Resource.Id.fill; + global::Xamarin.Essentials.Resource.Id.fill_horizontal = global::xamarinFormApp.Droid.Resource.Id.fill_horizontal; + global::Xamarin.Essentials.Resource.Id.fill_vertical = global::xamarinFormApp.Droid.Resource.Id.fill_vertical; + global::Xamarin.Essentials.Resource.Id.forever = global::xamarinFormApp.Droid.Resource.Id.forever; + global::Xamarin.Essentials.Resource.Id.icon = global::xamarinFormApp.Droid.Resource.Id.icon; + global::Xamarin.Essentials.Resource.Id.icon_group = global::xamarinFormApp.Droid.Resource.Id.icon_group; + global::Xamarin.Essentials.Resource.Id.info = global::xamarinFormApp.Droid.Resource.Id.info; + global::Xamarin.Essentials.Resource.Id.italic = global::xamarinFormApp.Droid.Resource.Id.italic; + global::Xamarin.Essentials.Resource.Id.left = global::xamarinFormApp.Droid.Resource.Id.left; + global::Xamarin.Essentials.Resource.Id.line1 = global::xamarinFormApp.Droid.Resource.Id.line1; + global::Xamarin.Essentials.Resource.Id.line3 = global::xamarinFormApp.Droid.Resource.Id.line3; + global::Xamarin.Essentials.Resource.Id.none = global::xamarinFormApp.Droid.Resource.Id.none; + global::Xamarin.Essentials.Resource.Id.normal = global::xamarinFormApp.Droid.Resource.Id.normal; + global::Xamarin.Essentials.Resource.Id.notification_background = global::xamarinFormApp.Droid.Resource.Id.notification_background; + global::Xamarin.Essentials.Resource.Id.notification_main_column = global::xamarinFormApp.Droid.Resource.Id.notification_main_column; + global::Xamarin.Essentials.Resource.Id.notification_main_column_container = global::xamarinFormApp.Droid.Resource.Id.notification_main_column_container; + global::Xamarin.Essentials.Resource.Id.right = global::xamarinFormApp.Droid.Resource.Id.right; + global::Xamarin.Essentials.Resource.Id.right_icon = global::xamarinFormApp.Droid.Resource.Id.right_icon; + global::Xamarin.Essentials.Resource.Id.right_side = global::xamarinFormApp.Droid.Resource.Id.right_side; + global::Xamarin.Essentials.Resource.Id.start = global::xamarinFormApp.Droid.Resource.Id.start; + global::Xamarin.Essentials.Resource.Id.tag_transition_group = global::xamarinFormApp.Droid.Resource.Id.tag_transition_group; + global::Xamarin.Essentials.Resource.Id.tag_unhandled_key_event_manager = global::xamarinFormApp.Droid.Resource.Id.tag_unhandled_key_event_manager; + global::Xamarin.Essentials.Resource.Id.tag_unhandled_key_listeners = global::xamarinFormApp.Droid.Resource.Id.tag_unhandled_key_listeners; + global::Xamarin.Essentials.Resource.Id.text = global::xamarinFormApp.Droid.Resource.Id.text; + global::Xamarin.Essentials.Resource.Id.text2 = global::xamarinFormApp.Droid.Resource.Id.text2; + global::Xamarin.Essentials.Resource.Id.time = global::xamarinFormApp.Droid.Resource.Id.time; + global::Xamarin.Essentials.Resource.Id.title = global::xamarinFormApp.Droid.Resource.Id.title; + global::Xamarin.Essentials.Resource.Id.top = global::xamarinFormApp.Droid.Resource.Id.top; + global::Xamarin.Essentials.Resource.Integer.status_bar_notification_info_maxnum = global::xamarinFormApp.Droid.Resource.Integer.status_bar_notification_info_maxnum; + global::Xamarin.Essentials.Resource.Layout.browser_actions_context_menu_page = global::xamarinFormApp.Droid.Resource.Layout.browser_actions_context_menu_page; + global::Xamarin.Essentials.Resource.Layout.browser_actions_context_menu_row = global::xamarinFormApp.Droid.Resource.Layout.browser_actions_context_menu_row; + global::Xamarin.Essentials.Resource.Layout.notification_action = global::xamarinFormApp.Droid.Resource.Layout.notification_action; + global::Xamarin.Essentials.Resource.Layout.notification_action_tombstone = global::xamarinFormApp.Droid.Resource.Layout.notification_action_tombstone; + global::Xamarin.Essentials.Resource.Layout.notification_template_custom_big = global::xamarinFormApp.Droid.Resource.Layout.notification_template_custom_big; + global::Xamarin.Essentials.Resource.Layout.notification_template_icon_group = global::xamarinFormApp.Droid.Resource.Layout.notification_template_icon_group; + global::Xamarin.Essentials.Resource.Layout.notification_template_part_chronometer = global::xamarinFormApp.Droid.Resource.Layout.notification_template_part_chronometer; + global::Xamarin.Essentials.Resource.Layout.notification_template_part_time = global::xamarinFormApp.Droid.Resource.Layout.notification_template_part_time; + global::Xamarin.Essentials.Resource.String.status_bar_notification_info_overflow = global::xamarinFormApp.Droid.Resource.String.status_bar_notification_info_overflow; + global::Xamarin.Essentials.Resource.Style.TextAppearance_Compat_Notification = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification; + global::Xamarin.Essentials.Resource.Style.TextAppearance_Compat_Notification_Info = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Info; + global::Xamarin.Essentials.Resource.Style.TextAppearance_Compat_Notification_Line2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Line2; + global::Xamarin.Essentials.Resource.Style.TextAppearance_Compat_Notification_Time = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Time; + global::Xamarin.Essentials.Resource.Style.TextAppearance_Compat_Notification_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Title; + global::Xamarin.Essentials.Resource.Style.Widget_Compat_NotificationActionContainer = global::xamarinFormApp.Droid.Resource.Style.Widget_Compat_NotificationActionContainer; + global::Xamarin.Essentials.Resource.Style.Widget_Compat_NotificationActionText = global::xamarinFormApp.Droid.Resource.Style.Widget_Compat_NotificationActionText; + global::Xamarin.Essentials.Resource.Style.Widget_Support_CoordinatorLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Support_CoordinatorLayout; + global::Xamarin.Essentials.Resource.Styleable.ColorStateListItem = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem; + global::Xamarin.Essentials.Resource.Styleable.ColorStateListItem_alpha = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_alpha; + global::Xamarin.Essentials.Resource.Styleable.ColorStateListItem_android_alpha = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_android_alpha; + global::Xamarin.Essentials.Resource.Styleable.ColorStateListItem_android_color = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_android_color; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_keylines = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_keylines; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_Layout = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_Layout_android_layout_gravity = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_android_layout_gravity; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_Layout_layout_anchor = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_anchor; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_Layout_layout_anchorGravity = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_anchorGravity; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_Layout_layout_behavior = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_behavior; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_Layout_layout_dodgeInsetEdges = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_dodgeInsetEdges; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_Layout_layout_insetEdge = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_insetEdge; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_Layout_layout_keyline = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_keyline; + global::Xamarin.Essentials.Resource.Styleable.CoordinatorLayout_statusBarBackground = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_statusBarBackground; + global::Xamarin.Essentials.Resource.Styleable.FontFamily = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_android_font = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_font; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_android_fontStyle = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontStyle; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_android_fontVariationSettings = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontVariationSettings; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_android_fontWeight = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontWeight; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_android_ttcIndex = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_ttcIndex; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_font = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_font; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_fontStyle = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontStyle; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_fontVariationSettings = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontVariationSettings; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_fontWeight = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontWeight; + global::Xamarin.Essentials.Resource.Styleable.FontFamilyFont_ttcIndex = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_ttcIndex; + global::Xamarin.Essentials.Resource.Styleable.FontFamily_fontProviderAuthority = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderAuthority; + global::Xamarin.Essentials.Resource.Styleable.FontFamily_fontProviderCerts = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderCerts; + global::Xamarin.Essentials.Resource.Styleable.FontFamily_fontProviderFetchStrategy = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderFetchStrategy; + global::Xamarin.Essentials.Resource.Styleable.FontFamily_fontProviderFetchTimeout = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderFetchTimeout; + global::Xamarin.Essentials.Resource.Styleable.FontFamily_fontProviderPackage = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderPackage; + global::Xamarin.Essentials.Resource.Styleable.FontFamily_fontProviderQuery = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderQuery; + global::Xamarin.Essentials.Resource.Styleable.GradientColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor; + global::Xamarin.Essentials.Resource.Styleable.GradientColorItem = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem; + global::Xamarin.Essentials.Resource.Styleable.GradientColorItem_android_color = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem_android_color; + global::Xamarin.Essentials.Resource.Styleable.GradientColorItem_android_offset = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem_android_offset; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_centerColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerColor; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_centerX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerX; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_centerY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerY; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_endColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endColor; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_endX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endX; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_endY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endY; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_gradientRadius = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_gradientRadius; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_startColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startColor; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_startX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startX; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_startY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startY; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_tileMode = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_tileMode; + global::Xamarin.Essentials.Resource.Styleable.GradientColor_android_type = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_type; + global::Xamarin.Essentials.Resource.Xml.xamarin_essentials_fileprovider_file_paths = global::xamarinFormApp.Droid.Resource.Xml.xamarin_essentials_fileprovider_file_paths; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_fade_in = global::xamarinFormApp.Droid.Resource.Animation.abc_fade_in; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_fade_out = global::xamarinFormApp.Droid.Resource.Animation.abc_fade_out; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_grow_fade_in_from_bottom = global::xamarinFormApp.Droid.Resource.Animation.abc_grow_fade_in_from_bottom; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_popup_enter = global::xamarinFormApp.Droid.Resource.Animation.abc_popup_enter; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_popup_exit = global::xamarinFormApp.Droid.Resource.Animation.abc_popup_exit; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_shrink_fade_out_from_bottom = global::xamarinFormApp.Droid.Resource.Animation.abc_shrink_fade_out_from_bottom; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_slide_in_bottom = global::xamarinFormApp.Droid.Resource.Animation.abc_slide_in_bottom; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_slide_in_top = global::xamarinFormApp.Droid.Resource.Animation.abc_slide_in_top; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_slide_out_bottom = global::xamarinFormApp.Droid.Resource.Animation.abc_slide_out_bottom; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_slide_out_top = global::xamarinFormApp.Droid.Resource.Animation.abc_slide_out_top; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_tooltip_enter = global::xamarinFormApp.Droid.Resource.Animation.abc_tooltip_enter; + global::Xamarin.Forms.Platform.Android.Resource.Animation.abc_tooltip_exit = global::xamarinFormApp.Droid.Resource.Animation.abc_tooltip_exit; + global::Xamarin.Forms.Platform.Android.Resource.Animation.design_bottom_sheet_slide_in = global::xamarinFormApp.Droid.Resource.Animation.design_bottom_sheet_slide_in; + global::Xamarin.Forms.Platform.Android.Resource.Animation.design_bottom_sheet_slide_out = global::xamarinFormApp.Droid.Resource.Animation.design_bottom_sheet_slide_out; + global::Xamarin.Forms.Platform.Android.Resource.Animation.design_snackbar_in = global::xamarinFormApp.Droid.Resource.Animation.design_snackbar_in; + global::Xamarin.Forms.Platform.Android.Resource.Animation.design_snackbar_out = global::xamarinFormApp.Droid.Resource.Animation.design_snackbar_out; + global::Xamarin.Forms.Platform.Android.Resource.Animation.EnterFromLeft = global::xamarinFormApp.Droid.Resource.Animation.EnterFromLeft; + global::Xamarin.Forms.Platform.Android.Resource.Animation.EnterFromRight = global::xamarinFormApp.Droid.Resource.Animation.EnterFromRight; + global::Xamarin.Forms.Platform.Android.Resource.Animation.ExitToLeft = global::xamarinFormApp.Droid.Resource.Animation.ExitToLeft; + global::Xamarin.Forms.Platform.Android.Resource.Animation.ExitToRight = global::xamarinFormApp.Droid.Resource.Animation.ExitToRight; + global::Xamarin.Forms.Platform.Android.Resource.Animator.design_appbar_state_list_animator = global::xamarinFormApp.Droid.Resource.Animator.design_appbar_state_list_animator; + global::Xamarin.Forms.Platform.Android.Resource.Animator.design_fab_hide_motion_spec = global::xamarinFormApp.Droid.Resource.Animator.design_fab_hide_motion_spec; + global::Xamarin.Forms.Platform.Android.Resource.Animator.design_fab_show_motion_spec = global::xamarinFormApp.Droid.Resource.Animator.design_fab_show_motion_spec; + global::Xamarin.Forms.Platform.Android.Resource.Animator.mtrl_btn_state_list_anim = global::xamarinFormApp.Droid.Resource.Animator.mtrl_btn_state_list_anim; + global::Xamarin.Forms.Platform.Android.Resource.Animator.mtrl_btn_unelevated_state_list_anim = global::xamarinFormApp.Droid.Resource.Animator.mtrl_btn_unelevated_state_list_anim; + global::Xamarin.Forms.Platform.Android.Resource.Animator.mtrl_chip_state_list_anim = global::xamarinFormApp.Droid.Resource.Animator.mtrl_chip_state_list_anim; + global::Xamarin.Forms.Platform.Android.Resource.Animator.mtrl_fab_hide_motion_spec = global::xamarinFormApp.Droid.Resource.Animator.mtrl_fab_hide_motion_spec; + global::Xamarin.Forms.Platform.Android.Resource.Animator.mtrl_fab_show_motion_spec = global::xamarinFormApp.Droid.Resource.Animator.mtrl_fab_show_motion_spec; + global::Xamarin.Forms.Platform.Android.Resource.Animator.mtrl_fab_transformation_sheet_collapse_spec = global::xamarinFormApp.Droid.Resource.Animator.mtrl_fab_transformation_sheet_collapse_spec; + global::Xamarin.Forms.Platform.Android.Resource.Animator.mtrl_fab_transformation_sheet_expand_spec = global::xamarinFormApp.Droid.Resource.Animator.mtrl_fab_transformation_sheet_expand_spec; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarDivider = global::xamarinFormApp.Droid.Resource.Attribute.actionBarDivider; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarItemBackground = global::xamarinFormApp.Droid.Resource.Attribute.actionBarItemBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarPopupTheme = global::xamarinFormApp.Droid.Resource.Attribute.actionBarPopupTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarSize = global::xamarinFormApp.Droid.Resource.Attribute.actionBarSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarSplitStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarSplitStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarTabBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarTabBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarTabStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarTabStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarTabTextStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarTabTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarTheme = global::xamarinFormApp.Droid.Resource.Attribute.actionBarTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionBarWidgetTheme = global::xamarinFormApp.Droid.Resource.Attribute.actionBarWidgetTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionDropDownStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionDropDownStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionLayout = global::xamarinFormApp.Droid.Resource.Attribute.actionLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionMenuTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.actionMenuTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionMenuTextColor = global::xamarinFormApp.Droid.Resource.Attribute.actionMenuTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeBackground = global::xamarinFormApp.Droid.Resource.Attribute.actionModeBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeCloseButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionModeCloseButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeCloseDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeCloseDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeCopyDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeCopyDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeCutDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeCutDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeFindDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeFindDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModePasteDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModePasteDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModePopupWindowStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionModePopupWindowStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeSelectAllDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeSelectAllDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeShareDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeShareDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeSplitBackground = global::xamarinFormApp.Droid.Resource.Attribute.actionModeSplitBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionModeStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionModeWebSearchDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeWebSearchDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionOverflowButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionOverflowButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionOverflowMenuStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionOverflowMenuStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionProviderClass = global::xamarinFormApp.Droid.Resource.Attribute.actionProviderClass; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.actionViewClass = global::xamarinFormApp.Droid.Resource.Attribute.actionViewClass; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.activityChooserViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.activityChooserViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.alertDialogButtonGroupStyle = global::xamarinFormApp.Droid.Resource.Attribute.alertDialogButtonGroupStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.alertDialogCenterButtons = global::xamarinFormApp.Droid.Resource.Attribute.alertDialogCenterButtons; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.alertDialogStyle = global::xamarinFormApp.Droid.Resource.Attribute.alertDialogStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.alertDialogTheme = global::xamarinFormApp.Droid.Resource.Attribute.alertDialogTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.allowStacking = global::xamarinFormApp.Droid.Resource.Attribute.allowStacking; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.alpha = global::xamarinFormApp.Droid.Resource.Attribute.alpha; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.alphabeticModifiers = global::xamarinFormApp.Droid.Resource.Attribute.alphabeticModifiers; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.arrowHeadLength = global::xamarinFormApp.Droid.Resource.Attribute.arrowHeadLength; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.arrowShaftLength = global::xamarinFormApp.Droid.Resource.Attribute.arrowShaftLength; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.autoCompleteTextViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.autoCompleteTextViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.autoSizeMaxTextSize = global::xamarinFormApp.Droid.Resource.Attribute.autoSizeMaxTextSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.autoSizeMinTextSize = global::xamarinFormApp.Droid.Resource.Attribute.autoSizeMinTextSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.autoSizePresetSizes = global::xamarinFormApp.Droid.Resource.Attribute.autoSizePresetSizes; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.autoSizeStepGranularity = global::xamarinFormApp.Droid.Resource.Attribute.autoSizeStepGranularity; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.autoSizeTextType = global::xamarinFormApp.Droid.Resource.Attribute.autoSizeTextType; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.background = global::xamarinFormApp.Droid.Resource.Attribute.background; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.backgroundSplit = global::xamarinFormApp.Droid.Resource.Attribute.backgroundSplit; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.backgroundStacked = global::xamarinFormApp.Droid.Resource.Attribute.backgroundStacked; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.backgroundTint = global::xamarinFormApp.Droid.Resource.Attribute.backgroundTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.backgroundTintMode = global::xamarinFormApp.Droid.Resource.Attribute.backgroundTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.barLength = global::xamarinFormApp.Droid.Resource.Attribute.barLength; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.behavior_autoHide = global::xamarinFormApp.Droid.Resource.Attribute.behavior_autoHide; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.behavior_fitToContents = global::xamarinFormApp.Droid.Resource.Attribute.behavior_fitToContents; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.behavior_hideable = global::xamarinFormApp.Droid.Resource.Attribute.behavior_hideable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.behavior_overlapTop = global::xamarinFormApp.Droid.Resource.Attribute.behavior_overlapTop; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.behavior_peekHeight = global::xamarinFormApp.Droid.Resource.Attribute.behavior_peekHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.behavior_skipCollapsed = global::xamarinFormApp.Droid.Resource.Attribute.behavior_skipCollapsed; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.borderlessButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.borderlessButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.borderWidth = global::xamarinFormApp.Droid.Resource.Attribute.borderWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.bottomAppBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.bottomAppBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.bottomNavigationStyle = global::xamarinFormApp.Droid.Resource.Attribute.bottomNavigationStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.bottomSheetDialogTheme = global::xamarinFormApp.Droid.Resource.Attribute.bottomSheetDialogTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.bottomSheetStyle = global::xamarinFormApp.Droid.Resource.Attribute.bottomSheetStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxBackgroundColor = global::xamarinFormApp.Droid.Resource.Attribute.boxBackgroundColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxBackgroundMode = global::xamarinFormApp.Droid.Resource.Attribute.boxBackgroundMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxCollapsedPaddingTop = global::xamarinFormApp.Droid.Resource.Attribute.boxCollapsedPaddingTop; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxCornerRadiusBottomEnd = global::xamarinFormApp.Droid.Resource.Attribute.boxCornerRadiusBottomEnd; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxCornerRadiusBottomStart = global::xamarinFormApp.Droid.Resource.Attribute.boxCornerRadiusBottomStart; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxCornerRadiusTopEnd = global::xamarinFormApp.Droid.Resource.Attribute.boxCornerRadiusTopEnd; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxCornerRadiusTopStart = global::xamarinFormApp.Droid.Resource.Attribute.boxCornerRadiusTopStart; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxStrokeColor = global::xamarinFormApp.Droid.Resource.Attribute.boxStrokeColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.boxStrokeWidth = global::xamarinFormApp.Droid.Resource.Attribute.boxStrokeWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonBarButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonBarNegativeButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarNegativeButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonBarNeutralButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarNeutralButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonBarPositiveButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarPositiveButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonGravity = global::xamarinFormApp.Droid.Resource.Attribute.buttonGravity; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonIconDimen = global::xamarinFormApp.Droid.Resource.Attribute.buttonIconDimen; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonPanelSideLayout = global::xamarinFormApp.Droid.Resource.Attribute.buttonPanelSideLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonStyleSmall = global::xamarinFormApp.Droid.Resource.Attribute.buttonStyleSmall; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonTint = global::xamarinFormApp.Droid.Resource.Attribute.buttonTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.buttonTintMode = global::xamarinFormApp.Droid.Resource.Attribute.buttonTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.cardBackgroundColor = global::xamarinFormApp.Droid.Resource.Attribute.cardBackgroundColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.cardCornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.cardCornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.cardElevation = global::xamarinFormApp.Droid.Resource.Attribute.cardElevation; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.cardMaxElevation = global::xamarinFormApp.Droid.Resource.Attribute.cardMaxElevation; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.cardPreventCornerOverlap = global::xamarinFormApp.Droid.Resource.Attribute.cardPreventCornerOverlap; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.cardUseCompatPadding = global::xamarinFormApp.Droid.Resource.Attribute.cardUseCompatPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.cardViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.cardViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.checkboxStyle = global::xamarinFormApp.Droid.Resource.Attribute.checkboxStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.checkedChip = global::xamarinFormApp.Droid.Resource.Attribute.checkedChip; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.checkedIcon = global::xamarinFormApp.Droid.Resource.Attribute.checkedIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.checkedIconEnabled = global::xamarinFormApp.Droid.Resource.Attribute.checkedIconEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.checkedIconVisible = global::xamarinFormApp.Droid.Resource.Attribute.checkedIconVisible; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.checkedTextViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.checkedTextViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipBackgroundColor = global::xamarinFormApp.Droid.Resource.Attribute.chipBackgroundColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipCornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.chipCornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipEndPadding = global::xamarinFormApp.Droid.Resource.Attribute.chipEndPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipGroupStyle = global::xamarinFormApp.Droid.Resource.Attribute.chipGroupStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipIcon = global::xamarinFormApp.Droid.Resource.Attribute.chipIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipIconEnabled = global::xamarinFormApp.Droid.Resource.Attribute.chipIconEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipIconSize = global::xamarinFormApp.Droid.Resource.Attribute.chipIconSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipIconTint = global::xamarinFormApp.Droid.Resource.Attribute.chipIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipIconVisible = global::xamarinFormApp.Droid.Resource.Attribute.chipIconVisible; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipMinHeight = global::xamarinFormApp.Droid.Resource.Attribute.chipMinHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipSpacing = global::xamarinFormApp.Droid.Resource.Attribute.chipSpacing; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipSpacingHorizontal = global::xamarinFormApp.Droid.Resource.Attribute.chipSpacingHorizontal; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipSpacingVertical = global::xamarinFormApp.Droid.Resource.Attribute.chipSpacingVertical; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipStandaloneStyle = global::xamarinFormApp.Droid.Resource.Attribute.chipStandaloneStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipStartPadding = global::xamarinFormApp.Droid.Resource.Attribute.chipStartPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipStrokeColor = global::xamarinFormApp.Droid.Resource.Attribute.chipStrokeColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipStrokeWidth = global::xamarinFormApp.Droid.Resource.Attribute.chipStrokeWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.chipStyle = global::xamarinFormApp.Droid.Resource.Attribute.chipStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.closeIcon = global::xamarinFormApp.Droid.Resource.Attribute.closeIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.closeIconEnabled = global::xamarinFormApp.Droid.Resource.Attribute.closeIconEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.closeIconEndPadding = global::xamarinFormApp.Droid.Resource.Attribute.closeIconEndPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.closeIconSize = global::xamarinFormApp.Droid.Resource.Attribute.closeIconSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.closeIconStartPadding = global::xamarinFormApp.Droid.Resource.Attribute.closeIconStartPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.closeIconTint = global::xamarinFormApp.Droid.Resource.Attribute.closeIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.closeIconVisible = global::xamarinFormApp.Droid.Resource.Attribute.closeIconVisible; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.closeItemLayout = global::xamarinFormApp.Droid.Resource.Attribute.closeItemLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.collapseContentDescription = global::xamarinFormApp.Droid.Resource.Attribute.collapseContentDescription; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.collapsedTitleGravity = global::xamarinFormApp.Droid.Resource.Attribute.collapsedTitleGravity; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.collapsedTitleTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.collapsedTitleTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.collapseIcon = global::xamarinFormApp.Droid.Resource.Attribute.collapseIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.collectionViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.collectionViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.color = global::xamarinFormApp.Droid.Resource.Attribute.color; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorAccent = global::xamarinFormApp.Droid.Resource.Attribute.colorAccent; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorBackgroundFloating = global::xamarinFormApp.Droid.Resource.Attribute.colorBackgroundFloating; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorButtonNormal = global::xamarinFormApp.Droid.Resource.Attribute.colorButtonNormal; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorControlActivated = global::xamarinFormApp.Droid.Resource.Attribute.colorControlActivated; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorControlHighlight = global::xamarinFormApp.Droid.Resource.Attribute.colorControlHighlight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorControlNormal = global::xamarinFormApp.Droid.Resource.Attribute.colorControlNormal; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorError = global::xamarinFormApp.Droid.Resource.Attribute.colorError; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorPrimary = global::xamarinFormApp.Droid.Resource.Attribute.colorPrimary; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorPrimaryDark = global::xamarinFormApp.Droid.Resource.Attribute.colorPrimaryDark; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorSecondary = global::xamarinFormApp.Droid.Resource.Attribute.colorSecondary; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.colorSwitchThumbNormal = global::xamarinFormApp.Droid.Resource.Attribute.colorSwitchThumbNormal; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.commitIcon = global::xamarinFormApp.Droid.Resource.Attribute.commitIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentDescription = global::xamarinFormApp.Droid.Resource.Attribute.contentDescription; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentInsetEnd = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetEnd; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentInsetEndWithActions = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetEndWithActions; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentInsetLeft = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetLeft; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentInsetRight = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetRight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentInsetStart = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetStart; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentInsetStartWithNavigation = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetStartWithNavigation; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentPadding = global::xamarinFormApp.Droid.Resource.Attribute.contentPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentPaddingBottom = global::xamarinFormApp.Droid.Resource.Attribute.contentPaddingBottom; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentPaddingLeft = global::xamarinFormApp.Droid.Resource.Attribute.contentPaddingLeft; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentPaddingRight = global::xamarinFormApp.Droid.Resource.Attribute.contentPaddingRight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentPaddingTop = global::xamarinFormApp.Droid.Resource.Attribute.contentPaddingTop; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.contentScrim = global::xamarinFormApp.Droid.Resource.Attribute.contentScrim; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.controlBackground = global::xamarinFormApp.Droid.Resource.Attribute.controlBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.coordinatorLayoutStyle = global::xamarinFormApp.Droid.Resource.Attribute.coordinatorLayoutStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.cornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.cornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.counterEnabled = global::xamarinFormApp.Droid.Resource.Attribute.counterEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.counterMaxLength = global::xamarinFormApp.Droid.Resource.Attribute.counterMaxLength; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.counterOverflowTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.counterOverflowTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.counterTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.counterTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.customNavigationLayout = global::xamarinFormApp.Droid.Resource.Attribute.customNavigationLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.defaultQueryHint = global::xamarinFormApp.Droid.Resource.Attribute.defaultQueryHint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.dialogCornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.dialogCornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.dialogPreferredPadding = global::xamarinFormApp.Droid.Resource.Attribute.dialogPreferredPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.dialogTheme = global::xamarinFormApp.Droid.Resource.Attribute.dialogTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.displayOptions = global::xamarinFormApp.Droid.Resource.Attribute.displayOptions; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.divider = global::xamarinFormApp.Droid.Resource.Attribute.divider; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.dividerHorizontal = global::xamarinFormApp.Droid.Resource.Attribute.dividerHorizontal; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.dividerPadding = global::xamarinFormApp.Droid.Resource.Attribute.dividerPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.dividerVertical = global::xamarinFormApp.Droid.Resource.Attribute.dividerVertical; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.drawableSize = global::xamarinFormApp.Droid.Resource.Attribute.drawableSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.drawerArrowStyle = global::xamarinFormApp.Droid.Resource.Attribute.drawerArrowStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.dropdownListPreferredItemHeight = global::xamarinFormApp.Droid.Resource.Attribute.dropdownListPreferredItemHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.dropDownListViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.dropDownListViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.editTextBackground = global::xamarinFormApp.Droid.Resource.Attribute.editTextBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.editTextColor = global::xamarinFormApp.Droid.Resource.Attribute.editTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.editTextStyle = global::xamarinFormApp.Droid.Resource.Attribute.editTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.elevation = global::xamarinFormApp.Droid.Resource.Attribute.elevation; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.enforceMaterialTheme = global::xamarinFormApp.Droid.Resource.Attribute.enforceMaterialTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.enforceTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.enforceTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.errorEnabled = global::xamarinFormApp.Droid.Resource.Attribute.errorEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.errorTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.errorTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expandActivityOverflowButtonDrawable = global::xamarinFormApp.Droid.Resource.Attribute.expandActivityOverflowButtonDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expanded = global::xamarinFormApp.Droid.Resource.Attribute.expanded; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expandedTitleGravity = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleGravity; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expandedTitleMargin = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMargin; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expandedTitleMarginBottom = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMarginBottom; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expandedTitleMarginEnd = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMarginEnd; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expandedTitleMarginStart = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMarginStart; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expandedTitleMarginTop = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMarginTop; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.expandedTitleTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fabAlignmentMode = global::xamarinFormApp.Droid.Resource.Attribute.fabAlignmentMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fabCradleMargin = global::xamarinFormApp.Droid.Resource.Attribute.fabCradleMargin; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fabCradleRoundedCornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.fabCradleRoundedCornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fabCradleVerticalOffset = global::xamarinFormApp.Droid.Resource.Attribute.fabCradleVerticalOffset; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fabCustomSize = global::xamarinFormApp.Droid.Resource.Attribute.fabCustomSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fabSize = global::xamarinFormApp.Droid.Resource.Attribute.fabSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fastScrollEnabled = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fastScrollHorizontalThumbDrawable = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollHorizontalThumbDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fastScrollHorizontalTrackDrawable = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollHorizontalTrackDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fastScrollVerticalThumbDrawable = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollVerticalThumbDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fastScrollVerticalTrackDrawable = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollVerticalTrackDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.firstBaselineToTopHeight = global::xamarinFormApp.Droid.Resource.Attribute.firstBaselineToTopHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.floatingActionButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.floatingActionButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.font = global::xamarinFormApp.Droid.Resource.Attribute.font; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontFamily = global::xamarinFormApp.Droid.Resource.Attribute.fontFamily; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontProviderAuthority = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderAuthority; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontProviderCerts = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderCerts; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontProviderFetchStrategy = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderFetchStrategy; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontProviderFetchTimeout = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderFetchTimeout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontProviderPackage = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderPackage; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontProviderQuery = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderQuery; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontStyle = global::xamarinFormApp.Droid.Resource.Attribute.fontStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontVariationSettings = global::xamarinFormApp.Droid.Resource.Attribute.fontVariationSettings; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.fontWeight = global::xamarinFormApp.Droid.Resource.Attribute.fontWeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.foregroundInsidePadding = global::xamarinFormApp.Droid.Resource.Attribute.foregroundInsidePadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.gapBetweenBars = global::xamarinFormApp.Droid.Resource.Attribute.gapBetweenBars; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.goIcon = global::xamarinFormApp.Droid.Resource.Attribute.goIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.headerLayout = global::xamarinFormApp.Droid.Resource.Attribute.headerLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.height = global::xamarinFormApp.Droid.Resource.Attribute.height; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.helperText = global::xamarinFormApp.Droid.Resource.Attribute.helperText; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.helperTextEnabled = global::xamarinFormApp.Droid.Resource.Attribute.helperTextEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.helperTextTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.helperTextTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.hideMotionSpec = global::xamarinFormApp.Droid.Resource.Attribute.hideMotionSpec; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.hideOnContentScroll = global::xamarinFormApp.Droid.Resource.Attribute.hideOnContentScroll; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.hideOnScroll = global::xamarinFormApp.Droid.Resource.Attribute.hideOnScroll; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.hintAnimationEnabled = global::xamarinFormApp.Droid.Resource.Attribute.hintAnimationEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.hintEnabled = global::xamarinFormApp.Droid.Resource.Attribute.hintEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.hintTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.hintTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.homeAsUpIndicator = global::xamarinFormApp.Droid.Resource.Attribute.homeAsUpIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.homeLayout = global::xamarinFormApp.Droid.Resource.Attribute.homeLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.hoveredFocusedTranslationZ = global::xamarinFormApp.Droid.Resource.Attribute.hoveredFocusedTranslationZ; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.icon = global::xamarinFormApp.Droid.Resource.Attribute.icon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.iconEndPadding = global::xamarinFormApp.Droid.Resource.Attribute.iconEndPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.iconGravity = global::xamarinFormApp.Droid.Resource.Attribute.iconGravity; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.iconifiedByDefault = global::xamarinFormApp.Droid.Resource.Attribute.iconifiedByDefault; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.iconPadding = global::xamarinFormApp.Droid.Resource.Attribute.iconPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.iconSize = global::xamarinFormApp.Droid.Resource.Attribute.iconSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.iconStartPadding = global::xamarinFormApp.Droid.Resource.Attribute.iconStartPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.iconTint = global::xamarinFormApp.Droid.Resource.Attribute.iconTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.iconTintMode = global::xamarinFormApp.Droid.Resource.Attribute.iconTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.imageButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.imageButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.indeterminateProgressStyle = global::xamarinFormApp.Droid.Resource.Attribute.indeterminateProgressStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.initialActivityCount = global::xamarinFormApp.Droid.Resource.Attribute.initialActivityCount; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.insetForeground = global::xamarinFormApp.Droid.Resource.Attribute.insetForeground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.isLightTheme = global::xamarinFormApp.Droid.Resource.Attribute.isLightTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemBackground = global::xamarinFormApp.Droid.Resource.Attribute.itemBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemHorizontalPadding = global::xamarinFormApp.Droid.Resource.Attribute.itemHorizontalPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemHorizontalTranslationEnabled = global::xamarinFormApp.Droid.Resource.Attribute.itemHorizontalTranslationEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemIconPadding = global::xamarinFormApp.Droid.Resource.Attribute.itemIconPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemIconSize = global::xamarinFormApp.Droid.Resource.Attribute.itemIconSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemIconTint = global::xamarinFormApp.Droid.Resource.Attribute.itemIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemPadding = global::xamarinFormApp.Droid.Resource.Attribute.itemPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemSpacing = global::xamarinFormApp.Droid.Resource.Attribute.itemSpacing; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.itemTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemTextAppearanceActive = global::xamarinFormApp.Droid.Resource.Attribute.itemTextAppearanceActive; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemTextAppearanceInactive = global::xamarinFormApp.Droid.Resource.Attribute.itemTextAppearanceInactive; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.itemTextColor = global::xamarinFormApp.Droid.Resource.Attribute.itemTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.keylines = global::xamarinFormApp.Droid.Resource.Attribute.keylines; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.labelVisibilityMode = global::xamarinFormApp.Droid.Resource.Attribute.labelVisibilityMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.lastBaselineToBottomHeight = global::xamarinFormApp.Droid.Resource.Attribute.lastBaselineToBottomHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout = global::xamarinFormApp.Droid.Resource.Attribute.layout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layoutManager = global::xamarinFormApp.Droid.Resource.Attribute.layoutManager; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_anchor = global::xamarinFormApp.Droid.Resource.Attribute.layout_anchor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_anchorGravity = global::xamarinFormApp.Droid.Resource.Attribute.layout_anchorGravity; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_behavior = global::xamarinFormApp.Droid.Resource.Attribute.layout_behavior; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_collapseMode = global::xamarinFormApp.Droid.Resource.Attribute.layout_collapseMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_collapseParallaxMultiplier = global::xamarinFormApp.Droid.Resource.Attribute.layout_collapseParallaxMultiplier; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_dodgeInsetEdges = global::xamarinFormApp.Droid.Resource.Attribute.layout_dodgeInsetEdges; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_insetEdge = global::xamarinFormApp.Droid.Resource.Attribute.layout_insetEdge; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_keyline = global::xamarinFormApp.Droid.Resource.Attribute.layout_keyline; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_scrollFlags = global::xamarinFormApp.Droid.Resource.Attribute.layout_scrollFlags; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.layout_scrollInterpolator = global::xamarinFormApp.Droid.Resource.Attribute.layout_scrollInterpolator; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.liftOnScroll = global::xamarinFormApp.Droid.Resource.Attribute.liftOnScroll; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.lineHeight = global::xamarinFormApp.Droid.Resource.Attribute.lineHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.lineSpacing = global::xamarinFormApp.Droid.Resource.Attribute.lineSpacing; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listChoiceBackgroundIndicator = global::xamarinFormApp.Droid.Resource.Attribute.listChoiceBackgroundIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listDividerAlertDialog = global::xamarinFormApp.Droid.Resource.Attribute.listDividerAlertDialog; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listItemLayout = global::xamarinFormApp.Droid.Resource.Attribute.listItemLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listLayout = global::xamarinFormApp.Droid.Resource.Attribute.listLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listMenuViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.listMenuViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listPopupWindowStyle = global::xamarinFormApp.Droid.Resource.Attribute.listPopupWindowStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listPreferredItemHeight = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listPreferredItemHeightLarge = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemHeightLarge; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listPreferredItemHeightSmall = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemHeightSmall; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listPreferredItemPaddingLeft = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemPaddingLeft; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.listPreferredItemPaddingRight = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemPaddingRight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.logo = global::xamarinFormApp.Droid.Resource.Attribute.logo; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.logoDescription = global::xamarinFormApp.Droid.Resource.Attribute.logoDescription; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.materialButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.materialButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.materialCardViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.materialCardViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.maxActionInlineWidth = global::xamarinFormApp.Droid.Resource.Attribute.maxActionInlineWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.maxButtonHeight = global::xamarinFormApp.Droid.Resource.Attribute.maxButtonHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.maxImageSize = global::xamarinFormApp.Droid.Resource.Attribute.maxImageSize; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.measureWithLargestChild = global::xamarinFormApp.Droid.Resource.Attribute.measureWithLargestChild; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.menu = global::xamarinFormApp.Droid.Resource.Attribute.menu; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.multiChoiceItemLayout = global::xamarinFormApp.Droid.Resource.Attribute.multiChoiceItemLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.navigationContentDescription = global::xamarinFormApp.Droid.Resource.Attribute.navigationContentDescription; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.navigationIcon = global::xamarinFormApp.Droid.Resource.Attribute.navigationIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.navigationMode = global::xamarinFormApp.Droid.Resource.Attribute.navigationMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.navigationViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.navigationViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.numericModifiers = global::xamarinFormApp.Droid.Resource.Attribute.numericModifiers; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.overlapAnchor = global::xamarinFormApp.Droid.Resource.Attribute.overlapAnchor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.paddingBottomNoButtons = global::xamarinFormApp.Droid.Resource.Attribute.paddingBottomNoButtons; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.paddingEnd = global::xamarinFormApp.Droid.Resource.Attribute.paddingEnd; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.paddingStart = global::xamarinFormApp.Droid.Resource.Attribute.paddingStart; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.paddingTopNoTitle = global::xamarinFormApp.Droid.Resource.Attribute.paddingTopNoTitle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.panelBackground = global::xamarinFormApp.Droid.Resource.Attribute.panelBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.panelMenuListTheme = global::xamarinFormApp.Droid.Resource.Attribute.panelMenuListTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.panelMenuListWidth = global::xamarinFormApp.Droid.Resource.Attribute.panelMenuListWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.passwordToggleContentDescription = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleContentDescription; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.passwordToggleDrawable = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.passwordToggleEnabled = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.passwordToggleTint = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.passwordToggleTintMode = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.popupMenuStyle = global::xamarinFormApp.Droid.Resource.Attribute.popupMenuStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.popupTheme = global::xamarinFormApp.Droid.Resource.Attribute.popupTheme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.popupWindowStyle = global::xamarinFormApp.Droid.Resource.Attribute.popupWindowStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.preserveIconSpacing = global::xamarinFormApp.Droid.Resource.Attribute.preserveIconSpacing; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.pressedTranslationZ = global::xamarinFormApp.Droid.Resource.Attribute.pressedTranslationZ; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.progressBarPadding = global::xamarinFormApp.Droid.Resource.Attribute.progressBarPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.progressBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.progressBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.queryBackground = global::xamarinFormApp.Droid.Resource.Attribute.queryBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.queryHint = global::xamarinFormApp.Droid.Resource.Attribute.queryHint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.radioButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.radioButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.ratingBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.ratingBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.ratingBarStyleIndicator = global::xamarinFormApp.Droid.Resource.Attribute.ratingBarStyleIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.ratingBarStyleSmall = global::xamarinFormApp.Droid.Resource.Attribute.ratingBarStyleSmall; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.reverseLayout = global::xamarinFormApp.Droid.Resource.Attribute.reverseLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.rippleColor = global::xamarinFormApp.Droid.Resource.Attribute.rippleColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.scrimAnimationDuration = global::xamarinFormApp.Droid.Resource.Attribute.scrimAnimationDuration; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.scrimBackground = global::xamarinFormApp.Droid.Resource.Attribute.scrimBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.scrimVisibleHeightTrigger = global::xamarinFormApp.Droid.Resource.Attribute.scrimVisibleHeightTrigger; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.scrollViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.scrollViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.searchHintIcon = global::xamarinFormApp.Droid.Resource.Attribute.searchHintIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.searchIcon = global::xamarinFormApp.Droid.Resource.Attribute.searchIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.searchViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.searchViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.seekBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.seekBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.selectableItemBackground = global::xamarinFormApp.Droid.Resource.Attribute.selectableItemBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.selectableItemBackgroundBorderless = global::xamarinFormApp.Droid.Resource.Attribute.selectableItemBackgroundBorderless; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.showAsAction = global::xamarinFormApp.Droid.Resource.Attribute.showAsAction; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.showDividers = global::xamarinFormApp.Droid.Resource.Attribute.showDividers; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.showMotionSpec = global::xamarinFormApp.Droid.Resource.Attribute.showMotionSpec; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.showText = global::xamarinFormApp.Droid.Resource.Attribute.showText; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.showTitle = global::xamarinFormApp.Droid.Resource.Attribute.showTitle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.singleChoiceItemLayout = global::xamarinFormApp.Droid.Resource.Attribute.singleChoiceItemLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.singleLine = global::xamarinFormApp.Droid.Resource.Attribute.singleLine; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.singleSelection = global::xamarinFormApp.Droid.Resource.Attribute.singleSelection; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.snackbarButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.snackbarButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.snackbarStyle = global::xamarinFormApp.Droid.Resource.Attribute.snackbarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.spanCount = global::xamarinFormApp.Droid.Resource.Attribute.spanCount; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.spinBars = global::xamarinFormApp.Droid.Resource.Attribute.spinBars; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.spinnerDropDownItemStyle = global::xamarinFormApp.Droid.Resource.Attribute.spinnerDropDownItemStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.spinnerStyle = global::xamarinFormApp.Droid.Resource.Attribute.spinnerStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.splitTrack = global::xamarinFormApp.Droid.Resource.Attribute.splitTrack; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.srcCompat = global::xamarinFormApp.Droid.Resource.Attribute.srcCompat; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.stackFromEnd = global::xamarinFormApp.Droid.Resource.Attribute.stackFromEnd; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.state_above_anchor = global::xamarinFormApp.Droid.Resource.Attribute.state_above_anchor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.state_collapsed = global::xamarinFormApp.Droid.Resource.Attribute.state_collapsed; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.state_collapsible = global::xamarinFormApp.Droid.Resource.Attribute.state_collapsible; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.state_liftable = global::xamarinFormApp.Droid.Resource.Attribute.state_liftable; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.state_lifted = global::xamarinFormApp.Droid.Resource.Attribute.state_lifted; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.statusBarBackground = global::xamarinFormApp.Droid.Resource.Attribute.statusBarBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.statusBarScrim = global::xamarinFormApp.Droid.Resource.Attribute.statusBarScrim; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.strokeColor = global::xamarinFormApp.Droid.Resource.Attribute.strokeColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.strokeWidth = global::xamarinFormApp.Droid.Resource.Attribute.strokeWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.subMenuArrow = global::xamarinFormApp.Droid.Resource.Attribute.subMenuArrow; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.submitBackground = global::xamarinFormApp.Droid.Resource.Attribute.submitBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.subtitle = global::xamarinFormApp.Droid.Resource.Attribute.subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.subtitleTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.subtitleTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.subtitleTextColor = global::xamarinFormApp.Droid.Resource.Attribute.subtitleTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.subtitleTextStyle = global::xamarinFormApp.Droid.Resource.Attribute.subtitleTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.suggestionRowLayout = global::xamarinFormApp.Droid.Resource.Attribute.suggestionRowLayout; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.switchMinWidth = global::xamarinFormApp.Droid.Resource.Attribute.switchMinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.switchPadding = global::xamarinFormApp.Droid.Resource.Attribute.switchPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.switchStyle = global::xamarinFormApp.Droid.Resource.Attribute.switchStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.switchTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.switchTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabBackground = global::xamarinFormApp.Droid.Resource.Attribute.tabBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabContentStart = global::xamarinFormApp.Droid.Resource.Attribute.tabContentStart; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabGravity = global::xamarinFormApp.Droid.Resource.Attribute.tabGravity; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabIconTint = global::xamarinFormApp.Droid.Resource.Attribute.tabIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabIconTintMode = global::xamarinFormApp.Droid.Resource.Attribute.tabIconTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabIndicator = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabIndicatorAnimationDuration = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorAnimationDuration; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabIndicatorColor = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabIndicatorFullWidth = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorFullWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabIndicatorGravity = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorGravity; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabIndicatorHeight = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorHeight; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabInlineLabel = global::xamarinFormApp.Droid.Resource.Attribute.tabInlineLabel; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabMaxWidth = global::xamarinFormApp.Droid.Resource.Attribute.tabMaxWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabMinWidth = global::xamarinFormApp.Droid.Resource.Attribute.tabMinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabMode = global::xamarinFormApp.Droid.Resource.Attribute.tabMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabPadding = global::xamarinFormApp.Droid.Resource.Attribute.tabPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabPaddingBottom = global::xamarinFormApp.Droid.Resource.Attribute.tabPaddingBottom; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabPaddingEnd = global::xamarinFormApp.Droid.Resource.Attribute.tabPaddingEnd; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabPaddingStart = global::xamarinFormApp.Droid.Resource.Attribute.tabPaddingStart; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabPaddingTop = global::xamarinFormApp.Droid.Resource.Attribute.tabPaddingTop; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabRippleColor = global::xamarinFormApp.Droid.Resource.Attribute.tabRippleColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabSelectedTextColor = global::xamarinFormApp.Droid.Resource.Attribute.tabSelectedTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabStyle = global::xamarinFormApp.Droid.Resource.Attribute.tabStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.tabTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabTextColor = global::xamarinFormApp.Droid.Resource.Attribute.tabTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tabUnboundedRipple = global::xamarinFormApp.Droid.Resource.Attribute.tabUnboundedRipple; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAllCaps = global::xamarinFormApp.Droid.Resource.Attribute.textAllCaps; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceBody1 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceBody1; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceBody2 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceBody2; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceButton = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceButton; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceCaption = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceCaption; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceHeadline1 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline1; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceHeadline2 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline2; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceHeadline3 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline3; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceHeadline4 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline4; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceHeadline5 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline5; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceHeadline6 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline6; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceLargePopupMenu = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceLargePopupMenu; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceListItem = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceListItem; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceListItemSecondary = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceListItemSecondary; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceListItemSmall = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceListItemSmall; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceOverline = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceOverline; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearancePopupMenuHeader = global::xamarinFormApp.Droid.Resource.Attribute.textAppearancePopupMenuHeader; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceSearchResultSubtitle = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSearchResultSubtitle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceSearchResultTitle = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSearchResultTitle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceSmallPopupMenu = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSmallPopupMenu; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceSubtitle1 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSubtitle1; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textAppearanceSubtitle2 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSubtitle2; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textColorAlertDialogListItem = global::xamarinFormApp.Droid.Resource.Attribute.textColorAlertDialogListItem; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textColorSearchUrl = global::xamarinFormApp.Droid.Resource.Attribute.textColorSearchUrl; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textEndPadding = global::xamarinFormApp.Droid.Resource.Attribute.textEndPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textInputStyle = global::xamarinFormApp.Droid.Resource.Attribute.textInputStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.textStartPadding = global::xamarinFormApp.Droid.Resource.Attribute.textStartPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.theme = global::xamarinFormApp.Droid.Resource.Attribute.theme; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.thickness = global::xamarinFormApp.Droid.Resource.Attribute.thickness; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.thumbTextPadding = global::xamarinFormApp.Droid.Resource.Attribute.thumbTextPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.thumbTint = global::xamarinFormApp.Droid.Resource.Attribute.thumbTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.thumbTintMode = global::xamarinFormApp.Droid.Resource.Attribute.thumbTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tickMark = global::xamarinFormApp.Droid.Resource.Attribute.tickMark; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tickMarkTint = global::xamarinFormApp.Droid.Resource.Attribute.tickMarkTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tickMarkTintMode = global::xamarinFormApp.Droid.Resource.Attribute.tickMarkTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tint = global::xamarinFormApp.Droid.Resource.Attribute.tint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tintMode = global::xamarinFormApp.Droid.Resource.Attribute.tintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.title = global::xamarinFormApp.Droid.Resource.Attribute.title; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleEnabled = global::xamarinFormApp.Droid.Resource.Attribute.titleEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleMargin = global::xamarinFormApp.Droid.Resource.Attribute.titleMargin; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleMarginBottom = global::xamarinFormApp.Droid.Resource.Attribute.titleMarginBottom; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleMarginEnd = global::xamarinFormApp.Droid.Resource.Attribute.titleMarginEnd; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleMargins = global::xamarinFormApp.Droid.Resource.Attribute.titleMargins; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleMarginStart = global::xamarinFormApp.Droid.Resource.Attribute.titleMarginStart; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleMarginTop = global::xamarinFormApp.Droid.Resource.Attribute.titleMarginTop; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.titleTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleTextColor = global::xamarinFormApp.Droid.Resource.Attribute.titleTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.titleTextStyle = global::xamarinFormApp.Droid.Resource.Attribute.titleTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.toolbarId = global::xamarinFormApp.Droid.Resource.Attribute.toolbarId; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.toolbarNavigationButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.toolbarNavigationButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.toolbarStyle = global::xamarinFormApp.Droid.Resource.Attribute.toolbarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tooltipForegroundColor = global::xamarinFormApp.Droid.Resource.Attribute.tooltipForegroundColor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tooltipFrameBackground = global::xamarinFormApp.Droid.Resource.Attribute.tooltipFrameBackground; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.tooltipText = global::xamarinFormApp.Droid.Resource.Attribute.tooltipText; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.track = global::xamarinFormApp.Droid.Resource.Attribute.track; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.trackTint = global::xamarinFormApp.Droid.Resource.Attribute.trackTint; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.trackTintMode = global::xamarinFormApp.Droid.Resource.Attribute.trackTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.ttcIndex = global::xamarinFormApp.Droid.Resource.Attribute.ttcIndex; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.useCompatPadding = global::xamarinFormApp.Droid.Resource.Attribute.useCompatPadding; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.viewInflaterClass = global::xamarinFormApp.Droid.Resource.Attribute.viewInflaterClass; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.voiceIcon = global::xamarinFormApp.Droid.Resource.Attribute.voiceIcon; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowActionBar = global::xamarinFormApp.Droid.Resource.Attribute.windowActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowActionBarOverlay = global::xamarinFormApp.Droid.Resource.Attribute.windowActionBarOverlay; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowActionModeOverlay = global::xamarinFormApp.Droid.Resource.Attribute.windowActionModeOverlay; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowFixedHeightMajor = global::xamarinFormApp.Droid.Resource.Attribute.windowFixedHeightMajor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowFixedHeightMinor = global::xamarinFormApp.Droid.Resource.Attribute.windowFixedHeightMinor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowFixedWidthMajor = global::xamarinFormApp.Droid.Resource.Attribute.windowFixedWidthMajor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowFixedWidthMinor = global::xamarinFormApp.Droid.Resource.Attribute.windowFixedWidthMinor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowMinWidthMajor = global::xamarinFormApp.Droid.Resource.Attribute.windowMinWidthMajor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowMinWidthMinor = global::xamarinFormApp.Droid.Resource.Attribute.windowMinWidthMinor; + global::Xamarin.Forms.Platform.Android.Resource.Attribute.windowNoTitle = global::xamarinFormApp.Droid.Resource.Attribute.windowNoTitle; + global::Xamarin.Forms.Platform.Android.Resource.Boolean.abc_action_bar_embed_tabs = global::xamarinFormApp.Droid.Resource.Boolean.abc_action_bar_embed_tabs; + global::Xamarin.Forms.Platform.Android.Resource.Boolean.abc_allow_stacked_button_bar = global::xamarinFormApp.Droid.Resource.Boolean.abc_allow_stacked_button_bar; + global::Xamarin.Forms.Platform.Android.Resource.Boolean.abc_config_actionMenuItemAllCaps = global::xamarinFormApp.Droid.Resource.Boolean.abc_config_actionMenuItemAllCaps; + global::Xamarin.Forms.Platform.Android.Resource.Boolean.mtrl_btn_textappearance_all_caps = global::xamarinFormApp.Droid.Resource.Boolean.mtrl_btn_textappearance_all_caps; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_background_cache_hint_selector_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_background_cache_hint_selector_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_background_cache_hint_selector_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_background_cache_hint_selector_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_btn_colored_borderless_text_material = global::xamarinFormApp.Droid.Resource.Color.abc_btn_colored_borderless_text_material; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_btn_colored_text_material = global::xamarinFormApp.Droid.Resource.Color.abc_btn_colored_text_material; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_color_highlight_material = global::xamarinFormApp.Droid.Resource.Color.abc_color_highlight_material; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_hint_foreground_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_hint_foreground_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_hint_foreground_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_hint_foreground_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_input_method_navigation_guard = global::xamarinFormApp.Droid.Resource.Color.abc_input_method_navigation_guard; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_primary_text_disable_only_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_primary_text_disable_only_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_primary_text_disable_only_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_primary_text_disable_only_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_primary_text_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_primary_text_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_primary_text_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_primary_text_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_search_url_text = global::xamarinFormApp.Droid.Resource.Color.abc_search_url_text; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_search_url_text_normal = global::xamarinFormApp.Droid.Resource.Color.abc_search_url_text_normal; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_search_url_text_pressed = global::xamarinFormApp.Droid.Resource.Color.abc_search_url_text_pressed; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_search_url_text_selected = global::xamarinFormApp.Droid.Resource.Color.abc_search_url_text_selected; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_secondary_text_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_secondary_text_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_secondary_text_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_secondary_text_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_tint_btn_checkable = global::xamarinFormApp.Droid.Resource.Color.abc_tint_btn_checkable; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_tint_default = global::xamarinFormApp.Droid.Resource.Color.abc_tint_default; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_tint_edittext = global::xamarinFormApp.Droid.Resource.Color.abc_tint_edittext; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_tint_seek_thumb = global::xamarinFormApp.Droid.Resource.Color.abc_tint_seek_thumb; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_tint_spinner = global::xamarinFormApp.Droid.Resource.Color.abc_tint_spinner; + global::Xamarin.Forms.Platform.Android.Resource.Color.abc_tint_switch_track = global::xamarinFormApp.Droid.Resource.Color.abc_tint_switch_track; + global::Xamarin.Forms.Platform.Android.Resource.Color.accent_material_dark = global::xamarinFormApp.Droid.Resource.Color.accent_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.accent_material_light = global::xamarinFormApp.Droid.Resource.Color.accent_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.background_floating_material_dark = global::xamarinFormApp.Droid.Resource.Color.background_floating_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.background_floating_material_light = global::xamarinFormApp.Droid.Resource.Color.background_floating_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.background_material_dark = global::xamarinFormApp.Droid.Resource.Color.background_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.background_material_light = global::xamarinFormApp.Droid.Resource.Color.background_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.bright_foreground_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_disabled_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.bright_foreground_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_disabled_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.bright_foreground_inverse_material_dark = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_inverse_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.bright_foreground_inverse_material_light = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_inverse_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.bright_foreground_material_dark = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.bright_foreground_material_light = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.button_material_dark = global::xamarinFormApp.Droid.Resource.Color.button_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.button_material_light = global::xamarinFormApp.Droid.Resource.Color.button_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.cardview_dark_background = global::xamarinFormApp.Droid.Resource.Color.cardview_dark_background; + global::Xamarin.Forms.Platform.Android.Resource.Color.cardview_light_background = global::xamarinFormApp.Droid.Resource.Color.cardview_light_background; + global::Xamarin.Forms.Platform.Android.Resource.Color.cardview_shadow_end_color = global::xamarinFormApp.Droid.Resource.Color.cardview_shadow_end_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.cardview_shadow_start_color = global::xamarinFormApp.Droid.Resource.Color.cardview_shadow_start_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_bottom_navigation_shadow_color = global::xamarinFormApp.Droid.Resource.Color.design_bottom_navigation_shadow_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_default_color_primary = global::xamarinFormApp.Droid.Resource.Color.design_default_color_primary; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_default_color_primary_dark = global::xamarinFormApp.Droid.Resource.Color.design_default_color_primary_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_error = global::xamarinFormApp.Droid.Resource.Color.design_error; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_fab_shadow_end_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_shadow_end_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_fab_shadow_mid_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_shadow_mid_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_fab_shadow_start_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_shadow_start_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_fab_stroke_end_inner_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_stroke_end_inner_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_fab_stroke_end_outer_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_stroke_end_outer_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_fab_stroke_top_inner_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_stroke_top_inner_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_fab_stroke_top_outer_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_stroke_top_outer_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_snackbar_background_color = global::xamarinFormApp.Droid.Resource.Color.design_snackbar_background_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.design_tint_password_toggle = global::xamarinFormApp.Droid.Resource.Color.design_tint_password_toggle; + global::Xamarin.Forms.Platform.Android.Resource.Color.dim_foreground_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.dim_foreground_disabled_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.dim_foreground_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.dim_foreground_disabled_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.dim_foreground_material_dark = global::xamarinFormApp.Droid.Resource.Color.dim_foreground_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.dim_foreground_material_light = global::xamarinFormApp.Droid.Resource.Color.dim_foreground_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.error_color_material_dark = global::xamarinFormApp.Droid.Resource.Color.error_color_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.error_color_material_light = global::xamarinFormApp.Droid.Resource.Color.error_color_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.foreground_material_dark = global::xamarinFormApp.Droid.Resource.Color.foreground_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.foreground_material_light = global::xamarinFormApp.Droid.Resource.Color.foreground_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.highlighted_text_material_dark = global::xamarinFormApp.Droid.Resource.Color.highlighted_text_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.highlighted_text_material_light = global::xamarinFormApp.Droid.Resource.Color.highlighted_text_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_blue_grey_800 = global::xamarinFormApp.Droid.Resource.Color.material_blue_grey_800; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_blue_grey_900 = global::xamarinFormApp.Droid.Resource.Color.material_blue_grey_900; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_blue_grey_950 = global::xamarinFormApp.Droid.Resource.Color.material_blue_grey_950; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_deep_teal_200 = global::xamarinFormApp.Droid.Resource.Color.material_deep_teal_200; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_deep_teal_500 = global::xamarinFormApp.Droid.Resource.Color.material_deep_teal_500; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_grey_100 = global::xamarinFormApp.Droid.Resource.Color.material_grey_100; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_grey_300 = global::xamarinFormApp.Droid.Resource.Color.material_grey_300; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_grey_50 = global::xamarinFormApp.Droid.Resource.Color.material_grey_50; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_grey_600 = global::xamarinFormApp.Droid.Resource.Color.material_grey_600; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_grey_800 = global::xamarinFormApp.Droid.Resource.Color.material_grey_800; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_grey_850 = global::xamarinFormApp.Droid.Resource.Color.material_grey_850; + global::Xamarin.Forms.Platform.Android.Resource.Color.material_grey_900 = global::xamarinFormApp.Droid.Resource.Color.material_grey_900; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_bottom_nav_colored_item_tint = global::xamarinFormApp.Droid.Resource.Color.mtrl_bottom_nav_colored_item_tint; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_bottom_nav_item_tint = global::xamarinFormApp.Droid.Resource.Color.mtrl_bottom_nav_item_tint; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_btn_bg_color_disabled = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_bg_color_disabled; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_btn_bg_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_bg_color_selector; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_btn_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_ripple_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_btn_stroke_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_stroke_color_selector; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_btn_text_btn_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_text_btn_ripple_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_btn_text_color_disabled = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_text_color_disabled; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_btn_text_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_text_color_selector; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_btn_transparent_bg_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_transparent_bg_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_chip_background_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_chip_background_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_chip_close_icon_tint = global::xamarinFormApp.Droid.Resource.Color.mtrl_chip_close_icon_tint; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_chip_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_chip_ripple_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_chip_text_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_chip_text_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_fab_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_fab_ripple_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_scrim_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_scrim_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_tabs_colored_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_colored_ripple_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_tabs_icon_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_icon_color_selector; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_tabs_icon_color_selector_colored = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_icon_color_selector_colored; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_tabs_legacy_text_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_legacy_text_color_selector; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_tabs_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_ripple_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_textinput_default_box_stroke_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_textinput_default_box_stroke_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_textinput_disabled_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_textinput_disabled_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_textinput_filled_box_default_background_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_textinput_filled_box_default_background_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_textinput_hovered_box_stroke_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_textinput_hovered_box_stroke_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.mtrl_text_btn_text_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_text_btn_text_color_selector; + global::Xamarin.Forms.Platform.Android.Resource.Color.notification_action_color_filter = global::xamarinFormApp.Droid.Resource.Color.notification_action_color_filter; + global::Xamarin.Forms.Platform.Android.Resource.Color.notification_icon_bg_color = global::xamarinFormApp.Droid.Resource.Color.notification_icon_bg_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.notification_material_background_media_default_color = global::xamarinFormApp.Droid.Resource.Color.notification_material_background_media_default_color; + global::Xamarin.Forms.Platform.Android.Resource.Color.primary_dark_material_dark = global::xamarinFormApp.Droid.Resource.Color.primary_dark_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.primary_dark_material_light = global::xamarinFormApp.Droid.Resource.Color.primary_dark_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.primary_material_dark = global::xamarinFormApp.Droid.Resource.Color.primary_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.primary_material_light = global::xamarinFormApp.Droid.Resource.Color.primary_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.primary_text_default_material_dark = global::xamarinFormApp.Droid.Resource.Color.primary_text_default_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.primary_text_default_material_light = global::xamarinFormApp.Droid.Resource.Color.primary_text_default_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.primary_text_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.primary_text_disabled_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.primary_text_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.primary_text_disabled_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.ripple_material_dark = global::xamarinFormApp.Droid.Resource.Color.ripple_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.ripple_material_light = global::xamarinFormApp.Droid.Resource.Color.ripple_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.secondary_text_default_material_dark = global::xamarinFormApp.Droid.Resource.Color.secondary_text_default_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.secondary_text_default_material_light = global::xamarinFormApp.Droid.Resource.Color.secondary_text_default_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.secondary_text_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.secondary_text_disabled_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.secondary_text_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.secondary_text_disabled_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.switch_thumb_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_disabled_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.switch_thumb_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_disabled_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.switch_thumb_material_dark = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.switch_thumb_material_light = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.switch_thumb_normal_material_dark = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_normal_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.switch_thumb_normal_material_light = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_normal_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Color.tooltip_background_dark = global::xamarinFormApp.Droid.Resource.Color.tooltip_background_dark; + global::Xamarin.Forms.Platform.Android.Resource.Color.tooltip_background_light = global::xamarinFormApp.Droid.Resource.Color.tooltip_background_light; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_content_inset_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_content_inset_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_content_inset_with_nav = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_content_inset_with_nav; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_default_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_default_height_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_default_padding_end_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_default_padding_end_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_default_padding_start_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_default_padding_start_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_elevation_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_elevation_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_icon_vertical_padding_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_icon_vertical_padding_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_overflow_padding_end_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_overflow_padding_end_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_overflow_padding_start_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_overflow_padding_start_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_stacked_max_height = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_stacked_max_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_stacked_tab_max_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_stacked_tab_max_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_subtitle_bottom_margin_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_subtitle_bottom_margin_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_bar_subtitle_top_margin_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_subtitle_top_margin_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_button_min_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_button_min_height_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_button_min_width_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_button_min_width_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_action_button_min_width_overflow_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_button_min_width_overflow_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_alert_dialog_button_bar_height = global::xamarinFormApp.Droid.Resource.Dimension.abc_alert_dialog_button_bar_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_alert_dialog_button_dimen = global::xamarinFormApp.Droid.Resource.Dimension.abc_alert_dialog_button_dimen; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_button_inset_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_button_inset_horizontal_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_button_inset_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_button_inset_vertical_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_button_padding_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_button_padding_horizontal_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_button_padding_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_button_padding_vertical_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_cascading_menus_min_smallest_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_cascading_menus_min_smallest_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_config_prefDialogWidth = global::xamarinFormApp.Droid.Resource.Dimension.abc_config_prefDialogWidth; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_control_corner_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_control_corner_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_control_inset_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_control_inset_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_control_padding_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_control_padding_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_corner_radius_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_corner_radius_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_fixed_height_major = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_fixed_height_major; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_fixed_height_minor = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_fixed_height_minor; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_fixed_width_major = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_fixed_width_major; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_fixed_width_minor = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_fixed_width_minor; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_list_padding_bottom_no_buttons = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_list_padding_bottom_no_buttons; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_list_padding_top_no_title = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_list_padding_top_no_title; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_min_width_major = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_min_width_major; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_min_width_minor = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_min_width_minor; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_padding_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_padding_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_padding_top_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_padding_top_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dialog_title_divider_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_title_divider_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_disabled_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.abc_disabled_alpha_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_disabled_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.abc_disabled_alpha_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dropdownitem_icon_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_dropdownitem_icon_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dropdownitem_text_padding_left = global::xamarinFormApp.Droid.Resource.Dimension.abc_dropdownitem_text_padding_left; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_dropdownitem_text_padding_right = global::xamarinFormApp.Droid.Resource.Dimension.abc_dropdownitem_text_padding_right; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_edit_text_inset_bottom_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_edit_text_inset_bottom_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_edit_text_inset_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_edit_text_inset_horizontal_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_edit_text_inset_top_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_edit_text_inset_top_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_floating_window_z = global::xamarinFormApp.Droid.Resource.Dimension.abc_floating_window_z; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_list_item_padding_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_list_item_padding_horizontal_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_panel_menu_list_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_panel_menu_list_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_progress_bar_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_progress_bar_height_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_search_view_preferred_height = global::xamarinFormApp.Droid.Resource.Dimension.abc_search_view_preferred_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_search_view_preferred_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_search_view_preferred_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_seekbar_track_background_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_seekbar_track_background_height_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_seekbar_track_progress_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_seekbar_track_progress_height_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_select_dialog_padding_start_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_select_dialog_padding_start_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_switch_padding = global::xamarinFormApp.Droid.Resource.Dimension.abc_switch_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_body_1_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_body_1_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_body_2_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_body_2_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_button_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_button_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_caption_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_caption_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_display_1_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_display_1_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_display_2_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_display_2_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_display_3_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_display_3_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_display_4_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_display_4_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_headline_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_headline_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_large_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_large_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_medium_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_medium_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_menu_header_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_menu_header_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_menu_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_menu_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_small_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_small_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_subhead_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_subhead_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_subtitle_material_toolbar = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_subtitle_material_toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_title_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_title_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.abc_text_size_title_material_toolbar = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_title_material_toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.cardview_compat_inset_shadow = global::xamarinFormApp.Droid.Resource.Dimension.cardview_compat_inset_shadow; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.cardview_default_elevation = global::xamarinFormApp.Droid.Resource.Dimension.cardview_default_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.cardview_default_radius = global::xamarinFormApp.Droid.Resource.Dimension.cardview_default_radius; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.compat_button_inset_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_inset_horizontal_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.compat_button_inset_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_inset_vertical_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.compat_button_padding_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_padding_horizontal_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.compat_button_padding_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_padding_vertical_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.compat_control_corner_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_control_corner_material; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.compat_notification_large_icon_max_height = global::xamarinFormApp.Droid.Resource.Dimension.compat_notification_large_icon_max_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.compat_notification_large_icon_max_width = global::xamarinFormApp.Droid.Resource.Dimension.compat_notification_large_icon_max_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_appbar_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_appbar_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_active_item_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_active_item_max_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_active_item_min_width = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_active_item_min_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_active_text_size = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_active_text_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_height = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_icon_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_item_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_item_max_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_item_min_width = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_item_min_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_margin = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_margin; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_shadow_height = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_shadow_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_navigation_text_size = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_text_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_sheet_modal_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_sheet_modal_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_bottom_sheet_peek_height_min = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_sheet_peek_height_min; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_fab_border_width = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_border_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_fab_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_fab_image_size = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_image_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_fab_size_mini = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_size_mini; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_fab_size_normal = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_size_normal; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_fab_translation_z_hovered_focused = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_translation_z_hovered_focused; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_fab_translation_z_pressed = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_translation_z_pressed; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_navigation_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_navigation_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_icon_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_navigation_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_icon_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_navigation_item_horizontal_padding = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_item_horizontal_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_navigation_item_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_item_icon_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_navigation_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_max_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_navigation_padding_bottom = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_padding_bottom; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_navigation_separator_vertical_padding = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_separator_vertical_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_action_inline_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_action_inline_max_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_background_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_background_corner_radius; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_extra_spacing_horizontal = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_extra_spacing_horizontal; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_max_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_min_width = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_min_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_padding_horizontal = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_padding_horizontal; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_padding_vertical = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_padding_vertical; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_padding_vertical_2lines = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_padding_vertical_2lines; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_snackbar_text_size = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_text_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_tab_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_tab_max_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_tab_scrollable_min_width = global::xamarinFormApp.Droid.Resource.Dimension.design_tab_scrollable_min_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_tab_text_size = global::xamarinFormApp.Droid.Resource.Dimension.design_tab_text_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_tab_text_size_2line = global::xamarinFormApp.Droid.Resource.Dimension.design_tab_text_size_2line; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.design_textinput_caption_translate_y = global::xamarinFormApp.Droid.Resource.Dimension.design_textinput_caption_translate_y; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.disabled_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.disabled_alpha_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.disabled_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.disabled_alpha_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.fastscroll_default_thickness = global::xamarinFormApp.Droid.Resource.Dimension.fastscroll_default_thickness; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.fastscroll_margin = global::xamarinFormApp.Droid.Resource.Dimension.fastscroll_margin; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.fastscroll_minimum_range = global::xamarinFormApp.Droid.Resource.Dimension.fastscroll_minimum_range; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.highlight_alpha_material_colored = global::xamarinFormApp.Droid.Resource.Dimension.highlight_alpha_material_colored; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.highlight_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.highlight_alpha_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.highlight_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.highlight_alpha_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.hint_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.hint_alpha_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.hint_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.hint_alpha_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.hint_pressed_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.hint_pressed_alpha_material_dark; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.hint_pressed_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.hint_pressed_alpha_material_light; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.item_touch_helper_max_drag_scroll_per_frame = global::xamarinFormApp.Droid.Resource.Dimension.item_touch_helper_max_drag_scroll_per_frame; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.item_touch_helper_swipe_escape_max_velocity = global::xamarinFormApp.Droid.Resource.Dimension.item_touch_helper_swipe_escape_max_velocity; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.item_touch_helper_swipe_escape_velocity = global::xamarinFormApp.Droid.Resource.Dimension.item_touch_helper_swipe_escape_velocity; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_bottomappbar_fabOffsetEndMode = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_fabOffsetEndMode; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_bottomappbar_fab_cradle_margin = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_fab_cradle_margin; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_bottomappbar_fab_cradle_rounded_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_fab_cradle_rounded_corner_radius; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_bottomappbar_fab_cradle_vertical_offset = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_fab_cradle_vertical_offset; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_bottomappbar_height = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_corner_radius; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_dialog_btn_min_width = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_dialog_btn_min_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_disabled_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_disabled_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_disabled_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_disabled_z; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_focused_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_focused_z; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_hovered_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_hovered_z; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_icon_btn_padding_left = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_icon_btn_padding_left; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_icon_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_inset = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_inset; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_letter_spacing = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_letter_spacing; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_padding_bottom = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_padding_bottom; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_padding_left = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_padding_left; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_padding_right = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_padding_right; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_padding_top = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_padding_top; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_pressed_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_pressed_z; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_stroke_size = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_stroke_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_text_btn_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_text_btn_icon_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_text_btn_padding_left = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_text_btn_padding_left; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_text_btn_padding_right = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_text_btn_padding_right; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_text_size = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_text_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_btn_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_z; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_card_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_card_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_card_spacing = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_card_spacing; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_chip_pressed_translation_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_chip_pressed_translation_z; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_chip_text_size = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_chip_text_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_fab_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_fab_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_fab_translation_z_hovered_focused = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_fab_translation_z_hovered_focused; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_fab_translation_z_pressed = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_fab_translation_z_pressed; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_navigation_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_navigation_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_navigation_item_horizontal_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_navigation_item_horizontal_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_navigation_item_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_navigation_item_icon_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_snackbar_background_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_snackbar_background_corner_radius; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_snackbar_margin = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_snackbar_margin; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_textinput_box_bottom_offset = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_bottom_offset; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_textinput_box_corner_radius_medium = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_corner_radius_medium; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_textinput_box_corner_radius_small = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_corner_radius_small; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_textinput_box_label_cutout_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_label_cutout_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_textinput_box_padding_end = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_padding_end; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_textinput_box_stroke_width_default = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_stroke_width_default; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_textinput_box_stroke_width_focused = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_stroke_width_focused; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_textinput_outline_box_expanded_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_outline_box_expanded_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.mtrl_toolbar_default_height = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_toolbar_default_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_action_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_action_icon_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_action_text_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_action_text_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_big_circle_margin = global::xamarinFormApp.Droid.Resource.Dimension.notification_big_circle_margin; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_content_margin_start = global::xamarinFormApp.Droid.Resource.Dimension.notification_content_margin_start; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_large_icon_height = global::xamarinFormApp.Droid.Resource.Dimension.notification_large_icon_height; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_large_icon_width = global::xamarinFormApp.Droid.Resource.Dimension.notification_large_icon_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_main_column_padding_top = global::xamarinFormApp.Droid.Resource.Dimension.notification_main_column_padding_top; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_media_narrow_margin = global::xamarinFormApp.Droid.Resource.Dimension.notification_media_narrow_margin; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_right_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_right_icon_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_right_side_padding_top = global::xamarinFormApp.Droid.Resource.Dimension.notification_right_side_padding_top; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_small_icon_background_padding = global::xamarinFormApp.Droid.Resource.Dimension.notification_small_icon_background_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_small_icon_size_as_large = global::xamarinFormApp.Droid.Resource.Dimension.notification_small_icon_size_as_large; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_subtext_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_subtext_size; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_top_pad = global::xamarinFormApp.Droid.Resource.Dimension.notification_top_pad; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.notification_top_pad_large_text = global::xamarinFormApp.Droid.Resource.Dimension.notification_top_pad_large_text; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.subtitle_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.subtitle_corner_radius; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.subtitle_outline_width = global::xamarinFormApp.Droid.Resource.Dimension.subtitle_outline_width; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.subtitle_shadow_offset = global::xamarinFormApp.Droid.Resource.Dimension.subtitle_shadow_offset; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.subtitle_shadow_radius = global::xamarinFormApp.Droid.Resource.Dimension.subtitle_shadow_radius; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.tooltip_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_corner_radius; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.tooltip_horizontal_padding = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_horizontal_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.tooltip_margin = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_margin; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.tooltip_precise_anchor_extra_offset = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_precise_anchor_extra_offset; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.tooltip_precise_anchor_threshold = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_precise_anchor_threshold; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.tooltip_vertical_padding = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_vertical_padding; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.tooltip_y_offset_non_touch = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_y_offset_non_touch; + global::Xamarin.Forms.Platform.Android.Resource.Dimension.tooltip_y_offset_touch = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_y_offset_touch; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ab_share_pack_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ab_share_pack_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_action_bar_item_background_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_action_bar_item_background_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_borderless_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_borderless_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_check_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_check_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_check_to_on_mtrl_000 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_check_to_on_mtrl_000; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_check_to_on_mtrl_015 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_check_to_on_mtrl_015; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_colored_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_colored_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_default_mtrl_shape = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_default_mtrl_shape; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_radio_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_radio_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_radio_to_on_mtrl_000 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_radio_to_on_mtrl_000; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_radio_to_on_mtrl_015 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_radio_to_on_mtrl_015; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_switch_to_on_mtrl_00001 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_switch_to_on_mtrl_00001; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_btn_switch_to_on_mtrl_00012 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_switch_to_on_mtrl_00012; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_cab_background_internal_bg = global::xamarinFormApp.Droid.Resource.Drawable.abc_cab_background_internal_bg; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_cab_background_top_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_cab_background_top_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_cab_background_top_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_cab_background_top_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_control_background_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_control_background_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_dialog_material_background = global::xamarinFormApp.Droid.Resource.Drawable.abc_dialog_material_background; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_edit_text_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_edit_text_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_ab_back_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_ab_back_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_arrow_drop_right_black_24dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_arrow_drop_right_black_24dp; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_clear_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_clear_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_commit_search_api_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_commit_search_api_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_go_search_api_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_go_search_api_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_menu_copy_mtrl_am_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_copy_mtrl_am_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_menu_cut_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_cut_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_menu_overflow_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_overflow_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_menu_paste_mtrl_am_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_paste_mtrl_am_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_menu_selectall_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_selectall_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_menu_share_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_share_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_search_api_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_search_api_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_star_black_16dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_black_16dp; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_star_black_36dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_black_36dp; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_star_black_48dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_black_48dp; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_star_half_black_16dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_half_black_16dp; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_star_half_black_36dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_half_black_36dp; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_star_half_black_48dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_half_black_48dp; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ic_voice_search_api_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_voice_search_api_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_item_background_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_item_background_holo_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_item_background_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_item_background_holo_light; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_divider_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_divider_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_divider_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_divider_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_focused_holo = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_focused_holo; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_longpressed_holo = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_longpressed_holo; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_pressed_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_pressed_holo_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_pressed_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_pressed_holo_light; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_selector_background_transition_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_background_transition_holo_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_selector_background_transition_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_background_transition_holo_light; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_selector_disabled_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_disabled_holo_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_selector_disabled_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_disabled_holo_light; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_selector_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_holo_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_list_selector_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_holo_light; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_menu_hardkey_panel_mtrl_mult = global::xamarinFormApp.Droid.Resource.Drawable.abc_menu_hardkey_panel_mtrl_mult; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_popup_background_mtrl_mult = global::xamarinFormApp.Droid.Resource.Drawable.abc_popup_background_mtrl_mult; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ratingbar_indicator_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ratingbar_indicator_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ratingbar_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ratingbar_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_ratingbar_small_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ratingbar_small_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_scrubber_control_off_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_control_off_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_scrubber_control_to_pressed_mtrl_000 = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_control_to_pressed_mtrl_000; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_scrubber_control_to_pressed_mtrl_005 = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_control_to_pressed_mtrl_005; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_scrubber_primary_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_primary_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_scrubber_track_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_track_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_seekbar_thumb_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_seekbar_thumb_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_seekbar_tick_mark_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_seekbar_tick_mark_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_seekbar_track_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_seekbar_track_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_spinner_mtrl_am_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_spinner_mtrl_am_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_spinner_textfield_background_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_spinner_textfield_background_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_switch_thumb_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_switch_thumb_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_switch_track_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_switch_track_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_tab_indicator_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_tab_indicator_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_tab_indicator_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_tab_indicator_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_textfield_activated_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_activated_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_textfield_default_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_default_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_textfield_search_activated_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_search_activated_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_textfield_search_default_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_search_default_mtrl_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_textfield_search_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_search_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_text_cursor_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_cursor_material; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_text_select_handle_left_mtrl_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_left_mtrl_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_text_select_handle_left_mtrl_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_left_mtrl_light; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_text_select_handle_middle_mtrl_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_middle_mtrl_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_text_select_handle_middle_mtrl_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_middle_mtrl_light; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_text_select_handle_right_mtrl_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_right_mtrl_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_text_select_handle_right_mtrl_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_right_mtrl_light; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.abc_vector_test = global::xamarinFormApp.Droid.Resource.Drawable.abc_vector_test; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.avd_hide_password = global::xamarinFormApp.Droid.Resource.Drawable.avd_hide_password; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.avd_show_password = global::xamarinFormApp.Droid.Resource.Drawable.avd_show_password; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.design_bottom_navigation_item_background = global::xamarinFormApp.Droid.Resource.Drawable.design_bottom_navigation_item_background; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.design_fab_background = global::xamarinFormApp.Droid.Resource.Drawable.design_fab_background; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.design_ic_visibility = global::xamarinFormApp.Droid.Resource.Drawable.design_ic_visibility; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.design_ic_visibility_off = global::xamarinFormApp.Droid.Resource.Drawable.design_ic_visibility_off; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.design_password_eye = global::xamarinFormApp.Droid.Resource.Drawable.design_password_eye; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.design_snackbar_background = global::xamarinFormApp.Droid.Resource.Drawable.design_snackbar_background; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.ic_mtrl_chip_checked_black = global::xamarinFormApp.Droid.Resource.Drawable.ic_mtrl_chip_checked_black; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.ic_mtrl_chip_checked_circle = global::xamarinFormApp.Droid.Resource.Drawable.ic_mtrl_chip_checked_circle; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.ic_mtrl_chip_close_circle = global::xamarinFormApp.Droid.Resource.Drawable.ic_mtrl_chip_close_circle; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.mtrl_snackbar_background = global::xamarinFormApp.Droid.Resource.Drawable.mtrl_snackbar_background; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.mtrl_tabs_default_indicator = global::xamarinFormApp.Droid.Resource.Drawable.mtrl_tabs_default_indicator; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.navigation_empty_icon = global::xamarinFormApp.Droid.Resource.Drawable.navigation_empty_icon; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_action_background = global::xamarinFormApp.Droid.Resource.Drawable.notification_action_background; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_bg_low = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_bg_low_normal = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low_normal; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_bg_low_pressed = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low_pressed; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_bg_normal = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_normal; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_bg_normal_pressed = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_normal_pressed; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_icon_background = global::xamarinFormApp.Droid.Resource.Drawable.notification_icon_background; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_template_icon_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_template_icon_bg; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_template_icon_low_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_template_icon_low_bg; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notification_tile_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_tile_bg; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.notify_panel_notification_icon_bg = global::xamarinFormApp.Droid.Resource.Drawable.notify_panel_notification_icon_bg; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.tooltip_frame_dark = global::xamarinFormApp.Droid.Resource.Drawable.tooltip_frame_dark; + global::Xamarin.Forms.Platform.Android.Resource.Drawable.tooltip_frame_light = global::xamarinFormApp.Droid.Resource.Drawable.tooltip_frame_light; + global::Xamarin.Forms.Platform.Android.Resource.Id.action0 = global::xamarinFormApp.Droid.Resource.Id.action0; + global::Xamarin.Forms.Platform.Android.Resource.Id.actions = global::xamarinFormApp.Droid.Resource.Id.actions; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_bar = global::xamarinFormApp.Droid.Resource.Id.action_bar; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_bar_activity_content = global::xamarinFormApp.Droid.Resource.Id.action_bar_activity_content; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_bar_container = global::xamarinFormApp.Droid.Resource.Id.action_bar_container; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_bar_root = global::xamarinFormApp.Droid.Resource.Id.action_bar_root; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_bar_spinner = global::xamarinFormApp.Droid.Resource.Id.action_bar_spinner; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_bar_subtitle = global::xamarinFormApp.Droid.Resource.Id.action_bar_subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_bar_title = global::xamarinFormApp.Droid.Resource.Id.action_bar_title; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_container = global::xamarinFormApp.Droid.Resource.Id.action_container; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_context_bar = global::xamarinFormApp.Droid.Resource.Id.action_context_bar; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_divider = global::xamarinFormApp.Droid.Resource.Id.action_divider; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_image = global::xamarinFormApp.Droid.Resource.Id.action_image; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_menu_divider = global::xamarinFormApp.Droid.Resource.Id.action_menu_divider; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_menu_presenter = global::xamarinFormApp.Droid.Resource.Id.action_menu_presenter; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_mode_bar = global::xamarinFormApp.Droid.Resource.Id.action_mode_bar; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_mode_bar_stub = global::xamarinFormApp.Droid.Resource.Id.action_mode_bar_stub; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_mode_close_button = global::xamarinFormApp.Droid.Resource.Id.action_mode_close_button; + global::Xamarin.Forms.Platform.Android.Resource.Id.action_text = global::xamarinFormApp.Droid.Resource.Id.action_text; + global::Xamarin.Forms.Platform.Android.Resource.Id.activity_chooser_view_content = global::xamarinFormApp.Droid.Resource.Id.activity_chooser_view_content; + global::Xamarin.Forms.Platform.Android.Resource.Id.add = global::xamarinFormApp.Droid.Resource.Id.add; + global::Xamarin.Forms.Platform.Android.Resource.Id.alertTitle = global::xamarinFormApp.Droid.Resource.Id.alertTitle; + global::Xamarin.Forms.Platform.Android.Resource.Id.all = global::xamarinFormApp.Droid.Resource.Id.all; + global::Xamarin.Forms.Platform.Android.Resource.Id.ALT = global::xamarinFormApp.Droid.Resource.Id.ALT; + global::Xamarin.Forms.Platform.Android.Resource.Id.always = global::xamarinFormApp.Droid.Resource.Id.always; + global::Xamarin.Forms.Platform.Android.Resource.Id.async = global::xamarinFormApp.Droid.Resource.Id.async; + global::Xamarin.Forms.Platform.Android.Resource.Id.auto = global::xamarinFormApp.Droid.Resource.Id.auto; + global::Xamarin.Forms.Platform.Android.Resource.Id.beginning = global::xamarinFormApp.Droid.Resource.Id.beginning; + global::Xamarin.Forms.Platform.Android.Resource.Id.blocking = global::xamarinFormApp.Droid.Resource.Id.blocking; + global::Xamarin.Forms.Platform.Android.Resource.Id.bottom = global::xamarinFormApp.Droid.Resource.Id.bottom; + global::Xamarin.Forms.Platform.Android.Resource.Id.bottomtab_navarea = global::xamarinFormApp.Droid.Resource.Id.bottomtab_navarea; + global::Xamarin.Forms.Platform.Android.Resource.Id.bottomtab_tabbar = global::xamarinFormApp.Droid.Resource.Id.bottomtab_tabbar; + global::Xamarin.Forms.Platform.Android.Resource.Id.buttonPanel = global::xamarinFormApp.Droid.Resource.Id.buttonPanel; + global::Xamarin.Forms.Platform.Android.Resource.Id.cancel_action = global::xamarinFormApp.Droid.Resource.Id.cancel_action; + global::Xamarin.Forms.Platform.Android.Resource.Id.center = global::xamarinFormApp.Droid.Resource.Id.center; + global::Xamarin.Forms.Platform.Android.Resource.Id.center_horizontal = global::xamarinFormApp.Droid.Resource.Id.center_horizontal; + global::Xamarin.Forms.Platform.Android.Resource.Id.center_vertical = global::xamarinFormApp.Droid.Resource.Id.center_vertical; + global::Xamarin.Forms.Platform.Android.Resource.Id.checkbox = global::xamarinFormApp.Droid.Resource.Id.checkbox; + global::Xamarin.Forms.Platform.Android.Resource.Id.chronometer = global::xamarinFormApp.Droid.Resource.Id.chronometer; + global::Xamarin.Forms.Platform.Android.Resource.Id.clip_horizontal = global::xamarinFormApp.Droid.Resource.Id.clip_horizontal; + global::Xamarin.Forms.Platform.Android.Resource.Id.clip_vertical = global::xamarinFormApp.Droid.Resource.Id.clip_vertical; + global::Xamarin.Forms.Platform.Android.Resource.Id.collapseActionView = global::xamarinFormApp.Droid.Resource.Id.collapseActionView; + global::Xamarin.Forms.Platform.Android.Resource.Id.container = global::xamarinFormApp.Droid.Resource.Id.container; + global::Xamarin.Forms.Platform.Android.Resource.Id.content = global::xamarinFormApp.Droid.Resource.Id.content; + global::Xamarin.Forms.Platform.Android.Resource.Id.contentPanel = global::xamarinFormApp.Droid.Resource.Id.contentPanel; + global::Xamarin.Forms.Platform.Android.Resource.Id.coordinator = global::xamarinFormApp.Droid.Resource.Id.coordinator; + global::Xamarin.Forms.Platform.Android.Resource.Id.CTRL = global::xamarinFormApp.Droid.Resource.Id.CTRL; + global::Xamarin.Forms.Platform.Android.Resource.Id.custom = global::xamarinFormApp.Droid.Resource.Id.custom; + global::Xamarin.Forms.Platform.Android.Resource.Id.customPanel = global::xamarinFormApp.Droid.Resource.Id.customPanel; + global::Xamarin.Forms.Platform.Android.Resource.Id.decor_content_parent = global::xamarinFormApp.Droid.Resource.Id.decor_content_parent; + global::Xamarin.Forms.Platform.Android.Resource.Id.default_activity_button = global::xamarinFormApp.Droid.Resource.Id.default_activity_button; + global::Xamarin.Forms.Platform.Android.Resource.Id.design_bottom_sheet = global::xamarinFormApp.Droid.Resource.Id.design_bottom_sheet; + global::Xamarin.Forms.Platform.Android.Resource.Id.design_menu_item_action_area = global::xamarinFormApp.Droid.Resource.Id.design_menu_item_action_area; + global::Xamarin.Forms.Platform.Android.Resource.Id.design_menu_item_action_area_stub = global::xamarinFormApp.Droid.Resource.Id.design_menu_item_action_area_stub; + global::Xamarin.Forms.Platform.Android.Resource.Id.design_menu_item_text = global::xamarinFormApp.Droid.Resource.Id.design_menu_item_text; + global::Xamarin.Forms.Platform.Android.Resource.Id.design_navigation_view = global::xamarinFormApp.Droid.Resource.Id.design_navigation_view; + global::Xamarin.Forms.Platform.Android.Resource.Id.disableHome = global::xamarinFormApp.Droid.Resource.Id.disableHome; + global::Xamarin.Forms.Platform.Android.Resource.Id.edit_query = global::xamarinFormApp.Droid.Resource.Id.edit_query; + global::Xamarin.Forms.Platform.Android.Resource.Id.end = global::xamarinFormApp.Droid.Resource.Id.end; + global::Xamarin.Forms.Platform.Android.Resource.Id.end_padder = global::xamarinFormApp.Droid.Resource.Id.end_padder; + global::Xamarin.Forms.Platform.Android.Resource.Id.enterAlways = global::xamarinFormApp.Droid.Resource.Id.enterAlways; + global::Xamarin.Forms.Platform.Android.Resource.Id.enterAlwaysCollapsed = global::xamarinFormApp.Droid.Resource.Id.enterAlwaysCollapsed; + global::Xamarin.Forms.Platform.Android.Resource.Id.exitUntilCollapsed = global::xamarinFormApp.Droid.Resource.Id.exitUntilCollapsed; + global::Xamarin.Forms.Platform.Android.Resource.Id.expanded_menu = global::xamarinFormApp.Droid.Resource.Id.expanded_menu; + global::Xamarin.Forms.Platform.Android.Resource.Id.expand_activities_button = global::xamarinFormApp.Droid.Resource.Id.expand_activities_button; + global::Xamarin.Forms.Platform.Android.Resource.Id.fill = global::xamarinFormApp.Droid.Resource.Id.fill; + global::Xamarin.Forms.Platform.Android.Resource.Id.filled = global::xamarinFormApp.Droid.Resource.Id.filled; + global::Xamarin.Forms.Platform.Android.Resource.Id.fill_horizontal = global::xamarinFormApp.Droid.Resource.Id.fill_horizontal; + global::Xamarin.Forms.Platform.Android.Resource.Id.fill_vertical = global::xamarinFormApp.Droid.Resource.Id.fill_vertical; + global::Xamarin.Forms.Platform.Android.Resource.Id.@fixed = global::xamarinFormApp.Droid.Resource.Id.@fixed; + global::Xamarin.Forms.Platform.Android.Resource.Id.flyoutcontent_appbar = global::xamarinFormApp.Droid.Resource.Id.flyoutcontent_appbar; + global::Xamarin.Forms.Platform.Android.Resource.Id.flyoutcontent_recycler = global::xamarinFormApp.Droid.Resource.Id.flyoutcontent_recycler; + global::Xamarin.Forms.Platform.Android.Resource.Id.forever = global::xamarinFormApp.Droid.Resource.Id.forever; + global::Xamarin.Forms.Platform.Android.Resource.Id.FUNCTION = global::xamarinFormApp.Droid.Resource.Id.FUNCTION; + global::Xamarin.Forms.Platform.Android.Resource.Id.ghost_view = global::xamarinFormApp.Droid.Resource.Id.ghost_view; + global::Xamarin.Forms.Platform.Android.Resource.Id.group_divider = global::xamarinFormApp.Droid.Resource.Id.group_divider; + global::Xamarin.Forms.Platform.Android.Resource.Id.home = global::xamarinFormApp.Droid.Resource.Id.home; + global::Xamarin.Forms.Platform.Android.Resource.Id.homeAsUp = global::xamarinFormApp.Droid.Resource.Id.homeAsUp; + global::Xamarin.Forms.Platform.Android.Resource.Id.icon = global::xamarinFormApp.Droid.Resource.Id.icon; + global::Xamarin.Forms.Platform.Android.Resource.Id.icon_group = global::xamarinFormApp.Droid.Resource.Id.icon_group; + global::Xamarin.Forms.Platform.Android.Resource.Id.ifRoom = global::xamarinFormApp.Droid.Resource.Id.ifRoom; + global::Xamarin.Forms.Platform.Android.Resource.Id.image = global::xamarinFormApp.Droid.Resource.Id.image; + global::Xamarin.Forms.Platform.Android.Resource.Id.info = global::xamarinFormApp.Droid.Resource.Id.info; + global::Xamarin.Forms.Platform.Android.Resource.Id.italic = global::xamarinFormApp.Droid.Resource.Id.italic; + global::Xamarin.Forms.Platform.Android.Resource.Id.item_touch_helper_previous_elevation = global::xamarinFormApp.Droid.Resource.Id.item_touch_helper_previous_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Id.labeled = global::xamarinFormApp.Droid.Resource.Id.labeled; + global::Xamarin.Forms.Platform.Android.Resource.Id.largeLabel = global::xamarinFormApp.Droid.Resource.Id.largeLabel; + global::Xamarin.Forms.Platform.Android.Resource.Id.left = global::xamarinFormApp.Droid.Resource.Id.left; + global::Xamarin.Forms.Platform.Android.Resource.Id.line1 = global::xamarinFormApp.Droid.Resource.Id.line1; + global::Xamarin.Forms.Platform.Android.Resource.Id.line3 = global::xamarinFormApp.Droid.Resource.Id.line3; + global::Xamarin.Forms.Platform.Android.Resource.Id.listMode = global::xamarinFormApp.Droid.Resource.Id.listMode; + global::Xamarin.Forms.Platform.Android.Resource.Id.list_item = global::xamarinFormApp.Droid.Resource.Id.list_item; + global::Xamarin.Forms.Platform.Android.Resource.Id.main_appbar = global::xamarinFormApp.Droid.Resource.Id.main_appbar; + global::Xamarin.Forms.Platform.Android.Resource.Id.main_tablayout = global::xamarinFormApp.Droid.Resource.Id.main_tablayout; + global::Xamarin.Forms.Platform.Android.Resource.Id.main_toolbar = global::xamarinFormApp.Droid.Resource.Id.main_toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Id.main_viewpager = global::xamarinFormApp.Droid.Resource.Id.main_viewpager; + global::Xamarin.Forms.Platform.Android.Resource.Id.masked = global::xamarinFormApp.Droid.Resource.Id.masked; + global::Xamarin.Forms.Platform.Android.Resource.Id.media_actions = global::xamarinFormApp.Droid.Resource.Id.media_actions; + global::Xamarin.Forms.Platform.Android.Resource.Id.message = global::xamarinFormApp.Droid.Resource.Id.message; + global::Xamarin.Forms.Platform.Android.Resource.Id.META = global::xamarinFormApp.Droid.Resource.Id.META; + global::Xamarin.Forms.Platform.Android.Resource.Id.middle = global::xamarinFormApp.Droid.Resource.Id.middle; + global::Xamarin.Forms.Platform.Android.Resource.Id.mini = global::xamarinFormApp.Droid.Resource.Id.mini; + global::Xamarin.Forms.Platform.Android.Resource.Id.mtrl_child_content_container = global::xamarinFormApp.Droid.Resource.Id.mtrl_child_content_container; + global::Xamarin.Forms.Platform.Android.Resource.Id.mtrl_internal_children_alpha_tag = global::xamarinFormApp.Droid.Resource.Id.mtrl_internal_children_alpha_tag; + global::Xamarin.Forms.Platform.Android.Resource.Id.multiply = global::xamarinFormApp.Droid.Resource.Id.multiply; + global::Xamarin.Forms.Platform.Android.Resource.Id.navigation_header_container = global::xamarinFormApp.Droid.Resource.Id.navigation_header_container; + global::Xamarin.Forms.Platform.Android.Resource.Id.never = global::xamarinFormApp.Droid.Resource.Id.never; + global::Xamarin.Forms.Platform.Android.Resource.Id.none = global::xamarinFormApp.Droid.Resource.Id.none; + global::Xamarin.Forms.Platform.Android.Resource.Id.normal = global::xamarinFormApp.Droid.Resource.Id.normal; + global::Xamarin.Forms.Platform.Android.Resource.Id.notification_background = global::xamarinFormApp.Droid.Resource.Id.notification_background; + global::Xamarin.Forms.Platform.Android.Resource.Id.notification_main_column = global::xamarinFormApp.Droid.Resource.Id.notification_main_column; + global::Xamarin.Forms.Platform.Android.Resource.Id.notification_main_column_container = global::xamarinFormApp.Droid.Resource.Id.notification_main_column_container; + global::Xamarin.Forms.Platform.Android.Resource.Id.outline = global::xamarinFormApp.Droid.Resource.Id.outline; + global::Xamarin.Forms.Platform.Android.Resource.Id.parallax = global::xamarinFormApp.Droid.Resource.Id.parallax; + global::Xamarin.Forms.Platform.Android.Resource.Id.parentPanel = global::xamarinFormApp.Droid.Resource.Id.parentPanel; + global::Xamarin.Forms.Platform.Android.Resource.Id.parent_matrix = global::xamarinFormApp.Droid.Resource.Id.parent_matrix; + global::Xamarin.Forms.Platform.Android.Resource.Id.pin = global::xamarinFormApp.Droid.Resource.Id.pin; + global::Xamarin.Forms.Platform.Android.Resource.Id.progress_circular = global::xamarinFormApp.Droid.Resource.Id.progress_circular; + global::Xamarin.Forms.Platform.Android.Resource.Id.progress_horizontal = global::xamarinFormApp.Droid.Resource.Id.progress_horizontal; + global::Xamarin.Forms.Platform.Android.Resource.Id.radio = global::xamarinFormApp.Droid.Resource.Id.radio; + global::Xamarin.Forms.Platform.Android.Resource.Id.right = global::xamarinFormApp.Droid.Resource.Id.right; + global::Xamarin.Forms.Platform.Android.Resource.Id.right_icon = global::xamarinFormApp.Droid.Resource.Id.right_icon; + global::Xamarin.Forms.Platform.Android.Resource.Id.right_side = global::xamarinFormApp.Droid.Resource.Id.right_side; + global::Xamarin.Forms.Platform.Android.Resource.Id.save_image_matrix = global::xamarinFormApp.Droid.Resource.Id.save_image_matrix; + global::Xamarin.Forms.Platform.Android.Resource.Id.save_non_transition_alpha = global::xamarinFormApp.Droid.Resource.Id.save_non_transition_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Id.save_scale_type = global::xamarinFormApp.Droid.Resource.Id.save_scale_type; + global::Xamarin.Forms.Platform.Android.Resource.Id.screen = global::xamarinFormApp.Droid.Resource.Id.screen; + global::Xamarin.Forms.Platform.Android.Resource.Id.scroll = global::xamarinFormApp.Droid.Resource.Id.scroll; + global::Xamarin.Forms.Platform.Android.Resource.Id.scrollable = global::xamarinFormApp.Droid.Resource.Id.scrollable; + global::Xamarin.Forms.Platform.Android.Resource.Id.scrollIndicatorDown = global::xamarinFormApp.Droid.Resource.Id.scrollIndicatorDown; + global::Xamarin.Forms.Platform.Android.Resource.Id.scrollIndicatorUp = global::xamarinFormApp.Droid.Resource.Id.scrollIndicatorUp; + global::Xamarin.Forms.Platform.Android.Resource.Id.scrollView = global::xamarinFormApp.Droid.Resource.Id.scrollView; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_badge = global::xamarinFormApp.Droid.Resource.Id.search_badge; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_bar = global::xamarinFormApp.Droid.Resource.Id.search_bar; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_button = global::xamarinFormApp.Droid.Resource.Id.search_button; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_close_btn = global::xamarinFormApp.Droid.Resource.Id.search_close_btn; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_edit_frame = global::xamarinFormApp.Droid.Resource.Id.search_edit_frame; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_go_btn = global::xamarinFormApp.Droid.Resource.Id.search_go_btn; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_mag_icon = global::xamarinFormApp.Droid.Resource.Id.search_mag_icon; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_plate = global::xamarinFormApp.Droid.Resource.Id.search_plate; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_src_text = global::xamarinFormApp.Droid.Resource.Id.search_src_text; + global::Xamarin.Forms.Platform.Android.Resource.Id.search_voice_btn = global::xamarinFormApp.Droid.Resource.Id.search_voice_btn; + global::Xamarin.Forms.Platform.Android.Resource.Id.selected = global::xamarinFormApp.Droid.Resource.Id.selected; + global::Xamarin.Forms.Platform.Android.Resource.Id.select_dialog_listview = global::xamarinFormApp.Droid.Resource.Id.select_dialog_listview; + global::Xamarin.Forms.Platform.Android.Resource.Id.shellcontent_appbar = global::xamarinFormApp.Droid.Resource.Id.shellcontent_appbar; + global::Xamarin.Forms.Platform.Android.Resource.Id.shellcontent_toolbar = global::xamarinFormApp.Droid.Resource.Id.shellcontent_toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Id.SHIFT = global::xamarinFormApp.Droid.Resource.Id.SHIFT; + global::Xamarin.Forms.Platform.Android.Resource.Id.shortcut = global::xamarinFormApp.Droid.Resource.Id.shortcut; + global::Xamarin.Forms.Platform.Android.Resource.Id.showCustom = global::xamarinFormApp.Droid.Resource.Id.showCustom; + global::Xamarin.Forms.Platform.Android.Resource.Id.showHome = global::xamarinFormApp.Droid.Resource.Id.showHome; + global::Xamarin.Forms.Platform.Android.Resource.Id.showTitle = global::xamarinFormApp.Droid.Resource.Id.showTitle; + global::Xamarin.Forms.Platform.Android.Resource.Id.smallLabel = global::xamarinFormApp.Droid.Resource.Id.smallLabel; + global::Xamarin.Forms.Platform.Android.Resource.Id.snackbar_action = global::xamarinFormApp.Droid.Resource.Id.snackbar_action; + global::Xamarin.Forms.Platform.Android.Resource.Id.snackbar_text = global::xamarinFormApp.Droid.Resource.Id.snackbar_text; + global::Xamarin.Forms.Platform.Android.Resource.Id.snap = global::xamarinFormApp.Droid.Resource.Id.snap; + global::Xamarin.Forms.Platform.Android.Resource.Id.snapMargins = global::xamarinFormApp.Droid.Resource.Id.snapMargins; + global::Xamarin.Forms.Platform.Android.Resource.Id.spacer = global::xamarinFormApp.Droid.Resource.Id.spacer; + global::Xamarin.Forms.Platform.Android.Resource.Id.split_action_bar = global::xamarinFormApp.Droid.Resource.Id.split_action_bar; + global::Xamarin.Forms.Platform.Android.Resource.Id.src_atop = global::xamarinFormApp.Droid.Resource.Id.src_atop; + global::Xamarin.Forms.Platform.Android.Resource.Id.src_in = global::xamarinFormApp.Droid.Resource.Id.src_in; + global::Xamarin.Forms.Platform.Android.Resource.Id.src_over = global::xamarinFormApp.Droid.Resource.Id.src_over; + global::Xamarin.Forms.Platform.Android.Resource.Id.start = global::xamarinFormApp.Droid.Resource.Id.start; + global::Xamarin.Forms.Platform.Android.Resource.Id.status_bar_latest_event_content = global::xamarinFormApp.Droid.Resource.Id.status_bar_latest_event_content; + global::Xamarin.Forms.Platform.Android.Resource.Id.stretch = global::xamarinFormApp.Droid.Resource.Id.stretch; + global::Xamarin.Forms.Platform.Android.Resource.Id.submenuarrow = global::xamarinFormApp.Droid.Resource.Id.submenuarrow; + global::Xamarin.Forms.Platform.Android.Resource.Id.submit_area = global::xamarinFormApp.Droid.Resource.Id.submit_area; + global::Xamarin.Forms.Platform.Android.Resource.Id.SYM = global::xamarinFormApp.Droid.Resource.Id.SYM; + global::Xamarin.Forms.Platform.Android.Resource.Id.tabMode = global::xamarinFormApp.Droid.Resource.Id.tabMode; + global::Xamarin.Forms.Platform.Android.Resource.Id.tag_transition_group = global::xamarinFormApp.Droid.Resource.Id.tag_transition_group; + global::Xamarin.Forms.Platform.Android.Resource.Id.tag_unhandled_key_event_manager = global::xamarinFormApp.Droid.Resource.Id.tag_unhandled_key_event_manager; + global::Xamarin.Forms.Platform.Android.Resource.Id.tag_unhandled_key_listeners = global::xamarinFormApp.Droid.Resource.Id.tag_unhandled_key_listeners; + global::Xamarin.Forms.Platform.Android.Resource.Id.text = global::xamarinFormApp.Droid.Resource.Id.text; + global::Xamarin.Forms.Platform.Android.Resource.Id.text2 = global::xamarinFormApp.Droid.Resource.Id.text2; + global::Xamarin.Forms.Platform.Android.Resource.Id.textinput_counter = global::xamarinFormApp.Droid.Resource.Id.textinput_counter; + global::Xamarin.Forms.Platform.Android.Resource.Id.textinput_error = global::xamarinFormApp.Droid.Resource.Id.textinput_error; + global::Xamarin.Forms.Platform.Android.Resource.Id.textinput_helper_text = global::xamarinFormApp.Droid.Resource.Id.textinput_helper_text; + global::Xamarin.Forms.Platform.Android.Resource.Id.textSpacerNoButtons = global::xamarinFormApp.Droid.Resource.Id.textSpacerNoButtons; + global::Xamarin.Forms.Platform.Android.Resource.Id.textSpacerNoTitle = global::xamarinFormApp.Droid.Resource.Id.textSpacerNoTitle; + global::Xamarin.Forms.Platform.Android.Resource.Id.textStart = global::xamarinFormApp.Droid.Resource.Id.textStart; + global::Xamarin.Forms.Platform.Android.Resource.Id.text_input_password_toggle = global::xamarinFormApp.Droid.Resource.Id.text_input_password_toggle; + global::Xamarin.Forms.Platform.Android.Resource.Id.time = global::xamarinFormApp.Droid.Resource.Id.time; + global::Xamarin.Forms.Platform.Android.Resource.Id.title = global::xamarinFormApp.Droid.Resource.Id.title; + global::Xamarin.Forms.Platform.Android.Resource.Id.titleDividerNoCustom = global::xamarinFormApp.Droid.Resource.Id.titleDividerNoCustom; + global::Xamarin.Forms.Platform.Android.Resource.Id.title_template = global::xamarinFormApp.Droid.Resource.Id.title_template; + global::Xamarin.Forms.Platform.Android.Resource.Id.top = global::xamarinFormApp.Droid.Resource.Id.top; + global::Xamarin.Forms.Platform.Android.Resource.Id.topPanel = global::xamarinFormApp.Droid.Resource.Id.topPanel; + global::Xamarin.Forms.Platform.Android.Resource.Id.touch_outside = global::xamarinFormApp.Droid.Resource.Id.touch_outside; + global::Xamarin.Forms.Platform.Android.Resource.Id.transition_current_scene = global::xamarinFormApp.Droid.Resource.Id.transition_current_scene; + global::Xamarin.Forms.Platform.Android.Resource.Id.transition_layout_save = global::xamarinFormApp.Droid.Resource.Id.transition_layout_save; + global::Xamarin.Forms.Platform.Android.Resource.Id.transition_position = global::xamarinFormApp.Droid.Resource.Id.transition_position; + global::Xamarin.Forms.Platform.Android.Resource.Id.transition_scene_layoutid_cache = global::xamarinFormApp.Droid.Resource.Id.transition_scene_layoutid_cache; + global::Xamarin.Forms.Platform.Android.Resource.Id.transition_transform = global::xamarinFormApp.Droid.Resource.Id.transition_transform; + global::Xamarin.Forms.Platform.Android.Resource.Id.uniform = global::xamarinFormApp.Droid.Resource.Id.uniform; + global::Xamarin.Forms.Platform.Android.Resource.Id.unlabeled = global::xamarinFormApp.Droid.Resource.Id.unlabeled; + global::Xamarin.Forms.Platform.Android.Resource.Id.up = global::xamarinFormApp.Droid.Resource.Id.up; + global::Xamarin.Forms.Platform.Android.Resource.Id.useLogo = global::xamarinFormApp.Droid.Resource.Id.useLogo; + global::Xamarin.Forms.Platform.Android.Resource.Id.view_offset_helper = global::xamarinFormApp.Droid.Resource.Id.view_offset_helper; + global::Xamarin.Forms.Platform.Android.Resource.Id.visible = global::xamarinFormApp.Droid.Resource.Id.visible; + global::Xamarin.Forms.Platform.Android.Resource.Id.withText = global::xamarinFormApp.Droid.Resource.Id.withText; + global::Xamarin.Forms.Platform.Android.Resource.Id.wrap_content = global::xamarinFormApp.Droid.Resource.Id.wrap_content; + global::Xamarin.Forms.Platform.Android.Resource.Integer.abc_config_activityDefaultDur = global::xamarinFormApp.Droid.Resource.Integer.abc_config_activityDefaultDur; + global::Xamarin.Forms.Platform.Android.Resource.Integer.abc_config_activityShortDur = global::xamarinFormApp.Droid.Resource.Integer.abc_config_activityShortDur; + global::Xamarin.Forms.Platform.Android.Resource.Integer.app_bar_elevation_anim_duration = global::xamarinFormApp.Droid.Resource.Integer.app_bar_elevation_anim_duration; + global::Xamarin.Forms.Platform.Android.Resource.Integer.bottom_sheet_slide_duration = global::xamarinFormApp.Droid.Resource.Integer.bottom_sheet_slide_duration; + global::Xamarin.Forms.Platform.Android.Resource.Integer.cancel_button_image_alpha = global::xamarinFormApp.Droid.Resource.Integer.cancel_button_image_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Integer.config_tooltipAnimTime = global::xamarinFormApp.Droid.Resource.Integer.config_tooltipAnimTime; + global::Xamarin.Forms.Platform.Android.Resource.Integer.design_snackbar_text_max_lines = global::xamarinFormApp.Droid.Resource.Integer.design_snackbar_text_max_lines; + global::Xamarin.Forms.Platform.Android.Resource.Integer.design_tab_indicator_anim_duration_ms = global::xamarinFormApp.Droid.Resource.Integer.design_tab_indicator_anim_duration_ms; + global::Xamarin.Forms.Platform.Android.Resource.Integer.hide_password_duration = global::xamarinFormApp.Droid.Resource.Integer.hide_password_duration; + global::Xamarin.Forms.Platform.Android.Resource.Integer.mtrl_btn_anim_delay_ms = global::xamarinFormApp.Droid.Resource.Integer.mtrl_btn_anim_delay_ms; + global::Xamarin.Forms.Platform.Android.Resource.Integer.mtrl_btn_anim_duration_ms = global::xamarinFormApp.Droid.Resource.Integer.mtrl_btn_anim_duration_ms; + global::Xamarin.Forms.Platform.Android.Resource.Integer.mtrl_chip_anim_duration = global::xamarinFormApp.Droid.Resource.Integer.mtrl_chip_anim_duration; + global::Xamarin.Forms.Platform.Android.Resource.Integer.mtrl_tab_indicator_anim_duration_ms = global::xamarinFormApp.Droid.Resource.Integer.mtrl_tab_indicator_anim_duration_ms; + global::Xamarin.Forms.Platform.Android.Resource.Integer.show_password_duration = global::xamarinFormApp.Droid.Resource.Integer.show_password_duration; + global::Xamarin.Forms.Platform.Android.Resource.Integer.status_bar_notification_info_maxnum = global::xamarinFormApp.Droid.Resource.Integer.status_bar_notification_info_maxnum; + global::Xamarin.Forms.Platform.Android.Resource.Interpolator.mtrl_fast_out_linear_in = global::xamarinFormApp.Droid.Resource.Interpolator.mtrl_fast_out_linear_in; + global::Xamarin.Forms.Platform.Android.Resource.Interpolator.mtrl_fast_out_slow_in = global::xamarinFormApp.Droid.Resource.Interpolator.mtrl_fast_out_slow_in; + global::Xamarin.Forms.Platform.Android.Resource.Interpolator.mtrl_linear = global::xamarinFormApp.Droid.Resource.Interpolator.mtrl_linear; + global::Xamarin.Forms.Platform.Android.Resource.Interpolator.mtrl_linear_out_slow_in = global::xamarinFormApp.Droid.Resource.Interpolator.mtrl_linear_out_slow_in; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_action_bar_title_item = global::xamarinFormApp.Droid.Resource.Layout.abc_action_bar_title_item; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_action_bar_up_container = global::xamarinFormApp.Droid.Resource.Layout.abc_action_bar_up_container; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_action_menu_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_action_menu_item_layout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_action_menu_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_action_menu_layout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_action_mode_bar = global::xamarinFormApp.Droid.Resource.Layout.abc_action_mode_bar; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_action_mode_close_item_material = global::xamarinFormApp.Droid.Resource.Layout.abc_action_mode_close_item_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_activity_chooser_view = global::xamarinFormApp.Droid.Resource.Layout.abc_activity_chooser_view; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_activity_chooser_view_list_item = global::xamarinFormApp.Droid.Resource.Layout.abc_activity_chooser_view_list_item; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_alert_dialog_button_bar_material = global::xamarinFormApp.Droid.Resource.Layout.abc_alert_dialog_button_bar_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_alert_dialog_material = global::xamarinFormApp.Droid.Resource.Layout.abc_alert_dialog_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_alert_dialog_title_material = global::xamarinFormApp.Droid.Resource.Layout.abc_alert_dialog_title_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_cascading_menu_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_cascading_menu_item_layout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_dialog_title_material = global::xamarinFormApp.Droid.Resource.Layout.abc_dialog_title_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_expanded_menu_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_expanded_menu_layout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_list_menu_item_checkbox = global::xamarinFormApp.Droid.Resource.Layout.abc_list_menu_item_checkbox; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_list_menu_item_icon = global::xamarinFormApp.Droid.Resource.Layout.abc_list_menu_item_icon; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_list_menu_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_list_menu_item_layout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_list_menu_item_radio = global::xamarinFormApp.Droid.Resource.Layout.abc_list_menu_item_radio; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_popup_menu_header_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_popup_menu_header_item_layout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_popup_menu_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_popup_menu_item_layout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_screen_content_include = global::xamarinFormApp.Droid.Resource.Layout.abc_screen_content_include; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_screen_simple = global::xamarinFormApp.Droid.Resource.Layout.abc_screen_simple; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_screen_simple_overlay_action_mode = global::xamarinFormApp.Droid.Resource.Layout.abc_screen_simple_overlay_action_mode; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_screen_toolbar = global::xamarinFormApp.Droid.Resource.Layout.abc_screen_toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_search_dropdown_item_icons_2line = global::xamarinFormApp.Droid.Resource.Layout.abc_search_dropdown_item_icons_2line; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_search_view = global::xamarinFormApp.Droid.Resource.Layout.abc_search_view; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_select_dialog_material = global::xamarinFormApp.Droid.Resource.Layout.abc_select_dialog_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.abc_tooltip = global::xamarinFormApp.Droid.Resource.Layout.abc_tooltip; + global::Xamarin.Forms.Platform.Android.Resource.Layout.BottomTabLayout = global::xamarinFormApp.Droid.Resource.Layout.BottomTabLayout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_bottom_navigation_item = global::xamarinFormApp.Droid.Resource.Layout.design_bottom_navigation_item; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_bottom_sheet_dialog = global::xamarinFormApp.Droid.Resource.Layout.design_bottom_sheet_dialog; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_layout_snackbar = global::xamarinFormApp.Droid.Resource.Layout.design_layout_snackbar; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_layout_snackbar_include = global::xamarinFormApp.Droid.Resource.Layout.design_layout_snackbar_include; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_layout_tab_icon = global::xamarinFormApp.Droid.Resource.Layout.design_layout_tab_icon; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_layout_tab_text = global::xamarinFormApp.Droid.Resource.Layout.design_layout_tab_text; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_menu_item_action_area = global::xamarinFormApp.Droid.Resource.Layout.design_menu_item_action_area; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_navigation_item = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_item; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_navigation_item_header = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_item_header; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_navigation_item_separator = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_item_separator; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_navigation_item_subheader = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_item_subheader; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_navigation_menu = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_menu; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_navigation_menu_item = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_menu_item; + global::Xamarin.Forms.Platform.Android.Resource.Layout.design_text_input_password_icon = global::xamarinFormApp.Droid.Resource.Layout.design_text_input_password_icon; + global::Xamarin.Forms.Platform.Android.Resource.Layout.FlyoutContent = global::xamarinFormApp.Droid.Resource.Layout.FlyoutContent; + global::Xamarin.Forms.Platform.Android.Resource.Layout.mtrl_layout_snackbar = global::xamarinFormApp.Droid.Resource.Layout.mtrl_layout_snackbar; + global::Xamarin.Forms.Platform.Android.Resource.Layout.mtrl_layout_snackbar_include = global::xamarinFormApp.Droid.Resource.Layout.mtrl_layout_snackbar_include; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_action = global::xamarinFormApp.Droid.Resource.Layout.notification_action; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_action_tombstone = global::xamarinFormApp.Droid.Resource.Layout.notification_action_tombstone; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_media_action = global::xamarinFormApp.Droid.Resource.Layout.notification_media_action; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_media_cancel_action = global::xamarinFormApp.Droid.Resource.Layout.notification_media_cancel_action; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_big_media = global::xamarinFormApp.Droid.Resource.Layout.notification_template_big_media; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_big_media_custom = global::xamarinFormApp.Droid.Resource.Layout.notification_template_big_media_custom; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_big_media_narrow = global::xamarinFormApp.Droid.Resource.Layout.notification_template_big_media_narrow; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_big_media_narrow_custom = global::xamarinFormApp.Droid.Resource.Layout.notification_template_big_media_narrow_custom; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_custom_big = global::xamarinFormApp.Droid.Resource.Layout.notification_template_custom_big; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_icon_group = global::xamarinFormApp.Droid.Resource.Layout.notification_template_icon_group; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_lines_media = global::xamarinFormApp.Droid.Resource.Layout.notification_template_lines_media; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_media = global::xamarinFormApp.Droid.Resource.Layout.notification_template_media; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_media_custom = global::xamarinFormApp.Droid.Resource.Layout.notification_template_media_custom; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_part_chronometer = global::xamarinFormApp.Droid.Resource.Layout.notification_template_part_chronometer; + global::Xamarin.Forms.Platform.Android.Resource.Layout.notification_template_part_time = global::xamarinFormApp.Droid.Resource.Layout.notification_template_part_time; + global::Xamarin.Forms.Platform.Android.Resource.Layout.RootLayout = global::xamarinFormApp.Droid.Resource.Layout.RootLayout; + global::Xamarin.Forms.Platform.Android.Resource.Layout.select_dialog_item_material = global::xamarinFormApp.Droid.Resource.Layout.select_dialog_item_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.select_dialog_multichoice_material = global::xamarinFormApp.Droid.Resource.Layout.select_dialog_multichoice_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.select_dialog_singlechoice_material = global::xamarinFormApp.Droid.Resource.Layout.select_dialog_singlechoice_material; + global::Xamarin.Forms.Platform.Android.Resource.Layout.ShellContent = global::xamarinFormApp.Droid.Resource.Layout.ShellContent; + global::Xamarin.Forms.Platform.Android.Resource.Layout.support_simple_spinner_dropdown_item = global::xamarinFormApp.Droid.Resource.Layout.support_simple_spinner_dropdown_item; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_action_bar_home_description = global::xamarinFormApp.Droid.Resource.String.abc_action_bar_home_description; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_action_bar_up_description = global::xamarinFormApp.Droid.Resource.String.abc_action_bar_up_description; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_action_menu_overflow_description = global::xamarinFormApp.Droid.Resource.String.abc_action_menu_overflow_description; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_action_mode_done = global::xamarinFormApp.Droid.Resource.String.abc_action_mode_done; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_activitychooserview_choose_application = global::xamarinFormApp.Droid.Resource.String.abc_activitychooserview_choose_application; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_activity_chooser_view_see_all = global::xamarinFormApp.Droid.Resource.String.abc_activity_chooser_view_see_all; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_capital_off = global::xamarinFormApp.Droid.Resource.String.abc_capital_off; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_capital_on = global::xamarinFormApp.Droid.Resource.String.abc_capital_on; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_body_1_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_body_1_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_body_2_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_body_2_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_button_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_button_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_caption_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_caption_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_display_1_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_display_1_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_display_2_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_display_2_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_display_3_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_display_3_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_display_4_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_display_4_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_headline_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_headline_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_menu_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_menu_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_subhead_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_subhead_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_font_family_title_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_title_material; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_alt_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_alt_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_ctrl_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_ctrl_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_delete_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_delete_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_enter_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_enter_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_function_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_function_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_meta_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_meta_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_shift_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_shift_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_space_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_space_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_menu_sym_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_sym_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_prepend_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_prepend_shortcut_label; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_searchview_description_clear = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_clear; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_searchview_description_query = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_query; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_searchview_description_search = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_search; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_searchview_description_submit = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_submit; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_searchview_description_voice = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_voice; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_search_hint = global::xamarinFormApp.Droid.Resource.String.abc_search_hint; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_shareactionprovider_share_with = global::xamarinFormApp.Droid.Resource.String.abc_shareactionprovider_share_with; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_shareactionprovider_share_with_application = global::xamarinFormApp.Droid.Resource.String.abc_shareactionprovider_share_with_application; + global::Xamarin.Forms.Platform.Android.Resource.String.abc_toolbar_collapse_description = global::xamarinFormApp.Droid.Resource.String.abc_toolbar_collapse_description; + global::Xamarin.Forms.Platform.Android.Resource.String.appbar_scrolling_view_behavior = global::xamarinFormApp.Droid.Resource.String.appbar_scrolling_view_behavior; + global::Xamarin.Forms.Platform.Android.Resource.String.bottom_sheet_behavior = global::xamarinFormApp.Droid.Resource.String.bottom_sheet_behavior; + global::Xamarin.Forms.Platform.Android.Resource.String.character_counter_content_description = global::xamarinFormApp.Droid.Resource.String.character_counter_content_description; + global::Xamarin.Forms.Platform.Android.Resource.String.character_counter_pattern = global::xamarinFormApp.Droid.Resource.String.character_counter_pattern; + global::Xamarin.Forms.Platform.Android.Resource.String.fab_transformation_scrim_behavior = global::xamarinFormApp.Droid.Resource.String.fab_transformation_scrim_behavior; + global::Xamarin.Forms.Platform.Android.Resource.String.fab_transformation_sheet_behavior = global::xamarinFormApp.Droid.Resource.String.fab_transformation_sheet_behavior; + global::Xamarin.Forms.Platform.Android.Resource.String.hide_bottom_view_on_scroll_behavior = global::xamarinFormApp.Droid.Resource.String.hide_bottom_view_on_scroll_behavior; + global::Xamarin.Forms.Platform.Android.Resource.String.mtrl_chip_close_icon_content_description = global::xamarinFormApp.Droid.Resource.String.mtrl_chip_close_icon_content_description; + global::Xamarin.Forms.Platform.Android.Resource.String.overflow_tab_title = global::xamarinFormApp.Droid.Resource.String.overflow_tab_title; + global::Xamarin.Forms.Platform.Android.Resource.String.password_toggle_content_description = global::xamarinFormApp.Droid.Resource.String.password_toggle_content_description; + global::Xamarin.Forms.Platform.Android.Resource.String.path_password_eye = global::xamarinFormApp.Droid.Resource.String.path_password_eye; + global::Xamarin.Forms.Platform.Android.Resource.String.path_password_eye_mask_strike_through = global::xamarinFormApp.Droid.Resource.String.path_password_eye_mask_strike_through; + global::Xamarin.Forms.Platform.Android.Resource.String.path_password_eye_mask_visible = global::xamarinFormApp.Droid.Resource.String.path_password_eye_mask_visible; + global::Xamarin.Forms.Platform.Android.Resource.String.path_password_strike_through = global::xamarinFormApp.Droid.Resource.String.path_password_strike_through; + global::Xamarin.Forms.Platform.Android.Resource.String.search_menu_title = global::xamarinFormApp.Droid.Resource.String.search_menu_title; + global::Xamarin.Forms.Platform.Android.Resource.String.status_bar_notification_info_overflow = global::xamarinFormApp.Droid.Resource.String.status_bar_notification_info_overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.AlertDialog_AppCompat = global::xamarinFormApp.Droid.Resource.Style.AlertDialog_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.AlertDialog_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.AlertDialog_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Animation_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Animation_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Animation_AppCompat_DropDownUp = global::xamarinFormApp.Droid.Resource.Style.Animation_AppCompat_DropDownUp; + global::Xamarin.Forms.Platform.Android.Resource.Style.Animation_AppCompat_Tooltip = global::xamarinFormApp.Droid.Resource.Style.Animation_AppCompat_Tooltip; + global::Xamarin.Forms.Platform.Android.Resource.Style.Animation_Design_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Animation_Design_BottomSheetDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.AppCompatDialogStyle = global::xamarinFormApp.Droid.Resource.Style.AppCompatDialogStyle; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_AlertDialog_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_AlertDialog_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_AlertDialog_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_AlertDialog_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Animation_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Animation_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Animation_AppCompat_DropDownUp = global::xamarinFormApp.Droid.Resource.Style.Base_Animation_AppCompat_DropDownUp; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Animation_AppCompat_Tooltip = global::xamarinFormApp.Droid.Resource.Style.Base_Animation_AppCompat_Tooltip; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_CardView = global::xamarinFormApp.Droid.Resource.Style.Base_CardView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_DialogWindowTitleBackground_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_DialogWindowTitleBackground_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_DialogWindowTitle_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_DialogWindowTitle_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Body1 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Body1; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Body2 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Body2; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Button = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Button; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Caption = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Caption; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Display1 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Display1; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Display2 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Display2; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Display3 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Display3; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Display4 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Display4; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Headline = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Headline; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Large = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Large; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Large_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Large_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Large = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Large; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Small = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Medium = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Medium; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Medium_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Medium_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Menu = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Menu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_SearchResult = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_SearchResult; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_SearchResult_Subtitle = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_SearchResult_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_SearchResult_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_SearchResult_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Small = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Small_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Small_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Subhead = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Subhead; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Subhead_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Subhead_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Title_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Tooltip = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Tooltip; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Menu = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Menu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionMode_Subtitle = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionMode_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionMode_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionMode_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Borderless_Colored = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Borderless_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Colored = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_DropDownItem = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_DropDownItem; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Header = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Header; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Large = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Large; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Small = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_Switch = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Switch; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_AppCompat_Widget_TextView_SpinnerItem = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_TextView_SpinnerItem; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_Widget_AppCompat_ExpandedMenu_Item = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_Widget_AppCompat_ExpandedMenu_Item; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_Widget_AppCompat_Toolbar_Subtitle = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_Widget_AppCompat_Toolbar_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_TextAppearance_Widget_AppCompat_Toolbar_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_Widget_AppCompat_Toolbar_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_AppCompat_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_AppCompat_Dark = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Dark; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_AppCompat_Dark_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Dark_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_AppCompat_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_ThemeOverlay_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_CompactMenu = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_CompactMenu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Dialog_FixedSize = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Dialog_FixedSize; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Light_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_DarkActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Light_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Light_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Light_Dialog_FixedSize = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_Dialog_FixedSize; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_AppCompat_Light_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_CompactMenu = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_CompactMenu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Dialog_FixedSize = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Dialog_FixedSize; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_DarkActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light_DarkActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_DarkActionBar_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_FixedSize = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_FixedSize; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_ThemeOverlay_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V14_ThemeOverlay_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_ThemeOverlay_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_V14_ThemeOverlay_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_Theme_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_Theme_MaterialComponents_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_Theme_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_Theme_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_Theme_MaterialComponents_Light_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Light_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_Theme_MaterialComponents_Light_DarkActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Light_DarkActionBar_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V14_Theme_MaterialComponents_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Light_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V21_ThemeOverlay_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V21_ThemeOverlay_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V21_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V21_Theme_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V21_Theme_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V21_Theme_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V21_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V21_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V21_Theme_AppCompat_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V21_Theme_AppCompat_Light_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V22_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V22_Theme_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V22_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V22_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V23_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V23_Theme_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V23_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V23_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V26_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V26_Theme_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V26_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V26_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V26_Widget_AppCompat_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Base_V26_Widget_AppCompat_Toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V28_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V28_Theme_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V28_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V28_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V7_ThemeOverlay_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V7_ThemeOverlay_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V7_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Theme_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V7_Theme_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Theme_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V7_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V7_Theme_AppCompat_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Theme_AppCompat_Light_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V7_Widget_AppCompat_AutoCompleteTextView = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Widget_AppCompat_AutoCompleteTextView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V7_Widget_AppCompat_EditText = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Widget_AppCompat_EditText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_V7_Widget_AppCompat_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Widget_AppCompat_Toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionBar_Solid = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar_Solid; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionBar_TabBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar_TabBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionBar_TabText = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar_TabText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionBar_TabView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar_TabView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionButton = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionButton_CloseMode = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionButton_CloseMode; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionButton_Overflow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionButton_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActionMode = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionMode; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ActivityChooserView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActivityChooserView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_AutoCompleteTextView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_AutoCompleteTextView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Button = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ButtonBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ButtonBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ButtonBar_AlertDialog = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ButtonBar_AlertDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Button_Borderless = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_Borderless; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Button_Borderless_Colored = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_Borderless_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Button_ButtonBar_AlertDialog = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_ButtonBar_AlertDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Button_Colored = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Button_Small = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_CompoundButton_CheckBox = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_CompoundButton_CheckBox; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_CompoundButton_RadioButton = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_CompoundButton_RadioButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_CompoundButton_Switch = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_CompoundButton_Switch; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_DrawerArrowToggle = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_DrawerArrowToggle; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_DrawerArrowToggle_Common = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_DrawerArrowToggle_Common; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_DropDownItem_Spinner = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_DropDownItem_Spinner; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_EditText = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_EditText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ImageButton = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ImageButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Light_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_Solid = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_Solid; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabText = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabText_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabText_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Light_PopupMenu = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_PopupMenu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Light_PopupMenu_Overflow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_PopupMenu_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ListMenuView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListMenuView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ListPopupWindow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListPopupWindow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ListView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ListView_DropDown = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListView_DropDown; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ListView_Menu = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListView_Menu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_PopupMenu = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_PopupMenu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_PopupMenu_Overflow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_PopupMenu_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_PopupWindow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_PopupWindow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ProgressBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ProgressBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_ProgressBar_Horizontal = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ProgressBar_Horizontal; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_RatingBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_RatingBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_RatingBar_Indicator = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_RatingBar_Indicator; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_RatingBar_Small = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_RatingBar_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_SearchView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_SearchView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_SearchView_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_SearchView_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_SeekBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_SeekBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_SeekBar_Discrete = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_SeekBar_Discrete; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Spinner = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Spinner; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Spinner_Underlined = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Spinner_Underlined; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_TextView_SpinnerItem = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_TextView_SpinnerItem; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_AppCompat_Toolbar_Button_Navigation = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Toolbar_Button_Navigation; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_Design_TabLayout = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_Design_TabLayout; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_MaterialComponents_Chip = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_MaterialComponents_Chip; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_MaterialComponents_TextInputEditText = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_MaterialComponents_TextInputEditText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Base_Widget_MaterialComponents_TextInputLayout = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_MaterialComponents_TextInputLayout; + global::Xamarin.Forms.Platform.Android.Resource.Style.CardView = global::xamarinFormApp.Droid.Resource.Style.CardView; + global::Xamarin.Forms.Platform.Android.Resource.Style.CardView_Dark = global::xamarinFormApp.Droid.Resource.Style.CardView_Dark; + global::Xamarin.Forms.Platform.Android.Resource.Style.CardView_Light = global::xamarinFormApp.Droid.Resource.Style.CardView_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.collectionViewTheme = global::xamarinFormApp.Droid.Resource.Style.collectionViewTheme; + global::Xamarin.Forms.Platform.Android.Resource.Style.MainTheme = global::xamarinFormApp.Droid.Resource.Style.MainTheme; + global::Xamarin.Forms.Platform.Android.Resource.Style.MainTheme_Base = global::xamarinFormApp.Droid.Resource.Style.MainTheme_Base; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Platform_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.Platform_MaterialComponents; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Platform_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_MaterialComponents_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Platform_MaterialComponents_Light_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_ThemeOverlay_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Platform_ThemeOverlay_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_ThemeOverlay_AppCompat_Dark = global::xamarinFormApp.Droid.Resource.Style.Platform_ThemeOverlay_AppCompat_Dark; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_ThemeOverlay_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_ThemeOverlay_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_V21_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Platform_V21_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_V21_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_V21_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_V25_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Platform_V25_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_V25_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_V25_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Platform_Widget_AppCompat_Spinner = global::xamarinFormApp.Droid.Resource.Style.Platform_Widget_AppCompat_Spinner; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_DialogWindowTitle_AppCompat = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_DialogWindowTitle_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_ActionBar_TitleItem = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_ActionBar_TitleItem; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_DialogTitle_Icon = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_DialogTitle_Icon; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_InternalGroup = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_InternalGroup; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Shortcut = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Shortcut; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_SubmenuArrow = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_SubmenuArrow; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Text = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Text; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Title = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_SearchView_MagIcon = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_SearchView_MagIcon; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Icon1 = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Icon1; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Icon2 = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Icon2; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Query = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Query; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Text = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Text; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlUnderlay_Widget_AppCompat_ActionButton = global::xamarinFormApp.Droid.Resource.Style.RtlUnderlay_Widget_AppCompat_ActionButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.RtlUnderlay_Widget_AppCompat_ActionButton_Overflow = global::xamarinFormApp.Droid.Resource.Style.RtlUnderlay_Widget_AppCompat_ActionButton_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.scrollViewScrollBars = global::xamarinFormApp.Droid.Resource.Style.scrollViewScrollBars; + global::Xamarin.Forms.Platform.Android.Resource.Style.scrollViewTheme = global::xamarinFormApp.Droid.Resource.Style.scrollViewTheme; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Body1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Body1; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Body2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Body2; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Button = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Button; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Caption = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Caption; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Display1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Display1; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Display2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Display2; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Display3 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Display3; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Display4 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Display4; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Headline = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Headline; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Large = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Large; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Large_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Large_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Light_SearchResult_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Light_SearchResult_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Light_SearchResult_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Light_SearchResult_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Light_Widget_PopupMenu_Large = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Light_Widget_PopupMenu_Large; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Light_Widget_PopupMenu_Small = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Light_Widget_PopupMenu_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Medium = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Medium; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Medium_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Medium_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Menu = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Menu; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_SearchResult_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_SearchResult_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_SearchResult_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_SearchResult_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Small = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Small_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Small_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Subhead = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Subhead; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Subhead_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Subhead_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Title_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Tooltip = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Tooltip; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Menu = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Menu; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Subtitle_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Subtitle_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Title_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_Button = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Button; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_Button_Borderless_Colored = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Button_Borderless_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_Button_Colored = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Button_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_Button_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Button_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_DropDownItem = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_DropDownItem; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Header = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Header; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Large = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Large; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Small = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_Switch = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Switch; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_AppCompat_Widget_TextView_SpinnerItem = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_TextView_SpinnerItem; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Info = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Info; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Info_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Info_Media; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Line2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Line2; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Line2_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Line2_Media; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Media; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Time = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Time; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Time_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Time_Media; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Compat_Notification_Title_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Title_Media; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Design_CollapsingToolbar_Expanded = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_CollapsingToolbar_Expanded; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Design_Counter = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Counter; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Design_Counter_Overflow = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Counter_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Design_Error = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Error; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Design_HelperText = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_HelperText; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Design_Hint = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Hint; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Design_Snackbar_Message = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Snackbar_Message; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Design_Tab = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Tab; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Body1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Body1; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Body2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Body2; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Button = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Button; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Caption = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Caption; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Chip = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Chip; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Headline1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline1; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Headline2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline2; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Headline3 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline3; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Headline4 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline4; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Headline5 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline5; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Headline6 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline6; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Overline = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Overline; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Subtitle1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Subtitle1; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Subtitle2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Subtitle2; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_MaterialComponents_Tab = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Tab; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Widget_AppCompat_ExpandedMenu_Item = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Widget_AppCompat_ExpandedMenu_Item; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Widget_AppCompat_Toolbar_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Widget_AppCompat_Toolbar_Subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Style.TextAppearance_Widget_AppCompat_Toolbar_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Widget_AppCompat_Toolbar_Title; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_AppCompat = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_AppCompat_ActionBar = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_AppCompat_Dark = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Dark; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_AppCompat_Dark_ActionBar = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Dark_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_AppCompat_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_ActionBar = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_Dark = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Dark; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_Dark_ActionBar = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Dark_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox_Dense = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox_Dense; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox; + global::Xamarin.Forms.Platform.Android.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox_Dense = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox_Dense; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_CompactMenu = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_CompactMenu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_DayNight = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_DayNight_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_DarkActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_DayNight_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_DayNight_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_DayNight_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_DayNight_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_DayNight_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_NoActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Light_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_DarkActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Light_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Light_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Light_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_Light_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_NoActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_AppCompat_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_NoActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_Design = global::xamarinFormApp.Droid.Resource.Style.Theme_Design; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_Design_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_BottomSheetDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_Design_Light = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_Design_Light_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_Light_BottomSheetDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_Design_Light_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_Light_NoActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_Design_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_NoActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_BottomSheetDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_CompactMenu = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_CompactMenu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_BottomSheetDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_DarkActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_DarkActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_DarkActionBar_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_DialogWhenLarge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_Dialog_Alert; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_NoActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_Light_NoActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_NoActionBar_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_NoActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Theme_MaterialComponents_NoActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_NoActionBar_Bridge; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionBar_Solid = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar_Solid; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionBar_TabBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar_TabBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionBar_TabText = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar_TabText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionBar_TabView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar_TabView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionButton = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionButton_CloseMode = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionButton_CloseMode; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionButton_Overflow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionButton_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActionMode = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionMode; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ActivityChooserView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActivityChooserView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_AutoCompleteTextView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_AutoCompleteTextView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Button = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ButtonBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ButtonBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ButtonBar_AlertDialog = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ButtonBar_AlertDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Button_Borderless = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_Borderless; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Button_Borderless_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_Borderless_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Button_ButtonBar_AlertDialog = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_ButtonBar_AlertDialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Button_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Button_Small = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_CompoundButton_CheckBox = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_CompoundButton_CheckBox; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_CompoundButton_RadioButton = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_CompoundButton_RadioButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_CompoundButton_Switch = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_CompoundButton_Switch; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_DrawerArrowToggle = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_DrawerArrowToggle; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_DropDownItem_Spinner = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_DropDownItem_Spinner; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_EditText = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_EditText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ImageButton = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ImageButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar_Solid = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_Solid; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar_Solid_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_Solid_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar_TabBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar_TabBar_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabBar_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar_TabText = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar_TabText_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabText_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar_TabView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionBar_TabView_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabView_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionButton = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionButton_CloseMode = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionButton_CloseMode; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionButton_Overflow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionButton_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActionMode_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionMode_Inverse; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ActivityChooserView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActivityChooserView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_AutoCompleteTextView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_AutoCompleteTextView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_DropDownItem_Spinner = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_DropDownItem_Spinner; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ListPopupWindow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ListPopupWindow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_ListView_DropDown = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ListView_DropDown; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_PopupMenu = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_PopupMenu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_PopupMenu_Overflow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_PopupMenu_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_SearchView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_SearchView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Light_Spinner_DropDown_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_Spinner_DropDown_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ListMenuView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListMenuView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ListPopupWindow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListPopupWindow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ListView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ListView_DropDown = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListView_DropDown; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ListView_Menu = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListView_Menu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_PopupMenu = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_PopupMenu; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_PopupMenu_Overflow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_PopupMenu_Overflow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_PopupWindow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_PopupWindow; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ProgressBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ProgressBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_ProgressBar_Horizontal = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ProgressBar_Horizontal; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_RatingBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_RatingBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_RatingBar_Indicator = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_RatingBar_Indicator; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_RatingBar_Small = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_RatingBar_Small; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_SearchView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_SearchView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_SearchView_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_SearchView_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_SeekBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_SeekBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_SeekBar_Discrete = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_SeekBar_Discrete; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Spinner = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Spinner; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Spinner_DropDown = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Spinner_DropDown; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Spinner_DropDown_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Spinner_DropDown_ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Spinner_Underlined = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Spinner_Underlined; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_TextView_SpinnerItem = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_TextView_SpinnerItem; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_AppCompat_Toolbar_Button_Navigation = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Toolbar_Button_Navigation; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Compat_NotificationActionContainer = global::xamarinFormApp.Droid.Resource.Style.Widget_Compat_NotificationActionContainer; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Compat_NotificationActionText = global::xamarinFormApp.Droid.Resource.Style.Widget_Compat_NotificationActionText; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_AppBarLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_AppBarLayout; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_BottomNavigationView = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_BottomNavigationView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_BottomSheet_Modal = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_BottomSheet_Modal; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_CollapsingToolbar = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_CollapsingToolbar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_FloatingActionButton = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_FloatingActionButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_NavigationView = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_NavigationView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_ScrimInsetsFrameLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_ScrimInsetsFrameLayout; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_Snackbar = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_Snackbar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_TabLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_TabLayout; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Design_TextInputLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_TextInputLayout; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_BottomAppBar = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomAppBar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_BottomAppBar_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomAppBar_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_BottomNavigationView = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomNavigationView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_BottomNavigationView_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomNavigationView_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_BottomSheet_Modal = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomSheet_Modal; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_Icon; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_OutlinedButton = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_OutlinedButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_OutlinedButton_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_OutlinedButton_Icon; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_TextButton = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_TextButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_TextButton_Dialog = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_TextButton_Dialog; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_TextButton_Dialog_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_TextButton_Dialog_Icon; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_TextButton_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_TextButton_Icon; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_UnelevatedButton = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_UnelevatedButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Button_UnelevatedButton_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_UnelevatedButton_Icon; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_CardView = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_CardView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_ChipGroup = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_ChipGroup; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Chip_Action = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Chip_Action; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Chip_Choice = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Chip_Choice; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Chip_Entry = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Chip_Entry; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Chip_Filter = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Chip_Filter; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_FloatingActionButton = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_FloatingActionButton; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_NavigationView = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_NavigationView; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Snackbar = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Snackbar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Snackbar_FullWidth = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Snackbar_FullWidth; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TabLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TabLayout; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TabLayout_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TabLayout_Colored; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TextInputEditText_FilledBox = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputEditText_FilledBox; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TextInputEditText_FilledBox_Dense = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputEditText_FilledBox_Dense; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TextInputEditText_OutlinedBox = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputEditText_OutlinedBox; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TextInputEditText_OutlinedBox_Dense = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputEditText_OutlinedBox_Dense; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TextInputLayout_FilledBox = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputLayout_FilledBox; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TextInputLayout_FilledBox_Dense = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputLayout_FilledBox_Dense; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TextInputLayout_OutlinedBox = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputLayout_OutlinedBox; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_TextInputLayout_OutlinedBox_Dense = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputLayout_OutlinedBox_Dense; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_MaterialComponents_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Style.Widget_Support_CoordinatorLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Support_CoordinatorLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBarLayout = global::xamarinFormApp.Droid.Resource.Styleable.ActionBarLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBarLayout_android_layout_gravity = global::xamarinFormApp.Droid.Resource.Styleable.ActionBarLayout_android_layout_gravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_background = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_background; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_backgroundSplit = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_backgroundSplit; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_backgroundStacked = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_backgroundStacked; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_contentInsetEnd = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_contentInsetEndWithActions = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetEndWithActions; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_contentInsetLeft = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetLeft; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_contentInsetRight = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetRight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_contentInsetStart = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_contentInsetStartWithNavigation = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetStartWithNavigation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_customNavigationLayout = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_customNavigationLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_displayOptions = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_displayOptions; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_divider = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_divider; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_elevation = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_height = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_height; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_hideOnContentScroll = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_hideOnContentScroll; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_homeAsUpIndicator = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_homeAsUpIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_homeLayout = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_homeLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_icon = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_icon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_indeterminateProgressStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_indeterminateProgressStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_itemPadding = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_itemPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_logo = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_logo; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_navigationMode = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_navigationMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_popupTheme = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_popupTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_progressBarPadding = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_progressBarPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_progressBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_progressBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_subtitle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_subtitleTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_subtitleTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_title = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_title; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionBar_titleTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_titleTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMenuItemView = global::xamarinFormApp.Droid.Resource.Styleable.ActionMenuItemView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMenuItemView_android_minWidth = global::xamarinFormApp.Droid.Resource.Styleable.ActionMenuItemView_android_minWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMenuView = global::xamarinFormApp.Droid.Resource.Styleable.ActionMenuView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMode = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMode_background = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_background; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMode_backgroundSplit = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_backgroundSplit; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMode_closeItemLayout = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_closeItemLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMode_height = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_height; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMode_subtitleTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_subtitleTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActionMode_titleTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_titleTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActivityChooserView = global::xamarinFormApp.Droid.Resource.Styleable.ActivityChooserView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActivityChooserView_expandActivityOverflowButtonDrawable = global::xamarinFormApp.Droid.Resource.Styleable.ActivityChooserView_expandActivityOverflowButtonDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ActivityChooserView_initialActivityCount = global::xamarinFormApp.Droid.Resource.Styleable.ActivityChooserView_initialActivityCount; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog_android_layout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_android_layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog_buttonIconDimen = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_buttonIconDimen; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog_buttonPanelSideLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_buttonPanelSideLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog_listItemLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_listItemLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog_listLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_listLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog_multiChoiceItemLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_multiChoiceItemLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog_showTitle = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_showTitle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AlertDialog_singleChoiceItemLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_singleChoiceItemLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableCompat = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableCompat_android_constantSize = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_constantSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableCompat_android_dither = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_dither; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableCompat_android_enterFadeDuration = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_enterFadeDuration; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableCompat_android_exitFadeDuration = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_exitFadeDuration; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableCompat_android_variablePadding = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_variablePadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableCompat_android_visible = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_visible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableItem = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableItem; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableItem_android_drawable = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableItem_android_drawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableItem_android_id = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableItem_android_id; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableTransition = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableTransition_android_drawable = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition_android_drawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableTransition_android_fromId = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition_android_fromId; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableTransition_android_reversible = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition_android_reversible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AnimatedStateListDrawableTransition_android_toId = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition_android_toId; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayoutStates = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayoutStates_state_collapsed = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates_state_collapsed; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayoutStates_state_collapsible = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates_state_collapsible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayoutStates_state_liftable = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates_state_liftable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayoutStates_state_lifted = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates_state_lifted; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_android_background = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_android_background; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_android_keyboardNavigationCluster = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_android_keyboardNavigationCluster; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_android_touchscreenBlocksFocus = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_android_touchscreenBlocksFocus; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_elevation = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_expanded = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_expanded; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_Layout = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_Layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_Layout_layout_scrollFlags = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_Layout_layout_scrollFlags; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_Layout_layout_scrollInterpolator = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_Layout_layout_scrollInterpolator; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppBarLayout_liftOnScroll = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_liftOnScroll; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatImageView = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatImageView_android_src = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView_android_src; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatImageView_srcCompat = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView_srcCompat; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatImageView_tint = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView_tint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatImageView_tintMode = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView_tintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatSeekBar = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatSeekBar_android_thumb = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar_android_thumb; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatSeekBar_tickMark = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar_tickMark; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatSeekBar_tickMarkTint = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar_tickMarkTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatSeekBar_tickMarkTintMode = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar_tickMarkTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextHelper = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextHelper_android_drawableBottom = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableBottom; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextHelper_android_drawableEnd = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextHelper_android_drawableLeft = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableLeft; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextHelper_android_drawableRight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableRight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextHelper_android_drawableStart = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextHelper_android_drawableTop = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableTop; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextHelper_android_textAppearance = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_textAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_android_textAppearance = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_android_textAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_autoSizeMaxTextSize = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizeMaxTextSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_autoSizeMinTextSize = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizeMinTextSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_autoSizePresetSizes = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizePresetSizes; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_autoSizeStepGranularity = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizeStepGranularity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_autoSizeTextType = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizeTextType; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_firstBaselineToTopHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_firstBaselineToTopHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_fontFamily = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_fontFamily; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_lastBaselineToBottomHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_lastBaselineToBottomHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_lineHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_lineHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTextView_textAllCaps = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_textAllCaps; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarDivider = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarDivider; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarItemBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarItemBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarPopupTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarPopupTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarSize = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarSplitStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarSplitStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarTabBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarTabBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarTabStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarTabStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarTabTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarTabTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionBarWidgetTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarWidgetTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionDropDownStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionDropDownStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionMenuTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionMenuTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionMenuTextColor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionMenuTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeCloseButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeCloseButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeCloseDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeCloseDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeCopyDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeCopyDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeCutDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeCutDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeFindDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeFindDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModePasteDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModePasteDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModePopupWindowStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModePopupWindowStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeSelectAllDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeSelectAllDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeShareDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeShareDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeSplitBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeSplitBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionModeWebSearchDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeWebSearchDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionOverflowButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionOverflowButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_actionOverflowMenuStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionOverflowMenuStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_activityChooserViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_activityChooserViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_alertDialogButtonGroupStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_alertDialogButtonGroupStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_alertDialogCenterButtons = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_alertDialogCenterButtons; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_alertDialogStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_alertDialogStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_alertDialogTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_alertDialogTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_android_windowAnimationStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_android_windowAnimationStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_android_windowIsFloating = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_android_windowIsFloating; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_autoCompleteTextViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_autoCompleteTextViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_borderlessButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_borderlessButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_buttonBarButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_buttonBarNegativeButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarNegativeButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_buttonBarNeutralButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarNeutralButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_buttonBarPositiveButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarPositiveButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_buttonBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_buttonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_buttonStyleSmall = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonStyleSmall; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_checkboxStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_checkboxStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_checkedTextViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_checkedTextViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorAccent = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorAccent; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorBackgroundFloating = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorBackgroundFloating; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorButtonNormal = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorButtonNormal; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorControlActivated = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorControlActivated; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorControlHighlight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorControlHighlight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorControlNormal = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorControlNormal; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorError = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorError; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorPrimary = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorPrimary; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorPrimaryDark = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorPrimaryDark; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_colorSwitchThumbNormal = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorSwitchThumbNormal; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_controlBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_controlBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_dialogCornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dialogCornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_dialogPreferredPadding = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dialogPreferredPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_dialogTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dialogTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_dividerHorizontal = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dividerHorizontal; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_dividerVertical = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dividerVertical; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_dropdownListPreferredItemHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dropdownListPreferredItemHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_dropDownListViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dropDownListViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_editTextBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_editTextBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_editTextColor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_editTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_editTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_editTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_homeAsUpIndicator = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_homeAsUpIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_imageButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_imageButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listChoiceBackgroundIndicator = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listChoiceBackgroundIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listDividerAlertDialog = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listDividerAlertDialog; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listMenuViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listMenuViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listPopupWindowStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPopupWindowStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listPreferredItemHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listPreferredItemHeightLarge = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemHeightLarge; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listPreferredItemHeightSmall = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemHeightSmall; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listPreferredItemPaddingLeft = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemPaddingLeft; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_listPreferredItemPaddingRight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemPaddingRight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_panelBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_panelBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_panelMenuListTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_panelMenuListTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_panelMenuListWidth = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_panelMenuListWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_popupMenuStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_popupMenuStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_popupWindowStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_popupWindowStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_radioButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_radioButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_ratingBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_ratingBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_ratingBarStyleIndicator = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_ratingBarStyleIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_ratingBarStyleSmall = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_ratingBarStyleSmall; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_searchViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_searchViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_seekBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_seekBarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_selectableItemBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_selectableItemBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_selectableItemBackgroundBorderless = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_selectableItemBackgroundBorderless; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_spinnerDropDownItemStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_spinnerDropDownItemStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_spinnerStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_spinnerStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_switchStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_switchStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textAppearanceLargePopupMenu = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceLargePopupMenu; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textAppearanceListItem = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceListItem; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textAppearanceListItemSecondary = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceListItemSecondary; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textAppearanceListItemSmall = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceListItemSmall; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textAppearancePopupMenuHeader = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearancePopupMenuHeader; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textAppearanceSearchResultSubtitle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceSearchResultSubtitle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textAppearanceSearchResultTitle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceSearchResultTitle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textAppearanceSmallPopupMenu = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceSmallPopupMenu; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textColorAlertDialogListItem = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textColorAlertDialogListItem; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_textColorSearchUrl = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textColorSearchUrl; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_toolbarNavigationButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_toolbarNavigationButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_toolbarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_toolbarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_tooltipForegroundColor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_tooltipForegroundColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_tooltipFrameBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_tooltipFrameBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_viewInflaterClass = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_viewInflaterClass; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowActionBar = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowActionBar; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowActionBarOverlay = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowActionBarOverlay; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowActionModeOverlay = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowActionModeOverlay; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowFixedHeightMajor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowFixedHeightMajor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowFixedHeightMinor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowFixedHeightMinor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowFixedWidthMajor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowFixedWidthMajor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowFixedWidthMinor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowFixedWidthMinor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowMinWidthMajor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowMinWidthMajor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowMinWidthMinor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowMinWidthMinor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.AppCompatTheme_windowNoTitle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowNoTitle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomAppBar = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomAppBar_backgroundTint = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_backgroundTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomAppBar_fabAlignmentMode = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_fabAlignmentMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomAppBar_fabCradleMargin = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_fabCradleMargin; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomAppBar_fabCradleRoundedCornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_fabCradleRoundedCornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomAppBar_fabCradleVerticalOffset = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_fabCradleVerticalOffset; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomAppBar_hideOnScroll = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_hideOnScroll; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_elevation = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_itemBackground = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_itemHorizontalTranslationEnabled = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemHorizontalTranslationEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_itemIconSize = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemIconSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_itemIconTint = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_itemTextAppearanceActive = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemTextAppearanceActive; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_itemTextAppearanceInactive = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemTextAppearanceInactive; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_itemTextColor = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_labelVisibilityMode = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_labelVisibilityMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomNavigationView_menu = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_menu; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomSheetBehavior_Layout = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomSheetBehavior_Layout_behavior_fitToContents = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout_behavior_fitToContents; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomSheetBehavior_Layout_behavior_hideable = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout_behavior_hideable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomSheetBehavior_Layout_behavior_peekHeight = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout_behavior_peekHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.BottomSheetBehavior_Layout_behavior_skipCollapsed = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout_behavior_skipCollapsed; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ButtonBarLayout = global::xamarinFormApp.Droid.Resource.Styleable.ButtonBarLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ButtonBarLayout_allowStacking = global::xamarinFormApp.Droid.Resource.Styleable.ButtonBarLayout_allowStacking; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView = global::xamarinFormApp.Droid.Resource.Styleable.CardView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_android_minHeight = global::xamarinFormApp.Droid.Resource.Styleable.CardView_android_minHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_android_minWidth = global::xamarinFormApp.Droid.Resource.Styleable.CardView_android_minWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_cardBackgroundColor = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardBackgroundColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_cardCornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardCornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_cardElevation = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardElevation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_cardMaxElevation = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardMaxElevation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_cardPreventCornerOverlap = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardPreventCornerOverlap; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_cardUseCompatPadding = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardUseCompatPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_contentPadding = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_contentPaddingBottom = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPaddingBottom; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_contentPaddingLeft = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPaddingLeft; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_contentPaddingRight = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPaddingRight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CardView_contentPaddingTop = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPaddingTop; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip = global::xamarinFormApp.Droid.Resource.Styleable.Chip; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ChipGroup = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ChipGroup_checkedChip = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_checkedChip; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ChipGroup_chipSpacing = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_chipSpacing; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ChipGroup_chipSpacingHorizontal = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_chipSpacingHorizontal; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ChipGroup_chipSpacingVertical = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_chipSpacingVertical; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ChipGroup_singleLine = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_singleLine; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ChipGroup_singleSelection = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_singleSelection; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_android_checkable = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_checkable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_android_ellipsize = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_ellipsize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_android_maxWidth = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_maxWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_android_text = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_text; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_android_textAppearance = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_textAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_checkedIcon = global::xamarinFormApp.Droid.Resource.Styleable.Chip_checkedIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_checkedIconEnabled = global::xamarinFormApp.Droid.Resource.Styleable.Chip_checkedIconEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_checkedIconVisible = global::xamarinFormApp.Droid.Resource.Styleable.Chip_checkedIconVisible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipBackgroundColor = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipBackgroundColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipCornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipCornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipEndPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipEndPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipIcon = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipIconEnabled = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIconEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipIconSize = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIconSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipIconTint = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipIconVisible = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIconVisible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipMinHeight = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipMinHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipStartPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipStartPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipStrokeColor = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipStrokeColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_chipStrokeWidth = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipStrokeWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_closeIcon = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_closeIconEnabled = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_closeIconEndPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconEndPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_closeIconSize = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_closeIconStartPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconStartPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_closeIconTint = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_closeIconVisible = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconVisible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_hideMotionSpec = global::xamarinFormApp.Droid.Resource.Styleable.Chip_hideMotionSpec; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_iconEndPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_iconEndPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_iconStartPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_iconStartPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_rippleColor = global::xamarinFormApp.Droid.Resource.Styleable.Chip_rippleColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_showMotionSpec = global::xamarinFormApp.Droid.Resource.Styleable.Chip_showMotionSpec; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_textEndPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_textEndPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Chip_textStartPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_textStartPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_collapsedTitleGravity = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_collapsedTitleGravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_collapsedTitleTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_collapsedTitleTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_contentScrim = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_contentScrim; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_expandedTitleGravity = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleGravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMargin = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMargin; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginBottom = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginBottom; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginEnd = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginStart = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginTop = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginTop; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_expandedTitleTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_Layout = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_Layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_Layout_layout_collapseMode = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_Layout_layout_collapseMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_Layout_layout_collapseParallaxMultiplier = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_Layout_layout_collapseParallaxMultiplier; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_scrimAnimationDuration = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_scrimAnimationDuration; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_scrimVisibleHeightTrigger = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_scrimVisibleHeightTrigger; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_statusBarScrim = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_statusBarScrim; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_title = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_title; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_titleEnabled = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_titleEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CollapsingToolbarLayout_toolbarId = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_toolbarId; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ColorStateListItem = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ColorStateListItem_alpha = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ColorStateListItem_android_alpha = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_android_alpha; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ColorStateListItem_android_color = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_android_color; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CompoundButton = global::xamarinFormApp.Droid.Resource.Styleable.CompoundButton; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CompoundButton_android_button = global::xamarinFormApp.Droid.Resource.Styleable.CompoundButton_android_button; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CompoundButton_buttonTint = global::xamarinFormApp.Droid.Resource.Styleable.CompoundButton_buttonTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CompoundButton_buttonTintMode = global::xamarinFormApp.Droid.Resource.Styleable.CompoundButton_buttonTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_keylines = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_keylines; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_Layout = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_Layout_android_layout_gravity = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_android_layout_gravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_Layout_layout_anchor = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_anchor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_Layout_layout_anchorGravity = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_anchorGravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_Layout_layout_behavior = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_behavior; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_Layout_layout_dodgeInsetEdges = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_dodgeInsetEdges; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_Layout_layout_insetEdge = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_insetEdge; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_Layout_layout_keyline = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_keyline; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.CoordinatorLayout_statusBarBackground = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_statusBarBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DesignTheme = global::xamarinFormApp.Droid.Resource.Styleable.DesignTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DesignTheme_bottomSheetDialogTheme = global::xamarinFormApp.Droid.Resource.Styleable.DesignTheme_bottomSheetDialogTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DesignTheme_bottomSheetStyle = global::xamarinFormApp.Droid.Resource.Styleable.DesignTheme_bottomSheetStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle_arrowHeadLength = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_arrowHeadLength; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle_arrowShaftLength = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_arrowShaftLength; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle_barLength = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_barLength; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle_color = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_color; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle_drawableSize = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_drawableSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle_gapBetweenBars = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_gapBetweenBars; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle_spinBars = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_spinBars; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.DrawerArrowToggle_thickness = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_thickness; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_backgroundTint = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_backgroundTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_backgroundTintMode = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_backgroundTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_Behavior_Layout = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_Behavior_Layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_Behavior_Layout_behavior_autoHide = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_Behavior_Layout_behavior_autoHide; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_borderWidth = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_borderWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_elevation = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_fabCustomSize = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_fabCustomSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_fabSize = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_fabSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_hideMotionSpec = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_hideMotionSpec; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_hoveredFocusedTranslationZ = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_hoveredFocusedTranslationZ; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_maxImageSize = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_maxImageSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_pressedTranslationZ = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_pressedTranslationZ; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_rippleColor = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_rippleColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_showMotionSpec = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_showMotionSpec; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FloatingActionButton_useCompatPadding = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_useCompatPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FlowLayout = global::xamarinFormApp.Droid.Resource.Styleable.FlowLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FlowLayout_itemSpacing = global::xamarinFormApp.Droid.Resource.Styleable.FlowLayout_itemSpacing; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FlowLayout_lineSpacing = global::xamarinFormApp.Droid.Resource.Styleable.FlowLayout_lineSpacing; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamily = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_android_font = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_font; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_android_fontStyle = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_android_fontVariationSettings = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontVariationSettings; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_android_fontWeight = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontWeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_android_ttcIndex = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_ttcIndex; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_font = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_font; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_fontStyle = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_fontVariationSettings = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontVariationSettings; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_fontWeight = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontWeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamilyFont_ttcIndex = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_ttcIndex; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamily_fontProviderAuthority = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderAuthority; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamily_fontProviderCerts = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderCerts; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamily_fontProviderFetchStrategy = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderFetchStrategy; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamily_fontProviderFetchTimeout = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderFetchTimeout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamily_fontProviderPackage = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderPackage; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.FontFamily_fontProviderQuery = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderQuery; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ForegroundLinearLayout = global::xamarinFormApp.Droid.Resource.Styleable.ForegroundLinearLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ForegroundLinearLayout_android_foreground = global::xamarinFormApp.Droid.Resource.Styleable.ForegroundLinearLayout_android_foreground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ForegroundLinearLayout_android_foregroundGravity = global::xamarinFormApp.Droid.Resource.Styleable.ForegroundLinearLayout_android_foregroundGravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ForegroundLinearLayout_foregroundInsidePadding = global::xamarinFormApp.Droid.Resource.Styleable.ForegroundLinearLayout_foregroundInsidePadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColorItem = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColorItem_android_color = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem_android_color; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColorItem_android_offset = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem_android_offset; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_centerColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_centerX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerX; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_centerY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerY; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_endColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_endX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endX; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_endY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endY; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_gradientRadius = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_gradientRadius; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_startColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_startX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startX; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_startY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startY; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_tileMode = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_tileMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.GradientColor_android_type = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_type; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ItemsViewRendererTheme = global::xamarinFormApp.Droid.Resource.Styleable.ItemsViewRendererTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ItemsViewRendererTheme_collectionViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.ItemsViewRendererTheme_collectionViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_android_baselineAligned = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_baselineAligned; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_android_baselineAlignedChildIndex = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_baselineAlignedChildIndex; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_android_gravity = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_gravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_android_orientation = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_orientation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_android_weightSum = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_weightSum; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_divider = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_divider; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_dividerPadding = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_dividerPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_Layout = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_gravity = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_gravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_height = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_height; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_weight = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_weight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_width = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_width; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_measureWithLargestChild = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_measureWithLargestChild; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.LinearLayoutCompat_showDividers = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_showDividers; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ListPopupWindow = global::xamarinFormApp.Droid.Resource.Styleable.ListPopupWindow; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ListPopupWindow_android_dropDownHorizontalOffset = global::xamarinFormApp.Droid.Resource.Styleable.ListPopupWindow_android_dropDownHorizontalOffset; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ListPopupWindow_android_dropDownVerticalOffset = global::xamarinFormApp.Droid.Resource.Styleable.ListPopupWindow_android_dropDownVerticalOffset; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_android_insetBottom = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_android_insetBottom; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_android_insetLeft = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_android_insetLeft; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_android_insetRight = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_android_insetRight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_android_insetTop = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_android_insetTop; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_backgroundTint = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_backgroundTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_backgroundTintMode = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_backgroundTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_cornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_cornerRadius; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_icon = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_icon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_iconGravity = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconGravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_iconPadding = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_iconSize = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_iconTint = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_iconTintMode = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_rippleColor = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_rippleColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_strokeColor = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_strokeColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialButton_strokeWidth = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_strokeWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialCardView = global::xamarinFormApp.Droid.Resource.Styleable.MaterialCardView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialCardView_strokeColor = global::xamarinFormApp.Droid.Resource.Styleable.MaterialCardView_strokeColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialCardView_strokeWidth = global::xamarinFormApp.Droid.Resource.Styleable.MaterialCardView_strokeWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_bottomSheetDialogTheme = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_bottomSheetDialogTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_bottomSheetStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_bottomSheetStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_chipGroupStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_chipGroupStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_chipStandaloneStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_chipStandaloneStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_chipStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_chipStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_colorAccent = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorAccent; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_colorBackgroundFloating = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorBackgroundFloating; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_colorPrimary = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorPrimary; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_colorPrimaryDark = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorPrimaryDark; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_colorSecondary = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorSecondary; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_editTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_editTextStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_floatingActionButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_floatingActionButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_materialButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_materialButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_materialCardViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_materialCardViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_navigationViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_navigationViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_scrimBackground = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_scrimBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_snackbarButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_snackbarButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_tabStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_tabStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceBody1 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceBody1; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceBody2 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceBody2; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceButton = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceButton; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceCaption = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceCaption; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline1 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline1; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline2 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline2; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline3 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline3; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline4 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline4; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline5 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline5; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline6 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline6; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceOverline = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceOverline; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceSubtitle1 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceSubtitle1; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textAppearanceSubtitle2 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceSubtitle2; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MaterialComponentsTheme_textInputStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textInputStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuGroup = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuGroup_android_checkableBehavior = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_checkableBehavior; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuGroup_android_enabled = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_enabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuGroup_android_id = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_id; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuGroup_android_menuCategory = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_menuCategory; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuGroup_android_orderInCategory = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_orderInCategory; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuGroup_android_visible = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_visible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_actionLayout = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_actionLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_actionProviderClass = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_actionProviderClass; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_actionViewClass = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_actionViewClass; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_alphabeticModifiers = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_alphabeticModifiers; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_alphabeticShortcut = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_alphabeticShortcut; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_checkable = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_checkable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_checked = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_checked; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_enabled = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_enabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_icon = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_icon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_id = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_id; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_menuCategory = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_menuCategory; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_numericShortcut = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_numericShortcut; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_onClick = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_onClick; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_orderInCategory = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_orderInCategory; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_title = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_title; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_titleCondensed = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_titleCondensed; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_android_visible = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_visible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_contentDescription = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_contentDescription; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_iconTint = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_iconTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_iconTintMode = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_iconTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_numericModifiers = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_numericModifiers; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_showAsAction = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_showAsAction; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuItem_tooltipText = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_tooltipText; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView = global::xamarinFormApp.Droid.Resource.Styleable.MenuView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_android_headerBackground = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_headerBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_android_horizontalDivider = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_horizontalDivider; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_android_itemBackground = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_itemBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_android_itemIconDisabledAlpha = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_itemIconDisabledAlpha; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_android_itemTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_itemTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_android_verticalDivider = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_verticalDivider; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_android_windowAnimationStyle = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_windowAnimationStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_preserveIconSpacing = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_preserveIconSpacing; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.MenuView_subMenuArrow = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_subMenuArrow; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_android_background = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_android_background; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_android_fitsSystemWindows = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_android_fitsSystemWindows; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_android_maxWidth = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_android_maxWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_elevation = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_headerLayout = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_headerLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_itemBackground = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_itemHorizontalPadding = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemHorizontalPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_itemIconPadding = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemIconPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_itemIconTint = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_itemTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_itemTextColor = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.NavigationView_menu = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_menu; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.PopupWindow = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindow; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.PopupWindowBackgroundState = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindowBackgroundState; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.PopupWindowBackgroundState_state_above_anchor = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindowBackgroundState_state_above_anchor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.PopupWindow_android_popupAnimationStyle = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindow_android_popupAnimationStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.PopupWindow_android_popupBackground = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindow_android_popupBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.PopupWindow_overlapAnchor = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindow_overlapAnchor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecycleListView = global::xamarinFormApp.Droid.Resource.Styleable.RecycleListView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecycleListView_paddingBottomNoButtons = global::xamarinFormApp.Droid.Resource.Styleable.RecycleListView_paddingBottomNoButtons; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecycleListView_paddingTopNoTitle = global::xamarinFormApp.Droid.Resource.Styleable.RecycleListView_paddingTopNoTitle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_android_descendantFocusability = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_android_descendantFocusability; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_android_orientation = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_android_orientation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_fastScrollEnabled = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_fastScrollHorizontalThumbDrawable = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollHorizontalThumbDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_fastScrollHorizontalTrackDrawable = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollHorizontalTrackDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_fastScrollVerticalThumbDrawable = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollVerticalThumbDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_fastScrollVerticalTrackDrawable = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollVerticalTrackDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_layoutManager = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_layoutManager; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_reverseLayout = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_reverseLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_spanCount = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_spanCount; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.RecyclerView_stackFromEnd = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_stackFromEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ScrimInsetsFrameLayout = global::xamarinFormApp.Droid.Resource.Styleable.ScrimInsetsFrameLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ScrimInsetsFrameLayout_insetForeground = global::xamarinFormApp.Droid.Resource.Styleable.ScrimInsetsFrameLayout_insetForeground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ScrollingViewBehavior_Layout = global::xamarinFormApp.Droid.Resource.Styleable.ScrollingViewBehavior_Layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ScrollingViewBehavior_Layout_behavior_overlapTop = global::xamarinFormApp.Droid.Resource.Styleable.ScrollingViewBehavior_Layout_behavior_overlapTop; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ScrollViewRendererTheme = global::xamarinFormApp.Droid.Resource.Styleable.ScrollViewRendererTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ScrollViewRendererTheme_scrollViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.ScrollViewRendererTheme_scrollViewStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView = global::xamarinFormApp.Droid.Resource.Styleable.SearchView; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_android_focusable = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_android_focusable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_android_imeOptions = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_android_imeOptions; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_android_inputType = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_android_inputType; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_android_maxWidth = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_android_maxWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_closeIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_closeIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_commitIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_commitIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_defaultQueryHint = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_defaultQueryHint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_goIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_goIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_iconifiedByDefault = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_iconifiedByDefault; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_layout = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_queryBackground = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_queryBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_queryHint = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_queryHint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_searchHintIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_searchHintIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_searchIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_searchIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_submitBackground = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_submitBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_suggestionRowLayout = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_suggestionRowLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SearchView_voiceIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_voiceIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Snackbar = global::xamarinFormApp.Droid.Resource.Styleable.Snackbar; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SnackbarLayout = global::xamarinFormApp.Droid.Resource.Styleable.SnackbarLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SnackbarLayout_android_maxWidth = global::xamarinFormApp.Droid.Resource.Styleable.SnackbarLayout_android_maxWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SnackbarLayout_elevation = global::xamarinFormApp.Droid.Resource.Styleable.SnackbarLayout_elevation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SnackbarLayout_maxActionInlineWidth = global::xamarinFormApp.Droid.Resource.Styleable.SnackbarLayout_maxActionInlineWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Snackbar_snackbarButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.Snackbar_snackbarButtonStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Snackbar_snackbarStyle = global::xamarinFormApp.Droid.Resource.Styleable.Snackbar_snackbarStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Spinner = global::xamarinFormApp.Droid.Resource.Styleable.Spinner; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Spinner_android_dropDownWidth = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_android_dropDownWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Spinner_android_entries = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_android_entries; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Spinner_android_popupBackground = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_android_popupBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Spinner_android_prompt = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_android_prompt; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Spinner_popupTheme = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_popupTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawable = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawableItem = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawableItem; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawableItem_android_drawable = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawableItem_android_drawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawable_android_constantSize = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_constantSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawable_android_dither = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_dither; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawable_android_enterFadeDuration = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_enterFadeDuration; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawable_android_exitFadeDuration = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_exitFadeDuration; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawable_android_variablePadding = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_variablePadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.StateListDrawable_android_visible = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_visible; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_android_textOff = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_android_textOff; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_android_textOn = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_android_textOn; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_android_thumb = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_android_thumb; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_showText = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_showText; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_splitTrack = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_splitTrack; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_switchMinWidth = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_switchMinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_switchPadding = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_switchPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_switchTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_switchTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_thumbTextPadding = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_thumbTextPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_thumbTint = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_thumbTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_thumbTintMode = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_thumbTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_track = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_track; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_trackTint = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_trackTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.SwitchCompat_trackTintMode = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_trackTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabItem = global::xamarinFormApp.Droid.Resource.Styleable.TabItem; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabItem_android_icon = global::xamarinFormApp.Droid.Resource.Styleable.TabItem_android_icon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabItem_android_layout = global::xamarinFormApp.Droid.Resource.Styleable.TabItem_android_layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabItem_android_text = global::xamarinFormApp.Droid.Resource.Styleable.TabItem_android_text; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabBackground = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabBackground; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabContentStart = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabContentStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabGravity = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabGravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabIconTint = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIconTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabIconTintMode = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIconTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabIndicator = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicator; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabIndicatorAnimationDuration = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorAnimationDuration; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabIndicatorColor = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabIndicatorFullWidth = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorFullWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabIndicatorGravity = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorGravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabIndicatorHeight = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabInlineLabel = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabInlineLabel; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabMaxWidth = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabMaxWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabMinWidth = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabMinWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabMode = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabPadding = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPadding; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabPaddingBottom = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPaddingBottom; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabPaddingEnd = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPaddingEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabPaddingStart = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPaddingStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabPaddingTop = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPaddingTop; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabRippleColor = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabRippleColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabSelectedTextColor = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabSelectedTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabTextColor = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TabLayout_tabUnboundedRipple = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabUnboundedRipple; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_fontFamily = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_fontFamily; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_shadowColor = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_shadowColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_shadowDx = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_shadowDx; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_shadowDy = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_shadowDy; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_shadowRadius = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_shadowRadius; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_textColor = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_textColorHint = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textColorHint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_textColorLink = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textColorLink; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_textSize = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textSize; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_textStyle = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textStyle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_android_typeface = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_typeface; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_fontFamily = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_fontFamily; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextAppearance_textAllCaps = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_textAllCaps; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_android_hint = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_android_hint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_android_textColorHint = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_android_textColorHint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxBackgroundColor = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxBackgroundColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxBackgroundMode = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxBackgroundMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxCollapsedPaddingTop = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCollapsedPaddingTop; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxCornerRadiusBottomEnd = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCornerRadiusBottomEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxCornerRadiusBottomStart = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCornerRadiusBottomStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxCornerRadiusTopEnd = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCornerRadiusTopEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxCornerRadiusTopStart = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCornerRadiusTopStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxStrokeColor = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxStrokeColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_boxStrokeWidth = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxStrokeWidth; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_counterEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_counterEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_counterMaxLength = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_counterMaxLength; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_counterOverflowTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_counterOverflowTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_counterTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_counterTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_errorEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_errorEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_errorTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_errorTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_helperText = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_helperText; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_helperTextEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_helperTextEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_helperTextTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_helperTextTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_hintAnimationEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_hintAnimationEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_hintEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_hintEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_hintTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_hintTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_passwordToggleContentDescription = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleContentDescription; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_passwordToggleDrawable = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleDrawable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_passwordToggleEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleEnabled; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_passwordToggleTint = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.TextInputLayout_passwordToggleTintMode = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ThemeEnforcement = global::xamarinFormApp.Droid.Resource.Styleable.ThemeEnforcement; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ThemeEnforcement_android_textAppearance = global::xamarinFormApp.Droid.Resource.Styleable.ThemeEnforcement_android_textAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ThemeEnforcement_enforceMaterialTheme = global::xamarinFormApp.Droid.Resource.Styleable.ThemeEnforcement_enforceMaterialTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ThemeEnforcement_enforceTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.ThemeEnforcement_enforceTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_android_gravity = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_android_gravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_android_minHeight = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_android_minHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_buttonGravity = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_buttonGravity; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_collapseContentDescription = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_collapseContentDescription; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_collapseIcon = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_collapseIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_contentInsetEnd = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_contentInsetEndWithActions = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetEndWithActions; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_contentInsetLeft = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetLeft; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_contentInsetRight = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetRight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_contentInsetStart = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_contentInsetStartWithNavigation = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetStartWithNavigation; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_logo = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_logo; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_logoDescription = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_logoDescription; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_maxButtonHeight = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_maxButtonHeight; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_navigationContentDescription = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_navigationContentDescription; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_navigationIcon = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_navigationIcon; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_popupTheme = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_popupTheme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_subtitle = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_subtitle; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_subtitleTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_subtitleTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_subtitleTextColor = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_subtitleTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_title = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_title; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_titleMargin = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMargin; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_titleMarginBottom = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMarginBottom; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_titleMarginEnd = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMarginEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_titleMargins = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMargins; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_titleMarginStart = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMarginStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_titleMarginTop = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMarginTop; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_titleTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleTextAppearance; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.Toolbar_titleTextColor = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleTextColor; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.View = global::xamarinFormApp.Droid.Resource.Styleable.View; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ViewBackgroundHelper = global::xamarinFormApp.Droid.Resource.Styleable.ViewBackgroundHelper; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ViewBackgroundHelper_android_background = global::xamarinFormApp.Droid.Resource.Styleable.ViewBackgroundHelper_android_background; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ViewBackgroundHelper_backgroundTint = global::xamarinFormApp.Droid.Resource.Styleable.ViewBackgroundHelper_backgroundTint; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ViewBackgroundHelper_backgroundTintMode = global::xamarinFormApp.Droid.Resource.Styleable.ViewBackgroundHelper_backgroundTintMode; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ViewStubCompat = global::xamarinFormApp.Droid.Resource.Styleable.ViewStubCompat; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ViewStubCompat_android_id = global::xamarinFormApp.Droid.Resource.Styleable.ViewStubCompat_android_id; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ViewStubCompat_android_inflatedId = global::xamarinFormApp.Droid.Resource.Styleable.ViewStubCompat_android_inflatedId; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.ViewStubCompat_android_layout = global::xamarinFormApp.Droid.Resource.Styleable.ViewStubCompat_android_layout; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.View_android_focusable = global::xamarinFormApp.Droid.Resource.Styleable.View_android_focusable; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.View_android_theme = global::xamarinFormApp.Droid.Resource.Styleable.View_android_theme; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.View_paddingEnd = global::xamarinFormApp.Droid.Resource.Styleable.View_paddingEnd; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.View_paddingStart = global::xamarinFormApp.Droid.Resource.Styleable.View_paddingStart; + global::Xamarin.Forms.Platform.Android.Resource.Styleable.View_theme = global::xamarinFormApp.Droid.Resource.Styleable.View_theme; + global::Xamarin.Forms.Platform.Resource.Animation.abc_fade_in = global::xamarinFormApp.Droid.Resource.Animation.abc_fade_in; + global::Xamarin.Forms.Platform.Resource.Animation.abc_fade_out = global::xamarinFormApp.Droid.Resource.Animation.abc_fade_out; + global::Xamarin.Forms.Platform.Resource.Animation.abc_grow_fade_in_from_bottom = global::xamarinFormApp.Droid.Resource.Animation.abc_grow_fade_in_from_bottom; + global::Xamarin.Forms.Platform.Resource.Animation.abc_popup_enter = global::xamarinFormApp.Droid.Resource.Animation.abc_popup_enter; + global::Xamarin.Forms.Platform.Resource.Animation.abc_popup_exit = global::xamarinFormApp.Droid.Resource.Animation.abc_popup_exit; + global::Xamarin.Forms.Platform.Resource.Animation.abc_shrink_fade_out_from_bottom = global::xamarinFormApp.Droid.Resource.Animation.abc_shrink_fade_out_from_bottom; + global::Xamarin.Forms.Platform.Resource.Animation.abc_slide_in_bottom = global::xamarinFormApp.Droid.Resource.Animation.abc_slide_in_bottom; + global::Xamarin.Forms.Platform.Resource.Animation.abc_slide_in_top = global::xamarinFormApp.Droid.Resource.Animation.abc_slide_in_top; + global::Xamarin.Forms.Platform.Resource.Animation.abc_slide_out_bottom = global::xamarinFormApp.Droid.Resource.Animation.abc_slide_out_bottom; + global::Xamarin.Forms.Platform.Resource.Animation.abc_slide_out_top = global::xamarinFormApp.Droid.Resource.Animation.abc_slide_out_top; + global::Xamarin.Forms.Platform.Resource.Animation.abc_tooltip_enter = global::xamarinFormApp.Droid.Resource.Animation.abc_tooltip_enter; + global::Xamarin.Forms.Platform.Resource.Animation.abc_tooltip_exit = global::xamarinFormApp.Droid.Resource.Animation.abc_tooltip_exit; + global::Xamarin.Forms.Platform.Resource.Animation.design_bottom_sheet_slide_in = global::xamarinFormApp.Droid.Resource.Animation.design_bottom_sheet_slide_in; + global::Xamarin.Forms.Platform.Resource.Animation.design_bottom_sheet_slide_out = global::xamarinFormApp.Droid.Resource.Animation.design_bottom_sheet_slide_out; + global::Xamarin.Forms.Platform.Resource.Animation.design_snackbar_in = global::xamarinFormApp.Droid.Resource.Animation.design_snackbar_in; + global::Xamarin.Forms.Platform.Resource.Animation.design_snackbar_out = global::xamarinFormApp.Droid.Resource.Animation.design_snackbar_out; + global::Xamarin.Forms.Platform.Resource.Animation.EnterFromLeft = global::xamarinFormApp.Droid.Resource.Animation.EnterFromLeft; + global::Xamarin.Forms.Platform.Resource.Animation.EnterFromRight = global::xamarinFormApp.Droid.Resource.Animation.EnterFromRight; + global::Xamarin.Forms.Platform.Resource.Animation.ExitToLeft = global::xamarinFormApp.Droid.Resource.Animation.ExitToLeft; + global::Xamarin.Forms.Platform.Resource.Animation.ExitToRight = global::xamarinFormApp.Droid.Resource.Animation.ExitToRight; + global::Xamarin.Forms.Platform.Resource.Animator.design_appbar_state_list_animator = global::xamarinFormApp.Droid.Resource.Animator.design_appbar_state_list_animator; + global::Xamarin.Forms.Platform.Resource.Animator.design_fab_hide_motion_spec = global::xamarinFormApp.Droid.Resource.Animator.design_fab_hide_motion_spec; + global::Xamarin.Forms.Platform.Resource.Animator.design_fab_show_motion_spec = global::xamarinFormApp.Droid.Resource.Animator.design_fab_show_motion_spec; + global::Xamarin.Forms.Platform.Resource.Animator.mtrl_btn_state_list_anim = global::xamarinFormApp.Droid.Resource.Animator.mtrl_btn_state_list_anim; + global::Xamarin.Forms.Platform.Resource.Animator.mtrl_btn_unelevated_state_list_anim = global::xamarinFormApp.Droid.Resource.Animator.mtrl_btn_unelevated_state_list_anim; + global::Xamarin.Forms.Platform.Resource.Animator.mtrl_chip_state_list_anim = global::xamarinFormApp.Droid.Resource.Animator.mtrl_chip_state_list_anim; + global::Xamarin.Forms.Platform.Resource.Animator.mtrl_fab_hide_motion_spec = global::xamarinFormApp.Droid.Resource.Animator.mtrl_fab_hide_motion_spec; + global::Xamarin.Forms.Platform.Resource.Animator.mtrl_fab_show_motion_spec = global::xamarinFormApp.Droid.Resource.Animator.mtrl_fab_show_motion_spec; + global::Xamarin.Forms.Platform.Resource.Animator.mtrl_fab_transformation_sheet_collapse_spec = global::xamarinFormApp.Droid.Resource.Animator.mtrl_fab_transformation_sheet_collapse_spec; + global::Xamarin.Forms.Platform.Resource.Animator.mtrl_fab_transformation_sheet_expand_spec = global::xamarinFormApp.Droid.Resource.Animator.mtrl_fab_transformation_sheet_expand_spec; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarDivider = global::xamarinFormApp.Droid.Resource.Attribute.actionBarDivider; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarItemBackground = global::xamarinFormApp.Droid.Resource.Attribute.actionBarItemBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarPopupTheme = global::xamarinFormApp.Droid.Resource.Attribute.actionBarPopupTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarSize = global::xamarinFormApp.Droid.Resource.Attribute.actionBarSize; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarSplitStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarSplitStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarTabBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarTabBarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarTabStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarTabStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarTabTextStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionBarTabTextStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarTheme = global::xamarinFormApp.Droid.Resource.Attribute.actionBarTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.actionBarWidgetTheme = global::xamarinFormApp.Droid.Resource.Attribute.actionBarWidgetTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.actionButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionDropDownStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionDropDownStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionLayout = global::xamarinFormApp.Droid.Resource.Attribute.actionLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.actionMenuTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.actionMenuTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.actionMenuTextColor = global::xamarinFormApp.Droid.Resource.Attribute.actionMenuTextColor; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeBackground = global::xamarinFormApp.Droid.Resource.Attribute.actionModeBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeCloseButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionModeCloseButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeCloseDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeCloseDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeCopyDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeCopyDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeCutDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeCutDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeFindDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeFindDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModePasteDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModePasteDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModePopupWindowStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionModePopupWindowStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeSelectAllDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeSelectAllDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeShareDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeShareDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeSplitBackground = global::xamarinFormApp.Droid.Resource.Attribute.actionModeSplitBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionModeStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionModeWebSearchDrawable = global::xamarinFormApp.Droid.Resource.Attribute.actionModeWebSearchDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.actionOverflowButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionOverflowButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionOverflowMenuStyle = global::xamarinFormApp.Droid.Resource.Attribute.actionOverflowMenuStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.actionProviderClass = global::xamarinFormApp.Droid.Resource.Attribute.actionProviderClass; + global::Xamarin.Forms.Platform.Resource.Attribute.actionViewClass = global::xamarinFormApp.Droid.Resource.Attribute.actionViewClass; + global::Xamarin.Forms.Platform.Resource.Attribute.activityChooserViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.activityChooserViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.alertDialogButtonGroupStyle = global::xamarinFormApp.Droid.Resource.Attribute.alertDialogButtonGroupStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.alertDialogCenterButtons = global::xamarinFormApp.Droid.Resource.Attribute.alertDialogCenterButtons; + global::Xamarin.Forms.Platform.Resource.Attribute.alertDialogStyle = global::xamarinFormApp.Droid.Resource.Attribute.alertDialogStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.alertDialogTheme = global::xamarinFormApp.Droid.Resource.Attribute.alertDialogTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.allowStacking = global::xamarinFormApp.Droid.Resource.Attribute.allowStacking; + global::Xamarin.Forms.Platform.Resource.Attribute.alpha = global::xamarinFormApp.Droid.Resource.Attribute.alpha; + global::Xamarin.Forms.Platform.Resource.Attribute.alphabeticModifiers = global::xamarinFormApp.Droid.Resource.Attribute.alphabeticModifiers; + global::Xamarin.Forms.Platform.Resource.Attribute.arrowHeadLength = global::xamarinFormApp.Droid.Resource.Attribute.arrowHeadLength; + global::Xamarin.Forms.Platform.Resource.Attribute.arrowShaftLength = global::xamarinFormApp.Droid.Resource.Attribute.arrowShaftLength; + global::Xamarin.Forms.Platform.Resource.Attribute.autoCompleteTextViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.autoCompleteTextViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.autoSizeMaxTextSize = global::xamarinFormApp.Droid.Resource.Attribute.autoSizeMaxTextSize; + global::Xamarin.Forms.Platform.Resource.Attribute.autoSizeMinTextSize = global::xamarinFormApp.Droid.Resource.Attribute.autoSizeMinTextSize; + global::Xamarin.Forms.Platform.Resource.Attribute.autoSizePresetSizes = global::xamarinFormApp.Droid.Resource.Attribute.autoSizePresetSizes; + global::Xamarin.Forms.Platform.Resource.Attribute.autoSizeStepGranularity = global::xamarinFormApp.Droid.Resource.Attribute.autoSizeStepGranularity; + global::Xamarin.Forms.Platform.Resource.Attribute.autoSizeTextType = global::xamarinFormApp.Droid.Resource.Attribute.autoSizeTextType; + global::Xamarin.Forms.Platform.Resource.Attribute.background = global::xamarinFormApp.Droid.Resource.Attribute.background; + global::Xamarin.Forms.Platform.Resource.Attribute.backgroundSplit = global::xamarinFormApp.Droid.Resource.Attribute.backgroundSplit; + global::Xamarin.Forms.Platform.Resource.Attribute.backgroundStacked = global::xamarinFormApp.Droid.Resource.Attribute.backgroundStacked; + global::Xamarin.Forms.Platform.Resource.Attribute.backgroundTint = global::xamarinFormApp.Droid.Resource.Attribute.backgroundTint; + global::Xamarin.Forms.Platform.Resource.Attribute.backgroundTintMode = global::xamarinFormApp.Droid.Resource.Attribute.backgroundTintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.barLength = global::xamarinFormApp.Droid.Resource.Attribute.barLength; + global::Xamarin.Forms.Platform.Resource.Attribute.behavior_autoHide = global::xamarinFormApp.Droid.Resource.Attribute.behavior_autoHide; + global::Xamarin.Forms.Platform.Resource.Attribute.behavior_fitToContents = global::xamarinFormApp.Droid.Resource.Attribute.behavior_fitToContents; + global::Xamarin.Forms.Platform.Resource.Attribute.behavior_hideable = global::xamarinFormApp.Droid.Resource.Attribute.behavior_hideable; + global::Xamarin.Forms.Platform.Resource.Attribute.behavior_overlapTop = global::xamarinFormApp.Droid.Resource.Attribute.behavior_overlapTop; + global::Xamarin.Forms.Platform.Resource.Attribute.behavior_peekHeight = global::xamarinFormApp.Droid.Resource.Attribute.behavior_peekHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.behavior_skipCollapsed = global::xamarinFormApp.Droid.Resource.Attribute.behavior_skipCollapsed; + global::Xamarin.Forms.Platform.Resource.Attribute.borderlessButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.borderlessButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.borderWidth = global::xamarinFormApp.Droid.Resource.Attribute.borderWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.bottomAppBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.bottomAppBarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.bottomNavigationStyle = global::xamarinFormApp.Droid.Resource.Attribute.bottomNavigationStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.bottomSheetDialogTheme = global::xamarinFormApp.Droid.Resource.Attribute.bottomSheetDialogTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.bottomSheetStyle = global::xamarinFormApp.Droid.Resource.Attribute.bottomSheetStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.boxBackgroundColor = global::xamarinFormApp.Droid.Resource.Attribute.boxBackgroundColor; + global::Xamarin.Forms.Platform.Resource.Attribute.boxBackgroundMode = global::xamarinFormApp.Droid.Resource.Attribute.boxBackgroundMode; + global::Xamarin.Forms.Platform.Resource.Attribute.boxCollapsedPaddingTop = global::xamarinFormApp.Droid.Resource.Attribute.boxCollapsedPaddingTop; + global::Xamarin.Forms.Platform.Resource.Attribute.boxCornerRadiusBottomEnd = global::xamarinFormApp.Droid.Resource.Attribute.boxCornerRadiusBottomEnd; + global::Xamarin.Forms.Platform.Resource.Attribute.boxCornerRadiusBottomStart = global::xamarinFormApp.Droid.Resource.Attribute.boxCornerRadiusBottomStart; + global::Xamarin.Forms.Platform.Resource.Attribute.boxCornerRadiusTopEnd = global::xamarinFormApp.Droid.Resource.Attribute.boxCornerRadiusTopEnd; + global::Xamarin.Forms.Platform.Resource.Attribute.boxCornerRadiusTopStart = global::xamarinFormApp.Droid.Resource.Attribute.boxCornerRadiusTopStart; + global::Xamarin.Forms.Platform.Resource.Attribute.boxStrokeColor = global::xamarinFormApp.Droid.Resource.Attribute.boxStrokeColor; + global::Xamarin.Forms.Platform.Resource.Attribute.boxStrokeWidth = global::xamarinFormApp.Droid.Resource.Attribute.boxStrokeWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonBarButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonBarNegativeButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarNegativeButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonBarNeutralButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarNeutralButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonBarPositiveButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarPositiveButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonBarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonGravity = global::xamarinFormApp.Droid.Resource.Attribute.buttonGravity; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonIconDimen = global::xamarinFormApp.Droid.Resource.Attribute.buttonIconDimen; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonPanelSideLayout = global::xamarinFormApp.Droid.Resource.Attribute.buttonPanelSideLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonStyle = global::xamarinFormApp.Droid.Resource.Attribute.buttonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonStyleSmall = global::xamarinFormApp.Droid.Resource.Attribute.buttonStyleSmall; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonTint = global::xamarinFormApp.Droid.Resource.Attribute.buttonTint; + global::Xamarin.Forms.Platform.Resource.Attribute.buttonTintMode = global::xamarinFormApp.Droid.Resource.Attribute.buttonTintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.cardBackgroundColor = global::xamarinFormApp.Droid.Resource.Attribute.cardBackgroundColor; + global::Xamarin.Forms.Platform.Resource.Attribute.cardCornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.cardCornerRadius; + global::Xamarin.Forms.Platform.Resource.Attribute.cardElevation = global::xamarinFormApp.Droid.Resource.Attribute.cardElevation; + global::Xamarin.Forms.Platform.Resource.Attribute.cardMaxElevation = global::xamarinFormApp.Droid.Resource.Attribute.cardMaxElevation; + global::Xamarin.Forms.Platform.Resource.Attribute.cardPreventCornerOverlap = global::xamarinFormApp.Droid.Resource.Attribute.cardPreventCornerOverlap; + global::Xamarin.Forms.Platform.Resource.Attribute.cardUseCompatPadding = global::xamarinFormApp.Droid.Resource.Attribute.cardUseCompatPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.cardViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.cardViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.checkboxStyle = global::xamarinFormApp.Droid.Resource.Attribute.checkboxStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.checkedChip = global::xamarinFormApp.Droid.Resource.Attribute.checkedChip; + global::Xamarin.Forms.Platform.Resource.Attribute.checkedIcon = global::xamarinFormApp.Droid.Resource.Attribute.checkedIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.checkedIconEnabled = global::xamarinFormApp.Droid.Resource.Attribute.checkedIconEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.checkedIconVisible = global::xamarinFormApp.Droid.Resource.Attribute.checkedIconVisible; + global::Xamarin.Forms.Platform.Resource.Attribute.checkedTextViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.checkedTextViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.chipBackgroundColor = global::xamarinFormApp.Droid.Resource.Attribute.chipBackgroundColor; + global::Xamarin.Forms.Platform.Resource.Attribute.chipCornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.chipCornerRadius; + global::Xamarin.Forms.Platform.Resource.Attribute.chipEndPadding = global::xamarinFormApp.Droid.Resource.Attribute.chipEndPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.chipGroupStyle = global::xamarinFormApp.Droid.Resource.Attribute.chipGroupStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.chipIcon = global::xamarinFormApp.Droid.Resource.Attribute.chipIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.chipIconEnabled = global::xamarinFormApp.Droid.Resource.Attribute.chipIconEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.chipIconSize = global::xamarinFormApp.Droid.Resource.Attribute.chipIconSize; + global::Xamarin.Forms.Platform.Resource.Attribute.chipIconTint = global::xamarinFormApp.Droid.Resource.Attribute.chipIconTint; + global::Xamarin.Forms.Platform.Resource.Attribute.chipIconVisible = global::xamarinFormApp.Droid.Resource.Attribute.chipIconVisible; + global::Xamarin.Forms.Platform.Resource.Attribute.chipMinHeight = global::xamarinFormApp.Droid.Resource.Attribute.chipMinHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.chipSpacing = global::xamarinFormApp.Droid.Resource.Attribute.chipSpacing; + global::Xamarin.Forms.Platform.Resource.Attribute.chipSpacingHorizontal = global::xamarinFormApp.Droid.Resource.Attribute.chipSpacingHorizontal; + global::Xamarin.Forms.Platform.Resource.Attribute.chipSpacingVertical = global::xamarinFormApp.Droid.Resource.Attribute.chipSpacingVertical; + global::Xamarin.Forms.Platform.Resource.Attribute.chipStandaloneStyle = global::xamarinFormApp.Droid.Resource.Attribute.chipStandaloneStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.chipStartPadding = global::xamarinFormApp.Droid.Resource.Attribute.chipStartPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.chipStrokeColor = global::xamarinFormApp.Droid.Resource.Attribute.chipStrokeColor; + global::Xamarin.Forms.Platform.Resource.Attribute.chipStrokeWidth = global::xamarinFormApp.Droid.Resource.Attribute.chipStrokeWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.chipStyle = global::xamarinFormApp.Droid.Resource.Attribute.chipStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.closeIcon = global::xamarinFormApp.Droid.Resource.Attribute.closeIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.closeIconEnabled = global::xamarinFormApp.Droid.Resource.Attribute.closeIconEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.closeIconEndPadding = global::xamarinFormApp.Droid.Resource.Attribute.closeIconEndPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.closeIconSize = global::xamarinFormApp.Droid.Resource.Attribute.closeIconSize; + global::Xamarin.Forms.Platform.Resource.Attribute.closeIconStartPadding = global::xamarinFormApp.Droid.Resource.Attribute.closeIconStartPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.closeIconTint = global::xamarinFormApp.Droid.Resource.Attribute.closeIconTint; + global::Xamarin.Forms.Platform.Resource.Attribute.closeIconVisible = global::xamarinFormApp.Droid.Resource.Attribute.closeIconVisible; + global::Xamarin.Forms.Platform.Resource.Attribute.closeItemLayout = global::xamarinFormApp.Droid.Resource.Attribute.closeItemLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.collapseContentDescription = global::xamarinFormApp.Droid.Resource.Attribute.collapseContentDescription; + global::Xamarin.Forms.Platform.Resource.Attribute.collapsedTitleGravity = global::xamarinFormApp.Droid.Resource.Attribute.collapsedTitleGravity; + global::Xamarin.Forms.Platform.Resource.Attribute.collapsedTitleTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.collapsedTitleTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.collapseIcon = global::xamarinFormApp.Droid.Resource.Attribute.collapseIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.collectionViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.collectionViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.color = global::xamarinFormApp.Droid.Resource.Attribute.color; + global::Xamarin.Forms.Platform.Resource.Attribute.colorAccent = global::xamarinFormApp.Droid.Resource.Attribute.colorAccent; + global::Xamarin.Forms.Platform.Resource.Attribute.colorBackgroundFloating = global::xamarinFormApp.Droid.Resource.Attribute.colorBackgroundFloating; + global::Xamarin.Forms.Platform.Resource.Attribute.colorButtonNormal = global::xamarinFormApp.Droid.Resource.Attribute.colorButtonNormal; + global::Xamarin.Forms.Platform.Resource.Attribute.colorControlActivated = global::xamarinFormApp.Droid.Resource.Attribute.colorControlActivated; + global::Xamarin.Forms.Platform.Resource.Attribute.colorControlHighlight = global::xamarinFormApp.Droid.Resource.Attribute.colorControlHighlight; + global::Xamarin.Forms.Platform.Resource.Attribute.colorControlNormal = global::xamarinFormApp.Droid.Resource.Attribute.colorControlNormal; + global::Xamarin.Forms.Platform.Resource.Attribute.colorError = global::xamarinFormApp.Droid.Resource.Attribute.colorError; + global::Xamarin.Forms.Platform.Resource.Attribute.colorPrimary = global::xamarinFormApp.Droid.Resource.Attribute.colorPrimary; + global::Xamarin.Forms.Platform.Resource.Attribute.colorPrimaryDark = global::xamarinFormApp.Droid.Resource.Attribute.colorPrimaryDark; + global::Xamarin.Forms.Platform.Resource.Attribute.colorSecondary = global::xamarinFormApp.Droid.Resource.Attribute.colorSecondary; + global::Xamarin.Forms.Platform.Resource.Attribute.colorSwitchThumbNormal = global::xamarinFormApp.Droid.Resource.Attribute.colorSwitchThumbNormal; + global::Xamarin.Forms.Platform.Resource.Attribute.commitIcon = global::xamarinFormApp.Droid.Resource.Attribute.commitIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.contentDescription = global::xamarinFormApp.Droid.Resource.Attribute.contentDescription; + global::Xamarin.Forms.Platform.Resource.Attribute.contentInsetEnd = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetEnd; + global::Xamarin.Forms.Platform.Resource.Attribute.contentInsetEndWithActions = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetEndWithActions; + global::Xamarin.Forms.Platform.Resource.Attribute.contentInsetLeft = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetLeft; + global::Xamarin.Forms.Platform.Resource.Attribute.contentInsetRight = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetRight; + global::Xamarin.Forms.Platform.Resource.Attribute.contentInsetStart = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetStart; + global::Xamarin.Forms.Platform.Resource.Attribute.contentInsetStartWithNavigation = global::xamarinFormApp.Droid.Resource.Attribute.contentInsetStartWithNavigation; + global::Xamarin.Forms.Platform.Resource.Attribute.contentPadding = global::xamarinFormApp.Droid.Resource.Attribute.contentPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.contentPaddingBottom = global::xamarinFormApp.Droid.Resource.Attribute.contentPaddingBottom; + global::Xamarin.Forms.Platform.Resource.Attribute.contentPaddingLeft = global::xamarinFormApp.Droid.Resource.Attribute.contentPaddingLeft; + global::Xamarin.Forms.Platform.Resource.Attribute.contentPaddingRight = global::xamarinFormApp.Droid.Resource.Attribute.contentPaddingRight; + global::Xamarin.Forms.Platform.Resource.Attribute.contentPaddingTop = global::xamarinFormApp.Droid.Resource.Attribute.contentPaddingTop; + global::Xamarin.Forms.Platform.Resource.Attribute.contentScrim = global::xamarinFormApp.Droid.Resource.Attribute.contentScrim; + global::Xamarin.Forms.Platform.Resource.Attribute.controlBackground = global::xamarinFormApp.Droid.Resource.Attribute.controlBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.coordinatorLayoutStyle = global::xamarinFormApp.Droid.Resource.Attribute.coordinatorLayoutStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.cornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.cornerRadius; + global::Xamarin.Forms.Platform.Resource.Attribute.counterEnabled = global::xamarinFormApp.Droid.Resource.Attribute.counterEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.counterMaxLength = global::xamarinFormApp.Droid.Resource.Attribute.counterMaxLength; + global::Xamarin.Forms.Platform.Resource.Attribute.counterOverflowTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.counterOverflowTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.counterTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.counterTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.customNavigationLayout = global::xamarinFormApp.Droid.Resource.Attribute.customNavigationLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.defaultQueryHint = global::xamarinFormApp.Droid.Resource.Attribute.defaultQueryHint; + global::Xamarin.Forms.Platform.Resource.Attribute.dialogCornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.dialogCornerRadius; + global::Xamarin.Forms.Platform.Resource.Attribute.dialogPreferredPadding = global::xamarinFormApp.Droid.Resource.Attribute.dialogPreferredPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.dialogTheme = global::xamarinFormApp.Droid.Resource.Attribute.dialogTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.displayOptions = global::xamarinFormApp.Droid.Resource.Attribute.displayOptions; + global::Xamarin.Forms.Platform.Resource.Attribute.divider = global::xamarinFormApp.Droid.Resource.Attribute.divider; + global::Xamarin.Forms.Platform.Resource.Attribute.dividerHorizontal = global::xamarinFormApp.Droid.Resource.Attribute.dividerHorizontal; + global::Xamarin.Forms.Platform.Resource.Attribute.dividerPadding = global::xamarinFormApp.Droid.Resource.Attribute.dividerPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.dividerVertical = global::xamarinFormApp.Droid.Resource.Attribute.dividerVertical; + global::Xamarin.Forms.Platform.Resource.Attribute.drawableSize = global::xamarinFormApp.Droid.Resource.Attribute.drawableSize; + global::Xamarin.Forms.Platform.Resource.Attribute.drawerArrowStyle = global::xamarinFormApp.Droid.Resource.Attribute.drawerArrowStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.dropdownListPreferredItemHeight = global::xamarinFormApp.Droid.Resource.Attribute.dropdownListPreferredItemHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.dropDownListViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.dropDownListViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.editTextBackground = global::xamarinFormApp.Droid.Resource.Attribute.editTextBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.editTextColor = global::xamarinFormApp.Droid.Resource.Attribute.editTextColor; + global::Xamarin.Forms.Platform.Resource.Attribute.editTextStyle = global::xamarinFormApp.Droid.Resource.Attribute.editTextStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.elevation = global::xamarinFormApp.Droid.Resource.Attribute.elevation; + global::Xamarin.Forms.Platform.Resource.Attribute.enforceMaterialTheme = global::xamarinFormApp.Droid.Resource.Attribute.enforceMaterialTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.enforceTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.enforceTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.errorEnabled = global::xamarinFormApp.Droid.Resource.Attribute.errorEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.errorTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.errorTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.expandActivityOverflowButtonDrawable = global::xamarinFormApp.Droid.Resource.Attribute.expandActivityOverflowButtonDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.expanded = global::xamarinFormApp.Droid.Resource.Attribute.expanded; + global::Xamarin.Forms.Platform.Resource.Attribute.expandedTitleGravity = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleGravity; + global::Xamarin.Forms.Platform.Resource.Attribute.expandedTitleMargin = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMargin; + global::Xamarin.Forms.Platform.Resource.Attribute.expandedTitleMarginBottom = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMarginBottom; + global::Xamarin.Forms.Platform.Resource.Attribute.expandedTitleMarginEnd = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMarginEnd; + global::Xamarin.Forms.Platform.Resource.Attribute.expandedTitleMarginStart = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMarginStart; + global::Xamarin.Forms.Platform.Resource.Attribute.expandedTitleMarginTop = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleMarginTop; + global::Xamarin.Forms.Platform.Resource.Attribute.expandedTitleTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.expandedTitleTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.fabAlignmentMode = global::xamarinFormApp.Droid.Resource.Attribute.fabAlignmentMode; + global::Xamarin.Forms.Platform.Resource.Attribute.fabCradleMargin = global::xamarinFormApp.Droid.Resource.Attribute.fabCradleMargin; + global::Xamarin.Forms.Platform.Resource.Attribute.fabCradleRoundedCornerRadius = global::xamarinFormApp.Droid.Resource.Attribute.fabCradleRoundedCornerRadius; + global::Xamarin.Forms.Platform.Resource.Attribute.fabCradleVerticalOffset = global::xamarinFormApp.Droid.Resource.Attribute.fabCradleVerticalOffset; + global::Xamarin.Forms.Platform.Resource.Attribute.fabCustomSize = global::xamarinFormApp.Droid.Resource.Attribute.fabCustomSize; + global::Xamarin.Forms.Platform.Resource.Attribute.fabSize = global::xamarinFormApp.Droid.Resource.Attribute.fabSize; + global::Xamarin.Forms.Platform.Resource.Attribute.fastScrollEnabled = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.fastScrollHorizontalThumbDrawable = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollHorizontalThumbDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.fastScrollHorizontalTrackDrawable = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollHorizontalTrackDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.fastScrollVerticalThumbDrawable = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollVerticalThumbDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.fastScrollVerticalTrackDrawable = global::xamarinFormApp.Droid.Resource.Attribute.fastScrollVerticalTrackDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.firstBaselineToTopHeight = global::xamarinFormApp.Droid.Resource.Attribute.firstBaselineToTopHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.floatingActionButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.floatingActionButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.font = global::xamarinFormApp.Droid.Resource.Attribute.font; + global::Xamarin.Forms.Platform.Resource.Attribute.fontFamily = global::xamarinFormApp.Droid.Resource.Attribute.fontFamily; + global::Xamarin.Forms.Platform.Resource.Attribute.fontProviderAuthority = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderAuthority; + global::Xamarin.Forms.Platform.Resource.Attribute.fontProviderCerts = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderCerts; + global::Xamarin.Forms.Platform.Resource.Attribute.fontProviderFetchStrategy = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderFetchStrategy; + global::Xamarin.Forms.Platform.Resource.Attribute.fontProviderFetchTimeout = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderFetchTimeout; + global::Xamarin.Forms.Platform.Resource.Attribute.fontProviderPackage = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderPackage; + global::Xamarin.Forms.Platform.Resource.Attribute.fontProviderQuery = global::xamarinFormApp.Droid.Resource.Attribute.fontProviderQuery; + global::Xamarin.Forms.Platform.Resource.Attribute.fontStyle = global::xamarinFormApp.Droid.Resource.Attribute.fontStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.fontVariationSettings = global::xamarinFormApp.Droid.Resource.Attribute.fontVariationSettings; + global::Xamarin.Forms.Platform.Resource.Attribute.fontWeight = global::xamarinFormApp.Droid.Resource.Attribute.fontWeight; + global::Xamarin.Forms.Platform.Resource.Attribute.foregroundInsidePadding = global::xamarinFormApp.Droid.Resource.Attribute.foregroundInsidePadding; + global::Xamarin.Forms.Platform.Resource.Attribute.gapBetweenBars = global::xamarinFormApp.Droid.Resource.Attribute.gapBetweenBars; + global::Xamarin.Forms.Platform.Resource.Attribute.goIcon = global::xamarinFormApp.Droid.Resource.Attribute.goIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.headerLayout = global::xamarinFormApp.Droid.Resource.Attribute.headerLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.height = global::xamarinFormApp.Droid.Resource.Attribute.height; + global::Xamarin.Forms.Platform.Resource.Attribute.helperText = global::xamarinFormApp.Droid.Resource.Attribute.helperText; + global::Xamarin.Forms.Platform.Resource.Attribute.helperTextEnabled = global::xamarinFormApp.Droid.Resource.Attribute.helperTextEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.helperTextTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.helperTextTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.hideMotionSpec = global::xamarinFormApp.Droid.Resource.Attribute.hideMotionSpec; + global::Xamarin.Forms.Platform.Resource.Attribute.hideOnContentScroll = global::xamarinFormApp.Droid.Resource.Attribute.hideOnContentScroll; + global::Xamarin.Forms.Platform.Resource.Attribute.hideOnScroll = global::xamarinFormApp.Droid.Resource.Attribute.hideOnScroll; + global::Xamarin.Forms.Platform.Resource.Attribute.hintAnimationEnabled = global::xamarinFormApp.Droid.Resource.Attribute.hintAnimationEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.hintEnabled = global::xamarinFormApp.Droid.Resource.Attribute.hintEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.hintTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.hintTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.homeAsUpIndicator = global::xamarinFormApp.Droid.Resource.Attribute.homeAsUpIndicator; + global::Xamarin.Forms.Platform.Resource.Attribute.homeLayout = global::xamarinFormApp.Droid.Resource.Attribute.homeLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.hoveredFocusedTranslationZ = global::xamarinFormApp.Droid.Resource.Attribute.hoveredFocusedTranslationZ; + global::Xamarin.Forms.Platform.Resource.Attribute.icon = global::xamarinFormApp.Droid.Resource.Attribute.icon; + global::Xamarin.Forms.Platform.Resource.Attribute.iconEndPadding = global::xamarinFormApp.Droid.Resource.Attribute.iconEndPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.iconGravity = global::xamarinFormApp.Droid.Resource.Attribute.iconGravity; + global::Xamarin.Forms.Platform.Resource.Attribute.iconifiedByDefault = global::xamarinFormApp.Droid.Resource.Attribute.iconifiedByDefault; + global::Xamarin.Forms.Platform.Resource.Attribute.iconPadding = global::xamarinFormApp.Droid.Resource.Attribute.iconPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.iconSize = global::xamarinFormApp.Droid.Resource.Attribute.iconSize; + global::Xamarin.Forms.Platform.Resource.Attribute.iconStartPadding = global::xamarinFormApp.Droid.Resource.Attribute.iconStartPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.iconTint = global::xamarinFormApp.Droid.Resource.Attribute.iconTint; + global::Xamarin.Forms.Platform.Resource.Attribute.iconTintMode = global::xamarinFormApp.Droid.Resource.Attribute.iconTintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.imageButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.imageButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.indeterminateProgressStyle = global::xamarinFormApp.Droid.Resource.Attribute.indeterminateProgressStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.initialActivityCount = global::xamarinFormApp.Droid.Resource.Attribute.initialActivityCount; + global::Xamarin.Forms.Platform.Resource.Attribute.insetForeground = global::xamarinFormApp.Droid.Resource.Attribute.insetForeground; + global::Xamarin.Forms.Platform.Resource.Attribute.isLightTheme = global::xamarinFormApp.Droid.Resource.Attribute.isLightTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.itemBackground = global::xamarinFormApp.Droid.Resource.Attribute.itemBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.itemHorizontalPadding = global::xamarinFormApp.Droid.Resource.Attribute.itemHorizontalPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.itemHorizontalTranslationEnabled = global::xamarinFormApp.Droid.Resource.Attribute.itemHorizontalTranslationEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.itemIconPadding = global::xamarinFormApp.Droid.Resource.Attribute.itemIconPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.itemIconSize = global::xamarinFormApp.Droid.Resource.Attribute.itemIconSize; + global::Xamarin.Forms.Platform.Resource.Attribute.itemIconTint = global::xamarinFormApp.Droid.Resource.Attribute.itemIconTint; + global::Xamarin.Forms.Platform.Resource.Attribute.itemPadding = global::xamarinFormApp.Droid.Resource.Attribute.itemPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.itemSpacing = global::xamarinFormApp.Droid.Resource.Attribute.itemSpacing; + global::Xamarin.Forms.Platform.Resource.Attribute.itemTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.itemTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.itemTextAppearanceActive = global::xamarinFormApp.Droid.Resource.Attribute.itemTextAppearanceActive; + global::Xamarin.Forms.Platform.Resource.Attribute.itemTextAppearanceInactive = global::xamarinFormApp.Droid.Resource.Attribute.itemTextAppearanceInactive; + global::Xamarin.Forms.Platform.Resource.Attribute.itemTextColor = global::xamarinFormApp.Droid.Resource.Attribute.itemTextColor; + global::Xamarin.Forms.Platform.Resource.Attribute.keylines = global::xamarinFormApp.Droid.Resource.Attribute.keylines; + global::Xamarin.Forms.Platform.Resource.Attribute.labelVisibilityMode = global::xamarinFormApp.Droid.Resource.Attribute.labelVisibilityMode; + global::Xamarin.Forms.Platform.Resource.Attribute.lastBaselineToBottomHeight = global::xamarinFormApp.Droid.Resource.Attribute.lastBaselineToBottomHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.layout = global::xamarinFormApp.Droid.Resource.Attribute.layout; + global::Xamarin.Forms.Platform.Resource.Attribute.layoutManager = global::xamarinFormApp.Droid.Resource.Attribute.layoutManager; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_anchor = global::xamarinFormApp.Droid.Resource.Attribute.layout_anchor; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_anchorGravity = global::xamarinFormApp.Droid.Resource.Attribute.layout_anchorGravity; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_behavior = global::xamarinFormApp.Droid.Resource.Attribute.layout_behavior; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_collapseMode = global::xamarinFormApp.Droid.Resource.Attribute.layout_collapseMode; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_collapseParallaxMultiplier = global::xamarinFormApp.Droid.Resource.Attribute.layout_collapseParallaxMultiplier; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_dodgeInsetEdges = global::xamarinFormApp.Droid.Resource.Attribute.layout_dodgeInsetEdges; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_insetEdge = global::xamarinFormApp.Droid.Resource.Attribute.layout_insetEdge; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_keyline = global::xamarinFormApp.Droid.Resource.Attribute.layout_keyline; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_scrollFlags = global::xamarinFormApp.Droid.Resource.Attribute.layout_scrollFlags; + global::Xamarin.Forms.Platform.Resource.Attribute.layout_scrollInterpolator = global::xamarinFormApp.Droid.Resource.Attribute.layout_scrollInterpolator; + global::Xamarin.Forms.Platform.Resource.Attribute.liftOnScroll = global::xamarinFormApp.Droid.Resource.Attribute.liftOnScroll; + global::Xamarin.Forms.Platform.Resource.Attribute.lineHeight = global::xamarinFormApp.Droid.Resource.Attribute.lineHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.lineSpacing = global::xamarinFormApp.Droid.Resource.Attribute.lineSpacing; + global::Xamarin.Forms.Platform.Resource.Attribute.listChoiceBackgroundIndicator = global::xamarinFormApp.Droid.Resource.Attribute.listChoiceBackgroundIndicator; + global::Xamarin.Forms.Platform.Resource.Attribute.listDividerAlertDialog = global::xamarinFormApp.Droid.Resource.Attribute.listDividerAlertDialog; + global::Xamarin.Forms.Platform.Resource.Attribute.listItemLayout = global::xamarinFormApp.Droid.Resource.Attribute.listItemLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.listLayout = global::xamarinFormApp.Droid.Resource.Attribute.listLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.listMenuViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.listMenuViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.listPopupWindowStyle = global::xamarinFormApp.Droid.Resource.Attribute.listPopupWindowStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.listPreferredItemHeight = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.listPreferredItemHeightLarge = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemHeightLarge; + global::Xamarin.Forms.Platform.Resource.Attribute.listPreferredItemHeightSmall = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemHeightSmall; + global::Xamarin.Forms.Platform.Resource.Attribute.listPreferredItemPaddingLeft = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemPaddingLeft; + global::Xamarin.Forms.Platform.Resource.Attribute.listPreferredItemPaddingRight = global::xamarinFormApp.Droid.Resource.Attribute.listPreferredItemPaddingRight; + global::Xamarin.Forms.Platform.Resource.Attribute.logo = global::xamarinFormApp.Droid.Resource.Attribute.logo; + global::Xamarin.Forms.Platform.Resource.Attribute.logoDescription = global::xamarinFormApp.Droid.Resource.Attribute.logoDescription; + global::Xamarin.Forms.Platform.Resource.Attribute.materialButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.materialButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.materialCardViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.materialCardViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.maxActionInlineWidth = global::xamarinFormApp.Droid.Resource.Attribute.maxActionInlineWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.maxButtonHeight = global::xamarinFormApp.Droid.Resource.Attribute.maxButtonHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.maxImageSize = global::xamarinFormApp.Droid.Resource.Attribute.maxImageSize; + global::Xamarin.Forms.Platform.Resource.Attribute.measureWithLargestChild = global::xamarinFormApp.Droid.Resource.Attribute.measureWithLargestChild; + global::Xamarin.Forms.Platform.Resource.Attribute.menu = global::xamarinFormApp.Droid.Resource.Attribute.menu; + global::Xamarin.Forms.Platform.Resource.Attribute.multiChoiceItemLayout = global::xamarinFormApp.Droid.Resource.Attribute.multiChoiceItemLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.navigationContentDescription = global::xamarinFormApp.Droid.Resource.Attribute.navigationContentDescription; + global::Xamarin.Forms.Platform.Resource.Attribute.navigationIcon = global::xamarinFormApp.Droid.Resource.Attribute.navigationIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.navigationMode = global::xamarinFormApp.Droid.Resource.Attribute.navigationMode; + global::Xamarin.Forms.Platform.Resource.Attribute.navigationViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.navigationViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.numericModifiers = global::xamarinFormApp.Droid.Resource.Attribute.numericModifiers; + global::Xamarin.Forms.Platform.Resource.Attribute.overlapAnchor = global::xamarinFormApp.Droid.Resource.Attribute.overlapAnchor; + global::Xamarin.Forms.Platform.Resource.Attribute.paddingBottomNoButtons = global::xamarinFormApp.Droid.Resource.Attribute.paddingBottomNoButtons; + global::Xamarin.Forms.Platform.Resource.Attribute.paddingEnd = global::xamarinFormApp.Droid.Resource.Attribute.paddingEnd; + global::Xamarin.Forms.Platform.Resource.Attribute.paddingStart = global::xamarinFormApp.Droid.Resource.Attribute.paddingStart; + global::Xamarin.Forms.Platform.Resource.Attribute.paddingTopNoTitle = global::xamarinFormApp.Droid.Resource.Attribute.paddingTopNoTitle; + global::Xamarin.Forms.Platform.Resource.Attribute.panelBackground = global::xamarinFormApp.Droid.Resource.Attribute.panelBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.panelMenuListTheme = global::xamarinFormApp.Droid.Resource.Attribute.panelMenuListTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.panelMenuListWidth = global::xamarinFormApp.Droid.Resource.Attribute.panelMenuListWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.passwordToggleContentDescription = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleContentDescription; + global::Xamarin.Forms.Platform.Resource.Attribute.passwordToggleDrawable = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleDrawable; + global::Xamarin.Forms.Platform.Resource.Attribute.passwordToggleEnabled = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.passwordToggleTint = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleTint; + global::Xamarin.Forms.Platform.Resource.Attribute.passwordToggleTintMode = global::xamarinFormApp.Droid.Resource.Attribute.passwordToggleTintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.popupMenuStyle = global::xamarinFormApp.Droid.Resource.Attribute.popupMenuStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.popupTheme = global::xamarinFormApp.Droid.Resource.Attribute.popupTheme; + global::Xamarin.Forms.Platform.Resource.Attribute.popupWindowStyle = global::xamarinFormApp.Droid.Resource.Attribute.popupWindowStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.preserveIconSpacing = global::xamarinFormApp.Droid.Resource.Attribute.preserveIconSpacing; + global::Xamarin.Forms.Platform.Resource.Attribute.pressedTranslationZ = global::xamarinFormApp.Droid.Resource.Attribute.pressedTranslationZ; + global::Xamarin.Forms.Platform.Resource.Attribute.progressBarPadding = global::xamarinFormApp.Droid.Resource.Attribute.progressBarPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.progressBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.progressBarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.queryBackground = global::xamarinFormApp.Droid.Resource.Attribute.queryBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.queryHint = global::xamarinFormApp.Droid.Resource.Attribute.queryHint; + global::Xamarin.Forms.Platform.Resource.Attribute.radioButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.radioButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.ratingBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.ratingBarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.ratingBarStyleIndicator = global::xamarinFormApp.Droid.Resource.Attribute.ratingBarStyleIndicator; + global::Xamarin.Forms.Platform.Resource.Attribute.ratingBarStyleSmall = global::xamarinFormApp.Droid.Resource.Attribute.ratingBarStyleSmall; + global::Xamarin.Forms.Platform.Resource.Attribute.reverseLayout = global::xamarinFormApp.Droid.Resource.Attribute.reverseLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.rippleColor = global::xamarinFormApp.Droid.Resource.Attribute.rippleColor; + global::Xamarin.Forms.Platform.Resource.Attribute.scrimAnimationDuration = global::xamarinFormApp.Droid.Resource.Attribute.scrimAnimationDuration; + global::Xamarin.Forms.Platform.Resource.Attribute.scrimBackground = global::xamarinFormApp.Droid.Resource.Attribute.scrimBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.scrimVisibleHeightTrigger = global::xamarinFormApp.Droid.Resource.Attribute.scrimVisibleHeightTrigger; + global::Xamarin.Forms.Platform.Resource.Attribute.scrollViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.scrollViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.searchHintIcon = global::xamarinFormApp.Droid.Resource.Attribute.searchHintIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.searchIcon = global::xamarinFormApp.Droid.Resource.Attribute.searchIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.searchViewStyle = global::xamarinFormApp.Droid.Resource.Attribute.searchViewStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.seekBarStyle = global::xamarinFormApp.Droid.Resource.Attribute.seekBarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.selectableItemBackground = global::xamarinFormApp.Droid.Resource.Attribute.selectableItemBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.selectableItemBackgroundBorderless = global::xamarinFormApp.Droid.Resource.Attribute.selectableItemBackgroundBorderless; + global::Xamarin.Forms.Platform.Resource.Attribute.showAsAction = global::xamarinFormApp.Droid.Resource.Attribute.showAsAction; + global::Xamarin.Forms.Platform.Resource.Attribute.showDividers = global::xamarinFormApp.Droid.Resource.Attribute.showDividers; + global::Xamarin.Forms.Platform.Resource.Attribute.showMotionSpec = global::xamarinFormApp.Droid.Resource.Attribute.showMotionSpec; + global::Xamarin.Forms.Platform.Resource.Attribute.showText = global::xamarinFormApp.Droid.Resource.Attribute.showText; + global::Xamarin.Forms.Platform.Resource.Attribute.showTitle = global::xamarinFormApp.Droid.Resource.Attribute.showTitle; + global::Xamarin.Forms.Platform.Resource.Attribute.singleChoiceItemLayout = global::xamarinFormApp.Droid.Resource.Attribute.singleChoiceItemLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.singleLine = global::xamarinFormApp.Droid.Resource.Attribute.singleLine; + global::Xamarin.Forms.Platform.Resource.Attribute.singleSelection = global::xamarinFormApp.Droid.Resource.Attribute.singleSelection; + global::Xamarin.Forms.Platform.Resource.Attribute.snackbarButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.snackbarButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.snackbarStyle = global::xamarinFormApp.Droid.Resource.Attribute.snackbarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.spanCount = global::xamarinFormApp.Droid.Resource.Attribute.spanCount; + global::Xamarin.Forms.Platform.Resource.Attribute.spinBars = global::xamarinFormApp.Droid.Resource.Attribute.spinBars; + global::Xamarin.Forms.Platform.Resource.Attribute.spinnerDropDownItemStyle = global::xamarinFormApp.Droid.Resource.Attribute.spinnerDropDownItemStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.spinnerStyle = global::xamarinFormApp.Droid.Resource.Attribute.spinnerStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.splitTrack = global::xamarinFormApp.Droid.Resource.Attribute.splitTrack; + global::Xamarin.Forms.Platform.Resource.Attribute.srcCompat = global::xamarinFormApp.Droid.Resource.Attribute.srcCompat; + global::Xamarin.Forms.Platform.Resource.Attribute.stackFromEnd = global::xamarinFormApp.Droid.Resource.Attribute.stackFromEnd; + global::Xamarin.Forms.Platform.Resource.Attribute.state_above_anchor = global::xamarinFormApp.Droid.Resource.Attribute.state_above_anchor; + global::Xamarin.Forms.Platform.Resource.Attribute.state_collapsed = global::xamarinFormApp.Droid.Resource.Attribute.state_collapsed; + global::Xamarin.Forms.Platform.Resource.Attribute.state_collapsible = global::xamarinFormApp.Droid.Resource.Attribute.state_collapsible; + global::Xamarin.Forms.Platform.Resource.Attribute.state_liftable = global::xamarinFormApp.Droid.Resource.Attribute.state_liftable; + global::Xamarin.Forms.Platform.Resource.Attribute.state_lifted = global::xamarinFormApp.Droid.Resource.Attribute.state_lifted; + global::Xamarin.Forms.Platform.Resource.Attribute.statusBarBackground = global::xamarinFormApp.Droid.Resource.Attribute.statusBarBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.statusBarScrim = global::xamarinFormApp.Droid.Resource.Attribute.statusBarScrim; + global::Xamarin.Forms.Platform.Resource.Attribute.strokeColor = global::xamarinFormApp.Droid.Resource.Attribute.strokeColor; + global::Xamarin.Forms.Platform.Resource.Attribute.strokeWidth = global::xamarinFormApp.Droid.Resource.Attribute.strokeWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.subMenuArrow = global::xamarinFormApp.Droid.Resource.Attribute.subMenuArrow; + global::Xamarin.Forms.Platform.Resource.Attribute.submitBackground = global::xamarinFormApp.Droid.Resource.Attribute.submitBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.subtitle = global::xamarinFormApp.Droid.Resource.Attribute.subtitle; + global::Xamarin.Forms.Platform.Resource.Attribute.subtitleTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.subtitleTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.subtitleTextColor = global::xamarinFormApp.Droid.Resource.Attribute.subtitleTextColor; + global::Xamarin.Forms.Platform.Resource.Attribute.subtitleTextStyle = global::xamarinFormApp.Droid.Resource.Attribute.subtitleTextStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.suggestionRowLayout = global::xamarinFormApp.Droid.Resource.Attribute.suggestionRowLayout; + global::Xamarin.Forms.Platform.Resource.Attribute.switchMinWidth = global::xamarinFormApp.Droid.Resource.Attribute.switchMinWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.switchPadding = global::xamarinFormApp.Droid.Resource.Attribute.switchPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.switchStyle = global::xamarinFormApp.Droid.Resource.Attribute.switchStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.switchTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.switchTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.tabBackground = global::xamarinFormApp.Droid.Resource.Attribute.tabBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.tabContentStart = global::xamarinFormApp.Droid.Resource.Attribute.tabContentStart; + global::Xamarin.Forms.Platform.Resource.Attribute.tabGravity = global::xamarinFormApp.Droid.Resource.Attribute.tabGravity; + global::Xamarin.Forms.Platform.Resource.Attribute.tabIconTint = global::xamarinFormApp.Droid.Resource.Attribute.tabIconTint; + global::Xamarin.Forms.Platform.Resource.Attribute.tabIconTintMode = global::xamarinFormApp.Droid.Resource.Attribute.tabIconTintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.tabIndicator = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicator; + global::Xamarin.Forms.Platform.Resource.Attribute.tabIndicatorAnimationDuration = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorAnimationDuration; + global::Xamarin.Forms.Platform.Resource.Attribute.tabIndicatorColor = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorColor; + global::Xamarin.Forms.Platform.Resource.Attribute.tabIndicatorFullWidth = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorFullWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.tabIndicatorGravity = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorGravity; + global::Xamarin.Forms.Platform.Resource.Attribute.tabIndicatorHeight = global::xamarinFormApp.Droid.Resource.Attribute.tabIndicatorHeight; + global::Xamarin.Forms.Platform.Resource.Attribute.tabInlineLabel = global::xamarinFormApp.Droid.Resource.Attribute.tabInlineLabel; + global::Xamarin.Forms.Platform.Resource.Attribute.tabMaxWidth = global::xamarinFormApp.Droid.Resource.Attribute.tabMaxWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.tabMinWidth = global::xamarinFormApp.Droid.Resource.Attribute.tabMinWidth; + global::Xamarin.Forms.Platform.Resource.Attribute.tabMode = global::xamarinFormApp.Droid.Resource.Attribute.tabMode; + global::Xamarin.Forms.Platform.Resource.Attribute.tabPadding = global::xamarinFormApp.Droid.Resource.Attribute.tabPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.tabPaddingBottom = global::xamarinFormApp.Droid.Resource.Attribute.tabPaddingBottom; + global::Xamarin.Forms.Platform.Resource.Attribute.tabPaddingEnd = global::xamarinFormApp.Droid.Resource.Attribute.tabPaddingEnd; + global::Xamarin.Forms.Platform.Resource.Attribute.tabPaddingStart = global::xamarinFormApp.Droid.Resource.Attribute.tabPaddingStart; + global::Xamarin.Forms.Platform.Resource.Attribute.tabPaddingTop = global::xamarinFormApp.Droid.Resource.Attribute.tabPaddingTop; + global::Xamarin.Forms.Platform.Resource.Attribute.tabRippleColor = global::xamarinFormApp.Droid.Resource.Attribute.tabRippleColor; + global::Xamarin.Forms.Platform.Resource.Attribute.tabSelectedTextColor = global::xamarinFormApp.Droid.Resource.Attribute.tabSelectedTextColor; + global::Xamarin.Forms.Platform.Resource.Attribute.tabStyle = global::xamarinFormApp.Droid.Resource.Attribute.tabStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.tabTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.tabTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.tabTextColor = global::xamarinFormApp.Droid.Resource.Attribute.tabTextColor; + global::Xamarin.Forms.Platform.Resource.Attribute.tabUnboundedRipple = global::xamarinFormApp.Droid.Resource.Attribute.tabUnboundedRipple; + global::Xamarin.Forms.Platform.Resource.Attribute.textAllCaps = global::xamarinFormApp.Droid.Resource.Attribute.textAllCaps; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceBody1 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceBody1; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceBody2 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceBody2; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceButton = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceButton; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceCaption = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceCaption; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceHeadline1 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline1; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceHeadline2 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline2; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceHeadline3 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline3; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceHeadline4 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline4; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceHeadline5 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline5; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceHeadline6 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceHeadline6; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceLargePopupMenu = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceLargePopupMenu; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceListItem = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceListItem; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceListItemSecondary = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceListItemSecondary; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceListItemSmall = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceListItemSmall; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceOverline = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceOverline; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearancePopupMenuHeader = global::xamarinFormApp.Droid.Resource.Attribute.textAppearancePopupMenuHeader; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceSearchResultSubtitle = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSearchResultSubtitle; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceSearchResultTitle = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSearchResultTitle; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceSmallPopupMenu = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSmallPopupMenu; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceSubtitle1 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSubtitle1; + global::Xamarin.Forms.Platform.Resource.Attribute.textAppearanceSubtitle2 = global::xamarinFormApp.Droid.Resource.Attribute.textAppearanceSubtitle2; + global::Xamarin.Forms.Platform.Resource.Attribute.textColorAlertDialogListItem = global::xamarinFormApp.Droid.Resource.Attribute.textColorAlertDialogListItem; + global::Xamarin.Forms.Platform.Resource.Attribute.textColorSearchUrl = global::xamarinFormApp.Droid.Resource.Attribute.textColorSearchUrl; + global::Xamarin.Forms.Platform.Resource.Attribute.textEndPadding = global::xamarinFormApp.Droid.Resource.Attribute.textEndPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.textInputStyle = global::xamarinFormApp.Droid.Resource.Attribute.textInputStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.textStartPadding = global::xamarinFormApp.Droid.Resource.Attribute.textStartPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.theme = global::xamarinFormApp.Droid.Resource.Attribute.theme; + global::Xamarin.Forms.Platform.Resource.Attribute.thickness = global::xamarinFormApp.Droid.Resource.Attribute.thickness; + global::Xamarin.Forms.Platform.Resource.Attribute.thumbTextPadding = global::xamarinFormApp.Droid.Resource.Attribute.thumbTextPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.thumbTint = global::xamarinFormApp.Droid.Resource.Attribute.thumbTint; + global::Xamarin.Forms.Platform.Resource.Attribute.thumbTintMode = global::xamarinFormApp.Droid.Resource.Attribute.thumbTintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.tickMark = global::xamarinFormApp.Droid.Resource.Attribute.tickMark; + global::Xamarin.Forms.Platform.Resource.Attribute.tickMarkTint = global::xamarinFormApp.Droid.Resource.Attribute.tickMarkTint; + global::Xamarin.Forms.Platform.Resource.Attribute.tickMarkTintMode = global::xamarinFormApp.Droid.Resource.Attribute.tickMarkTintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.tint = global::xamarinFormApp.Droid.Resource.Attribute.tint; + global::Xamarin.Forms.Platform.Resource.Attribute.tintMode = global::xamarinFormApp.Droid.Resource.Attribute.tintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.title = global::xamarinFormApp.Droid.Resource.Attribute.title; + global::Xamarin.Forms.Platform.Resource.Attribute.titleEnabled = global::xamarinFormApp.Droid.Resource.Attribute.titleEnabled; + global::Xamarin.Forms.Platform.Resource.Attribute.titleMargin = global::xamarinFormApp.Droid.Resource.Attribute.titleMargin; + global::Xamarin.Forms.Platform.Resource.Attribute.titleMarginBottom = global::xamarinFormApp.Droid.Resource.Attribute.titleMarginBottom; + global::Xamarin.Forms.Platform.Resource.Attribute.titleMarginEnd = global::xamarinFormApp.Droid.Resource.Attribute.titleMarginEnd; + global::Xamarin.Forms.Platform.Resource.Attribute.titleMargins = global::xamarinFormApp.Droid.Resource.Attribute.titleMargins; + global::Xamarin.Forms.Platform.Resource.Attribute.titleMarginStart = global::xamarinFormApp.Droid.Resource.Attribute.titleMarginStart; + global::Xamarin.Forms.Platform.Resource.Attribute.titleMarginTop = global::xamarinFormApp.Droid.Resource.Attribute.titleMarginTop; + global::Xamarin.Forms.Platform.Resource.Attribute.titleTextAppearance = global::xamarinFormApp.Droid.Resource.Attribute.titleTextAppearance; + global::Xamarin.Forms.Platform.Resource.Attribute.titleTextColor = global::xamarinFormApp.Droid.Resource.Attribute.titleTextColor; + global::Xamarin.Forms.Platform.Resource.Attribute.titleTextStyle = global::xamarinFormApp.Droid.Resource.Attribute.titleTextStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.toolbarId = global::xamarinFormApp.Droid.Resource.Attribute.toolbarId; + global::Xamarin.Forms.Platform.Resource.Attribute.toolbarNavigationButtonStyle = global::xamarinFormApp.Droid.Resource.Attribute.toolbarNavigationButtonStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.toolbarStyle = global::xamarinFormApp.Droid.Resource.Attribute.toolbarStyle; + global::Xamarin.Forms.Platform.Resource.Attribute.tooltipForegroundColor = global::xamarinFormApp.Droid.Resource.Attribute.tooltipForegroundColor; + global::Xamarin.Forms.Platform.Resource.Attribute.tooltipFrameBackground = global::xamarinFormApp.Droid.Resource.Attribute.tooltipFrameBackground; + global::Xamarin.Forms.Platform.Resource.Attribute.tooltipText = global::xamarinFormApp.Droid.Resource.Attribute.tooltipText; + global::Xamarin.Forms.Platform.Resource.Attribute.track = global::xamarinFormApp.Droid.Resource.Attribute.track; + global::Xamarin.Forms.Platform.Resource.Attribute.trackTint = global::xamarinFormApp.Droid.Resource.Attribute.trackTint; + global::Xamarin.Forms.Platform.Resource.Attribute.trackTintMode = global::xamarinFormApp.Droid.Resource.Attribute.trackTintMode; + global::Xamarin.Forms.Platform.Resource.Attribute.ttcIndex = global::xamarinFormApp.Droid.Resource.Attribute.ttcIndex; + global::Xamarin.Forms.Platform.Resource.Attribute.useCompatPadding = global::xamarinFormApp.Droid.Resource.Attribute.useCompatPadding; + global::Xamarin.Forms.Platform.Resource.Attribute.viewInflaterClass = global::xamarinFormApp.Droid.Resource.Attribute.viewInflaterClass; + global::Xamarin.Forms.Platform.Resource.Attribute.voiceIcon = global::xamarinFormApp.Droid.Resource.Attribute.voiceIcon; + global::Xamarin.Forms.Platform.Resource.Attribute.windowActionBar = global::xamarinFormApp.Droid.Resource.Attribute.windowActionBar; + global::Xamarin.Forms.Platform.Resource.Attribute.windowActionBarOverlay = global::xamarinFormApp.Droid.Resource.Attribute.windowActionBarOverlay; + global::Xamarin.Forms.Platform.Resource.Attribute.windowActionModeOverlay = global::xamarinFormApp.Droid.Resource.Attribute.windowActionModeOverlay; + global::Xamarin.Forms.Platform.Resource.Attribute.windowFixedHeightMajor = global::xamarinFormApp.Droid.Resource.Attribute.windowFixedHeightMajor; + global::Xamarin.Forms.Platform.Resource.Attribute.windowFixedHeightMinor = global::xamarinFormApp.Droid.Resource.Attribute.windowFixedHeightMinor; + global::Xamarin.Forms.Platform.Resource.Attribute.windowFixedWidthMajor = global::xamarinFormApp.Droid.Resource.Attribute.windowFixedWidthMajor; + global::Xamarin.Forms.Platform.Resource.Attribute.windowFixedWidthMinor = global::xamarinFormApp.Droid.Resource.Attribute.windowFixedWidthMinor; + global::Xamarin.Forms.Platform.Resource.Attribute.windowMinWidthMajor = global::xamarinFormApp.Droid.Resource.Attribute.windowMinWidthMajor; + global::Xamarin.Forms.Platform.Resource.Attribute.windowMinWidthMinor = global::xamarinFormApp.Droid.Resource.Attribute.windowMinWidthMinor; + global::Xamarin.Forms.Platform.Resource.Attribute.windowNoTitle = global::xamarinFormApp.Droid.Resource.Attribute.windowNoTitle; + global::Xamarin.Forms.Platform.Resource.Boolean.abc_action_bar_embed_tabs = global::xamarinFormApp.Droid.Resource.Boolean.abc_action_bar_embed_tabs; + global::Xamarin.Forms.Platform.Resource.Boolean.abc_allow_stacked_button_bar = global::xamarinFormApp.Droid.Resource.Boolean.abc_allow_stacked_button_bar; + global::Xamarin.Forms.Platform.Resource.Boolean.abc_config_actionMenuItemAllCaps = global::xamarinFormApp.Droid.Resource.Boolean.abc_config_actionMenuItemAllCaps; + global::Xamarin.Forms.Platform.Resource.Boolean.mtrl_btn_textappearance_all_caps = global::xamarinFormApp.Droid.Resource.Boolean.mtrl_btn_textappearance_all_caps; + global::Xamarin.Forms.Platform.Resource.Color.abc_background_cache_hint_selector_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_background_cache_hint_selector_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.abc_background_cache_hint_selector_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_background_cache_hint_selector_material_light; + global::Xamarin.Forms.Platform.Resource.Color.abc_btn_colored_borderless_text_material = global::xamarinFormApp.Droid.Resource.Color.abc_btn_colored_borderless_text_material; + global::Xamarin.Forms.Platform.Resource.Color.abc_btn_colored_text_material = global::xamarinFormApp.Droid.Resource.Color.abc_btn_colored_text_material; + global::Xamarin.Forms.Platform.Resource.Color.abc_color_highlight_material = global::xamarinFormApp.Droid.Resource.Color.abc_color_highlight_material; + global::Xamarin.Forms.Platform.Resource.Color.abc_hint_foreground_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_hint_foreground_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.abc_hint_foreground_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_hint_foreground_material_light; + global::Xamarin.Forms.Platform.Resource.Color.abc_input_method_navigation_guard = global::xamarinFormApp.Droid.Resource.Color.abc_input_method_navigation_guard; + global::Xamarin.Forms.Platform.Resource.Color.abc_primary_text_disable_only_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_primary_text_disable_only_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.abc_primary_text_disable_only_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_primary_text_disable_only_material_light; + global::Xamarin.Forms.Platform.Resource.Color.abc_primary_text_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_primary_text_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.abc_primary_text_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_primary_text_material_light; + global::Xamarin.Forms.Platform.Resource.Color.abc_search_url_text = global::xamarinFormApp.Droid.Resource.Color.abc_search_url_text; + global::Xamarin.Forms.Platform.Resource.Color.abc_search_url_text_normal = global::xamarinFormApp.Droid.Resource.Color.abc_search_url_text_normal; + global::Xamarin.Forms.Platform.Resource.Color.abc_search_url_text_pressed = global::xamarinFormApp.Droid.Resource.Color.abc_search_url_text_pressed; + global::Xamarin.Forms.Platform.Resource.Color.abc_search_url_text_selected = global::xamarinFormApp.Droid.Resource.Color.abc_search_url_text_selected; + global::Xamarin.Forms.Platform.Resource.Color.abc_secondary_text_material_dark = global::xamarinFormApp.Droid.Resource.Color.abc_secondary_text_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.abc_secondary_text_material_light = global::xamarinFormApp.Droid.Resource.Color.abc_secondary_text_material_light; + global::Xamarin.Forms.Platform.Resource.Color.abc_tint_btn_checkable = global::xamarinFormApp.Droid.Resource.Color.abc_tint_btn_checkable; + global::Xamarin.Forms.Platform.Resource.Color.abc_tint_default = global::xamarinFormApp.Droid.Resource.Color.abc_tint_default; + global::Xamarin.Forms.Platform.Resource.Color.abc_tint_edittext = global::xamarinFormApp.Droid.Resource.Color.abc_tint_edittext; + global::Xamarin.Forms.Platform.Resource.Color.abc_tint_seek_thumb = global::xamarinFormApp.Droid.Resource.Color.abc_tint_seek_thumb; + global::Xamarin.Forms.Platform.Resource.Color.abc_tint_spinner = global::xamarinFormApp.Droid.Resource.Color.abc_tint_spinner; + global::Xamarin.Forms.Platform.Resource.Color.abc_tint_switch_track = global::xamarinFormApp.Droid.Resource.Color.abc_tint_switch_track; + global::Xamarin.Forms.Platform.Resource.Color.accent_material_dark = global::xamarinFormApp.Droid.Resource.Color.accent_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.accent_material_light = global::xamarinFormApp.Droid.Resource.Color.accent_material_light; + global::Xamarin.Forms.Platform.Resource.Color.background_floating_material_dark = global::xamarinFormApp.Droid.Resource.Color.background_floating_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.background_floating_material_light = global::xamarinFormApp.Droid.Resource.Color.background_floating_material_light; + global::Xamarin.Forms.Platform.Resource.Color.background_material_dark = global::xamarinFormApp.Droid.Resource.Color.background_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.background_material_light = global::xamarinFormApp.Droid.Resource.Color.background_material_light; + global::Xamarin.Forms.Platform.Resource.Color.bright_foreground_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_disabled_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.bright_foreground_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_disabled_material_light; + global::Xamarin.Forms.Platform.Resource.Color.bright_foreground_inverse_material_dark = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_inverse_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.bright_foreground_inverse_material_light = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_inverse_material_light; + global::Xamarin.Forms.Platform.Resource.Color.bright_foreground_material_dark = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.bright_foreground_material_light = global::xamarinFormApp.Droid.Resource.Color.bright_foreground_material_light; + global::Xamarin.Forms.Platform.Resource.Color.button_material_dark = global::xamarinFormApp.Droid.Resource.Color.button_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.button_material_light = global::xamarinFormApp.Droid.Resource.Color.button_material_light; + global::Xamarin.Forms.Platform.Resource.Color.cardview_dark_background = global::xamarinFormApp.Droid.Resource.Color.cardview_dark_background; + global::Xamarin.Forms.Platform.Resource.Color.cardview_light_background = global::xamarinFormApp.Droid.Resource.Color.cardview_light_background; + global::Xamarin.Forms.Platform.Resource.Color.cardview_shadow_end_color = global::xamarinFormApp.Droid.Resource.Color.cardview_shadow_end_color; + global::Xamarin.Forms.Platform.Resource.Color.cardview_shadow_start_color = global::xamarinFormApp.Droid.Resource.Color.cardview_shadow_start_color; + global::Xamarin.Forms.Platform.Resource.Color.design_bottom_navigation_shadow_color = global::xamarinFormApp.Droid.Resource.Color.design_bottom_navigation_shadow_color; + global::Xamarin.Forms.Platform.Resource.Color.design_default_color_primary = global::xamarinFormApp.Droid.Resource.Color.design_default_color_primary; + global::Xamarin.Forms.Platform.Resource.Color.design_default_color_primary_dark = global::xamarinFormApp.Droid.Resource.Color.design_default_color_primary_dark; + global::Xamarin.Forms.Platform.Resource.Color.design_error = global::xamarinFormApp.Droid.Resource.Color.design_error; + global::Xamarin.Forms.Platform.Resource.Color.design_fab_shadow_end_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_shadow_end_color; + global::Xamarin.Forms.Platform.Resource.Color.design_fab_shadow_mid_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_shadow_mid_color; + global::Xamarin.Forms.Platform.Resource.Color.design_fab_shadow_start_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_shadow_start_color; + global::Xamarin.Forms.Platform.Resource.Color.design_fab_stroke_end_inner_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_stroke_end_inner_color; + global::Xamarin.Forms.Platform.Resource.Color.design_fab_stroke_end_outer_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_stroke_end_outer_color; + global::Xamarin.Forms.Platform.Resource.Color.design_fab_stroke_top_inner_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_stroke_top_inner_color; + global::Xamarin.Forms.Platform.Resource.Color.design_fab_stroke_top_outer_color = global::xamarinFormApp.Droid.Resource.Color.design_fab_stroke_top_outer_color; + global::Xamarin.Forms.Platform.Resource.Color.design_snackbar_background_color = global::xamarinFormApp.Droid.Resource.Color.design_snackbar_background_color; + global::Xamarin.Forms.Platform.Resource.Color.design_tint_password_toggle = global::xamarinFormApp.Droid.Resource.Color.design_tint_password_toggle; + global::Xamarin.Forms.Platform.Resource.Color.dim_foreground_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.dim_foreground_disabled_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.dim_foreground_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.dim_foreground_disabled_material_light; + global::Xamarin.Forms.Platform.Resource.Color.dim_foreground_material_dark = global::xamarinFormApp.Droid.Resource.Color.dim_foreground_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.dim_foreground_material_light = global::xamarinFormApp.Droid.Resource.Color.dim_foreground_material_light; + global::Xamarin.Forms.Platform.Resource.Color.error_color_material_dark = global::xamarinFormApp.Droid.Resource.Color.error_color_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.error_color_material_light = global::xamarinFormApp.Droid.Resource.Color.error_color_material_light; + global::Xamarin.Forms.Platform.Resource.Color.foreground_material_dark = global::xamarinFormApp.Droid.Resource.Color.foreground_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.foreground_material_light = global::xamarinFormApp.Droid.Resource.Color.foreground_material_light; + global::Xamarin.Forms.Platform.Resource.Color.highlighted_text_material_dark = global::xamarinFormApp.Droid.Resource.Color.highlighted_text_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.highlighted_text_material_light = global::xamarinFormApp.Droid.Resource.Color.highlighted_text_material_light; + global::Xamarin.Forms.Platform.Resource.Color.material_blue_grey_800 = global::xamarinFormApp.Droid.Resource.Color.material_blue_grey_800; + global::Xamarin.Forms.Platform.Resource.Color.material_blue_grey_900 = global::xamarinFormApp.Droid.Resource.Color.material_blue_grey_900; + global::Xamarin.Forms.Platform.Resource.Color.material_blue_grey_950 = global::xamarinFormApp.Droid.Resource.Color.material_blue_grey_950; + global::Xamarin.Forms.Platform.Resource.Color.material_deep_teal_200 = global::xamarinFormApp.Droid.Resource.Color.material_deep_teal_200; + global::Xamarin.Forms.Platform.Resource.Color.material_deep_teal_500 = global::xamarinFormApp.Droid.Resource.Color.material_deep_teal_500; + global::Xamarin.Forms.Platform.Resource.Color.material_grey_100 = global::xamarinFormApp.Droid.Resource.Color.material_grey_100; + global::Xamarin.Forms.Platform.Resource.Color.material_grey_300 = global::xamarinFormApp.Droid.Resource.Color.material_grey_300; + global::Xamarin.Forms.Platform.Resource.Color.material_grey_50 = global::xamarinFormApp.Droid.Resource.Color.material_grey_50; + global::Xamarin.Forms.Platform.Resource.Color.material_grey_600 = global::xamarinFormApp.Droid.Resource.Color.material_grey_600; + global::Xamarin.Forms.Platform.Resource.Color.material_grey_800 = global::xamarinFormApp.Droid.Resource.Color.material_grey_800; + global::Xamarin.Forms.Platform.Resource.Color.material_grey_850 = global::xamarinFormApp.Droid.Resource.Color.material_grey_850; + global::Xamarin.Forms.Platform.Resource.Color.material_grey_900 = global::xamarinFormApp.Droid.Resource.Color.material_grey_900; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_bottom_nav_colored_item_tint = global::xamarinFormApp.Droid.Resource.Color.mtrl_bottom_nav_colored_item_tint; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_bottom_nav_item_tint = global::xamarinFormApp.Droid.Resource.Color.mtrl_bottom_nav_item_tint; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_btn_bg_color_disabled = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_bg_color_disabled; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_btn_bg_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_bg_color_selector; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_btn_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_ripple_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_btn_stroke_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_stroke_color_selector; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_btn_text_btn_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_text_btn_ripple_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_btn_text_color_disabled = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_text_color_disabled; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_btn_text_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_text_color_selector; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_btn_transparent_bg_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_btn_transparent_bg_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_chip_background_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_chip_background_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_chip_close_icon_tint = global::xamarinFormApp.Droid.Resource.Color.mtrl_chip_close_icon_tint; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_chip_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_chip_ripple_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_chip_text_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_chip_text_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_fab_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_fab_ripple_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_scrim_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_scrim_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_tabs_colored_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_colored_ripple_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_tabs_icon_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_icon_color_selector; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_tabs_icon_color_selector_colored = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_icon_color_selector_colored; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_tabs_legacy_text_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_legacy_text_color_selector; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_tabs_ripple_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_tabs_ripple_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_textinput_default_box_stroke_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_textinput_default_box_stroke_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_textinput_disabled_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_textinput_disabled_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_textinput_filled_box_default_background_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_textinput_filled_box_default_background_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_textinput_hovered_box_stroke_color = global::xamarinFormApp.Droid.Resource.Color.mtrl_textinput_hovered_box_stroke_color; + global::Xamarin.Forms.Platform.Resource.Color.mtrl_text_btn_text_color_selector = global::xamarinFormApp.Droid.Resource.Color.mtrl_text_btn_text_color_selector; + global::Xamarin.Forms.Platform.Resource.Color.notification_action_color_filter = global::xamarinFormApp.Droid.Resource.Color.notification_action_color_filter; + global::Xamarin.Forms.Platform.Resource.Color.notification_icon_bg_color = global::xamarinFormApp.Droid.Resource.Color.notification_icon_bg_color; + global::Xamarin.Forms.Platform.Resource.Color.notification_material_background_media_default_color = global::xamarinFormApp.Droid.Resource.Color.notification_material_background_media_default_color; + global::Xamarin.Forms.Platform.Resource.Color.primary_dark_material_dark = global::xamarinFormApp.Droid.Resource.Color.primary_dark_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.primary_dark_material_light = global::xamarinFormApp.Droid.Resource.Color.primary_dark_material_light; + global::Xamarin.Forms.Platform.Resource.Color.primary_material_dark = global::xamarinFormApp.Droid.Resource.Color.primary_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.primary_material_light = global::xamarinFormApp.Droid.Resource.Color.primary_material_light; + global::Xamarin.Forms.Platform.Resource.Color.primary_text_default_material_dark = global::xamarinFormApp.Droid.Resource.Color.primary_text_default_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.primary_text_default_material_light = global::xamarinFormApp.Droid.Resource.Color.primary_text_default_material_light; + global::Xamarin.Forms.Platform.Resource.Color.primary_text_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.primary_text_disabled_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.primary_text_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.primary_text_disabled_material_light; + global::Xamarin.Forms.Platform.Resource.Color.ripple_material_dark = global::xamarinFormApp.Droid.Resource.Color.ripple_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.ripple_material_light = global::xamarinFormApp.Droid.Resource.Color.ripple_material_light; + global::Xamarin.Forms.Platform.Resource.Color.secondary_text_default_material_dark = global::xamarinFormApp.Droid.Resource.Color.secondary_text_default_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.secondary_text_default_material_light = global::xamarinFormApp.Droid.Resource.Color.secondary_text_default_material_light; + global::Xamarin.Forms.Platform.Resource.Color.secondary_text_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.secondary_text_disabled_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.secondary_text_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.secondary_text_disabled_material_light; + global::Xamarin.Forms.Platform.Resource.Color.switch_thumb_disabled_material_dark = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_disabled_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.switch_thumb_disabled_material_light = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_disabled_material_light; + global::Xamarin.Forms.Platform.Resource.Color.switch_thumb_material_dark = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.switch_thumb_material_light = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_material_light; + global::Xamarin.Forms.Platform.Resource.Color.switch_thumb_normal_material_dark = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_normal_material_dark; + global::Xamarin.Forms.Platform.Resource.Color.switch_thumb_normal_material_light = global::xamarinFormApp.Droid.Resource.Color.switch_thumb_normal_material_light; + global::Xamarin.Forms.Platform.Resource.Color.tooltip_background_dark = global::xamarinFormApp.Droid.Resource.Color.tooltip_background_dark; + global::Xamarin.Forms.Platform.Resource.Color.tooltip_background_light = global::xamarinFormApp.Droid.Resource.Color.tooltip_background_light; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_content_inset_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_content_inset_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_content_inset_with_nav = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_content_inset_with_nav; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_default_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_default_height_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_default_padding_end_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_default_padding_end_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_default_padding_start_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_default_padding_start_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_elevation_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_elevation_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_icon_vertical_padding_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_icon_vertical_padding_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_overflow_padding_end_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_overflow_padding_end_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_overflow_padding_start_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_overflow_padding_start_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_stacked_max_height = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_stacked_max_height; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_stacked_tab_max_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_stacked_tab_max_width; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_subtitle_bottom_margin_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_subtitle_bottom_margin_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_bar_subtitle_top_margin_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_bar_subtitle_top_margin_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_button_min_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_button_min_height_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_button_min_width_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_button_min_width_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_action_button_min_width_overflow_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_action_button_min_width_overflow_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_alert_dialog_button_bar_height = global::xamarinFormApp.Droid.Resource.Dimension.abc_alert_dialog_button_bar_height; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_alert_dialog_button_dimen = global::xamarinFormApp.Droid.Resource.Dimension.abc_alert_dialog_button_dimen; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_button_inset_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_button_inset_horizontal_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_button_inset_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_button_inset_vertical_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_button_padding_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_button_padding_horizontal_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_button_padding_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_button_padding_vertical_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_cascading_menus_min_smallest_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_cascading_menus_min_smallest_width; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_config_prefDialogWidth = global::xamarinFormApp.Droid.Resource.Dimension.abc_config_prefDialogWidth; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_control_corner_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_control_corner_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_control_inset_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_control_inset_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_control_padding_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_control_padding_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_corner_radius_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_corner_radius_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_fixed_height_major = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_fixed_height_major; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_fixed_height_minor = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_fixed_height_minor; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_fixed_width_major = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_fixed_width_major; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_fixed_width_minor = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_fixed_width_minor; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_list_padding_bottom_no_buttons = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_list_padding_bottom_no_buttons; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_list_padding_top_no_title = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_list_padding_top_no_title; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_min_width_major = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_min_width_major; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_min_width_minor = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_min_width_minor; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_padding_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_padding_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_padding_top_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_padding_top_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dialog_title_divider_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_dialog_title_divider_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_disabled_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.abc_disabled_alpha_material_dark; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_disabled_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.abc_disabled_alpha_material_light; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dropdownitem_icon_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_dropdownitem_icon_width; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dropdownitem_text_padding_left = global::xamarinFormApp.Droid.Resource.Dimension.abc_dropdownitem_text_padding_left; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_dropdownitem_text_padding_right = global::xamarinFormApp.Droid.Resource.Dimension.abc_dropdownitem_text_padding_right; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_edit_text_inset_bottom_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_edit_text_inset_bottom_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_edit_text_inset_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_edit_text_inset_horizontal_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_edit_text_inset_top_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_edit_text_inset_top_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_floating_window_z = global::xamarinFormApp.Droid.Resource.Dimension.abc_floating_window_z; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_list_item_padding_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_list_item_padding_horizontal_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_panel_menu_list_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_panel_menu_list_width; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_progress_bar_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_progress_bar_height_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_search_view_preferred_height = global::xamarinFormApp.Droid.Resource.Dimension.abc_search_view_preferred_height; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_search_view_preferred_width = global::xamarinFormApp.Droid.Resource.Dimension.abc_search_view_preferred_width; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_seekbar_track_background_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_seekbar_track_background_height_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_seekbar_track_progress_height_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_seekbar_track_progress_height_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_select_dialog_padding_start_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_select_dialog_padding_start_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_switch_padding = global::xamarinFormApp.Droid.Resource.Dimension.abc_switch_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_body_1_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_body_1_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_body_2_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_body_2_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_button_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_button_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_caption_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_caption_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_display_1_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_display_1_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_display_2_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_display_2_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_display_3_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_display_3_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_display_4_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_display_4_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_headline_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_headline_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_large_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_large_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_medium_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_medium_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_menu_header_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_menu_header_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_menu_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_menu_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_small_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_small_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_subhead_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_subhead_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_subtitle_material_toolbar = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_subtitle_material_toolbar; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_title_material = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_title_material; + global::Xamarin.Forms.Platform.Resource.Dimension.abc_text_size_title_material_toolbar = global::xamarinFormApp.Droid.Resource.Dimension.abc_text_size_title_material_toolbar; + global::Xamarin.Forms.Platform.Resource.Dimension.cardview_compat_inset_shadow = global::xamarinFormApp.Droid.Resource.Dimension.cardview_compat_inset_shadow; + global::Xamarin.Forms.Platform.Resource.Dimension.cardview_default_elevation = global::xamarinFormApp.Droid.Resource.Dimension.cardview_default_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.cardview_default_radius = global::xamarinFormApp.Droid.Resource.Dimension.cardview_default_radius; + global::Xamarin.Forms.Platform.Resource.Dimension.compat_button_inset_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_inset_horizontal_material; + global::Xamarin.Forms.Platform.Resource.Dimension.compat_button_inset_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_inset_vertical_material; + global::Xamarin.Forms.Platform.Resource.Dimension.compat_button_padding_horizontal_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_padding_horizontal_material; + global::Xamarin.Forms.Platform.Resource.Dimension.compat_button_padding_vertical_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_button_padding_vertical_material; + global::Xamarin.Forms.Platform.Resource.Dimension.compat_control_corner_material = global::xamarinFormApp.Droid.Resource.Dimension.compat_control_corner_material; + global::Xamarin.Forms.Platform.Resource.Dimension.compat_notification_large_icon_max_height = global::xamarinFormApp.Droid.Resource.Dimension.compat_notification_large_icon_max_height; + global::Xamarin.Forms.Platform.Resource.Dimension.compat_notification_large_icon_max_width = global::xamarinFormApp.Droid.Resource.Dimension.compat_notification_large_icon_max_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_appbar_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_appbar_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_active_item_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_active_item_max_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_active_item_min_width = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_active_item_min_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_active_text_size = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_active_text_size; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_height = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_height; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_icon_size; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_item_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_item_max_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_item_min_width = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_item_min_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_margin = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_margin; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_shadow_height = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_shadow_height; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_navigation_text_size = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_navigation_text_size; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_sheet_modal_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_sheet_modal_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.design_bottom_sheet_peek_height_min = global::xamarinFormApp.Droid.Resource.Dimension.design_bottom_sheet_peek_height_min; + global::Xamarin.Forms.Platform.Resource.Dimension.design_fab_border_width = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_border_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_fab_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.design_fab_image_size = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_image_size; + global::Xamarin.Forms.Platform.Resource.Dimension.design_fab_size_mini = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_size_mini; + global::Xamarin.Forms.Platform.Resource.Dimension.design_fab_size_normal = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_size_normal; + global::Xamarin.Forms.Platform.Resource.Dimension.design_fab_translation_z_hovered_focused = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_translation_z_hovered_focused; + global::Xamarin.Forms.Platform.Resource.Dimension.design_fab_translation_z_pressed = global::xamarinFormApp.Droid.Resource.Dimension.design_fab_translation_z_pressed; + global::Xamarin.Forms.Platform.Resource.Dimension.design_navigation_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.design_navigation_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_icon_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.design_navigation_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_icon_size; + global::Xamarin.Forms.Platform.Resource.Dimension.design_navigation_item_horizontal_padding = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_item_horizontal_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.design_navigation_item_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_item_icon_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.design_navigation_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_max_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_navigation_padding_bottom = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_padding_bottom; + global::Xamarin.Forms.Platform.Resource.Dimension.design_navigation_separator_vertical_padding = global::xamarinFormApp.Droid.Resource.Dimension.design_navigation_separator_vertical_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_action_inline_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_action_inline_max_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_background_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_background_corner_radius; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_elevation = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_extra_spacing_horizontal = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_extra_spacing_horizontal; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_max_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_min_width = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_min_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_padding_horizontal = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_padding_horizontal; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_padding_vertical = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_padding_vertical; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_padding_vertical_2lines = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_padding_vertical_2lines; + global::Xamarin.Forms.Platform.Resource.Dimension.design_snackbar_text_size = global::xamarinFormApp.Droid.Resource.Dimension.design_snackbar_text_size; + global::Xamarin.Forms.Platform.Resource.Dimension.design_tab_max_width = global::xamarinFormApp.Droid.Resource.Dimension.design_tab_max_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_tab_scrollable_min_width = global::xamarinFormApp.Droid.Resource.Dimension.design_tab_scrollable_min_width; + global::Xamarin.Forms.Platform.Resource.Dimension.design_tab_text_size = global::xamarinFormApp.Droid.Resource.Dimension.design_tab_text_size; + global::Xamarin.Forms.Platform.Resource.Dimension.design_tab_text_size_2line = global::xamarinFormApp.Droid.Resource.Dimension.design_tab_text_size_2line; + global::Xamarin.Forms.Platform.Resource.Dimension.design_textinput_caption_translate_y = global::xamarinFormApp.Droid.Resource.Dimension.design_textinput_caption_translate_y; + global::Xamarin.Forms.Platform.Resource.Dimension.disabled_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.disabled_alpha_material_dark; + global::Xamarin.Forms.Platform.Resource.Dimension.disabled_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.disabled_alpha_material_light; + global::Xamarin.Forms.Platform.Resource.Dimension.fastscroll_default_thickness = global::xamarinFormApp.Droid.Resource.Dimension.fastscroll_default_thickness; + global::Xamarin.Forms.Platform.Resource.Dimension.fastscroll_margin = global::xamarinFormApp.Droid.Resource.Dimension.fastscroll_margin; + global::Xamarin.Forms.Platform.Resource.Dimension.fastscroll_minimum_range = global::xamarinFormApp.Droid.Resource.Dimension.fastscroll_minimum_range; + global::Xamarin.Forms.Platform.Resource.Dimension.highlight_alpha_material_colored = global::xamarinFormApp.Droid.Resource.Dimension.highlight_alpha_material_colored; + global::Xamarin.Forms.Platform.Resource.Dimension.highlight_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.highlight_alpha_material_dark; + global::Xamarin.Forms.Platform.Resource.Dimension.highlight_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.highlight_alpha_material_light; + global::Xamarin.Forms.Platform.Resource.Dimension.hint_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.hint_alpha_material_dark; + global::Xamarin.Forms.Platform.Resource.Dimension.hint_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.hint_alpha_material_light; + global::Xamarin.Forms.Platform.Resource.Dimension.hint_pressed_alpha_material_dark = global::xamarinFormApp.Droid.Resource.Dimension.hint_pressed_alpha_material_dark; + global::Xamarin.Forms.Platform.Resource.Dimension.hint_pressed_alpha_material_light = global::xamarinFormApp.Droid.Resource.Dimension.hint_pressed_alpha_material_light; + global::Xamarin.Forms.Platform.Resource.Dimension.item_touch_helper_max_drag_scroll_per_frame = global::xamarinFormApp.Droid.Resource.Dimension.item_touch_helper_max_drag_scroll_per_frame; + global::Xamarin.Forms.Platform.Resource.Dimension.item_touch_helper_swipe_escape_max_velocity = global::xamarinFormApp.Droid.Resource.Dimension.item_touch_helper_swipe_escape_max_velocity; + global::Xamarin.Forms.Platform.Resource.Dimension.item_touch_helper_swipe_escape_velocity = global::xamarinFormApp.Droid.Resource.Dimension.item_touch_helper_swipe_escape_velocity; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_bottomappbar_fabOffsetEndMode = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_fabOffsetEndMode; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_bottomappbar_fab_cradle_margin = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_fab_cradle_margin; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_bottomappbar_fab_cradle_rounded_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_fab_cradle_rounded_corner_radius; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_bottomappbar_fab_cradle_vertical_offset = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_fab_cradle_vertical_offset; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_bottomappbar_height = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_bottomappbar_height; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_corner_radius; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_dialog_btn_min_width = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_dialog_btn_min_width; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_disabled_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_disabled_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_disabled_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_disabled_z; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_focused_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_focused_z; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_hovered_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_hovered_z; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_icon_btn_padding_left = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_icon_btn_padding_left; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_icon_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_inset = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_inset; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_letter_spacing = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_letter_spacing; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_padding_bottom = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_padding_bottom; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_padding_left = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_padding_left; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_padding_right = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_padding_right; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_padding_top = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_padding_top; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_pressed_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_pressed_z; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_stroke_size = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_stroke_size; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_text_btn_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_text_btn_icon_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_text_btn_padding_left = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_text_btn_padding_left; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_text_btn_padding_right = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_text_btn_padding_right; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_text_size = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_text_size; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_btn_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_btn_z; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_card_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_card_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_card_spacing = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_card_spacing; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_chip_pressed_translation_z = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_chip_pressed_translation_z; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_chip_text_size = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_chip_text_size; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_fab_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_fab_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_fab_translation_z_hovered_focused = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_fab_translation_z_hovered_focused; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_fab_translation_z_pressed = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_fab_translation_z_pressed; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_navigation_elevation = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_navigation_elevation; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_navigation_item_horizontal_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_navigation_item_horizontal_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_navigation_item_icon_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_navigation_item_icon_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_snackbar_background_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_snackbar_background_corner_radius; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_snackbar_margin = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_snackbar_margin; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_textinput_box_bottom_offset = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_bottom_offset; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_textinput_box_corner_radius_medium = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_corner_radius_medium; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_textinput_box_corner_radius_small = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_corner_radius_small; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_textinput_box_label_cutout_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_label_cutout_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_textinput_box_padding_end = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_padding_end; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_textinput_box_stroke_width_default = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_stroke_width_default; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_textinput_box_stroke_width_focused = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_box_stroke_width_focused; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_textinput_outline_box_expanded_padding = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_textinput_outline_box_expanded_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.mtrl_toolbar_default_height = global::xamarinFormApp.Droid.Resource.Dimension.mtrl_toolbar_default_height; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_action_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_action_icon_size; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_action_text_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_action_text_size; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_big_circle_margin = global::xamarinFormApp.Droid.Resource.Dimension.notification_big_circle_margin; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_content_margin_start = global::xamarinFormApp.Droid.Resource.Dimension.notification_content_margin_start; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_large_icon_height = global::xamarinFormApp.Droid.Resource.Dimension.notification_large_icon_height; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_large_icon_width = global::xamarinFormApp.Droid.Resource.Dimension.notification_large_icon_width; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_main_column_padding_top = global::xamarinFormApp.Droid.Resource.Dimension.notification_main_column_padding_top; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_media_narrow_margin = global::xamarinFormApp.Droid.Resource.Dimension.notification_media_narrow_margin; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_right_icon_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_right_icon_size; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_right_side_padding_top = global::xamarinFormApp.Droid.Resource.Dimension.notification_right_side_padding_top; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_small_icon_background_padding = global::xamarinFormApp.Droid.Resource.Dimension.notification_small_icon_background_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_small_icon_size_as_large = global::xamarinFormApp.Droid.Resource.Dimension.notification_small_icon_size_as_large; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_subtext_size = global::xamarinFormApp.Droid.Resource.Dimension.notification_subtext_size; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_top_pad = global::xamarinFormApp.Droid.Resource.Dimension.notification_top_pad; + global::Xamarin.Forms.Platform.Resource.Dimension.notification_top_pad_large_text = global::xamarinFormApp.Droid.Resource.Dimension.notification_top_pad_large_text; + global::Xamarin.Forms.Platform.Resource.Dimension.subtitle_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.subtitle_corner_radius; + global::Xamarin.Forms.Platform.Resource.Dimension.subtitle_outline_width = global::xamarinFormApp.Droid.Resource.Dimension.subtitle_outline_width; + global::Xamarin.Forms.Platform.Resource.Dimension.subtitle_shadow_offset = global::xamarinFormApp.Droid.Resource.Dimension.subtitle_shadow_offset; + global::Xamarin.Forms.Platform.Resource.Dimension.subtitle_shadow_radius = global::xamarinFormApp.Droid.Resource.Dimension.subtitle_shadow_radius; + global::Xamarin.Forms.Platform.Resource.Dimension.tooltip_corner_radius = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_corner_radius; + global::Xamarin.Forms.Platform.Resource.Dimension.tooltip_horizontal_padding = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_horizontal_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.tooltip_margin = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_margin; + global::Xamarin.Forms.Platform.Resource.Dimension.tooltip_precise_anchor_extra_offset = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_precise_anchor_extra_offset; + global::Xamarin.Forms.Platform.Resource.Dimension.tooltip_precise_anchor_threshold = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_precise_anchor_threshold; + global::Xamarin.Forms.Platform.Resource.Dimension.tooltip_vertical_padding = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_vertical_padding; + global::Xamarin.Forms.Platform.Resource.Dimension.tooltip_y_offset_non_touch = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_y_offset_non_touch; + global::Xamarin.Forms.Platform.Resource.Dimension.tooltip_y_offset_touch = global::xamarinFormApp.Droid.Resource.Dimension.tooltip_y_offset_touch; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ab_share_pack_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ab_share_pack_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_action_bar_item_background_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_action_bar_item_background_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_borderless_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_borderless_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_check_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_check_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_check_to_on_mtrl_000 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_check_to_on_mtrl_000; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_check_to_on_mtrl_015 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_check_to_on_mtrl_015; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_colored_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_colored_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_default_mtrl_shape = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_default_mtrl_shape; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_radio_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_radio_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_radio_to_on_mtrl_000 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_radio_to_on_mtrl_000; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_radio_to_on_mtrl_015 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_radio_to_on_mtrl_015; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_switch_to_on_mtrl_00001 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_switch_to_on_mtrl_00001; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_btn_switch_to_on_mtrl_00012 = global::xamarinFormApp.Droid.Resource.Drawable.abc_btn_switch_to_on_mtrl_00012; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_cab_background_internal_bg = global::xamarinFormApp.Droid.Resource.Drawable.abc_cab_background_internal_bg; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_cab_background_top_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_cab_background_top_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_cab_background_top_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_cab_background_top_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_control_background_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_control_background_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_dialog_material_background = global::xamarinFormApp.Droid.Resource.Drawable.abc_dialog_material_background; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_edit_text_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_edit_text_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_ab_back_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_ab_back_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_arrow_drop_right_black_24dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_arrow_drop_right_black_24dp; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_clear_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_clear_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_commit_search_api_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_commit_search_api_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_go_search_api_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_go_search_api_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_menu_copy_mtrl_am_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_copy_mtrl_am_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_menu_cut_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_cut_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_menu_overflow_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_overflow_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_menu_paste_mtrl_am_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_paste_mtrl_am_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_menu_selectall_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_selectall_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_menu_share_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_menu_share_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_search_api_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_search_api_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_star_black_16dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_black_16dp; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_star_black_36dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_black_36dp; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_star_black_48dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_black_48dp; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_star_half_black_16dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_half_black_16dp; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_star_half_black_36dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_half_black_36dp; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_star_half_black_48dp = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_star_half_black_48dp; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ic_voice_search_api_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ic_voice_search_api_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_item_background_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_item_background_holo_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_item_background_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_item_background_holo_light; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_divider_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_divider_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_divider_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_divider_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_focused_holo = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_focused_holo; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_longpressed_holo = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_longpressed_holo; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_pressed_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_pressed_holo_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_pressed_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_pressed_holo_light; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_selector_background_transition_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_background_transition_holo_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_selector_background_transition_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_background_transition_holo_light; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_selector_disabled_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_disabled_holo_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_selector_disabled_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_disabled_holo_light; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_selector_holo_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_holo_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_list_selector_holo_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_list_selector_holo_light; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_menu_hardkey_panel_mtrl_mult = global::xamarinFormApp.Droid.Resource.Drawable.abc_menu_hardkey_panel_mtrl_mult; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_popup_background_mtrl_mult = global::xamarinFormApp.Droid.Resource.Drawable.abc_popup_background_mtrl_mult; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ratingbar_indicator_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ratingbar_indicator_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ratingbar_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ratingbar_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_ratingbar_small_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_ratingbar_small_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_scrubber_control_off_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_control_off_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_scrubber_control_to_pressed_mtrl_000 = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_control_to_pressed_mtrl_000; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_scrubber_control_to_pressed_mtrl_005 = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_control_to_pressed_mtrl_005; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_scrubber_primary_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_primary_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_scrubber_track_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_scrubber_track_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_seekbar_thumb_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_seekbar_thumb_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_seekbar_tick_mark_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_seekbar_tick_mark_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_seekbar_track_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_seekbar_track_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_spinner_mtrl_am_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_spinner_mtrl_am_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_spinner_textfield_background_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_spinner_textfield_background_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_switch_thumb_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_switch_thumb_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_switch_track_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_switch_track_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_tab_indicator_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_tab_indicator_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_tab_indicator_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_tab_indicator_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_textfield_activated_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_activated_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_textfield_default_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_default_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_textfield_search_activated_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_search_activated_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_textfield_search_default_mtrl_alpha = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_search_default_mtrl_alpha; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_textfield_search_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_textfield_search_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_text_cursor_material = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_cursor_material; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_text_select_handle_left_mtrl_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_left_mtrl_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_text_select_handle_left_mtrl_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_left_mtrl_light; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_text_select_handle_middle_mtrl_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_middle_mtrl_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_text_select_handle_middle_mtrl_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_middle_mtrl_light; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_text_select_handle_right_mtrl_dark = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_right_mtrl_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_text_select_handle_right_mtrl_light = global::xamarinFormApp.Droid.Resource.Drawable.abc_text_select_handle_right_mtrl_light; + global::Xamarin.Forms.Platform.Resource.Drawable.abc_vector_test = global::xamarinFormApp.Droid.Resource.Drawable.abc_vector_test; + global::Xamarin.Forms.Platform.Resource.Drawable.avd_hide_password = global::xamarinFormApp.Droid.Resource.Drawable.avd_hide_password; + global::Xamarin.Forms.Platform.Resource.Drawable.avd_show_password = global::xamarinFormApp.Droid.Resource.Drawable.avd_show_password; + global::Xamarin.Forms.Platform.Resource.Drawable.design_bottom_navigation_item_background = global::xamarinFormApp.Droid.Resource.Drawable.design_bottom_navigation_item_background; + global::Xamarin.Forms.Platform.Resource.Drawable.design_fab_background = global::xamarinFormApp.Droid.Resource.Drawable.design_fab_background; + global::Xamarin.Forms.Platform.Resource.Drawable.design_ic_visibility = global::xamarinFormApp.Droid.Resource.Drawable.design_ic_visibility; + global::Xamarin.Forms.Platform.Resource.Drawable.design_ic_visibility_off = global::xamarinFormApp.Droid.Resource.Drawable.design_ic_visibility_off; + global::Xamarin.Forms.Platform.Resource.Drawable.design_password_eye = global::xamarinFormApp.Droid.Resource.Drawable.design_password_eye; + global::Xamarin.Forms.Platform.Resource.Drawable.design_snackbar_background = global::xamarinFormApp.Droid.Resource.Drawable.design_snackbar_background; + global::Xamarin.Forms.Platform.Resource.Drawable.ic_mtrl_chip_checked_black = global::xamarinFormApp.Droid.Resource.Drawable.ic_mtrl_chip_checked_black; + global::Xamarin.Forms.Platform.Resource.Drawable.ic_mtrl_chip_checked_circle = global::xamarinFormApp.Droid.Resource.Drawable.ic_mtrl_chip_checked_circle; + global::Xamarin.Forms.Platform.Resource.Drawable.ic_mtrl_chip_close_circle = global::xamarinFormApp.Droid.Resource.Drawable.ic_mtrl_chip_close_circle; + global::Xamarin.Forms.Platform.Resource.Drawable.mtrl_snackbar_background = global::xamarinFormApp.Droid.Resource.Drawable.mtrl_snackbar_background; + global::Xamarin.Forms.Platform.Resource.Drawable.mtrl_tabs_default_indicator = global::xamarinFormApp.Droid.Resource.Drawable.mtrl_tabs_default_indicator; + global::Xamarin.Forms.Platform.Resource.Drawable.navigation_empty_icon = global::xamarinFormApp.Droid.Resource.Drawable.navigation_empty_icon; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_action_background = global::xamarinFormApp.Droid.Resource.Drawable.notification_action_background; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_bg_low = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_bg_low_normal = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low_normal; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_bg_low_pressed = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_low_pressed; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_bg_normal = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_normal; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_bg_normal_pressed = global::xamarinFormApp.Droid.Resource.Drawable.notification_bg_normal_pressed; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_icon_background = global::xamarinFormApp.Droid.Resource.Drawable.notification_icon_background; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_template_icon_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_template_icon_bg; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_template_icon_low_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_template_icon_low_bg; + global::Xamarin.Forms.Platform.Resource.Drawable.notification_tile_bg = global::xamarinFormApp.Droid.Resource.Drawable.notification_tile_bg; + global::Xamarin.Forms.Platform.Resource.Drawable.notify_panel_notification_icon_bg = global::xamarinFormApp.Droid.Resource.Drawable.notify_panel_notification_icon_bg; + global::Xamarin.Forms.Platform.Resource.Drawable.tooltip_frame_dark = global::xamarinFormApp.Droid.Resource.Drawable.tooltip_frame_dark; + global::Xamarin.Forms.Platform.Resource.Drawable.tooltip_frame_light = global::xamarinFormApp.Droid.Resource.Drawable.tooltip_frame_light; + global::Xamarin.Forms.Platform.Resource.Id.action0 = global::xamarinFormApp.Droid.Resource.Id.action0; + global::Xamarin.Forms.Platform.Resource.Id.actions = global::xamarinFormApp.Droid.Resource.Id.actions; + global::Xamarin.Forms.Platform.Resource.Id.action_bar = global::xamarinFormApp.Droid.Resource.Id.action_bar; + global::Xamarin.Forms.Platform.Resource.Id.action_bar_activity_content = global::xamarinFormApp.Droid.Resource.Id.action_bar_activity_content; + global::Xamarin.Forms.Platform.Resource.Id.action_bar_container = global::xamarinFormApp.Droid.Resource.Id.action_bar_container; + global::Xamarin.Forms.Platform.Resource.Id.action_bar_root = global::xamarinFormApp.Droid.Resource.Id.action_bar_root; + global::Xamarin.Forms.Platform.Resource.Id.action_bar_spinner = global::xamarinFormApp.Droid.Resource.Id.action_bar_spinner; + global::Xamarin.Forms.Platform.Resource.Id.action_bar_subtitle = global::xamarinFormApp.Droid.Resource.Id.action_bar_subtitle; + global::Xamarin.Forms.Platform.Resource.Id.action_bar_title = global::xamarinFormApp.Droid.Resource.Id.action_bar_title; + global::Xamarin.Forms.Platform.Resource.Id.action_container = global::xamarinFormApp.Droid.Resource.Id.action_container; + global::Xamarin.Forms.Platform.Resource.Id.action_context_bar = global::xamarinFormApp.Droid.Resource.Id.action_context_bar; + global::Xamarin.Forms.Platform.Resource.Id.action_divider = global::xamarinFormApp.Droid.Resource.Id.action_divider; + global::Xamarin.Forms.Platform.Resource.Id.action_image = global::xamarinFormApp.Droid.Resource.Id.action_image; + global::Xamarin.Forms.Platform.Resource.Id.action_menu_divider = global::xamarinFormApp.Droid.Resource.Id.action_menu_divider; + global::Xamarin.Forms.Platform.Resource.Id.action_menu_presenter = global::xamarinFormApp.Droid.Resource.Id.action_menu_presenter; + global::Xamarin.Forms.Platform.Resource.Id.action_mode_bar = global::xamarinFormApp.Droid.Resource.Id.action_mode_bar; + global::Xamarin.Forms.Platform.Resource.Id.action_mode_bar_stub = global::xamarinFormApp.Droid.Resource.Id.action_mode_bar_stub; + global::Xamarin.Forms.Platform.Resource.Id.action_mode_close_button = global::xamarinFormApp.Droid.Resource.Id.action_mode_close_button; + global::Xamarin.Forms.Platform.Resource.Id.action_text = global::xamarinFormApp.Droid.Resource.Id.action_text; + global::Xamarin.Forms.Platform.Resource.Id.activity_chooser_view_content = global::xamarinFormApp.Droid.Resource.Id.activity_chooser_view_content; + global::Xamarin.Forms.Platform.Resource.Id.add = global::xamarinFormApp.Droid.Resource.Id.add; + global::Xamarin.Forms.Platform.Resource.Id.alertTitle = global::xamarinFormApp.Droid.Resource.Id.alertTitle; + global::Xamarin.Forms.Platform.Resource.Id.all = global::xamarinFormApp.Droid.Resource.Id.all; + global::Xamarin.Forms.Platform.Resource.Id.ALT = global::xamarinFormApp.Droid.Resource.Id.ALT; + global::Xamarin.Forms.Platform.Resource.Id.always = global::xamarinFormApp.Droid.Resource.Id.always; + global::Xamarin.Forms.Platform.Resource.Id.async = global::xamarinFormApp.Droid.Resource.Id.async; + global::Xamarin.Forms.Platform.Resource.Id.auto = global::xamarinFormApp.Droid.Resource.Id.auto; + global::Xamarin.Forms.Platform.Resource.Id.beginning = global::xamarinFormApp.Droid.Resource.Id.beginning; + global::Xamarin.Forms.Platform.Resource.Id.blocking = global::xamarinFormApp.Droid.Resource.Id.blocking; + global::Xamarin.Forms.Platform.Resource.Id.bottom = global::xamarinFormApp.Droid.Resource.Id.bottom; + global::Xamarin.Forms.Platform.Resource.Id.bottomtab_navarea = global::xamarinFormApp.Droid.Resource.Id.bottomtab_navarea; + global::Xamarin.Forms.Platform.Resource.Id.bottomtab_tabbar = global::xamarinFormApp.Droid.Resource.Id.bottomtab_tabbar; + global::Xamarin.Forms.Platform.Resource.Id.buttonPanel = global::xamarinFormApp.Droid.Resource.Id.buttonPanel; + global::Xamarin.Forms.Platform.Resource.Id.cancel_action = global::xamarinFormApp.Droid.Resource.Id.cancel_action; + global::Xamarin.Forms.Platform.Resource.Id.center = global::xamarinFormApp.Droid.Resource.Id.center; + global::Xamarin.Forms.Platform.Resource.Id.center_horizontal = global::xamarinFormApp.Droid.Resource.Id.center_horizontal; + global::Xamarin.Forms.Platform.Resource.Id.center_vertical = global::xamarinFormApp.Droid.Resource.Id.center_vertical; + global::Xamarin.Forms.Platform.Resource.Id.checkbox = global::xamarinFormApp.Droid.Resource.Id.checkbox; + global::Xamarin.Forms.Platform.Resource.Id.chronometer = global::xamarinFormApp.Droid.Resource.Id.chronometer; + global::Xamarin.Forms.Platform.Resource.Id.clip_horizontal = global::xamarinFormApp.Droid.Resource.Id.clip_horizontal; + global::Xamarin.Forms.Platform.Resource.Id.clip_vertical = global::xamarinFormApp.Droid.Resource.Id.clip_vertical; + global::Xamarin.Forms.Platform.Resource.Id.collapseActionView = global::xamarinFormApp.Droid.Resource.Id.collapseActionView; + global::Xamarin.Forms.Platform.Resource.Id.container = global::xamarinFormApp.Droid.Resource.Id.container; + global::Xamarin.Forms.Platform.Resource.Id.content = global::xamarinFormApp.Droid.Resource.Id.content; + global::Xamarin.Forms.Platform.Resource.Id.contentPanel = global::xamarinFormApp.Droid.Resource.Id.contentPanel; + global::Xamarin.Forms.Platform.Resource.Id.coordinator = global::xamarinFormApp.Droid.Resource.Id.coordinator; + global::Xamarin.Forms.Platform.Resource.Id.CTRL = global::xamarinFormApp.Droid.Resource.Id.CTRL; + global::Xamarin.Forms.Platform.Resource.Id.custom = global::xamarinFormApp.Droid.Resource.Id.custom; + global::Xamarin.Forms.Platform.Resource.Id.customPanel = global::xamarinFormApp.Droid.Resource.Id.customPanel; + global::Xamarin.Forms.Platform.Resource.Id.decor_content_parent = global::xamarinFormApp.Droid.Resource.Id.decor_content_parent; + global::Xamarin.Forms.Platform.Resource.Id.default_activity_button = global::xamarinFormApp.Droid.Resource.Id.default_activity_button; + global::Xamarin.Forms.Platform.Resource.Id.design_bottom_sheet = global::xamarinFormApp.Droid.Resource.Id.design_bottom_sheet; + global::Xamarin.Forms.Platform.Resource.Id.design_menu_item_action_area = global::xamarinFormApp.Droid.Resource.Id.design_menu_item_action_area; + global::Xamarin.Forms.Platform.Resource.Id.design_menu_item_action_area_stub = global::xamarinFormApp.Droid.Resource.Id.design_menu_item_action_area_stub; + global::Xamarin.Forms.Platform.Resource.Id.design_menu_item_text = global::xamarinFormApp.Droid.Resource.Id.design_menu_item_text; + global::Xamarin.Forms.Platform.Resource.Id.design_navigation_view = global::xamarinFormApp.Droid.Resource.Id.design_navigation_view; + global::Xamarin.Forms.Platform.Resource.Id.disableHome = global::xamarinFormApp.Droid.Resource.Id.disableHome; + global::Xamarin.Forms.Platform.Resource.Id.edit_query = global::xamarinFormApp.Droid.Resource.Id.edit_query; + global::Xamarin.Forms.Platform.Resource.Id.end = global::xamarinFormApp.Droid.Resource.Id.end; + global::Xamarin.Forms.Platform.Resource.Id.end_padder = global::xamarinFormApp.Droid.Resource.Id.end_padder; + global::Xamarin.Forms.Platform.Resource.Id.enterAlways = global::xamarinFormApp.Droid.Resource.Id.enterAlways; + global::Xamarin.Forms.Platform.Resource.Id.enterAlwaysCollapsed = global::xamarinFormApp.Droid.Resource.Id.enterAlwaysCollapsed; + global::Xamarin.Forms.Platform.Resource.Id.exitUntilCollapsed = global::xamarinFormApp.Droid.Resource.Id.exitUntilCollapsed; + global::Xamarin.Forms.Platform.Resource.Id.expanded_menu = global::xamarinFormApp.Droid.Resource.Id.expanded_menu; + global::Xamarin.Forms.Platform.Resource.Id.expand_activities_button = global::xamarinFormApp.Droid.Resource.Id.expand_activities_button; + global::Xamarin.Forms.Platform.Resource.Id.fill = global::xamarinFormApp.Droid.Resource.Id.fill; + global::Xamarin.Forms.Platform.Resource.Id.filled = global::xamarinFormApp.Droid.Resource.Id.filled; + global::Xamarin.Forms.Platform.Resource.Id.fill_horizontal = global::xamarinFormApp.Droid.Resource.Id.fill_horizontal; + global::Xamarin.Forms.Platform.Resource.Id.fill_vertical = global::xamarinFormApp.Droid.Resource.Id.fill_vertical; + global::Xamarin.Forms.Platform.Resource.Id.@fixed = global::xamarinFormApp.Droid.Resource.Id.@fixed; + global::Xamarin.Forms.Platform.Resource.Id.flyoutcontent_appbar = global::xamarinFormApp.Droid.Resource.Id.flyoutcontent_appbar; + global::Xamarin.Forms.Platform.Resource.Id.flyoutcontent_recycler = global::xamarinFormApp.Droid.Resource.Id.flyoutcontent_recycler; + global::Xamarin.Forms.Platform.Resource.Id.forever = global::xamarinFormApp.Droid.Resource.Id.forever; + global::Xamarin.Forms.Platform.Resource.Id.FUNCTION = global::xamarinFormApp.Droid.Resource.Id.FUNCTION; + global::Xamarin.Forms.Platform.Resource.Id.ghost_view = global::xamarinFormApp.Droid.Resource.Id.ghost_view; + global::Xamarin.Forms.Platform.Resource.Id.group_divider = global::xamarinFormApp.Droid.Resource.Id.group_divider; + global::Xamarin.Forms.Platform.Resource.Id.home = global::xamarinFormApp.Droid.Resource.Id.home; + global::Xamarin.Forms.Platform.Resource.Id.homeAsUp = global::xamarinFormApp.Droid.Resource.Id.homeAsUp; + global::Xamarin.Forms.Platform.Resource.Id.icon = global::xamarinFormApp.Droid.Resource.Id.icon; + global::Xamarin.Forms.Platform.Resource.Id.icon_group = global::xamarinFormApp.Droid.Resource.Id.icon_group; + global::Xamarin.Forms.Platform.Resource.Id.ifRoom = global::xamarinFormApp.Droid.Resource.Id.ifRoom; + global::Xamarin.Forms.Platform.Resource.Id.image = global::xamarinFormApp.Droid.Resource.Id.image; + global::Xamarin.Forms.Platform.Resource.Id.info = global::xamarinFormApp.Droid.Resource.Id.info; + global::Xamarin.Forms.Platform.Resource.Id.italic = global::xamarinFormApp.Droid.Resource.Id.italic; + global::Xamarin.Forms.Platform.Resource.Id.item_touch_helper_previous_elevation = global::xamarinFormApp.Droid.Resource.Id.item_touch_helper_previous_elevation; + global::Xamarin.Forms.Platform.Resource.Id.labeled = global::xamarinFormApp.Droid.Resource.Id.labeled; + global::Xamarin.Forms.Platform.Resource.Id.largeLabel = global::xamarinFormApp.Droid.Resource.Id.largeLabel; + global::Xamarin.Forms.Platform.Resource.Id.left = global::xamarinFormApp.Droid.Resource.Id.left; + global::Xamarin.Forms.Platform.Resource.Id.line1 = global::xamarinFormApp.Droid.Resource.Id.line1; + global::Xamarin.Forms.Platform.Resource.Id.line3 = global::xamarinFormApp.Droid.Resource.Id.line3; + global::Xamarin.Forms.Platform.Resource.Id.listMode = global::xamarinFormApp.Droid.Resource.Id.listMode; + global::Xamarin.Forms.Platform.Resource.Id.list_item = global::xamarinFormApp.Droid.Resource.Id.list_item; + global::Xamarin.Forms.Platform.Resource.Id.main_appbar = global::xamarinFormApp.Droid.Resource.Id.main_appbar; + global::Xamarin.Forms.Platform.Resource.Id.main_tablayout = global::xamarinFormApp.Droid.Resource.Id.main_tablayout; + global::Xamarin.Forms.Platform.Resource.Id.main_toolbar = global::xamarinFormApp.Droid.Resource.Id.main_toolbar; + global::Xamarin.Forms.Platform.Resource.Id.main_viewpager = global::xamarinFormApp.Droid.Resource.Id.main_viewpager; + global::Xamarin.Forms.Platform.Resource.Id.masked = global::xamarinFormApp.Droid.Resource.Id.masked; + global::Xamarin.Forms.Platform.Resource.Id.media_actions = global::xamarinFormApp.Droid.Resource.Id.media_actions; + global::Xamarin.Forms.Platform.Resource.Id.message = global::xamarinFormApp.Droid.Resource.Id.message; + global::Xamarin.Forms.Platform.Resource.Id.META = global::xamarinFormApp.Droid.Resource.Id.META; + global::Xamarin.Forms.Platform.Resource.Id.middle = global::xamarinFormApp.Droid.Resource.Id.middle; + global::Xamarin.Forms.Platform.Resource.Id.mini = global::xamarinFormApp.Droid.Resource.Id.mini; + global::Xamarin.Forms.Platform.Resource.Id.mtrl_child_content_container = global::xamarinFormApp.Droid.Resource.Id.mtrl_child_content_container; + global::Xamarin.Forms.Platform.Resource.Id.mtrl_internal_children_alpha_tag = global::xamarinFormApp.Droid.Resource.Id.mtrl_internal_children_alpha_tag; + global::Xamarin.Forms.Platform.Resource.Id.multiply = global::xamarinFormApp.Droid.Resource.Id.multiply; + global::Xamarin.Forms.Platform.Resource.Id.navigation_header_container = global::xamarinFormApp.Droid.Resource.Id.navigation_header_container; + global::Xamarin.Forms.Platform.Resource.Id.never = global::xamarinFormApp.Droid.Resource.Id.never; + global::Xamarin.Forms.Platform.Resource.Id.none = global::xamarinFormApp.Droid.Resource.Id.none; + global::Xamarin.Forms.Platform.Resource.Id.normal = global::xamarinFormApp.Droid.Resource.Id.normal; + global::Xamarin.Forms.Platform.Resource.Id.notification_background = global::xamarinFormApp.Droid.Resource.Id.notification_background; + global::Xamarin.Forms.Platform.Resource.Id.notification_main_column = global::xamarinFormApp.Droid.Resource.Id.notification_main_column; + global::Xamarin.Forms.Platform.Resource.Id.notification_main_column_container = global::xamarinFormApp.Droid.Resource.Id.notification_main_column_container; + global::Xamarin.Forms.Platform.Resource.Id.outline = global::xamarinFormApp.Droid.Resource.Id.outline; + global::Xamarin.Forms.Platform.Resource.Id.parallax = global::xamarinFormApp.Droid.Resource.Id.parallax; + global::Xamarin.Forms.Platform.Resource.Id.parentPanel = global::xamarinFormApp.Droid.Resource.Id.parentPanel; + global::Xamarin.Forms.Platform.Resource.Id.parent_matrix = global::xamarinFormApp.Droid.Resource.Id.parent_matrix; + global::Xamarin.Forms.Platform.Resource.Id.pin = global::xamarinFormApp.Droid.Resource.Id.pin; + global::Xamarin.Forms.Platform.Resource.Id.progress_circular = global::xamarinFormApp.Droid.Resource.Id.progress_circular; + global::Xamarin.Forms.Platform.Resource.Id.progress_horizontal = global::xamarinFormApp.Droid.Resource.Id.progress_horizontal; + global::Xamarin.Forms.Platform.Resource.Id.radio = global::xamarinFormApp.Droid.Resource.Id.radio; + global::Xamarin.Forms.Platform.Resource.Id.right = global::xamarinFormApp.Droid.Resource.Id.right; + global::Xamarin.Forms.Platform.Resource.Id.right_icon = global::xamarinFormApp.Droid.Resource.Id.right_icon; + global::Xamarin.Forms.Platform.Resource.Id.right_side = global::xamarinFormApp.Droid.Resource.Id.right_side; + global::Xamarin.Forms.Platform.Resource.Id.save_image_matrix = global::xamarinFormApp.Droid.Resource.Id.save_image_matrix; + global::Xamarin.Forms.Platform.Resource.Id.save_non_transition_alpha = global::xamarinFormApp.Droid.Resource.Id.save_non_transition_alpha; + global::Xamarin.Forms.Platform.Resource.Id.save_scale_type = global::xamarinFormApp.Droid.Resource.Id.save_scale_type; + global::Xamarin.Forms.Platform.Resource.Id.screen = global::xamarinFormApp.Droid.Resource.Id.screen; + global::Xamarin.Forms.Platform.Resource.Id.scroll = global::xamarinFormApp.Droid.Resource.Id.scroll; + global::Xamarin.Forms.Platform.Resource.Id.scrollable = global::xamarinFormApp.Droid.Resource.Id.scrollable; + global::Xamarin.Forms.Platform.Resource.Id.scrollIndicatorDown = global::xamarinFormApp.Droid.Resource.Id.scrollIndicatorDown; + global::Xamarin.Forms.Platform.Resource.Id.scrollIndicatorUp = global::xamarinFormApp.Droid.Resource.Id.scrollIndicatorUp; + global::Xamarin.Forms.Platform.Resource.Id.scrollView = global::xamarinFormApp.Droid.Resource.Id.scrollView; + global::Xamarin.Forms.Platform.Resource.Id.search_badge = global::xamarinFormApp.Droid.Resource.Id.search_badge; + global::Xamarin.Forms.Platform.Resource.Id.search_bar = global::xamarinFormApp.Droid.Resource.Id.search_bar; + global::Xamarin.Forms.Platform.Resource.Id.search_button = global::xamarinFormApp.Droid.Resource.Id.search_button; + global::Xamarin.Forms.Platform.Resource.Id.search_close_btn = global::xamarinFormApp.Droid.Resource.Id.search_close_btn; + global::Xamarin.Forms.Platform.Resource.Id.search_edit_frame = global::xamarinFormApp.Droid.Resource.Id.search_edit_frame; + global::Xamarin.Forms.Platform.Resource.Id.search_go_btn = global::xamarinFormApp.Droid.Resource.Id.search_go_btn; + global::Xamarin.Forms.Platform.Resource.Id.search_mag_icon = global::xamarinFormApp.Droid.Resource.Id.search_mag_icon; + global::Xamarin.Forms.Platform.Resource.Id.search_plate = global::xamarinFormApp.Droid.Resource.Id.search_plate; + global::Xamarin.Forms.Platform.Resource.Id.search_src_text = global::xamarinFormApp.Droid.Resource.Id.search_src_text; + global::Xamarin.Forms.Platform.Resource.Id.search_voice_btn = global::xamarinFormApp.Droid.Resource.Id.search_voice_btn; + global::Xamarin.Forms.Platform.Resource.Id.selected = global::xamarinFormApp.Droid.Resource.Id.selected; + global::Xamarin.Forms.Platform.Resource.Id.select_dialog_listview = global::xamarinFormApp.Droid.Resource.Id.select_dialog_listview; + global::Xamarin.Forms.Platform.Resource.Id.shellcontent_appbar = global::xamarinFormApp.Droid.Resource.Id.shellcontent_appbar; + global::Xamarin.Forms.Platform.Resource.Id.shellcontent_toolbar = global::xamarinFormApp.Droid.Resource.Id.shellcontent_toolbar; + global::Xamarin.Forms.Platform.Resource.Id.SHIFT = global::xamarinFormApp.Droid.Resource.Id.SHIFT; + global::Xamarin.Forms.Platform.Resource.Id.shortcut = global::xamarinFormApp.Droid.Resource.Id.shortcut; + global::Xamarin.Forms.Platform.Resource.Id.showCustom = global::xamarinFormApp.Droid.Resource.Id.showCustom; + global::Xamarin.Forms.Platform.Resource.Id.showHome = global::xamarinFormApp.Droid.Resource.Id.showHome; + global::Xamarin.Forms.Platform.Resource.Id.showTitle = global::xamarinFormApp.Droid.Resource.Id.showTitle; + global::Xamarin.Forms.Platform.Resource.Id.smallLabel = global::xamarinFormApp.Droid.Resource.Id.smallLabel; + global::Xamarin.Forms.Platform.Resource.Id.snackbar_action = global::xamarinFormApp.Droid.Resource.Id.snackbar_action; + global::Xamarin.Forms.Platform.Resource.Id.snackbar_text = global::xamarinFormApp.Droid.Resource.Id.snackbar_text; + global::Xamarin.Forms.Platform.Resource.Id.snap = global::xamarinFormApp.Droid.Resource.Id.snap; + global::Xamarin.Forms.Platform.Resource.Id.snapMargins = global::xamarinFormApp.Droid.Resource.Id.snapMargins; + global::Xamarin.Forms.Platform.Resource.Id.spacer = global::xamarinFormApp.Droid.Resource.Id.spacer; + global::Xamarin.Forms.Platform.Resource.Id.split_action_bar = global::xamarinFormApp.Droid.Resource.Id.split_action_bar; + global::Xamarin.Forms.Platform.Resource.Id.src_atop = global::xamarinFormApp.Droid.Resource.Id.src_atop; + global::Xamarin.Forms.Platform.Resource.Id.src_in = global::xamarinFormApp.Droid.Resource.Id.src_in; + global::Xamarin.Forms.Platform.Resource.Id.src_over = global::xamarinFormApp.Droid.Resource.Id.src_over; + global::Xamarin.Forms.Platform.Resource.Id.start = global::xamarinFormApp.Droid.Resource.Id.start; + global::Xamarin.Forms.Platform.Resource.Id.status_bar_latest_event_content = global::xamarinFormApp.Droid.Resource.Id.status_bar_latest_event_content; + global::Xamarin.Forms.Platform.Resource.Id.stretch = global::xamarinFormApp.Droid.Resource.Id.stretch; + global::Xamarin.Forms.Platform.Resource.Id.submenuarrow = global::xamarinFormApp.Droid.Resource.Id.submenuarrow; + global::Xamarin.Forms.Platform.Resource.Id.submit_area = global::xamarinFormApp.Droid.Resource.Id.submit_area; + global::Xamarin.Forms.Platform.Resource.Id.SYM = global::xamarinFormApp.Droid.Resource.Id.SYM; + global::Xamarin.Forms.Platform.Resource.Id.tabMode = global::xamarinFormApp.Droid.Resource.Id.tabMode; + global::Xamarin.Forms.Platform.Resource.Id.tag_transition_group = global::xamarinFormApp.Droid.Resource.Id.tag_transition_group; + global::Xamarin.Forms.Platform.Resource.Id.tag_unhandled_key_event_manager = global::xamarinFormApp.Droid.Resource.Id.tag_unhandled_key_event_manager; + global::Xamarin.Forms.Platform.Resource.Id.tag_unhandled_key_listeners = global::xamarinFormApp.Droid.Resource.Id.tag_unhandled_key_listeners; + global::Xamarin.Forms.Platform.Resource.Id.text = global::xamarinFormApp.Droid.Resource.Id.text; + global::Xamarin.Forms.Platform.Resource.Id.text2 = global::xamarinFormApp.Droid.Resource.Id.text2; + global::Xamarin.Forms.Platform.Resource.Id.textinput_counter = global::xamarinFormApp.Droid.Resource.Id.textinput_counter; + global::Xamarin.Forms.Platform.Resource.Id.textinput_error = global::xamarinFormApp.Droid.Resource.Id.textinput_error; + global::Xamarin.Forms.Platform.Resource.Id.textinput_helper_text = global::xamarinFormApp.Droid.Resource.Id.textinput_helper_text; + global::Xamarin.Forms.Platform.Resource.Id.textSpacerNoButtons = global::xamarinFormApp.Droid.Resource.Id.textSpacerNoButtons; + global::Xamarin.Forms.Platform.Resource.Id.textSpacerNoTitle = global::xamarinFormApp.Droid.Resource.Id.textSpacerNoTitle; + global::Xamarin.Forms.Platform.Resource.Id.textStart = global::xamarinFormApp.Droid.Resource.Id.textStart; + global::Xamarin.Forms.Platform.Resource.Id.text_input_password_toggle = global::xamarinFormApp.Droid.Resource.Id.text_input_password_toggle; + global::Xamarin.Forms.Platform.Resource.Id.time = global::xamarinFormApp.Droid.Resource.Id.time; + global::Xamarin.Forms.Platform.Resource.Id.title = global::xamarinFormApp.Droid.Resource.Id.title; + global::Xamarin.Forms.Platform.Resource.Id.titleDividerNoCustom = global::xamarinFormApp.Droid.Resource.Id.titleDividerNoCustom; + global::Xamarin.Forms.Platform.Resource.Id.title_template = global::xamarinFormApp.Droid.Resource.Id.title_template; + global::Xamarin.Forms.Platform.Resource.Id.top = global::xamarinFormApp.Droid.Resource.Id.top; + global::Xamarin.Forms.Platform.Resource.Id.topPanel = global::xamarinFormApp.Droid.Resource.Id.topPanel; + global::Xamarin.Forms.Platform.Resource.Id.touch_outside = global::xamarinFormApp.Droid.Resource.Id.touch_outside; + global::Xamarin.Forms.Platform.Resource.Id.transition_current_scene = global::xamarinFormApp.Droid.Resource.Id.transition_current_scene; + global::Xamarin.Forms.Platform.Resource.Id.transition_layout_save = global::xamarinFormApp.Droid.Resource.Id.transition_layout_save; + global::Xamarin.Forms.Platform.Resource.Id.transition_position = global::xamarinFormApp.Droid.Resource.Id.transition_position; + global::Xamarin.Forms.Platform.Resource.Id.transition_scene_layoutid_cache = global::xamarinFormApp.Droid.Resource.Id.transition_scene_layoutid_cache; + global::Xamarin.Forms.Platform.Resource.Id.transition_transform = global::xamarinFormApp.Droid.Resource.Id.transition_transform; + global::Xamarin.Forms.Platform.Resource.Id.uniform = global::xamarinFormApp.Droid.Resource.Id.uniform; + global::Xamarin.Forms.Platform.Resource.Id.unlabeled = global::xamarinFormApp.Droid.Resource.Id.unlabeled; + global::Xamarin.Forms.Platform.Resource.Id.up = global::xamarinFormApp.Droid.Resource.Id.up; + global::Xamarin.Forms.Platform.Resource.Id.useLogo = global::xamarinFormApp.Droid.Resource.Id.useLogo; + global::Xamarin.Forms.Platform.Resource.Id.view_offset_helper = global::xamarinFormApp.Droid.Resource.Id.view_offset_helper; + global::Xamarin.Forms.Platform.Resource.Id.visible = global::xamarinFormApp.Droid.Resource.Id.visible; + global::Xamarin.Forms.Platform.Resource.Id.withText = global::xamarinFormApp.Droid.Resource.Id.withText; + global::Xamarin.Forms.Platform.Resource.Id.wrap_content = global::xamarinFormApp.Droid.Resource.Id.wrap_content; + global::Xamarin.Forms.Platform.Resource.Integer.abc_config_activityDefaultDur = global::xamarinFormApp.Droid.Resource.Integer.abc_config_activityDefaultDur; + global::Xamarin.Forms.Platform.Resource.Integer.abc_config_activityShortDur = global::xamarinFormApp.Droid.Resource.Integer.abc_config_activityShortDur; + global::Xamarin.Forms.Platform.Resource.Integer.app_bar_elevation_anim_duration = global::xamarinFormApp.Droid.Resource.Integer.app_bar_elevation_anim_duration; + global::Xamarin.Forms.Platform.Resource.Integer.bottom_sheet_slide_duration = global::xamarinFormApp.Droid.Resource.Integer.bottom_sheet_slide_duration; + global::Xamarin.Forms.Platform.Resource.Integer.cancel_button_image_alpha = global::xamarinFormApp.Droid.Resource.Integer.cancel_button_image_alpha; + global::Xamarin.Forms.Platform.Resource.Integer.config_tooltipAnimTime = global::xamarinFormApp.Droid.Resource.Integer.config_tooltipAnimTime; + global::Xamarin.Forms.Platform.Resource.Integer.design_snackbar_text_max_lines = global::xamarinFormApp.Droid.Resource.Integer.design_snackbar_text_max_lines; + global::Xamarin.Forms.Platform.Resource.Integer.design_tab_indicator_anim_duration_ms = global::xamarinFormApp.Droid.Resource.Integer.design_tab_indicator_anim_duration_ms; + global::Xamarin.Forms.Platform.Resource.Integer.hide_password_duration = global::xamarinFormApp.Droid.Resource.Integer.hide_password_duration; + global::Xamarin.Forms.Platform.Resource.Integer.mtrl_btn_anim_delay_ms = global::xamarinFormApp.Droid.Resource.Integer.mtrl_btn_anim_delay_ms; + global::Xamarin.Forms.Platform.Resource.Integer.mtrl_btn_anim_duration_ms = global::xamarinFormApp.Droid.Resource.Integer.mtrl_btn_anim_duration_ms; + global::Xamarin.Forms.Platform.Resource.Integer.mtrl_chip_anim_duration = global::xamarinFormApp.Droid.Resource.Integer.mtrl_chip_anim_duration; + global::Xamarin.Forms.Platform.Resource.Integer.mtrl_tab_indicator_anim_duration_ms = global::xamarinFormApp.Droid.Resource.Integer.mtrl_tab_indicator_anim_duration_ms; + global::Xamarin.Forms.Platform.Resource.Integer.show_password_duration = global::xamarinFormApp.Droid.Resource.Integer.show_password_duration; + global::Xamarin.Forms.Platform.Resource.Integer.status_bar_notification_info_maxnum = global::xamarinFormApp.Droid.Resource.Integer.status_bar_notification_info_maxnum; + global::Xamarin.Forms.Platform.Resource.Interpolator.mtrl_fast_out_linear_in = global::xamarinFormApp.Droid.Resource.Interpolator.mtrl_fast_out_linear_in; + global::Xamarin.Forms.Platform.Resource.Interpolator.mtrl_fast_out_slow_in = global::xamarinFormApp.Droid.Resource.Interpolator.mtrl_fast_out_slow_in; + global::Xamarin.Forms.Platform.Resource.Interpolator.mtrl_linear = global::xamarinFormApp.Droid.Resource.Interpolator.mtrl_linear; + global::Xamarin.Forms.Platform.Resource.Interpolator.mtrl_linear_out_slow_in = global::xamarinFormApp.Droid.Resource.Interpolator.mtrl_linear_out_slow_in; + global::Xamarin.Forms.Platform.Resource.Layout.abc_action_bar_title_item = global::xamarinFormApp.Droid.Resource.Layout.abc_action_bar_title_item; + global::Xamarin.Forms.Platform.Resource.Layout.abc_action_bar_up_container = global::xamarinFormApp.Droid.Resource.Layout.abc_action_bar_up_container; + global::Xamarin.Forms.Platform.Resource.Layout.abc_action_menu_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_action_menu_item_layout; + global::Xamarin.Forms.Platform.Resource.Layout.abc_action_menu_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_action_menu_layout; + global::Xamarin.Forms.Platform.Resource.Layout.abc_action_mode_bar = global::xamarinFormApp.Droid.Resource.Layout.abc_action_mode_bar; + global::Xamarin.Forms.Platform.Resource.Layout.abc_action_mode_close_item_material = global::xamarinFormApp.Droid.Resource.Layout.abc_action_mode_close_item_material; + global::Xamarin.Forms.Platform.Resource.Layout.abc_activity_chooser_view = global::xamarinFormApp.Droid.Resource.Layout.abc_activity_chooser_view; + global::Xamarin.Forms.Platform.Resource.Layout.abc_activity_chooser_view_list_item = global::xamarinFormApp.Droid.Resource.Layout.abc_activity_chooser_view_list_item; + global::Xamarin.Forms.Platform.Resource.Layout.abc_alert_dialog_button_bar_material = global::xamarinFormApp.Droid.Resource.Layout.abc_alert_dialog_button_bar_material; + global::Xamarin.Forms.Platform.Resource.Layout.abc_alert_dialog_material = global::xamarinFormApp.Droid.Resource.Layout.abc_alert_dialog_material; + global::Xamarin.Forms.Platform.Resource.Layout.abc_alert_dialog_title_material = global::xamarinFormApp.Droid.Resource.Layout.abc_alert_dialog_title_material; + global::Xamarin.Forms.Platform.Resource.Layout.abc_cascading_menu_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_cascading_menu_item_layout; + global::Xamarin.Forms.Platform.Resource.Layout.abc_dialog_title_material = global::xamarinFormApp.Droid.Resource.Layout.abc_dialog_title_material; + global::Xamarin.Forms.Platform.Resource.Layout.abc_expanded_menu_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_expanded_menu_layout; + global::Xamarin.Forms.Platform.Resource.Layout.abc_list_menu_item_checkbox = global::xamarinFormApp.Droid.Resource.Layout.abc_list_menu_item_checkbox; + global::Xamarin.Forms.Platform.Resource.Layout.abc_list_menu_item_icon = global::xamarinFormApp.Droid.Resource.Layout.abc_list_menu_item_icon; + global::Xamarin.Forms.Platform.Resource.Layout.abc_list_menu_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_list_menu_item_layout; + global::Xamarin.Forms.Platform.Resource.Layout.abc_list_menu_item_radio = global::xamarinFormApp.Droid.Resource.Layout.abc_list_menu_item_radio; + global::Xamarin.Forms.Platform.Resource.Layout.abc_popup_menu_header_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_popup_menu_header_item_layout; + global::Xamarin.Forms.Platform.Resource.Layout.abc_popup_menu_item_layout = global::xamarinFormApp.Droid.Resource.Layout.abc_popup_menu_item_layout; + global::Xamarin.Forms.Platform.Resource.Layout.abc_screen_content_include = global::xamarinFormApp.Droid.Resource.Layout.abc_screen_content_include; + global::Xamarin.Forms.Platform.Resource.Layout.abc_screen_simple = global::xamarinFormApp.Droid.Resource.Layout.abc_screen_simple; + global::Xamarin.Forms.Platform.Resource.Layout.abc_screen_simple_overlay_action_mode = global::xamarinFormApp.Droid.Resource.Layout.abc_screen_simple_overlay_action_mode; + global::Xamarin.Forms.Platform.Resource.Layout.abc_screen_toolbar = global::xamarinFormApp.Droid.Resource.Layout.abc_screen_toolbar; + global::Xamarin.Forms.Platform.Resource.Layout.abc_search_dropdown_item_icons_2line = global::xamarinFormApp.Droid.Resource.Layout.abc_search_dropdown_item_icons_2line; + global::Xamarin.Forms.Platform.Resource.Layout.abc_search_view = global::xamarinFormApp.Droid.Resource.Layout.abc_search_view; + global::Xamarin.Forms.Platform.Resource.Layout.abc_select_dialog_material = global::xamarinFormApp.Droid.Resource.Layout.abc_select_dialog_material; + global::Xamarin.Forms.Platform.Resource.Layout.abc_tooltip = global::xamarinFormApp.Droid.Resource.Layout.abc_tooltip; + global::Xamarin.Forms.Platform.Resource.Layout.BottomTabLayout = global::xamarinFormApp.Droid.Resource.Layout.BottomTabLayout; + global::Xamarin.Forms.Platform.Resource.Layout.design_bottom_navigation_item = global::xamarinFormApp.Droid.Resource.Layout.design_bottom_navigation_item; + global::Xamarin.Forms.Platform.Resource.Layout.design_bottom_sheet_dialog = global::xamarinFormApp.Droid.Resource.Layout.design_bottom_sheet_dialog; + global::Xamarin.Forms.Platform.Resource.Layout.design_layout_snackbar = global::xamarinFormApp.Droid.Resource.Layout.design_layout_snackbar; + global::Xamarin.Forms.Platform.Resource.Layout.design_layout_snackbar_include = global::xamarinFormApp.Droid.Resource.Layout.design_layout_snackbar_include; + global::Xamarin.Forms.Platform.Resource.Layout.design_layout_tab_icon = global::xamarinFormApp.Droid.Resource.Layout.design_layout_tab_icon; + global::Xamarin.Forms.Platform.Resource.Layout.design_layout_tab_text = global::xamarinFormApp.Droid.Resource.Layout.design_layout_tab_text; + global::Xamarin.Forms.Platform.Resource.Layout.design_menu_item_action_area = global::xamarinFormApp.Droid.Resource.Layout.design_menu_item_action_area; + global::Xamarin.Forms.Platform.Resource.Layout.design_navigation_item = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_item; + global::Xamarin.Forms.Platform.Resource.Layout.design_navigation_item_header = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_item_header; + global::Xamarin.Forms.Platform.Resource.Layout.design_navigation_item_separator = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_item_separator; + global::Xamarin.Forms.Platform.Resource.Layout.design_navigation_item_subheader = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_item_subheader; + global::Xamarin.Forms.Platform.Resource.Layout.design_navigation_menu = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_menu; + global::Xamarin.Forms.Platform.Resource.Layout.design_navigation_menu_item = global::xamarinFormApp.Droid.Resource.Layout.design_navigation_menu_item; + global::Xamarin.Forms.Platform.Resource.Layout.design_text_input_password_icon = global::xamarinFormApp.Droid.Resource.Layout.design_text_input_password_icon; + global::Xamarin.Forms.Platform.Resource.Layout.FlyoutContent = global::xamarinFormApp.Droid.Resource.Layout.FlyoutContent; + global::Xamarin.Forms.Platform.Resource.Layout.mtrl_layout_snackbar = global::xamarinFormApp.Droid.Resource.Layout.mtrl_layout_snackbar; + global::Xamarin.Forms.Platform.Resource.Layout.mtrl_layout_snackbar_include = global::xamarinFormApp.Droid.Resource.Layout.mtrl_layout_snackbar_include; + global::Xamarin.Forms.Platform.Resource.Layout.notification_action = global::xamarinFormApp.Droid.Resource.Layout.notification_action; + global::Xamarin.Forms.Platform.Resource.Layout.notification_action_tombstone = global::xamarinFormApp.Droid.Resource.Layout.notification_action_tombstone; + global::Xamarin.Forms.Platform.Resource.Layout.notification_media_action = global::xamarinFormApp.Droid.Resource.Layout.notification_media_action; + global::Xamarin.Forms.Platform.Resource.Layout.notification_media_cancel_action = global::xamarinFormApp.Droid.Resource.Layout.notification_media_cancel_action; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_big_media = global::xamarinFormApp.Droid.Resource.Layout.notification_template_big_media; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_big_media_custom = global::xamarinFormApp.Droid.Resource.Layout.notification_template_big_media_custom; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_big_media_narrow = global::xamarinFormApp.Droid.Resource.Layout.notification_template_big_media_narrow; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_big_media_narrow_custom = global::xamarinFormApp.Droid.Resource.Layout.notification_template_big_media_narrow_custom; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_custom_big = global::xamarinFormApp.Droid.Resource.Layout.notification_template_custom_big; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_icon_group = global::xamarinFormApp.Droid.Resource.Layout.notification_template_icon_group; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_lines_media = global::xamarinFormApp.Droid.Resource.Layout.notification_template_lines_media; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_media = global::xamarinFormApp.Droid.Resource.Layout.notification_template_media; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_media_custom = global::xamarinFormApp.Droid.Resource.Layout.notification_template_media_custom; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_part_chronometer = global::xamarinFormApp.Droid.Resource.Layout.notification_template_part_chronometer; + global::Xamarin.Forms.Platform.Resource.Layout.notification_template_part_time = global::xamarinFormApp.Droid.Resource.Layout.notification_template_part_time; + global::Xamarin.Forms.Platform.Resource.Layout.RootLayout = global::xamarinFormApp.Droid.Resource.Layout.RootLayout; + global::Xamarin.Forms.Platform.Resource.Layout.select_dialog_item_material = global::xamarinFormApp.Droid.Resource.Layout.select_dialog_item_material; + global::Xamarin.Forms.Platform.Resource.Layout.select_dialog_multichoice_material = global::xamarinFormApp.Droid.Resource.Layout.select_dialog_multichoice_material; + global::Xamarin.Forms.Platform.Resource.Layout.select_dialog_singlechoice_material = global::xamarinFormApp.Droid.Resource.Layout.select_dialog_singlechoice_material; + global::Xamarin.Forms.Platform.Resource.Layout.ShellContent = global::xamarinFormApp.Droid.Resource.Layout.ShellContent; + global::Xamarin.Forms.Platform.Resource.Layout.support_simple_spinner_dropdown_item = global::xamarinFormApp.Droid.Resource.Layout.support_simple_spinner_dropdown_item; + global::Xamarin.Forms.Platform.Resource.String.abc_action_bar_home_description = global::xamarinFormApp.Droid.Resource.String.abc_action_bar_home_description; + global::Xamarin.Forms.Platform.Resource.String.abc_action_bar_up_description = global::xamarinFormApp.Droid.Resource.String.abc_action_bar_up_description; + global::Xamarin.Forms.Platform.Resource.String.abc_action_menu_overflow_description = global::xamarinFormApp.Droid.Resource.String.abc_action_menu_overflow_description; + global::Xamarin.Forms.Platform.Resource.String.abc_action_mode_done = global::xamarinFormApp.Droid.Resource.String.abc_action_mode_done; + global::Xamarin.Forms.Platform.Resource.String.abc_activitychooserview_choose_application = global::xamarinFormApp.Droid.Resource.String.abc_activitychooserview_choose_application; + global::Xamarin.Forms.Platform.Resource.String.abc_activity_chooser_view_see_all = global::xamarinFormApp.Droid.Resource.String.abc_activity_chooser_view_see_all; + global::Xamarin.Forms.Platform.Resource.String.abc_capital_off = global::xamarinFormApp.Droid.Resource.String.abc_capital_off; + global::Xamarin.Forms.Platform.Resource.String.abc_capital_on = global::xamarinFormApp.Droid.Resource.String.abc_capital_on; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_body_1_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_body_1_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_body_2_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_body_2_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_button_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_button_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_caption_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_caption_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_display_1_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_display_1_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_display_2_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_display_2_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_display_3_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_display_3_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_display_4_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_display_4_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_headline_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_headline_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_menu_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_menu_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_subhead_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_subhead_material; + global::Xamarin.Forms.Platform.Resource.String.abc_font_family_title_material = global::xamarinFormApp.Droid.Resource.String.abc_font_family_title_material; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_alt_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_alt_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_ctrl_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_ctrl_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_delete_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_delete_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_enter_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_enter_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_function_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_function_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_meta_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_meta_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_shift_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_shift_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_space_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_space_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_menu_sym_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_menu_sym_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_prepend_shortcut_label = global::xamarinFormApp.Droid.Resource.String.abc_prepend_shortcut_label; + global::Xamarin.Forms.Platform.Resource.String.abc_searchview_description_clear = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_clear; + global::Xamarin.Forms.Platform.Resource.String.abc_searchview_description_query = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_query; + global::Xamarin.Forms.Platform.Resource.String.abc_searchview_description_search = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_search; + global::Xamarin.Forms.Platform.Resource.String.abc_searchview_description_submit = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_submit; + global::Xamarin.Forms.Platform.Resource.String.abc_searchview_description_voice = global::xamarinFormApp.Droid.Resource.String.abc_searchview_description_voice; + global::Xamarin.Forms.Platform.Resource.String.abc_search_hint = global::xamarinFormApp.Droid.Resource.String.abc_search_hint; + global::Xamarin.Forms.Platform.Resource.String.abc_shareactionprovider_share_with = global::xamarinFormApp.Droid.Resource.String.abc_shareactionprovider_share_with; + global::Xamarin.Forms.Platform.Resource.String.abc_shareactionprovider_share_with_application = global::xamarinFormApp.Droid.Resource.String.abc_shareactionprovider_share_with_application; + global::Xamarin.Forms.Platform.Resource.String.abc_toolbar_collapse_description = global::xamarinFormApp.Droid.Resource.String.abc_toolbar_collapse_description; + global::Xamarin.Forms.Platform.Resource.String.appbar_scrolling_view_behavior = global::xamarinFormApp.Droid.Resource.String.appbar_scrolling_view_behavior; + global::Xamarin.Forms.Platform.Resource.String.bottom_sheet_behavior = global::xamarinFormApp.Droid.Resource.String.bottom_sheet_behavior; + global::Xamarin.Forms.Platform.Resource.String.character_counter_content_description = global::xamarinFormApp.Droid.Resource.String.character_counter_content_description; + global::Xamarin.Forms.Platform.Resource.String.character_counter_pattern = global::xamarinFormApp.Droid.Resource.String.character_counter_pattern; + global::Xamarin.Forms.Platform.Resource.String.fab_transformation_scrim_behavior = global::xamarinFormApp.Droid.Resource.String.fab_transformation_scrim_behavior; + global::Xamarin.Forms.Platform.Resource.String.fab_transformation_sheet_behavior = global::xamarinFormApp.Droid.Resource.String.fab_transformation_sheet_behavior; + global::Xamarin.Forms.Platform.Resource.String.hide_bottom_view_on_scroll_behavior = global::xamarinFormApp.Droid.Resource.String.hide_bottom_view_on_scroll_behavior; + global::Xamarin.Forms.Platform.Resource.String.mtrl_chip_close_icon_content_description = global::xamarinFormApp.Droid.Resource.String.mtrl_chip_close_icon_content_description; + global::Xamarin.Forms.Platform.Resource.String.overflow_tab_title = global::xamarinFormApp.Droid.Resource.String.overflow_tab_title; + global::Xamarin.Forms.Platform.Resource.String.password_toggle_content_description = global::xamarinFormApp.Droid.Resource.String.password_toggle_content_description; + global::Xamarin.Forms.Platform.Resource.String.path_password_eye = global::xamarinFormApp.Droid.Resource.String.path_password_eye; + global::Xamarin.Forms.Platform.Resource.String.path_password_eye_mask_strike_through = global::xamarinFormApp.Droid.Resource.String.path_password_eye_mask_strike_through; + global::Xamarin.Forms.Platform.Resource.String.path_password_eye_mask_visible = global::xamarinFormApp.Droid.Resource.String.path_password_eye_mask_visible; + global::Xamarin.Forms.Platform.Resource.String.path_password_strike_through = global::xamarinFormApp.Droid.Resource.String.path_password_strike_through; + global::Xamarin.Forms.Platform.Resource.String.search_menu_title = global::xamarinFormApp.Droid.Resource.String.search_menu_title; + global::Xamarin.Forms.Platform.Resource.String.status_bar_notification_info_overflow = global::xamarinFormApp.Droid.Resource.String.status_bar_notification_info_overflow; + global::Xamarin.Forms.Platform.Resource.Style.AlertDialog_AppCompat = global::xamarinFormApp.Droid.Resource.Style.AlertDialog_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.AlertDialog_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.AlertDialog_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Animation_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Animation_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Animation_AppCompat_DropDownUp = global::xamarinFormApp.Droid.Resource.Style.Animation_AppCompat_DropDownUp; + global::Xamarin.Forms.Platform.Resource.Style.Animation_AppCompat_Tooltip = global::xamarinFormApp.Droid.Resource.Style.Animation_AppCompat_Tooltip; + global::Xamarin.Forms.Platform.Resource.Style.Animation_Design_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Animation_Design_BottomSheetDialog; + global::Xamarin.Forms.Platform.Resource.Style.AppCompatDialogStyle = global::xamarinFormApp.Droid.Resource.Style.AppCompatDialogStyle; + global::Xamarin.Forms.Platform.Resource.Style.Base_AlertDialog_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_AlertDialog_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_AlertDialog_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_AlertDialog_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_Animation_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Animation_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_Animation_AppCompat_DropDownUp = global::xamarinFormApp.Droid.Resource.Style.Base_Animation_AppCompat_DropDownUp; + global::Xamarin.Forms.Platform.Resource.Style.Base_Animation_AppCompat_Tooltip = global::xamarinFormApp.Droid.Resource.Style.Base_Animation_AppCompat_Tooltip; + global::Xamarin.Forms.Platform.Resource.Style.Base_CardView = global::xamarinFormApp.Droid.Resource.Style.Base_CardView; + global::Xamarin.Forms.Platform.Resource.Style.Base_DialogWindowTitleBackground_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_DialogWindowTitleBackground_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_DialogWindowTitle_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_DialogWindowTitle_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Body1 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Body1; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Body2 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Body2; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Button = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Button; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Caption = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Caption; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Display1 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Display1; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Display2 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Display2; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Display3 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Display3; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Display4 = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Display4; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Headline = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Headline; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Large = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Large; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Large_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Large_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Large = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Large; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Small = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Small; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Medium = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Medium; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Medium_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Medium_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Menu = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Menu; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_SearchResult = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_SearchResult; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_SearchResult_Subtitle = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_SearchResult_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_SearchResult_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_SearchResult_Title; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Small = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Small; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Small_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Small_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Subhead = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Subhead; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Subhead_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Subhead_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Title; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Title_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Tooltip = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Tooltip; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Menu = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Menu; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Title; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionMode_Subtitle = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionMode_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionMode_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_ActionMode_Title; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Borderless_Colored = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Borderless_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Colored = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Button_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_DropDownItem = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_DropDownItem; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Header = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Header; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Large = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Large; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Small = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_PopupMenu_Small; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_Switch = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_Switch; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_AppCompat_Widget_TextView_SpinnerItem = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_AppCompat_Widget_TextView_SpinnerItem; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_Widget_AppCompat_ExpandedMenu_Item = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_Widget_AppCompat_ExpandedMenu_Item; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_Widget_AppCompat_Toolbar_Subtitle = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_Widget_AppCompat_Toolbar_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.Base_TextAppearance_Widget_AppCompat_Toolbar_Title = global::xamarinFormApp.Droid.Resource.Style.Base_TextAppearance_Widget_AppCompat_Toolbar_Title; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_AppCompat_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_AppCompat_Dark = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Dark; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_AppCompat_Dark_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Dark_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_AppCompat_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_ThemeOverlay_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_ThemeOverlay_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_CompactMenu = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_CompactMenu; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Dialog_FixedSize = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Dialog_FixedSize; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Light_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_DarkActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Light_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Light_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Light_Dialog_FixedSize = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_Dialog_FixedSize; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_AppCompat_Light_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_AppCompat_Light_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_CompactMenu = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_CompactMenu; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Dialog_FixedSize = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Dialog_FixedSize; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_DarkActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light_DarkActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_DarkActionBar_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_FixedSize = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_FixedSize; + global::Xamarin.Forms.Platform.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Base_Theme_MaterialComponents_Light_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_ThemeOverlay_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V14_ThemeOverlay_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_ThemeOverlay_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Base_V14_ThemeOverlay_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_Theme_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_Theme_MaterialComponents_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_Theme_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_Theme_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_Theme_MaterialComponents_Light_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Light_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_Theme_MaterialComponents_Light_DarkActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Light_DarkActionBar_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Base_V14_Theme_MaterialComponents_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V14_Theme_MaterialComponents_Light_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V21_ThemeOverlay_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V21_ThemeOverlay_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V21_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V21_Theme_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_V21_Theme_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V21_Theme_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V21_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V21_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_V21_Theme_AppCompat_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V21_Theme_AppCompat_Light_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V22_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V22_Theme_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_V22_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V22_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_V23_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V23_Theme_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_V23_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V23_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_V26_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V26_Theme_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_V26_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V26_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_V26_Widget_AppCompat_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Base_V26_Widget_AppCompat_Toolbar; + global::Xamarin.Forms.Platform.Resource.Style.Base_V28_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V28_Theme_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_V28_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V28_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_V7_ThemeOverlay_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V7_ThemeOverlay_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V7_Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Theme_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Base_V7_Theme_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Theme_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V7_Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Base_V7_Theme_AppCompat_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Theme_AppCompat_Light_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_V7_Widget_AppCompat_AutoCompleteTextView = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Widget_AppCompat_AutoCompleteTextView; + global::Xamarin.Forms.Platform.Resource.Style.Base_V7_Widget_AppCompat_EditText = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Widget_AppCompat_EditText; + global::Xamarin.Forms.Platform.Resource.Style.Base_V7_Widget_AppCompat_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Base_V7_Widget_AppCompat_Toolbar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionBar_Solid = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar_Solid; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionBar_TabBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar_TabBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionBar_TabText = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar_TabText; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionBar_TabView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionBar_TabView; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionButton = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionButton; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionButton_CloseMode = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionButton_CloseMode; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionButton_Overflow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionButton_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActionMode = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActionMode; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ActivityChooserView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ActivityChooserView; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_AutoCompleteTextView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_AutoCompleteTextView; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Button = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ButtonBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ButtonBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ButtonBar_AlertDialog = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ButtonBar_AlertDialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Button_Borderless = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_Borderless; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Button_Borderless_Colored = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_Borderless_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Button_ButtonBar_AlertDialog = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_ButtonBar_AlertDialog; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Button_Colored = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Button_Small = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Button_Small; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_CompoundButton_CheckBox = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_CompoundButton_CheckBox; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_CompoundButton_RadioButton = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_CompoundButton_RadioButton; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_CompoundButton_Switch = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_CompoundButton_Switch; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_DrawerArrowToggle = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_DrawerArrowToggle; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_DrawerArrowToggle_Common = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_DrawerArrowToggle_Common; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_DropDownItem_Spinner = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_DropDownItem_Spinner; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_EditText = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_EditText; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ImageButton = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ImageButton; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Light_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_Solid = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_Solid; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabText = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabText; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabText_Inverse = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabText_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_ActionBar_TabView; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Light_PopupMenu = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_PopupMenu; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Light_PopupMenu_Overflow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Light_PopupMenu_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ListMenuView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListMenuView; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ListPopupWindow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListPopupWindow; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ListView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListView; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ListView_DropDown = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListView_DropDown; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ListView_Menu = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ListView_Menu; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_PopupMenu = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_PopupMenu; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_PopupMenu_Overflow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_PopupMenu_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_PopupWindow = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_PopupWindow; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ProgressBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ProgressBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_ProgressBar_Horizontal = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_ProgressBar_Horizontal; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_RatingBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_RatingBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_RatingBar_Indicator = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_RatingBar_Indicator; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_RatingBar_Small = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_RatingBar_Small; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_SearchView = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_SearchView; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_SearchView_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_SearchView_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_SeekBar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_SeekBar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_SeekBar_Discrete = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_SeekBar_Discrete; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Spinner = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Spinner; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Spinner_Underlined = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Spinner_Underlined; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_TextView_SpinnerItem = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_TextView_SpinnerItem; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Toolbar; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_AppCompat_Toolbar_Button_Navigation = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_AppCompat_Toolbar_Button_Navigation; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_Design_TabLayout = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_Design_TabLayout; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_MaterialComponents_Chip = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_MaterialComponents_Chip; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_MaterialComponents_TextInputEditText = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_MaterialComponents_TextInputEditText; + global::Xamarin.Forms.Platform.Resource.Style.Base_Widget_MaterialComponents_TextInputLayout = global::xamarinFormApp.Droid.Resource.Style.Base_Widget_MaterialComponents_TextInputLayout; + global::Xamarin.Forms.Platform.Resource.Style.CardView = global::xamarinFormApp.Droid.Resource.Style.CardView; + global::Xamarin.Forms.Platform.Resource.Style.CardView_Dark = global::xamarinFormApp.Droid.Resource.Style.CardView_Dark; + global::Xamarin.Forms.Platform.Resource.Style.CardView_Light = global::xamarinFormApp.Droid.Resource.Style.CardView_Light; + global::Xamarin.Forms.Platform.Resource.Style.collectionViewTheme = global::xamarinFormApp.Droid.Resource.Style.collectionViewTheme; + global::Xamarin.Forms.Platform.Resource.Style.MainTheme = global::xamarinFormApp.Droid.Resource.Style.MainTheme; + global::Xamarin.Forms.Platform.Resource.Style.MainTheme_Base = global::xamarinFormApp.Droid.Resource.Style.MainTheme_Base; + global::Xamarin.Forms.Platform.Resource.Style.Platform_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Platform_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Platform_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Platform_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.Platform_MaterialComponents; + global::Xamarin.Forms.Platform.Resource.Style.Platform_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Platform_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Platform_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Resource.Style.Platform_MaterialComponents_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Platform_MaterialComponents_Light_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Platform_ThemeOverlay_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Platform_ThemeOverlay_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Platform_ThemeOverlay_AppCompat_Dark = global::xamarinFormApp.Droid.Resource.Style.Platform_ThemeOverlay_AppCompat_Dark; + global::Xamarin.Forms.Platform.Resource.Style.Platform_ThemeOverlay_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_ThemeOverlay_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Platform_V21_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Platform_V21_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Platform_V21_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_V21_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Platform_V25_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Platform_V25_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Platform_V25_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Platform_V25_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Platform_Widget_AppCompat_Spinner = global::xamarinFormApp.Droid.Resource.Style.Platform_Widget_AppCompat_Spinner; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_DialogWindowTitle_AppCompat = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_DialogWindowTitle_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_ActionBar_TitleItem = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_ActionBar_TitleItem; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_DialogTitle_Icon = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_DialogTitle_Icon; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_InternalGroup = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_InternalGroup; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Shortcut = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Shortcut; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_SubmenuArrow = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_SubmenuArrow; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Text = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Text; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Title = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_PopupMenuItem_Title; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_SearchView_MagIcon = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_SearchView_MagIcon; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Icon1 = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Icon1; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Icon2 = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Icon2; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Query = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Query; + global::Xamarin.Forms.Platform.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Text = global::xamarinFormApp.Droid.Resource.Style.RtlOverlay_Widget_AppCompat_Search_DropDown_Text; + global::Xamarin.Forms.Platform.Resource.Style.RtlUnderlay_Widget_AppCompat_ActionButton = global::xamarinFormApp.Droid.Resource.Style.RtlUnderlay_Widget_AppCompat_ActionButton; + global::Xamarin.Forms.Platform.Resource.Style.RtlUnderlay_Widget_AppCompat_ActionButton_Overflow = global::xamarinFormApp.Droid.Resource.Style.RtlUnderlay_Widget_AppCompat_ActionButton_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.scrollViewScrollBars = global::xamarinFormApp.Droid.Resource.Style.scrollViewScrollBars; + global::Xamarin.Forms.Platform.Resource.Style.scrollViewTheme = global::xamarinFormApp.Droid.Resource.Style.scrollViewTheme; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Body1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Body1; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Body2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Body2; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Button = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Button; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Caption = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Caption; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Display1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Display1; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Display2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Display2; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Display3 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Display3; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Display4 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Display4; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Headline = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Headline; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Large = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Large; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Large_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Large_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Light_SearchResult_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Light_SearchResult_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Light_SearchResult_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Light_SearchResult_Title; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Light_Widget_PopupMenu_Large = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Light_Widget_PopupMenu_Large; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Light_Widget_PopupMenu_Small = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Light_Widget_PopupMenu_Small; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Medium = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Medium; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Medium_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Medium_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Menu = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Menu; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_SearchResult_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_SearchResult_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_SearchResult_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_SearchResult_Title; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Small = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Small; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Small_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Small_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Subhead = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Subhead; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Subhead_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Subhead_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Title; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Title_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Tooltip = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Tooltip; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Menu = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Menu; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Title; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Subtitle_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Subtitle_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Title; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Title_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_ActionMode_Title_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_Button = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Button; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_Button_Borderless_Colored = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Button_Borderless_Colored; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_Button_Colored = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Button_Colored; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_Button_Inverse = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Button_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_DropDownItem = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_DropDownItem; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Header = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Header; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Large = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Large; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Small = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_PopupMenu_Small; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_Switch = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_Switch; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_AppCompat_Widget_TextView_SpinnerItem = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_AppCompat_Widget_TextView_SpinnerItem; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Info = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Info; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Info_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Info_Media; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Line2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Line2; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Line2_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Line2_Media; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Media; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Time = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Time; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Time_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Time_Media; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Title; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Compat_Notification_Title_Media = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Compat_Notification_Title_Media; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Design_CollapsingToolbar_Expanded = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_CollapsingToolbar_Expanded; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Design_Counter = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Counter; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Design_Counter_Overflow = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Counter_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Design_Error = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Error; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Design_HelperText = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_HelperText; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Design_Hint = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Hint; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Design_Snackbar_Message = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Snackbar_Message; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Design_Tab = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Design_Tab; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Body1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Body1; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Body2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Body2; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Button = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Button; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Caption = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Caption; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Chip = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Chip; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Headline1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline1; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Headline2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline2; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Headline3 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline3; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Headline4 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline4; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Headline5 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline5; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Headline6 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Headline6; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Overline = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Overline; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Subtitle1 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Subtitle1; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Subtitle2 = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Subtitle2; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_MaterialComponents_Tab = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_MaterialComponents_Tab; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Widget_AppCompat_ExpandedMenu_Item = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Widget_AppCompat_ExpandedMenu_Item; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Widget_AppCompat_Toolbar_Subtitle = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Widget_AppCompat_Toolbar_Subtitle; + global::Xamarin.Forms.Platform.Resource.Style.TextAppearance_Widget_AppCompat_Toolbar_Title = global::xamarinFormApp.Droid.Resource.Style.TextAppearance_Widget_AppCompat_Toolbar_Title; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_AppCompat = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_AppCompat_ActionBar = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_AppCompat_Dark = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Dark; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_AppCompat_Dark_ActionBar = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Dark_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_AppCompat_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_ActionBar = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_Dark = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Dark; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_Dark_ActionBar = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Dark_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox_Dense = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox_Dense; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox; + global::Xamarin.Forms.Platform.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox_Dense = global::xamarinFormApp.Droid.Resource.Style.ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox_Dense; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_CompactMenu = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_CompactMenu; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_DayNight = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_DayNight_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_DarkActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_DayNight_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_DayNight_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_DayNight_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_DayNight_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_DayNight_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DayNight_NoActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Light = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Light_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_DarkActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Light_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Light_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Light_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_Light_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_Light_NoActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_AppCompat_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_AppCompat_NoActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_Design = global::xamarinFormApp.Droid.Resource.Style.Theme_Design; + global::Xamarin.Forms.Platform.Resource.Style.Theme_Design_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_BottomSheetDialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_Design_Light = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_Light; + global::Xamarin.Forms.Platform.Resource.Style.Theme_Design_Light_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_Light_BottomSheetDialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_Design_Light_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_Light_NoActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_Design_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_Design_NoActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_BottomSheetDialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_CompactMenu = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_CompactMenu; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_BottomSheetDialog = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_BottomSheetDialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_DarkActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_DarkActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_DarkActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_DarkActionBar_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_Dialog = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_DialogWhenLarge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_DialogWhenLarge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_Dialog_Alert = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_Dialog_Alert; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_Dialog_MinWidth = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_Dialog_MinWidth; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_NoActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_Light_NoActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_Light_NoActionBar_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_NoActionBar = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_NoActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Theme_MaterialComponents_NoActionBar_Bridge = global::xamarinFormApp.Droid.Resource.Style.Theme_MaterialComponents_NoActionBar_Bridge; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionBar_Solid = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar_Solid; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionBar_TabBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar_TabBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionBar_TabText = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar_TabText; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionBar_TabView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionBar_TabView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionButton = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionButton_CloseMode = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionButton_CloseMode; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionButton_Overflow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionButton_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActionMode = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActionMode; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ActivityChooserView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ActivityChooserView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_AutoCompleteTextView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_AutoCompleteTextView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Button = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ButtonBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ButtonBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ButtonBar_AlertDialog = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ButtonBar_AlertDialog; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Button_Borderless = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_Borderless; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Button_Borderless_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_Borderless_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Button_ButtonBar_AlertDialog = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_ButtonBar_AlertDialog; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Button_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Button_Small = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Button_Small; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_CompoundButton_CheckBox = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_CompoundButton_CheckBox; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_CompoundButton_RadioButton = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_CompoundButton_RadioButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_CompoundButton_Switch = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_CompoundButton_Switch; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_DrawerArrowToggle = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_DrawerArrowToggle; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_DropDownItem_Spinner = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_DropDownItem_Spinner; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_EditText = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_EditText; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ImageButton = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ImageButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar_Solid = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_Solid; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar_Solid_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_Solid_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar_TabBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar_TabBar_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabBar_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar_TabText = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabText; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar_TabText_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabText_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar_TabView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionBar_TabView_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionBar_TabView_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionButton = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionButton_CloseMode = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionButton_CloseMode; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionButton_Overflow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionButton_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActionMode_Inverse = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActionMode_Inverse; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ActivityChooserView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ActivityChooserView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_AutoCompleteTextView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_AutoCompleteTextView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_DropDownItem_Spinner = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_DropDownItem_Spinner; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ListPopupWindow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ListPopupWindow; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_ListView_DropDown = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_ListView_DropDown; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_PopupMenu = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_PopupMenu; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_PopupMenu_Overflow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_PopupMenu_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_SearchView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_SearchView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Light_Spinner_DropDown_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Light_Spinner_DropDown_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ListMenuView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListMenuView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ListPopupWindow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListPopupWindow; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ListView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ListView_DropDown = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListView_DropDown; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ListView_Menu = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ListView_Menu; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_PopupMenu = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_PopupMenu; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_PopupMenu_Overflow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_PopupMenu_Overflow; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_PopupWindow = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_PopupWindow; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ProgressBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ProgressBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_ProgressBar_Horizontal = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_ProgressBar_Horizontal; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_RatingBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_RatingBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_RatingBar_Indicator = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_RatingBar_Indicator; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_RatingBar_Small = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_RatingBar_Small; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_SearchView = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_SearchView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_SearchView_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_SearchView_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_SeekBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_SeekBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_SeekBar_Discrete = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_SeekBar_Discrete; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Spinner = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Spinner; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Spinner_DropDown = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Spinner_DropDown; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Spinner_DropDown_ActionBar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Spinner_DropDown_ActionBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Spinner_Underlined = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Spinner_Underlined; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_TextView_SpinnerItem = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_TextView_SpinnerItem; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Toolbar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_AppCompat_Toolbar_Button_Navigation = global::xamarinFormApp.Droid.Resource.Style.Widget_AppCompat_Toolbar_Button_Navigation; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Compat_NotificationActionContainer = global::xamarinFormApp.Droid.Resource.Style.Widget_Compat_NotificationActionContainer; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Compat_NotificationActionText = global::xamarinFormApp.Droid.Resource.Style.Widget_Compat_NotificationActionText; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_AppBarLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_AppBarLayout; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_BottomNavigationView = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_BottomNavigationView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_BottomSheet_Modal = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_BottomSheet_Modal; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_CollapsingToolbar = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_CollapsingToolbar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_FloatingActionButton = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_FloatingActionButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_NavigationView = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_NavigationView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_ScrimInsetsFrameLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_ScrimInsetsFrameLayout; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_Snackbar = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_Snackbar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_TabLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_TabLayout; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Design_TextInputLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Design_TextInputLayout; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_BottomAppBar = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomAppBar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_BottomAppBar_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomAppBar_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_BottomNavigationView = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomNavigationView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_BottomNavigationView_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomNavigationView_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_BottomSheet_Modal = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_BottomSheet_Modal; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_Icon; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_OutlinedButton = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_OutlinedButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_OutlinedButton_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_OutlinedButton_Icon; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_TextButton = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_TextButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_TextButton_Dialog = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_TextButton_Dialog; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_TextButton_Dialog_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_TextButton_Dialog_Icon; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_TextButton_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_TextButton_Icon; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_UnelevatedButton = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_UnelevatedButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Button_UnelevatedButton_Icon = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Button_UnelevatedButton_Icon; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_CardView = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_CardView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_ChipGroup = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_ChipGroup; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Chip_Action = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Chip_Action; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Chip_Choice = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Chip_Choice; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Chip_Entry = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Chip_Entry; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Chip_Filter = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Chip_Filter; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_FloatingActionButton = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_FloatingActionButton; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_NavigationView = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_NavigationView; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Snackbar = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Snackbar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Snackbar_FullWidth = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Snackbar_FullWidth; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TabLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TabLayout; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TabLayout_Colored = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TabLayout_Colored; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TextInputEditText_FilledBox = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputEditText_FilledBox; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TextInputEditText_FilledBox_Dense = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputEditText_FilledBox_Dense; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TextInputEditText_OutlinedBox = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputEditText_OutlinedBox; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TextInputEditText_OutlinedBox_Dense = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputEditText_OutlinedBox_Dense; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TextInputLayout_FilledBox = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputLayout_FilledBox; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TextInputLayout_FilledBox_Dense = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputLayout_FilledBox_Dense; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TextInputLayout_OutlinedBox = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputLayout_OutlinedBox; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_TextInputLayout_OutlinedBox_Dense = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_TextInputLayout_OutlinedBox_Dense; + global::Xamarin.Forms.Platform.Resource.Style.Widget_MaterialComponents_Toolbar = global::xamarinFormApp.Droid.Resource.Style.Widget_MaterialComponents_Toolbar; + global::Xamarin.Forms.Platform.Resource.Style.Widget_Support_CoordinatorLayout = global::xamarinFormApp.Droid.Resource.Style.Widget_Support_CoordinatorLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBarLayout = global::xamarinFormApp.Droid.Resource.Styleable.ActionBarLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBarLayout_android_layout_gravity = global::xamarinFormApp.Droid.Resource.Styleable.ActionBarLayout_android_layout_gravity; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_background = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_background; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_backgroundSplit = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_backgroundSplit; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_backgroundStacked = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_backgroundStacked; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_contentInsetEnd = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_contentInsetEndWithActions = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetEndWithActions; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_contentInsetLeft = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetLeft; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_contentInsetRight = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetRight; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_contentInsetStart = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetStart; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_contentInsetStartWithNavigation = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_contentInsetStartWithNavigation; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_customNavigationLayout = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_customNavigationLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_displayOptions = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_displayOptions; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_divider = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_divider; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_elevation = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_elevation; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_height = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_height; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_hideOnContentScroll = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_hideOnContentScroll; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_homeAsUpIndicator = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_homeAsUpIndicator; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_homeLayout = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_homeLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_icon = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_icon; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_indeterminateProgressStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_indeterminateProgressStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_itemPadding = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_itemPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_logo = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_logo; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_navigationMode = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_navigationMode; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_popupTheme = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_popupTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_progressBarPadding = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_progressBarPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_progressBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_progressBarStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_subtitle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_subtitle; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_subtitleTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_subtitleTextStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_title = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_title; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionBar_titleTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionBar_titleTextStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMenuItemView = global::xamarinFormApp.Droid.Resource.Styleable.ActionMenuItemView; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMenuItemView_android_minWidth = global::xamarinFormApp.Droid.Resource.Styleable.ActionMenuItemView_android_minWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMenuView = global::xamarinFormApp.Droid.Resource.Styleable.ActionMenuView; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMode = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMode_background = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_background; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMode_backgroundSplit = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_backgroundSplit; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMode_closeItemLayout = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_closeItemLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMode_height = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_height; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMode_subtitleTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_subtitleTextStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.ActionMode_titleTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.ActionMode_titleTextStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.ActivityChooserView = global::xamarinFormApp.Droid.Resource.Styleable.ActivityChooserView; + global::Xamarin.Forms.Platform.Resource.Styleable.ActivityChooserView_expandActivityOverflowButtonDrawable = global::xamarinFormApp.Droid.Resource.Styleable.ActivityChooserView_expandActivityOverflowButtonDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.ActivityChooserView_initialActivityCount = global::xamarinFormApp.Droid.Resource.Styleable.ActivityChooserView_initialActivityCount; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog_android_layout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_android_layout; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog_buttonIconDimen = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_buttonIconDimen; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog_buttonPanelSideLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_buttonPanelSideLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog_listItemLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_listItemLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog_listLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_listLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog_multiChoiceItemLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_multiChoiceItemLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog_showTitle = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_showTitle; + global::Xamarin.Forms.Platform.Resource.Styleable.AlertDialog_singleChoiceItemLayout = global::xamarinFormApp.Droid.Resource.Styleable.AlertDialog_singleChoiceItemLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableCompat = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableCompat_android_constantSize = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_constantSize; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableCompat_android_dither = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_dither; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableCompat_android_enterFadeDuration = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_enterFadeDuration; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableCompat_android_exitFadeDuration = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_exitFadeDuration; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableCompat_android_variablePadding = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_variablePadding; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableCompat_android_visible = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableCompat_android_visible; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableItem = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableItem; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableItem_android_drawable = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableItem_android_drawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableItem_android_id = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableItem_android_id; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableTransition = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableTransition_android_drawable = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition_android_drawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableTransition_android_fromId = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition_android_fromId; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableTransition_android_reversible = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition_android_reversible; + global::Xamarin.Forms.Platform.Resource.Styleable.AnimatedStateListDrawableTransition_android_toId = global::xamarinFormApp.Droid.Resource.Styleable.AnimatedStateListDrawableTransition_android_toId; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayoutStates = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayoutStates_state_collapsed = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates_state_collapsed; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayoutStates_state_collapsible = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates_state_collapsible; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayoutStates_state_liftable = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates_state_liftable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayoutStates_state_lifted = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayoutStates_state_lifted; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_android_background = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_android_background; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_android_keyboardNavigationCluster = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_android_keyboardNavigationCluster; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_android_touchscreenBlocksFocus = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_android_touchscreenBlocksFocus; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_elevation = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_elevation; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_expanded = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_expanded; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_Layout = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_Layout; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_Layout_layout_scrollFlags = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_Layout_layout_scrollFlags; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_Layout_layout_scrollInterpolator = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_Layout_layout_scrollInterpolator; + global::Xamarin.Forms.Platform.Resource.Styleable.AppBarLayout_liftOnScroll = global::xamarinFormApp.Droid.Resource.Styleable.AppBarLayout_liftOnScroll; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatImageView = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatImageView_android_src = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView_android_src; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatImageView_srcCompat = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView_srcCompat; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatImageView_tint = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView_tint; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatImageView_tintMode = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatImageView_tintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatSeekBar = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatSeekBar_android_thumb = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar_android_thumb; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatSeekBar_tickMark = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar_tickMark; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatSeekBar_tickMarkTint = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar_tickMarkTint; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatSeekBar_tickMarkTintMode = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatSeekBar_tickMarkTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextHelper = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextHelper_android_drawableBottom = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableBottom; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextHelper_android_drawableEnd = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextHelper_android_drawableLeft = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableLeft; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextHelper_android_drawableRight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableRight; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextHelper_android_drawableStart = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableStart; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextHelper_android_drawableTop = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_drawableTop; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextHelper_android_textAppearance = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextHelper_android_textAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_android_textAppearance = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_android_textAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_autoSizeMaxTextSize = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizeMaxTextSize; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_autoSizeMinTextSize = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizeMinTextSize; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_autoSizePresetSizes = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizePresetSizes; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_autoSizeStepGranularity = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizeStepGranularity; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_autoSizeTextType = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_autoSizeTextType; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_firstBaselineToTopHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_firstBaselineToTopHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_fontFamily = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_fontFamily; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_lastBaselineToBottomHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_lastBaselineToBottomHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_lineHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_lineHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTextView_textAllCaps = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTextView_textAllCaps; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarDivider = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarDivider; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarItemBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarItemBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarPopupTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarPopupTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarSize = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarSize; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarSplitStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarSplitStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarTabBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarTabBarStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarTabStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarTabStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarTabTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarTabTextStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionBarWidgetTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionBarWidgetTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionDropDownStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionDropDownStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionMenuTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionMenuTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionMenuTextColor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionMenuTextColor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeCloseButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeCloseButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeCloseDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeCloseDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeCopyDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeCopyDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeCutDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeCutDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeFindDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeFindDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModePasteDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModePasteDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModePopupWindowStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModePopupWindowStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeSelectAllDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeSelectAllDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeShareDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeShareDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeSplitBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeSplitBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionModeWebSearchDrawable = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionModeWebSearchDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionOverflowButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionOverflowButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_actionOverflowMenuStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_actionOverflowMenuStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_activityChooserViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_activityChooserViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_alertDialogButtonGroupStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_alertDialogButtonGroupStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_alertDialogCenterButtons = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_alertDialogCenterButtons; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_alertDialogStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_alertDialogStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_alertDialogTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_alertDialogTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_android_windowAnimationStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_android_windowAnimationStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_android_windowIsFloating = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_android_windowIsFloating; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_autoCompleteTextViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_autoCompleteTextViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_borderlessButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_borderlessButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_buttonBarButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_buttonBarNegativeButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarNegativeButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_buttonBarNeutralButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarNeutralButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_buttonBarPositiveButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarPositiveButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_buttonBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonBarStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_buttonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_buttonStyleSmall = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_buttonStyleSmall; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_checkboxStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_checkboxStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_checkedTextViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_checkedTextViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorAccent = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorAccent; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorBackgroundFloating = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorBackgroundFloating; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorButtonNormal = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorButtonNormal; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorControlActivated = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorControlActivated; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorControlHighlight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorControlHighlight; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorControlNormal = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorControlNormal; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorError = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorError; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorPrimary = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorPrimary; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorPrimaryDark = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorPrimaryDark; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_colorSwitchThumbNormal = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_colorSwitchThumbNormal; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_controlBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_controlBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_dialogCornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dialogCornerRadius; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_dialogPreferredPadding = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dialogPreferredPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_dialogTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dialogTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_dividerHorizontal = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dividerHorizontal; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_dividerVertical = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dividerVertical; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_dropdownListPreferredItemHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dropdownListPreferredItemHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_dropDownListViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_dropDownListViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_editTextBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_editTextBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_editTextColor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_editTextColor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_editTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_editTextStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_homeAsUpIndicator = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_homeAsUpIndicator; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_imageButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_imageButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listChoiceBackgroundIndicator = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listChoiceBackgroundIndicator; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listDividerAlertDialog = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listDividerAlertDialog; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listMenuViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listMenuViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listPopupWindowStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPopupWindowStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listPreferredItemHeight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listPreferredItemHeightLarge = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemHeightLarge; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listPreferredItemHeightSmall = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemHeightSmall; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listPreferredItemPaddingLeft = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemPaddingLeft; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_listPreferredItemPaddingRight = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_listPreferredItemPaddingRight; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_panelBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_panelBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_panelMenuListTheme = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_panelMenuListTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_panelMenuListWidth = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_panelMenuListWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_popupMenuStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_popupMenuStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_popupWindowStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_popupWindowStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_radioButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_radioButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_ratingBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_ratingBarStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_ratingBarStyleIndicator = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_ratingBarStyleIndicator; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_ratingBarStyleSmall = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_ratingBarStyleSmall; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_searchViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_searchViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_seekBarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_seekBarStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_selectableItemBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_selectableItemBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_selectableItemBackgroundBorderless = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_selectableItemBackgroundBorderless; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_spinnerDropDownItemStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_spinnerDropDownItemStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_spinnerStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_spinnerStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_switchStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_switchStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textAppearanceLargePopupMenu = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceLargePopupMenu; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textAppearanceListItem = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceListItem; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textAppearanceListItemSecondary = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceListItemSecondary; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textAppearanceListItemSmall = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceListItemSmall; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textAppearancePopupMenuHeader = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearancePopupMenuHeader; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textAppearanceSearchResultSubtitle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceSearchResultSubtitle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textAppearanceSearchResultTitle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceSearchResultTitle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textAppearanceSmallPopupMenu = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textAppearanceSmallPopupMenu; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textColorAlertDialogListItem = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textColorAlertDialogListItem; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_textColorSearchUrl = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_textColorSearchUrl; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_toolbarNavigationButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_toolbarNavigationButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_toolbarStyle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_toolbarStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_tooltipForegroundColor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_tooltipForegroundColor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_tooltipFrameBackground = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_tooltipFrameBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_viewInflaterClass = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_viewInflaterClass; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowActionBar = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowActionBar; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowActionBarOverlay = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowActionBarOverlay; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowActionModeOverlay = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowActionModeOverlay; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowFixedHeightMajor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowFixedHeightMajor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowFixedHeightMinor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowFixedHeightMinor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowFixedWidthMajor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowFixedWidthMajor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowFixedWidthMinor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowFixedWidthMinor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowMinWidthMajor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowMinWidthMajor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowMinWidthMinor = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowMinWidthMinor; + global::Xamarin.Forms.Platform.Resource.Styleable.AppCompatTheme_windowNoTitle = global::xamarinFormApp.Droid.Resource.Styleable.AppCompatTheme_windowNoTitle; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomAppBar = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomAppBar_backgroundTint = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_backgroundTint; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomAppBar_fabAlignmentMode = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_fabAlignmentMode; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomAppBar_fabCradleMargin = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_fabCradleMargin; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomAppBar_fabCradleRoundedCornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_fabCradleRoundedCornerRadius; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomAppBar_fabCradleVerticalOffset = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_fabCradleVerticalOffset; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomAppBar_hideOnScroll = global::xamarinFormApp.Droid.Resource.Styleable.BottomAppBar_hideOnScroll; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_elevation = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_elevation; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_itemBackground = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_itemHorizontalTranslationEnabled = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemHorizontalTranslationEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_itemIconSize = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemIconSize; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_itemIconTint = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemIconTint; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_itemTextAppearanceActive = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemTextAppearanceActive; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_itemTextAppearanceInactive = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemTextAppearanceInactive; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_itemTextColor = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_itemTextColor; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_labelVisibilityMode = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_labelVisibilityMode; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomNavigationView_menu = global::xamarinFormApp.Droid.Resource.Styleable.BottomNavigationView_menu; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomSheetBehavior_Layout = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomSheetBehavior_Layout_behavior_fitToContents = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout_behavior_fitToContents; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomSheetBehavior_Layout_behavior_hideable = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout_behavior_hideable; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomSheetBehavior_Layout_behavior_peekHeight = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout_behavior_peekHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.BottomSheetBehavior_Layout_behavior_skipCollapsed = global::xamarinFormApp.Droid.Resource.Styleable.BottomSheetBehavior_Layout_behavior_skipCollapsed; + global::Xamarin.Forms.Platform.Resource.Styleable.ButtonBarLayout = global::xamarinFormApp.Droid.Resource.Styleable.ButtonBarLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.ButtonBarLayout_allowStacking = global::xamarinFormApp.Droid.Resource.Styleable.ButtonBarLayout_allowStacking; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView = global::xamarinFormApp.Droid.Resource.Styleable.CardView; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_android_minHeight = global::xamarinFormApp.Droid.Resource.Styleable.CardView_android_minHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_android_minWidth = global::xamarinFormApp.Droid.Resource.Styleable.CardView_android_minWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_cardBackgroundColor = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardBackgroundColor; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_cardCornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardCornerRadius; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_cardElevation = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardElevation; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_cardMaxElevation = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardMaxElevation; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_cardPreventCornerOverlap = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardPreventCornerOverlap; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_cardUseCompatPadding = global::xamarinFormApp.Droid.Resource.Styleable.CardView_cardUseCompatPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_contentPadding = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_contentPaddingBottom = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPaddingBottom; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_contentPaddingLeft = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPaddingLeft; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_contentPaddingRight = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPaddingRight; + global::Xamarin.Forms.Platform.Resource.Styleable.CardView_contentPaddingTop = global::xamarinFormApp.Droid.Resource.Styleable.CardView_contentPaddingTop; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip = global::xamarinFormApp.Droid.Resource.Styleable.Chip; + global::Xamarin.Forms.Platform.Resource.Styleable.ChipGroup = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup; + global::Xamarin.Forms.Platform.Resource.Styleable.ChipGroup_checkedChip = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_checkedChip; + global::Xamarin.Forms.Platform.Resource.Styleable.ChipGroup_chipSpacing = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_chipSpacing; + global::Xamarin.Forms.Platform.Resource.Styleable.ChipGroup_chipSpacingHorizontal = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_chipSpacingHorizontal; + global::Xamarin.Forms.Platform.Resource.Styleable.ChipGroup_chipSpacingVertical = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_chipSpacingVertical; + global::Xamarin.Forms.Platform.Resource.Styleable.ChipGroup_singleLine = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_singleLine; + global::Xamarin.Forms.Platform.Resource.Styleable.ChipGroup_singleSelection = global::xamarinFormApp.Droid.Resource.Styleable.ChipGroup_singleSelection; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_android_checkable = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_checkable; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_android_ellipsize = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_ellipsize; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_android_maxWidth = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_maxWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_android_text = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_text; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_android_textAppearance = global::xamarinFormApp.Droid.Resource.Styleable.Chip_android_textAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_checkedIcon = global::xamarinFormApp.Droid.Resource.Styleable.Chip_checkedIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_checkedIconEnabled = global::xamarinFormApp.Droid.Resource.Styleable.Chip_checkedIconEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_checkedIconVisible = global::xamarinFormApp.Droid.Resource.Styleable.Chip_checkedIconVisible; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipBackgroundColor = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipBackgroundColor; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipCornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipCornerRadius; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipEndPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipEndPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipIcon = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipIconEnabled = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIconEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipIconSize = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIconSize; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipIconTint = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIconTint; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipIconVisible = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipIconVisible; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipMinHeight = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipMinHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipStartPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipStartPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipStrokeColor = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipStrokeColor; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_chipStrokeWidth = global::xamarinFormApp.Droid.Resource.Styleable.Chip_chipStrokeWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_closeIcon = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_closeIconEnabled = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_closeIconEndPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconEndPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_closeIconSize = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconSize; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_closeIconStartPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconStartPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_closeIconTint = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconTint; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_closeIconVisible = global::xamarinFormApp.Droid.Resource.Styleable.Chip_closeIconVisible; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_hideMotionSpec = global::xamarinFormApp.Droid.Resource.Styleable.Chip_hideMotionSpec; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_iconEndPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_iconEndPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_iconStartPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_iconStartPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_rippleColor = global::xamarinFormApp.Droid.Resource.Styleable.Chip_rippleColor; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_showMotionSpec = global::xamarinFormApp.Droid.Resource.Styleable.Chip_showMotionSpec; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_textEndPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_textEndPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.Chip_textStartPadding = global::xamarinFormApp.Droid.Resource.Styleable.Chip_textStartPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_collapsedTitleGravity = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_collapsedTitleGravity; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_collapsedTitleTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_collapsedTitleTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_contentScrim = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_contentScrim; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_expandedTitleGravity = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleGravity; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMargin = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMargin; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginBottom = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginBottom; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginEnd = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginStart = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginStart; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginTop = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleMarginTop; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_expandedTitleTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_expandedTitleTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_Layout = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_Layout; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_Layout_layout_collapseMode = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_Layout_layout_collapseMode; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_Layout_layout_collapseParallaxMultiplier = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_Layout_layout_collapseParallaxMultiplier; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_scrimAnimationDuration = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_scrimAnimationDuration; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_scrimVisibleHeightTrigger = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_scrimVisibleHeightTrigger; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_statusBarScrim = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_statusBarScrim; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_title = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_title; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_titleEnabled = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_titleEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.CollapsingToolbarLayout_toolbarId = global::xamarinFormApp.Droid.Resource.Styleable.CollapsingToolbarLayout_toolbarId; + global::Xamarin.Forms.Platform.Resource.Styleable.ColorStateListItem = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem; + global::Xamarin.Forms.Platform.Resource.Styleable.ColorStateListItem_alpha = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_alpha; + global::Xamarin.Forms.Platform.Resource.Styleable.ColorStateListItem_android_alpha = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_android_alpha; + global::Xamarin.Forms.Platform.Resource.Styleable.ColorStateListItem_android_color = global::xamarinFormApp.Droid.Resource.Styleable.ColorStateListItem_android_color; + global::Xamarin.Forms.Platform.Resource.Styleable.CompoundButton = global::xamarinFormApp.Droid.Resource.Styleable.CompoundButton; + global::Xamarin.Forms.Platform.Resource.Styleable.CompoundButton_android_button = global::xamarinFormApp.Droid.Resource.Styleable.CompoundButton_android_button; + global::Xamarin.Forms.Platform.Resource.Styleable.CompoundButton_buttonTint = global::xamarinFormApp.Droid.Resource.Styleable.CompoundButton_buttonTint; + global::Xamarin.Forms.Platform.Resource.Styleable.CompoundButton_buttonTintMode = global::xamarinFormApp.Droid.Resource.Styleable.CompoundButton_buttonTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_keylines = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_keylines; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_Layout = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_Layout_android_layout_gravity = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_android_layout_gravity; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_Layout_layout_anchor = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_anchor; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_Layout_layout_anchorGravity = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_anchorGravity; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_Layout_layout_behavior = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_behavior; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_Layout_layout_dodgeInsetEdges = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_dodgeInsetEdges; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_Layout_layout_insetEdge = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_insetEdge; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_Layout_layout_keyline = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_Layout_layout_keyline; + global::Xamarin.Forms.Platform.Resource.Styleable.CoordinatorLayout_statusBarBackground = global::xamarinFormApp.Droid.Resource.Styleable.CoordinatorLayout_statusBarBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.DesignTheme = global::xamarinFormApp.Droid.Resource.Styleable.DesignTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.DesignTheme_bottomSheetDialogTheme = global::xamarinFormApp.Droid.Resource.Styleable.DesignTheme_bottomSheetDialogTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.DesignTheme_bottomSheetStyle = global::xamarinFormApp.Droid.Resource.Styleable.DesignTheme_bottomSheetStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle_arrowHeadLength = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_arrowHeadLength; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle_arrowShaftLength = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_arrowShaftLength; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle_barLength = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_barLength; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle_color = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_color; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle_drawableSize = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_drawableSize; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle_gapBetweenBars = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_gapBetweenBars; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle_spinBars = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_spinBars; + global::Xamarin.Forms.Platform.Resource.Styleable.DrawerArrowToggle_thickness = global::xamarinFormApp.Droid.Resource.Styleable.DrawerArrowToggle_thickness; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_backgroundTint = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_backgroundTint; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_backgroundTintMode = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_backgroundTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_Behavior_Layout = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_Behavior_Layout; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_Behavior_Layout_behavior_autoHide = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_Behavior_Layout_behavior_autoHide; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_borderWidth = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_borderWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_elevation = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_elevation; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_fabCustomSize = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_fabCustomSize; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_fabSize = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_fabSize; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_hideMotionSpec = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_hideMotionSpec; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_hoveredFocusedTranslationZ = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_hoveredFocusedTranslationZ; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_maxImageSize = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_maxImageSize; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_pressedTranslationZ = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_pressedTranslationZ; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_rippleColor = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_rippleColor; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_showMotionSpec = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_showMotionSpec; + global::Xamarin.Forms.Platform.Resource.Styleable.FloatingActionButton_useCompatPadding = global::xamarinFormApp.Droid.Resource.Styleable.FloatingActionButton_useCompatPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.FlowLayout = global::xamarinFormApp.Droid.Resource.Styleable.FlowLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.FlowLayout_itemSpacing = global::xamarinFormApp.Droid.Resource.Styleable.FlowLayout_itemSpacing; + global::Xamarin.Forms.Platform.Resource.Styleable.FlowLayout_lineSpacing = global::xamarinFormApp.Droid.Resource.Styleable.FlowLayout_lineSpacing; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamily = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_android_font = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_font; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_android_fontStyle = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_android_fontVariationSettings = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontVariationSettings; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_android_fontWeight = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_fontWeight; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_android_ttcIndex = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_android_ttcIndex; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_font = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_font; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_fontStyle = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_fontVariationSettings = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontVariationSettings; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_fontWeight = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_fontWeight; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamilyFont_ttcIndex = global::xamarinFormApp.Droid.Resource.Styleable.FontFamilyFont_ttcIndex; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamily_fontProviderAuthority = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderAuthority; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamily_fontProviderCerts = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderCerts; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamily_fontProviderFetchStrategy = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderFetchStrategy; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamily_fontProviderFetchTimeout = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderFetchTimeout; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamily_fontProviderPackage = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderPackage; + global::Xamarin.Forms.Platform.Resource.Styleable.FontFamily_fontProviderQuery = global::xamarinFormApp.Droid.Resource.Styleable.FontFamily_fontProviderQuery; + global::Xamarin.Forms.Platform.Resource.Styleable.ForegroundLinearLayout = global::xamarinFormApp.Droid.Resource.Styleable.ForegroundLinearLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.ForegroundLinearLayout_android_foreground = global::xamarinFormApp.Droid.Resource.Styleable.ForegroundLinearLayout_android_foreground; + global::Xamarin.Forms.Platform.Resource.Styleable.ForegroundLinearLayout_android_foregroundGravity = global::xamarinFormApp.Droid.Resource.Styleable.ForegroundLinearLayout_android_foregroundGravity; + global::Xamarin.Forms.Platform.Resource.Styleable.ForegroundLinearLayout_foregroundInsidePadding = global::xamarinFormApp.Droid.Resource.Styleable.ForegroundLinearLayout_foregroundInsidePadding; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColorItem = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColorItem_android_color = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem_android_color; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColorItem_android_offset = global::xamarinFormApp.Droid.Resource.Styleable.GradientColorItem_android_offset; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_centerColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerColor; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_centerX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerX; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_centerY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_centerY; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_endColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endColor; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_endX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endX; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_endY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_endY; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_gradientRadius = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_gradientRadius; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_startColor = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startColor; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_startX = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startX; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_startY = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_startY; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_tileMode = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_tileMode; + global::Xamarin.Forms.Platform.Resource.Styleable.GradientColor_android_type = global::xamarinFormApp.Droid.Resource.Styleable.GradientColor_android_type; + global::Xamarin.Forms.Platform.Resource.Styleable.ItemsViewRendererTheme = global::xamarinFormApp.Droid.Resource.Styleable.ItemsViewRendererTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.ItemsViewRendererTheme_collectionViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.ItemsViewRendererTheme_collectionViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_android_baselineAligned = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_baselineAligned; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_android_baselineAlignedChildIndex = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_baselineAlignedChildIndex; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_android_gravity = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_gravity; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_android_orientation = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_orientation; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_android_weightSum = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_android_weightSum; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_divider = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_divider; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_dividerPadding = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_dividerPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_Layout = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_gravity = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_gravity; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_height = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_height; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_weight = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_weight; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_width = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_Layout_android_layout_width; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_measureWithLargestChild = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_measureWithLargestChild; + global::Xamarin.Forms.Platform.Resource.Styleable.LinearLayoutCompat_showDividers = global::xamarinFormApp.Droid.Resource.Styleable.LinearLayoutCompat_showDividers; + global::Xamarin.Forms.Platform.Resource.Styleable.ListPopupWindow = global::xamarinFormApp.Droid.Resource.Styleable.ListPopupWindow; + global::Xamarin.Forms.Platform.Resource.Styleable.ListPopupWindow_android_dropDownHorizontalOffset = global::xamarinFormApp.Droid.Resource.Styleable.ListPopupWindow_android_dropDownHorizontalOffset; + global::Xamarin.Forms.Platform.Resource.Styleable.ListPopupWindow_android_dropDownVerticalOffset = global::xamarinFormApp.Droid.Resource.Styleable.ListPopupWindow_android_dropDownVerticalOffset; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_android_insetBottom = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_android_insetBottom; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_android_insetLeft = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_android_insetLeft; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_android_insetRight = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_android_insetRight; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_android_insetTop = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_android_insetTop; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_backgroundTint = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_backgroundTint; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_backgroundTintMode = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_backgroundTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_cornerRadius = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_cornerRadius; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_icon = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_icon; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_iconGravity = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconGravity; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_iconPadding = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_iconSize = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconSize; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_iconTint = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconTint; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_iconTintMode = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_iconTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_rippleColor = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_rippleColor; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_strokeColor = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_strokeColor; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialButton_strokeWidth = global::xamarinFormApp.Droid.Resource.Styleable.MaterialButton_strokeWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialCardView = global::xamarinFormApp.Droid.Resource.Styleable.MaterialCardView; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialCardView_strokeColor = global::xamarinFormApp.Droid.Resource.Styleable.MaterialCardView_strokeColor; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialCardView_strokeWidth = global::xamarinFormApp.Droid.Resource.Styleable.MaterialCardView_strokeWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_bottomSheetDialogTheme = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_bottomSheetDialogTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_bottomSheetStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_bottomSheetStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_chipGroupStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_chipGroupStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_chipStandaloneStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_chipStandaloneStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_chipStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_chipStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_colorAccent = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorAccent; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_colorBackgroundFloating = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorBackgroundFloating; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_colorPrimary = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorPrimary; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_colorPrimaryDark = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorPrimaryDark; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_colorSecondary = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_colorSecondary; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_editTextStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_editTextStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_floatingActionButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_floatingActionButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_materialButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_materialButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_materialCardViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_materialCardViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_navigationViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_navigationViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_scrimBackground = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_scrimBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_snackbarButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_snackbarButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_tabStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_tabStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceBody1 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceBody1; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceBody2 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceBody2; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceButton = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceButton; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceCaption = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceCaption; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline1 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline1; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline2 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline2; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline3 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline3; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline4 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline4; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline5 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline5; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline6 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceHeadline6; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceOverline = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceOverline; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceSubtitle1 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceSubtitle1; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textAppearanceSubtitle2 = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textAppearanceSubtitle2; + global::Xamarin.Forms.Platform.Resource.Styleable.MaterialComponentsTheme_textInputStyle = global::xamarinFormApp.Droid.Resource.Styleable.MaterialComponentsTheme_textInputStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuGroup = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuGroup_android_checkableBehavior = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_checkableBehavior; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuGroup_android_enabled = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_enabled; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuGroup_android_id = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_id; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuGroup_android_menuCategory = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_menuCategory; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuGroup_android_orderInCategory = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_orderInCategory; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuGroup_android_visible = global::xamarinFormApp.Droid.Resource.Styleable.MenuGroup_android_visible; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_actionLayout = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_actionLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_actionProviderClass = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_actionProviderClass; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_actionViewClass = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_actionViewClass; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_alphabeticModifiers = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_alphabeticModifiers; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_alphabeticShortcut = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_alphabeticShortcut; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_checkable = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_checkable; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_checked = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_checked; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_enabled = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_enabled; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_icon = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_icon; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_id = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_id; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_menuCategory = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_menuCategory; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_numericShortcut = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_numericShortcut; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_onClick = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_onClick; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_orderInCategory = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_orderInCategory; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_title = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_title; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_titleCondensed = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_titleCondensed; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_android_visible = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_android_visible; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_contentDescription = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_contentDescription; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_iconTint = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_iconTint; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_iconTintMode = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_iconTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_numericModifiers = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_numericModifiers; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_showAsAction = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_showAsAction; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuItem_tooltipText = global::xamarinFormApp.Droid.Resource.Styleable.MenuItem_tooltipText; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView = global::xamarinFormApp.Droid.Resource.Styleable.MenuView; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_android_headerBackground = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_headerBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_android_horizontalDivider = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_horizontalDivider; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_android_itemBackground = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_itemBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_android_itemIconDisabledAlpha = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_itemIconDisabledAlpha; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_android_itemTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_itemTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_android_verticalDivider = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_verticalDivider; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_android_windowAnimationStyle = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_android_windowAnimationStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_preserveIconSpacing = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_preserveIconSpacing; + global::Xamarin.Forms.Platform.Resource.Styleable.MenuView_subMenuArrow = global::xamarinFormApp.Droid.Resource.Styleable.MenuView_subMenuArrow; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_android_background = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_android_background; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_android_fitsSystemWindows = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_android_fitsSystemWindows; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_android_maxWidth = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_android_maxWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_elevation = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_elevation; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_headerLayout = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_headerLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_itemBackground = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_itemHorizontalPadding = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemHorizontalPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_itemIconPadding = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemIconPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_itemIconTint = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemIconTint; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_itemTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_itemTextColor = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_itemTextColor; + global::Xamarin.Forms.Platform.Resource.Styleable.NavigationView_menu = global::xamarinFormApp.Droid.Resource.Styleable.NavigationView_menu; + global::Xamarin.Forms.Platform.Resource.Styleable.PopupWindow = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindow; + global::Xamarin.Forms.Platform.Resource.Styleable.PopupWindowBackgroundState = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindowBackgroundState; + global::Xamarin.Forms.Platform.Resource.Styleable.PopupWindowBackgroundState_state_above_anchor = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindowBackgroundState_state_above_anchor; + global::Xamarin.Forms.Platform.Resource.Styleable.PopupWindow_android_popupAnimationStyle = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindow_android_popupAnimationStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.PopupWindow_android_popupBackground = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindow_android_popupBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.PopupWindow_overlapAnchor = global::xamarinFormApp.Droid.Resource.Styleable.PopupWindow_overlapAnchor; + global::Xamarin.Forms.Platform.Resource.Styleable.RecycleListView = global::xamarinFormApp.Droid.Resource.Styleable.RecycleListView; + global::Xamarin.Forms.Platform.Resource.Styleable.RecycleListView_paddingBottomNoButtons = global::xamarinFormApp.Droid.Resource.Styleable.RecycleListView_paddingBottomNoButtons; + global::Xamarin.Forms.Platform.Resource.Styleable.RecycleListView_paddingTopNoTitle = global::xamarinFormApp.Droid.Resource.Styleable.RecycleListView_paddingTopNoTitle; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_android_descendantFocusability = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_android_descendantFocusability; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_android_orientation = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_android_orientation; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_fastScrollEnabled = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_fastScrollHorizontalThumbDrawable = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollHorizontalThumbDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_fastScrollHorizontalTrackDrawable = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollHorizontalTrackDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_fastScrollVerticalThumbDrawable = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollVerticalThumbDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_fastScrollVerticalTrackDrawable = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_fastScrollVerticalTrackDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_layoutManager = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_layoutManager; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_reverseLayout = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_reverseLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_spanCount = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_spanCount; + global::Xamarin.Forms.Platform.Resource.Styleable.RecyclerView_stackFromEnd = global::xamarinFormApp.Droid.Resource.Styleable.RecyclerView_stackFromEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.ScrimInsetsFrameLayout = global::xamarinFormApp.Droid.Resource.Styleable.ScrimInsetsFrameLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.ScrimInsetsFrameLayout_insetForeground = global::xamarinFormApp.Droid.Resource.Styleable.ScrimInsetsFrameLayout_insetForeground; + global::Xamarin.Forms.Platform.Resource.Styleable.ScrollingViewBehavior_Layout = global::xamarinFormApp.Droid.Resource.Styleable.ScrollingViewBehavior_Layout; + global::Xamarin.Forms.Platform.Resource.Styleable.ScrollingViewBehavior_Layout_behavior_overlapTop = global::xamarinFormApp.Droid.Resource.Styleable.ScrollingViewBehavior_Layout_behavior_overlapTop; + global::Xamarin.Forms.Platform.Resource.Styleable.ScrollViewRendererTheme = global::xamarinFormApp.Droid.Resource.Styleable.ScrollViewRendererTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.ScrollViewRendererTheme_scrollViewStyle = global::xamarinFormApp.Droid.Resource.Styleable.ScrollViewRendererTheme_scrollViewStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView = global::xamarinFormApp.Droid.Resource.Styleable.SearchView; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_android_focusable = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_android_focusable; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_android_imeOptions = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_android_imeOptions; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_android_inputType = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_android_inputType; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_android_maxWidth = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_android_maxWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_closeIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_closeIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_commitIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_commitIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_defaultQueryHint = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_defaultQueryHint; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_goIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_goIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_iconifiedByDefault = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_iconifiedByDefault; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_layout = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_layout; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_queryBackground = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_queryBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_queryHint = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_queryHint; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_searchHintIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_searchHintIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_searchIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_searchIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_submitBackground = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_submitBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_suggestionRowLayout = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_suggestionRowLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.SearchView_voiceIcon = global::xamarinFormApp.Droid.Resource.Styleable.SearchView_voiceIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.Snackbar = global::xamarinFormApp.Droid.Resource.Styleable.Snackbar; + global::Xamarin.Forms.Platform.Resource.Styleable.SnackbarLayout = global::xamarinFormApp.Droid.Resource.Styleable.SnackbarLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.SnackbarLayout_android_maxWidth = global::xamarinFormApp.Droid.Resource.Styleable.SnackbarLayout_android_maxWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.SnackbarLayout_elevation = global::xamarinFormApp.Droid.Resource.Styleable.SnackbarLayout_elevation; + global::Xamarin.Forms.Platform.Resource.Styleable.SnackbarLayout_maxActionInlineWidth = global::xamarinFormApp.Droid.Resource.Styleable.SnackbarLayout_maxActionInlineWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.Snackbar_snackbarButtonStyle = global::xamarinFormApp.Droid.Resource.Styleable.Snackbar_snackbarButtonStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.Snackbar_snackbarStyle = global::xamarinFormApp.Droid.Resource.Styleable.Snackbar_snackbarStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.Spinner = global::xamarinFormApp.Droid.Resource.Styleable.Spinner; + global::Xamarin.Forms.Platform.Resource.Styleable.Spinner_android_dropDownWidth = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_android_dropDownWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.Spinner_android_entries = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_android_entries; + global::Xamarin.Forms.Platform.Resource.Styleable.Spinner_android_popupBackground = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_android_popupBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.Spinner_android_prompt = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_android_prompt; + global::Xamarin.Forms.Platform.Resource.Styleable.Spinner_popupTheme = global::xamarinFormApp.Droid.Resource.Styleable.Spinner_popupTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawable = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawableItem = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawableItem; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawableItem_android_drawable = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawableItem_android_drawable; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawable_android_constantSize = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_constantSize; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawable_android_dither = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_dither; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawable_android_enterFadeDuration = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_enterFadeDuration; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawable_android_exitFadeDuration = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_exitFadeDuration; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawable_android_variablePadding = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_variablePadding; + global::Xamarin.Forms.Platform.Resource.Styleable.StateListDrawable_android_visible = global::xamarinFormApp.Droid.Resource.Styleable.StateListDrawable_android_visible; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_android_textOff = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_android_textOff; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_android_textOn = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_android_textOn; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_android_thumb = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_android_thumb; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_showText = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_showText; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_splitTrack = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_splitTrack; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_switchMinWidth = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_switchMinWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_switchPadding = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_switchPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_switchTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_switchTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_thumbTextPadding = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_thumbTextPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_thumbTint = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_thumbTint; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_thumbTintMode = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_thumbTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_track = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_track; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_trackTint = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_trackTint; + global::Xamarin.Forms.Platform.Resource.Styleable.SwitchCompat_trackTintMode = global::xamarinFormApp.Droid.Resource.Styleable.SwitchCompat_trackTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.TabItem = global::xamarinFormApp.Droid.Resource.Styleable.TabItem; + global::Xamarin.Forms.Platform.Resource.Styleable.TabItem_android_icon = global::xamarinFormApp.Droid.Resource.Styleable.TabItem_android_icon; + global::Xamarin.Forms.Platform.Resource.Styleable.TabItem_android_layout = global::xamarinFormApp.Droid.Resource.Styleable.TabItem_android_layout; + global::Xamarin.Forms.Platform.Resource.Styleable.TabItem_android_text = global::xamarinFormApp.Droid.Resource.Styleable.TabItem_android_text; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabBackground = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabBackground; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabContentStart = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabContentStart; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabGravity = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabGravity; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabIconTint = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIconTint; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabIconTintMode = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIconTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabIndicator = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicator; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabIndicatorAnimationDuration = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorAnimationDuration; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabIndicatorColor = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorColor; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabIndicatorFullWidth = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorFullWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabIndicatorGravity = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorGravity; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabIndicatorHeight = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabIndicatorHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabInlineLabel = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabInlineLabel; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabMaxWidth = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabMaxWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabMinWidth = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabMinWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabMode = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabMode; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabPadding = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPadding; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabPaddingBottom = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPaddingBottom; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabPaddingEnd = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPaddingEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabPaddingStart = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPaddingStart; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabPaddingTop = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabPaddingTop; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabRippleColor = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabRippleColor; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabSelectedTextColor = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabSelectedTextColor; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabTextColor = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabTextColor; + global::Xamarin.Forms.Platform.Resource.Styleable.TabLayout_tabUnboundedRipple = global::xamarinFormApp.Droid.Resource.Styleable.TabLayout_tabUnboundedRipple; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_fontFamily = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_fontFamily; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_shadowColor = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_shadowColor; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_shadowDx = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_shadowDx; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_shadowDy = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_shadowDy; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_shadowRadius = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_shadowRadius; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_textColor = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textColor; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_textColorHint = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textColorHint; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_textColorLink = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textColorLink; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_textSize = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textSize; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_textStyle = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_textStyle; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_android_typeface = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_android_typeface; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_fontFamily = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_fontFamily; + global::Xamarin.Forms.Platform.Resource.Styleable.TextAppearance_textAllCaps = global::xamarinFormApp.Droid.Resource.Styleable.TextAppearance_textAllCaps; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_android_hint = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_android_hint; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_android_textColorHint = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_android_textColorHint; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxBackgroundColor = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxBackgroundColor; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxBackgroundMode = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxBackgroundMode; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxCollapsedPaddingTop = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCollapsedPaddingTop; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxCornerRadiusBottomEnd = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCornerRadiusBottomEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxCornerRadiusBottomStart = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCornerRadiusBottomStart; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxCornerRadiusTopEnd = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCornerRadiusTopEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxCornerRadiusTopStart = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxCornerRadiusTopStart; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxStrokeColor = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxStrokeColor; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_boxStrokeWidth = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_boxStrokeWidth; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_counterEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_counterEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_counterMaxLength = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_counterMaxLength; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_counterOverflowTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_counterOverflowTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_counterTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_counterTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_errorEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_errorEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_errorTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_errorTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_helperText = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_helperText; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_helperTextEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_helperTextEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_helperTextTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_helperTextTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_hintAnimationEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_hintAnimationEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_hintEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_hintEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_hintTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_hintTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_passwordToggleContentDescription = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleContentDescription; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_passwordToggleDrawable = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleDrawable; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_passwordToggleEnabled = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleEnabled; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_passwordToggleTint = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleTint; + global::Xamarin.Forms.Platform.Resource.Styleable.TextInputLayout_passwordToggleTintMode = global::xamarinFormApp.Droid.Resource.Styleable.TextInputLayout_passwordToggleTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.ThemeEnforcement = global::xamarinFormApp.Droid.Resource.Styleable.ThemeEnforcement; + global::Xamarin.Forms.Platform.Resource.Styleable.ThemeEnforcement_android_textAppearance = global::xamarinFormApp.Droid.Resource.Styleable.ThemeEnforcement_android_textAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.ThemeEnforcement_enforceMaterialTheme = global::xamarinFormApp.Droid.Resource.Styleable.ThemeEnforcement_enforceMaterialTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.ThemeEnforcement_enforceTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.ThemeEnforcement_enforceTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_android_gravity = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_android_gravity; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_android_minHeight = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_android_minHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_buttonGravity = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_buttonGravity; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_collapseContentDescription = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_collapseContentDescription; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_collapseIcon = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_collapseIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_contentInsetEnd = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_contentInsetEndWithActions = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetEndWithActions; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_contentInsetLeft = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetLeft; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_contentInsetRight = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetRight; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_contentInsetStart = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetStart; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_contentInsetStartWithNavigation = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_contentInsetStartWithNavigation; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_logo = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_logo; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_logoDescription = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_logoDescription; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_maxButtonHeight = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_maxButtonHeight; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_navigationContentDescription = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_navigationContentDescription; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_navigationIcon = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_navigationIcon; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_popupTheme = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_popupTheme; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_subtitle = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_subtitle; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_subtitleTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_subtitleTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_subtitleTextColor = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_subtitleTextColor; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_title = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_title; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_titleMargin = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMargin; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_titleMarginBottom = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMarginBottom; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_titleMarginEnd = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMarginEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_titleMargins = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMargins; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_titleMarginStart = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMarginStart; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_titleMarginTop = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleMarginTop; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_titleTextAppearance = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleTextAppearance; + global::Xamarin.Forms.Platform.Resource.Styleable.Toolbar_titleTextColor = global::xamarinFormApp.Droid.Resource.Styleable.Toolbar_titleTextColor; + global::Xamarin.Forms.Platform.Resource.Styleable.View = global::xamarinFormApp.Droid.Resource.Styleable.View; + global::Xamarin.Forms.Platform.Resource.Styleable.ViewBackgroundHelper = global::xamarinFormApp.Droid.Resource.Styleable.ViewBackgroundHelper; + global::Xamarin.Forms.Platform.Resource.Styleable.ViewBackgroundHelper_android_background = global::xamarinFormApp.Droid.Resource.Styleable.ViewBackgroundHelper_android_background; + global::Xamarin.Forms.Platform.Resource.Styleable.ViewBackgroundHelper_backgroundTint = global::xamarinFormApp.Droid.Resource.Styleable.ViewBackgroundHelper_backgroundTint; + global::Xamarin.Forms.Platform.Resource.Styleable.ViewBackgroundHelper_backgroundTintMode = global::xamarinFormApp.Droid.Resource.Styleable.ViewBackgroundHelper_backgroundTintMode; + global::Xamarin.Forms.Platform.Resource.Styleable.ViewStubCompat = global::xamarinFormApp.Droid.Resource.Styleable.ViewStubCompat; + global::Xamarin.Forms.Platform.Resource.Styleable.ViewStubCompat_android_id = global::xamarinFormApp.Droid.Resource.Styleable.ViewStubCompat_android_id; + global::Xamarin.Forms.Platform.Resource.Styleable.ViewStubCompat_android_inflatedId = global::xamarinFormApp.Droid.Resource.Styleable.ViewStubCompat_android_inflatedId; + global::Xamarin.Forms.Platform.Resource.Styleable.ViewStubCompat_android_layout = global::xamarinFormApp.Droid.Resource.Styleable.ViewStubCompat_android_layout; + global::Xamarin.Forms.Platform.Resource.Styleable.View_android_focusable = global::xamarinFormApp.Droid.Resource.Styleable.View_android_focusable; + global::Xamarin.Forms.Platform.Resource.Styleable.View_android_theme = global::xamarinFormApp.Droid.Resource.Styleable.View_android_theme; + global::Xamarin.Forms.Platform.Resource.Styleable.View_paddingEnd = global::xamarinFormApp.Droid.Resource.Styleable.View_paddingEnd; + global::Xamarin.Forms.Platform.Resource.Styleable.View_paddingStart = global::xamarinFormApp.Droid.Resource.Styleable.View_paddingStart; + global::Xamarin.Forms.Platform.Resource.Styleable.View_theme = global::xamarinFormApp.Droid.Resource.Styleable.View_theme; + } + + public partial class Animation + { + + // aapt resource value: 0x7F010000 + public const int abc_fade_in = 2130771968; + + // aapt resource value: 0x7F010001 + public const int abc_fade_out = 2130771969; + + // aapt resource value: 0x7F010002 + public const int abc_grow_fade_in_from_bottom = 2130771970; + + // aapt resource value: 0x7F010003 + public const int abc_popup_enter = 2130771971; + + // aapt resource value: 0x7F010004 + public const int abc_popup_exit = 2130771972; + + // aapt resource value: 0x7F010005 + public const int abc_shrink_fade_out_from_bottom = 2130771973; + + // aapt resource value: 0x7F010006 + public const int abc_slide_in_bottom = 2130771974; + + // aapt resource value: 0x7F010007 + public const int abc_slide_in_top = 2130771975; + + // aapt resource value: 0x7F010008 + public const int abc_slide_out_bottom = 2130771976; + + // aapt resource value: 0x7F010009 + public const int abc_slide_out_top = 2130771977; + + // aapt resource value: 0x7F01000A + public const int abc_tooltip_enter = 2130771978; + + // aapt resource value: 0x7F01000B + public const int abc_tooltip_exit = 2130771979; + + // aapt resource value: 0x7F01000C + public const int design_bottom_sheet_slide_in = 2130771980; + + // aapt resource value: 0x7F01000D + public const int design_bottom_sheet_slide_out = 2130771981; + + // aapt resource value: 0x7F01000E + public const int design_snackbar_in = 2130771982; + + // aapt resource value: 0x7F01000F + public const int design_snackbar_out = 2130771983; + + // aapt resource value: 0x7F010010 + public const int EnterFromLeft = 2130771984; + + // aapt resource value: 0x7F010011 + public const int EnterFromRight = 2130771985; + + // aapt resource value: 0x7F010012 + public const int ExitToLeft = 2130771986; + + // aapt resource value: 0x7F010013 + public const int ExitToRight = 2130771987; + + static Animation() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Animation() + { + } + } + + public partial class Animator + { + + // aapt resource value: 0x7F020000 + public const int design_appbar_state_list_animator = 2130837504; + + // aapt resource value: 0x7F020001 + public const int design_fab_hide_motion_spec = 2130837505; + + // aapt resource value: 0x7F020002 + public const int design_fab_show_motion_spec = 2130837506; + + // aapt resource value: 0x7F020003 + public const int mtrl_btn_state_list_anim = 2130837507; + + // aapt resource value: 0x7F020004 + public const int mtrl_btn_unelevated_state_list_anim = 2130837508; + + // aapt resource value: 0x7F020005 + public const int mtrl_chip_state_list_anim = 2130837509; + + // aapt resource value: 0x7F020006 + public const int mtrl_fab_hide_motion_spec = 2130837510; + + // aapt resource value: 0x7F020007 + public const int mtrl_fab_show_motion_spec = 2130837511; + + // aapt resource value: 0x7F020008 + public const int mtrl_fab_transformation_sheet_collapse_spec = 2130837512; + + // aapt resource value: 0x7F020009 + public const int mtrl_fab_transformation_sheet_expand_spec = 2130837513; + + static Animator() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Animator() + { + } + } + + public partial class Attribute + { + + // aapt resource value: 0x7F030000 + public const int actionBarDivider = 2130903040; + + // aapt resource value: 0x7F030001 + public const int actionBarItemBackground = 2130903041; + + // aapt resource value: 0x7F030002 + public const int actionBarPopupTheme = 2130903042; + + // aapt resource value: 0x7F030003 + public const int actionBarSize = 2130903043; + + // aapt resource value: 0x7F030004 + public const int actionBarSplitStyle = 2130903044; + + // aapt resource value: 0x7F030005 + public const int actionBarStyle = 2130903045; + + // aapt resource value: 0x7F030006 + public const int actionBarTabBarStyle = 2130903046; + + // aapt resource value: 0x7F030007 + public const int actionBarTabStyle = 2130903047; + + // aapt resource value: 0x7F030008 + public const int actionBarTabTextStyle = 2130903048; + + // aapt resource value: 0x7F030009 + public const int actionBarTheme = 2130903049; + + // aapt resource value: 0x7F03000A + public const int actionBarWidgetTheme = 2130903050; + + // aapt resource value: 0x7F03000B + public const int actionButtonStyle = 2130903051; + + // aapt resource value: 0x7F03000C + public const int actionDropDownStyle = 2130903052; + + // aapt resource value: 0x7F03000D + public const int actionLayout = 2130903053; + + // aapt resource value: 0x7F03000E + public const int actionMenuTextAppearance = 2130903054; + + // aapt resource value: 0x7F03000F + public const int actionMenuTextColor = 2130903055; + + // aapt resource value: 0x7F030010 + public const int actionModeBackground = 2130903056; + + // aapt resource value: 0x7F030011 + public const int actionModeCloseButtonStyle = 2130903057; + + // aapt resource value: 0x7F030012 + public const int actionModeCloseDrawable = 2130903058; + + // aapt resource value: 0x7F030013 + public const int actionModeCopyDrawable = 2130903059; + + // aapt resource value: 0x7F030014 + public const int actionModeCutDrawable = 2130903060; + + // aapt resource value: 0x7F030015 + public const int actionModeFindDrawable = 2130903061; + + // aapt resource value: 0x7F030016 + public const int actionModePasteDrawable = 2130903062; + + // aapt resource value: 0x7F030017 + public const int actionModePopupWindowStyle = 2130903063; + + // aapt resource value: 0x7F030018 + public const int actionModeSelectAllDrawable = 2130903064; + + // aapt resource value: 0x7F030019 + public const int actionModeShareDrawable = 2130903065; + + // aapt resource value: 0x7F03001A + public const int actionModeSplitBackground = 2130903066; + + // aapt resource value: 0x7F03001B + public const int actionModeStyle = 2130903067; + + // aapt resource value: 0x7F03001C + public const int actionModeWebSearchDrawable = 2130903068; + + // aapt resource value: 0x7F03001D + public const int actionOverflowButtonStyle = 2130903069; + + // aapt resource value: 0x7F03001E + public const int actionOverflowMenuStyle = 2130903070; + + // aapt resource value: 0x7F03001F + public const int actionProviderClass = 2130903071; + + // aapt resource value: 0x7F030020 + public const int actionViewClass = 2130903072; + + // aapt resource value: 0x7F030021 + public const int activityChooserViewStyle = 2130903073; + + // aapt resource value: 0x7F030022 + public const int alertDialogButtonGroupStyle = 2130903074; + + // aapt resource value: 0x7F030023 + public const int alertDialogCenterButtons = 2130903075; + + // aapt resource value: 0x7F030024 + public const int alertDialogStyle = 2130903076; + + // aapt resource value: 0x7F030025 + public const int alertDialogTheme = 2130903077; + + // aapt resource value: 0x7F030026 + public const int allowStacking = 2130903078; + + // aapt resource value: 0x7F030027 + public const int alpha = 2130903079; + + // aapt resource value: 0x7F030028 + public const int alphabeticModifiers = 2130903080; + + // aapt resource value: 0x7F030029 + public const int arrowHeadLength = 2130903081; + + // aapt resource value: 0x7F03002A + public const int arrowShaftLength = 2130903082; + + // aapt resource value: 0x7F03002B + public const int autoCompleteTextViewStyle = 2130903083; + + // aapt resource value: 0x7F03002C + public const int autoSizeMaxTextSize = 2130903084; + + // aapt resource value: 0x7F03002D + public const int autoSizeMinTextSize = 2130903085; + + // aapt resource value: 0x7F03002E + public const int autoSizePresetSizes = 2130903086; + + // aapt resource value: 0x7F03002F + public const int autoSizeStepGranularity = 2130903087; + + // aapt resource value: 0x7F030030 + public const int autoSizeTextType = 2130903088; + + // aapt resource value: 0x7F030031 + public const int background = 2130903089; + + // aapt resource value: 0x7F030032 + public const int backgroundSplit = 2130903090; + + // aapt resource value: 0x7F030033 + public const int backgroundStacked = 2130903091; + + // aapt resource value: 0x7F030034 + public const int backgroundTint = 2130903092; + + // aapt resource value: 0x7F030035 + public const int backgroundTintMode = 2130903093; + + // aapt resource value: 0x7F030036 + public const int barLength = 2130903094; + + // aapt resource value: 0x7F030037 + public const int behavior_autoHide = 2130903095; + + // aapt resource value: 0x7F030038 + public const int behavior_fitToContents = 2130903096; + + // aapt resource value: 0x7F030039 + public const int behavior_hideable = 2130903097; + + // aapt resource value: 0x7F03003A + public const int behavior_overlapTop = 2130903098; + + // aapt resource value: 0x7F03003B + public const int behavior_peekHeight = 2130903099; + + // aapt resource value: 0x7F03003C + public const int behavior_skipCollapsed = 2130903100; + + // aapt resource value: 0x7F03003E + public const int borderlessButtonStyle = 2130903102; + + // aapt resource value: 0x7F03003D + public const int borderWidth = 2130903101; + + // aapt resource value: 0x7F03003F + public const int bottomAppBarStyle = 2130903103; + + // aapt resource value: 0x7F030040 + public const int bottomNavigationStyle = 2130903104; + + // aapt resource value: 0x7F030041 + public const int bottomSheetDialogTheme = 2130903105; + + // aapt resource value: 0x7F030042 + public const int bottomSheetStyle = 2130903106; + + // aapt resource value: 0x7F030043 + public const int boxBackgroundColor = 2130903107; + + // aapt resource value: 0x7F030044 + public const int boxBackgroundMode = 2130903108; + + // aapt resource value: 0x7F030045 + public const int boxCollapsedPaddingTop = 2130903109; + + // aapt resource value: 0x7F030046 + public const int boxCornerRadiusBottomEnd = 2130903110; + + // aapt resource value: 0x7F030047 + public const int boxCornerRadiusBottomStart = 2130903111; + + // aapt resource value: 0x7F030048 + public const int boxCornerRadiusTopEnd = 2130903112; + + // aapt resource value: 0x7F030049 + public const int boxCornerRadiusTopStart = 2130903113; + + // aapt resource value: 0x7F03004A + public const int boxStrokeColor = 2130903114; + + // aapt resource value: 0x7F03004B + public const int boxStrokeWidth = 2130903115; + + // aapt resource value: 0x7F03004C + public const int buttonBarButtonStyle = 2130903116; + + // aapt resource value: 0x7F03004D + public const int buttonBarNegativeButtonStyle = 2130903117; + + // aapt resource value: 0x7F03004E + public const int buttonBarNeutralButtonStyle = 2130903118; + + // aapt resource value: 0x7F03004F + public const int buttonBarPositiveButtonStyle = 2130903119; + + // aapt resource value: 0x7F030050 + public const int buttonBarStyle = 2130903120; + + // aapt resource value: 0x7F030051 + public const int buttonGravity = 2130903121; + + // aapt resource value: 0x7F030052 + public const int buttonIconDimen = 2130903122; + + // aapt resource value: 0x7F030053 + public const int buttonPanelSideLayout = 2130903123; + + // aapt resource value: 0x7F030054 + public const int buttonStyle = 2130903124; + + // aapt resource value: 0x7F030055 + public const int buttonStyleSmall = 2130903125; + + // aapt resource value: 0x7F030056 + public const int buttonTint = 2130903126; + + // aapt resource value: 0x7F030057 + public const int buttonTintMode = 2130903127; + + // aapt resource value: 0x7F030058 + public const int cardBackgroundColor = 2130903128; + + // aapt resource value: 0x7F030059 + public const int cardCornerRadius = 2130903129; + + // aapt resource value: 0x7F03005A + public const int cardElevation = 2130903130; + + // aapt resource value: 0x7F03005B + public const int cardMaxElevation = 2130903131; + + // aapt resource value: 0x7F03005C + public const int cardPreventCornerOverlap = 2130903132; + + // aapt resource value: 0x7F03005D + public const int cardUseCompatPadding = 2130903133; + + // aapt resource value: 0x7F03005E + public const int cardViewStyle = 2130903134; + + // aapt resource value: 0x7F03005F + public const int checkboxStyle = 2130903135; + + // aapt resource value: 0x7F030060 + public const int checkedChip = 2130903136; + + // aapt resource value: 0x7F030061 + public const int checkedIcon = 2130903137; + + // aapt resource value: 0x7F030062 + public const int checkedIconEnabled = 2130903138; + + // aapt resource value: 0x7F030063 + public const int checkedIconVisible = 2130903139; + + // aapt resource value: 0x7F030064 + public const int checkedTextViewStyle = 2130903140; + + // aapt resource value: 0x7F030065 + public const int chipBackgroundColor = 2130903141; + + // aapt resource value: 0x7F030066 + public const int chipCornerRadius = 2130903142; + + // aapt resource value: 0x7F030067 + public const int chipEndPadding = 2130903143; + + // aapt resource value: 0x7F030068 + public const int chipGroupStyle = 2130903144; + + // aapt resource value: 0x7F030069 + public const int chipIcon = 2130903145; + + // aapt resource value: 0x7F03006A + public const int chipIconEnabled = 2130903146; + + // aapt resource value: 0x7F03006B + public const int chipIconSize = 2130903147; + + // aapt resource value: 0x7F03006C + public const int chipIconTint = 2130903148; + + // aapt resource value: 0x7F03006D + public const int chipIconVisible = 2130903149; + + // aapt resource value: 0x7F03006E + public const int chipMinHeight = 2130903150; + + // aapt resource value: 0x7F03006F + public const int chipSpacing = 2130903151; + + // aapt resource value: 0x7F030070 + public const int chipSpacingHorizontal = 2130903152; + + // aapt resource value: 0x7F030071 + public const int chipSpacingVertical = 2130903153; + + // aapt resource value: 0x7F030072 + public const int chipStandaloneStyle = 2130903154; + + // aapt resource value: 0x7F030073 + public const int chipStartPadding = 2130903155; + + // aapt resource value: 0x7F030074 + public const int chipStrokeColor = 2130903156; + + // aapt resource value: 0x7F030075 + public const int chipStrokeWidth = 2130903157; + + // aapt resource value: 0x7F030076 + public const int chipStyle = 2130903158; + + // aapt resource value: 0x7F030077 + public const int closeIcon = 2130903159; + + // aapt resource value: 0x7F030078 + public const int closeIconEnabled = 2130903160; + + // aapt resource value: 0x7F030079 + public const int closeIconEndPadding = 2130903161; + + // aapt resource value: 0x7F03007A + public const int closeIconSize = 2130903162; + + // aapt resource value: 0x7F03007B + public const int closeIconStartPadding = 2130903163; + + // aapt resource value: 0x7F03007C + public const int closeIconTint = 2130903164; + + // aapt resource value: 0x7F03007D + public const int closeIconVisible = 2130903165; + + // aapt resource value: 0x7F03007E + public const int closeItemLayout = 2130903166; + + // aapt resource value: 0x7F03007F + public const int collapseContentDescription = 2130903167; + + // aapt resource value: 0x7F030081 + public const int collapsedTitleGravity = 2130903169; + + // aapt resource value: 0x7F030082 + public const int collapsedTitleTextAppearance = 2130903170; + + // aapt resource value: 0x7F030080 + public const int collapseIcon = 2130903168; + + // aapt resource value: 0x7F030083 + public const int collectionViewStyle = 2130903171; + + // aapt resource value: 0x7F030084 + public const int color = 2130903172; + + // aapt resource value: 0x7F030085 + public const int colorAccent = 2130903173; + + // aapt resource value: 0x7F030086 + public const int colorBackgroundFloating = 2130903174; + + // aapt resource value: 0x7F030087 + public const int colorButtonNormal = 2130903175; + + // aapt resource value: 0x7F030088 + public const int colorControlActivated = 2130903176; + + // aapt resource value: 0x7F030089 + public const int colorControlHighlight = 2130903177; + + // aapt resource value: 0x7F03008A + public const int colorControlNormal = 2130903178; + + // aapt resource value: 0x7F03008B + public const int colorError = 2130903179; + + // aapt resource value: 0x7F03008C + public const int colorPrimary = 2130903180; + + // aapt resource value: 0x7F03008D + public const int colorPrimaryDark = 2130903181; + + // aapt resource value: 0x7F03008E + public const int colorSecondary = 2130903182; + + // aapt resource value: 0x7F03008F + public const int colorSwitchThumbNormal = 2130903183; + + // aapt resource value: 0x7F030090 + public const int commitIcon = 2130903184; + + // aapt resource value: 0x7F030091 + public const int contentDescription = 2130903185; + + // aapt resource value: 0x7F030092 + public const int contentInsetEnd = 2130903186; + + // aapt resource value: 0x7F030093 + public const int contentInsetEndWithActions = 2130903187; + + // aapt resource value: 0x7F030094 + public const int contentInsetLeft = 2130903188; + + // aapt resource value: 0x7F030095 + public const int contentInsetRight = 2130903189; + + // aapt resource value: 0x7F030096 + public const int contentInsetStart = 2130903190; + + // aapt resource value: 0x7F030097 + public const int contentInsetStartWithNavigation = 2130903191; + + // aapt resource value: 0x7F030098 + public const int contentPadding = 2130903192; + + // aapt resource value: 0x7F030099 + public const int contentPaddingBottom = 2130903193; + + // aapt resource value: 0x7F03009A + public const int contentPaddingLeft = 2130903194; + + // aapt resource value: 0x7F03009B + public const int contentPaddingRight = 2130903195; + + // aapt resource value: 0x7F03009C + public const int contentPaddingTop = 2130903196; + + // aapt resource value: 0x7F03009D + public const int contentScrim = 2130903197; + + // aapt resource value: 0x7F03009E + public const int controlBackground = 2130903198; + + // aapt resource value: 0x7F03009F + public const int coordinatorLayoutStyle = 2130903199; + + // aapt resource value: 0x7F0300A0 + public const int cornerRadius = 2130903200; + + // aapt resource value: 0x7F0300A1 + public const int counterEnabled = 2130903201; + + // aapt resource value: 0x7F0300A2 + public const int counterMaxLength = 2130903202; + + // aapt resource value: 0x7F0300A3 + public const int counterOverflowTextAppearance = 2130903203; + + // aapt resource value: 0x7F0300A4 + public const int counterTextAppearance = 2130903204; + + // aapt resource value: 0x7F0300A5 + public const int customNavigationLayout = 2130903205; + + // aapt resource value: 0x7F0300A6 + public const int defaultQueryHint = 2130903206; + + // aapt resource value: 0x7F0300A7 + public const int dialogCornerRadius = 2130903207; + + // aapt resource value: 0x7F0300A8 + public const int dialogPreferredPadding = 2130903208; + + // aapt resource value: 0x7F0300A9 + public const int dialogTheme = 2130903209; + + // aapt resource value: 0x7F0300AA + public const int displayOptions = 2130903210; + + // aapt resource value: 0x7F0300AB + public const int divider = 2130903211; + + // aapt resource value: 0x7F0300AC + public const int dividerHorizontal = 2130903212; + + // aapt resource value: 0x7F0300AD + public const int dividerPadding = 2130903213; + + // aapt resource value: 0x7F0300AE + public const int dividerVertical = 2130903214; + + // aapt resource value: 0x7F0300AF + public const int drawableSize = 2130903215; + + // aapt resource value: 0x7F0300B0 + public const int drawerArrowStyle = 2130903216; + + // aapt resource value: 0x7F0300B2 + public const int dropdownListPreferredItemHeight = 2130903218; + + // aapt resource value: 0x7F0300B1 + public const int dropDownListViewStyle = 2130903217; + + // aapt resource value: 0x7F0300B3 + public const int editTextBackground = 2130903219; + + // aapt resource value: 0x7F0300B4 + public const int editTextColor = 2130903220; + + // aapt resource value: 0x7F0300B5 + public const int editTextStyle = 2130903221; + + // aapt resource value: 0x7F0300B6 + public const int elevation = 2130903222; + + // aapt resource value: 0x7F0300B7 + public const int enforceMaterialTheme = 2130903223; + + // aapt resource value: 0x7F0300B8 + public const int enforceTextAppearance = 2130903224; + + // aapt resource value: 0x7F0300B9 + public const int errorEnabled = 2130903225; + + // aapt resource value: 0x7F0300BA + public const int errorTextAppearance = 2130903226; + + // aapt resource value: 0x7F0300BB + public const int expandActivityOverflowButtonDrawable = 2130903227; + + // aapt resource value: 0x7F0300BC + public const int expanded = 2130903228; + + // aapt resource value: 0x7F0300BD + public const int expandedTitleGravity = 2130903229; + + // aapt resource value: 0x7F0300BE + public const int expandedTitleMargin = 2130903230; + + // aapt resource value: 0x7F0300BF + public const int expandedTitleMarginBottom = 2130903231; + + // aapt resource value: 0x7F0300C0 + public const int expandedTitleMarginEnd = 2130903232; + + // aapt resource value: 0x7F0300C1 + public const int expandedTitleMarginStart = 2130903233; + + // aapt resource value: 0x7F0300C2 + public const int expandedTitleMarginTop = 2130903234; + + // aapt resource value: 0x7F0300C3 + public const int expandedTitleTextAppearance = 2130903235; + + // aapt resource value: 0x7F0300C4 + public const int fabAlignmentMode = 2130903236; + + // aapt resource value: 0x7F0300C5 + public const int fabCradleMargin = 2130903237; + + // aapt resource value: 0x7F0300C6 + public const int fabCradleRoundedCornerRadius = 2130903238; + + // aapt resource value: 0x7F0300C7 + public const int fabCradleVerticalOffset = 2130903239; + + // aapt resource value: 0x7F0300C8 + public const int fabCustomSize = 2130903240; + + // aapt resource value: 0x7F0300C9 + public const int fabSize = 2130903241; + + // aapt resource value: 0x7F0300CA + public const int fastScrollEnabled = 2130903242; + + // aapt resource value: 0x7F0300CB + public const int fastScrollHorizontalThumbDrawable = 2130903243; + + // aapt resource value: 0x7F0300CC + public const int fastScrollHorizontalTrackDrawable = 2130903244; + + // aapt resource value: 0x7F0300CD + public const int fastScrollVerticalThumbDrawable = 2130903245; + + // aapt resource value: 0x7F0300CE + public const int fastScrollVerticalTrackDrawable = 2130903246; + + // aapt resource value: 0x7F0300CF + public const int firstBaselineToTopHeight = 2130903247; + + // aapt resource value: 0x7F0300D0 + public const int floatingActionButtonStyle = 2130903248; + + // aapt resource value: 0x7F0300D1 + public const int font = 2130903249; + + // aapt resource value: 0x7F0300D2 + public const int fontFamily = 2130903250; + + // aapt resource value: 0x7F0300D3 + public const int fontProviderAuthority = 2130903251; + + // aapt resource value: 0x7F0300D4 + public const int fontProviderCerts = 2130903252; + + // aapt resource value: 0x7F0300D5 + public const int fontProviderFetchStrategy = 2130903253; + + // aapt resource value: 0x7F0300D6 + public const int fontProviderFetchTimeout = 2130903254; + + // aapt resource value: 0x7F0300D7 + public const int fontProviderPackage = 2130903255; + + // aapt resource value: 0x7F0300D8 + public const int fontProviderQuery = 2130903256; + + // aapt resource value: 0x7F0300D9 + public const int fontStyle = 2130903257; + + // aapt resource value: 0x7F0300DA + public const int fontVariationSettings = 2130903258; + + // aapt resource value: 0x7F0300DB + public const int fontWeight = 2130903259; + + // aapt resource value: 0x7F0300DC + public const int foregroundInsidePadding = 2130903260; + + // aapt resource value: 0x7F0300DD + public const int gapBetweenBars = 2130903261; + + // aapt resource value: 0x7F0300DE + public const int goIcon = 2130903262; + + // aapt resource value: 0x7F0300DF + public const int headerLayout = 2130903263; + + // aapt resource value: 0x7F0300E0 + public const int height = 2130903264; + + // aapt resource value: 0x7F0300E1 + public const int helperText = 2130903265; + + // aapt resource value: 0x7F0300E2 + public const int helperTextEnabled = 2130903266; + + // aapt resource value: 0x7F0300E3 + public const int helperTextTextAppearance = 2130903267; + + // aapt resource value: 0x7F0300E4 + public const int hideMotionSpec = 2130903268; + + // aapt resource value: 0x7F0300E5 + public const int hideOnContentScroll = 2130903269; + + // aapt resource value: 0x7F0300E6 + public const int hideOnScroll = 2130903270; + + // aapt resource value: 0x7F0300E7 + public const int hintAnimationEnabled = 2130903271; + + // aapt resource value: 0x7F0300E8 + public const int hintEnabled = 2130903272; + + // aapt resource value: 0x7F0300E9 + public const int hintTextAppearance = 2130903273; + + // aapt resource value: 0x7F0300EA + public const int homeAsUpIndicator = 2130903274; + + // aapt resource value: 0x7F0300EB + public const int homeLayout = 2130903275; + + // aapt resource value: 0x7F0300EC + public const int hoveredFocusedTranslationZ = 2130903276; + + // aapt resource value: 0x7F0300ED + public const int icon = 2130903277; + + // aapt resource value: 0x7F0300EE + public const int iconEndPadding = 2130903278; + + // aapt resource value: 0x7F0300EF + public const int iconGravity = 2130903279; + + // aapt resource value: 0x7F0300F5 + public const int iconifiedByDefault = 2130903285; + + // aapt resource value: 0x7F0300F0 + public const int iconPadding = 2130903280; + + // aapt resource value: 0x7F0300F1 + public const int iconSize = 2130903281; + + // aapt resource value: 0x7F0300F2 + public const int iconStartPadding = 2130903282; + + // aapt resource value: 0x7F0300F3 + public const int iconTint = 2130903283; + + // aapt resource value: 0x7F0300F4 + public const int iconTintMode = 2130903284; + + // aapt resource value: 0x7F0300F6 + public const int imageButtonStyle = 2130903286; + + // aapt resource value: 0x7F0300F7 + public const int indeterminateProgressStyle = 2130903287; + + // aapt resource value: 0x7F0300F8 + public const int initialActivityCount = 2130903288; + + // aapt resource value: 0x7F0300F9 + public const int insetForeground = 2130903289; + + // aapt resource value: 0x7F0300FA + public const int isLightTheme = 2130903290; + + // aapt resource value: 0x7F0300FB + public const int itemBackground = 2130903291; + + // aapt resource value: 0x7F0300FC + public const int itemHorizontalPadding = 2130903292; + + // aapt resource value: 0x7F0300FD + public const int itemHorizontalTranslationEnabled = 2130903293; + + // aapt resource value: 0x7F0300FE + public const int itemIconPadding = 2130903294; + + // aapt resource value: 0x7F0300FF + public const int itemIconSize = 2130903295; + + // aapt resource value: 0x7F030100 + public const int itemIconTint = 2130903296; + + // aapt resource value: 0x7F030101 + public const int itemPadding = 2130903297; + + // aapt resource value: 0x7F030102 + public const int itemSpacing = 2130903298; + + // aapt resource value: 0x7F030103 + public const int itemTextAppearance = 2130903299; + + // aapt resource value: 0x7F030104 + public const int itemTextAppearanceActive = 2130903300; + + // aapt resource value: 0x7F030105 + public const int itemTextAppearanceInactive = 2130903301; + + // aapt resource value: 0x7F030106 + public const int itemTextColor = 2130903302; + + // aapt resource value: 0x7F030107 + public const int keylines = 2130903303; + + // aapt resource value: 0x7F030108 + public const int labelVisibilityMode = 2130903304; + + // aapt resource value: 0x7F030109 + public const int lastBaselineToBottomHeight = 2130903305; + + // aapt resource value: 0x7F03010A + public const int layout = 2130903306; + + // aapt resource value: 0x7F03010B + public const int layoutManager = 2130903307; + + // aapt resource value: 0x7F03010C + public const int layout_anchor = 2130903308; + + // aapt resource value: 0x7F03010D + public const int layout_anchorGravity = 2130903309; + + // aapt resource value: 0x7F03010E + public const int layout_behavior = 2130903310; + + // aapt resource value: 0x7F03010F + public const int layout_collapseMode = 2130903311; + + // aapt resource value: 0x7F030110 + public const int layout_collapseParallaxMultiplier = 2130903312; + + // aapt resource value: 0x7F030111 + public const int layout_dodgeInsetEdges = 2130903313; + + // aapt resource value: 0x7F030112 + public const int layout_insetEdge = 2130903314; + + // aapt resource value: 0x7F030113 + public const int layout_keyline = 2130903315; + + // aapt resource value: 0x7F030114 + public const int layout_scrollFlags = 2130903316; + + // aapt resource value: 0x7F030115 + public const int layout_scrollInterpolator = 2130903317; + + // aapt resource value: 0x7F030116 + public const int liftOnScroll = 2130903318; + + // aapt resource value: 0x7F030117 + public const int lineHeight = 2130903319; + + // aapt resource value: 0x7F030118 + public const int lineSpacing = 2130903320; + + // aapt resource value: 0x7F030119 + public const int listChoiceBackgroundIndicator = 2130903321; + + // aapt resource value: 0x7F03011A + public const int listDividerAlertDialog = 2130903322; + + // aapt resource value: 0x7F03011B + public const int listItemLayout = 2130903323; + + // aapt resource value: 0x7F03011C + public const int listLayout = 2130903324; + + // aapt resource value: 0x7F03011D + public const int listMenuViewStyle = 2130903325; + + // aapt resource value: 0x7F03011E + public const int listPopupWindowStyle = 2130903326; + + // aapt resource value: 0x7F03011F + public const int listPreferredItemHeight = 2130903327; + + // aapt resource value: 0x7F030120 + public const int listPreferredItemHeightLarge = 2130903328; + + // aapt resource value: 0x7F030121 + public const int listPreferredItemHeightSmall = 2130903329; + + // aapt resource value: 0x7F030122 + public const int listPreferredItemPaddingLeft = 2130903330; + + // aapt resource value: 0x7F030123 + public const int listPreferredItemPaddingRight = 2130903331; + + // aapt resource value: 0x7F030124 + public const int logo = 2130903332; + + // aapt resource value: 0x7F030125 + public const int logoDescription = 2130903333; + + // aapt resource value: 0x7F030126 + public const int materialButtonStyle = 2130903334; + + // aapt resource value: 0x7F030127 + public const int materialCardViewStyle = 2130903335; + + // aapt resource value: 0x7F030128 + public const int maxActionInlineWidth = 2130903336; + + // aapt resource value: 0x7F030129 + public const int maxButtonHeight = 2130903337; + + // aapt resource value: 0x7F03012A + public const int maxImageSize = 2130903338; + + // aapt resource value: 0x7F03012B + public const int measureWithLargestChild = 2130903339; + + // aapt resource value: 0x7F03012C + public const int menu = 2130903340; + + // aapt resource value: 0x7F03012D + public const int multiChoiceItemLayout = 2130903341; + + // aapt resource value: 0x7F03012E + public const int navigationContentDescription = 2130903342; + + // aapt resource value: 0x7F03012F + public const int navigationIcon = 2130903343; + + // aapt resource value: 0x7F030130 + public const int navigationMode = 2130903344; + + // aapt resource value: 0x7F030131 + public const int navigationViewStyle = 2130903345; + + // aapt resource value: 0x7F030132 + public const int numericModifiers = 2130903346; + + // aapt resource value: 0x7F030133 + public const int overlapAnchor = 2130903347; + + // aapt resource value: 0x7F030134 + public const int paddingBottomNoButtons = 2130903348; + + // aapt resource value: 0x7F030135 + public const int paddingEnd = 2130903349; + + // aapt resource value: 0x7F030136 + public const int paddingStart = 2130903350; + + // aapt resource value: 0x7F030137 + public const int paddingTopNoTitle = 2130903351; + + // aapt resource value: 0x7F030138 + public const int panelBackground = 2130903352; + + // aapt resource value: 0x7F030139 + public const int panelMenuListTheme = 2130903353; + + // aapt resource value: 0x7F03013A + public const int panelMenuListWidth = 2130903354; + + // aapt resource value: 0x7F03013B + public const int passwordToggleContentDescription = 2130903355; + + // aapt resource value: 0x7F03013C + public const int passwordToggleDrawable = 2130903356; + + // aapt resource value: 0x7F03013D + public const int passwordToggleEnabled = 2130903357; + + // aapt resource value: 0x7F03013E + public const int passwordToggleTint = 2130903358; + + // aapt resource value: 0x7F03013F + public const int passwordToggleTintMode = 2130903359; + + // aapt resource value: 0x7F030140 + public const int popupMenuStyle = 2130903360; + + // aapt resource value: 0x7F030141 + public const int popupTheme = 2130903361; + + // aapt resource value: 0x7F030142 + public const int popupWindowStyle = 2130903362; + + // aapt resource value: 0x7F030143 + public const int preserveIconSpacing = 2130903363; + + // aapt resource value: 0x7F030144 + public const int pressedTranslationZ = 2130903364; + + // aapt resource value: 0x7F030145 + public const int progressBarPadding = 2130903365; + + // aapt resource value: 0x7F030146 + public const int progressBarStyle = 2130903366; + + // aapt resource value: 0x7F030147 + public const int queryBackground = 2130903367; + + // aapt resource value: 0x7F030148 + public const int queryHint = 2130903368; + + // aapt resource value: 0x7F030149 + public const int radioButtonStyle = 2130903369; + + // aapt resource value: 0x7F03014A + public const int ratingBarStyle = 2130903370; + + // aapt resource value: 0x7F03014B + public const int ratingBarStyleIndicator = 2130903371; + + // aapt resource value: 0x7F03014C + public const int ratingBarStyleSmall = 2130903372; + + // aapt resource value: 0x7F03014D + public const int reverseLayout = 2130903373; + + // aapt resource value: 0x7F03014E + public const int rippleColor = 2130903374; + + // aapt resource value: 0x7F03014F + public const int scrimAnimationDuration = 2130903375; + + // aapt resource value: 0x7F030150 + public const int scrimBackground = 2130903376; + + // aapt resource value: 0x7F030151 + public const int scrimVisibleHeightTrigger = 2130903377; + + // aapt resource value: 0x7F030152 + public const int scrollViewStyle = 2130903378; + + // aapt resource value: 0x7F030153 + public const int searchHintIcon = 2130903379; + + // aapt resource value: 0x7F030154 + public const int searchIcon = 2130903380; + + // aapt resource value: 0x7F030155 + public const int searchViewStyle = 2130903381; + + // aapt resource value: 0x7F030156 + public const int seekBarStyle = 2130903382; + + // aapt resource value: 0x7F030157 + public const int selectableItemBackground = 2130903383; + + // aapt resource value: 0x7F030158 + public const int selectableItemBackgroundBorderless = 2130903384; + + // aapt resource value: 0x7F030159 + public const int showAsAction = 2130903385; + + // aapt resource value: 0x7F03015A + public const int showDividers = 2130903386; + + // aapt resource value: 0x7F03015B + public const int showMotionSpec = 2130903387; + + // aapt resource value: 0x7F03015C + public const int showText = 2130903388; + + // aapt resource value: 0x7F03015D + public const int showTitle = 2130903389; + + // aapt resource value: 0x7F03015E + public const int singleChoiceItemLayout = 2130903390; + + // aapt resource value: 0x7F03015F + public const int singleLine = 2130903391; + + // aapt resource value: 0x7F030160 + public const int singleSelection = 2130903392; + + // aapt resource value: 0x7F030161 + public const int snackbarButtonStyle = 2130903393; + + // aapt resource value: 0x7F030162 + public const int snackbarStyle = 2130903394; + + // aapt resource value: 0x7F030163 + public const int spanCount = 2130903395; + + // aapt resource value: 0x7F030164 + public const int spinBars = 2130903396; + + // aapt resource value: 0x7F030165 + public const int spinnerDropDownItemStyle = 2130903397; + + // aapt resource value: 0x7F030166 + public const int spinnerStyle = 2130903398; + + // aapt resource value: 0x7F030167 + public const int splitTrack = 2130903399; + + // aapt resource value: 0x7F030168 + public const int srcCompat = 2130903400; + + // aapt resource value: 0x7F030169 + public const int stackFromEnd = 2130903401; + + // aapt resource value: 0x7F03016A + public const int state_above_anchor = 2130903402; + + // aapt resource value: 0x7F03016B + public const int state_collapsed = 2130903403; + + // aapt resource value: 0x7F03016C + public const int state_collapsible = 2130903404; + + // aapt resource value: 0x7F03016D + public const int state_liftable = 2130903405; + + // aapt resource value: 0x7F03016E + public const int state_lifted = 2130903406; + + // aapt resource value: 0x7F03016F + public const int statusBarBackground = 2130903407; + + // aapt resource value: 0x7F030170 + public const int statusBarScrim = 2130903408; + + // aapt resource value: 0x7F030171 + public const int strokeColor = 2130903409; + + // aapt resource value: 0x7F030172 + public const int strokeWidth = 2130903410; + + // aapt resource value: 0x7F030173 + public const int subMenuArrow = 2130903411; + + // aapt resource value: 0x7F030174 + public const int submitBackground = 2130903412; + + // aapt resource value: 0x7F030175 + public const int subtitle = 2130903413; + + // aapt resource value: 0x7F030176 + public const int subtitleTextAppearance = 2130903414; + + // aapt resource value: 0x7F030177 + public const int subtitleTextColor = 2130903415; + + // aapt resource value: 0x7F030178 + public const int subtitleTextStyle = 2130903416; + + // aapt resource value: 0x7F030179 + public const int suggestionRowLayout = 2130903417; + + // aapt resource value: 0x7F03017A + public const int switchMinWidth = 2130903418; + + // aapt resource value: 0x7F03017B + public const int switchPadding = 2130903419; + + // aapt resource value: 0x7F03017C + public const int switchStyle = 2130903420; + + // aapt resource value: 0x7F03017D + public const int switchTextAppearance = 2130903421; + + // aapt resource value: 0x7F03017E + public const int tabBackground = 2130903422; + + // aapt resource value: 0x7F03017F + public const int tabContentStart = 2130903423; + + // aapt resource value: 0x7F030180 + public const int tabGravity = 2130903424; + + // aapt resource value: 0x7F030181 + public const int tabIconTint = 2130903425; + + // aapt resource value: 0x7F030182 + public const int tabIconTintMode = 2130903426; + + // aapt resource value: 0x7F030183 + public const int tabIndicator = 2130903427; + + // aapt resource value: 0x7F030184 + public const int tabIndicatorAnimationDuration = 2130903428; + + // aapt resource value: 0x7F030185 + public const int tabIndicatorColor = 2130903429; + + // aapt resource value: 0x7F030186 + public const int tabIndicatorFullWidth = 2130903430; + + // aapt resource value: 0x7F030187 + public const int tabIndicatorGravity = 2130903431; + + // aapt resource value: 0x7F030188 + public const int tabIndicatorHeight = 2130903432; + + // aapt resource value: 0x7F030189 + public const int tabInlineLabel = 2130903433; + + // aapt resource value: 0x7F03018A + public const int tabMaxWidth = 2130903434; + + // aapt resource value: 0x7F03018B + public const int tabMinWidth = 2130903435; + + // aapt resource value: 0x7F03018C + public const int tabMode = 2130903436; + + // aapt resource value: 0x7F03018D + public const int tabPadding = 2130903437; + + // aapt resource value: 0x7F03018E + public const int tabPaddingBottom = 2130903438; + + // aapt resource value: 0x7F03018F + public const int tabPaddingEnd = 2130903439; + + // aapt resource value: 0x7F030190 + public const int tabPaddingStart = 2130903440; + + // aapt resource value: 0x7F030191 + public const int tabPaddingTop = 2130903441; + + // aapt resource value: 0x7F030192 + public const int tabRippleColor = 2130903442; + + // aapt resource value: 0x7F030193 + public const int tabSelectedTextColor = 2130903443; + + // aapt resource value: 0x7F030194 + public const int tabStyle = 2130903444; + + // aapt resource value: 0x7F030195 + public const int tabTextAppearance = 2130903445; + + // aapt resource value: 0x7F030196 + public const int tabTextColor = 2130903446; + + // aapt resource value: 0x7F030197 + public const int tabUnboundedRipple = 2130903447; + + // aapt resource value: 0x7F030198 + public const int textAllCaps = 2130903448; + + // aapt resource value: 0x7F030199 + public const int textAppearanceBody1 = 2130903449; + + // aapt resource value: 0x7F03019A + public const int textAppearanceBody2 = 2130903450; + + // aapt resource value: 0x7F03019B + public const int textAppearanceButton = 2130903451; + + // aapt resource value: 0x7F03019C + public const int textAppearanceCaption = 2130903452; + + // aapt resource value: 0x7F03019D + public const int textAppearanceHeadline1 = 2130903453; + + // aapt resource value: 0x7F03019E + public const int textAppearanceHeadline2 = 2130903454; + + // aapt resource value: 0x7F03019F + public const int textAppearanceHeadline3 = 2130903455; + + // aapt resource value: 0x7F0301A0 + public const int textAppearanceHeadline4 = 2130903456; + + // aapt resource value: 0x7F0301A1 + public const int textAppearanceHeadline5 = 2130903457; + + // aapt resource value: 0x7F0301A2 + public const int textAppearanceHeadline6 = 2130903458; + + // aapt resource value: 0x7F0301A3 + public const int textAppearanceLargePopupMenu = 2130903459; + + // aapt resource value: 0x7F0301A4 + public const int textAppearanceListItem = 2130903460; + + // aapt resource value: 0x7F0301A5 + public const int textAppearanceListItemSecondary = 2130903461; + + // aapt resource value: 0x7F0301A6 + public const int textAppearanceListItemSmall = 2130903462; + + // aapt resource value: 0x7F0301A7 + public const int textAppearanceOverline = 2130903463; + + // aapt resource value: 0x7F0301A8 + public const int textAppearancePopupMenuHeader = 2130903464; + + // aapt resource value: 0x7F0301A9 + public const int textAppearanceSearchResultSubtitle = 2130903465; + + // aapt resource value: 0x7F0301AA + public const int textAppearanceSearchResultTitle = 2130903466; + + // aapt resource value: 0x7F0301AB + public const int textAppearanceSmallPopupMenu = 2130903467; + + // aapt resource value: 0x7F0301AC + public const int textAppearanceSubtitle1 = 2130903468; + + // aapt resource value: 0x7F0301AD + public const int textAppearanceSubtitle2 = 2130903469; + + // aapt resource value: 0x7F0301AE + public const int textColorAlertDialogListItem = 2130903470; + + // aapt resource value: 0x7F0301AF + public const int textColorSearchUrl = 2130903471; + + // aapt resource value: 0x7F0301B0 + public const int textEndPadding = 2130903472; + + // aapt resource value: 0x7F0301B1 + public const int textInputStyle = 2130903473; + + // aapt resource value: 0x7F0301B2 + public const int textStartPadding = 2130903474; + + // aapt resource value: 0x7F0301B3 + public const int theme = 2130903475; + + // aapt resource value: 0x7F0301B4 + public const int thickness = 2130903476; + + // aapt resource value: 0x7F0301B5 + public const int thumbTextPadding = 2130903477; + + // aapt resource value: 0x7F0301B6 + public const int thumbTint = 2130903478; + + // aapt resource value: 0x7F0301B7 + public const int thumbTintMode = 2130903479; + + // aapt resource value: 0x7F0301B8 + public const int tickMark = 2130903480; + + // aapt resource value: 0x7F0301B9 + public const int tickMarkTint = 2130903481; + + // aapt resource value: 0x7F0301BA + public const int tickMarkTintMode = 2130903482; + + // aapt resource value: 0x7F0301BB + public const int tint = 2130903483; + + // aapt resource value: 0x7F0301BC + public const int tintMode = 2130903484; + + // aapt resource value: 0x7F0301BD + public const int title = 2130903485; + + // aapt resource value: 0x7F0301BE + public const int titleEnabled = 2130903486; + + // aapt resource value: 0x7F0301BF + public const int titleMargin = 2130903487; + + // aapt resource value: 0x7F0301C0 + public const int titleMarginBottom = 2130903488; + + // aapt resource value: 0x7F0301C1 + public const int titleMarginEnd = 2130903489; + + // aapt resource value: 0x7F0301C4 + public const int titleMargins = 2130903492; + + // aapt resource value: 0x7F0301C2 + public const int titleMarginStart = 2130903490; + + // aapt resource value: 0x7F0301C3 + public const int titleMarginTop = 2130903491; + + // aapt resource value: 0x7F0301C5 + public const int titleTextAppearance = 2130903493; + + // aapt resource value: 0x7F0301C6 + public const int titleTextColor = 2130903494; + + // aapt resource value: 0x7F0301C7 + public const int titleTextStyle = 2130903495; + + // aapt resource value: 0x7F0301C8 + public const int toolbarId = 2130903496; + + // aapt resource value: 0x7F0301C9 + public const int toolbarNavigationButtonStyle = 2130903497; + + // aapt resource value: 0x7F0301CA + public const int toolbarStyle = 2130903498; + + // aapt resource value: 0x7F0301CB + public const int tooltipForegroundColor = 2130903499; + + // aapt resource value: 0x7F0301CC + public const int tooltipFrameBackground = 2130903500; + + // aapt resource value: 0x7F0301CD + public const int tooltipText = 2130903501; + + // aapt resource value: 0x7F0301CE + public const int track = 2130903502; + + // aapt resource value: 0x7F0301CF + public const int trackTint = 2130903503; + + // aapt resource value: 0x7F0301D0 + public const int trackTintMode = 2130903504; + + // aapt resource value: 0x7F0301D1 + public const int ttcIndex = 2130903505; + + // aapt resource value: 0x7F0301D2 + public const int useCompatPadding = 2130903506; + + // aapt resource value: 0x7F0301D3 + public const int viewInflaterClass = 2130903507; + + // aapt resource value: 0x7F0301D4 + public const int voiceIcon = 2130903508; + + // aapt resource value: 0x7F0301D5 + public const int windowActionBar = 2130903509; + + // aapt resource value: 0x7F0301D6 + public const int windowActionBarOverlay = 2130903510; + + // aapt resource value: 0x7F0301D7 + public const int windowActionModeOverlay = 2130903511; + + // aapt resource value: 0x7F0301D8 + public const int windowFixedHeightMajor = 2130903512; + + // aapt resource value: 0x7F0301D9 + public const int windowFixedHeightMinor = 2130903513; + + // aapt resource value: 0x7F0301DA + public const int windowFixedWidthMajor = 2130903514; + + // aapt resource value: 0x7F0301DB + public const int windowFixedWidthMinor = 2130903515; + + // aapt resource value: 0x7F0301DC + public const int windowMinWidthMajor = 2130903516; + + // aapt resource value: 0x7F0301DD + public const int windowMinWidthMinor = 2130903517; + + // aapt resource value: 0x7F0301DE + public const int windowNoTitle = 2130903518; + + static Attribute() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Attribute() + { + } + } + + public partial class Boolean + { + + // aapt resource value: 0x7F040000 + public const int abc_action_bar_embed_tabs = 2130968576; + + // aapt resource value: 0x7F040001 + public const int abc_allow_stacked_button_bar = 2130968577; + + // aapt resource value: 0x7F040002 + public const int abc_config_actionMenuItemAllCaps = 2130968578; + + // aapt resource value: 0x7F040003 + public const int mtrl_btn_textappearance_all_caps = 2130968579; + + static Boolean() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Boolean() + { + } + } + + public partial class Color + { + + // aapt resource value: 0x7F050000 + public const int abc_background_cache_hint_selector_material_dark = 2131034112; + + // aapt resource value: 0x7F050001 + public const int abc_background_cache_hint_selector_material_light = 2131034113; + + // aapt resource value: 0x7F050002 + public const int abc_btn_colored_borderless_text_material = 2131034114; + + // aapt resource value: 0x7F050003 + public const int abc_btn_colored_text_material = 2131034115; + + // aapt resource value: 0x7F050004 + public const int abc_color_highlight_material = 2131034116; + + // aapt resource value: 0x7F050005 + public const int abc_hint_foreground_material_dark = 2131034117; + + // aapt resource value: 0x7F050006 + public const int abc_hint_foreground_material_light = 2131034118; + + // aapt resource value: 0x7F050007 + public const int abc_input_method_navigation_guard = 2131034119; + + // aapt resource value: 0x7F050008 + public const int abc_primary_text_disable_only_material_dark = 2131034120; + + // aapt resource value: 0x7F050009 + public const int abc_primary_text_disable_only_material_light = 2131034121; + + // aapt resource value: 0x7F05000A + public const int abc_primary_text_material_dark = 2131034122; + + // aapt resource value: 0x7F05000B + public const int abc_primary_text_material_light = 2131034123; + + // aapt resource value: 0x7F05000C + public const int abc_search_url_text = 2131034124; + + // aapt resource value: 0x7F05000D + public const int abc_search_url_text_normal = 2131034125; + + // aapt resource value: 0x7F05000E + public const int abc_search_url_text_pressed = 2131034126; + + // aapt resource value: 0x7F05000F + public const int abc_search_url_text_selected = 2131034127; + + // aapt resource value: 0x7F050010 + public const int abc_secondary_text_material_dark = 2131034128; + + // aapt resource value: 0x7F050011 + public const int abc_secondary_text_material_light = 2131034129; + + // aapt resource value: 0x7F050012 + public const int abc_tint_btn_checkable = 2131034130; + + // aapt resource value: 0x7F050013 + public const int abc_tint_default = 2131034131; + + // aapt resource value: 0x7F050014 + public const int abc_tint_edittext = 2131034132; + + // aapt resource value: 0x7F050015 + public const int abc_tint_seek_thumb = 2131034133; + + // aapt resource value: 0x7F050016 + public const int abc_tint_spinner = 2131034134; + + // aapt resource value: 0x7F050017 + public const int abc_tint_switch_track = 2131034135; + + // aapt resource value: 0x7F050018 + public const int accent_material_dark = 2131034136; + + // aapt resource value: 0x7F050019 + public const int accent_material_light = 2131034137; + + // aapt resource value: 0x7F05001A + public const int background_floating_material_dark = 2131034138; + + // aapt resource value: 0x7F05001B + public const int background_floating_material_light = 2131034139; + + // aapt resource value: 0x7F05001C + public const int background_material_dark = 2131034140; + + // aapt resource value: 0x7F05001D + public const int background_material_light = 2131034141; + + // aapt resource value: 0x7F05001E + public const int bright_foreground_disabled_material_dark = 2131034142; + + // aapt resource value: 0x7F05001F + public const int bright_foreground_disabled_material_light = 2131034143; + + // aapt resource value: 0x7F050020 + public const int bright_foreground_inverse_material_dark = 2131034144; + + // aapt resource value: 0x7F050021 + public const int bright_foreground_inverse_material_light = 2131034145; + + // aapt resource value: 0x7F050022 + public const int bright_foreground_material_dark = 2131034146; + + // aapt resource value: 0x7F050023 + public const int bright_foreground_material_light = 2131034147; + + // aapt resource value: 0x7F050024 + public const int browser_actions_bg_grey = 2131034148; + + // aapt resource value: 0x7F050025 + public const int browser_actions_divider_color = 2131034149; + + // aapt resource value: 0x7F050026 + public const int browser_actions_text_color = 2131034150; + + // aapt resource value: 0x7F050027 + public const int browser_actions_title_color = 2131034151; + + // aapt resource value: 0x7F050028 + public const int button_material_dark = 2131034152; + + // aapt resource value: 0x7F050029 + public const int button_material_light = 2131034153; + + // aapt resource value: 0x7F05002A + public const int cardview_dark_background = 2131034154; + + // aapt resource value: 0x7F05002B + public const int cardview_light_background = 2131034155; + + // aapt resource value: 0x7F05002C + public const int cardview_shadow_end_color = 2131034156; + + // aapt resource value: 0x7F05002D + public const int cardview_shadow_start_color = 2131034157; + + // aapt resource value: 0x7F05002E + public const int colorAccent = 2131034158; + + // aapt resource value: 0x7F05002F + public const int colorPrimary = 2131034159; + + // aapt resource value: 0x7F050030 + public const int colorPrimaryDark = 2131034160; + + // aapt resource value: 0x7F050031 + public const int design_bottom_navigation_shadow_color = 2131034161; + + // aapt resource value: 0x7F050032 + public const int design_default_color_primary = 2131034162; + + // aapt resource value: 0x7F050033 + public const int design_default_color_primary_dark = 2131034163; + + // aapt resource value: 0x7F050034 + public const int design_error = 2131034164; + + // aapt resource value: 0x7F050035 + public const int design_fab_shadow_end_color = 2131034165; + + // aapt resource value: 0x7F050036 + public const int design_fab_shadow_mid_color = 2131034166; + + // aapt resource value: 0x7F050037 + public const int design_fab_shadow_start_color = 2131034167; + + // aapt resource value: 0x7F050038 + public const int design_fab_stroke_end_inner_color = 2131034168; + + // aapt resource value: 0x7F050039 + public const int design_fab_stroke_end_outer_color = 2131034169; + + // aapt resource value: 0x7F05003A + public const int design_fab_stroke_top_inner_color = 2131034170; + + // aapt resource value: 0x7F05003B + public const int design_fab_stroke_top_outer_color = 2131034171; + + // aapt resource value: 0x7F05003C + public const int design_snackbar_background_color = 2131034172; + + // aapt resource value: 0x7F05003D + public const int design_tint_password_toggle = 2131034173; + + // aapt resource value: 0x7F05003E + public const int dim_foreground_disabled_material_dark = 2131034174; + + // aapt resource value: 0x7F05003F + public const int dim_foreground_disabled_material_light = 2131034175; + + // aapt resource value: 0x7F050040 + public const int dim_foreground_material_dark = 2131034176; + + // aapt resource value: 0x7F050041 + public const int dim_foreground_material_light = 2131034177; + + // aapt resource value: 0x7F050042 + public const int error_color_material_dark = 2131034178; + + // aapt resource value: 0x7F050043 + public const int error_color_material_light = 2131034179; + + // aapt resource value: 0x7F050044 + public const int foreground_material_dark = 2131034180; + + // aapt resource value: 0x7F050045 + public const int foreground_material_light = 2131034181; + + // aapt resource value: 0x7F050046 + public const int highlighted_text_material_dark = 2131034182; + + // aapt resource value: 0x7F050047 + public const int highlighted_text_material_light = 2131034183; + + // aapt resource value: 0x7F050048 + public const int launcher_background = 2131034184; + + // aapt resource value: 0x7F050049 + public const int material_blue_grey_800 = 2131034185; + + // aapt resource value: 0x7F05004A + public const int material_blue_grey_900 = 2131034186; + + // aapt resource value: 0x7F05004B + public const int material_blue_grey_950 = 2131034187; + + // aapt resource value: 0x7F05004C + public const int material_deep_teal_200 = 2131034188; + + // aapt resource value: 0x7F05004D + public const int material_deep_teal_500 = 2131034189; + + // aapt resource value: 0x7F05004E + public const int material_grey_100 = 2131034190; + + // aapt resource value: 0x7F05004F + public const int material_grey_300 = 2131034191; + + // aapt resource value: 0x7F050050 + public const int material_grey_50 = 2131034192; + + // aapt resource value: 0x7F050051 + public const int material_grey_600 = 2131034193; + + // aapt resource value: 0x7F050052 + public const int material_grey_800 = 2131034194; + + // aapt resource value: 0x7F050053 + public const int material_grey_850 = 2131034195; + + // aapt resource value: 0x7F050054 + public const int material_grey_900 = 2131034196; + + // aapt resource value: 0x7F050055 + public const int mtrl_bottom_nav_colored_item_tint = 2131034197; + + // aapt resource value: 0x7F050056 + public const int mtrl_bottom_nav_item_tint = 2131034198; + + // aapt resource value: 0x7F050057 + public const int mtrl_btn_bg_color_disabled = 2131034199; + + // aapt resource value: 0x7F050058 + public const int mtrl_btn_bg_color_selector = 2131034200; + + // aapt resource value: 0x7F050059 + public const int mtrl_btn_ripple_color = 2131034201; + + // aapt resource value: 0x7F05005A + public const int mtrl_btn_stroke_color_selector = 2131034202; + + // aapt resource value: 0x7F05005B + public const int mtrl_btn_text_btn_ripple_color = 2131034203; + + // aapt resource value: 0x7F05005C + public const int mtrl_btn_text_color_disabled = 2131034204; + + // aapt resource value: 0x7F05005D + public const int mtrl_btn_text_color_selector = 2131034205; + + // aapt resource value: 0x7F05005E + public const int mtrl_btn_transparent_bg_color = 2131034206; + + // aapt resource value: 0x7F05005F + public const int mtrl_chip_background_color = 2131034207; + + // aapt resource value: 0x7F050060 + public const int mtrl_chip_close_icon_tint = 2131034208; + + // aapt resource value: 0x7F050061 + public const int mtrl_chip_ripple_color = 2131034209; + + // aapt resource value: 0x7F050062 + public const int mtrl_chip_text_color = 2131034210; + + // aapt resource value: 0x7F050063 + public const int mtrl_fab_ripple_color = 2131034211; + + // aapt resource value: 0x7F050064 + public const int mtrl_scrim_color = 2131034212; + + // aapt resource value: 0x7F050065 + public const int mtrl_tabs_colored_ripple_color = 2131034213; + + // aapt resource value: 0x7F050066 + public const int mtrl_tabs_icon_color_selector = 2131034214; + + // aapt resource value: 0x7F050067 + public const int mtrl_tabs_icon_color_selector_colored = 2131034215; + + // aapt resource value: 0x7F050068 + public const int mtrl_tabs_legacy_text_color_selector = 2131034216; + + // aapt resource value: 0x7F050069 + public const int mtrl_tabs_ripple_color = 2131034217; + + // aapt resource value: 0x7F05006B + public const int mtrl_textinput_default_box_stroke_color = 2131034219; + + // aapt resource value: 0x7F05006C + public const int mtrl_textinput_disabled_color = 2131034220; + + // aapt resource value: 0x7F05006D + public const int mtrl_textinput_filled_box_default_background_color = 2131034221; + + // aapt resource value: 0x7F05006E + public const int mtrl_textinput_hovered_box_stroke_color = 2131034222; + + // aapt resource value: 0x7F05006A + public const int mtrl_text_btn_text_color_selector = 2131034218; + + // aapt resource value: 0x7F05006F + public const int notification_action_color_filter = 2131034223; + + // aapt resource value: 0x7F050070 + public const int notification_icon_bg_color = 2131034224; + + // aapt resource value: 0x7F050071 + public const int notification_material_background_media_default_color = 2131034225; + + // aapt resource value: 0x7F050072 + public const int primary_dark_material_dark = 2131034226; + + // aapt resource value: 0x7F050073 + public const int primary_dark_material_light = 2131034227; + + // aapt resource value: 0x7F050074 + public const int primary_material_dark = 2131034228; + + // aapt resource value: 0x7F050075 + public const int primary_material_light = 2131034229; + + // aapt resource value: 0x7F050076 + public const int primary_text_default_material_dark = 2131034230; + + // aapt resource value: 0x7F050077 + public const int primary_text_default_material_light = 2131034231; + + // aapt resource value: 0x7F050078 + public const int primary_text_disabled_material_dark = 2131034232; + + // aapt resource value: 0x7F050079 + public const int primary_text_disabled_material_light = 2131034233; + + // aapt resource value: 0x7F05007A + public const int ripple_material_dark = 2131034234; + + // aapt resource value: 0x7F05007B + public const int ripple_material_light = 2131034235; + + // aapt resource value: 0x7F05007C + public const int secondary_text_default_material_dark = 2131034236; + + // aapt resource value: 0x7F05007D + public const int secondary_text_default_material_light = 2131034237; + + // aapt resource value: 0x7F05007E + public const int secondary_text_disabled_material_dark = 2131034238; + + // aapt resource value: 0x7F05007F + public const int secondary_text_disabled_material_light = 2131034239; + + // aapt resource value: 0x7F050080 + public const int switch_thumb_disabled_material_dark = 2131034240; + + // aapt resource value: 0x7F050081 + public const int switch_thumb_disabled_material_light = 2131034241; + + // aapt resource value: 0x7F050082 + public const int switch_thumb_material_dark = 2131034242; + + // aapt resource value: 0x7F050083 + public const int switch_thumb_material_light = 2131034243; + + // aapt resource value: 0x7F050084 + public const int switch_thumb_normal_material_dark = 2131034244; + + // aapt resource value: 0x7F050085 + public const int switch_thumb_normal_material_light = 2131034245; + + // aapt resource value: 0x7F050086 + public const int tooltip_background_dark = 2131034246; + + // aapt resource value: 0x7F050087 + public const int tooltip_background_light = 2131034247; + + static Color() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Color() + { + } + } + + public partial class Dimension + { + + // aapt resource value: 0x7F060000 + public const int abc_action_bar_content_inset_material = 2131099648; + + // aapt resource value: 0x7F060001 + public const int abc_action_bar_content_inset_with_nav = 2131099649; + + // aapt resource value: 0x7F060002 + public const int abc_action_bar_default_height_material = 2131099650; + + // aapt resource value: 0x7F060003 + public const int abc_action_bar_default_padding_end_material = 2131099651; + + // aapt resource value: 0x7F060004 + public const int abc_action_bar_default_padding_start_material = 2131099652; + + // aapt resource value: 0x7F060005 + public const int abc_action_bar_elevation_material = 2131099653; + + // aapt resource value: 0x7F060006 + public const int abc_action_bar_icon_vertical_padding_material = 2131099654; + + // aapt resource value: 0x7F060007 + public const int abc_action_bar_overflow_padding_end_material = 2131099655; + + // aapt resource value: 0x7F060008 + public const int abc_action_bar_overflow_padding_start_material = 2131099656; + + // aapt resource value: 0x7F060009 + public const int abc_action_bar_stacked_max_height = 2131099657; + + // aapt resource value: 0x7F06000A + public const int abc_action_bar_stacked_tab_max_width = 2131099658; + + // aapt resource value: 0x7F06000B + public const int abc_action_bar_subtitle_bottom_margin_material = 2131099659; + + // aapt resource value: 0x7F06000C + public const int abc_action_bar_subtitle_top_margin_material = 2131099660; + + // aapt resource value: 0x7F06000D + public const int abc_action_button_min_height_material = 2131099661; + + // aapt resource value: 0x7F06000E + public const int abc_action_button_min_width_material = 2131099662; + + // aapt resource value: 0x7F06000F + public const int abc_action_button_min_width_overflow_material = 2131099663; + + // aapt resource value: 0x7F060010 + public const int abc_alert_dialog_button_bar_height = 2131099664; + + // aapt resource value: 0x7F060011 + public const int abc_alert_dialog_button_dimen = 2131099665; + + // aapt resource value: 0x7F060012 + public const int abc_button_inset_horizontal_material = 2131099666; + + // aapt resource value: 0x7F060013 + public const int abc_button_inset_vertical_material = 2131099667; + + // aapt resource value: 0x7F060014 + public const int abc_button_padding_horizontal_material = 2131099668; + + // aapt resource value: 0x7F060015 + public const int abc_button_padding_vertical_material = 2131099669; + + // aapt resource value: 0x7F060016 + public const int abc_cascading_menus_min_smallest_width = 2131099670; + + // aapt resource value: 0x7F060017 + public const int abc_config_prefDialogWidth = 2131099671; + + // aapt resource value: 0x7F060018 + public const int abc_control_corner_material = 2131099672; + + // aapt resource value: 0x7F060019 + public const int abc_control_inset_material = 2131099673; + + // aapt resource value: 0x7F06001A + public const int abc_control_padding_material = 2131099674; + + // aapt resource value: 0x7F06001B + public const int abc_dialog_corner_radius_material = 2131099675; + + // aapt resource value: 0x7F06001C + public const int abc_dialog_fixed_height_major = 2131099676; + + // aapt resource value: 0x7F06001D + public const int abc_dialog_fixed_height_minor = 2131099677; + + // aapt resource value: 0x7F06001E + public const int abc_dialog_fixed_width_major = 2131099678; + + // aapt resource value: 0x7F06001F + public const int abc_dialog_fixed_width_minor = 2131099679; + + // aapt resource value: 0x7F060020 + public const int abc_dialog_list_padding_bottom_no_buttons = 2131099680; + + // aapt resource value: 0x7F060021 + public const int abc_dialog_list_padding_top_no_title = 2131099681; + + // aapt resource value: 0x7F060022 + public const int abc_dialog_min_width_major = 2131099682; + + // aapt resource value: 0x7F060023 + public const int abc_dialog_min_width_minor = 2131099683; + + // aapt resource value: 0x7F060024 + public const int abc_dialog_padding_material = 2131099684; + + // aapt resource value: 0x7F060025 + public const int abc_dialog_padding_top_material = 2131099685; + + // aapt resource value: 0x7F060026 + public const int abc_dialog_title_divider_material = 2131099686; + + // aapt resource value: 0x7F060027 + public const int abc_disabled_alpha_material_dark = 2131099687; + + // aapt resource value: 0x7F060028 + public const int abc_disabled_alpha_material_light = 2131099688; + + // aapt resource value: 0x7F060029 + public const int abc_dropdownitem_icon_width = 2131099689; + + // aapt resource value: 0x7F06002A + public const int abc_dropdownitem_text_padding_left = 2131099690; + + // aapt resource value: 0x7F06002B + public const int abc_dropdownitem_text_padding_right = 2131099691; + + // aapt resource value: 0x7F06002C + public const int abc_edit_text_inset_bottom_material = 2131099692; + + // aapt resource value: 0x7F06002D + public const int abc_edit_text_inset_horizontal_material = 2131099693; + + // aapt resource value: 0x7F06002E + public const int abc_edit_text_inset_top_material = 2131099694; + + // aapt resource value: 0x7F06002F + public const int abc_floating_window_z = 2131099695; + + // aapt resource value: 0x7F060030 + public const int abc_list_item_padding_horizontal_material = 2131099696; + + // aapt resource value: 0x7F060031 + public const int abc_panel_menu_list_width = 2131099697; + + // aapt resource value: 0x7F060032 + public const int abc_progress_bar_height_material = 2131099698; + + // aapt resource value: 0x7F060033 + public const int abc_search_view_preferred_height = 2131099699; + + // aapt resource value: 0x7F060034 + public const int abc_search_view_preferred_width = 2131099700; + + // aapt resource value: 0x7F060035 + public const int abc_seekbar_track_background_height_material = 2131099701; + + // aapt resource value: 0x7F060036 + public const int abc_seekbar_track_progress_height_material = 2131099702; + + // aapt resource value: 0x7F060037 + public const int abc_select_dialog_padding_start_material = 2131099703; + + // aapt resource value: 0x7F060038 + public const int abc_switch_padding = 2131099704; + + // aapt resource value: 0x7F060039 + public const int abc_text_size_body_1_material = 2131099705; + + // aapt resource value: 0x7F06003A + public const int abc_text_size_body_2_material = 2131099706; + + // aapt resource value: 0x7F06003B + public const int abc_text_size_button_material = 2131099707; + + // aapt resource value: 0x7F06003C + public const int abc_text_size_caption_material = 2131099708; + + // aapt resource value: 0x7F06003D + public const int abc_text_size_display_1_material = 2131099709; + + // aapt resource value: 0x7F06003E + public const int abc_text_size_display_2_material = 2131099710; + + // aapt resource value: 0x7F06003F + public const int abc_text_size_display_3_material = 2131099711; + + // aapt resource value: 0x7F060040 + public const int abc_text_size_display_4_material = 2131099712; + + // aapt resource value: 0x7F060041 + public const int abc_text_size_headline_material = 2131099713; + + // aapt resource value: 0x7F060042 + public const int abc_text_size_large_material = 2131099714; + + // aapt resource value: 0x7F060043 + public const int abc_text_size_medium_material = 2131099715; + + // aapt resource value: 0x7F060044 + public const int abc_text_size_menu_header_material = 2131099716; + + // aapt resource value: 0x7F060045 + public const int abc_text_size_menu_material = 2131099717; + + // aapt resource value: 0x7F060046 + public const int abc_text_size_small_material = 2131099718; + + // aapt resource value: 0x7F060047 + public const int abc_text_size_subhead_material = 2131099719; + + // aapt resource value: 0x7F060048 + public const int abc_text_size_subtitle_material_toolbar = 2131099720; + + // aapt resource value: 0x7F060049 + public const int abc_text_size_title_material = 2131099721; + + // aapt resource value: 0x7F06004A + public const int abc_text_size_title_material_toolbar = 2131099722; + + // aapt resource value: 0x7F06004B + public const int browser_actions_context_menu_max_width = 2131099723; + + // aapt resource value: 0x7F06004C + public const int browser_actions_context_menu_min_padding = 2131099724; + + // aapt resource value: 0x7F06004D + public const int cardview_compat_inset_shadow = 2131099725; + + // aapt resource value: 0x7F06004E + public const int cardview_default_elevation = 2131099726; + + // aapt resource value: 0x7F06004F + public const int cardview_default_radius = 2131099727; + + // aapt resource value: 0x7F060050 + public const int compat_button_inset_horizontal_material = 2131099728; + + // aapt resource value: 0x7F060051 + public const int compat_button_inset_vertical_material = 2131099729; + + // aapt resource value: 0x7F060052 + public const int compat_button_padding_horizontal_material = 2131099730; + + // aapt resource value: 0x7F060053 + public const int compat_button_padding_vertical_material = 2131099731; + + // aapt resource value: 0x7F060054 + public const int compat_control_corner_material = 2131099732; + + // aapt resource value: 0x7F060055 + public const int compat_notification_large_icon_max_height = 2131099733; + + // aapt resource value: 0x7F060056 + public const int compat_notification_large_icon_max_width = 2131099734; + + // aapt resource value: 0x7F060057 + public const int design_appbar_elevation = 2131099735; + + // aapt resource value: 0x7F060058 + public const int design_bottom_navigation_active_item_max_width = 2131099736; + + // aapt resource value: 0x7F060059 + public const int design_bottom_navigation_active_item_min_width = 2131099737; + + // aapt resource value: 0x7F06005A + public const int design_bottom_navigation_active_text_size = 2131099738; + + // aapt resource value: 0x7F06005B + public const int design_bottom_navigation_elevation = 2131099739; + + // aapt resource value: 0x7F06005C + public const int design_bottom_navigation_height = 2131099740; + + // aapt resource value: 0x7F06005D + public const int design_bottom_navigation_icon_size = 2131099741; + + // aapt resource value: 0x7F06005E + public const int design_bottom_navigation_item_max_width = 2131099742; + + // aapt resource value: 0x7F06005F + public const int design_bottom_navigation_item_min_width = 2131099743; + + // aapt resource value: 0x7F060060 + public const int design_bottom_navigation_margin = 2131099744; + + // aapt resource value: 0x7F060061 + public const int design_bottom_navigation_shadow_height = 2131099745; + + // aapt resource value: 0x7F060062 + public const int design_bottom_navigation_text_size = 2131099746; + + // aapt resource value: 0x7F060063 + public const int design_bottom_sheet_modal_elevation = 2131099747; + + // aapt resource value: 0x7F060064 + public const int design_bottom_sheet_peek_height_min = 2131099748; + + // aapt resource value: 0x7F060065 + public const int design_fab_border_width = 2131099749; + + // aapt resource value: 0x7F060066 + public const int design_fab_elevation = 2131099750; + + // aapt resource value: 0x7F060067 + public const int design_fab_image_size = 2131099751; + + // aapt resource value: 0x7F060068 + public const int design_fab_size_mini = 2131099752; + + // aapt resource value: 0x7F060069 + public const int design_fab_size_normal = 2131099753; + + // aapt resource value: 0x7F06006A + public const int design_fab_translation_z_hovered_focused = 2131099754; + + // aapt resource value: 0x7F06006B + public const int design_fab_translation_z_pressed = 2131099755; + + // aapt resource value: 0x7F06006C + public const int design_navigation_elevation = 2131099756; + + // aapt resource value: 0x7F06006D + public const int design_navigation_icon_padding = 2131099757; + + // aapt resource value: 0x7F06006E + public const int design_navigation_icon_size = 2131099758; + + // aapt resource value: 0x7F06006F + public const int design_navigation_item_horizontal_padding = 2131099759; + + // aapt resource value: 0x7F060070 + public const int design_navigation_item_icon_padding = 2131099760; + + // aapt resource value: 0x7F060071 + public const int design_navigation_max_width = 2131099761; + + // aapt resource value: 0x7F060072 + public const int design_navigation_padding_bottom = 2131099762; + + // aapt resource value: 0x7F060073 + public const int design_navigation_separator_vertical_padding = 2131099763; + + // aapt resource value: 0x7F060074 + public const int design_snackbar_action_inline_max_width = 2131099764; + + // aapt resource value: 0x7F060075 + public const int design_snackbar_background_corner_radius = 2131099765; + + // aapt resource value: 0x7F060076 + public const int design_snackbar_elevation = 2131099766; + + // aapt resource value: 0x7F060077 + public const int design_snackbar_extra_spacing_horizontal = 2131099767; + + // aapt resource value: 0x7F060078 + public const int design_snackbar_max_width = 2131099768; + + // aapt resource value: 0x7F060079 + public const int design_snackbar_min_width = 2131099769; + + // aapt resource value: 0x7F06007A + public const int design_snackbar_padding_horizontal = 2131099770; + + // aapt resource value: 0x7F06007B + public const int design_snackbar_padding_vertical = 2131099771; + + // aapt resource value: 0x7F06007C + public const int design_snackbar_padding_vertical_2lines = 2131099772; + + // aapt resource value: 0x7F06007D + public const int design_snackbar_text_size = 2131099773; + + // aapt resource value: 0x7F06007E + public const int design_tab_max_width = 2131099774; + + // aapt resource value: 0x7F06007F + public const int design_tab_scrollable_min_width = 2131099775; + + // aapt resource value: 0x7F060080 + public const int design_tab_text_size = 2131099776; + + // aapt resource value: 0x7F060081 + public const int design_tab_text_size_2line = 2131099777; + + // aapt resource value: 0x7F060082 + public const int design_textinput_caption_translate_y = 2131099778; + + // aapt resource value: 0x7F060083 + public const int disabled_alpha_material_dark = 2131099779; + + // aapt resource value: 0x7F060084 + public const int disabled_alpha_material_light = 2131099780; + + // aapt resource value: 0x7F060085 + public const int fastscroll_default_thickness = 2131099781; + + // aapt resource value: 0x7F060086 + public const int fastscroll_margin = 2131099782; + + // aapt resource value: 0x7F060087 + public const int fastscroll_minimum_range = 2131099783; + + // aapt resource value: 0x7F060088 + public const int highlight_alpha_material_colored = 2131099784; + + // aapt resource value: 0x7F060089 + public const int highlight_alpha_material_dark = 2131099785; + + // aapt resource value: 0x7F06008A + public const int highlight_alpha_material_light = 2131099786; + + // aapt resource value: 0x7F06008B + public const int hint_alpha_material_dark = 2131099787; + + // aapt resource value: 0x7F06008C + public const int hint_alpha_material_light = 2131099788; + + // aapt resource value: 0x7F06008D + public const int hint_pressed_alpha_material_dark = 2131099789; + + // aapt resource value: 0x7F06008E + public const int hint_pressed_alpha_material_light = 2131099790; + + // aapt resource value: 0x7F06008F + public const int item_touch_helper_max_drag_scroll_per_frame = 2131099791; + + // aapt resource value: 0x7F060090 + public const int item_touch_helper_swipe_escape_max_velocity = 2131099792; + + // aapt resource value: 0x7F060091 + public const int item_touch_helper_swipe_escape_velocity = 2131099793; + + // aapt resource value: 0x7F060092 + public const int mtrl_bottomappbar_fabOffsetEndMode = 2131099794; + + // aapt resource value: 0x7F060093 + public const int mtrl_bottomappbar_fab_cradle_margin = 2131099795; + + // aapt resource value: 0x7F060094 + public const int mtrl_bottomappbar_fab_cradle_rounded_corner_radius = 2131099796; + + // aapt resource value: 0x7F060095 + public const int mtrl_bottomappbar_fab_cradle_vertical_offset = 2131099797; + + // aapt resource value: 0x7F060096 + public const int mtrl_bottomappbar_height = 2131099798; + + // aapt resource value: 0x7F060097 + public const int mtrl_btn_corner_radius = 2131099799; + + // aapt resource value: 0x7F060098 + public const int mtrl_btn_dialog_btn_min_width = 2131099800; + + // aapt resource value: 0x7F060099 + public const int mtrl_btn_disabled_elevation = 2131099801; + + // aapt resource value: 0x7F06009A + public const int mtrl_btn_disabled_z = 2131099802; + + // aapt resource value: 0x7F06009B + public const int mtrl_btn_elevation = 2131099803; + + // aapt resource value: 0x7F06009C + public const int mtrl_btn_focused_z = 2131099804; + + // aapt resource value: 0x7F06009D + public const int mtrl_btn_hovered_z = 2131099805; + + // aapt resource value: 0x7F06009E + public const int mtrl_btn_icon_btn_padding_left = 2131099806; + + // aapt resource value: 0x7F06009F + public const int mtrl_btn_icon_padding = 2131099807; + + // aapt resource value: 0x7F0600A0 + public const int mtrl_btn_inset = 2131099808; + + // aapt resource value: 0x7F0600A1 + public const int mtrl_btn_letter_spacing = 2131099809; + + // aapt resource value: 0x7F0600A2 + public const int mtrl_btn_padding_bottom = 2131099810; + + // aapt resource value: 0x7F0600A3 + public const int mtrl_btn_padding_left = 2131099811; + + // aapt resource value: 0x7F0600A4 + public const int mtrl_btn_padding_right = 2131099812; + + // aapt resource value: 0x7F0600A5 + public const int mtrl_btn_padding_top = 2131099813; + + // aapt resource value: 0x7F0600A6 + public const int mtrl_btn_pressed_z = 2131099814; + + // aapt resource value: 0x7F0600A7 + public const int mtrl_btn_stroke_size = 2131099815; + + // aapt resource value: 0x7F0600A8 + public const int mtrl_btn_text_btn_icon_padding = 2131099816; + + // aapt resource value: 0x7F0600A9 + public const int mtrl_btn_text_btn_padding_left = 2131099817; + + // aapt resource value: 0x7F0600AA + public const int mtrl_btn_text_btn_padding_right = 2131099818; + + // aapt resource value: 0x7F0600AB + public const int mtrl_btn_text_size = 2131099819; + + // aapt resource value: 0x7F0600AC + public const int mtrl_btn_z = 2131099820; + + // aapt resource value: 0x7F0600AD + public const int mtrl_card_elevation = 2131099821; + + // aapt resource value: 0x7F0600AE + public const int mtrl_card_spacing = 2131099822; + + // aapt resource value: 0x7F0600AF + public const int mtrl_chip_pressed_translation_z = 2131099823; + + // aapt resource value: 0x7F0600B0 + public const int mtrl_chip_text_size = 2131099824; + + // aapt resource value: 0x7F0600B1 + public const int mtrl_fab_elevation = 2131099825; + + // aapt resource value: 0x7F0600B2 + public const int mtrl_fab_translation_z_hovered_focused = 2131099826; + + // aapt resource value: 0x7F0600B3 + public const int mtrl_fab_translation_z_pressed = 2131099827; + + // aapt resource value: 0x7F0600B4 + public const int mtrl_navigation_elevation = 2131099828; + + // aapt resource value: 0x7F0600B5 + public const int mtrl_navigation_item_horizontal_padding = 2131099829; + + // aapt resource value: 0x7F0600B6 + public const int mtrl_navigation_item_icon_padding = 2131099830; + + // aapt resource value: 0x7F0600B7 + public const int mtrl_snackbar_background_corner_radius = 2131099831; + + // aapt resource value: 0x7F0600B8 + public const int mtrl_snackbar_margin = 2131099832; + + // aapt resource value: 0x7F0600B9 + public const int mtrl_textinput_box_bottom_offset = 2131099833; + + // aapt resource value: 0x7F0600BA + public const int mtrl_textinput_box_corner_radius_medium = 2131099834; + + // aapt resource value: 0x7F0600BB + public const int mtrl_textinput_box_corner_radius_small = 2131099835; + + // aapt resource value: 0x7F0600BC + public const int mtrl_textinput_box_label_cutout_padding = 2131099836; + + // aapt resource value: 0x7F0600BD + public const int mtrl_textinput_box_padding_end = 2131099837; + + // aapt resource value: 0x7F0600BE + public const int mtrl_textinput_box_stroke_width_default = 2131099838; + + // aapt resource value: 0x7F0600BF + public const int mtrl_textinput_box_stroke_width_focused = 2131099839; + + // aapt resource value: 0x7F0600C0 + public const int mtrl_textinput_outline_box_expanded_padding = 2131099840; + + // aapt resource value: 0x7F0600C1 + public const int mtrl_toolbar_default_height = 2131099841; + + // aapt resource value: 0x7F0600C2 + public const int notification_action_icon_size = 2131099842; + + // aapt resource value: 0x7F0600C3 + public const int notification_action_text_size = 2131099843; + + // aapt resource value: 0x7F0600C4 + public const int notification_big_circle_margin = 2131099844; + + // aapt resource value: 0x7F0600C5 + public const int notification_content_margin_start = 2131099845; + + // aapt resource value: 0x7F0600C6 + public const int notification_large_icon_height = 2131099846; + + // aapt resource value: 0x7F0600C7 + public const int notification_large_icon_width = 2131099847; + + // aapt resource value: 0x7F0600C8 + public const int notification_main_column_padding_top = 2131099848; + + // aapt resource value: 0x7F0600C9 + public const int notification_media_narrow_margin = 2131099849; + + // aapt resource value: 0x7F0600CA + public const int notification_right_icon_size = 2131099850; + + // aapt resource value: 0x7F0600CB + public const int notification_right_side_padding_top = 2131099851; + + // aapt resource value: 0x7F0600CC + public const int notification_small_icon_background_padding = 2131099852; + + // aapt resource value: 0x7F0600CD + public const int notification_small_icon_size_as_large = 2131099853; + + // aapt resource value: 0x7F0600CE + public const int notification_subtext_size = 2131099854; + + // aapt resource value: 0x7F0600CF + public const int notification_top_pad = 2131099855; + + // aapt resource value: 0x7F0600D0 + public const int notification_top_pad_large_text = 2131099856; + + // aapt resource value: 0x7F0600D1 + public const int subtitle_corner_radius = 2131099857; + + // aapt resource value: 0x7F0600D2 + public const int subtitle_outline_width = 2131099858; + + // aapt resource value: 0x7F0600D3 + public const int subtitle_shadow_offset = 2131099859; + + // aapt resource value: 0x7F0600D4 + public const int subtitle_shadow_radius = 2131099860; + + // aapt resource value: 0x7F0600D5 + public const int tooltip_corner_radius = 2131099861; + + // aapt resource value: 0x7F0600D6 + public const int tooltip_horizontal_padding = 2131099862; + + // aapt resource value: 0x7F0600D7 + public const int tooltip_margin = 2131099863; + + // aapt resource value: 0x7F0600D8 + public const int tooltip_precise_anchor_extra_offset = 2131099864; + + // aapt resource value: 0x7F0600D9 + public const int tooltip_precise_anchor_threshold = 2131099865; + + // aapt resource value: 0x7F0600DA + public const int tooltip_vertical_padding = 2131099866; + + // aapt resource value: 0x7F0600DB + public const int tooltip_y_offset_non_touch = 2131099867; + + // aapt resource value: 0x7F0600DC + public const int tooltip_y_offset_touch = 2131099868; + + static Dimension() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Dimension() + { + } + } + + public partial class Drawable + { + + // aapt resource value: 0x7F070006 + public const int abc_ab_share_pack_mtrl_alpha = 2131165190; + + // aapt resource value: 0x7F070007 + public const int abc_action_bar_item_background_material = 2131165191; + + // aapt resource value: 0x7F070008 + public const int abc_btn_borderless_material = 2131165192; + + // aapt resource value: 0x7F070009 + public const int abc_btn_check_material = 2131165193; + + // aapt resource value: 0x7F07000A + public const int abc_btn_check_to_on_mtrl_000 = 2131165194; + + // aapt resource value: 0x7F07000B + public const int abc_btn_check_to_on_mtrl_015 = 2131165195; + + // aapt resource value: 0x7F07000C + public const int abc_btn_colored_material = 2131165196; + + // aapt resource value: 0x7F07000D + public const int abc_btn_default_mtrl_shape = 2131165197; + + // aapt resource value: 0x7F07000E + public const int abc_btn_radio_material = 2131165198; + + // aapt resource value: 0x7F07000F + public const int abc_btn_radio_to_on_mtrl_000 = 2131165199; + + // aapt resource value: 0x7F070010 + public const int abc_btn_radio_to_on_mtrl_015 = 2131165200; + + // aapt resource value: 0x7F070011 + public const int abc_btn_switch_to_on_mtrl_00001 = 2131165201; + + // aapt resource value: 0x7F070012 + public const int abc_btn_switch_to_on_mtrl_00012 = 2131165202; + + // aapt resource value: 0x7F070013 + public const int abc_cab_background_internal_bg = 2131165203; + + // aapt resource value: 0x7F070014 + public const int abc_cab_background_top_material = 2131165204; + + // aapt resource value: 0x7F070015 + public const int abc_cab_background_top_mtrl_alpha = 2131165205; + + // aapt resource value: 0x7F070016 + public const int abc_control_background_material = 2131165206; + + // aapt resource value: 0x7F070017 + public const int abc_dialog_material_background = 2131165207; + + // aapt resource value: 0x7F070018 + public const int abc_edit_text_material = 2131165208; + + // aapt resource value: 0x7F070019 + public const int abc_ic_ab_back_material = 2131165209; + + // aapt resource value: 0x7F07001A + public const int abc_ic_arrow_drop_right_black_24dp = 2131165210; + + // aapt resource value: 0x7F07001B + public const int abc_ic_clear_material = 2131165211; + + // aapt resource value: 0x7F07001C + public const int abc_ic_commit_search_api_mtrl_alpha = 2131165212; + + // aapt resource value: 0x7F07001D + public const int abc_ic_go_search_api_material = 2131165213; + + // aapt resource value: 0x7F07001E + public const int abc_ic_menu_copy_mtrl_am_alpha = 2131165214; + + // aapt resource value: 0x7F07001F + public const int abc_ic_menu_cut_mtrl_alpha = 2131165215; + + // aapt resource value: 0x7F070020 + public const int abc_ic_menu_overflow_material = 2131165216; + + // aapt resource value: 0x7F070021 + public const int abc_ic_menu_paste_mtrl_am_alpha = 2131165217; + + // aapt resource value: 0x7F070022 + public const int abc_ic_menu_selectall_mtrl_alpha = 2131165218; + + // aapt resource value: 0x7F070023 + public const int abc_ic_menu_share_mtrl_alpha = 2131165219; + + // aapt resource value: 0x7F070024 + public const int abc_ic_search_api_material = 2131165220; + + // aapt resource value: 0x7F070025 + public const int abc_ic_star_black_16dp = 2131165221; + + // aapt resource value: 0x7F070026 + public const int abc_ic_star_black_36dp = 2131165222; + + // aapt resource value: 0x7F070027 + public const int abc_ic_star_black_48dp = 2131165223; + + // aapt resource value: 0x7F070028 + public const int abc_ic_star_half_black_16dp = 2131165224; + + // aapt resource value: 0x7F070029 + public const int abc_ic_star_half_black_36dp = 2131165225; + + // aapt resource value: 0x7F07002A + public const int abc_ic_star_half_black_48dp = 2131165226; + + // aapt resource value: 0x7F07002B + public const int abc_ic_voice_search_api_material = 2131165227; + + // aapt resource value: 0x7F07002C + public const int abc_item_background_holo_dark = 2131165228; + + // aapt resource value: 0x7F07002D + public const int abc_item_background_holo_light = 2131165229; + + // aapt resource value: 0x7F07002E + public const int abc_list_divider_material = 2131165230; + + // aapt resource value: 0x7F07002F + public const int abc_list_divider_mtrl_alpha = 2131165231; + + // aapt resource value: 0x7F070030 + public const int abc_list_focused_holo = 2131165232; + + // aapt resource value: 0x7F070031 + public const int abc_list_longpressed_holo = 2131165233; + + // aapt resource value: 0x7F070032 + public const int abc_list_pressed_holo_dark = 2131165234; + + // aapt resource value: 0x7F070033 + public const int abc_list_pressed_holo_light = 2131165235; + + // aapt resource value: 0x7F070034 + public const int abc_list_selector_background_transition_holo_dark = 2131165236; + + // aapt resource value: 0x7F070035 + public const int abc_list_selector_background_transition_holo_light = 2131165237; + + // aapt resource value: 0x7F070036 + public const int abc_list_selector_disabled_holo_dark = 2131165238; + + // aapt resource value: 0x7F070037 + public const int abc_list_selector_disabled_holo_light = 2131165239; + + // aapt resource value: 0x7F070038 + public const int abc_list_selector_holo_dark = 2131165240; + + // aapt resource value: 0x7F070039 + public const int abc_list_selector_holo_light = 2131165241; + + // aapt resource value: 0x7F07003A + public const int abc_menu_hardkey_panel_mtrl_mult = 2131165242; + + // aapt resource value: 0x7F07003B + public const int abc_popup_background_mtrl_mult = 2131165243; + + // aapt resource value: 0x7F07003C + public const int abc_ratingbar_indicator_material = 2131165244; + + // aapt resource value: 0x7F07003D + public const int abc_ratingbar_material = 2131165245; + + // aapt resource value: 0x7F07003E + public const int abc_ratingbar_small_material = 2131165246; + + // aapt resource value: 0x7F07003F + public const int abc_scrubber_control_off_mtrl_alpha = 2131165247; + + // aapt resource value: 0x7F070040 + public const int abc_scrubber_control_to_pressed_mtrl_000 = 2131165248; + + // aapt resource value: 0x7F070041 + public const int abc_scrubber_control_to_pressed_mtrl_005 = 2131165249; + + // aapt resource value: 0x7F070042 + public const int abc_scrubber_primary_mtrl_alpha = 2131165250; + + // aapt resource value: 0x7F070043 + public const int abc_scrubber_track_mtrl_alpha = 2131165251; + + // aapt resource value: 0x7F070044 + public const int abc_seekbar_thumb_material = 2131165252; + + // aapt resource value: 0x7F070045 + public const int abc_seekbar_tick_mark_material = 2131165253; + + // aapt resource value: 0x7F070046 + public const int abc_seekbar_track_material = 2131165254; + + // aapt resource value: 0x7F070047 + public const int abc_spinner_mtrl_am_alpha = 2131165255; + + // aapt resource value: 0x7F070048 + public const int abc_spinner_textfield_background_material = 2131165256; + + // aapt resource value: 0x7F070049 + public const int abc_switch_thumb_material = 2131165257; + + // aapt resource value: 0x7F07004A + public const int abc_switch_track_mtrl_alpha = 2131165258; + + // aapt resource value: 0x7F07004B + public const int abc_tab_indicator_material = 2131165259; + + // aapt resource value: 0x7F07004C + public const int abc_tab_indicator_mtrl_alpha = 2131165260; + + // aapt resource value: 0x7F070054 + public const int abc_textfield_activated_mtrl_alpha = 2131165268; + + // aapt resource value: 0x7F070055 + public const int abc_textfield_default_mtrl_alpha = 2131165269; + + // aapt resource value: 0x7F070056 + public const int abc_textfield_search_activated_mtrl_alpha = 2131165270; + + // aapt resource value: 0x7F070057 + public const int abc_textfield_search_default_mtrl_alpha = 2131165271; + + // aapt resource value: 0x7F070058 + public const int abc_textfield_search_material = 2131165272; + + // aapt resource value: 0x7F07004D + public const int abc_text_cursor_material = 2131165261; + + // aapt resource value: 0x7F07004E + public const int abc_text_select_handle_left_mtrl_dark = 2131165262; + + // aapt resource value: 0x7F07004F + public const int abc_text_select_handle_left_mtrl_light = 2131165263; + + // aapt resource value: 0x7F070050 + public const int abc_text_select_handle_middle_mtrl_dark = 2131165264; + + // aapt resource value: 0x7F070051 + public const int abc_text_select_handle_middle_mtrl_light = 2131165265; + + // aapt resource value: 0x7F070052 + public const int abc_text_select_handle_right_mtrl_dark = 2131165266; + + // aapt resource value: 0x7F070053 + public const int abc_text_select_handle_right_mtrl_light = 2131165267; + + // aapt resource value: 0x7F070059 + public const int abc_vector_test = 2131165273; + + // aapt resource value: 0x7F07005A + public const int avd_hide_password = 2131165274; + + // aapt resource value: 0x7F07005B + public const int avd_show_password = 2131165275; + + // aapt resource value: 0x7F07005C + public const int design_bottom_navigation_item_background = 2131165276; + + // aapt resource value: 0x7F07005D + public const int design_fab_background = 2131165277; + + // aapt resource value: 0x7F07005E + public const int design_ic_visibility = 2131165278; + + // aapt resource value: 0x7F07005F + public const int design_ic_visibility_off = 2131165279; + + // aapt resource value: 0x7F070060 + public const int design_password_eye = 2131165280; + + // aapt resource value: 0x7F070061 + public const int design_snackbar_background = 2131165281; + + // aapt resource value: 0x7F070065 + public const int icon_about = 2131165285; + + // aapt resource value: 0x7F070066 + public const int icon_feed = 2131165286; + + // aapt resource value: 0x7F070062 + public const int ic_mtrl_chip_checked_black = 2131165282; + + // aapt resource value: 0x7F070063 + public const int ic_mtrl_chip_checked_circle = 2131165283; + + // aapt resource value: 0x7F070064 + public const int ic_mtrl_chip_close_circle = 2131165284; + + // aapt resource value: 0x7F070067 + public const int mtrl_snackbar_background = 2131165287; + + // aapt resource value: 0x7F070068 + public const int mtrl_tabs_default_indicator = 2131165288; + + // aapt resource value: 0x7F070069 + public const int navigation_empty_icon = 2131165289; + + // aapt resource value: 0x7F07006A + public const int notification_action_background = 2131165290; + + // aapt resource value: 0x7F07006B + public const int notification_bg = 2131165291; + + // aapt resource value: 0x7F07006C + public const int notification_bg_low = 2131165292; + + // aapt resource value: 0x7F07006D + public const int notification_bg_low_normal = 2131165293; + + // aapt resource value: 0x7F07006E + public const int notification_bg_low_pressed = 2131165294; + + // aapt resource value: 0x7F07006F + public const int notification_bg_normal = 2131165295; + + // aapt resource value: 0x7F070070 + public const int notification_bg_normal_pressed = 2131165296; + + // aapt resource value: 0x7F070071 + public const int notification_icon_background = 2131165297; + + // aapt resource value: 0x7F070072 + public const int notification_template_icon_bg = 2131165298; + + // aapt resource value: 0x7F070073 + public const int notification_template_icon_low_bg = 2131165299; + + // aapt resource value: 0x7F070074 + public const int notification_tile_bg = 2131165300; + + // aapt resource value: 0x7F070075 + public const int notify_panel_notification_icon_bg = 2131165301; + + // aapt resource value: 0x7F070076 + public const int tooltip_frame_dark = 2131165302; + + // aapt resource value: 0x7F070077 + public const int tooltip_frame_light = 2131165303; + + // aapt resource value: 0x7F070078 + public const int xamarin_logo = 2131165304; + + static Drawable() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Drawable() + { + } + } + + public partial class Id + { + + // aapt resource value: 0x7F080006 + public const int action0 = 2131230726; + + // aapt resource value: 0x7F080018 + public const int actions = 2131230744; + + // aapt resource value: 0x7F080007 + public const int action_bar = 2131230727; + + // aapt resource value: 0x7F080008 + public const int action_bar_activity_content = 2131230728; + + // aapt resource value: 0x7F080009 + public const int action_bar_container = 2131230729; + + // aapt resource value: 0x7F08000A + public const int action_bar_root = 2131230730; + + // aapt resource value: 0x7F08000B + public const int action_bar_spinner = 2131230731; + + // aapt resource value: 0x7F08000C + public const int action_bar_subtitle = 2131230732; + + // aapt resource value: 0x7F08000D + public const int action_bar_title = 2131230733; + + // aapt resource value: 0x7F08000E + public const int action_container = 2131230734; + + // aapt resource value: 0x7F08000F + public const int action_context_bar = 2131230735; + + // aapt resource value: 0x7F080010 + public const int action_divider = 2131230736; + + // aapt resource value: 0x7F080011 + public const int action_image = 2131230737; + + // aapt resource value: 0x7F080012 + public const int action_menu_divider = 2131230738; + + // aapt resource value: 0x7F080013 + public const int action_menu_presenter = 2131230739; + + // aapt resource value: 0x7F080014 + public const int action_mode_bar = 2131230740; + + // aapt resource value: 0x7F080015 + public const int action_mode_bar_stub = 2131230741; + + // aapt resource value: 0x7F080016 + public const int action_mode_close_button = 2131230742; + + // aapt resource value: 0x7F080017 + public const int action_text = 2131230743; + + // aapt resource value: 0x7F080019 + public const int activity_chooser_view_content = 2131230745; + + // aapt resource value: 0x7F08001A + public const int add = 2131230746; + + // aapt resource value: 0x7F08001B + public const int alertTitle = 2131230747; + + // aapt resource value: 0x7F08001C + public const int all = 2131230748; + + // aapt resource value: 0x7F080000 + public const int ALT = 2131230720; + + // aapt resource value: 0x7F08001D + public const int always = 2131230749; + + // aapt resource value: 0x7F08001E + public const int async = 2131230750; + + // aapt resource value: 0x7F08001F + public const int auto = 2131230751; + + // aapt resource value: 0x7F080020 + public const int beginning = 2131230752; + + // aapt resource value: 0x7F080021 + public const int blocking = 2131230753; + + // aapt resource value: 0x7F080022 + public const int bottom = 2131230754; + + // aapt resource value: 0x7F080023 + public const int bottomtab_navarea = 2131230755; + + // aapt resource value: 0x7F080024 + public const int bottomtab_tabbar = 2131230756; + + // aapt resource value: 0x7F080025 + public const int browser_actions_header_text = 2131230757; + + // aapt resource value: 0x7F080028 + public const int browser_actions_menu_items = 2131230760; + + // aapt resource value: 0x7F080026 + public const int browser_actions_menu_item_icon = 2131230758; + + // aapt resource value: 0x7F080027 + public const int browser_actions_menu_item_text = 2131230759; + + // aapt resource value: 0x7F080029 + public const int browser_actions_menu_view = 2131230761; + + // aapt resource value: 0x7F08002A + public const int buttonPanel = 2131230762; + + // aapt resource value: 0x7F08002B + public const int cancel_action = 2131230763; + + // aapt resource value: 0x7F08002C + public const int center = 2131230764; + + // aapt resource value: 0x7F08002D + public const int center_horizontal = 2131230765; + + // aapt resource value: 0x7F08002E + public const int center_vertical = 2131230766; + + // aapt resource value: 0x7F08002F + public const int checkbox = 2131230767; + + // aapt resource value: 0x7F080030 + public const int chronometer = 2131230768; + + // aapt resource value: 0x7F080031 + public const int clip_horizontal = 2131230769; + + // aapt resource value: 0x7F080032 + public const int clip_vertical = 2131230770; + + // aapt resource value: 0x7F080033 + public const int collapseActionView = 2131230771; + + // aapt resource value: 0x7F080034 + public const int container = 2131230772; + + // aapt resource value: 0x7F080035 + public const int content = 2131230773; + + // aapt resource value: 0x7F080036 + public const int contentPanel = 2131230774; + + // aapt resource value: 0x7F080037 + public const int coordinator = 2131230775; + + // aapt resource value: 0x7F080001 + public const int CTRL = 2131230721; + + // aapt resource value: 0x7F080038 + public const int custom = 2131230776; + + // aapt resource value: 0x7F080039 + public const int customPanel = 2131230777; + + // aapt resource value: 0x7F08003A + public const int decor_content_parent = 2131230778; + + // aapt resource value: 0x7F08003B + public const int default_activity_button = 2131230779; + + // aapt resource value: 0x7F08003C + public const int design_bottom_sheet = 2131230780; + + // aapt resource value: 0x7F08003D + public const int design_menu_item_action_area = 2131230781; + + // aapt resource value: 0x7F08003E + public const int design_menu_item_action_area_stub = 2131230782; + + // aapt resource value: 0x7F08003F + public const int design_menu_item_text = 2131230783; + + // aapt resource value: 0x7F080040 + public const int design_navigation_view = 2131230784; + + // aapt resource value: 0x7F080041 + public const int disableHome = 2131230785; + + // aapt resource value: 0x7F080042 + public const int edit_query = 2131230786; + + // aapt resource value: 0x7F080043 + public const int end = 2131230787; + + // aapt resource value: 0x7F080044 + public const int end_padder = 2131230788; + + // aapt resource value: 0x7F080045 + public const int enterAlways = 2131230789; + + // aapt resource value: 0x7F080046 + public const int enterAlwaysCollapsed = 2131230790; + + // aapt resource value: 0x7F080047 + public const int exitUntilCollapsed = 2131230791; + + // aapt resource value: 0x7F080049 + public const int expanded_menu = 2131230793; + + // aapt resource value: 0x7F080048 + public const int expand_activities_button = 2131230792; + + // aapt resource value: 0x7F08004A + public const int fill = 2131230794; + + // aapt resource value: 0x7F08004D + public const int filled = 2131230797; + + // aapt resource value: 0x7F08004B + public const int fill_horizontal = 2131230795; + + // aapt resource value: 0x7F08004C + public const int fill_vertical = 2131230796; + + // aapt resource value: 0x7F08004E + public const int @fixed = 2131230798; + + // aapt resource value: 0x7F08004F + public const int flyoutcontent_appbar = 2131230799; + + // aapt resource value: 0x7F080050 + public const int flyoutcontent_recycler = 2131230800; + + // aapt resource value: 0x7F080051 + public const int forever = 2131230801; + + // aapt resource value: 0x7F080002 + public const int FUNCTION = 2131230722; + + // aapt resource value: 0x7F080052 + public const int ghost_view = 2131230802; + + // aapt resource value: 0x7F080053 + public const int group_divider = 2131230803; + + // aapt resource value: 0x7F080054 + public const int home = 2131230804; + + // aapt resource value: 0x7F080055 + public const int homeAsUp = 2131230805; + + // aapt resource value: 0x7F080056 + public const int icon = 2131230806; + + // aapt resource value: 0x7F080057 + public const int icon_group = 2131230807; + + // aapt resource value: 0x7F080058 + public const int ifRoom = 2131230808; + + // aapt resource value: 0x7F080059 + public const int image = 2131230809; + + // aapt resource value: 0x7F08005A + public const int info = 2131230810; + + // aapt resource value: 0x7F08005B + public const int italic = 2131230811; + + // aapt resource value: 0x7F08005C + public const int item_touch_helper_previous_elevation = 2131230812; + + // aapt resource value: 0x7F08005D + public const int labeled = 2131230813; + + // aapt resource value: 0x7F08005E + public const int largeLabel = 2131230814; + + // aapt resource value: 0x7F08005F + public const int left = 2131230815; + + // aapt resource value: 0x7F080060 + public const int line1 = 2131230816; + + // aapt resource value: 0x7F080061 + public const int line3 = 2131230817; + + // aapt resource value: 0x7F080062 + public const int listMode = 2131230818; + + // aapt resource value: 0x7F080063 + public const int list_item = 2131230819; + + // aapt resource value: 0x7F080064 + public const int main_appbar = 2131230820; + + // aapt resource value: 0x7F080065 + public const int main_tablayout = 2131230821; + + // aapt resource value: 0x7F080066 + public const int main_toolbar = 2131230822; + + // aapt resource value: 0x7F080067 + public const int main_viewpager = 2131230823; + + // aapt resource value: 0x7F080068 + public const int masked = 2131230824; + + // aapt resource value: 0x7F080069 + public const int media_actions = 2131230825; + + // aapt resource value: 0x7F08006A + public const int message = 2131230826; + + // aapt resource value: 0x7F080003 + public const int META = 2131230723; + + // aapt resource value: 0x7F08006B + public const int middle = 2131230827; + + // aapt resource value: 0x7F08006C + public const int mini = 2131230828; + + // aapt resource value: 0x7F08006D + public const int mtrl_child_content_container = 2131230829; + + // aapt resource value: 0x7F08006E + public const int mtrl_internal_children_alpha_tag = 2131230830; + + // aapt resource value: 0x7F08006F + public const int multiply = 2131230831; + + // aapt resource value: 0x7F080070 + public const int navigation_header_container = 2131230832; + + // aapt resource value: 0x7F080071 + public const int never = 2131230833; + + // aapt resource value: 0x7F080072 + public const int none = 2131230834; + + // aapt resource value: 0x7F080073 + public const int normal = 2131230835; + + // aapt resource value: 0x7F080074 + public const int notification_background = 2131230836; + + // aapt resource value: 0x7F080075 + public const int notification_main_column = 2131230837; + + // aapt resource value: 0x7F080076 + public const int notification_main_column_container = 2131230838; + + // aapt resource value: 0x7F080077 + public const int outline = 2131230839; + + // aapt resource value: 0x7F080078 + public const int parallax = 2131230840; + + // aapt resource value: 0x7F080079 + public const int parentPanel = 2131230841; + + // aapt resource value: 0x7F08007A + public const int parent_matrix = 2131230842; + + // aapt resource value: 0x7F08007B + public const int pin = 2131230843; + + // aapt resource value: 0x7F08007C + public const int progress_circular = 2131230844; + + // aapt resource value: 0x7F08007D + public const int progress_horizontal = 2131230845; + + // aapt resource value: 0x7F08007E + public const int radio = 2131230846; + + // aapt resource value: 0x7F08007F + public const int right = 2131230847; + + // aapt resource value: 0x7F080080 + public const int right_icon = 2131230848; + + // aapt resource value: 0x7F080081 + public const int right_side = 2131230849; + + // aapt resource value: 0x7F080082 + public const int save_image_matrix = 2131230850; + + // aapt resource value: 0x7F080083 + public const int save_non_transition_alpha = 2131230851; + + // aapt resource value: 0x7F080084 + public const int save_scale_type = 2131230852; + + // aapt resource value: 0x7F080085 + public const int screen = 2131230853; + + // aapt resource value: 0x7F080086 + public const int scroll = 2131230854; + + // aapt resource value: 0x7F08008A + public const int scrollable = 2131230858; + + // aapt resource value: 0x7F080087 + public const int scrollIndicatorDown = 2131230855; + + // aapt resource value: 0x7F080088 + public const int scrollIndicatorUp = 2131230856; + + // aapt resource value: 0x7F080089 + public const int scrollView = 2131230857; + + // aapt resource value: 0x7F08008B + public const int search_badge = 2131230859; + + // aapt resource value: 0x7F08008C + public const int search_bar = 2131230860; + + // aapt resource value: 0x7F08008D + public const int search_button = 2131230861; + + // aapt resource value: 0x7F08008E + public const int search_close_btn = 2131230862; + + // aapt resource value: 0x7F08008F + public const int search_edit_frame = 2131230863; + + // aapt resource value: 0x7F080090 + public const int search_go_btn = 2131230864; + + // aapt resource value: 0x7F080091 + public const int search_mag_icon = 2131230865; + + // aapt resource value: 0x7F080092 + public const int search_plate = 2131230866; + + // aapt resource value: 0x7F080093 + public const int search_src_text = 2131230867; + + // aapt resource value: 0x7F080094 + public const int search_voice_btn = 2131230868; + + // aapt resource value: 0x7F080096 + public const int selected = 2131230870; + + // aapt resource value: 0x7F080095 + public const int select_dialog_listview = 2131230869; + + // aapt resource value: 0x7F080097 + public const int shellcontent_appbar = 2131230871; + + // aapt resource value: 0x7F080098 + public const int shellcontent_toolbar = 2131230872; + + // aapt resource value: 0x7F080004 + public const int SHIFT = 2131230724; + + // aapt resource value: 0x7F080099 + public const int shortcut = 2131230873; + + // aapt resource value: 0x7F08009A + public const int showCustom = 2131230874; + + // aapt resource value: 0x7F08009B + public const int showHome = 2131230875; + + // aapt resource value: 0x7F08009C + public const int showTitle = 2131230876; + + // aapt resource value: 0x7F08009D + public const int sliding_tabs = 2131230877; + + // aapt resource value: 0x7F08009E + public const int smallLabel = 2131230878; + + // aapt resource value: 0x7F08009F + public const int snackbar_action = 2131230879; + + // aapt resource value: 0x7F0800A0 + public const int snackbar_text = 2131230880; + + // aapt resource value: 0x7F0800A1 + public const int snap = 2131230881; + + // aapt resource value: 0x7F0800A2 + public const int snapMargins = 2131230882; + + // aapt resource value: 0x7F0800A3 + public const int spacer = 2131230883; + + // aapt resource value: 0x7F0800A4 + public const int split_action_bar = 2131230884; + + // aapt resource value: 0x7F0800A5 + public const int src_atop = 2131230885; + + // aapt resource value: 0x7F0800A6 + public const int src_in = 2131230886; + + // aapt resource value: 0x7F0800A7 + public const int src_over = 2131230887; + + // aapt resource value: 0x7F0800A8 + public const int start = 2131230888; + + // aapt resource value: 0x7F0800A9 + public const int status_bar_latest_event_content = 2131230889; + + // aapt resource value: 0x7F0800AA + public const int stretch = 2131230890; + + // aapt resource value: 0x7F0800AB + public const int submenuarrow = 2131230891; + + // aapt resource value: 0x7F0800AC + public const int submit_area = 2131230892; + + // aapt resource value: 0x7F080005 + public const int SYM = 2131230725; + + // aapt resource value: 0x7F0800AD + public const int tabMode = 2131230893; + + // aapt resource value: 0x7F0800AE + public const int tag_transition_group = 2131230894; + + // aapt resource value: 0x7F0800AF + public const int tag_unhandled_key_event_manager = 2131230895; + + // aapt resource value: 0x7F0800B0 + public const int tag_unhandled_key_listeners = 2131230896; + + // aapt resource value: 0x7F0800B1 + public const int text = 2131230897; + + // aapt resource value: 0x7F0800B2 + public const int text2 = 2131230898; + + // aapt resource value: 0x7F0800B7 + public const int textinput_counter = 2131230903; + + // aapt resource value: 0x7F0800B8 + public const int textinput_error = 2131230904; + + // aapt resource value: 0x7F0800B9 + public const int textinput_helper_text = 2131230905; + + // aapt resource value: 0x7F0800B3 + public const int textSpacerNoButtons = 2131230899; + + // aapt resource value: 0x7F0800B4 + public const int textSpacerNoTitle = 2131230900; + + // aapt resource value: 0x7F0800B5 + public const int textStart = 2131230901; + + // aapt resource value: 0x7F0800B6 + public const int text_input_password_toggle = 2131230902; + + // aapt resource value: 0x7F0800BA + public const int time = 2131230906; + + // aapt resource value: 0x7F0800BB + public const int title = 2131230907; + + // aapt resource value: 0x7F0800BC + public const int titleDividerNoCustom = 2131230908; + + // aapt resource value: 0x7F0800BD + public const int title_template = 2131230909; + + // aapt resource value: 0x7F0800BE + public const int toolbar = 2131230910; + + // aapt resource value: 0x7F0800BF + public const int top = 2131230911; + + // aapt resource value: 0x7F0800C0 + public const int topPanel = 2131230912; + + // aapt resource value: 0x7F0800C1 + public const int touch_outside = 2131230913; + + // aapt resource value: 0x7F0800C2 + public const int transition_current_scene = 2131230914; + + // aapt resource value: 0x7F0800C3 + public const int transition_layout_save = 2131230915; + + // aapt resource value: 0x7F0800C4 + public const int transition_position = 2131230916; + + // aapt resource value: 0x7F0800C5 + public const int transition_scene_layoutid_cache = 2131230917; + + // aapt resource value: 0x7F0800C6 + public const int transition_transform = 2131230918; + + // aapt resource value: 0x7F0800C7 + public const int uniform = 2131230919; + + // aapt resource value: 0x7F0800C8 + public const int unlabeled = 2131230920; + + // aapt resource value: 0x7F0800C9 + public const int up = 2131230921; + + // aapt resource value: 0x7F0800CA + public const int useLogo = 2131230922; + + // aapt resource value: 0x7F0800CB + public const int view_offset_helper = 2131230923; + + // aapt resource value: 0x7F0800CC + public const int visible = 2131230924; + + // aapt resource value: 0x7F0800CD + public const int withText = 2131230925; + + // aapt resource value: 0x7F0800CE + public const int wrap_content = 2131230926; + + static Id() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Id() + { + } + } + + public partial class Integer + { + + // aapt resource value: 0x7F090000 + public const int abc_config_activityDefaultDur = 2131296256; + + // aapt resource value: 0x7F090001 + public const int abc_config_activityShortDur = 2131296257; + + // aapt resource value: 0x7F090002 + public const int app_bar_elevation_anim_duration = 2131296258; + + // aapt resource value: 0x7F090003 + public const int bottom_sheet_slide_duration = 2131296259; + + // aapt resource value: 0x7F090004 + public const int cancel_button_image_alpha = 2131296260; + + // aapt resource value: 0x7F090005 + public const int config_tooltipAnimTime = 2131296261; + + // aapt resource value: 0x7F090006 + public const int design_snackbar_text_max_lines = 2131296262; + + // aapt resource value: 0x7F090007 + public const int design_tab_indicator_anim_duration_ms = 2131296263; + + // aapt resource value: 0x7F090008 + public const int hide_password_duration = 2131296264; + + // aapt resource value: 0x7F090009 + public const int mtrl_btn_anim_delay_ms = 2131296265; + + // aapt resource value: 0x7F09000A + public const int mtrl_btn_anim_duration_ms = 2131296266; + + // aapt resource value: 0x7F09000B + public const int mtrl_chip_anim_duration = 2131296267; + + // aapt resource value: 0x7F09000C + public const int mtrl_tab_indicator_anim_duration_ms = 2131296268; + + // aapt resource value: 0x7F09000D + public const int show_password_duration = 2131296269; + + // aapt resource value: 0x7F09000E + public const int status_bar_notification_info_maxnum = 2131296270; + + static Integer() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Integer() + { + } + } + + public partial class Interpolator + { + + // aapt resource value: 0x7F0A0000 + public const int mtrl_fast_out_linear_in = 2131361792; + + // aapt resource value: 0x7F0A0001 + public const int mtrl_fast_out_slow_in = 2131361793; + + // aapt resource value: 0x7F0A0002 + public const int mtrl_linear = 2131361794; + + // aapt resource value: 0x7F0A0003 + public const int mtrl_linear_out_slow_in = 2131361795; + + static Interpolator() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Interpolator() + { + } + } + + public partial class Layout + { + + // aapt resource value: 0x7F0B0000 + public const int abc_action_bar_title_item = 2131427328; + + // aapt resource value: 0x7F0B0001 + public const int abc_action_bar_up_container = 2131427329; + + // aapt resource value: 0x7F0B0002 + public const int abc_action_menu_item_layout = 2131427330; + + // aapt resource value: 0x7F0B0003 + public const int abc_action_menu_layout = 2131427331; + + // aapt resource value: 0x7F0B0004 + public const int abc_action_mode_bar = 2131427332; + + // aapt resource value: 0x7F0B0005 + public const int abc_action_mode_close_item_material = 2131427333; + + // aapt resource value: 0x7F0B0006 + public const int abc_activity_chooser_view = 2131427334; + + // aapt resource value: 0x7F0B0007 + public const int abc_activity_chooser_view_list_item = 2131427335; + + // aapt resource value: 0x7F0B0008 + public const int abc_alert_dialog_button_bar_material = 2131427336; + + // aapt resource value: 0x7F0B0009 + public const int abc_alert_dialog_material = 2131427337; + + // aapt resource value: 0x7F0B000A + public const int abc_alert_dialog_title_material = 2131427338; + + // aapt resource value: 0x7F0B000B + public const int abc_cascading_menu_item_layout = 2131427339; + + // aapt resource value: 0x7F0B000C + public const int abc_dialog_title_material = 2131427340; + + // aapt resource value: 0x7F0B000D + public const int abc_expanded_menu_layout = 2131427341; + + // aapt resource value: 0x7F0B000E + public const int abc_list_menu_item_checkbox = 2131427342; + + // aapt resource value: 0x7F0B000F + public const int abc_list_menu_item_icon = 2131427343; + + // aapt resource value: 0x7F0B0010 + public const int abc_list_menu_item_layout = 2131427344; + + // aapt resource value: 0x7F0B0011 + public const int abc_list_menu_item_radio = 2131427345; + + // aapt resource value: 0x7F0B0012 + public const int abc_popup_menu_header_item_layout = 2131427346; + + // aapt resource value: 0x7F0B0013 + public const int abc_popup_menu_item_layout = 2131427347; + + // aapt resource value: 0x7F0B0014 + public const int abc_screen_content_include = 2131427348; + + // aapt resource value: 0x7F0B0015 + public const int abc_screen_simple = 2131427349; + + // aapt resource value: 0x7F0B0016 + public const int abc_screen_simple_overlay_action_mode = 2131427350; + + // aapt resource value: 0x7F0B0017 + public const int abc_screen_toolbar = 2131427351; + + // aapt resource value: 0x7F0B0018 + public const int abc_search_dropdown_item_icons_2line = 2131427352; + + // aapt resource value: 0x7F0B0019 + public const int abc_search_view = 2131427353; + + // aapt resource value: 0x7F0B001A + public const int abc_select_dialog_material = 2131427354; + + // aapt resource value: 0x7F0B001B + public const int abc_tooltip = 2131427355; + + // aapt resource value: 0x7F0B001C + public const int BottomTabLayout = 2131427356; + + // aapt resource value: 0x7F0B001D + public const int browser_actions_context_menu_page = 2131427357; + + // aapt resource value: 0x7F0B001E + public const int browser_actions_context_menu_row = 2131427358; + + // aapt resource value: 0x7F0B001F + public const int design_bottom_navigation_item = 2131427359; + + // aapt resource value: 0x7F0B0020 + public const int design_bottom_sheet_dialog = 2131427360; + + // aapt resource value: 0x7F0B0021 + public const int design_layout_snackbar = 2131427361; + + // aapt resource value: 0x7F0B0022 + public const int design_layout_snackbar_include = 2131427362; + + // aapt resource value: 0x7F0B0023 + public const int design_layout_tab_icon = 2131427363; + + // aapt resource value: 0x7F0B0024 + public const int design_layout_tab_text = 2131427364; + + // aapt resource value: 0x7F0B0025 + public const int design_menu_item_action_area = 2131427365; + + // aapt resource value: 0x7F0B0026 + public const int design_navigation_item = 2131427366; + + // aapt resource value: 0x7F0B0027 + public const int design_navigation_item_header = 2131427367; + + // aapt resource value: 0x7F0B0028 + public const int design_navigation_item_separator = 2131427368; + + // aapt resource value: 0x7F0B0029 + public const int design_navigation_item_subheader = 2131427369; + + // aapt resource value: 0x7F0B002A + public const int design_navigation_menu = 2131427370; + + // aapt resource value: 0x7F0B002B + public const int design_navigation_menu_item = 2131427371; + + // aapt resource value: 0x7F0B002C + public const int design_text_input_password_icon = 2131427372; + + // aapt resource value: 0x7F0B002D + public const int FlyoutContent = 2131427373; + + // aapt resource value: 0x7F0B002E + public const int mtrl_layout_snackbar = 2131427374; + + // aapt resource value: 0x7F0B002F + public const int mtrl_layout_snackbar_include = 2131427375; + + // aapt resource value: 0x7F0B0030 + public const int notification_action = 2131427376; + + // aapt resource value: 0x7F0B0031 + public const int notification_action_tombstone = 2131427377; + + // aapt resource value: 0x7F0B0032 + public const int notification_media_action = 2131427378; + + // aapt resource value: 0x7F0B0033 + public const int notification_media_cancel_action = 2131427379; + + // aapt resource value: 0x7F0B0034 + public const int notification_template_big_media = 2131427380; + + // aapt resource value: 0x7F0B0035 + public const int notification_template_big_media_custom = 2131427381; + + // aapt resource value: 0x7F0B0036 + public const int notification_template_big_media_narrow = 2131427382; + + // aapt resource value: 0x7F0B0037 + public const int notification_template_big_media_narrow_custom = 2131427383; + + // aapt resource value: 0x7F0B0038 + public const int notification_template_custom_big = 2131427384; + + // aapt resource value: 0x7F0B0039 + public const int notification_template_icon_group = 2131427385; + + // aapt resource value: 0x7F0B003A + public const int notification_template_lines_media = 2131427386; + + // aapt resource value: 0x7F0B003B + public const int notification_template_media = 2131427387; + + // aapt resource value: 0x7F0B003C + public const int notification_template_media_custom = 2131427388; + + // aapt resource value: 0x7F0B003D + public const int notification_template_part_chronometer = 2131427389; + + // aapt resource value: 0x7F0B003E + public const int notification_template_part_time = 2131427390; + + // aapt resource value: 0x7F0B003F + public const int RootLayout = 2131427391; + + // aapt resource value: 0x7F0B0040 + public const int select_dialog_item_material = 2131427392; + + // aapt resource value: 0x7F0B0041 + public const int select_dialog_multichoice_material = 2131427393; + + // aapt resource value: 0x7F0B0042 + public const int select_dialog_singlechoice_material = 2131427394; + + // aapt resource value: 0x7F0B0043 + public const int ShellContent = 2131427395; + + // aapt resource value: 0x7F0B0044 + public const int support_simple_spinner_dropdown_item = 2131427396; + + // aapt resource value: 0x7F0B0045 + public const int Tabbar = 2131427397; + + // aapt resource value: 0x7F0B0046 + public const int Toolbar = 2131427398; + + static Layout() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Layout() + { + } + } + + public partial class Mipmap + { + + // aapt resource value: 0x7F0C0000 + public const int icon = 2131492864; + + // aapt resource value: 0x7F0C0001 + public const int icon_round = 2131492865; + + // aapt resource value: 0x7F0C0002 + public const int launcher_foreground = 2131492866; + + static Mipmap() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Mipmap() + { + } + } + + public partial class String + { + + // aapt resource value: 0x7F0D0000 + public const int abc_action_bar_home_description = 2131558400; + + // aapt resource value: 0x7F0D0001 + public const int abc_action_bar_up_description = 2131558401; + + // aapt resource value: 0x7F0D0002 + public const int abc_action_menu_overflow_description = 2131558402; + + // aapt resource value: 0x7F0D0003 + public const int abc_action_mode_done = 2131558403; + + // aapt resource value: 0x7F0D0005 + public const int abc_activitychooserview_choose_application = 2131558405; + + // aapt resource value: 0x7F0D0004 + public const int abc_activity_chooser_view_see_all = 2131558404; + + // aapt resource value: 0x7F0D0006 + public const int abc_capital_off = 2131558406; + + // aapt resource value: 0x7F0D0007 + public const int abc_capital_on = 2131558407; + + // aapt resource value: 0x7F0D0008 + public const int abc_font_family_body_1_material = 2131558408; + + // aapt resource value: 0x7F0D0009 + public const int abc_font_family_body_2_material = 2131558409; + + // aapt resource value: 0x7F0D000A + public const int abc_font_family_button_material = 2131558410; + + // aapt resource value: 0x7F0D000B + public const int abc_font_family_caption_material = 2131558411; + + // aapt resource value: 0x7F0D000C + public const int abc_font_family_display_1_material = 2131558412; + + // aapt resource value: 0x7F0D000D + public const int abc_font_family_display_2_material = 2131558413; + + // aapt resource value: 0x7F0D000E + public const int abc_font_family_display_3_material = 2131558414; + + // aapt resource value: 0x7F0D000F + public const int abc_font_family_display_4_material = 2131558415; + + // aapt resource value: 0x7F0D0010 + public const int abc_font_family_headline_material = 2131558416; + + // aapt resource value: 0x7F0D0011 + public const int abc_font_family_menu_material = 2131558417; + + // aapt resource value: 0x7F0D0012 + public const int abc_font_family_subhead_material = 2131558418; + + // aapt resource value: 0x7F0D0013 + public const int abc_font_family_title_material = 2131558419; + + // aapt resource value: 0x7F0D0014 + public const int abc_menu_alt_shortcut_label = 2131558420; + + // aapt resource value: 0x7F0D0015 + public const int abc_menu_ctrl_shortcut_label = 2131558421; + + // aapt resource value: 0x7F0D0016 + public const int abc_menu_delete_shortcut_label = 2131558422; + + // aapt resource value: 0x7F0D0017 + public const int abc_menu_enter_shortcut_label = 2131558423; + + // aapt resource value: 0x7F0D0018 + public const int abc_menu_function_shortcut_label = 2131558424; + + // aapt resource value: 0x7F0D0019 + public const int abc_menu_meta_shortcut_label = 2131558425; + + // aapt resource value: 0x7F0D001A + public const int abc_menu_shift_shortcut_label = 2131558426; + + // aapt resource value: 0x7F0D001B + public const int abc_menu_space_shortcut_label = 2131558427; + + // aapt resource value: 0x7F0D001C + public const int abc_menu_sym_shortcut_label = 2131558428; + + // aapt resource value: 0x7F0D001D + public const int abc_prepend_shortcut_label = 2131558429; + + // aapt resource value: 0x7F0D001F + public const int abc_searchview_description_clear = 2131558431; + + // aapt resource value: 0x7F0D0020 + public const int abc_searchview_description_query = 2131558432; + + // aapt resource value: 0x7F0D0021 + public const int abc_searchview_description_search = 2131558433; + + // aapt resource value: 0x7F0D0022 + public const int abc_searchview_description_submit = 2131558434; + + // aapt resource value: 0x7F0D0023 + public const int abc_searchview_description_voice = 2131558435; + + // aapt resource value: 0x7F0D001E + public const int abc_search_hint = 2131558430; + + // aapt resource value: 0x7F0D0024 + public const int abc_shareactionprovider_share_with = 2131558436; + + // aapt resource value: 0x7F0D0025 + public const int abc_shareactionprovider_share_with_application = 2131558437; + + // aapt resource value: 0x7F0D0026 + public const int abc_toolbar_collapse_description = 2131558438; + + // aapt resource value: 0x7F0D0027 + public const int appbar_scrolling_view_behavior = 2131558439; + + // aapt resource value: 0x7F0D0028 + public const int bottom_sheet_behavior = 2131558440; + + // aapt resource value: 0x7F0D0029 + public const int character_counter_content_description = 2131558441; + + // aapt resource value: 0x7F0D002A + public const int character_counter_pattern = 2131558442; + + // aapt resource value: 0x7F0D002B + public const int fab_transformation_scrim_behavior = 2131558443; + + // aapt resource value: 0x7F0D002C + public const int fab_transformation_sheet_behavior = 2131558444; + + // aapt resource value: 0x7F0D002D + public const int hide_bottom_view_on_scroll_behavior = 2131558445; + + // aapt resource value: 0x7F0D002E + public const int mtrl_chip_close_icon_content_description = 2131558446; + + // aapt resource value: 0x7F0D002F + public const int overflow_tab_title = 2131558447; + + // aapt resource value: 0x7F0D0030 + public const int password_toggle_content_description = 2131558448; + + // aapt resource value: 0x7F0D0031 + public const int path_password_eye = 2131558449; + + // aapt resource value: 0x7F0D0032 + public const int path_password_eye_mask_strike_through = 2131558450; + + // aapt resource value: 0x7F0D0033 + public const int path_password_eye_mask_visible = 2131558451; + + // aapt resource value: 0x7F0D0034 + public const int path_password_strike_through = 2131558452; + + // aapt resource value: 0x7F0D0035 + public const int search_menu_title = 2131558453; + + // aapt resource value: 0x7F0D0036 + public const int status_bar_notification_info_overflow = 2131558454; + + static String() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private String() + { + } + } + + public partial class Style + { + + // aapt resource value: 0x7F0E0000 + public const int AlertDialog_AppCompat = 2131623936; + + // aapt resource value: 0x7F0E0001 + public const int AlertDialog_AppCompat_Light = 2131623937; + + // aapt resource value: 0x7F0E0002 + public const int Animation_AppCompat_Dialog = 2131623938; + + // aapt resource value: 0x7F0E0003 + public const int Animation_AppCompat_DropDownUp = 2131623939; + + // aapt resource value: 0x7F0E0004 + public const int Animation_AppCompat_Tooltip = 2131623940; + + // aapt resource value: 0x7F0E0005 + public const int Animation_Design_BottomSheetDialog = 2131623941; + + // aapt resource value: 0x7F0E0006 + public const int AppCompatDialogStyle = 2131623942; + + // aapt resource value: 0x7F0E0007 + public const int Base_AlertDialog_AppCompat = 2131623943; + + // aapt resource value: 0x7F0E0008 + public const int Base_AlertDialog_AppCompat_Light = 2131623944; + + // aapt resource value: 0x7F0E0009 + public const int Base_Animation_AppCompat_Dialog = 2131623945; + + // aapt resource value: 0x7F0E000A + public const int Base_Animation_AppCompat_DropDownUp = 2131623946; + + // aapt resource value: 0x7F0E000B + public const int Base_Animation_AppCompat_Tooltip = 2131623947; + + // aapt resource value: 0x7F0E000C + public const int Base_CardView = 2131623948; + + // aapt resource value: 0x7F0E000E + public const int Base_DialogWindowTitleBackground_AppCompat = 2131623950; + + // aapt resource value: 0x7F0E000D + public const int Base_DialogWindowTitle_AppCompat = 2131623949; + + // aapt resource value: 0x7F0E000F + public const int Base_TextAppearance_AppCompat = 2131623951; + + // aapt resource value: 0x7F0E0010 + public const int Base_TextAppearance_AppCompat_Body1 = 2131623952; + + // aapt resource value: 0x7F0E0011 + public const int Base_TextAppearance_AppCompat_Body2 = 2131623953; + + // aapt resource value: 0x7F0E0012 + public const int Base_TextAppearance_AppCompat_Button = 2131623954; + + // aapt resource value: 0x7F0E0013 + public const int Base_TextAppearance_AppCompat_Caption = 2131623955; + + // aapt resource value: 0x7F0E0014 + public const int Base_TextAppearance_AppCompat_Display1 = 2131623956; + + // aapt resource value: 0x7F0E0015 + public const int Base_TextAppearance_AppCompat_Display2 = 2131623957; + + // aapt resource value: 0x7F0E0016 + public const int Base_TextAppearance_AppCompat_Display3 = 2131623958; + + // aapt resource value: 0x7F0E0017 + public const int Base_TextAppearance_AppCompat_Display4 = 2131623959; + + // aapt resource value: 0x7F0E0018 + public const int Base_TextAppearance_AppCompat_Headline = 2131623960; + + // aapt resource value: 0x7F0E0019 + public const int Base_TextAppearance_AppCompat_Inverse = 2131623961; + + // aapt resource value: 0x7F0E001A + public const int Base_TextAppearance_AppCompat_Large = 2131623962; + + // aapt resource value: 0x7F0E001B + public const int Base_TextAppearance_AppCompat_Large_Inverse = 2131623963; + + // aapt resource value: 0x7F0E001C + public const int Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Large = 2131623964; + + // aapt resource value: 0x7F0E001D + public const int Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Small = 2131623965; + + // aapt resource value: 0x7F0E001E + public const int Base_TextAppearance_AppCompat_Medium = 2131623966; + + // aapt resource value: 0x7F0E001F + public const int Base_TextAppearance_AppCompat_Medium_Inverse = 2131623967; + + // aapt resource value: 0x7F0E0020 + public const int Base_TextAppearance_AppCompat_Menu = 2131623968; + + // aapt resource value: 0x7F0E0021 + public const int Base_TextAppearance_AppCompat_SearchResult = 2131623969; + + // aapt resource value: 0x7F0E0022 + public const int Base_TextAppearance_AppCompat_SearchResult_Subtitle = 2131623970; + + // aapt resource value: 0x7F0E0023 + public const int Base_TextAppearance_AppCompat_SearchResult_Title = 2131623971; + + // aapt resource value: 0x7F0E0024 + public const int Base_TextAppearance_AppCompat_Small = 2131623972; + + // aapt resource value: 0x7F0E0025 + public const int Base_TextAppearance_AppCompat_Small_Inverse = 2131623973; + + // aapt resource value: 0x7F0E0026 + public const int Base_TextAppearance_AppCompat_Subhead = 2131623974; + + // aapt resource value: 0x7F0E0027 + public const int Base_TextAppearance_AppCompat_Subhead_Inverse = 2131623975; + + // aapt resource value: 0x7F0E0028 + public const int Base_TextAppearance_AppCompat_Title = 2131623976; + + // aapt resource value: 0x7F0E0029 + public const int Base_TextAppearance_AppCompat_Title_Inverse = 2131623977; + + // aapt resource value: 0x7F0E002A + public const int Base_TextAppearance_AppCompat_Tooltip = 2131623978; + + // aapt resource value: 0x7F0E002B + public const int Base_TextAppearance_AppCompat_Widget_ActionBar_Menu = 2131623979; + + // aapt resource value: 0x7F0E002C + public const int Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle = 2131623980; + + // aapt resource value: 0x7F0E002D + public const int Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse = 2131623981; + + // aapt resource value: 0x7F0E002E + public const int Base_TextAppearance_AppCompat_Widget_ActionBar_Title = 2131623982; + + // aapt resource value: 0x7F0E002F + public const int Base_TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse = 2131623983; + + // aapt resource value: 0x7F0E0030 + public const int Base_TextAppearance_AppCompat_Widget_ActionMode_Subtitle = 2131623984; + + // aapt resource value: 0x7F0E0031 + public const int Base_TextAppearance_AppCompat_Widget_ActionMode_Title = 2131623985; + + // aapt resource value: 0x7F0E0032 + public const int Base_TextAppearance_AppCompat_Widget_Button = 2131623986; + + // aapt resource value: 0x7F0E0033 + public const int Base_TextAppearance_AppCompat_Widget_Button_Borderless_Colored = 2131623987; + + // aapt resource value: 0x7F0E0034 + public const int Base_TextAppearance_AppCompat_Widget_Button_Colored = 2131623988; + + // aapt resource value: 0x7F0E0035 + public const int Base_TextAppearance_AppCompat_Widget_Button_Inverse = 2131623989; + + // aapt resource value: 0x7F0E0036 + public const int Base_TextAppearance_AppCompat_Widget_DropDownItem = 2131623990; + + // aapt resource value: 0x7F0E0037 + public const int Base_TextAppearance_AppCompat_Widget_PopupMenu_Header = 2131623991; + + // aapt resource value: 0x7F0E0038 + public const int Base_TextAppearance_AppCompat_Widget_PopupMenu_Large = 2131623992; + + // aapt resource value: 0x7F0E0039 + public const int Base_TextAppearance_AppCompat_Widget_PopupMenu_Small = 2131623993; + + // aapt resource value: 0x7F0E003A + public const int Base_TextAppearance_AppCompat_Widget_Switch = 2131623994; + + // aapt resource value: 0x7F0E003B + public const int Base_TextAppearance_AppCompat_Widget_TextView_SpinnerItem = 2131623995; + + // aapt resource value: 0x7F0E003C + public const int Base_TextAppearance_Widget_AppCompat_ExpandedMenu_Item = 2131623996; + + // aapt resource value: 0x7F0E003D + public const int Base_TextAppearance_Widget_AppCompat_Toolbar_Subtitle = 2131623997; + + // aapt resource value: 0x7F0E003E + public const int Base_TextAppearance_Widget_AppCompat_Toolbar_Title = 2131623998; + + // aapt resource value: 0x7F0E005E + public const int Base_ThemeOverlay_AppCompat = 2131624030; + + // aapt resource value: 0x7F0E005F + public const int Base_ThemeOverlay_AppCompat_ActionBar = 2131624031; + + // aapt resource value: 0x7F0E0060 + public const int Base_ThemeOverlay_AppCompat_Dark = 2131624032; + + // aapt resource value: 0x7F0E0061 + public const int Base_ThemeOverlay_AppCompat_Dark_ActionBar = 2131624033; + + // aapt resource value: 0x7F0E0062 + public const int Base_ThemeOverlay_AppCompat_Dialog = 2131624034; + + // aapt resource value: 0x7F0E0063 + public const int Base_ThemeOverlay_AppCompat_Dialog_Alert = 2131624035; + + // aapt resource value: 0x7F0E0064 + public const int Base_ThemeOverlay_AppCompat_Light = 2131624036; + + // aapt resource value: 0x7F0E0065 + public const int Base_ThemeOverlay_MaterialComponents_Dialog = 2131624037; + + // aapt resource value: 0x7F0E0066 + public const int Base_ThemeOverlay_MaterialComponents_Dialog_Alert = 2131624038; + + // aapt resource value: 0x7F0E003F + public const int Base_Theme_AppCompat = 2131623999; + + // aapt resource value: 0x7F0E0040 + public const int Base_Theme_AppCompat_CompactMenu = 2131624000; + + // aapt resource value: 0x7F0E0041 + public const int Base_Theme_AppCompat_Dialog = 2131624001; + + // aapt resource value: 0x7F0E0045 + public const int Base_Theme_AppCompat_DialogWhenLarge = 2131624005; + + // aapt resource value: 0x7F0E0042 + public const int Base_Theme_AppCompat_Dialog_Alert = 2131624002; + + // aapt resource value: 0x7F0E0043 + public const int Base_Theme_AppCompat_Dialog_FixedSize = 2131624003; + + // aapt resource value: 0x7F0E0044 + public const int Base_Theme_AppCompat_Dialog_MinWidth = 2131624004; + + // aapt resource value: 0x7F0E0046 + public const int Base_Theme_AppCompat_Light = 2131624006; + + // aapt resource value: 0x7F0E0047 + public const int Base_Theme_AppCompat_Light_DarkActionBar = 2131624007; + + // aapt resource value: 0x7F0E0048 + public const int Base_Theme_AppCompat_Light_Dialog = 2131624008; + + // aapt resource value: 0x7F0E004C + public const int Base_Theme_AppCompat_Light_DialogWhenLarge = 2131624012; + + // aapt resource value: 0x7F0E0049 + public const int Base_Theme_AppCompat_Light_Dialog_Alert = 2131624009; + + // aapt resource value: 0x7F0E004A + public const int Base_Theme_AppCompat_Light_Dialog_FixedSize = 2131624010; + + // aapt resource value: 0x7F0E004B + public const int Base_Theme_AppCompat_Light_Dialog_MinWidth = 2131624011; + + // aapt resource value: 0x7F0E004D + public const int Base_Theme_MaterialComponents = 2131624013; + + // aapt resource value: 0x7F0E004E + public const int Base_Theme_MaterialComponents_Bridge = 2131624014; + + // aapt resource value: 0x7F0E004F + public const int Base_Theme_MaterialComponents_CompactMenu = 2131624015; + + // aapt resource value: 0x7F0E0050 + public const int Base_Theme_MaterialComponents_Dialog = 2131624016; + + // aapt resource value: 0x7F0E0054 + public const int Base_Theme_MaterialComponents_DialogWhenLarge = 2131624020; + + // aapt resource value: 0x7F0E0051 + public const int Base_Theme_MaterialComponents_Dialog_Alert = 2131624017; + + // aapt resource value: 0x7F0E0052 + public const int Base_Theme_MaterialComponents_Dialog_FixedSize = 2131624018; + + // aapt resource value: 0x7F0E0053 + public const int Base_Theme_MaterialComponents_Dialog_MinWidth = 2131624019; + + // aapt resource value: 0x7F0E0055 + public const int Base_Theme_MaterialComponents_Light = 2131624021; + + // aapt resource value: 0x7F0E0056 + public const int Base_Theme_MaterialComponents_Light_Bridge = 2131624022; + + // aapt resource value: 0x7F0E0057 + public const int Base_Theme_MaterialComponents_Light_DarkActionBar = 2131624023; + + // aapt resource value: 0x7F0E0058 + public const int Base_Theme_MaterialComponents_Light_DarkActionBar_Bridge = 2131624024; + + // aapt resource value: 0x7F0E0059 + public const int Base_Theme_MaterialComponents_Light_Dialog = 2131624025; + + // aapt resource value: 0x7F0E005D + public const int Base_Theme_MaterialComponents_Light_DialogWhenLarge = 2131624029; + + // aapt resource value: 0x7F0E005A + public const int Base_Theme_MaterialComponents_Light_Dialog_Alert = 2131624026; + + // aapt resource value: 0x7F0E005B + public const int Base_Theme_MaterialComponents_Light_Dialog_FixedSize = 2131624027; + + // aapt resource value: 0x7F0E005C + public const int Base_Theme_MaterialComponents_Light_Dialog_MinWidth = 2131624028; + + // aapt resource value: 0x7F0E006E + public const int Base_V14_ThemeOverlay_MaterialComponents_Dialog = 2131624046; + + // aapt resource value: 0x7F0E006F + public const int Base_V14_ThemeOverlay_MaterialComponents_Dialog_Alert = 2131624047; + + // aapt resource value: 0x7F0E0067 + public const int Base_V14_Theme_MaterialComponents = 2131624039; + + // aapt resource value: 0x7F0E0068 + public const int Base_V14_Theme_MaterialComponents_Bridge = 2131624040; + + // aapt resource value: 0x7F0E0069 + public const int Base_V14_Theme_MaterialComponents_Dialog = 2131624041; + + // aapt resource value: 0x7F0E006A + public const int Base_V14_Theme_MaterialComponents_Light = 2131624042; + + // aapt resource value: 0x7F0E006B + public const int Base_V14_Theme_MaterialComponents_Light_Bridge = 2131624043; + + // aapt resource value: 0x7F0E006C + public const int Base_V14_Theme_MaterialComponents_Light_DarkActionBar_Bridge = 2131624044; + + // aapt resource value: 0x7F0E006D + public const int Base_V14_Theme_MaterialComponents_Light_Dialog = 2131624045; + + // aapt resource value: 0x7F0E0074 + public const int Base_V21_ThemeOverlay_AppCompat_Dialog = 2131624052; + + // aapt resource value: 0x7F0E0070 + public const int Base_V21_Theme_AppCompat = 2131624048; + + // aapt resource value: 0x7F0E0071 + public const int Base_V21_Theme_AppCompat_Dialog = 2131624049; + + // aapt resource value: 0x7F0E0072 + public const int Base_V21_Theme_AppCompat_Light = 2131624050; + + // aapt resource value: 0x7F0E0073 + public const int Base_V21_Theme_AppCompat_Light_Dialog = 2131624051; + + // aapt resource value: 0x7F0E0075 + public const int Base_V22_Theme_AppCompat = 2131624053; + + // aapt resource value: 0x7F0E0076 + public const int Base_V22_Theme_AppCompat_Light = 2131624054; + + // aapt resource value: 0x7F0E0077 + public const int Base_V23_Theme_AppCompat = 2131624055; + + // aapt resource value: 0x7F0E0078 + public const int Base_V23_Theme_AppCompat_Light = 2131624056; + + // aapt resource value: 0x7F0E0079 + public const int Base_V26_Theme_AppCompat = 2131624057; + + // aapt resource value: 0x7F0E007A + public const int Base_V26_Theme_AppCompat_Light = 2131624058; + + // aapt resource value: 0x7F0E007B + public const int Base_V26_Widget_AppCompat_Toolbar = 2131624059; + + // aapt resource value: 0x7F0E007C + public const int Base_V28_Theme_AppCompat = 2131624060; + + // aapt resource value: 0x7F0E007D + public const int Base_V28_Theme_AppCompat_Light = 2131624061; + + // aapt resource value: 0x7F0E0082 + public const int Base_V7_ThemeOverlay_AppCompat_Dialog = 2131624066; + + // aapt resource value: 0x7F0E007E + public const int Base_V7_Theme_AppCompat = 2131624062; + + // aapt resource value: 0x7F0E007F + public const int Base_V7_Theme_AppCompat_Dialog = 2131624063; + + // aapt resource value: 0x7F0E0080 + public const int Base_V7_Theme_AppCompat_Light = 2131624064; + + // aapt resource value: 0x7F0E0081 + public const int Base_V7_Theme_AppCompat_Light_Dialog = 2131624065; + + // aapt resource value: 0x7F0E0083 + public const int Base_V7_Widget_AppCompat_AutoCompleteTextView = 2131624067; + + // aapt resource value: 0x7F0E0084 + public const int Base_V7_Widget_AppCompat_EditText = 2131624068; + + // aapt resource value: 0x7F0E0085 + public const int Base_V7_Widget_AppCompat_Toolbar = 2131624069; + + // aapt resource value: 0x7F0E0086 + public const int Base_Widget_AppCompat_ActionBar = 2131624070; + + // aapt resource value: 0x7F0E0087 + public const int Base_Widget_AppCompat_ActionBar_Solid = 2131624071; + + // aapt resource value: 0x7F0E0088 + public const int Base_Widget_AppCompat_ActionBar_TabBar = 2131624072; + + // aapt resource value: 0x7F0E0089 + public const int Base_Widget_AppCompat_ActionBar_TabText = 2131624073; + + // aapt resource value: 0x7F0E008A + public const int Base_Widget_AppCompat_ActionBar_TabView = 2131624074; + + // aapt resource value: 0x7F0E008B + public const int Base_Widget_AppCompat_ActionButton = 2131624075; + + // aapt resource value: 0x7F0E008C + public const int Base_Widget_AppCompat_ActionButton_CloseMode = 2131624076; + + // aapt resource value: 0x7F0E008D + public const int Base_Widget_AppCompat_ActionButton_Overflow = 2131624077; + + // aapt resource value: 0x7F0E008E + public const int Base_Widget_AppCompat_ActionMode = 2131624078; + + // aapt resource value: 0x7F0E008F + public const int Base_Widget_AppCompat_ActivityChooserView = 2131624079; + + // aapt resource value: 0x7F0E0090 + public const int Base_Widget_AppCompat_AutoCompleteTextView = 2131624080; + + // aapt resource value: 0x7F0E0091 + public const int Base_Widget_AppCompat_Button = 2131624081; + + // aapt resource value: 0x7F0E0097 + public const int Base_Widget_AppCompat_ButtonBar = 2131624087; + + // aapt resource value: 0x7F0E0098 + public const int Base_Widget_AppCompat_ButtonBar_AlertDialog = 2131624088; + + // aapt resource value: 0x7F0E0092 + public const int Base_Widget_AppCompat_Button_Borderless = 2131624082; + + // aapt resource value: 0x7F0E0093 + public const int Base_Widget_AppCompat_Button_Borderless_Colored = 2131624083; + + // aapt resource value: 0x7F0E0094 + public const int Base_Widget_AppCompat_Button_ButtonBar_AlertDialog = 2131624084; + + // aapt resource value: 0x7F0E0095 + public const int Base_Widget_AppCompat_Button_Colored = 2131624085; + + // aapt resource value: 0x7F0E0096 + public const int Base_Widget_AppCompat_Button_Small = 2131624086; + + // aapt resource value: 0x7F0E0099 + public const int Base_Widget_AppCompat_CompoundButton_CheckBox = 2131624089; + + // aapt resource value: 0x7F0E009A + public const int Base_Widget_AppCompat_CompoundButton_RadioButton = 2131624090; + + // aapt resource value: 0x7F0E009B + public const int Base_Widget_AppCompat_CompoundButton_Switch = 2131624091; + + // aapt resource value: 0x7F0E009C + public const int Base_Widget_AppCompat_DrawerArrowToggle = 2131624092; + + // aapt resource value: 0x7F0E009D + public const int Base_Widget_AppCompat_DrawerArrowToggle_Common = 2131624093; + + // aapt resource value: 0x7F0E009E + public const int Base_Widget_AppCompat_DropDownItem_Spinner = 2131624094; + + // aapt resource value: 0x7F0E009F + public const int Base_Widget_AppCompat_EditText = 2131624095; + + // aapt resource value: 0x7F0E00A0 + public const int Base_Widget_AppCompat_ImageButton = 2131624096; + + // aapt resource value: 0x7F0E00A1 + public const int Base_Widget_AppCompat_Light_ActionBar = 2131624097; + + // aapt resource value: 0x7F0E00A2 + public const int Base_Widget_AppCompat_Light_ActionBar_Solid = 2131624098; + + // aapt resource value: 0x7F0E00A3 + public const int Base_Widget_AppCompat_Light_ActionBar_TabBar = 2131624099; + + // aapt resource value: 0x7F0E00A4 + public const int Base_Widget_AppCompat_Light_ActionBar_TabText = 2131624100; + + // aapt resource value: 0x7F0E00A5 + public const int Base_Widget_AppCompat_Light_ActionBar_TabText_Inverse = 2131624101; + + // aapt resource value: 0x7F0E00A6 + public const int Base_Widget_AppCompat_Light_ActionBar_TabView = 2131624102; + + // aapt resource value: 0x7F0E00A7 + public const int Base_Widget_AppCompat_Light_PopupMenu = 2131624103; + + // aapt resource value: 0x7F0E00A8 + public const int Base_Widget_AppCompat_Light_PopupMenu_Overflow = 2131624104; + + // aapt resource value: 0x7F0E00A9 + public const int Base_Widget_AppCompat_ListMenuView = 2131624105; + + // aapt resource value: 0x7F0E00AA + public const int Base_Widget_AppCompat_ListPopupWindow = 2131624106; + + // aapt resource value: 0x7F0E00AB + public const int Base_Widget_AppCompat_ListView = 2131624107; + + // aapt resource value: 0x7F0E00AC + public const int Base_Widget_AppCompat_ListView_DropDown = 2131624108; + + // aapt resource value: 0x7F0E00AD + public const int Base_Widget_AppCompat_ListView_Menu = 2131624109; + + // aapt resource value: 0x7F0E00AE + public const int Base_Widget_AppCompat_PopupMenu = 2131624110; + + // aapt resource value: 0x7F0E00AF + public const int Base_Widget_AppCompat_PopupMenu_Overflow = 2131624111; + + // aapt resource value: 0x7F0E00B0 + public const int Base_Widget_AppCompat_PopupWindow = 2131624112; + + // aapt resource value: 0x7F0E00B1 + public const int Base_Widget_AppCompat_ProgressBar = 2131624113; + + // aapt resource value: 0x7F0E00B2 + public const int Base_Widget_AppCompat_ProgressBar_Horizontal = 2131624114; + + // aapt resource value: 0x7F0E00B3 + public const int Base_Widget_AppCompat_RatingBar = 2131624115; + + // aapt resource value: 0x7F0E00B4 + public const int Base_Widget_AppCompat_RatingBar_Indicator = 2131624116; + + // aapt resource value: 0x7F0E00B5 + public const int Base_Widget_AppCompat_RatingBar_Small = 2131624117; + + // aapt resource value: 0x7F0E00B6 + public const int Base_Widget_AppCompat_SearchView = 2131624118; + + // aapt resource value: 0x7F0E00B7 + public const int Base_Widget_AppCompat_SearchView_ActionBar = 2131624119; + + // aapt resource value: 0x7F0E00B8 + public const int Base_Widget_AppCompat_SeekBar = 2131624120; + + // aapt resource value: 0x7F0E00B9 + public const int Base_Widget_AppCompat_SeekBar_Discrete = 2131624121; + + // aapt resource value: 0x7F0E00BA + public const int Base_Widget_AppCompat_Spinner = 2131624122; + + // aapt resource value: 0x7F0E00BB + public const int Base_Widget_AppCompat_Spinner_Underlined = 2131624123; + + // aapt resource value: 0x7F0E00BC + public const int Base_Widget_AppCompat_TextView_SpinnerItem = 2131624124; + + // aapt resource value: 0x7F0E00BD + public const int Base_Widget_AppCompat_Toolbar = 2131624125; + + // aapt resource value: 0x7F0E00BE + public const int Base_Widget_AppCompat_Toolbar_Button_Navigation = 2131624126; + + // aapt resource value: 0x7F0E00BF + public const int Base_Widget_Design_TabLayout = 2131624127; + + // aapt resource value: 0x7F0E00C0 + public const int Base_Widget_MaterialComponents_Chip = 2131624128; + + // aapt resource value: 0x7F0E00C1 + public const int Base_Widget_MaterialComponents_TextInputEditText = 2131624129; + + // aapt resource value: 0x7F0E00C2 + public const int Base_Widget_MaterialComponents_TextInputLayout = 2131624130; + + // aapt resource value: 0x7F0E00C3 + public const int CardView = 2131624131; + + // aapt resource value: 0x7F0E00C4 + public const int CardView_Dark = 2131624132; + + // aapt resource value: 0x7F0E00C5 + public const int CardView_Light = 2131624133; + + // aapt resource value: 0x7F0E01F7 + public const int collectionViewTheme = 2131624439; + + // aapt resource value: 0x7F0E00C6 + public const int MainTheme = 2131624134; + + // aapt resource value: 0x7F0E00C7 + public const int MainTheme_Base = 2131624135; + + // aapt resource value: 0x7F0E00C8 + public const int Platform_AppCompat = 2131624136; + + // aapt resource value: 0x7F0E00C9 + public const int Platform_AppCompat_Light = 2131624137; + + // aapt resource value: 0x7F0E00CA + public const int Platform_MaterialComponents = 2131624138; + + // aapt resource value: 0x7F0E00CB + public const int Platform_MaterialComponents_Dialog = 2131624139; + + // aapt resource value: 0x7F0E00CC + public const int Platform_MaterialComponents_Light = 2131624140; + + // aapt resource value: 0x7F0E00CD + public const int Platform_MaterialComponents_Light_Dialog = 2131624141; + + // aapt resource value: 0x7F0E00CE + public const int Platform_ThemeOverlay_AppCompat = 2131624142; + + // aapt resource value: 0x7F0E00CF + public const int Platform_ThemeOverlay_AppCompat_Dark = 2131624143; + + // aapt resource value: 0x7F0E00D0 + public const int Platform_ThemeOverlay_AppCompat_Light = 2131624144; + + // aapt resource value: 0x7F0E00D1 + public const int Platform_V21_AppCompat = 2131624145; + + // aapt resource value: 0x7F0E00D2 + public const int Platform_V21_AppCompat_Light = 2131624146; + + // aapt resource value: 0x7F0E00D3 + public const int Platform_V25_AppCompat = 2131624147; + + // aapt resource value: 0x7F0E00D4 + public const int Platform_V25_AppCompat_Light = 2131624148; + + // aapt resource value: 0x7F0E00D5 + public const int Platform_Widget_AppCompat_Spinner = 2131624149; + + // aapt resource value: 0x7F0E00D6 + public const int RtlOverlay_DialogWindowTitle_AppCompat = 2131624150; + + // aapt resource value: 0x7F0E00D7 + public const int RtlOverlay_Widget_AppCompat_ActionBar_TitleItem = 2131624151; + + // aapt resource value: 0x7F0E00D8 + public const int RtlOverlay_Widget_AppCompat_DialogTitle_Icon = 2131624152; + + // aapt resource value: 0x7F0E00D9 + public const int RtlOverlay_Widget_AppCompat_PopupMenuItem = 2131624153; + + // aapt resource value: 0x7F0E00DA + public const int RtlOverlay_Widget_AppCompat_PopupMenuItem_InternalGroup = 2131624154; + + // aapt resource value: 0x7F0E00DB + public const int RtlOverlay_Widget_AppCompat_PopupMenuItem_Shortcut = 2131624155; + + // aapt resource value: 0x7F0E00DC + public const int RtlOverlay_Widget_AppCompat_PopupMenuItem_SubmenuArrow = 2131624156; + + // aapt resource value: 0x7F0E00DD + public const int RtlOverlay_Widget_AppCompat_PopupMenuItem_Text = 2131624157; + + // aapt resource value: 0x7F0E00DE + public const int RtlOverlay_Widget_AppCompat_PopupMenuItem_Title = 2131624158; + + // aapt resource value: 0x7F0E00E4 + public const int RtlOverlay_Widget_AppCompat_SearchView_MagIcon = 2131624164; + + // aapt resource value: 0x7F0E00DF + public const int RtlOverlay_Widget_AppCompat_Search_DropDown = 2131624159; + + // aapt resource value: 0x7F0E00E0 + public const int RtlOverlay_Widget_AppCompat_Search_DropDown_Icon1 = 2131624160; + + // aapt resource value: 0x7F0E00E1 + public const int RtlOverlay_Widget_AppCompat_Search_DropDown_Icon2 = 2131624161; + + // aapt resource value: 0x7F0E00E2 + public const int RtlOverlay_Widget_AppCompat_Search_DropDown_Query = 2131624162; + + // aapt resource value: 0x7F0E00E3 + public const int RtlOverlay_Widget_AppCompat_Search_DropDown_Text = 2131624163; + + // aapt resource value: 0x7F0E00E5 + public const int RtlUnderlay_Widget_AppCompat_ActionButton = 2131624165; + + // aapt resource value: 0x7F0E00E6 + public const int RtlUnderlay_Widget_AppCompat_ActionButton_Overflow = 2131624166; + + // aapt resource value: 0x7F0E01F8 + public const int scrollViewScrollBars = 2131624440; + + // aapt resource value: 0x7F0E01F9 + public const int scrollViewTheme = 2131624441; + + // aapt resource value: 0x7F0E00E7 + public const int TextAppearance_AppCompat = 2131624167; + + // aapt resource value: 0x7F0E00E8 + public const int TextAppearance_AppCompat_Body1 = 2131624168; + + // aapt resource value: 0x7F0E00E9 + public const int TextAppearance_AppCompat_Body2 = 2131624169; + + // aapt resource value: 0x7F0E00EA + public const int TextAppearance_AppCompat_Button = 2131624170; + + // aapt resource value: 0x7F0E00EB + public const int TextAppearance_AppCompat_Caption = 2131624171; + + // aapt resource value: 0x7F0E00EC + public const int TextAppearance_AppCompat_Display1 = 2131624172; + + // aapt resource value: 0x7F0E00ED + public const int TextAppearance_AppCompat_Display2 = 2131624173; + + // aapt resource value: 0x7F0E00EE + public const int TextAppearance_AppCompat_Display3 = 2131624174; + + // aapt resource value: 0x7F0E00EF + public const int TextAppearance_AppCompat_Display4 = 2131624175; + + // aapt resource value: 0x7F0E00F0 + public const int TextAppearance_AppCompat_Headline = 2131624176; + + // aapt resource value: 0x7F0E00F1 + public const int TextAppearance_AppCompat_Inverse = 2131624177; + + // aapt resource value: 0x7F0E00F2 + public const int TextAppearance_AppCompat_Large = 2131624178; + + // aapt resource value: 0x7F0E00F3 + public const int TextAppearance_AppCompat_Large_Inverse = 2131624179; + + // aapt resource value: 0x7F0E00F4 + public const int TextAppearance_AppCompat_Light_SearchResult_Subtitle = 2131624180; + + // aapt resource value: 0x7F0E00F5 + public const int TextAppearance_AppCompat_Light_SearchResult_Title = 2131624181; + + // aapt resource value: 0x7F0E00F6 + public const int TextAppearance_AppCompat_Light_Widget_PopupMenu_Large = 2131624182; + + // aapt resource value: 0x7F0E00F7 + public const int TextAppearance_AppCompat_Light_Widget_PopupMenu_Small = 2131624183; + + // aapt resource value: 0x7F0E00F8 + public const int TextAppearance_AppCompat_Medium = 2131624184; + + // aapt resource value: 0x7F0E00F9 + public const int TextAppearance_AppCompat_Medium_Inverse = 2131624185; + + // aapt resource value: 0x7F0E00FA + public const int TextAppearance_AppCompat_Menu = 2131624186; + + // aapt resource value: 0x7F0E00FB + public const int TextAppearance_AppCompat_SearchResult_Subtitle = 2131624187; + + // aapt resource value: 0x7F0E00FC + public const int TextAppearance_AppCompat_SearchResult_Title = 2131624188; + + // aapt resource value: 0x7F0E00FD + public const int TextAppearance_AppCompat_Small = 2131624189; + + // aapt resource value: 0x7F0E00FE + public const int TextAppearance_AppCompat_Small_Inverse = 2131624190; + + // aapt resource value: 0x7F0E00FF + public const int TextAppearance_AppCompat_Subhead = 2131624191; + + // aapt resource value: 0x7F0E0100 + public const int TextAppearance_AppCompat_Subhead_Inverse = 2131624192; + + // aapt resource value: 0x7F0E0101 + public const int TextAppearance_AppCompat_Title = 2131624193; + + // aapt resource value: 0x7F0E0102 + public const int TextAppearance_AppCompat_Title_Inverse = 2131624194; + + // aapt resource value: 0x7F0E0103 + public const int TextAppearance_AppCompat_Tooltip = 2131624195; + + // aapt resource value: 0x7F0E0104 + public const int TextAppearance_AppCompat_Widget_ActionBar_Menu = 2131624196; + + // aapt resource value: 0x7F0E0105 + public const int TextAppearance_AppCompat_Widget_ActionBar_Subtitle = 2131624197; + + // aapt resource value: 0x7F0E0106 + public const int TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse = 2131624198; + + // aapt resource value: 0x7F0E0107 + public const int TextAppearance_AppCompat_Widget_ActionBar_Title = 2131624199; + + // aapt resource value: 0x7F0E0108 + public const int TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse = 2131624200; + + // aapt resource value: 0x7F0E0109 + public const int TextAppearance_AppCompat_Widget_ActionMode_Subtitle = 2131624201; + + // aapt resource value: 0x7F0E010A + public const int TextAppearance_AppCompat_Widget_ActionMode_Subtitle_Inverse = 2131624202; + + // aapt resource value: 0x7F0E010B + public const int TextAppearance_AppCompat_Widget_ActionMode_Title = 2131624203; + + // aapt resource value: 0x7F0E010C + public const int TextAppearance_AppCompat_Widget_ActionMode_Title_Inverse = 2131624204; + + // aapt resource value: 0x7F0E010D + public const int TextAppearance_AppCompat_Widget_Button = 2131624205; + + // aapt resource value: 0x7F0E010E + public const int TextAppearance_AppCompat_Widget_Button_Borderless_Colored = 2131624206; + + // aapt resource value: 0x7F0E010F + public const int TextAppearance_AppCompat_Widget_Button_Colored = 2131624207; + + // aapt resource value: 0x7F0E0110 + public const int TextAppearance_AppCompat_Widget_Button_Inverse = 2131624208; + + // aapt resource value: 0x7F0E0111 + public const int TextAppearance_AppCompat_Widget_DropDownItem = 2131624209; + + // aapt resource value: 0x7F0E0112 + public const int TextAppearance_AppCompat_Widget_PopupMenu_Header = 2131624210; + + // aapt resource value: 0x7F0E0113 + public const int TextAppearance_AppCompat_Widget_PopupMenu_Large = 2131624211; + + // aapt resource value: 0x7F0E0114 + public const int TextAppearance_AppCompat_Widget_PopupMenu_Small = 2131624212; + + // aapt resource value: 0x7F0E0115 + public const int TextAppearance_AppCompat_Widget_Switch = 2131624213; + + // aapt resource value: 0x7F0E0116 + public const int TextAppearance_AppCompat_Widget_TextView_SpinnerItem = 2131624214; + + // aapt resource value: 0x7F0E0117 + public const int TextAppearance_Compat_Notification = 2131624215; + + // aapt resource value: 0x7F0E0118 + public const int TextAppearance_Compat_Notification_Info = 2131624216; + + // aapt resource value: 0x7F0E0119 + public const int TextAppearance_Compat_Notification_Info_Media = 2131624217; + + // aapt resource value: 0x7F0E011A + public const int TextAppearance_Compat_Notification_Line2 = 2131624218; + + // aapt resource value: 0x7F0E011B + public const int TextAppearance_Compat_Notification_Line2_Media = 2131624219; + + // aapt resource value: 0x7F0E011C + public const int TextAppearance_Compat_Notification_Media = 2131624220; + + // aapt resource value: 0x7F0E011D + public const int TextAppearance_Compat_Notification_Time = 2131624221; + + // aapt resource value: 0x7F0E011E + public const int TextAppearance_Compat_Notification_Time_Media = 2131624222; + + // aapt resource value: 0x7F0E011F + public const int TextAppearance_Compat_Notification_Title = 2131624223; + + // aapt resource value: 0x7F0E0120 + public const int TextAppearance_Compat_Notification_Title_Media = 2131624224; + + // aapt resource value: 0x7F0E0121 + public const int TextAppearance_Design_CollapsingToolbar_Expanded = 2131624225; + + // aapt resource value: 0x7F0E0122 + public const int TextAppearance_Design_Counter = 2131624226; + + // aapt resource value: 0x7F0E0123 + public const int TextAppearance_Design_Counter_Overflow = 2131624227; + + // aapt resource value: 0x7F0E0124 + public const int TextAppearance_Design_Error = 2131624228; + + // aapt resource value: 0x7F0E0125 + public const int TextAppearance_Design_HelperText = 2131624229; + + // aapt resource value: 0x7F0E0126 + public const int TextAppearance_Design_Hint = 2131624230; + + // aapt resource value: 0x7F0E0127 + public const int TextAppearance_Design_Snackbar_Message = 2131624231; + + // aapt resource value: 0x7F0E0128 + public const int TextAppearance_Design_Tab = 2131624232; + + // aapt resource value: 0x7F0E0129 + public const int TextAppearance_MaterialComponents_Body1 = 2131624233; + + // aapt resource value: 0x7F0E012A + public const int TextAppearance_MaterialComponents_Body2 = 2131624234; + + // aapt resource value: 0x7F0E012B + public const int TextAppearance_MaterialComponents_Button = 2131624235; + + // aapt resource value: 0x7F0E012C + public const int TextAppearance_MaterialComponents_Caption = 2131624236; + + // aapt resource value: 0x7F0E012D + public const int TextAppearance_MaterialComponents_Chip = 2131624237; + + // aapt resource value: 0x7F0E012E + public const int TextAppearance_MaterialComponents_Headline1 = 2131624238; + + // aapt resource value: 0x7F0E012F + public const int TextAppearance_MaterialComponents_Headline2 = 2131624239; + + // aapt resource value: 0x7F0E0130 + public const int TextAppearance_MaterialComponents_Headline3 = 2131624240; + + // aapt resource value: 0x7F0E0131 + public const int TextAppearance_MaterialComponents_Headline4 = 2131624241; + + // aapt resource value: 0x7F0E0132 + public const int TextAppearance_MaterialComponents_Headline5 = 2131624242; + + // aapt resource value: 0x7F0E0133 + public const int TextAppearance_MaterialComponents_Headline6 = 2131624243; + + // aapt resource value: 0x7F0E0134 + public const int TextAppearance_MaterialComponents_Overline = 2131624244; + + // aapt resource value: 0x7F0E0135 + public const int TextAppearance_MaterialComponents_Subtitle1 = 2131624245; + + // aapt resource value: 0x7F0E0136 + public const int TextAppearance_MaterialComponents_Subtitle2 = 2131624246; + + // aapt resource value: 0x7F0E0137 + public const int TextAppearance_MaterialComponents_Tab = 2131624247; + + // aapt resource value: 0x7F0E0138 + public const int TextAppearance_Widget_AppCompat_ExpandedMenu_Item = 2131624248; + + // aapt resource value: 0x7F0E0139 + public const int TextAppearance_Widget_AppCompat_Toolbar_Subtitle = 2131624249; + + // aapt resource value: 0x7F0E013A + public const int TextAppearance_Widget_AppCompat_Toolbar_Title = 2131624250; + + // aapt resource value: 0x7F0E016B + public const int ThemeOverlay_AppCompat = 2131624299; + + // aapt resource value: 0x7F0E016C + public const int ThemeOverlay_AppCompat_ActionBar = 2131624300; + + // aapt resource value: 0x7F0E016D + public const int ThemeOverlay_AppCompat_Dark = 2131624301; + + // aapt resource value: 0x7F0E016E + public const int ThemeOverlay_AppCompat_Dark_ActionBar = 2131624302; + + // aapt resource value: 0x7F0E016F + public const int ThemeOverlay_AppCompat_Dialog = 2131624303; + + // aapt resource value: 0x7F0E0170 + public const int ThemeOverlay_AppCompat_Dialog_Alert = 2131624304; + + // aapt resource value: 0x7F0E0171 + public const int ThemeOverlay_AppCompat_Light = 2131624305; + + // aapt resource value: 0x7F0E0172 + public const int ThemeOverlay_MaterialComponents = 2131624306; + + // aapt resource value: 0x7F0E0173 + public const int ThemeOverlay_MaterialComponents_ActionBar = 2131624307; + + // aapt resource value: 0x7F0E0174 + public const int ThemeOverlay_MaterialComponents_Dark = 2131624308; + + // aapt resource value: 0x7F0E0175 + public const int ThemeOverlay_MaterialComponents_Dark_ActionBar = 2131624309; + + // aapt resource value: 0x7F0E0176 + public const int ThemeOverlay_MaterialComponents_Dialog = 2131624310; + + // aapt resource value: 0x7F0E0177 + public const int ThemeOverlay_MaterialComponents_Dialog_Alert = 2131624311; + + // aapt resource value: 0x7F0E0178 + public const int ThemeOverlay_MaterialComponents_Light = 2131624312; + + // aapt resource value: 0x7F0E0179 + public const int ThemeOverlay_MaterialComponents_TextInputEditText = 2131624313; + + // aapt resource value: 0x7F0E017A + public const int ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox = 2131624314; + + // aapt resource value: 0x7F0E017B + public const int ThemeOverlay_MaterialComponents_TextInputEditText_FilledBox_Dense = 2131624315; + + // aapt resource value: 0x7F0E017C + public const int ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox = 2131624316; + + // aapt resource value: 0x7F0E017D + public const int ThemeOverlay_MaterialComponents_TextInputEditText_OutlinedBox_Dense = 2131624317; + + // aapt resource value: 0x7F0E013B + public const int Theme_AppCompat = 2131624251; + + // aapt resource value: 0x7F0E013C + public const int Theme_AppCompat_CompactMenu = 2131624252; + + // aapt resource value: 0x7F0E013D + public const int Theme_AppCompat_DayNight = 2131624253; + + // aapt resource value: 0x7F0E013E + public const int Theme_AppCompat_DayNight_DarkActionBar = 2131624254; + + // aapt resource value: 0x7F0E013F + public const int Theme_AppCompat_DayNight_Dialog = 2131624255; + + // aapt resource value: 0x7F0E0142 + public const int Theme_AppCompat_DayNight_DialogWhenLarge = 2131624258; + + // aapt resource value: 0x7F0E0140 + public const int Theme_AppCompat_DayNight_Dialog_Alert = 2131624256; + + // aapt resource value: 0x7F0E0141 + public const int Theme_AppCompat_DayNight_Dialog_MinWidth = 2131624257; + + // aapt resource value: 0x7F0E0143 + public const int Theme_AppCompat_DayNight_NoActionBar = 2131624259; + + // aapt resource value: 0x7F0E0144 + public const int Theme_AppCompat_Dialog = 2131624260; + + // aapt resource value: 0x7F0E0147 + public const int Theme_AppCompat_DialogWhenLarge = 2131624263; + + // aapt resource value: 0x7F0E0145 + public const int Theme_AppCompat_Dialog_Alert = 2131624261; + + // aapt resource value: 0x7F0E0146 + public const int Theme_AppCompat_Dialog_MinWidth = 2131624262; + + // aapt resource value: 0x7F0E0148 + public const int Theme_AppCompat_Light = 2131624264; + + // aapt resource value: 0x7F0E0149 + public const int Theme_AppCompat_Light_DarkActionBar = 2131624265; + + // aapt resource value: 0x7F0E014A + public const int Theme_AppCompat_Light_Dialog = 2131624266; + + // aapt resource value: 0x7F0E014D + public const int Theme_AppCompat_Light_DialogWhenLarge = 2131624269; + + // aapt resource value: 0x7F0E014B + public const int Theme_AppCompat_Light_Dialog_Alert = 2131624267; + + // aapt resource value: 0x7F0E014C + public const int Theme_AppCompat_Light_Dialog_MinWidth = 2131624268; + + // aapt resource value: 0x7F0E014E + public const int Theme_AppCompat_Light_NoActionBar = 2131624270; + + // aapt resource value: 0x7F0E014F + public const int Theme_AppCompat_NoActionBar = 2131624271; + + // aapt resource value: 0x7F0E0150 + public const int Theme_Design = 2131624272; + + // aapt resource value: 0x7F0E0151 + public const int Theme_Design_BottomSheetDialog = 2131624273; + + // aapt resource value: 0x7F0E0152 + public const int Theme_Design_Light = 2131624274; + + // aapt resource value: 0x7F0E0153 + public const int Theme_Design_Light_BottomSheetDialog = 2131624275; + + // aapt resource value: 0x7F0E0154 + public const int Theme_Design_Light_NoActionBar = 2131624276; + + // aapt resource value: 0x7F0E0155 + public const int Theme_Design_NoActionBar = 2131624277; + + // aapt resource value: 0x7F0E0156 + public const int Theme_MaterialComponents = 2131624278; + + // aapt resource value: 0x7F0E0157 + public const int Theme_MaterialComponents_BottomSheetDialog = 2131624279; + + // aapt resource value: 0x7F0E0158 + public const int Theme_MaterialComponents_Bridge = 2131624280; + + // aapt resource value: 0x7F0E0159 + public const int Theme_MaterialComponents_CompactMenu = 2131624281; + + // aapt resource value: 0x7F0E015A + public const int Theme_MaterialComponents_Dialog = 2131624282; + + // aapt resource value: 0x7F0E015D + public const int Theme_MaterialComponents_DialogWhenLarge = 2131624285; + + // aapt resource value: 0x7F0E015B + public const int Theme_MaterialComponents_Dialog_Alert = 2131624283; + + // aapt resource value: 0x7F0E015C + public const int Theme_MaterialComponents_Dialog_MinWidth = 2131624284; + + // aapt resource value: 0x7F0E015E + public const int Theme_MaterialComponents_Light = 2131624286; + + // aapt resource value: 0x7F0E015F + public const int Theme_MaterialComponents_Light_BottomSheetDialog = 2131624287; + + // aapt resource value: 0x7F0E0160 + public const int Theme_MaterialComponents_Light_Bridge = 2131624288; + + // aapt resource value: 0x7F0E0161 + public const int Theme_MaterialComponents_Light_DarkActionBar = 2131624289; + + // aapt resource value: 0x7F0E0162 + public const int Theme_MaterialComponents_Light_DarkActionBar_Bridge = 2131624290; + + // aapt resource value: 0x7F0E0163 + public const int Theme_MaterialComponents_Light_Dialog = 2131624291; + + // aapt resource value: 0x7F0E0166 + public const int Theme_MaterialComponents_Light_DialogWhenLarge = 2131624294; + + // aapt resource value: 0x7F0E0164 + public const int Theme_MaterialComponents_Light_Dialog_Alert = 2131624292; + + // aapt resource value: 0x7F0E0165 + public const int Theme_MaterialComponents_Light_Dialog_MinWidth = 2131624293; + + // aapt resource value: 0x7F0E0167 + public const int Theme_MaterialComponents_Light_NoActionBar = 2131624295; + + // aapt resource value: 0x7F0E0168 + public const int Theme_MaterialComponents_Light_NoActionBar_Bridge = 2131624296; + + // aapt resource value: 0x7F0E0169 + public const int Theme_MaterialComponents_NoActionBar = 2131624297; + + // aapt resource value: 0x7F0E016A + public const int Theme_MaterialComponents_NoActionBar_Bridge = 2131624298; + + // aapt resource value: 0x7F0E017E + public const int Widget_AppCompat_ActionBar = 2131624318; + + // aapt resource value: 0x7F0E017F + public const int Widget_AppCompat_ActionBar_Solid = 2131624319; + + // aapt resource value: 0x7F0E0180 + public const int Widget_AppCompat_ActionBar_TabBar = 2131624320; + + // aapt resource value: 0x7F0E0181 + public const int Widget_AppCompat_ActionBar_TabText = 2131624321; + + // aapt resource value: 0x7F0E0182 + public const int Widget_AppCompat_ActionBar_TabView = 2131624322; + + // aapt resource value: 0x7F0E0183 + public const int Widget_AppCompat_ActionButton = 2131624323; + + // aapt resource value: 0x7F0E0184 + public const int Widget_AppCompat_ActionButton_CloseMode = 2131624324; + + // aapt resource value: 0x7F0E0185 + public const int Widget_AppCompat_ActionButton_Overflow = 2131624325; + + // aapt resource value: 0x7F0E0186 + public const int Widget_AppCompat_ActionMode = 2131624326; + + // aapt resource value: 0x7F0E0187 + public const int Widget_AppCompat_ActivityChooserView = 2131624327; + + // aapt resource value: 0x7F0E0188 + public const int Widget_AppCompat_AutoCompleteTextView = 2131624328; + + // aapt resource value: 0x7F0E0189 + public const int Widget_AppCompat_Button = 2131624329; + + // aapt resource value: 0x7F0E018F + public const int Widget_AppCompat_ButtonBar = 2131624335; + + // aapt resource value: 0x7F0E0190 + public const int Widget_AppCompat_ButtonBar_AlertDialog = 2131624336; + + // aapt resource value: 0x7F0E018A + public const int Widget_AppCompat_Button_Borderless = 2131624330; + + // aapt resource value: 0x7F0E018B + public const int Widget_AppCompat_Button_Borderless_Colored = 2131624331; + + // aapt resource value: 0x7F0E018C + public const int Widget_AppCompat_Button_ButtonBar_AlertDialog = 2131624332; + + // aapt resource value: 0x7F0E018D + public const int Widget_AppCompat_Button_Colored = 2131624333; + + // aapt resource value: 0x7F0E018E + public const int Widget_AppCompat_Button_Small = 2131624334; + + // aapt resource value: 0x7F0E0191 + public const int Widget_AppCompat_CompoundButton_CheckBox = 2131624337; + + // aapt resource value: 0x7F0E0192 + public const int Widget_AppCompat_CompoundButton_RadioButton = 2131624338; + + // aapt resource value: 0x7F0E0193 + public const int Widget_AppCompat_CompoundButton_Switch = 2131624339; + + // aapt resource value: 0x7F0E0194 + public const int Widget_AppCompat_DrawerArrowToggle = 2131624340; + + // aapt resource value: 0x7F0E0195 + public const int Widget_AppCompat_DropDownItem_Spinner = 2131624341; + + // aapt resource value: 0x7F0E0196 + public const int Widget_AppCompat_EditText = 2131624342; + + // aapt resource value: 0x7F0E0197 + public const int Widget_AppCompat_ImageButton = 2131624343; + + // aapt resource value: 0x7F0E0198 + public const int Widget_AppCompat_Light_ActionBar = 2131624344; + + // aapt resource value: 0x7F0E0199 + public const int Widget_AppCompat_Light_ActionBar_Solid = 2131624345; + + // aapt resource value: 0x7F0E019A + public const int Widget_AppCompat_Light_ActionBar_Solid_Inverse = 2131624346; + + // aapt resource value: 0x7F0E019B + public const int Widget_AppCompat_Light_ActionBar_TabBar = 2131624347; + + // aapt resource value: 0x7F0E019C + public const int Widget_AppCompat_Light_ActionBar_TabBar_Inverse = 2131624348; + + // aapt resource value: 0x7F0E019D + public const int Widget_AppCompat_Light_ActionBar_TabText = 2131624349; + + // aapt resource value: 0x7F0E019E + public const int Widget_AppCompat_Light_ActionBar_TabText_Inverse = 2131624350; + + // aapt resource value: 0x7F0E019F + public const int Widget_AppCompat_Light_ActionBar_TabView = 2131624351; + + // aapt resource value: 0x7F0E01A0 + public const int Widget_AppCompat_Light_ActionBar_TabView_Inverse = 2131624352; + + // aapt resource value: 0x7F0E01A1 + public const int Widget_AppCompat_Light_ActionButton = 2131624353; + + // aapt resource value: 0x7F0E01A2 + public const int Widget_AppCompat_Light_ActionButton_CloseMode = 2131624354; + + // aapt resource value: 0x7F0E01A3 + public const int Widget_AppCompat_Light_ActionButton_Overflow = 2131624355; + + // aapt resource value: 0x7F0E01A4 + public const int Widget_AppCompat_Light_ActionMode_Inverse = 2131624356; + + // aapt resource value: 0x7F0E01A5 + public const int Widget_AppCompat_Light_ActivityChooserView = 2131624357; + + // aapt resource value: 0x7F0E01A6 + public const int Widget_AppCompat_Light_AutoCompleteTextView = 2131624358; + + // aapt resource value: 0x7F0E01A7 + public const int Widget_AppCompat_Light_DropDownItem_Spinner = 2131624359; + + // aapt resource value: 0x7F0E01A8 + public const int Widget_AppCompat_Light_ListPopupWindow = 2131624360; + + // aapt resource value: 0x7F0E01A9 + public const int Widget_AppCompat_Light_ListView_DropDown = 2131624361; + + // aapt resource value: 0x7F0E01AA + public const int Widget_AppCompat_Light_PopupMenu = 2131624362; + + // aapt resource value: 0x7F0E01AB + public const int Widget_AppCompat_Light_PopupMenu_Overflow = 2131624363; + + // aapt resource value: 0x7F0E01AC + public const int Widget_AppCompat_Light_SearchView = 2131624364; + + // aapt resource value: 0x7F0E01AD + public const int Widget_AppCompat_Light_Spinner_DropDown_ActionBar = 2131624365; + + // aapt resource value: 0x7F0E01AE + public const int Widget_AppCompat_ListMenuView = 2131624366; + + // aapt resource value: 0x7F0E01AF + public const int Widget_AppCompat_ListPopupWindow = 2131624367; + + // aapt resource value: 0x7F0E01B0 + public const int Widget_AppCompat_ListView = 2131624368; + + // aapt resource value: 0x7F0E01B1 + public const int Widget_AppCompat_ListView_DropDown = 2131624369; + + // aapt resource value: 0x7F0E01B2 + public const int Widget_AppCompat_ListView_Menu = 2131624370; + + // aapt resource value: 0x7F0E01B3 + public const int Widget_AppCompat_PopupMenu = 2131624371; + + // aapt resource value: 0x7F0E01B4 + public const int Widget_AppCompat_PopupMenu_Overflow = 2131624372; + + // aapt resource value: 0x7F0E01B5 + public const int Widget_AppCompat_PopupWindow = 2131624373; + + // aapt resource value: 0x7F0E01B6 + public const int Widget_AppCompat_ProgressBar = 2131624374; + + // aapt resource value: 0x7F0E01B7 + public const int Widget_AppCompat_ProgressBar_Horizontal = 2131624375; + + // aapt resource value: 0x7F0E01B8 + public const int Widget_AppCompat_RatingBar = 2131624376; + + // aapt resource value: 0x7F0E01B9 + public const int Widget_AppCompat_RatingBar_Indicator = 2131624377; + + // aapt resource value: 0x7F0E01BA + public const int Widget_AppCompat_RatingBar_Small = 2131624378; + + // aapt resource value: 0x7F0E01BB + public const int Widget_AppCompat_SearchView = 2131624379; + + // aapt resource value: 0x7F0E01BC + public const int Widget_AppCompat_SearchView_ActionBar = 2131624380; + + // aapt resource value: 0x7F0E01BD + public const int Widget_AppCompat_SeekBar = 2131624381; + + // aapt resource value: 0x7F0E01BE + public const int Widget_AppCompat_SeekBar_Discrete = 2131624382; + + // aapt resource value: 0x7F0E01BF + public const int Widget_AppCompat_Spinner = 2131624383; + + // aapt resource value: 0x7F0E01C0 + public const int Widget_AppCompat_Spinner_DropDown = 2131624384; + + // aapt resource value: 0x7F0E01C1 + public const int Widget_AppCompat_Spinner_DropDown_ActionBar = 2131624385; + + // aapt resource value: 0x7F0E01C2 + public const int Widget_AppCompat_Spinner_Underlined = 2131624386; + + // aapt resource value: 0x7F0E01C3 + public const int Widget_AppCompat_TextView_SpinnerItem = 2131624387; + + // aapt resource value: 0x7F0E01C4 + public const int Widget_AppCompat_Toolbar = 2131624388; + + // aapt resource value: 0x7F0E01C5 + public const int Widget_AppCompat_Toolbar_Button_Navigation = 2131624389; + + // aapt resource value: 0x7F0E01C6 + public const int Widget_Compat_NotificationActionContainer = 2131624390; + + // aapt resource value: 0x7F0E01C7 + public const int Widget_Compat_NotificationActionText = 2131624391; + + // aapt resource value: 0x7F0E01C8 + public const int Widget_Design_AppBarLayout = 2131624392; + + // aapt resource value: 0x7F0E01C9 + public const int Widget_Design_BottomNavigationView = 2131624393; + + // aapt resource value: 0x7F0E01CA + public const int Widget_Design_BottomSheet_Modal = 2131624394; + + // aapt resource value: 0x7F0E01CB + public const int Widget_Design_CollapsingToolbar = 2131624395; + + // aapt resource value: 0x7F0E01CC + public const int Widget_Design_FloatingActionButton = 2131624396; + + // aapt resource value: 0x7F0E01CD + public const int Widget_Design_NavigationView = 2131624397; + + // aapt resource value: 0x7F0E01CE + public const int Widget_Design_ScrimInsetsFrameLayout = 2131624398; + + // aapt resource value: 0x7F0E01CF + public const int Widget_Design_Snackbar = 2131624399; + + // aapt resource value: 0x7F0E01D0 + public const int Widget_Design_TabLayout = 2131624400; + + // aapt resource value: 0x7F0E01D1 + public const int Widget_Design_TextInputLayout = 2131624401; + + // aapt resource value: 0x7F0E01D2 + public const int Widget_MaterialComponents_BottomAppBar = 2131624402; + + // aapt resource value: 0x7F0E01D3 + public const int Widget_MaterialComponents_BottomAppBar_Colored = 2131624403; + + // aapt resource value: 0x7F0E01D4 + public const int Widget_MaterialComponents_BottomNavigationView = 2131624404; + + // aapt resource value: 0x7F0E01D5 + public const int Widget_MaterialComponents_BottomNavigationView_Colored = 2131624405; + + // aapt resource value: 0x7F0E01D6 + public const int Widget_MaterialComponents_BottomSheet_Modal = 2131624406; + + // aapt resource value: 0x7F0E01D7 + public const int Widget_MaterialComponents_Button = 2131624407; + + // aapt resource value: 0x7F0E01D8 + public const int Widget_MaterialComponents_Button_Icon = 2131624408; + + // aapt resource value: 0x7F0E01D9 + public const int Widget_MaterialComponents_Button_OutlinedButton = 2131624409; + + // aapt resource value: 0x7F0E01DA + public const int Widget_MaterialComponents_Button_OutlinedButton_Icon = 2131624410; + + // aapt resource value: 0x7F0E01DB + public const int Widget_MaterialComponents_Button_TextButton = 2131624411; + + // aapt resource value: 0x7F0E01DC + public const int Widget_MaterialComponents_Button_TextButton_Dialog = 2131624412; + + // aapt resource value: 0x7F0E01DD + public const int Widget_MaterialComponents_Button_TextButton_Dialog_Icon = 2131624413; + + // aapt resource value: 0x7F0E01DE + public const int Widget_MaterialComponents_Button_TextButton_Icon = 2131624414; + + // aapt resource value: 0x7F0E01DF + public const int Widget_MaterialComponents_Button_UnelevatedButton = 2131624415; + + // aapt resource value: 0x7F0E01E0 + public const int Widget_MaterialComponents_Button_UnelevatedButton_Icon = 2131624416; + + // aapt resource value: 0x7F0E01E1 + public const int Widget_MaterialComponents_CardView = 2131624417; + + // aapt resource value: 0x7F0E01E6 + public const int Widget_MaterialComponents_ChipGroup = 2131624422; + + // aapt resource value: 0x7F0E01E2 + public const int Widget_MaterialComponents_Chip_Action = 2131624418; + + // aapt resource value: 0x7F0E01E3 + public const int Widget_MaterialComponents_Chip_Choice = 2131624419; + + // aapt resource value: 0x7F0E01E4 + public const int Widget_MaterialComponents_Chip_Entry = 2131624420; + + // aapt resource value: 0x7F0E01E5 + public const int Widget_MaterialComponents_Chip_Filter = 2131624421; + + // aapt resource value: 0x7F0E01E7 + public const int Widget_MaterialComponents_FloatingActionButton = 2131624423; + + // aapt resource value: 0x7F0E01E8 + public const int Widget_MaterialComponents_NavigationView = 2131624424; + + // aapt resource value: 0x7F0E01E9 + public const int Widget_MaterialComponents_Snackbar = 2131624425; + + // aapt resource value: 0x7F0E01EA + public const int Widget_MaterialComponents_Snackbar_FullWidth = 2131624426; + + // aapt resource value: 0x7F0E01EB + public const int Widget_MaterialComponents_TabLayout = 2131624427; + + // aapt resource value: 0x7F0E01EC + public const int Widget_MaterialComponents_TabLayout_Colored = 2131624428; + + // aapt resource value: 0x7F0E01ED + public const int Widget_MaterialComponents_TextInputEditText_FilledBox = 2131624429; + + // aapt resource value: 0x7F0E01EE + public const int Widget_MaterialComponents_TextInputEditText_FilledBox_Dense = 2131624430; + + // aapt resource value: 0x7F0E01EF + public const int Widget_MaterialComponents_TextInputEditText_OutlinedBox = 2131624431; + + // aapt resource value: 0x7F0E01F0 + public const int Widget_MaterialComponents_TextInputEditText_OutlinedBox_Dense = 2131624432; + + // aapt resource value: 0x7F0E01F1 + public const int Widget_MaterialComponents_TextInputLayout_FilledBox = 2131624433; + + // aapt resource value: 0x7F0E01F2 + public const int Widget_MaterialComponents_TextInputLayout_FilledBox_Dense = 2131624434; + + // aapt resource value: 0x7F0E01F3 + public const int Widget_MaterialComponents_TextInputLayout_OutlinedBox = 2131624435; + + // aapt resource value: 0x7F0E01F4 + public const int Widget_MaterialComponents_TextInputLayout_OutlinedBox_Dense = 2131624436; + + // aapt resource value: 0x7F0E01F5 + public const int Widget_MaterialComponents_Toolbar = 2131624437; + + // aapt resource value: 0x7F0E01F6 + public const int Widget_Support_CoordinatorLayout = 2131624438; + + static Style() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Style() + { + } + } + + public partial class Styleable + { + + // aapt resource value: { 0x7F030031,0x7F030032,0x7F030033,0x7F030092,0x7F030093,0x7F030094,0x7F030095,0x7F030096,0x7F030097,0x7F0300A5,0x7F0300AA,0x7F0300AB,0x7F0300B6,0x7F0300E0,0x7F0300E5,0x7F0300EA,0x7F0300EB,0x7F0300ED,0x7F0300F7,0x7F030101,0x7F030124,0x7F030130,0x7F030141,0x7F030145,0x7F030146,0x7F030175,0x7F030178,0x7F0301BD,0x7F0301C7 } + public static int[] ActionBar = new int[] { + 2130903089, + 2130903090, + 2130903091, + 2130903186, + 2130903187, + 2130903188, + 2130903189, + 2130903190, + 2130903191, + 2130903205, + 2130903210, + 2130903211, + 2130903222, + 2130903264, + 2130903269, + 2130903274, + 2130903275, + 2130903277, + 2130903287, + 2130903297, + 2130903332, + 2130903344, + 2130903361, + 2130903365, + 2130903366, + 2130903413, + 2130903416, + 2130903485, + 2130903495}; + + // aapt resource value: { 0x10100B3 } + public static int[] ActionBarLayout = new int[] { + 16842931}; + + // aapt resource value: 0 + public const int ActionBarLayout_android_layout_gravity = 0; + + // aapt resource value: 0 + public const int ActionBar_background = 0; + + // aapt resource value: 1 + public const int ActionBar_backgroundSplit = 1; + + // aapt resource value: 2 + public const int ActionBar_backgroundStacked = 2; + + // aapt resource value: 3 + public const int ActionBar_contentInsetEnd = 3; + + // aapt resource value: 4 + public const int ActionBar_contentInsetEndWithActions = 4; + + // aapt resource value: 5 + public const int ActionBar_contentInsetLeft = 5; + + // aapt resource value: 6 + public const int ActionBar_contentInsetRight = 6; + + // aapt resource value: 7 + public const int ActionBar_contentInsetStart = 7; + + // aapt resource value: 8 + public const int ActionBar_contentInsetStartWithNavigation = 8; + + // aapt resource value: 9 + public const int ActionBar_customNavigationLayout = 9; + + // aapt resource value: 10 + public const int ActionBar_displayOptions = 10; + + // aapt resource value: 11 + public const int ActionBar_divider = 11; + + // aapt resource value: 12 + public const int ActionBar_elevation = 12; + + // aapt resource value: 13 + public const int ActionBar_height = 13; + + // aapt resource value: 14 + public const int ActionBar_hideOnContentScroll = 14; + + // aapt resource value: 15 + public const int ActionBar_homeAsUpIndicator = 15; + + // aapt resource value: 16 + public const int ActionBar_homeLayout = 16; + + // aapt resource value: 17 + public const int ActionBar_icon = 17; + + // aapt resource value: 18 + public const int ActionBar_indeterminateProgressStyle = 18; + + // aapt resource value: 19 + public const int ActionBar_itemPadding = 19; + + // aapt resource value: 20 + public const int ActionBar_logo = 20; + + // aapt resource value: 21 + public const int ActionBar_navigationMode = 21; + + // aapt resource value: 22 + public const int ActionBar_popupTheme = 22; + + // aapt resource value: 23 + public const int ActionBar_progressBarPadding = 23; + + // aapt resource value: 24 + public const int ActionBar_progressBarStyle = 24; + + // aapt resource value: 25 + public const int ActionBar_subtitle = 25; + + // aapt resource value: 26 + public const int ActionBar_subtitleTextStyle = 26; + + // aapt resource value: 27 + public const int ActionBar_title = 27; + + // aapt resource value: 28 + public const int ActionBar_titleTextStyle = 28; + + // aapt resource value: { 0x101013F } + public static int[] ActionMenuItemView = new int[] { + 16843071}; + + // aapt resource value: 0 + public const int ActionMenuItemView_android_minWidth = 0; + + // aapt resource value: { 0xFFFFFFFF } + public static int[] ActionMenuView = new int[] { + -1}; + + // aapt resource value: { 0x7F030031,0x7F030032,0x7F03007E,0x7F0300E0,0x7F030178,0x7F0301C7 } + public static int[] ActionMode = new int[] { + 2130903089, + 2130903090, + 2130903166, + 2130903264, + 2130903416, + 2130903495}; + + // aapt resource value: 0 + public const int ActionMode_background = 0; + + // aapt resource value: 1 + public const int ActionMode_backgroundSplit = 1; + + // aapt resource value: 2 + public const int ActionMode_closeItemLayout = 2; + + // aapt resource value: 3 + public const int ActionMode_height = 3; + + // aapt resource value: 4 + public const int ActionMode_subtitleTextStyle = 4; + + // aapt resource value: 5 + public const int ActionMode_titleTextStyle = 5; + + // aapt resource value: { 0x7F0300BB,0x7F0300F8 } + public static int[] ActivityChooserView = new int[] { + 2130903227, + 2130903288}; + + // aapt resource value: 0 + public const int ActivityChooserView_expandActivityOverflowButtonDrawable = 0; + + // aapt resource value: 1 + public const int ActivityChooserView_initialActivityCount = 1; + + // aapt resource value: { 0x10100F2,0x7F030052,0x7F030053,0x7F03011B,0x7F03011C,0x7F03012D,0x7F03015D,0x7F03015E } + public static int[] AlertDialog = new int[] { + 16842994, + 2130903122, + 2130903123, + 2130903323, + 2130903324, + 2130903341, + 2130903389, + 2130903390}; + + // aapt resource value: 0 + public const int AlertDialog_android_layout = 0; + + // aapt resource value: 1 + public const int AlertDialog_buttonIconDimen = 1; + + // aapt resource value: 2 + public const int AlertDialog_buttonPanelSideLayout = 2; + + // aapt resource value: 3 + public const int AlertDialog_listItemLayout = 3; + + // aapt resource value: 4 + public const int AlertDialog_listLayout = 4; + + // aapt resource value: 5 + public const int AlertDialog_multiChoiceItemLayout = 5; + + // aapt resource value: 6 + public const int AlertDialog_showTitle = 6; + + // aapt resource value: 7 + public const int AlertDialog_singleChoiceItemLayout = 7; + + // aapt resource value: { 0x101011C,0x1010194,0x1010195,0x1010196,0x101030C,0x101030D } + public static int[] AnimatedStateListDrawableCompat = new int[] { + 16843036, + 16843156, + 16843157, + 16843158, + 16843532, + 16843533}; + + // aapt resource value: 3 + public const int AnimatedStateListDrawableCompat_android_constantSize = 3; + + // aapt resource value: 0 + public const int AnimatedStateListDrawableCompat_android_dither = 0; + + // aapt resource value: 4 + public const int AnimatedStateListDrawableCompat_android_enterFadeDuration = 4; + + // aapt resource value: 5 + public const int AnimatedStateListDrawableCompat_android_exitFadeDuration = 5; + + // aapt resource value: 2 + public const int AnimatedStateListDrawableCompat_android_variablePadding = 2; + + // aapt resource value: 1 + public const int AnimatedStateListDrawableCompat_android_visible = 1; + + // aapt resource value: { 0x10100D0,0x1010199 } + public static int[] AnimatedStateListDrawableItem = new int[] { + 16842960, + 16843161}; + + // aapt resource value: 1 + public const int AnimatedStateListDrawableItem_android_drawable = 1; + + // aapt resource value: 0 + public const int AnimatedStateListDrawableItem_android_id = 0; + + // aapt resource value: { 0x1010199,0x1010449,0x101044A,0x101044B } + public static int[] AnimatedStateListDrawableTransition = new int[] { + 16843161, + 16843849, + 16843850, + 16843851}; + + // aapt resource value: 0 + public const int AnimatedStateListDrawableTransition_android_drawable = 0; + + // aapt resource value: 2 + public const int AnimatedStateListDrawableTransition_android_fromId = 2; + + // aapt resource value: 3 + public const int AnimatedStateListDrawableTransition_android_reversible = 3; + + // aapt resource value: 1 + public const int AnimatedStateListDrawableTransition_android_toId = 1; + + // aapt resource value: { 0x10100D4,0x101048F,0x1010540,0x7F0300B6,0x7F0300BC,0x7F030116 } + public static int[] AppBarLayout = new int[] { + 16842964, + 16843919, + 16844096, + 2130903222, + 2130903228, + 2130903318}; + + // aapt resource value: { 0x7F03016B,0x7F03016C,0x7F03016D,0x7F03016E } + public static int[] AppBarLayoutStates = new int[] { + 2130903403, + 2130903404, + 2130903405, + 2130903406}; + + // aapt resource value: 0 + public const int AppBarLayoutStates_state_collapsed = 0; + + // aapt resource value: 1 + public const int AppBarLayoutStates_state_collapsible = 1; + + // aapt resource value: 2 + public const int AppBarLayoutStates_state_liftable = 2; + + // aapt resource value: 3 + public const int AppBarLayoutStates_state_lifted = 3; + + // aapt resource value: 0 + public const int AppBarLayout_android_background = 0; + + // aapt resource value: 2 + public const int AppBarLayout_android_keyboardNavigationCluster = 2; + + // aapt resource value: 1 + public const int AppBarLayout_android_touchscreenBlocksFocus = 1; + + // aapt resource value: 3 + public const int AppBarLayout_elevation = 3; + + // aapt resource value: 4 + public const int AppBarLayout_expanded = 4; + + // aapt resource value: { 0x7F030114,0x7F030115 } + public static int[] AppBarLayout_Layout = new int[] { + 2130903316, + 2130903317}; + + // aapt resource value: 0 + public const int AppBarLayout_Layout_layout_scrollFlags = 0; + + // aapt resource value: 1 + public const int AppBarLayout_Layout_layout_scrollInterpolator = 1; + + // aapt resource value: 5 + public const int AppBarLayout_liftOnScroll = 5; + + // aapt resource value: { 0x1010119,0x7F030168,0x7F0301BB,0x7F0301BC } + public static int[] AppCompatImageView = new int[] { + 16843033, + 2130903400, + 2130903483, + 2130903484}; + + // aapt resource value: 0 + public const int AppCompatImageView_android_src = 0; + + // aapt resource value: 1 + public const int AppCompatImageView_srcCompat = 1; + + // aapt resource value: 2 + public const int AppCompatImageView_tint = 2; + + // aapt resource value: 3 + public const int AppCompatImageView_tintMode = 3; + + // aapt resource value: { 0x1010142,0x7F0301B8,0x7F0301B9,0x7F0301BA } + public static int[] AppCompatSeekBar = new int[] { + 16843074, + 2130903480, + 2130903481, + 2130903482}; + + // aapt resource value: 0 + public const int AppCompatSeekBar_android_thumb = 0; + + // aapt resource value: 1 + public const int AppCompatSeekBar_tickMark = 1; + + // aapt resource value: 2 + public const int AppCompatSeekBar_tickMarkTint = 2; + + // aapt resource value: 3 + public const int AppCompatSeekBar_tickMarkTintMode = 3; + + // aapt resource value: { 0x1010034,0x101016D,0x101016E,0x101016F,0x1010170,0x1010392,0x1010393 } + public static int[] AppCompatTextHelper = new int[] { + 16842804, + 16843117, + 16843118, + 16843119, + 16843120, + 16843666, + 16843667}; + + // aapt resource value: 2 + public const int AppCompatTextHelper_android_drawableBottom = 2; + + // aapt resource value: 6 + public const int AppCompatTextHelper_android_drawableEnd = 6; + + // aapt resource value: 3 + public const int AppCompatTextHelper_android_drawableLeft = 3; + + // aapt resource value: 4 + public const int AppCompatTextHelper_android_drawableRight = 4; + + // aapt resource value: 5 + public const int AppCompatTextHelper_android_drawableStart = 5; + + // aapt resource value: 1 + public const int AppCompatTextHelper_android_drawableTop = 1; + + // aapt resource value: 0 + public const int AppCompatTextHelper_android_textAppearance = 0; + + // aapt resource value: { 0x1010034,0x7F03002C,0x7F03002D,0x7F03002E,0x7F03002F,0x7F030030,0x7F0300CF,0x7F0300D2,0x7F030109,0x7F030117,0x7F030198 } + public static int[] AppCompatTextView = new int[] { + 16842804, + 2130903084, + 2130903085, + 2130903086, + 2130903087, + 2130903088, + 2130903247, + 2130903250, + 2130903305, + 2130903319, + 2130903448}; + + // aapt resource value: 0 + public const int AppCompatTextView_android_textAppearance = 0; + + // aapt resource value: 1 + public const int AppCompatTextView_autoSizeMaxTextSize = 1; + + // aapt resource value: 2 + public const int AppCompatTextView_autoSizeMinTextSize = 2; + + // aapt resource value: 3 + public const int AppCompatTextView_autoSizePresetSizes = 3; + + // aapt resource value: 4 + public const int AppCompatTextView_autoSizeStepGranularity = 4; + + // aapt resource value: 5 + public const int AppCompatTextView_autoSizeTextType = 5; + + // aapt resource value: 6 + public const int AppCompatTextView_firstBaselineToTopHeight = 6; + + // aapt resource value: 7 + public const int AppCompatTextView_fontFamily = 7; + + // aapt resource value: 8 + public const int AppCompatTextView_lastBaselineToBottomHeight = 8; + + // aapt resource value: 9 + public const int AppCompatTextView_lineHeight = 9; + + // aapt resource value: 10 + public const int AppCompatTextView_textAllCaps = 10; + + // aapt resource value: { 0x1010057,0x10100AE,0x7F030000,0x7F030001,0x7F030002,0x7F030003,0x7F030004,0x7F030005,0x7F030006,0x7F030007,0x7F030008,0x7F030009,0x7F03000A,0x7F03000B,0x7F03000C,0x7F03000E,0x7F03000F,0x7F030010,0x7F030011,0x7F030012,0x7F030013,0x7F030014,0x7F030015,0x7F030016,0x7F030017,0x7F030018,0x7F030019,0x7F03001A,0x7F03001B,0x7F03001C,0x7F03001D,0x7F03001E,0x7F030021,0x7F030022,0x7F030023,0x7F030024,0x7F030025,0x7F03002B,0x7F03003E,0x7F03004C,0x7F03004D,0x7F03004E,0x7F03004F,0x7F030050,0x7F030054,0x7F030055,0x7F03005F,0x7F030064,0x7F030085,0x7F030086,0x7F030087,0x7F030088,0x7F030089,0x7F03008A,0x7F03008B,0x7F03008C,0x7F03008D,0x7F03008F,0x7F03009E,0x7F0300A7,0x7F0300A8,0x7F0300A9,0x7F0300AC,0x7F0300AE,0x7F0300B1,0x7F0300B2,0x7F0300B3,0x7F0300B4,0x7F0300B5,0x7F0300EA,0x7F0300F6,0x7F030119,0x7F03011A,0x7F03011D,0x7F03011E,0x7F03011F,0x7F030120,0x7F030121,0x7F030122,0x7F030123,0x7F030138,0x7F030139,0x7F03013A,0x7F030140,0x7F030142,0x7F030149,0x7F03014A,0x7F03014B,0x7F03014C,0x7F030155,0x7F030156,0x7F030157,0x7F030158,0x7F030165,0x7F030166,0x7F03017C,0x7F0301A3,0x7F0301A4,0x7F0301A5,0x7F0301A6,0x7F0301A8,0x7F0301A9,0x7F0301AA,0x7F0301AB,0x7F0301AE,0x7F0301AF,0x7F0301C9,0x7F0301CA,0x7F0301CB,0x7F0301CC,0x7F0301D3,0x7F0301D5,0x7F0301D6,0x7F0301D7,0x7F0301D8,0x7F0301D9,0x7F0301DA,0x7F0301DB,0x7F0301DC,0x7F0301DD,0x7F0301DE } + public static int[] AppCompatTheme = new int[] { + 16842839, + 16842926, + 2130903040, + 2130903041, + 2130903042, + 2130903043, + 2130903044, + 2130903045, + 2130903046, + 2130903047, + 2130903048, + 2130903049, + 2130903050, + 2130903051, + 2130903052, + 2130903054, + 2130903055, + 2130903056, + 2130903057, + 2130903058, + 2130903059, + 2130903060, + 2130903061, + 2130903062, + 2130903063, + 2130903064, + 2130903065, + 2130903066, + 2130903067, + 2130903068, + 2130903069, + 2130903070, + 2130903073, + 2130903074, + 2130903075, + 2130903076, + 2130903077, + 2130903083, + 2130903102, + 2130903116, + 2130903117, + 2130903118, + 2130903119, + 2130903120, + 2130903124, + 2130903125, + 2130903135, + 2130903140, + 2130903173, + 2130903174, + 2130903175, + 2130903176, + 2130903177, + 2130903178, + 2130903179, + 2130903180, + 2130903181, + 2130903183, + 2130903198, + 2130903207, + 2130903208, + 2130903209, + 2130903212, + 2130903214, + 2130903217, + 2130903218, + 2130903219, + 2130903220, + 2130903221, + 2130903274, + 2130903286, + 2130903321, + 2130903322, + 2130903325, + 2130903326, + 2130903327, + 2130903328, + 2130903329, + 2130903330, + 2130903331, + 2130903352, + 2130903353, + 2130903354, + 2130903360, + 2130903362, + 2130903369, + 2130903370, + 2130903371, + 2130903372, + 2130903381, + 2130903382, + 2130903383, + 2130903384, + 2130903397, + 2130903398, + 2130903420, + 2130903459, + 2130903460, + 2130903461, + 2130903462, + 2130903464, + 2130903465, + 2130903466, + 2130903467, + 2130903470, + 2130903471, + 2130903497, + 2130903498, + 2130903499, + 2130903500, + 2130903507, + 2130903509, + 2130903510, + 2130903511, + 2130903512, + 2130903513, + 2130903514, + 2130903515, + 2130903516, + 2130903517, + 2130903518}; + + // aapt resource value: 2 + public const int AppCompatTheme_actionBarDivider = 2; + + // aapt resource value: 3 + public const int AppCompatTheme_actionBarItemBackground = 3; + + // aapt resource value: 4 + public const int AppCompatTheme_actionBarPopupTheme = 4; + + // aapt resource value: 5 + public const int AppCompatTheme_actionBarSize = 5; + + // aapt resource value: 6 + public const int AppCompatTheme_actionBarSplitStyle = 6; + + // aapt resource value: 7 + public const int AppCompatTheme_actionBarStyle = 7; + + // aapt resource value: 8 + public const int AppCompatTheme_actionBarTabBarStyle = 8; + + // aapt resource value: 9 + public const int AppCompatTheme_actionBarTabStyle = 9; + + // aapt resource value: 10 + public const int AppCompatTheme_actionBarTabTextStyle = 10; + + // aapt resource value: 11 + public const int AppCompatTheme_actionBarTheme = 11; + + // aapt resource value: 12 + public const int AppCompatTheme_actionBarWidgetTheme = 12; + + // aapt resource value: 13 + public const int AppCompatTheme_actionButtonStyle = 13; + + // aapt resource value: 14 + public const int AppCompatTheme_actionDropDownStyle = 14; + + // aapt resource value: 15 + public const int AppCompatTheme_actionMenuTextAppearance = 15; + + // aapt resource value: 16 + public const int AppCompatTheme_actionMenuTextColor = 16; + + // aapt resource value: 17 + public const int AppCompatTheme_actionModeBackground = 17; + + // aapt resource value: 18 + public const int AppCompatTheme_actionModeCloseButtonStyle = 18; + + // aapt resource value: 19 + public const int AppCompatTheme_actionModeCloseDrawable = 19; + + // aapt resource value: 20 + public const int AppCompatTheme_actionModeCopyDrawable = 20; + + // aapt resource value: 21 + public const int AppCompatTheme_actionModeCutDrawable = 21; + + // aapt resource value: 22 + public const int AppCompatTheme_actionModeFindDrawable = 22; + + // aapt resource value: 23 + public const int AppCompatTheme_actionModePasteDrawable = 23; + + // aapt resource value: 24 + public const int AppCompatTheme_actionModePopupWindowStyle = 24; + + // aapt resource value: 25 + public const int AppCompatTheme_actionModeSelectAllDrawable = 25; + + // aapt resource value: 26 + public const int AppCompatTheme_actionModeShareDrawable = 26; + + // aapt resource value: 27 + public const int AppCompatTheme_actionModeSplitBackground = 27; + + // aapt resource value: 28 + public const int AppCompatTheme_actionModeStyle = 28; + + // aapt resource value: 29 + public const int AppCompatTheme_actionModeWebSearchDrawable = 29; + + // aapt resource value: 30 + public const int AppCompatTheme_actionOverflowButtonStyle = 30; + + // aapt resource value: 31 + public const int AppCompatTheme_actionOverflowMenuStyle = 31; + + // aapt resource value: 32 + public const int AppCompatTheme_activityChooserViewStyle = 32; + + // aapt resource value: 33 + public const int AppCompatTheme_alertDialogButtonGroupStyle = 33; + + // aapt resource value: 34 + public const int AppCompatTheme_alertDialogCenterButtons = 34; + + // aapt resource value: 35 + public const int AppCompatTheme_alertDialogStyle = 35; + + // aapt resource value: 36 + public const int AppCompatTheme_alertDialogTheme = 36; + + // aapt resource value: 1 + public const int AppCompatTheme_android_windowAnimationStyle = 1; + + // aapt resource value: 0 + public const int AppCompatTheme_android_windowIsFloating = 0; + + // aapt resource value: 37 + public const int AppCompatTheme_autoCompleteTextViewStyle = 37; + + // aapt resource value: 38 + public const int AppCompatTheme_borderlessButtonStyle = 38; + + // aapt resource value: 39 + public const int AppCompatTheme_buttonBarButtonStyle = 39; + + // aapt resource value: 40 + public const int AppCompatTheme_buttonBarNegativeButtonStyle = 40; + + // aapt resource value: 41 + public const int AppCompatTheme_buttonBarNeutralButtonStyle = 41; + + // aapt resource value: 42 + public const int AppCompatTheme_buttonBarPositiveButtonStyle = 42; + + // aapt resource value: 43 + public const int AppCompatTheme_buttonBarStyle = 43; + + // aapt resource value: 44 + public const int AppCompatTheme_buttonStyle = 44; + + // aapt resource value: 45 + public const int AppCompatTheme_buttonStyleSmall = 45; + + // aapt resource value: 46 + public const int AppCompatTheme_checkboxStyle = 46; + + // aapt resource value: 47 + public const int AppCompatTheme_checkedTextViewStyle = 47; + + // aapt resource value: 48 + public const int AppCompatTheme_colorAccent = 48; + + // aapt resource value: 49 + public const int AppCompatTheme_colorBackgroundFloating = 49; + + // aapt resource value: 50 + public const int AppCompatTheme_colorButtonNormal = 50; + + // aapt resource value: 51 + public const int AppCompatTheme_colorControlActivated = 51; + + // aapt resource value: 52 + public const int AppCompatTheme_colorControlHighlight = 52; + + // aapt resource value: 53 + public const int AppCompatTheme_colorControlNormal = 53; + + // aapt resource value: 54 + public const int AppCompatTheme_colorError = 54; + + // aapt resource value: 55 + public const int AppCompatTheme_colorPrimary = 55; + + // aapt resource value: 56 + public const int AppCompatTheme_colorPrimaryDark = 56; + + // aapt resource value: 57 + public const int AppCompatTheme_colorSwitchThumbNormal = 57; + + // aapt resource value: 58 + public const int AppCompatTheme_controlBackground = 58; + + // aapt resource value: 59 + public const int AppCompatTheme_dialogCornerRadius = 59; + + // aapt resource value: 60 + public const int AppCompatTheme_dialogPreferredPadding = 60; + + // aapt resource value: 61 + public const int AppCompatTheme_dialogTheme = 61; + + // aapt resource value: 62 + public const int AppCompatTheme_dividerHorizontal = 62; + + // aapt resource value: 63 + public const int AppCompatTheme_dividerVertical = 63; + + // aapt resource value: 65 + public const int AppCompatTheme_dropdownListPreferredItemHeight = 65; + + // aapt resource value: 64 + public const int AppCompatTheme_dropDownListViewStyle = 64; + + // aapt resource value: 66 + public const int AppCompatTheme_editTextBackground = 66; + + // aapt resource value: 67 + public const int AppCompatTheme_editTextColor = 67; + + // aapt resource value: 68 + public const int AppCompatTheme_editTextStyle = 68; + + // aapt resource value: 69 + public const int AppCompatTheme_homeAsUpIndicator = 69; + + // aapt resource value: 70 + public const int AppCompatTheme_imageButtonStyle = 70; + + // aapt resource value: 71 + public const int AppCompatTheme_listChoiceBackgroundIndicator = 71; + + // aapt resource value: 72 + public const int AppCompatTheme_listDividerAlertDialog = 72; + + // aapt resource value: 73 + public const int AppCompatTheme_listMenuViewStyle = 73; + + // aapt resource value: 74 + public const int AppCompatTheme_listPopupWindowStyle = 74; + + // aapt resource value: 75 + public const int AppCompatTheme_listPreferredItemHeight = 75; + + // aapt resource value: 76 + public const int AppCompatTheme_listPreferredItemHeightLarge = 76; + + // aapt resource value: 77 + public const int AppCompatTheme_listPreferredItemHeightSmall = 77; + + // aapt resource value: 78 + public const int AppCompatTheme_listPreferredItemPaddingLeft = 78; + + // aapt resource value: 79 + public const int AppCompatTheme_listPreferredItemPaddingRight = 79; + + // aapt resource value: 80 + public const int AppCompatTheme_panelBackground = 80; + + // aapt resource value: 81 + public const int AppCompatTheme_panelMenuListTheme = 81; + + // aapt resource value: 82 + public const int AppCompatTheme_panelMenuListWidth = 82; + + // aapt resource value: 83 + public const int AppCompatTheme_popupMenuStyle = 83; + + // aapt resource value: 84 + public const int AppCompatTheme_popupWindowStyle = 84; + + // aapt resource value: 85 + public const int AppCompatTheme_radioButtonStyle = 85; + + // aapt resource value: 86 + public const int AppCompatTheme_ratingBarStyle = 86; + + // aapt resource value: 87 + public const int AppCompatTheme_ratingBarStyleIndicator = 87; + + // aapt resource value: 88 + public const int AppCompatTheme_ratingBarStyleSmall = 88; + + // aapt resource value: 89 + public const int AppCompatTheme_searchViewStyle = 89; + + // aapt resource value: 90 + public const int AppCompatTheme_seekBarStyle = 90; + + // aapt resource value: 91 + public const int AppCompatTheme_selectableItemBackground = 91; + + // aapt resource value: 92 + public const int AppCompatTheme_selectableItemBackgroundBorderless = 92; + + // aapt resource value: 93 + public const int AppCompatTheme_spinnerDropDownItemStyle = 93; + + // aapt resource value: 94 + public const int AppCompatTheme_spinnerStyle = 94; + + // aapt resource value: 95 + public const int AppCompatTheme_switchStyle = 95; + + // aapt resource value: 96 + public const int AppCompatTheme_textAppearanceLargePopupMenu = 96; + + // aapt resource value: 97 + public const int AppCompatTheme_textAppearanceListItem = 97; + + // aapt resource value: 98 + public const int AppCompatTheme_textAppearanceListItemSecondary = 98; + + // aapt resource value: 99 + public const int AppCompatTheme_textAppearanceListItemSmall = 99; + + // aapt resource value: 100 + public const int AppCompatTheme_textAppearancePopupMenuHeader = 100; + + // aapt resource value: 101 + public const int AppCompatTheme_textAppearanceSearchResultSubtitle = 101; + + // aapt resource value: 102 + public const int AppCompatTheme_textAppearanceSearchResultTitle = 102; + + // aapt resource value: 103 + public const int AppCompatTheme_textAppearanceSmallPopupMenu = 103; + + // aapt resource value: 104 + public const int AppCompatTheme_textColorAlertDialogListItem = 104; + + // aapt resource value: 105 + public const int AppCompatTheme_textColorSearchUrl = 105; + + // aapt resource value: 106 + public const int AppCompatTheme_toolbarNavigationButtonStyle = 106; + + // aapt resource value: 107 + public const int AppCompatTheme_toolbarStyle = 107; + + // aapt resource value: 108 + public const int AppCompatTheme_tooltipForegroundColor = 108; + + // aapt resource value: 109 + public const int AppCompatTheme_tooltipFrameBackground = 109; + + // aapt resource value: 110 + public const int AppCompatTheme_viewInflaterClass = 110; + + // aapt resource value: 111 + public const int AppCompatTheme_windowActionBar = 111; + + // aapt resource value: 112 + public const int AppCompatTheme_windowActionBarOverlay = 112; + + // aapt resource value: 113 + public const int AppCompatTheme_windowActionModeOverlay = 113; + + // aapt resource value: 114 + public const int AppCompatTheme_windowFixedHeightMajor = 114; + + // aapt resource value: 115 + public const int AppCompatTheme_windowFixedHeightMinor = 115; + + // aapt resource value: 116 + public const int AppCompatTheme_windowFixedWidthMajor = 116; + + // aapt resource value: 117 + public const int AppCompatTheme_windowFixedWidthMinor = 117; + + // aapt resource value: 118 + public const int AppCompatTheme_windowMinWidthMajor = 118; + + // aapt resource value: 119 + public const int AppCompatTheme_windowMinWidthMinor = 119; + + // aapt resource value: 120 + public const int AppCompatTheme_windowNoTitle = 120; + + // aapt resource value: { 0x7F030034,0x7F0300C4,0x7F0300C5,0x7F0300C6,0x7F0300C7,0x7F0300E6 } + public static int[] BottomAppBar = new int[] { + 2130903092, + 2130903236, + 2130903237, + 2130903238, + 2130903239, + 2130903270}; + + // aapt resource value: 0 + public const int BottomAppBar_backgroundTint = 0; + + // aapt resource value: 1 + public const int BottomAppBar_fabAlignmentMode = 1; + + // aapt resource value: 2 + public const int BottomAppBar_fabCradleMargin = 2; + + // aapt resource value: 3 + public const int BottomAppBar_fabCradleRoundedCornerRadius = 3; + + // aapt resource value: 4 + public const int BottomAppBar_fabCradleVerticalOffset = 4; + + // aapt resource value: 5 + public const int BottomAppBar_hideOnScroll = 5; + + // aapt resource value: { 0x7F0300B6,0x7F0300FB,0x7F0300FD,0x7F0300FF,0x7F030100,0x7F030104,0x7F030105,0x7F030106,0x7F030108,0x7F03012C } + public static int[] BottomNavigationView = new int[] { + 2130903222, + 2130903291, + 2130903293, + 2130903295, + 2130903296, + 2130903300, + 2130903301, + 2130903302, + 2130903304, + 2130903340}; + + // aapt resource value: 0 + public const int BottomNavigationView_elevation = 0; + + // aapt resource value: 1 + public const int BottomNavigationView_itemBackground = 1; + + // aapt resource value: 2 + public const int BottomNavigationView_itemHorizontalTranslationEnabled = 2; + + // aapt resource value: 3 + public const int BottomNavigationView_itemIconSize = 3; + + // aapt resource value: 4 + public const int BottomNavigationView_itemIconTint = 4; + + // aapt resource value: 5 + public const int BottomNavigationView_itemTextAppearanceActive = 5; + + // aapt resource value: 6 + public const int BottomNavigationView_itemTextAppearanceInactive = 6; + + // aapt resource value: 7 + public const int BottomNavigationView_itemTextColor = 7; + + // aapt resource value: 8 + public const int BottomNavigationView_labelVisibilityMode = 8; + + // aapt resource value: 9 + public const int BottomNavigationView_menu = 9; + + // aapt resource value: { 0x7F030038,0x7F030039,0x7F03003B,0x7F03003C } + public static int[] BottomSheetBehavior_Layout = new int[] { + 2130903096, + 2130903097, + 2130903099, + 2130903100}; + + // aapt resource value: 0 + public const int BottomSheetBehavior_Layout_behavior_fitToContents = 0; + + // aapt resource value: 1 + public const int BottomSheetBehavior_Layout_behavior_hideable = 1; + + // aapt resource value: 2 + public const int BottomSheetBehavior_Layout_behavior_peekHeight = 2; + + // aapt resource value: 3 + public const int BottomSheetBehavior_Layout_behavior_skipCollapsed = 3; + + // aapt resource value: { 0x7F030026 } + public static int[] ButtonBarLayout = new int[] { + 2130903078}; + + // aapt resource value: 0 + public const int ButtonBarLayout_allowStacking = 0; + + // aapt resource value: { 0x101013F,0x1010140,0x7F030058,0x7F030059,0x7F03005A,0x7F03005B,0x7F03005C,0x7F03005D,0x7F030098,0x7F030099,0x7F03009A,0x7F03009B,0x7F03009C } + public static int[] CardView = new int[] { + 16843071, + 16843072, + 2130903128, + 2130903129, + 2130903130, + 2130903131, + 2130903132, + 2130903133, + 2130903192, + 2130903193, + 2130903194, + 2130903195, + 2130903196}; + + // aapt resource value: 1 + public const int CardView_android_minHeight = 1; + + // aapt resource value: 0 + public const int CardView_android_minWidth = 0; + + // aapt resource value: 2 + public const int CardView_cardBackgroundColor = 2; + + // aapt resource value: 3 + public const int CardView_cardCornerRadius = 3; + + // aapt resource value: 4 + public const int CardView_cardElevation = 4; + + // aapt resource value: 5 + public const int CardView_cardMaxElevation = 5; + + // aapt resource value: 6 + public const int CardView_cardPreventCornerOverlap = 6; + + // aapt resource value: 7 + public const int CardView_cardUseCompatPadding = 7; + + // aapt resource value: 8 + public const int CardView_contentPadding = 8; + + // aapt resource value: 9 + public const int CardView_contentPaddingBottom = 9; + + // aapt resource value: 10 + public const int CardView_contentPaddingLeft = 10; + + // aapt resource value: 11 + public const int CardView_contentPaddingRight = 11; + + // aapt resource value: 12 + public const int CardView_contentPaddingTop = 12; + + // aapt resource value: { 0x1010034,0x10100AB,0x101011F,0x101014F,0x10101E5,0x7F030061,0x7F030062,0x7F030063,0x7F030065,0x7F030066,0x7F030067,0x7F030069,0x7F03006A,0x7F03006B,0x7F03006C,0x7F03006D,0x7F03006E,0x7F030073,0x7F030074,0x7F030075,0x7F030077,0x7F030078,0x7F030079,0x7F03007A,0x7F03007B,0x7F03007C,0x7F03007D,0x7F0300E4,0x7F0300EE,0x7F0300F2,0x7F03014E,0x7F03015B,0x7F0301B0,0x7F0301B2 } + public static int[] Chip = new int[] { + 16842804, + 16842923, + 16843039, + 16843087, + 16843237, + 2130903137, + 2130903138, + 2130903139, + 2130903141, + 2130903142, + 2130903143, + 2130903145, + 2130903146, + 2130903147, + 2130903148, + 2130903149, + 2130903150, + 2130903155, + 2130903156, + 2130903157, + 2130903159, + 2130903160, + 2130903161, + 2130903162, + 2130903163, + 2130903164, + 2130903165, + 2130903268, + 2130903278, + 2130903282, + 2130903374, + 2130903387, + 2130903472, + 2130903474}; + + // aapt resource value: { 0x7F030060,0x7F03006F,0x7F030070,0x7F030071,0x7F03015F,0x7F030160 } + public static int[] ChipGroup = new int[] { + 2130903136, + 2130903151, + 2130903152, + 2130903153, + 2130903391, + 2130903392}; + + // aapt resource value: 0 + public const int ChipGroup_checkedChip = 0; + + // aapt resource value: 1 + public const int ChipGroup_chipSpacing = 1; + + // aapt resource value: 2 + public const int ChipGroup_chipSpacingHorizontal = 2; + + // aapt resource value: 3 + public const int ChipGroup_chipSpacingVertical = 3; + + // aapt resource value: 4 + public const int ChipGroup_singleLine = 4; + + // aapt resource value: 5 + public const int ChipGroup_singleSelection = 5; + + // aapt resource value: 4 + public const int Chip_android_checkable = 4; + + // aapt resource value: 1 + public const int Chip_android_ellipsize = 1; + + // aapt resource value: 2 + public const int Chip_android_maxWidth = 2; + + // aapt resource value: 3 + public const int Chip_android_text = 3; + + // aapt resource value: 0 + public const int Chip_android_textAppearance = 0; + + // aapt resource value: 5 + public const int Chip_checkedIcon = 5; + + // aapt resource value: 6 + public const int Chip_checkedIconEnabled = 6; + + // aapt resource value: 7 + public const int Chip_checkedIconVisible = 7; + + // aapt resource value: 8 + public const int Chip_chipBackgroundColor = 8; + + // aapt resource value: 9 + public const int Chip_chipCornerRadius = 9; + + // aapt resource value: 10 + public const int Chip_chipEndPadding = 10; + + // aapt resource value: 11 + public const int Chip_chipIcon = 11; + + // aapt resource value: 12 + public const int Chip_chipIconEnabled = 12; + + // aapt resource value: 13 + public const int Chip_chipIconSize = 13; + + // aapt resource value: 14 + public const int Chip_chipIconTint = 14; + + // aapt resource value: 15 + public const int Chip_chipIconVisible = 15; + + // aapt resource value: 16 + public const int Chip_chipMinHeight = 16; + + // aapt resource value: 17 + public const int Chip_chipStartPadding = 17; + + // aapt resource value: 18 + public const int Chip_chipStrokeColor = 18; + + // aapt resource value: 19 + public const int Chip_chipStrokeWidth = 19; + + // aapt resource value: 20 + public const int Chip_closeIcon = 20; + + // aapt resource value: 21 + public const int Chip_closeIconEnabled = 21; + + // aapt resource value: 22 + public const int Chip_closeIconEndPadding = 22; + + // aapt resource value: 23 + public const int Chip_closeIconSize = 23; + + // aapt resource value: 24 + public const int Chip_closeIconStartPadding = 24; + + // aapt resource value: 25 + public const int Chip_closeIconTint = 25; + + // aapt resource value: 26 + public const int Chip_closeIconVisible = 26; + + // aapt resource value: 27 + public const int Chip_hideMotionSpec = 27; + + // aapt resource value: 28 + public const int Chip_iconEndPadding = 28; + + // aapt resource value: 29 + public const int Chip_iconStartPadding = 29; + + // aapt resource value: 30 + public const int Chip_rippleColor = 30; + + // aapt resource value: 31 + public const int Chip_showMotionSpec = 31; + + // aapt resource value: 32 + public const int Chip_textEndPadding = 32; + + // aapt resource value: 33 + public const int Chip_textStartPadding = 33; + + // aapt resource value: { 0x7F030081,0x7F030082,0x7F03009D,0x7F0300BD,0x7F0300BE,0x7F0300BF,0x7F0300C0,0x7F0300C1,0x7F0300C2,0x7F0300C3,0x7F03014F,0x7F030151,0x7F030170,0x7F0301BD,0x7F0301BE,0x7F0301C8 } + public static int[] CollapsingToolbarLayout = new int[] { + 2130903169, + 2130903170, + 2130903197, + 2130903229, + 2130903230, + 2130903231, + 2130903232, + 2130903233, + 2130903234, + 2130903235, + 2130903375, + 2130903377, + 2130903408, + 2130903485, + 2130903486, + 2130903496}; + + // aapt resource value: 0 + public const int CollapsingToolbarLayout_collapsedTitleGravity = 0; + + // aapt resource value: 1 + public const int CollapsingToolbarLayout_collapsedTitleTextAppearance = 1; + + // aapt resource value: 2 + public const int CollapsingToolbarLayout_contentScrim = 2; + + // aapt resource value: 3 + public const int CollapsingToolbarLayout_expandedTitleGravity = 3; + + // aapt resource value: 4 + public const int CollapsingToolbarLayout_expandedTitleMargin = 4; + + // aapt resource value: 5 + public const int CollapsingToolbarLayout_expandedTitleMarginBottom = 5; + + // aapt resource value: 6 + public const int CollapsingToolbarLayout_expandedTitleMarginEnd = 6; + + // aapt resource value: 7 + public const int CollapsingToolbarLayout_expandedTitleMarginStart = 7; + + // aapt resource value: 8 + public const int CollapsingToolbarLayout_expandedTitleMarginTop = 8; + + // aapt resource value: 9 + public const int CollapsingToolbarLayout_expandedTitleTextAppearance = 9; + + // aapt resource value: { 0x7F03010F,0x7F030110 } + public static int[] CollapsingToolbarLayout_Layout = new int[] { + 2130903311, + 2130903312}; + + // aapt resource value: 0 + public const int CollapsingToolbarLayout_Layout_layout_collapseMode = 0; + + // aapt resource value: 1 + public const int CollapsingToolbarLayout_Layout_layout_collapseParallaxMultiplier = 1; + + // aapt resource value: 10 + public const int CollapsingToolbarLayout_scrimAnimationDuration = 10; + + // aapt resource value: 11 + public const int CollapsingToolbarLayout_scrimVisibleHeightTrigger = 11; + + // aapt resource value: 12 + public const int CollapsingToolbarLayout_statusBarScrim = 12; + + // aapt resource value: 13 + public const int CollapsingToolbarLayout_title = 13; + + // aapt resource value: 14 + public const int CollapsingToolbarLayout_titleEnabled = 14; + + // aapt resource value: 15 + public const int CollapsingToolbarLayout_toolbarId = 15; + + // aapt resource value: { 0x10101A5,0x101031F,0x7F030027 } + public static int[] ColorStateListItem = new int[] { + 16843173, + 16843551, + 2130903079}; + + // aapt resource value: 2 + public const int ColorStateListItem_alpha = 2; + + // aapt resource value: 1 + public const int ColorStateListItem_android_alpha = 1; + + // aapt resource value: 0 + public const int ColorStateListItem_android_color = 0; + + // aapt resource value: { 0x1010107,0x7F030056,0x7F030057 } + public static int[] CompoundButton = new int[] { + 16843015, + 2130903126, + 2130903127}; + + // aapt resource value: 0 + public const int CompoundButton_android_button = 0; + + // aapt resource value: 1 + public const int CompoundButton_buttonTint = 1; + + // aapt resource value: 2 + public const int CompoundButton_buttonTintMode = 2; + + // aapt resource value: { 0x7F030107,0x7F03016F } + public static int[] CoordinatorLayout = new int[] { + 2130903303, + 2130903407}; + + // aapt resource value: 0 + public const int CoordinatorLayout_keylines = 0; + + // aapt resource value: { 0x10100B3,0x7F03010C,0x7F03010D,0x7F03010E,0x7F030111,0x7F030112,0x7F030113 } + public static int[] CoordinatorLayout_Layout = new int[] { + 16842931, + 2130903308, + 2130903309, + 2130903310, + 2130903313, + 2130903314, + 2130903315}; + + // aapt resource value: 0 + public const int CoordinatorLayout_Layout_android_layout_gravity = 0; + + // aapt resource value: 1 + public const int CoordinatorLayout_Layout_layout_anchor = 1; + + // aapt resource value: 2 + public const int CoordinatorLayout_Layout_layout_anchorGravity = 2; + + // aapt resource value: 3 + public const int CoordinatorLayout_Layout_layout_behavior = 3; + + // aapt resource value: 4 + public const int CoordinatorLayout_Layout_layout_dodgeInsetEdges = 4; + + // aapt resource value: 5 + public const int CoordinatorLayout_Layout_layout_insetEdge = 5; + + // aapt resource value: 6 + public const int CoordinatorLayout_Layout_layout_keyline = 6; + + // aapt resource value: 1 + public const int CoordinatorLayout_statusBarBackground = 1; + + // aapt resource value: { 0x7F030041,0x7F030042 } + public static int[] DesignTheme = new int[] { + 2130903105, + 2130903106}; + + // aapt resource value: 0 + public const int DesignTheme_bottomSheetDialogTheme = 0; + + // aapt resource value: 1 + public const int DesignTheme_bottomSheetStyle = 1; + + // aapt resource value: { 0x7F030029,0x7F03002A,0x7F030036,0x7F030084,0x7F0300AF,0x7F0300DD,0x7F030164,0x7F0301B4 } + public static int[] DrawerArrowToggle = new int[] { + 2130903081, + 2130903082, + 2130903094, + 2130903172, + 2130903215, + 2130903261, + 2130903396, + 2130903476}; + + // aapt resource value: 0 + public const int DrawerArrowToggle_arrowHeadLength = 0; + + // aapt resource value: 1 + public const int DrawerArrowToggle_arrowShaftLength = 1; + + // aapt resource value: 2 + public const int DrawerArrowToggle_barLength = 2; + + // aapt resource value: 3 + public const int DrawerArrowToggle_color = 3; + + // aapt resource value: 4 + public const int DrawerArrowToggle_drawableSize = 4; + + // aapt resource value: 5 + public const int DrawerArrowToggle_gapBetweenBars = 5; + + // aapt resource value: 6 + public const int DrawerArrowToggle_spinBars = 6; + + // aapt resource value: 7 + public const int DrawerArrowToggle_thickness = 7; + + // aapt resource value: { 0x7F030034,0x7F030035,0x7F03003D,0x7F0300B6,0x7F0300C8,0x7F0300C9,0x7F0300E4,0x7F0300EC,0x7F03012A,0x7F030144,0x7F03014E,0x7F03015B,0x7F0301D2 } + public static int[] FloatingActionButton = new int[] { + 2130903092, + 2130903093, + 2130903101, + 2130903222, + 2130903240, + 2130903241, + 2130903268, + 2130903276, + 2130903338, + 2130903364, + 2130903374, + 2130903387, + 2130903506}; + + // aapt resource value: 0 + public const int FloatingActionButton_backgroundTint = 0; + + // aapt resource value: 1 + public const int FloatingActionButton_backgroundTintMode = 1; + + // aapt resource value: { 0x7F030037 } + public static int[] FloatingActionButton_Behavior_Layout = new int[] { + 2130903095}; + + // aapt resource value: 0 + public const int FloatingActionButton_Behavior_Layout_behavior_autoHide = 0; + + // aapt resource value: 2 + public const int FloatingActionButton_borderWidth = 2; + + // aapt resource value: 3 + public const int FloatingActionButton_elevation = 3; + + // aapt resource value: 4 + public const int FloatingActionButton_fabCustomSize = 4; + + // aapt resource value: 5 + public const int FloatingActionButton_fabSize = 5; + + // aapt resource value: 6 + public const int FloatingActionButton_hideMotionSpec = 6; + + // aapt resource value: 7 + public const int FloatingActionButton_hoveredFocusedTranslationZ = 7; + + // aapt resource value: 8 + public const int FloatingActionButton_maxImageSize = 8; + + // aapt resource value: 9 + public const int FloatingActionButton_pressedTranslationZ = 9; + + // aapt resource value: 10 + public const int FloatingActionButton_rippleColor = 10; + + // aapt resource value: 11 + public const int FloatingActionButton_showMotionSpec = 11; + + // aapt resource value: 12 + public const int FloatingActionButton_useCompatPadding = 12; + + // aapt resource value: { 0x7F030102,0x7F030118 } + public static int[] FlowLayout = new int[] { + 2130903298, + 2130903320}; + + // aapt resource value: 0 + public const int FlowLayout_itemSpacing = 0; + + // aapt resource value: 1 + public const int FlowLayout_lineSpacing = 1; + + // aapt resource value: { 0x7F0300D3,0x7F0300D4,0x7F0300D5,0x7F0300D6,0x7F0300D7,0x7F0300D8 } + public static int[] FontFamily = new int[] { + 2130903251, + 2130903252, + 2130903253, + 2130903254, + 2130903255, + 2130903256}; + + // aapt resource value: { 0x1010532,0x1010533,0x101053F,0x101056F,0x1010570,0x7F0300D1,0x7F0300D9,0x7F0300DA,0x7F0300DB,0x7F0301D1 } + public static int[] FontFamilyFont = new int[] { + 16844082, + 16844083, + 16844095, + 16844143, + 16844144, + 2130903249, + 2130903257, + 2130903258, + 2130903259, + 2130903505}; + + // aapt resource value: 0 + public const int FontFamilyFont_android_font = 0; + + // aapt resource value: 2 + public const int FontFamilyFont_android_fontStyle = 2; + + // aapt resource value: 4 + public const int FontFamilyFont_android_fontVariationSettings = 4; + + // aapt resource value: 1 + public const int FontFamilyFont_android_fontWeight = 1; + + // aapt resource value: 3 + public const int FontFamilyFont_android_ttcIndex = 3; + + // aapt resource value: 5 + public const int FontFamilyFont_font = 5; + + // aapt resource value: 6 + public const int FontFamilyFont_fontStyle = 6; + + // aapt resource value: 7 + public const int FontFamilyFont_fontVariationSettings = 7; + + // aapt resource value: 8 + public const int FontFamilyFont_fontWeight = 8; + + // aapt resource value: 9 + public const int FontFamilyFont_ttcIndex = 9; + + // aapt resource value: 0 + public const int FontFamily_fontProviderAuthority = 0; + + // aapt resource value: 1 + public const int FontFamily_fontProviderCerts = 1; + + // aapt resource value: 2 + public const int FontFamily_fontProviderFetchStrategy = 2; + + // aapt resource value: 3 + public const int FontFamily_fontProviderFetchTimeout = 3; + + // aapt resource value: 4 + public const int FontFamily_fontProviderPackage = 4; + + // aapt resource value: 5 + public const int FontFamily_fontProviderQuery = 5; + + // aapt resource value: { 0x1010109,0x1010200,0x7F0300DC } + public static int[] ForegroundLinearLayout = new int[] { + 16843017, + 16843264, + 2130903260}; + + // aapt resource value: 0 + public const int ForegroundLinearLayout_android_foreground = 0; + + // aapt resource value: 1 + public const int ForegroundLinearLayout_android_foregroundGravity = 1; + + // aapt resource value: 2 + public const int ForegroundLinearLayout_foregroundInsidePadding = 2; + + // aapt resource value: { 0x101019D,0x101019E,0x10101A1,0x10101A2,0x10101A3,0x10101A4,0x1010201,0x101020B,0x1010510,0x1010511,0x1010512,0x1010513 } + public static int[] GradientColor = new int[] { + 16843165, + 16843166, + 16843169, + 16843170, + 16843171, + 16843172, + 16843265, + 16843275, + 16844048, + 16844049, + 16844050, + 16844051}; + + // aapt resource value: { 0x10101A5,0x1010514 } + public static int[] GradientColorItem = new int[] { + 16843173, + 16844052}; + + // aapt resource value: 0 + public const int GradientColorItem_android_color = 0; + + // aapt resource value: 1 + public const int GradientColorItem_android_offset = 1; + + // aapt resource value: 7 + public const int GradientColor_android_centerColor = 7; + + // aapt resource value: 3 + public const int GradientColor_android_centerX = 3; + + // aapt resource value: 4 + public const int GradientColor_android_centerY = 4; + + // aapt resource value: 1 + public const int GradientColor_android_endColor = 1; + + // aapt resource value: 10 + public const int GradientColor_android_endX = 10; + + // aapt resource value: 11 + public const int GradientColor_android_endY = 11; + + // aapt resource value: 5 + public const int GradientColor_android_gradientRadius = 5; + + // aapt resource value: 0 + public const int GradientColor_android_startColor = 0; + + // aapt resource value: 8 + public const int GradientColor_android_startX = 8; + + // aapt resource value: 9 + public const int GradientColor_android_startY = 9; + + // aapt resource value: 6 + public const int GradientColor_android_tileMode = 6; + + // aapt resource value: 2 + public const int GradientColor_android_type = 2; + + // aapt resource value: { 0x7F030083 } + public static int[] ItemsViewRendererTheme = new int[] { + 2130903171}; + + // aapt resource value: 0 + public const int ItemsViewRendererTheme_collectionViewStyle = 0; + + // aapt resource value: { 0x10100AF,0x10100C4,0x1010126,0x1010127,0x1010128,0x7F0300AB,0x7F0300AD,0x7F03012B,0x7F03015A } + public static int[] LinearLayoutCompat = new int[] { + 16842927, + 16842948, + 16843046, + 16843047, + 16843048, + 2130903211, + 2130903213, + 2130903339, + 2130903386}; + + // aapt resource value: 2 + public const int LinearLayoutCompat_android_baselineAligned = 2; + + // aapt resource value: 3 + public const int LinearLayoutCompat_android_baselineAlignedChildIndex = 3; + + // aapt resource value: 0 + public const int LinearLayoutCompat_android_gravity = 0; + + // aapt resource value: 1 + public const int LinearLayoutCompat_android_orientation = 1; + + // aapt resource value: 4 + public const int LinearLayoutCompat_android_weightSum = 4; + + // aapt resource value: 5 + public const int LinearLayoutCompat_divider = 5; + + // aapt resource value: 6 + public const int LinearLayoutCompat_dividerPadding = 6; + + // aapt resource value: { 0x10100B3,0x10100F4,0x10100F5,0x1010181 } + public static int[] LinearLayoutCompat_Layout = new int[] { + 16842931, + 16842996, + 16842997, + 16843137}; + + // aapt resource value: 0 + public const int LinearLayoutCompat_Layout_android_layout_gravity = 0; + + // aapt resource value: 2 + public const int LinearLayoutCompat_Layout_android_layout_height = 2; + + // aapt resource value: 3 + public const int LinearLayoutCompat_Layout_android_layout_weight = 3; + + // aapt resource value: 1 + public const int LinearLayoutCompat_Layout_android_layout_width = 1; + + // aapt resource value: 7 + public const int LinearLayoutCompat_measureWithLargestChild = 7; + + // aapt resource value: 8 + public const int LinearLayoutCompat_showDividers = 8; + + // aapt resource value: { 0x10102AC,0x10102AD } + public static int[] ListPopupWindow = new int[] { + 16843436, + 16843437}; + + // aapt resource value: 0 + public const int ListPopupWindow_android_dropDownHorizontalOffset = 0; + + // aapt resource value: 1 + public const int ListPopupWindow_android_dropDownVerticalOffset = 1; + + // aapt resource value: { 0x10101B7,0x10101B8,0x10101B9,0x10101BA,0x7F030034,0x7F030035,0x7F0300A0,0x7F0300ED,0x7F0300EF,0x7F0300F0,0x7F0300F1,0x7F0300F3,0x7F0300F4,0x7F03014E,0x7F030171,0x7F030172 } + public static int[] MaterialButton = new int[] { + 16843191, + 16843192, + 16843193, + 16843194, + 2130903092, + 2130903093, + 2130903200, + 2130903277, + 2130903279, + 2130903280, + 2130903281, + 2130903283, + 2130903284, + 2130903374, + 2130903409, + 2130903410}; + + // aapt resource value: 3 + public const int MaterialButton_android_insetBottom = 3; + + // aapt resource value: 0 + public const int MaterialButton_android_insetLeft = 0; + + // aapt resource value: 1 + public const int MaterialButton_android_insetRight = 1; + + // aapt resource value: 2 + public const int MaterialButton_android_insetTop = 2; + + // aapt resource value: 4 + public const int MaterialButton_backgroundTint = 4; + + // aapt resource value: 5 + public const int MaterialButton_backgroundTintMode = 5; + + // aapt resource value: 6 + public const int MaterialButton_cornerRadius = 6; + + // aapt resource value: 7 + public const int MaterialButton_icon = 7; + + // aapt resource value: 8 + public const int MaterialButton_iconGravity = 8; + + // aapt resource value: 9 + public const int MaterialButton_iconPadding = 9; + + // aapt resource value: 10 + public const int MaterialButton_iconSize = 10; + + // aapt resource value: 11 + public const int MaterialButton_iconTint = 11; + + // aapt resource value: 12 + public const int MaterialButton_iconTintMode = 12; + + // aapt resource value: 13 + public const int MaterialButton_rippleColor = 13; + + // aapt resource value: 14 + public const int MaterialButton_strokeColor = 14; + + // aapt resource value: 15 + public const int MaterialButton_strokeWidth = 15; + + // aapt resource value: { 0x7F030171,0x7F030172 } + public static int[] MaterialCardView = new int[] { + 2130903409, + 2130903410}; + + // aapt resource value: 0 + public const int MaterialCardView_strokeColor = 0; + + // aapt resource value: 1 + public const int MaterialCardView_strokeWidth = 1; + + // aapt resource value: { 0x7F030041,0x7F030042,0x7F030068,0x7F030072,0x7F030076,0x7F030085,0x7F030086,0x7F03008C,0x7F03008D,0x7F03008E,0x7F0300B5,0x7F0300D0,0x7F030126,0x7F030127,0x7F030131,0x7F030150,0x7F030161,0x7F030194,0x7F030199,0x7F03019A,0x7F03019B,0x7F03019C,0x7F03019D,0x7F03019E,0x7F03019F,0x7F0301A0,0x7F0301A1,0x7F0301A2,0x7F0301A7,0x7F0301AC,0x7F0301AD,0x7F0301B1 } + public static int[] MaterialComponentsTheme = new int[] { + 2130903105, + 2130903106, + 2130903144, + 2130903154, + 2130903158, + 2130903173, + 2130903174, + 2130903180, + 2130903181, + 2130903182, + 2130903221, + 2130903248, + 2130903334, + 2130903335, + 2130903345, + 2130903376, + 2130903393, + 2130903444, + 2130903449, + 2130903450, + 2130903451, + 2130903452, + 2130903453, + 2130903454, + 2130903455, + 2130903456, + 2130903457, + 2130903458, + 2130903463, + 2130903468, + 2130903469, + 2130903473}; + + // aapt resource value: 0 + public const int MaterialComponentsTheme_bottomSheetDialogTheme = 0; + + // aapt resource value: 1 + public const int MaterialComponentsTheme_bottomSheetStyle = 1; + + // aapt resource value: 2 + public const int MaterialComponentsTheme_chipGroupStyle = 2; + + // aapt resource value: 3 + public const int MaterialComponentsTheme_chipStandaloneStyle = 3; + + // aapt resource value: 4 + public const int MaterialComponentsTheme_chipStyle = 4; + + // aapt resource value: 5 + public const int MaterialComponentsTheme_colorAccent = 5; + + // aapt resource value: 6 + public const int MaterialComponentsTheme_colorBackgroundFloating = 6; + + // aapt resource value: 7 + public const int MaterialComponentsTheme_colorPrimary = 7; + + // aapt resource value: 8 + public const int MaterialComponentsTheme_colorPrimaryDark = 8; + + // aapt resource value: 9 + public const int MaterialComponentsTheme_colorSecondary = 9; + + // aapt resource value: 10 + public const int MaterialComponentsTheme_editTextStyle = 10; + + // aapt resource value: 11 + public const int MaterialComponentsTheme_floatingActionButtonStyle = 11; + + // aapt resource value: 12 + public const int MaterialComponentsTheme_materialButtonStyle = 12; + + // aapt resource value: 13 + public const int MaterialComponentsTheme_materialCardViewStyle = 13; + + // aapt resource value: 14 + public const int MaterialComponentsTheme_navigationViewStyle = 14; + + // aapt resource value: 15 + public const int MaterialComponentsTheme_scrimBackground = 15; + + // aapt resource value: 16 + public const int MaterialComponentsTheme_snackbarButtonStyle = 16; + + // aapt resource value: 17 + public const int MaterialComponentsTheme_tabStyle = 17; + + // aapt resource value: 18 + public const int MaterialComponentsTheme_textAppearanceBody1 = 18; + + // aapt resource value: 19 + public const int MaterialComponentsTheme_textAppearanceBody2 = 19; + + // aapt resource value: 20 + public const int MaterialComponentsTheme_textAppearanceButton = 20; + + // aapt resource value: 21 + public const int MaterialComponentsTheme_textAppearanceCaption = 21; + + // aapt resource value: 22 + public const int MaterialComponentsTheme_textAppearanceHeadline1 = 22; + + // aapt resource value: 23 + public const int MaterialComponentsTheme_textAppearanceHeadline2 = 23; + + // aapt resource value: 24 + public const int MaterialComponentsTheme_textAppearanceHeadline3 = 24; + + // aapt resource value: 25 + public const int MaterialComponentsTheme_textAppearanceHeadline4 = 25; + + // aapt resource value: 26 + public const int MaterialComponentsTheme_textAppearanceHeadline5 = 26; + + // aapt resource value: 27 + public const int MaterialComponentsTheme_textAppearanceHeadline6 = 27; + + // aapt resource value: 28 + public const int MaterialComponentsTheme_textAppearanceOverline = 28; + + // aapt resource value: 29 + public const int MaterialComponentsTheme_textAppearanceSubtitle1 = 29; + + // aapt resource value: 30 + public const int MaterialComponentsTheme_textAppearanceSubtitle2 = 30; + + // aapt resource value: 31 + public const int MaterialComponentsTheme_textInputStyle = 31; + + // aapt resource value: { 0x101000E,0x10100D0,0x1010194,0x10101DE,0x10101DF,0x10101E0 } + public static int[] MenuGroup = new int[] { + 16842766, + 16842960, + 16843156, + 16843230, + 16843231, + 16843232}; + + // aapt resource value: 5 + public const int MenuGroup_android_checkableBehavior = 5; + + // aapt resource value: 0 + public const int MenuGroup_android_enabled = 0; + + // aapt resource value: 1 + public const int MenuGroup_android_id = 1; + + // aapt resource value: 3 + public const int MenuGroup_android_menuCategory = 3; + + // aapt resource value: 4 + public const int MenuGroup_android_orderInCategory = 4; + + // aapt resource value: 2 + public const int MenuGroup_android_visible = 2; + + // aapt resource value: { 0x1010002,0x101000E,0x10100D0,0x1010106,0x1010194,0x10101DE,0x10101DF,0x10101E1,0x10101E2,0x10101E3,0x10101E4,0x10101E5,0x101026F,0x7F03000D,0x7F03001F,0x7F030020,0x7F030028,0x7F030091,0x7F0300F3,0x7F0300F4,0x7F030132,0x7F030159,0x7F0301CD } + public static int[] MenuItem = new int[] { + 16842754, + 16842766, + 16842960, + 16843014, + 16843156, + 16843230, + 16843231, + 16843233, + 16843234, + 16843235, + 16843236, + 16843237, + 16843375, + 2130903053, + 2130903071, + 2130903072, + 2130903080, + 2130903185, + 2130903283, + 2130903284, + 2130903346, + 2130903385, + 2130903501}; + + // aapt resource value: 13 + public const int MenuItem_actionLayout = 13; + + // aapt resource value: 14 + public const int MenuItem_actionProviderClass = 14; + + // aapt resource value: 15 + public const int MenuItem_actionViewClass = 15; + + // aapt resource value: 16 + public const int MenuItem_alphabeticModifiers = 16; + + // aapt resource value: 9 + public const int MenuItem_android_alphabeticShortcut = 9; + + // aapt resource value: 11 + public const int MenuItem_android_checkable = 11; + + // aapt resource value: 3 + public const int MenuItem_android_checked = 3; + + // aapt resource value: 1 + public const int MenuItem_android_enabled = 1; + + // aapt resource value: 0 + public const int MenuItem_android_icon = 0; + + // aapt resource value: 2 + public const int MenuItem_android_id = 2; + + // aapt resource value: 5 + public const int MenuItem_android_menuCategory = 5; + + // aapt resource value: 10 + public const int MenuItem_android_numericShortcut = 10; + + // aapt resource value: 12 + public const int MenuItem_android_onClick = 12; + + // aapt resource value: 6 + public const int MenuItem_android_orderInCategory = 6; + + // aapt resource value: 7 + public const int MenuItem_android_title = 7; + + // aapt resource value: 8 + public const int MenuItem_android_titleCondensed = 8; + + // aapt resource value: 4 + public const int MenuItem_android_visible = 4; + + // aapt resource value: 17 + public const int MenuItem_contentDescription = 17; + + // aapt resource value: 18 + public const int MenuItem_iconTint = 18; + + // aapt resource value: 19 + public const int MenuItem_iconTintMode = 19; + + // aapt resource value: 20 + public const int MenuItem_numericModifiers = 20; + + // aapt resource value: 21 + public const int MenuItem_showAsAction = 21; + + // aapt resource value: 22 + public const int MenuItem_tooltipText = 22; + + // aapt resource value: { 0x10100AE,0x101012C,0x101012D,0x101012E,0x101012F,0x1010130,0x1010131,0x7F030143,0x7F030173 } + public static int[] MenuView = new int[] { + 16842926, + 16843052, + 16843053, + 16843054, + 16843055, + 16843056, + 16843057, + 2130903363, + 2130903411}; + + // aapt resource value: 4 + public const int MenuView_android_headerBackground = 4; + + // aapt resource value: 2 + public const int MenuView_android_horizontalDivider = 2; + + // aapt resource value: 5 + public const int MenuView_android_itemBackground = 5; + + // aapt resource value: 6 + public const int MenuView_android_itemIconDisabledAlpha = 6; + + // aapt resource value: 1 + public const int MenuView_android_itemTextAppearance = 1; + + // aapt resource value: 3 + public const int MenuView_android_verticalDivider = 3; + + // aapt resource value: 0 + public const int MenuView_android_windowAnimationStyle = 0; + + // aapt resource value: 7 + public const int MenuView_preserveIconSpacing = 7; + + // aapt resource value: 8 + public const int MenuView_subMenuArrow = 8; + + // aapt resource value: { 0x10100D4,0x10100DD,0x101011F,0x7F0300B6,0x7F0300DF,0x7F0300FB,0x7F0300FC,0x7F0300FE,0x7F030100,0x7F030103,0x7F030106,0x7F03012C } + public static int[] NavigationView = new int[] { + 16842964, + 16842973, + 16843039, + 2130903222, + 2130903263, + 2130903291, + 2130903292, + 2130903294, + 2130903296, + 2130903299, + 2130903302, + 2130903340}; + + // aapt resource value: 0 + public const int NavigationView_android_background = 0; + + // aapt resource value: 1 + public const int NavigationView_android_fitsSystemWindows = 1; + + // aapt resource value: 2 + public const int NavigationView_android_maxWidth = 2; + + // aapt resource value: 3 + public const int NavigationView_elevation = 3; + + // aapt resource value: 4 + public const int NavigationView_headerLayout = 4; + + // aapt resource value: 5 + public const int NavigationView_itemBackground = 5; + + // aapt resource value: 6 + public const int NavigationView_itemHorizontalPadding = 6; + + // aapt resource value: 7 + public const int NavigationView_itemIconPadding = 7; + + // aapt resource value: 8 + public const int NavigationView_itemIconTint = 8; + + // aapt resource value: 9 + public const int NavigationView_itemTextAppearance = 9; + + // aapt resource value: 10 + public const int NavigationView_itemTextColor = 10; + + // aapt resource value: 11 + public const int NavigationView_menu = 11; + + // aapt resource value: { 0x1010176,0x10102C9,0x7F030133 } + public static int[] PopupWindow = new int[] { + 16843126, + 16843465, + 2130903347}; + + // aapt resource value: { 0x7F03016A } + public static int[] PopupWindowBackgroundState = new int[] { + 2130903402}; + + // aapt resource value: 0 + public const int PopupWindowBackgroundState_state_above_anchor = 0; + + // aapt resource value: 1 + public const int PopupWindow_android_popupAnimationStyle = 1; + + // aapt resource value: 0 + public const int PopupWindow_android_popupBackground = 0; + + // aapt resource value: 2 + public const int PopupWindow_overlapAnchor = 2; + + // aapt resource value: { 0x7F030134,0x7F030137 } + public static int[] RecycleListView = new int[] { + 2130903348, + 2130903351}; + + // aapt resource value: 0 + public const int RecycleListView_paddingBottomNoButtons = 0; + + // aapt resource value: 1 + public const int RecycleListView_paddingTopNoTitle = 1; + + // aapt resource value: { 0x10100C4,0x10100F1,0x7F0300CA,0x7F0300CB,0x7F0300CC,0x7F0300CD,0x7F0300CE,0x7F03010B,0x7F03014D,0x7F030163,0x7F030169 } + public static int[] RecyclerView = new int[] { + 16842948, + 16842993, + 2130903242, + 2130903243, + 2130903244, + 2130903245, + 2130903246, + 2130903307, + 2130903373, + 2130903395, + 2130903401}; + + // aapt resource value: 1 + public const int RecyclerView_android_descendantFocusability = 1; + + // aapt resource value: 0 + public const int RecyclerView_android_orientation = 0; + + // aapt resource value: 2 + public const int RecyclerView_fastScrollEnabled = 2; + + // aapt resource value: 3 + public const int RecyclerView_fastScrollHorizontalThumbDrawable = 3; + + // aapt resource value: 4 + public const int RecyclerView_fastScrollHorizontalTrackDrawable = 4; + + // aapt resource value: 5 + public const int RecyclerView_fastScrollVerticalThumbDrawable = 5; + + // aapt resource value: 6 + public const int RecyclerView_fastScrollVerticalTrackDrawable = 6; + + // aapt resource value: 7 + public const int RecyclerView_layoutManager = 7; + + // aapt resource value: 8 + public const int RecyclerView_reverseLayout = 8; + + // aapt resource value: 9 + public const int RecyclerView_spanCount = 9; + + // aapt resource value: 10 + public const int RecyclerView_stackFromEnd = 10; + + // aapt resource value: { 0x7F0300F9 } + public static int[] ScrimInsetsFrameLayout = new int[] { + 2130903289}; + + // aapt resource value: 0 + public const int ScrimInsetsFrameLayout_insetForeground = 0; + + // aapt resource value: { 0x7F03003A } + public static int[] ScrollingViewBehavior_Layout = new int[] { + 2130903098}; + + // aapt resource value: 0 + public const int ScrollingViewBehavior_Layout_behavior_overlapTop = 0; + + // aapt resource value: { 0x7F030152 } + public static int[] ScrollViewRendererTheme = new int[] { + 2130903378}; + + // aapt resource value: 0 + public const int ScrollViewRendererTheme_scrollViewStyle = 0; + + // aapt resource value: { 0x10100DA,0x101011F,0x1010220,0x1010264,0x7F030077,0x7F030090,0x7F0300A6,0x7F0300DE,0x7F0300F5,0x7F03010A,0x7F030147,0x7F030148,0x7F030153,0x7F030154,0x7F030174,0x7F030179,0x7F0301D4 } + public static int[] SearchView = new int[] { + 16842970, + 16843039, + 16843296, + 16843364, + 2130903159, + 2130903184, + 2130903206, + 2130903262, + 2130903285, + 2130903306, + 2130903367, + 2130903368, + 2130903379, + 2130903380, + 2130903412, + 2130903417, + 2130903508}; + + // aapt resource value: 0 + public const int SearchView_android_focusable = 0; + + // aapt resource value: 3 + public const int SearchView_android_imeOptions = 3; + + // aapt resource value: 2 + public const int SearchView_android_inputType = 2; + + // aapt resource value: 1 + public const int SearchView_android_maxWidth = 1; + + // aapt resource value: 4 + public const int SearchView_closeIcon = 4; + + // aapt resource value: 5 + public const int SearchView_commitIcon = 5; + + // aapt resource value: 6 + public const int SearchView_defaultQueryHint = 6; + + // aapt resource value: 7 + public const int SearchView_goIcon = 7; + + // aapt resource value: 8 + public const int SearchView_iconifiedByDefault = 8; + + // aapt resource value: 9 + public const int SearchView_layout = 9; + + // aapt resource value: 10 + public const int SearchView_queryBackground = 10; + + // aapt resource value: 11 + public const int SearchView_queryHint = 11; + + // aapt resource value: 12 + public const int SearchView_searchHintIcon = 12; + + // aapt resource value: 13 + public const int SearchView_searchIcon = 13; + + // aapt resource value: 14 + public const int SearchView_submitBackground = 14; + + // aapt resource value: 15 + public const int SearchView_suggestionRowLayout = 15; + + // aapt resource value: 16 + public const int SearchView_voiceIcon = 16; + + // aapt resource value: { 0x7F030161,0x7F030162 } + public static int[] Snackbar = new int[] { + 2130903393, + 2130903394}; + + // aapt resource value: { 0x101011F,0x7F0300B6,0x7F030128 } + public static int[] SnackbarLayout = new int[] { + 16843039, + 2130903222, + 2130903336}; + + // aapt resource value: 0 + public const int SnackbarLayout_android_maxWidth = 0; + + // aapt resource value: 1 + public const int SnackbarLayout_elevation = 1; + + // aapt resource value: 2 + public const int SnackbarLayout_maxActionInlineWidth = 2; + + // aapt resource value: 0 + public const int Snackbar_snackbarButtonStyle = 0; + + // aapt resource value: 1 + public const int Snackbar_snackbarStyle = 1; + + // aapt resource value: { 0x10100B2,0x1010176,0x101017B,0x1010262,0x7F030141 } + public static int[] Spinner = new int[] { + 16842930, + 16843126, + 16843131, + 16843362, + 2130903361}; + + // aapt resource value: 3 + public const int Spinner_android_dropDownWidth = 3; + + // aapt resource value: 0 + public const int Spinner_android_entries = 0; + + // aapt resource value: 1 + public const int Spinner_android_popupBackground = 1; + + // aapt resource value: 2 + public const int Spinner_android_prompt = 2; + + // aapt resource value: 4 + public const int Spinner_popupTheme = 4; + + // aapt resource value: { 0x101011C,0x1010194,0x1010195,0x1010196,0x101030C,0x101030D } + public static int[] StateListDrawable = new int[] { + 16843036, + 16843156, + 16843157, + 16843158, + 16843532, + 16843533}; + + // aapt resource value: { 0x1010199 } + public static int[] StateListDrawableItem = new int[] { + 16843161}; + + // aapt resource value: 0 + public const int StateListDrawableItem_android_drawable = 0; + + // aapt resource value: 3 + public const int StateListDrawable_android_constantSize = 3; + + // aapt resource value: 0 + public const int StateListDrawable_android_dither = 0; + + // aapt resource value: 4 + public const int StateListDrawable_android_enterFadeDuration = 4; + + // aapt resource value: 5 + public const int StateListDrawable_android_exitFadeDuration = 5; + + // aapt resource value: 2 + public const int StateListDrawable_android_variablePadding = 2; + + // aapt resource value: 1 + public const int StateListDrawable_android_visible = 1; + + // aapt resource value: { 0x1010124,0x1010125,0x1010142,0x7F03015C,0x7F030167,0x7F03017A,0x7F03017B,0x7F03017D,0x7F0301B5,0x7F0301B6,0x7F0301B7,0x7F0301CE,0x7F0301CF,0x7F0301D0 } + public static int[] SwitchCompat = new int[] { + 16843044, + 16843045, + 16843074, + 2130903388, + 2130903399, + 2130903418, + 2130903419, + 2130903421, + 2130903477, + 2130903478, + 2130903479, + 2130903502, + 2130903503, + 2130903504}; + + // aapt resource value: 1 + public const int SwitchCompat_android_textOff = 1; + + // aapt resource value: 0 + public const int SwitchCompat_android_textOn = 0; + + // aapt resource value: 2 + public const int SwitchCompat_android_thumb = 2; + + // aapt resource value: 3 + public const int SwitchCompat_showText = 3; + + // aapt resource value: 4 + public const int SwitchCompat_splitTrack = 4; + + // aapt resource value: 5 + public const int SwitchCompat_switchMinWidth = 5; + + // aapt resource value: 6 + public const int SwitchCompat_switchPadding = 6; + + // aapt resource value: 7 + public const int SwitchCompat_switchTextAppearance = 7; + + // aapt resource value: 8 + public const int SwitchCompat_thumbTextPadding = 8; + + // aapt resource value: 9 + public const int SwitchCompat_thumbTint = 9; + + // aapt resource value: 10 + public const int SwitchCompat_thumbTintMode = 10; + + // aapt resource value: 11 + public const int SwitchCompat_track = 11; + + // aapt resource value: 12 + public const int SwitchCompat_trackTint = 12; + + // aapt resource value: 13 + public const int SwitchCompat_trackTintMode = 13; + + // aapt resource value: { 0x1010002,0x10100F2,0x101014F } + public static int[] TabItem = new int[] { + 16842754, + 16842994, + 16843087}; + + // aapt resource value: 0 + public const int TabItem_android_icon = 0; + + // aapt resource value: 1 + public const int TabItem_android_layout = 1; + + // aapt resource value: 2 + public const int TabItem_android_text = 2; + + // aapt resource value: { 0x7F03017E,0x7F03017F,0x7F030180,0x7F030181,0x7F030182,0x7F030183,0x7F030184,0x7F030185,0x7F030186,0x7F030187,0x7F030188,0x7F030189,0x7F03018A,0x7F03018B,0x7F03018C,0x7F03018D,0x7F03018E,0x7F03018F,0x7F030190,0x7F030191,0x7F030192,0x7F030193,0x7F030195,0x7F030196,0x7F030197 } + public static int[] TabLayout = new int[] { + 2130903422, + 2130903423, + 2130903424, + 2130903425, + 2130903426, + 2130903427, + 2130903428, + 2130903429, + 2130903430, + 2130903431, + 2130903432, + 2130903433, + 2130903434, + 2130903435, + 2130903436, + 2130903437, + 2130903438, + 2130903439, + 2130903440, + 2130903441, + 2130903442, + 2130903443, + 2130903445, + 2130903446, + 2130903447}; + + // aapt resource value: 0 + public const int TabLayout_tabBackground = 0; + + // aapt resource value: 1 + public const int TabLayout_tabContentStart = 1; + + // aapt resource value: 2 + public const int TabLayout_tabGravity = 2; + + // aapt resource value: 3 + public const int TabLayout_tabIconTint = 3; + + // aapt resource value: 4 + public const int TabLayout_tabIconTintMode = 4; + + // aapt resource value: 5 + public const int TabLayout_tabIndicator = 5; + + // aapt resource value: 6 + public const int TabLayout_tabIndicatorAnimationDuration = 6; + + // aapt resource value: 7 + public const int TabLayout_tabIndicatorColor = 7; + + // aapt resource value: 8 + public const int TabLayout_tabIndicatorFullWidth = 8; + + // aapt resource value: 9 + public const int TabLayout_tabIndicatorGravity = 9; + + // aapt resource value: 10 + public const int TabLayout_tabIndicatorHeight = 10; + + // aapt resource value: 11 + public const int TabLayout_tabInlineLabel = 11; + + // aapt resource value: 12 + public const int TabLayout_tabMaxWidth = 12; + + // aapt resource value: 13 + public const int TabLayout_tabMinWidth = 13; + + // aapt resource value: 14 + public const int TabLayout_tabMode = 14; + + // aapt resource value: 15 + public const int TabLayout_tabPadding = 15; + + // aapt resource value: 16 + public const int TabLayout_tabPaddingBottom = 16; + + // aapt resource value: 17 + public const int TabLayout_tabPaddingEnd = 17; + + // aapt resource value: 18 + public const int TabLayout_tabPaddingStart = 18; + + // aapt resource value: 19 + public const int TabLayout_tabPaddingTop = 19; + + // aapt resource value: 20 + public const int TabLayout_tabRippleColor = 20; + + // aapt resource value: 21 + public const int TabLayout_tabSelectedTextColor = 21; + + // aapt resource value: 22 + public const int TabLayout_tabTextAppearance = 22; + + // aapt resource value: 23 + public const int TabLayout_tabTextColor = 23; + + // aapt resource value: 24 + public const int TabLayout_tabUnboundedRipple = 24; + + // aapt resource value: { 0x1010095,0x1010096,0x1010097,0x1010098,0x101009A,0x101009B,0x1010161,0x1010162,0x1010163,0x1010164,0x10103AC,0x7F0300D2,0x7F030198 } + public static int[] TextAppearance = new int[] { + 16842901, + 16842902, + 16842903, + 16842904, + 16842906, + 16842907, + 16843105, + 16843106, + 16843107, + 16843108, + 16843692, + 2130903250, + 2130903448}; + + // aapt resource value: 10 + public const int TextAppearance_android_fontFamily = 10; + + // aapt resource value: 6 + public const int TextAppearance_android_shadowColor = 6; + + // aapt resource value: 7 + public const int TextAppearance_android_shadowDx = 7; + + // aapt resource value: 8 + public const int TextAppearance_android_shadowDy = 8; + + // aapt resource value: 9 + public const int TextAppearance_android_shadowRadius = 9; + + // aapt resource value: 3 + public const int TextAppearance_android_textColor = 3; + + // aapt resource value: 4 + public const int TextAppearance_android_textColorHint = 4; + + // aapt resource value: 5 + public const int TextAppearance_android_textColorLink = 5; + + // aapt resource value: 0 + public const int TextAppearance_android_textSize = 0; + + // aapt resource value: 2 + public const int TextAppearance_android_textStyle = 2; + + // aapt resource value: 1 + public const int TextAppearance_android_typeface = 1; + + // aapt resource value: 11 + public const int TextAppearance_fontFamily = 11; + + // aapt resource value: 12 + public const int TextAppearance_textAllCaps = 12; + + // aapt resource value: { 0x101009A,0x1010150,0x7F030043,0x7F030044,0x7F030045,0x7F030046,0x7F030047,0x7F030048,0x7F030049,0x7F03004A,0x7F03004B,0x7F0300A1,0x7F0300A2,0x7F0300A3,0x7F0300A4,0x7F0300B9,0x7F0300BA,0x7F0300E1,0x7F0300E2,0x7F0300E3,0x7F0300E7,0x7F0300E8,0x7F0300E9,0x7F03013B,0x7F03013C,0x7F03013D,0x7F03013E,0x7F03013F } + public static int[] TextInputLayout = new int[] { + 16842906, + 16843088, + 2130903107, + 2130903108, + 2130903109, + 2130903110, + 2130903111, + 2130903112, + 2130903113, + 2130903114, + 2130903115, + 2130903201, + 2130903202, + 2130903203, + 2130903204, + 2130903225, + 2130903226, + 2130903265, + 2130903266, + 2130903267, + 2130903271, + 2130903272, + 2130903273, + 2130903355, + 2130903356, + 2130903357, + 2130903358, + 2130903359}; + + // aapt resource value: 1 + public const int TextInputLayout_android_hint = 1; + + // aapt resource value: 0 + public const int TextInputLayout_android_textColorHint = 0; + + // aapt resource value: 2 + public const int TextInputLayout_boxBackgroundColor = 2; + + // aapt resource value: 3 + public const int TextInputLayout_boxBackgroundMode = 3; + + // aapt resource value: 4 + public const int TextInputLayout_boxCollapsedPaddingTop = 4; + + // aapt resource value: 5 + public const int TextInputLayout_boxCornerRadiusBottomEnd = 5; + + // aapt resource value: 6 + public const int TextInputLayout_boxCornerRadiusBottomStart = 6; + + // aapt resource value: 7 + public const int TextInputLayout_boxCornerRadiusTopEnd = 7; + + // aapt resource value: 8 + public const int TextInputLayout_boxCornerRadiusTopStart = 8; + + // aapt resource value: 9 + public const int TextInputLayout_boxStrokeColor = 9; + + // aapt resource value: 10 + public const int TextInputLayout_boxStrokeWidth = 10; + + // aapt resource value: 11 + public const int TextInputLayout_counterEnabled = 11; + + // aapt resource value: 12 + public const int TextInputLayout_counterMaxLength = 12; + + // aapt resource value: 13 + public const int TextInputLayout_counterOverflowTextAppearance = 13; + + // aapt resource value: 14 + public const int TextInputLayout_counterTextAppearance = 14; + + // aapt resource value: 15 + public const int TextInputLayout_errorEnabled = 15; + + // aapt resource value: 16 + public const int TextInputLayout_errorTextAppearance = 16; + + // aapt resource value: 17 + public const int TextInputLayout_helperText = 17; + + // aapt resource value: 18 + public const int TextInputLayout_helperTextEnabled = 18; + + // aapt resource value: 19 + public const int TextInputLayout_helperTextTextAppearance = 19; + + // aapt resource value: 20 + public const int TextInputLayout_hintAnimationEnabled = 20; + + // aapt resource value: 21 + public const int TextInputLayout_hintEnabled = 21; + + // aapt resource value: 22 + public const int TextInputLayout_hintTextAppearance = 22; + + // aapt resource value: 23 + public const int TextInputLayout_passwordToggleContentDescription = 23; + + // aapt resource value: 24 + public const int TextInputLayout_passwordToggleDrawable = 24; + + // aapt resource value: 25 + public const int TextInputLayout_passwordToggleEnabled = 25; + + // aapt resource value: 26 + public const int TextInputLayout_passwordToggleTint = 26; + + // aapt resource value: 27 + public const int TextInputLayout_passwordToggleTintMode = 27; + + // aapt resource value: { 0x1010034,0x7F0300B7,0x7F0300B8 } + public static int[] ThemeEnforcement = new int[] { + 16842804, + 2130903223, + 2130903224}; + + // aapt resource value: 0 + public const int ThemeEnforcement_android_textAppearance = 0; + + // aapt resource value: 1 + public const int ThemeEnforcement_enforceMaterialTheme = 1; + + // aapt resource value: 2 + public const int ThemeEnforcement_enforceTextAppearance = 2; + + // aapt resource value: { 0x10100AF,0x1010140,0x7F030051,0x7F03007F,0x7F030080,0x7F030092,0x7F030093,0x7F030094,0x7F030095,0x7F030096,0x7F030097,0x7F030124,0x7F030125,0x7F030129,0x7F03012E,0x7F03012F,0x7F030141,0x7F030175,0x7F030176,0x7F030177,0x7F0301BD,0x7F0301BF,0x7F0301C0,0x7F0301C1,0x7F0301C2,0x7F0301C3,0x7F0301C4,0x7F0301C5,0x7F0301C6 } + public static int[] Toolbar = new int[] { + 16842927, + 16843072, + 2130903121, + 2130903167, + 2130903168, + 2130903186, + 2130903187, + 2130903188, + 2130903189, + 2130903190, + 2130903191, + 2130903332, + 2130903333, + 2130903337, + 2130903342, + 2130903343, + 2130903361, + 2130903413, + 2130903414, + 2130903415, + 2130903485, + 2130903487, + 2130903488, + 2130903489, + 2130903490, + 2130903491, + 2130903492, + 2130903493, + 2130903494}; + + // aapt resource value: 0 + public const int Toolbar_android_gravity = 0; + + // aapt resource value: 1 + public const int Toolbar_android_minHeight = 1; + + // aapt resource value: 2 + public const int Toolbar_buttonGravity = 2; + + // aapt resource value: 3 + public const int Toolbar_collapseContentDescription = 3; + + // aapt resource value: 4 + public const int Toolbar_collapseIcon = 4; + + // aapt resource value: 5 + public const int Toolbar_contentInsetEnd = 5; + + // aapt resource value: 6 + public const int Toolbar_contentInsetEndWithActions = 6; + + // aapt resource value: 7 + public const int Toolbar_contentInsetLeft = 7; + + // aapt resource value: 8 + public const int Toolbar_contentInsetRight = 8; + + // aapt resource value: 9 + public const int Toolbar_contentInsetStart = 9; + + // aapt resource value: 10 + public const int Toolbar_contentInsetStartWithNavigation = 10; + + // aapt resource value: 11 + public const int Toolbar_logo = 11; + + // aapt resource value: 12 + public const int Toolbar_logoDescription = 12; + + // aapt resource value: 13 + public const int Toolbar_maxButtonHeight = 13; + + // aapt resource value: 14 + public const int Toolbar_navigationContentDescription = 14; + + // aapt resource value: 15 + public const int Toolbar_navigationIcon = 15; + + // aapt resource value: 16 + public const int Toolbar_popupTheme = 16; + + // aapt resource value: 17 + public const int Toolbar_subtitle = 17; + + // aapt resource value: 18 + public const int Toolbar_subtitleTextAppearance = 18; + + // aapt resource value: 19 + public const int Toolbar_subtitleTextColor = 19; + + // aapt resource value: 20 + public const int Toolbar_title = 20; + + // aapt resource value: 21 + public const int Toolbar_titleMargin = 21; + + // aapt resource value: 22 + public const int Toolbar_titleMarginBottom = 22; + + // aapt resource value: 23 + public const int Toolbar_titleMarginEnd = 23; + + // aapt resource value: 26 + public const int Toolbar_titleMargins = 26; + + // aapt resource value: 24 + public const int Toolbar_titleMarginStart = 24; + + // aapt resource value: 25 + public const int Toolbar_titleMarginTop = 25; + + // aapt resource value: 27 + public const int Toolbar_titleTextAppearance = 27; + + // aapt resource value: 28 + public const int Toolbar_titleTextColor = 28; + + // aapt resource value: { 0x1010000,0x10100DA,0x7F030135,0x7F030136,0x7F0301B3 } + public static int[] View = new int[] { + 16842752, + 16842970, + 2130903349, + 2130903350, + 2130903475}; + + // aapt resource value: { 0x10100D4,0x7F030034,0x7F030035 } + public static int[] ViewBackgroundHelper = new int[] { + 16842964, + 2130903092, + 2130903093}; + + // aapt resource value: 0 + public const int ViewBackgroundHelper_android_background = 0; + + // aapt resource value: 1 + public const int ViewBackgroundHelper_backgroundTint = 1; + + // aapt resource value: 2 + public const int ViewBackgroundHelper_backgroundTintMode = 2; + + // aapt resource value: { 0x10100D0,0x10100F2,0x10100F3 } + public static int[] ViewStubCompat = new int[] { + 16842960, + 16842994, + 16842995}; + + // aapt resource value: 0 + public const int ViewStubCompat_android_id = 0; + + // aapt resource value: 2 + public const int ViewStubCompat_android_inflatedId = 2; + + // aapt resource value: 1 + public const int ViewStubCompat_android_layout = 1; + + // aapt resource value: 1 + public const int View_android_focusable = 1; + + // aapt resource value: 0 + public const int View_android_theme = 0; + + // aapt resource value: 2 + public const int View_paddingEnd = 2; + + // aapt resource value: 3 + public const int View_paddingStart = 3; + + // aapt resource value: 4 + public const int View_theme = 4; + + static Styleable() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Styleable() + { + } + } + + public partial class Xml + { + + // aapt resource value: 0x7F100000 + public const int xamarin_essentials_fileprovider_file_paths = 2131755008; + + static Xml() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Xml() + { + } + } + } +} +#pragma warning restore 1591 diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/drawable/icon_about.png b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/drawable/icon_about.png new file mode 100644 index 0000000000000000000000000000000000000000..48845257c0518f1f45f140fde0f47b773b0c3d5e GIT binary patch literal 518 zcmV+h0{Q)kP)Px$z)3_wR7ef&mpw{DK@^1(5nX_l3aQ+Hpsj{C?wR{$=G}SebpEmC8R%9Ve;fS(j^Gj8gFEmI&fpWA zz$yHItzi?VbNC7$;T1H2UAXmq_1@p@SEt^%#^~Yj4DaD#p_@AO#u;B5$3*%xmo*)X zGhUy{Fmr>4l_M7ejMt~qOt^MVU)?7sbOHM4SG*@K5W9vs+#q;|UUSgTjhTh7np0M? z;T-%Edd)#Uef3Y`j9y=*5>%N1{q)s8iCcQdNk#om>xBMESj{XdIh-Q6gD$}}EP=lI z2W*7aPs8%+TIJw$zT`x|`t{X6AeO+qwg*v*4bKey17Zm*iGsR$W9i{y3CtL0zxh~E z2YvMqh$Y}AISGn(8~SE9;RMmB-Eo7PzWN8mW?)M10km?p3H|idKMQMi?kwn|d4Sdd zuYH(8@mZjWr`B3eLzC!13&+r#1~6V9{VHRvUqth4&D`a14NEtsI`ziYdUE0x;GXa! z#i{fR7{l0CvA^4|PQ7tSbd$ZyoqkLVpzpH@tn7aQWBpNl0S&!a8UpxaD*ylh07*qo IM6N<$g2fH;yZ`_I literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/drawable/icon_feed.png b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/drawable/icon_feed.png new file mode 100644 index 0000000000000000000000000000000000000000..fdf6daf8c9af60bf3cfabca744f23483e0f50704 GIT binary patch literal 415 zcmV;Q0bu@#P)Px$SxH1eR7ef&l(9+!K@f&d304+Dfcu5;=<-__*BMKmY8_?xm{w=y(DvPX8Y#x6G8+v*!Po3ozcR zwbmWn3^IGJquYfc%-{u<5;+q%pwk2F!3Zwk2Ex6R(Wc|F2;m-r*iz;R(jDXoTL4wV_D1;t@_jzJN85FJc2qBJ^&ok44h(5@aDV zfis9hYEq~^_SSsunkA}LqzNUWc0t}ZI~Z`;iLs=Tc6?zg}j zoEeiRD$E)0eha)wnlX8z!kqE$dTur{P=fwp*oV#VDl?(Po7o#O5e4ek_ohXBRhodSiT!QBJFi~GlWzk6R< zYp*0f&e>=7%rkms60W2miToDtEgT#ivb2<#3LM-khnL^Oh;Lp#w^j4CUcP|l!t%m! za5b^-9*kbY!3n`hiwUcFz#nBHq|%Gegb3G)!Ba$}5KBp*i;*M61C>7jUnvI@z2DAs z9(&`20Th;&`JM|@jt@YLAeIh@{~Uk2cEaks(#HFFiQm@>+y*U!axd|&d@;y6cT4?I z3Cl*JbYO+YWd83e0fLa|HcWF9PCD<8#fE$vjbv*x5i&kyym5x1g62xDv<@8)ISx_h zt0*%adZAi8Y2T1i|Fzf<-^(Gy#4O46w-Yv!fSY3XO+8s=c-QStNy+0pL%oszUR{JZ-TF!rYRhspurLouTBLJp z!~&&gwJ>BgCurMV@cid6AAx{|qwYyhodiM;Mvfig!y)*HGfm@_keFrOS0Cy`+5dfT zPz}&(0aS2)Wtz{63VA1+36orx<8i>BVWOA(3ZOLnXJsL^SDo*|Y>UpXaNB3=rQKJ5 zG~L&FwUgZ6c9*ARjRWPn|5-4RTy-)BHdwLg;BxS&ehT3>7Y~MJQd~0~@9wF@f5{yJ;z9~xii{UMRdNale5 zYBj6r2ca*^lS066Wfm26mj7_b3A5w@k)Xg{6?CI-lk8N`=pK$#-b=mwCH$be{XZDE zND?BHSa%D|<+b$${OAQ|^{i|SbT-?OFbnoTM|?EWPN zx}BP=|B5CPNXs7_kFv}Zem%l%;&ye1;gLMCYec)_e2F|6_iu!}X9W$%{3Y@jLg?5M zF;NGZNlx~c`xxCL_WyDR6_7;mB5iOCG^hF}tOlPzoEX$Jp&g{$+=XDJJ^U{syMZ#o zxj)Dp)g#^{@H>nfK!HP7 zrM*YY?|(#4BS~`a@JU)#J4yz3p)8T^%IsYR;5+Lno zz>E4&Jh(w^hsMsk3NTV*2=1fPM{xfQTDe?OAT7&Z7m|9c#xUrjSGv{l0api-etryY zE8}Ba!2A!TdokbiTl9nLxfNQ^)r0xJ2oTNO3ci6LRwn!diuZi*ZzOjCz3KC`sZVq7 z08~G-dp`|U4l)kfZByQ~(Pzns^N`p@Szid1rgbG@`5Z^F;YDRGpbIb zUE2))Kg`Jm11(gEL@bJpR$NxaOhpg9T);C3#ZMU2mxu%izf9M)I=aGiy`vG^rReXp zKvdQr5=8&eB2XjHLeZKs!>nGsaE-JU&$g74tiODc5HuCj?O0v9wL7Ncem_&BjhPxU zgV4CT-S7{>l$ZeZ#e&jel5Zp$NVV-`UjvRLek8td%*Km%H*5Z31-QdXIRWbCwb9As zmGq*X`}GgvtYp7&Ts8okd>p=c<#Yq;i;hue8+0WAri7q-#;3OPWJf9<9Yz4p?qwZ7 z;a`u`d0|#EY4hG#hKGE_QHg)%ooKELAs0&HzHp6(zeDpZJV`ad;6m#wjIutq{{z}b zIe<0AdvAtCm7>gFDa^Z5QYn?M5Yis2Q4>SH6PD6}L|abf)aTX-QvMGe-QAd)G$f$3 zNqy?P&LUnk>MsZ}Z!Q5hty&2F9lwD2h*828_tY#0|9BapUx>ex=W|f0W}AHQ0Y$Lx zjRJkgA2_L8X+lhhhri_mwY-$$4*qd$pih`LN}G3PGUfKS96*`B?C0ZaAKjMd9DQ2= z4WeA|UJp%Bh2=js-k0*!YV%I@fXc0_^-s~>i$%!*28C+i6!2FugOItNF7Rpo%_u6s zvoyi)F3ba+PGpdZ%lhdN!hE}}&xIAHl(dk&(x36Sh2%E2|EDw{KeQX!UYRwC`{SUy zn_SzU>LOLAh40n=%H1?qHP zKehF@Sws==NGgJ`PqeF`&dn%q7QocEUOt=A zKKnmsGDJf>2^sfb=Gma;mZXf8Z!2 zj(Do~`Bi0hbj4!Ph*$D4zE834f~hCYJMxJt^YuoOH}0zd_rjuH#69o;i|*c?lQS88 z1jakZGyhlDjVGYUw(Hy&kuMIJqk-MvV6jD<&J=mcrnN(c|Igw;k#8sZ9V{w!1{aSR z(4Uki-=BRBF^}7Y^T-~y zqlZ@1;2AA57sAZtR?;A?U-mqcVxg_p|6mIgfwA6ZPOCdN+Q(jFTJx)BW1mr7H#qCJ zd$`#sS5laeAdf>a#xo^_@q~+bv@3st#&#O+neO`~ByT}=XyIeYz{bJr03RaLl!3-R zO4{6n{JpKPu@P}u)B_$0;%=Ow{2>^L1tCJ|l>A|zVlf6&zU)J*I`z|sxeeK{`$+Kz z=l`YS4s*RtDwcgTVBbCMGAvL6`qbw>^o~AD?pyX`+X-V#M|2W{9&U?2qTOii>yL-y z8$IoA@2;3+?4F0XD%j)Ucwzk|Su?^=XEN*KXS|1w`oM8qPwt<{70ww=f*LabWkcGk?hZSoo(+ z`&0SM$#kJykvDeCmK82Q;gWK!ujLK@cZ`yTzg@+hWUhG@4IcdgIv9_^RBnXI!3u%x zvUR4lh~JW+lYn5lIN&mWn~mzB`o%Iuk$2Y=;sZ)0c~YQv1>8@jG6)n-yXY>emQ+p) zwSQ}uCt{(;m9f|(TlO?sCj#BM#efVO<)un+wb-(tgiR!K&(phol3DTf53?-6aoJey zs2L5<8x5C+TEGwQx8L3=f7P&M{5i#T<{HOTBsCHCgX#?HMk z!>#{zH+u*m{pjxfq$1Pf_V7n^w(@+>!{Fmcj4J6x#@h2)!&ZB$YEeReBxsPa*~i=~ z;cz<8?Fys>E#>%wS3z;7qJd16lX zBn$gFSuU;c{zzg@`x7`m5`!u!{uZ>11hJ{8v><*ijqDn|*6*z4wCLzOG7+{P`l8M$ z3Q6jQOQrqjE1o*3&774&hw?b)yE!ZAMD0;j-7MfWFz@Zzm$|JIsbqOA^) zvdhSXMxS z<5uYpS)HPMRFaX}f2SU~nLw48Zr`l$WwV|TeU(0zi-ujc%4v&b^-V0f&`p0AsI4oP zTE#h7uegaKDC%9WiwnI2OTt zt49PQ45P&_`0^4Jv4jI=Z}|mZPT~6t^Gr^Z0=pIVCJ~3J$VzH{=3m zJTCE;a%w8pE!1@tPrwRTi;~3|Tt_rGP#@jgE+uM+|CL>yS$vA_(UlLZ;I+!wdQO>h z?FePKtgP$&UrkI*5VCj)myV`_TKu?0kA~?wV1AHFnMNA1f&*@jBZ!%^mijZEU{$zF zh>0kZLkTQWS3B>9nC{x9q36ID(c%4S$P_M%6~h+}JAxDjPHesKE6IuZ_7a82KiAdA z&DaMWeycIA= zdI>iEmOK_Q8aJQ`{cQFxl$Ox=d(p^h=ARXXJfj!|)QC{68@ND^wwjxT%QK3UR3#sV zR6JBvskpE&DW?N5LaqsUv_Fd<6mScs)5P4qgH3w|LW1V+YjA7QYWAyt)l_FhPTn_G zdNJpGfcT|;inPJMAjCb}OT9w_-+;S)e0JvPkj;1)&3fwD`UoB}8~lJ=2;hFRUbF5C z-YR}Y5*(JyD#!?p_7Si{!e1XxA+}+0{)nepPj+FajUgvDQ$LCs)lmSeR6esy)IL~h zG~Tk}Z5^HLuBz?w#?9pChI9@t$^2Xtljq>hON<<*?zx7*M_*+A$A=!#p4MO6>$y-d zoPO-y-Jch3n+tfdu9-{xOplC9`aRR2l>NnfIB*KxzPZ$=Z-IZfc8I&5QX>x|jUo*f zsTMgQCX0%9StDi`OE}E(xBeg6UbjiVarb5XLRu;9XaR3C8A8*^lDZkcZ?-fs9d$yY zE)e#J33;E7A8wzk{~pMj6?ksK^GP7Y_anrU7J_Uu>Sr;h{=l@ z3x-tEjGLeuwSr%?r1cizDrqeGbo#jP_ZM`~Cn=Dg6V?y?-Ouw#_>!&2O+P2wu-+}8 z!gn5tL?IyTMI{gqG~76xHDg^qK<$GX5D!-?%{?AtBepDj+qtOXsM0_2hdf@(1qpOo zQ3fzBPg)ZBEc0r!$;38ONggE3o8y6F0`LN9;_W!}LiIp;C^)`GJji6-0+a3|@$-ww z8Sa|Nb^=y1=cV(w4jNk>OyTp>)q1b)-(Gpz$k3Cngbp!P=b*3Yp$C{weoMp4f^Bn* zPb!{1FKb4iYpgi5BDE2;0g~NoUGOBn`R4oPx=sC=S4pib(38Mf+I1~jzw41sl}*A#J#p|w@hyQtE^yeL3Es_X|se6MT9{+9Ug_CUcL;L}l@ zU(bo$1xMKQp~`_lBEm;&tKbZ4z|D8i8T8~qt50RT7eN*JjRm|4D1gR#E@&|kD~zBiXnx)#x5YqcW2S4dgiK8b5Nq6vf`LkjcnL2O-zq zZ3w*|rslJ0f1RH`|HH(}mc7Z6QK>{Fd#e+T8=AoC?^>$xd6xu3DjRuvYm+9OwI?y* zmE6wnAJ>l53v+hXi_n2t1#~7b;*zbU*g}aznt97=pLQY?wu7KwlMh{%=g!?uWX3A5 z_*L`$TvKP1=dpDdRr9XWX2Hjii}s(q^`=~J_Z2*y?7Rbb1k>w&dn_1L1LzoW?M-V? zaW)_!D^lx`WABhf_9ebAR?sBaeIpFX3h%xw*jvd@(J(wS|LwWjmJ--CO^fVd|P;9jb+i7rsp|pa!kgJ zO=YXrCs1qBOvuK;5*;JJSHEVu^X!gt^lGRAANRPzG^fLC{#U1BQCDjtX zejE+X@k%~>H~(wCKyzVAhs)&?hkuup^7UDdQfE3lHtdn>YOedPi%olFy2yl-73-7d zU|JF>p~%6*B-i^j1zcYP1I$B7^%lvY=3fpue|%>3zExr-Sr2JIaNbZ@njcgeXyzk4 zQ5#DJA-Pc%lB`VZTRKefZFICc7snTY2M>H{_dUfkcXcNnz0^tFXFTtPzg-E#iEi>8^mZkAqzDFa5f^N)kbVMbc?mqw09#Bo`gvS5#VhW8pKoH=KyBkX!eOCq1NU z-^^5MZ6I9dtZd?5I?hHfxrxx2{M}wppQK8iZW5 zlNZg8=W1$o?cSUp#X^dBOIjiGBNvoON13_3uO`cfv+njzHMZt&eCkUs2gn>g=6u4n zmtPJ&n)hE}BjxB0e!aQ;vFrlqe~mP2LnpaB8kfoYt8lWhvXf|0eWD9F!o>ZM-gvt2 zfkyR0E~K#&W5j&kgN(y`N$znem&Vw?f6(*1RVWQrc~@Jmz}{3IrlucL6?r`+41=gi z`*uBHE&<9Q*N1cAl8|4+vqpmz#~3vw=WeeXZQS27VhMkHWM<%5L|qG;kS)wRDJ?j4 z%_zTH@e@86QNmdemXFYbIQL?>FRV$}v@!SChzNpL?`us*lOqG|k({i;yuL%?98$l2 zhcArEGP&y7D{ej`ZgRD=2m9AjUR@S$ukczw5!|{_&f++2Go`!g1KHv~D=X*4Cu_Vq zQ@PUE!SColH8pO*qjNTKmw0Fc7?_)-(ZspG$Mui(B~=AInc?x)28^FyOd#u7PhU-Z z*x&&dA;AXt2IYQ{5XAboPHs+90SIL4R4y;)&F{BGR;^;Yp>p<+-zy+d54(2U{(Z+j z_kiq_G?SZQ(j3cjJ!#Jsial|!7?~@1r8xZ|RwKX)tu)LWvr~s6ly0v~ztvflw99>c zIh#K8YImD3fy_U-oHJoRiXJzM3I{YEcQ1EkZ(5~%(}}^78TloTjEBk(HX4^sI?WPi z?#KE75Bc!(2RT2qg3}S&qW>Yh!knyKJdf6FIL(ua10qipN& zm3&e=iVnGT8pbxn9rEi&0Ji6Mj6%?Bm3zQAkxS+4`6(5y_sYVGjnQ>62W6`+F3F*L zzp}dcZ99T1lgA!Py($1e&}KDc(diNKX4GcSF8!zNRSh0)o9V9%vRLCgeX;?9pPB4r z@cad?QUmQp!vklH%qV)_zE}o5Z{6JYDG-Ot66TFmYw_&R?Kg^_(TVHierZnXIGdnN zMLA#tl;zOwgQFLP8#yyhy#=gb9>1>#5_&3veRDHtaf~_$NMZq%2lwM)d0X;Px>N|p zt>@Q2sZp(S&s|e}SXoi(g;3$ z8FX$bOw#mW1KgoJE?T6~RzE&-W$)TU&391<02xN4QqN z*(3a;!H08)hpGN5iHYp3s!OVu>fGQYWn2v0;GcpLqV$pwJ+8(E)FlenPsO%PH6xea z7!XyxWY-!WAX~nxW+$odNCyMEhObvEm^IqHFYx@pyZqj4tzySYKA|z*mkDIz z4i>qQSmTbn&Pl>C-|AY0rdzbm{pMLIF~az496cOfe8}`Kni`%WMW+tU`16}&G2tQt zkSg?4`p{tBWS&m*oNwl~jAm=}+~xiAc+4g3(YrZWZQW4sFaEP$Kkk0(&)y7YD>8l1 zDL+(j+sIj*$46%3g#G-MU?%YP5vxo!){QGPY2pY%*?QKV+gOBI%UNf(&%(erKgKEaSA9 zKB4{NnlbH=h4cKhP$5)D(8)CNJjW?`?O1w}M^}wdBZ+@SI)Z8p`!KxQqyBT+@z``q zzF)N(^PSoqhAGzCtNFfE9zrkdM%#QQ1RA?c7W5A`r8Gt~&3M zYMiu>JoBe*ZtlZT8)~2K(^o~I*%L=DQ!)olx7r0Km805)AD`Ig@)oRqXGh`*@>^Am zO^}}go=YaT6T{$qR0(6<-@B%HjoBSf=kCz$`FL0mKHd-!CGW9jyHmT2Ns%@xywl9s+Fxyy$n@3A+;`@n7nw-%`*{Zc#ic#IAQwrdEQ|>@niqS>y_OQH?uf zbdV8NCym;*qX8+XOxxqONF^zJf*oI1F5k-@B0L@|#)TH-fZHVy3=o~)l04kKid2-e zn$^fWgOSif$%6h|EGqhkIz_LvUg8a^{ zV}4}&l_j60Ci{?qVEgm22I#uCJpB@hHYoLuZ=uh(e;>LD=G@wvoWCD5$l6bkP$TMP z3!w6T52@j??c4p@LOpw&`tlCc!3mu5s|(fb{U9WRdn9IL%#rOi(N%xrAmyhfl2O6A zjf1yog^o7HhxVze0syEPAd?JpW<0PXZan(T$)8EmHLW(kl2<|D7SRG|R3rB-tCS9K zn)T}7>e#QigS*j0G{nGlc=~7KJxzgx)*7bY*B9!`->>i=d6MPuKzok|R0_XD90N09 zmx!4XD_4E3SsZMnU+XV8eim2P7Ot&_ftiBI>&<>vN)as6kc^>V_CU+Y9Gbqn>)A{h zVf+$Qfx65mX-3rRiNSGU^8>C=GJC9MduLuUL}gyz?KHFue2Ddqe`qPgq}(Tvb^K5x zU#Ly`TioOc2z^}F*Rsw7U3+B})xN;)o7Ng@`lYum){eB zCo}x0vPQ}_ROg>04jkFo3wCycdMeVD+7d1rY;=P^UXo(*Yb>4Pm@7liZ>rz8(P3u| zd&TUw^f>S+4Rr52&uh(>6$q1#x6MD!pQTp%r#n?OieYu~O1!JmSYi(-(|T*r$2R=e z;rFg&=J}2C$$}}3XJDclO^4l+N|PBOSD(@+pP{7R^Wj^FKJlfDL|(HV?BLqFDp#t; zozyv2D&V$PFo1TryE>=b$~eW)xIUt@Pvt{C^#pWnEVq+ueh$w3#Afippete}EjXE&AYr0QZl$=`EcI9r~PkOJ1l;D9>-GB51H!}1`#I^r;y}6ROSPoR4CvTA z#OmeHal+1`g3N3M&*S2TmW-?i+q5h)W+*Y{zw#Ayvt1Z=MDWAJWbczyCl{<;BqEE}CR)4v;#T@P04rib*;(<7d?&x04eJ5iiZk zMR8qalX;NHZyjg@N9}c=y>5iVdN#-(Mvzt)Jgz7WiIav{lXj=a1T<&-RMz2h}GFqsXv3{K}GwY*GfPF5^Y; zX&4FteoU`Qmwb_ye^!b!`tmjDtL<*3D!<~W^mLsHrsC>;P{GC>!;3QNSZH{RvCbn- ziI3M*;eSjwRv9Q{`qN&p-w`3o8I~NprjQEGO61tcId+q9XU1W$?LOfKD;MZ_?U-!w zOG_muBq@)trdHxiT0U6_Uu+jktjq>Z-ldxD{&g?U2Gtv0%`0aYi{{pB zSej8ZfcrAL8`bE!Y*mBz>i)3>c&QM!D3b&RYJo$c^s6fp*(B1w+wooQ0C$xgl#Z(8HABynmjWr} zQS-sD2O$?=rGuzvws{N{P3IyKHAoh6!n4A{7yoKc*)&SVMJz?!`iPqUAc~@zMc14& zvJmJd)*)vPQ-SUs7NWb;jInQd+DvoiyVB(Rm`6smHWN|PCYGTFjkzA?)M4zI#XV>x z%e_9g_*%+@%m|Y|}nMB2NghYLVz?<>z-konCvbxz9Q=-4*!cc4=ow7Q;ps zp+88fpv2lMdh-ddsJuEa=SpM=eTqE*0wnfWSfyeml9m2x?PAG4%UqLbCECJlKSm!c3zXFTJV&CZY*nfrN#>Z%Nm5hop2 zKBI9)P~ZgkDGg?6=B1)Ag;#Y+tq;=6k2;b$l;0RT7o}_fJ4Ff%)1u$-%$7{n@rP0+!?q7LZrkRTc8basV zPpNVApd38YsR%gPXkDW$Kj7Q+X3X=$-v2=O)qQ=HOb`)jasCk!YkSZlQ~ZS1oGZ3K(%$h?PJy`d-ce6Wsku+)CQ^wrL7Kov8tg(WFOy2y92E{3#l5NGA!C|KR8ziW z(lpbV2m#4KcH=spi2|SWPbY)&Ucfea_M(k(_s*F6y$qbKN}5shX7Lj8R_Do(qwY%m z_@TMjsO&&d``V?tJWq<8s<7$ezS37kYh*ZaBuQVaCu@1sak{uTFCG>+d?O@rPFdNM z?mzhbvC2WMG>S0n$ag|@dRWy_BhP)%vncfNI~UlzH~Ho-PNBk_omZmDPGfNGT;G!6 zH(v8#cpjL-PnFAY*1%uY;2iAkzMAQMFkL^&{@E_T48d+Wb9h;W@q1`D=vxlGBIv!R zB4zAxlwA&q{VKh;s$qJ2aHb$9e2#xh+zwMW&cS7(3=5SnoB0Jt?Oxp3B#fZ&XfnF5 z#vq0QP?Dm4$?y2yn)Z(<62auSZz2hQ6sDKA-dEbCnh&@-pDJ2k%mcPL$Mab&6VPs( z2aDgd#)8sdAyIqouv>nPG*IIw=EuN7FnLIkMBgbs{Y>~fSr<0Jka;ts0Bo38 zH`IWNr)J4b?D$giSB#YxezLyn$p^V_*3(h*#ozS=G+S-R9A0{}*gqCqL?s$s$ak$2 zX3(PoiDV}^Z30(h=>~7Pk*^%BZb`8hsu@iNHJOrl1sRmfVnxiIfT2$$D^#?CAHF~-VmJwLR`yK|0KC2v=P2xp%TNAYN=PRlPL zG87L?f>hz3dyCoMNknQ9rvUVMa?QtVjyCZ^-u9aDOn|O|6*`g*uezD7$X?^K_wV*k z!>RSzR}QG;G;|VWl_Hfk$?Yq?G^6}9G$>5T2SF+_6y0^Ij#?bx9ui{Z|O zeY}=D8Vz=bE{w??a;ChJSl*iVWhung>T@}=AIG~eZrHBgNYuT$J^^BBI+262EQiDu z*X};elx!4mp3r};9Tu^^D!K@nuMbw!^JAC;+%dBe1ZYl`%OI`R+l`1~K^pLOKu_3w4KxU$o@%`JJ)y)T$Hh-Jqvg&njfXVpa zuCyoB0h?)MlskLC=26>kqJ=o9xL1!b3%^$zC!1g&)U}k%28Bagv7klpE>!%^wgMe^ zkt|Yt0lX@B%P!%S^{NFZRt*cCa(WIS`%&3GU(vs*bCe><6f>eH#&r}Jm0xE zk3xVPiNjsPe(k*)!{}jx4p_pXSq2~Kmp^xZw?(KUVlwmZWcjK$=^rae*XnF88iPJ&f2k`7aG58UsCp40a^OCYln|yO}#C^7Rwi~-|w}&tNO;ER5qq$W+ zufzE3+KBHFpFokPrPjz}${mL$>~hfk%~T$HSU>lRd&8N#+S_lc`7~=#@tcs#_asyh zmFHsQYV+=7tyA3N6V){lnKiVxoJfDoI28;QvXC*=?6pUJJjS53$lCyZ`gW$*r*Y>@ z06&%#uEdK3sWp&xZ@%8s*ipXhb$Vl?ddSL_(?8bT8L_{+HgSR}!1Ef7dI@nk1D*vr z$pOKRI{Mo)H|JVxMPOFsvg&;BJmoxTDzCke)OWr}O8Du_c+->ao%iM!hoW5$<3#*z z&Mv}21xCE?%69dnq49Y$KRw(Tm(#Uz)5b&(!BWE3(PZoAb_5Y$pDniK$s8UPbe!#A z1F}09eoVookSn6Y4>qplGnb(=3LxO{Ea=^P+j6x99*3kXkzcpms8^~bKOo?fq|543 z<`)$7FPC-!^$+bY39S`b&&_lZVwAt>ls<+0B`;23Oz=_Q$_E>bkjVPg{Ocl)CH5kx zagL={?dWGO0jK-Qw{1#P0NC<#wdxytI*D)2rYIk-7{D0n+V+LKJaQEXBBwftZDBvy z0)?^~YaqwoN)2Tmu|gMN8Vk)5UDIV2KBiuIGGI+ELGzz6ROf3o_QogUY7=RsNQt&T zoWI)4(kc-Da`n+gsN7id`}tVkiw3}(;x`Xy#+OlNq;` zK|e^Yvo#CgQJEKE1O0xtvaSR_@j-Xf86N0oXnis9QmqOllDwv;V zU#octr%>!(gMz=~z2ONhw=TPZ<#KuCxOL*hNx^AFeHUu5J*;{q-1b}aHKDRdvfD4< zn;1A~2{>pCbo5Q0#Q|;@r<&JcXNjuex@0Eh+)eCJ{fJDFXx&#WkEj<#R=3_YZ;U6u ziQ_f}sf>Vxr{KDdi&4e-TfUoQhcUp9%%EY6bpl@^H#GQ%_va-#EmvPF{QUBDEso@Q0c1Q5(NXu+E@T~q4U=;Q zicopfr%(#U<)Cp{X&b#m7iC?*`}En2zJK5FIM%N8R`_Rdx$e zAV#JRX!;2ogER9yrl*4fFM_Klci^!;Z-m!=>sf@9Ds+idf7s2Ax1TPvm6-Ewbw1VD zD^Z^rGFlG~w8)ju7L1CaU}INP70ddAd86k773g|*$vnPwbDne0t)39LN_-t+WeZG@O&*`FhKY(SnLu>*=Newjz3R z^tFtedQ4-SAVidyFn#5Y(eGroDf5f^dKbdyCZXI#a^ znpg?;^?ZAOQ3}A@!V*6aVY4?h#g#xCIIrj@QV3WwkU2Cc(%bTw9uam!McE|U+lPKy zm3Y>CTI1IAXSrZoQ7u^Hm+wEPp*@7khEF5m&(YvtJ(DqOP>sDPK=KP9%Yps^vyBzW zAIBp1nhtXL`?+C~@E9j>BN;-x079m>nVA|+@V8jOT@wo32ZLk|AAUcvucikOt#{#J zlwl{Ph5WfU)WM#{)z?)Ow;!M+=(seg{~;5^W6WvfKX7b^cP23Y{8xkf5mM%FaN43h%2IwD z>xypsYY4YjN^)j_VztZ5Dw3CX*JE>R!_Y z2YzMq+NR@e$0TnpV2_8osGNO_at?aG4-(EZgs_kflZW=rC-~v;`&wE)xlz6hbdb&` zvxC%t5=Y(aw5zd2lBkO(!CiIxg;yEp_IYvaSVj3K7geC+h}#ZJgMfF>UGrXQ_XMi| z_(z*>$8J1DBo5@YpWnzD{1mu9a*&_x=x+@SsY1OepS;=vxYSCOi-K=!zy6MsRIQHb z*$thXL{{LA;4OR6{{*--$h*_$l=PfeDL4g}EMwy&zh;|q2Z5}v>s*rt-Bo)j zuP(Tz3ukOm3wE7Zm9dTjlpREq3I7 zNU|(}hDz57TO6QH^dZQ1!PiXBQ=Ez;I%hMwXqUWHM&T06q3BDLat=OuKW{!Ru2cB& zuhq`o%-moCr%M$Zh!8$8Lw{`xago4>opXbqrxj9cVTBgzA`vbh9p%$RG}A4ZhDg1B z?7AD~LoM!-*u3_?0vd?Bxp{CwJ``N3ecY1w{Hg;`%TtAhWkbxNWzg2PyNSzo%^#Gq zMxvJ1)AU!$srl71-tZll$B##x?hWFqQtV07`~E<`Ue5wfFYY3eTrK!>pzJ|(xRx1y zrc5V7z(Mk|jph$?gTk(WCmHBoejNFug}ckt3B@XBI<@D^TfZO5P}^|(<4K=Ar+f1@`neye zcCh`Uv_}P^!=_i2Yd`=}Ia&z?O$WRdXU2V+Ps~+9=RqX}NSCnr4LtjlK@~-`k8p>~ z75^WsUx_+QU&FHRSAT30T9A)TS&23s+{8C0*3P-;beip4sH=1wjnJgR4OWcBV%F^C zaNIJb-)}o;24Gt z41J&H1tdp23KxoHFo#w^TgJJTqL10KdT;hZdp6IcBrOapqF0^b(h2J?l1Dy_pILmZ zT64eW30g^zzg8Mi^iqKss@HNGF=Y{7m~a(;?n;Yp=NVI7?pL<3cH$3vLZ*(^9-}_X zy~rTW%4a2_rCt9+sq_YrdEV+-rSTSvsZCJ9WGeeK+~fDEOR-W4ocy$FdTLL2Ua%UO_C8!`b~(ez(DIQT6Et08s8h zsVe?wqGyKP<|ip0qcwnn6wNb+wtPtzV`-S;tj{i0$QIFM24pQ(rJO7{7b12gbWDD* zzfc#OogguUFw_9u<4)Mt48GHdR0A6omloxbCB{8bOiz_$fWQAW5#reTruKmH`|O#Q zZc{74NxF=OXw!})O%sBnB!3y+ZR0>K-&$#kfV|*aQF{*15412oNi65Jan(u#)h)^G z`iUQhviFt%X(X2wP{CwARIpJ7rpNuW$-4j3epYtDzB!p#7eCe`J_D@V)GwPF!;GjQ zW^2B=IQDX`(JE$~2I*Kb9I%}62*yeMAbq#7@v4BD04H>5HWZxo`P#p@Np~#1S)b1uZEf_U zv~F#k2mNd+d1%0B62)G5`%c-3pY!3UR|K0G^yja`8_-E>>Lm7~wiy8$NR>)n%@NmN zj@0T>s~l%Gp|6n$zxHzMEktrTmpPUVlybi(OTZgQcj7^`M8!L6$;rb5GK-sRH$MRJ z1gT%Ll?S`SrV^a7!&Puhei@b6Iv3Z64t+@ul#x^Qmgsd>Ftu(9CkO-m<*~(^=`7-c zCIx;STr?Nx(S8G4t@62Yzz7aRwzt>J@I@Zz5@}q&QWC;1?c)?29d+JxREb$(Po#&} z^5Ren=2N$`jk=*_Beg|xDH6bU)4j!9CzzaGO<-myfY>5FvC1TFJu1d|^*yLiHSSrc zZX>6sh2G9VVhM24 z{f5<8)5-=fT!Y@7iIk`bxJkWBGMNx#oriS(DJr~%JHqr4GIrUL26jiQpjn!i+U@GJ zr*xc~QC9~(efdF7R!b>^p>AOplf zOLX<~CH-PcLJs==lqpEn64{m)c?*q`+N_!G&V z<$!evQoAwb`75jupvE!L))>tA9@2Pl&Tzuxokda_b!(L|*b=G*7v|yz92aI^TkPSF zir*&MesMWcr&F!kYE}x>XOebe1+}7=jBx+JeS)jFcbg!FMtn}(gjy`{R$|U^sy88&8 zV)x#}tyR_(3jzLfxvG$9c(6ow>rJf$slQ*3ALQI#8e2=)p*E0B9)rYx?Z&|Yrow8)z}(}1p+IeXx+wJvBs|LR>TB@Ji@?#Bz=R7_ zjgqOGx8a2O&bMclV!sHOcQ%1|i4BeYer8-vI>+vDdx4diY3z3{d>1wtc?fuc}^l8bKBTUJJ@(WMY z`S~OF&y!zig0gP%mhEp1Tuf-CMZ7tJ?7P+FRY2nMxqQGU5Z$CLO2awh2A?+hmsAVI z@GJ58sH#tDM7-Z=<)%5pcayXU?(G^4c&cvdTv>JRg4*Ln zDunuvz6g$)i*@`gLRgM5^zzLaRByEgbL?_2XiLe`trky1C&%sy)=p>=Hg^}>_kLh< za*j*{fhCsh2C$K_8dH%Hzr(G?DX!0EA?ZS*lj*o~1PCjl!TPj?`1IBi);cfqMY;T- zQxx5TAAOnvQ=N-b_LJ`r-DK8xHY^kpg*cP8^>s7Zvlv*jf?ofE+{I7hr+P;#R> zoy+9|45*ATDgT^kUS&uOc*U0-{J%2JJRGXF4d6OWp|X`XvKASJWZ&1U*~gMn_T`nO zEMv(!ro|FQVX_Wmo2W@BA*t~yLe`NbVWOH0CNj3M%y+!k^_B1XuIv19{=O{W4MLsqFvI7KDj33LQ8iz z+ZNOor&JQNpMr@;dk>a|;}lp|?Zd9O>AE`feFMw6z{)W&ic4@>6I$O96%I`ql8OC( zj?O$lgC^Yq8 z-QTU+@1tG_uC{6icj{@ZM$JRIw)byBA5asoh>R4DfQb&`+bS{q{g|_o8*2k2*_F}~ zDs+Q~POayJebQfFP}pW+B0ucJN_9m&uQpuvq`&5`7!wz6$u8|ugGS$mAytI9mf_Oh zx{c{q(0$+52$$HYvG+%ZLM%T2YkPKb#(Jh3;qH|Julvzori;lR-dEMn6uCIn6W?0{`> zxAD|8U5Q-_15XrT^O$<+ahw*je7|=0TuyA|J9VE0BH&@)*7dx?688@2NM;#?syHq@#9?m%fNsfcjtmE<;PrM z*_(3m!KT9$IeB*D2Z5J%2G4o`(0(<*3=dZ=`(h9#!z>=yaz<4MP$qWT?Yb8mxotWR zPRu?E9ej?rF+NDF4Uvo1OBu2xtccRN%$+;*yAXlb&XZveyBE5bR;S`yE3Qvi*+g;V za&12eeVY?nu9PHr%4y}yqoTGDMU*DbXp;NnBU}9o{;b1n&4yJUoGdhCpw+N@`jDAFiMitl3N)3-z%2n~zd7n8aA}n}818tEYQ*bzJQW--_4s2@f z3Ky-go_*vUSdw)wM%^(~yI#j5Z&tG{Bo-#Yly{w_#`g~mEkB-nt)qsz4^cP$>3hv( zGHgr6b1cR?+tmwz!f)&U;uPX5Mb3~>#)b2?V+D&Vuin4B3hzmD#kh?s@OBKoeb(Fm zmoYP`0slw@?(mTH8`DVGcNJH3j$nXQ3!k>Dn9%5D#7hc_PM*}Cs5y_po2d68BAP2g z%adN_7rpW2nnPTG_FDj(c4Gl81o?9={>*E;)!|V2MMx$%h2PHb+<+X;j;9Un0nCSv$kcP0o<=syuey5v<=1)H7i#$q1wKca9G=>u$2s z%fbJ(gy!>FkWCR-BusZl!R}sSc08Yi&y4cm1mQ9wYbj>;+zo4_m6O#*Ed02d<~I#K z(V+S4*70A*$Xoq~Ezo^#iWgH{Mk6a`Z_K0$D8o$Cphisf(Z5@&=NNQu$NKW0S@q-% z{f|NoZ=mc~7Mw==pW(UV4_e>yWzm0X}rWu?@cD>=lDBi!UsuhkoQK zs8muPL_9>P#|6V->!yvBd~QFk@ zaK51bU2lOcVB48KmkF6O)hm_pW%VL?j{GWKDoU{|4P1vJ;_BU7q?+2+k4B$1|DgGk zhrD&^9@8!|EfOXkgqBQad$gRdD9ko9Tj!9V7nx-msyb2#A4Y_rdOaCAnB-7-A@&Y%#>lj5kN2(p0gEN%H>t)C)e z^l_jYPAtz}6%f2<G1w$O|6)=06A8k12I ztFK!3x7IS3gaW_Y9;U0dwK+6EbtgZL`@0mdXD6|AFoQHqRg5o_YWU7(_s-Qb*4ZoD5_Hfxxl7eeXUrmhGfqBxqiJA zF;q4q@d*}Du>*;oL9Qxc0h zH#uL3?QCULfPfbeOhK>M-_cpECUb41P2B~Uj>XQN)nd-B0c#jYc%+n!0R_7}A zw9|`+9!H#L`V;`LRhEQYO|X_s86qiZeVkZ$ftAXQ?xJiBEm2-^hNj17D#iq3k6)bd zyVzmAsi0Z4@5V8FPUVkCzNs!J6m7>;3W0p!muXR%afaZ8P^OLTY>`xnk!G~2 zb|%weUpy6WSZ;&lScGA2i*yd8c9&+x1C?*y*tZ*-a!pU7F)Ka3o?n&KA*d^w#%1sBI;x*y6$xJqX}rB`ZLhX#ibLS<2CQ((ca4|YOeDd=Ol6RH zdt0D67coRS-3*!agxNktDCWN*N%A{jgAM^9LBf{z~4zxDB%qh`k@MGwL_7o25Ml=|Qzkyb`yAZ~& zqgf@mtI7e=J-UV?8^~in6i`#m%fnvN)xCQqWq>$QRMyCmC7XW?3|E(_&p_(Qy###n znRBexi0$1b|6I5s2tyZ;)Ko5-@~*Y2G8=1pc~pG@+whWhxx?oVS!`u zO=eywC~i?ky@j}%Fw4ToTLyRD;$(yV$U?adalGQeh6V#t&XZFt0(PI7`TA!8*2d)r zsX0o2KrIRE^gR74Fsp-KVSFm4=cPOrJpynY{cd}U=TX^jNDjE^tUQdevnt_rz}r&Q z%<0d7%V5e-8gToP*m|Jq?UR5#ExUt=nrwfF^}fN%VJ}NoP)rH-5z39&chXECWsAD<;BhmL$kd8RJ zBs;LmWDMKTH7}#(zei9$O&?}T&ev5ux+b&Z_H1L!;+WKV@`0{C3szd^P0h2{_sF^f zai`#2JdLMLznDR8zi-H5H{u@c!#1#`4e!@{Hrqu~m72_4Ne^Zc^kG~jgIeLQKnU2BX+-}XNpMy%Pa~>$d7P#JJ8sRp zCgQ(CLAfPUJ^A+@Tf$WU z43#**|3;K(dXb}Ud*LuDrgFtJu4)XE|3CaMF#wZq06S<|R+xV$o)iF$i%>+VLUe7C zn7>rVUwzu6ClMlThO-k77PBndk~rRcA@c>6_7|#qB5Lk0{}FH%`P)ChWgZ4}4k42- zLrbqXHXA`lB60&kOU!@5$jWyHfAb*z4LN^f9LPN@wVBxxK7Qq+zm0mX6rdMMkv&uq zzSs0!Cb&%TV5{V`x7ZHmoT^@o#v+7{*vA-S*^W)v0}2BjUGRyUb(ODt|5_jF?x)th{d43rstbJQ(}5evoI6NI z_mf;-*wNvXYx0q=%2fZ0%#uf)I}K0eY5b1%I!$xfnJV8H>;81?MmC!YW7Ts(JUrn~ z*MNP*f_fQF#!En3(t{&@PM}WKNMjphSjFsE_wcL02e>QWfyE?6Cgl86AQ-TF3n`*%i@@g8iv>fm4e4N}{MK)r%x(yyjzIiX zfRVJE_U!{(ObJUp1+s%2&~X%9j3A8YhAZz?^aT4*D5Uy?mUu|&5)-5~_Jq4SJ|K4A zcrA-v&XWE=Hr-8#zXmYkZQ#Y^++ji@SXTWJEjbwRV3>&9eD9TSs|CV;>;CWuX0nz + diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/layout/Toolbar.xml b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/layout/Toolbar.xml new file mode 100644 index 00000000..aabd0a3b --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/layout/Toolbar.xml @@ -0,0 +1,9 @@ + + diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-anydpi-v26/icon.xml b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-anydpi-v26/icon.xml new file mode 100644 index 00000000..88d1d0a1 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-anydpi-v26/icon.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-anydpi-v26/icon_round.xml b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-anydpi-v26/icon_round.xml new file mode 100644 index 00000000..88d1d0a1 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-anydpi-v26/icon_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-hdpi/icon.png b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-hdpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4623ca2c42f2a8574089377b0419413605ae977e GIT binary patch literal 4754 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

IB1M9 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 literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-mdpi/icon.png b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/mipmap-mdpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9b1d25e25de64c1ee12f91c9b41f85b0e84664e3 GIT binary patch literal 2807 zcmVV%+Ahsfn`@<87OU$M|p)R8nh*~mfD9x3|b9X zVyqe|v6VJPOicq@OC(q@n0D0&wvk#;wAN}-Y_vs;ZLwjyZ7C42<+aSd*w@U?>(0!* ze!p|?cjnAxc6P`9;~)LVo%7xA`TM?e?z!hKLcCA!ci=sBz^Kx@TKg))D|1J2qcGI~ zlD4-UY@a_qQum91VO-}3JB;|8&1S}z)FBJUr{i0UhA^_WW3&w<6JI;LV#!I*olShv zN^i$nfV5kFpndj)`p7>zQ&w{_Z!6#k>1YU%SzaCl9Z9)j;9nOs#nifRY%r1h#4Dd& z@(yG~x~nVk{hGe}O1DNsedH(S64~Zq0m#jnJDQ71 zKb8Vyu+Kc-wxTPYTW)!s_Jc%3&dMWaVcU_q&vtn#y)&J^b@?BUe%h1yL$RqE$5Mc3 zX=yP;U1Vz_S5S`3_`44|12%l=X{`&${Br3-PUsDCIFZO!nUj-L7)L8WLU`kbJ2&)Z za`PFO9?$U5_^?Va0K`7B`*bH|EYt$&MRljM3twKk>RwOn53P9#QKU?>D(0DFgVF` zMonI-ckLkqC@de%1tAobllP>p=Bq#S!4@(a5j+Bnq?Gboo_XyWW5N}0(ZgE@V?X)3 z54{9TKNt~&3xE!!gM|)MDnq$0O^Jk3p?GTH;V&*d>xo$9-Hx(^>Kn)H=<$JP(6((0 zyHF4Xx-iNMGVg81;8iAK02Ka?^vjcvdvQ!a2SV;@cPdv`+gSgoCep)6o^5r7l-=>? zwi^?{@JmD4{AD­tF!X^xmau1*w)$C_XL;&E{@RUn?0ix-jm$>5s;LL9txp$G>| zVVVX#goc>=>``F`f*yP-l6{G32nU@Bwsqs7l^^*Ri*>LgJp)E4a>b)Mc-c9050@9= z-#tSjL?CK|0Rj{d-}NTZc6y!mC?%0B9ba;KenHBy&{#drhhe zCY%Awg+>e|?Xhg}^r;wBiZ;xjMzcWAf`hXX{5=&h_fYpSQ%ncX^@ukUmWs*9*oR$H zbj-*FY90YL_T^D80RG0zWeXpom(~n6;E{vzy&P!??0)Bx7`Adsylh&NxNbZhQauMW z7fqO2V~8)zjw(BwWIIoE3d0P@B?N^(2NwigcP4k$l#kDQkXVTmG7uLaZExED(&Usd z@3UwpK`{M-vHu>i2I-~q#L0_LE4oiU3+|4DZaOp@_spIwpBFaz!@FJLKPjAk5VZ(i z@4lXo&f6mC822yT`?pD642hWwfXt|$IB8pNI@92W^vr1BKt%~ad3S~>etD)(^ry2* zeM1zpP$NCvwI2|lpH*D@7A>)zC%Pyj?Lpr9hqH=FJa?Z*=zG&v!??yNTQ#+u0cmr~ zbFVFqJ7NtrR1$+`oUYVO!il7g03;n#{OmYAj2f+*+f2^_o&j5Yb!L;mj>Gip)14wl z&kv*Y=YUUOP7PY`7+BPHKyOha?*wK@#0ia8Odm1bOhgz`j{Gf;p zrKl@Umy?02-zcO#S zXbKwip5P2hr5L?YO6W1z6mp57ms!p;;G{2{*B+@ zgyV``Cptu)mX%5S{Nu-q+bovTH|I4jqXITdZGD?0#=5D}HlfkTPJo7~;j=q&Rk|I168zGfhOpru3CD z5C_aCgg1O)sQ*_TE$iFKw6p*c6yiq?J?vytgXMq&wEI>q&4O+6?rWMvV=eZ5m(cwz z?GJd6QW@%CC-QWNtj7}ysm~T7$2&r)ZQw4DGPWSHZ9r;V$kK?=! zLTo+0&bxX?Gz1Ls_4&o_4`eL4rQ#XmMqrzLp=Vf}8c4{v_*pfxSvjEw*=SNG9-zrEM#u-kWz4&A+);`uaGDzYASl|q{9~v(7^=xr+rQ4q}AUE)s z`Y9n(tesOlpbh8pV$a!rda=3ar5)Q-MSto{i1YE3OpKq~ubM0tkE5kGO1FT;xzx2q z5H>Fy+$AI~fCUiRXC7F+w=f((!s}C7vIi`Quzs3 z&wU5Kjf-gcRVV-$>_q(4j_=&HkMeN$8IpPvGX{)MT29xyn`{ebz*0gk_j1Jb%@dUp z`}!U_)Dcp5hDZZn*fL>9`W?L+hO9h`#Ik53@tTp+xQqh~-RB>oJ1mLI47o|V8)Ud@ zuHJRv>0ndy=M3tc4g|*N3_c%qLWjBgEN4H?EN2y;oos+n`zFxEa@*|feCFc%m1{}P z1(dq#4jK=mT&Df#COex>7D2ea*j?oIh_5T{lFP&k4Oqc*3Wd|qu_kI0^{@4%gTuuq~#Jp74369EHH>`qpD3{$I+lJhug;Sj_ z6Q6ZvG#U-p{9w_ae4pSul@DiSLyj~9h|dmo zEEco!ofkJdRt9oKFkmA;uZ*f>>@4Nziftx0>^c>}BQ$pz{73{FT;VHs{pDG+q3JgF z&wxd9fQJDWQ`A()$@9)Y-(NevamOn1MECW+lnqvC26P7m%4LtWZM5TqF&nRTZ>wR@ zJnBwk<>fntVj{NncH2heqH9bc$1(%J!Ltx-+VK6wwbw4$X@r6wrY*G=%J)ii=*~E~ zd|T$^(fj*;yy*>!hgUTU7`2FM3II;nMNk}o(yeg|!QI^A?*2vB zsXp7T)Adz%q?(HCXEYKt7#Nt(@^aD||53;P777v!4D6$sjp2V9SPu%ix&FQ&j-6t}*$N@#-SJ z4T7w+z`v=Fql~NL;D4d*O(C2 z7^NiqFHy!#H1Fs4^K`rz08lDh6lG_uC2FRSqK0-=f2YdyT^#y zu~3dJVE1YFvl$y3+d|9{YW<;7q27-cPq8D~^&V7U3A=-(i2HJI(_-OAux) z^gB=xb||S;!~|IeDGQ$?1J7f^m8(&e82^%Nq$VYg@`PH1KHx-tT~r%GS6N%3Kp_mC zkdO4|U8sy&T%lS?SN|zfTu9W7i0mt{yU&y+lTICs#lUhls1|BQdlD(ht*}&3n;`yl zqpYtQ1iQ&nfXKOZzl!`sC;FRKdD3N;gGH}2}1lEfKDb}8%B z`AR#~F?!#j8*7xWjwg?8Dccm2()_p8-GvyTk=_(s;t>TllT)<>O#k!?{p+QF=NRWt zq-ZV-Xo@*~bu!5ZiEThy25_LI@&K_DudEKsGC}ucQy-!I0!b!j`&eGG1sh_Hy1WX_ zvKDbsk1e4#v;u?iv{5wSM4An|GbOP$@gl1OKck%Q4olU{e;aoW@qo(BSIM42^95+y z>IH3eNq9b|nuBP$3)g}BK~QQ;=`N%C*zq^?2O=ZEM-9C)qwQ|=e>5hwYVuK>iiqX9 zjJ#M@&gI$+zQaLf7%Mi7UU0lJP(RK4hj3Q=1Aj!_fOoM_(H(gg&_9odxWO;VI&9bX zn$i>HsTYw%bDlcVg7DO==m5bFX7P&glAmk8e=P?AiAP`eKLS_1g z$`%hE6g7sUQb#74QMbbtE51{+OyzNQoqIA-sV!o+Kp2?}Q;@<{bO+q~-;sapQ?wnE z3Mmr_C&h|#)t7MshYB4hokGB+W};=_TZ)?)2J3-IVywKwBI*R%&l&Z1EBXE%AN=|S zxEe@jiFv`Y-HL5d$;nB>Y$QLXuvy@&$d7L00K9^+W1RC$li08g*f;kFp6{=YLne4c z5x?!JUHh0tck!i|166dJB7SYSPk_KmZ0eH{4NF2tdvT zDNp>KY=LdQS3_pH@#MvF$Uk)f2V)J5J(AW7OXj?2m=&r_UDwBMuNhu*$tAn%=RS`; zEV17Owe%+R7KC}V2{K$z`xHE-vW0^-RcLqf$2WdHBXX|TwYuQoU>yqqauIeM9K&L2 z7T4J}OCr9kX~u?=Rm> zUvOT(Jm#sY#GB{Tr*0AU%3S|T5DAF&NegQeTls#bCITZDJ%s!pmCULFkrar7jK3HT z(MNWS$;d}BBWJFh+J2xQh$O_dz|WS)=J)OUOP7!A>-46NcJF0lj2dMjHFx4LmbU)R zX6ydNysA=n9u~gmXrMu=y0z5H*OW=#Eh)0(tgJN_2??l!larGobX!$bcOPL62`0xg zE6&3+!@mvI2qSVIb_71|e^T~822~d_$7v?A^qdFgkL!{6u`4VH<)AAC^Rgm;GK0C8 z7^nTr01nD0WNJ){e(Z&C+G6k`!{`njKZ@0Fk4oW0w*recHL-az5~%#+ zg4q zFl6sAY;$x$Cvw$+@%Ch-Bqa+o_7LYA?&cNUQtjyM9)C2DoK?7Arrx(I3F|c?`%KU( zYv7Qt+gZQ;#y%knS#DI~?iV()x?sc_rzW;6N$kvzcA@>FE_cr9aio71h6)AN2MvM8$>ZYEM9#H)u{& z(kS)TGZp@BG;ryN->uZk2Re)@DoK_dzF?(Yn^*Y6_OQh@V0TP zF0vqH>W;O1zt(Ea&~(Q}4Y2^_?0Kd|%*s45bm z20sb^Z*_fxsn}0Fk_4JdPy_QX<9omWYhDkZu3JfwpFaX{X{X#@nHljInU9tPM^DE>Ifu) zqBy;LasMvniLF+CdsB}B%wf)*{svdAN;Vy^Kh1Pmbb#E*iwE^^LOqH9G+k_Z#ufFf z?cMaMH_-4KU6f_=E}Z-VL^(%rR-o|4ir7HXq@`O#GTn-d@4Fy7J6w!Gcl_^#?Bn;A zYptL`c480qS(1yxh%vOA&<@RbRbmBzkxBLzCsQVu#qd)VLASWFGZK~zJwXE-`MM(i zwX{!aIZbg1?lI);IF2lmQi(G1Mr8Re#AUbwnz6;o6JPz|=2 zWf?=fQ3pDeNAJ)|y**y<*Ouk^R$df_1BK62O3g;%tYX3%;?=3&Q@I z5q~3Ja>*wnIfzK@puRUZO|Ns#Cg%+p)6Jk?(zKh%)3{QGr~=eCto=jnjF{0XGLFf!ssETuX&Sblrva zt%v@Man4xy_!+MxZ!0>K%3SsXO1ory{^Kdk?`8uKd|Q3Ltw_tsF!W%h+#dsn;vbDb zHU6VdkX8Q7K}#ZlavV<+vPQY$(&M(@p|->YbANVXVG%V_5U{F-AXSlYLv@uKFQ`*5 z;<<7Z%}z9Md5==qvz(EKr;(O@zccIf;Ad@+;xiS_8Ln!E-M2T`o>Exu-p}w)1%9Ly zz2;M{ZNL0!cdtO4&eU9Y6nhTBfo95#n~CTDpRxXD`~MfZ{*Ol1HhlUmK(ISv1Y)d5 z5^jZQ8{I({nl4pdp)de8uS(B9ON7%RH%h~A5$^n6ifS||0K-PNbeqIpR)_fMLYKTk zINE97w8HAIs}Zs|{)o>JDx+?V0}9mWcfZn9u1Qj$dR^VU47q+?r?`zwr45CO&{rdw z$|Gu7#99lo8;{I0;&?3z%K`dpa)D6Nm4gamw%1)wFQl`B1|{Hzk8SU)!F0pM>DtmC zf7mCR&I~N(u|zi4HbuKU7&IQK4?u|$_t8msxpA@kR=ec#*b+xqG zC=?}b+`QVoNz(QzL$y*Qxe0=hH!(>-h%6$;bNkZ03--C{7CAM;u8^6>z1_96NY^EJP$LiA)jBkeSznAaP6iw&MEZxL3_+fl7 zQ1AK^Y?D6ZBS;7X;5|8i%}J?1uXQRlc$DWZ8Kj#$Gg6xO5c}v$ZF3 z%7@j@*ntPNcwD@fw6iCS)_?2xxw%xqqu|7|X>s$E;n)x))CHT`M#|D7!3Ra{`CjcL z`;-_3SZPT4dmPeeZYMtd|eMG=IM&#K0 z3$vz|kU2*yk;QKcHNHg@$tcZiKBoNV|D*B z$VB`pezKa?*Y#d>VFCZ-&eJ3DB16(iAbM|jq9$|-=LZS9^G&Ds!dEurGw4aS@p~E} zNXY8X5IfKYRT+td=$kBgw{=zfb;i55s{HHT@Fju7)i~>~QETFjDG!;KEWA;(#~?>o z|Gs@6uI+9_Loq$M@w#uP18y*T$9|(A++Vo4hP%4Kuwl0Xc#O`YSlYLK1nGk4{Ozqs zvDKIm5bl15(eIKyC9CE(pKqn;b>|9NxH=Nl+Fe7TG4yG7^e|h|ztf|t%Sn5G_3I8DHEpl7oFEV>`mAE7u)v?EJ^wf*IGh1#C*(Tv z>>)ZS(2ij9@?G$NgsYvEpO1$MS}CKXmrrdUb{!7)sDZLs$x-^p%Y7VNlAFA*2tV}H z?JX*JO@=>^Sbh+jB*5-~r*9TEgOaSuXZ<7F$D&lXn&s|kqteP2#@X!Xg0X1+>&SOk zZVnLYtu7hA3Ne*%Q!kGty#2|SG9`mn;KAbK;3YB$d*08ePaCe-^?dEENG8*^U@mEb zI5{Lb#~?UG=_M3gQ`73(Kimm%(vfDyi_Lb53vAx#06Dy#NAU~c|4=rem`x^L_{xQ` zXdg%vpCXI!ukC>T>_?)Eq(gQnbj%(`{B>J009K~kCUprsq=#ln?_WWfgU^jTroC2j zsyicTZdltqqTTWlC)swim%RW2C`V$V5}c+}OyPdH5K?LQ?7M?CL&1!?fPFbuwtO9o*XGK*DO@32*u{b z2B)v$T#xnV6amt_mnu+&|9*{&4&@q{SvDB`;xXj*OHs-2h4#9hVa?cX?#^7!;n|N1 zO{FF5t}X$obR}~vJNa($MBiIfj_viaGH9bdadA_JhF=J~eG9xF+s0wsVY|4v_&y%X z3gu9eE6k-8iNng9>FF0gK$VdW(t?%!?1KA6{HKIUZU5yx1z~`o5uJd1ztyh@uj;2G z%N}sSpHza?ZZYA=T%VymOTJo@VcY$QFMGp2(bQ5%>rvo`i|;&_KuW(vxhwTIfRi4! zq%yf@GN#$-REA%tyN3rNzxP_3o5gtTgrCYaX8vmsE4BKTil83Ipp1&mMx$)ten*Hl%QjAXoDZ83oy=*dG!oYokm=)sUz*CSk7w0BS{iri|WIc+zgb^4?JNzD|unYFog^ zyNXq#iQ(>vD?l}GxmfbvPJCj-nqH&~6YFA%n3@3}(`6iQUBSLWF*GaqYel+lOcSY{ z<-3)Xgad0!k^L_sB|r19b=L@xd(?|b0oB7*rp;xZ!n({ME(K{R?^AWcod=0My#*;3 z{kIT_q{+ZUu>Z^bMPAq^LWYa2?oQ*rZ(m-=JV5b=w0E9LfJdD0(rc!@6!;jbFnAdr zvGjpi$bebsvkHZN_RH%VPeo5C20~RK?wBi$#W3GfNl0F6ALk37Y*}PPUQ!ZHL3&!V z)fs_Hx#PBwO4B9hhSgTc3XNBTLCZhupTbFMBcgJPqBnqKbFCNd`&Vl3-vb|V-+y|} zxc2b&Np*g)Ms~XbV%h3QhA53FXM(QFm+atkzmCL_JJ_z%I-L=^bnCd!lk4YkX>Q$_ zO7H==|6HUCC5+AjnCCgOg-2SJxu(K2UX>?KU35g%A9r2Sao8CMMR8-a55lxe>hf~E zCHtf43koC&k!#}mrX@bUzqUB7C#g0;txcozCA#}l=M==_bY(IBXj>nwqTmPAU;G>! zdP<7l>Z);{w`Uu+yB`CT+&9)Fo|59bAbn0ZyJx@kFcH0(zFr2Q9%Vl5~IkX@F7c3gUF}>1R;Q+NLXW*CLuu5r1wrb>HY0<{#*4|pLe_J z_3Q4};5XAZU%hkhxo5loxm9)RR;7&@FXIS|BQTD@I0EAcj3Y3Pz&HZq2#h1}{|$lI z8#Lh9*?)TZLuJNX5R03mOwP>C<+5@3&V>Y!bC^yuPa_v%!PVCat}V7>v3OR%Xi8_Z z8?&*p>(`#PaBW0*+T5t?W1WE5$-jMazq$L*_*H*4`~E%2jOov0O)47(n>Uu6gB}4w zFY5>zb%@5Kp;agYc@*tQ%Xz&6ztF3Q$4q5e+|*W-o9eQ%`*wG=o%81ppVDp342YJr zHkJv9Em^ZBZe|_x*QUPIah<7*4crAtj|Sk!1W_gdvILuQT3;uCe9CL!sS6sF1nN_E za(S7VU0we4q}`iNzI*A?EL7Q7N@_0yr8KB*rE8B`zNRCLH|JB?^4V$_NvD48-ks&w{7~xO%XQ0{NL$6@8gK?Z-U*iBq?OWjjjvGZtq6u!v2a zF@0rwe?Is_Wt*2Ej!(;Djwd{ziP&j843d95D?BxETA;E@C-0zRNaV9|C< zo-bb(^5D0ovL878-u0)uI;CirIsw2SUS2urn$Bbzbz3k9JwTs5h!Ffi9S(!D*#$Jp zhXpdK)3F`a+?Pzn$|g?2y#ROx;|h}ZI-ryf z!_A$|^pUUcSzxll&Kk;x>iYrUEW#Ppnn=I>%(X9mhB~F9rA$CzN-0p1%ArSy~4^SQr;6`1*|D<*X-@F^LJ~-@+J0#7_^c zjGUG<0mq&4&i`)jPt9XE7?d6u`7U*rpM&~chP2%oUC56s>zW%1P2S8~`&09eI^o1` z!o6!_r0r5AAoi|bJUFjUwi*)tofm)%6(wgqDF)%{p{>E?Ot!Ps_mS5x(ge)flTPZO ztqb%JW1hY=bi(x6l$5b`$Kqc&;m-T#`l{O8i0Y+C0LBoTI&{i#wpY1;f4$qttQRkmr^9aocZe~ z{;@M%c9yr<;01xmG>~p+nDu(w0sXE#+QA_e0Et5bgns(s4HLFdAjiYw4F1j2_kB=` zv)`iwe)eW!OHcjfW5-f%G<38Hz}REeQ)^f3Nv348bD&^gBPj!5dIP2n&SDKd`=WeN zhjLLgQeRDQ#DxOc-N|%W<+K^grE13y{z%Jc6JY-3f#*Nomdc#OL68;-h}ZmpiZJy+ zIaqB&&*U&!UUmXXA#KE|YhSRh&o0`b3S_l>OEUG&cdvc+EcTC-jwS)IW6wLUJX108 zitcoF#8ZKT(x8KfLW+9WY=#bH@~+jw)L=qCtmNsd002Jh=_Ih5{<>t$refmvfPvU% zcbJ=kyip}!?%7}ZitLpff}nU5@`f4DYd_?mLl8JHQavI)`=RIRfCsP$7?VYc{;)z{ z=+i!U(C{V&SxpUU-S{bhuh%$ofbV5LTE2f>7P+!6IiLv*^;+Fyo5plbVabx#3iV{>pa1=ZA!1-6T zB~mp6MD-7<5^znk*{sRQ(`81Etbd@5xf7Y6%-6b&fiUB0aZsi;kvV$zzhCy*z*rHLViORXwe0qZsj`Z1^l`V-p9U`Y@M#C{ zJ7<6l(y}pvc-&mKwaH|BJHB`xIkI+&IeXreJbMt(GgJeTr!0+y6U)tq51!?+gEoAx z+|p=ozMM2X0~jyj*9D=&C;LeugZCivKIB`#N}8^!HWSo~PQdYRd)s%~5}7&FWWZ>n z?j{1>5u6SXvMh1Y+0mCV_q@_fRw%t_@d0MPn71s|0(zE$uk&apfUJBjI%2MYpQy6t zF1q)@lD(iR@0%d2a7}1~%n8=yMlPk=b z2h12?IW_qF$+i|T;6dPBcm@)I_=ZA|V}WVN;=sdMXRhqRV{iZCe4iyGx(t;7Yqxgx z>}9goKZ!t-(yR^yJhvSshnd%s%9^{jHc}*%o_qLwb6{oMWc?(B3i(VsF$9E5WEEAY ztQMcmNj&Un(7nhbKWp~Y;-7hm3}vVUnA3mtr+4g4nU7_8?)j$Z3>02K z$@4`5UTB{%?d+8q__J5rO;0LKwLug&(XTC*2_=^mIzc#5v;V|tRp#Wm;m;W`4qrEH zmj!^o^10WxE=7x#c zU#RFYx^j3=lABOHIo%LzY5#8iw|D=^>rUHppbek_+ibD zQ<}^Px>z5O%C9x`r4Kpd(;tm|XAqWv*x|Q5JgqktyEtsGU&Rx63JZe3a|V$HN=^kc zvR`(`uisqwEZDztg1P9e@^B>%m;}&rf$ob#%>Ey5dfg<&2WP(%LLT^xU(0ZuVHjvR zT?dA}CjJ#*DtwviD%i_LJw1 zf&4HEEcaz&|8e|n4jc1NY;w)CFYHdHD&PIUU+U72^t)t7=3@7iHQ)AvcW1_5xGUi;lG0&caozw8Lbx)W1ZDXf&4xarS zCpGn0z;nk=9{6E>=npIHiBv`Pw5gw$J`B_!toOOKmXFKz>I@ntr2xQ2ac4JY4f-f! z>yQOcQSjXooB`5-8HzVyD>oIs7r@44vMjBQ=gfZ{S$OuZkTVKzy9S1xAAvhgCIM26 zUuy*DY32}h_~3qSZsx%uVaD%>s!STWz^M+l5_d;DGT<8 zaPtasn3oOdh$qwD-Z*DDf+D~$=(foN)rB5(uo`gIp`+{Y703R)9QVB1s!fL0?HLo= z<1yE~(jv3pyY_1_9hc^_j`$&?<=E!fC|fK|rR{c09_D!sF%(bt^)_)Pz_3mP9oc@r zp#ubqL2AAR*pnIPg)LpswokgU@AHX;!S1&f3F=rao%7h1f=|%r9yUidQsrw4wUOtz z4D9I&WB_y+*v05;TdZgMda>)6hk0JZ3hrtCGuPK>y8v09{J4P?3Q9k5y2*e&lzcxq zbJpA`=I{a!RnWQWZ}n!6Jk{PPE1alugxEN1?*92xS%e40?+gI_V37^#>IkdoVlmy_ z^rWlcCLp`_iAU}*iN2I}>;?iOVLXrTX%c8q)@{FU7=ROWQm;Q}szl>U@*<{Cd8%oT zd9bD1-dyjf?=a0h(NEA9AANwS^k3@u?!EX`EcB)OZ9MWr9%V*E`}{SBY0_@K!ds z2jJ-zPq|SAOVrOEJY6nDQ6tFL)KVDxP~*?n9^3+!$=A2v)Bfw5H%o710^k>@_qVRO z`C8N0y_bQIYSRQ6l$RLRDTg*e2L*#;yyw;xqKnfM7zdCJIs>FL)%(oj zJNmc3bZgFE5eY9S0M#v;r|Xd8OfLjH5c_qa%f5_JH>)GKwj08=rEC1$}h0O(?^)Ze`Pn>XY- zJ6;E%`X6Vz$XGtt@M!D8nFY#2_lMOFtu8az=P6Wvw5dLLnL;0sN8osZu9K(UsIpX6 zRfo!#64VQ*uMa&=FVZMm#qzWJI_jH$`0blS9AfT&&`5?Z?yE}l1p~_$)oOWlJNsqXdD-Fx2KziwWqU`rxzpcHrVQhWTl9}TA#N737f!5pDk$XOAFeRDS#u@0}A^mPOUVj&5M4I3*jp_)CU`CXajtnk*Fi^ zb?v?8`PS$s=yxxeZceHh_~H)0Lr)*kQ$PfZEErRIcgu4vD=xoRQ~>^<*$-200>EP| zQ0nad>%-UN5(&E`BG?epB@ApPLd%8K5ok=V{a-)kfUxd>x9;_J^Th7(Ermb`fykM# zY>0iN%f(krodwj#z;!~%9|_GR`ZKBZ>#h-9>;eKy;+khJECCRJFhEbV+`8(CWW&w} zyqj14jJJX!SuEI)XMqD0B;Z4HCL4SO7gg{Vw!XJkoXMK2CB)&c(4|@6ELU`aq!`cZ~EsBfJ;ZqGe?r*#8M|ki`$dR}5(MAd-0M{$r zwR?8|?#|_=ucrr!BLN$FZm}~>jA1YT68UbwQ2DvME9Mt$kmLP`I!FZ%ToZG0T#FBG z3zVWC;y{l zq=nw~An_kHK6Oy7nNwgdzr8nMu6wz~f(qYy_Iqt_#_Cy%JHy7VqqfP5-JQ)%KfU@#(%&aX=#5wF7D@o+>{*bk-`?E&(#9LZ9?mGJgLmt? z4SCGGFUrgH{R%vEZED|V*5Ey^WKV-nTcn(|z?uhqY?r6ydtZ&7Gw^-U5whc|c1oc) z(vnN1OrmbX^+vD~8$-^1_!%kz7$Xj3GST?`FWsK)XseTYULg>g$r-QvI2keH4w8qi ze;wkX>q^=0!A$0!KW))A{gIEhT?mPQ)e+s5au(nw9##HLVmP=O4`y*$@4p5&#)Q#vAh9?iZd~o=Nlvr>Yw^+B~2fRxtZ7lLw-5ym*NyYhPu%h%1CjmSQ zx;q}eS02uK6Br;0sjd4B0^$K~#eyHq%;)7@ZCJrz@ZVG$W#&T8f*2+!Jne%bj0F@4 zgN=6i_;=-o9U{+ON_+G<8w;dISOkmib-!IE+W0HGMbCbC8;)1VB4Ky~K6Sy>w=J(c zbkRAnGWox?GA_(+6g@`pblZ~vPZZ?F7X=8OW)T?^0MlX6h1#YQq15yI$!$FHW-F2* z?~RqI$SU^wQ!j72tLgGjT`EGj{NN10WDN^h*!cx-=toj=>E_05`yGGk5>ruCt$}7D zXcVg#?$-nlP(Vfm?aOiu+&?S`J`e;yuoIDF_Jd-?Fs+M40YQcMqu;QX_S#0Fx-2_8 zI&Qk^^QqPbz49pveAq4a5~O3W%hKLW>vtwz*>X!RlggXr?yMx}qdGloX3be~_e15iGY{fS zrvtVN0S=I1%mte^Knnq0NWV~@wm+JBroHvGU6(FB({y&?ksA+Qn4E=%GsxXY&Hxy} zHBR0cbnZ!Pes)zZm9Uo?S|{kFT`c5^bxm|4XW|{`c-@9~v+>LV`=mlZS0MU?G^K;ImH3gs@HBQd2y|ryFT06-8(362hkfP)9n3jxnWYJFYTJ~e+V>Ny!>_wR4R zCniJg^%vuRGzp-6yDaT`{K0LB`j_vJKSgEv1Ro6xkk264q%@)_bqPG%l(F{McmpZ+ z`ZGIUz5`#c&_d=Y{os#vvCGc3=8X;KfAB-%i_6YoKXiq~S*kMt*zktDum8Enug#`{&C)@BAxtne z4Xa08js_VWLxwzP=29>G34e9~TezJ440lwXOO*fwfq?8ggVvj_UYBZad_?bdqLW}k zSl7`G8x442e8|611!G7z?Ro@b5}&y77QNSBOpK*Y0MCN%ob+Ui-gtLz zU5&9w41DM+X*eT&A5c^f$!8wjQ1y=Yo)W95nr+IRK8y{=?;n%;MZEfBq-Tbt?{yQgPSha{CLkh;@!@nq8Y0M zz%OjecW3q;a<$MYa!i&3fASdozsG_V4zBh1Umn=$1n~MBA8D4hjCBGKEiQBTgGG3m zj{|MY{;~8e=7(KyZO1Ck?rjOhH6Lq!Z*yy4tstz@m9Yka_5nB!4Le#a3QM_?R*aRmMkBk;cl;@2^Y SHSs+F0000i@UqKyKMfI+WmKH-}Yf2 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 P@D>J7S3j3^P6 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 |g84p7#db3$Hn3iwQ|;AP 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/XFAC|otxVq4mdH0gtTc)G)?7Zf7)_f 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 literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/values/colors.xml b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/values/colors.xml new file mode 100644 index 00000000..d9f6e0ba --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/values/colors.xml @@ -0,0 +1,7 @@ + + + #FFFFFF + #3F51B5 + #303F9F + #FF4081 + diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/values/styles.xml b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/values/styles.xml new file mode 100644 index 00000000..4b9805f3 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/Resources/values/styles.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.Android/xamarinFormApp.Android.csproj b/Examples/xamarinFormApp/xamarinFormApp.Android/xamarinFormApp.Android.csproj new file mode 100644 index 00000000..7d9c3215 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.Android/xamarinFormApp.Android.csproj @@ -0,0 +1,115 @@ + + + + Debug + AnyCPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE} + {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {6968b3a4-1835-46a3-ac5c-1ae33b475983} + Library + xamarinFormApp.Droid + xamarinFormApp.Android + True + True + Resources\Resource.designer.cs + Resource + Properties\AndroidManifest.xml + Resources + Assets + false + v9.0 + true + true + Xamarin.Android.Net.AndroidClientHandler + + + + + true + portable + false + bin\Debug + DEBUG; + prompt + 4 + None + false + false + false + false + CJK;West + + + true + portable + true + bin\Release + prompt + 4 + true + false + false + false + false + false + CJK;West + armeabi-v7a;x86;x86_64;arm64-v8a + None + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {19768622-95F4-4D1B-AAF4-090274F22EB5} + xamarinFormApp + + + + + + + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/AppDelegate.cs b/Examples/xamarinFormApp/xamarinFormApp.iOS/AppDelegate.cs new file mode 100644 index 00000000..bb46f05d --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.iOS/AppDelegate.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Foundation; +using UIKit; + +namespace xamarinFormApp.iOS +{ + // The UIApplicationDelegate for the application. This class is responsible for launching the + // User Interface of the application, as well as listening (and optionally responding) to + // application events from iOS. + [Register("AppDelegate")] + public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate + { + // + // This method is invoked when the application has loaded and is ready to run. In this + // method you should instantiate the window, load the UI into it and then make the window + // visible. + // + // You have 17 seconds to return from this method, or iOS will terminate your application. + // + public override bool FinishedLaunching(UIApplication app, NSDictionary options) + { + global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental"); + global::Xamarin.Forms.Forms.Init(); + LoadApplication(new App()); + + return base.FinishedLaunching(app, options); + } + } +} diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..98f4d035 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,117 @@ +{ + "images": [ + { + "scale": "2x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon40.png" + }, + { + "scale": "3x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon60.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon58.png" + }, + { + "scale": "3x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon87.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon80.png" + }, + { + "scale": "3x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "2x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "3x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon180.png" + }, + { + "scale": "1x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon20.png" + }, + { + "scale": "2x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "1x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon29.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon58.png" + }, + { + "scale": "1x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon80.png" + }, + { + "scale": "1x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon76.png" + }, + { + "scale": "2x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon152.png" + }, + { + "scale": "2x", + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "Icon167.png" + }, + { + "scale": "1x", + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "Icon1024.png" + } + ], + "properties": {}, + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png new file mode 100644 index 0000000000000000000000000000000000000000..9174c989a9c8b8a5ca133228f4ed7c173fffd2ee GIT binary patch literal 70429 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 z zCn)b8&=oMu6ygwwJfdasJX|@L6?m1Dv0X9t>JAWO^UIj0#&(3UrHx;vP^3g= zL{(XT!?`D*pP8)WoGHYEZZc$!odTzb8n)q0|88*>6P z`?6&CSv_W7r2yF0beQ2*?V^_%pKktVAo`)T^26X@NpK_*-ni{D7{Sp{C0A<|16l(; zOL*xGW|*sKsiwHvE!h3QXe@^a#6W3}8!DQu-h?A_4gkeRYkt4NC~GR5P8eyp;9kVQ8$QG$5ad7Fo23Z~ak1jY~RXG{v?3G$RarFe`XePu3X{R+=mBOw&X zks)|Sc$RcG-jhn!`~-x|vg!&DA&@}QH^RNdyy9nq56yrU$^qAaS+F_NOaeFb)CVaH z?!UvPajgrK&zqdAs>&Def#wkcG_UhmYOVw^M`VZz@+4IWAVzK%`+za9rm2SD9={u@ zlx5D6UDL;lc7#9`+%vnlP3PescU=N`DHQPt_N55GNBMkVCRMR4?fvp zAFsvcHN4c9rb>J@{*IH>RTr9de%9i4Gd(cbFa9SP4anhoP;TA0!oZyB8?lNMDHPHK zCaOaFU9?x2A!o>p>mCF9r+hKs9Czu_P1l$LWU%}q#)=T3p`ZnYyeHmsewqw`}L^4LuHqfo+CG6<2n7#l^3;H^^!1 zsaieYFnN)Kc7Mv}^xE)4kXUw8<9I+jMB@QV9T9I8haLDt1Ne#exWUfGYG$4uMoEu& zo81#2up18Y40h%tIsOZglp(ltVsE*j1~$lVd|;rN)&${~o~-%KZnJp&3|OFR{^8E9 zJ;fCu53Ysw%}@VYWE*z7r)&4P=^B-SF%a@>*9g84<4aFUZT7x)qdsS+#2tu5NbpU@ zg;EwV)l-#sK>#r9>(0Figx{9lKm>KvRj;y<8 zc8SxMW4<11(s@QMV_}n9MRzA*62->vzxmHh1)GVASEJY7LVtRw`Rv{v`(Fuc00(&o z%m>gS2aJekmdNQ4p<{pD3HqZ-%4hdU1__xYhLi9mTJXD|E zE`t6SX)}l_DY5vO0Xrs#O6_DKtPKn0f+e~SprDYmJL_`<053iA5P`zn z4<5etc%aF58sHFr#M;U-9|=;l)J#Q2vS!Q9(d(EX6fubL%uA_lqa2%!cpNIv78QZ}Ayo(>C(ZpsRtKhzD--fpuoCch87cX-Bna9_{z%$b*dHM0?+T&Hk!+^UM`r|vq z2Id$??bX^|tfYaE+h#Nik(ZcN+wt)28q^gWe!y8jDCXrD<2qV#49x@5$8&Zrd5NTs zNYcix;9fe#PQQ;T?!6hG>9K{K+RCPqiGc9z%t{=`QaX>7O{l(+#7mJ1>Rae^J?82e z6cLqLypskTCyu>uc~$0-XZ^1Qvhwr+pKQ#CKImhGu*MGM*ZrROuAHWuT*yM$ieEy8*KLFMMdLZL|D+yDmy@3_PELTEVMI6nwfcYA3ZQ9wwKdtkT z;`;z7fU{U6>CS7kr3=A-()_G*G(Mjf2wXKe

Fpy)y!S(AQHSG#udd_8#b4sQu!R zu5}IzX*$;Hxs1sgr9+QLeUpi2f*mS@gu1o7j$4a#3eTy87Cy1W(bOxj9-8ZRrIM4o z(cA}65RvU5I{R>voiE4hq?IR|Ex_{-*@Npqt( zIDp!L(vSJ6d4kt3bs?%QG|WN<_=G`~ybhL&9_Y*G$dd&gzIVx_>J;7D4C2nuwc4#) z5oJX$8=Md9e*Hi8-uf-dt_vH6aex6-NQT&YzDk9kkAV%_iab>#OS+YuEn$;$M;c(Sd)J0rIbX z{EH0#cbb8K`3uC+X#dwI2Izf^0iyroYQl1He~3Sp z9Fx@l`8(iZoPRI=N3{P+<9~JRUupa+jel|Df6(z?6#ZZK@vk)gl?IxW{OczE-*gi+ zb8qh85`ndqgV%nJ>guX{$n)M6qHnj_T$b`tR34FDa`$1_^U?ItSlFw7d=L5&1Cl^` zzpFQD=#B9D^F*$kw;n?UG)96ooiUh<(xCDxFm&rVoixfLVV1D$51WNGgTyb4hxoep zCkq#MwtDymBypp3DCNYLDZkdfjO{|In?8-NU#Mn=$kbsx4g1<{dG1OsOM z^S(GH0vscF2!TPh=BouYuW&YxI~I4S;wDeL#7504see`vK7baJIpAFjE;|jybj?Ma z4DlkjJ_ZDL!-{brXo3m*fPv-j&+x{K#^1jM!aVx;bWXQPf2BwTCGFF=BX2&$R%NH69*WD((3g^WLA>z!2{l#;#hj53RrdA*6k@ z>)frxQ$dTm%&tDoNad2N!Xf?80s~Br8`5}Z{yEctC?Atp>LVRH<6aCCqyi0$1~e4H z1Doqa98wsV*Pu7G$2)Q2?W1PQ=~EW$#YJ&Jl)^*uRFsW|nIg(BdB6zd*<{TqmuLPA zo^UGz!$FSD5FMyg8)gU+$Eg&1s~c*jpE%q4ZQk`@hQJb8BA>%7*oaVDkH6_MBYHGQ zZUcEsfdz{bOFRTmQ8<9w?k7Egoe+b7hez-{|L9yZ6$udpR!<-4Z7Dv-OBZ6tp0M!7 z+l{wR>yO)}z`Bp|NNx89(5?A!1i334oHD^iEAMQaS@h6+VJDnTUjhSjAB*@chR>?M zMa%hWT%f5I+-?O&DF{s3|2^auhVXYYZ5WMlDsileyDcV|8K&a&-!2A+Q*b$9T;oXj--c-MIcGjH`Q)ok9@te@%IVBB6 z+@-WYrOWHLw^o)XiG)?@fM9fij3T9<^M+wSj$qzRve6M>d8 z9##had3h00gQ*I|!Kvaz!2IffZ0b3>j(}V#FnvPc1^9d&my1ed+&Y>aN76hiO@%Eqs96VKz?GBY$o^^fpwH#q8W1)rgpdg1#+iCr0EF;rVtjf zw7>iF8Cn`THv+bpruM@+k~jHa%z*3Q&R72J`rx;f1GEXWJ8`t^Omh5$hE+zu?6bt3 zh~`%ebCC0+-+XLtG|2#~`N}MgN#iY$^#lDqVo~U3r-=3O1Jp4$&Tk4JO40#ojEfIN zLQsuZ(k_yRZ4);n55SWXrvOiG2(gd@#8Zdx0k+CjM{Snl*VKeLNbfI>0gVp95W$nu z>MMz?MR{OakSn3_=nV%L>nG~7E6{Ypfd1xsCDOZsKbFL3P#NTCbs&BEoR}~~PCvM# zQg<=iO-|qVkCN#TW?&3JZmQ6NC#d?kJSEF+zb>aRzEf-l9k#i#(`-dn zwj0K5mc-zx5ne}|QpdFtAQcQejZx`WUCxx*JjCYUEa%F5CiHKGi<=P9kjCvq?9fwF zPY!#0Ec;_fa$srE4^Ggk<^X-Iks6nzP%EE$Dxs|Wt>iLg^#o`N_<7*~DWdslTgVQ@ zh!S}3u<ENlKq+q-TSn`EL$8o-Xx?;mt>y*II$^sY?%|IpsMJKM2n@|(e zUP?K$u<1dJR%s=m(zfKxhEPHa)%glroTVwsW5*W15P4xVIzqL@$uJL|%rQAgIi?8< zSvM~&uVB}GslE#pNM=jTi<_FDso4 z-@4rIQCatChJo82=z`liCm4C5gim$n!Qr>%w_OhvFV#sG-=go@#Y&+Q2S*9;&BLR< z~}{!Wy}U z8_`F+?$^*Z^by#QI*%L`FzZ@zQze51UO&x>cbb=nR##w`9QA;QIfO_P={R9`2Rp(rfLDMQ(B{q(EVQo7`mcTJf(*G=@5L}P&(>C;=_BoOWV_6t*|bbun_f>NP>k-{^n=vBY1a^Y>kwf@=K*Dmg7TX2CEpC{RlA$f_q( zpl-r8;B0Is%E(Tv=cS)z_a642Pyjv9nkr4Dlil0u-u`PiXhoI;Ya+5_fI$fdAZ{g- zO!x$8FOe#4Xq_VL(4ldZ6K7|#Wu)si3yYa$w0$_sM2Y_DoHPSt-VOVw7zFl;olx^y zwZI0ipMIfL(z$tYC-xtWq(X!94&ej8uBS;FS{uSYw80!`VgWixCh<}L7ZNV6X&{v= zTqnUw?`XHbnz4Hu3@MIy9MDE5&dz#_h84=m;Tqd2TJ)c-fr1!@REYspQ8Jbt)lF)6 zRRn4mSC$@4Z}iuM{kaHCtPhvrBgU#7iTiklozu?pwF=-sp^`wHG_jUhgD{%%1%zXR z$>>z^fr|E@HSS8ydlS*H4tGy>nv91Xy@LOSf@wIY1Fa$};7+I*hx z>;&@)p??q{n+uV+*nurX_SR}=RaKjUpn4&zk+@MQh%fxj9-ht$}7%YlR;J{<8|HEBndHrI7}l zR)eq*+Hwf%pV6p7pSgWz0VUzTdboM&t53cr?AoKH>Hwq)Ng$>O!hn$BjYymD`0U9{ zxaOvHUcKc%rv&$kBlysd!=B_Mx$}vsUKwX=&D*>5KxqnK&oG`!2af}tw}-?%b`737 z*Ze`Dg&Hrq*#9FRahm&(Flh|eWQ3ROVQiDkA+G$e1rC4~hbRCoAx}>*f#OLU4_6HH z?4bAjf@yd0La_6g`G%73r=34S0>i=-SuJ2_A+i5-*0}UN zRQ?aRU_b(Hqa7!3OZB-5QRjA(iHO>`cR(&JV4YZN`9&i{Z54)2pkXfPMgUGG zqZNFca5v|LDe{Nog}N^n7kWC=Xp5}9KlKD7AQsC|4W584*?Y6Ti9arf;umlHnc@plG{)a2)D@_coLpIbE5I-rjsc-10Vr4* zH256)mD6Fo(6(}So`vb^g$l!#ELyuQYQz_!{dE*4<)z|#DVSRnCTl(Qo6+IjQ&|9O zf_lw>QRs01tV#V3*3{`m@u2}0mPm&d=3U5&3OP$mm%I{g7(cKI1llT6s6M^(XMt$C z5+xz0u?s@KH}s~n$T8jo+JX@fibWBEQIS6_)*9h$W6>X4_XoQI;sFh;&i>{M{AUFs zys(PLxl^k^UB9c-vVPR4jnee*o#{Jtk@q1fO-l1~H#V4z;NBUuQAF6l8dSl239BTN z2_Hxq{|H!gYA>wQT^E~2jRf|Wi@K-=<3J4YcZC*f>QQGxM$ivkq4$0u*J`qQ2tL8U zLm>kXrM0|D9oj?oU*MrG*AOB}00sJc+Igv@%PUX&U%$n)Ue8HZrwr+C-S{9{!!X!? zAao!0d@@Wsn`_|2D{G90=+MtnqSVDQCjIiAx9|JQ)CnU4uDz7$cXO0|T}T1?of#h! zG4(oJD%BL`{yqvWj|NulKWu^wO}#&K<^qF~n4f*zv{cs=&VwS*c|Q=??fw!%5=U^n z#c*uI{qw_@<$$Uhn;h1wOuCis;rQmFI1HLv<}4bt#^x0Xfu3;nqg3-VJLd2VVbVk&aedMql$jg9H#R zl_E=m14E@w5c~Q|ql=@(gT&>(nW(GCda2j~6+*6!Nq!0hR&g6B~vChl<_^~MzR@^s^~laKwwK2h9wo)QU!C?+R+ zCD*D{sQ)G!a@F=m^d?G5+xuP+t~c7}Qrb{S6>eVS9c;v|uRty?y+^OoQbhH@IR$RV zhQRPt9LPG1AI|k-FTXic8P4m0EHgkihzT}0aS=!rT^O}?m5{koife|TrV?i3WqEfF zt;T-?SAQJ0XAo<4RW;b%N@@NbfoLrzxsO>W&v`9sB@z(Rrl?&wPsC|vylV;#9 z3Hd=pHpd^NwvuvT;7lmze47&&LvRoq(Ph>;Y-?B{-FtaW@lJIv42hT0>e zS>>f~I;vf1TR+ zpF>bH_iDyE_bF#4A58(bjE|*r?XMCNJJ`9+eiPDOpTMaLPMLVm<{QdIJ(DPDsw(jO zB@#w(L=kGx?7kc1eg0!BI%fRA=d5S9Lz|&Fw^#l6GI{dMy*z$q&V?n6d`+VE_{HJN z_hyKkYcPCCQu9Bq<%E5Q*hUzz7&73=>M?@+==>2mSgqBb@6YFE7ZoqLly2v1GZ5Tk zlgD2UCSQb%w%YKTp=nFStB`z3tjb9b-p@~JxAtSMK6u+X@S&`JAR?s)PFF<#VtXop zgQ*rDhWj=@9JC*OleaZ0c$;lCPGLM#QtZ36;>H;olmavb_82|TV_@C{st8u0+ zaa`!aXwGn}F6MnflZgv2Q>_9PGJ?xKf%zyk`^pH9723~yy!gKK4g=qfwR>;0hQWUD zu0C+5bL7TXupn{cs|mfNMu#kob^#wj=(>DEa3A}CP47Rw0OnQw-W>FVa`RNih@{i_ zxS+I9MS3TpbmCnzKN86VFIs7|xbV$G<7n@0HDJx2CD_J~hdW~@aHr~GMX&XrzRt7q zN#MG{7Q+?3X|Lw~{SC-?fY><_OM^GqUk*}suQZyVP&zXx?ovtK+JwFD)l)y>)AWro zkE&BwYwx}T`%6?!D)P)NTow92WKeET;G!i^aDVxS$L*m4C5fS`6<__VzWK%%gEFAi z(eic9Yr`pk_}2j9f3WcjTSo3F$RWf7%2CHKaT9`#cP_y}d>H2(BDKC-Z#IcwD2hyx zi)tl3omCZCE>-pExn3Qde{Zr<#kYJJL)xFoM)5Rid-3$M{l59s#yY?i9_bPv)!U2L zIb%)_-c~Ri?|r<9h5X*LN7fqTho*kGz|pusf#+45KLZ(vZ&L&hxvkXNo2i+A6gz!W zmyMWjaC3E-(Rm_MMv8i+&;2P zQ9Fw{J2l-{iofm5mR-Ua(wqzZ4&r(m5KH=pgE7f)r)#W|*@fLdc3w&Im|bO5z%uN( zT%R1jMiy<#B;9pTb19=Ph(0b`QcGYUrf;?VJ-l(cMsTowU(9#z0sVqJ;|IpG@XkEL zNr@M1x7oiL#;hH0@Xu<|Roaa4uNw@FmBVlW*6{$o7a4qSM;h@UAfMtvk7^xiN=>tS zX|8-amqHoI{FFXqe*XsC8fH2{97!sBcBqfD zluUU9EMl85-e>0)rjy3rW`w#-M|P!JHxxz&;#t6I22!qz$s%|H3LBp;2o82VO_9!I z@Agsu#e^NP;kj<-;pid35wG<;a&DwM^bGVXc{dmM?eP3wkU&GdAa4F zTmVr<3U&`9{n(Gp&C-U$y2yn|e^4sZZw=3e4?h(kVVX%JE(V6DrECo*Kfy|9QWrOla zv`d|!qPbd*nCeBaVCpHaa-LlcqkT`BcxHNGw^k$gr&T!GKSeg_IMFq6ny;u^FL871 z2Y(=&*9_Z%{urDZn88~C$&wvpvGitBkf;aL-@h9S^c>sN85SfxPig(S({D?#%Qf?b zTw?#0@D;9_RI6~YV(Wuacs~cy?)X+$bCq3hS~N57x5?$Muaw;-y7frJgx+J+-2G8U z(o!3xxr#jz<d~omhGW zGwr7mhIS7q5|*{7O10p!8?l?i+}nv!rW>SubNn8vb$n;1`Q1x9GKaQ%hfE?U(8_8l zfCK0L!lzh`^p|p%BByQnX~-m1A8#w%CTR>zE)c5!Dpa!XSvLoak3IdNp=Y)A@B#jf zGs_meCexK@CFIe%;Azr}h8t@9!0lgd43*}9f07EETX<^sEbt+QfS~M3Ci&3J2O<)* zb|SB)yizc;2#$EShmul)8=1~p9eqG0wMfZ}lP~XDkOTVfPYk-%+G3cQ5({;W|~nfx>CSmzkxa+t;rB?E3v^eedr3rL-C^;)F>DA>QNA z80IU`@o~9;vU_IA9Z^?ZRH!#oV_G$`T<&0vP&a+P4|1w$f<>Eu<@1OaUoy}@ZP29F z`6zgXAG3vjqWUf6Dwj`U8u)Cz_<-+T+DTgm= z_6y!dAG=c0ww7OnoDM0xSMHKEbPs7=QZst_a2=mt8pFqO{E7DU=wxgc6+imsYnV_7 zI*Al%`B@c~%~gJ7Q=+I@$6OS?Z>f6f+58QhF>)9oXvxr!w)`y2ZIY6lOmI+(PJWXs z)IM$5^-7e>>{Gdef7zEu2pd?Us z+DACx+h)&tdC`1Pj_B!kUKP%GPS&?PB9b9!a<@S|wCv29-4VT6t1>dyUDIzHNupXh zWv7%buPFGE+fqj*vrbPXQ`?%Cr0e+HVbRdTfpSwWh{xj{uV4er!MaQhwLbdoMp$e) zVL1q|{Y4s>)Sh5nW|WFtb~RW>xPDN)yrJas^qUitGh-%c>>oy_`%J!US`?jG@{mcz z&%kp&H_ROiNWIKd5xU%3dcl*EAmSE#(yl!l&paz4;U`y8w986>b+D7;%h0#6@r*{L zhid27>;%{|s|Onypod58d$5CbTsB7!|LL2Ene~3(e(xmq4stX>9bEQRUd8#QW! zR?SP#gX{1t78lCA^jqIIOn-$|@MN1f;_dJ(GS+cSv6oSo<)$Y_Dbr_xti#XOd^hPy zph?R%<}Hp2xAApnVh*dOhYiE&zc2sZNE?&#>$etK-g67zYnqg7 zOT8SFNM%7TG~=z0$jt2YzmW~ot3N~oi;7b0TYZj>I$T;oc+r2;p-QljJA~!(K!BR- zOgbdc%#F#P|70hgB}P6AdFg;1emc4Rcj~Ny>GXZ=?-*(u0mRO4Eb?(5NwI^19~U7` zuhxI#vGiE$bT7S0pg8XD`Xrc?IrcICV})_HW9MUGnpK@NlCTcyywFHF)0}s*itgZe zAP`}(H*wf6klKj)?q9(}ygE$x&DqwMerXQiZ>d~c8H6rT*TrDT;$Tm2f4Yx7@uZ@uMF345%fLz6@=nW-5>tCMj ztq*HJ3SXvxNJ!;EIqlJO$u@^?o%Av3)j#BoFF9SlDT+&ghJSXtPq`_Est;=j4aNa zl)vxXehOU34AXA6RX{zLPPO=SS?%3Od)r6m0sN^77X#y11l9>``1b5|W}n-ynOl!8 z`GGKT>-pMV3w-pvTjsA_g)5%MJa5le)Rg2O$OFXD!R#wNi`Xzoa(HUIN58X?1*Nk} z4;YFQ;+?M|i>fR7-5@

>5(9LhcY!ztnkkI5XJ=TATRVN8h*{Z|qWc>i%d;x4Lch zg+u>_GVkY_`;p%4@D?NH2K%7_QltJD5YmN#kj_430w2PG_uowScqXyRBtxWdfVWW| zFY-NQn;yxfndbEr%7vH4$c(FS5Pmhqywizk$~)HR5-XnlQ8E1~lw>Uj8Xd75BUBeP zXJp@BajwQI90B70TNvlj=5SaFiMs>HdVDLv32Qz|V4#l-7Dpl+ja9?hlMHCFJQ|X0 zcpmMDfJRc|B6X_DMM5j_6c(1E|1@iBX;NuC7P`xDMXUS z>z?2)d@G`ca9cd#iLyDNg8xvoN4KOgm{mN9+W(U1%}B#CM}=ryQ5R{iCpJvAgH#9rBq51{>M|L#QOkJklJn zF!-0_uBja67U)0ODhhkMpx#oB8ZvaoN(soi3_|&pk~57T{kE|yCzCotCDeAuoT*?} z8m}$o==c=YdH1=m50>^~mGJGSA8y2#JWQ~Ou2UJu;^8tYB#Fa?^l?9-?*2RB--P>u z=o;iR2vi9_X$(FifgTm+N!Wr9>Acq7e`A};sN~MtSFLXq!Jv;; zwAa|STrtni>R12Hn5#WT6mleN`4@)E=eVZALetZQUNtv6M;WpGc}ad72<9AGL+TD$ zcnN$58LSO5Yu_ z+!gbYvAde)rftz2YFsz!UgIh(bsw+kI~oKk-xZW28Eza zx^BxU6C*c}NtXt=-8T#*nSKzzx(yDGZDUR2(uqTrHzM?rcLSCJOt@TS3;t$i188RE zY9%qac+cQ{TH<;8OFFBIw>x2*9O-w)*o5S6%xn48JC+I8ZxOa5F;?C&CDG4Qnf!PE z;}Z#06b&H_P zgZ(c0UujIMBwh_CaeQP|t*^92I74vd5(-P*+I!|To zlu3kIj3weJC>|NUsCo#s0XZ+@C-K39>H(}Zf(NmyyiZLT`fM+Ss=Vj-R4+x4m*Esk1l+l2w6kzgx3I6+{RODZu*%v#Hvf_Zx|UOt+Qy1J zRt;Y!T}mblWRB!N0y{Jrwwqy4F3ReTM?jjnrm^nc|E(=~f5dU^_niQ2O!J|_GEKOf zhDw9A2DP=ty=hRp=CJuCGz4Svnb^W${(q_#xW@6?0Yz(2PW|D^y0Qfc(V8b_fLOv( z(CH1c2x5<=$tcU_2?e6Yunk?(WvnBK+wO&FcVoFlz)OneHt>7?da=%)Aj9_4HA~GS znW#+HIa}UN9~J-f6Ul_kL)WdXfA|^Ey#iWF#Ro(CtI4Zwhe0hdF;a)KRjfOT1U_QCsC&5SoPUG(mbID!ON!D7dPu!q^0d#4Z| z%TYF_==Q6*q(6Dvk*8L9mCP!aJNLAh+#)u2Og39)4$I~QY38QOxfT_en{6L^JwenyFqij%B?$unY4%>UB1GrPIJQk{izWNd;s5_E(-0ZWUcB*QXt z(seg!L;P3h=HdQ#6;4lg6!EW#3iTa;u{6>y~EU zlkCo4yluH$9yikaF*>*W567C|LNgO@eOF@f>oB?4B7_ z)h$1BsHaf2CW85cOc4e{08@~H@xm5 z{q{>fULt$BTNp~2E>Ew1Z6TL5AEUS`UMU3u3YW96&bRc;pxc@*ahBi%LBIq2N2FU$ zPRsqbFutb9Pj1Hmca}asVe5`{+1#WyMSFHF3$VaI<_^T*}*oQQSBP9 zpUO@_Y;ppeB~uwSP5|l@U0flLHE8yPio@p|53k;3kVE>Uo*Ai}4(;hBArCgys5R@pRn1qdYJ_2_emsBKEsA=t?Z!7-IojE9`wOVa z!Uj1Cf1kW9{&?~fdC7epU?uJIzd5J>Y$%$vPt!~XXCA_`X)|!5g0D1*(9M-O{T3bz zsOqP;k$y!D;gU{o@1z^~=x@(C`B&9`oshPC3}M0jE%XiNA&bNw9Vn!EhLOQW6ZuZu z(btfoY$XR2?U4q2|9G-j-^gXCD9T;lv7@u2Lm};bZQQKo!Z>UV+yY+i6;x~uw zNHj+n$~KPF9=&ITe~auvDz1~Sh5jz|Bn;P3*+SJHYqAg`KK}I_qb@R+)?d6465RPh zF?A9|xdh#3U1D(rPu)m9dtR6uPBZ!a^pXs3+kdqXQ`U_cC?>M0uf|}#5|+S;+R%HU zIX`%XE>x+4dXkYP-6kBQi8KWmuZwNAzk+*UrEOvOOe)Af2eQh1b%;E(e%JN>{d2SG z@9)#*=t6F$TJbX)a(vJRFE!W!O=o6>ecOK43*~2SSr@_{WY>$Q&J$(9jBRppdzb>+ zOzH%!i|SYp_CVdh2vCe{yB};sPhpB%g8>o@KA523I0f?+sQF_9l~SDvt~@k_xlcY6 z2Jak5Q!d4sm{XR$S1I<&_=qvs3`weR4{Y|{bsx6pozFwD_L)|-b&c3DQo(O@Fw@e^ z!(6nnS{)69_^+1OfZ+nlL4(C$_(r@EfirseWrIF@iFywdi3KSllFr?_g1bKHGj$+_ zUekuq9Ij}|W;z{KZJJK4pSE?v_wDjvG{EWpinH&EX}T$(LXJ9wmr`=NU0;(VLUjBl zj&+5A@`tg!D%Tez5B^iwq0c;!S0ARhq1JPlJ!YEbuSED1Yy#KJ59VKI?TUI_ryQ#m zIDRsG&WR}Lrs+51g zi_4Go{7`|Nnrix6?m+NuOl{!&>%Vr$*pQrr>)ls8$b5lDlt&QHfqZIDq@Qg9ov!Gy z(_r4axVKl{lrk;_xbN8JSDTTW>_$W3$EgIFVFipVv5Wz~)j zaa=rL%_)oZ`6^dpgYcs3>pC_%LBOJquzK#IUd@Gz=&(P?R1fyHvmj5W(VfPDi9Cn& zF>u{0NQgLOiMvYTUAeN~F`O?d+?I;C`i4szDX#bo#&DbPgWRL2@2n-lQum>dYS+S& zmP5z9qla;xQ|oyfd0W-=TcJlJZ-<b>fF$GZOX zj^pSTc*CXx5u#oak#Jv3*hQwbwrb2WX3vvz#+KdQ)?xa8nLW{WSJijfjAo5iM*+TE}~ofmdH{p401I=UaR+ z&FLsBQ+fV6YF1mZ`Zd;4X{Eg7e3LNp!Tb)4Uj|`4w;UdjN3RD$`T?F2sA-TdO0geEAGZG#?mUs02;DD1gVZa?5Xz^2s+AB&lHE)e+~Me5DJgc?8OFUU?7qjD+_krnW)3>-;4Z zalkcbsA(-}p;5#}>4V|gYmIVbgu9{s9$)$O&MRFf*ppJCi(P;BYo*1mTC23bny0AM z(1yHX42~_kAFnD>N4kdBXeC?HJUKu`qF~Vb0Y5+oH*s#c&GbqvO~fExW%P`-R7arF z2ucT#N6Ko~4f>A7;dteua@CuXIsBW;(iZHxEP|?B`RT2RTOG=h5po@j4=D8DNuxq4NLxlJ%9Ae#Rks%tz(rl;TPu#2%2(At=;BOpLn!bQ z=lD#XU>4};GK@17DMY%11h@tO1*x}DsWiKW0o0n~oo+>xHUcbu_TA_BnD%%Ii!oo`7m9FL zxN}?S^&9akh))xWN8b|3FmoqX5?ww#^<%ZQ>l zzZ-BL|F_UM9a|k$>^w}FDoe3@n-GS7a8o7_6Qv~)@6F4lZ%uCURn?@S@swYMe{!?* zBZi@l;hv3G0y}u^CgiIXm!98O7^flR*G}xN=5t>U3;B2Fi@%fhHt@FSGFkvv+EQ2a z-y^lK*@?xXWX%ysL%I_a#?tS z+=1L^a$4L{Is-xY{2g%wc0ix_ zGgABF=&Xds1*gu^8?-}ENG)C>b7))3+GfJ7r-qHQRZqqZHlD%HwS)CO&#DIYJKXd1 ztvMU&!9}_cKGKf}bbs`^?334vgkEQ^@AS%(Qiz+F`%TmJITl;fRJw^dZnWb!)hEU0 zt$=oxGJW5NNvY0%`535nX@@WEfB#b@+YT-m&M@h2V`G7|yph;_+V`{aw{)Q=J+UsR zxhm&svHR3ht~z6>HVaM9&lE|F*|By{=jC#cS3Faqv@r$dDY`^jE@ z+TZ@FH%dmC%Jy}hz%l+E=8(2;iFXC{OJFso9u*ACr_nq*R2jaU?#lmdp5VcC>u1w%KXwqlo@#cW+ z%G$T}tfl3MTUO~=SNxtbt;jLQ@ujC{L4+BLSafh^WZTKBi%Q*v&4$L#z0|xwm<7m1 zi^oV2zdM6=QGQzbvQ^Br)!H*?(uDODe(P}B{Bp1O5o%nZ;kDbBqoYd|r9khZE+6Ty z9WiI;x6)$^9yh!C{TB9-5N#+K+tapOOT$@kZWW(%^AL|OWP9to62SI0CH=PNnluof zVUHlUkj%V;b5X2~AWdqaY}@1z7%g#RfapE!AoaoNa)?!Q1GDgh>Vq=c^5x+(tuPXft;)3;pP^snauj!w+_{vnpt1!#GT1d=)Ynj4WX;P9 z=Ie}GFn&$Igw-EDfeX_QOs^Agk^EdEP=)R)j^Vn{Kz>QQdT>88KFOuONu73N5ytKYJDM}ny zOX4lw=6)j57|G3+OqY4HBCZQKcU$ zisdIIXB41LjN;7?CC>&)KM21#rykGib`y&w*?QbHhWkA6DuzcFxG;hiWtAuofA_6M*%?u{M&f@V}Wz zN)~MXQo~aa0+f+EUW{5dC4hw6aQ#NlEdVIAg#&7wX*QvY5R}>f6Mvlh0dYf^$j?9Z?!XncbVk(Cg zd<_f6S7d9)yH3@6smMHYMo9*xe9iKhm^;i4la!EQyHdZQ!TvYF!dyD&xZRcgb#p`# zoH!si2`)#uT1becYYSXIw}&2B5{<{bIq@BpLydnLzK$#n8re_r@P1W5P1HTQ$K3^9 z3AT4IyNDcin_WJ+gV_6`kU~o+aFQ-2s(WesnXh!x@ttUkIE^3}Cv&mGkg(jqc&>p| zw_!O0Dk7ScxV8I;-y)!cr0p*r$LIU&qNy&t3w~Fqd)|&vR zE7Z$IE&h0tx0LLq;^g&V#bb=Nd3UwSJPD4I_o_p^%6x;6l$&N=09bRHf&k_w!@$o{ zvp6m5U_KmOre}H08@Cj8aI+{zIFk5fe7UcfQonBU#rGF=H}N@mxWPrWJ--4vRTum> zDwZBNaimTC#pK@O($#e2rb#5GE8t=;>0{|4Cz@?Ut}(Jgh0%%mYoLKp3zpzD3Ek!j z`EbLHg#?)v^{vJ=Pn;{OO8EP{u!PaNUI&BgPu6$yYBjpk`)ZILRCtE{UOivlaaWzZ zV|*K(oW>K{(y&;9lguf%9)FGa=~`>Tr%ue7C_b)(p>tu1?(>q=WP1FnHZNM6mr~;T zV2zWx@rY(72R{_%#F%@q#QSmLodI_*l{+E_)~ezL%jJr_+rGOmnbW`Br%GsPkEC#E z{);Dy;CZBQYF#uxUin1)Y}(Nh-hnij4GH{mUfk22aljj<(gA` zUXH67gEx5nmW!tv=BcxTby1a*C)kx4snK|>7uc;Gm7lt|W+|)`H1MB{zSar7Xq^zw z4fTq+s(7G(ud8?CxJFRKv8*xf6au@Ud-hj!U&%`hEG|&OU;q)WFk-FFU!Td$p z28kaY#uwbA))%RY@Dni4^fnzE(cxW9^zkzte}RgKQF=bQoEW+`7uDLYCmydXAD7}iFK)aj|amP=*Q6IMO&QF`loZN8eP z>zg=?-_=rTshoVSk-&vB;%U4l=@lYH>UOe)-F6>IW9WzT*z*yi$n_sD3ZgvsZp>oS zdO{z8g9RCuFLCiPpJX%)QyVgs4^n5s5VS-j0UckiaE4{Nb`p9%$_Xh?ttaPkb@)tK z>DKnHd_TDH3{vTh)Ise{3nzOKrmu|M6`+sU61XQidw->k8K<$1;?kxdSW&uU64|oA zf-FdiaUn=LA>1tn{JuXo4behp+@sj)z3*FKw>?kBP{uHm%YTM#;)~MJ`gHD~T&l#; zUYB$wID7xf`dAg)#8LjqtHJf~16AZy#I3dh<|E#w%^s|Vx;L3IEgQ2ICHA{>jGLrO z-M@n^XJIM#iFWhBI1!+{tA)AzuXt6F2;o%_A@@Bh@QSN1g+}F;QplfGQ9SNkv0|DC z_0ppY!9cNyvaoT4d!_$gLj=da);*XMRb75wx>0#;`kHNG;ML$l!g#_g-9$l_2;pN| zy7_;U-Ai#ksfz?DxkdgF<6gH{^|!|=cfxch(m783r}>ZvK&E#O?ViW>bKaLiib>=D{f*r>+3Z~Y&wYu$=#iP!SQ4KuiYK>byA7lgP+&A;j zPk-uuG~YwO<&#&qlhXc#)EmJyT^Ac;r8$(xa<&T0?Ms^B1Zlo-@uhjV`}9+kNig4v zod+DMPq>>4L}xnGz!tUIwg;dWm@hKHiboet;fZ^rSx zl=}!A(G3UsKL2xMfE)UfYhZ;SpH4hy#0{GCjP+=`)aDESi%0ipUDFQ_2I*g^TShS) z6?^S;`D6dIG&u}4O+M=U67u||h&YdIa}PV@11qFhKQhnkA-s*~;-f3GuTzF$YZW|A zQnUE8LGx8de_Mo^O2Tb*=6ZgLMsTj|8=%4us6=K%{FxwbMW&GB6#K;`)fjIXwoqVc z&7rEuWa(KQyONf?2U@Z(*!A8=mz?cwh_8;un46CF(N9mBZVs-5xApV~IlA_+h2Sr( zglf3Cq!@zTJ4KL+_#PCON;fYW(C$VZKbLBe37c;n`H|iJi=-{>OiIkhr%`zSb4p_M zVs&a7;E5=!cZd4{+qgVQ48xY>6gqxAm=P6fKh)n&AdT(D5VLDY?G~S-Om7?OuprOU zpWQ1lu+4ppS-s-muCptXX^h?S`O7Zesu)!b?~9 zxD2f7PofTDKh12_6H;OPB(A!ut&z0dd&%*9IVBhwr>kD`;s0yz%KxG6qCaC~jj>cj zw(MjH*_)9qd)n+v(Sj^lLc+*X5hGhW&*s#Q&dPl#Xwz>+CT-G!1xsfq>1xYAMoLzf+mJ~U2kz0*M=Vt+YuTitx; zLqGn2$J*dwT^WI+R*2_lryN?ke%5C^e|&+oqx=w$-ErqbgH`ty{L9dO0g_DPD~*$5 ziq5hZw>rkyKz$%1T>{i4Rq&oY2lKk`l9(AS&vTaL&$mVaWZ%*|jX%6NyFUir*ZUV( z3ylS(wlt~T*yli)90}n|*MFC^-!$SIm#_I*k0)Kx&9Lb(FlF5G4npfNKGj-QM%IG@L@dvT))O}WADJg zzGo>ng9Jyy#qBruRMOnWy+Kx0HbPdPbrrB-GfoLX1fFs2Rhw$xAC8BY;GWyikss2L z@r@NR=;&J)=d;J{X4yKPX$#Nj`z(t0zpd!jW+;d((~`m7)9g`x@K#wj(XacmO< zgX6Y(BTBtB`Qn#e8477U<$Z}$%`R6F>vZ#SQnJU2WJS>o5`nvP;X?>z;IoROa6gX0_OCm~oxO<>vr!l4*0mln zyLN|JTic6gxEaj}`uLvv<-a*|CzQ}%^l)6>F}bQH)Ly?m^g~+Ove}u~@-q|8HjD?( zK+WX^P|3$B{UWIO?b5zylbNc&vL!n_I?Hh}-lU+hP%?I{^cuXpPV=Pn*B+0c1b=K1 zh>pn0W6G=Zt)ro1yFj{Sp4URMc9-n*0bFYd!y$A`OUt%4r>i$ca^-4F_a2#^`TEsu zXeUA%G6qXGn`S+s2Z6G-o(G33=kS5|AII|;TMBvOZXDntxf;KAokh}yUJ-;U69Ubnv~=*33X^^uwCCLq!( z%{-rTsbO`?nG31TP)+Fu%c!wWEs&l544Z23T3Z)--Ktov$f}8@f(>m#z#+=6{b(cBHUVm1$dY8P1bM#i>`KpDj-Y-gg zyIi#D%F!VUD(hV`sD_Rr*~1SU63feungo~*&H`lCnCFLW;Y$z7oEO96RnYM)*Pg#F z?<~xi6#w%&eLD*)=QUQoT5E=^5vh>LMG|rd-)MSwn!M24))za*`tF6hc>&2R)wh0Q zN9g=#H_K0_&DV~mCUH}#ByAnZ`nK_6%~f^D(n|pp`7N7m+fOkuhai<{)nBcam<xY37=rdqG%XS%K5$7k0R?r7+UlSS#+ z1lUs}21Tm_!)-To?np9zB81z9P4x8fGIOpU`!aBA4y&Rp9)^v`axY3qIL-43AtL|= zk>+RxmOB2J6hRMQUOOs9# z1NR3zj;~xXk(zEjr4}Eowzwrl~n1l zm1-=t7RZ^k3hV(}=t*=H^cj*Ea&q&$N{_#lAwhh#&gv*1UUT=i2Ez=z3-#h~2<0Dd zmF&KU(#x&31D_^6_dara@FCq?ZFQz5j=QuYn1?!gZzPL5+G()_azpi<{PwY*u!Ca4 zBlf$Ubg%5)um0ko@6^h&RAv8Et+szopYlbxYGMz8lU^|bItu>?9sjL-LAE6M@u3y& zsO+O!yRi*T(#7-yt8J)8KexL&$$5L+Qn+*aT11x$Nb3@zfiowHz2}@KUJfyKj9^4U z&6-dR(aOuUCSR{i6&J`XKJ?)E7TzF`8`98d(%7(4BYTU|#;9`VQ8hPz9yZrM=i8{R$+pXxxyq)V!l{Gk@7YBpYA9-_^*lsKFo@xBt{XRQ1*($@{d^Tn>QjM| zso6pW5@Q8J_C7?E=n2_gu%s#*<=>C+9e-g}!GRoyd(Fh2dLA`Y0#{AbI{utjy#ZIV zGXL$}G&Y02?Mh6WCVEY&H+i4MSEZg+Z=u4EMbRVCLky21TyU^u)v2AiRjNCDkV_=( z*(Vy`hKK^{eM?j3T;zI8qCKhHwjDg|LSa>e{D=?6slfr8iVNlCDc~M-YL_9Mv3s9CUJ@B{cN3pVOOMTryw&kWsG2q)EjpWiRSJYBgu0gHQ0U%IKX;TM zB_3GLjkyugD~Tuo9ZH{TR$%?xsWVei5!n26R~`}EUVLRCq7O$W~6v~=d~k3DghzYWMWLeY8?Lg65MI zSpfbn7*Z`>b5(dxL}>Wjp5z=YEt2;uke!GUFYG0K>q%YU?kH(ixhXYuWmtum{@k%5 zWf&$h96ko{e!G|Q;23xkyfDipr_bIx2;0#Uppe3i&U*0CqqpoPFDCUbKFQ@N#VGNq zI>#YDjZuMfd*qjzq{WV8J7upp8hJ_|LhQ50sr@Uh*{I1=6@x9y3m;jHRh_+#B zl5wlao8-Nb5tI^0r?g~`$~9!qAez{L+*UQ0odx<6c7y!Jzx3yS!dm;`C>jL=D6yG{ zKY266=kBFqzw1sG{T#>y5u@5B=?>3KaIMB=Vc|N-&BO1w+%s^0fAQdiF3AjB``PzMF@a~qfiVvj!<=Z|-x=QZE8PvHeQY3r`M15~^bmtOxJV+f&H zs)#NcfPKSN8NL+;jv`s|P+1$0AMilD;|*;Klhcqj5MVv{^to8=KFv-CIs=f@Fap<- zH_?~z!Hl`(WhrM$1f)?RD;N>Dn1vIOM71}+3*qZpxA=)L0$eGNhh$)CuGauBv{OBx z((0rF`9tTUO3xXt*Hx0x&&}0UvH$xt7N(4I1aIic&AfIf zq#s5RKIc@r>KCd)bW&;f@h6%bFXKa-n$Qf3Q#~ou0Tf~KfuSeB)g*+ZU6KrVBvH=X zv+U?oU)p6gFBZpz($}YkoJ92Ys?7gF7|!qEc#I!X)_rC=dK|juWt>;Uij3@3v_{7i z$ozc(S_N+VFU0UV=}RaeO9^c_rSf{Y$d{W_!V)@%?+|$D>k}dDh;$^45n3cUJbUnouX^OBO$+YA#i{$_H3tnDpb)n&gHG~rW54v!!_tYcwYkmk1 zSGr_^&u)A(ka+O+d7!>i(PPkF9qd!wS&r*?tJA;|q-uXI5u@c+ib5}gTXrz)fH@WN4)4{HA6)8?~PCa5l{FvVPEsX!lt z>;^~9ZDu8$qVrV{Q;o%U1i!o4og}tR?)s^~f|uSWdR-9xmxb9Dv_7+>4MDYkj(NfJ+L%>?~xzJJD^*m5nyv#Z2dG> z>Hh&;9heh=z`61cK*WHP2>z+Fjy_0Z84YM8K=}NY&Kd-XauGfMg)_^gj8O;?!EumE z>CquXc+ycF7j~ruNo7f+{8W*BuYiFj|6UQ1s?8q^q*1=wfTlK#S3w&Ep4Io%re`Z0 z*$|tltnYJzt&@OTb&lLt23MM1PodvB+RK|Xa*abO6VWIP^tL7HsTmymvQSXNReI^f zAOH>d^ja+N@(Ic#d6O(nw2eQ8uyBBi#asmyJ1bqu38VT0=N48ZKXgc@2SmAK(8>av zM^Mgnd_l1VuM_&!o#IGk5*)G7LIj~<0uxNB)N=t<`GU%c%9kIvl`vKeQdY!IJ~Cv2 z4vnM6X$}VMK7^Wchf*vH(%&y*-Rnf8E;3X;_`+>SH^yUe3C?8F^a12N-X$|Tlc?^4 zX6KJ?&a%UD69d7jSiZz;fNkwyUEhGh=aM^TWKbIW^x?RO4&-KrY?S%tud52yMdTP@ zxB5Yd*R2Xf8Fj2bGGM&)ffh>V;Y#NyV|)}mLpqJpW%i|Wt?<#4K^0N2QEg);1ZdL1 zG4Qi%orMPhX;|gg-!>5%rE-9er>M3B^oouO80s6WPJbls$HCc2h-(blAQN(s*KDL# zf!CJFEa>BNGueXa&m&LWXh4%Go~8tg<@5cv&fX0z%HIyYF%B+g!KTCh26-xEhy(9a z%-{cUVnpWO<^!D*@$|ngOh&=S>3+?WF+mR6o)p}Tqi#LHJG@ro&Fi54#!*)?`AgqIf=AXPtC{#26E| zAN(HJl46P!7gbTi0r{G@gcH4I5RB>rH51Gc(gLvc*?#sj>$C7_CijIa|B&C%8Oe8V zC6eM_1;g;K;HJu{cMe2Qo@NWy2KXDvXPyMa2F^IJX(3b$9mwhAoWnaT#DwWUK4!|EU9!+QAqr}W?MO8lM2NAARi?3 z_WZ$doiG!FZ7AD)O0uO0pPryXZ`h5dOrm1Xj^r7vYP8wLu3VKmnCBYkL9b$w0T9^MiYZS!2-*C(Y+qUJ5r_zcMBW_I?XR=q>TM zKp4BhU`hkx&qW0~A7%|4@j-Cbw98TD{0Z|%br#KoVL|vlHC7bIL5vej zxB~wMA9=XaYCl%x$o>=+6C=u{gR~#fI0zaRovderm<}qMnwN>%@IaHukIF><9E`xwDJ27p5f>0{gGJmm^jls9!EzR&;V@?d8}zmzG&Whr~9G@d!X ze6Vy(l2;UvZWy?fBzZ>t7E3=xtQ6FTQ{dzeo(M+(nFHHGPI*V*_ z&}rnQ0;$pe+zRZMzurUss{$jFe@u&ocBuRJ+wciO^*Eq#4jIsYo8aW&{oftXWb#`? zKb7OR7X6gO?~V2^Ui^lNUzDt>N|-%#;W62GD1H&py~y#9ZE)78y*{+(YMo}Xo< PgFh2POM|ilu9yD@)d*=D literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png new file mode 100644 index 0000000000000000000000000000000000000000..9c60a1761dbf62cc2a45ff98b9fdb63ade16e4d9 GIT binary patch literal 3773 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 Dh-f%Y literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png new file mode 100644 index 0000000000000000000000000000000000000000..448d6efb577d07e227a5c62545173ddf6bd86b55 GIT binary patch literal 4750 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 literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png new file mode 100644 index 0000000000000000000000000000000000000000..8524768f8d764da7e9c452a444208708f2d18ff1 GIT binary patch literal 4692 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 literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png new file mode 100644 index 0000000000000000000000000000000000000000..60a64703c0f11d08705cd607f7751338707f5919 GIT binary patch literal 5192 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 nB>N_)Q7iwV%v7MwAoJ}E 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 T3-0p800000NkvXXu0mjfSlal| literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png new file mode 100644 index 0000000000000000000000000000000000000000..1ad04f004b638bf781012290d78e4138f97bbe5e GIT binary patch literal 1761 zcmV<71|Io|P)4P%ubY|S^%$zf~ zmwTOa@12BA$oV-Y9!V&U%c=j==#_}M2ylE}1m>yyDoGsZ#Yy zNX}RO*f(MzmKS&u`qiajIyW{Y_LC%m2NqT@Ic|QpvYqwNgBK7n5X%c(3k^?2>EOA` zqGaXjE7H9BiJ55fh0iJRW}@=&(@R^E1hLB>kE%PS6eP@VZVdtn(fh;5DPKg!j;fJZ%)wH{Wn#~V&#n(o1URS zsyS`0Tu2m;-H}z9O^h`!UZAFr@?0a7Z;pYOi0uZhgzh=rOEDi`FIkKtVu*gEcSM!h zmb#_XR$akjlg$JI75MXgWkG7IUnYJ+X=1J!qJ%jXVj{L1I2QU%?=?DgV^U?)92DZm zV?>``xT1#kZdgUt!2n?|0>*6ae4tikA9FAlJ}kjmMQm_z3LB5sZYHBKdbex9_Hv@K z%Y?q@9-)b7vJ6X$3h0B4tH__=#*`9^efY@IQfghn*=E2Nb8sR8lrQlu`Ca_Rmm6>Z z7bkEe^w8M>x;hoNUvWu_GZJPVpI;bMTsBpf(@U$Ch(-gk0T#WpsaB1{7ISQ~Y48mW z;Nk?@LjM_?q{BV-D=veoOmJoncVDC1GwGGz(O5@o7ZkGCIJMPO(7K9b6M_wF?Xqd< zo4J6KF0_U2<1=T3x0qc6G6#g+^=N{QTpChC!GZuCY*|eU{Rw)LMN7a2wwbaCdn_dE zzy+Lip(XU4-+SoTFyEcnH3?HRV^%-;Ylx;|>8v&^Dy459ZJ_1zio`68!6s8SO(6sq zaN75WUKiF9+8MruR3=w5)hzA^Z1clVBuXc)+8@e);xX7bfygR&FsIIt-gQ+==(c;S z#J*CO1qZBF&M&6TRmskZXaMOU6&?jn_(BqY5 z>Y|^?uOh;yp6w0QR1`>tiEz_-{Zu!N#(nhRndJV$7;LOgPyZQ*J2yCin+~*u!qKj# zItsG2IDi{ZH+E6j=D|ht=qWxKNxaA6E>3Wna>=z1gy?*#>|g_1^BGspGro&OWRc(k zPP)(*y0WZ7Z-kICr3#g7($P*LCjE>7S`Xh~s!b~bPTo0XSkRm2T(M`QZbv-`Imx*Ulqk*aI* zaqa*=>61?nFb8w3wuiA&zyVyGz>!cm-pY3xEsMEiY)Th4FVrtqWp%V~gxW82)>4^N z*H{>GR?m$^s6BN^M=4^iEjT7(gM(8z7K#9Sn(M_`)oSH2zHDCla&cmK)bb|4nAMIO ze4S3gI9L8AD+T9c#C8K8JF)I68NBWK`5pE`q^OR#h~-u!e7P2i$UDq7^*uZr< zbp8sR<$nYxb8EKH|BltapZ^j3+PZt_u^PR*lT6;TCNxu^yFH$j(!JXvbmHfQ>a0>O z+2k{tOWD%ln$M`tD&>+*KBKvmEgi1;jOwgXF4_DG_&r&PcxYTT00000NkvXXu0mjf DptxI> literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png new file mode 100644 index 0000000000000000000000000000000000000000..2dd52620a8f15577e56ec7fe8e671988dd17ab0f GIT binary patch literal 2537 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 literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png new file mode 100644 index 0000000000000000000000000000000000000000..b058cae2f440e5a5875e45c036c99f1fb6356046 GIT binary patch literal 2332 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 Kc&(xHv;P1B$EH01 literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png new file mode 100644 index 0000000000000000000000000000000000000000..4954a4bd33f613d45f74dc0b12beb516e3b38661 GIT binary patch literal 2758 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 z + + + + + + diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Info.plist b/Examples/xamarinFormApp/xamarinFormApp.iOS/Info.plist new file mode 100644 index 00000000..3061d399 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.iOS/Info.plist @@ -0,0 +1,38 @@ + + + + + UIDeviceFamily + + 1 + 2 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + MinimumOSVersion + 8.0 + CFBundleDisplayName + xamarinFormApp + CFBundleIdentifier + com.companyname.xamarinFormApp + CFBundleVersion + 1.0 + UILaunchStoryboardName + LaunchScreen + CFBundleName + xamarinFormApp + XSAppIconAssets + Assets.xcassets/AppIcon.appiconset + + diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Main.cs b/Examples/xamarinFormApp/xamarinFormApp.iOS/Main.cs new file mode 100644 index 00000000..d56c4f5a --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.iOS/Main.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Foundation; +using UIKit; + +namespace xamarinFormApp.iOS +{ + public class Application + { + // This is the main entry point of the application. + static void Main(string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main(args, null, "AppDelegate"); + } + } +} diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Properties/AssemblyInfo.cs b/Examples/xamarinFormApp/xamarinFormApp.iOS/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..58d86602 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.iOS/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("xamarinFormApp.iOS")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("xamarinFormApp.iOS")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default-568h@2x.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default-568h@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..26c6461e50acdf5342b6d3de82513ad48e562c4c GIT binary patch literal 8884 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 literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default@2x.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/Default@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..dbd6bd3e8646fe4dfa515cf345cbcb30271ae103 GIT binary patch literal 8368 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 GkpBQzOK;x* literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/LaunchScreen.storyboard b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/LaunchScreen.storyboard new file mode 100644 index 00000000..a639c2f1 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/LaunchScreen.storyboard @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about.png new file mode 100644 index 0000000000000000000000000000000000000000..48845257c0518f1f45f140fde0f47b773b0c3d5e GIT binary patch literal 518 zcmV+h0{Q)kP)Px$z)3_wR7ef&mpw{DK@^1(5nX_l3aQ+Hpsj{C?wR{$=G}SebpEmC8R%9Ve;fS(j^Gj8gFEmI&fpWA zz$yHItzi?VbNC7$;T1H2UAXmq_1@p@SEt^%#^~Yj4DaD#p_@AO#u;B5$3*%xmo*)X zGhUy{Fmr>4l_M7ejMt~qOt^MVU)?7sbOHM4SG*@K5W9vs+#q;|UUSgTjhTh7np0M? z;T-%Edd)#Uef3Y`j9y=*5>%N1{q)s8iCcQdNk#om>xBMESj{XdIh-Q6gD$}}EP=lI z2W*7aPs8%+TIJw$zT`x|`t{X6AeO+qwg*v*4bKey17Zm*iGsR$W9i{y3CtL0zxh~E z2YvMqh$Y}AISGn(8~SE9;RMmB-Eo7PzWN8mW?)M10km?p3H|idKMQMi?kwn|d4Sdd zuYH(8@mZjWr`B3eLzC!13&+r#1~6V9{VHRvUqth4&D`a14NEtsI`ziYdUE0x;GXa! z#i{fR7{l0CvA^4|PQ7tSbd$ZyoqkLVpzpH@tn7aQWBpNl0S&!a8UpxaD*ylh07*qo IM6N<$g2fH;yZ`_I literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about@2x.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f9ba9f9631d47165a9b744fafb484afb42e55b6f GIT binary patch literal 1137 zcmV-%1djWOP)Px(D@jB_RA>e5n!RolK@^1(gism_1T78XPf*g47eERUsS$4gEfjf!JcSD+npDt4 zkfcZx@&+IykUKgM2norF_&Hy^SHhk(p52|9-HrE1$7_%0-h1Zm?96z^OG_QP40IXj zGSFpUaWk--u<7R&YfZc>-W0Eil=VdLL;Nm&6bIs=xGhrFT3nX$$KsB7B>pK#Y_P=# zzFGss_QhYKHTqcZ_rz!7eet?@Nj#U4_muG+b*PJt+2aeJjZVY`3EUKaiU=QxTjC>; z?}`E&Z1I6FeBzrJW&Fu39v;Z`7ZH)a#TVigF%=(Whc65X;6GG@vCZ2zVgUc&4f~F*S%uY&4)HX%g(t4;A>9SQm(m z29kiLB;dItAla|8@zz*0SWk#PCNT0c;PL#`(d`vB7id8f+M>-4%)K_%r5x}S)(dE& zXQDC6I$<*lu&ZlTumZ&2=Zw6ktSW4Z#9vUb1Z5RQ7Yi}ZTQa$0#t@>>hDNlaIT-r# zgwRkUEqC4;Zdb}ez-A~k2LYL6fEkIQmbWnzfJU^U`MJ>R30wz%*MMN-1VR z!Sfn&iZUV7_KhJs{Wcv=sUzfD;?g8(&)WYMQMLj(DF0u+suAjxVix zHO=2vH_g@tN2*T(2AS1u$GZ6irrFxyDE3Lf+sx{oW8M4$(|lM( zYRn%)F{eSVA45JpfI)CyJS%c?+ZLb|&HJJa^p9Em>GBaDBG;j1L(`wo)iH)%( zhM-uFfcKVIk*tK?6pfjH;G3d|r5A+U7LS#HXxrilw!QqSyF=4mfBG}A%EESmLYy%; z8kky|d^E;?i%4d)qcJkVHZvzL?71)8;i%etf(^ZrY3A33J03sDfL?5*9oC$LTK*tG z5>~_m(RxB1j{`C3g=jzvnv#Nm))N>LQvPS4_CHDen`y=b21f40uE<;*3;4FFj+n%5 z1ehIcibNPagC%Jw;0vFYXkrnwQDB|G0)!PKyS4ioYiq$ zMOjY-Y+W;@v4J@d*^1j1XKrTbyAE9jx(sv~sFZ=f2nI+1ndQ_`00000NkvXXu0mjf D$cP8y literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about@3x.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_about@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..fa470c26dfc413123f45de48e9e6887c6058361c GIT binary patch literal 2019 zcmV<92ORi`P)Px+ok>JNRCodHoX=|%XB@_(ZH3x+C`u2x7!>p%1#6%bPf|#a9*YNCQi7M_sg#Nk z=-zVDzd$I|Kua&Z6hvsTy-2aT6zJ&u8O~kF|6E`9YYSo55rIlNi(uz zxH=^Js91E=GgK{$E8@C1F`)Ao#kSb%NWG!$OCsXYNrQmT;|G8E?G>-B?c`I3gHmZ! zi?`(dXR%v|HEla59u}(v{?CiV>&}6^$ZssMLsd~Yr@9w@Pp{923?V5&JmM1H^C3U- zB;T>YK2>sE^g{pA>z4ScI7$$|C6bTlN516UcpO&+4@58Sl3wqxS!LuyUY;j;lYe7z zN}2nR!%=p+=GBm&pAFK2tri{Iz}rq@jy^Of?3pdP<4Q*Ui1Yv+|rjFa5LHRWzcscs3><+rHR zJ#w&i;^ThZ@AC&0jQZkWqwbNe9kF`o3v0|IQ{W{9`AlRO;9D?SUb8&~e8x=uBU?pX zRPZ<&p2%i8Uo{Z4mfO@Gra#%$&lMmFykd52qiudfIu+(PXa_L!ONpNp41(6vzxDd#di2!+Wrm;wRzCh)xei5i4t&jVzQ(^jL zI$+D=Tw(O_+u;YK>r_~2nGU#b-e%0s=G2ty;W`y+Q>FuMnYX@Xd-ncuH(d|csj%)c z9pJM)4_Fvvf_Atbu2Z1|gLc57LeG=A!}X}F16EDjqq55^=$VVLG0_1%00dp=<{*&HmORd|>t@n*KB#y7aXS zfly^TfX{x(pAJ4!yDMHySWDdtRC}fFLVk-0!|2JLPW#h(BsjFLeWSK#whf z2V4gMz0I=g@s5*s)P61g(Rn@W=9nBVh_rB4?8Y{2m=%wSp#Ajk@c-hQyC?va91{YtW>SpF2;W;XAy3YX+K;*a!Kk`$PKCtOuGZ^19W7>^@@pKl)7!e^WG zR_gj&j9RI?7TBRIu8WZvk7)0yMP|cGf_kVcYWzhub=L;_l*t1z61*mx|1vTTpbqMZ z+NhIyYX|O#cvL$Qy(~Nbzo5k3bjmt_j-V5odM1!J`Nsi8OMSJ+k}~w9IenXUO(0(% zcBqHC8iVdm-~!f^yCd@S3vT1YkE4Xs)vpQMqMnYOHEqd{JmU-||3(ZuMS5~!_PZkr zV;|wWqMm*TzA+?A#hI* literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_feed.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/icon_feed.png new file mode 100644 index 0000000000000000000000000000000000000000..fdf6daf8c9af60bf3cfabca744f23483e0f50704 GIT binary patch literal 415 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 literal 0 HcmV?d00001 diff --git a/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/xamarin_logo@2x.png b/Examples/xamarinFormApp/xamarinFormApp.iOS/Resources/xamarin_logo@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a5b9fc0e447bc328ad1c8018d4a928e4f8a24edf GIT binary patch literal 9337 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�G=^86OPDW4b{;^3fPi%8|Lz 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 + + + Debug + iPhoneSimulator + 8.0.30703 + 2.0 + {F4C814E7-FCDC-4596-854D-8FA5CD992C67} + {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {89a4fe7c-635d-49c9-8d8c-5cd363c0d68d} + Exe + xamarinFormApp.iOS + Resources + xamarinFormApp.iOS + true + NSUrlSessionHandler + automatic + + + true + full + false + bin\iPhoneSimulator\Debug + DEBUG + prompt + 4 + x86_64 + None + true + + + none + true + bin\iPhoneSimulator\Release + prompt + 4 + None + x86_64 + + + true + full + false + bin\iPhone\Debug + DEBUG + prompt + 4 + ARM64 + iPhone Developer + true + Entitlements.plist + None + -all + + + none + true + bin\iPhone\Release + prompt + 4 + ARM64 + iPhone Developer + Entitlements.plist + + + + + + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + {19768622-95F4-4D1B-AAF4-090274F22EB5} + xamarinFormApp + + + \ No newline at end of file diff --git a/Examples/xamarinFormApp/xamarinFormApp.sln b/Examples/xamarinFormApp/xamarinFormApp.sln new file mode 100644 index 00000000..265a3077 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp.sln @@ -0,0 +1,97 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30717.126 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xamarinFormApp.Android", "xamarinFormApp.Android\xamarinFormApp.Android.csproj", "{0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xamarinFormApp.iOS", "xamarinFormApp.iOS\xamarinFormApp.iOS.csproj", "{F4C814E7-FCDC-4596-854D-8FA5CD992C67}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xamarinFormApp", "xamarinFormApp\xamarinFormApp.csproj", "{E4094717-ED1A-4174-8D86-A65D2AD1380C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xamarinForm.Wpf", "xamarinForm.Wpf\xamarinForm.Wpf.csproj", "{12EC22F5-2586-4AD3-AE03-319C2FAC0B06}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|iPhone = Debug|iPhone + Debug|iPhoneSimulator = Debug|iPhoneSimulator + Release|Any CPU = Release|Any CPU + Release|iPhone = Release|iPhone + Release|iPhoneSimulator = Release|iPhoneSimulator + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|iPhone.Build.0 = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|iPhone.Deploy.0 = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|Any CPU.Build.0 = Release|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|Any CPU.Deploy.0 = Release|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|iPhone.ActiveCfg = Release|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|iPhone.Build.0 = Release|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|iPhone.Deploy.0 = Release|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {0BFC3652-7CD1-49E4-BA9A-70E5EC818FCE}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|Any CPU.ActiveCfg = Debug|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|Any CPU.Build.0 = Debug|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|Any CPU.Deploy.0 = Debug|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|iPhone.ActiveCfg = Debug|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|iPhone.Build.0 = Debug|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|iPhone.Deploy.0 = Debug|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|Any CPU.Build.0 = Release|iPhoneSimulator + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|Any CPU.Deploy.0 = Release|iPhoneSimulator + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|iPhone.ActiveCfg = Release|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|iPhone.Build.0 = Release|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|iPhone.Deploy.0 = Release|iPhone + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {F4C814E7-FCDC-4596-854D-8FA5CD992C67}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|iPhone.Build.0 = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|iPhone.Deploy.0 = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|Any CPU.Build.0 = Release|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|Any CPU.Deploy.0 = Release|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|iPhone.ActiveCfg = Release|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|iPhone.Build.0 = Release|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|iPhone.Deploy.0 = Release|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {E4094717-ED1A-4174-8D86-A65D2AD1380C}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Debug|iPhone.Build.0 = Debug|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Release|Any CPU.Build.0 = Release|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Release|iPhone.ActiveCfg = Release|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Release|iPhone.Build.0 = Release|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {12EC22F5-2586-4AD3-AE03-319C2FAC0B06}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {36BB8C05-4557-4287-B5A7-FD085825E6E0} + EndGlobalSection +EndGlobal diff --git a/Examples/xamarinFormApp/xamarinFormApp/App.xaml b/Examples/xamarinFormApp/xamarinFormApp/App.xaml new file mode 100644 index 00000000..9e63ee9e --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp/App.xaml @@ -0,0 +1,32 @@ + + + + + + #2196F3 + + + + diff --git a/Examples/xamarinFormApp/xamarinFormApp/App.xaml.cs b/Examples/xamarinFormApp/xamarinFormApp/App.xaml.cs new file mode 100644 index 00000000..b49cdb8d --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp/App.xaml.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using Xamarin.Forms; +using Xamarin.Forms.Xaml; +using xamarinFormApp.Models; +using xamarinFormApp.Services; +using xamarinFormApp.Views; + +namespace xamarinFormApp +{ + public partial class App : Application + { + public static IFreeSql fsql; + + public App() + { + InitializeComponent(); + test(); + DependencyService.Register(); + MainPage = new AppShell(); + } + void test() + { + List items; + + + items = new List() + { + new Item { Id = Guid.NewGuid().ToString(), Text = "假装 First item", Description="This is an item description." }, + new Item { Id = Guid.NewGuid().ToString(), Text = "的哥 Second item", Description="This is an item description." }, + new Item { Id = Guid.NewGuid().ToString(), Text = "四风 Third item", Description="This is an item description." }, + new Item { Id = Guid.NewGuid().ToString(), Text = "加州 Fourth item", Description="This is an item description." }, + new Item { Id = Guid.NewGuid().ToString(), Text = "阳光 Fifth item", Description="This is an item description." }, + new Item { Id = Guid.NewGuid().ToString(), Text = "孔雀 Sixth item", Description="This is an item description." } + }; + + + + try + { + #region mssql测试没问题 + + // fsql = new FreeSql.FreeSqlBuilder() + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=192.168.1.100;Initial Catalog=demo;Persist Security Info=True;MultipleActiveResultSets=true;User ID=sa;Password=a123456;Connect Timeout=30;min pool size=1;connection lifetime=15") + //.UseAutoSyncStructure(true) //自动同步实体结构【开发环境必备】 + //.UseMonitorCommand(cmd => Console.Write(cmd.CommandText)) + //.Build(); + + #endregion + + #region Sqlite需要反射,明天有时间再补充代码 + + // fsql = new FreeSql.FreeSqlBuilder() + //.UseConnectionString(FreeSql.DataType.Sqlite, "Data Source=document.db; Pooling=true;Min Pool Size=1") + //.UseAutoSyncStructure(true) //自动同步实体结构【开发环境必备】 + //.UseMonitorCommand(cmd => Console.Write(cmd.CommandText)) + //.Build(); + + #endregion + + #region mysql使用 reeSql.Provider.MySqlConnector , debug和release都设置为不链接即可 + + fsql = new FreeSql.FreeSqlBuilder() +.UseConnectionString(FreeSql.DataType.MySql, "Data Source=192.168.1.100;Port=3306;User ID=root;Password=a123456; Initial Catalog=test;Charset=utf8; SslMode=none;Min pool size=1") +.UseAutoSyncStructure(true) //自动同步实体结构【开发环境必备】 +.UseMonitorCommand(cmd => Console.Write(cmd.CommandText)) +.Build(); + #endregion + + fsql.CodeFirst.SyncStructure(); + if (fsql.Select().Count()<10) fsql.Insert().AppendData(items).ExecuteAffrows(); + var res = fsql.Select().ToList(a=>a.Text); + res.ForEach(a => { + Debug.WriteLine(" <== 测试测试测试 ==> " + a); + }); + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + } + protected override void OnStart() + { + } + + protected override void OnSleep() + { + } + + protected override void OnResume() + { + } + } +} diff --git a/Examples/xamarinFormApp/xamarinFormApp/AppShell.xaml b/Examples/xamarinFormApp/xamarinFormApp/AppShell.xaml new file mode 100644 index 00000000..68a70eb8 --- /dev/null +++ b/Examples/xamarinFormApp/xamarinFormApp/AppShell.xaml @@ -0,0 +1,46 @@ + + + + + + + + +

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�$#oyij7u8P{)$1YwU8+_}& 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 H=FZ;$l&O*< literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index 59867ec7..83080c14 100644 --- a/readme.md +++ b/readme.md @@ -16,10 +16,10 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ | | | | - | - | -| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | -| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) | -| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | -| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分表分库》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | +| | [《新人学习指引》](https://www.cnblogs.com/FreeSql/p/11531300.html) \| [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) | +| | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) | +| | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《AOP》](https://github.com/2881099/FreeSql/wiki/AOP) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) | +| | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分表分库》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93) \| [《黑科技》](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C) \| [《常见问题》](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) \| [*更新日志*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) | > FreeSql 提供多种使用习惯,请根据实际情况选择团队合适的一种: @@ -37,7 +37,7 @@ FreeSql 是功能强大的对象关系映射技术(O/RM),支持 .NETCore 2.1+ - [内容管理系统](https://github.com/hejiyong/fscms)